summaryrefslogtreecommitdiff
path: root/chromium/components
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-16 09:59:13 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-20 10:28:53 +0000
commit6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch)
treec8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/components
parent3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff)
downloadqtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components')
-rw-r--r--chromium/components/BUILD.gn5
-rw-r--r--chromium/components/OWNERS10
-rw-r--r--chromium/components/account_id/account_id.cc2
-rw-r--r--chromium/components/arc/BUILD.gn33
-rw-r--r--chromium/components/arc/arc_bridge_host_impl.cc46
-rw-r--r--chromium/components/arc/arc_bridge_service.cc47
-rw-r--r--chromium/components/arc/arc_browser_context_keyed_service_factory_base.h1
-rw-r--r--chromium/components/arc/arc_features.cc4
-rw-r--r--chromium/components/arc/arc_features.h1
-rw-r--r--chromium/components/arc/arc_features_parser.cc10
-rw-r--r--chromium/components/arc/arc_prefs.cc33
-rw-r--r--chromium/components/arc/arc_prefs.h19
-rw-r--r--chromium/components/arc/arc_session_impl.cc25
-rw-r--r--chromium/components/arc/arc_session_impl_unittest.cc7
-rw-r--r--chromium/components/arc/arc_session_runner.cc1
-rw-r--r--chromium/components/arc/arc_util.cc1
-rw-r--r--chromium/components/arc/bluetooth/bluetooth_type_converters.cc83
-rw-r--r--chromium/components/arc/bluetooth/bluetooth_type_converters_unittest.cc89
-rw-r--r--chromium/components/arc/common/accessibility_helper.mojom7
-rw-r--r--chromium/components/arc/common/app.mojom68
-rw-r--r--chromium/components/arc/common/bluetooth.mojom16
-rw-r--r--chromium/components/arc/common/intent_helper.mojom20
-rw-r--r--chromium/components/arc/common/usb_host.mojom20
-rw-r--r--chromium/components/arc/crash_collector/arc_crash_collector_bridge.cc1
-rw-r--r--chromium/components/arc/ime/arc_ime_service.cc2
-rw-r--r--chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc17
-rw-r--r--chromium/components/arc/intent_helper/arc_intent_helper_bridge.h5
-rw-r--r--chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc8
-rw-r--r--chromium/components/arc/intent_helper/open_url_delegate.h10
-rw-r--r--chromium/components/arc/metrics/arc_metrics_constants.h16
-rw-r--r--chromium/components/arc/metrics/arc_metrics_service.cc54
-rw-r--r--chromium/components/arc/metrics/arc_metrics_service.h24
-rw-r--r--chromium/components/arc/metrics/arc_metrics_service_unittest.cc76
-rw-r--r--chromium/components/arc/metrics/stability_metrics_manager.cc112
-rw-r--r--chromium/components/arc/metrics/stability_metrics_manager.h63
-rw-r--r--chromium/components/arc/metrics/stability_metrics_manager_unittest.cc105
-rw-r--r--chromium/components/arc/power/arc_power_bridge.cc26
-rw-r--r--chromium/components/arc/power/arc_power_bridge.h1
-rw-r--r--chromium/components/arc/power/arc_power_bridge_unittest.cc118
-rw-r--r--chromium/components/arc/timer/arc_timer_bridge.cc47
-rw-r--r--chromium/components/arc/timer/arc_timer_bridge.h7
-rw-r--r--chromium/components/arc/timer/arc_timer_bridge_unittest.cc9
-rw-r--r--chromium/components/arc/usb/usb_host_bridge.cc8
-rw-r--r--chromium/components/arc/usb/usb_host_bridge.h3
-rw-r--r--chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc24
-rw-r--r--chromium/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc1
-rw-r--r--chromium/components/arc/video_accelerator/protected_buffer_manager.cc1
-rw-r--r--chromium/components/arc/volume_mounter/DEPS2
-rw-r--r--chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.cc31
-rw-r--r--chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.h2
-rw-r--r--chromium/components/arc/wake_lock/arc_wake_lock_bridge.cc142
-rw-r--r--chromium/components/arc/wake_lock/arc_wake_lock_bridge.h63
-rw-r--r--chromium/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc193
-rw-r--r--chromium/components/arc/wake_lock/wake_lock_observer.h28
-rw-r--r--chromium/components/assist_ranker/base_predictor_unittest.cc4
-rw-r--r--chromium/components/assist_ranker/binary_classifier_predictor.cc4
-rw-r--r--chromium/components/assist_ranker/classifier_predictor.cc4
-rw-r--r--chromium/components/assist_ranker/example_preprocessing.cc6
-rw-r--r--chromium/components/assist_ranker/example_preprocessing_unittest.cc4
-rw-r--r--chromium/components/assist_ranker/proto/example_preprocessor.proto2
-rw-r--r--chromium/components/assist_ranker/ranker_model_loader_impl_unittest.cc1
-rw-r--r--chromium/components/assist_ranker/ranker_url_fetcher.cc1
-rw-r--r--chromium/components/autofill/OWNERS1
-rw-r--r--chromium/components/autofill/android/BUILD.gn16
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java17
-rw-r--r--chromium/components/autofill/android/java/strings/autofill_strings.grd11
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc3
-rw-r--r--chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc1
-rw-r--r--chromium/components/autofill/content/renderer/form_autofill_util.cc20
-rw-r--r--chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc2
-rw-r--r--chromium/components/autofill/content/renderer/form_tracker.cc20
-rw-r--r--chromium/components/autofill/content/renderer/form_tracker.h5
-rw-r--r--chromium/components/autofill/content/renderer/page_form_analyser_logger.cc30
-rw-r--r--chromium/components/autofill/content/renderer/page_passwords_analyser.cc2
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.cc9
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.h4
-rw-r--r--chromium/components/autofill/content/renderer/password_generation_agent.cc11
-rw-r--r--chromium/components/autofill/content/renderer/prefilled_values_detector.cc2
-rw-r--r--chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc5
-rw-r--r--chromium/components/autofill/core/browser/BUILD.gn34
-rw-r--r--chromium/components/autofill/core/browser/DEPS1
-rw-r--r--chromium/components/autofill/core/browser/OWNERS1
-rw-r--r--chromium/components/autofill/core/browser/accessory_sheet_data.cc5
-rw-r--r--chromium/components/autofill/core/browser/accessory_sheet_data.h16
-rw-r--r--chromium/components/autofill/core/browser/account_info_getter.h2
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.cc31
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.h39
-rw-r--r--chromium/components/autofill/core/browser/address_i18n_unittest.cc24
-rw-r--r--chromium/components/autofill/core/browser/autocomplete_history_manager.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_assistant.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_client.h63
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.cc16
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.h32
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model_unittest.cc43
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager.cc167
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager.h23
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc335
-rw-r--r--chromium/components/autofill/core/browser/autofill_driver_factory.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.cc3
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate.cc20
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc42
-rw-r--r--chromium/components/autofill/core/browser/autofill_field.cc13
-rw-r--r--chromium/components/autofill/core/browser/autofill_field.h15
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.cc87
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.h17
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager_unittest.cc121
-rw-r--r--chromium/components/autofill/core/browser/autofill_merge_unittest.cc4
-rw-r--r--chromium/components/autofill/core/browser/autofill_metadata.h4
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.cc486
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.h253
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics_unittest.cc1531
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.cc61
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.h45
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util.cc235
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util.h20
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_unittest.cc653
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validation_util.cc196
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc834
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator.cc14
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator.h18
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc176
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc15
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_scanner.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.cc2
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_type.cc3
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc13
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h11
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc52
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.cc36
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.h49
-rw-r--r--chromium/components/autofill/core/browser/contact_info_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/credit_card.cc31
-rw-r--r--chromium/components/autofill/core/browser/credit_card.h2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager.cc129
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager.h55
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc344
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc138
-rw-r--r--chromium/components/autofill/core/browser/credit_card_unittest.cc160
-rw-r--r--chromium/components/autofill/core/browser/field_filler.cc4
-rw-r--r--chromium/components/autofill/core/browser/field_filler_unittest.cc111
-rw-r--r--chromium/components/autofill/core/browser/field_types.h5
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.cc13
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.h5
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/form_field.cc22
-rw-r--r--chromium/components/autofill/core/browser/form_field.h2
-rw-r--r--chromium/components/autofill/core/browser/form_structure.cc1
-rw-r--r--chromium/components/autofill/core/browser/form_structure.h4
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.cc17
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.h53
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.cc115
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.h58
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc100
-rw-r--r--chromium/components/autofill/core/browser/legacy_strike_database.cc1
-rw-r--r--chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/legal_message_line_unittest.cc6
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager.cc156
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager.h32
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc325
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database.cc7
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database.h10
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc111
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc91
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.h45
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc194
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h91
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc199
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.h107
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_events.h97
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc1
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.cc31
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.h5
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client_unittest.cc49
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.cc18
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.h7
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.cc276
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.h85
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager_unittest.cc1089
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n.cc11
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n.h10
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc37
-rw-r--r--chromium/components/autofill/core/browser/price_field.cc34
-rw-r--r--chromium/components/autofill/core/browser/price_field.h40
-rw-r--r--chromium/components/autofill/core/browser/price_field_unittest.cc78
-rw-r--r--chromium/components/autofill/core/browser/proto/server.proto8
-rw-r--r--chromium/components/autofill/core/browser/randomized_encoder_unittest.cc12
-rw-r--r--chromium/components/autofill/core/browser/region_data_loader_impl.cc1
-rw-r--r--chromium/components/autofill/core/browser/search_field.cc4
-rw-r--r--chromium/components/autofill/core/browser/search_field.h3
-rw-r--r--chromium/components/autofill/core/browser/strike_database.cc55
-rw-r--r--chromium/components/autofill/core/browser/strike_database.h33
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_base.cc47
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_base.h35
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc46
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h36
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc289
-rw-r--r--chromium/components/autofill/core/browser/strike_database_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/suggestion.cc2
-rw-r--r--chromium/components/autofill/core/browser/suggestion.h2
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.cc8
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.h4
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection_unittest.cc80
-rw-r--r--chromium/components/autofill/core/browser/suggestion_test_helpers.h6
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.cc21
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.h10
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator.cc12
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator.h5
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc39
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h41
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_provider.h2
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_manager.cc28
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_manager.h17
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc13
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h20
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.cc7
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.h13
-rw-r--r--chromium/components/autofill/core/browser/test_strike_database.cc2
-rw-r--r--chromium/components/autofill/core/browser/test_strike_database.h2
-rw-r--r--chromium/components/autofill/core/browser/travel_field.cc53
-rw-r--r--chromium/components/autofill/core/browser/travel_field.h33
-rw-r--r--chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc77
-rw-r--r--chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h60
-rw-r--r--chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc3
-rw-r--r--chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc30
-rw-r--r--chromium/components/autofill/core/browser/validation.cc7
-rw-r--r--chromium/components/autofill/core/browser/validation.h2
-rw-r--r--chromium/components/autofill/core/browser/validation_unittest.cc66
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_change.h25
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc9
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h9
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc41
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h5
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc45
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc15
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc8
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc826
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc17
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc27
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h5
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc18
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h6
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc10
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h1
-rw-r--r--chromium/components/autofill/core/common/autofill_features.cc34
-rw-r--r--chromium/components/autofill/core/common/autofill_features.h9
-rw-r--r--chromium/components/autofill/core/common/autofill_prefs_unittest.cc3
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.cc70
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.h5
-rw-r--r--chromium/components/autofill/core/common/autofill_regexes_unittest.cc116
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.cc11
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.h2
-rw-r--r--chromium/components/autofill/core/common/autofill_util.cc3
-rw-r--r--chromium/components/autofill/core/common/autofill_util_unittest.cc30
-rw-r--r--chromium/components/autofill/core/common/form_field_data.h2
-rw-r--r--chromium/components/autofill/core/common/password_generation_util.cc23
-rw-r--r--chromium/components/autofill/core/common/password_generation_util.h25
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.cc10
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_agent.mm2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.h2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.mm2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h3
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm4
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h1
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm4
-rw-r--r--chromium/components/autofill/ios/browser/autofill_util.mm7
-rw-r--r--chromium/components/autofill/ios/browser/js_suggestion_manager.mm1
-rw-r--r--chromium/components/autofill/ios/browser/resources/autofill_controller.js2
-rw-r--r--chromium/components/autofill/ios/form_util/form_activity_tab_helper.h3
-rw-r--r--chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm3
-rw-r--r--chromium/components/autofill_assistant/OWNERS3
-rw-r--r--chromium/components/autofill_assistant/browser/BUILD.gn18
-rw-r--r--chromium/components/autofill_assistant/browser/actions/action.cc79
-rw-r--r--chromium/components/autofill_assistant/browser/actions/action.h10
-rw-r--r--chromium/components/autofill_assistant/browser/actions/action_delegate.h36
-rw-r--r--chromium/components/autofill_assistant/browser/actions/autofill_action.cc19
-rw-r--r--chromium/components/autofill_assistant/browser/actions/autofill_action.h2
-rw-r--r--chromium/components/autofill_assistant/browser/actions/autofill_action_unittest.cc82
-rw-r--r--chromium/components/autofill_assistant/browser/actions/get_payment_information_action.cc15
-rw-r--r--chromium/components/autofill_assistant/browser/actions/get_payment_information_action.h2
-rw-r--r--chromium/components/autofill_assistant/browser/actions/mock_action_delegate.h24
-rw-r--r--chromium/components/autofill_assistant/browser/actions/prompt_action.cc231
-rw-r--r--chromium/components/autofill_assistant/browser/actions/prompt_action.h45
-rw-r--r--chromium/components/autofill_assistant/browser/actions/prompt_action_unittest.cc201
-rw-r--r--chromium/components/autofill_assistant/browser/actions/set_form_field_value_action.cc4
-rw-r--r--chromium/components/autofill_assistant/browser/actions/show_details_action.cc103
-rw-r--r--chromium/components/autofill_assistant/browser/actions/show_details_action.h7
-rw-r--r--chromium/components/autofill_assistant/browser/actions/show_info_box_action.cc30
-rw-r--r--chromium/components/autofill_assistant/browser/actions/show_info_box_action.h28
-rw-r--r--chromium/components/autofill_assistant/browser/actions/show_progress_bar_action.cc13
-rw-r--r--chromium/components/autofill_assistant/browser/actions/stop_action.cc6
-rw-r--r--chromium/components/autofill_assistant/browser/actions/unsupported_action.h2
-rw-r--r--chromium/components/autofill_assistant/browser/batch_element_checker_unittest.cc14
-rw-r--r--chromium/components/autofill_assistant/browser/chip.cc19
-rw-r--r--chromium/components/autofill_assistant/browser/chip.h20
-rw-r--r--chromium/components/autofill_assistant/browser/client.h10
-rw-r--r--chromium/components/autofill_assistant/browser/controller.cc513
-rw-r--r--chromium/components/autofill_assistant/browser/controller.h151
-rw-r--r--chromium/components/autofill_assistant/browser/controller_unittest.cc477
-rw-r--r--chromium/components/autofill_assistant/browser/details.cc250
-rw-r--r--chromium/components/autofill_assistant/browser/details.h63
-rw-r--r--chromium/components/autofill_assistant/browser/devtools/devtools_client.cc2
-rw-r--r--chromium/components/autofill_assistant/browser/element_area.cc37
-rw-r--r--chromium/components/autofill_assistant/browser/element_area.h20
-rw-r--r--chromium/components/autofill_assistant/browser/element_area_unittest.cc168
-rw-r--r--chromium/components/autofill_assistant/browser/element_precondition.cc100
-rw-r--r--chromium/components/autofill_assistant/browser/element_precondition.h59
-rw-r--r--chromium/components/autofill_assistant/browser/element_precondition_unittest.cc179
-rw-r--r--chromium/components/autofill_assistant/browser/fake_script_executor_delegate.cc91
-rw-r--r--chromium/components/autofill_assistant/browser/fake_script_executor_delegate.h92
-rw-r--r--chromium/components/autofill_assistant/browser/features.cc20
-rw-r--r--chromium/components/autofill_assistant/browser/features.h21
-rw-r--r--chromium/components/autofill_assistant/browser/info_box.cc22
-rw-r--r--chromium/components/autofill_assistant/browser/info_box.h35
-rw-r--r--chromium/components/autofill_assistant/browser/metrics.h91
-rw-r--r--chromium/components/autofill_assistant/browser/mock_client_memory.cc12
-rw-r--r--chromium/components/autofill_assistant/browser/mock_client_memory.h32
-rw-r--r--chromium/components/autofill_assistant/browser/mock_ui_controller.h25
-rw-r--r--chromium/components/autofill_assistant/browser/mock_web_controller.h2
-rw-r--r--chromium/components/autofill_assistant/browser/payment_information.h32
-rw-r--r--chromium/components/autofill_assistant/browser/payment_request.cc18
-rw-r--r--chromium/components/autofill_assistant/browser/payment_request.h52
-rw-r--r--chromium/components/autofill_assistant/browser/protocol_utils.cc31
-rw-r--r--chromium/components/autofill_assistant/browser/protocol_utils.h12
-rw-r--r--chromium/components/autofill_assistant/browser/protocol_utils_unittest.cc61
-rw-r--r--chromium/components/autofill_assistant/browser/script.h3
-rw-r--r--chromium/components/autofill_assistant/browser/script_executor.cc179
-rw-r--r--chromium/components/autofill_assistant/browser/script_executor.h26
-rw-r--r--chromium/components/autofill_assistant/browser/script_executor_delegate.h25
-rw-r--r--chromium/components/autofill_assistant/browser/script_executor_unittest.cc79
-rw-r--r--chromium/components/autofill_assistant/browser/script_precondition.cc134
-rw-r--r--chromium/components/autofill_assistant/browser/script_precondition.h34
-rw-r--r--chromium/components/autofill_assistant/browser/script_precondition_unittest.cc22
-rw-r--r--chromium/components/autofill_assistant/browser/script_tracker.cc19
-rw-r--r--chromium/components/autofill_assistant/browser/script_tracker.h11
-rw-r--r--chromium/components/autofill_assistant/browser/script_tracker_unittest.cc190
-rw-r--r--chromium/components/autofill_assistant/browser/selector.cc14
-rw-r--r--chromium/components/autofill_assistant/browser/selector.h5
-rw-r--r--chromium/components/autofill_assistant/browser/service.cc5
-rw-r--r--chromium/components/autofill_assistant/browser/service.proto201
-rw-r--r--chromium/components/autofill_assistant/browser/state.h39
-rw-r--r--chromium/components/autofill_assistant/browser/ui_controller.cc16
-rw-r--r--chromium/components/autofill_assistant/browser/ui_controller.h66
-rw-r--r--chromium/components/autofill_assistant/browser/ui_delegate.h52
-rw-r--r--chromium/components/autofill_assistant/browser/web_controller.cc168
-rw-r--r--chromium/components/autofill_assistant/browser/web_controller.h22
-rw-r--r--chromium/components/autofill_assistant/browser/web_controller_browsertest.cc6
-rw-r--r--chromium/components/autofill_assistant_strings.grdp24
-rw-r--r--chromium/components/autofill_strings.grdp7
-rw-r--r--chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java17
-rw-r--r--chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java6
-rw-r--r--chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java25
-rw-r--r--chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java2
-rw-r--r--chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java42
-rw-r--r--chromium/components/background_task_scheduler/android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java2
-rw-r--r--chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java2
-rw-r--r--chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java8
-rw-r--r--chromium/components/bookmarks/browser/bookmark_codec.cc23
-rw-r--r--chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc2
-rw-r--r--chromium/components/bookmarks/browser/bookmark_expanded_state_tracker_unittest.cc3
-rw-r--r--chromium/components/bookmarks/browser/bookmark_model_unittest.cc2
-rw-r--r--chromium/components/bookmarks/browser/bookmark_storage.cc76
-rw-r--r--chromium/components/bookmarks/browser/bookmark_storage.h5
-rw-r--r--chromium/components/bookmarks/browser/bookmark_utils.cc3
-rw-r--r--chromium/components/bookmarks/browser/model_loader.cc26
-rw-r--r--chromium/components/bookmarks/browser/model_loader.h1
-rw-r--r--chromium/components/bookmarks/browser/titled_url_node_sorter.h2
-rw-r--r--chromium/components/browser_sync/BUILD.gn6
-rw-r--r--chromium/components/browser_sync/DEPS1
-rw-r--r--chromium/components/browser_sync/abstract_profile_sync_service_test.cc15
-rw-r--r--chromium/components/browser_sync/browser_sync_client.cc19
-rw-r--r--chromium/components/browser_sync/browser_sync_client.h75
-rw-r--r--chromium/components/browser_sync/browser_sync_switches.cc11
-rw-r--r--chromium/components/browser_sync/browser_sync_switches.h10
-rw-r--r--chromium/components/browser_sync/profile_sync_components_factory_impl.cc82
-rw-r--r--chromium/components/browser_sync/profile_sync_components_factory_impl.h18
-rw-r--r--chromium/components/browser_sync/profile_sync_service.cc283
-rw-r--r--chromium/components/browser_sync/profile_sync_service.h84
-rw-r--r--chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc95
-rw-r--r--chromium/components/browser_sync/profile_sync_service_bookmark_unittest.cc32
-rw-r--r--chromium/components/browser_sync/profile_sync_service_mock.cc15
-rw-r--r--chromium/components/browser_sync/profile_sync_service_mock.h14
-rw-r--r--chromium/components/browser_sync/profile_sync_service_startup_unittest.cc335
-rw-r--r--chromium/components/browser_sync/profile_sync_service_unittest.cc572
-rw-r--r--chromium/components/browser_sync/profile_sync_test_util.cc209
-rw-r--r--chromium/components/browser_sync/profile_sync_test_util.h64
-rw-r--r--chromium/components/browser_sync/sync_auth_manager.cc98
-rw-r--r--chromium/components/browser_sync/sync_auth_manager.h44
-rw-r--r--chromium/components/browser_sync/sync_auth_manager_unittest.cc107
-rw-r--r--chromium/components/browser_sync/sync_user_settings_impl.cc161
-rw-r--r--chromium/components/browser_sync/sync_user_settings_impl.h77
-rw-r--r--chromium/components/browser_sync/sync_user_settings_mock.cc13
-rw-r--r--chromium/components/browser_sync/sync_user_settings_mock.h50
-rw-r--r--chromium/components/browser_watcher/postmortem_report_collector_unittest.cc12
-rw-r--r--chromium/components/browser_watcher/window_hang_monitor_win.cc1
-rw-r--r--chromium/components/browser_watcher/window_hang_monitor_win_unittest.cc21
-rw-r--r--chromium/components/browsing_data/content/conditional_cache_counting_helper.cc1
-rw-r--r--chromium/components/browsing_data/core/browsing_data_utils_unittest.cc3
-rw-r--r--chromium/components/browsing_data/core/counters/autofill_counter.cc1
-rw-r--r--chromium/components/browsing_data/core/counters/bookmark_counter.cc3
-rw-r--r--chromium/components/browsing_data/core/counters/browsing_data_counter.cc1
-rw-r--r--chromium/components/browsing_data/core/counters/browsing_data_counter_unittest.cc1
-rw-r--r--chromium/components/browsing_data/core/counters/history_counter.cc1
-rw-r--r--chromium/components/browsing_data/core/counters/passwords_counter.cc1
-rw-r--r--chromium/components/browsing_data/core/counters/passwords_counter.h2
-rw-r--r--chromium/components/browsing_data/core/history_notice_utils.cc7
-rw-r--r--chromium/components/captive_portal/captive_portal_detector.cc1
-rw-r--r--chromium/components/cast_certificate/cast_crl.h2
-rw-r--r--chromium/components/cast_channel/BUILD.gn3
-rw-r--r--chromium/components/cast_channel/cast_auth_util.cc2
-rw-r--r--chromium/components/cast_channel/cast_framer.cc3
-rw-r--r--chromium/components/cast_channel/cast_message_handler.cc14
-rw-r--r--chromium/components/cast_channel/cast_message_handler.h3
-rw-r--r--chromium/components/cast_channel/cast_message_handler_unittest.cc54
-rw-r--r--chromium/components/cast_channel/cast_message_util.cc300
-rw-r--r--chromium/components/cast_channel/cast_message_util_unittest.cc14
-rw-r--r--chromium/components/cast_channel/cast_socket.h1
-rw-r--r--chromium/components/cast_channel/cast_socket_unittest.cc14
-rw-r--r--chromium/components/cast_channel/cast_test_util.h5
-rw-r--r--chromium/components/cast_channel/cast_transport_unittest.cc1
-rw-r--r--chromium/components/cast_channel/enum_table.cc44
-rw-r--r--chromium/components/cast_channel/enum_table.h368
-rw-r--r--chromium/components/cast_channel/enum_table_unittest.cc173
-rw-r--r--chromium/components/cast_channel/keep_alive_delegate.cc1
-rw-r--r--chromium/components/cast_channel/keep_alive_delegate_unittest.cc1
-rw-r--r--chromium/components/cast_channel/mojo_data_pump.cc1
-rw-r--r--chromium/components/cast_channel/mojo_data_pump.h2
-rw-r--r--chromium/components/cdm/browser/media_drm_storage_impl.cc236
-rw-r--r--chromium/components/cdm/browser/media_drm_storage_impl.h40
-rw-r--r--chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc106
-rw-r--r--chromium/components/certificate_transparency/ct_known_logs.h8
-rw-r--r--chromium/components/certificate_transparency/log_dns_client.cc48
-rw-r--r--chromium/components/certificate_transparency/log_dns_client.h9
-rw-r--r--chromium/components/certificate_transparency/log_dns_client_unittest.cc334
-rw-r--r--chromium/components/certificate_transparency/mock_log_dns_traffic.cc12
-rw-r--r--chromium/components/certificate_transparency/mock_log_dns_traffic.h12
-rw-r--r--chromium/components/certificate_transparency/single_tree_tracker.cc44
-rw-r--r--chromium/components/certificate_transparency/single_tree_tracker.h25
-rw-r--r--chromium/components/certificate_transparency/single_tree_tracker_unittest.cc306
-rw-r--r--chromium/components/certificate_transparency/tree_state_tracker.cc3
-rw-r--r--chromium/components/certificate_transparency/tree_state_tracker.h2
-rw-r--r--chromium/components/certificate_transparency/tree_state_tracker_unittest.cc5
-rw-r--r--chromium/components/chrome_cleaner/public/constants/result_codes.h14
-rw-r--r--chromium/components/cloud_devices/common/cloud_device_description.cc58
-rw-r--r--chromium/components/cloud_devices/common/cloud_device_description.h29
-rw-r--r--chromium/components/cloud_devices/common/description_items.h22
-rw-r--r--chromium/components/cloud_devices/common/description_items_inl.h133
-rw-r--r--chromium/components/cloud_devices/common/printer_description.cc1210
-rw-r--r--chromium/components/cloud_devices/common/printer_description.h168
-rw-r--r--chromium/components/cloud_devices/common/printer_description_unittest.cc687
-rw-r--r--chromium/components/component_updater/OWNERS3
-rw-r--r--chromium/components/component_updater/README.md2
-rw-r--r--chromium/components/component_updater/component_installer_unittest.cc1
-rw-r--r--chromium/components/component_updater/component_updater_service.cc1
-rw-r--r--chromium/components/component_updater/configurator_impl.cc1
-rw-r--r--chromium/components/component_updater/configurator_impl_unittest.cc4
-rw-r--r--chromium/components/component_updater/timer_update_scheduler.cc4
-rw-r--r--chromium/components/components_locale_settings.grd13
-rw-r--r--chromium/components/components_strings.grd14
-rw-r--r--chromium/components/consent_auditor/consent_auditor_impl.cc2
-rw-r--r--chromium/components/consent_auditor/consent_auditor_impl.h13
-rw-r--r--chromium/components/consent_auditor/consent_auditor_impl_unittest.cc6
-rw-r--r--chromium/components/consent_auditor/consent_sync_bridge.h7
-rw-r--r--chromium/components/consent_auditor/consent_sync_bridge_impl.cc27
-rw-r--r--chromium/components/consent_auditor/consent_sync_bridge_impl.h67
-rw-r--r--chromium/components/consent_auditor/consent_sync_bridge_impl_unittest.cc30
-rw-r--r--chromium/components/content_capture/DEPS4
-rw-r--r--chromium/components/content_capture/OWNERS3
-rw-r--r--chromium/components/content_capture/android/BUILD.gn40
-rw-r--r--chromium/components/content_capture/android/DEPS5
-rw-r--r--chromium/components/content_capture/android/content_capture_features_android.cc10
-rw-r--r--chromium/components/content_capture/android/content_capture_receiver_manager_android.cc124
-rw-r--r--chromium/components/content_capture/android/content_capture_receiver_manager_android.h40
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java30
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java83
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java14
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java78
-rw-r--r--chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java20
-rw-r--r--chromium/components/content_capture/browser/BUILD.gn38
-rw-r--r--chromium/components/content_capture/browser/DEPS4
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver.cc59
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver.h62
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_manager.cc134
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_manager.h89
-rw-r--r--chromium/components/content_capture/browser/content_capture_receiver_test.cc354
-rw-r--r--chromium/components/content_capture/common/BUILD.gn72
-rw-r--r--chromium/components/content_capture/common/OWNERS6
-rw-r--r--chromium/components/content_capture/common/content_capture.mojom18
-rw-r--r--chromium/components/content_capture/common/content_capture.typemap20
-rw-r--r--chromium/components/content_capture/common/content_capture_data.cc24
-rw-r--r--chromium/components/content_capture/common/content_capture_data.h45
-rw-r--r--chromium/components/content_capture/common/content_capture_data.mojom16
-rw-r--r--chromium/components/content_capture/common/content_capture_features.cc35
-rw-r--r--chromium/components/content_capture/common/content_capture_features.h26
-rw-r--r--chromium/components/content_capture/common/content_capture_struct_traits.cc28
-rw-r--r--chromium/components/content_capture/common/content_capture_struct_traits.h42
-rw-r--r--chromium/components/content_capture/common/content_capture_struct_traits_unittest.cc59
-rw-r--r--chromium/components/content_capture/common/traits_test_service.test-mojom14
-rw-r--r--chromium/components/content_capture/renderer/BUILD.gn18
-rw-r--r--chromium/components/content_capture/renderer/DEPS4
-rw-r--r--chromium/components/content_capture/renderer/content_capture_sender.cc89
-rw-r--r--chromium/components/content_capture/renderer/content_capture_sender.h53
-rw-r--r--chromium/components/content_settings/core/browser/BUILD.gn3
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc4
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_policy_provider.cc2
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref.cc4
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref_unittest.cc153
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_registry.cc10
-rw-r--r--chromium/components/content_settings/core/browser/website_settings_registry.cc5
-rw-r--r--chromium/components/content_settings/core/common/content_settings.cc4
-rw-r--r--chromium/components/content_settings/core/common/content_settings_pattern_parser.cc10
-rw-r--r--chromium/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc10
-rw-r--r--chromium/components/content_settings/core/common/content_settings_types.h7
-rw-r--r--chromium/components/contextual_search/content/renderer/contextual_search_wrapper.cc2
-rw-r--r--chromium/components/contextual_search/content/renderer/overlay_js_render_frame_observer.cc3
-rw-r--r--chromium/components/contextual_search/core/browser/contextual_search_preference.h2
-rw-r--r--chromium/components/crash/content/app/BUILD.gn45
-rw-r--r--chromium/components/crash/content/app/breakpad_linux.cc2
-rw-r--r--chromium/components/crash/content/app/breakpad_linux.h3
-rw-r--r--chromium/components/crash/content/app/breakpad_win.cc4
-rw-r--r--chromium/components/crash/content/app/chrome_crashpad_handler.cc17
-rw-r--r--chromium/components/crash/content/app/crash_export_stubs.cc2
-rw-r--r--chromium/components/crash/content/app/crash_export_thunks.cc4
-rw-r--r--chromium/components/crash/content/app/crash_export_thunks.h5
-rw-r--r--chromium/components/crash/content/app/crashpad.cc32
-rw-r--r--chromium/components/crash/content/app/crashpad.h10
-rw-r--r--chromium/components/crash/content/app/crashpad_linux.cc111
-rw-r--r--chromium/components/crash/content/app/crashpad_mac.mm3
-rw-r--r--chromium/components/crash/content/app/fallback_crash_handler_launcher_win.cc2
-rw-r--r--chromium/components/crash/content/app/fallback_crash_handler_win.cc4
-rw-r--r--chromium/components/crash/content/app/fallback_crash_handler_win_unittest.cc4
-rw-r--r--chromium/components/crash/content/browser/child_exit_observer_android.cc3
-rw-r--r--chromium/components/crash/content/browser/child_exit_observer_android.h2
-rw-r--r--chromium/components/crash/content/browser/child_process_crash_observer_android.cc2
-rw-r--r--chromium/components/crash/content/browser/crash_handler_host_linux.cc3
-rw-r--r--chromium/components/crash/core/browser/resources/crashes.html5
-rw-r--r--chromium/components/crash/core/common/BUILD.gn5
-rw-r--r--chromium/components/crash/core/common/crash_key.cc1
-rw-r--r--chromium/components/crash/core/common/crash_key.h7
-rw-r--r--chromium/components/cronet/BUILD.gn2
-rw-r--r--chromium/components/cronet/android/BUILD.gn2
-rw-r--r--chromium/components/cronet/native/BUILD.gn5
-rw-r--r--chromium/components/data_reduction_proxy/DEPS3
-rw-r--r--chromium/components/data_reduction_proxy/content/DEPS1
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/BUILD.gn2
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_decider.cc6
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc3
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc3
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider.cc4
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider_unittest.cc2
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.cc (renamed from chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc)2
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h (renamed from chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h)6
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc34
-rw-r--r--chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc2
-rw-r--r--chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.cc8
-rw-r--r--chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h3
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/BUILD.gn2
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc12
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc9
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc3
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc23
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc6
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc3
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc2
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h7
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc4
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc31
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc21
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h2
-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_unittest.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h10
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc2
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc4
-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/browser/data_reduction_proxy_test_utils.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc18
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h8
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/data_usage_store.cc2
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc16
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/secure_proxy_checker.cc1
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc6
-rw-r--r--chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc5
-rw-r--r--chromium/components/data_reduction_proxy/core/common/BUILD.gn3
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.cc19
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_features.h3
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc24
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc9
-rw-r--r--chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h4
-rw-r--r--chromium/components/data_use_measurement/content/content_url_request_classifier.cc4
-rw-r--r--chromium/components/data_use_measurement/core/data_use_measurement.cc1
-rw-r--r--chromium/components/dbus/BUILD.gn14
-rw-r--r--chromium/components/dbus/OWNERS1
-rw-r--r--chromium/components/dbus/dbus_thread_linux.cc29
-rw-r--r--chromium/components/dbus/dbus_thread_linux.h29
-rw-r--r--chromium/components/dom_distiller/content/browser/distillability_driver.cc19
-rw-r--r--chromium/components/dom_distiller/content/browser/distillability_driver.h3
-rw-r--r--chromium/components/dom_distiller/content/browser/distillable_page_utils_browsertest.cc10
-rw-r--r--chromium/components/dom_distiller/content/browser/distiller_javascript_utils.cc3
-rw-r--r--chromium/components/dom_distiller/content/browser/distiller_page_web_contents.cc9
-rw-r--r--chromium/components/dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc41
-rw-r--r--chromium/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc11
-rw-r--r--chromium/components/dom_distiller/content/renderer/distillability_agent.cc43
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.cc6
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h5
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_native_javascript.cc32
-rw-r--r--chromium/components/dom_distiller/content/renderer/distiller_native_javascript.h5
-rw-r--r--chromium/components/dom_distiller/core/distilled_content_store.h4
-rw-r--r--chromium/components/dom_distiller/core/distiller.cc4
-rw-r--r--chromium/components/dom_distiller/core/distiller_unittest.cc2
-rw-r--r--chromium/components/dom_distiller/core/distiller_url_fetcher.cc1
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_features.h3
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_service.cc1
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_service_unittest.cc4
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_switches.cc4
-rw-r--r--chromium/components/dom_distiller/core/dom_distiller_switches.h4
-rw-r--r--chromium/components/dom_distiller/core/fake_distiller_page.h2
-rw-r--r--chromium/components/dom_distiller/core/page_features.cc3
-rw-r--r--chromium/components/dom_distiller/core/page_features_unittest.cc5
-rw-r--r--chromium/components/dom_distiller/core/task_tracker_unittest.cc1
-rw-r--r--chromium/components/dom_distiller/core/url_utils.cc4
-rw-r--r--chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc1
-rw-r--r--chromium/components/dom_distiller/webui/resources/about_dom_distiller.html1
-rw-r--r--chromium/components/domain_reliability/config.cc2
-rw-r--r--chromium/components/domain_reliability/context_unittest.cc18
-rw-r--r--chromium/components/domain_reliability/header.cc2
-rw-r--r--chromium/components/domain_reliability/monitor.cc8
-rw-r--r--chromium/components/domain_reliability/monitor_unittest.cc9
-rw-r--r--chromium/components/domain_reliability/quic_error_mapping.cc3
-rw-r--r--chromium/components/domain_reliability/util.cc1
-rw-r--r--chromium/components/download/content/internal/download_driver_impl.cc10
-rw-r--r--chromium/components/download/content/internal/download_driver_impl_unittest.cc8
-rw-r--r--chromium/components/download/internal/background_service/blob_task_proxy.cc1
-rw-r--r--chromium/components/download/internal/background_service/config.cc11
-rw-r--r--chromium/components/download/internal/background_service/config.h9
-rw-r--r--chromium/components/download/internal/background_service/controller_impl.cc6
-rw-r--r--chromium/components/download/internal/background_service/controller_impl_unittest.cc37
-rw-r--r--chromium/components/download/internal/background_service/debugging_client.cc2
-rw-r--r--chromium/components/download/internal/background_service/driver_entry.h4
-rw-r--r--chromium/components/download/internal/background_service/empty_file_monitor.cc1
-rw-r--r--chromium/components/download/internal/background_service/file_monitor_impl.cc15
-rw-r--r--chromium/components/download/internal/background_service/in_memory_download_unittest.cc1
-rw-r--r--chromium/components/download/internal/background_service/scheduler/device_status_listener.cc18
-rw-r--r--chromium/components/download/internal/background_service/scheduler/device_status_listener.h8
-rw-r--r--chromium/components/download/internal/background_service/scheduler/device_status_listener_unittest.cc39
-rw-r--r--chromium/components/download/internal/background_service/scheduler/scheduler_impl_unittest.cc2
-rw-r--r--chromium/components/download/internal/background_service/stats.cc4
-rw-r--r--chromium/components/download/internal/background_service/stats.h3
-rw-r--r--chromium/components/download/internal/common/BUILD.gn35
-rw-r--r--chromium/components/download/internal/common/DEPS2
-rw-r--r--chromium/components/download/internal/common/android/download_collection_bridge.cc189
-rw-r--r--chromium/components/download/internal/common/android/download_collection_bridge.h81
-rw-r--r--chromium/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java291
-rw-r--r--chromium/components/download/internal/common/base_file.cc66
-rw-r--r--chromium/components/download/internal/common/base_file_win.cc3
-rw-r--r--chromium/components/download/internal/common/download_db_cache.cc1
-rw-r--r--chromium/components/download/internal/common/download_file_impl.cc51
-rw-r--r--chromium/components/download/internal/common/download_file_unittest.cc9
-rw-r--r--chromium/components/download/internal/common/download_item_impl.cc48
-rw-r--r--chromium/components/download/internal/common/download_item_impl_unittest.cc12
-rw-r--r--chromium/components/download/internal/common/download_path_reservation_tracker.cc518
-rw-r--r--chromium/components/download/internal/common/download_path_reservation_tracker_unittest.cc728
-rw-r--r--chromium/components/download/internal/common/download_response_handler.cc2
-rw-r--r--chromium/components/download/internal/common/download_stats.cc46
-rw-r--r--chromium/components/download/internal/common/download_utils.cc15
-rw-r--r--chromium/components/download/internal/common/download_worker.cc3
-rw-r--r--chromium/components/download/internal/common/in_progress_download_manager.cc110
-rw-r--r--chromium/components/download/internal/common/parallel_download_job_unittest.cc3
-rw-r--r--chromium/components/download/internal/common/parallel_download_utils_unittest.cc6
-rw-r--r--chromium/components/download/internal/common/resource_downloader.cc1
-rw-r--r--chromium/components/download/internal/common/url_download_request_handle.cc1
-rw-r--r--chromium/components/download/public/background_service/download_metadata.cc3
-rw-r--r--chromium/components/download/public/background_service/download_metadata.h4
-rw-r--r--chromium/components/download/public/background_service/download_service.h2
-rw-r--r--chromium/components/download/public/background_service/navigation_monitor.h2
-rw-r--r--chromium/components/download/public/common/BUILD.gn7
-rw-r--r--chromium/components/download/public/common/auto_resumption_handler.cc1
-rw-r--r--chromium/components/download/public/common/base_file.h6
-rw-r--r--chromium/components/download/public/common/download_features.cc10
-rw-r--r--chromium/components/download/public/common/download_features.h10
-rw-r--r--chromium/components/download/public/common/download_file.h16
-rw-r--r--chromium/components/download/public/common/download_file_impl.h16
-rw-r--r--chromium/components/download/public/common/download_item_impl.h4
-rw-r--r--chromium/components/download/public/common/download_path_reservation_tracker.h119
-rw-r--r--chromium/components/download/public/common/download_stats.h9
-rw-r--r--chromium/components/download/public/common/download_url_parameters.cc4
-rw-r--r--chromium/components/download/public/common/download_url_parameters.h12
-rw-r--r--chromium/components/download/public/common/in_progress_download_manager.h31
-rw-r--r--chromium/components/download/public/common/mock_download_file.h10
-rw-r--r--chromium/components/download/public/task/task_manager_unittest.cc1
-rw-r--r--chromium/components/download/quarantine/BUILD.gn5
-rw-r--r--chromium/components/download/quarantine/common_linux.cc12
-rw-r--r--chromium/components/download/quarantine/common_linux.h21
-rw-r--r--chromium/components/download/quarantine/quarantine.cc4
-rw-r--r--chromium/components/download/quarantine/quarantine_linux.cc64
-rw-r--r--chromium/components/download/quarantine/quarantine_linux_unittest.cc183
-rw-r--r--chromium/components/download/quarantine/quarantine_mac.mm52
-rw-r--r--chromium/components/download/quarantine/quarantine_mac_unittest.mm79
-rw-r--r--chromium/components/download/quarantine/quarantine_win.cc3
-rw-r--r--chromium/components/download/quarantine/test_support.cc4
-rw-r--r--chromium/components/download/quarantine/test_support_linux.cc58
-rw-r--r--chromium/components/download/quarantine/test_support_mac.mm3
-rw-r--r--chromium/components/embedder_support/android/BUILD.gn15
-rw-r--r--chromium/components/embedder_support/android/delegate/color_chooser_android.h2
-rw-r--r--chromium/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd11
-rw-r--r--chromium/components/embedder_support/android/view/content_view_render_view.cc4
-rw-r--r--chromium/components/error_page/common/error_page_switches.cc10
-rw-r--r--chromium/components/error_page/common/error_page_switches.h4
-rw-r--r--chromium/components/error_page/common/localized_error.cc32
-rw-r--r--chromium/components/error_page/common/net_error_info.h18
-rw-r--r--chromium/components/error_page_strings.grdp10
-rw-r--r--chromium/components/exo/BUILD.gn2
-rw-r--r--chromium/components/exo/buffer.cc11
-rw-r--r--chromium/components/exo/buffer.h9
-rw-r--r--chromium/components/exo/buffer_unittest.cc25
-rw-r--r--chromium/components/exo/client_controlled_shell_surface.cc28
-rw-r--r--chromium/components/exo/client_controlled_shell_surface_unittest.cc112
-rw-r--r--chromium/components/exo/data_offer.cc3
-rw-r--r--chromium/components/exo/data_offer.h2
-rw-r--r--chromium/components/exo/data_offer_unittest.cc6
-rw-r--r--chromium/components/exo/data_source.cc1
-rw-r--r--chromium/components/exo/display.h2
-rw-r--r--chromium/components/exo/frame_sink_resource_manager.cc52
-rw-r--r--chromium/components/exo/frame_sink_resource_manager.h45
-rw-r--r--chromium/components/exo/fullscreen_shell_surface_unittest.cc1
-rw-r--r--chromium/components/exo/gaming_seat_unittest.cc4
-rw-r--r--chromium/components/exo/input_method_surface.cc22
-rw-r--r--chromium/components/exo/input_method_surface.h3
-rw-r--r--chromium/components/exo/keyboard.cc6
-rw-r--r--chromium/components/exo/layer_tree_frame_sink_holder.cc34
-rw-r--r--chromium/components/exo/layer_tree_frame_sink_holder.h15
-rw-r--r--chromium/components/exo/pointer.cc189
-rw-r--r--chromium/components/exo/pointer.h51
-rw-r--r--chromium/components/exo/pointer_unittest.cc36
-rw-r--r--chromium/components/exo/relative_pointer_delegate.h29
-rw-r--r--chromium/components/exo/seat.cc1
-rw-r--r--chromium/components/exo/shell_surface.cc9
-rw-r--r--chromium/components/exo/shell_surface.h5
-rw-r--r--chromium/components/exo/shell_surface_base.cc2
-rw-r--r--chromium/components/exo/shell_surface_unittest.cc1
-rw-r--r--chromium/components/exo/shell_surface_util.cc17
-rw-r--r--chromium/components/exo/surface.cc49
-rw-r--r--chromium/components/exo/surface.h6
-rw-r--r--chromium/components/exo/surface_tree_host.cc2
-rw-r--r--chromium/components/exo/surface_unittest.cc42
-rw-r--r--chromium/components/exo/text_input.cc113
-rw-r--r--chromium/components/exo/text_input.h14
-rw-r--r--chromium/components/exo/text_input_unittest.cc93
-rw-r--r--chromium/components/exo/wayland/BUILD.gn15
-rw-r--r--chromium/components/exo/wayland/clients/client_helper.cc2
-rw-r--r--chromium/components/exo/wayland/clients/perftests.cc6
-rw-r--r--chromium/components/exo/wayland/clients/rects.cc2
-rw-r--r--chromium/components/exo/wayland/server.cc935
-rw-r--r--chromium/components/exo/wayland/server_util.cc6
-rw-r--r--chromium/components/exo/wayland/wl_compositor.cc1
-rw-r--r--chromium/components/exo/wayland/wl_data_device_manager.cc364
-rw-r--r--chromium/components/exo/wayland/wl_data_device_manager.h25
-rw-r--r--chromium/components/exo/wayland/wl_shell.cc1
-rw-r--r--chromium/components/exo/wayland/wp_presentation.cc104
-rw-r--r--chromium/components/exo/wayland/wp_presentation.h23
-rw-r--r--chromium/components/exo/wayland/wp_viewporter.cc159
-rw-r--r--chromium/components/exo/wayland/wp_viewporter.h23
-rw-r--r--chromium/components/exo/wayland/zaura_shell.cc2
-rw-r--r--chromium/components/exo/wayland/zcr_alpha_compositing.cc141
-rw-r--r--chromium/components/exo/wayland/zcr_alpha_compositing.h23
-rw-r--r--chromium/components/exo/wayland/zcr_keyboard_configuration.cc26
-rw-r--r--chromium/components/exo/wayland/zcr_notification_shell.cc1
-rw-r--r--chromium/components/exo/wayland/zcr_remote_shell.cc1
-rw-r--r--chromium/components/exo/wayland/zcr_secure_output.cc113
-rw-r--r--chromium/components/exo/wayland/zcr_secure_output.h23
-rw-r--r--chromium/components/exo/wayland/zcr_stylus.cc107
-rw-r--r--chromium/components/exo/wayland/zcr_stylus.h23
-rw-r--r--chromium/components/exo/wayland/zcr_stylus_tools.cc2
-rw-r--r--chromium/components/exo/wayland/zwp_fullscreen_shell.cc1
-rw-r--r--chromium/components/exo/wayland/zwp_linux_explicit_synchronization.cc2
-rw-r--r--chromium/components/exo/wayland/zwp_relative_pointer_manager.cc102
-rw-r--r--chromium/components/exo/wayland/zwp_relative_pointer_manager.h23
-rw-r--r--chromium/components/exo/wayland/zwp_text_input_manager.cc21
-rw-r--r--chromium/components/exo/wayland/zxdg_shell.cc1
-rw-r--r--chromium/components/exo/wm_helper_chromeos.cc6
-rw-r--r--chromium/components/favicon/content/content_favicon_driver.cc3
-rw-r--r--chromium/components/favicon/core/favicon_handler_unittest.cc1
-rw-r--r--chromium/components/favicon/core/favicon_server_fetcher_params.h10
-rw-r--r--chromium/components/favicon/core/favicon_service_impl.cc1
-rw-r--r--chromium/components/favicon/core/large_icon_service.h2
-rw-r--r--chromium/components/favicon/core/large_icon_service_impl.cc21
-rw-r--r--chromium/components/favicon/core/large_icon_service_impl_unittest.cc40
-rw-r--r--chromium/components/favicon/ios/web_favicon_driver.h2
-rw-r--r--chromium/components/favicon/ios/web_favicon_driver.mm2
-rw-r--r--chromium/components/feature_engagement/features.gni3
-rw-r--r--chromium/components/feature_engagement/internal/never_availability_model.cc1
-rw-r--r--chromium/components/feature_engagement/internal/persistent_event_store_unittest.cc1
-rw-r--r--chromium/components/feature_engagement/internal/tracker_impl.cc6
-rw-r--r--chromium/components/feature_engagement/internal/tracker_impl_unittest.cc4
-rw-r--r--chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java10
-rw-r--r--chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java89
-rw-r--r--chromium/components/feature_engagement/public/feature_constants.cc10
-rw-r--r--chromium/components/feature_engagement/public/feature_constants.h5
-rw-r--r--chromium/components/feature_engagement/public/feature_list.cc5
-rw-r--r--chromium/components/feature_engagement/public/feature_list.h14
-rw-r--r--chromium/components/feed/OWNERS1
-rw-r--r--chromium/components/feed/content/feed_host_service.cc6
-rw-r--r--chromium/components/feed/content/feed_host_service.h4
-rw-r--r--chromium/components/feed/content/feed_offline_host.cc8
-rw-r--r--chromium/components/feed/content/feed_offline_host_unittest.cc4
-rw-r--r--chromium/components/feed/core/BUILD.gn7
-rw-r--r--chromium/components/feed/core/feed_content_database.cc8
-rw-r--r--chromium/components/feed/core/feed_content_database_unittest.cc1
-rw-r--r--chromium/components/feed/core/feed_image_database.cc247
-rw-r--r--chromium/components/feed/core/feed_image_database.h136
-rw-r--r--chromium/components/feed/core/feed_image_database_unittest.cc302
-rw-r--r--chromium/components/feed/core/feed_image_manager.cc295
-rw-r--r--chromium/components/feed/core/feed_image_manager.h138
-rw-r--r--chromium/components/feed/core/feed_image_manager_unittest.cc1
-rw-r--r--chromium/components/feed/core/feed_journal_database.cc1
-rw-r--r--chromium/components/feed/core/feed_journal_database_unittest.cc1
-rw-r--r--chromium/components/feed/core/feed_logging_metrics.cc195
-rw-r--r--chromium/components/feed/core/feed_logging_metrics.h30
-rw-r--r--chromium/components/feed/core/feed_logging_metrics_unittest.cc51
-rw-r--r--chromium/components/feed/core/feed_networking_host.cc73
-rw-r--r--chromium/components/feed/core/feed_networking_host_unittest.cc1
-rw-r--r--chromium/components/feed/core/feed_scheduler_host.cc205
-rw-r--r--chromium/components/feed/core/feed_scheduler_host.h32
-rw-r--r--chromium/components/feed/core/feed_scheduler_host_unittest.cc28
-rw-r--r--chromium/components/feed/core/proto/BUILD.gn1
-rw-r--r--chromium/components/feed/core/proto/cached_image.proto20
-rw-r--r--chromium/components/feed/core/user_classifier_unittest.cc2
-rw-r--r--chromium/components/feedback/anonymizer_tool.cc106
-rw-r--r--chromium/components/feedback/anonymizer_tool_unittest.cc69
-rw-r--r--chromium/components/feedback/feedback_data.cc24
-rw-r--r--chromium/components/feedback/feedback_data.h16
-rw-r--r--chromium/components/feedback/feedback_data_unittest.cc3
-rw-r--r--chromium/components/feedback/feedback_report.cc1
-rw-r--r--chromium/components/feedback/feedback_uploader.cc5
-rw-r--r--chromium/components/feedback/feedback_uploader_dispatch_unittest.cc7
-rw-r--r--chromium/components/flags_ui/feature_entry.cc2
-rw-r--r--chromium/components/flags_ui/flags_state.cc2
-rw-r--r--chromium/components/flags_ui/resources/flags.css51
-rw-r--r--chromium/components/flags_ui/resources/flags.html6
-rw-r--r--chromium/components/flags_ui/resources/flags.js43
-rw-r--r--chromium/components/google/core/browser/google_url_tracker_unittest.cc1
-rw-r--r--chromium/components/google/core/browser/google_util_unittest.cc26
-rw-r--r--chromium/components/google/core/common/google_util.cc43
-rw-r--r--chromium/components/google/core/common/google_util.h8
-rw-r--r--chromium/components/grpc_support/bidirectional_stream.cc1
-rw-r--r--chromium/components/grpc_support/bidirectional_stream_c.cc1
-rw-r--r--chromium/components/grpc_support/bidirectional_stream_unittest.cc6
-rw-r--r--chromium/components/guest_view/browser/guest_view_base.cc3
-rw-r--r--chromium/components/guest_view/browser/test_guest_view_manager.cc2
-rw-r--r--chromium/components/guest_view/browser/test_guest_view_manager.h1
-rw-r--r--chromium/components/guest_view/renderer/guest_view_container.cc1
-rw-r--r--chromium/components/gwp_asan/BUILD.gn2
-rw-r--r--chromium/components/gwp_asan/buildflags/BUILD.gn11
-rw-r--r--chromium/components/gwp_asan/buildflags/buildflags.gni10
-rw-r--r--chromium/components/gwp_asan/client/guarded_page_allocator.cc110
-rw-r--r--chromium/components/gwp_asan/client/guarded_page_allocator.h11
-rw-r--r--chromium/components/gwp_asan/client/guarded_page_allocator_posix.cc10
-rw-r--r--chromium/components/gwp_asan/client/guarded_page_allocator_unittest.cc15
-rw-r--r--chromium/components/gwp_asan/client/guarded_page_allocator_win.cc2
-rw-r--r--chromium/components/gwp_asan/client/gwp_asan.cc70
-rw-r--r--chromium/components/gwp_asan/client/gwp_asan.h7
-rw-r--r--chromium/components/gwp_asan/client/sampling_allocator_shims.cc40
-rw-r--r--chromium/components/gwp_asan/client/sampling_allocator_shims_unittest.cc5
-rw-r--r--chromium/components/gwp_asan/common/BUILD.gn23
-rw-r--r--chromium/components/gwp_asan/common/allocator_state.cc13
-rw-r--r--chromium/components/gwp_asan/common/allocator_state.h36
-rw-r--r--chromium/components/gwp_asan/common/allocator_state_unittest.cc13
-rw-r--r--chromium/components/gwp_asan/common/pack_stack_trace.cc110
-rw-r--r--chromium/components/gwp_asan/common/pack_stack_trace.h40
-rw-r--r--chromium/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc47
-rw-r--r--chromium/components/gwp_asan/common/pack_stack_trace_unittest.cc98
-rw-r--r--chromium/components/gwp_asan/common/pack_stack_trace_unpack_fuzzer.cc27
-rw-r--r--chromium/components/gwp_asan/crash_handler/crash.proto4
-rw-r--r--chromium/components/gwp_asan/crash_handler/crash_analyzer.cc45
-rw-r--r--chromium/components/gwp_asan/crash_handler/crash_analyzer.h4
-rw-r--r--chromium/components/gwp_asan/crash_handler/crash_handler.cc33
-rw-r--r--chromium/components/gwp_asan/crash_handler/crash_handler_unittest.cc12
-rw-r--r--chromium/components/heap_profiling/client_connection_manager.cc1
-rw-r--r--chromium/components/heap_profiling/heap_profiling_test_shim.cc5
-rw-r--r--chromium/components/heap_profiling/heap_profiling_test_shim.h1
-rw-r--r--chromium/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java8
-rw-r--r--chromium/components/heap_profiling/supervisor.cc20
-rw-r--r--chromium/components/heap_profiling/supervisor.h2
-rw-r--r--chromium/components/heap_profiling/test_driver.cc12
-rw-r--r--chromium/components/heap_profiling/test_driver.h18
-rw-r--r--chromium/components/history/core/browser/browsing_history_service.cc1
-rw-r--r--chromium/components/history/core/browser/browsing_history_service_unittest.cc9
-rw-r--r--chromium/components/history/core/browser/expire_history_backend.cc36
-rw-r--r--chromium/components/history/core/browser/expire_history_backend.h8
-rw-r--r--chromium/components/history/core/browser/expire_history_backend_unittest.cc60
-rw-r--r--chromium/components/history/core/browser/history_backend.cc50
-rw-r--r--chromium/components/history/core/browser/history_backend.h10
-rw-r--r--chromium/components/history/core/browser/history_backend_db_unittest.cc1
-rw-r--r--chromium/components/history/core/browser/history_backend_unittest.cc23
-rw-r--r--chromium/components/history/core/browser/history_service.cc101
-rw-r--r--chromium/components/history/core/browser/history_service.h8
-rw-r--r--chromium/components/history/core/browser/history_service_unittest.cc106
-rw-r--r--chromium/components/history/core/browser/history_types.cc2
-rw-r--r--chromium/components/history/core/browser/sync/delete_directive_handler.cc73
-rw-r--r--chromium/components/history/core/browser/sync/delete_directive_handler.h4
-rw-r--r--chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc30
-rw-r--r--chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.h6
-rw-r--r--chromium/components/history/core/browser/sync/history_model_worker.cc1
-rw-r--r--chromium/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc3
-rw-r--r--chromium/components/history/core/browser/visit_database.cc2
-rw-r--r--chromium/components/history/core/browser/web_history_service.cc11
-rw-r--r--chromium/components/history/core/browser/web_history_service_unittest.cc1
-rw-r--r--chromium/components/history/ios/browser/web_state_top_sites_observer.h2
-rw-r--r--chromium/components/history/ios/browser/web_state_top_sites_observer.mm2
-rw-r--r--chromium/components/image_fetcher/OWNERS1
-rw-r--r--chromium/components/image_fetcher/core/BUILD.gn1
-rw-r--r--chromium/components/image_fetcher/core/cache/BUILD.gn1
-rw-r--r--chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.cc85
-rw-r--r--chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h26
-rw-r--r--chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter_unittest.cc163
-rw-r--r--chromium/components/image_fetcher/core/cache/image_cache.cc5
-rw-r--r--chromium/components/image_fetcher/core/cache/image_cache.h2
-rw-r--r--chromium/components/image_fetcher/core/cache/image_cache_unittest.cc74
-rw-r--r--chromium/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc54
-rw-r--r--chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc9
-rw-r--r--chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc104
-rw-r--r--chromium/components/image_fetcher/core/cached_image_fetcher.cc206
-rw-r--r--chromium/components/image_fetcher/core/cached_image_fetcher.h43
-rw-r--r--chromium/components/image_fetcher/core/cached_image_fetcher_service.cc22
-rw-r--r--chromium/components/image_fetcher/core/cached_image_fetcher_service.h17
-rw-r--r--chromium/components/image_fetcher/core/cached_image_fetcher_unittest.cc103
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher.cc21
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher.h5
-rw-r--r--chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc1
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher.cc23
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher.h126
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_impl.cc31
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_impl.h21
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_impl_unittest.cc70
-rw-r--r--chromium/components/image_fetcher/core/image_fetcher_types.h12
-rw-r--r--chromium/components/image_fetcher/core/mock_image_fetcher.cc9
-rw-r--r--chromium/components/image_fetcher/core/mock_image_fetcher.h24
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h2
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.mm4
-rw-r--r--chromium/components/image_fetcher/ios/ios_image_decoder_impl.mm1
-rw-r--r--chromium/components/infobars/core/infobar.cc2
-rw-r--r--chromium/components/invalidation/impl/BUILD.gn5
-rw-r--r--chromium/components/invalidation/public/BUILD.gn1
-rw-r--r--chromium/components/journey/journey_info_fetcher.cc1
-rw-r--r--chromium/components/journey/journey_info_json_request.cc6
-rw-r--r--chromium/components/keyed_service/DEPS1
-rw-r--r--chromium/components/keyed_service/OWNERS1
-rw-r--r--chromium/components/keyed_service/content/BUILD.gn1
-rw-r--r--chromium/components/keyed_service/content/browser_context_dependency_manager.cc2
-rw-r--r--chromium/components/keyed_service/content/browser_context_dependency_manager.h2
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc23
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_base_factory.h30
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc49
-rw-r--r--chromium/components/keyed_service/content/browser_context_keyed_service_factory.h28
-rw-r--r--chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc34
-rw-r--r--chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h17
-rw-r--r--chromium/components/keyed_service/core/BUILD.gn7
-rw-r--r--chromium/components/keyed_service/core/dependency_manager.cc14
-rw-r--r--chromium/components/keyed_service/core/dependency_manager.h17
-rw-r--r--chromium/components/keyed_service/core/keyed_service_base_factory.cc72
-rw-r--r--chromium/components/keyed_service/core/keyed_service_base_factory.h62
-rw-r--r--chromium/components/keyed_service/core/keyed_service_factory.cc43
-rw-r--r--chromium/components/keyed_service/core/keyed_service_factory.h49
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc48
-rw-r--r--chromium/components/keyed_service/core/refcounted_keyed_service_factory.h43
-rw-r--r--chromium/components/keyed_service/core/simple_dependency_manager.cc63
-rw-r--r--chromium/components/keyed_service/core/simple_dependency_manager.h47
-rw-r--r--chromium/components/keyed_service/core/simple_factory_key.cc11
-rw-r--r--chromium/components/keyed_service/core/simple_factory_key.h37
-rw-r--r--chromium/components/keyed_service/core/simple_keyed_service_factory.cc114
-rw-r--r--chromium/components/keyed_service/core/simple_keyed_service_factory.h118
-rw-r--r--chromium/components/keyed_service/ios/browser_state_dependency_manager.cc3
-rw-r--r--chromium/components/keyed_service/ios/browser_state_dependency_manager.h2
-rw-r--r--chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc40
-rw-r--r--chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h18
-rw-r--r--chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc35
-rw-r--r--chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h17
-rw-r--r--chromium/components/language/DEPS1
-rw-r--r--chromium/components/language/content/browser/geo_language_model_unittest.cc1
-rw-r--r--chromium/components/language/content/browser/geo_language_provider.cc2
-rw-r--r--chromium/components/language/content/browser/geo_language_provider_unittest.cc1
-rw-r--r--chromium/components/language/content/browser/language_code_locator.h2
-rw-r--r--chromium/components/language/content/browser/test_utils.h1
-rw-r--r--chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree.h4
-rw-r--r--chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree_datatest.cc3
-rw-r--r--chromium/components/language/core/browser/BUILD.gn3
-rw-r--r--chromium/components/language/core/browser/heuristic_language_model_unittest.cc24
-rw-r--r--chromium/components/language/core/browser/language_prefs.cc29
-rw-r--r--chromium/components/language/core/browser/language_prefs.h20
-rw-r--r--chromium/components/language/core/browser/pref_names.cc10
-rw-r--r--chromium/components/language/core/browser/pref_names.h6
-rw-r--r--chromium/components/language/core/common/BUILD.gn3
-rw-r--r--chromium/components/language/core/common/language_util.cc118
-rw-r--r--chromium/components/language/core/common/language_util.h24
-rw-r--r--chromium/components/language/core/common/language_util_unittest.cc65
-rw-r--r--chromium/components/language/ios/browser/ios_language_detection_tab_helper.h2
-rw-r--r--chromium/components/language/ios/browser/ios_language_detection_tab_helper.mm2
-rw-r--r--chromium/components/leveldb_proto/BUILD.gn10
-rw-r--r--chromium/components/leveldb_proto/OWNERS1
-rw-r--r--chromium/components/leveldb_proto/internal/leveldb_database.cc9
-rw-r--r--chromium/components/leveldb_proto/internal/leveldb_database.h1
-rw-r--r--chromium/components/leveldb_proto/internal/migration_delegate.cc63
-rw-r--r--chromium/components/leveldb_proto/internal/migration_delegate.h76
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_impl.cc46
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_impl.h540
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_impl_unittest.cc941
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_perftest.cc12
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_selector.cc572
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_selector.h166
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_wrapper.cc19
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_wrapper.h707
-rw-r--r--chromium/components/leveldb_proto/internal/proto_database_wrapper_unittest.cc562
-rw-r--r--chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.cc257
-rw-r--r--chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.h376
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database.cc193
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database.h132
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_client.cc232
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_client.h342
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc20
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc411
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_provider.cc3
-rw-r--r--chromium/components/leveldb_proto/internal/shared_proto_database_unittest.cc49
-rw-r--r--chromium/components/leveldb_proto/internal/unique_proto_database.cc167
-rw-r--r--chromium/components/leveldb_proto/internal/unique_proto_database.h302
-rw-r--r--chromium/components/leveldb_proto/internal/unique_proto_database_unittest.cc54
-rw-r--r--chromium/components/leveldb_proto/public/proto_database.h16
-rw-r--r--chromium/components/leveldb_proto/public/proto_database_provider.cc2
-rw-r--r--chromium/components/leveldb_proto/public/proto_database_provider.h24
-rw-r--r--chromium/components/leveldb_proto/public/shared_proto_database_client_list.cc45
-rw-r--r--chromium/components/leveldb_proto/public/shared_proto_database_client_list.h38
-rw-r--r--chromium/components/leveldb_proto/testing/fake_db.h28
-rw-r--r--chromium/components/link_header_util/link_header_util_unittest.cc6
-rw-r--r--chromium/components/management_strings.grdp150
-rw-r--r--chromium/components/metrics/BUILD.gn4
-rw-r--r--chromium/components/metrics/DEPS1
-rw-r--r--chromium/components/metrics/call_stack_profile_builder.cc43
-rw-r--r--chromium/components/metrics/call_stack_profile_builder.h30
-rw-r--r--chromium/components/metrics/call_stack_profile_builder_unittest.cc145
-rw-r--r--chromium/components/metrics/drive_metrics_provider.cc3
-rw-r--r--chromium/components/metrics/enabled_state_provider.cc10
-rw-r--r--chromium/components/metrics/file_metrics_provider.cc30
-rw-r--r--chromium/components/metrics/file_metrics_provider_unittest.cc8
-rw-r--r--chromium/components/metrics/legacy_call_stack_profile_builder.cc356
-rw-r--r--chromium/components/metrics/legacy_call_stack_profile_builder.h164
-rw-r--r--chromium/components/metrics/legacy_call_stack_profile_builder_unittest.cc427
-rw-r--r--chromium/components/metrics/machine_id_provider_win.cc3
-rw-r--r--chromium/components/metrics/metrics_reporting_service.cc4
-rw-r--r--chromium/components/metrics/metrics_reporting_service.h4
-rw-r--r--chromium/components/metrics/metrics_service.h5
-rw-r--r--chromium/components/metrics/metrics_service_accessor.cc7
-rw-r--r--chromium/components/metrics/metrics_service_client.cc8
-rw-r--r--chromium/components/metrics/metrics_service_client.h9
-rw-r--r--chromium/components/metrics/metrics_service_unittest.cc2
-rw-r--r--chromium/components/metrics/metrics_state_manager.cc58
-rw-r--r--chromium/components/metrics/metrics_state_manager.h27
-rw-r--r--chromium/components/metrics/metrics_state_manager_unittest.cc145
-rw-r--r--chromium/components/metrics/net/net_metrics_log_uploader.cc7
-rw-r--r--chromium/components/metrics/net/net_metrics_log_uploader.h6
-rw-r--r--chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc8
-rw-r--r--chromium/components/metrics/net/network_metrics_provider.cc1
-rw-r--r--chromium/components/metrics/net/network_metrics_provider_unittest.cc14
-rw-r--r--chromium/components/metrics/persisted_logs.cc6
-rw-r--r--chromium/components/metrics/persisted_logs_metrics.h2
-rw-r--r--chromium/components/metrics/reporting_service.h7
-rw-r--r--chromium/components/metrics/reporting_service_unittest.cc4
-rw-r--r--chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc1
-rw-r--r--chromium/components/metrics/stability_metrics_helper.cc6
-rw-r--r--chromium/components/metrics/test_metrics_service_client.cc4
-rw-r--r--chromium/components/metrics/test_metrics_service_client.h4
-rw-r--r--chromium/components/metrics_services_manager/metrics_services_manager.cc1
-rw-r--r--chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadCallable.java38
-rw-r--r--chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploaderImpl.java8
-rw-r--r--chromium/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java38
-rw-r--r--chromium/components/mirroring/OWNERS1
-rw-r--r--chromium/components/mirroring/browser/single_client_video_capture_host.cc18
-rw-r--r--chromium/components/mirroring/browser/single_client_video_capture_host.h4
-rw-r--r--chromium/components/mirroring/browser/single_client_video_capture_host_unittest.cc1
-rw-r--r--chromium/components/mirroring/service/BUILD.gn20
-rw-r--r--chromium/components/mirroring/service/OWNERS6
-rw-r--r--chromium/components/mirroring/service/captured_audio_input.cc1
-rw-r--r--chromium/components/mirroring/service/captured_audio_input_unittest.cc2
-rw-r--r--chromium/components/mirroring/service/fake_video_capture_host.cc1
-rw-r--r--chromium/components/mirroring/service/fake_video_capture_host.h5
-rw-r--r--chromium/components/mirroring/service/manifest.cc32
-rw-r--r--chromium/components/mirroring/service/manifest.h16
-rw-r--r--chromium/components/mirroring/service/manifest.json18
-rw-r--r--chromium/components/mirroring/service/media_remoter.cc1
-rw-r--r--chromium/components/mirroring/service/media_remoter.h1
-rw-r--r--chromium/components/mirroring/service/message_dispatcher.cc2
-rw-r--r--chromium/components/mirroring/service/mirroring_service.cc1
-rw-r--r--chromium/components/mirroring/service/receiver_response.cc3
-rw-r--r--chromium/components/mirroring/service/receiver_response_unittest.cc2
-rw-r--r--chromium/components/mirroring/service/session.cc1
-rw-r--r--chromium/components/mirroring/service/session.h1
-rw-r--r--chromium/components/mirroring/service/session_monitor.cc4
-rw-r--r--chromium/components/mirroring/service/session_monitor_unittest.cc2
-rw-r--r--chromium/components/mirroring/service/session_unittest.cc2
-rw-r--r--chromium/components/mirroring/service/udp_socket_client.cc1
-rw-r--r--chromium/components/mirroring/service/video_capture_client.cc2
-rw-r--r--chromium/components/mirroring/service/video_capture_client_unittest.cc8
-rw-r--r--chromium/components/mirroring/service/wifi_status_monitor_unittest.cc2
-rw-r--r--chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java70
-rw-r--r--chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java11
-rw-r--r--chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java3
-rw-r--r--chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java5
-rw-r--r--chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java5
-rw-r--r--chromium/components/nacl/broker/BUILD.gn15
-rw-r--r--chromium/components/nacl/loader/BUILD.gn15
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_delegate.cc7
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_delegate.h4
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_throttle.cc30
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_throttle.h16
-rw-r--r--chromium/components/navigation_interception/intercept_navigation_throttle_unittest.cc9
-rw-r--r--chromium/components/net_log/net_export_file_writer.cc1
-rw-r--r--chromium/components/net_log/net_export_file_writer_unittest.cc4
-rw-r--r--chromium/components/neterror/resources/neterror.css2
-rw-r--r--chromium/components/neterror/resources/neterror.html6
-rw-r--r--chromium/components/neterror/resources/neterror.js32
-rw-r--r--chromium/components/network_hints/browser/network_hints_message_filter.cc1
-rw-r--r--chromium/components/network_hints/renderer/dns_prefetch_queue_unittest.cc2
-rw-r--r--chromium/components/network_session_configurator/browser/network_session_configurator.cc49
-rw-r--r--chromium/components/network_session_configurator/browser/network_session_configurator_unittest.cc31
-rw-r--r--chromium/components/network_time/network_time_test_utils.cc2
-rw-r--r--chromium/components/network_time/network_time_test_utils.h2
-rw-r--r--chromium/components/network_time/network_time_tracker.cc6
-rw-r--r--chromium/components/network_time/network_time_tracker_unittest.cc1
-rw-r--r--chromium/components/ntp_snippets/BUILD.gn1
-rw-r--r--chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc2
-rw-r--r--chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils_unittest.cc9
-rw-r--r--chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.cc1
-rw-r--r--chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler_unittest.cc5
-rw-r--r--chromium/components/ntp_snippets/breaking_news/subscription_json_request.cc5
-rw-r--r--chromium/components/ntp_snippets/breaking_news/subscription_json_request_unittest.cc8
-rw-r--r--chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.cc4
-rw-r--r--chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.h4
-rw-r--r--chromium/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc2
-rw-r--r--chromium/components/ntp_snippets/category_rankers/click_based_category_ranker.cc8
-rw-r--r--chromium/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc4
-rw-r--r--chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc2
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_service.cc4
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_service.h4
-rw-r--r--chromium/components/ntp_snippets/content_suggestions_service_unittest.cc4
-rw-r--r--chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc7
-rw-r--r--chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc5
-rw-r--r--chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc1
-rw-r--r--chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc1
-rw-r--r--chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc4
-rw-r--r--chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc3
-rw-r--r--chromium/components/ntp_snippets/features.cc5
-rw-r--r--chromium/components/ntp_snippets/features.h3
-rw-r--r--chromium/components/ntp_snippets/logger_unittest.cc2
-rw-r--r--chromium/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc2
-rw-r--r--chromium/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc2
-rw-r--r--chromium/components/ntp_snippets/remote/cached_image_fetcher.cc24
-rw-r--r--chromium/components/ntp_snippets/remote/cached_image_fetcher.h4
-rw-r--r--chromium/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc25
-rw-r--r--chromium/components/ntp_snippets/remote/json_request.cc5
-rw-r--r--chromium/components/ntp_snippets/remote/json_request_unittest.cc12
-rw-r--r--chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc8
-rw-r--r--chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc13
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestion_unittest.cc4
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_database.cc1
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc34
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h8
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc3
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc48
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_scheduler_impl_unittest.cc8
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc1
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc1
-rw-r--r--chromium/components/ntp_snippets/user_classifier_unittest.cc2
-rw-r--r--chromium/components/ntp_tiles/BUILD.gn1
-rw-r--r--chromium/components/ntp_tiles/custom_links_manager_impl.cc1
-rw-r--r--chromium/components/ntp_tiles/custom_links_manager_impl_unittest.cc47
-rw-r--r--chromium/components/ntp_tiles/custom_links_store.cc11
-rw-r--r--chromium/components/ntp_tiles/custom_links_store_unittest.cc54
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl.cc17
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl.h1
-rw-r--r--chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc124
-rw-r--r--chromium/components/ntp_tiles/json_unsafe_parser.cc2
-rw-r--r--chromium/components/ntp_tiles/most_visited_sites.cc3
-rw-r--r--chromium/components/ntp_tiles/most_visited_sites_unittest.cc25
-rw-r--r--chromium/components/ntp_tiles/ntp_tile.cc3
-rw-r--r--chromium/components/ntp_tiles/ntp_tile.h4
-rw-r--r--chromium/components/ntp_tiles/popular_sites_impl.cc10
-rw-r--r--chromium/components/ntp_tiles/tile_source.h3
-rw-r--r--chromium/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc6
-rw-r--r--chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html22
-rw-r--r--chromium/components/offline_items_collection/core/BUILD.gn2
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_aggregator.cc2
-rw-r--r--chromium/components/offline_items_collection/core/offline_content_aggregator_unittest.cc1
-rw-r--r--chromium/components/offline_items_collection/core/rename_result.h19
-rw-r--r--chromium/components/offline_items_collection/core/throttled_offline_content_provider_unittest.cc1
-rw-r--r--chromium/components/offline_pages/content/background_loader/DEPS1
-rw-r--r--chromium/components/offline_pages/content/background_loader/background_loader_contents_unittest.cc6
-rw-r--r--chromium/components/offline_pages/content/renovations/render_frame_script_injector.cc1
-rw-r--r--chromium/components/offline_pages/core/BUILD.gn3
-rw-r--r--chromium/components/offline_pages/core/background/BUILD.gn3
-rw-r--r--chromium/components/offline_pages/core/background/add_request_task.cc37
-rw-r--r--chromium/components/offline_pages/core/background/add_request_task.h46
-rw-r--r--chromium/components/offline_pages/core/background/add_request_task_unittest.cc184
-rw-r--r--chromium/components/offline_pages/core/background/change_requests_state_task_unittest.cc10
-rw-r--r--chromium/components/offline_pages/core/background/cleanup_task_unittest.cc16
-rw-r--r--chromium/components/offline_pages/core/background/get_requests_task_unittest.cc18
-rw-r--r--chromium/components/offline_pages/core/background/mark_attempt_aborted_task_unittest.cc8
-rw-r--r--chromium/components/offline_pages/core/background/mark_attempt_completed_task_unittest.cc11
-rw-r--r--chromium/components/offline_pages/core/background/mark_attempt_started_task_unittest.cc13
-rw-r--r--chromium/components/offline_pages/core/background/offliner_client.cc1
-rw-r--r--chromium/components/offline_pages/core/background/pending_state_updater.cc1
-rw-r--r--chromium/components/offline_pages/core/background/pick_request_task_unittest.cc12
-rw-r--r--chromium/components/offline_pages/core/background/reconcile_task_unittest.cc16
-rw-r--r--chromium/components/offline_pages/core/background/remove_requests_task_unittest.cc18
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator.cc10
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator.h3
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator_stub_taco.cc1
-rw-r--r--chromium/components/offline_pages/core/background/request_coordinator_unittest.cc15
-rw-r--r--chromium/components/offline_pages/core/background/request_queue.cc38
-rw-r--r--chromium/components/offline_pages/core/background/request_queue.h16
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_results.h2
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_store.cc52
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_store.h7
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_store_unittest.cc50
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_task_test_base.cc1
-rw-r--r--chromium/components/offline_pages/core/background/request_queue_unittest.cc43
-rw-r--r--chromium/components/offline_pages/core/background/test_request_queue_store.cc1
-rw-r--r--chromium/components/offline_pages/core/downloads/download_ui_adapter.cc36
-rw-r--r--chromium/components/offline_pages/core/downloads/download_ui_adapter.h3
-rw-r--r--chromium/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc3
-rw-r--r--chromium/components/offline_pages/core/downloads/offline_item_conversions.cc5
-rw-r--r--chromium/components/offline_pages/core/downloads/offline_item_conversions_unittest.cc20
-rw-r--r--chromium/components/offline_pages/core/model/add_page_task.cc2
-rw-r--r--chromium/components/offline_pages/core/model/add_page_task_unittest.cc2
-rw-r--r--chromium/components/offline_pages/core/model/cleanup_thumbnails_task.cc1
-rw-r--r--chromium/components/offline_pages/core/model/cleanup_thumbnails_task_unittest.cc4
-rw-r--r--chromium/components/offline_pages/core/model/clear_digest_task.cc2
-rw-r--r--chromium/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc1
-rw-r--r--chromium/components/offline_pages/core/model/delete_page_task.cc72
-rw-r--r--chromium/components/offline_pages/core/model/delete_page_task_unittest.cc34
-rw-r--r--chromium/components/offline_pages/core/model/get_pages_task.cc6
-rw-r--r--chromium/components/offline_pages/core/model/get_pages_task_unittest.cc1
-rw-r--r--chromium/components/offline_pages/core/model/get_thumbnail_task.cc1
-rw-r--r--chromium/components/offline_pages/core/model/get_thumbnail_task_unittest.cc3
-rw-r--r--chromium/components/offline_pages/core/model/has_thumbnail_task.cc1
-rw-r--r--chromium/components/offline_pages/core/model/has_thumbnail_task_unittest.cc3
-rw-r--r--chromium/components/offline_pages/core/model/mark_page_accessed_task.cc2
-rw-r--r--chromium/components/offline_pages/core/model/offline_page_item_generator.cc4
-rw-r--r--chromium/components/offline_pages/core/model/offline_page_model_taskified.cc8
-rw-r--r--chromium/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc6
-rw-r--r--chromium/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc1
-rw-r--r--chromium/components/offline_pages/core/model/store_thumbnail_task.cc1
-rw-r--r--chromium/components/offline_pages/core/model/store_thumbnail_task_unittest.cc3
-rw-r--r--chromium/components/offline_pages/core/model/update_file_path_task.cc2
-rw-r--r--chromium/components/offline_pages/core/model/update_file_path_task_unittest.cc1
-rw-r--r--chromium/components/offline_pages/core/offline_page_archiver_unittest.cc1
-rw-r--r--chromium/components/offline_pages/core/offline_page_client_policy.h2
-rw-r--r--chromium/components/offline_pages/core/offline_page_feature.cc14
-rw-r--r--chromium/components/offline_pages/core/offline_page_feature.h8
-rw-r--r--chromium/components/offline_pages/core/offline_page_feature_unittest.cc20
-rw-r--r--chromium/components/offline_pages/core/offline_page_item.cc3
-rw-r--r--chromium/components/offline_pages/core/offline_page_item.h7
-rw-r--r--chromium/components/offline_pages/core/offline_page_item_utils.cc20
-rw-r--r--chromium/components/offline_pages/core/offline_page_item_utils.h18
-rw-r--r--chromium/components/offline_pages/core/offline_page_item_utils_unittest.cc27
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store.cc179
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store.h160
-rw-r--r--chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc41
-rw-r--r--chromium/components/offline_pages/core/offline_page_model.h9
-rw-r--r--chromium/components/offline_pages/core/offline_page_thumbnail.cc4
-rw-r--r--chromium/components/offline_pages/core/prefetch/fake_suggestions_provider.cc1
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc4
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h1
-rw-r--r--chromium/components/offline_pages/core/prefetch/generate_page_bundle_request_unittest.cc36
-rw-r--r--chromium/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc17
-rw-r--r--chromium/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h3
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc2
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc28
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc2
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_importer_impl.cc2
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc3
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc4
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_prefs.cc18
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_prefs.h12
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_prefs_unittest.cc15
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc17
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h2
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc4
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_request_operation_response_unittest.cc4
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_server_urls.cc1
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_server_urls.h1
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc6
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h5
-rw-r--r--chromium/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc2
-rw-r--r--chromium/components/offline_pages/core/prefetch/store/prefetch_store.cc156
-rw-r--r--chromium/components/offline_pages/core/prefetch/store/prefetch_store.h149
-rw-r--r--chromium/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc3
-rw-r--r--chromium/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc29
-rw-r--r--chromium/components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.cc1
-rw-r--r--chromium/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc1
-rw-r--r--chromium/components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc16
-rw-r--r--chromium/components/offline_pages/core/prefetch/thumbnail_fetcher.h20
-rw-r--r--chromium/components/offline_pages/task/BUILD.gn3
-rw-r--r--chromium/components/offline_pages/task/DEPS3
-rw-r--r--chromium/components/offline_pages/task/sql_store_base.cc201
-rw-r--r--chromium/components/offline_pages/task/sql_store_base.h190
-rw-r--r--chromium/components/omnibox/browser/BUILD.gn17
-rw-r--r--chromium/components/omnibox/common/BUILD.gn5
-rw-r--r--chromium/components/omnibox_strings.grdp44
-rw-r--r--chromium/components/open_from_clipboard/BUILD.gn11
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content.cc18
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content_features.cc11
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content_features.h15
-rw-r--r--chromium/components/open_from_clipboard/clipboard_recent_content_impl_ios.h2
-rw-r--r--chromium/components/optimization_guide/OWNERS2
-rw-r--r--chromium/components/optimization_guide/optimization_guide_service.h2
-rw-r--r--chromium/components/optimization_guide/proto/hints.proto97
-rw-r--r--chromium/components/optimization_guide/test_hints_component_creator.cc2
-rw-r--r--chromium/components/os_crypt/key_storage_kwallet_unittest.cc6
-rw-r--r--chromium/components/os_crypt/key_storage_linux_unittest.cc6
-rw-r--r--chromium/components/os_crypt/kwallet_dbus_unittest.cc9
-rw-r--r--chromium/components/os_crypt/libsecret_util_linux.cc2
-rw-r--r--chromium/components/os_crypt/os_crypt_linux_unittest.cc2
-rw-r--r--chromium/components/os_crypt/os_crypt_unittest.cc2
-rw-r--r--chromium/components/page_image_annotation/content/renderer/BUILD.gn4
-rw-r--r--chromium/components/page_image_annotation/core/page_annotator.cc1
-rw-r--r--chromium/components/page_image_annotation/core/page_annotator_unittest.cc8
-rw-r--r--chromium/components/page_info_strings.grdp19
-rw-r--r--chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_PRESENTING_TEXT.png.sha11
-rw-r--r--chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_TURN_OFF_BUTTON_TEXT.png.sha11
-rw-r--r--chromium/components/pairing/BUILD.gn2
-rw-r--r--chromium/components/pairing/bluetooth_host_pairing_controller.cc1
-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_unittest.cc7
-rw-r--r--chromium/components/password_manager/core/browser/BUILD.gn3
-rw-r--r--chromium/components/password_manager/core/browser/DEPS1
-rw-r--r--chromium/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc1
-rw-r--r--chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetch_throttler.cc1
-rw-r--r--chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc1
-rw-r--r--chromium/components/password_manager/core/browser/browser_save_password_progress_logger.cc26
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_impl.cc1
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_password_form_manager.cc1
-rw-r--r--chromium/components/password_manager/core/browser/credential_manager_pending_request_task.cc1
-rw-r--r--chromium/components/password_manager/core/browser/credentials_filter.h5
-rw-r--r--chromium/components/password_manager/core/browser/export/password_manager_exporter.cc1
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher_impl.cc3
-rw-r--r--chromium/components/password_manager/core/browser/form_fetcher_impl_unittest.cc17
-rw-r--r--chromium/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc2
-rw-r--r--chromium/components/password_manager/core/browser/form_parsing/ios_form_parser_unittest.cc8
-rw-r--r--chromium/components/password_manager/core/browser/http_credentials_cleaner.cc1
-rw-r--r--chromium/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc6
-rw-r--r--chromium/components/password_manager/core/browser/http_password_store_migrator.cc1
-rw-r--r--chromium/components/password_manager/core/browser/import/csv_reader.cc29
-rw-r--r--chromium/components/password_manager/core/browser/import/csv_reader.h3
-rw-r--r--chromium/components/password_manager/core/browser/import/csv_reader_unittest.cc18
-rw-r--r--chromium/components/password_manager/core/browser/login_database.cc154
-rw-r--r--chromium/components/password_manager/core/browser/login_database.h40
-rw-r--r--chromium/components/password_manager/core/browser/login_database_unittest.cc36
-rw-r--r--chromium/components/password_manager/core/browser/mock_password_store.h4
-rw-r--r--chromium/components/password_manager/core/browser/new_password_form_manager.cc6
-rw-r--r--chromium/components/password_manager/core/browser/new_password_form_manager_unittest.cc6
-rw-r--r--chromium/components/password_manager/core/browser/password_autofill_manager.cc3
-rw-r--r--chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc36
-rw-r--r--chromium/components/password_manager/core/browser/password_manager.cc69
-rw-r--r--chromium/components/password_manager/core/browser/password_manager.h34
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_unittest.cc5
-rw-r--r--chromium/components/password_manager/core/browser/password_manager_util.cc1
-rw-r--r--chromium/components/password_manager/core/browser/password_store.cc1
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default.cc10
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default.h5
-rw-r--r--chromium/components/password_manager/core/browser/password_store_default_unittest.cc6
-rw-r--r--chromium/components/password_manager/core/browser/password_store_origin_unittest.h5
-rw-r--r--chromium/components/password_manager/core/browser/password_store_signin_notifier.cc11
-rw-r--r--chromium/components/password_manager/core/browser/password_store_signin_notifier.h3
-rw-r--r--chromium/components/password_manager/core/browser/password_store_sync.h27
-rw-r--r--chromium/components/password_manager/core/browser/site_affiliation/asset_link_data.cc2
-rw-r--r--chromium/components/password_manager/core/browser/stub_credentials_filter.cc10
-rw-r--r--chromium/components/password_manager/core/browser/stub_credentials_filter.h9
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_model_type_controller.cc12
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_model_type_controller.h8
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_model_worker.cc1
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_sync_bridge.cc497
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_sync_bridge.h19
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc554
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.cc237
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h75
-rw-r--r--chromium/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc1
-rw-r--r--chromium/components/password_manager/core/browser/sync_credentials_filter.cc77
-rw-r--r--chromium/components/password_manager/core/browser/sync_credentials_filter.h12
-rw-r--r--chromium/components/password_manager/core/browser/sync_credentials_filter_unittest.cc212
-rw-r--r--chromium/components/password_manager/core/browser/test_password_store.cc8
-rw-r--r--chromium/components/password_manager/core/browser/test_password_store.h5
-rw-r--r--chromium/components/password_manager/core/browser/votes_uploader.cc9
-rw-r--r--chromium/components/password_manager/core/browser/votes_uploader.h9
-rw-r--r--chromium/components/password_manager/core/browser/votes_uploader_unittest.cc2
-rw-r--r--chromium/components/password_manager/core/common/credential_manager_types.cc2
-rw-r--r--chromium/components/password_manager/core/common/password_manager_features.cc21
-rw-r--r--chromium/components/password_manager/core/common/password_manager_features.h4
-rw-r--r--chromium/components/password_manager/core/common/passwords_directory_util_ios.cc3
-rw-r--r--chromium/components/password_manager/ios/password_form_helper.h9
-rw-r--r--chromium/components/password_manager/ios/password_form_helper.mm40
-rw-r--r--chromium/components/password_manager/ios/password_form_helper_unittest.mm49
-rw-r--r--chromium/components/password_manager/ios/resources/password_controller.js28
-rw-r--r--chromium/components/payments/content/BUILD.gn2
-rw-r--r--chromium/components/payments/content/android/payment_manifest_downloader_android.cc1
-rw-r--r--chromium/components/payments/content/content_payment_request_delegate.h4
-rw-r--r--chromium/components/payments/content/initialization_task.cc31
-rw-r--r--chromium/components/payments/content/initialization_task.h105
-rw-r--r--chromium/components/payments/content/installable_payment_app_crawler.cc1
-rw-r--r--chromium/components/payments/content/payment_request.cc73
-rw-r--r--chromium/components/payments/content/payment_request.h9
-rw-r--r--chromium/components/payments/content/payment_request_spec.cc9
-rw-r--r--chromium/components/payments/content/payment_request_state.cc41
-rw-r--r--chromium/components/payments/content/payment_request_state.h16
-rw-r--r--chromium/components/payments/content/payment_request_state_unittest.cc103
-rw-r--r--chromium/components/payments/content/payment_response_helper_unittest.cc5
-rw-r--r--chromium/components/payments/content/service_worker_payment_app_factory.cc1
-rw-r--r--chromium/components/payments/content/service_worker_payment_instrument.cc49
-rw-r--r--chromium/components/payments/content/service_worker_payment_instrument.h7
-rw-r--r--chromium/components/payments/content/service_worker_payment_instrument_unittest.cc19
-rw-r--r--chromium/components/payments/content/test_content_payment_request_delegate.cc4
-rw-r--r--chromium/components/payments/content/test_content_payment_request_delegate.h1
-rw-r--r--chromium/components/payments/content/utility/payment_manifest_parser_unittest.cc14
-rw-r--r--chromium/components/payments/content/utility/payment_method_manifest_parser_fuzzer.cc3
-rw-r--r--chromium/components/payments/content/utility/payment_web_app_manifest_parser_fuzzer.cc3
-rw-r--r--chromium/components/payments/core/can_make_payment_query.cc101
-rw-r--r--chromium/components/payments/core/can_make_payment_query.h14
-rw-r--r--chromium/components/payments/core/can_make_payment_query_unittest.cc168
-rw-r--r--chromium/components/payments/core/currency_formatter_unittest.cc2
-rw-r--r--chromium/components/payments/core/features.cc4
-rw-r--r--chromium/components/payments/core/journey_logger.cc8
-rw-r--r--chromium/components/payments/core/journey_logger.h11
-rw-r--r--chromium/components/payments/core/payment_address.cc2
-rw-r--r--chromium/components/payments/core/payment_address_unittest.cc7
-rw-r--r--chromium/components/payments/core/payment_details_validation_unittest.cc4
-rw-r--r--chromium/components/payments/core/payment_instrument.h1
-rw-r--r--chromium/components/payments/core/payment_manifest_downloader.cc1
-rw-r--r--chromium/components/payments/core/payment_manifest_downloader_unittest.cc1
-rw-r--r--chromium/components/payments/core/payment_request_data_util.cc7
-rw-r--r--chromium/components/payments/core/payment_request_data_util_unittest.cc2
-rw-r--r--chromium/components/payments/core/payments_validators.cc43
-rw-r--r--chromium/components/payments/core/payments_validators.h13
-rw-r--r--chromium/components/payments/core/payments_validators_unittest.cc141
-rw-r--r--chromium/components/payments/mojom/payment_request_data.mojom11
-rw-r--r--chromium/components/pdf/browser/pdf_web_contents_helper.cc8
-rw-r--r--chromium/components/pdf/browser/pdf_web_contents_helper.h4
-rw-r--r--chromium/components/pdf/browser/pdf_web_contents_helper_client.h8
-rw-r--r--chromium/components/pdf/common/pdf.mojom3
-rw-r--r--chromium/components/pdf/renderer/pdf_accessibility_tree.h2
-rw-r--r--chromium/components/pdf/renderer/pepper_pdf_host.cc13
-rw-r--r--chromium/components/pdf/renderer/pepper_pdf_host.h2
-rw-r--r--chromium/components/pdf_strings.grdp25
-rw-r--r--chromium/components/plugins/renderer/webview_plugin.cc10
-rw-r--r--chromium/components/plugins/renderer/webview_plugin.h2
-rw-r--r--chromium/components/policy/BUILD.gn11
-rw-r--r--chromium/components/policy/content/BUILD.gn2
-rw-r--r--chromium/components/policy/core/common/BUILD.gn3
-rw-r--r--chromium/components/policy/proto/BUILD.gn5
-rw-r--r--chromium/components/policy_strings.grdp109
-rw-r--r--chromium/components/pref_registry/pref_registry_syncable.cc1
-rw-r--r--chromium/components/pref_registry/pref_registry_syncable.h5
-rw-r--r--chromium/components/prefs/default_pref_store.cc5
-rw-r--r--chromium/components/prefs/default_pref_store.h6
-rw-r--r--chromium/components/prefs/default_pref_store_unittest.cc9
-rw-r--r--chromium/components/prefs/in_memory_pref_store.cc5
-rw-r--r--chromium/components/prefs/json_pref_store_unittest.cc14
-rw-r--r--chromium/components/prefs/pref_member_unittest.cc3
-rw-r--r--chromium/components/prefs/pref_registry.cc24
-rw-r--r--chromium/components/prefs/pref_registry.h6
-rw-r--r--chromium/components/prefs/pref_registry_simple.cc42
-rw-r--r--chromium/components/prefs/pref_registry_simple.h4
-rw-r--r--chromium/components/prefs/pref_service.cc2
-rw-r--r--chromium/components/prefs/pref_service_factory.cc1
-rw-r--r--chromium/components/prefs/pref_service_unittest.cc2
-rw-r--r--chromium/components/prefs/pref_value_map.cc6
-rw-r--r--chromium/components/prefs/pref_value_map.h5
-rw-r--r--chromium/components/prefs/pref_value_map_unittest.cc38
-rw-r--r--chromium/components/prefs/scoped_user_pref_update_unittest.cc15
-rw-r--r--chromium/components/prefs/testing_pref_store.cc9
-rw-r--r--chromium/components/prefs/value_map_pref_store.cc6
-rw-r--r--chromium/components/previews/DEPS7
-rw-r--r--chromium/components/previews/content/BUILD.gn6
-rw-r--r--chromium/components/previews/content/DEPS1
-rw-r--r--chromium/components/previews/content/hint_cache_leveldb_store.cc1
-rw-r--r--chromium/components/previews/content/hints_fetcher.cc63
-rw-r--r--chromium/components/previews/content/hints_fetcher.h78
-rw-r--r--chromium/components/previews/content/previews_content_util.cc228
-rw-r--r--chromium/components/previews/content/previews_content_util.h50
-rw-r--r--chromium/components/previews/content/previews_content_util_unittest.cc490
-rw-r--r--chromium/components/previews/content/previews_decider_impl.cc73
-rw-r--r--chromium/components/previews/content/previews_decider_impl.h8
-rw-r--r--chromium/components/previews/content/previews_decider_impl_unittest.cc83
-rw-r--r--chromium/components/previews/content/previews_hints.cc43
-rw-r--r--chromium/components/previews/content/previews_hints_unittest.cc61
-rw-r--r--chromium/components/previews/content/previews_optimization_guide.cc81
-rw-r--r--chromium/components/previews/content/previews_optimization_guide.h37
-rw-r--r--chromium/components/previews/content/previews_optimization_guide_unittest.cc63
-rw-r--r--chromium/components/previews/content/previews_top_host_provider.h27
-rw-r--r--chromium/components/previews/content/previews_ui_service_unittest.cc1
-rw-r--r--chromium/components/previews/content/proto/BUILD.gn18
-rw-r--r--chromium/components/previews/content/proto/hints_header_include.h12
-rw-r--r--chromium/components/previews/core/bloom_filter.h2
-rw-r--r--chromium/components/previews/core/previews_black_list_unittest.cc12
-rw-r--r--chromium/components/previews/core/previews_experiments.cc9
-rw-r--r--chromium/components/previews/core/previews_experiments.h8
-rw-r--r--chromium/components/previews/core/previews_features.cc18
-rw-r--r--chromium/components/previews/core/previews_features.h2
-rw-r--r--chromium/components/previews/core/previews_logger_unittest.cc2
-rw-r--r--chromium/components/print_media_strings.grdp497
-rw-r--r--chromium/components/printing/browser/BUILD.gn25
-rw-r--r--chromium/components/printing/browser/print_media_l10n.cc206
-rw-r--r--chromium/components/printing/browser/print_media_l10n.h17
-rw-r--r--chromium/components/printing/browser/print_media_l10n_unittest.cc60
-rw-r--r--chromium/components/printing/browser/printer_capabilities.cc27
-rw-r--r--chromium/components/printing/browser/printer_capabilities_mac.mm3
-rw-r--r--chromium/components/printing/common/cloud_print_cdd_conversion.cc29
-rw-r--r--chromium/components/printing/renderer/BUILD.gn8
-rw-r--r--chromium/components/printing/renderer/print_render_frame_helper.cc27
-rw-r--r--chromium/components/printing/renderer/print_render_frame_helper.h5
-rw-r--r--chromium/components/printing/renderer/print_render_frame_helper_android.cc7
-rw-r--r--chromium/components/printing/renderer/print_render_frame_helper_linux.cc1
-rw-r--r--chromium/components/printing/renderer/print_render_frame_helper_mac.mm3
-rw-r--r--chromium/components/proxy_config/pref_proxy_config_tracker_impl.cc10
-rw-r--r--chromium/components/query_parser/query_parser.cc2
-rw-r--r--chromium/components/query_parser/snippet_unittest.cc26
-rw-r--r--chromium/components/quirks/quirks_client.cc3
-rw-r--r--chromium/components/quirks/quirks_manager.cc1
-rw-r--r--chromium/components/rappor/bloom_filter.h2
-rw-r--r--chromium/components/rappor/log_uploader.cc1
-rw-r--r--chromium/components/rappor/log_uploader_interface.h4
-rw-r--r--chromium/components/rappor/log_uploader_unittest.cc13
-rw-r--r--chromium/components/rappor/test_rappor_service.cc1
-rw-r--r--chromium/components/reading_list/core/proto/BUILD.gn3
-rw-r--r--chromium/components/reading_list/core/reading_list_entry.cc2
-rw-r--r--chromium/components/resources/security_interstitials_resources.grdp1
-rw-r--r--chromium/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiHandler.java12
-rw-r--r--chromium/components/safe_browsing/android/remote_database_manager.cc8
-rw-r--r--chromium/components/safe_browsing/android/remote_database_manager_unittest.cc2
-rw-r--r--chromium/components/safe_browsing/android/safe_browsing_api_handler.h2
-rw-r--r--chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc8
-rw-r--r--chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.h2
-rw-r--r--chromium/components/safe_browsing/android/safe_browsing_api_handler_util.cc3
-rw-r--r--chromium/components/safe_browsing/base_ui_manager.cc6
-rw-r--r--chromium/components/safe_browsing/browser/BUILD.gn3
-rw-r--r--chromium/components/safe_browsing/browser/base_parallel_resource_throttle.cc4
-rw-r--r--chromium/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc3
-rw-r--r--chromium/components/safe_browsing/browser/browser_url_loader_throttle.cc10
-rw-r--r--chromium/components/safe_browsing/browser/mojo_safe_browsing_impl.cc1
-rw-r--r--chromium/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc6
-rw-r--r--chromium/components/safe_browsing/browser/threat_details_cache.cc4
-rw-r--r--chromium/components/safe_browsing/common/BUILD.gn1
-rw-r--r--chromium/components/safe_browsing/common/safebrowsing_constants.cc29
-rw-r--r--chromium/components/safe_browsing/common/safebrowsing_constants.h19
-rw-r--r--chromium/components/safe_browsing/db/BUILD.gn18
-rw-r--r--chromium/components/safe_browsing/db/database_manager.cc1
-rw-r--r--chromium/components/safe_browsing/db/v4_database.cc1
-rw-r--r--chromium/components/safe_browsing/db/v4_get_hash_protocol_manager.cc1
-rw-r--r--chromium/components/safe_browsing/db/v4_get_hash_protocol_manager_unittest.cc7
-rw-r--r--chromium/components/safe_browsing/db/v4_local_database_manager.cc5
-rw-r--r--chromium/components/safe_browsing/db/v4_local_database_manager_unittest.cc1
-rw-r--r--chromium/components/safe_browsing/db/v4_rice.cc2
-rw-r--r--chromium/components/safe_browsing/db/v4_store.cc12
-rw-r--r--chromium/components/safe_browsing/db/v4_store.h1
-rw-r--r--chromium/components/safe_browsing/db/v4_store_fuzzer.cc132
-rw-r--r--chromium/components/safe_browsing/db/v4_update_protocol_manager.cc1
-rw-r--r--chromium/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc1
-rw-r--r--chromium/components/safe_browsing/features.cc6
-rw-r--r--chromium/components/safe_browsing/features.h3
-rw-r--r--chromium/components/safe_browsing/password_protection/BUILD.gn3
-rw-r--r--chromium/components/safe_browsing/password_protection/DEPS1
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_request.cc71
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_request.h15
-rw-r--r--chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc41
-rw-r--r--chromium/components/safe_browsing/password_protection/visual_utils.cc176
-rw-r--r--chromium/components/safe_browsing/password_protection/visual_utils.h45
-rw-r--r--chromium/components/safe_browsing/password_protection/visual_utils_unittest.cc256
-rw-r--r--chromium/components/safe_browsing/ping_manager.cc1
-rw-r--r--chromium/components/safe_browsing/proto/PRESUBMIT.py33
-rw-r--r--chromium/components/safe_browsing/proto/csd.proto12
-rw-r--r--chromium/components/safe_browsing/renderer/renderer_url_loader_throttle.cc10
-rw-r--r--chromium/components/safe_browsing/renderer/threat_dom_details.cc1
-rw-r--r--chromium/components/safe_browsing/triggers/ad_sampler_trigger.cc1
-rw-r--r--chromium/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc2
-rw-r--r--chromium/components/safe_browsing/triggers/suspicious_site_trigger.cc1
-rw-r--r--chromium/components/safe_browsing/triggers/trigger_manager.cc1
-rw-r--r--chromium/components/safe_browsing/triggers/trigger_throttler.cc2
-rw-r--r--chromium/components/safe_browsing/triggers/trigger_throttler.h2
-rw-r--r--chromium/components/safe_browsing/web_ui/resources/safe_browsing.html20
-rw-r--r--chromium/components/safe_browsing/web_ui/resources/safe_browsing.js20
-rw-r--r--chromium/components/safe_browsing/web_ui/safe_browsing_ui.cc20
-rw-r--r--chromium/components/safe_search_api/BUILD.gn23
-rw-r--r--chromium/components/safe_search_api/OWNERS1
-rw-r--r--chromium/components/safe_search_api/fake_url_checker_client.cc28
-rw-r--r--chromium/components/safe_search_api/fake_url_checker_client.h39
-rw-r--r--chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.cc160
-rw-r--r--chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.h65
-rw-r--r--chromium/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc136
-rw-r--r--chromium/components/safe_search_api/stub_url_checker.cc10
-rw-r--r--chromium/components/safe_search_api/url_checker.cc157
-rw-r--r--chromium/components/safe_search_api/url_checker.h50
-rw-r--r--chromium/components/safe_search_api/url_checker_client.h38
-rw-r--r--chromium/components/safe_search_api/url_checker_unittest.cc84
-rw-r--r--chromium/components/scheduling_metrics/task_duration_metric_reporter.h2
-rw-r--r--chromium/components/search_engines/default_search_manager.cc3
-rw-r--r--chromium/components/search_engines/default_search_manager_unittest.cc2
-rw-r--r--chromium/components/search_engines/default_search_policy_handler.cc4
-rw-r--r--chromium/components/search_engines/keyword_table.cc2
-rw-r--r--chromium/components/search_engines/prepopulated_engines.json15
-rw-r--r--chromium/components/search_engines/search_engine_data_type_controller.cc1
-rw-r--r--chromium/components/search_engines/search_engine_data_type_controller_unittest.cc29
-rw-r--r--chromium/components/search_engines/template_url.cc51
-rw-r--r--chromium/components/search_engines/template_url.h1
-rw-r--r--chromium/components/search_engines/template_url_data_util.cc11
-rw-r--r--chromium/components/search_engines/template_url_fetcher.cc1
-rw-r--r--chromium/components/search_engines/template_url_prepopulate_data.cc2
-rw-r--r--chromium/components/search_engines/template_url_service.cc1
-rw-r--r--chromium/components/search_engines/template_url_service_util_unittest.cc2
-rw-r--r--chromium/components/search_engines/template_url_unittest.cc20
-rw-r--r--chromium/components/search_provider_logos/google_logo_api.cc5
-rw-r--r--chromium/components/search_provider_logos/logo_cache.cc4
-rw-r--r--chromium/components/search_provider_logos/logo_service_impl.cc1
-rw-r--r--chromium/components/search_provider_logos/logo_service_impl_unittest.cc6
-rw-r--r--chromium/components/search_provider_logos/switches.cc9
-rw-r--r--chromium/components/security_interstitials/content/BUILD.gn2
-rw-r--r--chromium/components/security_interstitials/content/origin_policy_interstitial_page.cc130
-rw-r--r--chromium/components/security_interstitials/content/origin_policy_interstitial_page.h54
-rw-r--r--chromium/components/security_interstitials/content/origin_policy_ui.cc72
-rw-r--r--chromium/components/security_interstitials/content/origin_policy_ui.h20
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_page.cc4
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_page.h4
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_tab_helper.cc9
-rw-r--r--chromium/components/security_interstitials/content/security_interstitial_tab_helper.h6
-rw-r--r--chromium/components/security_interstitials/content/unsafe_resource.cc2
-rw-r--r--chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h2
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/1x/info.pngbin0 -> 1971 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/images/2x/info.pngbin0 -> 4835 bytes
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_large.html3
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_large.js30
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_lookalikeurl.css14
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html16
-rw-r--r--chromium/components/security_interstitials/core/browser/resources/list_of_interstitials.html14
-rw-r--r--chromium/components/security_interstitials/core/common/resources/interstitial_common.css1
-rw-r--r--chromium/components/security_interstitials/core/controller_client.h1
-rw-r--r--chromium/components/security_interstitials/core/metrics_helper.cc1
-rw-r--r--chromium/components/security_interstitials_strings.grdp64
-rw-r--r--chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha11
-rw-r--r--chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha11
-rw-r--r--chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha11
-rw-r--r--chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha11
-rw-r--r--chromium/components/security_state/content/content_utils.cc2
-rw-r--r--chromium/components/security_state/core/BUILD.gn2
-rw-r--r--chromium/components/security_state/core/security_state_ui.cc29
-rw-r--r--chromium/components/security_state/core/security_state_ui.h21
-rw-r--r--chromium/components/security_state_strings.grdp2
-rw-r--r--chromium/components/send_tab_to_self/BUILD.gn9
-rw-r--r--chromium/components/send_tab_to_self/OWNERS1
-rw-r--r--chromium/components/send_tab_to_self/proto/BUILD.gn13
-rw-r--r--chromium/components/send_tab_to_self/proto/DEPS3
-rw-r--r--chromium/components/send_tab_to_self/proto/send_tab_to_self.proto23
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_bridge.cc295
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_bridge.h70
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc279
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_entry.cc60
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_entry.h18
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc40
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_model.h17
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_model_observer.h14
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_sync_service.cc (renamed from chromium/components/send_tab_to_self/send_tab_to_self_service.cc)19
-rw-r--r--chromium/components/send_tab_to_self/send_tab_to_self_sync_service.h (renamed from chromium/components/send_tab_to_self/send_tab_to_self_service.h)24
-rw-r--r--chromium/components/services/filesystem/BUILD.gn25
-rw-r--r--chromium/components/services/filesystem/OWNERS5
-rw-r--r--chromium/components/services/filesystem/directory_impl_unittest.cc1
-rw-r--r--chromium/components/services/filesystem/file_impl_unittest.cc1
-rw-r--r--chromium/components/services/filesystem/file_system_app.cc1
-rw-r--r--chromium/components/services/filesystem/files_test_base.cc16
-rw-r--r--chromium/components/services/filesystem/manifest.json15
-rw-r--r--chromium/components/services/filesystem/public/cpp/BUILD.gn16
-rw-r--r--chromium/components/services/filesystem/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/filesystem/public/cpp/manifest.cc27
-rw-r--r--chromium/components/services/filesystem/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/filesystem/test_manifest.json11
-rw-r--r--chromium/components/services/font/BUILD.gn25
-rw-r--r--chromium/components/services/font/OWNERS5
-rw-r--r--chromium/components/services/font/font_loader_unittest.cc16
-rw-r--r--chromium/components/services/font/font_service_app.cc1
-rw-r--r--chromium/components/services/font/fontconfig_matching.cc16
-rw-r--r--chromium/components/services/font/manifest.json15
-rw-r--r--chromium/components/services/font/ppapi_fontconfig_matching.cc27
-rw-r--r--chromium/components/services/font/public/cpp/BUILD.gn13
-rw-r--r--chromium/components/services/font/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/font/public/cpp/font_loader.cc17
-rw-r--r--chromium/components/services/font/public/cpp/font_loader.h3
-rw-r--r--chromium/components/services/font/public/cpp/font_service_thread.cc81
-rw-r--r--chromium/components/services/font/public/cpp/font_service_thread.h21
-rw-r--r--chromium/components/services/font/public/cpp/manifest.cc32
-rw-r--r--chromium/components/services/font/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/font/test_manifest.json11
-rw-r--r--chromium/components/services/heap_profiling/BUILD.gn6
-rw-r--r--chromium/components/services/heap_profiling/OWNERS3
-rw-r--r--chromium/components/services/heap_profiling/allocation_tracker.cc1
-rw-r--r--chromium/components/services/heap_profiling/connection_manager.cc98
-rw-r--r--chromium/components/services/heap_profiling/connection_manager.h10
-rw-r--r--chromium/components/services/heap_profiling/heap_profiling_manifest.json20
-rw-r--r--chromium/components/services/heap_profiling/heap_profiling_service.cc32
-rw-r--r--chromium/components/services/heap_profiling/heap_profiling_service.h3
-rw-r--r--chromium/components/services/heap_profiling/json_exporter.cc2
-rw-r--r--chromium/components/services/heap_profiling/json_exporter_unittest.cc15
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/BUILD.gn14
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/client.cc5
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/client.h1
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/controller.cc3
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/controller.h2
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/manifest.cc39
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc291
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h13
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/settings.cc17
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/settings.h1
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/switches.cc2
-rw-r--r--chromium/components/services/heap_profiling/public/cpp/switches.h2
-rw-r--r--chromium/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom43
-rw-r--r--chromium/components/services/heap_profiling/receiver_pipe_win.cc6
-rw-r--r--chromium/components/services/leveldb/BUILD.gn29
-rw-r--r--chromium/components/services/leveldb/OWNERS6
-rw-r--r--chromium/components/services/leveldb/env_mojo.cc1
-rw-r--r--chromium/components/services/leveldb/leveldb_app.cc1
-rw-r--r--chromium/components/services/leveldb/leveldb_service_impl.cc1
-rw-r--r--chromium/components/services/leveldb/leveldb_service_unittest.cc18
-rw-r--r--chromium/components/services/leveldb/manifest.json15
-rw-r--r--chromium/components/services/leveldb/public/cpp/BUILD.gn13
-rw-r--r--chromium/components/services/leveldb/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/leveldb/public/cpp/manifest.cc28
-rw-r--r--chromium/components/services/leveldb/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/leveldb/remote_iterator_unittest.cc15
-rw-r--r--chromium/components/services/leveldb/test_manifest.json12
-rw-r--r--chromium/components/services/patch/BUILD.gn7
-rw-r--r--chromium/components/services/patch/OWNERS3
-rw-r--r--chromium/components/services/patch/manifest.json15
-rw-r--r--chromium/components/services/patch/public/cpp/BUILD.gn13
-rw-r--r--chromium/components/services/patch/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/patch/public/cpp/manifest.cc33
-rw-r--r--chromium/components/services/patch/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/pdf_compositor/BUILD.gn6
-rw-r--r--chromium/components/services/pdf_compositor/OWNERS3
-rw-r--r--chromium/components/services/pdf_compositor/pdf_compositor_impl_unittest.cc1
-rw-r--r--chromium/components/services/pdf_compositor/pdf_compositor_manifest.json20
-rw-r--r--chromium/components/services/pdf_compositor/pdf_compositor_service.cc1
-rw-r--r--chromium/components/services/pdf_compositor/pdf_compositor_service_unittest.cc1
-rw-r--r--chromium/components/services/pdf_compositor/public/cpp/BUILD.gn13
-rw-r--r--chromium/components/services/pdf_compositor/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/pdf_compositor/public/cpp/manifest.cc34
-rw-r--r--chromium/components/services/pdf_compositor/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/unzip/BUILD.gn7
-rw-r--r--chromium/components/services/unzip/OWNERS2
-rw-r--r--chromium/components/services/unzip/manifest.json15
-rw-r--r--chromium/components/services/unzip/public/cpp/BUILD.gn13
-rw-r--r--chromium/components/services/unzip/public/cpp/OWNERS4
-rw-r--r--chromium/components/services/unzip/public/cpp/manifest.cc32
-rw-r--r--chromium/components/services/unzip/public/cpp/manifest.h16
-rw-r--r--chromium/components/services/unzip/public/cpp/test_unzip_service.cc2
-rw-r--r--chromium/components/services/unzip/unzipper_impl.cc2
-rw-r--r--chromium/components/sessions/core/session_service_commands.cc100
-rw-r--r--chromium/components/sessions/core/session_service_commands.h8
-rw-r--r--chromium/components/signin/core/browser/BUILD.gn36
-rw-r--r--chromium/components/signin/core/browser/DEPS2
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.cc140
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.h77
-rw-r--r--chromium/components/signin/core/browser/account_consistency_method.cc5
-rw-r--r--chromium/components/signin/core/browser/account_consistency_method.h9
-rw-r--r--chromium/components/signin/core/browser/account_fetcher_service.cc61
-rw-r--r--chromium/components/signin/core/browser/account_fetcher_service.h46
-rw-r--r--chromium/components/signin/core/browser/account_info.cc29
-rw-r--r--chromium/components/signin/core/browser/account_info.h36
-rw-r--r--chromium/components/signin/core/browser/account_investigator.cc26
-rw-r--r--chromium/components/signin/core/browser/account_investigator.h14
-rw-r--r--chromium/components/signin/core/browser/account_investigator_unittest.cc45
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.cc172
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.h33
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_delegate.cc12
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_delegate_unittest.cc8
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_unittest.cc434
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service.cc7
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service.h6
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service_unittest.cc2
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java4
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java4
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java5
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.cc15
-rw-r--r--chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc2
-rw-r--r--chromium/components/signin/core/browser/dice_header_helper.cc9
-rw-r--r--chromium/components/signin/core/browser/dice_header_helper.h4
-rw-r--r--chromium/components/signin/core/browser/fake_account_fetcher_service.cc49
-rw-r--r--chromium/components/signin/core/browser/fake_account_fetcher_service.h65
-rw-r--r--chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.cc99
-rw-r--r--chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.h72
-rw-r--r--chromium/components/signin/core/browser/fake_profile_oauth2_token_service.cc14
-rw-r--r--chromium/components/signin/core/browser/fake_profile_oauth2_token_service.h4
-rw-r--r--chromium/components/signin/core/browser/fake_signin_manager.cc153
-rw-r--r--chromium/components/signin/core/browser/fake_signin_manager.h85
-rw-r--r--chromium/components/signin/core/browser/gaia_cookie_manager_service.cc225
-rw-r--r--chromium/components/signin/core/browser/gaia_cookie_manager_service.h103
-rw-r--r--chromium/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc288
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc73
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h49
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc76
-rw-r--r--chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc6
-rw-r--r--chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h5
-rw-r--r--chromium/components/signin/core/browser/mutable_profile_oauth2_token_service_delegate_unittest.cc31
-rw-r--r--chromium/components/signin/core/browser/oauth2_token_service_delegate_android.cc33
-rw-r--r--chromium/components/signin/core/browser/oauth2_token_service_delegate_android.h15
-rw-r--r--chromium/components/signin/core/browser/profile_oauth2_token_service.h6
-rw-r--r--chromium/components/signin/core/browser/resources/signin_index.html5
-rw-r--r--chromium/components/signin/core/browser/signin_client.h10
-rw-r--r--chromium/components/signin/core/browser/signin_error_controller.cc6
-rw-r--r--chromium/components/signin/core/browser/signin_error_controller.h7
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.cc7
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.h3
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper_unittest.cc23
-rw-r--r--chromium/components/signin/core/browser/signin_manager.cc215
-rw-r--r--chromium/components/signin/core/browser/signin_manager.h110
-rw-r--r--chromium/components/signin/core/browser/signin_manager_base.cc12
-rw-r--r--chromium/components/signin/core/browser/signin_manager_base.h42
-rw-r--r--chromium/components/signin/core/browser/signin_manager_unittest.cc105
-rw-r--r--chromium/components/signin/core/browser/signin_metrics.cc19
-rw-r--r--chromium/components/signin/core/browser/signin_metrics.h43
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider.cc40
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider.h27
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider_delegate.h10
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc12
-rw-r--r--chromium/components/signin/core/browser/signin_tracker.cc46
-rw-r--r--chromium/components/signin/core/browser/signin_tracker.h96
-rw-r--r--chromium/components/signin/core/browser/signin_tracker_unittest.cc89
-rw-r--r--chromium/components/signin/core/browser/test_image_decoder.cc23
-rw-r--r--chromium/components/signin/core/browser/test_image_decoder.h35
-rw-r--r--chromium/components/signin/core/browser/test_signin_client.cc68
-rw-r--r--chromium/components/signin/core/browser/test_signin_client.h24
-rw-r--r--chromium/components/signin/core/browser/ubertoken_fetcher_impl.cc1
-rw-r--r--chromium/components/signin/core/browser/ubertoken_fetcher_impl_unittest.cc1
-rw-r--r--chromium/components/signin/core/browser/webdata/token_web_data.cc2
-rw-r--r--chromium/components/signin/ios/browser/BUILD.gn3
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.h29
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.mm44
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service_unittest.mm89
-rw-r--r--chromium/components/signin/ios/browser/active_state_manager.h2
-rw-r--r--chromium/components/signin/ios/browser/merge_session_observer_bridge.h44
-rw-r--r--chromium/components/signin/ios/browser/merge_session_observer_bridge.mm31
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h4
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm13
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm2
-rw-r--r--chromium/components/signin/ios/browser/wait_for_network_callback_helper.cc13
-rw-r--r--chromium/components/signin/ios/browser/wait_for_network_callback_helper.h4
-rw-r--r--chromium/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java4
-rw-r--r--chromium/components/spellcheck/browser/spell_check_host_impl.cc15
-rw-r--r--chromium/components/spellcheck/browser/spell_check_host_impl.h6
-rw-r--r--chromium/components/spellcheck/browser/spellcheck_host_metrics.cc17
-rw-r--r--chromium/components/spellcheck/browser/spellcheck_host_metrics.h2
-rw-r--r--chromium/components/spellcheck/browser/spellchecker_session_bridge_android.cc6
-rw-r--r--chromium/components/spellcheck/browser/spelling_service_client.cc4
-rw-r--r--chromium/components/spellcheck/common/spellcheck.mojom6
-rw-r--r--chromium/components/spellcheck/common/spellcheck_common.cc4
-rw-r--r--chromium/components/spellcheck/renderer/BUILD.gn8
-rw-r--r--chromium/components/spellcheck/renderer/custom_dictionary_engine.cc15
-rw-r--r--chromium/components/spellcheck/renderer/custom_dictionary_engine.h4
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck.cc25
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck.h8
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_language.cc20
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_language.h12
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc16
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_provider.cc32
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_provider.h6
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_provider_test.cc10
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_provider_test.h6
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_unittest.cc74
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_worditerator.cc11
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_worditerator.h10
-rw-r--r--chromium/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc21
-rw-r--r--chromium/components/ssl_errors/error_classification_unittest.cc1
-rw-r--r--chromium/components/startup_metric_utils/browser/startup_metric_utils.cc12
-rw-r--r--chromium/components/storage_monitor/image_capture_device.mm1
-rw-r--r--chromium/components/storage_monitor/image_capture_device_manager_unittest.mm2
-rw-r--r--chromium/components/storage_monitor/media_storage_util.cc1
-rw-r--r--chromium/components/storage_monitor/media_storage_util_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/mtab_watcher_linux.cc3
-rw-r--r--chromium/components/storage_monitor/mtp_manager_client_chromeos.cc1
-rw-r--r--chromium/components/storage_monitor/portable_device_watcher_win.cc19
-rw-r--r--chromium/components/storage_monitor/storage_info_utils.cc4
-rw-r--r--chromium/components/storage_monitor/storage_monitor.h2
-rw-r--r--chromium/components/storage_monitor/storage_monitor_chromeos.cc2
-rw-r--r--chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/storage_monitor_linux.cc9
-rw-r--r--chromium/components/storage_monitor/storage_monitor_linux_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/storage_monitor_mac.mm6
-rw-r--r--chromium/components/storage_monitor/storage_monitor_mac_unittest.mm7
-rw-r--r--chromium/components/storage_monitor/storage_monitor_unittest.cc1
-rw-r--r--chromium/components/storage_monitor/test_media_transfer_protocol_manager_chromeos.cc2
-rw-r--r--chromium/components/storage_monitor/test_storage_monitor.cc1
-rw-r--r--chromium/components/storage_monitor/test_storage_monitor.h4
-rw-r--r--chromium/components/storage_monitor/volume_mount_watcher_win.cc40
-rw-r--r--chromium/components/strings/BUILD.gn22
-rw-r--r--chromium/components/strings/components_chromium_strings_hi.xtb8
-rw-r--r--chromium/components/strings/components_chromium_strings_ja.xtb2
-rw-r--r--chromium/components/strings/components_google_chrome_strings_hi.xtb10
-rw-r--r--chromium/components/strings/components_google_chrome_strings_ja.xtb2
-rw-r--r--chromium/components/strings/components_strings_am.xtb241
-rw-r--r--chromium/components/strings/components_strings_ar.xtb250
-rw-r--r--chromium/components/strings/components_strings_bg.xtb250
-rw-r--r--chromium/components/strings/components_strings_bn.xtb250
-rw-r--r--chromium/components/strings/components_strings_ca.xtb239
-rw-r--r--chromium/components/strings/components_strings_cs.xtb239
-rw-r--r--chromium/components/strings/components_strings_da.xtb250
-rw-r--r--chromium/components/strings/components_strings_de.xtb247
-rw-r--r--chromium/components/strings/components_strings_el.xtb250
-rw-r--r--chromium/components/strings/components_strings_en-GB.xtb255
-rw-r--r--chromium/components/strings/components_strings_es-419.xtb250
-rw-r--r--chromium/components/strings/components_strings_es.xtb241
-rw-r--r--chromium/components/strings/components_strings_et.xtb250
-rw-r--r--chromium/components/strings/components_strings_fa.xtb250
-rw-r--r--chromium/components/strings/components_strings_fi.xtb250
-rw-r--r--chromium/components/strings/components_strings_fil.xtb250
-rw-r--r--chromium/components/strings/components_strings_fr.xtb239
-rw-r--r--chromium/components/strings/components_strings_gu.xtb250
-rw-r--r--chromium/components/strings/components_strings_hi.xtb367
-rw-r--r--chromium/components/strings/components_strings_hr.xtb250
-rw-r--r--chromium/components/strings/components_strings_hu.xtb250
-rw-r--r--chromium/components/strings/components_strings_id.xtb250
-rw-r--r--chromium/components/strings/components_strings_it.xtb250
-rw-r--r--chromium/components/strings/components_strings_iw.xtb239
-rw-r--r--chromium/components/strings/components_strings_ja.xtb297
-rw-r--r--chromium/components/strings/components_strings_kn.xtb249
-rw-r--r--chromium/components/strings/components_strings_ko.xtb250
-rw-r--r--chromium/components/strings/components_strings_lt.xtb250
-rw-r--r--chromium/components/strings/components_strings_lv.xtb240
-rw-r--r--chromium/components/strings/components_strings_ml.xtb239
-rw-r--r--chromium/components/strings/components_strings_mr.xtb250
-rw-r--r--chromium/components/strings/components_strings_ms.xtb240
-rw-r--r--chromium/components/strings/components_strings_nl.xtb239
-rw-r--r--chromium/components/strings/components_strings_no.xtb252
-rw-r--r--chromium/components/strings/components_strings_pl.xtb250
-rw-r--r--chromium/components/strings/components_strings_pt-BR.xtb250
-rw-r--r--chromium/components/strings/components_strings_pt-PT.xtb250
-rw-r--r--chromium/components/strings/components_strings_ro.xtb250
-rw-r--r--chromium/components/strings/components_strings_ru.xtb239
-rw-r--r--chromium/components/strings/components_strings_sk.xtb239
-rw-r--r--chromium/components/strings/components_strings_sl.xtb250
-rw-r--r--chromium/components/strings/components_strings_sr.xtb250
-rw-r--r--chromium/components/strings/components_strings_sv.xtb250
-rw-r--r--chromium/components/strings/components_strings_sw.xtb250
-rw-r--r--chromium/components/strings/components_strings_ta.xtb253
-rw-r--r--chromium/components/strings/components_strings_te.xtb269
-rw-r--r--chromium/components/strings/components_strings_th.xtb250
-rw-r--r--chromium/components/strings/components_strings_tr.xtb250
-rw-r--r--chromium/components/strings/components_strings_uk.xtb250
-rw-r--r--chromium/components/strings/components_strings_vi.xtb250
-rw-r--r--chromium/components/strings/components_strings_zh-CN.xtb239
-rw-r--r--chromium/components/strings/components_strings_zh-TW.xtb250
-rw-r--r--chromium/components/subresource_filter/content/browser/BUILD.gn7
-rw-r--r--chromium/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc13
-rw-r--r--chromium/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc10
-rw-r--r--chromium/components/subresource_filter/content/browser/ruleset_service.cc7
-rw-r--r--chromium/components/subresource_filter/content/browser/ruleset_service_unittest.cc2
-rw-r--r--chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc1
-rw-r--r--chromium/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc1
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.cc1
-rw-r--r--chromium/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc12
-rw-r--r--chromium/components/subresource_filter/content/common/ad_delay_throttle.cc2
-rw-r--r--chromium/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc6
-rw-r--r--chromium/components/subresource_filter/content/renderer/subresource_filter_agent.cc1
-rw-r--r--chromium/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc15
-rw-r--r--chromium/components/subresource_filter/core/browser/subresource_filter_features.cc1
-rw-r--r--chromium/components/subresource_filter/core/common/first_party_origin_unittest.cc8
-rw-r--r--chromium/components/subresource_filter/core/common/indexed_ruleset.cc4
-rw-r--r--chromium/components/subresource_filter/core/common/test_ruleset_creator.cc4
-rw-r--r--chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc2
-rw-r--r--chromium/components/subresource_filter/tools/filter_tool.cc3
-rw-r--r--chromium/components/subresource_filter/tools/indexing_tool_unittest.cc6
-rw-r--r--chromium/components/subresource_filter/tools/ruleset_converter/BUILD.gn6
-rw-r--r--chromium/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc4
-rw-r--r--chromium/components/suggestions/suggestions_service_impl.cc5
-rw-r--r--chromium/components/suggestions/webui/suggestions_source.cc2
-rw-r--r--chromium/components/supervised_user_error_page/gin_wrapper.cc1
-rw-r--r--chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css73
-rw-r--r--chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html5
-rw-r--r--chromium/components/supervised_user_error_page/supervised_user_error_page.cc6
-rw-r--r--chromium/components/supervised_user_error_page/supervised_user_error_page_unittest.cc12
-rw-r--r--chromium/components/sync/BUILD.gn23
-rw-r--r--chromium/components/sync/android/BUILD.gn2
-rw-r--r--chromium/components/sync/protocol/protocol_sources.gni2
-rw-r--r--chromium/components/sync_bookmarks/bookmark_change_processor.cc38
-rw-r--r--chromium/components/sync_bookmarks/bookmark_change_processor.h25
-rw-r--r--chromium/components/sync_bookmarks/bookmark_data_type_controller.cc26
-rw-r--r--chromium/components/sync_bookmarks/bookmark_data_type_controller.h15
-rw-r--r--chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc58
-rw-r--r--chromium/components/sync_bookmarks/bookmark_local_changes_builder.cc9
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_associator.cc26
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_associator.h25
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_type_processor.cc21
-rw-r--r--chromium/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc8
-rw-r--r--chromium/components/sync_bookmarks/bookmark_specifics_conversions.cc32
-rw-r--r--chromium/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc46
-rw-r--r--chromium/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc1
-rw-r--r--chromium/components/sync_preferences/pref_model_associator.cc5
-rw-r--r--chromium/components/sync_preferences/pref_service_syncable_unittest.cc7
-rw-r--r--chromium/components/sync_sessions/favicon_cache.cc5
-rw-r--r--chromium/components/sync_sessions/favicon_cache.h2
-rw-r--r--chromium/components/sync_sessions/local_session_event_handler_impl.cc3
-rw-r--r--chromium/components/sync_sessions/lost_navigations_recorder.h2
-rw-r--r--chromium/components/sync_sessions/lost_navigations_recorder_unittest.cc4
-rw-r--r--chromium/components/sync_sessions/open_tabs_ui_delegate_impl_unittest.cc1
-rw-r--r--chromium/components/sync_sessions/session_model_type_controller.cc2
-rw-r--r--chromium/components/sync_sessions/session_store.cc254
-rw-r--r--chromium/components/sync_sessions/session_store.h64
-rw-r--r--chromium/components/sync_sessions/session_store_unittest.cc97
-rw-r--r--chromium/components/sync_sessions/session_sync_bridge.cc111
-rw-r--r--chromium/components/sync_sessions/session_sync_bridge.h12
-rw-r--r--chromium/components/sync_sessions/session_sync_bridge_unittest.cc8
-rw-r--r--chromium/components/sync_sessions/session_sync_service.h3
-rw-r--r--chromium/components/sync_sessions/session_sync_service_impl.cc5
-rw-r--r--chromium/components/sync_sessions/session_sync_service_impl.h3
-rw-r--r--chromium/components/sync_sessions/synced_session_unittest.cc6
-rw-r--r--chromium/components/sync_ui_strings.grdp20
-rw-r--r--chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha11
-rw-r--r--chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha11
-rw-r--r--chromium/components/task_scheduler_util/variations_util.cc13
-rw-r--r--chromium/components/task_scheduler_util/variations_util_unittest.cc28
-rw-r--r--chromium/components/test/BUILD.gn2
-rw-r--r--chromium/components/timers/alarm_timer_chromeos.cc62
-rw-r--r--chromium/components/timers/alarm_timer_chromeos.h27
-rw-r--r--chromium/components/timers/alarm_timer_unittest.cc122
-rw-r--r--chromium/components/tracing/BUILD.gn4
-rw-r--r--chromium/components/tracing/common/native_stack_sampler_android.cc9
-rw-r--r--chromium/components/tracing/common/native_stack_sampler_android.h1
-rw-r--r--chromium/components/tracing/common/stack_unwinder_android_unittest.cc1
-rw-r--r--chromium/components/tracing/common/trace_startup.cc51
-rw-r--r--chromium/components/tracing/common/trace_startup.h17
-rw-r--r--chromium/components/tracing/common/trace_startup_config.cc28
-rw-r--r--chromium/components/tracing/common/trace_startup_config.h2
-rw-r--r--chromium/components/tracing/common/tracing_sampler_profiler.cc115
-rw-r--r--chromium/components/tracing/common/tracing_sampler_profiler.h24
-rw-r--r--chromium/components/tracing/common/tracing_sampler_profiler_unittest.cc33
-rw-r--r--chromium/components/tracing/common/tracing_switches.cc16
-rw-r--r--chromium/components/tracing/common/tracing_switches.h3
-rw-r--r--chromium/components/translate/core/browser/BUILD.gn41
-rw-r--r--chromium/components/translate/core/language_detection/BUILD.gn1
-rw-r--r--chromium/components/translate_strings.grdp9
-rw-r--r--chromium/components/typemaps.gni1
-rw-r--r--chromium/components/ui_devtools/BUILD.gn4
-rw-r--r--chromium/components/ui_devtools/OWNERS1
-rw-r--r--chromium/components/ui_devtools/css_agent.cc6
-rw-r--r--chromium/components/ui_devtools/css_agent_unittest.cc14
-rw-r--r--chromium/components/ui_devtools/devtools_base_agent.h4
-rw-r--r--chromium/components/ui_devtools/devtools_client.cc6
-rw-r--r--chromium/components/ui_devtools/devtools_server.cc2
-rw-r--r--chromium/components/ui_devtools/devtools_server.h3
-rw-r--r--chromium/components/ui_devtools/dom_agent.cc2
-rw-r--r--chromium/components/ui_devtools/inspector_protocol_config.json2
-rw-r--r--chromium/components/ui_devtools/overlay_agent.cc2
-rw-r--r--chromium/components/ui_devtools/overlay_agent.h4
-rw-r--r--chromium/components/ui_devtools/string_util.cc33
-rw-r--r--chromium/components/ui_devtools/string_util.h93
-rw-r--r--chromium/components/ui_devtools/ui_devtools_unittest_utils.cc2
-rw-r--r--chromium/components/ui_devtools/ui_element.cc15
-rw-r--r--chromium/components/ui_devtools/ui_element.h14
-rw-r--r--chromium/components/ui_devtools/ui_element_delegate.h4
-rw-r--r--chromium/components/ui_devtools/views/dom_agent_aura.cc3
-rw-r--r--chromium/components/ui_devtools/views/overlay_agent_aura.cc2
-rw-r--r--chromium/components/ui_devtools/views/overlay_agent_aura.h4
-rw-r--r--chromium/components/ui_devtools/views/view_element.cc3
-rw-r--r--chromium/components/ui_devtools/views/view_element.h2
-rw-r--r--chromium/components/ui_devtools/views/widget_element.h2
-rw-r--r--chromium/components/ui_devtools/views/widget_element_unittest.cc2
-rw-r--r--chromium/components/ui_devtools/views/window_element.cc3
-rw-r--r--chromium/components/ui_devtools/views/window_element.h2
-rw-r--r--chromium/components/ui_devtools/viz/BUILD.gn2
-rw-r--r--chromium/components/ui_devtools/viz/dom_agent_viz.cc67
-rw-r--r--chromium/components/ui_devtools/viz/dom_agent_viz.h17
-rw-r--r--chromium/components/ui_devtools/viz/frame_sink_element.cc2
-rw-r--r--chromium/components/ui_devtools/viz/frame_sink_element.h4
-rw-r--r--chromium/components/ui_devtools/viz/overlay_agent_viz.cc2
-rw-r--r--chromium/components/ui_devtools/viz/overlay_agent_viz.h2
-rw-r--r--chromium/components/ui_devtools/viz/surface_element.cc2
-rw-r--r--chromium/components/ui_devtools/viz/surface_element.h4
-rw-r--r--chromium/components/ui_devtools/viz/viz_devtools_unittest.cc78
-rw-r--r--chromium/components/ui_devtools/viz/viz_element.cc66
-rw-r--r--chromium/components/ui_devtools/viz/viz_element.h39
-rw-r--r--chromium/components/ukm/content/DEPS2
-rw-r--r--chromium/components/ukm/content/source_url_recorder.cc133
-rw-r--r--chromium/components/ukm/content/source_url_recorder_test.cc84
-rw-r--r--chromium/components/ukm/debug/PRESUBMIT.py17
-rw-r--r--chromium/components/ukm/debug/ukm_debug_data_extractor.cc1
-rw-r--r--chromium/components/ukm/ios/BUILD.gn15
-rw-r--r--chromium/components/ukm/ios/features.cc8
-rw-r--r--chromium/components/ukm/ios/features.h13
-rw-r--r--chromium/components/ukm/observers/sync_disable_observer.cc4
-rw-r--r--chromium/components/ukm/test_ukm_recorder.cc5
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.cc12
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.h10
-rw-r--r--chromium/components/ukm/ukm_recorder_impl_unittest.cc67
-rw-r--r--chromium/components/ukm/ukm_reporting_service.cc12
-rw-r--r--chromium/components/ukm/ukm_reporting_service.h4
-rw-r--r--chromium/components/ukm/ukm_service.h7
-rw-r--r--chromium/components/unified_consent/BUILD.gn6
-rw-r--r--chromium/components/unified_consent/pref_names.cc9
-rw-r--r--chromium/components/unified_consent/pref_names.h6
-rw-r--r--chromium/components/unified_consent/unified_consent_metrics.cc111
-rw-r--r--chromium/components/unified_consent/unified_consent_metrics.h26
-rw-r--r--chromium/components/unified_consent/unified_consent_service.cc134
-rw-r--r--chromium/components/unified_consent/unified_consent_service.h68
-rw-r--r--chromium/components/unified_consent/unified_consent_service_client.cc54
-rw-r--r--chromium/components/unified_consent/unified_consent_service_client.h89
-rw-r--r--chromium/components/unified_consent/unified_consent_service_unittest.cc155
-rw-r--r--chromium/components/update_client/BUILD.gn48
-rw-r--r--chromium/components/update_client/DEPS12
-rw-r--r--chromium/components/update_client/background_downloader_win.cc2
-rw-r--r--chromium/components/update_client/component.cc5
-rw-r--r--chromium/components/update_client/configurator.h5
-rw-r--r--chromium/components/update_client/crx_downloader.cc7
-rw-r--r--chromium/components/update_client/crx_downloader.h14
-rw-r--r--chromium/components/update_client/crx_downloader_unittest.cc6
-rw-r--r--chromium/components/update_client/net/DEPS5
-rw-r--r--chromium/components/update_client/net/network_chromium.h39
-rw-r--r--chromium/components/update_client/net/network_impl.cc207
-rw-r--r--chromium/components/update_client/net/network_impl.h65
-rw-r--r--chromium/components/update_client/net/url_loader_post_interceptor.cc (renamed from chromium/components/update_client/url_loader_post_interceptor.cc)7
-rw-r--r--chromium/components/update_client/net/url_loader_post_interceptor.h (renamed from chromium/components/update_client/url_loader_post_interceptor.h)12
-rw-r--r--chromium/components/update_client/network.cc12
-rw-r--r--chromium/components/update_client/network.h89
-rw-r--r--chromium/components/update_client/ping_manager.cc1
-rw-r--r--chromium/components/update_client/ping_manager_unittest.cc23
-rw-r--r--chromium/components/update_client/protocol_parser_json.cc2
-rw-r--r--chromium/components/update_client/request_sender.cc124
-rw-r--r--chromium/components/update_client/request_sender.h31
-rw-r--r--chromium/components/update_client/request_sender_unittest.cc5
-rw-r--r--chromium/components/update_client/test_configurator.cc12
-rw-r--r--chromium/components/update_client/test_configurator.h5
-rw-r--r--chromium/components/update_client/test_installer.cc1
-rw-r--r--chromium/components/update_client/update_checker.cc6
-rw-r--r--chromium/components/update_client/update_checker_unittest.cc83
-rw-r--r--chromium/components/update_client/update_client_unittest.cc43
-rw-r--r--chromium/components/update_client/update_engine.cc9
-rw-r--r--chromium/components/update_client/updater_state.cc2
-rw-r--r--chromium/components/update_client/url_fetcher_downloader.cc138
-rw-r--r--chromium/components/update_client/url_fetcher_downloader.h28
-rw-r--r--chromium/components/update_client/utils.cc62
-rw-r--r--chromium/components/update_client/utils.h20
-rw-r--r--chromium/components/upload_list/text_log_upload_list_unittest.cc2
-rw-r--r--chromium/components/url_formatter/elide_url.cc2
-rw-r--r--chromium/components/url_formatter/top_domains/BUILD.gn27
-rw-r--r--chromium/components/url_formatter/top_domains/make_top_domain_list_for_edit_distance.cc12
-rw-r--r--chromium/components/url_formatter/top_domains/top500_domains.h13
-rw-r--r--chromium/components/url_pattern_index/fuzzy_pattern_matching.h6
-rw-r--r--chromium/components/url_pattern_index/url_pattern.cc148
-rw-r--r--chromium/components/url_pattern_index/url_pattern_index.cc7
-rw-r--r--chromium/components/url_pattern_index/url_pattern_index.h2
-rw-r--r--chromium/components/url_pattern_index/url_pattern_unittest.cc40
-rw-r--r--chromium/components/user_manager/fake_user_manager.cc4
-rw-r--r--chromium/components/user_manager/fake_user_manager.h1
-rw-r--r--chromium/components/user_manager/known_user.cc16
-rw-r--r--chromium/components/user_manager/known_user.h11
-rw-r--r--chromium/components/user_manager/user.h9
-rw-r--r--chromium/components/user_manager/user_manager.h12
-rw-r--r--chromium/components/user_manager/user_manager_base.cc41
-rw-r--r--chromium/components/user_manager/user_manager_base.h2
-rw-r--r--chromium/components/user_manager/user_unittest.cc9
-rw-r--r--chromium/components/variations/BUILD.gn13
-rw-r--r--chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java31
-rw-r--r--chromium/components/variations/entropy_provider.cc5
-rw-r--r--chromium/components/variations/entropy_provider_unittest.cc2
-rw-r--r--chromium/components/variations/experiment_labels.cc49
-rw-r--r--chromium/components/variations/experiment_labels.h20
-rw-r--r--chromium/components/variations/experiment_labels_unittest.cc87
-rw-r--r--chromium/components/variations/net/variations_http_headers.cc262
-rw-r--r--chromium/components/variations/net/variations_http_headers.h84
-rw-r--r--chromium/components/variations/net/variations_http_headers_unittest.cc5
-rw-r--r--chromium/components/variations/platform_field_trials.h4
-rw-r--r--chromium/components/variations/processed_study.cc6
-rw-r--r--chromium/components/variations/proto/study.proto4
-rw-r--r--chromium/components/variations/service/variations_field_trial_creator.cc1
-rw-r--r--chromium/components/variations/service/variations_field_trial_creator_unittest.cc2
-rw-r--r--chromium/components/variations/service/variations_service.cc16
-rw-r--r--chromium/components/variations/service/variations_service.h8
-rw-r--r--chromium/components/variations/service/variations_service_unittest.cc2
-rw-r--r--chromium/components/variations/study_filtering.cc4
-rw-r--r--chromium/components/variations/study_filtering_unittest.cc9
-rw-r--r--chromium/components/variations/variations_experiment_util.cc54
-rw-r--r--chromium/components/variations/variations_experiment_util.h25
-rw-r--r--chromium/components/variations/variations_http_header_provider.cc26
-rw-r--r--chromium/components/variations/variations_http_header_provider.h6
-rw-r--r--chromium/components/variations/variations_http_header_provider_unittest.cc21
-rw-r--r--chromium/components/variations/variations_id_collection_unittest.cc1
-rw-r--r--chromium/components/variations/variations_murmur_hash.h6
-rw-r--r--chromium/components/variations/variations_request_scheduler_mobile.h1
-rw-r--r--chromium/components/variations/variations_seed_processor.cc8
-rw-r--r--chromium/components/variations/variations_seed_processor_unittest.cc16
-rw-r--r--chromium/components/vector_icons/BUILD.gn1
-rw-r--r--chromium/components/vector_icons/serial_port.icon25
-rw-r--r--chromium/components/version_info/version_info.cc6
-rw-r--r--chromium/components/version_info/version_info.h3
-rw-r--r--chromium/components/version_ui/resources/about_version.html1
-rw-r--r--chromium/components/visitedlink/renderer/visitedlink_slave.cc1
-rw-r--r--chromium/components/viz/client/client_resource_provider.cc36
-rw-r--r--chromium/components/viz/client/client_resource_provider.h14
-rw-r--r--chromium/components/viz/client/client_resource_provider_unittest.cc6
-rw-r--r--chromium/components/viz/common/BUILD.gn12
-rw-r--r--chromium/components/viz/common/DEPS3
-rw-r--r--chromium/components/viz/common/display/overlay_strategy.cc34
-rw-r--r--chromium/components/viz/common/display/overlay_strategy.h34
-rw-r--r--chromium/components/viz/common/display/overlay_strategy_unittest.cc43
-rw-r--r--chromium/components/viz/common/display/renderer_settings.h3
-rw-r--r--chromium/components/viz/common/features.cc37
-rw-r--r--chromium/components/viz/common/features.h5
-rw-r--r--chromium/components/viz/common/frame_sinks/begin_frame_args.cc14
-rw-r--r--chromium/components/viz/common/frame_sinks/begin_frame_args.h22
-rw-r--r--chromium/components/viz/common/frame_sinks/begin_frame_source.cc59
-rw-r--r--chromium/components/viz/common/frame_sinks/begin_frame_source.h14
-rw-r--r--chromium/components/viz/common/frame_sinks/begin_frame_source_unittest.cc47
-rw-r--r--chromium/components/viz/common/frame_sinks/copy_output_util.cc7
-rw-r--r--chromium/components/viz/common/frame_sinks/copy_output_util.h29
-rw-r--r--chromium/components/viz/common/gl_helper.cc1
-rw-r--r--chromium/components/viz/common/gl_helper_unittest.cc2
-rw-r--r--chromium/components/viz/common/gl_i420_converter_pixeltest.cc2
-rw-r--r--chromium/components/viz/common/gl_scaler.cc8
-rw-r--r--chromium/components/viz/common/gl_scaler_shader_pixeltest.cc6
-rw-r--r--chromium/components/viz/common/gpu/vulkan_in_process_context_provider.cc26
-rw-r--r--chromium/components/viz/common/hit_test/hit_test_data_builder.cc15
-rw-r--r--chromium/components/viz/common/quads/draw_quad.h6
-rw-r--r--chromium/components/viz/common/quads/draw_quad_perftest.cc4
-rw-r--r--chromium/components/viz/common/quads/draw_quad_unittest.cc52
-rw-r--r--chromium/components/viz/common/quads/frame_deadline.cc2
-rw-r--r--chromium/components/viz/common/quads/render_pass.cc6
-rw-r--r--chromium/components/viz/common/quads/render_pass.h6
-rw-r--r--chromium/components/viz/common/quads/render_pass_unittest.cc15
-rw-r--r--chromium/components/viz/common/quads/shared_quad_state.h7
-rw-r--r--chromium/components/viz/common/quads/stream_video_draw_quad.cc15
-rw-r--r--chromium/components/viz/common/quads/stream_video_draw_quad.h11
-rw-r--r--chromium/components/viz/common/quads/video_hole_draw_quad.cc48
-rw-r--r--chromium/components/viz/common/quads/video_hole_draw_quad.h51
-rw-r--r--chromium/components/viz/common/resources/resource_format_utils.cc8
-rw-r--r--chromium/components/viz/common/resources/returned_resource.h14
-rw-r--r--chromium/components/viz/common/skia_helper.cc1
-rw-r--r--chromium/components/viz/common/surfaces/child_local_surface_id_allocator.cc41
-rw-r--r--chromium/components/viz/common/surfaces/child_local_surface_id_allocator.h12
-rw-r--r--chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.cc15
-rw-r--r--chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.h2
-rw-r--r--chromium/components/viz/common/viz_utils.cc19
-rw-r--r--chromium/components/viz/common/viz_utils.h16
-rw-r--r--chromium/components/viz/common/yuv_readback_unittest.cc6
-rw-r--r--chromium/components/viz/demo/BUILD.gn83
-rw-r--r--chromium/components/viz/demo/DEPS17
-rw-r--r--chromium/components/viz/demo/client/DEPS3
-rw-r--r--chromium/components/viz/demo/client/demo_client.cc188
-rw-r--r--chromium/components/viz/demo/client/demo_client.h123
-rw-r--r--chromium/components/viz/demo/demo_main.cc199
-rw-r--r--chromium/components/viz/demo/host/DEPS6
-rw-r--r--chromium/components/viz/demo/host/demo_host.cc169
-rw-r--r--chromium/components/viz/demo/host/demo_host.h70
-rw-r--r--chromium/components/viz/demo/service/DEPS6
-rw-r--r--chromium/components/viz/demo/service/demo_service.cc29
-rw-r--r--chromium/components/viz/demo/service/demo_service.h37
-rw-r--r--chromium/components/viz/host/DEPS1
-rw-r--r--chromium/components/viz/host/client_frame_sink_video_capturer.cc8
-rw-r--r--chromium/components/viz/host/client_frame_sink_video_capturer.h1
-rw-r--r--chromium/components/viz/host/gpu_client.cc1
-rw-r--r--chromium/components/viz/host/gpu_host_impl.cc4
-rw-r--r--chromium/components/viz/host/hit_test/hit_test_query.cc23
-rw-r--r--chromium/components/viz/host/hit_test/hit_test_query.h2
-rw-r--r--chromium/components/viz/host/hit_test/hit_test_query_fuzzer.cc3
-rw-r--r--chromium/components/viz/host/hit_test/hit_test_query_unittest.cc22
-rw-r--r--chromium/components/viz/host/host_frame_sink_manager.cc3
-rw-r--r--chromium/components/viz/host/host_frame_sink_manager.h5
-rw-r--r--chromium/components/viz/host/host_gpu_memory_buffer_manager.cc1
-rw-r--r--chromium/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc9
-rw-r--r--chromium/components/viz/host/renderer_settings_creation.cc3
-rw-r--r--chromium/components/viz/service/BUILD.gn25
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/BUILD.gn79
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/DEPS10
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.cc54
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto62
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc142
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h25
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc142
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h58
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc118
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h51
-rwxr-xr-xchromium/components/viz/service/compositor_frame_fuzzer/generate_renderpass_binary.py39
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/1_quad_renderpass.asciipb63
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/2_quad_renderpass.asciipb112
-rw-r--r--chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/solid_color_tiled_background_with_2_quads_on_top.asciipb406
-rw-r--r--chromium/components/viz/service/display/bsp_tree_perftest.cc6
-rw-r--r--chromium/components/viz/service/display/ca_layer_overlay.cc9
-rw-r--r--chromium/components/viz/service/display/copy_output_scaling_pixeltest.cc4
-rw-r--r--chromium/components/viz/service/display/dc_layer_overlay.cc245
-rw-r--r--chromium/components/viz/service/display/dc_layer_overlay.h24
-rw-r--r--chromium/components/viz/service/display/direct_renderer.cc61
-rw-r--r--chromium/components/viz/service/display/direct_renderer.h16
-rw-r--r--chromium/components/viz/service/display/display.cc47
-rw-r--r--chromium/components/viz/service/display/display.h10
-rw-r--r--chromium/components/viz/service/display/display_perftest.cc4
-rw-r--r--chromium/components/viz/service/display/display_resource_provider.cc106
-rw-r--r--chromium/components/viz/service/display/display_resource_provider.h14
-rw-r--r--chromium/components/viz/service/display/display_resource_provider_unittest.cc57
-rw-r--r--chromium/components/viz/service/display/display_scheduler.cc1
-rw-r--r--chromium/components/viz/service/display/display_unittest.cc63
-rw-r--r--chromium/components/viz/service/display/gl_renderer.cc87
-rw-r--r--chromium/components/viz/service/display/gl_renderer.h13
-rw-r--r--chromium/components/viz/service/display/gl_renderer_copier.cc102
-rw-r--r--chromium/components/viz/service/display/gl_renderer_copier.h51
-rw-r--r--chromium/components/viz/service/display/gl_renderer_copier_pixeltest.cc33
-rw-r--r--chromium/components/viz/service/display/gl_renderer_copier_unittest.cc5
-rw-r--r--chromium/components/viz/service/display/gl_renderer_unittest.cc54
-rw-r--r--chromium/components/viz/service/display/output_surface.cc9
-rw-r--r--chromium/components/viz/service/display/output_surface.h27
-rw-r--r--chromium/components/viz/service/display/overlay_candidate.cc159
-rw-r--r--chromium/components/viz/service/display/overlay_candidate.h6
-rw-r--r--chromium/components/viz/service/display/overlay_processor.cc79
-rw-r--r--chromium/components/viz/service/display/overlay_processor.h16
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_fullscreen.cc4
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_fullscreen.h2
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_single_on_top.cc4
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_single_on_top.h2
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_underlay.cc4
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_underlay.h2
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_underlay_cast.cc22
-rw-r--r--chromium/components/viz/service/display/overlay_strategy_underlay_cast.h2
-rw-r--r--chromium/components/viz/service/display/overlay_unittest.cc499
-rw-r--r--chromium/components/viz/service/display/renderer_pixeltest.cc250
-rw-r--r--chromium/components/viz/service/display/resource_metadata.h3
-rw-r--r--chromium/components/viz/service/display/skia_output_surface.h23
-rw-r--r--chromium/components/viz/service/display/skia_renderer.cc380
-rw-r--r--chromium/components/viz/service/display/skia_renderer.h44
-rw-r--r--chromium/components/viz/service/display/software_renderer.cc72
-rw-r--r--chromium/components/viz/service/display/software_renderer.h3
-rw-r--r--chromium/components/viz/service/display/surface_aggregator.cc63
-rw-r--r--chromium/components/viz/service/display/surface_aggregator.h13
-rw-r--r--chromium/components/viz/service/display/surface_aggregator_perftest.cc4
-rw-r--r--chromium/components/viz/service/display/surface_aggregator_pixeltest.cc33
-rw-r--r--chromium/components/viz/service/display/surface_aggregator_unittest.cc898
-rw-r--r--chromium/components/viz/service/display_embedder/DEPS2
-rw-r--r--chromium/components/viz/service/display_embedder/buffer_queue.cc56
-rw-r--r--chromium/components/viz/service/display_embedder/buffer_queue.h1
-rw-r--r--chromium/components/viz/service/display_embedder/buffer_queue_unittest.cc19
-rw-r--r--chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc68
-rw-r--r--chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h15
-rw-r--r--chromium/components/viz/service/display_embedder/direct_context_provider.cc340
-rw-r--r--chromium/components/viz/service/display_embedder/direct_context_provider.h151
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface.cc17
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface.h3
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_android.cc12
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_android.h3
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc14
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h1
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc53
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h9
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_ozone.cc8
-rw-r--r--chromium/components/viz/service/display_embedder/gl_output_surface_ozone.h3
-rw-r--r--chromium/components/viz/service/display_embedder/gpu_display_provider.cc62
-rw-r--r--chromium/components/viz/service/display_embedder/gpu_display_provider.h6
-rw-r--r--chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.cc93
-rw-r--r--chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.h30
-rw-r--r--chromium/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc87
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl.cc318
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl.h59
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc519
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h163
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc971
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h126
-rw-r--r--chromium/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc70
-rw-r--r--chromium/components/viz/service/display_embedder/software_output_device_win.cc7
-rw-r--r--chromium/components/viz/service/display_embedder/software_output_surface.cc44
-rw-r--r--chromium/components/viz/service/display_embedder/software_output_surface.h19
-rw-r--r--chromium/components/viz/service/display_embedder/viz_process_context_provider.cc28
-rw-r--r--chromium/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc2
-rw-r--r--chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.cc47
-rw-r--r--chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.h17
-rw-r--r--chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc39
-rw-r--r--chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.cc11
-rw-r--r--chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.h3
-rw-r--r--chromium/components/viz/service/frame_sinks/external_begin_frame_source_android_unittest.cc17
-rw-r--r--chromium/components/viz/service/frame_sinks/frame_sink_manager_impl.cc7
-rw-r--r--chromium/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc13
-rw-r--r--chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc8
-rw-r--r--chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h1
-rw-r--r--chromium/components/viz/service/frame_sinks/surface_references_unittest.cc11
-rw-r--r--chromium/components/viz/service/frame_sinks/surface_synchronization_unittest.cc109
-rw-r--r--chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc159
-rw-r--r--chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h21
-rw-r--r--chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc482
-rw-r--r--chromium/components/viz/service/frame_sinks/video_capture/video_capture_overlay_unittest.cc2
-rw-r--r--chromium/components/viz/service/frame_sinks/video_detector_unittest.cc19
-rw-r--r--chromium/components/viz/service/gl/gpu_service_impl.cc25
-rw-r--r--chromium/components/viz/service/gl/gpu_service_impl.h133
-rw-r--r--chromium/components/viz/service/gl/gpu_service_impl_unittest.cc2
-rw-r--r--chromium/components/viz/service/hit_test/hit_test_aggregator_unittest.cc13
-rw-r--r--chromium/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java11
-rw-r--r--chromium/components/viz/service/main/BUILD.gn2
-rw-r--r--chromium/components/viz/service/main/viz_compositor_thread_runner.cc8
-rw-r--r--chromium/components/viz/service/main/viz_main_impl.cc6
-rw-r--r--chromium/components/viz/service/main/viz_main_impl.h2
-rw-r--r--chromium/components/viz/service/surfaces/surface.cc56
-rw-r--r--chromium/components/viz/service/surfaces/surface.h4
-rw-r--r--chromium/components/viz/service/surfaces/surface_allocation_group.cc115
-rw-r--r--chromium/components/viz/service/surfaces/surface_allocation_group.h79
-rw-r--r--chromium/components/viz/service/surfaces/surface_client.h3
-rw-r--r--chromium/components/viz/service/surfaces/surface_manager.cc162
-rw-r--r--chromium/components/viz/service/surfaces/surface_manager.h32
-rw-r--r--chromium/components/viz/service/surfaces/surface_unittest.cc1
-rw-r--r--chromium/components/viz/test/BUILD.gn6
-rw-r--r--chromium/components/web_cache/browser/web_cache_manager.cc18
-rw-r--r--chromium/components/web_resource/resource_request_allowed_notifier.cc1
-rw-r--r--chromium/components/web_resource/resource_request_allowed_notifier_test_util.cc1
-rw-r--r--chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc2
-rw-r--r--chromium/components/web_resource/web_resource_service_unittest.cc2
-rw-r--r--chromium/components/web_restrictions/browser/web_restrictions_client.cc13
-rw-r--r--chromium/components/webcrypto/algorithms/aes.cc2
-rw-r--r--chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc12
-rw-r--r--chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc6
-rw-r--r--chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc10
-rw-r--r--chromium/components/webcrypto/algorithms/aes_kw_unittest.cc27
-rw-r--r--chromium/components/webcrypto/algorithms/ecdh_unittest.cc19
-rw-r--r--chromium/components/webcrypto/algorithms/ecdsa_unittest.cc22
-rw-r--r--chromium/components/webcrypto/algorithms/hmac_unittest.cc6
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc6
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc6
-rw-r--r--chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc24
-rw-r--r--chromium/components/webcrypto/algorithms/sha_unittest.cc12
-rw-r--r--chromium/components/webcrypto/algorithms/test_helpers.cc85
-rw-r--r--chromium/components/webcrypto/algorithms/test_helpers.h17
-rw-r--r--chromium/components/webcrypto/jwk.cc39
-rw-r--r--chromium/components/webcrypto/jwk.h4
-rw-r--r--chromium/components/webdata/common/web_database_migration_unittest.cc2
-rw-r--r--chromium/components/webdata/common/web_database_service.h2
-rw-r--r--chromium/components/webrtc_logging/browser/log_cleanup.cc3
-rw-r--r--chromium/components/wifi/fake_wifi_service.cc5
-rw-r--r--chromium/components/wifi/wifi_service_mac.mm9
-rw-r--r--chromium/components/wifi/wifi_service_win.cc23
-rw-r--r--chromium/components/zoom/page_zoom.cc1
-rw-r--r--chromium/components/zoom/zoom_controller.cc1
-rw-r--r--chromium/components/zucchini/main_utils.cc2
-rw-r--r--chromium/components/zucchini/rel32_utils.h118
-rw-r--r--chromium/components/zucchini/rel32_utils_unittest.cc435
2453 files changed, 68885 insertions, 34474 deletions
diff --git a/chromium/components/BUILD.gn b/chromium/components/BUILD.gn
index 9e87ff42ea2..68fcbda884d 100644
--- a/chromium/components/BUILD.gn
+++ b/chromium/components/BUILD.gn
@@ -90,6 +90,7 @@ test("components_unittests") {
"//components/cloud_devices/common:unit_tests",
"//components/component_updater:unit_tests",
"//components/consent_auditor:unit_tests",
+ "//components/content_capture/common:unit_tests",
"//components/content_settings/core/browser:unit_tests",
"//components/content_settings/core/common:unit_tests",
"//components/crx_file:unit_tests",
@@ -213,6 +214,7 @@ test("components_unittests") {
"//components/cast_certificate:unit_tests",
"//components/cast_channel:unit_tests",
"//components/certificate_transparency:unit_tests",
+ "//components/content_capture/browser:unit_tests",
"//components/contextual_search/core:unit_tests",
"//components/crash/content/app:unit_tests",
"//components/crash/content/browser:unit_tests",
@@ -290,6 +292,7 @@ test("components_unittests") {
"//components/cdm/browser:unit_tests",
"//components/crash/android:java",
"//components/crash/android:unit_tests",
+ "//components/download/internal/common:internal_java",
"//components/gcm_driver/instance_id:test_support",
"//components/gcm_driver/instance_id/android:instance_id_driver_java",
"//components/gcm_driver/instance_id/android:instance_id_driver_test_support_java",
@@ -391,6 +394,7 @@ test("components_unittests") {
repack("components_tests_pak") {
sources = [
"$root_gen_dir/components/components_resources.pak",
+ "$root_gen_dir/components/strings/components_locale_settings_en-US.pak",
"$root_gen_dir/components/strings/components_strings_en-US.pak",
]
@@ -547,6 +551,7 @@ if (!is_ios) {
deps += [
"//components/autofill_assistant/browser",
"//components/autofill_assistant/browser:proto",
+ "//components/download/internal/common:internal_java",
"//content/public/test/android:web_test_java_support",
"//content/test:web_test_support",
"//testing/android/native_test:native_test_support",
diff --git a/chromium/components/OWNERS b/chromium/components/OWNERS
index 50c10c453c2..99f4521ed90 100644
--- a/chromium/components/OWNERS
+++ b/chromium/components/OWNERS
@@ -11,7 +11,7 @@ per-file browsing_data_strings.grdp=file://components/browsing_data/OWNERS
per-file crash_strings.grdp=file://components/crash/OWNERS
per-file dom_distiller_strings.grdp=file://components/dom_distiller/OWNERS
per-file error_page_strings.grdp=file://components/error_page/OWNERS
-per-file management_strings.grdp=file://components/policy/OWNERS
+per-file management_strings.grdp=file://docs/privacy/OWNERS
per-file ntp_snippets_strings.grdp=file://components/ntp_snippets/OWNERS
per-file omnibox_strings.grdp=file://components/omnibox/OWNERS
per-file page_info_strings.grdp=file://chrome/browser/ui/page_info/OWNERS
@@ -19,6 +19,7 @@ per-file password_manager_strings.grdp=file://components/password_manager/OWNERS
per-file payments_strings.grdp=file://components/payments/OWNERS
per-file pdf_strings.grdp=file://pdf/OWNERS
per-file policy_strings.grdp=file://components/policy/OWNERS
+per-file print_media_strings.grdp=file://components/printing/OWNERS
per-file printing_component_strings.grdp=file://components/printing/OWNERS
per-file reset_password_strings.grdp=file://components/safe_browsing/OWNERS
per-file security_interstitials_strings.grdp=file://components/security_interstitials/OWNERS
@@ -34,6 +35,7 @@ per-file web_contents_delegate_android_strings.grdp=file://components/embedder_s
# Translation artifacts:
per-file *.xtb=file://tools/translation/TRANSLATION_OWNERS
-# These are for the common case of adding or removing tests. If you're making
-# structural changes, please get a review from one of the overall components
-# OWNERS.
+# This is for the common case of adding or removing tests or files. If you're
+# making structural changes, please get a review from one of the overall
+# components OWNERS.
+per-file BUILD.gn=file://build/OWNERS
diff --git a/chromium/components/account_id/account_id.cc b/chromium/components/account_id/account_id.cc
index 8b5eb0a139a..859cd4a6cbb 100644
--- a/chromium/components/account_id/account_id.cc
+++ b/chromium/components/account_id/account_id.cc
@@ -241,7 +241,7 @@ std::string AccountId::Serialize() const {
bool AccountId::Deserialize(const std::string& serialized,
AccountId* account_id) {
base::JSONReader reader;
- std::unique_ptr<const base::Value> value(reader.Read(serialized));
+ std::unique_ptr<const base::Value> value(reader.ReadDeprecated(serialized));
const base::DictionaryValue* dictionary_value = nullptr;
if (!value || !value->GetAsDictionary(&dictionary_value))
diff --git a/chromium/components/arc/BUILD.gn b/chromium/components/arc/BUILD.gn
index 8a54e198fd9..40d99691681 100644
--- a/chromium/components/arc/BUILD.gn
+++ b/chromium/components/arc/BUILD.gn
@@ -43,6 +43,8 @@ static_library("arc") {
"lock_screen/arc_lock_screen_bridge.h",
"metrics/arc_metrics_service.cc",
"metrics/arc_metrics_service.h",
+ "metrics/stability_metrics_manager.cc",
+ "metrics/stability_metrics_manager.h",
"midis/arc_midis_bridge.cc",
"midis/arc_midis_bridge.h",
"net/always_on_vpn_manager.cc",
@@ -68,7 +70,6 @@ static_library("arc") {
"volume_mounter/arc_volume_mounter_bridge.h",
"wake_lock/arc_wake_lock_bridge.cc",
"wake_lock/arc_wake_lock_bridge.h",
- "wake_lock/wake_lock_observer.h",
]
public_deps = [
@@ -81,8 +82,8 @@ static_library("arc") {
"//ash:ash",
"//ash/public/cpp",
"//base",
- "//chromeos:chromeos_constants",
"//chromeos/audio",
+ "//chromeos/constants",
"//chromeos/dbus",
"//chromeos/dbus:login_manager_proto",
"//chromeos/dbus:power_manager_proto",
@@ -114,6 +115,7 @@ static_library("arc") {
"//ui/base:base",
"//ui/base/clipboard",
"//ui/base/ime",
+ "//ui/chromeos/strings",
"//ui/display/manager",
"//ui/events",
"//ui/events:dom_keycode_converter",
@@ -152,6 +154,23 @@ static_library("arc_base_enums") {
]
}
+static_library("arc_base_utils") {
+ sources = [
+ "arc_features.cc",
+ "arc_features.h",
+ "arc_util.cc",
+ "arc_util.h",
+ ]
+
+ deps = [
+ "//ash/public/cpp",
+ "//base",
+ "//chromeos/constants",
+ "//chromeos/dbus",
+ "//ui/aura",
+ ]
+}
+
static_library("arc_base") {
# TODO(hidehiko): Revisit here and move back some files to "arc"
# on completion to move ArcSession task to ArcSessionManager.
@@ -167,8 +186,6 @@ static_library("arc_base") {
"arc_container_client_adapter.h",
"arc_data_remover.cc",
"arc_data_remover.h",
- "arc_features.cc",
- "arc_features.h",
"arc_features_parser.cc",
"arc_features_parser.h",
"arc_service_manager.cc",
@@ -179,8 +196,6 @@ static_library("arc_base") {
"arc_session_impl.h",
"arc_session_runner.cc",
"arc_session_runner.h",
- "arc_util.cc",
- "arc_util.h",
"arc_vm_client_adapter.cc",
"arc_vm_client_adapter.h",
]
@@ -188,7 +203,7 @@ static_library("arc_base") {
deps = [
"//ash/public/cpp",
"//base",
- "//chromeos:chromeos_constants",
+ "//chromeos/constants",
"//chromeos/cryptohome",
"//chromeos/dbus",
"//chromeos/dbus:login_manager_proto",
@@ -204,6 +219,7 @@ static_library("arc_base") {
public_deps = [
":arc_base_enums",
+ ":arc_base_utils",
":connection_holder",
":prefs",
"//components/arc/common",
@@ -316,6 +332,7 @@ source_set("unit_tests") {
"intent_helper/intent_filter_unittest.cc",
"intent_helper/link_handler_model_unittest.cc",
"metrics/arc_metrics_service_unittest.cc",
+ "metrics/stability_metrics_manager_unittest.cc",
"net/always_on_vpn_manager_unittest.cc",
"net/arc_net_host_impl_unittest.cc",
"power/arc_power_bridge_unittest.cc",
@@ -328,7 +345,7 @@ source_set("unit_tests") {
"//ash/public/cpp",
"//base",
"//base/test:test_support",
- "//chromeos:chromeos_constants",
+ "//chromeos/constants",
"//chromeos/cryptohome:test_support",
"//chromeos/dbus:power_manager_proto",
"//chromeos/dbus:test_support",
diff --git a/chromium/components/arc/arc_bridge_host_impl.cc b/chromium/components/arc/arc_bridge_host_impl.cc
index 9c21978b8a0..46562959b1b 100644
--- a/chromium/components/arc/arc_bridge_host_impl.cc
+++ b/chromium/components/arc/arc_bridge_host_impl.cc
@@ -12,6 +12,52 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "components/arc/arc_bridge_service.h"
+#include "components/arc/common/accessibility_helper.mojom.h"
+#include "components/arc/common/app.mojom.h"
+#include "components/arc/common/app_permissions.mojom.h"
+#include "components/arc/common/appfuse.mojom.h"
+#include "components/arc/common/audio.mojom.h"
+#include "components/arc/common/auth.mojom.h"
+#include "components/arc/common/backup_settings.mojom.h"
+#include "components/arc/common/bluetooth.mojom.h"
+#include "components/arc/common/boot_phase_monitor.mojom.h"
+#include "components/arc/common/cast_receiver.mojom.h"
+#include "components/arc/common/cert_store.mojom.h"
+#include "components/arc/common/clipboard.mojom.h"
+#include "components/arc/common/crash_collector.mojom.h"
+#include "components/arc/common/disk_quota.mojom.h"
+#include "components/arc/common/enterprise_reporting.mojom.h"
+#include "components/arc/common/file_system.mojom.h"
+#include "components/arc/common/ime.mojom.h"
+#include "components/arc/common/input_method_manager.mojom.h"
+#include "components/arc/common/intent_helper.mojom.h"
+#include "components/arc/common/kiosk.mojom.h"
+#include "components/arc/common/lock_screen.mojom.h"
+#include "components/arc/common/media_session.mojom.h"
+#include "components/arc/common/metrics.mojom.h"
+#include "components/arc/common/midis.mojom.h"
+#include "components/arc/common/net.mojom.h"
+#include "components/arc/common/obb_mounter.mojom.h"
+#include "components/arc/common/oemcrypto.mojom.h"
+#include "components/arc/common/pip.mojom.h"
+#include "components/arc/common/policy.mojom.h"
+#include "components/arc/common/power.mojom.h"
+#include "components/arc/common/print.mojom.h"
+#include "components/arc/common/process.mojom.h"
+#include "components/arc/common/property.mojom.h"
+#include "components/arc/common/rotation_lock.mojom.h"
+#include "components/arc/common/screen_capture.mojom.h"
+#include "components/arc/common/storage_manager.mojom.h"
+#include "components/arc/common/timer.mojom.h"
+#include "components/arc/common/tracing.mojom.h"
+#include "components/arc/common/tts.mojom.h"
+#include "components/arc/common/usb_host.mojom.h"
+#include "components/arc/common/video.mojom.h"
+#include "components/arc/common/voice_interaction_arc_home.mojom.h"
+#include "components/arc/common/voice_interaction_framework.mojom.h"
+#include "components/arc/common/volume_mounter.mojom.h"
+#include "components/arc/common/wake_lock.mojom.h"
+#include "components/arc/common/wallpaper.mojom.h"
#include "components/arc/mojo_channel.h"
#include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/connector.h"
diff --git a/chromium/components/arc/arc_bridge_service.cc b/chromium/components/arc/arc_bridge_service.cc
index 3c1b50402bf..99eccc72248 100644
--- a/chromium/components/arc/arc_bridge_service.cc
+++ b/chromium/components/arc/arc_bridge_service.cc
@@ -4,7 +4,54 @@
#include "components/arc/arc_bridge_service.h"
+// These header is necessary for instantiation of ConnectionHolder.
+#include "components/arc/common/accessibility_helper.mojom.h"
+#include "components/arc/common/app.mojom.h"
+#include "components/arc/common/app_permissions.mojom.h"
+#include "components/arc/common/appfuse.mojom.h"
#include "components/arc/common/arc_bridge.mojom.h"
+#include "components/arc/common/audio.mojom.h"
+#include "components/arc/common/auth.mojom.h"
+#include "components/arc/common/backup_settings.mojom.h"
+#include "components/arc/common/bluetooth.mojom.h"
+#include "components/arc/common/boot_phase_monitor.mojom.h"
+#include "components/arc/common/cast_receiver.mojom.h"
+#include "components/arc/common/cert_store.mojom.h"
+#include "components/arc/common/clipboard.mojom.h"
+#include "components/arc/common/crash_collector.mojom.h"
+#include "components/arc/common/disk_quota.mojom.h"
+#include "components/arc/common/enterprise_reporting.mojom.h"
+#include "components/arc/common/file_system.mojom.h"
+#include "components/arc/common/ime.mojom.h"
+#include "components/arc/common/input_method_manager.mojom.h"
+#include "components/arc/common/intent_helper.mojom.h"
+#include "components/arc/common/kiosk.mojom.h"
+#include "components/arc/common/lock_screen.mojom.h"
+#include "components/arc/common/media_session.mojom.h"
+#include "components/arc/common/metrics.mojom.h"
+#include "components/arc/common/midis.mojom.h"
+#include "components/arc/common/net.mojom.h"
+#include "components/arc/common/obb_mounter.mojom.h"
+#include "components/arc/common/oemcrypto.mojom.h"
+#include "components/arc/common/pip.mojom.h"
+#include "components/arc/common/policy.mojom.h"
+#include "components/arc/common/power.mojom.h"
+#include "components/arc/common/print.mojom.h"
+#include "components/arc/common/process.mojom.h"
+#include "components/arc/common/property.mojom.h"
+#include "components/arc/common/rotation_lock.mojom.h"
+#include "components/arc/common/screen_capture.mojom.h"
+#include "components/arc/common/storage_manager.mojom.h"
+#include "components/arc/common/timer.mojom.h"
+#include "components/arc/common/tracing.mojom.h"
+#include "components/arc/common/tts.mojom.h"
+#include "components/arc/common/usb_host.mojom.h"
+#include "components/arc/common/video.mojom.h"
+#include "components/arc/common/voice_interaction_arc_home.mojom.h"
+#include "components/arc/common/voice_interaction_framework.mojom.h"
+#include "components/arc/common/volume_mounter.mojom.h"
+#include "components/arc/common/wake_lock.mojom.h"
+#include "components/arc/common/wallpaper.mojom.h"
namespace arc {
diff --git a/chromium/components/arc/arc_browser_context_keyed_service_factory_base.h b/chromium/components/arc/arc_browser_context_keyed_service_factory_base.h
index 86b664ba54c..04c5dda968a 100644
--- a/chromium/components/arc/arc_browser_context_keyed_service_factory_base.h
+++ b/chromium/components/arc/arc_browser_context_keyed_service_factory_base.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "components/arc/arc_service_manager.h"
diff --git a/chromium/components/arc/arc_features.cc b/chromium/components/arc/arc_features.cc
index cc2630396b8..0e1b8c2fc0a 100644
--- a/chromium/components/arc/arc_features.cc
+++ b/chromium/components/arc/arc_features.cc
@@ -43,6 +43,10 @@ const base::Feature kEnableUnifiedAudioFocusFeature{
const base::Feature kFilePickerExperimentFeature{
"ArcFilePickerExperiment", base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls experimental ARC graphic buffers visualization tools.
+const base::Feature kGraphicBuffersVisualizationTool{
+ "ArcGraphicBuffersVisualizationTool", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls experimental native bridge feature for ARC.
const base::Feature kNativeBridgeExperimentFeature {
"ArcNativeBridgeExperiment", base::FEATURE_ENABLED_BY_DEFAULT
diff --git a/chromium/components/arc/arc_features.h b/chromium/components/arc/arc_features.h
index ad3c7f00dc7..0fea34b662b 100644
--- a/chromium/components/arc/arc_features.h
+++ b/chromium/components/arc/arc_features.h
@@ -20,6 +20,7 @@ extern const base::Feature kEnableDocumentsProviderInFilesAppFeature;
extern const base::Feature kEnableRegularToChildTransitionFeature;
extern const base::Feature kEnableUnifiedAudioFocusFeature;
extern const base::Feature kFilePickerExperimentFeature;
+extern const base::Feature kGraphicBuffersVisualizationTool;
extern const base::Feature kNativeBridgeExperimentFeature;
extern const base::Feature kSmartTextSelectionFeature;
extern const base::Feature kUsbHostFeature;
diff --git a/chromium/components/arc/arc_features_parser.cc b/chromium/components/arc/arc_features_parser.cc
index 77b9c2ef956..8c031c1f3d6 100644
--- a/chromium/components/arc/arc_features_parser.cc
+++ b/chromium/components/arc/arc_features_parser.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/stl_util.h"
@@ -28,8 +29,8 @@ base::Optional<ArcFeatures> ParseFeaturesJson(base::StringPiece input_json) {
int error_code;
std::string error_msg;
std::unique_ptr<base::Value> json_value =
- base::JSONReader::ReadAndReturnError(input_json, base::JSON_PARSE_RFC,
- &error_code, &error_msg);
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ input_json, base::JSON_PARSE_RFC, &error_code, &error_msg);
if (!json_value || !json_value->is_dict()) {
LOG(ERROR) << "Error parsing feature JSON: " << error_msg;
return base::nullopt;
@@ -109,12 +110,13 @@ base::Optional<ArcFeatures> ParseFeaturesJson(base::StringPiece input_json) {
base::Optional<ArcFeatures> ReadOnFileThread(const base::FilePath& file_path) {
DCHECK(!file_path.empty());
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
std::string input_json;
{
base::ScopedBlockingCall scoped_blocking_call(
- base::BlockingType::MAY_BLOCK);
+ FROM_HERE, base::BlockingType::MAY_BLOCK);
if (!base::ReadFileToString(file_path, &input_json)) {
PLOG(ERROR) << "Cannot read file " << file_path.value()
<< " into string.";
diff --git a/chromium/components/arc/arc_prefs.cc b/chromium/components/arc/arc_prefs.cc
index 1e567715b02..9213704e7a9 100644
--- a/chromium/components/arc/arc_prefs.cc
+++ b/chromium/components/arc/arc_prefs.cc
@@ -12,6 +12,9 @@
namespace arc {
namespace prefs {
+// ======== PROFILE PREFS ========
+// See below for local state prefs.
+
// A bool preference indicating whether traffic other than the VPN connection
// set via kAlwaysOnVpnPackage should be blackholed.
const char kAlwaysOnVpnLockdown[] = "arc.vpn.always_on.lockdown";
@@ -87,9 +90,6 @@ const char kArcSkippedReportingNotice[] = "arc.skipped.reporting.notice";
// the user directory (i.e., the user finished required migration.)
const char kArcCompatibleFilesystemChosen[] =
"arc.compatible_filesystem.chosen";
-// A preference that indicates that user accepted Voice Interaction Value Prop.
-const char kArcVoiceInteractionValuePropAccepted[] =
- "arc.voice_interaction_value_prop.accepted";
// Integer pref indicating the ecryptfs to ext4 migration strategy. One of
// options: forbidden = 0, migrate = 1, wipe = 2 or ask the user = 3.
const char kEcryptfsMigrationStrategy[] = "ecryptfs_migration_strategy";
@@ -112,13 +112,10 @@ const char kEngagementTimeOsVersion[] =
// engagement time was last recorded. Accumulated results are sent to UMA if day
// ID has changed.
const char kEngagementTimeDayId[] = "arc.metrics.engagement_time.day_id";
-// A preference that indicates the user has accepted voice interaction activity
-// control settings.
-const char kVoiceInteractionActivityControlAccepted[] =
- "settings.voice_interaction.activity_control.accepted";
// A preference that indicates the user has allowed voice interaction services
// to access the "context" (text and graphic content that is currently on
-// screen).
+// screen). This preference can be overridden by the
+// VoiceInteractionContextEnabled administrator policy.
const char kVoiceInteractionContextEnabled[] =
"settings.voice_interaction.context.enabled";
// A preference that indicates the user has enabled voice interaction services.
@@ -128,7 +125,8 @@ const char kVoiceInteractionEnabled[] = "settings.voice_interaction.enabled";
const char kVoiceInteractionHotwordAlwaysOn[] =
"settings.voice_interaction.hotword.always_on";
// A preference that indicates the user has allowed voice interaction services
-// to use hotword listening.
+// to use hotword listening. This preference can be overridden by the
+// VoiceInteractionHotwordEnabled administrator policy.
const char kVoiceInteractionHotwordEnabled[] =
"settings.voice_interaction.hotword.enabled";
// A preference that indicates whether microphone should be open when the voice
@@ -140,6 +138,18 @@ const char kVoiceInteractionLaunchWithMicOpen[] =
const char kVoiceInteractionNotificationEnabled[] =
"settings.voice_interaction.notification.enabled";
+// ======== LOCAL STATE PREFS ========
+
+// A dictionary preference that keeps track of stability metric values, which is
+// maintained by StabilityMetricsManager. Persisting values in local state is
+// required to include these metrics in the initial stability log in case of a
+// crash.
+const char kStabilityMetrics[] = "arc.metrics.stability";
+
+void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
+ registry->RegisterDictionaryPref(kStabilityMetrics);
+}
+
void RegisterProfilePrefs(PrefRegistrySimple* registry) {
// TODO(dspaid): Implement a mechanism to allow this to sync on first boot
// only.
@@ -163,8 +173,6 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) {
static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
// Sorted in lexicographical order.
- registry->RegisterBooleanPref(kVoiceInteractionActivityControlAccepted,
- false);
registry->RegisterBooleanPref(kAlwaysOnVpnLockdown, false);
registry->RegisterStringPref(kAlwaysOnVpnPackage, std::string());
registry->RegisterBooleanPref(kArcDataRemoveRequested, false);
@@ -179,7 +187,6 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(kArcSkippedReportingNotice, false);
registry->RegisterBooleanPref(kArcTermsAccepted, false);
registry->RegisterBooleanPref(kArcTermsShownInOobe, false);
- registry->RegisterBooleanPref(kArcVoiceInteractionValuePropAccepted, false);
registry->RegisterTimeDeltaPref(kEngagementTimeBackground, base::TimeDelta());
registry->RegisterIntegerPref(kEngagementTimeDayId, 0);
registry->RegisterTimeDeltaPref(kEngagementTimeForeground, base::TimeDelta());
@@ -187,7 +194,7 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterTimeDeltaPref(kEngagementTimeTotal, base::TimeDelta());
registry->RegisterBooleanPref(kVoiceInteractionContextEnabled, false);
registry->RegisterBooleanPref(kVoiceInteractionEnabled, false);
- registry->RegisterBooleanPref(kVoiceInteractionHotwordAlwaysOn, true);
+ registry->RegisterBooleanPref(kVoiceInteractionHotwordAlwaysOn, false);
registry->RegisterBooleanPref(kVoiceInteractionHotwordEnabled, false);
registry->RegisterBooleanPref(kVoiceInteractionNotificationEnabled, true);
registry->RegisterBooleanPref(kVoiceInteractionLaunchWithMicOpen, false);
diff --git a/chromium/components/arc/arc_prefs.h b/chromium/components/arc/arc_prefs.h
index ecfc6f248f3..1e0dc0a160b 100644
--- a/chromium/components/arc/arc_prefs.h
+++ b/chromium/components/arc/arc_prefs.h
@@ -12,41 +12,38 @@ class PrefRegistrySimple;
namespace arc {
namespace prefs {
-// Sorted in lexicographical order.
+// Profile prefs in lexicographical order. See below for local state prefs.
ARC_EXPORT extern const char kAlwaysOnVpnLockdown[];
ARC_EXPORT extern const char kAlwaysOnVpnPackage[];
ARC_EXPORT extern const char kArcActiveDirectoryPlayUserId[];
ARC_EXPORT extern const char kArcApps[];
ARC_EXPORT extern const char kArcBackupRestoreEnabled[];
+ARC_EXPORT extern const char kArcCompatibleFilesystemChosen[];
ARC_EXPORT extern const char kArcDataRemoveRequested[];
ARC_EXPORT extern const char kArcEnabled[];
ARC_EXPORT extern const char kArcFastAppReinstallPackages[];
ARC_EXPORT extern const char kArcFastAppReinstallStarted[];
ARC_EXPORT extern const char kArcInitialSettingsPending[];
-ARC_EXPORT extern const char kArcPolicyComplianceReported[];
-ARC_EXPORT extern const char kArcTermsAccepted[];
-ARC_EXPORT extern const char kArcTermsShownInOobe[];
ARC_EXPORT extern const char kArcLocationServiceEnabled[];
ARC_EXPORT extern const char kArcPackages[];
ARC_EXPORT extern const char kArcPaiStarted[];
+ARC_EXPORT extern const char kArcPolicyComplianceReported[];
ARC_EXPORT extern const char kArcProvisioningInitiatedFromOobe[];
-ARC_EXPORT extern const char kArcPushInstallAppsRequested[];
ARC_EXPORT extern const char kArcPushInstallAppsPending[];
+ARC_EXPORT extern const char kArcPushInstallAppsRequested[];
ARC_EXPORT extern const char kArcSetNotificationsEnabledDeferred[];
ARC_EXPORT extern const char kArcSignedIn[];
ARC_EXPORT extern const char kArcSkippedReportingNotice[];
ARC_EXPORT extern const char kArcSupervisionTransition[];
-ARC_EXPORT extern const char kArcCompatibleFilesystemChosen[];
-ARC_EXPORT extern const char kArcVoiceInteractionValuePropAccepted[];
+ARC_EXPORT extern const char kArcTermsAccepted[];
+ARC_EXPORT extern const char kArcTermsShownInOobe[];
ARC_EXPORT extern const char kEcryptfsMigrationStrategy[];
ARC_EXPORT extern const char kEngagementTimeBackground[];
ARC_EXPORT extern const char kEngagementTimeDayId[];
ARC_EXPORT extern const char kEngagementTimeForeground[];
ARC_EXPORT extern const char kEngagementTimeOsVersion[];
ARC_EXPORT extern const char kEngagementTimeTotal[];
-
// TODO(b/110211045): Move Assistant related prefs to ash.
-ARC_EXPORT extern const char kVoiceInteractionActivityControlAccepted[];
ARC_EXPORT extern const char kVoiceInteractionContextEnabled[];
ARC_EXPORT extern const char kVoiceInteractionEnabled[];
ARC_EXPORT extern const char kVoiceInteractionHotwordAlwaysOn[];
@@ -54,6 +51,10 @@ ARC_EXPORT extern const char kVoiceInteractionHotwordEnabled[];
ARC_EXPORT extern const char kVoiceInteractionLaunchWithMicOpen[];
ARC_EXPORT extern const char kVoiceInteractionNotificationEnabled[];
+// Local state prefs in lexicographical order.
+ARC_EXPORT extern const char kStabilityMetrics[];
+
+void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
void RegisterProfilePrefs(PrefRegistrySimple* registry);
} // namespace prefs
diff --git a/chromium/components/arc/arc_session_impl.cc b/chromium/components/arc/arc_session_impl.cc
index 891f62ad7e3..3dc198a1499 100644
--- a/chromium/components/arc/arc_session_impl.cc
+++ b/chromium/components/arc/arc_session_impl.cc
@@ -13,6 +13,7 @@
#include <vector>
#include "ash/public/cpp/default_scale_factor_retriever.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/location.h"
@@ -43,6 +44,9 @@ namespace {
constexpr char kArcBridgeSocketPath[] = "/run/chrome/arc_bridge.sock";
constexpr char kArcBridgeSocketGroup[] = "arc-bridge";
+constexpr char kOn[] = "on";
+constexpr char kOff[] = "off";
+
std::string GenerateRandomToken() {
char random_bytes[16];
base::RandBytes(random_bytes, 16);
@@ -371,6 +375,27 @@ void ArcSessionImpl::OnLcdDensity(int32_t lcd_density) {
base::FeatureList::IsEnabled(arc::kFilePickerExperimentFeature));
request.set_lcd_density(lcd_density);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ chromeos::switches::kArcPlayStoreAutoUpdate)) {
+ const std::string value =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ chromeos::switches::kArcPlayStoreAutoUpdate);
+ if (value == kOn) {
+ request.set_play_store_auto_update(
+ login_manager::
+ StartArcMiniContainerRequest_PlayStoreAutoUpdate_AUTO_UPDATE_ON);
+ VLOG(1) << "Play Store auto-update is forced on";
+ } else if (value == kOff) {
+ request.set_play_store_auto_update(
+ login_manager::
+ StartArcMiniContainerRequest_PlayStoreAutoUpdate_AUTO_UPDATE_OFF);
+ VLOG(1) << "Play Store auto-update is forced off";
+ } else {
+ LOG(ERROR) << "Invalid parameter " << value << " for "
+ << chromeos::switches::kArcPlayStoreAutoUpdate;
+ }
+ }
+
VLOG(1) << "Starting ARC mini instance with lcd_density="
<< request.lcd_density();
diff --git a/chromium/components/arc/arc_session_impl_unittest.cc b/chromium/components/arc/arc_session_impl_unittest.cc
index 3df6f4b8266..2cd6bae8313 100644
--- a/chromium/components/arc/arc_session_impl_unittest.cc
+++ b/chromium/components/arc/arc_session_impl_unittest.cc
@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/run_loop.h"
@@ -631,9 +632,9 @@ TEST_P(ArcSessionImplPackagesCacheModeTest, PackagesCacheModes) {
.packages_cache_mode());
}
-INSTANTIATE_TEST_CASE_P(,
- ArcSessionImplPackagesCacheModeTest,
- ::testing::ValuesIn(kPackagesCacheModeStates));
+INSTANTIATE_TEST_SUITE_P(,
+ ArcSessionImplPackagesCacheModeTest,
+ ::testing::ValuesIn(kPackagesCacheModeStates));
TEST_F(ArcSessionImplTest, DemoSession) {
auto arc_session = CreateArcSession();
diff --git a/chromium/components/arc/arc_session_runner.cc b/chromium/components/arc/arc_session_runner.cc
index 23cf4f20be3..c06d2f0b86d 100644
--- a/chromium/components/arc/arc_session_runner.cc
+++ b/chromium/components/arc/arc_session_runner.cc
@@ -4,6 +4,7 @@
#include "components/arc/arc_session_runner.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
diff --git a/chromium/components/arc/arc_util.cc b/chromium/components/arc/arc_util.cc
index 323d3d99ea3..4eaf4db07fa 100644
--- a/chromium/components/arc/arc_util.cc
+++ b/chromium/components/arc/arc_util.cc
@@ -8,6 +8,7 @@
#include <string>
#include "ash/public/cpp/app_types.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "chromeos/constants/chromeos_switches.h"
diff --git a/chromium/components/arc/bluetooth/bluetooth_type_converters.cc b/chromium/components/arc/bluetooth/bluetooth_type_converters.cc
index 9581d5138fc..1bcda4b89c8 100644
--- a/chromium/components/arc/bluetooth/bluetooth_type_converters.cc
+++ b/chromium/components/arc/bluetooth/bluetooth_type_converters.cc
@@ -84,38 +84,33 @@ TypeConverter<arc::mojom::BluetoothSdpAttributePtr,
size_t depth) {
auto result = arc::mojom::BluetoothSdpAttribute::New();
result->type = attr_bluez.type();
- result->type_size = 0;
-
+ result->type_size = attr_bluez.size();
switch (result->type) {
case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
+ result->value = base::Value();
+ return result;
case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
case bluez::BluetoothServiceAttributeValueBlueZ::INT:
+ result->value = base::Value(attr_bluez.value().GetInt());
+ return result;
+ case bluez::BluetoothServiceAttributeValueBlueZ::URL:
case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
- case bluez::BluetoothServiceAttributeValueBlueZ::URL:
- case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
- result->type_size = attr_bluez.size();
- std::string json;
- base::JSONWriter::Write(attr_bluez.value(), &json);
- result->json_value = std::move(json);
- break;
- }
+ result->value = base::Value(attr_bluez.value().GetString());
+ return result;
+ case bluez::BluetoothServiceAttributeValueBlueZ::BOOL:
+ result->value = base::Value(attr_bluez.value().GetBool());
+ return result;
case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE:
- if (depth + 1 >= arc::kBluetoothSDPMaxDepth) {
- result->type = bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE;
- result->type_size = 0;
- return result;
- }
- for (const auto& child : attr_bluez.sequence()) {
+ if (depth + 1 >= arc::kBluetoothSDPMaxDepth)
+ return Convert(bluez::BluetoothServiceAttributeValueBlueZ(), 0);
+ for (const auto& child : attr_bluez.sequence())
result->sequence.push_back(Convert(child, depth + 1));
- }
result->type_size = result->sequence.size();
- break;
+ return result;
default:
NOTREACHED();
}
-
- return result;
}
// static
@@ -124,47 +119,41 @@ TypeConverter<bluez::BluetoothServiceAttributeValueBlueZ,
arc::mojom::BluetoothSdpAttributePtr>::
Convert(const arc::mojom::BluetoothSdpAttributePtr& attr, size_t depth) {
bluez::BluetoothServiceAttributeValueBlueZ::Type type = attr->type;
+ if (type != bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE &&
+ !attr->value.has_value()) {
+ return bluez::BluetoothServiceAttributeValueBlueZ();
+ }
switch (type) {
case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE:
+ return bluez::BluetoothServiceAttributeValueBlueZ();
case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
case bluez::BluetoothServiceAttributeValueBlueZ::INT:
+ return bluez::BluetoothServiceAttributeValueBlueZ(
+ type, attr->type_size,
+ std::make_unique<base::Value>(attr->value->GetInt()));
+ case bluez::BluetoothServiceAttributeValueBlueZ::URL:
case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
- case bluez::BluetoothServiceAttributeValueBlueZ::URL:
- case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
- if (!attr->json_value.has_value()) {
- return bluez::BluetoothServiceAttributeValueBlueZ(
- bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
- std::make_unique<base::Value>());
- }
-
return bluez::BluetoothServiceAttributeValueBlueZ(
- type, static_cast<size_t>(attr->type_size),
- base::JSONReader::Read(attr->json_value.value()));
- }
+ type, attr->type_size,
+ std::make_unique<base::Value>(attr->value->GetString()));
+ case bluez::BluetoothServiceAttributeValueBlueZ::BOOL:
+ return bluez::BluetoothServiceAttributeValueBlueZ(
+ type, attr->type_size,
+ std::make_unique<base::Value>(attr->value->GetBool()));
case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE: {
- if (depth + 1 >= arc::kBluetoothSDPMaxDepth || attr->sequence.empty()) {
- return bluez::BluetoothServiceAttributeValueBlueZ(
- bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
- std::make_unique<base::Value>());
- }
-
- auto bluez_sequence = std::make_unique<
+ if (depth + 1 >= arc::kBluetoothSDPMaxDepth || attr->sequence.empty())
+ return bluez::BluetoothServiceAttributeValueBlueZ();
+ auto sequence = std::make_unique<
bluez::BluetoothServiceAttributeValueBlueZ::Sequence>();
- for (const auto& child : attr->sequence) {
- bluez_sequence->push_back(Convert(child, depth + 1));
- }
- return bluez::BluetoothServiceAttributeValueBlueZ(
- std::move(bluez_sequence));
- break;
+ for (const auto& child : attr->sequence)
+ sequence->emplace_back(Convert(child, depth + 1));
+ return bluez::BluetoothServiceAttributeValueBlueZ(std::move(sequence));
}
default:
NOTREACHED();
}
- return bluez::BluetoothServiceAttributeValueBlueZ(
- bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, 0,
- std::make_unique<base::Value>());
}
// static
diff --git a/chromium/components/arc/bluetooth/bluetooth_type_converters_unittest.cc b/chromium/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
index 213c8f0efdf..1cdbe259e11 100644
--- a/chromium/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
+++ b/chromium/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
@@ -9,8 +9,6 @@
#include <string>
#include <vector>
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
#include "base/values.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluetooth_uuid.h"
@@ -31,16 +29,14 @@ arc::mojom::BluetoothSdpAttributePtr CreateDeepMojoSequenceAttribute(
if (depth > 0u) {
value->type = bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE;
- value->json_value.reset();
+ value->value = base::Value();
value->sequence.push_back(CreateDeepMojoSequenceAttribute(depth - 1));
value->type_size = static_cast<uint32_t>(value->sequence.size());
} else {
uint16_t data = 3;
value->type = bluez::BluetoothServiceAttributeValueBlueZ::UINT;
value->type_size = static_cast<uint32_t>(sizeof(data));
- std::string json;
- base::JSONWriter::Write(base::Value(static_cast<int>(data)), &json);
- value->json_value = std::move(json);
+ value->value = base::Value(data);
}
return value;
}
@@ -81,12 +77,6 @@ size_t GetDepthOfBlueZAttribute(
return depth;
}
-std::string ValueToJson(const base::Value& value) {
- std::string json;
- base::JSONWriter::Write(value, &json);
- return json;
-}
-
} // namespace
namespace mojo {
@@ -135,7 +125,7 @@ TEST(BluetoothTypeConverterTest,
auto mojo = arc::mojom::BluetoothSdpAttribute::New();
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::BOOL;
mojo->type_size = static_cast<uint32_t>(sizeof(bool));
- mojo->json_value = ValueToJson(base::Value(true));
+ mojo->value = base::Value(true);
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -151,7 +141,7 @@ TEST(BluetoothTypeConverterTest,
auto mojo = arc::mojom::BluetoothSdpAttribute::New();
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::UINT;
mojo->type_size = static_cast<uint32_t>(sizeof(kValue));
- mojo->json_value = ValueToJson(base::Value(static_cast<int>(kValue)));
+ mojo->value = base::Value(static_cast<int>(kValue));
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -167,7 +157,7 @@ TEST(BluetoothTypeConverterTest,
auto mojo = arc::mojom::BluetoothSdpAttribute::New();
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::INT;
mojo->type_size = static_cast<uint32_t>(sizeof(kValue));
- mojo->json_value = ValueToJson(base::Value(static_cast<int>(kValue)));
+ mojo->value = base::Value(static_cast<int>(kValue));
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -186,7 +176,7 @@ TEST(BluetoothTypeConverterTest,
// UUIDs are all stored in string form, but it can be converted to one of
// UUID16, UUID32 and UUID128.
mojo->type_size = static_cast<uint32_t>(sizeof(uint16_t));
- mojo->json_value = ValueToJson(base::Value(kValue));
+ mojo->value = base::Value(kValue);
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -206,7 +196,7 @@ TEST(BluetoothTypeConverterTest,
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::STRING;
// Subtract '\0'-terminate size.
mojo->type_size = static_cast<uint32_t>(kValueSize);
- mojo->json_value = ValueToJson(base::Value(kValue));
+ mojo->value = base::Value(kValue);
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -228,7 +218,7 @@ TEST(BluetoothTypeConverterTest, ConvertMojoSequenceAttributeToBlueZAttribute) {
auto value_uuid = arc::mojom::BluetoothSdpAttribute::New();
value_uuid->type = bluez::BluetoothServiceAttributeValueBlueZ::UUID;
value_uuid->type_size = static_cast<uint32_t>(sizeof(uint16_t));
- value_uuid->json_value = ValueToJson(base::Value(kL2capUuid));
+ value_uuid->value = base::Value(kL2capUuid);
sequence_mojo->sequence.push_back(std::move(value_uuid));
}
{
@@ -236,12 +226,11 @@ TEST(BluetoothTypeConverterTest, ConvertMojoSequenceAttributeToBlueZAttribute) {
auto value_channel = arc::mojom::BluetoothSdpAttribute::New();
value_channel->type = bluez::BluetoothServiceAttributeValueBlueZ::UINT;
value_channel->type_size = static_cast<uint32_t>(sizeof(kL2capChannel));
- value_channel->json_value =
- ValueToJson(base::Value(static_cast<int>(kL2capChannel)));
+ value_channel->value = base::Value(static_cast<int>(kL2capChannel));
sequence_mojo->sequence.push_back(std::move(value_channel));
}
sequence_mojo->type_size = sequence_mojo->sequence.size();
- sequence_mojo->json_value = base::nullopt;
+ sequence_mojo->value = base::nullopt;
auto sequence_blue_z =
sequence_mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -275,7 +264,7 @@ TEST(BluetoothTypeConverterTest,
auto mojo = arc::mojom::BluetoothSdpAttribute::New();
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::UINT;
mojo->type_size = static_cast<uint32_t>(sizeof(uint32_t));
- mojo->json_value = base::nullopt;
+ mojo->value = base::nullopt;
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -291,7 +280,7 @@ TEST(BluetoothTypeConverterTest,
auto mojo = arc::mojom::BluetoothSdpAttribute::New();
mojo->type = bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE;
mojo->type_size = 0;
- mojo->json_value = base::nullopt;
+ mojo->value = base::nullopt;
auto blue_z = mojo.To<bluez::BluetoothServiceAttributeValueBlueZ>();
@@ -324,10 +313,8 @@ TEST(BluetoothTypeConverterTest,
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE, mojo->type);
EXPECT_EQ(0u, mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- EXPECT_TRUE(value->is_none());
+ ASSERT_TRUE(mojo->value.has_value());
+ EXPECT_TRUE(mojo->value->is_none());
}
TEST(BluetoothTypeConverterTest,
@@ -343,11 +330,9 @@ TEST(BluetoothTypeConverterTest,
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::UINT, mojo->type);
EXPECT_EQ(sizeof(kValue), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_int());
- EXPECT_EQ(kValue, static_cast<uint16_t>(value->GetInt()));
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_int());
+ EXPECT_EQ(kValue, static_cast<uint16_t>(mojo->value->GetInt()));
}
TEST(BluetoothTypeConverterTest,
@@ -362,11 +347,9 @@ TEST(BluetoothTypeConverterTest,
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::BOOL, mojo->type);
EXPECT_EQ(static_cast<uint32_t>(sizeof(bool)), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_bool());
- EXPECT_FALSE(value->GetBool());
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_bool());
+ EXPECT_FALSE(mojo->value->GetBool());
}
TEST(BluetoothTypeConverterTest,
@@ -382,11 +365,9 @@ TEST(BluetoothTypeConverterTest,
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::UUID, mojo->type);
EXPECT_EQ(static_cast<uint32_t>(sizeof(uint16_t)), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_string());
- EXPECT_EQ(kValue, value->GetString());
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_string());
+ EXPECT_EQ(kValue, mojo->value->GetString());
}
TEST(BluetoothTypeConverterTest,
@@ -403,11 +384,9 @@ TEST(BluetoothTypeConverterTest,
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::STRING, mojo->type);
EXPECT_EQ(static_cast<uint32_t>(kValueSize), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_string());
- EXPECT_EQ(kValue, value->GetString());
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_string());
+ EXPECT_EQ(kValue, mojo->value->GetString());
}
TEST(BluetoothTypeConverterTest, ConvertBlueZSequenceAttributeToMojoAttribute) {
@@ -438,22 +417,18 @@ TEST(BluetoothTypeConverterTest, ConvertBlueZSequenceAttributeToMojoAttribute) {
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::UUID, mojo->type);
EXPECT_EQ(static_cast<uint32_t>(sizeof(uint16_t)), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_string());
- EXPECT_EQ(kL2capUuid, value->GetString());
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_string());
+ EXPECT_EQ(kL2capUuid, mojo->value->GetString());
}
{
const auto& mojo = sequence_mojo->sequence[1];
EXPECT_EQ(bluez::BluetoothServiceAttributeValueBlueZ::UINT, mojo->type);
EXPECT_EQ(static_cast<uint32_t>(sizeof(uint16_t)), mojo->type_size);
- ASSERT_TRUE(mojo->json_value.has_value());
- auto value = base::JSONReader::Read(mojo->json_value.value());
- ASSERT_TRUE(value);
- ASSERT_TRUE(value->is_int());
- EXPECT_EQ(kL2capChannel, static_cast<uint16_t>(value->GetInt()));
+ ASSERT_TRUE(mojo->value.has_value());
+ ASSERT_TRUE(mojo->value->is_int());
+ EXPECT_EQ(kL2capChannel, static_cast<uint16_t>(mojo->value->GetInt()));
}
}
diff --git a/chromium/components/arc/common/accessibility_helper.mojom b/chromium/components/arc/common/accessibility_helper.mojom
index 8c01c586c37..e17e44c4b5e 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: 15
+// Next MinVersion: 16
module arc.mojom;
@@ -307,7 +307,7 @@ enum AccessibilityFilterType {
ALL,
// Send complete subtrees for root nodes with whitelisted package names.
- [MinVersion=2] WHITELISTED_PACKAGE_NAME
+ [MinVersion=2] WHITELISTED_PACKAGE_NAME_DEPRECATED
};
[Extensible]
@@ -349,6 +349,9 @@ struct AccessibilityEventData {
// True if this event has happened on
// AccessibilityWindowInfo.TYPE_INPUT_METHOD.
[MinVersion=14] bool is_input_method_window;
+
+ // Retrieved from AccessibilityRecord.getText().
+ [MinVersion=15] array<string>? eventText;
};
// AccessibilityActionData is a struct to contain info of AccessibilityAction in
diff --git a/chromium/components/arc/common/app.mojom b/chromium/components/arc/common/app.mojom
index 203e4ddae76..cd51d4dffe2 100644
--- a/chromium/components/arc/common/app.mojom
+++ b/chromium/components/arc/common/app.mojom
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Next MinVersion: 41
+// Next MinVersion: 42
module arc.mojom;
+import "components/arc/common/app_permissions.mojom";
import "components/arc/common/gfx.mojom";
import "components/arc/common/scale_factor.mojom";
import "ui/accessibility/mojom/ax_assistant_structure.mojom";
@@ -55,6 +56,7 @@ struct ArcPackageInfo {
// If non-null, signifies this package represents a web app that should be
// installed on the browser side.
[MinVersion=38] WebAppInfo? web_app_info;
+ [MinVersion=41] map<AppPermission, bool>? permissions;
};
// Describes ARC app shortcut.
@@ -191,6 +193,42 @@ enum AppShortcutItemType {
kDynamic = 1,
};
+[Extensible]
+enum AppReinstallState {
+ // Request and response successful.
+ REQUEST_SUCCESS = 0,
+ // Request Timeout
+ REQUEST_TIMEOUT = 1,
+ // No Account.
+ REQUEST_NO_ACCOUNT = 2,
+ // Null data from aidl.
+ REQUEST_NULL_DATA = 3,
+ // Data that can't be converted from aidl bundle to mojom struct.
+ REQUEST_BUNDLE_ERROR = 4,
+ // Request failure other reason.
+ REQUEST_UNKNOWN_FAILURE = 5,
+};
+
+// Describes app reinstall candidates that are shown to users as suggestions.
+struct AppReinstallCandidate {
+ // The package name of this in the Play Store.
+ string package_name;
+
+ // The title of this package in the Play Store.
+ string title;
+
+ // The url of an icon for this package. Optional, a default icon is used if
+ // unset.
+ string? icon_url;
+
+ // Ratings Count from Play Store for this package. e.g. "17103" .
+ // Default of 0 if not set.
+ int64 rating_count;
+
+ // Mean star rating for this package, [1, 5]. 0 indicates missing.
+ float star_rating;
+};
+
// Describes app shortcut that is published by Android's ShortcutManager.
struct AppShortcutItem {
// The ID of this shortcut. Unique within each publisher app and stable across
@@ -238,19 +276,12 @@ enum PaiFlowState {
};
// Next method ID: 18
+// Deprecated method IDs: 1
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.
[MinVersion=1] OnAppAddedDeprecated@2(AppInfo app);
- // Receives an icon of required |scale_factor| for specific ARC app. The app
- // is defined by |package_name| and |activity|. The icon content cannot be
- // empty and must match to |scale_factor| assuming 48x48 for
- // SCALE_FACTOR_100P. |scale_factor| is an enum defined at ui/base/layout.h.
- // |icon_png_data| is a png-encoded image.
- OnAppIconDeprecated@1(string package_name, string activity,
- ScaleFactor scale_factor, array<uint8> icon_png_data);
-
// Receives a list of available ARC apps to Chrome. Members of AppInfo must
// contain non-empty string.
OnAppListRefreshed@0(array<AppInfo> apps);
@@ -320,6 +351,7 @@ interface AppHost {
// TODO(lhchavez): Migrate all request/response messages to Mojo.
// Next method ID: 33
+// Deprecated method IDs: 3, 13
interface AppInstance {
// DEPRECATED: Please use Init@21 instead.
InitDeprecated@0(AppHost host_ptr);
@@ -374,24 +406,12 @@ interface AppInstance {
int32 pixel_size) =>
(array<uint8> icon_png_data);
- // Sends a request to ARC for the ARC app icon of a required scale factor.
- // Scale factor is an enum defined at ui/base/layout.h. App is defined by
- // |package_name| and |activity|, which cannot be empty.
- RequestAppIconDeprecated@3(string package_name, string activity,
- ScaleFactor scale_factor);
-
// Sends a request for the ARC shortcut icon of a given resource id and
// |pixel_size|.
[MinVersion=36] RequestShortcutIcon@28(string icon_resource_id,
int32 pixel_size) =>
(array<uint8> icon_png_data);
- // Sends a request for the ARC shortcut icon of a given resource id and scale
- // factor.
- [MinVersion=9] RequestShortcutIconDeprecated@13(
- string icon_resource_id, ScaleFactor scale_factor) =>
- (array<uint8> icon_png_data);
-
// Sends a request for the ARC icon for a given |package_name| and
// |pixel_size|. If |normalize| is true, the icon will be normalized per
// Android's icon guidelines, otherwise, the raw unnormalized icon is
@@ -432,6 +452,12 @@ interface AppInstance {
// Sends a request to ARC to start FastAppReinstall flow.
[MinVersion=33] StartFastAppReinstallFlow@25(array<string> arc_package_names);
+ // Sends a request to ARC to retrieve an array of app reinstall
+ // candidates for this user on this device. Order of results is in an
+ // unspecified order of relevance from Play Store.
+ [MinVersion=39] GetAppReinstallCandidates@31() =>
+ (AppReinstallState state, array<AppReinstallCandidate> candidates);
+
// Sends a request to ARC to uninstall the given package. Error (if ever
// happens) is ignored, and uninstall option should appear in the UI.
[MinVersion=2] UninstallPackage@5(string package_name);
diff --git a/chromium/components/arc/common/bluetooth.mojom b/chromium/components/arc/common/bluetooth.mojom
index da30438846e..67720f4e604 100644
--- a/chromium/components/arc/common/bluetooth.mojom
+++ b/chromium/components/arc/common/bluetooth.mojom
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next MinVersion: 14
+// Next MinVersion: 15
module arc.mojom;
+import "mojo/public/mojom/base/values.mojom";
+
[Extensible]
enum BluetoothAdapterState {
OFF = 0,
@@ -271,16 +273,8 @@ struct BluetoothSdpAttribute {
BluetoothSdpAttributeType type;
uint32 type_size;
array<BluetoothSdpAttribute> sequence;
-
- // Holds the stringified JSON value of this attribute.
- // If the type is NULLTYPE or SEQUENCE, this is empty.
- // Explicitly specify the ordinal @3, because introducing this is a breaking
- // change. This field is introduced between version 7 and 8, though
- // MinVersion is not annotated because of breaking change, too.
- // See details in the bug linked below.
- // TODO(crbug.com/767313): Use mojo/public/mojom/base/values.mojom, when new
- // libmojo (440057 or later) is rolled to ARC repository.
- string? json_value@3;
+ string? deprecated_json_value@3;
+ [MinVersion=14] mojo_base.mojom.Value? value;
};
struct BluetoothSdpRecord {
diff --git a/chromium/components/arc/common/intent_helper.mojom b/chromium/components/arc/common/intent_helper.mojom
index 65f4139df81..3cf770135ca 100644
--- a/chromium/components/arc/common/intent_helper.mojom
+++ b/chromium/components/arc/common/intent_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: 25
+// Next MinVersion: 26
module arc.mojom;
@@ -163,9 +163,14 @@ struct TextSelectionAction {
[MinVersion=23] ArcBitmap? bitmap_icon;
};
+// Interface to interact with a custom tab.
+// Close the interface pointer to close the custom tab.
+interface CustomTabSession {
+};
+
// Handles intents from ARC in Chrome.
// Deprecated method ID: 4
-// Next method ID: 10
+// Next method ID: 11
interface IntentHelperHost {
// Called when icons associated with the package are no longer up to date.
[MinVersion=3] OnIconInvalidated@1(string package_name);
@@ -182,6 +187,17 @@ interface IntentHelperHost {
// navigate to as well. No special URLs that allow access to privileged functions are allowed.
OnOpenUrl@0(string url);
+ // Opens the url with a custom tab.
+ // |task_id| and |surface_id| specify the Android task and the surface on
+ // which the custom tab should be shown.
+ // |top_margin| is the height of the space at the top of the window which
+ // needs to be vacant to display the top bar rendered by Android code.
+ [MinVersion=25] OnOpenCustomTab@10(string url,
+ int32 task_id,
+ int32 surface_id,
+ int32 top_margin)
+ => (CustomTabSession? session);
+
// Opens the wallpaper picker dialog.
[MinVersion=6] OpenWallpaperPicker@3();
diff --git a/chromium/components/arc/common/usb_host.mojom b/chromium/components/arc/common/usb_host.mojom
index 0b2863f51be..466864e39fd 100644
--- a/chromium/components/arc/common/usb_host.mojom
+++ b/chromium/components/arc/common/usb_host.mojom
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Next MinVersion: 3
+// Next MinVersion: 4
module arc.mojom;
// re-use device.mojom.UsbDeviceInfo
import "device/usb/public/mojom/device.mojom";
-// Next method ID: 3
+// Next method ID: 4
interface UsbHostHost {
// Tries to open the USB device node for the device named 'guid' for caller
// 'pkg_name' and returns an open file descriptor to this node. 'pkg_name'
@@ -16,8 +16,20 @@ interface UsbHostHost {
// call will fail. Note the 'pkg_name' is informational purposes only, there
// is no effective way that host can restrict access to only a specific
// package at the security boundary formed by this Mojo interface.
- OpenDevice@0(string guid,
- [MinVersion=1] string? pkg_name) => (handle usb_fd);
+ // Deprecated.
+ OpenDeviceDeprecated@0(string guid,
+ [MinVersion=1] string? pkg_name) => (handle usb_fd);
+
+ // Tries to open the USB device node for the device named 'guid' for caller
+ // 'pkg_name' and returns an open file descriptor to this node. 'pkg_name'
+ // needs to have previously called RequestPermission for this 'guid' else this
+ // call will fail. Note the 'pkg_name' is informational purposes only, there
+ // is no effective way that host can restrict access to only a specific
+ // package at the security boundary formed by this Mojo interface.
+ // When app tries to open a device without requesting permission, or
+ // permission_broker rejects the open request, empty handle will be returned.
+ [MinVersion=3] OpenDevice@3(string guid, string? pkg_name) =>
+ (handle? usb_fd);
// Returns the USB device descriptors for the device named 'guid'.
GetDeviceInfo@1(string guid) => (string device_name,
diff --git a/chromium/components/arc/crash_collector/arc_crash_collector_bridge.cc b/chromium/components/arc/crash_collector/arc_crash_collector_bridge.cc
index ec0e49eef14..6f112ba7828 100644
--- a/chromium/components/arc/crash_collector/arc_crash_collector_bridge.cc
+++ b/chromium/components/arc/crash_collector/arc_crash_collector_bridge.cc
@@ -9,6 +9,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
diff --git a/chromium/components/arc/ime/arc_ime_service.cc b/chromium/components/arc/ime/arc_ime_service.cc
index 18a58f439a8..54ba67fb873 100644
--- a/chromium/components/arc/ime/arc_ime_service.cc
+++ b/chromium/components/arc/ime/arc_ime_service.cc
@@ -340,8 +340,6 @@ void ArcImeService::RequestHideIme() {
// Overridden from keyboard::KeyboardControllerObserver
void ArcImeService::OnKeyboardAppearanceChanged(
const keyboard::KeyboardStateDescriptor& state) {
- if (!focused_arc_window_)
- return;
gfx::Rect new_bounds = state.occluded_bounds;
// Multiply by the scale factor. To convert from DIP to physical pixels.
// The default scale factor is always used in Android side regardless of
diff --git a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 95339444048..83b7d761f65 100644
--- a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -171,6 +171,23 @@ void ArcIntentHelperBridge::OnOpenUrl(const std::string& url) {
g_open_url_delegate->OpenUrlFromArc(gurl);
}
+void ArcIntentHelperBridge::OnOpenCustomTab(const std::string& url,
+ int32_t task_id,
+ int32_t surface_id,
+ int32_t top_margin,
+ OnOpenCustomTabCallback callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Converts |url| to a fixed-up one and checks validity.
+ const GURL gurl(url_formatter::FixupURL(url, /*desired_tld=*/std::string()));
+ if (!gurl.is_valid() ||
+ allowed_arc_schemes_.find(gurl.scheme()) == allowed_arc_schemes_.end()) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+ g_open_url_delegate->OpenArcCustomTab(gurl, task_id, surface_id, top_margin,
+ std::move(callback));
+}
+
void ArcIntentHelperBridge::OnOpenChromePage(mojom::ChromePage page) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = allowed_chrome_pages_map_.find(page);
diff --git a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.h b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.h
index 69c777c45b6..8cdf2c354ed 100644
--- a/chromium/components/arc/intent_helper/arc_intent_helper_bridge.h
+++ b/chromium/components/arc/intent_helper/arc_intent_helper_bridge.h
@@ -65,6 +65,11 @@ class ArcIntentHelperBridge
std::vector<IntentFilter> intent_filters) override;
void OnOpenDownloads() override;
void OnOpenUrl(const std::string& url) override;
+ void OnOpenCustomTab(const std::string& url,
+ int32_t task_id,
+ int32_t surface_id,
+ int32_t top_margin,
+ OnOpenCustomTabCallback callback) override;
void OnOpenChromePage(mojom::ChromePage page) override;
void OpenWallpaperPicker() override;
void SetWallpaperDeprecated(const std::vector<uint8_t>& jpeg_data) override;
diff --git a/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
index 356770383e6..48aa782d30d 100644
--- a/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
+++ b/chromium/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
@@ -40,6 +40,14 @@ class ArcIntentHelperTest : public testing::Test {
// OpenUrlDelegate:
void OpenUrlFromArc(const GURL& url) override { last_opened_url_ = url; }
void OpenWebAppFromArc(const GURL& url) override { last_opened_url_ = url; }
+ void OpenArcCustomTab(
+ const GURL& url,
+ int32_t task_id,
+ int32_t surface_id,
+ int32_t top_margin,
+ mojom::IntentHelperHost::OnOpenCustomTabCallback callback) override {
+ std::move(callback).Run(nullptr);
+ }
GURL TakeLastOpenedUrl() {
GURL result = std::move(last_opened_url_);
diff --git a/chromium/components/arc/intent_helper/open_url_delegate.h b/chromium/components/arc/intent_helper/open_url_delegate.h
index db0b1ca5374..cc1eeae119b 100644
--- a/chromium/components/arc/intent_helper/open_url_delegate.h
+++ b/chromium/components/arc/intent_helper/open_url_delegate.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_ARC_INTENT_HELPER_OPEN_URL_DELEGATE_H_
#define COMPONENTS_ARC_INTENT_HELPER_OPEN_URL_DELEGATE_H_
+#include "components/arc/common/intent_helper.mojom.h"
+
class GURL;
namespace arc {
@@ -19,6 +21,14 @@ class OpenUrlDelegate {
// Opens the given URL as a web app in the Chrome browser, falling back to
// opening as a tab if no installed web app is found.
virtual void OpenWebAppFromArc(const GURL& url) = 0;
+
+ // Opens the given URL in a custom tab.
+ virtual void OpenArcCustomTab(
+ const GURL& url,
+ int32_t task_id,
+ int32_t surface_id,
+ int32_t top_margin,
+ mojom::IntentHelperHost::OnOpenCustomTabCallback callback) = 0;
};
} // namespace arc
diff --git a/chromium/components/arc/metrics/arc_metrics_constants.h b/chromium/components/arc/metrics/arc_metrics_constants.h
index 59a828686ef..4e48ecdc354 100644
--- a/chromium/components/arc/metrics/arc_metrics_constants.h
+++ b/chromium/components/arc/metrics/arc_metrics_constants.h
@@ -7,6 +7,22 @@
namespace arc {
+// Native bridge types for UMA recording (Arc.NativeBridge). These values are
+// persisted to logs, and should therefore never be renumbered nor reused.
+// Should be synced with ArcNativeBridgeType in
+// tools/metrics/histograms/enums.xml.
+enum class NativeBridgeType {
+ // Native bridge value has not been received from the container yet.
+ UNKNOWN = 0,
+ // Native bridge is not used.
+ NONE = 1,
+ // Using houdini translator.
+ HOUDINI = 2,
+ // Using ndk-translation translator.
+ NDK_TRANSLATION = 3,
+ kMaxValue = NDK_TRANSLATION,
+};
+
// Defines ARC App user interaction types to track how users use ARC apps.
// These enums are used to define the buckets for an enumerated UMA histogram
// and need to be synced with tools/metrics/histograms/enums.xml.
diff --git a/chromium/components/arc/metrics/arc_metrics_service.cc b/chromium/components/arc/metrics/arc_metrics_service.cc
index eb023fc5018..ad2859d6bc2 100644
--- a/chromium/components/arc/metrics/arc_metrics_service.cc
+++ b/chromium/components/arc/metrics/arc_metrics_service.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_functions.h"
@@ -23,6 +24,7 @@
#include "components/arc/arc_prefs.h"
#include "components/arc/arc_util.h"
#include "components/arc/metrics/arc_metrics_constants.h"
+#include "components/arc/metrics/stability_metrics_manager.h"
#include "components/exo/wm_helper.h"
#include "components/prefs/pref_service.h"
#include "components/session_manager/core/session_manager.h"
@@ -140,7 +142,6 @@ ArcMetricsService::ArcMetricsService(content::BrowserContext* context,
: arc_bridge_service_(bridge_service),
arc_window_delegate_(std::make_unique<ArcWindowDelegateImpl>(this)),
process_observer_(this),
- native_bridge_type_(NativeBridgeType::UNKNOWN),
pref_service_(user_prefs::UserPrefs::Get(context)),
clock_(base::DefaultClock::GetInstance()),
tick_clock_(base::DefaultTickClock::GetInstance()),
@@ -150,8 +151,7 @@ ArcMetricsService::ArcMetricsService(content::BrowserContext* context,
arc_bridge_service_->process()->AddObserver(&process_observer_);
arc_window_delegate_->RegisterActivationChangeObserver();
session_manager::SessionManager::Get()->AddObserver(this);
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
- this);
+ chromeos::PowerManagerClient::Get()->AddObserver(this);
DCHECK(pref_service_);
RestoreEngagementTimeFromPrefs();
@@ -161,6 +161,9 @@ ArcMetricsService::ArcMetricsService(content::BrowserContext* context,
save_engagement_time_to_prefs_timer_.Start(
FROM_HERE, kSaveEngagementTimeToPrefsPeriod, this,
&ArcMetricsService::SaveEngagementTimeToPrefs);
+
+ StabilityMetricsManager::Get()->SetArcNativeBridgeType(
+ NativeBridgeType::UNKNOWN);
}
ArcMetricsService::~ArcMetricsService() {
@@ -170,8 +173,7 @@ ArcMetricsService::~ArcMetricsService() {
UpdateEngagementTime();
SaveEngagementTimeToPrefs();
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
- this);
+ chromeos::PowerManagerClient::Get()->RemoveObserver(this);
session_manager::SessionManager::Get()->RemoveObserver(this);
arc_window_delegate_->UnregisterActivationChangeObserver();
arc_bridge_service_->process()->RemoveObserver(&process_observer_);
@@ -278,7 +280,18 @@ void ArcMetricsService::ReportBootProgress(
return;
}
- // Retrieve ARC start time from session manager.
+ if (IsArcVmEnabled()) {
+ // For VM builds, do not call into session_manager since we don't use it
+ // for the builds. Using base::TimeTicks() is fine for now because 1) the
+ // clocks in host and guest are not synchronized, and 2) the guest does not
+ // support mini container.
+ // TODO(yusukes): Once the guest supports mini container (details TBD), we
+ // should have the guest itself report the timing of the upgrade.
+ OnArcStartTimeRetrieved(std::move(events), boot_type, base::TimeTicks());
+ return;
+ }
+
+ // Retrieve ARC full container's start time from session manager.
chromeos::SessionManagerClient* session_manager_client =
chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
session_manager_client->GetArcStartTime(base::BindOnce(
@@ -287,29 +300,26 @@ void ArcMetricsService::ReportBootProgress(
}
void ArcMetricsService::ReportNativeBridge(
- mojom::NativeBridgeType native_bridge_type) {
+ mojom::NativeBridgeType mojo_native_bridge_type) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- VLOG(2) << "Mojo native bridge type is " << native_bridge_type;
+ VLOG(2) << "Mojo native bridge type is " << mojo_native_bridge_type;
- // Save value for RecordNativeBridgeUMA instead of recording
- // immediately since it must appear in every metrics interval
- // uploaded to UMA.
- switch (native_bridge_type) {
+ NativeBridgeType native_bridge_type = NativeBridgeType::UNKNOWN;
+ switch (mojo_native_bridge_type) {
case mojom::NativeBridgeType::NONE:
- native_bridge_type_ = NativeBridgeType::NONE;
- return;
+ native_bridge_type = NativeBridgeType::NONE;
+ break;
case mojom::NativeBridgeType::HOUDINI:
- native_bridge_type_ = NativeBridgeType::HOUDINI;
- return;
+ native_bridge_type = NativeBridgeType::HOUDINI;
+ break;
case mojom::NativeBridgeType::NDK_TRANSLATION:
- native_bridge_type_ = NativeBridgeType::NDK_TRANSLATION;
- return;
+ native_bridge_type = NativeBridgeType::NDK_TRANSLATION;
+ break;
}
- NOTREACHED() << native_bridge_type;
-}
+ DCHECK_NE(native_bridge_type, NativeBridgeType::UNKNOWN)
+ << mojo_native_bridge_type;
-void ArcMetricsService::RecordNativeBridgeUMA() {
- UMA_HISTOGRAM_ENUMERATION("Arc.NativeBridge", native_bridge_type_);
+ StabilityMetricsManager::Get()->SetArcNativeBridgeType(native_bridge_type);
}
void ArcMetricsService::OnWindowActivated(
diff --git a/chromium/components/arc/metrics/arc_metrics_service.h b/chromium/components/arc/metrics/arc_metrics_service.h
index faffff74d3e..6c4d88fa2f3 100644
--- a/chromium/components/arc/metrics/arc_metrics_service.h
+++ b/chromium/components/arc/metrics/arc_metrics_service.h
@@ -49,20 +49,6 @@ class ArcMetricsService : public KeyedService,
public chromeos::PowerManagerClient::Observer,
public mojom::MetricsHost {
public:
- // These values are persisted to logs, and should therefore never be
- // renumbered nor reused. They are public for testing only.
- enum class NativeBridgeType {
- // Native bridge value has not been received from the container yet.
- UNKNOWN = 0,
- // Native bridge is not used.
- NONE = 1,
- // Using houdini translator.
- HOUDINI = 2,
- // Using ndk-translation translator.
- NDK_TRANSLATION = 3,
- kMaxValue = NDK_TRANSLATION,
- };
-
// Delegate for handling window focus observation that is used to track ARC
// app usage metrics.
class ArcWindowDelegate {
@@ -107,10 +93,6 @@ class ArcMetricsService : public KeyedService,
mojom::BootType boot_type) override;
void ReportNativeBridge(mojom::NativeBridgeType native_bridge_type) override;
- // Records native bridge UMA according to value received from the
- // container or as UNKNOWN if the value has not been recieved yet.
- void RecordNativeBridgeUMA();
-
// wm::ActivationChangeObserver overrides.
// Records to UMA when a user has interacted with an ARC app window.
void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
@@ -132,10 +114,6 @@ class ArcMetricsService : public KeyedService,
const std::string& intent);
void OnTaskDestroyed(int32_t task_id);
- NativeBridgeType native_bridge_type_for_testing() const {
- return native_bridge_type_;
- }
-
private:
// Adapter to be able to also observe ProcessInstance events.
class ProcessObserver : public ConnectionObserver<mojom::ProcessInstance> {
@@ -193,8 +171,6 @@ class ArcMetricsService : public KeyedService,
ProcessObserver process_observer_;
base::RepeatingTimer request_process_list_timer_;
- NativeBridgeType native_bridge_type_;
-
PrefService* const pref_service_;
const base::Clock* clock_;
const base::TickClock* tick_clock_;
diff --git a/chromium/components/arc/metrics/arc_metrics_service_unittest.cc b/chromium/components/arc/metrics/arc_metrics_service_unittest.cc
index a5e64668ea7..4e7d0916e73 100644
--- a/chromium/components/arc/metrics/arc_metrics_service_unittest.cc
+++ b/chromium/components/arc/metrics/arc_metrics_service_unittest.cc
@@ -23,7 +23,9 @@
#include "components/arc/arc_prefs.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/metrics/arc_metrics_constants.h"
+#include "components/arc/metrics/stability_metrics_manager.h"
#include "components/arc/test/test_browser_context.h"
+#include "components/prefs/testing_pref_service.h"
#include "components/session_manager/core/session_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -128,16 +130,32 @@ class DBusThreadManagerLifetimeHelper {
// Set fake clients for testing.
dbus_thread_manager_setter->SetSessionManagerClient(
std::make_unique<chromeos::FakeSessionManagerClient>());
- dbus_thread_manager_setter->SetPowerManagerClient(
- std::make_unique<chromeos::FakePowerManagerClient>());
+ chromeos::PowerManagerClient::Initialize();
}
~DBusThreadManagerLifetimeHelper() {
+ chromeos::PowerManagerClient::Shutdown();
// Destroy the global DBusThreadManager instance.
chromeos::DBusThreadManager::Shutdown();
}
};
+// Helper class that ensures lifetime of StabilityMetricsManager for testing.
+class ScopedStabilityMetricsManager {
+ public:
+ ScopedStabilityMetricsManager() {
+ prefs::RegisterLocalStatePrefs(local_state_.registry());
+ StabilityMetricsManager::Initialize(&local_state_);
+ }
+
+ ~ScopedStabilityMetricsManager() { StabilityMetricsManager::Shutdown(); }
+
+ private:
+ TestingPrefServiceSimple local_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedStabilityMetricsManager);
+};
+
// Initializes dependencies before creating ArcMetricsService instance.
ArcMetricsService* CreateArcMetricsService(TestBrowserContext* context) {
// Register preferences for ARC++ engagement time metrics.
@@ -233,16 +251,17 @@ class ArcMetricsServiceTest : public testing::Test {
chromeos::FakePowerManagerClient* GetPowerManagerClient() {
return static_cast<chromeos::FakePowerManagerClient*>(
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
+ chromeos::PowerManagerClient::Get());
}
content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<ArcServiceManager> arc_service_manager_;
- // DBusThreadManager and SessionManager should outlive TestBrowserContext
- // which destructs ArcMetricsService in dtor.
+ // DBusThreadManager, SessionManager and StabilityMetricsManager should
+ // outlive TestBrowserContext which destructs ArcMetricsService in dtor.
DBusThreadManagerLifetimeHelper dbus_thread_manager_lifetime_helper_;
session_manager::SessionManager session_manager_;
+ ScopedStabilityMetricsManager scoped_stability_metrics_manager_;
std::unique_ptr<TestBrowserContext> context_;
std::unique_ptr<aura::Window> fake_arc_window_;
@@ -376,46 +395,19 @@ TEST_F(ArcMetricsServiceTest, ReportBootProgress_InvalidBootType) {
}
TEST_F(ArcMetricsServiceTest, ReportNativeBridge) {
- EXPECT_EQ(service()->native_bridge_type_for_testing(),
- ArcMetricsService::NativeBridgeType::UNKNOWN);
+ // SetArcNativeBridgeType should be called once ArcMetricsService is
+ // constructed.
+ EXPECT_EQ(StabilityMetricsManager::Get()->GetArcNativeBridgeType(),
+ NativeBridgeType::UNKNOWN);
service()->ReportNativeBridge(mojom::NativeBridgeType::NONE);
- EXPECT_EQ(service()->native_bridge_type_for_testing(),
- ArcMetricsService::NativeBridgeType::NONE);
+ EXPECT_EQ(StabilityMetricsManager::Get()->GetArcNativeBridgeType(),
+ NativeBridgeType::NONE);
service()->ReportNativeBridge(mojom::NativeBridgeType::HOUDINI);
- EXPECT_EQ(service()->native_bridge_type_for_testing(),
- ArcMetricsService::NativeBridgeType::HOUDINI);
+ EXPECT_EQ(StabilityMetricsManager::Get()->GetArcNativeBridgeType(),
+ NativeBridgeType::HOUDINI);
service()->ReportNativeBridge(mojom::NativeBridgeType::NDK_TRANSLATION);
- EXPECT_EQ(service()->native_bridge_type_for_testing(),
- ArcMetricsService::NativeBridgeType::NDK_TRANSLATION);
-}
-
-TEST_F(ArcMetricsServiceTest, RecordNativeBridgeUMA) {
- base::HistogramTester tester;
- service()->RecordNativeBridgeUMA();
- tester.ExpectUniqueSample(
- "Arc.NativeBridge",
- static_cast<int>(ArcMetricsService::NativeBridgeType::UNKNOWN), 1);
- service()->ReportNativeBridge(mojom::NativeBridgeType::NONE);
- // Check that ReportNativeBridge doesn't record histograms.
- tester.ExpectTotalCount("Arc.NativeBridge", 1);
- service()->RecordNativeBridgeUMA();
- tester.ExpectBucketCount(
- "Arc.NativeBridge",
- static_cast<int>(ArcMetricsService::NativeBridgeType::NONE), 1);
- service()->ReportNativeBridge(mojom::NativeBridgeType::HOUDINI);
- tester.ExpectTotalCount("Arc.NativeBridge", 2);
- service()->RecordNativeBridgeUMA();
- tester.ExpectBucketCount(
- "Arc.NativeBridge",
- static_cast<int>(ArcMetricsService::NativeBridgeType::HOUDINI), 1);
- service()->ReportNativeBridge(mojom::NativeBridgeType::NDK_TRANSLATION);
- tester.ExpectTotalCount("Arc.NativeBridge", 3);
- service()->RecordNativeBridgeUMA();
- tester.ExpectBucketCount(
- "Arc.NativeBridge",
- static_cast<int>(ArcMetricsService::NativeBridgeType::NDK_TRANSLATION),
- 1);
- tester.ExpectTotalCount("Arc.NativeBridge", 4);
+ EXPECT_EQ(StabilityMetricsManager::Get()->GetArcNativeBridgeType(),
+ NativeBridgeType::NDK_TRANSLATION);
}
TEST_F(ArcMetricsServiceTest, RecordArcWindowFocusAction) {
diff --git a/chromium/components/arc/metrics/stability_metrics_manager.cc b/chromium/components/arc/metrics/stability_metrics_manager.cc
new file mode 100644
index 00000000000..8bd1c59c855
--- /dev/null
+++ b/chromium/components/arc/metrics/stability_metrics_manager.cc
@@ -0,0 +1,112 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/metrics/stability_metrics_manager.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "components/arc/arc_prefs.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
+
+namespace arc {
+
+namespace {
+
+constexpr char kArcEnabledStateKey[] = "enabled_state";
+constexpr char kArcNativeBridgeTypeKey[] = "native_bridge_type";
+
+StabilityMetricsManager* g_stability_metrics_manager = nullptr;
+
+} // namespace
+
+// static
+void StabilityMetricsManager::Initialize(PrefService* local_state) {
+ DCHECK(!g_stability_metrics_manager);
+ g_stability_metrics_manager = new StabilityMetricsManager(local_state);
+}
+
+// static
+void StabilityMetricsManager::Shutdown() {
+ DCHECK(g_stability_metrics_manager);
+ delete g_stability_metrics_manager;
+ g_stability_metrics_manager = nullptr;
+}
+
+// static
+StabilityMetricsManager* StabilityMetricsManager::Get() {
+ return g_stability_metrics_manager;
+}
+
+StabilityMetricsManager::StabilityMetricsManager(PrefService* local_state)
+ : local_state_(local_state) {}
+
+StabilityMetricsManager::~StabilityMetricsManager() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void StabilityMetricsManager::RecordMetricsToUMA() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // GetDictionary() should never return null, but since this may be called
+ // early on browser startup, be paranoid here to prevent going into a crash
+ // loop.
+ if (!local_state_->GetDictionary(prefs::kStabilityMetrics)) {
+ NOTREACHED() << "Local state unavailable, not recording stabiltiy metrics.";
+ return;
+ }
+
+ const base::Optional<bool> enabled_state = GetArcEnabledState();
+ if (enabled_state)
+ UMA_STABILITY_HISTOGRAM_ENUMERATION("Arc.State", *enabled_state ? 1 : 0, 2);
+
+ const base::Optional<NativeBridgeType> native_bridge_type =
+ GetArcNativeBridgeType();
+ if (native_bridge_type) {
+ UMA_STABILITY_HISTOGRAM_ENUMERATION(
+ "Arc.NativeBridge", *native_bridge_type,
+ static_cast<int>(NativeBridgeType::kMaxValue) + 1);
+ }
+}
+
+void StabilityMetricsManager::ResetMetrics() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DictionaryPrefUpdate update(local_state_, prefs::kStabilityMetrics);
+ update->Clear();
+}
+
+base::Optional<bool> StabilityMetricsManager::GetArcEnabledState() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ const base::DictionaryValue* dict =
+ local_state_->GetDictionary(prefs::kStabilityMetrics);
+ return dict->FindBoolKey(kArcEnabledStateKey);
+}
+
+void StabilityMetricsManager::SetArcEnabledState(bool enabled) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DictionaryPrefUpdate update(local_state_, prefs::kStabilityMetrics);
+ update->SetKey(kArcEnabledStateKey, base::Value(enabled));
+}
+
+base::Optional<NativeBridgeType>
+StabilityMetricsManager::GetArcNativeBridgeType() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ const base::DictionaryValue* dict =
+ local_state_->GetDictionary(prefs::kStabilityMetrics);
+ base::Optional<int> native_bridge_type =
+ dict->FindIntKey(kArcNativeBridgeTypeKey);
+ if (native_bridge_type) {
+ return base::make_optional(
+ static_cast<NativeBridgeType>(*native_bridge_type));
+ }
+ return base::nullopt;
+}
+
+void StabilityMetricsManager::SetArcNativeBridgeType(
+ NativeBridgeType native_bridge_type) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DictionaryPrefUpdate update(local_state_, prefs::kStabilityMetrics);
+ update->SetKey(kArcNativeBridgeTypeKey,
+ base::Value(static_cast<int>(native_bridge_type)));
+}
+
+} // namespace arc
diff --git a/chromium/components/arc/metrics/stability_metrics_manager.h b/chromium/components/arc/metrics/stability_metrics_manager.h
new file mode 100644
index 00000000000..3e852cc6df6
--- /dev/null
+++ b/chromium/components/arc/metrics/stability_metrics_manager.h
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_ARC_METRICS_STABILITY_METRICS_MANAGER_H_
+#define COMPONENTS_ARC_METRICS_STABILITY_METRICS_MANAGER_H_
+
+#include "base/optional.h"
+#include "base/sequence_checker.h"
+#include "components/arc/metrics/arc_metrics_constants.h"
+
+class PrefService;
+
+namespace arc {
+
+// Singleton instance that keeps track of ARC-related stability metrics. In case
+// of a crash, stability metrics from previous session are included in initial
+// stability log, which is generated early on browser startup when ARC services
+// aren't available. This class supports recording stability metrics by
+// persisting them into local state.
+class StabilityMetricsManager {
+ public:
+ static void Initialize(PrefService* local_state);
+ static void Shutdown();
+
+ // May return null if not initialized, which happens only in unit tests.
+ static StabilityMetricsManager* Get();
+
+ // Reads metrics from |local_state_| and record to UMA. Called from
+ // ChromeOSMetricsProvider to include stability metrics in all uploaded UMA
+ // logs.
+ void RecordMetricsToUMA();
+
+ // Resets metrics persisted in |local_state_|. Called from ArcSessionManager
+ // which determines whether stability metrics should be recorded for current
+ // session,
+ void ResetMetrics();
+
+ // Returns current persisted value (if exists) for Arc.State UMA histogram.
+ base::Optional<bool> GetArcEnabledState();
+
+ // Sets value for Arc.State UMA histogram.
+ void SetArcEnabledState(bool enabled);
+
+ // Returns current persisted value (if exists) for Arc.State UMA histogram.
+ base::Optional<NativeBridgeType> GetArcNativeBridgeType();
+
+ // Sets value for Arc.NativeBridgeType UMA histogram.
+ void SetArcNativeBridgeType(NativeBridgeType native_bridge_type);
+
+ private:
+ explicit StabilityMetricsManager(PrefService* local_state);
+ ~StabilityMetricsManager();
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ PrefService* const local_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(StabilityMetricsManager);
+};
+
+} // namespace arc
+
+#endif // COMPONENTS_ARC_METRICS_STABILITY_METRICS_MANAGER_H_
diff --git a/chromium/components/arc/metrics/stability_metrics_manager_unittest.cc b/chromium/components/arc/metrics/stability_metrics_manager_unittest.cc
new file mode 100644
index 00000000000..5cc11c8d3f4
--- /dev/null
+++ b/chromium/components/arc/metrics/stability_metrics_manager_unittest.cc
@@ -0,0 +1,105 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/arc/metrics/stability_metrics_manager.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "components/arc/arc_prefs.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+class StabilityMetricsManagerTest : public testing::Test {
+ protected:
+ StabilityMetricsManagerTest() {
+ prefs::RegisterLocalStatePrefs(local_state.registry());
+ StabilityMetricsManager::Initialize(&local_state);
+ }
+
+ ~StabilityMetricsManagerTest() override {
+ StabilityMetricsManager::Shutdown();
+ }
+
+ static StabilityMetricsManager* manager() {
+ return StabilityMetricsManager::Get();
+ }
+
+ private:
+ TestingPrefServiceSimple local_state;
+
+ DISALLOW_COPY_AND_ASSIGN(StabilityMetricsManagerTest);
+};
+
+TEST_F(StabilityMetricsManagerTest, GetArcEnabledState) {
+ EXPECT_FALSE(manager()->GetArcEnabledState().has_value());
+
+ manager()->SetArcEnabledState(true);
+ EXPECT_EQ(manager()->GetArcEnabledState(), true);
+
+ manager()->SetArcEnabledState(false);
+ EXPECT_EQ(manager()->GetArcEnabledState(), false);
+
+ manager()->ResetMetrics();
+ EXPECT_FALSE(manager()->GetArcEnabledState().has_value());
+}
+
+TEST_F(StabilityMetricsManagerTest, GetArcNativeBridgeType) {
+ EXPECT_FALSE(manager()->GetArcNativeBridgeType().has_value());
+
+ for (NativeBridgeType type :
+ {NativeBridgeType::UNKNOWN, NativeBridgeType::NONE,
+ NativeBridgeType::HOUDINI, NativeBridgeType::NDK_TRANSLATION}) {
+ manager()->SetArcNativeBridgeType(type);
+ EXPECT_EQ(manager()->GetArcNativeBridgeType(), type);
+ }
+
+ manager()->ResetMetrics();
+ EXPECT_FALSE(manager()->GetArcNativeBridgeType().has_value());
+}
+
+TEST_F(StabilityMetricsManagerTest, RecordEnabledStateToUMA) {
+ base::HistogramTester tester;
+
+ manager()->SetArcEnabledState(true);
+ manager()->RecordMetricsToUMA();
+ tester.ExpectBucketCount("Arc.State", 1, 1);
+
+ manager()->SetArcEnabledState(false);
+ manager()->RecordMetricsToUMA();
+ tester.ExpectBucketCount("Arc.State", 0, 1);
+}
+
+TEST_F(StabilityMetricsManagerTest, RecordNativeBridgeTypeToUMA) {
+ base::HistogramTester tester;
+
+ EXPECT_EQ(NativeBridgeType::kMaxValue, NativeBridgeType::NDK_TRANSLATION);
+ for (NativeBridgeType type :
+ {NativeBridgeType::UNKNOWN, NativeBridgeType::NONE,
+ NativeBridgeType::HOUDINI, NativeBridgeType::NDK_TRANSLATION}) {
+ manager()->SetArcNativeBridgeType(type);
+ manager()->RecordMetricsToUMA();
+ tester.ExpectBucketCount("Arc.NativeBridge", static_cast<int>(type), 1);
+ }
+}
+
+TEST_F(StabilityMetricsManagerTest, ResetMetrics) {
+ base::HistogramTester tester;
+
+ manager()->SetArcEnabledState(true);
+ manager()->SetArcNativeBridgeType(NativeBridgeType::NONE);
+ manager()->RecordMetricsToUMA();
+ tester.ExpectBucketCount("Arc.State", 1, 1);
+ tester.ExpectBucketCount("Arc.NativeBridge",
+ static_cast<int>(NativeBridgeType::NONE), 1);
+
+ manager()->ResetMetrics();
+ manager()->RecordMetricsToUMA();
+ // Bucket counts should remain the same.
+ tester.ExpectBucketCount("Arc.State", 1, 1);
+ tester.ExpectBucketCount("Arc.NativeBridge",
+ static_cast<int>(NativeBridgeType::NONE), 1);
+}
+
+} // namespace arc
diff --git a/chromium/components/arc/power/arc_power_bridge.cc b/chromium/components/arc/power/arc_power_bridge.cc
index 28ab5763c4e..518fc56d225 100644
--- a/chromium/components/arc/power/arc_power_bridge.cc
+++ b/chromium/components/arc/power/arc_power_bridge.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "ash/shell.h"
+#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
@@ -22,6 +23,7 @@
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "ui/display/manager/display_configurator.h"
namespace arc {
namespace {
@@ -151,21 +153,17 @@ void ArcPowerBridge::OnConnectionReady() {
// TODO(mash): Support this functionality without ash::Shell access in Chrome.
if (ash::Shell::HasInstance())
ash::Shell::Get()->display_configurator()->AddObserver(this);
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
- this);
- chromeos::DBusThreadManager::Get()
- ->GetPowerManagerClient()
- ->GetScreenBrightnessPercent(
- base::BindOnce(&ArcPowerBridge::OnGetScreenBrightnessPercent,
- weak_ptr_factory_.GetWeakPtr()));
+ chromeos::PowerManagerClient::Get()->AddObserver(this);
+ chromeos::PowerManagerClient::Get()->GetScreenBrightnessPercent(
+ base::BindOnce(&ArcPowerBridge::OnGetScreenBrightnessPercent,
+ weak_ptr_factory_.GetWeakPtr()));
}
void ArcPowerBridge::OnConnectionClosed() {
// TODO(mash): Support this functionality without ash::Shell access in Chrome.
if (ash::Shell::HasInstance())
ash::Shell::Get()->display_configurator()->RemoveObserver(this);
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
- this);
+ chromeos::PowerManagerClient::Get()->RemoveObserver(this);
wake_lock_requestors_.clear();
}
@@ -176,9 +174,9 @@ void ArcPowerBridge::SuspendImminent(
if (!power_instance)
return;
- power_instance->Suspend(chromeos::DBusThreadManager::Get()
- ->GetPowerManagerClient()
- ->GetSuspendReadinessCallback(FROM_HERE));
+ power_instance->Suspend(
+ chromeos::PowerManagerClient::Get()->GetSuspendReadinessCallback(
+ FROM_HERE));
}
void ArcPowerBridge::SuspendDone(const base::TimeDelta& sleep_duration) {
@@ -268,9 +266,7 @@ void ArcPowerBridge::OnScreenBrightnessUpdateRequest(double percent) {
power_manager::SetBacklightBrightnessRequest_Transition_GRADUAL);
request.set_cause(
power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST);
- chromeos::DBusThreadManager::Get()
- ->GetPowerManagerClient()
- ->SetScreenBrightness(request);
+ chromeos::PowerManagerClient::Get()->SetScreenBrightness(request);
}
ArcPowerBridge::WakeLockRequestor* ArcPowerBridge::GetWakeLockRequestor(
diff --git a/chromium/components/arc/power/arc_power_bridge.h b/chromium/components/arc/power/arc_power_bridge.h
index 5697d7c004b..34df4abe2bb 100644
--- a/chromium/components/arc/power/arc_power_bridge.h
+++ b/chromium/components/arc/power/arc_power_bridge.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/optional.h"
+#include "base/timer/timer.h"
#include "chromeos/dbus/power_manager_client.h"
#include "components/arc/common/power.mojom.h"
#include "components/arc/connection_observer.h"
diff --git a/chromium/components/arc/power/arc_power_bridge_unittest.cc b/chromium/components/arc/power/arc_power_bridge_unittest.cc
index 012e8e7f284..f6dc18d3b16 100644
--- a/chromium/components/arc/power/arc_power_bridge_unittest.cc
+++ b/chromium/components/arc/power/arc_power_bridge_unittest.cc
@@ -8,7 +8,6 @@
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "components/arc/arc_bridge_service.h"
@@ -30,11 +29,12 @@ class ArcPowerBridgeTest : public testing::Test {
// Initial screen brightness percent for the Chrome OS power manager.
static constexpr double kInitialBrightness = 100.0;
- ArcPowerBridgeTest() {
- chromeos::DBusThreadManager::Initialize();
- power_manager_client_ = static_cast<chromeos::FakePowerManagerClient*>(
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
- power_manager_client_->set_screen_brightness_percent(kInitialBrightness);
+ ArcPowerBridgeTest() = default;
+ ~ArcPowerBridgeTest() override = default;
+
+ void SetUp() override {
+ chromeos::PowerManagerClient::Initialize();
+ power_manager_client()->set_screen_brightness_percent(kInitialBrightness);
wake_lock_provider_ = std::make_unique<device::TestWakeLockProvider>(
connector_factory_.RegisterInstance(device::mojom::kServiceName));
@@ -47,10 +47,10 @@ class ArcPowerBridgeTest : public testing::Test {
CreatePowerInstance();
}
- ~ArcPowerBridgeTest() override {
+ void TearDown() override {
DestroyPowerInstance();
power_bridge_.reset();
- chromeos::DBusThreadManager::Shutdown();
+ chromeos::PowerManagerClient::Shutdown();
}
protected:
@@ -82,18 +82,37 @@ class ArcPowerBridgeTest : public testing::Test {
power_bridge_->FlushWakeLocksForTesting();
}
+ // Returns the number of active wake locks of type |type|.
+ int GetActiveWakeLocks(WakeLockType type) {
+ base::RunLoop run_loop;
+ int result_count = 0;
+ wake_lock_provider_->GetActiveWakeLocksForTests(
+ type,
+ base::BindOnce(
+ [](base::RunLoop* run_loop, int* result_count, int32_t count) {
+ *result_count = count;
+ run_loop->Quit();
+ },
+ &run_loop, &result_count));
+ run_loop.Run();
+ return result_count;
+ }
+
+ chromeos::FakePowerManagerClient* power_manager_client() {
+ return chromeos::FakePowerManagerClient::Get();
+ }
+
base::test::ScopedTaskEnvironment scoped_task_environment_;
service_manager::TestConnectorFactory connector_factory_;
- std::unique_ptr<device::TestWakeLockProvider> wake_lock_provider_;
-
- chromeos::FakePowerManagerClient* power_manager_client_; // Not owned.
std::unique_ptr<ArcBridgeService> bridge_service_;
std::unique_ptr<FakePowerInstance> power_instance_;
std::unique_ptr<ArcPowerBridge> power_bridge_;
private:
+ std::unique_ptr<device::TestWakeLockProvider> wake_lock_provider_;
+
DISALLOW_COPY_AND_ASSIGN(ArcPowerBridgeTest);
};
@@ -104,26 +123,29 @@ TEST_F(ArcPowerBridgeTest, SuspendAndResume) {
// When powerd notifies Chrome that the system is about to suspend,
// ArcPowerBridge should notify Android and take a suspend readiness callback
// to defer the suspend operation.
- power_manager_client_->SendSuspendImminent(
+ power_manager_client()->SendSuspendImminent(
power_manager::SuspendImminent_Reason_OTHER);
EXPECT_EQ(1, power_instance_->num_suspend());
EXPECT_EQ(0, power_instance_->num_resume());
- EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
+ EXPECT_EQ(1,
+ power_manager_client()->GetNumPendingSuspendReadinessCallbacks());
// Simulate Android acknowledging that it's ready for the system to suspend.
power_instance_->GetSuspendCallback().Run();
- EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
+ EXPECT_EQ(0,
+ power_manager_client()->GetNumPendingSuspendReadinessCallbacks());
- power_manager_client_->SendSuspendDone();
+ power_manager_client()->SendSuspendDone();
EXPECT_EQ(1, power_instance_->num_suspend());
EXPECT_EQ(1, power_instance_->num_resume());
// We shouldn't crash if the instance isn't ready.
DestroyPowerInstance();
- power_manager_client_->SendSuspendImminent(
+ power_manager_client()->SendSuspendImminent(
power_manager::SuspendImminent_Reason_OTHER);
- EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
- power_manager_client_->SendSuspendDone();
+ EXPECT_EQ(0,
+ power_manager_client()->GetNumPendingSuspendReadinessCallbacks());
+ power_manager_client()->SendSuspendDone();
}
TEST_F(ArcPowerBridgeTest, SetInteractive) {
@@ -145,24 +167,24 @@ TEST_F(ArcPowerBridgeTest, ScreenBrightness) {
// Check that Chrome OS brightness changes are passed to Android.
const double kUpdatedBrightness = 45.0;
- power_manager_client_->set_screen_brightness_percent(kUpdatedBrightness);
+ power_manager_client()->set_screen_brightness_percent(kUpdatedBrightness);
power_manager::BacklightBrightnessChange change;
change.set_percent(kUpdatedBrightness);
change.set_cause(power_manager::BacklightBrightnessChange_Cause_USER_REQUEST);
- power_manager_client_->SendScreenBrightnessChanged(change);
+ power_manager_client()->SendScreenBrightnessChanged(change);
EXPECT_DOUBLE_EQ(kUpdatedBrightness, power_instance_->screen_brightness());
// Requests from Android should update the Chrome OS brightness.
const double kAndroidBrightness = 70.0;
power_bridge_->OnScreenBrightnessUpdateRequest(kAndroidBrightness);
EXPECT_DOUBLE_EQ(kAndroidBrightness,
- power_manager_client_->screen_brightness_percent());
+ power_manager_client()->screen_brightness_percent());
// To prevent battles between Chrome OS and Android, the updated brightness
// shouldn't be passed to Android immediately, but it should be passed after
// the timer fires.
change.set_percent(kAndroidBrightness);
- power_manager_client_->SendScreenBrightnessChanged(change);
+ power_manager_client()->SendScreenBrightnessChanged(change);
EXPECT_DOUBLE_EQ(kUpdatedBrightness, power_instance_->screen_brightness());
ASSERT_TRUE(power_bridge_->TriggerNotifyBrightnessTimerForTesting());
EXPECT_DOUBLE_EQ(kAndroidBrightness, power_instance_->screen_brightness());
@@ -170,71 +192,59 @@ TEST_F(ArcPowerBridgeTest, ScreenBrightness) {
TEST_F(ArcPowerBridgeTest, DifferentWakeLocks) {
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleepAllowDimming));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(0,
+ GetActiveWakeLocks(WakeLockType::kPreventDisplaySleepAllowDimming));
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::DIM);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleepAllowDimming));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1,
+ GetActiveWakeLocks(WakeLockType::kPreventDisplaySleepAllowDimming));
ReleaseDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleepAllowDimming));
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1,
+ GetActiveWakeLocks(WakeLockType::kPreventDisplaySleepAllowDimming));
ReleaseDisplayWakeLock(mojom::DisplayWakeLockType::DIM);
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleepAllowDimming));
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(0,
+ GetActiveWakeLocks(WakeLockType::kPreventDisplaySleepAllowDimming));
}
TEST_F(ArcPowerBridgeTest, ConsolidateWakeLocks) {
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// Acquiring a second Android wake lock of the same time shouldn't result in a
// second device service wake lock being requested.
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
ReleaseDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// The device service wake lock should only be released when all Android wake
// locks have been released.
ReleaseDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
}
TEST_F(ArcPowerBridgeTest, ReleaseWakeLocksWhenInstanceClosed) {
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- ASSERT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ ASSERT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// If the instance is closed, all wake locks should be released.
base::RunLoop run_loop;
- wake_lock_provider_->set_wake_lock_canceled_callback(run_loop.QuitClosure());
DestroyPowerInstance();
- run_loop.Run();
- EXPECT_EQ(0, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ run_loop.RunUntilIdle();
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// Check that wake locks can be requested after the instance becomes ready
// again.
CreatePowerInstance();
AcquireDisplayWakeLock(mojom::DisplayWakeLockType::BRIGHT);
- EXPECT_EQ(1, wake_lock_provider_->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
}
} // namespace arc
diff --git a/chromium/components/arc/timer/arc_timer_bridge.cc b/chromium/components/arc/timer/arc_timer_bridge.cc
index a2ce052fda9..fffe9ed01c8 100644
--- a/chromium/components/arc/timer/arc_timer_bridge.cc
+++ b/chromium/components/arc/timer/arc_timer_bridge.cc
@@ -4,6 +4,7 @@
#include <set>
+#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
@@ -127,6 +128,7 @@ void ArcTimerBridge::CreateTimers(
// Convert mojo arguments to D-Bus arguments required by powerd to create
// timers.
std::vector<std::pair<clockid_t, base::ScopedFD>> requests;
+ std::vector<clockid_t> clock_ids;
for (auto& request : arc_timer_requests) {
clockid_t clock_id = request->clock_id;
base::ScopedFD expiration_fd =
@@ -137,11 +139,13 @@ void ArcTimerBridge::CreateTimers(
return;
}
requests.emplace_back(clock_id, std::move(expiration_fd));
+ clock_ids.emplace_back(clock_id);
}
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->DeleteArcTimers(
- kTag, base::BindOnce(&ArcTimerBridge::OnDeleteBeforeCreateArcTimers,
- weak_ptr_factory_.GetWeakPtr(), std::move(requests),
- std::move(callback)));
+ chromeos::PowerManagerClient::Get()->CreateArcTimers(
+ kTag, std::move(requests),
+ base::BindOnce(&ArcTimerBridge::OnCreateArcTimers,
+ weak_ptr_factory_.GetWeakPtr(), std::move(clock_ids),
+ std::move(callback)));
}
void ArcTimerBridge::StartTimer(clockid_t clock_id,
@@ -153,13 +157,13 @@ void ArcTimerBridge::StartTimer(clockid_t clock_id,
std::move(callback).Run(mojom::ArcTimerResult::FAILURE);
return;
}
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->StartArcTimer(
+ chromeos::PowerManagerClient::Get()->StartArcTimer(
timer_id.value(), absolute_expiration_time,
base::BindOnce(&OnStartTimer, std::move(callback)));
}
void ArcTimerBridge::DeleteArcTimers() {
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->DeleteArcTimers(
+ chromeos::PowerManagerClient::Get()->DeleteArcTimers(
kTag, base::BindOnce(&ArcTimerBridge::OnDeleteArcTimers,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -176,36 +180,15 @@ void ArcTimerBridge::OnDeleteArcTimers(bool result) {
timer_ids_.clear();
}
-void ArcTimerBridge::OnDeleteBeforeCreateArcTimers(
- std::vector<std::pair<clockid_t, base::ScopedFD>>
- create_arc_timers_requests,
- CreateTimersCallback callback,
- bool result) {
- if (!result) {
- LOG(ERROR) << "Delete timers before create failed";
- std::move(callback).Run(mojom::ArcTimerResult::FAILURE);
- return;
- }
-
- DVLOG(1) << "Delete before create timers succeeded";
- // If the delete call succeeded then delete any timer ids stored and make a
- // create timers call.
- timer_ids_.clear();
- std::vector<clockid_t> clock_ids;
- for (const auto& request : create_arc_timers_requests)
- clock_ids.emplace_back(request.first);
-
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->CreateArcTimers(
- kTag, std::move(create_arc_timers_requests),
- base::BindOnce(&ArcTimerBridge::OnCreateArcTimers,
- weak_ptr_factory_.GetWeakPtr(), std::move(clock_ids),
- std::move(callback)));
-}
-
void ArcTimerBridge::OnCreateArcTimers(
std::vector<clockid_t> clock_ids,
CreateTimersCallback callback,
base::Optional<std::vector<TimerId>> timer_ids) {
+ // Any old timers associated with the same tag are always cleared by the API
+ // regardless of the new timers being created successfully or not. Clear the
+ // cached timer ids in that case.
+ timer_ids_.clear();
+
// The API returns a list of timer ids corresponding to each clock in
// |clock_ids|.
if (!timer_ids.has_value()) {
diff --git a/chromium/components/arc/timer/arc_timer_bridge.h b/chromium/components/arc/timer/arc_timer_bridge.h
index 162941a4aab..790e4fef8be 100644
--- a/chromium/components/arc/timer/arc_timer_bridge.h
+++ b/chromium/components/arc/timer/arc_timer_bridge.h
@@ -69,13 +69,6 @@ class ArcTimerBridge : public KeyedService,
// Callback for (powerd API) call made in |DeleteArcTimers|.
void OnDeleteArcTimers(bool result);
- // Callback for delete timers (powerd API) call made in |CreateTimers|.
- void OnDeleteBeforeCreateArcTimers(
- std::vector<std::pair<clockid_t, base::ScopedFD>>
- create_arc_timers_requests,
- CreateTimersCallback callback,
- bool result);
-
// Callback for powerd's D-Bus API called in |CreateTimers|.
void OnCreateArcTimers(std::vector<clockid_t> clock_ids,
CreateTimersCallback callback,
diff --git a/chromium/components/arc/timer/arc_timer_bridge_unittest.cc b/chromium/components/arc/timer/arc_timer_bridge_unittest.cc
index d91abf12cc5..7f126b3d402 100644
--- a/chromium/components/arc/timer/arc_timer_bridge_unittest.cc
+++ b/chromium/components/arc/timer/arc_timer_bridge_unittest.cc
@@ -15,7 +15,6 @@
#include "base/posix/unix_domain_socket.h"
#include "base/run_loop.h"
#include "base/time/time.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service_manager.h"
@@ -91,7 +90,7 @@ class ArcTimerTest : public testing::Test {
public:
ArcTimerTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
- chromeos::DBusThreadManager::Initialize();
+ chromeos::PowerManagerClient::Initialize();
timer_bridge_ = ArcTimerBridge::GetForBrowserContextForTesting(&context_);
// This results in ArcTimerBridge::OnInstanceReady being called.
ArcServiceManager::Get()->arc_bridge_service()->timer()->SetInstance(
@@ -106,7 +105,7 @@ class ArcTimerTest : public testing::Test {
ArcServiceManager::Get()->arc_bridge_service()->timer()->CloseInstance(
&timer_instance_);
timer_bridge_->Shutdown();
- chromeos::DBusThreadManager::Shutdown();
+ chromeos::PowerManagerClient::Shutdown();
}
protected:
@@ -285,8 +284,8 @@ TEST_F(ArcTimerTest, InvalidStartTimerArgsTest) {
TEST_F(ArcTimerTest, CheckMultipleCreateTimersTest) {
std::vector<clockid_t> clocks = {CLOCK_REALTIME_ALARM};
EXPECT_TRUE(CreateTimers(clocks));
- // The create implementation calls powerd's delete API before calling create.
- // The second create should thus succeed.
+ // The power manager implicitly deletes old timers associated with a tag
+ // during a create call. Thus, consecutive create calls should succeed.
EXPECT_TRUE(CreateTimers(clocks));
}
diff --git a/chromium/components/arc/usb/usb_host_bridge.cc b/chromium/components/arc/usb/usb_host_bridge.cc
index 5e2c24bf907..6c78aff75e2 100644
--- a/chromium/components/arc/usb/usb_host_bridge.cc
+++ b/chromium/components/arc/usb/usb_host_bridge.cc
@@ -166,6 +166,14 @@ void ArcUsbHostBridge::OpenDevice(const std::string& guid,
base::Bind(&OnDeviceOpenError, repeating_callback));
}
+void ArcUsbHostBridge::OpenDeviceDeprecated(
+ const std::string& guid,
+ const base::Optional<std::string>& package,
+ OpenDeviceCallback callback) {
+ LOG(ERROR) << "ArcUsbHostBridge::OpenDeviceDeprecated is deprecated";
+ OpenDevice(guid, package, std::move(callback));
+}
+
void ArcUsbHostBridge::GetDeviceInfo(const std::string& guid,
GetDeviceInfoCallback callback) {
if (!usb_service_) {
diff --git a/chromium/components/arc/usb/usb_host_bridge.h b/chromium/components/arc/usb/usb_host_bridge.h
index 35e87b8f3e2..04719ee01b9 100644
--- a/chromium/components/arc/usb/usb_host_bridge.h
+++ b/chromium/components/arc/usb/usb_host_bridge.h
@@ -53,6 +53,9 @@ class ArcUsbHostBridge : public KeyedService,
const std::string& package,
bool interactive,
RequestPermissionCallback callback) override;
+ void OpenDeviceDeprecated(const std::string& guid,
+ const base::Optional<std::string>& package,
+ OpenDeviceCallback callback) override;
void OpenDevice(const std::string& guid,
const base::Optional<std::string>& package,
OpenDeviceCallback callback) override;
diff --git a/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc b/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
index 29193169d7e..e17506ea304 100644
--- a/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
+++ b/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
@@ -4,6 +4,7 @@
#include "components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h"
+#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
@@ -537,8 +538,27 @@ void GpuArcVideoDecodeAccelerator::ImportBufferForPicture(
mojom::VideoDecodeAccelerator::Result::INVALID_ARGUMENT);
return;
}
- gmb_handle.native_pixmap_handle.fds.push_back(
- base::FileDescriptor(handle_fd.release(), true));
+
+ const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format);
+
+ // TODO(crbug.com/911370): Remove this workaround once Android passes one fd
+ // per plane.
+ std::array<base::ScopedFD, media::VideoFrame::kMaxPlanes> scoped_fds;
+ scoped_fds[0].reset(handle_fd.release());
+ for (size_t i = 1; i < num_planes; ++i) {
+ scoped_fds[i].reset(HANDLE_EINTR(dup(scoped_fds[0].get())));
+ if (!scoped_fds[i].is_valid()) {
+ VLOGF(1) << "Failed to duplicate fd.";
+ client_->NotifyError(
+ mojom::VideoDecodeAccelerator::Result::PLATFORM_FAILURE);
+ return;
+ }
+ }
+ for (size_t i = 0; i < num_planes; ++i) {
+ gmb_handle.native_pixmap_handle.fds.push_back(
+ base::FileDescriptor(scoped_fds[i].release(), true));
+ }
+
for (const auto& plane : planes) {
gmb_handle.native_pixmap_handle.planes.emplace_back(plane.stride,
plane.offset, 0);
diff --git a/chromium/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc b/chromium/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
index 897139311e1..ea5987514e6 100644
--- a/chromium/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
+++ b/chromium/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/system/sys_info.h"
#include "components/arc/video_accelerator/arc_video_accelerator_util.h"
diff --git a/chromium/components/arc/video_accelerator/protected_buffer_manager.cc b/chromium/components/arc/video_accelerator/protected_buffer_manager.cc
index 1ec0230b289..d13225a4e1a 100644
--- a/chromium/components/arc/video_accelerator/protected_buffer_manager.cc
+++ b/chromium/components/arc/video_accelerator/protected_buffer_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/bits.h"
#include "base/logging.h"
#include "base/memory/shared_memory.h"
diff --git a/chromium/components/arc/volume_mounter/DEPS b/chromium/components/arc/volume_mounter/DEPS
index f1ce17bc73e..fb773c7119d 100644
--- a/chromium/components/arc/volume_mounter/DEPS
+++ b/chromium/components/arc/volume_mounter/DEPS
@@ -1,4 +1,6 @@
include_rules = [
"+chromeos/disks",
"+third_party/re2",
+ "+ui/base/l10n",
+ "+ui/chromeos/strings",
]
diff --git a/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
index 7b131a39469..fe2523b1647 100644
--- a/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
+++ b/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -8,11 +8,14 @@
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/task/post_task.h"
+#include "chromeos/constants/chromeos_features.h"
#include "chromeos/disks/disk.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "third_party/re2/src/re2/re2.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/strings/grit/ui_chromeos_strings.h"
using chromeos::disks::DiskMountManager;
@@ -20,6 +23,11 @@ namespace arc {
namespace {
+// TODO(crbug.com/929031): Move MyFiles constants to a common place.
+constexpr char kMyFilesPath[] = "/home/chronos/user/MyFiles";
+// Dummy UUID for MyFiles volume.
+constexpr char kMyFilesUuid[] = "0000000000000000000000000000CAFEF00D2019";
+// Dummy UUID for testing.
constexpr char kDummyUuid[] = "00000000000000000000000000000000DEADBEEF";
// Singleton factory for ArcVolumeMounterBridge.
@@ -66,12 +74,35 @@ ArcVolumeMounterBridge::~ArcVolumeMounterBridge() {
// Sends MountEvents of all existing MountPoints in cros-disks.
void ArcVolumeMounterBridge::SendAllMountEvents() {
+ if (base::FeatureList::IsEnabled(chromeos::features::kMyFilesVolume))
+ SendMountEventForMyFiles();
+
for (const auto& keyValue : DiskMountManager::GetInstance()->mount_points()) {
OnMountEvent(DiskMountManager::MountEvent::MOUNTING,
chromeos::MountError::MOUNT_ERROR_NONE, keyValue.second);
}
}
+// Notifies ARC of MyFiles volume by sending a mount event.
+void ArcVolumeMounterBridge::SendMountEventForMyFiles() {
+ mojom::VolumeMounterInstance* volume_mounter_instance =
+ ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->volume_mounter(),
+ OnMountEvent);
+
+ if (!volume_mounter_instance)
+ return;
+
+ std::string device_label =
+ l10n_util::GetStringUTF8(IDS_FILE_BROWSER_MY_FILES_ROOT_LABEL);
+
+ // TODO(niwa): Add a new DeviceType enum value for MyFiles.
+ chromeos::DeviceType device_type = chromeos::DeviceType::DEVICE_TYPE_SD;
+
+ volume_mounter_instance->OnMountEvent(mojom::MountPointInfo::New(
+ chromeos::disks::DiskMountManager::MOUNTING, kMyFilesPath, kMyFilesPath,
+ kMyFilesUuid, device_label, device_type));
+}
+
void ArcVolumeMounterBridge::OnConnectionReady() {
// Deferring the SendAllMountEvents as a task to current thread to not
// block the mojo request since SendAllMountEvents might takes non trivial
diff --git a/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.h
index 6da3adde8f0..1e01b6465a6 100644
--- a/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.h
+++ b/chromium/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -55,6 +55,8 @@ class ArcVolumeMounterBridge
private:
void SendAllMountEvents();
+ void SendMountEventForMyFiles();
+
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
base::WeakPtrFactory<ArcVolumeMounterBridge> weak_ptr_factory_;
diff --git a/chromium/components/arc/wake_lock/arc_wake_lock_bridge.cc b/chromium/components/arc/wake_lock/arc_wake_lock_bridge.cc
index 2fe9e39ba8e..8c526ca99c4 100644
--- a/chromium/components/arc/wake_lock/arc_wake_lock_bridge.cc
+++ b/chromium/components/arc/wake_lock/arc_wake_lock_bridge.cc
@@ -5,11 +5,9 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
-#include "base/observer_list.h"
-#include "base/task/post_task.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_policy_controller.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
@@ -49,8 +47,7 @@ class ArcWakeLockBridgeFactory
// WakeLockRequester requests a wake lock from the device service in response
// to wake lock requests of a given type from Android. A count is kept of
-// outstanding Android requests so that only a single actual wake lock is
-// used.
+// outstanding Android requests so that only a single actual wake lock is used.
class ArcWakeLockBridge::WakeLockRequester {
public:
WakeLockRequester(device::mojom::WakeLockType type,
@@ -80,9 +77,6 @@ class ArcWakeLockBridge::WakeLockRequester {
}
wake_lock_->RequestWakeLock();
-
- for (auto& observer : observers_)
- observer.OnWakeLockAcquire();
}
// Decrements the number of outstanding Android requests. Cancels the device
@@ -101,27 +95,10 @@ class ArcWakeLockBridge::WakeLockRequester {
}
DCHECK(wake_lock_);
- DVLOG(1) << "Partial wake lock force release. Count: " << wake_lock_count_;
+ DVLOG(1) << "Partial wake force release. Count: " << wake_lock_count_;
wake_lock_->CancelWakeLock();
-
- for (auto& observer : observers_)
- observer.OnWakeLockRelease();
- }
-
- bool IsWakeLockHeld() const { return wake_lock_count_ > 0; }
-
- void AddObserver(WakeLockObserver* observer) {
- DCHECK(observer);
- observers_.AddObserver(observer);
}
- void RemoveObserver(WakeLockObserver* observer) {
- DCHECK(observer);
- observers_.RemoveObserver(observer);
- }
-
- bool HasObservers() const { return observers_.might_have_observers(); }
-
// Runs the message loop until replies have been received for all pending
// requests on |wake_lock_|.
void FlushForTesting() {
@@ -142,8 +119,6 @@ class ArcWakeLockBridge::WakeLockRequester {
// Lazily initialized in response to first request.
device::mojom::WakeLockPtr wake_lock_;
- base::ObserverList<WakeLockObserver>::Unchecked observers_;
-
DISALLOW_COPY_AND_ASSIGN(WakeLockRequester);
};
@@ -164,9 +139,6 @@ ArcWakeLockBridge* ArcWakeLockBridge::GetForBrowserContextForTesting(
return ArcWakeLockBridgeFactory::GetForBrowserContextForTesting(context);
}
-constexpr base::TimeDelta ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout;
-constexpr base::TimeDelta ArcWakeLockBridge::kDarkResumeHardTimeout;
-
ArcWakeLockBridge::ArcWakeLockBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service)
: arc_bridge_service_(bridge_service),
@@ -174,16 +146,11 @@ ArcWakeLockBridge::ArcWakeLockBridge(content::BrowserContext* context,
weak_ptr_factory_(this) {
arc_bridge_service_->wake_lock()->SetHost(this);
arc_bridge_service_->wake_lock()->AddObserver(this);
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
- this);
}
ArcWakeLockBridge::~ArcWakeLockBridge() {
arc_bridge_service_->wake_lock()->RemoveObserver(this);
arc_bridge_service_->wake_lock()->SetHost(nullptr);
- // In case some this wasn't cleared while handling a dark resume.
- GetWakeLockRequester(device::mojom::WakeLockType::kPreventAppSuspension)
- ->RemoveObserver(this);
}
void ArcWakeLockBridge::OnConnectionClosed() {
@@ -191,6 +158,11 @@ void ArcWakeLockBridge::OnConnectionClosed() {
wake_lock_requesters_.clear();
}
+void ArcWakeLockBridge::FlushWakeLocksForTesting() {
+ for (const auto& it : wake_lock_requesters_)
+ it.second->FlushForTesting();
+}
+
void ArcWakeLockBridge::AcquirePartialWakeLock(
AcquirePartialWakeLockCallback callback) {
GetWakeLockRequester(device::mojom::WakeLockType::kPreventAppSuspension)
@@ -205,104 +177,6 @@ void ArcWakeLockBridge::ReleasePartialWakeLock(
std::move(callback).Run(true);
}
-void ArcWakeLockBridge::DarkSuspendImminent() {
- DVLOG(1) << __func__;
- suspend_readiness_cb_ = chromeos::DBusThreadManager::Get()
- ->GetPowerManagerClient()
- ->GetSuspendReadinessCallback(FROM_HERE);
- // Post task that will check for any wake locks acquired in dark resume.
- base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&ArcWakeLockBridge::HandleDarkResumeWakeLockCheckTimeout,
- dark_resume_weak_ptr_factory_.GetWeakPtr()),
- kDarkResumeWakeLockCheckTimeout);
-}
-
-void ArcWakeLockBridge::SuspendDone(const base::TimeDelta& sleep_duration) {
- DVLOG(1) << __func__;
- // Clear any dark resume state when the device resumes.
- ClearDarkResumeState();
-}
-
-void ArcWakeLockBridge::OnWakeLockRelease() {
- // This observer is only registered once dark resume starts.
- DCHECK(suspend_readiness_cb_);
- DVLOG(1) << __func__;
-
- // At this point the instance has done its work, tell the power daemon to
- // re-suspend.
- std::move(suspend_readiness_cb_).Run();
- ClearDarkResumeState();
-}
-
-void ArcWakeLockBridge::FlushWakeLocksForTesting() {
- for (const auto& it : wake_lock_requesters_)
- it.second->FlushForTesting();
-}
-
-bool ArcWakeLockBridge::IsSuspendReadinessStateSetForTesting() const {
- return !suspend_readiness_cb_.is_null();
-}
-
-bool ArcWakeLockBridge::WakeLockHasObserversForTesting(
- device::mojom::WakeLockType type) {
- return GetWakeLockRequester(
- device::mojom::WakeLockType::kPreventAppSuspension)
- ->HasObservers();
-}
-
-void ArcWakeLockBridge::HandleDarkResumeWakeLockCheckTimeout() {
- DVLOG(1) << __func__;
- DCHECK_CALLED_ON_VALID_SEQUENCE(dark_resume_tasks_sequence_checker_);
- // Check if any wake locks are held at this point. If not, then it's assumed
- // the instance either acquired and released one or had no reason to acquire
- // one in the first place. If it wants to after this then too bad, tell the
- // power daemon to re-suspend and invalidate any other state associated with
- // dark resume.
- if (!GetWakeLockRequester(device::mojom::WakeLockType::kPreventAppSuspension)
- ->IsWakeLockHeld()) {
- DVLOG(1) << "Wake lock not held during check";
- std::move(suspend_readiness_cb_).Run();
- ClearDarkResumeState();
- return;
- }
-
- DVLOG(1) << "Wake lock held during check";
- // If a wake lock is held then register for a wake lock release
- // notification. As soon as it's released tell power daemon to re-suspend.
- // If the instance takes a long time then tell powerd daemon to re-suspend
- // after a hard timeout irrespective of wake locks held.
- GetWakeLockRequester(device::mojom::WakeLockType::kPreventAppSuspension)
- ->AddObserver(this);
-
- // Post task that will tell the power daemon to re-suspend after a dark
- // resume irrespective of any state. This is a last resort timeout to ensure
- // the device doesn't stay up indefinitely in dark resume.
- base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&ArcWakeLockBridge::HandleDarkResumeHardTimeout,
- dark_resume_weak_ptr_factory_.GetWeakPtr()),
- kDarkResumeHardTimeout);
-}
-
-void ArcWakeLockBridge::HandleDarkResumeHardTimeout() {
- DVLOG(1) << __func__;
- DCHECK_CALLED_ON_VALID_SEQUENCE(dark_resume_tasks_sequence_checker_);
- // Enough is enough. Tell power daemon it's okay to suspend.
- DCHECK(suspend_readiness_cb_);
- std::move(suspend_readiness_cb_).Run();
- ClearDarkResumeState();
-}
-
-void ArcWakeLockBridge::ClearDarkResumeState() {
- DVLOG(1) << __func__;
- // Invalidate all other state associated with dark resume.
- suspend_readiness_cb_.Reset();
- GetWakeLockRequester(device::mojom::WakeLockType::kPreventAppSuspension)
- ->RemoveObserver(this);
- dark_resume_weak_ptr_factory_.InvalidateWeakPtrs();
-}
-
ArcWakeLockBridge::WakeLockRequester* ArcWakeLockBridge::GetWakeLockRequester(
device::mojom::WakeLockType type) {
auto it = wake_lock_requesters_.find(type);
diff --git a/chromium/components/arc/wake_lock/arc_wake_lock_bridge.h b/chromium/components/arc/wake_lock/arc_wake_lock_bridge.h
index 545b9b0c4af..67ce3eec355 100644
--- a/chromium/components/arc/wake_lock/arc_wake_lock_bridge.h
+++ b/chromium/components/arc/wake_lock/arc_wake_lock_bridge.h
@@ -10,11 +10,8 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "chromeos/dbus/power_manager_client.h"
#include "components/arc/common/wake_lock.mojom.h"
#include "components/arc/connection_observer.h"
-#include "components/arc/wake_lock/wake_lock_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/common/service_manager_connection.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -33,9 +30,7 @@ class ArcBridgeService;
// Sets wake up timers / alarms based on calls from the instance.
class ArcWakeLockBridge : public KeyedService,
public ConnectionObserver<mojom::WakeLockInstance>,
- public mojom::WakeLockHost,
- public chromeos::PowerManagerClient::Observer,
- public WakeLockObserver {
+ public mojom::WakeLockHost {
public:
// Returns the factory instance for this class.
static BrowserContextKeyedServiceFactory* GetFactory();
@@ -59,36 +54,13 @@ class ArcWakeLockBridge : public KeyedService,
// ConnectionObserver<mojom::WakeLockInstance>::Observer overrides.
void OnConnectionClosed() override;
- // mojom::WakeLockHost overrides.
- void AcquirePartialWakeLock(AcquirePartialWakeLockCallback callback) override;
- void ReleasePartialWakeLock(ReleasePartialWakeLockCallback callback) override;
-
- // chromeos::PowerManagerClient::Observer overrides.
- void DarkSuspendImminent() override;
- void SuspendDone(const base::TimeDelta& sleep_duration) override;
-
- // WakeLockObserver override.
- void OnWakeLockRelease() override;
-
// Runs the message loop until replies have been received for all pending
// device service requests in |wake_lock_requesters_|.
void FlushWakeLocksForTesting();
- // Checks if |suspend_readiness_cb_| is set.
- bool IsSuspendReadinessStateSetForTesting() const;
-
- // Returns true iff wake lock of |type| has observers.
- bool WakeLockHasObserversForTesting(device::mojom::WakeLockType type);
-
- // Time after a dark resume when wake lock count is checked and a decision is
- // made to re-suspend or wait for wake lock release.
- static constexpr base::TimeDelta kDarkResumeWakeLockCheckTimeout =
- base::TimeDelta::FromSeconds(3);
-
- // Max time to wait for wake lock release after a wake lock check after a dark
- // resume. After this time the system is asked to re-suspend.
- static constexpr base::TimeDelta kDarkResumeHardTimeout =
- base::TimeDelta::FromSeconds(10);
+ // mojom::WakeLockHost overrides.
+ void AcquirePartialWakeLock(AcquirePartialWakeLockCallback callback) override;
+ void ReleasePartialWakeLock(ReleasePartialWakeLockCallback callback) override;
private:
class WakeLockRequester;
@@ -96,20 +68,6 @@ class ArcWakeLockBridge : public KeyedService,
// Returns the WakeLockRequester for |type|, creating one if needed.
WakeLockRequester* GetWakeLockRequester(device::mojom::WakeLockType type);
- // Runs |kDarkResumeWakeLockCheckTimeout| time delta after a dark resume.
- // Checks if app suspension wake locks (partial wake locks for Android) are
- // held. If no wake locks are held then re-suspends the device else schedules
- // |HandleDarkResumeHardTimeout|.
- void HandleDarkResumeWakeLockCheckTimeout();
-
- // Runs |kDarkResumeHardTimeout| time delta after a
- // |HandleDarkResumeWakeLockCheckTimeout|. Clears all dark resume state and
- // re-suspends the device.
- void HandleDarkResumeHardTimeout();
-
- // Clears all state associated with dark resume.
- void ClearDarkResumeState();
-
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
// If non-null, used instead of the process-wide connector to fetch services.
@@ -120,21 +78,8 @@ class ArcWakeLockBridge : public KeyedService,
std::map<device::mojom::WakeLockType, std::unique_ptr<WakeLockRequester>>
wake_lock_requesters_;
- // Called when system is ready to supend after a |DarkSupendImminent| i.e.
- // after a dark resume.
- base::OnceClosure suspend_readiness_cb_;
-
mojo::Binding<mojom::WakeLockHost> binding_;
- // Used for checking if |DarkResumeWakeLockCheckTimeout| and
- // |DarkResumeHardTimeout| run on the same sequence.
- SEQUENCE_CHECKER(dark_resume_tasks_sequence_checker_);
-
- // Factory used to schedule and cancel
- // |HandleDarkResumeWakeLockCheckTimeout| and |HandleDarkResumeHardTimeout|.
- // At any point either none or one of these tasks is in flight.
- base::WeakPtrFactory<ArcWakeLockBridge> dark_resume_weak_ptr_factory_{this};
-
base::WeakPtrFactory<ArcWakeLockBridge> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ArcWakeLockBridge);
diff --git a/chromium/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc b/chromium/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc
index 07a0fc39821..e840b6710b1 100644
--- a/chromium/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc
+++ b/chromium/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc
@@ -7,10 +7,9 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_power_manager_client.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/common/power.mojom.h"
#include "components/arc/test/connection_holder_util.h"
@@ -32,10 +31,6 @@ class ArcWakeLockBridgeTest : public testing::Test {
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
wake_lock_provider_(
connector_factory_.RegisterInstance(device::mojom::kServiceName)) {
- fake_power_manager_client_ = new chromeos::FakePowerManagerClient;
- chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
- base::WrapUnique(fake_power_manager_client_));
-
bridge_service_ = std::make_unique<ArcBridgeService>();
wake_lock_bridge_ =
std::make_unique<ArcWakeLockBridge>(nullptr, bridge_service_.get());
@@ -47,27 +42,6 @@ class ArcWakeLockBridgeTest : public testing::Test {
~ArcWakeLockBridgeTest() override { DestroyWakeLockInstance(); }
protected:
- // Creates a FakeWakeLockInstance for |bridge_service_|. This results in
- // ArcWakeLockBridge::OnInstanceReady() being called.
- void CreateWakeLockInstance() {
- instance_ = std::make_unique<FakeWakeLockInstance>();
- bridge_service_->wake_lock()->SetInstance(instance_.get());
- WaitForInstanceReady(bridge_service_->wake_lock());
- }
-
- // Destroys the FakeWakeLockInstance. This results in
- // ArcWakeLockBridge::OnInstanceClosed() being called.
- void DestroyWakeLockInstance() {
- if (!instance_)
- return;
- bridge_service_->wake_lock()->CloseInstance(instance_.get());
- instance_.reset();
- }
-
- device::TestWakeLockProvider* GetWakeLockProvider() {
- return &wake_lock_provider_;
- }
-
// Returns true iff there is no failure acquiring a system wake lock.
bool AcquirePartialWakeLock() {
base::RunLoop loop;
@@ -90,29 +64,42 @@ class ArcWakeLockBridgeTest : public testing::Test {
return result;
}
- // Return true iff all dark resume related state is set i.e the suspend
- // readiness callback is set and wake lock release event has observers.
- bool IsDarkResumeStateSet() const {
- return wake_lock_bridge_->IsSuspendReadinessStateSetForTesting() &&
- wake_lock_bridge_->WakeLockHasObserversForTesting(
- WakeLockType::kPreventAppSuspension);
+ // Creates a FakeWakeLockInstance for |bridge_service_|. This results in
+ // ArcWakeLockBridge::OnInstanceReady() being called.
+ void CreateWakeLockInstance() {
+ instance_ = std::make_unique<FakeWakeLockInstance>();
+ bridge_service_->wake_lock()->SetInstance(instance_.get());
+ WaitForInstanceReady(bridge_service_->wake_lock());
}
- // Return true iff all dark resume related state is reset. This should be true
- // when device exits dark resume either by re-suspending or transitioning to
- // full resume.
- bool IsDarkResumeStateReset() const {
- return !wake_lock_bridge_->WakeLockHasObserversForTesting(
- WakeLockType::kPreventAppSuspension) &&
- !wake_lock_bridge_->IsSuspendReadinessStateSetForTesting();
+ // Destroys the FakeWakeLockInstance. This results in
+ // ArcWakeLockBridge::OnInstanceClosed() being called.
+ void DestroyWakeLockInstance() {
+ if (!instance_)
+ return;
+ bridge_service_->wake_lock()->CloseInstance(instance_.get());
+ instance_.reset();
}
- base::test::ScopedTaskEnvironment scoped_task_environment_;
-
- // Owned by chromeos::DBusThreadManager.
- chromeos::FakePowerManagerClient* fake_power_manager_client_;
+ // Returns the number of active wake locks of type |type|.
+ int GetActiveWakeLocks(WakeLockType type) {
+ base::RunLoop run_loop;
+ int result_count = 0;
+ wake_lock_provider_.GetActiveWakeLocksForTests(
+ type,
+ base::BindOnce(
+ [](base::RunLoop* run_loop, int* result_count, int32_t count) {
+ *result_count = count;
+ run_loop->Quit();
+ },
+ &run_loop, &result_count));
+ run_loop.Run();
+ return result_count;
+ }
private:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+
service_manager::TestConnectorFactory connector_factory_;
device::TestWakeLockProvider wake_lock_provider_;
@@ -125,12 +112,10 @@ class ArcWakeLockBridgeTest : public testing::Test {
TEST_F(ArcWakeLockBridgeTest, AcquireAndReleaseSinglePartialWakeLock) {
EXPECT_TRUE(AcquirePartialWakeLock());
- EXPECT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
EXPECT_TRUE(ReleasePartialWakeLock());
- EXPECT_EQ(0, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
TEST_F(ArcWakeLockBridgeTest, AcquireAndReleaseMultiplePartialWakeLocks) {
@@ -138,133 +123,35 @@ TEST_F(ArcWakeLockBridgeTest, AcquireAndReleaseMultiplePartialWakeLocks) {
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_TRUE(AcquirePartialWakeLock());
- EXPECT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// Releasing two wake locks after acquiring three should not result in
// releasing a wake lock.
EXPECT_TRUE(ReleasePartialWakeLock());
EXPECT_TRUE(ReleasePartialWakeLock());
- EXPECT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// Releasing the remaining wake lock should result in the release of the wake
// lock.
EXPECT_TRUE(ReleasePartialWakeLock());
- EXPECT_EQ(0, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
TEST_F(ArcWakeLockBridgeTest, ReleaseWakeLockOnInstanceClosed) {
EXPECT_TRUE(AcquirePartialWakeLock());
- ASSERT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
+ ASSERT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// If the instance is closed, all wake locks should be released.
base::RunLoop run_loop;
- GetWakeLockProvider()->set_wake_lock_canceled_callback(
- run_loop.QuitClosure());
DestroyWakeLockInstance();
- run_loop.Run();
- EXPECT_EQ(0, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventDisplaySleep));
+ run_loop.RunUntilIdle();
+ EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// Check that wake locks can be requested after the instance becomes ready
// again.
CreateWakeLockInstance();
EXPECT_TRUE(AcquirePartialWakeLock());
- EXPECT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
-}
-
-TEST_F(ArcWakeLockBridgeTest, CheckSuspendAfterDarkResumeNoWakeLocksHeld) {
- // Trigger a dark resume event, move time forward to trigger a wake lock check
- // and check if a re-suspend happened if no wake locks were acquired.
- fake_power_manager_client_->SendDarkSuspendImminent();
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateReset());
-
- // Trigger a dark resume event, acquire and release a wake lock and move time
- // forward to trigger a wake lock check. The device should re-suspend in this
- // case since no wake locks were held at the time of the wake lock check.
- fake_power_manager_client_->SendDarkSuspendImminent();
- EXPECT_TRUE(AcquirePartialWakeLock());
- EXPECT_TRUE(ReleasePartialWakeLock());
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout);
- base::RunLoop run_loop2;
- run_loop2.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateReset());
-}
-
-TEST_F(ArcWakeLockBridgeTest, CheckSuspendAfterDarkResumeWakeLocksHeld) {
- // Trigger a dark resume event, acquire a wake lock and move time forward to a
- // wake lock check. At this point the system shouldn't re-suspend i.e. the
- // suspend readiness callback should be set and wake lock release should have
- // observers.
- fake_power_manager_client_->SendDarkSuspendImminent();
- EXPECT_TRUE(AcquirePartialWakeLock());
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateSet());
-
- // Move time forward by < |kDarkResumeHardTimeout| and release the
- // partial wake lock.This should instantaneously re-suspend the device.
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeHardTimeout -
- base::TimeDelta::FromSeconds(1));
- EXPECT_TRUE(ReleasePartialWakeLock());
- base::RunLoop run_loop2;
- run_loop2.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateReset());
-}
-
-TEST_F(ArcWakeLockBridgeTest, CheckSuspendAfterDarkResumeHardTimeout) {
- // Trigger a dark resume event, acquire a wake lock and move time forward to a
- // wake lock check. At this point the system shouldn't re-suspend i.e. the
- // suspend readiness callback should be set and wake lock release should have
- // observers.
- fake_power_manager_client_->SendDarkSuspendImminent();
- EXPECT_TRUE(AcquirePartialWakeLock());
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateSet());
-
- // Move time forward by |kDarkResumeHardTimeout|. At this point the
- // device should re-suspend even though the wake lock is acquired.
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeHardTimeout);
- EXPECT_EQ(1, GetWakeLockProvider()->GetActiveWakeLocksOfType(
- WakeLockType::kPreventAppSuspension));
- base::RunLoop run_loop2;
- run_loop2.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateReset());
-}
-
-TEST_F(ArcWakeLockBridgeTest, CheckStateResetAfterSuspendDone) {
- // Trigger a dark resume event, acquire a wake lock and move time forward to a
- // wake lock check. At this point the system shouldn't re-suspend i.e. the
- // suspend readiness callback should be set and wake lock release should have
- // observers.
- fake_power_manager_client_->SendDarkSuspendImminent();
- EXPECT_TRUE(AcquirePartialWakeLock());
- scoped_task_environment_.FastForwardBy(
- ArcWakeLockBridge::kDarkResumeWakeLockCheckTimeout);
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- EXPECT_TRUE(IsDarkResumeStateSet());
-
- // Trigger suspend done event. Check if state is reset as dark resume would be
- // exited.
- fake_power_manager_client_->SendSuspendDone();
- EXPECT_TRUE(IsDarkResumeStateReset());
+ EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
} // namespace arc
diff --git a/chromium/components/arc/wake_lock/wake_lock_observer.h b/chromium/components/arc/wake_lock/wake_lock_observer.h
deleted file mode 100644
index 45072a678f3..00000000000
--- a/chromium/components/arc/wake_lock/wake_lock_observer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_ARC_WAKE_LOCK_WAKE_LOCK_OBSERVER_H_
-#define COMPONENTS_ARC_WAKE_LOCK_WAKE_LOCK_OBSERVER_H_
-
-namespace arc {
-
-// This is an interface for classes that want to learn when Android wake locks
-// are acquired or released. Observer should register themselves by calling the
-// overriding class's AddObserver() method.
-class WakeLockObserver {
- public:
- virtual ~WakeLockObserver() = default;
-
- // Called when the tracked wake lock is acquired the first time i.e.
- // number of holders increases to 1.
- virtual void OnWakeLockAcquire() {}
-
- // Called when the tracked wake lock is released the last time i.e. the number
- // of holders goes to 0.
- virtual void OnWakeLockRelease() {}
-};
-
-} // namespace arc
-
-#endif // COMPONENTS_ARC_WAKE_LOCK_WAKE_LOCK_OBSERVER_H_
diff --git a/chromium/components/assist_ranker/base_predictor_unittest.cc b/chromium/components/assist_ranker/base_predictor_unittest.cc
index 6b330bae386..9339229b0e4 100644
--- a/chromium/components/assist_ranker/base_predictor_unittest.cc
+++ b/chromium/components/assist_ranker/base_predictor_unittest.cc
@@ -71,7 +71,7 @@ class FakePredictor : public BasePredictor {
// |predictor_config|.
static std::unique_ptr<FakePredictor> Create(
PredictorConfig predictor_config);
- ~FakePredictor() override{};
+ ~FakePredictor() override {}
// Validation will always succeed.
static RankerModelStatus ValidateModel(const RankerModel& model) {
return RankerModelStatus::OK;
@@ -79,7 +79,7 @@ class FakePredictor : public BasePredictor {
protected:
// Not implementing any inference logic.
- bool Initialize() override { return true; };
+ bool Initialize() override { return true; }
private:
FakePredictor(const PredictorConfig& config) : BasePredictor(config) {}
diff --git a/chromium/components/assist_ranker/binary_classifier_predictor.cc b/chromium/components/assist_ranker/binary_classifier_predictor.cc
index 402aa5931c6..54e1eb9889f 100644
--- a/chromium/components/assist_ranker/binary_classifier_predictor.cc
+++ b/chromium/components/assist_ranker/binary_classifier_predictor.cc
@@ -19,8 +19,8 @@ namespace assist_ranker {
BinaryClassifierPredictor::BinaryClassifierPredictor(
const PredictorConfig& config)
- : BasePredictor(config){};
-BinaryClassifierPredictor::~BinaryClassifierPredictor(){};
+ : BasePredictor(config) {}
+BinaryClassifierPredictor::~BinaryClassifierPredictor() {}
// static
std::unique_ptr<BinaryClassifierPredictor> BinaryClassifierPredictor::Create(
diff --git a/chromium/components/assist_ranker/classifier_predictor.cc b/chromium/components/assist_ranker/classifier_predictor.cc
index 31e90bee90b..80fa065edfa 100644
--- a/chromium/components/assist_ranker/classifier_predictor.cc
+++ b/chromium/components/assist_ranker/classifier_predictor.cc
@@ -21,8 +21,8 @@
namespace assist_ranker {
ClassifierPredictor::ClassifierPredictor(const PredictorConfig& config)
- : BasePredictor(config){};
-ClassifierPredictor::~ClassifierPredictor(){};
+ : BasePredictor(config) {}
+ClassifierPredictor::~ClassifierPredictor() {}
// static
std::unique_ptr<ClassifierPredictor> ClassifierPredictor::Create(
diff --git a/chromium/components/assist_ranker/example_preprocessing.cc b/chromium/components/assist_ranker/example_preprocessing.cc
index 8b9dde81ba0..b5929e6afc9 100644
--- a/chromium/components/assist_ranker/example_preprocessing.cc
+++ b/chromium/components/assist_ranker/example_preprocessing.cc
@@ -95,7 +95,7 @@ int ExamplePreprocessor::AddBucketizedFeatures(
break;
}
// Set one hot feature as features[feature_name] = "index";
- feature_map[feature_name].set_string_value(base::IntToString(index));
+ feature_map[feature_name].set_string_value(base::NumberToString(index));
}
return error_code;
}
@@ -135,10 +135,10 @@ int ExamplePreprocessor::ConvertToStringFeatures(
switch (feature.feature_type_case()) {
case Feature::kBoolValue:
feature.set_string_value(
- base::IntToString(static_cast<int>(feature.bool_value())));
+ base::NumberToString(static_cast<int>(feature.bool_value())));
break;
case Feature::kInt32Value:
- feature.set_string_value(base::IntToString(feature.int32_value()));
+ feature.set_string_value(base::NumberToString(feature.int32_value()));
break;
case Feature::kStringValue:
break;
diff --git a/chromium/components/assist_ranker/example_preprocessing_unittest.cc b/chromium/components/assist_ranker/example_preprocessing_unittest.cc
index aac69e185b3..79c1e7618cd 100644
--- a/chromium/components/assist_ranker/example_preprocessing_unittest.cc
+++ b/chromium/components/assist_ranker/example_preprocessing_unittest.cc
@@ -193,9 +193,9 @@ TEST_F(ExamplePreprocessorTest, ConvertToStringFeatures) {
ExamplePreprocessor::kSuccess);
(*expected.mutable_features())[bool_name_].set_string_value(
- base::IntToString(static_cast<int>(bool_value_)));
+ base::NumberToString(static_cast<int>(bool_value_)));
(*expected.mutable_features())[int32_name_].set_string_value(
- base::IntToString(int32_value_));
+ base::NumberToString(int32_value_));
EXPECT_EQUALS_EXAMPLE(example_, expected);
}
diff --git a/chromium/components/assist_ranker/proto/example_preprocessor.proto b/chromium/components/assist_ranker/proto/example_preprocessor.proto
index 800c9dfd538..3d6626aa3ef 100644
--- a/chromium/components/assist_ranker/proto/example_preprocessor.proto
+++ b/chromium/components/assist_ranker/proto/example_preprocessor.proto
@@ -31,7 +31,7 @@ message ExamplePreprocessorConfig {
map<string, float> normalizers = 4;
// Features inside this list will be converted to string_value. bool_value,
- // int32_value will be converted by base::IntToString; string_value will be
+ // int32_value will be converted by base::NumberToString; string_value will be
// kept as original; fails for other feature_types.
repeated string convert_to_string_features = 5;
}
diff --git a/chromium/components/assist_ranker/ranker_model_loader_impl_unittest.cc b/chromium/components/assist_ranker/ranker_model_loader_impl_unittest.cc
index eef70df081a..c8476fe8bcf 100644
--- a/chromium/components/assist_ranker/ranker_model_loader_impl_unittest.cc
+++ b/chromium/components/assist_ranker/ranker_model_loader_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
+#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
diff --git a/chromium/components/assist_ranker/ranker_url_fetcher.cc b/chromium/components/assist_ranker/ranker_url_fetcher.cc
index 8d0f709499b..1bc28ee4958 100644
--- a/chromium/components/assist_ranker/ranker_url_fetcher.cc
+++ b/chromium/components/assist_ranker/ranker_url_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/assist_ranker/ranker_url_fetcher.h"
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "net/base/load_flags.h"
diff --git a/chromium/components/autofill/OWNERS b/chromium/components/autofill/OWNERS
index f1fa6a5c923..09f6941e2cc 100644
--- a/chromium/components/autofill/OWNERS
+++ b/chromium/components/autofill/OWNERS
@@ -4,5 +4,6 @@ ftirelo@chromium.org
mahmadi@chromium.org
rogerm@chromium.org
sebsg@chromium.org
+tmartino@chromium.org
# COMPONENT: UI>Browser>Autofill
diff --git a/chromium/components/autofill/android/BUILD.gn b/chromium/components/autofill/android/BUILD.gn
index c952a263e04..bd2ac36e3c9 100644
--- a/chromium/components/autofill/android/BUILD.gn
+++ b/chromium/components/autofill/android/BUILD.gn
@@ -7,22 +7,24 @@ import("//build/config/android/rules.gni")
java_strings_grd("autofill_strings_grd") {
grd_file = "java/strings/autofill_strings.grd"
outputs = [
+ "values/autofill_strings.xml",
"values-am/autofill_strings.xml",
"values-ar/autofill_strings.xml",
"values-bg/autofill_strings.xml",
+ "values-bn/autofill_strings.xml",
"values-ca/autofill_strings.xml",
"values-cs/autofill_strings.xml",
"values-da/autofill_strings.xml",
"values-de/autofill_strings.xml",
"values-el/autofill_strings.xml",
- "values/autofill_strings.xml",
"values-en-rGB/autofill_strings.xml",
"values-es/autofill_strings.xml",
"values-es-rUS/autofill_strings.xml",
+ "values-et/autofill_strings.xml",
"values-fa/autofill_strings.xml",
"values-fi/autofill_strings.xml",
- "values-tl/autofill_strings.xml",
"values-fr/autofill_strings.xml",
+ "values-gu/autofill_strings.xml",
"values-hi/autofill_strings.xml",
"values-hr/autofill_strings.xml",
"values-hu/autofill_strings.xml",
@@ -30,11 +32,15 @@ java_strings_grd("autofill_strings_grd") {
"values-it/autofill_strings.xml",
"values-iw/autofill_strings.xml",
"values-ja/autofill_strings.xml",
+ "values-kn/autofill_strings.xml",
"values-ko/autofill_strings.xml",
"values-lt/autofill_strings.xml",
"values-lv/autofill_strings.xml",
- "values-nl/autofill_strings.xml",
+ "values-ml/autofill_strings.xml",
+ "values-mr/autofill_strings.xml",
+ "values-ms/autofill_strings.xml",
"values-nb/autofill_strings.xml",
+ "values-nl/autofill_strings.xml",
"values-pl/autofill_strings.xml",
"values-pt-rBR/autofill_strings.xml",
"values-pt-rPT/autofill_strings.xml",
@@ -45,7 +51,10 @@ java_strings_grd("autofill_strings_grd") {
"values-sr/autofill_strings.xml",
"values-sv/autofill_strings.xml",
"values-sw/autofill_strings.xml",
+ "values-ta/autofill_strings.xml",
+ "values-te/autofill_strings.xml",
"values-th/autofill_strings.xml",
+ "values-tl/autofill_strings.xml",
"values-tr/autofill_strings.xml",
"values-uk/autofill_strings.xml",
"values-vi/autofill_strings.xml",
@@ -65,6 +74,7 @@ android_resources("autofill_java_resources") {
java_cpp_enum("autofill_core_browser_java_enums") {
sources = [
+ "../core/browser/accessory_sheet_data.h",
"../core/browser/popup_item_ids.h",
]
}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
index f0114b9fa9f..aa4a395dbda 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
+++ b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
@@ -20,12 +20,13 @@ public class FormFieldData {
/**
* Define the control types supported by android.view.autofill.AutofillValue.
*/
- @IntDef({TYPE_TEXT, TYPE_TOGGLE, TYPE_LIST})
+ @IntDef({ControlType.TEXT, ControlType.TOGGLE, ControlType.LIST})
@Retention(RetentionPolicy.SOURCE)
- public @interface ControlType {}
- public static final int TYPE_TEXT = 0;
- public static final int TYPE_TOGGLE = 1;
- public static final int TYPE_LIST = 2;
+ public @interface ControlType {
+ int TEXT = 0;
+ int TOGGLE = 1;
+ int LIST = 2;
+ }
public final String mLabel;
public final String mName;
@@ -63,11 +64,11 @@ public class FormFieldData {
mOptionContents = optionContents;
mIsChecked = isChecked;
if (mOptionValues != null && mOptionValues.length != 0) {
- mControlType = TYPE_LIST;
+ mControlType = ControlType.LIST;
} else if (isCheckField) {
- mControlType = TYPE_TOGGLE;
+ mControlType = ControlType.TOGGLE;
} else {
- mControlType = TYPE_TEXT;
+ mControlType = ControlType.TEXT;
}
mMaxLength = maxLength;
mHeuristicType = heuristicType;
diff --git a/chromium/components/autofill/android/java/strings/autofill_strings.grd b/chromium/components/autofill/android/java/strings/autofill_strings.grd
index cd32decc6f7..e4e1b595e83 100644
--- a/chromium/components/autofill/android/java/strings/autofill_strings.grd
+++ b/chromium/components/autofill/android/java/strings/autofill_strings.grd
@@ -6,6 +6,7 @@
<output filename="values-am/autofill_strings.xml" lang="am" type="android" />
<output filename="values-ar/autofill_strings.xml" lang="ar" type="android" />
<output filename="values-bg/autofill_strings.xml" lang="bg" type="android" />
+ <output filename="values-bn/autofill_strings.xml" lang="bn" type="android" />
<output filename="values-ca/autofill_strings.xml" lang="ca" type="android" />
<output filename="values-cs/autofill_strings.xml" lang="cs" type="android" />
<output filename="values-da/autofill_strings.xml" lang="da" type="android" />
@@ -15,20 +16,26 @@
<output filename="values-en-rGB/autofill_strings.xml" lang="en-GB" type="android" />
<output filename="values-es/autofill_strings.xml" lang="es" type="android" />
<output filename="values-es-rUS/autofill_strings.xml" lang="es-419" type="android" />
+ <output filename="values-et/autofill_strings.xml" lang="et" type="android" />
<output filename="values-fa/autofill_strings.xml" lang="fa" type="android" />
<output filename="values-fi/autofill_strings.xml" lang="fi" type="android" />
<output filename="values-tl/autofill_strings.xml" lang="fil" type="android" />
<output filename="values-fr/autofill_strings.xml" lang="fr" type="android" />
+ <output filename="values-gu/autofill_strings.xml" lang="gu" type="android" />
+ <output filename="values-iw/autofill_strings.xml" lang="he" type="android" />
<output filename="values-hi/autofill_strings.xml" lang="hi" type="android" />
<output filename="values-hr/autofill_strings.xml" lang="hr" type="android" />
<output filename="values-hu/autofill_strings.xml" lang="hu" type="android" />
<output filename="values-in/autofill_strings.xml" lang="id" type="android" />
<output filename="values-it/autofill_strings.xml" lang="it" type="android" />
- <output filename="values-iw/autofill_strings.xml" lang="he" type="android" />
<output filename="values-ja/autofill_strings.xml" lang="ja" type="android" />
+ <output filename="values-kn/autofill_strings.xml" lang="kn" type="android" />
<output filename="values-ko/autofill_strings.xml" lang="ko" type="android" />
<output filename="values-lt/autofill_strings.xml" lang="lt" type="android" />
<output filename="values-lv/autofill_strings.xml" lang="lv" type="android" />
+ <output filename="values-ml/autofill_strings.xml" lang="ml" type="android" />
+ <output filename="values-mr/autofill_strings.xml" lang="mr" type="android" />
+ <output filename="values-ms/autofill_strings.xml" lang="ms" type="android" />
<output filename="values-nl/autofill_strings.xml" lang="nl" type="android" />
<output filename="values-nb/autofill_strings.xml" lang="no" type="android" />
<output filename="values-pl/autofill_strings.xml" lang="pl" type="android" />
@@ -41,6 +48,8 @@
<output filename="values-sr/autofill_strings.xml" lang="sr" type="android" />
<output filename="values-sv/autofill_strings.xml" lang="sv" type="android" />
<output filename="values-sw/autofill_strings.xml" lang="sw" type="android" />
+ <output filename="values-ta/autofill_strings.xml" lang="ta" type="android" />
+ <output filename="values-te/autofill_strings.xml" lang="te" type="android" />
<output filename="values-th/autofill_strings.xml" lang="th" type="android" />
<output filename="values-tr/autofill_strings.xml" lang="tr" type="android" />
<output filename="values-uk/autofill_strings.xml" lang="uk" type="android" />
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 1a08f64bb43..c0dc02de81e 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -11,6 +11,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -207,7 +208,7 @@ class FakeAutofillAgent : public mojom::AutofillAgent {
void SetFocusRequiresScroll(bool require) override {}
- void SetQueryPasswordSuggestion(bool query) override{};
+ void SetQueryPasswordSuggestion(bool query) override {}
void GetElementFormAndFieldData(
const std::vector<std::string>& selectors,
diff --git a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
index 2d2534c264f..d750fa4aaba 100644
--- a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
+++ b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
@@ -4,6 +4,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/autofill/content/renderer/form_autofill_util.cc b/chromium/components/autofill/content/renderer/form_autofill_util.cc
index c446763ff7a..f3894b9cee3 100644
--- a/chromium/components/autofill/content/renderer/form_autofill_util.cc
+++ b/chromium/components/autofill/content/renderer/form_autofill_util.cc
@@ -16,6 +16,7 @@
#include "base/command_line.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
@@ -98,6 +99,15 @@ enum FieldFilterMask {
FILTER_NON_FOCUSABLE_ELEMENTS,
};
+// Returns whether sending autofill field metadata to the server is enabled.
+// TODO(crbug.com/938804): Remove this when button titles are crowdsourced in
+// all channels.
+bool IsAutofillFieldMetadataEnabled() {
+ static base::NoDestructor<std::string> kGroupName(
+ base::FieldTrialList::FindFullName("AutofillFieldMetadata"));
+ return base::StartsWith(*kGroupName, "Enabled", base::CompareCase::SENSITIVE);
+}
+
void TruncateString(base::string16* str, size_t max_length) {
if (str->length() > max_length)
str->resize(max_length);
@@ -1415,6 +1425,11 @@ bool UnownedFormElementsAndFieldSetsToFormData(
FormData* form,
FormFieldData* field) {
form->origin = GetCanonicalOriginForDocument(document);
+ if (IsAutofillFieldMetadataEnabled() && !document.Body().IsNull()) {
+ SCOPED_UMA_HISTOGRAM_TIMER(
+ "PasswordManager.ButtonTitlePerformance.NoFormTag");
+ form->button_titles = InferButtonTitlesForForm(document.Body());
+ }
if (document.GetFrame() && document.GetFrame()->Top()) {
form->main_frame_origin = document.GetFrame()->Top()->GetSecurityOrigin();
} else {
@@ -1791,6 +1806,11 @@ bool WebFormElementToFormData(
form->unique_renderer_id = form_element.UniqueRendererFormId();
form->origin = GetCanonicalOriginForDocument(frame->GetDocument());
form->action = GetCanonicalActionForForm(form_element);
+ if (IsAutofillFieldMetadataEnabled()) {
+ SCOPED_UMA_HISTOGRAM_TIMER(
+ "PasswordManager.ButtonTitlePerformance.HasFormTag");
+ form->button_titles = InferButtonTitlesForForm(form_element);
+ }
if (frame->Top()) {
form->main_frame_origin = frame->Top()->GetSecurityOrigin();
} else {
diff --git a/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
index 48ce8bb59a6..f9b4f4e2edf 100644
--- a/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
+++ b/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -316,7 +316,7 @@ TEST_F(FormAutofillUtilsTest, InferButtonTitleForFormTest_TooLongTitle) {
std::string kFormHtml = "<form id='target'>";
for (int i = 0; i < 10; i++) {
std::string kFieldHtml =
- "<input type='button' value='" + base::IntToString(i) + title + "'>";
+ "<input type='button' value='" + base::NumberToString(i) + title + "'>";
kFormHtml += kFieldHtml;
}
kFormHtml += "</form>";
diff --git a/chromium/components/autofill/content/renderer/form_tracker.cc b/chromium/components/autofill/content/renderer/form_tracker.cc
index 3b2fe682d38..f5360b1c02c 100644
--- a/chromium/components/autofill/content/renderer/form_tracker.cc
+++ b/chromium/components/autofill/content/renderer/form_tracker.cc
@@ -4,6 +4,7 @@
#include "components/autofill/content/renderer/form_tracker.h"
+#include "base/bind.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/render_frame.h"
@@ -155,8 +156,9 @@ void FormTracker::DidCommitProvisionalLoad(bool is_same_document_navigation,
FireSubmissionIfFormDisappear(SubmissionSource::SAME_DOCUMENT_NAVIGATION);
}
-void FormTracker::DidStartProvisionalLoad(WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void FormTracker::DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(form_tracker_sequence_checker_);
blink::WebLocalFrame* navigated_frame = render_frame()->GetWebFrame();
// Ony handle main frame.
@@ -167,15 +169,11 @@ void FormTracker::DidStartProvisionalLoad(WebDocumentLoader* document_loader,
// the user is performing actions outside the page (e.g. typed url,
// history navigation). We don't want to trigger saving in these cases.
- // We are interested only in content initiated navigations. Explicit browser
- // initiated navigations (e.g. via omnibox) are discarded here. Similarly
- // PlzNavigate navigations originating from the browser are discarded because
- // they were already processed as a content initiated one
- // (i.e. DidStartProvisionalLoad is called twice in this case). The check for
- // kWebNavigationTypeLinkClicked is reliable only for content initiated
- // navigations.
- if (is_content_initiated && document_loader->GetNavigationType() !=
- blink::kWebNavigationTypeLinkClicked) {
+ // We are interested only in content-initiated navigations. Explicit browser
+ // initiated navigations (e.g. via omnibox) don't have a navigation type
+ // and are discarded here.
+ if (navigation_type.has_value() &&
+ navigation_type.value() != blink::kWebNavigationTypeLinkClicked) {
FireProbablyFormSubmitted();
}
}
diff --git a/chromium/components/autofill/content/renderer/form_tracker.h b/chromium/components/autofill/content/renderer/form_tracker.h
index b7e7bcd4b3f..b31d9b05a8c 100644
--- a/chromium/components/autofill/content/renderer/form_tracker.h
+++ b/chromium/components/autofill/content/renderer/form_tracker.h
@@ -91,8 +91,9 @@ class FormTracker : public content::RenderFrameObserver {
// content::RenderFrameObserver:
void DidCommitProvisionalLoad(bool is_same_document_navigation,
ui::PageTransition transition) override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) override;
void FrameDetached() override;
void WillSendSubmitEvent(const blink::WebFormElement& form) override;
void WillSubmitForm(const blink::WebFormElement& form) override;
diff --git a/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc b/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
index 40676cad5c5..88821bf6f22 100644
--- a/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
+++ b/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
@@ -6,7 +6,11 @@
#include <utility>
+#include "base/strings/string_util.h"
#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_element.h"
+#include "third_party/blink/public/web/web_input_element.h"
+#include "third_party/blink/public/web/web_node.h"
namespace autofill {
@@ -38,11 +42,31 @@ void PageFormAnalyserLogger::Flush() {
text.clear();
text += "[DOM] ";
text += entry.message;
- for (unsigned i = 0; i < entry.nodes.size(); ++i)
- text += " %o";
+
+ std::vector<blink::WebNode> nodesToLog;
+ for (unsigned i = 0; i < entry.nodes.size(); ++i) {
+ if (entry.nodes[i].IsElementNode()) {
+ const blink::WebElement element =
+ entry.nodes[i].ToConst<blink::WebElement>();
+ const blink::WebInputElement* webInputElement =
+ blink::ToWebInputElement(&element);
+
+ // Filter out password inputs with values from being logged, as their
+ // values are also logged.
+ const bool shouldObfuscate =
+ webInputElement &&
+ webInputElement->IsPasswordFieldForAutofill() &&
+ !webInputElement->Value().IsEmpty();
+
+ if (!shouldObfuscate) {
+ text += " %o";
+ nodesToLog.push_back(element);
+ }
+ }
+ }
blink::WebConsoleMessage message(level, blink::WebString::FromUTF8(text));
- message.nodes = std::move(entry.nodes); // avoids copying node vectors.
+ message.nodes = std::move(nodesToLog); // avoids copying node vectors.
frame_->AddMessageToConsole(message);
}
}
diff --git a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
index 7a8d2087700..ef70bae8012 100644
--- a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
+++ b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
@@ -95,7 +95,7 @@ struct FormInputCollection {
} \
}; \
base::LazyInstance<re2::RE2, LabelPatternLazyInstanceTraits_##NAME> NAME = \
- LAZY_INSTANCE_INITIALIZER;
+ LAZY_INSTANCE_INITIALIZER
DECLARE_LAZY_MATCHER(ignored_characters_matcher, R"(\W)");
DECLARE_LAZY_MATCHER(username_matcher, R"(user(name)?|login)");
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.cc b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
index ed933f790ea..e46c75175c3 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1015,10 +1015,6 @@ bool PasswordAutofillAgent::ShowSuggestions(const WebInputElement& element,
element != password_info->password_field))
return true;
- UMA_HISTOGRAM_BOOLEAN(
- "PasswordManager.AutocompletePopupSuppressedByGeneration",
- generation_popup_showing);
-
if (generation_popup_showing)
return false;
@@ -1351,9 +1347,8 @@ void PasswordAutofillAgent::OnDestruct() {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
-void PasswordAutofillAgent::DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void PasswordAutofillAgent::ReadyToCommitNavigation(
+ blink::WebDocumentLoader* document_loader) {
std::unique_ptr<RendererSavePasswordProgressLogger> logger;
if (logging_state_active_) {
logger.reset(new RendererSavePasswordProgressLogger(
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.h b/chromium/components/autofill/content/renderer/password_autofill_agent.h
index 01cc65b4e55..520d2ccb2ed 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.h
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.h
@@ -248,8 +248,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
// RenderFrameObserver:
void DidFinishDocumentLoad() override;
void DidFinishLoad() override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void ReadyToCommitNavigation(
+ blink::WebDocumentLoader* document_loader) override;
void WillCommitProvisionalLoad() override;
void DidCommitProvisionalLoad(bool is_same_document_navigation,
ui::PageTransition transition) override;
diff --git a/chromium/components/autofill/content/renderer/password_generation_agent.cc b/chromium/components/autofill/content/renderer/password_generation_agent.cc
index deaa4959b13..67693adae4d 100644
--- a/chromium/components/autofill/content/renderer/password_generation_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_generation_agent.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/stl_util.h"
@@ -453,6 +454,8 @@ void PasswordGenerationAgent::GeneratedPasswordAccepted(
password_generation::PASSWORD_ACCEPTED);
LogMessage(Logger::STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED);
for (auto& password_element : current_generation_item_->password_elements_) {
+ base::AutoReset<bool> auto_reset_update_confirmation_password(
+ &current_generation_item_->updating_other_password_fileds_, true);
password_element.SetAutofillValue(blink::WebString::FromUTF16(password));
// setAutofillValue() above may have resulted in JavaScript closing the
// frame.
@@ -691,7 +694,6 @@ bool PasswordGenerationAgent::FocusedNodeHasChanged(
const blink::WebElement web_element = node.ToConst<blink::WebElement>();
if (!web_element.GetDocument().GetFrame()) {
- AutomaticGenerationStatusChanged(false);
return false;
}
@@ -738,7 +740,6 @@ bool PasswordGenerationAgent::FocusedNodeHasChanged(
return true;
}
- AutomaticGenerationStatusChanged(false);
return false;
}
@@ -746,7 +747,8 @@ void PasswordGenerationAgent::DidEndTextFieldEditing(
const blink::WebInputElement& element) {
if (!element.IsNull() && current_generation_item_ &&
element == current_generation_item_->generation_element_) {
- AutomaticGenerationStatusChanged(false);
+ if (!current_generation_item_->password_is_generated_)
+ AutomaticGenerationStatusChanged(false);
current_generation_item_->generation_element_.SetShouldRevealPassword(
false);
}
@@ -897,6 +899,9 @@ void PasswordGenerationAgent::MaybeCreateCurrentGenerationItem(
? password_agent_->GetPasswordFormFromUnownedInputElements()
: password_agent_->GetPasswordFormFromWebForm(element.Form());
+ if (!password_form)
+ return;
+
std::vector<blink::WebInputElement> passwords = {element};
WebFormControlElement confirmation_password =
diff --git a/chromium/components/autofill/content/renderer/prefilled_values_detector.cc b/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
index c20059cf053..80290a4595f 100644
--- a/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
+++ b/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
@@ -21,7 +21,7 @@ const base::flat_set<std::string, std::less<>>& KnownUsernamePlaceholders() {
"3~15个字符,中文字符7个以内",
"benutzername",
"client id",
- "codice titolare"
+ "codice titolare",
"digite seu cpf ou e-mail",
"ds logon username",
"email",
diff --git a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
index 46aae75d3e6..9001bcd8f9b 100644
--- a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
+++ b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
@@ -9,8 +9,6 @@
#include "base/values.h"
#include "third_party/blink/public/web/web_form_control_element.h"
-using base::UintToString;
-
namespace autofill {
RendererSavePasswordProgressLogger::RendererSavePasswordProgressLogger(
@@ -30,7 +28,8 @@ void RendererSavePasswordProgressLogger::LogElementName(
const blink::WebFormControlElement& element) {
std::string text =
"name = " + ScrubElementID(element.NameForAutofill().Utf8()) +
- ", renderer_id = " + UintToString(element.UniqueRendererFormControlId());
+ ", renderer_id = " +
+ base::NumberToString(element.UniqueRendererFormControlId());
LogValue(label, base::Value(text));
}
diff --git a/chromium/components/autofill/core/browser/BUILD.gn b/chromium/components/autofill/core/browser/BUILD.gn
index 9cf6e445d70..fea04db6961 100644
--- a/chromium/components/autofill/core/browser/BUILD.gn
+++ b/chromium/components/autofill/core/browser/BUILD.gn
@@ -18,6 +18,8 @@ jumbo_static_library("browser") {
"address_combobox_model.h",
"address_field.cc",
"address_field.h",
+ "address_form_label_formatter.cc",
+ "address_form_label_formatter.h",
"address_i18n.cc",
"address_i18n.h",
"address_normalization_manager.cc",
@@ -92,6 +94,8 @@ jumbo_static_library("browser") {
"autofill_wallet_model_type_controller.h",
"card_unmask_delegate.cc",
"card_unmask_delegate.h",
+ "contact_form_label_formatter.cc",
+ "contact_form_label_formatter.h",
"contact_info.cc",
"contact_info.h",
"country_combobox_model.cc",
@@ -125,6 +129,10 @@ jumbo_static_library("browser") {
"form_structure.h",
"form_types.cc",
"form_types.h",
+ "label_formatter.cc",
+ "label_formatter.h",
+ "label_formatter_utils.cc",
+ "label_formatter_utils.h",
"legacy_strike_database.cc",
"legacy_strike_database.h",
"legal_message_line.cc",
@@ -133,6 +141,13 @@ jumbo_static_library("browser") {
"local_card_migration_manager.h",
"local_card_migration_strike_database.cc",
"local_card_migration_strike_database.h",
+ "metrics/address_form_event_logger.cc",
+ "metrics/address_form_event_logger.h",
+ "metrics/credit_card_form_event_logger.cc",
+ "metrics/credit_card_form_event_logger.h",
+ "metrics/form_event_logger_base.cc",
+ "metrics/form_event_logger_base.h",
+ "metrics/form_events.h",
"name_field.cc",
"name_field.h",
"password_requirements_spec_fetcher.h",
@@ -161,6 +176,8 @@ jumbo_static_library("browser") {
"phone_number_i18n.h",
"popup_item_ids.h",
"popup_types.h",
+ "price_field.cc",
+ "price_field.h",
"randomized_encoder.cc",
"randomized_encoder.h",
"rationalization_util.cc",
@@ -179,6 +196,8 @@ jumbo_static_library("browser") {
"strike_database.h",
"strike_database_integrator_base.cc",
"strike_database_integrator_base.h",
+ "strike_database_integrator_test_strike_database.cc",
+ "strike_database_integrator_test_strike_database.h",
"subkey_requester.cc",
"subkey_requester.h",
"suggestion.cc",
@@ -188,6 +207,8 @@ jumbo_static_library("browser") {
"sync_utils.h",
"test_data_creator.cc",
"test_data_creator.h",
+ "travel_field.cc",
+ "travel_field.h",
"ui/card_unmask_prompt_controller.h",
"ui/card_unmask_prompt_controller_impl.cc",
"ui/card_unmask_prompt_controller_impl.h",
@@ -252,6 +273,8 @@ jumbo_static_library("browser") {
"autofill_save_card_infobar_delegate_mobile.cc",
"autofill_save_card_infobar_delegate_mobile.h",
"autofill_save_card_infobar_mobile.h",
+ "ui/card_expiration_date_fix_flow_view_delegate_mobile.cc",
+ "ui/card_expiration_date_fix_flow_view_delegate_mobile.h",
"ui/card_name_fix_flow_view_delegate_mobile.cc",
"ui/card_name_fix_flow_view_delegate_mobile.h",
]
@@ -295,6 +318,7 @@ jumbo_static_library("browser") {
"//base",
"//base:i18n",
"//components/data_use_measurement/core",
+ "//components/google/core/common",
"//components/history/core/browser",
"//components/infobars/core",
"//components/keyed_service/core",
@@ -375,6 +399,8 @@ jumbo_static_library("test_support") {
"test_autofill_manager.h",
"test_autofill_profile_validator.cc",
"test_autofill_profile_validator.h",
+ "test_autofill_profile_validator_delayed.cc",
+ "test_autofill_profile_validator_delayed.h",
"test_autofill_provider.cc",
"test_autofill_provider.h",
"test_credit_card_save_manager.cc",
@@ -390,8 +416,6 @@ jumbo_static_library("test_support") {
"test_legacy_strike_database.h",
"test_local_card_migration_manager.cc",
"test_local_card_migration_manager.h",
- "test_local_card_migration_strike_database.cc",
- "test_local_card_migration_strike_database.h",
"test_personal_data_manager.cc",
"test_personal_data_manager.h",
"test_region_data_loader.cc",
@@ -517,17 +541,16 @@ source_set("unit_tests") {
"country_names_unittest.cc",
"credit_card_field_unittest.cc",
"credit_card_save_manager_unittest.cc",
- "credit_card_save_strike_database_unittest.cc",
"credit_card_unittest.cc",
"field_candidates_unittest.cc",
"field_filler_unittest.cc",
"form_data_importer_unittest.cc",
"form_field_unittest.cc",
"form_structure_unittest.cc",
+ "label_formatter_utils_unittest.cc",
"legacy_strike_database_unittest.cc",
"legal_message_line_unittest.cc",
"local_card_migration_manager_unittest.cc",
- "local_card_migration_strike_database_unittest.cc",
"name_field_unittest.cc",
"password_generator_fips181_unittest.cc",
"password_generator_unittest.cc",
@@ -540,11 +563,13 @@ source_set("unit_tests") {
"phone_field_unittest.cc",
"phone_number_i18n_unittest.cc",
"phone_number_unittest.cc",
+ "price_field_unittest.cc",
"proto/legacy_proto_bridge_unittest.cc",
"randomized_encoder_unittest.cc",
"rationalization_util_unittest.cc",
"region_combobox_model_unittest.cc",
"search_field_unittest.cc",
+ "strike_database_integrator_test_strike_database_unittest.cc",
"strike_database_unittest.cc",
"subkey_requester_unittest.cc",
"suggestion_selection_unittest.cc",
@@ -600,6 +625,7 @@ source_set("unit_tests") {
"//components/ukm:test_support",
"//components/variations",
"//components/variations:test_support",
+ "//components/variations/net",
"//components/version_info:version_info",
"//components/webdata/common",
"//components/webdata_services:test_support",
diff --git a/chromium/components/autofill/core/browser/DEPS b/chromium/components/autofill/core/browser/DEPS
index 35cb68b74d4..3536f9f5ce0 100644
--- a/chromium/components/autofill/core/browser/DEPS
+++ b/chromium/components/autofill/core/browser/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+components/data_use_measurement/core",
+ "+components/google/core/common/google_util.h",
"+components/grit/components_scaled_resources.h",
"+components/history/core/browser",
"+components/infobars/core",
diff --git a/chromium/components/autofill/core/browser/OWNERS b/chromium/components/autofill/core/browser/OWNERS
new file mode 100644
index 00000000000..013fa313149
--- /dev/null
+++ b/chromium/components/autofill/core/browser/OWNERS
@@ -0,0 +1 @@
+parastoog@google.com
diff --git a/chromium/components/autofill/core/browser/accessory_sheet_data.cc b/chromium/components/autofill/core/browser/accessory_sheet_data.cc
index dc0eb25bd7d..75cce7ffa5b 100644
--- a/chromium/components/autofill/core/browser/accessory_sheet_data.cc
+++ b/chromium/components/autofill/core/browser/accessory_sheet_data.cc
@@ -67,8 +67,9 @@ bool FooterCommand::operator==(const FooterCommand& fc) const {
return display_text_ == fc.display_text_;
}
-AccessorySheetData::AccessorySheetData(const base::string16& title)
- : title_(title) {}
+AccessorySheetData::AccessorySheetData(FallbackSheetType sheet_type,
+ const base::string16& title)
+ : sheet_type_(sheet_type), title_(title) {}
AccessorySheetData::AccessorySheetData(const AccessorySheetData& data) =
default;
diff --git a/chromium/components/autofill/core/browser/accessory_sheet_data.h b/chromium/components/autofill/core/browser/accessory_sheet_data.h
index 5e439d787c1..384079b895e 100644
--- a/chromium/components/autofill/core/browser/accessory_sheet_data.h
+++ b/chromium/components/autofill/core/browser/accessory_sheet_data.h
@@ -87,14 +87,20 @@ class FooterCommand {
base::string16 display_text_;
};
+// GENERATED_JAVA_ENUM_PACKAGE: (
+// org.chromium.chrome.browser.autofill.keyboard_accessory)
+enum class FallbackSheetType {
+ // Indicates the data type to which an AccessorySheetData object corresponds.
+ PASSWORD,
+ CREDIT_CARD
+};
+
// Represents the contents of a bottom sheet tab below the keyboard accessory,
// which can correspond to passwords, credit cards, or profiles data.
-//
-// TODO(crbug.com/902425): Add a field to indicate if this corresponds to
-// password, profile, or credit card data.
class AccessorySheetData {
public:
- explicit AccessorySheetData(const base::string16& title);
+ explicit AccessorySheetData(FallbackSheetType sheet_type,
+ const base::string16& title);
AccessorySheetData(const AccessorySheetData& data);
AccessorySheetData(AccessorySheetData&& data);
@@ -104,6 +110,7 @@ class AccessorySheetData {
AccessorySheetData& operator=(AccessorySheetData&& data);
const base::string16& title() const { return title_; }
+ FallbackSheetType get_sheet_type() const { return sheet_type_; }
void add_user_info(UserInfo user_info) {
user_info_list_.emplace_back(std::move(user_info));
@@ -126,6 +133,7 @@ class AccessorySheetData {
bool operator==(const AccessorySheetData& data) const;
private:
+ FallbackSheetType sheet_type_;
base::string16 title_;
std::vector<UserInfo> user_info_list_;
std::vector<FooterCommand> footer_commands_;
diff --git a/chromium/components/autofill/core/browser/account_info_getter.h b/chromium/components/autofill/core/browser/account_info_getter.h
index 7d71b5fae99..44fa238ebec 100644
--- a/chromium/components/autofill/core/browser/account_info_getter.h
+++ b/chromium/components/autofill/core/browser/account_info_getter.h
@@ -17,7 +17,7 @@ class AccountInfoGetter {
// Returns the account info that should be used when communicating with the
// Payments server. The AccountInfo could be empty if there is no account to
// be used by the Payments server.
- virtual AccountInfo GetAccountInfoForPaymentsServer() const = 0;
+ virtual CoreAccountInfo GetAccountInfoForPaymentsServer() const = 0;
// Returns true - When user is both signed-in and enabled sync.
// Returns false - When user is not signed-in or does not have sync the
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
new file mode 100644
index 00000000000..604dd7882da
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/address_form_label_formatter.h"
+
+namespace autofill {
+
+AddressFormLabelFormatter::AddressFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types)
+ : LabelFormatter(app_locale, focused_field_type, field_types) {
+ for (const ServerFieldType& type : field_types) {
+ if (type != focused_field_type && type != ADDRESS_HOME_COUNTRY &&
+ type != ADDRESS_BILLING_COUNTRY) {
+ field_types_for_labels_.push_back(type);
+ }
+ }
+}
+
+AddressFormLabelFormatter::~AddressFormLabelFormatter() {}
+
+std::vector<base::string16> AddressFormLabelFormatter::GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const {
+ // TODO(crbug.com/936168): Implement GetLabels().
+ std::vector<base::string16> labels;
+ return labels;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter.h b/chromium/components/autofill/core/browser/address_form_label_formatter.h
new file mode 100644
index 00000000000..1f0c4850a3d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+// A LabelFormatter that creates Suggestions' disambiguating labels for forms
+// with name and address fields and without email or phone fields.
+class AddressFormLabelFormatter : public LabelFormatter {
+ public:
+ AddressFormLabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+
+ ~AddressFormLabelFormatter() override;
+
+ std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const override;
+
+ private:
+ // A collection of field types that can be used to make labels. This
+ // collection excludes the focused_field_type_ and address countries.
+ std::vector<ServerFieldType> field_types_for_labels_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/address_i18n_unittest.cc b/chromium/components/autofill/core/browser/address_i18n_unittest.cc
index 2647d888fe2..0f96565a4b7 100644
--- a/chromium/components/autofill/core/browser/address_i18n_unittest.cc
+++ b/chromium/components/autofill/core/browser/address_i18n_unittest.cc
@@ -55,7 +55,7 @@ TEST_P(FieldTypeMirrorConversionsTest, FieldTypeMirrorConversions) {
EXPECT_EQ(test_data.server_field, server_field);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AddressI18nTest,
FieldTypeMirrorConversionsTest,
testing::Values(
@@ -108,17 +108,17 @@ TEST_P(FieldTypeUnidirectionalConversionsTest,
EXPECT_EQ(test_data.expected_address_field, actual_address_field);
}
-INSTANTIATE_TEST_CASE_P(AddressI18nTest,
- FieldTypeUnidirectionalConversionsTest,
- testing::Values(
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_BILLING_LINE1, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_BILLING_LINE2, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_HOME_LINE1, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_HOME_LINE2, STREET_ADDRESS}));
+INSTANTIATE_TEST_SUITE_P(AddressI18nTest,
+ FieldTypeUnidirectionalConversionsTest,
+ testing::Values(
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_BILLING_LINE1, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_BILLING_LINE2, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_HOME_LINE1, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_HOME_LINE2, STREET_ADDRESS}));
TEST(AddressI18nTest, UnconvertableServerFields) {
EXPECT_FALSE(FieldForType(PHONE_HOME_NUMBER, nullptr));
diff --git a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
index d15eb19251a..8eae19020de 100644
--- a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
+++ b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
diff --git a/chromium/components/autofill/core/browser/autofill_assistant.cc b/chromium/components/autofill/core/browser/autofill_assistant.cc
index d72104c0909..5cbbd241c0b 100644
--- a/chromium/components/autofill/core/browser/autofill_assistant.cc
+++ b/chromium/components/autofill/core/browser/autofill_assistant.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/autofill_assistant.h"
+#include "base/bind.h"
#include "base/containers/adapters.h"
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_manager.h"
diff --git a/chromium/components/autofill/core/browser/autofill_client.h b/chromium/components/autofill/core/browser/autofill_client.h
index cb53a600e65..0341ce2c565 100644
--- a/chromium/components/autofill/core/browser/autofill_client.h
+++ b/chromium/components/autofill/core/browser/autofill_client.h
@@ -123,6 +123,35 @@ class AutofillClient : public RiskDataLoader {
base::string16 expiration_date_year;
};
+ // Used for options of upload prompt.
+ struct SaveCreditCardOptions {
+ SaveCreditCardOptions& with_has_non_focusable_field(bool b) {
+ has_non_focusable_field = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_should_request_name_from_user(bool b) {
+ should_request_name_from_user = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_should_request_expiration_date_from_user(
+ bool b) {
+ should_request_expiration_date_from_user = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_show_prompt(bool b = true) {
+ show_prompt = b;
+ return *this;
+ }
+
+ bool has_non_focusable_field = false;
+ bool should_request_name_from_user = false;
+ bool should_request_expiration_date_from_user = false;
+ bool show_prompt = false;
+ };
+
// Callback to run after local credit card save is offered. Sends whether the
// prompt was accepted, declined, or ignored in |user_decision|.
typedef base::OnceCallback<void(SaveCardOfferUserDecision user_decision)>
@@ -247,35 +276,43 @@ class AutofillClient : public RiskDataLoader {
// Runs |callback| once the user makes a decision with respect to the
// offer-to-save prompt. On desktop, shows the offer-to-save bubble if
- // |show_prompt| is true; otherwise only shows the omnibox icon. On mobile,
- // shows the offer-to-save infobar if |show_prompt| is true; otherwise does
- // not offer to save at all.
+ // |options.show_prompt| is true; otherwise only shows the
+ // omnibox icon. On mobile, shows the offer-to-save infobar if
+ // |options.show_prompt| is true; otherwise does not offer to
+ // save at all.
virtual void ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ AutofillClient::SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) = 0;
#if defined(OS_ANDROID)
- // Run |callback| if the card should be uploaded to payments with updated
- // name from the user.
+ // Display the cardholder name fix flow prompt and run the |callback| if
+ // the card should be uploaded to payments with updated name from the user.
virtual void ConfirmAccountNameFixFlow(
base::OnceCallback<void(const base::string16&)> callback) = 0;
+ // Display the expiration date fix flow prompt with the |card| details
+ // and run the |callback| if the card should be uploaded to payments with
+ // updated expiration date from the user.
+ virtual void ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) = 0;
#endif // defined(OS_ANDROID)
// Runs |callback| once the user makes a decision with respect to the
// offer-to-save prompt. Displays the contents of |legal_message| to the user.
// Displays a cardholder name textfield in the bubble if
- // |should_request_name_from_user| is true. Displays a pair of expiration date
- // dropdowns in the bubble if |should_request_expiration_date_from_user| is
- // true. On desktop, shows the offer-to-save bubble if |show_prompt| is true;
+ // |options.should_request_name_from_user| is true. Displays
+ // a pair of expiration date dropdowns in the bubble if
+ // |should_request_expiration_date_from_user| is true. On desktop, shows the
+ // offer-to-save bubble if |options.show_prompt| is true;
// otherwise only shows the omnibox icon. On mobile, shows the offer-to-save
- // infobar if |show_prompt| is true; otherwise does not offer to save at all.
+ // infobar if |options.show_prompt| is true; otherwise does
+ // not offer to save at all.
virtual void ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) = 0;
// Will show an infobar to get user consent for Credit Card assistive filling.
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.cc b/chromium/components/autofill/core/browser/autofill_data_model.cc
index 913bfe22e69..59f83e57b3e 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_model.cc
@@ -37,8 +37,9 @@ bool AutofillDataModel::UseDateEqualsInSeconds(
return !((other->use_date() - use_date()).InSeconds());
}
-bool AutofillDataModel::CompareFrecency(const AutofillDataModel* other,
- base::Time comparison_time) const {
+bool AutofillDataModel::HasGreaterFrecencyThan(
+ const AutofillDataModel* other,
+ base::Time comparison_time) const {
double score = GetFrecencyScore(comparison_time);
double other_score = other->GetFrecencyScore(comparison_time);
@@ -79,4 +80,15 @@ bool AutofillDataModel::IsDeletable() const {
return use_date_ < AutofillClock::Now() - kDisusedDataModelDeletionTimeDelta;
}
+AutofillDataModel::ValidityState AutofillDataModel::GetValidityState(
+ ServerFieldType type,
+ AutofillDataModel::ValidationSource source) const {
+ return AutofillDataModel::UNSUPPORTED;
+}
+
+bool AutofillDataModel::ShouldSkipFillingOrSuggesting(
+ ServerFieldType type) const {
+ return false;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.h b/chromium/components/autofill/core/browser/autofill_data_model.h
index 719df504e04..07fd92b828d 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.h
+++ b/chromium/components/autofill/core/browser/autofill_data_model.h
@@ -22,6 +22,26 @@ struct AutofillMetadata;
// PersonalDataManager.
class AutofillDataModel : public FormGroup {
public:
+ enum ValidityState {
+ // The field has not been validated.
+ UNVALIDATED = 0,
+ // The field is empty.
+ EMPTY = 1,
+ // The field is valid.
+ VALID = 2,
+ // The field is invalid.
+ INVALID = 3,
+ // The validation for the field is unsupported.
+ UNSUPPORTED = 4,
+ };
+
+ enum ValidationSource {
+ // The validity state is according to the client validation.
+ CLIENT = 0,
+ // The validity state is according to the server validation.
+ SERVER = 1,
+ };
+
AutofillDataModel(const std::string& guid, const std::string& origin);
~AutofillDataModel() override;
@@ -56,8 +76,8 @@ class AutofillDataModel : public FormGroup {
// a combination of frequency and recency to determine the relevance of the
// profile. |comparison_time_| allows consistent sorting throughout the
// comparisons.
- bool CompareFrecency(const AutofillDataModel* other,
- base::Time comparison_time) const;
+ bool HasGreaterFrecencyThan(const AutofillDataModel* other,
+ base::Time comparison_time) const;
// Gets the metadata associated with this autofill data model.
virtual AutofillMetadata GetMetadata() const;
@@ -70,6 +90,14 @@ class AutofillDataModel : public FormGroup {
// longer than |kDisusedCreditCardDeletionTimeDelta|.
virtual bool IsDeletable() const;
+ // Returns the validity state of the specified autofill type.
+ virtual ValidityState GetValidityState(ServerFieldType type,
+ ValidationSource source) const;
+
+ // Check for the validity of the data. Leave the field empty if the data is
+ // invalid and the relevant feature is enabled.
+ virtual bool ShouldSkipFillingOrSuggesting(ServerFieldType type) const;
+
protected:
// Called to update |use_count_| and |use_date_| when this data model is
// the subject of user interaction (usually, when it's used to fill a form).
diff --git a/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc b/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
index 670e50ce8d1..f719d9b7ac7 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
@@ -110,7 +110,7 @@ TEST(AutofillDataModelTest, IsDeletable) {
}
enum Expectation { GREATER, LESS };
-struct CompareFrecencyTestCase {
+struct HasGreaterFrecencyThanTestCase {
const std::string guid_a;
const int use_count_a;
const base::Time use_date_a;
@@ -122,10 +122,10 @@ struct CompareFrecencyTestCase {
base::Time now = base::Time::Now();
-class CompareFrecencyTest
- : public testing::TestWithParam<CompareFrecencyTestCase> {};
+class HasGreaterFrecencyThanTest
+ : public testing::TestWithParam<HasGreaterFrecencyThanTestCase> {};
-TEST_P(CompareFrecencyTest, CompareFrecency) {
+TEST_P(HasGreaterFrecencyThanTest, HasGreaterFrecencyThan) {
auto test_case = GetParam();
TestAutofillDataModel model_a(test_case.guid_a, test_case.use_count_a,
test_case.use_date_a);
@@ -133,39 +133,44 @@ TEST_P(CompareFrecencyTest, CompareFrecency) {
test_case.use_date_b);
EXPECT_EQ(test_case.expectation == GREATER,
- model_a.CompareFrecency(&model_b, now));
+ model_a.HasGreaterFrecencyThan(&model_b, now));
EXPECT_NE(test_case.expectation == GREATER,
- model_b.CompareFrecency(&model_a, now));
+ model_b.HasGreaterFrecencyThan(&model_a, now));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataModelTest,
- CompareFrecencyTest,
+ HasGreaterFrecencyThanTest,
testing::Values(
// Same frecency, model_a has a smaller GUID (tie breaker).
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 8, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 8, now,
+ LESS},
// Same recency, model_a has a bigger frequency.
- CompareFrecencyTestCase{"guid_a", 10, now, "guid_b", 8, now, GREATER},
+ HasGreaterFrecencyThanTestCase{"guid_a", 10, now, "guid_b", 8, now,
+ GREATER},
// Same recency, model_a has a smaller frequency.
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 10, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 10, now,
+ LESS},
// Same frequency, model_a is more recent.
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 8,
- now - base::TimeDelta::FromDays(1), GREATER},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 8,
+ now - base::TimeDelta::FromDays(1),
+ GREATER},
// Same frequency, model_a is less recent.
- CompareFrecencyTestCase{"guid_a", 8, now - base::TimeDelta::FromDays(1),
- "guid_b", 8, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8,
+ now - base::TimeDelta::FromDays(1),
+ "guid_b", 8, now, LESS},
// Special case: occasional profiles. A profile with relatively low
// usage and used recently (model_b) should not rank higher than a more
// used profile that has been unused for a short amount of time
// (model_a).
- CompareFrecencyTestCase{
+ HasGreaterFrecencyThanTestCase{
"guid_a", 300, now - base::TimeDelta::FromDays(5), "guid_b", 10,
now - base::TimeDelta::FromDays(1), GREATER},
// Special case: moving. A new profile used frequently (model_b) should
// rank higher than a profile with more usage that has not been used for
// a while (model_a).
- CompareFrecencyTestCase{"guid_a", 300,
- now - base::TimeDelta::FromDays(15), "guid_b",
- 10, now - base::TimeDelta::FromDays(1), LESS}));
+ HasGreaterFrecencyThanTestCase{
+ "guid_a", 300, now - base::TimeDelta::FromDays(15), "guid_b", 10,
+ now - base::TimeDelta::FromDays(1), LESS}));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
index d2de5151ec8..57c7748b217 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
@@ -25,7 +25,7 @@ TEST_P(IsCJKNameTest, IsCJKName) {
<< "Failed for: " << test_case.full_name;
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtilTest,
IsCJKNameTest,
testing::Values(
@@ -73,7 +73,7 @@ TEST_P(SplitNameTest, SplitName) {
EXPECT_EQ(base::UTF8ToUTF16(test_case.family_name), name_parts.family);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
SplitNameTest,
testing::Values(
@@ -150,7 +150,7 @@ TEST_P(JoinNamePartsTest, JoinNameParts) {
EXPECT_EQ(base::UTF8ToUTF16(test_case.full_name), joined);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
JoinNamePartsTest,
testing::Values(
@@ -213,7 +213,7 @@ TEST_P(ValidCountryCodeTest, ValidCountryCode) {
IsValidCountryCode(test_case.country_code));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
ValidCountryCodeTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager.cc b/chromium/components/autofill/core/browser/autofill_download_manager.cc
index adeb0145dd7..1b9a0429dd4 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/autofill_download_manager.h"
+#include <algorithm>
#include <tuple>
#include <utility>
@@ -34,6 +35,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/submission_source.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/google/core/common/google_util.h"
#include "components/history/core/browser/history_service.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
@@ -52,6 +54,12 @@ namespace autofill {
namespace {
+// The reserved identifier ranges for autofill server experiments.
+constexpr std::pair<int, int> kAutofillExperimentRanges[] = {
+ {3312923, 3312930}, {3314208, 3314209}, {3314711, 3314712},
+ {3314445, 3314448}, {3314854, 3314883},
+};
+
const size_t kMaxQueryGetSize = 1400; // 1.25KB
const size_t kAutofillDownloadManagerMaxFormCacheSize = 16;
const size_t kMaxFieldsPerQueryRequest = 100;
@@ -85,6 +93,13 @@ const net::BackoffEntry::Policy kAutofillBackoffPolicy = {
const char kDefaultAutofillServerURL[] =
"https://clients1.google.com/tbproxy/af/";
+// The default number of days after which to reset the registry of autofill
+// events for which an upload has been sent.
+constexpr base::FeatureParam<int> kAutofillUploadThrottlingPeriodInDays(
+ &features::kAutofillUploadThrottling,
+ switches::kAutofillUploadThrottlingPeriodInDays,
+ 28);
+
// Header for API key.
constexpr char kGoogApiKey[] = "X-Goog-Api-Key";
// Header to get base64 encoded serialized proto from API for safety.
@@ -93,6 +108,12 @@ constexpr char kGoogEncodeResponseIfExecutable[] =
constexpr char kDefaultAPIKey[] = "";
+// The maximum number of attempts for a given autofill request.
+constexpr base::FeatureParam<int> kAutofillMaxServerAttempts(
+ &features::kAutofillServerCommunication,
+ "max-attempts",
+ 5);
+
// Returns the base URL for the autofill server.
GURL GetAutofillServerURL() {
// If a valid autofill server URL is specified on the command line, then the
@@ -136,6 +157,20 @@ GURL GetAutofillServerURL() {
return autofill_server_url;
}
+base::TimeDelta GetThrottleResetPeriod() {
+ return base::TimeDelta::FromDays(
+ std::max(1, kAutofillUploadThrottlingPeriodInDays.Get()));
+}
+
+// Returns true if |id| is within |kAutofillExperimentRanges|.
+bool IsAutofillExperimentId(int id) {
+ for (const auto& range : kAutofillExperimentRanges) {
+ if (range.first <= id && id <= range.second)
+ return true;
+ }
+ return false;
+}
+
// Helper to log the HTTP |response_code| and other data received for
// |request_type| to UMA.
void LogHttpResponseData(AutofillDownloadManager::RequestType request_type,
@@ -343,21 +378,24 @@ std::ostream& operator<<(std::ostream& out,
return out;
}
-// Check for and returns true if |upload_event| is allowed to trigger an upload
-// for |form|. If true, updates |prefs| to track that |upload_event| has been
-// recorded for |form|.
-bool IsUploadAllowed(const FormStructure& form, PrefService* pref_service) {
- if (!pref_service ||
- !base::FeatureList::IsEnabled(features::kAutofillUploadThrottling)) {
- return true;
- }
+// Returns true if an upload of |form| triggered by |form.submission_source()|
+// can be throttled/suppressed. This is true if |prefs| indicates that this
+// upload has already happened within the last update window. Updates |prefs|
+// account for the upload for |form|.
+bool CanThrottleUpload(const FormStructure& form,
+ base::TimeDelta throttle_reset_period,
+ PrefService* pref_service) {
+ // PasswordManager uploads are triggered via specific first occurrences and
+ // do not participate in the pref-service tracked throttling mechanism. Return
+ // false for these uploads.
+ if (!pref_service)
+ return false;
// If the upload event pref needs to be reset, clear it now.
- static constexpr base::TimeDelta kResetPeriod = base::TimeDelta::FromDays(28);
base::Time now = AutofillClock::Now();
base::Time last_reset =
pref_service->GetTime(prefs::kAutofillUploadEventsLastResetTimestamp);
- if ((now - last_reset) > kResetPeriod) {
+ if ((now - last_reset) > throttle_reset_period) {
AutofillDownloadManager::ClearUploadHistory(pref_service);
}
@@ -376,17 +414,15 @@ bool IsUploadAllowed(const FormStructure& form, PrefService* pref_service) {
DCHECK_LT(bit, 32);
const int mask = (1 << bit);
- // Check if the upload should be allowed and, if so, update the upload event
- // pref to set the appropriate bit.
- bool allow_upload = ((value & mask) == 0);
- if (allow_upload) {
+ // Check if this is the first upload for this event. If so, update the upload
+ // event pref to set the appropriate bit.
+ bool is_first_upload_for_event = ((value & mask) == 0);
+ if (is_first_upload_for_event) {
DictionaryPrefUpdate update(pref_service, prefs::kAutofillUploadEvents);
update->SetKey(std::move(key), base::Value(value | mask));
}
- // Capture metrics and return.
- AutofillMetrics::LogUploadEvent(form.submission_source(), allow_upload);
- return allow_upload;
+ return !is_first_upload_for_event;
}
// Determines whether to use the API instead of the legacy server.
@@ -441,8 +477,20 @@ struct AutofillDownloadManager::FormRequestData {
std::vector<std::string> form_signatures;
RequestType request_type;
std::string payload;
+ int num_attempts = 0;
};
+ScopedActiveAutofillExperiments::ScopedActiveAutofillExperiments() {
+ AutofillDownloadManager::ResetActiveExperiments();
+}
+
+ScopedActiveAutofillExperiments::~ScopedActiveAutofillExperiments() {
+ AutofillDownloadManager::ResetActiveExperiments();
+}
+
+std::vector<variations::VariationID>*
+ AutofillDownloadManager::active_experiments_ = nullptr;
+
AutofillDownloadManager::AutofillDownloadManager(AutofillDriver* driver,
Observer* observer,
const std::string& api_key)
@@ -450,6 +498,7 @@ AutofillDownloadManager::AutofillDownloadManager(AutofillDriver* driver,
observer_(observer),
api_key_(api_key),
autofill_server_url_(GetAutofillServerURL()),
+ throttle_reset_period_(GetThrottleResetPeriod()),
max_form_cache_size_(kAutofillDownloadManagerMaxFormCacheSize),
loader_backoff_(&kAutofillBackoffPolicy),
weak_factory_(this) {
@@ -472,6 +521,7 @@ bool AutofillDownloadManager::StartQueryRequest(
if (CountActiveFieldsInForms(forms) > kMaxFieldsPerQueryRequest)
return false;
+ // Encode the query for the requested forms.
AutofillQueryContents query;
FormRequestData request_data;
if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures,
@@ -479,6 +529,17 @@ bool AutofillDownloadManager::StartQueryRequest(
return false;
}
+ // The set of active autofill experiments is constant for the life of the
+ // process. We initialize and statically cache it on first use. Leaked on
+ // process termination.
+ if (active_experiments_ == nullptr)
+ InitActiveExperiments();
+
+ // Attach any active autofill experiments.
+ query.mutable_experiments()->Reserve(active_experiments_->size());
+ for (int id : *active_experiments_)
+ query.mutable_experiments()->Add(id);
+
// Get the query request payload.
std::string payload;
bool is_payload_serialized =
@@ -515,7 +576,18 @@ bool AutofillDownloadManager::StartUploadRequest(
const std::string& login_form_signature,
bool observed_submission,
PrefService* prefs) {
- if (!IsEnabled() || !IsUploadAllowed(form, prefs))
+ if (!IsEnabled())
+ return false;
+
+ bool can_throttle_upload =
+ CanThrottleUpload(form, throttle_reset_period_, prefs);
+ bool throttling_is_enabled =
+ base::FeatureList::IsEnabled(features::kAutofillUploadThrottling);
+ bool is_small_form = form.active_field_count() < 3;
+ bool allow_upload =
+ !(can_throttle_upload && (throttling_is_enabled || is_small_form));
+ AutofillMetrics::LogUploadEvent(form.submission_source(), allow_upload);
+ if (!allow_upload)
return false;
AutofillUploadContents upload;
@@ -525,6 +597,18 @@ bool AutofillDownloadManager::StartUploadRequest(
return false;
}
+ // If this upload was a candidate for throttling, tag it and make sure that
+ // any throttling sensitive features are enforced.
+ if (can_throttle_upload) {
+ upload.set_was_throttleable(true);
+
+ // Don't send randomized metadata.
+ upload.clear_randomized_form_metadata();
+ for (auto& f : *upload.mutable_field()) {
+ f.clear_randomized_field_metadata();
+ }
+ }
+
// Get the POST payload that contains upload data.
std::string payload;
bool is_payload = UseApi() ? GetUploadPayloadForApi(upload, &payload)
@@ -637,11 +721,11 @@ bool AutofillDownloadManager::StartRequest(FormRequestData request_data) {
resource_request->method = method;
// Add Chrome experiment state to the request headers.
- variations::AppendVariationHeadersUnknownSignedIn(
+ variations::AppendVariationsHeaderUnknownSignedIn(
request_url,
driver_->IsIncognito() ? variations::InIncognito::kYes
: variations::InIncognito::kNo,
- &resource_request->headers);
+ resource_request.get());
// Set headers specific to the API if using it.
if (UseApi())
@@ -649,10 +733,10 @@ bool AutofillDownloadManager::StartRequest(FormRequestData request_data) {
resource_request->headers.SetHeader(kGoogEncodeResponseIfExecutable,
"base64");
- // Put API key in request's header if there is.
- if (!api_key_.empty() &&
- variations::ShouldAppendVariationHeaders(request_url)) {
- // Make sure that we only send the API key to endpoints trusted by Chrome.
+ // Put API key in request's header if a key exists, and the endpoint is
+ // trusted by Google.
+ if (!api_key_.empty() && request_url.SchemeIs(url::kHttpsScheme) &&
+ google_util::IsGoogleAssociatedDomainUrl(request_url)) {
resource_request->headers.SetHeader(kGoogApiKey, api_key_);
}
@@ -738,6 +822,16 @@ std::string AutofillDownloadManager::GetCombinedSignature(
return signature;
}
+// static
+int AutofillDownloadManager::GetMaxServerAttempts() {
+ // This value is constant for the life of the browser, so we cache it
+ // statically on first use to avoid re-parsing the param on each retry
+ // opportunity. The range is forced to be within [1, 20].
+ static int max_attempts =
+ std::max(1, std::min(20, kAutofillMaxServerAttempts.Get()));
+ return max_attempts;
+}
+
void AutofillDownloadManager::OnSimpleLoaderComplete(
std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
FormRequestData request_data,
@@ -786,6 +880,10 @@ void AutofillDownloadManager::OnSimpleLoaderComplete(
if (response_code >= 400 && response_code <= 499)
return;
+ // If we've exhausted the maximum number of attempts, don't retry.
+ if (++request_data.num_attempts >= GetMaxServerAttempts())
+ return;
+
base::TimeDelta backoff = loader_backoff_.GetTimeUntilRelease();
LogExponentialBackoffDelay(request_data.request_type, backoff);
@@ -815,4 +913,25 @@ void AutofillDownloadManager::OnSimpleLoaderComplete(
observer_->OnUploadedPossibleFieldTypes();
}
+void AutofillDownloadManager::InitActiveExperiments() {
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ DCHECK(variations_http_header_provider != nullptr);
+
+ delete active_experiments_;
+ active_experiments_ = new std::vector<variations::VariationID>(
+ variations_http_header_provider->GetVariationsVector(
+ variations::GOOGLE_WEB_PROPERTIES_TRIGGER));
+ base::EraseIf(*active_experiments_, [](variations::VariationID id) {
+ return !IsAutofillExperimentId(id);
+ });
+ std::sort(active_experiments_->begin(), active_experiments_->end());
+}
+
+// static
+void AutofillDownloadManager::ResetActiveExperiments() {
+ delete active_experiments_;
+ active_experiments_ = nullptr;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager.h b/chromium/components/autofill/core/browser/autofill_download_manager.h
index ae7a8a988b2..f38c3ae8218 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_download_manager.h
@@ -19,6 +19,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_type.h"
+#include "components/variations/variations_http_header_provider.h"
#include "net/base/backoff_entry.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
@@ -30,6 +31,13 @@ namespace autofill {
class AutofillDriver;
class FormStructure;
+// A helper to make sure that tests which modify the set of active autofill
+// experiments do not interfere with one another.
+struct ScopedActiveAutofillExperiments {
+ ScopedActiveAutofillExperiments();
+ ~ScopedActiveAutofillExperiments();
+};
+
// Handles getting and updating Autofill heuristics.
class AutofillDownloadManager {
public:
@@ -108,9 +116,12 @@ class AutofillDownloadManager {
private:
friend class AutofillDownloadManagerTest;
+ friend struct ScopedActiveAutofillExperiments;
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, QueryAndUploadTest);
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, BackoffLogic_Upload);
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, BackoffLogic_Query);
+ FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, RetryLimit_Upload);
+ FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, RetryLimit_Query);
struct FormRequestData;
typedef std::list<std::pair<std::string, std::string> > QueryRequestCache;
@@ -151,12 +162,18 @@ class AutofillDownloadManager {
std::string GetCombinedSignature(
const std::vector<std::string>& forms_in_query) const;
+ // Returns the maximum number of attempts for a given autofill server request.
+ static int GetMaxServerAttempts();
+
void OnSimpleLoaderComplete(
std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
FormRequestData request_data,
base::TimeTicks request_start,
std::unique_ptr<std::string> response_body);
+ static void InitActiveExperiments();
+ static void ResetActiveExperiments();
+
// The AutofillDriver that this instance will use. Must not be null, and must
// outlive this instance.
AutofillDriver* const driver_; // WEAK
@@ -172,6 +189,12 @@ class AutofillDownloadManager {
// final path component for the request and the query params.
const GURL autofill_server_url_;
+ // The period after which the tracked set of uploads to throttle is reset.
+ const base::TimeDelta throttle_reset_period_;
+
+ // The set of active autofill server experiments.
+ static std::vector<variations::VariationID>* active_experiments_;
+
// Loaders used for the processing the requests. Invalidated after completion.
std::list<std::unique_ptr<network::SimpleURLLoader>> url_loaders_;
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
index 13d7f760d5c..9e23fc158a4 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -38,6 +38,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "components/prefs/pref_service.h"
+#include "components/variations/variations_http_header_provider.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
@@ -127,7 +128,7 @@ bool GetUploadRequestProtoFromRequest(
// The responses in test are out of order and verify: successful query request,
// successful upload request, failed upload request.
class AutofillDownloadManagerTest : public AutofillDownloadManager::Observer,
- public testing::Test {
+ public ::testing::Test {
public:
AutofillDownloadManagerTest()
: test_shared_loader_factory_(
@@ -186,6 +187,7 @@ class AutofillDownloadManagerTest : public AutofillDownloadManager::Observer,
ResponseData() : type_of_response(REQUEST_QUERY_FAILED), error(0) {}
};
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
base::test::ScopedTaskEnvironment task_environment_;
std::list<ResponseData> responses_;
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
@@ -766,6 +768,163 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Upload) {
EXPECT_EQ(1, buckets[0].count);
}
+TEST_F(AutofillDownloadManagerTest, RetryLimit_Query) {
+ FormData form;
+ FormFieldData field;
+ field.label = UTF8ToUTF16("address");
+ field.name = UTF8ToUTF16("address");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("address2");
+ field.name = UTF8ToUTF16("address2");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("city");
+ field.name = UTF8ToUTF16("city");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = base::string16();
+ field.name = UTF8ToUTF16("Submit");
+ field.form_control_type = "submit";
+ form.fields.push_back(field);
+
+ std::vector<std::unique_ptr<FormStructure>> form_structures;
+ form_structures.push_back(std::make_unique<FormStructure>(form));
+
+ // Request with id 0.
+ base::HistogramTester histogram;
+ EXPECT_TRUE(
+ download_manager_.StartQueryRequest(ToRawPointerVector(form_structures)));
+ histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+
+ const auto kTimeDeltaMargin = base::TimeDelta::FromMilliseconds(100);
+ const int max_attempts = download_manager_.GetMaxServerAttempts();
+ int attempt = 0;
+ while (true) {
+ auto* request = test_url_loader_factory_.GetPendingRequest(attempt);
+ ASSERT_TRUE(request != nullptr);
+
+ // Request error incurs a retry after 1 second.
+ test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
+ request,
+ network::CreateResourceResponseHead(net::HTTP_INTERNAL_SERVER_ERROR),
+ "<html></html>", network::URLLoaderCompletionStatus(net::OK));
+
+ EXPECT_EQ(1U, responses_.size());
+ const auto& response = responses_.front();
+ EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_QUERY_FAILED,
+ response.type_of_response);
+ EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, response.error);
+ responses_.pop_front();
+
+ if (++attempt >= max_attempts)
+ break;
+
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ download_manager_.loader_backoff_.GetTimeUntilRelease() +
+ kTimeDeltaMargin);
+ run_loop.Run();
+ }
+
+ // There should not be an additional retry.
+ EXPECT_EQ(attempt, max_attempts);
+ EXPECT_EQ(nullptr, test_url_loader_factory_.GetPendingRequest(attempt));
+ EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+
+ // Verify metrics.
+ histogram.ExpectBucketCount("Autofill.Query.HttpResponseOrErrorCode",
+ net::HTTP_INTERNAL_SERVER_ERROR, max_attempts);
+ auto buckets = histogram.GetAllSamples("Autofill.Query.FailingPayloadSize");
+ ASSERT_EQ(1U, buckets.size());
+ EXPECT_EQ(max_attempts, buckets[0].count);
+}
+
+TEST_F(AutofillDownloadManagerTest, RetryLimit_Upload) {
+ FormData form;
+ FormFieldData field;
+ field.label = UTF8ToUTF16("address");
+ field.name = UTF8ToUTF16("address");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("address2");
+ field.name = UTF8ToUTF16("address2");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("city");
+ field.name = UTF8ToUTF16("city");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = base::string16();
+ field.name = UTF8ToUTF16("Submit");
+ field.form_control_type = "submit";
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram;
+ const auto kTimeDeltaMargin = base::TimeDelta::FromMilliseconds(100);
+
+ auto form_structure = std::make_unique<FormStructure>(form);
+ form_structure->set_submission_source(SubmissionSource::FORM_SUBMISSION);
+
+ // Request with id 0.
+ EXPECT_TRUE(download_manager_.StartUploadRequest(
+ *form_structure, true, ServerFieldTypeSet(), std::string(), true,
+ pref_service_.get()));
+
+ const int max_attempts = download_manager_.GetMaxServerAttempts();
+ int attempt = 0;
+ while (true) {
+ auto* request = test_url_loader_factory_.GetPendingRequest(attempt);
+ ASSERT_TRUE(request != nullptr);
+
+ // Simulate a server failure.
+ test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
+ request,
+ network::CreateResourceResponseHead(net::HTTP_INTERNAL_SERVER_ERROR),
+ "", network::URLLoaderCompletionStatus(net::OK));
+
+ // Check that it was a failure.
+ ASSERT_EQ(1U, responses_.size());
+ const auto& response = responses_.front();
+ EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_UPLOAD_FAILED,
+ response.type_of_response);
+ EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, response.error);
+ responses_.pop_front();
+
+ if (++attempt >= max_attempts)
+ break;
+
+ // A retry should have been scheduled with wait time on the order of
+ // |delay|.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ download_manager_.loader_backoff_.GetTimeUntilRelease() +
+ kTimeDeltaMargin);
+ run_loop.Run();
+ }
+
+ // There should not be an additional retry.
+ EXPECT_EQ(attempt, max_attempts);
+ EXPECT_EQ(nullptr, test_url_loader_factory_.GetPendingRequest(attempt));
+ EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+
+ // Verify metrics.
+ histogram.ExpectBucketCount("Autofill.Upload.HttpResponseOrErrorCode",
+ net::HTTP_INTERNAL_SERVER_ERROR, max_attempts);
+ auto buckets = histogram.GetAllSamples("Autofill.Upload.FailingPayloadSize");
+ ASSERT_EQ(1U, buckets.size());
+ EXPECT_EQ(max_attempts, buckets[0].count);
+}
+
TEST_F(AutofillDownloadManagerTest, QueryTooManyFieldsTest) {
// Create a query that contains too many fields for the server.
std::vector<FormData> forms(21);
@@ -773,8 +932,8 @@ TEST_F(AutofillDownloadManagerTest, QueryTooManyFieldsTest) {
for (auto& form : forms) {
for (size_t i = 0; i < 5; ++i) {
FormFieldData field;
- field.label = base::IntToString16(i);
- field.name = base::IntToString16(i);
+ field.label = base::NumberToString16(i);
+ field.name = base::NumberToString16(i);
field.form_control_type = "text";
form.fields.push_back(field);
}
@@ -794,8 +953,8 @@ TEST_F(AutofillDownloadManagerTest, QueryNotTooManyFieldsTest) {
for (auto& form : forms) {
for (size_t i = 0; i < 4; ++i) {
FormFieldData field;
- field.label = base::IntToString16(i);
- field.name = base::IntToString16(i);
+ field.label = base::NumberToString16(i);
+ field.name = base::NumberToString16(i);
field.form_control_type = "text";
form.fields.push_back(field);
}
@@ -1024,6 +1183,11 @@ class AutofillServerCommunicationTest
void TearDown() override {
if (server_.Started())
ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete());
+
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ if (variations_http_header_provider != nullptr)
+ variations_http_header_provider->ResetForTesting();
}
// AutofillDownloadManager::Observer implementation.
@@ -1098,6 +1262,7 @@ class AutofillServerCommunicationTest
EXPECT_EQ(run_loop_, nullptr);
run_loop_ = std::make_unique<base::RunLoop>();
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
AutofillDownloadManager download_manager(driver_.get(), this);
bool succeeded =
download_manager.StartQueryRequest(ToRawPointerVector(form_structures));
@@ -1115,6 +1280,7 @@ class AutofillServerCommunicationTest
EXPECT_EQ(run_loop_, nullptr);
run_loop_ = std::make_unique<base::RunLoop>();
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
AutofillDownloadManager download_manager(driver_.get(), this);
bool succeeded = download_manager.StartUploadRequest(
form, form_was_autofilled, available_field_types, login_form_signature,
@@ -1188,11 +1354,11 @@ TEST_P(AutofillServerCommunicationTest, Upload) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillServerCommunicationTest,
- ::testing::Values(DISABLED,
- FINCHED_URL,
- COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillServerCommunicationTest,
+ ::testing::Values(DISABLED,
+ FINCHED_URL,
+ COMMAND_LINE_URL));
using AutofillQueryTest = AutofillServerCommunicationTest;
@@ -1221,8 +1387,8 @@ TEST_P(AutofillQueryTest, CacheableResponse) {
histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
}
- // Query again the next day. This should go to the cache, since the max-age
- // for the cached response is 2 days.
+ // Query again. This should go to the cache, since the max-age for the cached
+ // response is 2 days.
{
SCOPED_TRACE("Second Query");
base::HistogramTester histogram;
@@ -1236,6 +1402,76 @@ TEST_P(AutofillQueryTest, CacheableResponse) {
}
}
+TEST_P(AutofillQueryTest, SendsExperiment) {
+ FormFieldData field;
+ field.label = UTF8ToUTF16("First Name:");
+ field.name = UTF8ToUTF16("firstname");
+ field.form_control_type = "text";
+
+ FormData form;
+ form.fields.push_back(field);
+
+ std::vector<std::unique_ptr<FormStructure>> form_structures;
+ form_structures.push_back(std::make_unique<FormStructure>(form));
+
+ // Query for the form. This should go to the embedded server.
+ {
+ SCOPED_TRACE("First Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(1u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
+ }
+
+ // Add experiment/variation idd from the range reserved for autofill.
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ ASSERT_TRUE(variations_http_header_provider != nullptr);
+ variations_http_header_provider->ForceVariationIds(
+ {"t3314883", "t3312923", "t3314885"}, // first two valid, out-of-order
+ {});
+
+ // Query again. This should go to the embedded server since it's not the same
+ // as the previously cached query.
+ {
+ SCOPED_TRACE("Second Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ payloads_.clear();
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(1u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
+
+ ASSERT_EQ(1u, payloads_.size());
+ AutofillQueryContents query_contents;
+ ASSERT_TRUE(query_contents.ParseFromString(payloads_[0]));
+ ASSERT_EQ(2, query_contents.experiments_size());
+ EXPECT_EQ(3312923, query_contents.experiments(0));
+ EXPECT_EQ(3314883, query_contents.experiments(1));
+ }
+
+ // Query a third time (will experiments still enabled). This should go to the
+ // cache.
+ {
+ SCOPED_TRACE("Third Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(0u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_HIT, 1);
+ }
+}
+
TEST_P(AutofillQueryTest, ExpiredCacheInResponse) {
FormFieldData field;
field.label = UTF8ToUTF16("First Name:");
@@ -1468,9 +1704,9 @@ TEST_P(AutofillQueryTest, RichMetadata_Disabled) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server. We also excluded DISABLED, since
// these tests exercise "enabled" functionality.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillQueryTest,
- ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillQueryTest,
+ ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
using AutofillUploadTest = AutofillServerCommunicationTest;
@@ -1622,19 +1858,29 @@ TEST_P(AutofillUploadTest, Throttling) {
TEST_P(AutofillUploadTest, ThrottlingDisabled) {
ASSERT_NE(DISABLED, GetParam());
+ base::test::ScopedFeatureList local_feature;
+ local_feature.InitWithFeatures(
+ // Enabled.
+ {},
+ // Disabled
+ {features::kAutofillUploadThrottling,
+ features::kAutofillEnforceMinRequiredFieldsForUpload});
FormData form;
+ FormData small_form;
FormFieldData field;
field.label = UTF8ToUTF16("First Name:");
field.name = UTF8ToUTF16("firstname");
field.form_control_type = "text";
form.fields.push_back(field);
+ small_form.fields.push_back(field);
field.label = UTF8ToUTF16("Last Name:");
field.name = UTF8ToUTF16("lastname");
field.form_control_type = "text";
form.fields.push_back(field);
+ small_form.fields.push_back(field);
field.label = UTF8ToUTF16("Email:");
field.name = UTF8ToUTF16("email");
@@ -1643,15 +1889,16 @@ TEST_P(AutofillUploadTest, ThrottlingDisabled) {
AutofillDownloadManager download_manager(driver_.get(), this);
FormStructure form_structure(form);
-
- base::test::ScopedFeatureList local_feature;
- local_feature.InitAndDisableFeature(features::kAutofillUploadThrottling);
+ FormStructure small_form_structure(small_form);
for (int i = 0; i < 8; ++i) {
SCOPED_TRACE(base::StringPrintf("submission source = %d", i));
base::HistogramTester histogram_tester;
auto submission_source = static_cast<SubmissionSource>(i);
form_structure.set_submission_source(submission_source);
+ small_form_structure.set_submission_source(submission_source);
+
+ payloads_.clear();
// The first attempt should succeed.
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
@@ -1662,19 +1909,45 @@ TEST_P(AutofillUploadTest, ThrottlingDisabled) {
// The third attempt should also succeed
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
- // No throttling metrics should be logged.
- EXPECT_TRUE(histogram_tester.GetAllSamples("Autofill.UploadEvent").empty());
- EXPECT_TRUE(
- histogram_tester
- .GetAllSamples(AutofillMetrics::SubmissionSourceToUploadEventMetric(
- submission_source))
- .empty());
+ // The first small form attempt should succeed
+ EXPECT_TRUE(SendUploadRequest(small_form_structure, true, {}, "", true));
+
+ // The second small form attempt should be throttled, even if throttling
+ // is disabled.
+ EXPECT_FALSE(SendUploadRequest(small_form_structure, true, {}, "", true));
+
+ // All uploads were allowed..
+ histogram_tester.ExpectBucketCount("Autofill.UploadEvent", 1, 4);
+ histogram_tester.ExpectBucketCount(
+ AutofillMetrics::SubmissionSourceToUploadEventMetric(submission_source),
+ 1, 4);
+ histogram_tester.ExpectBucketCount(
+ AutofillMetrics::SubmissionSourceToUploadEventMetric(submission_source),
+ 0, 1);
+
+ // The last middle two uploads were marked as throttle-able.
+ ASSERT_EQ(4u, payloads_.size());
+ for (size_t i = 0; i < payloads_.size(); ++i) {
+ AutofillUploadContents upload_contents;
+ ASSERT_TRUE(upload_contents.ParseFromString(payloads_[i]));
+ EXPECT_EQ(upload_contents.was_throttleable(), (i == 1 || i == 2))
+ << "Wrong was_throttleable value for upload " << i;
+ EXPECT_FALSE(upload_contents.has_randomized_form_metadata());
+ for (const auto& field : upload_contents.field()) {
+ EXPECT_FALSE(field.has_randomized_field_metadata());
+ }
+ }
}
}
TEST_P(AutofillUploadTest, PeriodicReset) {
ASSERT_NE(DISABLED, GetParam());
+ base::test::ScopedFeatureList local_feature;
+ local_feature.InitAndEnableFeatureWithParameters(
+ features::kAutofillUploadThrottling,
+ {{switches::kAutofillUploadThrottlingPeriodInDays, "16"}});
+
FormData form;
FormFieldData field;
@@ -1708,11 +1981,11 @@ TEST_P(AutofillUploadTest, PeriodicReset) {
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
// Advance the clock, but not past the reset period. The pref won't reset,
- // so the upload should never be sent.
- test_clock.Advance(base::TimeDelta::FromDays(27));
+ // so the upload should not be sent.
+ test_clock.Advance(base::TimeDelta::FromDays(15));
EXPECT_FALSE(SendUploadRequest(form_structure, true, {}, "", true));
- // Advance the clock beyond the reset period. The pref should bfde reset and
+ // Advance the clock beyond the reset period. The pref should be reset and
// the upload should succeed.
test_clock.Advance(base::TimeDelta::FromDays(2)); // Total = 29
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
@@ -1779,8 +2052,8 @@ TEST_P(AutofillUploadTest, ResetOnClearUploadHisotry) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server. We also excluded DISABLED, since
// these tests exercise "enabled" functionality.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillUploadTest,
- ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillUploadTest,
+ ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_driver_factory.h b/chromium/components/autofill/core/browser/autofill_driver_factory.h
index cfb7d05b855..0c1a0a1062d 100644
--- a/chromium/components/autofill/core/browser/autofill_driver_factory.h
+++ b/chromium/components/autofill/core/browser/autofill_driver_factory.h
@@ -34,7 +34,7 @@ class AutofillDriverFactory {
// Handles hiding of the corresponding tab.
void TabHidden();
- AutofillClient* client() { return client_; };
+ AutofillClient* client() { return client_; }
protected:
// The API manipulating the drivers map is protected to guarantee subclasses
diff --git a/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc b/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
index 0df561935d5..7e11d2a33f8 100644
--- a/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill/core/browser/test_autofill_client.h"
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.cc b/chromium/components/autofill/core/browser/autofill_experiments.cc
index 13e96ebe22c..ffc1f9c2c89 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.cc
+++ b/chromium/components/autofill/core/browser/autofill_experiments.cc
@@ -20,6 +20,7 @@
#include "components/strings/grit/components_strings.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_utils.h"
+#include "components/sync/driver/sync_user_settings.h"
#include "components/variations/variations_associated_data.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
@@ -70,7 +71,7 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
// Users who have enabled a passphrase have chosen to not make their sync
// information accessible to Google. Since upload makes credit card data
// available to other Google systems, disable it for passphrase users.
- if (sync_service->IsUsingSecondaryPassphrase())
+ if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase())
return false;
// Don't offer upload for users that are only syncing locally, since they
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate.cc b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
index 2f40e6d1911..0024f2d615f 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
@@ -90,7 +90,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
Suggestion scan_credit_card(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD));
scan_credit_card.frontend_id = POPUP_ITEM_ID_SCAN_CREDIT_CARD;
- scan_credit_card.icon = base::ASCIIToUTF16("scanCreditCardIcon");
+ scan_credit_card.icon = "scanCreditCardIcon";
suggestions.push_back(scan_credit_card);
}
@@ -108,7 +108,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
suggestions.emplace_back(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS));
suggestions.back().frontend_id = POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS;
- suggestions.back().icon = base::ASCIIToUTF16("google");
+ suggestions.back().icon = "google";
}
if (has_autofill_suggestions_)
@@ -358,12 +358,12 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
// So Google Pay Icon is just attached to an existing menu item.
if (is_all_server_suggestions) {
#if defined(OS_ANDROID) || defined(OS_IOS)
- suggestions->back().icon = base::ASCIIToUTF16("googlePay");
+ suggestions->back().icon = "googlePay";
#else
- suggestions->back().icon = base::ASCIIToUTF16(
+ suggestions->back().icon =
ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled()
? "googlePayDark"
- : "googlePay");
+ : "googlePay";
#endif
}
@@ -373,7 +373,7 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
features::kAutofillDownstreamUseGooglePayBrandingOniOS) &&
is_all_server_suggestions) {
Suggestion googlepay_icon;
- googlepay_icon.icon = base::ASCIIToUTF16("googlePay");
+ googlepay_icon.icon = "googlePay";
googlepay_icon.frontend_id = POPUP_ITEM_ID_GOOGLE_PAY_BRANDING;
suggestions->insert(suggestions->begin(), googlepay_icon);
}
@@ -381,10 +381,10 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
#if defined(OS_ANDROID)
if (IsKeyboardAccessoryEnabled()) {
- suggestions->back().icon = base::ASCIIToUTF16("settings");
+ suggestions->back().icon = "settings";
if (IsHintEnabledInKeyboardAccessory() && !query_field_.is_autofilled) {
Suggestion create_icon;
- create_icon.icon = base::ASCIIToUTF16("create");
+ create_icon.icon = "create";
create_icon.frontend_id = POPUP_ITEM_ID_CREATE_HINT;
suggestions->push_back(create_icon);
}
@@ -419,8 +419,12 @@ void AutofillExternalDelegate::InsertDataListValues(
suggestions->insert(suggestions->begin(), data_list_values_.size(),
Suggestion());
for (size_t i = 0; i < data_list_values_.size(); i++) {
+ // A suggestion's label has one line of disambiguating information to show
+ // to the user. However, when the two-line suggestion display experiment is
+ // enabled on desktop, label is replaced by additional label.
(*suggestions)[i].value = data_list_values_[i];
(*suggestions)[i].label = data_list_labels_[i];
+ (*suggestions)[i].additional_label = data_list_labels_[i];
(*suggestions)[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY;
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 32c3dd956b0..3e7d77e2a14 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -408,15 +408,16 @@ TEST_F(AutofillExternalDelegateUnitTest, UpdateDataListWhileShowingPopup) {
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
IssueOnQuery(kQueryId);
- std::vector<base::string16> data_list_items;
- data_list_items.push_back(base::ASCIIToUTF16("Rick"));
- data_list_items.push_back(base::ASCIIToUTF16("Deckard"));
+ std::vector<base::string16> data_list_values{base::ASCIIToUTF16("Rick"),
+ base::ASCIIToUTF16("Beyonce")};
+ std::vector<base::string16> data_list_labels{base::ASCIIToUTF16("Deckard"),
+ base::ASCIIToUTF16("Knowles")};
EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
- data_list_items, data_list_items));
+ data_list_values, data_list_labels));
- external_delegate_->SetCurrentDataListValues(data_list_items,
- data_list_items);
+ external_delegate_->SetCurrentDataListValues(data_list_values,
+ data_list_labels);
// The enums must be cast to ints to prevent compile errors on linux_rel.
auto element_ids = testing::ElementsAre(
@@ -434,6 +435,8 @@ TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
std::vector<Suggestion> autofill_item;
autofill_item.push_back(Suggestion());
autofill_item[0].value = ASCIIToUTF16("Rick");
+ autofill_item[0].label = ASCIIToUTF16("Deckard");
+ autofill_item[0].additional_label = ASCIIToUTF16("Deckard");
autofill_item[0].frontend_id = kAutofillProfileId;
external_delegate_->OnSuggestionsReturned(
kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
@@ -444,15 +447,16 @@ TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutocompleteDatalistValues) {
IssueOnQuery(kQueryId);
- std::vector<base::string16> data_list_items;
- data_list_items.push_back(base::ASCIIToUTF16("Rick"));
- data_list_items.push_back(base::ASCIIToUTF16("Deckard"));
+ std::vector<base::string16> data_list_values{base::ASCIIToUTF16("Rick"),
+ base::ASCIIToUTF16("Beyonce")};
+ std::vector<base::string16> data_list_labels{base::ASCIIToUTF16("Deckard"),
+ base::ASCIIToUTF16("Knowles")};
EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
- data_list_items, data_list_items));
+ data_list_values, data_list_labels));
- external_delegate_->SetCurrentDataListValues(data_list_items,
- data_list_items);
+ external_delegate_->SetCurrentDataListValues(data_list_values,
+ data_list_labels);
// The enums must be cast to ints to prevent compile errors on linux_rel.
auto element_ids = testing::ElementsAre(
@@ -753,8 +757,7 @@ TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) {
IssueOnQuery(kQueryId);
- auto element_icons = testing::ElementsAre(
- base::string16(), base::ASCIIToUTF16("googlePay"));
+ auto element_icons = testing::ElementsAre(std::string(), "googlePay");
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -777,8 +780,7 @@ TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIconOniOS) {
IssueOnQuery(kQueryId);
auto element_icons =
- testing::ElementsAre(base::ASCIIToUTF16("googlePay"), base::string16(),
- base::ASCIIToUTF16("googlePay"));
+ testing::ElementsAre("googlePay", std::string(), "googlePay");
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -801,8 +803,8 @@ TEST_F(AutofillExternalDelegateUnitTest,
IssueOnQuery(kQueryId);
auto element_icons = testing::ElementsAre(
- base::string16(),
- base::string16() /* Autofill setting item does not have icon. */);
+ std::string(),
+ std::string() /* Autofill setting item does not have icon. */);
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -822,8 +824,8 @@ TEST_F(AutofillExternalDelegateUnitTest,
IssueOnQuery(kQueryId);
auto element_icons = testing::ElementsAre(
- base::string16(),
- base::string16() /* Autofill setting item does not have icon. */);
+ std::string(),
+ std::string() /* Autofill setting item does not have icon. */);
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
diff --git a/chromium/components/autofill/core/browser/autofill_field.cc b/chromium/components/autofill/core/browser/autofill_field.cc
index e0eb40ca514..e60544c60ab 100644
--- a/chromium/components/autofill/core/browser/autofill_field.cc
+++ b/chromium/components/autofill/core/browser/autofill_field.cc
@@ -6,8 +6,6 @@
#include <stdint.h>
-#include <utility>
-
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "components/autofill/core/browser/field_types.h"
@@ -73,18 +71,17 @@ void AutofillField::set_server_type(ServerFieldType type) {
}
void AutofillField::add_possible_types_validities(
- const std::map<ServerFieldType, AutofillProfile::ValidityState>&
- possible_types_validities) {
+ const ServerFieldTypeValidityStateMap& possible_types_validities) {
for (const auto& possible_type_validity : possible_types_validities) {
possible_types_validities_[possible_type_validity.first].push_back(
possible_type_validity.second);
}
}
-std::vector<AutofillProfile::ValidityState>
+std::vector<AutofillDataModel::ValidityState>
AutofillField::get_validities_for_possible_type(ServerFieldType type) {
if (possible_types_validities_.find(type) == possible_types_validities_.end())
- return {AutofillProfile::UNVALIDATED};
+ return {AutofillDataModel::UNVALIDATED};
return possible_types_validities_[type];
}
@@ -172,7 +169,7 @@ FieldSignature AutofillField::GetFieldSignature() const {
}
std::string AutofillField::FieldSignatureAsStr() const {
- return base::UintToString(GetFieldSignature());
+ return base::NumberToString(GetFieldSignature());
}
bool AutofillField::IsFieldFillable() const {
@@ -187,7 +184,7 @@ void AutofillField::NormalizePossibleTypesValidities() {
for (const auto& possible_type : possible_types_) {
if (possible_types_validities_[possible_type].empty()) {
possible_types_validities_[possible_type].push_back(
- AutofillProfile::UNVALIDATED);
+ AutofillDataModel::UNVALIDATED);
}
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_field.h b/chromium/components/autofill/core/browser/autofill_field.h
index 8b565fb0b9d..b7f9069b16f 100644
--- a/chromium/components/autofill/core/browser/autofill_field.h
+++ b/chromium/components/autofill/core/browser/autofill_field.h
@@ -7,7 +7,10 @@
#include <stddef.h>
+#include <map>
#include <string>
+#include <utility>
+#include <vector>
#include "base/macros.h"
#include "base/optional.h"
@@ -22,9 +25,12 @@
namespace autofill {
-typedef std::map<ServerFieldType, std::vector<AutofillProfile::ValidityState>>
+typedef std::map<ServerFieldType, std::vector<AutofillDataModel::ValidityState>>
ServerFieldTypeValidityStatesMap;
+typedef std::map<ServerFieldType, AutofillDataModel::ValidityState>
+ ServerFieldTypeValidityStateMap;
+
class AutofillField : public FormFieldData {
public:
enum PhonePart {
@@ -60,8 +66,7 @@ class AutofillField : public FormFieldData {
void set_heuristic_type(ServerFieldType type);
void set_server_type(ServerFieldType type);
void add_possible_types_validities(
- const std::map<ServerFieldType, AutofillProfile::ValidityState>&
- possible_types_validities);
+ const ServerFieldTypeValidityStateMap& possible_types_validities);
void set_server_predictions(
const std::vector<AutofillQueryResponseContents::Field::FieldPrediction>
predictions) {
@@ -74,8 +79,8 @@ class AutofillField : public FormFieldData {
const ServerFieldTypeValidityStatesMap& possible_types_validities) {
possible_types_validities_ = possible_types_validities;
}
- std::vector<AutofillProfile::ValidityState> get_validities_for_possible_type(
- ServerFieldType);
+ std::vector<AutofillDataModel::ValidityState>
+ get_validities_for_possible_type(ServerFieldType);
void SetHtmlType(HtmlFieldType type, HtmlFieldMode mode);
void set_previously_autofilled(bool previously_autofilled) {
diff --git a/chromium/components/autofill/core/browser/autofill_manager.cc b/chromium/components/autofill/core/browser/autofill_manager.cc
index 95dcd22455c..dcc247b97d0 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager.cc
@@ -51,6 +51,9 @@
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_data_importer.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/phone_number.h"
@@ -395,10 +398,11 @@ void AutofillManager::OnFormSubmittedImpl(const FormData& form,
form_for_autocomplete, client_->IsAutocompleteEnabled());
if (IsProfileAutofillEnabled()) {
- address_form_event_logger_->OnWillSubmitForm(sync_state_);
+ address_form_event_logger_->OnWillSubmitForm(sync_state_, *submitted_form);
}
if (IsCreditCardAutofillEnabled()) {
- credit_card_form_event_logger_->OnWillSubmitForm(sync_state_);
+ credit_card_form_event_logger_->OnWillSubmitForm(sync_state_,
+ *submitted_form);
}
submitted_form->set_submission_source(source);
@@ -414,19 +418,13 @@ void AutofillManager::OnFormSubmittedImpl(const FormData& form,
submitted_form->set_submission_source(source);
- CreditCard credit_card =
- client_->GetFormDataImporter()->ExtractCreditCardFromForm(
- *submitted_form);
- AutofillMetrics::CardNumberStatus card_number_status =
- GetCardNumberStatus(credit_card);
-
if (IsProfileAutofillEnabled()) {
- address_form_event_logger_->OnFormSubmitted(
- /*force_logging=*/false, card_number_status, sync_state_);
+ address_form_event_logger_->OnFormSubmitted(/*force_logging=*/false,
+ sync_state_, *submitted_form);
}
if (IsCreditCardAutofillEnabled()) {
credit_card_form_event_logger_->OnFormSubmitted(
- enable_ablation_logging_, card_number_status, sync_state_);
+ enable_ablation_logging_, sync_state_, *submitted_form);
}
if (!submitted_form->IsAutofillable())
@@ -711,7 +709,7 @@ void AutofillManager::FillOrPreviewCreditCardForm(
masked_card_, AutofillClient::UNMASK_FOR_AUTOFILL,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr());
credit_card_form_event_logger_->OnDidSelectMaskedServerCardSuggestion(
- form_structure->form_parsed_timestamp(), sync_state_);
+ *form_structure, sync_state_);
return;
}
credit_card_form_event_logger_->OnDidFillSuggestion(
@@ -1228,12 +1226,11 @@ void AutofillManager::Reset() {
form_interactions_ukm_logger_.reset(
new AutofillMetrics::FormInteractionsUkmLogger(
client_->GetUkmRecorder(), client_->GetUkmSourceId()));
- address_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
- /*is_for_credit_card=*/false, driver()->IsInMainFrame(),
- form_interactions_ukm_logger_.get()));
- credit_card_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
- /*is_for_credit_card=*/true, driver()->IsInMainFrame(),
- form_interactions_ukm_logger_.get()));
+ address_form_event_logger_.reset(new AddressFormEventLogger(
+ driver()->IsInMainFrame(), form_interactions_ukm_logger_.get()));
+ credit_card_form_event_logger_.reset(new CreditCardFormEventLogger(
+ driver()->IsInMainFrame(), form_interactions_ukm_logger_.get(),
+ personal_data_, client_));
#if defined(OS_ANDROID) || defined(OS_IOS)
autofill_assistant_.Reset();
#endif
@@ -1270,16 +1267,15 @@ AutofillManager::AutofillManager(
std::make_unique<AutofillMetrics::FormInteractionsUkmLogger>(
client->GetUkmRecorder(),
client->GetUkmSourceId())),
- address_form_event_logger_(
- std::make_unique<AutofillMetrics::FormEventLogger>(
- /*is_for_credit_card=*/false,
- driver->IsInMainFrame(),
- form_interactions_ukm_logger_.get())),
+ address_form_event_logger_(std::make_unique<AddressFormEventLogger>(
+ driver->IsInMainFrame(),
+ form_interactions_ukm_logger_.get())),
credit_card_form_event_logger_(
- std::make_unique<AutofillMetrics::FormEventLogger>(
- /*is_for_credit_card=*/true,
+ std::make_unique<CreditCardFormEventLogger>(
driver->IsInMainFrame(),
- form_interactions_ukm_logger_.get())),
+ form_interactions_ukm_logger_.get(),
+ personal_data_,
+ client_)),
#if defined(OS_ANDROID) || defined(OS_IOS)
autofill_assistant_(this),
#endif
@@ -1661,10 +1657,10 @@ void AutofillManager::OnFormsParsed(
}
}
if (card_form) {
- credit_card_form_event_logger_->OnDidParseForm();
+ credit_card_form_event_logger_->OnDidParseForm(*form_structure);
}
if (address_form) {
- address_form_event_logger_->OnDidParseForm();
+ address_form_event_logger_->OnDidParseForm(*form_structure);
}
// If a form with the same name was previously filled, and there has not
@@ -1824,8 +1820,7 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
for (const AutofillProfile& profile : profiles) {
- std::map<ServerFieldType, AutofillProfile::ValidityState>
- matching_types_validities;
+ ServerFieldTypeValidityStateMap matching_types_validities;
profile.GetMatchingTypesAndValidities(value, app_locale, &matching_types,
&matching_types_validities);
field->add_possible_types_validities(matching_types_validities);
@@ -1838,9 +1833,8 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
if (matching_types.empty()) {
matching_types.insert(UNKNOWN_TYPE);
- std::map<ServerFieldType, AutofillProfile::ValidityState>
- matching_types_validities;
- matching_types_validities[UNKNOWN_TYPE] = AutofillProfile::UNVALIDATED;
+ ServerFieldTypeValidityStateMap matching_types_validities;
+ matching_types_validities[UNKNOWN_TYPE] = AutofillDataModel::UNVALIDATED;
field->add_possible_types_validities(matching_types_validities);
}
@@ -2029,7 +2023,8 @@ bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
if (itr == filling_contexts_map_.end())
return false;
- address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_);
+ address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_,
+ form_structure);
FillingContext* filling_context = itr->second.get();
base::TimeTicks now = base::TimeTicks::Now();
@@ -2037,7 +2032,8 @@ bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
if (filling_context->attempted_refill &&
delta.InMilliseconds() < kLimitBeforeRefillMs) {
- address_form_event_logger_->OnSubsequentRefillAttempt(sync_state_);
+ address_form_event_logger_->OnSubsequentRefillAttempt(sync_state_,
+ form_structure);
}
return !filling_context->attempted_refill &&
@@ -2051,7 +2047,7 @@ void AutofillManager::TriggerRefill(const FormData& form) {
DCHECK(form_structure);
- address_form_event_logger_->OnDidRefill(sync_state_);
+ address_form_event_logger_->OnDidRefill(sync_state_, *form_structure);
auto itr =
filling_contexts_map_.find(form_structure->GetIdentifierForRefill());
@@ -2117,10 +2113,10 @@ void AutofillManager::GetAvailableSuggestions(
if (context->focused_field->Type().group() == CREDIT_CARD) {
context->is_filling_credit_card = true;
credit_card_form_event_logger_->OnDidInteractWithAutofillableForm(
- context->form_structure->form_signature(), sync_state_);
+ *(context->form_structure), sync_state_);
} else {
address_form_event_logger_->OnDidInteractWithAutofillableForm(
- context->form_structure->form_signature(), sync_state_);
+ *(context->form_structure), sync_state_);
}
}
@@ -2179,19 +2175,4 @@ void AutofillManager::GetAvailableSuggestions(
}
}
-AutofillMetrics::CardNumberStatus AutofillManager::GetCardNumberStatus(
- CreditCard& credit_card) {
- base::string16 number = credit_card.number();
- if (number.empty())
- return AutofillMetrics::EMPTY_CARD;
- else if (!HasCorrectLength(number))
- return AutofillMetrics::WRONG_SIZE_CARD;
- else if (!PassesLuhnCheck(number))
- return AutofillMetrics::FAIL_LUHN_CHECK_CARD;
- else if (personal_data_->IsKnownCard(credit_card))
- return AutofillMetrics::KNOWN_CARD;
- else
- return AutofillMetrics::UNKNOWN_CARD;
-}
-
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_manager.h b/chromium/components/autofill/core/browser/autofill_manager.h
index 588f1ee0693..e9871cd2c89 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_manager.h
@@ -29,6 +29,8 @@
#include "components/autofill/core/browser/card_unmask_delegate.h"
#include "components/autofill/core/browser/field_filler.h"
#include "components/autofill/core/browser/form_types.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
#include "components/autofill/core/browser/payments/full_card_request.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/popup_types.h"
@@ -433,9 +435,10 @@ class AutofillManager : public AutofillHandler,
// |FieldTypeGroup|.
bool FormHasAddressField(const FormData& form) WARN_UNUSED_RESULT;
- // Returns a list of values from the stored profiles that match |type| and the
- // value of |field| and returns the labels of the matching profiles. |labels|
- // is filled with the Profile label.
+ // Returns Suggestions corresponding to both the |autofill_field| type and
+ // stored profiles whose values match the contents of |field|. |form| stores
+ // data about the form with which the user is interacting, e.g. the number and
+ // types of form fields.
std::vector<Suggestion> GetProfileSuggestions(
const FormStructure& form,
const FormFieldData& field,
@@ -498,9 +501,6 @@ class AutofillManager : public AutofillHandler,
bool should_notify,
const base::string16& cvc);
- AutofillMetrics::CardNumberStatus GetCardNumberStatus(
- CreditCard& credit_card);
-
// Whether there should be an attemps to refill the form. Returns true if all
// the following are satisfied:
// There have been no refill on that page yet.
@@ -550,9 +550,8 @@ class AutofillManager : public AutofillHandler,
form_interactions_ukm_logger_;
// Utilities for logging form events.
- std::unique_ptr<AutofillMetrics::FormEventLogger> address_form_event_logger_;
- std::unique_ptr<AutofillMetrics::FormEventLogger>
- credit_card_form_event_logger_;
+ std::unique_ptr<AddressFormEventLogger> address_form_event_logger_;
+ std::unique_ptr<CreditCardFormEventLogger> credit_card_form_event_logger_;
// Have we logged whether Autofill is enabled for this page load?
bool has_logged_autofill_enabled_ = false;
diff --git a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
index 68c0d62c8da..20c8ed86951 100644
--- a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <memory>
+#include <tuple>
#include <utility>
#include <vector>
@@ -33,6 +34,7 @@
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
@@ -295,7 +297,6 @@ class AutofillManagerTest : public testing::Test {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
personal_data_.SetPrefService(autofill_client_.GetPrefs());
@@ -1609,9 +1610,9 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
FormSubmitted(form);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
+ 1);
}
// Test that we return normal autofill suggestions when trying to autofill
@@ -4422,8 +4423,8 @@ class ProfileMatchingTypesTest
: public AutofillManagerTest,
public ::testing::WithParamInterface<
std::tuple<ProfileMatchingTypesTestCase,
- int, // AutofillProfile::ValidityState
- bool>> {}; // AutofillProfile::ValidationSource
+ int, // AutofillDataModel::ValidityState
+ bool>> {}; // AutofillDataModel::ValidationSource
const ProfileMatchingTypesTestCase kProfileMatchingTypesTestCases[] = {
// Profile fields matches.
@@ -4517,9 +4518,9 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
// Unpack the test paramters
const auto& test_case = std::get<0>(GetParam());
auto validity_state =
- static_cast<AutofillProfile::ValidityState>(std::get<1>(GetParam()));
+ static_cast<AutofillDataModel::ValidityState>(std::get<1>(GetParam()));
const auto& validation_source =
- static_cast<AutofillProfile::ValidationSource>(std::get<2>(GetParam()));
+ static_cast<AutofillDataModel::ValidationSource>(std::get<2>(GetParam()));
SCOPED_TRACE(base::StringPrintf(
"Test: input_value='%s', field_type=%s, validity_state=%d, "
@@ -4528,8 +4529,8 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
AutofillType(test_case.field_type).ToString().c_str(), validity_state,
validation_source));
- ASSERT_LE(AutofillProfile::UNVALIDATED, validity_state);
- ASSERT_LE(validity_state, AutofillProfile::UNSUPPORTED);
+ ASSERT_LE(AutofillDataModel::UNVALIDATED, validity_state);
+ ASSERT_LE(validity_state, AutofillDataModel::UNSUPPORTED);
// Set up the test profiles.
std::vector<AutofillProfile> profiles;
@@ -4556,11 +4557,11 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
for (auto& profile : profiles) {
if (test_case.field_type == UNKNOWN_TYPE) {
// An UNKNOWN type is always UNVALIDATED
- validity_state = AutofillProfile::UNVALIDATED;
+ validity_state = AutofillDataModel::UNVALIDATED;
} else if (profile.IsAnInvalidPhoneNumber(test_case.field_type)) {
// a phone field is a compound field, an invalid part would make it
// invalid.
- validity_state = AutofillProfile::INVALID;
+ validity_state = AutofillDataModel::INVALID;
}
profile.SetValidityState(test_case.field_type, validity_state,
validation_source);
@@ -4605,19 +4606,19 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
EXPECT_NE(possible_types_validities.end(),
possible_types_validities.find(test_case.field_type));
EXPECT_EQ(possible_types_validities[test_case.field_type][0],
- (validation_source == AutofillProfile::SERVER)
+ (validation_source == AutofillDataModel::SERVER)
? validity_state
- : AutofillProfile::UNVALIDATED);
+ : AutofillDataModel::UNVALIDATED);
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillManagerTest,
ProfileMatchingTypesTest,
testing::Combine(
testing::ValuesIn(kProfileMatchingTypesTestCases),
- testing::Range(static_cast<int>(AutofillProfile::UNVALIDATED),
- static_cast<int>(AutofillProfile::UNSUPPORTED) + 1),
+ testing::Range(static_cast<int>(AutofillDataModel::UNVALIDATED),
+ static_cast<int>(AutofillDataModel::UNSUPPORTED) + 1),
testing::Bool()));
// Tests that DeterminePossibleFieldTypesForUpload is called when a form is
@@ -4683,8 +4684,8 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
"", "Memphis", "Tennessee", "38116", "US",
"(234) 567-8901");
profile.set_guid("00000000-0000-0000-0000-000000000001");
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
profiles.push_back(profile);
}
{
@@ -4693,8 +4694,8 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
"1331 W Georgia", "", "Vancouver", "Tennessee",
"V4D 4S4", "CA", "(778) 567-8901");
profile.set_guid("00000000-0000-0000-0000-000000000002");
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
profiles.push_back(profile);
}
@@ -4702,7 +4703,7 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
typedef struct {
std::string input_value;
ServerFieldType field_type;
- std::vector<AutofillProfile::ValidityState> expected_validity_states;
+ std::vector<AutofillDataModel::ValidityState> expected_validity_states;
} TestFieldData;
std::vector<TestFieldData> test_cases[3];
@@ -4711,16 +4712,18 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
// possible_field_types would only include the type ADDRESS_HOME_STATE, and
// the corresponding validity of that type would include both VALID and
// INVALID.
- test_cases[0].push_back({"Tennessee",
- ADDRESS_HOME_STATE,
- {AutofillProfile::VALID, AutofillProfile::INVALID}});
+ test_cases[0].push_back(
+ {"Tennessee",
+ ADDRESS_HOME_STATE,
+ {AutofillDataModel::VALID, AutofillDataModel::INVALID}});
// Alice appears only in the second profile as a NAME_FIRST, and it's
// UNVALIDATED.
test_cases[1].push_back(
- {"Alice", NAME_FIRST, {AutofillProfile::UNVALIDATED}});
+ {"Alice", NAME_FIRST, {AutofillDataModel::UNVALIDATED}});
// An UNKNOWN type is always UNVALIDATED.
- test_cases[2].push_back(
- {"What a beautiful day!", UNKNOWN_TYPE, {AutofillProfile::UNVALIDATED}});
+ test_cases[2].push_back({"What a beautiful day!",
+ UNKNOWN_TYPE,
+ {AutofillDataModel::UNVALIDATED}});
for (const std::vector<TestFieldData>& test_fields : test_cases) {
FormData form;
@@ -5392,9 +5395,8 @@ TEST_F(AutofillManagerTest, CreditCardDisabledDoesNotSuggest) {
// Verify that typing "gmail" will match "theking@gmail.com" and
// "buddy@gmail.com" when substring matching is enabled.
TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5414,9 +5416,8 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
// Verify that typing "apple" will match "123 Apple St." when substring matching
// is enabled.
TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens_CaseIgnored) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5435,9 +5436,8 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens_CaseIgnored) {
// Verify that typing "mail" will not match any of the "@gmail.com" email
// addresses when substring matching is enabled.
TEST_F(AutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5454,9 +5454,8 @@ TEST_F(AutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
// Verify that typing "pres" will match "Elvis Presley" when substring matching
// is enabled.
TEST_F(AutofillManagerTest, DisplayCreditCardSuggestionsWithMatchingTokens) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5485,9 +5484,8 @@ TEST_F(AutofillManagerTest, DisplayCreditCardSuggestionsWithMatchingTokens) {
// Verify that typing "lvis" will not match any of the credit card name when
// substring matching is enabled.
TEST_F(AutofillManagerTest, NoCreditCardSuggestionsForNonPrefixTokenMatch) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5695,9 +5693,8 @@ TEST_F(AutofillManagerTest, ShouldShowCreditCardSigninPromo_AddressField) {
// substring matched.
TEST_F(AutofillManagerTest,
DisplaySuggestionsWithPrefixesPrecedeSubstringMatched) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -6233,12 +6230,10 @@ TEST_F(AutofillManagerTest, DidShowSuggestions_LogAutofillAddressShownMetric) {
histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Address",
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE,
1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// No Autocomplete or credit cards logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6264,12 +6259,10 @@ TEST_F(AutofillManagerTest,
histogram_tester.ExpectBucketCount("Autofill.UserHappiness.CreditCard",
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE,
1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// No Autocomplete or address logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6284,9 +6277,8 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, form.fields[0]);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
// No Autocomplete or credit cards logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6303,9 +6295,8 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, form.fields[0]);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
// No Autocomplete or address logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6523,6 +6514,6 @@ TEST_P(OnFocusOnFormFieldTest, CreditCardSuggestions_Ablation) {
CheckNoSuggestionsAvailableOnFieldFocus();
}
-INSTANTIATE_TEST_CASE_P(All, OnFocusOnFormFieldTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(All, OnFocusOnFormFieldTest, testing::Bool());
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
index caf34836790..bd1bbb316a7 100644
--- a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -304,6 +304,8 @@ TEST_P(AutofillMergeTest, DataDrivenMergeProfiles) {
kIsExpectedToPass);
}
-INSTANTIATE_TEST_CASE_P(, AutofillMergeTest, testing::ValuesIn(GetTestFiles()));
+INSTANTIATE_TEST_SUITE_P(,
+ AutofillMergeTest,
+ testing::ValuesIn(GetTestFiles()));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_metadata.h b/chromium/components/autofill/core/browser/autofill_metadata.h
index 6a70a06bb49..3fbc2e12a26 100644
--- a/chromium/components/autofill/core/browser/autofill_metadata.h
+++ b/chromium/components/autofill/core/browser/autofill_metadata.h
@@ -15,8 +15,8 @@ namespace autofill {
// abstract the data from the metadata.
struct AutofillMetadata {
public:
- AutofillMetadata(){};
- ~AutofillMetadata(){};
+ AutofillMetadata() {}
+ ~AutofillMetadata() {}
bool operator==(const AutofillMetadata&) const;
bool operator!=(const AutofillMetadata&) const;
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.cc b/chromium/components/autofill/core/browser/autofill_metrics.cc
index 6e405659280..b88ad9a0269 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics.cc
@@ -23,12 +23,16 @@
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/submission_source.h"
+#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
namespace autofill {
namespace {
+// Exponential bucket spacing for UKM event data.
+const double kAutofillEventDataBucketSpacing = 2.0;
+
// Note: if adding an enum value here, update the corresponding description for
// AutofillTypeQualityByFieldType in histograms.xml.
enum FieldTypeGroupForMetrics {
@@ -264,21 +268,6 @@ const char* GetQualityMetricTypeSuffix(
}
}
-const char* GetSyncStateSuffix(AutofillSyncSigninState sync_state) {
- switch (sync_state) {
- case AutofillSyncSigninState::kSignedOut:
- return ".SignedOut";
- case AutofillSyncSigninState::kSignedIn:
- return ".SignedIn";
- case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
- return ".SignedInAndWalletSyncTransportEnabled";
- case AutofillSyncSigninState::kSignedInAndSyncFeature:
- return ".SignedInAndSyncFeature";
- case AutofillSyncSigninState::kNumSyncStates:
- return ".Unknown";
- }
-}
-
// Given a set of |possible_types| for a field, select the best type to use as
// the "actual" field type when calculating metrics. If the |predicted_type| is
// among the |possible_types] then use that as the best type (i.e., the
@@ -568,30 +557,6 @@ void LogPredictionQualityMetrics(
is_empty, is_ambiguous);
}
-AutofillMetrics::FormEvent GetCardNumberStatusFormEvent(
- const AutofillMetrics::CardNumberStatus card_number_status) {
- switch (card_number_status) {
- case AutofillMetrics::EMPTY_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
- case AutofillMetrics::WRONG_SIZE_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD;
- case AutofillMetrics::FAIL_LUHN_CHECK_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD;
- case AutofillMetrics::KNOWN_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD;
- case AutofillMetrics::UNKNOWN_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD;
- }
- NOTREACHED();
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
-}
-
} // namespace
const int kMaxBucketsCount = 50;
@@ -614,6 +579,11 @@ void AutofillMetrics::LogSubmittedServerCardExpirationStatusMetric(
}
// static
+void AutofillMetrics::LogMaskedCardComparisonNetworksMatch(bool matches) {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MaskedCardComparisonNetworksMatch", matches);
+}
+
+// static
void AutofillMetrics::LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
SaveTypeMetric metric) {
UMA_HISTOGRAM_ENUMERATION(
@@ -622,6 +592,14 @@ void AutofillMetrics::LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
}
// static
+void AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ SaveTypeMetric metric) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ metric);
+}
+
+// static
void AutofillMetrics::LogUploadDisallowedForNetworkMetric(
const std::string& network) {
UploadDisallowedForNetworkMetric metric;
@@ -687,19 +665,31 @@ void AutofillMetrics::LogCardUploadDecisionMetrics(
void AutofillMetrics::LogCreditCardInfoBarMetric(
InfoBarMetric metric,
bool is_uploading,
- bool is_requesting_cardholder_name,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision) {
DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
std::string destination = is_uploading ? ".Server" : ".Local";
base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination,
metric, NUM_INFO_BAR_METRICS);
- if (is_requesting_cardholder_name) {
+ if (options.should_request_name_from_user) {
base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
".RequestingCardholderName",
metric, NUM_INFO_BAR_METRICS);
}
+ if (options.should_request_expiration_date_from_user) {
+ base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
+ ".RequestingExpirationDate",
+ metric, NUM_INFO_BAR_METRICS);
+ }
+
+ if (options.has_non_focusable_field) {
+ base::UmaHistogramEnumeration(
+ "Autofill.CreditCardInfoBar" + destination + ".FromNonFocusableForm",
+ metric, NUM_INFO_BAR_METRICS);
+ }
+
base::UmaHistogramEnumeration(
"Autofill.CreditCardInfoBar" + destination +
PreviousSaveCreditCardPromptUserDecisionToString(
@@ -727,8 +717,7 @@ void AutofillMetrics::LogSaveCardPromptMetric(
SaveCardPromptMetric metric,
bool is_uploading,
bool is_reshow,
- bool is_requesting_cardholder_name,
- bool is_requesting_expiration_date,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision,
security_state::SecurityLevel security_level,
AutofillSyncSigninState sync_state) {
@@ -740,18 +729,23 @@ void AutofillMetrics::LogSaveCardPromptMetric(
base::UmaHistogramEnumeration(metric_with_destination_and_show, metric,
NUM_SAVE_CARD_PROMPT_METRICS);
base::UmaHistogramEnumeration(
- metric_with_destination_and_show + GetSyncStateSuffix(sync_state), metric,
- NUM_SAVE_CARD_PROMPT_METRICS);
- if (is_requesting_cardholder_name) {
+ metric_with_destination_and_show + GetMetricsSyncStateSuffix(sync_state),
+ metric, NUM_SAVE_CARD_PROMPT_METRICS);
+ if (options.should_request_name_from_user) {
base::UmaHistogramEnumeration(
metric_with_destination_and_show + ".RequestingCardholderName", metric,
NUM_SAVE_CARD_PROMPT_METRICS);
}
- if (is_requesting_expiration_date) {
+ if (options.should_request_expiration_date_from_user) {
base::UmaHistogramEnumeration(
metric_with_destination_and_show + ".RequestingExpirationDate", metric,
NUM_SAVE_CARD_PROMPT_METRICS);
}
+ if (options.has_non_focusable_field) {
+ base::UmaHistogramEnumeration(
+ metric_with_destination_and_show + ".FromNonFocusableForm", metric,
+ NUM_SAVE_CARD_PROMPT_METRICS);
+ }
base::UmaHistogramEnumeration(
metric_with_destination_and_show +
PreviousSaveCreditCardPromptUserDecisionToString(
@@ -944,7 +938,19 @@ void AutofillMetrics::LogUnmaskPromptEvent(UnmaskPromptEvent event) {
void AutofillMetrics::LogCardholderNameFixFlowPromptEvent(
CardholderNameFixFlowPromptEvent event) {
UMA_HISTOGRAM_ENUMERATION("Autofill.CardholderNameFixFlowPrompt.Events",
- event, NUM_FIXFLOW_PROMPT_EVENTS);
+ event, NUM_CARDHOLDER_NAME_FIXFLOW_PROMPT_EVENTS);
+}
+
+// static
+void AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ ExpirationDateFixFlowPromptEvent event) {
+ UMA_HISTOGRAM_ENUMERATION("Autofill.ExpirationDateFixFlowPrompt.Events",
+ event);
+}
+
+// static
+void AutofillMetrics::LogExpirationDateFixFlowPromptShown() {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.ExpirationDateFixFlowPromptShown", true);
}
// static
@@ -1246,7 +1252,8 @@ void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(
AutofillSyncSigninState sync_state) {
std::string name("Autofill.IsEnabled.PageLoad");
UMA_HISTOGRAM_BOOLEAN(name, enabled);
- base::UmaHistogramBoolean(name + GetSyncStateSuffix(sync_state), enabled);
+ base::UmaHistogramBoolean(name + GetMetricsSyncStateSuffix(sync_state),
+ enabled);
}
// static
@@ -1670,338 +1677,16 @@ void AutofillMetrics::LogDeveloperEngagementUkm(
.Record(ukm_recorder);
}
-AutofillMetrics::FormEventLogger::FormEventLogger(
- bool is_for_credit_card,
- bool is_in_main_frame,
- AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
- : is_for_credit_card_(is_for_credit_card),
- is_in_main_frame_(is_in_main_frame),
- server_record_type_count_(0),
- local_record_type_count_(0),
- is_context_secure_(false),
- has_logged_interacted_(false),
- has_logged_popup_suppressed_(false),
- has_logged_suggestions_shown_(false),
- has_logged_masked_server_card_suggestion_selected_(false),
- has_logged_suggestion_filled_(false),
- has_logged_will_submit_(false),
- has_logged_submitted_(false),
- has_logged_bank_name_available_(false),
- logged_suggestion_filled_was_server_data_(false),
- logged_suggestion_filled_was_masked_server_card_(false),
- form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
-
-void AutofillMetrics::FormEventLogger::OnDidParseForm() {
- Log(AutofillMetrics::FORM_EVENT_DID_PARSE_FORM);
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ParsedCreditCardForm"));
- } else {
- base::RecordAction(base::UserMetricsAction("Autofill_ParsedProfileForm"));
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm(
- FormSignature form_signature,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- if (!has_logged_interacted_) {
- has_logged_interacted_ = true;
- form_interactions_ukm_logger_->LogInteractedWithForm(
- is_for_credit_card_, local_record_type_count_,
- server_record_type_count_, form_signature);
- Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidPollSuggestions(
- const FormFieldData& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Record only one poll user action for consecutive polls of the same field.
- // This is to avoid recording too many poll actions (for example when a user
- // types in a field, triggering multiple queries) to make the analysis more
- // simple.
- if (!field.SameFieldAs(last_polled_field_)) {
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_PolledCreditCardSuggestions"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("Autofill_PolledProfileSuggestions"));
- }
-
- last_polled_field_ = field;
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnPopupSuppressed(
- const FormStructure& form,
- const AutofillField& field) {
- Log(AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED);
- if (!has_logged_popup_suppressed_) {
- has_logged_popup_suppressed_ = true;
- Log(AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidShowSuggestions(
- const FormStructure& form,
- const AutofillField& field,
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- form_interactions_ukm_logger_->LogSuggestionsShown(
- form, field, form_parsed_timestamp);
-
- Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
- if (!has_logged_suggestions_shown_) {
- has_logged_suggestions_shown_ = true;
- Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- }
-
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ShowedCreditCardSuggestions"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ShowedProfileSuggestions"));
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidSelectMaskedServerCardSuggestion(
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(is_for_credit_card_);
- form_interactions_ukm_logger_->LogSelectedMaskedServerCard(
- form_parsed_timestamp);
-
- Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED);
- if (!has_logged_masked_server_card_suggestion_selected_) {
- has_logged_masked_server_card_suggestion_selected_ = true;
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
- const CreditCard& credit_card,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(is_for_credit_card_);
- form_interactions_ukm_logger_->LogDidFillSuggestion(
- static_cast<int>(credit_card.record_type()),
- /*is_for_credit_card=*/true, form, field);
-
- if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD)
- Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED);
- else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD)
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
- else
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
-
- if (!has_logged_suggestion_filled_) {
- has_logged_suggestion_filled_ = true;
- logged_suggestion_filled_was_server_data_ =
- credit_card.record_type() == CreditCard::MASKED_SERVER_CARD ||
- credit_card.record_type() == CreditCard::FULL_SERVER_CARD;
- logged_suggestion_filled_was_masked_server_card_ =
- credit_card.record_type() == CreditCard::MASKED_SERVER_CARD;
- if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- } else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
- }
- }
-
- base::RecordAction(
- base::UserMetricsAction("Autofill_FilledCreditCardSuggestion"));
-}
-
-void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
- const AutofillProfile& profile,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(!is_for_credit_card_);
- form_interactions_ukm_logger_->LogDidFillSuggestion(
- static_cast<int>(profile.record_type()),
- /*is_for_for_credit_card=*/false, form, field);
-
- if (profile.record_type() == AutofillProfile::SERVER_PROFILE)
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
- else
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
-
- if (!has_logged_suggestion_filled_) {
- has_logged_suggestion_filled_ = true;
- logged_suggestion_filled_was_server_data_ =
- profile.record_type() == AutofillProfile::SERVER_PROFILE;
- Log(profile.record_type() == AutofillProfile::SERVER_PROFILE
- ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
- : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
- }
-
- base::RecordAction(
- base::UserMetricsAction("Autofill_FilledProfileSuggestion"));
-}
-
-void AutofillMetrics::FormEventLogger::OnWillSubmitForm(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Not logging this kind of form if we haven't logged a user interaction.
- if (!has_logged_interacted_)
- return;
-
- // Not logging twice.
- if (has_logged_will_submit_)
- return;
- has_logged_will_submit_ = true;
-
- if (!has_logged_suggestion_filled_) {
- Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE);
- } else if (logged_suggestion_filled_was_masked_server_card_) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE);
- } else if (logged_suggestion_filled_was_server_data_) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE);
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE);
- }
-
- if (has_logged_suggestions_shown_) {
- Log(AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE);
- }
-
- base::RecordAction(base::UserMetricsAction("Autofill_OnWillSubmitForm"));
-}
-
-void AutofillMetrics::FormEventLogger::OnFormSubmitted(
- bool force_logging,
- CardNumberStatus card_number_status,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Not logging this kind of form if we haven't logged a user interaction.
- if (!has_logged_interacted_)
- return;
-
- // Not logging twice.
- if (has_logged_submitted_)
- return;
- has_logged_submitted_ = true;
-
- if (!has_logged_suggestion_filled_) {
- Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE);
- } else if (logged_suggestion_filled_was_masked_server_card_) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
- } else if (logged_suggestion_filled_was_server_data_) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE);
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE);
- }
-
- if (has_logged_suggestions_shown_ || force_logging) {
- Log(AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE);
- if (is_for_credit_card_ && !has_logged_suggestion_filled_) {
- Log(GetCardNumberStatusFormEvent(card_number_status));
- }
- }
-}
-
-void AutofillMetrics::FormEventLogger::SetBankNameAvailable() {
- has_logged_bank_name_available_ = true;
-}
-
-void AutofillMetrics::FormEventLogger::OnDidSeeFillableDynamicForm(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM);
-}
-
-void AutofillMetrics::FormEventLogger::OnDidRefill(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL);
-}
-
-void AutofillMetrics::FormEventLogger::OnSubsequentRefillAttempt(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL);
-}
-
-void AutofillMetrics::FormEventLogger::Log(FormEvent event) const {
- DCHECK_LT(event, NUM_FORM_EVENTS);
- std::string name("Autofill.FormEvents.");
- if (is_for_credit_card_)
- name += "CreditCard";
- else
- name += "Address";
- base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
-
- // Log again in a different histogram so that iframes can be analyzed on their
- // own.
- base::UmaHistogramEnumeration(
- name + (is_in_main_frame_ ? ".IsInMainFrame" : ".IsInIFrame"), event,
- NUM_FORM_EVENTS);
-
- // Log again in a different histogram for credit card forms on nonsecure
- // pages, so that form interactions on nonsecure pages can be analyzed on
- // their own.
- if (is_for_credit_card_ && !is_context_secure_) {
- base::UmaHistogramEnumeration(name + ".OnNonsecurePage", event,
- NUM_FORM_EVENTS);
- }
-
- // Logging again in a different histogram for segmentation purposes.
- if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
- name += ".WithNoData";
- else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
- name += ".WithOnlyServerData";
- else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
- name += ".WithOnlyLocalData";
- else
- name += ".WithBothServerAndLocalData";
- base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
- base::UmaHistogramEnumeration(name + GetSyncStateSuffix(sync_state_), event,
- NUM_FORM_EVENTS);
-}
-
-void AutofillMetrics::FormEventLogger::Log(
- BankNameDisplayedFormEvent event) const {
- DCHECK_LT(event, BANK_NAME_NUM_FORM_EVENTS);
- std::string name("Autofill.FormEvents.CreditCard.BankNameDisplayed");
- base::UmaHistogramEnumeration(name, event, BANK_NAME_NUM_FORM_EVENTS);
-}
-
AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
ukm::UkmRecorder* ukm_recorder,
const ukm::SourceId source_id)
- : ukm_recorder_(ukm_recorder), source_id_(source_id) {}
+ : ukm_recorder_(ukm_recorder), source_id_(source_id) {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.CanLogUKM", CanLog());
+}
void AutofillMetrics::FormInteractionsUkmLogger::OnFormsParsed(
const ukm::SourceId source_id) {
- if (ukm_recorder_ == nullptr)
+ if (!CanLog())
return;
source_id_ = source_id;
@@ -2041,17 +1726,6 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown(
.Record(ukm_recorder_);
}
-void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard(
- const base::TimeTicks& form_parsed_timestamp) {
- if (!CanLog())
- return;
-
- ukm::builders::Autofill_SelectedMaskedServerCard(source_id_)
- .SetMillisecondsSinceFormParsed(
- MillisecondsSinceFormParsed(form_parsed_timestamp))
- .Record(ukm_recorder_);
-}
-
void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
int record_type,
bool is_for_credit_card,
@@ -2197,6 +1871,23 @@ void AutofillMetrics::LogWalletSyncTransportCardsOptIn(bool is_opted_in) {
"Autofill.HadUserOptedIn_To_WalletSyncTransportServerCards", is_opted_in);
}
+// static
+const char* AutofillMetrics::GetMetricsSyncStateSuffix(
+ AutofillSyncSigninState sync_state) {
+ switch (sync_state) {
+ case AutofillSyncSigninState::kSignedOut:
+ return ".SignedOut";
+ case AutofillSyncSigninState::kSignedIn:
+ return ".SignedIn";
+ case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
+ return ".SignedInAndWalletSyncTransportEnabled";
+ case AutofillSyncSigninState::kSignedInAndSyncFeature:
+ return ".SignedInAndSyncFeature";
+ case AutofillSyncSigninState::kNumSyncStates:
+ return ".Unknown";
+ }
+}
+
void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
bool is_for_credit_card,
bool has_upi_vpa_field,
@@ -2224,6 +1915,24 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
builder.Record(ukm_recorder_);
}
+void AutofillMetrics::FormInteractionsUkmLogger::LogFormEvent(
+ FormEvent form_event,
+ const std::set<FormType>& form_types,
+ const base::TimeTicks& form_parsed_timestamp) {
+ if (!CanLog())
+ return;
+
+ if (form_parsed_timestamp.is_null())
+ return;
+
+ ukm::builders::Autofill_FormEvent builder(source_id_);
+ builder.SetAutofillFormEvent(static_cast<int>(form_event))
+ .SetFormTypes(FormTypesToBitVector(form_types))
+ .SetMillisecondsSinceFormParsed(
+ MillisecondsSinceFormParsed(form_parsed_timestamp))
+ .Record(ukm_recorder_);
+}
+
bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
return ukm_recorder_ != nullptr;
}
@@ -2234,7 +1943,10 @@ int64_t AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed(
// Use the pinned timestamp as the current time if it's set.
base::TimeTicks now =
pinned_timestamp_.is_null() ? base::TimeTicks::Now() : pinned_timestamp_;
- return (now - form_parsed_timestamp).InMilliseconds();
+
+ return ukm::GetExponentialBucketMin(
+ (now - form_parsed_timestamp).InMilliseconds(),
+ kAutofillEventDataBucketSpacing);
}
AutofillMetrics::UkmTimestampPin::UkmTimestampPin(
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.h b/chromium/components/autofill/core/browser/autofill_metrics.h
index 2e2f6150140..39c231415ae 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.h
+++ b/chromium/components/autofill/core/browser/autofill_metrics.h
@@ -18,6 +18,7 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_types.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/signatures_util.h"
@@ -110,6 +111,11 @@ class AutofillMetrics {
// A pair of dropdowns for the user to select expiration date was surfaced
// in the offer-to-save dialog.
USER_REQUESTED_TO_PROVIDE_EXPIRATION_DATE = 1 << 14,
+ // All the required conditions were satisfied even though the form is
+ // unfocused after the user entered information into it.
+ UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD = 1 << 15,
+ // The card does not satisfy any of the ranges of supported BIN ranges.
+ UPLOAD_NOT_OFFERED_UNSUPPORTED_BIN_RANGE = 1 << 16,
// Update |kNumCardUploadDecisionMetrics| when adding new enum here.
};
@@ -169,7 +175,7 @@ class AutofillMetrics {
// Metric to measure if a submitted card's expiration date matches the same
// server card's expiration date (unmasked or not). Cards are considered to
// be the same if they have the same card number (if unmasked) or if they have
- // the same network and last four digits (if masked).
+ // the same last four digits (if masked).
enum SubmittedServerCardExpirationStatusMetric {
// The submitted card and the unmasked server card had the same expiration
// date.
@@ -592,111 +598,6 @@ class AutofillMetrics {
NUM_USER_HAPPINESS_METRICS,
};
- // Form Events for autofill.
- // These events are triggered separetly for address and credit card forms.
- enum FormEvent {
- // User interacted with a field of this kind of form. Logged only once per
- // page load.
- FORM_EVENT_INTERACTED_ONCE = 0,
- // A dropdown with suggestions was shown.
- FORM_EVENT_SUGGESTIONS_SHOWN,
- // Same as above, but recoreded only once per page load.
- FORM_EVENT_SUGGESTIONS_SHOWN_ONCE,
- // A local suggestion was used to fill the form.
- FORM_EVENT_LOCAL_SUGGESTION_FILLED,
- // A server suggestion was used to fill the form.
- // When dealing with credit cards, this means a full server card was used
- // to fill.
- FORM_EVENT_SERVER_SUGGESTION_FILLED,
- // A masked server card suggestion was used to fill the form.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED,
- // A suggestion was used to fill the form. The origin type (local or server
- // or masked server card) of the first selected within a page load will
- // determine which of the following two will be fired.
- FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- // A form was submitted. Depending on the user filling a local, server,
- // masked server card or no suggestion one of the following will be
- // triggered. Only one of the following four will be triggered per page
- // load.
- FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
- // A masked server card suggestion was selected to fill the form.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED,
- // Same as above but only triggered once per page load.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- // An autofillable form is about to be submitted. If the submission is not
- // interrupted by JavaScript, the "form submitted" events above will also be
- // logged. Depending on the user filling a local, server, masked server card
- // or no suggestion one of the following will be triggered, at most once per
- // page load.
- FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
- // A dropdown with suggestions was shown and a form was submitted after
- // that.
- FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
- // A dropdown with suggestions was shown and a form is about to be
- // submitted. If the submission is not interrupted by JavaScript, the "form
- // submitted" event above will also be logged.
- FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE,
- // A dropdown with credit card suggestions was shown, but they were not used
- // to fill the form. Depending on the user submitting a card known by the
- // browser, submitting a card that the browser does not know about,
- // submitting with an empty card number, submitting with a card number of
- // wrong size or submitting with a card number that does not pass luhn
- // check, one of the following will be triggered. At most one of the
- // following five metrics will be triggered per submit.
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
-
- // The form was changed dynamically. This value has been deprecated.
- FORM_EVENT_DID_SEE_DYNAMIC_FORM,
- // The form was changed dynamically and was fillable.
- FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
- // There was a dynamic change of the form and it got re-filled
- // automatically.
- FORM_EVENT_DID_DYNAMIC_REFILL,
- // The form dynamically changed another time after the refill.
- FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL,
- // The popup was suppressed because the native view couldn't be created.
- FORM_EVENT_POPUP_SUPPRESSED,
- // Same as above, but recoreded only once per page load.
- FORM_EVENT_POPUP_SUPPRESSED_ONCE,
-
- // The form was parsed.
- FORM_EVENT_DID_PARSE_FORM,
-
- NUM_FORM_EVENTS,
- };
-
- // Indicates submitted card information.
- enum CardNumberStatus {
- EMPTY_CARD,
- WRONG_SIZE_CARD,
- FAIL_LUHN_CHECK_CARD,
- KNOWN_CARD,
- UNKNOWN_CARD
- };
-
- // Form Events for autofill with bank name available for display.
- enum BankNameDisplayedFormEvent {
- // A dropdown with suggestions was shown and at least one suggestion has a
- // bank name. Logged at most once per page load.
- FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE = 0,
- // A server suggestion was used to fill the form and at least one suggestion
- // has a bank name. Logged at most once per page load.
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
- BANK_NAME_NUM_FORM_EVENTS,
- };
-
// Cardholder name fix flow prompt metrics.
enum CardholderNameFixFlowPromptEvent {
// The prompt was shown.
@@ -707,7 +608,18 @@ class AutofillMetrics {
CARDHOLDER_NAME_FIX_FLOW_PROMPT_DISMISSED,
// The prompt was closed without user interaction.
CARDHOLDER_NAME_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
- NUM_FIXFLOW_PROMPT_EVENTS,
+ NUM_CARDHOLDER_NAME_FIXFLOW_PROMPT_EVENTS,
+ };
+
+ // Expiration date fix flow prompt metrics.
+ enum class ExpirationDateFixFlowPromptEvent {
+ // The prompt was accepted by user.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_ACCEPTED = 0,
+ // The prompt was dismissed by user.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_DISMISSED,
+ // The prompt was closed without user interaction.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
+ kMaxValue = EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
};
// Events related to the Unmask Credit Card Prompt.
@@ -872,8 +784,6 @@ class AutofillMetrics {
void LogSuggestionsShown(const FormStructure& form,
const AutofillField& field,
const base::TimeTicks& form_parsed_timestamp);
- void LogSelectedMaskedServerCard(
- const base::TimeTicks& form_parsed_timestamp);
void LogDidFillSuggestion(int record_type,
bool is_for_credit_card,
const FormStructure& form,
@@ -896,6 +806,9 @@ class AutofillMetrics {
AutofillFormSubmittedState state,
const base::TimeTicks& form_parsed_timestamp,
FormSignature form_signature);
+ void LogFormEvent(FormEvent form_event,
+ const std::set<FormType>& form_types,
+ const base::TimeTicks& form_parsed_timestamp);
// Log whether the autofill decided to skip or to fill each
// hidden/representational field.
@@ -941,11 +854,20 @@ class AutofillMetrics {
static void LogSubmittedServerCardExpirationStatusMetric(
SubmittedServerCardExpirationStatusMetric metric);
+ // When a masked card is compared with another card, logs whether the cards'
+ // networks match.
+ static void LogMaskedCardComparisonNetworksMatch(bool matches);
+
// When credit card save is not offered (either at all on mobile or by simply
// not showing the bubble on desktop), logs the occurrence.
static void LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
SaveTypeMetric metric);
+ // When local card migration is not offered due to max strike limit reached,
+ // logs the occurrence.
+ static void LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ SaveTypeMetric metric);
+
// When credit card upload is disallowed for a particular network, logs which
// network was blocked.
static void LogUploadDisallowedForNetworkMetric(const std::string& network);
@@ -977,7 +899,7 @@ class AutofillMetrics {
static void LogCreditCardInfoBarMetric(
InfoBarMetric metric,
bool is_uploading,
- bool is_requesting_cardholder_name,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision);
static void LogCreditCardFillingInfoBarMetric(InfoBarMetric metric);
static void LogSaveCardRequestExpirationDateReasonMetric(
@@ -986,8 +908,7 @@ class AutofillMetrics {
SaveCardPromptMetric metric,
bool is_uploading,
bool is_reshow,
- bool is_requesting_cardholder_name,
- bool is_requesting_expiration_date_from_user,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision,
security_state::SecurityLevel security_level,
AutofillSyncSigninState sync_state);
@@ -1069,6 +990,13 @@ class AutofillMetrics {
static void LogCardholderNameFixFlowPromptEvent(
CardholderNameFixFlowPromptEvent event);
+ // Logs |event| to expiration date fix flow prompt events histogram.
+ static void LogExpirationDateFixFlowPromptEvent(
+ ExpirationDateFixFlowPromptEvent event);
+
+ // Logs the count of expiration date fix flow prompts shown histogram.
+ static void LogExpirationDateFixFlowPromptShown();
+
// Logs the time elapsed between the unmask prompt being shown and it
// being closed.
static void LogUnmaskPromptEventDuration(const base::TimeDelta& duration,
@@ -1303,108 +1231,13 @@ class AutofillMetrics {
// server cards to be shown.
static void LogWalletSyncTransportCardsOptIn(bool is_opted_in);
- // Utility to log autofill form events in the relevant histograms depending on
- // the presence of server and/or local data.
- class FormEventLogger {
- public:
- FormEventLogger(bool is_for_credit_card,
- bool is_in_main_frame,
- FormInteractionsUkmLogger* form_interactions_ukm_logger);
-
- inline void set_server_record_type_count(size_t server_record_type_count) {
- server_record_type_count_ = server_record_type_count;
- }
-
- inline void set_local_record_type_count(size_t local_record_type_count) {
- local_record_type_count_ = local_record_type_count;
- }
-
- inline void set_is_context_secure(bool is_context_secure) {
- is_context_secure_ = is_context_secure;
- }
-
- void OnDidInteractWithAutofillableForm(FormSignature form_signature,
- AutofillSyncSigninState sync_state);
-
- void OnDidPollSuggestions(const FormFieldData& field,
- AutofillSyncSigninState sync_state);
-
- void OnDidParseForm();
-
- void OnDidInteractWithAutofillableForm(FormSignature form_signature);
-
- void OnPopupSuppressed(const FormStructure& form,
- const AutofillField& field);
-
- void OnDidShowSuggestions(const FormStructure& form,
- const AutofillField& field,
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state);
-
- void OnDidSelectMaskedServerCardSuggestion(
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state);
-
- // In case of masked cards, caller must make sure this gets called before
- // the card is upgraded to a full card.
- void OnDidFillSuggestion(const CreditCard& credit_card,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state);
-
- void OnDidFillSuggestion(const AutofillProfile& profile,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state);
-
- void OnWillSubmitForm(AutofillSyncSigninState sync_state);
-
- void OnFormSubmitted(bool force_logging,
- const CardNumberStatus card_number_status,
- AutofillSyncSigninState sync_state);
-
- void SetBankNameAvailable();
-
- void OnDidSeeFillableDynamicForm(AutofillSyncSigninState sync_state);
-
- void OnDidRefill(AutofillSyncSigninState sync_state);
-
- void OnSubsequentRefillAttempt(AutofillSyncSigninState sync_state);
-
- private:
- void Log(FormEvent event) const;
- void Log(BankNameDisplayedFormEvent event) const;
-
- bool is_for_credit_card_;
- bool is_in_main_frame_;
- size_t server_record_type_count_;
- size_t local_record_type_count_;
- bool is_context_secure_;
- bool has_logged_interacted_;
- bool has_logged_popup_suppressed_;
- bool has_logged_suggestions_shown_;
- bool has_logged_masked_server_card_suggestion_selected_;
- bool has_logged_suggestion_filled_;
- bool has_logged_will_submit_;
- bool has_logged_submitted_;
- bool has_logged_bank_name_available_;
- bool logged_suggestion_filled_was_server_data_;
- bool logged_suggestion_filled_was_masked_server_card_;
-
- // The last field that was polled for suggestions.
- FormFieldData last_polled_field_;
-
- FormInteractionsUkmLogger*
- form_interactions_ukm_logger_; // Weak reference.
-
- AutofillSyncSigninState sync_state_ =
- AutofillSyncSigninState::kNumSyncStates;
- };
+ static const char* GetMetricsSyncStateSuffix(
+ AutofillSyncSigninState sync_state);
private:
static void Log(AutocompleteEvent event);
- static const int kNumCardUploadDecisionMetrics = 15;
+ static const int kNumCardUploadDecisionMetrics = 17;
DISALLOW_IMPLICIT_CONSTRUCTORS(AutofillMetrics);
};
diff --git a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
index 213d7d340fa..87afa30900e 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -23,6 +23,9 @@
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_external_delegate.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
@@ -70,8 +73,6 @@ using UkmCardUploadDecisionType = ukm::builders::Autofill_CardUploadDecision;
using UkmDeveloperEngagementType = ukm::builders::Autofill_DeveloperEngagement;
using UkmInteractedWithFormType = ukm::builders::Autofill_InteractedWithForm;
using UkmSuggestionsShownType = ukm::builders::Autofill_SuggestionsShown;
-using UkmSelectedMaskedServerCardType =
- ukm::builders::Autofill_SelectedMaskedServerCard;
using UkmSuggestionFilledType = ukm::builders::Autofill_SuggestionFilled;
using UkmTextFieldDidChangeType = ukm::builders::Autofill_TextFieldDidChange;
using UkmLogHiddenRepresentationalFieldSkipDecisionType =
@@ -81,10 +82,13 @@ using UkmLogRepeatedServerTypePredictionRationalized =
using UkmFormSubmittedType = ukm::builders::Autofill_FormSubmitted;
using UkmFieldTypeValidationType = ukm::builders::Autofill_FieldTypeValidation;
using UkmFieldFillStatusType = ukm::builders::Autofill_FieldFillStatus;
+using UkmFormEventType = ukm::builders::Autofill_FormEvent;
using ExpectedUkmMetrics =
std::vector<std::vector<std::pair<const char*, int64_t>>>;
+const char* kTestGuid = "00000000-0000-0000-0000-000000000001";
+
int64_t Collapse(uint64_t sig) {
return sig % 1021;
}
@@ -131,10 +135,10 @@ MATCHER(CompareMetricsIgnoringMillisecondsSinceFormParsed, "") {
UkmSuggestionFilledType::kMillisecondsSinceFormParsedName));
}
-void VerifyFormInteractionUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
- const FormData& form,
- const char* event_name,
- const ExpectedUkmMetrics& expected_metrics) {
+void VerifyUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
+ const FormData& form,
+ const char* event_name,
+ const ExpectedUkmMetrics& expected_metrics) {
auto entries = ukm_recorder.GetEntriesByName(event_name);
EXPECT_LE(entries.size(), expected_metrics.size());
@@ -154,16 +158,15 @@ void VerifySubmitFormUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
bool is_for_credit_card,
bool has_upi_vpa_field,
const std::set<FormType>& form_types) {
- VerifyFormInteractionUkm(
- ukm_recorder, form, UkmFormSubmittedType::kEntryName,
- {{{UkmFormSubmittedType::kAutofillFormSubmittedStateName, state},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmFormSubmittedType::kIsForCreditCardName, is_for_credit_card},
- {UkmFormSubmittedType::kHasUpiVpaFieldName, has_upi_vpa_field},
- {UkmFormSubmittedType::kFormTypesName,
- AutofillMetrics::FormTypesToBitVector(form_types)},
- {UkmFormSubmittedType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(ukm_recorder, form, UkmFormSubmittedType::kEntryName,
+ {{{UkmFormSubmittedType::kAutofillFormSubmittedStateName, state},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmFormSubmittedType::kIsForCreditCardName, is_for_credit_card},
+ {UkmFormSubmittedType::kHasUpiVpaFieldName, has_upi_vpa_field},
+ {UkmFormSubmittedType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector(form_types)},
+ {UkmFormSubmittedType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
}
void AppendFieldFillStatusUkm(const FormData& form,
@@ -218,6 +221,14 @@ void AppendFieldTypeUkm(const FormData& form,
}
}
+void SetProfileTestData(AutofillProfile* profile) {
+ test::SetProfileInfo(profile, "Elvis", "Aaron", "Presley",
+ "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
+ "Apt. 10", "Memphis", "Tennessee", "38116", "US",
+ "12345678901");
+ profile->set_guid(kTestGuid);
+}
+
class MockAutofillClient : public TestAutofillClient {
public:
MockAutofillClient() {}
@@ -242,7 +253,8 @@ class AutofillMetricsTest : public testing::Test {
void CreateAmbiguousProfiles();
// Removes all existing profiles and creates one profile.
- void RecreateProfile();
+ // |is_server| allows creation of |SERVER_PROFILE|.
+ void RecreateProfile(bool is_server);
// Removes all existing credit cards and creates a local, masked server,
// and/or full server credit card, according to the parameters.
@@ -353,16 +365,19 @@ void AutofillMetricsTest::CreateAmbiguousProfiles() {
personal_data_->Refresh();
}
-void AutofillMetricsTest::RecreateProfile() {
+void AutofillMetricsTest::RecreateProfile(bool is_server) {
personal_data_->ClearProfiles();
- AutofillProfile profile;
- test::SetProfileInfo(&profile, "Elvis", "Aaron", "Presley",
- "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
- "Apt. 10", "Memphis", "Tennessee", "38116", "US",
- "12345678901");
- profile.set_guid("00000000-0000-0000-0000-000000000001");
- personal_data_->AddProfile(profile);
+ if (is_server) {
+ AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "server_id");
+ SetProfileTestData(&profile);
+ personal_data_->AddProfile(profile);
+ } else {
+ AutofillProfile profile;
+ SetProfileTestData(&profile);
+ personal_data_->AddProfile(profile);
+ }
+
personal_data_->Refresh();
}
@@ -424,7 +439,7 @@ void AutofillMetricsTest::CreateTestAutofillProfiles() {
"theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
"Apt. 10", "Memphis", "Tennessee", "38116", "US",
"12345678901");
- profile1.set_guid("00000000-0000-0000-0000-000000000001");
+ profile1.set_guid(kTestGuid);
personal_data_->AddProfile(profile1);
AutofillProfile profile2;
@@ -453,12 +468,12 @@ class AutofillMetricsIFrameTest : public AutofillMetricsTest,
const std::string credit_card_form_events_frame_histogram_;
};
-INSTANTIATE_TEST_CASE_P(AutofillMetricsTest,
- AutofillMetricsIFrameTest,
- testing::Bool());
+INSTANTIATE_TEST_SUITE_P(AutofillMetricsTest,
+ AutofillMetricsIFrameTest,
+ testing::Bool());
-// Test parameter indicates if the metrics are being logged for a form in an
-// iframe or the main frame. True means the form is in the main frame.
+// Test parameter indicates if the metrics are being logged for a form
+// with a companyname field specified.
class AutofillMetricsCompanyTest : public AutofillMetricsTest,
public testing::WithParamInterface<bool> {
public:
@@ -477,9 +492,9 @@ class AutofillMetricsCompanyTest : public AutofillMetricsTest,
base::test::ScopedFeatureList scoped_feature_list_;
};
-INSTANTIATE_TEST_CASE_P(AutofillMetricsTest,
- AutofillMetricsCompanyTest,
- testing::Bool());
+INSTANTIATE_TEST_SUITE_P(AutofillMetricsTest,
+ AutofillMetricsCompanyTest,
+ testing::Bool());
// Test that we log quality metrics appropriately.
TEST_F(AutofillMetricsTest, QualityMetrics) {
@@ -723,7 +738,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -788,7 +803,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -815,7 +830,7 @@ TEST_F(AutofillMetricsTest,
// correctly.
TEST_F(AutofillMetricsTest, LogHiddenRepresentationalFieldSkipDecision) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
@@ -870,13 +885,13 @@ TEST_F(AutofillMetricsTest, LogHiddenRepresentationalFieldSkipDecision) {
// Simulate filling form.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogHiddenRepresentationalFieldSkipDecisionType::kEntryName,
{{{UkmLogHiddenRepresentationalFieldSkipDecisionType::kFormSignatureName,
@@ -1019,7 +1034,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedAddressTypeRationalized) {
.size(),
(size_t)2);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogRepeatedServerTypePredictionRationalized::kEntryName,
{{{UkmLogRepeatedServerTypePredictionRationalized::kFormSignatureName,
@@ -1134,7 +1149,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedStateCountryTypeRationalized) {
.size(),
(size_t)3);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogRepeatedServerTypePredictionRationalized::kEntryName,
{{{UkmLogRepeatedServerTypePredictionRationalized::kFormSignatureName,
@@ -1242,7 +1257,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -1323,7 +1338,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -1622,9 +1637,8 @@ TEST_P(QualityMetricsTest, Classification) {
ExpectedUkmMetrics expected_ukm_metrics;
AppendFieldTypeUkm(form, heuristic_types, server_types, actual_types,
&expected_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldTypeValidationType::kEntryName,
- expected_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldTypeValidationType::kEntryName,
+ expected_ukm_metrics);
// Validate the total samples and the crossed (predicted-to-actual) samples.
for (const auto& source : prediction_sources) {
@@ -1722,7 +1736,7 @@ TEST_P(QualityMetricsTest, Classification) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillMetricsTest,
QualityMetricsTest,
testing::Values(QualityMetricsTestCase{NO_SERVER_DATA, EMPTY_TYPE},
@@ -2882,7 +2896,6 @@ TEST_F(AutofillMetricsTest, AutofillIsEnabledAtStartup) {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", true, 1);
}
@@ -2897,7 +2910,6 @@ TEST_F(AutofillMetricsTest, AutofillIsDisabledAtStartup) {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", false, 1);
}
@@ -3107,7 +3119,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
"Autofill_FormSubmitted_NonFillable"));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
@@ -3128,7 +3140,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
@@ -3182,7 +3194,7 @@ TEST_F(AutofillMetricsTest, UpiVpaUkmTest) {
// Test that the profile checkout flow user actions are correctly logged.
TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
@@ -3237,7 +3249,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Simulate selecting a profile suggestions.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
external_delegate_->OnQuery(0, form, form.fields.front(), gfx::RectF());
external_delegate_->DidAcceptSuggestion(
ASCIIToUTF16("Test"),
@@ -3249,7 +3261,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Simulate filling a profile suggestion.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -3270,7 +3282,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
"Autofill_FormSubmitted_NonFillable"));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, ADDRESS_HOME_STATE},
@@ -3291,24 +3303,23 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}},
+ {{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
// Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
// because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
VerifySubmitFormUkm(test_ukm_recorder_, form,
@@ -3443,7 +3454,7 @@ TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) {
// Tests that the Autofill_PolledProfileSuggestions user action is only logged
// once if the field is queried repeatedly.
TEST_F(AutofillMetricsTest, PolledProfileSuggestions_DebounceLogs) {
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up the form data.
FormData form;
@@ -3528,8 +3539,8 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_DID_PARSE_FORM,
+ 1);
}
// Test that we log interacted form event for credit cards related.
@@ -3562,12 +3573,11 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardInteractedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_INTERACTED_ONCE, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
- histogram_tester.ExpectUniqueSample(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ credit_card_form_events_frame_histogram_, FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -3581,12 +3591,11 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardInteractedFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->OnQueryFormFieldAutofill(
1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_INTERACTED_ONCE, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
- histogram_tester.ExpectUniqueSample(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ credit_card_form_events_frame_histogram_, FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
}
@@ -3619,18 +3628,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardPopupSuppressedFormEvents) {
// Simulating popup being suppressed.
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
}
autofill_manager_->Reset();
@@ -3641,18 +3646,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardPopupSuppressedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
}
}
@@ -3685,18 +3686,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3713,18 +3710,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3741,18 +3734,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form,
field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3773,21 +3762,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3803,21 +3788,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3835,21 +3816,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3865,21 +3842,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3924,18 +3897,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSelectedFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -3955,18 +3926,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSelectedFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
}
}
@@ -4006,18 +3975,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -4038,18 +4005,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
}
// Recreating cards as the previous test should have upgraded the masked
@@ -4070,18 +4035,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -4103,18 +4066,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
}
// Recreate masked server cards with bank names.
@@ -4140,7 +4101,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4165,7 +4126,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4189,7 +4150,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4213,7 +4174,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4328,8 +4289,7 @@ TEST_F(AutofillMetricsTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 1);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 1);
}
TEST_P(AutofillMetricsIFrameTest,
@@ -4370,12 +4330,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
1);
}
@@ -4419,12 +4377,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
1);
}
@@ -4469,12 +4425,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
1);
}
@@ -4519,12 +4473,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
1);
}
@@ -4574,38 +4526,32 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 0);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
}
TEST_F(AutofillMetricsTest, ShouldNotLogFormEventNoCardForAddressForm) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -4638,8 +4584,7 @@ TEST_F(AutofillMetricsTest, ShouldNotLogFormEventNoCardForAddressForm) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 0);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 0);
}
// Test that we log submitted form events for credit cards.
@@ -4681,16 +4626,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -4714,18 +4659,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -4762,18 +4707,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
autofill_manager_->Reset();
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -4809,18 +4754,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
{UkmSuggestionFilledType::kIsForCreditCardName, true},
@@ -4855,18 +4800,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName,
CreditCard::FULL_SERVER_CARD},
@@ -4902,32 +4847,26 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
-
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- CreditCard::MASKED_SERVER_CARD},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, true},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.back()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSelectedMaskedServerCardType::kEntryName,
- {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
+
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ CreditCard::MASKED_SERVER_CARD},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, true},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.back()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
/*is_for_credit_card=*/true,
@@ -4965,7 +4904,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
autofill_manager_->OnFormSubmitted(form, false,
SubmissionSource::FORM_SUBMISSION);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
{{{UkmFormSubmittedType::kAutofillFormSubmittedStateName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
@@ -4988,70 +4927,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
}
@@ -5070,74 +5005,70 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -5195,16 +5126,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -5221,16 +5152,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5250,16 +5181,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5280,16 +5211,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5308,18 +5239,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
"6011000990139424");
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
}
// Recreating cards as the previous test should have upgraded the masked
@@ -5343,70 +5272,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics ::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics ::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
}
@@ -5424,70 +5349,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
}
@@ -5529,12 +5450,11 @@ TEST_F(AutofillMetricsTest, MixedParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address.WithNoData",
+ FORM_EVENT_DID_PARSE_FORM, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_DID_PARSE_FORM,
+ 1);
}
// Test that we log parsed form events for address.
@@ -5564,9 +5484,19 @@ TEST_F(AutofillMetricsTest, AddressParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address.WithNoData",
+ FORM_EVENT_DID_PARSE_FORM, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName, FORM_EVENT_DID_PARSE_FORM},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Test that we log interacted form events for address.
@@ -5599,13 +5529,25 @@ TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
+ FORM_EVENT_INTERACTED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_INTERACTED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5615,16 +5557,26 @@ TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->OnQueryFormFieldAutofill(
1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
+ FORM_EVENT_INTERACTED_ONCE, 1);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_INTERACTED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
}
// Test that popup suppressed form events for address are logged.
TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5652,16 +5604,32 @@ TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5669,19 +5637,39 @@ TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
}
// Test that we log suggestion shown form events for address.
TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5709,21 +5697,36 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5731,21 +5734,41 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5753,24 +5776,26 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form,
field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(0u, entries.size());
}
}
// Test that we log filled form events for address.
TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5797,45 +5822,99 @@ TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
{
// Simulating selecting/filling a local profile suggestion.
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
- // Simulating selecting/filling a local profile suggestion.
+ // Simulating selecting/filling a local profile suggestion more than once.
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ }
+
+ // Create a server profile and reset the autofill manager state.
+ RecreateProfile(/*is_server=*/true);
+ autofill_manager_->Reset();
+ autofill_manager_->AddSeenForm(form, field_types, field_types);
+
+ {
+ // Simulate selecting/filling a server profile suggestion.
+ base::HistogramTester histogram_tester;
+ std::string guid(kTestGuid); // server profile
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
+ }
+
+ autofill_manager_->Reset();
+ autofill_manager_->AddSeenForm(form, field_types, field_types);
+
+ {
+ // Simulate selecting/filling a server profile suggestion more than once.
+ base::HistogramTester histogram_tester;
+ std::string guid(kTestGuid); // server profile
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
}
}
// Test that we log submitted form events for address.
TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5868,10 +5947,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -5897,10 +5976,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
autofill_manager_->Reset();
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -5923,14 +6002,15 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5938,7 +6018,7 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -5946,10 +6026,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5968,32 +6048,33 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6006,45 +6087,48 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
}
}
// Test that we log "will submit" and "submitted" form events for address.
TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -6077,14 +6161,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6097,14 +6182,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6112,7 +6198,7 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -6120,14 +6206,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6141,42 +6228,45 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6188,38 +6278,40 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
}
}
@@ -6257,12 +6349,13 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(true /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6275,11 +6368,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(false /* include_local_credit_card */,
true /* include_masked_server_credit_card */,
@@ -6292,11 +6386,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyServerData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(false /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6309,11 +6404,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyServerData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(true /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6326,7 +6422,7 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithBothServerAndLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
}
@@ -6362,14 +6458,14 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ "Autofill.FormEvents.Address.WithNoData", FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
autofill_manager_->AddSeenForm(form, field_types, field_types);
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
{
// Simulate activating the autofill popup for the street field.
@@ -6378,7 +6474,7 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.Address.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
}
@@ -6476,14 +6572,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Non fillable form.
@@ -6513,14 +6607,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Fillable form.
@@ -6555,14 +6647,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Autofilled none with suggestions shown.
@@ -6578,18 +6668,17 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
EXPECT_EQ(1, user_action_tester.GetActionCount(
"Autofill_FormSubmitted_FilledNone_SuggestionsShown"));
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
- {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[2]))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))},
- {UkmTextFieldDidChangeType::kHeuristicTypeName,
- PHONE_HOME_WHOLE_NUMBER},
- {UkmTextFieldDidChangeType::kHtmlFieldTypeName,
- HTML_TYPE_UNSPECIFIED},
- {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA}}});
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
+ {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[2]))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))},
+ {UkmTextFieldDidChangeType::kHeuristicTypeName,
+ PHONE_HOME_WHOLE_NUMBER},
+ {UkmTextFieldDidChangeType::kHtmlFieldTypeName,
+ HTML_TYPE_UNSPECIFIED},
+ {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA}}});
expected_form_submission_ukm_metrics.push_back(
{{UkmFormSubmittedType::kAutofillFormSubmittedStateName,
@@ -6602,14 +6691,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Mark one of the fields as autofilled.
@@ -6639,14 +6726,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Mark all of the fillable fields as autofilled.
@@ -6677,14 +6762,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Clear out the third field's value.
@@ -6722,14 +6805,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
}
@@ -6797,14 +6878,12 @@ TEST_F(
AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
}
@@ -7166,7 +7245,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
// Simulate editing an autofilled field.
{
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -7214,12 +7293,11 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
autofill_manager_->Reset();
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmInteractedWithFormType::kEntryName,
- {{{UkmInteractedWithFormType::kIsForCreditCardName, false},
- {UkmInteractedWithFormType::kLocalRecordTypeCountName, 0},
- {UkmInteractedWithFormType::kServerRecordTypeCountName, 0}}});
- VerifyFormInteractionUkm(
+ VerifyUkm(test_ukm_recorder_, form, UkmInteractedWithFormType::kEntryName,
+ {{{UkmInteractedWithFormType::kIsForCreditCardName, false},
+ {UkmInteractedWithFormType::kLocalRecordTypeCountName, 0},
+ {UkmInteractedWithFormType::kServerRecordTypeCountName, 0}}});
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName,
@@ -7256,24 +7334,23 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
Collapse(CalculateFieldSignatureForField(form.fields[1]))},
{UkmSuggestionsShownType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[0]))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[2]))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[0]))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}},
+ {{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[2]))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(
test_ukm_recorder_, form, UkmTextFieldDidChangeType::kEntryName,
{{{UkmTextFieldDidChangeType::kFieldTypeGroupName, NAME},
{UkmTextFieldDidChangeType::kHeuristicTypeName, NAME_FULL},
@@ -8010,13 +8087,12 @@ TEST_F(AutofillMetricsTest, NonsecureCreditCardForm) {
SubmissionSource::FORM_SUBMISSION);
histograms.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.OnNonsecurePage",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
histograms.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
}
}
@@ -8066,12 +8142,10 @@ TEST_F(AutofillMetricsTest,
base::HistogramTester histograms;
autofill_manager_->OnFormSubmitted(form, false,
SubmissionSource::FORM_SUBMISSION);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
// Check that the nonsecure histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(
@@ -8180,7 +8254,7 @@ TEST_F(AutofillMetricsTest, MAYBE_AutofillSuggestionShownTest) {
// Simulate and Autofill query on credit card name field.
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
form.fields[0]);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionsShownType::kMillisecondsSinceFormParsedName, 0},
{UkmSuggestionsShownType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
@@ -8217,7 +8291,7 @@ TEST_F(AutofillMetricsTest, DynamicFormMetrics) {
// Simulate seeing.
base::HistogramTester histogram_tester;
autofill_manager_->AddSeenForm(form, field_types, field_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Simulate checking whether to fill a dynamic form before the form was filled
// initially.
@@ -8233,39 +8307,33 @@ TEST_F(AutofillMetricsTest, DynamicFormMetrics) {
// Simulate checking whether to fill a dynamic form after the form was filled
// initially.
autofill_manager_->ShouldTriggerRefill(form_structure);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
// Trigger a refill, the refill metric should be updated.
autofill_manager_->TriggerRefill(form);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
// Trigger a check to see whether a refill should happen. The
autofill_manager_->ShouldTriggerRefill(form_structure);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 1);
}
// Tests that the LogUserHappinessBySecurityLevel are recorded correctly.
@@ -8433,8 +8501,7 @@ TEST_F(AutofillMetricsTest,
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING,
/*is_uploading=*/true, /*is_reshow=*/false,
- /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date=*/false,
+ AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/1,
security_state::SecurityLevel::EV_SECURE, SyncSigninState::kSignedOut);
histogram_tester.ExpectBucketCount(
@@ -8446,8 +8513,7 @@ TEST_F(AutofillMetricsTest,
base::HistogramTester histogram_tester;
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/false,
- /*is_reshow=*/true, /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date=*/false,
+ /*is_reshow=*/true, AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/0,
security_state::SecurityLevel::SECURE, SyncSigninState::kSignedOut);
histogram_tester.ExpectBucketCount(
@@ -8499,25 +8565,32 @@ TEST_F(AutofillMetricsTest, LogNumberOfAutocompleteEntriesCleanedUp) {
// Verify that we correctly log FormEvent metrics with the appropriate sync
// state.
TEST_F(AutofillMetricsTest, FormEventMetrics_BySyncState) {
+ FormData form;
+ FormStructure form_structure(form);
+ std::vector<FormData> forms(1, form);
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
+ autofill_manager_->Reset();
+
{
base::HistogramTester histogram_tester;
- AutofillMetrics::FormEventLogger logger(
- /*is_for_credit_card=*/true, /*is_in_main_frame=*/false,
+ AddressFormEventLogger logger(
+ /*is_in_main_frame=*/true,
/*form_interactions_ukm_logger=*/nullptr);
- logger.OnDidSeeFillableDynamicForm(AutofillSyncSigninState::kSignedOut);
+ logger.OnDidSeeFillableDynamicForm(AutofillSyncSigninState::kSignedOut,
+ form_structure);
histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard.WithNoData.SignedOut",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
+ "Autofill.FormEvents.Address.WithNoData.SignedOut",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
}
{
base::HistogramTester histogram_tester;
- AutofillMetrics::FormEventLogger logger(
- /*is_for_credit_card=*/false, /*is_in_main_frame=*/true,
+ AddressFormEventLogger logger(
+ /*is_in_main_frame=*/true,
/*form_interactions_ukm_logger=*/nullptr);
- logger.OnDidRefill(AutofillSyncSigninState::kSignedIn);
+ logger.OnDidRefill(AutofillSyncSigninState::kSignedIn, form_structure);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address.WithNoData.SignedIn",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
}
}
@@ -8552,8 +8625,7 @@ TEST_F(AutofillMetricsTest, LogSaveCardPromptMetric_BySyncState) {
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING,
/*is_uploading=*/true, /*is_reshow=*/false,
- /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date_from_user=*/false,
+ AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/1,
security_state::SecurityLevel::EV_SECURE, SyncSigninState::kSignedIn);
histogram_tester.ExpectBucketCount(
@@ -8564,8 +8636,7 @@ TEST_F(AutofillMetricsTest, LogSaveCardPromptMetric_BySyncState) {
base::HistogramTester histogram_tester;
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/false,
- /*is_reshow=*/true, /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date_from_user=*/false,
+ /*is_reshow=*/true, AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/0,
security_state::SecurityLevel::SECURE,
SyncSigninState::kSignedInAndSyncFeature);
diff --git a/chromium/components/autofill/core/browser/autofill_profile.cc b/chromium/components/autofill/core/browser/autofill_profile.cc
index 750b4bb9b34..dd8c59b8f7a 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile.cc
@@ -337,8 +337,7 @@ void AutofillProfile::GetMatchingTypesAndValidities(
const base::string16& text,
const std::string& app_locale,
ServerFieldTypeSet* matching_types,
- std::map<ServerFieldType, AutofillProfile::ValidityState>*
- matching_types_validities) const {
+ ServerFieldTypeValidityStateMap* matching_types_validities) const {
if (!matching_types && !matching_types_validities)
return;
@@ -828,6 +827,38 @@ void AutofillProfile::RecordAndLogUse() {
RecordUse();
}
+bool AutofillProfile::HasGreaterFrescocencyThan(
+ const AutofillProfile* other,
+ base::Time comparison_time,
+ bool use_client_validation,
+ bool use_server_validation) const {
+ bool is_valid = (!use_client_validation || IsValidByClient()) &&
+ (!use_server_validation || IsValidByServer());
+ bool other_is_valid = (!use_client_validation || other->IsValidByClient()) &&
+ (!use_server_validation || other->IsValidByServer());
+ if (is_valid == other_is_valid)
+ return HasGreaterFrecencyThan(other, comparison_time);
+ if (is_valid && !other_is_valid)
+ return true;
+ return false;
+}
+
+bool AutofillProfile::IsValidByClient() const {
+ for (auto const& it : client_validity_states_) {
+ if (it.second == INVALID)
+ return false;
+ }
+ return true;
+}
+
+bool AutofillProfile::IsValidByServer() const {
+ for (auto const& it : server_validity_states_) {
+ if (it.second == INVALID)
+ return false;
+ }
+ return true;
+}
+
bool AutofillProfile::IsAnInvalidPhoneNumber(ServerFieldType type) const {
if (GetValidityState(type, SERVER) == VALID ||
(type != PHONE_HOME_WHOLE_NUMBER && type != PHONE_HOME_NUMBER &&
@@ -860,7 +891,7 @@ bool AutofillProfile::IsAnInvalidPhoneNumber(ServerFieldType type) const {
return false;
}
-AutofillProfile::ValidityState AutofillProfile::GetValidityState(
+AutofillDataModel::ValidityState AutofillProfile::GetValidityState(
ServerFieldType type,
ValidationSource validation_source) const {
if (validation_source == CLIENT) {
@@ -917,7 +948,6 @@ int AutofillProfile::GetClientValidityBitfieldValue() const {
int validity_value = 0;
size_t field_type_shift = 0;
for (ServerFieldType supported_type : kSupportedTypesByClientForValidation) {
- DCHECK(GetValidityState(supported_type, CLIENT) != UNSUPPORTED);
validity_value |= GetValidityState(supported_type, CLIENT)
<< field_type_shift;
field_type_shift += kValidityBitsPerType;
@@ -952,6 +982,29 @@ void AutofillProfile::SetClientValidityFromBitfieldValue(
}
}
+bool AutofillProfile::ShouldSkipFillingOrSuggesting(
+ ServerFieldType type) const {
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation) &&
+ GetValidityState(type, AutofillProfile::SERVER) ==
+ AutofillProfile::INVALID) {
+ return true;
+ }
+
+ // We are making an exception and skipping the validation check for address
+ // fields when the country is empty.
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation) &&
+ GetValidityState(type, AutofillProfile::CLIENT) ==
+ AutofillProfile::INVALID &&
+ (GroupTypeOfServerFieldType(type) != ADDRESS_HOME ||
+ !GetRawInfo(ADDRESS_HOME_COUNTRY).empty())) {
+ return true;
+ }
+
+ return false;
+}
+
base::string16 AutofillProfile::GetInfoImpl(
const AutofillType& type,
const std::string& app_locale) const {
diff --git a/chromium/components/autofill/core/browser/autofill_profile.h b/chromium/components/autofill/core/browser/autofill_profile.h
index 3d051f90202..bf1c5494762 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.h
+++ b/chromium/components/autofill/core/browser/autofill_profile.h
@@ -9,6 +9,7 @@
#include <iosfwd>
#include <list>
+#include <map>
#include <string>
#include <vector>
@@ -40,26 +41,6 @@ class AutofillProfile : public AutofillDataModel {
SERVER_PROFILE,
};
- enum ValidityState {
- // The field has not been validated.
- UNVALIDATED = 0,
- // The field is empty.
- EMPTY = 1,
- // The field is valid.
- VALID = 2,
- // The field is invalid.
- INVALID = 3,
- // The validation for the field is unsupported.
- UNSUPPORTED = 4,
- };
-
- enum ValidationSource {
- // The validity state is according to the client validation.
- CLIENT = 0,
- // The validity state is according to the server validation.
- SERVER = 1,
- };
-
AutofillProfile(const std::string& guid, const std::string& origin);
// Server profile constructor. The type must be SERVER_PROFILE (this serves
@@ -224,6 +205,24 @@ class AutofillProfile : public AutofillDataModel {
// use and updates |previous_use_date_| to the last value of |use_date_|.
void RecordAndLogUse();
+ // Returns true if the current profile has greater frescocency than the
+ // |other|. Frescocency is a combination of validation score and frecency to
+ // determine the relevance of the profile. Frescocency is a total order: it
+ // puts all the valid profiles before the invalid ones, and uses frecency
+ // (another total order) in case of tie. Please see
+ // AutofillDataModel::HasGreaterFrecencyThan.
+ bool HasGreaterFrescocencyThan(const AutofillProfile* other,
+ base::Time comparison_time,
+ bool use_client_validation,
+ bool use_server_validation) const;
+
+ // Returns false if the profile has any invalid field, according to the client
+ // source of validation.
+ bool IsValidByClient() const;
+ // Returns false if the profile has any invalid field, according to the server
+ // source of validation.
+ bool IsValidByServer() const;
+
const base::Time& previous_use_date() const { return previous_use_date_; }
void set_previous_use_date(const base::Time& time) {
previous_use_date_ = time;
@@ -235,7 +234,7 @@ class AutofillProfile : public AutofillDataModel {
// Returns the validity state of the specified autofill type.
ValidityState GetValidityState(ServerFieldType type,
- ValidationSource source) const;
+ ValidationSource source) const override;
// Sets the validity state of the specified autofill type.
// This should only be called from autofill profile validtion API or in tests.
@@ -275,6 +274,10 @@ class AutofillProfile : public AutofillDataModel {
is_client_validity_states_updated_ = is_client_validity_states_updated;
}
+ // Check for the validity of the data. Leave the field empty if the data is
+ // invalid and the relevant feature is enabled.
+ bool ShouldSkipFillingOrSuggesting(ServerFieldType type) const override;
+
base::WeakPtr<const AutofillProfile> GetWeakPtr() const {
return weak_ptr_factory_.GetWeakPtr();
}
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc b/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
index f54c16134a2..0d6a67f24a8 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
@@ -5,10 +5,14 @@
#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "base/guid.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/proto/autofill_sync.pb.h"
@@ -54,72 +58,40 @@ std::unique_ptr<EntityData> CreateEntityDataFromAutofillProfile(
entry.is_client_validity_states_updated());
// Set repeated fields.
- if (entry.HasRawInfo(NAME_FIRST)) {
- specifics->add_name_first(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FIRST))));
- }
- if (entry.HasRawInfo(NAME_MIDDLE)) {
- specifics->add_name_middle(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_MIDDLE))));
- }
- if (entry.HasRawInfo(NAME_LAST)) {
- specifics->add_name_last(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_LAST))));
- }
- if (entry.HasRawInfo(NAME_FULL)) {
- specifics->add_name_full(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FULL))));
- }
- if (entry.HasRawInfo(EMAIL_ADDRESS)) {
- specifics->add_email_address(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(EMAIL_ADDRESS))));
- }
- if (entry.HasRawInfo(PHONE_HOME_WHOLE_NUMBER)) {
- specifics->add_phone_home_whole_number(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(PHONE_HOME_WHOLE_NUMBER))));
- }
+ specifics->add_name_first(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FIRST))));
+ specifics->add_name_middle(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_MIDDLE))));
+ specifics->add_name_last(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_LAST))));
+ specifics->add_name_full(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FULL))));
+ specifics->add_email_address(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(EMAIL_ADDRESS))));
+ specifics->add_phone_home_whole_number(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(PHONE_HOME_WHOLE_NUMBER))));
// Set simple single-valued fields.
- if (entry.HasRawInfo(COMPANY_NAME)) {
- specifics->set_company_name(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(COMPANY_NAME))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_CITY)) {
- specifics->set_address_home_city(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_CITY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_STATE)) {
- specifics->set_address_home_state(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STATE))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_ZIP)) {
- specifics->set_address_home_zip(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_ZIP))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_SORTING_CODE)) {
- specifics->set_address_home_sorting_code(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)) {
- specifics->set_address_home_dependent_locality(TruncateUTF8(
- UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_COUNTRY)) {
- specifics->set_address_home_country(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_COUNTRY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_STREET_ADDRESS)) {
- specifics->set_address_home_street_address(TruncateUTF8(
- UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_LINE1)) {
- specifics->set_address_home_line1(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE1))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_LINE2)) {
- specifics->set_address_home_line2(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE2))));
- }
+ specifics->set_company_name(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(COMPANY_NAME))));
+ specifics->set_address_home_city(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_CITY))));
+ specifics->set_address_home_state(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STATE))));
+ specifics->set_address_home_zip(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_ZIP))));
+ specifics->set_address_home_sorting_code(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
+ specifics->set_address_home_dependent_locality(TruncateUTF8(
+ UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
+ specifics->set_address_home_country(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_COUNTRY))));
+ specifics->set_address_home_street_address(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
+ specifics->set_address_home_line1(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE1))));
+ specifics->set_address_home_line2(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE2))));
return entity_data;
}
@@ -141,78 +113,65 @@ std::unique_ptr<AutofillProfile> CreateAutofillProfileFromSpecifics(
specifics.validity_state_bitfield());
// Set repeated fields.
- if (specifics.name_first_size() > 0) {
- profile->SetRawInfo(NAME_FIRST, UTF8ToUTF16(specifics.name_first(0)));
- }
- if (specifics.name_middle_size() > 0) {
- profile->SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(specifics.name_middle(0)));
- }
- if (specifics.name_last_size() > 0) {
- profile->SetRawInfo(NAME_LAST, UTF8ToUTF16(specifics.name_last(0)));
- }
+ profile->SetRawInfo(NAME_FIRST, UTF8ToUTF16(specifics.name_first_size()
+ ? specifics.name_first(0)
+ : std::string()));
+ profile->SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(specifics.name_middle_size()
+ ? specifics.name_middle(0)
+ : std::string()));
+ profile->SetRawInfo(
+ NAME_LAST, UTF8ToUTF16(specifics.name_last_size() ? specifics.name_last(0)
+ : std::string()));
+ profile->SetRawInfo(
+ EMAIL_ADDRESS,
+ UTF8ToUTF16(specifics.email_address_size() ? specifics.email_address(0)
+ : std::string()));
+ profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+ UTF8ToUTF16(specifics.phone_home_whole_number_size()
+ ? specifics.phone_home_whole_number(0)
+ : std::string()));
+
+ // Older versions don't have a separate full name; don't overwrite full name
+ // in this case.
if (specifics.name_full_size() > 0) {
profile->SetRawInfo(NAME_FULL, UTF8ToUTF16(specifics.name_full(0)));
}
- if (specifics.email_address_size() > 0) {
- profile->SetRawInfo(EMAIL_ADDRESS, UTF8ToUTF16(specifics.email_address(0)));
- }
- if (specifics.phone_home_whole_number_size() > 0) {
- profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
- UTF8ToUTF16(specifics.phone_home_whole_number(0)));
- }
// Set simple single-valued fields.
- if (specifics.has_company_name()) {
- profile->SetRawInfo(COMPANY_NAME, UTF8ToUTF16(specifics.company_name()));
- }
- if (specifics.has_address_home_city()) {
- profile->SetRawInfo(ADDRESS_HOME_CITY,
- UTF8ToUTF16(specifics.address_home_city()));
- }
- if (specifics.has_address_home_state()) {
- profile->SetRawInfo(ADDRESS_HOME_STATE,
- UTF8ToUTF16(specifics.address_home_state()));
- }
- if (specifics.has_address_home_zip()) {
- profile->SetRawInfo(ADDRESS_HOME_ZIP,
- UTF8ToUTF16(specifics.address_home_zip()));
- }
- if (specifics.has_address_home_sorting_code()) {
- profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE,
- UTF8ToUTF16(specifics.address_home_sorting_code()));
- }
- if (specifics.has_address_home_dependent_locality()) {
- profile->SetRawInfo(
- ADDRESS_HOME_DEPENDENT_LOCALITY,
- UTF8ToUTF16(specifics.address_home_dependent_locality()));
- }
- if (specifics.has_address_home_country()) {
- // Update the country field, which can contain either a country code (if set
- // by a newer version of Chrome), or a country name (if set by an older
- // version of Chrome).
- // TODO(jkrcal): Move this migration logic into Address::SetRawInfo()?
- base::string16 country_name_or_code =
- base::ASCIIToUTF16(specifics.address_home_country());
- std::string country_code =
- CountryNames::GetInstance()->GetCountryCode(country_name_or_code);
- profile->SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16(country_code));
- }
- if (specifics.has_address_home_line1()) {
+ profile->SetRawInfo(COMPANY_NAME, UTF8ToUTF16(specifics.company_name()));
+ profile->SetRawInfo(ADDRESS_HOME_CITY,
+ UTF8ToUTF16(specifics.address_home_city()));
+ profile->SetRawInfo(ADDRESS_HOME_STATE,
+ UTF8ToUTF16(specifics.address_home_state()));
+ profile->SetRawInfo(ADDRESS_HOME_ZIP,
+ UTF8ToUTF16(specifics.address_home_zip()));
+ profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE,
+ UTF8ToUTF16(specifics.address_home_sorting_code()));
+ profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ UTF8ToUTF16(specifics.address_home_dependent_locality()));
+
+ // Update the country field, which can contain either a country code (if set
+ // by a newer version of Chrome), or a country name (if set by an older
+ // version of Chrome).
+ // TODO(jkrcal): Move this migration logic into Address::SetRawInfo()?
+ base::string16 country_name_or_code =
+ base::ASCIIToUTF16(specifics.address_home_country());
+ std::string country_code =
+ CountryNames::GetInstance()->GetCountryCode(country_name_or_code);
+ profile->SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16(country_code));
+
+ // Set either the deprecated subparts (line1 & line2) or the full address
+ // (street_address) if it is present. This is needed because all the address
+ // fields are backed by the same storage.
+ if (specifics.has_address_home_street_address()) {
+ profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ UTF8ToUTF16(specifics.address_home_street_address()));
+ } else {
profile->SetRawInfo(ADDRESS_HOME_LINE1,
UTF8ToUTF16(specifics.address_home_line1()));
- }
- if (specifics.has_address_home_line2()) {
profile->SetRawInfo(ADDRESS_HOME_LINE2,
UTF8ToUTF16(specifics.address_home_line2()));
}
- // Set first the deprecated subparts (line1 & line2) and only after that the
- // full address (street_address) so that the latter wins in case of conflict.
- // This is needed because all the address fields are backed by the same
- // storage.
- if (specifics.has_address_home_street_address()) {
- profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
- UTF8ToUTF16(specifics.address_home_street_address()));
- }
// This has to be the last one, otherwise setting the raw info may change it.
profile->set_is_client_validity_states_updated(
@@ -235,4 +194,28 @@ std::string GetStorageKeyFromAutofillProfileSpecifics(
return specifics.guid();
}
+bool IsLocalProfileEqualToServerProfile(
+ const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+ const AutofillProfile& local_profile,
+ const std::string& app_locale) {
+ AutofillProfileComparator comparator(app_locale);
+ for (const auto& server_profile : server_profiles) {
+ // The same logic as when deciding whether to convert into a new profile in
+ // PersonalDataManager::MergeServerAddressesIntoProfiles.
+ if (comparator.AreMergeable(*server_profile, local_profile) &&
+ (!local_profile.IsVerified() || !server_profile->IsVerified())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin origin) {
+ UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.AddOrUpdateOrigin", origin);
+}
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin) {
+ UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.DeleteOrigin", origin);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util.h b/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
index a43595262bf..87d677a7155 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
@@ -7,6 +7,8 @@
#include <memory>
#include <string>
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include <vector>
namespace syncer {
struct EntityData;
@@ -40,6 +42,24 @@ std::string GetStorageKeyFromAutofillProfile(const AutofillProfile& entry);
std::string GetStorageKeyFromAutofillProfileSpecifics(
const sync_pb::AutofillProfileSpecifics& specifics);
+// TODO(crbug.com/904390): Remove when the investigation is over.
+bool IsLocalProfileEqualToServerProfile(
+ const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+ const AutofillProfile& local_profile,
+ const std::string& app_locale);
+
+// TODO(crbug.com/904390): Remove when the investigation is over.
+enum class AutofillProfileSyncChangeOrigin {
+ kTrulyLocal = 0,
+ kConvertedLocal = 1,
+ kIncrementalRemote = 2,
+ kInitial = 3,
+ kMaxValue = kInitial,
+};
+void ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin origin);
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin);
+
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_SYNC_UTIL_H_
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
index b9677d58b27..3925a7ee402 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
@@ -133,7 +133,7 @@ TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile) {
entity_data->specifics.autofill_profile().SerializeAsString());
}
-// Test that fields not set for the input are also not set on the output.
+// Test that fields not set for the input are empty in the output.
TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile_Empty) {
AutofillProfile profile(kGuid, std::string());
ASSERT_FALSE(profile.HasRawInfo(NAME_FULL));
@@ -141,8 +141,10 @@ TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile_Empty) {
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
- EXPECT_EQ(0, entity_data->specifics.autofill_profile().name_full_size());
- EXPECT_FALSE(entity_data->specifics.autofill_profile().has_company_name());
+ EXPECT_EQ(1, entity_data->specifics.autofill_profile().name_full_size());
+ EXPECT_EQ("", entity_data->specifics.autofill_profile().name_full(0));
+ EXPECT_TRUE(entity_data->specifics.autofill_profile().has_company_name());
+ EXPECT_EQ("", entity_data->specifics.autofill_profile().company_name());
}
// Test that long fields get trimmed.
diff --git a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
index 2a045233d55..539a255e776 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -15,12 +15,14 @@
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/autofill_metadata.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/form_field_data.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -306,25 +308,21 @@ TEST(AutofillProfileTest, CreateInferredLabelsI18n_FR) {
"antoine@exemple.com", "Exemple Inc", "8 Rue de Londres",
"", "Paris", "", "75009", "FR", "+33 (0) 1 42 68 53 00");
profiles.back()->set_language_code("fr_FR");
- profiles.back()->SetInfo(
- AutofillType(ADDRESS_HOME_SORTING_CODE), UTF8ToUTF16("CEDEX"), "en-US");
static const char* kExpectedLabels[] = {
"",
"Antoine de Saint-Exupéry",
"Antoine de Saint-Exupéry, 8 Rue de Londres",
"Antoine de Saint-Exupéry, 8 Rue de Londres, Paris",
"Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
- "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris CEDEX",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
};
std::vector<base::string16> labels;
@@ -1058,7 +1056,7 @@ TEST(AutofillProfileTest,
AutofillProfile b = a;
b.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Märion"));
b.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16("Mitchéll"));
- b.SetRawInfo(NAME_LAST,UTF8ToUTF16("Morrison"));
+ b.SetRawInfo(NAME_LAST, UTF8ToUTF16("Morrison"));
b.SetRawInfo(NAME_FULL, UTF8ToUTF16(""));
EXPECT_TRUE(a.SaveAdditionalInfo(b, "en-US"));
@@ -1130,7 +1128,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
profile.SetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// It's based on the server side validation.
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE1));
@@ -1144,8 +1143,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_HOME_CITY_CODE, AutofillProfile::INVALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_HOME_CITY_CODE, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE2));
EXPECT_EQ(true, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1157,7 +1156,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
profile.SetValidityState(PHONE_BILLING_COUNTRY_CODE,
- AutofillProfile::INVALID, AutofillProfile::SERVER);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE2));
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1167,8 +1167,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
}
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_BILLING_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_BILLING_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_CITY_CODE));
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1179,8 +1179,9 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
}
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_BILLING_WHOLE_NUMBER, AutofillProfile::VALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_BILLING_WHOLE_NUMBER,
+ AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false,
profile.IsAnInvalidPhoneNumber(PHONE_BILLING_COUNTRY_CODE));
@@ -1196,52 +1197,55 @@ TEST(AutofillProfileTest, ValidityStatesClients) {
AutofillProfile profile;
// The default validity state should be UNVALIDATED.
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// Make sure setting the validity state works.
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- EXPECT_EQ(AutofillProfile::VALID,
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, ValidityStatesServer) {
AutofillProfile profile;
+ EXPECT_TRUE(test::GetFullProfile().IsValidByServer());
// The default validity state should be UNVALIDATED.
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::SERVER));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::SERVER));
// Make sure setting the validity state works.
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::SERVER);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::SERVER);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::SERVER);
- EXPECT_EQ(AutofillProfile::VALID,
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::SERVER);
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::SERVER));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::SERVER));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::SERVER));
+ AutofillDataModel::SERVER));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::SERVER));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::SERVER));
+ EXPECT_FALSE(profile.IsValidByServer());
}
TEST(AutofillProfileTest, ValidityStates_ClientUnsupportedTypes) {
@@ -1249,26 +1253,26 @@ TEST(AutofillProfileTest, ValidityStates_ClientUnsupportedTypes) {
// The validity state of unsupported types should be UNSUPPORTED.
EXPECT_EQ(
- AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::CLIENT));
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::CLIENT));
// Make sure setting the validity state of an unsupported type does nothing.
- profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_LINE2, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE2, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE1,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE2,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ EXPECT_EQ(
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE2, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Country) {
@@ -1278,18 +1282,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Country) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01
EXPECT_EQ(1, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10
EXPECT_EQ(2, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11
EXPECT_EQ(3, profile.GetClientValidityBitfieldValue());
}
@@ -1301,18 +1305,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_State) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b0100
EXPECT_EQ(4, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b1000
EXPECT_EQ(8, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b1100
EXPECT_EQ(12, profile.GetClientValidityBitfieldValue());
}
@@ -1324,18 +1328,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Zip) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b010000
EXPECT_EQ(16, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b100000
EXPECT_EQ(32, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b110000
EXPECT_EQ(48, profile.GetClientValidityBitfieldValue());
}
@@ -1347,18 +1351,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_City) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01000000
EXPECT_EQ(64, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10000000
EXPECT_EQ(128, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11000000
EXPECT_EQ(192, profile.GetClientValidityBitfieldValue());
}
@@ -1371,20 +1375,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_DependentLocality) {
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::EMPTY, AutofillDataModel::CLIENT);
// 0b0100000000
EXPECT_EQ(256, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::VALID, AutofillDataModel::CLIENT);
// 0b1000000000
EXPECT_EQ(512, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b1100000000
EXPECT_EQ(768, profile.GetClientValidityBitfieldValue());
}
@@ -1396,18 +1398,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Email) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b010000000000
EXPECT_EQ(1024, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b100000000000
EXPECT_EQ(2048, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b110000000000
EXPECT_EQ(3072, profile.GetClientValidityBitfieldValue());
}
@@ -1419,18 +1421,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Phone) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01000000000000
EXPECT_EQ(4096, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10000000000000
EXPECT_EQ(8192, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11000000000000
EXPECT_EQ(12288, profile.GetClientValidityBitfieldValue());
}
@@ -1442,39 +1444,41 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Mixed) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b01110011010010
EXPECT_EQ(7378, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b11001110101101
EXPECT_EQ(13229, profile.GetClientValidityBitfieldValue());
}
@@ -1485,24 +1489,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Country) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01
profile.SetClientValidityFromBitfieldValue(1);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10
profile.SetClientValidityFromBitfieldValue(2);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11
profile.SetClientValidityFromBitfieldValue(3);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_State) {
@@ -1511,24 +1519,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_State) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b0100
profile.SetClientValidityFromBitfieldValue(4);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1000
profile.SetClientValidityFromBitfieldValue(8);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1100
profile.SetClientValidityFromBitfieldValue(12);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Zip) {
@@ -1537,24 +1549,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Zip) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b010000
profile.SetClientValidityFromBitfieldValue(16);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b100000
profile.SetClientValidityFromBitfieldValue(32);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b110000
profile.SetClientValidityFromBitfieldValue(48);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_City) {
@@ -1563,24 +1579,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_City) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01000000
profile.SetClientValidityFromBitfieldValue(64);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10000000
profile.SetClientValidityFromBitfieldValue(128);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11000000
profile.SetClientValidityFromBitfieldValue(192);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest,
@@ -1590,24 +1610,28 @@ TEST(AutofillProfileTest,
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b0100000000
profile.SetClientValidityFromBitfieldValue(256);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1000000000
profile.SetClientValidityFromBitfieldValue(512);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1100000000
profile.SetClientValidityFromBitfieldValue(768);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Email) {
@@ -1616,24 +1640,25 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Email) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b010000000000
profile.SetClientValidityFromBitfieldValue(1024);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b100000000000
profile.SetClientValidityFromBitfieldValue(2048);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b110000000000
profile.SetClientValidityFromBitfieldValue(3072);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Phone) {
@@ -1642,24 +1667,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Phone) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01000000000000
profile.SetClientValidityFromBitfieldValue(4096);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10000000000000
profile.SetClientValidityFromBitfieldValue(8192);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11000000000000
profile.SetClientValidityFromBitfieldValue(12288);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Mixed) {
@@ -1671,51 +1700,52 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Mixed) {
// 0b01110011010010
profile.SetClientValidityFromBitfieldValue(7378);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b11001110101101
profile.SetClientValidityFromBitfieldValue(13229);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, GetMetadata) {
@@ -1835,4 +1865,163 @@ TEST(AutofillProfileTest, EqualsForClientValidationPurpose) {
EXPECT_TRUE(profile.EqualsForClientValidationPurpose(profile3));
}
+// Tests that the skip decision is made correctly.
+TEST(AutofillProfileTest, ShouldSkipFillingOrSuggesting) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::UNSUPPORTED,
+ AutofillProfile::CLIENT);
+
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::ASCIIToUTF16(""));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::ASCIIToUTF16("CA"));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+}
+
+enum Expectation { GREATER, LESS, EQUAL };
+
+struct HasGreaterFrescocencyTestCase {
+ const AutofillDataModel::ValidityState client_validity_state_a;
+ const AutofillDataModel::ValidityState server_validity_state_a;
+ const AutofillDataModel::ValidityState client_validity_state_b;
+ const AutofillDataModel::ValidityState server_validity_state_b;
+
+ const bool use_client_validation;
+ const bool use_server_validation;
+ Expectation expectation;
+};
+
+class HasGreaterFrescocencyTest
+ : public testing::TestWithParam<HasGreaterFrescocencyTestCase> {};
+
+TEST_P(HasGreaterFrescocencyTest, HasGreaterFrescocency) {
+ auto test_case = GetParam();
+ AutofillProfile profile_a("00000000-0000-0000-0000-000000000001", "");
+ AutofillProfile profile_b("00000000-0000-0000-0000-000000000002", "");
+
+ profile_a.SetValidityState(EMAIL_ADDRESS, test_case.client_validity_state_a,
+ AutofillDataModel::CLIENT);
+ profile_a.SetValidityState(ADDRESS_HOME_ZIP,
+ test_case.server_validity_state_a,
+ AutofillDataModel::SERVER);
+
+ profile_b.SetValidityState(ADDRESS_HOME_CITY,
+ test_case.client_validity_state_b,
+ AutofillDataModel::CLIENT);
+ profile_b.SetValidityState(PHONE_HOME_NUMBER,
+ test_case.server_validity_state_b,
+ AutofillDataModel::SERVER);
+
+ base::Time now = base::Time::Now();
+
+ if (test_case.expectation == EQUAL) {
+ EXPECT_EQ(profile_a.HasGreaterFrecencyThan(&profile_b, now),
+ profile_a.HasGreaterFrescocencyThan(
+ &profile_b, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+ return;
+ }
+
+ EXPECT_EQ(test_case.expectation == GREATER,
+ profile_a.HasGreaterFrescocencyThan(
+ &profile_b, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+ EXPECT_NE(test_case.expectation == GREATER,
+ profile_b.HasGreaterFrescocencyThan(
+ &profile_a, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ AutofillProfileTest,
+ HasGreaterFrescocencyTest,
+ testing::Values(
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED, false,
+ false, EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, false,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, true,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, false, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED, false,
+ true, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, true, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::VALID, true,
+ true, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, true, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, true, true,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::INVALID, AutofillDataModel::VALID, true, false,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::VALID, true,
+ false, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, true, false,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID, true, false,
+ GREATER}));
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc b/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
index 15b2d5926e4..8adf7430917 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
@@ -41,33 +41,34 @@ using ::i18n::addressinput::MISMATCHING_VALUE;
using ::i18n::addressinput::MISSING_REQUIRED_FIELD;
using ::i18n::addressinput::UNEXPECTED_FIELD;
using ::i18n::addressinput::UNKNOWN_VALUE;
+using ::i18n::addressinput::UNSUPPORTED_FIELD;
using ::i18n::phonenumbers::PhoneNumberUtil;
const AddressField kFields[] = {COUNTRY, ADMIN_AREA, LOCALITY,
DEPENDENT_LOCALITY, POSTAL_CODE};
-const AddressProblem kProblems[] = {UNEXPECTED_FIELD, MISSING_REQUIRED_FIELD,
- UNKNOWN_VALUE, INVALID_FORMAT,
- MISMATCHING_VALUE};
+const AddressProblem kProblems[] = {UNEXPECTED_FIELD, MISSING_REQUIRED_FIELD,
+ UNKNOWN_VALUE, INVALID_FORMAT,
+ MISMATCHING_VALUE, UNSUPPORTED_FIELD};
// If the |address_field| is valid, set the validity state of the
// |address_field| in the |profile| to the |state| and return true.
// Otherwise, return false.
bool SetValidityStateForAddressField(const AutofillProfile* profile,
AddressField address_field,
- AutofillProfile::ValidityState state) {
+ AutofillDataModel::ValidityState state) {
ServerFieldType server_field = i18n::TypeForField(address_field,
/*billing=*/false);
if (server_field == UNKNOWN_TYPE)
return false;
DCHECK(profile);
- profile->SetValidityState(server_field, state, AutofillProfile::CLIENT);
+ profile->SetValidityState(server_field, state, AutofillDataModel::CLIENT);
return true;
}
// Set the validity state of all address fields in the |profile| to |state|.
void SetAllAddressValidityStates(const AutofillProfile* profile,
- AutofillProfile::ValidityState state) {
+ AutofillDataModel::ValidityState state) {
DCHECK(profile);
for (auto field : kFields)
SetValidityStateForAddressField(profile, field, state);
@@ -110,54 +111,56 @@ void InitializeAddressFromProfile(const AutofillProfile& profile,
void SetEmptyValidityIfEmpty(const AutofillProfile* profile) {
if (profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty())
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_STATE).empty())
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_CITY).empty())
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY).empty())
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::EMPTY, AutofillProfile::CLIENT);
+ AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_ZIP).empty())
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
}
void SetInvalidIfUnvalidated(const AutofillProfile* profile) {
if (profile->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
}
@@ -166,58 +169,62 @@ void MaybeApplyValidToFields(const AutofillProfile* profile) {
// subregion can only be validated if its super-region is VALID. In this
// case, it's VALID if it has not been marked as INVALID or EMPTY.
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED &&
- profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::VALID) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED &&
+ profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::VALID) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED &&
- profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::VALID) {
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED &&
+ profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::VALID) {
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::VALID, AutofillProfile::CLIENT);
+ AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
// ZIP only depends on COUNTRY. If it's not so far marked as INVALID or EMPTY,
// then it's VALID.
- if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
}
void ApplyValidOnlyIfAllChildrenNotInvalid(const AutofillProfile* profile) {
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID &&
- profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID &&
+ profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
}
@@ -239,7 +246,7 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
DCHECK(address_validator);
DCHECK(profile);
- SetAllAddressValidityStates(profile, AutofillProfile::UNVALIDATED);
+ SetAllAddressValidityStates(profile, AutofillDataModel::UNVALIDATED);
if (!base::ContainsValue(
CountryDataMap::GetInstance()->country_codes(),
@@ -247,13 +254,14 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
// If the country code is not in the database, the country code and the
// profile are invalid, and other fields cannot be validated, because it is
// unclear which, if any, rule should apply.
- SetValidityStateForAddressField(profile, COUNTRY, AutofillProfile::INVALID);
+ SetValidityStateForAddressField(profile, COUNTRY,
+ AutofillDataModel::INVALID);
SetEmptyValidityIfEmpty(profile);
return AddressValidator::SUCCESS;
}
// The COUNTRY was already listed in the CountryDataMap, therefore it's valid.
- SetValidityStateForAddressField(profile, COUNTRY, AutofillProfile::VALID);
+ SetValidityStateForAddressField(profile, COUNTRY, AutofillDataModel::VALID);
AddressData address;
InitializeAddressFromProfile(*profile, &address);
@@ -262,9 +270,25 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
AddressValidator::Status status =
address_validator->ValidateAddress(address, GetFilter(), &problems);
- for (auto problem : problems)
- SetValidityStateForAddressField(profile, problem.first,
- AutofillProfile::INVALID);
+ // The address fields for which validation is not supported by the metadata
+ // will be marked as UNSUPPORTED_FIELDs. These fields should be treated like
+ // VALID fields to stay consistent. INVALID_FORMATs, MISMATCHING_VALUEs or
+ // UNKNOWN_VALUEs are INVALID. MISSING_REQUIRED_FIELD would be marked as EMPTY
+ // along other empty fields. UNEXPECTED_FIELD would mean that there is also no
+ // metadata for validation, therefore, they are also UNSUPPORTED_FIELDs, and
+ // thus they would be treated as VALID fields.
+ for (auto problem : problems) {
+ if (problem.second == UNSUPPORTED_FIELD) {
+ SetValidityStateForAddressField(profile, problem.first,
+ AutofillDataModel::VALID);
+
+ } else if (problem.second == INVALID_FORMAT ||
+ problem.second == MISMATCHING_VALUE ||
+ problem.second == UNKNOWN_VALUE) {
+ SetValidityStateForAddressField(profile, problem.first,
+ AutofillDataModel::INVALID);
+ }
+ }
SetEmptyValidityIfEmpty(profile);
@@ -301,24 +325,24 @@ void ValidateAddressStrictly(const AutofillProfile* profile,
void ValidateEmailAddress(const AutofillProfile* profile) {
const base::string16& email = profile->GetRawInfo(EMAIL_ADDRESS);
if (email.empty()) {
- profile->SetValidityState(EMAIL_ADDRESS, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(EMAIL_ADDRESS, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
return;
}
profile->SetValidityState(EMAIL_ADDRESS,
autofill::IsValidEmailAddress(email)
- ? AutofillProfile::VALID
- : AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ ? AutofillDataModel::VALID
+ : AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
void ValidatePhoneNumber(const AutofillProfile* profile) {
const std::string& phone_number =
base::UTF16ToUTF8(profile->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
if (phone_number.empty()) {
- profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
return;
}
@@ -329,8 +353,8 @@ void ValidatePhoneNumber(const AutofillProfile* profile) {
// If the country code is not in the database, the phone number cannot be
// validated.
profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::CLIENT);
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
return;
}
@@ -338,9 +362,9 @@ void ValidatePhoneNumber(const AutofillProfile* profile) {
profile->SetValidityState(
PHONE_HOME_WHOLE_NUMBER,
phone_util->IsPossibleNumberForString(phone_number, country_code)
- ? AutofillProfile::VALID
- : AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ ? AutofillDataModel::VALID
+ : AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
} // namespace profile_validation_util
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
index 6b609ed9125..59a29b7a650 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
@@ -84,24 +84,24 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForCanada) {
// Postal Code: "H3B 2T9", Country Code: "CA",
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// For Canada, there is no rule and data to validate the city.
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// Canada doesn't have a dependent locality. It's not filled, and yet the
// profile is valid.
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -112,23 +112,23 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The zip, the state and the city can't be validated, because we don't know
// the country, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -138,23 +138,23 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The zip, the state and the city can't be validated, because we don't know
// the country, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -165,21 +165,21 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaNotExists) {
@@ -188,23 +188,23 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaNotExists) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because we don't know the state, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyAdminArea) {
@@ -212,23 +212,23 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyAdminArea) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because we don't know the state, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaFullName) {
@@ -237,21 +237,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaFullName) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaLowerCase) {
@@ -260,21 +260,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaLowerCase) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -284,21 +284,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -313,21 +313,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipNoSpace) {
@@ -336,21 +336,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipNoSpace) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipLowerCase) {
@@ -360,21 +360,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipLowerCase) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_InvalidZip) {
@@ -383,21 +383,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_InvalidZip) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyZip) {
@@ -405,21 +405,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyZip) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyCity) {
@@ -430,21 +430,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyCity) {
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateFullProfile_EmptyFields) {
@@ -455,21 +455,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullProfile_EmptyFields) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForChina) {
@@ -480,21 +480,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForChina) {
AutofillProfile profile(autofill::test::GetFullValidProfileForChina());
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -504,25 +504,25 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(invalid_city));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The city which is the only dependent field on state is invalid, in the
// strict validation the state would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -535,25 +535,25 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(city));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The city which is the only dependent field on state is invalid, in the
// strict validation the state would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -568,21 +568,21 @@ TEST_F(AutofillProfileValidationUtilTest,
base::UTF8ToUTF16(district));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -593,21 +593,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -619,23 +619,23 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, base::UTF8ToUTF16("赫"));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The dependent locality which is the only dependent field on city is
// invalid, in the strict validation the city would also be invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -648,23 +648,23 @@ TEST_F(AutofillProfileValidationUtilTest,
base::UTF8ToUTF16("蒙城县"));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The only that depend on city (dependent locality) is invalid,
// in the strict validation city would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_FullValidProfile) {
@@ -672,18 +672,18 @@ TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_FullValidProfile) {
// Country Code: "CA", Phone Number: "15141112233"
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_EmptyPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::string16());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -694,9 +694,9 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -708,103 +708,103 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::string16());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_InvalidPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("151411122334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("1(514)111-22-334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("251411122334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("Hello!"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_ValidPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("5141112233"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("514-111-2233"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("1(514)111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 514 111 22 33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 (514)-111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("(514)-111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 650 GOO OGLE"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("778 111 22 33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_FullValidProfile) {
@@ -812,16 +812,16 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_FullValidProfile) {
// Email: "alice@wonderland.ca"
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_EmptyEmailAddress) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::string16());
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -829,24 +829,24 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("Hello!"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice.wonderland"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice@"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice@=wonderland.com"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_ValidEmailAddress) {
@@ -854,40 +854,40 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_ValidEmailAddress) {
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice@wonderland"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice@wonderland.fiction"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice+cat@wonderland.fiction.book"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateProfile_FullValidProfile) {
// This is a full valid profile:
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateProfileTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -896,20 +896,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("ABC 123"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -918,20 +924,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("33"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -940,20 +952,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("fakeaddress"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -968,33 +986,33 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
// The fields that depend on country (state and zip) are both invalid,
// therefore in the strict validation this is considered as invalid.
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The state is not a Chinese state, so it's considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because the state value is not
// valid, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
// The zip is not a Chinese one, therefore it's invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1010,35 +1028,35 @@ TEST_F(AutofillProfileValidationUtilTest,
// The fields that depend on Country (state and zip) are both invalid,
// therefore in the strict validation this is considered as invalid.
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The state is not a Canadian state, so it's considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// We can't validate city, because state is not valid, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality is not a Canadian field, so it's considered as
// invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
// The zip is not a Canadian one, therefore it's invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1052,34 +1070,34 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The only field that depends on state (city) is invalid, in the strict
// validation this makes state also invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city is in another province.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because the city value is not
// valid, in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1093,33 +1111,33 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// City can't be validated, because the state is missing, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator.cc b/chromium/components/autofill/core/browser/autofill_profile_validator.cc
index 35d0a46aa30..6a2744fc227 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator.cc
@@ -14,7 +14,6 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
-#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_validation_util.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
@@ -39,14 +38,13 @@ AutofillProfileValidator::ValidationRequest::ValidationRequest(
base::WeakPtr<const AutofillProfile> profile,
autofill::AddressValidator* validator,
AutofillProfileValidatorCallback on_validated)
- : profile_(profile),
+ : profile_(*profile),
validator_(validator),
on_validated_(std::move(on_validated)),
has_responded_(false),
weak_factory_(this) {
on_timeout_.Reset(base::BindOnce(&ValidationRequest::OnRulesLoaded,
weak_factory_.GetWeakPtr()));
- DCHECK(profile_);
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, on_timeout_.callback(),
base::TimeDelta::FromSeconds(kRulesLoadingTimeoutSeconds));
@@ -63,12 +61,8 @@ void AutofillProfileValidator::ValidationRequest::OnRulesLoaded() {
return;
has_responded_ = true;
- if (!profile_)
- return;
-
- profile_validation_util::ValidateProfile(profile_.get(), validator_);
-
- std::move(on_validated_).Run(profile_.get());
+ profile_validation_util::ValidateProfile(&profile_, validator_);
+ std::move(on_validated_).Run(&profile_);
}
AutofillProfileValidator::AutofillProfileValidator(
@@ -102,7 +96,7 @@ void AutofillProfileValidator::StartProfileValidation(
// Start loading the rules for the region. If the rules were already in the
// process of being loaded, this call will do nothing.
- address_validator_.LoadRules(region_code);
+ LoadRulesForRegion(region_code);
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator.h b/chromium/components/autofill/core/browser/autofill_profile_validator.h
index 52d88a8d677..2253b4d4498 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator.h
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator.h
@@ -14,14 +14,13 @@
#include "base/cancelable_callback.h"
#include "base/macros.h"
+#include "components/autofill/core/browser/autofill_profile.h"
#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
namespace autofill {
-class AutofillProfile;
-
using AutofillProfileValidatorCallback =
base::OnceCallback<void(const AutofillProfile*)>;
@@ -45,6 +44,13 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
void StartProfileValidation(const AutofillProfile* profile,
AutofillProfileValidatorCallback cb);
+ protected:
+ // Starts loading the rules for the specified |region_code|.
+ virtual void LoadRulesForRegion(const std::string& region_code);
+
+ // The address validator used to load rules.
+ AddressValidator address_validator_;
+
private:
// ValidationRequest loads Rules from the server and validates various fields
// in an autofill profile.
@@ -60,7 +66,7 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
void OnRulesLoaded();
private:
- base::WeakPtr<const AutofillProfile> profile_;
+ AutofillProfile profile_;
// Not owned. Outlives this object.
AddressValidator* validator_;
@@ -78,9 +84,6 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
// Returns whether the rules for the specified |region_code| is loaded.
bool AreRulesLoadedForRegion(const std::string& region_code);
- // Starts loading the rules for the specified |region_code|.
- void LoadRulesForRegion(const std::string& region_code);
-
// Implementation of the LoadRulesListener interface. Called when the address
// rules for the |region_code| have finished loading.
void OnAddressValidationRulesLoaded(const std::string& region_code,
@@ -90,9 +93,6 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
std::map<std::string, std::vector<std::unique_ptr<ValidationRequest>>>
pending_requests_;
- // The address validator used to load rules.
- AddressValidator address_validator_;
-
DISALLOW_COPY_AND_ASSIGN(AutofillProfileValidator);
};
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
index 72a48f3fce4..34203afe788 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
@@ -87,7 +87,7 @@ class AutofillProfileValidatorTest : public testing::Test {
for (auto expectation : expected_validity_) {
EXPECT_EQ(expectation.second,
profile->GetValidityState(expectation.first,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
}
@@ -101,7 +101,7 @@ class AutofillProfileValidatorTest : public testing::Test {
AutofillProfileValidatorCallback onvalidated_cb_;
- std::vector<std::pair<ServerFieldType, AutofillProfile::ValidityState>>
+ std::vector<std::pair<ServerFieldType, AutofillDataModel::ValidityState>>
expected_validity_;
private:
@@ -122,11 +122,14 @@ TEST_F(AutofillProfileValidatorTest, ValidateFullValidProfile_RulesNotLoaded) {
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -143,11 +146,11 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_RulesLoaded) {
EXPECT_EQ(true, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -164,11 +167,12 @@ TEST_F(AutofillProfileValidatorTest,
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::UNVALIDATED},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::UNVALIDATED},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -184,11 +188,11 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_RuleNotExists) {
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::UNVALIDATED},
- {ADDRESS_HOME_ZIP, AutofillProfile::UNVALIDATED},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::UNVALIDATED},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::UNVALIDATED},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -203,11 +207,12 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_EmptyCountryCode) {
// Set up the test expectations.
// The phone is validated for the US.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::UNVALIDATED},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::UNVALIDATED},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -220,11 +225,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidPhone) {
base::UTF8ToUTF16("Invalid Phone"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -236,11 +244,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidAddress) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -254,11 +265,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -272,11 +286,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("Invalid Zip"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -290,11 +307,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("Invalid Zip"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::EMPTY}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::EMPTY}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -308,11 +328,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::string16());
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::EMPTY},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -327,11 +350,14 @@ TEST_F(AutofillProfileValidatorTest,
base::UTF8ToUTF16("Invalid Phone"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -343,11 +369,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidEmail) {
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("Invalid Email"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -363,11 +392,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
index f46ca53cf0c..22fc50b9595 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -28,7 +28,7 @@ namespace autofill {
AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
bool upload,
- bool should_request_name_from_user,
+ AutofillClient::SaveCreditCardOptions options,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
AutofillClient::UploadSaveCardPromptCallback
@@ -38,7 +38,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
bool is_off_the_record)
: ConfirmInfoBarDelegate(),
upload_(upload),
- should_request_name_from_user_(should_request_name_from_user),
+ options_(options),
upload_save_card_prompt_callback_(
std::move(upload_save_card_prompt_callback)),
local_save_card_prompt_callback_(
@@ -59,7 +59,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
/*escape_apostrophes=*/true)) {
AutofillMetrics::LogCreditCardInfoBarMetric(
AutofillMetrics::INFOBAR_NOT_SHOWN_INVALID_LEGAL_MESSAGE, upload_,
- should_request_name_from_user_,
+ options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
return;
@@ -67,7 +67,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
}
AutofillMetrics::LogCreditCardInfoBarMetric(
- AutofillMetrics::INFOBAR_SHOWN, upload_, should_request_name_from_user_,
+ AutofillMetrics::INFOBAR_SHOWN, upload_, options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
}
@@ -153,7 +153,10 @@ base::string16 AutofillSaveCardInfoBarDelegateMobile::GetButtonLabel(
return base::string16();
}
- return should_request_name_from_user_
+ // Requesting name or expiration date from the user makes the save prompt a
+ // 2-step fix flow.
+ return options_.should_request_name_from_user ||
+ options_.should_request_expiration_date_from_user
? l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONTINUE)
: l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT);
}
@@ -178,7 +181,7 @@ void AutofillSaveCardInfoBarDelegateMobile::LogUserAction(
DCHECK(!had_user_interaction_);
AutofillMetrics::LogCreditCardInfoBarMetric(
- user_action, upload_, should_request_name_from_user_,
+ user_action, upload_, options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
pref_service_->SetInteger(
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
index ed98a20297b..a99817a0ec5 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
@@ -31,7 +31,7 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
public:
AutofillSaveCardInfoBarDelegateMobile(
bool upload,
- bool should_request_name_from_user,
+ AutofillClient::SaveCreditCardOptions options,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
AutofillClient::UploadSaveCardPromptCallback
@@ -84,8 +84,10 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
// Whether the action is an upload or a local save.
bool upload_;
- // Whether the user should enter/confirm cardholder name.
- bool should_request_name_from_user_;
+ // If the cardholder name is missing, request the name from the user before
+ // saving the card. If the expiration date is missing, request the missing
+ // data from the user before saving the card.
+ AutofillClient::SaveCreditCardOptions options_;
// The callback to run once the user makes a decision with respect to the
// credit card upload offer-to-save prompt (if |upload_| is true).
diff --git a/chromium/components/autofill/core/browser/autofill_scanner.h b/chromium/components/autofill/core/browser/autofill_scanner.h
index 0babe38a2fd..a4826a522b2 100644
--- a/chromium/components/autofill/core/browser/autofill_scanner.h
+++ b/chromium/components/autofill/core/browser/autofill_scanner.h
@@ -46,7 +46,7 @@ class AutofillScanner {
size_t SaveCursor();
// This is only for logging purposes.
- size_t CursorIndex() { return static_cast<size_t>(cursor_ - begin_); };
+ size_t CursorIndex() { return static_cast<size_t>(cursor_ - begin_); }
private:
void Init(const std::vector<AutofillField*>& fields);
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.cc b/chromium/components/autofill/core/browser/autofill_test_utils.cc
index 9126d95ec29..ffab385a580 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.cc
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.cc
@@ -587,7 +587,7 @@ void InitializePossibleTypesAndValidities(
std::vector<ServerFieldTypeValidityStatesMap>&
possible_field_types_validities,
const std::vector<ServerFieldType>& possible_types,
- const std::vector<AutofillProfile::ValidityState>& validity_states) {
+ const std::vector<AutofillDataModel::ValidityState>& validity_states) {
possible_field_types.push_back(ServerFieldTypeSet());
possible_field_types_validities.push_back(ServerFieldTypeValidityStatesMap());
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.h b/chromium/components/autofill/core/browser/autofill_test_utils.h
index b67a11c3655..02eb5847a07 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.h
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.h
@@ -216,7 +216,7 @@ void InitializePossibleTypesAndValidities(
std::vector<ServerFieldTypeValidityStatesMap>&
possible_field_types_validities,
const std::vector<ServerFieldType>& possible_type,
- const std::vector<AutofillProfile::ValidityState>& validity_state = {});
+ const std::vector<AutofillDataModel::ValidityState>& validity_state = {});
// Fills the upload |field| with the information passed by parameter. If the
// value of a const char* parameter is NULL, the corresponding attribute won't
diff --git a/chromium/components/autofill/core/browser/autofill_type.cc b/chromium/components/autofill/core/browser/autofill_type.cc
index 3f2b48a3509..62bb3c04655 100644
--- a/chromium/components/autofill/core/browser/autofill_type.cc
+++ b/chromium/components/autofill/core/browser/autofill_type.cc
@@ -116,6 +116,7 @@ FieldTypeGroup GroupTypeOfServerFieldType(ServerFieldType field_type) {
case USERNAME:
return USERNAME_FIELD;
+ case PRICE:
case SEARCH_TERM:
return UNFILLABLE;
@@ -774,6 +775,8 @@ std::string AutofillType::ServerFieldTypeToString(ServerFieldType type) {
return "CONFIRMATION_PASSWORD";
case SEARCH_TERM:
return "SEARCH_TERM";
+ case PRICE:
+ return "PRICE";
case AMBIGUOUS_TYPE:
return "AMBIGUOUS_TYPE";
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
index 0459e25d4ff..7ad8b87e824 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
@@ -11,6 +11,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
+#include "components/sync/base/data_type_histogram.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/sync_error.h"
@@ -24,6 +25,7 @@ AutofillWalletDataTypeController::AutofillWalletDataTypeController(
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service)
: AsyncDirectoryTypeController(type,
dump_stack,
@@ -31,6 +33,7 @@ AutofillWalletDataTypeController::AutofillWalletDataTypeController(
sync_client,
syncer::GROUP_DB,
std::move(db_thread)),
+ pdm_provider_(pdm_provider),
callback_registered_(false),
web_data_service_(web_data_service),
currently_enabled_(IsEnabled()) {
@@ -95,10 +98,14 @@ void AutofillWalletDataTypeController::StopModels() {
if (!sync_service()->CanSyncFeatureStart() ||
!sync_service()->GetPreferredDataTypes().Has(type()) ||
!currently_enabled_) {
- autofill::PersonalDataManager* pdm =
- sync_client()->GetPersonalDataManager();
- if (pdm)
+ autofill::PersonalDataManager* pdm = pdm_provider_.Run();
+ if (pdm) {
+ int count = pdm->GetServerCreditCards().size() +
+ pdm->GetServerProfiles().size() +
+ (pdm->GetPaymentsCustomerData() == nullptr ? 0 : 1);
+ SyncWalletDataRecordClearedEntitiesCount(count);
pdm->ClearAllServerData();
+ }
}
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
index 837d293a4be..be0e0fff83a 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#include "base/callback.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "components/prefs/pref_change_registrar.h"
@@ -12,7 +13,8 @@
namespace autofill {
class AutofillWebDataService;
-}
+class PersonalDataManager;
+} // namespace autofill
namespace syncer {
class SyncClient;
@@ -25,6 +27,9 @@ namespace browser_sync {
class AutofillWalletDataTypeController
: public syncer::AsyncDirectoryTypeController {
public:
+ using PersonalDataManagerProvider =
+ base::RepeatingCallback<autofill::PersonalDataManager*()>;
+
// |type| should be either AUTOFILL_WALLET or AUTOFILL_WALLET_METADATA.
// |dump_stack| is called when an unrecoverable error occurs.
AutofillWalletDataTypeController(
@@ -33,6 +38,7 @@ class AutofillWalletDataTypeController
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service);
~AutofillWalletDataTypeController() override;
@@ -51,6 +57,9 @@ class AutofillWalletDataTypeController
// Report an error (which will stop the datatype asynchronously).
void DisableForPolicy();
+ // Callback that allows accessing PersonalDataManager lazily.
+ const PersonalDataManagerProvider pdm_provider_;
+
// Whether the database loaded callback has been registered.
bool callback_registered_;
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
index 1d391861d1b..c8a98aff248 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
@@ -24,20 +24,21 @@
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/data_type_controller_mock.h"
#include "components/sync/driver/fake_generic_change_processor.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/driver/fake_sync_service.h"
-#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/fake_syncable_service.h"
#include "components/sync/model/sync_error.h"
#include "testing/gtest/include/gtest/gtest.h"
-using autofill::AutofillWebDataService;
-
namespace browser_sync {
namespace {
+using autofill::AutofillWebDataService;
+using testing::_;
+using testing::Return;
+
// Fake WebDataService implementation that stubs out the database loading.
class FakeWebDataService : public AutofillWebDataService {
public:
@@ -76,12 +77,9 @@ class FakeWebDataService : public AutofillWebDataService {
DISALLOW_COPY_AND_ASSIGN(FakeWebDataService);
};
-class AutofillWalletDataTypeControllerTest : public testing::Test,
- public syncer::FakeSyncClient {
+class AutofillWalletDataTypeControllerTest : public testing::Test {
public:
- AutofillWalletDataTypeControllerTest()
- : syncer::FakeSyncClient(&profile_sync_factory_),
- last_type_(syncer::UNSPECIFIED) {}
+ AutofillWalletDataTypeControllerTest() : last_type_(syncer::UNSPECIFIED) {}
~AutofillWalletDataTypeControllerTest() override {}
void SetUp() override {
@@ -90,12 +88,18 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
prefs_.registry()->RegisterBooleanPref(
autofill::prefs::kAutofillCreditCardEnabled, true);
+ ON_CALL(sync_client_, GetPrefService()).WillByDefault(Return(&prefs_));
+ ON_CALL(sync_client_, GetSyncableServiceForType(_))
+ .WillByDefault(Return(syncable_service_.AsWeakPtr()));
+
web_data_service_ = base::MakeRefCounted<FakeWebDataService>(
base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
autofill_wallet_dtc_ = std::make_unique<AutofillWalletDataTypeController>(
syncer::AUTOFILL_WALLET_DATA, base::ThreadTaskRunnerHandle::Get(),
- base::DoNothing(), &sync_service_, this, web_data_service_);
+ base::DoNothing(), &sync_service_, &sync_client_,
+ AutofillWalletDataTypeController::PersonalDataManagerProvider(),
+ web_data_service_);
last_type_ = syncer::UNSPECIFIED;
last_error_ = syncer::SyncError();
@@ -108,20 +112,12 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
syncable_service_.StopSyncing(syncer::AUTOFILL_WALLET_DATA);
}
- // FakeSyncClient overrides.
- PrefService* GetPrefService() override { return &prefs_; }
-
- base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
- syncer::ModelType type) override {
- return syncable_service_.AsWeakPtr();
- }
-
protected:
void SetStartExpectations() {
autofill_wallet_dtc_->SetGenericChangeProcessorFactoryForTest(
std::make_unique<syncer::FakeGenericChangeProcessorFactory>(
std::make_unique<syncer::FakeGenericChangeProcessor>(
- syncer::AUTOFILL_WALLET_DATA, this)));
+ syncer::AUTOFILL_WALLET_DATA)));
}
void Start() {
@@ -147,10 +143,10 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
TestingPrefServiceSimple prefs_;
syncer::FakeSyncService sync_service_;
syncer::StartCallbackMock start_callback_;
- syncer::SyncApiComponentFactoryMock profile_sync_factory_;
syncer::FakeSyncableService syncable_service_;
std::unique_ptr<AutofillWalletDataTypeController> autofill_wallet_dtc_;
scoped_refptr<FakeWebDataService> web_data_service_;
+ testing::NiceMock<syncer::SyncClientMock> sync_client_;
syncer::ModelType last_type_;
syncer::SyncError last_error_;
@@ -183,8 +179,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
EXPECT_EQ(syncer::DataTypeController::RUNNING, autofill_wallet_dtc_->state());
EXPECT_FALSE(last_error_.IsSet());
EXPECT_EQ(syncer::AUTOFILL_WALLET_DATA, last_type_);
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), false);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), true);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, false);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(last_error_.IsSet());
}
@@ -202,8 +198,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
EXPECT_EQ(syncer::DataTypeController::RUNNING, autofill_wallet_dtc_->state());
EXPECT_FALSE(last_error_.IsSet());
EXPECT_EQ(syncer::AUTOFILL_WALLET_DATA, last_type_);
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), true);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), false);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, true);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, false);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(last_error_.IsSet());
}
@@ -212,8 +208,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
DatatypeDisabledByWalletImportAtStartup) {
SetStartExpectations();
web_data_service_->LoadDatabase();
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), false);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), true);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, false);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, true);
EXPECT_EQ(syncer::DataTypeController::NOT_RUNNING,
autofill_wallet_dtc_->state());
Start();
@@ -225,8 +221,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
DatatypeDisabledByCreditCardsAtStartup) {
SetStartExpectations();
web_data_service_->LoadDatabase();
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), true);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), false);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, true);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, false);
EXPECT_EQ(syncer::DataTypeController::NOT_RUNNING,
autofill_wallet_dtc_->state());
Start();
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter.cc b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
new file mode 100644
index 00000000000..47701675865
--- /dev/null
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/contact_form_label_formatter.h"
+
+namespace autofill {
+
+ContactFormLabelFormatter::ContactFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::set<FieldTypeGroup>& field_type_groups)
+ : LabelFormatter(app_locale, focused_field_type, field_types),
+ field_type_groups_(field_type_groups),
+ filtered_field_type_groups_(field_type_groups) {
+ for (const ServerFieldType& type : field_types) {
+ if (type != focused_field_type) {
+ field_types_for_labels_.push_back(type);
+ }
+ }
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(focused_field_type).GetStorableType()).group();
+ filtered_field_type_groups_.erase(group);
+}
+
+ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
+
+std::vector<base::string16> ContactFormLabelFormatter::GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const {
+ // TODO(crbug.com/936168): Implement GetLabels().
+ std::vector<base::string16> labels;
+ return labels;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter.h b/chromium/components/autofill/core/browser/contact_form_label_formatter.h
new file mode 100644
index 00000000000..38684976af4
--- /dev/null
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+// A LabelFormatter that creates Suggestions' disambiguating labels for forms
+// containing name and phone or email fields.
+class ContactFormLabelFormatter : public LabelFormatter {
+ public:
+ ContactFormLabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::set<FieldTypeGroup>& field_type_groups);
+
+ ~ContactFormLabelFormatter() override;
+
+ std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const override;
+
+ private:
+ // A collection of field types that can be used to make labels. This
+ // collection excludes the focused_field_type_.
+ std::vector<ServerFieldType> field_types_for_labels_;
+
+ // A collection of meaningful FieldTypeGroups in the form with which the user
+ // is interacting.
+ std::set<FieldTypeGroup> field_type_groups_;
+
+ // A collection of meaningful FieldTypeGroups in the form with which the user
+ // is interacting minus the focused field's corresponding FieldTypeGroup.
+ std::set<FieldTypeGroup> filtered_field_type_groups_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/contact_info_unittest.cc b/chromium/components/autofill/core/browser/contact_info_unittest.cc
index d07dfa041f1..3f2502fa654 100644
--- a/chromium/components/autofill/core/browser/contact_info_unittest.cc
+++ b/chromium/components/autofill/core/browser/contact_info_unittest.cc
@@ -46,7 +46,7 @@ TEST_P(SetFullNameTest, SetFullName) {
name.GetInfo(AutofillType(NAME_FULL), "en-US"));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
SetFullNameTest,
testing::Values(
@@ -215,7 +215,7 @@ struct ParsedNamesAreEqualTestCase {
starting_profile.ParsedNamesAreEqual(additional_profile));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
ParsedNamesAreEqualTest,
testing::Values(
@@ -308,7 +308,7 @@ struct ParsedNamesAreEqualTestCase {
existing_name.GetRawInfo(NAME_FULL));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
OverwriteNameTest,
testing::Values(
@@ -387,7 +387,7 @@ struct NamePartsAreEmptyTestCase {
EXPECT_EQ(test_case.expected_result, name.NamePartsAreEmpty());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
NamePartsAreEmptyTest,
testing::Values(NamePartsAreEmptyTestCase{"", "", "", "", true},
diff --git a/chromium/components/autofill/core/browser/credit_card.cc b/chromium/components/autofill/core/browser/credit_card.cc
index 139dca405e1..5d0273de71c 100644
--- a/chromium/components/autofill/core/browser/credit_card.cc
+++ b/chromium/components/autofill/core/browser/credit_card.cc
@@ -30,6 +30,7 @@
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_metadata.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
@@ -655,10 +656,30 @@ bool CreditCard::IsLocalDuplicateOfServerCard(const CreditCard& other) const {
}
bool CreditCard::HasSameNumberAs(const CreditCard& other) const {
- // For masked cards, this is the best we can do to compare card numbers.
+ // Masked cards are considered to have the same number if their last four
+ // digits match and if any expiration date information available for both
+ // cards matches.
if (record_type() == MASKED_SERVER_CARD ||
other.record_type() == MASKED_SERVER_CARD) {
- return NetworkAndLastFourDigits() == other.NetworkAndLastFourDigits();
+ bool last_four_digits_match = LastFourDigits() == other.LastFourDigits();
+ // The below metric is logged because this function previously compared
+ // cards' last four digits and networks if one card was masked. It may be
+ // useful to know how often networks match when the last four digits match.
+ // It is expected that when two cards' last four digits are the same, their
+ // networks will almost always match, too.
+ if (last_four_digits_match) {
+ AutofillMetrics::LogMaskedCardComparisonNetworksMatch(
+ NetworkForDisplay() == other.NetworkForDisplay());
+ }
+
+ bool months_match = expiration_month() == other.expiration_month() ||
+ expiration_month() == 0 ||
+ other.expiration_month() == 0;
+
+ bool years_match = expiration_year() == other.expiration_year() ||
+ expiration_year() == 0 || other.expiration_year() == 0;
+
+ return last_four_digits_match && months_match && years_match;
}
return StripSeparators(number_) == StripSeparators(other.number_);
@@ -869,7 +890,7 @@ base::string16 CreditCard::ExpirationMonthAsString() const {
if (expiration_month_ == 0)
return base::string16();
- base::string16 month = base::IntToString16(expiration_month_);
+ base::string16 month = base::NumberToString16(expiration_month_);
if (expiration_month_ >= 10)
return month;
@@ -882,7 +903,7 @@ base::string16 CreditCard::Expiration4DigitYearAsString() const {
if (expiration_year_ == 0)
return base::string16();
- return base::IntToString16(Expiration4DigitYear());
+ return base::NumberToString16(Expiration4DigitYear());
}
bool CreditCard::HasFirstAndLastName() const {
@@ -898,7 +919,7 @@ base::string16 CreditCard::Expiration2DigitYearAsString() const {
if (expiration_year_ == 0)
return base::string16();
- return base::IntToString16(Expiration2DigitYear());
+ return base::NumberToString16(Expiration2DigitYear());
}
void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
diff --git a/chromium/components/autofill/core/browser/credit_card.h b/chromium/components/autofill/core/browser/credit_card.h
index deff6364ddc..397ac1bda06 100644
--- a/chromium/components/autofill/core/browser/credit_card.h
+++ b/chromium/components/autofill/core/browser/credit_card.h
@@ -165,7 +165,7 @@ class CreditCard : public AutofillDataModel {
bool IsLocalDuplicateOfServerCard(const CreditCard& other) const;
// Determines if |this| has the same number as |other|. If either is a masked
- // server card, compares the last four digits only.
+ // server card, compares their last four digits and expiration dates.
bool HasSameNumberAs(const CreditCard& other) const;
// Equality operators compare GUIDs, origins, and the contents.
diff --git a/chromium/components/autofill/core/browser/credit_card_field.cc b/chromium/components/autofill/core/browser/credit_card_field.cc
index fb1f8bf9914..cbf5de6d188 100644
--- a/chromium/components/autofill/core/browser/credit_card_field.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field.cc
@@ -322,7 +322,7 @@ bool CreditCardField::LikelyCardYearSelectField(AutofillScanner* scanner) {
for (int year = time_exploded.year;
year < time_exploded.year + kYearsToMatch;
++year) {
- years_to_check.push_back(base::IntToString16(year));
+ years_to_check.push_back(base::NumberToString16(year));
}
return (FindConsecutiveStrings(years_to_check, field->option_values) ||
FindConsecutiveStrings(years_to_check, field->option_contents));
diff --git a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
index f701a390212..35ee3dba298 100644
--- a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -375,7 +375,7 @@ TEST_P(ParseExpFieldTest, ParseExpField) {
field_candidates_map_[ASCIIToUTF16("exp3")].BestHeuristicType());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardFieldTest,
ParseExpFieldTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.cc b/chromium/components/autofill/core/browser/credit_card_save_manager.cc
index cef57c082f9..910d5e02fd6 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.cc
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager.cc
@@ -15,6 +15,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@@ -87,7 +88,9 @@ CreditCardSaveManager::CreditCardSaveManager(
// This is to initialize StrikeDatabase is if it hasn't been already, so that
// its cache would be loaded and ready to use when the first CCSM is created.
if (base::FeatureList::IsEnabled(
- features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
+ features::kAutofillSaveCreditCardUsesStrikeSystemV2) ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
// Only init when |kAutofillSaveCreditCardUsesStrikeSystemV2| is enabled. If
// flag is off and LegacyStrikeDatabase instead of StrikeDatabase is used,
// this init will cause failure on GetStrikes().
@@ -98,9 +101,11 @@ CreditCardSaveManager::CreditCardSaveManager(
CreditCardSaveManager::~CreditCardSaveManager() {}
void CreditCardSaveManager::AttemptToOfferCardLocalSave(
+ bool has_non_focusable_field,
const CreditCard& card) {
local_card_save_candidate_ = card;
show_save_prompt_ = base::nullopt;
+ has_non_focusable_field_ = has_non_focusable_field;
// Query the Autofill StrikeDatabase on if we should pop up the
// offer-to-save prompt for this card.
@@ -125,6 +130,7 @@ void CreditCardSaveManager::AttemptToOfferCardLocalSave(
void CreditCardSaveManager::AttemptToOfferCardUploadSave(
const FormStructure& submitted_form,
+ bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card) {
// Abort the uploading if |payments_client_| is nullptr.
@@ -151,6 +157,8 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
found_value_in_cvc_field_ = false;
found_cvc_value_in_non_cvc_field_ = false;
+ has_non_focusable_field_ = has_non_focusable_field;
+
for (const auto& field : submitted_form) {
const bool is_valid_cvc = IsValidCreditCardSecurityCode(
field->value, upload_request_.card.network());
@@ -175,6 +183,11 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
pending_upload_request_origin_ = submitted_form.main_frame_origin();
+ if (has_non_focusable_field_) {
+ upload_decision_metrics_ |=
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD;
+ }
+
if (upload_request_.cvc.empty()) {
// Apply the CVC decision to |upload_decision_metrics_| to denote a problem
// was found.
@@ -328,7 +341,9 @@ void CreditCardSaveManager::OnDidUploadCard(
/*is_local=*/false,
GetCreditCardSaveStrikeDatabase()->GetStrikes(
base::UTF16ToUTF8(upload_request_.card.LastFourDigits())));
- // Clear all strikes for this card, in case it is later removed.
+
+ // Clear all CreditCardSave strikes for this card, in case it is later
+ // removed.
GetCreditCardSaveStrikeDatabase()->ClearStrikes(
base::UTF16ToUTF8(upload_request_.card.LastFourDigits()));
} else if (base::FeatureList::IsEnabled(
@@ -377,11 +392,22 @@ void CreditCardSaveManager::OnDidUploadCard(
CreditCardSaveStrikeDatabase*
CreditCardSaveManager::GetCreditCardSaveStrikeDatabase() {
- if (strike_database_.get() == nullptr) {
- strike_database_ = std::make_unique<CreditCardSaveStrikeDatabase>(
- CreditCardSaveStrikeDatabase(client_->GetStrikeDatabase()));
+ if (credit_card_save_strike_database_.get() == nullptr) {
+ credit_card_save_strike_database_ =
+ std::make_unique<CreditCardSaveStrikeDatabase>(
+ CreditCardSaveStrikeDatabase(client_->GetStrikeDatabase()));
}
- return strike_database_.get();
+ return credit_card_save_strike_database_.get();
+}
+
+LocalCardMigrationStrikeDatabase*
+CreditCardSaveManager::GetLocalCardMigrationStrikeDatabase() {
+ if (local_card_migration_strike_database_.get() == nullptr) {
+ local_card_migration_strike_database_ =
+ std::make_unique<LocalCardMigrationStrikeDatabase>(
+ LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase()));
+ }
+ return local_card_migration_strike_database_.get();
}
void CreditCardSaveManager::OnDidGetStrikesForLocalSave(const int num_strikes) {
@@ -396,8 +422,8 @@ void CreditCardSaveManager::OnDidGetStrikesForUploadSave(
show_save_prompt_ =
num_strikes < kMaxStrikesToPreventPoppingUpOfferToSavePrompt;
- // Only offer upload once both Payments and the Autofill LegacyStrikeDatabase
- // have returned their decisions. Use population of
+ // Only offer upload once both Payments and the Autofill
+ // LegacyStrikeDatabase have returned their decisions. Use population of
// |upload_request_.context_token| as an indicator of the Payments call
// returning successfully.
if (!upload_request_.context_token.empty())
@@ -407,12 +433,24 @@ void CreditCardSaveManager::OnDidGetStrikesForUploadSave(
void CreditCardSaveManager::OnDidGetUploadDetails(
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
if (observer_for_testing_)
observer_for_testing_->OnReceivedGetUploadDetailsResponse();
if (result == AutofillClient::SUCCESS) {
// Do *not* call payments_client_->Prepare() here. We shouldn't send
// credentials until the user has explicitly accepted a prompt to upload.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillDoNotUploadSaveUnsupportedCards) &&
+ !supported_card_bin_ranges.empty() &&
+ !IsCreditCardSupported(supported_card_bin_ranges)) {
+ AttemptToOfferCardLocalSave(has_non_focusable_field_,
+ upload_request_.card);
+ upload_decision_metrics_ |=
+ AutofillMetrics::UPLOAD_NOT_OFFERED_UNSUPPORTED_BIN_RANGE;
+ LogCardUploadDecisions(upload_decision_metrics_);
+ return;
+ }
upload_request_.context_token = context_token;
legal_message_ = base::DictionaryValue::From(std::move(legal_message));
@@ -445,8 +483,10 @@ void CreditCardSaveManager::OnDidGetUploadDetails(
upload_request_.detected_values & DetectedValue::ADDRESS_NAME) &&
upload_request_.detected_values & DetectedValue::POSTAL_CODE &&
upload_request_.detected_values & DetectedValue::CVC;
- if (found_name_and_postal_code_and_cvc && !uploading_local_card_)
- AttemptToOfferCardLocalSave(upload_request_.card);
+ if (found_name_and_postal_code_and_cvc && !uploading_local_card_) {
+ AttemptToOfferCardLocalSave(has_non_focusable_field_,
+ upload_request_.card);
+ }
upload_decision_metrics_ |=
AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED;
LogCardUploadDecisions(upload_decision_metrics_);
@@ -467,7 +507,9 @@ void CreditCardSaveManager::OfferCardLocalSave() {
if (observer_for_testing_)
observer_for_testing_->OnOfferLocalSave();
client_->ConfirmSaveCreditCardLocally(
- local_card_save_candidate_, show_save_prompt_.value(),
+ local_card_save_candidate_,
+ AutofillClient::SaveCreditCardOptions().with_show_prompt(
+ show_save_prompt_.value()),
base::BindOnce(&CreditCardSaveManager::OnUserDidDecideOnLocalSave,
weak_ptr_factory_.GetWeakPtr()));
@@ -488,17 +530,19 @@ void CreditCardSaveManager::OfferCardUploadSave() {
#else
bool is_mobile_build = false;
#endif // #if defined(OS_ANDROID) || defined(OS_IOS)
-
// If |show_save_prompt_.value()| is false, desktop builds will still offer
// save in the omnibox without popping-up the bubble. Mobile builds, however,
// should not display the offer-to-save infobar at all.
if (!is_mobile_build || show_save_prompt_.value()) {
user_did_accept_upload_prompt_ = false;
-
client_->ConfirmSaveCreditCardToCloud(
upload_request_.card, std::move(legal_message_),
- should_request_name_from_user_,
- should_request_expiration_date_from_user_, show_save_prompt_.value(),
+ AutofillClient::SaveCreditCardOptions()
+ .with_has_non_focusable_field(has_non_focusable_field_)
+ .with_should_request_name_from_user(should_request_name_from_user_)
+ .with_should_request_expiration_date_from_user(
+ should_request_expiration_date_from_user_)
+ .with_show_prompt(show_save_prompt_.value()),
base::BindOnce(&CreditCardSaveManager::OnUserDidDecideOnUploadSave,
weak_ptr_factory_.GetWeakPtr()));
client_->LoadRiskData(
@@ -537,12 +581,13 @@ void CreditCardSaveManager::OnUserDidDecideOnLocalSave(
/*is_local=*/true);
if (base::FeatureList::IsEnabled(
features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
- // Log how many strikes the card had when it was saved.
+ // Log how many CreditCardSave strikes the card had when it was saved.
LogStrikesPresentWhenCardSaved(
/*is_local=*/true,
GetCreditCardSaveStrikeDatabase()->GetStrikes(base::UTF16ToUTF8(
local_card_save_candidate_.LastFourDigits())));
- // Clear all strikes for this card, in case it is later removed.
+ // Clear all CreditCardSave strikes for this card, in case it is later
+ // removed.
GetCreditCardSaveStrikeDatabase()->ClearStrikes(
base::UTF16ToUTF8(local_card_save_candidate_.LastFourDigits()));
} else if (base::FeatureList::IsEnabled(
@@ -563,6 +608,12 @@ void CreditCardSaveManager::OnUserDidDecideOnLocalSave(
base::UTF16ToUTF8(local_card_save_candidate_.LastFourDigits())),
base::DoNothing());
}
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ GetLocalCardMigrationStrikeDatabase()->RemoveStrikes(
+ LocalCardMigrationStrikeDatabase::
+ kStrikesToRemoveWhenLocalCardAdded);
+ }
personal_data_manager_->OnAcceptedLocalCreditCardSave(
local_card_save_candidate_);
@@ -818,12 +869,19 @@ void CreditCardSaveManager::OnUserDidDecideOnUploadSave(
const AutofillClient::UserProvidedCardDetails& user_provided_card_details) {
switch (user_decision) {
case AutofillClient::ACCEPTED:
-// On Android, requesting cardholder name is a two step flow.
+// On Android, requesting cardholder name or expiration date is a two step
+// flow.
#if defined(OS_ANDROID)
if (should_request_name_from_user_) {
client_->ConfirmAccountNameFixFlow(base::BindOnce(
&CreditCardSaveManager::OnUserDidAcceptAccountNameFixFlow,
weak_ptr_factory_.GetWeakPtr()));
+ } else if (should_request_expiration_date_from_user_) {
+ client_->ConfirmExpirationDateFixFlow(
+ upload_request_.card,
+ base::BindOnce(
+ &CreditCardSaveManager::OnUserDidAcceptExpirationDateFixFlow,
+ weak_ptr_factory_.GetWeakPtr()));
} else {
OnUserDidAcceptUploadHelper(user_provided_card_details);
}
@@ -850,6 +908,13 @@ void CreditCardSaveManager::OnUserDidAcceptAccountNameFixFlow(
/*expiration_date_month=*/base::string16(),
/*expiration_date_year=*/base::string16()});
}
+
+void CreditCardSaveManager::OnUserDidAcceptExpirationDateFixFlow(
+ const base::string16& month,
+ const base::string16& year) {
+ OnUserDidAcceptUploadHelper(
+ {/*cardholder_name=*/base::string16(), month, year});
+}
#endif
void CreditCardSaveManager::OnUserDidAcceptUploadHelper(
@@ -913,7 +978,7 @@ void CreditCardSaveManager::SendUploadCardRequest() {
void CreditCardSaveManager::OnUserDidIgnoreOrDeclineSave(
const base::string16& card_last_four_digits) {
- if (show_save_prompt_.value()) {
+ if (show_save_prompt_ != base::nullopt && show_save_prompt_.value()) {
if (base::FeatureList::IsEnabled(
features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
// If the user rejected or ignored save and the offer-to-save bubble or
@@ -1005,4 +1070,28 @@ void CreditCardSaveManager::LogSaveCardRequestExpirationDateReasonMetric() {
}
}
+bool CreditCardSaveManager::IsCreditCardSupported(
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
+ base::string16 stripped_number =
+ CreditCard::StripSeparators(upload_request_.card.number());
+ for (auto& bin_range : supported_card_bin_ranges) {
+ unsigned long range_num_of_digits =
+ base::NumberToString(bin_range.first).size();
+ DCHECK_EQ(range_num_of_digits,
+ base::NumberToString(bin_range.second).size());
+ // The first n digits of credit card number, where n is the number of
+ // digits in range's starting/ending number.
+ int first_digits_start, first_digits_end;
+ base::StringToInt(stripped_number.substr(0, range_num_of_digits),
+ &first_digits_start);
+ base::StringToInt(stripped_number.substr(0, range_num_of_digits),
+ &first_digits_end);
+ if (first_digits_start >= bin_range.first &&
+ first_digits_end <= bin_range.second) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.h b/chromium/components/autofill/core/browser/credit_card_save_manager.h
index a1ae70e31ff..5cffff6e8c9 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.h
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager.h
@@ -8,6 +8,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/optional.h"
@@ -18,6 +19,7 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/credit_card_save_strike_database.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "url/origin.h"
@@ -93,11 +95,18 @@ class CreditCardSaveManager {
virtual ~CreditCardSaveManager();
// Begins the process to offer local credit card save to the user.
- void AttemptToOfferCardLocalSave(const CreditCard& card);
+ // If |has_non_focusable_field| is true, the save is triggered by a form that
+ // has non_focusable fields.
+ void AttemptToOfferCardLocalSave(bool has_non_focusable_field,
+ const CreditCard& card);
// Begins the process to offer upload credit card save to the user if the
// imported card passes all requirements and Google Payments approves.
+ // If |has_non_focusable_field| is true, the save is triggered by a form that
+ // has non-focusable fields. if |uploading_local_card| is true, the card being
+ // offered for upload is already a local card on the device.
void AttemptToOfferCardUploadSave(const FormStructure& submitted_form,
+ bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card);
@@ -124,12 +133,17 @@ class CreditCardSaveManager {
private:
friend class CreditCardSaveManagerTest;
friend class CreditCardSaveManagerTestObserverBridge;
+ friend class LocalCardMigrationBrowserTest;
friend class TestCreditCardSaveManager;
friend class SaveCardBubbleViewsFullFormBrowserTest;
+ friend class SaveCardInfobarEGTestHelper;
// Returns the CreditCardSaveStrikeDatabase for |client_|.
CreditCardSaveStrikeDatabase* GetCreditCardSaveStrikeDatabase();
+ // Returns the GetLocalCardMigrationStrikeDatabase for |client_|.
+ LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase();
+
// Sets |show_save_prompt| and moves forward with offering credit card local
// save.
void OnDidGetStrikesForLocalSave(const int num_strikes);
@@ -140,10 +154,14 @@ class CreditCardSaveManager {
// Returns the legal message retrieved from Payments. On failure or not
// meeting Payments's conditions for upload, |legal_message| will contain
- // nullptr.
- void OnDidGetUploadDetails(AutofillClient::PaymentsRpcResult result,
- const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message);
+ // nullptr. |supported_card_bin_ranges| is a list of BIN prefix ranges which
+ // are supoorted, with the first and second number in the pair being the start
+ // and end of the range.
+ void OnDidGetUploadDetails(
+ AutofillClient::PaymentsRpcResult result,
+ const base::string16& context_token,
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
// Logs the number of strikes that a card had when save succeeded.
void LogStrikesPresentWhenCardSaved(bool is_local, const int num_strikes);
@@ -196,12 +214,16 @@ class CreditCardSaveManager {
user_provided_card_details);
#if defined(OS_ANDROID)
- // Sets |user_did_accept_upload_prompt_| and calls SendUploadCardRequest if
- // the risk data is available. Sets the cardholder name on the upload request
- // if |cardholder_name| is set.
+ // Upload the card details with the user provided cardholder_name.
// Only relevant for mobile as fix flow is two steps on mobile compared to
// one step on desktop.
void OnUserDidAcceptAccountNameFixFlow(const base::string16& cardholder_name);
+
+ // Upload the card details with the user provided expiration date month and
+ // year. Only relevant for mobile as fix flow is two steps on mobile compared
+ // to one step on desktop.
+ void OnUserDidAcceptExpirationDateFixFlow(const base::string16& month,
+ const base::string16& year);
#endif // defined(OS_ANDROID)
// Helper function that calls SendUploadCardRequest by setting
@@ -242,6 +264,13 @@ class CreditCardSaveManager {
// Logs the reason why expiration date was explicitly requested.
void LogSaveCardRequestExpirationDateReasonMetric();
+ // Checks if credit card matches one of the ranges in
+ // |supported_card_bin_ranges|, inclusive of the start and end boundaries.
+ // For example, if the range consists of std::pair<34, 36>, then all cards
+ // with first two digits of 34, 35 and 36 are supported.
+ bool IsCreditCardSupported(
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
+
// For testing.
void SetEventObserverForTesting(ObserverForTest* observer) {
observer_for_testing_ = observer;
@@ -302,12 +331,22 @@ class CreditCardSaveManager {
// determined to be a CVC field via heuristics has a valid CVC |value|.
bool found_cvc_value_in_non_cvc_field_ = false;
+ // |has_non_focusable_field_| is |true| if there exists a field that
+ // |is_focusable| is false.
+ bool has_non_focusable_field_ = false;
+
// The origin of the top level frame from which a form is uploaded.
url::Origin pending_upload_request_origin_;
// The returned legal message from a GetUploadDetails call to Google Payments.
std::unique_ptr<base::DictionaryValue> legal_message_;
+ std::unique_ptr<CreditCardSaveStrikeDatabase>
+ credit_card_save_strike_database_;
+
+ std::unique_ptr<LocalCardMigrationStrikeDatabase>
+ local_card_migration_strike_database_;
+
std::unique_ptr<CreditCardSaveStrikeDatabase> strike_database_;
// May be null.
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
index ef3e151e073..d4d246aaf5f 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -117,7 +117,6 @@ class CreditCardSaveManagerTest : public testing::Test {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
personal_data_.SetSyncServiceForTest(&sync_service_);
autocomplete_history_manager_.Init(
@@ -183,7 +182,8 @@ class CreditCardSaveManagerTest : public testing::Test {
void CreateTestCreditCardFormData(FormData* form,
bool is_https,
bool use_month_type,
- bool split_names = false) {
+ bool split_names = false,
+ bool is_from_non_focusable_form = false) {
form->name = ASCIIToUTF16("MyForm");
if (is_https) {
form->origin = GURL("https://myform.com/form.html");
@@ -214,6 +214,7 @@ class CreditCardSaveManagerTest : public testing::Test {
form->fields.push_back(field);
}
test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ field.is_focusable = !is_from_non_focusable_form;
form->fields.push_back(field);
if (use_month_type) {
test::CreateTestFormField("Expiration Date", "ccmonth", "", "month",
@@ -756,6 +757,170 @@ TEST_F(CreditCardSaveManagerTest,
"Autofill.SaveCardReachedPersonalDataManager.Server", 0);
}
+// Tests metrics for supporting unfocused card form.
+TEST_F(CreditCardSaveManagerTest, UploadCreditCard_WithNonFocusableField) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+ // Verify that the correct histogram entries were logged.
+ ExpectCardUploadDecision(histogram_tester, AutofillMetrics::UPLOAD_OFFERED);
+ ExpectCardUploadDecision(
+ histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(
+ AutofillMetrics::UPLOAD_OFFERED |
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD);
+}
+
+// Tests upload card save will still work as usual when supporting unfocused
+// card form experiment is off.
+TEST_F(CreditCardSaveManagerTest,
+ UploadCreditCard_WithNonFocusableField_ExpOff) {
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests local card save will still work as usual when supporting unfocused card
+// form feature is already on.
+TEST_F(CreditCardSaveManagerTest, LocalCreditCard_WithNonFocusableField) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests local card save will still work as usual when supporting unfocused card
+// form experiment is off.
+TEST_F(CreditCardSaveManagerTest,
+ LocalCreditCard_WithNonFocusableField_ExpOff) {
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
// Tests that a credit card inferred from a form with a credit card first and
// last name can be uploaded.
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_FirstAndLastName) {
@@ -2831,7 +2996,7 @@ TEST_F(CreditCardSaveManagerTest, DuplicateMaskedCreditCard_NoUpload) {
}
// This class is parametrized to allow running all the inheriting tests with and
-// without a specific feature enabled. See INSTANTIATE_TEST_CASE_P.
+// without a specific feature enabled. See INSTANTIATE_TEST_SUITE_P.
class CreditCardSaveManagerFeatureParameterizedTest
: public CreditCardSaveManagerTest,
public ::testing::WithParamInterface<
@@ -3928,9 +4093,9 @@ TEST_P(CreditCardSaveManagerFeatureParameterizedTest,
// Feature disabled
// CreditCardSaveManagerFeatureParameterizedTest.NothingIfNothingFound/1:
// Feature enabled.
-INSTANTIATE_TEST_CASE_P(, // Empty instatiation name.
- CreditCardSaveManagerFeatureParameterizedTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(, // Empty instatiation name.
+ CreditCardSaveManagerFeatureParameterizedTest,
+ ::testing::Values(false, true));
TEST_F(CreditCardSaveManagerTest,
UploadCreditCard_DoNotAddAnyFlagStatesToRequestIfExperimentsOff) {
@@ -5232,4 +5397,171 @@ TEST_F(CreditCardSaveManagerTest, OnUserDidAcceptUpload_NotifiesPDM) {
UserHasAcceptedUpload({});
}
+// Tests that 2 LocalCardMigrationStrikes are removed when cards are saved
+// locally.
+TEST_F(CreditCardSaveManagerTest,
+ LocalCreditCard_LocalCardMigrationStrikesRemovedOnLocalSave) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+
+ // Start with 3 strikes in |local_card_migration_strike_database|.
+ local_card_migration_strike_database.AddStrikes(3);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with credit card first and last name
+ // fields.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+
+ // 2 strikes should be removed when card was saved locally.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 1);
+}
+
+// Tests that no LocalCardMigrationStrikes get removed due to cards being
+// uploaded.
+TEST_F(CreditCardSaveManagerTest,
+ UploadCreditCard_NoLocalSaveMigrationStrikesRemovedOnUpload) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+
+ // Start with 3 strikes in |local_card_migration_strike_database|.
+ local_card_migration_strike_database.AddStrikes(3);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with credit card first and last name
+ // fields.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+
+ // Strike count shouldn't change.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+}
+
+// Tests that if a card doesn't fall in any of the supported bin ranges, local
+// save is offered rather than upload save.
+TEST_F(CreditCardSaveManagerTest, UploadSaveNotOfferedForUnsupportedCard) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillDoNotUploadSaveUnsupportedCards);
+ std::vector<std::pair<int, int>> supported_card_bin_ranges{
+ std::make_pair(4111, 4113), std::make_pair(34, 34),
+ std::make_pair(300, 305)};
+ payments_client_->SetSupportedBINRanges(supported_card_bin_ranges);
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("5454545454545454");
+ credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // Since card isn't in any of the supported ranges, local save should be
+ // offered and upload save should not.
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests that if a card falls in one of the supported bin ranges, upload save
+// is offered.
+TEST_F(CreditCardSaveManagerTest, UploadSaveOfferedForSupportedCard) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillDoNotUploadSaveUnsupportedCards);
+ // Set supported BIN ranges.
+ std::vector<std::pair<int, int>> supported_card_bin_ranges{
+ std::make_pair(4111, 4113)};
+ payments_client_->SetSupportedBINRanges(supported_card_bin_ranges);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // Since card is in one of the supported ranges(4111-4113), upload save should
+ // be offered.
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc b/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc
deleted file mode 100644
index 6628663394c..00000000000
--- a/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/credit_card_save_strike_database.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/autofill/core/browser/proto/strike_data.pb.h"
-#include "components/autofill/core/browser/test_autofill_clock.h"
-#include "components/autofill/core/browser/test_credit_card_save_strike_database.h"
-#include "components/autofill/core/common/autofill_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-class CreditCardSaveStrikeDatabaseTest : public ::testing::Test {
- public:
- CreditCardSaveStrikeDatabaseTest()
- : strike_database_(new StrikeDatabase(InitFilePath())) {}
-
- protected:
- base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- TestCreditCardSaveStrikeDatabase strike_database_;
-
- private:
- static const base::FilePath InitFilePath() {
- base::ScopedTempDir temp_dir_;
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- const base::FilePath file_path =
- temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
- return file_path;
- }
-
- base::HistogramTester histogram_tester_;
-};
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, GetKeyForCreditCardSaveTest) {
- const std::string last_four = "1234";
- EXPECT_EQ("CreditCardSave__1234", strike_database_.GetKey(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, MaxStrikesLimitReachedTest) {
- const std::string last_four = "1234";
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 1st strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 2nd strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 3rd strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest,
- CreditCardSaveNthStrikeAddedHistogram) {
- const std::string last_four1 = "1234";
- const std::string last_four2 = "9876";
- // 1st strike added for |last_four1|.
- strike_database_.AddStrike(last_four1);
- // 2nd strike added for |last_four1|.
- strike_database_.AddStrike(last_four1);
- // 1st strike added for |last_four2|.
- strike_database_.AddStrike(last_four2);
- std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
- "Autofill.StrikeDatabase.NthStrikeAdded.CreditCardSave");
- // There should be two buckets, one for 1st strike, one for 2nd strike count.
- ASSERT_EQ(2U, buckets.size());
- // Both |last_four1| and |last_four2| have 1st strikes recorded.
- EXPECT_EQ(2, buckets[0].count);
- // Only |last_four1| has 2nd strike recorded.
- EXPECT_EQ(1, buckets[1].count);
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest,
- AddStrikeForZeroAndNonZeroStrikesTest) {
- const std::string last_four = "1234";
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four));
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(2, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForNonZeroStrikesTest) {
- const std::string last_four = "1234";
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four));
- strike_database_.ClearStrikes(last_four);
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForZeroStrikesTest) {
- const std::string last_four = "1234";
- strike_database_.ClearStrikes(last_four);
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, RemoveExpiredStrikesTest) {
- autofill::TestAutofillClock test_clock;
- test_clock.SetNow(AutofillClock::Now());
- const std::string last_four1 = "1234";
- const std::string last_four2 = "9876";
- strike_database_.AddStrike(last_four1);
-
- // Advance clock to past the entry for |last_four1|'s expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- strike_database_.AddStrike(last_four2);
- strike_database_.RemoveExpiredStrikes();
-
- // |last_four1|'s entry should have its most recent strike expire, but
- // |last_four2|'s should not.
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four1));
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four2));
-
- // Advance clock to past |last_four2|'s expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- strike_database_.RemoveExpiredStrikes();
-
- // |last_four1| and |last_four2| should have no more unexpired strikes.
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four1));
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four2));
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_unittest.cc b/chromium/components/autofill/core/browser/credit_card_unittest.cc
index 9552cae6cd4..71153c60fab 100644
--- a/chromium/components/autofill/core/browser/credit_card_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_unittest.cc
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_experiments.h"
@@ -364,19 +365,19 @@ TEST_P(SetExpirationYearFromStringTest, SetExpirationYearFromString) {
<< test_case.expiration_year << " " << test_case.expected_year;
}
-INSTANTIATE_TEST_CASE_P(CreditCardTest,
- SetExpirationYearFromStringTest,
- testing::Values(
- // Valid values.
- SetExpirationYearFromStringTestCase{"2040", 2040},
- SetExpirationYearFromStringTestCase{"45", 2045},
- SetExpirationYearFromStringTestCase{"045", 2045},
- SetExpirationYearFromStringTestCase{"9", 2009},
+INSTANTIATE_TEST_SUITE_P(CreditCardTest,
+ SetExpirationYearFromStringTest,
+ testing::Values(
+ // Valid values.
+ SetExpirationYearFromStringTestCase{"2040", 2040},
+ SetExpirationYearFromStringTestCase{"45", 2045},
+ SetExpirationYearFromStringTestCase{"045", 2045},
+ SetExpirationYearFromStringTestCase{"9", 2009},
- // Unrecognized year values.
- SetExpirationYearFromStringTestCase{"052045", 0},
- SetExpirationYearFromStringTestCase{"123", 0},
- SetExpirationYearFromStringTestCase{"y2045", 0}));
+ // Unrecognized year values.
+ SetExpirationYearFromStringTestCase{"052045", 0},
+ SetExpirationYearFromStringTestCase{"123", 0},
+ SetExpirationYearFromStringTestCase{"y2045", 0}));
struct SetExpirationDateFromStringTestCase {
std::string expiration_date;
@@ -396,7 +397,7 @@ TEST_P(SetExpirationDateFromStringTest, SetExpirationDateFromString) {
EXPECT_EQ(test_case.expected_year, card.expiration_year());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
SetExpirationDateFromStringTest,
testing::Values(
@@ -486,7 +487,7 @@ TEST_P(IsLocalDuplicateOfServerCardTest, IsLocalDuplicateOfServerCard) {
<< " when comparing cards " << a.Label() << " and " << b.Label();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
IsLocalDuplicateOfServerCardTest,
testing::Values(
@@ -517,9 +518,6 @@ INSTANTIATE_TEST_CASE_P(
LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
"John Dillinger", "9012", "01", "2010", "1", kVisaCard, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
- "John Dillinger", "9012", "01", "2010", "1", kMasterCard, false},
- IsLocalDuplicateOfServerCardTestCase{
LOCAL_CARD, "John Dillinger", "4234-5678-9012", "01", "2010", "1",
FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
"1", nullptr, true},
@@ -536,31 +534,123 @@ TEST(CreditCardTest, HasSameNumberAs) {
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
- // Same number.
+ // Cards with the same number are the same.
a.set_record_type(CreditCard::LOCAL_CARD);
a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
- a.set_record_type(CreditCard::LOCAL_CARD);
+ b.set_record_type(CreditCard::LOCAL_CARD);
b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
- // Local cards shouldn't match even if the last 4 are the same.
+ // Local cards with different overall numbers shouldn't match even if the last
+ // four digits are the same.
a.set_record_type(CreditCard::LOCAL_CARD);
a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
- a.set_record_type(CreditCard::LOCAL_CARD);
+ b.set_record_type(CreditCard::LOCAL_CARD);
b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111222222221111"));
EXPECT_FALSE(a.HasSameNumberAs(b));
EXPECT_FALSE(b.HasSameNumberAs(a));
- // Likewise if one is an unmasked server card.
+ // When one card is a full server card, the other is a local card, and the
+ // cards have different overall numbers but the same last four digits, they
+ // should not match.
a.set_record_type(CreditCard::FULL_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111222222221111"));
EXPECT_FALSE(a.HasSameNumberAs(b));
EXPECT_FALSE(b.HasSameNumberAs(a));
- // But if one is a masked card, then they should.
- b.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ // When one card is a masked server card, the other is a local card, and the
+ // cards have the same last four digits, they should match.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4331111111111111"));
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // When one card is a masked server card, the other is a full server card, and
+ // the cards have the same last four digits, they should match.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::FULL_SERVER_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4331111111111111"));
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then partial or missing expiration date information
+ // should not prevent the function from returning true.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2025"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then non-matching expiration months should cause the
+ // function to return false.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("03"));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ EXPECT_FALSE(a.HasSameNumberAs(b));
+ EXPECT_FALSE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then non-matching expiration years should cause the
+ // function to return false.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2025"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2026"));
+ EXPECT_FALSE(a.HasSameNumberAs(b));
+ EXPECT_FALSE(b.HasSameNumberAs(a));
+}
+
+TEST(CreditCardTest, HasSameNumberAs_LogMaskedCardComparisonNetworksMatch) {
+ CreditCard a(base::GenerateGUID(), std::string());
+ CreditCard b(base::GenerateGUID(), std::string());
+
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetNetworkForMaskedCard(kVisaCard);
+ // CreditCard b's network is set to kVisaCard because it starts with 4, so the
+ // two cards have the same network.
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.MaskedCardComparisonNetworksMatch", true, 1);
+}
+
+TEST(CreditCardTest,
+ HasSameNumberAs_LogMaskedCardComparisonNetworksDoNotMatch) {
+ CreditCard a(base::GenerateGUID(), std::string());
+ CreditCard b(base::GenerateGUID(), std::string());
+
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetNetworkForMaskedCard(kDiscoverCard);
+ // CreditCard b's network is set to kVisaCard because it starts with 4. The
+ // two cards have the same last four digits, but their networks are different,
+ // so this discrepancy should be logged.
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.MaskedCardComparisonNetworksMatch", false, 1);
}
TEST(CreditCardTest, Compare) {
@@ -931,9 +1021,9 @@ TEST(CreditCardTest, IsValidCardNumberAndExpiryDate) {
base::Time::Exploded now_exploded;
now.LocalExplode(&now_exploded);
card.SetRawInfo(CREDIT_CARD_EXP_MONTH,
- base::IntToString16(now_exploded.month));
+ base::NumberToString16(now_exploded.month));
card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
- base::IntToString16(now_exploded.year - 1));
+ base::NumberToString16(now_exploded.year - 1));
card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
EXPECT_FALSE(card.IsValid());
EXPECT_FALSE(card.HasValidExpirationDate());
@@ -1152,9 +1242,9 @@ const CreditCardMatchingTypesCase kCreditCardMatchingTypesTestCases[] = {
{"2021", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()},
};
-INSTANTIATE_TEST_CASE_P(CreditCardTest,
- CreditCardMatchingTypesTest,
- testing::ValuesIn(kCreditCardMatchingTypesTestCases));
+INSTANTIATE_TEST_SUITE_P(CreditCardTest,
+ CreditCardMatchingTypesTest,
+ testing::ValuesIn(kCreditCardMatchingTypesTestCases));
struct GetCardNetworkTestCase {
const char* card_number;
@@ -1162,7 +1252,7 @@ struct GetCardNetworkTestCase {
bool is_valid;
};
-// We are doing batches here because INSTANTIATE_TEST_CASE_P has a
+// We are doing batches here because INSTANTIATE_TEST_SUITE_P has a
// 50 upper limit.
class GetCardNetworkTestBatch1
: public testing::TestWithParam<GetCardNetworkTestCase> {};
@@ -1175,7 +1265,7 @@ TEST_P(GetCardNetworkTestBatch1, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch1,
testing::Values(
@@ -1238,7 +1328,7 @@ TEST_P(GetCardNetworkTestBatch2, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch2,
testing::Values(
@@ -1291,7 +1381,7 @@ TEST_P(GetCardNetworkTestBatch3, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch3,
testing::Values(
@@ -1351,7 +1441,7 @@ TEST_P(GetCardNetworkTestBatch4, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch4,
testing::Values(
@@ -1482,7 +1572,7 @@ TEST_P(ShouldUpdateExpirationTest, ShouldUpdateExpiration) {
card.ShouldUpdateExpiration(testingTimes.now_));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
ShouldUpdateExpirationTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/field_filler.cc b/chromium/components/autofill/core/browser/field_filler.cc
index e1e56eb081d..736b6684b6a 100644
--- a/chromium/components/autofill/core/browser/field_filler.cc
+++ b/chromium/components/autofill/core/browser/field_filler.cc
@@ -624,6 +624,7 @@ bool FieldFiller::FillFormField(const AutofillField& field,
FormFieldData* field_data,
const base::string16& cvc) {
const AutofillType type = field.Type();
+
// Don't fill if autocomplete=off is set on |field| on desktop for non credit
// card related fields.
if (!base::FeatureList::IsEnabled(features::kAutofillAlwaysFillAddresses) &&
@@ -632,6 +633,9 @@ bool FieldFiller::FillFormField(const AutofillField& field,
return false;
}
+ if (data_model.ShouldSkipFillingOrSuggesting(type.GetStorableType()))
+ return false;
+
base::string16 value = data_model.GetInfo(type, app_locale_);
if (type.GetStorableType() == CREDIT_CARD_VERIFICATION_CODE)
value = cvc;
diff --git a/chromium/components/autofill/core/browser/field_filler_unittest.cc b/chromium/components/autofill/core/browser/field_filler_unittest.cc
index eb2f698627f..82728e71ec7 100644
--- a/chromium/components/autofill/core/browser/field_filler_unittest.cc
+++ b/chromium/components/autofill/core/browser/field_filler_unittest.cc
@@ -110,6 +110,29 @@ void TestFillingExpirationMonth(const std::vector<const char*>& values,
EXPECT_EQ(ASCIIToUTF16("Nov"), field.option_contents[content_index]);
}
+void TestFillingInvalidFields(const base::string16& state,
+ const base::string16& city) {
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ AutofillField field_state;
+ field_state.set_heuristic_type(ADDRESS_HOME_STATE);
+ AutofillField field_city;
+ field_city.set_heuristic_type(ADDRESS_HOME_CITY);
+
+ FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
+ filler.FillFormField(field_state, profile, &field_state,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(state, field_state.value);
+
+ filler.FillFormField(field_city, profile, &field_city,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(city, field_city.value);
+}
+
struct CreditCardTestCase {
std::string card_number_;
size_t total_splits_;
@@ -388,6 +411,82 @@ TEST_F(AutofillFieldFillerTest, FillFormField_AutocompleteOff_CreditCardField) {
EXPECT_EQ(ASCIIToUTF16("4111111111111111"), field.value);
}
+// Verify that when the relevant feature is enabled, the invalid fields don't
+// get filled.
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_ServerClient) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/base::string16(),
+ /*city=*/base::string16());
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_OnlyServer) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillProfileClientValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/base::string16(),
+ /*city=*/ASCIIToUTF16("Elysium"));
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_OnlyClient) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/ASCIIToUTF16("CA"),
+ /*city=*/base::string16());
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_NoValidity) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/ASCIIToUTF16("CA"),
+ /*city=*/ASCIIToUTF16("Elysium"));
+}
+
+// Tests that using only client side validation, if the country is empty, the
+// address fields will get filled regardless of their invalidity.
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_CountryEmpty) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation});
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16(""));
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ AutofillField field_state;
+ field_state.set_heuristic_type(ADDRESS_HOME_STATE);
+ AutofillField field_email;
+ field_email.set_heuristic_type(EMAIL_ADDRESS);
+
+ FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
+ // State is filled, because it's an address field.
+ filler.FillFormField(field_state, profile, &field_state,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(ASCIIToUTF16("CA"), field_state.value);
+
+ // Email is not filled, because it's not an address field, and it doesn't
+ // depend on the country.
+ filler.FillFormField(field_email, profile, &field_email,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(ASCIIToUTF16(""), field_email.value);
+}
+
struct AutofillFieldFillerTestCase {
HtmlFieldType field_type;
size_t field_max_length;
@@ -413,7 +512,7 @@ TEST_P(PhoneNumberTest, FillPhoneNumber) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
PhoneNumberTest,
testing::Values(
@@ -463,7 +562,7 @@ TEST_P(ExpirationYearTest, FillExpirationYearInput) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
ExpirationYearTest,
testing::Values(
@@ -527,7 +626,7 @@ TEST_P(ExpirationDateTest, FillExpirationDateInput) {
EXPECT_EQ(response, test_case.expected_response);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
ExpirationDateTest,
testing::Values(
@@ -717,7 +816,7 @@ TEST_P(AutofillSelectWithStatesTest, FillSelectWithStates) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillSelectWithStatesTest,
testing::Values(
@@ -805,7 +904,7 @@ TEST_P(AutofillSelectWithExpirationMonthTest,
test_case.select_values.size());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillSelectWithExpirationMonthTest,
testing::Values(
@@ -1291,7 +1390,7 @@ TEST_P(AutofillStateTextTest, FillStateText) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillStateTextTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/field_types.h b/chromium/components/autofill/core/browser/field_types.h
index fe6d8ab5c1c..c10fd8df61d 100644
--- a/chromium/components/autofill/core/browser/field_types.h
+++ b/chromium/components/autofill/core/browser/field_types.h
@@ -169,9 +169,12 @@ enum ServerFieldType {
// Search term fields are detected, but not filled.
SEARCH_TERM = 97,
+ // Price fields are detected, but not filled.
+ PRICE = 98,
+
// No new types can be added without a corresponding change to the Autofill
// server.
- MAX_VALID_FIELD_TYPE = 98,
+ MAX_VALID_FIELD_TYPE = 99,
};
// The list of all HTML autocomplete field type hints supported by Chrome.
diff --git a/chromium/components/autofill/core/browser/form_data_importer.cc b/chromium/components/autofill/core/browser/form_data_importer.cc
index 03b9216973a..15e57a10910 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer.cc
@@ -14,6 +14,7 @@
#include <set>
#include <utility>
+#include "base/bind.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -176,7 +177,7 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardUploadSave(
- submitted_form, *imported_credit_card,
+ submitted_form, has_non_focusable_field_, *imported_credit_card,
/*uploading_local_card=*/imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::LOCAL_CARD);
} else {
@@ -184,7 +185,7 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
DCHECK(imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardLocalSave(
- *imported_credit_card);
+ has_non_focusable_field_, *imported_credit_card);
}
}
@@ -442,7 +443,10 @@ bool FormDataImporter::ImportCreditCard(
// there is for local cards.
for (const CreditCard* card :
personal_data_manager_->GetServerCreditCards()) {
- if (candidate_credit_card.HasSameNumberAs(*card)) {
+ if ((card->record_type() == CreditCard::MASKED_SERVER_CARD &&
+ card->LastFourDigits() == candidate_credit_card.LastFourDigits()) ||
+ (card->record_type() == CreditCard::FULL_SERVER_CARD &&
+ candidate_credit_card.HasSameNumberAs(*card))) {
// Don't update card if the expiration date is missing
if (candidate_credit_card.expiration_month() == 0 ||
candidate_credit_card.expiration_year() == 0) {
@@ -504,6 +508,9 @@ CreditCard FormDataImporter::ExtractCreditCardFromForm(
if (field_type.group() != CREDIT_CARD)
continue;
+ if (!field->is_focusable)
+ has_non_focusable_field_ = true;
+
// If we've seen the same credit card field type twice in the same form,
// set |has_duplicate_field_type| to true.
ServerFieldType server_field_type = field_type.GetStorableType();
diff --git a/chromium/components/autofill/core/browser/form_data_importer.h b/chromium/components/autofill/core/browser/form_data_importer.h
index 0a11aeb00a4..a195d96cc86 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.h
+++ b/chromium/components/autofill/core/browser/form_data_importer.h
@@ -120,6 +120,10 @@ class FormDataImporter {
CreditCard ExtractCreditCardFromForm(const FormStructure& form,
bool* hasDuplicateFieldType);
+ // Whether the form imported has non-focusable fields after user entered
+ // information into it.
+ bool has_non_focusable_field_ = false;
+
// The associated autofill client. Weak reference.
AutofillClient* client_;
@@ -145,6 +149,7 @@ class FormDataImporter {
friend class AutofillMergeTest;
friend class FormDataImporterTest;
friend class FormDataImporterTestBase;
+ friend class LocalCardMigrationBrowserTest;
friend class SaveCardBubbleViewsFullFormBrowserTest;
friend class SaveCardInfobarEGTestHelper;
FRIEND_TEST_ALL_PREFIXES(AutofillMergeTest, MergeProfiles);
diff --git a/chromium/components/autofill/core/browser/form_data_importer_unittest.cc b/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
index a205459df88..00280a55dde 100644
--- a/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -124,7 +124,6 @@ class FormDataImporterTestBase {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/(user_mode == USER_MODE_INCOGNITO));
personal_data_manager_->AddObserver(&personal_data_observer_);
personal_data_manager_->OnSyncServiceInitialized(nullptr);
diff --git a/chromium/components/autofill/core/browser/form_field.cc b/chromium/components/autofill/core/browser/form_field.cc
index 3328e18c6f9..7b2aac8f7ab 100644
--- a/chromium/components/autofill/core/browser/form_field.cc
+++ b/chromium/components/autofill/core/browser/form_field.cc
@@ -23,7 +23,9 @@
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/name_field.h"
#include "components/autofill/core/browser/phone_field.h"
+#include "components/autofill/core/browser/price_field.h"
#include "components/autofill/core/browser/search_field.h"
+#include "components/autofill/core/browser/travel_field.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_regexes.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -31,14 +33,16 @@
namespace autofill {
// There's an implicit precedence determined by the values assigned here. Email
-// is currently the most important followed by Phone, Address, Credit Card,
-// Name, and Search.
+// is currently the most important followed by Phone, Travel, Address,
+// Credit Card, Name, and Search.
const float FormField::kBaseEmailParserScore = 1.4f;
const float FormField::kBasePhoneParserScore = 1.3f;
-const float FormField::kBaseAddressParserScore = 1.2f;
-const float FormField::kBaseCreditCardParserScore = 1.1f;
-const float FormField::kBaseNameParserScore = 1.0f;
-const float FormField::kBaseSearchParserScore = 0.9f;
+const float FormField::kBaseTravelParserScore = 1.2f;
+const float FormField::kBaseAddressParserScore = 1.1f;
+const float FormField::kBaseCreditCardParserScore = 1.0f;
+const float FormField::kBasePriceParserScore = 0.95f;
+const float FormField::kBaseNameParserScore = 0.9f;
+const float FormField::kBaseSearchParserScore = 0.8f;
// static
FieldCandidatesMap FormField::ParseFormFields(
@@ -69,6 +73,9 @@ FieldCandidatesMap FormField::ParseFormFields(
// Phone pass.
ParseFormFieldsPass(PhoneField::Parse, processed_fields, &field_candidates);
+ // Travel pass.
+ ParseFormFieldsPass(TravelField::Parse, processed_fields, &field_candidates);
+
// Address pass.
ParseFormFieldsPass(autofill::AddressField::Parse, processed_fields,
&field_candidates);
@@ -77,6 +84,9 @@ FieldCandidatesMap FormField::ParseFormFields(
ParseFormFieldsPass(CreditCardField::Parse, processed_fields,
&field_candidates);
+ // Price pass.
+ ParseFormFieldsPass(PriceField::Parse, processed_fields, &field_candidates);
+
// Name pass.
ParseFormFieldsPass(NameField::Parse, processed_fields, &field_candidates);
diff --git a/chromium/components/autofill/core/browser/form_field.h b/chromium/components/autofill/core/browser/form_field.h
index c14e88f2b98..8471b0ff3f6 100644
--- a/chromium/components/autofill/core/browser/form_field.h
+++ b/chromium/components/autofill/core/browser/form_field.h
@@ -60,8 +60,10 @@ class FormField {
// Initial values assigned to FieldCandidates by their corresponding parsers.
static const float kBaseEmailParserScore;
static const float kBasePhoneParserScore;
+ static const float kBaseTravelParserScore;
static const float kBaseAddressParserScore;
static const float kBaseCreditCardParserScore;
+ static const float kBasePriceParserScore;
static const float kBaseNameParserScore;
static const float kBaseSearchParserScore;
diff --git a/chromium/components/autofill/core/browser/form_structure.cc b/chromium/components/autofill/core/browser/form_structure.cc
index c715abb098f..07adcce22f2 100644
--- a/chromium/components/autofill/core/browser/form_structure.cc
+++ b/chromium/components/autofill/core/browser/form_structure.cc
@@ -18,7 +18,6 @@
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
-#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
diff --git a/chromium/components/autofill/core/browser/form_structure.h b/chromium/components/autofill/core/browser/form_structure.h
index 218c73ed169..414345d7744 100644
--- a/chromium/components/autofill/core/browser/form_structure.h
+++ b/chromium/components/autofill/core/browser/form_structure.h
@@ -319,7 +319,7 @@ class FormStructure {
// - Name for Autofill of first field
base::string16 GetIdentifierForRefill() const;
- int developer_engagement_metrics() { return developer_engagement_metrics_; };
+ int developer_engagement_metrics() { return developer_engagement_metrics_; }
void set_randomized_encoder(std::unique_ptr<RandomizedEncoder> encoder);
@@ -348,7 +348,7 @@ class FormStructure {
if (sectioned_indexes.empty())
return (size_t)-1; // Shouldn't happen.
return sectioned_indexes.back().back();
- };
+ }
void AddFieldIndex(const size_t index, bool is_new_section) {
if (is_new_section || Empty()) {
diff --git a/chromium/components/autofill/core/browser/label_formatter.cc b/chromium/components/autofill/core/browser/label_formatter.cc
new file mode 100644
index 00000000000..32426dd7790
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter.cc
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+LabelFormatter::LabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types)
+ : app_locale_(app_locale),
+ focused_field_type_(focused_field_type),
+ field_types_(field_types) {}
+LabelFormatter::~LabelFormatter() = default;
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter.h b/chromium/components/autofill/core/browser/label_formatter.h
new file mode 100644
index 00000000000..d436401044d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+
+namespace autofill {
+
+// Handles the creation of Suggestions' disambiguating labels.
+class LabelFormatter {
+ public:
+ LabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+ virtual ~LabelFormatter();
+
+ // Returns a collection of |labels| formed by extracting useful disambiguating
+ // information from a collection of |profiles|.
+ virtual std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const = 0;
+
+ protected:
+ const std::string& app_locale() const { return app_locale_; }
+ ServerFieldType focused_field_type() const { return focused_field_type_; }
+ const std::vector<ServerFieldType>& field_types() const {
+ return field_types_;
+ }
+
+ private:
+ // The locale for which to generate labels. This reflects the language and
+ // country for which the application is translated, e.g. en_AU for Austalian
+ // English.
+ std::string app_locale_;
+
+ // The field on which the user is currently focused.
+ ServerFieldType focused_field_type_;
+
+ // A collection of meaningful field types in the form with which the user is
+ // interacting.
+ std::vector<ServerFieldType> field_types_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.cc b/chromium/components/autofill/core/browser/label_formatter_utils.cc
new file mode 100644
index 00000000000..53d8eab8836
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.cc
@@ -0,0 +1,115 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+#include <memory>
+#include <set>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/address_form_label_formatter.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/contact_form_label_formatter.h"
+#include "components/autofill/core/browser/validation.h"
+
+namespace autofill {
+namespace {
+
+bool ContainsName(uint32_t groups) {
+ return groups & label_formatter_groups::kName;
+}
+
+bool ContainsAddress(uint32_t groups) {
+ return groups & label_formatter_groups::kAddress;
+}
+
+bool ContainsEmail(uint32_t groups) {
+ return groups & label_formatter_groups::kEmail;
+}
+
+bool ContainsPhone(uint32_t groups) {
+ return groups & label_formatter_groups::kPhone;
+}
+
+std::set<FieldTypeGroup> GetFieldTypeGroups(uint32_t groups) {
+ std::set<FieldTypeGroup> field_type_groups;
+ if (ContainsName(groups)) {
+ field_type_groups.insert(NAME);
+ }
+ if (ContainsAddress(groups)) {
+ field_type_groups.insert(ADDRESS_HOME);
+ }
+ if (ContainsEmail(groups)) {
+ field_type_groups.insert(EMAIL);
+ }
+ if (ContainsPhone(groups)) {
+ field_type_groups.insert(PHONE_HOME);
+ }
+ return field_type_groups;
+}
+
+} // namespace
+
+std::vector<ServerFieldType> FilterFieldTypes(
+ const std::vector<ServerFieldType>& field_types) {
+ std::vector<ServerFieldType> filtered_field_types;
+ for (const ServerFieldType& field_type : field_types) {
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(field_type).GetStorableType()).group();
+ if (group == NAME || group == ADDRESS_HOME || group == EMAIL ||
+ group == PHONE_HOME) {
+ filtered_field_types.push_back(field_type);
+ }
+ }
+ return filtered_field_types;
+}
+
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types) {
+ uint32_t group_bitmask = 0;
+ for (const ServerFieldType& type : field_types) {
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(type).GetStorableType()).group();
+ switch (group) {
+ case autofill::NAME:
+ group_bitmask |= label_formatter_groups::kName;
+ break;
+ case autofill::ADDRESS_HOME:
+ group_bitmask |= label_formatter_groups::kAddress;
+ break;
+ case autofill::EMAIL:
+ group_bitmask |= label_formatter_groups::kEmail;
+ break;
+ case autofill::PHONE_HOME:
+ group_bitmask |= label_formatter_groups::kPhone;
+ break;
+ default:
+ break;
+ }
+ }
+ return group_bitmask;
+}
+
+std::unique_ptr<LabelFormatter> Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types) {
+ const uint32_t groups = DetermineGroups(field_types);
+
+ if (!ContainsName(groups)) {
+ return nullptr;
+ }
+ if (ContainsAddress(groups) && !ContainsEmail(groups) &&
+ !ContainsPhone(groups)) {
+ return std::make_unique<AddressFormLabelFormatter>(
+ app_locale, focused_field_type, FilterFieldTypes(field_types));
+ }
+ if (ContainsEmail(groups) || ContainsPhone(groups)) {
+ return std::make_unique<ContactFormLabelFormatter>(
+ app_locale, focused_field_type, FilterFieldTypes(field_types),
+ GetFieldTypeGroups(groups));
+ }
+ return nullptr;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.h b/chromium/components/autofill/core/browser/label_formatter_utils.h
new file mode 100644
index 00000000000..80b21942c39
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.h
@@ -0,0 +1,58 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+namespace label_formatter_groups {
+
+// Bits for FieldTypeGroup options.
+// The form contains at least one field associated with the NAME_HOME or
+// NAME_BILLING FieldTypeGroups.
+constexpr uint32_t kName = 1 << 0;
+// The form contains at least one field associated with the ADDRESS_HOME or
+// ADDRESS_BILLING FieldTypeGroups.
+constexpr uint32_t kAddress = 1 << 1;
+// The form contains at least one field associated with the EMAIL
+// FieldTypeGroup.
+constexpr uint32_t kEmail = 1 << 2;
+// The form contains at least one field associated with the PHONE_HOME or
+// PHONE_BILLING FieldTypeGroup.
+constexpr uint32_t kPhone = 1 << 3;
+
+} // namespace label_formatter_groups
+
+// Returns a subset of meaningful ServerFieldTypes found in |field_types|.
+// ServerFieldTypes like NO_SERVER_DATA and UNKNOWN_TYPE are frequently found in
+// the collection of types sent from the frontend. Other types, e.g.
+// COMPANY_NAME and PHONE_FAX_WHOLE_NUMBER, are also sometimes present. These
+// types are not useful to LabelFormatters, so only types related to names,
+// addresses, emails, and phone numbers are in the results.
+std::vector<ServerFieldType> FilterFieldTypes(
+ const std::vector<ServerFieldType>& field_types);
+
+// Returns a bitmask indicating whether the NAME, ADDRESS_HOME, EMAIL, and
+// PHONE_HOME FieldTypeGroups are associated with the given |field_types|.
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types);
+
+// Creates a form-specific LabelFormatter according to |field_types|. If the
+// given |field_types| do not correspond to a LabelFormatter, then nullptr will
+// be returned.
+std::unique_ptr<LabelFormatter> Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
new file mode 100644
index 00000000000..660cb0263d3
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
@@ -0,0 +1,100 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+using label_formatter_groups::kAddress;
+using label_formatter_groups::kEmail;
+using label_formatter_groups::kName;
+using label_formatter_groups::kPhone;
+
+} // namespace
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesNoFiltering) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_LAST, NAME_BILLING_LAST, ADDRESS_HOME_ZIP,
+ ADDRESS_BILLING_ZIP, EMAIL_ADDRESS, PHONE_HOME_NUMBER,
+ PHONE_BILLING_NUMBER};
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesFilterCompany) {
+ const std::vector<ServerFieldType> field_types{NAME_LAST, COMPANY_NAME};
+ const std::vector<ServerFieldType> expected_filtered_field_types{NAME_LAST};
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(expected_filtered_field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesForNoGivenFieldTypes) {
+ const std::vector<ServerFieldType> field_types =
+ std::vector<ServerFieldType>();
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNameAndAddress) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_FIRST, NAME_LAST, ADDRESS_HOME_LINE1,
+ ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNameAndAddress) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_BILLING_FULL, ADDRESS_BILLING_LINE1, ADDRESS_BILLING_CITY,
+ ADDRESS_BILLING_STATE, ADDRESS_BILLING_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNamePhoneAndEmail) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_FULL, PHONE_HOME_CITY_AND_NUMBER, EMAIL_ADDRESS};
+
+ const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNamePhoneAndEmail) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_BILLING_FULL, PHONE_BILLING_WHOLE_NUMBER, EMAIL_ADDRESS};
+
+ const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForUnknownServerFieldType) {
+ const std::vector<ServerFieldType> field_types{UNKNOWN_TYPE, NAME_FULL,
+ ADDRESS_HOME_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForNoServerFieldTypes) {
+ const std::vector<ServerFieldType> field_types =
+ std::vector<ServerFieldType>();
+ const uint32_t expected_group_bitmask = 0;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+} // namespace autofill \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database.cc b/chromium/components/autofill/core/browser/legacy_strike_database.cc
index e6fbef3f7d3..d575b2e43ae 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database.cc
+++ b/chromium/components/autofill/core/browser/legacy_strike_database.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc b/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
index af63074c357..44e60a4ae0c 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc b/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
index e3147f1ee7d..6a5c5ba8fd8 100644
--- a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
+++ b/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
@@ -104,7 +104,7 @@ class LegalMessageLineTest : public ::testing::TestWithParam<TestCase> {
// Verifies that legal message parsing is correct.
TEST_P(LegalMessageLineTest, Parsing) {
std::unique_ptr<base::Value> value(
- base::JSONReader::Read(GetParam().message_json));
+ base::JSONReader::ReadDeprecated(GetParam().message_json));
ASSERT_TRUE(value);
base::DictionaryValue* dictionary = nullptr;
EXPECT_TRUE(value->GetAsDictionary(&dictionary));
@@ -114,9 +114,9 @@ TEST_P(LegalMessageLineTest, Parsing) {
GetParam().escape_apostrophes);
EXPECT_EQ(GetParam().expected_lines, actual_lines);
-};
+}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
TestCases,
LegalMessageLineTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.cc b/chromium/components/autofill/core/browser/local_card_migration_manager.cc
index 764f9159b7f..f77d16d7bde 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager.cc
@@ -10,6 +10,8 @@
#include <vector>
#include "base/bind.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_experiments.h"
@@ -39,7 +41,19 @@ LocalCardMigrationManager::LocalCardMigrationManager(
payments_client_(payments_client),
app_locale_(app_locale),
personal_data_manager_(personal_data_manager),
- weak_ptr_factory_(this) {}
+ weak_ptr_factory_(this) {
+ // This is to initialize StrikeDatabase is if it hasn't been already, so that
+ // its cache would be loaded and ready to use when the first LCMM is created.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillSaveCreditCardUsesStrikeSystemV2) ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ // Only init when |kAutofillSaveCreditCardUsesStrikeSystemV2| is enabled. If
+ // flag is off and LegacyStrikeDatabase instead of StrikeDatabase is used,
+ // this init will cause failure on GetStrikes().
+ client_->GetStrikeDatabase();
+ }
+}
LocalCardMigrationManager::~LocalCardMigrationManager() {}
@@ -62,9 +76,26 @@ bool LocalCardMigrationManager::ShouldOfferLocalCardMigration(
if (!IsCreditCardMigrationEnabled())
return false;
- // Don't show the the prompt if user cancelled/rejected previously.
- if (prefs::IsLocalCardMigrationPromptPreviouslyCancelled(client_->GetPrefs()))
+ // Don't show the prompt if max strike count was reached.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2) &&
+ GetLocalCardMigrationStrikeDatabase()->IsMaxStrikesLimitReached()) {
+ switch (imported_credit_card_record_type) {
+ case FormDataImporter::ImportedCreditCardRecordType::LOCAL_CARD:
+ AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ AutofillMetrics::SaveTypeMetric::LOCAL);
+ break;
+ case FormDataImporter::ImportedCreditCardRecordType::SERVER_CARD:
+ AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ AutofillMetrics::SaveTypeMetric::SERVER);
+ break;
+ }
+ return false;
+ } else if (prefs::IsLocalCardMigrationPromptPreviouslyCancelled(
+ client_->GetPrefs())) {
+ // Don't show the the prompt if user cancelled/rejected previously.
return false;
+ }
// Fetch all migratable credit cards and store in |migratable_credit_cards_|.
GetMigratableCreditCards();
@@ -88,6 +119,9 @@ void LocalCardMigrationManager::AttemptToOfferLocalCardMigration(
return;
migration_request_ = payments::PaymentsClient::MigrationRequestDetails();
+ if (observer_for_testing_)
+ observer_for_testing_->OnDecideToRequestLocalCardMigration();
+
payments_client_->GetUploadDetails(
std::vector<AutofillProfile>(), GetDetectedValues(),
/*active_experiments=*/std::vector<const char*>(), app_locale_,
@@ -116,16 +150,32 @@ void LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(
user_accepted_main_migration_dialog_ = true;
AutofillMetrics::LogLocalCardMigrationPromptMetric(
local_card_migration_origin_, AutofillMetrics::MAIN_DIALOG_ACCEPTED);
+
+ // Log number of LocalCardMigration strikes when migration was accepted.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ base::UmaHistogramCounts1000(
+ "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted",
+ GetLocalCardMigrationStrikeDatabase()->GetStrikes());
+ }
+
+ // If there are cards which aren't selected, add 3 strikes to
+ // LocalCardMigrationStrikeDatabase.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2) &&
+ (selected_card_guids.size() < migratable_credit_cards_.size())) {
+ GetLocalCardMigrationStrikeDatabase()->AddStrikes(
+ LocalCardMigrationStrikeDatabase::
+ kStrikesToAddWhenCardsDeselectedAtMigration);
+ }
+
// Update the |migratable_credit_cards_| with the |selected_card_guids|. This
// will remove any card from |migratable_credit_cards_| of which the GUID is
// not in |selected_card_guids|.
auto card_is_selected = [&selected_card_guids](MigratableCreditCard& card) {
return !base::ContainsValue(selected_card_guids, card.credit_card().guid());
};
- migratable_credit_cards_.erase(
- std::remove_if(migratable_credit_cards_.begin(),
- migratable_credit_cards_.end(), card_is_selected),
- migratable_credit_cards_.end());
+ base::EraseIf(migratable_credit_cards_, card_is_selected);
// Populating risk data and offering migration two-round pop-ups occur
// asynchronously. If |migration_risk_data_| has already been loaded, send the
// migrate local cards request. Otherwise, continue to wait and let
@@ -145,24 +195,44 @@ bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() {
bool migration_experiment_enabled =
features::GetLocalCardMigrationExperimentalFlag() !=
features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
- bool credit_card_upload_enabled = ::autofill::IsCreditCardUploadEnabled(
- client_->GetPrefs(), client_->GetSyncService(),
- client_->GetIdentityManager()->GetPrimaryAccountInfo().email);
+
+ // If |observer_for_testing_| is set, assume we are in a browsertest and
+ // credit card upload should be enabled by default. Cannot get around this as
+ // Chrome OS testing requires an unsupported email domain (i.e.
+ // stub-user@example.com).
+ bool credit_card_upload_enabled =
+ observer_for_testing_ ||
+ ::autofill::IsCreditCardUploadEnabled(
+ client_->GetPrefs(), client_->GetSyncService(),
+ personal_data_manager_->GetAccountInfoForPaymentsServer().email);
+
bool has_google_payments_account =
(payments::GetBillingCustomerId(personal_data_manager_,
payments_client_->GetPrefService()) != 0);
- bool sync_feature_enabled =
- (personal_data_manager_->GetSyncSigninState() ==
- AutofillSyncSigninState::kSignedInAndSyncFeature);
+
+ AutofillSyncSigninState sync_state =
+ personal_data_manager_->GetSyncSigninState();
+
return migration_experiment_enabled && credit_card_upload_enabled &&
- has_google_payments_account && sync_feature_enabled;
+ has_google_payments_account &&
+ // User signed-in and turned sync on.
+ (sync_state == AutofillSyncSigninState::kSignedInAndSyncFeature ||
+ // User signed-in but not turned on sync.
+ (sync_state == AutofillSyncSigninState::
+ kSignedInAndWalletSyncTransportEnabled &&
+ base::FeatureList::IsEnabled(
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser)));
}
void LocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
+ if (observer_for_testing_)
+ observer_for_testing_->OnReceivedGetUploadDetailsResponse();
+
if (result == AutofillClient::SUCCESS) {
migration_request_.context_token = context_token;
legal_message_ = base::DictionaryValue::From(std::move(legal_message));
@@ -196,6 +266,9 @@ void LocalCardMigrationManager::OnDidMigrateLocalCards(
AutofillClient::PaymentsRpcResult result,
std::unique_ptr<std::unordered_map<std::string, std::string>> save_result,
const std::string& display_text) {
+ if (observer_for_testing_)
+ observer_for_testing_->OnReceivedMigrateCardsResponse();
+
if (!save_result)
return;
@@ -203,26 +276,32 @@ void LocalCardMigrationManager::OnDidMigrateLocalCards(
std::vector<CreditCard> migrated_cards;
// Traverse the migratable credit cards to update each migrated card status.
for (MigratableCreditCard& card : migratable_credit_cards_) {
+ // If it is run in a test, count all cards as successfully migrated.
+ if (observer_for_testing_) {
+ migrated_cards.push_back(card.credit_card());
+ continue;
+ }
+
// Not every card exists in the |save_result| since some cards are
// unchecked by the user and not migrated.
auto it = save_result->find(card.credit_card().guid());
- // If current card exists in the |save_result|, update its migration
- // status.
- if (it != save_result->end()) {
- // Server-side response can return SUCCESS, TEMPORARY_FAILURE, or
- // PERMANENT_FAILURE (see SaveResult enum). Branch here depending on
- // which is received.
- if (it->second == kMigrationResultPermanentFailure ||
- it->second == kMigrationResultTemporaryFailure) {
- card.set_migration_status(autofill::MigratableCreditCard::
- MigrationStatus::FAILURE_ON_UPLOAD);
- } else if (it->second == kMigrationResultSuccess) {
- card.set_migration_status(autofill::MigratableCreditCard::
- MigrationStatus::SUCCESS_ON_UPLOAD);
- migrated_cards.push_back(card.credit_card());
- } else {
- NOTREACHED();
- }
+ // If current card does not exist in the |save_result|, skip it.
+ if (it == save_result->end())
+ continue;
+
+ // Otherwise update its migration status. Server-side response can return
+ // SUCCESS, TEMPORARY_FAILURE, or PERMANENT_FAILURE (see SaveResult
+ // enum). Branch here depending on which is received.
+ if (it->second == kMigrationResultPermanentFailure ||
+ it->second == kMigrationResultTemporaryFailure) {
+ card.set_migration_status(
+ autofill::MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD);
+ } else if (it->second == kMigrationResultSuccess) {
+ card.set_migration_status(
+ autofill::MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD);
+ migrated_cards.push_back(card.credit_card());
+ } else {
+ NOTREACHED();
}
}
// Remove cards that were successfully migrated from local storage.
@@ -254,6 +333,9 @@ void LocalCardMigrationManager::OnDidGetMigrationRiskData(
// Send the migration request. Will call payments_client to create a new
// PaymentsRequest. Also create a new callback function OnDidMigrateLocalCards.
void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {
+ if (observer_for_testing_)
+ observer_for_testing_->OnSentMigrateCardsRequest();
+
migration_request_.app_locale = app_locale_;
migration_request_.billing_customer_number = payments::GetBillingCustomerId(
personal_data_manager_, payments_client_->GetPrefService());
@@ -264,6 +346,16 @@ void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {
user_accepted_main_migration_dialog_ = false;
}
+LocalCardMigrationStrikeDatabase*
+LocalCardMigrationManager::GetLocalCardMigrationStrikeDatabase() {
+ if (local_card_migration_strike_database_.get() == nullptr) {
+ local_card_migration_strike_database_ =
+ std::make_unique<LocalCardMigrationStrikeDatabase>(
+ LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase()));
+ }
+ return local_card_migration_strike_database_.get();
+}
+
// Pops up a larger, modal dialog showing the local cards to be uploaded. Pass
// the reference of vector<MigratableCreditCard> and the callback function is
// OnUserAcceptedMainMigrationDialog(). Can be called when user agrees to
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.h b/chromium/components/autofill/core/browser/local_card_migration_manager.h
index 06e5ce5832c..02365d324a1 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager.h
@@ -7,11 +7,13 @@
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
namespace autofill {
@@ -43,7 +45,7 @@ class MigratableCreditCard {
FAILURE_ON_UPLOAD,
};
- MigratableCreditCard(const CreditCard& credit_card);
+ explicit MigratableCreditCard(const CreditCard& credit_card);
~MigratableCreditCard();
CreditCard credit_card() const { return credit_card_; }
@@ -66,6 +68,16 @@ class MigratableCreditCard {
// Owned by FormDataImporter.
class LocalCardMigrationManager {
public:
+ // An observer class used by browsertests that gets notified whenever
+ // particular actions occur.
+ class ObserverForTest {
+ public:
+ virtual void OnDecideToRequestLocalCardMigration() = 0;
+ virtual void OnReceivedGetUploadDetailsResponse() = 0;
+ virtual void OnSentMigrateCardsRequest() = 0;
+ virtual void OnReceivedMigrateCardsResponse() = 0;
+ };
+
// The parameters should outlive the LocalCardMigrationManager.
LocalCardMigrationManager(AutofillClient* client,
payments::PaymentsClient* payments_client,
@@ -123,7 +135,8 @@ class LocalCardMigrationManager {
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message);
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
// Callback after successfully getting the migration save results. Map
// migration save result to each card depending on the |save_result|. Will
@@ -141,6 +154,7 @@ class LocalCardMigrationManager {
payments::PaymentsClient* payments_client_;
private:
+ friend class LocalCardMigrationBrowserTest;
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationPermanentFailure);
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
@@ -150,6 +164,9 @@ class LocalCardMigrationManager {
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
MigrateCreditCard_ToggleIsChosen);
+ // Returns the LocalCardMigrationStrikeDatabase for |client_|.
+ LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase();
+
// Pops up a larger, modal dialog showing the local cards to be uploaded.
void ShowMainMigrationDialog();
@@ -161,6 +178,11 @@ class LocalCardMigrationManager {
// Finalizes the migration request and calls PaymentsClient.
void SendMigrateLocalCardsRequest();
+ // For testing.
+ void SetEventObserverForTesting(ObserverForTest* observer) {
+ observer_for_testing_ = observer;
+ }
+
std::unique_ptr<base::DictionaryValue> legal_message_;
std::string app_locale_;
@@ -187,6 +209,12 @@ class LocalCardMigrationManager {
// Record the triggering source of the local card migration.
AutofillMetrics::LocalCardMigrationOrigin local_card_migration_origin_;
+ // Initialized only during tests.
+ ObserverForTest* observer_for_testing_ = nullptr;
+
+ std::unique_ptr<LocalCardMigrationStrikeDatabase>
+ local_card_migration_strike_database_;
+
base::WeakPtrFactory<LocalCardMigrationManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationManager);
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc b/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
index 6dd9308c48a..9e6e3a98e10 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
@@ -29,6 +29,7 @@
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
@@ -81,6 +82,10 @@ class LocalCardMigrationManagerTest : public testing::Test {
local_card_migration_manager_ = new TestLocalCardMigrationManager(
autofill_driver_.get(), &autofill_client_, payments_client_,
&personal_data_);
+ std::unique_ptr<TestStrikeDatabase> test_strike_database =
+ std::make_unique<TestStrikeDatabase>();
+ strike_database_ = test_strike_database.get();
+ autofill_client_.set_test_strike_database(std::move(test_strike_database));
autofill::TestFormDataImporter* test_form_data_importer =
new TestFormDataImporter(
&autofill_client_, payments_client_,
@@ -108,16 +113,6 @@ class LocalCardMigrationManagerTest : public testing::Test {
request_context_ = nullptr;
}
- void EnableAutofillCreditCardLocalCardMigrationExperiment() {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillCreditCardLocalCardMigration);
- }
-
- void DisableAutofillCreditCardLocalCardMigrationExperiment() {
- scoped_feature_list_.InitAndDisableFeature(
- features::kAutofillCreditCardLocalCardMigration);
- }
-
void FormsSeen(const std::vector<FormData>& forms) {
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
}
@@ -177,6 +172,8 @@ class LocalCardMigrationManagerTest : public testing::Test {
MockAutocompleteHistoryManager autocomplete_history_manager_;
syncer::TestSyncService sync_service_;
base::test::ScopedFeatureList scoped_feature_list_;
+ // Ends up getting owned (and destroyed) by TestAutofillClient:
+ TestStrikeDatabase* strike_database_;
// Ends up getting owned (and destroyed) by TestFormDataImporter:
TestCreditCardSaveManager* credit_card_save_manager_;
// Ends up getting owned (and destroyed) by TestFormDataImporter:
@@ -188,7 +185,8 @@ class LocalCardMigrationManagerTest : public testing::Test {
// Having one local card on file and using it will not trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithOneLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -221,7 +219,8 @@ TEST_F(LocalCardMigrationManagerTest,
// trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseNewCardWithAnyLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -251,7 +250,8 @@ TEST_F(LocalCardMigrationManagerTest,
// migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithMoreLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -297,7 +297,8 @@ TEST_F(LocalCardMigrationManagerTest,
// cards as long as the other local cards are not eligible for migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithInvalidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -330,7 +331,8 @@ TEST_F(LocalCardMigrationManagerTest,
// will trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseServerCardWithOneValidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -379,7 +381,8 @@ TEST_F(LocalCardMigrationManagerTest,
// cards as long as the other local cards are not eligible for migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseServerCardWithNoneValidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -421,7 +424,8 @@ TEST_F(LocalCardMigrationManagerTest,
// is off, will not trigger migration.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_FeatureNotEnabled) {
// Turn off the experiment flag.
- DisableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -448,20 +452,22 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_FeatureNotEnabled) {
}
// Do not trigger migration if user only signs in.
-TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnly) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOff) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillEnableAccountWalletStorage},
+ // Disabled
+ {features::kAutofillEnableLocalCardMigrationForNonSyncUser});
- // Make a non-primary account available with both a refresh token and cookie
- // to be in Sync Transport for Wallet mode, in which case this account is
- // signed in only without sync enabled.
- sync_service_.SetIsAuthenticatedAccountPrimary(false);
- sync_service_.SetActiveDataTypes(
- syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
- /*disabled_features=*/{});
+ // Mock Chrome Sync is disabled.
+ local_card_migration_manager_->ResetSyncState(
+ AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
@@ -483,10 +489,50 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnly) {
EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
}
+// Trigger migration if user only signs in and if experiment is enabled.
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOn) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser,
+ features::kAutofillEnableAccountWalletStorage},
+ // Disabled
+ {});
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+
+ // Mock Chrome Sync is disabled.
+ local_card_migration_manager_->ResetSyncState(
+ AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
+
+ // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ // Add another local credit card.
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid2");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+}
+
// Use one local card with more valid local cards available but billing customer
// number is blank, will not trigger migration.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
@@ -512,7 +558,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) {
// migratable.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_LocalCardMatchMaskedServerCard) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -549,7 +596,8 @@ TEST_F(LocalCardMigrationManagerTest,
// migratable.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_LocalCardMatchFullServerCard) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -581,7 +629,8 @@ TEST_F(LocalCardMigrationManagerTest,
// GetDetectedValues() should includes cardholder name if all cards have it.
TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -613,7 +662,8 @@ TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
// a cardholder name.
TEST_F(LocalCardMigrationManagerTest,
GetDetectedValues_OneCardWithoutCardHolderName) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -644,7 +694,8 @@ TEST_F(LocalCardMigrationManagerTest,
// account.
TEST_F(LocalCardMigrationManagerTest,
GetDetectedValues_IncludeGooglePaymentsAccount) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -675,7 +726,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddMigrateCardsBillableServiceNumberInRequest) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -708,7 +760,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddUploadCardSourceInRequest_CheckoutFlow) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -741,7 +794,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddUploadCardSourceInRequest_SettingsPage) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -770,7 +824,8 @@ TEST_F(LocalCardMigrationManagerTest,
// be triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSettingsPage) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -809,7 +864,8 @@ TEST_F(LocalCardMigrationManagerTest,
// prompt are both triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSubmittedForm) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -840,7 +896,8 @@ TEST_F(LocalCardMigrationManagerTest,
// prompt are not triggered as user previously rejected the prompt.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_DontTriggerFromSubmittedForm) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -877,7 +934,8 @@ TEST_F(LocalCardMigrationManagerTest,
// Verify that given the parsed response from the payments client, the migration
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -918,7 +976,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationTemporaryFailure) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -961,7 +1020,8 @@ TEST_F(LocalCardMigrationManagerTest,
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationPermanentFailure) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -1002,7 +1062,8 @@ TEST_F(LocalCardMigrationManagerTest,
// Verify selected cards are correctly passed to manager.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
@@ -1025,7 +1086,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
}
TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
@@ -1038,4 +1100,175 @@ TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) {
EXPECT_FALSE(personal_data_.GetCreditCardWithGUID("guid1"));
}
+// Use one local card with more valid local cards available, don't show prompt
+// if max strikes reached.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateLocalCreditCard_MaxStrikesReached) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(7);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 7);
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ // Add another local credit card, so it will trigger migration.
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid2");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ base::HistogramTester histogram_tester;
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+
+ // Local card migration not triggered since max strikes have been reached.
+ EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+
+ // Verify that the correct histogram entry was logged.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ AutofillMetrics::SaveTypeMetric::LOCAL, 1);
+}
+
+// Use one server card with more valid local cards available, don't show prompt
+// if max strikes reached.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateServerCreditCard_MaxStrikesReached) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(7);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 7);
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+
+ // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
+ // we will enter below.
+ CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
+ test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
+ test::NextYear().c_str(), "1");
+ credit_card.SetNetworkForMaskedCard(kVisaCard);
+ personal_data_.AddServerCreditCard(credit_card);
+ // Add one valid local credit card, so it will trigger migration
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid1");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ base::HistogramTester histogram_tester;
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+
+ // Local card migration not triggered since max strikes have been reached.
+ EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+
+ // Verify that the correct histogram entry was logged.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ AutofillMetrics::SaveTypeMetric::SERVER, 1);
+}
+
+// When local card migration is attempted and some cards aren't selected,
+// 3 strikes should be added.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateCreditCard_StrikesAddedWhenSomeCardsNotSelected) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ // LocalCardMigrationStrikeDatabase should initially have no strikes.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 0);
+
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+ test::NextYear().c_str(), "1", "guid2");
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ local_card_migration_manager_->GetMigratableCreditCards();
+
+ // Only select one of the two cards.
+ autofill_client_.set_migration_card_selections(
+ std::vector<std::string>{"guid1"});
+ local_card_migration_manager_->AttemptToOfferLocalCardMigration(true);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+}
+
+// When local card migration is accepted, UMA metrics for LocalCardMigration
+// strike count is logged.
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_StrikeCountUMALogged) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+ test::NextYear().c_str(), "1", "guid2");
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ local_card_migration_manager_->GetMigratableCreditCards();
+
+ // Add 4 LocalCardMigration strikes.
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(4);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 4);
+
+ base::HistogramTester histogram_tester;
+
+ // Select the cards.
+ autofill_client_.set_migration_card_selections(
+ std::vector<std::string>{"guid1", "guid2"});
+ local_card_migration_manager_->AttemptToOfferLocalCardMigration(true);
+
+ // Verify that the strike count was logged when card migration accepted.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted", 4,
+ 1);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc b/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
index 6125d447a75..5c204950aa7 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
@@ -8,6 +8,13 @@
namespace autofill {
+const int LocalCardMigrationStrikeDatabase::kStrikesToRemoveWhenLocalCardAdded =
+ 2;
+const int LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed = 2;
+const int LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed = 3;
+const int LocalCardMigrationStrikeDatabase::
+ kStrikesToAddWhenCardsDeselectedAtMigration = 3;
+
LocalCardMigrationStrikeDatabase::LocalCardMigrationStrikeDatabase(
StrikeDatabase* strike_database)
: StrikeDatabaseIntegratorBase(strike_database) {
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h b/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
index ab25114d903..1124374313e 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
+++ b/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
@@ -18,6 +18,16 @@ class LocalCardMigrationStrikeDatabase : public StrikeDatabaseIntegratorBase {
LocalCardMigrationStrikeDatabase(StrikeDatabase* strike_database);
~LocalCardMigrationStrikeDatabase() override;
+ // Strikes to remove when user adds new local card.
+ static const int kStrikesToRemoveWhenLocalCardAdded;
+ // Strikes to add when user closes LocalCardMigrationBubble.
+ static const int kStrikesToAddWhenBubbleClosed;
+ // Strikes to add when user closes LocalCardMigrationDialog.
+ static const int kStrikesToAddWhenDialogClosed;
+ // Number of strikes to add when user de-selected some local cards during
+ // migration.
+ static const int kStrikesToAddWhenCardsDeselectedAtMigration;
+
std::string GetProjectPrefix() override;
int GetMaxStrikesLimit() override;
long long GetExpiryTimeMicros() override;
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc b/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc
deleted file mode 100644
index c7d3ad022d5..00000000000
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/local_card_migration_strike_database.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/autofill/core/browser/proto/strike_data.pb.h"
-#include "components/autofill/core/browser/test_autofill_clock.h"
-#include "components/autofill/core/browser/test_local_card_migration_strike_database.h"
-#include "components/autofill/core/common/autofill_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-class LocalCardMigrationStrikeDatabaseTest : public ::testing::Test {
- public:
- LocalCardMigrationStrikeDatabaseTest()
- : strike_database_(new StrikeDatabase(InitFilePath())) {}
-
- protected:
- base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- TestLocalCardMigrationStrikeDatabase strike_database_;
-
- private:
- static const base::FilePath InitFilePath() {
- base::ScopedTempDir temp_dir_;
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- const base::FilePath file_path =
- temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
- return file_path;
- }
-
- base::HistogramTester histogram_tester_;
-};
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, MaxStrikesLimitReachedTest) {
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
- // 3 strikes added.
- strike_database_.AddStrikes(3);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
- // 4 strike added, total strike count is 7.
- strike_database_.AddStrikes(4);
- EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- LocalCardMigrationNthStrikeAddedHistogram) {
- // 2 strikes logged.
- strike_database_.AddStrikes(2);
- strike_database_.RemoveStrikes(2);
- // 1 strike logged.
- strike_database_.AddStrike();
- // 2 strikes logged.
- strike_database_.AddStrike();
- std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
- "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration");
- // There should be two buckets, for strike counts of 1 and 2.
- ASSERT_EQ(2U, buckets.size());
- // Bucket for 1 strike should have count of 1.
- EXPECT_EQ(1, buckets[0].count);
- // Bucket for 2 strikes should have count of 2.
- EXPECT_EQ(2, buckets[1].count);
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- AddStrikeForZeroAndNonZeroStrikesTest) {
- EXPECT_EQ(0, strike_database_.GetStrikes());
- strike_database_.AddStrike();
- EXPECT_EQ(1, strike_database_.GetStrikes());
- strike_database_.AddStrikes(2);
- EXPECT_EQ(3, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- ClearStrikesForNonZeroStrikesTest) {
- strike_database_.AddStrikes(3);
- EXPECT_EQ(3, strike_database_.GetStrikes());
- strike_database_.ClearStrikes();
- EXPECT_EQ(0, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, ClearStrikesForZeroStrikesTest) {
- strike_database_.ClearStrikes();
- EXPECT_EQ(0, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, RemoveExpiredStrikesTest) {
- autofill::TestAutofillClock test_clock;
- test_clock.SetNow(AutofillClock::Now());
- strike_database_.AddStrikes(2);
- EXPECT_EQ(2, strike_database_.GetStrikes());
-
- // Advance clock to past expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- // One strike should be removed.
- strike_database_.RemoveExpiredStrikes();
- EXPECT_EQ(1, strike_database_.GetStrikes());
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
new file mode 100644
index 00000000000..06674d12c2d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+
+namespace autofill {
+
+AddressFormEventLogger::AddressFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
+ : FormEventLoggerBase("Address",
+ is_in_main_frame,
+ form_interactions_ukm_logger) {}
+
+AddressFormEventLogger::~AddressFormEventLogger() = default;
+
+void AddressFormEventLogger::OnDidFillSuggestion(
+ const AutofillProfile& profile,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state) {
+ AutofillProfile::RecordType record_type = profile.record_type();
+ sync_state_ = sync_state;
+
+ form_interactions_ukm_logger_->LogDidFillSuggestion(
+ record_type,
+ /*is_for_for_credit_card=*/false, form, field);
+
+ if (record_type == AutofillProfile::SERVER_PROFILE) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED, form);
+ }
+
+ if (!has_logged_suggestion_filled_) {
+ has_logged_suggestion_filled_ = true;
+ logged_suggestion_filled_was_server_data_ =
+ record_type == AutofillProfile::SERVER_PROFILE;
+ Log(record_type == AutofillProfile::SERVER_PROFILE
+ ? FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
+ : FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ form);
+ }
+
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_FilledProfileSuggestion"));
+}
+
+void AddressFormEventLogger::OnDidSeeFillableDynamicForm(
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, form);
+}
+
+void AddressFormEventLogger::OnDidRefill(AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DID_DYNAMIC_REFILL, form);
+}
+
+void AddressFormEventLogger::OnSubsequentRefillAttempt(
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, form);
+}
+
+void AddressFormEventLogger::RecordPollSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_PolledProfileSuggestions"));
+}
+
+void AddressFormEventLogger::RecordParseForm() {
+ base::RecordAction(base::UserMetricsAction("Autofill_ParsedProfileForm"));
+}
+
+void AddressFormEventLogger::RecordShowSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_ShowedProfileSuggestions"));
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
new file mode 100644
index 00000000000..a115ffbde83
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
+
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+
+namespace autofill {
+
+class AddressFormEventLogger : public FormEventLoggerBase {
+ public:
+ AddressFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
+
+ ~AddressFormEventLogger() override;
+
+ void OnDidFillSuggestion(const AutofillProfile& profile,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidSeeFillableDynamicForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnDidRefill(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnSubsequentRefillAttempt(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ protected:
+ void RecordPollSuggestions() override;
+ void RecordParseForm() override;
+ void RecordShowSuggestions() override;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
diff --git a/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc
new file mode 100644
index 00000000000..ea19e7317b9
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc
@@ -0,0 +1,194 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_data_importer.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/validation.h"
+
+namespace autofill {
+
+CreditCardFormEventLogger::CreditCardFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+ PersonalDataManager* personal_data_manager,
+ AutofillClient* client)
+ : FormEventLoggerBase("CreditCard",
+ is_in_main_frame,
+ form_interactions_ukm_logger),
+ personal_data_manager_(personal_data_manager),
+ client_(client) {}
+
+CreditCardFormEventLogger::~CreditCardFormEventLogger() = default;
+
+void CreditCardFormEventLogger::OnDidSelectMaskedServerCardSuggestion(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, form);
+ if (!has_logged_masked_server_card_suggestion_selected_) {
+ has_logged_masked_server_card_suggestion_selected_ = true;
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::SetBankNameAvailable() {
+ has_logged_bank_name_available_ = true;
+}
+
+void CreditCardFormEventLogger::OnDidFillSuggestion(
+ const CreditCard& credit_card,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state) {
+ CreditCard::RecordType record_type = credit_card.record_type();
+ sync_state_ = sync_state;
+
+ form_interactions_ukm_logger_->LogDidFillSuggestion(
+ record_type,
+ /*is_for_credit_card=*/true, form, field);
+
+ if (record_type == CreditCard::MASKED_SERVER_CARD)
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, form);
+ else if (record_type == CreditCard::FULL_SERVER_CARD)
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED, form);
+ else
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED, form);
+
+ if (!has_logged_suggestion_filled_) {
+ has_logged_suggestion_filled_ = true;
+ logged_suggestion_filled_was_server_data_ =
+ record_type == CreditCard::MASKED_SERVER_CARD ||
+ record_type == CreditCard::FULL_SERVER_CARD;
+ logged_suggestion_filled_was_masked_server_card_ =
+ record_type == CreditCard::MASKED_SERVER_CARD;
+ if (record_type == CreditCard::MASKED_SERVER_CARD) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, form);
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+ } else if (record_type == CreditCard::FULL_SERVER_CARD) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, form);
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, form);
+ }
+ }
+
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_FilledCreditCardSuggestion"));
+}
+
+void CreditCardFormEventLogger::RecordPollSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_PolledCreditCardSuggestions"));
+}
+
+void CreditCardFormEventLogger::RecordParseForm() {
+ base::RecordAction(base::UserMetricsAction("Autofill_ParsedCreditCardForm"));
+}
+
+void CreditCardFormEventLogger::RecordShowSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_ShowedCreditCardSuggestions"));
+}
+
+void CreditCardFormEventLogger::LogWillSubmitForm(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_masked_server_card_) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::LogFormSubmitted(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_masked_server_card_) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::LogUkmInteractedWithForm(
+ FormSignature form_signature) {
+ form_interactions_ukm_logger_->LogInteractedWithForm(
+ /*is_for_credit_card=*/true, local_record_type_count_,
+ server_record_type_count_, form_signature);
+}
+
+void CreditCardFormEventLogger::OnSuggestionsShownOnce() {
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+}
+
+void CreditCardFormEventLogger::OnSuggestionsShownSubmittedOnce(
+ const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ const CreditCard credit_card =
+ client_->GetFormDataImporter()->ExtractCreditCardFromForm(form);
+ Log(GetCardNumberStatusFormEvent(credit_card), form);
+ }
+}
+
+void CreditCardFormEventLogger::OnLog(const std::string& name,
+ FormEvent event) const {
+ // Log in a different histogram for credit card forms on nonsecure pages so
+ // that form interactions on nonsecure pages can be analyzed on their own.
+ if (!is_context_secure_) {
+ base::UmaHistogramEnumeration(name + ".OnNonsecurePage", event,
+ NUM_FORM_EVENTS);
+ }
+}
+
+void CreditCardFormEventLogger::Log(BankNameDisplayedFormEvent event) const {
+ DCHECK_LT(event, BANK_NAME_NUM_FORM_EVENTS);
+ const std::string name("Autofill.FormEvents.CreditCard.BankNameDisplayed");
+ base::UmaHistogramEnumeration(name, event, BANK_NAME_NUM_FORM_EVENTS);
+}
+
+FormEvent CreditCardFormEventLogger::GetCardNumberStatusFormEvent(
+ const CreditCard& credit_card) {
+ const base::string16 number = credit_card.number();
+ FormEvent form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD;
+
+ if (number.empty()) {
+ form_event = FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
+ } else if (!HasCorrectLength(number)) {
+ form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD;
+ } else if (!PassesLuhnCheck(number)) {
+ form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD;
+ } else if (personal_data_manager_->IsKnownCard(credit_card)) {
+ form_event = FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD;
+ }
+
+ return form_event;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h
new file mode 100644
index 00000000000..67a16324dae
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+
+namespace autofill {
+
+class CreditCardFormEventLogger : public FormEventLoggerBase {
+ public:
+ // Form Events for autofill with bank name available for display.
+ enum BankNameDisplayedFormEvent {
+ // A dropdown with suggestions was shown and at least one suggestion has a
+ // bank name. Logged at most once per page load.
+ FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE = 0,
+ // A server suggestion was used to fill the form and at least one suggestion
+ // has a bank name. Logged at most once per page load.
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
+ BANK_NAME_NUM_FORM_EVENTS,
+ };
+
+ CreditCardFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+ PersonalDataManager* personal_data_manager,
+ AutofillClient* client);
+
+ ~CreditCardFormEventLogger() override;
+
+ inline void set_is_context_secure(bool is_context_secure) {
+ is_context_secure_ = is_context_secure;
+ }
+
+ void OnDidSelectMaskedServerCardSuggestion(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state);
+
+ void SetBankNameAvailable();
+
+ // In case of masked cards, caller must make sure this gets called before
+ // the card is upgraded to a full card.
+ void OnDidFillSuggestion(const CreditCard& credit_card,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state);
+
+ protected:
+ // FormEventLoggerBase pure-virtual overrides.
+ void RecordPollSuggestions() override;
+ void RecordParseForm() override;
+ void RecordShowSuggestions() override;
+
+ // FormEventLoggerBase virtual overrides.
+ void LogWillSubmitForm(const FormStructure& form) override;
+ void LogFormSubmitted(const FormStructure& form) override;
+ void LogUkmInteractedWithForm(FormSignature form_signature) override;
+ void OnSuggestionsShownOnce() override;
+ void OnSuggestionsShownSubmittedOnce(const FormStructure& form) override;
+ void OnLog(const std::string& name, FormEvent event) const override;
+
+ // Bringing base class' Log function into scope to allow overloading.
+ using FormEventLoggerBase::Log;
+
+ private:
+ void Log(BankNameDisplayedFormEvent event) const;
+ FormEvent GetCardNumberStatusFormEvent(const CreditCard& credit_card);
+
+ bool is_context_secure_ = false;
+ bool has_logged_bank_name_available_ = false;
+ bool has_logged_masked_server_card_suggestion_selected_ = false;
+ bool logged_suggestion_filled_was_masked_server_card_ = false;
+
+ // Weak references.
+ PersonalDataManager* personal_data_manager_;
+ AutofillClient* client_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
diff --git a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
new file mode 100644
index 00000000000..99025b5070b
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
@@ -0,0 +1,199 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/time/time.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/common/form_field_data.h"
+#include "components/autofill/core/common/signatures_util.h"
+
+namespace autofill {
+
+FormEventLoggerBase::FormEventLoggerBase(
+ const std::string& form_type_name,
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
+ : form_type_name_(form_type_name),
+ is_in_main_frame_(is_in_main_frame),
+ form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
+
+FormEventLoggerBase::~FormEventLoggerBase() = default;
+
+void FormEventLoggerBase::OnDidInteractWithAutofillableForm(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ if (!has_logged_interacted_) {
+ has_logged_interacted_ = true;
+ LogUkmInteractedWithForm(form.form_signature());
+ Log(FORM_EVENT_INTERACTED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::OnDidPollSuggestions(
+ const FormFieldData& field,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ // Record only one poll user action for consecutive polls of the same field.
+ // This is to avoid recording too many poll actions (for example when a user
+ // types in a field, triggering multiple queries) to make the analysis more
+ // simple.
+ if (!field.SameFieldAs(last_polled_field_)) {
+ RecordPollSuggestions();
+ last_polled_field_ = field;
+ }
+}
+
+void FormEventLoggerBase::OnDidParseForm(const FormStructure& form) {
+ Log(FORM_EVENT_DID_PARSE_FORM, form);
+ RecordParseForm();
+}
+
+void FormEventLoggerBase::OnPopupSuppressed(const FormStructure& form,
+ const AutofillField& field) {
+ Log(FORM_EVENT_POPUP_SUPPRESSED, form);
+ if (!has_logged_popup_suppressed_) {
+ has_logged_popup_suppressed_ = true;
+ Log(FORM_EVENT_POPUP_SUPPRESSED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::OnDidShowSuggestions(
+ const FormStructure& form,
+ const AutofillField& field,
+ const base::TimeTicks& form_parsed_timestamp,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ form_interactions_ukm_logger_->LogSuggestionsShown(form, field,
+ form_parsed_timestamp);
+
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN, form);
+ if (!has_logged_suggestions_shown_) {
+ has_logged_suggestions_shown_ = true;
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, form);
+ OnSuggestionsShownOnce();
+ }
+
+ RecordShowSuggestions();
+}
+
+void FormEventLoggerBase::OnWillSubmitForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ // Not logging this kind of form if we haven't logged a user interaction.
+ if (!has_logged_interacted_)
+ return;
+
+ // Not logging twice.
+ if (has_logged_will_submit_)
+ return;
+ has_logged_will_submit_ = true;
+
+ LogWillSubmitForm(form);
+
+ if (has_logged_suggestions_shown_) {
+ Log(FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, form);
+ }
+
+ base::RecordAction(base::UserMetricsAction("Autofill_OnWillSubmitForm"));
+}
+
+void FormEventLoggerBase::OnFormSubmitted(bool force_logging,
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ // Not logging this kind of form if we haven't logged a user interaction.
+ if (!has_logged_interacted_)
+ return;
+
+ // Not logging twice.
+ if (has_logged_submitted_)
+ return;
+ has_logged_submitted_ = true;
+
+ LogFormSubmitted(form);
+
+ if (has_logged_suggestions_shown_ || force_logging) {
+ Log(FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, form);
+ OnSuggestionsShownSubmittedOnce(form);
+ }
+}
+
+void FormEventLoggerBase::Log(FormEvent event,
+ const FormStructure& form) const {
+ DCHECK_LT(event, NUM_FORM_EVENTS);
+ std::string name("Autofill.FormEvents." + form_type_name_);
+ base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
+
+ // Log UKM metrics for only autofillable form events.
+ if (form.IsAutofillable()) {
+ form_interactions_ukm_logger_->LogFormEvent(event, form.GetFormTypes(),
+ form.form_parsed_timestamp());
+ }
+
+ // Log again in a different histogram so that iframes can be analyzed on
+ // their own.
+ base::UmaHistogramEnumeration(
+ name + (is_in_main_frame_ ? ".IsInMainFrame" : ".IsInIFrame"), event,
+ NUM_FORM_EVENTS);
+
+ // Allow specialized type of logging.
+ OnLog(name, event);
+
+ // Logging again in a different histogram for segmentation purposes.
+ if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
+ name += ".WithNoData";
+ else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
+ name += ".WithOnlyServerData";
+ else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
+ name += ".WithOnlyLocalData";
+ else
+ name += ".WithBothServerAndLocalData";
+ base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
+ base::UmaHistogramEnumeration(
+ name + AutofillMetrics::GetMetricsSyncStateSuffix(sync_state_), event,
+ NUM_FORM_EVENTS);
+}
+
+void FormEventLoggerBase::LogWillSubmitForm(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::LogFormSubmitted(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::LogUkmInteractedWithForm(
+ FormSignature form_signature) {
+ form_interactions_ukm_logger_->LogInteractedWithForm(
+ /*is_for_credit_card=*/false, local_record_type_count_,
+ server_record_type_count_, form_signature);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
new file mode 100644
index 00000000000..173df3b0ddd
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
@@ -0,0 +1,107 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/common/form_field_data.h"
+
+namespace autofill {
+
+// Utility to log autofill form events in the relevant histograms depending on
+// the presence of server and/or local data.
+class FormEventLoggerBase {
+ public:
+ FormEventLoggerBase(
+ const std::string& form_type_name,
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
+
+ inline void set_server_record_type_count(size_t server_record_type_count) {
+ server_record_type_count_ = server_record_type_count;
+ }
+
+ inline void set_local_record_type_count(size_t local_record_type_count) {
+ local_record_type_count_ = local_record_type_count;
+ }
+
+ void OnDidInteractWithAutofillableForm(const FormStructure& form,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidPollSuggestions(const FormFieldData& field,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidParseForm(const FormStructure& form);
+
+ void OnPopupSuppressed(const FormStructure& form, const AutofillField& field);
+
+ void OnDidShowSuggestions(const FormStructure& form,
+ const AutofillField& field,
+ const base::TimeTicks& form_parsed_timestamp,
+ AutofillSyncSigninState sync_state);
+
+ void OnWillSubmitForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnFormSubmitted(bool force_logging,
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ protected:
+ virtual ~FormEventLoggerBase();
+
+ void Log(FormEvent event, const FormStructure& form) const;
+
+ virtual void RecordPollSuggestions() = 0;
+ virtual void RecordParseForm() = 0;
+ virtual void RecordShowSuggestions() = 0;
+
+ virtual void LogWillSubmitForm(const FormStructure& form);
+ virtual void LogFormSubmitted(const FormStructure& form);
+
+ // Only used for UKM backward compatibility since it depends on IsCreditCard.
+ // TODO (crbug.com/925913): Remove IsCreditCard from UKM logs amd replace with
+ // |form_type_name_|.
+ virtual void LogUkmInteractedWithForm(FormSignature form_signature);
+
+ virtual void OnSuggestionsShownOnce() {}
+ virtual void OnSuggestionsShownSubmittedOnce(const FormStructure& form) {}
+ virtual void OnLog(const std::string& name, FormEvent event) const {}
+
+ // Constructor parameters.
+ std::string form_type_name_;
+ bool is_in_main_frame_;
+
+ // State variables.
+ size_t server_record_type_count_ = 0;
+ size_t local_record_type_count_ = 0;
+ bool has_logged_interacted_ = false;
+ bool has_logged_popup_suppressed_ = false;
+ bool has_logged_suggestions_shown_ = false;
+ bool has_logged_suggestion_filled_ = false;
+ bool has_logged_will_submit_ = false;
+ bool has_logged_submitted_ = false;
+ bool logged_suggestion_filled_was_server_data_ = false;
+
+ // The last field that was polled for suggestions.
+ FormFieldData last_polled_field_;
+
+ // Weak reference.
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger_;
+
+ AutofillSyncSigninState sync_state_ = AutofillSyncSigninState::kNumSyncStates;
+};
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
diff --git a/chromium/components/autofill/core/browser/metrics/form_events.h b/chromium/components/autofill/core/browser/metrics/form_events.h
new file mode 100644
index 00000000000..40cbbe0517d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_events.h
@@ -0,0 +1,97 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_
+
+namespace autofill {
+
+// Form Events for autofill.
+// These events are triggered separetly for address and credit card forms.
+enum FormEvent {
+ // User interacted with a field of this kind of form. Logged only once per
+ // page load.
+ FORM_EVENT_INTERACTED_ONCE = 0,
+ // A dropdown with suggestions was shown.
+ FORM_EVENT_SUGGESTIONS_SHOWN,
+ // Same as above, but recoreded only once per page load.
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE,
+ // A local suggestion was used to fill the form.
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED,
+ // A server suggestion was used to fill the form.
+ // When dealing with credit cards, this means a full server card was used
+ // to fill.
+ FORM_EVENT_SERVER_SUGGESTION_FILLED,
+ // A masked server card suggestion was used to fill the form.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED,
+ // A suggestion was used to fill the form. The origin type (local or server
+ // or masked server card) of the first selected within a page load will
+ // determine which of the following two will be fired.
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
+ // A form was submitted. Depending on the user filling a local, server,
+ // masked server card or no suggestion one of the following will be
+ // triggered. Only one of the following four will be triggered per page
+ // load.
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
+ // A masked server card suggestion was selected to fill the form.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED,
+ // Same as above but only triggered once per page load.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
+ // An autofillable form is about to be submitted. If the submission is not
+ // interrupted by JavaScript, the "form submitted" events above will also be
+ // logged. Depending on the user filling a local, server, masked server card
+ // or no suggestion one of the following will be triggered, at most once per
+ // page load.
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
+ // A dropdown with suggestions was shown and a form was submitted after
+ // that.
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
+ // A dropdown with suggestions was shown and a form is about to be
+ // submitted. If the submission is not interrupted by JavaScript, the "form
+ // submitted" event above will also be logged.
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE,
+ // A dropdown with credit card suggestions was shown, but they were not used
+ // to fill the form. Depending on the user submitting a card known by the
+ // browser, submitting a card that the browser does not know about,
+ // submitting with an empty card number, submitting with a card number of
+ // wrong size or submitting with a card number that does not pass luhn
+ // check, one of the following will be triggered. At most one of the
+ // following five metrics will be triggered per submit.
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
+
+ // The form was changed dynamically. This value has been deprecated.
+ FORM_EVENT_DID_SEE_DYNAMIC_FORM,
+ // The form was changed dynamically and was fillable.
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ // There was a dynamic change of the form and it got re-filled
+ // automatically.
+ FORM_EVENT_DID_DYNAMIC_REFILL,
+ // The form dynamically changed another time after the refill.
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL,
+ // The popup was suppressed because the native view couldn't be created.
+ FORM_EVENT_POPUP_SUPPRESSED,
+ // Same as above, but recoreded only once per page load.
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE,
+
+ // The form was parsed.
+ FORM_EVENT_DID_PARSE_FORM,
+
+ NUM_FORM_EVENTS,
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_ \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
index 2c065752666..ff4367110f0 100644
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
+++ b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/password_requirements_spec_fetcher_impl.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/md5.h"
#include "base/metrics/histogram_functions.h"
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.cc b/chromium/components/autofill/core/browser/payments/payments_client.cc
index ac4803ae4a3..3fda27d89e6 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@@ -342,7 +343,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
PaymentsClient::UploadCardSource upload_card_source)
: addresses_(addresses),
@@ -441,6 +443,16 @@ class GetUploadDetailsRequest : public PaymentsRequest {
base::Value* dictionary_value = response.FindKey("legal_message");
if (dictionary_value)
legal_message_ = std::make_unique<base::Value>(dictionary_value->Clone());
+
+ base::Value* list_ptr = response.FindKey("supported_card_bin_ranges");
+ if (list_ptr && list_ptr->is_list()) {
+ for (base::Value& result : list_ptr->GetList()) {
+ DCHECK(result.is_dict());
+ base::Optional<int> start = response.FindIntKey("start");
+ base::Optional<int> end = response.FindIntKey("end");
+ supported_card_bin_ranges_.push_back(std::make_pair(*start, *end));
+ }
+ }
}
bool IsResponseComplete() override {
@@ -448,7 +460,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
}
void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override {
- std::move(callback_).Run(result, context_token_, std::move(legal_message_));
+ std::move(callback_).Run(result, context_token_, std::move(legal_message_),
+ supported_card_bin_ranges_);
}
private:
@@ -459,10 +472,12 @@ class GetUploadDetailsRequest : public PaymentsRequest {
std::string app_locale_;
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)>
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)>
callback_;
base::string16 context_token_;
std::unique_ptr<base::Value> legal_message_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
const int billable_service_number_;
PaymentsClient::UploadCardSource upload_card_source_;
};
@@ -770,7 +785,8 @@ void PaymentsClient::GetUploadDetails(
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source) {
IssueRequest(
@@ -845,11 +861,11 @@ void PaymentsClient::InitializeResourceRequest() {
// Add Chrome experiment state to the request headers.
net::HttpRequestHeaders headers;
// User is always signed-in to be able to upload card to Google Payments.
- variations::AppendVariationHeaders(
+ variations::AppendVariationsHeader(
resource_request_->url,
is_off_the_record_ ? variations::InIncognito::kYes
: variations::InIncognito::kNo,
- variations::SignedIn::kYes, &resource_request_->headers);
+ variations::SignedIn::kYes, resource_request_.get());
}
}
@@ -878,7 +894,8 @@ void PaymentsClient::OnSimpleLoaderCompleteInternal(int response_code,
// Valid response.
case net::HTTP_OK: {
std::string error_code;
- std::unique_ptr<base::Value> message_value = base::JSONReader::Read(data);
+ std::unique_ptr<base::Value> message_value =
+ base::JSONReader::ReadDeprecated(data);
if (message_value.get() && message_value->is_dict()) {
response_dict =
base::Value::FromUniquePtrValue(std::move(message_value));
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.h b/chromium/components/autofill/core/browser/payments/payments_client.h
index be0bc533999..ad6c075aa75 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/payments_client.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CLIENT_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CLIENT_H_
+#include <utility>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
@@ -178,7 +180,8 @@ class PaymentsClient {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source =
UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE);
diff --git a/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc b/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
index 1b733047735..6f9edcede0d 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -5,6 +5,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
@@ -24,6 +25,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
+#include "components/variations/net/variations_http_headers.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_http_header_provider.h"
#include "services/identity/public/cpp/identity_test_environment.h"
@@ -64,11 +66,13 @@ class PaymentsClientTest : public testing::Test {
server_id_.clear();
real_pan_.clear();
legal_message_.reset();
+ has_variations_header_ = false;
factory()->SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) {
intercepted_headers_ = request.headers;
intercepted_body_ = network::GetUploadData(request);
+ has_variations_header_ = variations::HasVariationsHeader(request);
}));
test_shared_loader_factory_ =
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
@@ -115,11 +119,14 @@ class PaymentsClientTest : public testing::Test {
real_pan_ = real_pan;
}
- void OnDidGetUploadDetails(AutofillClient::PaymentsRpcResult result,
- const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ void OnDidGetUploadDetails(
+ AutofillClient::PaymentsRpcResult result,
+ const base::string16& context_token,
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
result_ = result;
legal_message_ = std::move(legal_message);
+ supported_card_bin_ranges_ = supported_card_bin_ranges;
}
void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
@@ -207,7 +214,7 @@ class PaymentsClientTest : public testing::Test {
const std::string& GetUploadData() { return intercepted_body_; }
- net::HttpRequestHeaders* GetRequestHeaders() { return &intercepted_headers_; }
+ bool HasVariationsHeader() { return has_variations_header_; }
// Issues access token in response to any access token request. This will
// start the Payments Request which requires the authentication.
@@ -233,6 +240,7 @@ class PaymentsClientTest : public testing::Test {
std::string server_id_;
std::string real_pan_;
std::unique_ptr<base::Value> legal_message_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
std::vector<MigratableCreditCard> migratable_credit_cards_;
std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_;
std::string display_text_;
@@ -245,6 +253,7 @@ class PaymentsClientTest : public testing::Test {
identity::IdentityTestEnvironment identity_test_env_;
net::HttpRequestHeaders intercepted_headers_;
+ bool has_variations_header_;
std::string intercepted_body_;
base::WeakPtrFactory<PaymentsClientTest> weak_ptr_factory_;
@@ -536,10 +545,8 @@ TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTest) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartGettingUploadDetails();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -554,10 +561,8 @@ TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartGettingUploadDetails();
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -572,10 +577,8 @@ TEST_F(PaymentsClientTest, UploadCardVariationsTest) {
StartUploading(/*include_cvc=*/true);
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -590,10 +593,8 @@ TEST_F(PaymentsClientTest, UploadCardVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartUploading(/*include_cvc=*/true);
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -608,10 +609,8 @@ TEST_F(PaymentsClientTest, UnmaskCardVariationsTest) {
StartUnmasking();
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -626,10 +625,8 @@ TEST_F(PaymentsClientTest, UnmaskCardVariationsTestExperimentOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartUnmasking();
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -645,10 +642,8 @@ TEST_F(PaymentsClientTest, MigrateCardsVariationsTest) {
StartMigrating(/*has_cardholder_name=*/true);
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -663,10 +658,8 @@ TEST_F(PaymentsClientTest, MigrateCardsVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartMigrating(/*has_cardholder_name=*/true);
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
diff --git a/chromium/components/autofill/core/browser/payments/test_payments_client.cc b/chromium/components/autofill/core/browser/payments/test_payments_client.cc
index 8bf0f86a13d..e58fe67248f 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.cc
@@ -30,7 +30,8 @@ void TestPaymentsClient::GetUploadDetails(
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
PaymentsClient::UploadCardSource upload_card_source) {
upload_details_addresses_ = addresses;
@@ -38,11 +39,11 @@ void TestPaymentsClient::GetUploadDetails(
active_experiments_ = active_experiments;
billable_service_number_ = billable_service_number;
upload_card_source_ = upload_card_source;
- std::move(callback).Run(app_locale == "en-US"
- ? AutofillClient::SUCCESS
- : AutofillClient::PERMANENT_FAILURE,
- base::ASCIIToUTF16("this is a context token"),
- std::unique_ptr<base::Value>(nullptr));
+ std::move(callback).Run(
+ app_locale == "en-US" ? AutofillClient::SUCCESS
+ : AutofillClient::PERMANENT_FAILURE,
+ base::ASCIIToUTF16("this is a context token"),
+ std::unique_ptr<base::Value>(nullptr), supported_card_bin_ranges_);
}
void TestPaymentsClient::UploadCard(
@@ -71,5 +72,10 @@ void TestPaymentsClient::SetSaveResultForCardsMigration(
save_result_ = std::move(save_result);
}
+void TestPaymentsClient::SetSupportedBINRanges(
+ std::vector<std::pair<int, int>> bin_ranges) {
+ supported_card_bin_ranges_ = bin_ranges;
+}
+
} // namespace payments
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/payments/test_payments_client.h b/chromium/components/autofill/core/browser/payments/test_payments_client.h
index 01e9d008903..e7f6c928e48 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_PAYMENTS_CLIENT_H_
#include <string>
+#include <utility>
#include <vector>
#include "components/autofill/core/browser/payments/payments_client.h"
@@ -34,7 +35,8 @@ class TestPaymentsClient : public payments::PaymentsClient {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source =
UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE) override;
@@ -55,6 +57,8 @@ class TestPaymentsClient : public payments::PaymentsClient {
std::unique_ptr<std::unordered_map<std::string, std::string>>
save_result);
+ void SetSupportedBINRanges(std::vector<std::pair<int, int>> bin_ranges);
+
int detected_values_in_upload_details() const { return detected_values_; }
const std::vector<AutofillProfile>& addresses_in_upload_details() const {
return upload_details_addresses_;
@@ -74,6 +78,7 @@ class TestPaymentsClient : public payments::PaymentsClient {
private:
std::string server_id_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
std::vector<AutofillProfile> upload_details_addresses_;
std::vector<AutofillProfile> upload_card_addresses_;
int detected_values_;
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.cc b/chromium/components/autofill/core/browser/personal_data_manager.cc
index 7c66782f7a5..902884a4b06 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager.cc
@@ -13,6 +13,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
@@ -268,7 +269,6 @@ void PersonalDataManager::Init(
identity::IdentityManager* identity_manager,
AutofillProfileValidator* client_profile_validator,
history::HistoryService* history_service,
- GaiaCookieManagerService* cookie_manager_service,
bool is_off_the_record) {
CountryNames::SetLocaleString(app_locale_);
database_helper_->Init(profile_database, account_database);
@@ -287,12 +287,11 @@ void PersonalDataManager::Init(
if (history_service_)
history_service_->AddObserver(this);
- // Listen for cookie deletion by the user.
- cookie_manager_service_ = cookie_manager_service;
- if (cookie_manager_service_)
- cookie_manager_service_->AddObserver(this);
-
+ // Listen for account cookie deletion by the user.
identity_manager_ = identity_manager;
+ if (identity_manager_)
+ identity_manager_->AddObserver(this);
+
is_off_the_record_ = is_off_the_record;
if (!is_off_the_record_)
@@ -340,9 +339,9 @@ void PersonalDataManager::Shutdown() {
history_service_->RemoveObserver(this);
history_service_ = nullptr;
- if (cookie_manager_service_)
- cookie_manager_service_->RemoveObserver(this);
- cookie_manager_service_ = nullptr;
+ if (identity_manager_)
+ identity_manager_->RemoveObserver(this);
+ identity_manager_ = nullptr;
}
void PersonalDataManager::OnSyncServiceInitialized(
@@ -483,16 +482,12 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
}
is_data_loaded_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " refresh is done, notifying PersonalDataChanged";
NotifyPersonalDataChanged();
}
}
void PersonalDataManager::AutofillMultipleChanged() {
has_synced_new_data_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " has synced new data, refreshing";
Refresh();
}
@@ -536,7 +531,7 @@ void PersonalDataManager::OnSyncShutdown(syncer::SyncService* sync_service) {
sync_service_ = nullptr;
}
-AccountInfo PersonalDataManager::GetAccountInfoForPaymentsServer() const {
+CoreAccountInfo PersonalDataManager::GetAccountInfoForPaymentsServer() const {
// If butter is enabled or the feature to get the Payment Identity from Sync
// is enabled, return the account of the active signed-in user irrespective of
// whether they enabled sync or not.
@@ -558,7 +553,7 @@ bool PersonalDataManager::IsSyncFeatureEnabled() const {
!database_helper_->IsUsingAccountStorageForServerData();
}
-void PersonalDataManager::OnGaiaCookieDeletedByUserAction() {
+void PersonalDataManager::OnAccountsCookieDeletedByUserAction() {
// Clear all the Sync Transport feature opt-ins.
::autofill::prefs::ClearSyncTransportOptIns(pref_service_);
}
@@ -630,19 +625,19 @@ void PersonalDataManager::RecordUseOf(const AutofillDataModel& data_model) {
AutofillProfile* profile = GetProfileByGUID(data_model.guid());
if (profile) {
- if (profile->record_type() == AutofillProfile::LOCAL_PROFILE) {
- // We can't make the change directly on the web_profiles_, the update
- // should happen in the database first.
- AutofillProfile updated_profile(*profile);
- updated_profile.RecordAndLogUse();
- UpdateProfileInDB(updated_profile);
- } else if (profile->record_type() == AutofillProfile::SERVER_PROFILE) {
- profile->RecordAndLogUse();
- // TODO(crbug.com/864519): Update this once addresses support account
- // storage, and also use the server database.
- database_helper_->GetLocalDatabase()->UpdateServerAddressMetadata(
- *profile);
- Refresh();
+ profile->RecordAndLogUse();
+
+ switch (profile->record_type()) {
+ case AutofillProfile::LOCAL_PROFILE:
+ UpdateProfileInDB(*profile, /*enforced=*/true);
+ break;
+ case AutofillProfile::SERVER_PROFILE:
+ DCHECK(database_helper_->GetServerDatabase())
+ << "Recording use of server address without server storage.";
+ database_helper_->GetServerDatabase()->UpdateServerAddressMetadata(
+ *profile);
+ Refresh();
+ break;
}
}
}
@@ -1006,19 +1001,45 @@ void PersonalDataManager::UpdateClientValidityStates(
bool update_validation =
pref_service_->GetInteger(prefs::kAutofillLastVersionValidated) <
CHROME_VERSION_MAJOR;
+
+ DVLOG(1) << "Autofill profile client validation "
+ << (update_validation ? "needs to be" : "has already been")
+ << " performed for this version";
+
for (const auto* profile : profiles) {
if (!profile->is_client_validity_states_updated() || update_validation) {
+ profile->set_is_client_validity_states_updated(false);
+ ongoing_profile_changes_[profile->guid()].push_back(
+ AutofillProfileDeepChange(AutofillProfileChange::UPDATE, *profile));
+ ongoing_profile_changes_[profile->guid()].back().set_enforce_update();
client_profile_validator_->StartProfileValidation(
profile, base::BindOnce(&PersonalDataManager::OnValidated,
weak_factory_.GetWeakPtr()));
}
}
+
// Set the pref to the current major version if already not set.
if (update_validation)
pref_service_->SetInteger(prefs::kAutofillLastVersionValidated,
CHROME_VERSION_MAJOR);
}
+bool PersonalDataManager::UpdateClientValidityStates(
+ const AutofillProfile& profile) {
+ if (!base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation) ||
+ !client_profile_validator_ ||
+ profile.is_client_validity_states_updated()) {
+ OnValidated(&profile);
+ return false;
+ }
+
+ client_profile_validator_->StartProfileValidation(
+ &profile, base::BindOnce(&PersonalDataManager::OnValidated,
+ weak_factory_.GetWeakPtr()));
+ return true;
+}
+
std::vector<AutofillProfile*> PersonalDataManager::GetServerProfiles() const {
std::vector<AutofillProfile*> result;
if (!IsAutofillProfileEnabled())
@@ -1078,55 +1099,30 @@ std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest()
std::vector<AutofillProfile*> profiles = GetProfiles();
- // Rank the suggestions by frecency (see AutofillDataModel for details).
+ bool use_server_validation = base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation);
+ bool use_client_validation = base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation);
+
+ // Rank the suggestions by frescocency (see AutofillDataModel for details).
+ // Frescocency is frecency + validity score.
const base::Time comparison_time = AutofillClock::Now();
std::sort(profiles.begin(), profiles.end(),
- [comparison_time](const AutofillDataModel* a,
- const AutofillDataModel* b) {
- return a->CompareFrecency(b, comparison_time);
+ [comparison_time, use_client_validation, use_server_validation](
+ const AutofillProfile* a, const AutofillProfile* b) {
+ return a->HasGreaterFrescocencyThan(b, comparison_time,
+ use_client_validation,
+ use_server_validation);
});
return profiles;
}
-// static
-void PersonalDataManager::MaybeRemoveInvalidSuggestions(
- const AutofillType& type,
- std::vector<AutofillProfile*>* profiles) {
- const bool suggest_invalid = base::FeatureList::IsEnabled(
- features::kAutofillSuggestInvalidProfileData);
-
- for (size_t i = 0; i < profiles->size(); ++i) {
- bool is_client_invalid =
- (*profiles)[i]->GetValidityState(type.GetStorableType(),
- AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID;
-
- bool is_server_invalid =
- (*profiles)[i]->GetValidityState(type.GetStorableType(),
- AutofillProfile::SERVER) ==
- AutofillProfile::INVALID;
-
- if ((is_server_invalid || is_client_invalid) && !suggest_invalid)
- (*profiles)[i] = nullptr;
- if (is_server_invalid || is_client_invalid)
- UMA_HISTOGRAM_BOOLEAN("Autofill.InvalidProfileData.UsedForSuggestion",
- suggest_invalid);
- }
-
- if (!suggest_invalid) {
- profiles->erase(
- std::stable_partition(profiles->begin(), profiles->end(),
- [](AutofillProfile* p) { return p != nullptr; }),
- profiles->end());
- }
-}
-
std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
const AutofillType& type,
const base::string16& field_contents,
bool field_is_autofilled,
- const std::vector<ServerFieldType>& other_field_types) {
+ const std::vector<ServerFieldType>& field_types) {
if (IsInAutofillSuggestionsDisabledExperiment())
return std::vector<Suggestion>();
@@ -1134,6 +1130,11 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
base::string16 field_contents_canon =
comparator.NormalizeForComparison(field_contents);
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation)) {
+ UpdateProfilesServerValidityMapsIfNeeded(GetProfiles());
+ }
+
// Get the profiles to suggest, which are already sorted.
std::vector<AutofillProfile*> sorted_profiles = GetProfilesToSuggest();
@@ -1147,9 +1148,6 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
suggestion_selection::RemoveProfilesNotUsedSinceTimestamp(
min_last_used, &sorted_profiles);
}
- // We need the updated information on the validity states of the profiles.
- UpdateProfilesServerValidityMapsIfNeeded(sorted_profiles);
- MaybeRemoveInvalidSuggestions(type, &sorted_profiles);
}
std::vector<AutofillProfile*> matched_profiles;
@@ -1161,19 +1159,21 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
// Don't show two suggestions if one is a subset of the other.
std::vector<AutofillProfile*> unique_matched_profiles;
std::vector<Suggestion> unique_suggestions =
- suggestion_selection::GetUniqueSuggestions(other_field_types, app_locale_,
+ suggestion_selection::GetUniqueSuggestions(field_types, app_locale_,
matched_profiles, suggestions,
&unique_matched_profiles);
// Generate disambiguating labels based on the list of matches.
std::vector<base::string16> labels;
- AutofillProfile::CreateInferredLabels(
- unique_matched_profiles, &other_field_types, type.GetStorableType(), 1,
- app_locale_, &labels);
+ AutofillProfile::CreateInferredLabels(unique_matched_profiles, &field_types,
+ type.GetStorableType(), 1, app_locale_,
+ &labels);
DCHECK_EQ(unique_suggestions.size(), labels.size());
for (size_t i = 0; i < labels.size(); i++) {
+ // A suggestion's label has one line of disambiguating information to show
+ // to the user. However, when the two-line suggestion display experiment is
+ // enabled on desktop, label is replaced by additional label.
unique_suggestions[i].label = labels[i];
- // Used when two-line display is enabled.
unique_suggestions[i].additional_label = labels[i];
}
@@ -1212,7 +1212,7 @@ const std::vector<CreditCard*> PersonalDataManager::GetCreditCardsToSuggest(
if (a_is_expired != b->IsExpired(comparison_time))
return !a_is_expired;
- return a->CompareFrecency(b, comparison_time);
+ return a->HasGreaterFrecencyThan(b, comparison_time);
});
return cards_to_suggest;
@@ -1342,7 +1342,7 @@ void PersonalDataManager::ClearProfileNonSettingsOrigins() {
for (AutofillProfile* profile : GetProfiles()) {
if (profile->origin() != kSettingsOrigin && !profile->origin().empty()) {
profile->set_origin(std::string());
- UpdateProfileInDB(*profile);
+ UpdateProfileInDB(*profile, /*enforced=*/true);
}
}
@@ -1386,9 +1386,7 @@ void PersonalDataManager::MoveJapanCityToStreetAddress() {
: street_address + line_separator + city;
profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, street_address);
profile->SetRawInfo(ADDRESS_HOME_CITY, base::string16());
-
- // Make the update.
- UpdateProfileInDB(*profile);
+ UpdateProfileInDB(*profile, /*enforced=*/true);
}
}
@@ -1397,17 +1395,36 @@ void PersonalDataManager::MoveJapanCityToStreetAddress() {
}
void PersonalDataManager::OnValidated(const AutofillProfile* profile) {
- // We always set a value for country validity state.
- DCHECK(profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) !=
- AutofillProfile::UNVALIDATED);
+ if (!profile)
+ return;
+
+ if (!ProfileChangesAreOnGoing(profile->guid()))
+ return;
// Set the validity states updated, only when the validation has occurred. If
// the rules were not loaded for any reason, don't set the flag.
- if (profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) !=
- AutofillProfile::UNVALIDATED)
- profile->set_is_client_validity_states_updated(true);
+ bool validity_updated =
+ (profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
+ AutofillProfile::CLIENT) !=
+ AutofillProfile::UNVALIDATED);
+
+ // For every relevant profile change on the ongoing_profile_changes_, mark the
+ // change to show that the validation is done, and set the validity of the
+ // profile if the validity was updated.
+ for (const auto& change : ongoing_profile_changes_[profile->guid()]) {
+ if (!profile->EqualsForClientValidationPurpose(*(change.profile())))
+ continue;
+
+ change.validation_effort_made();
+
+ if (validity_updated) {
+ change.profile()->set_is_client_validity_states_updated(true);
+ change.profile()->SetClientValidityFromBitfieldValue(
+ profile->GetClientValidityBitfieldValue());
+ }
+ }
+
+ HandleNextProfileChange(profile->guid());
}
const ProfileValidityMap& PersonalDataManager::GetProfileValidityByGUID(
@@ -1450,7 +1467,7 @@ std::string PersonalDataManager::MergeProfile(
const std::unique_ptr<AutofillProfile>& b) {
if (a->IsVerified() != b->IsVerified())
return !a->IsVerified();
- return a->CompareFrecency(b.get(), comparison_time);
+ return a->HasGreaterFrecencyThan(b.get(), comparison_time);
});
// Set to true if |existing_profiles| already contains an equivalent profile.
@@ -1954,10 +1971,8 @@ void PersonalDataManager::OnAutofillProfileChanged(
const AutofillProfileDeepChange& change) {
const auto& guid = change.key();
const auto& change_type = change.type();
- const auto& profile = change.profile();
-
+ const auto& profile = *(change.profile());
DCHECK(guid == profile.guid());
-
// Happens only in tests.
if (!ProfileChangesAreOnGoing(guid)) {
DVLOG(1) << "Received an unexpected response from database.";
@@ -1976,7 +1991,8 @@ void PersonalDataManager::OnAutofillProfileChanged(
case AutofillProfileChange::UPDATE:
profiles_server_validities_need_update_ = true;
if (profile_exists &&
- !existing_profile->EqualsForUpdatePurposes(profile)) {
+ (change.enforce_update() ||
+ !existing_profile->EqualsForUpdatePurposes(profile))) {
web_profiles_.erase(
FindElementByGUID<AutofillProfile>(web_profiles_, guid));
web_profiles_.push_back(std::make_unique<AutofillProfile>(profile));
@@ -2034,7 +2050,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
Suggestion* suggestion = &suggestions.back();
suggestion->value = credit_card->GetInfo(type, app_locale_);
- suggestion->icon = base::UTF8ToUTF16(credit_card->network());
+ suggestion->icon = credit_card->network();
suggestion->backend_id = credit_card->guid();
suggestion->match = prefix_matched_suggestion
? Suggestion::PREFIX_MATCH
@@ -2063,7 +2079,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
suggestion->label = credit_card->NetworkOrBankNameAndLastFourDigits();
#else
suggestion->label = credit_card->ObfuscatedLastFourDigits();
- // Ad the card number with expiry information in the additional
+ // Add the card number with expiry information in the additional
// label portion so that we an show it when two-line display is
// enabled.
suggestion->additional_label =
@@ -2177,7 +2193,7 @@ void PersonalDataManager::DedupeProfiles(
const std::unique_ptr<AutofillProfile>& b) {
if (a->IsVerified() != b->IsVerified())
return !a->IsVerified();
- return a->CompareFrecency(b.get(), comparison_time);
+ return a->HasGreaterFrecencyThan(b.get(), comparison_time);
});
AutofillProfileComparator comparator(app_locale_);
@@ -2321,9 +2337,6 @@ void PersonalDataManager::ConvertWalletAddressesAndUpdateWalletCards() {
UpdateCardsBillingAddressReference(guids_merge_map);
// Force a reload of the profiles and cards.
- // TODO(crbug.com/915229): Remove once the investigation is over.
- if (has_converted_addresses)
- DLOG(WARNING) << this << " conversion of addresses done";
}
}
@@ -2334,11 +2347,6 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
// If the full Sync feature isn't enabled, then do NOT convert any Wallet
// addresses to local ones.
if (!IsSyncFeatureEnabled()) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this
- << " not converting as sync feature is not enabled, probably "
- "due to sync_service_ being "
- << sync_service_;
return false;
}
@@ -2352,12 +2360,9 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
if (!wallet_address->has_converted()) {
// Try to merge the server address into a similar local profile, or create
// a new local profile if no similar profile is found.
- // TODO(crbug.com/864519): Use GetAccountInfoForPaymentsServer instead of
- // going to IdentityManager directly. This will be necessary to properly
- // support Wallet addresses with Butter.
std::string address_guid = MergeServerAddressesIntoProfiles(
*wallet_address, local_profiles, app_locale_,
- identity_manager_->GetPrimaryAccountInfo().email);
+ GetAccountInfoForPaymentsServer().email);
// Update the map to transfer the billing address relationship from the
// server address to the converted/merged local profile.
@@ -2365,8 +2370,6 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
// Update the wallet addresses metadata to record the conversion.
wallet_address->set_has_converted(true);
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " converting address " << *wallet_address;
database_helper_->GetServerDatabase()->UpdateServerAddressMetadata(
*wallet_address);
@@ -2541,6 +2544,9 @@ bool PersonalDataManager::DeleteDisusedAddresses() {
}
void PersonalDataManager::ApplyAddressFixesAndCleanups() {
+ // Validate profiles once per major.
+ UpdateClientValidityStates(GetProfiles());
+
// One-time fix, otherwise NOP.
RemoveOrphanAutofillTableRows();
@@ -2579,7 +2585,6 @@ void PersonalDataManager::ResetProfileValidity() {
}
void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
- // Add the new profile to the web database.
if (profile.IsEmpty(app_locale_)) {
NotifyPersonalDataChanged();
return;
@@ -2591,26 +2596,30 @@ void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
NotifyPersonalDataChanged();
return;
}
- database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
}
- ongoing_profile_changes_[profile.guid()].push(
+ ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::ADD, profile));
+ UpdateClientValidityStates(profile);
}
-void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile) {
- if (!ProfileChangesAreOnGoing(profile.guid())) {
+void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile,
+ bool enforced) {
+ // if the update is enforced, don't check if a similar profile already exists
+ // or not. Otherwise, check if updating the profile makes sense.
+ if (!enforced && !ProfileChangesAreOnGoing(profile.guid())) {
const auto* existing_profile = GetProfileByGUID(profile.guid());
bool profile_exists = (existing_profile != nullptr);
- if (profile_exists && !existing_profile->EqualsForUpdatePurposes(profile)) {
- database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
- } else {
+ if (!profile_exists || existing_profile->EqualsForUpdatePurposes(profile)) {
NotifyPersonalDataChanged();
return;
}
}
- ongoing_profile_changes_[profile.guid()].push(
+ ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::UPDATE, profile));
+ if (enforced)
+ ongoing_profile_changes_[profile.guid()].back().set_enforce_update();
+ UpdateClientValidityStates(profile);
}
void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
@@ -2619,11 +2628,12 @@ void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
NotifyPersonalDataChanged();
return;
}
-
- if (!ProfileChangesAreOnGoing(guid))
+ AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, guid);
+ if (!ProfileChangesAreOnGoing(guid)) {
database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
- ongoing_profile_changes_[guid].push(
- AutofillProfileDeepChange(AutofillProfileChange::REMOVE, guid));
+ change.set_is_ongoing_on_background();
+ }
+ ongoing_profile_changes_[guid].push_back(std::move(change));
}
void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
@@ -2631,10 +2641,13 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
const auto& change = ongoing_profile_changes_[guid].front();
+ if (change.is_ongoing_on_background())
+ return;
+
const auto& change_type = change.type();
const auto* existing_profile = GetProfileByGUID(guid);
const bool profile_exists = (existing_profile != nullptr);
- const auto& profile = ongoing_profile_changes_[guid].front().profile();
+ const auto& profile = *(ongoing_profile_changes_[guid].front().profile());
DCHECK(guid == profile.guid());
@@ -2644,23 +2657,30 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
}
database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
+ change.set_is_ongoing_on_background();
return;
}
+ if (!change.has_validation_effort_made())
+ return;
+
if (change_type == AutofillProfileChange::ADD) {
if (profile_exists || FindByContents(web_profiles_, profile)) {
OnProfileChangeDone(guid);
return;
}
database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
+ change.set_is_ongoing_on_background();
return;
}
- if (!profile_exists || existing_profile->EqualsForUpdatePurposes(profile)) {
+ if (profile_exists && (change.enforce_update() ||
+ !existing_profile->EqualsForUpdatePurposes(profile))) {
+ database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
+ change.set_is_ongoing_on_background();
+ } else {
OnProfileChangeDone(guid);
- return;
}
- database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
}
bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
@@ -2670,7 +2690,7 @@ bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
}
bool PersonalDataManager::ProfileChangesAreOnGoing() {
- for (auto task : ongoing_profile_changes_) {
+ for (const auto& task : ongoing_profile_changes_) {
if (ProfileChangesAreOnGoing(task.first)) {
return true;
}
@@ -2679,7 +2699,7 @@ bool PersonalDataManager::ProfileChangesAreOnGoing() {
}
void PersonalDataManager::OnProfileChangeDone(const std::string& guid) {
- ongoing_profile_changes_[guid].pop();
+ ongoing_profile_changes_[guid].pop_front();
if (!ProfileChangesAreOnGoing()) {
Refresh();
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.h b/chromium/components/autofill/core/browser/personal_data_manager.h
index 754305dd365..df97465f599 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/personal_data_manager.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PERSONAL_DATA_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PERSONAL_DATA_MANAGER_H_
+#include <deque>
#include <list>
#include <memory>
#include <set>
@@ -36,9 +37,9 @@
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_member.h"
#include "components/signin/core/browser/account_info.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/sync/driver/sync_service_observer.h"
#include "components/webdata/common/web_data_service_consumer.h"
+#include "services/identity/public/cpp/identity_manager.h"
class Browser;
class PrefService;
@@ -56,10 +57,6 @@ void SetProfiles(int, std::vector<autofill::AutofillProfile>*);
void SetCreditCards(int, std::vector<autofill::CreditCard>*);
} // namespace autofill_helper
-namespace identity {
-class IdentityManager;
-}
-
namespace syncer {
class SyncService;
} // namespace syncer
@@ -74,7 +71,7 @@ class PersonalDataManager : public KeyedService,
public AutofillWebDataServiceObserverOnUISequence,
public history::HistoryServiceObserver,
public syncer::SyncServiceObserver,
- public GaiaCookieManagerService::Observer,
+ public identity::IdentityManager::Observer,
public AccountInfoGetter {
public:
explicit PersonalDataManager(const std::string& app_locale);
@@ -95,7 +92,6 @@ class PersonalDataManager : public KeyedService,
identity::IdentityManager* identity_manager,
AutofillProfileValidator* client_profile_validator,
history::HistoryService* history_service,
- GaiaCookieManagerService* cookie_manager_service,
bool is_off_the_record);
// KeyedService:
@@ -123,14 +119,14 @@ class PersonalDataManager : public KeyedService,
void OnSyncShutdown(syncer::SyncService* sync) override;
// AccountInfoGetter:
- AccountInfo GetAccountInfoForPaymentsServer() const override;
+ CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
bool IsSyncFeatureEnabled() const override;
- // GaiaCookieManagerService::Observer:
- void OnGaiaCookieDeletedByUserAction() override;
+ // identity::IdentityManager::Observer:
+ void OnAccountsCookieDeletedByUserAction() override;
// Returns the current sync status.
- AutofillSyncSigninState GetSyncSigninState() const;
+ virtual AutofillSyncSigninState GetSyncSigninState() const;
// Adds a listener to be notified of PersonalDataManager events.
virtual void AddObserver(PersonalDataManagerObserver* observer);
@@ -167,8 +163,7 @@ class PersonalDataManager : public KeyedService,
virtual void RemoveByGUID(const std::string& guid);
// Returns the profile with the specified |guid|, or nullptr if there is no
- // profile with the specified |guid|. Both web and auxiliary profiles may
- // be returned.
+ // profile with the specified |guid|.
virtual AutofillProfile* GetProfileByGUID(const std::string& guid);
// Returns the profile with the specified |guid| from the given |profiles|, or
@@ -255,11 +250,16 @@ class PersonalDataManager : public KeyedService,
void UpdateProfilesServerValidityMapsIfNeeded(
const std::vector<AutofillProfile*>& profiles);
- // Updates the validity states of |profiles| according to client side
- // validation API: |client_profile_validator_|.
+ // Requests an update for the validity states of the |profiles| according to
+ // client side validation API: |client_profile_validator_|.
void UpdateClientValidityStates(
const std::vector<AutofillProfile*>& profiles);
+ // Requests an update for the validity states of the |profile| according to
+ // the client side validation API: |client_profile_validator_|. Returns true
+ // if the validation was requested.
+ bool UpdateClientValidityStates(const AutofillProfile& profile);
+
// Returns the profiles to suggest to the user, ordered by frecency.
std::vector<AutofillProfile*> GetProfilesToSuggest() const;
@@ -269,15 +269,16 @@ class PersonalDataManager : public KeyedService,
const AutofillType& type,
std::vector<AutofillProfile*>* profiles);
- // Loads profiles that can suggest data for |type|. |field_contents| is the
- // part the user has already typed. |field_is_autofilled| is true if the field
- // has already been autofilled. |other_field_types| represents the rest of
- // form.
+ // Returns Suggestions corresponding to the focused field's |type| and
+ // |field_contents|, i.e. what the user has typed. |field_is_autofilled| is
+ // true if the field has already been autofilled, and |field_types| stores the
+ // types of all the form's input fields, including the field with which the
+ // user is interacting.
std::vector<Suggestion> GetProfileSuggestions(
const AutofillType& type,
const base::string16& field_contents,
bool field_is_autofilled,
- const std::vector<ServerFieldType>& other_field_types);
+ const std::vector<ServerFieldType>& field_types);
// Tries to delete disused addresses once per major version if the
// feature is enabled.
@@ -385,8 +386,10 @@ class PersonalDataManager : public KeyedService,
// Records the sync transport consent if the user is in sync transport mode.
virtual void OnUserAcceptedUpstreamOffer();
- // Triggered when a profile is added/updated/removed on db.
- void OnAutofillProfileChanged(const AutofillProfileDeepChange& change);
+ void set_client_profile_validator_for_test(
+ AutofillProfileValidator* validator) {
+ client_profile_validator_ = validator;
+ }
protected:
// Only PersonalDataManagerFactory and certain tests can create instances of
@@ -396,8 +399,6 @@ class PersonalDataManager : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
AddCreditCard_CrazyCharacters);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, AddCreditCard_Invalid);
- FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, FirstMiddleLast);
- FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillIsEnabledAtStartup);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DedupeProfiles_ProfilesToDelete);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
@@ -442,8 +443,6 @@ class PersonalDataManager : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DoNotConvertWalletAddressesInEphemeralStorage);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
- DeleteDisusedCreditCards_OncePerVersion);
- FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DeleteDisusedCreditCards_DoNothingWhenDisabled);
FRIEND_TEST_ALL_PREFIXES(
PersonalDataManagerTest,
@@ -467,9 +466,10 @@ class PersonalDataManager : public KeyedService,
ClearCreditCardNonSettingsOrigins);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
MoveJapanCityToStreetAddress);
- FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, RequestProfileValidity);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnServer);
+ RequestProfileServerValidity);
+ FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
+ GetProfileSuggestions_Validity);
friend class autofill::AutofillInteractiveTest;
friend class autofill::PersonalDataManagerFactory;
@@ -477,6 +477,8 @@ class PersonalDataManager : public KeyedService,
friend class FormDataImporterTest;
friend class PersonalDataManagerTest;
friend class PersonalDataManagerTestBase;
+ friend class PersonalDataManagerHelper;
+ friend class PersonalDataManagerMockTest;
friend class SaveImportedProfileTest;
friend class ProfileSyncServiceAutofillTest;
friend class ::RemoveAutofillTester;
@@ -561,7 +563,8 @@ class PersonalDataManager : public KeyedService,
// https://crbug.com/871301
void MoveJapanCityToStreetAddress();
- // Called when the |profile| is validated by the AutofillProfileValidator.
+ // Called when the |profile| is validated by the AutofillProfileValidator,
+ // updates the profiles on the |ongoing_profile_changes_| and the DB.
virtual void OnValidated(const AutofillProfile* profile);
// Get the profiles fields validity map by |guid|.
@@ -578,15 +581,11 @@ class PersonalDataManager : public KeyedService,
std::vector<std::unique_ptr<AutofillProfile>> web_profiles_;
// Profiles read from the user's account stored on the server.
- mutable std::vector<std::unique_ptr<AutofillProfile>> server_profiles_;
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles_;
// Stores the PaymentsCustomerData obtained from the database.
std::unique_ptr<PaymentsCustomerData> payments_customer_data_;
- // Storage for web profiles. Contents are weak references. Lifetime managed
- // by |web_profiles_|.
- mutable std::vector<AutofillProfile*> profiles_;
-
// Cached versions of the local and server credit cards.
std::vector<std::unique_ptr<CreditCard>> local_credit_cards_;
std::vector<std::unique_ptr<CreditCard>> server_credit_cards_;
@@ -722,11 +721,16 @@ class PersonalDataManager : public KeyedService,
// Resets |synced_profile_validity_|.
void ResetProfileValidity();
- // Add/Update/Remove profiles on DB.
+ // Add/Update/Remove |profile| on DB.
void AddProfileToDB(const AutofillProfile& profile);
- void UpdateProfileInDB(const AutofillProfile& profile);
+ // |enforced| is true when the update should happen regardless of an equal
+ // profile. (equal in the sense of AutofillProfile::EqualForUpdate)
+ void UpdateProfileInDB(const AutofillProfile& profile, bool enforced = false);
void RemoveProfileFromDB(const std::string& guid);
+ // Triggered when a profile is added/updated/removed on db.
+ void OnAutofillProfileChanged(const AutofillProfileDeepChange& change);
+
// Look at the next profile change for profile with guid = |guid|, and handle
// it.
void HandleNextProfileChange(const std::string& guid);
@@ -754,21 +758,16 @@ class PersonalDataManager : public KeyedService,
// remove itself from the history service's observer list on shutdown.
history::HistoryService* history_service_ = nullptr;
- // The GaiaCookieManagerService to be observed by the personal data manager.
- // Must outlive this instance. This unowned pointer is retained so the PDM can
- // remove itself from the cookie manager service's observer list on shutdown.
- GaiaCookieManagerService* cookie_manager_service_ = nullptr;
-
// Pref registrar for managing the change observers.
PrefChangeRegistrar pref_registrar_;
// Profiles validity read from the prefs. They are kept updated by
// observing changes in pref_services. We need to set the
- // |profile_validities_need_update| whenever this is changed.
+ // |profile_validities_need_update_| whenever this is changed.
std::unique_ptr<UserProfileValidityMap> synced_profile_validity_;
// A timely ordered list of on going changes for each profile.
- std::unordered_map<std::string, std::queue<AutofillProfileDeepChange>>
+ std::unordered_map<std::string, std::deque<AutofillProfileDeepChange>>
ongoing_profile_changes_;
// The client side profile validator.
diff --git a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
index f06c16f345b..20fb473789c 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -60,12 +60,16 @@
#include "components/webdata/common/web_database_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_environment.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
+const char kPrimaryAccountEmail[] = "syncuser@example.com";
+const char kSyncTransportAccountEmail[] = "transport@example.com";
+
enum UserMode { USER_MODE_NORMAL, USER_MODE_INCOGNITO };
const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
@@ -132,7 +136,8 @@ void ExpectSameElements(const std::vector<T*>& expectations,
class PersonalDataManagerTestBase {
protected:
- PersonalDataManagerTestBase() {
+ PersonalDataManagerTestBase()
+ : identity_test_env_(&test_url_loader_factory_) {
// Enable account storage by default, some tests will override this to be
// false.
scoped_features_.InitWithFeatures(
@@ -176,13 +181,6 @@ class PersonalDataManagerTestBase {
account_database_service_->Init();
test::DisableSystemServices(prefs_.get());
- ResetPersonalDataManager(USER_MODE_NORMAL);
-
- // Reset the deduping and profile validation prefs to their default value.
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionDeduped, 0);
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionValidated, CHROME_VERSION_MAJOR);
}
void TearDownTest() {
@@ -193,11 +191,11 @@ class PersonalDataManagerTestBase {
}
void ResetPersonalDataManager(UserMode user_mode,
- bool use_sync_transport_mode) {
+ bool use_sync_transport_mode,
+ PersonalDataManager* personal_data) {
bool is_incognito = (user_mode == USER_MODE_INCOGNITO);
- personal_data_.reset(new PersonalDataManagerMock("en"));
- personal_data_->Init(
+ personal_data->Init(
scoped_refptr<AutofillWebDataService>(profile_database_service_),
base::FeatureList::IsEnabled(
features::kAutofillEnableAccountWalletStorage)
@@ -205,44 +203,147 @@ class PersonalDataManagerTestBase {
: nullptr,
prefs_.get(), identity_test_env_.identity_manager(),
TestAutofillProfileValidator::GetInstance(),
- /*history_service=*/nullptr, /*cookie_manager_sevice=*/nullptr,
- is_incognito);
+ /*history_service=*/nullptr, is_incognito);
- personal_data_->AddObserver(&personal_data_observer_);
+ personal_data->AddObserver(&personal_data_observer_);
AccountInfo account_info;
- account_info.email = "sync@account";
+ account_info.email = use_sync_transport_mode ? kSyncTransportAccountEmail
+ : kPrimaryAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(!use_sync_transport_mode);
- personal_data_->OnSyncServiceInitialized(&sync_service_);
- personal_data_->OnStateChanged(&sync_service_);
+ personal_data->OnSyncServiceInitialized(&sync_service_);
+ personal_data->OnStateChanged(&sync_service_);
WaitForOnPersonalDataChangedRepeatedly();
}
- void ResetPersonalDataManager(UserMode user_mode) {
- ResetPersonalDataManager(user_mode, /*use_sync_transport_mode=*/false);
- }
-
- void ResetProfiles() {
- std::vector<AutofillProfile> empty_profiles;
- personal_data_->SetProfiles(&empty_profiles);
- WaitForOnPersonalDataChanged();
- }
-
- bool TurnOnSyncFeature() WARN_UNUSED_RESULT {
+ bool TurnOnSyncFeature(PersonalDataManager* personal_data)
+ WARN_UNUSED_RESULT {
sync_service_.SetIsAuthenticatedAccountPrimary(true);
if (!sync_service_.IsSyncFeatureEnabled())
return false;
- personal_data_->OnStateChanged(&sync_service_);
- return personal_data_->IsSyncFeatureEnabled();
+ personal_data->OnStateChanged(&sync_service_);
+
+ return personal_data->IsSyncFeatureEnabled();
}
void EnableWalletCardImport() {
- identity_test_env_.MakePrimaryAccountAvailable("syncuser@example.com");
+ identity_test_env_.MakePrimaryAccountAvailable(kPrimaryAccountEmail);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableOfferStoreUnmaskedWalletCards);
}
+ void RemoveByGUIDFromPersonalDataManager(const std::string& guid,
+ PersonalDataManager* personal_data) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+
+ personal_data->RemoveByGUID(guid);
+ run_loop.Run();
+ }
+
+ void SetServerCards(std::vector<CreditCard> server_cards) {
+ test::SetServerCreditCards(account_autofill_table_, server_cards);
+ }
+
+ // Verify that the web database has been updated and the notification sent.
+ void WaitOnceForOnPersonalDataChanged() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ run_loop.Run();
+ }
+
+ // Verifies that the web database has been updated and the notification sent.
+ void WaitForOnPersonalDataChanged() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+ run_loop.Run();
+ }
+
+ // Verifies that the web database has been updated and the notification sent.
+ void WaitForOnPersonalDataChangedRepeatedly() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+ run_loop.Run();
+ }
+
+ AccountInfo SetActiveSecondaryAccount() {
+ AccountInfo account_info;
+ account_info.email = kSyncTransportAccountEmail;
+ account_info.account_id = "account_id";
+ sync_service_.SetAuthenticatedAccountInfo(account_info);
+ sync_service_.SetIsAuthenticatedAccountPrimary(false);
+ return account_info;
+ }
+
+ void MoveJapanCityToStreetAddress(PersonalDataManager* personal_data,
+ int move_times) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(move_times);
+ personal_data->MoveJapanCityToStreetAddress();
+ run_loop.Run();
+ }
+
+ // The temporary directory should be deleted at the end to ensure that
+ // files are not used anymore and deletion succeeds.
+ base::ScopedTempDir temp_dir_;
+ base::test::ScopedTaskEnvironment task_environment_{
+ base::test::ScopedTaskEnvironment::MainThreadType::UI};
+ std::unique_ptr<PrefService> prefs_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ identity::IdentityTestEnvironment identity_test_env_;
+ syncer::TestSyncService sync_service_;
+ scoped_refptr<AutofillWebDataService> profile_database_service_;
+ scoped_refptr<AutofillWebDataService> account_database_service_;
+ scoped_refptr<WebDatabaseService> profile_web_database_;
+ scoped_refptr<WebDatabaseService> account_web_database_;
+ AutofillTable* profile_autofill_table_; // weak ref
+ AutofillTable* account_autofill_table_; // weak ref
+ PersonalDataLoadedObserverMock personal_data_observer_;
+ base::test::ScopedFeatureList scoped_features_;
+};
+
+class PersonalDataManagerHelper : public PersonalDataManagerTestBase {
+ protected:
+ virtual ~PersonalDataManagerHelper() {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset();
+ }
+
+ void ResetPersonalDataManager(UserMode user_mode,
+ bool use_account_server_storage = false) {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset(new PersonalDataManager("en"));
+ PersonalDataManagerTestBase::ResetPersonalDataManager(
+ user_mode, use_account_server_storage, personal_data_.get());
+ }
+
+ void ResetProfiles() {
+ std::vector<AutofillProfile> empty_profiles;
+ personal_data_->SetProfiles(&empty_profiles);
+ WaitForOnPersonalDataChanged();
+ }
+
+ bool TurnOnSyncFeature() {
+ return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
+ }
+
void EnableAutofillProfileCleanup() {
personal_data_->is_autofill_profile_cleanup_pending_ = true;
}
@@ -400,14 +501,8 @@ class PersonalDataManagerTestBase {
}
void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
- base::RunLoop run_loop;
- EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
- .WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
- .Times(testing::AnyNumber());
-
- personal_data_->RemoveByGUID(guid);
- run_loop.Run();
+ PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
+ guid, personal_data_.get());
}
void SetServerCards(const std::vector<CreditCard>& server_cards) {
@@ -423,7 +518,8 @@ class PersonalDataManagerTestBase {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
personal_data_->SaveImportedProfile(profile);
run_loop.Run();
@@ -433,91 +529,147 @@ class PersonalDataManagerTestBase {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
run_loop.Run();
}
- // Verifies that the web database has been updated and the notification sent.
- void WaitForOnPersonalDataChanged() {
+ std::unique_ptr<PersonalDataManager> personal_data_;
+};
+
+class PersonalDataManagerTest : public PersonalDataManagerHelper,
+ public testing::Test {
+ protected:
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ }
+ void TearDown() override { TearDownTest(); }
+};
+
+class PersonalDataManagerMockTest : public PersonalDataManagerTestBase,
+ public testing::Test {
+ protected:
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ // Reset the deduping and profile validation prefs to their default value.
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionDeduped, 0);
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionValidated,
+ atoi(version_info::GetVersionNumber().c_str()));
+ personal_data_->is_autofill_profile_cleanup_pending_ = true;
+ }
+
+ void TearDown() override {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset();
+ TearDownTest();
+ }
+
+ void ResetPersonalDataManager(UserMode user_mode) {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset(new PersonalDataManagerMock("en"));
+ PersonalDataManagerTestBase::ResetPersonalDataManager(
+ user_mode, /*use_account_server_storage=*/true, personal_data_.get());
+ }
+
+ bool TurnOnSyncFeature() {
+ return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
+ }
+
+ void StopTheDedupeProcess() {
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionDeduped,
+ atoi(version_info::GetVersionNumber().c_str()));
+ }
+
+ void ResetAutofillLastVersionValidated() {
+ ASSERT_TRUE(personal_data_);
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionValidated, 0);
+ }
+
+ void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
+
+ personal_data_->AddProfile(profile);
+
run_loop.Run();
}
- void WaitOnceForOnPersonalDataChanged() {
+ void UpdateProfileOnPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+
+ personal_data_->UpdateProfile(profile);
+
run_loop.Run();
}
- // Verifies that the web database has been updated and the notification sent.
- void WaitForOnPersonalDataChangedRepeatedly() {
+ void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
+ PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
+ guid, personal_data_.get());
+ }
+
+ void UpdateClientValidityStatesOnPersonalDataManager(
+ const std::vector<AutofillProfile*>& profiles) {
+ int num_updates = 0;
+ if (GetLastVersionValidatedUpdate() < CHROME_VERSION_MAJOR) {
+ num_updates = profiles.size();
+ } else {
+ for (auto* profile : profiles) {
+ if (!profile->is_client_validity_states_updated())
+ num_updates++;
+ }
+ }
+
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(num_updates);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
+ // Validate the profiles through the client validation API.
+ personal_data_->UpdateClientValidityStates(profiles);
run_loop.Run();
}
- void ExpectOnValidated(AutofillProfile* profile) {
- EXPECT_CALL(*personal_data_, OnValidated(profile)).Times(1);
- ON_CALL(*personal_data_, OnValidated(profile))
- .WillByDefault(testing::Invoke(
- personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
- }
-
- void ResetAutofillLastVersionValidated() {
- ASSERT_TRUE(personal_data_);
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionValidated, 0);
- }
-
int GetLastVersionValidatedUpdate() {
return personal_data_->pref_service_->GetInteger(
prefs::kAutofillLastVersionValidated);
}
- AccountInfo SetActiveSecondaryAccount() {
- AccountInfo account_info;
- account_info.email = "signed_in_account@email.com";
- account_info.account_id = "account_id";
- sync_service_.SetAuthenticatedAccountInfo(account_info);
- sync_service_.SetIsAuthenticatedAccountPrimary(false);
- return account_info;
- }
-
- // The temporary directory should be deleted at the end to ensure that
- // files are not used anymore and deletion succeeds.
- base::ScopedTempDir temp_dir_;
- base::test::ScopedTaskEnvironment task_environment_{
- base::test::ScopedTaskEnvironment::MainThreadType::UI};
- std::unique_ptr<PrefService> prefs_;
- identity::IdentityTestEnvironment identity_test_env_;
- syncer::TestSyncService sync_service_;
- scoped_refptr<AutofillWebDataService> profile_database_service_;
- scoped_refptr<AutofillWebDataService> account_database_service_;
- scoped_refptr<WebDatabaseService> profile_web_database_;
- scoped_refptr<WebDatabaseService> account_web_database_;
- AutofillTable* profile_autofill_table_ = nullptr; // weak ref
- AutofillTable* account_autofill_table_ = nullptr; // weak ref
- PersonalDataLoadedObserverMock personal_data_observer_;
std::unique_ptr<PersonalDataManagerMock> personal_data_;
- base::test::ScopedFeatureList scoped_features_;
-};
-
-class PersonalDataManagerTest : public PersonalDataManagerTestBase,
- public testing::Test {
- void SetUp() override { SetUpTest(); }
-
- void TearDown() override { TearDownTest(); }
};
TEST_F(PersonalDataManagerTest, AddProfile) {
@@ -572,6 +724,7 @@ TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
personal_data_->AddProfile(profile);
personal_data_->RemoveByGUID(profile.guid());
+ personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
auto profiles = personal_data_->GetProfiles();
@@ -581,20 +734,54 @@ TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
personal_data_->RemoveByGUID(profile.guid());
personal_data_->RemoveByGUID(profile.guid());
WaitForOnPersonalDataChanged();
+
profiles = personal_data_->GetProfiles();
ASSERT_EQ(0U, profiles.size());
personal_data_->AddProfile(profile);
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
personal_data_->UpdateProfile(profile);
+ WaitForOnPersonalDataChanged();
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+ base::ASCIIToUTF16("new@email.com"));
+
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newer@email.com"));
personal_data_->UpdateProfile(profile);
+ profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newest@email.com"));
+ personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
- base::ASCIIToUTF16("newer@email.com"));
+ base::ASCIIToUTF16("newest@email.com"));
+}
+
+// The changes should happen in the same order as requested. If the later change
+// is validated before an earlier one, still we should process the earlier one
+// first.
+TEST_F(PersonalDataManagerTest, InconsistentValidationSequence) {
+ auto profile = test::GetFullProfile();
+ // Slow validation.
+ personal_data_->set_client_profile_validator_for_test(
+ TestAutofillProfileValidator::GetDelayedInstance());
+ personal_data_->AddProfile(profile);
+
+ // No validator, zero delay for validation.
+ personal_data_->set_client_profile_validator_for_test(nullptr);
+ profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
+ personal_data_->UpdateProfile(profile);
+
+ WaitForOnPersonalDataChanged();
+
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+ base::ASCIIToUTF16("new@email.com"));
+ EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
}
// Test that a new profile has its basic information set.
@@ -1453,7 +1640,6 @@ TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
"Hollywood", "CA", "91601", "US", "12345678910");
EXPECT_FALSE(profile.IsVerified());
- // Add the profile to the database.
AddProfileToPersonalDataManager(profile);
// Make sure everything is set up correctly.
@@ -2104,66 +2290,57 @@ TEST_F(PersonalDataManagerTest,
}
// Tests that suggestions based on invalid data are handled correctly.
-TEST_F(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnClient) {
- // Set up 2 different profiles.
- AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "123 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "9876543210");
- profile1.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
- profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
- AddProfileToPersonalDataManager(profile1);
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
+ // Set up 2 different profiles: one valid and one invalid.
+ AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
+ valid_profile.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(200));
+ valid_profile.set_use_count(1);
+ AddProfileToPersonalDataManager(valid_profile);
- AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "456 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "1234567890");
- AddProfileToPersonalDataManager(profile2);
+ AutofillProfile invalid_profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&invalid_profile, "Marion1", "Mitchell", "Morrison",
+ "invalid email", "Fox",
+ "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+ "Hollywood", "CA", "91601", "US", "Invalid Phone");
+ invalid_profile.set_use_date(AutofillClock::Now());
+ invalid_profile.set_use_count(1000);
+ AddProfileToPersonalDataManager(invalid_profile);
- ResetPersonalDataManager(USER_MODE_NORMAL);
- {
- base::HistogramTester histogram_tester;
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(1U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", false, 1);
- }
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
+ // Invalid based on client, and not invalid by server. Relying on both
+ // validity sources.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(2U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value);
- EXPECT_EQ(base::ASCIIToUTF16("9876543210"), suggestions[1].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", true, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_TRUE(profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
-}
-// Tests that suggestions based on invalid data are handled correctly.
-TEST_F(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnServer) {
- // Set up 2 different profiles.
- AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "123 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "9876543210");
// Set the validity state of ADDRESS_HOME_STATE to INVALID on the prefs.
{
ProfileValidityMap profile_validity_map;
@@ -2171,9 +2348,11 @@ TEST_F(PersonalDataManagerTest,
std::string autofill_profile_validity;
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
- (*profile_validity_map.mutable_field_validity_states())[static_cast<int>(
- ADDRESS_HOME_STATE)] = static_cast<int>(AutofillProfile::INVALID);
- (*user_profile_validity_map.mutable_profile_validity())[profile1.guid()] =
+ (*profile_validity_map
+ .mutable_field_validity_states())[static_cast<int>(EMAIL_ADDRESS)] =
+ static_cast<int>(AutofillProfile::INVALID);
+ (*user_profile_validity_map
+ .mutable_profile_validity())[invalid_profile.guid()] =
profile_validity_map;
ASSERT_TRUE(user_profile_validity_map.SerializeToString(
&autofill_profile_validity));
@@ -2181,44 +2360,98 @@ TEST_F(PersonalDataManagerTest,
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
}
- profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
- AddProfileToPersonalDataManager(profile1);
-
- AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "456 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "NY", "91601", "US", "1234567890");
- AddProfileToPersonalDataManager(profile2);
-
- ResetPersonalDataManager(USER_MODE_NORMAL);
+ // Invalid based on client, and server. Relying on both validity sources.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(ADDRESS_HOME_STATE), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(1U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("NY"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", false, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation,
+ features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
-
+ // Invalid based on client, and server. Relying only on the client source.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(ADDRESS_HOME_STATE), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(2U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("CA"), suggestions[1].value);
- EXPECT_EQ(base::ASCIIToUTF16("NY"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", true, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses,
+ features::kAutofillProfileServerValidation});
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
+ }
+ // Invalid based on client, and server. Relying on server as a validity
+ // source.
+ {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillProfileClientValidation,
+ features::kAutofillSuppressDisusedAddresses});
+ LOG(ERROR) << __FUNCTION__;
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
}
@@ -2995,16 +3228,6 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
base::TimeDelta::FromDays(15));
server_cards.back().SetNetworkForMaskedCard(kVisaCard);
- // This server card is identical to a local card, but has a different
- // card type. Not a dupe and therefore both should appear in the suggestions.
- server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
- test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker", "5100", "12",
- "2999", "1");
- server_cards.back().set_use_count(3);
- server_cards.back().set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- server_cards.back().SetNetworkForMaskedCard(kVisaCard);
-
// This unmasked server card is an exact dupe of a local card. Therefore only
// this card should appear in the suggestions as full server cards have
// precedence over local cards.
@@ -3021,23 +3244,22 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
// Make sure everything is set up correctly.
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
- EXPECT_EQ(6U, personal_data_->GetCreditCards().size());
+ EXPECT_EQ(5U, personal_data_->GetCreditCards().size());
std::vector<Suggestion> suggestions =
personal_data_->GetCreditCardSuggestions(
AutofillType(CREDIT_CARD_NAME_FULL),
/* field_contents= */ base::string16(),
/*include_server_cards=*/true);
- ASSERT_EQ(4U, suggestions.size());
+ ASSERT_EQ(3U, suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
- EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[3].value);
suggestions = personal_data_->GetCreditCardSuggestions(
AutofillType(CREDIT_CARD_NUMBER), /* field_contents= */ base::string16(),
/*include_server_cards=*/true);
- ASSERT_EQ(4U, suggestions.size());
+ ASSERT_EQ(3U, suggestions.size());
EXPECT_EQ(base::UTF8ToUTF16(std::string("Visa ") +
test::ObfuscatedCardDigitsAsUTF8("3456")),
suggestions[0].value);
@@ -3047,9 +3269,6 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
EXPECT_EQ(base::UTF8ToUTF16(std::string("Mastercard ") +
test::ObfuscatedCardDigitsAsUTF8("5100")),
suggestions[2].value);
- EXPECT_EQ(base::UTF8ToUTF16(std::string("Visa ") +
- test::ObfuscatedCardDigitsAsUTF8("5100")),
- suggestions[3].value);
}
// Tests that a full server card can be a dupe of more than one local card.
@@ -3249,40 +3468,39 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_FullServerAndMasked) {
EXPECT_EQ(2U, credit_cards.size());
}
-// Tests that slightly different local, full server, and masked credit cards are
-// not deduped.
+// Tests that different local, masked, and full server credit cards are not
+// deduped.
TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_DifferentCards) {
std::list<CreditCard*> credit_cards;
- CreditCard credit_card2("002149C1-EE28-4213-A3B9-DA243FFF021B",
- test::kEmptyOrigin);
- credit_card2.set_use_count(1);
- credit_card2.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(1));
- test::SetCreditCardInfo(&credit_card2, "Homer Simpson",
+ CreditCard local_card("002149C1-EE28-4213-A3B9-DA243FFF021B",
+ test::kEmptyOrigin);
+ local_card.set_use_count(1);
+ local_card.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
+ test::SetCreditCardInfo(&local_card, "Homer Simpson",
"5105105105105100" /* Mastercard */, "", "", "");
- credit_cards.push_back(&credit_card2);
+ credit_cards.push_back(&local_card);
- // Create a masked server card that is slightly different of the local card.
- CreditCard credit_card4(CreditCard::MASKED_SERVER_CARD, "b456");
- test::SetCreditCardInfo(&credit_card4, "Homer Simpson", "5100", "12", "2999",
+ // Create a masked server card that is different from the local card.
+ CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "b456");
+ test::SetCreditCardInfo(&masked_card, "Homer Simpson", "0005", "12", "2999",
"1");
- credit_card4.set_use_count(3);
- credit_card4.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- credit_card4.SetNetworkForMaskedCard(kVisaCard);
- credit_cards.push_back(&credit_card4);
+ masked_card.set_use_count(3);
+ masked_card.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(15));
+ // credit_card4.SetNetworkForMaskedCard(kVisaCard);
+ credit_cards.push_back(&masked_card);
// Create a full server card that is slightly different of the two other
// cards.
- CreditCard credit_card5(CreditCard::FULL_SERVER_CARD, "c789");
- test::SetCreditCardInfo(&credit_card5, "Homer Simpson",
+ CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "c789");
+ test::SetCreditCardInfo(&full_server_card, "Homer Simpson",
"378282246310005" /* American Express */, "04",
"2999", "1");
- credit_card5.set_use_count(1);
- credit_card5.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- credit_cards.push_back(&credit_card5);
+ full_server_card.set_use_count(1);
+ full_server_card.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(15));
+ credit_cards.push_back(&full_server_card);
PersonalDataManager::DedupeCreditCardToSuggest(&credit_cards);
EXPECT_EQ(3U, credit_cards.size());
@@ -3535,13 +3753,16 @@ typedef struct {
} SaveImportedProfileTestCase;
class SaveImportedProfileTest
- : public PersonalDataManagerTestBase,
+ : public PersonalDataManagerHelper,
public testing::TestWithParam<SaveImportedProfileTestCase> {
public:
SaveImportedProfileTest() {}
~SaveImportedProfileTest() override {}
- void SetUp() override { SetUpTest(); }
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ }
void TearDown() override { TearDownTest(); }
};
@@ -3605,7 +3826,7 @@ TEST_P(SaveImportedProfileTest, SaveImportedProfile) {
ResetProfiles();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PersonalDataManagerTest,
SaveImportedProfileTest,
testing::Values(
@@ -5207,7 +5428,7 @@ TEST_F(PersonalDataManagerTest,
// Make sure that the added address has the email address of the currently
// signed-in user.
- EXPECT_EQ(base::UTF8ToUTF16("syncuser@example.com"),
+ EXPECT_EQ(base::UTF8ToUTF16(kPrimaryAccountEmail),
profiles[0]->GetRawInfo(EMAIL_ADDRESS));
}
@@ -5344,9 +5565,6 @@ TEST_F(PersonalDataManagerTest,
///////////////////////////////////////////////////////////////////////
personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
- ///////////////////////////////////////////////////////////////////////
- // Validation.
- ///////////////////////////////////////////////////////////////////////
// Since there should be no change in data, OnPersonalDataChanged should not
// have been called.
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
@@ -5418,6 +5636,7 @@ TEST_F(
"2999", "1");
local_card.set_billing_address_id(kServerAddressId);
personal_data_->AddCreditCard(local_card);
+ WaitForOnPersonalDataChanged();
std::vector<CreditCard> server_cards;
server_cards.push_back(
@@ -6213,6 +6432,10 @@ TEST_F(PersonalDataManagerTest, OnSyncServiceInitialized_NotActiveSyncService) {
1);
histogram_tester.ExpectUniqueSample(
"Autofill.ResetFullServerCards.NumberOfCardsReset", 1, 1);
+
+ // Call OnSyncShutdown to ensure removing observer added by
+ // OnSyncServiceInitialized.
+ personal_data_->OnSyncShutdown(&sync_service);
}
#endif // !defined(OS_LINUX) || defined(OS_CHROMEOS)
@@ -6465,6 +6688,9 @@ TEST_F(PersonalDataManagerTest, ClearCreditCardNonSettingsOrigins) {
// Tests that all city fields in a Japan profile are moved to the street address
// field.
TEST_F(PersonalDataManagerTest, MoveJapanCityToStreetAddress) {
+ // Turn on sync feature to avoid calling MoveJapanCityToStreetAddress on
+ // adding the profiles implicitly.
+ ASSERT_TRUE(TurnOnSyncFeature());
// A US profile with both street address and a city.
std::string guid0 = base::GenerateGUID();
{
@@ -6514,14 +6740,12 @@ TEST_F(PersonalDataManagerTest, MoveJapanCityToStreetAddress) {
"JP", "");
AddProfileToPersonalDataManager(profile4);
}
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(5U, profiles.size());
- base::RunLoop run_loop;
- EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
- .WillRepeatedly(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
- .Times(2); // For the Japan profiles where the city is not empty.
- personal_data_->MoveJapanCityToStreetAddress();
- run_loop.Run();
+ MoveJapanCityToStreetAddress(
+ personal_data_.get(),
+ 2); // For the japan profiles where the city is not empty.
{
AutofillProfile* profile0 = personal_data_->GetProfileByGUID(guid0);
@@ -6742,9 +6966,9 @@ TEST_F(PersonalDataManagerTest, UseCorrectStorageForDifferentCards) {
EXPECT_EQ(profile, *profiles[0]);
}
-// Requests profiles fields validities: empty profiles, non-existent profiles,
-// and normal ones.
-TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
+// Requests profiles fields validities according to the server: empty profiles,
+// non-existent profiles, and normal ones.
+TEST_F(PersonalDataManagerTest, RequestProfileServerValidity) {
ResetPersonalDataManager(USER_MODE_NORMAL);
ProfileValidityMap profile_validity_map;
@@ -6767,10 +6991,10 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
std::vector<ServerFieldType> types = {
ADDRESS_HOME_LINE1, ADDRESS_HOME_STATE, ADDRESS_HOME_COUNTRY,
EMAIL_ADDRESS, ADDRESS_HOME_ZIP, NAME_FULL};
- std::vector<AutofillProfile::ValidityState> states = {
- AutofillProfile::UNSUPPORTED, AutofillProfile::EMPTY,
- AutofillProfile::INVALID, AutofillProfile::VALID,
- AutofillProfile::UNVALIDATED, AutofillProfile::INVALID};
+ std::vector<AutofillDataModel::ValidityState> states = {
+ AutofillDataModel::UNSUPPORTED, AutofillDataModel::EMPTY,
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::INVALID};
ASSERT_EQ(types.size(), states.size());
for (unsigned long i = 0; i < types.size(); ++i) {
(*profile_validity_map
@@ -6791,7 +7015,7 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
autofill_profile_validity.clear();
(*profile_validity_map
.mutable_field_validity_states())[static_cast<int>(EMAIL_ADDRESS)] =
- static_cast<int>(AutofillProfile::VALID);
+ static_cast<int>(AutofillDataModel::VALID);
(*user_profile_validity_map.mutable_profile_validity())[guid] =
profile_validity_map;
ASSERT_TRUE(
@@ -6818,130 +7042,54 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
validities =
personal_data_->GetProfileValidityByGUID(guid).field_validity_states();
ASSERT_FALSE(validities.empty());
- EXPECT_EQ(validities.at(EMAIL_ADDRESS), AutofillProfile::VALID);
+ EXPECT_EQ(validities.at(EMAIL_ADDRESS), AutofillDataModel::VALID);
}
// Use the client side validation API to validate three PDM profiles. This one
// doesn't test the upload process or saving to the database.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates) {
- // Create three profiles and add them to personal_data_.
- AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
- valid_profile.set_use_date(AutofillClock::Now());
- valid_profile.set_guid("00000000-0000-0000-0000-000000000001");
- AddProfileToPersonalDataManager(valid_profile);
-
- AutofillProfile profile_invalid_phone_email(
- test::GetFullValidProfileForChina());
- profile_invalid_phone_email.SetRawInfo(
- PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("invalid phone number!"));
- profile_invalid_phone_email.SetRawInfo(EMAIL_ADDRESS,
- base::UTF8ToUTF16("invalid email!"));
- profile_invalid_phone_email.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(10));
- profile_invalid_phone_email.set_guid("00000000-0000-0000-0000-000000000002");
- AddProfileToPersonalDataManager(profile_invalid_phone_email);
-
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates) {
AutofillProfile profile_invalid_province(base::GenerateGUID(),
test::kEmptyOrigin);
test::SetProfileInfo(&profile_invalid_province, "Alice", "", "Munro",
"alice@munro.ca", "Fox", "123 Zoo St", "unit 5",
"Montreal", "CA", "H3C 2A3", "CA", "15142343254");
- profile_invalid_province.set_guid("00000000-0000-0000-0000-000000000003");
- profile_invalid_province.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(100));
AddProfileToPersonalDataManager(profile_invalid_province);
- ASSERT_EQ(3U, personal_data_->GetProfiles().size());
-
- // Validate the profiles through the client validation API.
+ ASSERT_EQ(1U, personal_data_->GetProfiles().size());
auto profiles = personal_data_->GetProfiles();
- for (auto* profile : profiles) {
- ASSERT_FALSE(profile->is_client_validity_states_updated());
- // Expect OnValidated to be called for each profile.
- ExpectOnValidated(profile);
- }
+ profiles[0]->set_is_client_validity_states_updated(false);
- personal_data_->UpdateClientValidityStates(profiles);
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
- ASSERT_EQ(3U, profiles.size());
- // The profiles are ordered according to their guid.
- // valid_profile:
- ASSERT_EQ(valid_profile.guid(), profiles[0]->guid());
EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profiles[0]->GetValidityState(ADDRESS_HOME_STATE,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
+ AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_CITY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profiles[0]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
+ AutofillDataModel::VALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
AutofillProfile::CLIENT));
-
- // profile_invalid_phone_email:
- ASSERT_EQ(profile_invalid_phone_email.guid(), profiles[1]->guid());
- EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profiles[1]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[1]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
-
- ASSERT_EQ(profile_invalid_province.guid(), profiles[2]->guid());
- EXPECT_TRUE(profiles[2]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profiles[2]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[2]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[2]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
}
// Check the validity update status for AutofillProfiles.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_UpdatedFlag) {
// Create two profiles and add them to personal_data_.
AutofillProfile profile1(test::GetFullValidProfileForCanada());
AddProfileToPersonalDataManager(profile1);
@@ -6951,18 +7099,10 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
ASSERT_EQ(2U, personal_data_->GetProfiles().size());
- // Validate the profiles through the client validation API.
+ // The validities were set when the profiles were added.
auto profiles = personal_data_->GetProfiles();
- ASSERT_FALSE(profiles[0]->is_client_validity_states_updated());
- ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
-
- ExpectOnValidated(profiles[0]);
- ExpectOnValidated(profiles[1]);
- personal_data_->UpdateClientValidityStates(profiles);
-
- ASSERT_EQ(2U, profiles.size());
- EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
- EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+ ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
+ ASSERT_TRUE(profiles[1]->is_client_validity_states_updated());
*profiles[1] = *profiles[0];
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
@@ -6972,118 +7112,189 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
- ExpectOnValidated(profiles[1]);
- personal_data_->UpdateClientValidityStates(profiles);
+ profiles[0]->SetRawInfo(NAME_FULL, base::UTF8ToUTF16("Goli Boli"));
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
- ASSERT_TRUE(profiles[1]->is_client_validity_states_updated());
+}
+
+// Check the validity update status for AutofillProfiles.
+TEST_F(PersonalDataManagerMockTest,
+ UpdateClientValidityStates_UpdatedFlag_Merge) {
+ // Set the pref to the current major version.
+ StopTheDedupeProcess();
+
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ AddProfileToPersonalDataManager(profile1);
+
+ AutofillProfile profile2(test::GetFullValidProfileForCanada());
+ profile2.set_guid("00000000-0000-0000-0000-000000002019");
+ profile2.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16(""));
+ AddProfileToPersonalDataManager(profile2);
+
+ // The validities were set when the profiles were added.
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
profiles[1]->MergeDataFrom(*profiles[0], "en");
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
-
- profiles[0]->SetRawInfo(NAME_FULL, base::UTF8ToUTF16("Goli Boli"));
- ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
}
// Check that the validity states are not updated when the validity flags are up
// to date.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_AlreadyUpdated) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_AlreadyUpdated) {
// Create two profiles and add them to personal_data_.
AutofillProfile profile1(test::GetFullValidProfileForCanada());
profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
AddProfileToPersonalDataManager(profile1);
- AutofillProfile profile2(test::GetFullValidProfileForChina());
- profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
- AddProfileToPersonalDataManager(profile2);
-
- EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
-
auto profiles = personal_data_->GetProfiles();
- ASSERT_EQ(2U, profiles.size());
+ ASSERT_EQ(1U, profiles.size());
+ // The validities were updated when the profile was added.
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+
+ // Change the email, the validity update would turn false.
+ profiles[0]->SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("alice@gmail.com"));
+ EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
// Pretend that the validity states are updated.
profiles[0]->set_is_client_validity_states_updated(true);
- profiles[1]->set_is_client_validity_states_updated(true);
// Validating the profiles through the client validation API should not change
// the validity states.
personal_data_->UpdateClientValidityStates(profiles);
+
profiles = personal_data_->GetProfiles();
- ASSERT_EQ(2U, profiles.size());
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
+ ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
+ AutofillDataModel::INVALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
+ // Try with the flag as not updated.
+ profiles[0]->set_is_client_validity_states_updated(false);
+
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
}
// Verify that the fields are validated according to the version.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_Version) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_Version) {
// Create two profiles and add them to personal_data_. Set the guids
// explicitly to preserve the order.
- AutofillProfile profile1(test::GetFullValidProfileForCanada());
- profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
- profile1.set_guid("00000000-0000-0000-0000-000000000001");
- AddProfileToPersonalDataManager(profile1);
-
AutofillProfile profile2(test::GetFullValidProfileForChina());
profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
profile2.set_guid("00000000-0000-0000-0000-000000000002");
+ profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(200));
AddProfileToPersonalDataManager(profile2);
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
+ profile1.set_use_date(AutofillClock::Now());
+ profile1.set_guid("00000000-0000-0000-0000-000000000001");
+ AddProfileToPersonalDataManager(profile1);
+
auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
- // Pretend that the validity states are updated.
- profiles[0]->set_is_client_validity_states_updated(true);
- profiles[1]->set_is_client_validity_states_updated(true);
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
+ EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+ EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
- // Should validate regardless of the validity update flag, because of the
- // major version update.
- ResetAutofillLastVersionValidated();
+ // No validation as both validity update flags are true, and the validation
+ // version is set to this version.
+ base::RunLoop run_loop;
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
+ personal_data_->UpdateClientValidityStates(profiles);
profiles = personal_data_->GetProfiles();
ASSERT_EQ(2U, profiles.size());
+ ResetAutofillLastVersionValidated();
- ExpectOnValidated(profiles[0]);
- ExpectOnValidated(profiles[1]);
+ EXPECT_EQ(0, GetLastVersionValidatedUpdate());
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
+ EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+
+ // Should validate regardless of the validity update flag, because of the
+ // major version update.
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(2);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(personal_data_.get(),
+ &PersonalDataManagerMock::OnValidatedPDM));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(2);
+ // Validate the profiles through the client validation API.
personal_data_->UpdateClientValidityStates(profiles);
+ run_loop.Run();
- EXPECT_EQ(AutofillProfile::VALID,
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
+ ASSERT_EQ(profiles[0]->guid(), profile1.guid());
+
+ // Verify that the version of the last update is set to this version.
+ EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
+
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
AutofillProfile::CLIENT));
+}
- // Verify that the version of the last update is set to this version.
- EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
+// Verifies that the profiles are validated when added, updated.
+TEST_F(PersonalDataManagerMockTest, UpdateProfilesValidityStates_AddUpdate) {
+ // Add
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ AddProfileToPersonalDataManager(profile1);
- // Update should not update any validity state, because both the validity
- // state flag and the version are up to date.
- // A fake change in the validity state of profile[1].
- profiles[1]->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
- EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
- personal_data_->UpdateClientValidityStates(profiles);
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(true, profiles[0]->is_client_validity_states_updated());
+
+ // Update
+ profile1.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("email!"));
+ UpdateProfileOnPersonalDataManager(profile1);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(true, profiles[0]->is_client_validity_states_updated());
+}
+
+// Verify that slow delayed validation will still work.
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_Delayed) {
+ personal_data_->set_client_profile_validator_for_test(
+ TestAutofillProfileValidator::GetDelayedInstance());
+
+ AutofillProfile profile(test::GetFullProfile());
+ AddProfileToPersonalDataManager(profile);
+
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+
+ profiles[0]->set_is_client_validity_states_updated(false);
+
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+ profiles[0] =
+ nullptr; // make sure the async task doesn't depend on the pointer.
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
}
// The validation should not happen when the feature is disabled.
@@ -7101,24 +7312,21 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_Disabled) {
personal_data_->UpdateClientValidityStates(profiles);
EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
}
TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
- const std::string kIdentityManagerAccountEmail = "identity_account@email.com";
- const std::string kSyncServiceAccountEmail = "active_sync_account@email.com";
-
// Make the IdentityManager return a non-empty AccountInfo when
// GetPrimaryAccountInfo() is called.
- identity_test_env_.SetPrimaryAccount(kIdentityManagerAccountEmail);
+ identity_test_env_.SetPrimaryAccount(kPrimaryAccountEmail);
ResetPersonalDataManager(USER_MODE_NORMAL);
// Make the sync service return a non-empty AccountInfo when
// GetAuthenticatedAccountInfo() is called.
AccountInfo active_info;
- active_info.email = kSyncServiceAccountEmail;
+ active_info.email = kSyncTransportAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(active_info);
// The IdentityManager's AccountInfo should be returned by default.
@@ -7129,7 +7337,7 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*disabled_features=*/{features::kAutofillEnableAccountWalletStorage,
features::kAutofillGetPaymentsIdentityFromSync});
- EXPECT_EQ(kIdentityManagerAccountEmail,
+ EXPECT_EQ(kPrimaryAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
@@ -7141,7 +7349,7 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
/*disabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync});
- EXPECT_EQ(kSyncServiceAccountEmail,
+ EXPECT_EQ(kSyncTransportAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
@@ -7153,12 +7361,12 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*enabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync},
/*disabled_features=*/{features::kAutofillEnableAccountWalletStorage});
- EXPECT_EQ(kSyncServiceAccountEmail,
+ EXPECT_EQ(kSyncTransportAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
}
-TEST_F(PersonalDataManagerTest, OnGaiaCookieDeletedByUserAction) {
+TEST_F(PersonalDataManagerTest, OnAccountsCookieDeletedByUserAction) {
// Set up some sync transport opt-ins in the prefs.
::autofill::prefs::SetUserOptedInWalletSyncTransport(prefs_.get(), "account1",
true);
@@ -7166,7 +7374,7 @@ TEST_F(PersonalDataManagerTest, OnGaiaCookieDeletedByUserAction) {
prefs_->GetDictionary(prefs::kAutofillSyncTransportOptIn)->DictEmpty());
// Simulate that the cookies get cleared by the user.
- personal_data_->OnGaiaCookieDeletedByUserAction();
+ personal_data_->OnAccountsCookieDeletedByUserAction();
// Make sure the pref is now empty.
EXPECT_TRUE(
@@ -7186,7 +7394,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
// Set everything up so that the proposition should be shown.
// Set an an active secondary account.
AccountInfo active_info;
- active_info.email = "signed_in_account@email.com";
+ active_info.email = kPrimaryAccountEmail;
active_info.account_id = "account_id";
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
@@ -7258,7 +7466,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
EXPECT_FALSE(personal_data_->ShouldShowCardsFromAccountOption());
// The metric should not be logged if the user had no server cards.
histogram_tester.ExpectTotalCount(kHistogramName, 0);
- };
+ }
// Re-set some server cards. Check that the function now returns true.
SetServerCards(server_cards);
@@ -7311,7 +7519,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
// Set everything up so that the proposition should be shown on Desktop.
// Set an an active secondary account.
AccountInfo active_info;
- active_info.email = "signed_in_account@email.com";
+ active_info.email = kPrimaryAccountEmail;
active_info.account_id = "account_id";
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
@@ -7444,7 +7652,7 @@ TEST_F(PersonalDataManagerTest, GetSyncSigninState) {
// Simulate that the user has enabled the sync feature.
AccountInfo primary_account_info;
- primary_account_info.email = "active_sync_account@email.com";
+ primary_account_info.email = kPrimaryAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(primary_account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(true);
// MakePrimaryAccountAvailable is not supported on CrOS.
@@ -7477,10 +7685,9 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
///////////////////////////////////////////////////////////
// Make a non-primary account available with both a refresh token and cookie
// to be in Sync Transport for Wallet mode.
- AccountInfo active_info;
- active_info.email = "test@gmail.com";
- active_info.account_id = "account_id";
- identity_test_env_.SetPrimaryAccount(active_info.email);
+ CoreAccountInfo active_info =
+ identity_test_env_.MakeAccountAvailable(kSyncTransportAccountEmail);
+ identity_test_env_.SetCookieAccounts({{active_info.email, active_info.gaia}});
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
sync_service_.SetActiveDataTypes(
@@ -7488,13 +7695,10 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
// Make sure there are no opt-ins recorded yet.
ASSERT_FALSE(prefs::IsUserOptedInWalletSyncTransport(prefs_.get(),
active_info.account_id));
-// The kSignedInAndWalletSyncTransportEnabled state is not available on CrOS.
-#if !defined(OS_CHROMEOS)
{
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
- /*disabled_features=*/{});
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillEnableAccountWalletStorage);
EXPECT_EQ(AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled,
personal_data_->GetSyncSigninState());
@@ -7504,7 +7708,6 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
EXPECT_TRUE(prefs::IsUserOptedInWalletSyncTransport(
prefs_.get(), active_info.account_id));
}
-#endif // !defined(OS_CHROMEOS)
// Clear the prefs.
prefs::ClearSyncTransportOptIns(prefs_.get());
@@ -7515,10 +7718,11 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
// kSignedIn
///////////////////////////////////////////////////////////
{
+ // Without AccountWalletStorage, kSignedInAndWalletSyncTransportEnabled
+ // shouldn't be available.
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{},
- /*disabled_features=*/{features::kAutofillEnableAccountWalletStorage});
+ scoped_features.InitAndDisableFeature(
+ features::kAutofillEnableAccountWalletStorage);
EXPECT_EQ(AutofillSyncSigninState::kSignedIn,
personal_data_->GetSyncSigninState());
@@ -7536,11 +7740,11 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
active_info.account_id));
///////////////////////////////////////////////////////////
- // kSignedInAndSyncFeature
+ // kSignedOut
///////////////////////////////////////////////////////////
- sync_service_.SetIsAuthenticatedAccountPrimary(true);
+ identity_test_env_.RemoveRefreshTokenForAccount(active_info.account_id);
{
- EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedOut,
personal_data_->GetSyncSigninState());
// Make sure an opt-in does not get recorded even if the user accepted an
@@ -7550,19 +7754,13 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
prefs_.get(), active_info.account_id));
}
- // Clear the prefs.
- prefs::ClearSyncTransportOptIns(prefs_.get());
- ASSERT_FALSE(prefs::IsUserOptedInWalletSyncTransport(prefs_.get(),
- active_info.account_id));
-
///////////////////////////////////////////////////////////
- // kSignedOut
+ // kSignedInAndSyncFeature
///////////////////////////////////////////////////////////
-// ClearPrimaryAccount is not supported on CrOS.
-#if !defined(OS_CHROMEOS)
+ identity_test_env_.SetPrimaryAccount(active_info.email);
+ sync_service_.SetIsAuthenticatedAccountPrimary(true);
{
- identity_test_env_.ClearPrimaryAccount();
- EXPECT_EQ(AutofillSyncSigninState::kSignedOut,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
personal_data_->GetSyncSigninState());
// Make sure an opt-in does not get recorded even if the user accepted an
@@ -7571,7 +7769,6 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
EXPECT_FALSE(prefs::IsUserOptedInWalletSyncTransport(
prefs_.get(), active_info.account_id));
}
-#endif // !defined(OS_CHROMEOS)
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n.cc b/chromium/components/autofill/core/browser/phone_number_i18n.cc
index f4e7e3ba8fb..956eed000e7 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n.cc
+++ b/chromium/components/autofill/core/browser/phone_number_i18n.cc
@@ -214,7 +214,7 @@ bool ParsePhoneNumber(const base::string16& value,
i18n_number->country_code_source() !=
::i18n::phonenumbers::PhoneNumber::FROM_DEFAULT_COUNTRY) {
*country_code =
- base::UTF8ToUTF16(base::IntToString(i18n_number->country_code()));
+ base::UTF8ToUTF16(base::NumberToString(i18n_number->country_code()));
}
// The region might be different from what we started with.
@@ -329,6 +329,15 @@ base::string16 GetFormattedPhoneNumberForDisplay(const AutofillProfile& profile,
return base::UTF8ToUTF16(phone);
}
+std::string FormatPhoneNationallyForDisplay(const std::string& phone_number,
+ const std::string& country_code) {
+ if (IsValidPhoneNumber(phone_number, country_code)) {
+ return FormatPhoneNumber(phone_number, country_code,
+ PhoneNumberUtil::PhoneNumberFormat::NATIONAL);
+ }
+ return phone_number;
+}
+
std::string FormatPhoneForDisplay(const std::string& phone_number,
const std::string& country_code) {
if (IsValidPhoneNumber(phone_number, country_code)) {
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n.h b/chromium/components/autofill/core/browser/phone_number_i18n.h
index 5f6f7674e2d..8def9448679 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n.h
+++ b/chromium/components/autofill/core/browser/phone_number_i18n.h
@@ -90,12 +90,18 @@ bool PhoneNumbersMatch(const base::string16& number_a,
const std::string& app_locale);
// Returns the phone number from the given |profile| formatted for display.
-// If it's valid number for the country of profile, or for the |locale| given
-// as a fall back, return the number in internaional format; otherwise return
+// If it's a valid number for the profile's country or for the |locale| given
+// as a fallback, returns the number in international format; otherwise returns
// the raw number string from profile.
base::string16 GetFormattedPhoneNumberForDisplay(const AutofillProfile& profile,
const std::string& locale);
+// Returns |phone_number| in i18n::phonenumbers::PhoneNumberUtil::
+// PhoneNumberFormat::NATIONAL format if the number is valid for
+// |country_code|. Otherwise, returns the given |phone_number|.
+std::string FormatPhoneNationallyForDisplay(const std::string& phone_number,
+ const std::string& country_code);
+
// Formats the given number |phone_number| to
// i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL format
// by using i18n::phonenumbers::PhoneNumberUtil::Format.
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc b/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
index 54103973681..a65481ec311 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
+++ b/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
@@ -90,7 +90,7 @@ TEST_P(ParseNumberTest, ParsePhoneNumber) {
EXPECT_EQ(test_case.deduced_region, deduced_region);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PhoneNumberI18NTest,
ParseNumberTest,
testing::Values(
@@ -272,6 +272,37 @@ TEST(PhoneNumberUtilTest, FormatPhoneForResponse) {
i18n::FormatPhoneForResponse("(1) 515-123-1234", "US"));
}
+// Tests that phone numbers are correctly formatted in a national format.
+TEST(PhoneNumberUtilTest, FormatPhoneNationallyForDisplay) {
+ // Invalid US and Brazilian numbers are not formatted.
+ EXPECT_EQ("1234567890",
+ i18n::FormatPhoneNationallyForDisplay("1234567890", "US"));
+ EXPECT_EQ("(11) 13333-4444",
+ i18n::FormatPhoneNationallyForDisplay("(11) 13333-4444", "BR"));
+ EXPECT_EQ("(11) 13333-4444",
+ i18n::FormatPhoneNationallyForDisplay("(11) 13333-4444", "IN"));
+
+ // Valid US, Canadian, UK, and Brazilian numbers are nationally formatted.
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("2024440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("+1(202)4440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("12024440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("(202)4440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("202-444-0000", "US"));
+ EXPECT_EQ("(819) 555-9999",
+ i18n::FormatPhoneNationallyForDisplay("+1(819)555 9999", "CA"));
+ EXPECT_EQ("(819) 555-9999",
+ i18n::FormatPhoneNationallyForDisplay("18195559999", "CA"));
+ EXPECT_EQ("020 7601 4444",
+ i18n::FormatPhoneNationallyForDisplay("+4402076014444", "UK"));
+ EXPECT_EQ("(21) 3883-5600",
+ i18n::FormatPhoneNationallyForDisplay("2138835600", "BR"));
+}
+
// Tests that the phone numbers are correctly formatted to display to the user.
TEST(PhoneNumberUtilTest, FormatPhoneForDisplay) {
// Invalid number is not formatted.
@@ -314,7 +345,7 @@ TEST_P(GetFormattedPhoneNumberForDisplayTest,
profile, GetParam().locale)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
GetFormattedPhoneNumberForDisplay,
GetFormattedPhoneNumberForDisplayTest,
testing::Values(
@@ -421,7 +452,7 @@ INSTANTIATE_TEST_CASE_P(
// This number is not a valid US number, we won't try to format.
PhoneNumberFormatCase("55 5342 8400", "US", "5553428400")));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
GetFormattedPhoneNumberForDisplay_EdgeCases,
GetFormattedPhoneNumberForDisplayTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/price_field.cc b/chromium/components/autofill/core/browser/price_field.cc
new file mode 100644
index 00000000000..59cbca3b493
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field.cc
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/price_field.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
+
+namespace autofill {
+
+// static
+std::unique_ptr<FormField> PriceField::Parse(AutofillScanner* scanner) {
+ AutofillField* field;
+ if (ParseFieldSpecifics(
+ scanner, base::UTF8ToUTF16(kPriceRe),
+ MATCH_DEFAULT | MATCH_NUMBER | MATCH_SELECT | MATCH_TEXT_AREA,
+ &field)) {
+ return std::make_unique<PriceField>(field);
+ }
+
+ return nullptr;
+}
+
+PriceField::PriceField(const AutofillField* field) : field_(field) {}
+
+void PriceField::AddClassifications(
+ FieldCandidatesMap* field_candidates) const {
+ AddClassification(field_, PRICE, kBasePriceParserScore, field_candidates);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/price_field.h b/chromium/components/autofill/core/browser/price_field.h
new file mode 100644
index 00000000000..65989b8ad10
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
+
+#include <memory>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/autofill/core/browser/form_field.h"
+
+namespace autofill {
+
+class AutofillField;
+class AutofillScanner;
+
+// Price fields are not filled by autofill, but identifying them will help to
+// reduce the number of false positives.
+class PriceField : public FormField {
+ public:
+ static std::unique_ptr<FormField> Parse(AutofillScanner* scanner);
+ PriceField(const AutofillField* field);
+
+ protected:
+ void AddClassifications(FieldCandidatesMap* field_candidates) const override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParsePrice);
+ FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParseNonPrice);
+
+ const AutofillField* field_;
+
+ DISALLOW_COPY_AND_ASSIGN(PriceField);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
diff --git a/chromium/components/autofill/core/browser/price_field_unittest.cc b/chromium/components/autofill/core/browser/price_field_unittest.cc
new file mode 100644
index 00000000000..626cac72591
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/price_field.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/form_field_data.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::ASCIIToUTF16;
+
+namespace autofill {
+
+class PriceFieldTest : public testing::Test {
+ public:
+ PriceFieldTest() {}
+
+ protected:
+ std::vector<std::unique_ptr<AutofillField>> list_;
+ std::unique_ptr<PriceField> field_;
+ FieldCandidatesMap field_candidates_map_;
+
+ // Downcast for tests.
+ static std::unique_ptr<PriceField> Parse(AutofillScanner* scanner) {
+ std::unique_ptr<FormField> field = PriceField::Parse(scanner);
+ return std::unique_ptr<PriceField>(
+ static_cast<PriceField*>(field.release()));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PriceFieldTest);
+};
+
+TEST_F(PriceFieldTest, ParsePrice) {
+ FormFieldData price_field;
+ price_field.form_control_type = "text";
+
+ price_field.label = ASCIIToUTF16("name your price");
+ price_field.name = ASCIIToUTF16("userPrice");
+
+ list_.push_back(
+ std::make_unique<AutofillField>(price_field, ASCIIToUTF16("price1")));
+
+ AutofillScanner scanner(list_);
+ field_ = Parse(&scanner);
+ ASSERT_NE(nullptr, field_.get());
+ field_->AddClassifications(&field_candidates_map_);
+ ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("price1")) !=
+ field_candidates_map_.end());
+ EXPECT_EQ(PRICE,
+ field_candidates_map_[ASCIIToUTF16("price1")].BestHeuristicType());
+}
+
+TEST_F(PriceFieldTest, ParseNonPrice) {
+ FormFieldData address_field;
+ address_field.form_control_type = "text";
+
+ address_field.label = ASCIIToUTF16("Name");
+ address_field.name = ASCIIToUTF16("firstName");
+
+ list_.push_back(
+ std::make_unique<AutofillField>(address_field, ASCIIToUTF16("name1")));
+
+ AutofillScanner scanner(list_);
+ field_ = Parse(&scanner);
+ ASSERT_EQ(nullptr, field_.get());
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/proto/server.proto b/chromium/components/autofill/core/browser/proto/server.proto
index 079c9449ffc..86bc91e222d 100644
--- a/chromium/components/autofill/core/browser/proto/server.proto
+++ b/chromium/components/autofill/core/browser/proto/server.proto
@@ -14,7 +14,7 @@ import "password_requirements.proto";
// Request to query field suggestions for forms in a page from legacy Autofill
// API.
-// Next available id: 14
+// Next available id: 15
message AutofillQueryContents {
reserved 11; // Reserved for server use.
required string client_version = 1;
@@ -28,6 +28,7 @@ message AutofillQueryContents {
optional AutofillRandomizedFieldMetadata field_metadata = 13;
}
}
+ repeated int64 experiments = 14;
}
// Response from Autofill query on the legacy API that gives field suggestions
@@ -185,7 +186,7 @@ message AutofillRandomizedFieldMetadata {
// This message contains information about the field types in a single form.
// It is sent by the toolbar to contribute to the field type statistics.
-// Next available id: 38
+// Next available id: 39
message AutofillUploadContents {
required string client_version = 1;
required fixed64 form_signature = 2;
@@ -396,6 +397,9 @@ message AutofillUploadContents {
// Whether the fields are enclosed by a <form> tag or are unowned elements.
optional bool has_form_tag = 37;
+
+ // Captures whether or not this upload was a candidate for throttling.
+ optional bool was_throttleable = 38;
}
// This proto contains information about the validity of each field in an
diff --git a/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc b/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
index d034c86cae0..9819106c68c 100644
--- a/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
+++ b/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
@@ -160,9 +160,9 @@ TEST_P(RandomizedEncoderTest, EncodeLarge) {
EXPECT_EQ(expected_result, actual_result);
}
-INSTANTIATE_TEST_CASE_P(All,
- RandomizedEncoderTest,
- ::testing::ValuesIn(kEncodeParams));
+INSTANTIATE_TEST_SUITE_P(All,
+ RandomizedEncoderTest,
+ ::testing::ValuesIn(kEncodeParams));
namespace {
@@ -321,6 +321,6 @@ TEST_P(RandomizedDecoderTest, Decode) {
}
}
-INSTANTIATE_TEST_CASE_P(All,
- RandomizedDecoderTest,
- ::testing::ValuesIn(kDecodeParams));
+INSTANTIATE_TEST_SUITE_P(All,
+ RandomizedDecoderTest,
+ ::testing::ValuesIn(kDecodeParams));
diff --git a/chromium/components/autofill/core/browser/region_data_loader_impl.cc b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
index 698c425dda9..c54700b584f 100644
--- a/chromium/components/autofill/core/browser/region_data_loader_impl.cc
+++ b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/region_data_loader_impl.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h"
diff --git a/chromium/components/autofill/core/browser/search_field.cc b/chromium/components/autofill/core/browser/search_field.cc
index f2b19b9461d..f684baea1f1 100644
--- a/chromium/components/autofill/core/browser/search_field.cc
+++ b/chromium/components/autofill/core/browser/search_field.cc
@@ -5,6 +5,7 @@
#include "components/autofill/core/browser/search_field.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
@@ -14,7 +15,8 @@ namespace autofill {
std::unique_ptr<FormField> SearchField::Parse(AutofillScanner* scanner) {
AutofillField* field;
if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kSearchTermRe),
- MATCH_DEFAULT | MATCH_SEARCH, &field)) {
+ MATCH_DEFAULT | MATCH_SEARCH | MATCH_TEXT_AREA,
+ &field)) {
return std::make_unique<SearchField>(field);
}
diff --git a/chromium/components/autofill/core/browser/search_field.h b/chromium/components/autofill/core/browser/search_field.h
index 41d0c396d1d..bfbf77f71c3 100644
--- a/chromium/components/autofill/core/browser/search_field.h
+++ b/chromium/components/autofill/core/browser/search_field.h
@@ -13,6 +13,9 @@
namespace autofill {
+class AutofillField;
+class AutofillScanner;
+
// Search fields are not filled by autofill, but identifying them will help
// to reduce the number of false positives.
class SearchField : public FormField {
diff --git a/chromium/components/autofill/core/browser/strike_database.cc b/chromium/components/autofill/core/browser/strike_database.cc
index 0e247e7d2e3..41002501b2b 100644
--- a/chromium/components/autofill/core/browser/strike_database.cc
+++ b/chromium/components/autofill/core/browser/strike_database.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/strike_database.h"
+#include <algorithm>
#include <string>
#include <utility>
#include <vector>
@@ -39,7 +40,7 @@ StrikeDatabase::StrikeDatabase(const base::FilePath& database_dir)
StrikeDatabase::~StrikeDatabase() {}
-int StrikeDatabase::AddStrikes(int strikes_increase, const std::string key) {
+int StrikeDatabase::AddStrikes(int strikes_increase, const std::string& key) {
DCHECK(strikes_increase > 0);
int num_strikes =
strike_map_cache_.count(key) // Cache has entry for |key|.
@@ -49,29 +50,41 @@ int StrikeDatabase::AddStrikes(int strikes_increase, const std::string key) {
return num_strikes;
}
-int StrikeDatabase::RemoveStrikes(int strikes_decrease, const std::string key) {
- DCHECK(strikes_decrease > 0);
- DCHECK(strike_map_cache_.count(key));
- int num_strikes = strike_map_cache_[key].num_strikes() - strikes_decrease;
- if (num_strikes < 1) {
- ClearStrikes(key);
- return 0;
- }
+int StrikeDatabase::RemoveStrikes(int strikes_decrease,
+ const std::string& key) {
+ int num_strikes = GetStrikes(key);
+ num_strikes = std::max(0, num_strikes - strikes_decrease);
SetStrikeData(key, num_strikes);
return num_strikes;
}
-int StrikeDatabase::GetStrikes(const std::string key) {
- return strike_map_cache_.count(key) // Cache contains entry for |key|.
- ? strike_map_cache_[key].num_strikes()
- : 0;
+int StrikeDatabase::GetStrikes(const std::string& key) {
+ auto iter = strike_map_cache_.find(key);
+ return (iter != strike_map_cache_.end()) ? iter->second.num_strikes() : 0;
}
-void StrikeDatabase::ClearStrikes(const std::string key) {
+void StrikeDatabase::ClearStrikes(const std::string& key) {
strike_map_cache_.erase(key);
ClearAllProtoStrikesForKey(key, base::DoNothing());
}
+void StrikeDatabase::ClearAllStrikesForProject(
+ const std::string& project_prefix) {
+ std::vector<std::string> keys_to_delete;
+ for (std::pair<std::string, StrikeData> entry : strike_map_cache_) {
+ if (entry.first.find(project_prefix) == 0) {
+ keys_to_delete.push_back(entry.first);
+ }
+ }
+ for (std::string key : keys_to_delete)
+ ClearStrikes(key);
+}
+
+void StrikeDatabase::ClearAllStrikes() {
+ strike_map_cache_.clear();
+ ClearAllProtoStrikes(base::DoNothing());
+}
+
StrikeDatabase::StrikeDatabase()
: db_(nullptr),
database_dir_(base::FilePath(nullptr)),
@@ -106,7 +119,11 @@ void StrikeDatabase::OnDatabaseLoadKeysAndEntries(
strike_map_cache_.insert(entries->begin(), entries->end());
}
-void StrikeDatabase::SetStrikeData(const std::string key, int num_strikes) {
+void StrikeDatabase::SetStrikeData(const std::string& key, int num_strikes) {
+ if (num_strikes == 0) {
+ ClearStrikes(key);
+ return;
+ }
StrikeData data;
data.set_num_strikes(num_strikes);
data.set_last_update_timestamp(
@@ -115,7 +132,7 @@ void StrikeDatabase::SetStrikeData(const std::string key, int num_strikes) {
SetProtoStrikeData(key, data, base::DoNothing());
}
-void StrikeDatabase::GetProtoStrikes(const std::string key,
+void StrikeDatabase::GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback) {
if (!database_initialized_) {
outer_callback.Run(false);
@@ -156,7 +173,7 @@ void StrikeDatabase::ClearAllProtoStrikesForKey(
/*keys_to_remove=*/std::move(keys_to_remove), outer_callback);
}
-void StrikeDatabase::GetProtoStrikeData(const std::string key,
+void StrikeDatabase::GetProtoStrikeData(const std::string& key,
const GetValueCallback& callback) {
if (!database_initialized_) {
callback.Run(false, nullptr);
@@ -200,4 +217,8 @@ void StrikeDatabase::UpdateCache(const std::string& key,
strike_map_cache_[key] = data;
}
+std::string StrikeDatabase::GetPrefixFromKey(const std::string& key) {
+ return key.substr(0, key.find(kKeyDeliminator));
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database.h b/chromium/components/autofill/core/browser/strike_database.h
index bea6da0aa80..8b8915df770 100644
--- a/chromium/components/autofill/core/browser/strike_database.h
+++ b/chromium/components/autofill/core/browser/strike_database.h
@@ -16,6 +16,11 @@
#include "components/leveldb_proto/public/proto_database.h"
namespace autofill {
+
+namespace {
+const char kKeyDeliminator[] = "__";
+} // namespace
+
class StrikeData;
// Manages data on whether different Autofill opportunities should be offered to
@@ -49,18 +54,26 @@ class StrikeDatabase : public KeyedService {
// Increases in-memory cache by |strikes_increase| and updates underlying
// ProtoDatabase.
- int AddStrikes(int strikes_increase, const std::string key);
+ int AddStrikes(int strikes_increase, const std::string& key);
// Removes |strikes_decrease| in-memory cache strikes, updates
// last_update_timestamp, and updates underlying ProtoDatabase.
- int RemoveStrikes(int strikes_decrease, const std::string key);
+ int RemoveStrikes(int strikes_decrease, const std::string& key);
// Returns strike count from in-memory cache.
- int GetStrikes(const std::string key);
+ int GetStrikes(const std::string& key);
+
+ // Removes database entry for |key| from in-memory cache and underlying
+ // ProtoDatabase.
+ void ClearStrikes(const std::string& key);
+
+ // Removes all database entries from in-memory cache and underlying
+ // ProtoDatabase for the whole project.
+ void ClearAllStrikesForProject(const std::string& project_prefix);
// Removes all database entries from in-memory cache and underlying
// ProtoDatabase.
- void ClearStrikes(const std::string key);
+ void ClearAllStrikes();
protected:
friend class StrikeDatabaseIntegratorBase;
@@ -92,6 +105,7 @@ class StrikeDatabase : public KeyedService {
GetIdForCreditCardSaveTest);
FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
RemoveExpiredStrikesOnLoadTest);
+ friend class SaveCardInfobarEGTestHelper;
friend class StrikeDatabaseTest;
friend class StrikeDatabaseTester;
@@ -102,13 +116,13 @@ class StrikeDatabase : public KeyedService {
std::unique_ptr<std::map<std::string, StrikeData>> entries);
// Updates the StrikeData for |key| in the cache and ProtoDatabase to have
- // |num_stikes|, and the current time as timestamp.
- void SetStrikeData(const std::string key, int num_strikes);
+ // |num_strikes|, and the current time as timestamp.
+ void SetStrikeData(const std::string& key, int num_strikes);
// Passes the number of strikes for |key| to |outer_callback|. In the case
// that the database fails to retrieve the strike update or if no entry is
// found for |key|, 0 is passed.
- virtual void GetProtoStrikes(const std::string key,
+ virtual void GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback);
// Removes all database entries, which ensures there will be no saved strikes
@@ -123,7 +137,7 @@ class StrikeDatabase : public KeyedService {
const ClearStrikesCallback& outer_callback);
// Passes success status and StrikeData entry for |key| to |inner_callback|.
- void GetProtoStrikeData(const std::string key,
+ void GetProtoStrikeData(const std::string& key,
const GetValueCallback& inner_callback);
// Sets the entry for |key| to |strike_data|. Success status is passed to the
@@ -143,6 +157,9 @@ class StrikeDatabase : public KeyedService {
// Sets the entry for |key| in |strike_map_cache_| to |data|.
void UpdateCache(const std::string& key, const StrikeData& data);
+ // Extracts per-project prefix from |key|.
+ std::string GetPrefixFromKey(const std::string& key);
+
base::WeakPtrFactory<StrikeDatabase> weak_ptr_factory_;
};
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc b/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
index f6438197ffd..5b0426188a7 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/strike_database_integrator_base.h"
+#include <algorithm>
#include <string>
#include <utility>
#include <vector>
@@ -19,10 +20,6 @@
namespace autofill {
-namespace {
-const char kKeyDeliminator[] = "__";
-} // namespace
-
StrikeDatabaseIntegratorBase::StrikeDatabaseIntegratorBase(
StrikeDatabase* strike_database)
: strike_database_(strike_database) {}
@@ -30,18 +27,18 @@ StrikeDatabaseIntegratorBase::StrikeDatabaseIntegratorBase(
StrikeDatabaseIntegratorBase::~StrikeDatabaseIntegratorBase() {}
bool StrikeDatabaseIntegratorBase::IsMaxStrikesLimitReached(
- const std::string id) {
+ const std::string& id) {
CheckIdUniqueness(id);
return GetStrikes(id) >= GetMaxStrikesLimit();
}
-int StrikeDatabaseIntegratorBase::AddStrike(const std::string id) {
+int StrikeDatabaseIntegratorBase::AddStrike(const std::string& id) {
CheckIdUniqueness(id);
return AddStrikes(1, id);
}
int StrikeDatabaseIntegratorBase::AddStrikes(int strikes_increase,
- const std::string id) {
+ const std::string& id) {
CheckIdUniqueness(id);
int num_strikes = strike_database_->AddStrikes(strikes_increase, GetKey(id));
base::UmaHistogramCounts1000(
@@ -50,42 +47,58 @@ int StrikeDatabaseIntegratorBase::AddStrikes(int strikes_increase,
return num_strikes;
}
-int StrikeDatabaseIntegratorBase::RemoveStrike(const std::string id) {
+int StrikeDatabaseIntegratorBase::RemoveStrike(const std::string& id) {
CheckIdUniqueness(id);
return strike_database_->RemoveStrikes(1, GetKey(id));
}
-int StrikeDatabaseIntegratorBase::RemoveStrikes(int strikes_decrease,
- const std::string id) {
+int StrikeDatabaseIntegratorBase::RemoveStrikes(int strike_decrease,
+ const std::string& id) {
CheckIdUniqueness(id);
- return strike_database_->RemoveStrikes(strikes_decrease, GetKey(id));
+ return strike_database_->RemoveStrikes(strike_decrease, GetKey(id));
}
-int StrikeDatabaseIntegratorBase::GetStrikes(const std::string id) {
+int StrikeDatabaseIntegratorBase::GetStrikes(const std::string& id) {
CheckIdUniqueness(id);
return strike_database_->GetStrikes(GetKey(id));
}
-void StrikeDatabaseIntegratorBase::ClearStrikes(const std::string id) {
+void StrikeDatabaseIntegratorBase::ClearStrikes(const std::string& id) {
CheckIdUniqueness(id);
strike_database_->ClearStrikes(GetKey(id));
}
+void StrikeDatabaseIntegratorBase::ClearAllStrikes() {
+ strike_database_->ClearAllStrikesForProject(GetProjectPrefix());
+}
+
void StrikeDatabaseIntegratorBase::RemoveExpiredStrikes() {
std::vector<std::string> expired_keys;
for (auto entry : strike_database_->strike_map_cache_) {
if (AutofillClock::Now().ToDeltaSinceWindowsEpoch().InMicroseconds() -
entry.second.last_update_timestamp() >
GetExpiryTimeMicros()) {
- if (strike_database_->GetStrikes(entry.first) > 0)
+ if (strike_database_->GetStrikes(entry.first) > 0) {
expired_keys.push_back(entry.first);
+ base::UmaHistogramCounts1000(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired." +
+ strike_database_->GetPrefixFromKey(entry.first),
+ strike_database_->GetStrikes(entry.first));
+ }
}
}
- for (std::string key : expired_keys)
- strike_database_->RemoveStrikes(1, key);
+ for (std::string key : expired_keys) {
+ int strikes_to_remove = 1;
+ // If the key is already over the limit, remove additional strikes to
+ // emulate setting it back to the limit. These are done together to avoid
+ // multiple calls to the file system ProtoDatabase.
+ strikes_to_remove +=
+ std::max(0, strike_database_->GetStrikes(key) - GetMaxStrikesLimit());
+ strike_database_->RemoveStrikes(strikes_to_remove, key);
+ }
}
-std::string StrikeDatabaseIntegratorBase::GetKey(const std::string id) {
+std::string StrikeDatabaseIntegratorBase::GetKey(const std::string& id) {
return GetProjectPrefix() + kKeyDeliminator + id;
}
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.h b/chromium/components/autofill/core/browser/strike_database_integrator_base.h
index 9f207da9d94..3e1bf565d8a 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.h
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_base.h
@@ -24,29 +24,33 @@ class StrikeDatabaseIntegratorBase {
// Returns whether or not strike count for |id| has reached the strike limit
// set by GetMaxStrikesLimit().
- bool IsMaxStrikesLimitReached(const std::string id = kSharedId);
+ bool IsMaxStrikesLimitReached(const std::string& id = kSharedId);
// Increments in-memory cache and updates underlying ProtoDatabase.
- int AddStrike(const std::string id = kSharedId);
+ int AddStrike(const std::string& id = kSharedId);
// Increases in-memory cache by |strikes_increase| and updates underlying
// ProtoDatabase.
- int AddStrikes(int strikes_increase, const std::string id = kSharedId);
+ int AddStrikes(int strikes_increase, const std::string& id = kSharedId);
// Removes an in-memory cache strike, updates last_update_timestamp, and
// updates underlying ProtoDatabase.
- int RemoveStrike(const std::string id = kSharedId);
+ int RemoveStrike(const std::string& id = kSharedId);
// Removes |strikes_decrease| in-memory cache strikes, updates
// |last_update_timestamp|, and updates underlying ProtoDatabase.
- int RemoveStrikes(int strikes_decrease, const std::string id = kSharedId);
+ int RemoveStrikes(int strikes_decrease, const std::string& id = kSharedId);
// Returns strike count from in-memory cache.
- int GetStrikes(const std::string id = kSharedId);
+ int GetStrikes(const std::string& id = kSharedId);
// Removes all database entries from in-memory cache and underlying
// ProtoDatabase.
- void ClearStrikes(const std::string id = kSharedId);
+ void ClearStrikes(const std::string& id = kSharedId);
+
+ // Removes all database entries from in-memory cache and underlying
+ // ProtoDatabase for the whole project.
+ void ClearAllStrikes();
protected:
// Removes all strikes in which it has been longer than GetExpiryTimeMicros()
@@ -56,14 +60,15 @@ class StrikeDatabaseIntegratorBase {
private:
FRIEND_TEST_ALL_PREFIXES(ChromeBrowsingDataRemoverDelegateTest,
StrikeDatabaseEmptyOnAutofillRemoveEverything);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- GetKeyForCreditCardSaveTest);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- GetIdForCreditCardSaveTest);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- RemoveExpiredStrikesTest);
- FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationStrikeDatabaseTest,
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
RemoveExpiredStrikesTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ GetKeyForStrikeDatabaseIntegratorUniqueIdTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesUniqueIdTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTestLogsUMA);
+ friend class SaveCardInfobarEGTestHelper;
friend class StrikeDatabaseTest;
friend class StrikeDatabaseTester;
@@ -79,7 +84,7 @@ class StrikeDatabaseIntegratorBase {
}
// Generates key based on project-specific string identifier.
- std::string GetKey(const std::string id);
+ std::string GetKey(const std::string& id);
// Returns a prefix unique to each project, which will be used to create
// database key.
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc
new file mode 100644
index 00000000000..c5be5139c42
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/strike_database_integrator_test_strike_database.h"
+
+#include "components/autofill/core/browser/proto/strike_data.pb.h"
+
+namespace autofill {
+
+const char kProjectPrefix[] = "StrikeDatabaseIntegratorTest";
+const int kMaxStrikesLimit = 6;
+// Expiry time is 1 year.
+const long long kExpiryTimeMicros = (long long)1000000 * 60 * 60 * 24 * 365;
+
+StrikeDatabaseIntegratorTestStrikeDatabase::
+ StrikeDatabaseIntegratorTestStrikeDatabase(StrikeDatabase* strike_database)
+ : StrikeDatabaseIntegratorBase(strike_database) {
+ RemoveExpiredStrikes();
+}
+
+StrikeDatabaseIntegratorTestStrikeDatabase::
+ ~StrikeDatabaseIntegratorTestStrikeDatabase() {}
+
+std::string StrikeDatabaseIntegratorTestStrikeDatabase::GetProjectPrefix() {
+ return kProjectPrefix;
+}
+
+int StrikeDatabaseIntegratorTestStrikeDatabase::GetMaxStrikesLimit() {
+ return kMaxStrikesLimit;
+}
+
+long long StrikeDatabaseIntegratorTestStrikeDatabase::GetExpiryTimeMicros() {
+ return kExpiryTimeMicros;
+}
+
+bool StrikeDatabaseIntegratorTestStrikeDatabase::UniqueIdsRequired() {
+ return unique_ids_required_;
+}
+
+void StrikeDatabaseIntegratorTestStrikeDatabase::SetUniqueIdsRequired(
+ bool unique_ids_required) {
+ unique_ids_required_ = unique_ids_required;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h
new file mode 100644
index 00000000000..3a50f6e75f5
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/strike_database.h"
+#include "components/autofill/core/browser/strike_database_integrator_base.h"
+
+namespace autofill {
+
+// Mock per-project implementation of StrikeDatabase to test the functions in
+// StrikeDatabaseIntegrator.
+class StrikeDatabaseIntegratorTestStrikeDatabase
+ : public StrikeDatabaseIntegratorBase {
+ public:
+ StrikeDatabaseIntegratorTestStrikeDatabase(StrikeDatabase* strike_database);
+ ~StrikeDatabaseIntegratorTestStrikeDatabase() override;
+
+ std::string GetProjectPrefix() override;
+ int GetMaxStrikesLimit() override;
+ long long GetExpiryTimeMicros() override;
+ bool UniqueIdsRequired() override;
+
+ void SetUniqueIdsRequired(bool unique_ids_required);
+
+ private:
+ bool unique_ids_required_ = false;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc
new file mode 100644
index 00000000000..a6e961b7fde
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc
@@ -0,0 +1,289 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/strike_database_integrator_test_strike_database.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/autofill/core/browser/proto/strike_data.pb.h"
+#include "components/autofill/core/browser/test_autofill_clock.h"
+#include "components/autofill/core/common/autofill_clock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+class StrikeDatabaseIntegratorTestStrikeDatabaseTest : public ::testing::Test {
+ public:
+ StrikeDatabaseIntegratorTestStrikeDatabaseTest()
+ : strike_database_(new StrikeDatabase(InitFilePath())) {}
+
+ protected:
+ base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ StrikeDatabaseIntegratorTestStrikeDatabase strike_database_;
+
+ private:
+ static const base::FilePath InitFilePath() {
+ base::ScopedTempDir temp_dir_;
+ EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+ const base::FilePath file_path =
+ temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
+ return file_path;
+ }
+
+ base::HistogramTester histogram_tester_;
+};
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ MaxStrikesLimitReachedTest) {
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
+ // 3 strikes added.
+ strike_database_.AddStrikes(3);
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
+ // 4 strike added, total strike count is 7.
+ strike_database_.AddStrikes(4);
+ EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorTestNthStrikeAddedHistogram) {
+ // 2 strikes logged.
+ strike_database_.AddStrikes(2);
+ strike_database_.RemoveStrikes(2);
+ // 1 strike logged.
+ strike_database_.AddStrike();
+ // 2 strikes logged.
+ strike_database_.AddStrike();
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.NthStrikeAdded.StrikeDatabaseIntegratorTest");
+ // There should be two buckets, for strike counts of 1 and 2.
+ ASSERT_EQ(2U, buckets.size());
+ // Bucket for 1 strike should have count of 1.
+ EXPECT_EQ(1, buckets[0].count);
+ // Bucket for 2 strikes should have count of 2.
+ EXPECT_EQ(2, buckets[1].count);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ AddStrikeForZeroAndNonZeroStrikesTest) {
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+ strike_database_.AddStrike();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(3, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForNonZeroStrikesTest) {
+ strike_database_.AddStrikes(3);
+ EXPECT_EQ(3, strike_database_.GetStrikes());
+ strike_database_.ClearStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForZeroStrikesTest) {
+ strike_database_.ClearStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTest) {
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(2, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // One strike should be removed.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+
+ // Strike count is past the max limit.
+ strike_database_.AddStrikes(10);
+ EXPECT_EQ(11, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // Strike count should be one less than the max limit.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(5, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTestLogsUMA) {
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(2, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // One strike should be removed.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+
+ // Strike count is past the max limit.
+ strike_database_.AddStrikes(10);
+ EXPECT_EQ(11, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // Strike count should be one less than the max limit.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(5, strike_database_.GetStrikes());
+
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest");
+ // There should be two buckets, for strike counts of 2 and 11.
+ ASSERT_EQ(2U, buckets.size());
+ // Bucket for 2 strikes should have count of 1.
+ GetHistogramTester()->ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest",
+ 2, 1);
+ // Bucket for 11 strikes should have count of 1.
+ GetHistogramTester()->ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest",
+ 11, 1);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ GetKeyForStrikeDatabaseIntegratorUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ("StrikeDatabaseIntegratorTest__1234",
+ strike_database_.GetKey(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ MaxStrikesLimitReachedUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(unique_id));
+ // 1 strike added for |unique_id|.
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(unique_id));
+ // 6 strikes added for |unique_id|.
+ strike_database_.AddStrikes(6, unique_id);
+ EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorUniqueIdTestNthStrikeAddedHistogram) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ // 1st strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 2nd strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 1st strike added for |unique_id_2|.
+ strike_database_.AddStrike(unique_id_2);
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.NthStrikeAdded."
+ "StrikeDatabaseIntegratorTest");
+ // There should be two buckets, one for 1st strike, one for 2nd strike count.
+ ASSERT_EQ(2U, buckets.size());
+ // Both |unique_id_1| and |unique_id_2| have 1st strikes recorded.
+ EXPECT_EQ(2, buckets[0].count);
+ // Only |unique_id_1| has 2nd strike recorded.
+ EXPECT_EQ(1, buckets[1].count);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorUniqueIdTestClearAllStrikes) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ // 1 strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 3 strikes added for |unique_id_2|.
+ strike_database_.AddStrikes(3, unique_id_2);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(3, strike_database_.GetStrikes(unique_id_2));
+ strike_database_.ClearAllStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_2));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ AddStrikeForZeroAndNonZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id));
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(2, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForNonZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id));
+ strike_database_.ClearStrikes(unique_id);
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ strike_database_.ClearStrikes(unique_id);
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ strike_database_.AddStrike(unique_id_1);
+
+ // Advance clock to past the entry for |unique_id_1|'s expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ strike_database_.AddStrike(unique_id_2);
+ strike_database_.RemoveExpiredStrikes();
+
+ // |unique_id_1|'s entry should have its most recent strike expire, but
+ // |unique_id_2|'s should not.
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id_2));
+
+ // Advance clock to past |unique_id_2|'s expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ strike_database_.RemoveExpiredStrikes();
+
+ // |unique_id_1| and |unique_id_2| should have no more unexpired strikes.
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_2));
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database_unittest.cc b/chromium/components/autofill/core/browser/strike_database_unittest.cc
index 57075bb0bac..88a5edeed45 100644
--- a/chromium/components/autofill/core/browser/strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/strike_database_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/autofill/core/browser/suggestion.cc b/chromium/components/autofill/core/browser/suggestion.cc
index c98e0cab5ec..9182bd12337 100644
--- a/chromium/components/autofill/core/browser/suggestion.cc
+++ b/chromium/components/autofill/core/browser/suggestion.cc
@@ -35,7 +35,7 @@ Suggestion::Suggestion(const std::string& v,
: frontend_id(fid),
value(base::UTF8ToUTF16(v)),
label(base::UTF8ToUTF16(l)),
- icon(base::UTF8ToUTF16(i)),
+ icon(i),
match(PREFIX_MATCH),
is_value_secondary(false) {}
diff --git a/chromium/components/autofill/core/browser/suggestion.h b/chromium/components/autofill/core/browser/suggestion.h
index bef99f87e62..0df9efe674b 100644
--- a/chromium/components/autofill/core/browser/suggestion.h
+++ b/chromium/components/autofill/core/browser/suggestion.h
@@ -53,7 +53,7 @@ struct Suggestion {
// Contains an image to display for the suggestion.
gfx::Image custom_icon;
// If |custom_icon| is empty, the name of the fallback built-in icon.
- base::string16 icon;
+ std::string icon;
MatchMode match;
bool is_value_secondary; // |value| should be displayed as secondary text.
};
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.cc b/chromium/components/autofill/core/browser/suggestion_selection.cc
index 354c174d5b0..0a8d6c04a10 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.cc
+++ b/chromium/components/autofill/core/browser/suggestion_selection.cc
@@ -69,6 +69,10 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
matched_profiles->size() < kMaxSuggestedProfilesCount;
i++) {
AutofillProfile* profile = profiles[i];
+
+ if (profile->ShouldSkipFillingOrSuggesting(type.GetStorableType()))
+ continue;
+
base::string16 value =
GetInfoInOneLine(profile, type, comparator.app_locale());
if (value.empty())
@@ -100,7 +104,7 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
}
std::vector<Suggestion> GetUniqueSuggestions(
- const std::vector<ServerFieldType>& other_field_types,
+ const std::vector<ServerFieldType>& field_types,
const std::string app_locale,
const std::vector<AutofillProfile*> matched_profiles,
const std::vector<Suggestion>& suggestions,
@@ -109,7 +113,7 @@ std::vector<Suggestion> GetUniqueSuggestions(
// Limit number of unique profiles as having too many makes the browser hang
// due to drawing calculations (and is also not very useful for the user).
- ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end());
+ ServerFieldTypeSet types(field_types.begin(), field_types.end());
for (size_t i = 0; i < matched_profiles.size() &&
unique_suggestions.size() < kMaxUniqueSuggestionsCount;
++i) {
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.h b/chromium/components/autofill/core/browser/suggestion_selection.h
index 09c64924182..0e6909e4c51 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.h
+++ b/chromium/components/autofill/core/browser/suggestion_selection.h
@@ -34,8 +34,10 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
// Dedupes given suggestions based on if one is a subset of the other.
// Returns unique_suggestions, and adds the corresponding profiles to
// |unique_matched_profiles|. At most |kMaxUniqueSuggestionsCount| are returned.
+// |field_types| stores all of the form's ServerFieldTypes, including that of
+// the field on which the user is currently focused.
std::vector<Suggestion> GetUniqueSuggestions(
- const std::vector<ServerFieldType>& other_field_types,
+ const std::vector<ServerFieldType>& field_types,
const std::string app_locale,
const std::vector<AutofillProfile*> matched_profiles,
const std::vector<Suggestion>& suggestions,
diff --git a/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc b/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
index 5ee5174898e..cb36a7d90d5 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
+++ b/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
@@ -11,10 +11,12 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,8 +31,40 @@ using testing::ResultOf;
namespace {
const std::string TEST_APP_LOCALE = "en-US";
+
+template <typename T>
+bool CompareElements(T* a, T* b) {
+ return a->Compare(*b) < 0;
+}
+
+template <typename T>
+bool ElementsEqual(T* a, T* b) {
+ return a->Compare(*b) == 0;
}
+// Verifies that two vectors have the same elements (according to T::Compare)
+// while ignoring order. This is useful because multiple profiles or credit
+// cards that are added to the SQLite DB within the same second will be returned
+// in GUID (aka random) order.
+template <typename T>
+void ExpectSameElements(const std::vector<T*>& expectations,
+ const std::vector<T*>& results) {
+ ASSERT_EQ(expectations.size(), results.size());
+
+ std::vector<T*> expectations_copy = expectations;
+ std::sort(expectations_copy.begin(), expectations_copy.end(),
+ CompareElements<T>);
+ std::vector<T*> results_copy = results;
+ std::sort(results_copy.begin(), results_copy.end(), CompareElements<T>);
+
+ EXPECT_EQ(std::mismatch(results_copy.begin(), results_copy.end(),
+ expectations_copy.begin(), ElementsEqual<T>)
+ .first,
+ results_copy.end());
+}
+
+} // anonymous namespace
+
class SuggestionSelectionTest : public testing::Test {
public:
SuggestionSelectionTest()
@@ -150,6 +184,52 @@ TEST_F(SuggestionSelectionTest, GetPrefixMatchedSuggestions_LimitProfiles) {
Not(base::ASCIIToUTF16("Marie")))));
}
+TEST_F(SuggestionSelectionTest, GetPrefixMatchedSuggestions_SkipInvalid) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+
+ const std::unique_ptr<AutofillProfile> profile_server_invalid =
+ CreateProfileUniquePtr("Marion");
+ const std::unique_ptr<AutofillProfile> profile_client_invalid =
+ CreateProfileUniquePtr("Bob");
+ const std::unique_ptr<AutofillProfile> profile_valid =
+ CreateProfileUniquePtr("Rose");
+ const std::unique_ptr<AutofillProfile> profile_client_invalid_country_empty =
+ CreateProfileUniquePtr("Lost");
+
+ profile_server_invalid->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::SERVER);
+ profile_client_invalid->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ profile_client_invalid_country_empty->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ profile_client_invalid_country_empty->SetRawInfo(ADDRESS_HOME_COUNTRY,
+ base::ASCIIToUTF16(""));
+
+ const std::vector<AutofillProfile*> profiles_data = {
+ profile_server_invalid.get(), profile_client_invalid.get(),
+ profile_valid.get(), profile_client_invalid_country_empty.get()};
+
+ std::vector<AutofillProfile*> matched_profiles;
+ auto suggestions = GetPrefixMatchedSuggestions(
+ AutofillType(ADDRESS_HOME_STATE), GetCanonicalUtf16Content("C"),
+ comparator_, profiles_data, &matched_profiles);
+
+ ASSERT_EQ(2U, suggestions.size());
+ ASSERT_EQ(2U, matched_profiles.size());
+ EXPECT_THAT(suggestions,
+ ElementsAre(Field(&Suggestion::value, base::ASCIIToUTF16("CA")),
+ Field(&Suggestion::value, base::ASCIIToUTF16("CA"))));
+
+ std::vector<AutofillProfile*> expected_result;
+ expected_result.push_back(profile_valid.get());
+ expected_result.push_back(profile_client_invalid_country_empty.get());
+ ExpectSameElements(matched_profiles, expected_result);
+}
+
TEST_F(SuggestionSelectionTest, GetUniqueSuggestions_SingleDedupe) {
// Give two suggestions with the same name, and no other field to compare.
// Expect only one unique suggestion.
diff --git a/chromium/components/autofill/core/browser/suggestion_test_helpers.h b/chromium/components/autofill/core/browser/suggestion_test_helpers.h
index a5262c052fd..60084bc45a3 100644
--- a/chromium/components/autofill/core/browser/suggestion_test_helpers.h
+++ b/chromium/components/autofill/core/browser/suggestion_test_helpers.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTION_TEST_HELPERS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTION_TEST_HELPERS_H_
+#include <string>
+
#include "components/autofill/core/browser/suggestion.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -85,8 +87,8 @@ template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorIconsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(
- new SuggestionVectorMembersAreMatcher<base::string16>(elts_are_matcher,
- &Suggestion::icon));
+ new SuggestionVectorMembersAreMatcher<std::string>(elts_are_matcher,
+ &Suggestion::icon));
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.cc b/chromium/components/autofill/core/browser/test_autofill_client.cc
index b26056019a3..dadbbd1dfed 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_client.cc
@@ -6,6 +6,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/local_card_migration_manager.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -121,10 +122,10 @@ void TestAutofillClient::ConfirmSaveAutofillProfile(
void TestAutofillClient::ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) {
confirm_save_credit_card_locally_called_ = true;
- offer_to_save_credit_card_bubble_was_shown_ = show_prompt;
+ offer_to_save_credit_card_bubble_was_shown_ = options.show_prompt;
std::move(callback).Run(AutofillClient::ACCEPTED);
}
@@ -134,16 +135,24 @@ void TestAutofillClient::ConfirmAccountNameFixFlow(
credit_card_name_fix_flow_bubble_was_shown_ = true;
std::move(callback).Run(base::string16(base::ASCIIToUTF16("Gaia Name")));
}
+
+void TestAutofillClient::ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) {
+ credit_card_name_fix_flow_bubble_was_shown_ = true;
+ std::move(callback).Run(
+ base::string16(base::ASCIIToUTF16("03")),
+ base::string16(base::ASCIIToUTF16(test::NextYear().c_str())));
+}
#endif // defined(OS_ANDROID)
void TestAutofillClient::ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) {
- offer_to_save_credit_card_bubble_was_shown_ = show_prompt;
+ offer_to_save_credit_card_bubble_was_shown_ = options.show_prompt;
std::move(callback).Run(AutofillClient::ACCEPTED, {});
}
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.h b/chromium/components/autofill/core/browser/test_autofill_client.h
index c2237b15534..71baad73db0 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.h
+++ b/chromium/components/autofill/core/browser/test_autofill_client.h
@@ -69,18 +69,20 @@ class TestAutofillClient : public AutofillClient {
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) override;
#if defined(OS_ANDROID)
void ConfirmAccountNameFixFlow(
base::OnceCallback<void(const base::string16&)> callback) override;
+ void ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) override;
#endif // defined(OS_ANDROID)
void ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) override;
void ConfirmCreditCardFillAssist(const CreditCard& card,
base::OnceClosure callback) override;
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc b/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
index d3eba5d0ee7..8828311186a 100644
--- a/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
@@ -49,8 +49,18 @@ AutofillProfileValidator* TestAutofillProfileValidator::GetInstance() {
return &(instance.Get().autofill_profile_validator_);
}
+// static
+TestAutofillProfileValidatorDelayed*
+TestAutofillProfileValidator::GetDelayedInstance() {
+ static base::LazyInstance<TestAutofillProfileValidator>::DestructorAtExit
+ instance = LAZY_INSTANCE_INITIALIZER;
+ return &(instance.Get().autofill_profile_validator_delayed_);
+}
+
TestAutofillProfileValidator::TestAutofillProfileValidator()
- : autofill_profile_validator_(GetInputSource(), GetInputStorage()) {}
+ : autofill_profile_validator_(GetInputSource(), GetInputStorage()),
+ autofill_profile_validator_delayed_(GetInputSource(), GetInputStorage()) {
+}
TestAutofillProfileValidator::~TestAutofillProfileValidator() {}
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator.h b/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
index 93b7eeee17f..6fa2fbb04a2 100644
--- a/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
@@ -8,6 +8,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "components/autofill/core/browser/autofill_profile_validator.h"
+#include "components/autofill/core/browser/test_autofill_profile_validator_delayed.h"
namespace autofill {
@@ -15,6 +16,7 @@ namespace autofill {
class TestAutofillProfileValidator {
public:
static AutofillProfileValidator* GetInstance();
+ static TestAutofillProfileValidatorDelayed* GetDelayedInstance();
private:
friend struct base::LazyInstanceTraitsBase<TestAutofillProfileValidator>;
@@ -22,8 +24,9 @@ class TestAutofillProfileValidator {
TestAutofillProfileValidator();
~TestAutofillProfileValidator();
- // The only instance that exists.
+ // The only instance that exists of normal and delayed validators.
AutofillProfileValidator autofill_profile_validator_;
+ TestAutofillProfileValidatorDelayed autofill_profile_validator_delayed_;
DISALLOW_COPY_AND_ASSIGN(TestAutofillProfileValidator);
};
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc
new file mode 100644
index 00000000000..ed92eae2fcf
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc
@@ -0,0 +1,39 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/test_autofill_profile_validator_delayed.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/cancelable_callback.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+
+namespace autofill {
+namespace {
+
+const int kRulesDelayedLoadingTimeSeconds = 3;
+
+} // namespace
+
+TestAutofillProfileValidatorDelayed::TestAutofillProfileValidatorDelayed(
+ std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage)
+ : AutofillProfileValidator(std::move(source), std::move(storage)) {}
+
+TestAutofillProfileValidatorDelayed::~TestAutofillProfileValidatorDelayed() {}
+
+void TestAutofillProfileValidatorDelayed::LoadRulesInstantly(
+ const std::string& region_code) {
+ address_validator_.LoadRules(region_code);
+}
+
+void TestAutofillProfileValidatorDelayed::LoadRulesForRegion(
+ const std::string& region_code) {
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&TestAutofillProfileValidatorDelayed::LoadRulesInstantly,
+ base::Unretained(this), region_code),
+ base::TimeDelta::FromSeconds(kRulesDelayedLoadingTimeSeconds));
+}
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h
new file mode 100644
index 00000000000..846c249ee79
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
+
+#include <memory>
+#include <string>
+
+#include "components/autofill/core/browser/autofill_profile_validator.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+namespace autofill {
+
+// Singleton that owns a single AutofillProfileValidator instance. It's a
+// delayed validator used in tests, to make sure that the system can handle
+// possible delays in the real world.
+class TestAutofillProfileValidatorDelayed : public AutofillProfileValidator {
+ public:
+ // Takes ownership of |source| and |storage|.
+ TestAutofillProfileValidatorDelayed(
+ std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage);
+
+ ~TestAutofillProfileValidatorDelayed() override;
+
+ // Starts loading the rules for the specified |region_code|.
+ void LoadRulesForRegion(const std::string& region_code) override;
+
+ private:
+ void LoadRulesInstantly(const std::string& region_code);
+
+ DISALLOW_COPY_AND_ASSIGN(TestAutofillProfileValidatorDelayed);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
diff --git a/chromium/components/autofill/core/browser/test_autofill_provider.h b/chromium/components/autofill/core/browser/test_autofill_provider.h
index 8c69b47e99e..ef533d89c24 100644
--- a/chromium/components/autofill/core/browser/test_autofill_provider.h
+++ b/chromium/components/autofill/core/browser/test_autofill_provider.h
@@ -11,7 +11,7 @@ namespace autofill {
class TestAutofillProvider : public AutofillProvider {
public:
- ~TestAutofillProvider() override{};
+ ~TestAutofillProvider() override {}
// AutofillProvider:
void OnQueryFormFieldAutofill(AutofillHandlerProxy* handler,
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc b/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
index cc72aed5cf6..b9808476079 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
@@ -8,7 +8,6 @@
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
-#include "services/identity/public/cpp/identity_manager.h"
namespace autofill {
@@ -16,11 +15,12 @@ TestLocalCardMigrationManager::TestLocalCardMigrationManager(
AutofillDriver* driver,
AutofillClient* client,
payments::TestPaymentsClient* payments_client,
- PersonalDataManager* personal_data_manager)
+ TestPersonalDataManager* personal_data_manager)
: LocalCardMigrationManager(client,
payments_client,
"en-US",
- personal_data_manager) {}
+ personal_data_manager),
+ personal_data_manager_(personal_data_manager) {}
TestLocalCardMigrationManager::~TestLocalCardMigrationManager() {}
@@ -28,10 +28,19 @@ bool TestLocalCardMigrationManager::IsCreditCardMigrationEnabled() {
bool migration_experiment_enabled =
features::GetLocalCardMigrationExperimentalFlag() !=
features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
+
bool has_google_payments_account =
(static_cast<int64_t>(payments_client_->GetPrefService()->GetDouble(
prefs::kAutofillBillingCustomerNumber)) != 0);
- return migration_experiment_enabled && has_google_payments_account;
+
+ bool sync_feature_enabled =
+ (personal_data_manager_->GetSyncSigninState() ==
+ AutofillSyncSigninState::kSignedInAndSyncFeature);
+
+ return migration_experiment_enabled && has_google_payments_account &&
+ (sync_feature_enabled ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser));
}
bool TestLocalCardMigrationManager::LocalCardMigrationWasTriggered() {
@@ -58,15 +67,22 @@ void TestLocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(
LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(selected_cards);
}
+void TestLocalCardMigrationManager::ResetSyncState(
+ AutofillSyncSigninState sync_state) {
+ personal_data_manager_->SetSyncAndSignInState(sync_state);
+}
+
void TestLocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_bin_ranges) {
if (result == AutofillClient::SUCCESS) {
local_card_migration_was_triggered_ = true;
LocalCardMigrationManager::OnDidGetUploadDetails(
- is_from_settings_page, result, context_token, std::move(legal_message));
+ is_from_settings_page, result, context_token, std::move(legal_message),
+ supported_bin_ranges);
}
}
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h b/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
index 97e4518eb15..722d366dd20 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
@@ -5,9 +5,14 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
+#include <memory>
#include <string>
+#include <utility>
+#include <vector>
#include "components/autofill/core/browser/local_card_migration_manager.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/browser/test_personal_data_manager.h"
namespace autofill {
@@ -17,14 +22,13 @@ class TestPaymentsClient;
class AutofillClient;
class AutofillDriver;
-class PersonalDataManager;
class TestLocalCardMigrationManager : public LocalCardMigrationManager {
public:
TestLocalCardMigrationManager(AutofillDriver* driver,
AutofillClient* client,
payments::TestPaymentsClient* payments_client,
- PersonalDataManager* personal_data_manager);
+ TestPersonalDataManager* personal_data_manager);
~TestLocalCardMigrationManager() override;
// Override the base function. Checks the existnece of billing customer number
@@ -50,12 +54,17 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
void OnUserAcceptedMainMigrationDialog(
const std::vector<std::string>& selected_cards) override;
+ // Mock the Chrome Sync state in the LocalCardMigrationManager. If not set,
+ // default to AutofillSyncSigninState::kSignedInAndSyncFeature.
+ void ResetSyncState(AutofillSyncSigninState sync_state);
+
private:
void OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) override;
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_bin_ranges) override;
bool local_card_migration_was_triggered_ = false;
@@ -63,6 +72,8 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
bool main_prompt_was_shown_ = false;
+ TestPersonalDataManager* personal_data_manager_;
+
DISALLOW_COPY_AND_ASSIGN(TestLocalCardMigrationManager);
};
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc b/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc
deleted file mode 100644
index cc212712538..00000000000
--- a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/test_local_card_migration_strike_database.h"
-
-namespace autofill {
-
-TestLocalCardMigrationStrikeDatabase::TestLocalCardMigrationStrikeDatabase(
- StrikeDatabase* strike_database)
- : LocalCardMigrationStrikeDatabase(strike_database) {}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h b/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h
deleted file mode 100644
index c1cac181ceb..00000000000
--- a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
-
-#include "components/autofill/core/browser/local_card_migration_strike_database.h"
-
-namespace autofill {
-
-class TestLocalCardMigrationStrikeDatabase
- : public LocalCardMigrationStrikeDatabase {
- public:
- TestLocalCardMigrationStrikeDatabase(StrikeDatabase* strike_database);
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/test_personal_data_manager.cc b/chromium/components/autofill/core/browser/test_personal_data_manager.cc
index 9a6e5c35765..209cf497334 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.cc
@@ -19,6 +19,10 @@ void TestPersonalDataManager::OnSyncServiceInitialized(
sync_service_initialized_ = true;
}
+AutofillSyncSigninState TestPersonalDataManager::GetSyncSigninState() const {
+ return sync_and_signin_state_;
+}
+
void TestPersonalDataManager::RecordUseOf(const AutofillDataModel& data_model) {
CreditCard* credit_card = GetCreditCardWithGUID(data_model.guid().c_str());
if (credit_card)
@@ -248,7 +252,8 @@ bool TestPersonalDataManager::IsSyncFeatureEnabled() const {
return sync_feature_enabled_;
}
-AccountInfo TestPersonalDataManager::GetAccountInfoForPaymentsServer() const {
+CoreAccountInfo TestPersonalDataManager::GetAccountInfoForPaymentsServer()
+ const {
return account_info_;
}
diff --git a/chromium/components/autofill/core/browser/test_personal_data_manager.h b/chromium/components/autofill/core/browser/test_personal_data_manager.h
index ae3a7cdb449..8aedd182f36 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.h
@@ -28,6 +28,7 @@ class TestPersonalDataManager : public PersonalDataManager {
// for various tests, whether to skip calls to uncreated databases/services,
// or to make things easier in general to toggle.
void OnSyncServiceInitialized(syncer::SyncService* sync_service) override;
+ AutofillSyncSigninState GetSyncSigninState() const override;
void RecordUseOf(const AutofillDataModel& data_model) override;
std::string SaveImportedProfile(
const AutofillProfile& imported_profile) override;
@@ -55,7 +56,7 @@ class TestPersonalDataManager : public PersonalDataManager {
CreditCard* GetCreditCardByNumber(const std::string& number) override;
bool IsDataLoaded() const override;
bool IsSyncFeatureEnabled() const override;
- AccountInfo GetAccountInfoForPaymentsServer() const override;
+ CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
// Unique to TestPersonalDataManager:
@@ -115,7 +116,11 @@ class TestPersonalDataManager : public PersonalDataManager {
void SetSyncFeatureEnabled(bool enabled) { sync_feature_enabled_ = enabled; }
- void SetAccountInfoForPayments(const AccountInfo& account_info) {
+ void SetSyncAndSignInState(AutofillSyncSigninState sync_and_signin_state) {
+ sync_and_signin_state_ = sync_and_signin_state;
+ }
+
+ void SetAccountInfoForPayments(const CoreAccountInfo& account_info) {
account_info_ = account_info;
}
@@ -129,8 +134,10 @@ class TestPersonalDataManager : public PersonalDataManager {
base::Optional<bool> autofill_credit_card_enabled_;
base::Optional<bool> autofill_wallet_import_enabled_;
bool sync_feature_enabled_ = false;
+ AutofillSyncSigninState sync_and_signin_state_ =
+ AutofillSyncSigninState::kSignedInAndSyncFeature;
bool sync_service_initialized_ = false;
- AccountInfo account_info_;
+ CoreAccountInfo account_info_;
DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager);
};
diff --git a/chromium/components/autofill/core/browser/test_strike_database.cc b/chromium/components/autofill/core/browser/test_strike_database.cc
index bb242f48306..4aee9cb4746 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.cc
+++ b/chromium/components/autofill/core/browser/test_strike_database.cc
@@ -13,7 +13,7 @@ TestStrikeDatabase::TestStrikeDatabase() {}
TestStrikeDatabase::~TestStrikeDatabase() {}
void TestStrikeDatabase::GetProtoStrikes(
- const std::string key,
+ const std::string& key,
const StrikesCallback& outer_callback) {
outer_callback.Run(GetStrikesForTesting(key));
}
diff --git a/chromium/components/autofill/core/browser/test_strike_database.h b/chromium/components/autofill/core/browser/test_strike_database.h
index ebe7731cb1f..d46be27bc4b 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.h
+++ b/chromium/components/autofill/core/browser/test_strike_database.h
@@ -22,7 +22,7 @@ class TestStrikeDatabase : public StrikeDatabase {
~TestStrikeDatabase() override;
// StrikeDatabase:
- void GetProtoStrikes(const std::string key,
+ void GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback) override;
void ClearAllProtoStrikes(
const ClearStrikesCallback& outer_callback) override;
diff --git a/chromium/components/autofill/core/browser/travel_field.cc b/chromium/components/autofill/core/browser/travel_field.cc
new file mode 100644
index 00000000000..cee6b3491c7
--- /dev/null
+++ b/chromium/components/autofill/core/browser/travel_field.cc
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/travel_field.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
+
+namespace autofill {
+
+TravelField::~TravelField() = default;
+
+// static
+std::unique_ptr<FormField> TravelField::Parse(AutofillScanner* scanner) {
+ if (!scanner || scanner->IsEnd()) {
+ return nullptr;
+ }
+
+ auto travel_field = std::make_unique<TravelField>();
+ if (ParseField(scanner, base::UTF8ToUTF16(kPassportRe),
+ &travel_field->passport_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kTravelOriginRe),
+ &travel_field->origin_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kTravelDestinationRe),
+ &travel_field->destination_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kFlightRe),
+ &travel_field->flight_)) {
+ // If any regex matches, then we found a travel field.
+ return std::move(travel_field);
+ }
+
+ return nullptr;
+}
+
+void TravelField::AddClassifications(
+ FieldCandidatesMap* field_candidates) const {
+ // Simply tag all the fields as unknown types. Travel is currently used as
+ // filter.
+ AddClassification(passport_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(origin_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(destination_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(flight_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/travel_field.h b/chromium/components/autofill/core/browser/travel_field.h
new file mode 100644
index 00000000000..0608d26c450
--- /dev/null
+++ b/chromium/components/autofill/core/browser/travel_field.h
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
+
+#include <memory>
+
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/browser/form_field.h"
+
+namespace autofill {
+
+class TravelField : public FormField {
+ public:
+ ~TravelField() override;
+
+ static std::unique_ptr<FormField> Parse(AutofillScanner* scanner);
+
+ protected:
+ void AddClassifications(FieldCandidatesMap* field_candidates) const override;
+
+ private:
+ // All of the following fields are optional.
+ AutofillField* passport_;
+ AutofillField* origin_;
+ AutofillField* destination_;
+ AutofillField* flight_;
+};
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc
new file mode 100644
index 00000000000..812c157cc11
--- /dev/null
+++ b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc
@@ -0,0 +1,77 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/grit/components_scaled_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace autofill {
+
+CardExpirationDateFixFlowViewDelegateMobile::
+ CardExpirationDateFixFlowViewDelegateMobile(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback)
+ : upload_save_card_callback_(std::move(upload_save_card_callback)),
+ shown_(false),
+ had_user_interaction_(false),
+ card_label_(card.NetworkAndLastFourDigits()) {
+ DCHECK(!upload_save_card_callback_.is_null());
+}
+
+CardExpirationDateFixFlowViewDelegateMobile::
+ ~CardExpirationDateFixFlowViewDelegateMobile() {
+ if (shown_ && !had_user_interaction_)
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION);
+}
+
+int CardExpirationDateFixFlowViewDelegateMobile::GetIconId() const {
+ return IDR_AUTOFILL_GOOGLE_PAY_WITH_DIVIDER;
+}
+
+base::string16 CardExpirationDateFixFlowViewDelegateMobile::GetTitleText()
+ const {
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_SAVE_CARD_UPDATE_EXPIRATION_DATE_TITLE);
+}
+
+base::string16 CardExpirationDateFixFlowViewDelegateMobile::GetSaveButtonLabel()
+ const {
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL);
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Accept(
+ const base::string16& month,
+ const base::string16& year) {
+ std::move(upload_save_card_callback_).Run(month, year);
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_ACCEPTED);
+ had_user_interaction_ = true;
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Dismissed() {
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_DISMISSED);
+ had_user_interaction_ = true;
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Shown() {
+ AutofillMetrics::LogExpirationDateFixFlowPromptShown();
+ shown_ = true;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h
new file mode 100644
index 00000000000..d749b79ad1f
--- /dev/null
+++ b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+
+namespace autofill {
+
+// Enables the user to accept or deny expiration date fix flow prompt.
+// Only used on mobile. This class is responsible for its destruction.
+// Destruction is achieved by calling delete when the prompt is
+// dismissed.
+class CardExpirationDateFixFlowViewDelegateMobile {
+ public:
+ CardExpirationDateFixFlowViewDelegateMobile(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback);
+
+ ~CardExpirationDateFixFlowViewDelegateMobile();
+
+ const base::string16& card_label() const { return card_label_; }
+
+ int GetIconId() const;
+ base::string16 GetTitleText() const;
+ base::string16 GetSaveButtonLabel() const;
+ void Accept(const base::string16& month, const base::string16& year);
+ void Dismissed();
+ void Shown();
+
+ private:
+ // The callback to save the credit card to Google Payments once user accepts
+ // fix flow.
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback_;
+
+ // Whether the prompt was shown to the user.
+ bool shown_;
+
+ // Did the user ever explicitly accept or dismiss this prompt?
+ bool had_user_interaction_;
+
+ // Label of the card describing the network and the last four digits.
+ base::string16 card_label_;
+
+ DISALLOW_COPY_AND_ASSIGN(CardExpirationDateFixFlowViewDelegateMobile);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc b/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
index 61ef3737f53..c5d3b1f8980 100644
--- a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
@@ -49,7 +49,8 @@ base::string16 CardNameFixFlowViewDelegateMobile::GetInferredCardHolderName()
}
base::string16 CardNameFixFlowViewDelegateMobile::GetSaveButtonLabel() const {
- return l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_FIX_FLOW_PROMPT_SAVE_CARD);
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL);
}
void CardNameFixFlowViewDelegateMobile::Accept(const base::string16& name) {
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
index 529554614e0..9012160a9b2 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
+++ b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
@@ -500,12 +500,12 @@ TEST_P(CvcInputValidationTest, CvcInputValidation) {
delegate_->response().cvc);
}
-INSTANTIATE_TEST_CASE_P(CardUnmaskPromptControllerImplTest,
- CvcInputValidationTest,
- testing::Values(CvcCase{"123", true, "123"},
- CvcCase{"123 ", true, "123"},
- CvcCase{" 1234 ", false},
- CvcCase{"IOU", false}));
+INSTANTIATE_TEST_SUITE_P(CardUnmaskPromptControllerImplTest,
+ CvcInputValidationTest,
+ testing::Values(CvcCase{"123", true, "123"},
+ CvcCase{"123 ", true, "123"},
+ CvcCase{" 1234 ", false},
+ CvcCase{"IOU", false}));
class CvcInputAmexValidationTest
: public CardUnmaskPromptControllerImplGenericTest,
@@ -541,14 +541,14 @@ TEST_P(CvcInputAmexValidationTest, CvcInputValidation) {
delegate_->response().cvc);
}
-INSTANTIATE_TEST_CASE_P(CardUnmaskPromptControllerImplTest,
- CvcInputAmexValidationTest,
- testing::Values(CvcCase{"123", false},
- CvcCase{"123 ", false},
- CvcCase{"1234", true, "1234"},
- CvcCase{"\t1234 ", true, "1234"},
- CvcCase{" 1234", true, "1234"},
- CvcCase{"IOU$", false}));
+INSTANTIATE_TEST_SUITE_P(CardUnmaskPromptControllerImplTest,
+ CvcInputAmexValidationTest,
+ testing::Values(CvcCase{"123", false},
+ CvcCase{"123 ", false},
+ CvcCase{"1234", true, "1234"},
+ CvcCase{"\t1234 ", true, "1234"},
+ CvcCase{" 1234", true, "1234"},
+ CvcCase{"IOU$", false}));
struct ExpirationDateTestCase {
const char* input_month;
@@ -584,7 +584,7 @@ TEST_P(ExpirationDateValidationTest, ExpirationDateValidation) {
ASCIIToUTF16(exp_case.input_year)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CardUnmaskPromptControllerImplTest,
ExpirationDateValidationTest,
testing::Values(ExpirationDateTestCase{"01", "2040", true},
diff --git a/chromium/components/autofill/core/browser/validation.cc b/chromium/components/autofill/core/browser/validation.cc
index bce4371b0de..3b4bf965681 100644
--- a/chromium/components/autofill/core/browser/validation.cc
+++ b/chromium/components/autofill/core/browser/validation.cc
@@ -51,7 +51,7 @@ bool IsValidCreditCardExpirationYear(int year, const base::Time& now) {
}
bool IsValidCreditCardNumber(const base::string16& text) {
- base::string16 number = CreditCard::StripSeparators(text);
+ const base::string16 number = CreditCard::StripSeparators(text);
if (!HasCorrectLength(number))
return false;
@@ -92,12 +92,13 @@ bool HasCorrectLength(const base::string16& number) {
return true;
}
-bool PassesLuhnCheck(base::string16& number) {
+// TODO (crbug.com/927767): Add unit tests for this function.
+bool PassesLuhnCheck(const base::string16& number) {
// Use the Luhn formula [3] to validate the number.
// [3] http://en.wikipedia.org/wiki/Luhn_algorithm
int sum = 0;
bool odd = false;
- for (base::string16::reverse_iterator iter = number.rbegin();
+ for (base::string16::const_reverse_iterator iter = number.rbegin();
iter != number.rend(); ++iter) {
if (!base::IsAsciiDigit(*iter))
return false;
diff --git a/chromium/components/autofill/core/browser/validation.h b/chromium/components/autofill/core/browser/validation.h
index 5c7dccf1a65..470d07556a0 100644
--- a/chromium/components/autofill/core/browser/validation.h
+++ b/chromium/components/autofill/core/browser/validation.h
@@ -52,7 +52,7 @@ bool IsValidCreditCardNumber(const base::string16& text);
bool HasCorrectLength(const base::string16& number);
// Returns true if |number| passes the validation by Luhn formula.
-bool PassesLuhnCheck(base::string16& number);
+bool PassesLuhnCheck(const base::string16& number);
// Returns true if |code| looks like a valid credit card security code
// for the given credit card type.
diff --git a/chromium/components/autofill/core/browser/validation_unittest.cc b/chromium/components/autofill/core/browser/validation_unittest.cc
index b9a9808d306..2604226c1a6 100644
--- a/chromium/components/autofill/core/browser/validation_unittest.cc
+++ b/chromium/components/autofill/core/browser/validation_unittest.cc
@@ -188,7 +188,7 @@ TEST_P(AutofillTypeValidationTest, IsValidForType) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardExpDate,
AutofillTypeValidationTest,
testing::Values(
@@ -231,7 +231,7 @@ INSTANTIATE_TEST_CASE_P(
false,
IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardMonth,
AutofillTypeValidationTest,
testing::Values(
@@ -254,7 +254,7 @@ INSTANTIATE_TEST_CASE_P(
false,
IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRATION_MONTH)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardYear,
AutofillTypeValidationTest,
testing::Values(
@@ -351,7 +351,7 @@ const static std::set<std::string> kAllBasicCardNetworks{
"amex", "discover", "diners", "elo", "jcb",
"mastercard", "mir", "unionpay", "visa"};
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardNumber,
AutofillCCNumberValidationTest,
testing::Values(
@@ -433,7 +433,7 @@ TEST_P(AutofillGetCvcLengthForCardType, GetCvcLengthForCardType) {
GetCvcLengthForCardType(GetParam().card_type));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardCvcLength,
AutofillGetCvcLengthForCardType,
testing::Values(
@@ -465,33 +465,33 @@ TEST_P(AutofillIsUPIVirtualPaymentAddress, IsUPIVirtualPaymentAddress) {
IsUPIVirtualPaymentAddress(ASCIIToUTF16("user@" + GetParam() + ".com")));
}
-INSTANTIATE_TEST_CASE_P(UPIVirtualPaymentAddress,
- AutofillIsUPIVirtualPaymentAddress,
- testing::Values("upi",
- "allbank",
- "andb",
- "axisbank",
- "barodampay",
- "mahb",
- "cnrb",
- "csbpay",
- "dcb",
- "federal",
- "hdfcbank",
- "pockets",
- "icici",
- "idfcbank",
- "indus",
- "kbl",
- "kaypay",
- "pnb",
- "sib",
- "sbi",
- "tjsb",
- "uco",
- "unionbank",
- "united",
- "vijb",
- "ybl"));
+INSTANTIATE_TEST_SUITE_P(UPIVirtualPaymentAddress,
+ AutofillIsUPIVirtualPaymentAddress,
+ testing::Values("upi",
+ "allbank",
+ "andb",
+ "axisbank",
+ "barodampay",
+ "mahb",
+ "cnrb",
+ "csbpay",
+ "dcb",
+ "federal",
+ "hdfcbank",
+ "pockets",
+ "icici",
+ "idfcbank",
+ "indus",
+ "kbl",
+ "kaypay",
+ "pnb",
+ "sib",
+ "sbi",
+ "tjsb",
+ "uco",
+ "unionbank",
+ "united",
+ "vijb",
+ "ybl"));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_change.h b/chromium/components/autofill/core/browser/webdata/autofill_change.h
index 16c6290fa60..9605de1e35b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_change.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_change.h
@@ -97,10 +97,33 @@ class AutofillProfileDeepChange : public AutofillProfileChange {
~AutofillProfileDeepChange() override {}
- AutofillProfile profile() const { return profile_; }
+ const AutofillProfile* profile() const { return &profile_; }
+ bool is_ongoing_on_background() const { return is_ongoing_on_background_; }
+ void set_is_ongoing_on_background() const {
+ is_ongoing_on_background_ = true;
+ }
+
+ void validation_effort_made() const { validation_effort_made_ = true; }
+ bool has_validation_effort_made() const { return validation_effort_made_; }
+
+ void set_enforce_update() { enforce_update_ = true; }
+ bool enforce_update() const { return enforce_update_; }
private:
AutofillProfile profile_;
+ // Is true when the change is taking place on the database side on the
+ // background.
+ mutable bool is_ongoing_on_background_ = false;
+ // Is true when the |profile_| has gone through the validation process.
+ // Note: This could be different from the
+ // profile_.is_client_validity_states_updated. |validation_effort_made_| shows
+ // that the effort has been made, but not necessarily successful, and profile
+ // validity may or may not be updated.
+ mutable bool validation_effort_made_ = false;
+
+ // Is true when the update should happen regardless of an equal profile.
+ // (equal in the sense of AutofillProfile::EqualForUpdate)
+ mutable bool enforce_update_ = false;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
index f05cd1227fd..bd2bff78a16 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
@@ -27,6 +27,7 @@ AutofillProfileDataTypeController::AutofillProfileDataTypeController(
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service)
: AsyncDirectoryTypeController(syncer::AUTOFILL_PROFILE,
dump_stack,
@@ -34,6 +35,7 @@ AutofillProfileDataTypeController::AutofillProfileDataTypeController(
sync_client,
syncer::GROUP_DB,
std::move(db_thread)),
+ pdm_provider_(pdm_provider),
web_data_service_(web_data_service),
callback_registered_(false),
currently_enabled_(IsEnabled()) {
@@ -53,7 +55,7 @@ void AutofillProfileDataTypeController::OnPersonalDataChanged() {
DCHECK(CalledOnValidThread());
DCHECK_EQ(state(), MODEL_STARTING);
- sync_client()->GetPersonalDataManager()->RemoveObserver(this);
+ pdm_provider_.Run()->RemoveObserver(this);
if (!web_data_service_)
return;
@@ -78,8 +80,7 @@ bool AutofillProfileDataTypeController::StartModels() {
DisableForPolicy();
return false;
}
- autofill::PersonalDataManager* personal_data =
- sync_client()->GetPersonalDataManager();
+ autofill::PersonalDataManager* personal_data = pdm_provider_.Run();
// Make sure PDM has the sync service. This is needed because in the account
// wallet data mode, PDM uses the service to determine whether to use the
@@ -118,7 +119,7 @@ bool AutofillProfileDataTypeController::StartModels() {
void AutofillProfileDataTypeController::StopModels() {
DCHECK(CalledOnValidThread());
- sync_client()->GetPersonalDataManager()->RemoveObserver(this);
+ pdm_provider_.Run()->RemoveObserver(this);
}
bool AutofillProfileDataTypeController::ReadyForStart() const {
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
index b2886eea632..4641b0d223d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_DATA_TYPE_CONTROLLER_H_
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -16,6 +17,7 @@
namespace autofill {
class AutofillWebDataService;
+class PersonalDataManager;
} // namespace autofill
namespace syncer {
@@ -30,12 +32,16 @@ class AutofillProfileDataTypeController
: public syncer::AsyncDirectoryTypeController,
public autofill::PersonalDataManagerObserver {
public:
+ using PersonalDataManagerProvider =
+ base::RepeatingCallback<autofill::PersonalDataManager*()>;
+
// |dump_stack| is called when an unrecoverable error occurs.
AutofillProfileDataTypeController(
scoped_refptr<base::SingleThreadTaskRunner> db_thread,
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service);
~AutofillProfileDataTypeController() override;
@@ -61,6 +67,9 @@ class AutofillProfileDataTypeController
// Report an error (which will stop the datatype asynchronously).
void DisableForPolicy();
+ // Callback that allows accessing PersonalDataManager lazily.
+ const PersonalDataManagerProvider pdm_provider_;
+
// A reference to the AutofillWebDataService for this controller.
scoped_refptr<autofill::AutofillWebDataService> web_data_service_;
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 4ee20ea6814..a5047b4ae5b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -124,8 +124,9 @@ Optional<syncer::ModelError> AutofillProfileSyncBridge::MergeSyncData(
RETURN_IF_ERROR(
initial_sync_tracker.MergeSimilarEntriesForInitialSync(app_locale_));
- RETURN_IF_ERROR(
- FlushSyncTracker(std::move(metadata_change_list), &initial_sync_tracker));
+ RETURN_IF_ERROR(FlushSyncTracker(std::move(metadata_change_list),
+ &initial_sync_tracker,
+ AutofillProfileSyncChangeOrigin::kInitial));
web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL_PROFILE);
return base::nullopt;
@@ -156,7 +157,8 @@ Optional<ModelError> AutofillProfileSyncBridge::ApplySyncChanges(
}
}
- return FlushSyncTracker(std::move(metadata_change_list), &tracker);
+ return FlushSyncTracker(std::move(metadata_change_list), &tracker,
+ AutofillProfileSyncChangeOrigin::kIncrementalRemote);
}
void AutofillProfileSyncBridge::GetData(StorageKeyList storage_keys,
@@ -215,6 +217,21 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
std::make_unique<syncer::SyncMetadataStoreChangeList>(
GetAutofillTable(), syncer::AUTOFILL_PROFILE);
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ bool is_converted_from_server = false;
+ if (change.type() == AutofillProfileChange::REMOVE) {
+ // The profile is not available any more so we cannot compare its value,
+ // instead we use a rougher test based on the id - whether it is a local
+ // GUID or a server id. As a result, it has a different semantics compared
+ // to AddOrUpdate.
+ is_converted_from_server = !base::IsValidGUID(change.key());
+ } else {
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ GetAutofillTable()->GetServerProfiles(&server_profiles);
+ is_converted_from_server = IsLocalProfileEqualToServerProfile(
+ server_profiles, *change.data_model(), app_locale_);
+ }
+
switch (change.type()) {
case AutofillProfileChange::ADD:
case AutofillProfileChange::UPDATE:
@@ -222,6 +239,12 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
change.key(),
CreateEntityDataFromAutofillProfile(*change.data_model()),
metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::REMOVE:
// Removals have no data_model() so this change can still be for a
@@ -231,6 +254,12 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
// TODO(jkrcal): implement a hash map of known storage_keys and use it
// here.
change_processor()->Delete(change.key(), metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileDeleteOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::EXPIRE:
// EXPIRE changes are not being issued for profiles.
@@ -245,7 +274,8 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
std::unique_ptr<MetadataChangeList> metadata_change_list,
- AutofillProfileSyncDifferenceTracker* tracker) {
+ AutofillProfileSyncDifferenceTracker* tracker,
+ AutofillProfileSyncChangeOrigin origin) {
DCHECK(tracker);
RETURN_IF_ERROR(tracker->FlushToLocal(
@@ -259,6 +289,9 @@ base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
CreateEntityDataFromAutofillProfile(*entry),
metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(origin);
}
return static_cast<syncer::SyncMetadataStoreChangeList*>(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
index a6e50098fe8..9b449f47d66 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
@@ -29,6 +29,7 @@ class AutofillProfileSyncDifferenceTracker;
class AutofillTable;
class AutofillWebDataBackend;
class AutofillWebDataService;
+enum class AutofillProfileSyncChangeOrigin;
// Sync bridge implementation for AUTOFILL_PROFILE model type. Takes care of
// propagating local autofill profiles to other clients as well as incorporating
@@ -90,7 +91,9 @@ class AutofillProfileSyncBridge
// Flushes changes accumulated within |tracker| both to local and to sync.
base::Optional<syncer::ModelError> FlushSyncTracker(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
- AutofillProfileSyncDifferenceTracker* tracker);
+ AutofillProfileSyncDifferenceTracker* tracker,
+ // TODO(crbug.com/904390): Remove |origin| when the investigation is over.
+ AutofillProfileSyncChangeOrigin origin);
// Synchronously load sync metadata from the autofill table and pass it to the
// processor so that it can start tracking changes.
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
index 552c2dabef6..08e50b60dfa 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -1208,7 +1208,7 @@ TEST_P(AutofillProfileSyncBridgeUpdatesUsageStatsTest, UpdatesUsageStats) {
EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(merged)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillProfileSyncBridgeTest,
AutofillProfileSyncBridgeUpdatesUsageStatsTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index 51d3cb7ee83..8022c6abd15 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -17,6 +17,8 @@
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/form_group.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
@@ -184,6 +186,10 @@ AutofillProfileSyncableService::MergeDataAndStartSyncing(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_ADD,
CreateData(*(it.second))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin::kInitial);
profiles_map_[it.first] = it.second;
}
@@ -192,6 +198,10 @@ AutofillProfileSyncableService::MergeDataAndStartSyncing(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
CreateData(*(bundle.profiles_to_sync_back[i]))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin::kInitial);
}
if (!new_changes.empty()) {
@@ -603,6 +613,24 @@ void AutofillProfileSyncableService::ActOnChange(
return;
}
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ bool is_converted_from_server = false;
+ if (change.type() == AutofillProfileChange::REMOVE) {
+ // The profile is not available any more so we cannot compare its value,
+ // instead we use a rougher test based on the id - whether it is a local
+ // GUID or a server id. As a result, it has a different semantics compared
+ // to AddOrUpdate.
+ is_converted_from_server = !base::IsValidGUID(change.key());
+ } else {
+ // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests.
+ if (webdata_backend_ != nullptr) {
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ GetAutofillTable()->GetServerProfiles(&server_profiles);
+ is_converted_from_server = IsLocalProfileEqualToServerProfile(
+ server_profiles, *change.data_model(), app_locale_);
+ }
+ }
+
syncer::SyncChangeList new_changes;
DataBundle bundle;
switch (change.type()) {
@@ -616,6 +644,12 @@ void AutofillProfileSyncableService::ActOnChange(
profiles_.push_back(
std::make_unique<AutofillProfile>(*(change.data_model())));
profiles_map_[change.data_model()->guid()] = profiles_.back().get();
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::UPDATE: {
auto it = profiles_map_.find(change.data_model()->guid());
@@ -625,6 +659,12 @@ void AutofillProfileSyncableService::ActOnChange(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
CreateData(*(change.data_model()))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
}
case AutofillProfileChange::REMOVE: {
@@ -636,6 +676,11 @@ void AutofillProfileSyncableService::ActOnChange(
syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
CreateData(empty_profile)));
profiles_map_.erase(change.key());
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileDeleteOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
}
break;
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
index b4dc3f5db51..1b605e9446b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -1557,7 +1557,7 @@ TEST_P(SyncUpdatesUsageStatsTest, SyncUpdatesUsageStats) {
autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillProfileSyncableServiceTest,
SyncUpdatesUsageStatsTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
index 593ce4bc14c..5a9777ebc0d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
@@ -58,4 +58,4 @@ CreateAutofillWalletSpecificsForPaymentsCustomerData(
return wallet_specifics;
}
-} // namespace autofill \ No newline at end of file
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 14d9f4ec53d..5ca2d3bd78a 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -2797,9 +2797,8 @@ class GetFormValuesTest : public testing::TestWithParam<GetFormValuesTestCase> {
};
TEST_P(GetFormValuesTest, GetFormValuesForElementName_SubstringMatchEnabled) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
auto test_case = GetParam();
SCOPED_TRACE(testing::Message()
@@ -2831,7 +2830,7 @@ TEST_P(GetFormValuesTest, GetFormValuesForElementName_SubstringMatchEnabled) {
table_->RemoveFormElementsAddedBetween(t1, Time(), &changes);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillTableTest,
GetFormValuesTest,
testing::Values(GetFormValuesTestCase{{"user.test", "test_user"},
@@ -2979,10 +2978,10 @@ TEST_P(AutofillTableTestPerModelType, AutofillCorruptModelTypeState) {
EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
}
-INSTANTIATE_TEST_CASE_P(AutofillTableTest,
- AutofillTableTestPerModelType,
- testing::Values(syncer::AUTOFILL,
- syncer::AUTOFILL_PROFILE));
+INSTANTIATE_TEST_SUITE_P(AutofillTableTest,
+ AutofillTableTestPerModelType,
+ testing::Values(syncer::AUTOFILL,
+ syncer::AUTOFILL_PROFILE));
TEST_F(AutofillTableTest, RemoveOrphanAutofillTableRows) {
// Populate the different tables.
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
index 98721d9d598..5f511af4a6c 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -320,7 +320,9 @@ AutofillWalletMetadataSyncBridge::AutofillWalletMetadataSyncBridge(
LoadDataCacheAndMetadata();
}
-AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {}
+AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
void AutofillWalletMetadataSyncBridge::OnWalletDataTrackingStateChanged(
bool is_tracking) {
@@ -338,6 +340,7 @@ base::Optional<syncer::ModelError>
AutofillWalletMetadataSyncBridge::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// First upload local entities that are not mentioned in |entity_data|.
UploadInitialLocalData(metadata_change_list.get(), entity_data);
@@ -349,6 +352,7 @@ base::Optional<syncer::ModelError>
AutofillWalletMetadataSyncBridge::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return MergeRemoteChanges(std::move(metadata_change_list),
std::move(entity_data));
}
@@ -369,6 +373,7 @@ void AutofillWalletMetadataSyncBridge::GetAllDataForDebugging(
std::string AutofillWalletMetadataSyncBridge::GetClientTag(
const syncer::EntityData& entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const WalletMetadataSpecifics& remote_metadata =
entity_data.specifics.wallet_metadata();
return GetClientTagForSpecificsId(remote_metadata.type(),
@@ -377,6 +382,7 @@ std::string AutofillWalletMetadataSyncBridge::GetClientTag(
std::string AutofillWalletMetadataSyncBridge::GetStorageKey(
const syncer::EntityData& entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return GetStorageKeyForWalletMetadataTypeAndSpecificsId(
entity_data.specifics.wallet_metadata().type(),
entity_data.specifics.wallet_metadata().id());
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
index 4306ae52280..a9322372bcb 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -81,6 +81,9 @@ const std::string kCard1StorageKey =
const char kAddr1SyncTag[] = "address-YWRkcjHvv74=";
const char kCard1SyncTag[] = "card-Y2FyZDHvv74=";
+const char kLocalAddr1ServerId[] = "e171e3ed-858a-4dd5-9bf3-8517f14ba5fc";
+const char kLocalAddr2ServerId[] = "fa232b9a-f248-4e5a-8d76-d46f821c0c5f";
+
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
@@ -103,17 +106,18 @@ std::string GetCardStorageKey(const std::string& specifics_id) {
WalletMetadataSpecifics::CARD, specifics_id);
}
-WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddressWithUseStats(
+WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddressWithDetails(
const std::string& specifics_id,
size_t use_count,
- int64_t use_date) {
+ int64_t use_date,
+ bool has_converted = false) {
WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::ADDRESS);
specifics.set_use_count(use_count);
specifics.set_use_date(use_date);
- // Set the default value according to the constructor of AutofillProfile.
- specifics.set_address_has_converted(false);
+ // False is the default value according to the constructor of AutofillProfile.
+ specifics.set_address_has_converted(has_converted);
return specifics;
}
@@ -121,22 +125,24 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddress(
const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
- return CreateWalletMetadataSpecificsForAddressWithUseStats(
+ return CreateWalletMetadataSpecificsForAddressWithDetails(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
-WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithUseStats(
+WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithDetails(
const std::string& specifics_id,
size_t use_count,
- int64_t use_date) {
+ int64_t use_date,
+ const std::string& billing_address_id = "") {
WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::CARD);
specifics.set_use_count(use_count);
specifics.set_use_date(use_date);
- // Set the default value according to the constructor of AutofillProfile.
- specifics.set_card_billing_address_id("");
+ // "" is the default value according to the constructor of AutofillProfile;
+ // this field is Base64 encoded in the protobuf.
+ specifics.set_card_billing_address_id(GetBase64EncodedId(billing_address_id));
return specifics;
}
@@ -144,29 +150,49 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard(
const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
- return CreateWalletMetadataSpecificsForCardWithUseStats(
+ return CreateWalletMetadataSpecificsForCardWithDetails(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
-AutofillProfile CreateServerProfileWithUseStats(const std::string& server_id,
- size_t use_count,
- int64_t use_date) {
+AutofillProfile CreateServerProfileWithDetails(const std::string& server_id,
+ size_t use_count,
+ int64_t use_date,
+ bool has_converted = false) {
AutofillProfile profile = CreateServerProfile(server_id);
profile.set_use_count(use_count);
profile.set_use_date(UseDateFromProtoValue(use_date));
+ profile.set_has_converted(has_converted);
return profile;
}
-CreditCard CreateServerCreditCardWithUseStats(const std::string& server_id,
- size_t use_count,
- int64_t use_date) {
+CreditCard CreateServerCreditCardWithDetails(
+ const std::string& server_id,
+ size_t use_count,
+ int64_t use_date,
+ const std::string& billing_address_id = "") {
CreditCard card = CreateServerCreditCard(server_id);
card.set_use_count(use_count);
card.set_use_date(UseDateFromProtoValue(use_date));
+ card.set_billing_address_id(billing_address_id);
return card;
}
+AutofillProfile CreateServerProfileFromSpecifics(
+ const WalletMetadataSpecifics& specifics) {
+ return CreateServerProfileWithDetails(
+ GetBase64DecodedId(specifics.id()), specifics.use_count(),
+ specifics.use_date(), specifics.address_has_converted());
+}
+
+CreditCard CreateServerCreditCardFromSpecifics(
+ const WalletMetadataSpecifics& specifics) {
+ return CreateServerCreditCardWithDetails(
+ GetBase64DecodedId(specifics.id()), specifics.use_count(),
+ specifics.use_date(),
+ GetBase64DecodedId(specifics.card_billing_address_id()));
+}
+
void ExtractWalletMetadataSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch,
std::vector<WalletMetadataSpecifics>* output) {
@@ -182,7 +208,7 @@ std::string WalletMetadataSpecificsAsDebugString(
output << "[id: " << specifics.id()
<< ", type: " << static_cast<int>(specifics.type())
<< ", use_count: " << specifics.use_count()
- << ", use_date: " << UseDateFromProtoValue(specifics.use_date())
+ << ", use_date: " << specifics.use_date()
<< ", card_billing_address_id: "
<< (specifics.has_card_billing_address_id()
? specifics.card_billing_address_id()
@@ -256,11 +282,47 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
}
- void ResetBridge() {
+ void ResetBridge(bool initial_sync_done = true) {
+ sync_pb::ModelTypeState model_type_state;
+ model_type_state.set_initial_sync_done(initial_sync_done);
+ EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_METADATA,
+ model_type_state));
bridge_.reset(new AutofillWalletMetadataSyncBridge(
mock_processor_.CreateForwardingProcessor(), &backend_));
}
+ void StartSyncing(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ base::RunLoop loop;
+ syncer::DataTypeActivationRequest request;
+ request.error_handler = base::DoNothing();
+ real_processor_->OnSyncStarting(
+ request,
+ base::BindLambdaForTesting(
+ [&loop](std::unique_ptr<syncer::DataTypeActivationResponse>) {
+ loop.Quit();
+ }));
+ loop.Run();
+
+ ReceiveUpdates(remote_data);
+ }
+
+ void ReceiveUpdates(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ // Make sure each update has an updated response version so that it does not
+ // get filtered out as reflection by the processor.
+ ++response_version;
+ // After this update initial sync is for sure done.
+ sync_pb::ModelTypeState state;
+ state.set_initial_sync_done(true);
+
+ syncer::UpdateResponseDataList updates;
+ for (const WalletMetadataSpecifics& specifics : remote_data) {
+ updates.push_back(SpecificsToUpdateResponse(specifics));
+ }
+ real_processor_->OnUpdateReceived(state, updates);
+ }
+
EntityData SpecificsToEntity(const WalletMetadataSpecifics& specifics) {
EntityData data;
*data.specifics.mutable_wallet_metadata() = specifics;
@@ -269,6 +331,14 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
return data;
}
+ syncer::UpdateResponseData SpecificsToUpdateResponse(
+ const WalletMetadataSpecifics& specifics) {
+ syncer::UpdateResponseData data;
+ data.entity = SpecificsToEntity(specifics).PassToPtr();
+ data.response_version = response_version;
+ return data;
+ }
+
std::vector<WalletMetadataSpecifics> GetAllLocalData() {
std::vector<WalletMetadataSpecifics> data;
// Perform an async call synchronously for testing.
@@ -321,6 +391,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
MockAutofillWebDataBackend* backend() { return &backend_; }
private:
+ int response_version = 0;
autofill::TestAutofillClock test_clock_;
ScopedTempDir temp_dir_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
@@ -449,15 +520,15 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
// local metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DontSendLowerValueToServerOnUpdate) {
- table()->SetServerProfiles({CreateServerProfileWithUseStats(
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/2, /*use_date=*/5)});
- table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/3, /*use_date=*/6)});
ResetBridge();
- AutofillProfile updated_profile = CreateServerProfileWithUseStats(
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/4);
- CreditCard updated_card = CreateServerCreditCardWithUseStats(
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
@@ -472,9 +543,44 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
EXPECT_THAT(
GetAllLocalDataInclRestart(),
UnorderedElementsAre(
- EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithUseStats(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5)),
- EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithUseStats(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6))));
+}
+
+// Verify that lower values of metadata are not sent to the sync server when
+// local metadata is created (tests the case when metadata with higher use
+// counts arrive before the data, the data bridge later notifies about creation
+// for data that is already there).
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ DontSendLowerValueToServerOnCreation) {
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
+ kAddr1ServerId, /*use_count=*/2, /*use_date=*/5)});
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
+ kCard1ServerId, /*use_count=*/3, /*use_date=*/6)});
+ ResetBridge();
+
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
+ kAddr1ServerId, /*use_count=*/1, /*use_date=*/4);
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
+ kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
+
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ bridge()->AutofillProfileChanged(
+ AutofillProfileChange(AutofillProfileChange::ADD,
+ updated_profile.server_id(), &updated_profile));
+ bridge()->CreditCardChanged(CreditCardChange(
+ CreditCardChange::ADD, updated_card.server_id(), &updated_card));
+
+ // Check that also the local metadata did not get updated.
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5)),
+ EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6))));
}
@@ -482,22 +588,22 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
SendHigherValuesToServerOnLocalUpdate) {
- table()->SetServerProfiles({CreateServerProfileWithUseStats(
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/2)});
- table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/3, /*use_date=*/4)});
ResetBridge();
- AutofillProfile updated_profile = CreateServerProfileWithUseStats(
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard updated_card = CreateServerCreditCardWithUseStats(
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -522,16 +628,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
TEST_F(AutofillWalletMetadataSyncBridgeTest,
SendNewDataToServerOnLocalAddition) {
ResetBridge();
- AutofillProfile new_profile = CreateServerProfileWithUseStats(
+ AutofillProfile new_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard new_card = CreateServerCreditCardWithUseStats(
+ CreditCard new_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -556,16 +662,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// recreates metadata that may get deleted in the mean-time).
TEST_F(AutofillWalletMetadataSyncBridgeTest, SendNewDataToServerOnLocalUpdate) {
ResetBridge();
- AutofillProfile new_profile = CreateServerProfileWithUseStats(
+ AutofillProfile new_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard new_card = CreateServerCreditCardWithUseStats(
+ CreditCard new_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -588,9 +694,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, SendNewDataToServerOnLocalUpdate) {
// Verify that one-off deletion of existing metadata is sent to the sync server.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DeleteExistingDataFromServerOnLocalDeletion) {
- AutofillProfile existing_profile = CreateServerProfileWithUseStats(
+ AutofillProfile existing_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard existing_card = CreateServerCreditCardWithUseStats(
+ CreditCard existing_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
table()->SetServerProfiles({existing_profile});
table()->SetServerCreditCards({existing_card});
@@ -611,9 +717,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// Verify that deletion of non-existing metadata is not sent to the sync server.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DoNotDeleteNonExistingDataFromServerOnLocalDeletion) {
- AutofillProfile existing_profile = CreateServerProfileWithUseStats(
+ AutofillProfile existing_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard existing_card = CreateServerCreditCardWithUseStats(
+ CreditCard existing_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
// Save only data and not metadata.
table()->SetServerAddressesData({existing_profile});
@@ -624,7 +730,6 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
ASSERT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
- EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
@@ -635,4 +740,639 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
}
+enum RemoteChangesMode {
+ INITIAL_SYNC_ADD, // Initial sync -> ADD changes.
+ LATER_SYNC_ADD, // Later sync; the client receives the data for the first
+ // time -> ADD changes.
+ LATER_SYNC_UPDATE // Later sync; the client has received the data before ->
+ // UPDATE changes.
+};
+
+// Parametrized fixture for tests that apply in the same way for all
+// RemoteChangesModes.
+class AutofillWalletMetadataSyncBridgeRemoteChangesTest
+ : public testing::WithParamInterface<RemoteChangesMode>,
+ public AutofillWalletMetadataSyncBridgeTest {
+ public:
+ AutofillWalletMetadataSyncBridgeRemoteChangesTest() {}
+ ~AutofillWalletMetadataSyncBridgeRemoteChangesTest() override {}
+
+ void ResetBridgeWithPotentialInitialSync(
+ const std::vector<WalletMetadataSpecifics>& remote_data) {
+ AutofillWalletMetadataSyncBridgeTest::ResetBridge(
+ /*initial_sync_done=*/GetParam() != INITIAL_SYNC_ADD);
+
+ if (GetParam() == LATER_SYNC_UPDATE) {
+ StartSyncing(remote_data);
+ }
+ }
+
+ void ReceivePotentiallyInitialUpdates(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ if (GetParam() != LATER_SYNC_UPDATE) {
+ StartSyncing(remote_data);
+ } else {
+ AutofillWalletMetadataSyncBridgeTest::ReceiveUpdates(remote_data);
+ }
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AutofillWalletMetadataSyncBridgeRemoteChangesTest);
+};
+
+// No upstream communication or local DB change happens if the server sends an
+// empty update.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, EmptyUpdateIgnored) {
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ResetBridgeWithPotentialInitialSync({});
+ ReceivePotentiallyInitialUpdates({});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
+}
+
+// No upstream communication or local DB change happens if the server sends the
+// same data as we have locally.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, SameDataIgnored) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({profile, card});
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Tests that if the remote use stats are higher / newer, they should win over
+// local stats.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_RemoteWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile),
+ EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if the local use stats are higher / newer, they should win over
+// remote stats.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_LocalWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(profile), _));
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Tests that the conflicts are resolved component-wise (a higher use_count is
+// taken from local data, a newer use_data is taken from remote data).
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_BothWin1) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/50);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile),
+ EqualsSpecifics(merged_card)));
+}
+
+// Tests that the conflicts are resolved component-wise, like the previous test,
+// only the other way around (a higher use_count is taken from remote data, a
+// newer use_data is taken from local data).
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_BothWin2) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile),
+ EqualsSpecifics(merged_card)));
+}
+
+// No merge logic is applied if local data has initial use_count (=1). In this
+// situation, we just take over the remote entity completely.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferRemoteIfLocalHasInitialUseCount) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/1, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile),
+ EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that with a conflict in billing_address_id, we prefer an ID of a local
+// profile over an ID of a server profile. In this test, the preferred ID is in
+// the remote update that we need to store locally.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferLocalBillingAddressId_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that with a conflict in billing_address_id, we prefer an ID of a local
+// profile over an ID of a server profile. In this test, the preferred ID is in
+// the local data that we need to upstream.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferLocalBillingAddressId_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that if both addresses have billing address ids of local profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// remote entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfLocalIds_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kLocalAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if both addresses have billing address ids of local profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// local entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfLocalIds_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that if both addresses have billing address ids of server profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// remote entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if both addresses have billing address ids of server profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// local entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that the conflict resolution happens component-wise. To avoid
+// combinatorial explosion, this only tests when both have billing address ids
+// of server profiles, one entity is more recently used but the other entity has
+// a higher use_count. We should pick the billing_address_id of the newer one
+// but have the use_count updated to the maximum as well. In this test, the
+// remote entity is the more recently used.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_BothWin1) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_card)));
+}
+
+// Tests that the conflict resolution happens component-wise. To avoid
+// combinatorial explosion, this only tests when both have billing address ids
+// of server profiles, one entity is more recently used but the other entity has
+// a higher use_count. We should pick the billing_address_id of the newer one
+// but have the use_count updated to the maximum as well. In this test, the
+// local entity is the more recently used.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_BothWin2) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_card)));
+}
+
+// Tests that if the has_converted bit differs, we always end up with the true
+// value. This test has the remote entity converted which should get updated in
+// the local DB.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_RemoteWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile)));
+}
+
+// Tests that if the has_converted bit differs, we always end up with the true
+// value. This test has the local entity converted which should get upstreamed.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_LocalWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile)));
+}
+
+// Tests that the conflict resolution happens component-wise. If one entity
+// has_converted but the other entity has higher use_count, we should end up
+// with an entity that has_converted and has the higher use_count. This test has
+// the remote entity converted.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_BothWin1) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile)));
+}
+
+// Tests that the conflict resolution happens component-wise. If one entity
+// has_converted but the other entity has higher use_count, we should end up
+// with an entity that has_converted and has the higher use_count. This test has
+// the local entity converted.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_BothWin2) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile)));
+}
+
+INSTANTIATE_TEST_SUITE_P(,
+ AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ ::testing::Values(INITIAL_SYNC_ADD,
+ LATER_SYNC_ADD,
+ LATER_SYNC_UPDATE));
+
} // namespace autofill
+
+namespace sync_pb {
+
+// Makes the GMock matchers print out a readable version of the protobuf.
+void PrintTo(const WalletMetadataSpecifics& specifics, std::ostream* os) {
+ *os << autofill::WalletMetadataSpecificsAsDebugString(specifics);
+}
+
+} // namespace sync_pb
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
index 86fd8a07dff..7b88c1b8b36 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
@@ -511,8 +511,6 @@ syncer::SyncError AutofillWalletMetadataSyncableService::ProcessSyncChanges(
// get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " ProcessSyncChanges notify the PDM";
web_data_backend_->NotifyOfMultipleAutofillChanges();
ignore_multiple_changed_notification_ = false;
}
@@ -541,13 +539,9 @@ void AutofillWalletMetadataSyncableService::AutofillProfileChanged(
it->GetSpecifics().wallet_metadata();
const AutofillProfile& local = *change.data_model();
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " AutofillProfileChanged " << local;
if (!AreLocalUseStatsUpdated(remote, local) &&
!IsLocalHasConvertedStatusUpdated(remote, local)) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " Nothing has changed, not syncing up.";
return;
}
@@ -573,8 +567,11 @@ void AutofillWalletMetadataSyncableService::CreditCardChanged(
server_id, sync_pb::WalletMetadataSpecifics::CARD, &cache_);
if (it == cache_.end())
return;
- // Implicitly, we filter out ADD (not in cache) and REMOVE (!data_model()).
- DCHECK(change.type() == AutofillProfileChange::UPDATE);
+ // Deletions and creations are treated by Wallet data sync (and propagated
+ // here by AutofillMultipleChanged()). We only treat updates here.
+ if (change.type() != AutofillProfileChange::UPDATE) {
+ return;
+ }
const sync_pb::WalletMetadataSpecifics& remote =
it->GetSpecifics().wallet_metadata();
@@ -662,8 +659,6 @@ bool AutofillWalletMetadataSyncableService::GetLocalData(
bool AutofillWalletMetadataSyncableService::UpdateAddressStats(
const AutofillProfile& profile) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " Applying change from sync " << profile;
return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase())
->UpdateServerAddressMetadata(profile);
}
@@ -763,8 +758,6 @@ syncer::SyncMergeResult AutofillWalletMetadataSyncableService::MergeData(
// get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " MergeData notify the PDM";
web_data_backend_->NotifyOfMultipleAutofillChanges();
ignore_multiple_changed_notification_ = false;
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
index 8631ea78944..a3a4494ddb1 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -21,6 +21,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_util.h"
+#include "components/sync/base/data_type_histogram.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h"
@@ -253,8 +254,7 @@ bool AutofillWalletSyncBridge::SupportsIncrementalUpdates() const {
return false;
}
-AutofillWalletSyncBridge::StopSyncResponse
-AutofillWalletSyncBridge::ApplyStopSyncChanges(
+void AutofillWalletSyncBridge::ApplyStopSyncChanges(
std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list) {
// If a metadata change list gets passed in, that means sync is actually
// disabled, so we want to delete the payments data.
@@ -262,11 +262,25 @@ AutofillWalletSyncBridge::ApplyStopSyncChanges(
if (initial_sync_done_) {
active_callback_.Run(false);
}
+
+ // Report count of entities to delete. This use case should be pretty rare
+ // so it is okay to read it from DB again.
+ // TODO(crbug.com/853688): Remove when wallet data is launched on USS, incl.
+ // the helper function SyncWalletDataRecordClearedEntitiesCount().
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> cards;
+ std::unique_ptr<PaymentsCustomerData> customer_data;
+ if (GetAutofillTable()->GetServerProfiles(&profiles) &&
+ GetAutofillTable()->GetServerCreditCards(&cards) &&
+ GetAutofillTable()->GetPaymentsCustomerData(&customer_data)) {
+ int count = profiles.size() + cards.size() + (customer_data ? 1 : 0);
+ SyncWalletDataRecordClearedEntitiesCount(count);
+ }
+
SetSyncData(syncer::EntityChangeList());
initial_sync_done_ = false;
}
- return StopSyncResponse::kModelStillReadyToSync;
}
void AutofillWalletSyncBridge::GetAllDataForTesting(DataCallback callback) {
@@ -327,6 +341,13 @@ void AutofillWalletSyncBridge::SetSyncData(
wallet_data_changed |=
SetWalletAddresses(std::move(wallet_addresses), should_log_diff);
+ // Commit the transaction to make sure the data and the metadata with the
+ // new progress marker is written down (especially on Android where we
+ // cannot rely on commiting transactions on shutdown). We need to commit
+ // even if the wallet data has not changed because the model type state incl.
+ // the progress marker always changes.
+ web_data_backend_->CommitChanges();
+
if (web_data_backend_ && wallet_data_changed)
web_data_backend_->NotifyOfMultipleAutofillChanges();
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
index 17ea21c91bb..3f91a3c6276 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -66,9 +66,8 @@ class AutofillWalletSyncBridge : public base::SupportsUserData::Data,
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
bool SupportsIncrementalUpdates() const override;
- StopSyncResponse ApplyStopSyncChanges(
- std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list)
- override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
// Sends all Wallet Data to the |callback| and keeps all the strings in their
// original format (whereas GetAllDataForDebugging() has to make them UTF-8).
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
index 97c9520760b..9549f984cc4 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -369,7 +369,7 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
base::MockCallback<base::RepeatingCallback<void(bool)>>* active_callback() {
return &active_callback_;
- };
+ }
private:
autofill::TestAutofillClock test_clock_;
@@ -487,6 +487,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NewWalletAddressAndCard) {
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
AddChange(address2.server_id(), address2)));
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
@@ -533,6 +534,7 @@ TEST_P(AutofillWalletSyncBridgeTest,
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({profile_specifics, card_specifics, customer_data_specifics});
if (IsWalletMetadataOnUSS()) {
@@ -573,6 +575,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NewPaymentsCustomerData) {
&customer_data_specifics2);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
StartSyncing({profile_specifics, card_specifics, customer_data_specifics2});
@@ -596,6 +599,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NoWalletAddressOrCard) {
table()->SetServerCreditCards({local_card});
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(local_profile.server_id())));
EXPECT_CALL(*backend(),
@@ -636,6 +640,8 @@ TEST_P(AutofillWalletSyncBridgeTest,
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker on the client.
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
StartSyncing({profile_specifics, card_specifics, customer_data_specifics});
@@ -672,6 +678,7 @@ TEST_P(AutofillWalletSyncBridgeTest,
SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
&customer_data_specifics);
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(profile2.server_id())));
@@ -817,6 +824,7 @@ TEST_P(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_ClearAllData) {
CreditCard local_card = test::GetMaskedServerCard();
table()->SetServerCreditCards({local_card});
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(local_profile.server_id())));
@@ -846,6 +854,8 @@ TEST_P(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_KeepData) {
CreditCard local_card = test::GetMaskedServerCard();
table()->SetServerCreditCards({local_card});
+ // We do not write to DB at all, so we should not commit any changes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
@@ -884,8 +894,8 @@ TEST_P(AutofillWalletSyncBridgeTest, NotifiesWhenActivelySyncing) {
bridge()->ApplyStopSyncChanges(/*delete_metadata_change_list=*/nullptr);
}
-INSTANTIATE_TEST_CASE_P(USS,
- AutofillWalletSyncBridgeTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(USS,
+ AutofillWalletSyncBridgeTest,
+ ::testing::Values(false, true));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
index 43ff06e9619..aa37b89bc4d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
@@ -34,6 +34,12 @@ class AutofillWebDataBackend {
// Remove expired elements from the database and commit if needed.
virtual void RemoveExpiredFormElements() = 0;
+ // Commits the currently open transaction in the database. Should be only used
+ // by parties that talk directly to the database and not through the
+ // WebDatabase backend (notably Sync reacting to remote changes coming from
+ // the server).
+ virtual void CommitChanges() = 0;
+
// Notifies listeners on the DB sequence that an AutofillProfile has been
// added/removed/updated in the WebDatabase.
// NOTE: This method is intended to be called from the DB sequence. The UI
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index e69f6834bc4..d7cb6af4768 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -25,6 +25,12 @@ using base::Time;
namespace autofill {
+namespace {
+WebDatabase::State DoNothingAndCommit(WebDatabase* db) {
+ return WebDatabase::COMMIT_NEEDED;
+}
+} // namespace
+
AutofillWebDataBackendImpl::AutofillWebDataBackendImpl(
scoped_refptr<WebDatabaseBackend> web_database_backend,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
@@ -64,6 +70,10 @@ WebDatabase* AutofillWebDataBackendImpl::GetDatabase() {
return web_database_backend_->database();
}
+void AutofillWebDataBackendImpl::CommitChanges() {
+ web_database_backend_->ExecuteWriteTask(Bind(&DoNothingAndCommit));
+}
+
void AutofillWebDataBackendImpl::RemoveExpiredFormElements() {
web_database_backend_->ExecuteWriteTask(
Bind(&AutofillWebDataBackendImpl::RemoveExpiredFormElementsImpl, this));
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
index 9b4a5a2abb6..b508bda93b1 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
@@ -70,6 +70,7 @@ class AutofillWebDataBackendImpl
void NotifyOfCreditCardChanged(const CreditCardChange& change) override;
void NotifyOfMultipleAutofillChanges() override;
void NotifyThatSyncHasStarted(syncer::ModelType model_type) override;
+ void CommitChanges() override;
// TODO(crbug.com/920214): Deprecated, will be removed when
// autocomplete retention policy shipped. Replaced by
diff --git a/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h b/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
index 7b747246664..3368878abf0 100644
--- a/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
+++ b/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
@@ -27,6 +27,7 @@ class MockAutofillWebDataBackend : public AutofillWebDataBackend {
MOCK_METHOD1(RemoveObserver,
void(AutofillWebDataServiceObserverOnDBSequence* observer));
MOCK_METHOD0(RemoveExpiredFormElements, void());
+ MOCK_METHOD0(CommitChanges, void());
MOCK_METHOD1(NotifyOfAutofillProfileChanged,
void(const AutofillProfileChange& change));
MOCK_METHOD1(NotifyOfCreditCardChanged, void(const CreditCardChange& change));
diff --git a/chromium/components/autofill/core/common/autofill_features.cc b/chromium/components/autofill/core/common/autofill_features.cc
index fbe039a1880..72ad75881ad 100644
--- a/chromium/components/autofill/core/common/autofill_features.cc
+++ b/chromium/components/autofill/core/common/autofill_features.cc
@@ -67,6 +67,10 @@ const base::Feature kAutofillDeleteDisusedAddresses{
const base::Feature kAutofillDeleteDisusedCreditCards{
"AutofillDeleteDisusedCreditCards", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kAutofillDoNotUploadSaveUnsupportedCards{
+ "AutofillDoNotUploadSaveUnsupportedCards",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the credit card downstream keyboard accessory shows
// the Google Pay logo animation on iOS.
const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS{
@@ -96,6 +100,12 @@ const base::Feature kAutofillEnableCompanyName{
const base::Feature kAutofillEnableIFrameSupportOniOS{
"AutofillEnableIFrameSupportOniOS", base::FEATURE_ENABLED_BY_DEFAULT};
+// When enabled, enable local card migration flow for user who has signed in but
+// has not turned on sync.
+const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser{
+ "AutofillEnableLocalCardMigrationForNonSyncUser",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// When enabled, no local copy of server card will be saved when upload
// succeeds.
const base::Feature kAutofillNoLocalSaveOnUploadSuccess{
@@ -147,6 +157,12 @@ const base::Feature kAutofillLocalCardMigrationShowFeedback{
"AutofillLocalCardMigrationShowFeedback",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether offering to migrate cards will consider data from the
+// Autofill strike database (new version).
+const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2{
+ "AutofillLocalCardMigrationUsesStrikeSystemV2",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the manual fallback will be present.
const base::Feature kAutofillManualFallback{"AutofillManualFallback",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -166,6 +182,11 @@ const base::Feature kAutofillPreferServerNamePredictions{
const base::Feature kAutofillPrefilledFields{"AutofillPrefilledFields",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Controls whether Autofill uses server-side validation to ensure that fields
+// with invalid data are not suggested.
+const base::Feature kAutofillProfileServerValidation{
+ "AutofillProfileServerValidation", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether or not a group of fields not enclosed in a form can be
// considered a form. If this is enabled, unowned fields will only constitute
// a form if there are signals to suggest that this might a checkout page.
@@ -249,6 +270,11 @@ const base::Feature kAutofillShowAutocompleteConsoleWarnings{
"AutofillShowAutocompleteConsoleWarnings",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether suggestions' labels use the full disclosure format to
+// display disambiguation information.
+const base::Feature kAutofillShowFullDisclosureLabel{
+ "AutofillShowFullDisclosureLabel", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls attaching the autofill type predictions to their respective
// element in the DOM.
const base::Feature kAutofillShowTypePredictions{
@@ -259,9 +285,6 @@ const base::Feature kAutofillShowTypePredictions{
const base::Feature kAutofillSkipComparingInferredLabels{
"AutofillSkipComparingInferredLabels", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kAutofillSuggestInvalidProfileData{
- "AutofillSuggestInvalidProfileData", base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kAutofillSuppressDisusedAddresses{
"AutofillSuppressDisusedAddresses", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -271,6 +294,11 @@ const base::Feature kAutofillProfileClientValidation{
const base::Feature kAutofillSuppressDisusedCreditCards{
"AutofillSuppressDisusedCreditCards", base::FEATURE_ENABLED_BY_DEFAULT};
+// Controls whether Autofill should search prefixes of all words/tokens when
+// filtering profiles, or only on prefixes of the whole string.
+const base::Feature kAutofillTokenPrefixMatching{
+ "AutofillTokenPrefixMatching", base::FEATURE_DISABLED_BY_DEFAULT};
+
const base::Feature kAutofillUploadThrottling{"AutofillUploadThrottling",
base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromium/components/autofill/core/common/autofill_features.h b/chromium/components/autofill/core/common/autofill_features.h
index 01e901d9043..cd7525fce26 100644
--- a/chromium/components/autofill/core/common/autofill_features.h
+++ b/chromium/components/autofill/core/common/autofill_features.h
@@ -33,12 +33,14 @@ extern const base::Feature kAutofillCreditCardAssist;
extern const base::Feature kAutofillCreditCardLocalCardMigration;
extern const base::Feature kAutofillDeleteDisusedAddresses;
extern const base::Feature kAutofillDeleteDisusedCreditCards;
+extern const base::Feature kAutofillDoNotUploadSaveUnsupportedCards;
extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS;
extern const base::Feature kAutofillDynamicForms;
extern const base::Feature kAutofillEnableAccountWalletStorage;
extern const base::Feature kAutofillEnableAccountWalletStorageUpload;
extern const base::Feature kAutofillEnableCompanyName;
extern const base::Feature kAutofillEnableIFrameSupportOniOS;
+extern const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
@@ -46,13 +48,15 @@ extern const base::Feature kAutofillGetPaymentsIdentityFromSync;
extern const base::Feature kAutofillImportNonFocusableCreditCardForms;
extern const base::Feature kAutofillKeyboardAccessory;
extern const base::Feature kAutofillLocalCardMigrationShowFeedback;
+extern const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2;
extern const base::Feature kAutofillManualFallback;
extern const base::Feature kAutofillManualFallbackPhaseTwo;
extern const base::Feature kAutofillMetadataUploads;
-extern const base::Feature kAutofillPreferServerNamePredictions;
extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess;
extern const base::Feature kAutofillOverrideWithRaterConsensus;
+extern const base::Feature kAutofillPreferServerNamePredictions;
extern const base::Feature kAutofillPrefilledFields;
+extern const base::Feature kAutofillProfileServerValidation;
extern const base::Feature kAutofillRestrictUnownedFieldsToFormlessCheckout;
extern const base::Feature kAutofillRichMetadataQueries;
extern const base::Feature kAutofillSaveCardDialogUnlabeledExpirationDate;
@@ -67,11 +71,12 @@ extern const base::Feature kAutofillServerCommunication;
extern const base::Feature kAutofillSettingsCardTypeSplit;
extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms;
extern const base::Feature kAutofillShowAutocompleteConsoleWarnings;
+extern const base::Feature kAutofillShowFullDisclosureLabel;
extern const base::Feature kAutofillShowTypePredictions;
extern const base::Feature kAutofillSkipComparingInferredLabels;
-extern const base::Feature kAutofillSuggestInvalidProfileData;
extern const base::Feature kAutofillSuppressDisusedAddresses;
extern const base::Feature kAutofillSuppressDisusedCreditCards;
+extern const base::Feature kAutofillTokenPrefixMatching;
extern const base::Feature kAutofillUploadThrottling;
extern const base::Feature kAutofillUpstream;
extern const base::Feature kAutofillUpstreamAllowAllEmailDomains;
diff --git a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
index 1a9e4e0558e..9ce7a569f66 100644
--- a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
@@ -195,7 +195,8 @@ TEST_F(AutofillPrefsTest, WalletSyncTransportPref_CanBeSetAndReadFromJSON) {
std::string output_js;
EXPECT_TRUE(base::JSONWriter::Write(*dictionary, &output_js));
EXPECT_TRUE(dictionary->Equals(
- base::DictionaryValue::From(base::JSONReader::Read(output_js)).get()));
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(output_js))
+ .get()));
}
} // namespace prefs
diff --git a/chromium/components/autofill/core/common/autofill_regex_constants.cc b/chromium/components/autofill/core/common/autofill_regex_constants.cc
index d861aa9ea87..c8f46238fe1 100644
--- a/chromium/components/autofill/core/common/autofill_regex_constants.cc
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.cc
@@ -21,15 +21,15 @@ const char kRegionIgnoredRe[] =
const char kAddressNameIgnoredRe[] = "address.*nickname|address.*label";
const char kCompanyRe[] =
"company|business|organization|organisation"
- "|firma|firmenname" // de-DE
- "|empresa" // es
- "|societe|société" // fr-FR
- "|ragione.?sociale" // it-IT
- "|会社" // ja-JP
- "|название.?компании" // ru
- "|单位|公司" // zh-CN
- "|شرکت" // fa
- "|회사|직장"; // ko-KR
+ "|(?<!con)firma|firmenname" // de-DE
+ "|empresa" // es
+ "|societe|société" // fr-FR
+ "|ragione.?sociale" // it-IT
+ "|会社" // ja-JP
+ "|название.?компании" // ru
+ "|单位|公司" // zh-CN
+ "|شرکت" // fa
+ "|회사|직장"; // ko-KR
const char kAddressLine1Re[] =
"^address$|address[_-]?line(one)?|address1|addr1|street"
"|(?:shipping|billing)address$"
@@ -79,11 +79,11 @@ const char kAddressLinesExtraRe[] =
const char kAddressLookupRe[] = "lookup";
const char kCountryRe[] =
"country|countries"
- "|país|pais" // es
- "|国" // ja-JP
- "|国家" // zh-CN
- "|국가|나라" // ko-KR
- "|کشور"; // fa
+ "|país|pais" // es
+ "|(?<!(入|出))国" // ja-JP
+ "|国家" // zh-CN
+ "|국가|나라" // ko-KR
+ "|کشور"; // fa
const char kCountryLocationRe[] = "location";
const char kZipCodeRe[] =
"zip|postal|post.*code|pcode"
@@ -144,6 +144,15 @@ const char kSearchTermRe[] =
"|искать|найти|поиск"; // ru
/////////////////////////////////////////////////////////////////////////////
+// field_price.cc
+/////////////////////////////////////////////////////////////////////////////
+const char kPriceRe[] =
+ "\\bprice\\b|\\brate\\b|\\bcost\\b"
+ "قیمة‎|سعر‎" // ar
+ "قیمت" // fa
+ "|\\bprix\\b|\\bcoût\\b|\\bcout\\b|\\btarif\\b"; // fr-CA
+
+/////////////////////////////////////////////////////////////////////////////
// credit_card_field.cc
/////////////////////////////////////////////////////////////////////////////
const char kNameOnCardRe[] =
@@ -243,6 +252,7 @@ const char kDebitCardRe[] = "debit.*card";
const char kEmailRe[] =
"e.?mail"
"|courriel" // fr
+ "|correo.*electr(o|ó)nico" // es-ES
"|メールアドレス" // ja-JP
"|Электронной.?Почты" // ru
"|邮件|邮箱" // zh-CN
@@ -262,7 +272,7 @@ const char kNameRe[] =
"^name|full.?name|your.?name|customer.?name|bill.?name|ship.?name"
"|name.*first.*last|firstandlastname"
"|nombre.*y.*apellidos" // es
- "|^nom" // fr-FR
+ "|^nom(?!bre)" // fr-FR
"|お名前|氏名" // ja-JP
"|^nome" // pt-BR, pt-PT
"|نام.*نام.*خانوادگی" // fa
@@ -286,11 +296,15 @@ const char kMiddleInitialRe[] = "middle.*initial|m\\.i\\.|mi$|\\bmi\\b";
const char kMiddleNameRe[] =
"middle.*name|mname|middle$"
"|apellido.?materno|lastlastname"; // es
+
+// TODO(crbug.com/928851): Revisit "morada" from pt-PT as it means address and
+// not "last name", and "surename" in pt-PT as it's not Portuguese (or any
+// language?).
const char kLastNameRe[] =
"last.*name|lname|surname|last$|secondname|family.*name"
"|nachname" // de-DE
- "|apellido" // es
- "|famille|^nom" // fr-FR
+ "|apellidos?" // es
+ "|famille|^nom(?!bre)" // fr-FR
"|cognome" // it-IT
"|姓" // ja-JP
"|morada|apelidos|surename|sobrenome" // pt-BR, pt-PT
@@ -329,6 +343,28 @@ const char kPhoneExtensionRe[] =
"|ramal"; // pt-BR, pt-PT
/////////////////////////////////////////////////////////////////////////////
+// travel_field.cc
+/////////////////////////////////////////////////////////////////////////////
+
+const char kPassportRe[] =
+ "document.*number|passport" // en-US
+ "|passeport" // fr-FR
+ "|numero.*documento|pasaporte" // es-ES
+ "|書類"; // ja-JP
+const char kTravelOriginRe[] =
+ "point.*of.*entry|arrival" // en-US
+ "|punto.*internaci(o|ó)n|fecha.*llegada" // es-ES
+ "|入国"; // ja-JP
+const char kTravelDestinationRe[] =
+ "departure" // en-US
+ "|fecha.*salida|destino" // es-ES
+ "|出国"; // ja-JP
+const char kFlightRe[] =
+ "airline|flight" // en-US
+ "|aerol(i|í)nea|n(u|ú)mero.*vuelo" // es-ES
+ "|便名|航空会社"; // ja-JP
+
+/////////////////////////////////////////////////////////////////////////////
// validation.cc
/////////////////////////////////////////////////////////////////////////////
const char kUPIVirtualPaymentAddressRe[] =
diff --git a/chromium/components/autofill/core/common/autofill_regex_constants.h b/chromium/components/autofill/core/common/autofill_regex_constants.h
index bcb18d1cda8..870a800c58f 100644
--- a/chromium/components/autofill/core/common/autofill_regex_constants.h
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.h
@@ -56,6 +56,11 @@ extern const char kPhonePrefixRe[];
extern const char kPhoneSuffixRe[];
extern const char kPhoneExtensionRe[];
extern const char kSearchTermRe[];
+extern const char kPassportRe[];
+extern const char kTravelOriginRe[];
+extern const char kTravelDestinationRe[];
+extern const char kFlightRe[];
+extern const char kPriceRe[];
// Used to match field data that might be a UPI Virtual Payment Address.
// See:
diff --git a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
index 4b0820d5f2a..4201bceef30 100644
--- a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
@@ -32,23 +32,23 @@ struct InputPatternTestCase {
ASCIIToUTF16(test_case.pattern)));
}
- INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- PositiveSampleTest,
- testing::Values(
- // Empty pattern
- InputPatternTestCase{"", ""},
- InputPatternTestCase{
- "Look, ma' -- a non-empty string!", ""},
- // Substring
- InputPatternTestCase{"string", "tri"},
- // Substring at beginning
- InputPatternTestCase{"string", "str"},
- InputPatternTestCase{"string", "^str"},
- // Substring at end
- InputPatternTestCase{"string", "ring"},
- InputPatternTestCase{"string", "ring$"},
- // Case-insensitive
- InputPatternTestCase{"StRiNg", "string"}));
+ INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ PositiveSampleTest,
+ testing::Values(
+ // Empty pattern
+ InputPatternTestCase{"", ""},
+ InputPatternTestCase{
+ "Look, ma' -- a non-empty string!", ""},
+ // Substring
+ InputPatternTestCase{"string", "tri"},
+ // Substring at beginning
+ InputPatternTestCase{"string", "str"},
+ InputPatternTestCase{"string", "^str"},
+ // Substring at end
+ InputPatternTestCase{"string", "ring"},
+ InputPatternTestCase{"string", "ring$"},
+ // Case-insensitive
+ InputPatternTestCase{"StRiNg", "string"}));
class NegativeSampleTest
: public testing::TestWithParam<InputPatternTestCase> {};
@@ -61,20 +61,20 @@ struct InputPatternTestCase {
ASCIIToUTF16(test_case.pattern)));
}
-INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- NegativeSampleTest,
- testing::Values(
- // Empty string
- InputPatternTestCase{
- "", "Look, ma' -- a non-empty pattern!"},
- // Substring
- InputPatternTestCase{"string", "trn"},
- // Substring at beginning
- InputPatternTestCase{"string", " str"},
- InputPatternTestCase{"string", "^tri"},
- // Substring at end
- InputPatternTestCase{"string", "ring "},
- InputPatternTestCase{"string", "rin$"}));
+INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ NegativeSampleTest,
+ testing::Values(
+ // Empty string
+ InputPatternTestCase{
+ "", "Look, ma' -- a non-empty pattern!"},
+ // Substring
+ InputPatternTestCase{"string", "trn"},
+ // Substring at beginning
+ InputPatternTestCase{"string", " str"},
+ InputPatternTestCase{"string", "^tri"},
+ // Substring at end
+ InputPatternTestCase{"string", "ring "},
+ InputPatternTestCase{"string", "rin$"}));
struct InputTestCase {
const char* const input;
@@ -90,7 +90,7 @@ struct InputTestCase {
EXPECT_TRUE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate2DigitYearPositive,
testing::Values(InputTestCase{"mm / yy"},
@@ -124,7 +124,7 @@ struct InputTestCase {
EXPECT_FALSE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate2DigitYearNegative,
testing::Values(InputTestCase{""},
@@ -164,30 +164,30 @@ struct InputTestCase {
EXPECT_TRUE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- ExpirationDate4DigitYearPositive,
- testing::Values(
- // Simple four year cases
- InputTestCase{"mm / yyyy"},
- InputTestCase{"mm/ yyyy"},
- InputTestCase{"mm /yyyy"},
- InputTestCase{"mm/yyyy"},
- InputTestCase{"mm - yyyy"},
- InputTestCase{"mm- yyyy"},
- InputTestCase{"mm -yyyy"},
- InputTestCase{"mm-yyyy"},
- InputTestCase{"mmyyyy"},
- // Complex four year cases
- InputTestCase{"Expiration Date (MM / YYYY)"},
- InputTestCase{"Expiration Date (MM/YYYY)"},
- InputTestCase{"Expiration Date (MM - YYYY)"},
- InputTestCase{"Expiration Date (MM-YYYY)"},
- InputTestCase{"Expiration Date MM / YYYY"},
- InputTestCase{"Expiration Date MM/YYYY"},
- InputTestCase{"Expiration Date MM - YYYY"},
- InputTestCase{"Expiration Date MM-YYYY"},
- InputTestCase{"expiration date yyyy"},
- InputTestCase{"Exp Date (MM / YYYY)"}));
+ INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ ExpirationDate4DigitYearPositive,
+ testing::Values(
+ // Simple four year cases
+ InputTestCase{"mm / yyyy"},
+ InputTestCase{"mm/ yyyy"},
+ InputTestCase{"mm /yyyy"},
+ InputTestCase{"mm/yyyy"},
+ InputTestCase{"mm - yyyy"},
+ InputTestCase{"mm- yyyy"},
+ InputTestCase{"mm -yyyy"},
+ InputTestCase{"mm-yyyy"},
+ InputTestCase{"mmyyyy"},
+ // Complex four year cases
+ InputTestCase{"Expiration Date (MM / YYYY)"},
+ InputTestCase{"Expiration Date (MM/YYYY)"},
+ InputTestCase{"Expiration Date (MM - YYYY)"},
+ InputTestCase{"Expiration Date (MM-YYYY)"},
+ InputTestCase{"Expiration Date MM / YYYY"},
+ InputTestCase{"Expiration Date MM/YYYY"},
+ InputTestCase{"Expiration Date MM - YYYY"},
+ InputTestCase{"Expiration Date MM-YYYY"},
+ InputTestCase{"expiration date yyyy"},
+ InputTestCase{"Exp Date (MM / YYYY)"}));
class ExpirationDate4DigitYearNegative
: public testing::TestWithParam<InputTestCase> {};
@@ -199,7 +199,7 @@ struct InputTestCase {
EXPECT_FALSE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate4DigitYearNegative,
testing::Values(InputTestCase{""},
diff --git a/chromium/components/autofill/core/common/autofill_switches.cc b/chromium/components/autofill/core/common/autofill_switches.cc
index 4bb9f632105..cf0334180cf 100644
--- a/chromium/components/autofill/core/common/autofill_switches.cc
+++ b/chromium/components/autofill/core/common/autofill_switches.cc
@@ -22,6 +22,11 @@ const char kAutofillServerURL[] = "autofill-server-url";
const char kAutofillMetadataUploadEncoding[] =
"autofill-metadata-upload-encoding";
+// The number of days after which to reset the registry of autofill events for
+// which an upload has been sent.
+const char kAutofillUploadThrottlingPeriodInDays[] =
+ "autofill-upload-throttling-period-in-days";
+
// Force hiding the local save checkbox in the autofill dialog box for getting
// the full credit card number for a wallet card. The card will never be stored
// locally.
@@ -33,10 +38,6 @@ const char kDisableOfferStoreUnmaskedWalletCards[] =
const char kEnableOfferStoreUnmaskedWalletCards[] =
"enable-offer-store-unmasked-wallet-cards";
-// Enables suggestions with substring matching instead of prefix matching.
-const char kEnableSuggestionsWithSubstringMatch[] =
- "enable-suggestions-with-substring-match";
-
// Ignores autocomplete="off" for Autofill data (profiles + credit cards).
const char kIgnoreAutocompleteOffForAutofill[] =
"ignore-autocomplete-off-autofill";
@@ -48,7 +49,7 @@ const char kShowAutofillTypePredictions[] = "show-autofill-type-predictions";
const char kShowAutofillSignatures[] = "show-autofill-signatures";
// Use the sandbox Online Wallet service URL (for developer testing).
-const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox";
+const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox";
} // namespace switches
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/autofill_switches.h b/chromium/components/autofill/core/common/autofill_switches.h
index 2f58a2d51a7..0e6bffefcc7 100644
--- a/chromium/components/autofill/core/common/autofill_switches.h
+++ b/chromium/components/autofill/core/common/autofill_switches.h
@@ -15,9 +15,9 @@ namespace switches {
extern const char kAutofillAPIKey[];
extern const char kAutofillServerURL[];
extern const char kAutofillMetadataUploadEncoding[];
+extern const char kAutofillUploadThrottlingPeriodInDays[];
extern const char kDisableOfferStoreUnmaskedWalletCards[];
extern const char kEnableOfferStoreUnmaskedWalletCards[];
-extern const char kEnableSuggestionsWithSubstringMatch[];
extern const char kIgnoreAutocompleteOffForAutofill[];
extern const char kShowAutofillTypePredictions[];
extern const char kShowAutofillSignatures[];
diff --git a/chromium/components/autofill/core/common/autofill_util.cc b/chromium/components/autofill/core/common/autofill_util.cc
index 0191e664fe3..adf79a52ee2 100644
--- a/chromium/components/autofill/core/common/autofill_util.cc
+++ b/chromium/components/autofill/core/common/autofill_util.cc
@@ -51,8 +51,7 @@ struct Compare : base::CaseInsensitiveCompareASCII<Char> {
} // namespace
bool IsFeatureSubstringMatchEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ return base::FeatureList::IsEnabled(features::kAutofillTokenPrefixMatching);
}
bool IsShowAutofillSignaturesEnabled() {
diff --git a/chromium/components/autofill/core/common/autofill_util_unittest.cc b/chromium/components/autofill/core/common/autofill_util_unittest.cc
index 6a59b0d618f..4f1430a88bd 100644
--- a/chromium/components/autofill/core/common/autofill_util_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_util_unittest.cc
@@ -9,7 +9,8 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/common/autofill_switches.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
@@ -27,14 +28,19 @@ class FieldIsTokenBoundarySubstringCaseTest
TEST_P(FieldIsTokenBoundarySubstringCaseTest,
FieldIsSuggestionSubstringStartingOnTokenBoundary) {
- // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet
- // without a flag.
- EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary(
- base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false));
+ {
+ base::test::ScopedFeatureList features_disabled;
+ features_disabled.InitAndDisableFeature(
+ features::kAutofillTokenPrefixMatching);
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet
+ // without a flag.
+ EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary(
+ base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false));
+ }
+
+ base::test::ScopedFeatureList features_enabled;
+ features_enabled.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
auto test_case = GetParam();
SCOPED_TRACE(testing::Message()
@@ -49,7 +55,7 @@ TEST_P(FieldIsTokenBoundarySubstringCaseTest,
test_case.case_sensitive));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
FieldIsTokenBoundarySubstringCaseTest,
testing::Values(
@@ -91,7 +97,7 @@ TEST_P(PrefixEndingOnTokenBoundaryTest, IsPrefixOfEmailEndingWithAtSign) {
base::ASCIIToUTF16(test_case.field_contents)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
PrefixEndingOnTokenBoundaryTest,
testing::Values(AtSignPrefixCase{"ab@cd.b", "a", false},
@@ -136,7 +142,7 @@ TEST_P(GetTextSelectionStartTest, GetTextSelectionStart) {
test_case.case_sensitive));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
GetTextSelectionStartTest,
testing::Values(
@@ -172,7 +178,7 @@ TEST_P(LowercaseAndTokenizeAttributeStringTest,
LowercaseAndTokenizeAttributeString(test_case.attribute));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
LowercaseAndTokenizeAttributeStringTest,
testing::Values(
diff --git a/chromium/components/autofill/core/common/form_field_data.h b/chromium/components/autofill/core/common/form_field_data.h
index 8b67278ba80..cfe44ba6eaa 100644
--- a/chromium/components/autofill/core/common/form_field_data.h
+++ b/chromium/components/autofill/core/common/form_field_data.h
@@ -108,7 +108,7 @@ struct FormFieldData {
// Returns true if the field is visible to the user.
bool IsVisible() const {
return is_focusable && role != ROLE_ATTRIBUTE_PRESENTATION;
- };
+ }
// Note: operator==() performs a full-field-comparison(byte by byte), this is
// different from SameFieldAs(), which ignores comparison for those "values"
diff --git a/chromium/components/autofill/core/common/password_generation_util.cc b/chromium/components/autofill/core/common/password_generation_util.cc
index c040a3ea40a..1e5af2bafc9 100644
--- a/chromium/components/autofill/core/common/password_generation_util.cc
+++ b/chromium/components/autofill/core/common/password_generation_util.cc
@@ -13,15 +13,6 @@
namespace autofill {
namespace password_generation {
-PasswordGenerationActions::PasswordGenerationActions()
- : learn_more_visited(false),
- password_accepted(false),
- password_edited(false),
- password_regenerated(false) {
-}
-
-PasswordGenerationActions::~PasswordGenerationActions() {
-}
PasswordGenerationUIData::PasswordGenerationUIData(
const gfx::RectF& bounds,
@@ -39,20 +30,6 @@ PasswordGenerationUIData::PasswordGenerationUIData() = default;
PasswordGenerationUIData::~PasswordGenerationUIData() = default;
-void LogUserActions(PasswordGenerationActions actions) {
- UserAction action = IGNORE_FEATURE;
- if (actions.password_accepted) {
- if (actions.password_edited)
- action = ACCEPT_AFTER_EDITING;
- else
- action = ACCEPT_ORIGINAL_PASSWORD;
- } else if (actions.learn_more_visited) {
- action = LEARN_MORE;
- }
- UMA_HISTOGRAM_ENUMERATION("PasswordGeneration.UserActions",
- action, ACTION_ENUM_COUNT);
-}
-
void LogPasswordGenerationEvent(PasswordGenerationEvent event) {
UMA_HISTOGRAM_ENUMERATION("PasswordGeneration.Event",
event, EVENT_ENUM_COUNT);
diff --git a/chromium/components/autofill/core/common/password_generation_util.h b/chromium/components/autofill/core/common/password_generation_util.h
index fa350e93110..b84433a5b21 100644
--- a/chromium/components/autofill/core/common/password_generation_util.h
+++ b/chromium/components/autofill/core/common/password_generation_util.h
@@ -124,33 +124,8 @@ struct PasswordGenerationUIData {
autofill::PasswordForm password_form;
};
-void LogUserActions(PasswordGenerationActions actions);
-
void LogPasswordGenerationEvent(PasswordGenerationEvent event);
-// Enumerates user actions after password generation bubble is shown.
-// These are visible for testing purposes.
-enum UserAction {
- // User closes the bubble without any meaningful actions (e.g. use backspace
- // key, close the bubble, click outside the bubble, etc).
- IGNORE_FEATURE,
-
- // User navigates to the learn more page. Note that in the current
- // implementation this will result in closing the bubble so this action
- // doesn't overlap with the following two actions.
- LEARN_MORE,
-
- // User accepts the generated password without manually editing it (but
- // including changing it through the regenerate button).
- ACCEPT_ORIGINAL_PASSWORD,
-
- // User accepts the gererated password after manually editing it.
- ACCEPT_AFTER_EDITING,
-
- // Number of enum entries, used for UMA histogram reporting macros.
- ACTION_ENUM_COUNT
-};
-
// Returns true if Password Generation is enabled according to the field
// trial result and the flags.
bool IsPasswordGenerationEnabled();
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.cc b/chromium/components/autofill/core/common/save_password_progress_logger.cc
index de254813971..266a8303a5e 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.cc
@@ -18,7 +18,7 @@
using base::checked_cast;
using base::DictionaryValue;
-using base::UintToString;
+using base::NumberToString;
using base::Value;
namespace autofill {
@@ -72,19 +72,19 @@ void SavePasswordProgressLogger::LogPasswordForm(
ScrubElementID(form.username_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_USERNAME_ELEMENT_RENDERER_ID),
- UintToString(form.username_element_renderer_id));
+ NumberToString(form.username_element_renderer_id));
}
log.SetString(GetStringFromID(STRING_PASSWORD_ELEMENT),
ScrubElementID(form.password_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.password_element_renderer_id));
+ NumberToString(form.password_element_renderer_id));
}
log.SetString(GetStringFromID(STRING_NEW_PASSWORD_ELEMENT),
ScrubElementID(form.new_password_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_NEW_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.new_password_element_renderer_id));
+ NumberToString(form.new_password_element_renderer_id));
}
if (!form.confirmation_password_element.empty()) {
log.SetString(GetStringFromID(STRING_CONFIRMATION_PASSWORD_ELEMENT),
@@ -92,7 +92,7 @@ void SavePasswordProgressLogger::LogPasswordForm(
if (form.has_renderer_ids) {
log.SetString(
GetStringFromID(STRING_CONFIRMATION_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.confirmation_password_element_renderer_id));
+ NumberToString(form.confirmation_password_element_renderer_id));
}
}
log.SetBoolean(GetStringFromID(STRING_PASSWORD_GENERATED),
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc b/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
index a20d11946af..325873f2750 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
@@ -40,7 +40,7 @@ class TestLogger : public SavePasswordProgressLogger {
std::string accumulated_log_;
};
-}; // namespace
+} // namespace
TEST(SavePasswordProgressLoggerTest, LogPasswordForm) {
TestLogger logger;
diff --git a/chromium/components/autofill/ios/browser/autofill_agent.mm b/chromium/components/autofill/ios/browser/autofill_agent.mm
index eb8bf0dd088..d6de84b5ce7 100644
--- a/chromium/components/autofill/ios/browser/autofill_agent.mm
+++ b/chromium/components/autofill/ios/browser/autofill_agent.mm
@@ -538,7 +538,7 @@ autofillManagerFromWebState:(web::WebState*)webState
FormSuggestion* suggestion = [FormSuggestion
suggestionWithValue:value
displayDescription:displayDescription
- icon:base::SysUTF16ToNSString(popup_suggestion.icon)
+ icon:base::SysUTF8ToNSString(popup_suggestion.icon)
identifier:popup_suggestion.frontend_id];
// Put "clear form" entry at the front of the suggestions. If
diff --git a/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h b/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
index d99ed3ec9fe..3265d09b7fe 100644
--- a/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
+++ b/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
@@ -12,7 +12,7 @@
namespace autofill {
class AutofillPopupDelegate;
struct Suggestion;
-};
+}
// Interface used to pipe events from AutofillClientIOS to the embedder.
@protocol AutofillClientIOSBridge
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.h b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
index f460f3f12c7..5e9408dbb98 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
@@ -65,7 +65,7 @@ class AutofillDriverIOS : public AutofillDriver {
const gfx::RectF& bounding_box) override;
bool is_processed() const { return processed_; }
- void set_processed(bool processed) { processed_ = processed; };
+ void set_processed(bool processed) { processed_ = processed; }
protected:
AutofillDriverIOS(
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
index ce08c746ecd..214164a003d 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -107,7 +107,7 @@ void AutofillDriverIOS::SendFormDataToRenderer(
void AutofillDriverIOS::PropagateAutofillPredictions(
const std::vector<autofill::FormStructure*>& forms) {
autofill_manager_.client()->PropagateAutofillPredictions(nullptr, forms);
-};
+}
void AutofillDriverIOS::SendAutofillTypePredictionsToRenderer(
const std::vector<FormStructure*>& forms) {
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
index 56a6630190e..005468fb616 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
@@ -47,11 +47,14 @@ class AutofillDriverIOSWebFrameFactory
web::WebFrame* web_frame);
private:
+ friend class web::WebStateUserData<AutofillDriverIOSWebFrameFactory>;
+
web::WebState* web_state_ = nullptr;
AutofillClient* client_ = nullptr;
id<AutofillDriverIOSBridge> bridge_ = nil;
std::string app_locale_;
AutofillManager::AutofillDownloadManagerState enable_download_manager_;
+ WEB_STATE_USER_DATA_KEY_DECL();
};
// AutofillDriverIOSWebFrame will keep a refcountable AutofillDriverIOS. This is
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
index 2c4988db611..cc3c6d6e7a4 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
@@ -4,7 +4,7 @@
#include "components/autofill/ios/browser/autofill_driver_ios_webframe.h"
-#include "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state.h"
namespace autofill {
@@ -101,4 +101,6 @@ AutofillDriverIOSWebFrame::GetRetainableDriver() {
return driver_;
}
+WEB_STATE_USER_DATA_KEY_IMPL(AutofillDriverIOSWebFrameFactory)
+
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
index 7e3dabd4c62..0da71bf0bce 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
@@ -34,6 +34,7 @@ class AutofillDriverIOSWebState
id<AutofillDriverIOSBridge> bridge,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager);
+ WEB_STATE_USER_DATA_KEY_DECL();
};
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
index 0237ae17128..723b4b97f39 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
@@ -4,7 +4,7 @@
#include "components/autofill/ios/browser/autofill_driver_ios_webstate.h"
-#include "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
@@ -43,4 +43,6 @@ AutofillDriverIOSWebState::AutofillDriverIOSWebState(
AutofillDriverIOSWebState::~AutofillDriverIOSWebState() {}
+WEB_STATE_USER_DATA_KEY_IMPL(AutofillDriverIOSWebState)
+
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_util.mm b/chromium/components/autofill/ios/browser/autofill_util.mm
index 673b520ecf9..208e29c433a 100644
--- a/chromium/components/autofill/ios/browser/autofill_util.mm
+++ b/chromium/components/autofill/ios/browser/autofill_util.mm
@@ -54,9 +54,10 @@ std::unique_ptr<base::Value> ParseJson(NSString* json_string) {
// Convert JSON string to JSON object |JSONValue|.
int error_code = 0;
std::string error_message;
- std::unique_ptr<base::Value> json_value(base::JSONReader::ReadAndReturnError(
- base::SysNSStringToUTF8(json_string), base::JSON_PARSE_RFC, &error_code,
- &error_message));
+ std::unique_ptr<base::Value> json_value(
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ base::SysNSStringToUTF8(json_string), base::JSON_PARSE_RFC,
+ &error_code, &error_message));
if (error_code)
return nullptr;
diff --git a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
index 4b6c3f2e814..39f77b5c090 100644
--- a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
+++ b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/format_macros.h"
#include "base/json/string_escape.h"
diff --git a/chromium/components/autofill/ios/browser/resources/autofill_controller.js b/chromium/components/autofill/ios/browser/resources/autofill_controller.js
index ec5477b5d45..2172b64182e 100644
--- a/chromium/components/autofill/ios/browser/resources/autofill_controller.js
+++ b/chromium/components/autofill/ios/browser/resources/autofill_controller.js
@@ -256,7 +256,7 @@ __gCrWeb.autofill['fillForm'] = function(data, forceFillFieldIdentifier) {
if (!__gCrWeb.autofill.styleInjected) {
var style = document.createElement('style');
style.textContent = '[chrome-autofilled] {' +
- 'background-color:#FAFFBD !important;' +
+ 'background-color:#E8F0FE !important;' +
'background-image:none !important;' +
'color:#000000 !important;' +
'}';
diff --git a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
index 3af1db68bab..714fc282c4d 100644
--- a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
+++ b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
@@ -33,6 +33,7 @@ class FormActivityTabHelper
private:
friend class web::WebStateUserData<FormActivityTabHelper>;
+
// TestFormActivityTabHelper can be used by tests that want to simulate form
// events without loading page and executing JavaScript.
// To trigger events, TestFormActivityTabHelper will access |observer_|.
@@ -69,6 +70,8 @@ class FormActivityTabHelper
// The observers.
base::ObserverList<FormActivityObserver>::Unchecked observers_;
+ WEB_STATE_USER_DATA_KEY_DECL();
+
DISALLOW_COPY_AND_ASSIGN(FormActivityTabHelper);
};
diff --git a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
index ed04da751eb..ba38e373c5b 100644
--- a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
+++ b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
@@ -6,6 +6,7 @@
#import <Foundation/Foundation.h>
+#include "base/bind.h"
#include "base/values.h"
#include "components/autofill/ios/form_util/form_activity_observer.h"
#include "components/autofill/ios/form_util/form_activity_params.h"
@@ -144,4 +145,6 @@ void FormActivityTabHelper::WebStateDestroyed(web::WebState* web_state) {
web_state_ = nullptr;
}
+WEB_STATE_USER_DATA_KEY_IMPL(FormActivityTabHelper)
+
} // namespace autofill
diff --git a/chromium/components/autofill_assistant/OWNERS b/chromium/components/autofill_assistant/OWNERS
index 40806071efd..931f689fa18 100644
--- a/chromium/components/autofill_assistant/OWNERS
+++ b/chromium/components/autofill_assistant/OWNERS
@@ -1,4 +1,7 @@
+# Please keep these in alphabetical order
+arbesser@google.com
gogerald@chromium.org
+jdemeulenaere@chromium.org
mcarlen@chromium.org
rouslan@chromium.org
szermatt@chromium.org
diff --git a/chromium/components/autofill_assistant/browser/BUILD.gn b/chromium/components/autofill_assistant/browser/BUILD.gn
index 5a283b2042d..6ba75192935 100644
--- a/chromium/components/autofill_assistant/browser/BUILD.gn
+++ b/chromium/components/autofill_assistant/browser/BUILD.gn
@@ -21,7 +21,6 @@ proto_java_library("proto_java") {
java_cpp_enum("autofill_assistant_enums_java") {
sources = [
- "chip.h",
"metrics.h",
"overlay_state.h",
]
@@ -57,6 +56,8 @@ jumbo_static_library("browser") {
"actions/set_form_field_value_action.h",
"actions/show_details_action.cc",
"actions/show_details_action.h",
+ "actions/show_info_box_action.cc",
+ "actions/show_info_box_action.h",
"actions/show_progress_bar_action.cc",
"actions/show_progress_bar_action.h",
"actions/stop_action.cc",
@@ -82,10 +83,17 @@ jumbo_static_library("browser") {
"details.h",
"element_area.cc",
"element_area.h",
+ "element_precondition.cc",
+ "element_precondition.h",
+ "features.cc",
+ "features.h",
+ "info_box.cc",
+ "info_box.h",
"metrics.cc",
"metrics.h",
"overlay_state.h",
- "payment_information.h",
+ "payment_request.cc",
+ "payment_request.h",
"protocol_utils.cc",
"protocol_utils.h",
"rectf.cc",
@@ -136,11 +144,13 @@ source_set("unit_tests") {
"actions/autofill_action_unittest.cc",
"actions/mock_action_delegate.cc",
"actions/mock_action_delegate.h",
+ "actions/prompt_action_unittest.cc",
"batch_element_checker_unittest.cc",
"controller_unittest.cc",
"element_area_unittest.cc",
- "mock_client_memory.cc",
- "mock_client_memory.h",
+ "element_precondition_unittest.cc",
+ "fake_script_executor_delegate.cc",
+ "fake_script_executor_delegate.h",
"mock_run_once_callback.h",
"mock_service.cc",
"mock_service.h",
diff --git a/chromium/components/autofill_assistant/browser/actions/action.cc b/chromium/components/autofill_assistant/browser/actions/action.cc
index d90f037e1f5..30f4a5f3a46 100644
--- a/chromium/components/autofill_assistant/browser/actions/action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/action.cc
@@ -36,4 +36,83 @@ std::vector<std::string> Action::ExtractVector(
return vector;
}
+std::ostream& operator<<(std::ostream& out, const Action& action) {
+ out << action.proto().action_info_case();
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out,
+ const ActionProto::ActionInfoCase& action_case) {
+#ifdef NDEBUG
+ out << static_cast<int>(action_case);
+ return out;
+#else
+ switch (action_case) {
+ case ActionProto::ActionInfoCase::kClick:
+ out << "Click";
+ break;
+ case ActionProto::ActionInfoCase::kSetFormValue:
+ out << "KeyboardInput";
+ break;
+ case ActionProto::ActionInfoCase::kSelectOption:
+ out << "SelectOption";
+ break;
+ case ActionProto::ActionInfoCase::kNavigate:
+ out << "Navigate";
+ break;
+ case ActionProto::ActionInfoCase::kPrompt:
+ out << "Prompt";
+ break;
+ case ActionProto::ActionInfoCase::kTell:
+ out << "Tell";
+ break;
+ case ActionProto::ActionInfoCase::kFocusElement:
+ out << "FocusElement";
+ break;
+ case ActionProto::ActionInfoCase::kWaitForDom:
+ out << "WaitForDom";
+ break;
+ case ActionProto::ActionInfoCase::kUseCard:
+ out << "UseCard";
+ break;
+ case ActionProto::ActionInfoCase::kUseAddress:
+ out << "UseAddress";
+ break;
+ case ActionProto::ActionInfoCase::kUploadDom:
+ out << "UploadDom";
+ break;
+ case ActionProto::ActionInfoCase::kShowProgressBar:
+ out << "ShowProgressBar";
+ break;
+ case ActionProto::ActionInfoCase::kHighlightElement:
+ out << "HighlightElement";
+ break;
+ case ActionProto::ActionInfoCase::kShowDetails:
+ out << "ShowDetails";
+ break;
+ case ActionProto::ActionInfoCase::kReset:
+ out << "Reset";
+ break;
+ case ActionProto::ActionInfoCase::kStop:
+ out << "Stop";
+ break;
+ case ActionProto::ActionInfoCase::kGetPaymentInformation:
+ out << "GetPaymentInformation";
+ break;
+ case ActionProto::ActionInfoCase::kSetAttribute:
+ out << "SetAttribute";
+ break;
+ case ActionProto::ActionInfoCase::kShowInfoBox:
+ out << "ShowInfoBox";
+ break;
+ case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET:
+ out << "ACTION_INFO_NOT_SET";
+ break;
+ // Intentionally no default case to make compilation fail if a new value
+ // was added to the enum but not to this list.
+ }
+ return out;
+#endif // NDEBUG
+}
+
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/action.h b/chromium/components/autofill_assistant/browser/actions/action.h
index 0ecf2970938..fda288af71b 100644
--- a/chromium/components/autofill_assistant/browser/actions/action.h
+++ b/chromium/components/autofill_assistant/browser/actions/action.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_ACTION_H_
#include <memory>
+#include <ostream>
#include <string>
#include <vector>
@@ -45,6 +46,10 @@ class Action {
void UpdateProcessedAction(ProcessedActionStatusProto status);
+ // Intended for debugging. Writes a string representation of |action| to
+ // |out|.
+ friend std::ostream& operator<<(std::ostream& out, const Action& action);
+
const ActionProto proto_;
// Accumulate any result of this action during ProcessAction. Is only valid
@@ -52,5 +57,10 @@ class Action {
std::unique_ptr<ProcessedActionProto> processed_action_proto_;
};
+// Intended for debugging. Writes a string representation of |action_case| to
+// |out|.
+std::ostream& operator<<(std::ostream& out,
+ const ActionProto::ActionInfoCase& action_case);
+
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_ACTION_H_
diff --git a/chromium/components/autofill_assistant/browser/actions/action_delegate.h b/chromium/components/autofill_assistant/browser/actions/action_delegate.h
index 78e515aafda..db092d84b53 100644
--- a/chromium/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/chromium/components/autofill_assistant/browser/actions/action_delegate.h
@@ -12,6 +12,7 @@
#include "base/callback_forward.h"
#include "components/autofill_assistant/browser/batch_element_checker.h"
#include "components/autofill_assistant/browser/details.h"
+#include "components/autofill_assistant/browser/info_box.h"
#include "components/autofill_assistant/browser/selector.h"
#include "components/autofill_assistant/browser/ui_controller.h"
#include "third_party/blink/public/mojom/payments/payment_request.mojom.h"
@@ -30,7 +31,6 @@ class WebContents;
namespace autofill_assistant {
class ClientMemory;
-struct PaymentInformation;
// Action delegate called when processing actions.
class ActionDelegate {
@@ -83,7 +83,12 @@ class ActionDelegate {
// scripts, even though we're in the middle of a script. This includes
// allowing access to the touchable elements set previously, in the same
// script.
- virtual void Prompt(std::unique_ptr<std::vector<Chip>> chips) = 0;
+ //
+ // |on_terminate| is called if the prompt is terminated, by Autofill Assistant
+ // shutting down. The action should return immediately with client error
+ // USER_ABORTED_ACTION.
+ virtual void Prompt(std::unique_ptr<std::vector<Chip>> chips,
+ base::OnceCallback<void()> on_terminate) = 0;
// Remove all chips from the UI.
virtual void CancelPrompt() = 0;
@@ -91,10 +96,7 @@ class ActionDelegate {
// Asks the user to provide the data used by UseAddressAction and
// UseCreditCardAction.
virtual void GetPaymentInformation(
- payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)> callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks) = 0;
+ std::unique_ptr<PaymentRequestOptions> options) = 0;
using GetFullCardCallback =
base::OnceCallback<void(std::unique_ptr<autofill::CreditCard> card,
@@ -178,10 +180,6 @@ class ActionDelegate {
// state.
virtual void Restart() = 0;
- // Stop the current script, shutdown autofill assistant and show |message| if
- // it is not empty or a default message otherwise.
- virtual void StopCurrentScriptAndShutdown(const std::string& message) = 0;
-
// Return the current ClientMemory.
virtual ClientMemory* GetClientMemory() = 0;
@@ -191,17 +189,21 @@ class ActionDelegate {
// Get associated web contents.
virtual content::WebContents* GetWebContents() = 0;
- // Clears contextual information.
- virtual void ClearDetails() = 0;
-
// Sets or updates contextual information.
- virtual void SetDetails(const Details& details) = 0;
+ // Passing nullptr clears the contextual information.
+ virtual void SetDetails(std::unique_ptr<Details> details) = 0;
+
+ // Clears the info box.
+ virtual void ClearInfoBox() = 0;
+
+ // Sets or updates info box.
+ virtual void SetInfoBox(const InfoBox& infoBox) = 0;
// Show the progress bar and set it at |progress|%.
- virtual void ShowProgressBar(int progress) = 0;
+ virtual void SetProgress(int progress) = 0;
- // Hide the progress bar.
- virtual void HideProgressBar() = 0;
+ // Shows the progress bar when |visible| is true. Hides it when false.
+ virtual void SetProgressVisible(bool visible) = 0;
protected:
ActionDelegate() = default;
diff --git a/chromium/components/autofill_assistant/browser/actions/autofill_action.cc b/chromium/components/autofill_assistant/browser/actions/autofill_action.cc
index e5573c33914..024cc1369b0 100644
--- a/chromium/components/autofill_assistant/browser/actions/autofill_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/autofill_action.cc
@@ -26,8 +26,6 @@ AutofillAction::AutofillAction(const ActionProto& proto)
prompt_ = proto.use_address().prompt();
name_ = proto.use_address().name();
selector_ = Selector(proto.use_address().form_field_element());
- fill_form_message_ = proto.use_address().strings().fill_form();
- check_form_message_ = proto.use_address().strings().check_form();
required_fields_value_status_.resize(
proto_.use_address().required_fields_size(), UNKNOWN);
} else {
@@ -36,8 +34,6 @@ AutofillAction::AutofillAction(const ActionProto& proto)
prompt_ = proto.use_card().prompt();
name_ = "";
selector_ = Selector(proto.use_card().form_field_element());
- fill_form_message_ = proto.use_card().strings().fill_form();
- check_form_message_ = proto.use_card().strings().check_form();
}
DCHECK(!selector_.empty());
}
@@ -60,11 +56,7 @@ void AutofillAction::InternalProcessAction(
(!is_autofill_card_ &&
delegate->GetClientMemory()->selected_address(name_));
if (!has_valid_data) {
- // User selected 'Fill manually'.
- // TODO(crbug.com/806868): Check whether it is still possible to reach this
- // part of the code.
- delegate->StopCurrentScriptAndShutdown(fill_form_message_);
- EndAction(MANUAL_FALLBACK);
+ EndAction(PRECONDITION_FAILED);
return;
}
@@ -113,8 +105,7 @@ void AutofillAction::OnGetFullCard(ActionDelegate* delegate,
if (!card) {
// Gracefully shutdown the script. The empty message forces the use of the
// default message.
- delegate->StopCurrentScriptAndShutdown("");
- EndAction(MANUAL_FALLBACK);
+ EndAction(GET_FULL_CARD_FAILED);
return;
}
@@ -194,9 +185,7 @@ void AutofillAction::OnCheckRequiredFieldsDone(ActionDelegate* delegate,
}
if (!allow_fallback) {
- // Validation failed and we don't want to try the fallback, so we stop
- // the script.
- delegate->StopCurrentScriptAndShutdown(check_form_message_);
+ // Validation failed and we don't want to try the fallback.
EndAction(MANUAL_FALLBACK);
return;
}
@@ -216,7 +205,6 @@ void AutofillAction::OnCheckRequiredFieldsDone(ActionDelegate* delegate,
}
}
if (!has_fallbacks) {
- delegate->StopCurrentScriptAndShutdown(check_form_message_);
EndAction(MANUAL_FALLBACK);
return;
}
@@ -272,7 +260,6 @@ void AutofillAction::OnSetFallbackFieldValue(ActionDelegate* delegate,
bool successful) {
if (!successful) {
// Fallback failed: we stop the script without checking the fields.
- delegate->StopCurrentScriptAndShutdown(check_form_message_);
EndAction(MANUAL_FALLBACK);
return;
}
diff --git a/chromium/components/autofill_assistant/browser/actions/autofill_action.h b/chromium/components/autofill_assistant/browser/actions/autofill_action.h
index 1229f08888d..8a25c075bb6 100644
--- a/chromium/components/autofill_assistant/browser/actions/autofill_action.h
+++ b/chromium/components/autofill_assistant/browser/actions/autofill_action.h
@@ -92,8 +92,6 @@ class AutofillAction : public Action {
std::string name_;
std::string prompt_;
Selector selector_;
- std::string fill_form_message_;
- std::string check_form_message_;
// True if autofilling a card, otherwise we are autofilling an address.
bool is_autofill_card_;
diff --git a/chromium/components/autofill_assistant/browser/actions/autofill_action_unittest.cc b/chromium/components/autofill_assistant/browser/actions/autofill_action_unittest.cc
index d016598f3b4..596b65f8a9f 100644
--- a/chromium/components/autofill_assistant/browser/actions/autofill_action_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/actions/autofill_action_unittest.cc
@@ -8,11 +8,12 @@
#include "base/bind.h"
#include "base/guid.h"
+#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
-#include "components/autofill_assistant/browser/mock_client_memory.h"
+#include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_web_controller.h"
#include "components/autofill_assistant/browser/service.pb.h"
@@ -34,7 +35,7 @@ using ::testing::StrNe;
class MockPersonalDataManager : public autofill::PersonalDataManager {
public:
MockPersonalDataManager() : PersonalDataManager("en-US") {}
- ~MockPersonalDataManager() override{};
+ ~MockPersonalDataManager() override {}
// PersonalDataManager:
std::string SaveImportedProfile(
@@ -98,16 +99,19 @@ class DirectCallback {
class AutofillActionTest : public testing::Test {
public:
void SetUp() override {
- autofill_profile_ = std::make_unique<autofill::AutofillProfile>(
+ auto autofill_profile = std::make_unique<autofill::AutofillProfile>(
base::GenerateGUID(), autofill::test::kEmptyOrigin);
- autofill::test::SetProfileInfo(autofill_profile_.get(), kFirstName, "",
+ autofill::test::SetProfileInfo(autofill_profile.get(), kFirstName, "",
kLastName, kEmail, "", "", "", "", "", "",
"", "");
personal_data_manager_ = std::make_unique<MockPersonalDataManager>();
- personal_data_manager_->SaveImportedProfile(*autofill_profile_);
+ personal_data_manager_->SaveImportedProfile(*autofill_profile);
+
+ client_memory_.set_selected_address(kAddressName,
+ std::move(autofill_profile));
ON_CALL(mock_action_delegate_, GetClientMemory)
- .WillByDefault(Return(&mock_client_memory_));
+ .WillByDefault(Return(&client_memory_));
ON_CALL(mock_action_delegate_, GetPersonalDataManager)
.WillByDefault(Return(personal_data_manager_.get()));
ON_CALL(mock_action_delegate_, CreateBatchElementChecker)
@@ -125,16 +129,12 @@ class AutofillActionTest : public testing::Test {
const char* const kFirstName = "FirstName";
const char* const kLastName = "LastName";
const char* const kEmail = "foobar@gmail.com";
- const char* const kFillForm = "fill_form";
- const char* const kCheckForm = "check_form";
ActionProto CreateUseAddressAction() {
ActionProto action;
UseAddressProto* use_address = action.mutable_use_address();
use_address->set_name(kAddressName);
use_address->mutable_form_field_element()->add_selectors(kFakeSelector);
- use_address->mutable_strings()->set_fill_form(kFillForm);
- use_address->mutable_strings()->set_check_form(kCheckForm);
return action;
}
@@ -150,8 +150,6 @@ class AutofillActionTest : public testing::Test {
ActionProto action;
UseCreditCardProto* use_card = action.mutable_use_card();
use_card->mutable_form_field_element()->add_selectors(kFakeSelector);
- use_card->mutable_strings()->set_fill_form(kFillForm);
- use_card->mutable_strings()->set_check_form(kCheckForm);
return action;
}
@@ -164,36 +162,37 @@ class AutofillActionTest : public testing::Test {
return callback.GetResultOrDie()->status();
}
- void ExpectActionToStopScript(const ActionProto& action_proto,
- const std::string& expected_message) {
- EXPECT_CALL(mock_action_delegate_,
- StopCurrentScriptAndShutdown(expected_message));
-
- EXPECT_EQ(ProcessedActionStatusProto::MANUAL_FALLBACK,
- ProcessAction(action_proto));
- }
-
MockActionDelegate mock_action_delegate_;
MockWebController mock_web_controller_;
- MockClientMemory mock_client_memory_;
- std::unique_ptr<autofill::AutofillProfile> autofill_profile_;
+ ClientMemory client_memory_;
std::unique_ptr<autofill::PersonalDataManager> personal_data_manager_;
};
-TEST_F(AutofillActionTest, FillManually) {
+#if !defined(OS_ANDROID)
+#define MAYBE_FillManually FillManually
+#else
+#define MAYBE_FillManually DISABLED_FillManually
+#endif
+TEST_F(AutofillActionTest, MAYBE_FillManually) {
+ InSequence seq;
+
+ ActionProto action_proto = CreateUseAddressAction();
+ action_proto.mutable_use_address()->set_prompt(kSelectionPrompt);
+
+ EXPECT_EQ(ProcessedActionStatusProto::MANUAL_FALLBACK,
+ ProcessAction(action_proto));
+}
+
+TEST_F(AutofillActionTest, NoSelectedAddress) {
InSequence seq;
ActionProto action_proto = CreateUseAddressAction();
action_proto.mutable_use_address()->set_prompt(kSelectionPrompt);
- // No selection was made previously.
- // Note: We use ON_CALL instead of EXPECT_CALL as the `has_selected_address`
- // call is made inside a DCHECK, which means this won't be called when testing
- // a release build.
- ON_CALL(mock_client_memory_, has_selected_address(kAddressName))
- .WillByDefault(Return(true));
+ client_memory_.set_selected_address(kAddressName, nullptr);
- ExpectActionToStopScript(action_proto, kFillForm);
+ EXPECT_EQ(ProcessedActionStatusProto::PRECONDITION_FAILED,
+ ProcessAction(action_proto));
}
TEST_F(AutofillActionTest, ValidationSucceeds) {
@@ -207,12 +206,6 @@ TEST_F(AutofillActionTest, ValidationSucceeds) {
AddRequiredField(&action_proto, UseAddressProto::RequiredField::EMAIL,
"#email");
- // Return a fake selected address.
- ON_CALL(mock_client_memory_, has_selected_address(kAddressName))
- .WillByDefault(Return(true));
- ON_CALL(mock_client_memory_, selected_address(kAddressName))
- .WillByDefault(Return(autofill_profile_.get()));
-
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
@@ -237,12 +230,6 @@ TEST_F(AutofillActionTest, FallbackFails) {
AddRequiredField(&action_proto, UseAddressProto::RequiredField::EMAIL,
"#email");
- // Return a fake selected address.
- ON_CALL(mock_client_memory_, has_selected_address(kAddressName))
- .WillByDefault(Return(true));
- ON_CALL(mock_client_memory_, selected_address(kAddressName))
- .WillByDefault(Return(autofill_profile_.get()));
-
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
@@ -264,7 +251,8 @@ TEST_F(AutofillActionTest, FallbackFails) {
OnSetFieldValue(Eq(Selector({"#first_name"})), kFirstName, _))
.WillOnce(RunOnceCallback<2>(false));
- ExpectActionToStopScript(action_proto, kCheckForm);
+ EXPECT_EQ(ProcessedActionStatusProto::MANUAL_FALLBACK,
+ ProcessAction(action_proto));
}
TEST_F(AutofillActionTest, FallbackSucceeds) {
@@ -278,12 +266,6 @@ TEST_F(AutofillActionTest, FallbackSucceeds) {
AddRequiredField(&action_proto, UseAddressProto::RequiredField::EMAIL,
"#email");
- // Return a fake selected address.
- ON_CALL(mock_client_memory_, has_selected_address(kAddressName))
- .WillByDefault(Return(true));
- ON_CALL(mock_client_memory_, selected_address(kAddressName))
- .WillByDefault(Return(autofill_profile_.get()));
-
// Autofill succeeds.
EXPECT_CALL(mock_action_delegate_,
OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _))
diff --git a/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.cc b/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.cc
index 11af5c9d261..7b838dd14b4 100644
--- a/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.cc
@@ -4,6 +4,7 @@
#include "components/autofill_assistant/browser/actions/get_payment_information_action.h"
+#include <algorithm>
#include <utility>
#include "base/bind.h"
@@ -33,8 +34,7 @@ void GetPaymentInformationAction::InternalProcessAction(
const GetPaymentInformationProto& get_payment_information =
proto_.get_payment_information();
- payments::mojom::PaymentOptionsPtr payment_options =
- payments::mojom::PaymentOptions::New();
+ auto payment_options = std::make_unique<PaymentRequestOptions>();
if (get_payment_information.has_contact_details()) {
auto contact_details = get_payment_information.contact_details();
payment_options->request_payer_email =
@@ -44,23 +44,20 @@ void GetPaymentInformationAction::InternalProcessAction(
contact_details.request_payer_phone();
}
- std::vector<std::string> supported_basic_card_networks;
std::copy(get_payment_information.supported_basic_card_networks().begin(),
get_payment_information.supported_basic_card_networks().end(),
- std::back_inserter(supported_basic_card_networks));
+ std::back_inserter(payment_options->supported_basic_card_networks));
payment_options->request_shipping =
!get_payment_information.shipping_address_name().empty();
-
- delegate->GetPaymentInformation(
- std::move(payment_options),
+ payment_options->callback =
base::BindOnce(&GetPaymentInformationAction::OnGetPaymentInformation,
weak_ptr_factory_.GetWeakPtr(), delegate,
- std::move(get_payment_information), std::move(callback)),
- get_payment_information.prompt(), supported_basic_card_networks);
+ std::move(get_payment_information), std::move(callback));
if (get_payment_information.has_prompt()) {
delegate->SetStatusMessage(get_payment_information.prompt());
}
+ delegate->GetPaymentInformation(std::move(payment_options));
}
void GetPaymentInformationAction::OnGetPaymentInformation(
diff --git a/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.h b/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.h
index cce34f80c5d..2a28b9421e8 100644
--- a/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.h
+++ b/chromium/components/autofill_assistant/browser/actions/get_payment_information_action.h
@@ -12,7 +12,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill_assistant/browser/actions/action.h"
-#include "components/autofill_assistant/browser/payment_information.h"
+#include "components/autofill_assistant/browser/payment_request.h"
namespace autofill_assistant {
diff --git a/chromium/components/autofill_assistant/browser/actions/mock_action_delegate.h b/chromium/components/autofill_assistant/browser/actions/mock_action_delegate.h
index ecce453fbef..b854c93dcf4 100644
--- a/chromium/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/chromium/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -54,7 +54,9 @@ class MockActionDelegate : public ActionDelegate {
void(const Selector& selector,
base::OnceCallback<void(bool)> callback));
- MOCK_METHOD1(Prompt, void(std::unique_ptr<std::vector<Chip>> chips));
+ MOCK_METHOD2(Prompt,
+ void(std::unique_ptr<std::vector<Chip>> chips,
+ base::OnceCallback<void()> on_terminate));
MOCK_METHOD0(CancelPrompt, void());
void FillAddressForm(const autofill::AutofillProfile* profile,
@@ -93,13 +95,8 @@ class MockActionDelegate : public ActionDelegate {
void(const Selector& selector,
base::OnceCallback<void(bool)> callback));
- MOCK_METHOD4(
- GetPaymentInformation,
- void(payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)>
- callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks));
+ MOCK_METHOD1(GetPaymentInformation,
+ void(std::unique_ptr<PaymentRequestOptions> options));
MOCK_METHOD1(GetFullCard, void(GetFullCardCallback callback));
@@ -136,11 +133,12 @@ class MockActionDelegate : public ActionDelegate {
MOCK_METHOD0(GetClientMemory, ClientMemory*());
MOCK_METHOD0(GetPersonalDataManager, autofill::PersonalDataManager*());
MOCK_METHOD0(GetWebContents, content::WebContents*());
- MOCK_METHOD1(StopCurrentScriptAndShutdown, void(const std::string& message));
- MOCK_METHOD1(SetDetails, void(const Details& details));
- MOCK_METHOD0(ClearDetails, void());
- MOCK_METHOD1(ShowProgressBar, void(int progress));
- MOCK_METHOD0(HideProgressBar, void());
+ MOCK_METHOD1(SetDetails, void(std::unique_ptr<Details> details));
+ MOCK_METHOD1(SetInfoBox, void(const InfoBox& info_box));
+ MOCK_METHOD0(ClearInfoBox, void());
+ MOCK_METHOD1(SetProgress, void(int progress));
+ MOCK_METHOD1(SetProgressVisible, void(bool visible));
+ MOCK_METHOD1(SetChips, void(std::unique_ptr<std::vector<Chip>> chips));
};
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/prompt_action.cc b/chromium/components/autofill_assistant/browser/actions/prompt_action.cc
index f3a83b4874b..2a1f9bd5ea5 100644
--- a/chromium/components/autofill_assistant/browser/actions/prompt_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/prompt_action.cc
@@ -9,12 +9,20 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "components/autofill_assistant/browser/actions/action_delegate.h"
+#include "components/autofill_assistant/browser/element_precondition.h"
#include "url/gurl.h"
namespace autofill_assistant {
+namespace {
+// Time between two chip precondition checks.
+static constexpr base::TimeDelta kPreconditionChipCheckInterval =
+ base::TimeDelta::FromSeconds(1);
+} // namespace
+
PromptAction::PromptAction(const ActionProto& proto)
: Action(proto), weak_ptr_factory_(this) {
DCHECK(proto_.has_prompt());
@@ -24,123 +32,178 @@ PromptAction::~PromptAction() {}
void PromptAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
- delegate->SetStatusMessage(proto_.prompt().message());
+ if (proto_.prompt().choices_size() == 0) {
+ UpdateProcessedAction(OTHER_ACTION_STATUS);
+ std::move(callback).Run(std::move(processed_action_proto_));
+ return;
+ }
+ delegate_ = delegate;
callback_ = std::move(callback);
- DCHECK_GT(proto_.prompt().choices_size(), 0);
-
- delegate->Prompt(CreateChips());
+ delegate->SetStatusMessage(proto_.prompt().message());
- batch_element_checker_ = delegate->CreateBatchElementChecker();
+ SetupAutoSelect();
+ SetupPreconditions();
+ CheckPreconditions();
+ UpdateChips();
+}
- // Register elements whose existence enable new chips.
- for (int i = 0; i < proto_.prompt().choices_size(); i++) {
+void PromptAction::SetupPreconditions() {
+ int choice_count = proto_.prompt().choices_size();
+ preconditions_.resize(choice_count);
+ precondition_results_.resize(choice_count);
+ for (int i = 0; i < choice_count; i++) {
auto& choice_proto = proto_.prompt().choices(i);
- Selector selector(choice_proto.show_only_if_element_exists());
- if (selector.empty())
- continue;
-
- batch_element_checker_->AddElementCheck(
- kExistenceCheck, selector,
- base::BindOnce(&PromptAction::OnRequiredElementExists,
- weak_ptr_factory_.GetWeakPtr(),
- base::Unretained(delegate), i));
+ preconditions_[i] = std::make_unique<ElementPrecondition>(
+ choice_proto.show_only_if_element_exists(),
+ choice_proto.show_only_if_form_value_matches());
+ precondition_results_[i] = false;
}
+}
- // Wait as long as necessary for one of the elements to show up. This is
- // cancelled by CancelProto()
- for (const auto& choice_proto : proto_.prompt().choices()) {
- Selector selector(choice_proto.element_exists());
- if (selector.empty())
- continue;
+void PromptAction::CheckPreconditions() {
+ // This method might be called by PostDelayedTask, possibly after
+ // OnSuggestionChosen ran. The condition on callback_ makes sure that the
+ // caller is still waiting for a response.
+ if (!callback_)
+ return;
- std::string payload;
- choice_proto.SerializeToString(&payload);
- batch_element_checker_->AddElementCheck(
- kExistenceCheck, selector,
- base::BindOnce(&PromptAction::OnElementExist,
- weak_ptr_factory_.GetWeakPtr(), payload));
+ precondition_checker_ = delegate_->CreateBatchElementChecker();
+ for (size_t i = 0; i < preconditions_.size(); i++) {
+ preconditions_[i]->Check(precondition_checker_.get(),
+ base::BindOnce(&PromptAction::OnPreconditionResult,
+ weak_ptr_factory_.GetWeakPtr(), i));
}
+ precondition_checker_->Run(
+ // Try once; retries are handled by OnPreconditionChecksDone.
+ base::TimeDelta::FromSeconds(0),
+ /* try_done= */ base::DoNothing(),
+ base::BindOnce(&PromptAction::OnPreconditionChecksDone,
+ weak_ptr_factory_.GetWeakPtr()));
+}
- batch_element_checker_->Run(
- base::TimeDelta::Max(),
- /* try_done= */
- base::BindRepeating(&PromptAction::OnElementChecksDone,
- weak_ptr_factory_.GetWeakPtr(),
- base::Unretained(delegate)),
- /* all_done= */ base::DoNothing());
+void PromptAction::OnPreconditionResult(size_t choice_index, bool result) {
+ if (precondition_results_[choice_index] == result)
+ return;
+
+ precondition_results_[choice_index] = result;
+ precondition_changed_ = true;
}
-std::unique_ptr<std::vector<Chip>> PromptAction::CreateChips() {
- auto chips = std::make_unique<std::vector<Chip>>();
- // TODO(crbug.com/806868): Surface type in proto instead of guessing it from
- // highlight flag.
- Chip::Type non_highlight_type = Chip::Type::CHIP_ASSISTIVE;
- for (const auto& choice_proto : proto_.prompt().choices()) {
- if (!choice_proto.name().empty() && choice_proto.highlight()) {
- non_highlight_type = Chip::Type::BUTTON_TEXT;
- break;
- }
+void PromptAction::OnPreconditionChecksDone() {
+ if (precondition_changed_)
+ UpdateChips();
+
+ if (HasNonemptyPreconditions()) {
+ // If there are element preconditions, the result can change with time, so
+ // schedule another check later on.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&PromptAction::CheckPreconditions,
+ weak_ptr_factory_.GetWeakPtr()),
+ kPreconditionChipCheckInterval);
}
+}
+
+bool PromptAction::HasNonemptyPreconditions() {
+ for (const auto& precondition : preconditions_) {
+ if (!precondition->empty())
+ return true;
+ }
+ return false;
+}
+void PromptAction::UpdateChips() {
+ DCHECK(callback_); // Make sure we're still waiting for a response
+
+ auto chips = std::make_unique<std::vector<Chip>>();
for (int i = 0; i < proto_.prompt().choices_size(); i++) {
- auto& choice_proto = proto_.prompt().choices(i);
- if (choice_proto.show_only_if_element_exists().selectors_size() > 0 &&
- required_element_found_.count(i) == 0)
+ if (!precondition_results_[i]) // chip disabled
continue;
+ auto& choice_proto = proto_.prompt().choices(i);
chips->emplace_back();
- chips->back().type = choice_proto.highlight()
- ? Chip::Type::BUTTON_FILLED_BLUE
- : non_highlight_type;
- chips->back().text = choice_proto.name();
+ Chip& chip = chips->back();
+ chip.text = choice_proto.name();
+ chip.type = choice_proto.chip_type();
+ chips->back().callback = base::BindOnce(&PromptAction::OnSuggestionChosen,
+ weak_ptr_factory_.GetWeakPtr(), i);
+ }
+ SetDefaultChipType(chips.get());
+ delegate_->Prompt(std::move(chips),
+ base::BindOnce(&PromptAction::OnTerminated,
+ weak_ptr_factory_.GetWeakPtr()));
+ precondition_changed_ = false;
+}
+
+void PromptAction::SetupAutoSelect() {
+ // Wait as long as necessary for one of the elements to show up. This is
+ // cancelled by CancelProto()
+ for (int i = 0; i < proto_.prompt().choices_size(); i++) {
+ Selector selector(
+ proto_.prompt().choices(i).auto_select_if_element_exists());
+ if (selector.empty())
+ continue;
- std::string server_payload;
- choice_proto.SerializeToString(&server_payload);
+ if (!auto_select_checker_)
+ auto_select_checker_ = delegate_->CreateBatchElementChecker();
- chips->back().callback =
- base::BindOnce(&PromptAction::OnSuggestionChosen,
- weak_ptr_factory_.GetWeakPtr(), server_payload);
+ auto_select_checker_->AddElementCheck(
+ kExistenceCheck, selector,
+ base::BindOnce(&PromptAction::OnAutoSelectElementExists,
+ weak_ptr_factory_.GetWeakPtr(), i));
}
- return chips;
+ if (!auto_select_checker_)
+ return;
+
+ auto_select_checker_->Run(base::TimeDelta::Max(),
+ /* try_done= */
+ base::BindRepeating(&PromptAction::OnAutoSelectDone,
+ weak_ptr_factory_.GetWeakPtr()),
+ /* all_done= */ base::DoNothing());
}
-void PromptAction::OnElementExist(const std::string& payload, bool exists) {
+void PromptAction::OnAutoSelectElementExists(int choice_index, bool exists) {
if (exists)
- forced_payload_ = payload;
+ auto_select_choice_index_ = choice_index;
- // Forcing the chip click is delayed until try_done, as it indirectly deletes
- // batch_element_checker_, which isn't supported from an element check
- // callback.
+ // Calling OnSuggestionChosen() is delayed until try_done, as it indirectly
+ // deletes the batch element checker, which isn't supported from an element
+ // check callback.
}
-void PromptAction::OnRequiredElementExists(ActionDelegate* delegate,
- int choice_index,
- bool exists) {
- if (!exists)
- return;
-
- required_element_found_.insert(choice_index);
- delegate->Prompt(CreateChips());
+void PromptAction::OnAutoSelectDone() {
+ if (auto_select_choice_index_ >= 0) {
+ delegate_->CancelPrompt();
+ OnSuggestionChosen(auto_select_choice_index_);
+ }
}
-void PromptAction::OnElementChecksDone(ActionDelegate* delegate) {
- if (!forced_payload_.empty()) {
- delegate->CancelPrompt();
- OnSuggestionChosen(forced_payload_);
+void PromptAction::OnSuggestionChosen(int choice_index) {
+ if (!callback_) {
+ NOTREACHED();
+ return;
}
-}
+ DCHECK(choice_index >= 0 && choice_index <= proto_.prompt().choices_size());
+
+ // Interrupt checks.
+ precondition_checker_.reset();
+ auto_select_checker_.reset();
-void PromptAction::OnSuggestionChosen(const std::string& payload) {
- batch_element_checker_.reset();
PromptProto::Choice choice;
- if (!choice.ParseFromString(payload)) {
- DLOG(ERROR) << "Invalid result.";
- UpdateProcessedAction(OTHER_ACTION_STATUS);
- } else {
- UpdateProcessedAction(ACTION_APPLIED);
- std::swap(*processed_action_proto_->mutable_prompt_choice(), choice);
+ UpdateProcessedAction(ACTION_APPLIED);
+ *processed_action_proto_->mutable_prompt_choice() =
+ proto_.prompt().choices(choice_index);
+ std::move(callback_).Run(std::move(processed_action_proto_));
+}
+
+void PromptAction::OnTerminated() {
+ if (!callback_) {
+ NOTREACHED();
+ return;
}
+ UpdateProcessedAction(USER_ABORTED_ACTION);
std::move(callback_).Run(std::move(processed_action_proto_));
}
+
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/prompt_action.h b/chromium/components/autofill_assistant/browser/actions/prompt_action.h
index 49f8192fcc0..95465e77e15 100644
--- a/chromium/components/autofill_assistant/browser/actions/prompt_action.h
+++ b/chromium/components/autofill_assistant/browser/actions/prompt_action.h
@@ -15,6 +15,7 @@
#include "components/autofill_assistant/browser/actions/action.h"
#include "components/autofill_assistant/browser/batch_element_checker.h"
#include "components/autofill_assistant/browser/chip.h"
+#include "components/autofill_assistant/browser/element_precondition.h"
namespace autofill_assistant {
@@ -29,22 +30,42 @@ class PromptAction : public Action {
void InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) override;
- std::unique_ptr<std::vector<Chip>> CreateChips();
- void OnElementExist(const std::string& payload, bool exists);
- void OnRequiredElementExists(ActionDelegate* delegate,
- int choice_index,
- bool exists);
- void OnElementChecksDone(ActionDelegate* delegate);
- void OnSuggestionChosen(const std::string& payload);
+ void SetupPreconditions();
+ void CheckPreconditions();
+ void OnPreconditionResult(size_t choice_index, bool result);
+ bool HasNonemptyPreconditions();
+ void OnPreconditionChecksDone();
+ void UpdateChips();
+ void SetupAutoSelect();
+ void OnAutoSelectElementExists(int choice_index, bool exists);
+ void OnAutoSelectDone();
+ void OnSuggestionChosen(int choice_index);
+ void OnTerminated();
ProcessActionCallback callback_;
+ ActionDelegate* delegate_;
- std::string forced_payload_;
- std::unique_ptr<BatchElementChecker> batch_element_checker_;
+ // preconditions_[i] contains the element preconditions for
+ // proto.prompt.choice[i].
+ std::vector<std::unique_ptr<ElementPrecondition>> preconditions_;
+
+ // precondition_results_[i] contains the last result reported by
+ // preconditions_[i].
+ std::vector<bool> precondition_results_;
+
+ // true if something in precondition_results_ has changed, which means that
+ // the set of chips must be updated.
+ bool precondition_changed_ = false;
+
+ // Batch element checker for preconditions.
+ std::unique_ptr<BatchElementChecker> precondition_checker_;
+
+ // If >= 0, contains the index of the Choice to auto-select.
+ int auto_select_choice_index_ = -1;
+
+ // Batch element checker for auto-selection, if any.
+ std::unique_ptr<BatchElementChecker> auto_select_checker_;
- // Index of an element in PromptActionProto::choices that has a
- // show_only_if_element_exists condition that is met.
- std::set<int> required_element_found_;
base::WeakPtrFactory<PromptAction> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PromptAction);
diff --git a/chromium/components/autofill_assistant/browser/actions/prompt_action_unittest.cc b/chromium/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
new file mode 100644
index 00000000000..e169e431a21
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/actions/prompt_action_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/actions/prompt_action.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/test/mock_callback.h"
+#include "base/test/scoped_task_environment.h"
+#include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
+#include "components/autofill_assistant/browser/mock_run_once_callback.h"
+#include "components/autofill_assistant/browser/mock_web_controller.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+namespace {
+
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::IsEmpty;
+using ::testing::IsNull;
+using ::testing::Pointee;
+using ::testing::Property;
+using ::testing::SizeIs;
+
+class PromptActionTest : public testing::Test {
+ public:
+ PromptActionTest()
+ : task_env_(
+ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
+
+ void SetUp() override {
+ ON_CALL(mock_web_controller_, OnElementCheck(_, _, _))
+ .WillByDefault(RunOnceCallback<2>(false));
+ ON_CALL(mock_web_controller_, OnGetFieldValue(_, _))
+ .WillByDefault(RunOnceCallback<1>(false, ""));
+
+ ON_CALL(mock_action_delegate_, CreateBatchElementChecker)
+ .WillByDefault(Invoke([this]() {
+ return std::make_unique<BatchElementChecker>(&mock_web_controller_);
+ }));
+
+ ON_CALL(mock_action_delegate_, Prompt(_, _))
+ .WillByDefault(Invoke([this](std::unique_ptr<std::vector<Chip>> chips,
+ base::OnceCallback<void()> on_terminate) {
+ chips_ = std::move(chips);
+ on_terminate_ = std::move(on_terminate);
+ }));
+ prompt_proto_ = proto_.mutable_prompt();
+ }
+
+ protected:
+ // task_env_ must be first to guarantee other field
+ // creation run in that environment.
+ base::test::ScopedTaskEnvironment task_env_;
+
+ MockActionDelegate mock_action_delegate_;
+ MockWebController mock_web_controller_;
+ base::MockCallback<Action::ProcessActionCallback> callback_;
+ ActionProto proto_;
+ PromptProto* prompt_proto_;
+ std::unique_ptr<std::vector<Chip>> chips_;
+ base::OnceCallback<void()> on_terminate_;
+};
+
+TEST_F(PromptActionTest, ChoicesMissing) {
+ EXPECT_CALL(callback_, Run(Pointee(Property(&ProcessedActionProto::status,
+ OTHER_ACTION_STATUS))));
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+}
+
+TEST_F(PromptActionTest, SelectButtons) {
+ auto* ok_proto = prompt_proto_->add_choices();
+ ok_proto->set_name("Ok");
+ ok_proto->set_chip_type(HIGHLIGHTED_ACTION);
+ ok_proto->set_server_payload("ok");
+
+ auto* cancel_proto = prompt_proto_->add_choices();
+ cancel_proto->set_name("Cancel");
+ cancel_proto->set_chip_type(NORMAL_ACTION);
+ cancel_proto->set_server_payload("cancel");
+
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+
+ ASSERT_THAT(chips_, Pointee(SizeIs(2)));
+
+ EXPECT_EQ("Ok", (*chips_)[0].text);
+ EXPECT_EQ(HIGHLIGHTED_ACTION, (*chips_)[0].type);
+
+ EXPECT_EQ("Cancel", (*chips_)[1].text);
+ EXPECT_EQ(NORMAL_ACTION, (*chips_)[1].type);
+
+ EXPECT_CALL(
+ callback_,
+ Run(Pointee(AllOf(
+ Property(&ProcessedActionProto::status, ACTION_APPLIED),
+ Property(&ProcessedActionProto::prompt_choice,
+ Property(&PromptProto::Choice::server_payload, "ok"))))));
+ DCHECK((*chips_)[0].callback);
+ std::move((*chips_)[0].callback).Run();
+}
+
+TEST_F(PromptActionTest, ShowOnlyIfElementExists) {
+ auto* ok_proto = prompt_proto_->add_choices();
+ ok_proto->set_name("Ok");
+ ok_proto->set_chip_type(HIGHLIGHTED_ACTION);
+ ok_proto->set_server_payload("ok");
+ ok_proto->add_show_only_if_element_exists()->add_selectors("element");
+
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+
+ ASSERT_THAT(chips_, Pointee(IsEmpty()));
+
+ EXPECT_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"element"})), _))
+ .WillRepeatedly(RunOnceCallback<2>(true));
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ ASSERT_THAT(chips_, Pointee(SizeIs(1)));
+
+ EXPECT_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"element"})), _))
+ .WillRepeatedly(RunOnceCallback<2>(false));
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ ASSERT_THAT(chips_, Pointee(IsEmpty()));
+}
+
+TEST_F(PromptActionTest, AutoSelect) {
+ auto* choice_proto = prompt_proto_->add_choices();
+ choice_proto->set_server_payload("auto-select");
+ choice_proto->mutable_auto_select_if_element_exists()->add_selectors(
+ "element");
+
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+
+ EXPECT_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"element"})), _))
+ .WillRepeatedly(RunOnceCallback<2>(true));
+
+ EXPECT_CALL(mock_action_delegate_, CancelPrompt());
+ EXPECT_CALL(
+ callback_,
+ Run(Pointee(AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED),
+ Property(&ProcessedActionProto::prompt_choice,
+ Property(&PromptProto::Choice::server_payload,
+ "auto-select"))))));
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+}
+
+TEST_F(PromptActionTest, AutoSelectWithButton) {
+ auto* ok_proto = prompt_proto_->add_choices();
+ ok_proto->set_name("Ok");
+ ok_proto->set_chip_type(HIGHLIGHTED_ACTION);
+ ok_proto->set_server_payload("ok");
+ ok_proto->add_show_only_if_element_exists()->add_selectors("element");
+
+ auto* choice_proto = prompt_proto_->add_choices();
+ choice_proto->set_server_payload("auto-select");
+ choice_proto->mutable_auto_select_if_element_exists()->add_selectors(
+ "element");
+
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+
+ ASSERT_THAT(chips_, Pointee(SizeIs(1)));
+
+ EXPECT_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"element"})), _))
+ .WillRepeatedly(RunOnceCallback<2>(true));
+ EXPECT_CALL(
+ callback_,
+ Run(Pointee(AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED),
+ Property(&ProcessedActionProto::prompt_choice,
+ Property(&PromptProto::Choice::server_payload,
+ "auto-select"))))));
+ task_env_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+}
+
+TEST_F(PromptActionTest, Terminate) {
+ auto* ok_proto = prompt_proto_->add_choices();
+ ok_proto->set_name("Ok");
+ ok_proto->set_chip_type(HIGHLIGHTED_ACTION);
+ ok_proto->set_server_payload("ok");
+
+ PromptAction action(proto_);
+ action.ProcessAction(&mock_action_delegate_, callback_.Get());
+
+ EXPECT_CALL(callback_, Run(Pointee(Property(&ProcessedActionProto::status,
+ USER_ABORTED_ACTION))));
+ std::move(on_terminate_).Run();
+}
+
+} // namespace
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/set_form_field_value_action.cc b/chromium/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
index e1492731290..7e1438051dd 100644
--- a/chromium/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
@@ -83,7 +83,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
weak_ptr_factory_.GetWeakPtr(), delegate,
std::move(callback), /* next = */ next + 1));
} else {
- DLOG(ERROR)
+ DVLOG(3)
<< "SetFormFieldValueProto_KeyPress: field `keycode' is deprecated "
<< "and only supports US-ASCII values (encountered "
<< key_field.keycode() << "). Use field `key' instead.";
@@ -99,7 +99,7 @@ void SetFormFieldValueAction::OnSetFieldValue(ActionDelegate* delegate,
std::move(callback), /* next = */ next + 1));
break;
default:
- DLOG(ERROR) << "Unrecognized field for SetFormFieldValueProto_KeyPress";
+ DVLOG(1) << "Unrecognized field for SetFormFieldValueProto_KeyPress";
OnSetFieldValue(delegate, std::move(callback), next, /* status= */ false);
break;
}
diff --git a/chromium/components/autofill_assistant/browser/actions/show_details_action.cc b/chromium/components/autofill_assistant/browser/actions/show_details_action.cc
index 3568b6f7c2a..3839729186a 100644
--- a/chromium/components/autofill_assistant/browser/actions/show_details_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/show_details_action.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "components/autofill_assistant/browser/actions/action_delegate.h"
#include "components/autofill_assistant/browser/details.h"
@@ -16,8 +17,7 @@
namespace autofill_assistant {
-ShowDetailsAction::ShowDetailsAction(const ActionProto& proto)
- : Action(proto), weak_ptr_factory_(this) {
+ShowDetailsAction::ShowDetailsAction(const ActionProto& proto) : Action(proto) {
DCHECK(proto_.has_show_details());
}
@@ -25,76 +25,43 @@ ShowDetailsAction::~ShowDetailsAction() {}
void ShowDetailsAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
- callback_ = std::move(callback);
-
- if (!proto_.show_details().has_details()) {
- delegate->ClearDetails();
- OnActionProcessed(ACTION_APPLIED);
- return;
- }
-
- Details details;
- details.proto = proto_.show_details().details();
- details.changes = proto_.show_details().change_flags();
- delegate->SetDetails(details);
-
- if (!details.changes.user_approval_required()) {
- OnActionProcessed(ACTION_APPLIED);
- return;
+ std::unique_ptr<Details> details = nullptr;
+ bool details_valid = true;
+
+ switch (proto_.show_details().data_to_show_case()) {
+ case ShowDetailsProto::DataToShowCase::kDetails:
+ details = std::make_unique<Details>();
+ details_valid =
+ Details::UpdateFromProto(proto_.show_details(), details.get());
+ break;
+ case ShowDetailsProto::DataToShowCase::kContactDetails:
+ details = std::make_unique<Details>();
+ details_valid = Details::UpdateFromContactDetails(
+ proto_.show_details(), delegate->GetClientMemory(), details.get());
+ break;
+ case ShowDetailsProto::DataToShowCase::kShippingAddress:
+ details = std::make_unique<Details>();
+ details_valid = Details::UpdateFromShippingAddress(
+ proto_.show_details(), delegate->GetClientMemory(), details.get());
+ break;
+ case ShowDetailsProto::DataToShowCase::kCreditCard:
+ details = std::make_unique<Details>();
+ details_valid = Details::UpdateFromSelectedCreditCard(
+ proto_.show_details(), delegate->GetClientMemory(), details.get());
+ break;
+ case ShowDetailsProto::DataToShowCase::DATA_TO_SHOW_NOT_SET:
+ // Clear Details. Calling SetDetails with nullptr clears the details.
+ break;
}
- // Ask for user approval.
-
- std::string previous_status_message = delegate->GetStatusMessage();
- delegate->SetStatusMessage(
- l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER));
-
- // Continue button.
- auto chips = std::make_unique<std::vector<Chip>>();
- chips->emplace_back();
- chips->back().text =
- l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_CONTINUE_BUTTON);
- chips->back().type = Chip::Type::BUTTON_FILLED_BLUE;
- chips->back().callback = base::BindOnce(
- &ShowDetailsAction::OnUserResponse, weak_ptr_factory_.GetWeakPtr(),
- base::Unretained(delegate), previous_status_message,
- /* success= */ true);
-
- // Go back button.
- chips->emplace_back();
- chips->back().text =
- l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER_GO_BACK);
- chips->back().type = Chip::Type::BUTTON_TEXT;
- chips->back().callback = base::BindOnce(
- &ShowDetailsAction::OnUserResponse, weak_ptr_factory_.GetWeakPtr(),
- base::Unretained(delegate), previous_status_message,
- /* success= */ false);
-
- delegate->Prompt(std::move(chips));
-}
-
-void ShowDetailsAction::OnUserResponse(
- ActionDelegate* delegate,
- const std::string& previous_status_message,
- bool can_continue) {
- if (!can_continue) {
- delegate->Close();
- OnActionProcessed(MANUAL_FALLBACK);
+ if (!details_valid) {
+ DVLOG(1) << "Failed to fill the details";
+ UpdateProcessedAction(OTHER_ACTION_STATUS);
} else {
- // Same details, without highlights.
- Details details;
- details.proto = proto_.show_details().details();
- delegate->SetDetails(details);
- // Restore status message
- delegate->SetStatusMessage(previous_status_message);
- OnActionProcessed(ACTION_APPLIED);
+ delegate->SetDetails(std::move(details));
+ UpdateProcessedAction(ACTION_APPLIED);
}
-}
-
-void ShowDetailsAction::OnActionProcessed(ProcessedActionStatusProto status) {
- DCHECK(callback_);
- UpdateProcessedAction(status);
- std::move(callback_).Run(std::move(processed_action_proto_));
+ std::move(callback).Run(std::move(processed_action_proto_));
}
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/show_details_action.h b/chromium/components/autofill_assistant/browser/actions/show_details_action.h
index f29c3f1bde3..1b1b8bd8050 100644
--- a/chromium/components/autofill_assistant/browser/actions/show_details_action.h
+++ b/chromium/components/autofill_assistant/browser/actions/show_details_action.h
@@ -23,13 +23,6 @@ class ShowDetailsAction : public Action {
// Overrides Action:
void InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) override;
- void OnUserResponse(ActionDelegate* delegate,
- const std::string& old_status_message,
- bool can_continue);
- void OnActionProcessed(ProcessedActionStatusProto status);
-
- ProcessActionCallback callback_;
- base::WeakPtrFactory<ShowDetailsAction> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ShowDetailsAction);
};
diff --git a/chromium/components/autofill_assistant/browser/actions/show_info_box_action.cc b/chromium/components/autofill_assistant/browser/actions/show_info_box_action.cc
new file mode 100644
index 00000000000..31ac1b69ebc
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/actions/show_info_box_action.cc
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/actions/show_info_box_action.h"
+
+#include <utility>
+
+#include "components/autofill_assistant/browser/actions/action_delegate.h"
+#include "components/autofill_assistant/browser/info_box.h"
+
+namespace autofill_assistant {
+
+ShowInfoBoxAction::ShowInfoBoxAction(const ActionProto& proto)
+ : Action(proto) {}
+
+ShowInfoBoxAction::~ShowInfoBoxAction() {}
+
+void ShowInfoBoxAction::InternalProcessAction(ActionDelegate* delegate,
+ ProcessActionCallback callback) {
+ if (!proto_.show_info_box().has_info_box()) {
+ delegate->ClearInfoBox();
+ } else {
+ delegate->SetInfoBox(InfoBox(proto_.show_info_box()));
+ }
+ UpdateProcessedAction(ACTION_APPLIED);
+ std::move(callback).Run(std::move(processed_action_proto_));
+}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/actions/show_info_box_action.h b/chromium/components/autofill_assistant/browser/actions/show_info_box_action.h
new file mode 100644
index 00000000000..d8b1022838d
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/actions/show_info_box_action.h
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_INFO_BOX_ACTION_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_INFO_BOX_ACTION_H_
+
+#include "base/macros.h"
+#include "components/autofill_assistant/browser/actions/action.h"
+
+namespace autofill_assistant {
+
+// Action to show informational content in the sheet.
+class ShowInfoBoxAction : public Action {
+ public:
+ explicit ShowInfoBoxAction(const ActionProto& proto);
+ ~ShowInfoBoxAction() override;
+
+ private:
+ // Overrides Action:
+ void InternalProcessAction(ActionDelegate* delegate,
+ ProcessActionCallback callback) override;
+
+ DISALLOW_COPY_AND_ASSIGN(ShowInfoBoxAction);
+};
+
+} // namespace autofill_assistant
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_INFO_BOX_ACTION_H_
diff --git a/chromium/components/autofill_assistant/browser/actions/show_progress_bar_action.cc b/chromium/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
index 7094a1c61d3..243f4dace57 100644
--- a/chromium/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
@@ -24,13 +24,14 @@ ShowProgressBarAction::~ShowProgressBarAction() {}
void ShowProgressBarAction::InternalProcessAction(
ActionDelegate* delegate,
ProcessActionCallback callback) {
- if (proto_.show_progress_bar().done()) {
- delegate->HideProgressBar();
- } else {
- int progress =
- std::min(100, std::max(0, proto_.show_progress_bar().progress()));
+ if (!proto_.show_progress_bar().message().empty()) {
delegate->SetStatusMessage(proto_.show_progress_bar().message());
- delegate->ShowProgressBar(progress);
+ }
+ int progress =
+ std::min(100, std::max(0, proto_.show_progress_bar().progress()));
+ delegate->SetProgress(progress);
+ if (proto_.show_progress_bar().has_hide()) {
+ delegate->SetProgressVisible(!proto_.show_progress_bar().hide());
}
UpdateProcessedAction(ACTION_APPLIED);
diff --git a/chromium/components/autofill_assistant/browser/actions/stop_action.cc b/chromium/components/autofill_assistant/browser/actions/stop_action.cc
index 4ff6cd58605..b220bf599d5 100644
--- a/chromium/components/autofill_assistant/browser/actions/stop_action.cc
+++ b/chromium/components/autofill_assistant/browser/actions/stop_action.cc
@@ -20,7 +20,11 @@ StopAction::~StopAction() {}
void StopAction::InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) {
- delegate->Shutdown();
+ if (proto_.stop().close_cct()) {
+ delegate->Close();
+ } else {
+ delegate->Shutdown();
+ }
UpdateProcessedAction(ACTION_APPLIED);
std::move(callback).Run(std::move(processed_action_proto_));
}
diff --git a/chromium/components/autofill_assistant/browser/actions/unsupported_action.h b/chromium/components/autofill_assistant/browser/actions/unsupported_action.h
index a372e5b76d4..4c67bf2b801 100644
--- a/chromium/components/autofill_assistant/browser/actions/unsupported_action.h
+++ b/chromium/components/autofill_assistant/browser/actions/unsupported_action.h
@@ -20,8 +20,6 @@ class UnsupportedAction : public Action {
void InternalProcessAction(ActionDelegate* delegate,
ProcessActionCallback callback) override;
- void OnUnsupported(ProcessActionCallback callback, bool status);
-
DISALLOW_COPY_AND_ASSIGN(UnsupportedAction);
};
diff --git a/chromium/components/autofill_assistant/browser/batch_element_checker_unittest.cc b/chromium/components/autofill_assistant/browser/batch_element_checker_unittest.cc
index 4b45a975954..de579347a76 100644
--- a/chromium/components/autofill_assistant/browser/batch_element_checker_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/batch_element_checker_unittest.cc
@@ -7,6 +7,8 @@
#include <map>
#include <set>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
@@ -270,7 +272,7 @@ TEST_F(BatchElementCheckerTest, EventuallyFindAll) {
// The first try should have run, not fully successful, and should now be
// waiting for the second try.
- EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_TRUE(scoped_task_environment_.NextTaskIsDelayed());
EXPECT_THAT(element_exists_results_, Contains(Pair("1", true)));
EXPECT_THAT(element_exists_results_, Not(Contains(Key("2"))));
EXPECT_THAT(all_done_, Not(Contains("all_done")));
@@ -278,7 +280,7 @@ TEST_F(BatchElementCheckerTest, EventuallyFindAll) {
// The second try should have found 2 and finished.
AdvanceTime();
- EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_EQ(scoped_task_environment_.GetPendingMainThreadTaskCount(), 0u);
EXPECT_THAT(element_exists_results_, Contains(Pair("2", true)));
EXPECT_THAT(all_done_, Contains("all_done"));
EXPECT_TRUE(checks_.all_found());
@@ -304,19 +306,19 @@ TEST_F(BatchElementCheckerTest, EventuallyFindSome) {
// The first try should have run, not fully successful, and should now be
// waiting for the second try.
- EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_TRUE(scoped_task_environment_.NextTaskIsDelayed());
EXPECT_THAT(element_exists_results_, Contains(Pair("1", true)));
EXPECT_THAT(element_exists_results_, Not(Contains(Key("2"))));
EXPECT_THAT(all_done_, Not(Contains("all_done")));
// The second try still doesn't work'
AdvanceTime();
- EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_TRUE(scoped_task_environment_.NextTaskIsDelayed());
EXPECT_THAT(element_exists_results_, Not(Contains(Key("2"))));
// Give up after the third try
AdvanceTime();
- EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_EQ(scoped_task_environment_.GetPendingMainThreadTaskCount(), 0u);
EXPECT_THAT(element_exists_results_, Contains(Pair("2", false)));
EXPECT_THAT(all_done_, Contains("all_done"));
EXPECT_FALSE(checks_.all_found());
@@ -354,7 +356,7 @@ TEST_F(BatchElementCheckerTest, TryOnceGivenSmallDuration) {
checks_.Run(base::TimeDelta::FromMilliseconds(10), base::DoNothing(),
DoneCallback("all_done"));
- EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_EQ(scoped_task_environment_.GetPendingMainThreadTaskCount(), 0u);
EXPECT_THAT(element_exists_results_, Contains(Pair("does_not_exist", false)));
EXPECT_THAT(all_done_, Contains("all_done"));
EXPECT_FALSE(checks_.all_found());
diff --git a/chromium/components/autofill_assistant/browser/chip.cc b/chromium/components/autofill_assistant/browser/chip.cc
index ca62f06af60..8d97580cda2 100644
--- a/chromium/components/autofill_assistant/browser/chip.cc
+++ b/chromium/components/autofill_assistant/browser/chip.cc
@@ -11,4 +11,21 @@ Chip::~Chip() = default;
Chip::Chip(Chip&&) = default;
Chip& Chip::operator=(Chip&&) = default;
-} // namespace autofill_assistant \ No newline at end of file
+void SetDefaultChipType(std::vector<Chip>* chips) {
+ ChipType default_type = SUGGESTION;
+ for (const Chip& chip : *chips) {
+ if (chip.type != UNKNOWN_CHIP_TYPE && chip.type != SUGGESTION) {
+ // If there's an action chip, assume chips with unknown type are also
+ // actions.
+ default_type = NORMAL_ACTION;
+ break;
+ }
+ }
+ for (Chip& chip : *chips) {
+ if (chip.type == UNKNOWN_CHIP_TYPE) {
+ chip.type = default_type;
+ }
+ }
+}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/chip.h b/chromium/components/autofill_assistant/browser/chip.h
index 9bd44cf099f..941b5a410f1 100644
--- a/chromium/components/autofill_assistant/browser/chip.h
+++ b/chromium/components/autofill_assistant/browser/chip.h
@@ -6,8 +6,10 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_CHIP_H_
#include <string>
+#include <vector>
#include "base/callback.h"
+#include "components/autofill_assistant/browser/service.pb.h"
namespace autofill_assistant {
@@ -18,20 +20,7 @@ struct Chip {
Chip(Chip&&);
Chip& operator=(Chip&&);
- // The type a chip can have. The terminology is borrow from:
- // - https://guidelines.googleplex.com/googlematerial/components/chips.html
- // - https://guidelines.googleplex.com/googlematerial/components/buttons.html
- // GENERATED_JAVA_ENUM_PACKAGE: (
- // org.chromium.chrome.browser.autofill_assistant.carousel)
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: AssistantChipType
- enum Type {
- CHIP_ASSISTIVE = 0,
- BUTTON_FILLED_BLUE = 1,
- BUTTON_TEXT = 2,
- };
-
- // The type of the chip.
- Type type;
+ ChipType type;
// Localized string to display.
std::string text;
@@ -40,6 +29,9 @@ struct Chip {
base::OnceClosure callback;
};
+// Guarantees that the Chip.type of all chips is set to a sensible value.
+void SetDefaultChipType(std::vector<Chip>* chips);
+
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_CHIP_H_
diff --git a/chromium/components/autofill_assistant/browser/client.h b/chromium/components/autofill_assistant/browser/client.h
index 1bb17d426d8..d8fa36f788f 100644
--- a/chromium/components/autofill_assistant/browser/client.h
+++ b/chromium/components/autofill_assistant/browser/client.h
@@ -7,6 +7,8 @@
#include <string>
+#include "components/autofill_assistant/browser/metrics.h"
+
namespace autofill {
class PersonalDataManager;
} // namespace autofill
@@ -21,6 +23,12 @@ class Client {
public:
virtual ~Client() = default;
+ // Show the UI, creates one if necessary.
+ virtual void ShowUI() = 0;
+
+ // Destroys the UI, but keep the controller, if any exists.
+ virtual void DestroyUI() = 0;
+
// Returns the API key to be used for requests to the backend.
virtual std::string GetApiKey() = 0;
@@ -48,7 +56,7 @@ class Client {
// Stops autofill assistant for the current WebContents, both controller and
// UI.
- virtual void Stop() = 0;
+ virtual void Shutdown(Metrics::DropOutReason reason) = 0;
protected:
Client() = default;
diff --git a/chromium/components/autofill_assistant/browser/controller.cc b/chromium/components/autofill_assistant/browser/controller.cc
index 6e22ff1cd60..441fd0faa1c 100644
--- a/chromium/components/autofill_assistant/browser/controller.cc
+++ b/chromium/components/autofill_assistant/browser/controller.cc
@@ -6,11 +6,15 @@
#include <utility>
+#include "base/bind.h"
#include "base/json/json_writer.h"
+#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
+#include "base/time/tick_clock.h"
#include "base/values.h"
+#include "components/autofill_assistant/browser/features.h"
#include "components/autofill_assistant/browser/metrics.h"
#include "components/autofill_assistant/browser/protocol_utils.h"
#include "components/autofill_assistant/browser/ui_controller.h"
@@ -32,12 +36,9 @@ static constexpr base::TimeDelta kPeriodicScriptCheckInterval =
base::TimeDelta::FromSeconds(2);
// Number of script checks to run after a call to StartPeriodicScriptChecks.
+// This limit does not apply when in autostart mode.
static constexpr int kPeriodicScriptCheckCount = 10;
-// Maximum number of script checks we should do before failing when trying to
-// autostart.
-static constexpr int kAutostartCheckCountLimit = 5;
-
// The initial progress to set when autostarting and showing the "Loading..."
// message.
static constexpr int kAutostartInitialProgress = 10;
@@ -53,28 +54,24 @@ static const char* const kWebsiteVisitedBeforeParameterName =
"WEBSITE_VISITED_BEFORE";
static const char* const kTrueValue = "true";
-
} // namespace
-Controller::Controller(content::WebContents* web_contents, Client* client)
+Controller::Controller(content::WebContents* web_contents,
+ Client* client,
+ const base::TickClock* tick_clock)
: content::WebContentsObserver(web_contents),
client_(client),
- weak_ptr_factory_(this) {
- // Only set the controller as the delegate if web_contents does not yet have
- // one.
- // TODO(crbug.com/806868): Find a better way to get a loading progress instead
- // of using the controller as a web_contents delegate. It may interfere with
- // an already existing delegate.
- if (web_contents->GetDelegate() == nullptr) {
- clear_web_contents_delegate_ = true;
- web_contents->SetDelegate(this);
- }
-}
+ tick_clock_(tick_clock),
+ weak_ptr_factory_(this) {}
-Controller::~Controller() {
- if (clear_web_contents_delegate_) {
- web_contents()->SetDelegate(nullptr);
- }
+Controller::~Controller() = default;
+
+const GURL& Controller::GetCurrentURL() {
+ const GURL& last_committed = web_contents()->GetLastCommittedURL();
+ if (!last_committed.is_empty())
+ return last_committed;
+
+ return initial_url_;
}
Service* Controller::GetService() {
@@ -85,6 +82,17 @@ Service* Controller::GetService() {
}
UiController* Controller::GetUiController() {
+ if (will_shutdown_) {
+ // Never call the UI controller after having announced a shutdown, no matter
+ // what happens; this is part of the contract of UIDelegate.
+ //
+ // TODO(crbug/925947): Once UIController has become observer, clear list of
+ // observers instead.
+ if (!noop_ui_controller_) {
+ noop_ui_controller_ = std::make_unique<UiController>();
+ }
+ return noop_ui_controller_.get();
+ }
return client_->GetUiController();
}
@@ -127,28 +135,137 @@ std::string Controller::GetStatusMessage() const {
return status_message_;
}
-void Controller::SetDetails(const Details& details) {
- if (!details_) {
- details_ = std::make_unique<Details>();
- }
- *details_ = details;
+void Controller::SetDetails(std::unique_ptr<Details> details) {
+ details_ = std::move(details);
GetUiController()->OnDetailsChanged(details_.get());
}
-void Controller::ClearDetails() {
- details_.reset();
- GetUiController()->OnDetailsChanged(nullptr);
-}
-
const Details* Controller::GetDetails() const {
return details_.get();
}
+int Controller::GetProgress() const {
+ return progress_;
+}
+
+void Controller::SetInfoBox(const InfoBox& info_box) {
+ if (!info_box_) {
+ info_box_ = std::make_unique<InfoBox>();
+ }
+ *info_box_ = info_box;
+ GetUiController()->OnInfoBoxChanged(info_box_.get());
+}
+
+void Controller::ClearInfoBox() {
+ info_box_.reset();
+ GetUiController()->OnInfoBoxChanged(nullptr);
+}
+
+const InfoBox* Controller::GetInfoBox() const {
+ return info_box_.get();
+}
+
+void Controller::SetProgress(int progress) {
+ // Progress can only increase.
+ if (progress_ >= progress)
+ return;
+
+ progress_ = progress;
+ GetUiController()->OnProgressChanged(progress);
+}
+
+void Controller::SetProgressVisible(bool visible) {
+ if (progress_visible_ == visible)
+ return;
+
+ progress_visible_ = visible;
+ GetUiController()->OnProgressVisibilityChanged(visible);
+}
+
+bool Controller::GetProgressVisible() const {
+ return progress_visible_;
+}
+
+const std::vector<Chip>& Controller::GetSuggestions() const {
+ static const base::NoDestructor<std::vector<Chip>> no_suggestions_;
+ return suggestions_ ? *suggestions_ : *no_suggestions_;
+}
+
+const std::vector<Chip>& Controller::GetActions() const {
+ static const base::NoDestructor<std::vector<Chip>> no_actions_;
+ return actions_ ? *actions_ : *no_actions_;
+}
+
+void Controller::SetChips(std::unique_ptr<std::vector<Chip>> chips) {
+ // We split the chips into suggestions and actions, that are displayed in
+ // different carousels.
+ actions_.reset();
+ suggestions_.reset();
+
+ if (chips && !chips->empty()) {
+ for (auto iter = chips->begin(); iter != chips->end(); iter++) {
+ if (iter->type == SUGGESTION) {
+ if (!suggestions_) {
+ suggestions_ = std::make_unique<std::vector<Chip>>();
+ }
+
+ suggestions_->emplace_back(std::move(*iter));
+ } else {
+ if (!actions_) {
+ actions_ = std::make_unique<std::vector<Chip>>();
+ }
+
+ actions_->emplace_back(std::move(*iter));
+ }
+ }
+ }
+
+ GetUiController()->OnSuggestionsChanged(GetSuggestions());
+ GetUiController()->OnActionsChanged(GetActions());
+}
+
+void Controller::SelectSuggestion(int index) {
+ SelectChip(suggestions_.get(), index);
+}
+
+void Controller::SelectAction(int index) {
+ SelectChip(actions_.get(), index);
+}
+
+void Controller::SelectChip(std::vector<Chip>* chips, int chip_index) {
+ if (!chips || chip_index < 0 ||
+ static_cast<size_t>(chip_index) >= chips->size()) {
+ NOTREACHED() << "Invalid chip index: " << chip_index;
+ return;
+ }
+
+ if (!(*chips)[chip_index].callback) {
+ return;
+ }
+
+ // If the button clicked is not the Cancel button, then we clear the
+ // current chips and run the callback.
+ auto callback = std::move((*chips)[chip_index].callback);
+ SetChips(nullptr);
+ std::move(callback).Run();
+}
+
+void Controller::StopAndShutdown(Metrics::DropOutReason reason) {
+ ClearInfoBox();
+ SetDetails(nullptr);
+ SetChips(nullptr);
+ SetPaymentRequestOptions(nullptr);
+ EnterState(AutofillAssistantState::STOPPED);
+ client_->Shutdown(reason);
+}
+
void Controller::EnterState(AutofillAssistantState state) {
- if (state_ == state)
+ if (state_ == state || state_ == AutofillAssistantState::STOPPED)
return;
- DCHECK_NE(state_, AutofillAssistantState::STOPPED)
- << "Unexpected transition from STOPPED to " << static_cast<int>(state);
+ // TODO(b/128300038): Forbid transition out of stopped again instead of
+ // ignoring it once shutdown sequence is less complex.
+
+ DVLOG(2) << __func__ << ": " << state_ << " -> " << state;
state_ = state;
GetUiController()->OnStateChanged(state);
@@ -161,14 +278,16 @@ void Controller::SetWebControllerAndServiceForTest(
service_ = std::move(service);
}
-void Controller::GetOrCheckScripts(const GURL& url) {
+void Controller::GetOrCheckScripts() {
if (!started_ || script_tracker()->running()) {
return;
}
+ const GURL& url = GetCurrentURL();
if (script_domain_ != url.host()) {
StopPeriodicScriptChecks();
script_domain_ = url.host();
+ DVLOG(2) << "GetScripts for " << script_domain_;
GetService()->GetScriptsForUrl(
url, parameters_,
base::BindOnce(&Controller::OnGetScripts, base::Unretained(this), url));
@@ -197,21 +316,26 @@ void Controller::StopPeriodicScriptChecks() {
}
void Controller::OnPeriodicScriptCheck() {
- if (periodic_script_check_count_ <= 0) {
+ if (periodic_script_check_count_ > 0) {
+ periodic_script_check_count_--;
+ }
+
+ if (periodic_script_check_count_ <= 0 && !allow_autostart_) {
DCHECK_EQ(0, periodic_script_check_count_);
periodic_script_check_scheduled_ = false;
return;
}
- if (should_fail_after_checking_scripts_ &&
- ++total_script_check_count_ >= kAutostartCheckCountLimit) {
- should_fail_after_checking_scripts_ = false;
- OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR),
- Metrics::AUTOSTART_TIMEOUT);
+ if (allow_autostart_ && !autostart_timeout_script_path_.empty() &&
+ tick_clock_->NowTicks() >= absolute_autostart_timeout_) {
+ DVLOG(1) << __func__ << " giving up waiting on autostart.";
+ std::string script_path = autostart_timeout_script_path_;
+ autostart_timeout_script_path_.clear();
+ periodic_script_check_scheduled_ = false;
+ ExecuteScript(script_path, state_);
return;
}
- periodic_script_check_count_--;
script_tracker()->CheckScripts(kPeriodicScriptCheckInterval);
base::PostDelayedTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
@@ -232,20 +356,47 @@ void Controller::OnGetScripts(const GURL& url,
return;
if (!result) {
- LOG(ERROR) << "Failed to get assistant scripts for URL " << url.spec();
- // TODO(crbug.com/806868): Terminate Autofill Assistant.
+ DVLOG(1) << "Failed to get assistant scripts for " << script_domain_;
+ OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR),
+ Metrics::GET_SCRIPTS_FAILED);
+ return;
+ }
+
+ SupportsScriptResponseProto response_proto;
+ if (!response_proto.ParseFromString(response)) {
+ DVLOG(2) << __func__ << " from " << script_domain_ << " returned "
+ << "unparseable response";
+ OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR),
+ Metrics::GET_SCRIPTS_UNPARSABLE);
return;
}
std::vector<std::unique_ptr<Script>> scripts;
- bool parse_result = ProtocolUtils::ParseScripts(response, &scripts);
- DCHECK(parse_result);
+ for (const auto& script_proto : response_proto.scripts()) {
+ ProtocolUtils::AddScript(script_proto, &scripts);
+ }
+ if (scripts.empty()) {
+ OnNoRunnableScripts();
+ return;
+ }
+
+ if (allow_autostart_) {
+ autostart_timeout_script_path_ =
+ response_proto.script_timeout_error().script_path();
+ autostart_timeout_ = base::TimeDelta::FromMilliseconds(
+ response_proto.script_timeout_error().timeout_ms());
+ absolute_autostart_timeout_ = tick_clock_->NowTicks() + autostart_timeout_;
+ }
+
+ DVLOG(2) << __func__ << " from " << script_domain_ << " returned "
+ << scripts.size() << " scripts";
script_tracker()->SetScripts(std::move(scripts));
script_tracker()->CheckScripts(kPeriodicScriptCheckInterval);
StartPeriodicScriptChecks();
}
-void Controller::ExecuteScript(const std::string& script_path) {
+void Controller::ExecuteScript(const std::string& script_path,
+ AutofillAssistantState end_state) {
DCHECK(!script_tracker()->running());
EnterState(AutofillAssistantState::RUNNING);
@@ -254,20 +405,22 @@ void Controller::ExecuteScript(const std::string& script_path) {
StopPeriodicScriptChecks();
// Runnable scripts will be checked and reported if necessary after executing
// the script.
- script_tracker()->ClearRunnableScripts();
- GetUiController()->ClearChips();
+ script_tracker_->ClearRunnableScripts();
+ SetChips(nullptr);
// TODO(crbug.com/806868): Consider making ClearRunnableScripts part of
// ExecuteScripts to simplify the controller.
script_tracker()->ExecuteScript(
- script_path, base::BindOnce(&Controller::OnScriptExecuted,
- // script_tracker_ is owned by Controller.
- base::Unretained(this), script_path));
+ script_path,
+ base::BindOnce(&Controller::OnScriptExecuted,
+ // script_tracker_ is owned by Controller.
+ base::Unretained(this), script_path, end_state));
}
void Controller::OnScriptExecuted(const std::string& script_path,
+ AutofillAssistantState end_state,
const ScriptExecutor::Result& result) {
if (!result.success) {
- LOG(ERROR) << "Failed to execute script " << script_path;
+ DVLOG(1) << "Failed to execute script " << script_path;
OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR),
Metrics::SCRIPT_FAILED);
return;
@@ -279,26 +432,27 @@ void Controller::OnScriptExecuted(const std::string& script_path,
switch (result.at_end) {
case ScriptExecutor::SHUTDOWN:
- GetUiController()->Shutdown(Metrics::SCRIPT_SHUTDOWN);
+ client_->Shutdown(Metrics::SCRIPT_SHUTDOWN);
return;
+
case ScriptExecutor::TERMINATE:
// TODO(crbug.com/806868): Distinguish shutdown from terminate: Users
// should be allowed to undo shutdown, but not terminate.
//
- // This is coming from a client Stop() to clean up and we already counted
- // it as a stop event. The code here is only executed if no script was
- // running, so there may be some double counting.
- GetUiController()->Shutdown(Metrics::SAFETY_NET_TERMINATE);
+ // There should have been a previous call to Terminate() that set the
+ // reason, thus SAFETY_NET_TERMINATE should never be logged, unless
+ // there's a bug.
+ DCHECK_NE(terminate_reason_, Metrics::SAFETY_NET_TERMINATE);
+ client_->Shutdown(terminate_reason_);
return;
case ScriptExecutor::SHUTDOWN_GRACEFULLY:
GetWebController()->ClearCookie();
- stop_reason_ = Metrics::SCRIPT_SHUTDOWN;
- EnterState(AutofillAssistantState::STOPPED);
+ StopAndShutdown(Metrics::SCRIPT_SHUTDOWN);
return;
case ScriptExecutor::CLOSE_CUSTOM_TAB:
- GetUiController()->Close();
+ client_->Shutdown(Metrics::CUSTOM_TAB_CLOSED);
return;
case ScriptExecutor::RESTART:
@@ -311,33 +465,22 @@ void Controller::OnScriptExecuted(const std::string& script_path,
break;
default:
- DLOG(ERROR) << "Unexpected value for at_end: " << result.at_end;
+ DVLOG(1) << "Unexpected value for at_end: " << result.at_end;
break;
}
- EnterState(AutofillAssistantState::PROMPT);
- GetOrCheckScripts(web_contents()->GetLastCommittedURL());
-}
-
-void Controller::OnFatalError(const std::string& error_message,
- Metrics::DropOutReason reason) {
- if (state_ == AutofillAssistantState::STOPPED)
- return;
-
- StopPeriodicScriptChecks();
- SetStatusMessage(error_message);
- stop_reason_ = reason;
- EnterState(AutofillAssistantState::STOPPED);
+ EnterState(end_state);
+ GetOrCheckScripts();
}
bool Controller::MaybeAutostartScript(
const std::vector<ScriptHandle>& runnable_scripts) {
- // We want to g through all runnable autostart interrupts first, one at a
+ // We want to go through all runnable autostart interrupts first, one at a
// time. To do that, always run highest priority autostartable interrupt from
// runnable_script, which is ordered by priority.
for (const auto& script : runnable_scripts) {
if (script.autostart && script.interrupt) {
std::string script_path = script.path;
- ExecuteScript(script_path);
+ ExecuteScript(script_path, state_);
// making a copy of script.path is necessary, as ExecuteScript clears
// runnable_scripts, so script.path will not survive until the end of
// ExecuteScript.
@@ -359,67 +502,79 @@ bool Controller::MaybeAutostartScript(
}
}
if (autostart_count == 1) {
- allow_autostart_ = false;
- ExecuteScript(autostart_path);
+ DisableAutostart();
+ ExecuteScript(autostart_path, AutofillAssistantState::PROMPT);
return true;
}
}
return false;
}
-void Controller::OnGetCookie(const GURL& initial_url, bool has_cookie) {
+void Controller::DisableAutostart() {
+ allow_autostart_ = false;
+ autostart_timeout_script_path_.clear();
+}
+
+void Controller::OnGetCookie(bool has_cookie) {
if (has_cookie) {
// This code is only active with the experiment parameter.
parameters_.insert(
std::make_pair(kWebsiteVisitedBeforeParameterName, kTrueValue));
- OnSetCookie(initial_url, has_cookie);
+ OnSetCookie(has_cookie);
return;
}
GetWebController()->SetCookie(
- initial_url.host(),
+ initial_url_.host(),
base::BindOnce(&Controller::OnSetCookie,
// WebController is owned by Controller.
- base::Unretained(this), initial_url));
+ base::Unretained(this)));
}
-void Controller::OnSetCookie(const GURL& initial_url, bool result) {
+void Controller::OnSetCookie(bool result) {
DCHECK(result) << "Setting cookie failed";
- FinishStart(initial_url);
+ FinishStart();
}
-void Controller::FinishStart(const GURL& initial_url) {
+void Controller::FinishStart() {
started_ = true;
- GetOrCheckScripts(initial_url);
if (allow_autostart_) {
- should_fail_after_checking_scripts_ = true;
MaybeSetInitialDetails();
- SetStatusMessage(l10n_util::GetStringFUTF8(
- IDS_AUTOFILL_ASSISTANT_LOADING, base::UTF8ToUTF16(initial_url.host())));
- GetUiController()->ShowProgressBar(kAutostartInitialProgress);
+ SetStatusMessage(
+ l10n_util::GetStringFUTF8(IDS_AUTOFILL_ASSISTANT_LOADING,
+ base::UTF8ToUTF16(initial_url_.host())));
+ SetProgress(kAutostartInitialProgress);
}
+ GetOrCheckScripts();
}
void Controller::MaybeSetInitialDetails() {
- Details details;
- if (details.UpdateFromParameters(parameters_))
- SetDetails(details);
+ auto details = std::make_unique<Details>();
+ if (details->UpdateFromParameters(parameters_))
+ SetDetails(std::move(details));
}
-void Controller::Start(const GURL& initialUrl,
+bool Controller::NeedsUI() const {
+ return state_ != AutofillAssistantState::INACTIVE &&
+ state_ != AutofillAssistantState::STOPPED;
+}
+
+void Controller::Start(const GURL& initial_url,
const std::map<std::string, std::string>& parameters) {
if (state_ != AutofillAssistantState::INACTIVE) {
NOTREACHED();
return;
}
- EnterState(AutofillAssistantState::STARTING);
parameters_ = parameters;
+ initial_url_ = initial_url;
+ EnterState(AutofillAssistantState::STARTING);
+ client_->ShowUI();
if (IsCookieExperimentEnabled()) {
GetWebController()->HasCookie(
base::BindOnce(&Controller::OnGetCookie,
// WebController is owned by Controller.
- base::Unretained(this), initialUrl));
+ base::Unretained(this)));
} else {
- FinishStart(initialUrl);
+ FinishStart();
}
}
@@ -427,20 +582,23 @@ AutofillAssistantState Controller::GetState() {
return state_;
}
-bool Controller::Terminate() {
+bool Controller::Terminate(Metrics::DropOutReason reason) {
StopPeriodicScriptChecks();
- if (script_tracker_)
- return script_tracker_->Terminate();
+ if (!will_shutdown_) {
+ UiController* ui_controller = GetUiController();
+ will_shutdown_ = true;
+ ui_controller->WillShutdown(reason);
+ }
+ if (script_tracker_ && !script_tracker_->Terminate()) {
+ terminate_reason_ = reason;
+ return false;
+ }
return true;
}
void Controller::OnScriptSelected(const std::string& script_path) {
DCHECK(!script_path.empty());
-
- // This is a script selected from the UI, so it should disable autostart.
- allow_autostart_ = false;
-
- ExecuteScript(script_path);
+ ExecuteScript(script_path, AutofillAssistantState::PROMPT);
}
void Controller::UpdateTouchableArea() {
@@ -473,19 +631,55 @@ std::string Controller::GetDebugContext() {
return output_js;
}
-Metrics::DropOutReason Controller::GetDropOutReason() const {
- return stop_reason_;
+const PaymentRequestOptions* Controller::GetPaymentRequestOptions() const {
+ return payment_request_options_.get();
+}
+
+void Controller::SetPaymentInformation(
+ std::unique_ptr<PaymentInformation> payment_information) {
+ if (!payment_request_options_)
+ return;
+
+ auto callback = std::move(payment_request_options_->callback);
+ SetPaymentRequestOptions(nullptr);
+ std::move(callback).Run(std::move(payment_information));
+}
+
+void Controller::GetTouchableArea(std::vector<RectF>* area) const {
+ if (touchable_element_area_)
+ touchable_element_area_->GetRectangles(area);
}
-void Controller::OnNoRunnableScriptsAnymore() {
+void Controller::OnFatalError(const std::string& error_message,
+ Metrics::DropOutReason reason) {
+ LOG(ERROR) << "Autofill Assistant has encountered an error and is shutting "
+ "down, reason="
+ << reason;
+ if (state_ == AutofillAssistantState::STOPPED)
+ return;
+
+ StopPeriodicScriptChecks();
+ SetStatusMessage(error_message);
+ StopAndShutdown(reason);
+}
+
+void Controller::OnNoRunnableScripts() {
if (script_tracker()->running())
return;
+ if (state_ == AutofillAssistantState::STARTING) {
+ // We're still waiting for the set of initial scripts, but either didn't get
+ // any scripts or didn't get scripts that could possibly become runnable
+ // with a DOM change.
+ OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR),
+ Metrics::NO_INITIAL_SCRIPTS);
+ return;
+ }
+
// We're navigated to a page that has no scripts or the scripts have reached a
// state from which they cannot recover through a DOM change.
OnFatalError(l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP),
Metrics::NO_SCRIPTS);
- return;
}
void Controller::OnRunnableScriptsChanged(
@@ -495,10 +689,6 @@ void Controller::OnRunnableScriptsChanged(
if (script_tracker()->running() || state_ == AutofillAssistantState::STOPPED)
return;
- if (!runnable_scripts.empty()) {
- should_fail_after_checking_scripts_ = false;
- }
-
if (MaybeAutostartScript(runnable_scripts)) {
return;
}
@@ -513,52 +703,44 @@ void Controller::OnRunnableScriptsChanged(
}
// Update the set of scripts in the UI.
- // TODO(crbug.com/806868): Surface type in proto instead of guessing it from
- // highlight flag.
- Chip::Type non_highlight_type = Chip::Type::CHIP_ASSISTIVE;
- for (const auto& script : runnable_scripts) {
- if (!script.autostart && !script.name.empty() && script.highlight) {
- non_highlight_type = Chip::Type::BUTTON_TEXT;
- break;
- }
- }
-
auto chips = std::make_unique<std::vector<Chip>>();
for (const auto& script : runnable_scripts) {
if (!script.autostart && !script.name.empty()) {
chips->emplace_back();
- chips->back().type = script.highlight ? Chip::Type::BUTTON_FILLED_BLUE
- : non_highlight_type;
chips->back().text = script.name;
+ chips->back().type = script.chip_type;
chips->back().callback =
base::BindOnce(&Controller::OnScriptSelected,
weak_ptr_factory_.GetWeakPtr(), script.path);
}
}
+ SetDefaultChipType(chips.get());
- if (allow_autostart_) {
+ if (chips->empty() && state_ == AutofillAssistantState::STARTING) {
+ // Continue waiting
+ return;
+ }
+
+ if (allow_autostart_ ||
+ state_ == AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT) {
// Autostart was expected, but only non-autostartable scripts were found.
- //
- // TODO(crbug.com/806868): Consider the case where no non-autostartable
- // scripts were found.
+ DisableAutostart();
EnterState(AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT);
} else {
EnterState(AutofillAssistantState::PROMPT);
}
- GetUiController()->SetChips(std::move(chips));
+ SetChips(std::move(chips));
}
void Controller::DidAttachInterstitialPage() {
- GetUiController()->Shutdown(Metrics::INTERSTITIAL_PAGE);
+ client_->Shutdown(Metrics::INTERSTITIAL_PAGE);
}
void Controller::DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
// validated_url might not be the page URL. Ignore it and always check the
// last committed url.
- // Note that we also check for scripts in LoadProgressChanged below. This is
- // the last attempt and occurs later than a load progress of 1.0.
- GetOrCheckScripts(web_contents()->GetLastCommittedURL());
+ GetOrCheckScripts();
}
void Controller::DidStartNavigation(
@@ -590,27 +772,20 @@ void Controller::DidStartNavigation(
}
void Controller::DocumentAvailableInMainFrame() {
- GetOrCheckScripts(web_contents()->GetLastCommittedURL());
+ GetOrCheckScripts();
}
void Controller::RenderProcessGone(base::TerminationStatus status) {
- GetUiController()->Shutdown(Metrics::RENDER_PROCESS_GONE);
+ client_->Shutdown(Metrics::RENDER_PROCESS_GONE);
}
-void Controller::LoadProgressChanged(content::WebContents* source,
- double progress) {
- int percent = 100 * progress;
- // We wait for a page to be at least 40 percent loaded. Then a new
- // precondition check is started every additional 20 percent.
- if (percent >= 40 && percent % 20 == 0) {
- DCHECK(web_contents()->GetLastCommittedURL().is_valid());
- // In order to show available scripts as early as possible we start checking
- // preconditions when the page has not yet fully loaded. This can lead to
- // the behavior where scripts are being added sequentially instead of all
- // at the same time. Also, depending on the progress values, we may never
- // actually get here. In that case the only check will happen in
- // DidFinishLoad.
- GetOrCheckScripts(web_contents()->GetLastCommittedURL());
+void Controller::OnWebContentsFocused(
+ content::RenderWidgetHost* render_widget_host) {
+ if (NeedsUI() &&
+ base::FeatureList::IsEnabled(features::kAutofillAssistantChromeEntry)) {
+ // Show UI again when re-focused in case the web contents moved activity.
+ // This is only enabled when tab-switching is enabled.
+ client_->ShowUI();
}
}
@@ -619,14 +794,42 @@ bool Controller::IsCookieExperimentEnabled() const {
return iter != parameters_.end() && iter->second == "1";
}
+void Controller::OnTouchableAreaChanged(const std::vector<RectF>& areas) {
+ GetUiController()->OnTouchableAreaChanged(areas);
+}
+
+void Controller::SetPaymentRequestOptions(
+ std::unique_ptr<PaymentRequestOptions> options) {
+ DCHECK(!options || options->callback);
+
+ if (payment_request_options_ == nullptr && options == nullptr)
+ return;
+
+ payment_request_options_ = std::move(options);
+ GetUiController()->OnPaymentRequestChanged(payment_request_options_.get());
+}
+
+void Controller::CancelPaymentRequest() {
+ if (!payment_request_options_)
+ return;
+
+ auto callback = std::move(payment_request_options_->callback);
+ SetPaymentRequestOptions(nullptr);
+
+ if (!callback) {
+ NOTREACHED();
+ return;
+ }
+ auto result = std::make_unique<PaymentInformation>();
+ result->succeed = false;
+ std::move(callback).Run(std::move(result));
+}
+
ElementArea* Controller::touchable_element_area() {
if (!touchable_element_area_) {
touchable_element_area_ = std::make_unique<ElementArea>(this);
touchable_element_area_->SetOnUpdate(base::BindRepeating(
- &UiController::SetTouchableArea,
- // Unretained is safe, since touchable_element_area_ is guaranteed to be
- // deleted before the UI controller.
- base::Unretained(GetUiController())));
+ &Controller::OnTouchableAreaChanged, weak_ptr_factory_.GetWeakPtr()));
}
return touchable_element_area_.get();
}
diff --git a/chromium/components/autofill_assistant/browser/controller.h b/chromium/components/autofill_assistant/browser/controller.h
index cf9ceb7dd06..9ca624d12c9 100644
--- a/chromium/components/autofill_assistant/browser/controller.h
+++ b/chromium/components/autofill_assistant/browser/controller.h
@@ -15,6 +15,7 @@
#include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/element_area.h"
#include "components/autofill_assistant/browser/metrics.h"
+#include "components/autofill_assistant/browser/payment_request.h"
#include "components/autofill_assistant/browser/script.h"
#include "components/autofill_assistant/browser/script_executor_delegate.h"
#include "components/autofill_assistant/browser/script_tracker.h"
@@ -30,6 +31,10 @@ class RenderFrameHost;
class WebContents;
} // namespace content
+namespace base {
+class TickClock;
+} // namespace base
+
namespace autofill_assistant {
class ControllerTest;
@@ -39,24 +44,27 @@ class ControllerTest;
class Controller : public ScriptExecutorDelegate,
public UiDelegate,
public ScriptTracker::Listener,
- private content::WebContentsObserver,
- private content::WebContentsDelegate {
+ private content::WebContentsObserver {
public:
- // |web_contents| and |client| must remain valid for the lifetime of the
- // instance.
- Controller(content::WebContents* web_contents, Client* client);
+ // |web_contents|, |client| and |tick_clock| must remain valid for the
+ // lifetime of the instance.
+ Controller(content::WebContents* web_contents,
+ Client* client,
+ const base::TickClock* tick_clock);
~Controller() override;
+ // Returns true if the controller is in a state where UI is necessary.
+ bool NeedsUI() const;
+
// Called when autofill assistant can start executing scripts.
- void Start(const GURL& initialUrl,
+ void Start(const GURL& initial_url,
const std::map<std::string, std::string>& parameters);
// Initiates a clean shutdown.
//
// This function returns false when it needs more time to properly shut down
- // the script tracker. It usually means that it either has to wait for a
- // script to find an appropriate moment to suspend execution or wait for a
- // script checking round to complete.
+ // the script tracker. In that case, the controller is responsible for calling
+ // Client::Shutdown at the right time for the given reason.
//
// A caller is expected to try again later when this function returns false. A
// return value of true means that the scrip tracker can safely be destroyed.
@@ -64,9 +72,10 @@ class Controller : public ScriptExecutorDelegate,
// TODO(crbug.com/806868): Instead of this safety net, the proper fix is to
// switch to weak pointers everywhere so that dangling callbacks are not an
// issue.
- bool Terminate();
+ bool Terminate(Metrics::DropOutReason reason);
// Overrides ScriptExecutorDelegate:
+ const GURL& GetCurrentURL() override;
Service* GetService() override;
UiController* GetUiController() override;
WebController* GetWebController() override;
@@ -77,10 +86,41 @@ class Controller : public ScriptExecutorDelegate,
void SetTouchableElementArea(const ElementAreaProto& area) override;
void SetStatusMessage(const std::string& message) override;
std::string GetStatusMessage() const override;
- void SetDetails(const Details& details) override;
- void ClearDetails() override;
+ void SetDetails(std::unique_ptr<Details> details) override;
+ void SetInfoBox(const InfoBox& info_box) override;
+ void ClearInfoBox() override;
+ void SetProgress(int progress) override;
+ void SetProgressVisible(bool visible) override;
+ void SetChips(std::unique_ptr<std::vector<Chip>> chips) override;
+
+ // Stops the controller with |reason| and destroys this. The current status
+ // message must contain the error message.
+ void StopAndShutdown(Metrics::DropOutReason reason);
void EnterState(AutofillAssistantState state) override;
bool IsCookieExperimentEnabled() const;
+ void SetPaymentRequestOptions(
+ std::unique_ptr<PaymentRequestOptions> options) override;
+ void CancelPaymentRequest() override;
+
+ // Overrides autofill_assistant::UiDelegate:
+ AutofillAssistantState GetState() override;
+ void UpdateTouchableArea() override;
+ void OnUserInteractionInsideTouchableArea() override;
+ const Details* GetDetails() const override;
+ const InfoBox* GetInfoBox() const override;
+ int GetProgress() const override;
+ bool GetProgressVisible() const override;
+ const std::vector<Chip>& GetSuggestions() const override;
+ void SelectSuggestion(int index) override;
+ const std::vector<Chip>& GetActions() const override;
+ void SelectAction(int index) override;
+ std::string GetDebugContext() override;
+ const PaymentRequestOptions* GetPaymentRequestOptions() const override;
+ void SetPaymentInformation(
+ std::unique_ptr<PaymentInformation> payment_information) override;
+ void GetTouchableArea(std::vector<RectF>* area) const override;
+ void OnFatalError(const std::string& error_message,
+ Metrics::DropOutReason reason) override;
private:
friend ControllerTest;
@@ -89,10 +129,15 @@ class Controller : public ScriptExecutorDelegate,
std::unique_ptr<WebController> web_controller,
std::unique_ptr<Service> service);
- void GetOrCheckScripts(const GURL& url);
+ void GetOrCheckScripts();
void OnGetScripts(const GURL& url, bool result, const std::string& response);
- void ExecuteScript(const std::string& script_path);
+
+ // Execute |script_path| and, if execution succeeds, enter |end_state| and
+ // call |on_success|.
+ void ExecuteScript(const std::string& script_path,
+ AutofillAssistantState end_state);
void OnScriptExecuted(const std::string& script_path,
+ AutofillAssistantState end_state,
const ScriptExecutor::Result& result);
// Check script preconditions every few seconds for a certain number of times.
@@ -104,38 +149,28 @@ class Controller : public ScriptExecutorDelegate,
void StopPeriodicScriptChecks();
void OnPeriodicScriptCheck();
- // Shows the given message and stops the controller with |reason|.
- void OnFatalError(const std::string& error_message,
- Metrics::DropOutReason reason);
-
// Runs autostart scripts from |runnable_scripts|, if the conditions are
// right. Returns true if a script was auto-started.
bool MaybeAutostartScript(const std::vector<ScriptHandle>& runnable_scripts);
+ void DisableAutostart();
+
// Autofill Assistant cookie logic.
//
// On startup of the controller we set a cookie. If a cookie already existed
// for the intial URL, we show a warning that the website has already been
// visited and could contain old data. The cookie is cleared (or expires) when
// a script terminated with a Stop action.
- void OnGetCookie(const GURL& initial_url, bool has_cookie);
- void OnSetCookie(const GURL& initial_url, bool result);
- void FinishStart(const GURL& initial_url);
+ void OnGetCookie(bool has_cookie);
+ void OnSetCookie(bool result);
+ void FinishStart();
void MaybeSetInitialDetails();
// Called when a script is selected.
void OnScriptSelected(const std::string& script_path);
- // Overrides autofill_assistant::UiDelegate:
- AutofillAssistantState GetState() override;
- void UpdateTouchableArea() override;
- void OnUserInteractionInsideTouchableArea() override;
- const Details* GetDetails() const override;
- std::string GetDebugContext() override;
- Metrics::DropOutReason GetDropOutReason() const override;
-
// Overrides ScriptTracker::Listener:
- void OnNoRunnableScriptsAnymore() override;
+ void OnNoRunnableScripts() override;
void OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) override;
@@ -147,15 +182,20 @@ class Controller : public ScriptExecutorDelegate,
content::NavigationHandle* navigation_handle) override;
void DocumentAvailableInMainFrame() override;
void RenderProcessGone(base::TerminationStatus status) override;
+ void OnWebContentsFocused(
+ content::RenderWidgetHost* render_widget_host) override;
- // Overrides content::WebContentsDelegate:
- void LoadProgressChanged(content::WebContents* source,
- double progress) override;
+ void OnTouchableAreaChanged(const std::vector<RectF>& areas);
+
+ void SelectChip(std::vector<Chip>* chips, int chip_index);
ElementArea* touchable_element_area();
ScriptTracker* script_tracker();
Client* const client_;
+ const base::TickClock* const tick_clock_;
+
+ std::unique_ptr<UiController> noop_ui_controller_;
// Lazily instantiate in GetWebController().
std::unique_ptr<WebController> web_controller_;
@@ -169,6 +209,9 @@ class Controller : public ScriptExecutorDelegate,
AutofillAssistantState state_ = AutofillAssistantState::INACTIVE;
+ // The URL passed to Start(). Used only as long as there's no committed URL.
+ GURL initial_url_;
+
// Domain of the last URL the controller requested scripts from.
std::string script_domain_;
bool allow_autostart_ = true;
@@ -178,15 +221,18 @@ class Controller : public ScriptExecutorDelegate,
// Number of remaining periodic checks.
int periodic_script_check_count_ = 0;
- int total_script_check_count_ = 0;
- // Whether to clear the web_contents delegate when the controller is
- // destroyed.
- bool clear_web_contents_delegate_ = false;
+ // Run this script if no scripts become autostartable after
+ // absolute_autostart_timeout.
+ //
+ // Ignored unless |allow_autostart_| is true.
+ std::string autostart_timeout_script_path_;
+
+ // How long to wait for an autostartable script before failing.
+ base::TimeDelta autostart_timeout_;
- // Whether we should hide the overlay and show an error message after a first
- // unsuccessful round of preconditions checking.
- bool should_fail_after_checking_scripts_ = false;
+ // Ticks at which we'll have reached |autostart_timeout_|.
+ base::TimeTicks absolute_autostart_timeout_;
// Area of the screen that corresponds to the current set of touchable
// elements.
@@ -199,11 +245,32 @@ class Controller : public ScriptExecutorDelegate,
// Current details, may be null.
std::unique_ptr<Details> details_;
+ // Current info box, may be null.
+ std::unique_ptr<InfoBox> info_box_;
+
+ // Current progress.
+ int progress_ = 0;
+
+ // Current visibility of the progress bar. It is initially visible.
+ bool progress_visible_ = true;
+
+ // Current set of suggestions. May be null, but never empty.
+ std::unique_ptr<std::vector<Chip>> suggestions_;
+
+ // Current set of actions. May be null, but never empty.
+ std::unique_ptr<std::vector<Chip>> actions_;
+
// Flag indicates whether it is ready to fetch and execute scripts.
bool started_ = false;
- // Drop out reason set when the controller enters a STOPPED state.
- Metrics::DropOutReason stop_reason_ = Metrics::AA_START;
+ // A reason passed previously to Terminate(). SAFETY_NET_TERMINATE is a
+ // placeholder.
+ Metrics::DropOutReason terminate_reason_ = Metrics::SAFETY_NET_TERMINATE;
+
+ // True once UiController::WillShutdown has been called.
+ bool will_shutdown_ = false;
+
+ std::unique_ptr<PaymentRequestOptions> payment_request_options_;
// Tracks scripts and script execution. It's kept at the end, as it tend to
// depend on everything the controller support, through script and script
diff --git a/chromium/components/autofill_assistant/browser/controller_unittest.cc b/chromium/components/autofill_assistant/browser/controller_unittest.cc
index 9df02460e54..bdd246462ad 100644
--- a/chromium/components/autofill_assistant/browser/controller_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/controller_unittest.cc
@@ -8,22 +8,28 @@
#include <utility>
#include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/autofill_assistant/browser/features.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_service.h"
#include "components/autofill_assistant/browser/mock_ui_controller.h"
#include "components/autofill_assistant/browser/mock_web_controller.h"
#include "components/autofill_assistant/browser/service.h"
-#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace autofill_assistant {
using ::testing::_;
+using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::Eq;
+using ::testing::Field;
+using ::testing::Gt;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::NiceMock;
@@ -55,7 +61,9 @@ class FakeClient : public Client {
std::string GetAccountEmailAddress() override { return ""; }
std::string GetLocale() override { return ""; }
std::string GetCountryCode() override { return ""; }
- void Stop() override {}
+ MOCK_METHOD1(Shutdown, void(Metrics::DropOutReason reason));
+ MOCK_METHOD0(ShowUI, void());
+ MOCK_METHOD0(DestroyUI, void());
private:
UiController* ui_controller_;
@@ -63,20 +71,27 @@ class FakeClient : public Client {
} // namespace
-class ControllerTest : public content::RenderViewHostTestHarness {
+class ControllerTest : public testing::Test {
public:
- ControllerTest() : fake_client_(&mock_ui_controller_) {}
+ ControllerTest()
+ : thread_bundle_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME),
+ web_contents_(
+ content::WebContentsTester::CreateTestWebContents(&browser_context_,
+ nullptr)),
+ fake_client_(&mock_ui_controller_) {}
~ControllerTest() override {}
void SetUp() override {
- content::RenderViewHostTestHarness::SetUp();
-
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillAssistantChromeEntry);
auto web_controller = std::make_unique<NiceMock<MockWebController>>();
mock_web_controller_ = web_controller.get();
auto service = std::make_unique<NiceMock<MockService>>();
mock_service_ = service.get();
- controller_ = std::make_unique<Controller>(web_contents(), &fake_client_);
+ controller_ = std::make_unique<Controller>(
+ web_contents_.get(), &fake_client_, thread_bundle_.GetMockTickClock());
controller_->SetWebControllerAndServiceForTest(std::move(web_controller),
std::move(service));
@@ -88,23 +103,16 @@ class ControllerTest : public content::RenderViewHostTestHarness {
ON_CALL(*mock_service_, OnGetActions(_, _, _, _, _, _))
.WillByDefault(RunOnceCallback<5>(true, ""));
- // Make WebController::GetUrl accessible.
- ON_CALL(*mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_));
+ ON_CALL(*mock_service_, OnGetNextActions(_, _, _, _))
+ .WillByDefault(RunOnceCallback<3>(true, ""));
ON_CALL(mock_ui_controller_, OnStateChanged(_))
.WillByDefault(Invoke([this](AutofillAssistantState state) {
states_.emplace_back(state);
}));
- tester_ = content::WebContentsTester::For(web_contents());
- }
-
- void TearDown() override {
- // Controller must be deleted before the WebContents, owned by
- // RenderViewHostTestHarness. In production, this is guaranteed by
- // autofill_assistant::ClientAndroid, which owns Controller.
- controller_.reset();
- content::RenderViewHostTestHarness::TearDown();
+ ON_CALL(*mock_web_controller_, OnElementCheck(_, _, _))
+ .WillByDefault(RunOnceCallback<2>(false));
}
protected:
@@ -125,14 +133,23 @@ class ControllerTest : public content::RenderViewHostTestHarness {
run_once->set_status(SCRIPT_STATUS_NOT_RUN);
}
- void Start() {
- GURL initialUrl("http://initialurl.com");
- controller_->Start(initialUrl, /* parameters= */ {});
+ void SetupScriptsForURL(const std::string& url,
+ SupportsScriptResponseProto scripts) {
+ std::string scripts_str;
+ scripts.SerializeToString(&scripts_str);
+ EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(GURL(url)), _, _))
+ .WillOnce(RunOnceCallback<2>(true, scripts_str));
+ }
+
+ void Start() { Start("http://initialurl.com"); }
+
+ void Start(const std::string& url) {
+ controller_->Start(GURL(url), /* parameters= */ {});
}
void SetLastCommittedUrl(const GURL& url) {
- url_ = url;
- tester_->SetLastCommittedURL(url);
+ content::WebContentsTester::For(web_contents_.get())
+ ->SetLastCommittedURL(url);
}
// Updates the current url of the controller and forces a refresh, without
@@ -142,8 +159,8 @@ class ControllerTest : public content::RenderViewHostTestHarness {
controller_->DidFinishLoad(nullptr, url);
}
- void SimulateProgressChanged(double progress) {
- controller_->LoadProgressChanged(web_contents(), progress);
+ void SimulateWebContentsFocused() {
+ controller_->OnWebContentsFocused(nullptr);
}
// Sets up the next call to the service for scripts to return |response|.
@@ -164,68 +181,121 @@ class ControllerTest : public content::RenderViewHostTestHarness {
.WillRepeatedly(RunOnceCallback<2>(true, response_str));
}
- void ExecuteScript(const std::string& script_path) {
- controller_->OnScriptSelected(script_path);
- }
-
UiDelegate* GetUiDelegate() { return controller_.get(); }
- GURL url_;
+ // |thread_bundle_| must be the first field, to make sure that everything runs
+ // in the same task environment.
+ content::TestBrowserThreadBundle thread_bundle_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+ content::TestBrowserContext browser_context_;
+ std::unique_ptr<content::WebContents> web_contents_;
+ base::TimeTicks now_;
std::vector<AutofillAssistantState> states_;
MockService* mock_service_;
MockWebController* mock_web_controller_;
- FakeClient fake_client_;
+ NiceMock<FakeClient> fake_client_;
NiceMock<MockUiController> mock_ui_controller_;
- content::WebContentsTester* tester_;
std::unique_ptr<Controller> controller_;
};
TEST_F(ControllerTest, FetchAndRunScripts) {
- Start();
-
- // Going to the URL triggers a whole flow:
- // 1. loading scripts
SupportsScriptResponseProto script_response;
AddRunnableScript(&script_response, "script1");
- AddRunnableScript(&script_response, "script2");
+ auto* script2 = AddRunnableScript(&script_response, "script2");
+ RunOnce(script2);
SetNextScriptResponse(script_response);
- // 2. checking the scripts
- // 3. offering the choices: script1 and script2
- // 4. script1 is chosen
- EXPECT_CALL(mock_ui_controller_, SetChips(Pointee(SizeIs(2))))
- .WillOnce([this](std::unique_ptr<std::vector<Chip>> chips) {
- std::vector<std::string> texts;
- for (const auto& chip : *chips) {
- texts.emplace_back(chip.text);
- }
- EXPECT_THAT(texts, UnorderedElementsAre("script1", "script2"));
-
- Sequence sequence;
- // Selecting a script should clean the bottom bar.
- EXPECT_CALL(mock_ui_controller_, ClearChips()).InSequence(sequence);
- // After the script is done both scripts are again valid and should be
- // shown.
- EXPECT_CALL(mock_ui_controller_, SetChips(Pointee(SizeIs(2))))
- .InSequence(sequence);
-
- std::move((*chips)[0].callback).Run();
- });
-
- // 5. script1 run successfully (no actions).
- EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script1"), _, _, _, _, _))
+ testing::InSequence seq;
+
+ Start("http://a.example.com/path");
+
+ // Offering the choices: script1 and script2
+ EXPECT_EQ(AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT,
+ controller_->GetState());
+ EXPECT_THAT(controller_->GetSuggestions(),
+ UnorderedElementsAre(Field(&Chip::text, StrEq("script1")),
+ Field(&Chip::text, StrEq("script2"))));
+
+ // Choose script2 and run it successfully.
+ EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script2"), _, _, _, _, _))
.WillOnce(RunOnceCallback<5>(true, ""));
+ controller_->SelectSuggestion(1);
- // 6. As nothing is selected the flow terminates.
+ // Offering the remaining choice: script1 as script2 can only run once.
+ EXPECT_EQ(AutofillAssistantState::PROMPT, controller_->GetState());
+ EXPECT_THAT(controller_->GetSuggestions(),
+ ElementsAre(Field(&Chip::text, StrEq("script1"))));
+}
- // Start the flow.
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+TEST_F(ControllerTest, NoScripts) {
+ SupportsScriptResponseProto empty;
+ SetNextScriptResponse(empty);
+
+ Start("http://a.example.com/path");
+ EXPECT_EQ(AutofillAssistantState::STOPPED, controller_->GetState());
}
-TEST_F(ControllerTest, ShowFirstInitialPrompt) {
- Start();
+TEST_F(ControllerTest, NoRelevantScripts) {
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "no_match")
+ ->mutable_presentation()
+ ->mutable_precondition()
+ ->add_domain("http://otherdomain.com");
+ SetNextScriptResponse(script_response);
+
+ Start("http://a.example.com/path");
+ EXPECT_EQ(AutofillAssistantState::STOPPED, controller_->GetState());
+}
+
+TEST_F(ControllerTest, NoRelevantScriptYet) {
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "no_match_yet")
+ ->mutable_presentation()
+ ->mutable_precondition()
+ ->add_elements_exist()
+ ->add_selectors("#element");
+ SetNextScriptResponse(script_response);
+ Start("http://a.example.com/path");
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+}
+TEST_F(ControllerTest, ReportPromptAndSuggestionsChanged) {
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "script1");
+ AddRunnableScript(&script_response, "script2");
+ SetNextScriptResponse(script_response);
+
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(SizeIs(2)));
+ Start("http://a.example.com/path");
+
+ EXPECT_EQ(AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT,
+ controller_->GetState());
+}
+
+TEST_F(ControllerTest, ClearChipsWhenRunning) {
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "script1");
+ AddRunnableScript(&script_response, "script2");
+ SetNextScriptResponse(script_response);
+
+ // Discover 2 scripts, one is selected and run (with no chips shown), then the
+ // same chips are shown.
+ {
+ testing::InSequence seq;
+ // Discover 2 scripts, script1 and script2.
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(SizeIs(2)));
+ // Set of chips is cleared while running script1.
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(SizeIs(0)));
+ // This test doesn't specify what happens after that.
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(_))
+ .Times(AnyNumber());
+ }
+ Start("http://a.example.com/path");
+ controller_->SelectSuggestion(0);
+}
+
+TEST_F(ControllerTest, ShowFirstInitialStatusMessage) {
SupportsScriptResponseProto script_response;
AddRunnableScript(&script_response, "script1");
@@ -246,16 +316,17 @@ TEST_F(ControllerTest, ShowFirstInitialPrompt) {
SetNextScriptResponse(script_response);
- // Script3, with higher priority (lower number), wins.
- EXPECT_CALL(mock_ui_controller_, OnStatusMessageChanged("script3 prompt"));
- EXPECT_CALL(mock_ui_controller_, SetChips(Pointee(SizeIs(4))));
+ Start("http://a.example.com/path");
- // Start the flow.
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+ EXPECT_THAT(controller_->GetSuggestions(), SizeIs(4));
+ // Script3, with higher priority (lower number), wins.
+ EXPECT_EQ("script3 prompt", controller_->GetStatusMessage());
}
TEST_F(ControllerTest, Stop) {
- Start();
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "stop");
+ SetNextScriptResponse(script_response);
ActionsResponseProto actions_response;
actions_response.add_actions()->mutable_stop();
@@ -263,36 +334,34 @@ TEST_F(ControllerTest, Stop) {
actions_response.SerializeToString(&actions_response_str);
EXPECT_CALL(*mock_service_, OnGetActions(StrEq("stop"), _, _, _, _, _))
.WillOnce(RunOnceCallback<5>(true, actions_response_str));
- EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _))
- .WillOnce(RunOnceCallback<3>(true, ""));
- EXPECT_CALL(mock_ui_controller_, Shutdown(_));
+ Start();
+ ASSERT_THAT(controller_->GetSuggestions(), SizeIs(1));
+
+ testing::InSequence seq;
+ EXPECT_CALL(fake_client_, Shutdown(Metrics::SCRIPT_SHUTDOWN));
+ controller_->SelectSuggestion(0);
- ExecuteScript("stop");
+ // Simulates Client::Shutdown(SCRIPT_SHUTDOWN)
+ EXPECT_CALL(mock_ui_controller_, WillShutdown(Metrics::SCRIPT_SHUTDOWN));
+ EXPECT_TRUE(controller_->Terminate(Metrics::SCRIPT_SHUTDOWN));
}
TEST_F(ControllerTest, Reset) {
- Start();
- {
- InSequence sequence;
-
// 1. Fetch scripts for URL, which in contains a single "reset" script.
SupportsScriptResponseProto script_response;
- AddRunnableScript(&script_response, "reset");
+ auto* reset_script = AddRunnableScript(&script_response, "reset");
+ RunOnce(reset_script);
std::string script_response_str;
script_response.SerializeToString(&script_response_str);
EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _))
- .WillOnce(RunOnceCallback<2>(true, script_response_str));
-
- // 2. Execute the "reset" script, which contains a reset action.
- EXPECT_CALL(mock_ui_controller_, SetChips(Pointee(SizeIs(1))))
- .WillOnce([](std::unique_ptr<std::vector<Chip>> chips) {
- std::move((*chips)[0].callback).Run();
- });
+ .WillRepeatedly(RunOnceCallback<2>(true, script_response_str));
- // Selecting a script should clean the bottom bar.
- EXPECT_CALL(mock_ui_controller_, ClearChips());
+ Start("http://a.example.com/path");
+ EXPECT_THAT(controller_->GetSuggestions(),
+ ElementsAre(Field(&Chip::text, StrEq("reset"))));
+ // 2. Execute the "reset" script, which contains a reset action.
ActionsResponseProto actions_response;
actions_response.add_actions()->mutable_reset();
std::string actions_response_str;
@@ -300,30 +369,22 @@ TEST_F(ControllerTest, Reset) {
EXPECT_CALL(*mock_service_, OnGetActions(StrEq("reset"), _, _, _, _, _))
.WillOnce(RunOnceCallback<5>(true, actions_response_str));
- // 3. Report the result of running that action.
- EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _))
- .WillOnce(RunOnceCallback<3>(true, ""));
+ controller_->GetClientMemory()->set_selected_card(
+ std::make_unique<autofill::CreditCard>());
+ EXPECT_TRUE(controller_->GetClientMemory()->has_selected_card());
- // 4. The reset action forces a reload of the scripts, even though the URL
- // hasn't changed. The "reset" script is reported again to UpdateScripts.
- EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _))
- .WillOnce(RunOnceCallback<2>(true, script_response_str));
-
- // Reset forces the controller to fetch the scripts twice, even though the
- // URL doesn't change..
- EXPECT_CALL(mock_ui_controller_, SetChips(Pointee(SizeIs(1))));
- }
+ controller_->SelectSuggestion(0);
- // Resetting should clear the client memory
- controller_->GetClientMemory()->set_selected_card(nullptr);
-
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+ // Resetting should have cleared the client memory
+ EXPECT_FALSE(controller_->GetClientMemory()->has_selected_card());
- EXPECT_FALSE(controller_->GetClientMemory()->selected_card());
+ // The reset script should be available again, even though it's marked
+ // RunOnce, as the script state should have been cleared as well.
+ EXPECT_THAT(controller_->GetSuggestions(),
+ ElementsAre(Field(&Chip::text, StrEq("reset"))));
}
TEST_F(ControllerTest, RefreshScriptWhenDomainChanges) {
- Start();
EXPECT_CALL(*mock_service_,
OnGetScriptsForUrl(Eq(GURL("http://a.example.com/path1")), _, _))
@@ -332,7 +393,7 @@ TEST_F(ControllerTest, RefreshScriptWhenDomainChanges) {
OnGetScriptsForUrl(Eq(GURL("http://b.example.com/path1")), _, _))
.WillOnce(RunOnceCallback<2>(true, ""));
- SimulateNavigateToUrl(GURL("http://a.example.com/path1"));
+ Start("http://a.example.com/path1");
SimulateNavigateToUrl(GURL("http://a.example.com/path2"));
SimulateNavigateToUrl(GURL("http://b.example.com/path1"));
SimulateNavigateToUrl(GURL("http://b.example.com/path2"));
@@ -350,8 +411,6 @@ TEST_F(ControllerTest, ForwardParameters) {
}
TEST_F(ControllerTest, Autostart) {
- Start();
-
SupportsScriptResponseProto script_response;
AddRunnableScript(&script_response, "runnable");
AddRunnableScript(&script_response, "autostart")
@@ -363,12 +422,10 @@ TEST_F(ControllerTest, Autostart) {
EXPECT_CALL(*mock_service_, OnGetActions(StrEq("autostart"), _, _, _, _, _))
.WillOnce(RunOnceCallback<5>(true, ""));
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+ Start("http://a.example.com/path");
}
TEST_F(ControllerTest, AutostartFirstInterrupt) {
- Start();
-
SupportsScriptResponseProto script_response;
AddRunnableScript(&script_response, "runnable");
@@ -392,12 +449,10 @@ TEST_F(ControllerTest, AutostartFirstInterrupt) {
// The script fails, ending the flow. What matters is that the correct
// expectation is met.
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+ Start("http://a.example.com/path");
}
TEST_F(ControllerTest, InterruptThenAutostart) {
- Start();
-
SupportsScriptResponseProto script_response;
AddRunnableScript(&script_response, "runnable");
@@ -420,38 +475,23 @@ TEST_F(ControllerTest, InterruptThenAutostart) {
OnGetActions(StrEq("autostart"), _, _, _, _, _));
}
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
+ Start("http://a.example.com/path");
}
TEST_F(ControllerTest, AutostartIsNotPassedToTheUi) {
- Start();
-
SupportsScriptResponseProto script_response;
auto* autostart = AddRunnableScript(&script_response, "runnable");
autostart->mutable_presentation()->set_autostart(true);
RunOnce(autostart);
SetRepeatedScriptResponse(script_response);
- EXPECT_CALL(mock_ui_controller_, ClearChips()).Times(AtLeast(1));
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(SizeIs(0u)))
+ .Times(AnyNumber());
+ EXPECT_CALL(mock_ui_controller_, OnSuggestionsChanged(SizeIs(Gt(0u))))
+ .Times(0);
SimulateNavigateToUrl(GURL("http://a.example.com/path"));
-}
-
-TEST_F(ControllerTest, LoadProgressChanged) {
- Start();
-
- SetLastCommittedUrl(GURL("http://a.example.com/path"));
-
- EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)).Times(0);
-
- SimulateProgressChanged(0.1);
- SimulateProgressChanged(0.3);
- SimulateProgressChanged(0.5);
-
- EXPECT_CALL(*mock_service_,
- OnGetScriptsForUrl(Eq(GURL("http://a.example.com/path")), _, _))
- .WillOnce(RunOnceCallback<2>(true, ""));
- SimulateProgressChanged(0.4);
+ EXPECT_THAT(controller_->GetSuggestions(), SizeIs(0));
}
TEST_F(ControllerTest, InitialUrlLoads) {
@@ -481,10 +521,31 @@ TEST_F(ControllerTest, CookieExperimentEnabled) {
EXPECT_TRUE(controller_->IsCookieExperimentEnabled());
}
+TEST_F(ControllerTest, ProgressIncreasesAtStart) {
+ EXPECT_EQ(0, controller_->GetProgress());
+ EXPECT_CALL(mock_ui_controller_, OnProgressChanged(10));
+ Start();
+ EXPECT_EQ(10, controller_->GetProgress());
+}
+
+TEST_F(ControllerTest, SetProgress) {
+ Start();
+ EXPECT_CALL(mock_ui_controller_, OnProgressChanged(20));
+ controller_->SetProgress(20);
+ EXPECT_EQ(20, controller_->GetProgress());
+}
+
+TEST_F(ControllerTest, IgnoreProgressDecreases) {
+ Start();
+ EXPECT_CALL(mock_ui_controller_, OnProgressChanged(Not(15)))
+ .Times(AnyNumber());
+ controller_->SetProgress(20);
+ controller_->SetProgress(15);
+ EXPECT_EQ(20, controller_->GetProgress());
+}
+
TEST_F(ControllerTest, StateChanges) {
EXPECT_EQ(AutofillAssistantState::INACTIVE, GetUiDelegate()->GetState());
- Start();
- EXPECT_EQ(AutofillAssistantState::STARTING, GetUiDelegate()->GetState());
SupportsScriptResponseProto script_response;
auto* script1 = AddRunnableScript(&script_response, "script1");
@@ -493,15 +554,16 @@ TEST_F(ControllerTest, StateChanges) {
RunOnce(script2);
SetNextScriptResponse(script_response);
- SimulateNavigateToUrl(GURL("http://a.example.com/path"));
-
- EXPECT_EQ(AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT,
- GetUiDelegate()->GetState());
+ Start("http://a.example.com/path");
+ EXPECT_THAT(states_,
+ ElementsAre(AutofillAssistantState::STARTING,
+ AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT));
// Run script1: State should become RUNNING, as there's another script, then
// go back to prompt to propose that script.
states_.clear();
- ExecuteScript("script1"); // returns immediately
+ ASSERT_THAT(controller_->GetSuggestions(), SizeIs(2));
+ controller_->SelectSuggestion(0);
EXPECT_EQ(AutofillAssistantState::PROMPT, GetUiDelegate()->GetState());
EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::RUNNING,
@@ -510,12 +572,135 @@ TEST_F(ControllerTest, StateChanges) {
// Run script2: State should become STOPPED, as there are no more runnable
// scripts.
states_.clear();
- ExecuteScript("script2");
+ ASSERT_THAT(controller_->GetSuggestions(), SizeIs(1));
+ controller_->SelectSuggestion(0);
EXPECT_EQ(AutofillAssistantState::STOPPED, GetUiDelegate()->GetState());
EXPECT_THAT(states_, ElementsAre(AutofillAssistantState::RUNNING,
AutofillAssistantState::PROMPT,
AutofillAssistantState::STOPPED));
+
+ // The cancel button is removed.
+ EXPECT_TRUE(controller_->GetActions().empty());
}
+TEST_F(ControllerTest, ShowUIWhenStarting) {
+ EXPECT_CALL(fake_client_, ShowUI());
+ Start();
+}
+
+TEST_F(ControllerTest, ShowUIWhenContentsFocused) {
+ SimulateWebContentsFocused(); // must not call ShowUI
+
+ testing::InSequence seq;
+ EXPECT_CALL(fake_client_, ShowUI());
+
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "script1");
+ SetNextScriptResponse(script_response);
+ Start(); // must call ShowUI
+
+ EXPECT_CALL(fake_client_, ShowUI());
+ SimulateWebContentsFocused(); // must call ShowUI
+
+ controller_->OnFatalError("test", Metrics::TAB_CHANGED);
+ SimulateWebContentsFocused(); // must not call ShowUI
+}
+
+TEST_F(ControllerTest, KeepCheckingForElement) {
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "no_match_yet")
+ ->mutable_presentation()
+ ->mutable_precondition()
+ ->add_elements_exist()
+ ->add_selectors("#element");
+ SetNextScriptResponse(script_response);
+
+ Start("http://a.example.com/path");
+ // No scripts yet; the element doesn't exit.
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+
+ for (int i = 0; i < 3; i++) {
+ thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+ }
+
+ EXPECT_CALL(*mock_web_controller_, OnElementCheck(_, _, _))
+ .WillRepeatedly(RunOnceCallback<2>(true));
+ thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+ EXPECT_EQ(AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT,
+ controller_->GetState());
+}
+
+TEST_F(ControllerTest, ScriptTimeoutError) {
+ // Wait for #element to show up for will_never_match. After 25s, execute the
+ // script on_timeout_error.
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "will_never_match")
+ ->mutable_presentation()
+ ->mutable_precondition()
+ ->add_elements_exist()
+ ->add_selectors("#element");
+ script_response.mutable_script_timeout_error()->set_timeout_ms(30000);
+ script_response.mutable_script_timeout_error()->set_script_path(
+ "on_timeout_error");
+ SetNextScriptResponse(script_response);
+
+ // on_timeout_error stops everything with a custom error message.
+ ActionsResponseProto on_timeout_error;
+ on_timeout_error.add_actions()->mutable_tell()->set_message("I give up");
+ on_timeout_error.add_actions()->mutable_stop();
+ std::string on_timeout_error_str;
+ on_timeout_error.SerializeToString(&on_timeout_error_str);
+ EXPECT_CALL(*mock_service_,
+ OnGetActions(StrEq("on_timeout_error"), _, _, _, _, _))
+ .WillOnce(RunOnceCallback<5>(true, on_timeout_error_str));
+
+ Start("http://a.example.com/path");
+ for (int i = 0; i < 30; i++) {
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+ thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ }
+ EXPECT_EQ(AutofillAssistantState::STOPPED, controller_->GetState());
+ EXPECT_EQ("I give up", controller_->GetStatusMessage());
+}
+
+TEST_F(ControllerTest, ScriptTimeoutWarning) {
+ // Wait for #element to show up for will_never_match. After 10s, execute the
+ // script on_timeout_error.
+ SupportsScriptResponseProto script_response;
+ AddRunnableScript(&script_response, "will_never_match")
+ ->mutable_presentation()
+ ->mutable_precondition()
+ ->add_elements_exist()
+ ->add_selectors("#element");
+ script_response.mutable_script_timeout_error()->set_timeout_ms(4000);
+ script_response.mutable_script_timeout_error()->set_script_path(
+ "on_timeout_error");
+ SetNextScriptResponse(script_response);
+
+ // on_timeout_error displays an error message and terminates
+ ActionsResponseProto on_timeout_error;
+ on_timeout_error.add_actions()->mutable_tell()->set_message("This is slow");
+ std::string on_timeout_error_str;
+ on_timeout_error.SerializeToString(&on_timeout_error_str);
+ EXPECT_CALL(*mock_service_,
+ OnGetActions(StrEq("on_timeout_error"), _, _, _, _, _))
+ .WillOnce(RunOnceCallback<5>(true, on_timeout_error_str));
+
+ Start("http://a.example.com/path");
+
+ // Warning after 4s, script succeeds and the client continues to wait.
+ for (int i = 0; i < 4; i++) {
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+ thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ }
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+ EXPECT_EQ("This is slow", controller_->GetStatusMessage());
+ for (int i = 0; i < 10; i++) {
+ EXPECT_EQ(AutofillAssistantState::STARTING, controller_->GetState());
+ thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ }
+}
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/details.cc b/chromium/components/autofill_assistant/browser/details.cc
index f1fe4eafceb..5fc9edda8ce 100644
--- a/chromium/components/autofill_assistant/browser/details.cc
+++ b/chromium/components/autofill_assistant/browser/details.cc
@@ -4,81 +4,249 @@
#include "components/autofill_assistant/browser/details.h"
+#include <unordered_set>
+
#include <base/strings/stringprintf.h>
+#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/country_names.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
namespace autofill_assistant {
+constexpr char kSpaceBetweenCardNumAndDate[] = " ";
+
+// static
+bool Details::UpdateFromProto(const ShowDetailsProto& proto, Details* details) {
+ if (!proto.has_details()) {
+ return false;
+ }
+
+ ShowDetailsProto updated_proto = proto;
+ // Legacy treatment for old proto fields. Can be removed once the backend
+ // is updated to set the description_line_1/line_2 fields.
+ if (updated_proto.details().has_description() &&
+ !updated_proto.details().has_description_line_2()) {
+ updated_proto.mutable_details()->set_description_line_2(
+ updated_proto.details().description());
+ }
+ details->SetDetailsProto(updated_proto.details());
+ details->SetDetailsChangesProto(updated_proto.change_flags());
+ return true;
+}
+
+// static
+bool Details::UpdateFromContactDetails(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details) {
+ std::string contact_details = proto.contact_details();
+ if (!client_memory->has_selected_address(contact_details)) {
+ return false;
+ }
+
+ ShowDetailsProto updated_proto = proto;
+ auto* profile = client_memory->selected_address(contact_details);
+ auto* details_proto = updated_proto.mutable_details();
+ // TODO(crbug.com/806868): Get the actual script locale.
+ std::string app_locale = "en-US";
+ details_proto->set_title(
+ l10n_util::GetStringUTF8(IDS_PAYMENTS_CONTACT_DETAILS_LABEL));
+ details_proto->set_description_line_1(
+ base::UTF16ToUTF8(profile->GetInfo(autofill::NAME_FULL, app_locale)));
+ details_proto->set_description_line_2(
+ base::UTF16ToUTF8(profile->GetInfo(autofill::EMAIL_ADDRESS, app_locale)));
+ details->SetDetailsProto(updated_proto.details());
+ details->SetDetailsChangesProto(updated_proto.change_flags());
+ return true;
+}
+
+// static
+bool Details::UpdateFromShippingAddress(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details) {
+ std::string shipping_address = proto.shipping_address();
+ if (!client_memory->has_selected_address(shipping_address)) {
+ return false;
+ }
+
+ ShowDetailsProto updated_proto = proto;
+ auto* profile = client_memory->selected_address(shipping_address);
+ auto* details_proto = updated_proto.mutable_details();
+ // TODO(crbug.com/806868): Get the actual script locale.
+ std::string app_locale = "en-US";
+ autofill::CountryNames* country_names = autofill::CountryNames::GetInstance();
+ details_proto->set_title(
+ l10n_util::GetStringUTF8(IDS_PAYMENTS_SHIPPING_ADDRESS_LABEL));
+ details_proto->set_description_line_1(
+ base::UTF16ToUTF8(profile->GetInfo(autofill::NAME_FULL, app_locale)));
+ details_proto->set_description_line_2(base::StrCat({
+ base::UTF16ToUTF8(
+ profile->GetInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, app_locale)),
+ " ",
+ base::UTF16ToUTF8(
+ profile->GetInfo(autofill::ADDRESS_HOME_ZIP, app_locale)),
+ " ",
+ base::UTF16ToUTF8(
+ profile->GetInfo(autofill::ADDRESS_HOME_CITY, app_locale)),
+ " ",
+ country_names->GetCountryCode(
+ profile->GetInfo(autofill::ADDRESS_HOME_COUNTRY, app_locale)),
+ }));
+ details->SetDetailsProto(updated_proto.details());
+ details->SetDetailsChangesProto(updated_proto.change_flags());
+ return true;
+}
+
+bool Details::UpdateFromSelectedCreditCard(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details) {
+ if (!client_memory->has_selected_card() || !proto.credit_card()) {
+ return false;
+ }
+
+ ShowDetailsProto updated_proto = proto;
+ auto* card = client_memory->selected_card();
+ auto* details_proto = updated_proto.mutable_details();
+ details_proto->set_title(
+ l10n_util::GetStringUTF8(IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL));
+ details_proto->set_description_line_1(
+ base::StrCat({base::UTF16ToUTF8(card->ObfuscatedLastFourDigits()),
+ kSpaceBetweenCardNumAndDate,
+ base::UTF16ToUTF8(card->AbbreviatedExpirationDateForDisplay(
+ /* with_prefix = */ false))}));
+ details->SetDetailsProto(updated_proto.details());
+ details->SetDetailsChangesProto(updated_proto.change_flags());
+ return true;
+}
+
base::Value Details::GetDebugContext() const {
base::Value dict(base::Value::Type::DICTIONARY);
- if (!proto.title().empty())
- dict.SetKey("title", base::Value(proto.title()));
-
- if (!proto.url().empty())
- dict.SetKey("url", base::Value(proto.url()));
-
- if (!proto.m_id().empty())
- dict.SetKey("mId", base::Value(proto.m_id()));
-
- if (!proto.total_price().empty())
- dict.SetKey("total_price", base::Value(proto.total_price()));
-
- if (!proto.description().empty())
- dict.SetKey("description", base::Value(proto.description()));
-
- if (proto.has_datetime()) {
- dict.SetKey(
- "datetime",
- base::Value(base::StringPrintf(
- "%d-%02d-%02dT%02d:%02d:%02d",
- static_cast<int>(proto.datetime().date().year()),
- proto.datetime().date().month(), proto.datetime().date().day(),
- proto.datetime().time().hour(), proto.datetime().time().minute(),
- proto.datetime().time().second())));
+ if (!detailsProto().title().empty())
+ dict.SetKey("title", base::Value(detailsProto().title()));
+
+ if (!detailsProto().image_url().empty())
+ dict.SetKey("image_url", base::Value(detailsProto().image_url()));
+
+ if (!detailsProto().total_price().empty())
+ dict.SetKey("total_price", base::Value(detailsProto().total_price()));
+
+ if (!detailsProto().description_line_1().empty())
+ dict.SetKey("description_line_1",
+ base::Value(detailsProto().description_line_1()));
+
+ if (!detailsProto().description_line_2().empty())
+ dict.SetKey("description_line_2",
+ base::Value(detailsProto().description_line_2()));
+
+ if (detailsProto().has_datetime()) {
+ dict.SetKey("datetime",
+ base::Value(base::StringPrintf(
+ "%d-%02d-%02dT%02d:%02d:%02d",
+ static_cast<int>(detailsProto().datetime().date().year()),
+ detailsProto().datetime().date().month(),
+ detailsProto().datetime().date().day(),
+ detailsProto().datetime().time().hour(),
+ detailsProto().datetime().time().minute(),
+ detailsProto().datetime().time().second())));
}
- if (!datetime.empty())
- dict.SetKey("datetime_str", base::Value(datetime));
+ if (!datetime_.empty())
+ dict.SetKey("datetime_str", base::Value(datetime_));
dict.SetKey("user_approval_required",
- base::Value(changes.user_approval_required()));
- dict.SetKey("highlight_title", base::Value(changes.highlight_title()));
- dict.SetKey("highlight_date", base::Value(changes.highlight_date()));
+ base::Value(changes().user_approval_required()));
+ dict.SetKey("highlight_title", base::Value(changes().highlight_title()));
+ dict.SetKey("highlight_line1", base::Value(changes().highlight_line1()));
+ dict.SetKey("highlight_line2", base::Value(changes().highlight_line2()));
return dict;
}
bool Details::UpdateFromParameters(
const std::map<std::string, std::string>& parameters) {
+ // Whenever details are updated from parameters we want to animate missing
+ // data.
+ proto_.set_animate_placeholders(true);
+ proto_.set_show_image_placeholder(true);
+ if (MaybeUpdateFromDetailsParameters(parameters)) {
+ return true;
+ }
+
+ // NOTE: The logic below is only needed for backward compatibility.
+ // Remove once we always pass detail parameters.
bool is_updated = false;
for (const auto& iter : parameters) {
std::string key = iter.first;
- if (base::EndsWith(key, "E_NAME", base::CompareCase::SENSITIVE)) {
- proto.set_title(iter.second);
+ if (key == "MOVIES_MOVIE_NAME") {
+ proto_.set_title(iter.second);
is_updated = true;
continue;
}
- if (base::EndsWith(key, "R_NAME", base::CompareCase::SENSITIVE)) {
- proto.set_description(iter.second);
+ if (key == "MOVIES_THEATER_NAME") {
+ proto_.set_description_line_2(iter.second);
is_updated = true;
continue;
}
- if (base::EndsWith(key, "MID", base::CompareCase::SENSITIVE)) {
- proto.set_m_id(iter.second);
+ if (iter.first.compare("MOVIES_SCREENING_DATETIME") == 0) {
+ // TODO(crbug.com/806868): Parse the string here and fill
+ // proto.description_line_1, then get rid of datetime_ in Details.
+ datetime_ = iter.second;
is_updated = true;
continue;
}
+ }
+ return is_updated;
+}
+
+bool Details::MaybeUpdateFromDetailsParameters(
+ const std::map<std::string, std::string>& parameters) {
+ bool details_updated = false;
+ for (const auto& iter : parameters) {
+ std::string key = iter.first;
+ if (key == "DETAILS_TITLE") {
+ proto_.set_title(iter.second);
+ details_updated = true;
+ continue;
+ }
- if (base::EndsWith(key, "DATETIME", base::CompareCase::SENSITIVE)) {
- // TODO(crbug.com/806868): Parse the string here and fill proto.datetime,
- // then get rid of the field datetime in Details.
- datetime = iter.second;
- is_updated = true;
+ if (key == "DETAILS_DESCRIPTION_LINE_1") {
+ proto_.set_description_line_1(iter.second);
+ details_updated = true;
+ continue;
+ }
+
+ if (key == "DETAILS_DESCRIPTION_LINE_2") {
+ proto_.set_description_line_2(iter.second);
+ details_updated = true;
+ continue;
+ }
+
+ if (key == "DETAILS_IMAGE_URL") {
+ proto_.set_image_url(iter.second);
+ details_updated = true;
+ continue;
+ }
+
+ if (key == "DETAILS_TOTAL_PRICE_LABEL") {
+ proto_.set_total_price_label(iter.second);
+ details_updated = true;
+ continue;
+ }
+
+ if (key == "DETAILS_TOTAL_PRICE") {
+ proto_.set_total_price(iter.second);
+ details_updated = true;
continue;
}
}
- return is_updated;
+ return details_updated;
+}
+
+void Details::ClearChanges() {
+ change_flags_.Clear();
}
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/details.h b/chromium/components/autofill_assistant/browser/details.h
index fb00f1fdc4e..310cc71da51 100644
--- a/chromium/components/autofill_assistant/browser/details.h
+++ b/chromium/components/autofill_assistant/browser/details.h
@@ -9,20 +9,16 @@
#include <string>
#include "base/values.h"
+#include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/service.pb.h"
namespace autofill_assistant {
-struct Details {
- DetailsProto proto;
- DetailsChanges changes;
-
- // RFC 3339 date-time. Ignore if proto.datetime is set.
- //
- // TODO(crbug.com/806868): parse RFC 3339 date-time on the C++ side and fill
- // proto.datetime with the result instead of carrying a string representation
- // of the datetime.
- std::string datetime;
+class Details {
+ public:
+ const DetailsProto& detailsProto() const { return proto_; }
+ const DetailsChangesProto& changes() const { return change_flags_; }
+ const std::string GetDatetime() const { return datetime_; }
// Returns a dictionary describing the current execution context, which
// is intended to be serialized as JSON string. The execution context is
@@ -31,8 +27,55 @@ struct Details {
// Update details from the given parameters. Returns true if changes were
// made.
+ // If one of the generic detail parameter is present then vertical specific
+ // parameters are not used for Details creation.
bool UpdateFromParameters(
const std::map<std::string, std::string>& parameters);
+
+ // Updates the details to show data directly from proto. Returns true if
+ // |details| were successfully updated.
+ static bool UpdateFromProto(const ShowDetailsProto& proto, Details* details);
+
+ // Updates the details to show selected contact details. It shows only full
+ // name and email. Returns true if |details| were successfully updated.
+ static bool UpdateFromContactDetails(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details);
+
+ // Updates the details to show selected shipping details. It shows full name
+ // and address. Returns true if |details| were successfully updated.
+ static bool UpdateFromShippingAddress(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details);
+
+ // Updates the details to show credit card selected by the user. Returns true
+ // if |details| were successfully updated.
+ static bool UpdateFromSelectedCreditCard(const ShowDetailsProto& proto,
+ ClientMemory* client_memory,
+ Details* details);
+
+ void SetDetailsProto(const DetailsProto& proto) { proto_ = proto; }
+ void SetDetailsChangesProto(const DetailsChangesProto& change_flags) {
+ change_flags_ = change_flags;
+ }
+ // Clears all change flags.
+ void ClearChanges();
+
+ private:
+ // Tries updating the details using generic detail parameters. Returns true
+ // if at least one generic detail parameter was found and used.
+ bool MaybeUpdateFromDetailsParameters(
+ const std::map<std::string, std::string>& parameters);
+
+ DetailsProto proto_;
+ DetailsChangesProto change_flags_;
+
+ // RFC 3339 date-time. Ignore if proto.description_line_1 is set.
+ //
+ // TODO(crbug.com/806868): parse RFC 3339 date-time on the C++ side and fill
+ // proto.description_line_1 with the result instead of carrying a string
+ // representation of the datetime.
+ std::string datetime_;
};
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/devtools/devtools_client.cc b/chromium/components/autofill_assistant/browser/devtools/devtools_client.cc
index 4660e5567d9..4627fb6cb74 100644
--- a/chromium/components/autofill_assistant/browser/devtools/devtools_client.cc
+++ b/chromium/components/autofill_assistant/browser/devtools/devtools_client.cc
@@ -102,7 +102,7 @@ void DevtoolsClient::DispatchProtocolMessage(
DCHECK_EQ(agent_host, agent_host_.get());
std::unique_ptr<base::Value> message =
- base::JSONReader::Read(json_message, base::JSON_PARSE_RFC);
+ base::JSONReader::ReadDeprecated(json_message, base::JSON_PARSE_RFC);
DCHECK(message && message->is_dict());
const base::DictionaryValue* message_dict;
diff --git a/chromium/components/autofill_assistant/browser/element_area.cc b/chromium/components/autofill_assistant/browser/element_area.cc
index a315a8967f7..2617d5cdd5e 100644
--- a/chromium/components/autofill_assistant/browser/element_area.cc
+++ b/chromium/components/autofill_assistant/browser/element_area.cc
@@ -39,12 +39,15 @@ void ElementArea::SetFromProto(const ElementAreaProto& proto) {
for (const auto& rectangle_proto : proto.rectangles()) {
rectangles_.emplace_back();
Rectangle& rectangle = rectangles_.back();
+ rectangle.full_width = rectangle_proto.full_width();
+ DVLOG(3) << "Touchable Rectangle"
+ << (rectangle.full_width ? " (full_width)" : "") << ":";
for (const auto& element_proto : rectangle_proto.elements()) {
rectangle.positions.emplace_back();
ElementPosition& position = rectangle.positions.back();
position.selector = Selector(element_proto);
+ DVLOG(3) << " " << position.selector;
}
- rectangle.full_width = rectangle_proto.full_width();
}
ReportUpdate();
@@ -81,15 +84,11 @@ void ElementArea::UpdatePositions() {
}
}
-bool ElementArea::IsEmpty() const {
- for (const auto& rectangle : rectangles_) {
- for (const auto& position : rectangle.positions) {
- if (!position.rect.empty()) {
- return false;
- }
- }
+void ElementArea::GetRectangles(std::vector<RectF>* area) {
+ for (auto& rectangle : rectangles_) {
+ area->emplace_back();
+ rectangle.FillRect(&area->back());
}
- return true;
}
ElementArea::ElementPosition::ElementPosition() = default;
@@ -109,7 +108,7 @@ bool ElementArea::Rectangle::IsPending() const {
return false;
}
-bool ElementArea::Rectangle::FillRect(RectF* rect) const {
+void ElementArea::Rectangle::FillRect(RectF* rect) const {
bool has_first_rect = false;
for (const auto& position : positions) {
if (position.rect.empty())
@@ -125,14 +124,11 @@ bool ElementArea::Rectangle::FillRect(RectF* rect) const {
rect->left = std::min(rect->left, position.rect.left);
rect->right = std::max(rect->right, position.rect.right);
}
- if (!has_first_rect)
- return false;
-
- if (full_width) {
+ if (has_first_rect && full_width) {
rect->left = 0.0;
rect->right = 1.0;
}
- return true;
+ return;
}
void ElementArea::KeepUpdatingElementPositions() {
@@ -181,14 +177,9 @@ void ElementArea::ReportUpdate() {
}
}
- std::vector<RectF> areas;
- for (auto& rectangle : rectangles_) {
- RectF rect;
- if (rectangle.FillRect(&rect)) {
- areas.emplace_back(rect);
- }
- }
- on_update_.Run(areas);
+ std::vector<RectF> area;
+ GetRectangles(&area);
+ on_update_.Run(area);
}
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/element_area.h b/chromium/components/autofill_assistant/browser/element_area.h
index 1ea21bae45a..1074ccd2597 100644
--- a/chromium/components/autofill_assistant/browser/element_area.h
+++ b/chromium/components/autofill_assistant/browser/element_area.h
@@ -43,23 +43,25 @@ class ElementArea {
// Does nothing if the area is empty.
void UpdatePositions();
- // Returns true if there are no elements to check or if the elements don't
- // exist.
- bool IsEmpty() const;
-
- // Returns true if there are elements to check.
- bool HasElements() const { return !rectangles_.empty(); }
-
// Defines a callback that'll be run every time the set of element coordinates
// changes.
//
// The argument reports the areas that corresponds to currently known
// elements, which might be empty.
void SetOnUpdate(
- base::RepeatingCallback<void(const std::vector<RectF>& areas)> cb) {
+ base::RepeatingCallback<void(const std::vector<RectF>& rectangles)> cb) {
on_update_ = cb;
}
+ // Gets the position on the screen of all the rectangles that correspond to
+ // the configured area.
+ //
+ // Each element in the vector corresponds to a rectangle, which might or might
+ // not be empty.
+ //
+ // Note that the vector is not cleared before rectangles are added.
+ void GetRectangles(std::vector<RectF>* area);
+
private:
// A rectangle that corresponds to the area of the visual viewport covered by
// an element. Coordinates are values between 0 and 1, relative to the size of
@@ -93,7 +95,7 @@ class ElementArea {
bool IsPending() const;
// Fills the given rectangle from the current state, if possible.
- bool FillRect(RectF* rect) const;
+ void FillRect(RectF* rect) const;
};
void KeepUpdatingElementPositions();
diff --git a/chromium/components/autofill_assistant/browser/element_area_unittest.cc b/chromium/components/autofill_assistant/browser/element_area_unittest.cc
index 58cbb5f4035..b4c01884a64 100644
--- a/chromium/components/autofill_assistant/browser/element_area_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/element_area_unittest.cc
@@ -6,10 +6,13 @@
#include <algorithm>
#include <map>
+#include <ostream>
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
+#include "components/autofill_assistant/browser/fake_script_executor_delegate.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_web_controller.h"
#include "components/autofill_assistant/browser/script_executor_delegate.h"
@@ -22,6 +25,19 @@ using ::testing::IsEmpty;
namespace autofill_assistant {
+// User-friendly RectF string representation for matchers.
+//
+// operator<< must not be in an anonymous namespace to be usable in all
+// matchers.
+std::string ToString(const RectF& rect) {
+ return base::StringPrintf("RectF(%2.2f, %2.2f, %2.2f, %2.2f)", rect.left,
+ rect.top, rect.right, rect.bottom);
+}
+
+std::ostream& operator<<(std::ostream& out, const RectF& rectf) {
+ return out << ToString(rectf);
+}
+
namespace {
MATCHER_P4(MatchingRectF,
@@ -29,86 +45,71 @@ MATCHER_P4(MatchingRectF,
top,
right,
bottom,
- base::StringPrintf("MatchingRectF(%2.2f, %2.2f, %2.2f, %2.2f)",
- left,
- top,
- right,
- bottom)) {
- return abs(left - arg.left) < 0.01 && abs(top - arg.top) < 0.01 &&
- abs(right - arg.right) < 0.01 && abs(bottom - arg.bottom) < 0.01;
+ ToString(RectF{left, top, right, bottom})) {
+ if (abs(left - arg.left) < 0.01 && abs(top - arg.top) < 0.01 &&
+ abs(right - arg.right) < 0.01 && abs(bottom - arg.bottom) < 0.01) {
+ return true;
+ }
+ *result_listener << arg;
+ return false;
+}
+
+MATCHER(EmptyRectF, "EmptyRectF") {
+ if (arg.empty())
+ return true;
+
+ *result_listener << arg;
+ return false;
}
ACTION(DoNothing) {}
-class ElementAreaTest : public testing::Test, public ScriptExecutorDelegate {
+class ElementAreaTest : public testing::Test {
protected:
ElementAreaTest()
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
- element_area_(this) {
+ element_area_(&delegate_) {
+ delegate_.SetWebController(&mock_web_controller_);
ON_CALL(mock_web_controller_, OnGetElementPosition(_, _))
.WillByDefault(RunOnceCallback<1>(false, RectF()));
element_area_.SetOnUpdate(base::BindRepeating(&ElementAreaTest::OnUpdate,
base::Unretained(this)));
}
- // Overrides ScriptTrackerDelegate
- Service* GetService() override { return nullptr; }
-
- UiController* GetUiController() override { return nullptr; }
-
- WebController* GetWebController() override { return &mock_web_controller_; }
-
- ClientMemory* GetClientMemory() override { return nullptr; }
-
- void EnterState(AutofillAssistantState state) override {}
-
- const std::map<std::string, std::string>& GetParameters() override {
- return parameters_;
- }
-
- autofill::PersonalDataManager* GetPersonalDataManager() override {
- return nullptr;
- }
-
- content::WebContents* GetWebContents() override { return nullptr; }
-
- void SetTouchableElementArea(const ElementAreaProto& element_area) override {}
-
- void SetStatusMessage(const std::string& status_message) override {}
- std::string GetStatusMessage() const override { return std::string(); }
-
- void SetDetails(const Details& details) override {}
-
- void ClearDetails() override {}
-
void SetElement(const std::string& selector) {
ElementAreaProto area;
area.add_rectangles()->add_elements()->add_selectors(selector);
element_area_.SetFromProto(area);
}
- void OnUpdate(const std::vector<RectF>& area) { highlighted_area_ = area; }
+ void OnUpdate(const std::vector<RectF>& area) { reported_area_ = area; }
// scoped_task_environment_ must be first to guarantee other field
// creation run in that environment.
base::test::ScopedTaskEnvironment scoped_task_environment_;
MockWebController mock_web_controller_;
- std::map<std::string, std::string> parameters_;
+ FakeScriptExecutorDelegate delegate_;
ElementArea element_area_;
- std::vector<RectF> highlighted_area_;
+ std::vector<RectF> reported_area_;
};
TEST_F(ElementAreaTest, Empty) {
- EXPECT_TRUE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_, IsEmpty());
+ EXPECT_THAT(reported_area_, IsEmpty());
+
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, IsEmpty());
}
TEST_F(ElementAreaTest, ElementNotFound) {
SetElement("#not_found");
- EXPECT_TRUE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_, IsEmpty());
+ EXPECT_THAT(reported_area_, ElementsAre(EmptyRectF()));
+
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(EmptyRectF()));
}
TEST_F(ElementAreaTest, OneRectangle) {
@@ -117,8 +118,19 @@ TEST_F(ElementAreaTest, OneRectangle) {
.WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f)));
SetElement("#found");
- EXPECT_FALSE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_,
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles,
+ ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f)));
+}
+
+TEST_F(ElementAreaTest, CallOnUpdate) {
+ EXPECT_CALL(mock_web_controller_,
+ OnGetElementPosition(Eq(Selector({"#found"})), _))
+ .WillOnce(RunOnceCallback<1>(true, RectF(0.25f, 0.25f, 0.75f, 0.75f)));
+
+ SetElement("#found");
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.25f, 0.25f, 0.75f, 0.75f)));
}
@@ -135,10 +147,10 @@ TEST_F(ElementAreaTest, TwoRectangles) {
area_proto.add_rectangles()->add_elements()->add_selectors("#bottom_right");
element_area_.SetFromProto(area_proto);
- EXPECT_FALSE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_,
- ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f),
- MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f)));
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 0.25f, 0.25f),
+ MatchingRectF(0.25f, 0.25f, 1.0f, 1.0f)));
}
TEST_F(ElementAreaTest, OneRectangleTwoElements) {
@@ -155,9 +167,9 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) {
rectangle_proto->add_elements()->add_selectors("#element2");
element_area_.SetFromProto(area_proto);
- EXPECT_FALSE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_,
- ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f)));
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.2f, 0.6f, 0.5f)));
}
TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
@@ -177,9 +189,11 @@ TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) {
rectangle_proto->add_elements()->add_selectors("#element2");
element_area_.SetFromProto(area_proto);
- EXPECT_TRUE(element_area_.HasElements());
- EXPECT_FALSE(element_area_.IsEmpty());
- EXPECT_THAT(highlighted_area_, IsEmpty());
+ EXPECT_THAT(reported_area_, ElementsAre(EmptyRectF()));
+
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.3f, 0.2f, 0.4f)));
}
TEST_F(ElementAreaTest, OneRectangleFourElements) {
@@ -204,11 +218,12 @@ TEST_F(ElementAreaTest, OneRectangleFourElements) {
rectangle_proto->add_elements()->add_selectors("#element4");
element_area_.SetFromProto(area_proto);
- EXPECT_THAT(highlighted_area_,
- ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f)));
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.0f, 1.0f, 1.0f)));
}
-TEST_F(ElementAreaTest, OneRectangleMissingElements) {
+TEST_F(ElementAreaTest, OneRectangleMissingElementsReported) {
EXPECT_CALL(mock_web_controller_,
OnGetElementPosition(Eq(Selector({"#element1"})), _))
.WillOnce(RunOnceCallback<1>(true, RectF(0.1f, 0.1f, 0.2f, 0.2f)));
@@ -222,7 +237,11 @@ TEST_F(ElementAreaTest, OneRectangleMissingElements) {
rectangle_proto->add_elements()->add_selectors("#element2");
element_area_.SetFromProto(area_proto);
- EXPECT_THAT(highlighted_area_,
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f)));
+
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.1f, 0.1f, 0.2f, 0.2f)));
}
@@ -241,8 +260,9 @@ TEST_F(ElementAreaTest, FullWidthRectangle) {
rectangle_proto->set_full_width(true);
element_area_.SetFromProto(area_proto);
- EXPECT_THAT(highlighted_area_,
- ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f)));
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.3f, 1.0f, 0.8f)));
}
TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
@@ -254,12 +274,18 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
SetElement("#element");
- EXPECT_THAT(highlighted_area_,
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
element_area_.UpdatePositions();
- EXPECT_THAT(highlighted_area_,
+ // Updated area is available
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
+
+ // Updated area is reported
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
}
@@ -272,13 +298,19 @@ TEST_F(ElementAreaTest, ElementMovesWithTime) {
SetElement("#element");
- EXPECT_THAT(highlighted_area_,
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.25f, 1.0f, 0.5f)));
scoped_task_environment_.FastForwardBy(
base::TimeDelta::FromMilliseconds(100));
- EXPECT_THAT(highlighted_area_,
+ // Updated area is available
+ std::vector<RectF> rectangles;
+ element_area_.GetRectangles(&rectangles);
+ EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
+
+ // Updated area is reported
+ EXPECT_THAT(reported_area_,
ElementsAre(MatchingRectF(0.0f, 0.5f, 1.0f, 0.75f)));
}
} // namespace
diff --git a/chromium/components/autofill_assistant/browser/element_precondition.cc b/chromium/components/autofill_assistant/browser/element_precondition.cc
new file mode 100644
index 00000000000..5c433f392a7
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/element_precondition.cc
@@ -0,0 +1,100 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/element_precondition.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "components/autofill_assistant/browser/batch_element_checker.h"
+#include "components/autofill_assistant/browser/selector.h"
+
+namespace autofill_assistant {
+
+ElementPrecondition::ElementPrecondition(
+ const google::protobuf::RepeatedPtrField<ElementReferenceProto>&
+ element_exists,
+ const google::protobuf::RepeatedPtrField<FormValueMatchProto>&
+ form_value_match)
+ : form_value_match_(form_value_match.begin(), form_value_match.end()),
+ weak_ptr_factory_(this) {
+ for (const auto& element : element_exists) {
+ // TODO(crbug.com/806868): Check if we shouldn't skip the script when this
+ // happens.
+ if (element.selectors_size() == 0) {
+ DVLOG(3) << "Ignored empty selectors in script precondition.";
+ continue;
+ }
+
+ elements_exist_.emplace_back(Selector(element));
+ }
+}
+
+ElementPrecondition::~ElementPrecondition() = default;
+
+void ElementPrecondition::Check(BatchElementChecker* batch_checks,
+ base::OnceCallback<void(bool)> callback) {
+ pending_check_count_ = elements_exist_.size() + form_value_match_.size();
+ if (pending_check_count_ == 0) {
+ std::move(callback).Run(true);
+ return;
+ }
+
+ callback_ = std::move(callback);
+ for (const auto& selector : elements_exist_) {
+ base::OnceCallback<void(bool)> callback =
+ base::BindOnce(&ElementPrecondition::OnCheckElementExists,
+ weak_ptr_factory_.GetWeakPtr());
+ batch_checks->AddElementCheck(kExistenceCheck, selector,
+ std::move(callback));
+ }
+ for (size_t i = 0; i < form_value_match_.size(); i++) {
+ const auto& value_match = form_value_match_[i];
+ DCHECK(!value_match.element().selectors().empty());
+ batch_checks->AddFieldValueCheck(
+ Selector(value_match.element()),
+ base::BindOnce(&ElementPrecondition::OnGetFieldValue,
+ weak_ptr_factory_.GetWeakPtr(), i));
+ }
+}
+
+void ElementPrecondition::OnCheckElementExists(bool exists) {
+ ReportCheckResult(exists);
+}
+
+void ElementPrecondition::OnGetFieldValue(int index,
+ bool exists,
+ const std::string& value) {
+ if (!exists) {
+ ReportCheckResult(false);
+ return;
+ }
+
+ // TODO(crbug.com/806868): Differentiate between empty value and failure.
+ const auto& value_match = form_value_match_[index];
+ if (value_match.has_value()) {
+ ReportCheckResult(value == value_match.value());
+ return;
+ }
+
+ ReportCheckResult(!value.empty());
+}
+
+void ElementPrecondition::ReportCheckResult(bool success) {
+ if (!callback_)
+ return;
+
+ if (!success) {
+ std::move(callback_).Run(false);
+ return;
+ }
+
+ --pending_check_count_;
+ if (pending_check_count_ <= 0) {
+ DCHECK_EQ(pending_check_count_, 0);
+ std::move(callback_).Run(true);
+ }
+}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/element_precondition.h b/chromium/components/autofill_assistant/browser/element_precondition.h
new file mode 100644
index 00000000000..83b0e8c6161
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/element_precondition.h
@@ -0,0 +1,59 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ELEMENT_PRECONDITION_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ELEMENT_PRECONDITION_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+
+namespace autofill_assistant {
+class BatchElementChecker;
+struct Selector;
+
+class ElementPrecondition {
+ public:
+ ElementPrecondition(
+ const google::protobuf::RepeatedPtrField<ElementReferenceProto>&
+ element_exists,
+ const google::protobuf::RepeatedPtrField<FormValueMatchProto>&
+ form_value_match);
+ ~ElementPrecondition();
+
+ // Check whether the conditions satisfied and return the result through
+ // |callback|. |batch_checks| must remain valid until the callback is run.
+ //
+ // Calling Check() while another check is in progress cancels the previously
+ // running check.
+ void Check(BatchElementChecker* batch_checks,
+ base::OnceCallback<void(bool)> callback);
+
+ bool empty() { return elements_exist_.empty() && form_value_match_.empty(); }
+
+ private:
+ void OnCheckElementExists(bool exists);
+ void OnGetFieldValue(int index, bool exists, const std::string& value);
+ void ReportCheckResult(bool success);
+
+ std::vector<Selector> elements_exist_;
+ std::vector<FormValueMatchProto> form_value_match_;
+
+ // Number of checks for which there's still no result.
+ int pending_check_count_;
+
+ base::OnceCallback<void(bool)> callback_;
+
+ base::WeakPtrFactory<ElementPrecondition> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ElementPrecondition);
+};
+
+} // namespace autofill_assistant
+
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ELEMENT_PRECONDITION_H_
diff --git a/chromium/components/autofill_assistant/browser/element_precondition_unittest.cc b/chromium/components/autofill_assistant/browser/element_precondition_unittest.cc
new file mode 100644
index 00000000000..c98af5701f4
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/element_precondition_unittest.cc
@@ -0,0 +1,179 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/script_precondition.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "base/test/mock_callback.h"
+#include "components/autofill_assistant/browser/batch_element_checker.h"
+#include "components/autofill_assistant/browser/mock_run_once_callback.h"
+#include "components/autofill_assistant/browser/mock_web_controller.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/re2/src/re2/re2.h"
+
+namespace autofill_assistant {
+namespace {
+
+using ::testing::_;
+using ::testing::Eq;
+
+class ElementPreconditionTest : public testing::Test {
+ public:
+ void SetUp() override {
+ ON_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"exists"})), _))
+ .WillByDefault(RunOnceCallback<2>(true));
+ ON_CALL(mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"empty"})), _))
+ .WillByDefault(RunOnceCallback<2>(true));
+ ON_CALL(
+ mock_web_controller_,
+ OnElementCheck(kExistenceCheck, Eq(Selector({"does_not_exist"})), _))
+ .WillByDefault(RunOnceCallback<2>(false));
+
+ ON_CALL(mock_web_controller_, OnGetFieldValue(Eq(Selector({"exists"})), _))
+ .WillByDefault(RunOnceCallback<1>(true, "foo"));
+ ON_CALL(mock_web_controller_,
+ OnGetFieldValue(Eq(Selector({"does_not_exist"})), _))
+ .WillByDefault(RunOnceCallback<1>(false, ""));
+ ON_CALL(mock_web_controller_, OnGetFieldValue(Eq(Selector({"empty"})), _))
+ .WillByDefault(RunOnceCallback<1>(true, ""));
+ }
+
+ protected:
+ // Runs a precondition given |exists_| and |value_match_|.
+ void Check(base::OnceCallback<void(bool)> callback) {
+ ElementPrecondition precondition(exist_, value_match_);
+ BatchElementChecker batch_checks(&mock_web_controller_);
+ precondition.Check(&batch_checks, std::move(callback));
+ batch_checks.Run(base::TimeDelta::FromSeconds(0),
+ /* try_done=*/base::DoNothing(),
+ /* all_done=*/base::DoNothing());
+ }
+
+ MockWebController mock_web_controller_;
+ base::MockCallback<base::OnceCallback<void(bool)>> mock_callback_;
+ google::protobuf::RepeatedPtrField<ElementReferenceProto> exist_;
+ google::protobuf::RepeatedPtrField<FormValueMatchProto> value_match_;
+};
+
+TEST_F(ElementPreconditionTest, Empty) {
+ EXPECT_TRUE(ElementPrecondition(exist_, value_match_).empty());
+}
+
+TEST_F(ElementPreconditionTest, NonEmpty) {
+ exist_.Add()->add_selectors("exists");
+ EXPECT_FALSE(ElementPrecondition(exist_, value_match_).empty());
+}
+
+TEST_F(ElementPreconditionTest, NoConditions) {
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, EmptySelector) {
+ exist_.Add();
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, ElementExists) {
+ exist_.Add()->add_selectors("exists");
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, ElementDoesNotExist) {
+ exist_.Add()->add_selectors("does_not_exist");
+
+ EXPECT_CALL(mock_callback_, Run(false));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueMatchDoesNotExist) {
+ value_match_.Add()->mutable_element()->add_selectors("does_not_exist");
+
+ EXPECT_CALL(mock_callback_, Run(false));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueMatchNonEmpty) {
+ value_match_.Add()->mutable_element()->add_selectors("exists");
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueShouldNotMatchEmpty) {
+ value_match_.Add()->mutable_element()->add_selectors("empty");
+
+ EXPECT_CALL(mock_callback_, Run(false));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueShouldMatchEmpty) {
+ auto* match = value_match_.Add();
+ match->mutable_element()->add_selectors("empty");
+ match->set_value("");
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueMatchWrongValue) {
+ auto* match = value_match_.Add();
+ match->mutable_element()->add_selectors("exists");
+ match->set_value("wrong");
+
+ EXPECT_CALL(mock_callback_, Run(false));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, FormValueMatchCorrectValue) {
+ auto* match = value_match_.Add();
+ match->mutable_element()->add_selectors("exists");
+ match->set_value("foo");
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, SomeMatch) {
+ exist_.Add()->add_selectors("exists");
+ exist_.Add()->add_selectors("does_not_exist");
+
+ value_match_.Add()->mutable_element()->add_selectors("empty");
+ auto* match = value_match_.Add();
+ match->mutable_element()->add_selectors("exists");
+ match->set_value("wrong");
+
+ EXPECT_CALL(mock_callback_, Run(false));
+ Check(mock_callback_.Get());
+}
+
+TEST_F(ElementPreconditionTest, AllMatch) {
+ exist_.Add()->add_selectors("exists");
+ exist_.Add()->add_selectors("empty");
+
+ auto* match_exists = value_match_.Add();
+ match_exists->mutable_element()->add_selectors("exists");
+ match_exists->set_value("foo");
+
+ auto* match_empty = value_match_.Add();
+ match_empty->mutable_element()->add_selectors("empty");
+ match_empty->set_value("");
+
+ EXPECT_CALL(mock_callback_, Run(true));
+ Check(mock_callback_.Get());
+}
+
+} // namespace
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.cc
new file mode 100644
index 00000000000..7a3426c9fb1
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/fake_script_executor_delegate.h"
+
+#include <utility>
+
+namespace autofill_assistant {
+
+FakeScriptExecutorDelegate::FakeScriptExecutorDelegate() = default;
+FakeScriptExecutorDelegate::~FakeScriptExecutorDelegate() = default;
+
+const GURL& FakeScriptExecutorDelegate::GetCurrentURL() {
+ return current_url_;
+}
+
+Service* FakeScriptExecutorDelegate::GetService() {
+ return service_;
+}
+
+UiController* FakeScriptExecutorDelegate::GetUiController() {
+ return ui_controller_;
+}
+
+WebController* FakeScriptExecutorDelegate::GetWebController() {
+ return web_controller_;
+}
+
+ClientMemory* FakeScriptExecutorDelegate::GetClientMemory() {
+ return &memory_;
+}
+
+const std::map<std::string, std::string>&
+FakeScriptExecutorDelegate::GetParameters() {
+ return parameters_;
+}
+
+autofill::PersonalDataManager*
+FakeScriptExecutorDelegate::GetPersonalDataManager() {
+ return nullptr;
+}
+
+content::WebContents* FakeScriptExecutorDelegate::GetWebContents() {
+ return nullptr;
+}
+
+void FakeScriptExecutorDelegate::EnterState(AutofillAssistantState state) {
+ state_ = state;
+}
+
+void FakeScriptExecutorDelegate::SetTouchableElementArea(
+ const ElementAreaProto& element) {}
+
+void FakeScriptExecutorDelegate::SetStatusMessage(const std::string& message) {
+ status_message_ = message;
+}
+
+std::string FakeScriptExecutorDelegate::GetStatusMessage() const {
+ return status_message_;
+}
+
+void FakeScriptExecutorDelegate::SetDetails(std::unique_ptr<Details> details) {
+ details_ = std::move(details);
+}
+
+void FakeScriptExecutorDelegate::SetInfoBox(const InfoBox& info_box) {
+ info_box_ = std::make_unique<InfoBox>(info_box);
+}
+
+void FakeScriptExecutorDelegate::ClearInfoBox() {
+ info_box_ = nullptr;
+}
+
+void FakeScriptExecutorDelegate::SetProgress(int progress) {}
+
+void FakeScriptExecutorDelegate::SetProgressVisible(bool visible) {}
+
+void FakeScriptExecutorDelegate::SetChips(
+ std::unique_ptr<std::vector<Chip>> chips) {
+ chips_ = std::move(chips);
+}
+
+void FakeScriptExecutorDelegate::SetPaymentRequestOptions(
+ std::unique_ptr<PaymentRequestOptions> options) {
+ payment_request_options_ = std::move(options);
+}
+
+void FakeScriptExecutorDelegate::CancelPaymentRequest() {}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.h b/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.h
new file mode 100644
index 00000000000..4670bac2005
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -0,0 +1,92 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FAKE_SCRIPT_EXECUTOR_DELEGATE_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FAKE_SCRIPT_EXECUTOR_DELEGATE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "components/autofill_assistant/browser/client_memory.h"
+#include "components/autofill_assistant/browser/script_executor_delegate.h"
+
+namespace autofill_assistant {
+
+// Implementation of ScriptExecutorDelegate that's convenient to use in
+// unittests.
+class FakeScriptExecutorDelegate : public ScriptExecutorDelegate {
+ public:
+ FakeScriptExecutorDelegate();
+ ~FakeScriptExecutorDelegate() override;
+
+ const GURL& GetCurrentURL() override;
+ Service* GetService() override;
+ UiController* GetUiController() override;
+ WebController* GetWebController() override;
+ ClientMemory* GetClientMemory() override;
+ const std::map<std::string, std::string>& GetParameters() override;
+ autofill::PersonalDataManager* GetPersonalDataManager() override;
+ content::WebContents* GetWebContents() override;
+ void EnterState(AutofillAssistantState state) override;
+ void SetTouchableElementArea(const ElementAreaProto& element) override;
+ void SetStatusMessage(const std::string& message) override;
+ std::string GetStatusMessage() const override;
+ void SetDetails(std::unique_ptr<Details> details) override;
+ void SetInfoBox(const InfoBox& info_box) override;
+ void ClearInfoBox() override;
+ void SetProgress(int progress) override;
+ void SetProgressVisible(bool visible) override;
+ void SetChips(std::unique_ptr<std::vector<Chip>> chips) override;
+ void SetPaymentRequestOptions(
+ std::unique_ptr<PaymentRequestOptions> options) override;
+ void CancelPaymentRequest() override;
+
+ void SetCurrentURL(const GURL& url) { current_url_ = url; }
+
+ void SetService(Service* service) { service_ = service; }
+
+ void SetUiController(UiController* ui_controller) {
+ ui_controller_ = ui_controller;
+ }
+
+ void SetWebController(WebController* web_controller) {
+ web_controller_ = web_controller;
+ }
+
+ std::map<std::string, std::string>* GetMutableParameters() {
+ return &parameters_;
+ }
+
+ AutofillAssistantState GetState() { return state_; }
+
+ Details* GetDetails() { return details_.get(); }
+
+ InfoBox* GetInfoBox() { return info_box_.get(); }
+
+ std::vector<Chip>* GetChips() { return chips_.get(); }
+
+ PaymentRequestOptions* GetOptions() { return payment_request_options_.get(); }
+
+ private:
+ GURL current_url_;
+ Service* service_ = nullptr;
+ UiController* ui_controller_ = nullptr;
+ WebController* web_controller_ = nullptr;
+ ClientMemory memory_;
+ std::map<std::string, std::string> parameters_;
+ AutofillAssistantState state_ = AutofillAssistantState::INACTIVE;
+ std::string status_message_;
+ std::unique_ptr<Details> details_;
+ std::unique_ptr<InfoBox> info_box_;
+ std::unique_ptr<std::vector<Chip>> chips_;
+ std::unique_ptr<PaymentRequestOptions> payment_request_options_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeScriptExecutorDelegate);
+};
+
+} // namespace autofill_assistant
+
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FAKE_SCRIPT_EXECUTOR_DELEGATE_H_
diff --git a/chromium/components/autofill_assistant/browser/features.cc b/chromium/components/autofill_assistant/browser/features.cc
new file mode 100644
index 00000000000..845b393c2aa
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/features.cc
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/features.h"
+
+#include "base/feature_list.h"
+
+namespace autofill_assistant {
+namespace features {
+
+const base::Feature kAutofillAssistant{"AutofillAssistant",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Controls whether to query backend service to start any assisted actions.
+const base::Feature kAutofillAssistantChromeEntry{
+ "AutofillAssistantChromeEntry", base::FEATURE_DISABLED_BY_DEFAULT};
+
+} // namespace features
+} // namespace autofill_assistant \ No newline at end of file
diff --git a/chromium/components/autofill_assistant/browser/features.h b/chromium/components/autofill_assistant/browser/features.h
new file mode 100644
index 00000000000..eedd49e404a
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/features.h
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_
+
+namespace base {
+struct Feature;
+}
+
+namespace autofill_assistant {
+namespace features {
+// All features in alphabetical order.
+extern const base::Feature kAutofillAssistant;
+extern const base::Feature kAutofillAssistantChromeEntry;
+
+} // namespace features
+} // namespace autofill_assistant
+
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_
diff --git a/chromium/components/autofill_assistant/browser/info_box.cc b/chromium/components/autofill_assistant/browser/info_box.cc
new file mode 100644
index 00000000000..23d4714bbb3
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/info_box.cc
@@ -0,0 +1,22 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/info_box.h"
+
+#include <unordered_set>
+
+namespace autofill_assistant {
+
+InfoBox::InfoBox(const ShowInfoBoxProto& proto) : proto_(proto) {}
+
+base::Value InfoBox::GetDebugContext() const {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ if (!info_box().image_path().empty())
+ dict.SetKey("image_path", base::Value(info_box().image_path()));
+ if (!info_box().explanation().empty())
+ dict.SetKey("explanation", base::Value(info_box().explanation()));
+ return dict;
+}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/info_box.h b/chromium/components/autofill_assistant/browser/info_box.h
new file mode 100644
index 00000000000..67fa522aec7
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/info_box.h
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_INFO_BOX_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_INFO_BOX_H_
+
+#include <map>
+#include <string>
+
+#include "base/values.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+
+namespace autofill_assistant {
+
+class InfoBox {
+ public:
+ InfoBox() = default;
+ InfoBox(const ShowInfoBoxProto& proto);
+
+ const ShowInfoBoxProto& proto() const { return proto_; }
+
+ // Returns a dictionary describing the current execution context, which
+ // is intended to be serialized as JSON string. The execution context is
+ // useful when analyzing feedback forms and for debugging in general.
+ base::Value GetDebugContext() const;
+
+ private:
+ const InfoBoxProto& info_box() const { return proto_.info_box(); }
+ ShowInfoBoxProto proto_;
+};
+
+} // namespace autofill_assistant
+
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_INFO_BOX_H_
diff --git a/chromium/components/autofill_assistant/browser/metrics.h b/chromium/components/autofill_assistant/browser/metrics.h
index f8fbf27d065..adeae33600c 100644
--- a/chromium/components/autofill_assistant/browser/metrics.h
+++ b/chromium/components/autofill_assistant/browser/metrics.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_METRICS_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_METRICS_H_
+#include <ostream>
+
namespace autofill_assistant {
// A class to generate Autofill Assistant related histograms.
@@ -33,10 +35,97 @@ class Metrics {
SAFETY_NET_TERMINATE = 14, // This is a "should never happen" entry.
TAB_DETACHED = 15,
TAB_CHANGED = 16,
- NUM_ENTRIES = 17,
+ GET_SCRIPTS_FAILED = 17,
+ GET_SCRIPTS_UNPARSABLE = 18,
+ NO_INITIAL_SCRIPTS = 19,
+
+ NUM_ENTRIES = 20,
};
static void RecordDropOut(DropOutReason reason);
+
+ // Intended for debugging: writes string representation of |reason| to |out|.
+ friend std::ostream& operator<<(std::ostream& out,
+ const DropOutReason& reason) {
+#ifdef NDEBUG
+ // Non-debugging builds write the enum number.
+ out << static_cast<int>(reason);
+ return out;
+#else
+ // Debugging builds write a string representation of |reason|.
+ switch (reason) {
+ case AA_START:
+ out << "AA_START";
+ break;
+ case AUTOSTART_TIMEOUT:
+ out << "AUTOSTART_TIMEOUT";
+ break;
+ case NO_SCRIPTS:
+ out << "NO_SCRIPTS";
+ break;
+ case CUSTOM_TAB_CLOSED:
+ out << "CUSTOM_TAB_CLOSED";
+ break;
+ case DECLINED:
+ out << "DECLINED";
+ break;
+ case SHEET_CLOSED:
+ out << "SHEET_CLOSED";
+ break;
+ case SCRIPT_FAILED:
+ out << "SCRIPT_FAILED";
+ break;
+ case NAVIGATION:
+ out << "NAVIGATION";
+ break;
+ case OVERLAY_STOP:
+ out << "OVERLAY_STOP";
+ break;
+ case PR_FAILED:
+ out << "PR_FAILED";
+ break;
+ case CONTENT_DESTROYED:
+ out << "CONTENT_DESTROYED";
+ break;
+ case RENDER_PROCESS_GONE:
+ out << "RENDER_PROCESS_GONE";
+ break;
+ case INTERSTITIAL_PAGE:
+ out << "INTERSTITIAL_PAGE";
+ break;
+ case SCRIPT_SHUTDOWN:
+ out << "SCRIPT_SHUTDOWN";
+ break;
+ case SAFETY_NET_TERMINATE:
+ out << "SAFETY_NET_TERMINATE";
+ break;
+ case TAB_DETACHED:
+ out << "TAB_DETACHED";
+ break;
+ case TAB_CHANGED:
+ out << "TAB_CHANGED";
+ break;
+
+ case NUM_ENTRIES:
+ out << "NUM_ENTRIES";
+ break;
+
+ case GET_SCRIPTS_FAILED:
+ out << "GET_SCRIPTS_FAILED";
+ break;
+
+ case GET_SCRIPTS_UNPARSABLE:
+ out << "GET_SCRIPTS_UNPARSEABLE";
+ break;
+
+ case NO_INITIAL_SCRIPTS:
+ out << "NO_INITIAL_SCRIPTS";
+ // Intentionally no default case to make compilation fail if a new value
+ // was added to the enum but not to this list.
+ }
+ return out;
+#endif // NDEBUG
+ }
};
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/mock_client_memory.cc b/chromium/components/autofill_assistant/browser/mock_client_memory.cc
deleted file mode 100644
index 8b634ee0409..00000000000
--- a/chromium/components/autofill_assistant/browser/mock_client_memory.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill_assistant/browser/mock_client_memory.h"
-
-namespace autofill_assistant {
-
-MockClientMemory::MockClientMemory() = default;
-MockClientMemory::~MockClientMemory() = default;
-
-} // namespace autofill_assistant \ No newline at end of file
diff --git a/chromium/components/autofill_assistant/browser/mock_client_memory.h b/chromium/components/autofill_assistant/browser/mock_client_memory.h
deleted file mode 100644
index 4d9db241a23..00000000000
--- a/chromium/components/autofill_assistant/browser/mock_client_memory.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_MEMORY_H_
-#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_MEMORY_H_
-
-#include "components/autofill_assistant/browser/client_memory.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace autofill_assistant {
-
-class MockClientMemory : public ClientMemory {
- public:
- MockClientMemory();
- ~MockClientMemory();
-
- MOCK_METHOD0(selected_card, const autofill::CreditCard*());
- MOCK_METHOD0(has_selected_card, bool());
- MOCK_METHOD1(selected_address,
- const autofill::AutofillProfile*(const std::string& name));
- MOCK_METHOD1(has_selected_address, bool(const std::string& name));
- MOCK_METHOD1(set_selected_card,
- void(std::unique_ptr<autofill::CreditCard> card));
- MOCK_METHOD2(set_selected_address,
- void(const std::string& name,
- std::unique_ptr<autofill::AutofillProfile> address));
-};
-
-} // namespace autofill_assistant
-
-#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_MOCK_CLIENT_MEMORY_H_
diff --git a/chromium/components/autofill_assistant/browser/mock_ui_controller.h b/chromium/components/autofill_assistant/browser/mock_ui_controller.h
index 877427f8dc6..85557f97559 100644
--- a/chromium/components/autofill_assistant/browser/mock_ui_controller.h
+++ b/chromium/components/autofill_assistant/browser/mock_ui_controller.h
@@ -24,23 +24,18 @@ class MockUiController : public UiController {
MOCK_METHOD1(OnStatusMessageChanged, void(const std::string& message));
MOCK_METHOD1(OnStateChanged, void(AutofillAssistantState));
- MOCK_METHOD1(Shutdown, void(Metrics::DropOutReason));
- MOCK_METHOD0(Close, void());
- MOCK_METHOD1(SetChips, void(std::unique_ptr<std::vector<Chip>> chips));
- MOCK_METHOD0(ClearChips, void());
- MOCK_METHOD4(
- GetPaymentInformation,
- void(payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)>
- callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks));
+ MOCK_METHOD1(WillShutdown, void(Metrics::DropOutReason));
+ MOCK_METHOD1(OnSuggestionsChanged,
+ void(const std::vector<Chip>& suggestions));
+ MOCK_METHOD1(OnActionsChanged, void(const std::vector<Chip>& actions));
+ MOCK_METHOD1(OnPaymentRequestChanged,
+ void(const PaymentRequestOptions* options));
MOCK_METHOD1(OnDetailsChanged, void(const Details* details));
- MOCK_METHOD1(ShowProgressBar, void(int progress));
- MOCK_METHOD0(HideProgressBar, void());
- MOCK_METHOD1(SetTouchableArea, void(const std::vector<RectF>& areas));
+ MOCK_METHOD1(OnInfoBoxChanged, void(const InfoBox* info_box));
+ MOCK_METHOD1(OnProgressChanged, void(int progress));
+ MOCK_METHOD1(OnProgressVisibilityChanged, void(bool visible));
+ MOCK_METHOD1(OnTouchableAreaChanged, void(const std::vector<RectF>& areas));
MOCK_CONST_METHOD0(Terminate, bool());
- MOCK_METHOD0(ExpandBottomSheet, void());
MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason());
};
diff --git a/chromium/components/autofill_assistant/browser/mock_web_controller.h b/chromium/components/autofill_assistant/browser/mock_web_controller.h
index c5eeffd88f8..210cbf13f21 100644
--- a/chromium/components/autofill_assistant/browser/mock_web_controller.h
+++ b/chromium/components/autofill_assistant/browser/mock_web_controller.h
@@ -20,8 +20,6 @@ class MockWebController : public WebController {
MockWebController();
~MockWebController() override;
- MOCK_METHOD0(GetUrl, const GURL&());
-
MOCK_METHOD1(LoadURL, void(const GURL&));
void ClickOrTapElement(const Selector& selector,
diff --git a/chromium/components/autofill_assistant/browser/payment_information.h b/chromium/components/autofill_assistant/browser/payment_information.h
deleted file mode 100644
index d4ffdf0dedd..00000000000
--- a/chromium/components/autofill_assistant/browser/payment_information.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_INFORMATION_H_
-#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_INFORMATION_H_
-
-#include <string>
-
-namespace autofill {
-class AutofillProfile;
-class CreditCard;
-} // namespace autofill
-
-namespace autofill_assistant {
-
-// Struct for holding the payment information data.
-struct PaymentInformation {
- PaymentInformation();
- ~PaymentInformation();
-
- bool succeed;
- std::unique_ptr<autofill::CreditCard> card;
- std::unique_ptr<autofill::AutofillProfile> shipping_address;
- std::unique_ptr<autofill::AutofillProfile> billing_address;
- std::string payer_name;
- std::string payer_phone;
- std::string payer_email;
- bool is_terms_and_conditions_accepted;
-};
-} // namespace autofill_assistant
-#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_INFORMATION_H_
diff --git a/chromium/components/autofill_assistant/browser/payment_request.cc b/chromium/components/autofill_assistant/browser/payment_request.cc
new file mode 100644
index 00000000000..8fb37f6c60d
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/payment_request.cc
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/payment_request.h"
+
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
+
+namespace autofill_assistant {
+
+PaymentInformation::PaymentInformation() = default;
+PaymentInformation::~PaymentInformation() = default;
+
+PaymentRequestOptions::PaymentRequestOptions() = default;
+PaymentRequestOptions::~PaymentRequestOptions() = default;
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/payment_request.h b/chromium/components/autofill_assistant/browser/payment_request.h
new file mode 100644
index 00000000000..77fa4202426
--- /dev/null
+++ b/chromium/components/autofill_assistant/browser/payment_request.h
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_REQUEST_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_REQUEST_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+
+namespace autofill {
+class AutofillProfile;
+class CreditCard;
+} // namespace autofill
+
+namespace autofill_assistant {
+
+// Struct for holding the payment information data.
+struct PaymentInformation {
+ PaymentInformation();
+ ~PaymentInformation();
+
+ bool succeed = false;
+ std::unique_ptr<autofill::CreditCard> card;
+ std::unique_ptr<autofill::AutofillProfile> shipping_address;
+ std::unique_ptr<autofill::AutofillProfile> billing_address;
+ std::string payer_name;
+ std::string payer_phone;
+ std::string payer_email;
+ bool is_terms_and_conditions_accepted = false;
+};
+
+// Struct for holding the payment request options.
+struct PaymentRequestOptions {
+ PaymentRequestOptions();
+ ~PaymentRequestOptions();
+
+ bool request_payer_name = false;
+ bool request_payer_email = false;
+ bool request_payer_phone = false;
+ bool request_shipping = false;
+ std::vector<std::string> supported_basic_card_networks;
+ std::string default_email;
+
+ base::OnceCallback<void(std::unique_ptr<PaymentInformation>)> callback;
+};
+
+} // namespace autofill_assistant
+#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_PAYMENT_REQUEST_H_
diff --git a/chromium/components/autofill_assistant/browser/protocol_utils.cc b/chromium/components/autofill_assistant/browser/protocol_utils.cc
index a1c7b6680d8..b8f2614c315 100644
--- a/chromium/components/autofill_assistant/browser/protocol_utils.cc
+++ b/chromium/components/autofill_assistant/browser/protocol_utils.cc
@@ -20,6 +20,7 @@
#include "components/autofill_assistant/browser/actions/set_attribute_action.h"
#include "components/autofill_assistant/browser/actions/set_form_field_value_action.h"
#include "components/autofill_assistant/browser/actions/show_details_action.h"
+#include "components/autofill_assistant/browser/actions/show_info_box_action.h"
#include "components/autofill_assistant/browser/actions/show_progress_bar_action.h"
#include "components/autofill_assistant/browser/actions/stop_action.h"
#include "components/autofill_assistant/browser/actions/tell_action.h"
@@ -66,26 +67,6 @@ std::string ProtocolUtils::CreateGetScriptsRequest(
}
// static
-bool ProtocolUtils::ParseScripts(
- const std::string& response,
- std::vector<std::unique_ptr<Script>>* scripts) {
- DCHECK(scripts);
-
- SupportsScriptResponseProto response_proto;
- if (!response_proto.ParseFromString(response)) {
- LOG(ERROR) << "Failed to parse getting assistant scripts response.";
- return false;
- }
-
- scripts->clear();
- for (const auto& script_proto : response_proto.scripts()) {
- ProtocolUtils::AddScript(script_proto, scripts);
- }
-
- return true;
-}
-
-// static
void ProtocolUtils::AddScript(const SupportedScriptProto& script_proto,
std::vector<std::unique_ptr<Script>>* scripts) {
auto script = std::make_unique<Script>();
@@ -96,7 +77,7 @@ void ProtocolUtils::AddScript(const SupportedScriptProto& script_proto,
script->handle.autostart = presentation.autostart();
script->handle.interrupt = presentation.interrupt();
script->handle.initial_prompt = presentation.initial_prompt();
- script->handle.highlight = presentation.highlight();
+ script->handle.chip_type = presentation.chip_type();
script->precondition = ScriptPrecondition::FromProto(
script_proto.path(), presentation.precondition());
script->priority = presentation.priority();
@@ -261,10 +242,14 @@ bool ProtocolUtils::ParseActions(const std::string& response,
actions->emplace_back(std::make_unique<SetAttributeAction>(action));
break;
}
+ case ActionProto::ActionInfoCase::kShowInfoBox: {
+ actions->emplace_back(std::make_unique<ShowInfoBoxAction>(action));
+ break;
+ }
default:
case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: {
- DLOG(ERROR) << "Unknown or unsupported action with action_case="
- << action.action_info_case();
+ DVLOG(1) << "Unknown or unsupported action with action_case="
+ << action.action_info_case();
actions->emplace_back(std::make_unique<UnsupportedAction>(action));
break;
}
diff --git a/chromium/components/autofill_assistant/browser/protocol_utils.h b/chromium/components/autofill_assistant/browser/protocol_utils.h
index aa977ccbdf8..0bc04f43b13 100644
--- a/chromium/components/autofill_assistant/browser/protocol_utils.h
+++ b/chromium/components/autofill_assistant/browser/protocol_utils.h
@@ -28,18 +28,6 @@ class ProtocolUtils {
const std::map<std::string, std::string>& parameters,
const ClientContextProto& client_context);
- using Scripts = std::map<Script*, std::unique_ptr<Script>>;
- // Parse assistant scripts from the given |response|, which should not be an
- // empty string.
- //
- // Parsed assistant scripts are returned through |scripts|, which should not
- // be nullptr. Returned scripts are guaranteed to be fully initialized, and
- // have a name, path and precondition.
- //
- // Return false if parse failed, otherwise return true.
- static bool ParseScripts(const std::string& response,
- std::vector<std::unique_ptr<Script>>* scripts);
-
// Convert |script_proto| to a script struct and if the script is valid, add
// it to |scripts|.
static void AddScript(const SupportedScriptProto& script_proto,
diff --git a/chromium/components/autofill_assistant/browser/protocol_utils_unittest.cc b/chromium/components/autofill_assistant/browser/protocol_utils_unittest.cc
index 185cf7171b9..74037423ff3 100644
--- a/chromium/components/autofill_assistant/browser/protocol_utils_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/protocol_utils_unittest.cc
@@ -28,48 +28,49 @@ void AssertClientContext(const ClientContextProto& context) {
EXPECT_EQ("v", context.chrome().chrome_version());
}
-TEST(ProtocolUtilsTest, NoScripts) {
+TEST(ProtocolUtilsTest, ScriptMissingPath) {
+ SupportedScriptProto script;
+ script.mutable_presentation()->set_name("missing path");
std::vector<std::unique_ptr<Script>> scripts;
- EXPECT_TRUE(ProtocolUtils::ParseScripts("", &scripts));
+ ProtocolUtils::AddScript(script, &scripts);
+
EXPECT_THAT(scripts, IsEmpty());
}
-TEST(ProtocolUtilsTest, SomeInvalidScripts) {
- SupportsScriptResponseProto proto;
+TEST(ProtocolUtilsTest, ScriptMissingName) {
+ SupportedScriptProto script;
+ script.set_path("missing name");
+ std::vector<std::unique_ptr<Script>> scripts;
+ ProtocolUtils::AddScript(script, &scripts);
- // 2 Invalid scripts, 1 valid one, with no preconditions.
- proto.add_scripts()->mutable_presentation()->set_name("missing path");
- proto.add_scripts()->set_path("missing name");
- SupportedScriptProto* script = proto.add_scripts();
- script->set_path("ok");
- script->mutable_presentation()->set_name("ok name");
+ EXPECT_THAT(scripts, IsEmpty());
+}
- // Only the valid script is returned.
+TEST(ProtocolUtilsTest, MinimalValidScript) {
+ SupportedScriptProto script;
+ script.set_path("path");
+ script.mutable_presentation()->set_name("name");
std::vector<std::unique_ptr<Script>> scripts;
- std::string proto_str;
- proto.SerializeToString(&proto_str);
- EXPECT_TRUE(ProtocolUtils::ParseScripts(proto_str, &scripts));
+ ProtocolUtils::AddScript(script, &scripts);
+
ASSERT_THAT(scripts, SizeIs(1));
- EXPECT_EQ("ok", scripts[0]->handle.path);
- EXPECT_EQ("ok name", scripts[0]->handle.name);
+ EXPECT_EQ("path", scripts[0]->handle.path);
+ EXPECT_EQ("name", scripts[0]->handle.name);
EXPECT_NE(nullptr, scripts[0]->precondition);
}
TEST(ProtocolUtilsTest, OneFullyFeaturedScript) {
- SupportsScriptResponseProto proto;
-
- SupportedScriptProto* script = proto.add_scripts();
- script->set_path("path");
- auto* presentation = script->mutable_presentation();
+ SupportedScriptProto script_proto;
+ script_proto.set_path("path");
+ auto* presentation = script_proto.mutable_presentation();
presentation->set_name("name");
presentation->set_autostart(true);
presentation->set_initial_prompt("prompt");
presentation->mutable_precondition()->add_domain("www.example.com");
std::vector<std::unique_ptr<Script>> scripts;
- std::string proto_str;
- proto.SerializeToString(&proto_str);
- EXPECT_TRUE(ProtocolUtils::ParseScripts(proto_str, &scripts));
+ ProtocolUtils::AddScript(script_proto, &scripts);
+
ASSERT_THAT(scripts, SizeIs(1));
EXPECT_EQ("path", scripts[0]->handle.path);
EXPECT_EQ("name", scripts[0]->handle.name);
@@ -79,20 +80,16 @@ TEST(ProtocolUtilsTest, OneFullyFeaturedScript) {
}
TEST(ProtocolUtilsTest, AllowInterruptsWithNoName) {
- SupportsScriptResponseProto proto;
-
- SupportedScriptProto* script = proto.add_scripts();
- script->set_path("path");
- auto* presentation = script->mutable_presentation();
+ SupportedScriptProto script_proto;
+ script_proto.set_path("path");
+ auto* presentation = script_proto.mutable_presentation();
presentation->set_autostart(true);
presentation->set_initial_prompt("prompt");
presentation->set_interrupt(true);
presentation->mutable_precondition()->add_domain("www.example.com");
std::vector<std::unique_ptr<Script>> scripts;
- std::string proto_str;
- proto.SerializeToString(&proto_str);
- EXPECT_TRUE(ProtocolUtils::ParseScripts(proto_str, &scripts));
+ ProtocolUtils::AddScript(script_proto, &scripts);
ASSERT_THAT(scripts, SizeIs(1));
EXPECT_EQ("path", scripts[0]->handle.path);
EXPECT_EQ("", scripts[0]->handle.name);
diff --git a/chromium/components/autofill_assistant/browser/script.h b/chromium/components/autofill_assistant/browser/script.h
index 320aa601721..b728b6f65a2 100644
--- a/chromium/components/autofill_assistant/browser/script.h
+++ b/chromium/components/autofill_assistant/browser/script.h
@@ -9,6 +9,7 @@
#include <string>
#include "components/autofill_assistant/browser/script_precondition.h"
+#include "components/autofill_assistant/browser/service.pb.h"
namespace autofill_assistant {
@@ -25,7 +26,7 @@ struct ScriptHandle {
// When set to true this script can be run in 'autostart mode'. Script won't
// be shown.
bool autostart;
- bool highlight;
+ ChipType chip_type;
// If set, the script might be run during WaitForDom actions with
// allow_interrupt=true.
diff --git a/chromium/components/autofill_assistant/browser/script_executor.cc b/chromium/components/autofill_assistant/browser/script_executor.cc
index ac4bdd55f46..59f6083aa10 100644
--- a/chromium/components/autofill_assistant/browser/script_executor.cc
+++ b/chromium/components/autofill_assistant/browser/script_executor.cc
@@ -4,15 +4,18 @@
#include "components/autofill_assistant/browser/script_executor.h"
+#include <ostream>
#include <string>
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill_assistant/browser/actions/action.h"
#include "components/autofill_assistant/browser/batch_element_checker.h"
#include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/protocol_utils.h"
@@ -30,6 +33,91 @@ namespace {
// to show up.
constexpr base::TimeDelta kShortWaitForElementDeadline =
base::TimeDelta::FromSeconds(2);
+
+// Intended for debugging. Writes a string representation of the status to
+// |out|.
+std::ostream& operator<<(std::ostream& out,
+ const ProcessedActionStatusProto& status) {
+#ifdef NDEBUG
+ out << static_cast<int>(status);
+ return out;
+#else
+ switch (status) {
+ case ProcessedActionStatusProto::UNKNOWN_ACTION_STATUS:
+ out << "UNKNOWN_ACTION_STATUS";
+ break;
+ case ProcessedActionStatusProto::ELEMENT_RESOLUTION_FAILED:
+ out << "ELEMENT_RESOLUTION_FAILED";
+ break;
+ case ProcessedActionStatusProto::ACTION_APPLIED:
+ out << "ACTION_APPLIED";
+ break;
+ case ProcessedActionStatusProto::OTHER_ACTION_STATUS:
+ out << "OTHER_ACTION_STATUS";
+ break;
+ case ProcessedActionStatusProto::PAYMENT_REQUEST_ERROR:
+ out << "PAYMENT_REQUEST_ERROR";
+ break;
+ case ProcessedActionStatusProto::UNSUPPORTED_ACTION:
+ out << "UNSUPPORTED_ACTION";
+ break;
+ case ProcessedActionStatusProto::MANUAL_FALLBACK:
+ out << "MANUAL_FALLBACK";
+ break;
+ case ProcessedActionStatusProto::INTERRUPT_FAILED:
+ out << "INTERRUPT_FAILED";
+ break;
+ case ProcessedActionStatusProto::USER_ABORTED_ACTION:
+ out << "USER_ABORTED_ACTION";
+ break;
+
+ case ProcessedActionStatusProto::GET_FULL_CARD_FAILED:
+ out << "GET_FULL_CARD_FAILED";
+ break;
+
+ case ProcessedActionStatusProto::PRECONDITION_FAILED:
+ out << "PRECONDITION_FAILED";
+ break;
+
+ // Intentionally no default case to make compilation fail if a new value
+ // was added to the enum but not to this list.
+ }
+ return out;
+#endif // NDEBUG
+}
+
+std::ostream& operator<<(std::ostream& out,
+ const ScriptExecutor::AtEnd& at_end) {
+#ifdef NDEBUG
+ out << static_cast<int>(at_end);
+ return out;
+#else
+ switch (at_end) {
+ case ScriptExecutor::CONTINUE:
+ out << "CONTINUE";
+ break;
+ case ScriptExecutor::SHUTDOWN:
+ out << "SHUTDOWN";
+ break;
+ case ScriptExecutor::SHUTDOWN_GRACEFULLY:
+ out << "SHUTDOWN_GRACEFULLY";
+ break;
+ case ScriptExecutor::CLOSE_CUSTOM_TAB:
+ out << "CLOSE_CUSTOM_TAB";
+ break;
+ case ScriptExecutor::RESTART:
+ out << "RESTART";
+ break;
+ case ScriptExecutor::TERMINATE:
+ out << "TERMINATE";
+ break;
+ // Intentionally no default case to make compilation fail if a new value
+ // was added to the enum but not to this list.
+ }
+ return out;
+#endif // NDEBUG
+}
+
} // namespace
ScriptExecutor::ScriptExecutor(
@@ -62,14 +150,16 @@ ScriptExecutor::Result::Result() = default;
ScriptExecutor::Result::~Result() = default;
void ScriptExecutor::Run(RunScriptCallback callback) {
+ DVLOG(2) << "Starting script " << script_path_;
(*scripts_state_)[script_path_] = SCRIPT_STATUS_RUNNING;
callback_ = std::move(callback);
DCHECK(delegate_->GetService());
+ DVLOG(2) << "GetActions for " << delegate_->GetCurrentURL().host();
delegate_->GetService()->GetActions(
- script_path_, delegate_->GetWebController()->GetUrl(),
- delegate_->GetParameters(), last_global_payload_, last_script_payload_,
+ script_path_, delegate_->GetCurrentURL(), delegate_->GetParameters(),
+ last_global_payload_, last_script_payload_,
base::BindOnce(&ScriptExecutor::OnGetActions,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -122,16 +212,12 @@ void ScriptExecutor::ClickOrTapElement(
}
void ScriptExecutor::GetPaymentInformation(
- payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)> callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks) {
+ std::unique_ptr<PaymentRequestOptions> options) {
+ options->callback = base::BindOnce(&ScriptExecutor::OnGetPaymentInformation,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::move(options->callback));
+ delegate_->SetPaymentRequestOptions(std::move(options));
delegate_->EnterState(AutofillAssistantState::PROMPT);
- delegate_->GetUiController()->GetPaymentInformation(
- std::move(payment_options),
- base::BindOnce(&ScriptExecutor::OnGetPaymentInformation,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
- title, supported_basic_card_networks);
}
void ScriptExecutor::OnGetPaymentInformation(
@@ -163,7 +249,8 @@ void ScriptExecutor::OnGetFullCard(GetFullCardCallback callback,
std::move(callback).Run(std::move(card), cvc);
}
-void ScriptExecutor::Prompt(std::unique_ptr<std::vector<Chip>> chips) {
+void ScriptExecutor::Prompt(std::unique_ptr<std::vector<Chip>> chips,
+ base::OnceCallback<void()> on_terminate) {
if (touchable_element_area_) {
// SetChips reproduces the end-of-script appearance and behavior during
// script execution. This includes allowing access to touchable elements,
@@ -188,11 +275,16 @@ void ScriptExecutor::Prompt(std::unique_ptr<std::vector<Chip>> chips) {
}
delegate_->EnterState(AutofillAssistantState::PROMPT);
- delegate_->GetUiController()->SetChips(std::move(chips));
+ delegate_->SetChips(std::move(chips));
+ on_terminate_prompt_ = std::move(on_terminate);
}
void ScriptExecutor::CancelPrompt() {
- delegate_->GetUiController()->ClearChips();
+ // Delete on_terminate_prompt_ if necessary, without running.
+ if (on_terminate_prompt_)
+ std::move(on_terminate_prompt_);
+
+ delegate_->SetChips(nullptr);
CleanUpAfterPrompt();
}
@@ -246,12 +338,12 @@ void ScriptExecutor::SetTouchableElementArea(
std::make_unique<ElementAreaProto>(touchable_element_area);
}
-void ScriptExecutor::ShowProgressBar(int progress) {
- delegate_->GetUiController()->ShowProgressBar(progress);
+void ScriptExecutor::SetProgress(int progress) {
+ delegate_->SetProgress(progress);
}
-void ScriptExecutor::HideProgressBar() {
- delegate_->GetUiController()->HideProgressBar();
+void ScriptExecutor::SetProgressVisible(bool visible) {
+ delegate_->SetProgressVisible(visible);
}
void ScriptExecutor::SetFieldValue(const Selector& selector,
@@ -304,6 +396,16 @@ void ScriptExecutor::Terminate() {
wait_with_interrupts_->Terminate();
at_end_ = TERMINATE;
should_stop_script_ = true;
+
+ // Force PR and other prompt-based actions to end.
+ //
+ // TODO(b/128300038): get rid of this special case. Instead, delete actions
+ // without waiting for them to return.
+ delegate_->CancelPaymentRequest();
+ if (on_terminate_prompt_) {
+ std::move(on_terminate_prompt_).Run();
+ CancelPrompt();
+ }
}
void ScriptExecutor::Close() {
@@ -315,15 +417,6 @@ void ScriptExecutor::Restart() {
at_end_ = RESTART;
}
-void ScriptExecutor::StopCurrentScriptAndShutdown(const std::string& message) {
- // Use a default message when |message| is empty.
- delegate_->SetStatusMessage(
- message.empty() ? l10n_util::GetStringUTF8(IDS_AUTOFILL_ASSISTANT_GIVE_UP)
- : message);
- at_end_ = SHUTDOWN_GRACEFULLY;
- should_stop_script_ = true;
-}
-
ClientMemory* ScriptExecutor::GetClientMemory() {
return delegate_->GetClientMemory();
}
@@ -336,16 +429,21 @@ content::WebContents* ScriptExecutor::GetWebContents() {
return delegate_->GetWebContents();
}
-void ScriptExecutor::ClearDetails() {
- delegate_->ClearDetails();
+void ScriptExecutor::SetDetails(std::unique_ptr<Details> details) {
+ return delegate_->SetDetails(std::move(details));
}
-void ScriptExecutor::SetDetails(const Details& details) {
- return delegate_->SetDetails(details);
+void ScriptExecutor::ClearInfoBox() {
+ delegate_->ClearInfoBox();
+}
+
+void ScriptExecutor::SetInfoBox(const InfoBox& info_box) {
+ delegate_->SetInfoBox(info_box);
}
void ScriptExecutor::OnGetActions(bool result, const std::string& response) {
bool success = result && ProcessNextActionResponse(response);
+ DVLOG(2) << __func__ << " result=" << result;
if (should_stop_script_) {
// The last action forced the script to stop. Sending the result of the
// action is considered best effort in this situation. Report a successful
@@ -406,7 +504,7 @@ void ScriptExecutor::ReportScriptsUpdateToListener(
void ScriptExecutor::RunCallback(bool success) {
DCHECK(callback_);
if (should_clean_contextual_ui_on_finish_ || !success) {
- ClearDetails();
+ SetDetails(nullptr);
should_clean_contextual_ui_on_finish_ = false;
}
@@ -430,7 +528,7 @@ void ScriptExecutor::ProcessNextAction() {
// we could have more |processed_actions| than |actions_|.
if (actions_.size() <= processed_actions_.size()) {
DCHECK_EQ(actions_.size(), processed_actions_.size());
- // Request more actions to execute.
+ DVLOG(2) << __func__ << ", get more actions";
GetNextActions();
return;
}
@@ -450,6 +548,7 @@ void ScriptExecutor::ProcessNextAction() {
}
void ScriptExecutor::ProcessAction(Action* action) {
+ DVLOG(2) << "Begin action: " << *action;
action->ProcessAction(this, base::BindOnce(&ScriptExecutor::OnProcessedAction,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -474,6 +573,8 @@ void ScriptExecutor::OnProcessedAction(
ProcessedActionStatusProto::USER_ABORTED_ACTION);
}
if (processed_action.status() != ProcessedActionStatusProto::ACTION_APPLIED) {
+ DVLOG(1) << "Action failed: " << processed_action.status()
+ << ", get more actions";
// Report error immediately, interrupting action processing.
GetNextActions();
return;
@@ -562,9 +663,8 @@ void ScriptExecutor::WaitWithInterrupts::Run() {
}
interrupt->precondition->Check(
- main_script_->delegate_->GetWebController()->GetUrl(),
- batch_element_checker_.get(), main_script_->delegate_->GetParameters(),
- *main_script_->scripts_state_,
+ main_script_->delegate_->GetCurrentURL(), batch_element_checker_.get(),
+ main_script_->delegate_->GetParameters(), *main_script_->scripts_state_,
base::BindOnce(&WaitWithInterrupts::OnPreconditionCheckDone,
weak_ptr_factory_.GetWeakPtr(),
base::Unretained(interrupt)));
@@ -705,4 +805,11 @@ void ScriptExecutor::WaitWithInterrupts::Terminate() {
interrupt_executor_->Terminate();
}
+std::ostream& operator<<(std::ostream& out,
+ const ScriptExecutor::Result& result) {
+ result.success ? out << "succeeded. " : out << "failed. ";
+ out << "at_end = " << result.at_end;
+ return out;
+}
+
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/script_executor.h b/chromium/components/autofill_assistant/browser/script_executor.h
index 3a055d9fd72..853078c9f11 100644
--- a/chromium/components/autofill_assistant/browser/script_executor.h
+++ b/chromium/components/autofill_assistant/browser/script_executor.h
@@ -8,6 +8,7 @@
#include <deque>
#include <map>
#include <memory>
+#include <ostream>
#include <set>
#include <string>
#include <vector>
@@ -17,6 +18,7 @@
#include "components/autofill_assistant/browser/actions/action.h"
#include "components/autofill_assistant/browser/actions/action_delegate.h"
#include "components/autofill_assistant/browser/details.h"
+#include "components/autofill_assistant/browser/info_box.h"
#include "components/autofill_assistant/browser/script.h"
#include "components/autofill_assistant/browser/script_executor_delegate.h"
#include "components/autofill_assistant/browser/service.pb.h"
@@ -87,6 +89,8 @@ class ScriptExecutor : public ActionDelegate {
Result();
~Result();
+
+ friend std::ostream& operator<<(std::ostream& out, const Result& result);
};
using RunScriptCallback = base::OnceCallback<void(const Result&)>;
@@ -111,12 +115,10 @@ class ScriptExecutor : public ActionDelegate {
void ClickOrTapElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) override;
void GetPaymentInformation(
- payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)> callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks) override;
+ std::unique_ptr<PaymentRequestOptions> options) override;
void GetFullCard(GetFullCardCallback callback) override;
- void Prompt(std::unique_ptr<std::vector<Chip>> chips) override;
+ void Prompt(std::unique_ptr<std::vector<Chip>> chips,
+ base::OnceCallback<void()> on_terminate) override;
void CancelPrompt() override;
void FillAddressForm(const autofill::AutofillProfile* profile,
const Selector& selector,
@@ -155,11 +157,11 @@ class ScriptExecutor : public ActionDelegate {
ClientMemory* GetClientMemory() override;
autofill::PersonalDataManager* GetPersonalDataManager() override;
content::WebContents* GetWebContents() override;
- void StopCurrentScriptAndShutdown(const std::string& message) override;
- void ClearDetails() override;
- void SetDetails(const Details& details) override;
- void ShowProgressBar(int progress) override;
- void HideProgressBar() override;
+ void SetDetails(std::unique_ptr<Details> details) override;
+ void ClearInfoBox() override;
+ void SetInfoBox(const InfoBox& info_box) override;
+ void SetProgress(int progress) override;
+ void SetProgressVisible(bool visible) override;
private:
// Helper for WaitForElementVisible that keeps track of the state required to
@@ -310,6 +312,10 @@ class ScriptExecutor : public ActionDelegate {
std::unique_ptr<WaitWithInterrupts> wait_with_interrupts_;
+ // Callback set by Prompt(). This is called when the prompt is terminated
+ // without selecting any chips. nullptr unless showing a prompt.
+ base::OnceCallback<void()> on_terminate_prompt_;
+
base::WeakPtrFactory<ScriptExecutor> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ScriptExecutor);
};
diff --git a/chromium/components/autofill_assistant/browser/script_executor_delegate.h b/chromium/components/autofill_assistant/browser/script_executor_delegate.h
index b728f774348..8881a0feb7e 100644
--- a/chromium/components/autofill_assistant/browser/script_executor_delegate.h
+++ b/chromium/components/autofill_assistant/browser/script_executor_delegate.h
@@ -6,10 +6,16 @@
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SCRIPT_EXECUTOR_DELEGATE_H_
#include <map>
+#include <memory>
#include <string>
+#include <vector>
+#include "components/autofill_assistant/browser/chip.h"
#include "components/autofill_assistant/browser/details.h"
+#include "components/autofill_assistant/browser/info_box.h"
+#include "components/autofill_assistant/browser/payment_request.h"
#include "components/autofill_assistant/browser/state.h"
+#include "url/gurl.h"
namespace autofill {
class PersonalDataManager;
@@ -28,20 +34,14 @@ class ClientMemory;
class ScriptExecutorDelegate {
public:
+ virtual const GURL& GetCurrentURL() = 0;
virtual Service* GetService() = 0;
-
virtual UiController* GetUiController() = 0;
-
virtual WebController* GetWebController() = 0;
-
virtual ClientMemory* GetClientMemory() = 0;
-
virtual const std::map<std::string, std::string>& GetParameters() = 0;
-
virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
-
virtual content::WebContents* GetWebContents() = 0;
-
virtual void EnterState(AutofillAssistantState state) = 0;
// Make the area of the screen that correspond to the given elements
@@ -49,8 +49,15 @@ class ScriptExecutorDelegate {
virtual void SetTouchableElementArea(const ElementAreaProto& element) = 0;
virtual void SetStatusMessage(const std::string& message) = 0;
virtual std::string GetStatusMessage() const = 0;
- virtual void SetDetails(const Details& details) = 0;
- virtual void ClearDetails() = 0;
+ virtual void SetDetails(std::unique_ptr<Details> details) = 0;
+ virtual void SetInfoBox(const InfoBox& info_box) = 0;
+ virtual void ClearInfoBox() = 0;
+ virtual void SetPaymentRequestOptions(
+ std::unique_ptr<PaymentRequestOptions> options) = 0;
+ virtual void CancelPaymentRequest() = 0;
+ virtual void SetProgress(int progress) = 0;
+ virtual void SetProgressVisible(bool visible) = 0;
+ virtual void SetChips(std::unique_ptr<std::vector<Chip>> chips) = 0;
// Makes no area of the screen touchable.
void ClearTouchableElementArea() {
diff --git a/chromium/components/autofill_assistant/browser/script_executor_unittest.cc b/chromium/components/autofill_assistant/browser/script_executor_unittest.cc
index 9a4b3915029..955a728c01d 100644
--- a/chromium/components/autofill_assistant/browser/script_executor_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -11,6 +11,7 @@
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill_assistant/browser/client_memory.h"
+#include "components/autofill_assistant/browser/fake_script_executor_delegate.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_service.h"
#include "components/autofill_assistant/browser/mock_ui_controller.h"
@@ -44,17 +45,20 @@ using ::testing::StrictMock;
const char* kScriptPath = "script_path";
class ScriptExecutorTest : public testing::Test,
- public ScriptExecutorDelegate,
public ScriptExecutor::Listener {
public:
void SetUp() override {
+ delegate_.SetService(&mock_service_);
+ delegate_.SetUiController(&mock_ui_controller_);
+ delegate_.SetWebController(&mock_web_controller_);
+ delegate_.SetCurrentURL(GURL("http://example.com/"));
+
executor_ = std::make_unique<ScriptExecutor>(
kScriptPath,
/* global_payload= */ "initial global payload",
/* script_payload= */ "initial payload",
/* listener= */ this, &scripts_state_, &ordered_interrupts_,
- /* delegate= */ this);
- url_ = GURL("http://example.com/");
+ /* delegate= */ &delegate_);
// In this test, "tell" actions always succeed and "click" actions always
// fail. The following makes a click action fail immediately
@@ -65,7 +69,6 @@ class ScriptExecutorTest : public testing::Test,
.WillByDefault(RunOnceCallback<2>(true));
ON_CALL(mock_web_controller_, OnFocusElement(_, _))
.WillByDefault(RunOnceCallback<1>(true));
- ON_CALL(mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_));
}
protected:
@@ -73,39 +76,6 @@ class ScriptExecutorTest : public testing::Test,
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}
- // Implements ScriptExecutorDelegate
- Service* GetService() override { return &mock_service_; }
-
- UiController* GetUiController() override { return &mock_ui_controller_; }
-
- WebController* GetWebController() override { return &mock_web_controller_; }
-
- ClientMemory* GetClientMemory() override { return &memory_; }
-
- void SetTouchableElementArea(const ElementAreaProto& area) {}
-
- void SetStatusMessage(const std::string& status_message) {
- status_message_ = status_message;
- }
-
- std::string GetStatusMessage() const override { return status_message_; }
-
- void ClearDetails() override { cleared_details_ = true; }
-
- void SetDetails(const Details& details) override {}
-
- void EnterState(AutofillAssistantState state) {}
-
- const std::map<std::string, std::string>& GetParameters() override {
- return parameters_;
- }
-
- autofill::PersonalDataManager* GetPersonalDataManager() override {
- return nullptr;
- }
-
- content::WebContents* GetWebContents() override { return nullptr; }
-
// Implements ScriptExecutor::Listener
void OnServerPayloadChanged(const std::string& global_payload,
const std::string& script_payload) override {
@@ -175,8 +145,8 @@ class ScriptExecutorTest : public testing::Test,
// scoped_task_environment_ must be first to guarantee other field
// creation run in that environment.
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ FakeScriptExecutorDelegate delegate_;
Script script_;
- ClientMemory memory_;
StrictMock<MockService> mock_service_;
NiceMock<MockWebController> mock_web_controller_;
NiceMock<MockUiController> mock_ui_controller_;
@@ -191,12 +161,8 @@ class ScriptExecutorTest : public testing::Test,
std::vector<std::unique_ptr<Script>> scripts_update_;
int scripts_update_count_ = 0;
std::unique_ptr<ScriptExecutor> executor_;
- std::map<std::string, std::string> parameters_;
StrictMock<base::MockCallback<ScriptExecutor::RunScriptCallback>>
executor_callback_;
- GURL url_;
- std::string status_message_;
- bool cleared_details_ = false;
};
TEST_F(ScriptExecutorTest, GetActionsFails) {
@@ -210,8 +176,9 @@ TEST_F(ScriptExecutorTest, GetActionsFails) {
}
TEST_F(ScriptExecutorTest, ForwardParameters) {
- parameters_["param1"] = "value1";
- parameters_["param2"] = "value2";
+ auto* parameters = delegate_.GetMutableParameters();
+ (*parameters)["param1"] = "value1";
+ (*parameters)["param2"] = "value2";
EXPECT_CALL(mock_service_,
OnGetActions(StrEq(kScriptPath), _,
AllOf(Contains(Pair("param1", "value1")),
@@ -381,14 +348,14 @@ TEST_F(ScriptExecutorTest, RunDelayedAction) {
// executor_callback_.Run() not expected to be run just yet, as the action is
// delayed.
executor_->Run(executor_callback_.Get());
- EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_TRUE(scoped_task_environment_.NextTaskIsDelayed());
// Moving forward in time triggers action execution.
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, true)));
scoped_task_environment_.FastForwardBy(
base::TimeDelta::FromMilliseconds(1000));
- EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
+ EXPECT_EQ(scoped_task_environment_.GetPendingMainThreadTaskCount(), 0u);
}
TEST_F(ScriptExecutorTest, ClearDetailsWhenFinished) {
@@ -405,8 +372,10 @@ TEST_F(ScriptExecutorTest, ClearDetailsWhenFinished) {
.WillOnce(RunOnceCallback<3>(true, ""));
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, true)));
+
+ delegate_.SetDetails(std::make_unique<Details>()); // empty, but not null
executor_->Run(executor_callback_.Get());
- EXPECT_TRUE(cleared_details_);
+ EXPECT_EQ(nullptr, delegate_.GetDetails());
}
TEST_F(ScriptExecutorTest, DontClearDetailsIfOtherActionsAreLeft) {
@@ -424,9 +393,9 @@ TEST_F(ScriptExecutorTest, DontClearDetailsIfOtherActionsAreLeft) {
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, true)));
+ delegate_.SetDetails(std::make_unique<Details>()); // empty, but not null
executor_->Run(executor_callback_.Get());
-
- EXPECT_FALSE(cleared_details_);
+ EXPECT_NE(nullptr, delegate_.GetDetails());
}
TEST_F(ScriptExecutorTest, ClearDetailsOnError) {
@@ -438,9 +407,9 @@ TEST_F(ScriptExecutorTest, ClearDetailsOnError) {
.WillOnce(RunOnceCallback<3>(false, ""));
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, false)));
-
+ delegate_.SetDetails(std::make_unique<Details>()); // empty, but not null
executor_->Run(executor_callback_.Get());
- EXPECT_TRUE(cleared_details_);
+ EXPECT_EQ(nullptr, delegate_.GetDetails());
}
TEST_F(ScriptExecutorTest, UpdateScriptStateWhileRunning) {
@@ -917,9 +886,9 @@ TEST_F(ScriptExecutorTest, RestorePreInterruptStatusMessage) {
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, true)));
- status_message_ = "pre-run status";
+ delegate_.SetStatusMessage("pre-run status");
executor_->Run(executor_callback_.Get());
- EXPECT_EQ("pre-interrupt status", status_message_);
+ EXPECT_EQ("pre-interrupt status", delegate_.GetStatusMessage());
}
TEST_F(ScriptExecutorTest, KeepStatusMessageWhenNotInterrupted) {
@@ -938,9 +907,9 @@ TEST_F(ScriptExecutorTest, KeepStatusMessageWhenNotInterrupted) {
EXPECT_CALL(executor_callback_,
Run(Field(&ScriptExecutor::Result::success, true)));
- status_message_ = "pre-run status";
+ delegate_.SetStatusMessage("pre-run status");
executor_->Run(executor_callback_.Get());
- EXPECT_EQ("pre-interrupt status", status_message_);
+ EXPECT_EQ("pre-interrupt status", delegate_.GetStatusMessage());
}
} // namespace
diff --git a/chromium/components/autofill_assistant/browser/script_precondition.cc b/chromium/components/autofill_assistant/browser/script_precondition.cc
index b56c04a494e..bab669ff6a0 100644
--- a/chromium/components/autofill_assistant/browser/script_precondition.cc
+++ b/chromium/components/autofill_assistant/browser/script_precondition.cc
@@ -15,61 +15,30 @@
#include "url/gurl.h"
namespace autofill_assistant {
+
// Static
std::unique_ptr<ScriptPrecondition> ScriptPrecondition::FromProto(
const std::string& script_path,
const ScriptPreconditionProto& script_precondition_proto) {
- std::vector<Selector> elements_exist;
- for (const auto& element : script_precondition_proto.elements_exist()) {
- // TODO(crbug.com/806868): Check if we shouldn't skip the script when this
- // happens.
- if (element.selectors_size() == 0) {
- DLOG(WARNING)
- << "Empty selectors in script precondition for script path: "
- << script_path << ".";
- continue;
- }
-
- elements_exist.emplace_back(Selector(element));
- }
-
- std::set<std::string> domain_match;
- for (const auto& domain : script_precondition_proto.domain()) {
- domain_match.emplace(domain);
- }
-
std::vector<std::unique_ptr<re2::RE2>> path_pattern;
for (const auto& pattern : script_precondition_proto.path_pattern()) {
auto re = std::make_unique<re2::RE2>(pattern);
if (re->error_code() != re2::RE2::NoError) {
- DLOG(ERROR) << "Invalid regexp in script precondition '" << pattern
- << "' for script path: " << script_path << ".";
+ DVLOG(1) << "Invalid regexp in script precondition '" << pattern
+ << "' for script path: " << script_path << ".";
return nullptr;
}
path_pattern.emplace_back(std::move(re));
}
- std::vector<ScriptParameterMatchProto> parameter_match;
- for (const auto& match : script_precondition_proto.script_parameter_match()) {
- parameter_match.emplace_back(match);
- }
-
- std::vector<FormValueMatchProto> form_value_match;
- for (const auto& match : script_precondition_proto.form_value_match()) {
- form_value_match.emplace_back(match);
- }
-
- std::vector<ScriptStatusMatchProto> status_matches;
- for (const auto& status_match :
- script_precondition_proto.script_status_match()) {
- status_matches.push_back(status_match);
- }
-
// TODO(crbug.com/806868): Detect unknown or unsupported conditions and
// reject them.
return std::make_unique<ScriptPrecondition>(
- elements_exist, domain_match, std::move(path_pattern), parameter_match,
- form_value_match, status_matches);
+ script_precondition_proto.domain(), std::move(path_pattern),
+ script_precondition_proto.script_status_match(),
+ script_precondition_proto.script_parameter_match(),
+ script_precondition_proto.elements_exist(),
+ script_precondition_proto.form_value_match());
}
ScriptPrecondition::~ScriptPrecondition() {}
@@ -85,46 +54,25 @@ void ScriptPrecondition::Check(
std::move(callback).Run(false);
return;
}
-
- pending_check_count_ = elements_exist_.size() + form_value_match_.size();
- if (pending_check_count_ == 0) {
- std::move(callback).Run(true);
- return;
- }
-
- check_preconditions_callback_ = std::move(callback);
- for (const auto& selector : elements_exist_) {
- base::OnceCallback<void(bool)> callback =
- base::BindOnce(&ScriptPrecondition::OnCheckElementExists,
- weak_ptr_factory_.GetWeakPtr());
- batch_checks->AddElementCheck(kExistenceCheck, selector,
- std::move(callback));
- }
- for (size_t i = 0; i < form_value_match_.size(); i++) {
- const auto& value_match = form_value_match_[i];
- DCHECK(!value_match.element().selectors().empty());
- batch_checks->AddFieldValueCheck(
- Selector(value_match.element()),
- base::BindOnce(&ScriptPrecondition::OnGetFieldValue,
- weak_ptr_factory_.GetWeakPtr(), i));
- }
+ element_precondition_.Check(batch_checks, std::move(callback));
}
ScriptPrecondition::ScriptPrecondition(
- const std::vector<Selector>& elements_exist,
- const std::set<std::string>& domain_match,
+ const google::protobuf::RepeatedPtrField<std::string>& domain_match,
std::vector<std::unique_ptr<re2::RE2>> path_pattern,
- const std::vector<ScriptParameterMatchProto>& parameter_match,
- const std::vector<FormValueMatchProto>& form_value_match,
- const std::vector<ScriptStatusMatchProto>& status_match)
- : elements_exist_(elements_exist),
- domain_match_(domain_match),
+ const google::protobuf::RepeatedPtrField<ScriptStatusMatchProto>&
+ status_match,
+ const google::protobuf::RepeatedPtrField<ScriptParameterMatchProto>&
+ parameter_match,
+ const google::protobuf::RepeatedPtrField<ElementReferenceProto>&
+ element_exists,
+ const google::protobuf::RepeatedPtrField<FormValueMatchProto>&
+ form_value_match)
+ : domain_match_(domain_match.begin(), domain_match.end()),
path_pattern_(std::move(path_pattern)),
- parameter_match_(parameter_match),
- form_value_match_(form_value_match),
- status_match_(status_match),
- pending_check_count_(0),
- weak_ptr_factory_(this) {}
+ parameter_match_(parameter_match.begin(), parameter_match.end()),
+ status_match_(status_match.begin(), status_match.end()),
+ element_precondition_(element_exists, form_value_match) {}
bool ScriptPrecondition::MatchDomain(const GURL& url) const {
if (domain_match_.empty())
@@ -197,42 +145,4 @@ bool ScriptPrecondition::MatchScriptStatus(
return true;
}
-void ScriptPrecondition::OnCheckElementExists(bool exists) {
- ReportCheckResult(exists);
-}
-
-void ScriptPrecondition::OnGetFieldValue(int index,
- bool exists,
- const std::string& value) {
- if (!exists) {
- ReportCheckResult(false);
- return;
- }
-
- // TODO(crbug.com/806868): Differentiate between empty value and failure.
- const auto& value_match = form_value_match_[index];
- if (value_match.has_value()) {
- ReportCheckResult(value == value_match.value());
- return;
- }
-
- ReportCheckResult(!value.empty());
-}
-
-void ScriptPrecondition::ReportCheckResult(bool success) {
- if (!check_preconditions_callback_)
- return;
-
- if (!success) {
- std::move(check_preconditions_callback_).Run(false);
- return;
- }
-
- --pending_check_count_;
- if (pending_check_count_ <= 0) {
- DCHECK_EQ(pending_check_count_, 0);
- std::move(check_preconditions_callback_).Run(true);
- }
-}
-
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/script_precondition.h b/chromium/components/autofill_assistant/browser/script_precondition.h
index d1c60273271..88ff96a96cd 100644
--- a/chromium/components/autofill_assistant/browser/script_precondition.h
+++ b/chromium/components/autofill_assistant/browser/script_precondition.h
@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/element_precondition.h"
#include "components/autofill_assistant/browser/service.pb.h"
#include "components/autofill_assistant/browser/web_controller.h"
@@ -37,12 +38,17 @@ class ScriptPrecondition {
const ScriptPreconditionProto& script_precondition_proto);
ScriptPrecondition(
- const std::vector<Selector>& elements_exist,
- const std::set<std::string>& domain_match,
+ const google::protobuf::RepeatedPtrField<std::string>& domain_match,
std::vector<std::unique_ptr<re2::RE2>> path_pattern,
- const std::vector<ScriptParameterMatchProto>& parameter_match,
- const std::vector<FormValueMatchProto>& form_value_match,
- const std::vector<ScriptStatusMatchProto>& status_match);
+ const google::protobuf::RepeatedPtrField<ScriptStatusMatchProto>&
+ status_match,
+ const google::protobuf::RepeatedPtrField<ScriptParameterMatchProto>&
+ parameter_match,
+ const google::protobuf::RepeatedPtrField<ElementReferenceProto>&
+ element_exists,
+ const google::protobuf::RepeatedPtrField<FormValueMatchProto>&
+ form_value_match);
+
~ScriptPrecondition();
// Check whether the conditions satisfied and return the result through
@@ -64,12 +70,6 @@ class ScriptPrecondition {
bool MatchScriptStatus(
const std::map<std::string, ScriptStatusProto>& executed_scripts) const;
- void OnCheckElementExists(bool exists);
- void OnGetFieldValue(int index, bool exists, const std::string& value);
- void ReportCheckResult(bool success);
-
- std::vector<Selector> elements_exist_;
-
// Domain (exact match) excluding the last '/' character.
std::set<std::string> domain_match_;
@@ -79,20 +79,10 @@ class ScriptPrecondition {
// Condition on parameters, identified by name, as found in the intent.
std::vector<ScriptParameterMatchProto> parameter_match_;
- // Conditions on form fields value.
- std::vector<FormValueMatchProto> form_value_match_;
-
// Conditions regarding the execution status of passed scripts.
std::vector<ScriptStatusMatchProto> status_match_;
- // Number of checks for which there's still no result.
- int pending_check_count_;
-
- // A callback called as soon as an element or field check fails or, failing
- // that, when |pending_check_count_| reaches 0.
- base::OnceCallback<void(bool)> check_preconditions_callback_;
-
- base::WeakPtrFactory<ScriptPrecondition> weak_ptr_factory_;
+ ElementPrecondition element_precondition_;
DISALLOW_COPY_AND_ASSIGN(ScriptPrecondition);
};
diff --git a/chromium/components/autofill_assistant/browser/script_precondition_unittest.cc b/chromium/components/autofill_assistant/browser/script_precondition_unittest.cc
index 03ca796d1fb..fd7a02cc0eb 100644
--- a/chromium/components/autofill_assistant/browser/script_precondition_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/script_precondition_unittest.cc
@@ -64,11 +64,6 @@ class ScriptPreconditionTest : public testing::Test {
.WillByDefault(RunOnceCallback<2>(false));
SetUrl("http://www.example.com/path");
- ON_CALL(mock_web_controller_, OnGetFieldValue(Eq(Selector({"exists"})), _))
- .WillByDefault(RunOnceCallback<1>(true, "foo"));
- ON_CALL(mock_web_controller_,
- OnGetFieldValue(Eq(Selector({"does_not_exist"})), _))
- .WillByDefault(RunOnceCallback<1>(false, ""));
}
protected:
@@ -316,22 +311,5 @@ TEST_F(ScriptPreconditionTest, MultipleConditions) {
EXPECT_FALSE(Check(proto)) << "Element can not match.";
}
-TEST_F(ScriptPreconditionTest, FormValueMatch) {
- ScriptPreconditionProto proto;
- FormValueMatchProto* match = proto.add_form_value_match();
- match->mutable_element()->add_selectors("exists");
- EXPECT_TRUE(Check(proto));
-
- match->set_value("bar");
- EXPECT_FALSE(Check(proto));
-
- match->set_value("foo");
- EXPECT_TRUE(Check(proto));
-
- match->clear_value();
- match->mutable_element()->set_selectors(0, "does_not_exist");
- EXPECT_FALSE(Check(proto));
-}
-
} // namespace
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/script_tracker.cc b/chromium/components/autofill_assistant/browser/script_tracker.cc
index 78f45117a15..104ec3163c8 100644
--- a/chromium/components/autofill_assistant/browser/script_tracker.cc
+++ b/chromium/components/autofill_assistant/browser/script_tracker.cc
@@ -36,7 +36,6 @@ ScriptTracker::ScriptTracker(ScriptExecutorDelegate* delegate,
ScriptTracker::Listener* listener)
: delegate_(delegate),
listener_(listener),
- reported_runnable_scripts_(false),
weak_ptr_factory_(this) {
DCHECK(delegate_);
DCHECK(listener_);
@@ -73,6 +72,7 @@ void ScriptTracker::CheckScripts(const base::TimeDelta& max_duration) {
DCHECK(pending_runnable_scripts_.empty());
+ GURL url = delegate_->GetCurrentURL();
batch_element_checker_ =
delegate_->GetWebController()->CreateBatchElementChecker();
for (const auto& entry : available_scripts_) {
@@ -81,17 +81,19 @@ void ScriptTracker::CheckScripts(const base::TimeDelta& max_duration) {
continue;
script->precondition->Check(
- delegate_->GetWebController()->GetUrl(), batch_element_checker_.get(),
- delegate_->GetParameters(), scripts_state_,
+ url, batch_element_checker_.get(), delegate_->GetParameters(),
+ scripts_state_,
base::BindOnce(&ScriptTracker::OnPreconditionCheck,
weak_ptr_factory_.GetWeakPtr(), script));
}
if (batch_element_checker_->all_found() &&
- pending_runnable_scripts_.empty() && reported_runnable_scripts_) {
+ pending_runnable_scripts_.empty() && !available_scripts_.empty()) {
+ DVLOG(1) << __func__ << ": No runnable scripts for " << url << " out of "
+ << available_scripts_.size() << " available.";
// There are no runnable scripts, even though we haven't checked the DOM
// yet. Report it all immediately.
UpdateRunnableScriptsIfNecessary();
- listener_->OnNoRunnableScriptsAnymore();
+ listener_->OnNoRunnableScripts();
OnCheckDone();
return;
}
@@ -108,8 +110,8 @@ void ScriptTracker::CheckScripts(const base::TimeDelta& max_duration) {
void ScriptTracker::ExecuteScript(const std::string& script_path,
ScriptExecutor::RunScriptCallback callback) {
if (running()) {
- DLOG(ERROR) << "Do not expect executing the script (" << script_path
- << " when there is a script running.";
+ DVLOG(1) << "Do not expect executing the script (" << script_path
+ << " when there is a script running.";
ScriptExecutor::Result result;
result.success = false;
std::move(callback).Run(result);
@@ -170,7 +172,7 @@ base::Value ScriptTracker::GetDebugContext() const {
script_js.SetKey("path", base::Value(entry.path));
script_js.SetKey("initial_prompt", base::Value(entry.initial_prompt));
script_js.SetKey("autostart", base::Value(entry.autostart));
- script_js.SetKey("highlight", base::Value(entry.highlight));
+ script_js.SetKey("chip_type", base::Value(entry.chip_type));
runnable_scripts_js.push_back(std::move(script_js));
}
dict.SetKey("runnable-scripts", base::Value(runnable_scripts_js));
@@ -204,7 +206,6 @@ void ScriptTracker::UpdateRunnableScriptsIfNecessary() {
runnable_scripts_.push_back(script->handle);
}
- reported_runnable_scripts_ = true;
listener_->OnRunnableScriptsChanged(runnable_scripts_);
}
diff --git a/chromium/components/autofill_assistant/browser/script_tracker.h b/chromium/components/autofill_assistant/browser/script_tracker.h
index 515933e43e6..fdec2a4c5d8 100644
--- a/chromium/components/autofill_assistant/browser/script_tracker.h
+++ b/chromium/components/autofill_assistant/browser/script_tracker.h
@@ -45,9 +45,9 @@ class ScriptTracker : public ScriptExecutor::Listener {
//
// This is not called if a DOM change could make some scripts runnable.
//
- // This is not called until some scripts have been reported runnable to
- // OnRunnableScriptsChanged at least once.
- virtual void OnNoRunnableScriptsAnymore() = 0;
+ // This is only called when there are scripts. That is, SetScripts was last
+ // passed a non-empty vector.
+ virtual void OnNoRunnableScripts() = 0;
};
// |delegate| and |listener| should outlive this object and should not be
@@ -145,11 +145,6 @@ class ScriptTracker : public ScriptExecutor::Listener {
// the bottom bar.
std::vector<ScriptHandle> runnable_scripts_;
- // True if OnRunnableScriptsChanged was called at least once - necessarily
- // with a non-empty set of scripts the first time, since the tracker starts
- // with an empty set of scripts.
- bool reported_runnable_scripts_;
-
// Sets of available scripts. SetScripts resets this and interrupts
// any pending check.
AvailableScriptMap available_scripts_;
diff --git a/chromium/components/autofill_assistant/browser/script_tracker_unittest.cc b/chromium/components/autofill_assistant/browser/script_tracker_unittest.cc
index 4784a1fac3c..9e4cbad266e 100644
--- a/chromium/components/autofill_assistant/browser/script_tracker_unittest.cc
+++ b/chromium/components/autofill_assistant/browser/script_tracker_unittest.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "base/test/mock_callback.h"
-#include "components/autofill_assistant/browser/client_memory.h"
+#include "components/autofill_assistant/browser/fake_script_executor_delegate.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_service.h"
#include "components/autofill_assistant/browser/mock_ui_controller.h"
@@ -30,11 +30,11 @@ using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::UnorderedElementsAre;
-class ScriptTrackerTest : public testing::Test,
- public ScriptTracker::Listener,
- public ScriptExecutorDelegate {
+class ScriptTrackerTest : public testing::Test, public ScriptTracker::Listener {
public:
void SetUp() override {
+ delegate_.SetCurrentURL(GURL("http://www.example.com/"));
+
ON_CALL(mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"exists"})), _))
.WillByDefault(RunOnceCallback<2>(true));
@@ -42,7 +42,6 @@ class ScriptTrackerTest : public testing::Test,
mock_web_controller_,
OnElementCheck(kExistenceCheck, Eq(Selector({"does_not_exist"})), _))
.WillByDefault(RunOnceCallback<2>(false));
- ON_CALL(mock_web_controller_, GetUrl()).WillByDefault(ReturnRef(url_));
// Scripts run, but have no actions.
ON_CALL(mock_service_, OnGetActions(_, _, _, _, _, _))
@@ -53,40 +52,12 @@ class ScriptTrackerTest : public testing::Test,
ScriptTrackerTest()
: no_runnable_scripts_anymore_(0),
runnable_scripts_changed_(0),
- tracker_(this, this) {}
-
- // Overrides ScriptTrackerDelegate
- Service* GetService() override { return &mock_service_; }
-
- UiController* GetUiController() override { return &mock_ui_controller_; }
-
- WebController* GetWebController() override { return &mock_web_controller_; }
-
- ClientMemory* GetClientMemory() override { return &client_memory_; }
-
- void EnterState(AutofillAssistantState state) override {}
-
- const std::map<std::string, std::string>& GetParameters() override {
- return parameters_;
+ tracker_(&delegate_, /* listener=*/this) {
+ delegate_.SetService(&mock_service_);
+ delegate_.SetUiController(&mock_ui_controller_);
+ delegate_.SetWebController(&mock_web_controller_);
}
- autofill::PersonalDataManager* GetPersonalDataManager() override {
- return nullptr;
- }
-
- content::WebContents* GetWebContents() override { return nullptr; }
-
- void SetTouchableElementArea(const ElementAreaProto& element_area) override {}
-
- void SetStatusMessage(const std::string& status_message) override {
- status_message_ = status_message;
- }
- std::string GetStatusMessage() const { return status_message_; }
-
- void SetDetails(const Details& details) override {}
-
- void ClearDetails() override {}
-
// Overrides ScriptTracker::Listener
void OnRunnableScriptsChanged(
const std::vector<ScriptHandle>& runnable_scripts) override {
@@ -94,22 +65,26 @@ class ScriptTrackerTest : public testing::Test,
runnable_scripts_ = runnable_scripts;
}
- void OnNoRunnableScriptsAnymore() override { no_runnable_scripts_anymore_++; }
+ void OnNoRunnableScripts() override { no_runnable_scripts_anymore_++; }
- void SetAndCheckScripts(const SupportsScriptResponseProto& response) {
- std::string response_str;
- response.SerializeToString(&response_str);
+ void SetAndCheckScripts() {
std::vector<std::unique_ptr<Script>> scripts;
- ProtocolUtils::ParseScripts(response_str, &scripts);
+ for (const auto& script_proto : scripts_proto_) {
+ ProtocolUtils::AddScript(*script_proto, &scripts);
+ }
tracker_.SetScripts(std::move(scripts));
tracker_.CheckScripts(base::TimeDelta::FromSeconds(0));
}
- static SupportedScriptProto* AddScript(SupportsScriptResponseProto* response,
- const std::string& name,
- const std::string& path,
- const std::string& selector) {
- SupportedScriptProto* script = response->add_scripts();
+ SupportedScriptProto* AddScript() {
+ scripts_proto_.emplace_back(new SupportedScriptProto);
+ return scripts_proto_.back().get();
+ }
+
+ SupportedScriptProto* AddScript(const std::string& name,
+ const std::string& path,
+ const std::string& selector) {
+ SupportedScriptProto* script = AddScript();
script->set_path(path);
script->mutable_presentation()->set_name(name);
if (!selector.empty()) {
@@ -150,16 +125,15 @@ class ScriptTrackerTest : public testing::Test,
NiceMock<MockService> mock_service_;
NiceMock<MockWebController> mock_web_controller_;
NiceMock<MockUiController> mock_ui_controller_;
- ClientMemory client_memory_;
- std::map<std::string, std::string> parameters_;
// Number of times NoRunnableScriptsAnymore was called.
int no_runnable_scripts_anymore_;
// Number of times OnRunnableScriptsChanged was called.
int runnable_scripts_changed_;
std::vector<ScriptHandle> runnable_scripts_;
+ FakeScriptExecutorDelegate delegate_;
ScriptTracker tracker_;
- std::string status_message_;
+ std::vector<std::unique_ptr<SupportedScriptProto>> scripts_proto_;
};
TEST_F(ScriptTrackerTest, NoScripts) {
@@ -171,32 +145,30 @@ TEST_F(ScriptTrackerTest, NoScripts) {
}
TEST_F(ScriptTrackerTest, SomeRunnableScripts) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "not runnable name", "not runnable path",
- "does_not_exist");
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("not runnable name", "not runnable path", "does_not_exist");
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
ASSERT_THAT(runnable_scripts(), SizeIs(1));
EXPECT_EQ("runnable name", runnable_scripts()[0].name);
EXPECT_EQ("runnable path", runnable_scripts()[0].path);
+ EXPECT_EQ(0, no_runnable_scripts_anymore_);
}
TEST_F(ScriptTrackerTest, DoNotCheckInterruptWithNoName) {
- SupportsScriptResponseProto scripts;
// The interrupt's preconditions would all be met, but it won't be reported
// since it doesn't have a name.
- auto* no_name = AddScript(&scripts, "", "path1", "exists");
+ auto* no_name = AddScript("", "path1", "exists");
no_name->mutable_presentation()->set_interrupt(true);
// The interrupt's preconditions are met and it will be reported as a normal
// script.
- auto* with_name = AddScript(&scripts, "with name", "path2", "exists");
+ auto* with_name = AddScript("with name", "path2", "exists");
with_name->mutable_presentation()->set_interrupt(true);
- SetAndCheckScripts(scripts);
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
ASSERT_THAT(runnable_scripts(), SizeIs(1));
@@ -204,93 +176,87 @@ TEST_F(ScriptTrackerTest, DoNotCheckInterruptWithNoName) {
}
TEST_F(ScriptTrackerTest, ReportInterruptToAutostart) {
- SupportsScriptResponseProto scripts;
// The interrupt's preconditions are met and it will be reported as runnable
// for autostart.
- auto* autostart = AddScript(&scripts, "", "path2", "exists");
+ auto* autostart = AddScript("", "path2", "exists");
autostart->mutable_presentation()->set_interrupt(true);
autostart->mutable_presentation()->set_autostart(true);
- SetAndCheckScripts(scripts);
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
ASSERT_THAT(runnable_scripts(), SizeIs(1));
}
TEST_F(ScriptTrackerTest, OrderScriptsByPriority) {
- SupportsScriptResponseProto scripts;
-
- SupportedScriptProto* a = scripts.add_scripts();
+ SupportedScriptProto* a = AddScript();
a->set_path("a");
a->mutable_presentation()->set_name("a");
a->mutable_presentation()->set_priority(2);
- SupportedScriptProto* b = scripts.add_scripts();
+ SupportedScriptProto* b = AddScript();
b->set_path("b");
b->mutable_presentation()->set_name("b");
b->mutable_presentation()->set_priority(3);
- SupportedScriptProto* c = scripts.add_scripts();
+ SupportedScriptProto* c = AddScript();
c->set_path("c");
c->mutable_presentation()->set_name("c");
c->mutable_presentation()->set_priority(1);
- SetAndCheckScripts(scripts);
+
+ SetAndCheckScripts();
ASSERT_THAT(runnable_script_paths(), ElementsAre("c", "a", "b"));
}
TEST_F(ScriptTrackerTest, NewScriptChangesNothing) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
- SetAndCheckScripts(scripts);
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
}
TEST_F(ScriptTrackerTest, NewScriptClearsRunnable) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
EXPECT_THAT(runnable_scripts(), SizeIs(1));
- SetAndCheckScripts(SupportsScriptResponseProto::default_instance());
+ scripts_proto_.clear();
+ SetAndCheckScripts();
EXPECT_EQ(2, runnable_scripts_changed_);
EXPECT_THAT(runnable_scripts(), IsEmpty());
}
TEST_F(ScriptTrackerTest, NewScriptAddsRunnable) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
EXPECT_THAT(runnable_scripts(), SizeIs(1));
- AddScript(&scripts, "new runnable name", "new runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("new runnable name", "new runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(2, runnable_scripts_changed_);
EXPECT_THAT(runnable_scripts(), SizeIs(2));
}
TEST_F(ScriptTrackerTest, NewScriptChangesRunnable) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
EXPECT_THAT(runnable_scripts(), SizeIs(1));
- scripts.clear_scripts();
- AddScript(&scripts, "new runnable name", "new runnable path", "exists");
- SetAndCheckScripts(scripts);
+ scripts_proto_.clear();
+ AddScript("new runnable name", "new runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(2, runnable_scripts_changed_);
}
TEST_F(ScriptTrackerTest, CheckScriptsAgainAfterScriptEnd) {
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "script 1", "script1", "exists");
- AddScript(&scripts, "script 2", "script2", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("script 1", "script1", "exists");
+ AddScript("script 2", "script2", "exists");
+ SetAndCheckScripts();
// Both scripts are runnable
EXPECT_EQ(1, runnable_scripts_changed_);
@@ -317,9 +283,8 @@ TEST_F(ScriptTrackerTest, CheckScriptsAfterDOMChange) {
OnElementCheck(kExistenceCheck, Eq(Selector({"maybe_exists"})), _))
.WillOnce(RunOnceCallback<2>(false));
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "script name", "script path", "maybe_exists");
- SetAndCheckScripts(scripts);
+ AddScript("script name", "script path", "maybe_exists");
+ SetAndCheckScripts();
// No scripts are runnable.
EXPECT_THAT(runnable_scripts(), IsEmpty());
@@ -337,9 +302,8 @@ TEST_F(ScriptTrackerTest, CheckScriptsAfterDOMChange) {
TEST_F(ScriptTrackerTest, UpdateScriptList) {
// 1. Initialize runnable scripts with a single valid script.
- SupportsScriptResponseProto scripts;
- AddScript(&scripts, "runnable name", "runnable path", "exists");
- SetAndCheckScripts(scripts);
+ AddScript("runnable name", "runnable path", "exists");
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
ASSERT_THAT(runnable_scripts(), SizeIs(1));
@@ -351,9 +315,9 @@ TEST_F(ScriptTrackerTest, UpdateScriptList) {
actions_response.add_actions()->mutable_tell()->set_message("hi");
*actions_response.mutable_update_script_list()->add_scripts() =
- *AddScript(&scripts, "update name", "update path", "exists");
+ *AddScript("update name", "update path", "exists");
*actions_response.mutable_update_script_list()->add_scripts() =
- *AddScript(&scripts, "update name 2", "update path 2", "exists");
+ *AddScript("update name 2", "update path 2", "exists");
EXPECT_CALL(mock_service_,
OnGetActions(StrEq("runnable name"), _, _, _, _, _))
@@ -378,11 +342,9 @@ TEST_F(ScriptTrackerTest, UpdateScriptList) {
TEST_F(ScriptTrackerTest, UpdateScriptListFromInterrupt) {
// 1. Initialize runnable scripts with a single valid interrupt script.
- SupportsScriptResponseProto scripts;
- auto* script =
- AddScript(&scripts, "runnable name", "runnable path", "exists");
+ auto* script = AddScript("runnable name", "runnable path", "exists");
script->mutable_presentation()->set_interrupt(true);
- SetAndCheckScripts(scripts);
+ SetAndCheckScripts();
EXPECT_EQ(1, runnable_scripts_changed_);
ASSERT_THAT(runnable_scripts(), SizeIs(1));
@@ -395,9 +357,9 @@ TEST_F(ScriptTrackerTest, UpdateScriptListFromInterrupt) {
actions_response.add_actions()->mutable_tell()->set_message("hi");
*actions_response.mutable_update_script_list()->add_scripts() =
- *AddScript(&scripts, "update name", "update path", "exists");
+ *AddScript("update name", "update path", "exists");
*actions_response.mutable_update_script_list()->add_scripts() =
- *AddScript(&scripts, "update name 2", "update path 2", "exists");
+ *AddScript("update name 2", "update path 2", "exists");
EXPECT_CALL(mock_service_,
OnGetActions(StrEq("runnable name"), _, _, _, _, _))
@@ -420,4 +382,22 @@ TEST_F(ScriptTrackerTest, UpdateScriptListFromInterrupt) {
EXPECT_EQ("update path 2", runnable_scripts()[1].path);
}
+TEST_F(ScriptTrackerTest, NoRunnableScriptsEvenWithDOMChanges) {
+ auto* script = AddScript("name", "path", "");
+ script->mutable_presentation()->mutable_precondition()->add_path_pattern(
+ "doesnotmatch");
+ SetAndCheckScripts();
+
+ EXPECT_THAT(runnable_scripts(), SizeIs(0));
+ EXPECT_EQ(1, no_runnable_scripts_anymore_);
+}
+
+TEST_F(ScriptTrackerTest, NoRunnableScriptsWaitingForDOMChanges) {
+ AddScript("runnable name", "runnable path", "does_not_exist");
+ SetAndCheckScripts();
+
+ EXPECT_THAT(runnable_scripts(), SizeIs(0));
+ EXPECT_EQ(0, no_runnable_scripts_anymore_);
+}
+
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/selector.cc b/chromium/components/autofill_assistant/browser/selector.cc
index 2f4b06b224a..6e41fa6bb53 100644
--- a/chromium/components/autofill_assistant/browser/selector.cc
+++ b/chromium/components/autofill_assistant/browser/selector.cc
@@ -4,6 +4,8 @@
#include "components/autofill_assistant/browser/selector.h"
+#include "base/strings/string_util.h"
+
namespace autofill_assistant {
Selector::Selector() : pseudo_type(PseudoType::UNDEFINED) {}
@@ -41,4 +43,14 @@ bool Selector::empty() const {
return this->selectors.empty();
}
-} // namespace autofill_assistant \ No newline at end of file
+std::ostream& operator<<(std::ostream& out, const Selector& selector) {
+#ifdef NDEBUG
+ out << selector.selectors.size() << " element(s)";
+ return out;
+#else
+ out << "elements=[" << base::JoinString(selector.selectors, ",") << "]";
+ return out;
+#endif // NDEBUG
+}
+
+} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/selector.h b/chromium/components/autofill_assistant/browser/selector.h
index 713828b86f4..686d0d91404 100644
--- a/chromium/components/autofill_assistant/browser/selector.h
+++ b/chromium/components/autofill_assistant/browser/selector.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SELECTOR_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_SELECTOR_H_
+#include <ostream>
#include <string>
#include <vector>
@@ -39,6 +40,10 @@ struct Selector {
bool operator<(const Selector& other) const;
bool operator==(const Selector& other) const;
+ // The output operator. The actual selectors are only available in debug
+ // builds.
+ friend std::ostream& operator<<(std::ostream& out, const Selector& selector);
+
// Checks whether this selector is empty.
bool empty() const;
};
diff --git a/chromium/components/autofill_assistant/browser/service.cc b/chromium/components/autofill_assistant/browser/service.cc
index f07ca76dee6..fa8672671ef 100644
--- a/chromium/components/autofill_assistant/browser/service.cc
+++ b/chromium/components/autofill_assistant/browser/service.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/strings/strcat.h"
@@ -171,8 +172,10 @@ void Service::StartLoader(Loader* loader) {
resource_request->load_flags =
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
if (access_token_.empty()) {
+ std::string query_str = base::StrCat({"key=", api_key_});
+ // query_str must remain valid until ReplaceComponents() has returned.
url::StringPieceReplacements<std::string> add_key;
- add_key.SetQueryStr(base::StrCat({"key=", api_key_}));
+ add_key.SetQueryStr(query_str);
resource_request->url = loader->url.ReplaceComponents(add_key);
} else {
resource_request->url = loader->url;
diff --git a/chromium/components/autofill_assistant/browser/service.proto b/chromium/components/autofill_assistant/browser/service.proto
index 843a939c43a..72370487ab8 100644
--- a/chromium/components/autofill_assistant/browser/service.proto
+++ b/chromium/components/autofill_assistant/browser/service.proto
@@ -55,6 +55,22 @@ message ScriptParameterProto {
// Response of the list of supported scripts.
message SupportsScriptResponseProto {
repeated SupportedScriptProto scripts = 1;
+
+ // Defines what should happen if no scripts in [scripts] becomes runnable,
+ // because of preconditions.
+ optional ScriptTimeoutError script_timeout_error = 2;
+}
+
+message ScriptTimeoutError {
+ // Wait for that long before considering that scripts preconditions have timed
+ // out and executing the script specified in script_path.
+ //
+ // The script might be called more than once if the script terminates
+ // successfully and again still nothing is found after timeout_ms.
+ optional int32 timeout_ms = 1;
+
+ // The script to execute when the error happens.
+ optional string script_path = 2;
}
// Supported script.
@@ -80,11 +96,12 @@ message SupportedScriptProto {
// priority 1.
optional int32 priority = 5;
- // Whether the script should be highlighted.
- optional bool highlight = 7;
+ // Describes the chip to be shown. The name of the chip is set by the
+ // name field.
+ optional ChipType chip_type = 10;
- // When set to true this script can be run in 'autostart mode'. Script won't
- // be shown.
+ // When set to true this script can be run in 'autostart mode'. Chip won't
+ // be shown; name and chip_type are ignored.
optional bool autostart = 8;
// When set to true this script will be run from WaitForDom actions with
@@ -94,6 +111,42 @@ message SupportedScriptProto {
optional PresentationProto presentation = 2;
}
+enum ChipType {
+ UNKNOWN_CHIP_TYPE = 0;
+
+ // Chip is a highlighted (blue) action chip.
+ HIGHLIGHTED_ACTION = 1;
+
+ // Chip is a suggestion.
+ SUGGESTION = 2;
+
+ // Chip is a normal action chip.
+ NORMAL_ACTION = 3;
+
+ // A cancel chip, which closes AA in a way that allows the user to undo.
+ //
+ // The action associated with the chip is only executed after enough time has
+ // passed that undo is not possible.
+ //
+ // The presence of this chip inhibit the addition of an implicit close or
+ // cancel button.
+ CANCEL_ACTION = 4;
+
+ // A close chip, which closes AA immediately.
+ //
+ // The presence of this chip inhibit the addition of an implicit close or
+ // cancel button. Otherwise, buttons of this type work and look like a
+ // NORMAL_ACTION.
+ CLOSE_ACTION = 5;
+
+ // Chip is a highlighted (blue) action chip.
+ //
+ // The presence of this chip inhibit the addition of an implicit close or
+ // cancel button. Otherwise, buttons of this type work and look like a
+ // HIGHLIGHTED_ACTION.
+ DONE_ACTION = 6;
+}
+
enum ScriptStatusProto {
// Never explicitly set. Reading this value means the enum field is either
// not set or set to a value not listed here.
@@ -266,6 +319,7 @@ message ActionProto {
StopProto stop = 35;
GetPaymentInformationProto get_payment_information = 36;
SetAttributeProto set_attribute = 37;
+ ShowInfoBoxProto show_info_box = 39;
}
// Set to true to make the client remove any contextual information if the
@@ -333,6 +387,23 @@ enum ProcessedActionStatusProto {
// affect any action. It is a signal that the action or script ran in an
// abnormal situation and its outcome cannot be trusted.
USER_ABORTED_ACTION = 8;
+
+ // The Autofill Action failed to get the full card information.
+ //
+ // Possible causes:
+ // - the user filled in the wrong CVC number.
+ // - the card has expired
+ GET_FULL_CARD_FAILED = 9;
+
+ // The action did not have what it needs. This is generally a bug in the
+ // script.
+ //
+ // This is currently returned by the autofill action, when it could not find
+ // the credit card or the address it needs in the client memory. This is
+ // usually the sign that the Get Payment Information action was not run or
+ // failed.
+ //
+ PRECONDITION_FAILED = 10;
}
// The pseudo type values come from
@@ -423,14 +494,6 @@ message ElementAreaProto {
repeated Rectangle rectangles = 1;
}
-message AutofillStrings {
- optional string fill_manually = 1;
-
- optional string fill_form = 2;
-
- optional string check_form = 3;
-}
-
// Fill a form with an address if there is, otherwise fail this action.
message UseAddressProto {
// Message used to indicate what form fields should be filled with what
@@ -474,8 +537,6 @@ message UseAddressProto {
// An optional list of fields that should be filled by this action.
repeated RequiredField required_fields = 6;
-
- optional AutofillStrings strings = 8;
}
// Fill a form with a credit card if there is, otherwise fail this action.
@@ -486,8 +547,6 @@ message UseCreditCardProto {
// A reference to the card number field in the form that should be filled.
optional ElementReferenceProto form_field_element = 3;
-
- optional AutofillStrings strings = 8;
}
// Ask Chrome to wait for an element in the DOM. This can be used to only
@@ -515,9 +574,6 @@ message UploadDomProto {
// Shows the progress bar.
message ShowProgressBarProto {
- // Specifies whether the progress is done and should be removed.
- optional bool done = 2;
-
// Message to show on the progress bar while loading.
optional string message = 3;
@@ -525,6 +581,9 @@ message ShowProgressBarProto {
// will be capped to 100, values below 0 will be capped to 0 by the client.
// NOTE: Setting |progress| to 100 is an equivalent of setting |done| to true.
optional int32 progress = 6;
+
+ // Hide the progress bar in the UI.
+ optional bool hide = 7;
}
// Contain all arguments to perform a highlight element action.
@@ -545,28 +604,33 @@ message PromptProto {
// Display this message to the user.
optional string message = 1;
- // A choice that is made either directly by clicking on a chip or button, or
+ // A choice that is made either directly by clicking on a chip or chip, or
// implicitly by making a change on the website that is then detected by
// looking for the existence of an element.
//
// One of these protos must is transmitted as-is back to the server as part of
// ProcessedActionProto.
message Choice {
- // Localized text message to display. Not required if element_exists is set.
+ // Localized text message to display. Not required if
+ // auto_select_if_element_exists is set.
optional string name = 2;
- // If set, the choice should be highlighted. Ignored unless name is set.
- optional bool highlight = 3;
+ // Describes the chip to be shown. The name of the chip is set by the
+ // name field.
+ optional ChipType chip_type = 7;
+
+ // Auto-select this choice if the given element exist.
+ optional ElementReferenceProto auto_select_if_element_exists = 4;
- // Optionally auto-select this choice if the given element exist.
- optional ElementReferenceProto element_exists = 4;
+ // The chip is only visible if all the given element exists.
+ repeated ElementReferenceProto show_only_if_element_exists = 6;
+
+ // The chip is only visible if all the form values match.
+ repeated FormValueMatchProto show_only_if_form_value_matches = 8;
// Server payload originally sent by the server. This should
// be transmitted as-is by the client without interpreting.
optional bytes server_payload = 5;
-
- // The chip is only visible if the given element exists.
- optional ElementReferenceProto show_only_if_element_exists = 6;
}
repeated Choice choices = 4;
}
@@ -606,7 +670,13 @@ message GetPaymentInformationProto {
message ResetProto {}
// Stop Autofill Assistant.
-message StopProto {}
+message StopProto {
+ // If true, close the Chrome Custom Tab, in addition to shutting down Autofill
+ // Assistant.
+ optional bool close_cct = 2;
+
+ reserved 1; // stop_action_type
+}
message DateProto {
optional int64 year = 1;
@@ -634,41 +704,71 @@ message DateTimeProto {
optional TimeProto time = 2;
}
-message DetailsChanges {
- // Whether the changes require user approval.
+message DetailsChangesProto {
+ // Whether the changes require user approval. This de-emphasize
+ // non-highlighted fields.
optional bool user_approval_required = 1;
// Whether the title should be highlighted.
optional bool highlight_title = 2;
- // Whether the date should be highlighted.
- optional bool highlight_date = 3;
+ // Whether the first description line should be highlighted.
+ optional bool highlight_line1 = 3;
+
+ // Whether the second description line should be highlighted.
+ optional bool highlight_line2 = 4;
}
message DetailsProto {
optional string title = 1;
- optional string url = 2;
+ oneof image {
+ string image_url = 2;
+ // When set to true shows placeholder in place of an image.
+ bool show_image_placeholder = 10;
+ }
+
+ // Optional label to provide additional price information.
+ optional string total_price_label = 9;
+ // The price containing the total amount and the currency to pay, formatted
+ // in the client's locale (e.g., $123.00).
+ optional string total_price = 6;
- optional DateTimeProto datetime = 3;
+ optional string description_line_1 = 7;
+ optional string description_line_2 = 8;
+ // Deprecated, but currently still necessary and supported. We can get rid of
+ // these fields when the backend starts setting description_line_1 and 2.
+ optional DateTimeProto datetime = 3;
optional string description = 4;
- // Mid that comes from Knowledge Graph. Uniquely identify the object that this
- // proto describes.
- optional string m_id = 5;
+ // Asks the UI to show animated placeholders for missing fields.
+ // The placeholder will be shown on effectively missing:
+ // * title
+ // * image
+ // * description line (1 or 2)
+ // TODO(crbug.com/806868): Make the fields for displaying placeholders
+ // configurable by the server.
+ optional bool animate_placeholders = 11;
- // Price label containing the total amount and the currency to pay, formatted
- // in the client's locale (e.g., $123.00).
- optional string total_price = 6;
+ // Deprecated, no longer supported.
+ reserved 5;
}
// Show contextual information.
message ShowDetailsProto {
- optional DetailsProto details = 1;
+ oneof data_to_show {
+ DetailsProto details = 1;
+ // Shows full name and email address.
+ string contact_details = 3;
+ bool credit_card = 4;
+ // Shows full name and address.
+ string shipping_address = 5;
+ }
// Flags indicating which parts of the details (if any) have changed.
- optional DetailsChanges change_flags = 2;
+ // This field is taken into account only if |details| is filled.
+ optional DetailsChangesProto change_flags = 2;
}
// Set the value of an form element.
@@ -705,3 +805,18 @@ message SetAttributeProto {
// The value to set.
optional string value = 3;
}
+
+message InfoBoxProto {
+ // Optional path to an image. Ok tick used if not set.
+ optional string image_path = 1;
+
+ // The explanation to show in the box. Not setting this field will clear an
+ // existing info box.
+ optional string explanation = 2;
+}
+
+// Shows an info box with informational content. The info box content is cleared
+// when |info_box| is not set.
+message ShowInfoBoxProto {
+ optional InfoBoxProto info_box = 1;
+}
diff --git a/chromium/components/autofill_assistant/browser/state.h b/chromium/components/autofill_assistant/browser/state.h
index e6a770fb11a..d0ff42d0572 100644
--- a/chromium/components/autofill_assistant/browser/state.h
+++ b/chromium/components/autofill_assistant/browser/state.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_STATE_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_STATE_H_
+#include <ostream>
+
namespace autofill_assistant {
// High-level states the Autofill Assistant can be in.
@@ -47,6 +49,43 @@ enum class AutofillAssistantState {
STOPPED
};
+inline std::ostream& operator<<(std::ostream& out,
+ const AutofillAssistantState& state) {
+#ifdef NDEBUG
+ // Non-debugging builds write the enum number.
+ out << static_cast<int>(state);
+ return out;
+#else
+ // Debugging builds write a string representation of |state|.
+ switch (state) {
+ case AutofillAssistantState::INACTIVE:
+ out << "INACTIVE";
+ break;
+ case AutofillAssistantState::STARTING:
+ out << "STARTING";
+ break;
+ case AutofillAssistantState::RUNNING:
+ out << "RUNNING";
+ break;
+ case AutofillAssistantState::PROMPT:
+ out << "PROMPT";
+ break;
+ case AutofillAssistantState::AUTOSTART_FALLBACK_PROMPT:
+ out << "AUTOSTART_FALLBACK_PROMPT";
+ break;
+ case AutofillAssistantState::MODAL_DIALOG:
+ out << "MODAL_DIALOG";
+ break;
+ case AutofillAssistantState::STOPPED:
+ out << "STOPPED";
+ break;
+ // Intentionally no default case to make compilation fail if a new value
+ // was added to the enum but not to this list.
+ }
+ return out;
+#endif // NDEBUG
+}
+
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_STATE_H_
diff --git a/chromium/components/autofill_assistant/browser/ui_controller.cc b/chromium/components/autofill_assistant/browser/ui_controller.cc
index bb1f8c09e96..2e45db0307d 100644
--- a/chromium/components/autofill_assistant/browser/ui_controller.cc
+++ b/chromium/components/autofill_assistant/browser/ui_controller.cc
@@ -9,8 +9,20 @@
namespace autofill_assistant {
-PaymentInformation::PaymentInformation() : succeed(false) {}
+UiController::UiController() = default;
+UiController::~UiController() = default;
-PaymentInformation::~PaymentInformation() = default;
+void UiController::OnStateChanged(AutofillAssistantState new_state) {}
+void UiController::OnStatusMessageChanged(const std::string& message) {}
+void UiController::WillShutdown(Metrics::DropOutReason reason) {}
+void UiController::OnSuggestionsChanged(const std::vector<Chip>& suggestions) {}
+void UiController::OnActionsChanged(const std::vector<Chip>& actions) {}
+void UiController::OnPaymentRequestChanged(
+ const PaymentRequestOptions* options) {}
+void UiController::OnDetailsChanged(const Details* details) {}
+void UiController::OnInfoBoxChanged(const InfoBox* info_box) {}
+void UiController::OnProgressChanged(int progress) {}
+void UiController::OnProgressVisibilityChanged(bool visible) {}
+void UiController::OnTouchableAreaChanged(const std::vector<RectF>& areas) {}
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/ui_controller.h b/chromium/components/autofill_assistant/browser/ui_controller.h
index 2c9944e0901..eadb49cc7db 100644
--- a/chromium/components/autofill_assistant/browser/ui_controller.h
+++ b/chromium/components/autofill_assistant/browser/ui_controller.h
@@ -12,8 +12,9 @@
#include "base/callback_forward.h"
#include "components/autofill_assistant/browser/chip.h"
#include "components/autofill_assistant/browser/details.h"
+#include "components/autofill_assistant/browser/info_box.h"
#include "components/autofill_assistant/browser/metrics.h"
-#include "components/autofill_assistant/browser/payment_information.h"
+#include "components/autofill_assistant/browser/payment_request.h"
#include "components/autofill_assistant/browser/script.h"
#include "components/autofill_assistant/browser/state.h"
#include "components/autofill_assistant/browser/ui_delegate.h"
@@ -22,57 +23,58 @@
namespace autofill_assistant {
// Controller to control autofill assistant UI.
+//
+// TODO(crbug/925947): Rename this class to Observer and make treat it as a real
+// observer in the Controller.
class UiController {
public:
- virtual ~UiController() = default;
+ UiController();
+ virtual ~UiController();
// Called when the controller has entered a new state.
- virtual void OnStateChanged(AutofillAssistantState new_state) = 0;
+ virtual void OnStateChanged(AutofillAssistantState new_state);
// Report that the status message has changed.
- virtual void OnStatusMessageChanged(const std::string& message) = 0;
+ virtual void OnStatusMessageChanged(const std::string& message);
- // Shuts down Autofill Assistant: hide the UI and frees any associated state.
+ // Autofill Assistant is about to be shut down for this tab.
//
- // Warning: this indirectly deletes the caller.
- virtual void Shutdown(Metrics::DropOutReason reason) = 0;
+ // Pointer to UIDelegate will become invalid as soon as this method has
+ // returned.
+ virtual void WillShutdown(Metrics::DropOutReason reason);
- // Shuts down Autofill Assistant and closes Chrome.
- virtual void Close() = 0;
+ // Report that the set of suggestions has changed.
+ virtual void OnSuggestionsChanged(const std::vector<Chip>& suggestions);
- // Show UI to ask user to make a choice between different chips.
- virtual void SetChips(std::unique_ptr<std::vector<Chip>> chips) = 0;
+ // Report that the set of actions has changed.
+ virtual void OnActionsChanged(const std::vector<Chip>& actions);
- // Remove all chips from the UI.
- virtual void ClearChips() = 0;
-
- // Get payment information (through similar to payment request UX) to fill
- // forms.
- virtual void GetPaymentInformation(
- payments::mojom::PaymentOptionsPtr payment_options,
- base::OnceCallback<void(std::unique_ptr<PaymentInformation>)> callback,
- const std::string& title,
- const std::vector<std::string>& supported_basic_card_networks) = 0;
+ // Gets or clears request for payment information.
+ virtual void OnPaymentRequestChanged(const PaymentRequestOptions* options);
// Called when details have changed. Details will be null if they have been
// cleared.
- virtual void OnDetailsChanged(const Details* details) = 0;
+ virtual void OnDetailsChanged(const Details* details);
+
+ // Called when info box has changed. |info_box| will be null if it has been
+ // cleared.
+ virtual void OnInfoBoxChanged(const InfoBox* info_box);
- // Show the progress bar and set it at |progress|%.
- virtual void ShowProgressBar(int progress) = 0;
+ // Called when the current progress has changed. Progress, is expressed as a
+ // percentage.
+ virtual void OnProgressChanged(int progress);
- // Hide the progress bar.
- virtual void HideProgressBar() = 0;
+ // Called when the current progress bar visibility has changed. If |visible|
+ // is true, then the bar is now shown.
+ virtual void OnProgressVisibilityChanged(bool visible);
// Updates the area of the visible viewport that is accessible when the
// overlay state is OverlayState::PARTIAL.
//
- // |areas| is expressed in coordinates relative to the width or height of the
- // visible viewport, as a number between 0 and 1. It can be empty.
- virtual void SetTouchableArea(const std::vector<RectF>& areas) = 0;
-
- protected:
- UiController() = default;
+ // |rectangles| contains one element per configured rectangles, though these
+ // can correspond to empty rectangles. Coordinates are relative to the width
+ // or height of the visible viewport, as a number between 0 and 1.
+ virtual void OnTouchableAreaChanged(const std::vector<RectF>& rectangles);
};
} // namespace autofill_assistant
#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_CONTROLLER_H_
diff --git a/chromium/components/autofill_assistant/browser/ui_delegate.h b/chromium/components/autofill_assistant/browser/ui_delegate.h
index 62e67bdfed9..554e8196bf1 100644
--- a/chromium/components/autofill_assistant/browser/ui_delegate.h
+++ b/chromium/components/autofill_assistant/browser/ui_delegate.h
@@ -5,9 +5,14 @@
#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_DELEGATE_H_
#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_UI_DELEGATE_H_
+#include <memory>
#include <string>
+#include <vector>
+#include "base/optional.h"
#include "components/autofill_assistant/browser/metrics.h"
+#include "components/autofill_assistant/browser/payment_request.h"
+#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/state.h"
namespace autofill_assistant {
@@ -39,8 +44,51 @@ class UiDelegate {
// Returns the current contextual information. May be null if empty.
virtual const Details* GetDetails() const = 0;
- // Returns the drop out reason for the last state transition to STOPPED.
- virtual Metrics::DropOutReason GetDropOutReason() const = 0;
+ // Returns the current info box data. May be null if empty.
+ virtual const InfoBox* GetInfoBox() const = 0;
+
+ // Returns the current progress; a percentage.
+ virtual int GetProgress() const = 0;
+
+ // Returns whether the progress bar is visible.
+ virtual bool GetProgressVisible() const = 0;
+
+ // Returns the current set of suggestions.
+ virtual const std::vector<Chip>& GetSuggestions() const = 0;
+
+ // Selects a suggestion, from the set of suggestions returned by
+ // GetSuggestions().
+ virtual void SelectSuggestion(int suggestion) = 0;
+
+ // Returns the current set of actions.
+ virtual const std::vector<Chip>& GetActions() const = 0;
+
+ // Selects an action, from the set of actions returned by GetActions().
+ virtual void SelectAction(int action) = 0;
+
+ // If the controller is waiting for payment request information, this
+ // field contains a non-null options describing the request.
+ virtual const PaymentRequestOptions* GetPaymentRequestOptions() const = 0;
+
+ // Sets payment information, in response to the current payment request
+ // options.
+ virtual void SetPaymentInformation(
+ std::unique_ptr<PaymentInformation> payment_information) = 0;
+
+ // Adds the rectangles that correspond to the current touchable area to the
+ // given vector.
+ //
+ // At the end of this call, |rectangles| contains one element per configured
+ // rectangles, though these can correspond to empty rectangles. Coordinates
+ // are relative to the width or height of the visible viewport, as a number
+ // between 0 and 1.
+ //
+ // Note that the vector is not cleared before rectangles are added.
+ virtual void GetTouchableArea(std::vector<RectF>* rectangles) const = 0;
+
+ // Reports a fatal error to Autofill Assistant, which should then stop.
+ virtual void OnFatalError(const std::string& error_message,
+ Metrics::DropOutReason reason) = 0;
protected:
UiDelegate() = default;
diff --git a/chromium/components/autofill_assistant/browser/web_controller.cc b/chromium/components/autofill_assistant/browser/web_controller.cc
index 4880a18589f..921a3170f2e 100644
--- a/chromium/components/autofill_assistant/browser/web_controller.cc
+++ b/chromium/components/autofill_assistant/browser/web_controller.cc
@@ -9,10 +9,12 @@
#include <ctime>
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
@@ -32,12 +34,12 @@ namespace autofill_assistant {
using autofill::ContentAutofillDriver;
namespace {
-// Time between two periodic box model checks.
-static constexpr base::TimeDelta kPeriodicBoxModelCheckInterval =
+// Time between two periodic box model and document ready state checks.
+static constexpr base::TimeDelta kPeriodicCheckInterval =
base::TimeDelta::FromMilliseconds(200);
// Timeout after roughly 10 seconds (50*200ms).
-constexpr int kPeriodicBoxModelCheckRounds = 50;
+constexpr int kPeriodicCheckRounds = 50;
// Expiration time for the Autofill Assistant cookie.
constexpr int kCookieExpiresSeconds = 600;
@@ -151,6 +153,13 @@ const char* const kQuerySelectorAll =
return undefined;
})";
+// Javascript code to query whether the document is ready for interact.
+const char* const kIsDocumentReadyForInteract =
+ R"(function () {
+ return document.readyState == 'interactive'
+ || document.readyState == 'complete';
+ })";
+
bool ConvertPseudoType(const PseudoType pseudo_type,
dom::PseudoType* pseudo_type_output) {
switch (pseudo_type) {
@@ -218,7 +227,7 @@ void WebController::ElementPositionGetter::Start(
devtools_client_ = devtools_client;
object_id_ = element_object_id;
callback_ = std::move(callback);
- remaining_rounds_ = kPeriodicBoxModelCheckRounds;
+ remaining_rounds_ = kPeriodicCheckRounds;
// Wait for a roundtrips through the renderer and compositor pipeline,
// otherwise touch event may be dropped because of missing handler.
@@ -252,7 +261,7 @@ void WebController::ElementPositionGetter::GetAndWaitBoxModelStable() {
void WebController::ElementPositionGetter::OnGetBoxModelForStableCheck(
std::unique_ptr<dom::GetBoxModelResult> result) {
if (!result || !result->GetModel() || !result->GetModel()->GetContent()) {
- DLOG(ERROR) << "Failed to get box model.";
+ DVLOG(1) << __func__ << " Failed to get box model.";
OnError();
return;
}
@@ -266,17 +275,15 @@ void WebController::ElementPositionGetter::OnGetBoxModelForStableCheck(
round((round((*content_box)[3]) + round((*content_box)[5])) * 0.5);
// Wait for at least three rounds (~600ms =
- // 3*kPeriodicBoxModelCheckInterval) for visual state update callback since
+ // 3*kPeriodicCheckInterval) for visual state update callback since
// it might take longer time to return or never return if no updates.
- DCHECK(kPeriodicBoxModelCheckRounds > 2 &&
- kPeriodicBoxModelCheckRounds >= remaining_rounds_);
+ DCHECK(kPeriodicCheckRounds > 2 && kPeriodicCheckRounds >= remaining_rounds_);
if (has_point_ && new_point_x == point_x_ && new_point_y == point_y_ &&
- (visual_state_updated_ ||
- remaining_rounds_ + 2 < kPeriodicBoxModelCheckRounds)) {
+ (visual_state_updated_ || remaining_rounds_ + 2 < kPeriodicCheckRounds)) {
// Note that there is still a chance that the element's position has been
// changed after the last call of GetBoxModel, however, it might be safe
// to assume the element's position will not be changed before issuing
- // click or tap event after stable for kPeriodicBoxModelCheckInterval. In
+ // click or tap event after stable for kPeriodicCheckInterval. In
// addition, checking again after issuing click or tap event doesn't help
// since the change may be expected.
OnResult(new_point_x, new_point_y);
@@ -317,13 +324,13 @@ void WebController::ElementPositionGetter::OnGetBoxModelForStableCheck(
base::BindOnce(
&WebController::ElementPositionGetter::GetAndWaitBoxModelStable,
weak_ptr_factory_.GetWeakPtr()),
- kPeriodicBoxModelCheckInterval);
+ kPeriodicCheckInterval);
}
void WebController::ElementPositionGetter::OnScrollIntoView(
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
- DLOG(ERROR) << "Failed to scroll the element.";
+ DVLOG(1) << __func__ << " Failed to scroll the element.";
OnError();
return;
}
@@ -334,7 +341,7 @@ void WebController::ElementPositionGetter::OnScrollIntoView(
base::BindOnce(
&WebController::ElementPositionGetter::GetAndWaitBoxModelStable,
weak_ptr_factory_.GetWeakPtr()),
- kPeriodicBoxModelCheckInterval);
+ kPeriodicCheckInterval);
}
void WebController::ElementPositionGetter::OnResult(int x, int y) {
@@ -370,17 +377,15 @@ WebController::FillFormInputData::FillFormInputData() {}
WebController::FillFormInputData::~FillFormInputData() {}
-const GURL& WebController::GetUrl() {
- return web_contents_->GetLastCommittedURL();
-}
-
void WebController::LoadURL(const GURL& url) {
+ DVLOG(3) << __func__ << " " << url;
web_contents_->GetController().LoadURLWithParams(
content::NavigationController::LoadURLParams(url));
}
void WebController::ClickOrTapElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector;
#if defined(OS_ANDROID)
TapElement(selector, std::move(callback));
#else
@@ -414,12 +419,31 @@ void WebController::OnFindElementForClickOrTap(
std::unique_ptr<FindElementResult> result) {
// Found element must belong to a frame.
if (!result->container_frame_host || result->object_id.empty()) {
- DLOG(ERROR) << "Failed to find the element to click or tap.";
+ DVLOG(1) << __func__ << " Failed to find the element to click or tap.";
OnResult(false, std::move(callback));
return;
}
- ClickOrTapElement(std::move(result), is_a_click, std::move(callback));
+ std::string element_object_id = result->object_id;
+ WaitForDocumentToBecomeInteractive(
+ kPeriodicCheckRounds, element_object_id,
+ base::BindOnce(
+ &WebController::OnWaitDocumentToBecomeInteractiveForClickOrTap,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback), is_a_click,
+ std::move(result)));
+}
+
+void WebController::OnWaitDocumentToBecomeInteractiveForClickOrTap(
+ base::OnceCallback<void(bool)> callback,
+ bool is_a_click,
+ std::unique_ptr<FindElementResult> target_element,
+ bool result) {
+ if (!result) {
+ OnResult(false, std::move(callback));
+ return;
+ }
+
+ ClickOrTapElement(std::move(target_element), is_a_click, std::move(callback));
}
void WebController::ClickOrTapElement(
@@ -448,7 +472,7 @@ void WebController::OnScrollIntoView(
bool is_a_click,
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
- DLOG(ERROR) << "Failed to scroll the element.";
+ DVLOG(1) << __func__ << " Failed to scroll the element.";
OnResult(false, std::move(callback));
return;
}
@@ -471,7 +495,7 @@ void WebController::TapOrClickOnCoordinates(
int x,
int y) {
if (!has_coordinates) {
- DLOG(ERROR) << "Failed to get element position.";
+ DVLOG(1) << __func__ << " Failed to get element position.";
OnResult(false, std::move(callback));
return;
}
@@ -510,7 +534,8 @@ void WebController::OnDispatchPressMouseEvent(
int y,
std::unique_ptr<input::DispatchMouseEventResult> result) {
if (!result) {
- DLOG(ERROR) << "Failed to dispatch mouse left button pressed event.";
+ DVLOG(1) << __func__
+ << " Failed to dispatch mouse left button pressed event.";
OnResult(false, std::move(callback));
return;
}
@@ -537,7 +562,7 @@ void WebController::OnDispatchTouchEventStart(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<input::DispatchTouchEventResult> result) {
if (!result) {
- DLOG(ERROR) << "Failed to dispatch touch start event.";
+ DVLOG(1) << __func__ << " Failed to dispatch touch start event.";
OnResult(false, std::move(callback));
return;
}
@@ -620,7 +645,7 @@ void WebController::OnGetDocumentElement(
element_result->container_frame_selector_index = 0;
element_result->object_id = "";
if (!result || !result->GetResult() || !result->GetResult()->HasObjectId()) {
- DLOG(ERROR) << "Failed to get document root element.";
+ DVLOG(1) << __func__ << " Failed to get document root element.";
std::move(callback).Run(std::move(element_result));
return;
}
@@ -715,7 +740,7 @@ void WebController::OnDescribeNodeForPseudoElement(
FindElementCallback callback,
std::unique_ptr<dom::DescribeNodeResult> result) {
if (!result || !result->GetNode()) {
- DLOG(ERROR) << "Failed to describe the node for pseudo element.";
+ DVLOG(1) << __func__ << " Failed to describe the node for pseudo element.";
std::move(callback).Run(std::move(element_result));
return;
}
@@ -761,7 +786,7 @@ void WebController::OnDescribeNode(
FindElementCallback callback,
std::unique_ptr<dom::DescribeNodeResult> result) {
if (!result || !result->GetNode()) {
- DLOG(ERROR) << "Failed to describe the node.";
+ DVLOG(1) << __func__ << " Failed to describe the node.";
std::move(callback).Run(std::move(element_result));
return;
}
@@ -792,13 +817,13 @@ void WebController::OnDescribeNode(
element_result->container_frame_host = FindCorrespondingRenderFrameHost(
frame_name, node->GetContentDocument()->GetDocumentURL());
if (!element_result->container_frame_host) {
- DLOG(ERROR) << "Failed to find corresponding owner frame.";
+ DVLOG(1) << __func__ << " Failed to find corresponding owner frame.";
std::move(callback).Run(std::move(element_result));
return;
}
} else if (node->HasFrameId()) {
// TODO(crbug.com/806868): Support out-of-process iframe.
- DLOG(WARNING) << "The element is inside an OOPIF.";
+ DVLOG(3) << "Warning (unsupported): the element is inside an OOPIF.";
std::move(callback).Run(std::move(element_result));
return;
}
@@ -833,7 +858,7 @@ void WebController::OnResolveNode(
FindElementCallback callback,
std::unique_ptr<dom::ResolveNodeResult> result) {
if (!result || !result->GetObject() || !result->GetObject()->HasObjectId()) {
- DLOG(ERROR) << "Failed to resolve object id from backend id.";
+ DVLOG(1) << __func__ << " Failed to resolve object id from backend id.";
std::move(callback).Run(std::move(element_result));
return;
}
@@ -874,7 +899,7 @@ void WebController::OnFindElementForFocusElement(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<FindElementResult> element_result) {
if (element_result->object_id.empty()) {
- DLOG(ERROR) << "Failed to find the element to focus on.";
+ DVLOG(1) << __func__ << " Failed to find the element to focus on.";
OnResult(false, std::move(callback));
return;
}
@@ -898,7 +923,7 @@ void WebController::OnFocusElement(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
- DLOG(ERROR) << "Failed to focus on element.";
+ DVLOG(1) << __func__ << " Failed to focus on element.";
OnResult(false, std::move(callback));
return;
}
@@ -908,6 +933,7 @@ void WebController::OnFocusElement(
void WebController::FillAddressForm(const autofill::AutofillProfile* profile,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << selector;
auto data_to_autofill = std::make_unique<FillFormInputData>();
data_to_autofill->profile =
std::make_unique<autofill::AutofillProfile>(*profile);
@@ -925,7 +951,7 @@ void WebController::OnFindElementForFillingForm(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<FindElementResult> element_result) {
if (element_result->object_id.empty()) {
- DLOG(ERROR) << "Failed to find the element for filling the form.";
+ DVLOG(1) << __func__ << " Failed to find the element for filling the form.";
OnResult(false, std::move(callback));
return;
}
@@ -951,7 +977,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm(
const autofill::FormData& form_data,
const autofill::FormFieldData& form_field) {
if (form_data.fields.empty()) {
- DLOG(ERROR) << "Failed to get form data to fill form.";
+ DVLOG(1) << __func__ << " Failed to get form data to fill form.";
OnResult(false, std::move(callback));
return;
}
@@ -959,7 +985,7 @@ void WebController::OnGetFormAndFieldDataForFillingForm(
ContentAutofillDriver* driver =
ContentAutofillDriver::GetForRenderFrameHost(container_frame_host);
if (!driver) {
- DLOG(ERROR) << "Failed to get the autofill driver.";
+ DVLOG(1) << __func__ << " Failed to get the autofill driver.";
OnResult(false, std::move(callback));
return;
}
@@ -980,6 +1006,7 @@ void WebController::FillCardForm(std::unique_ptr<autofill::CreditCard> card,
const base::string16& cvc,
const Selector& selector,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector;
auto data_to_autofill = std::make_unique<FillFormInputData>();
data_to_autofill->card = std::move(card);
data_to_autofill->cvc = cvc;
@@ -994,6 +1021,7 @@ void WebController::FillCardForm(std::unique_ptr<autofill::CreditCard> card,
void WebController::SelectOption(const Selector& selector,
const std::string& selected_option,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector << ", option=" << selected_option;
FindElement(selector,
/* strict_mode= */ true,
base::BindOnce(&WebController::OnFindElementForSelectOption,
@@ -1007,7 +1035,7 @@ void WebController::OnFindElementForSelectOption(
std::unique_ptr<FindElementResult> element_result) {
const std::string object_id = element_result->object_id;
if (object_id.empty()) {
- DLOG(ERROR) << "Failed to find the element to select an option.";
+ DVLOG(1) << __func__ << " Failed to find the element to select an option.";
OnResult(false, std::move(callback));
return;
}
@@ -1032,7 +1060,7 @@ void WebController::OnSelectOption(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
- DLOG(ERROR) << "Failed to select option.";
+ DVLOG(1) << __func__ << " Failed to select option.";
OnResult(false, std::move(callback));
return;
}
@@ -1044,6 +1072,7 @@ void WebController::OnSelectOption(
void WebController::HighlightElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector;
FindElement(
selector,
/* strict_mode= */ true,
@@ -1056,7 +1085,7 @@ void WebController::OnFindElementForHighlightElement(
std::unique_ptr<FindElementResult> element_result) {
const std::string object_id = element_result->object_id;
if (object_id.empty()) {
- DLOG(ERROR) << "Failed to find the element to highlight.";
+ DVLOG(1) << __func__ << " Failed to find the element to highlight.";
OnResult(false, std::move(callback));
return;
}
@@ -1079,7 +1108,7 @@ void WebController::OnHighlightElement(
base::OnceCallback<void(bool)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
- DLOG(ERROR) << "Failed to highlight element.";
+ DVLOG(1) << __func__ << " Failed to highlight element.";
OnResult(false, std::move(callback));
return;
}
@@ -1090,6 +1119,7 @@ void WebController::OnHighlightElement(
void WebController::FocusElement(const Selector& selector,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector;
DCHECK(!selector.empty());
FindElement(
selector,
@@ -1145,6 +1175,8 @@ void WebController::SetFieldValue(const Selector& selector,
const std::string& value,
bool simulate_key_presses,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector << ", value=" << value
+ << ", simulate_key_presses=" << simulate_key_presses;
if (simulate_key_presses) {
std::vector<std::string> utf8_chars;
base::i18n::UTF8CharIterator iter(&value);
@@ -1152,7 +1184,8 @@ void WebController::SetFieldValue(const Selector& selector,
wchar_t wide_char = iter.get();
std::string utf8_char;
if (!base::WideToUTF8(&wide_char, 1, &utf8_char)) {
- DLOG(ERROR) << "Failed to convert character to UTF-8: " << wide_char;
+ DVLOG(1) << __func__
+ << " Failed to convert character to UTF-8: " << wide_char;
OnResult(false, std::move(callback));
return;
}
@@ -1290,6 +1323,9 @@ void WebController::SetAttribute(const Selector& selector,
const std::vector<std::string>& attribute,
const std::string& value,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector << ", attribute=["
+ << base::JoinString(attribute, ",") << "], value=" << value;
+
DCHECK(!selector.empty());
DCHECK_GT(attribute.size(), 0u);
FindElement(selector,
@@ -1344,6 +1380,8 @@ void WebController::SendKeyboardInput(
const Selector& selector,
const std::vector<std::string>& utf8_chars,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " " << selector
+ << ", input=" << base::JoinString(utf8_chars, "");
DCHECK(!selector.empty());
FindElement(selector,
/* strict_mode= */ true,
@@ -1366,6 +1404,7 @@ void WebController::OnFindElementForSendKeyboardInput(
void WebController::GetOuterHtml(
const Selector& selector,
base::OnceCallback<void(bool, const std::string&)> callback) {
+ DVLOG(3) << __func__ << " " << selector;
FindElement(
selector,
/* strict_mode= */ true,
@@ -1449,6 +1488,7 @@ void WebController::OnFindElementForGetOuterHtml(
std::unique_ptr<FindElementResult> element_result) {
const std::string object_id = element_result->object_id;
if (object_id.empty()) {
+ DVLOG(2) << __func__ << " Failed to find element for GetOuterHtml";
OnResult(false, "", std::move(callback));
return;
}
@@ -1467,6 +1507,7 @@ void WebController::OnGetOuterHtml(
base::OnceCallback<void(bool, const std::string&)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result) {
if (!result || result->HasExceptionDetails()) {
+ DVLOG(2) << __func__ << " Failed to find element for GetOuterHtml";
OnResult(false, "", std::move(callback));
return;
}
@@ -1479,6 +1520,7 @@ void WebController::OnGetOuterHtml(
void WebController::SetCookie(const std::string& domain,
base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__ << " domain=" << domain;
DCHECK(!domain.empty());
auto expires_seconds =
std::chrono::seconds(std::time(nullptr)).count() + kCookieExpiresSeconds;
@@ -1500,6 +1542,7 @@ void WebController::OnSetCookie(
}
void WebController::HasCookie(base::OnceCallback<void(bool)> callback) {
+ DVLOG(3) << __func__;
devtools_client_->GetNetwork()->GetCookies(
base::BindOnce(&WebController::OnHasCookie,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
@@ -1525,8 +1568,53 @@ void WebController::OnHasCookie(
}
void WebController::ClearCookie() {
+ DVLOG(3) << __func__;
devtools_client_->GetNetwork()->DeleteCookies(kAutofillAssistantCookieName,
base::DoNothing());
}
+void WebController::WaitForDocumentToBecomeInteractive(
+ int remaining_rounds,
+ std::string object_id,
+ base::OnceCallback<void(bool)> callback) {
+ devtools_client_->GetRuntime()->CallFunctionOn(
+ runtime::CallFunctionOnParams::Builder()
+ .SetObjectId(object_id)
+ .SetFunctionDeclaration(std::string(kIsDocumentReadyForInteract))
+ .SetReturnByValue(true)
+ .Build(),
+ base::BindOnce(&WebController::OnWaitForDocumentToBecomeInteractive,
+ weak_ptr_factory_.GetWeakPtr(), remaining_rounds,
+ object_id, std::move(callback)));
+}
+
+void WebController::OnWaitForDocumentToBecomeInteractive(
+ int remaining_rounds,
+ std::string object_id,
+ base::OnceCallback<void(bool)> callback,
+ std::unique_ptr<runtime::CallFunctionOnResult> result) {
+ if (!result || !result->GetResult() || result->HasExceptionDetails() ||
+ remaining_rounds <= 0) {
+ DVLOG(1) << __func__
+ << " Failed to wait for the document to become interactive with "
+ "remaining_rounds: "
+ << remaining_rounds;
+ std::move(callback).Run(false);
+ return;
+ }
+
+ DCHECK(result->GetResult()->GetValue()->is_bool());
+ if (result->GetResult()->GetValue()->GetBool()) {
+ std::move(callback).Run(true);
+ return;
+ }
+
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&WebController::WaitForDocumentToBecomeInteractive,
+ weak_ptr_factory_.GetWeakPtr(), --remaining_rounds,
+ object_id, std::move(callback)),
+ kPeriodicCheckInterval);
+}
+
} // namespace autofill_assistant
diff --git a/chromium/components/autofill_assistant/browser/web_controller.h b/chromium/components/autofill_assistant/browser/web_controller.h
index db6204f9c69..74b36f5c7d7 100644
--- a/chromium/components/autofill_assistant/browser/web_controller.h
+++ b/chromium/components/autofill_assistant/browser/web_controller.h
@@ -20,6 +20,7 @@
#include "components/autofill_assistant/browser/devtools/devtools_client.h"
#include "components/autofill_assistant/browser/rectf.h"
#include "components/autofill_assistant/browser/selector.h"
+#include "url/gurl.h"
namespace autofill {
class AutofillProfile;
@@ -58,9 +59,6 @@ class WebController {
std::unique_ptr<DevtoolsClient> devtools_client);
virtual ~WebController();
- // Returns the last committed URL of the associated |web_contents_|.
- virtual const GURL& GetUrl();
-
// Load |url| in the current tab. Returns immediately, before the new page has
// been loaded.
virtual void LoadURL(const GURL& url);
@@ -267,6 +265,11 @@ class WebController {
void OnFindElementForClickOrTap(base::OnceCallback<void(bool)> callback,
bool is_a_click,
std::unique_ptr<FindElementResult> result);
+ void OnWaitDocumentToBecomeInteractiveForClickOrTap(
+ base::OnceCallback<void(bool)> callback,
+ bool is_a_click,
+ std::unique_ptr<FindElementResult> target_element,
+ bool result);
void OnFindElementForTap(base::OnceCallback<void(bool)> callback,
std::unique_ptr<FindElementResult> result);
void ClickOrTapElement(std::unique_ptr<FindElementResult> target_element,
@@ -435,11 +438,9 @@ class WebController {
void OnGetOuterHtml(
base::OnceCallback<void(bool, const std::string&)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result);
-
void OnFindElementForPosition(
base::OnceCallback<void(bool, const RectF&)> callback,
std::unique_ptr<FindElementResult> result);
-
void OnGetElementPositionResult(
base::OnceCallback<void(bool, const RectF&)> callback,
std::unique_ptr<runtime::CallFunctionOnResult> result);
@@ -457,6 +458,17 @@ class WebController {
void OnHasCookie(base::OnceCallback<void(bool)> callback,
std::unique_ptr<network::GetCookiesResult> result);
+ // Waits for the document.readyState to be 'interactive' or 'complete'.
+ void WaitForDocumentToBecomeInteractive(
+ int remaining_rounds,
+ std::string object_id,
+ base::OnceCallback<void(bool)> callback);
+ void OnWaitForDocumentToBecomeInteractive(
+ int remaining_rounds,
+ std::string object_id,
+ base::OnceCallback<void(bool)> callback,
+ std::unique_ptr<runtime::CallFunctionOnResult> result);
+
// Weak pointer is fine here since it must outlive this web controller, which
// is guaranteed by the owner of this object.
content::WebContents* web_contents_;
diff --git a/chromium/components/autofill_assistant/browser/web_controller_browsertest.cc b/chromium/components/autofill_assistant/browser/web_controller_browsertest.cc
index 3a23ff2972e..078adf35158 100644
--- a/chromium/components/autofill_assistant/browser/web_controller_browsertest.cc
+++ b/chromium/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -751,10 +751,12 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ConcurrentGetFieldsValue) {
}
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, NavigateToUrl) {
- EXPECT_EQ(kTargetWebsitePath, web_controller_->GetUrl().path());
+ EXPECT_EQ(kTargetWebsitePath,
+ shell()->web_contents()->GetLastCommittedURL().path());
web_controller_->LoadURL(GURL(url::kAboutBlankURL));
WaitForLoadStop(shell()->web_contents());
- EXPECT_EQ(url::kAboutBlankURL, web_controller_->GetUrl().spec());
+ EXPECT_EQ(url::kAboutBlankURL,
+ shell()->web_contents()->GetLastCommittedURL().spec());
}
IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, HighlightElement) {
diff --git a/chromium/components/autofill_assistant_strings.grdp b/chromium/components/autofill_assistant_strings.grdp
index 45c36e30f8f..bd0f46439a9 100644
--- a/chromium/components/autofill_assistant_strings.grdp
+++ b/chromium/components/autofill_assistant_strings.grdp
@@ -2,10 +2,12 @@
<grit-part>
<if expr="is_android">
<message name="IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR" desc="Text label that is shown when autofill assistant cannot help anymore, because something went wrong.">
- Something went wrong. You can finish your order on the website.
+ Sorry, something went wrong.
</message>
- <message name="IDS_AUTOFILL_ASSISTANT_GIVE_UP" desc="Text label that is shown when autofill assistant cannot help anymore, because of a user action." formatter_data="android_java">
- I cannot help anymore, please continue on your own.
+ <message name="IDS_AUTOFILL_ASSISTANT_GIVE_UP"
+ desc="Text label that is shown when autofill assistant cannot help anymore, because of a user action."
+ internal_comment="TODO(wnwen): Remove duplication in chrome/android/features/autofill_assistant/strings/android_chrome_autofill_assistant_strings.grd">
+ Sorry I'm not able to help, please continue on your own.
</message>
<message name="IDS_AUTOFILL_ASSISTANT_MAYBE_GIVE_UP" desc="Text label shown next to an UNDO button when user action indicate they want to continue on their own.">
Continue manually?
@@ -13,26 +15,14 @@
<message name="IDS_AUTOFILL_ASSISTANT_LOADING" desc="Text label that is shown during the loading of the first page, right after being triggered.">
Opening <ph name="SITE_NAME">$1<ex>google.com</ex></ph>…
</message>
- <message name="IDS_AUTOFILL_ASSISTANT_PAYMENT_INFO_CONFIRM" desc="Text on the payment request primary button to confirm payment information [CHAR-LIMIT=32]" formatter_data="android_java">
- Continue
- </message>
<message name="IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER" desc="Shown as Status Message when details differ.">
The screening is different from what you selected. Continue?
</message>
- <message name="IDS_AUTOFILL_ASSISTANT_DETAILS_DIFFER_GO_BACK" desc="Shown on a button allowing going back when details differ.">
- Go back
- </message>
- <message name="IDS_AUTOFILL_ASSISTANT_FIRST_RUN_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant first run screen is shown." formatter_data="android_java">
- Google Assistant in Chrome first run screen is shown
- </message>
- <message name="IDS_AUTOFILL_ASSISTANT_AVAILABLE_ACCESSIBILITY" desc="Accessibility description of Autofill Assistant is available." formatter_data="android_java">
- Google Assistant in Chrome is available near bottom of the screen
- </message>
<message name="IDS_AUTOFILL_ASSISTANT_CONTINUE_BUTTON" desc="Generic label for a button to continue to the next screen.">
Continue
</message>
<message name="IDS_AUTOFILL_ASSISTANT_STOPPED" desc="Text label that is shown when stopping the Autofill Assistant.">
- Google Assistant in Chrome stopping
- </message>
+ Google Assistant in Chrome stopping
+ </message>
</if>
</grit-part>
diff --git a/chromium/components/autofill_strings.grdp b/chromium/components/autofill_strings.grdp
index 2016de68e4f..8c5ba229d61 100644
--- a/chromium/components/autofill_strings.grdp
+++ b/chromium/components/autofill_strings.grdp
@@ -214,7 +214,7 @@
<message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save card prompt when the card is to be saved locally. The prompt can be either a bubble or an infobar.">
Save card?
</message>
- <message name="IDS_AUTOFILL_NAME_FIX_FLOW_PROMPT_SAVE_CARD" desc="Text to show for the Autofill save credit card prompt card holder name fix flow button." formatter_data="android_java">
+ <message name="IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL" desc="Text to show on the button to save the card to Google when the fix flow dialog is shown after the Autofill save card prompt." formatter_data="android_java">
Save card
</message>
<if expr="is_linux and not chromeos">
@@ -268,6 +268,9 @@
<message name="IDS_AUTOFILL_SAVE_CARD_CARDHOLDER_NAME_FIX_FLOW_HEADER" desc="Header for the cardholder name fix flow.">
Confirm name
</message>
+ <message name="IDS_AUTOFILL_SAVE_CARD_UPDATE_EXPIRATION_DATE_TITLE" desc="Title for the dialog requesting the user to fill in the expiration date of the credit card during the save card to google flow.">
+ Enter expiration date
+ </message>
<message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_TOOLTIP" desc="The tooltip hover text that explains why credit card upload to Google Payments is being offered.">
Chrome is offering to save your cards in your Google Account because you are signed in. You can change this behavior in settings.
</message>
@@ -464,7 +467,7 @@
<message name="IDS_AUTOFILL_CARD_UNMASK_INVALID_EXPIRATION_DATE" desc="Error message to show when a user has input an invalid or old expiration date.">
The card is expired
</message>
- <message name="IDS_AUTOFILL_CARD_UNMASK_EXPIRATION_DATE_SEPARATOR" desc="Separator for a credit card expiration date, e.g. the slash in 05/16." formatter_data="android_java">
+ <message name="IDS_AUTOFILL_EXPIRATION_DATE_SEPARATOR" desc="Separator for a credit card expiration date, e.g. the slash in 05/16." formatter_data="android_java">
/
</message>
<message name="IDS_AUTOFILL_CARD_UNMASK_NEW_CARD_LINK" desc="Text for link that prompts user to update their credit card after it may have been re-issued." formatter_data="android_java">
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
index 5fc778baa2e..43e350fb6b6 100644
--- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
+++ b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
@@ -18,4 +18,21 @@ public final class BackgroundTaskSchedulerExternalUma {
public static void reportTaskStartedNative(int taskId) {
BackgroundTaskSchedulerUma.getInstance().reportTaskStartedNative(taskId);
}
+
+ /**
+ * Report metrics for starting a NativeBackgroundTask. This does not consider tasks that are
+ * short-circuited before any work is done.
+ */
+ public static void reportNativeTaskStarted(int taskId) {
+ BackgroundTaskSchedulerUma.getInstance().reportNativeTaskStarted(taskId);
+ }
+
+ /**
+ * Reports metrics that a NativeBackgroundTask has been finished cleanly (i.e., no unexpected
+ * exits because of chrome crash or OOM). This includes tasks that have been stopped due to
+ * timeout.
+ */
+ public static void reportNativeTaskFinished(int taskId) {
+ BackgroundTaskSchedulerUma.getInstance().reportNativeTaskFinished(taskId);
+ }
} \ No newline at end of file
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java
index 8976d139b36..bc759eb8e45 100644
--- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java
+++ b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManager.java
@@ -120,11 +120,11 @@ class BackgroundTaskSchedulerGcmNetworkManager implements BackgroundTaskSchedule
@TaskInfo.NetworkType int networkType) {
switch (networkType) {
// This is correct: GcmNM ANY means no network is guaranteed.
- case TaskInfo.NETWORK_TYPE_NONE:
+ case TaskInfo.NetworkType.NONE:
return Task.NETWORK_STATE_ANY;
- case TaskInfo.NETWORK_TYPE_ANY:
+ case TaskInfo.NetworkType.ANY:
return Task.NETWORK_STATE_CONNECTED;
- case TaskInfo.NETWORK_TYPE_UNMETERED:
+ case TaskInfo.NetworkType.UNMETERED:
return Task.NETWORK_STATE_UNMETERED;
default:
assert false;
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java
index d1ca29e8a1d..abc46e6c6f8 100644
--- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java
+++ b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUma.java
@@ -36,8 +36,10 @@ class BackgroundTaskSchedulerUma {
static final int BACKGROUND_TASK_DEPRECATED_EXPLORE_SITES_REFRESH = 16;
static final int BACKGROUND_TASK_EXPLORE_SITES_REFRESH = 17;
static final int BACKGROUND_TASK_DOWNLOAD_AUTO_RESUMPTION = 18;
+ static final int BACKGROUND_TASK_ONE_SHOT_SYNC_WAKE_UP = 19;
+ static final int BACKGROUND_TASK_NOTIFICATION_SCHEDULER = 20;
// Keep this one at the end and increment appropriately when adding new tasks.
- static final int BACKGROUND_TASK_COUNT = 19;
+ static final int BACKGROUND_TASK_COUNT = 21;
static final String KEY_CACHED_UMA = "bts_cached_uma";
@@ -157,6 +159,23 @@ class BackgroundTaskSchedulerUma {
toUmaEnumValueFromTaskId(taskId));
}
+ /**
+ * Report metrics for starting a NativeBackgroundTask. This does not consider tasks that are
+ * short-circuited before any work is done.
+ */
+ public void reportNativeTaskStarted(int taskId) {
+ cacheEvent("Android.NativeBackgroundTask.TaskStarted", toUmaEnumValueFromTaskId(taskId));
+ }
+
+ /**
+ * Reports metrics that a NativeBackgroundTask has been finished cleanly (i.e., no unexpected
+ * exits because of chrome crash or OOM). This includes tasks that have been stopped due to
+ * timeout.
+ */
+ public void reportNativeTaskFinished(int taskId) {
+ cacheEvent("Android.NativeBackgroundTask.TaskFinished", toUmaEnumValueFromTaskId(taskId));
+ }
+
/** Method that actually invokes histogram recording. Extracted for testing. */
@VisibleForTesting
void recordEnumeratedHistogram(String histogram, int value, int maxCount) {
@@ -262,6 +281,10 @@ class BackgroundTaskSchedulerUma {
return BACKGROUND_TASK_DEPRECATED_EXPLORE_SITES_REFRESH;
case TaskIds.EXPLORE_SITES_REFRESH_JOB_ID:
return BACKGROUND_TASK_EXPLORE_SITES_REFRESH;
+ case TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID:
+ return BACKGROUND_TASK_ONE_SHOT_SYNC_WAKE_UP;
+ case TaskIds.NOTIFICATION_SCHEDULER_JOB_ID:
+ return BACKGROUND_TASK_NOTIFICATION_SCHEDULER;
default:
assert false;
}
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java
index 959377ada7f..9e6f4b4734e 100644
--- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java
+++ b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskIds.java
@@ -31,6 +31,8 @@ public final class TaskIds {
public static final int COMPONENT_UPDATE_JOB_ID = 2;
public static final int DEPRECATED_EXPLORE_SITES_REFRESH_JOB_ID = 100;
public static final int EXPLORE_SITES_REFRESH_JOB_ID = 101;
+ public static final int BACKGROUND_SYNC_ONE_SHOT_JOB_ID = 102;
+ public static final int NOTIFICATION_SCHEDULER_JOB_ID = 103;
private TaskIds() {}
}
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java
index ed78922bbf1..f155a4cd265 100644
--- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java
+++ b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java
@@ -113,28 +113,28 @@ public class TaskInfo {
}
}
+ @IntDef({NetworkType.NONE, NetworkType.ANY, NetworkType.UNMETERED})
@Retention(RetentionPolicy.SOURCE)
- @IntDef({NETWORK_TYPE_NONE, NETWORK_TYPE_ANY, NETWORK_TYPE_UNMETERED})
- public @interface NetworkType {}
-
- /**
- * This task has no requirements for network connectivity. Default.
- *
- * @see NetworkType
- */
- public static final int NETWORK_TYPE_NONE = 0;
- /**
- * This task requires network connectivity.
- *
- * @see NetworkType
- */
- public static final int NETWORK_TYPE_ANY = 1;
- /**
- * This task requires network connectivity that is unmetered.
- *
- * @see NetworkType
- */
- public static final int NETWORK_TYPE_UNMETERED = 2;
+ public @interface NetworkType {
+ /**
+ * This task has no requirements for network connectivity. Default.
+ *
+ * @see NetworkType
+ */
+ int NONE = 0;
+ /**
+ * This task requires network connectivity.
+ *
+ * @see NetworkType
+ */
+ int ANY = 1;
+ /**
+ * This task requires network connectivity that is unmetered.
+ *
+ * @see NetworkType
+ */
+ int UNMETERED = 2;
+ }
/**
* The task ID should be unique across all tasks. A list of such unique IDs exists in
diff --git a/chromium/components/background_task_scheduler/android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java b/chromium/components/background_task_scheduler/android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java
index f4e375b4482..5aabb75530a 100644
--- a/chromium/components/background_task_scheduler/android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java
+++ b/chromium/components/background_task_scheduler/android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java
@@ -145,7 +145,7 @@ public class BackgroundTaskSchedulerJobServiceTest {
jobInfo = BackgroundTaskSchedulerJobService.createJobInfoFromTaskInfo(
InstrumentationRegistry.getTargetContext(),
- taskBuilder.setRequiredNetworkType(TaskInfo.NETWORK_TYPE_UNMETERED).build());
+ taskBuilder.setRequiredNetworkType(TaskInfo.NetworkType.UNMETERED).build());
Assert.assertEquals(JobInfo.NETWORK_TYPE_UNMETERED, jobInfo.getNetworkType());
jobInfo = BackgroundTaskSchedulerJobService.createJobInfoFromTaskInfo(
diff --git a/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java b/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java
index f9dcca686c7..cad5c84b159 100644
--- a/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java
+++ b/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerGcmNetworkManagerTest.java
@@ -153,7 +153,7 @@ public class BackgroundTaskSchedulerGcmNetworkManagerTest {
assertTrue(task.isPersisted());
task = BackgroundTaskSchedulerGcmNetworkManager.createTaskFromTaskInfo(
- taskBuilder.setRequiredNetworkType(TaskInfo.NETWORK_TYPE_UNMETERED).build());
+ taskBuilder.setRequiredNetworkType(TaskInfo.NetworkType.UNMETERED).build());
assertEquals(Task.NETWORK_STATE_UNMETERED, task.getRequiredNetwork());
task = BackgroundTaskSchedulerGcmNetworkManager.createTaskFromTaskInfo(
diff --git a/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java b/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java
index 905c63d5eac..1023e9387f4 100644
--- a/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java
+++ b/chromium/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java
@@ -96,7 +96,13 @@ public class BackgroundTaskSchedulerUmaTest {
assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_DEPRECATED_EXPLORE_SITES_REFRESH,
BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(
TaskIds.DEPRECATED_EXPLORE_SITES_REFRESH_JOB_ID));
- assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_COUNT, 19);
+ assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_ONE_SHOT_SYNC_WAKE_UP,
+ BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(
+ TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID));
+ assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_NOTIFICATION_SCHEDULER,
+ BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(
+ TaskIds.NOTIFICATION_SCHEDULER_JOB_ID));
+ assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_COUNT, 21);
}
@Test
diff --git a/chromium/components/bookmarks/browser/bookmark_codec.cc b/chromium/components/bookmarks/browser/bookmark_codec.cc
index 36d60c05588..e1d11239a70 100644
--- a/chromium/components/bookmarks/browser/bookmark_codec.cc
+++ b/chromium/components/bookmarks/browser/bookmark_codec.cc
@@ -57,7 +57,7 @@ BookmarkCodec::BookmarkCodec()
BookmarkNode::kInvalidSyncTransactionVersion) {
}
-BookmarkCodec::~BookmarkCodec() {}
+BookmarkCodec::~BookmarkCodec() = default;
std::unique_ptr<base::Value> BookmarkCodec::Encode(
BookmarkModel* model,
@@ -86,7 +86,7 @@ std::unique_ptr<base::Value> BookmarkCodec::Encode(
if (sync_transaction_version !=
BookmarkNode::kInvalidSyncTransactionVersion) {
roots->SetString(kSyncTransactionVersion,
- base::Int64ToString(sync_transaction_version));
+ base::NumberToString(sync_transaction_version));
}
auto main = std::make_unique<base::DictionaryValue>();
main->SetInteger(kVersionKey, kCurrentVersion);
@@ -99,7 +99,8 @@ std::unique_ptr<base::Value> BookmarkCodec::Encode(
if (!sync_metadata_str.empty()) {
std::string sync_metadata_str_base64;
base::Base64Encode(sync_metadata_str, &sync_metadata_str_base64);
- main->SetString(kSyncMetadata, std::move(sync_metadata_str_base64));
+ main->SetKey(kSyncMetadata,
+ base::Value(std::move(sync_metadata_str_base64)));
}
return std::move(main);
}
@@ -130,12 +131,12 @@ bool BookmarkCodec::Decode(const base::Value& value,
std::unique_ptr<base::Value> BookmarkCodec::EncodeNode(
const BookmarkNode* node) {
std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
- std::string id = base::Int64ToString(node->id());
+ std::string id = base::NumberToString(node->id());
value->SetString(kIdKey, id);
const base::string16& title = node->GetTitle();
value->SetString(kNameKey, title);
value->SetString(kDateAddedKey,
- base::Int64ToString(node->date_added().ToInternalValue()));
+ base::NumberToString(node->date_added().ToInternalValue()));
if (node->is_url()) {
value->SetString(kTypeKey, kTypeURL);
std::string url = node->url().possibly_invalid_spec();
@@ -145,7 +146,7 @@ std::unique_ptr<base::Value> BookmarkCodec::EncodeNode(
value->SetString(kTypeKey, kTypeFolder);
value->SetString(
kDateModifiedKey,
- base::Int64ToString(node->date_folder_modified().ToInternalValue()));
+ base::NumberToString(node->date_folder_modified().ToInternalValue()));
UpdateChecksumWithFolderNode(id, title);
auto child_values = std::make_unique<base::ListValue>();
@@ -159,7 +160,7 @@ std::unique_ptr<base::Value> BookmarkCodec::EncodeNode(
if (node->sync_transaction_version() !=
BookmarkNode::kInvalidSyncTransactionVersion) {
value->SetString(kSyncTransactionVersion,
- base::Int64ToString(node->sync_transaction_version()));
+ base::NumberToString(node->sync_transaction_version()));
}
return std::move(value);
}
@@ -167,8 +168,8 @@ std::unique_ptr<base::Value> BookmarkCodec::EncodeNode(
std::unique_ptr<base::Value> BookmarkCodec::EncodeMetaInfo(
const BookmarkNode::MetaInfoMap& meta_info_map) {
auto meta_info = std::make_unique<base::DictionaryValue>();
- for (auto it = meta_info_map.begin(); it != meta_info_map.end(); ++it) {
- meta_info->SetKey(it->first, base::Value(it->second));
+ for (const auto& item : meta_info_map) {
+ meta_info->SetKey(item.first, base::Value(item.second));
}
return std::move(meta_info);
}
@@ -315,7 +316,7 @@ bool BookmarkCodec::DecodeNode(const base::DictionaryValue& value,
std::string date_added_string;
if (!value.GetString(kDateAddedKey, &date_added_string))
- date_added_string = base::Int64ToString(Time::Now().ToInternalValue());
+ date_added_string = base::NumberToString(Time::Now().ToInternalValue());
int64_t internal_time;
base::StringToInt64(date_added_string, &internal_time);
@@ -344,7 +345,7 @@ bool BookmarkCodec::DecodeNode(const base::DictionaryValue& value,
} else {
std::string last_modified_date;
if (!value.GetString(kDateModifiedKey, &last_modified_date))
- last_modified_date = base::Int64ToString(Time::Now().ToInternalValue());
+ last_modified_date = base::NumberToString(Time::Now().ToInternalValue());
const base::Value* child_values;
if (!value.Get(kChildrenKey, &child_values))
diff --git a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
index 27998816168..40cdbaaa076 100644
--- a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
+++ b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
@@ -109,7 +109,7 @@ void BookmarkExpandedStateTracker::UpdatePrefs(const Nodes& nodes) {
std::vector<base::Value> values;
values.reserve(nodes.size());
for (const auto* node : nodes) {
- values.emplace_back(base::Int64ToString(node->id()));
+ values.emplace_back(base::NumberToString(node->id()));
}
pref_service_->Set(prefs::kBookmarkEditorExpandedNodes,
diff --git a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker_unittest.cc b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker_unittest.cc
index f59a18f19d0..9ab01a3fab6 100644
--- a/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker_unittest.cc
+++ b/chromium/components/bookmarks/browser/bookmark_expanded_state_tracker_unittest.cc
@@ -44,8 +44,7 @@ BookmarkExpandedStateTrackerTest::BookmarkExpandedStateTrackerTest() {}
BookmarkExpandedStateTrackerTest::~BookmarkExpandedStateTrackerTest() {}
void BookmarkExpandedStateTrackerTest::SetUp() {
- prefs_.registry()->RegisterListPref(prefs::kBookmarkEditorExpandedNodes,
- std::make_unique<base::ListValue>());
+ prefs_.registry()->RegisterListPref(prefs::kBookmarkEditorExpandedNodes);
prefs_.registry()->RegisterListPref(prefs::kManagedBookmarks);
model_.reset(new BookmarkModel(std::make_unique<TestBookmarkClient>()));
model_->Load(&prefs_, base::FilePath(),
diff --git a/chromium/components/bookmarks/browser/bookmark_model_unittest.cc b/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
index 9e07e4df4d5..1a09c01c455 100644
--- a/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
+++ b/chromium/components/bookmarks/browser/bookmark_model_unittest.cc
@@ -139,7 +139,7 @@ void PopulateNodeImpl(const std::vector<std::string>& description,
// in debugging.
static int next_folder_id = 1;
TestNode* new_node = parent->Add(
- std::make_unique<TestNode>(base::IntToString16(next_folder_id++),
+ std::make_unique<TestNode>(base::NumberToString16(next_folder_id++),
BookmarkNode::FOLDER),
parent->child_count());
PopulateNodeImpl(description, index, new_node);
diff --git a/chromium/components/bookmarks/browser/bookmark_storage.cc b/chromium/components/bookmarks/browser/bookmark_storage.cc
index 4131094283e..7299cefe3ba 100644
--- a/chromium/components/bookmarks/browser/bookmark_storage.cc
+++ b/chromium/components/bookmarks/browser/bookmark_storage.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
#include <algorithm>
+#include <unordered_map>
#include <utility>
#include "base/bind.h"
@@ -14,6 +15,7 @@
#include "base/json/json_file_value_serializer.h"
#include "base/json/json_reader.h"
#include "base/json/json_string_value_serializer.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/sequenced_task_runner.h"
@@ -56,9 +58,61 @@ void AddBookmarksToIndex(BookmarkLoadDetails* details,
}
}
+// Helper function to recursively traverse the bookmark tree and count the
+// number of bookmarks (excluding folders) per URL (more precisely, per URL
+// hash).
+void PopulateNumNodesPerUrlHash(
+ const BookmarkNode* node,
+ std::unordered_map<size_t, int>* num_nodes_per_url_hash) {
+ DCHECK(num_nodes_per_url_hash);
+ DCHECK(node);
+
+ if (!node->is_folder())
+ (*num_nodes_per_url_hash)[std::hash<std::string>()(node->url().spec())]++;
+
+ for (int i = 0; i < node->child_count(); ++i)
+ PopulateNumNodesPerUrlHash(node->GetChild(i), num_nodes_per_url_hash);
+}
+
+// Computes the number of bookmarks (excluding folders) with a URL that is used
+// by at least one other bookmark.
+int GetNumDuplicateUrls(const BookmarkNode* root) {
+ DCHECK(root);
+
+ // The key is hash of the URL, instead of the full URL, to keep memory usage
+ // low. The value indicates the node count.
+ std::unordered_map<size_t, int> num_nodes_per_url_hash;
+ PopulateNumNodesPerUrlHash(root, &num_nodes_per_url_hash);
+
+ int num_duplicate_urls = 0;
+ for (const auto& url_hash_and_count : num_nodes_per_url_hash) {
+ if (url_hash_and_count.second > 1)
+ num_duplicate_urls += url_hash_and_count.second;
+ }
+ return num_duplicate_urls;
+}
+
+// Computes the number of bookmarks with an empty title. This includes folders
+// too except for the root.
+int GetNumNodesWithEmptyTitle(const BookmarkNode* node) {
+ DCHECK(node);
+
+ int num_nodes_with_empty_title = 0;
+
+ if (!node->is_root() && node->GetTitle().empty())
+ ++num_nodes_with_empty_title;
+
+ for (int i = 0; i < node->child_count(); ++i)
+ num_nodes_with_empty_title += GetNumNodesWithEmptyTitle(node->GetChild(i));
+
+ return num_nodes_with_empty_title;
+}
+
} // namespace
-void LoadBookmarks(const base::FilePath& path, BookmarkLoadDetails* details) {
+void LoadBookmarks(const base::FilePath& path,
+ bool emit_experimental_uma,
+ BookmarkLoadDetails* details) {
bool load_index = false;
bool bookmark_file_exists = base::PathExists(path);
if (bookmark_file_exists) {
@@ -120,6 +174,26 @@ void LoadBookmarks(const base::FilePath& path, BookmarkLoadDetails* details) {
UMA_HISTOGRAM_COUNTS_100000(
"Bookmarks.Count.OnProfileLoad",
base::saturated_cast<int>(details->url_index()->UrlCount()));
+
+ if (emit_experimental_uma && details->root_node()) {
+ TimeTicks start_time = TimeTicks::Now();
+
+ int num_duplicate_urls = GetNumDuplicateUrls(details->root_node());
+ if (num_duplicate_urls > 0) {
+ base::UmaHistogramCounts10000(
+ "Bookmarks.Count.OnProfileLoad.DuplicateUrl", num_duplicate_urls);
+ }
+
+ int num_nodes_with_empty_title =
+ GetNumNodesWithEmptyTitle(details->root_node());
+ if (num_nodes_with_empty_title > 0) {
+ base::UmaHistogramCounts10000("Bookmarks.Count.OnProfileLoad.EmptyTitle",
+ num_nodes_with_empty_title);
+ }
+
+ UMA_HISTOGRAM_TIMES("Bookmarks.DuplicateAndEmptyTitleDetectionTime",
+ TimeTicks::Now() - start_time);
+ }
}
// BookmarkLoadDetails ---------------------------------------------------------
diff --git a/chromium/components/bookmarks/browser/bookmark_storage.h b/chromium/components/bookmarks/browser/bookmark_storage.h
index 1abc6da1079..c611e5fa498 100644
--- a/chromium/components/bookmarks/browser/bookmark_storage.h
+++ b/chromium/components/bookmarks/browser/bookmark_storage.h
@@ -141,8 +141,11 @@ class BookmarkLoadDetails {
};
// Loads the bookmarks. This is intended to be called on the background thread.
-// Updates state in |details| based on the load.
+// Updates state in |details| based on the load. |emit_experimental_uma|
+// determines whether a few newly introduced and experimental UMA metrics should
+// be logged.
void LoadBookmarks(const base::FilePath& profile_path,
+ bool emit_experimental_uma,
BookmarkLoadDetails* details);
// BookmarkStorage handles reading/write the bookmark bar model. The
diff --git a/chromium/components/bookmarks/browser/bookmark_utils.cc b/chromium/components/bookmarks/browser/bookmark_utils.cc
index 759b0492db6..0b1f89cb9fe 100644
--- a/chromium/components/bookmarks/browser/bookmark_utils.cc
+++ b/chromium/components/bookmarks/browser/bookmark_utils.cc
@@ -459,8 +459,7 @@ void RegisterManagedBookmarksPrefs(PrefRegistrySimple* registry) {
// will cause a deadlock (see http://crbug.com/97955). If we truly
// want to sync the expanded state of folders, it should be part of
// bookmark sync itself (i.e., a property of the sync folder nodes).
- registry->RegisterListPref(prefs::kBookmarkEditorExpandedNodes,
- std::make_unique<base::ListValue>());
+ registry->RegisterListPref(prefs::kBookmarkEditorExpandedNodes);
registry->RegisterListPref(prefs::kManagedBookmarks);
registry->RegisterStringPref(
prefs::kManagedBookmarksFolderName, std::string());
diff --git a/chromium/components/bookmarks/browser/model_loader.cc b/chromium/components/bookmarks/browser/model_loader.cc
index f1316cdf6f5..12fe8d32547 100644
--- a/chromium/components/bookmarks/browser/model_loader.cc
+++ b/chromium/components/bookmarks/browser/model_loader.cc
@@ -5,6 +5,7 @@
#include "components/bookmarks/browser/model_loader.h"
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/bookmarks/browser/bookmark_storage.h"
@@ -12,6 +13,15 @@
namespace bookmarks {
+namespace {
+
+// TODO(mastiz): Remove this kill switch asap since the UMA metrics entail
+// negligible risks for stability or performance overhead.
+const base::Feature kEmitExperimentalBookmarkLoadUma{
+ "EmitExperimentalBookmarkLoadUma", base::FEATURE_ENABLED_BY_DEFAULT};
+
+} // namespace
+
// static
scoped_refptr<ModelLoader> ModelLoader::Create(
const base::FilePath& profile_path,
@@ -21,11 +31,18 @@ scoped_refptr<ModelLoader> ModelLoader::Create(
// Note: base::MakeRefCounted is not available here, as ModelLoader's
// constructor is private.
auto model_loader = base::WrapRefCounted(new ModelLoader());
+ // We plumb the value for kEmitExperimentalBookmarkLoadUma as retrieved on
+ // the UI thread to avoid issues with TSAN bots (in case there are tests that
+ // override feature toggles -not necessarily this one- while bookmark loading
+ // is ongoing, which is problematic due to how feature overriding for tests is
+ // implemented).
load_sequenced_task_runner->PostTask(
FROM_HERE,
- base::BindOnce(&ModelLoader::DoLoadOnBackgroundThread, model_loader,
- profile_path, base::ThreadTaskRunnerHandle::Get(),
- std::move(details), std::move(callback)));
+ base::BindOnce(
+ &ModelLoader::DoLoadOnBackgroundThread, model_loader, profile_path,
+ base::FeatureList::IsEnabled(kEmitExperimentalBookmarkLoadUma),
+ base::ThreadTaskRunnerHandle::Get(), std::move(details),
+ std::move(callback)));
return model_loader;
}
@@ -41,10 +58,11 @@ ModelLoader::~ModelLoader() = default;
void ModelLoader::DoLoadOnBackgroundThread(
const base::FilePath& profile_path,
+ bool emit_experimental_uma,
scoped_refptr<base::SequencedTaskRunner> main_sequenced_task_runner,
std::unique_ptr<BookmarkLoadDetails> details,
LoadCallback callback) {
- LoadBookmarks(profile_path, details.get());
+ LoadBookmarks(profile_path, emit_experimental_uma, details.get());
history_bookmark_model_ = details->url_index();
loaded_signal_.Signal();
main_sequenced_task_runner->PostTask(
diff --git a/chromium/components/bookmarks/browser/model_loader.h b/chromium/components/bookmarks/browser/model_loader.h
index 1a1477cb74e..6ff48d1d838 100644
--- a/chromium/components/bookmarks/browser/model_loader.h
+++ b/chromium/components/bookmarks/browser/model_loader.h
@@ -57,6 +57,7 @@ class ModelLoader : public base::RefCountedThreadSafe<ModelLoader> {
// Performs the load on a background thread.
void DoLoadOnBackgroundThread(
const base::FilePath& profile_path,
+ bool emit_experimental_uma,
scoped_refptr<base::SequencedTaskRunner> main_sequenced_task_runner,
std::unique_ptr<BookmarkLoadDetails> details,
LoadCallback callback);
diff --git a/chromium/components/bookmarks/browser/titled_url_node_sorter.h b/chromium/components/bookmarks/browser/titled_url_node_sorter.h
index 7913ef057fa..f5a2d7f1020 100644
--- a/chromium/components/bookmarks/browser/titled_url_node_sorter.h
+++ b/chromium/components/bookmarks/browser/titled_url_node_sorter.h
@@ -18,7 +18,7 @@ class TitledUrlNodeSorter {
using TitledUrlNodes = std::vector<const TitledUrlNode*>;
using TitledUrlNodeSet = base::flat_set<const TitledUrlNode*>;
- virtual ~TitledUrlNodeSorter() {};
+ virtual ~TitledUrlNodeSorter() {}
// Sorts |matches| in an implementation-specific way, placing the results in
// |sorted_nodes|.
diff --git a/chromium/components/browser_sync/BUILD.gn b/chromium/components/browser_sync/BUILD.gn
index ce5383c83df..4265fc598a1 100644
--- a/chromium/components/browser_sync/BUILD.gn
+++ b/chromium/components/browser_sync/BUILD.gn
@@ -6,6 +6,8 @@ import("//build/config/features.gni")
static_library("browser_sync") {
sources = [
+ "browser_sync_client.cc",
+ "browser_sync_client.h",
"browser_sync_switches.cc",
"browser_sync_switches.h",
"profile_sync_components_factory_impl.cc",
@@ -16,8 +18,6 @@ static_library("browser_sync") {
"signin_confirmation_helper.h",
"sync_auth_manager.cc",
"sync_auth_manager.h",
- "sync_user_settings_impl.cc",
- "sync_user_settings_impl.h",
]
public_deps = [
@@ -105,8 +105,6 @@ static_library("test_support") {
"profile_sync_service_mock.h",
"profile_sync_test_util.cc",
"profile_sync_test_util.h",
- "sync_user_settings_mock.cc",
- "sync_user_settings_mock.h",
"test_http_bridge_factory.cc",
"test_http_bridge_factory.h",
"test_profile_sync_service.cc",
diff --git a/chromium/components/browser_sync/DEPS b/chromium/components/browser_sync/DEPS
index 6dcdc6da51b..83aedd9ff3a 100644
--- a/chromium/components/browser_sync/DEPS
+++ b/chromium/components/browser_sync/DEPS
@@ -10,6 +10,7 @@ include_rules = [
"+components/pref_registry",
"+components/prefs",
"+components/reading_list/features",
+ "+components/send_tab_to_self",
"+components/signin/core/browser",
# Use identity_manager.h instead of the below files;
# see https://groups.google.com/a/chromium.org/d/msg/chromium-dev/dgFLuxqZt1o/iEqkyoQQBwAJ for help and info.
diff --git a/chromium/components/browser_sync/abstract_profile_sync_service_test.cc b/chromium/components/browser_sync/abstract_profile_sync_service_test.cc
index 58ba130fe53..996565828a1 100644
--- a/chromium/components/browser_sync/abstract_profile_sync_service_test.cc
+++ b/chromium/components/browser_sync/abstract_profile_sync_service_test.cc
@@ -22,8 +22,8 @@
#include "components/sync/syncable/test_user_share.h"
#include "services/network/test/test_network_connection_tracker.h"
-using syncer::SyncBackendHostImpl;
using syncer::ModelType;
+using syncer::SyncEngineImpl;
using testing::_;
using testing::ByMove;
using testing::Return;
@@ -37,11 +37,10 @@ std::unique_ptr<syncer::HttpPostProviderFactory> GetHttpPostProviderFactory(
return std::make_unique<TestHttpBridgeFactory>();
}
-class SyncEngineForProfileSyncTest : public SyncBackendHostImpl {
+class SyncEngineForProfileSyncTest : public SyncEngineImpl {
public:
SyncEngineForProfileSyncTest(
const base::FilePath& temp_dir,
- syncer::SyncClient* sync_client,
invalidation::InvalidationService* invalidator,
const base::WeakPtr<syncer::SyncPrefs>& sync_prefs,
base::OnceClosure callback);
@@ -62,13 +61,11 @@ class SyncEngineForProfileSyncTest : public SyncBackendHostImpl {
SyncEngineForProfileSyncTest::SyncEngineForProfileSyncTest(
const base::FilePath& temp_dir,
- syncer::SyncClient* sync_client,
invalidation::InvalidationService* invalidator,
const base::WeakPtr<syncer::SyncPrefs>& sync_prefs,
base::OnceClosure callback)
- : SyncBackendHostImpl(
+ : SyncEngineImpl(
"dummy_debug_name",
- sync_client,
invalidator,
sync_prefs,
temp_dir.Append(base::FilePath(FILE_PATH_LITERAL("test")))),
@@ -96,7 +93,7 @@ void SyncEngineForProfileSyncTest::Initialize(InitParams params) {
factory_switches, syncer::EngineComponentsFactory::STORAGE_IN_MEMORY,
nullptr);
- SyncBackendHostImpl::Initialize(std::move(params));
+ SyncEngineImpl::Initialize(std::move(params));
}
void SyncEngineForProfileSyncTest::ConfigureDataTypes(ConfigureParams params) {
@@ -142,11 +139,11 @@ void AbstractProfileSyncServiceTest::CreateSyncService(
syncer::SyncApiComponentFactoryMock* components =
profile_sync_service_bundle_.component_factory();
auto engine = std::make_unique<SyncEngineForProfileSyncTest>(
- temp_dir_.GetPath(), sync_service_->GetSyncClientForTest(),
+ temp_dir_.GetPath(),
profile_sync_service_bundle_.fake_invalidation_service(),
sync_service_->sync_prefs()->AsWeakPtr(),
std::move(initialization_success_callback));
- EXPECT_CALL(*components, CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*components, CreateSyncEngine(_, _, _))
.WillOnce(Return(ByMove(std::move(engine))));
sync_service_->sync_prefs()->SetFirstSetupComplete();
diff --git a/chromium/components/browser_sync/browser_sync_client.cc b/chromium/components/browser_sync/browser_sync_client.cc
new file mode 100644
index 00000000000..9c285221c32
--- /dev/null
+++ b/chromium/components/browser_sync/browser_sync_client.cc
@@ -0,0 +1,19 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/browser_sync/browser_sync_client.h"
+
+#include "components/sync/model/model_type_store_service.h"
+
+namespace browser_sync {
+
+BrowserSyncClient::BrowserSyncClient() = default;
+
+BrowserSyncClient::~BrowserSyncClient() = default;
+
+base::FilePath BrowserSyncClient::GetSyncDataPath() {
+ return GetModelTypeStoreService()->GetSyncDataPath();
+}
+
+} // namespace browser_sync
diff --git a/chromium/components/browser_sync/browser_sync_client.h b/chromium/components/browser_sync/browser_sync_client.h
new file mode 100644
index 00000000000..a628137651e
--- /dev/null
+++ b/chromium/components/browser_sync/browser_sync_client.h
@@ -0,0 +1,75 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_CLIENT_H_
+#define COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_CLIENT_H_
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "components/sync/driver/sync_client.h"
+#include "components/sync/model/model_type_controller_delegate.h"
+
+class BookmarkUndoService;
+
+namespace autofill {
+class PersonalDataManager;
+} // namespace autofill
+
+namespace bookmarks {
+class BookmarkModel;
+} // namespace bookmarks
+
+namespace favicon {
+class FaviconService;
+} // namespace favicon
+
+namespace history {
+class HistoryService;
+} // namespace history
+
+namespace sync_sessions {
+class SessionSyncService;
+} // namespace sync_sessions
+
+namespace syncer {
+class ModelTypeStoreService;
+} // namespace syncer
+
+namespace browser_sync {
+
+// Extension to interface syncer::SyncClient to bundle dependencies that
+// sync-the-feature requires for datatypes common to all platforms.
+// Note: on some platforms, getters might return nullptr. Callers are expected
+// to handle these scenarios gracefully.
+class BrowserSyncClient : public syncer::SyncClient {
+ public:
+ BrowserSyncClient();
+ ~BrowserSyncClient() override;
+
+ base::FilePath GetSyncDataPath() final;
+ virtual syncer::ModelTypeStoreService* GetModelTypeStoreService() = 0;
+
+ // Returns a weak pointer to the ModelTypeControllerDelegate specified by
+ // |type|. Weak pointer may be unset if service is already destroyed.
+ virtual base::WeakPtr<syncer::ModelTypeControllerDelegate>
+ GetControllerDelegateForModelType(syncer::ModelType type) = 0;
+
+ // DataType specific service getters.
+ virtual bookmarks::BookmarkModel* GetBookmarkModel() = 0;
+ virtual favicon::FaviconService* GetFaviconService() = 0;
+ virtual history::HistoryService* GetHistoryService() = 0;
+ virtual sync_sessions::SessionSyncService* GetSessionSyncService() = 0;
+ virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
+ virtual BookmarkUndoService* GetBookmarkUndoService() = 0;
+ virtual base::RepeatingClosure GetPasswordStateChangedCallback() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BrowserSyncClient);
+};
+
+} // namespace browser_sync
+
+#endif // COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_CLIENT_H_
diff --git a/chromium/components/browser_sync/browser_sync_switches.cc b/chromium/components/browser_sync/browser_sync_switches.cc
index e970f0a0140..caf84911ef6 100644
--- a/chromium/components/browser_sync/browser_sync_switches.cc
+++ b/chromium/components/browser_sync/browser_sync_switches.cc
@@ -4,6 +4,8 @@
#include "components/browser_sync/browser_sync_switches.h"
+#include "base/command_line.h"
+
namespace switches {
// Disables syncing browser data to a Google Account.
@@ -24,4 +26,13 @@ const char kEnableLocalSyncBackend[] = "enable-local-sync-backend";
// flag is present.
const char kLocalSyncBackendDir[] = "local-sync-backend-dir";
+// If enabled, the sync engine will be shut down in the "paused" state.
+const base::Feature kStopSyncInPausedState{"StopSyncInPausedState",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsSyncAllowedByFlag() {
+ return !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableSync);
+}
+
} // namespace switches
diff --git a/chromium/components/browser_sync/browser_sync_switches.h b/chromium/components/browser_sync/browser_sync_switches.h
index fa706677c97..872285341f7 100644
--- a/chromium/components/browser_sync/browser_sync_switches.h
+++ b/chromium/components/browser_sync/browser_sync_switches.h
@@ -7,6 +7,8 @@
#ifndef COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_SWITCHES_H_
#define COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_SWITCHES_H_
+#include "base/feature_list.h"
+
namespace switches {
extern const char kDisableSync[];
@@ -14,6 +16,14 @@ extern const char kDisableSyncTypes[];
extern const char kEnableLocalSyncBackend[];
extern const char kLocalSyncBackendDir[];
+extern const base::Feature kStopSyncInPausedState;
+
+// Returns whether sync is allowed to run based on command-line switches.
+// Profile::IsSyncAllowed() is probably a better signal than this function.
+// This function can be called from any thread, and the implementation doesn't
+// assume it's running on the UI thread.
+bool IsSyncAllowedByFlag();
+
} // namespace switches
#endif // COMPONENTS_BROWSER_SYNC_BROWSER_SYNC_SWITCHES_H_
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 942bf26cbbd..77fc254affc 100644
--- a/chromium/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/chromium/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
@@ -19,6 +20,7 @@
#include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/browser_sync/browser_sync_client.h"
#include "components/browser_sync/browser_sync_switches.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/history/core/browser/sync/history_delete_directives_data_type_controller.h"
@@ -27,16 +29,14 @@
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/sync/password_data_type_controller.h"
#include "components/password_manager/core/browser/sync/password_model_type_controller.h"
-#include "components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h"
#include "components/prefs/pref_service.h"
#include "components/reading_list/features/reading_list_switches.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/device_info/device_info_sync_service.h"
#include "components/sync/driver/async_directory_type_controller.h"
#include "components/sync/driver/data_type_manager_impl.h"
-#include "components/sync/driver/glue/sync_backend_host_impl.h"
+#include "components/sync/driver/glue/sync_engine_impl.h"
#include "components/sync/driver/model_type_controller.h"
-#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/driver/syncable_service_based_model_type_controller.h"
#include "components/sync/engine/sync_engine.h"
@@ -106,7 +106,7 @@ AutofillWalletMetadataDelegateFromDataService(
} // namespace
ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
- syncer::SyncClient* sync_client,
+ browser_sync::BrowserSyncClient* sync_client,
version_info::Channel channel,
const char* history_disabled_pref,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
@@ -125,7 +125,9 @@ ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
web_data_service_on_disk_(web_data_service_on_disk),
web_data_service_in_memory_(web_data_service_in_memory),
password_store_(password_store),
- bookmark_sync_service_(bookmark_sync_service) {}
+ bookmark_sync_service_(bookmark_sync_service) {
+ DCHECK(sync_client_);
+}
ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {}
@@ -134,6 +136,7 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
syncer::ModelTypeSet disabled_types,
syncer::SyncService* sync_service) {
syncer::DataTypeController::TypeVector controllers;
+
const base::RepeatingClosure dump_stack =
base::BindRepeating(&syncer::ReportUnrecoverableError, channel_);
@@ -179,6 +182,8 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
controllers.push_back(
std::make_unique<AutofillProfileDataTypeController>(
db_thread_, dump_stack, sync_service, sync_client_,
+ base::BindRepeating(&BrowserSyncClient::GetPersonalDataManager,
+ base::Unretained(sync_client_)),
web_data_service_on_disk_));
}
}
@@ -197,7 +202,10 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
controllers.push_back(
std::make_unique<AutofillWalletDataTypeController>(
syncer::AUTOFILL_WALLET_DATA, db_thread_, dump_stack,
- sync_service, sync_client_, web_data_service_on_disk_));
+ sync_service, sync_client_,
+ base::BindRepeating(&BrowserSyncClient::GetPersonalDataManager,
+ base::Unretained(sync_client_)),
+ web_data_service_on_disk_));
}
}
@@ -215,7 +223,10 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
controllers.push_back(
std::make_unique<AutofillWalletDataTypeController>(
syncer::AUTOFILL_WALLET_METADATA, db_thread_, dump_stack,
- sync_service, sync_client_, web_data_service_on_disk_));
+ sync_service, sync_client_,
+ base::BindRepeating(&BrowserSyncClient::GetPersonalDataManager,
+ base::Unretained(sync_client_)),
+ web_data_service_on_disk_));
}
}
}
@@ -234,7 +245,8 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
sync_client_->GetFaviconService()))));
} else {
controllers.push_back(std::make_unique<BookmarkDataTypeController>(
- dump_stack, sync_service, sync_client_));
+ dump_stack, sync_service, sync_client_->GetBookmarkModel(),
+ sync_client_->GetHistoryService(), this));
}
}
@@ -257,7 +269,8 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
switches::kSyncPseudoUSSHistoryDeleteDirectives)) {
controllers.push_back(
std::make_unique<HistoryDeleteDirectivesModelTypeController>(
- dump_stack, sync_service, sync_client_));
+ dump_stack, sync_service,
+ sync_client_->GetModelTypeStoreService(), sync_client_));
} else {
controllers.push_back(
@@ -323,14 +336,7 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
controllers.push_back(
std::make_unique<password_manager::PasswordModelTypeController>(
password_store_->CreateSyncControllerDelegate(), sync_service,
- sync_client_));
- } else if (base::FeatureList::IsEnabled(
- switches::kSyncPseudoUSSPasswords)) {
- controllers.push_back(
- std::make_unique<password_manager::
- PasswordSyncableServiceBasedModelTypeController>(
- sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
- dump_stack, password_store_, sync_service, sync_client_));
+ sync_client_->GetPasswordStateChangedCallback()));
} else {
controllers.push_back(std::make_unique<PasswordDataTypeController>(
dump_stack, sync_service, sync_client_,
@@ -398,6 +404,9 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
syncer::USER_EVENTS));
}
+ // TODO(crbug.com/919489): Enable security events once their controller
+ // delegate is wired properly.
+
// Forward both on-disk and in-memory storage modes to the same delegate,
// since behavior for USER_CONSENTS does not differ (they are always
// persisted).
@@ -407,16 +416,16 @@ ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
syncer::USER_CONSENTS,
/*delegate_on_disk=*/
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
- ui_thread_,
- base::BindRepeating(
- &syncer::SyncClient::GetControllerDelegateForModelType,
- base::Unretained(sync_client_), syncer::USER_CONSENTS)),
+ ui_thread_, base::BindRepeating(&browser_sync::BrowserSyncClient::
+ GetControllerDelegateForModelType,
+ base::Unretained(sync_client_),
+ syncer::USER_CONSENTS)),
/*delegate_in_memory=*/
std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
- ui_thread_,
- base::BindRepeating(
- &syncer::SyncClient::GetControllerDelegateForModelType,
- base::Unretained(sync_client_), syncer::USER_CONSENTS))));
+ ui_thread_, base::BindRepeating(&browser_sync::BrowserSyncClient::
+ GetControllerDelegateForModelType,
+ base::Unretained(sync_client_),
+ syncer::USER_CONSENTS))));
return controllers;
}
@@ -431,18 +440,18 @@ ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
syncer::ModelTypeConfigurer* configurer,
DataTypeManagerObserver* observer) {
return std::make_unique<DataTypeManagerImpl>(
- sync_client_, initial_types, debug_info_listener, controllers,
- encryption_handler, configurer, observer);
+ initial_types, debug_info_listener, controllers, encryption_handler,
+ configurer, observer);
}
std::unique_ptr<syncer::SyncEngine>
ProfileSyncComponentsFactoryImpl::CreateSyncEngine(
const std::string& name,
invalidation::InvalidationService* invalidator,
- const base::WeakPtr<syncer::SyncPrefs>& sync_prefs,
- const base::FilePath& sync_data_folder) {
- return std::make_unique<syncer::SyncBackendHostImpl>(
- name, sync_client_, invalidator, sync_prefs, sync_data_folder);
+ const base::WeakPtr<syncer::SyncPrefs>& sync_prefs) {
+ return std::make_unique<syncer::SyncEngineImpl>(
+ name, invalidator, sync_prefs,
+ sync_client_->GetModelTypeStoreService()->GetSyncDataPath());
}
syncer::SyncApiComponentFactory::SyncComponents
@@ -458,12 +467,13 @@ ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
#endif
auto model_associator = std::make_unique<BookmarkModelAssociator>(
- bookmark_model, sync_client_, user_share, error_handler->Copy(),
+ bookmark_model, sync_client_->GetBookmarkUndoService(),
+ sync_client_->GetFaviconService(), user_share, error_handler->Copy(),
kExpectMobileBookmarksFolder);
SyncComponents components;
components.change_processor = std::make_unique<BookmarkChangeProcessor>(
- sync_client_, model_associator.get(), std::move(error_handler));
+ model_associator.get(), std::move(error_handler));
components.model_associator = std::move(model_associator);
return components;
}
@@ -483,9 +493,9 @@ std::unique_ptr<ModelTypeController> ProfileSyncComponentsFactoryImpl::
return std::make_unique<ModelTypeController>(
type, std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
ui_thread_,
- base::BindRepeating(
- &syncer::SyncClient::GetControllerDelegateForModelType,
- base::Unretained(sync_client_), type)));
+ base::BindRepeating(&browser_sync::BrowserSyncClient::
+ GetControllerDelegateForModelType,
+ base::Unretained(sync_client_), type)));
}
std::unique_ptr<ModelTypeController>
diff --git a/chromium/components/browser_sync/profile_sync_components_factory_impl.h b/chromium/components/browser_sync/profile_sync_components_factory_impl.h
index bcd2b05c9ca..c68ccd146aa 100644
--- a/chromium/components/browser_sync/profile_sync_components_factory_impl.h
+++ b/chromium/components/browser_sync/profile_sync_components_factory_impl.h
@@ -19,7 +19,6 @@
namespace syncer {
class ModelTypeController;
class ModelTypeControllerDelegate;
-class SyncClient;
class SyncService;
}
@@ -37,11 +36,13 @@ class BookmarkSyncService;
namespace browser_sync {
+class BrowserSyncClient;
+
class ProfileSyncComponentsFactoryImpl
: public syncer::SyncApiComponentFactory {
public:
ProfileSyncComponentsFactoryImpl(
- syncer::SyncClient* sync_client,
+ BrowserSyncClient* sync_client,
version_info::Channel channel,
const char* history_disabled_pref,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
@@ -54,10 +55,14 @@ class ProfileSyncComponentsFactoryImpl
sync_bookmarks::BookmarkSyncService* bookmark_sync_service);
~ProfileSyncComponentsFactoryImpl() override;
- // SyncApiComponentFactory implementation:
+ // Creates and returns enabled datatypes and their controllers.
+ // |disabled_types| allows callers to prevent certain types from being
+ // created (e.g. to honor command-line flags).
syncer::DataTypeController::TypeVector CreateCommonDataTypeControllers(
syncer::ModelTypeSet disabled_types,
- syncer::SyncService* sync_service) override;
+ syncer::SyncService* sync_service);
+
+ // SyncApiComponentFactory implementation:
std::unique_ptr<syncer::DataTypeManager> CreateDataTypeManager(
syncer::ModelTypeSet initial_types,
const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
@@ -69,8 +74,7 @@ class ProfileSyncComponentsFactoryImpl
std::unique_ptr<syncer::SyncEngine> CreateSyncEngine(
const std::string& name,
invalidation::InvalidationService* invalidator,
- const base::WeakPtr<syncer::SyncPrefs>& sync_prefs,
- const base::FilePath& sync_data_folder) override;
+ const base::WeakPtr<syncer::SyncPrefs>& sync_prefs) override;
syncer::SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents(
std::unique_ptr<syncer::DataTypeErrorHandler> error_handler,
syncer::UserShare* user_share) override;
@@ -105,7 +109,7 @@ class ProfileSyncComponentsFactoryImpl
syncer::SyncService* sync_service);
// Client/platform specific members.
- syncer::SyncClient* const sync_client_;
+ BrowserSyncClient* const sync_client_;
const version_info::Channel channel_;
const char* history_disabled_pref_;
const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
diff --git a/chromium/components/browser_sync/profile_sync_service.cc b/chromium/components/browser_sync/profile_sync_service.cc
index a0355393cab..787e2d24941 100644
--- a/chromium/components/browser_sync/profile_sync_service.cc
+++ b/chromium/components/browser_sync/profile_sync_service.cc
@@ -13,42 +13,32 @@
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/browser_sync/browser_sync_switches.h"
#include "components/browser_sync/sync_auth_manager.h"
-#include "components/invalidation/impl/invalidation_prefs.h"
-#include "components/invalidation/impl/invalidation_switches.h"
#include "components/invalidation/public/invalidation_service.h"
-#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/account_info.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/sync/base/bind_to_task_runner.h"
-#include "components/sync/base/cryptographer.h"
-#include "components/sync/base/passphrase_enums.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/base/stop_source.h"
#include "components/sync/base/sync_base_switches.h"
#include "components/sync/device_info/device_info_sync_service.h"
#include "components/sync/device_info/local_device_info_provider.h"
#include "components/sync/driver/backend_migrator.h"
-#include "components/sync/driver/clear_server_data_events.h"
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/directory_data_type_controller.h"
#include "components/sync/driver/sync_api_component_factory.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/driver/sync_type_preference_provider.h"
#include "components/sync/driver/sync_util.h"
-#include "components/sync/engine/configure_reason.h"
#include "components/sync/engine/cycle/type_debug_info_observer.h"
#include "components/sync/engine/engine_components_factory_impl.h"
#include "components/sync/engine/net/http_bridge_network_resources.h"
#include "components/sync/engine/net/network_resources.h"
#include "components/sync/engine/polling_constants.h"
#include "components/sync/engine/sync_encryption_handler.h"
-#include "components/sync/model/change_processor.h"
-#include "components/sync/model/model_type_store_service.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/syncable/base_transaction.h"
#include "components/sync/syncable/directory.h"
@@ -144,10 +134,6 @@ DataTypeController::TypeMap BuildDataTypeControllerMap(
return type_map;
}
-bool IsStandaloneTransportEnabled() {
- return base::FeatureList::IsEnabled(switches::kSyncStandaloneTransport);
-}
-
} // namespace
ProfileSyncService::InitParams::InitParams() = default;
@@ -159,7 +145,6 @@ ProfileSyncService::ProfileSyncService(InitParams init_params)
sync_prefs_(sync_client_->GetPrefService()),
identity_manager_(init_params.identity_manager),
auth_manager_(std::make_unique<SyncAuthManager>(
- &sync_prefs_,
identity_manager_,
base::BindRepeating(&ProfileSyncService::AccountStateChanged,
base::Unretained(this)),
@@ -197,10 +182,11 @@ ProfileSyncService::ProfileSyncService(InitParams init_params)
weak_factory_(this) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(sync_client_);
+ DCHECK(IsLocalSyncEnabled() || identity_manager_ != nullptr);
// If Sync is disabled via command line flag, then ProfileSyncService
// shouldn't be instantiated.
- DCHECK(IsSyncAllowedByFlag());
+ DCHECK(switches::IsSyncAllowedByFlag());
std::string last_version = sync_prefs_.GetLastRunVersion();
std::string current_version = PRODUCT_VERSION;
@@ -216,7 +202,7 @@ ProfileSyncService::ProfileSyncService(InitParams init_params)
startup_controller_ = std::make_unique<syncer::StartupController>(
base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes,
base::Unretained(this)),
- base::BindRepeating(&ProfileSyncService::ShouldStartEngine,
+ base::BindRepeating(&ProfileSyncService::IsEngineAllowedToStart,
base::Unretained(this)),
base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents,
base::Unretained(this)));
@@ -260,7 +246,7 @@ void ProfileSyncService::Initialize() {
data_type_controllers_ =
BuildDataTypeControllerMap(sync_client_->CreateDataTypeControllers(this));
- user_settings_ = std::make_unique<SyncUserSettingsImpl>(
+ user_settings_ = std::make_unique<syncer::SyncUserSettingsImpl>(
&crypto_, &sync_prefs_, GetRegisteredDataTypes(),
base::BindRepeating(&ProfileSyncService::SyncAllowedByPlatformChanged,
base::Unretained(this)));
@@ -302,19 +288,6 @@ void ProfileSyncService::Initialize() {
}
void ProfileSyncService::StartSyncingWithServer() {
- if (base::FeatureList::IsEnabled(
- switches::kSyncClearDataOnPassphraseEncryption) &&
- sync_prefs_.GetPassphraseEncryptionTransitionInProgress()) {
- DCHECK(CanConfigureDataTypes(/*bypass_setup_in_progress_check=*/false));
- // We are restarting catchup configuration after browser restart.
- UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents",
- syncer::CLEAR_SERVER_DATA_RETRIED,
- syncer::CLEAR_SERVER_DATA_MAX);
-
- crypto_.BeginConfigureCatchUpBeforeClear();
- return;
- }
-
if (engine_)
engine_->StartSyncingWithServer();
@@ -360,14 +333,7 @@ void ProfileSyncService::AccountStateChanged() {
StopImpl(CLEAR_DATA);
DCHECK(!engine_);
} else {
-#if !defined(OS_CHROMEOS)
- // TODO(crbug.com/814787): SyncAuthManager shouldn't call us again if we
- // already have the signed-in account, and hence we shouldn't have an engine
- // here, but some tests on ChromeOS set the account without notifying, which
- // get us into an inconsistent state. Since calling TryStart() again in that
- // case isn't harmful, skip the DCHECK on ChromeOS for now.
DCHECK(!engine_);
-#endif
startup_controller_->TryStart(/*force_immediate=*/IsSetupInProgress());
}
for (auto* provider : invalidations_identity_providers_) {
@@ -380,9 +346,20 @@ void ProfileSyncService::AccountStateChanged() {
void ProfileSyncService::CredentialsChanged() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- syncer::SyncCredentials credentials = auth_manager_->GetCredentials();
+ // If the engine isn't allowed to start anymore due to the credentials change,
+ // then shut down. This happens when the user signs out on the web, i.e. we're
+ // in the "Sync paused" state.
+ if (!IsEngineAllowedToStart()) {
+ // This will notify observers if appropriate.
+ StopImpl(KEEP_DATA);
+ return;
+ }
- if (engine_) {
+ if (!engine_) {
+ startup_controller_->TryStart(/*force_immediate=*/true);
+ } else {
+ // If the engine already exists, just propagate the new credentials.
+ syncer::SyncCredentials credentials = auth_manager_->GetCredentials();
if (credentials.sync_token.empty()) {
engine_->InvalidateCredentials();
} else {
@@ -394,34 +371,12 @@ void ProfileSyncService::CredentialsChanged() {
}
bool ProfileSyncService::IsEngineAllowedToStart() const {
- int disable_reasons = GetDisableReasons();
- if (IsStandaloneTransportEnabled()) {
- // USER_CHOICE (i.e. the Sync feature toggle) and PLATFORM_OVERRIDE (i.e.
- // Android's "MasterSync" toggle) do not prevent starting up the Sync
- // transport.
- const int kDisableReasonMask =
- ~(DISABLE_REASON_USER_CHOICE | DISABLE_REASON_PLATFORM_OVERRIDE);
- disable_reasons &= kDisableReasonMask;
- }
- return disable_reasons == DISABLE_REASON_NONE;
-}
-
-bool ProfileSyncService::ShouldStartEngine(
- bool bypass_first_setup_check) const {
- if (!IsEngineAllowedToStart()) {
- return false;
- }
- // If standalone transport is enabled, we always start the engine as soon as
- // we can.
- if (IsStandaloneTransportEnabled()) {
- return true;
- }
- // Without standalone transport, we generally wait for first-time setup to be
- // complete before starting the engine (because if it isn't, we can't
- // configure the DataTypeManager anyway). Note that if a setup is currently in
- // progress (which requires the engine to be initialized), then
- // |bypass_first_setup_check| will be set to true.
- return bypass_first_setup_check || IsFirstSetupComplete();
+ // USER_CHOICE (i.e. the Sync feature toggle) and PLATFORM_OVERRIDE (i.e.
+ // Android's "MasterSync" toggle) do not prevent starting up the Sync
+ // transport.
+ const int kDisableReasonMask =
+ ~(DISABLE_REASON_USER_CHOICE | DISABLE_REASON_PLATFORM_OVERRIDE);
+ return (GetDisableReasons() & kDisableReasonMask) == DISABLE_REASON_NONE;
}
bool ProfileSyncService::IsEncryptedDatatypeEnabled() const {
@@ -476,7 +431,7 @@ void ProfileSyncService::OnDataTypeRequestsSyncStartup(syncer::ModelType type) {
// The major version has changed and a local syncable change was made.
// Reset the passphrase prompt state.
passphrase_prompt_triggered_by_version_ = false;
- sync_prefs_.SetPassphrasePrompted(false);
+ SetPassphrasePrompted(false);
NotifyObservers();
}
@@ -494,8 +449,7 @@ void ProfileSyncService::StartUpSlowEngineComponents() {
engine_ = sync_client_->GetSyncApiComponentFactory()->CreateSyncEngine(
debug_identifier_, sync_client_->GetInvalidationService(),
- sync_prefs_.AsWeakPtr(),
- sync_client_->GetModelTypeStoreService()->GetSyncDataPath());
+ sync_prefs_.AsWeakPtr());
// Clear any old errors the first time sync starts.
if (!IsFirstSetupComplete())
@@ -516,21 +470,7 @@ void ProfileSyncService::StartUpSlowEngineComponents() {
debug_identifier_,
base::BindRepeating(&syncer::SyncClient::CreateModelWorkerForGroup,
base::Unretained(sync_client_.get())));
- params.encryption_observer_proxies.push_back(
- crypto_.GetEncryptionObserverProxy());
-
- // Let datatypes install their own proxy encryption observers that receive
- // updates from the sync thread. Currently, this is necessary for pseudo-USS
- // PASSWORDS only.
- for (const std::pair<const syncer::ModelType,
- std::unique_ptr<DataTypeController>>&
- type_and_controller : data_type_controllers_) {
- std::unique_ptr<syncer::SyncEncryptionHandler::Observer> proxy_observer =
- type_and_controller.second->GetEncryptionObserverProxy();
- if (proxy_observer) {
- params.encryption_observer_proxies.push_back(std::move(proxy_observer));
- }
- }
+ params.encryption_observer_proxy = crypto_.GetEncryptionObserverProxy();
params.extensions_activity = sync_client_->GetExtensionsActivity();
params.event_handler = GetJsEventHandler();
@@ -558,6 +498,9 @@ void ProfileSyncService::StartUpSlowEngineComponents() {
sync_prefs_.GetEncryptionBootstrapToken();
params.restored_keystore_key_for_bootstrapping =
sync_prefs_.GetKeystoreEncryptionBootstrapToken();
+ params.cache_guid = sync_prefs_.GetCacheGuid();
+ params.birthday = sync_prefs_.GetBirthday();
+ params.bag_of_chips = sync_prefs_.GetBagOfChips();
params.engine_components_factory =
std::make_unique<EngineComponentsFactoryImpl>(
EngineSwitchesFromCommandLine());
@@ -595,8 +538,8 @@ void ProfileSyncService::StartUpSlowEngineComponents() {
void ProfileSyncService::Shutdown() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- ShutdownImpl(syncer::BROWSER_SHUTDOWN);
NotifyShutdown();
+ ShutdownImpl(syncer::BROWSER_SHUTDOWN);
// All observers must be gone now: All KeyedServices should have unregistered
// their observers already before, in their own Shutdown(), and all others
@@ -622,9 +565,8 @@ void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) {
// the data directory needs to be cleaned up here.
sync_thread_->task_runner()->PostTask(
FROM_HERE,
- base::BindOnce(
- &syncer::syncable::Directory::DeleteDirectoryFiles,
- sync_client_->GetModelTypeStoreService()->GetSyncDataPath()));
+ base::BindOnce(&syncer::syncable::Directory::DeleteDirectoryFiles,
+ sync_client_->GetSyncDataPath()));
}
return;
}
@@ -680,7 +622,7 @@ void ProfileSyncService::ShutdownImpl(syncer::ShutdownReason reason) {
expect_sync_configuration_aborted_ = false;
engine_initialized_ = false;
last_snapshot_ = syncer::SyncCycleSnapshot();
- auth_manager_->Clear();
+ auth_manager_->ConnectionClosed();
NotifyObservers();
@@ -718,7 +660,7 @@ int ProfileSyncService::GetDisableReasons() const {
// If Sync is disabled via command line flag, then ProfileSyncService
// shouldn't even be instantiated.
- DCHECK(IsSyncAllowedByFlag());
+ DCHECK(switches::IsSyncAllowedByFlag());
int result = DISABLE_REASON_NONE;
if (!user_settings_->IsSyncAllowedByPlatform()) {
@@ -739,6 +681,11 @@ int ProfileSyncService::GetDisableReasons() const {
if (unrecoverable_error_reason_ != ERROR_REASON_UNSET) {
result = result | DISABLE_REASON_UNRECOVERABLE_ERROR;
}
+ if (base::FeatureList::IsEnabled(switches::kStopSyncInPausedState)) {
+ if (auth_manager_->IsSyncPaused()) {
+ result = result | DISABLE_REASON_PAUSED;
+ }
+ }
return result;
}
@@ -752,14 +699,14 @@ syncer::SyncService::TransportState ProfileSyncService::GetTransportState()
return TransportState::DISABLED;
}
- // Typically, Sync won't start until the initial setup is at least in
- // progress. StartupController::TryStartImmediately bypasses the first setup
- // check though, so we first have to check whether the engine is initialized.
if (!engine_initialized_) {
switch (startup_controller_->GetState()) {
+ // TODO(crbug.com/935523): If the engine is allowed to start, then we
+ // should generally have kicked off the startup process already, so
+ // NOT_STARTED should be impossible. But we can temporarily be in this
+ // state between shutting down and starting up again (e.g. during the
+ // NotifyObservers() call in ShutdownImpl()).
case syncer::StartupController::State::NOT_STARTED:
- DCHECK(!engine_);
- return TransportState::WAITING_FOR_START_REQUEST;
case syncer::StartupController::State::STARTING_DEFERRED:
DCHECK(!engine_);
return TransportState::START_DEFERRED;
@@ -783,11 +730,6 @@ syncer::SyncService::TransportState ProfileSyncService::GetTransportState()
return TransportState::PENDING_DESIRED_CONFIGURATION;
}
- // Unless standalone transport is enabled, the DataTypeManager shouldn't get
- // configured (i.e. leave the STOPPED state) before the initial setup is
- // complete.
- DCHECK(IsStandaloneTransportEnabled() || IsFirstSetupComplete());
-
// Note that if a setup is started after the data types have been configured,
// then they'll stay configured even though CanConfigureDataTypes will be
// false.
@@ -913,6 +855,7 @@ void ProfileSyncService::OnEngineInitialized(
const std::string& bag_of_chips,
bool success) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!cache_guid.empty());
// TODO(treib): Based on some crash reports, it seems like the user could have
// signed out already at this point, so many of the steps below, including
@@ -962,8 +905,8 @@ void ProfileSyncService::OnEngineInitialized(
data_type_manager_ =
sync_client_->GetSyncApiComponentFactory()->CreateDataTypeManager(
- initial_types, debug_info_listener, &data_type_controllers_, this,
- engine_.get(), this);
+ initial_types, debug_info_listener, &data_type_controllers_,
+ user_settings_.get(), engine_.get(), this);
crypto_.SetSyncEngine(engine_.get());
@@ -991,11 +934,6 @@ void ProfileSyncService::OnEngineInitialized(
}
NotifyObservers();
-
- // Nobody will call us to start if no sign in is going to happen.
- if (IsLocalSyncEnabled()) {
- startup_controller_->TryStart(/*force_immediate=*/true);
- }
}
void ProfileSyncService::OnSyncCycleCompleted(
@@ -1019,14 +957,6 @@ void ProfileSyncService::OnSyncCycleCompleted(
sync_prefs_.SetBagOfChips(user_share->directory->bag_of_chips());
}
- if (IsDataTypeControllerRunning(syncer::SESSIONS) &&
- snapshot.model_neutral_state().get_updates_request_types.Has(
- syncer::SESSIONS) &&
- !syncer::HasSyncerError(snapshot.model_neutral_state())) {
- // Trigger garbage collection of old sessions now that we've downloaded
- // any new session data.
- sync_client_->GetSessionSyncService()->ScheduleGarbageCollection();
- }
DVLOG(2) << "Notifying observers sync cycle completed";
NotifySyncCycleCompleted();
}
@@ -1112,10 +1042,6 @@ void ProfileSyncService::OnActionableError(
case syncer::RESET_LOCAL_SYNC_DATA:
ShutdownImpl(syncer::DISABLE_SYNC);
startup_controller_->TryStart(IsSetupInProgress());
- UMA_HISTOGRAM_ENUMERATION(
- "Sync.ClearServerDataEvents",
- syncer::CLEAR_SERVER_DATA_RESET_LOCAL_DATA_RECEIVED,
- syncer::CLEAR_SERVER_DATA_MAX);
break;
case syncer::UNKNOWN_ACTION:
NOTREACHED();
@@ -1123,38 +1049,6 @@ void ProfileSyncService::OnActionableError(
NotifyObservers();
}
-void ProfileSyncService::ClearAndRestartSyncForPassphraseEncryption() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- engine_->ClearServerData(
- base::BindRepeating(&ProfileSyncService::OnClearServerDataDone,
- sync_enabled_weak_factory_.GetWeakPtr()));
-}
-
-void ProfileSyncService::OnClearServerDataDone() {
- DCHECK(sync_prefs_.GetPassphraseEncryptionTransitionInProgress());
- sync_prefs_.SetPassphraseEncryptionTransitionInProgress(false);
-
- // Call to ClearServerData generates new keystore key on the server. This
- // makes keystore bootstrap token invalid. Let's clear it from preferences.
- sync_prefs_.SetKeystoreEncryptionBootstrapToken(std::string());
-
- // Shutdown sync, delete the Directory, then restart, restoring the cached
- // nigori state.
- ShutdownImpl(syncer::DISABLE_SYNC);
- startup_controller_->TryStart(IsSetupInProgress());
- UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents",
- syncer::CLEAR_SERVER_DATA_SUCCEEDED,
- syncer::CLEAR_SERVER_DATA_MAX);
-}
-
-void ProfileSyncService::ClearServerDataForTest(const base::Closure& callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // Sync has a restriction that the engine must be in configuration mode
- // in order to run clear server data.
- engine_->StartConfiguration();
- engine_->ClearServerData(callback);
-}
-
void ProfileSyncService::OnConfigureDone(
const DataTypeManager::ConfigureResult& result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1191,12 +1085,6 @@ void ProfileSyncService::OnConfigureDone(
// Handle unrecoverable error.
if (result.status != DataTypeManager::OK) {
- if (result.was_catch_up_configure) {
- // Record catchup configuration failure.
- UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents",
- syncer::CLEAR_SERVER_DATA_CATCHUP_FAILED,
- syncer::CLEAR_SERVER_DATA_MAX);
- }
// Something catastrophic had happened. We should only have one
// error representing it.
syncer::SyncError error =
@@ -1219,7 +1107,8 @@ void ProfileSyncService::OnConfigureDone(
// We should never get in a state where we have no encrypted datatypes
// enabled, and yet we still think we require a passphrase for decryption.
- DCHECK(!IsPassphraseRequiredForDecryption() || IsEncryptedDatatypeEnabled());
+ DCHECK(!GetUserSettings()->IsPassphraseRequiredForDecryption() ||
+ IsEncryptedDatatypeEnabled());
// Notify listeners that configuration is done.
for (auto& observer : observers_)
@@ -1239,11 +1128,6 @@ void ProfileSyncService::OnConfigureDone(
return;
}
- if (result.was_catch_up_configure) {
- ClearAndRestartSyncForPassphraseEncryption();
- return;
- }
-
RecordMemoryUsageHistograms();
StartSyncingWithServer();
@@ -1274,7 +1158,7 @@ bool ProfileSyncService::QueryDetailedSyncStatus(
return false;
}
-const GoogleServiceAuthError& ProfileSyncService::GetAuthError() const {
+GoogleServiceAuthError ProfileSyncService::GetAuthError() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return auth_manager_->GetLastAuthError();
}
@@ -1286,7 +1170,6 @@ bool ProfileSyncService::CanConfigureDataTypes(
// easier to keep it like this. Changing this will likely require changes to
// the setup UI flow.
return data_type_manager_ &&
- (IsFirstSetupComplete() || IsStandaloneTransportEnabled()) &&
(bypass_setup_in_progress_check || !IsSetupInProgress());
}
@@ -1326,21 +1209,11 @@ bool ProfileSyncService::IsPassphraseRequired() const {
return user_settings_->IsPassphraseRequired();
}
-bool ProfileSyncService::IsPassphraseRequiredForDecryption() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // If there is an encrypted datatype enabled and we don't have the proper
- // passphrase, we must prompt the user for a passphrase. The only way for the
- // user to avoid entering their passphrase is to disable the encrypted types.
- return IsEncryptedDatatypeEnabled() && IsPassphraseRequired();
-}
-
base::Time ProfileSyncService::GetLastSyncedTime() const {
return sync_prefs_.GetLastSyncedTime();
}
-void ProfileSyncService::OnPreferredDataTypesPrefChange(
- bool sync_everything,
- syncer::ModelTypeSet preferred_types) {
+void ProfileSyncService::OnPreferredDataTypesPrefChange() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!engine_ && !HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR)) {
@@ -1409,11 +1282,6 @@ syncer::ModelTypeSet ProfileSyncService::GetActiveDataTypes() const {
return data_type_manager_->GetActiveDataTypes();
}
-bool ProfileSyncService::IsUsingSecondaryPassphrase() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return user_settings_->IsUsingSecondaryPassphrase();
-}
-
void ProfileSyncService::SyncAllowedByPlatformChanged(bool allowed) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1422,9 +1290,7 @@ void ProfileSyncService::SyncAllowedByPlatformChanged(bool allowed) {
// TODO(crbug.com/856179): Evaluate whether we can get away without a full
// restart (i.e. just reconfigure plus whatever cleanup is necessary). See
// also similar comment in OnSyncRequestedPrefChange().
- if (IsStandaloneTransportEnabled()) {
- startup_controller_->TryStart(/*force_immediate=*/false);
- }
+ startup_controller_->TryStart(/*force_immediate=*/false);
}
}
@@ -1433,13 +1299,13 @@ void ProfileSyncService::ConfigureDataTypeManager(
syncer::ConfigureContext configure_context;
configure_context.authenticated_account_id =
GetAuthenticatedAccountInfo().account_id;
- configure_context.cache_guid = sync_client_->GetDeviceInfoSyncService()
- ->GetLocalDeviceInfoProvider()
- ->GetLocalSyncCacheGUID();
+ configure_context.cache_guid = sync_prefs_.GetCacheGuid();
configure_context.storage_option = syncer::STORAGE_ON_DISK;
configure_context.reason = reason;
configure_context.configuration_start_time = base::Time::Now();
+ DCHECK(!configure_context.cache_guid.empty());
+
if (!migrator_) {
// We create the migrator at the same time.
migrator_ = std::make_unique<syncer::BackendMigrator>(
@@ -1451,8 +1317,7 @@ void ProfileSyncService::ConfigureDataTypeManager(
base::Unretained(this)));
// Override reason if no configuration has completed ever.
- if (is_first_time_sync_configure_ &&
- reason != syncer::CONFIGURE_REASON_CATCH_UP) {
+ if (is_first_time_sync_configure_) {
configure_context.reason = syncer::CONFIGURE_REASON_NEW_CLIENT;
}
}
@@ -1470,13 +1335,12 @@ void ProfileSyncService::ConfigureDataTypeManager(
syncer::ModelTypeSet types = GetPreferredDataTypes();
// In transport-only mode, only a subset of data types is supported.
if (use_transport_only_mode) {
- DCHECK(IsStandaloneTransportEnabled());
syncer::ModelTypeSet allowed_types = {syncer::USER_CONSENTS};
if (base::FeatureList::IsEnabled(
autofill::features::kAutofillEnableAccountWalletStorage) &&
base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) {
- if (!IsUsingSecondaryPassphrase() ||
+ if (!GetUserSettings()->IsUsingSecondaryPassphrase() ||
base::FeatureList::IsEnabled(
switches::
kSyncAllowWalletDataInTransportModeWithCustomPassphrase)) {
@@ -1662,17 +1526,17 @@ void ProfileSyncService::OnFirstSetupCompletePrefChange(
void ProfileSyncService::OnSyncRequestedPrefChange(bool is_sync_requested) {
if (is_sync_requested) {
- NotifyObservers();
-
// If the Sync engine was already initialized (probably running in transport
// mode), just reconfigure.
- if (IsStandaloneTransportEnabled() && engine_initialized_) {
+ if (engine_initialized_) {
ReconfigureDatatypeManager(/*bypass_setup_in_progress_check=*/false);
} else {
// Otherwise try to start up. Note that there might still be other disable
// reasons remaining, in which case this will effectively do nothing.
startup_controller_->TryStart(/*force_immediate=*/true);
}
+
+ NotifyObservers();
} else {
// This will notify the observers.
if (is_stopping_and_clearing_) {
@@ -1686,9 +1550,7 @@ void ProfileSyncService::OnSyncRequestedPrefChange(bool is_sync_requested) {
// restart (i.e. just reconfigure plus whatever cleanup is necessary).
// Especially in the CLEAR_DATA case, StopImpl does a lot of cleanup that
// might still be required.
- if (IsStandaloneTransportEnabled()) {
- startup_controller_->TryStart(/*force_immediate=*/false);
- }
+ startup_controller_->TryStart(/*force_immediate=*/false);
}
}
@@ -1889,7 +1751,7 @@ void ProfileSyncService::GetAllNodes(
}
}
-AccountInfo ProfileSyncService::GetAuthenticatedAccountInfo() const {
+CoreAccountInfo ProfileSyncService::GetAuthenticatedAccountInfo() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return auth_manager_->GetActiveAccountInfo().account_info;
}
@@ -1910,12 +1772,6 @@ base::WeakPtr<syncer::JsController> ProfileSyncService::GetJsController() {
return sync_js_controller_.AsWeakPtr();
}
-// static
-bool ProfileSyncService::IsSyncAllowedByFlag() {
- return !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableSync);
-}
-
void ProfileSyncService::StopAndClear() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -2032,6 +1888,14 @@ void ProfileSyncService::FlushDirectory() const {
engine_->FlushDirectory();
}
+bool ProfileSyncService::IsPassphrasePrompted() const {
+ return sync_prefs_.IsPassphrasePrompted();
+}
+
+void ProfileSyncService::SetPassphrasePrompted(bool prompted) {
+ sync_prefs_.SetPassphrasePrompted(prompted);
+}
+
scoped_refptr<base::SingleThreadTaskRunner>
ProfileSyncService::GetSyncThreadTaskRunnerForTest() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -2046,16 +1910,15 @@ ProfileSyncService::GetEncryptionObserverForTest() {
void ProfileSyncService::RemoveClientFromServer() const {
if (!engine_initialized_)
return;
- const std::string cache_guid = sync_client_->GetDeviceInfoSyncService()
- ->GetLocalDeviceInfoProvider()
- ->GetLocalSyncCacheGUID();
+ const std::string cache_guid = sync_prefs_.GetCacheGuid();
+ DCHECK(!cache_guid.empty());
std::string birthday;
syncer::UserShare* user_share = GetUserShare();
if (user_share && user_share->directory.get()) {
birthday = user_share->directory->store_birthday();
}
const std::string& access_token = auth_manager_->access_token();
- if (!access_token.empty() && !cache_guid.empty() && !birthday.empty()) {
+ if (!access_token.empty() && !birthday.empty()) {
sync_stopped_reporter_->ReportSyncStopped(access_token, cache_guid,
birthday);
}
diff --git a/chromium/components/browser_sync/profile_sync_service.h b/chromium/components/browser_sync/profile_sync_service.h
index 74818b55931..6c01395b954 100644
--- a/chromium/components/browser_sync/profile_sync_service.h
+++ b/chromium/components/browser_sync/profile_sync_service.h
@@ -20,7 +20,6 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
-#include "components/browser_sync/sync_user_settings_impl.h"
#include "components/invalidation/public/identity_provider.h"
#include "components/sync/base/experiments.h"
#include "components/sync/base/model_type.h"
@@ -35,6 +34,7 @@
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_crypto.h"
#include "components/sync/driver/sync_stopped_reporter.h"
+#include "components/sync/driver/sync_user_settings_impl.h"
#include "components/sync/engine/configure_reason.h"
#include "components/sync/engine/events/protocol_event_observer.h"
#include "components/sync/engine/net/network_time_update_callback.h"
@@ -42,7 +42,6 @@
#include "components/sync/engine/sync_engine.h"
#include "components/sync/engine/sync_engine_host.h"
#include "components/sync/js/sync_js_controller.h"
-#include "components/version_info/version_info.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_manager.h"
@@ -185,9 +184,9 @@ class ProfileSyncService : public syncer::SyncService,
int GetDisableReasons() const override;
TransportState GetTransportState() const override;
bool IsLocalSyncEnabled() const override;
- AccountInfo GetAuthenticatedAccountInfo() const override;
+ CoreAccountInfo GetAuthenticatedAccountInfo() const override;
bool IsAuthenticatedAccountPrimary() const override;
- const GoogleServiceAuthError& GetAuthError() const override;
+ GoogleServiceAuthError GetAuthError() const override;
std::unique_ptr<syncer::SyncSetupInProgressHandle> GetSetupInProgressHandle()
override;
bool IsSetupInProgress() const override;
@@ -204,8 +203,12 @@ class ProfileSyncService : public syncer::SyncService,
void AddObserver(syncer::SyncServiceObserver* observer) override;
void RemoveObserver(syncer::SyncServiceObserver* observer) override;
bool HasObserver(const syncer::SyncServiceObserver* observer) const override;
- bool IsPassphraseRequiredForDecryption() const override;
- bool IsUsingSecondaryPassphrase() const override;
+ void AddPreferenceProvider(
+ syncer::SyncTypePreferenceProvider* provider) override;
+ void RemovePreferenceProvider(
+ syncer::SyncTypePreferenceProvider* provider) override;
+ bool HasPreferenceProvider(
+ syncer::SyncTypePreferenceProvider* provider) const override;
syncer::UserShare* GetUserShare() const override;
syncer::SyncTokenStatus GetSyncTokenStatus() const override;
bool QueryDetailedSyncStatus(syncer::SyncStatus* result) const override;
@@ -227,16 +230,6 @@ class ProfileSyncService : public syncer::SyncService,
void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>&
callback) override;
- // Add a sync type preference provider. Each provider may only be added once.
- void AddPreferenceProvider(syncer::SyncTypePreferenceProvider* provider);
- // Remove a sync type preference provider. May only be called for providers
- // that have been added. Providers must not remove themselves while being
- // called back.
- void RemovePreferenceProvider(syncer::SyncTypePreferenceProvider* provider);
- // Check whether a given sync type preference provider has been added.
- bool HasPreferenceProvider(
- syncer::SyncTypePreferenceProvider* provider) const;
-
// SyncEngineHost implementation.
void OnEngineInitialized(
syncer::ModelTypeSet initial_types,
@@ -269,9 +262,10 @@ class ProfileSyncService : public syncer::SyncService,
const syncer::DataTypeManager::ConfigureResult& result) override;
void OnConfigureStart() override;
- // DataTypeEncryptionHandler implementation.
- bool IsPassphraseRequired() const override;
- syncer::ModelTypeSet GetEncryptedDataTypes() const override;
+ // TODO(crbug.com/884159): Remove these; they should be queried via
+ // SyncUserSettings instead.
+ bool IsPassphraseRequired() const;
+ syncer::ModelTypeSet GetEncryptedDataTypes() const;
// IdentityManager::Observer implementation.
void OnAccountsInCookieUpdated(
@@ -288,23 +282,10 @@ class ProfileSyncService : public syncer::SyncService,
bool HasCookieJarMismatch(
const std::vector<gaia::ListedAccount>& cookie_jar_accounts);
- // Reconfigures the data type manager with the latest enabled types.
- // Note: Does not initialize the engine if it is not already initialized.
- // If a Sync setup is currently in progress (i.e. a settings UI is open), then
- // the reconfiguration will only happen if |bypass_setup_in_progress_check| is
- // set to true.
- void ReconfigureDatatypeManager(bool bypass_setup_in_progress_check);
-
syncer::PassphraseRequiredReason passphrase_required_reason_for_test() const {
return crypto_.passphrase_required_reason();
}
- // Returns whether sync is allowed to run based on command-line switches.
- // Profile::IsSyncAllowed() is probably a better signal than this function.
- // This function can be called from any thread, and the implementation doesn't
- // assume it's running on the UI thread.
- static bool IsSyncAllowedByFlag();
-
// syncer::UnrecoverableErrorHandler implementation.
void OnUnrecoverableError(const base::Location& from_here,
const std::string& message) override;
@@ -327,9 +308,7 @@ class ProfileSyncService : public syncer::SyncService,
void OnSyncManagedPrefChange(bool is_sync_managed) override;
void OnFirstSetupCompletePrefChange(bool is_first_setup_complete) override;
void OnSyncRequestedPrefChange(bool is_sync_requested) override;
- void OnPreferredDataTypesPrefChange(
- bool sync_everything,
- syncer::ModelTypeSet preferred_types) override;
+ void OnPreferredDataTypesPrefChange() override;
// Returns true if the syncer is waiting for new datatypes to be encrypted.
bool encryption_pending() const;
@@ -353,6 +332,9 @@ class ProfileSyncService : public syncer::SyncService,
// killed in the near future.
void FlushDirectory() const;
+ bool IsPassphrasePrompted() const;
+ void SetPassphrasePrompted(bool prompted);
+
void SyncAllowedByPlatformChanged(bool allowed);
// Sometimes we need to wait for tasks on the sync thread in tests.
@@ -362,10 +344,6 @@ class ProfileSyncService : public syncer::SyncService,
// Some tests rely on injecting calls to the encryption observer.
syncer::SyncEncryptionHandler::Observer* GetEncryptionObserverForTest();
- // Calls sync engine to send ClearServerDataMessage to server. This is used
- // to start accounts with a clean slate when performing end to end testing.
- void ClearServerDataForTest(const base::Closure& callback);
-
syncer::SyncClient* GetSyncClientForTest();
private:
@@ -395,9 +373,6 @@ class ProfileSyncService : public syncer::SyncService,
bool IsEngineAllowedToStart() const;
- // Callback for StartupController.
- bool ShouldStartEngine(bool bypass_first_setup_check) const;
-
enum UnrecoverableErrorReason {
ERROR_REASON_UNSET,
ERROR_REASON_SYNCER,
@@ -410,6 +385,13 @@ class ProfileSyncService : public syncer::SyncService,
friend class TestProfileSyncService;
+ // Reconfigures the data type manager with the latest enabled types.
+ // Note: Does not initialize the engine if it is not already initialized.
+ // If a Sync setup is currently in progress (i.e. a settings UI is open), then
+ // the reconfiguration will only happen if |bypass_setup_in_progress_check| is
+ // set to true.
+ void ReconfigureDatatypeManager(bool bypass_setup_in_progress_check);
+
// Helper to install and configure a data type manager.
void ConfigureDataTypeManager(syncer::ConfigureReason reason);
@@ -474,22 +456,6 @@ class ProfileSyncService : public syncer::SyncService,
// Estimates and records memory usage histograms per type.
void RecordMemoryUsageHistograms();
- // After user switches to custom passphrase encryption a set of steps needs to
- // be performed:
- //
- // - Download all latest updates from server (catch up configure).
- // - Clear user data on server.
- // - Clear directory so that data is merged from model types and encrypted.
- //
- // SyncServiceCrypto::BeginConfigureCatchUpBeforeClear() and the following two
- // functions perform these steps.
-
- // Calls sync engine to send ClearServerDataMessage to server.
- void ClearAndRestartSyncForPassphraseEncryption();
-
- // Restarts sync clearing directory in the process.
- void OnClearServerDataDone();
-
// True if setup has been completed at least once and is not in progress.
bool CanConfigureDataTypes(bool bypass_setup_in_progress_check) const;
@@ -510,7 +476,7 @@ class ProfileSyncService : public syncer::SyncService,
// email address and sign-out upon error.
identity::IdentityManager* const identity_manager_;
- std::unique_ptr<SyncUserSettingsImpl> user_settings_;
+ std::unique_ptr<syncer::SyncUserSettingsImpl> user_settings_;
// Handles tracking of the authenticated account and acquiring access tokens.
// Only null after Shutdown().
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 1d047f82579..0944b52030a 100644
--- a/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -22,6 +22,7 @@
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/bind_test_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -42,7 +43,9 @@
#include "components/sync/driver/data_type_controller.h"
#include "components/sync/driver/data_type_manager_impl.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/engine/data_type_debug_info_listener.h"
+#include "components/sync/engine/sequenced_model_worker.h"
#include "components/sync/protocol/autofill_specifics.pb.h"
#include "components/sync/syncable/mutable_entry.h"
#include "components/sync/syncable/read_node.h"
@@ -82,11 +85,12 @@ using syncer::syncable::UNITTEST;
using syncer::syncable::WriterTag;
using syncer::syncable::WriteTransaction;
using testing::_;
+using testing::ByMove;
using testing::DoAll;
using testing::ElementsAre;
using testing::Not;
-using testing::SetArgPointee;
using testing::Return;
+using testing::SetArgPointee;
namespace browser_sync {
@@ -140,6 +144,11 @@ class AutofillTableMock : public AutofillTable {
MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&)); // NOLINT
MOCK_METHOD1(AddAutofillProfile, bool(const AutofillProfile&)); // NOLINT
MOCK_METHOD1(RemoveAutofillProfile, bool(const std::string&)); // NOLINT
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ MOCK_CONST_METHOD1(
+ GetServerProfiles,
+ bool(std::vector<std::unique_ptr<AutofillProfile>>*)); // NOLINT
};
MATCHER_P(MatchProfiles, profile, "") {
@@ -179,6 +188,7 @@ class FakeAutofillBackend : public autofill::AutofillWebDataBackend {
void RemoveObserver(
autofill::AutofillWebDataServiceObserverOnDBSequence* observer) override {
}
+ void CommitChanges() override {}
void RemoveExpiredFormElements() override {}
void NotifyOfAutofillProfileChanged(
@@ -328,11 +338,9 @@ class WebDataServiceFake : public AutofillWebDataService {
DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake);
};
-ACTION_P2(ReturnNewDataTypeManagerWithDebugListener,
- sync_client,
- debug_listener) {
- return std::make_unique<syncer::DataTypeManagerImpl>(
- sync_client, arg0, debug_listener, arg2, arg3, arg4, arg5);
+ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
+ return std::make_unique<syncer::DataTypeManagerImpl>(arg0, debug_listener,
+ arg2, arg3, arg4, arg5);
}
class MockPersonalDataManager : public PersonalDataManager {
@@ -371,8 +379,6 @@ class ProfileSyncServiceAutofillTest
profile_sync_service_bundle()->pref_service()->registry());
data_type_thread()->Start();
- profile_sync_service_bundle()->set_db_thread(
- data_type_thread()->task_runner());
web_database_ = std::make_unique<WebDatabaseFake>(&autofill_table_);
web_data_wrapper_ = std::make_unique<MockWebDataServiceWrapper>(
@@ -396,20 +402,9 @@ class ProfileSyncServiceAutofillTest
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
web_data_service_->StartSyncableService();
-
- ProfileSyncServiceBundle::SyncClientBuilder builder(
- profile_sync_service_bundle());
- builder.SetPersonalDataManager(personal_data_manager_.get());
- builder.SetSyncableServiceCallback(base::BindRepeating(
- &ProfileSyncServiceAutofillTest::GetSyncableServiceForType,
- base::Unretained(this)));
- builder.set_activate_model_creation();
- sync_client_owned_ = builder.Build();
- sync_client_ = sync_client_owned_.get();
}
~ProfileSyncServiceAutofillTest() override {
@@ -436,22 +431,37 @@ class ProfileSyncServiceAutofillTest
profile_sync_service_bundle()
->identity_test_env()
->MakePrimaryAccountAvailable("test_user@gmail.com");
- CreateSyncService(std::move(sync_client_owned_), std::move(callback));
-
- EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
- CreateCommonDataTypeControllers(_, _))
- .WillOnce(testing::InvokeWithoutArgs([=]() {
- syncer::DataTypeController::TypeVector controllers;
- controllers.push_back(
- std::make_unique<AutofillProfileDataTypeController>(
- data_type_thread()->task_runner(), base::DoNothing(),
- sync_service(), sync_client_, web_data_service_));
- return controllers;
+
+ std::unique_ptr<syncer::SyncClientMock> sync_client =
+ profile_sync_service_bundle()->CreateSyncClientMock();
+ syncer::SyncClientMock* sync_client_copy = sync_client.get();
+ CreateSyncService(std::move(sync_client), std::move(callback));
+
+ syncer::DataTypeController::TypeVector controllers;
+ controllers.push_back(std::make_unique<AutofillProfileDataTypeController>(
+ data_type_thread()->task_runner(), /*dump_stack=*/base::DoNothing(),
+ sync_service(), sync_client_copy,
+ base::BindLambdaForTesting([&]() -> autofill::PersonalDataManager* {
+ return personal_data_manager_.get();
+ }),
+ web_data_service_));
+
+ ON_CALL(*sync_client_copy, GetSyncableServiceForType(AUTOFILL_PROFILE))
+ .WillByDefault(testing::Invoke([=](syncer::ModelType) {
+ return AutofillProfileSyncableService::FromWebDataService(
+ web_data_service_.get())
+ ->AsWeakPtr();
}));
- EXPECT_CALL(*profile_sync_service_bundle()->component_factory(),
- CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewDataTypeManagerWithDebugListener(
- sync_client_,
+ ON_CALL(*sync_client_copy, CreateDataTypeControllers(_))
+ .WillByDefault(Return(ByMove(std::move(controllers))));
+ ON_CALL(*sync_client_copy, CreateModelWorkerForGroup(syncer::GROUP_DB))
+ .WillByDefault(
+ Return(base::MakeRefCounted<syncer::SequencedModelWorker>(
+ data_type_thread()->task_runner(), syncer::GROUP_DB)));
+
+ ON_CALL(*profile_sync_service_bundle()->component_factory(),
+ CreateDataTypeManager(_, _, _, _, _, _))
+ .WillByDefault(ReturnNewDataTypeManagerWithDebugListener(
syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));
EXPECT_CALL(personal_data_manager(), IsDataLoaded())
@@ -529,14 +539,6 @@ class ProfileSyncServiceAutofillTest
private:
friend class AddAutofillProfileHelper;
- base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
- syncer::ModelType type) {
- DCHECK(type == AUTOFILL_PROFILE);
- return AutofillProfileSyncableService::FromWebDataService(
- web_data_service_.get())
- ->AsWeakPtr();
- }
-
AutofillTableMock autofill_table_;
std::unique_ptr<WebDatabaseFake> web_database_;
std::unique_ptr<MockWebDataServiceWrapper> web_data_wrapper_;
@@ -544,11 +546,6 @@ class ProfileSyncServiceAutofillTest
std::unique_ptr<MockPersonalDataManager> personal_data_manager_;
syncer::DataTypeAssociationStats association_stats_;
base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;
- // |sync_client_owned_| keeps the created client until it is passed to the
- // created ProfileSyncService. |sync_client_| just keeps a weak reference to
- // the client the whole time.
- std::unique_ptr<syncer::FakeSyncClient> sync_client_owned_;
- syncer::FakeSyncClient* sync_client_;
DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest);
};
@@ -959,6 +956,10 @@ TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
"Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
"Orlando", "FL", "32801", "US", "19482937549");
+ // TODO(crbug.com/904390): Remove when the investigation is over. This call is
+ // needed in the AutofillProfileChanged() callback.
+ EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));
+
AutofillProfileChange change(AutofillProfileChange::ADD, added_profile.guid(),
&added_profile);
web_data_service()->OnAutofillProfileChanged(change);
diff --git a/chromium/components/browser_sync/profile_sync_service_bookmark_unittest.cc b/chromium/components/browser_sync/profile_sync_service_bookmark_unittest.cc
index 5076b1b5b11..1cf5fbffee9 100644
--- a/chromium/components/browser_sync/profile_sync_service_bookmark_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_bookmark_unittest.cc
@@ -18,6 +18,7 @@
#include "base/containers/queue.h"
#include "base/containers/stack.h"
#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
@@ -37,8 +38,6 @@
#include "components/bookmarks/managed/managed_bookmark_service.h"
#include "components/bookmarks/test/bookmark_test_helpers.h"
#include "components/bookmarks/test/test_bookmark_client.h"
-#include "components/browser_sync/profile_sync_test_util.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/engine/engine_util.h"
#include "components/sync/model/data_type_error_handler.h"
#include "components/sync/model/data_type_error_handler_mock.h"
@@ -56,6 +55,7 @@
#include "components/sync/syncable/write_transaction.h"
#include "components/sync_bookmarks/bookmark_change_processor.h"
#include "components/sync_bookmarks/bookmark_model_associator.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -87,7 +87,7 @@ void MakeServerUpdate(syncer::WriteTransaction* trans,
syncer::syncable::ChangeEntryIDAndUpdateChildren(
trans->GetWrappedWriteTrans(), node->GetMutableEntryForTest(),
syncer::syncable::Id::CreateFromServerId(
- base::Int64ToString(node->GetId())));
+ base::NumberToString(node->GetId())));
node->GetMutableEntryForTest()->PutBaseVersion(10);
node->GetMutableEntryForTest()->PutIsUnappliedUpdate(true);
}
@@ -355,18 +355,12 @@ class ProfileSyncServiceBookmarkTest : public testing::Test {
ProfileSyncServiceBookmarkTest()
: managed_bookmark_service_(new bookmarks::ManagedBookmarkService(
- profile_sync_service_bundle_.pref_service(),
+ &pref_service_,
base::Bind(ReturnEmptyString))),
local_merge_result_(syncer::BOOKMARKS),
syncer_merge_result_(syncer::BOOKMARKS) {
EXPECT_TRUE(data_dir_.CreateUniqueTempDir());
- ProfileSyncServiceBundle::SyncClientBuilder builder(
- &profile_sync_service_bundle_);
- builder.SetBookmarkModelCallback(base::Bind(
- &ProfileSyncServiceBookmarkTest::model, base::Unretained(this)));
- sync_client_ = builder.Build();
- bookmarks::RegisterProfilePrefs(
- profile_sync_service_bundle_.pref_service()->registry());
+ bookmarks::RegisterProfilePrefs(pref_service_.registry());
}
~ProfileSyncServiceBookmarkTest() override {
@@ -454,8 +448,7 @@ class ProfileSyncServiceBookmarkTest : public testing::Test {
false);
}
- model->Load(profile_sync_service_bundle_.pref_service(), data_path,
- base::ThreadTaskRunnerHandle::Get(),
+ model->Load(&pref_service_, data_path, base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
bookmarks::test::WaitForBookmarkModelToLoad(model.get());
return model;
@@ -548,7 +541,8 @@ class ProfileSyncServiceBookmarkTest : public testing::Test {
// Set up model associator.
model_associator_ = std::make_unique<BookmarkModelAssociator>(
- model_.get(), sync_client_.get(), test_user_share_.user_share(),
+ model_.get(), /*bookmark_undo_service=*/nullptr,
+ /*favicon_service=*/nullptr, test_user_share_.user_share(),
std::make_unique<syncer::DataTypeErrorHandlerMock>(),
kExpectMobileBookmarks);
@@ -795,7 +789,7 @@ class ProfileSyncServiceBookmarkTest : public testing::Test {
std::make_unique<syncer::DataTypeErrorHandlerMock>();
mock_error_handler_ = error_handler.get();
change_processor_ = std::make_unique<BookmarkChangeProcessor>(
- sync_client_.get(), model_associator_.get(), std::move(error_handler));
+ model_associator_.get(), std::move(error_handler));
}
syncer::DataTypeErrorHandlerMock* mock_error_handler() {
@@ -815,9 +809,7 @@ class ProfileSyncServiceBookmarkTest : public testing::Test {
private:
base::TestMessageLoop message_loop_;
base::ScopedTempDir data_dir_;
- ProfileSyncServiceBundle profile_sync_service_bundle_;
-
- std::unique_ptr<syncer::FakeSyncClient> sync_client_;
+ sync_preferences::TestingPrefServiceSyncable pref_service_;
std::unique_ptr<BookmarkModel> model_;
syncer::TestUserShare test_user_share_;
std::unique_ptr<BookmarkChangeProcessor> change_processor_;
@@ -1440,7 +1432,7 @@ TEST_F(ProfileSyncServiceBookmarkTest, RepeatedMiddleInsertion) {
// position.
for (int i = 0; i < kTimesToInsert; ++i) {
base::string16 title =
- base::ASCIIToUTF16("Pre-insertion ") + base::IntToString16(i);
+ base::ASCIIToUTF16("Pre-insertion ") + base::NumberToString16(i);
model()->AddFolder(model()->other_node(), 1, title);
count++;
}
@@ -1449,7 +1441,7 @@ TEST_F(ProfileSyncServiceBookmarkTest, RepeatedMiddleInsertion) {
// second-to-last position.
for (int i = 0; i < kTimesToInsert; ++i) {
base::string16 title =
- base::ASCIIToUTF16("Post-insertion ") + base::IntToString16(i);
+ base::ASCIIToUTF16("Post-insertion ") + base::NumberToString16(i);
model()->AddFolder(model()->other_node(), count - 1, title);
count++;
}
diff --git a/chromium/components/browser_sync/profile_sync_service_mock.cc b/chromium/components/browser_sync/profile_sync_service_mock.cc
index 6e94fecb7a8..c0692f365c0 100644
--- a/chromium/components/browser_sync/profile_sync_service_mock.cc
+++ b/chromium/components/browser_sync/profile_sync_service_mock.cc
@@ -15,7 +15,7 @@ ProfileSyncServiceMock::ProfileSyncServiceMock(InitParams init_params)
ProfileSyncServiceMock::~ProfileSyncServiceMock() {}
-SyncUserSettingsMock* ProfileSyncServiceMock::GetUserSettingsMock() {
+syncer::SyncUserSettingsMock* ProfileSyncServiceMock::GetUserSettingsMock() {
return &user_settings_;
}
@@ -34,22 +34,9 @@ bool ProfileSyncServiceMock::IsAuthenticatedAccountPrimary() const {
syncer::ModelTypeSet ProfileSyncServiceMock::GetPreferredDataTypes() const {
return syncer::SyncPrefs::ResolvePrefGroups(
- /*registered_types=*/syncer::ModelTypeSet::All(),
user_settings_.GetChosenDataTypes());
}
-bool ProfileSyncServiceMock::IsPassphraseRequiredForDecryption() const {
- return user_settings_.IsPassphraseRequiredForDecryption();
-}
-
-bool ProfileSyncServiceMock::IsUsingSecondaryPassphrase() const {
- return user_settings_.IsUsingSecondaryPassphrase();
-}
-
-bool ProfileSyncServiceMock::IsPassphraseRequired() const {
- return user_settings_.IsPassphraseRequired();
-}
-
std::unique_ptr<syncer::SyncSetupInProgressHandle>
ProfileSyncServiceMock::GetSetupInProgressHandleConcrete() {
return browser_sync::ProfileSyncService::GetSetupInProgressHandle();
diff --git a/chromium/components/browser_sync/profile_sync_service_mock.h b/chromium/components/browser_sync/profile_sync_service_mock.h
index 1f292beda89..55dcbcd7fb3 100644
--- a/chromium/components/browser_sync/profile_sync_service_mock.h
+++ b/chromium/components/browser_sync/profile_sync_service_mock.h
@@ -10,8 +10,8 @@
#include "base/memory/weak_ptr.h"
#include "components/browser_sync/profile_sync_service.h"
-#include "components/browser_sync/sync_user_settings_mock.h"
#include "components/sync/base/model_type.h"
+#include "components/sync/driver/sync_user_settings_mock.h"
#include "components/sync/protocol/sync_protocol_error.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -23,7 +23,7 @@ class ProfileSyncServiceMock : public ProfileSyncService {
explicit ProfileSyncServiceMock(InitParams init_params);
~ProfileSyncServiceMock() override;
- SyncUserSettingsMock* GetUserSettingsMock();
+ syncer::SyncUserSettingsMock* GetUserSettingsMock();
// SyncService overrides.
syncer::SyncUserSettings* GetUserSettings() override;
@@ -34,7 +34,7 @@ class ProfileSyncServiceMock : public ProfileSyncService {
// return true by default, as a workaround for tests not setting up an
// authenticated account and IsSyncFeatureEnabled() therefore returning false.
bool IsAuthenticatedAccountPrimary() const override;
- MOCK_CONST_METHOD0(GetAuthError, const GoogleServiceAuthError&());
+ MOCK_CONST_METHOD0(GetAuthError, GoogleServiceAuthError());
MOCK_METHOD0(GetSetupInProgressHandle,
std::unique_ptr<syncer::SyncSetupInProgressHandle>());
@@ -49,9 +49,6 @@ class ProfileSyncServiceMock : public ProfileSyncService {
MOCK_METHOD1(AddObserver, void(syncer::SyncServiceObserver*));
MOCK_METHOD1(RemoveObserver, void(syncer::SyncServiceObserver*));
- bool IsPassphraseRequiredForDecryption() const override;
- bool IsUsingSecondaryPassphrase() const override;
-
MOCK_CONST_METHOD0(GetUserShare, syncer::UserShare*());
MOCK_CONST_METHOD1(QueryDetailedSyncStatus,
@@ -80,9 +77,6 @@ class ProfileSyncServiceMock : public ProfileSyncService {
void(const syncer::DataTypeManager::ConfigureResult&));
MOCK_METHOD0(OnConfigureStart, void());
- // DataTypeEncryptionHandler overrides.
- bool IsPassphraseRequired() const override;
-
// syncer::UnrecoverableErrorHandler overrides.
MOCK_METHOD2(OnUnrecoverableError,
void(const base::Location& location,
@@ -100,7 +94,7 @@ class ProfileSyncServiceMock : public ProfileSyncService {
GetSetupInProgressHandleConcrete();
private:
- testing::NiceMock<SyncUserSettingsMock> user_settings_;
+ testing::NiceMock<syncer::SyncUserSettingsMock> user_settings_;
};
} // namespace browser_sync
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 e5043a0d9ba..14d5e399fb0 100644
--- a/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_startup_unittest.cc
@@ -4,6 +4,7 @@
#include "components/browser_sync/profile_sync_service.h"
+#include "base/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "components/browser_sync/profile_sync_test_util.h"
@@ -12,6 +13,7 @@
#include "components/sync/driver/data_type_manager_mock.h"
#include "components/sync/driver/fake_data_type_controller.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/engine/fake_sync_engine.h"
#include "components/sync/engine/mock_sync_engine.h"
@@ -76,24 +78,20 @@ class ProfileSyncServiceStartupTest : public testing::Test {
void CreateSyncService(ProfileSyncService::StartBehavior start_behavior,
syncer::ModelTypeSet registered_types =
syncer::ModelTypeSet(syncer::BOOKMARKS)) {
- ProfileSyncServiceBundle::SyncClientBuilder builder(
- &profile_sync_service_bundle_);
- ProfileSyncService::InitParams init_params =
- profile_sync_service_bundle_.CreateBasicInitParams(start_behavior,
- builder.Build());
-
- ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _))
- .WillByDefault(InvokeWithoutArgs([=]() {
- syncer::DataTypeController::TypeVector controllers;
- for (syncer::ModelType type : registered_types) {
- controllers.push_back(
- std::make_unique<syncer::FakeDataTypeController>(type));
- }
- return controllers;
- }));
-
- sync_service_ =
- std::make_unique<ProfileSyncService>(std::move(init_params));
+ syncer::DataTypeController::TypeVector controllers;
+ for (syncer::ModelType type : registered_types) {
+ controllers.push_back(
+ std::make_unique<syncer::FakeDataTypeController>(type));
+ }
+
+ std::unique_ptr<syncer::SyncClientMock> sync_client =
+ profile_sync_service_bundle_.CreateSyncClientMock();
+ ON_CALL(*sync_client, CreateDataTypeControllers(_))
+ .WillByDefault(Return(ByMove(std::move(controllers))));
+
+ sync_service_ = std::make_unique<ProfileSyncService>(
+ profile_sync_service_bundle_.CreateBasicInitParams(
+ start_behavior, std::move(sync_client)));
}
void SimulateTestUserSignin() {
@@ -122,7 +120,7 @@ class ProfileSyncServiceStartupTest : public testing::Test {
FakeSyncEngine* SetUpFakeSyncEngine() {
auto sync_engine = std::make_unique<FakeSyncEngine>();
FakeSyncEngine* sync_engine_raw = sync_engine.get();
- ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ ON_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillByDefault(Return(ByMove(std::move(sync_engine))));
return sync_engine_raw;
}
@@ -130,7 +128,7 @@ class ProfileSyncServiceStartupTest : public testing::Test {
MockSyncEngine* SetUpMockSyncEngine() {
auto sync_engine = std::make_unique<NiceMock<MockSyncEngine>>();
MockSyncEngine* sync_engine_raw = sync_engine.get();
- ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ ON_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillByDefault(Return(ByMove(std::move(sync_engine))));
return sync_engine_raw;
}
@@ -158,110 +156,10 @@ class ProfileSyncServiceStartupTest : public testing::Test {
std::unique_ptr<ProfileSyncService> sync_service_;
};
-class ProfileSyncServiceWithStandaloneTransportStartupTest
- : public ProfileSyncServiceStartupTest {
- protected:
- ProfileSyncServiceWithStandaloneTransportStartupTest() {
- feature_list_.InitAndEnableFeature(switches::kSyncStandaloneTransport);
- }
-
- ~ProfileSyncServiceWithStandaloneTransportStartupTest() override {}
-
- private:
- base::test::ScopedFeatureList feature_list_;
-};
-
-class ProfileSyncServiceWithoutStandaloneTransportStartupTest
- : public ProfileSyncServiceStartupTest {
- protected:
- ProfileSyncServiceWithoutStandaloneTransportStartupTest() {
- feature_list_.InitAndDisableFeature(switches::kSyncStandaloneTransport);
- }
-
- ~ProfileSyncServiceWithoutStandaloneTransportStartupTest() override {}
-
- private:
- base::test::ScopedFeatureList feature_list_;
-};
-
// ChromeOS does not support sign-in after startup (in particular,
// IdentityManager::Observer::OnPrimaryAccountSet never gets called).
#if !defined(OS_CHROMEOS)
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest,
- StartFirstTime) {
- // We've never completed startup.
- ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
-
- CreateSyncService(ProfileSyncService::MANUAL_START);
- SetUpFakeSyncEngine();
- DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
- EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::STOPPED));
-
- // Should not actually start, rather just clean things up and wait
- // to be enabled.
- sync_service()->Initialize();
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
- sync_service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- sync_service()->GetTransportState());
-
- // Preferences should be back to defaults.
- EXPECT_EQ(base::Time(), sync_prefs()->GetLastSyncedTime());
- EXPECT_FALSE(sync_prefs()->IsFirstSetupComplete());
-
- // This tells the ProfileSyncService that setup is now in progress, which
- // causes it to try starting up the engine. We're not signed in yet though, so
- // that won't work.
- auto sync_blocker = sync_service()->GetSetupInProgressHandle();
- EXPECT_FALSE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
- sync_service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- sync_service()->GetTransportState());
-
- // Simulate successful signin. This will cause ProfileSyncService to start,
- // since all conditions are now fulfilled.
- SimulateTestUserSignin();
-
- // Now we're signed in, so the engine can start. There's already a setup in
- // progress, so we don't go into the WAITING_FOR_START_REQUEST state. Engine
- // initialization is immediate in this test, so we also bypass the
- // INITIALIZING state.
- EXPECT_TRUE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- sync_service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
- sync_service()->GetTransportState());
-
- // Simulate the UI telling sync it has finished setting up. Note that this is
- // a two-step process: Releasing the SetupInProgressHandle, and marking first
- // setup complete.
- sync_blocker.reset();
- // Now setup isn't in progress anymore, but Sync is still waiting to be told
- // that the initial setup was completed.
- ASSERT_FALSE(sync_service()->IsSetupInProgress());
- EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
- sync_service()->GetTransportState());
-
- // Marking first setup complete will let ProfileSyncService configure the
- // DataTypeManager.
- EXPECT_CALL(*data_type_manager, Configure(_, _));
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURED));
- sync_service()->GetUserSettings()->SetFirstSetupComplete();
-
- // This should have fully enabled sync.
- EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
- sync_service()->GetTransportState());
- EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
-
- EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StartFirstTime) {
+TEST_F(ProfileSyncServiceStartupTest, StartFirstTime) {
// We've never completed startup.
ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
@@ -296,10 +194,8 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StartFirstTime) {
SimulateTestUserSignin();
- // Now we're signed in, so the engine can start. There's already a setup in
- // progress, so we don't go into the WAITING_FOR_START_REQUEST state. Engine
- // initialization is immediate in this test, so we also bypass the
- // INITIALIZING state.
+ // Now we're signed in, so the engine can start. Engine initialization is
+ // immediate in this test, so we bypass the INITIALIZING state.
EXPECT_TRUE(sync_service()->IsEngineInitialized());
EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
sync_service()->GetDisableReasons());
@@ -465,26 +361,7 @@ TEST_F(ProfileSyncServiceStartupTest, StartNormal) {
EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
}
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, StopSync) {
- sync_prefs()->SetFirstSetupComplete();
- CreateSyncService(ProfileSyncService::MANUAL_START);
- SimulateTestUserSignin();
- SetUpFakeSyncEngine();
- DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURED));
- ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
-
- sync_service()->Initialize();
-
- EXPECT_CALL(*data_type_manager, Stop(syncer::STOP_SYNC));
- sync_service()->GetUserSettings()->SetSyncRequested(false);
-
- EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StopSync) {
+TEST_F(ProfileSyncServiceStartupTest, StopSync) {
sync_prefs()->SetFirstSetupComplete();
CreateSyncService(ProfileSyncService::MANUAL_START);
SimulateTestUserSignin();
@@ -509,26 +386,7 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StopSync) {
EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, DisableSync) {
- sync_prefs()->SetFirstSetupComplete();
- CreateSyncService(ProfileSyncService::MANUAL_START);
- SimulateTestUserSignin();
- SetUpFakeSyncEngine();
- DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURED));
- ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
-
- sync_service()->Initialize();
-
- EXPECT_CALL(*data_type_manager, Stop(syncer::DISABLE_SYNC));
- sync_service()->StopAndClear();
-
- EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, DisableSync) {
+TEST_F(ProfileSyncServiceStartupTest, DisableSync) {
sync_prefs()->SetFirstSetupComplete();
CreateSyncService(ProfileSyncService::MANUAL_START);
SimulateTestUserSignin();
@@ -558,8 +416,7 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, DisableSync) {
TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) {
// Clear the datatype preference fields (simulating bug 154940).
pref_service()->ClearPref(syncer::prefs::kSyncKeepEverythingSynced);
- syncer::ModelTypeSet user_types = syncer::UserTypes();
- for (syncer::ModelType type : user_types) {
+ for (syncer::ModelType type : syncer::UserSelectableTypes()) {
pref_service()->ClearPref(syncer::SyncPrefs::GetPrefNameForDataType(type));
}
@@ -610,7 +467,7 @@ TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
// Disable sync through policy.
sync_prefs()->SetManagedForTest(true);
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)).Times(0);
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _)).Times(0);
EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
.Times(0);
sync_service()->Initialize();
@@ -618,58 +475,7 @@ TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
sync_service()->GetDisableReasons());
}
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, SwitchManaged) {
- sync_prefs()->SetFirstSetupComplete();
- CreateSyncService(ProfileSyncService::MANUAL_START);
- SimulateTestUserSignin();
- SetUpFakeSyncEngine();
- DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
- EXPECT_CALL(*data_type_manager, Configure(_, _));
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURED));
- ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
- sync_service()->Initialize();
- EXPECT_TRUE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- sync_service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
- sync_service()->GetTransportState());
- EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
-
- // The service should stop when switching to managed mode.
- Mock::VerifyAndClearExpectations(data_type_manager);
- EXPECT_CALL(*data_type_manager, state())
- .WillOnce(Return(DataTypeManager::CONFIGURED));
- EXPECT_CALL(*data_type_manager, Stop(syncer::DISABLE_SYNC));
- sync_prefs()->SetManagedForTest(true);
- ASSERT_EQ(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
- sync_service()->GetDisableReasons());
- EXPECT_FALSE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- sync_service()->GetTransportState());
- EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
- // Note that PSS no longer references |data_type_manager| after stopping.
-
- // When switching back to unmanaged, the state should change but sync should
- // not start automatically because IsFirstSetupComplete() will be false and
- // no setup is in progress.
- // A new DataTypeManager should not be created.
- Mock::VerifyAndClearExpectations(data_type_manager);
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .Times(0);
- sync_prefs()->SetManagedForTest(false);
- ASSERT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- sync_service()->GetDisableReasons());
- EXPECT_FALSE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST,
- sync_service()->GetTransportState());
- EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
- EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, SwitchManaged) {
+TEST_F(ProfileSyncServiceStartupTest, SwitchManaged) {
sync_prefs()->SetFirstSetupComplete();
CreateSyncService(ProfileSyncService::MANUAL_START);
SimulateTestUserSignin();
@@ -770,94 +576,7 @@ TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) {
// ChromeOS does not support sign-in after startup (in particular,
// IdentityManager::Observer::OnPrimaryAccountSet never gets called).
#if !defined(OS_CHROMEOS)
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest,
- FullStartupSequenceFirstTime) {
- // We've never completed startup.
- ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
-
- MockSyncEngine* sync_engine = SetUpMockSyncEngine();
- EXPECT_CALL(*sync_engine, Initialize(_)).Times(0);
-
- DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
- EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::STOPPED));
-
- // Note: Deferred startup is only enabled if SESSIONS is among the preferred
- // data types.
- CreateSyncService(ProfileSyncService::MANUAL_START,
- syncer::ModelTypeSet(syncer::SESSIONS));
- sync_service()->Initialize();
-
- // There is no signed-in user, but nothing else prevents Sync from starting.
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
- sync_service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- sync_service()->GetTransportState());
-
- // Sign in. Now Sync is ready to start, just waiting for a prod.
- SimulateTestUserSignin();
- EXPECT_EQ(syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST,
- sync_service()->GetTransportState());
-
- // Once we give the service a prod by initiating Sync setup, it'll start and
- // initialize the engine. Since this is the initial Sync start, this will not
- // be deferred.
- EXPECT_CALL(*sync_engine, Initialize(_));
- auto setup_in_progress_handle = sync_service()->GetSetupInProgressHandle();
- EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
- sync_service()->GetTransportState());
-
- // Once the engine calls back and says it's initialized, we're just waiting
- // for the user to finish the initial configuration (choosing data types etc.)
- // before actually syncing data.
- sync_service()->OnEngineInitialized(
- syncer::ModelTypeSet(), syncer::WeakHandle<syncer::JsBackend>(),
- syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), "test-guid",
- "test-session-name", "test-birthday", "test-bag-of-chips",
- /*success=*/true);
- ASSERT_TRUE(sync_service()->IsEngineInitialized());
- EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
- sync_service()->GetTransportState());
- EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
-
- // Once the user finishes the initial setup, the service can actually start
- // configuring the data types. Just marking the initial setup as complete
- // isn't enough though, because setup is still considered in progress (we
- // haven't released the setup-in-progress handle).
- sync_service()->GetUserSettings()->SetFirstSetupComplete();
- EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
- sync_service()->GetTransportState());
- EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
-
- // Releasing the setup in progress handle lets the service actually configure
- // the DataTypeManager.
- EXPECT_CALL(*data_type_manager, Configure(_, _))
- .WillOnce(InvokeWithoutArgs(sync_service(),
- &ProfileSyncService::OnConfigureStart));
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURING));
- setup_in_progress_handle.reset();
- // While DataTypeManager configuration is ongoing, the overall state is still
- // CONFIGURING.
- EXPECT_EQ(syncer::SyncService::TransportState::CONFIGURING,
- sync_service()->GetTransportState());
- EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
-
- // Finally, once the DataTypeManager says it's done with configuration, Sync
- // is actually fully up and running.
- DataTypeManager::ConfigureResult configure_result(
- DataTypeManager::OK, syncer::ModelTypeSet(syncer::SESSIONS));
- ON_CALL(*data_type_manager, state())
- .WillByDefault(Return(DataTypeManager::CONFIGURED));
- sync_service()->OnConfigureDone(configure_result);
- EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
- sync_service()->GetTransportState());
- EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest,
- FullStartupSequenceFirstTime) {
+TEST_F(ProfileSyncServiceStartupTest, FullStartupSequenceFirstTime) {
// We've never completed startup.
ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
diff --git a/chromium/components/browser_sync/profile_sync_service_unittest.cc b/chromium/components/browser_sync/profile_sync_service_unittest.cc
index f22814e489a..33fab583992 100644
--- a/chromium/components/browser_sync/profile_sync_service_unittest.cc
+++ b/chromium/components/browser_sync/profile_sync_service_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/run_loop.h"
@@ -21,6 +22,7 @@
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/fake_data_type_controller.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/driver/sync_service_observer.h"
#include "components/sync/driver/sync_token_status.h"
@@ -130,24 +132,6 @@ class FakeSyncEngineCollectCredentials : public syncer::FakeSyncEngine {
base::RepeatingClosure invalidate_credentials_callback_;
};
-// FakeSyncEngine that calls an external callback when ClearServerData is
-// called.
-class FakeSyncEngineCaptureClearServerData : public syncer::FakeSyncEngine {
- public:
- using ClearServerDataCalled =
- base::RepeatingCallback<void(const base::Closure&)>;
- explicit FakeSyncEngineCaptureClearServerData(
- const ClearServerDataCalled& clear_server_data_called)
- : clear_server_data_called_(clear_server_data_called) {}
-
- void ClearServerData(const base::Closure& callback) override {
- clear_server_data_called_.Run(callback);
- }
-
- private:
- ClearServerDataCalled clear_server_data_called_;
-};
-
ACTION(ReturnNewFakeSyncEngine) {
return std::make_unique<syncer::FakeSyncEngine>();
}
@@ -156,11 +140,6 @@ ACTION(ReturnNewFakeSyncEngineNoReturn) {
return std::make_unique<FakeSyncEngineNoReturn>();
}
-void OnClearServerDataCalled(base::Closure* captured_callback,
- const base::Closure& callback) {
- *captured_callback = callback;
-}
-
// A test harness that uses a real ProfileSyncService and in most cases a
// FakeSyncEngine.
//
@@ -188,22 +167,20 @@ class ProfileSyncServiceTest : public ::testing::Test {
void CreateService(ProfileSyncService::StartBehavior behavior) {
DCHECK(!service_);
- ProfileSyncServiceBundle::SyncClientBuilder builder(
- &profile_sync_service_bundle_);
- ProfileSyncService::InitParams init_params =
- profile_sync_service_bundle_.CreateBasicInitParams(behavior,
- builder.Build());
- service_ = std::make_unique<ProfileSyncService>(std::move(init_params));
+ syncer::DataTypeController::TypeVector controllers;
+ controllers.push_back(
+ std::make_unique<syncer::FakeDataTypeController>(syncer::BOOKMARKS));
- ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _))
- .WillByDefault(testing::InvokeWithoutArgs([=]() {
- syncer::DataTypeController::TypeVector controllers;
- controllers.push_back(
- std::make_unique<syncer::FakeDataTypeController>(
- syncer::BOOKMARKS));
- return controllers;
- }));
- ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ std::unique_ptr<syncer::SyncClientMock> sync_client =
+ profile_sync_service_bundle_.CreateSyncClientMock();
+ ON_CALL(*sync_client, CreateDataTypeControllers(_))
+ .WillByDefault(Return(ByMove(std::move(controllers))));
+
+ service_ = std::make_unique<ProfileSyncService>(
+ profile_sync_service_bundle_.CreateBasicInitParams(
+ behavior, std::move(sync_client)));
+
+ ON_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillByDefault(ReturnNewFakeSyncEngine());
ON_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
.WillByDefault(
@@ -213,26 +190,25 @@ class ProfileSyncServiceTest : public ::testing::Test {
void CreateServiceWithLocalSyncBackend() {
DCHECK(!service_);
- ProfileSyncServiceBundle::SyncClientBuilder builder(
- &profile_sync_service_bundle_);
+ syncer::DataTypeController::TypeVector controllers;
+ controllers.push_back(
+ std::make_unique<syncer::FakeDataTypeController>(syncer::BOOKMARKS));
+
+ std::unique_ptr<syncer::SyncClientMock> sync_client =
+ profile_sync_service_bundle_.CreateSyncClientMock();
+ ON_CALL(*sync_client, CreateDataTypeControllers(_))
+ .WillByDefault(Return(ByMove(std::move(controllers))));
+
ProfileSyncService::InitParams init_params =
profile_sync_service_bundle_.CreateBasicInitParams(
- ProfileSyncService::AUTO_START, builder.Build());
+ ProfileSyncService::AUTO_START, std::move(sync_client));
prefs()->SetBoolean(syncer::prefs::kEnableLocalSyncBackend, true);
init_params.identity_manager = nullptr;
service_ = std::make_unique<ProfileSyncService>(std::move(init_params));
- ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_, _))
- .WillByDefault(testing::InvokeWithoutArgs([=]() {
- syncer::DataTypeController::TypeVector controllers;
- controllers.push_back(
- std::make_unique<syncer::FakeDataTypeController>(
- syncer::BOOKMARKS));
- return controllers;
- }));
- ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ ON_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillByDefault(ReturnNewFakeSyncEngine());
ON_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
.WillByDefault(
@@ -273,8 +249,6 @@ class ProfileSyncServiceTest : public ::testing::Test {
void OnConfigureCalled(syncer::ConfigureReason configure_reason) {
syncer::DataTypeManager::ConfigureResult result;
result.status = syncer::DataTypeManager::OK;
- if (configure_reason == syncer::CONFIGURE_REASON_CATCH_UP)
- result.was_catch_up_configure = true;
service()->OnConfigureDone(result);
}
@@ -324,32 +298,6 @@ class ProfileSyncServiceTest : public ::testing::Test {
std::unique_ptr<ProfileSyncService> service_;
};
-class ProfileSyncServiceWithStandaloneTransportTest
- : public ProfileSyncServiceTest {
- protected:
- ProfileSyncServiceWithStandaloneTransportTest() {
- feature_list_.InitAndEnableFeature(switches::kSyncStandaloneTransport);
- }
-
- ~ProfileSyncServiceWithStandaloneTransportTest() override {}
-
- private:
- base::test::ScopedFeatureList feature_list_;
-};
-
-class ProfileSyncServiceWithoutStandaloneTransportTest
- : public ProfileSyncServiceTest {
- protected:
- ProfileSyncServiceWithoutStandaloneTransportTest() {
- feature_list_.InitAndDisableFeature(switches::kSyncStandaloneTransport);
- }
-
- ~ProfileSyncServiceWithoutStandaloneTransportTest() override {}
-
- private:
- base::test::ScopedFeatureList feature_list_;
-};
-
// Verify that the server URLs are sane.
TEST_F(ProfileSyncServiceTest, InitialState) {
CreateService(ProfileSyncService::AUTO_START);
@@ -362,7 +310,7 @@ TEST_F(ProfileSyncServiceTest, InitialState) {
TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) {
SignIn();
CreateService(ProfileSyncService::AUTO_START);
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(ReturnNewFakeSyncEngine());
EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
.WillOnce(
@@ -376,7 +324,7 @@ TEST_F(ProfileSyncServiceTest, SuccessfulInitialization) {
TEST_F(ProfileSyncServiceTest, SuccessfulLocalBackendInitialization) {
CreateServiceWithLocalSyncBackend();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(ReturnNewFakeSyncEngine());
EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
.WillOnce(
@@ -389,41 +337,8 @@ TEST_F(ProfileSyncServiceTest, SuccessfulLocalBackendInitialization) {
}
// Verify that an initialization where first setup is not complete does not
-// start up the backend.
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportTest, NeedsConfirmation) {
- SignIn();
- CreateService(ProfileSyncService::MANUAL_START);
-
- syncer::SyncPrefs sync_prefs(prefs());
- base::Time now = base::Time::Now();
- sync_prefs.SetLastSyncedTime(now);
- sync_prefs.SetDataTypesConfiguration(/*keep_everything_synced=*/true,
- syncer::UserTypes(),
- syncer::UserSelectableTypes());
- service()->Initialize();
-
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- service()->GetDisableReasons());
- // Note: At this point the engine *can* start, but nothing has kicked it off
- // (usually that happens via getting and then releasing a
- // SyncSetupInProgressHandle), so the state is still WAITING_FOR_START_REQUEST
- // and not PENDING_DESIRED_CONFIGURATION.
- EXPECT_EQ(syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST,
- service()->GetTransportState());
-
- // Once we kick off initialization by getting and releasing a setup handle,
- // the state goes to PENDING_DESIRED_CONFIGURATION.
- service()->GetSetupInProgressHandle();
- EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
- service()->GetTransportState());
-
- // The last sync time shouldn't be cleared.
- // TODO(zea): figure out a way to check that the directory itself wasn't
- // cleared.
- EXPECT_EQ(now, sync_prefs.GetLastSyncedTime());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest, NeedsConfirmation) {
+// start up Sync-the-feature.
+TEST_F(ProfileSyncServiceTest, NeedsConfirmation) {
SignIn();
CreateService(ProfileSyncService::MANUAL_START);
@@ -535,7 +450,7 @@ TEST_F(ProfileSyncServiceTest, DisabledByPolicyAfterInit) {
// before the backend initialize call returns.
TEST_F(ProfileSyncServiceTest, AbortedByShutdown) {
CreateService(ProfileSyncService::AUTO_START);
- ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ ON_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillByDefault(ReturnNewFakeSyncEngineNoReturn());
SignIn();
@@ -547,42 +462,10 @@ TEST_F(ProfileSyncServiceTest, AbortedByShutdown) {
}
// Test SetSyncRequested(false) before we've initialized the backend.
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportTest, EarlyRequestStop) {
- CreateService(ProfileSyncService::AUTO_START);
- // Set up a fake sync engine that will not immediately finish initialization.
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(ReturnNewFakeSyncEngineNoReturn());
- SignIn();
- InitializeForNthSync();
-
- ASSERT_EQ(syncer::SyncService::TransportState::INITIALIZING,
- service()->GetTransportState());
-
- // Request stop. Sync should get disabled.
- service()->GetUserSettings()->SetSyncRequested(false);
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_USER_CHOICE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- service()->GetTransportState());
- EXPECT_FALSE(service()->IsSyncFeatureEnabled());
-
- // Request start again, this time with an engine that does get initialized.
- // Sync should become active.
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(ReturnNewFakeSyncEngine());
- service()->GetUserSettings()->SetSyncRequested(true);
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- EXPECT_TRUE(service()->IsSyncFeatureActive());
- EXPECT_TRUE(service()->IsSyncFeatureEnabled());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest, EarlyRequestStop) {
+TEST_F(ProfileSyncServiceTest, EarlyRequestStop) {
CreateService(ProfileSyncService::AUTO_START);
// Set up a fake sync engine that will not immediately finish initialization.
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(ReturnNewFakeSyncEngineNoReturn());
SignIn();
InitializeForNthSync();
@@ -592,7 +475,7 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportTest, EarlyRequestStop) {
// Request stop. This should immediately restart the service in standalone
// transport mode.
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(ReturnNewFakeSyncEngine());
service()->GetUserSettings()->SetSyncRequested(false);
EXPECT_EQ(syncer::SyncService::DISABLE_REASON_USER_CHOICE,
@@ -613,43 +496,7 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportTest, EarlyRequestStop) {
}
// Test SetSyncRequested(false) after we've initialized the backend.
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportTest,
- DisableAndEnableSyncTemporarily) {
- CreateService(ProfileSyncService::AUTO_START);
- SignIn();
- InitializeForNthSync();
-
- ASSERT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart));
- ASSERT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- service()->GetDisableReasons());
- ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- ASSERT_TRUE(service()->IsSyncFeatureActive());
- ASSERT_TRUE(service()->IsSyncFeatureEnabled());
-
- testing::Mock::VerifyAndClearExpectations(component_factory());
-
- service()->GetUserSettings()->SetSyncRequested(false);
- EXPECT_TRUE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart));
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_USER_CHOICE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- service()->GetTransportState());
- EXPECT_FALSE(service()->IsSyncFeatureActive());
- EXPECT_FALSE(service()->IsSyncFeatureEnabled());
-
- service()->GetUserSettings()->SetSyncRequested(true);
- EXPECT_FALSE(prefs()->GetBoolean(syncer::prefs::kSyncSuppressStart));
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- EXPECT_TRUE(service()->IsSyncFeatureActive());
- EXPECT_TRUE(service()->IsSyncFeatureEnabled());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest,
- DisableAndEnableSyncTemporarily) {
+TEST_F(ProfileSyncServiceTest, DisableAndEnableSyncTemporarily) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
InitializeForNthSync();
@@ -760,7 +607,7 @@ TEST_F(ProfileSyncServiceTest, RevokeAccessTokenFromTokenService) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(
Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
&init_credentials, base::RepeatingClosure()))));
@@ -797,8 +644,74 @@ TEST_F(ProfileSyncServiceTest, RevokeAccessTokenFromTokenService) {
// Checks that CREDENTIALS_REJECTED_BY_CLIENT resets the access token and stops
// Sync. Regression test for https://crbug.com/824791.
-TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient) {
+TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient_StopSync) {
+ base::test::ScopedFeatureList feature;
+ feature.InitAndEnableFeature(switches::kStopSyncInPausedState);
+
syncer::SyncCredentials init_credentials;
+
+ CreateService(ProfileSyncService::AUTO_START);
+ SignIn();
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
+ .WillOnce(
+ Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
+ &init_credentials, base::RepeatingClosure()))));
+ InitializeForNthSync();
+ ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
+ service()->GetTransportState());
+
+ TestSyncServiceObserver observer;
+ service()->AddObserver(&observer);
+
+ const std::string primary_account_id =
+ identity_manager()->GetPrimaryAccountId();
+
+ // Make sure the expected credentials (correct account_id, empty access token)
+ // were passed to the SyncEngine.
+ ASSERT_EQ(primary_account_id, init_credentials.account_id);
+ ASSERT_TRUE(init_credentials.sync_token.empty());
+
+ // At this point, the real SyncEngine would try to connect to the server, fail
+ // (because it has no access token), and eventually call
+ // OnConnectionStatusChange(CONNECTION_AUTH_ERROR). Since our fake SyncEngine
+ // doesn't do any of this, call that explicitly here.
+ service()->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR);
+
+ base::RunLoop().RunUntilIdle();
+ ASSERT_FALSE(service()->GetAccessTokenForTest().empty());
+ ASSERT_EQ(GoogleServiceAuthError::AuthErrorNone(), service()->GetAuthError());
+ ASSERT_EQ(GoogleServiceAuthError::AuthErrorNone(), observer.auth_error());
+
+ // Simulate the credentials getting locally rejected by the client by setting
+ // the refresh token to a special invalid value.
+ identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
+ const GoogleServiceAuthError rejected_by_client =
+ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_CLIENT);
+ ASSERT_EQ(rejected_by_client,
+ identity_test_env()
+ ->identity_manager()
+ ->GetErrorStateOfRefreshTokenForAccount(primary_account_id));
+ EXPECT_TRUE(service()->GetAccessTokenForTest().empty());
+
+ // The observer should have been notified of the auth error state.
+ EXPECT_EQ(rejected_by_client, observer.auth_error());
+ // The Sync engine should have been shut down.
+ EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
+ service()->GetTransportState());
+ EXPECT_TRUE(
+ service()->HasDisableReason(syncer::SyncService::DISABLE_REASON_PAUSED));
+
+ service()->RemoveObserver(&observer);
+}
+
+TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient_DoNotStopSync) {
+ base::test::ScopedFeatureList feature;
+ feature.InitAndDisableFeature(switches::kStopSyncInPausedState);
+
+ syncer::SyncCredentials init_credentials;
+
bool invalidate_credentials_called = false;
base::RepeatingClosure invalidate_credentials_callback =
base::BindRepeating([](bool* called) { *called = true; },
@@ -806,7 +719,7 @@ TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(
Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
&init_credentials, invalidate_credentials_callback))));
@@ -839,7 +752,7 @@ TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient) {
// Simulate the credentials getting locally rejected by the client by setting
// the refresh token to a special invalid value.
identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
- GoogleServiceAuthError rejected_by_client =
+ const GoogleServiceAuthError rejected_by_client =
GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_REJECTED_BY_CLIENT);
@@ -852,7 +765,7 @@ TEST_F(ProfileSyncServiceTest, CredentialsRejectedByClient) {
// The observer should have been notified of the auth error state.
EXPECT_EQ(rejected_by_client, observer.auth_error());
- // The overall state should remain ACTIVE.
+ // The Sync engine should still be running.
EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
service()->GetTransportState());
@@ -866,7 +779,7 @@ TEST_F(ProfileSyncServiceTest, SignOutRevokeAccessToken) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(
Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
&init_credentials, base::RepeatingClosure()))));
@@ -905,28 +818,7 @@ TEST_F(ProfileSyncServiceTest, SignOutRevokeAccessToken) {
#endif
// Verify that LastSyncedTime and local DeviceInfo is cleared on sign out.
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportTest, ClearDataOnSignOut) {
- SignIn();
- CreateService(ProfileSyncService::AUTO_START);
- InitializeForNthSync();
- ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTime(),
- base::TimeDelta::FromMinutes(1));
- ASSERT_TRUE(local_device_info_provider()->GetLocalDeviceInfo());
-
- // Sign out.
- service()->StopAndClear();
-
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- service()->GetTransportState());
- EXPECT_FALSE(service()->IsSyncFeatureEnabled());
-
- EXPECT_TRUE(service()->GetLastSyncedTime().is_null());
- EXPECT_FALSE(local_device_info_provider()->GetLocalDeviceInfo());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest, ClearDataOnSignOut) {
+TEST_F(ProfileSyncServiceTest, ClearDataOnSignOut) {
SignIn();
CreateService(ProfileSyncService::AUTO_START);
InitializeForNthSync();
@@ -950,7 +842,7 @@ TEST_F(ProfileSyncServiceWithStandaloneTransportTest, ClearDataOnSignOut) {
EXPECT_TRUE(local_device_info_provider()->GetLocalDeviceInfo());
}
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest, CancelSyncAfterSignOut) {
+TEST_F(ProfileSyncServiceTest, CancelSyncAfterSignOut) {
SignIn();
CreateService(ProfileSyncService::AUTO_START);
InitializeForNthSync();
@@ -982,7 +874,7 @@ TEST_F(ProfileSyncServiceTest, CredentialErrorReturned) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(
Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
&init_credentials, base::RepeatingClosure()))));
@@ -1045,7 +937,7 @@ TEST_F(ProfileSyncServiceTest, CredentialErrorClearsOnNewToken) {
CreateService(ProfileSyncService::AUTO_START);
SignIn();
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(
Return(ByMove(std::make_unique<FakeSyncEngineCollectCredentials>(
&init_credentials, base::RepeatingClosure()))));
@@ -1112,12 +1004,12 @@ TEST_F(ProfileSyncServiceTest, CredentialErrorClearsOnNewToken) {
// Verify that the disable sync flag disables sync.
TEST_F(ProfileSyncServiceTest, DisableSyncFlag) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
- EXPECT_FALSE(ProfileSyncService::IsSyncAllowedByFlag());
+ EXPECT_FALSE(switches::IsSyncAllowedByFlag());
}
// Verify that no disable sync flag enables sync.
TEST_F(ProfileSyncServiceTest, NoDisableSyncFlag) {
- EXPECT_TRUE(ProfileSyncService::IsSyncAllowedByFlag());
+ EXPECT_TRUE(switches::IsSyncAllowedByFlag());
}
// Test Sync will stop after receive memory pressure
@@ -1160,193 +1052,6 @@ TEST_F(ProfileSyncServiceTest, MemoryPressureRecording) {
EXPECT_TRUE(sync_prefs.DidSyncShutdownCleanly());
}
-// Verify that OnLocalSetPassphraseEncryption triggers catch up configure sync
-// cycle, calls ClearServerData, shuts down and restarts sync.
-TEST_F(ProfileSyncServiceTest, OnLocalSetPassphraseEncryption) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- switches::kSyncClearDataOnPassphraseEncryption);
- SignIn();
- CreateService(ProfileSyncService::AUTO_START);
-
- base::Closure captured_callback;
- syncer::ConfigureReason configure_reason = syncer::CONFIGURE_REASON_UNKNOWN;
-
- // Initialize sync, ensure that both DataTypeManager and SyncEngine are
- // initialized and DTM::Configure is called with
- // CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE.
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(
- Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>(
- base::BindRepeating(&OnClearServerDataCalled,
- base::Unretained(&captured_callback))))));
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- InitializeForNthSync();
- ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- testing::Mock::VerifyAndClearExpectations(component_factory());
- ASSERT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
- syncer::DataTypeManager::ConfigureResult result;
- result.status = syncer::DataTypeManager::OK;
- service()->OnConfigureDone(result);
-
- // Simulate user entering encryption passphrase. Ensure that catch up
- // configure cycle is started (DTM::Configure is called with
- // CONFIGURE_REASON_CATCH_UP).
- const syncer::SyncEncryptionHandler::NigoriState nigori_state;
- service()->GetEncryptionObserverForTest()->OnLocalSetPassphraseEncryption(
- nigori_state);
- EXPECT_EQ(syncer::CONFIGURE_REASON_CATCH_UP, configure_reason);
- EXPECT_TRUE(captured_callback.is_null());
-
- // Simulate configure successful. Ensure that SBH::ClearServerData is called.
- result.was_catch_up_configure = true;
- service()->OnConfigureDone(result);
- result.was_catch_up_configure = false;
- EXPECT_FALSE(captured_callback.is_null());
-
- // Once SBH::ClearServerData finishes successfully ensure that sync is
- // restarted.
- configure_reason = syncer::CONFIGURE_REASON_UNKNOWN;
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- captured_callback.Run();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
- service()->OnConfigureDone(result);
-}
-
-// Verify that if after OnLocalSetPassphraseEncryption catch up configure sync
-// cycle gets interrupted, it starts again after browser restart.
-TEST_F(ProfileSyncServiceTest,
- OnLocalSetPassphraseEncryption_RestartDuringCatchUp) {
- syncer::ConfigureReason configure_reason = syncer::CONFIGURE_REASON_UNKNOWN;
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- switches::kSyncClearDataOnPassphraseEncryption);
- SignIn();
- CreateService(ProfileSyncService::AUTO_START);
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- InitializeForNthSync();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- ASSERT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
- syncer::DataTypeManager::ConfigureResult result;
- result.status = syncer::DataTypeManager::OK;
- service()->OnConfigureDone(result);
-
- // Simulate user entering encryption passphrase. Ensure Configure was called
- // but don't let it continue.
- const syncer::SyncEncryptionHandler::NigoriState nigori_state;
- service()->GetEncryptionObserverForTest()->OnLocalSetPassphraseEncryption(
- nigori_state);
- EXPECT_EQ(syncer::CONFIGURE_REASON_CATCH_UP, configure_reason);
-
- // Simulate browser restart. First configuration is a regular one.
- ShutdownAndDeleteService();
- CreateService(ProfileSyncService::AUTO_START);
- base::Closure captured_callback;
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(
- Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>(
- base::BindRepeating(&OnClearServerDataCalled,
- base::Unretained(&captured_callback))))));
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- InitializeForNthSync();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
- EXPECT_TRUE(captured_callback.is_null());
-
- // Simulate configure successful. This time it should be catch up.
- service()->OnConfigureDone(result);
- EXPECT_EQ(syncer::CONFIGURE_REASON_CATCH_UP, configure_reason);
- EXPECT_TRUE(captured_callback.is_null());
-
- // Simulate catch up configure successful. Ensure that SBH::ClearServerData is
- // called.
- result.was_catch_up_configure = true;
- service()->OnConfigureDone(result);
- result.was_catch_up_configure = false;
- EXPECT_FALSE(captured_callback.is_null());
-
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- captured_callback.Run();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
-}
-
-// Verify that if after OnLocalSetPassphraseEncryption ClearServerData gets
-// interrupted, transition again from catch up sync cycle after browser restart.
-TEST_F(ProfileSyncServiceTest,
- OnLocalSetPassphraseEncryption_RestartDuringClearServerData) {
- base::Closure captured_callback;
- syncer::ConfigureReason configure_reason = syncer::CONFIGURE_REASON_UNKNOWN;
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- switches::kSyncClearDataOnPassphraseEncryption);
- SignIn();
- CreateService(ProfileSyncService::AUTO_START);
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(
- Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>(
- base::BindRepeating(&OnClearServerDataCalled,
- base::Unretained(&captured_callback))))));
- InitializeForNthSync();
- testing::Mock::VerifyAndClearExpectations(component_factory());
-
- // Simulate user entering encryption passphrase.
- const syncer::SyncEncryptionHandler::NigoriState nigori_state;
- service()->GetEncryptionObserverForTest()->OnLocalSetPassphraseEncryption(
- nigori_state);
- EXPECT_FALSE(captured_callback.is_null());
- captured_callback.Reset();
-
- // Simulate browser restart. First configuration is a regular one.
- ShutdownAndDeleteService();
- CreateService(ProfileSyncService::AUTO_START);
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
- .WillOnce(
- Return(ByMove(std::make_unique<FakeSyncEngineCaptureClearServerData>(
- base::BindRepeating(&OnClearServerDataCalled,
- base::Unretained(&captured_callback))))));
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- InitializeForNthSync();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
- EXPECT_TRUE(captured_callback.is_null());
-
- // Simulate configure successful. This time it should be catch up.
- syncer::DataTypeManager::ConfigureResult result;
- result.status = syncer::DataTypeManager::OK;
- service()->OnConfigureDone(result);
- EXPECT_EQ(syncer::CONFIGURE_REASON_CATCH_UP, configure_reason);
- EXPECT_TRUE(captured_callback.is_null());
-
- // Simulate catch up configure successful. Ensure that SBH::ClearServerData is
- // called.
- result.was_catch_up_configure = true;
- service()->OnConfigureDone(result);
- result.was_catch_up_configure = false;
- EXPECT_FALSE(captured_callback.is_null());
-
- EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
- .WillOnce(ReturnNewFakeDataTypeManager(
- GetRecordingConfigureCalledCallback(&configure_reason)));
- captured_callback.Run();
- testing::Mock::VerifyAndClearExpectations(component_factory());
- EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, configure_reason);
-}
-
// Test that the passphrase prompt due to version change logic gets triggered
// on a datatype type requesting startup, but only happens once.
TEST_F(ProfileSyncServiceTest, PassphrasePromptDueToVersion) {
@@ -1388,7 +1093,7 @@ TEST_F(ProfileSyncServiceTest, ResetSyncData) {
ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback()))
.WillOnce(
ReturnNewFakeDataTypeManager(GetDefaultConfigureCalledCallback()));
- EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
+ EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _))
.WillOnce(ReturnNewFakeSyncEngine())
.WillOnce(ReturnNewFakeSyncEngine());
@@ -1401,44 +1106,7 @@ TEST_F(ProfileSyncServiceTest, ResetSyncData) {
// Test that when ProfileSyncService receives actionable error
// DISABLE_SYNC_ON_CLIENT it disables sync and signs out.
-TEST_F(ProfileSyncServiceWithoutStandaloneTransportTest, DisableSyncOnClient) {
- SignIn();
- CreateService(ProfileSyncService::AUTO_START);
- InitializeForNthSync();
-
- ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
- service()->GetTransportState());
- ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTime(),
- base::TimeDelta::FromMinutes(1));
- ASSERT_TRUE(local_device_info_provider()->GetLocalDeviceInfo());
-
- syncer::SyncProtocolError client_cmd;
- client_cmd.action = syncer::DISABLE_SYNC_ON_CLIENT;
- service()->OnActionableError(client_cmd);
-
-#if defined(OS_CHROMEOS)
- // ChromeOS does not support signout.
- EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_USER_CHOICE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- service()->GetTransportState());
-#else
- EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
- EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN |
- syncer::SyncService::DISABLE_REASON_USER_CHOICE,
- service()->GetDisableReasons());
- EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
- service()->GetTransportState());
- EXPECT_TRUE(service()->GetLastSyncedTime().is_null());
- EXPECT_FALSE(local_device_info_provider()->GetLocalDeviceInfo());
-#endif
-
- EXPECT_FALSE(service()->IsSyncFeatureEnabled());
- EXPECT_FALSE(service()->IsSyncFeatureActive());
-}
-
-TEST_F(ProfileSyncServiceWithStandaloneTransportTest, DisableSyncOnClient) {
+TEST_F(ProfileSyncServiceTest, DisableSyncOnClient) {
SignIn();
CreateService(ProfileSyncService::AUTO_START);
InitializeForNthSync();
@@ -1530,8 +1198,9 @@ TEST_F(ProfileSyncServiceTest, ConfigureDataTypeManagerReason) {
service()->OnConfigureDone(configure_result);
// Reconfiguration.
- service()->ReconfigureDatatypeManager(
- /*bypass_setup_in_progress_check=*/false);
+ // Trigger a reconfig by grabbing a SyncSetupInProgressHandle and immediately
+ // releasing it again (via the temporary unique_ptr going away).
+ service()->GetSetupInProgressHandle();
EXPECT_EQ(syncer::CONFIGURE_REASON_RECONFIGURATION, configure_reason);
service()->OnConfigureDone(configure_result);
ShutdownAndDeleteService();
@@ -1549,8 +1218,9 @@ TEST_F(ProfileSyncServiceTest, ConfigureDataTypeManagerReason) {
service()->OnConfigureDone(configure_result);
// Reconfiguration.
- service()->ReconfigureDatatypeManager(
- /*bypass_setup_in_progress_check=*/false);
+ // Trigger a reconfig by grabbing a SyncSetupInProgressHandle and immediately
+ // releasing it again (via the temporary unique_ptr going away).
+ service()->GetSetupInProgressHandle();
EXPECT_EQ(syncer::CONFIGURE_REASON_RECONFIGURATION, configure_reason);
service()->OnConfigureDone(configure_result);
ShutdownAndDeleteService();
diff --git a/chromium/components/browser_sync/profile_sync_test_util.cc b/chromium/components/browser_sync/profile_sync_test_util.cc
index 5fa7ecbf84c..ec37273b415 100644
--- a/chromium/components/browser_sync/profile_sync_test_util.cc
+++ b/chromium/components/browser_sync/profile_sync_test_util.cc
@@ -7,19 +7,11 @@
#include <string>
#include <utility>
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/bookmarks/browser/bookmark_model.h"
-#include "components/history/core/browser/history_service.h"
-#include "components/history/core/browser/sync/history_model_worker.h"
+#include "base/bind_helpers.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/device_info/local_device_info_provider_impl.h"
#include "components/sync/engine/passive_model_worker.h"
-#include "components/sync/engine/sequenced_model_worker.h"
-#include "components/sync/engine/ui_model_worker.h"
#include "components/sync/model/model_type_store_test_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -29,189 +21,10 @@
namespace browser_sync {
-namespace {
-
-class BundleSyncClient : public syncer::FakeSyncClient {
- public:
- BundleSyncClient(syncer::SyncApiComponentFactory* factory,
- PrefService* pref_service,
- syncer::ModelTypeStoreService* model_type_store_service,
- syncer::DeviceInfoSyncService* device_info_sync_service,
- autofill::PersonalDataManager* personal_data_manager,
- const base::Callback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>& get_syncable_service_callback,
- const base::Callback<bookmarks::BookmarkModel*(void)>&
- get_bookmark_model_callback,
- scoped_refptr<base::SequencedTaskRunner> db_thread,
- scoped_refptr<base::SequencedTaskRunner> file_thread,
- history::HistoryService* history_service);
-
- ~BundleSyncClient() override;
-
- PrefService* GetPrefService() override;
- autofill::PersonalDataManager* GetPersonalDataManager() override;
- base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
- syncer::ModelType type) override;
- syncer::ModelTypeStoreService* GetModelTypeStoreService() override;
- syncer::DeviceInfoSyncService* GetDeviceInfoSyncService() override;
- scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup(
- syncer::ModelSafeGroup group) override;
- history::HistoryService* GetHistoryService() override;
- bookmarks::BookmarkModel* GetBookmarkModel() override;
-
- private:
- PrefService* const pref_service_;
- syncer::ModelTypeStoreService* const model_type_store_service_;
- syncer::DeviceInfoSyncService* const device_info_sync_service_;
- autofill::PersonalDataManager* const personal_data_manager_;
- const base::Callback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>
- get_syncable_service_callback_;
- const base::Callback<bookmarks::BookmarkModel*(void)>
- get_bookmark_model_callback_;
- // These task runners, if not null, are used in CreateModelWorkerForGroup.
- const scoped_refptr<base::SequencedTaskRunner> db_thread_;
- const scoped_refptr<base::SequencedTaskRunner> file_thread_;
- history::HistoryService* history_service_;
-};
-
-BundleSyncClient::BundleSyncClient(
- syncer::SyncApiComponentFactory* factory,
- PrefService* pref_service,
- syncer::ModelTypeStoreService* model_type_store_service,
- syncer::DeviceInfoSyncService* device_info_sync_service,
- autofill::PersonalDataManager* personal_data_manager,
- const base::Callback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>& get_syncable_service_callback,
- const base::Callback<bookmarks::BookmarkModel*(void)>&
- get_bookmark_model_callback,
- scoped_refptr<base::SequencedTaskRunner> db_thread,
- scoped_refptr<base::SequencedTaskRunner> file_thread,
- history::HistoryService* history_service)
- : syncer::FakeSyncClient(factory),
- pref_service_(pref_service),
- model_type_store_service_(model_type_store_service),
- device_info_sync_service_(device_info_sync_service),
- personal_data_manager_(personal_data_manager),
- get_syncable_service_callback_(get_syncable_service_callback),
- get_bookmark_model_callback_(get_bookmark_model_callback),
- db_thread_(db_thread),
- file_thread_(file_thread),
- history_service_(history_service) {
- EXPECT_EQ(!!db_thread_, !!file_thread_);
-}
-
-BundleSyncClient::~BundleSyncClient() = default;
-
-PrefService* BundleSyncClient::GetPrefService() {
- return pref_service_;
-}
-
-autofill::PersonalDataManager* BundleSyncClient::GetPersonalDataManager() {
- return personal_data_manager_;
-}
-
-base::WeakPtr<syncer::SyncableService>
-BundleSyncClient::GetSyncableServiceForType(syncer::ModelType type) {
- if (get_syncable_service_callback_.is_null())
- return syncer::FakeSyncClient::GetSyncableServiceForType(type);
- return get_syncable_service_callback_.Run(type);
-}
-
-scoped_refptr<syncer::ModelSafeWorker>
-BundleSyncClient::CreateModelWorkerForGroup(syncer::ModelSafeGroup group) {
- if (!db_thread_)
- return FakeSyncClient::CreateModelWorkerForGroup(group);
- EXPECT_TRUE(file_thread_)
- << "DB thread was specified but FILE thread was not.";
- switch (group) {
- case syncer::GROUP_DB:
- return new syncer::SequencedModelWorker(db_thread_, syncer::GROUP_DB);
- case syncer::GROUP_FILE:
- return new syncer::SequencedModelWorker(file_thread_, syncer::GROUP_FILE);
- case syncer::GROUP_UI:
- return new syncer::UIModelWorker(base::ThreadTaskRunnerHandle::Get());
- case syncer::GROUP_PASSIVE:
- return new syncer::PassiveModelWorker();
- case syncer::GROUP_HISTORY: {
- history::HistoryService* history_service = GetHistoryService();
- if (!history_service)
- return nullptr;
- return new HistoryModelWorker(history_service->AsWeakPtr(),
- base::ThreadTaskRunnerHandle::Get());
- }
- default:
- return nullptr;
- }
-}
-
-syncer::ModelTypeStoreService* BundleSyncClient::GetModelTypeStoreService() {
- return model_type_store_service_;
-}
-
-syncer::DeviceInfoSyncService* BundleSyncClient::GetDeviceInfoSyncService() {
- return device_info_sync_service_;
-}
-
-history::HistoryService* BundleSyncClient::GetHistoryService() {
- if (history_service_)
- return history_service_;
- return FakeSyncClient::GetHistoryService();
-}
-
-bookmarks::BookmarkModel* BundleSyncClient::GetBookmarkModel() {
- if (get_bookmark_model_callback_.is_null())
- return FakeSyncClient::GetBookmarkModel();
- return get_bookmark_model_callback_.Run();
-}
-
-} // namespace
-
-ProfileSyncServiceBundle::SyncClientBuilder::~SyncClientBuilder() = default;
-
-ProfileSyncServiceBundle::SyncClientBuilder::SyncClientBuilder(
- ProfileSyncServiceBundle* bundle)
- : bundle_(bundle) {}
-
-void ProfileSyncServiceBundle::SyncClientBuilder::SetPersonalDataManager(
- autofill::PersonalDataManager* personal_data_manager) {
- personal_data_manager_ = personal_data_manager;
-}
-
-// The client will call this callback to produce the service.
-void ProfileSyncServiceBundle::SyncClientBuilder::SetSyncableServiceCallback(
- const base::RepeatingCallback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>& get_syncable_service_callback) {
- get_syncable_service_callback_ = get_syncable_service_callback;
-}
-
-void ProfileSyncServiceBundle::SyncClientBuilder::SetHistoryService(
- history::HistoryService* history_service) {
- history_service_ = history_service;
-}
-
-void ProfileSyncServiceBundle::SyncClientBuilder::SetBookmarkModelCallback(
- const base::Callback<bookmarks::BookmarkModel*(void)>&
- get_bookmark_model_callback) {
- get_bookmark_model_callback_ = get_bookmark_model_callback;
-}
-
-std::unique_ptr<syncer::FakeSyncClient>
-ProfileSyncServiceBundle::SyncClientBuilder::Build() {
- return std::make_unique<BundleSyncClient>(
- bundle_->component_factory(), bundle_->pref_service(),
- &bundle_->model_type_store_service_, &bundle_->device_info_sync_service_,
- personal_data_manager_, get_syncable_service_callback_,
- get_bookmark_model_callback_,
- activate_model_creation_ ? bundle_->db_thread() : nullptr,
- activate_model_creation_ ? base::SequencedTaskRunnerHandle::Get()
- : nullptr,
- history_service_);
-}
+using testing::Return;
ProfileSyncServiceBundle::ProfileSyncServiceBundle()
- : db_thread_(base::SequencedTaskRunnerHandle::Get()),
- device_info_sync_service_(
+ : device_info_sync_service_(
model_type_store_service_.GetStoreFactory(),
std::make_unique<syncer::LocalDeviceInfoProviderImpl>(
version_info::Channel::UNKNOWN,
@@ -229,6 +42,22 @@ ProfileSyncServiceBundle::ProfileSyncServiceBundle()
ProfileSyncServiceBundle::~ProfileSyncServiceBundle() {}
+std::unique_ptr<syncer::SyncClientMock>
+ProfileSyncServiceBundle::CreateSyncClientMock() {
+ auto sync_client =
+ std::make_unique<testing::NiceMock<syncer::SyncClientMock>>();
+ ON_CALL(*sync_client, GetPrefService()).WillByDefault(Return(&pref_service_));
+ ON_CALL(*sync_client, GetDeviceInfoSyncService())
+ .WillByDefault(Return(&device_info_sync_service_));
+ ON_CALL(*sync_client, GetSyncApiComponentFactory())
+ .WillByDefault(Return(&component_factory_));
+ // Used by control types.
+ ON_CALL(*sync_client, CreateModelWorkerForGroup(syncer::GROUP_PASSIVE))
+ .WillByDefault(
+ Return(base::MakeRefCounted<syncer::PassiveModelWorker>()));
+ return std::move(sync_client);
+}
+
ProfileSyncService::InitParams ProfileSyncServiceBundle::CreateBasicInitParams(
ProfileSyncService::StartBehavior start_behavior,
std::unique_ptr<syncer::SyncClient> sync_client) {
diff --git a/chromium/components/browser_sync/profile_sync_test_util.h b/chromium/components/browser_sync/profile_sync_test_util.h
index a5827184fcc..bda4db31f07 100644
--- a/chromium/components/browser_sync/profile_sync_test_util.h
+++ b/chromium/components/browser_sync/profile_sync_test_util.h
@@ -14,17 +14,13 @@
#include "components/invalidation/impl/fake_invalidation_service.h"
#include "components/invalidation/impl/profile_identity_provider.h"
#include "components/sync/device_info/device_info_sync_service_impl.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/model/test_model_type_store_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "services/network/test/test_url_loader_factory.h"
-namespace history {
-class HistoryService;
-}
-
namespace user_prefs {
class PrefRegistrySyncable;
}
@@ -44,54 +40,8 @@ class ProfileSyncServiceBundle {
~ProfileSyncServiceBundle();
- // Builders
-
- // Builds a child of FakeSyncClient which overrides some of the client's
- // accessors to return objects from the bundle.
- class SyncClientBuilder {
- public:
- // Construct the builder and associate with the |bundle| to source objects
- // from.
- explicit SyncClientBuilder(ProfileSyncServiceBundle* bundle);
-
- ~SyncClientBuilder();
-
- void SetPersonalDataManager(
- autofill::PersonalDataManager* personal_data_manager);
-
- // The client will call this callback to produce the SyncableService
- // specific to |type|.
- void SetSyncableServiceCallback(
- const base::RepeatingCallback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>& get_syncable_service_callback);
-
- void SetHistoryService(history::HistoryService* history_service);
-
- void SetBookmarkModelCallback(
- const base::Callback<bookmarks::BookmarkModel*(void)>&
- get_bookmark_model_callback);
-
- void set_activate_model_creation() { activate_model_creation_ = true; }
-
- std::unique_ptr<syncer::FakeSyncClient> Build();
-
- private:
- // Associated bundle to source objects from.
- ProfileSyncServiceBundle* const bundle_;
-
- autofill::PersonalDataManager* personal_data_manager_;
- base::Callback<base::WeakPtr<syncer::SyncableService>(
- syncer::ModelType type)>
- get_syncable_service_callback_;
- history::HistoryService* history_service_ = nullptr;
- base::Callback<bookmarks::BookmarkModel*(void)>
- get_bookmark_model_callback_;
- // If set, the built client will be able to build some ModelSafeWorker
- // instances.
- bool activate_model_creation_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(SyncClientBuilder);
- };
+ // Creates a mock sync client that leverages the dependencies in this bundle.
+ std::unique_ptr<syncer::SyncClientMock> CreateSyncClientMock();
// Creates an InitParams instance with the specified |start_behavior| and
// |sync_client|, and fills the rest with dummy values and objects owned by
@@ -130,19 +80,11 @@ class ProfileSyncServiceBundle {
return &fake_invalidation_service_;
}
- base::SequencedTaskRunner* db_thread() { return db_thread_.get(); }
-
- void set_db_thread(
- const scoped_refptr<base::SequencedTaskRunner>& db_thread) {
- db_thread_ = db_thread;
- }
-
syncer::DeviceInfoSyncService* device_info_sync_service() {
return &device_info_sync_service_;
}
private:
- scoped_refptr<base::SequencedTaskRunner> db_thread_;
sync_preferences::TestingPrefServiceSyncable pref_service_;
syncer::TestModelTypeStoreService model_type_store_service_;
syncer::DeviceInfoSyncServiceImpl device_info_sync_service_;
diff --git a/chromium/components/browser_sync/sync_auth_manager.cc b/chromium/components/browser_sync/sync_auth_manager.cc
index c0f6cba8f95..7bfa58fa645 100644
--- a/chromium/components/browser_sync/sync_auth_manager.cc
+++ b/chromium/components/browser_sync/sync_auth_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "components/sync/base/stop_source.h"
@@ -49,21 +50,28 @@ constexpr net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = {
false,
};
+bool IsWebSignout(const GoogleServiceAuthError& auth_error) {
+ // The identity code sets an account's refresh token to be invalid (error
+ // CREDENTIALS_REJECTED_BY_CLIENT) if the user signs out of that account on
+ // the web.
+ return auth_error ==
+ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_CLIENT);
+}
+
} // namespace
SyncAuthManager::SyncAuthManager(
- syncer::SyncPrefs* sync_prefs,
identity::IdentityManager* identity_manager,
const AccountStateChangedCallback& account_state_changed,
const CredentialsChangedCallback& credentials_changed)
- : sync_prefs_(sync_prefs),
- identity_manager_(identity_manager),
+ : identity_manager_(identity_manager),
account_state_changed_callback_(account_state_changed),
credentials_changed_callback_(credentials_changed),
registered_for_auth_notifications_(false),
request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy),
weak_ptr_factory_(this) {
- DCHECK(sync_prefs_);
// |identity_manager_| can be null if local Sync is enabled.
}
@@ -86,24 +94,28 @@ void SyncAuthManager::RegisterForAuthNotifications() {
}
syncer::SyncAccountInfo SyncAuthManager::GetActiveAccountInfo() const {
- if (!registered_for_auth_notifications_) {
- return syncer::SyncAccountInfo();
- }
+ // Note: |sync_account_| should generally be identical to the result of a
+ // DetermineAccountToUse() call, but there are a few edge cases when it isn't:
+ // E.g. when another identity observer gets notified before us and calls in
+ // here, or when we're currently switching accounts in
+ // UpdateSyncAccountIfNecessary(). So unfortunately we can't verify this.
+ return sync_account_;
+}
-#if defined(OS_CHROMEOS)
- if (!base::FeatureList::IsEnabled(switches::kSyncSupportSecondaryAccount)) {
- // TODO(crbug.com/814787): Once the ChromeOS test setup is fixed, we can
- // just return |sync_account_| here instead of re-querying.
- return DetermineAccountToUse();
+GoogleServiceAuthError SyncAuthManager::GetLastAuthError() const {
+ // TODO(crbug.com/921553): Which error should take precedence?
+ if (partial_token_status_.connection_status ==
+ syncer::CONNECTION_SERVER_ERROR) {
+ // TODO(crbug.com/921553): Verify whether CONNECTION_FAILED is really an
+ // appropriate auth error here; maybe SERVICE_ERROR would be better? Or
+ // maybe we shouldn't expose this case as an auth error at all?
+ return GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
}
-#endif // !defined(OS_CHROMEOS)
- // Note: At this point, |sync_account_| should generally be identical to the
- // result of a DetermineAccountToUse() call, but there are a few edge cases
- // when it isn't: E.g. when another identity observer gets notified before us
- // and calls in here, or when we're currently switching accounts in
- // UpdateSyncAccountIfNecessary(). So unfortunately we can't verify this.
+ return last_auth_error_;
+}
- return sync_account_;
+bool SyncAuthManager::IsSyncPaused() const {
+ return IsWebSignout(GetLastAuthError());
}
syncer::SyncTokenStatus SyncAuthManager::GetSyncTokenStatus() const {
@@ -121,9 +133,7 @@ syncer::SyncTokenStatus SyncAuthManager::GetSyncTokenStatus() const {
}
syncer::SyncCredentials SyncAuthManager::GetCredentials() const {
- // TODO(crbug.com/814787): Once the ChromeOS test setup is fixed, we can just
- // use |sync_account_| directly here.
- const AccountInfo account_info = GetActiveAccountInfo().account_info;
+ const CoreAccountInfo& account_info = sync_account_.account_info;
syncer::SyncCredentials credentials;
credentials.account_id = account_info.account_id;
@@ -190,13 +200,11 @@ void SyncAuthManager::ConnectionStatusChanged(syncer::ConnectionStatus status) {
if (!request_access_token_retry_timer_.IsRunning()) {
request_access_token_backoff_.Reset();
}
- last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
break;
case syncer::CONNECTION_SERVER_ERROR:
- // TODO(crbug.com/839834): Verify whether CONNECTION_FAILED is really an
- // appropriate auth error here; maybe SERVICE_ERROR would be better?
- last_auth_error_ =
- GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
+ // Note: This case will be exposed as an auth error, due to the
+ // |connection_status| in |partial_token_error_|.
+ DCHECK(GetLastAuthError().IsTransientError());
break;
case syncer::CONNECTION_NOT_ATTEMPTED:
// The connection status should never change to "not attempted".
@@ -236,28 +244,25 @@ void SyncAuthManager::ScheduleAccessTokenRequest() {
weak_ptr_factory_.GetWeakPtr()));
}
-void SyncAuthManager::Clear() {
- // TODO(crbug.com/839834): Clearing the auth error here isn't quite right.
- // It makes sense to clear any auth error we got from the Sync server, but we
- // should probably retain any errors from the identity manager.
- last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
+void SyncAuthManager::ConnectionClosed() {
+ partial_token_status_ = syncer::SyncTokenStatus();
ClearAccessTokenAndRequest();
}
void SyncAuthManager::OnPrimaryAccountSet(
- const AccountInfo& primary_account_info) {
+ const CoreAccountInfo& primary_account_info) {
UpdateSyncAccountIfNecessary();
}
void SyncAuthManager::OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) {
+ const CoreAccountInfo& previous_primary_account_info) {
UMA_HISTOGRAM_ENUMERATION("Sync.StopSource", syncer::SIGN_OUT,
syncer::STOP_SOURCE_LIMIT);
UpdateSyncAccountIfNecessary();
}
void SyncAuthManager::OnRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
if (UpdateSyncAccountIfNecessary()) {
// If the syncing account was updated as a result of this, then all that's
// necessary has been handled; nothing else to be done here.
@@ -269,16 +274,13 @@ void SyncAuthManager::OnRefreshTokenUpdatedForAccount(
}
// Compute the validity of the new refresh token: The identity code sets an
- // account's refresh token to be invalid (error
- // CREDENTIALS_REJECTED_BY_CLIENT) if the user signs out of that account on
- // the web.
+ // account's refresh token to be invalid if the user signs out of that account
+ // on the web.
// TODO(blundell): Hide this logic inside IdentityManager.
GoogleServiceAuthError token_error =
identity_manager_->GetErrorStateOfRefreshTokenForAccount(
account_info.account_id);
- if (token_error == GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
- GoogleServiceAuthError::InvalidGaiaCredentialsReason::
- CREDENTIALS_REJECTED_BY_CLIENT)) {
+ if (IsWebSignout(token_error)) {
// When the refresh token is replaced by an invalid token, Sync must be
// stopped immediately, even if the current access token is still valid.
// This happens e.g. when the user signs out of the web with Dice enabled.
@@ -324,6 +326,7 @@ void SyncAuthManager::OnRefreshTokenRemovedForAccount(
// If we're still here, then that means Chrome is still signed in to this
// account. Keep Sync alive but set an auth error.
+ // TODO(crbug.com/906995): Should we stop Sync in this case?
DCHECK_EQ(sync_account_.account_info.account_id,
identity_manager_->GetPrimaryAccountId());
@@ -354,8 +357,7 @@ syncer::SyncAccountInfo SyncAuthManager::DetermineAccountToUse() const {
DCHECK(registered_for_auth_notifications_);
return syncer::DetermineAccountToUse(
identity_manager_,
- base::FeatureList::IsEnabled(switches::kSyncStandaloneTransport) &&
- base::FeatureList::IsEnabled(switches::kSyncSupportSecondaryAccount));
+ base::FeatureList::IsEnabled(switches::kSyncSupportSecondaryAccount));
}
bool SyncAuthManager::UpdateSyncAccountIfNecessary() {
@@ -376,7 +378,8 @@ bool SyncAuthManager::UpdateSyncAccountIfNecessary() {
sync_account_ = syncer::SyncAccountInfo();
// Also clear any pending request or auth errors we might have, since they
// aren't meaningful anymore.
- Clear();
+ ConnectionClosed();
+ last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
account_state_changed_callback_.Run();
}
@@ -404,9 +407,6 @@ void SyncAuthManager::RequestAccessToken() {
request_access_token_retry_timer_.Stop();
}
- const identity::ScopeSet kOAuth2ScopeSet{
- GaiaConstants::kChromeSyncOAuth2Scope};
-
// Invalidate any previous token, otherwise the token service will return the
// same token again.
InvalidateAccessToken();
@@ -417,7 +417,7 @@ void SyncAuthManager::RequestAccessToken() {
ongoing_access_token_fetch_ =
identity_manager_->CreateAccessTokenFetcherForAccount(
sync_account_.account_info.account_id, kSyncOAuthConsumerName,
- kOAuth2ScopeSet,
+ {GaiaConstants::kChromeSyncOAuth2Scope},
base::BindOnce(&SyncAuthManager::AccessTokenFetched,
base::Unretained(this)),
identity::AccessTokenFetcher::Mode::kWaitUntilRefreshTokenAvailable);
@@ -439,7 +439,6 @@ void SyncAuthManager::AccessTokenFetched(
switch (error.state()) {
case GoogleServiceAuthError::NONE:
partial_token_status_.token_receive_time = base::Time::Now();
- sync_prefs_->SetSyncAuthError(false);
last_auth_error_ = GoogleServiceAuthError::AuthErrorNone();
break;
case GoogleServiceAuthError::CONNECTION_FAILED:
@@ -454,7 +453,6 @@ void SyncAuthManager::AccessTokenFetched(
ScheduleAccessTokenRequest();
break;
case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
- sync_prefs_->SetSyncAuthError(true);
last_auth_error_ = error;
break;
default:
diff --git a/chromium/components/browser_sync/sync_auth_manager.h b/chromium/components/browser_sync/sync_auth_manager.h
index a860d542909..fa97a6f1813 100644
--- a/chromium/components/browser_sync/sync_auth_manager.h
+++ b/chromium/components/browser_sync/sync_auth_manager.h
@@ -27,7 +27,6 @@ class AccessTokenFetcher;
namespace syncer {
struct SyncCredentials;
-class SyncPrefs;
} // namespace syncer
namespace browser_sync {
@@ -47,11 +46,9 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
// added/changed/removed. Call GetCredentials to get the new state.
using CredentialsChangedCallback = base::RepeatingClosure;
- // |sync_prefs| must not be null and must outlive this.
// |identity_manager| may be null (this is the case if local Sync is enabled),
// but if non-null, must outlive this object.
- SyncAuthManager(syncer::SyncPrefs* sync_prefs,
- identity::IdentityManager* identity_manager,
+ SyncAuthManager(identity::IdentityManager* identity_manager,
const AccountStateChangedCallback& account_state_changed,
const CredentialsChangedCallback& credentials_changed);
~SyncAuthManager() override;
@@ -67,9 +64,14 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
// server. Note that this account may not be blessed for Sync-the-feature.
syncer::SyncAccountInfo GetActiveAccountInfo() const;
- const GoogleServiceAuthError& GetLastAuthError() const {
- return last_auth_error_;
- }
+ // Returns the last auth error that was encountered. The error could have come
+ // from the Sync server or from the IdentityManager.
+ GoogleServiceAuthError GetLastAuthError() const;
+
+ // Returns whether we are in the "Sync paused" state. That means there is a
+ // primary account, but the user signed out in the content area, and so we
+ // don't have credentials for it anymore.
+ bool IsSyncPaused() const;
// Returns the credentials to be passed to the SyncEngine.
syncer::SyncCredentials GetCredentials() const;
@@ -81,19 +83,22 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
syncer::SyncTokenStatus GetSyncTokenStatus() const;
// Called by ProfileSyncService when the status of the connection to the Sync
- // server changed. Updates auth error state accordingly.
+ // server changed. Updates auth error state accordingly. During Sync startup,
+ // this is what initiates fetching an access token.
void ConnectionStatusChanged(syncer::ConnectionStatus status);
- // Clears all auth-related state (error, cached access token etc). Called
- // when Sync is turned off.
- void Clear();
+ // Called by ProfileSyncService when the connection to the Sync server is
+ // closed (due to Sync being shut down). Clears all related state (such as
+ // cached access token, error from the server, etc).
+ void ConnectionClosed();
// identity::IdentityManager::Observer implementation.
- void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
+ void OnPrimaryAccountSet(
+ const CoreAccountInfo& primary_account_info) override;
void OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) override;
+ const CoreAccountInfo& previous_primary_account_info) override;
void OnRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info) override;
+ const CoreAccountInfo& account_info) override;
void OnRefreshTokenRemovedForAccount(const std::string& account_id) override;
void OnAccountsInCookieUpdated(
const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
@@ -134,7 +139,6 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
void AccessTokenFetched(GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info);
- syncer::SyncPrefs* const sync_prefs_;
identity::IdentityManager* const identity_manager_;
const AccountStateChangedCallback account_state_changed_callback_;
@@ -147,12 +151,8 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
// delayed startup.
syncer::SyncAccountInfo sync_account_;
- // This is a cache of the last authentication response we received either
- // from the sync server or from Chrome's identity/token management system.
- // TODO(crbug.com/839834): Differentiate between these types of auth errors,
- // since their semantics and lifetimes are quite different: e.g. the former
- // can only exist while the Sync engine is initialized; the latter exists
- // independent of Sync state, and probably shouldn't get reset in Clear().
+ // This is a cache of the last authentication response we received from
+ // Chrome's identity/token management system.
GoogleServiceAuthError last_auth_error_;
// The current access token. This is mutually exclusive with
@@ -172,7 +172,7 @@ class SyncAuthManager : public identity::IdentityManager::Observer {
// Info about the state of our access token, for display in the internals UI.
// "Partial" because this instance is not fully populated - in particular,
- // |have_token| and |next_token_request_time| get computed on demand.
+ // |has_token| and |next_token_request_time| get computed on demand.
syncer::SyncTokenStatus partial_token_status_;
base::WeakPtrFactory<SyncAuthManager> weak_ptr_factory_;
diff --git a/chromium/components/browser_sync/sync_auth_manager_unittest.cc b/chromium/components/browser_sync/sync_auth_manager_unittest.cc
index 945f7c2a64e..e0509f7f964 100644
--- a/chromium/components/browser_sync/sync_auth_manager_unittest.cc
+++ b/chromium/components/browser_sync/sync_auth_manager_unittest.cc
@@ -10,13 +10,12 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
-#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/engine/connection_status.h"
#include "components/sync/engine/sync_credentials.h"
-#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "net/base/net_errors.h"
#include "services/identity/public/cpp/identity_test_environment.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,10 +30,7 @@ class SyncAuthManagerTest : public testing::Test {
using CredentialsChangedCallback =
SyncAuthManager::CredentialsChangedCallback;
- SyncAuthManagerTest() : identity_env_(&test_url_loader_factory_) {
- syncer::SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
- sync_prefs_ = std::make_unique<syncer::SyncPrefs>(&pref_service_);
- }
+ SyncAuthManagerTest() : identity_env_(&test_url_loader_factory_) {}
~SyncAuthManagerTest() override {}
@@ -45,14 +41,14 @@ class SyncAuthManagerTest : public testing::Test {
std::unique_ptr<SyncAuthManager> CreateAuthManager(
const AccountStateChangedCallback& account_state_changed,
const CredentialsChangedCallback& credentials_changed) {
- return std::make_unique<SyncAuthManager>(
- sync_prefs_.get(), identity_env_.identity_manager(),
- account_state_changed, credentials_changed);
+ return std::make_unique<SyncAuthManager>(identity_env_.identity_manager(),
+ account_state_changed,
+ credentials_changed);
}
std::unique_ptr<SyncAuthManager> CreateAuthManagerForLocalSync() {
- return std::make_unique<SyncAuthManager>(
- sync_prefs_.get(), nullptr, base::DoNothing(), base::DoNothing());
+ return std::make_unique<SyncAuthManager>(nullptr, base::DoNothing(),
+ base::DoNothing());
}
identity::IdentityTestEnvironment* identity_env() { return &identity_env_; }
@@ -61,8 +57,6 @@ class SyncAuthManagerTest : public testing::Test {
base::test::ScopedTaskEnvironment task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
identity::IdentityTestEnvironment identity_env_;
- sync_preferences::TestingPrefServiceSyncable pref_service_;
- std::unique_ptr<syncer::SyncPrefs> sync_prefs_;
};
TEST_F(SyncAuthManagerTest, ProvidesNothingInLocalSyncMode) {
@@ -75,8 +69,8 @@ TEST_F(SyncAuthManagerTest, ProvidesNothingInLocalSyncMode) {
EXPECT_TRUE(auth_manager->access_token().empty());
// Note: Calling RegisterForAuthNotifications is illegal in local Sync mode,
// so we don't test that.
- // Calling Clear() does nothing, but shouldn't crash.
- auth_manager->Clear();
+ // Calling ConnectionClosed() does nothing, but shouldn't crash.
+ auth_manager->ConnectionClosed();
}
// ChromeOS doesn't support sign-in/sign-out.
@@ -169,6 +163,33 @@ TEST_F(SyncAuthManagerTest, ClearsAuthErrorOnSignout) {
EXPECT_EQ(auth_manager->GetLastAuthError().state(),
GoogleServiceAuthError::NONE);
}
+
+TEST_F(SyncAuthManagerTest, DoesNotClearAuthErrorOnSyncDisable) {
+ // Start out already signed in before the SyncAuthManager is created.
+ std::string account_id =
+ identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
+
+ auto auth_manager = CreateAuthManager();
+
+ auth_manager->RegisterForAuthNotifications();
+
+ ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+ account_id);
+ ASSERT_EQ(auth_manager->GetLastAuthError().state(),
+ GoogleServiceAuthError::NONE);
+
+ // Force an auth error by revoking the refresh token.
+ identity_env()->RemoveRefreshTokenForPrimaryAccount();
+ ASSERT_NE(auth_manager->GetLastAuthError().state(),
+ GoogleServiceAuthError::NONE);
+
+ // Now Sync gets turned off, e.g. because the user disabled it.
+ auth_manager->ConnectionClosed();
+
+ // Since the user is still signed in, the auth error should have remained.
+ EXPECT_NE(auth_manager->GetLastAuthError().state(),
+ GoogleServiceAuthError::NONE);
+}
#endif // !OS_CHROMEOS
TEST_F(SyncAuthManagerTest, ForwardsCredentialsEvents) {
@@ -346,6 +367,37 @@ TEST_F(SyncAuthManagerTest, ExposesServerError) {
EXPECT_EQ(auth_manager->GetCredentials().sync_token, "access_token");
}
+TEST_F(SyncAuthManagerTest, ClearsServerErrorOnSyncDisable) {
+ std::string account_id =
+ identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
+ auto auth_manager = CreateAuthManager();
+ auth_manager->RegisterForAuthNotifications();
+ ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+ account_id);
+
+ // During Sync startup, the SyncEngine attempts to connect to the server
+ // without an access token, resulting in a call to ConnectionStatusChanged
+ // with CONNECTION_AUTH_ERROR. This is what kicks off the initial access token
+ // fetch.
+ auth_manager->ConnectionStatusChanged(syncer::CONNECTION_AUTH_ERROR);
+ identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ "access_token", base::Time::Now() + base::TimeDelta::FromHours(1));
+ ASSERT_EQ(auth_manager->GetCredentials().sync_token, "access_token");
+
+ // A server error happens.
+ auth_manager->ConnectionStatusChanged(syncer::CONNECTION_SERVER_ERROR);
+ ASSERT_NE(auth_manager->GetLastAuthError(),
+ GoogleServiceAuthError::AuthErrorNone());
+
+ // Now Sync gets turned off, e.g. because the user disabled it.
+ auth_manager->ConnectionClosed();
+
+ // This should have cleared the auth error, because it was due to a server
+ // error which is now not meaningful anymore.
+ EXPECT_EQ(auth_manager->GetLastAuthError(),
+ GoogleServiceAuthError::AuthErrorNone());
+}
+
TEST_F(SyncAuthManagerTest, RequestsNewAccessTokenOnExpiry) {
std::string account_id =
identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id;
@@ -548,10 +600,7 @@ TEST_F(SyncAuthManagerTest, IgnoresCookieJarIfFeatureDisabled) {
TEST_F(SyncAuthManagerTest, UsesCookieJarIfFeatureEnabled) {
base::test::ScopedFeatureList features;
- features.InitWithFeatures(
- /*enabled_features=*/{switches::kSyncStandaloneTransport,
- switches::kSyncSupportSecondaryAccount},
- /*disabled_features=*/{});
+ features.InitAndEnableFeature(switches::kSyncSupportSecondaryAccount);
auto auth_manager = CreateAuthManager();
auth_manager->RegisterForAuthNotifications();
@@ -572,10 +621,7 @@ TEST_F(SyncAuthManagerTest, UsesCookieJarIfFeatureEnabled) {
TEST_F(SyncAuthManagerTest, DropsAccountWhenCookieGoesAway) {
base::test::ScopedFeatureList features;
- features.InitWithFeatures(
- /*enabled_features=*/{switches::kSyncStandaloneTransport,
- switches::kSyncSupportSecondaryAccount},
- /*disabled_features=*/{});
+ features.InitAndEnableFeature(switches::kSyncSupportSecondaryAccount);
auto auth_manager = CreateAuthManager();
auth_manager->RegisterForAuthNotifications();
@@ -601,10 +647,7 @@ TEST_F(SyncAuthManagerTest, DropsAccountWhenCookieGoesAway) {
TEST_F(SyncAuthManagerTest, DropsAccountWhenRefreshTokenGoesAway) {
base::test::ScopedFeatureList features;
- features.InitWithFeatures(
- /*enabled_features=*/{switches::kSyncStandaloneTransport,
- switches::kSyncSupportSecondaryAccount},
- /*disabled_features=*/{});
+ features.InitAndEnableFeature(switches::kSyncSupportSecondaryAccount);
auto auth_manager = CreateAuthManager();
auth_manager->RegisterForAuthNotifications();
@@ -630,10 +673,7 @@ TEST_F(SyncAuthManagerTest, DropsAccountWhenRefreshTokenGoesAway) {
TEST_F(SyncAuthManagerTest, PrefersPrimaryAccountOverCookie) {
base::test::ScopedFeatureList features;
- features.InitWithFeatures(
- /*enabled_features=*/{switches::kSyncStandaloneTransport,
- switches::kSyncSupportSecondaryAccount},
- /*disabled_features=*/{});
+ features.InitAndEnableFeature(switches::kSyncSupportSecondaryAccount);
auto auth_manager = CreateAuthManager();
auth_manager->RegisterForAuthNotifications();
@@ -659,10 +699,7 @@ TEST_F(SyncAuthManagerTest, PrefersPrimaryAccountOverCookie) {
TEST_F(SyncAuthManagerTest, OnlyUsesFirstCookieAccount) {
base::test::ScopedFeatureList features;
- features.InitWithFeatures(
- /*enabled_features=*/{switches::kSyncStandaloneTransport,
- switches::kSyncSupportSecondaryAccount},
- /*disabled_features=*/{});
+ features.InitAndEnableFeature(switches::kSyncSupportSecondaryAccount);
auto auth_manager = CreateAuthManager();
auth_manager->RegisterForAuthNotifications();
diff --git a/chromium/components/browser_sync/sync_user_settings_impl.cc b/chromium/components/browser_sync/sync_user_settings_impl.cc
deleted file mode 100644
index e01353a7d8c..00000000000
--- a/chromium/components/browser_sync/sync_user_settings_impl.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/browser_sync/sync_user_settings_impl.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "components/sync/base/sync_prefs.h"
-#include "components/sync/driver/sync_service_crypto.h"
-
-namespace browser_sync {
-
-SyncUserSettingsImpl::SyncUserSettingsImpl(
- syncer::SyncServiceCrypto* crypto,
- syncer::SyncPrefs* prefs,
- syncer::ModelTypeSet registered_types,
- const base::RepeatingCallback<void(bool)>& sync_allowed_by_platform_changed)
- : crypto_(crypto),
- prefs_(prefs),
- registered_types_(registered_types),
- sync_allowed_by_platform_changed_cb_(sync_allowed_by_platform_changed) {
- DCHECK(crypto_);
- DCHECK(prefs_);
-}
-
-SyncUserSettingsImpl::~SyncUserSettingsImpl() = default;
-
-bool SyncUserSettingsImpl::IsSyncRequested() const {
- return prefs_->IsSyncRequested();
-}
-
-void SyncUserSettingsImpl::SetSyncRequested(bool requested) {
- prefs_->SetSyncRequested(requested);
-}
-
-bool SyncUserSettingsImpl::IsSyncAllowedByPlatform() const {
- return sync_allowed_by_platform_;
-}
-
-void SyncUserSettingsImpl::SetSyncAllowedByPlatform(bool allowed) {
- if (sync_allowed_by_platform_ == allowed) {
- return;
- }
-
- sync_allowed_by_platform_ = allowed;
-
- sync_allowed_by_platform_changed_cb_.Run(sync_allowed_by_platform_);
-}
-
-bool SyncUserSettingsImpl::IsFirstSetupComplete() const {
- return prefs_->IsFirstSetupComplete();
-}
-
-void SyncUserSettingsImpl::SetFirstSetupComplete() {
- prefs_->SetFirstSetupComplete();
-}
-
-bool SyncUserSettingsImpl::IsSyncEverythingEnabled() const {
- return prefs_->HasKeepEverythingSynced();
-}
-
-syncer::ModelTypeSet SyncUserSettingsImpl::GetChosenDataTypes() const {
- syncer::ModelTypeSet types = GetPreferredDataTypes();
- types.RetainAll(syncer::UserSelectableTypes());
- return types;
-}
-
-void SyncUserSettingsImpl::SetChosenDataTypes(bool sync_everything,
- syncer::ModelTypeSet types) {
- DCHECK(syncer::UserSelectableTypes().HasAll(types));
-
- prefs_->SetDataTypesConfiguration(sync_everything, registered_types_, types);
-}
-
-bool SyncUserSettingsImpl::IsEncryptEverythingAllowed() const {
- return crypto_->IsEncryptEverythingAllowed();
-}
-
-void SyncUserSettingsImpl::SetEncryptEverythingAllowed(bool allowed) {
- crypto_->SetEncryptEverythingAllowed(allowed);
-}
-
-bool SyncUserSettingsImpl::IsEncryptEverythingEnabled() const {
- return crypto_->IsEncryptEverythingEnabled();
-}
-
-void SyncUserSettingsImpl::EnableEncryptEverything() {
- crypto_->EnableEncryptEverything();
-}
-
-bool SyncUserSettingsImpl::IsPassphraseRequired() const {
- return crypto_->passphrase_required_reason() !=
- syncer::REASON_PASSPHRASE_NOT_REQUIRED;
-}
-
-bool SyncUserSettingsImpl::IsPassphraseRequiredForDecryption() const {
- // If there is an encrypted datatype enabled and we don't have the proper
- // passphrase, we must prompt the user for a passphrase. The only way for the
- // user to avoid entering their passphrase is to disable the encrypted types.
- return IsEncryptedDatatypeEnabled() && IsPassphraseRequired();
-}
-
-bool SyncUserSettingsImpl::IsUsingSecondaryPassphrase() const {
- return crypto_->IsUsingSecondaryPassphrase();
-}
-
-base::Time SyncUserSettingsImpl::GetExplicitPassphraseTime() const {
- return crypto_->GetExplicitPassphraseTime();
-}
-
-syncer::PassphraseType SyncUserSettingsImpl::GetPassphraseType() const {
- return crypto_->GetPassphraseType();
-}
-
-void SyncUserSettingsImpl::SetEncryptionPassphrase(
- const std::string& passphrase) {
- crypto_->SetEncryptionPassphrase(passphrase);
-}
-
-bool SyncUserSettingsImpl::SetDecryptionPassphrase(
- const std::string& passphrase) {
- DCHECK(IsPassphraseRequired())
- << "SetDecryptionPassphrase must not be called when "
- "IsPassphraseRequired() is false.";
-
- DVLOG(1) << "Setting passphrase for decryption.";
-
- bool result = crypto_->SetDecryptionPassphrase(passphrase);
- UMA_HISTOGRAM_BOOLEAN("Sync.PassphraseDecryptionSucceeded", result);
- return result;
-}
-
-syncer::ModelTypeSet SyncUserSettingsImpl::GetPreferredDataTypes() const {
- syncer::ModelTypeSet types = Union(
- prefs_->GetPreferredDataTypes(registered_types_), syncer::ControlTypes());
- if (prefs_->IsLocalSyncEnabled()) {
- types.Remove(syncer::APP_LIST);
- types.Remove(syncer::USER_CONSENTS);
- types.Remove(syncer::USER_EVENTS);
- }
- return types;
-}
-
-syncer::ModelTypeSet SyncUserSettingsImpl::GetEncryptedDataTypes() const {
- return crypto_->GetEncryptedDataTypes();
-}
-
-bool SyncUserSettingsImpl::IsEncryptedDatatypeEnabled() const {
- if (IsEncryptionPending())
- return true;
- const syncer::ModelTypeSet preferred_types = GetPreferredDataTypes();
- const syncer::ModelTypeSet encrypted_types = GetEncryptedDataTypes();
- DCHECK(encrypted_types.Has(syncer::PASSWORDS));
- return !Intersection(preferred_types, encrypted_types).Empty();
-}
-
-bool SyncUserSettingsImpl::IsEncryptionPending() const {
- return crypto_->encryption_pending();
-}
-
-} // namespace browser_sync
diff --git a/chromium/components/browser_sync/sync_user_settings_impl.h b/chromium/components/browser_sync/sync_user_settings_impl.h
deleted file mode 100644
index 5ef1ea4e481..00000000000
--- a/chromium/components/browser_sync/sync_user_settings_impl.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_IMPL_H_
-#define COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_IMPL_H_
-
-#include <string>
-
-#include "components/sync/driver/sync_user_settings.h"
-
-#include "base/callback.h"
-#include "components/sync/base/model_type.h"
-
-namespace syncer {
-class SyncPrefs;
-class SyncServiceCrypto;
-}
-
-namespace browser_sync {
-
-class SyncUserSettingsImpl : public syncer::SyncUserSettings {
- public:
- // Both |crypto| and |prefs| must not be null, and must outlive this object.
- SyncUserSettingsImpl(syncer::SyncServiceCrypto* crypto,
- syncer::SyncPrefs* prefs,
- syncer::ModelTypeSet registered_types,
- const base::RepeatingCallback<void(bool)>&
- sync_allowed_by_platform_changed);
- ~SyncUserSettingsImpl() override;
-
- bool IsSyncRequested() const override;
- void SetSyncRequested(bool requested) override;
-
- bool IsSyncAllowedByPlatform() const override;
- void SetSyncAllowedByPlatform(bool allowed) override;
-
- bool IsFirstSetupComplete() const override;
- void SetFirstSetupComplete() override;
-
- bool IsSyncEverythingEnabled() const override;
- syncer::ModelTypeSet GetChosenDataTypes() const override;
- void SetChosenDataTypes(bool sync_everything,
- syncer::ModelTypeSet types) override;
-
- bool IsEncryptEverythingAllowed() const override;
- void SetEncryptEverythingAllowed(bool allowed) override;
- bool IsEncryptEverythingEnabled() const override;
- void EnableEncryptEverything() override;
-
- bool IsPassphraseRequired() const override;
- bool IsPassphraseRequiredForDecryption() const override;
- bool IsUsingSecondaryPassphrase() const override;
- base::Time GetExplicitPassphraseTime() const override;
- syncer::PassphraseType GetPassphraseType() const override;
-
- void SetEncryptionPassphrase(const std::string& passphrase) override;
- bool SetDecryptionPassphrase(const std::string& passphrase) override;
-
- syncer::ModelTypeSet GetPreferredDataTypes() const;
- syncer::ModelTypeSet GetEncryptedDataTypes() const;
- bool IsEncryptedDatatypeEnabled() const;
- bool IsEncryptionPending() const;
-
- private:
- syncer::SyncServiceCrypto* const crypto_;
- syncer::SyncPrefs* const prefs_;
- const syncer::ModelTypeSet registered_types_;
- base::RepeatingCallback<void(bool)> sync_allowed_by_platform_changed_cb_;
-
- // Whether sync is currently allowed on this platform.
- bool sync_allowed_by_platform_ = true;
-};
-
-} // namespace browser_sync
-
-#endif // COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_IMPL_H_
diff --git a/chromium/components/browser_sync/sync_user_settings_mock.cc b/chromium/components/browser_sync/sync_user_settings_mock.cc
deleted file mode 100644
index 6a5c19937a8..00000000000
--- a/chromium/components/browser_sync/sync_user_settings_mock.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/browser_sync/sync_user_settings_mock.h"
-
-namespace browser_sync {
-
-SyncUserSettingsMock::SyncUserSettingsMock() = default;
-
-SyncUserSettingsMock::~SyncUserSettingsMock() = default;
-
-} // namespace browser_sync
diff --git a/chromium/components/browser_sync/sync_user_settings_mock.h b/chromium/components/browser_sync/sync_user_settings_mock.h
deleted file mode 100644
index 2d5b6351c0b..00000000000
--- a/chromium/components/browser_sync/sync_user_settings_mock.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_MOCK_H_
-#define COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_MOCK_H_
-
-#include <string>
-
-#include "components/sync/driver/sync_user_settings.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace browser_sync {
-
-class SyncUserSettingsMock : public syncer::SyncUserSettings {
- public:
- SyncUserSettingsMock();
- ~SyncUserSettingsMock() override;
-
- MOCK_CONST_METHOD0(IsSyncRequested, bool());
- MOCK_METHOD1(SetSyncRequested, void(bool));
-
- MOCK_CONST_METHOD0(IsSyncAllowedByPlatform, bool());
- MOCK_METHOD1(SetSyncAllowedByPlatform, void(bool));
-
- MOCK_CONST_METHOD0(IsFirstSetupComplete, bool());
- MOCK_METHOD0(SetFirstSetupComplete, void());
-
- MOCK_CONST_METHOD0(IsSyncEverythingEnabled, bool());
- MOCK_CONST_METHOD0(GetChosenDataTypes, syncer::ModelTypeSet());
- MOCK_METHOD2(SetChosenDataTypes, void(bool, syncer::ModelTypeSet));
-
- MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool());
- MOCK_METHOD1(SetEncryptEverythingAllowed, void(bool));
- MOCK_CONST_METHOD0(IsEncryptEverythingEnabled, bool());
- MOCK_METHOD0(EnableEncryptEverything, void());
-
- MOCK_CONST_METHOD0(IsPassphraseRequired, bool());
- MOCK_CONST_METHOD0(IsPassphraseRequiredForDecryption, bool());
- MOCK_CONST_METHOD0(IsUsingSecondaryPassphrase, bool());
- MOCK_CONST_METHOD0(GetExplicitPassphraseTime, base::Time());
- MOCK_CONST_METHOD0(GetPassphraseType, syncer::PassphraseType());
-
- MOCK_METHOD1(SetEncryptionPassphrase, void(const std::string&));
- MOCK_METHOD1(SetDecryptionPassphrase, bool(const std::string&));
-};
-
-} // namespace browser_sync
-
-#endif // COMPONENTS_BROWSER_SYNC_SYNC_USER_SETTINGS_MOCK_H_
diff --git a/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc b/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
index 86e2ee7df9d..2086aab75cc 100644
--- a/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
+++ b/chromium/components/browser_watcher/postmortem_report_collector_unittest.cc
@@ -209,12 +209,12 @@ TEST_P(PostmortemReportCollectorProcessTest, ProcessStuckFile) {
ValidateHistograms(expected_unclean, expected_system_unclean);
}
-INSTANTIATE_TEST_CASE_P(WithCrashDatabase,
- PostmortemReportCollectorProcessTest,
- ::testing::Values(true));
-INSTANTIATE_TEST_CASE_P(WithoutCrashDatabase,
- PostmortemReportCollectorProcessTest,
- ::testing::Values(true));
+INSTANTIATE_TEST_SUITE_P(WithCrashDatabase,
+ PostmortemReportCollectorProcessTest,
+ ::testing::Values(true));
+INSTANTIATE_TEST_SUITE_P(WithoutCrashDatabase,
+ PostmortemReportCollectorProcessTest,
+ ::testing::Values(true));
TEST(PostmortemReportCollectorTest, CollectEmptyFile) {
// Create an empty file.
diff --git a/chromium/components/browser_watcher/window_hang_monitor_win.cc b/chromium/components/browser_watcher/window_hang_monitor_win.cc
index 739a46ea054..a00df383218 100644
--- a/chromium/components/browser_watcher/window_hang_monitor_win.cc
+++ b/chromium/components/browser_watcher/window_hang_monitor_win.cc
@@ -5,6 +5,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/location.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 f4827ed38f5..8881f97e34f 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/bind.h"
#include "base/command_line.h"
#include "base/path_service.h"
#include "base/process/launch.h"
@@ -75,7 +76,7 @@ void AppendSwitchHandle(base::CommandLine* command_line,
std::string switch_name,
HANDLE handle) {
command_line->AppendSwitchASCII(
- switch_name, base::UintToString(base::win::HandleToUint32(handle)));
+ switch_name, base::NumberToString(base::win::HandleToUint32(handle)));
}
// Retrieves the |handle| associated to |switch_name| from the command line.
@@ -150,8 +151,9 @@ class MonitoredProcessClient {
base::WaitableEvent::InitialState::NOT_SIGNALED);
ASSERT_TRUE(message_window_thread_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&MonitoredProcessClient::CreateMessageWindowInWorkerThread,
- base::Unretained(this), &succeeded, &created)));
+ base::BindOnce(
+ &MonitoredProcessClient::CreateMessageWindowInWorkerThread,
+ base::Unretained(this), &succeeded, &created)));
created.Wait();
ASSERT_TRUE(succeeded);
}
@@ -159,8 +161,8 @@ class MonitoredProcessClient {
// Creates a thread then creates the message window on it.
void HangMessageWindow() {
message_window_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&base::WaitableEvent::Wait, base::Unretained(&hang_event_)));
+ FROM_HERE, base::BindOnce(&base::WaitableEvent::Wait,
+ base::Unretained(&hang_event_)));
}
bool SendSignalToParent(IPCSignal ipc_signal) {
@@ -200,8 +202,9 @@ class MonitoredProcessClient {
base::WaitableEvent::InitialState::NOT_SIGNALED);
message_window_thread_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&MonitoredProcessClient::DeleteMessageWindowInWorkerThread,
- base::Unretained(this), &deleted));
+ base::BindOnce(
+ &MonitoredProcessClient::DeleteMessageWindowInWorkerThread,
+ base::Unretained(this), &deleted));
deleted.Wait();
message_window_thread_.Stop();
@@ -292,8 +295,8 @@ class HangMonitorThread {
// operation completes.
void DestroyWatcher() {
thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&HangMonitorThread::ShutdownOnThread,
- base::Unretained(this)));
+ FROM_HERE, base::BindOnce(&HangMonitorThread::ShutdownOnThread,
+ base::Unretained(this)));
// This will block until the above-posted task completes.
thread_.Stop();
}
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 9cc0f3b8e07..a6fe6420bec 100644
--- a/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc
+++ b/chromium/components/browsing_data/content/conditional_cache_counting_helper.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
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 aa2f13698e5..f494e54051a 100644
--- a/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc
+++ b/chromium/components/browsing_data/core/browsing_data_utils_unittest.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind_helpers.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
@@ -167,4 +168,4 @@ TEST_F(BrowsingDataUtilsTest, HistoryCounterResult) {
}
}
-} // namespace browsing_data \ No newline at end of file
+} // namespace browsing_data
diff --git a/chromium/components/browsing_data/core/counters/autofill_counter.cc b/chromium/components/browsing_data/core/counters/autofill_counter.cc
index 7899e7bd0ea..87d7f268bac 100644
--- a/chromium/components/browsing_data/core/counters/autofill_counter.cc
+++ b/chromium/components/browsing_data/core/counters/autofill_counter.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.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"
diff --git a/chromium/components/browsing_data/core/counters/bookmark_counter.cc b/chromium/components/browsing_data/core/counters/bookmark_counter.cc
index c97d37ff392..ab1da23e77d 100644
--- a/chromium/components/browsing_data/core/counters/bookmark_counter.cc
+++ b/chromium/components/browsing_data/core/counters/bookmark_counter.cc
@@ -4,6 +4,7 @@
#include "components/browsing_data/core/counters/bookmark_counter.h"
+#include "base/bind.h"
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
@@ -41,7 +42,7 @@ class BookmarkModelHelper : public bookmarks::BaseBookmarkModelObserver {
bool ids_reassigned) override {
std::move(callback_).Run(model);
delete this;
- };
+ }
void BookmarkModelBeingDeleted(
bookmarks::BookmarkModel* bookmark_model) override {
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 86405559767..8a4b271bf0c 100644
--- a/chromium/components/browsing_data/core/counters/browsing_data_counter.cc
+++ b/chromium/components/browsing_data/core/counters/browsing_data_counter.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/trace_event/trace_event.h"
#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/pref_names.h"
diff --git a/chromium/components/browsing_data/core/counters/browsing_data_counter_unittest.cc b/chromium/components/browsing_data/core/counters/browsing_data_counter_unittest.cc
index 4bafa9eeddc..60ddc66c7bf 100644
--- a/chromium/components/browsing_data/core/counters/browsing_data_counter_unittest.cc
+++ b/chromium/components/browsing_data/core/counters/browsing_data_counter_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/browsing_data/core/counters/history_counter.cc b/chromium/components/browsing_data/core/counters/history_counter.cc
index dfa5433862f..99d27449046 100644
--- a/chromium/components/browsing_data/core/counters/history_counter.cc
+++ b/chromium/components/browsing_data/core/counters/history_counter.cc
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <memory>
+#include "base/bind.h"
#include "base/timer/timer.h"
#include "components/browsing_data/core/pref_names.h"
diff --git a/chromium/components/browsing_data/core/counters/passwords_counter.cc b/chromium/components/browsing_data/core/counters/passwords_counter.cc
index eac911c7e5a..98b5a564ba9 100644
--- a/chromium/components/browsing_data/core/counters/passwords_counter.cc
+++ b/chromium/components/browsing_data/core/counters/passwords_counter.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.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"
diff --git a/chromium/components/browsing_data/core/counters/passwords_counter.h b/chromium/components/browsing_data/core/counters/passwords_counter.h
index 901a07c2b10..7cfab40c5c6 100644
--- a/chromium/components/browsing_data/core/counters/passwords_counter.h
+++ b/chromium/components/browsing_data/core/counters/passwords_counter.h
@@ -29,7 +29,7 @@ class PasswordsCounter : public browsing_data::BrowsingDataCounter,
protected:
virtual std::unique_ptr<SyncResult> MakeResult();
- bool is_sync_active() { return sync_tracker_.IsSyncActive(); };
+ bool is_sync_active() { return sync_tracker_.IsSyncActive(); }
int num_passwords() { return num_passwords_; }
private:
diff --git a/chromium/components/browsing_data/core/history_notice_utils.cc b/chromium/components/browsing_data/core/history_notice_utils.cc
index 0254b5a55aa..379df8e8187 100644
--- a/chromium/components/browsing_data/core/history_notice_utils.cc
+++ b/chromium/components/browsing_data/core/history_notice_utils.cc
@@ -12,6 +12,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "components/history/core/browser/web_history_service.h"
#include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/sync_user_settings.h"
#include "components/version_info/version_info.h"
namespace {
@@ -60,7 +61,8 @@ void ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
if (!sync_service || !sync_service->IsSyncFeatureActive() ||
!sync_service->GetActiveDataTypes().Has(
syncer::HISTORY_DELETE_DIRECTIVES) ||
- sync_service->IsUsingSecondaryPassphrase() || !history_service) {
+ sync_service->GetUserSettings()->IsUsingSecondaryPassphrase() ||
+ !history_service) {
callback.Run(false);
return;
}
@@ -101,7 +103,8 @@ void ShouldPopupDialogAboutOtherFormsOfBrowsingHistory(
if (!sync_service || !sync_service->IsSyncFeatureActive() ||
!sync_service->GetActiveDataTypes().Has(
syncer::HISTORY_DELETE_DIRECTIVES) ||
- sync_service->IsUsingSecondaryPassphrase() || !history_service) {
+ sync_service->GetUserSettings()->IsUsingSecondaryPassphrase() ||
+ !history_service) {
callback.Run(false);
return;
}
diff --git a/chromium/components/captive_portal/captive_portal_detector.cc b/chromium/components/captive_portal/captive_portal_detector.cc
index 2902eb34d3e..4adf47f9b6e 100644
--- a/chromium/components/captive_portal/captive_portal_detector.cc
+++ b/chromium/components/captive_portal/captive_portal_detector.cc
@@ -4,6 +4,7 @@
#include "components/captive_portal/captive_portal_detector.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
diff --git a/chromium/components/cast_certificate/cast_crl.h b/chromium/components/cast_certificate/cast_crl.h
index df0f8afa24e..46daaecf562 100644
--- a/chromium/components/cast_certificate/cast_crl.h
+++ b/chromium/components/cast_certificate/cast_crl.h
@@ -23,7 +23,7 @@ namespace cast_certificate {
// This class represents the CRL information parsed from the binary proto.
class CastCRL {
public:
- virtual ~CastCRL(){};
+ virtual ~CastCRL() {}
// Verifies the revocation status of a cast device certificate given a chain
// of X.509 certificates.
diff --git a/chromium/components/cast_channel/BUILD.gn b/chromium/components/cast_channel/BUILD.gn
index c0b0b24b408..b0e2993d239 100644
--- a/chromium/components/cast_channel/BUILD.gn
+++ b/chromium/components/cast_channel/BUILD.gn
@@ -22,6 +22,8 @@ static_library("cast_channel") {
"cast_socket_service.h",
"cast_transport.cc",
"cast_transport.h",
+ "enum_table.cc",
+ "enum_table.h",
"keep_alive_delegate.cc",
"keep_alive_delegate.h",
"logger.cc",
@@ -76,6 +78,7 @@ source_set("unit_tests") {
"cast_socket_service_unittest.cc",
"cast_socket_unittest.cc",
"cast_transport_unittest.cc",
+ "enum_table_unittest.cc",
"keep_alive_delegate_unittest.cc",
"logger_unittest.cc",
]
diff --git a/chromium/components/cast_channel/cast_auth_util.cc b/chromium/components/cast_channel/cast_auth_util.cc
index 78404746189..fb9df96fdc8 100644
--- a/chromium/components/cast_channel/cast_auth_util.cc
+++ b/chromium/components/cast_channel/cast_auth_util.cc
@@ -89,7 +89,7 @@ AuthResult ParseAuthMessage(const CastMessage& challenge_reply,
if (auth_message->has_error()) {
return AuthResult::CreateWithParseError(
"Auth message error: " +
- base::IntToString(auth_message->error().error_type()),
+ base::NumberToString(auth_message->error().error_type()),
AuthResult::ERROR_MESSAGE_ERROR);
}
if (!auth_message->has_response()) {
diff --git a/chromium/components/cast_channel/cast_framer.cc b/chromium/components/cast_channel/cast_framer.cc
index b2830b9a91e..f6024ed64b7 100644
--- a/chromium/components/cast_channel/cast_framer.cc
+++ b/chromium/components/cast_channel/cast_framer.cc
@@ -68,8 +68,7 @@ size_t MessageFramer::MessageHeader::max_message_size() {
}
std::string MessageFramer::MessageHeader::ToString() {
- return "{message_size: " +
- base::UintToString(static_cast<uint32_t>(message_size)) + "}";
+ return "{message_size: " + base::NumberToString(message_size) + "}";
}
// static
diff --git a/chromium/components/cast_channel/cast_message_handler.cc b/chromium/components/cast_channel/cast_message_handler.cc
index 988ac760fe1..8baa632eead 100644
--- a/chromium/components/cast_channel/cast_message_handler.cc
+++ b/chromium/components/cast_channel/cast_message_handler.cc
@@ -6,7 +6,9 @@
#include <tuple>
#include <utility>
+#include <vector>
+#include "base/bind.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/default_tick_clock.h"
@@ -190,9 +192,11 @@ void CastMessageHandler::LaunchSession(int channel_id,
}
}
-void CastMessageHandler::StopSession(int channel_id,
- const std::string& session_id,
- ResultCallback callback) {
+void CastMessageHandler::StopSession(
+ int channel_id,
+ const std::string& session_id,
+ const base::Optional<std::string>& client_id,
+ ResultCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CastSocket* socket = socket_service_->GetSocket(channel_id);
if (!socket) {
@@ -206,8 +210,8 @@ void CastMessageHandler::StopSession(int channel_id,
<< ", request_id: " << request_id;
if (requests->AddStopRequest(std::make_unique<StopSessionRequest>(
request_id, std::move(callback), clock_))) {
- SendCastMessage(socket,
- CreateStopRequest(sender_id_, request_id, session_id));
+ SendCastMessage(socket, CreateStopRequest(client_id.value_or(sender_id_),
+ request_id, session_id));
}
}
diff --git a/chromium/components/cast_channel/cast_message_handler.h b/chromium/components/cast_channel/cast_message_handler.h
index 3a7b48e5212..902330217fe 100644
--- a/chromium/components/cast_channel/cast_message_handler.h
+++ b/chromium/components/cast_channel/cast_message_handler.h
@@ -11,8 +11,10 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/tick_clock.h"
+#include "base/timer/timer.h"
#include "base/token.h"
#include "base/values.h"
#include "components/cast_channel/cast_message_util.h"
@@ -175,6 +177,7 @@ class CastMessageHandler : public CastSocket::Observer {
// request.
virtual void StopSession(int channel_id,
const std::string& session_id,
+ const base::Optional<std::string>& client_id,
ResultCallback callback);
// Sends |message| to the device given by |channel_id|. The caller may use
diff --git a/chromium/components/cast_channel/cast_message_handler_unittest.cc b/chromium/components/cast_channel/cast_message_handler_unittest.cc
index b547907089d..908f75e9d30 100644
--- a/chromium/components/cast_channel/cast_message_handler_unittest.cc
+++ b/chromium/components/cast_channel/cast_message_handler_unittest.cc
@@ -4,6 +4,8 @@
#include "components/cast_channel/cast_message_handler.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
@@ -19,7 +21,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using base::test::IsJson;
-using base::test::ParseJson;
+using base::test::ParseJsonDeprecated;
using testing::_;
using testing::AnyNumber;
using testing::InSequence;
@@ -42,7 +44,7 @@ std::unique_ptr<base::Value> GetDictionaryFromCastMessage(
if (!message.has_payload_utf8())
return nullptr;
- return base::JSONReader::Read(message.payload_utf8());
+ return base::JSONReader::ReadDeprecated(message.payload_utf8());
}
CastMessageType GetMessageType(const CastMessage& message) {
@@ -138,11 +140,11 @@ class CastMessageHandlerTest : public testing::Test {
Result::kOk,
handler_.SendSetVolumeRequest(
channel_id_,
- *ParseJson(
+ *ParseJsonDeprecated(
R"({"sessionId": "theSessionId", "type": "SET_VOLUME"})"),
"theSourceId", set_volume_callback_.Get()));
}
- handler_.StopSession(channel_id_, "theSessionId",
+ handler_.StopSession(channel_id_, "theSessionId", "theSourceId",
stop_session_callback_.Get());
}
@@ -374,8 +376,9 @@ TEST_F(CastMessageHandlerTest, SendMediaRequest) {
"requestId": 1,
"type": "PLAY",
})";
- auto expected = CreateMediaRequest(*ParseJson(expected_body), 1,
- "theSourceId", "theDestinationId");
+ auto expected =
+ CreateMediaRequest(*ParseJsonDeprecated(expected_body), 1,
+ "theSourceId", "theDestinationId");
EXPECT_EQ(expected.namespace_(), message.namespace_());
EXPECT_EQ(expected.source_id(), message.source_id());
EXPECT_EQ(expected.destination_id(), message.destination_id());
@@ -390,8 +393,9 @@ TEST_F(CastMessageHandlerTest, SendMediaRequest) {
std::string message_str = R"({
"type": "PLAY",
})";
- base::Optional<int> request_id = handler_.SendMediaRequest(
- channel_id_, *ParseJson(message_str), "theSourceId", "theDestinationId");
+ base::Optional<int> request_id =
+ handler_.SendMediaRequest(channel_id_, *ParseJsonDeprecated(message_str),
+ "theSourceId", "theDestinationId");
EXPECT_EQ(1, request_id);
}
@@ -407,8 +411,8 @@ TEST_F(CastMessageHandlerTest, SendVolumeCommand) {
"requestId": 1,
"type": "SET_VOLUME",
})";
- auto expected = CreateSetVolumeRequest(*ParseJson(expected_body), 1,
- "theSourceId");
+ auto expected = CreateSetVolumeRequest(
+ *ParseJsonDeprecated(expected_body), 1, "theSourceId");
EXPECT_EQ(expected.namespace_(), message.namespace_());
EXPECT_EQ(expected.source_id(), message.source_id());
EXPECT_EQ(expected.destination_id(), message.destination_id());
@@ -425,7 +429,7 @@ TEST_F(CastMessageHandlerTest, SendVolumeCommand) {
"type": "SET_VOLUME",
})";
EXPECT_EQ(Result::kOk, handler_.SendSetVolumeRequest(
- channel_id_, *ParseJson(message_str),
+ channel_id_, *ParseJsonDeprecated(message_str),
"theSourceId", base::DoNothing::Once<Result>()));
}
@@ -470,7 +474,7 @@ TEST_F(CastMessageHandlerTest, HandlePendingRequest) {
// Handle pending launch session request.
handler_.HandleCastInternalMessage(channel_id_, "theSourceId",
- "theDestinationId", ParseJson(R"(
+ "theDestinationId", ParseJsonDeprecated(R"(
{
"requestId": 1,
"type": "RECEIVER_STATUS",
@@ -479,29 +483,29 @@ TEST_F(CastMessageHandlerTest, HandlePendingRequest) {
// Handle both pending get app availability requests.
handler_.HandleCastInternalMessage(channel_id_, "theSourceId",
- "theDestinationId", ParseJson(R"(
+ "theDestinationId", ParseJsonDeprecated(R"(
{
"requestId": 2,
"availability": {"theAppId": "APP_AVAILABLE"},
})"));
// Handle pending set volume request (1 of 2).
- handler_.HandleCastInternalMessage(channel_id_, "theSourceId",
- "theDestinationId",
- ParseJson(R"({"requestId": 3})"));
+ handler_.HandleCastInternalMessage(
+ channel_id_, "theSourceId", "theDestinationId",
+ ParseJsonDeprecated(R"({"requestId": 3})"));
// Skip request_id == 4, since it was used by the second get app availability
// request.
// Handle pending set volume request (2 of 2).
- handler_.HandleCastInternalMessage(channel_id_, "theSourceId",
- "theDestinationId",
- ParseJson(R"({"requestId": 5})"));
+ handler_.HandleCastInternalMessage(
+ channel_id_, "theSourceId", "theDestinationId",
+ ParseJsonDeprecated(R"({"requestId": 5})"));
// Handle pending stop session request.
- handler_.HandleCastInternalMessage(channel_id_, "theSourceId",
- "theDestinationId",
- ParseJson(R"({"requestId": 6})"));
+ handler_.HandleCastInternalMessage(
+ channel_id_, "theSourceId", "theDestinationId",
+ ParseJsonDeprecated(R"({"requestId": 6})"));
}
// Check that set volume requests time out correctly.
@@ -513,9 +517,9 @@ TEST_F(CastMessageHandlerTest, SetVolumeTimedOut) {
"type": "SET_VOLUME",
})";
base::MockCallback<ResultCallback> callback;
- EXPECT_EQ(Result::kOk,
- handler_.SendSetVolumeRequest(channel_id_, *ParseJson(message_str),
- "theSourceId", callback.Get()));
+ EXPECT_EQ(Result::kOk, handler_.SendSetVolumeRequest(
+ channel_id_, *ParseJsonDeprecated(message_str),
+ "theSourceId", callback.Get()));
EXPECT_CALL(callback, Run(Result::kFailed));
thread_bundle_.FastForwardBy(kRequestTimeout);
}
diff --git a/chromium/components/cast_channel/cast_message_util.cc b/chromium/components/cast_channel/cast_message_util.cc
index ad65f61ee93..5ebf3a948c7 100644
--- a/chromium/components/cast_channel/cast_message_util.cc
+++ b/chromium/components/cast_channel/cast_message_util.cc
@@ -12,52 +12,67 @@
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/enum_table.h"
#include "components/cast_channel/proto/cast_channel.pb.h"
using base::Value;
+using cast_util::EnumToString;
+using cast_util::StringToEnum;
+
+namespace cast_util {
+
+using namespace cast_channel;
+
+template <>
+const EnumTable<CastMessageType> EnumTable<CastMessageType>::instance({
+ {CastMessageType::kPing, "PING"},
+ {CastMessageType::kPong, "PONG"},
+ {CastMessageType::kGetAppAvailability, "GET_APP_AVAILABILITY"},
+ {CastMessageType::kReceiverStatusRequest, "GET_STATUS"},
+ {CastMessageType::kConnect, "CONNECT"},
+ {CastMessageType::kCloseConnection, "CLOSE"},
+ {CastMessageType::kBroadcast, "APPLICATION_BROADCAST"},
+ {CastMessageType::kLaunch, "LAUNCH"},
+ {CastMessageType::kStop, "STOP"},
+ {CastMessageType::kReceiverStatus, "RECEIVER_STATUS"},
+ {CastMessageType::kMediaStatus, "MEDIA_STATUS"},
+ {CastMessageType::kLaunchError, "LAUNCH_ERROR"},
+});
+
+template <>
+const EnumTable<V2MessageType> EnumTable<V2MessageType>::instance({
+ {V2MessageType::kEditTracksInfo, "EDIT_TRACKS_INFO"},
+ {V2MessageType::kGetStatus, "GET_STATUS"},
+ {V2MessageType::kLoad, "LOAD"},
+ {V2MessageType::kMediaGetStatus, "MEDIA_GET_STATUS"},
+ {V2MessageType::kMediaSetVolume, "MEDIA_SET_VOLUME"},
+ {V2MessageType::kPause, "PAUSE"},
+ {V2MessageType::kPlay, "PLAY"},
+ {V2MessageType::kPrecache, "PRECACHE"},
+ {V2MessageType::kQueueInsert, "QUEUE_INSERT"},
+ {V2MessageType::kQueueLoad, "QUEUE_LOAD"},
+ {V2MessageType::kQueueRemove, "QUEUE_REMOVE"},
+ {V2MessageType::kQueueReorder, "QUEUE_REORDER"},
+ {V2MessageType::kQueueUpdate, "QUEUE_UPDATE"},
+ {V2MessageType::kSeek, "SEEK"},
+ {V2MessageType::kSetVolume, "SET_VOLUME"},
+ {V2MessageType::kStop, "STOP"},
+ {V2MessageType::kStopMedia, "STOP_MEDIA"},
+});
+
+template <>
+const EnumTable<GetAppAvailabilityResult>
+ EnumTable<GetAppAvailabilityResult>::instance({
+ {GetAppAvailabilityResult::kAvailable, "APP_AVAILABLE"},
+ {GetAppAvailabilityResult::kUnavailable, "APP_UNAVAILABLE"},
+ });
+
+} // namespace cast_util
namespace cast_channel {
namespace {
-// String values for CastMessageType enum.
-constexpr char kCastMessageTypePingString[] = "PING";
-constexpr char kCastMessageTypePongString[] = "PONG";
-constexpr char kCastMessageTypeGetAppAvailabilityString[] =
- "GET_APP_AVAILABILITY";
-constexpr char kCastMessageTypeReceiverStatusRequestString[] = "GET_STATUS";
-constexpr char kCastMessageTypeConnectString[] = "CONNECT";
-constexpr char kCastMessageTypeCloseConnectionString[] = "CLOSE";
-constexpr char kCastMessageTypeBroadcastString[] = "APPLICATION_BROADCAST";
-constexpr char kCastMessageTypeLaunchString[] = "LAUNCH";
-constexpr char kCastMessageTypeStopString[] = "STOP";
-constexpr char kCastMessageTypeReceiverStatusString[] = "RECEIVER_STATUS";
-constexpr char kCastMessageTypeMediaStatusString[] = "MEDIA_STATUS";
-constexpr char kCastMessageTypeLaunchErrorString[] = "LAUNCH_ERROR";
-
-// String values for V2MessageType enum.
-constexpr char kV2MessageTypeEditTracksInfoString[] = "EDIT_TRACKS_INFO";
-constexpr char kV2MessageTypeGetStatusString[] = "GET_STATUS";
-constexpr char kV2MessageTypeLoadString[] = "LOAD";
-constexpr char kV2MessageTypeMediaGetStatusString[] = "MEDIA_GET_STATUS";
-constexpr char kV2MessageTypeMediaSetVolumeString[] = "MEDIA_SET_VOLUME";
-constexpr char kV2MessageTypePauseString[] = "PAUSE";
-constexpr char kV2MessageTypePlayString[] = "PLAY";
-constexpr char kV2MessageTypePrecacheString[] = "PRECACHE";
-constexpr char kV2MessageTypeQueueInsertString[] = "QUEUE_INSERT";
-constexpr char kV2MessageTypeQueueLoadString[] = "QUEUE_LOAD";
-constexpr char kV2MessageTypeQueueRemoveString[] = "QUEUE_REMOVE";
-constexpr char kV2MessageTypeQueueReorderString[] = "QUEUE_REORDER";
-constexpr char kV2MessageTypeQueueUpdateString[] = "QUEUE_UPDATE";
-constexpr char kV2MessageTypeSeekString[] = "SEEK";
-constexpr char kV2MessageTypeSetVolumeString[] = "SET_VOLUME";
-constexpr char kV2MessageTypeStopString[] = "STOP";
-constexpr char kV2MessageTypeStopMediaString[] = "STOP_MEDIA";
-
-// String values for GetAppAvailabilityResult enum.
-constexpr char kGetAppAvailabilityResultAvailableString[] = "APP_AVAILABLE";
-constexpr char kGetAppAvailabilityResultUnavailableString[] = "APP_UNAVAILABLE";
-
// The value used for "sdkType" in a virtual connect request. Historically, this
// value is used in the Media Router extension, but here it is reused in Chrome.
constexpr int kVirtualConnectSdkType = 2;
@@ -104,25 +119,25 @@ int GetVirtualConnectPlatformValue() {
// Cast V2 protocol. This is necessary because the protocol defines messages
// with the same type in different namespaces, and the namespace is lost when
// messages are passed using a CastInternalMessage object.
-std::string GetRemappedMediaRequestType(const std::string& v2_message_type) {
- V2MessageType type = V2MessageTypeFromString(v2_message_type);
- DCHECK(IsMediaRequestMessageType(type));
- const char* result;
- switch (type) {
+base::StringPiece GetRemappedMediaRequestType(
+ base::StringPiece v2_message_type) {
+ base::Optional<V2MessageType> type =
+ StringToEnum<V2MessageType>(v2_message_type);
+ DCHECK(type && IsMediaRequestMessageType(*type));
+ switch (*type) {
case V2MessageType::kStopMedia:
- result = ToString(V2MessageType::kStop);
+ type = V2MessageType::kStop;
break;
case V2MessageType::kMediaSetVolume:
- result = ToString(V2MessageType::kSetVolume);
+ type = V2MessageType::kSetVolume;
break;
case V2MessageType::kMediaGetStatus:
- result = ToString(V2MessageType::kGetStatus);
+ type = V2MessageType::kGetStatus;
break;
default:
return v2_message_type;
}
- DCHECK(result);
- return result;
+ return *EnumToString(*type);
}
} // namespace
@@ -155,141 +170,21 @@ CastMessageType ParseMessageTypeFromPayload(const base::Value& payload) {
}
const char* ToString(CastMessageType message_type) {
- switch (message_type) {
- case CastMessageType::kPing:
- return kCastMessageTypePingString;
- case CastMessageType::kPong:
- return kCastMessageTypePongString;
- case CastMessageType::kGetAppAvailability:
- return kCastMessageTypeGetAppAvailabilityString;
- case CastMessageType::kReceiverStatusRequest:
- return kCastMessageTypeReceiverStatusRequestString;
- case CastMessageType::kConnect:
- return kCastMessageTypeConnectString;
- case CastMessageType::kCloseConnection:
- return kCastMessageTypeCloseConnectionString;
- case CastMessageType::kBroadcast:
- return kCastMessageTypeBroadcastString;
- case CastMessageType::kLaunch:
- return kCastMessageTypeLaunchString;
- case CastMessageType::kStop:
- return kCastMessageTypeStopString;
- case CastMessageType::kReceiverStatus:
- return kCastMessageTypeReceiverStatusString;
- case CastMessageType::kMediaStatus:
- return kCastMessageTypeMediaStatusString;
- case CastMessageType::kLaunchError:
- return kCastMessageTypeLaunchErrorString;
- default:
- return "";
- }
+ return EnumToString(message_type).value_or("").data();
}
const char* ToString(V2MessageType message_type) {
- switch (message_type) {
- case V2MessageType::kEditTracksInfo:
- return kV2MessageTypeEditTracksInfoString;
- case V2MessageType::kGetStatus:
- return kV2MessageTypeGetStatusString;
- case V2MessageType::kLoad:
- return kV2MessageTypeLoadString;
- case V2MessageType::kMediaGetStatus:
- return kV2MessageTypeMediaGetStatusString;
- case V2MessageType::kMediaSetVolume:
- return kV2MessageTypeMediaSetVolumeString;
- case V2MessageType::kPause:
- return kV2MessageTypePauseString;
- case V2MessageType::kPlay:
- return kV2MessageTypePlayString;
- case V2MessageType::kPrecache:
- return kV2MessageTypePrecacheString;
- case V2MessageType::kQueueInsert:
- return kV2MessageTypeQueueInsertString;
- case V2MessageType::kQueueLoad:
- return kV2MessageTypeQueueLoadString;
- case V2MessageType::kQueueRemove:
- return kV2MessageTypeQueueRemoveString;
- case V2MessageType::kQueueReorder:
- return kV2MessageTypeQueueReorderString;
- case V2MessageType::kQueueUpdate:
- return kV2MessageTypeQueueUpdateString;
- case V2MessageType::kSeek:
- return kV2MessageTypeSeekString;
- case V2MessageType::kSetVolume:
- return kV2MessageTypeSetVolumeString;
- case V2MessageType::kStop:
- return kV2MessageTypeStopString;
- case V2MessageType::kStopMedia:
- return kV2MessageTypeStopMediaString;
- default:
- return nullptr;
- }
+ return EnumToString(message_type).value_or(nullptr).data();
}
CastMessageType CastMessageTypeFromString(const std::string& type) {
- if (type == kCastMessageTypePingString)
- return CastMessageType::kPing;
- if (type == kCastMessageTypePongString)
- return CastMessageType::kPong;
- if (type == kCastMessageTypeGetAppAvailabilityString)
- return CastMessageType::kGetAppAvailability;
- if (type == kCastMessageTypeReceiverStatusRequestString)
- return CastMessageType::kReceiverStatusRequest;
- if (type == kCastMessageTypeConnectString)
- return CastMessageType::kConnect;
- if (type == kCastMessageTypeCloseConnectionString)
- return CastMessageType::kCloseConnection;
- if (type == kCastMessageTypeBroadcastString)
- return CastMessageType::kBroadcast;
- if (type == kCastMessageTypeLaunchString)
- return CastMessageType::kLaunch;
- if (type == kCastMessageTypeStopString)
- return CastMessageType::kStop;
- if (type == kCastMessageTypeReceiverStatusString)
- return CastMessageType::kReceiverStatus;
- if (type == kCastMessageTypeMediaStatusString)
- return CastMessageType::kMediaStatus;
- if (type == kCastMessageTypeLaunchErrorString)
- return CastMessageType::kLaunchError;
- DVLOG(1) << "Unknown message type: " << type;
- return CastMessageType::kOther;
+ auto result = StringToEnum<CastMessageType>(type);
+ DVLOG_IF(1, !result) << "Unknown message type: " << type;
+ return result.value_or(CastMessageType::kOther);
}
V2MessageType V2MessageTypeFromString(const std::string& type) {
- if (type == kV2MessageTypeGetStatusString)
- return V2MessageType::kGetStatus;
- if (type == kV2MessageTypeLoadString)
- return V2MessageType::kLoad;
- if (type == kV2MessageTypeMediaGetStatusString)
- return V2MessageType::kMediaGetStatus;
- if (type == kV2MessageTypeMediaSetVolumeString)
- return V2MessageType::kMediaSetVolume;
- if (type == kV2MessageTypePauseString)
- return V2MessageType::kPause;
- if (type == kV2MessageTypePlayString)
- return V2MessageType::kPlay;
- if (type == kV2MessageTypePrecacheString)
- return V2MessageType::kPrecache;
- if (type == kV2MessageTypeQueueInsertString)
- return V2MessageType::kQueueInsert;
- if (type == kV2MessageTypeQueueLoadString)
- return V2MessageType::kQueueLoad;
- if (type == kV2MessageTypeQueueRemoveString)
- return V2MessageType::kQueueRemove;
- if (type == kV2MessageTypeQueueReorderString)
- return V2MessageType::kQueueReorder;
- if (type == kV2MessageTypeQueueUpdateString)
- return V2MessageType::kQueueUpdate;
- if (type == kV2MessageTypeSeekString)
- return V2MessageType::kSeek;
- if (type == kV2MessageTypeSetVolumeString)
- return V2MessageType::kSetVolume;
- if (type == kV2MessageTypeStopString)
- return V2MessageType::kStop;
- if (type == kV2MessageTypeStopMediaString)
- return V2MessageType::kStopMedia;
- else
- return V2MessageType::kOther;
+ return StringToEnum<V2MessageType>(type).value_or(V2MessageType::kOther);
}
std::string CastMessageToString(const CastMessage& message_proto) {
@@ -297,7 +192,7 @@ std::string CastMessageToString(const CastMessage& message_proto) {
out += "namespace = " + message_proto.namespace_();
out += ", sourceId = " + message_proto.source_id();
out += ", destId = " + message_proto.destination_id();
- out += ", type = " + base::IntToString(message_proto.payload_type());
+ out += ", type = " + base::NumberToString(message_proto.payload_type());
out += ", str = \"" + message_proto.payload_utf8() + "\"}";
return out;
}
@@ -317,7 +212,7 @@ std::string AuthMessageToString(const DeviceAuthMessage& message) {
}
if (message.has_error()) {
out += ", error: {";
- out += base::IntToString(message.error().error_type());
+ out += base::NumberToString(message.error().error_type());
out += "}";
}
out += "}";
@@ -356,11 +251,13 @@ bool IsPlatformSenderMessage(const CastMessage& message) {
}
CastMessage CreateKeepAlivePingMessage() {
- return CreateKeepAliveMessage(kCastMessageTypePingString);
+ return CreateKeepAliveMessage(
+ EnumToString<CastMessageType, CastMessageType::kPing>());
}
CastMessage CreateKeepAlivePongMessage() {
- return CreateKeepAliveMessage(kCastMessageTypePongString);
+ return CreateKeepAliveMessage(
+ EnumToString<CastMessageType, CastMessageType::kPong>());
}
CastMessage CreateVirtualConnectionRequest(
@@ -385,7 +282,9 @@ CastMessage CreateVirtualConnectionRequest(
}
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeConnectString));
+ dict.SetKey(
+ "type",
+ Value(EnumToString<CastMessageType, CastMessageType::kConnect>()));
dict.SetKey("userAgent", Value(user_agent));
dict.SetKey("connType", Value(connection_type));
dict.SetKey("origin", Value(Value::Type::DICTIONARY));
@@ -409,7 +308,9 @@ CastMessage CreateGetAppAvailabilityRequest(const std::string& source_id,
int request_id,
const std::string& app_id) {
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeGetAppAvailabilityString));
+ dict.SetKey("type",
+ Value(EnumToString<CastMessageType,
+ CastMessageType::kGetAppAvailability>()));
Value app_id_value(Value::Type::LIST);
app_id_value.GetList().push_back(Value(app_id));
dict.SetKey("appId", std::move(app_id_value));
@@ -422,7 +323,9 @@ CastMessage CreateGetAppAvailabilityRequest(const std::string& source_id,
CastMessage CreateReceiverStatusRequest(const std::string& source_id,
int request_id) {
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeReceiverStatusRequestString));
+ dict.SetKey("type",
+ Value(EnumToString<CastMessageType,
+ CastMessageType::kReceiverStatusRequest>()));
dict.SetKey("requestId", Value(request_id));
return CreateCastMessage(kReceiverNamespace, dict, source_id,
kPlatformReceiverId);
@@ -443,7 +346,9 @@ CastMessage CreateBroadcastRequest(const std::string& source_id,
const std::vector<std::string>& app_ids,
const BroadcastRequest& request) {
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeBroadcastString));
+ dict.SetKey(
+ "type",
+ Value(EnumToString<CastMessageType, CastMessageType::kBroadcast>()));
std::vector<Value> app_ids_value;
for (const std::string& app_id : app_ids)
app_ids_value.push_back(Value(app_id));
@@ -460,7 +365,8 @@ CastMessage CreateLaunchRequest(const std::string& source_id,
const std::string& app_id,
const std::string& locale) {
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeLaunchString));
+ dict.SetKey("type",
+ Value(EnumToString<CastMessageType, CastMessageType::kLaunch>()));
dict.SetKey("requestId", Value(request_id));
dict.SetKey("appId", Value(app_id));
dict.SetKey("language", Value(locale));
@@ -473,7 +379,8 @@ CastMessage CreateStopRequest(const std::string& source_id,
int request_id,
const std::string& session_id) {
Value dict(Value::Type::DICTIONARY);
- dict.SetKey("type", Value(kCastMessageTypeStopString));
+ dict.SetKey("type",
+ Value(EnumToString<CastMessageType, CastMessageType::kStop>()));
dict.SetKey("requestId", Value(request_id));
dict.SetKey("sessionId", Value(session_id));
return CreateCastMessage(kReceiverNamespace, dict, source_id,
@@ -510,7 +417,8 @@ CastMessage CreateSetVolumeRequest(const base::Value& body,
const std::string& source_id) {
DCHECK(body.FindKeyOfType("type", Value::Type::STRING) &&
body.FindKeyOfType("type", Value::Type::STRING)->GetString() ==
- kV2MessageTypeSetVolumeString);
+ (EnumToString<V2MessageType, V2MessageType::kSetVolume>())
+ .as_string());
Value dict = body.Clone();
dict.RemoveKey("sessionId");
dict.SetKey("requestId", Value(request_id));
@@ -541,14 +449,7 @@ bool IsMediaRequestMessageType(V2MessageType type) {
}
const char* ToString(GetAppAvailabilityResult result) {
- switch (result) {
- case GetAppAvailabilityResult::kAvailable:
- return kGetAppAvailabilityResultAvailableString;
- case GetAppAvailabilityResult::kUnavailable:
- return kGetAppAvailabilityResultUnavailableString;
- default:
- return nullptr;
- }
+ return EnumToString(result).value_or(nullptr).data();
}
base::Optional<int> GetRequestIdFromResponse(const Value& payload) {
@@ -567,14 +468,11 @@ GetAppAvailabilityResult GetAppAvailabilityResultFromResponse(
DCHECK(payload.is_dict());
const Value* availability_value =
payload.FindPathOfType({"availability", app_id}, Value::Type::STRING);
- if (availability_value) {
- const std::string& result_str = availability_value->GetString();
- if (result_str == kGetAppAvailabilityResultAvailableString)
- return GetAppAvailabilityResult::kAvailable;
- if (result_str == kGetAppAvailabilityResultUnavailableString)
- return GetAppAvailabilityResult::kUnavailable;
- }
- return GetAppAvailabilityResult::kUnknown;
+ if (!availability_value)
+ return GetAppAvailabilityResult::kUnknown;
+
+ return StringToEnum<GetAppAvailabilityResult>(availability_value->GetString())
+ .value_or(GetAppAvailabilityResult::kUnknown);
}
LaunchSessionResponse::LaunchSessionResponse() {}
diff --git a/chromium/components/cast_channel/cast_message_util_unittest.cc b/chromium/components/cast_channel/cast_message_util_unittest.cc
index 7bc1027eed2..24e96aea35f 100644
--- a/chromium/components/cast_channel/cast_message_util_unittest.cc
+++ b/chromium/components/cast_channel/cast_message_util_unittest.cc
@@ -10,7 +10,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using base::test::IsJson;
-using base::test::ParseJson;
+using base::test::ParseJsonDeprecated;
namespace cast_channel {
@@ -39,7 +39,7 @@ TEST(CastMessageUtilTest, GetLaunchSessionResponseOk) {
)";
LaunchSessionResponse response =
- GetLaunchSessionResponse(*ParseJson(payload));
+ GetLaunchSessionResponse(*ParseJsonDeprecated(payload));
EXPECT_EQ(LaunchSessionResponse::Result::kOk, response.result);
EXPECT_TRUE(response.receiver_status);
}
@@ -53,7 +53,7 @@ TEST(CastMessageUtilTest, GetLaunchSessionResponseError) {
)";
LaunchSessionResponse response =
- GetLaunchSessionResponse(*ParseJson(payload));
+ GetLaunchSessionResponse(*ParseJsonDeprecated(payload));
EXPECT_EQ(LaunchSessionResponse::Result::kError, response.result);
EXPECT_FALSE(response.receiver_status);
}
@@ -69,7 +69,7 @@ TEST(CastMessageUtilTest, GetLaunchSessionResponseUnknown) {
)";
LaunchSessionResponse response =
- GetLaunchSessionResponse(*ParseJson(payload));
+ GetLaunchSessionResponse(*ParseJsonDeprecated(payload));
EXPECT_EQ(LaunchSessionResponse::Result::kUnknown, response.result);
EXPECT_FALSE(response.receiver_status);
}
@@ -110,8 +110,8 @@ TEST(CastMessageUtilTest, CreateMediaRequest) {
"requestId": 123,
})";
- CastMessage message = CreateMediaRequest(*ParseJson(body), 123, "theSourceId",
- "theDestinationId");
+ CastMessage message = CreateMediaRequest(*ParseJsonDeprecated(body), 123,
+ "theSourceId", "theDestinationId");
ASSERT_TRUE(IsCastMessageValid(message));
EXPECT_EQ(kMediaNamespace, message.namespace_());
EXPECT_EQ("theSourceId", message.source_id());
@@ -130,7 +130,7 @@ TEST(CastMessageUtilTest, CreateVolumeRequest) {
})";
CastMessage message =
- CreateSetVolumeRequest(*ParseJson(body), 123, "theSourceId");
+ CreateSetVolumeRequest(*ParseJsonDeprecated(body), 123, "theSourceId");
ASSERT_TRUE(IsCastMessageValid(message));
EXPECT_EQ(kReceiverNamespace, message.namespace_());
EXPECT_EQ("theSourceId", message.source_id());
diff --git a/chromium/components/cast_channel/cast_socket.h b/chromium/components/cast_channel/cast_socket.h
index 8a65fa23d30..79e7620f8c9 100644
--- a/chromium/components/cast_channel/cast_socket.h
+++ b/chromium/components/cast_channel/cast_socket.h
@@ -27,6 +27,7 @@
#include "net/base/ip_endpoint.h"
#include "net/log/net_log_source.h"
#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/public/mojom/tls_socket.mojom.h"
namespace net {
class X509Certificate;
diff --git a/chromium/components/cast_channel/cast_socket_unittest.cc b/chromium/components/cast_channel/cast_socket_unittest.cc
index 6e6fc7a449c..9f1d9cadcde 100644
--- a/chromium/components/cast_channel/cast_socket_unittest.cc
+++ b/chromium/components/cast_channel/cast_socket_unittest.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/location.h"
@@ -36,7 +37,6 @@
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/cert/pem_tokenizer.h"
-#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_server_socket.h"
@@ -233,6 +233,7 @@ class MockTestCastSocket : public TestCastSocketBase {
DISALLOW_COPY_AND_ASSIGN(MockTestCastSocket);
};
+// TODO(https://crbug.com/928467): Remove this class.
class TestSocketFactory : public net::ClientSocketFactory {
public:
explicit TestSocketFactory(net::IPEndPoint ip) : ip_(ip) {}
@@ -314,30 +315,28 @@ class TestSocketFactory : public net::ClientSocketFactory {
}
}
std::unique_ptr<net::SSLClientSocket> CreateSSLClientSocket(
- std::unique_ptr<net::ClientSocketHandle> client_handle,
+ std::unique_ptr<net::StreamSocket> nested_socket,
const net::HostPortPair& host_and_port,
const net::SSLConfig& ssl_config,
const net::SSLClientSocketContext& context) override {
if (!ssl_connect_data_) {
// Test isn't overriding SSL socket creation.
return net::ClientSocketFactory::GetDefaultFactory()
- ->CreateSSLClientSocket(std::move(client_handle), host_and_port,
+ ->CreateSSLClientSocket(std::move(nested_socket), host_and_port,
ssl_config, context);
}
ssl_socket_data_provider_ = std::make_unique<net::SSLSocketDataProvider>(
ssl_connect_data_->mode, ssl_connect_data_->result);
- // auto client_handle = std::make_unique<net::ClientSocketHandle>();
if (tls_socket_created_)
std::move(tls_socket_created_).Run();
- // client_handle->SetSocket(std::move(tcp_socket));
return std::make_unique<net::MockSSLClientSocket>(
- std::move(client_handle), net::HostPortPair(), net::SSLConfig(),
+ std::move(nested_socket), net::HostPortPair(), net::SSLConfig(),
ssl_socket_data_provider_.get());
}
std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket(
- std::unique_ptr<net::ClientSocketHandle> transport_socket,
+ std::unique_ptr<net::StreamSocket> stream_socket,
const std::string& user_agent,
const net::HostPortPair& endpoint,
const net::ProxyServer& proxy_server,
@@ -351,7 +350,6 @@ class TestSocketFactory : public net::ClientSocketFactory {
NOTIMPLEMENTED();
return nullptr;
}
- void ClearSSLSessionCache() override { NOTIMPLEMENTED(); }
net::IPEndPoint ip_;
// Simulated connect data
diff --git a/chromium/components/cast_channel/cast_test_util.h b/chromium/components/cast_channel/cast_test_util.h
index 36821d25f3f..d037bc142c6 100644
--- a/chromium/components/cast_channel/cast_test_util.h
+++ b/chromium/components/cast_channel/cast_test_util.h
@@ -7,7 +7,9 @@
#include <string>
#include <utility>
+#include <vector>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/cast_channel/cast_message_handler.h"
@@ -163,9 +165,10 @@ class MockCastMessageHandler : public CastMessageHandler {
const std::string&,
base::TimeDelta,
LaunchSessionCallback callback));
- MOCK_METHOD3(StopSession,
+ MOCK_METHOD4(StopSession,
void(int channel_id,
const std::string& session_id,
+ const base::Optional<std::string>& client_id,
ResultCallback callback));
MOCK_METHOD2(SendAppMessage,
Result(int channel_id, const CastMessage& message));
diff --git a/chromium/components/cast_channel/cast_transport_unittest.cc b/chromium/components/cast_channel/cast_transport_unittest.cc
index a82935d8546..b0879f3fb85 100644
--- a/chromium/components/cast_channel/cast_transport_unittest.cc
+++ b/chromium/components/cast_channel/cast_transport_unittest.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/containers/queue.h"
#include "base/macros.h"
diff --git a/chromium/components/cast_channel/enum_table.cc b/chromium/components/cast_channel/enum_table.cc
new file mode 100644
index 00000000000..a47a2a274ba
--- /dev/null
+++ b/chromium/components/cast_channel/enum_table.cc
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cast_channel/enum_table.h"
+
+#include <cstdlib>
+
+namespace cast_util {
+
+#ifdef ARCH_CPU_64_BITS
+// This assertion is pretty paranoid. It will probably only ever be triggered
+// if someone who doesn't understand how EnumTable works tries to add extra
+// members to GenericEnumTableEntry.
+static_assert(sizeof(GenericEnumTableEntry) == 16,
+ "Instances of GenericEnumTableEntry are too big.");
+#endif
+
+// static
+const GenericEnumTableEntry* GenericEnumTableEntry::FindByString(
+ const GenericEnumTableEntry data[],
+ std::size_t size,
+ base::StringPiece str) {
+ for (std::size_t i = 0; i < size; i++) {
+ if (data[i].length == str.length() &&
+ std::memcmp(data[i].chars, str.data(), str.length()) == 0)
+ return &data[i];
+ }
+ return nullptr;
+}
+
+// static
+base::Optional<base::StringPiece> GenericEnumTableEntry::FindByValue(
+ const GenericEnumTableEntry data[],
+ std::size_t size,
+ int value) {
+ for (std::size_t i = 0; i < size; i++) {
+ if (data[i].value == value)
+ return data[i].str();
+ }
+ return base::nullopt;
+}
+
+} // namespace cast_util
diff --git a/chromium/components/cast_channel/enum_table.h b/chromium/components/cast_channel/enum_table.h
new file mode 100644
index 00000000000..e0551953a39
--- /dev/null
+++ b/chromium/components/cast_channel/enum_table.h
@@ -0,0 +1,368 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CAST_CHANNEL_ENUM_TABLE_H_
+#define COMPONENTS_CAST_CHANNEL_ENUM_TABLE_H_
+
+#include <cstdint>
+
+#include "base/logging.h"
+#include "base/optional.h"
+#include "base/strings/string_piece.h"
+#include "build/build_config.h"
+
+// TODO(jrw): Move this file to a more appropriate directory.
+//
+//
+// A bidirectional mapping between enum values and strings.
+//
+// Typical Usage
+// -------------
+//
+// The typical way to use this class is to define a specializtion of
+// EnumTable<E>::instance for a specific enum type, which is initialized with
+// a table of enum values and their corresponding strings:
+//
+// // In .h file:
+// enum class MyEnum { kFoo, kBar, ..., kOther };
+//
+// // In .cc file:
+//
+// template <>
+// constexpr EnumTable<MyEnum> EnumTable<MyEnum>::instance({
+// {MyEnum::kFoo, "FOO"},
+// {MyEnum::kBar, "BAR"},
+// ...
+// // No entry for kOther because it has no string representation.
+// });
+//
+// The functions EnumToString() and StringToEnum() are used to look up values
+// in the table. In some cases, it may be useful to wrap these functions for
+// special handling of unknown values, etc.:
+//
+// const char* MyEnumToString(MyEnum value) {
+// return EnumToString(value).value_or(nullptr).data();
+// }
+//
+// MyEnum StringToMyEnum(const std::string& name) {
+// return StringToEnum<MyEnum>(name).value_or(MyEnum::kOther);
+// }
+//
+// NOTE: Because it's a template specialization, the definition of
+// EnumTable<E>::instance has to be in the cast_util namespace. Alternatively,
+// you can declare your own table with any name you want and call its members
+// functions directly.
+//
+// To get a the string for an enum value that is known at compile time, there is
+// a special zero-argument form of EnumToString(), (and a corresponding member
+// function in EnumTable):
+//
+// // Compiles to base::StringPiece("FOO").
+// EnumToString<MyEnum, MyEnum::kFoo>();
+//
+// The syntax is a little awkward, but it saves you from having to duplicate
+// string literals or define each enum string as a named constant.
+//
+//
+// Why use an EnumTable?
+// ---------------------
+//
+// If you're only doing one-way conversions from an enum to a string, using an
+// EnumTable is almost identical to a switch statement. Typically a switch
+// statement that converts an enum value to a string will compile to a simple
+// constant-time lookup in a static array, and a call to an EnumTable's
+// GetString() method will compile to almost exactly the same code (with one
+// additional shlq instruction compared to the switch statement).
+//
+// If your enum values are non-consecutive, the GetString() method will perform
+// a linear search instead of an array lookup. The search should be competitve
+// in performance with a switch statement in this case. To avoid getting this
+// sub-optimal behavior by accident, you must explicitly request it with an
+// extra argument to EnumTable's constructor. If you don't do this, failure to
+// put the values in the correct order will cause your unit tests to fail on
+// startup with a decriptive error message.
+//
+// EnumTable really shines when you need to convert strings to enum values. A
+// typical implementation without EnumTable looks like this:
+//
+// constexpr char kMyEnumFooString[] = "FOO";
+// constexpr char kMyEnumBarString[] = "BAR";
+// ...
+//
+// MyEnum StringToMyEnum(const std::string& str) {
+// if (str == kMyEnumFooString) return MyEnum::kFoo;
+// if (str == kMyEnumBarString) return MyEnum::kBar;
+// ...
+// return kOther;
+// }
+//
+// If you roll your own solution, you can't do much better than this without
+// jumping through some hoops. Obvious improvements, like storing the data in a
+// global base::flat_map, are off-limits because Chromium requires all global
+// variables to have trivial destructors. A simple chain of "if" statements
+// works fine, but it has a number of drawbacks compared to an EnumTable:
+//
+// - You have to write and maintain a function separate from the one that
+// converts enum values to strings. With an EnumTable, a single declaration
+// lets you convert in both directions.
+//
+// - Since you will almost certainly be using the strings in more than one
+// place, you have to either define a named constant for each one, or live
+// with the fact that the string literals are duplicated, causing maintenance
+// headaches. With an EnumTable, each string naturally appears in only one
+// place, so there's no need for supplementary named constants. When you need
+// to refer to the string for a particular enum value, you can get it directly
+// from the table at compile time using the zero-argument EnumToString()
+// function or the zero-argument EnumTable<E>::ToString() method.
+//
+// - If you want to follow best practices, you'll need to write unit tests for
+// your functions that convert between strings and enums. When you use an
+// EnumTable, you don't write any functions, so there's nothing to test; all
+// the necessary testing is done by EnumTable's own unit tests.
+//
+// - The conversion function is essentially a fully-unrolled linear search
+// through all the possible string values. This bloats your code and causes
+// unnecessary churn in the instruction cache. Using an EnumTable, this
+// search is compiled into a single loop shared by all enums, which the
+// compiler can unroll, or not, as appropriate. On 64-bit platforms, the main
+// table uses only 16 bytes per entry, so memory locality is excellent and
+// impact on the data cache is minimal.
+//
+// - The hand-written function performs a function call for each candidate
+// string. EnumTable's search loop compares the lengths of the strings before
+// doing anything else, so most iterations don't call any functions and don't
+// access any memory aside from the lookup table itself.
+//
+// - If you accidentally duplicate any lines in the function, you're on your
+// own. EnumTable detects duplicate strings on startup (in debug builds), so
+// you'll never accidentally try to map a string to two different enum values.
+
+namespace cast_util {
+
+class
+#ifdef ARCH_CPU_64_BITS
+ alignas(16)
+#endif
+ GenericEnumTableEntry {
+ public:
+ inline constexpr GenericEnumTableEntry(int32_t value, base::StringPiece str);
+
+ private:
+ static const GenericEnumTableEntry* FindByString(
+ const GenericEnumTableEntry data[],
+ std::size_t size,
+ base::StringPiece str);
+ static base::Optional<base::StringPiece>
+ FindByValue(const GenericEnumTableEntry data[], std::size_t size, int value);
+
+ constexpr base::StringPiece str() const { return {chars, length}; }
+
+ // Instead of storing a base::StringPiece, it's broken apart and stored as a
+ // pointer and an unsigned int (rather than a std::size_t) so that table
+ // entries fit in 16 bytes with no padding on 64-bit platforms.
+ const char* chars;
+ uint32_t length;
+
+ int32_t value;
+
+ template <typename E>
+ friend class EnumTable;
+ DISALLOW_COPY_AND_ASSIGN(GenericEnumTableEntry);
+};
+
+// Yes, this really needs to be inlined. Even though it looks "complex" to the
+// style checker, everything is executed at compile time, so an EnumTable
+// instance can be fully initialized without executing any code.
+inline constexpr GenericEnumTableEntry::GenericEnumTableEntry(
+ int32_t value,
+ base::StringPiece str)
+ : chars(str.data()),
+ length(static_cast<uint32_t>(str.length())),
+ value(value) {}
+
+struct UnsortedEnumTable_t {};
+constexpr UnsortedEnumTable_t UnsortedEnumTable;
+
+// A table for associating enum values with string literals. This class is
+// designed for use as an initialized global variable, so it has a trivial
+// destructor and a simple constant-time constructor.
+template <typename E>
+class EnumTable {
+ public:
+ // DO NOT add any members to this class, or it will break the
+ // reinterpret_casts below. If necessary, add new members to
+ // GenericEnumTableEntry instead.
+ class Entry : public GenericEnumTableEntry {
+ public:
+ constexpr Entry(E value, base::StringPiece str)
+ : GenericEnumTableEntry(static_cast<int32_t>(value), str) {}
+
+ DISALLOW_COPY_AND_ASSIGN(Entry);
+ };
+
+ static_assert(sizeof(E) <= sizeof(int32_t),
+ "Enum must not use more than 32 bits of storage.");
+ static_assert(sizeof(Entry) == sizeof(GenericEnumTableEntry),
+ "EnumTable<E>::Entry must not have its own member variables.");
+
+ // Creates an EnumTable where data[i].value == i for all i. When a table is
+ // created with this constructor, the GetString() method is a simple array
+ // lookup that runs in constant time.
+ constexpr EnumTable(std::initializer_list<Entry> data)
+ : EnumTable(data, true) {
+#ifndef NDEBUG
+ // NOTE(jrw): This is compiled out when NDEBUG is defined, even if DCHECKS
+ // are normally enabled because DCHECK_ALWAYS_ON is defined. The reason for
+ // this is that if DCHECKs are enabled, global EnumTable instances will have
+ // a nontrivial constructor, which is flagged as a style violation by the
+ // linux-rel trybot.
+ auto found = FindUnsortedEntry(data);
+ DCHECK(!found) << "Entries' numerical values must be consecutive "
+ << "integers starting at 0; found problem at index "
+ << *found;
+#endif // NDEBUG
+ }
+
+ // Creates an EnumTable where data[i].value != i for some values of i. When
+ // a table is created with this constructor, the GetString() method must
+ // perform a linear search to find the correct string.
+ constexpr EnumTable(std::initializer_list<Entry> data, UnsortedEnumTable_t)
+ : EnumTable(data, false) {
+#ifndef NDEBUG
+ DCHECK(FindUnsortedEntry(data))
+ << "Don't use this constructor for sorted entries.";
+#endif // NDEBUG
+ }
+
+ // Gets the string associated with the given enum value. When the argument
+ // is a constant, prefer the zero-argument form below.
+ inline base::Optional<base::StringPiece> GetString(E value) const {
+ if (is_sorted_) {
+ const std::size_t index = static_cast<std::size_t>(value);
+ if (ANALYZER_ASSUME_TRUE(index < data_.size())) {
+ const auto& entry = data_.begin()[index];
+ return entry.str();
+ }
+ return {};
+ }
+ return GenericEnumTableEntry::FindByValue(
+ reinterpret_cast<const GenericEnumTableEntry*>(data_.begin()),
+ data_.size(), static_cast<int32_t>(value));
+ }
+
+ // This overload of GetString is designed for cases where the argument is a
+ // literal value. It will be evaluated at compile time in non-debug builds.
+ //
+ // If |Value| has no string defined in the table, you'll get an error at
+ // runtime in debug builds, but in release builds this function will just
+ // return a string holding an error message. Unfortunately it doesn't seem
+ // possible to report an error in evaluating a constexpr function at compile
+ // time without using exceptions.
+ template <E Value>
+ constexpr base::StringPiece GetString() const {
+ for (const auto& entry : data_) {
+ if (entry.value == static_cast<int32_t>(Value))
+ return entry.str();
+ }
+
+ NOTREACHED() << "No string for enum value: " << static_cast<int32_t>(Value);
+ return "[invalid enum value]";
+ }
+
+ // Gets the enum value associated with the given string. Unlike
+ // GetString(), this method is not defined as a constexpr, because it should
+ // never be called with a literal string; it's simpler to just refer to the
+ // enum value directly.
+ base::Optional<E> GetEnum(base::StringPiece str) const {
+ auto* entry = GenericEnumTableEntry::FindByString(
+ reinterpret_cast<const GenericEnumTableEntry*>(data_.begin()),
+ data_.size(), str);
+ return entry ? static_cast<E>(entry->value) : base::Optional<E>();
+ }
+
+ // The default instance of this class. There should normally only be one
+ // instance of this class for a given enum type. Users of this class are
+ // responsible for providing a suitable definition for each enum type if the
+ // EnumToString() or StringToEnum() functions are used.
+ static const EnumTable<E> instance;
+
+ private:
+#ifdef ARCH_CPU_64_BITS
+ // Align the data on a cache line boundary.
+ alignas(64)
+#endif
+ std::initializer_list<Entry> data_;
+ bool is_sorted_;
+
+ constexpr EnumTable(std::initializer_list<Entry> data, bool is_sorted)
+ : data_(data), is_sorted_(is_sorted) {
+#ifndef NDEBUG
+ // If the table is too large, it's probably time to update this class to do
+ // something smarter than a linear search.
+ DCHECK(data.size() <= 32) << "Table too large.";
+
+ for (std::size_t i = 0; i < data.size(); i++) {
+ for (std::size_t j = i + 1; j < data.size(); j++) {
+ const Entry& ei = data.begin()[i];
+ const Entry& ej = data.begin()[j];
+ DCHECK(ei.value != ej.value)
+ << "Found duplicate enum values at indices " << i << " and " << j;
+ DCHECK(ei.str() != ej.str())
+ << "Found duplicate strings at indices " << i << " and " << j;
+ }
+ }
+#endif // NDEBUG
+ }
+
+#ifndef NDEBUG
+ // Finds and returns the first i for which data[i].value != i;
+ constexpr static base::Optional<std::size_t> FindUnsortedEntry(
+ std::initializer_list<Entry> data) {
+ std::size_t counter = 0;
+ for (const auto& entry : data) {
+ if (static_cast<std::size_t>(entry.value) != counter) {
+ return counter;
+ }
+ ++counter;
+ }
+ return {};
+ }
+#endif // NDEBUG
+
+ DISALLOW_COPY_AND_ASSIGN(EnumTable);
+};
+
+// Converts an enum value to a string using the default table
+// (EnumTable<E>::instance) for the given enum type.
+template <typename E>
+inline base::Optional<base::StringPiece> EnumToString(E value) {
+ return EnumTable<E>::instance.GetString(value);
+}
+
+// Converts a literal enum value to a string at compile time using the default
+// table (EnumTable<E>::instance) for the given enum type.
+//
+// TODO(jrw): Once C++17 features are allowed, change this function to have only
+// one template parameter:
+//
+// template <auto Value>
+// inline base::StringPiece EnumToString() {
+// return EnumTable<decltype(Value)>::instance.template GetString<Value>();
+// }
+//
+template <typename E, E Value>
+inline base::StringPiece EnumToString() {
+ return EnumTable<E>::instance.template GetString<Value>();
+}
+
+// Converts a string to an enum value using the default table
+// (EnumTable<E>::instance) for the given enum type.
+template <typename E>
+inline base::Optional<E> StringToEnum(base::StringPiece str) {
+ return EnumTable<E>::instance.GetEnum(str);
+}
+
+} // namespace cast_util
+
+#endif // COMPONENTS_CAST_CHANNEL_ENUM_TABLE_H_
diff --git a/chromium/components/cast_channel/enum_table_unittest.cc b/chromium/components/cast_channel/enum_table_unittest.cc
new file mode 100644
index 00000000000..d9f900f89b6
--- /dev/null
+++ b/chromium/components/cast_channel/enum_table_unittest.cc
@@ -0,0 +1,173 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cast_channel/enum_table.h"
+
+#include "base/macros.h"
+#include "base/test/gtest_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cast_util {
+namespace {
+
+enum class MyEnum { kZero, kOne, kTwo, kOther };
+
+const EnumTable<MyEnum> kSorted({{MyEnum::kZero, "ZERO"},
+ {MyEnum::kOne, "ONE"},
+ {MyEnum::kTwo, "TWO"}});
+
+const EnumTable<MyEnum> kUnsorted({{MyEnum::kOne, "ONE"},
+ {MyEnum::kZero, "ZERO"},
+ {MyEnum::kTwo, "TWO"}},
+ UnsortedEnumTable);
+
+} // namespace
+
+template <>
+const EnumTable<MyEnum> EnumTable<MyEnum>::instance(
+ {{MyEnum::kZero, "ZERO_DEFAULT"},
+ {MyEnum::kOne, "ONE_DEFAULT"},
+ {MyEnum::kTwo, "TWO_DEFAULT"}});
+
+namespace {
+
+TEST(EnumTableTest, TestGetString) {
+ EXPECT_EQ("ZERO", kSorted.GetString(MyEnum::kZero));
+ EXPECT_EQ("ONE", kSorted.GetString(MyEnum::kOne));
+ EXPECT_EQ("TWO", kSorted.GetString(MyEnum::kTwo));
+ EXPECT_EQ(base::nullopt, kSorted.GetString(MyEnum::kOther));
+}
+
+TEST(EnumTableTest, TestGetStringUnsorted) {
+ EXPECT_EQ("ZERO", kUnsorted.GetString(MyEnum::kZero));
+ EXPECT_EQ("ONE", kUnsorted.GetString(MyEnum::kOne));
+ EXPECT_EQ("TWO", kUnsorted.GetString(MyEnum::kTwo));
+ EXPECT_EQ(base::nullopt, kUnsorted.GetString(MyEnum::kOther));
+}
+
+TEST(EnumTableTest, TestEnumToStringGlobal) {
+ EXPECT_EQ("ZERO_DEFAULT", EnumToString(MyEnum::kZero));
+ EXPECT_EQ("ONE_DEFAULT", EnumToString(MyEnum::kOne));
+ EXPECT_EQ("TWO_DEFAULT", EnumToString(MyEnum::kTwo));
+ EXPECT_EQ(base::nullopt, EnumToString(MyEnum::kOther));
+}
+
+TEST(EnumTableTest, TestStaticGetString) {
+ EXPECT_EQ("ZERO", kSorted.GetString<MyEnum::kZero>());
+ EXPECT_EQ("ONE", kSorted.GetString<MyEnum::kOne>());
+ EXPECT_EQ("TWO", kSorted.GetString<MyEnum::kTwo>());
+}
+
+TEST(EnumTableTest, TestStaticEnumToStringGlobal) {
+ // Extra parens are needed below, otherwise Clang gets confused.
+ EXPECT_EQ("ZERO_DEFAULT", (EnumToString<MyEnum, MyEnum::kZero>()));
+ EXPECT_EQ("ONE_DEFAULT", (EnumToString<MyEnum, MyEnum::kOne>()));
+ EXPECT_EQ("TWO_DEFAULT", (EnumToString<MyEnum, MyEnum::kTwo>()));
+}
+
+TEST(EnumTableTest, TestGetEnum) {
+ EXPECT_EQ(MyEnum::kZero, kSorted.GetEnum("ZERO"));
+ EXPECT_EQ(MyEnum::kOne, kSorted.GetEnum("ONE"));
+ EXPECT_EQ(MyEnum::kTwo, kSorted.GetEnum("TWO"));
+ EXPECT_EQ(base::nullopt, kSorted.GetEnum("THREE"));
+ EXPECT_EQ(base::nullopt, kSorted.GetEnum(nullptr));
+}
+
+TEST(EnumTableTest, TestStringToEnumGlobal) {
+ EXPECT_EQ(MyEnum::kZero, StringToEnum<MyEnum>("ZERO_DEFAULT"));
+ EXPECT_EQ(MyEnum::kOne, StringToEnum<MyEnum>("ONE_DEFAULT"));
+ EXPECT_EQ(MyEnum::kTwo, StringToEnum<MyEnum>("TWO_DEFAULT"));
+ EXPECT_EQ(base::nullopt, StringToEnum<MyEnum>("THREE"));
+ EXPECT_EQ(base::nullopt, StringToEnum<MyEnum>(nullptr));
+}
+
+// See note in enum_table.h for details of why these tests have to be compiled
+// out when NDEBUG is defined.
+#ifndef NDEBUG
+
+TEST(EnumTableDeathTest, Sorted) {
+ EXPECT_DCHECK_DEATH(EnumTable<MyEnum>(
+ {{MyEnum::kZero, "ZERO"}, {MyEnum::kTwo, "TWO"}, {MyEnum::kOne, "ONE"}}));
+}
+
+TEST(EnumTableDeathTest, Unsorted) {
+ EXPECT_DCHECK_DEATH(EnumTable<MyEnum>(
+ {{MyEnum::kZero, "ZERO"}, {MyEnum::kOne, "ONE"}, {MyEnum::kTwo, "TWO"}},
+ UnsortedEnumTable));
+}
+
+TEST(EnumTableDeathTest, DuplicateEnums) {
+ EXPECT_DCHECK_DEATH(EnumTable<MyEnum>({{MyEnum::kZero, "ZERO"},
+ {MyEnum::kTwo, "TWO"},
+ {MyEnum::kOne, "ONE"},
+ {MyEnum::kZero, "ZERO"}},
+ UnsortedEnumTable));
+}
+
+TEST(EnumTableDeathTest, DuplicateStrings) {
+ EXPECT_DCHECK_DEATH(EnumTable<MyEnum>(
+ {{MyEnum::kZero, "FOO"}, {MyEnum::kOne, "ONE"}, {MyEnum::kTwo, "FOO"}}));
+}
+
+TEST(EnumTableDeathTest, StaticEnumToString) {
+ EXPECT_DCHECK_DEATH(kSorted.GetString<MyEnum::kOther>());
+ EXPECT_DCHECK_DEATH((EnumToString<MyEnum, MyEnum::kOther>()));
+}
+
+enum class HugeEnum {
+ k0,
+ k1,
+ k2,
+ k3,
+ k4,
+ k5,
+ k6,
+ k7,
+ k8,
+ k9,
+ k10,
+ k11,
+ k12,
+ k13,
+ k14,
+ k15,
+ k16,
+ k17,
+ k18,
+ k19,
+ k20,
+ k21,
+ k22,
+ k23,
+ k24,
+ k25,
+ k26,
+ k27,
+ k28,
+ k29,
+ k30,
+ k31,
+ k32,
+};
+
+TEST(EnumTableDeathTest, HugeEnum) {
+ EXPECT_DCHECK_DEATH(EnumTable<HugeEnum>({
+ {HugeEnum::k0, "k0"}, {HugeEnum::k1, "k1"}, {HugeEnum::k2, "k2"},
+ {HugeEnum::k3, "k3"}, {HugeEnum::k4, "k4"}, {HugeEnum::k5, "k5"},
+ {HugeEnum::k6, "k6"}, {HugeEnum::k7, "k7"}, {HugeEnum::k8, "k8"},
+ {HugeEnum::k9, "k9"}, {HugeEnum::k10, "k10"}, {HugeEnum::k11, "k11"},
+ {HugeEnum::k12, "k12"}, {HugeEnum::k13, "k13"}, {HugeEnum::k14, "k14"},
+ {HugeEnum::k15, "k15"}, {HugeEnum::k16, "k16"}, {HugeEnum::k17, "k17"},
+ {HugeEnum::k18, "k18"}, {HugeEnum::k19, "k19"}, {HugeEnum::k20, "k20"},
+ {HugeEnum::k21, "k21"}, {HugeEnum::k22, "k22"}, {HugeEnum::k23, "k23"},
+ {HugeEnum::k24, "k24"}, {HugeEnum::k25, "k25"}, {HugeEnum::k26, "k26"},
+ {HugeEnum::k27, "k27"}, {HugeEnum::k28, "k28"}, {HugeEnum::k29, "k29"},
+ {HugeEnum::k30, "k30"}, {HugeEnum::k31, "k31"}, {HugeEnum::k32, "k32"},
+ }));
+}
+
+#endif // NDEBUG
+
+} // namespace
+} // namespace cast_util
diff --git a/chromium/components/cast_channel/keep_alive_delegate.cc b/chromium/components/cast_channel/keep_alive_delegate.cc
index adce84a141c..f75ea60c979 100644
--- a/chromium/components/cast_channel/keep_alive_delegate.cc
+++ b/chromium/components/cast_channel/keep_alive_delegate.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "components/cast_channel/cast_channel_enum.h"
#include "components/cast_channel/cast_socket.h"
#include "components/cast_channel/logger.h"
diff --git a/chromium/components/cast_channel/keep_alive_delegate_unittest.cc b/chromium/components/cast_channel/keep_alive_delegate_unittest.cc
index 087e0339c72..7b4c25cb669 100644
--- a/chromium/components/cast_channel/keep_alive_delegate_unittest.cc
+++ b/chromium/components/cast_channel/keep_alive_delegate_unittest.cc
@@ -14,6 +14,7 @@
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/tick_clock.h"
#include "base/timer/mock_timer.h"
+#include "base/timer/timer.h"
#include "base/values.h"
#include "components/cast_channel/cast_test_util.h"
#include "net/base/net_errors.h"
diff --git a/chromium/components/cast_channel/mojo_data_pump.cc b/chromium/components/cast_channel/mojo_data_pump.cc
index 6b705af2215..8018a72ffe8 100644
--- a/chromium/components/cast_channel/mojo_data_pump.cc
+++ b/chromium/components/cast_channel/mojo_data_pump.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
diff --git a/chromium/components/cast_channel/mojo_data_pump.h b/chromium/components/cast_channel/mojo_data_pump.h
index 97df8f1483a..a28f43714bb 100644
--- a/chromium/components/cast_channel/mojo_data_pump.h
+++ b/chromium/components/cast_channel/mojo_data_pump.h
@@ -14,7 +14,7 @@
namespace net {
class IOBuffer;
-}; // namespace net
+} // namespace net
namespace cast_channel {
diff --git a/chromium/components/cdm/browser/media_drm_storage_impl.cc b/chromium/components/cdm/browser/media_drm_storage_impl.cc
index a88497a2367..97c1bc1e175 100644
--- a/chromium/components/cdm/browser/media_drm_storage_impl.cc
+++ b/chromium/components/cdm/browser/media_drm_storage_impl.cc
@@ -4,15 +4,23 @@
#include "components/cdm/browser/media_drm_storage_impl.h"
+#include <map>
#include <memory>
+#include <tuple>
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "base/optional.h"
+#include "base/strings/string_util.h"
#include "base/value_conversions.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/navigation_handle.h"
#include "media/base/android/media_drm_key_type.h"
+#include "url/origin.h"
+#include "url/url_constants.h"
// The storage will be managed by PrefService. All data will be stored in a
// dictionary under the key "media.media_drm_storage". The dictionary is
@@ -427,6 +435,119 @@ base::UnguessableToken GetOriginIdForOrigin(
return origin_data->origin_id();
}
+// Map shared by all MediaDrmStorageImpl objects to prevent multiple Origin IDs
+// being allocated for the same origin. Initialize() can be called multiple
+// times for the same web origin (and profile). This class groups together
+// requests for the same web origin (and profile), calling |get_origin_id_cb|
+// only on the first request. This avoids a race condition where simultaneous
+// requests could result in different Origin IDs allocated for the same origin
+// (and only the last one saved in the preference).
+class InitializationSerializer {
+ public:
+ // Origin IDs are unique per preference service and origin.
+ struct PreferenceAndOriginKey {
+ // Allow use as a key in std::map.
+ bool operator<(const PreferenceAndOriginKey& other) const {
+ return std::tie(pref_service, origin) <
+ std::tie(other.pref_service, other.origin);
+ }
+
+ PrefService* pref_service;
+ const url::Origin origin;
+ };
+
+ // The InitializationSerializer is a global map shared by all
+ // MediaDrmStorageImpl instances.
+ static InitializationSerializer& GetInstance() {
+ static base::NoDestructor<InitializationSerializer>
+ s_origin_id_request_impl;
+ return *s_origin_id_request_impl;
+ }
+
+ InitializationSerializer() = default;
+ ~InitializationSerializer() = default;
+
+ void FetchOriginId(
+ PrefService* pref_service,
+ const url::Origin& origin,
+ MediaDrmStorageImpl::GetOriginIdCB get_origin_id_cb,
+ MediaDrmStorageImpl::OriginIdObtainedCB origin_id_obtained_cb) {
+ DVLOG(3) << __func__ << " origin: " << origin;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Check if the preference has an existing origin ID.
+ const base::DictionaryValue* storage_dict =
+ pref_service->GetDictionary(kMediaDrmStorage);
+ base::UnguessableToken origin_id =
+ GetOriginIdForOrigin(storage_dict, origin);
+ if (origin_id) {
+ std::move(origin_id_obtained_cb).Run(true, origin_id);
+ return;
+ }
+
+ // No origin ID found, so check if another Initialize() call is in progress.
+ PreferenceAndOriginKey key{pref_service, origin};
+ auto entry = pending_requests_.find(key);
+ if (entry != pending_requests_.end()) {
+ // Entry already exists, so simply add |origin_id_obtained_cb| to be
+ // called once the Origin ID is obtained.
+ entry->second.emplace_back(std::move(origin_id_obtained_cb));
+ return;
+ }
+
+ // Entry does not exist, so create a new one.
+ std::vector<MediaDrmStorageImpl::OriginIdObtainedCB>
+ origin_id_obtained_cb_list;
+ origin_id_obtained_cb_list.emplace_back(std::move(origin_id_obtained_cb));
+ pending_requests_.emplace(key, std::move(origin_id_obtained_cb_list));
+
+ // Now call |get_origin_id_cb|. It will call OnOriginIdObtained() when done,
+ // which will call all the callbacks saved for this preference and origin
+ // pair. Use of base::Unretained() is valid as |this| is a singleton stored
+ // in a static variable.
+ get_origin_id_cb.Run(
+ base::BindOnce(&InitializationSerializer::OnOriginIdObtained,
+ base::Unretained(this), pref_service, origin));
+ }
+
+ private:
+ void OnOriginIdObtained(
+ PrefService* pref_service,
+ const url::Origin& origin,
+ bool success,
+ const MediaDrmStorageImpl::MediaDrmOriginId& origin_id) {
+ DVLOG(3) << __func__ << " origin: " << origin;
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Save the origin ID in the preference as long as it is not null.
+ if (origin_id) {
+ DictionaryPrefUpdate update(pref_service, kMediaDrmStorage);
+ CreateOriginDictAndReturnSessionsDict(update.Get(), origin,
+ origin_id.value());
+ }
+
+ // Now call any callbacks waiting for this origin ID to be allocated.
+ auto entry = pending_requests_.find({pref_service, origin});
+ DCHECK(entry != pending_requests_.end());
+
+ std::vector<MediaDrmStorageImpl::OriginIdObtainedCB> callbacks;
+ callbacks.swap(entry->second);
+ pending_requests_.erase(entry);
+
+ for (auto& callback : callbacks)
+ std::move(callback).Run(success, origin_id);
+ }
+
+ // Note that this map is never deleted. As entries are removed when an origin
+ // ID is allocated, so it should never get too large.
+ std::map<PreferenceAndOriginKey,
+ std::vector<MediaDrmStorageImpl::OriginIdObtainedCB>>
+ pending_requests_;
+
+ THREAD_CHECKER(thread_checker_);
+ DISALLOW_COPY_AND_ASSIGN(InitializationSerializer);
+};
+
} // namespace
// static
@@ -524,14 +645,18 @@ MediaDrmStorageImpl::MediaDrmStorageImpl(
content::RenderFrameHost* render_frame_host,
PrefService* pref_service,
GetOriginIdCB get_origin_id_cb,
+ AllowEmptyOriginIdCB allow_empty_origin_id_cb,
media::mojom::MediaDrmStorageRequest request)
: FrameServiceBase(render_frame_host, std::move(request)),
pref_service_(pref_service),
get_origin_id_cb_(get_origin_id_cb),
+ allow_empty_origin_id_cb_(allow_empty_origin_id_cb),
weak_factory_(this) {
DVLOG(1) << __func__ << ": origin = " << origin();
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(pref_service_);
+ DCHECK(get_origin_id_cb_);
+ DCHECK(allow_empty_origin_id_cb_);
DCHECK(!origin().opaque());
}
@@ -539,7 +664,7 @@ MediaDrmStorageImpl::~MediaDrmStorageImpl() {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (init_cb_)
- std::move(init_cb_).Run(base::UnguessableToken::Null());
+ std::move(init_cb_).Run(false, base::nullopt);
}
void MediaDrmStorageImpl::Initialize(InitializeCallback callback) {
@@ -547,68 +672,63 @@ void MediaDrmStorageImpl::Initialize(InitializeCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!init_cb_);
- if (IsInitialized()) {
- std::move(callback).Run(origin_id_);
+ if (is_initialized_) {
+ std::move(callback).Run(true, origin_id_);
return;
}
DCHECK(!origin_id_);
- // Check if the preference has an existing origin ID.
- const base::DictionaryValue* storage_dict =
- pref_service_->GetDictionary(kMediaDrmStorage);
- origin_id_ = GetOriginIdForOrigin(storage_dict, origin());
- if (origin_id_) {
- std::move(callback).Run(origin_id_);
- return;
- }
-
- // No origin ID, so fetch one asynchronously. OnOriginIdObtained() is called
- // to finish initialization.
+ // Call using SerializeInitializeRequests() to handle the case where
+ // Initialize() is called concurrently for the same origin (and preference
+ // service). Note that if there is already an existing origin ID for this web
+ // origin saved in the preference, OnOriginIdObtained() will be called
+ // immediately.
init_cb_ = std::move(callback);
- get_origin_id_cb_.Run(base::BindOnce(&MediaDrmStorageImpl::OnOriginIdObtained,
- weak_factory_.GetWeakPtr()));
+ InitializationSerializer::GetInstance().FetchOriginId(
+ pref_service_, origin(), get_origin_id_cb_,
+ base::BindOnce(&MediaDrmStorageImpl::OnOriginIdObtained,
+ weak_factory_.GetWeakPtr()));
}
void MediaDrmStorageImpl::OnOriginIdObtained(
- const base::UnguessableToken& origin_id) {
- // If multiple MediaDrmStorage instances from the same web origin call
- // Initialize concurrently, then a previous instance may have successfully
- // obtained an origin ID and stored it for this origin. So check again to see
- // if an origin ID has been saved, and use it instead of |origin_id|. This
- // does mean that |origin_id| will be lost.
- // TODO(crbug.com/919228): Once pre-provisioned origins are used, |origin_id|
- // needs to be unprovisioned rather than dropped.
- DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage);
- auto stored_origin_id = GetOriginIdForOrigin(update.Get(), origin());
- if (stored_origin_id) {
- origin_id_ = stored_origin_id;
- std::move(init_cb_).Run(origin_id_);
+ bool success,
+ const MediaDrmOriginId& origin_id) {
+ is_initialized_ = true;
+
+ if (!success) {
+ // Unable to get a pre-provisioned origin ID, so call
+ // |allow_empty_origin_id_cb_| to see if the empty origin ID is allowed.
+ allow_empty_origin_id_cb_.Run(
+ base::BindOnce(&MediaDrmStorageImpl::OnEmptyOriginIdAllowed,
+ weak_factory_.GetWeakPtr()));
return;
}
- // As there is no current value, persist the origin ID into storage now.
- // TODO(crbug.com/917527): When pre-provisioned origins are supported, there
- // may not be any available, so an empty origin ID can be used temporarily.
- // The empty origin ID should not be saved in the preference, but should be
- // returned. Note that having |origin_id_| set is used to determine if this
- // object is initialized or not, so temporarily using an empty origin ID will
- // affect that, and that needs to be fixed too.
- DCHECK(origin_id) << "Empty origin ID not handled.";
origin_id_ = origin_id;
- CreateOriginDictAndReturnSessionsDict(update.Get(), origin(), origin_id_);
- std::move(init_cb_).Run(origin_id_);
+ std::move(init_cb_).Run(success, origin_id_);
+}
+
+void MediaDrmStorageImpl::OnEmptyOriginIdAllowed(bool allowed) {
+ std::move(init_cb_).Run(allowed, base::nullopt);
}
void MediaDrmStorageImpl::OnProvisioned(OnProvisionedCallback callback) {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!IsInitialized()) {
+ if (!is_initialized_) {
DVLOG(1) << __func__ << ": Not initialized.";
std::move(callback).Run(false);
return;
}
+ // If this is using an empty origin ID, it should not be provisioned.
+ if (!origin_id_) {
+ DVLOG(1) << __func__ << ": Empty origin ID.";
+ std::move(callback).Run(false);
+ return;
+ }
+
DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage);
base::DictionaryValue* storage_dict = update.Get();
DCHECK(storage_dict);
@@ -616,7 +736,8 @@ void MediaDrmStorageImpl::OnProvisioned(OnProvisionedCallback callback) {
// Update origin dict once origin provisioning completes. There may be
// orphaned session info from a previous provisioning. Clear them by
// recreating the dicts.
- CreateOriginDictAndReturnSessionsDict(storage_dict, origin(), origin_id_);
+ CreateOriginDictAndReturnSessionsDict(storage_dict, origin(),
+ origin_id_.value());
std::move(callback).Run(true);
}
@@ -627,12 +748,19 @@ void MediaDrmStorageImpl::SavePersistentSession(
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!IsInitialized()) {
+ if (!is_initialized_) {
DVLOG(1) << __func__ << ": Not initialized.";
std::move(callback).Run(false);
return;
}
+ // If this is using an empty origin ID, it cannot save persistent data.
+ if (!origin_id_) {
+ DVLOG(1) << __func__ << ": Empty origin ID.";
+ std::move(callback).Run(false);
+ return;
+ }
+
DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage);
base::DictionaryValue* storage_dict = update.Get();
DCHECK(storage_dict);
@@ -646,15 +774,15 @@ void MediaDrmStorageImpl::SavePersistentSession(
// branch. Deleting the profile causes reprovisioning of the origin.
if (!sessions_dict) {
DVLOG(1) << __func__ << ": No entry for origin " << origin();
- sessions_dict = CreateOriginDictAndReturnSessionsDict(storage_dict,
- origin(), origin_id_);
+ sessions_dict = CreateOriginDictAndReturnSessionsDict(
+ storage_dict, origin(), origin_id_.value());
DCHECK(sessions_dict);
}
DVLOG_IF(1, sessions_dict->FindKey(session_id))
<< __func__ << ": Session ID already exists and will be replaced.";
- // The key type of the session should be valid. MeidaDrmKeyType::MIN/UNKNOWN
+ // The key type of the session should be valid. MediaDrmKeyType::MIN/UNKNOWN
// is an invalid type and caller should never pass it here.
DCHECK_GT(session_data->key_type, media::MediaDrmKeyType::MIN);
DCHECK_LE(session_data->key_type, media::MediaDrmKeyType::MAX);
@@ -673,12 +801,19 @@ void MediaDrmStorageImpl::LoadPersistentSession(
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!IsInitialized()) {
+ if (!is_initialized_) {
DVLOG(1) << __func__ << ": Not initialized.";
std::move(callback).Run(nullptr);
return;
}
+ // If this is using an empty origin ID, it cannot save persistent data.
+ if (!origin_id_) {
+ DVLOG(1) << __func__ << ": Empty origin ID.";
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
const base::Value* sessions_dict =
GetSessionsDictFromStorageDict<const base::Value>(
pref_service_->GetDictionary(kMediaDrmStorage), origin().Serialize());
@@ -713,12 +848,19 @@ void MediaDrmStorageImpl::RemovePersistentSession(
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!IsInitialized()) {
+ if (!is_initialized_) {
DVLOG(1) << __func__ << ": Not initialized.";
std::move(callback).Run(false);
return;
}
+ // If this is using an empty origin ID, it cannot save persistent data.
+ if (!origin_id_) {
+ DVLOG(1) << __func__ << ": Empty origin ID.";
+ std::move(callback).Run(false);
+ return;
+ }
+
DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage);
base::Value* sessions_dict = GetSessionsDictFromStorageDict<base::Value>(
diff --git a/chromium/components/cdm/browser/media_drm_storage_impl.h b/chromium/components/cdm/browser/media_drm_storage_impl.h
index 4ca4ae1c7e4..c52038011ff 100644
--- a/chromium/components/cdm/browser/media_drm_storage_impl.h
+++ b/chromium/components/cdm/browser/media_drm_storage_impl.h
@@ -6,10 +6,12 @@
#define COMPONENTS_CDM_BROWSER_MEDIA_DRM_STORAGE_IMPL_H_
#include <set>
+#include <string>
#include <vector>
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
@@ -36,8 +38,19 @@ namespace cdm {
class MediaDrmStorageImpl final
: public content::FrameServiceBase<media::mojom::MediaDrmStorage> {
public:
- using GetOriginIdCB = base::RepeatingCallback<void(
- base::OnceCallback<void(const base::UnguessableToken&)>)>;
+ // When using per-origin provisioning, this is the ID for the origin.
+ // If not specified, the device specific origin ID is to be used.
+ using MediaDrmOriginId = base::Optional<base::UnguessableToken>;
+
+ // |success| is true if an origin ID was obtained and |origin_id| is
+ // specified, false otherwise.
+ using OriginIdObtainedCB =
+ base::OnceCallback<void(bool success, const MediaDrmOriginId& origin_id)>;
+ using GetOriginIdCB = base::RepeatingCallback<void(OriginIdObtainedCB)>;
+
+ // |callback| returns true if an empty origin ID is allowed, false if not.
+ using AllowEmptyOriginIdCB =
+ base::RepeatingCallback<void(base::OnceCallback<void(bool)> callback)>;
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
@@ -63,9 +76,14 @@ class MediaDrmStorageImpl final
base::Time end,
const base::RepeatingCallback<bool(const GURL&)>& filter);
+ // |get_origin_id_cb| must be provided and is used to obtain an origin ID.
+ // |allow_empty_origin_id_cb| is used to determine if an empty origin ID is
+ // allowed or not. It is called if |get_origin_id_cb| is unable to return an
+ // origin ID.
MediaDrmStorageImpl(content::RenderFrameHost* render_frame_host,
PrefService* pref_service,
GetOriginIdCB get_origin_id_cb,
+ AllowEmptyOriginIdCB allow_empty_origin_id_cb,
media::mojom::MediaDrmStorageRequest request);
// media::mojom::MediaDrmStorage implementation.
@@ -79,27 +97,33 @@ class MediaDrmStorageImpl final
void RemovePersistentSession(const std::string& session_id,
RemovePersistentSessionCallback callback) final;
- bool IsInitialized() const { return !!origin_id_; }
-
private:
// |this| can only be destructed as a FrameServiceBase.
~MediaDrmStorageImpl() final;
// Called when |get_origin_id_cb_| asynchronously returns a origin ID as part
- // of Initialize();
- void OnOriginIdObtained(const base::UnguessableToken& origin_id);
+ // of Initialize().
+ void OnOriginIdObtained(bool success, const MediaDrmOriginId& origin_id);
- PrefService* const pref_service_ = nullptr;
+ // Called after checking if an empty origin ID is allowed.
+ void OnEmptyOriginIdAllowed(bool allowed);
+
+ PrefService* const pref_service_;
GetOriginIdCB get_origin_id_cb_;
+ AllowEmptyOriginIdCB allow_empty_origin_id_cb_;
// ID for the current origin. Per EME spec on individualization,
// implementation should not expose application-specific information.
- base::UnguessableToken origin_id_;
+ // If not specified, the device specific origin ID is to be used.
+ MediaDrmOriginId origin_id_;
// As Initialize() may be asynchronous, save the InitializeCallback when
// necessary.
InitializeCallback init_cb_;
+ // Set when initialized.
+ bool is_initialized_ = false;
+
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<MediaDrmStorageImpl> weak_factory_;
};
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 d89ce253400..50c44d48a33 100644
--- a/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc
+++ b/chromium/components/cdm/browser/media_drm_storage_impl_unittest.cc
@@ -7,6 +7,8 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
+#include "base/optional.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/unguessable_token.h"
@@ -28,24 +30,39 @@ const char kMediaDrmStorage[] = "media.media_drm_storage";
const char kTestOrigin[] = "https://www.testorigin.com:80";
const char kTestOrigin2[] = "https://www.testorigin2.com:80";
-void OnMediaDrmStorageInit(base::UnguessableToken* out_origin_id,
- const base::UnguessableToken& origin_id) {
+using MediaDrmOriginId = MediaDrmStorageImpl::MediaDrmOriginId;
+
+void OnMediaDrmStorageInit(bool expected_success,
+ MediaDrmOriginId* out_origin_id,
+ bool success,
+ const MediaDrmOriginId& origin_id) {
DCHECK(out_origin_id);
- DCHECK(origin_id);
+ DCHECK_EQ(success, expected_success);
*out_origin_id = origin_id;
}
-void CreateOriginId(
- base::OnceCallback<void(const base::UnguessableToken&)> callback) {
- std::move(callback).Run(base::UnguessableToken::Create());
+void CreateOriginId(MediaDrmStorageImpl::OriginIdObtainedCB callback) {
+ std::move(callback).Run(true, base::UnguessableToken::Create());
+}
+
+void CreateEmptyOriginId(MediaDrmStorageImpl::OriginIdObtainedCB callback) {
+ // |callback| has to fail in order to check if empty origin ID allowed.
+ std::move(callback).Run(false, base::nullopt);
}
-void CreateOriginIdAsync(
- base::OnceCallback<void(const base::UnguessableToken&)> callback) {
+void CreateOriginIdAsync(MediaDrmStorageImpl::OriginIdObtainedCB callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&CreateOriginId, std::move(callback)));
}
+void AllowEmptyOriginId(base::OnceCallback<void(bool)> callback) {
+ std::move(callback).Run(true);
+}
+
+void DisallowEmptyOriginId(base::OnceCallback<void(bool)> callback) {
+ std::move(callback).Run(false);
+}
+
} // namespace
class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
@@ -66,6 +83,7 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
void TearDown() override {
media_drm_storage_.reset();
base::RunLoop().RunUntilIdle();
+ RenderViewHostTestHarness::TearDown();
}
protected:
@@ -73,7 +91,9 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
std::unique_ptr<media::MediaDrmStorage> CreateMediaDrmStorage(
content::RenderFrameHost* rfh,
- MediaDrmStorageImpl::GetOriginIdCB get_origin_id_cb) {
+ MediaDrmStorageImpl::GetOriginIdCB get_origin_id_cb,
+ MediaDrmStorageImpl::AllowEmptyOriginIdCB allow_empty_cb =
+ base::BindRepeating(&AllowEmptyOriginId)) {
media::mojom::MediaDrmStoragePtr media_drm_storage_ptr;
auto request = mojo::MakeRequest(&media_drm_storage_ptr);
@@ -82,14 +102,15 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
// The created object will be destroyed on connection error.
new MediaDrmStorageImpl(rfh, pref_service_.get(),
- std::move(get_origin_id_cb), std::move(request));
+ std::move(get_origin_id_cb),
+ std::move(allow_empty_cb), std::move(request));
return std::move(media_drm_storage);
}
std::unique_ptr<media::MediaDrmStorage> CreateAndInitMediaDrmStorage(
const GURL& origin,
- base::UnguessableToken* origin_id) {
+ MediaDrmOriginId* origin_id) {
DCHECK(origin_id);
std::unique_ptr<media::MediaDrmStorage> media_drm_storage =
@@ -97,7 +118,7 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
base::BindRepeating(&CreateOriginId));
media_drm_storage->Initialize(
- base::BindOnce(OnMediaDrmStorageInit, origin_id));
+ base::BindOnce(OnMediaDrmStorageInit, true, origin_id));
base::RunLoop().RunUntilIdle();
@@ -190,7 +211,7 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
std::unique_ptr<media::MediaDrmStorage> media_drm_storage_;
- base::UnguessableToken origin_id_;
+ MediaDrmOriginId origin_id_;
};
// MediaDrmStorageImpl should write origin ID to persistent storage when
@@ -199,10 +220,10 @@ class MediaDrmStorageImplTest : public content::RenderViewHostTestHarness {
// fully initialized.
// TODO(yucliu): Test origin ID is re-generated after clearing licenses.
TEST_F(MediaDrmStorageImplTest, Initialize_OriginIdNotChanged) {
- base::UnguessableToken original_origin_id = origin_id_;
+ MediaDrmOriginId original_origin_id = origin_id_;
ASSERT_TRUE(original_origin_id);
- base::UnguessableToken origin_id;
+ MediaDrmOriginId origin_id;
std::unique_ptr<media::MediaDrmStorage> storage =
CreateAndInitMediaDrmStorage(GURL(kTestOrigin), &origin_id);
EXPECT_EQ(origin_id, original_origin_id);
@@ -219,12 +240,16 @@ TEST_F(MediaDrmStorageImplTest, Initialize_Concurrent) {
std::unique_ptr<media::MediaDrmStorage> storage2 =
CreateMediaDrmStorage(rfh, base::BindRepeating(&CreateOriginId));
- base::UnguessableToken origin_id_1;
- storage1->Initialize(base::BindOnce(OnMediaDrmStorageInit, &origin_id_1));
- base::UnguessableToken origin_id_2;
- storage2->Initialize(base::BindOnce(OnMediaDrmStorageInit, &origin_id_2));
+ MediaDrmOriginId origin_id_1;
+ storage1->Initialize(
+ base::BindOnce(OnMediaDrmStorageInit, true, &origin_id_1));
+ MediaDrmOriginId origin_id_2;
+ storage2->Initialize(
+ base::BindOnce(OnMediaDrmStorageInit, true, &origin_id_2));
base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(origin_id_1);
+ EXPECT_TRUE(origin_id_2);
EXPECT_EQ(origin_id_1, origin_id_2);
}
@@ -236,20 +261,24 @@ TEST_F(MediaDrmStorageImplTest, Initialize_Concurrent_Async) {
std::unique_ptr<media::MediaDrmStorage> storage2 =
CreateMediaDrmStorage(rfh, base::BindRepeating(&CreateOriginIdAsync));
- base::UnguessableToken origin_id_1;
- storage1->Initialize(base::BindOnce(OnMediaDrmStorageInit, &origin_id_1));
- base::UnguessableToken origin_id_2;
- storage2->Initialize(base::BindOnce(OnMediaDrmStorageInit, &origin_id_2));
+ MediaDrmOriginId origin_id_1;
+ storage1->Initialize(
+ base::BindOnce(OnMediaDrmStorageInit, true, &origin_id_1));
+ MediaDrmOriginId origin_id_2;
+ storage2->Initialize(
+ base::BindOnce(OnMediaDrmStorageInit, true, &origin_id_2));
base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(origin_id_1);
+ EXPECT_TRUE(origin_id_2);
EXPECT_EQ(origin_id_1, origin_id_2);
}
TEST_F(MediaDrmStorageImplTest, Initialize_DifferentOrigins) {
- base::UnguessableToken origin_id_1 = origin_id_;
+ MediaDrmOriginId origin_id_1 = origin_id_;
ASSERT_TRUE(origin_id_1);
- base::UnguessableToken origin_id_2;
+ MediaDrmOriginId origin_id_2;
auto storage2 =
CreateAndInitMediaDrmStorage(GURL(kTestOrigin2), &origin_id_2);
ASSERT_TRUE(origin_id_2);
@@ -369,4 +398,31 @@ TEST_F(MediaDrmStorageImplTest, GetOriginsModifiedSince) {
EXPECT_EQ(origins4, std::vector<GURL>{GURL(kTestOrigin)});
}
+TEST_F(MediaDrmStorageImplTest, AllowEmptyOriginId) {
+ content::RenderFrameHost* rfh = SimulateNavigation(GURL(kTestOrigin2));
+
+ std::unique_ptr<media::MediaDrmStorage> storage =
+ CreateMediaDrmStorage(rfh, base::BindRepeating(&CreateEmptyOriginId));
+
+ MediaDrmOriginId origin_id;
+ storage->Initialize(base::BindOnce(OnMediaDrmStorageInit, true, &origin_id));
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(origin_id);
+}
+
+TEST_F(MediaDrmStorageImplTest, DisallowEmptyOriginId) {
+ content::RenderFrameHost* rfh = SimulateNavigation(GURL(kTestOrigin2));
+
+ std::unique_ptr<media::MediaDrmStorage> storage =
+ CreateMediaDrmStorage(rfh, base::BindRepeating(&CreateEmptyOriginId),
+ base::BindRepeating(&DisallowEmptyOriginId));
+
+ MediaDrmOriginId origin_id;
+ storage->Initialize(base::BindOnce(OnMediaDrmStorageInit, false, &origin_id));
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_FALSE(origin_id);
+}
+
} // namespace cdm
diff --git a/chromium/components/certificate_transparency/ct_known_logs.h b/chromium/components/certificate_transparency/ct_known_logs.h
index 59fbc6a9cad..9e5f081c6e9 100644
--- a/chromium/components/certificate_transparency/ct_known_logs.h
+++ b/chromium/components/certificate_transparency/ct_known_logs.h
@@ -19,16 +19,16 @@ namespace certificate_transparency {
struct CTLogInfo {
// The DER-encoded SubjectPublicKeyInfo for the log.
- const char* log_key;
+ const char* const log_key;
// The length, in bytes, of |log_key|.
- size_t log_key_length;
+ const size_t log_key_length;
// The user-friendly log name.
// Note: This will not be translated.
- const char* log_name;
+ const char* const log_name;
// The DNS API endpoint for the log.
// This is used as the parent domain for all queries about the log.
// https://github.com/google/certificate-transparency-rfcs/blob/master/dns/draft-ct-over-dns.md.
- const char* log_dns_domain;
+ const char* const log_dns_domain;
};
// Returns information about all known logs, which includes those that are
diff --git a/chromium/components/certificate_transparency/log_dns_client.cc b/chromium/components/certificate_transparency/log_dns_client.cc
index c95e3368c26..3d47b4a3c1c 100644
--- a/chromium/components/certificate_transparency/log_dns_client.cc
+++ b/chromium/components/certificate_transparency/log_dns_client.cc
@@ -27,6 +27,7 @@
#include "net/dns/dns_config.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_transaction.h"
+#include "net/dns/dns_util.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/record_parsed.h"
#include "net/dns/record_rdata.h"
@@ -160,18 +161,22 @@ class AuditProofQueryImpl : public LogDnsClient::AuditProofQuery {
// AuditProofQuery does not outlive LogDnsClient, so it's safe to leave
// ownership of |dns_client| with LogDnsClient.
AuditProofQueryImpl(net::DnsClient* dns_client,
+ net::URLRequestContext* url_request_context,
const std::string& domain_for_log,
const net::NetLogWithSource& net_log);
~AuditProofQueryImpl() override;
// Begins the process of getting an audit proof for the CT log entry with a
- // leaf hash of |leaf_hash|. The proof will be for a tree of size |tree_size|.
- // If it cannot be obtained synchronously, net::ERR_IO_PENDING will be
- // returned and |callback| will be invoked when the operation has completed
- // asynchronously. If the operation is cancelled (by deleting the
- // AuditProofQueryImpl), |cancellation_callback| will be invoked.
+ // leaf hash of |leaf_hash|. If |lookup_securely| is true, only secure DNS
+ // lookups will be performed, otherwise only insecure DNS lookups will be
+ // performed. The proof will be for a tree of size |tree_size|. If the proof
+ // cannot be obtained synchronously, net::ERR_IO_PENDING will be returned and
+ // |callback| will be invoked when the operation has completed asynchronously.
+ // If the operation is cancelled (by deleting the AuditProofQueryImpl),
+ // |cancellation_callback| will be invoked.
net::Error Start(std::string leaf_hash,
+ bool lookup_securely,
uint64_t tree_size,
net::CompletionOnceCallback callback,
base::OnceClosure cancellation_callback);
@@ -197,7 +202,8 @@ class AuditProofQueryImpl : public LogDnsClient::AuditProofQuery {
// is kept alive in |current_dns_transaction_|.
void OnDnsTransactionComplete(net::DnsTransaction* transaction,
int net_error,
- const net::DnsResponse* response);
+ const net::DnsResponse* response,
+ bool secure);
// Requests the leaf index for the CT log entry with |leaf_hash_|.
net::Error RequestLeafIndex();
@@ -239,6 +245,8 @@ class AuditProofQueryImpl : public LogDnsClient::AuditProofQuery {
std::string domain_for_log_;
// The Merkle leaf hash of the CT log entry an audit proof is required for.
std::string leaf_hash_;
+ // Whether the DNS request should be sent securely or insecurely.
+ bool lookup_securely_;
// The audit proof to populate.
net::ct::MerkleAuditProof proof_;
// The callback to invoke when the query is complete.
@@ -247,6 +255,8 @@ class AuditProofQueryImpl : public LogDnsClient::AuditProofQuery {
base::OnceClosure cancellation_callback_;
// The DnsClient to use for sending DNS requests to the CT log.
net::DnsClient* dns_client_;
+ // The URLRequestContext to use for sending DoH requests to the CT log.
+ net::URLRequestContext* url_request_context_;
// The most recent DNS request. Null if no DNS requests have been made.
std::unique_ptr<net::DnsTransaction> current_dns_transaction_;
// The most recent DNS response. Only valid so long as the corresponding DNS
@@ -260,12 +270,15 @@ class AuditProofQueryImpl : public LogDnsClient::AuditProofQuery {
base::WeakPtrFactory<AuditProofQueryImpl> weak_ptr_factory_;
};
-AuditProofQueryImpl::AuditProofQueryImpl(net::DnsClient* dns_client,
- const std::string& domain_for_log,
- const net::NetLogWithSource& net_log)
+AuditProofQueryImpl::AuditProofQueryImpl(
+ net::DnsClient* dns_client,
+ net::URLRequestContext* url_request_context,
+ const std::string& domain_for_log,
+ const net::NetLogWithSource& net_log)
: next_state_(State::NONE),
domain_for_log_(domain_for_log),
dns_client_(dns_client),
+ url_request_context_(url_request_context),
last_dns_response_(nullptr),
net_log_(net_log),
weak_ptr_factory_(this) {
@@ -281,6 +294,7 @@ AuditProofQueryImpl::~AuditProofQueryImpl() {
// |leaf_hash| is not a const-ref to allow callers to std::move that string into
// the method, avoiding the need to make a copy.
net::Error AuditProofQueryImpl::Start(std::string leaf_hash,
+ bool lookup_securely,
uint64_t tree_size,
net::CompletionOnceCallback callback,
base::OnceClosure cancellation_callback) {
@@ -289,6 +303,7 @@ net::Error AuditProofQueryImpl::Start(std::string leaf_hash,
start_time_ = base::TimeTicks::Now();
proof_.tree_size = tree_size;
leaf_hash_ = std::move(leaf_hash);
+ lookup_securely_ = lookup_securely;
callback_ = std::move(callback);
cancellation_callback_ = std::move(cancellation_callback);
// The first step in the query is to request the leaf index corresponding to
@@ -355,7 +370,8 @@ net::Error AuditProofQueryImpl::DoLoop(net::Error result) {
void AuditProofQueryImpl::OnDnsTransactionComplete(
net::DnsTransaction* transaction,
int net_error,
- const net::DnsResponse* response) {
+ const net::DnsResponse* response,
+ bool secure) {
DCHECK_EQ(current_dns_transaction_.get(), transaction);
last_dns_response_ = response;
net::Error result = DoLoop(static_cast<net::Error>(net_error));
@@ -471,16 +487,21 @@ bool AuditProofQueryImpl::StartDnsTransaction(const std::string& qname) {
qname, net::dns_protocol::kTypeTXT,
base::BindOnce(&AuditProofQueryImpl::OnDnsTransactionComplete,
weak_ptr_factory_.GetWeakPtr()),
- net_log_);
+ net_log_,
+ lookup_securely_ ? net::SecureDnsMode::SECURE : net::SecureDnsMode::OFF);
+ DCHECK(url_request_context_);
+ current_dns_transaction_->SetRequestContext(url_request_context_);
current_dns_transaction_->Start();
return true;
}
LogDnsClient::LogDnsClient(std::unique_ptr<net::DnsClient> dns_client,
+ net::URLRequestContext* url_request_context,
const net::NetLogWithSource& net_log,
size_t max_in_flight_queries)
: dns_client_(std::move(dns_client)),
+ url_request_context_(url_request_context),
net_log_(net_log),
in_flight_queries_(0),
max_in_flight_queries_(max_in_flight_queries) {
@@ -511,6 +532,7 @@ void LogDnsClient::NotifyWhenNotThrottled(base::OnceClosure callback) {
net::Error LogDnsClient::QueryAuditProof(
base::StringPiece domain_for_log,
std::string leaf_hash,
+ bool lookup_securely,
uint64_t tree_size,
std::unique_ptr<AuditProofQuery>* out_query,
const net::CompletionCallback& callback) {
@@ -524,13 +546,13 @@ net::Error LogDnsClient::QueryAuditProof(
return net::ERR_TEMPORARILY_THROTTLED;
}
- auto* query = new AuditProofQueryImpl(dns_client_.get(),
+ auto* query = new AuditProofQueryImpl(dns_client_.get(), url_request_context_,
domain_for_log.as_string(), net_log_);
out_query->reset(query);
++in_flight_queries_;
- return query->Start(std::move(leaf_hash), tree_size,
+ return query->Start(std::move(leaf_hash), lookup_securely, tree_size,
base::BindOnce(&LogDnsClient::QueryAuditProofComplete,
base::Unretained(this), callback),
base::BindOnce(&LogDnsClient::QueryAuditProofCancelled,
diff --git a/chromium/components/certificate_transparency/log_dns_client.h b/chromium/components/certificate_transparency/log_dns_client.h
index 1a280f383f1..0376f61e7d1 100644
--- a/chromium/components/certificate_transparency/log_dns_client.h
+++ b/chromium/components/certificate_transparency/log_dns_client.h
@@ -17,6 +17,7 @@
#include "net/base/net_errors.h"
#include "net/base/network_change_notifier.h"
#include "net/log/net_log_with_source.h"
+#include "net/url_request/url_request_context.h"
namespace net {
class DnsClient;
@@ -49,6 +50,7 @@ class LogDnsClient : public net::NetworkChangeNotifier::DNSObserver {
// limit will fail with net::TEMPORARILY_THROTTLED. Setting this to 0 will
// disable this limit.
LogDnsClient(std::unique_ptr<net::DnsClient> dns_client,
+ net::URLRequestContext* url_request_context,
const net::NetLogWithSource& net_log,
size_t max_concurrent_queries);
// Must be deleted on the same thread that it was created on.
@@ -76,6 +78,10 @@ class LogDnsClient : public net::NetworkChangeNotifier::DNSObserver {
// The |leaf_hash| is the SHA-256 Merkle leaf hash (see RFC6962, section 2.1).
// The size of the CT log tree, for which the proof is requested, must be
// provided in |tree_size|.
+ // The field |lookup_securely| specifies whether DNS lookups should be
+ // performed securely or insecurely. This value should be set according to
+ // whether the hostname lookup was resolved securely or not in order to
+ // help achieve resolver consistency between the hostname and proof lookups.
// A handle to the query will be placed in |out_query|. The audit proof can be
// obtained from that once the query completes. Deleting this handle before
// the query completes will cancel it. It must not outlive the LogDnsClient.
@@ -94,6 +100,7 @@ class LogDnsClient : public net::NetworkChangeNotifier::DNSObserver {
// not a SHA-256 hash.
net::Error QueryAuditProof(base::StringPiece domain_for_log,
std::string leaf_hash,
+ bool lookup_securely,
uint64_t tree_size,
std::unique_ptr<AuditProofQuery>* out_query,
const net::CompletionCallback& callback);
@@ -118,6 +125,8 @@ class LogDnsClient : public net::NetworkChangeNotifier::DNSObserver {
// Used to perform DNS queries.
std::unique_ptr<net::DnsClient> dns_client_;
+ // Used to perform DoH queries.
+ net::URLRequestContext* url_request_context_;
// Passed to the DNS client for logging.
net::NetLogWithSource net_log_;
// The number of queries that are currently in-flight.
diff --git a/chromium/components/certificate_transparency/log_dns_client_unittest.cc b/chromium/components/certificate_transparency/log_dns_client_unittest.cc
index a7027d8acd1..93da272e1ad 100644
--- a/chromium/components/certificate_transparency/log_dns_client_unittest.cc
+++ b/chromium/components/certificate_transparency/log_dns_client_unittest.cc
@@ -25,9 +25,12 @@
#include "net/cert/signed_certificate_timestamp.h"
#include "net/dns/dns_client.h"
#include "net/dns/dns_config.h"
+#include "net/dns/dns_test_util.h"
#include "net/dns/public/dns_protocol.h"
#include "net/log/net_log.h"
#include "net/test/gtest_util.h"
+#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -104,6 +107,18 @@ std::vector<std::string> GetSampleAuditProof(size_t length) {
} // namespace
class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
+ void SetUp() override {
+ net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ filter->AddHostnameInterceptor(
+ "https", "mock.http",
+ std::make_unique<MockLogDnsTraffic::DohJobInterceptor>());
+ }
+
+ void TearDown() override {
+ net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ filter->ClearHandlers();
+ }
+
protected:
LogDnsClientTest()
: network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
@@ -113,9 +128,17 @@ class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
std::unique_ptr<LogDnsClient> CreateLogDnsClient(
size_t max_concurrent_queries) {
- return std::make_unique<LogDnsClient>(mock_dns_.CreateDnsClient(),
- net::NetLogWithSource(),
- max_concurrent_queries);
+ return std::make_unique<LogDnsClient>(
+ mock_dns_.CreateDnsClient(), new net::TestURLRequestContext(),
+ net::NetLogWithSource(), max_concurrent_queries);
+ }
+
+ std::unique_ptr<LogDnsClient> CreateRuleBasedLogDnsClient(
+ net::MockDnsClientRuleList rules) {
+ return std::make_unique<LogDnsClient>(
+ std::make_unique<net::MockDnsClient>(net::DnsConfig(),
+ std::move(rules)),
+ new net::TestURLRequestContext(), net::NetLogWithSource(), 0);
}
// Convenience function for calling QueryAuditProof synchronously.
@@ -149,8 +172,10 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
kLeafIndexQnames[0], net::dns_protocol::kRcodeNXDOMAIN));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
- IsError(net::ERR_NAME_NOT_RESOLVED));
+ ASSERT_THAT(
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
+ IsError(net::ERR_NAME_NOT_RESOLVED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_NAME_NOT_RESOLVED, 1);
histograms_.ExpectUniqueSample(kLeafIndexRcodeHistogram,
@@ -165,8 +190,10 @@ TEST_P(LogDnsClientTest,
kLeafIndexQnames[0], net::dns_protocol::kRcodeSERVFAIL));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
- IsError(net::ERR_DNS_SERVER_FAILED));
+ ASSERT_THAT(
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
+ IsError(net::ERR_DNS_SERVER_FAILED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_DNS_SERVER_FAILED, 1);
histograms_.ExpectUniqueSample(kLeafIndexRcodeHistogram,
@@ -181,8 +208,10 @@ TEST_P(LogDnsClientTest,
kLeafIndexQnames[0], net::dns_protocol::kRcodeREFUSED));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
- IsError(net::ERR_DNS_SERVER_FAILED));
+ ASSERT_THAT(
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
+ IsError(net::ERR_DNS_SERVER_FAILED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_DNS_SERVER_FAILED, 1);
histograms_.ExpectUniqueSample(kLeafIndexRcodeHistogram,
@@ -212,7 +241,8 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsMalformedLeafIndexResponse) {
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
ASSERT_THAT(
- QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_DNS_MALFORMED_RESPONSE, 1);
@@ -225,19 +255,22 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsMalformedLeafIndexResponse) {
TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &query),
+ ASSERT_THAT(QueryAuditProof("", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
IsError(net::ERR_INVALID_ARGUMENT));
}
TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) {
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", "foo", kTreeSizes[0], &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", "foo", false /* lookup_securely */,
+ kTreeSizes[0], &query),
IsError(net::ERR_INVALID_ARGUMENT));
}
TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) {
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", "", kTreeSizes[0], &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", "", false /* lookup_securely */,
+ kTreeSizes[0], &query),
IsError(net::ERR_INVALID_ARGUMENT));
}
@@ -247,8 +280,10 @@ TEST_P(LogDnsClientTest,
kLeafIndexQnames[0], net::ERR_CONNECTION_REFUSED));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
- IsError(net::ERR_CONNECTION_REFUSED));
+ ASSERT_THAT(
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
+ IsError(net::ERR_CONNECTION_REFUSED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_CONNECTION_REFUSED, 1);
histograms_.ExpectTotalCount(kLeafIndexRcodeHistogram, 0);
@@ -261,8 +296,10 @@ TEST_P(LogDnsClientTest,
ASSERT_TRUE(mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &query),
- IsError(net::ERR_DNS_TIMED_OUT));
+ ASSERT_THAT(
+ QueryAuditProof("ct.test", kLeafHashes[0], false /* lookup_securely */,
+ kTreeSizes[0], &query),
+ IsError(net::ERR_DNS_TIMED_OUT));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram,
-net::ERR_DNS_TIMED_OUT, 1);
histograms_.ExpectTotalCount(kLeafIndexRcodeHistogram, 0);
@@ -290,7 +327,8 @@ TEST_P(LogDnsClientTest, QueryAuditProof) {
}
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsOk());
const net::ct::MerkleAuditProof& proof = query->GetProof();
EXPECT_THAT(proof.leaf_index, Eq(123456u));
@@ -333,7 +371,8 @@ TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
audit_proof.end()));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsOk());
const net::ct::MerkleAuditProof& proof = query->GetProof();
EXPECT_THAT(proof.leaf_index, Eq(123456u));
@@ -356,7 +395,8 @@ TEST_P(LogDnsClientTest,
"0.123456.999999.tree.ct.test.", net::dns_protocol::kRcodeNXDOMAIN));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_NAME_NOT_RESOLVED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -376,7 +416,8 @@ TEST_P(LogDnsClientTest,
"0.123456.999999.tree.ct.test.", net::dns_protocol::kRcodeSERVFAIL));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_SERVER_FAILED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -396,7 +437,8 @@ TEST_P(LogDnsClientTest,
"0.123456.999999.tree.ct.test.", net::dns_protocol::kRcodeREFUSED));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_SERVER_FAILED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -419,7 +461,8 @@ TEST_P(
"0.123456.999999.tree.ct.test.", std::vector<base::StringPiece>()));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -452,7 +495,8 @@ TEST_P(
{first_chunk_of_proof, second_chunk_of_proof}));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -475,7 +519,8 @@ TEST_P(LogDnsClientTest,
"0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -497,7 +542,8 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) {
"0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -518,7 +564,8 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) {
"0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_MALFORMED_RESPONSE));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -536,7 +583,8 @@ TEST_P(LogDnsClientTest,
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 123456, &query),
IsError(net::ERR_INVALID_ARGUMENT));
}
@@ -546,7 +594,8 @@ TEST_P(LogDnsClientTest,
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 123456, &query),
IsError(net::ERR_INVALID_ARGUMENT));
}
@@ -558,7 +607,8 @@ TEST_P(LogDnsClientTest,
"0.123456.999999.tree.ct.test.", net::ERR_CONNECTION_REFUSED));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_CONNECTION_REFUSED));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -577,7 +627,8 @@ TEST_P(LogDnsClientTest,
mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test."));
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
- ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &query),
+ ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999, &query),
IsError(net::ERR_DNS_TIMED_OUT));
histograms_.ExpectUniqueSample(kLeafIndexErrorHistogram, -net::OK, 1);
@@ -591,7 +642,8 @@ TEST_P(LogDnsClientTest,
TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) {
std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
net::DnsClient* dns_client = tmp.get();
- LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
+ LogDnsClient log_client(std::move(tmp), new net::TestURLRequestContext(),
+ net::NetLogWithSource(), 0);
// Get the current DNS config, modify it and broadcast the update.
net::DnsConfig config(*dns_client->GetConfig());
@@ -607,7 +659,8 @@ TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) {
TEST_P(LogDnsClientTest, IgnoresLatestDnsConfigIfInvalid) {
std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
net::DnsClient* dns_client = tmp.get();
- LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
+ LogDnsClient log_client(std::move(tmp), new net::TestURLRequestContext(),
+ net::NetLogWithSource(), 0);
// Get the current DNS config, modify it and broadcast the update.
net::DnsConfig config(*dns_client->GetConfig());
@@ -643,12 +696,14 @@ TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigMidQuery) {
std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
net::DnsClient* dns_client = tmp.get();
- LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
+ LogDnsClient log_client(std::move(tmp), new net::TestURLRequestContext(),
+ net::NetLogWithSource(), 0);
// Start query.
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
net::TestCompletionCallback callback;
- ASSERT_THAT(log_client.QueryAuditProof("ct.test", kLeafHashes[0], 999999,
+ ASSERT_THAT(log_client.QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
&query, callback.callback()),
IsError(net::ERR_IO_PENDING));
@@ -736,10 +791,10 @@ TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) {
// Start the queries.
for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
- ASSERT_THAT(
- log_client->QueryAuditProof("ct.test", kLeafHashes[i], kTreeSizes[i],
- &queries[i], callbacks[i].callback()),
- IsError(net::ERR_IO_PENDING))
+ ASSERT_THAT(log_client->QueryAuditProof(
+ "ct.test", kLeafHashes[i], false /* lookup_securely */,
+ kTreeSizes[i], &queries[i], callbacks[i].callback()),
+ IsError(net::ERR_IO_PENDING))
<< "query #" << i;
}
@@ -773,19 +828,17 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
ASSERT_TRUE(
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456));
- // It should require 3 requests to collect the entire audit proof, as there is
- // only space for 7 nodes per TXT record. One node is 32 bytes long and the
- // TXT RDATA can have a maximum length of 255 bytes (255 / 32).
- // Rate limiting should not interfere with these requests.
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "0.123456.999999.tree.ct.test.", audit_proof.begin(),
- audit_proof.begin() + 7));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "7.123456.999999.tree.ct.test.", audit_proof.begin() + 7,
- audit_proof.begin() + 14));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "14.123456.999999.tree.ct.test.", audit_proof.begin() + 14,
- audit_proof.end()));
+ // It takes a number of DNS requests to retrieve the entire |audit_proof|
+ // (see |kMaxProofNodesPerDnsResponse|).
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+
+ ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end));
+ }
const size_t kMaxConcurrentQueries = 1;
std::unique_ptr<LogDnsClient> log_client =
@@ -794,13 +847,15 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
// Try to start the queries.
std::unique_ptr<LogDnsClient::AuditProofQuery> query1;
net::TestCompletionCallback callback1;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
&query1, callback1.callback()),
IsError(net::ERR_IO_PENDING));
std::unique_ptr<LogDnsClient::AuditProofQuery> query2;
net::TestCompletionCallback callback2;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1],
+ false /* lookup_securely */, 999999,
&query2, callback2.callback()),
IsError(net::ERR_TEMPORARILY_THROTTLED));
@@ -814,19 +869,20 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
// Try a third query, which should succeed now that the first is finished.
ASSERT_TRUE(
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "0.666.999999.tree.ct.test.", audit_proof.begin(),
- audit_proof.begin() + 7));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "7.666.999999.tree.ct.test.", audit_proof.begin() + 7,
- audit_proof.begin() + 14));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "14.666.999999.tree.ct.test.", audit_proof.begin() + 14,
- audit_proof.end()));
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+
+ ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
+ base::StringPrintf("%zu.666.999999.tree.ct.test.", nodes_begin),
+ audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end));
+ }
std::unique_ptr<LogDnsClient::AuditProofQuery> query3;
net::TestCompletionCallback callback3;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[2], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[2],
+ false /* lookup_securely */, 999999,
&query3, callback3.callback()),
IsError(net::ERR_IO_PENDING));
@@ -850,15 +906,15 @@ TEST_P(LogDnsClientTest, NotifiesWhenNoLongerThrottled) {
ASSERT_TRUE(
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "0.123456.999999.tree.ct.test.", audit_proof.begin(),
- audit_proof.begin() + 7));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "7.123456.999999.tree.ct.test.", audit_proof.begin() + 7,
- audit_proof.begin() + 14));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "14.123456.999999.tree.ct.test.", audit_proof.begin() + 14,
- audit_proof.end()));
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+
+ ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end));
+ }
const size_t kMaxConcurrentQueries = 1;
std::unique_ptr<LogDnsClient> log_client =
@@ -867,7 +923,8 @@ TEST_P(LogDnsClientTest, NotifiesWhenNoLongerThrottled) {
// Start a query.
std::unique_ptr<LogDnsClient::AuditProofQuery> query1;
net::TestCompletionCallback query_callback1;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
&query1, query_callback1.callback()),
IsError(net::ERR_IO_PENDING));
@@ -880,19 +937,20 @@ TEST_P(LogDnsClientTest, NotifiesWhenNoLongerThrottled) {
// Start another query to check |not_throttled_callback| doesn't fire again.
ASSERT_TRUE(
mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[1], 666));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "0.666.999999.tree.ct.test.", audit_proof.begin(),
- audit_proof.begin() + 7));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "7.666.999999.tree.ct.test.", audit_proof.begin() + 7,
- audit_proof.begin() + 14));
- ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
- "14.666.999999.tree.ct.test.", audit_proof.begin() + 14,
- audit_proof.end()));
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+
+ ASSERT_TRUE(mock_dns_.ExpectAuditProofRequestAndResponse(
+ base::StringPrintf("%zu.666.999999.tree.ct.test.", nodes_begin),
+ audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end));
+ }
std::unique_ptr<LogDnsClient::AuditProofQuery> query2;
net::TestCompletionCallback query_callback2;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1],
+ false /* lookup_securely */, 999999,
&query2, query_callback2.callback()),
IsError(net::ERR_IO_PENDING));
@@ -916,7 +974,8 @@ TEST_P(LogDnsClientTest, CanCancelQueries) {
// Start query.
std::unique_ptr<LogDnsClient::AuditProofQuery> query;
net::TestCompletionCallback callback;
- ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
&query, callback.callback()),
IsError(net::ERR_IO_PENDING));
@@ -933,9 +992,106 @@ TEST_P(LogDnsClientTest, CanCancelQueries) {
histograms_.ExpectTotalCount(kAuditProofRcodeHistogram, 0);
}
-INSTANTIATE_TEST_CASE_P(ReadMode,
- LogDnsClientTest,
- ::testing::Values(net::IoMode::ASYNC,
- net::IoMode::SYNCHRONOUS));
+TEST_P(LogDnsClientTest, SecureDnsMode_Secure) {
+ const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
+
+ net::MockDnsClientRuleList rules;
+ // Make leaf index queries for kLeafIndexQnames[0] successful only when
+ // lookup_securely is true.
+ rules.emplace_back(
+ kLeafIndexQnames[0], net::dns_protocol::kTypeTXT,
+ net::SecureDnsMode::SECURE,
+ net::MockDnsClientRule::CreateSecureResult(net::BuildTestDnsResponse(
+ kLeafIndexQnames[0],
+ std::vector<std::vector<std::string>>({{"123456"}}))),
+ false /* delay */);
+
+ // Add successful audit proof queries for lookup_securely true.
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+ rules.emplace_back(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ net::dns_protocol::kTypeTXT, net::SecureDnsMode::SECURE,
+ net::MockDnsClientRule::CreateSecureResult(net::BuildTestDnsResponse(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ {{std::accumulate(audit_proof.begin() + nodes_begin,
+ audit_proof.begin() + nodes_end,
+ std::string())}})),
+ false /* delay */
+ );
+ }
+
+ std::unique_ptr<LogDnsClient> log_client =
+ CreateRuleBasedLogDnsClient(std::move(rules));
+
+ std::unique_ptr<LogDnsClient::AuditProofQuery> query;
+ net::TestCompletionCallback callback;
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
+ &query, callback.callback()),
+ IsError(net::ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_NAME_NOT_RESOLVED));
+
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ true /* lookup_securely */, 999999,
+ &query, callback.callback()),
+ IsError(net::ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+}
+
+TEST_P(LogDnsClientTest, SecureDnsMode_Insecure) {
+ const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
+
+ net::MockDnsClientRuleList rules;
+ // Make leaf index queries for kLeafIndexQnames[0] successful only when
+ // lookup_securely is false.
+ rules.emplace_back(kLeafIndexQnames[0], net::dns_protocol::kTypeTXT,
+ net::SecureDnsMode::OFF,
+ net::MockDnsClientRule::Result(net::BuildTestDnsResponse(
+ kLeafIndexQnames[0],
+ std::vector<std::vector<std::string>>({{"123456"}}))),
+ false /* delay */);
+
+ // Add successful audit proof queries for lookup_securely false.
+ for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
+ nodes_begin += kMaxProofNodesPerDnsResponse) {
+ const size_t nodes_end = std::min(
+ nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
+ rules.emplace_back(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ net::dns_protocol::kTypeTXT, net::SecureDnsMode::OFF,
+ net::MockDnsClientRule::Result(net::BuildTestDnsResponse(
+ base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
+ {{std::accumulate(audit_proof.begin() + nodes_begin,
+ audit_proof.begin() + nodes_end,
+ std::string())}})),
+ false /* delay */
+ );
+ }
+
+ std::unique_ptr<LogDnsClient> log_client =
+ CreateRuleBasedLogDnsClient(std::move(rules));
+
+ std::unique_ptr<LogDnsClient::AuditProofQuery> query;
+ net::TestCompletionCallback callback;
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ false /* lookup_securely */, 999999,
+ &query, callback.callback()),
+ IsError(net::ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+
+ ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0],
+ true /* lookup_securely */, 999999,
+ &query, callback.callback()),
+ IsError(net::ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_NAME_NOT_RESOLVED));
+}
+
+INSTANTIATE_TEST_SUITE_P(ReadMode,
+ LogDnsClientTest,
+ ::testing::Values(net::IoMode::ASYNC,
+ net::IoMode::SYNCHRONOUS));
} // namespace certificate_transparency
diff --git a/chromium/components/certificate_transparency/mock_log_dns_traffic.cc b/chromium/components/certificate_transparency/mock_log_dns_traffic.cc
index 4f90add2559..3d0c0ea04ca 100644
--- a/chromium/components/certificate_transparency/mock_log_dns_traffic.cc
+++ b/chromium/components/certificate_transparency/mock_log_dns_traffic.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/big_endian.h"
+#include "base/bind.h"
#include "base/containers/span.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
@@ -21,6 +22,7 @@
#include "net/dns/public/dns_protocol.h"
#include "net/dns/record_rdata.h"
#include "net/socket/socket_test_util.h"
+#include "net/url_request/url_request_error_job.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace certificate_transparency {
@@ -136,6 +138,13 @@ bool CreateDnsErrorResponse(const net::DnsQuery& query,
} // namespace
+net::URLRequestJob* MockLogDnsTraffic::DohJobInterceptor::MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ return new net::URLRequestErrorJob(request, network_delegate,
+ net::ERR_NOT_IMPLEMENTED);
+}
+
// A container for all of the data needed for simulating a socket.
// This is useful because Mock{Read,Write}, SequencedSocketData and
// MockClientSocketFactory all do not take ownership of or copy their arguments,
@@ -300,6 +309,9 @@ void MockLogDnsTraffic::InitializeDnsConfig() {
// sending real DNS queries. The mock sockets don't care that the address
// is invalid.
dns_config.nameservers.push_back(net::IPEndPoint());
+ // Add a DoH server.
+ dns_config.dns_over_https_servers.push_back(
+ {"https://mock.http/dns-query{?dns}", true /* use_post */});
// Don't attempt retransmissions - just fail.
dns_config.attempts = 1;
// This ensures timeouts are long enough for memory tests.
diff --git a/chromium/components/certificate_transparency/mock_log_dns_traffic.h b/chromium/components/certificate_transparency/mock_log_dns_traffic.h
index 60b080f4cd2..d70119e9887 100644
--- a/chromium/components/certificate_transparency/mock_log_dns_traffic.h
+++ b/chromium/components/certificate_transparency/mock_log_dns_traffic.h
@@ -16,6 +16,8 @@
#include "base/strings/string_piece.h"
#include "net/dns/dns_client.h"
#include "net/socket/socket_test_util.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_interceptor.h"
namespace net {
struct DnsConfig;
@@ -120,6 +122,16 @@ class MockLogDnsTraffic {
// Allows tests to change socket read mode. Only the LogDnsClient tests should
// need to do so, to ensure consistent behaviour regardless of mode.
friend class LogDnsClientTest;
+ friend class SingleTreeTrackerTest;
+
+ class DohJobInterceptor : public net::URLRequestInterceptor {
+ public:
+ DohJobInterceptor() {}
+
+ net::URLRequestJob* MaybeInterceptRequest(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+ };
class MockSocketData;
diff --git a/chromium/components/certificate_transparency/single_tree_tracker.cc b/chromium/components/certificate_transparency/single_tree_tracker.cc
index b20bc9e1eaf..854c08903b0 100644
--- a/chromium/components/certificate_transparency/single_tree_tracker.cc
+++ b/chromium/components/certificate_transparency/single_tree_tracker.cc
@@ -159,8 +159,10 @@ std::unique_ptr<base::Value> NetLogEntryAuditingEventCallback(
struct SingleTreeTracker::EntryToAudit {
base::Time sct_timestamp;
SHA256HashValue leaf_hash;
+ bool lookup_securely;
- explicit EntryToAudit(base::Time timestamp) : sct_timestamp(timestamp) {}
+ explicit EntryToAudit(base::Time timestamp, bool lookup_securely)
+ : sct_timestamp(timestamp), lookup_securely(lookup_securely) {}
};
// State of a log entry: its audit state and information necessary to
@@ -211,7 +213,9 @@ class SingleTreeTracker::NetworkObserver
// Orders entries by the SCT timestamp. In case of tie, which is very unlikely
// as it requires two SCTs issued from a log at exactly the same time, order
-// by leaf hash.
+// by leaf hash. There should never be multiple entries that are identical
+// apart from the |lookup_securely| field, so this field can be excluded from
+// the comparator.
bool SingleTreeTracker::OrderByTimestamp::operator()(
const EntryToAudit& lhs,
const EntryToAudit& rhs) const {
@@ -255,19 +259,21 @@ void SingleTreeTracker::OnSCTVerified(base::StringPiece hostname,
// It's ok to do this now, even though the inclusion check may not happen for
// some time, because SingleTreeTracker will discard the SCT if the network
// changes.
- if (!WasLookedUpOverDNS(hostname)) {
+ bool secure;
+ if (!WasLookedUpOverDNS(hostname, &secure)) {
LogCanBeCheckedForInclusionToUMA(NOT_AUDITED_NO_DNS_LOOKUP);
return;
}
- EntryToAudit entry(sct->timestamp);
+ EntryToAudit entry(sct->timestamp, secure /* lookup_securely */);
if (!GetLogEntryLeafHash(cert, sct, &entry.leaf_hash)) {
LogCanBeCheckedForInclusionToUMA(NOT_AUDITED_INVALID_LEAF_HASH);
return;
}
- // Avoid queueing multiple instances of the same entry.
- switch (GetAuditedEntryInclusionStatus(entry)) {
+ // Avoid queueing multiple instances of the same entry, ignoring the value of
+ // the |lookup_securely| field.
+ switch (GetAuditedEntryInclusionStatus(entry, nullptr)) {
case SCT_NOT_OBSERVED:
// No need to record UMA, will be done below.
break;
@@ -379,13 +385,14 @@ void SingleTreeTracker::ResetPendingQueue() {
}
SingleTreeTracker::SCTInclusionStatus
-SingleTreeTracker::GetLogEntryInclusionStatus(
+SingleTreeTracker::GetLogEntryInclusionStatusForTesting(
net::X509Certificate* cert,
- const SignedCertificateTimestamp* sct) {
- EntryToAudit entry(sct->timestamp);
+ const SignedCertificateTimestamp* sct,
+ bool* pending_lookup_securely) {
+ EntryToAudit entry(sct->timestamp, false /* lookup_securely */);
if (!GetLogEntryLeafHash(cert, sct, &entry.leaf_hash))
return SCT_NOT_OBSERVED;
- return GetAuditedEntryInclusionStatus(entry);
+ return GetAuditedEntryInclusionStatus(entry, pending_lookup_securely);
}
void SingleTreeTracker::ProcessPendingEntries() {
@@ -401,8 +408,8 @@ void SingleTreeTracker::ProcessPendingEntries() {
reinterpret_cast<const char*>(it->first.leaf_hash.data),
crypto::kSHA256Length);
net::Error result = dns_client_->QueryAuditProof(
- ct_log_->dns_domain(), leaf_hash, verified_sth_.tree_size,
- &(it->second.audit_proof_query),
+ ct_log_->dns_domain(), leaf_hash, it->first.lookup_securely,
+ verified_sth_.tree_size, &(it->second.audit_proof_query),
base::Bind(&SingleTreeTracker::OnAuditProofObtained,
base::Unretained(this), it->first));
// Handling proofs returned synchronously is not implemeted.
@@ -441,7 +448,9 @@ void SingleTreeTracker::ProcessPendingEntries() {
}
SingleTreeTracker::SCTInclusionStatus
-SingleTreeTracker::GetAuditedEntryInclusionStatus(const EntryToAudit& entry) {
+SingleTreeTracker::GetAuditedEntryInclusionStatus(
+ const EntryToAudit& entry,
+ bool* pending_lookup_securely) {
const auto checked_entries_iterator = checked_entries_.Get(entry.leaf_hash);
if (checked_entries_iterator != checked_entries_.end()) {
return SCT_INCLUDED_IN_LOG;
@@ -451,7 +460,9 @@ SingleTreeTracker::GetAuditedEntryInclusionStatus(const EntryToAudit& entry) {
if (pending_iterator == pending_entries_.end()) {
return SCT_NOT_OBSERVED;
}
-
+ // Found match in |pending_entries_|, so set |pending_lookup_securely|.
+ if (pending_lookup_securely)
+ *pending_lookup_securely = pending_iterator->first.lookup_securely;
switch (pending_iterator->second.state) {
case PENDING_NEWER_STH:
return SCT_PENDING_NEWER_STH;
@@ -525,10 +536,11 @@ void SingleTreeTracker::LogAuditResultToNetLog(const EntryToAudit& entry,
net_log_callback);
}
-bool SingleTreeTracker::WasLookedUpOverDNS(base::StringPiece hostname) const {
+bool SingleTreeTracker::WasLookedUpOverDNS(base::StringPiece hostname,
+ bool* secure) const {
net::HostCache::Entry::Source source;
net::HostCache::EntryStaleness staleness;
- return host_resolver_->HasCached(hostname, &source, &staleness) &&
+ return host_resolver_->HasCached(hostname, &source, &staleness, secure) &&
source == net::HostCache::Entry::SOURCE_DNS &&
staleness.network_changes == 0;
}
diff --git a/chromium/components/certificate_transparency/single_tree_tracker.h b/chromium/components/certificate_transparency/single_tree_tracker.h
index fa6b9d1e1f5..1beffdb2670 100644
--- a/chromium/components/certificate_transparency/single_tree_tracker.h
+++ b/chromium/components/certificate_transparency/single_tree_tracker.h
@@ -16,6 +16,7 @@
#include "net/base/hash_value.h"
#include "net/base/network_change_notifier.h"
#include "net/cert/signed_tree_head.h"
+#include "net/dns/host_cache.h"
#include "net/log/net_log_with_source.h"
namespace net {
@@ -153,13 +154,15 @@ class SingleTreeTracker {
// Must only be called for STHs issued by the log this instance tracks.
void NewSTHObserved(const net::ct::SignedTreeHead& sth);
- // Returns the status of a given log entry that is assembled from
- // |cert| and |sct|. If |cert| and |sct| were not previously observed,
- // |sct| is not an SCT for |cert| or |sct| is not for this log,
- // SCT_NOT_OBSERVED will be returned.
- SCTInclusionStatus GetLogEntryInclusionStatus(
+ // Returns the status of a given log entry that is assembled from |cert| and
+ // |sct|. If |cert| and |sct| were not previously observed, |sct| is not an
+ // SCT for |cert| or |sct| is not for this log, and SCT_NOT_OBSERVED will be
+ // returned. If the assembled entry is pending, |pending_lookup_securely| will
+ // be set to the value of the pending match's |lookup_securely| field.
+ SCTInclusionStatus GetLogEntryInclusionStatusForTesting(
net::X509Certificate* cert,
- const net::ct::SignedCertificateTimestamp* sct);
+ const net::ct::SignedCertificateTimestamp* sct,
+ bool* pending_lookup_securely = nullptr);
private:
struct EntryToAudit;
@@ -180,8 +183,12 @@ class SingleTreeTracker {
// Returns the inclusion status of the given |entry|, similar to
// GetLogEntryInclusionStatus(). The |entry| is an internal representation of
- // a certificate + SCT combination.
- SCTInclusionStatus GetAuditedEntryInclusionStatus(const EntryToAudit& entry);
+ // a certificate + SCT combination, and the |lookup_securely| value in |entry|
+ // is ignored. If |entry| has a pending status, |pending_lookup_securely| will
+ // be set to the value fo the pending match's |lookup_securely| field.
+ SCTInclusionStatus GetAuditedEntryInclusionStatus(
+ const EntryToAudit& entry,
+ bool* pending_lookup_securely);
// Processes the result of obtaining an audit proof for |entry|.
// * If an audit proof was successfully obtained and validated,
@@ -208,7 +215,7 @@ class SingleTreeTracker {
// Returns true if |hostname| has previously been looked up using DNS, and the
// network has not changed since.
- bool WasLookedUpOverDNS(base::StringPiece hostname) const;
+ bool WasLookedUpOverDNS(base::StringPiece hostname, bool* secure) const;
// Holds the latest STH fetched and verified for this log.
net::ct::SignedTreeHead verified_sth_;
diff --git a/chromium/components/certificate_transparency/single_tree_tracker_unittest.cc b/chromium/components/certificate_transparency/single_tree_tracker_unittest.cc
index 5552b64fe17..39ab151827c 100644
--- a/chromium/components/certificate_transparency/single_tree_tracker_unittest.cc
+++ b/chromium/components/certificate_transparency/single_tree_tracker_unittest.cc
@@ -32,6 +32,8 @@
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
#include "net/test/ct_test_util.h"
+#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::ct::SignedCertificateTimestamp;
@@ -174,10 +176,12 @@ void FillVectorWithValidAuditProofForTreeOfSize2(
void AddCacheEntry(net::HostCache* cache,
const std::string& hostname,
+ bool secure,
net::HostCache::Entry::Source source,
base::TimeDelta ttl) {
- cache->Set(net::HostCache::Key(hostname, net::ADDRESS_FAMILY_UNSPECIFIED, 0),
- net::HostCache::Entry(net::OK, net::AddressList(), source),
+ auto key = net::HostCache::Key(hostname, net::ADDRESS_FAMILY_UNSPECIFIED, 0);
+ key.secure = secure;
+ cache->Set(key, net::HostCache::Entry(net::OK, net::AddressList(), source),
base::TimeTicks::Now(), ttl);
}
@@ -201,12 +205,23 @@ class SingleTreeTrackerTest : public ::testing::Test {
net_change_notifier_ =
base::WrapUnique(net::NetworkChangeNotifier::CreateMock());
mock_dns_.InitializeDnsConfig();
+
+ net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ filter->AddHostnameInterceptor(
+ "https", "mock.http",
+ std::make_unique<MockLogDnsTraffic::DohJobInterceptor>());
+ }
+
+ void TearDown() override {
+ net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+ filter->ClearHandlers();
}
protected:
void CreateTreeTracker() {
log_dns_client_ = std::make_unique<LogDnsClient>(
- mock_dns_.CreateDnsClient(), net_log_with_source_, 1);
+ mock_dns_.CreateDnsClient(), new net::TestURLRequestContext(),
+ net_log_with_source_, 1);
tree_tracker_ = std::make_unique<SingleTreeTracker>(
log_, log_dns_client_.get(), &host_resolver_, &net_log_);
@@ -285,7 +300,7 @@ class SingleTreeTrackerTest : public ::testing::Test {
// the user had visited that host.
TEST_F(SingleTreeTrackerTest, DiscardsSCTWhenHostnameNotLookedUpUsingDNS) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_UNKNOWN, kZeroTTL);
base::HistogramTester histograms;
@@ -295,16 +310,16 @@ TEST_F(SingleTreeTrackerTest, DiscardsSCTWhenHostnameNotLookedUpUsingDNS) {
tree_tracker_->NewSTHObserved(sth);
// Make sure the SCT status is the same as if there's no STH for this log.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
// The status for this SCT should still be 'not observed'.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Exactly one value should be logged, indicating that the SCT could not be
// checked for inclusion because of no prior DNS lookup for this hostname.
@@ -329,16 +344,16 @@ TEST_F(SingleTreeTrackerTest, DiscardsSCTWhenHostnameIsIPLiteral) {
tree_tracker_->NewSTHObserved(sth);
// Make sure the SCT status is the same as if there's no STH for this log.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
tree_tracker_->OnSCTVerified("::1", chain_.get(), cert_sct_.get());
// The status for this SCT should still be 'not observed'.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Exactly one value should be logged, indicating that the SCT could not be
// checked for inclusion because of no prior DNS lookup for this hostname
@@ -360,7 +375,7 @@ TEST_F(SingleTreeTrackerTest, DiscardsSCTWhenHostnameIsIPLiteral) {
TEST_F(SingleTreeTrackerTest,
DiscardsSCTWhenHostnameLookedUpUsingDNSOnDiffNetwork) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
// Simulate network change.
@@ -373,16 +388,16 @@ TEST_F(SingleTreeTrackerTest,
tree_tracker_->NewSTHObserved(sth);
// Make sure the SCT status is the same as if there's no STH for this log.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
// The status for this SCT should still be 'not observed'.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Exactly one value should be logged, indicating that the SCT could not be
// checked for inclusion because of no prior DNS lookup for this hostname on
@@ -395,26 +410,83 @@ TEST_F(SingleTreeTrackerTest,
EXPECT_EQ(0u, net_log_.GetSize());
}
+TEST_F(SingleTreeTrackerTest, EntriesIndistinguishedBySecurity) {
+ CreateTreeTrackerWithDefaultDnsExpectation();
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
+ net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, true /* secure */,
+ net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
+
+ base::HistogramTester histograms;
+ // Provide an STH to the tree_tracker_.
+ SignedTreeHead sth;
+ GetSampleSignedTreeHead(&sth);
+ tree_tracker_->NewSTHObserved(sth);
+
+ // Make sure the SCT status is the same as if there's no STH for this log.
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
+
+ tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
+
+ // The status for this SCT should be 'pending inclusion check' with
+ // |pending_lookup_securely| set to true since the cache check will return the
+ // secure key.
+ bool pending_lookup_securely;
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get(), &pending_lookup_securely));
+ EXPECT_TRUE(pending_lookup_securely);
+
+ // Exactly one value should be logged, indicating the SCT can be checked for
+ // inclusion, as |tree_tracker_| did have a valid STH when it was notified
+ // of a new SCT.
+ histograms.ExpectUniqueSample(kCanCheckForInclusionHistogramName, 2, 1);
+
+ // Simulate network change.
+ host_resolver_.GetHostCache()->OnNetworkChange();
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
+ net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
+
+ tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
+
+ // The status for this SCT should still be 'pending inclusion check' with
+ // |pending_lookup_securely| set to true.
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get(), &pending_lookup_securely));
+ EXPECT_TRUE(pending_lookup_securely);
+
+ // Another value should be logged, indicating that there is already a
+ // pending audit check for this SCT.
+ histograms.ExpectBucketCount(kCanCheckForInclusionHistogramName, 6, 1);
+ // Nothing should be logged in the result histogram or net log since an
+ // inclusion check wasn't performed.
+ histograms.ExpectTotalCount(kInclusionCheckResultHistogramName, 0);
+ EXPECT_EQ(0u, net_log_.GetSize());
+}
+
// Test that an SCT is classified as pending for a newer STH if the
// SingleTreeTracker has not seen any STHs so far.
TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
base::HistogramTester histograms;
// First make sure the SCT has not been observed at all.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
// Since no STH was provided to the tree_tracker_ the status should be that
// the SCT is pending a newer STH.
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Expect logging of a value indicating a valid STH is required.
histograms.ExpectUniqueSample(kCanCheckForInclusionHistogramName, 0, 1);
@@ -425,7 +497,7 @@ TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTNoSTH) {
// SingleTreeTracker has a fresh-enough STH to check inclusion against.
TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
base::HistogramTester histograms;
@@ -436,17 +508,17 @@ TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) {
// Make sure the SCT status is the same as if there's no STH for
// this log.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
// The status for this SCT should be 'pending inclusion check' since the STH
// provided at the beginning of the test is newer than the SCT.
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Exactly one value should be logged, indicating the SCT can be checked for
// inclusion, as |tree_tracker_| did have a valid STH when it was notified
@@ -463,16 +535,16 @@ TEST_F(SingleTreeTrackerTest, CorrectlyClassifiesUnobservedSCTWithRecentSTH) {
// from pending newer STH to pending inclusion check.
TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
base::HistogramTester histograms;
// Report an observed SCT and make sure it's in the pending newer STH
// state.
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
histograms.ExpectTotalCount(kCanCheckForInclusionHistogramName, 1);
// Provide with a fresh STH
@@ -481,9 +553,9 @@ TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) {
tree_tracker_->NewSTHObserved(sth);
// Test that its status has changed.
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Check that no additional UMA was logged for this case as the histogram is
// only supposed to measure the state of newly-observed SCTs, not pending
// ones.
@@ -496,14 +568,14 @@ TEST_F(SingleTreeTrackerTest, CorrectlyUpdatesSCTStatusOnNewSTH) {
// inclusion against.
TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
// Notify of an SCT and make sure it's in the 'pending newer STH' state.
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Provide an old STH for the same log.
SignedTreeHead sth;
@@ -511,9 +583,9 @@ TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) {
tree_tracker_->NewSTHObserved(sth);
// Make sure the SCT's state hasn't changed.
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
EXPECT_EQ(0u, net_log_.GetSize());
}
@@ -522,7 +594,7 @@ TEST_F(SingleTreeTrackerTest, DoesNotUpdatesSCTStatusOnOldSTH) {
// STH.
TEST_F(SingleTreeTrackerTest, LogsUMAForNewSCTAndOldSTH) {
CreateTreeTrackerWithDefaultDnsExpectation();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
base::HistogramTester histograms;
@@ -551,13 +623,13 @@ TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterLeafIndexFetchFailure) {
net::Error::ERR_FAILED));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Provide with a fresh STH
SignedTreeHead sth;
@@ -565,9 +637,9 @@ TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterLeafIndexFetchFailure) {
tree_tracker_->NewSTHObserved(sth);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// There should have been one NetLog event, logged with failure.
EXPECT_TRUE(MatchAuditingResultInNetLog(
net_log_, LeafHash(chain_.get(), cert_sct_.get()), false));
@@ -589,13 +661,13 @@ TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterInclusionCheckFailure) {
net::Error::ERR_FAILED));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Provide with a fresh STH
SignedTreeHead sth;
@@ -603,9 +675,9 @@ TEST_F(SingleTreeTrackerTest, TestEntryNotPendingAfterInclusionCheckFailure) {
tree_tracker_->NewSTHObserved(sth);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// There should have been one NetLog event, logged with failure.
EXPECT_TRUE(MatchAuditingResultInNetLog(
net_log_, LeafHash(chain_.get(), cert_sct_.get()), false));
@@ -631,13 +703,13 @@ TEST_F(SingleTreeTrackerTest, TestEntryIncludedAfterInclusionCheckSuccess) {
audit_proof.begin() + 1));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Provide with a fresh STH, which is for a tree of size 2.
SignedTreeHead sth;
@@ -647,9 +719,9 @@ TEST_F(SingleTreeTrackerTest, TestEntryIncludedAfterInclusionCheckSuccess) {
tree_tracker_->NewSTHObserved(sth);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(
- SingleTreeTracker::SCT_INCLUDED_IN_LOG,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_INCLUDED_IN_LOG,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// There should have been one NetLog event, with success logged.
EXPECT_TRUE(MatchAuditingResultInNetLog(
net_log_, LeafHash(chain_.get(), cert_sct_.get()), true));
@@ -660,13 +732,13 @@ TEST_F(SingleTreeTrackerTest, TestEntryIncludedAfterInclusionCheckSuccess) {
TEST_F(SingleTreeTrackerTest,
TestInclusionCheckCancelledIfUnderMemoryPressure) {
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), cert_sct_.get());
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Provide with a fresh STH, which is for a tree of size 2.
SignedTreeHead sth;
@@ -689,9 +761,9 @@ TEST_F(SingleTreeTrackerTest,
base::RunLoop().RunUntilIdle();
// Expect the SCT to have been discarded.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
}
// Test that pending entries transition states correctly according to the
@@ -751,7 +823,7 @@ TEST_F(SingleTreeTrackerTest, TestMultipleEntriesTransitionStateCorrectly) {
ASSERT_TRUE(
ExpectLeafIndexRequestAndThrottle(chain_, newer_than_old_sth_sct));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
// Add SCTs in mixed order.
@@ -769,9 +841,9 @@ TEST_F(SingleTreeTrackerTest, TestMultipleEntriesTransitionStateCorrectly) {
for (const auto& sct :
{oldest_sct, not_auditable_by_old_sth_sct, newer_than_old_sth_sct,
not_auditable_by_new_sth_sct, newer_than_new_sth_sct}) {
- ASSERT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()))
+ ASSERT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()))
<< "SCT age: " << sct->timestamp;
}
@@ -779,15 +851,15 @@ TEST_F(SingleTreeTrackerTest, TestMultipleEntriesTransitionStateCorrectly) {
tree_tracker_->NewSTHObserved(old_sth);
// Ensure all but the oldest are in the PENDING_NEWER_STH state.
ASSERT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(),
- oldest_sct.get()));
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), oldest_sct.get()));
for (const auto& sct :
{not_auditable_by_old_sth_sct, newer_than_old_sth_sct,
not_auditable_by_new_sth_sct, newer_than_new_sth_sct}) {
- ASSERT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()))
+ ASSERT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()))
<< "SCT age: " << sct->timestamp;
}
@@ -797,17 +869,17 @@ TEST_F(SingleTreeTrackerTest, TestMultipleEntriesTransitionStateCorrectly) {
for (const auto& sct :
{not_auditable_by_old_sth_sct, newer_than_old_sth_sct}) {
- ASSERT_EQ(
- SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()))
+ ASSERT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()))
<< "SCT age: " << sct->timestamp;
}
for (const auto& sct :
{not_auditable_by_new_sth_sct, newer_than_new_sth_sct}) {
- ASSERT_EQ(
- SingleTreeTracker::SCT_PENDING_NEWER_STH,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()))
+ ASSERT_EQ(SingleTreeTracker::SCT_PENDING_NEWER_STH,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()))
<< "SCT age: " << sct->timestamp;
}
}
@@ -842,7 +914,7 @@ TEST_F(SingleTreeTrackerTest, TestThrottledEntryGetsHandledAfterUnthrottling) {
audit_proof.begin() + 1));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
SignedTreeHead sth;
@@ -855,27 +927,27 @@ TEST_F(SingleTreeTrackerTest, TestThrottledEntryGetsHandledAfterUnthrottling) {
// Both entries should be in the pending state, the first because the
// LogDnsClient did not invoke the callback yet, the second one because
// the LogDnsClient is "busy" with the first entry and so would throttle.
- ASSERT_EQ(
- SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
ASSERT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(),
- second_sct.get()));
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
+ ASSERT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), second_sct.get()));
// Process pending DNS queries so later assertions are on handling
// of the entries based on replies received.
base::RunLoop().RunUntilIdle();
// Check that the first sct is included in the log.
- ASSERT_EQ(
- SingleTreeTracker::SCT_INCLUDED_IN_LOG,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ ASSERT_EQ(SingleTreeTracker::SCT_INCLUDED_IN_LOG,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Check that the second SCT got an invalid proof and is not included, rather
// than being in the pending state.
ASSERT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(),
- second_sct.get()));
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), second_sct.get()));
}
// Test that proof fetching failure due to DNS config errors is handled
@@ -895,7 +967,7 @@ TEST_F(SingleTreeTrackerTest,
net_change_notifier_ =
base::WrapUnique(net::NetworkChangeNotifier::CreateMock());
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
tree_tracker_->NewSTHObserved(sth);
@@ -904,9 +976,9 @@ TEST_F(SingleTreeTrackerTest,
// Make sure the SCT status indicates the entry has been removed from
// the SingleTreeTracker's internal queue as the DNS lookup failed
// synchronously.
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), cert_sct_.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(
+ chain_.get(), cert_sct_.get()));
// Exactly one value should be logged, indicating the SCT can be checked for
// inclusion, as |tree_tracker_| did have a valid STH when it was notified
@@ -946,7 +1018,7 @@ TEST_F(SingleTreeTrackerTest, DiscardsPendingEntriesAfterNetworkChange) {
audit_proof.begin() + 1));
CreateTreeTracker();
- AddCacheEntry(host_resolver_.GetHostCache(), kHostname,
+ AddCacheEntry(host_resolver_.GetHostCache(), kHostname, false /* secure */,
net::HostCache::Entry::SOURCE_DNS, kZeroTTL);
// Provide an STH to the tree_tracker_.
@@ -958,9 +1030,9 @@ TEST_F(SingleTreeTrackerTest, DiscardsPendingEntriesAfterNetworkChange) {
tree_tracker_->OnSCTVerified(kHostname, chain_.get(), second_sct.get());
for (auto sct : {cert_sct_, second_sct}) {
- EXPECT_EQ(
- SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_PENDING_INCLUSION_CHECK,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()));
}
net_change_notifier_->NotifyObserversOfNetworkChangeForTests(
@@ -968,9 +1040,9 @@ TEST_F(SingleTreeTrackerTest, DiscardsPendingEntriesAfterNetworkChange) {
base::RunLoop().RunUntilIdle();
for (auto sct : {cert_sct_, second_sct}) {
- EXPECT_EQ(
- SingleTreeTracker::SCT_NOT_OBSERVED,
- tree_tracker_->GetLogEntryInclusionStatus(chain_.get(), sct.get()));
+ EXPECT_EQ(SingleTreeTracker::SCT_NOT_OBSERVED,
+ tree_tracker_->GetLogEntryInclusionStatusForTesting(chain_.get(),
+ sct.get()));
}
}
diff --git a/chromium/components/certificate_transparency/tree_state_tracker.cc b/chromium/components/certificate_transparency/tree_state_tracker.cc
index 288f9451b24..3b87858b81d 100644
--- a/chromium/components/certificate_transparency/tree_state_tracker.cc
+++ b/chromium/components/certificate_transparency/tree_state_tracker.cc
@@ -33,11 +33,12 @@ namespace certificate_transparency {
TreeStateTracker::TreeStateTracker(
std::vector<scoped_refptr<const CTLogVerifier>> ct_logs,
net::HostResolver* host_resolver,
+ net::URLRequestContext* url_request_context,
net::NetLog* net_log) {
std::unique_ptr<net::DnsClient> dns_client =
net::DnsClient::CreateClient(net_log);
dns_client_ = std::make_unique<LogDnsClient>(
- std::move(dns_client),
+ std::move(dns_client), url_request_context,
net::NetLogWithSource::Make(net_log,
net::NetLogSourceType::CT_TREE_STATE_TRACKER),
kMaxConcurrentDnsQueries);
diff --git a/chromium/components/certificate_transparency/tree_state_tracker.h b/chromium/components/certificate_transparency/tree_state_tracker.h
index 90dc7953c5f..97a22ad8f12 100644
--- a/chromium/components/certificate_transparency/tree_state_tracker.h
+++ b/chromium/components/certificate_transparency/tree_state_tracker.h
@@ -13,6 +13,7 @@
#include "base/memory/ref_counted.h"
#include "components/certificate_transparency/sth_observer.h"
#include "net/cert/ct_verifier.h"
+#include "net/url_request/url_request_context.h"
namespace net {
class NetLog;
@@ -46,6 +47,7 @@ class TreeStateTracker : public net::CTVerifier::Observer, public STHObserver {
// Observed STHs from logs not in this list will be simply ignored.
TreeStateTracker(std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs,
net::HostResolver* host_resolver,
+ net::URLRequestContext* url_request_context,
net::NetLog* net_log);
~TreeStateTracker() override;
diff --git a/chromium/components/certificate_transparency/tree_state_tracker_unittest.cc b/chromium/components/certificate_transparency/tree_state_tracker_unittest.cc
index 0be01503631..4dac773bad6 100644
--- a/chromium/components/certificate_transparency/tree_state_tracker_unittest.cc
+++ b/chromium/components/certificate_transparency/tree_state_tracker_unittest.cc
@@ -24,6 +24,7 @@
#include "net/log/net_log.h"
#include "net/log/test_net_log.h"
#include "net/test/ct_test_util.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::ct::SignedCertificateTimestamp;
@@ -77,8 +78,8 @@ TEST_F(TreeStateTrackerTest, TestDelegatesCorrectly) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(kCTLogAuditing);
- tree_tracker_ =
- std::make_unique<TreeStateTracker>(verifiers, &host_resolver_, &net_log_);
+ tree_tracker_ = std::make_unique<TreeStateTracker>(
+ verifiers, &host_resolver_, new net::TestURLRequestContext(), &net_log_);
// Add a cache entry for kHostname that indicates it was looked up over DNS.
// SingleTreeTracker requires this before it will request an inclusion proof,
diff --git a/chromium/components/chrome_cleaner/public/constants/result_codes.h b/chromium/components/chrome_cleaner/public/constants/result_codes.h
index 0a48fff59f0..0068f91cfd0 100644
--- a/chromium/components/chrome_cleaner/public/constants/result_codes.h
+++ b/chromium/components/chrome_cleaner/public/constants/result_codes.h
@@ -227,6 +227,20 @@ enum ResultCodeValues : ResultCode {
// result, we don't allow it.
RESULT_CODE_WRONG_ARCHITECTURE = 56,
+ // The process failed to complete in a reasonable amount of time and our
+ // watchdog terminated the process. At that time the engine was scanning the
+ // registry.
+ RESULT_CODE_WATCHDOG_TIMEOUT_WHILE_SCANNING_REGISTRY = 57,
+
+ // The process failed to complete in a reasonable amount of time and our
+ // watchdog terminated the process. At that time the engine was scanning the
+ // file system.
+ RESULT_CODE_WATCHDOG_TIMEOUT_WHILE_SCANNING_FILES = 58,
+
+ // The target process for the test engine sandbox disconnected from the IPC
+ // while the pipe was still needed by the broker process.
+ RESULT_CODE_TEST_ENGINE_SANDBOX_DISCONNECTED_TOO_SOON = 59,
+
// WHEN YOU ADD NEW EXIT CODES, DON'T FORGET TO UPDATE THE MONITORING RULES.
// See http://go/chrome-cleaner-exit-codes. (Google internal only - external
// contributors please ask one of the OWNERS to do the update.)
diff --git a/chromium/components/cloud_devices/common/cloud_device_description.cc b/chromium/components/cloud_devices/common/cloud_device_description.cc
index 1bb2e463c51..513a24f97f8 100644
--- a/chromium/components/cloud_devices/common/cloud_device_description.cc
+++ b/chromium/components/cloud_devices/common/cloud_device_description.cc
@@ -15,55 +15,57 @@
namespace cloud_devices {
CloudDeviceDescription::CloudDeviceDescription()
- : root_(std::make_unique<base::DictionaryValue>()) {
- root_->SetString(json::kVersion, json::kVersion10);
+ : root_(base::Value(base::Value::Type::DICTIONARY)) {
+ root_.SetKey(json::kVersion, base::Value(json::kVersion10));
}
CloudDeviceDescription::~CloudDeviceDescription() = default;
bool CloudDeviceDescription::InitFromString(const std::string& json) {
- auto parsed = base::DictionaryValue::From(base::JSONReader::Read(json));
- if (!parsed)
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(json);
+ if (!value)
return false;
- root_ = std::move(parsed);
- const base::Value* version = root_->FindKey(json::kVersion);
+ return InitFromValue(base::Value::FromUniquePtrValue(std::move(value)));
+}
+
+bool CloudDeviceDescription::InitFromValue(base::Value ticket) {
+ if (!ticket.is_dict())
+ return false;
+ root_ = std::move(ticket);
+ return IsValidTicket(root_);
+}
+
+// static
+bool CloudDeviceDescription::IsValidTicket(const base::Value& ticket) {
+ if (!ticket.is_dict())
+ return false;
+
+ const base::Value* version = ticket.FindKey(json::kVersion);
return version && version->GetString() == json::kVersion10;
}
std::string CloudDeviceDescription::ToString() const {
std::string json;
base::JSONWriter::WriteWithOptions(
- *root_, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
+ root_, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
return json;
}
base::Value CloudDeviceDescription::ToValue() && {
- return base::Value::FromUniquePtrValue(std::move(root_));
-}
-
-const base::DictionaryValue* CloudDeviceDescription::GetItem(
- const std::string& path) const {
- const base::DictionaryValue* value = nullptr;
- root_->GetDictionary(path, &value);
- return value;
-}
-
-base::DictionaryValue* CloudDeviceDescription::CreateItem(
- const std::string& path) {
- return root_->SetDictionary(path, std::make_unique<base::DictionaryValue>());
+ return std::move(root_);
}
-const base::ListValue* CloudDeviceDescription::GetListItem(
- const std::string& path) const {
- const base::ListValue* value = nullptr;
- root_->GetList(path, &value);
- return value;
+const base::Value* CloudDeviceDescription::GetItem(
+ const std::vector<base::StringPiece>& path,
+ base::Value::Type type) const {
+ return root_.FindPathOfType(path, type);
}
-base::ListValue* CloudDeviceDescription::CreateListItem(
- const std::string& path) {
- return root_->SetList(path, std::make_unique<base::ListValue>());
+base::Value* CloudDeviceDescription::CreateItem(
+ const std::vector<base::StringPiece>& path,
+ base::Value::Type type) {
+ return root_.SetPath(path, base::Value(type));
}
} // namespace cloud_devices
diff --git a/chromium/components/cloud_devices/common/cloud_device_description.h b/chromium/components/cloud_devices/common/cloud_device_description.h
index c2867312370..c8c87a67d83 100644
--- a/chromium/components/cloud_devices/common/cloud_device_description.h
+++ b/chromium/components/cloud_devices/common/cloud_device_description.h
@@ -7,8 +7,10 @@
#include <memory>
#include <string>
+#include <vector>
#include "base/macros.h"
+#include "base/strings/string_piece_forward.h"
#include "base/values.h"
namespace cloud_devices {
@@ -22,29 +24,26 @@ class CloudDeviceDescription {
~CloudDeviceDescription();
bool InitFromString(const std::string& json);
+ bool InitFromValue(base::Value value);
+
+ static bool IsValidTicket(const base::Value& value);
std::string ToString() const;
base::Value ToValue() &&;
- // Returns dictionary with capability/option.
- // Returns NULL if missing.
- const base::DictionaryValue* GetItem(const std::string& path) const;
-
- // Create dictionary for capability/option.
- // Never returns NULL.
- base::DictionaryValue* CreateItem(const std::string& path);
-
- // Returns list with capability/option.
- // Returns NULL if missing.
- const base::ListValue* GetListItem(const std::string& path) const;
+ // Returns item of given type with capability/option.
+ // Returns nullptr if missing.
+ const base::Value* GetItem(const std::vector<base::StringPiece>& path,
+ base::Value::Type type) const;
- // Create list for capability/option.
- // Never returns NULL.
- base::ListValue* CreateListItem(const std::string& path);
+ // Creates item with given type for capability/option.
+ // Returns nullptr if an intermediate Value in the path is not a dictionary.
+ base::Value* CreateItem(const std::vector<base::StringPiece>& path,
+ base::Value::Type type);
private:
- std::unique_ptr<base::DictionaryValue> root_;
+ base::Value root_;
DISALLOW_COPY_AND_ASSIGN(CloudDeviceDescription);
};
diff --git a/chromium/components/cloud_devices/common/description_items.h b/chromium/components/cloud_devices/common/description_items.h
index 8ceff58275d..5e2348e124c 100644
--- a/chromium/components/cloud_devices/common/description_items.h
+++ b/chromium/components/cloud_devices/common/description_items.h
@@ -19,10 +19,6 @@
#include "base/stl_util.h"
#include "components/cloud_devices/common/cloud_device_description.h"
-namespace base {
-class DictionaryValue;
-}
-
namespace cloud_devices {
// All traits below specify how to serialize and validate capabilities and
@@ -35,10 +31,10 @@ namespace cloud_devices {
// static std::string GetItemPath();
//
// // Loads ticket item. Returns false if failed.
-// static bool Load(const base::DictionaryValue& dict, ContentType* option);
+// static bool Load(const base::Value& dict, ContentType* option);
//
// // Saves ticket item.
-// static void Save(ContentType option, base::DictionaryValue* dict);
+// static void Save(ContentType option, base::Value* dict);
// Represents a CDD capability that is stored as a JSON list
// Ex: "<CAPABILITY_NAME>": [ {<VALUE>}, {<VALUE>}, {<VALUE>} ]
@@ -67,7 +63,7 @@ class ListCapability {
return base::ContainsValue(options_, option);
}
- void AddOption(const Option& option) { options_.push_back(option); }
+ void AddOption(Option&& option) { options_.emplace_back(std::move(option)); }
private:
typedef std::vector<Option> OptionVector;
@@ -85,11 +81,19 @@ template <class Option, class Traits>
class SelectionCapability {
public:
SelectionCapability();
+ SelectionCapability(SelectionCapability&& other);
~SelectionCapability();
+ SelectionCapability& operator=(SelectionCapability&& other);
+
+ bool operator==(const SelectionCapability& other) const;
+
bool LoadFrom(const CloudDeviceDescription& description);
void SaveTo(CloudDeviceDescription* description) const;
+ bool LoadFrom(const base::Value& dict);
+ void SaveTo(base::Value* dict) const;
+
void Reset() {
options_.clear();
default_idx_ = -1;
@@ -162,8 +166,8 @@ class BooleanCapability {
template <class Traits>
class EmptyCapability {
public:
- EmptyCapability() {};
- ~EmptyCapability() {};
+ EmptyCapability() {}
+ ~EmptyCapability() {}
bool LoadFrom(const CloudDeviceDescription& description);
void SaveTo(CloudDeviceDescription* description) const;
diff --git a/chromium/components/cloud_devices/common/description_items_inl.h b/chromium/components/cloud_devices/common/description_items_inl.h
index ad82045ad26..b63800a071d 100644
--- a/chromium/components/cloud_devices/common/description_items_inl.h
+++ b/chromium/components/cloud_devices/common/description_items_inl.h
@@ -45,18 +45,16 @@ template <class Option, class Traits>
bool ListCapability<Option, Traits>::LoadFrom(
const CloudDeviceDescription& description) {
Reset();
- const base::ListValue* options =
- description.GetListItem(Traits::GetCapabilityPath());
- if (!options)
+ const base::Value* options_value =
+ description.GetItem(Traits::GetCapabilityPath(), base::Value::Type::LIST);
+ if (!options_value)
return false;
- for (size_t i = 0; i < options->GetSize(); ++i) {
- const base::DictionaryValue* option_value = NULL;
- if (!options->GetDictionary(i, &option_value))
- return false; // Every entry must be a dictionary.
+ const base::Value::ListStorage& options = options_value->GetList();
+ for (const base::Value& option_value : options) {
Option option;
- if (!Traits::Load(*option_value, &option))
+ if (!option_value.is_dict() || !Traits::Load(option_value, &option))
return false;
- AddOption(option);
+ AddOption(std::move(option));
}
return IsValid();
}
@@ -65,13 +63,12 @@ template <class Option, class Traits>
void ListCapability<Option, Traits>::SaveTo(
CloudDeviceDescription* description) const {
DCHECK(IsValid());
- base::ListValue* options_list =
- description->CreateListItem(Traits::GetCapabilityPath());
- for (size_t i = 0; i < options_.size(); ++i) {
- std::unique_ptr<base::DictionaryValue> option_value(
- new base::DictionaryValue);
- Traits::Save(options_[i], option_value.get());
- options_list->Append(std::move(option_value));
+ base::Value* options_list = description->CreateItem(
+ Traits::GetCapabilityPath(), base::Value::Type::LIST);
+ for (const Option& option : options_) {
+ base::Value option_value(base::Value::Type::DICTIONARY);
+ Traits::Save(option, &option_value);
+ options_list->GetList().emplace_back(std::move(option_value));
}
}
@@ -81,10 +78,24 @@ SelectionCapability<Option, Traits>::SelectionCapability() {
}
template <class Option, class Traits>
+SelectionCapability<Option, Traits>::SelectionCapability(
+ SelectionCapability&& other) = default;
+
+template <class Option, class Traits>
SelectionCapability<Option, Traits>::~SelectionCapability() {
}
template <class Option, class Traits>
+SelectionCapability<Option, Traits>& SelectionCapability<Option, Traits>::
+operator=(SelectionCapability&& other) = default;
+
+template <class Option, class Traits>
+bool SelectionCapability<Option, Traits>::operator==(
+ const SelectionCapability<Option, Traits>& other) const {
+ return options_ == other.options_ && default_idx_ == other.default_idx_;
+}
+
+template <class Option, class Traits>
bool SelectionCapability<Option, Traits>::IsValid() const {
if (empty())
return false; // This type of capabilities can't be empty
@@ -98,23 +109,37 @@ bool SelectionCapability<Option, Traits>::IsValid() const {
template <class Option, class Traits>
bool SelectionCapability<Option, Traits>::LoadFrom(
const CloudDeviceDescription& description) {
- Reset();
- const base::DictionaryValue* item =
- description.GetItem(Traits::GetCapabilityPath());
- if (!item)
+ const base::Value* item = description.GetItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY);
+ if (!item) {
+ Reset();
return false;
- const base::ListValue* options = NULL;
- if (!item->GetList(json::kKeyOption, &options))
+ }
+ return LoadFrom(*item);
+}
+
+template <class Option, class Traits>
+void SelectionCapability<Option, Traits>::SaveTo(
+ CloudDeviceDescription* description) const {
+ DCHECK(IsValid());
+ SaveTo(description->CreateItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY));
+}
+
+template <class Option, class Traits>
+bool SelectionCapability<Option, Traits>::LoadFrom(const base::Value& dict) {
+ Reset();
+ const base::Value* options_value =
+ dict.FindKeyOfType(json::kKeyOption, base::Value::Type::LIST);
+ if (!options_value)
return false;
- for (size_t i = 0; i < options->GetSize(); ++i) {
- const base::DictionaryValue* option_value = NULL;
- if (!options->GetDictionary(i, &option_value))
- return false; // Every entry must be a dictionary.
+ const base::Value::ListStorage& options = options_value->GetList();
+ for (const base::Value& option_value : options) {
Option option;
- if (!Traits::Load(*option_value, &option))
+ if (!option_value.is_dict() || !Traits::Load(option_value, &option))
return false;
- bool is_default = false;
- option_value->GetBoolean(json::kKeyIsDefault, &is_default);
+ bool is_default =
+ option_value.FindBoolKey(json::kKeyIsDefault).value_or(false);
if (is_default && default_idx_ >= 0) {
return false; // Multiple defaults.
}
@@ -124,19 +149,17 @@ bool SelectionCapability<Option, Traits>::LoadFrom(
}
template <class Option, class Traits>
-void SelectionCapability<Option, Traits>::SaveTo(
- CloudDeviceDescription* description) const {
+void SelectionCapability<Option, Traits>::SaveTo(base::Value* dict) const {
DCHECK(IsValid());
- auto options_list = std::make_unique<base::ListValue>();
+ base::Value options_list(base::Value::Type::LIST);
for (size_t i = 0; i < options_.size(); ++i) {
- auto option_value = std::make_unique<base::DictionaryValue>();
+ base::Value option_value(base::Value::Type::DICTIONARY);
if (base::checked_cast<int>(i) == default_idx_)
- option_value->SetBoolean(json::kKeyIsDefault, true);
- Traits::Save(options_[i], option_value.get());
- options_list->Append(std::move(option_value));
+ option_value.SetKey(json::kKeyIsDefault, base::Value(true));
+ Traits::Save(options_[i], &option_value);
+ options_list.GetList().emplace_back(std::move(option_value));
}
- description->CreateItem(Traits::GetCapabilityPath())
- ->Set(json::kKeyOption, std::move(options_list));
+ dict->SetKey(json::kKeyOption, std::move(options_list));
}
template <class Traits>
@@ -152,34 +175,36 @@ template <class Traits>
bool BooleanCapability<Traits>::LoadFrom(
const CloudDeviceDescription& description) {
Reset();
- const base::DictionaryValue* dict =
- description.GetItem(Traits::GetCapabilityPath());
+ const base::Value* dict = description.GetItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY);
if (!dict)
return false;
- default_value_ = Traits::kDefault;
- dict->GetBoolean(json::kKeyDefault, &default_value_);
+ default_value_ = dict->FindBoolKey(json::kKeyDefault)
+ .value_or(static_cast<bool>(Traits::kDefault));
return true;
}
template <class Traits>
void BooleanCapability<Traits>::SaveTo(
CloudDeviceDescription* description) const {
- base::DictionaryValue* dict =
- description->CreateItem(Traits::GetCapabilityPath());
+ base::Value* dict = description->CreateItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY);
if (default_value_ != Traits::kDefault)
- dict->SetBoolean(json::kKeyDefault, default_value_);
+ dict->SetKey(json::kKeyDefault, base::Value(default_value_));
}
template <class Traits>
bool EmptyCapability<Traits>::LoadFrom(
const CloudDeviceDescription& description) {
- return description.GetItem(Traits::GetCapabilityPath()) != NULL;
+ return description.GetItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY) != nullptr;
}
template <class Traits>
void EmptyCapability<Traits>::SaveTo(
CloudDeviceDescription* description) const {
- description->CreateItem(Traits::GetCapabilityPath());
+ description->CreateItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY);
}
template <class Option, class Traits>
@@ -200,8 +225,8 @@ template <class Option, class Traits>
bool ValueCapability<Option, Traits>::LoadFrom(
const CloudDeviceDescription& description) {
Reset();
- const base::DictionaryValue* option_value =
- description.GetItem(Traits::GetCapabilityPath());
+ const base::Value* option_value = description.GetItem(
+ Traits::GetCapabilityPath(), base::Value::Type::DICTIONARY);
if (!option_value)
return false;
Option option;
@@ -215,7 +240,8 @@ template <class Option, class Traits>
void ValueCapability<Option, Traits>::SaveTo(
CloudDeviceDescription* description) const {
DCHECK(IsValid());
- Traits::Save(value(), description->CreateItem(Traits::GetCapabilityPath()));
+ Traits::Save(value(), description->CreateItem(Traits::GetCapabilityPath(),
+ base::Value::Type::DICTIONARY));
}
template <class Option, class Traits>
@@ -236,8 +262,8 @@ template <class Option, class Traits>
bool TicketItem<Option, Traits>::LoadFrom(
const CloudDeviceDescription& description) {
Reset();
- const base::DictionaryValue* option_value =
- description.GetItem(Traits::GetTicketItemPath());
+ const base::Value* option_value = description.GetItem(
+ Traits::GetTicketItemPath(), base::Value::Type::DICTIONARY);
if (!option_value)
return false;
Option option;
@@ -251,7 +277,8 @@ template <class Option, class Traits>
void TicketItem<Option, Traits>::SaveTo(
CloudDeviceDescription* description) const {
DCHECK(IsValid());
- Traits::Save(value(), description->CreateItem(Traits::GetTicketItemPath()));
+ Traits::Save(value(), description->CreateItem(Traits::GetTicketItemPath(),
+ base::Value::Type::DICTIONARY));
}
} // namespace cloud_devices
diff --git a/chromium/components/cloud_devices/common/printer_description.cc b/chromium/components/cloud_devices/common/printer_description.cc
index 733c1dc1ea6..f96b8f9eef4 100644
--- a/chromium/components/cloud_devices/common/printer_description.cc
+++ b/chromium/components/cloud_devices/common/printer_description.cc
@@ -9,10 +9,13 @@
#include <algorithm>
#include <memory>
#include <utility>
+#include <vector>
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/cloud_devices/common/cloud_device_description_consts.h"
@@ -29,10 +32,14 @@ const int32_t kMaxPageNumber = 1000000;
const char kSectionPrint[] = "print";
const char kSectionPrinter[] = "printer";
-const char kCustomName[] = "custom_display_name";
+const char kKeyCustomDisplayName[] = "custom_display_name";
const char kKeyContentType[] = "content_type";
+const char kKeyDisplayName[] = "display_name";
+const char kKeyId[] = "id";
const char kKeyName[] = "name";
const char kKeyType[] = "type";
+const char kKeyValue[] = "value";
+const char kKeyValueType[] = "value_type";
const char kKeyVendorId[] = "vendor_id";
// extern is required to be used in templates.
@@ -49,6 +56,13 @@ extern const char kOptionPageOrientation[] = "page_orientation";
extern const char kOptionPageRange[] = "page_range";
extern const char kOptionReverse[] = "reverse_order";
extern const char kOptionPwgRasterConfig[] = "pwg_raster_config";
+extern const char kOptionRangeCapability[] = "range_cap";
+extern const char kOptionSelectCapability[] = "select_cap";
+extern const char kOptionTypedValueCapability[] = "typed_value_cap";
+extern const char kOptionVendorCapability[] = "vendor_capability";
+#if defined(OS_CHROMEOS)
+extern const char kOptionPin[] = "pin";
+#endif // defined(OS_CHROMEOS)
const char kMarginBottom[] = "bottom_microns";
const char kMarginLeft[] = "left_microns";
@@ -71,6 +85,26 @@ const char kPwgRasterDocumentSheetBack[] = "document_sheet_back";
const char kPwgRasterReverseOrderStreaming[] = "reverse_order_streaming";
const char kPwgRasterRotateAllPages[] = "rotate_all_pages";
+const char kVendorCapabilityMinValue[] = "min";
+const char kVendorCapabilityMaxValue[] = "max";
+const char kVendorCapabilityDefaultValue[] = "default";
+
+#if defined(OS_CHROMEOS)
+const char kPinSupported[] = "supported";
+#endif // defined(OS_CHROMEOS)
+
+const char kTypeRangeVendorCapabilityFloat[] = "FLOAT";
+const char kTypeRangeVendorCapabilityInteger[] = "INTEGER";
+
+const char kTypeTypedValueVendorCapabilityBoolean[] = "BOOLEAN";
+const char kTypeTypedValueVendorCapabilityFloat[] = "FLOAT";
+const char kTypeTypedValueVendorCapabilityInteger[] = "INTEGER";
+const char kTypeTypedValueVendorCapabilityString[] = "STRING";
+
+const char kTypeVendorCapabilityRange[] = "RANGE";
+const char kTypeVendorCapabilitySelect[] = "SELECT";
+const char kTypeVendorCapabilityTypedValue[] = "TYPED_VALUE";
+
const char kTypeColorColor[] = "STANDARD_COLOR";
const char kTypeColorMonochrome[] = "STANDARD_MONOCHROME";
const char kTypeColorCustomColor[] = "CUSTOM_COLOR";
@@ -103,72 +137,107 @@ const char kTypeDocumentSheetBackRotated[] = "ROTATED";
const char kTypeDocumentSheetBackManualTumble[] = "MANUAL_TUMBLE";
const char kTypeDocumentSheetBackFlipped[] = "FLIPPED";
+const struct RangeVendorCapabilityTypeNames {
+ RangeVendorCapability::ValueType id;
+ const char* json_name;
+} kRangeVendorCapabilityTypeNames[] = {
+ {RangeVendorCapability::ValueType::FLOAT, kTypeRangeVendorCapabilityFloat},
+ {RangeVendorCapability::ValueType::INTEGER,
+ kTypeRangeVendorCapabilityInteger},
+};
+
+const struct TypedValueVendorCapabilityTypeNames {
+ TypedValueVendorCapability::ValueType id;
+ const char* json_name;
+} kTypedValueVendorCapabilityTypeNames[] = {
+ {TypedValueVendorCapability::ValueType::BOOLEAN,
+ kTypeTypedValueVendorCapabilityBoolean},
+ {TypedValueVendorCapability::ValueType::FLOAT,
+ kTypeTypedValueVendorCapabilityFloat},
+ {TypedValueVendorCapability::ValueType::INTEGER,
+ kTypeTypedValueVendorCapabilityInteger},
+ {TypedValueVendorCapability::ValueType::STRING,
+ kTypeTypedValueVendorCapabilityString},
+};
+
+const struct VendorCapabilityTypeNames {
+ VendorCapability::Type id;
+ const char* json_name;
+} kVendorCapabilityTypeNames[] = {
+ {VendorCapability::Type::RANGE, kTypeVendorCapabilityRange},
+ {VendorCapability::Type::SELECT, kTypeVendorCapabilitySelect},
+ {VendorCapability::Type::TYPED_VALUE, kTypeVendorCapabilityTypedValue},
+};
+
const struct ColorNames {
ColorType id;
const char* const json_name;
} kColorNames[] = {
- {STANDARD_COLOR, kTypeColorColor},
- {STANDARD_MONOCHROME, kTypeColorMonochrome},
- {CUSTOM_COLOR, kTypeColorCustomColor},
- {CUSTOM_MONOCHROME, kTypeColorCustomMonochrome},
- {AUTO_COLOR, kTypeColorAuto},
+ {ColorType::STANDARD_COLOR, kTypeColorColor},
+ {ColorType::STANDARD_MONOCHROME, kTypeColorMonochrome},
+ {ColorType::CUSTOM_COLOR, kTypeColorCustomColor},
+ {ColorType::CUSTOM_MONOCHROME, kTypeColorCustomMonochrome},
+ {ColorType::AUTO_COLOR, kTypeColorAuto},
};
const struct DuplexNames {
DuplexType id;
const char* const json_name;
} kDuplexNames[] = {
- {NO_DUPLEX, kTypeDuplexNoDuplex},
- {LONG_EDGE, kTypeDuplexLongEdge},
- {SHORT_EDGE, kTypeDuplexShortEdge},
+ {DuplexType::NO_DUPLEX, kTypeDuplexNoDuplex},
+ {DuplexType::LONG_EDGE, kTypeDuplexLongEdge},
+ {DuplexType::SHORT_EDGE, kTypeDuplexShortEdge},
};
const struct OrientationNames {
OrientationType id;
const char* const json_name;
} kOrientationNames[] = {
- {PORTRAIT, kTypeOrientationPortrait},
- {LANDSCAPE, kTypeOrientationLandscape},
- {AUTO_ORIENTATION, kTypeOrientationAuto},
+ {OrientationType::PORTRAIT, kTypeOrientationPortrait},
+ {OrientationType::LANDSCAPE, kTypeOrientationLandscape},
+ {OrientationType::AUTO_ORIENTATION, kTypeOrientationAuto},
};
const struct MarginsNames {
MarginsType id;
const char* const json_name;
} kMarginsNames[] = {
- {NO_MARGINS, kTypeMarginsBorderless},
- {STANDARD_MARGINS, kTypeMarginsStandard},
- {CUSTOM_MARGINS, kTypeMarginsCustom},
+ {MarginsType::NO_MARGINS, kTypeMarginsBorderless},
+ {MarginsType::STANDARD_MARGINS, kTypeMarginsStandard},
+ {MarginsType::CUSTOM_MARGINS, kTypeMarginsCustom},
};
const struct FitToPageNames {
FitToPageType id;
const char* const json_name;
} kFitToPageNames[] = {
- {NO_FITTING, kTypeFitToPageNoFitting},
- {FIT_TO_PAGE, kTypeFitToPageFitToPage},
- {GROW_TO_PAGE, kTypeFitToPageGrowToPage},
- {SHRINK_TO_PAGE, kTypeFitToPageShrinkToPage},
- {FILL_PAGE, kTypeFitToPageFillPage},
+ {FitToPageType::NO_FITTING, kTypeFitToPageNoFitting},
+ {FitToPageType::FIT_TO_PAGE, kTypeFitToPageFitToPage},
+ {FitToPageType::GROW_TO_PAGE, kTypeFitToPageGrowToPage},
+ {FitToPageType::SHRINK_TO_PAGE, kTypeFitToPageShrinkToPage},
+ {FitToPageType::FILL_PAGE, kTypeFitToPageFillPage},
};
const struct DocumentSheetBackNames {
DocumentSheetBack id;
const char* const json_name;
} kDocumentSheetBackNames[] = {
- {NORMAL, kTypeDocumentSheetBackNormal},
- {ROTATED, kTypeDocumentSheetBackRotated},
- {MANUAL_TUMBLE, kTypeDocumentSheetBackManualTumble},
- {FLIPPED, kTypeDocumentSheetBackFlipped}};
+ {DocumentSheetBack::NORMAL, kTypeDocumentSheetBackNormal},
+ {DocumentSheetBack::ROTATED, kTypeDocumentSheetBackRotated},
+ {DocumentSheetBack::MANUAL_TUMBLE, kTypeDocumentSheetBackManualTumble},
+ {DocumentSheetBack::FLIPPED, kTypeDocumentSheetBackFlipped}};
const int32_t kInchToUm = 25400;
const int32_t kMmToUm = 1000;
const int32_t kSizeTrasholdUm = 1000;
+// Json name of media type is constructed by removing "MediaType::" enum class
+// prefix from it.
#define MAP_CLOUD_PRINT_MEDIA_TYPE(type, width, height, unit_um) \
{ \
- type, #type, static_cast<int>(width* unit_um + 0.5), \
- static_cast<int>(height* unit_um + 0.5) \
+ type, &#type[strlen("MediaType::")], \
+ static_cast<int>(width * unit_um + 0.5), \
+ static_cast<int>(height * unit_um + 0.5) \
}
const struct MediaDefinition {
@@ -177,171 +246,189 @@ const struct MediaDefinition {
int width_um;
int height_um;
} kMediaDefinitions[] = {
- {CUSTOM_MEDIA, "CUSTOM", 0, 0},
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_INDEX_3X5, 3, 5, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_PERSONAL, 3.625f, 6.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_MONARCH, 3.875f, 7.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_NUMBER_9, 3.875f, 8.875f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_INDEX_4X6, 4, 6, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_NUMBER_10, 4.125f, 9.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_A2, 4.375f, 5.75f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_NUMBER_11, 4.5f, 10.375f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_NUMBER_12, 4.75f, 11, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_5X7, 5, 7, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_INDEX_5X8, 5, 8, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_NUMBER_14, 5, 11.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_INVOICE, 5.5f, 8.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_INDEX_4X6_EXT, 6, 8, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_6X9, 6, 9, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_C5, 6.5f, 9.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_7X9, 7, 9, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_EXECUTIVE, 7.25f, 10.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_GOVT_LETTER, 8, 10, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_GOVT_LEGAL, 8, 13, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_QUARTO, 8.5f, 10.83f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LETTER, 8.5f, 11, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_FANFOLD_EUR, 8.5f, 12, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LETTER_PLUS, 8.5f, 12.69f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_FOOLSCAP, 8.5f, 13, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LEGAL, 8.5f, 14, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_SUPER_A, 8.94f, 14, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_9X11, 9, 11, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ARCH_A, 9, 12, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LETTER_EXTRA, 9.5f, 12, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LEGAL_EXTRA, 9.5f, 15, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_10X11, 10, 11, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_10X13, 10, 13, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_10X14, 10, 14, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_10X15, 10, 15, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_11X12, 11, 12, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_EDP, 11, 14, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_FANFOLD_US, 11, 14.875f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_11X15, 11, 15, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_LEDGER, 11, 17, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_EUR_EDP, 12, 14, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ARCH_B, 12, 18, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_12X19, 12, 19, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_B_PLUS, 12, 19.17f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_SUPER_B, 13, 19, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_C, 17, 22, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ARCH_C, 18, 24, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_D, 22, 34, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ARCH_D, 24, 36, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ASME_F, 28, 40, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_WIDE_FORMAT, 30, 42, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_E, 34, 44, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_ARCH_E, 36, 48, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(NA_F, 44, 68, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ROC_16K, 7.75f, 10.75f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ROC_8K, 10.75f, 15.5f, kInchToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_32K, 97, 151, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_1, 102, 165, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_2, 102, 176, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_4, 110, 208, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_5, 110, 220, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_8, 120, 309, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_6, 120, 230, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_3, 125, 176, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_16K, 146, 215, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_7, 160, 230, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_JUURO_KU_KAI, 198, 275, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_PA_KAI, 267, 389, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_DAI_PA_KAI, 275, 395, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(PRC_10, 324, 458, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A10, 26, 37, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A9, 37, 52, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A8, 52, 74, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A7, 74, 105, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A6, 105, 148, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A5, 148, 210, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A5_EXTRA, 174, 235, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4, 210, 297, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4_TAB, 225, 297, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4_EXTRA, 235, 322, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3, 297, 420, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X3, 297, 630, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X4, 297, 841, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X5, 297, 1051, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X6, 297, 1261, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X7, 297, 1471, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X8, 297, 1682, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A4X9, 297, 1892, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3_EXTRA, 322, 445, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A2, 420, 594, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3X3, 420, 891, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3X4, 420, 1189, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3X5, 420, 1486, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3X6, 420, 1783, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A3X7, 420, 2080, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A1, 594, 841, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A2X3, 594, 1261, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A2X4, 594, 1682, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A2X5, 594, 2102, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A0, 841, 1189, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A1X3, 841, 1783, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A1X4, 841, 2378, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_2A0, 1189, 1682, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_A0X3, 1189, 2523, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B10, 31, 44, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B9, 44, 62, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B8, 62, 88, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B7, 88, 125, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B6, 125, 176, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B6C4, 125, 324, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B5, 176, 250, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B5_EXTRA, 201, 276, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B4, 250, 353, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B3, 353, 500, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B2, 500, 707, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B1, 707, 1000, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_B0, 1000, 1414, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C10, 28, 40, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C9, 40, 57, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C8, 57, 81, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C7, 81, 114, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C7C6, 81, 162, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C6, 114, 162, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C6C5, 114, 229, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C5, 162, 229, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C4, 229, 324, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C3, 324, 458, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C2, 458, 648, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C1, 648, 917, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_C0, 917, 1297, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_DL, 110, 220, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_RA2, 430, 610, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_SRA2, 450, 640, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_RA1, 610, 860, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_SRA1, 640, 900, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_RA0, 860, 1220, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(ISO_SRA0, 900, 1280, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B10, 32, 45, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B9, 45, 64, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B8, 64, 91, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B7, 91, 128, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B6, 128, 182, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B5, 182, 257, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B4, 257, 364, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B3, 364, 515, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B2, 515, 728, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B1, 728, 1030, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_B0, 1030, 1456, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JIS_EXEC, 216, 330, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_CHOU4, 90, 205, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_HAGAKI, 100, 148, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_YOU4, 105, 235, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_CHOU2, 111.1f, 146, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_CHOU3, 120, 235, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_OUFUKU, 148, 200, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_KAHU, 240, 322.1f, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(JPN_KAKU2, 240, 332, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_SMALL_PHOTO, 100, 150, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_ITALIAN, 110, 230, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_POSTFIX, 114, 229, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_LARGE_PHOTO, 200, 300, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_FOLIO, 210, 330, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_FOLIO_SP, 215, 315, kMmToUm),
- MAP_CLOUD_PRINT_MEDIA_TYPE(OM_INVITE, 220, 220, kMmToUm)};
+ {MediaType::CUSTOM_MEDIA, "CUSTOM", 0, 0},
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_INDEX_3X5, 3, 5, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_PERSONAL, 3.625f, 6.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_MONARCH, 3.875f, 7.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_NUMBER_9,
+ 3.875f,
+ 8.875f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_INDEX_4X6, 4, 6, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_NUMBER_10,
+ 4.125f,
+ 9.5f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_A2, 4.375f, 5.75f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_NUMBER_11,
+ 4.5f,
+ 10.375f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_NUMBER_12, 4.75f, 11, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_5X7, 5, 7, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_INDEX_5X8, 5, 8, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_NUMBER_14, 5, 11.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_INVOICE, 5.5f, 8.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_INDEX_4X6_EXT, 6, 8, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_6X9, 6, 9, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_C5, 6.5f, 9.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_7X9, 7, 9, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_EXECUTIVE,
+ 7.25f,
+ 10.5f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_GOVT_LETTER, 8, 10, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_GOVT_LEGAL, 8, 13, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_QUARTO, 8.5f, 10.83f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LETTER, 8.5f, 11, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_FANFOLD_EUR, 8.5f, 12, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LETTER_PLUS,
+ 8.5f,
+ 12.69f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_FOOLSCAP, 8.5f, 13, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LEGAL, 8.5f, 14, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_SUPER_A, 8.94f, 14, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_9X11, 9, 11, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ARCH_A, 9, 12, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LETTER_EXTRA, 9.5f, 12, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LEGAL_EXTRA, 9.5f, 15, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_10X11, 10, 11, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_10X13, 10, 13, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_10X14, 10, 14, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_10X15, 10, 15, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_11X12, 11, 12, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_EDP, 11, 14, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_FANFOLD_US,
+ 11,
+ 14.875f,
+ kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_11X15, 11, 15, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_LEDGER, 11, 17, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_EUR_EDP, 12, 14, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ARCH_B, 12, 18, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_12X19, 12, 19, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_B_PLUS, 12, 19.17f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_SUPER_B, 13, 19, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_C, 17, 22, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ARCH_C, 18, 24, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_D, 22, 34, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ARCH_D, 24, 36, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ASME_F, 28, 40, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_WIDE_FORMAT, 30, 42, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_E, 34, 44, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_ARCH_E, 36, 48, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::NA_F, 44, 68, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ROC_16K, 7.75f, 10.75f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ROC_8K, 10.75f, 15.5f, kInchToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_32K, 97, 151, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_1, 102, 165, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_2, 102, 176, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_4, 110, 208, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_5, 110, 220, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_8, 120, 309, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_6, 120, 230, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_3, 125, 176, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_16K, 146, 215, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_7, 160, 230, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_JUURO_KU_KAI, 198, 275, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_PA_KAI, 267, 389, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_DAI_PA_KAI, 275, 395, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::PRC_10, 324, 458, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A10, 26, 37, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A9, 37, 52, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A8, 52, 74, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A7, 74, 105, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A6, 105, 148, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A5, 148, 210, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A5_EXTRA, 174, 235, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4, 210, 297, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4_TAB, 225, 297, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4_EXTRA, 235, 322, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3, 297, 420, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X3, 297, 630, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X4, 297, 841, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X5, 297, 1051, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X6, 297, 1261, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X7, 297, 1471, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X8, 297, 1682, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A4X9, 297, 1892, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3_EXTRA, 322, 445, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A2, 420, 594, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3X3, 420, 891, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3X4, 420, 1189, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3X5, 420, 1486, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3X6, 420, 1783, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A3X7, 420, 2080, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A1, 594, 841, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A2X3, 594, 1261, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A2X4, 594, 1682, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A2X5, 594, 2102, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A0, 841, 1189, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A1X3, 841, 1783, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A1X4, 841, 2378, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_2A0, 1189, 1682, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_A0X3, 1189, 2523, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B10, 31, 44, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B9, 44, 62, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B8, 62, 88, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B7, 88, 125, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B6, 125, 176, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B6C4, 125, 324, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B5, 176, 250, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B5_EXTRA, 201, 276, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B4, 250, 353, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B3, 353, 500, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B2, 500, 707, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B1, 707, 1000, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_B0, 1000, 1414, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C10, 28, 40, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C9, 40, 57, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C8, 57, 81, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C7, 81, 114, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C7C6, 81, 162, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C6, 114, 162, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C6C5, 114, 229, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C5, 162, 229, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C4, 229, 324, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C3, 324, 458, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C2, 458, 648, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C1, 648, 917, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_C0, 917, 1297, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_DL, 110, 220, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_RA2, 430, 610, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_SRA2, 450, 640, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_RA1, 610, 860, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_SRA1, 640, 900, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_RA0, 860, 1220, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::ISO_SRA0, 900, 1280, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B10, 32, 45, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B9, 45, 64, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B8, 64, 91, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B7, 91, 128, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B6, 128, 182, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B5, 182, 257, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B4, 257, 364, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B3, 364, 515, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B2, 515, 728, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B1, 728, 1030, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_B0, 1030, 1456, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JIS_EXEC, 216, 330, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_CHOU4, 90, 205, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_HAGAKI, 100, 148, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_YOU4, 105, 235, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_CHOU2, 111.1f, 146, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_CHOU3, 120, 235, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_OUFUKU, 148, 200, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_KAHU, 240, 322.1f, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::JPN_KAKU2, 240, 332, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_SMALL_PHOTO, 100, 150, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_ITALIAN, 110, 230, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_POSTFIX, 114, 229, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_LARGE_PHOTO, 200, 300, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_FOLIO, 210, 330, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_FOLIO_SP, 215, 315, kMmToUm),
+ MAP_CLOUD_PRINT_MEDIA_TYPE(MediaType::OM_INVITE, 220, 220, kMmToUm)};
#undef MAP_CLOUD_PRINT_MEDIA_TYPE
const MediaDefinition& FindMediaByType(MediaType type) {
@@ -389,16 +476,341 @@ bool TypeFromString(const T& names, const std::string& type, IdType* id) {
} // namespace
PwgRasterConfig::PwgRasterConfig()
- : document_sheet_back(ROTATED),
+ : document_sheet_back(DocumentSheetBack::ROTATED),
reverse_order_streaming(false),
- rotate_all_pages(false) {
-}
+ rotate_all_pages(false) {}
PwgRasterConfig::~PwgRasterConfig() {}
-Color::Color() : type(AUTO_COLOR) {
+RangeVendorCapability::RangeVendorCapability() = default;
+
+RangeVendorCapability::RangeVendorCapability(ValueType value_type,
+ const std::string& min_value,
+ const std::string& max_value)
+ : RangeVendorCapability(value_type,
+ min_value,
+ max_value,
+ /*default_value=*/"") {}
+
+RangeVendorCapability::RangeVendorCapability(ValueType value_type,
+ const std::string& min_value,
+ const std::string& max_value,
+ const std::string& default_value)
+ : value_type_(value_type),
+ min_value_(min_value),
+ max_value_(max_value),
+ default_value_(default_value) {}
+
+RangeVendorCapability::RangeVendorCapability(RangeVendorCapability&& other) =
+ default;
+
+RangeVendorCapability::~RangeVendorCapability() = default;
+
+RangeVendorCapability& RangeVendorCapability::operator=(
+ RangeVendorCapability&& other) = default;
+
+bool RangeVendorCapability::operator==(
+ const RangeVendorCapability& other) const {
+ return value_type_ == other.value_type_ && min_value_ == other.min_value_ &&
+ max_value_ == other.max_value_ &&
+ default_value_ == other.default_value_;
+}
+
+bool RangeVendorCapability::IsValid() const {
+ if (min_value_.empty() || max_value_.empty())
+ return false;
+ switch (value_type_) {
+ case ValueType::FLOAT: {
+ double min_value;
+ double max_value;
+ if (!base::StringToDouble(min_value_, &min_value) ||
+ !base::StringToDouble(max_value_, &max_value) ||
+ min_value > max_value) {
+ return false;
+ }
+ if (!default_value_.empty()) {
+ double default_value;
+ if (!base::StringToDouble(default_value_, &default_value) ||
+ default_value < min_value || default_value > max_value) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case ValueType::INTEGER: {
+ int min_value;
+ int max_value;
+ if (!base::StringToInt(min_value_, &min_value) ||
+ !base::StringToInt(max_value_, &max_value) || min_value > max_value) {
+ return false;
+ }
+ if (!default_value_.empty()) {
+ int default_value;
+ if (!base::StringToInt(default_value_, &default_value) ||
+ default_value < min_value || default_value > max_value) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ NOTREACHED() << "Bad range capability value type";
+ return false;
+}
+
+bool RangeVendorCapability::LoadFrom(const base::Value& dict) {
+ const std::string* value_type_str = dict.FindStringKey(kKeyValueType);
+ if (!value_type_str || !TypeFromString(kRangeVendorCapabilityTypeNames,
+ *value_type_str, &value_type_)) {
+ return false;
+ }
+ const std::string* min_value_str =
+ dict.FindStringKey(kVendorCapabilityMinValue);
+ if (!min_value_str)
+ return false;
+ min_value_ = *min_value_str;
+ const std::string* max_value_str =
+ dict.FindStringKey(kVendorCapabilityMaxValue);
+ if (!max_value_str)
+ return false;
+ max_value_ = *max_value_str;
+ const std::string* default_value_str =
+ dict.FindStringKey(kVendorCapabilityDefaultValue);
+ if (default_value_str)
+ default_value_ = *default_value_str;
+ return IsValid();
+}
+
+void RangeVendorCapability::SaveTo(base::Value* dict) const {
+ DCHECK(IsValid());
+ dict->SetKey(
+ kKeyValueType,
+ base::Value(TypeToString(kRangeVendorCapabilityTypeNames, value_type_)));
+ dict->SetKey(kVendorCapabilityMinValue, base::Value(min_value_));
+ dict->SetKey(kVendorCapabilityMaxValue, base::Value(max_value_));
+ if (!default_value_.empty())
+ dict->SetKey(kVendorCapabilityDefaultValue, base::Value(default_value_));
+}
+
+SelectVendorCapabilityOption::SelectVendorCapabilityOption() = default;
+
+SelectVendorCapabilityOption::SelectVendorCapabilityOption(
+ const std::string& value,
+ const std::string& display_name)
+ : value(value), display_name(display_name) {}
+
+SelectVendorCapabilityOption::~SelectVendorCapabilityOption() = default;
+
+bool SelectVendorCapabilityOption::operator==(
+ const SelectVendorCapabilityOption& other) const {
+ return value == other.value && display_name == other.display_name;
+}
+
+bool SelectVendorCapabilityOption::IsValid() const {
+ return !value.empty() && !display_name.empty();
+}
+
+TypedValueVendorCapability::TypedValueVendorCapability() = default;
+
+TypedValueVendorCapability::TypedValueVendorCapability(ValueType value_type)
+ : TypedValueVendorCapability(value_type, /*default_value=*/"") {}
+
+TypedValueVendorCapability::TypedValueVendorCapability(
+ ValueType value_type,
+ const std::string& default_value)
+ : value_type_(value_type), default_value_(default_value) {}
+
+TypedValueVendorCapability::TypedValueVendorCapability(
+ TypedValueVendorCapability&& other) = default;
+
+TypedValueVendorCapability::~TypedValueVendorCapability() = default;
+
+TypedValueVendorCapability& TypedValueVendorCapability::operator=(
+ TypedValueVendorCapability&& other) = default;
+
+bool TypedValueVendorCapability::operator==(
+ const TypedValueVendorCapability& other) const {
+ return value_type_ == other.value_type_ &&
+ default_value_ == other.default_value_;
+}
+
+bool TypedValueVendorCapability::IsValid() const {
+ if (default_value_.empty())
+ return true;
+ switch (value_type_) {
+ case ValueType::BOOLEAN:
+ return default_value_ == "true" || default_value_ == "false";
+ case ValueType::FLOAT: {
+ double value;
+ return base::StringToDouble(default_value_, &value);
+ }
+ case ValueType::INTEGER: {
+ int value;
+ return base::StringToInt(default_value_, &value);
+ }
+ case ValueType::STRING:
+ return true;
+ }
+ NOTREACHED() << "Bad typed value capability value type";
+ return false;
+}
+
+bool TypedValueVendorCapability::LoadFrom(const base::Value& dict) {
+ const std::string* value_type_str = dict.FindStringKey(kKeyValueType);
+ if (!value_type_str || !TypeFromString(kTypedValueVendorCapabilityTypeNames,
+ *value_type_str, &value_type_)) {
+ return false;
+ }
+ const std::string* default_value_str =
+ dict.FindStringKey(kVendorCapabilityDefaultValue);
+ if (default_value_str)
+ default_value_ = *default_value_str;
+ return IsValid();
+}
+
+void TypedValueVendorCapability::SaveTo(base::Value* dict) const {
+ DCHECK(IsValid());
+ dict->SetKey(kKeyValueType,
+ base::Value(TypeToString(kTypedValueVendorCapabilityTypeNames,
+ value_type_)));
+ if (!default_value_.empty())
+ dict->SetKey(kVendorCapabilityDefaultValue, base::Value(default_value_));
+}
+
+VendorCapability::VendorCapability() = default;
+
+VendorCapability::VendorCapability(const std::string& id,
+ const std::string& display_name,
+ RangeVendorCapability range_capability)
+ : type_(Type::RANGE),
+ id_(id),
+ display_name_(display_name),
+ range_capability_(std::move(range_capability)) {}
+
+VendorCapability::VendorCapability(const std::string& id,
+ const std::string& display_name,
+ SelectVendorCapability select_capability)
+ : type_(Type::SELECT),
+ id_(id),
+ display_name_(display_name),
+ select_capability_(std::move(select_capability)) {}
+
+VendorCapability::VendorCapability(
+ const std::string& id,
+ const std::string& display_name,
+ TypedValueVendorCapability typed_value_capability)
+ : type_(Type::TYPED_VALUE),
+ id_(id),
+ display_name_(display_name),
+ typed_value_capability_(std::move(typed_value_capability)) {}
+
+VendorCapability::VendorCapability(VendorCapability&& other) = default;
+
+VendorCapability::~VendorCapability() = default;
+
+bool VendorCapability::operator==(const VendorCapability& other) const {
+ return type_ == other.type_ && id_ == other.id_ &&
+ display_name_ == other.display_name_ &&
+ range_capability_ == other.range_capability_ &&
+ select_capability_ == other.select_capability_ &&
+ typed_value_capability_ == other.typed_value_capability_;
+}
+
+bool VendorCapability::IsValid() const {
+ if (id_.empty() || display_name_.empty())
+ return false;
+ switch (type_) {
+ case Type::RANGE:
+ return !select_capability_ && !typed_value_capability_ &&
+ range_capability_ && range_capability_.value().IsValid();
+ case Type::SELECT:
+ return !range_capability_ && !typed_value_capability_ &&
+ select_capability_ && select_capability_.value().IsValid();
+ case Type::TYPED_VALUE:
+ return !range_capability_ && !select_capability_ &&
+ typed_value_capability_ &&
+ typed_value_capability_.value().IsValid();
+ }
+ NOTREACHED() << "Bad vendor capability type";
+ return false;
+}
+
+bool VendorCapability::LoadFrom(const base::Value& dict) {
+ const std::string* type_str = dict.FindStringKey(kKeyType);
+ if (!type_str ||
+ !TypeFromString(kVendorCapabilityTypeNames, *type_str, &type_)) {
+ return false;
+ }
+ const std::string* id_str = dict.FindStringKey(kKeyId);
+ if (!id_str)
+ return false;
+ id_ = *id_str;
+ const std::string* display_name_str = dict.FindStringKey(kKeyDisplayName);
+ if (!display_name_str)
+ return false;
+ display_name_ = *display_name_str;
+
+ const base::Value* range_capability_value =
+ dict.FindKey(kOptionRangeCapability);
+ if (range_capability_value) {
+ if (!range_capability_value->is_dict())
+ return false;
+ range_capability_ = RangeVendorCapability();
+ if (!range_capability_.value().LoadFrom(*range_capability_value))
+ return false;
+ }
+
+ const base::Value* select_capability_value =
+ dict.FindKey(kOptionSelectCapability);
+ if (select_capability_value) {
+ if (!select_capability_value->is_dict())
+ return false;
+ select_capability_ = SelectVendorCapability();
+ if (!select_capability_.value().LoadFrom(*select_capability_value))
+ return false;
+ }
+
+ const base::Value* typed_value_capability_value =
+ dict.FindKey(kOptionTypedValueCapability);
+ if (typed_value_capability_value) {
+ if (!typed_value_capability_value->is_dict())
+ return false;
+ typed_value_capability_ = TypedValueVendorCapability();
+ if (!typed_value_capability_.value().LoadFrom(
+ *typed_value_capability_value)) {
+ return false;
+ }
+ }
+
+ return IsValid();
}
+void VendorCapability::SaveTo(base::Value* dict) const {
+ DCHECK(IsValid());
+ dict->SetKey(kKeyType,
+ base::Value(TypeToString(kVendorCapabilityTypeNames, type_)));
+ dict->SetKey(kKeyId, base::Value(id_));
+ dict->SetKey(kKeyDisplayName, base::Value(display_name_));
+
+ if (range_capability_) {
+ base::Value range_capability_value(base::Value::Type::DICTIONARY);
+ range_capability_.value().SaveTo(&range_capability_value);
+ dict->SetKey(kOptionRangeCapability, std::move(range_capability_value));
+ } else if (select_capability_) {
+ base::Value select_capability_value(base::Value::Type::DICTIONARY);
+ select_capability_.value().SaveTo(&select_capability_value);
+ dict->SetKey(kOptionSelectCapability, std::move(select_capability_value));
+ } else {
+ DCHECK(typed_value_capability_);
+ base::Value typed_value_capability_value(base::Value::Type::DICTIONARY);
+ typed_value_capability_.value().SaveTo(&typed_value_capability_value);
+ dict->SetKey(kOptionTypedValueCapability,
+ std::move(typed_value_capability_value));
+ }
+}
+
+Color::Color() : type(ColorType::AUTO_COLOR) {}
+
Color::Color(ColorType type) : type(type) {
}
@@ -408,14 +820,17 @@ bool Color::operator==(const Color& other) const {
}
bool Color::IsValid() const {
- if (type != CUSTOM_COLOR && type != CUSTOM_MONOCHROME)
+ if (type != ColorType::CUSTOM_COLOR && type != ColorType::CUSTOM_MONOCHROME)
return true;
return !vendor_id.empty() && !custom_display_name.empty();
}
Margins::Margins()
- : type(STANDARD_MARGINS), top_um(0), right_um(0), bottom_um(0), left_um(0) {
-}
+ : type(MarginsType::STANDARD_MARGINS),
+ top_um(0),
+ right_um(0),
+ bottom_um(0),
+ left_um(0) {}
Margins::Margins(MarginsType type,
int32_t top_um,
@@ -448,8 +863,10 @@ bool Dpi::operator==(const Dpi& other) const {
}
Media::Media()
- : type(CUSTOM_MEDIA), width_um(0), height_um(0), is_continuous_feed(false) {
-}
+ : type(MediaType::CUSTOM_MEDIA),
+ width_um(0),
+ height_um(0),
+ is_continuous_feed(false) {}
Media::Media(MediaType type)
: type(type),
@@ -472,7 +889,7 @@ Media::Media(const std::string& custom_display_name,
const std::string& vendor_id,
int32_t width_um,
int32_t height_um)
- : type(CUSTOM_MEDIA),
+ : type(MediaType::CUSTOM_MEDIA),
width_um(width_um),
height_um(height_um),
is_continuous_feed(width_um <= 0 || height_um <= 0),
@@ -520,18 +937,12 @@ bool Interval::operator==(const Interval& other) const {
template <const char* kName>
class ItemsTraits {
public:
- static std::string GetCapabilityPath() {
- std::string result = kSectionPrinter;
- result += '.';
- result += kName;
- return result;
+ static std::vector<base::StringPiece> GetCapabilityPath() {
+ return {kSectionPrinter, kName};
}
- static std::string GetTicketItemPath() {
- std::string result = kSectionPrint;
- result += '.';
- result += kName;
- return result;
+ static std::vector<base::StringPiece> GetTicketItemPath() {
+ return {kSectionPrint, kName};
}
};
@@ -546,24 +957,30 @@ class NoValueValidation {
class ContentTypeTraits : public NoValueValidation,
public ItemsTraits<kOptionContentType> {
public:
- static bool Load(const base::DictionaryValue& dict, ContentType* option) {
- return dict.GetString(kKeyContentType, option);
+ static bool Load(const base::Value& dict, ContentType* option) {
+ const std::string* content_type = dict.FindStringKey(kKeyContentType);
+ if (!content_type)
+ return false;
+ *option = *content_type;
+ return true;
}
- static void Save(ContentType option, base::DictionaryValue* dict) {
- dict->SetString(kKeyContentType, option);
+ static void Save(ContentType option, base::Value* dict) {
+ dict->SetKey(kKeyContentType, base::Value(option));
}
};
class PwgRasterConfigTraits : public NoValueValidation,
public ItemsTraits<kOptionPwgRasterConfig> {
public:
- static bool Load(const base::DictionaryValue& dict, PwgRasterConfig* option) {
- std::string document_sheet_back;
+ static bool Load(const base::Value& dict, PwgRasterConfig* option) {
PwgRasterConfig option_out;
- if (dict.GetString(kPwgRasterDocumentSheetBack, &document_sheet_back)) {
- if (!TypeFromString(kDocumentSheetBackNames,
- document_sheet_back,
+ const base::Value* document_sheet_back =
+ dict.FindKey(kPwgRasterDocumentSheetBack);
+ if (document_sheet_back) {
+ if (!document_sheet_back->is_string() ||
+ !TypeFromString(kDocumentSheetBackNames,
+ document_sheet_back->GetString(),
&option_out.document_sheet_back)) {
return false;
}
@@ -574,40 +991,43 @@ class PwgRasterConfigTraits : public NoValueValidation,
if (document_types_supported) {
if (!document_types_supported->is_list())
return false;
-
- for (const auto& type : document_types_supported->GetList()) {
- if (!type.is_string())
+ for (const auto& type_value : document_types_supported->GetList()) {
+ if (!type_value.is_string())
return false;
- std::string type_str = type.GetString();
- if (type_str == kTypeDocumentSupportedTypeSRGB8)
- option_out.document_types_supported.push_back(SRGB_8);
- else if (type_str == kTypeDocumentSupportedTypeSGRAY8)
- option_out.document_types_supported.push_back(SGRAY_8);
+ const std::string& type = type_value.GetString();
+ if (type == kTypeDocumentSupportedTypeSRGB8) {
+ option_out.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SRGB_8);
+ } else if (type == kTypeDocumentSupportedTypeSGRAY8) {
+ option_out.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SGRAY_8);
+ }
}
}
- dict.GetBoolean(kPwgRasterReverseOrderStreaming,
- &option_out.reverse_order_streaming);
- dict.GetBoolean(kPwgRasterRotateAllPages, &option_out.rotate_all_pages);
+ option_out.reverse_order_streaming =
+ dict.FindBoolKey(kPwgRasterReverseOrderStreaming).value_or(false);
+ option_out.rotate_all_pages =
+ dict.FindBoolKey(kPwgRasterRotateAllPages).value_or(false);
*option = option_out;
return true;
}
- static void Save(const PwgRasterConfig& option, base::DictionaryValue* dict) {
- dict->SetString(
- kPwgRasterDocumentSheetBack,
- TypeToString(kDocumentSheetBackNames, option.document_sheet_back));
+ static void Save(const PwgRasterConfig& option, base::Value* dict) {
+ dict->SetKey(kPwgRasterDocumentSheetBack,
+ base::Value(TypeToString(kDocumentSheetBackNames,
+ option.document_sheet_back)));
if (!option.document_types_supported.empty()) {
base::Value::ListStorage supported_list;
for (const auto& type : option.document_types_supported) {
switch (type) {
- case SRGB_8:
+ case PwgDocumentTypeSupported::SRGB_8:
supported_list.push_back(
base::Value(kTypeDocumentSupportedTypeSRGB8));
break;
- case SGRAY_8:
+ case PwgDocumentTypeSupported::SGRAY_8:
supported_list.push_back(
base::Value(kTypeDocumentSupportedTypeSGRAY8));
break;
@@ -618,12 +1038,56 @@ class PwgRasterConfigTraits : public NoValueValidation,
}
if (option.reverse_order_streaming) {
- dict->SetBoolean(kPwgRasterReverseOrderStreaming,
- option.reverse_order_streaming);
+ dict->SetKey(kPwgRasterReverseOrderStreaming,
+ base::Value(option.reverse_order_streaming));
}
- if (option.rotate_all_pages)
- dict->SetBoolean(kPwgRasterRotateAllPages, option.rotate_all_pages);
+ if (option.rotate_all_pages) {
+ dict->SetKey(kPwgRasterRotateAllPages,
+ base::Value(option.rotate_all_pages));
+ }
+ }
+};
+
+class VendorCapabilityTraits : public ItemsTraits<kOptionVendorCapability> {
+ public:
+ static bool IsValid(const VendorCapability& option) {
+ return option.IsValid();
+ }
+
+ static bool Load(const base::Value& dict, VendorCapability* option) {
+ return option->LoadFrom(dict);
+ }
+
+ static void Save(const VendorCapability& option, base::Value* dict) {
+ option.SaveTo(dict);
+ }
+};
+
+class SelectVendorCapabilityTraits
+ : public ItemsTraits<kOptionSelectCapability> {
+ public:
+ static bool IsValid(const SelectVendorCapabilityOption& option) {
+ return option.IsValid();
+ }
+
+ static bool Load(const base::Value& dict,
+ SelectVendorCapabilityOption* option) {
+ const std::string* value = dict.FindStringKey(kKeyValue);
+ if (!value)
+ return false;
+ option->value = *value;
+ const std::string* display_name = dict.FindStringKey(kKeyDisplayName);
+ if (!display_name)
+ return false;
+ option->display_name = *display_name;
+ return true;
+ }
+
+ static void Save(const SelectVendorCapabilityOption& option,
+ base::Value* dict) {
+ dict->SetKey(kKeyValue, base::Value(option.value));
+ dict->SetKey(kKeyDisplayName, base::Value(option.display_name));
}
};
@@ -631,51 +1095,55 @@ class ColorTraits : public ItemsTraits<kOptionColor> {
public:
static bool IsValid(const Color& option) { return option.IsValid(); }
- static bool Load(const base::DictionaryValue& dict, Color* option) {
- std::string type_str;
- if (!dict.GetString(kKeyType, &type_str))
- return false;
- if (!TypeFromString(kColorNames, type_str, &option->type))
+ static bool Load(const base::Value& dict, Color* option) {
+ const std::string* type = dict.FindStringKey(kKeyType);
+ if (!type || !TypeFromString(kColorNames, *type, &option->type))
return false;
- dict.GetString(kKeyVendorId, &option->vendor_id);
- dict.GetString(kCustomName, &option->custom_display_name);
+ const std::string* vendor_id = dict.FindStringKey(kKeyVendorId);
+ if (vendor_id)
+ option->vendor_id = *vendor_id;
+ const std::string* custom_display_name =
+ dict.FindStringKey(kKeyCustomDisplayName);
+ if (custom_display_name)
+ option->custom_display_name = *custom_display_name;
return true;
}
- static void Save(const Color& option, base::DictionaryValue* dict) {
- dict->SetString(kKeyType, TypeToString(kColorNames, option.type));
+ static void Save(const Color& option, base::Value* dict) {
+ dict->SetKey(kKeyType, base::Value(TypeToString(kColorNames, option.type)));
if (!option.vendor_id.empty())
- dict->SetString(kKeyVendorId, option.vendor_id);
- if (!option.custom_display_name.empty())
- dict->SetString(kCustomName, option.custom_display_name);
+ dict->SetKey(kKeyVendorId, base::Value(option.vendor_id));
+ if (!option.custom_display_name.empty()) {
+ dict->SetKey(kKeyCustomDisplayName,
+ base::Value(option.custom_display_name));
+ }
}
};
class DuplexTraits : public NoValueValidation,
public ItemsTraits<kOptionDuplex> {
public:
- static bool Load(const base::DictionaryValue& dict, DuplexType* option) {
- std::string type_str;
- return dict.GetString(kKeyType, &type_str) &&
- TypeFromString(kDuplexNames, type_str, option);
+ static bool Load(const base::Value& dict, DuplexType* option) {
+ const std::string* type = dict.FindStringKey(kKeyType);
+ return type && TypeFromString(kDuplexNames, *type, option);
}
- static void Save(DuplexType option, base::DictionaryValue* dict) {
- dict->SetString(kKeyType, TypeToString(kDuplexNames, option));
+ static void Save(DuplexType option, base::Value* dict) {
+ dict->SetKey(kKeyType, base::Value(TypeToString(kDuplexNames, option)));
}
};
class OrientationTraits : public NoValueValidation,
public ItemsTraits<kOptionPageOrientation> {
public:
- static bool Load(const base::DictionaryValue& dict, OrientationType* option) {
- std::string type_str;
- return dict.GetString(kKeyType, &type_str) &&
- TypeFromString(kOrientationNames, type_str, option);
+ static bool Load(const base::Value& dict, OrientationType* option) {
+ const std::string* type = dict.FindStringKey(kKeyType);
+ return type && TypeFromString(kOrientationNames, *type, option);
}
- static void Save(OrientationType option, base::DictionaryValue* dict) {
- dict->SetString(kKeyType, TypeToString(kOrientationNames, option));
+ static void Save(OrientationType option, base::Value* dict) {
+ dict->SetKey(kKeyType,
+ base::Value(TypeToString(kOrientationNames, option)));
}
};
@@ -683,36 +1151,46 @@ class CopiesTraits : public ItemsTraits<kOptionCopies> {
public:
static bool IsValid(int32_t option) { return option >= 1; }
- static bool Load(const base::DictionaryValue& dict, int32_t* option) {
- return dict.GetInteger(kOptionCopies, option);
+ static bool Load(const base::Value& dict, int32_t* option) {
+ base::Optional<int> copies = dict.FindIntKey(kOptionCopies);
+ if (!copies)
+ return false;
+ *option = copies.value();
+ return true;
}
- static void Save(int32_t option, base::DictionaryValue* dict) {
- dict->SetInteger(kOptionCopies, option);
+ static void Save(int32_t option, base::Value* dict) {
+ dict->SetKey(kOptionCopies, base::Value(option));
}
};
class MarginsTraits : public NoValueValidation,
public ItemsTraits<kOptionMargins> {
public:
- static bool Load(const base::DictionaryValue& dict, Margins* option) {
- std::string type_str;
- if (!dict.GetString(kKeyType, &type_str))
+ static bool Load(const base::Value& dict, Margins* option) {
+ const std::string* type = dict.FindStringKey(kKeyType);
+ if (!type || !TypeFromString(kMarginsNames, *type, &option->type))
return false;
- if (!TypeFromString(kMarginsNames, type_str, &option->type))
+ base::Optional<int> top_um = dict.FindIntKey(kMarginTop);
+ base::Optional<int> right_um = dict.FindIntKey(kMarginRight);
+ base::Optional<int> bottom_um = dict.FindIntKey(kMarginBottom);
+ base::Optional<int> left_um = dict.FindIntKey(kMarginLeft);
+ if (!top_um || !right_um || !bottom_um || !left_um)
return false;
- return dict.GetInteger(kMarginTop, &option->top_um) &&
- dict.GetInteger(kMarginRight, &option->right_um) &&
- dict.GetInteger(kMarginBottom, &option->bottom_um) &&
- dict.GetInteger(kMarginLeft, &option->left_um);
+ option->top_um = top_um.value();
+ option->right_um = right_um.value();
+ option->bottom_um = bottom_um.value();
+ option->left_um = left_um.value();
+ return true;
}
- static void Save(const Margins& option, base::DictionaryValue* dict) {
- dict->SetString(kKeyType, TypeToString(kMarginsNames, option.type));
- dict->SetInteger(kMarginTop, option.top_um);
- dict->SetInteger(kMarginRight, option.right_um);
- dict->SetInteger(kMarginBottom, option.bottom_um);
- dict->SetInteger(kMarginLeft, option.left_um);
+ static void Save(const Margins& option, base::Value* dict) {
+ dict->SetKey(kKeyType,
+ base::Value(TypeToString(kMarginsNames, option.type)));
+ dict->SetKey(kMarginTop, base::Value(option.top_um));
+ dict->SetKey(kMarginRight, base::Value(option.right_um));
+ dict->SetKey(kMarginBottom, base::Value(option.bottom_um));
+ dict->SetKey(kMarginLeft, base::Value(option.left_um));
}
};
@@ -720,28 +1198,32 @@ class DpiTraits : public ItemsTraits<kOptionDpi> {
public:
static bool IsValid(const Dpi& option) { return option.IsValid(); }
- static bool Load(const base::DictionaryValue& dict, Dpi* option) {
- return dict.GetInteger(kDpiHorizontal, &option->horizontal) &&
- dict.GetInteger(kDpiVertical, &option->vertical);
+ static bool Load(const base::Value& dict, Dpi* option) {
+ base::Optional<int> horizontal = dict.FindIntKey(kDpiHorizontal);
+ base::Optional<int> vertical = dict.FindIntKey(kDpiVertical);
+ if (!horizontal || !vertical)
+ return false;
+ option->horizontal = horizontal.value();
+ option->vertical = vertical.value();
+ return true;
}
- static void Save(const Dpi& option, base::DictionaryValue* dict) {
- dict->SetInteger(kDpiHorizontal, option.horizontal);
- dict->SetInteger(kDpiVertical, option.vertical);
+ static void Save(const Dpi& option, base::Value* dict) {
+ dict->SetKey(kDpiHorizontal, base::Value(option.horizontal));
+ dict->SetKey(kDpiVertical, base::Value(option.vertical));
}
};
class FitToPageTraits : public NoValueValidation,
public ItemsTraits<kOptionFitToPage> {
public:
- static bool Load(const base::DictionaryValue& dict, FitToPageType* option) {
- std::string type_str;
- return dict.GetString(kKeyType, &type_str) &&
- TypeFromString(kFitToPageNames, type_str, option);
+ static bool Load(const base::Value& dict, FitToPageType* option) {
+ const std::string* type = dict.FindStringKey(kKeyType);
+ return type && TypeFromString(kFitToPageNames, *type, option);
}
- static void Save(FitToPageType option, base::DictionaryValue* dict) {
- dict->SetString(kKeyType, TypeToString(kFitToPageNames, option));
+ static void Save(FitToPageType option, base::Value* dict) {
+ dict->SetKey(kKeyType, base::Value(TypeToString(kFitToPageNames, option)));
}
};
@@ -756,33 +1238,32 @@ class PageRangeTraits : public ItemsTraits<kOptionPageRange> {
return true;
}
- static bool Load(const base::DictionaryValue& dict, PageRange* option) {
- const base::ListValue* list = nullptr;
- if (!dict.GetList(kPageRangeInterval, &list))
+ static bool Load(const base::Value& dict, PageRange* option) {
+ const base::Value* list_value =
+ dict.FindKeyOfType(kPageRangeInterval, base::Value::Type::LIST);
+ if (!list_value)
return false;
- for (size_t i = 0; i < list->GetSize(); ++i) {
- const base::DictionaryValue* interval = nullptr;
- if (!list->GetDictionary(i, &interval))
- return false;
- Interval new_interval(1, kMaxPageNumber);
- interval->GetInteger(kPageRangeStart, &new_interval.start);
- interval->GetInteger(kPageRangeEnd, &new_interval.end);
- option->push_back(new_interval);
+ const base::Value::ListStorage& list = list_value->GetList();
+ for (const base::Value& interval : list) {
+ int page_range_start = interval.FindIntKey(kPageRangeStart).value_or(1);
+ int page_range_end =
+ interval.FindIntKey(kPageRangeEnd).value_or(kMaxPageNumber);
+ option->push_back(Interval(page_range_start, page_range_end));
}
return true;
}
- static void Save(const PageRange& option, base::DictionaryValue* dict) {
+ static void Save(const PageRange& option, base::Value* dict) {
if (!option.empty()) {
- auto list = std::make_unique<base::ListValue>();
+ base::Value list(base::Value::Type::LIST);
for (size_t i = 0; i < option.size(); ++i) {
- auto interval = std::make_unique<base::DictionaryValue>();
- interval->SetInteger(kPageRangeStart, option[i].start);
+ base::Value interval(base::Value::Type::DICTIONARY);
+ interval.SetKey(kPageRangeStart, base::Value(option[i].start));
if (option[i].end < kMaxPageNumber)
- interval->SetInteger(kPageRangeEnd, option[i].end);
- list->Append(std::move(interval));
+ interval.SetKey(kPageRangeEnd, base::Value(option[i].end));
+ list.GetList().emplace_back(std::move(interval));
}
- dict->Set(kPageRangeInterval, std::move(list));
+ dict->SetKey(kPageRangeInterval, std::move(list));
}
}
};
@@ -791,34 +1272,48 @@ class MediaTraits : public ItemsTraits<kOptionMediaSize> {
public:
static bool IsValid(const Media& option) { return option.IsValid(); }
- static bool Load(const base::DictionaryValue& dict, Media* option) {
- std::string type_str;
- if (dict.GetString(kKeyName, &type_str)) {
- if (!TypeFromString(kMediaDefinitions, type_str, &option->type))
- return false;
- }
-
- dict.GetInteger(kMediaWidth, &option->width_um);
- dict.GetInteger(kMediaHeight, &option->height_um);
- dict.GetBoolean(kMediaIsContinuous, &option->is_continuous_feed);
- dict.GetString(kCustomName, &option->custom_display_name);
- dict.GetString(kKeyVendorId, &option->vendor_id);
+ static bool Load(const base::Value& dict, Media* option) {
+ const std::string* type = dict.FindStringKey(kKeyName);
+ if (type && !TypeFromString(kMediaDefinitions, *type, &option->type))
+ return false;
+ base::Optional<int> width_um = dict.FindIntKey(kMediaWidth);
+ if (width_um)
+ option->width_um = width_um.value();
+ base::Optional<int> height_um = dict.FindIntKey(kMediaHeight);
+ if (height_um)
+ option->height_um = height_um.value();
+ base::Optional<bool> is_continuous_feed =
+ dict.FindBoolKey(kMediaIsContinuous);
+ if (is_continuous_feed)
+ option->is_continuous_feed = is_continuous_feed.value();
+ const std::string* custom_display_name =
+ dict.FindStringKey(kKeyCustomDisplayName);
+ if (custom_display_name)
+ option->custom_display_name = *custom_display_name;
+ const std::string* vendor_id = dict.FindStringKey(kKeyVendorId);
+ if (vendor_id)
+ option->vendor_id = *vendor_id;
return true;
}
- static void Save(const Media& option, base::DictionaryValue* dict) {
- if (option.type != CUSTOM_MEDIA)
- dict->SetString(kKeyName, TypeToString(kMediaDefinitions, option.type));
- if (!option.custom_display_name.empty() || option.type == CUSTOM_MEDIA)
- dict->SetString(kCustomName, option.custom_display_name);
+ static void Save(const Media& option, base::Value* dict) {
+ if (option.type != MediaType::CUSTOM_MEDIA) {
+ dict->SetKey(kKeyName,
+ base::Value(TypeToString(kMediaDefinitions, option.type)));
+ }
+ if (!option.custom_display_name.empty() ||
+ option.type == MediaType::CUSTOM_MEDIA) {
+ dict->SetKey(kKeyCustomDisplayName,
+ base::Value(option.custom_display_name));
+ }
if (!option.vendor_id.empty())
- dict->SetString(kKeyVendorId, option.vendor_id);
+ dict->SetKey(kKeyVendorId, base::Value(option.vendor_id));
if (option.width_um > 0)
- dict->SetInteger(kMediaWidth, option.width_um);
+ dict->SetKey(kMediaWidth, base::Value(option.width_um));
if (option.height_um > 0)
- dict->SetInteger(kMediaHeight, option.height_um);
+ dict->SetKey(kMediaHeight, base::Value(option.height_um));
if (option.is_continuous_feed)
- dict->SetBoolean(kMediaIsContinuous, true);
+ dict->SetKey(kMediaIsContinuous, base::Value(true));
}
};
@@ -827,12 +1322,16 @@ class CollateTraits : public NoValueValidation,
public:
static const bool kDefault = true;
- static bool Load(const base::DictionaryValue& dict, bool* option) {
- return dict.GetBoolean(kOptionCollate, option);
+ static bool Load(const base::Value& dict, bool* option) {
+ base::Optional<bool> collate = dict.FindBoolKey(kOptionCollate);
+ if (!collate)
+ return false;
+ *option = collate.value();
+ return true;
}
- static void Save(bool option, base::DictionaryValue* dict) {
- dict->SetBoolean(kOptionCollate, option);
+ static void Save(bool option, base::Value* dict) {
+ dict->SetKey(kOptionCollate, base::Value(option));
}
};
@@ -841,14 +1340,35 @@ class ReverseTraits : public NoValueValidation,
public:
static const bool kDefault = false;
- static bool Load(const base::DictionaryValue& dict, bool* option) {
- return dict.GetBoolean(kOptionReverse, option);
+ static bool Load(const base::Value& dict, bool* option) {
+ base::Optional<bool> reverse = dict.FindBoolKey(kOptionReverse);
+ if (!reverse)
+ return false;
+ *option = reverse.value();
+ return true;
+ }
+
+ static void Save(bool option, base::Value* dict) {
+ dict->SetKey(kOptionReverse, base::Value(option));
+ }
+};
+
+#if defined(OS_CHROMEOS)
+class PinTraits : public NoValueValidation, public ItemsTraits<kOptionPin> {
+ public:
+ static bool Load(const base::Value& dict, bool* option) {
+ base::Optional<bool> supported = dict.FindBoolKey(kPinSupported);
+ if (!supported)
+ return false;
+ *option = supported.value();
+ return true;
}
- static void Save(bool option, base::DictionaryValue* dict) {
- dict->SetBoolean(kOptionReverse, option);
+ static void Save(bool option, base::Value* dict) {
+ dict->SetKey(kPinSupported, base::Value(option));
}
};
+#endif // defined(OS_CHROMEOS)
} // namespace printer
@@ -856,6 +1376,9 @@ using namespace printer;
template class ListCapability<ContentType, ContentTypeTraits>;
template class ValueCapability<PwgRasterConfig, PwgRasterConfigTraits>;
+template class ListCapability<VendorCapability, VendorCapabilityTraits>;
+template class SelectionCapability<SelectVendorCapabilityOption,
+ SelectVendorCapabilityTraits>;
template class SelectionCapability<Color, ColorTraits>;
template class SelectionCapability<DuplexType, DuplexTraits>;
template class SelectionCapability<OrientationType, OrientationTraits>;
@@ -867,6 +1390,9 @@ template class EmptyCapability<class CopiesTraits>;
template class EmptyCapability<class PageRangeTraits>;
template class BooleanCapability<class CollateTraits>;
template class BooleanCapability<class ReverseTraits>;
+#if defined(OS_CHROMEOS)
+template class ValueCapability<bool, class PinTraits>;
+#endif // defined(OS_CHROMEOS)
template class TicketItem<PwgRasterConfig, PwgRasterConfigTraits>;
template class TicketItem<Color, ColorTraits>;
diff --git a/chromium/components/cloud_devices/common/printer_description.h b/chromium/components/cloud_devices/common/printer_description.h
index 344075f8911..786b5e55c37 100644
--- a/chromium/components/cloud_devices/common/printer_description.h
+++ b/chromium/components/cloud_devices/common/printer_description.h
@@ -11,6 +11,8 @@
#include <vector>
#include "base/logging.h"
+#include "base/optional.h"
+#include "build/build_config.h"
#include "components/cloud_devices/common/description_items.h"
// Defines printer options, CDD and CJT items.
@@ -20,11 +22,22 @@ namespace cloud_devices {
namespace printer {
+struct SelectVendorCapabilityOption;
+class SelectVendorCapabilityTraits;
+typedef SelectionCapability<SelectVendorCapabilityOption,
+ SelectVendorCapabilityTraits>
+ SelectVendorCapability;
+
typedef std::string ContentType;
-enum DocumentSheetBack { NORMAL, ROTATED, MANUAL_TUMBLE, FLIPPED };
+enum class DocumentSheetBack {
+ NORMAL,
+ ROTATED,
+ MANUAL_TUMBLE,
+ FLIPPED,
+};
-enum PwgDocumentTypeSupported {
+enum class PwgDocumentTypeSupported {
SGRAY_8 = 22,
SRGB_8 = 23,
};
@@ -39,7 +52,138 @@ struct PwgRasterConfig {
bool rotate_all_pages;
};
-enum ColorType {
+class RangeVendorCapability {
+ public:
+ enum class ValueType {
+ FLOAT,
+ INTEGER,
+ };
+
+ RangeVendorCapability();
+ RangeVendorCapability(ValueType value_type,
+ const std::string& min_value,
+ const std::string& max_value);
+ RangeVendorCapability(ValueType value_type,
+ const std::string& min_value,
+ const std::string& max_value,
+ const std::string& default_value);
+ RangeVendorCapability(RangeVendorCapability&& other);
+ ~RangeVendorCapability();
+
+ RangeVendorCapability& operator=(RangeVendorCapability&& other);
+
+ bool operator==(const RangeVendorCapability& other) const;
+ bool operator!=(const RangeVendorCapability& other) const {
+ return !(*this == other);
+ }
+
+ bool IsValid() const;
+ bool LoadFrom(const base::Value& dict);
+ void SaveTo(base::Value* dict) const;
+
+ private:
+ ValueType value_type_;
+ std::string min_value_;
+ std::string max_value_;
+ std::string default_value_;
+
+ DISALLOW_COPY_AND_ASSIGN(RangeVendorCapability);
+};
+
+struct SelectVendorCapabilityOption {
+ SelectVendorCapabilityOption();
+ SelectVendorCapabilityOption(const std::string& value,
+ const std::string& display_name);
+ ~SelectVendorCapabilityOption();
+
+ bool IsValid() const;
+ bool operator==(const SelectVendorCapabilityOption& other) const;
+ bool operator!=(const SelectVendorCapabilityOption& other) const {
+ return !(*this == other);
+ }
+
+ std::string value;
+ std::string display_name;
+};
+
+class TypedValueVendorCapability {
+ public:
+ enum class ValueType {
+ BOOLEAN,
+ FLOAT,
+ INTEGER,
+ STRING,
+ };
+
+ TypedValueVendorCapability();
+ explicit TypedValueVendorCapability(ValueType value_type);
+ TypedValueVendorCapability(ValueType value_type,
+ const std::string& default_value);
+ TypedValueVendorCapability(TypedValueVendorCapability&& other);
+ ~TypedValueVendorCapability();
+
+ TypedValueVendorCapability& operator=(TypedValueVendorCapability&& other);
+
+ bool operator==(const TypedValueVendorCapability& other) const;
+ bool operator!=(const TypedValueVendorCapability& other) const {
+ return !(*this == other);
+ }
+
+ bool IsValid() const;
+ bool LoadFrom(const base::Value& dict);
+ void SaveTo(base::Value* dict) const;
+
+ private:
+ ValueType value_type_;
+ std::string default_value_;
+
+ DISALLOW_COPY_AND_ASSIGN(TypedValueVendorCapability);
+};
+
+class VendorCapability {
+ public:
+ enum class Type {
+ RANGE,
+ SELECT,
+ TYPED_VALUE,
+ };
+
+ VendorCapability();
+ VendorCapability(const std::string& id,
+ const std::string& display_name,
+ RangeVendorCapability range_capability);
+ VendorCapability(const std::string& id,
+ const std::string& display_name,
+ SelectVendorCapability select_capability);
+ VendorCapability(const std::string& id,
+ const std::string& display_name,
+ TypedValueVendorCapability typed_value_capability);
+ VendorCapability(VendorCapability&& other);
+ ~VendorCapability();
+
+ bool operator==(const VendorCapability& other) const;
+ bool operator!=(const VendorCapability& other) const {
+ return !(*this == other);
+ }
+
+ bool IsValid() const;
+ bool LoadFrom(const base::Value& dict);
+ void SaveTo(base::Value* dict) const;
+
+ private:
+ Type type_;
+ std::string id_;
+ std::string display_name_;
+
+ // If the CDD is valid, exactly one of the capabilities has non-nullopt value.
+ base::Optional<RangeVendorCapability> range_capability_;
+ base::Optional<SelectVendorCapability> select_capability_;
+ base::Optional<TypedValueVendorCapability> typed_value_capability_;
+
+ DISALLOW_COPY_AND_ASSIGN(VendorCapability);
+};
+
+enum class ColorType {
STANDARD_COLOR,
STANDARD_MONOCHROME,
CUSTOM_COLOR,
@@ -60,19 +204,19 @@ struct Color {
std::string custom_display_name;
};
-enum DuplexType {
+enum class DuplexType {
NO_DUPLEX,
LONG_EDGE,
SHORT_EDGE,
};
-enum OrientationType {
+enum class OrientationType {
PORTRAIT,
LANDSCAPE,
AUTO_ORIENTATION,
};
-enum MarginsType {
+enum class MarginsType {
NO_MARGINS,
STANDARD_MARGINS,
CUSTOM_MARGINS,
@@ -108,7 +252,7 @@ struct Dpi {
int32_t vertical;
};
-enum FitToPageType {
+enum class FitToPageType {
NO_FITTING,
FIT_TO_PAGE,
GROW_TO_PAGE,
@@ -116,7 +260,7 @@ enum FitToPageType {
FILL_PAGE,
};
-enum MediaType {
+enum class MediaType {
CUSTOM_MEDIA,
// North American standard sheet media names.
@@ -338,6 +482,7 @@ typedef std::vector<Interval> PageRange;
class ContentTypeTraits;
class PwgRasterConfigTraits;
+class VendorCapabilityTraits;
class ColorTraits;
class DuplexTraits;
class OrientationTraits;
@@ -352,6 +497,8 @@ class CollateTraits;
typedef ListCapability<ContentType, ContentTypeTraits> ContentTypesCapability;
typedef ValueCapability<PwgRasterConfig, PwgRasterConfigTraits>
PwgRasterConfigCapability;
+typedef ListCapability<VendorCapability, VendorCapabilityTraits>
+ VendorCapabilities;
typedef SelectionCapability<Color, ColorTraits> ColorCapability;
typedef SelectionCapability<DuplexType, DuplexTraits> DuplexCapability;
typedef SelectionCapability<OrientationType, OrientationTraits>
@@ -364,6 +511,11 @@ typedef EmptyCapability<class CopiesTraits> CopiesCapability;
typedef EmptyCapability<class PageRangeTraits> PageRangeCapability;
typedef BooleanCapability<class CollateTraits> CollateCapability;
typedef BooleanCapability<class ReverseTraits> ReverseCapability;
+#if defined(OS_CHROMEOS)
+// This capability is not a part of standard CDD description. It's used for
+// providing PIN printing opportunity in Chrome OS native printing.
+typedef ValueCapability<bool, class PinTraits> PinCapability;
+#endif // defined(OS_CHROMEOS)
typedef TicketItem<PwgRasterConfig, PwgRasterConfigTraits>
PwgRasterConfigTicketItem;
diff --git a/chromium/components/cloud_devices/common/printer_description_unittest.cc b/chromium/components/cloud_devices/common/printer_description_unittest.cc
index a61825f0187..776892cbc36 100644
--- a/chromium/components/cloud_devices/common/printer_description_unittest.cc
+++ b/chromium/components/cloud_devices/common/printer_description_unittest.cc
@@ -5,6 +5,7 @@
#include "components/cloud_devices/common/printer_description.h"
#include <memory>
+#include <utility>
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@@ -22,7 +23,7 @@ namespace printer {
std::string NormalizeJson(const std::string& json) {
std::string result = json;
base::ReplaceChars(result, "'", "\"", &result);
- std::unique_ptr<base::Value> value = base::JSONReader::Read(result);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(result);
base::JSONWriter::Write(*value, &result);
return result;
}
@@ -270,6 +271,266 @@ const char kDocumentTypeNotListCdd[] =
" }"
"}";
+const char kIntegerRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'INTEGER',"
+ " 'min': '0',"
+ " 'max': '10'"
+ "}";
+
+const char kFloatDefaultRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'FLOAT',"
+ " 'min': '0.0',"
+ " 'max': '1.0',"
+ " 'default': '0.5'"
+ "}";
+
+const char kInvalidTypeRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'BOOLEAN',"
+ " 'min': '0.0',"
+ " 'max': '1.0'"
+ "}";
+
+const char kMissingMinValueRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'INT',"
+ " 'max': '10'"
+ "}";
+
+const char kInvalidBoundariesRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'INT',"
+ " 'min': '10',"
+ " 'max': '0'"
+ "}";
+
+const char kInvalidDefaultValueRangeVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'FLOAT',"
+ " 'min': '0.0',"
+ " 'max': '5.0',"
+ " 'default': '10.0'"
+ "}";
+
+const char kSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': [ {"
+ " 'value': 'value_1',"
+ " 'display_name': 'name_1'"
+ " }, {"
+ " 'value': 'value_2',"
+ " 'display_name': 'name_2',"
+ " 'is_default': true"
+ " } ]"
+ "}";
+
+const char kNotListSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': {"
+ " 'value': 'value',"
+ " 'display_name': 'name'"
+ " }"
+ "}";
+
+const char kMissingValueSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': [ {"
+ " 'display_name': 'name'"
+ " } ]"
+ "}";
+
+const char kMissingDisplayNameSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': [ {"
+ " 'value': 'value'"
+ " } ]"
+ "}";
+
+const char kNoDefaultSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': [ {"
+ " 'value': 'value',"
+ " 'display_name': 'name'"
+ " } ]"
+ "}";
+
+const char kSeveralDefaultsSelectVendorCapabilityJson[] =
+ "{"
+ " 'option': [ {"
+ " 'value': 'value_1',"
+ " 'display_name': 'name_1',"
+ " 'is_default': true"
+ " }, {"
+ " 'value': 'value_2',"
+ " 'display_name': 'name_2',"
+ " 'is_default': true"
+ " } ]"
+ "}";
+
+const char kBooleanTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'BOOLEAN',"
+ " 'default': 'true'"
+ "}";
+
+const char kFloatTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'FLOAT',"
+ " 'default': '1.0'"
+ "}";
+
+const char kIntegerTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'INTEGER',"
+ " 'default': '10'"
+ "}";
+
+const char kStringTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'STRING',"
+ " 'default': 'value'"
+ "}";
+
+const char kMissingValueTypeTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'default': 'value'"
+ "}";
+
+const char kInvalidBooleanTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'BOOLEAN',"
+ " 'default': '1'"
+ "}";
+
+const char kInvalidFloatTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'FLOAT',"
+ " 'default': '1.1.1.1'"
+ "}";
+
+const char kInvalidIntegerTypedValueVendorCapabilityJson[] =
+ "{"
+ " 'value_type': 'INTEGER',"
+ " 'default': 'true'"
+ "}";
+
+const char kVendorCapabilityOnlyCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'vendor_capability': [ {"
+ " 'id': 'id_1',"
+ " 'display_name': 'name_1',"
+ " 'type': 'RANGE',"
+ " 'range_cap': {"
+ " 'value_type': 'INTEGER',"
+ " 'min': '1',"
+ " 'max': '10'"
+ " }"
+ " }, {"
+ " 'id': 'id_2',"
+ " 'display_name': 'name_2',"
+ " 'type': 'SELECT',"
+ " 'select_cap': {"
+ " 'option': [ {"
+ " 'value': 'value',"
+ " 'display_name': 'name',"
+ " 'is_default': true"
+ " } ]"
+ " }"
+ " }, {"
+ " 'id': 'id_3',"
+ " 'display_name': 'name_3',"
+ " 'type': 'TYPED_VALUE',"
+ " 'typed_value_cap': {"
+ " 'value_type': 'INTEGER',"
+ " 'default': '1'"
+ " }"
+ " } ]"
+ " }"
+ "}";
+
+const char kMissingIdVendorCapabilityCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'vendor_capability': [ {"
+ " 'display_name': 'name_1',"
+ " 'type': 'RANGE',"
+ " 'range_cap': {"
+ " 'value_type': 'INTEGER',"
+ " 'min': '1',"
+ " 'max': '10'"
+ " }"
+ " } ]"
+ " }"
+ "}";
+
+const char kInvalidInnerCapabilityVendorCapabilityCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'vendor_capability': [ {"
+ " 'display_name': 'name_1',"
+ " 'type': 'RANGE',"
+ " 'range_cap': {"
+ " 'value_type': 'INTEGER',"
+ " 'min': '10',"
+ " 'max': '1'"
+ " }"
+ " } ]"
+ " }"
+ "}";
+
+const char kNoInnerCapabilityVendorCapabilityCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'vendor_capability': [ {"
+ " 'display_name': 'name_1',"
+ " 'type': 'RANGE'"
+ " } ]"
+ " }"
+ "}";
+
+const char kSeveralInnerCapabilitiesVendorCapabilityCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'vendor_capability': [ {"
+ " 'id': 'id_1',"
+ " 'display_name': 'name_1',"
+ " 'type': 'RANGE',"
+ " 'range_cap': {"
+ " 'value_type': 'INTEGER',"
+ " 'min': '1',"
+ " 'max': '10'"
+ " },"
+ " 'select_cap': {"
+ " 'option': [ {"
+ " 'value': 'value',"
+ " 'display_name': 'name',"
+ " 'is_default': true"
+ " } ]"
+ " }"
+ " } ]"
+ " }"
+ "}";
+
+#if defined(OS_CHROMEOS)
+const char kPinOnlyCdd[] =
+ "{"
+ " 'version': '1.0',"
+ " 'printer': {"
+ " 'pin': {"
+ " 'supported': true"
+ " }"
+ " }"
+ "}";
+#endif // defined(OS_CHROMEOS)
+
const char kCjt[] =
"{"
" 'version': '1.0',"
@@ -338,6 +599,38 @@ const char kBadVersionCjt[] =
" }"
"}";
+const struct TestRangeCapabilities {
+ const char* const json_name;
+ RangeVendorCapability range_capability;
+} kTestRangeCapabilities[] = {
+ {kIntegerRangeVendorCapabilityJson,
+ RangeVendorCapability(RangeVendorCapability::ValueType::INTEGER,
+ "0",
+ "10")},
+ {kFloatDefaultRangeVendorCapabilityJson,
+ RangeVendorCapability(RangeVendorCapability::ValueType::FLOAT,
+ "0.0",
+ "1.0",
+ "0.5")}};
+
+const struct TestTypedValueCapabilities {
+ const char* const json_name;
+ TypedValueVendorCapability typed_value_capability;
+} kTestTypedValueCapabilities[] = {
+ {kBooleanTypedValueVendorCapabilityJson,
+ TypedValueVendorCapability(TypedValueVendorCapability::ValueType::BOOLEAN,
+ "true")},
+ {kFloatTypedValueVendorCapabilityJson,
+ TypedValueVendorCapability(TypedValueVendorCapability::ValueType::FLOAT,
+ "1.0")},
+ {kIntegerTypedValueVendorCapabilityJson,
+ TypedValueVendorCapability(TypedValueVendorCapability::ValueType::INTEGER,
+ "10")},
+ {kStringTypedValueVendorCapabilityJson,
+ TypedValueVendorCapability(TypedValueVendorCapability::ValueType::STRING,
+ "value")},
+};
+
TEST(PrinterDescriptionTest, CddInit) {
CloudDeviceDescription description;
EXPECT_EQ(NormalizeJson(kDefaultCdd), NormalizeJson(description.ToString()));
@@ -406,42 +699,42 @@ TEST(PrinterDescriptionTest, CddSetAll) {
content_types.AddOption("image/jpeg");
PwgRasterConfig custom_raster;
- custom_raster.document_sheet_back = MANUAL_TUMBLE;
+ custom_raster.document_sheet_back = DocumentSheetBack::MANUAL_TUMBLE;
custom_raster.reverse_order_streaming = true;
custom_raster.rotate_all_pages = false;
pwg_raster_config.set_value(custom_raster);
- color.AddDefaultOption(Color(STANDARD_COLOR), true);
- color.AddOption(Color(STANDARD_MONOCHROME));
- Color custom(CUSTOM_MONOCHROME);
+ color.AddDefaultOption(Color(ColorType::STANDARD_COLOR), true);
+ color.AddOption(Color(ColorType::STANDARD_MONOCHROME));
+ Color custom(ColorType::CUSTOM_MONOCHROME);
custom.vendor_id = "123";
custom.custom_display_name = "monochrome";
color.AddOption(custom);
- duplex.AddDefaultOption(LONG_EDGE, true);
- duplex.AddOption(SHORT_EDGE);
- duplex.AddOption(NO_DUPLEX);
+ duplex.AddDefaultOption(DuplexType::LONG_EDGE, true);
+ duplex.AddOption(DuplexType::SHORT_EDGE);
+ duplex.AddOption(DuplexType::NO_DUPLEX);
- orientation.AddOption(PORTRAIT);
- orientation.AddOption(LANDSCAPE);
- orientation.AddDefaultOption(AUTO_ORIENTATION, true);
+ orientation.AddOption(OrientationType::PORTRAIT);
+ orientation.AddOption(OrientationType::LANDSCAPE);
+ orientation.AddDefaultOption(OrientationType::AUTO_ORIENTATION, true);
- margins.AddDefaultOption(Margins(NO_MARGINS, 0, 0, 0, 0), true);
- margins.AddOption(Margins(STANDARD_MARGINS, 100, 200, 300, 400));
- margins.AddOption(Margins(CUSTOM_MARGINS, 1, 2, 3, 4));
+ margins.AddDefaultOption(Margins(MarginsType::NO_MARGINS, 0, 0, 0, 0), true);
+ margins.AddOption(Margins(MarginsType::STANDARD_MARGINS, 100, 200, 300, 400));
+ margins.AddOption(Margins(MarginsType::CUSTOM_MARGINS, 1, 2, 3, 4));
dpi.AddOption(Dpi(150, 250));
dpi.AddDefaultOption(Dpi(600, 1600), true);
- fit_to_page.AddDefaultOption(NO_FITTING, true);
- fit_to_page.AddOption(FIT_TO_PAGE);
- fit_to_page.AddOption(GROW_TO_PAGE);
- fit_to_page.AddOption(SHRINK_TO_PAGE);
- fit_to_page.AddOption(FILL_PAGE);
+ fit_to_page.AddDefaultOption(FitToPageType::NO_FITTING, true);
+ fit_to_page.AddOption(FitToPageType::FIT_TO_PAGE);
+ fit_to_page.AddOption(FitToPageType::GROW_TO_PAGE);
+ fit_to_page.AddOption(FitToPageType::SHRINK_TO_PAGE);
+ fit_to_page.AddOption(FitToPageType::FILL_PAGE);
- media.AddDefaultOption(Media(NA_LETTER, 2222, 3333), true);
- media.AddOption(Media(ISO_A6, 4444, 5555));
- media.AddOption(Media(JPN_YOU4, 6666, 7777));
+ media.AddDefaultOption(Media(MediaType::NA_LETTER, 2222, 3333), true);
+ media.AddOption(Media(MediaType::ISO_A6, 4444, 5555));
+ media.AddOption(Media(MediaType::JPN_YOU4, 6666, 7777));
media.AddOption(Media("Feed", "FEED", 1111, 0));
collate.set_default_value(false);
@@ -473,8 +766,10 @@ TEST(PrinterDescriptionTest, CddGetDocumentTypeSupported) {
PwgRasterConfigCapability pwg_raster;
EXPECT_TRUE(pwg_raster.LoadFrom(description));
ASSERT_EQ(1U, pwg_raster.value().document_types_supported.size());
- EXPECT_EQ(SRGB_8, pwg_raster.value().document_types_supported[0]);
- EXPECT_EQ(ROTATED, pwg_raster.value().document_sheet_back);
+ EXPECT_EQ(PwgDocumentTypeSupported::SRGB_8,
+ pwg_raster.value().document_types_supported[0]);
+ EXPECT_EQ(DocumentSheetBack::ROTATED,
+ pwg_raster.value().document_sheet_back);
EXPECT_FALSE(pwg_raster.value().reverse_order_streaming);
}
{
@@ -485,8 +780,10 @@ TEST(PrinterDescriptionTest, CddGetDocumentTypeSupported) {
PwgRasterConfigCapability pwg_raster;
EXPECT_TRUE(pwg_raster.LoadFrom(description));
ASSERT_EQ(1U, pwg_raster.value().document_types_supported.size());
- EXPECT_EQ(SGRAY_8, pwg_raster.value().document_types_supported[0]);
- EXPECT_EQ(ROTATED, pwg_raster.value().document_sheet_back);
+ EXPECT_EQ(PwgDocumentTypeSupported::SGRAY_8,
+ pwg_raster.value().document_types_supported[0]);
+ EXPECT_EQ(DocumentSheetBack::ROTATED,
+ pwg_raster.value().document_sheet_back);
EXPECT_FALSE(pwg_raster.value().reverse_order_streaming);
}
{
@@ -497,9 +794,12 @@ TEST(PrinterDescriptionTest, CddGetDocumentTypeSupported) {
PwgRasterConfigCapability pwg_raster;
EXPECT_TRUE(pwg_raster.LoadFrom(description));
ASSERT_EQ(2U, pwg_raster.value().document_types_supported.size());
- EXPECT_EQ(SRGB_8, pwg_raster.value().document_types_supported[0]);
- EXPECT_EQ(SGRAY_8, pwg_raster.value().document_types_supported[1]);
- EXPECT_EQ(ROTATED, pwg_raster.value().document_sheet_back);
+ EXPECT_EQ(PwgDocumentTypeSupported::SRGB_8,
+ pwg_raster.value().document_types_supported[0]);
+ EXPECT_EQ(PwgDocumentTypeSupported::SGRAY_8,
+ pwg_raster.value().document_types_supported[1]);
+ EXPECT_EQ(DocumentSheetBack::ROTATED,
+ pwg_raster.value().document_sheet_back);
EXPECT_FALSE(pwg_raster.value().reverse_order_streaming);
}
{
@@ -510,8 +810,10 @@ TEST(PrinterDescriptionTest, CddGetDocumentTypeSupported) {
PwgRasterConfigCapability pwg_raster;
EXPECT_TRUE(pwg_raster.LoadFrom(description));
ASSERT_EQ(1U, pwg_raster.value().document_types_supported.size());
- EXPECT_EQ(SRGB_8, pwg_raster.value().document_types_supported[0]);
- EXPECT_EQ(ROTATED, pwg_raster.value().document_sheet_back);
+ EXPECT_EQ(PwgDocumentTypeSupported::SRGB_8,
+ pwg_raster.value().document_types_supported[0]);
+ EXPECT_EQ(DocumentSheetBack::ROTATED,
+ pwg_raster.value().document_sheet_back);
EXPECT_FALSE(pwg_raster.value().reverse_order_streaming);
}
{
@@ -522,7 +824,8 @@ TEST(PrinterDescriptionTest, CddGetDocumentTypeSupported) {
PwgRasterConfigCapability pwg_raster;
EXPECT_TRUE(pwg_raster.LoadFrom(description));
EXPECT_EQ(0U, pwg_raster.value().document_types_supported.size());
- EXPECT_EQ(ROTATED, pwg_raster.value().document_sheet_back);
+ EXPECT_EQ(DocumentSheetBack::ROTATED,
+ pwg_raster.value().document_sheet_back);
EXPECT_FALSE(pwg_raster.value().reverse_order_streaming);
}
{
@@ -548,8 +851,9 @@ TEST(PrinterDescriptionTest, CddSetDocumentTypeSupported) {
CloudDeviceDescription description;
PwgRasterConfig custom_raster;
- custom_raster.document_types_supported.push_back(SRGB_8);
- custom_raster.document_sheet_back = ROTATED;
+ custom_raster.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SRGB_8);
+ custom_raster.document_sheet_back = DocumentSheetBack::ROTATED;
PwgRasterConfigCapability pwg_raster;
pwg_raster.set_value(custom_raster);
@@ -562,8 +866,9 @@ TEST(PrinterDescriptionTest, CddSetDocumentTypeSupported) {
CloudDeviceDescription description;
PwgRasterConfig custom_raster;
- custom_raster.document_types_supported.push_back(SGRAY_8);
- custom_raster.document_sheet_back = ROTATED;
+ custom_raster.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SGRAY_8);
+ custom_raster.document_sheet_back = DocumentSheetBack::ROTATED;
PwgRasterConfigCapability pwg_raster;
pwg_raster.set_value(custom_raster);
@@ -576,9 +881,11 @@ TEST(PrinterDescriptionTest, CddSetDocumentTypeSupported) {
CloudDeviceDescription description;
PwgRasterConfig custom_raster;
- custom_raster.document_types_supported.push_back(SRGB_8);
- custom_raster.document_types_supported.push_back(SGRAY_8);
- custom_raster.document_sheet_back = ROTATED;
+ custom_raster.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SRGB_8);
+ custom_raster.document_types_supported.push_back(
+ PwgDocumentTypeSupported::SGRAY_8);
+ custom_raster.document_sheet_back = DocumentSheetBack::ROTATED;
PwgRasterConfigCapability pwg_raster;
pwg_raster.set_value(custom_raster);
@@ -591,7 +898,7 @@ TEST(PrinterDescriptionTest, CddSetDocumentTypeSupported) {
CloudDeviceDescription description;
PwgRasterConfig custom_raster;
- custom_raster.document_sheet_back = ROTATED;
+ custom_raster.document_sheet_back = DocumentSheetBack::ROTATED;
PwgRasterConfigCapability pwg_raster;
pwg_raster.set_value(custom_raster);
@@ -602,6 +909,220 @@ TEST(PrinterDescriptionTest, CddSetDocumentTypeSupported) {
}
}
+TEST(PrinterDescriptionTest, CddGetRangeVendorCapability) {
+ for (const auto& capacity : kTestRangeCapabilities) {
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(NormalizeJson(capacity.json_name));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ RangeVendorCapability range_capability;
+ EXPECT_TRUE(range_capability.LoadFrom(description));
+ EXPECT_EQ(capacity.range_capability, range_capability);
+ }
+
+ const char* const kInvalidJsonNames[] = {
+ kMissingMinValueRangeVendorCapabilityJson,
+ kInvalidTypeRangeVendorCapabilityJson,
+ kInvalidBoundariesRangeVendorCapabilityJson,
+ kInvalidDefaultValueRangeVendorCapabilityJson};
+ for (const char* invalid_json_name : kInvalidJsonNames) {
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(NormalizeJson(invalid_json_name));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ RangeVendorCapability range_capability;
+ EXPECT_FALSE(range_capability.LoadFrom(description));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddSetRangeVendorCapability) {
+ for (const auto& capacity : kTestRangeCapabilities) {
+ base::Value range_capability_value(base::Value::Type::DICTIONARY);
+ capacity.range_capability.SaveTo(&range_capability_value);
+ std::string range_capability_str;
+ EXPECT_TRUE(base::JSONWriter::WriteWithOptions(
+ range_capability_value, base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &range_capability_str));
+ EXPECT_EQ(NormalizeJson(capacity.json_name),
+ NormalizeJson(range_capability_str));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddGetSelectVendorCapability) {
+ {
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(
+ NormalizeJson(kSelectVendorCapabilityJson));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ SelectVendorCapability select_capability;
+ EXPECT_TRUE(select_capability.LoadFrom(description));
+ EXPECT_EQ(2u, select_capability.size());
+ EXPECT_TRUE(select_capability.Contains(
+ SelectVendorCapabilityOption("value_1", "name_1")));
+ EXPECT_TRUE(select_capability.Contains(
+ SelectVendorCapabilityOption("value_2", "name_2")));
+ EXPECT_EQ(SelectVendorCapabilityOption("value_2", "name_2"),
+ select_capability.GetDefault());
+ }
+
+ const char* const kInvalidJsonNames[] = {
+ kNotListSelectVendorCapabilityJson,
+ kMissingValueSelectVendorCapabilityJson,
+ kMissingDisplayNameSelectVendorCapabilityJson,
+ kNoDefaultSelectVendorCapabilityJson,
+ kSeveralDefaultsSelectVendorCapabilityJson};
+ for (const char* invalid_json_name : kInvalidJsonNames) {
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(NormalizeJson(invalid_json_name));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ SelectVendorCapability select_capability;
+ EXPECT_FALSE(select_capability.LoadFrom(description));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddSetSelectVendorCapability) {
+ SelectVendorCapability select_capability;
+ select_capability.AddOption(
+ SelectVendorCapabilityOption("value_1", "name_1"));
+ select_capability.AddDefaultOption(
+ SelectVendorCapabilityOption("value_2", "name_2"), true);
+ base::Value select_capability_value(base::Value::Type::DICTIONARY);
+ select_capability.SaveTo(&select_capability_value);
+ std::string select_capability_str;
+ EXPECT_TRUE(base::JSONWriter::WriteWithOptions(
+ select_capability_value, base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &select_capability_str));
+ EXPECT_EQ(NormalizeJson(kSelectVendorCapabilityJson),
+ NormalizeJson(select_capability_str));
+}
+
+TEST(PrinterDescriptionTest, CddGetTypedValueVendorCapability) {
+ for (const auto& capacity : kTestTypedValueCapabilities) {
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(NormalizeJson(capacity.json_name));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ TypedValueVendorCapability typed_value_capability;
+ EXPECT_TRUE(typed_value_capability.LoadFrom(description));
+ EXPECT_EQ(capacity.typed_value_capability, typed_value_capability);
+ }
+
+ const char* const kInvalidJsonNames[] = {
+ kMissingValueTypeTypedValueVendorCapabilityJson,
+ kInvalidBooleanTypedValueVendorCapabilityJson,
+ kInvalidFloatTypedValueVendorCapabilityJson,
+ kInvalidIntegerTypedValueVendorCapabilityJson};
+ for (const char* invalid_json_name : kInvalidJsonNames) {
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(NormalizeJson(invalid_json_name));
+ ASSERT_TRUE(value);
+ base::Value description = base::Value::FromUniquePtrValue(std::move(value));
+ TypedValueVendorCapability typed_value_capability;
+ EXPECT_FALSE(typed_value_capability.LoadFrom(description));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddSetTypedValueVendorCapability) {
+ for (const auto& capacity : kTestTypedValueCapabilities) {
+ base::Value typed_value_capability_value(base::Value::Type::DICTIONARY);
+ capacity.typed_value_capability.SaveTo(&typed_value_capability_value);
+ std::string typed_value_capability_str;
+ EXPECT_TRUE(base::JSONWriter::WriteWithOptions(
+ typed_value_capability_value, base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &typed_value_capability_str));
+ EXPECT_EQ(NormalizeJson(capacity.json_name),
+ NormalizeJson(typed_value_capability_str));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddGetVendorCapability) {
+ {
+ CloudDeviceDescription description;
+ ASSERT_TRUE(
+ description.InitFromString(NormalizeJson(kVendorCapabilityOnlyCdd)));
+
+ VendorCapabilities vendor_capabilities;
+ EXPECT_TRUE(vendor_capabilities.LoadFrom(description));
+ EXPECT_EQ(3u, vendor_capabilities.size());
+ EXPECT_TRUE(vendor_capabilities.Contains(VendorCapability(
+ "id_1", "name_1",
+ RangeVendorCapability(RangeVendorCapability::ValueType::INTEGER, "1",
+ "10"))));
+ SelectVendorCapability select_capability;
+ select_capability.AddDefaultOption(
+ SelectVendorCapabilityOption("value", "name"), true);
+ EXPECT_TRUE(vendor_capabilities.Contains(
+ VendorCapability("id_2", "name_2", std::move(select_capability))));
+ EXPECT_TRUE(vendor_capabilities.Contains(VendorCapability(
+ "id_3", "name_3",
+ TypedValueVendorCapability(
+ TypedValueVendorCapability::ValueType::INTEGER, "1"))));
+ }
+
+ const char* const kInvalidJsonNames[] = {
+ kMissingIdVendorCapabilityCdd, kInvalidInnerCapabilityVendorCapabilityCdd,
+ kNoInnerCapabilityVendorCapabilityCdd,
+ kSeveralInnerCapabilitiesVendorCapabilityCdd};
+ for (const char* invalid_json_name : kInvalidJsonNames) {
+ CloudDeviceDescription description;
+ ASSERT_TRUE(description.InitFromString(NormalizeJson(invalid_json_name)));
+ VendorCapabilities vendor_capabilities;
+ EXPECT_FALSE(vendor_capabilities.LoadFrom(description));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddSetVendorCapability) {
+ CloudDeviceDescription description;
+
+ VendorCapabilities vendor_capabilities;
+ vendor_capabilities.AddOption(VendorCapability(
+ "id_1", "name_1",
+ RangeVendorCapability(RangeVendorCapability::ValueType::INTEGER, "1",
+ "10")));
+ SelectVendorCapability select_capability;
+ select_capability.AddDefaultOption(
+ SelectVendorCapabilityOption("value", "name"), true);
+ vendor_capabilities.AddOption(
+ VendorCapability("id_2", "name_2", std::move(select_capability)));
+ vendor_capabilities.AddOption(VendorCapability(
+ "id_3", "name_3",
+ TypedValueVendorCapability(TypedValueVendorCapability::ValueType::INTEGER,
+ "1")));
+
+ vendor_capabilities.SaveTo(&description);
+ EXPECT_EQ(NormalizeJson(kVendorCapabilityOnlyCdd),
+ NormalizeJson(description.ToString()));
+}
+
+#if defined(OS_CHROMEOS)
+TEST(PrinterDescriptionTest, CddGetPin) {
+ {
+ CloudDeviceDescription description;
+ ASSERT_TRUE(description.InitFromString(NormalizeJson(kPinOnlyCdd)));
+
+ PinCapability pin_capability;
+ EXPECT_TRUE(pin_capability.LoadFrom(description));
+ EXPECT_TRUE(pin_capability.value());
+ }
+ {
+ CloudDeviceDescription description;
+ ASSERT_TRUE(description.InitFromString(NormalizeJson(kDefaultCdd)));
+ PinCapability pin_capability;
+ EXPECT_FALSE(pin_capability.LoadFrom(description));
+ }
+}
+
+TEST(PrinterDescriptionTest, CddSetPin) {
+ CloudDeviceDescription description;
+
+ PinCapability pin_capability;
+ pin_capability.set_value(true);
+ pin_capability.SaveTo(&description);
+ EXPECT_EQ(NormalizeJson(kPinOnlyCdd), NormalizeJson(description.ToString()));
+}
+#endif // defined(OS_CHROMEOS)
+
TEST(PrinterDescriptionTest, CddGetAll) {
CloudDeviceDescription description;
ASSERT_TRUE(description.InitFromString(NormalizeJson(kCdd)));
@@ -639,49 +1160,52 @@ TEST(PrinterDescriptionTest, CddGetAll) {
EXPECT_TRUE(content_types.Contains("image/jpeg"));
EXPECT_EQ(0U, pwg_raster_config.value().document_types_supported.size());
- EXPECT_EQ(MANUAL_TUMBLE, pwg_raster_config.value().document_sheet_back);
+ EXPECT_EQ(DocumentSheetBack::MANUAL_TUMBLE,
+ pwg_raster_config.value().document_sheet_back);
EXPECT_TRUE(pwg_raster_config.value().reverse_order_streaming);
EXPECT_FALSE(pwg_raster_config.value().rotate_all_pages);
- EXPECT_TRUE(color.Contains(Color(STANDARD_COLOR)));
- EXPECT_TRUE(color.Contains(Color(STANDARD_MONOCHROME)));
- Color custom(CUSTOM_MONOCHROME);
+ EXPECT_TRUE(color.Contains(Color(ColorType::STANDARD_COLOR)));
+ EXPECT_TRUE(color.Contains(Color(ColorType::STANDARD_MONOCHROME)));
+ Color custom(ColorType::CUSTOM_MONOCHROME);
custom.vendor_id = "123";
custom.custom_display_name = "monochrome";
EXPECT_TRUE(color.Contains(custom));
- EXPECT_EQ(Color(STANDARD_COLOR), color.GetDefault());
+ EXPECT_EQ(Color(ColorType::STANDARD_COLOR), color.GetDefault());
- EXPECT_TRUE(duplex.Contains(LONG_EDGE));
- EXPECT_TRUE(duplex.Contains(SHORT_EDGE));
- EXPECT_TRUE(duplex.Contains(NO_DUPLEX));
- EXPECT_EQ(LONG_EDGE, duplex.GetDefault());
+ EXPECT_TRUE(duplex.Contains(DuplexType::LONG_EDGE));
+ EXPECT_TRUE(duplex.Contains(DuplexType::SHORT_EDGE));
+ EXPECT_TRUE(duplex.Contains(DuplexType::NO_DUPLEX));
+ EXPECT_EQ(DuplexType::LONG_EDGE, duplex.GetDefault());
- EXPECT_TRUE(orientation.Contains(PORTRAIT));
- EXPECT_TRUE(orientation.Contains(LANDSCAPE));
- EXPECT_TRUE(orientation.Contains(AUTO_ORIENTATION));
- EXPECT_EQ(AUTO_ORIENTATION, orientation.GetDefault());
+ EXPECT_TRUE(orientation.Contains(OrientationType::PORTRAIT));
+ EXPECT_TRUE(orientation.Contains(OrientationType::LANDSCAPE));
+ EXPECT_TRUE(orientation.Contains(OrientationType::AUTO_ORIENTATION));
+ EXPECT_EQ(OrientationType::AUTO_ORIENTATION, orientation.GetDefault());
- EXPECT_TRUE(margins.Contains(Margins(NO_MARGINS, 0, 0, 0, 0)));
- EXPECT_TRUE(margins.Contains(Margins(STANDARD_MARGINS, 100, 200, 300, 400)));
- EXPECT_TRUE(margins.Contains(Margins(CUSTOM_MARGINS, 1, 2, 3, 4)));
- EXPECT_EQ(Margins(NO_MARGINS, 0, 0, 0, 0), margins.GetDefault());
+ EXPECT_TRUE(margins.Contains(Margins(MarginsType::NO_MARGINS, 0, 0, 0, 0)));
+ EXPECT_TRUE(margins.Contains(
+ Margins(MarginsType::STANDARD_MARGINS, 100, 200, 300, 400)));
+ EXPECT_TRUE(
+ margins.Contains(Margins(MarginsType::CUSTOM_MARGINS, 1, 2, 3, 4)));
+ EXPECT_EQ(Margins(MarginsType::NO_MARGINS, 0, 0, 0, 0), margins.GetDefault());
EXPECT_TRUE(dpi.Contains(Dpi(150, 250)));
EXPECT_TRUE(dpi.Contains(Dpi(600, 1600)));
EXPECT_EQ(Dpi(600, 1600), dpi.GetDefault());
- EXPECT_TRUE(fit_to_page.Contains(NO_FITTING));
- EXPECT_TRUE(fit_to_page.Contains(FIT_TO_PAGE));
- EXPECT_TRUE(fit_to_page.Contains(GROW_TO_PAGE));
- EXPECT_TRUE(fit_to_page.Contains(SHRINK_TO_PAGE));
- EXPECT_TRUE(fit_to_page.Contains(FILL_PAGE));
- EXPECT_EQ(NO_FITTING, fit_to_page.GetDefault());
+ EXPECT_TRUE(fit_to_page.Contains(FitToPageType::NO_FITTING));
+ EXPECT_TRUE(fit_to_page.Contains(FitToPageType::FIT_TO_PAGE));
+ EXPECT_TRUE(fit_to_page.Contains(FitToPageType::GROW_TO_PAGE));
+ EXPECT_TRUE(fit_to_page.Contains(FitToPageType::SHRINK_TO_PAGE));
+ EXPECT_TRUE(fit_to_page.Contains(FitToPageType::FILL_PAGE));
+ EXPECT_EQ(FitToPageType::NO_FITTING, fit_to_page.GetDefault());
- EXPECT_TRUE(media.Contains(Media(NA_LETTER, 2222, 3333)));
- EXPECT_TRUE(media.Contains(Media(ISO_A6, 4444, 5555)));
- EXPECT_TRUE(media.Contains(Media(JPN_YOU4, 6666, 7777)));
+ EXPECT_TRUE(media.Contains(Media(MediaType::NA_LETTER, 2222, 3333)));
+ EXPECT_TRUE(media.Contains(Media(MediaType::ISO_A6, 4444, 5555)));
+ EXPECT_TRUE(media.Contains(Media(MediaType::JPN_YOU4, 6666, 7777)));
EXPECT_TRUE(media.Contains(Media("Feed", "FEED", 1111, 0)));
- EXPECT_EQ(Media(NA_LETTER, 2222, 3333), media.GetDefault());
+ EXPECT_EQ(Media(MediaType::NA_LETTER, 2222, 3333), media.GetDefault());
EXPECT_FALSE(collate.default_value());
EXPECT_TRUE(reverse.default_value());
@@ -743,22 +1267,22 @@ TEST(PrinterDescriptionTest, CjtSetAll) {
ReverseTicketItem reverse;
PwgRasterConfig custom_raster;
- custom_raster.document_sheet_back = MANUAL_TUMBLE;
+ custom_raster.document_sheet_back = DocumentSheetBack::MANUAL_TUMBLE;
custom_raster.reverse_order_streaming = true;
custom_raster.rotate_all_pages = false;
pwg_raster_config.set_value(custom_raster);
- color.set_value(Color(STANDARD_MONOCHROME));
- duplex.set_value(NO_DUPLEX);
- orientation.set_value(LANDSCAPE);
+ color.set_value(Color(ColorType::STANDARD_MONOCHROME));
+ duplex.set_value(DuplexType::NO_DUPLEX);
+ orientation.set_value(OrientationType::LANDSCAPE);
copies.set_value(123);
- margins.set_value(Margins(CUSTOM_MARGINS, 7, 6, 3, 1));
+ margins.set_value(Margins(MarginsType::CUSTOM_MARGINS, 7, 6, 3, 1));
dpi.set_value(Dpi(562, 125));
- fit_to_page.set_value(SHRINK_TO_PAGE);
+ fit_to_page.set_value(FitToPageType::SHRINK_TO_PAGE);
PageRange page_ranges;
page_ranges.push_back(Interval(1, 99));
page_ranges.push_back(Interval(150));
page_range.set_value(page_ranges);
- media.set_value(Media(ISO_C7C6, 4261, 334));
+ media.set_value(Media(MediaType::ISO_C7C6, 4261, 334));
collate.set_value(false);
reverse.set_value(true);
@@ -809,21 +1333,22 @@ TEST(PrinterDescriptionTest, CjtGetAll) {
EXPECT_TRUE(reverse.LoadFrom(description));
EXPECT_TRUE(media.LoadFrom(description));
- EXPECT_EQ(MANUAL_TUMBLE, pwg_raster_config.value().document_sheet_back);
+ EXPECT_EQ(DocumentSheetBack::MANUAL_TUMBLE,
+ pwg_raster_config.value().document_sheet_back);
EXPECT_TRUE(pwg_raster_config.value().reverse_order_streaming);
EXPECT_FALSE(pwg_raster_config.value().rotate_all_pages);
- EXPECT_EQ(color.value(), Color(STANDARD_MONOCHROME));
- EXPECT_EQ(duplex.value(), NO_DUPLEX);
- EXPECT_EQ(orientation.value(), LANDSCAPE);
+ EXPECT_EQ(color.value(), Color(ColorType::STANDARD_MONOCHROME));
+ EXPECT_EQ(duplex.value(), DuplexType::NO_DUPLEX);
+ EXPECT_EQ(orientation.value(), OrientationType::LANDSCAPE);
EXPECT_EQ(copies.value(), 123);
- EXPECT_EQ(margins.value(), Margins(CUSTOM_MARGINS, 7, 6, 3, 1));
+ EXPECT_EQ(margins.value(), Margins(MarginsType::CUSTOM_MARGINS, 7, 6, 3, 1));
EXPECT_EQ(dpi.value(), Dpi(562, 125));
- EXPECT_EQ(fit_to_page.value(), SHRINK_TO_PAGE);
+ EXPECT_EQ(fit_to_page.value(), FitToPageType::SHRINK_TO_PAGE);
PageRange page_ranges;
page_ranges.push_back(Interval(1, 99));
page_ranges.push_back(Interval(150));
EXPECT_EQ(page_range.value(), page_ranges);
- EXPECT_EQ(media.value(), Media(ISO_C7C6, 4261, 334));
+ EXPECT_EQ(media.value(), Media(MediaType::ISO_C7C6, 4261, 334));
EXPECT_FALSE(collate.value());
EXPECT_TRUE(reverse.value());
diff --git a/chromium/components/component_updater/OWNERS b/chromium/components/component_updater/OWNERS
index 2780b5b1544..ab443251aa9 100644
--- a/chromium/components/component_updater/OWNERS
+++ b/chromium/components/component_updater/OWNERS
@@ -1,6 +1,3 @@
-cpu@chromium.org
-laforge@chromium.org
-mal@chromium.org
sorin@chromium.org
waffles@chromium.org
diff --git a/chromium/components/component_updater/README.md b/chromium/components/component_updater/README.md
index bf3fc317517..a72b22fb520 100644
--- a/chromium/components/component_updater/README.md
+++ b/chromium/components/component_updater/README.md
@@ -37,7 +37,7 @@ out into a dynamically-linked library or data file.
### Create a CRX Package Signing Key & Manifest (Non-Google)
All components are delivered as CRX files (signed ZIP archives). You need to
create a signing key. If you are a Googler, follow the instructions at
-http://go/newchromecomponents for maximum key security. Otherwise, you can
+http://go/newchromecomponent for maximum key security. Otherwise, you can
create an RSA key pair using `openssl` or a similar tool.
You will additionally need to create a manifest.json file. If nothing else, the
diff --git a/chromium/components/component_updater/component_installer_unittest.cc b/chromium/components/component_updater/component_installer_unittest.cc
index afebb3d4302..638591a27d6 100644
--- a/chromium/components/component_updater/component_installer_unittest.cc
+++ b/chromium/components/component_updater/component_installer_unittest.cc
@@ -9,6 +9,7 @@
#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"
diff --git a/chromium/components/component_updater/component_updater_service.cc b/chromium/components/component_updater/component_updater_service.cc
index 2c11f11967d..a98f1866f1f 100644
--- a/chromium/components/component_updater/component_updater_service.cc
+++ b/chromium/components/component_updater/component_updater_service.cc
@@ -11,6 +11,7 @@
#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"
diff --git a/chromium/components/component_updater/configurator_impl.cc b/chromium/components/component_updater/configurator_impl.cc
index 2a964f77fa9..86f70034f29 100644
--- a/chromium/components/component_updater/configurator_impl.cc
+++ b/chromium/components/component_updater/configurator_impl.cc
@@ -8,6 +8,7 @@
#include <algorithm>
+#include "base/callback.h"
#include "base/feature_list.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
diff --git a/chromium/components/component_updater/configurator_impl_unittest.cc b/chromium/components/component_updater/configurator_impl_unittest.cc
index fe773294957..e5b9f8dc145 100644
--- a/chromium/components/component_updater/configurator_impl_unittest.cc
+++ b/chromium/components/component_updater/configurator_impl_unittest.cc
@@ -105,7 +105,7 @@ TEST_F(ComponentUpdaterConfiguratorImplTest, InitialDelay) {
bool PingsEnabled() const override { return false; }
bool TestRequest() const override { return false; }
GURL UrlSourceOverride() const override { return GURL(); }
- int InitialDelay() const override { return initial_delay_; };
+ int InitialDelay() const override { return initial_delay_; }
void set_fast_update(bool fast_update) { fast_update_ = fast_update; }
void set_initial_delay(int initial_delay) {
@@ -152,7 +152,7 @@ TEST_F(ComponentUpdaterConfiguratorImplTest, TestRequest) {
bool PingsEnabled() const override { return false; }
bool TestRequest() const override { return test_request_; }
GURL UrlSourceOverride() const override { return GURL(); }
- int InitialDelay() const override { return 0; };
+ int InitialDelay() const override { return 0; }
void set_test_request(bool test_request) { test_request_ = test_request; }
diff --git a/chromium/components/component_updater/timer_update_scheduler.cc b/chromium/components/component_updater/timer_update_scheduler.cc
index 51708525631..9035af21113 100644
--- a/chromium/components/component_updater/timer_update_scheduler.cc
+++ b/chromium/components/component_updater/timer_update_scheduler.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "components/component_updater/timer_update_scheduler.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
namespace component_updater {
@@ -24,4 +26,4 @@ void TimerUpdateScheduler::Stop() {
timer_.Stop();
}
-} // namespace component_updater \ No newline at end of file
+} // namespace component_updater
diff --git a/chromium/components/components_locale_settings.grd b/chromium/components/components_locale_settings.grd
index a9ffdfb30fb..fa2ed5b2a30 100644
--- a/chromium/components/components_locale_settings.grd
+++ b/chromium/components/components_locale_settings.grd
@@ -13,8 +13,8 @@
<output filename="components_locale_settings_da.pak" type="data_package" lang="da" />
<output filename="components_locale_settings_de.pak" type="data_package" lang="de" />
<output filename="components_locale_settings_el.pak" type="data_package" lang="el" />
- <output filename="components_locale_settings_en-GB.pak" type="data_package" lang="en-GB" />
<output filename="components_locale_settings_en-US.pak" type="data_package" lang="en" />
+ <output filename="components_locale_settings_en-GB.pak" type="data_package" lang="en-GB" />
<output filename="components_locale_settings_es.pak" type="data_package" lang="es" />
<if expr="is_ios">
<!-- iOS uses es-MX for es-419 -->
@@ -79,6 +79,7 @@
<output filename="java/res/values-am/components_locale_settings.xml" lang="am" type="android" context="android_java" />
<output filename="java/res/values-ar/components_locale_settings.xml" lang="ar" type="android" context="android_java" />
<output filename="java/res/values-bg/components_locale_settings.xml" lang="bg" type="android" context="android_java" />
+ <output filename="java/res/values-bn/components_locale_settings.xml" lang="bn" type="android" context="android_java" />
<output filename="java/res/values-ca/components_locale_settings.xml" lang="ca" type="android" context="android_java" />
<output filename="java/res/values-cs/components_locale_settings.xml" lang="cs" type="android" context="android_java" />
<output filename="java/res/values-da/components_locale_settings.xml" lang="da" type="android" context="android_java" />
@@ -88,20 +89,26 @@
<output filename="java/res/values-en-rGB/components_locale_settings.xml" lang="en-GB" type="android" context="android_java" />
<output filename="java/res/values-es/components_locale_settings.xml" lang="es" type="android" context="android_java" />
<output filename="java/res/values-es-rUS/components_locale_settings.xml" lang="es-419" type="android" context="android_java" />
+ <output filename="java/res/values-et/components_locale_settings.xml" lang="et" type="android" context="android_java" />
<output filename="java/res/values-fa/components_locale_settings.xml" lang="fa" type="android" context="android_java" />
<output filename="java/res/values-fi/components_locale_settings.xml" lang="fi" type="android" context="android_java" />
<output filename="java/res/values-tl/components_locale_settings.xml" lang="fil" type="android" context="android_java" />
<output filename="java/res/values-fr/components_locale_settings.xml" lang="fr" type="android" context="android_java" />
+ <output filename="java/res/values-gu/components_locale_settings.xml" lang="gu" type="android" context="android_java" />
+ <output filename="java/res/values-iw/components_locale_settings.xml" lang="he" type="android" context="android_java" />
<output filename="java/res/values-hi/components_locale_settings.xml" lang="hi" type="android" context="android_java" />
<output filename="java/res/values-hr/components_locale_settings.xml" lang="hr" type="android" context="android_java" />
<output filename="java/res/values-hu/components_locale_settings.xml" lang="hu" type="android" context="android_java" />
<output filename="java/res/values-in/components_locale_settings.xml" lang="id" type="android" context="android_java" />
<output filename="java/res/values-it/components_locale_settings.xml" lang="it" type="android" context="android_java" />
- <output filename="java/res/values-iw/components_locale_settings.xml" lang="he" type="android" context="android_java" />
<output filename="java/res/values-ja/components_locale_settings.xml" lang="ja" type="android" context="android_java" />
+ <output filename="java/res/values-kn/components_locale_settings.xml" lang="kn" type="android" context="android_java" />
<output filename="java/res/values-ko/components_locale_settings.xml" lang="ko" type="android" context="android_java" />
<output filename="java/res/values-lt/components_locale_settings.xml" lang="lt" type="android" context="android_java" />
<output filename="java/res/values-lv/components_locale_settings.xml" lang="lv" type="android" context="android_java" />
+ <output filename="java/res/values-ml/components_locale_settings.xml" lang="ml" type="android" context="android_java" />
+ <output filename="java/res/values-mr/components_locale_settings.xml" lang="mr" type="android" context="android_java" />
+ <output filename="java/res/values-ms/components_locale_settings.xml" lang="ms" type="android" context="android_java" />
<output filename="java/res/values-nl/components_locale_settings.xml" lang="nl" type="android" context="android_java" />
<output filename="java/res/values-nb/components_locale_settings.xml" lang="no" type="android" context="android_java" />
<output filename="java/res/values-pl/components_locale_settings.xml" lang="pl" type="android" context="android_java" />
@@ -114,6 +121,8 @@
<output filename="java/res/values-sr/components_locale_settings.xml" lang="sr" type="android" context="android_java" />
<output filename="java/res/values-sv/components_locale_settings.xml" lang="sv" type="android" context="android_java" />
<output filename="java/res/values-sw/components_locale_settings.xml" lang="sw" type="android" context="android_java" />
+ <output filename="java/res/values-ta/components_locale_settings.xml" lang="ta" type="android" context="android_java" />
+ <output filename="java/res/values-te/components_locale_settings.xml" lang="te" type="android" context="android_java" />
<output filename="java/res/values-th/components_locale_settings.xml" lang="th" type="android" context="android_java" />
<output filename="java/res/values-tr/components_locale_settings.xml" lang="tr" type="android" context="android_java" />
<output filename="java/res/values-uk/components_locale_settings.xml" lang="uk" type="android" context="android_java" />
diff --git a/chromium/components/components_strings.grd b/chromium/components/components_strings.grd
index 045961be0b0..65e94536718 100644
--- a/chromium/components/components_strings.grd
+++ b/chromium/components/components_strings.grd
@@ -15,8 +15,8 @@
<output filename="components_strings_da.pak" type="data_package" lang="da" />
<output filename="components_strings_de.pak" type="data_package" lang="de" />
<output filename="components_strings_el.pak" type="data_package" lang="el" />
- <output filename="components_strings_en-GB.pak" type="data_package" lang="en-GB" />
<output filename="components_strings_en-US.pak" type="data_package" lang="en" />
+ <output filename="components_strings_en-GB.pak" type="data_package" lang="en-GB" />
<output filename="components_strings_es.pak" type="data_package" lang="es" />
<if expr="is_ios">
<!-- iOS uses es-MX for es-419 -->
@@ -81,6 +81,7 @@
<output filename="java/res/values-am/components_strings.xml" lang="am" type="android" context="android_java" />
<output filename="java/res/values-ar/components_strings.xml" lang="ar" type="android" context="android_java" />
<output filename="java/res/values-bg/components_strings.xml" lang="bg" type="android" context="android_java" />
+ <output filename="java/res/values-bn/components_strings.xml" lang="bn" type="android" context="android_java" />
<output filename="java/res/values-ca/components_strings.xml" lang="ca" type="android" context="android_java" />
<output filename="java/res/values-cs/components_strings.xml" lang="cs" type="android" context="android_java" />
<output filename="java/res/values-da/components_strings.xml" lang="da" type="android" context="android_java" />
@@ -90,20 +91,26 @@
<output filename="java/res/values-en-rGB/components_strings.xml" lang="en-GB" type="android" context="android_java" />
<output filename="java/res/values-es/components_strings.xml" lang="es" type="android" context="android_java" />
<output filename="java/res/values-es-rUS/components_strings.xml" lang="es-419" type="android" context="android_java" />
+ <output filename="java/res/values-et/components_strings.xml" lang="et" type="android" context="android_java" />
<output filename="java/res/values-fa/components_strings.xml" lang="fa" type="android" context="android_java" />
<output filename="java/res/values-fi/components_strings.xml" lang="fi" type="android" context="android_java" />
<output filename="java/res/values-tl/components_strings.xml" lang="fil" type="android" context="android_java" />
<output filename="java/res/values-fr/components_strings.xml" lang="fr" type="android" context="android_java" />
+ <output filename="java/res/values-gu/components_strings.xml" lang="gu" type="android" context="android_java" />
+ <output filename="java/res/values-iw/components_strings.xml" lang="he" type="android" context="android_java" />
<output filename="java/res/values-hi/components_strings.xml" lang="hi" type="android" context="android_java" />
<output filename="java/res/values-hr/components_strings.xml" lang="hr" type="android" context="android_java" />
<output filename="java/res/values-hu/components_strings.xml" lang="hu" type="android" context="android_java" />
<output filename="java/res/values-in/components_strings.xml" lang="id" type="android" context="android_java" />
<output filename="java/res/values-it/components_strings.xml" lang="it" type="android" context="android_java" />
- <output filename="java/res/values-iw/components_strings.xml" lang="he" type="android" context="android_java" />
<output filename="java/res/values-ja/components_strings.xml" lang="ja" type="android" context="android_java" />
+ <output filename="java/res/values-kn/components_strings.xml" lang="kn" type="android" context="android_java" />
<output filename="java/res/values-ko/components_strings.xml" lang="ko" type="android" context="android_java" />
<output filename="java/res/values-lt/components_strings.xml" lang="lt" type="android" context="android_java" />
<output filename="java/res/values-lv/components_strings.xml" lang="lv" type="android" context="android_java" />
+ <output filename="java/res/values-ml/components_strings.xml" lang="ml" type="android" context="android_java" />
+ <output filename="java/res/values-mr/components_strings.xml" lang="mr" type="android" context="android_java" />
+ <output filename="java/res/values-ms/components_strings.xml" lang="ms" type="android" context="android_java" />
<output filename="java/res/values-nl/components_strings.xml" lang="nl" type="android" context="android_java" />
<output filename="java/res/values-nb/components_strings.xml" lang="no" type="android" context="android_java" />
<output filename="java/res/values-pl/components_strings.xml" lang="pl" type="android" context="android_java" />
@@ -116,6 +123,8 @@
<output filename="java/res/values-sr/components_strings.xml" lang="sr" type="android" context="android_java" />
<output filename="java/res/values-sv/components_strings.xml" lang="sv" type="android" context="android_java" />
<output filename="java/res/values-sw/components_strings.xml" lang="sw" type="android" context="android_java" />
+ <output filename="java/res/values-ta/components_strings.xml" lang="ta" type="android" context="android_java" />
+ <output filename="java/res/values-te/components_strings.xml" lang="te" type="android" context="android_java" />
<output filename="java/res/values-th/components_strings.xml" lang="th" type="android" context="android_java" />
<output filename="java/res/values-tr/components_strings.xml" lang="tr" type="android" context="android_java" />
<output filename="java/res/values-uk/components_strings.xml" lang="uk" type="android" context="android_java" />
@@ -204,6 +213,7 @@
<part file="payments_strings.grdp" />
<part file="pdf_strings.grdp" />
<part file="policy_strings.grdp" />
+ <part file="print_media_strings.grdp" />
<part file="printing_component_strings.grdp" />
<part file="reset_password_strings.grdp" />
<part file="safe_browsing_strings.grdp" />
diff --git a/chromium/components/consent_auditor/consent_auditor_impl.cc b/chromium/components/consent_auditor/consent_auditor_impl.cc
index 665cbad50de..860303dfe5e 100644
--- a/chromium/components/consent_auditor/consent_auditor_impl.cc
+++ b/chromium/components/consent_auditor/consent_auditor_impl.cc
@@ -46,7 +46,7 @@ std::unique_ptr<sync_pb::UserConsentSpecifics> CreateUserConsentSpecifics(
ConsentAuditorImpl::ConsentAuditorImpl(
PrefService* pref_service,
- std::unique_ptr<syncer::ConsentSyncBridge> consent_sync_bridge,
+ std::unique_ptr<ConsentSyncBridge> consent_sync_bridge,
const std::string& app_version,
const std::string& app_locale,
base::Clock* clock)
diff --git a/chromium/components/consent_auditor/consent_auditor_impl.h b/chromium/components/consent_auditor/consent_auditor_impl.h
index 8a9be1e4ba8..e10671d7b9a 100644
--- a/chromium/components/consent_auditor/consent_auditor_impl.h
+++ b/chromium/components/consent_auditor/consent_auditor_impl.h
@@ -28,12 +28,11 @@ namespace consent_auditor {
class ConsentAuditorImpl : public ConsentAuditor {
public:
- ConsentAuditorImpl(
- PrefService* pref_service,
- std::unique_ptr<syncer::ConsentSyncBridge> consent_sync_bridge,
- const std::string& app_version,
- const std::string& app_locale,
- base::Clock* clock);
+ ConsentAuditorImpl(PrefService* pref_service,
+ std::unique_ptr<ConsentSyncBridge> consent_sync_bridge,
+ const std::string& app_version,
+ const std::string& app_locale,
+ base::Clock* clock);
~ConsentAuditorImpl() override;
// KeyedService (through ConsentAuditor) implementation.
@@ -79,7 +78,7 @@ class ConsentAuditorImpl : public ConsentAuditor {
ConsentStatus status);
PrefService* pref_service_;
- std::unique_ptr<syncer::ConsentSyncBridge> consent_sync_bridge_;
+ std::unique_ptr<ConsentSyncBridge> consent_sync_bridge_;
std::string app_version_;
std::string app_locale_;
base::Clock* clock_;
diff --git a/chromium/components/consent_auditor/consent_auditor_impl_unittest.cc b/chromium/components/consent_auditor/consent_auditor_impl_unittest.cc
index 5974822b28d..8a8cc9fe272 100644
--- a/chromium/components/consent_auditor/consent_auditor_impl_unittest.cc
+++ b/chromium/components/consent_auditor/consent_auditor_impl_unittest.cc
@@ -75,7 +75,7 @@ void LoadEntriesFromLocalConsentRecord(const base::Value* consents,
*locale = locale_entry->GetString();
}
-class FakeConsentSyncBridge : public syncer::ConsentSyncBridge {
+class FakeConsentSyncBridge : public ConsentSyncBridge {
public:
~FakeConsentSyncBridge() override = default;
@@ -135,7 +135,7 @@ class ConsentAuditorImplTest : public testing::Test {
void SetAppLocale(const std::string& new_app_locale) {
app_locale_ = new_app_locale;
}
- void SetConsentSyncBridge(std::unique_ptr<syncer::ConsentSyncBridge> bridge) {
+ void SetConsentSyncBridge(std::unique_ptr<ConsentSyncBridge> bridge) {
consent_sync_bridge_ = std::move(bridge);
}
void SetClock(base::Clock* clock) { clock_ = clock; }
@@ -150,7 +150,7 @@ class ConsentAuditorImplTest : public testing::Test {
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
std::string app_version_;
std::string app_locale_;
- std::unique_ptr<syncer::ConsentSyncBridge> consent_sync_bridge_;
+ std::unique_ptr<ConsentSyncBridge> consent_sync_bridge_;
};
TEST_F(ConsentAuditorImplTest, LocalConsentPrefRepresentation) {
diff --git a/chromium/components/consent_auditor/consent_sync_bridge.h b/chromium/components/consent_auditor/consent_sync_bridge.h
index b14012d8e95..bc3eb8f6875 100644
--- a/chromium/components/consent_auditor/consent_sync_bridge.h
+++ b/chromium/components/consent_auditor/consent_sync_bridge.h
@@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "components/sync/model/model_type_controller_delegate.h"
-namespace syncer {
+namespace consent_auditor {
class ConsentSyncBridge {
public:
@@ -23,8 +23,11 @@ class ConsentSyncBridge {
// Returns the delegate for the controller, i.e. sync integration point.
virtual base::WeakPtr<syncer::ModelTypeControllerDelegate>
GetControllerDelegate() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConsentSyncBridge);
};
-} // namespace syncer
+} // namespace consent_auditor
#endif // COMPONENTS_CONSENT_AUDITOR_CONSENT_SYNC_BRIDGE_H_
diff --git a/chromium/components/consent_auditor/consent_sync_bridge_impl.cc b/chromium/components/consent_auditor/consent_sync_bridge_impl.cc
index cb4ee3b032b..4338d25fb0f 100644
--- a/chromium/components/consent_auditor/consent_sync_bridge_impl.cc
+++ b/chromium/components/consent_auditor/consent_sync_bridge_impl.cc
@@ -22,9 +22,20 @@
#include "components/sync/model/mutable_data_batch.h"
#include "components/sync/protocol/sync.pb.h"
-namespace syncer {
+namespace consent_auditor {
using sync_pb::UserConsentSpecifics;
+using syncer::EntityChange;
+using syncer::EntityChangeList;
+using syncer::EntityData;
+using syncer::MetadataBatch;
+using syncer::MetadataChangeList;
+using syncer::ModelError;
+using syncer::ModelTypeChangeProcessor;
+using syncer::ModelTypeStore;
+using syncer::ModelTypeSyncBridge;
+using syncer::MutableDataBatch;
+using syncer::OnceModelTypeStoreFactory;
using IdList = ModelTypeStore::IdList;
using Record = ModelTypeStore::Record;
using RecordList = ModelTypeStore::RecordList;
@@ -46,7 +57,7 @@ std::unique_ptr<EntityData> MoveToEntityData(
std::unique_ptr<UserConsentSpecifics> specifics) {
auto entity_data = std::make_unique<EntityData>();
entity_data->non_unique_name =
- base::Int64ToString(specifics->client_consent_time_usec());
+ base::NumberToString(specifics->client_consent_time_usec());
entity_data->specifics.set_allocated_user_consent(specifics.release());
return entity_data;
}
@@ -59,8 +70,9 @@ ConsentSyncBridgeImpl::ConsentSyncBridgeImpl(
: ModelTypeSyncBridge(std::move(change_processor)),
weak_ptr_factory_(this) {
std::move(store_factory)
- .Run(USER_CONSENTS, base::BindOnce(&ConsentSyncBridgeImpl::OnStoreCreated,
- weak_ptr_factory_.GetWeakPtr()));
+ .Run(syncer::USER_CONSENTS,
+ base::BindOnce(&ConsentSyncBridgeImpl::OnStoreCreated,
+ weak_ptr_factory_.GetWeakPtr()));
}
ConsentSyncBridgeImpl::~ConsentSyncBridgeImpl() {
@@ -123,8 +135,7 @@ std::string ConsentSyncBridgeImpl::GetStorageKey(
return GetStorageKeyFromSpecifics(entity_data.specifics.user_consent());
}
-ModelTypeSyncBridge::StopSyncResponse
-ConsentSyncBridgeImpl::ApplyStopSyncChanges(
+void ConsentSyncBridgeImpl::ApplyStopSyncChanges(
std::unique_ptr<MetadataChangeList> delete_metadata_change_list) {
// Sync can only be stopped after initialization.
DCHECK(deferred_consents_while_initializing_.empty());
@@ -143,8 +154,6 @@ ConsentSyncBridgeImpl::ApplyStopSyncChanges(
base::BindOnce(&ConsentSyncBridgeImpl::OnCommit,
weak_ptr_factory_.GetWeakPtr()));
}
-
- return StopSyncResponse::kModelStillReadyToSync;
}
void ConsentSyncBridgeImpl::ReadAllDataAndResubmit() {
@@ -311,4 +320,4 @@ void ConsentSyncBridgeImpl::OnReadAllData(
std::move(callback).Run(std::move(batch));
}
-} // namespace syncer
+} // namespace consent_auditor
diff --git a/chromium/components/consent_auditor/consent_sync_bridge_impl.h b/chromium/components/consent_auditor/consent_sync_bridge_impl.h
index 972c04922ed..be0ace22e9c 100644
--- a/chromium/components/consent_auditor/consent_sync_bridge_impl.h
+++ b/chromium/components/consent_auditor/consent_sync_bridge_impl.h
@@ -19,30 +19,31 @@
#include "components/sync/model/model_type_store.h"
#include "components/sync/model/model_type_sync_bridge.h"
-namespace syncer {
+namespace consent_auditor {
class ConsentSyncBridgeImpl : public ConsentSyncBridge,
- public ModelTypeSyncBridge {
+ public syncer::ModelTypeSyncBridge {
public:
ConsentSyncBridgeImpl(
- OnceModelTypeStoreFactory store_factory,
- std::unique_ptr<ModelTypeChangeProcessor> change_processor);
+ syncer::OnceModelTypeStoreFactory store_factory,
+ std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor);
~ConsentSyncBridgeImpl() override;
// ModelTypeSyncBridge implementation.
- std::unique_ptr<MetadataChangeList> CreateMetadataChangeList() override;
- base::Optional<ModelError> MergeSyncData(
- std::unique_ptr<MetadataChangeList> metadata_change_list,
- EntityChangeList entity_data) override;
- base::Optional<ModelError> ApplySyncChanges(
- std::unique_ptr<MetadataChangeList> metadata_change_list,
- EntityChangeList entity_changes) override;
+ std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
+ override;
+ base::Optional<syncer::ModelError> MergeSyncData(
+ std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
+ syncer::EntityChangeList entity_data) override;
+ base::Optional<syncer::ModelError> ApplySyncChanges(
+ std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
+ syncer::EntityChangeList entity_changes) override;
void GetData(StorageKeyList storage_keys, DataCallback callback) override;
void GetAllDataForDebugging(DataCallback callback) override;
- std::string GetClientTag(const EntityData& entity_data) override;
- std::string GetStorageKey(const EntityData& entity_data) override;
- StopSyncResponse ApplyStopSyncChanges(
- std::unique_ptr<MetadataChangeList> delete_metadata_change_list) override;
+ std::string GetClientTag(const syncer::EntityData& entity_data) override;
+ std::string GetStorageKey(const syncer::EntityData& entity_data) override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
// ConsentSyncBridge implementation.
void RecordConsent(
@@ -52,7 +53,7 @@ class ConsentSyncBridgeImpl : public ConsentSyncBridge,
static std::string GetStorageKeyFromSpecificsForTest(
const sync_pb::UserConsentSpecifics& specifics);
- std::unique_ptr<ModelTypeStore> StealStoreForTest();
+ std::unique_ptr<syncer::ModelTypeStore> StealStoreForTest();
private:
void RecordConsentImpl(
@@ -60,31 +61,33 @@ class ConsentSyncBridgeImpl : public ConsentSyncBridge,
// Record events in the deferred queue and clear the queue.
void ProcessQueuedEvents();
- void OnStoreCreated(const base::Optional<ModelError>& error,
- std::unique_ptr<ModelTypeStore> store);
- void OnReadAllMetadata(const base::Optional<ModelError>& error,
- std::unique_ptr<MetadataBatch> metadata_batch);
- void OnCommit(const base::Optional<ModelError>& error);
- void OnReadData(DataCallback callback,
- const base::Optional<ModelError>& error,
- std::unique_ptr<ModelTypeStore::RecordList> data_records,
- std::unique_ptr<ModelTypeStore::IdList> missing_id_list);
- void OnReadAllData(DataCallback callback,
- const base::Optional<ModelError>& error,
- std::unique_ptr<ModelTypeStore::RecordList> data_records);
+ void OnStoreCreated(const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore> store);
+ void OnReadAllMetadata(const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch);
+ void OnCommit(const base::Optional<syncer::ModelError>& error);
+ void OnReadData(
+ DataCallback callback,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records,
+ std::unique_ptr<syncer::ModelTypeStore::IdList> missing_id_list);
+ void OnReadAllData(
+ DataCallback callback,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records);
// Resubmit all the consents persisted in the store to sync consents, which
// were preserved when sync was disabled. This may resubmit entities that the
// processor already knows about (i.e. with metadata), but it is allowed.
void ReadAllDataAndResubmit();
void OnReadAllDataToResubmit(
- const base::Optional<ModelError>& error,
- std::unique_ptr<ModelTypeStore::RecordList> data_records);
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records);
// Persistent storage for in flight consents. Should remain quite small, as we
// delete upon commit confirmation. May contain consents without metadata
// (e.g. persisted when sync was disabled).
- std::unique_ptr<ModelTypeStore> store_;
+ std::unique_ptr<syncer::ModelTypeStore> store_;
// Used to store consents while the store or change processor are not
// ready.
@@ -96,6 +99,6 @@ class ConsentSyncBridgeImpl : public ConsentSyncBridge,
DISALLOW_COPY_AND_ASSIGN(ConsentSyncBridgeImpl);
};
-} // namespace syncer
+} // namespace consent_auditor
#endif // COMPONENTS_CONSENT_AUDITOR_CONSENT_SYNC_BRIDGE_IMPL_H_
diff --git a/chromium/components/consent_auditor/consent_sync_bridge_impl_unittest.cc b/chromium/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
index 8bee16056a1..1e258365ce3 100644
--- a/chromium/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
+++ b/chromium/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
@@ -19,10 +19,20 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace syncer {
+namespace consent_auditor {
namespace {
using sync_pb::UserConsentSpecifics;
+using syncer::DataBatch;
+using syncer::EntityChange;
+using syncer::EntityChangeList;
+using syncer::EntityData;
+using syncer::MetadataChangeList;
+using syncer::MockModelTypeChangeProcessor;
+using syncer::ModelTypeStore;
+using syncer::ModelTypeStoreTestUtil;
+using syncer::ModelTypeSyncBridge;
+using syncer::OnceModelTypeStoreFactory;
using testing::_;
using testing::ElementsAre;
using testing::Eq;
@@ -187,9 +197,7 @@ TEST_F(ConsentSyncBridgeImplTest, ShouldNotDeleteConsentsWhenSyncIsDisabled) {
std::make_unique<UserConsentSpecifics>(user_consent_specifics));
ASSERT_THAT(GetAllData(), SizeIs(1));
- EXPECT_THAT(
- bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()),
- Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync));
+ bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList());
// The bridge may asynchronously query the store to choose what to delete.
base::RunLoop().RunUntilIdle();
@@ -304,9 +312,7 @@ TEST_F(ConsentSyncBridgeImplTest,
// User disables sync, hovewer, the consent hasn't been submitted yet. It is
// preserved to be submitted when sync is re-enabled.
- EXPECT_THAT(
- bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()),
- Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync));
+ bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList());
// The bridge may asynchronously query the store to choose what to delete.
base::RunLoop().RunUntilIdle();
@@ -375,9 +381,7 @@ TEST_F(ConsentSyncBridgeImplTest,
std::make_unique<UserConsentSpecifics>(user_consent_specifics));
ASSERT_THAT(GetAllData(), SizeIs(1));
- EXPECT_THAT(
- bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()),
- Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync));
+ bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList());
// The bridge may asynchronously query the store to choose what to delete.
base::RunLoop().RunUntilIdle();
@@ -394,9 +398,7 @@ TEST_F(ConsentSyncBridgeImplTest,
EntityChangeList());
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(
- bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()),
- Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync));
+ bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList());
base::RunLoop().RunUntilIdle();
// This time their consent should be resubmitted, because it is for the same
@@ -412,4 +414,4 @@ TEST_F(ConsentSyncBridgeImplTest,
} // namespace
-} // namespace syncer
+} // namespace consent_auditor
diff --git a/chromium/components/content_capture/DEPS b/chromium/components/content_capture/DEPS
new file mode 100644
index 00000000000..08652470290
--- /dev/null
+++ b/chromium/components/content_capture/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+mojo",
+ "+ui",
+]
diff --git a/chromium/components/content_capture/OWNERS b/chromium/components/content_capture/OWNERS
new file mode 100644
index 00000000000..e63fd7ee0ae
--- /dev/null
+++ b/chromium/components/content_capture/OWNERS
@@ -0,0 +1,3 @@
+changwan@chromium.org
+michaelbai@chromium.org
+tobiasjs@chromium.org
diff --git a/chromium/components/content_capture/android/BUILD.gn b/chromium/components/content_capture/android/BUILD.gn
new file mode 100644
index 00000000000..7aeb2828c61
--- /dev/null
+++ b/chromium/components/content_capture/android/BUILD.gn
@@ -0,0 +1,40 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+source_set("android") {
+ sources = [
+ "content_capture_features_android.cc",
+ "content_capture_receiver_manager_android.cc",
+ "content_capture_receiver_manager_android.h",
+ ]
+ deps = [
+ ":jni_headers",
+ "//components/content_capture/browser",
+ ]
+}
+
+android_library("java") {
+ deps = [
+ "//base:base_java",
+ "//content/public/android:content_java",
+ ]
+ java_files = [
+ "java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureData.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
+ "java/src/org/chromium/components/content_capture/FrameSession.java",
+ ]
+}
+
+generate_jni("jni_headers") {
+ sources = [
+ "java/src/org/chromium/components/content_capture/ContentCaptureData.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java",
+ "java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java",
+ ]
+ jni_package = "content_capture"
+}
diff --git a/chromium/components/content_capture/android/DEPS b/chromium/components/content_capture/android/DEPS
new file mode 100644
index 00000000000..fb1ebefc6e4
--- /dev/null
+++ b/chromium/components/content_capture/android/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "+content/public/android",
+ "+content/public/browser",
+ "+jni",
+] \ No newline at end of file
diff --git a/chromium/components/content_capture/android/content_capture_features_android.cc b/chromium/components/content_capture/android/content_capture_features_android.cc
new file mode 100644
index 00000000000..49eb27676dd
--- /dev/null
+++ b/chromium/components/content_capture/android/content_capture_features_android.cc
@@ -0,0 +1,10 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/common/content_capture_features.h"
+#include "jni/ContentCaptureFeatures_jni.h"
+
+static jboolean JNI_ContentCaptureFeatures_IsEnabled(JNIEnv* env) {
+ return content_capture::features::IsContentCaptureEnabled();
+}
diff --git a/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc b/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc
new file mode 100644
index 00000000000..522bfdef526
--- /dev/null
+++ b/chromium/components/content_capture/android/content_capture_receiver_manager_android.cc
@@ -0,0 +1,124 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/android/content_capture_receiver_manager_android.h"
+
+#include <utility>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "content/public/browser/web_contents.h"
+#include "jni/ContentCaptureData_jni.h"
+#include "jni/ContentCaptureReceiverManager_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::JavaRef;
+using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaLongArray;
+
+void JNI_ContentCaptureReceiverManager_Init(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jcaller,
+ const base::android::JavaParamRef<jobject>& jweb_contents) {
+ auto* web_contents = content::WebContents::FromJavaWebContents(jweb_contents);
+ DCHECK(web_contents);
+ DCHECK(!content_capture::ContentCaptureReceiverManager::FromWebContents(
+ web_contents));
+ content_capture::ContentCaptureReceiverManagerAndroid::Create(web_contents,
+ jcaller);
+}
+
+namespace content_capture {
+
+namespace {
+
+ScopedJavaLocalRef<jobject> ToJavaObjectOfContentCaptureData(
+ JNIEnv* env,
+ const ContentCaptureData& data,
+ const JavaRef<jobject>& parent) {
+ ScopedJavaLocalRef<jstring> jvalue =
+ ConvertUTF16ToJavaString(env, data.value);
+ ScopedJavaLocalRef<jobject> jdata =
+ Java_ContentCaptureData_createContentCaptureData(
+ env, parent, data.id, jvalue, data.bounds.x(), data.bounds.y(),
+ data.bounds.width(), data.bounds.height());
+ if (jdata.is_null())
+ return jdata;
+ for (auto child : data.children) {
+ ToJavaObjectOfContentCaptureData(env, child, jdata);
+ }
+ return jdata;
+}
+
+ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfContentCaptureData(
+ JNIEnv* env,
+ const ContentCaptureSession& session) {
+ ScopedJavaLocalRef<jclass> object_clazz =
+ base::android::GetClass(env, "java/lang/Object");
+ jobjectArray joa =
+ env->NewObjectArray(session.size(), object_clazz.obj(), NULL);
+ jni_generator::CheckException(env);
+
+ for (size_t i = 0; i < session.size(); ++i) {
+ ScopedJavaLocalRef<jobject> item =
+ ToJavaObjectOfContentCaptureData(env, session[i], JavaRef<jobject>());
+ env->SetObjectArrayElement(joa, i, item.obj());
+ }
+ return ScopedJavaLocalRef<jobjectArray>(env, joa);
+}
+
+} // namespace
+
+ContentCaptureReceiverManagerAndroid::ContentCaptureReceiverManagerAndroid(
+ content::WebContents* web_contents,
+ const JavaRef<jobject>& jcaller)
+ : ContentCaptureReceiverManager(web_contents), java_ref_(jcaller) {}
+
+ContentCaptureReceiverManagerAndroid::~ContentCaptureReceiverManagerAndroid() =
+ default;
+
+void ContentCaptureReceiverManagerAndroid::Create(
+ content::WebContents* web_contents,
+ const JavaRef<jobject>& jcaller) {
+ if (FromWebContents(web_contents))
+ return;
+ new ContentCaptureReceiverManagerAndroid(web_contents, jcaller);
+}
+
+void ContentCaptureReceiverManagerAndroid::DidCaptureContent(
+ const ContentCaptureSession& parent_session,
+ const ContentCaptureData& data) {
+ JNIEnv* env = AttachCurrentThread();
+ DCHECK(java_ref_.obj());
+
+ ScopedJavaLocalRef<jobject> jdata =
+ ToJavaObjectOfContentCaptureData(env, data, JavaRef<jobject>());
+ if (jdata.is_null())
+ return;
+ Java_ContentCaptureReceiverManager_didCaptureContent(
+ env, java_ref_, ToJavaArrayOfContentCaptureData(env, parent_session),
+ jdata);
+}
+
+void ContentCaptureReceiverManagerAndroid::DidRemoveContent(
+ const ContentCaptureSession& session,
+ const std::vector<int64_t>& data) {
+ JNIEnv* env = AttachCurrentThread();
+ DCHECK(java_ref_.obj());
+ Java_ContentCaptureReceiverManager_didRemoveContent(
+ env, java_ref_, ToJavaArrayOfContentCaptureData(env, session),
+ ToJavaLongArray(env, data));
+}
+
+void ContentCaptureReceiverManagerAndroid::DidRemoveSession(
+ const ContentCaptureSession& session) {
+ JNIEnv* env = AttachCurrentThread();
+ DCHECK(java_ref_.obj());
+ Java_ContentCaptureReceiverManager_didRemoveSession(
+ env, java_ref_, ToJavaArrayOfContentCaptureData(env, session));
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/android/content_capture_receiver_manager_android.h b/chromium/components/content_capture/android/content_capture_receiver_manager_android.h
new file mode 100644
index 00000000000..46ec64df0b6
--- /dev/null
+++ b/chromium/components/content_capture/android/content_capture_receiver_manager_android.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
+#define COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
+
+#include <vector>
+
+#include "base/android/scoped_java_ref.h"
+#include "components/content_capture/browser/content_capture_receiver_manager.h"
+
+namespace content_capture {
+
+// The Android's implementation of ContentCaptureReceiverManager, it forwards
+// the received message to Java.
+class ContentCaptureReceiverManagerAndroid
+ : public ContentCaptureReceiverManager {
+ public:
+ ~ContentCaptureReceiverManagerAndroid() override;
+ static void Create(content::WebContents* web_contents,
+ const base::android::JavaRef<jobject>& jcaller);
+
+ void DidCaptureContent(const ContentCaptureSession& parent_session,
+ const ContentCaptureData& data) override;
+ void DidRemoveContent(const ContentCaptureSession& session,
+ const std::vector<int64_t>& data) override;
+ void DidRemoveSession(const ContentCaptureSession& session) override;
+
+ private:
+ ContentCaptureReceiverManagerAndroid(
+ content::WebContents* web_contents,
+ const base::android::JavaRef<jobject>& jcaller);
+
+ base::android::ScopedJavaGlobalRef<jobject> java_ref_;
+};
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_ANDROID_CONTENT_CAPTURE_RECEIVER_MANAGER_ANDROID_H_
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
new file mode 100644
index 00000000000..d9a458dbb12
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureConsumer.java
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.content_capture;
+
+/**
+ * This interface is for consumer to consume the captured content.
+ */
+public interface ContentCaptureConsumer {
+ /**
+ * Invoked when the content is captured from a frame.
+ * @param parentFrame is the parent of the frame from that the content captured.
+ * @param contentCaptureData is the captured content tree, its root is the frame.
+ */
+ void onContentCaptured(FrameSession parentFrame, ContentCaptureData contentCaptureData);
+
+ /**
+ * Invoked when the session is removed
+ * @param session is the removed frame.
+ */
+ void onSessionRemoved(FrameSession session);
+
+ /**
+ * Invoked when the content is removed from a frame
+ * @param session defines the frame from that the content removed
+ * @param removedIds are array of removed content id.
+ */
+ void onContentRemoved(FrameSession session, long[] removedIds);
+}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java
new file mode 100644
index 00000000000..94baa45f417
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureData.java
@@ -0,0 +1,83 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.content_capture;
+
+import android.graphics.Rect;
+
+import org.chromium.base.annotations.CalledByNative;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class is Java's representative of components/content_capture/common/content_capture_data.h
+ */
+public class ContentCaptureData {
+ private long mId;
+ private String mValue;
+ private Rect mBounds;
+ private ArrayList<ContentCaptureData> mChildren;
+
+ @CalledByNative
+ private static ContentCaptureData createContentCaptureData(
+ Object parent, long id, String value, int x, int y, int width, int height) {
+ ContentCaptureData data = new ContentCaptureData(id, value, x, y, width, height);
+ if (parent != null) {
+ ((ContentCaptureData) parent).addChild(data);
+ }
+ return data;
+ }
+
+ private ContentCaptureData(long id, String value, int x, int y, int width, int height) {
+ mId = id;
+ mValue = value;
+ mBounds = new Rect(x, y, x + width, y + height);
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ public Rect getBounds() {
+ return mBounds;
+ }
+
+ public List<ContentCaptureData> getChildren() {
+ return mChildren;
+ }
+
+ public boolean hasChildren() {
+ return mChildren != null && !mChildren.isEmpty();
+ }
+
+ public long getId() {
+ return mId;
+ }
+
+ private void addChild(ContentCaptureData data) {
+ if (mChildren == null) mChildren = new ArrayList<ContentCaptureData>();
+ mChildren.add(data);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("id:");
+ sb.append(mId);
+ sb.append(" value:");
+ sb.append(mValue);
+ sb.append(" bounds:");
+ sb.append(mBounds);
+ sb.append('\n');
+ if (hasChildren()) {
+ sb.append("children:");
+ sb.append(mChildren.size());
+ for (ContentCaptureData child : mChildren) {
+ sb.append(child.toString());
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java
new file mode 100644
index 00000000000..dc7ad565197
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureFeatures.java
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+package org.chromium.components.content_capture;
+
+/**
+ * The class to get if feature is enabled from native.
+ */
+public class ContentCaptureFeatures {
+ public static boolean isEnabled() {
+ return nativeIsEnabled();
+ }
+ private static native boolean nativeIsEnabled();
+}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
new file mode 100644
index 00000000000..c217f21c317
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/ContentCaptureReceiverManager.java
@@ -0,0 +1,78 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.content_capture;
+
+import android.view.ViewGroup;
+
+import org.chromium.base.CommandLine;
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.content_public.browser.WebContents;
+
+import java.util.Arrays;
+
+/**
+ * This class receives captured content from native and forwards to ContetnCaptureConsumer.
+ */
+public class ContentCaptureReceiverManager {
+ private static final String TAG = "ContentCapture";
+ private static final String FLAG = "dump-captured-content-to-logcat-for-testing";
+ private static Boolean sDump;
+
+ private ContentCaptureConsumer mContentCaptureConsumer;
+
+ public static ContentCaptureReceiverManager create(WebContents webContents) {
+ ContentCaptureReceiverManager manager = new ContentCaptureReceiverManager();
+ manager.nativeInit(webContents);
+ return manager;
+ }
+
+ public ContentCaptureReceiverManager() {
+ if (sDump == null) sDump = CommandLine.getInstance().hasSwitch(FLAG);
+ }
+
+ public void onContainerViewChanged(ViewGroup containerView) {
+ // Reset current consumer, the new consumer that associates with contanerView shall be set
+ // from setContentCaptureConsumer().
+ mContentCaptureConsumer = null;
+ }
+
+ public void setContentCaptureConsumer(ContentCaptureConsumer consumer) {
+ mContentCaptureConsumer = consumer;
+ }
+
+ @CalledByNative
+ private void didCaptureContent(Object[] session, ContentCaptureData data) {
+ if (mContentCaptureConsumer != null) {
+ mContentCaptureConsumer.onContentCaptured(toFrameSession(session), data);
+ }
+ if (sDump.booleanValue()) Log.i(TAG, "Captured Content: %s", data);
+ }
+
+ @CalledByNative
+ private void didRemoveContent(Object[] session, long[] data) {
+ FrameSession frameSession = toFrameSession(session);
+ if (mContentCaptureConsumer != null)
+ mContentCaptureConsumer.onContentRemoved(frameSession, data);
+ if (sDump.booleanValue()) {
+ Log.i(TAG, "Removed Content: %s", frameSession.get(0) + " " + Arrays.toString(data));
+ }
+ }
+
+ @CalledByNative
+ private void didRemoveSession(Object[] session) {
+ FrameSession frameSession = toFrameSession(session);
+ if (mContentCaptureConsumer != null) mContentCaptureConsumer.onSessionRemoved(frameSession);
+ if (sDump.booleanValue()) Log.i(TAG, "Removed Session: %s", frameSession.get(0));
+ }
+
+ private FrameSession toFrameSession(Object[] session) {
+ FrameSession frameSession = new FrameSession(session.length);
+ for (Object s : session) frameSession.add((ContentCaptureData) s);
+ return frameSession;
+ }
+
+ private native void nativeInit(WebContents webContents);
+}
diff --git a/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java
new file mode 100644
index 00000000000..b7597cdc0c5
--- /dev/null
+++ b/chromium/components/content_capture/android/java/src/org/chromium/components/content_capture/FrameSession.java
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.content_capture;
+
+import java.util.ArrayList;
+
+/**
+ * This class is used to specify the frame's session by a list of Frame ContentCaptureData from the
+ * interested frame to root.
+ */
+public class FrameSession extends ArrayList<ContentCaptureData> {
+ /**
+ * @param length is reserved frame list length.
+ */
+ public FrameSession(int length) {
+ super(length);
+ }
+}
diff --git a/chromium/components/content_capture/browser/BUILD.gn b/chromium/components/content_capture/browser/BUILD.gn
new file mode 100644
index 00000000000..455f1c41126
--- /dev/null
+++ b/chromium/components/content_capture/browser/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("browser") {
+ sources = [
+ "content_capture_receiver.cc",
+ "content_capture_receiver.h",
+ "content_capture_receiver_manager.cc",
+ "content_capture_receiver_manager.h",
+ ]
+
+ public_deps = [
+ "//base",
+ "//components/content_capture/common",
+ "//components/content_capture/common:mojo_interfaces",
+ "//content/public/browser",
+ "//ui/gfx/geometry",
+ ]
+
+ deps = []
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "content_capture_receiver_test.cc",
+ ]
+
+ deps = [
+ ":browser",
+ "//base",
+ "//base/test:test_support",
+ "//content/test:test_support",
+ "//mojo/public/cpp/bindings",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/content_capture/browser/DEPS b/chromium/components/content_capture/browser/DEPS
new file mode 100644
index 00000000000..d79a7d00f02
--- /dev/null
+++ b/chromium/components/content_capture/browser/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+content/public/browser",
+ "+content/public/test",
+]
diff --git a/chromium/components/content_capture/browser/content_capture_receiver.cc b/chromium/components/content_capture/browser/content_capture_receiver.cc
new file mode 100644
index 00000000000..394869bd014
--- /dev/null
+++ b/chromium/components/content_capture/browser/content_capture_receiver.cc
@@ -0,0 +1,59 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/browser/content_capture_receiver.h"
+
+#include <utility>
+
+#include "components/content_capture/browser/content_capture_receiver_manager.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+
+namespace content_capture {
+
+ContentCaptureReceiver::ContentCaptureReceiver(content::RenderFrameHost* rfh)
+ : bindings_(this), rfh_(rfh), id_(GetIdFrom(rfh)) {}
+
+ContentCaptureReceiver::~ContentCaptureReceiver() = default;
+
+int64_t ContentCaptureReceiver::GetIdFrom(content::RenderFrameHost* rfh) {
+ return static_cast<int64_t>(rfh->GetProcess()->GetID()) << 32 |
+ (rfh->GetRoutingID() & 0xFFFFFFFF);
+}
+
+void ContentCaptureReceiver::BindRequest(
+ mojom::ContentCaptureReceiverAssociatedRequest request) {
+ bindings_.Bind(std::move(request));
+}
+
+void ContentCaptureReceiver::DidCaptureContent(const ContentCaptureData& data,
+ bool first_data) {
+ auto* manager = ContentCaptureReceiverManager::FromWebContents(
+ content::WebContents::FromRenderFrameHost(rfh_));
+
+ if (first_data) {
+ // The session id of this frame isn't changed for new document navigation,
+ // so the previous session should be terminated.
+ if (frame_content_capture_data_.id != 0)
+ manager->DidRemoveSession(this);
+
+ frame_content_capture_data_.id = id_;
+ // Copies everything except id and children.
+ frame_content_capture_data_.value = data.value;
+ frame_content_capture_data_.bounds = data.bounds;
+ }
+ // We can't avoid copy the data here, because id need to be overriden.
+ ContentCaptureData content(data);
+ content.id = id_;
+ manager->DidCaptureContent(this, content);
+}
+
+void ContentCaptureReceiver::DidRemoveContent(
+ const std::vector<int64_t>& data) {
+ auto* manager = ContentCaptureReceiverManager::FromWebContents(
+ content::WebContents::FromRenderFrameHost(rfh_));
+ manager->DidRemoveContent(this, data);
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/browser/content_capture_receiver.h b/chromium/components/content_capture/browser/content_capture_receiver.h
new file mode 100644
index 00000000000..d745b072423
--- /dev/null
+++ b/chromium/components/content_capture/browser/content_capture_receiver.h
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_H_
+#define COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_H_
+
+#include <vector>
+
+#include "components/content_capture/common/content_capture.mojom.h"
+#include "components/content_capture/common/content_capture_data.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+
+namespace content {
+class RenderFrameHost;
+}
+
+namespace content_capture {
+
+// This class has an instance per RenderFrameHost, it receives messages from
+// renderer and forward them to ContentCaptureReceiverManager for further
+// processing.
+class ContentCaptureReceiver : public mojom::ContentCaptureReceiver {
+ public:
+ static int64_t GetIdFrom(content::RenderFrameHost* rfh);
+ explicit ContentCaptureReceiver(content::RenderFrameHost* rfh);
+ ~ContentCaptureReceiver() override;
+
+ // Binds to mojom.
+ void BindRequest(mojom::ContentCaptureReceiverAssociatedRequest request);
+
+ // mojom::ContentCaptureReceiver
+ void DidCaptureContent(const ContentCaptureData& data,
+ bool first_data) override;
+ void DidRemoveContent(const std::vector<int64_t>& data) override;
+
+ content::RenderFrameHost* rfh() const { return rfh_; }
+
+ // Return ContentCaptureData of the associated frame.
+ const ContentCaptureData& frame_content_capture_data() const {
+ return frame_content_capture_data_;
+ }
+
+ private:
+ mojo::AssociatedBinding<mojom::ContentCaptureReceiver> bindings_;
+ content::RenderFrameHost* rfh_;
+ ContentCaptureData frame_content_capture_data_;
+
+ // The content id of the associated frame, it is composed of RenderProcessHost
+ // unique ID and frame routing ID, and is unique in a WebContents.
+ // The ID is always generated in receiver because neither does the parent
+ // frame always have content, nor is its content always captured before child
+ // frame's; if the Id is generated in sender, the
+ // ContentCaptureReceiverManager can't get parent frame id in both cases.
+ int64_t id_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentCaptureReceiver);
+};
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_H_
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_manager.cc b/chromium/components/content_capture/browser/content_capture_receiver_manager.cc
new file mode 100644
index 00000000000..57e7702c39d
--- /dev/null
+++ b/chromium/components/content_capture/browser/content_capture_receiver_manager.cc
@@ -0,0 +1,134 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/browser/content_capture_receiver_manager.h"
+
+#include <utility>
+
+#include "components/content_capture/browser/content_capture_receiver.h"
+#include "content/public/browser/web_contents.h"
+
+namespace content_capture {
+namespace {
+
+const void* const kUserDataKey = &kUserDataKey;
+
+} // namespace
+
+ContentCaptureReceiverManager::ContentCaptureReceiverManager(
+ content::WebContents* web_contents)
+ : content::WebContentsObserver(web_contents) {
+ const std::vector<content::RenderFrameHost*> frames =
+ web_contents->GetAllFrames();
+ for (content::RenderFrameHost* frame : frames)
+ RenderFrameCreated(frame);
+
+ web_contents->SetUserData(
+ kUserDataKey, std::unique_ptr<ContentCaptureReceiverManager>(this));
+}
+
+ContentCaptureReceiverManager::~ContentCaptureReceiverManager() = default;
+
+ContentCaptureReceiverManager* ContentCaptureReceiverManager::FromWebContents(
+ content::WebContents* contents) {
+ return static_cast<ContentCaptureReceiverManager*>(
+ contents->GetUserData(kUserDataKey));
+}
+
+void ContentCaptureReceiverManager::BindContentCaptureReceiver(
+ mojom::ContentCaptureReceiverAssociatedRequest request,
+ content::RenderFrameHost* render_frame_host) {
+ content::WebContents* web_contents =
+ content::WebContents::FromRenderFrameHost(render_frame_host);
+
+ if (!web_contents)
+ return;
+
+ ContentCaptureReceiverManager* manager =
+ ContentCaptureReceiverManager::FromWebContents(web_contents);
+ if (!manager)
+ return;
+
+ auto* receiver = manager->ContentCaptureReceiverForFrame(render_frame_host);
+ if (receiver)
+ receiver->BindRequest(std::move(request));
+}
+
+ContentCaptureReceiver*
+ContentCaptureReceiverManager::ContentCaptureReceiverForFrame(
+ content::RenderFrameHost* render_frame_host) {
+ auto mapping = frame_map_.find(render_frame_host);
+ return mapping == frame_map_.end() ? nullptr : mapping->second.get();
+}
+
+void ContentCaptureReceiverManager::RenderFrameCreated(
+ content::RenderFrameHost* render_frame_host) {
+ // The frame might not have content, but it could be parent of other frame. we
+ // always create the ContentCaptureReceiver for ContentCaptureSession
+ // purpose.
+ if (ContentCaptureReceiverForFrame(render_frame_host))
+ return;
+ frame_map_.insert(std::make_pair(
+ render_frame_host,
+ std::make_unique<ContentCaptureReceiver>(render_frame_host)));
+}
+
+void ContentCaptureReceiverManager::RenderFrameDeleted(
+ content::RenderFrameHost* render_frame_host) {
+ frame_map_.erase(render_frame_host);
+}
+
+void ContentCaptureReceiverManager::DidCaptureContent(
+ ContentCaptureReceiver* content_capture_receiver,
+ const ContentCaptureData& data) {
+ // The root of |data| is frame, we need get its ancestor only.
+ ContentCaptureSession parent_session;
+ BuildContentCaptureSession(*content_capture_receiver,
+ true /* ancestor_only */, &parent_session);
+ DidCaptureContent(parent_session, data);
+}
+
+void ContentCaptureReceiverManager::DidRemoveContent(
+ ContentCaptureReceiver* content_capture_receiver,
+ const std::vector<int64_t>& data) {
+ ContentCaptureSession session;
+ // The |data| is a list of text content id, the session should include
+ // |content_capture_receiver| associated frame.
+ BuildContentCaptureSession(*content_capture_receiver,
+ false /* ancestor_only */, &session);
+ DidRemoveContent(session, data);
+}
+
+void ContentCaptureReceiverManager::DidRemoveSession(
+ ContentCaptureReceiver* content_capture_receiver) {
+ ContentCaptureSession session;
+ // The session should include the removed frame that the
+ // |content_capture_receiver| associated with.
+ BuildContentCaptureSession(*content_capture_receiver,
+ false /* ancestor_only */, &session);
+ DidRemoveSession(session);
+}
+
+void ContentCaptureReceiverManager::BuildContentCaptureSession(
+ const ContentCaptureReceiver& content_capture_receiver,
+ bool ancestor_only,
+ ContentCaptureSession* session) {
+ if (!ancestor_only)
+ session->push_back(content_capture_receiver.frame_content_capture_data());
+
+ content::RenderFrameHost* rfh = content_capture_receiver.rfh()->GetParent();
+ while (rfh) {
+ ContentCaptureReceiver* receiver = ContentCaptureReceiverForFrame(rfh);
+ // TODO(michaelbai): Only creates ContentCaptureReceiver here, clean up the
+ // code in RenderFrameCreated().
+ if (!receiver) {
+ RenderFrameCreated(rfh);
+ receiver = ContentCaptureReceiverForFrame(rfh);
+ }
+ session->push_back(receiver->frame_content_capture_data());
+ rfh = receiver->rfh()->GetParent();
+ }
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_manager.h b/chromium/components/content_capture/browser/content_capture_receiver_manager.h
new file mode 100644
index 00000000000..4ddbc8b1d80
--- /dev/null
+++ b/chromium/components/content_capture/browser/content_capture_receiver_manager.h
@@ -0,0 +1,89 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_MANAGER_H_
+#define COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_MANAGER_H_
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "base/supports_user_data.h"
+#include "components/content_capture/common/content_capture.mojom.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace content {
+class WebContents;
+} // namespace content
+
+namespace content_capture {
+
+class ContentCaptureReceiver;
+
+// This class has an instance per WebContents, it is the base class of
+// ContentCaptureReceiverManager implementation which shall overrides the pure
+// virtual methods to get the messages from each receivers, this class creates
+// the ContentCaptureReceiver and associates it with RenderFrameHost, it also
+// binds ContentCaptureReceiver with its peer ContentCaptureSender in renderer.
+// The ContentSession here is used to specify which frame the message came from.
+class ContentCaptureReceiverManager : public content::WebContentsObserver,
+ public base::SupportsUserData::Data {
+ public:
+ ~ContentCaptureReceiverManager() override;
+ static ContentCaptureReceiverManager* FromWebContents(
+ content::WebContents* contents);
+
+ // Binds the |request| with the |render_frame_host| associated
+ // ContentCaptureReceiver.
+ static void BindContentCaptureReceiver(
+ mojom::ContentCaptureReceiverAssociatedRequest request,
+ content::RenderFrameHost* render_frame_host);
+
+ // The methods called by ContentCaptureReceiver.
+ void DidCaptureContent(ContentCaptureReceiver* content_capture_receiver,
+ const ContentCaptureData& data);
+ void DidRemoveContent(ContentCaptureReceiver* content_capture_receiver,
+ const std::vector<int64_t>& data);
+ void DidRemoveSession(ContentCaptureReceiver* content_capture_receiver);
+
+ // content::WebContentsObserver:
+ void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
+ void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
+
+ size_t GetFrameMapSizeForTesting() const { return frame_map_.size(); }
+
+ protected:
+ ContentCaptureReceiverManager(content::WebContents* web_contents);
+
+ // Invoked when the captured content |data| from the |parent_session| was
+ // received.
+ virtual void DidCaptureContent(const ContentCaptureSession& parent_session,
+ const ContentCaptureData& data) = 0;
+ // Invoked when the list of content |ids| of the given |session| was removed.
+ virtual void DidRemoveContent(const ContentCaptureSession& session,
+ const std::vector<int64_t>& ids) = 0;
+ // Invoked when the given |session| was removed.
+ virtual void DidRemoveSession(const ContentCaptureSession& session) = 0;
+
+ private:
+ friend class ContentCaptureReceiverManagerHelper;
+
+ // Builds ContentCaptureSession and returns in |session|, |ancestor_only|
+ // specifies if only ancestor should be returned in |session|.
+ void BuildContentCaptureSession(
+ const ContentCaptureReceiver& content_capture_receiver,
+ bool ancestor_only,
+ ContentCaptureSession* session);
+
+ ContentCaptureReceiver* ContentCaptureReceiverForFrame(
+ content::RenderFrameHost* render_frame_host);
+
+ std::unordered_map<content::RenderFrameHost*,
+ std::unique_ptr<ContentCaptureReceiver>>
+ frame_map_;
+};
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_BROWSER_CONTENT_CAPTURE_RECEIVER_MANAGER_H_
diff --git a/chromium/components/content_capture/browser/content_capture_receiver_test.cc b/chromium/components/content_capture/browser/content_capture_receiver_test.cc
new file mode 100644
index 00000000000..9ada1eb1209
--- /dev/null
+++ b/chromium/components/content_capture/browser/content_capture_receiver_test.cc
@@ -0,0 +1,354 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/browser/content_capture_receiver.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "components/content_capture/browser/content_capture_receiver_manager.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_renderer_host.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content_capture {
+namespace {
+
+// Fake ContentCaptureSender to call ContentCaptureReceiver mojom interface.
+class FakeContentCaptureSender {
+ public:
+ FakeContentCaptureSender() {}
+
+ void DidCaptureContent(const ContentCaptureData& captured_content,
+ bool first_data) {
+ content_capture_receiver_->DidCaptureContent(captured_content, first_data);
+ }
+
+ void DidRemoveContent(const std::vector<int64_t>& data) {
+ content_capture_receiver_->DidRemoveContent(data);
+ }
+
+ mojom::ContentCaptureReceiverAssociatedRequest GetAssociatedRequest() {
+ return mojo::MakeRequestAssociatedWithDedicatedPipe(
+ &content_capture_receiver_);
+ }
+
+ private:
+ mojom::ContentCaptureReceiverAssociatedPtr content_capture_receiver_ =
+ nullptr;
+};
+
+// The helper class implements ContentCaptureReceiverManager and keeps the
+// result for verification.
+class ContentCaptureReceiverManagerHelper
+ : public ContentCaptureReceiverManager {
+ public:
+ static void Create(content::WebContents* web_contents) {
+ new ContentCaptureReceiverManagerHelper(web_contents);
+ }
+
+ ContentCaptureReceiverManagerHelper(content::WebContents* web_contents)
+ : ContentCaptureReceiverManager(web_contents) {}
+
+ void DidCaptureContent(const ContentCaptureSession& parent_session,
+ const ContentCaptureData& data) override {
+ parent_session_ = parent_session;
+ captured_data_ = data;
+ }
+
+ void DidRemoveContent(const ContentCaptureSession& session,
+ const std::vector<int64_t>& ids) override {
+ session_ = session;
+ removed_ids_ = ids;
+ }
+
+ void DidRemoveSession(const ContentCaptureSession& data) override {
+ removed_session_ = data;
+ }
+
+ const ContentCaptureSession& parent_session() const {
+ return parent_session_;
+ }
+
+ const ContentCaptureSession& session() const { return session_; }
+
+ const ContentCaptureData& captured_data() const { return captured_data_; }
+
+ const ContentCaptureSession& removed_session() const {
+ return removed_session_;
+ }
+
+ const std::vector<int64_t>& removed_ids() const { return removed_ids_; }
+
+ private:
+ ContentCaptureSession parent_session_;
+ ContentCaptureSession session_;
+ ContentCaptureData captured_data_;
+ std::vector<int64_t> removed_ids_;
+ ContentCaptureSession removed_session_;
+};
+
+class ContentCaptureReceiverTest : public content::RenderViewHostTestHarness {
+ public:
+ void SetUp() override {
+ content::RenderViewHostTestHarness::SetUp();
+ ContentCaptureReceiverManagerHelper::Create(web_contents());
+ content_capture_receiver_manager_helper_ =
+ static_cast<ContentCaptureReceiverManagerHelper*>(
+ ContentCaptureReceiverManager::FromWebContents(web_contents()));
+ // This needed to keep the WebContentsObserverSanityChecker checks happy for
+ // when AppendChild is called.
+ NavigateAndCommit(GURL("about:blank"));
+ content_capture_sender_ = std::make_unique<FakeContentCaptureSender>();
+ main_frame_ = web_contents()->GetMainFrame();
+ // Binds sender with receiver.
+ ContentCaptureReceiverManager::BindContentCaptureReceiver(
+ content_capture_sender_->GetAssociatedRequest(), main_frame_);
+
+ ContentCaptureData child;
+ // Have the unique id for text content.
+ child.id = 2;
+ child.value = base::ASCIIToUTF16("Hello");
+ child.bounds = gfx::Rect(5, 5, 5, 5);
+ // No need to set id in sender.
+ test_data_.value = base::ASCIIToUTF16("http://foo.com/bar");
+ test_data_.bounds = gfx::Rect(10, 10);
+ test_data_.children.push_back(child);
+ test_data2_.value = base::ASCIIToUTF16("http://foo.org/bar");
+ test_data2_.bounds = gfx::Rect(10, 10);
+ test_data2_.children.push_back(child);
+ }
+
+ void SetupChildFrame() {
+ child_content_capture_sender_ =
+ std::make_unique<FakeContentCaptureSender>();
+ child_frame_ =
+ content::RenderFrameHostTester::For(main_frame_)->AppendChild("child");
+ // Binds sender with receiver for child frame.
+ ContentCaptureReceiverManager::BindContentCaptureReceiver(
+ child_content_capture_sender_->GetAssociatedRequest(), child_frame_);
+ }
+
+ FakeContentCaptureSender* content_capture_sender() {
+ return content_capture_sender_.get();
+ }
+
+ FakeContentCaptureSender* child_content_capture_sender() {
+ return child_content_capture_sender_.get();
+ }
+
+ const ContentCaptureData& test_data() const { return test_data_; }
+ const ContentCaptureData& test_data2() const { return test_data2_; }
+ const std::vector<int64_t>& expected_removed_ids() const {
+ return expected_removed_ids_;
+ }
+
+ ContentCaptureData GetExpectedTestData(bool main_frame) const {
+ ContentCaptureData expected(test_data_);
+ // Replaces the id with expected id.
+ expected.id = ContentCaptureReceiver::GetIdFrom(main_frame ? main_frame_
+ : child_frame_);
+ return expected;
+ }
+
+ ContentCaptureData GetExpectedTestData2(bool main_frame) const {
+ ContentCaptureData expected(test_data2_);
+ // Replaces the id with expected id.
+ expected.id = ContentCaptureReceiver::GetIdFrom(main_frame ? main_frame_
+ : child_frame_);
+ return expected;
+ }
+
+ ContentCaptureReceiverManagerHelper* content_capture_receiver_manager_helper()
+ const {
+ return content_capture_receiver_manager_helper_;
+ }
+
+ void VerifySession(const ContentCaptureSession& expected,
+ const ContentCaptureSession& result) const {
+ EXPECT_EQ(expected.size(), result.size());
+ for (size_t i = 0; i < expected.size(); i++) {
+ EXPECT_EQ(expected[i].id, result[i].id);
+ EXPECT_EQ(expected[i].value, result[i].value);
+ EXPECT_EQ(expected[i].bounds, result[i].bounds);
+ }
+ }
+
+ void DidCaptureContent(const ContentCaptureData& captured_content,
+ bool first_data) {
+ base::RunLoop run_loop;
+ content_capture_sender()->DidCaptureContent(captured_content, first_data);
+ run_loop.RunUntilIdle();
+ }
+
+ void DidCaptureContentForChildFrame(
+ const ContentCaptureData& captured_content,
+ bool first_data) {
+ base::RunLoop run_loop;
+ child_content_capture_sender()->DidCaptureContent(captured_content,
+ first_data);
+ run_loop.RunUntilIdle();
+ }
+
+ void DidRemoveContent(const std::vector<int64_t>& data) {
+ base::RunLoop run_loop;
+ content_capture_sender()->DidRemoveContent(data);
+ run_loop.RunUntilIdle();
+ }
+
+ protected:
+ ContentCaptureReceiverManagerHelper*
+ content_capture_receiver_manager_helper_ = nullptr;
+
+ private:
+ // The sender for main frame.
+ std::unique_ptr<FakeContentCaptureSender> content_capture_sender_;
+ // The sender for child frame.
+ std::unique_ptr<FakeContentCaptureSender> child_content_capture_sender_;
+ content::RenderFrameHost* main_frame_ = nullptr;
+ content::RenderFrameHost* child_frame_ = nullptr;
+ ContentCaptureData test_data_;
+ ContentCaptureData test_data2_;
+ // Expected removed Ids.
+ std::vector<int64_t> expected_removed_ids_{2};
+};
+
+TEST_F(ContentCaptureReceiverTest, DidCaptureContent) {
+ DidCaptureContent(test_data(), true /* first_data */);
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+}
+
+TEST_F(ContentCaptureReceiverTest, DidCaptureContentWithUpdate) {
+ DidCaptureContent(test_data(), true /* first_data */);
+ // Verifies to get test_data() with correct frame content id.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+ // Simulates to update the content within the same document.
+ DidCaptureContent(test_data2(), false /* first_data */);
+ // Verifies to get test_data2() with correct frame content id.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ // Verifies that the sesssion isn't removed.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData2(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+}
+
+TEST_F(ContentCaptureReceiverTest, DidRemoveSession) {
+ DidCaptureContent(test_data(), true /* first_data */);
+ // Verifies to get test_data() with correct frame content id.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+ // Simulates to navigate other document.
+ DidCaptureContent(test_data2(), true /* first_data */);
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ // Verifies that the previous session was removed.
+ EXPECT_EQ(
+ 1u, content_capture_receiver_manager_helper()->removed_session().size());
+ std::vector<ContentCaptureData> expected{
+ GetExpectedTestData(true /* main_frame */)};
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->removed_session());
+ // Verifies that we get the test_data2() from the new document.
+ EXPECT_EQ(GetExpectedTestData2(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+}
+
+TEST_F(ContentCaptureReceiverTest, DidRemoveContent) {
+ DidCaptureContent(test_data(), true /* first_data */);
+ // Verifies to get test_data() with correct frame content id.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+ // Simulates to remove the content.
+ DidRemoveContent(expected_removed_ids());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ // Verifies that the removed_ids() was removed from the correct session.
+ EXPECT_EQ(expected_removed_ids(),
+ content_capture_receiver_manager_helper()->removed_ids());
+ std::vector<ContentCaptureData> expected{
+ GetExpectedTestData(true /* main_frame */)};
+ VerifySession(expected, content_capture_receiver_manager_helper()->session());
+}
+
+TEST_F(ContentCaptureReceiverTest, ChildFrameDidCaptureContent) {
+ // Simulate add child frame.
+ SetupChildFrame();
+ // Simulate to capture the content from main frame.
+ DidCaptureContent(test_data(), true /* first_data */);
+ // Verifies to get test_data() with correct frame content id.
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ EXPECT_EQ(GetExpectedTestData(true /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+ // Simulate to capture the content from child frame.
+ DidCaptureContentForChildFrame(test_data2(), true /* first_data */);
+ // Verifies that the parent_session was set correctly.
+ EXPECT_FALSE(
+ content_capture_receiver_manager_helper()->parent_session().empty());
+ std::vector<ContentCaptureData> expected{
+ GetExpectedTestData(true /* main_frame */)};
+ VerifySession(expected,
+ content_capture_receiver_manager_helper()->parent_session());
+ EXPECT_TRUE(
+ content_capture_receiver_manager_helper()->removed_session().empty());
+ // Verifies that we receive the correct content from child frame.
+ EXPECT_EQ(GetExpectedTestData2(false /* main_frame */),
+ content_capture_receiver_manager_helper()->captured_data());
+}
+
+class ContentCaptureReceiverMultipleFrameTest
+ : public ContentCaptureReceiverTest {
+ public:
+ void SetUp() override {
+ // Setup multiple frames before creates ContentCaptureReceiverManager.
+ content::RenderViewHostTestHarness::SetUp();
+ // This needed to keep the WebContentsObserverSanityChecker checks happy for
+ // when AppendChild is called.
+ NavigateAndCommit(GURL("about:blank"));
+ content::RenderFrameHostTester::For(web_contents()->GetMainFrame())
+ ->AppendChild("child");
+ ContentCaptureReceiverManagerHelper::Create(web_contents());
+ content_capture_receiver_manager_helper_ =
+ static_cast<ContentCaptureReceiverManagerHelper*>(
+ ContentCaptureReceiverManager::FromWebContents(web_contents()));
+ }
+
+ void TearDown() override { content::RenderViewHostTestHarness::TearDown(); }
+};
+
+TEST_F(ContentCaptureReceiverMultipleFrameTest,
+ ReceiverCreatedForExistingFrame) {
+ EXPECT_EQ(
+ 2u,
+ content_capture_receiver_manager_helper()->GetFrameMapSizeForTesting());
+}
+} // namespace
+} // namespace content_capture
diff --git a/chromium/components/content_capture/common/BUILD.gn b/chromium/components/content_capture/common/BUILD.gn
new file mode 100644
index 00000000000..326f9f19ddd
--- /dev/null
+++ b/chromium/components/content_capture/common/BUILD.gn
@@ -0,0 +1,72 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+source_set("common") {
+ sources = [
+ "content_capture_data.cc",
+ "content_capture_data.h",
+ "content_capture_features.cc",
+ "content_capture_features.h",
+ ]
+
+ deps = [
+ "//base",
+ "//ui/gfx/geometry",
+ ]
+}
+
+mojom("mojo_interfaces") {
+ sources = [
+ "content_capture.mojom",
+ ]
+
+ public_deps = [
+ ":mojo_types",
+ "//mojo/public/mojom/base",
+ "//ui/gfx/geometry/mojo",
+ ]
+}
+
+mojom("mojo_types") {
+ sources = [
+ "content_capture_data.mojom",
+ ]
+
+ public_deps = [
+ "//mojo/public/mojom/base",
+ "//ui/gfx/geometry/mojo",
+ ]
+}
+
+mojom("mojo_test_types") {
+ testonly = true
+ sources = [
+ "traits_test_service.test-mojom",
+ ]
+
+ public_deps = [
+ ":mojo_types",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "content_capture_struct_traits_unittest.cc",
+ ]
+
+ public_deps = [
+ ":mojo_test_types",
+ ]
+
+ deps = [
+ ":common",
+ "//base",
+ "//base/test:test_support",
+ "//mojo/public/cpp/bindings",
+ "//testing/gtest",
+ ]
+}
diff --git a/chromium/components/content_capture/common/OWNERS b/chromium/components/content_capture/common/OWNERS
new file mode 100644
index 00000000000..2c44a463856
--- /dev/null
+++ b/chromium/components/content_capture/common/OWNERS
@@ -0,0 +1,6 @@
+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/content_capture/common/content_capture.mojom b/chromium/components/content_capture/common/content_capture.mojom
new file mode 100644
index 00000000000..5bb2ff35dc1
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture.mojom
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content_capture.mojom;
+
+import "components/content_capture/common/content_capture_data.mojom";
+
+// The interface has one instance per RenderFrameHost in the browser
+// process. All methods are called by renderer.
+interface ContentCaptureReceiver {
+ // Invoked when the |data| is captured, |first_data| indicates if
+ // this is first data from the document.
+ DidCaptureContent(ContentCaptureData data, bool first_data);
+
+ // Invoked to notify that a list of content |ids| has been removed.
+ DidRemoveContent(array<int64> ids);
+}; \ No newline at end of file
diff --git a/chromium/components/content_capture/common/content_capture.typemap b/chromium/components/content_capture/common/content_capture.typemap
new file mode 100644
index 00000000000..9eefc29f786
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture.typemap
@@ -0,0 +1,20 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//components/content_capture/common/content_capture_data.mojom"
+public_headers =
+ [ "//components/content_capture/common/content_capture_data.h" ]
+traits_headers =
+ [ "//components/content_capture/common/content_capture_struct_traits.h" ]
+sources = [
+ "//components/content_capture/common/content_capture_struct_traits.cc",
+ "//components/content_capture/common/content_capture_struct_traits.h",
+]
+deps = [
+ "//base",
+ "//components/content_capture/common:common",
+ "//ui/gfx/geometry/mojo:struct_traits",
+]
+
+type_mappings = [ "content_capture.mojom.ContentCaptureData=content_capture::ContentCaptureData" ]
diff --git a/chromium/components/content_capture/common/content_capture_data.cc b/chromium/components/content_capture/common/content_capture_data.cc
new file mode 100644
index 00000000000..0c41c62ae30
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_data.cc
@@ -0,0 +1,24 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/common/content_capture_data.h"
+
+namespace content_capture {
+
+ContentCaptureData::ContentCaptureData() {}
+
+ContentCaptureData::ContentCaptureData(const ContentCaptureData& data)
+ : id(data.id),
+ value(data.value),
+ bounds(data.bounds),
+ children(data.children) {}
+
+ContentCaptureData::~ContentCaptureData() {}
+
+bool ContentCaptureData::operator==(const ContentCaptureData& other) const {
+ return id == other.id && value == other.value && bounds == other.bounds &&
+ children == other.children;
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/common/content_capture_data.h b/chromium/components/content_capture/common/content_capture_data.h
new file mode 100644
index 00000000000..6ed08805b06
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_data.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_DATA_H_
+#define COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_DATA_H_
+
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "ui/gfx/geometry/rect_f.h"
+
+namespace content_capture {
+
+// This struct defines the on-screen text content and its bounds in a frame,
+// the text is captured in renderer and sent to browser; the root of
+// this tree is frame, the child could be the scrollable area or the text
+// content.
+struct ContentCaptureData {
+ ContentCaptureData();
+ ContentCaptureData(const ContentCaptureData& data);
+ ~ContentCaptureData();
+
+ // The id of the frame or the content.
+ int64_t id = 0;
+ // The url of frame or the text of the content.
+ base::string16 value;
+ // The bounds of the frame or the content.
+ gfx::Rect bounds;
+ // The children content, only available for frame or scrollable area.
+ std::vector<ContentCaptureData> children;
+
+ bool operator==(const ContentCaptureData& other) const;
+
+ bool operator!=(const ContentCaptureData& other) const {
+ return !(*this == other);
+ }
+};
+
+// This defines a session, is a list of frames from current frame to root.
+using ContentCaptureSession = std::vector<ContentCaptureData>;
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_DATA_H_
diff --git a/chromium/components/content_capture/common/content_capture_data.mojom b/chromium/components/content_capture/common/content_capture_data.mojom
new file mode 100644
index 00000000000..1f3ece0e685
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_data.mojom
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content_capture.mojom;
+
+import "mojo/public/mojom/base/string16.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+
+// The mojom definition of content_capture::ContentCaptureData.
+struct ContentCaptureData {
+ int64 id;
+ mojo_base.mojom.String16 value;
+ gfx.mojom.Rect bounds;
+ array<ContentCaptureData> children;
+};
diff --git a/chromium/components/content_capture/common/content_capture_features.cc b/chromium/components/content_capture/common/content_capture_features.cc
new file mode 100644
index 00000000000..01ab6a96ad2
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_features.cc
@@ -0,0 +1,35 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/common/content_capture_features.h"
+
+#include "base/metrics/field_trial_params.h"
+
+namespace content_capture {
+namespace features {
+
+const base::Feature kContentCapture{"ContentCapture",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsContentCaptureEnabled() {
+ return base::FeatureList::IsEnabled(kContentCapture);
+}
+
+bool ShouldUseNodeID() {
+ return base::GetFieldTrialParamByFeatureAsBool(kContentCapture, "use_node_id",
+ false);
+}
+
+int TaskLongDelayInMilliseconds() {
+ return base::GetFieldTrialParamByFeatureAsInt(
+ kContentCapture, "task_long_delay_in_milliseconds", 5000);
+}
+
+int TaskShortDelayInMilliseconds() {
+ return base::GetFieldTrialParamByFeatureAsInt(
+ kContentCapture, "task_short_delay_in_milliseconds", 500);
+}
+
+} // namespace features
+} // namespace content_capture
diff --git a/chromium/components/content_capture/common/content_capture_features.h b/chromium/components/content_capture/common/content_capture_features.h
new file mode 100644
index 00000000000..eff8b18324b
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_features.h
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_FEATURES_H_
+#define COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace content_capture {
+
+namespace features {
+
+extern const base::Feature kContentCaptureEnabled;
+
+bool IsContentCaptureEnabled();
+bool ShouldUseNodeID();
+
+int TaskLongDelayInMilliseconds();
+int TaskShortDelayInMilliseconds();
+
+} // namespace features
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_FEATURES_H_
diff --git a/chromium/components/content_capture/common/content_capture_struct_traits.cc b/chromium/components/content_capture/common/content_capture_struct_traits.cc
new file mode 100644
index 00000000000..4be5c06232f
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_struct_traits.cc
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/common/content_capture_struct_traits.h"
+
+#include "mojo/public/cpp/base/string16_mojom_traits.h"
+#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+
+namespace mojo {
+
+// static
+bool StructTraits<content_capture::mojom::ContentCaptureDataDataView,
+ content_capture::ContentCaptureData>::
+ Read(content_capture::mojom::ContentCaptureDataDataView data,
+ content_capture::ContentCaptureData* out_data) {
+ out_data->id = data.id();
+ if (!data.ReadValue(&out_data->value))
+ return false;
+ if (!data.ReadBounds(&out_data->bounds))
+ return false;
+ if (!data.ReadChildren(&out_data->children))
+ return false;
+
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/components/content_capture/common/content_capture_struct_traits.h b/chromium/components/content_capture/common/content_capture_struct_traits.h
new file mode 100644
index 00000000000..85dd18ca485
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_struct_traits.h
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_STRUCT_TRAITS_H_
+#define COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_STRUCT_TRAITS_H_
+
+#include <vector>
+
+#include "components/content_capture/common/content_capture_data.h"
+#include "components/content_capture/common/content_capture_data.mojom.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "ui/gfx/geometry/rect_f.h"
+
+namespace mojo {
+
+template <>
+class StructTraits<content_capture::mojom::ContentCaptureDataDataView,
+ content_capture::ContentCaptureData> {
+ public:
+ static int64_t id(const content_capture::ContentCaptureData& r) {
+ return r.id;
+ }
+ static const base::string16& value(
+ const content_capture::ContentCaptureData& r) {
+ return r.value;
+ }
+ static const gfx::Rect& bounds(const content_capture::ContentCaptureData& r) {
+ return r.bounds;
+ }
+ static const std::vector<content_capture::ContentCaptureData>& children(
+ const content_capture::ContentCaptureData& r) {
+ return r.children;
+ }
+
+ static bool Read(content_capture::mojom::ContentCaptureDataDataView data,
+ content_capture::ContentCaptureData* out_data);
+};
+
+} // namespace mojo
+
+#endif // COMPONENTS_CONTENT_CAPTURE_COMMON_CONTENT_CAPTURE_STRUCT_TRAITS_H_
diff --git a/chromium/components/content_capture/common/content_capture_struct_traits_unittest.cc b/chromium/components/content_capture/common/content_capture_struct_traits_unittest.cc
new file mode 100644
index 00000000000..5bb7b331db3
--- /dev/null
+++ b/chromium/components/content_capture/common/content_capture_struct_traits_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/content_capture/common/traits_test_service.test-mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content_capture {
+namespace {
+
+class ContentCaptureStructTraitsTest : public testing::Test,
+ public mojom::TraitsTestService {
+ public:
+ ContentCaptureStructTraitsTest() = default;
+
+ protected:
+ mojom::TraitsTestServicePtr GetTraitsTestProxy() {
+ mojom::TraitsTestServicePtr proxy;
+ traits_test_bindings_.AddBinding(this, mojo::MakeRequest(&proxy));
+ return proxy;
+ }
+
+ private:
+ // TraitsTestService:
+ void EchoContentCaptureData(
+ const ContentCaptureData& i,
+ EchoContentCaptureDataCallback callback) override {
+ std::move(callback).Run(i);
+ }
+
+ base::MessageLoop loop_;
+ mojo::BindingSet<TraitsTestService> traits_test_bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentCaptureStructTraitsTest);
+};
+
+TEST_F(ContentCaptureStructTraitsTest, ContentCaptureData) {
+ ContentCaptureData child;
+ child.id = 2;
+ child.value = base::ASCIIToUTF16("Hello");
+ child.bounds = gfx::Rect(5, 5, 5, 5);
+ ContentCaptureData input;
+ input.id = 1;
+ input.value = base::ASCIIToUTF16("http://foo.com/bar");
+ input.bounds = gfx::Rect(10, 10);
+ input.children.push_back(child);
+
+ mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
+ ContentCaptureData output;
+ proxy->EchoContentCaptureData(input, &output);
+ EXPECT_EQ(input, output);
+}
+
+} // namespace
+} // namespace content_capture
diff --git a/chromium/components/content_capture/common/traits_test_service.test-mojom b/chromium/components/content_capture/common/traits_test_service.test-mojom
new file mode 100644
index 00000000000..af2e9e89cc9
--- /dev/null
+++ b/chromium/components/content_capture/common/traits_test_service.test-mojom
@@ -0,0 +1,14 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content_capture.mojom;
+
+import "components/content_capture/common/content_capture_data.mojom";
+
+// All functions on this interface echo their arguments to test StructTraits
+// serialization and deserialization.
+interface TraitsTestService {
+[Sync]
+ EchoContentCaptureData(ContentCaptureData i) => (ContentCaptureData pass);
+}; \ No newline at end of file
diff --git a/chromium/components/content_capture/renderer/BUILD.gn b/chromium/components/content_capture/renderer/BUILD.gn
new file mode 100644
index 00000000000..9d28338814c
--- /dev/null
+++ b/chromium/components/content_capture/renderer/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("renderer") {
+ sources = [
+ "content_capture_sender.cc",
+ "content_capture_sender.h",
+ ]
+
+ deps = [
+ "//components/content_capture/common",
+ "//components/content_capture/common:mojo_interfaces",
+ "//content/public/common",
+ "//content/public/renderer",
+ "//third_party/blink/public:blink",
+ ]
+}
diff --git a/chromium/components/content_capture/renderer/DEPS b/chromium/components/content_capture/renderer/DEPS
new file mode 100644
index 00000000000..179ad68ff40
--- /dev/null
+++ b/chromium/components/content_capture/renderer/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+content/public/renderer",
+ "+third_party/blink/public",
+] \ No newline at end of file
diff --git a/chromium/components/content_capture/renderer/content_capture_sender.cc b/chromium/components/content_capture/renderer/content_capture_sender.cc
new file mode 100644
index 00000000000..989ec63b723
--- /dev/null
+++ b/chromium/components/content_capture/renderer/content_capture_sender.cc
@@ -0,0 +1,89 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_capture/renderer/content_capture_sender.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "components/content_capture/common/content_capture_data.h"
+#include "components/content_capture/common/content_capture_features.h"
+#include "content/public/renderer/render_frame.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/web/web_content_holder.h"
+#include "third_party/blink/public/web/web_document.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+
+namespace content_capture {
+
+ContentCaptureSender::ContentCaptureSender(content::RenderFrame* render_frame)
+ : content::RenderFrameObserver(render_frame) {
+ render_frame->GetWebFrame()->SetContentCaptureClient(this);
+}
+
+ContentCaptureSender::~ContentCaptureSender() {}
+
+cc::NodeHolder::Type ContentCaptureSender::GetNodeHolderType() const {
+ if (content_capture::features::ShouldUseNodeID())
+ return cc::NodeHolder::Type::kID;
+ else
+ return cc::NodeHolder::Type::kTextHolder;
+}
+
+void ContentCaptureSender::GetTaskTimingParameters(
+ base::TimeDelta& short_delay,
+ base::TimeDelta& long_delay) const {
+ short_delay = base::TimeDelta::FromMilliseconds(
+ features::TaskShortDelayInMilliseconds());
+ long_delay = base::TimeDelta::FromMilliseconds(
+ features::TaskLongDelayInMilliseconds());
+}
+
+void ContentCaptureSender::DidCaptureContent(
+ const std::vector<scoped_refptr<blink::WebContentHolder>>& data,
+ bool first_data) {
+ ContentCaptureData frame_data;
+ FillContentCaptureData(&frame_data, first_data /* set_url */);
+
+ frame_data.children.reserve(data.size());
+ base::TimeTicks start = base::TimeTicks::Now();
+ for (auto holder : data) {
+ ContentCaptureData child;
+ child.id = holder->GetId();
+ child.value = holder->GetValue().Utf16();
+ child.bounds = holder->GetBoundingBox();
+ frame_data.children.push_back(child);
+ }
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "ContentCapture.GetBoundingBox", base::TimeTicks::Now() - start,
+ base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromMilliseconds(10), 50);
+ GetContentCaptureReceiver()->DidCaptureContent(frame_data, first_data);
+}
+
+void ContentCaptureSender::DidRemoveContent(const std::vector<int64_t>& data) {
+ GetContentCaptureReceiver()->DidRemoveContent(data);
+}
+
+void ContentCaptureSender::OnDestruct() {
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
+void ContentCaptureSender::FillContentCaptureData(ContentCaptureData* data,
+ bool set_url) {
+ data->bounds = render_frame()->GetWebFrame()->VisibleContentRect();
+ if (set_url) {
+ data->value =
+ render_frame()->GetWebFrame()->GetDocument().Url().GetString().Utf16();
+ }
+}
+
+const mojom::ContentCaptureReceiverAssociatedPtr&
+ContentCaptureSender::GetContentCaptureReceiver() {
+ if (!content_capture_receiver_) {
+ render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
+ mojo::MakeRequest(&content_capture_receiver_));
+ }
+ return content_capture_receiver_;
+}
+
+} // namespace content_capture
diff --git a/chromium/components/content_capture/renderer/content_capture_sender.h b/chromium/components/content_capture/renderer/content_capture_sender.h
new file mode 100644
index 00000000000..120cde15696
--- /dev/null
+++ b/chromium/components/content_capture/renderer/content_capture_sender.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CONTENT_CAPTURE_RENDERER_CONTENT_CAPTURE_SENDER_H_
+#define COMPONENTS_CONTENT_CAPTURE_RENDERER_CONTENT_CAPTURE_SENDER_H_
+
+#include <vector>
+
+#include "components/content_capture/common/content_capture.mojom.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "third_party/blink/public/web/web_content_capture_client.h"
+
+namespace content_capture {
+
+struct ContentCaptureData;
+
+// This class has one instance per RenderFrame, and implements
+// WebConetentCaptureClient to get the captured content and the removed
+// content from blink, then forward them to browser process; it enables
+// the ContentCapture in blink by setting WebContentCaptureClient to
+// WebLocalFrame.
+class ContentCaptureSender : public content::RenderFrameObserver,
+ public blink::WebContentCaptureClient {
+ public:
+ explicit ContentCaptureSender(content::RenderFrame* render_frame);
+ ~ContentCaptureSender() override;
+
+ // blink::WebContentCaptureClient:
+ cc::NodeHolder::Type GetNodeHolderType() const override;
+ void GetTaskTimingParameters(base::TimeDelta& short_delay,
+ base::TimeDelta& long_delay) const override;
+ void DidCaptureContent(
+ const std::vector<scoped_refptr<blink::WebContentHolder>>& data,
+ bool first_data) override;
+ void DidRemoveContent(const std::vector<int64_t>& data) override;
+
+ // content::RenderFrameObserver:
+ void OnDestruct() override;
+
+ private:
+ void FillContentCaptureData(ContentCaptureData* data, bool set_url);
+ const mojom::ContentCaptureReceiverAssociatedPtr& GetContentCaptureReceiver();
+
+ mojom::ContentCaptureReceiverAssociatedPtr content_capture_receiver_ =
+ nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentCaptureSender);
+};
+
+} // namespace content_capture
+
+#endif // COMPONENTS_CONTENT_CAPTURE_RENDERER_CONTENT_CAPTURE_SENDER_H_
diff --git a/chromium/components/content_settings/core/browser/BUILD.gn b/chromium/components/content_settings/core/browser/BUILD.gn
index 8e6d992b5c9..1edbe265cee 100644
--- a/chromium/components/content_settings/core/browser/BUILD.gn
+++ b/chromium/components/content_settings/core/browser/BUILD.gn
@@ -76,6 +76,7 @@ jumbo_source_set("unit_tests") {
testonly = true
sources = [
"content_settings_ephemeral_provider_unittest.cc",
+ "content_settings_pref_unittest.cc",
"content_settings_registry_unittest.cc",
"content_settings_rule_unittest.cc",
"content_settings_utils_unittest.cc",
@@ -95,8 +96,10 @@ jumbo_source_set("unit_tests") {
"//components/content_settings/core/test:test_support",
"//components/pref_registry:pref_registry",
"//components/prefs",
+ "//components/prefs:test_support",
"//components/sync_preferences:test_support",
"//extensions/buildflags",
+ "//testing/gmock",
"//testing/gtest",
"//url",
]
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 d45ed16dfcb..60836267296 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
@@ -82,9 +82,9 @@ bool OriginIdentifierValueMap::PatternPair::operator<(
std::tie(other.primary_pattern, other.secondary_pattern);
}
-OriginIdentifierValueMap::ValueEntry::ValueEntry(){};
+OriginIdentifierValueMap::ValueEntry::ValueEntry() {}
-OriginIdentifierValueMap::ValueEntry::~ValueEntry(){};
+OriginIdentifierValueMap::ValueEntry::~ValueEntry() {}
std::unique_ptr<RuleIterator> OriginIdentifierValueMap::GetRuleIterator(
ContentSettingsType content_type,
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 99b0c543c47..b3784368a93 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
@@ -322,7 +322,7 @@ void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
continue;
}
- std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(
pattern_filter_json, base::JSON_ALLOW_TRAILING_COMMAS);
if (!value || !value->is_dict()) {
VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
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 90facf52998..4e8ef3ac8df 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_pref.cc
@@ -404,7 +404,7 @@ void ContentSettingsPref::UpdatePref(
value->CreateDeepCopy());
// Update timestamp for whole resource dictionary.
settings_dictionary->SetKey(kLastModifiedPath,
- base::Value(base::Int64ToString(
+ base::Value(base::NumberToString(
last_modified.ToInternalValue())));
}
} else {
@@ -418,7 +418,7 @@ void ContentSettingsPref::UpdatePref(
settings_dictionary->SetWithoutPathExpansion(kSettingPath,
value->CreateDeepCopy());
settings_dictionary->SetKey(kLastModifiedPath,
- base::Value(base::Int64ToString(
+ base::Value(base::NumberToString(
last_modified.ToInternalValue())));
}
}
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref_unittest.cc b/chromium/components/content_settings/core/browser/content_settings_pref_unittest.cc
new file mode 100644
index 00000000000..652a041e4bc
--- /dev/null
+++ b/chromium/components/content_settings/core/browser/content_settings_pref_unittest.cc
@@ -0,0 +1,153 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_settings/core/browser/content_settings_pref.h"
+#include "components/content_settings/core/common/content_settings_pattern.h"
+
+#include "base/bind_helpers.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "components/content_settings/core/browser/content_settings_utils.h"
+#include "components/content_settings/core/common/content_settings_types.h"
+#include "components/prefs/pref_change_registrar.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"
+
+namespace content_settings {
+namespace {
+
+// Test content setting pattern pairs in string format. The percent-encoded
+// sequence "%61" should get canonicalized to the letter 'a'.
+constexpr char kTestPatternCanonicalAlpha[] = "https://alpha.com,*";
+constexpr char kTestPatternNonCanonicalAlpha1[] = "https://%61lpha.com,*";
+constexpr char kTestPatternNonCanonicalAlpha2[] = "https://alph%61.com,*";
+constexpr char kTestPatternCanonicalBeta[] = "https://beta.com,*";
+constexpr char kTestPatternNonCanonicalBeta[] = "https://bet%61.com,*";
+
+constexpr char kTestContentSettingPrefName[] = "content_settings.test";
+
+constexpr char kLastModifiedKey[] = "last_modified";
+constexpr char kSettingKey[] = "setting";
+constexpr char kTagKey[] = "tag";
+
+// Creates a JSON dictionary representing a dummy content setting exception
+// value in preferences. The setting will be marked with the |tag| like so:
+//
+// value = {
+// "last_modified": "...",
+// "setting": {
+// "tag": "...",
+// }
+// }
+base::Value CreateDummyContentSettingValue(base::StringPiece tag) {
+ base::Value setting(base::Value::Type::DICTIONARY);
+ setting.SetKey(kTagKey, base::Value(tag));
+
+ base::Value pref_value(base::Value::Type::DICTIONARY);
+ pref_value.SetKey(kLastModifiedKey, base::Value("13189876543210000"));
+ pref_value.SetKey(kSettingKey, std::move(setting));
+ return pref_value;
+}
+
+// Given the JSON dictionary representing the "setting" stored under a content
+// setting exception value, returns the tag.
+std::string GetTagFromDummyContentSetting(const base::Value& setting) {
+ const auto* tag = setting.FindKey(kTagKey);
+ return tag ? tag->GetString() : std::string();
+}
+
+// Given the JSON dictionary representing a content setting exception value,
+// returns the tag.
+std::string GetTagFromDummyContentSettingValue(const base::Value& pref_value) {
+ const auto* setting = pref_value.FindKey(kSettingKey);
+ return setting ? GetTagFromDummyContentSetting(*setting) : std::string();
+}
+
+} // namespace
+
+TEST(ContentSettingsPref, CanonicalizationWhileReadingFromPrefs) {
+ // Canonical/non-canonical patterns originally in preferences.
+ constexpr const char* kTestOriginalPatterns[] = {
+ kTestPatternNonCanonicalAlpha1,
+ kTestPatternNonCanonicalAlpha2,
+ kTestPatternCanonicalBeta,
+ kTestPatternNonCanonicalBeta,
+ };
+
+ // Upon construction, ContentSettingPref reads all content setting exception
+ // data stored in Preferences for a given content setting. This process also
+ // has the side effect that it migrates all data keyed under non-canonical
+ // content setting pattern pairs to be keyed under the corresponding canoncial
+ // pattern pair, both in Preferences, as well as in ContentSettingPref's
+ // in-memory |value_map| representation. There are two edge cases here:
+ //
+ // 1) If multiple non-canonical patterns map to the same canonical pattern,
+ // the data for the last read pattern is retained, the rest thrown away.
+ // 2) We ignore and delete non-canonical pattern pairs if a canonical one
+ // already exists.
+ //
+ // With regard to the test data, NonCanonicalAlpha1 and NonCanonicalAlpha2
+ // would both map to CanonicalAlpha, so the value for the latter should be
+ // retained.
+ //
+ // NonCanonicalBeta would be canonicalized to CanonicalBeta, but because there
+ // is already a value under that key, the latter should be retained and the
+ // non-canonical value thrown away.
+ using CanonicalPatternToTag = std::pair<std::string, std::string>;
+ const std::vector<CanonicalPatternToTag> kExpectedPatternsToTags = {
+ {kTestPatternCanonicalAlpha, kTestPatternNonCanonicalAlpha2},
+ {kTestPatternCanonicalBeta, kTestPatternCanonicalBeta},
+ };
+
+ auto original_pref_value = std::make_unique<base::DictionaryValue>();
+ for (const auto* pattern : kTestOriginalPatterns) {
+ original_pref_value->SetKey(pattern,
+ CreateDummyContentSettingValue(pattern));
+ }
+
+ TestingPrefServiceSimple prefs;
+ prefs.registry()->RegisterDictionaryPref(kTestContentSettingPrefName);
+ prefs.SetUserPref(kTestContentSettingPrefName,
+ std::move(original_pref_value));
+
+ PrefChangeRegistrar registrar;
+ registrar.Init(&prefs);
+ ContentSettingsPref content_settings_pref(
+ CONTENT_SETTINGS_TYPE_MEDIA_ENGAGEMENT, &prefs, &registrar,
+ kTestContentSettingPrefName, false, base::DoNothing());
+
+ // Verify that the |value_map| contains the expected content setting patterns
+ // and setting.
+
+ std::vector<CanonicalPatternToTag> patterns_to_tags_in_memory;
+ auto rule_iterator = content_settings_pref.GetRuleIterator(
+ std::string() /* resource_identifier */, false /* is_incognito */);
+ while (rule_iterator->HasNext()) {
+ auto rule = rule_iterator->Next();
+ patterns_to_tags_in_memory.emplace_back(
+ CreatePatternString(rule.primary_pattern, rule.secondary_pattern),
+ GetTagFromDummyContentSetting(rule.value));
+ }
+
+ EXPECT_THAT(patterns_to_tags_in_memory,
+ testing::UnorderedElementsAreArray(kExpectedPatternsToTags));
+
+ // Verify that Preferences do, as well.
+
+ std::vector<CanonicalPatternToTag> patterns_to_tags_in_prefs;
+ const auto* canonical_pref_value =
+ prefs.GetUserPref(kTestContentSettingPrefName);
+ ASSERT_TRUE(canonical_pref_value->is_dict());
+ for (const auto& key_value : canonical_pref_value->DictItems()) {
+ patterns_to_tags_in_prefs.emplace_back(
+ key_value.first, GetTagFromDummyContentSettingValue(key_value.second));
+ }
+
+ EXPECT_THAT(patterns_to_tags_in_prefs,
+ testing::UnorderedElementsAreArray(kExpectedPatternsToTags));
+}
+
+} // namespace content_settings
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 912fdeba281..03d0c89f73c 100644
--- a/chromium/components/content_settings/core/browser/content_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_registry.cc
@@ -440,6 +440,16 @@ void ContentSettingsRegistry::Init() {
ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
ContentSettingsInfo::PERSISTENT,
ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
+
+ Register(CONTENT_SETTINGS_TYPE_SERIAL_GUARD, "serial-guard",
+ CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
+ WhitelistedSchemes(),
+ ValidSettings(CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK),
+ WebsiteSettingsInfo::SINGLE_ORIGIN_WITH_EMBEDDED_EXCEPTIONS_SCOPE,
+ WebsiteSettingsRegistry::DESKTOP,
+ ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
+ ContentSettingsInfo::PERSISTENT,
+ ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
}
void ContentSettingsRegistry::Register(
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 052b8db744c..085efe9dc56 100644
--- a/chromium/components/content_settings/core/browser/website_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/website_settings_registry.cc
@@ -194,6 +194,11 @@ void WebsiteSettingsRegistry::Init() {
WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
WebsiteSettingsInfo::SINGLE_ORIGIN_WITH_EMBEDDED_EXCEPTIONS_SCOPE,
DESKTOP, WebsiteSettingsInfo::DONT_INHERIT_IN_INCOGNITO);
+ Register(CONTENT_SETTINGS_TYPE_SERIAL_CHOOSER_DATA, "serial-chooser-data",
+ nullptr, WebsiteSettingsInfo::UNSYNCABLE,
+ WebsiteSettingsInfo::NOT_LOSSY,
+ WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE,
+ DESKTOP, WebsiteSettingsInfo::DONT_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 28e51c015a5..cac5b0ca073 100644
--- a/chromium/components/content_settings/core/common/content_settings.cc
+++ b/chromium/components/content_settings/core/common/content_settings.cc
@@ -29,7 +29,7 @@ struct HistogramValue {
// content settings type name instead.
//
// The array size must be explicit for the static_asserts below.
-constexpr size_t kNumHistogramValues = 41;
+constexpr size_t kNumHistogramValues = 43;
constexpr HistogramValue kHistogramValue[kNumHistogramValues] = {
{CONTENT_SETTINGS_TYPE_COOKIES, 0},
{CONTENT_SETTINGS_TYPE_IMAGES, 1},
@@ -72,6 +72,8 @@ constexpr HistogramValue kHistogramValue[kNumHistogramValues] = {
{CONTENT_SETTINGS_TYPE_BACKGROUND_FETCH, 45},
{CONTENT_SETTINGS_TYPE_INTENT_PICKER_DISPLAY, 46},
{CONTENT_SETTINGS_TYPE_IDLE_DETECTION, 47},
+ {CONTENT_SETTINGS_TYPE_SERIAL_GUARD, 48},
+ {CONTENT_SETTINGS_TYPE_SERIAL_CHOOSER_DATA, 49},
};
} // namespace
diff --git a/chromium/components/content_settings/core/common/content_settings_pattern_parser.cc b/chromium/components/content_settings/core/common/content_settings_pattern_parser.cc
index 00af1089513..7064c2b4c96 100644
--- a/chromium/components/content_settings/core/common/content_settings_pattern_parser.cc
+++ b/chromium/components/content_settings/core/common/content_settings_pattern_parser.cc
@@ -20,6 +20,10 @@ const char kPortWildcard[] = "*";
const char kSchemeWildcard[] = "*";
const char kUrlPathSeparator[] = "/";
const char kUrlPortSeparator[] = ":";
+// A domain wildcard pattern involves exactly one separating dot,
+// inside the square brackets. This is a common misunderstanding of that
+// pattern that we want to check for. See: https://crbug.com/823706.
+const char kDomainWildcardWithSuperfluousDot[] = "[*.].";
} // namespace
@@ -130,6 +134,12 @@ void PatternParser::Parse(base::StringPiece pattern_spec,
return;
}
+ if (base::StartsWith(host_piece, kDomainWildcardWithSuperfluousDot,
+ base::CompareCase::SENSITIVE)) {
+ builder->Invalid();
+ return;
+ }
+
host_piece.remove_prefix(kDomainWildcardLength);
builder->WithDomainWildcard();
builder->WithHost(host_piece.as_string());
diff --git a/chromium/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc b/chromium/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
index 20c7c7ac022..244db0108a7 100644
--- a/chromium/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
+++ b/chromium/components/content_settings/core/common/content_settings_pattern_parser_unittest.cc
@@ -150,6 +150,16 @@ TEST(ContentSettingsPatternParserTest, ParsePatterns) {
::testing::Return(&builder));
content_settings::PatternParser::Parse("www.youtube.com*", &builder);
::testing::Mock::VerifyAndClear(&builder);
+
+ // Test for kDomainWildcardWithSuperfluousDot
+ EXPECT_CALL(builder, WithSchemeWildcard())
+ .Times(1)
+ .WillOnce(::testing::Return(&builder));
+ EXPECT_CALL(builder, Invalid())
+ .Times(1)
+ .WillOnce(::testing::Return(&builder));
+ content_settings::PatternParser::Parse("[*.].youtube.com", &builder);
+ ::testing::Mock::VerifyAndClear(&builder);
}
TEST(ContentSettingsPatternParserTest, ParseFilePatterns) {
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 17b6ab6df63..338fdd7ea5d 100644
--- a/chromium/components/content_settings/core/common/content_settings_types.h
+++ b/chromium/components/content_settings/core/common/content_settings_types.h
@@ -129,6 +129,13 @@ enum ContentSettingsType {
// Used to store whether to allow a website to detect user active/idle state.
CONTENT_SETTINGS_TYPE_IDLE_DETECTION,
+ // Content settings for access to serial ports. The "guard" content setting
+ // stores whether to allow sites to ask for permission to access a port. The
+ // permissions granted to access particular ports are stored in the "chooser
+ // data" website setting.
+ CONTENT_SETTINGS_TYPE_SERIAL_GUARD,
+ CONTENT_SETTINGS_TYPE_SERIAL_CHOOSER_DATA,
+
CONTENT_SETTINGS_NUM_TYPES,
};
diff --git a/chromium/components/contextual_search/content/renderer/contextual_search_wrapper.cc b/chromium/components/contextual_search/content/renderer/contextual_search_wrapper.cc
index 105783cb328..338c147ae6b 100644
--- a/chromium/components/contextual_search/content/renderer/contextual_search_wrapper.cc
+++ b/chromium/components/contextual_search/content/renderer/contextual_search_wrapper.cc
@@ -52,7 +52,7 @@ void ContextualSearchWrapper::Install(content::RenderFrame* render_frame) {
return;
v8::Local<v8::Object> chrome =
- content::GetOrCreateChromeObject(isolate, context->Global());
+ content::GetOrCreateChromeObject(isolate, context);
chrome->Set(gin::StringToV8(isolate, kContextualSearchObjectName),
wrapper.ToV8());
}
diff --git a/chromium/components/contextual_search/content/renderer/overlay_js_render_frame_observer.cc b/chromium/components/contextual_search/content/renderer/overlay_js_render_frame_observer.cc
index 00409a91835..6414880f55c 100644
--- a/chromium/components/contextual_search/content/renderer/overlay_js_render_frame_observer.cc
+++ b/chromium/components/contextual_search/content/renderer/overlay_js_render_frame_observer.cc
@@ -45,8 +45,7 @@ void OverlayJsRenderFrameObserver::EnableJsApi(bool should_enable) {
}
bool OverlayJsRenderFrameObserver::EnsureServiceConnected() {
- if (render_frame() && (!contextual_search_js_api_service_ ||
- !contextual_search_js_api_service_.is_bound())) {
+ if (render_frame() && !contextual_search_js_api_service_) {
render_frame()->GetRemoteInterfaces()->GetInterface(
&contextual_search_js_api_service_);
return true;
diff --git a/chromium/components/contextual_search/core/browser/contextual_search_preference.h b/chromium/components/contextual_search/core/browser/contextual_search_preference.h
index 69fcced6e77..7c99d436693 100644
--- a/chromium/components/contextual_search/core/browser/contextual_search_preference.h
+++ b/chromium/components/contextual_search/core/browser/contextual_search_preference.h
@@ -36,7 +36,7 @@ bool IsEnabled(const PrefService& prefs);
class ContextualSearchPreference {
public:
// No public constructor, use |GetInstance|.
- ~ContextualSearchPreference(){};
+ ~ContextualSearchPreference() {}
// Returns the singleton instance of this class, created when needed.
static ContextualSearchPreference* GetInstance();
diff --git a/chromium/components/crash/content/app/BUILD.gn b/chromium/components/crash/content/app/BUILD.gn
index 5a13a51923a..f71dd88a26b 100644
--- a/chromium/components/crash/content/app/BUILD.gn
+++ b/chromium/components/crash/content/app/BUILD.gn
@@ -66,7 +66,10 @@ static_library("app") {
}
if (is_android) {
- deps += [ "//components/crash/android:jni_headers" ]
+ deps += [
+ "//components/crash/android:jni_headers",
+ "//third_party/crashpad/crashpad/handler",
+ ]
}
if (is_android || is_linux) {
@@ -189,6 +192,46 @@ if (is_win) {
}
}
+if (is_mac) {
+ # We build a chromium-specific crashpad_handler executable so that we can
+ # define custom UserStreamDataSources.
+ executable("chrome_crashpad_handler") {
+ sources = [
+ "chrome_crashpad_handler.cc",
+ ]
+
+ deps = [
+ "//components/gwp_asan/crash_handler",
+ "//third_party/crashpad/crashpad/handler:handler",
+ ]
+
+ if (is_component_build) {
+ ldflags = [
+ # The handler is in
+ # Chromium.app/Contents/Versions/X/Chromium Framework.framework/Versions/A/Helpers/
+ # so set rpath up to the base.
+ "-rpath",
+ "@loader_path/../../../../../../../..",
+
+ # The handler is also in
+ # Content Shell.app/Contents/Frameworks/Content Shell Framework.framework/Versions/C/Helpers/
+ # so set the rpath for that too.
+ "-rpath",
+ "@loader_path/../../../../../../..",
+
+ # The handler can also be executed in an unbundled framework at
+ # Chromium Framework.framework/Versions/A/Helpers/
+ "-rpath",
+ "@loader_path/../../../..",
+
+ # The handler can be executed from headless_browsertests in Helpers/
+ "-rpath",
+ "@loader_path/..",
+ ]
+ }
+ }
+}
+
# This source set provides the functionality required for tests, which on Windows
# link the export thunks directly into the test binary.
source_set("test_support") {
diff --git a/chromium/components/crash/content/app/breakpad_linux.cc b/chromium/components/crash/content/app/breakpad_linux.cc
index a7378204ffa..ecc7d66acb0 100644
--- a/chromium/components/crash/content/app/breakpad_linux.cc
+++ b/chromium/components/crash/content/app/breakpad_linux.cc
@@ -2122,7 +2122,7 @@ bool IsCrashReporterEnabled() {
return g_is_crash_reporter_enabled;
}
-void SetFirstChanceExceptionHandler(bool (*handler)(int, void*, void*)) {
+void SetFirstChanceExceptionHandler(bool (*handler)(int, siginfo_t*, void*)) {
google_breakpad::SetFirstChanceExceptionHandler(handler);
}
diff --git a/chromium/components/crash/content/app/breakpad_linux.h b/chromium/components/crash/content/app/breakpad_linux.h
index 9ee85554812..6e95af6ca7f 100644
--- a/chromium/components/crash/content/app/breakpad_linux.h
+++ b/chromium/components/crash/content/app/breakpad_linux.h
@@ -7,6 +7,7 @@
#ifndef COMPONENTS_CRASH_CONTENT_APP_BREAKPAD_LINUX_H_
#define COMPONENTS_CRASH_CONTENT_APP_BREAKPAD_LINUX_H_
+#include <signal.h>
#include <string>
#include "build/build_config.h"
@@ -67,7 +68,7 @@ void GenerateMinidumpOnDemandForAndroid(int dump_fd);
// Install a handler that gets a change to handle faults before Breakpad does
// any processing. This is used by V8 for trap-based bounds checks.
-void SetFirstChanceExceptionHandler(bool (*handler)(int, void*, void*));
+void SetFirstChanceExceptionHandler(bool (*handler)(int, siginfo_t*, void*));
} // namespace breakpad
#endif // COMPONENTS_CRASH_CONTENT_APP_BREAKPAD_LINUX_H_
diff --git a/chromium/components/crash/content/app/breakpad_win.cc b/chromium/components/crash/content/app/breakpad_win.cc
index dec9daf1fdb..172cf5b6ef6 100644
--- a/chromium/components/crash/content/app/breakpad_win.cc
+++ b/chromium/components/crash/content/app/breakpad_win.cc
@@ -130,7 +130,7 @@ google_breakpad::CustomClientInfo* GetCustomInfo(
custom_entries->push_back(
google_breakpad::CustomInfoEntry(L"ptype", type.c_str()));
custom_entries->push_back(google_breakpad::CustomInfoEntry(
- L"pid", base::IntToString16(::GetCurrentProcessId()).c_str()));
+ L"pid", base::NumberToString16(::GetCurrentProcessId()).c_str()));
custom_entries->push_back(
google_breakpad::CustomInfoEntry(L"channel", channel_name.c_str()));
custom_entries->push_back(
@@ -634,7 +634,7 @@ ClearBreakpadPipeEnvironmentVariable() {
env->UnSetVar(kPipeNameVar);
}
-#ifdef _WIN64
+#ifdef _M_X64
int CrashForExceptionInNonABICompliantCodeRange(
PEXCEPTION_RECORD ExceptionRecord,
ULONG64 EstablisherFrame,
diff --git a/chromium/components/crash/content/app/chrome_crashpad_handler.cc b/chromium/components/crash/content/app/chrome_crashpad_handler.cc
new file mode 100644
index 00000000000..24a83887ac8
--- /dev/null
+++ b/chromium/components/crash/content/app/chrome_crashpad_handler.cc
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "components/gwp_asan/crash_handler/crash_handler.h"
+#include "third_party/crashpad/crashpad/handler/handler_main.h"
+#include "third_party/crashpad/crashpad/handler/user_stream_data_source.h"
+
+int main(int argc, char* argv[]) {
+ crashpad::UserStreamDataSources user_stream_data_sources;
+ user_stream_data_sources.push_back(
+ std::make_unique<gwp_asan::UserStreamDataSource>());
+
+ return crashpad::HandlerMain(argc, argv, &user_stream_data_sources);
+}
diff --git a/chromium/components/crash/content/app/crash_export_stubs.cc b/chromium/components/crash/content/app/crash_export_stubs.cc
index 3ff51649906..a4080e3c6a9 100644
--- a/chromium/components/crash/content/app/crash_export_stubs.cc
+++ b/chromium/components/crash/content/app/crash_export_stubs.cc
@@ -35,6 +35,8 @@ const wchar_t* GetCrashpadDatabasePath_ExportThunk() {
return nullptr;
}
+void ClearReportsBetween_ExportThunk(time_t begin, time_t end) {}
+
bool DumpHungProcessWithPtype_ExportThunk(HANDLE process_handle,
const char* ptype) {
return false;
diff --git a/chromium/components/crash/content/app/crash_export_thunks.cc b/chromium/components/crash/content/app/crash_export_thunks.cc
index 5a4e3f1781d..039f1806256 100644
--- a/chromium/components/crash/content/app/crash_export_thunks.cc
+++ b/chromium/components/crash/content/app/crash_export_thunks.cc
@@ -66,6 +66,10 @@ const wchar_t* GetCrashpadDatabasePath_ExportThunk() {
return crash_reporter::GetCrashpadDatabasePathImpl();
}
+void ClearReportsBetween_ExportThunk(time_t begin, time_t end) {
+ crash_reporter::ClearReportsBetweenImpl(begin, end);
+}
+
bool DumpHungProcessWithPtype_ExportThunk(HANDLE process_handle,
const char* ptype) {
base::Process process(process_handle);
diff --git a/chromium/components/crash/content/app/crash_export_thunks.h b/chromium/components/crash/content/app/crash_export_thunks.h
index e676e8ccc01..85c5c03e794 100644
--- a/chromium/components/crash/content/app/crash_export_thunks.h
+++ b/chromium/components/crash/content/app/crash_export_thunks.h
@@ -6,6 +6,7 @@
#define COMPONENTS_CRASH_CONTENT_APP_CRASH_EXPORT_THUNKS_H_
#include <stddef.h>
+#include <time.h>
#include <windows.h>
#include "build/build_config.h"
@@ -58,6 +59,10 @@ HANDLE InjectDumpForHungInput_ExportThunk(HANDLE process);
// Returns the crashpad database path.
const wchar_t* GetCrashpadDatabasePath_ExportThunk();
+// This function may be invoked across module boundaries to delete reports
+// within the time range. See crash_reporter::ClearReportsBetween.
+void ClearReportsBetween_ExportThunk(time_t begin, time_t end);
+
// Immediately dump |process| to a crash dump adorned with |ptype|.
// Takes ownership of |process|, does not kill nor affect the exit code of
// |process|.
diff --git a/chromium/components/crash/content/app/crashpad.cc b/chromium/components/crash/content/app/crashpad.cc
index a04a4d84300..5eba3742684 100644
--- a/chromium/components/crash/content/app/crashpad.cc
+++ b/chromium/components/crash/content/app/crashpad.cc
@@ -24,6 +24,8 @@
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "components/crash/content/app/crash_reporter_client.h"
#include "third_party/crashpad/crashpad/client/annotation.h"
@@ -164,11 +166,14 @@ void InitializeCrashpadImpl(bool initial_client,
static crashpad::StringAnnotation<12> pid_key("pid");
#if defined(OS_POSIX)
- pid_key.Set(base::IntToString(getpid()));
+ pid_key.Set(base::NumberToString(getpid()));
#elif defined(OS_WIN)
- pid_key.Set(base::IntToString(::GetCurrentProcessId()));
+ pid_key.Set(base::NumberToString(::GetCurrentProcessId()));
#endif
+ static crashpad::StringAnnotation<24> osarch_key("osarch");
+ osarch_key.Set(base::SysInfo::OperatingSystemArchitecture());
+
logging::SetLogMessageHandler(LogMessageHandler);
// If clients called CRASHPAD_SIMULATE_CRASH() instead of
@@ -325,6 +330,14 @@ base::FilePath GetCrashpadDatabasePath() {
#endif
}
+void ClearReportsBetween(const base::Time& begin, const base::Time& end) {
+#if defined(OS_WIN)
+ ClearReportsBetween_ExportThunk(begin.ToTimeT(), end.ToTimeT());
+#else
+ ClearReportsBetweenImpl(begin.ToTimeT(), end.ToTimeT());
+#endif
+}
+
void GetReportsImpl(std::vector<Report>* reports) {
reports->clear();
@@ -400,6 +413,21 @@ base::FilePath::StringType::const_pointer GetCrashpadDatabasePathImpl() {
return g_database_path->value().c_str();
}
+void ClearReportsBetweenImpl(time_t begin, time_t end) {
+ std::vector<Report> reports;
+ GetReports(&reports);
+ for (const Report& report : reports) {
+ // Delete if either time lies in the range, as they both reveal that the
+ // browser was open.
+ if ((begin <= report.capture_time && report.capture_time <= end) ||
+ (begin <= report.upload_time && report.upload_time <= end)) {
+ crashpad::UUID uuid;
+ uuid.InitializeFromString(report.local_id);
+ g_database->DeleteReport(uuid);
+ }
+ }
+}
+
namespace internal {
crashpad::CrashReportDatabase* GetCrashReportDatabase() {
diff --git a/chromium/components/crash/content/app/crashpad.h b/chromium/components/crash/content/app/crashpad.h
index c16f6b87b38..2a2675cf6f0 100644
--- a/chromium/components/crash/content/app/crashpad.h
+++ b/chromium/components/crash/content/app/crashpad.h
@@ -21,6 +21,10 @@
#include <windows.h>
#endif
+namespace base {
+class Time;
+}
+
namespace crashpad {
class CrashpadClient;
class CrashReportDatabase;
@@ -139,6 +143,9 @@ void CrashWithoutDumping(const std::string& message);
// Returns the Crashpad database path, only valid in the browser.
base::FilePath GetCrashpadDatabasePath();
+// Deletes any reports that were recorded or uploaded within the time range.
+void ClearReportsBetween(const base::Time& begin, const base::Time& end);
+
// The implementation function for GetReports.
void GetReportsImpl(std::vector<Report>* reports);
@@ -148,6 +155,9 @@ void RequestSingleCrashUploadImpl(const std::string& local_id);
// The implementation function for GetCrashpadDatabasePath.
base::FilePath::StringType::const_pointer GetCrashpadDatabasePathImpl();
+// The implementation function for ClearReportsBetween.
+void ClearReportsBetweenImpl(time_t begin, time_t end);
+
#if defined(OS_MACOSX)
// Captures a minidump for the process named by its |task_port| and stores it
// in the current crash report database.
diff --git a/chromium/components/crash/content/app/crashpad_linux.cc b/chromium/components/crash/content/app/crashpad_linux.cc
index 1c1c80bc92d..8e4764503da 100644
--- a/chromium/components/crash/content/app/crashpad_linux.cc
+++ b/chromium/components/crash/content/app/crashpad_linux.cc
@@ -4,6 +4,7 @@
#include "components/crash/content/app/crashpad.h"
+#include <dlfcn.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -247,6 +248,33 @@ void SetBuildInfoAnnotations(std::map<std::string, std::string>* annotations) {
}
}
+// Constructs paths to a handler trampoline executable and a library exporting
+// the symbol `CrashpadHandlerMain()`. This requires this function to be built
+// into the same object exporting this symbol and the handler trampoline is
+// adjacent to it.
+bool GetHandlerTrampoline(std::string* handler_trampoline,
+ std::string* handler_library) {
+ Dl_info info;
+ if (dladdr(reinterpret_cast<void*>(&GetHandlerTrampoline), &info) == 0) {
+ return false;
+ }
+
+ std::string local_handler_library(info.dli_fname);
+
+ size_t libdir_end = local_handler_library.rfind('/');
+ if (libdir_end == std::string::npos) {
+ return false;
+ }
+
+ std::string local_handler_trampoline(local_handler_library, 0,
+ libdir_end + 1);
+ local_handler_trampoline += "libcrashpad_handler_trampoline.so";
+
+ handler_trampoline->swap(local_handler_trampoline);
+ handler_library->swap(local_handler_library);
+ return true;
+}
+
#if defined(__arm__) && defined(__ARM_ARCH_7A__)
#define CURRENT_ABI "armeabi-v7a"
#elif defined(__arm__)
@@ -282,7 +310,8 @@ void MakePackagePaths(std::string* classpath, std::string* libpath) {
// Copies and extends the current environment with CLASSPATH and LD_LIBRARY_PATH
// set to library paths in the APK.
-bool BuildEnvironmentWithApk(std::vector<std::string>* result) {
+bool BuildEnvironmentWithApk(bool use_64_bit,
+ std::vector<std::string>* result) {
DCHECK(result->empty());
std::string classpath;
@@ -300,6 +329,12 @@ bool BuildEnvironmentWithApk(std::vector<std::string>* result) {
env->GetVar(kLdLibraryPathVar, &current_library_path);
library_path += ":" + current_library_path;
+ static constexpr char kRuntimeRootVar[] = "ANDROID_RUNTIME_ROOT";
+ std::string runtime_root;
+ if (env->GetVar(kRuntimeRootVar, &runtime_root)) {
+ library_path += ":" + runtime_root + (use_64_bit ? "/lib64" : "/lib");
+ }
+
result->push_back("CLASSPATH=" + classpath);
result->push_back("LD_LIBRARY_PATH=" + library_path);
for (char** envp = environ; *envp != nullptr; ++envp) {
@@ -415,6 +450,19 @@ bool SetLdLibraryPath(const base::FilePath& lib_path) {
}
class HandlerStarter {
+#if defined(OS_ANDROID)
+ // TODO(jperaza): Currently only launching a same-bitness handler is
+ // supported. The logic to build package paths, locate a handler executable,
+ // and the crashpad client interface for launching a Java handler need to be
+ // updated to use a specified bitness before a cross-bitness handler can be
+ // used.
+#if defined(ARCH_CPU_64_BITS)
+ static constexpr bool kUse64Bit = true;
+#else
+ static constexpr bool kUse64Bit = false;
+#endif
+#endif // OS_ANDROID
+
public:
static HandlerStarter* Get() {
static HandlerStarter* instance = new HandlerStarter();
@@ -443,26 +491,41 @@ class HandlerStarter {
}
#if defined(OS_ANDROID)
+ std::string browser_ptype;
+ if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
+ process_annotations["ptype"] = browser_ptype;
+ }
+
if (!base::PathExists(handler_path)) {
- use_java_handler_ = true;
+ // The linker doesn't support loading executables passed on its command
+ // line until Q.
+ if (base::android::BuildInfo::GetInstance()->is_at_least_q()) {
+ bool found_library =
+ GetHandlerTrampoline(&handler_trampoline_, &handler_library_);
+ DCHECK(found_library);
+ } else {
+ use_java_handler_ = true;
+ }
}
if (!dump_at_crash) {
return database_path;
}
- if (use_java_handler_) {
+ if (use_java_handler_ || !handler_trampoline_.empty()) {
std::vector<std::string> env;
- if (!BuildEnvironmentWithApk(&env)) {
+ if (!BuildEnvironmentWithApk(kUse64Bit, &env)) {
return database_path;
}
- // TODO(jperaza): The logic for constructing an appropriate
- // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
- // need to be launched by executing the dynamic linker instead.
- bool result = GetCrashpadClient().StartJavaHandlerAtCrash(
- kCrashpadJavaMain, &env, database_path, metrics_path, url,
- process_annotations, arguments);
+ bool result = use_java_handler_
+ ? GetCrashpadClient().StartJavaHandlerAtCrash(
+ kCrashpadJavaMain, &env, database_path,
+ metrics_path, url, process_annotations, arguments)
+ : GetCrashpadClient().StartHandlerWithLinkerAtCrash(
+ handler_trampoline_, handler_library_, kUse64Bit,
+ &env, database_path, metrics_path, url,
+ process_annotations, arguments);
DCHECK(result);
return database_path;
}
@@ -488,13 +551,6 @@ class HandlerStarter {
BuildHandlerArgs(client, &database_path, &metrics_path, &url,
&process_annotations, &arguments);
-#if defined(OS_ANDROID)
- std::string browser_ptype;
- if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
- process_annotations["ptype"] = browser_ptype;
- }
-#endif // defined(OS_ANDROID)
-
base::FilePath exe_dir;
base::FilePath handler_path;
if (!GetHandlerPath(&exe_dir, &handler_path)) {
@@ -502,18 +558,21 @@ class HandlerStarter {
}
#if defined(OS_ANDROID)
- if (use_java_handler_) {
+ if (use_java_handler_ || !handler_trampoline_.empty()) {
std::vector<std::string> env;
- if (!BuildEnvironmentWithApk(&env)) {
+ if (!BuildEnvironmentWithApk(kUse64Bit, &env)) {
return false;
}
- // TODO(jperaza): The logic for constructing an appropriate
- // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
- // need to be launched by executing the dynamic linker instead.
- bool result = GetCrashpadClient().StartJavaHandlerForClient(
- kCrashpadJavaMain, &env, database_path, metrics_path, url,
- process_annotations, arguments, fd);
+ bool result =
+ use_java_handler_
+ ? GetCrashpadClient().StartJavaHandlerForClient(
+ kCrashpadJavaMain, &env, database_path, metrics_path, url,
+ process_annotations, arguments, fd)
+ : GetCrashpadClient().StartHandlerWithLinkerForClient(
+ handler_trampoline_, handler_library_, kUse64Bit, &env,
+ database_path, metrics_path, url, process_annotations,
+ arguments, fd);
return result;
}
#endif
@@ -533,6 +592,8 @@ class HandlerStarter {
crashpad::SanitizationInformation browser_sanitization_info_;
#if defined(OS_ANDROID)
+ std::string handler_trampoline_;
+ std::string handler_library_;
bool use_java_handler_ = false;
#endif
diff --git a/chromium/components/crash/content/app/crashpad_mac.mm b/chromium/components/crash/content/app/crashpad_mac.mm
index f079174b358..a76d264648d 100644
--- a/chromium/components/crash/content/app/crashpad_mac.mm
+++ b/chromium/components/crash/content/app/crashpad_mac.mm
@@ -124,7 +124,8 @@ base::FilePath PlatformCrashpadInitialization(
@autoreleasepool {
base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
base::FilePath handler_path =
- framework_bundle_path.Append("Helpers").Append("crashpad_handler");
+ framework_bundle_path.Append("Helpers").Append(
+ "chrome_crashpad_handler");
// Is there a way to recover if this fails?
CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
diff --git a/chromium/components/crash/content/app/fallback_crash_handler_launcher_win.cc b/chromium/components/crash/content/app/fallback_crash_handler_launcher_win.cc
index 453ff606d8e..947bb0cb267 100644
--- a/chromium/components/crash/content/app/fallback_crash_handler_launcher_win.cc
+++ b/chromium/components/crash/content/app/fallback_crash_handler_launcher_win.cc
@@ -54,7 +54,7 @@ bool FallbackCrashHandlerLauncher::Initialize(
"exception-pointers",
base::NumberToString(reinterpret_cast<uintptr_t>(&exception_pointers_)));
cmd_line.AppendSwitchASCII(
- "process", base::UintToString(
+ "process", base::NumberToString(
base::win::HandleToUint32(self_process_handle_.Get())));
std::wstring str_cmd_line = cmd_line.GetCommandLineString();
diff --git a/chromium/components/crash/content/app/fallback_crash_handler_win.cc b/chromium/components/crash/content/app/fallback_crash_handler_win.cc
index c04570dae6a..56677a2df22 100644
--- a/chromium/components/crash/content/app/fallback_crash_handler_win.cc
+++ b/chromium/components/crash/content/app/fallback_crash_handler_win.cc
@@ -59,9 +59,9 @@ void AcquireMemoryMetrics(const base::Process& process,
// of system pages.
crash_keys->insert(std::make_pair(
"SystemCommitRemaining",
- base::UintToString(perf_info.CommitLimit - perf_info.CommitTotal)));
+ base::NumberToString(perf_info.CommitLimit - perf_info.CommitTotal)));
crash_keys->insert(std::make_pair(
- "SystemCommitLimit", base::UintToString(perf_info.CommitLimit)));
+ "SystemCommitLimit", base::NumberToString(perf_info.CommitLimit)));
}
}
diff --git a/chromium/components/crash/content/app/fallback_crash_handler_win_unittest.cc b/chromium/components/crash/content/app/fallback_crash_handler_win_unittest.cc
index 28950a24e9e..e21fecbe07d 100644
--- a/chromium/components/crash/content/app/fallback_crash_handler_win_unittest.cc
+++ b/chromium/components/crash/content/app/fallback_crash_handler_win_unittest.cc
@@ -120,7 +120,7 @@ class FallbackCrashHandlerWinTest : public testing::Test {
}
std::string SelfHandleAsString() const {
- return base::UintToString(base::win::HandleToUint32(self_handle_));
+ return base::NumberToString(base::win::HandleToUint32(self_handle_));
}
void CreateDatabase() {
@@ -155,7 +155,7 @@ TEST_F(FallbackCrashHandlerWinTest, ParseCommandLine) {
ASSERT_FALSE(handler.ParseCommandLine(cmd_line));
cmd_line.AppendSwitchASCII(
- "thread", base::UintToString(base::PlatformThread::CurrentId()));
+ "thread", base::NumberToString(base::PlatformThread::CurrentId()));
// Should succeed with a fully populated command line.
// Because of how handle ownership is guarded, we have to "disown" it before
diff --git a/chromium/components/crash/content/browser/child_exit_observer_android.cc b/chromium/components/crash/content/browser/child_exit_observer_android.cc
index cd62274d372..595a5274487 100644
--- a/chromium/components/crash/content/browser/child_exit_observer_android.cc
+++ b/chromium/components/crash/content/browser/child_exit_observer_android.cc
@@ -139,7 +139,8 @@ void ChildExitObserver::BrowserChildProcessHostDisconnected(
browser_child_process_info_.erase(it);
} else {
info.process_host_id = data.id;
- info.pid = data.GetProcess().Pid();
+ if (data.GetProcess().IsValid())
+ info.pid = data.GetProcess().Pid();
info.process_type = static_cast<content::ProcessType>(data.process_type);
info.app_state = base::android::ApplicationStatusListener::GetState();
info.normal_termination = true;
diff --git a/chromium/components/crash/content/browser/child_exit_observer_android.h b/chromium/components/crash/content/browser/child_exit_observer_android.h
index 161d2e88f04..1059f0c4493 100644
--- a/chromium/components/crash/content/browser/child_exit_observer_android.h
+++ b/chromium/components/crash/content/browser/child_exit_observer_android.h
@@ -47,6 +47,8 @@ class ChildExitObserver : public content::BrowserChildProcessObserver,
bool is_crashed() const { return crash_signo != kInvalidSigno; }
int process_host_id = content::ChildProcessHost::kInvalidUniqueID;
+ // |pid| may not be valid if termination happens before the process has
+ // finished launching.
base::ProcessHandle pid = base::kNullProcessHandle;
content::ProcessType process_type = content::PROCESS_TYPE_UNKNOWN;
base::android::ApplicationState app_state =
diff --git a/chromium/components/crash/content/browser/child_process_crash_observer_android.cc b/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
index cd46b75b334..33451d4efc7 100644
--- a/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
+++ b/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -36,7 +36,7 @@ void ChildProcessCrashObserver::OnChildExitImpl(
return;
}
- base::ScopedBlockingCall sbc(base::BlockingType::WILL_BLOCK);
+ base::ScopedBlockingCall sbc(FROM_HERE, base::BlockingType::WILL_BLOCK);
// 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
diff --git a/chromium/components/crash/content/browser/crash_handler_host_linux.cc b/chromium/components/crash/content/browser/crash_handler_host_linux.cc
index 13cf0e84db6..61bdd5df60d 100644
--- a/chromium/components/crash/content/browser/crash_handler_host_linux.cc
+++ b/chromium/components/crash/content/browser/crash_handler_host_linux.cc
@@ -411,7 +411,8 @@ void CrashHandlerHostLinux::FindCrashingThreadAndDump(
void CrashHandlerHostLinux::WriteDumpFile(BreakpadInfo* info,
std::unique_ptr<char[]> crash_context,
pid_t crashing_pid) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
// Set |info->distro| here because base::GetLinuxDistro() needs to run on a
// blocking sequence.
diff --git a/chromium/components/crash/core/browser/resources/crashes.html b/chromium/components/crash/core/browser/resources/crashes.html
index f6b80a7475b..e969cb13fc0 100644
--- a/chromium/components/crash/core/browser/resources/crashes.html
+++ b/chromium/components/crash/core/browser/resources/crashes.html
@@ -19,8 +19,8 @@
<script src="chrome://resources/js/action_link.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
- <script src="chrome://crashes/strings.js"></script>
- <script src="chrome://crashes/crashes.js"></script>
+ <script src="strings.js"></script>
+ <script src="crashes.js"></script>
</head>
<body>
<header><h1>$i18n{crashesTitle}</h1></header>
@@ -38,7 +38,6 @@
<div id="crashList"></div>
<p id="noCrashes" hidden>$i18n{noCrashesMessage}</p>
</div>
- <script src="chrome://resources/js/i18n_template.js"></script>
<script src="chrome://resources/js/jstemplate_compiled.js"></script>
</body>
</html>
diff --git a/chromium/components/crash/core/common/BUILD.gn b/chromium/components/crash/core/common/BUILD.gn
index 81912a5691c..8e2a6968525 100644
--- a/chromium/components/crash/core/common/BUILD.gn
+++ b/chromium/components/crash/core/common/BUILD.gn
@@ -65,8 +65,11 @@ target(crash_key_target_type, "crash_key") {
]
}
- deps = [
+ public_deps = [
":crash_buildflags",
+ ]
+
+ deps = [
"//base",
]
diff --git a/chromium/components/crash/core/common/crash_key.cc b/chromium/components/crash/core/common/crash_key.cc
index 1e2952dfcf7..7acaed36724 100644
--- a/chromium/components/crash/core/common/crash_key.cc
+++ b/chromium/components/crash/core/common/crash_key.cc
@@ -4,6 +4,7 @@
#include "components/crash/core/common/crash_key.h"
+#include "base/debug/stack_trace.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
diff --git a/chromium/components/crash/core/common/crash_key.h b/chromium/components/crash/core/common/crash_key.h
index f27b6eb67f9..a38e24ca14d 100644
--- a/chromium/components/crash/core/common/crash_key.h
+++ b/chromium/components/crash/core/common/crash_key.h
@@ -9,7 +9,6 @@
#include <string>
-#include "base/debug/stack_trace.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
@@ -24,6 +23,12 @@
#include "third_party/crashpad/crashpad/client/annotation.h" // nogncheck
#endif
+namespace base {
+namespace debug {
+class StackTrace;
+} // namespace debug
+} // namespace base
+
namespace crash_reporter {
class CrashKeyBreakpadTest;
diff --git a/chromium/components/cronet/BUILD.gn b/chromium/components/cronet/BUILD.gn
index 794bad117d3..df22474fde0 100644
--- a/chromium/components/cronet/BUILD.gn
+++ b/chromium/components/cronet/BUILD.gn
@@ -217,7 +217,7 @@ if (!is_ios && !is_android) {
# Copy boiler-plate files into the package.
copy("cronet_package_copy") {
sources = [
- "$root_out_dir/$_cronet_shared_lib_file_name",
+ "${root_out_dir}${shlib_subdir}/${_cronet_shared_lib_file_name}",
"//AUTHORS",
"//chrome/VERSION",
]
diff --git a/chromium/components/cronet/android/BUILD.gn b/chromium/components/cronet/android/BUILD.gn
index e21e8b98e7f..84b080a9f7c 100644
--- a/chromium/components/cronet/android/BUILD.gn
+++ b/chromium/components/cronet/android/BUILD.gn
@@ -789,6 +789,7 @@ if (!is_component_build) {
"//net/android:net_java",
"//net/android:net_java_test_support",
"//url:url_java",
+ "//third_party/junit",
]
android_library("cronet_javatests") {
@@ -843,7 +844,6 @@ if (!is_component_build) {
":cronet_urlconnection_impl_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/hamcrest:hamcrest_core_java",
- "//third_party/junit",
]
deps += cronet_javatests_deps_to_package
data = [
diff --git a/chromium/components/cronet/native/BUILD.gn b/chromium/components/cronet/native/BUILD.gn
index a281e8c0ae0..539b40e8178 100644
--- a/chromium/components/cronet/native/BUILD.gn
+++ b/chromium/components/cronet/native/BUILD.gn
@@ -41,6 +41,7 @@ source_set("cronet_native_impl") {
"//base",
"//components/cronet:cronet_common",
"//components/cronet:cronet_version_header",
+ "//components/cronet:metrics_util",
"//components/grpc_support:grpc_support",
"//net",
]
@@ -57,6 +58,8 @@ source_set("cronet_native_impl") {
"engine.h",
"io_buffer_with_cronet_buffer.cc",
"io_buffer_with_cronet_buffer.h",
+ "native_metrics_util.cc",
+ "native_metrics_util.h",
"runnables.cc",
"runnables.h",
"upload_data_sink.cc",
@@ -77,6 +80,7 @@ source_set("cronet_native_unittests") {
deps = [
":cronet_native_impl",
+ "//base/test:test_support",
"//components/cronet/native/test:cronet_native_testutil",
"//net:test_support",
"//testing/gtest",
@@ -85,6 +89,7 @@ source_set("cronet_native_unittests") {
configs += [ ":cronet_native_include_config" ]
sources = [
+ "native_metrics_util_test.cc",
"runnables_unittest.cc",
# Generated from cronet.idl.
diff --git a/chromium/components/data_reduction_proxy/DEPS b/chromium/components/data_reduction_proxy/DEPS
index 136e1906355..3f3525be8c4 100644
--- a/chromium/components/data_reduction_proxy/DEPS
+++ b/chromium/components/data_reduction_proxy/DEPS
@@ -2,7 +2,6 @@ include_rules = [
"+components/data_use_measurement/core",
"+components/pref_registry",
"+components/prefs",
- "+components/previews",
"+components/variations",
"+crypto",
"+google_apis",
@@ -10,6 +9,8 @@ include_rules = [
"+net",
"+services/network/public/cpp",
+ "-components"
+
# Data Reduction Proxy is a layered component; subdirectories must explicitly
# introduce the ability to use the content layer as appropriate.
"-components/data_reduction_proxy/content",
diff --git a/chromium/components/data_reduction_proxy/content/DEPS b/chromium/components/data_reduction_proxy/content/DEPS
index 774faa6d5a0..a72f56aa158 100644
--- a/chromium/components/data_reduction_proxy/content/DEPS
+++ b/chromium/components/data_reduction_proxy/content/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+components/data_reduction_proxy/core/browser",
"+components/data_reduction_proxy/core/common",
"+components/keyed_service",
+ "+components/previews",
"+components/user_prefs",
"+content/public/browser",
"+content/public/common",
diff --git a/chromium/components/data_reduction_proxy/content/browser/BUILD.gn b/chromium/components/data_reduction_proxy/content/browser/BUILD.gn
index 1e02ba706f8..8984e3d6225 100644
--- a/chromium/components/data_reduction_proxy/content/browser/BUILD.gn
+++ b/chromium/components/data_reduction_proxy/content/browser/BUILD.gn
@@ -10,6 +10,8 @@ static_library("browser") {
"content_lofi_ui_service.h",
"content_resource_type_provider.cc",
"content_resource_type_provider.h",
+ "data_reduction_proxy_page_load_timing.cc",
+ "data_reduction_proxy_page_load_timing.h",
"data_reduction_proxy_pingback_client_impl.cc",
"data_reduction_proxy_pingback_client_impl.h",
]
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 bcdd2848401..04cc9397134 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
@@ -57,7 +57,7 @@ ContentLoFiDecider::DetermineCommittedServerPreviewsState(
void ContentLoFiDecider::MaybeSetAcceptTransformHeader(
const net::URLRequest& request,
net::HttpRequestHeaders* headers) const {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
if (!request_info)
@@ -76,7 +76,7 @@ void ContentLoFiDecider::RemoveAcceptTransformHeader(
bool ContentLoFiDecider::IsClientLoFiImageRequest(
const net::URLRequest& request) const {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
return request_info &&
request_info->GetResourceType() == content::RESOURCE_TYPE_IMAGE &&
@@ -85,7 +85,7 @@ bool ContentLoFiDecider::IsClientLoFiImageRequest(
bool ContentLoFiDecider::IsClientLoFiAutoReloadRequest(
const net::URLRequest& request) const {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
return request_info &&
(request_info->GetPreviewsState() & content::CLIENT_LOFI_AUTO_RELOAD);
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 044de4bb192..5696fd8a59d 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
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/stl_util.h"
@@ -104,7 +105,7 @@ class ContentLoFiDeciderTest : public testing::Test {
content::ResourceRequestInfo::AllocateForTesting(
request, resource_type, nullptr, -1, -1, -1,
resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
- false, // allow_download
+ content::ResourceInterceptPolicy::kAllowNone,
false, // is_async
previews_state,
nullptr); // navigation_ui_data
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 7fa8efb24c6..d1ed6bc2f1b 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
@@ -74,8 +74,7 @@ class ContentLoFiUIServiceTest : public content::RenderViewHostTestHarness {
request.get(), content::RESOURCE_TYPE_SUB_FRAME, nullptr,
web_contents()->GetMainFrame()->GetProcess()->GetID(), -1,
web_contents()->GetMainFrame()->GetRoutingID(),
- /*is_main_frame=*/false,
- /*allow_download=*/false,
+ /*is_main_frame=*/false, content::ResourceInterceptPolicy::kAllowNone,
/*is_async=*/false, content::SERVER_LOFI_ON,
/*navigation_ui_data*/ nullptr);
diff --git a/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider.cc b/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider.cc
index 94b24feefa9..aa5bc913eb3 100644
--- a/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/content_resource_type_provider.cc
@@ -20,7 +20,7 @@ static const size_t kMaxCacheSize = 15;
// Returns the content type of |request|.
ResourceTypeProvider::ContentType GetContentTypeInternal(
const net::URLRequest& request) {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
if (!request_info)
@@ -70,7 +70,7 @@ void ContentResourceTypeProvider::SetContentType(
bool ContentResourceTypeProvider::IsNonContentInitiatedRequest(
const net::URLRequest& request) const {
- const auto* resource_request_info =
+ auto* resource_request_info =
content::ResourceRequestInfo::ForRequest(&request);
return !resource_request_info ||
(resource_request_info->GetGlobalRequestID() ==
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 86baaaf0343..1832a00b63c 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
@@ -104,7 +104,7 @@ class ContentResourceProviderTest : public testing::Test {
content::ResourceRequestInfo::AllocateForTesting(
request, resource_type, nullptr, -1, -1, -1,
resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
- false, // allow_download
+ content::ResourceInterceptPolicy::kAllowNone,
false, // is_async
content::PREVIEWS_OFF,
nullptr); // navigation_ui_data
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.cc
index 02c1da9d61c..8620c1975e1 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.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/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
+#include "components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h"
namespace data_reduction_proxy {
diff --git a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h
index 3f649ba779d..e02fc680f8e 100644
--- a/chromium/components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h
+++ b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.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_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H
-#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_CONTENT_BROWSER_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_CONTENT_BROWSER_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H_
#include <stdint.h>
@@ -114,4 +114,4 @@ struct DataReductionProxyPageLoadTiming {
} // namespace data_reduction_proxy
-#endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_COMMON_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H
+#endif // COMPONENTS_DATA_REDUCTION_PROXY_CONTENT_BROWSER_DATA_REDUCTION_PROXY_PAGE_LOAD_TIMING_H_
diff --git a/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc
index 5302c9c6168..4f2271bd5fc 100644
--- a/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <string>
+#include "base/bind.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
@@ -15,12 +16,13 @@
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/time/time.h"
+#include "components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/previews/core/previews_lite_page_redirect.h"
#include "components/variations/net/variations_http_headers.h"
#include "content/public/common/child_process_host.h"
#include "net/base/load_flags.h"
@@ -35,6 +37,27 @@ namespace data_reduction_proxy {
namespace {
+// Returns the HTTPSLitePagePreviewInfo_Status for a
+// |previews::ServerLitePageStatus|.
+HTTPSLitePagePreviewInfo_Status
+ProtoLitePageRedirectStatusFromLitePageRedirectStatus(
+ previews::ServerLitePageStatus status) {
+ switch (status) {
+ case previews::ServerLitePageStatus::kUnknown:
+ return HTTPSLitePagePreviewInfo_Status_UNKNOWN;
+ case previews::ServerLitePageStatus::kSuccess:
+ return HTTPSLitePagePreviewInfo_Status_SUCCESS;
+ case previews::ServerLitePageStatus::kBypass:
+ return HTTPSLitePagePreviewInfo_Status_BYPASS;
+ case previews::ServerLitePageStatus::kRedirect:
+ return HTTPSLitePagePreviewInfo_Status_REDIRECT;
+ case previews::ServerLitePageStatus::kFailure:
+ return HTTPSLitePagePreviewInfo_Status_FAILURE;
+ case previews::ServerLitePageStatus::kControl:
+ return HTTPSLitePagePreviewInfo_Status_CONTROL;
+ }
+}
+
static const char kHistogramSucceeded[] =
"DataReductionProxy.Pingback.Succeeded";
static const char kHistogramAttempted[] =
@@ -145,9 +168,8 @@ void AddDataToPageloadMetrics(const DataReductionProxyData& request_data,
protobuf_parser::CreateDurationFromTimeDelta(
timing.lite_page_redirect_penalty.value())
.release());
- info->set_status(
- protobuf_parser::ProtoLitePageRedirectStatusFromLitePageRedirectStatus(
- timing.lite_page_redirect_status.value()));
+ info->set_status(ProtoLitePageRedirectStatusFromLitePageRedirectStatus(
+ timing.lite_page_redirect_status.value()));
}
request->set_effective_connection_type(
@@ -428,9 +450,9 @@ void DataReductionProxyPingbackClientImpl::CreateLoaderForDataAndStart() {
net::LOAD_DO_NOT_SAVE_COOKIES;
resource_request->method = "POST";
// Attach variations headers.
- variations::AppendVariationHeaders(
+ variations::AppendVariationsHeader(
pingback_url_, variations::InIncognito::kNo, variations::SignedIn::kNo,
- &resource_request->headers);
+ resource_request.get());
// TODO(https://crbug.com/808498): Re-add data use measurement once
// SimpleURLLoader supports it.
// ID=data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY
diff --git a/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
index 19b5ec07d41..b3881966cdd 100644
--- a/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
+++ b/chromium/components/data_reduction_proxy/content/browser/data_reduction_proxy_pingback_client_impl_unittest.cc
@@ -21,9 +21,9 @@
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
+#include "components/data_reduction_proxy/content/browser/data_reduction_proxy_page_load_timing.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h"
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.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"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
diff --git a/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.cc b/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.cc
index 793067d82a7..67db6a63bae 100644
--- a/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.cc
+++ b/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.cc
@@ -4,6 +4,7 @@
#include "components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h"
+#include "base/bind.h"
#include "components/data_reduction_proxy/content/common/header_util.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_bypass_protocol.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
@@ -75,6 +76,7 @@ void DataReductionProxyURLLoaderThrottle::BeforeWillProcessResponse(
if (params::IsWarmupURL(response_url))
return;
+ before_will_process_response_received_ = true;
MaybeRetry(proxy_server, response_head.headers.get(), net::OK, defer);
}
@@ -136,8 +138,10 @@ void DataReductionProxyURLLoaderThrottle::WillProcessResponse(
void DataReductionProxyURLLoaderThrottle::WillOnCompleteWithError(
const network::URLLoaderCompletionStatus& status,
bool* defer) {
- MaybeRetry(status.proxy_server, nullptr,
- static_cast<net::Error>(status.error_code), defer);
+ if (!before_will_process_response_received_) {
+ MaybeRetry(status.proxy_server, nullptr,
+ static_cast<net::Error>(status.error_code), defer);
+ }
}
void DataReductionProxyURLLoaderThrottle::MarkProxiesAsBad(
diff --git a/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h b/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h
index d8d7edaf02b..bd99a5005b2 100644
--- a/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h
+++ b/chromium/components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle.h
@@ -87,6 +87,9 @@ class DataReductionProxyURLLoaderThrottle : public content::URLLoaderThrottle {
// The final load flags used to complete the request.
int final_load_flags_ = 0;
+ // True if BeforeWillProcessResponse has been called.
+ bool before_will_process_response_received_ = false;
+
base::WeakPtrFactory<DataReductionProxyURLLoaderThrottle> weak_factory_{this};
};
diff --git a/chromium/components/data_reduction_proxy/core/browser/BUILD.gn b/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
index 767626b1936..a50825d0a81 100644
--- a/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
+++ b/chromium/components/data_reduction_proxy/core/browser/BUILD.gn
@@ -71,7 +71,6 @@ if (is_android) {
"//components/data_use_measurement/core:ascriber",
"//components/pref_registry",
"//components/prefs",
- "//components/previews/core",
"//components/variations",
"//components/variations/net",
"//content/public/browser",
@@ -107,7 +106,6 @@ static_library("browser") {
"//components/data_use_measurement/core:ascriber",
"//components/pref_registry",
"//components/prefs",
- "//components/previews/core",
"//components/variations",
"//components/variations/net",
"//content/public/browser",
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 1983e3ea118..cd6eade5e31 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
@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/containers/span.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
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 c186174eeab..3279d3cfc65 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
@@ -71,7 +71,7 @@ void MaintainContentLengthPrefsWindow(base::ListValue* list, size_t length) {
// Newly added lists are empty. Add entries to back to fill the window,
// each initialized to zero.
while (list->GetSize() < length)
- list->AppendString(base::Int64ToString(0));
+ list->AppendString(base::NumberToString(0));
DCHECK_EQ(length, list->GetSize());
}
@@ -83,7 +83,7 @@ void AddInt64ToListPref(size_t index,
base::ListValue* list_update) {
int64_t value = GetInt64PrefValue(*list_update, index) + length;
list_update->Set(index,
- std::make_unique<base::Value>(base::Int64ToString(value)));
+ std::make_unique<base::Value>(base::NumberToString(value)));
}
// DailyContentLengthUpdate maintains a data saving pref. The pref is a list
@@ -227,7 +227,7 @@ void AddToDictionaryPref(PrefService* pref_service,
int value) {
DictionaryPrefUpdate pref_update(pref_service, pref);
base::DictionaryValue* pref_dict = pref_update.Get();
- const std::string key_str = base::IntToString(key);
+ const std::string key_str = base::NumberToString(key);
base::Value* dict_value = pref_dict->FindKey(key_str);
if (dict_value)
value += dict_value->GetInt();
@@ -365,7 +365,7 @@ class DataReductionProxyCompressionStats::DailyContentLengthUpdate {
for (int i = 0;
i < days_since_last_update && i < static_cast<int>(kNumDaysInHistory);
++i) {
- update_->AppendString(base::Int64ToString(0));
+ update_->AppendString(base::NumberToString(0));
}
// Entries for new days may have been appended. Maintain the invariant that
@@ -619,8 +619,8 @@ void DataReductionProxyCompressionStats::ResetStatistics() {
original_update->Clear();
received_update->Clear();
for (size_t i = 0; i < kNumDaysInHistory; ++i) {
- original_update->AppendString(base::Int64ToString(0));
- received_update->AppendString(base::Int64ToString(0));
+ original_update->AppendString(base::NumberToString(0));
+ received_update->AppendString(base::NumberToString(0));
}
}
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 f95add5c260..4d7ff435cbf 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
@@ -10,6 +10,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
@@ -175,7 +176,7 @@ class DataReductionProxyCompressionStatsTest : public testing::Test {
base::ListValue* update = compression_stats_->GetList(pref);
update->Clear();
for (size_t i = 0; i < kNumDaysInHistory; ++i) {
- update->Insert(0, std::make_unique<base::Value>(base::Int64ToString(0)));
+ update->Insert(0, std::make_unique<base::Value>(base::NumberToString(0)));
}
}
@@ -491,10 +492,10 @@ class DataReductionProxyCompressionStatsTest : public testing::Test {
int expected_value) const {
const base::DictionaryValue* dict =
compression_stats_->pref_service_->GetDictionary(pref);
- EXPECT_EQ(expected_value != 0, dict->HasKey(base::IntToString(key)));
+ EXPECT_EQ(expected_value != 0, dict->HasKey(base::NumberToString(key)));
if (expected_value) {
EXPECT_EQ(expected_value,
- dict->FindKey(base::IntToString(key))->GetInt());
+ dict->FindKey(base::NumberToString(key))->GetInt());
}
}
@@ -536,7 +537,7 @@ TEST_F(DataReductionProxyCompressionStatsTest, WritePrefsDelayed) {
TEST_F(DataReductionProxyCompressionStatsTest, StatsRestoredOnOnRestart) {
base::ListValue list_value;
list_value.Insert(0,
- std::make_unique<base::Value>(base::Int64ToString(1234)));
+ std::make_unique<base::Value>(base::NumberToString(1234)));
pref_service()->Set(prefs::kDailyHttpOriginalContentLength, list_value);
ResetCompressionStatsWithDelay(
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 71af80b0127..3a542238186 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
@@ -35,7 +35,6 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_type_info.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"
@@ -172,7 +171,7 @@ std::string DoGetCurrentNetworkID(
// connection type.
return "cell," + ssid_mccmnc;
}
- return base::IntToString(static_cast<int>(connection_type)) + "," +
+ return base::NumberToString(static_cast<int>(connection_type)) + "," +
ssid_mccmnc;
}
}
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 17b69c59011..f336ca666cc 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
@@ -25,7 +25,6 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_type_info.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
-#include "components/previews/core/previews_experiments.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_retry_info.h"
#include "services/network/public/cpp/network_connection_tracker.h"
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 3113154f9d8..3843b55ccd5 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
@@ -83,8 +83,8 @@ const uint32_t kMaxBackgroundFetchIntervalSeconds = 6 * 60 * 60; // 6 hours.
// Reduction Proxy configuration service.
const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
0, // num_errors_to_ignore
- 30 * 1000, // initial_delay_ms
- 4, // multiply_factor
+ 10 * 1000, // initial_delay_ms
+ 3, // multiply_factor
0.25, // jitter_factor,
128 * 60 * 1000, // maximum_backoff_ms
-1, // entry_lifetime_ms
@@ -468,7 +468,7 @@ void DataReductionProxyConfigServiceClient::RetrieveRemoteConfig() {
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES;
// Attach variations headers.
- url_loader_ = variations::CreateSimpleURLLoaderWithVariationsHeaders(
+ url_loader_ = variations::CreateSimpleURLLoaderWithVariationsHeader(
std::move(resource_request), variations::InIncognito::kNo,
variations::SignedIn::kNo, traffic_annotation);
@@ -534,6 +534,23 @@ void DataReductionProxyConfigServiceClient::HandleResponse(
std::string encoded_config;
base::Base64Encode(config_data, &encoded_config);
config_storer_.Run(encoded_config);
+
+ // Record timing metrics on successful requests only.
+ const network::ResourceResponseHead* info = url_loader_->ResponseInfo();
+ base::TimeDelta http_request_rtt =
+ info->response_start - info->request_start;
+ UMA_HISTOGRAM_TIMES("DataReductionProxy.ConfigService.HttpRequestRTT",
+ http_request_rtt);
+
+ if (info->load_timing.connect_timing.connect_end > base::TimeTicks() &&
+ info->load_timing.connect_timing.connect_start > base::TimeTicks()) {
+ base::TimeDelta connection_setup =
+ info->load_timing.connect_timing.connect_end -
+ info->load_timing.connect_timing.connect_start;
+ UMA_HISTOGRAM_TIMES(
+ "DataReductionProxy.ConfigService.ConnectionSetupTime",
+ connection_setup);
+ }
} else {
++failed_attempts_before_success_;
}
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 f73a903d59a..a04d6c55a83 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
@@ -555,6 +555,8 @@ TEST_F(DataReductionProxyConfigServiceClientTest, EnsureBackoff) {
// Tests that the config is read successfully on the first attempt.
TEST_F(DataReductionProxyConfigServiceClientTest, RemoteConfigSuccess) {
Init(true);
+ base::HistogramTester histogram_tester;
+
AddMockSuccess();
SetDataReductionProxyEnabled(true, true);
EXPECT_TRUE(configurator()->GetProxyConfig().proxy_rules().empty());
@@ -562,6 +564,8 @@ TEST_F(DataReductionProxyConfigServiceClientTest, RemoteConfigSuccess) {
config_client()->RetrieveConfig();
RunUntilIdle();
VerifyRemoteSuccess(true);
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.HttpRequestRTT", 1);
EXPECT_FALSE(configurator()->GetProxyConfig().proxy_rules().empty());
#if defined(OS_ANDROID)
EXPECT_FALSE(config_client()->foreground_fetch_pending());
@@ -650,6 +654,8 @@ TEST_F(DataReductionProxyConfigServiceClientTest,
histogram_tester.ExpectUniqueSample(
"DataReductionProxy.ConfigService.FetchFailedAttemptsBeforeSuccess", 1,
1);
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.HttpRequestRTT", 1);
}
// Verifies that the config is fetched successfully after IP address changes.
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 52951675694..20418b5f79c 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
@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
@@ -43,8 +44,6 @@
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_type_info.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
-#include "components/previews/core/previews_experiments.h"
-#include "components/previews/core/test_previews_decider.h"
#include "components/variations/variations_associated_data.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.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 5e799f18a23..367c0b73ce1 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
@@ -153,7 +153,7 @@ void DataReductionProxyDelegate::OnFallback(const net::ProxyServer& bad_proxy,
bypass_stats_->OnProxyFallback(bad_proxy, net_error);
}
-net::Error DataReductionProxyDelegate::OnTunnelHeadersReceived(
+net::Error DataReductionProxyDelegate::OnHttp1TunnelHeadersReceived(
const net::ProxyServer& proxy_server,
const net::HttpResponseHeaders& response_headers) {
return net::OK;
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 d759678a523..14ba5fa9cfe 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
@@ -44,9 +44,10 @@ class DataReductionProxyDelegate : public net::ProxyDelegate {
const net::ProxyRetryInfoMap& proxy_retry_info,
net::ProxyInfo* result) override;
void OnFallback(const net::ProxyServer& bad_proxy, int net_error) override;
- void OnBeforeTunnelRequest(const net::ProxyServer& proxy_server,
- net::HttpRequestHeaders* extra_headers) override {}
- net::Error OnTunnelHeadersReceived(
+ void OnBeforeHttp1TunnelRequest(
+ const net::ProxyServer& proxy_server,
+ net::HttpRequestHeaders* extra_headers) override {}
+ net::Error OnHttp1TunnelHeadersReceived(
const net::ProxyServer& proxy_server,
const net::HttpResponseHeaders& response_headers) 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 610e5832632..3ddb9cc39e1 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
@@ -873,10 +873,10 @@ TEST_F(DataReductionProxyDelegateTest, PartialRangeSavings) {
{"HTTP/1.1 200 OK\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"Content-Length: " +
- base::Int64ToString(static_cast<int64_t>(1) << 60) +
+ base::NumberToString(static_cast<int64_t>(1) << 60) +
"\r\n"
"Chrome-Proxy: ofcl=" +
- base::Int64ToString((static_cast<int64_t>(1) << 60) * 3) +
+ base::NumberToString((static_cast<int64_t>(1) << 60) * 3) +
"\r\n\r\n",
100, 300},
{"HTTP/1.1 206 Partial Content\r\n"
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 50175ff1b28..a3381c42ec4 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
@@ -25,6 +25,7 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/core/browser/network_properties_manager.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_bypass_protocol.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_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
@@ -163,7 +164,7 @@ void DataReductionProxyIOData::InitializeOnIOThread() {
config_->InitializeOnIOThread(
url_loader_factory,
base::BindRepeating(&DataReductionProxyIOData::CreateCustomProxyConfig,
- base::Unretained(this)),
+ base::Unretained(this), true),
network_properties_manager_.get());
bypass_stats_->InitializeOnIOThread();
proxy_delegate_->InitializeOnIOThread(this);
@@ -380,14 +381,14 @@ void DataReductionProxyIOData::OnProxyConfigUpdated() {
network::mojom::CustomProxyConfigPtr
DataReductionProxyIOData::CreateCustomProxyConfig(
+ bool is_warmup_url,
const std::vector<DataReductionProxyServer>& proxies_for_http) const {
auto config = network::mojom::CustomProxyConfig::New();
- config->rules =
- configurator_
- ->CreateProxyConfig(true /* probe_url_config */,
- config_->GetNetworkPropertiesManager(),
- proxies_for_http)
- .proxy_rules();
+ config->rules = configurator_
+ ->CreateProxyConfig(
+ is_warmup_url, config_->GetNetworkPropertiesManager(),
+ proxies_for_http)
+ .proxy_rules();
// Set an alternate proxy list to be used for media requests which only
// contains proxies supporting the media resource type.
@@ -408,6 +409,7 @@ DataReductionProxyIOData::CreateCustomProxyConfig(
request_options_->AddRequestHeader(&config->post_cache_headers,
base::nullopt);
+ config->can_use_proxy_on_http_url_redirect_cycles = false;
return config;
}
@@ -415,8 +417,10 @@ void DataReductionProxyIOData::UpdateCustomProxyConfig() {
if (!proxy_config_client_)
return;
- proxy_config_client_->OnCustomProxyConfigUpdated(
- CreateCustomProxyConfig(config_->GetProxiesForHttp()));
+ proxy_config_client_->OnCustomProxyConfigUpdated(CreateCustomProxyConfig(
+ !base::FeatureList::IsEnabled(
+ features::kDataReductionProxyDisableProxyFailedWarmup),
+ config_->GetProxiesForHttp()));
}
void DataReductionProxyIOData::UpdateThrottleConfig() {
@@ -481,16 +485,17 @@ void DataReductionProxyIOData::MarkProxiesAsBad(
// Sanity check the inputs, as this data may originate from a lower-privilege
// process (renderer).
- // The current policy sets this to 5 minutes, so don't allow a bigger
- // timespan.
- if (bypass_duration < base::TimeDelta() ||
- bypass_duration > base::TimeDelta::FromMinutes(5)) {
+ if (bypass_duration < base::TimeDelta()) {
LOG(ERROR) << "Received bad MarkProxiesAsBad() -- invalid bypass_duration: "
<< bypass_duration;
std::move(callback).Run();
return;
}
+ // Limit maximum bypass duration to a day.
+ if (bypass_duration > base::TimeDelta::FromDays(1))
+ bypass_duration = base::TimeDelta::FromDays(1);
+
// |bad_proxies| should be DRP servers or this API allows marking arbitrary
// proxies as bad. It is possible that proxies from an older config are
// received (FindConfiguredDataReductionProxy() searches recent proxies too).
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 6ff0c35de10..a26230a93d7 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
@@ -257,6 +257,7 @@ class DataReductionProxyIOData : public mojom::DataReductionProxy {
// Creates a config using |proxies_for_http| that can be sent to the
// NetworkContext.
network::mojom::CustomProxyConfigPtr CreateCustomProxyConfig(
+ bool is_warmup_url,
const std::vector<DataReductionProxyServer>& proxies_for_http) const;
// Called when the list of proxies changes.
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 020c266101f..ca981e2a488 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
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
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 1502f228c59..6d7c7066103 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
@@ -13,6 +13,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/metrics/field_trial.h"
@@ -48,9 +49,6 @@
#include "components/data_reduction_proxy/core/common/lofi_decider.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/data_reduction_proxy/proto/data_store.pb.h"
-#include "components/previews/core/previews_experiments.h"
-#include "components/previews/core/previews_features.h"
-#include "components/previews/core/test_previews_decider.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -744,9 +742,6 @@ TEST_F(DataReductionProxyNetworkDelegateTest, LoFiTransitions) {
data_reduction_proxy_info.UseNamedProxy(proxy);
}
- // Needed as a parameter, but functionality is not tested.
- previews::TestPreviewsDecider test_previews_decider(true);
-
{
// Main frame loaded. Lo-Fi should be used.
net::HttpRequestHeaders headers;
@@ -1052,11 +1047,6 @@ TEST_F(DataReductionProxyNetworkDelegateTest, RedirectRequestDataCleared) {
TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
Init(USE_INSECURE_PROXY);
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {previews::features::kPreviews,
- features::kDataReductionProxyDecidesTransform},
- {});
-
base::HistogramTester histogram_tester;
std::string response_headers =
@@ -1065,7 +1055,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetHistograms) {
"Expires: Mon, 24 Nov 2014 12:45:26 GMT\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"Chrome-Proxy: ofcl=" +
- base::Int64ToString(kOriginalContentLength) + "\r\n\r\n";
+ base::NumberToString(kOriginalContentLength) + "\r\n\r\n";
std::unique_ptr<net::URLRequest> fake_request(FetchURLRequest(
GURL(kTestURL), nullptr, response_headers, kResponseContentLength, 0));
@@ -1110,7 +1100,7 @@ TEST_F(DataReductionProxyNetworkDelegateTest, NetVideoHistograms) {
"Content-Type: video/mp4\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"Chrome-Proxy: ofcl=" +
- base::Int64ToString(kOriginalContentLength) + "\r\n\r\n";
+ base::NumberToString(kOriginalContentLength) + "\r\n\r\n";
FetchURLRequest(GURL(kTestURL), nullptr, video_response_headers,
kResponseContentLength, 0);
@@ -1289,8 +1279,9 @@ TEST_F(DataReductionProxyNetworkDelegateTest, DetailedNetHistograms) {
if (test.proxy_config == USE_INSECURE_PROXY) {
via_header = "Via: 1.1 Chrome-Compression-Proxy\r\n";
- ocl_header = "Chrome-Proxy: ofcl=" +
- base::Int64ToString(kOriginalContentLength) + "\r\n";
+ ocl_header =
+ "Chrome-Proxy: ofcl=" + base::NumberToString(kOriginalContentLength) +
+ "\r\n";
}
if (test.is_video) {
// Check video
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h
index c4153449d90..1228f8658dc 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h
@@ -13,7 +13,7 @@ struct DataReductionProxyPageLoadTiming;
// server.
class DataReductionProxyPingbackClient {
public:
- virtual ~DataReductionProxyPingbackClient(){};
+ virtual ~DataReductionProxyPingbackClient() {}
// Sends a pingback to the data saver proxy server about various timing
// information.
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 8d241701f34..52730fe1194 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->AppendString(base::Int64ToString(i + starting_value));
+ list->AppendString(base::NumberToString(i + starting_value));
}
}
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 fd87669abf7..7fd0632bf23 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
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
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 3d7ef53a791..ccd7f8850ab 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
@@ -18,6 +18,7 @@
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h"
#include "components/data_reduction_proxy/core/browser/db_data_owner.h"
#include "components/data_use_measurement/core/data_use_measurement.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
@@ -25,6 +26,7 @@
#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/mojom/network_context.mojom-forward.h"
class PrefService;
@@ -37,13 +39,13 @@ class TimeDelta;
namespace net {
class HttpRequestHeaders;
class URLRequestContextGetter;
+class ProxyList;
}
namespace data_reduction_proxy {
class DataReductionProxyCompressionStats;
class DataReductionProxyIOData;
-class DataReductionProxyPingbackClient;
class DataReductionProxyServiceObserver;
class DataReductionProxySettings;
@@ -133,6 +135,12 @@ class DataReductionProxyService
// Sets the reporting fraction in the pingback client.
void SetPingbackReportingFraction(float pingback_reporting_fraction);
+ // Sets |pingback_client_| to be used for testing purposes.
+ void SetPingbackClientForTesting(
+ DataReductionProxyPingbackClient* pingback_client) {
+ pingback_client_.reset(pingback_client);
+ }
+
// Notifies |this| that the user has requested to clear the browser
// cache. This method is not called if only a subset of site entries are
// cleared.
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index 7724904e2a7..6b0f30b3eb9 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -288,7 +288,7 @@ const net::HttpRequestHeaders&
DataReductionProxySettings::GetProxyRequestHeaders() const {
DCHECK(thread_checker_.CalledOnValidThread());
return proxy_request_headers_;
-};
+}
void DataReductionProxySettings::SetProxyRequestHeaders(
const net::HttpRequestHeaders& headers) {
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index 0945cd25296..42e379d8912 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -59,9 +59,9 @@ void DataReductionProxySettingsTestBase::SetUp() {
prefs::kDailyHttpReceivedContentLength);
for (int64_t i = 0; i < kNumDaysInHistory; i++) {
original_update->Insert(
- 0, std::make_unique<base::Value>(base::Int64ToString(2 * i)));
+ 0, std::make_unique<base::Value>(base::NumberToString(2 * i)));
received_update->Insert(
- 0, std::make_unique<base::Value>(base::Int64ToString(i)));
+ 0, std::make_unique<base::Value>(base::NumberToString(i)));
}
last_update_time_ = base::Time::Now().LocalMidnight();
pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
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 0f11a50982e..79922e12424 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
@@ -11,7 +11,6 @@
#include "base/command_line.h"
#include "base/macros.h"
-#include "base/md5.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_samples.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index 04f5236fb47..1719cae9cc4 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc
index 4bf28f77b9c..6636a40032d 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.cc
@@ -348,24 +348,6 @@ ProxyServer_ProxyScheme ProxySchemeFromScheme(net::ProxyServer::Scheme scheme) {
}
}
-HTTPSLitePagePreviewInfo_Status
-ProtoLitePageRedirectStatusFromLitePageRedirectStatus(
- previews::ServerLitePageStatus status) {
- switch (status) {
- case previews::ServerLitePageStatus::kUnknown:
- return HTTPSLitePagePreviewInfo_Status_UNKNOWN;
- case previews::ServerLitePageStatus::kSuccess:
- return HTTPSLitePagePreviewInfo_Status_SUCCESS;
- case previews::ServerLitePageStatus::kBypass:
- return HTTPSLitePagePreviewInfo_Status_BYPASS;
- case previews::ServerLitePageStatus::kRedirect:
- return HTTPSLitePagePreviewInfo_Status_REDIRECT;
- case previews::ServerLitePageStatus::kFailure:
- return HTTPSLitePagePreviewInfo_Status_FAILURE;
- case previews::ServerLitePageStatus::kControl:
- return HTTPSLitePagePreviewInfo_Status_CONTROL;
- }
-}
void TimeDeltaToDuration(const base::TimeDelta& time_delta,
Duration* duration) {
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h
index c6929bc0c67..a360fd11e80 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h
+++ b/chromium/components/data_reduction_proxy/core/browser/data_reduction_proxy_util.h
@@ -8,10 +8,8 @@
#include <memory>
#include <string>
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/data_reduction_proxy/proto/pageload_metrics.pb.h"
-#include "components/previews/core/previews_lite_page_redirect.h"
#include "net/base/network_change_notifier.h"
#include "net/base/proxy_server.h"
#include "net/nqe/effective_connection_type.h"
@@ -140,12 +138,6 @@ net::ProxyServer::Scheme SchemeFromProxyScheme(
// Returns the ProxyServer_ProxyScheme for a |net::ProxyServer::Scheme|.
ProxyServer_ProxyScheme ProxySchemeFromScheme(net::ProxyServer::Scheme scheme);
-// Returns the HTTPSLitePagePreviewInfo_Status for a
-// |previews::ServerLitePageStatus|.
-HTTPSLitePagePreviewInfo_Status
-ProtoLitePageRedirectStatusFromLitePageRedirectStatus(
- previews::ServerLitePageStatus status);
-
// Returns the |Duration| representation of |time_delta|.
void TimeDeltaToDuration(const base::TimeDelta& time_delta, Duration* duration);
diff --git a/chromium/components/data_reduction_proxy/core/browser/data_usage_store.cc b/chromium/components/data_reduction_proxy/core/browser/data_usage_store.cc
index dc1d7fd120c..2f3f3d3a69d 100644
--- a/chromium/components/data_reduction_proxy/core/browser/data_usage_store.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/data_usage_store.cc
@@ -143,7 +143,7 @@ void DataUsageStore::StoreCurrentDataUsageBucket(
base::Time::FromInternalValue(current.last_updated_timestamp());
buckets_to_save.insert(std::pair<std::string, std::string>(
- kCurrentBucketIndexKey, base::IntToString(current_bucket_index_)));
+ kCurrentBucketIndexKey, base::NumberToString(current_bucket_index_)));
DataStore::Status status = db_->Put(buckets_to_save);
if (status != DataStore::Status::OK) {
diff --git a/chromium/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc
index 0910e876abc..1129033dabb 100644
--- a/chromium/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc
@@ -243,7 +243,7 @@ TEST(NetworkPropertyTest, TestLimitPrefSize) {
size_t num_network_ids = 100;
for (size_t i = 0; i < num_network_ids; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
network_properties_manager.OnChangeInNetworkID(network_id);
// State should be reset when there is a change in the network ID.
@@ -271,14 +271,14 @@ TEST(NetworkPropertyTest, TestLimitPrefSize) {
// The last 10 network IDs are guaranteed to be present in the prefs.
for (size_t i = num_network_ids - 10; i < num_network_ids; ++i) {
EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties)
- ->HasKey("test" + base::IntToString(i)));
+ ->HasKey("test" + base::NumberToString(i)));
}
{
TestNetworkPropertiesManager network_properties_manager_2(
&test_prefs, base::ThreadTaskRunnerHandle::Get());
for (size_t i = 0; i < num_network_ids; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
network_properties_manager_2.OnChangeInNetworkID(network_id);
EXPECT_EQ(test_prefs.GetDictionary(prefs::kNetworkProperties)
@@ -466,7 +466,7 @@ TEST(NetworkPropertyTest, TestDeleteOldValues) {
&test_clock, &test_prefs, base::ThreadTaskRunnerHandle::Get());
for (size_t i = 0; i < 5; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
network_properties_manager.OnChangeInNetworkID(network_id);
network_properties_manager.SetIsCaptivePortal(true);
}
@@ -474,7 +474,7 @@ TEST(NetworkPropertyTest, TestDeleteOldValues) {
test_clock.Advance(base::TimeDelta::FromDays(20));
for (size_t i = 5; i < 10; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
network_properties_manager.OnChangeInNetworkID(network_id);
network_properties_manager.SetIsCaptivePortal(true);
}
@@ -484,7 +484,7 @@ TEST(NetworkPropertyTest, TestDeleteOldValues) {
// Verify the prefs.
EXPECT_EQ(10u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size());
for (size_t i = 0; i < 10; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties)
->HasKey(network_id));
}
@@ -494,7 +494,7 @@ TEST(NetworkPropertyTest, TestDeleteOldValues) {
TestNetworkPropertiesManager network_properties_manager_2(
&test_clock, &test_prefs, base::ThreadTaskRunnerHandle::Get());
for (size_t i = 0; i < 10; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties)
->HasKey(network_id));
@@ -507,7 +507,7 @@ TEST(NetworkPropertyTest, TestDeleteOldValues) {
TestNetworkPropertiesManager network_properties_manager_3(
&test_clock, &test_prefs, base::ThreadTaskRunnerHandle::Get());
for (size_t i = 0; i < 10; ++i) {
- std::string network_id("test" + base::IntToString(i));
+ std::string network_id("test" + base::NumberToString(i));
EXPECT_EQ(i >= 5, test_prefs.GetDictionary(prefs::kNetworkProperties)
->HasKey(network_id));
}
diff --git a/chromium/components/data_reduction_proxy/core/browser/secure_proxy_checker.cc b/chromium/components/data_reduction_proxy/core/browser/secure_proxy_checker.cc
index f2fe7608411..85ae826b37e 100644
--- a/chromium/components/data_reduction_proxy/core/browser/secure_proxy_checker.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/secure_proxy_checker.cc
@@ -4,6 +4,7 @@
#include "components/data_reduction_proxy/core/browser/secure_proxy_checker.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
diff --git a/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
index 00b58f5eedb..0b4fa4fc3c4 100644
--- a/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/data_reduction_proxy/core/browser/warmup_url_fetcher.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/guid.h"
#include "base/metrics/field_trial_params.h"
@@ -141,6 +142,11 @@ void WarmupURLFetcher::FetchWarmupURLNow(
// for loading user initiated requests.
resource_request->load_flags = net::LOAD_BYPASS_CACHE;
+ // TODO(957215): This is a temporary solution to mark the request to go
+ // through the data reduction proxy. Otherwise only navigation requests and
+ // renderer requests will be allowed to use the proxy.
+ resource_request->render_frame_id = MSG_ROUTING_CONTROL;
+
url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
traffic_annotation);
// |url_loader_| should not retry on 5xx errors. |url_loader_| should retry on
diff --git a/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
index 9ad4bc7abf9..e219a282650 100644
--- a/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
+++ b/chromium/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
@@ -75,9 +76,9 @@ class WarmupURLFetcherTest : public WarmupURLFetcher {
base::TimeDelta second_retry) {
std::map<std::string, std::string> params;
params["warmup_url_fetch_wait_timer_first_retry_seconds"] =
- base::IntToString(first_retry.InSeconds());
+ base::NumberToString(first_retry.InSeconds());
params["warmup_url_fetch_wait_timer_second_retry_seconds"] =
- base::IntToString(second_retry.InSeconds());
+ base::NumberToString(second_retry.InSeconds());
scoped_feature_list->InitAndEnableFeatureWithParameters(
features::kDataReductionProxyRobustConnection, params);
}
diff --git a/chromium/components/data_reduction_proxy/core/common/BUILD.gn b/chromium/components/data_reduction_proxy/core/common/BUILD.gn
index 4f4cc9e5620..8923dfba76c 100644
--- a/chromium/components/data_reduction_proxy/core/common/BUILD.gn
+++ b/chromium/components/data_reduction_proxy/core/common/BUILD.gn
@@ -19,8 +19,6 @@ template("common_tmpl") {
"data_reduction_proxy_features.h",
"data_reduction_proxy_headers.cc",
"data_reduction_proxy_headers.h",
- "data_reduction_proxy_page_load_timing.cc",
- "data_reduction_proxy_page_load_timing.h",
"data_reduction_proxy_params.cc",
"data_reduction_proxy_params.h",
"data_reduction_proxy_pref_names.cc",
@@ -46,7 +44,6 @@ template("common_tmpl") {
deps = [
"//base",
"//components/data_reduction_proxy/proto:data_reduction_proxy_proto",
- "//components/previews/core",
"//components/variations",
"//google_apis",
"//services/network/public/cpp",
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 1834dee646b..602140e1f32 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
@@ -46,5 +46,24 @@ const base::Feature kDataReductionProxyEnabledWithNetworkService{
"DataReductionProxyEnabledWithNetworkService",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables block action of all proxies when 502 is received with no
+// Chrome-Proxy header. The block duration is configurable via field trial with
+// a default of one second.
+const base::Feature kDataReductionProxyBlockOnBadGatewayResponse{
+ "DataReductionProxyBlockOnBadGatewayResponse",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enables populating the previews page ID from NavigationUIData to the
+// pingbacks.
+const base::Feature kDataReductionProxyPopulatePreviewsPageIDToPingback{
+ "DataReductionProxyPopulatePreviewsPageIDToPingback",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Enables not allowing proxies that fail warmup url fetch, to custom proxy
+// config updates when network service is enabled.
+const base::Feature kDataReductionProxyDisableProxyFailedWarmup{
+ "DataReductionProxyDisableProxyFailedWarmup",
+ base::FEATURE_ENABLED_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 3347846ff55..3bb6f48ddaf 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
@@ -17,6 +17,9 @@ extern const base::Feature kDogfood;
extern const base::Feature kDataSaverSiteBreakdownUsingPageLoadMetrics;
extern const base::Feature kDataReductionProxyEnabledWithNetworkService;
extern const base::Feature kDataSaverUseOnDeviceSafeBrowsing;
+extern const base::Feature kDataReductionProxyBlockOnBadGatewayResponse;
+extern const base::Feature kDataReductionProxyPopulatePreviewsPageIDToPingback;
+extern const base::Feature kDataReductionProxyDisableProxyFailedWarmup;
} // 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 0e4394ac8a5..c817c3aa458 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
@@ -414,14 +414,33 @@ DataReductionProxyBypassType GetDataReductionProxyBypassType(
// Fall back if a 500, 502 or 503 is returned.
if (headers.response_code() == net::HTTP_INTERNAL_SERVER_ERROR)
return BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR;
- if (headers.response_code() == net::HTTP_BAD_GATEWAY)
+ if (headers.response_code() == net::HTTP_BAD_GATEWAY) {
+ if (base::FeatureList::IsEnabled(
+ features::kDataReductionProxyBlockOnBadGatewayResponse)) {
+ // When 502 response is received with no valid directive in Chrome-Proxy
+ // header, it is likely the renderer may have been blocked in receiving
+ // the headers due to CORB, etc. In this case, block-once or a block all
+ // proxies for a small number of seconds can be an alternative.
+ data_reduction_proxy_info->bypass_all = true;
+ data_reduction_proxy_info->bypass_duration =
+ base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
+ features::kDataReductionProxyBlockOnBadGatewayResponse,
+ "block_duration_seconds", 1));
+ return BYPASS_EVENT_TYPE_SHORT;
+ }
return BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY;
+ }
if (headers.response_code() == net::HTTP_SERVICE_UNAVAILABLE)
return BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE;
// TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be
// interpreted by data reduction proxy.
if (headers.response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED &&
!headers.HasHeader("Proxy-Authenticate")) {
+ // Bypass all proxies for a few RTTs until the config fetch could update the
+ // session key. The value 500 ms is the RTT observed for config fetches.
+ data_reduction_proxy_info->bypass_all = true;
+ data_reduction_proxy_info->bypass_duration =
+ base::TimeDelta::FromMilliseconds(3 * 500);
return BYPASS_EVENT_TYPE_MALFORMED_407;
}
@@ -474,7 +493,8 @@ int64_t GetDataReductionProxyOFCL(const net::HttpResponseHeaders* headers) {
double EstimateCompressionRatioFromHeaders(
const network::ResourceResponseHead* response_head) {
if (!response_head->network_accessed || !response_head->headers ||
- response_head->headers->GetContentLength() <= 0) {
+ response_head->headers->GetContentLength() <= 0 ||
+ response_head->proxy_server.is_direct()) {
return 1.0; // No compression
}
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 b3c57b4cefa..47e69aab84f 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
@@ -34,7 +34,6 @@ namespace {
const char kEnabled[] = "Enabled";
const char kControl[] = "Control";
const char kDisabled[] = "Disabled";
-const char kExperimentsOption[] = "exp";
const char kDefaultSecureProxyCheckUrl[] = "http://check.googlezip.net/connect";
const char kDefaultWarmupUrl[] = "http://check.googlezip.net/e2e_probe";
@@ -152,14 +151,6 @@ bool IsIncludedInServerExperimentsFieldTrial() {
.find(kDisabled) != 0;
}
-bool IsIncludedInOnDeviceSafeBrowsingFieldTrial() {
- if (!params::IsIncludedInServerExperimentsFieldTrial())
- return false;
- std::string server_experiment = variations::GetVariationParamValue(
- params::GetServerExperimentsFieldTrialName(), kExperimentsOption);
- return server_experiment == "disable_server_safebrowsing";
-}
-
bool FetchWarmupProbeURLEnabled() {
return !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableDataReductionProxyWarmupURLFetch);
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 ac2e07eb027..e6444c2c0e2 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
@@ -65,10 +65,6 @@ const char* GetLoFiFlagFieldTrialName();
// server experiments for the data reduction proxy.
bool IsIncludedInServerExperimentsFieldTrial();
-// Returns true if Chrome should use on-device safe browsing checks, and
-// disable safe browsing checks provided by data saver proxy.
-bool IsIncludedInOnDeviceSafeBrowsingFieldTrial();
-
// Returns true if this client has the command line switch to enable forced
// pageload metrics pingbacks on every page load.
bool IsForcePingbackEnabledViaFlags();
diff --git a/chromium/components/data_use_measurement/content/content_url_request_classifier.cc b/chromium/components/data_use_measurement/content/content_url_request_classifier.cc
index 3678ace5217..720198b8ce0 100644
--- a/chromium/components/data_use_measurement/content/content_url_request_classifier.cc
+++ b/chromium/components/data_use_measurement/content/content_url_request_classifier.cc
@@ -45,7 +45,7 @@ namespace data_use_measurement {
DataUseUserData::DataUseContentType ContentURLRequestClassifier::GetContentType(
const net::URLRequest& request,
const net::HttpResponseHeaders& response_headers) const {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
std::string mime_type;
if (response_headers.GetMimeType(&mime_type)) {
@@ -137,7 +137,7 @@ void ContentURLRequestClassifier::RecordPageTransitionUMA(
bool ContentURLRequestClassifier::IsFavIconRequest(
const net::URLRequest& request) const {
- const content::ResourceRequestInfo* request_info =
+ content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(&request);
return request_info && request_info->GetResourceType() ==
content::ResourceType::RESOURCE_TYPE_FAVICON;
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 89e2b90e007..1002271fc94 100644
--- a/chromium/components/data_use_measurement/core/data_use_measurement.cc
+++ b/chromium/components/data_use_measurement/core/data_use_measurement.cc
@@ -6,6 +6,7 @@
#include <set>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
diff --git a/chromium/components/dbus/BUILD.gn b/chromium/components/dbus/BUILD.gn
new file mode 100644
index 00000000000..97b3a6191c7
--- /dev/null
+++ b/chromium/components/dbus/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+component("dbus_thread_linux") {
+ sources = [
+ "dbus_thread_linux.cc",
+ "dbus_thread_linux.h",
+ ]
+ defines = [ "IS_DBUS_IMPL" ]
+ deps = [
+ "//base",
+ ]
+}
diff --git a/chromium/components/dbus/OWNERS b/chromium/components/dbus/OWNERS
new file mode 100644
index 00000000000..6f555f868ec
--- /dev/null
+++ b/chromium/components/dbus/OWNERS
@@ -0,0 +1 @@
+file://dbus/OWNERS
diff --git a/chromium/components/dbus/dbus_thread_linux.cc b/chromium/components/dbus/dbus_thread_linux.cc
new file mode 100644
index 00000000000..c0825a2e49d
--- /dev/null
+++ b/chromium/components/dbus/dbus_thread_linux.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/dbus/dbus_thread_linux.h"
+
+#include "base/task/lazy_task_runner.h"
+
+namespace dbus_thread_linux {
+
+namespace {
+
+// Use TaskPriority::USER_BLOCKING, because there is a client
+// (NotificationPlatformBridgeLinuxImpl) which needs to run user-blocking tasks
+// on this thread. Use SingleThreadTaskRunnerThreadMode::SHARED, because DBus
+// does not require an exclusive use of the thread, only the existence of a
+// single thread for all tasks.
+base::LazySingleThreadTaskRunner g_dbus_thread_task_runner =
+ LAZY_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(
+ base::TaskTraits(base::MayBlock(), base::TaskPriority::USER_BLOCKING),
+ base::SingleThreadTaskRunnerThreadMode::SHARED);
+
+} // namespace
+
+scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() {
+ return g_dbus_thread_task_runner.Get();
+}
+
+} // namespace dbus_thread_linux
diff --git a/chromium/components/dbus/dbus_thread_linux.h b/chromium/components/dbus/dbus_thread_linux.h
new file mode 100644
index 00000000000..e2d1aa05a39
--- /dev/null
+++ b/chromium/components/dbus/dbus_thread_linux.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_DBUS_DBUS_THREAD_LINUX_H_
+#define COMPONENTS_DBUS_DBUS_THREAD_LINUX_H_
+
+#include "base/component_export.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "build/build_config.h"
+
+// Many APIs in ::dbus are required to be called from the same thread
+// (https://crbug.com/130984). Therefore, a SingleThreadedTaskRunner is
+// maintained and accessible through GetDBusTaskRunner(), from which all calls
+// to dbus on Linux have to be made.
+
+#if defined(OS_CHROMEOS)
+#error On ChromeOS, use DBusThreadManager instead.
+#endif
+
+namespace dbus_thread_linux {
+
+COMPONENT_EXPORT(DBUS)
+scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
+
+} // namespace dbus_thread_linux
+
+#endif // COMPONENTS_DBUS_DBUS_THREAD_LINUX_H_
diff --git a/chromium/components/dom_distiller/content/browser/distillability_driver.cc b/chromium/components/dom_distiller/content/browser/distillability_driver.cc
index bce43553663..3ace9fac50d 100644
--- a/chromium/components/dom_distiller/content/browser/distillability_driver.cc
+++ b/chromium/components/dom_distiller/content/browser/distillability_driver.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -23,13 +24,13 @@ class DistillabilityServiceImpl : public mojom::DistillabilityService {
base::WeakPtr<DistillabilityDriver> distillability_driver)
: distillability_driver_(distillability_driver) {}
- ~DistillabilityServiceImpl() override {
- }
+ ~DistillabilityServiceImpl() override {}
void NotifyIsDistillable(bool is_distillable,
bool is_last_update,
bool is_mobile_friendly) override {
- if (!distillability_driver_) return;
+ if (!distillability_driver_)
+ return;
distillability_driver_->OnDistillability(is_distillable, is_last_update,
is_mobile_friendly);
}
@@ -38,11 +39,10 @@ class DistillabilityServiceImpl : public mojom::DistillabilityService {
base::WeakPtr<DistillabilityDriver> distillability_driver_;
};
-DistillabilityDriver::DistillabilityDriver(
- content::WebContents* web_contents)
- : content::WebContentsObserver(web_contents),
- weak_factory_(this) {
- if (!web_contents) return;
+DistillabilityDriver::DistillabilityDriver(content::WebContents* web_contents)
+ : content::WebContentsObserver(web_contents), weak_factory_(this) {
+ if (!web_contents)
+ return;
frame_interfaces_.AddInterface(
base::BindRepeating(&DistillabilityDriver::CreateDistillabilityService,
base::Unretained(this)));
@@ -67,7 +67,8 @@ void DistillabilityDriver::SetDelegate(
void DistillabilityDriver::OnDistillability(bool distillable,
bool is_last,
bool is_mobile_friendly) {
- if (m_delegate_.is_null()) return;
+ if (m_delegate_.is_null())
+ return;
m_delegate_.Run(distillable, is_last, is_mobile_friendly);
}
diff --git a/chromium/components/dom_distiller/content/browser/distillability_driver.h b/chromium/components/dom_distiller/content/browser/distillability_driver.h
index 4c5307285a8..388e5171273 100644
--- a/chromium/components/dom_distiller/content/browser/distillability_driver.h
+++ b/chromium/components/dom_distiller/content/browser/distillability_driver.h
@@ -22,8 +22,7 @@ class DistillabilityDriver
public content::WebContentsUserData<DistillabilityDriver> {
public:
~DistillabilityDriver() override;
- void CreateDistillabilityService(
- mojom::DistillabilityServiceRequest request);
+ void CreateDistillabilityService(mojom::DistillabilityServiceRequest request);
void SetDelegate(const DistillabilityDelegate& delegate);
diff --git a/chromium/components/dom_distiller/content/browser/distillable_page_utils_browsertest.cc b/chromium/components/dom_distiller/content/browser/distillable_page_utils_browsertest.cc
index 933c7ce15d8..ee805259d55 100644
--- a/chromium/components/dom_distiller/content/browser/distillable_page_utils_browsertest.cc
+++ b/chromium/components/dom_distiller/content/browser/distillable_page_utils_browsertest.cc
@@ -45,10 +45,8 @@ class DomDistillerDistillablePageUtilsTest : public content::ContentBrowserTest,
base::RunLoop url_loaded_runner;
main_frame_loaded_callback_ = url_loaded_runner.QuitClosure();
current_web_contents->GetController().LoadURL(
- embedded_test_server()->GetURL(url),
- content::Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
+ embedded_test_server()->GetURL(url), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
url_loaded_runner.Run();
main_frame_loaded_callback_ = base::Closure();
Observe(nullptr);
@@ -96,9 +94,7 @@ class ResultHolder {
callback_.Run();
}
- bool GetResult() {
- return result_;
- }
+ bool GetResult() { return result_; }
base::Callback<void(bool)> GetCallback() {
return base::Bind(&ResultHolder::OnResult, base::Unretained(this));
diff --git a/chromium/components/dom_distiller/content/browser/distiller_javascript_utils.cc b/chromium/components/dom_distiller/content/browser/distiller_javascript_utils.cc
index 8994f44f9a0..11d0ba6a470 100644
--- a/chromium/components/dom_distiller/content/browser/distiller_javascript_utils.cc
+++ b/chromium/components/dom_distiller/content/browser/distiller_javascript_utils.cc
@@ -39,8 +39,7 @@ void RunIsolatedJavaScript(
// Make sure world ID was set.
DCHECK(distiller_javascript_world_id != invalid_world_id);
render_frame_host->ExecuteJavaScriptInIsolatedWorld(
- base::UTF8ToUTF16(buffer), callback,
- distiller_javascript_world_id);
+ base::UTF8ToUTF16(buffer), callback, distiller_javascript_world_id);
}
void RunIsolatedJavaScript(content::RenderFrameHost* render_frame_host,
diff --git a/chromium/components/dom_distiller/content/browser/distiller_page_web_contents.cc b/chromium/components/dom_distiller/content/browser/distiller_page_web_contents.cc
index 9dd3a81fea2..5bc57afabcb 100644
--- a/chromium/components/dom_distiller/content/browser/distiller_page_web_contents.cc
+++ b/chromium/components/dom_distiller/content/browser/distiller_page_web_contents.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
@@ -30,8 +31,7 @@ namespace dom_distiller {
SourcePageHandleWebContents::SourcePageHandleWebContents(
content::WebContents* web_contents,
bool owned)
- : web_contents_(web_contents), owned_(owned) {
-}
+ : web_contents_(web_contents), owned_(owned) {}
SourcePageHandleWebContents::~SourcePageHandleWebContents() {
if (owned_) {
@@ -76,11 +76,10 @@ DistillerPageWebContents::DistillerPageWebContents(
}
}
-DistillerPageWebContents::~DistillerPageWebContents() {
-}
+DistillerPageWebContents::~DistillerPageWebContents() {}
bool DistillerPageWebContents::StringifyOutput() {
- return false;
+ return false;
}
void DistillerPageWebContents::DistillPageImpl(const GURL& url,
diff --git a/chromium/components/dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc b/chromium/components/dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc
index 63536be31ff..94f59a07621 100644
--- a/chromium/components/dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc
+++ b/chromium/components/dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
@@ -330,8 +331,7 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest,
bool expect_new_web_contents = true;
bool setup_main_frame_observer = true;
bool wait_for_document_loaded = true;
- RunUseCurrentWebContentsTest(url,
- expect_new_web_contents,
+ RunUseCurrentWebContentsTest(url, expect_new_web_contents,
setup_main_frame_observer,
wait_for_document_loaded);
}
@@ -349,8 +349,7 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest,
bool expect_new_web_contents = true;
bool setup_main_frame_observer = false;
bool wait_for_document_loaded = true;
- RunUseCurrentWebContentsTest(url,
- expect_new_web_contents,
+ RunUseCurrentWebContentsTest(url, expect_new_web_contents,
setup_main_frame_observer,
wait_for_document_loaded);
}
@@ -368,8 +367,7 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest,
bool expect_new_web_contents = false;
bool setup_main_frame_observer = true;
bool wait_for_document_loaded = false;
- RunUseCurrentWebContentsTest(url,
- expect_new_web_contents,
+ RunUseCurrentWebContentsTest(url, expect_new_web_contents,
setup_main_frame_observer,
wait_for_document_loaded);
}
@@ -387,8 +385,7 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest,
bool expect_new_web_contents = false;
bool setup_main_frame_observer = true;
bool wait_for_document_loaded = true;
- RunUseCurrentWebContentsTest(url,
- expect_new_web_contents,
+ RunUseCurrentWebContentsTest(url, expect_new_web_contents,
setup_main_frame_observer,
wait_for_document_loaded);
}
@@ -408,10 +405,8 @@ void DistillerPageWebContentsTest::RunUseCurrentWebContentsTest(
url_loaded_runner.QuitClosure(),
wait_for_document_loaded);
current_web_contents->GetController().LoadURL(
- embedded_test_server()->GetURL(url),
- content::Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
+ embedded_test_server()->GetURL(url), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
url_loaded_runner.Run();
std::unique_ptr<SourcePageHandleWebContents> source_page_handle(
@@ -447,14 +442,11 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest,
current_web_contents);
base::RunLoop url_loaded_runner;
- WebContentsMainFrameHelper main_frame_loaded(current_web_contents,
- url_loaded_runner.QuitClosure(),
- true);
+ WebContentsMainFrameHelper main_frame_loaded(
+ current_web_contents, url_loaded_runner.QuitClosure(), true);
current_web_contents->GetController().LoadURL(
- embedded_test_server()->GetURL(kSimpleArticlePath),
- content::Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
+ embedded_test_server()->GetURL(kSimpleArticlePath), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
url_loaded_runner.Run();
std::unique_ptr<SourcePageHandleWebContents> source_page_handle(
@@ -567,14 +559,11 @@ IN_PROC_BROWSER_TEST_F(DistillerPageWebContentsTest, MAYBE_TestPinch) {
dom_distiller::WebContentsMainFrameObserver::CreateForWebContents(
web_contents);
base::RunLoop url_loaded_runner;
- WebContentsMainFrameHelper main_frame_loaded(web_contents,
- url_loaded_runner.QuitClosure(),
- true);
+ WebContentsMainFrameHelper main_frame_loaded(
+ web_contents, url_loaded_runner.QuitClosure(), true);
web_contents->GetController().LoadURL(
- embedded_test_server()->GetURL("/pinch_tester.html"),
- content::Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
+ embedded_test_server()->GetURL("/pinch_tester.html"), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
url_loaded_runner.Run();
// Execute the JS to run the tests, and wait until it has finished.
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 aee39118b89..c984483f47d 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
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/histogram_macros.h"
@@ -227,8 +228,7 @@ DomDistillerViewerSource::DomDistillerViewerSource(
dom_distiller_service_(dom_distiller_service),
distiller_ui_handle_(std::move(ui_handle)) {}
-DomDistillerViewerSource::~DomDistillerViewerSource() {
-}
+DomDistillerViewerSource::~DomDistillerViewerSource() {}
std::string DomDistillerViewerSource::GetSource() const {
return scheme_ + "://";
@@ -254,8 +254,8 @@ void DomDistillerViewerSource::StartDataRequest(
if (base::StartsWith(path, kViewerSaveFontScalingPath,
base::CompareCase::SENSITIVE)) {
double scale = 1.0;
- if (base::StringToDouble(
- path.substr(strlen(kViewerSaveFontScalingPath)), &scale)) {
+ if (base::StringToDouble(path.substr(strlen(kViewerSaveFontScalingPath)),
+ &scale)) {
dom_distiller_service_->GetDistilledPagePrefs()->SetFontScaling(scale);
}
}
@@ -308,8 +308,7 @@ bool DomDistillerViewerSource::ShouldServiceRequest(
return url.SchemeIs(scheme_);
}
-std::string DomDistillerViewerSource::GetContentSecurityPolicyStyleSrc()
- const {
+std::string DomDistillerViewerSource::GetContentSecurityPolicyStyleSrc() const {
return "style-src 'self' https://fonts.googleapis.com;";
}
diff --git a/chromium/components/dom_distiller/content/renderer/distillability_agent.cc b/chromium/components/dom_distiller/content/renderer/distillability_agent.cc
index 2a5b68b1092..2e4e0f9070b 100644
--- a/chromium/components/dom_distiller/content/renderer/distillability_agent.cc
+++ b/chromium/components/dom_distiller/content/renderer/distillability_agent.cc
@@ -100,10 +100,10 @@ bool IsDistillablePageAdaboost(WebDocument& doc,
int score_int = std::round(score * 100);
if (score > 0) {
UMA_HISTOGRAM_COUNTS_1000("DomDistiller.DistillabilityScoreNMF.Positive",
- score_int);
+ score_int);
} else {
UMA_HISTOGRAM_COUNTS_1000("DomDistiller.DistillabilityScoreNMF.Negative",
- -score_int);
+ -score_int);
}
if (distillable) {
// The long-article model is trained with pages that are
@@ -112,10 +112,10 @@ bool IsDistillablePageAdaboost(WebDocument& doc,
int long_score_int = std::round(long_score * 100);
if (long_score > 0) {
UMA_HISTOGRAM_COUNTS_1000("DomDistiller.LongArticleScoreNMF.Positive",
- long_score_int);
+ long_score_int);
} else {
UMA_HISTOGRAM_COUNTS_1000("DomDistiller.LongArticleScoreNMF.Negative",
- -long_score_int);
+ -long_score_int);
}
}
}
@@ -124,25 +124,25 @@ bool IsDistillablePageAdaboost(WebDocument& doc,
(static_cast<unsigned>(distillable) << 1);
if (is_last) {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.PageDistillableAfterLoading",
- bucket, 4);
+ bucket, 4);
} else {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.PageDistillableAfterParsing",
- bucket, 4);
+ bucket, 4);
if (!distillable) {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.DistillabilityRejection",
- NOT_ARTICLE, REJECTION_BUCKET_BOUNDARY);
+ NOT_ARTICLE, REJECTION_BUCKET_BOUNDARY);
} else if (features.is_mobile_friendly) {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.DistillabilityRejection",
- MOBILE_FRIENDLY, REJECTION_BUCKET_BOUNDARY);
+ MOBILE_FRIENDLY, REJECTION_BUCKET_BOUNDARY);
} else if (blacklisted) {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.DistillabilityRejection",
- BLACKLISTED, REJECTION_BUCKET_BOUNDARY);
+ BLACKLISTED, REJECTION_BUCKET_BOUNDARY);
} else if (!long_article) {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.DistillabilityRejection",
- TOO_SHORT, REJECTION_BUCKET_BOUNDARY);
+ TOO_SHORT, REJECTION_BUCKET_BOUNDARY);
} else {
UMA_HISTOGRAM_ENUMERATION("DomDistiller.DistillabilityRejection",
- NOT_REJECTED, REJECTION_BUCKET_BOUNDARY);
+ NOT_REJECTED, REJECTION_BUCKET_BOUNDARY);
}
}
@@ -174,20 +174,18 @@ bool IsDistillablePage(WebDocument& doc,
} // namespace
-DistillabilityAgent::DistillabilityAgent(
- content::RenderFrame* render_frame)
- : RenderFrameObserver(render_frame) {
-}
+DistillabilityAgent::DistillabilityAgent(content::RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame) {}
-void DistillabilityAgent::DidMeaningfulLayout(
- WebMeaningfulLayout layout_type) {
+void DistillabilityAgent::DidMeaningfulLayout(WebMeaningfulLayout layout_type) {
if (layout_type != WebMeaningfulLayout::kFinishedParsing &&
layout_type != WebMeaningfulLayout::kFinishedLoading) {
return;
}
DCHECK(render_frame());
- if (!render_frame()->IsMainFrame()) return;
+ if (!render_frame()->IsMainFrame())
+ return;
DCHECK(render_frame()->GetWebFrame());
WebDocument doc = render_frame()->GetWebFrame()->GetDocument();
if (doc.IsNull() || doc.Body().IsNull())
@@ -196,15 +194,16 @@ void DistillabilityAgent::DidMeaningfulLayout(
return;
bool is_loaded = layout_type == WebMeaningfulLayout::kFinishedLoading;
- if (!NeedToUpdate(is_loaded)) return;
+ if (!NeedToUpdate(is_loaded))
+ return;
bool is_last = IsLast(is_loaded);
// Connect to Mojo service on browser to notify page distillability.
mojom::DistillabilityServicePtr distillability_service;
- render_frame()->GetRemoteInterfaces()->GetInterface(
- &distillability_service);
+ render_frame()->GetRemoteInterfaces()->GetInterface(&distillability_service);
DCHECK(distillability_service);
- if (!distillability_service.is_bound()) return;
+ if (!distillability_service.is_bound())
+ return;
bool is_mobile_friendly = false;
bool is_distillable = IsDistillablePage(doc, is_last, is_mobile_friendly);
distillability_service->NotifyIsDistillable(is_distillable, is_last,
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 e249ce90447..29ff33b5509 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
@@ -32,9 +32,9 @@ DistillerJsRenderFrameObserver::DistillerJsRenderFrameObserver(
DistillerJsRenderFrameObserver::~DistillerJsRenderFrameObserver() {}
-void DistillerJsRenderFrameObserver::DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void DistillerJsRenderFrameObserver::DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) {
load_active_ = true;
}
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 f32e4e451ba..0868b85abce 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
@@ -28,8 +28,9 @@ class DistillerJsRenderFrameObserver : public content::RenderFrameObserver {
~DistillerJsRenderFrameObserver() override;
// RenderFrameObserver implementation.
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) override;
void DidFinishLoad() override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
diff --git a/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.cc b/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.cc
index 10c012c4b71..379776d4088 100644
--- a/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.cc
+++ b/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.cc
@@ -34,7 +34,7 @@ void DistillerNativeJavaScript::AddJavaScriptObjectToFrame(
v8::Context::Scope context_scope(context);
v8::Local<v8::Object> distiller_obj =
- GetOrCreateDistillerObject(isolate, context->Global());
+ GetOrCreateDistillerObject(isolate, context);
EnsureServiceConnected();
@@ -56,27 +56,33 @@ void DistillerNativeJavaScript::BindFunctionToObject(
const base::Callback<Sig> callback) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
// Get the isolate associated with this object.
- javascript_object->Set(gin::StringToSymbol(isolate, name),
- gin::CreateFunctionTemplate(isolate, callback)
- ->GetFunction(context)
- .ToLocalChecked());
+ javascript_object
+ ->Set(context, gin::StringToSymbol(isolate, name),
+ gin::CreateFunctionTemplate(isolate, callback)
+ ->GetFunction(context)
+ .ToLocalChecked())
+ .Check();
}
void DistillerNativeJavaScript::EnsureServiceConnected() {
if (!distiller_js_service_ || !distiller_js_service_.is_bound()) {
- render_frame_->GetRemoteInterfaces()->GetInterface(
- &distiller_js_service_);
+ render_frame_->GetRemoteInterfaces()->GetInterface(&distiller_js_service_);
}
}
-v8::Local<v8::Object> GetOrCreateDistillerObject(v8::Isolate* isolate,
- v8::Local<v8::Object> global) {
+v8::Local<v8::Object> GetOrCreateDistillerObject(
+ v8::Isolate* isolate,
+ v8::Local<v8::Context> context) {
+ v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Object> distiller_obj;
- v8::Local<v8::Value> distiller_value =
- global->Get(gin::StringToV8(isolate, "distiller"));
- if (distiller_value.IsEmpty() || !distiller_value->IsObject()) {
+ v8::Local<v8::Value> distiller_value;
+ if (!global->Get(context, gin::StringToV8(isolate, "distiller"))
+ .ToLocal(&distiller_value) ||
+ !distiller_value->IsObject()) {
distiller_obj = v8::Object::New(isolate);
- global->Set(gin::StringToSymbol(isolate, "distiller"), distiller_obj);
+ global
+ ->Set(context, gin::StringToSymbol(isolate, "distiller"), distiller_obj)
+ .Check();
} else {
distiller_obj = v8::Local<v8::Object>::Cast(distiller_value);
}
diff --git a/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.h b/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.h
index ecea4776ecd..4640d71f4be 100644
--- a/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.h
+++ b/chromium/components/dom_distiller/content/renderer/distiller_native_javascript.h
@@ -39,8 +39,9 @@ class DistillerNativeJavaScript {
};
// static
-v8::Local<v8::Object> GetOrCreateDistillerObject(v8::Isolate* isolate,
- v8::Local<v8::Object> global);
+v8::Local<v8::Object> GetOrCreateDistillerObject(
+ v8::Isolate* isolate,
+ v8::Local<v8::Context> context);
} // namespace dom_distiller
diff --git a/chromium/components/dom_distiller/core/distilled_content_store.h b/chromium/components/dom_distiller/core/distilled_content_store.h
index 29cb8742242..b3fe71a54c8 100644
--- a/chromium/components/dom_distiller/core/distilled_content_store.h
+++ b/chromium/components/dom_distiller/core/distilled_content_store.h
@@ -35,8 +35,8 @@ class DistilledContentStore {
virtual void LoadContent(const ArticleEntry& entry,
LoadCallback callback) = 0;
- DistilledContentStore() {};
- virtual ~DistilledContentStore() {};
+ DistilledContentStore() {}
+ virtual ~DistilledContentStore() {}
private:
DISALLOW_COPY_AND_ASSIGN(DistilledContentStore);
diff --git a/chromium/components/dom_distiller/core/distiller.cc b/chromium/components/dom_distiller/core/distiller.cc
index 86cf468c07c..fe4fbea65ba 100644
--- a/chromium/components/dom_distiller/core/distiller.cc
+++ b/chromium/components/dom_distiller/core/distiller.cc
@@ -285,8 +285,8 @@ void DistillerImpl::OnPageDistillationFinished(
for (int img_num = 0; img_num < distiller_result->content_images_size();
++img_num) {
- std::string image_id =
- base::IntToString(page_num + 1) + "_" + base::IntToString(img_num);
+ std::string image_id = base::NumberToString(page_num + 1) + "_" +
+ base::NumberToString(img_num);
MaybeFetchImage(page_num, image_id,
distiller_result->content_images(img_num).url());
}
diff --git a/chromium/components/dom_distiller/core/distiller_unittest.cc b/chromium/components/dom_distiller/core/distiller_unittest.cc
index 1de5eb92528..48a1ee4db3a 100644
--- a/chromium/components/dom_distiller/core/distiller_unittest.cc
+++ b/chromium/components/dom_distiller/core/distiller_unittest.cc
@@ -60,7 +60,7 @@ const char* kImageData[kTotalImages] = {"abcde", "12345", "VWXYZ"};
const char kDebugLog[] = "Debug Log";
const string GetImageName(int page_num, int image_num) {
- return base::IntToString(page_num) + "_" + base::IntToString(image_num);
+ return base::NumberToString(page_num) + "_" + base::NumberToString(image_num);
}
std::unique_ptr<base::Value> CreateDistilledValueReturnedFromJS(
diff --git a/chromium/components/dom_distiller/core/distiller_url_fetcher.cc b/chromium/components/dom_distiller/core/distiller_url_fetcher.cc
index 035d40c08b6..c4450a2e7c6 100644
--- a/chromium/components/dom_distiller/core/distiller_url_fetcher.cc
+++ b/chromium/components/dom_distiller/core/distiller_url_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/dom_distiller/core/distiller_url_fetcher.h"
+#include "base/bind.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
diff --git a/chromium/components/dom_distiller/core/dom_distiller_features.h b/chromium/components/dom_distiller/core/dom_distiller_features.h
index bdf40a97bce..22ed52f9903 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_features.h
+++ b/chromium/components/dom_distiller/core/dom_distiller_features.h
@@ -10,9 +10,6 @@ namespace dom_distiller {
// Returns true when flag enable-dom-distiller is set or enabled from Finch.
bool IsEnableDomDistillerSet();
-// Returns true when flag enable-sync-articles is set or enabled from Finch.
-bool IsEnableSyncArticlesSet();
-
} // namespace dom_distiller
#endif // COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_FEATURES_H_
diff --git a/chromium/components/dom_distiller/core/dom_distiller_service.cc b/chromium/components/dom_distiller/core/dom_distiller_service.cc
index bf1da18f734..f94b08f92b3 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_service.cc
+++ b/chromium/components/dom_distiller/core/dom_distiller_service.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/guid.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/components/dom_distiller/core/dom_distiller_service_unittest.cc b/chromium/components/dom_distiller/core/dom_distiller_service_unittest.cc
index 10d5652c887..5fe955c555e 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_service_unittest.cc
+++ b/chromium/components/dom_distiller/core/dom_distiller_service_unittest.cc
@@ -410,7 +410,7 @@ TEST_F(DomDistillerServiceTest, TestMultiplePageArticle) {
std::string base_url("http://www.example.com/p");
GURL pages_url[kPageCount];
for (int page_num = 0; page_num < kPageCount; ++page_num) {
- pages_url[page_num] = GURL(base_url + base::IntToString(page_num));
+ pages_url[page_num] = GURL(base_url + base::NumberToString(page_num));
}
MockArticleAvailableCallback article_cb;
@@ -529,7 +529,7 @@ TEST_F(DomDistillerServiceTest, TestGetUrlForMultiPageEntry) {
std::string base_url("http://www.example.com/p");
GURL pages_url[kPageCount];
for (int page_num = 0; page_num < kPageCount; ++page_num) {
- pages_url[page_num] = GURL(base_url + base::IntToString(page_num));
+ pages_url[page_num] = GURL(base_url + base::NumberToString(page_num));
}
MockArticleAvailableCallback article_cb;
diff --git a/chromium/components/dom_distiller/core/dom_distiller_switches.cc b/chromium/components/dom_distiller/core/dom_distiller_switches.cc
index 42c47e4dad6..0603cb42199 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_switches.cc
+++ b/chromium/components/dom_distiller/core/dom_distiller_switches.cc
@@ -17,11 +17,11 @@ const char kAllArticles[] = "allarticles";
const char kOGArticle[] = "opengraph";
const char kAlwaysTrue[] = "alwaystrue";
const char kNone[] = "none";
-};
+} // namespace reader_mode_heuristics
namespace reader_mode_feedback {
const char kOn[] = "on";
const char kOff[] = "off";
-};
+} // namespace reader_mode_feedback
} // namespace switches
diff --git a/chromium/components/dom_distiller/core/dom_distiller_switches.h b/chromium/components/dom_distiller/core/dom_distiller_switches.h
index 1ed7288df69..48e6a030ea2 100644
--- a/chromium/components/dom_distiller/core/dom_distiller_switches.h
+++ b/chromium/components/dom_distiller/core/dom_distiller_switches.h
@@ -28,12 +28,12 @@ extern const char kAllArticles[];
extern const char kOGArticle[];
extern const char kAlwaysTrue[];
extern const char kNone[];
-};
+} // namespace reader_mode_heuristics
namespace reader_mode_feedback {
extern const char kOn[];
extern const char kOff[];
-};
+} // namespace reader_mode_feedback
} // namespace switches
diff --git a/chromium/components/dom_distiller/core/fake_distiller_page.h b/chromium/components/dom_distiller/core/fake_distiller_page.h
index 82829eb9293..2f521c2d34b 100644
--- a/chromium/components/dom_distiller/core/fake_distiller_page.h
+++ b/chromium/components/dom_distiller/core/fake_distiller_page.h
@@ -30,7 +30,7 @@ class MockDistillerPage : public DistillerPage {
public:
MockDistillerPage();
~MockDistillerPage() override;
- bool StringifyOutput() override { return false; };
+ bool StringifyOutput() override { return false; }
MOCK_METHOD2(DistillPageImpl,
void(const GURL& gurl, const std::string& script));
};
diff --git a/chromium/components/dom_distiller/core/page_features.cc b/chromium/components/dom_distiller/core/page_features.cc
index a222bd3f2d6..6de750fc139 100644
--- a/chromium/components/dom_distiller/core/page_features.cc
+++ b/chromium/components/dom_distiller/core/page_features.cc
@@ -152,7 +152,8 @@ std::vector<double> CalculateDerivedFeaturesFromJSON(
return std::vector<double>();
}
- std::unique_ptr<base::Value> json = base::JSONReader::Read(stringified);
+ std::unique_ptr<base::Value> json =
+ base::JSONReader::ReadDeprecated(stringified);
if (!json) {
return std::vector<double>();
}
diff --git a/chromium/components/dom_distiller/core/page_features_unittest.cc b/chromium/components/dom_distiller/core/page_features_unittest.cc
index 93795c34f4c..4efa8dd48a1 100644
--- a/chromium/components/dom_distiller/core/page_features_unittest.cc
+++ b/chromium/components/dom_distiller/core/page_features_unittest.cc
@@ -38,11 +38,12 @@ TEST(DomDistillerPageFeaturesTest, TestCalculateDerivedFeatures) {
"components/test/data/dom_distiller/derived_features.json"),
&expected_output_data));
- std::unique_ptr<base::Value> input_json = base::JSONReader::Read(input_data);
+ std::unique_ptr<base::Value> input_json =
+ base::JSONReader::ReadDeprecated(input_data);
ASSERT_TRUE(input_json);
std::unique_ptr<base::Value> expected_output_json =
- base::JSONReader::Read(expected_output_data);
+ base::JSONReader::ReadDeprecated(expected_output_data);
ASSERT_TRUE(expected_output_json);
base::ListValue* input_entries;
diff --git a/chromium/components/dom_distiller/core/task_tracker_unittest.cc b/chromium/components/dom_distiller/core/task_tracker_unittest.cc
index da98901e707..bc7994854e7 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/bind.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "components/dom_distiller/core/article_distillation_update.h"
diff --git a/chromium/components/dom_distiller/core/url_utils.cc b/chromium/components/dom_distiller/core/url_utils.cc
index c34ec2932c3..cac08dd1b7c 100644
--- a/chromium/components/dom_distiller/core/url_utils.cc
+++ b/chromium/components/dom_distiller/core/url_utils.cc
@@ -35,8 +35,8 @@ const GURL GetDistillerViewUrlFromUrl(const std::string& scheme,
int64_t start_time_ms) {
GURL url(scheme + "://" + base::GenerateGUID());
if (start_time_ms > 0) {
- url = net::AppendOrReplaceQueryParameter(url, kTimeKey,
- base::IntToString(start_time_ms));
+ url = net::AppendOrReplaceQueryParameter(
+ url, kTimeKey, base::NumberToString(start_time_ms));
}
return net::AppendOrReplaceQueryParameter(url, kUrlKey, view_url.spec());
}
diff --git a/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc b/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
index 152ed1479d1..2b235bbefed 100644
--- a/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
+++ b/chromium/components/dom_distiller/standalone/content_extractor_browsertest.cc
@@ -7,6 +7,7 @@
#include <unordered_map>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/id_map.h"
#include "base/files/scoped_temp_dir.h"
diff --git a/chromium/components/dom_distiller/webui/resources/about_dom_distiller.html b/chromium/components/dom_distiller/webui/resources/about_dom_distiller.html
index e602355e5da..4b740266501 100644
--- a/chromium/components/dom_distiller/webui/resources/about_dom_distiller.html
+++ b/chromium/components/dom_distiller/webui/resources/about_dom_distiller.html
@@ -47,6 +47,5 @@ found in the LICENSE file.
</ul>
</div>
</div>
- <script src="chrome://resources/js/i18n_template.js"></script>
</body>
</html>
diff --git a/chromium/components/domain_reliability/config.cc b/chromium/components/domain_reliability/config.cc
index 5f5ba2e2298..5c03e832480 100644
--- a/chromium/components/domain_reliability/config.cc
+++ b/chromium/components/domain_reliability/config.cc
@@ -50,7 +50,7 @@ DomainReliabilityConfig::~DomainReliabilityConfig() {}
// static
std::unique_ptr<const DomainReliabilityConfig>
DomainReliabilityConfig::FromJSON(const base::StringPiece& json) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(json);
base::JSONValueConverter<DomainReliabilityConfig> converter;
std::unique_ptr<DomainReliabilityConfig> config(
new DomainReliabilityConfig());
diff --git a/chromium/components/domain_reliability/context_unittest.cc b/chromium/components/domain_reliability/context_unittest.cc
index 62f5dae7eef..b5b3c092fb0 100644
--- a/chromium/components/domain_reliability/context_unittest.cc
+++ b/chromium/components/domain_reliability/context_unittest.cc
@@ -301,7 +301,8 @@ TEST_F(DomainReliabilityContextTest, ReportUpload) {
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
EXPECT_TRUE(HasStringValue(*entry, "failure_data.custom_error",
@@ -358,7 +359,8 @@ TEST_F(DomainReliabilityContextTest, NetworkChanged) {
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", true));
@@ -388,7 +390,8 @@ TEST_F(DomainReliabilityContextTest,
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
@@ -421,7 +424,8 @@ TEST_F(DomainReliabilityContextTest,
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
@@ -455,7 +459,8 @@ TEST_F(DomainReliabilityContextTest,
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
@@ -500,7 +505,8 @@ TEST_F(DomainReliabilityContextTest, FractionalSampleRate) {
EXPECT_EQ(0, upload_max_depth());
EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
- std::unique_ptr<Value> value = base::JSONReader::Read(upload_report());
+ std::unique_ptr<Value> value =
+ base::JSONReader::ReadDeprecated(upload_report());
const DictionaryValue* entry;
ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry));
EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 0.5));
diff --git a/chromium/components/domain_reliability/header.cc b/chromium/components/domain_reliability/header.cc
index 81f190840f1..93cb220b3b8 100644
--- a/chromium/components/domain_reliability/header.cc
+++ b/chromium/components/domain_reliability/header.cc
@@ -291,7 +291,7 @@ std::string DomainReliabilityHeader::ToString() const {
string += "; ";
}
- string += "max-age=" + base::Int64ToString(max_age_s) + "; ";
+ string += "max-age=" + base::NumberToString(max_age_s) + "; ";
if (config_->include_subdomains)
string += "includeSubdomains; ";
diff --git a/chromium/components/domain_reliability/monitor.cc b/chromium/components/domain_reliability/monitor.cc
index a2a32334aea..6f094f167a6 100644
--- a/chromium/components/domain_reliability/monitor.cc
+++ b/chromium/components/domain_reliability/monitor.cc
@@ -12,11 +12,11 @@
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "components/domain_reliability/baked_in_configs.h"
#include "components/domain_reliability/google_configs.h"
#include "components/domain_reliability/header.h"
#include "components/domain_reliability/quic_error_mapping.h"
-#include "net/base/ip_endpoint.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -187,8 +187,8 @@ void DomainReliabilityMonitor::OnNetworkChanged(
}
void DomainReliabilityMonitor::ClearBrowsingData(
- DomainReliabilityClearMode mode,
- const base::Callback<bool(const GURL&)>& origin_filter) {
+ DomainReliabilityClearMode mode,
+ const base::Callback<bool(const GURL&)>& origin_filter) {
switch (mode) {
case CLEAR_BEACONS:
context_manager_.ClearBeacons(origin_filter);
@@ -242,7 +242,7 @@ DomainReliabilityMonitor::RequestInfo::RequestInfo(
request.GetLoadTimingInfo(&load_timing_info);
request.GetConnectionAttempts(&connection_attempts);
request.PopulateNetErrorDetails(&details);
- if (!request.GetRemoteEndpoint(&remote_endpoint))
+ if (!request.GetTransactionRemoteEndpoint(&remote_endpoint))
remote_endpoint = net::IPEndPoint();
}
diff --git a/chromium/components/domain_reliability/monitor_unittest.cc b/chromium/components/domain_reliability/monitor_unittest.cc
index 1619beef11f..cf32e1d7785 100644
--- a/chromium/components/domain_reliability/monitor_unittest.cc
+++ b/chromium/components/domain_reliability/monitor_unittest.cc
@@ -19,7 +19,6 @@
#include "components/domain_reliability/config.h"
#include "components/domain_reliability/google_configs.h"
#include "components/domain_reliability/test_util.h"
-#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
@@ -72,8 +71,8 @@ class DomainReliabilityMonitorTest : public testing::Test {
static RequestInfo MakeRequestInfo() {
RequestInfo request;
request.status = net::URLRequestStatus();
- request.response_info.socket_address =
- net::HostPortPair::FromString("12.34.56.78:80");
+ request.response_info.remote_endpoint =
+ net::IPEndPoint(net::IPAddress(12, 34, 56, 78), 80);
request.response_info.headers = MakeHttpResponseHeaders(
"HTTP/1.1 200 OK\n\n");
request.response_info.was_cached = false;
@@ -202,8 +201,8 @@ TEST_F(DomainReliabilityMonitorTest, WasFetchedViaProxy) {
RequestInfo request = MakeRequestInfo();
request.url = GURL("http://example/");
request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
- request.response_info.socket_address =
- net::HostPortPair::FromString("127.0.0.1:3128");
+ request.response_info.remote_endpoint =
+ net::IPEndPoint(net::IPAddress(127, 0, 0, 1), 3128);
request.response_info.was_fetched_via_proxy = true;
OnRequestLegComplete(request);
diff --git a/chromium/components/domain_reliability/quic_error_mapping.cc b/chromium/components/domain_reliability/quic_error_mapping.cc
index 42eedc824dc..7aaff704b1f 100644
--- a/chromium/components/domain_reliability/quic_error_mapping.cc
+++ b/chromium/components/domain_reliability/quic_error_mapping.cc
@@ -304,12 +304,13 @@ const struct QuicErrorMapping {
"quic.stream.id.in.stream_id_blocked.frame"},
{quic::QUIC_MAX_STREAM_ID_ERROR, "quic.stream.id.in.max_stream_id.frame"},
{quic::QUIC_HTTP_DECODER_ERROR, "quic.http.decoder.error"},
+ {quic::QUIC_STALE_CONNECTION_CANCELLED, "quic.stale.connection.cancelled"},
// No error. Used as bound while iterating.
{quic::QUIC_LAST_ERROR, "quic.last_error"}};
// Must be updated any time a quic::QuicErrorCode is deprecated in
-// net/quic/core/quic_packets.h.
+// net/third_party/quic/core/quic_error_codes.h.
const int kDeprecatedQuicErrorCount = 5;
const int kActiveQuicErrorCount =
quic::QUIC_LAST_ERROR - kDeprecatedQuicErrorCount;
diff --git a/chromium/components/domain_reliability/util.cc b/chromium/components/domain_reliability/util.cc
index 91d1b42467f..0531a836fbd 100644
--- a/chromium/components/domain_reliability/util.cc
+++ b/chromium/components/domain_reliability/util.cc
@@ -134,6 +134,7 @@ std::string GetDomainReliabilityProtocol(
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_44:
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_45:
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46:
+ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47:
case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99:
return "QUIC";
case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS:
diff --git a/chromium/components/download/content/internal/download_driver_impl.cc b/chromium/components/download/content/internal/download_driver_impl.cc
index bc3559371ca..58653eedde1 100644
--- a/chromium/components/download/content/internal/download_driver_impl.cc
+++ b/chromium/components/download/content/internal/download_driver_impl.cc
@@ -5,10 +5,13 @@
#include "components/download/content/internal/download_driver_impl.h"
#include <set>
+#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/metrics/histogram_functions.h"
+#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "components/download/internal/background_service/driver_entry.h"
@@ -98,6 +101,13 @@ DriverEntry DownloadDriverImpl::CreateDriverEntry(
!item->GetETag().empty() || !item->GetLastModifiedTime().empty();
}
entry.url_chain = item->GetUrlChain();
+
+ if (item->GetState() == DownloadItem::DownloadState::COMPLETE) {
+ std::string hash = item->GetHash();
+ if (!hash.empty())
+ entry.hash256 = base::HexEncode(hash.data(), hash.size());
+ }
+
return entry;
}
diff --git a/chromium/components/download/content/internal/download_driver_impl_unittest.cc b/chromium/components/download/content/internal/download_driver_impl_unittest.cc
index 3e8bbd1c57c..8cbe2b4df41 100644
--- a/chromium/components/download/content/internal/download_driver_impl_unittest.cc
+++ b/chromium/components/download/content/internal/download_driver_impl_unittest.cc
@@ -39,9 +39,12 @@ const char kFakeGuid[] = "fake_guid";
// driver entry.
MATCHER_P(DriverEntryEqual, entry, "") {
return entry.guid == arg.guid && entry.state == arg.state &&
- entry.done == arg.done &&
+ entry.done == arg.done && entry.can_resume == arg.can_resume &&
entry.bytes_downloaded == arg.bytes_downloaded &&
- entry.current_file_path.value() == arg.current_file_path.value();
+ entry.expected_total_size == arg.expected_total_size &&
+ entry.current_file_path.value() == arg.current_file_path.value() &&
+ entry.completion_time == arg.completion_time &&
+ entry.hash256 == arg.hash256;
}
} // namespace
@@ -162,6 +165,7 @@ TEST_F(DownloadDriverImplTest, DownloadItemUpdateEvents) {
fake_item.SetReceivedBytes(1024);
fake_item.SetState(DownloadState::COMPLETE);
+ fake_item.SetHash("01234567ABCDEF");
entry = DownloadDriverImpl::CreateDriverEntry(&fake_item);
EXPECT_CALL(mock_client_, OnDownloadSucceeded(DriverEntryEqual(entry)))
.Times(1)
diff --git a/chromium/components/download/internal/background_service/blob_task_proxy.cc b/chromium/components/download/internal/background_service/blob_task_proxy.cc
index 4c0813902d0..b7afc1cedbe 100644
--- a/chromium/components/download/internal/background_service/blob_task_proxy.cc
+++ b/chromium/components/download/internal/background_service/blob_task_proxy.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/guid.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/download/internal/background_service/config.cc b/chromium/components/download/internal/background_service/config.cc
index 800185c98af..f876e629b78 100644
--- a/chromium/components/download/internal/background_service/config.cc
+++ b/chromium/components/download/internal/background_service/config.cc
@@ -60,6 +60,11 @@ const base::TimeDelta kDefaultWindowEndTime = base::TimeDelta::FromHours(8);
// Default value for start up delay to wait for network stack ready.
const base::TimeDelta kDefaultNetworkStartupDelay =
+ base::TimeDelta::FromSeconds(25);
+
+// Default value for start up delay to wait for network stack ready when
+// triggered from a background task.
+const base::TimeDelta kDefaultNetworkStartupDelayBackgroundTask =
base::TimeDelta::FromSeconds(5);
// The default delay to notify the observer when network changes from
@@ -137,6 +142,12 @@ std::unique_ptr<Configuration> Configuration::CreateFromFinch() {
base::TimeDelta::FromMilliseconds(base::saturated_cast<int>(
GetFinchConfigUInt(kNetworkStartupDelayMsConfig,
kDefaultNetworkStartupDelay.InMilliseconds())));
+ config->network_startup_delay_backgroud_task =
+ base::TimeDelta::FromMilliseconds(
+ base::saturated_cast<int>(GetFinchConfigUInt(
+ kNetworkStartupDelayBackgroundTaskMsConfig,
+ kDefaultNetworkStartupDelayBackgroundTask.InMilliseconds())));
+
config->network_change_delay =
base::TimeDelta::FromMilliseconds(base::saturated_cast<int>(
GetFinchConfigUInt(kNetworkChangeDelayMsConfig,
diff --git a/chromium/components/download/internal/background_service/config.h b/chromium/components/download/internal/background_service/config.h
index 26af2e079af..47a1e1b3faf 100644
--- a/chromium/components/download/internal/background_service/config.h
+++ b/chromium/components/download/internal/background_service/config.h
@@ -54,6 +54,11 @@ constexpr char kWindowEndTimeSecondsConfig[] = "window_end_time_seconds";
// Configuration name for start up delay, measured in milliseconds.
constexpr char kNetworkStartupDelayMsConfig[] = "start_up_delay_ms";
+// Configuration name for start up delay when triggered from a background task,
+// measured in milliseconds.
+constexpr char kNetworkStartupDelayBackgroundTaskMsConfig[] =
+ "start_up_delay_background_task_ms";
+
// Configuration name for the delay to notify network status change, measured in
// milliseconds.
constexpr char kNetworkChangeDelayMsConfig[] = "network_change_delay_ms";
@@ -139,6 +144,10 @@ struct Configuration {
// ready.
base::TimeDelta network_startup_delay;
+ // The delay to initialize internal components to wait for network stack
+ // ready when triggered from a background task.
+ base::TimeDelta network_startup_delay_backgroud_task;
+
// The delay to notify network status changes.
base::TimeDelta network_change_delay;
diff --git a/chromium/components/download/internal/background_service/controller_impl.cc b/chromium/components/download/internal/background_service/controller_impl.cc
index eae2dc6abb2..3c76cce72aa 100644
--- a/chromium/components/download/internal/background_service/controller_impl.cc
+++ b/chromium/components/download/internal/background_service/controller_impl.cc
@@ -305,6 +305,7 @@ DownloadClient ControllerImpl::GetOwnerOfDownload(const std::string& guid) {
void ControllerImpl::OnStartScheduledTask(DownloadTaskType task_type,
TaskFinishedCallback callback) {
+ device_status_listener_->Start(config_->network_startup_delay_backgroud_task);
task_finished_callbacks_[task_type] = std::move(callback);
switch (controller_state_) {
@@ -678,7 +679,8 @@ void ControllerImpl::AttemptToFinalizeSetup() {
return;
}
- device_status_listener_->Start(this);
+ device_status_listener_->SetObserver(this);
+ device_status_listener_->Start(config_->network_startup_delay);
PollActiveDriverDownloads();
CancelOrphanedRequests();
CleanupUnknownFiles();
@@ -1150,6 +1152,7 @@ void ControllerImpl::HandleCompleteDownload(CompletionType type,
DCHECK(driver_entry.has_value());
stats::LogFilePathRenamed(driver_entry->current_file_path !=
entry->target_file_path);
+ stats::LogHashPresence(!driver_entry->hash256.empty());
entry->target_file_path = driver_entry->current_file_path;
entry->completion_time = driver_entry->completion_time;
entry->bytes_downloaded = driver_entry->bytes_downloaded;
@@ -1157,6 +1160,7 @@ void ControllerImpl::HandleCompleteDownload(CompletionType type,
driver_entry->bytes_downloaded,
entry->url_chain, entry->response_headers);
completion_info.blob_handle = driver_entry->blob_handle;
+ completion_info.hash256 = driver_entry->hash256;
entry->last_cleanup_check_time = driver_entry->completion_time;
base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromium/components/download/internal/background_service/controller_impl_unittest.cc b/chromium/components/download/internal/background_service/controller_impl_unittest.cc
index d9341255c64..0cd66071ce7 100644
--- a/chromium/components/download/internal/background_service/controller_impl_unittest.cc
+++ b/chromium/components/download/internal/background_service/controller_impl_unittest.cc
@@ -1010,6 +1010,7 @@ TEST_F(DownloadServiceControllerImplTest, OnDownloadSucceeded) {
CompletionInfo completion_info(dentry.current_file_path,
dentry.bytes_downloaded, entry.url_chain,
entry.response_headers);
+ completion_info.hash256 = "01234567ABCDEF";
EXPECT_CALL(*client_, OnServiceInitialized(false, _)).Times(1);
EXPECT_CALL(*client_, OnDownloadSucceeded(entry.guid, completion_info))
.Times(1);
@@ -1026,6 +1027,7 @@ TEST_F(DownloadServiceControllerImplTest, OnDownloadSucceeded) {
done_dentry.done = true;
done_dentry.current_file_path = completion_info.path;
done_dentry.bytes_downloaded = completion_info.bytes_downloaded;
+ done_dentry.hash256 = completion_info.hash256;
base::Time now = base::Time::Now();
done_dentry.completion_time = now;
@@ -1042,7 +1044,7 @@ TEST_F(DownloadServiceControllerImplTest, OnDownloadSucceeded) {
EXPECT_EQ(now, updated_entry->completion_time);
EXPECT_LE(done_dentry.completion_time + config_->file_keep_alive_time,
now + base::TimeDelta::FromSeconds(start_time));
-
+ EXPECT_EQ(completion_info.hash256, done_dentry.hash256);
task_runner_->RunUntilIdle();
}
@@ -1050,16 +1052,22 @@ TEST_F(DownloadServiceControllerImplTest, CompletionInfoPropagated) {
// Create initial Entry and DriverEntry objects.
Entry succeeded_entry = test::BuildBasicEntry(Entry::State::ACTIVE);
ASSERT_TRUE(succeeded_entry.response_headers);
+ Entry succeeded_with_hash_entry = test::BuildBasicEntry(Entry::State::ACTIVE);
+ ASSERT_TRUE(succeeded_with_hash_entry.response_headers);
Entry failed_entry = test::BuildBasicEntry(Entry::State::ACTIVE);
ASSERT_TRUE(failed_entry.response_headers);
- std::vector<Entry> entries = {succeeded_entry, failed_entry};
+ std::vector<Entry> entries = {succeeded_entry, succeeded_with_hash_entry,
+ failed_entry};
DriverEntry succeeded_dentry =
BuildDriverEntry(succeeded_entry, DriverEntry::State::IN_PROGRESS);
+ DriverEntry succeeded_with_hash_dentry = BuildDriverEntry(
+ succeeded_with_hash_entry, DriverEntry::State::IN_PROGRESS);
DriverEntry failed_dentry =
BuildDriverEntry(failed_entry, DriverEntry::State::IN_PROGRESS);
- driver_->AddTestData(
- std::vector<DriverEntry>{succeeded_dentry, failed_dentry});
+
+ driver_->AddTestData(std::vector<DriverEntry>{
+ succeeded_dentry, succeeded_with_hash_dentry, failed_dentry});
// Mock expectations.
EXPECT_CALL(*client_, OnServiceInitialized(false, _)).Times(1);
@@ -1068,6 +1076,10 @@ TEST_F(DownloadServiceControllerImplTest, CompletionInfoPropagated) {
EXPECT_CALL(*client_, OnDownloadSucceeded(succeeded_entry.guid, _))
.WillOnce(SaveArg<1>(&succeeded_completion_info));
+ CompletionInfo succeeded_with_hash_completion_info;
+ EXPECT_CALL(*client_, OnDownloadSucceeded(succeeded_with_hash_entry.guid, _))
+ .WillOnce(SaveArg<1>(&succeeded_with_hash_completion_info));
+
CompletionInfo failed_completion_info;
EXPECT_CALL(*client_, OnDownloadFailed(failed_entry.guid, _, _))
.WillOnce(SaveArg<1>(&failed_completion_info));
@@ -1084,6 +1096,13 @@ TEST_F(DownloadServiceControllerImplTest, CompletionInfoPropagated) {
succeeded_done_dentry.current_file_path =
base::FilePath::FromUTF8Unsafe("abc");
+ DriverEntry succeeded_with_hash_done_dentry =
+ BuildDriverEntry(succeeded_with_hash_entry, DriverEntry::State::COMPLETE);
+ succeeded_with_hash_done_dentry.done = true;
+ succeeded_with_hash_done_dentry.current_file_path =
+ base::FilePath::FromUTF8Unsafe("abc");
+ succeeded_with_hash_done_dentry.hash256 = "01234567ABCDEF";
+
DriverEntry failed_done_dentry =
BuildDriverEntry(failed_entry, DriverEntry::State::COMPLETE);
succeeded_done_dentry.current_file_path =
@@ -1091,6 +1110,7 @@ TEST_F(DownloadServiceControllerImplTest, CompletionInfoPropagated) {
failed_done_dentry.done = true;
driver_->NotifyDownloadSucceeded(succeeded_done_dentry);
+ driver_->NotifyDownloadSucceeded(succeeded_with_hash_done_dentry);
driver_->NotifyDownloadFailed(failed_done_dentry,
FailureType::NOT_RECOVERABLE);
task_runner_->RunUntilIdle();
@@ -1101,6 +1121,15 @@ TEST_F(DownloadServiceControllerImplTest, CompletionInfoPropagated) {
succeeded_entry.response_headers->raw_headers());
EXPECT_EQ(succeeded_completion_info.path,
succeeded_done_dentry.current_file_path);
+ EXPECT_EQ(succeeded_completion_info.hash256, "");
+
+ ASSERT_TRUE(succeeded_with_hash_completion_info.response_headers);
+ EXPECT_EQ(succeeded_with_hash_completion_info.response_headers->raw_headers(),
+ succeeded_with_hash_entry.response_headers->raw_headers());
+ EXPECT_EQ(succeeded_with_hash_completion_info.path,
+ succeeded_with_hash_done_dentry.current_file_path);
+ EXPECT_EQ(succeeded_with_hash_completion_info.hash256,
+ succeeded_with_hash_done_dentry.hash256);
ASSERT_TRUE(failed_completion_info.response_headers);
EXPECT_EQ(failed_completion_info.response_headers->raw_headers(),
diff --git a/chromium/components/download/internal/background_service/debugging_client.cc b/chromium/components/download/internal/background_service/debugging_client.cc
index 8a0846f5ef1..9bc4298b639 100644
--- a/chromium/components/download/internal/background_service/debugging_client.cc
+++ b/chromium/components/download/internal/background_service/debugging_client.cc
@@ -4,7 +4,9 @@
#include "components/download/internal/background_service/debugging_client.h"
+#include "base/bind.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/download/public/background_service/download_metadata.h"
#include "services/network/public/cpp/resource_request_body.h"
namespace download {
diff --git a/chromium/components/download/internal/background_service/driver_entry.h b/chromium/components/download/internal/background_service/driver_entry.h
index 170279bd0a0..cf3f973939b 100644
--- a/chromium/components/download/internal/background_service/driver_entry.h
+++ b/chromium/components/download/internal/background_service/driver_entry.h
@@ -82,6 +82,10 @@ struct DriverEntry {
// The url chain of the download. Download may encounter redirects, and
// fetches the content from the last url in the chain.
std::vector<GURL> url_chain;
+
+ // An optional base::HexEncoded SHA-256 hash (if available) of the file
+ // contents. If empty there is no available hash value.
+ std::string hash256;
};
} // namespace download
diff --git a/chromium/components/download/internal/background_service/empty_file_monitor.cc b/chromium/components/download/internal/background_service/empty_file_monitor.cc
index 185931f4e6c..6605eee262d 100644
--- a/chromium/components/download/internal/background_service/empty_file_monitor.cc
+++ b/chromium/components/download/internal/background_service/empty_file_monitor.cc
@@ -4,6 +4,7 @@
#include "components/download/internal/background_service/empty_file_monitor.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
namespace download {
diff --git a/chromium/components/download/internal/background_service/file_monitor_impl.cc b/chromium/components/download/internal/background_service/file_monitor_impl.cc
index 9bf542babd5..99cdf48a862 100644
--- a/chromium/components/download/internal/background_service/file_monitor_impl.cc
+++ b/chromium/components/download/internal/background_service/file_monitor_impl.cc
@@ -24,7 +24,8 @@ bool CalculateDiskUtilization(const base::FilePath& file_dir,
int64_t& total_disk_space,
int64_t& free_disk_space,
int64_t& files_size) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::FileEnumerator file_enumerator(file_dir, false /* recursive */,
base::FileEnumerator::FILES);
@@ -79,7 +80,8 @@ bool InitializeAndCreateDownloadDirectory(const base::FilePath& dir_path) {
void GetFilesInDirectory(const base::FilePath& directory,
std::set<base::FilePath>& paths_out) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::FileEnumerator file_enumerator(directory, false /* recursive */,
base::FileEnumerator::FILES);
@@ -91,7 +93,8 @@ void GetFilesInDirectory(const base::FilePath& directory,
void DeleteFilesOnFileThread(const std::set<base::FilePath>& paths,
stats::FileCleanupReason reason) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
int num_delete_attempted = 0;
int num_delete_failed = 0;
int num_delete_by_external = 0;
@@ -116,7 +119,8 @@ void DeleteFilesOnFileThread(const std::set<base::FilePath>& paths,
void DeleteUnknownFilesOnFileThread(
const base::FilePath& directory,
const std::set<base::FilePath>& download_file_paths) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
std::set<base::FilePath> files_in_dir;
GetFilesInDirectory(directory, files_in_dir);
@@ -127,7 +131,8 @@ void DeleteUnknownFilesOnFileThread(
}
bool HardRecoverOnFileThread(const base::FilePath& directory) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
std::set<base::FilePath> files_in_dir;
GetFilesInDirectory(directory, files_in_dir);
DeleteFilesOnFileThread(files_in_dir,
diff --git a/chromium/components/download/internal/background_service/in_memory_download_unittest.cc b/chromium/components/download/internal/background_service/in_memory_download_unittest.cc
index ac4c4d0fff6..532d31c06e4 100644
--- a/chromium/components/download/internal/background_service/in_memory_download_unittest.cc
+++ b/chromium/components/download/internal/background_service/in_memory_download_unittest.cc
@@ -4,6 +4,7 @@
#include "components/download/internal/background_service/in_memory_download.h"
+#include "base/bind.h"
#include "base/guid.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
diff --git a/chromium/components/download/internal/background_service/scheduler/device_status_listener.cc b/chromium/components/download/internal/background_service/scheduler/device_status_listener.cc
index 8398f9c923f..76f11e5db9c 100644
--- a/chromium/components/download/internal/background_service/scheduler/device_status_listener.cc
+++ b/chromium/components/download/internal/background_service/scheduler/device_status_listener.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/download/internal/background_service/scheduler/device_status_listener.h"
+#include "base/bind.h"
namespace download {
@@ -44,7 +45,6 @@ DeviceStatusListener::DeviceStatusListener(
observer_(nullptr),
listening_(false),
is_valid_state_(false),
- startup_delay_(startup_delay),
online_delay_(online_delay),
battery_listener_(std::move(battery_listener)) {}
@@ -58,21 +58,27 @@ const DeviceStatus& DeviceStatusListener::CurrentDeviceStatus() {
return status_;
}
-void DeviceStatusListener::Start(DeviceStatusListener::Observer* observer) {
- if (listening_)
- return;
-
+void DeviceStatusListener::SetObserver(
+ DeviceStatusListener::Observer* observer) {
DCHECK(observer);
observer_ = observer;
+}
+
+void DeviceStatusListener::Start(const base::TimeDelta& start_delay) {
+ if (listening_ || !observer_)
+ return;
// Network stack may shake off all connections after getting the IP address,
// use a delay to wait for potential network setup.
- timer_.Start(FROM_HERE, startup_delay_,
+ timer_.Start(FROM_HERE, start_delay,
base::BindOnce(&DeviceStatusListener::StartAfterDelay,
base::Unretained(this)));
}
void DeviceStatusListener::StartAfterDelay() {
+ if (listening_ || !observer_)
+ return;
+
// Listen to battery status changes.
DCHECK(battery_listener_);
battery_listener_->Start(this);
diff --git a/chromium/components/download/internal/background_service/scheduler/device_status_listener.h b/chromium/components/download/internal/background_service/scheduler/device_status_listener.h
index 54dc4c45c96..be56b7198d9 100644
--- a/chromium/components/download/internal/background_service/scheduler/device_status_listener.h
+++ b/chromium/components/download/internal/background_service/scheduler/device_status_listener.h
@@ -38,9 +38,12 @@ class DeviceStatusListener : public NetworkStatusListener::Observer,
// internal device status when called.
const DeviceStatus& CurrentDeviceStatus();
+ void SetObserver(DeviceStatusListener::Observer* observer);
+
// Starts/stops to listen network and battery change events, virtual for
// testing.
- virtual void Start(DeviceStatusListener::Observer* observer);
+ virtual void Start(const base::TimeDelta& start_delay);
+
virtual void Stop();
protected:
@@ -77,9 +80,6 @@ class DeviceStatusListener : public NetworkStatusListener::Observer,
// Used to start the device listener or notify network change after a delay.
base::OneShotTimer timer_;
- // The delay used on start up.
- base::TimeDelta startup_delay_;
-
// The delay used when network status becomes online.
base::TimeDelta online_delay_;
diff --git a/chromium/components/download/internal/background_service/scheduler/device_status_listener_unittest.cc b/chromium/components/download/internal/background_service/scheduler/device_status_listener_unittest.cc
index 070ebe8d2a8..d5e6bda0033 100644
--- a/chromium/components/download/internal/background_service/scheduler/device_status_listener_unittest.cc
+++ b/chromium/components/download/internal/background_service/scheduler/device_status_listener_unittest.cc
@@ -63,8 +63,19 @@ class TestDeviceStatusListener : public DeviceStatusListener {
std::move(battery_listener),
std::move(network_listener)) {}
+ // DeviceStatusListener implementation.
+ void Start(const base::TimeDelta& start_delay) override {
+ // Cache the start delay for verification.
+ start_delay_ = start_delay;
+ DeviceStatusListener::Start(start_delay);
+ }
+
+ base::TimeDelta start_delay() const { return start_delay_; }
+
private:
friend class DeviceStatusListenerTest;
+ base::TimeDelta start_delay_;
+
DISALLOW_COPY_AND_ASSIGN(TestDeviceStatusListener);
};
@@ -86,6 +97,7 @@ class DeviceStatusListenerTest : public testing::Test {
listener_ = std::make_unique<TestDeviceStatusListener>(
std::move(battery_listener), std::move(network_listener));
+ listener_->SetObserver(&mock_observer_);
}
void TearDown() override { listener_.reset(); }
@@ -100,7 +112,7 @@ class DeviceStatusListenerTest : public testing::Test {
EXPECT_CALL(mock_observer_, OnDeviceStatusChanged(_))
.Times(1)
.RetiresOnSaturation();
- listener_->Start(&mock_observer_);
+ listener_->Start(base::TimeDelta());
base::RunLoop().RunUntilIdle();
}
@@ -145,7 +157,8 @@ TEST_F(DeviceStatusListenerTest, InitialNoOptState) {
EXPECT_EQ(DeviceStatus(), listener_->CurrentDeviceStatus());
const int kInitialBatteryPercentage = 45;
- listener_->Start(&mock_observer_);
+ listener_->Start(base::TimeDelta());
+
ChangeBatteryPercentage(kInitialBatteryPercentage);
// We are in no opt state, notify the observer.
@@ -157,6 +170,20 @@ TEST_F(DeviceStatusListenerTest, InitialNoOptState) {
EXPECT_EQ(NetworkStatus::DISCONNECTED, status.network_status);
}
+// Verifies two Start() call will only do initialization for once, and the start
+// delay should be refreshed based on a later Start() call.
+TEST_F(DeviceStatusListenerTest, DuplicateStart) {
+ ChangeNetworkType(ConnectionType::CONNECTION_NONE);
+ SimulateBatteryChange(true); /* Not charging. */
+ EXPECT_EQ(DeviceStatus(), listener_->CurrentDeviceStatus());
+ const auto acutual_delay = base::TimeDelta::FromSeconds(0);
+ listener_->Start(base::TimeDelta::FromSeconds(1));
+ listener_->Start(acutual_delay);
+ EXPECT_CALL(mock_observer_, OnDeviceStatusChanged(_)).Times(1);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(listener_->start_delay(), acutual_delay);
+}
+
TEST_F(DeviceStatusListenerTest, TestValidStateChecks) {
ChangeNetworkType(ConnectionType::CONNECTION_NONE);
SimulateBatteryChange(true);
@@ -164,7 +191,7 @@ TEST_F(DeviceStatusListenerTest, TestValidStateChecks) {
{
EXPECT_CALL(mock_observer_, OnDeviceStatusChanged(_)).Times(0);
- listener_->Start(&mock_observer_);
+ listener_->Start(base::TimeDelta());
EXPECT_FALSE(listener_->is_valid_state());
}
@@ -196,7 +223,7 @@ TEST_F(DeviceStatusListenerTest, TestValidStateChecks) {
// Ensures the observer is notified when network condition changes.
TEST_F(DeviceStatusListenerTest, NotifyObserverNetworkChange) {
- listener_->Start(&mock_observer_);
+ listener_->Start(base::TimeDelta());
// Initial states check.
EXPECT_EQ(NetworkStatus::DISCONNECTED,
@@ -240,7 +267,7 @@ TEST_F(DeviceStatusListenerTest, NotifyObserverBatteryChange) {
SimulateBatteryChange(false); /* Charging. */
EXPECT_EQ(DeviceStatus(), listener_->CurrentDeviceStatus());
- listener_->Start(&mock_observer_);
+ listener_->Start(base::TimeDelta());
EXPECT_CALL(mock_observer_, OnDeviceStatusChanged(
BatteryStatusEqual(BatteryStatus::CHARGING)))
@@ -265,7 +292,7 @@ TEST_F(DeviceStatusListenerTest, NotifyObserverBatteryChange) {
listener_->CurrentDeviceStatus().battery_percentage);
listener_->Stop();
-};
+}
// Verify a sequence of offline->online->offline network state changes.
TEST_F(DeviceStatusListenerTest, OfflineOnlineOffline) {
diff --git a/chromium/components/download/internal/background_service/scheduler/scheduler_impl_unittest.cc b/chromium/components/download/internal/background_service/scheduler/scheduler_impl_unittest.cc
index 35eb57b4973..692471254b3 100644
--- a/chromium/components/download/internal/background_service/scheduler/scheduler_impl_unittest.cc
+++ b/chromium/components/download/internal/background_service/scheduler/scheduler_impl_unittest.cc
@@ -49,7 +49,7 @@ class DownloadSchedulerImplTest : public testing::Test {
void BuildDataEntries(size_t size) {
entries_ = std::vector<Entry>(size, Entry());
for (size_t i = 0; i < size; ++i) {
- entries_[i].guid = base::IntToString(i);
+ entries_[i].guid = base::NumberToString(i);
entries_[i].scheduling_params.battery_requirements =
SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE;
entries_[i].scheduling_params.network_requirements =
diff --git a/chromium/components/download/internal/background_service/stats.cc b/chromium/components/download/internal/background_service/stats.cc
index fc489146494..a5062f36555 100644
--- a/chromium/components/download/internal/background_service/stats.cc
+++ b/chromium/components/download/internal/background_service/stats.cc
@@ -396,5 +396,9 @@ void LogHasUploadData(DownloadClient client, bool has_upload_data) {
base::UmaHistogramBoolean(name, has_upload_data);
}
+void LogHashPresence(bool hash_exists) {
+ UMA_HISTOGRAM_BOOLEAN("Download.Service.Finish.ReportedHash", hash_exists);
+}
+
} // namespace stats
} // namespace download
diff --git a/chromium/components/download/internal/background_service/stats.h b/chromium/components/download/internal/background_service/stats.h
index 11100e1b06d..49de816c97f 100644
--- a/chromium/components/download/internal/background_service/stats.h
+++ b/chromium/components/download/internal/background_service/stats.h
@@ -227,6 +227,9 @@ void LogEntryRetryCount(uint32_t retry_count);
// Records whether the entry was an upload.
void LogHasUploadData(DownloadClient client, bool has_upload_data);
+// Records whether or not a completed entry has a hash value.
+void LogHashPresence(bool hash_exists);
+
} // namespace stats
} // namespace download
diff --git a/chromium/components/download/internal/common/BUILD.gn b/chromium/components/download/internal/common/BUILD.gn
index 0f957ee545b..6ca95c99e18 100644
--- a/chromium/components/download/internal/common/BUILD.gn
+++ b/chromium/components/download/internal/common/BUILD.gn
@@ -2,6 +2,11 @@
# 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("internal") {
visibility = [
":for_tests",
@@ -28,6 +33,7 @@ source_set("internal") {
"download_job_factory.cc",
"download_job_impl.cc",
"download_job_impl.h",
+ "download_path_reservation_tracker.cc",
"download_response_handler.cc",
"download_stats.cc",
"download_task_runner.cc",
@@ -61,6 +67,7 @@ source_set("internal") {
"//components/download/database",
"//components/download/public/common:interfaces",
"//components/download/quarantine",
+ "//components/filename_generation",
"//components/leveldb_proto",
"//mojo/public/c/system",
"//net",
@@ -68,11 +75,38 @@ source_set("internal") {
"//services/network/public/cpp",
]
+ if (is_android) {
+ sources += [
+ "android/download_collection_bridge.cc",
+ "android/download_collection_bridge.h",
+ ]
+
+ deps += [ ":jni_headers" ]
+ }
+
if (is_posix || is_fuchsia) {
sources += [ "base_file_posix.cc" ]
}
}
+if (is_android) {
+ android_library("internal_java") {
+ java_files = [ "android/java/src/org/chromium/components/download/DownloadCollectionBridge.java" ]
+
+ deps = [
+ "//base:base_java",
+ ]
+ }
+
+ generate_jni("jni_headers") {
+ visibility = [ ":*" ]
+ sources = [
+ "android/java/src/org/chromium/components/download/DownloadCollectionBridge.java",
+ ]
+ jni_package = "components/download/internal/common"
+ }
+}
+
# tests need to access both public and internal sources. So in the component
# build case, we exclude the internal dependency as it is included in the
# test_support target under public.
@@ -98,6 +132,7 @@ source_set("unit_tests") {
"download_db_cache_unittest.cc",
"download_file_unittest.cc",
"download_item_impl_unittest.cc",
+ "download_path_reservation_tracker_unittest.cc",
"download_stats_unittest.cc",
"download_ukm_helper_unittest.cc",
"parallel_download_job_unittest.cc",
diff --git a/chromium/components/download/internal/common/DEPS b/chromium/components/download/internal/common/DEPS
index 328cd269f8d..713aa400ea7 100644
--- a/chromium/components/download/internal/common/DEPS
+++ b/chromium/components/download/internal/common/DEPS
@@ -3,9 +3,11 @@ include_rules = [
"+components/download/downloader/in_progress",
"+components/download/public/common",
"+components/download/quarantine",
+ "+components/filename_generation/filename_generation.h",
"+components/leveldb_proto",
"+components/ukm/test_ukm_recorder.h",
"+crypto",
+ "+jni",
"+mojo/public/c/system",
"+mojo/public/cpp/bindings",
"+net/base/filename_util.h",
diff --git a/chromium/components/download/internal/common/android/download_collection_bridge.cc b/chromium/components/download/internal/common/android/download_collection_bridge.cc
new file mode 100644
index 00000000000..6b2f42f396a
--- /dev/null
+++ b/chromium/components/download/internal/common/android/download_collection_bridge.cc
@@ -0,0 +1,189 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/download/internal/common/android/download_collection_bridge.h"
+
+#include <utility>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/files/file_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/download/public/common/download_features.h"
+#include "components/download/public/common/download_interrupt_reasons.h"
+#include "jni/DownloadCollectionBridge_jni.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::JavaParamRef;
+using base::android::ScopedJavaLocalRef;
+
+namespace download {
+
+namespace {
+// Default value for |kDownloadExpirationDurationFinchKey|, when no parameter is
+// specified.
+const int kDefaultExpirationDurationInDays = 3;
+
+// Finch parameter key value of the duration in days for an intermediate
+// download to expire.
+constexpr char kDownloadExpirationDurationFinchKey[] = "expiration_duration";
+} // namespace
+// static
+base::FilePath DownloadCollectionBridge::CreateIntermediateUriForPublish(
+ const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jurl =
+ ConvertUTF8ToJavaString(env, original_url.spec());
+ ScopedJavaLocalRef<jstring> jreferrer =
+ ConvertUTF8ToJavaString(env, referrer_url.spec());
+ ScopedJavaLocalRef<jstring> jfile_name =
+ ConvertUTF16ToJavaString(env, file_name.AsUTF16Unsafe());
+ ScopedJavaLocalRef<jstring> jmime_type =
+ ConvertUTF8ToJavaString(env, mime_type);
+ ScopedJavaLocalRef<jstring> jcontent_uri =
+ Java_DownloadCollectionBridge_createIntermediateUriForPublish(
+ env, jfile_name, jmime_type, jurl, jreferrer);
+ if (jcontent_uri) {
+ std::string content_uri = ConvertJavaStringToUTF8(env, jcontent_uri);
+ return base::FilePath(content_uri);
+ }
+ return base::FilePath();
+}
+
+// static
+bool DownloadCollectionBridge::ShouldPublishDownload(
+ const base::FilePath& file_path) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jfile_path =
+ ConvertUTF16ToJavaString(env, file_path.AsUTF16Unsafe());
+ return Java_DownloadCollectionBridge_shouldPublishDownload(env, jfile_path);
+}
+
+// static
+DownloadInterruptReason DownloadCollectionBridge::MoveFileToIntermediateUri(
+ const base::FilePath& source_path,
+ const base::FilePath& destination_uri) {
+ DCHECK(!source_path.IsContentUri());
+ DCHECK(destination_uri.IsContentUri());
+
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jsource =
+ ConvertUTF8ToJavaString(env, source_path.value());
+ ScopedJavaLocalRef<jstring> jdestination =
+ ConvertUTF8ToJavaString(env, destination_uri.value());
+ bool success = Java_DownloadCollectionBridge_copyFileToIntermediateUri(
+ env, jsource, jdestination);
+ base::DeleteFile(source_path, false);
+ return success ? DOWNLOAD_INTERRUPT_REASON_NONE
+ : DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
+}
+
+// static
+void DownloadCollectionBridge::DeleteIntermediateUri(
+ const base::FilePath& intermediate_uri) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> juri =
+ ConvertUTF8ToJavaString(env, intermediate_uri.value());
+ Java_DownloadCollectionBridge_deleteIntermediateUri(env, juri);
+}
+
+// static
+base::FilePath DownloadCollectionBridge::PublishDownload(
+ const base::FilePath& intermediate_uri) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jintermediate_uri =
+ ConvertUTF8ToJavaString(env, intermediate_uri.value());
+ ScopedJavaLocalRef<jstring> jfinal_uri =
+ Java_DownloadCollectionBridge_publishDownload(env, jintermediate_uri);
+ if (jfinal_uri) {
+ std::string final_uri = ConvertJavaStringToUTF8(env, jfinal_uri);
+ return base::FilePath(final_uri);
+ }
+ return base::FilePath();
+}
+
+// static
+base::File DownloadCollectionBridge::OpenIntermediateUri(
+ const base::FilePath& intermediate_uri) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jintermediate_uri =
+ ConvertUTF8ToJavaString(env, intermediate_uri.value());
+ int fd =
+ Java_DownloadCollectionBridge_openIntermediateUri(env, jintermediate_uri);
+ if (fd < 0)
+ return base::File();
+ return base::File(fd);
+}
+
+// static
+bool DownloadCollectionBridge::FileNameExists(const base::FilePath& file_name) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jfile_name =
+ ConvertUTF8ToJavaString(env, file_name.value());
+ return Java_DownloadCollectionBridge_fileNameExists(env, jfile_name);
+}
+
+// static
+bool DownloadCollectionBridge::renameDownloadUri(
+ const base::FilePath& download_uri,
+ const base::FilePath& new_display_name) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jdownload_uri =
+ ConvertUTF8ToJavaString(env, download_uri.value());
+ ScopedJavaLocalRef<jstring> jdisplay_name =
+ ConvertUTF8ToJavaString(env, new_display_name.value());
+ return Java_DownloadCollectionBridge_renameDownloadUri(env, jdownload_uri,
+ jdisplay_name);
+}
+
+// static
+void DownloadCollectionBridge::GetDisplayNamesForDownloads(
+ GetDisplayNamesCallback cb) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jobjectArray> jdisplay_infos =
+ Java_DownloadCollectionBridge_getDisplayNamesForDownloads(env);
+ auto result = std::make_unique<std::map<std::string, base::FilePath>>();
+ if (!jdisplay_infos) {
+ std::move(cb).Run(std::move(result));
+ return;
+ }
+ jsize count = env->GetArrayLength(jdisplay_infos.obj());
+ for (jsize i = 0; i < count; ++i) {
+ base::android::ScopedJavaLocalRef<jobject> jdisplay_info(
+ env, env->GetObjectArrayElement(jdisplay_infos.obj(), i));
+ ScopedJavaLocalRef<jstring> juri =
+ Java_DisplayNameInfo_getDownloadUri(env, jdisplay_info);
+ ScopedJavaLocalRef<jstring> jdisplay_name =
+ Java_DisplayNameInfo_getDisplayName(env, jdisplay_info);
+ if (juri && jdisplay_name) {
+ std::string uri = ConvertJavaStringToUTF8(env, juri);
+ std::string display_name = ConvertJavaStringToUTF8(env, jdisplay_name);
+ result->emplace(uri, display_name);
+ }
+ }
+ std::move(cb).Run(std::move(result));
+}
+
+// static
+bool DownloadCollectionBridge::NeedToRetrieveDisplayNames() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ return Java_DownloadCollectionBridge_needToRetrieveDisplayNames(env);
+}
+
+jint JNI_DownloadCollectionBridge_GetExpirationDurationInDays(JNIEnv* env) {
+ std::string finch_value = base::GetFieldTrialParamValueByFeature(
+ features::kRefreshExpirationDate, kDownloadExpirationDurationFinchKey);
+ int days;
+ return base::StringToInt(finch_value, &days)
+ ? days
+ : kDefaultExpirationDurationInDays;
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/common/android/download_collection_bridge.h b/chromium/components/download/internal/common/android/download_collection_bridge.h
new file mode 100644
index 00000000000..f3f725b296f
--- /dev/null
+++ b/chromium/components/download/internal/common/android/download_collection_bridge.h
@@ -0,0 +1,81 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_DOWNLOAD_INTERNAL_COMMON_ANDROID_DOWNLOAD_COLLECTION_BRIDGE_H_
+#define COMPONENTS_DOWNLOAD_INTERNAL_COMMON_ANDROID_DOWNLOAD_COLLECTION_BRIDGE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "base/files/file.h"
+#include "base/macros.h"
+#include "components/download/public/common/download_export.h"
+#include "components/download/public/common/download_file.h"
+#include "components/download/public/common/in_progress_download_manager.h"
+
+namespace download {
+
+// Native class talking to the java side to publish a download to public
+// download collection.
+class COMPONENTS_DOWNLOAD_EXPORT DownloadCollectionBridge {
+ public:
+ // Creates the intermediate URI for download to write to.
+ // Called on non UI thread.
+ static base::FilePath CreateIntermediateUriForPublish(
+ const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type);
+ // Returns whether a download needs to be published.
+ // Can be called on any thread.
+ static bool ShouldPublishDownload(const base::FilePath& file_path);
+
+ // Moves existing file content to the intermediate Uri, and remove
+ // |source_path|.
+ // Called on non UI thread.
+ static DownloadInterruptReason MoveFileToIntermediateUri(
+ const base::FilePath& source_path,
+ const base::FilePath& destination_uri);
+
+ // Deletes the intermediate Uri that is being written to.
+ // Called on non UI thread.
+ static void DeleteIntermediateUri(const base::FilePath& intermediate_uri);
+
+ // Publishes the intermediate Uri to public download collection, and returns
+ // the final Uri.
+ // Called on non UI thread.
+ static base::FilePath PublishDownload(const base::FilePath& intermediate_uri);
+
+ // Opens the intermediate Uri for writing.
+ // Called on non UI thread.
+ static base::File OpenIntermediateUri(const base::FilePath& intermediate_uri);
+
+ // Checks whether a file name exists.
+ // Called on non UI thread.
+ static bool FileNameExists(const base::FilePath& file_name);
+
+ // Renames a content URI download to |new_display_name|. Returns true on
+ // success, and false otherwise.
+ // Called on non UI thread.
+ static bool renameDownloadUri(const base::FilePath& download_uri,
+ const base::FilePath& new_display_name);
+
+ // Whether download display names needs to be retrieved.
+ // TODO(qinmin): move display names to history and in-progress DB.
+ // Can be called on any thread.
+ static bool NeedToRetrieveDisplayNames();
+
+ using GetDisplayNamesCallback =
+ base::OnceCallback<void(InProgressDownloadManager::DisplayNames)>;
+ // Gets the display name for all downloads.
+ // Called on non UI thread.
+ static void GetDisplayNamesForDownloads(GetDisplayNamesCallback cb);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DownloadCollectionBridge);
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_INTERNAL_COMMON_ANDROID_DOWNLOAD_COLLECTION_BRIDGE_H_
diff --git a/chromium/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java b/chromium/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java
new file mode 100644
index 00000000000..e45a5b67fa3
--- /dev/null
+++ b/chromium/components/download/internal/common/android/java/src/org/chromium/components/download/DownloadCollectionBridge.java
@@ -0,0 +1,291 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.download;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Helper class for publishing download files to the public download collection.
+ */
+@JNINamespace("download")
+public class DownloadCollectionBridge {
+ // Singleton instance that allows embedders to replace their implementation.
+ private static DownloadCollectionBridge sDownloadCollectionBridge;
+ private static final String TAG = "DownloadCollection";
+ // Guards access to sDownloadCollectionBridge.
+ private static final Object sLock = new Object();
+
+ /**
+ * Class representing the Uri and display name pair for downloads.
+ */
+ protected static class DisplayNameInfo {
+ private final String mUri;
+ private final String mDisplayName;
+
+ public DisplayNameInfo(String uri, String displayName) {
+ mUri = uri;
+ mDisplayName = displayName;
+ }
+
+ @CalledByNative("DisplayNameInfo")
+ private String getDownloadUri() {
+ return mUri;
+ }
+
+ @CalledByNative("DisplayNameInfo")
+ private String getDisplayName() {
+ return mDisplayName;
+ }
+ }
+
+ /**
+ * Return getDownloadCollectionBridge singleton.
+ */
+ public static DownloadCollectionBridge getDownloadCollectionBridge() {
+ synchronized (sLock) {
+ if (sDownloadCollectionBridge == null) {
+ sDownloadCollectionBridge = new DownloadCollectionBridge();
+ }
+ }
+ return sDownloadCollectionBridge;
+ }
+
+ /**
+ * Sets the singlton object to use later.
+ */
+ public static void setDownloadCollectionBridge(DownloadCollectionBridge bridge) {
+ synchronized (sLock) {
+ sDownloadCollectionBridge = bridge;
+ }
+ }
+
+ /**
+ * Returns whether a download needs to be published.
+ * @param filePath File path of the download.
+ * @return True if the download needs to be published, or false otherwise.
+ */
+ protected boolean needToPublishDownload(final String filePath) {
+ return false;
+ }
+
+ /**
+ * Creates a pending session for download to be written into.
+ * @param fileName Name of the file.
+ * @param mimeType Mime type of the file.
+ * @param originalUrl Originating URL of the download.
+ * @param referrer Referrer of the download.
+ * @return Uri created for the pending session.
+ */
+ protected Uri createPendingSession(final String fileName, final String mimeType,
+ final String originalUrl, final String referrer) {
+ return null;
+ }
+
+ /**
+ * Copy file content from a source file to the pending Uri.
+ * @param sourcePath File content to be copied from.
+ * @param pendingUri Destination Uri to be copied to.
+ * @return true on success, or false otherwise.
+ */
+ protected boolean copyFileToPendingUri(final String sourcePath, final String pendingUri) {
+ return false;
+ }
+
+ /**
+ * Abandon the the intermediate Uri.
+ * @param pendingUri Intermediate Uri that is going to be deleted.
+ */
+ protected void abandonPendingUri(final String pendingUri) {}
+
+ /**
+ * Publish a completed download to public repository.
+ * @param pendingUri Pending uri to publish.
+ * @return Uri of the published file.
+ */
+ protected Uri publishCompletedDownload(final String pendingUri) {
+ return null;
+ }
+
+ /**
+ * @return whether a download with the file name exists.
+ */
+ protected boolean checkFileNameExists(final String fileName) {
+ return false;
+ }
+
+ /**
+ * Renames a download Uri with a display name.
+ * @param downloadUri Uri of the download.
+ * @param displayName New display name for the download.
+ * @return whether rename was successful.
+ */
+ protected boolean rename(final String downloadUri, final String displayName) {
+ return false;
+ }
+
+ /**
+ * @return Whether download display names needs to be retrieved.
+ */
+ protected boolean needToGetDisplayNames() {
+ return false;
+ }
+
+ /**
+ * Gets the display names for all downloads
+ * @return an array of download Uri and display name pair.
+ */
+ protected DisplayNameInfo[] getDisplayNames() {
+ return null;
+ }
+
+ /**
+ * @return whether download collection is supported.
+ */
+ protected boolean isDownloadCollectionSupported() {
+ return false;
+ }
+
+ /**
+ * Refreshes the expiration date so the unpublished download won't get abandoned.
+ * @param intermediateUri The intermediate Uri that is not yet published.
+ */
+ protected void refreshExpirationDate(final String intermediateUri) {}
+
+ /**
+ * Creates an intermediate URI for download to be written into. On completion, call
+ * nativeOnCreateIntermediateUriResult() with |callbackId|.
+ * @param fileName Name of the file.
+ * @param mimeType Mime type of the file.
+ * @param originalUrl Originating URL of the download.
+ * @param referrer Referrer of the download.
+ */
+ @CalledByNative
+ private static String createIntermediateUriForPublish(final String fileName,
+ final String mimeType, final String originalUrl, final String referrer) {
+ Uri uri = getDownloadCollectionBridge().createPendingSession(
+ fileName, mimeType, originalUrl, referrer);
+ return uri == null ? null : uri.toString();
+ }
+
+ /**
+ * Returns whether a download needs to be published.
+ * @param filePath File path of the download.
+ * @return True if the download needs to be published, or false otherwise.
+ */
+ @CalledByNative
+ private static boolean shouldPublishDownload(final String filePath) {
+ return getDownloadCollectionBridge().needToPublishDownload(filePath);
+ }
+
+ /**
+ * Copies file content from a source file to the destination Uri.
+ * @param sourcePath File content to be copied from.
+ * @param destinationUri Destination Uri to be copied to.
+ * @return True on success, or false otherwise.
+ */
+ @CalledByNative
+ private static boolean copyFileToIntermediateUri(
+ final String sourcePath, final String destinationUri) {
+ return getDownloadCollectionBridge().copyFileToPendingUri(sourcePath, destinationUri);
+ }
+
+ /**
+ * Deletes the intermediate Uri.
+ * @param uri Intermediate Uri that is going to be deleted.
+ */
+ @CalledByNative
+ private static void deleteIntermediateUri(final String uri) {
+ getDownloadCollectionBridge().abandonPendingUri(uri);
+ }
+
+ /**
+ * Publishes the completed download to public download collection.
+ * @param intermediateUri Intermediate Uri that is going to be published.
+ * @return Uri of the published file.
+ */
+ @CalledByNative
+ private static String publishDownload(final String intermediateUri) {
+ Uri uri = getDownloadCollectionBridge().publishCompletedDownload(intermediateUri);
+ return uri == null ? null : uri.toString();
+ }
+
+ /**
+ * Opens the intermediate Uri for writing.
+ * @param intermediateUri Intermediate Uri that is going to be written to.
+ * @return file descriptor that is opened for writing.
+ */
+ @CalledByNative
+ private static int openIntermediateUri(final String intermediateUri) {
+ try {
+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
+ ParcelFileDescriptor pfd =
+ resolver.openFileDescriptor(Uri.parse(intermediateUri), "rw");
+ getDownloadCollectionBridge().refreshExpirationDate(intermediateUri);
+ return pfd.detachFd();
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot open intermediate Uri.", e);
+ }
+ return -1;
+ }
+
+ /**
+ * @return whether a download with the file name exists.
+ */
+ @CalledByNative
+ private static boolean fileNameExists(final String fileName) {
+ return getDownloadCollectionBridge().checkFileNameExists(fileName);
+ }
+
+ /**
+ * Renames a download Uri with a display name.
+ * @param downloadUri Uri of the download.
+ * @param displayName New display name for the download.
+ * @return whether rename was successful.
+ */
+ @CalledByNative
+ private static boolean renameDownloadUri(final String downloadUri, final String displayName) {
+ return getDownloadCollectionBridge().rename(downloadUri, displayName);
+ }
+
+ /**
+ * @return Whether download display names needs to be retrieved.
+ */
+ @CalledByNative
+ private static boolean needToRetrieveDisplayNames() {
+ return getDownloadCollectionBridge().needToGetDisplayNames();
+ }
+
+ /**
+ * Gets the display names for all downloads
+ * @return an array of download Uri and display name pair.
+ */
+ @CalledByNative
+ private static DisplayNameInfo[] getDisplayNamesForDownloads() {
+ return getDownloadCollectionBridge().getDisplayNames();
+ }
+
+ /**
+ * @return whether download collection is supported.
+ */
+ public static boolean supportsDownloadCollection() {
+ return getDownloadCollectionBridge().isDownloadCollectionSupported();
+ }
+
+ /**
+ * @return number of days for an intermediate download to expire.
+ */
+ public static int getExpirationDurationInDays() {
+ return nativeGetExpirationDurationInDays();
+ }
+
+ private static native int nativeGetExpirationDurationInDays();
+}
diff --git a/chromium/components/download/internal/common/base_file.cc b/chromium/components/download/internal/common/base_file.cc
index 03416fb14a8..d2b4aca398e 100644
--- a/chromium/components/download/internal/common/base_file.cc
+++ b/chromium/components/download/internal/common/base_file.cc
@@ -25,6 +25,11 @@
#include "components/download/quarantine/quarantine.h"
#include "crypto/secure_hash.h"
+#if defined(OS_ANDROID)
+#include "base/android/content_uri_utils.h"
+#include "components/download/internal/common/android/download_collection_bridge.h"
+#endif // defined(OS_ANDROID)
+
#define CONDITIONAL_TRACE(trace) \
do { \
if (download_id_ != DownloadItem::kInvalidId) \
@@ -62,6 +67,29 @@ class FileErrorData : public base::trace_event::ConvertableToTraceFormat {
DownloadInterruptReason interrupt_reason_;
DISALLOW_COPY_AND_ASSIGN(FileErrorData);
};
+
+void InitializeFile(base::File* file, const base::FilePath& file_path) {
+#if defined(OS_ANDROID)
+ if (file_path.IsContentUri()) {
+ *file = DownloadCollectionBridge::OpenIntermediateUri(file_path);
+ return;
+ }
+#endif // defined(OS_ANDROID)
+ file->Initialize(file_path, base::File::FLAG_OPEN_ALWAYS |
+ base::File::FLAG_WRITE |
+ base::File::FLAG_READ);
+}
+
+void DeleteFile(const base::FilePath& file_path) {
+#if defined(OS_ANDROID)
+ if (file_path.IsContentUri()) {
+ DownloadCollectionBridge::DeleteIntermediateUri(file_path);
+ return;
+ }
+#endif // defined(OS_ANDROID)
+ base::DeleteFile(file_path, false);
+}
+
} // namespace
BaseFile::BaseFile(uint32_t download_id) : download_id_(download_id) {
@@ -194,12 +222,21 @@ DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) {
CONDITIONAL_TRACE(BEGIN2("download", "DownloadFileRename", "old_filename",
full_path_.AsUTF8Unsafe(), "new_filename",
new_path.AsUTF8Unsafe()));
+ bool need_to_move_file = true;
+#if defined(OS_ANDROID)
+ if (new_path.IsContentUri()) {
+ rename_result = DownloadCollectionBridge::MoveFileToIntermediateUri(
+ full_path_, new_path);
+ need_to_move_file = false;
+ }
+#endif
+ if (need_to_move_file) {
+ base::CreateDirectory(new_path.DirName());
- base::CreateDirectory(new_path.DirName());
-
- // A simple rename wouldn't work here since we want the file to have
- // permissions / security descriptors that makes sense in the new directory.
- rename_result = MoveFileAndAdjustPermissions(new_path);
+ // A simple rename wouldn't work here since we want the file to have
+ // permissions / security descriptors that makes sense in the new directory.
+ rename_result = MoveFileAndAdjustPermissions(new_path);
+ }
CONDITIONAL_TRACE(END0("download", "DownloadFileRename"));
@@ -236,7 +273,7 @@ void BaseFile::Cancel() {
if (!full_path_.empty()) {
CONDITIONAL_TRACE(
INSTANT0("download", "DownloadFileDeleted", TRACE_EVENT_SCOPE_THREAD));
- base::DeleteFile(full_path_, false);
+ DeleteFile(full_path_);
}
Detach();
@@ -334,9 +371,7 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far,
// Create a new file if it is not provided.
if (!file_.IsValid()) {
- file_.Initialize(full_path_, base::File::FLAG_OPEN_ALWAYS |
- base::File::FLAG_WRITE |
- base::File::FLAG_READ);
+ InitializeFile(&file_, full_path_);
if (!file_.IsValid()) {
return LogNetError("Open/Initialize File",
net::FileErrorToNetError(file_.error_details()));
@@ -446,6 +481,19 @@ DownloadInterruptReason BaseFile::LogInterruptReason(
return reason;
}
+#if defined(OS_ANDROID)
+DownloadInterruptReason BaseFile::PublishDownload() {
+ Close();
+ base::FilePath new_path =
+ DownloadCollectionBridge::PublishDownload(full_path_);
+ if (!new_path.empty()) {
+ full_path_ = new_path;
+ return DOWNLOAD_INTERRUPT_REASON_NONE;
+ }
+ return DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
+}
+#endif // defined(OS_ANDROID)
+
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
namespace {
diff --git a/chromium/components/download/internal/common/base_file_win.cc b/chromium/components/download/internal/common/base_file_win.cc
index 5af320732d9..97a8417f141 100644
--- a/chromium/components/download/internal/common/base_file_win.cc
+++ b/chromium/components/download/internal/common/base_file_win.cc
@@ -235,7 +235,8 @@ DownloadInterruptReason MapShFileOperationCodes(int code) {
// Returns a network error, or net::OK for success.
DownloadInterruptReason BaseFile::MoveFileAndAdjustPermissions(
const base::FilePath& new_path) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
// The parameters to SHFileOperation must be terminated with 2 NULL chars.
base::FilePath::StringType source = full_path_.value();
diff --git a/chromium/components/download/internal/common/download_db_cache.cc b/chromium/components/download/internal/common/download_db_cache.cc
index 4a117d3c28e..7e81fd7ef99 100644
--- a/chromium/components/download/internal/common/download_db_cache.cc
+++ b/chromium/components/download/internal/common/download_db_cache.cc
@@ -4,6 +4,7 @@
#include "components/download/internal/common/download_db_cache.h"
+#include "base/bind.h"
#include "components/download/database/download_db.h"
#include "components/download/database/download_db_conversions.h"
#include "components/download/database/download_db_entry.h"
diff --git a/chromium/components/download/internal/common/download_file_impl.cc b/chromium/components/download/internal/common/download_file_impl.cc
index f24872f25cf..e433cb0822c 100644
--- a/chromium/components/download/internal/common/download_file_impl.cc
+++ b/chromium/components/download/internal/common/download_file_impl.cc
@@ -13,7 +13,9 @@
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "components/download/internal/common/parallel_download_utils.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_destination_observer.h"
@@ -25,6 +27,10 @@
#include "net/base/io_buffer.h"
#include "services/network/public/cpp/features.h"
+#if defined(OS_ANDROID)
+#include "components/download/internal/common/android/download_collection_bridge.h"
+#endif // defined(OS_ANDROID)
+
namespace download {
namespace {
@@ -313,6 +319,30 @@ void DownloadFileImpl::RenameAndAnnotate(
RenameWithRetryInternal(std::move(parameters));
}
+#if defined(OS_ANDROID)
+void DownloadFileImpl::CreateIntermediateUriForPublish(
+ const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type,
+ const RenameCompletionCallback& callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::FilePath content_path =
+ DownloadCollectionBridge::CreateIntermediateUriForPublish(
+ original_url, referrer_url, file_name, mime_type);
+ DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
+ if (!content_path.empty())
+ reason = file_.Rename(content_path);
+ OnRenameComplete(reason, content_path, callback);
+}
+
+void DownloadFileImpl::PublishDownload(
+ const RenameCompletionCallback& callback) {
+ DownloadInterruptReason reason = file_.PublishDownload();
+ OnRenameComplete(reason, file_.full_path(), callback);
+}
+#endif // defined(OS_ANDROID)
+
base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename(
int attempt_number) {
DCHECK_GE(attempt_number, 0);
@@ -350,11 +380,7 @@ void DownloadFileImpl::RenameWithRetryInternal(
base::FilePath new_path = parameters->new_path;
if ((parameters->option & UNIQUIFY) && new_path != file_.full_path()) {
- int uniquifier =
- base::GetUniquePathNumber(new_path, base::FilePath::StringType());
- if (uniquifier > 0)
- new_path = new_path.InsertBeforeExtensionASCII(
- base::StringPrintf(" (%d)", uniquifier));
+ new_path = base::GetUniquePath(new_path);
}
DownloadInterruptReason reason = file_.Rename(new_path);
@@ -391,6 +417,13 @@ void DownloadFileImpl::RenameWithRetryInternal(
parameters->referrer_url);
}
+ OnRenameComplete(reason, new_path, parameters->completion_callback);
+}
+
+void DownloadFileImpl::OnRenameComplete(
+ DownloadInterruptReason reason,
+ const base::FilePath& new_path,
+ const RenameCompletionCallback& callback) {
if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
// Make sure our information is updated, since we're about to
// error out.
@@ -401,13 +434,13 @@ void DownloadFileImpl::RenameWithRetryInternal(
// the download being interrupted.
for (auto& stream : source_streams_)
stream.second->ClearDataReadyCallback();
-
- new_path.clear();
}
main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(parameters->completion_callback, reason, new_path));
+ FROM_HERE, base::BindOnce(callback, reason,
+ reason == DOWNLOAD_INTERRUPT_REASON_NONE
+ ? new_path
+ : base::FilePath()));
}
void DownloadFileImpl::Detach() {
diff --git a/chromium/components/download/internal/common/download_file_unittest.cc b/chromium/components/download/internal/common/download_file_unittest.cc
index 6420750219e..fb89b4c5797 100644
--- a/chromium/components/download/internal/common/download_file_unittest.cc
+++ b/chromium/components/download/internal/common/download_file_unittest.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -502,10 +503,10 @@ class DownloadFileTestWithRename
// DownloadFileTestWithRename.<FooTest> will be instantiated once with
// RenameAndAnnotate as the value parameter and once with RenameAndUniquify as
// the value parameter.
-INSTANTIATE_TEST_CASE_P(DownloadFile,
- DownloadFileTestWithRename,
- ::testing::Values(RENAME_AND_ANNOTATE,
- RENAME_AND_UNIQUIFY));
+INSTANTIATE_TEST_SUITE_P(DownloadFile,
+ DownloadFileTestWithRename,
+ ::testing::Values(RENAME_AND_ANNOTATE,
+ RENAME_AND_UNIQUIFY));
const char DownloadFileTest::kTestData1[] =
"Let's write some data to the file!\n";
diff --git a/chromium/components/download/internal/common/download_item_impl.cc b/chromium/components/download/internal/common/download_item_impl.cc
index 4b536f504a4..919c614041c 100644
--- a/chromium/components/download/internal/common/download_item_impl.cc
+++ b/chromium/components/download/internal/common/download_item_impl.cc
@@ -41,6 +41,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
+#include "build/build_config.h"
#include "components/download/database/in_progress/download_entry.h"
#include "components/download/internal/common/download_job_impl.h"
#include "components/download/internal/common/parallel_download_utils.h"
@@ -58,6 +59,10 @@
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#if defined(OS_ANDROID)
+#include "components/download/internal/common/android/download_collection_bridge.h"
+#endif // defined(OS_ANDROID)
+
namespace download {
namespace {
@@ -1122,17 +1127,11 @@ void DownloadItemImpl::UpdateValidatorsOnResumption(
// Record some stats. If the precondition failed (the server returned
// HTTP_PRECONDITION_FAILED), then the download will automatically retried as
// a full request rather than a partial. Full restarts clobber validators.
- int origin_state = 0;
- if (chain_iter != new_create_info.url_chain.end())
- origin_state |= ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS;
if (etag_ != new_create_info.etag ||
last_modified_time_ != new_create_info.last_modified) {
received_slices_.clear();
destination_info_.received_bytes = 0;
- origin_state |= ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED;
}
- if (content_disposition_ != new_create_info.content_disposition)
- origin_state |= ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED;
request_info_.url_chain.insert(request_info_.url_chain.end(), chain_iter,
new_create_info.url_chain.end());
@@ -1284,6 +1283,10 @@ void DownloadItemImpl::SetDelegate(DownloadItemImplDelegate* delegate) {
delegate_->Attach();
}
+void DownloadItemImpl::SetDownloadId(uint32_t download_id) {
+ download_id_ = download_id;
+}
+
// **** Download progression cascade
void DownloadItemImpl::Init(bool active,
@@ -1563,6 +1566,20 @@ void DownloadItemImpl::OnDownloadTargetDetermined(
DownloadFile::RenameCompletionCallback callback =
base::Bind(&DownloadItemImpl::OnDownloadRenamedToIntermediateName,
weak_ptr_factory_.GetWeakPtr());
+#if defined(OS_ANDROID)
+ if (download_type_ == TYPE_ACTIVE_DOWNLOAD &&
+ DownloadCollectionBridge::ShouldPublishDownload(GetTargetFilePath())) {
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DownloadFile::CreateIntermediateUriForPublish,
+ // Safe because we control download file lifetime.
+ base::Unretained(download_file_.get()), GetOriginalUrl(),
+ GetReferrerUrl(), GetTargetFilePath().BaseName(),
+ GetMimeType(), std::move(callback)));
+ return;
+ }
+#endif // defined(OS_ANDROID)
+
GetDownloadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&DownloadFile::RenameAndUniquify,
@@ -1582,6 +1599,14 @@ void DownloadItemImpl::OnDownloadRenamedToIntermediateName(
if (DOWNLOAD_INTERRUPT_REASON_NONE == reason) {
SetFullPath(full_path);
+#if defined(OS_ANDROID)
+ // For content URIs, target file path is the same as the current path.
+ if (full_path.IsContentUri()) {
+ if (display_name_.empty())
+ SetDisplayName(GetTargetFilePath().BaseName());
+ destination_info_.target_path = full_path;
+ }
+#endif // defined(OS_ANDROID)
} else {
// TODO(asanka): Even though the rename failed, it may still be possible to
// recover the partial state from the 'before' name.
@@ -1674,6 +1699,17 @@ void DownloadItemImpl::OnDownloadCompleting() {
DownloadFile::RenameCompletionCallback callback =
base::Bind(&DownloadItemImpl::OnDownloadRenamedToFinalName,
weak_ptr_factory_.GetWeakPtr());
+#if defined(OS_ANDROID)
+ if (GetTargetFilePath().IsContentUri()) {
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DownloadFile::PublishDownload,
+ // Safe because we control download file lifetime.
+ base::Unretained(download_file_.get()),
+ std::move(callback)));
+ return;
+ }
+#endif // defined(OS_ANDROID)
GetDownloadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&DownloadFile::RenameAndAnnotate,
diff --git a/chromium/components/download/internal/common/download_item_impl_unittest.cc b/chromium/components/download/internal/common/download_item_impl_unittest.cc
index 06e966d613c..02488f1ed77 100644
--- a/chromium/components/download/internal/common/download_item_impl_unittest.cc
+++ b/chromium/components/download/internal/common/download_item_impl_unittest.cc
@@ -2300,13 +2300,13 @@ class DownloadItemDestinationUpdateRaceTest
base::queue<base::Closure> failing_update_events_;
};
-INSTANTIATE_TEST_CASE_P(Success,
- DownloadItemDestinationUpdateRaceTest,
- ::testing::ValuesIn(GenerateSuccessfulEventLists()));
+INSTANTIATE_TEST_SUITE_P(Success,
+ DownloadItemDestinationUpdateRaceTest,
+ ::testing::ValuesIn(GenerateSuccessfulEventLists()));
-INSTANTIATE_TEST_CASE_P(Failure,
- DownloadItemDestinationUpdateRaceTest,
- ::testing::ValuesIn(GenerateFailingEventLists()));
+INSTANTIATE_TEST_SUITE_P(Failure,
+ DownloadItemDestinationUpdateRaceTest,
+ ::testing::ValuesIn(GenerateFailingEventLists()));
} // namespace
diff --git a/chromium/components/download/internal/common/download_path_reservation_tracker.cc b/chromium/components/download/internal/common/download_path_reservation_tracker.cc
new file mode 100644
index 00000000000..b5eccbdd941
--- /dev/null
+++ b/chromium/components/download/internal/common/download_path_reservation_tracker.cc
@@ -0,0 +1,518 @@
+// 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 "components/download/public/common/download_path_reservation_tracker.h"
+
+#include <stddef.h>
+
+#include <map>
+#include <string>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/sequenced_task_runner.h"
+#include "base/stl_util.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/lazy_task_runner.h"
+#include "base/task/post_task.h"
+#include "base/task_runner_util.h"
+#include "base/third_party/icu/icu_utf.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "components/download/public/common/download_item.h"
+#include "components/filename_generation/filename_generation.h"
+#include "net/base/filename_util.h"
+#include "url/gurl.h"
+
+#if defined(OS_ANDROID)
+#include "components/download/internal/common/android/download_collection_bridge.h"
+#endif
+
+namespace download {
+
+namespace {
+
+typedef DownloadItem* ReservationKey;
+typedef std::map<ReservationKey, base::FilePath> ReservationMap;
+
+// The length of the suffix string we append for an intermediate file name.
+// In the file name truncation, we keep the margin to append the suffix.
+// TODO(kinaba): remove the margin. The user should be able to set maximum
+// possible filename.
+const size_t kIntermediateNameSuffixLength = sizeof(".crdownload") - 1;
+
+#if defined(OS_WIN)
+// On windows, zone identifier is appended to the downloaded file name during
+// annotation. That increases the length of the final target path.
+const size_t kZoneIdentifierLength = sizeof(":Zone.Identifier") - 1;
+#endif // defined(OS_WIN)
+
+// Map of download path reservations. Each reserved path is associated with a
+// ReservationKey=DownloadItem*. This object is destroyed in |Revoke()| when
+// there are no more reservations.
+//
+// It is not an error, although undesirable, to have multiple DownloadItem*s
+// that are mapped to the same path. This can happen if a reservation is created
+// that is supposed to overwrite an existing reservation.
+ReservationMap* g_reservation_map = NULL;
+
+base::LazySequencedTaskRunner g_sequenced_task_runner =
+ LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER({base::MayBlock()});
+
+// Observes a DownloadItem for changes to its target path and state. Updates or
+// revokes associated download path reservations as necessary. Created, invoked
+// and destroyed on the UI thread.
+class DownloadItemObserver : public DownloadItem::Observer,
+ public base::SupportsUserData::Data {
+ public:
+ explicit DownloadItemObserver(DownloadItem* download_item);
+ ~DownloadItemObserver() override;
+
+ private:
+ // DownloadItem::Observer
+ void OnDownloadUpdated(DownloadItem* download) override;
+ void OnDownloadDestroyed(DownloadItem* download) override;
+
+ DownloadItem* download_item_;
+
+ // Last known target path for the download.
+ base::FilePath last_target_path_;
+
+ static const int kUserDataKey;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadItemObserver);
+};
+
+// Returns true if the given path is in use by a path reservation.
+bool IsPathReserved(const base::FilePath& path) {
+ // No reservation map => no reservations.
+ if (g_reservation_map == NULL)
+ return false;
+
+ // We only expect a small number of concurrent downloads at any given time, so
+ // going through all of them shouldn't be too slow.
+ for (ReservationMap::const_iterator iter = g_reservation_map->begin();
+ iter != g_reservation_map->end(); ++iter) {
+ if (base::FilePath::CompareEqualIgnoreCase(iter->second.value(),
+ path.value()))
+ return true;
+ }
+ return false;
+}
+
+// Returns true if the given file name is in use by any path reservation or the
+// file system. Called on the task runner returned by
+// DownloadPathReservationTracker::GetTaskRunner().
+bool IsFileNameInUse(const base::FilePath& path) {
+#if defined(OS_ANDROID)
+ // If there is a reservation, then the path is in use.
+ if (IsPathReserved(path.BaseName()))
+ return true;
+
+ if (DownloadCollectionBridge::FileNameExists(path.BaseName()))
+ return true;
+#endif
+ return false;
+}
+
+// Returns true if the given path is in use by any path reservation or the
+// file system. Called on the task runner returned by
+// DownloadPathReservationTracker::GetTaskRunner().
+bool IsPathInUse(const base::FilePath& path) {
+ // If there is a reservation, then the path is in use.
+ if (IsPathReserved(path))
+ return true;
+
+ // If the path exists in the file system, then the path is in use.
+ if (base::PathExists(path))
+ return true;
+
+ return false;
+}
+
+// Create a unique filename by appending a uniquifier. Modifies |path| in place
+// if successful and returns true. Otherwise |path| is left unmodified and
+// returns false. If |check_file_name_only| is true, this method will only check
+// the name of the file to guarantee that it is unique.
+bool CreateUniqueFilename(int max_path_component_length,
+ const base::Time& download_start_time,
+ base::FilePath* path,
+ bool check_file_name_only) {
+ // Try every numeric uniquifier. Then make one attempt with the timestamp.
+ for (int uniquifier = 1;
+ uniquifier <= DownloadPathReservationTracker::kMaxUniqueFiles + 1;
+ ++uniquifier) {
+ // Append uniquifier.
+ std::string suffix(base::StringPrintf(" (%d)", uniquifier));
+
+ // After we've tried all the unique numeric indices, make one attempt using
+ // the timestamp.
+ if (uniquifier > DownloadPathReservationTracker::kMaxUniqueFiles) {
+ // Generate an ISO8601 compliant local timestamp suffix that avoids
+ // reserved characters that are forbidden on some OSes like Windows.
+ base::Time::Exploded exploded;
+ download_start_time.LocalExplode(&exploded);
+ suffix = base::StringPrintf(
+ " - %04d-%02d-%02dT%02d%02d%02d.%03d", exploded.year, exploded.month,
+ exploded.day_of_month, exploded.hour, exploded.minute,
+ exploded.second, exploded.millisecond);
+ }
+
+ base::FilePath path_to_check(*path);
+ // If the name length limit is available (max_length != -1), and the
+ // the current name exceeds the limit, truncate.
+ if (max_path_component_length != -1) {
+#if defined(OS_WIN)
+ int limit =
+ max_path_component_length -
+ std::max(kIntermediateNameSuffixLength, kZoneIdentifierLength) -
+ suffix.size();
+#else
+ int limit = max_path_component_length - kIntermediateNameSuffixLength -
+ suffix.size();
+#endif // defined(OS_WIN)
+ // If truncation failed, give up uniquification.
+ if (limit <= 0 ||
+ !filename_generation::TruncateFilename(&path_to_check, limit))
+ break;
+ }
+ path_to_check = path_to_check.InsertBeforeExtensionASCII(suffix);
+
+ if ((check_file_name_only && !IsFileNameInUse(path_to_check)) ||
+ (!check_file_name_only && !IsPathInUse(path_to_check))) {
+ *path = path_to_check;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+struct CreateReservationInfo {
+ ReservationKey key;
+ base::FilePath source_path;
+ base::FilePath suggested_path;
+ base::FilePath default_download_path;
+ base::FilePath temporary_path;
+ base::FilePath fallback_directory; // directory to use when target path
+ // cannot be used.
+ bool create_target_directory;
+ base::Time start_time;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action;
+ DownloadPathReservationTracker::ReservedPathCallback completion_callback;
+};
+
+// Check if |target_path| is writable.
+bool IsPathWritable(const CreateReservationInfo& info,
+ const base::FilePath& target_path) {
+ if (base::PathIsWritable(target_path.DirName()))
+ return true;
+ // If a temporary file is already created under the same dir as |target_path|,
+ // return true. This is to avoid the windows network share issue. See
+ // http://crbug.com/383765.
+ return !info.temporary_path.empty() &&
+ info.temporary_path.DirName() == target_path.DirName();
+}
+
+// Called when reservation conflicts happen. Returns the result on whether the
+// conflict can be resolved, and uniquifying the file name if necessary. If
+// |check_file_name_only| is true, this method will only check the name of the
+// file to guarantee that it is unique.
+PathValidationResult ResolveReservationConflicts(
+ const CreateReservationInfo& info,
+ int max_path_component_length,
+ base::FilePath* target_path,
+ bool check_file_name_only) {
+ switch (info.conflict_action) {
+ case DownloadPathReservationTracker::UNIQUIFY:
+ return CreateUniqueFilename(max_path_component_length, info.start_time,
+ target_path, check_file_name_only)
+ ? PathValidationResult::SUCCESS
+ : PathValidationResult::CONFLICT;
+
+ case DownloadPathReservationTracker::OVERWRITE:
+ return PathValidationResult::SUCCESS;
+
+ case DownloadPathReservationTracker::PROMPT:
+ return PathValidationResult::CONFLICT;
+ }
+ NOTREACHED();
+ return PathValidationResult::SUCCESS;
+}
+
+// Verify that |target_path| can be written to and also resolve any conflicts if
+// necessary by uniquifying the filename.
+PathValidationResult ValidatePathAndResolveConflicts(
+ const CreateReservationInfo& info,
+ base::FilePath* target_path) {
+ // Check writability of the suggested path. If we can't write to it, default
+ // to the user's Documents directory. We'll prompt them in this case. No
+ // further amendments are made to the filename since the user is going to be
+ // prompted.
+ if (!IsPathWritable(info, *target_path)) {
+ DVLOG(1) << "Unable to write to path \"" << target_path->value() << "\"";
+ *target_path = info.fallback_directory.Append(target_path->BaseName());
+ return PathValidationResult::PATH_NOT_WRITABLE;
+ }
+
+ int max_path_component_length =
+ base::GetMaximumPathComponentLength(target_path->DirName());
+ // Check the limit of file name length if it could be obtained. When the
+ // suggested name exceeds the limit, truncate or prompt the user.
+ if (max_path_component_length != -1) {
+#if defined(OS_WIN)
+ int limit = max_path_component_length -
+ std::max(kIntermediateNameSuffixLength, kZoneIdentifierLength);
+#else
+ int limit = max_path_component_length - kIntermediateNameSuffixLength;
+#endif // defined(OS_WIN)
+ if (limit <= 0 ||
+ !filename_generation::TruncateFilename(target_path, limit))
+ return PathValidationResult::NAME_TOO_LONG;
+ }
+
+ // Disallow downloading a file onto itself. Assume that downloading a file
+ // onto another file that differs only by case is not enough of a legitimate
+ // edge case to justify determining the case sensitivity of the underlying
+ // filesystem.
+ if (*target_path == info.source_path)
+ return PathValidationResult::SAME_AS_SOURCE;
+
+ if (!IsPathInUse(*target_path))
+ return PathValidationResult::SUCCESS;
+
+ return ResolveReservationConflicts(info, max_path_component_length,
+ target_path, false);
+}
+
+// Called on the task runner returned by
+// DownloadPathReservationTracker::GetTaskRunner() to reserve a download path.
+// This method:
+// - Creates directory |default_download_path| if it doesn't exist.
+// - Verifies that the parent directory of |suggested_path| exists and is
+// writeable.
+// - Truncates the suggested name if it exceeds the filesystem's limit.
+// - Uniquifies |suggested_path| if |should_uniquify_path| is true.
+// - Schedules |callback| on the UI thread with the reserved path and a flag
+// indicating whether the returned path has been successfully verified.
+// - Returns the result of creating the path reservation.
+PathValidationResult CreateReservation(const CreateReservationInfo& info,
+ base::FilePath* reserved_path) {
+ DCHECK(info.suggested_path.IsAbsolute());
+
+ // Create a reservation map if one doesn't exist. It will be automatically
+ // deleted when all the reservations are revoked.
+ if (g_reservation_map == NULL)
+ g_reservation_map = new ReservationMap;
+
+ // Erase the reservation if it already exists. This can happen during
+ // automatic resumption where a new target determination request may be issued
+ // for a DownloadItem without an intervening transition to INTERRUPTED.
+ //
+ // Revoking and re-acquiring the reservation forces us to re-verify the claims
+ // we are making about the path.
+ g_reservation_map->erase(info.key);
+
+ base::FilePath target_path(info.suggested_path.NormalizePathSeparators());
+ base::FilePath target_dir = target_path.DirName();
+ base::FilePath filename = target_path.BaseName();
+
+#if defined(OS_ANDROID)
+ if (DownloadCollectionBridge::ShouldPublishDownload(target_path)) {
+ // If the download is written to a content URI, put file name in the
+ // reservation map as content URIs will always be different.
+ PathValidationResult result = PathValidationResult::SUCCESS;
+ if (IsFileNameInUse(filename)) {
+ int max_path_component_length =
+ base::GetMaximumPathComponentLength(target_path.DirName());
+ result = ResolveReservationConflicts(info, max_path_component_length,
+ &target_path, true);
+ }
+ (*g_reservation_map)[info.key] = target_path.BaseName();
+ *reserved_path = target_path;
+ return result;
+ }
+#endif
+ // Create target_dir if necessary and appropriate. target_dir may be the last
+ // directory that the user selected in a FilePicker; if that directory has
+ // since been removed, do NOT automatically re-create it. Only automatically
+ // create the directory if it is the default Downloads directory or if the
+ // caller explicitly requested automatic directory creation.
+ if (!base::DirectoryExists(target_dir) &&
+ (info.create_target_directory ||
+ (!info.default_download_path.empty() &&
+ (info.default_download_path == target_dir)))) {
+ base::CreateDirectory(target_dir);
+ }
+
+ PathValidationResult result =
+ ValidatePathAndResolveConflicts(info, &target_path);
+ (*g_reservation_map)[info.key] = target_path;
+ *reserved_path = target_path;
+ return result;
+}
+
+// Called on a background thread to update the path of the reservation
+// associated with |key| to |new_path|.
+void UpdateReservation(ReservationKey key, const base::FilePath& new_path) {
+ DCHECK(g_reservation_map != NULL);
+ auto iter = g_reservation_map->find(key);
+ if (iter != g_reservation_map->end()) {
+ iter->second = new_path;
+ } else {
+ // This would happen if an UpdateReservation() notification was scheduled on
+ // the SequencedTaskRunner before ReserveInternal(), or after a Revoke()
+ // call. Neither should happen.
+ NOTREACHED();
+ }
+}
+
+// Called on the FILE thread to remove the path reservation associated with
+// |key|.
+void RevokeReservation(ReservationKey key) {
+ DCHECK(g_reservation_map != NULL);
+ DCHECK(base::ContainsKey(*g_reservation_map, key));
+ g_reservation_map->erase(key);
+ if (g_reservation_map->size() == 0) {
+ // No more reservations. Delete map.
+ delete g_reservation_map;
+ g_reservation_map = NULL;
+ }
+}
+
+void RunGetReservedPathCallback(
+ const DownloadPathReservationTracker::ReservedPathCallback& callback,
+ const base::FilePath* reserved_path,
+ PathValidationResult result) {
+ callback.Run(result, *reserved_path);
+}
+
+// Gets the path reserved in the global |g_reservation_map|. For content Uri,
+// file name instead of file path is used.
+base::FilePath GetReservationPath(DownloadItem* download_item) {
+#if defined(OS_ANDROID)
+ if (download_item->GetTargetFilePath().IsContentUri())
+ return download_item->GetFileNameToReportUser();
+#endif
+ return download_item->GetTargetFilePath();
+}
+
+DownloadItemObserver::DownloadItemObserver(DownloadItem* download_item)
+ : download_item_(download_item),
+ last_target_path_(GetReservationPath(download_item)) {
+ download_item_->AddObserver(this);
+ download_item_->SetUserData(&kUserDataKey, base::WrapUnique(this));
+}
+
+DownloadItemObserver::~DownloadItemObserver() {
+ download_item_->RemoveObserver(this);
+ // DownloadItemObserver is owned by DownloadItem. It should only be getting
+ // destroyed because it's being removed from the UserData pool. No need to
+ // call DownloadItem::RemoveUserData().
+}
+
+void DownloadItemObserver::OnDownloadUpdated(DownloadItem* download) {
+ switch (download->GetState()) {
+ case DownloadItem::IN_PROGRESS: {
+ // Update the reservation.
+ base::FilePath new_target_path = GetReservationPath(download);
+ if (new_target_path != last_target_path_) {
+ DownloadPathReservationTracker::GetTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&UpdateReservation, download, new_target_path));
+ last_target_path_ = new_target_path;
+ }
+ break;
+ }
+
+ case DownloadItem::COMPLETE:
+ // If the download is complete, then it has already been renamed to the
+ // final name. The existence of the file on disk is sufficient to prevent
+ // conflicts from now on.
+
+ case DownloadItem::CANCELLED:
+ // We no longer need the reservation if the download is being removed.
+
+ case DownloadItem::INTERRUPTED:
+ // The download filename will need to be re-generated when the download is
+ // restarted. Holding on to the reservation now would prevent the name
+ // from being used for a subsequent retry attempt.
+ DownloadPathReservationTracker::GetTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&RevokeReservation, download));
+ download->RemoveUserData(&kUserDataKey);
+ break;
+
+ case DownloadItem::MAX_DOWNLOAD_STATE:
+ // Compiler appeasement.
+ NOTREACHED();
+ }
+}
+
+void DownloadItemObserver::OnDownloadDestroyed(DownloadItem* download) {
+ // Items should be COMPLETE/INTERRUPTED/CANCELLED before being destroyed.
+ NOTREACHED();
+ DownloadPathReservationTracker::GetTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&RevokeReservation, download));
+}
+
+// static
+const int DownloadItemObserver::kUserDataKey = 0;
+
+} // namespace
+
+// static
+void DownloadPathReservationTracker::GetReservedPath(
+ DownloadItem* download_item,
+ const base::FilePath& target_path,
+ const base::FilePath& default_path,
+ const base::FilePath& fallback_directory,
+ bool create_directory,
+ FilenameConflictAction conflict_action,
+ const ReservedPathCallback& callback) {
+ // Attach an observer to the download item so that we know when the target
+ // path changes and/or the download is no longer active.
+ new DownloadItemObserver(download_item);
+ // DownloadItemObserver deletes itself.
+
+ base::FilePath* reserved_path = new base::FilePath;
+ base::FilePath source_path;
+ if (download_item->GetURL().SchemeIsFile())
+ net::FileURLToFilePath(download_item->GetURL(), &source_path);
+ CreateReservationInfo info = {static_cast<ReservationKey>(download_item),
+ source_path,
+ target_path,
+ default_path,
+ download_item->GetTemporaryFilePath(),
+ fallback_directory,
+ create_directory,
+ download_item->GetStartTime(),
+ conflict_action,
+ callback};
+
+ base::PostTaskAndReplyWithResult(
+ GetTaskRunner().get(), FROM_HERE,
+ base::BindOnce(&CreateReservation, info, reserved_path),
+ base::BindOnce(&RunGetReservedPathCallback, callback,
+ base::Owned(reserved_path)));
+}
+
+// static
+bool DownloadPathReservationTracker::IsPathInUseForTesting(
+ const base::FilePath& path) {
+ return IsPathInUse(path);
+}
+
+// static
+scoped_refptr<base::SequencedTaskRunner>
+DownloadPathReservationTracker::GetTaskRunner() {
+ return g_sequenced_task_runner.Get();
+}
+
+} // namespace download
diff --git a/chromium/components/download/internal/common/download_path_reservation_tracker_unittest.cc b/chromium/components/download/internal/common/download_path_reservation_tracker_unittest.cc
new file mode 100644
index 00000000000..d9d87459f32
--- /dev/null
+++ b/chromium/components/download/internal/common/download_path_reservation_tracker_unittest.cc
@@ -0,0 +1,728 @@
+// 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 <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/test/test_file_util.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "components/download/public/common/download_path_reservation_tracker.h"
+#include "components/download/public/common/mock_download_item.h"
+#include "net/base/filename_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::AnyNumber;
+using testing::Return;
+using testing::ReturnRef;
+using testing::ReturnRefOfCopy;
+
+namespace download {
+
+namespace {
+
+class DownloadPathReservationTrackerTest : public testing::Test {
+ public:
+ DownloadPathReservationTrackerTest();
+
+ // testing::Test
+ void SetUp() override;
+ void TearDown() override;
+
+ std::unique_ptr<MockDownloadItem> CreateDownloadItem(int32_t id);
+ base::FilePath GetPathInDownloadsDirectory(
+ const base::FilePath::CharType* suffix);
+ bool IsPathInUse(const base::FilePath& path);
+ void RunUntilIdle();
+ void CallGetReservedPath(
+ DownloadItem* download_item,
+ const base::FilePath& target_path,
+ bool create_directory,
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action,
+ base::FilePath* return_path,
+ PathValidationResult* return_result);
+
+ const base::FilePath& default_download_path() const {
+ return default_download_path_;
+ }
+ void set_default_download_path(const base::FilePath& path) {
+ default_download_path_ = path;
+ }
+ void set_fallback_directory(const base::FilePath& path) {
+ fallback_directory_ = path;
+ }
+ // Creates a name of form 'a'*repeat + suffix
+ base::FilePath GetLongNamePathInDownloadsDirectory(
+ size_t repeat,
+ const base::FilePath::CharType* suffix);
+
+ protected:
+ base::ScopedTempDir test_download_dir_;
+ base::FilePath default_download_path_;
+ base::FilePath fallback_directory_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+ private:
+ void TestReservedPathCallback(base::FilePath* return_path,
+ PathValidationResult* return_result,
+ PathValidationResult result,
+ const base::FilePath& path);
+};
+
+DownloadPathReservationTrackerTest::DownloadPathReservationTrackerTest() =
+ default;
+
+void DownloadPathReservationTrackerTest::SetUp() {
+ ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
+ set_default_download_path(test_download_dir_.GetPath());
+}
+
+void DownloadPathReservationTrackerTest::TearDown() {
+ RunUntilIdle();
+}
+
+std::unique_ptr<MockDownloadItem>
+DownloadPathReservationTrackerTest::CreateDownloadItem(int32_t id) {
+ auto item = std::make_unique<::testing::StrictMock<MockDownloadItem>>();
+ EXPECT_CALL(*item, GetId()).WillRepeatedly(Return(id));
+ EXPECT_CALL(*item, GetTargetFilePath())
+ .WillRepeatedly(ReturnRefOfCopy(base::FilePath()));
+ EXPECT_CALL(*item, GetTemporaryFilePath())
+ .WillRepeatedly(Return(base::FilePath()));
+ EXPECT_CALL(*item, GetState())
+ .WillRepeatedly(Return(DownloadItem::IN_PROGRESS));
+ EXPECT_CALL(*item, GetURL()).WillRepeatedly(ReturnRefOfCopy(GURL()));
+
+ base::Time::Exploded exploded_reference_time;
+ exploded_reference_time.year = 2019;
+ exploded_reference_time.month = 1;
+ exploded_reference_time.day_of_month = 23;
+ exploded_reference_time.day_of_week = 3;
+ exploded_reference_time.hour = 16;
+ exploded_reference_time.minute = 35;
+ exploded_reference_time.second = 30;
+ exploded_reference_time.millisecond = 20;
+
+ base::Time test_time;
+ EXPECT_TRUE(
+ base::Time::FromLocalExploded(exploded_reference_time, &test_time));
+
+ EXPECT_CALL(*item, GetStartTime()).WillRepeatedly(Return(test_time));
+ return item;
+}
+
+base::FilePath DownloadPathReservationTrackerTest::GetPathInDownloadsDirectory(
+ const base::FilePath::CharType* suffix) {
+ return default_download_path().Append(suffix).NormalizePathSeparators();
+}
+
+bool DownloadPathReservationTrackerTest::IsPathInUse(
+ const base::FilePath& path) {
+ RunUntilIdle();
+ return DownloadPathReservationTracker::IsPathInUseForTesting(path);
+}
+
+void DownloadPathReservationTrackerTest::RunUntilIdle() {
+ scoped_task_environment_.RunUntilIdle();
+}
+
+void DownloadPathReservationTrackerTest::CallGetReservedPath(
+ DownloadItem* download_item,
+ const base::FilePath& target_path,
+ bool create_directory,
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action,
+ base::FilePath* return_path,
+ PathValidationResult* return_result) {
+ // Weak pointer factory to prevent the callback from running after this
+ // function has returned.
+ base::WeakPtrFactory<DownloadPathReservationTrackerTest> weak_ptr_factory(
+ this);
+ DownloadPathReservationTracker::GetReservedPath(
+ download_item, target_path, default_download_path(), fallback_directory_,
+ create_directory, conflict_action,
+ base::Bind(&DownloadPathReservationTrackerTest::TestReservedPathCallback,
+ weak_ptr_factory.GetWeakPtr(), return_path, return_result));
+ scoped_task_environment_.RunUntilIdle();
+}
+
+void DownloadPathReservationTrackerTest::TestReservedPathCallback(
+ base::FilePath* return_path,
+ PathValidationResult* return_result,
+ PathValidationResult result,
+ const base::FilePath& path) {
+ *return_path = path;
+ *return_result = result;
+}
+
+base::FilePath
+DownloadPathReservationTrackerTest::GetLongNamePathInDownloadsDirectory(
+ size_t repeat,
+ const base::FilePath::CharType* suffix) {
+ return GetPathInDownloadsDirectory(
+ (base::FilePath::StringType(repeat, FILE_PATH_LITERAL('a')) + suffix)
+ .c_str());
+}
+
+void SetDownloadItemState(MockDownloadItem* download_item,
+ DownloadItem::DownloadState state) {
+ EXPECT_CALL(*download_item, GetState()).WillRepeatedly(Return(state));
+ download_item->NotifyObserversDownloadUpdated();
+}
+
+} // namespace
+
+// A basic reservation is acquired and committed.
+TEST_F(DownloadPathReservationTrackerTest, BasicReservation) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ // Destroying the item should release the reservation.
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ item.reset();
+ RunUntilIdle();
+ EXPECT_FALSE(IsPathInUse(path));
+}
+
+// A download that is interrupted should lose its reservation.
+TEST_F(DownloadPathReservationTrackerTest, InterruptedDownload) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ // Once the download is interrupted, the path should become available again.
+ SetDownloadItemState(item.get(), DownloadItem::INTERRUPTED);
+ RunUntilIdle();
+ EXPECT_FALSE(IsPathInUse(path));
+}
+
+// A completed download should also lose its reservation.
+TEST_F(DownloadPathReservationTrackerTest, CompleteDownload) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ // Once the download completes, the path should become available again. For a
+ // real download, at this point only the path reservation will be released.
+ // The path wouldn't be available since it is occupied on disk by the
+ // completed download.
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ RunUntilIdle();
+ EXPECT_FALSE(IsPathInUse(path));
+}
+
+// If there are files on the file system, a unique reservation should uniquify
+// around it.
+TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ base::FilePath path1(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")));
+ // Create a file at |path|, and a .crdownload file at |path1|.
+ ASSERT_EQ(0, base::WriteFile(path, "", 0));
+ ASSERT_EQ(0, base::WriteFile(base::FilePath(path1.value() +
+ FILE_PATH_LITERAL(".crdownload")),
+ "", 0));
+ ASSERT_TRUE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ bool create_directory = false;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::UNIQUIFY;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_TRUE(IsPathInUse(reserved_path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ // The path should be uniquified, skipping over foo.txt but not over
+ // "foo (1).txt.crdownload"
+ EXPECT_EQ(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")).value(),
+ reserved_path.value());
+
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ item.reset();
+ RunUntilIdle();
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_FALSE(IsPathInUse(reserved_path));
+}
+
+// If there are conflicting files on the file system, an overwriting reservation
+// should succeed without altering the target path.
+TEST_F(DownloadPathReservationTrackerTest, ConflictingFiles_Overwrite) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ // Create a file at |path|.
+ ASSERT_EQ(0, base::WriteFile(path, "", 0));
+ ASSERT_TRUE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ bool create_directory = false;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_TRUE(IsPathInUse(reserved_path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ item.reset();
+ RunUntilIdle();
+}
+
+// If the source is a file:// URL that is in the download directory, then Chrome
+// could download the file onto itself. Test that this is flagged by DPRT.
+TEST_F(DownloadPathReservationTrackerTest, ConflictWithSource) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ ASSERT_EQ(0, base::WriteFile(path, "", 0));
+ ASSERT_TRUE(IsPathInUse(path));
+ EXPECT_CALL(*item, GetURL())
+ .WillRepeatedly(ReturnRefOfCopy(net::FilePathToFileURL(path)));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ bool create_directory = false;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::UNIQUIFY;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_EQ(PathValidationResult::SAME_AS_SOURCE, result);
+
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ item.reset();
+ RunUntilIdle();
+}
+
+// Multiple reservations for the same path should uniquify around each other.
+TEST_F(DownloadPathReservationTrackerTest, ConflictingReservations) {
+ std::unique_ptr<MockDownloadItem> item1 = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ base::FilePath uniquified_path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo (1).txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+ ASSERT_FALSE(IsPathInUse(uniquified_path));
+
+ base::FilePath reserved_path1;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ bool create_directory = false;
+
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::UNIQUIFY;
+ CallGetReservedPath(item1.get(), path, create_directory, conflict_action,
+ &reserved_path1, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+
+ {
+ // Requesting a reservation for the same path with uniquification results in
+ // a uniquified path.
+ std::unique_ptr<MockDownloadItem> item2 = CreateDownloadItem(2);
+ base::FilePath reserved_path2;
+ CallGetReservedPath(item2.get(), path, create_directory, conflict_action,
+ &reserved_path2, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_TRUE(IsPathInUse(uniquified_path));
+ EXPECT_EQ(uniquified_path.value(), reserved_path2.value());
+ SetDownloadItemState(item2.get(), DownloadItem::COMPLETE);
+ }
+ RunUntilIdle();
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_FALSE(IsPathInUse(uniquified_path));
+
+ {
+ // Since the previous download item was removed, requesting a reservation
+ // for the same path should result in the same uniquified path.
+ std::unique_ptr<MockDownloadItem> item2 = CreateDownloadItem(2);
+ base::FilePath reserved_path2;
+ CallGetReservedPath(item2.get(), path, create_directory, conflict_action,
+ &reserved_path2, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_TRUE(IsPathInUse(uniquified_path));
+ EXPECT_EQ(uniquified_path.value(), reserved_path2.value());
+ SetDownloadItemState(item2.get(), DownloadItem::COMPLETE);
+ }
+ RunUntilIdle();
+
+ // Now acquire an overwriting reservation. We should end up with the same
+ // non-uniquified path for both reservations.
+ std::unique_ptr<MockDownloadItem> item3 = CreateDownloadItem(2);
+ base::FilePath reserved_path3;
+ conflict_action = DownloadPathReservationTracker::OVERWRITE;
+ CallGetReservedPath(item3.get(), path, create_directory, conflict_action,
+ &reserved_path3, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_FALSE(IsPathInUse(uniquified_path));
+
+ EXPECT_EQ(path.value(), reserved_path1.value());
+ EXPECT_EQ(path.value(), reserved_path3.value());
+
+ SetDownloadItemState(item1.get(), DownloadItem::COMPLETE);
+ SetDownloadItemState(item3.get(), DownloadItem::COMPLETE);
+}
+
+// Two active downloads shouldn't be able to reserve paths that only differ by
+// case.
+TEST_F(DownloadPathReservationTrackerTest, ConflictingCaseReservations) {
+ std::unique_ptr<MockDownloadItem> item1 = CreateDownloadItem(1);
+ std::unique_ptr<MockDownloadItem> item2 = CreateDownloadItem(2);
+
+ base::FilePath path_foo =
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt"));
+ base::FilePath path_Foo =
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo.txt"));
+
+ base::FilePath first_reservation;
+ PathValidationResult result = PathValidationResult::PATH_NOT_WRITABLE;
+ CallGetReservedPath(item1.get(), path_foo, false,
+ DownloadPathReservationTracker::UNIQUIFY,
+ &first_reservation, &result);
+ EXPECT_TRUE(IsPathInUse(path_foo));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path_foo, first_reservation);
+
+ // Foo should also be in use at this point.
+ EXPECT_TRUE(IsPathInUse(path_Foo));
+
+ base::FilePath second_reservation;
+ CallGetReservedPath(item2.get(), path_Foo, false,
+ DownloadPathReservationTracker::UNIQUIFY,
+ &second_reservation, &result);
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(GetPathInDownloadsDirectory(FILE_PATH_LITERAL("Foo (1).txt")),
+ second_reservation);
+ SetDownloadItemState(item1.get(), DownloadItem::COMPLETE);
+ SetDownloadItemState(item2.get(), DownloadItem::COMPLETE);
+}
+
+// If a unique path cannot be determined after trying kMaxUniqueFiles
+// uniquifiers, then the callback should notified that verification failed, and
+// the returned path should be set to the original requested path.
+TEST_F(DownloadPathReservationTrackerTest, UnresolvedConflicts) {
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ // Make room for the path with no uniquifier, the |kMaxUniqueFiles|
+ // numerically uniquified paths, and then one more for the timestamp
+ // uniquified path.
+ std::unique_ptr<MockDownloadItem>
+ items[DownloadPathReservationTracker::kMaxUniqueFiles + 2];
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::UNIQUIFY;
+ bool create_directory = false;
+
+ // Create |kMaxUniqueFiles + 2| reservations for |path|. The first reservation
+ // will have no uniquifier. Then |kMaxUniqueFiles| paths have numeric
+ // uniquifiers. Then one more will have a timestamp uniquifier.
+ for (int i = 0; i <= DownloadPathReservationTracker::kMaxUniqueFiles + 1;
+ i++) {
+ SCOPED_TRACE(testing::Message() << "i = " << i);
+ base::FilePath reserved_path;
+ base::FilePath expected_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ if (i == 0) {
+ expected_path = path;
+ } else if (i > 0 && i <= DownloadPathReservationTracker::kMaxUniqueFiles) {
+ expected_path =
+ path.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", i));
+ } else {
+ expected_path =
+ path.InsertBeforeExtensionASCII(" - 2019-01-23T163530.020");
+ }
+ items[i] = CreateDownloadItem(i);
+ EXPECT_FALSE(IsPathInUse(expected_path));
+ CallGetReservedPath(items[i].get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(expected_path));
+ EXPECT_EQ(expected_path.value(), reserved_path.value());
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ }
+ // The next reservation for |path| will fail to be unique.
+ std::unique_ptr<MockDownloadItem> item =
+ CreateDownloadItem(DownloadPathReservationTracker::kMaxUniqueFiles + 2);
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_EQ(PathValidationResult::CONFLICT, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ for (auto& item : items)
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+}
+
+// If the target directory is unwriteable, then callback should be notified that
+// verification failed.
+TEST_F(DownloadPathReservationTrackerTest, UnwriteableDirectory) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ base::FilePath dir(path.DirName());
+ ASSERT_FALSE(IsPathInUse(path));
+
+ {
+ // Scope for FilePermissionRestorer
+ base::FilePermissionRestorer restorer(dir);
+ EXPECT_TRUE(base::MakeFileUnwritable(dir));
+ base::FilePath fallback_dir(FILE_PATH_LITERAL("/tmp/download"));
+ set_fallback_directory(fallback_dir);
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ // Verification fails.
+ EXPECT_EQ(PathValidationResult::PATH_NOT_WRITABLE, result);
+ EXPECT_EQ(path.BaseName().value(), reserved_path.BaseName().value());
+ EXPECT_EQ(fallback_dir.value(), reserved_path.DirName().value());
+ }
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+}
+
+// If the default download directory doesn't exist, then it should be
+// created. But only if we are actually going to create the download path there.
+TEST_F(DownloadPathReservationTrackerTest, CreateDefaultDownloadPath) {
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo/foo.txt")));
+ base::FilePath dir(path.DirName());
+ ASSERT_FALSE(base::DirectoryExists(dir));
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+
+ {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ // Verification fails because the directory doesn't exist.
+ EXPECT_EQ(PathValidationResult::PATH_NOT_WRITABLE, result);
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ }
+ ASSERT_FALSE(IsPathInUse(path));
+ {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ set_default_download_path(dir);
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ // Verification succeeds because the directory is created.
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_TRUE(base::DirectoryExists(dir));
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ }
+}
+
+// If the target path of the download item changes, the reservation should be
+// updated to match.
+TEST_F(DownloadPathReservationTrackerTest, UpdatesToTargetPath) {
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("foo.txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path.value(), reserved_path.value());
+
+ // The target path is initially empty. If an OnDownloadUpdated() is issued in
+ // this state, we shouldn't lose the reservation.
+ ASSERT_EQ(base::FilePath::StringType(), item->GetTargetFilePath().value());
+ item->NotifyObserversDownloadUpdated();
+ RunUntilIdle();
+ EXPECT_TRUE(IsPathInUse(path));
+
+ // If the target path changes, we should update the reservation to match.
+ base::FilePath new_target_path(
+ GetPathInDownloadsDirectory(FILE_PATH_LITERAL("bar.txt")));
+ ASSERT_FALSE(IsPathInUse(new_target_path));
+ EXPECT_CALL(*item, GetTargetFilePath())
+ .WillRepeatedly(ReturnRef(new_target_path));
+ item->NotifyObserversDownloadUpdated();
+ RunUntilIdle();
+ EXPECT_FALSE(IsPathInUse(path));
+ EXPECT_TRUE(IsPathInUse(new_target_path));
+
+ // Destroying the item should release the reservation.
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+ item.reset();
+ RunUntilIdle();
+ EXPECT_FALSE(IsPathInUse(new_target_path));
+}
+
+// Tests for long name truncation. On other platforms automatic truncation
+// is not performed (yet).
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+
+TEST_F(DownloadPathReservationTrackerTest, BasicTruncation) {
+ int real_max_length =
+ base::GetMaximumPathComponentLength(default_download_path());
+ ASSERT_NE(-1, real_max_length);
+
+#if defined(OS_WIN)
+ const size_t max_length = real_max_length - strlen(":Zone.Identifier");
+#else
+ // TODO(kinaba): the current implementation leaves spaces for appending
+ // ".crdownload". So take it into account. Should be removed in the future.
+ const size_t max_length = real_max_length - 11;
+#endif // defined(OS_WIN)
+
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(GetLongNamePathInDownloadsDirectory(
+ max_length, FILE_PATH_LITERAL(".txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(reserved_path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ // The file name length is truncated to max_length.
+ EXPECT_EQ(max_length, reserved_path.BaseName().value().size());
+ // But the extension is kept unchanged.
+ EXPECT_EQ(path.Extension(), reserved_path.Extension());
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+}
+
+TEST_F(DownloadPathReservationTrackerTest, TruncationConflict) {
+ int real_max_length =
+ base::GetMaximumPathComponentLength(default_download_path());
+ ASSERT_NE(-1, real_max_length);
+#if defined(OS_WIN)
+ const size_t max_length = real_max_length - strlen(":Zone.Identifier");
+#else
+ const size_t max_length = real_max_length - 11;
+#endif // defined(OS_WIN)
+
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(GetLongNamePathInDownloadsDirectory(
+ max_length, FILE_PATH_LITERAL(".txt")));
+ base::FilePath path0(GetLongNamePathInDownloadsDirectory(
+ max_length - 4, FILE_PATH_LITERAL(".txt")));
+ base::FilePath path1(GetLongNamePathInDownloadsDirectory(
+ max_length - 8, FILE_PATH_LITERAL(" (1).txt")));
+ base::FilePath path2(GetLongNamePathInDownloadsDirectory(
+ max_length - 8, FILE_PATH_LITERAL(" (2).txt")));
+ ASSERT_FALSE(IsPathInUse(path));
+ // "aaa...aaaaaaa.txt" (truncated path) and
+ // "aaa...aaa (1).txt" (truncated and first uniquification try) exists.
+ // "aaa...aaa (2).txt" should be used.
+ ASSERT_EQ(0, base::WriteFile(path0, "", 0));
+ ASSERT_EQ(0, base::WriteFile(path1, "", 0));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::NAME_TOO_LONG;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::UNIQUIFY;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ EXPECT_TRUE(IsPathInUse(reserved_path));
+ EXPECT_EQ(PathValidationResult::SUCCESS, result);
+ EXPECT_EQ(path2, reserved_path);
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+}
+
+TEST_F(DownloadPathReservationTrackerTest, TruncationFail) {
+ int real_max_length =
+ base::GetMaximumPathComponentLength(default_download_path());
+ ASSERT_NE(-1, real_max_length);
+#if defined(OS_WIN)
+ const size_t max_length = real_max_length - strlen(":Zone.Identifier");
+#else
+ const size_t max_length = real_max_length - 11;
+#endif // defined(OS_WIN)
+
+ std::unique_ptr<MockDownloadItem> item = CreateDownloadItem(1);
+ base::FilePath path(GetPathInDownloadsDirectory(
+ (FILE_PATH_LITERAL("a.") + base::FilePath::StringType(max_length, 'b'))
+ .c_str()));
+ ASSERT_FALSE(IsPathInUse(path));
+
+ base::FilePath reserved_path;
+ PathValidationResult result = PathValidationResult::SUCCESS;
+ DownloadPathReservationTracker::FilenameConflictAction conflict_action =
+ DownloadPathReservationTracker::OVERWRITE;
+ bool create_directory = false;
+ CallGetReservedPath(item.get(), path, create_directory, conflict_action,
+ &reserved_path, &result);
+ // We cannot truncate a path with very long extension.
+ EXPECT_EQ(PathValidationResult::NAME_TOO_LONG, result);
+ SetDownloadItemState(item.get(), DownloadItem::COMPLETE);
+}
+
+#endif // Platforms that support filename truncation.
+
+} // namespace download
diff --git a/chromium/components/download/internal/common/download_response_handler.cc b/chromium/components/download/internal/common/download_response_handler.cc
index acccd9169fe..7ab6994b362 100644
--- a/chromium/components/download/internal/common/download_response_handler.cc
+++ b/chromium/components/download/internal/common/download_response_handler.cc
@@ -129,7 +129,7 @@ DownloadResponseHandler::CreateDownloadCreateInfo(
create_info->total_bytes = head.content_length > 0 ? head.content_length : 0;
create_info->result = result;
if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
- create_info->remote_address = head.socket_address.host();
+ create_info->remote_address = head.remote_endpoint.ToStringWithoutPort();
create_info->method = method_;
create_info->connection_info = head.connection_info;
create_info->url_chain = url_chain_;
diff --git a/chromium/components/download/internal/common/download_stats.cc b/chromium/components/download/internal/common/download_stats.cc
index 11ac2934c88..f9ec2f1dd91 100644
--- a/chromium/components/download/internal/common/download_stats.cc
+++ b/chromium/components/download/internal/common/download_stats.cc
@@ -401,9 +401,44 @@ constexpr const base::FilePath::CharType* kDangerousFileTypes[] = {
FILE_PATH_LITERAL(".settingcontent-ms"),
FILE_PATH_LITERAL(".oxt"), // 317
FILE_PATH_LITERAL(".pyd"),
- FILE_PATH_LITERAL(".pyo"), // 319
- FILE_PATH_LITERAL(".desktop"), // 320
- FILE_PATH_LITERAL(".cpi"), // 321
+ FILE_PATH_LITERAL(".pyo"), // 319
+ FILE_PATH_LITERAL(".desktop"), // 320
+ FILE_PATH_LITERAL(".cpi"), // 321
+ FILE_PATH_LITERAL(".jpg"), // 322
+ FILE_PATH_LITERAL(".jpeg"), // 323
+ FILE_PATH_LITERAL(".mp3"), // 324
+ FILE_PATH_LITERAL(".mp4"), // 325
+ FILE_PATH_LITERAL(".png"), // 326
+ FILE_PATH_LITERAL(".xls"), // 327
+ FILE_PATH_LITERAL(".doc"), // 328
+ FILE_PATH_LITERAL(".pptx"), // 329
+ FILE_PATH_LITERAL(".csv"), // 330
+ FILE_PATH_LITERAL(".ica"), // 331
+ FILE_PATH_LITERAL(".ppt"), // 332
+ FILE_PATH_LITERAL(".gif"), // 333
+ FILE_PATH_LITERAL(".txt"), // 334
+ FILE_PATH_LITERAL(".package"), // 335
+ FILE_PATH_LITERAL(".tif"), // 336
+ FILE_PATH_LITERAL(".rtf"), // 337
+ FILE_PATH_LITERAL(".webp"), // 338
+ FILE_PATH_LITERAL(".mkv"), // 339
+ FILE_PATH_LITERAL(".wav"), // 340
+ FILE_PATH_LITERAL(".mov"), // 341
+ FILE_PATH_LITERAL(".dot"), // 342
+ FILE_PATH_LITERAL(".dotx"), // 343
+ FILE_PATH_LITERAL(".xlsb"), // 344
+ FILE_PATH_LITERAL(".xlt"), // 345
+ FILE_PATH_LITERAL(".xlm"), // 346
+ FILE_PATH_LITERAL(".xldm"), // 347
+ FILE_PATH_LITERAL(".xla"), // 348
+ FILE_PATH_LITERAL(".xlam"), // 349
+ FILE_PATH_LITERAL(".xll"), // 350
+ FILE_PATH_LITERAL(".xlw"), // 351
+ FILE_PATH_LITERAL(".pot"), // 352
+ FILE_PATH_LITERAL(".potm"), // 353
+ FILE_PATH_LITERAL(".ppsm"), // 354
+ FILE_PATH_LITERAL(".pps"), // 355
+ FILE_PATH_LITERAL(".mobileconfig"), // 356
// NOTE! When you add a type here, please add the UMA value as a comment.
// These must all match DownloadItem.DangerousFileType in
// enums.xml. From 263 onward, they should also match
@@ -1175,4 +1210,9 @@ void RecordInProgressDBCount(InProgressDBCountTypes type) {
UMA_HISTOGRAM_ENUMERATION("Download.InProgressDB.Counts", type);
}
+void RecordDuplicateInProgressDownloadIdCount(int count) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Download.DuplicateInProgressDownloadIdCount",
+ count, 1, 10, 11);
+}
+
} // namespace download
diff --git a/chromium/components/download/internal/common/download_utils.cc b/chromium/components/download/internal/common/download_utils.cc
index 47037e864dd..eb791965b8a 100644
--- a/chromium/components/download/internal/common/download_utils.cc
+++ b/chromium/components/download/internal/common/download_utils.cc
@@ -8,6 +8,7 @@
#include "base/format_macros.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons_utils.h"
#include "components/download/public/common/download_save_info.h"
@@ -19,6 +20,10 @@
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/resource_request.h"
+#if defined(OS_ANDROID)
+#include "base/android/content_uri_utils.h"
+#endif
+
namespace download {
namespace {
@@ -240,9 +245,6 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
request->allow_download = true;
request->is_main_frame = true;
- if (params->render_process_host_id() >= 0)
- request->render_frame_id = params->render_frame_host_routing_id();
-
bool has_upload_data = false;
if (params->post_body()) {
request->request_body = params->post_body();
@@ -532,7 +534,12 @@ bool IsDownloadDone(const GURL& url,
bool DeleteDownloadedFile(const base::FilePath& path) {
DCHECK(GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
-
+#if defined(OS_ANDROID)
+ if (path.IsContentUri()) {
+ base::DeleteContentUri(path);
+ return true;
+ }
+#endif
// Make sure we only delete files.
if (base::DirectoryExists(path))
return true;
diff --git a/chromium/components/download/internal/common/download_worker.cc b/chromium/components/download/internal/common/download_worker.cc
index f101d505ab7..05f82616ecd 100644
--- a/chromium/components/download/internal/common/download_worker.cc
+++ b/chromium/components/download/internal/common/download_worker.cc
@@ -4,6 +4,7 @@
#include "components/download/internal/common/download_worker.h"
+#include "base/bind.h"
#include "components/download/internal/common/resource_downloader.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons.h"
@@ -29,7 +30,7 @@ bool IsURLSafe(int render_process_id, const GURL& url) {
class CompletedInputStream : public InputStream {
public:
- CompletedInputStream(DownloadInterruptReason status) : status_(status){};
+ CompletedInputStream(DownloadInterruptReason status) : status_(status) {}
~CompletedInputStream() override = default;
// InputStream
diff --git a/chromium/components/download/internal/common/in_progress_download_manager.cc b/chromium/components/download/internal/common/in_progress_download_manager.cc
index abecb58e6b8..e6abb7cd024 100644
--- a/chromium/components/download/internal/common/in_progress_download_manager.cc
+++ b/chromium/components/download/internal/common/in_progress_download_manager.cc
@@ -4,9 +4,11 @@
#include "components/download/public/common/in_progress_download_manager.h"
+#include "base/bind.h"
#include "base/optional.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "components/download/database/download_db_entry.h"
#include "components/download/database/download_db_impl.h"
#include "components/download/database/download_namespace.h"
@@ -26,6 +28,10 @@
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_response.h"
+#if defined(OS_ANDROID)
+#include "components/download/internal/common/android/download_collection_bridge.h"
+#endif
+
namespace download {
namespace {
@@ -125,6 +131,16 @@ void CreateDownloadHandlerForNavigation(
main_task_runner);
}
+#if defined(OS_ANDROID)
+void OnDownloadDisplayNamesReturned(
+ DownloadCollectionBridge::GetDisplayNamesCallback callback,
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
+ InProgressDownloadManager::DisplayNames download_names) {
+ main_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), std::move(download_names)));
+}
+#endif
} // namespace
InProgressDownloadManager::InProgressDownloadManager(
@@ -138,6 +154,7 @@ InProgressDownloadManager::InProgressDownloadManager(
download_start_observer_(nullptr),
is_origin_secure_cb_(is_origin_secure_cb),
url_security_policy_(url_security_policy),
+ use_empty_db_(in_progress_db_dir.empty()),
weak_factory_(this) {
Initialize(in_progress_db_dir);
}
@@ -170,6 +187,28 @@ void InProgressDownloadManager::OnUrlDownloadHandlerCreated(
url_download_handlers_.push_back(std::move(downloader));
}
+bool InProgressDownloadManager::DownloadUrl(
+ std::unique_ptr<DownloadUrlParameters> params) {
+ DCHECK(!delegate_);
+ DCHECK(params->is_transient());
+
+ if (!url_loader_factory_getter_)
+ return false;
+
+ if (params->require_safety_checks())
+ return false;
+
+ if (params->file_path().empty())
+ return false;
+
+ // Start the new download, the download should be saved to the file path
+ // specifcied in the |params|.
+ BeginDownload(std::move(params), url_loader_factory_getter_,
+ true /* is_new_download */, GURL() /* site_url */,
+ GURL() /* tab_url */, GURL() /* tab_referral_url */);
+ return true;
+}
+
void InProgressDownloadManager::BeginDownload(
std::unique_ptr<DownloadUrlParameters> params,
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
@@ -221,7 +260,7 @@ void InProgressDownloadManager::Initialize(
DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD,
in_progress_db_dir));
download_db_cache_->Initialize(base::BindOnce(
- &InProgressDownloadManager::OnInitialized, weak_factory_.GetWeakPtr()));
+ &InProgressDownloadManager::OnDBInitialized, weak_factory_.GetWeakPtr()));
}
void InProgressDownloadManager::ShutDown() {
@@ -321,6 +360,10 @@ void InProgressDownloadManager::StartDownload(
std::move(url_loader_factory_getter)));
} else {
std::string guid = info->guid;
+ if (info->is_new_download) {
+ in_progress_downloads_.push_back(std::make_unique<DownloadItemImpl>(
+ this, DownloadItem::kInvalidId, *info));
+ }
StartDownloadWithItem(std::move(stream),
std::move(url_loader_factory_getter), std::move(info),
GetInProgressDownload(guid), false);
@@ -385,9 +428,33 @@ void InProgressDownloadManager::StartDownloadWithItem(
download_start_observer_->OnDownloadStarted(download);
}
-void InProgressDownloadManager::OnInitialized(
+void InProgressDownloadManager::OnDBInitialized(
bool success,
std::unique_ptr<std::vector<DownloadDBEntry>> entries) {
+#if defined(OS_ANDROID)
+ if (!use_empty_db_ &&
+ DownloadCollectionBridge::NeedToRetrieveDisplayNames()) {
+ DownloadCollectionBridge::GetDisplayNamesCallback callback =
+ base::BindOnce(&InProgressDownloadManager::OnDownloadNamesRetrieved,
+ weak_factory_.GetWeakPtr(), std::move(entries));
+ GetDownloadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &DownloadCollectionBridge::GetDisplayNamesForDownloads,
+ base::BindOnce(&OnDownloadDisplayNamesReturned, std::move(callback),
+ base::ThreadTaskRunnerHandle::Get())));
+ return;
+ }
+#endif
+ OnDownloadNamesRetrieved(std::move(entries), nullptr);
+}
+
+void InProgressDownloadManager::OnDownloadNamesRetrieved(
+ std::unique_ptr<std::vector<DownloadDBEntry>> entries,
+ DisplayNames display_names) {
+ std::set<uint32_t> download_ids;
+ int num_duplicates = 0;
+ display_names_ = std::move(display_names);
for (const auto& entry : *entries) {
base::Optional<DownloadEntry> download_entry =
CreateDownloadEntryFromDownloadDBEntry(entry);
@@ -397,12 +464,34 @@ void InProgressDownloadManager::OnInitialized(
auto item = CreateDownloadItemImpl(this, entry);
if (!item)
continue;
+ uint32_t download_id = item->GetId();
+ // Remove entries with duplicate ids.
+ if (download_id != DownloadItem::kInvalidId &&
+ base::ContainsKey(download_ids, download_id)) {
+ RemoveInProgressDownload(item->GetGuid());
+ num_duplicates++;
+ continue;
+ }
+#if defined(OS_ANDROID)
+ const base::FilePath& path = item->GetTargetFilePath();
+ if (path.IsContentUri()) {
+ base::FilePath display_name = GetDownloadDisplayName(path);
+ // If a download doesn't have a display name, remove it.
+ if (display_name.empty()) {
+ RemoveInProgressDownload(item->GetGuid());
+ continue;
+ } else {
+ item->SetDisplayName(display_name);
+ }
+ }
+#endif
item->AddObserver(download_db_cache_.get());
in_progress_downloads_.emplace_back(std::move(item));
+ download_ids.insert(download_id);
}
}
- if (base::FeatureList::IsEnabled(features::kDownloadDBForNewDownloads))
- OnAllInprogressDownloadsLoaded();
+ if (num_duplicates > 0)
+ RecordDuplicateInProgressDownloadIdCount(num_duplicates);
is_initialized_ = true;
for (auto& callback : on_initialized_callbacks_)
std::move(*callback).Run();
@@ -440,8 +529,21 @@ InProgressDownloadManager::TakeInProgressDownloads() {
return std::move(in_progress_downloads_);
}
+base::FilePath InProgressDownloadManager::GetDownloadDisplayName(
+ const base::FilePath& path) {
+#if defined(OS_ANDROID)
+ if (!display_names_)
+ return base::FilePath();
+ auto iter = display_names_->find(path.value());
+ if (iter != display_names_->end())
+ return iter->second;
+#endif
+ return base::FilePath();
+}
+
void InProgressDownloadManager::OnAllInprogressDownloadsLoaded() {
download_entries_.clear();
+ display_names_.reset();
}
void InProgressDownloadManager::AddInProgressDownloadForTest(
diff --git a/chromium/components/download/internal/common/parallel_download_job_unittest.cc b/chromium/components/download/internal/common/parallel_download_job_unittest.cc
index 61761c49fb4..3a46e76c054 100644
--- a/chromium/components/download/internal/common/parallel_download_job_unittest.cc
+++ b/chromium/components/download/internal/common/parallel_download_job_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
@@ -156,7 +157,7 @@ class ParallelDownloadJobTest : public testing::Test {
received_slices_ = slices;
}
- bool IsJobCanceled() const { return job_->is_canceled_; };
+ bool IsJobCanceled() const { return job_->is_canceled_; }
void MakeWorkerReady(
DownloadWorker* worker,
diff --git a/chromium/components/download/internal/common/parallel_download_utils_unittest.cc b/chromium/components/download/internal/common/parallel_download_utils_unittest.cc
index 79818681f66..af8aab73d76 100644
--- a/chromium/components/download/internal/common/parallel_download_utils_unittest.cc
+++ b/chromium/components/download/internal/common/parallel_download_utils_unittest.cc
@@ -268,9 +268,9 @@ TEST_P(ParallelDownloadUtilsRecoverErrorTest,
// The testing value specified offset for preceding stream. The error stream
// offset is fixed value.
-INSTANTIATE_TEST_CASE_P(ParallelDownloadUtilsTestSuite,
- ParallelDownloadUtilsRecoverErrorTest,
- ::testing::Values(0, 20, 80));
+INSTANTIATE_TEST_SUITE_P(ParallelDownloadUtilsTestSuite,
+ ParallelDownloadUtilsRecoverErrorTest,
+ ::testing::Values(0, 20, 80));
// Ensure the minimum slice size is correctly applied.
TEST_F(ParallelDownloadUtilsTest, FindSlicesForRemainingContentMinSliceSize) {
diff --git a/chromium/components/download/internal/common/resource_downloader.cc b/chromium/components/download/internal/common/resource_downloader.cc
index 751474fd56f..b5b86b05098 100644
--- a/chromium/components/download/internal/common/resource_downloader.cc
+++ b/chromium/components/download/internal/common/resource_downloader.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "components/download/public/common/download_url_loader_factory_getter.h"
#include "components/download/public/common/stream_handle_input_stream.h"
#include "components/download/public/common/url_download_request_handle.h"
diff --git a/chromium/components/download/internal/common/url_download_request_handle.cc b/chromium/components/download/internal/common/url_download_request_handle.cc
index 7fa6bd84eb7..9faf499f03d 100644
--- a/chromium/components/download/internal/common/url_download_request_handle.cc
+++ b/chromium/components/download/internal/common/url_download_request_handle.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/download/public/common/url_download_request_handle.h"
+#include "base/bind.h"
namespace download {
diff --git a/chromium/components/download/public/background_service/download_metadata.cc b/chromium/components/download/public/background_service/download_metadata.cc
index 0d869c66783..100a49d7bb9 100644
--- a/chromium/components/download/public/background_service/download_metadata.cc
+++ b/chromium/components/download/public/background_service/download_metadata.cc
@@ -42,7 +42,8 @@ bool CompletionInfo::operator==(const CompletionInfo& other) const {
return path == other.path && bytes_downloaded == other.bytes_downloaded &&
url_chain == other.url_chain &&
AreResponseHeadersEqual(response_headers.get(),
- other.response_headers.get());
+ other.response_headers.get()) &&
+ hash256 == other.hash256;
}
DownloadMetaData::DownloadMetaData() : current_size(0u), paused(false) {}
diff --git a/chromium/components/download/public/background_service/download_metadata.h b/chromium/components/download/public/background_service/download_metadata.h
index 80900c29731..cddd230e933 100644
--- a/chromium/components/download/public/background_service/download_metadata.h
+++ b/chromium/components/download/public/background_service/download_metadata.h
@@ -40,6 +40,10 @@ struct CompletionInfo {
// account changed values during retries/resumptions.
scoped_refptr<const net::HttpResponseHeaders> response_headers;
+ // An optional base::HexEncoded SHA-256 hash (if available) of the file
+ // contents. If empty there is no available hash value.
+ std::string hash256;
+
CompletionInfo();
CompletionInfo(
const base::FilePath& path,
diff --git a/chromium/components/download/public/background_service/download_service.h b/chromium/components/download/public/background_service/download_service.h
index 01168f7f36b..f8b1a729977 100644
--- a/chromium/components/download/public/background_service/download_service.h
+++ b/chromium/components/download/public/background_service/download_service.h
@@ -99,6 +99,8 @@ class DownloadService : public KeyedService {
// components in the larger system.
virtual Logger* GetLogger() = 0;
+ ~DownloadService() override = default;
+
protected:
DownloadService() = default;
diff --git a/chromium/components/download/public/background_service/navigation_monitor.h b/chromium/components/download/public/background_service/navigation_monitor.h
index 329c10a2383..9e9328fd5d7 100644
--- a/chromium/components/download/public/background_service/navigation_monitor.h
+++ b/chromium/components/download/public/background_service/navigation_monitor.h
@@ -53,7 +53,7 @@ class NavigationMonitor : public KeyedService {
base::TimeDelta navigation_timeout_delay) = 0;
protected:
- ~NavigationMonitor() override{};
+ ~NavigationMonitor() override {}
};
} // namespace download
diff --git a/chromium/components/download/public/common/BUILD.gn b/chromium/components/download/public/common/BUILD.gn
index a9437d472fa..5963bee87ad 100644
--- a/chromium/components/download/public/common/BUILD.gn
+++ b/chromium/components/download/public/common/BUILD.gn
@@ -38,6 +38,7 @@ component("public") {
"download_item_impl_delegate.h",
"download_job.h",
"download_job_factory.h",
+ "download_path_reservation_tracker.h",
"download_request_handle_interface.h",
"download_response_handler.h",
"download_save_info.cc",
@@ -139,6 +140,12 @@ source_set("test_support") {
"//testing/gmock",
"//url",
]
+
+ if (is_android) {
+ deps = [
+ "//components/download/internal/common:internal_java",
+ ]
+ }
}
source_set("unit_tests") {
diff --git a/chromium/components/download/public/common/auto_resumption_handler.cc b/chromium/components/download/public/common/auto_resumption_handler.cc
index fdd6eb4b047..eca40b4bfb1 100644
--- a/chromium/components/download/public/common/auto_resumption_handler.cc
+++ b/chromium/components/download/public/common/auto_resumption_handler.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/download/public/common/base_file.h b/chromium/components/download/public/common/base_file.h
index 524ef530262..d6716233e0a 100644
--- a/chromium/components/download/public/common/base_file.h
+++ b/chromium/components/download/public/common/base_file.h
@@ -21,6 +21,7 @@
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "components/download/public/common/download_export.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "crypto/secure_hash.h"
@@ -152,6 +153,11 @@ class COMPONENTS_DOWNLOAD_EXPORT BaseFile {
const GURL& source_url,
const GURL& referrer_url);
+#if defined(OS_ANDROID)
+ // Publishes the intermediate download to public download collection.
+ DownloadInterruptReason PublishDownload();
+#endif
+
// Returns the last known path to the download file. Can be empty if there's
// no file.
const base::FilePath& full_path() const { return full_path_; }
diff --git a/chromium/components/download/public/common/download_features.cc b/chromium/components/download/public/common/download_features.cc
index cf01b32cc39..10c102531a8 100644
--- a/chromium/components/download/public/common/download_features.cc
+++ b/chromium/components/download/public/common/download_features.cc
@@ -9,10 +9,13 @@
namespace download {
namespace features {
+const base::Feature kUseDownloadOfflineContentProvider{
+ "UseDownloadOfflineContentProvider", base::FEATURE_DISABLED_BY_DEFAULT};
+
const base::Feature kDownloadAutoResumptionNative {
"DownloadsAutoResumptionNative",
#if defined(OS_ANDROID)
- base::FEATURE_ENABLED_BY_DEFAULT
+ base::FEATURE_DISABLED_BY_DEFAULT
#else
base::FEATURE_DISABLED_BY_DEFAULT
#endif
@@ -30,5 +33,10 @@ const base::Feature kParallelDownloading {
const base::Feature kDownloadDBForNewDownloads{
"DownloadDBForNewDownloads", base::FEATURE_DISABLED_BY_DEFAULT};
+#if defined(OS_ANDROID)
+const base::Feature kRefreshExpirationDate{"RefreshExpirationDate",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+#endif
+
} // namespace features
} // namespace download
diff --git a/chromium/components/download/public/common/download_features.h b/chromium/components/download/public/common/download_features.h
index 9b6b89433be..b802cbf2840 100644
--- a/chromium/components/download/public/common/download_features.h
+++ b/chromium/components/download/public/common/download_features.h
@@ -6,11 +6,16 @@
#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_FEATURES_H_
#include "base/feature_list.h"
+#include "build/build_config.h"
#include "components/download/public/common/download_export.h"
namespace download {
namespace features {
+// Whether offline content provider should be used for the downloads UI..
+COMPONENTS_DOWNLOAD_EXPORT extern const base::Feature
+ kUseDownloadOfflineContentProvider;
+
// Whether download auto-resumptions are enabled in native.
COMPONENTS_DOWNLOAD_EXPORT extern const base::Feature
kDownloadAutoResumptionNative;
@@ -23,6 +28,11 @@ COMPONENTS_DOWNLOAD_EXPORT extern const base::Feature kParallelDownloading;
COMPONENTS_DOWNLOAD_EXPORT extern const base::Feature
kDownloadDBForNewDownloads;
+#if defined(OS_ANDROID)
+// Whether download expiration date will be refreshed on resumption.
+COMPONENTS_DOWNLOAD_EXPORT extern const base::Feature kRefreshExpirationDate;
+#endif
+
} // namespace features
} // namespace download
diff --git a/chromium/components/download/public/common/download_file.h b/chromium/components/download/public/common/download_file.h
index eb6d0563d17..50561a801aa 100644
--- a/chromium/components/download/public/common/download_file.h
+++ b/chromium/components/download/public/common/download_file.h
@@ -12,6 +12,7 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
+#include "build/build_config.h"
#include "components/download/public/common/base_file.h"
#include "components/download/public/common/download_export.h"
#include "components/download/public/common/download_interrupt_reasons.h"
@@ -106,6 +107,21 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadFile {
virtual void Pause() = 0;
virtual void Resume() = 0;
+
+#if defined(OS_ANDROID)
+ // Create an intermediate URI to write the download file. Once completes,
+ // |callback| is called with a content URI to be written into.
+ virtual void CreateIntermediateUriForPublish(
+ const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type,
+ const RenameCompletionCallback& callback) = 0;
+
+ // Publishes the download to public. Once completes, |callback| is called with
+ // the final content URI.
+ virtual void PublishDownload(const RenameCompletionCallback& callback) = 0;
+#endif // defined(OS_ANDROID)
};
} // namespace download
diff --git a/chromium/components/download/public/common/download_file_impl.h b/chromium/components/download/public/common/download_file_impl.h
index 96791e12cc7..1f82b9d92d4 100644
--- a/chromium/components/download/public/common/download_file_impl.h
+++ b/chromium/components/download/public/common/download_file_impl.h
@@ -23,6 +23,7 @@
#include "base/task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "components/download/public/common/base_file.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_save_info.h"
@@ -75,6 +76,16 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadFileImpl : public DownloadFile {
void Pause() override;
void Resume() override;
+#if defined(OS_ANDROID)
+ void CreateIntermediateUriForPublish(
+ const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type,
+ const RenameCompletionCallback& callback) override;
+ void PublishDownload(const RenameCompletionCallback& callback) override;
+#endif // defined(OS_ANDROID)
+
// Wrapper of a ByteStreamReader or ScopedDataPipeConsumerHandle, and the meta
// data needed to write to a slice of the target file.
//
@@ -213,6 +224,11 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadFileImpl : public DownloadFile {
// Rename file_ based on |parameters|.
void RenameWithRetryInternal(std::unique_ptr<RenameParameters> parameters);
+ // Called after |file_| was renamed.
+ void OnRenameComplete(DownloadInterruptReason reason,
+ const base::FilePath& content_path,
+ const RenameCompletionCallback& callback);
+
// Send an update on our progress.
void SendUpdate();
diff --git a/chromium/components/download/public/common/download_item_impl.h b/chromium/components/download/public/common/download_item_impl.h
index 4ede432f44f..a74c2251e04 100644
--- a/chromium/components/download/public/common/download_item_impl.h
+++ b/chromium/components/download/public/common/download_item_impl.h
@@ -120,6 +120,8 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadItemImpl
// Target path of an in-progress download. We may be downloading to a
// temporary or intermediate file (specified by |current_path|). Once the
// download completes, we will rename the file to |target_path|.
+ // |target_path| should be a valid file path on the system. On Android, this
+ // could be a content Uri.
base::FilePath target_path;
// Full path to the downloaded or downloading file. This is the path to the
@@ -349,6 +351,8 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadItemImpl
void SetDelegate(DownloadItemImplDelegate* delegate);
+ void SetDownloadId(uint32_t download_id);
+
const DownloadUrlParameters::RequestHeadersType& request_headers() const {
return request_headers_;
}
diff --git a/chromium/components/download/public/common/download_path_reservation_tracker.h b/chromium/components/download/public/common/download_path_reservation_tracker.h
new file mode 100644
index 00000000000..446a2de057c
--- /dev/null
+++ b/chromium/components/download/public/common/download_path_reservation_tracker.h
@@ -0,0 +1,119 @@
+// 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_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_PATH_RESERVATION_TRACKER_H_
+#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_PATH_RESERVATION_TRACKER_H_
+
+#include "base/callback_forward.h"
+#include "base/memory/ref_counted.h"
+#include "components/download/public/common/download_export.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+} // namespace base
+
+namespace download {
+class DownloadItem;
+
+// Used in UMA, do not remove, change or reuse existing entries.
+// Update histograms.xml and enums.xml when adding entries.
+enum class PathValidationResult {
+ SUCCESS = 0,
+ PATH_NOT_WRITABLE,
+ NAME_TOO_LONG,
+ CONFLICT,
+ SAME_AS_SOURCE,
+ COUNT,
+};
+
+// Chrome attempts to uniquify filenames that are assigned to downloads in order
+// to avoid overwriting files that already exist on the file system. Downloads
+// that are considered potentially dangerous use random intermediate filenames.
+// Therefore only considering files that exist on the filesystem is
+// insufficient. This class tracks files that are assigned to active downloads
+// so that uniquification can take those into account as well.
+class COMPONENTS_DOWNLOAD_EXPORT DownloadPathReservationTracker {
+ public:
+ // Callback used with |GetReservedPath|. |target_path| specifies the target
+ // path for the download. If |result| is SUCCESS then:
+ // - |requested_target_path| (passed into GetReservedPath()) was writeable.
+ // - |target_path| was verified as being unique if uniqueness was
+ // required.
+ //
+ // If |requested_target_path| was not writeable, then the parent directory of
+ // |target_path| may be different from that of |requested_target_path|.
+ using ReservedPathCallback =
+ base::Callback<void(PathValidationResult result,
+ const base::FilePath& target_path)>;
+
+ // The largest index for the uniquification suffix that we will try while
+ // attempting to come up with a unique path.
+ static const int kMaxUniqueFiles = 100;
+
+ enum FilenameConflictAction {
+ UNIQUIFY,
+ OVERWRITE,
+ PROMPT,
+ };
+
+ // When a path needs to be assigned to a download, this method is called on
+ // the UI thread along with a reference to the download item that will
+ // eventually receive the reserved path. This method creates a path
+ // reservation that will live until |download_item| is interrupted, cancelled,
+ // completes or is removed. This method will not modify |download_item|.
+ //
+ // The process of issuing a reservation happens on the task runner returned by
+ // DownloadPathReservationTracker::GetTaskRunner(), and involves:
+ //
+ // - Creating |requested_target_path.DirName()| if it doesn't already exist
+ // and either |create_directory| or |requested_target_path.DirName() ==
+ // default_download_path|.
+ //
+ // - Verifying that |requested_target_path| is writeable. If not,
+ // |fallback_directory| is used instead.
+ //
+ // - Uniquifying |requested_target_path| by suffixing the filename with a
+ // uniquifier (e.g. "foo.txt" -> "foo (1).txt") in order to avoid conflicts
+ // with files that already exist on the file system or other download path
+ // reservations. Uniquifying is only done if |conflict_action| is UNIQUIFY.
+ //
+ // - Posting a task back to the UI thread to invoke |completion_callback| with
+ // the reserved path and a bool indicating whether the returned path was
+ // verified as being writeable and unique.
+ //
+ // In addition, if the target path of |download_item| is changed to a path
+ // other than the reserved path, then the reservation will be updated to
+ // match. Such changes can happen if a "Save As" dialog was displayed and the
+ // user chose a different path. The new target path is not checked against
+ // active paths to enforce uniqueness. It is only used for uniquifying new
+ // reservations.
+ //
+ // Once |completion_callback| is invoked, it is the caller's responsibility to
+ // handle cases where the target path could not be verified and set the target
+ // path of the |download_item| appropriately.
+ //
+ // The current implementation doesn't look at symlinks/mount points. E.g.: It
+ // considers 'foo/bar/x.pdf' and 'foo/baz/x.pdf' to be two different paths,
+ // even though 'bar' might be a symlink to 'baz'.
+ static void GetReservedPath(DownloadItem* download_item,
+ const base::FilePath& requested_target_path,
+ const base::FilePath& default_download_path,
+ const base::FilePath& fallback_directory,
+ bool create_directory,
+ FilenameConflictAction conflict_action,
+ const ReservedPathCallback& callback);
+
+ // Returns true if |path| is in use by an existing path reservation. Should
+ // only be called on the task runner returned by
+ // DownloadPathReservationTracker::GetTaskRunner(). Currently only used by
+ // tests.
+ static bool IsPathInUseForTesting(const base::FilePath& path);
+
+ static scoped_refptr<base::SequencedTaskRunner> GetTaskRunner();
+};
+
+} // namespace download
+
+#endif // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_PATH_RESERVATION_TRACKER_H_
diff --git a/chromium/components/download/public/common/download_stats.h b/chromium/components/download/public/common/download_stats.h
index c77dffde007..b01123d1a91 100644
--- a/chromium/components/download/public/common/download_stats.h
+++ b/chromium/components/download/public/common/download_stats.h
@@ -360,13 +360,6 @@ enum SavePackageEvent {
COMPONENTS_DOWNLOAD_EXPORT void RecordSavePackageEvent(SavePackageEvent event);
-enum OriginStateOnResumption {
- ORIGIN_STATE_ON_RESUMPTION_ADDITIONAL_REDIRECTS = 1 << 0,
- ORIGIN_STATE_ON_RESUMPTION_VALIDATORS_CHANGED = 1 << 1,
- ORIGIN_STATE_ON_RESUMPTION_CONTENT_DISPOSITION_CHANGED = 1 << 2,
- ORIGIN_STATE_ON_RESUMPTION_MAX = 1 << 3
-};
-
// Enumeration for histogramming purposes.
// These values are written to logs. New enum values can be added, but existing
// enums must never be renumbered or deleted and reused.
@@ -415,6 +408,8 @@ COMPONENTS_DOWNLOAD_EXPORT void RecordDownloadHttpResponseCode(
COMPONENTS_DOWNLOAD_EXPORT void RecordInProgressDBCount(
InProgressDBCountTypes type);
+COMPONENTS_DOWNLOAD_EXPORT void RecordDuplicateInProgressDownloadIdCount(
+ int count);
} // namespace download
#endif // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_STATS_H_
diff --git a/chromium/components/download/public/common/download_url_parameters.cc b/chromium/components/download/public/common/download_url_parameters.cc
index 67787e548eb..fd465914dc1 100644
--- a/chromium/components/download/public/common/download_url_parameters.cc
+++ b/chromium/components/download/public/common/download_url_parameters.cc
@@ -32,13 +32,15 @@ DownloadUrlParameters::DownloadUrlParameters(
render_process_host_id_(render_process_host_id),
render_view_host_routing_id_(render_view_host_routing_id),
render_frame_host_routing_id_(render_frame_host_routing_id),
+ frame_tree_node_id_(-1),
url_(url),
do_not_prompt_for_login_(false),
follow_cross_origin_redirects_(true),
fetch_error_body_(false),
transient_(false),
traffic_annotation_(traffic_annotation),
- download_source_(DownloadSource::UNKNOWN) {}
+ download_source_(DownloadSource::UNKNOWN),
+ require_safety_checks_(true) {}
DownloadUrlParameters::~DownloadUrlParameters() = default;
diff --git a/chromium/components/download/public/common/download_url_parameters.h b/chromium/components/download/public/common/download_url_parameters.h
index eaa1a48206d..eb9422c7947 100644
--- a/chromium/components/download/public/common/download_url_parameters.h
+++ b/chromium/components/download/public/common/download_url_parameters.h
@@ -245,6 +245,12 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
upload_callback_ = upload_callback;
}
+ // Sets whether the download will require safety checks for its URL chain and
+ // downloaded content.
+ void set_require_safety_checks(bool require_safety_checks) {
+ require_safety_checks_ = require_safety_checks;
+ }
+
const OnStartedCallback& callback() const { return callback_; }
bool content_initiated() const { return content_initiated_; }
const std::string& last_modified() const { return last_modified_; }
@@ -275,6 +281,9 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
return render_frame_host_routing_id_;
}
+ void set_frame_tree_node_id(int id) { frame_tree_node_id_ = id; }
+ int frame_tree_node_id() const { return frame_tree_node_id_; }
+
const RequestHeadersType& request_headers() const { return request_headers_; }
const base::FilePath& file_path() const { return save_info_.file_path; }
const base::string16& suggested_name() const {
@@ -294,6 +303,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
bool fetch_error_body() const { return fetch_error_body_; }
bool is_transient() const { return transient_; }
std::string guid() const { return guid_; }
+ bool require_safety_checks() const { return require_safety_checks_; }
// STATE CHANGING: All save_info_ sub-objects will be in an indeterminate
// state following this call.
@@ -328,6 +338,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
int render_process_host_id_;
int render_view_host_routing_id_;
int render_frame_host_routing_id_;
+ int frame_tree_node_id_;
DownloadSaveInfo save_info_;
GURL url_;
bool do_not_prompt_for_login_;
@@ -339,6 +350,7 @@ class COMPONENTS_DOWNLOAD_EXPORT DownloadUrlParameters {
std::string request_origin_;
DownloadSource download_source_;
UploadProgressCallback upload_callback_;
+ bool require_safety_checks_;
DISALLOW_COPY_AND_ASSIGN(DownloadUrlParameters);
};
diff --git a/chromium/components/download/public/common/in_progress_download_manager.h b/chromium/components/download/public/common/in_progress_download_manager.h
index 563d97dedf0..c48eadc063f 100644
--- a/chromium/components/download/public/common/in_progress_download_manager.h
+++ b/chromium/components/download/public/common/in_progress_download_manager.h
@@ -5,8 +5,10 @@
#ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_IN_PROGRESS_DOWNLOAD_MANAGER_H_
#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_IN_PROGRESS_DOWNLOAD_MANAGER_H_
+#include <map>
#include <memory>
#include <set>
+#include <string>
#include <vector>
#include "base/memory/scoped_refptr.h"
@@ -44,6 +46,8 @@ class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
base::OnceCallback<void(std::unique_ptr<DownloadCreateInfo> info,
DownloadItemImpl*,
bool /* should_persist_new_download */)>;
+ using DisplayNames = std::unique_ptr<
+ std::map<std::string /*content URI*/, base::FilePath /* display name*/>>;
// Class to be notified when download starts/stops.
class COMPONENTS_DOWNLOAD_EXPORT Delegate {
@@ -76,6 +80,11 @@ class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
const IsOriginSecureCallback& is_origin_secure_cb,
const URLSecurityPolicy& url_security_policy);
~InProgressDownloadManager() override;
+
+ // Download a URL given by the |params|. Returns true if the download could
+ // take place, or false otherwise.
+ bool DownloadUrl(std::unique_ptr<DownloadUrlParameters> params);
+
// Called to start a download.
void BeginDownload(
std::unique_ptr<DownloadUrlParameters> params,
@@ -146,6 +155,10 @@ class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
// enabled by default.
void OnAllInprogressDownloadsLoaded();
+ // Gets the display name for a download. For non-android platforms, this
+ // always returns an empty path.
+ base::FilePath GetDownloadDisplayName(const base::FilePath& path);
+
void set_file_factory(std::unique_ptr<DownloadFileFactory> file_factory) {
file_factory_ = std::move(file_factory);
}
@@ -180,9 +193,14 @@ class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
void OnUrlDownloadHandlerCreated(
UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader) override;
- // Called when the object is initialized.
- void OnInitialized(bool success,
- std::unique_ptr<std::vector<DownloadDBEntry>> entries);
+ // Called when the in-progress DB is initialized.
+ void OnDBInitialized(bool success,
+ std::unique_ptr<std::vector<DownloadDBEntry>> entries);
+
+ // Called when download display names are retrieved,
+ void OnDownloadNamesRetrieved(
+ std::unique_ptr<std::vector<DownloadDBEntry>> entries,
+ DisplayNames display_names);
// Start a DownloadItemImpl.
void StartDownloadWithItem(
@@ -238,9 +256,16 @@ class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
// is not available.
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter_;
+ // Mapping between download URIs and display names.
+ // TODO(qinmin): move display name to history and in-progress DB.
+ DisplayNames display_names_;
+
// Used to check if the URL is safe.
URLSecurityPolicy url_security_policy_;
+ // Whether this object uses an empty database and no history will be saved.
+ bool use_empty_db_;
+
base::WeakPtrFactory<InProgressDownloadManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(InProgressDownloadManager);
diff --git a/chromium/components/download/public/common/mock_download_file.h b/chromium/components/download/public/common/mock_download_file.h
index 7684ee89a6e..53f016cb4ac 100644
--- a/chromium/components/download/public/common/mock_download_file.h
+++ b/chromium/components/download/public/common/mock_download_file.h
@@ -14,6 +14,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
+#include "build/build_config.h"
#include "components/download/public/common/download_file.h"
#include "components/download/public/common/input_stream.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -66,6 +67,15 @@ class MockDownloadFile : public DownloadFile {
MOCK_CONST_METHOD0(DebugString, std::string());
MOCK_METHOD0(Pause, void());
MOCK_METHOD0(Resume, void());
+#if defined(OS_ANDROID)
+ MOCK_METHOD5(CreateIntermediateUriForPublish,
+ void(const GURL& original_url,
+ const GURL& referrer_url,
+ const base::FilePath& file_name,
+ const std::string& mime_type,
+ const RenameCompletionCallback& callback));
+ MOCK_METHOD1(PublishDownload, void(const RenameCompletionCallback& callback));
+#endif // defined(OS_ANDROID)
};
} // namespace download
diff --git a/chromium/components/download/public/task/task_manager_unittest.cc b/chromium/components/download/public/task/task_manager_unittest.cc
index 5f069e4d8c9..526fa54e42b 100644
--- a/chromium/components/download/public/task/task_manager_unittest.cc
+++ b/chromium/components/download/public/task/task_manager_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/download/quarantine/BUILD.gn b/chromium/components/download/quarantine/BUILD.gn
index fafcb749063..4ce7b5bdc11 100644
--- a/chromium/components/download/quarantine/BUILD.gn
+++ b/chromium/components/download/quarantine/BUILD.gn
@@ -14,7 +14,6 @@ static_library("quarantine") {
"quarantine.h",
"quarantine_features_win.cc",
"quarantine_features_win.h",
- "quarantine_linux.cc",
"quarantine_mac.mm",
"quarantine_win.cc",
]
@@ -36,8 +35,6 @@ static_library("quarantine") {
source_set("common") {
sources = [
- "common_linux.cc",
- "common_linux.h",
"common_mac.h",
"common_mac.mm",
"common_win.cc",
@@ -62,7 +59,6 @@ source_set("test_support") {
sources = [
"test_support.cc",
"test_support.h",
- "test_support_linux.cc",
"test_support_mac.mm",
"test_support_win.cc",
]
@@ -86,7 +82,6 @@ source_set("unit_tests") {
testonly = true
sources = [
- "quarantine_linux_unittest.cc",
"quarantine_mac_unittest.mm",
"quarantine_win_unittest.cc",
]
diff --git a/chromium/components/download/quarantine/common_linux.cc b/chromium/components/download/quarantine/common_linux.cc
deleted file mode 100644
index 3674c8c2c55..00000000000
--- a/chromium/components/download/quarantine/common_linux.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/quarantine/common_linux.h"
-
-namespace download {
-
-const char kSourceURLExtendedAttrName[] = "user.xdg.origin.url";
-const char kReferrerURLExtendedAttrName[] = "user.xdg.referrer.url";
-
-} // namespace download
diff --git a/chromium/components/download/quarantine/common_linux.h b/chromium/components/download/quarantine/common_linux.h
deleted file mode 100644
index 6b52b1b436a..00000000000
--- a/chromium/components/download/quarantine/common_linux.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DOWNLOAD_QUARANTINE_COMMON_LINUX_H_
-#define COMPONENTS_DOWNLOAD_QUARANTINE_COMMON_LINUX_H_
-
-namespace download {
-
-// Attribute names to be used with setxattr and friends.
-//
-// The source URL attribute is part of the XDG standard.
-// The referrer URL attribute is not part of the XDG standard,
-// but it is used to keep the naming consistent.
-// http://freedesktop.org/wiki/CommonExtendedAttributes
-extern const char kSourceURLExtendedAttrName[];
-extern const char kReferrerURLExtendedAttrName[];
-
-} // namespace download
-
-#endif // COMPONENTS_DOWNLOAD_QUARANTINE_COMMON_LINUX_H_
diff --git a/chromium/components/download/quarantine/quarantine.cc b/chromium/components/download/quarantine/quarantine.cc
index 48a2c59c718..ac5b109edd0 100644
--- a/chromium/components/download/quarantine/quarantine.cc
+++ b/chromium/components/download/quarantine/quarantine.cc
@@ -6,7 +6,7 @@
#include "build/build_config.h"
-#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_LINUX)
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
namespace download {
@@ -19,4 +19,4 @@ QuarantineFileResult QuarantineFile(const base::FilePath& file,
} // namespace download
-#endif // !WIN && !MAC && !LINUX
+#endif // !WIN && !MAC
diff --git a/chromium/components/download/quarantine/quarantine_linux.cc b/chromium/components/download/quarantine/quarantine_linux.cc
deleted file mode 100644
index 8683056aae5..00000000000
--- a/chromium/components/download/quarantine/quarantine_linux.cc
+++ /dev/null
@@ -1,64 +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 "components/download/quarantine/quarantine.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/xattr.h>
-
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "components/download/quarantine/common_linux.h"
-#include "url/gurl.h"
-
-namespace download {
-
-namespace {
-
-bool SetExtendedFileAttribute(const char* path,
- const char* name,
- const char* value,
- size_t value_size,
- int flags) {
-// On Chrome OS, there is no component that can validate these extended
-// attributes so there is no need to set them.
-#if !defined(OS_CHROMEOS)
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- int result = setxattr(path, name, value, value_size, flags);
- if (result) {
- DPLOG(ERROR) << "Could not set extended attribute " << name << " on file "
- << path;
- return false;
- }
-#endif // !defined(OS_CHROMEOS)
- return true;
-}
-
-} // namespace
-
-QuarantineFileResult QuarantineFile(const base::FilePath& file,
- const GURL& source_url,
- const GURL& referrer_url,
- const std::string& client_guid) {
- bool source_succeeded =
- source_url.is_valid() &&
- SetExtendedFileAttribute(file.value().c_str(), kSourceURLExtendedAttrName,
- source_url.spec().c_str(),
- source_url.spec().length(), 0);
-
- // Referrer being empty is not considered an error. This could happen if the
- // referrer policy resulted in an empty referrer for the download request.
- bool referrer_succeeded =
- !referrer_url.is_valid() ||
- SetExtendedFileAttribute(
- file.value().c_str(), kReferrerURLExtendedAttrName,
- referrer_url.spec().c_str(), referrer_url.spec().length(), 0);
- return source_succeeded && referrer_succeeded
- ? QuarantineFileResult::OK
- : QuarantineFileResult::ANNOTATION_FAILED;
-}
-
-} // namespace download
diff --git a/chromium/components/download/quarantine/quarantine_linux_unittest.cc b/chromium/components/download/quarantine/quarantine_linux_unittest.cc
deleted file mode 100644
index 32164205d73..00000000000
--- a/chromium/components/download/quarantine/quarantine_linux_unittest.cc
+++ /dev/null
@@ -1,183 +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 "components/download/quarantine/quarantine.h"
-
-#include <errno.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/xattr.h>
-
-#include <algorithm>
-#include <sstream>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/strings/string_split.h"
-#include "components/download/quarantine/common_linux.h"
-#include "components/download/quarantine/test_support.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace download {
-namespace {
-
-using std::istringstream;
-using std::string;
-using std::vector;
-
-class QuarantineLinuxTest : public testing::Test {
- public:
- QuarantineLinuxTest()
- : source_url_("http://www.source.com"),
- referrer_url_("http://www.referrer.com"),
- is_xattr_supported_(false) {}
-
- const base::FilePath& test_file() const { return test_file_; }
-
- const base::FilePath& test_dir() const { return temp_dir_.GetPath(); }
-
- const GURL& source_url() const { return source_url_; }
-
- const GURL& referrer_url() const { return referrer_url_; }
-
- bool is_xattr_supported() const { return is_xattr_supported_; }
-
- protected:
- void SetUp() override {
-#if !defined(OS_CHROMEOS)
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- ASSERT_TRUE(
- base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_));
- int result =
- setxattr(test_file_.value().c_str(), "user.test", "test", 4, 0);
- is_xattr_supported_ = (!result) || (errno != ENOTSUP);
-#endif // !defined(OS_CHROMEOS)
- if (!is_xattr_supported_) {
- LOG(WARNING) << "Test will be skipped because extended attributes are "
- "not supported on this OS/file system.";
- }
- }
-
- void GetExtendedAttributeNames(vector<string>* attr_names) const {
- ssize_t len = listxattr(test_file().value().c_str(), nullptr, 0);
- if (len <= static_cast<ssize_t>(0))
- return;
- char* buffer = new char[len];
- len = listxattr(test_file().value().c_str(), buffer, len);
- *attr_names =
- base::SplitString(string(buffer, len), std::string(1, '\0'),
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- delete[] buffer;
- }
-
- private:
- base::ScopedTempDir temp_dir_;
- base::FilePath test_file_;
- GURL source_url_;
- GURL referrer_url_;
- bool is_xattr_supported_;
-};
-
-} // namespace
-
-TEST_F(QuarantineLinuxTest, CheckMetadataSetCorrectly) {
- if (!is_xattr_supported())
- return;
- EXPECT_EQ(
- QuarantineFileResult::OK,
- QuarantineFile(test_file(), source_url(), referrer_url(), std::string()));
- EXPECT_TRUE(IsFileQuarantined(test_file(), source_url(), referrer_url()));
-}
-
-TEST_F(QuarantineLinuxTest, SetMetadataMultipleTimes) {
- if (!is_xattr_supported())
- return;
- GURL dummy_url("http://www.dummy.com");
- EXPECT_EQ(QuarantineFileResult::OK,
- QuarantineFile(test_file(), dummy_url, dummy_url, std::string()));
- EXPECT_EQ(
- QuarantineFileResult::OK,
- QuarantineFile(test_file(), source_url(), referrer_url(), std::string()));
- EXPECT_TRUE(IsFileQuarantined(test_file(), source_url(), referrer_url()));
-}
-
-TEST_F(QuarantineLinuxTest, InvalidSourceURLTest) {
- if (!is_xattr_supported())
- return;
- GURL invalid_url;
- vector<string> attr_names;
- EXPECT_EQ(
- QuarantineFileResult::ANNOTATION_FAILED,
- QuarantineFile(test_file(), invalid_url, referrer_url(), std::string()));
- GetExtendedAttributeNames(&attr_names);
- EXPECT_FALSE(base::ContainsValue(attr_names, kSourceURLExtendedAttrName));
- EXPECT_TRUE(base::ContainsValue(attr_names, kReferrerURLExtendedAttrName));
-}
-
-TEST_F(QuarantineLinuxTest, InvalidReferrerURLTest) {
- if (!is_xattr_supported())
- return;
- GURL invalid_url;
- vector<string> attr_names;
- EXPECT_EQ(
- QuarantineFileResult::OK,
- QuarantineFile(test_file(), source_url(), invalid_url, std::string()));
- GetExtendedAttributeNames(&attr_names);
- EXPECT_FALSE(base::ContainsValue(attr_names, kReferrerURLExtendedAttrName));
- EXPECT_TRUE(IsFileQuarantined(test_file(), source_url(), GURL()));
-}
-
-TEST_F(QuarantineLinuxTest, InvalidURLsTest) {
- if (!is_xattr_supported())
- return;
- GURL invalid_url;
- vector<string> attr_names;
- EXPECT_EQ(
- QuarantineFileResult::ANNOTATION_FAILED,
- QuarantineFile(test_file(), invalid_url, invalid_url, std::string()));
- GetExtendedAttributeNames(&attr_names);
- EXPECT_FALSE(base::ContainsValue(attr_names, kSourceURLExtendedAttrName));
- EXPECT_FALSE(base::ContainsValue(attr_names, kReferrerURLExtendedAttrName));
- EXPECT_FALSE(IsFileQuarantined(test_file(), GURL(), GURL()));
-}
-
-TEST_F(QuarantineLinuxTest, IsFileQuarantined) {
- if (!is_xattr_supported())
- return;
- base::FilePath does_not_exist = test_dir().AppendASCII("a.jar");
- EXPECT_FALSE(IsFileQuarantined(does_not_exist, GURL(), GURL()));
-
- base::FilePath no_annotations = test_dir().AppendASCII("b.jar");
- ASSERT_EQ(5, base::WriteFile(no_annotations, "Hello", 5));
- EXPECT_FALSE(IsFileQuarantined(no_annotations, GURL(), GURL()));
-
- base::FilePath source_only = test_dir().AppendASCII("c.jar");
- ASSERT_EQ(5, base::WriteFile(source_only, "Hello", 5));
- ASSERT_EQ(QuarantineFileResult::OK,
- QuarantineFile(source_only, source_url(), GURL(), std::string()));
- EXPECT_TRUE(IsFileQuarantined(source_only, source_url(), GURL()));
- EXPECT_TRUE(IsFileQuarantined(source_only, GURL(), GURL()));
- EXPECT_TRUE(IsFileQuarantined(source_only, GURL(), referrer_url()));
- EXPECT_FALSE(IsFileQuarantined(source_only, referrer_url(), GURL()));
-
- base::FilePath fully_annotated = test_dir().AppendASCII("d.jar");
- ASSERT_EQ(5, base::WriteFile(fully_annotated, "Hello", 5));
- ASSERT_EQ(QuarantineFileResult::OK,
- QuarantineFile(fully_annotated, source_url(), referrer_url(),
- std::string()));
- EXPECT_TRUE(IsFileQuarantined(fully_annotated, GURL(), GURL()));
- EXPECT_TRUE(IsFileQuarantined(fully_annotated, source_url(), GURL()));
- EXPECT_TRUE(IsFileQuarantined(fully_annotated, source_url(), referrer_url()));
- EXPECT_TRUE(IsFileQuarantined(fully_annotated, GURL(), referrer_url()));
- EXPECT_FALSE(IsFileQuarantined(fully_annotated, source_url(), source_url()));
- EXPECT_FALSE(
- IsFileQuarantined(fully_annotated, referrer_url(), referrer_url()));
-}
-
-} // namespace download
diff --git a/chromium/components/download/quarantine/quarantine_mac.mm b/chromium/components/download/quarantine/quarantine_mac.mm
index c43cac8e91e..26b783a0ec5 100644
--- a/chromium/components/download/quarantine/quarantine_mac.mm
+++ b/chromium/components/download/quarantine/quarantine_mac.mm
@@ -10,7 +10,6 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
-#include "base/mac/availability.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_logging.h"
#include "base/mac/mac_util.h"
@@ -68,10 +67,17 @@ namespace {
// There is no documented API to set metadata on a file directly as of the
// 10.5 SDK. The MDSetItemAttribute function does exist to perform this task,
// but it's undocumented.
+//
+// Note that the Metadata.framework in CoreServices has been superseded by the
+// NSMetadata API (e.g. kMDItemWhereFroms -> NSMetadataItemWhereFromsKey, etc).
+// The NSMetadata API still is a query-only interface, with no way to set
+// attributes, so we continue to use the original API.
bool AddOriginMetadataToFile(const base::FilePath& file,
const GURL& source,
const GURL& referrer) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
+
// There's no declaration for MDItemSetAttribute in any known public SDK.
// It exists in the 10.4 and 10.5 runtimes. To play it safe, do the lookup
// at runtime instead of declaring it ourselves and linking against what's
@@ -81,22 +87,19 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
// - If Apple removes or renames the function in a future runtime, the
// loader won't refuse to let the application launch. Instead, we'll
// silently fail to set any metadata.
- typedef OSStatus (*MDItemSetAttribute_type)(MDItemRef, CFStringRef,
- CFTypeRef);
- static MDItemSetAttribute_type md_item_set_attribute_func = NULL;
-
- static bool did_symbol_lookup = false;
- if (!did_symbol_lookup) {
- did_symbol_lookup = true;
+ using MDItemSetAttribute_type =
+ OSStatus (*)(MDItemRef, CFStringRef, CFTypeRef);
+ static MDItemSetAttribute_type md_item_set_attribute_func =
+ []() -> MDItemSetAttribute_type {
CFBundleRef metadata_bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Metadata"));
if (!metadata_bundle)
- return false;
+ return nullptr;
- md_item_set_attribute_func =
- (MDItemSetAttribute_type)CFBundleGetFunctionPointerForName(
- metadata_bundle, CFSTR("MDItemSetAttribute"));
- }
+ return reinterpret_cast<MDItemSetAttribute_type>(
+ CFBundleGetFunctionPointerForName(metadata_bundle,
+ CFSTR("MDItemSetAttribute")));
+ }();
if (!md_item_set_attribute_func)
return false;
@@ -105,7 +108,7 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
return false;
base::ScopedCFTypeRef<MDItemRef> md_item(
- MDItemCreate(NULL, base::mac::NSToCFCast(file_path)));
+ MDItemCreate(kCFAllocatorDefault, base::mac::NSToCFCast(file_path)));
if (!md_item) {
LOG(WARNING) << "MDItemCreate failed for path " << file.value();
return false;
@@ -114,17 +117,21 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
// We won't put any more than 2 items into the attribute.
NSMutableArray* list = [NSMutableArray arrayWithCapacity:2];
- // Follow Safari's lead: the first item in the list is the source URL of
- // the downloaded file. If the referrer is known, store that, too.
+ // Follow Safari's lead: the first item in the list is the source URL of the
+ // downloaded file. If the referrer is known, store that, too. The URLs may be
+ // empty (e.g. files downloaded in Incognito mode); don't add empty URLs.
NSString* origin_url = base::SysUTF8ToNSString(source.spec());
- if (origin_url)
+ if (origin_url && [origin_url length])
[list addObject:origin_url];
NSString* referrer_url = base::SysUTF8ToNSString(referrer.spec());
- if (referrer_url)
+ if (referrer_url && [referrer_url length])
[list addObject:referrer_url];
- md_item_set_attribute_func(md_item, kMDItemWhereFroms,
- base::mac::NSToCFCast(list));
+ if ([list count]) {
+ md_item_set_attribute_func(md_item, kMDItemWhereFroms,
+ base::mac::NSToCFCast(list));
+ }
+
return true;
}
@@ -140,7 +147,8 @@ bool AddOriginMetadataToFile(const base::FilePath& file,
bool AddQuarantineMetadataToFile(const base::FilePath& file,
const GURL& source,
const GURL& referrer) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::scoped_nsobject<NSMutableDictionary> properties;
bool success = GetQuarantineProperties(file, &properties);
diff --git a/chromium/components/download/quarantine/quarantine_mac_unittest.mm b/chromium/components/download/quarantine/quarantine_mac_unittest.mm
index 7730710a1d4..d37d5eefa9e 100644
--- a/chromium/components/download/quarantine/quarantine_mac_unittest.mm
+++ b/chromium/components/download/quarantine/quarantine_mac_unittest.mm
@@ -6,14 +6,15 @@
#include <sys/xattr.h>
+#import <ApplicationServices/ApplicationServices.h>
#import <Foundation/Foundation.h>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
-#include "base/mac/availability.h"
-#include "base/mac/mac_util.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "components/download/quarantine/test_support.h"
@@ -32,28 +33,24 @@ class QuarantineMacTest : public testing::Test {
protected:
void SetUp() override {
- if (@available(macos 10.10, *)) {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- ASSERT_TRUE(
- base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_));
- file_url_.reset([[NSURL alloc]
- initFileURLWithPath:base::SysUTF8ToNSString(test_file_.value())]);
-
- base::scoped_nsobject<NSMutableDictionary> properties(
- [[NSMutableDictionary alloc] init]);
- [properties setValue:@"com.google.Chrome"
- forKey:static_cast<NSString*>(
- kLSQuarantineAgentBundleIdentifierKey)];
- [properties setValue:@"Google Chrome.app"
- forKey:static_cast<NSString*>(kLSQuarantineAgentNameKey)];
- [properties setValue:@(1) forKey:@"kLSQuarantineIsOwnedByCurrentUserKey"];
- bool success = [file_url_ setResourceValue:properties
- forKey:NSURLQuarantinePropertiesKey
- error:nullptr];
- ASSERT_TRUE(success);
- } else {
- LOG(WARNING) << "Test suite requires Mac OS X 10.10 or later";
- }
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_));
+ file_url_.reset([[NSURL alloc]
+ initFileURLWithPath:base::SysUTF8ToNSString(test_file_.value())]);
+
+ base::scoped_nsobject<NSMutableDictionary> properties(
+ [[NSMutableDictionary alloc] init]);
+ [properties
+ setValue:@"com.google.Chrome"
+ forKey:static_cast<NSString*>(kLSQuarantineAgentBundleIdentifierKey)];
+ [properties setValue:@"Google Chrome.app"
+ forKey:static_cast<NSString*>(kLSQuarantineAgentNameKey)];
+ [properties setValue:@(1) forKey:@"kLSQuarantineIsOwnedByCurrentUserKey"];
+ bool success = [file_url_ setResourceValue:properties
+ forKey:NSURLQuarantinePropertiesKey
+ error:nullptr];
+ ASSERT_TRUE(success);
}
base::ScopedTempDir temp_dir_;
@@ -64,16 +61,12 @@ class QuarantineMacTest : public testing::Test {
};
TEST_F(QuarantineMacTest, CheckMetadataSetCorrectly) {
- if (base::mac::IsAtMostOS10_9())
- return;
EXPECT_EQ(QuarantineFileResult::OK,
QuarantineFile(test_file_, source_url_, referrer_url_, ""));
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, referrer_url_));
}
TEST_F(QuarantineMacTest, SetMetadataMultipleTimes) {
- if (base::mac::IsAtMostOS10_9())
- return;
GURL dummy_url("http://www.dummy.example.com");
EXPECT_EQ(QuarantineFileResult::OK,
QuarantineFile(test_file_, source_url_, referrer_url_, ""));
@@ -83,21 +76,15 @@ TEST_F(QuarantineMacTest, SetMetadataMultipleTimes) {
}
TEST_F(QuarantineMacTest, IsFileQuarantined_NoFile) {
- if (base::mac::IsAtMostOS10_9())
- return;
base::FilePath does_not_exist = temp_dir_.GetPath().AppendASCII("a.jar");
EXPECT_FALSE(IsFileQuarantined(does_not_exist, GURL(), GURL()));
}
TEST_F(QuarantineMacTest, IsFileQuarantined_NoAnnotationsOnFile) {
- if (base::mac::IsAtMostOS10_9())
- return;
EXPECT_FALSE(IsFileQuarantined(test_file_, GURL(), GURL()));
}
TEST_F(QuarantineMacTest, IsFileQuarantined_SourceUrlOnly) {
- if (base::mac::IsAtMostOS10_9())
- return;
ASSERT_EQ(QuarantineFileResult::OK,
QuarantineFile(test_file_, source_url_, GURL(), std::string()));
EXPECT_TRUE(IsFileQuarantined(test_file_, source_url_, GURL()));
@@ -107,8 +94,6 @@ TEST_F(QuarantineMacTest, IsFileQuarantined_SourceUrlOnly) {
}
TEST_F(QuarantineMacTest, IsFileQuarantined_FullMetadata) {
- if (base::mac::IsAtMostOS10_9())
- return;
ASSERT_EQ(
QuarantineFileResult::OK,
QuarantineFile(test_file_, source_url_, referrer_url_, std::string()));
@@ -120,5 +105,25 @@ TEST_F(QuarantineMacTest, IsFileQuarantined_FullMetadata) {
EXPECT_FALSE(IsFileQuarantined(test_file_, referrer_url_, referrer_url_));
}
+TEST_F(QuarantineMacTest, NoWhereFromsKeyIfNoURLs) {
+ ASSERT_EQ(QuarantineFileResult::OK,
+ QuarantineFile(test_file_, GURL(), GURL(), std::string()));
+
+ NSString* file_path = base::mac::FilePathToNSString(test_file_);
+ ASSERT_NE(nullptr, file_path);
+ base::ScopedCFTypeRef<MDItemRef> md_item(
+ MDItemCreate(kCFAllocatorDefault, base::mac::NSToCFCast(file_path)));
+ if (!md_item) {
+ // The quarantine code ignores it if adding origin metadata fails. If for
+ // some reason MDItemCreate fails (which it seems to do on the bots, not
+ // sure why) just stop on the test.
+ return;
+ }
+
+ base::ScopedCFTypeRef<CFTypeRef> attr(
+ MDItemCopyAttribute(md_item, kMDItemWhereFroms));
+ EXPECT_FALSE(attr);
+}
+
} // namespace
-} // namespace downlod
+} // namespace download
diff --git a/chromium/components/download/quarantine/quarantine_win.cc b/chromium/components/download/quarantine/quarantine_win.cc
index 6ab164dc812..bd4827ce005 100644
--- a/chromium/components/download/quarantine/quarantine_win.cc
+++ b/chromium/components/download/quarantine/quarantine_win.cc
@@ -216,7 +216,8 @@ QuarantineFileResult QuarantineFile(const base::FilePath& file,
const GURL& source_url,
const GURL& referrer_url,
const std::string& client_guid) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
int64_t file_size = 0;
if (!base::PathExists(file) || !base::GetFileSize(file, &file_size))
diff --git a/chromium/components/download/quarantine/test_support.cc b/chromium/components/download/quarantine/test_support.cc
index e158051ae45..55ef0628d00 100644
--- a/chromium/components/download/quarantine/test_support.cc
+++ b/chromium/components/download/quarantine/test_support.cc
@@ -6,7 +6,7 @@
#include "build/build_config.h"
-#if !defined(OS_WIN) && !defined(OS_MACOSX) && !defined(OS_LINUX)
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
namespace download {
@@ -18,4 +18,4 @@ bool IsFileQuarantined(const base::FilePath& file,
} // namespace download
-#endif // !WIN && !MAC && !LINUX
+#endif // !WIN && !MAC
diff --git a/chromium/components/download/quarantine/test_support_linux.cc b/chromium/components/download/quarantine/test_support_linux.cc
deleted file mode 100644
index 63f8020dc11..00000000000
--- a/chromium/components/download/quarantine/test_support_linux.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/download/quarantine/test_support.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/xattr.h>
-
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "components/download/quarantine/common_linux.h"
-#include "url/gurl.h"
-
-namespace download {
-
-namespace {
-
-std::string GetExtendedFileAttribute(const char* path, const char* name) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- ssize_t len = getxattr(path, name, nullptr, 0);
- if (len <= 0)
- return std::string();
-
- std::vector<char> buffer(len);
- len = getxattr(path, name, buffer.data(), buffer.size());
- if (len < static_cast<ssize_t>(buffer.size()))
- return std::string();
- return std::string(buffer.begin(), buffer.end());
-}
-
-} // namespace
-
-bool IsFileQuarantined(const base::FilePath& file,
- const GURL& source_url,
- const GURL& referrer_url) {
- if (!base::PathExists(file))
- return false;
-
- std::string url_value = GetExtendedFileAttribute(file.value().c_str(),
- kSourceURLExtendedAttrName);
- if (source_url.is_empty())
- return !url_value.empty();
-
- if (source_url != GURL(url_value))
- return false;
-
- return !referrer_url.is_valid() ||
- GURL(GetExtendedFileAttribute(file.value().c_str(),
- kReferrerURLExtendedAttrName)) ==
- referrer_url;
-}
-
-} // namespace download
diff --git a/chromium/components/download/quarantine/test_support_mac.mm b/chromium/components/download/quarantine/test_support_mac.mm
index 7158aba6e13..54369105c91 100644
--- a/chromium/components/download/quarantine/test_support_mac.mm
+++ b/chromium/components/download/quarantine/test_support_mac.mm
@@ -20,7 +20,8 @@ namespace download {
bool IsFileQuarantined(const base::FilePath& file,
const GURL& expected_source_url,
const GURL& referrer_url) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
if (!base::PathExists(file))
return false;
diff --git a/chromium/components/embedder_support/android/BUILD.gn b/chromium/components/embedder_support/android/BUILD.gn
index ba53ed8edf9..7eb08dc7488 100644
--- a/chromium/components/embedder_support/android/BUILD.gn
+++ b/chromium/components/embedder_support/android/BUILD.gn
@@ -58,22 +58,24 @@ generate_jni("view_jni_headers") {
java_strings_grd("web_contents_delegate_strings_grd") {
grd_file = "java/strings/web_contents_delegate_android_strings.grd"
outputs = [
+ "values/web_contents_delegate_android_strings.xml",
"values-am/web_contents_delegate_android_strings.xml",
"values-ar/web_contents_delegate_android_strings.xml",
"values-bg/web_contents_delegate_android_strings.xml",
+ "values-bn/web_contents_delegate_android_strings.xml",
"values-ca/web_contents_delegate_android_strings.xml",
"values-cs/web_contents_delegate_android_strings.xml",
"values-da/web_contents_delegate_android_strings.xml",
"values-de/web_contents_delegate_android_strings.xml",
"values-el/web_contents_delegate_android_strings.xml",
- "values/web_contents_delegate_android_strings.xml",
"values-en-rGB/web_contents_delegate_android_strings.xml",
"values-es/web_contents_delegate_android_strings.xml",
"values-es-rUS/web_contents_delegate_android_strings.xml",
+ "values-et/web_contents_delegate_android_strings.xml",
"values-fa/web_contents_delegate_android_strings.xml",
"values-fi/web_contents_delegate_android_strings.xml",
- "values-tl/web_contents_delegate_android_strings.xml",
"values-fr/web_contents_delegate_android_strings.xml",
+ "values-gu/web_contents_delegate_android_strings.xml",
"values-hi/web_contents_delegate_android_strings.xml",
"values-hr/web_contents_delegate_android_strings.xml",
"values-hu/web_contents_delegate_android_strings.xml",
@@ -81,11 +83,15 @@ java_strings_grd("web_contents_delegate_strings_grd") {
"values-it/web_contents_delegate_android_strings.xml",
"values-iw/web_contents_delegate_android_strings.xml",
"values-ja/web_contents_delegate_android_strings.xml",
+ "values-kn/web_contents_delegate_android_strings.xml",
"values-ko/web_contents_delegate_android_strings.xml",
"values-lt/web_contents_delegate_android_strings.xml",
"values-lv/web_contents_delegate_android_strings.xml",
- "values-nl/web_contents_delegate_android_strings.xml",
+ "values-ml/web_contents_delegate_android_strings.xml",
+ "values-mr/web_contents_delegate_android_strings.xml",
+ "values-ms/web_contents_delegate_android_strings.xml",
"values-nb/web_contents_delegate_android_strings.xml",
+ "values-nl/web_contents_delegate_android_strings.xml",
"values-pl/web_contents_delegate_android_strings.xml",
"values-pt-rBR/web_contents_delegate_android_strings.xml",
"values-pt-rPT/web_contents_delegate_android_strings.xml",
@@ -96,7 +102,10 @@ java_strings_grd("web_contents_delegate_strings_grd") {
"values-sr/web_contents_delegate_android_strings.xml",
"values-sv/web_contents_delegate_android_strings.xml",
"values-sw/web_contents_delegate_android_strings.xml",
+ "values-ta/web_contents_delegate_android_strings.xml",
+ "values-te/web_contents_delegate_android_strings.xml",
"values-th/web_contents_delegate_android_strings.xml",
+ "values-tl/web_contents_delegate_android_strings.xml",
"values-tr/web_contents_delegate_android_strings.xml",
"values-uk/web_contents_delegate_android_strings.xml",
"values-vi/web_contents_delegate_android_strings.xml",
diff --git a/chromium/components/embedder_support/android/delegate/color_chooser_android.h b/chromium/components/embedder_support/android/delegate/color_chooser_android.h
index d05421b37e0..6b38cc1cb4c 100644
--- a/chromium/components/embedder_support/android/delegate/color_chooser_android.h
+++ b/chromium/components/embedder_support/android/delegate/color_chooser_android.h
@@ -12,7 +12,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "content/public/browser/color_chooser.h"
-#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom.h"
+#include "third_party/blink/public/mojom/choosers/color_chooser.mojom.h"
using base::android::AttachCurrentThread;
using base::android::ScopedJavaLocalRef;
diff --git a/chromium/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd b/chromium/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd
index b5177f01559..b438a13e59a 100644
--- a/chromium/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd
+++ b/chromium/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd
@@ -6,6 +6,7 @@
<output filename="values-am/web_contents_delegate_android_strings.xml" lang="am" type="android" />
<output filename="values-ar/web_contents_delegate_android_strings.xml" lang="ar" type="android" />
<output filename="values-bg/web_contents_delegate_android_strings.xml" lang="bg" type="android" />
+ <output filename="values-bn/web_contents_delegate_android_strings.xml" lang="bn" type="android" />
<output filename="values-ca/web_contents_delegate_android_strings.xml" lang="ca" type="android" />
<output filename="values-cs/web_contents_delegate_android_strings.xml" lang="cs" type="android" />
<output filename="values-da/web_contents_delegate_android_strings.xml" lang="da" type="android" />
@@ -15,20 +16,26 @@
<output filename="values-en-rGB/web_contents_delegate_android_strings.xml" lang="en-GB" type="android" />
<output filename="values-es/web_contents_delegate_android_strings.xml" lang="es" type="android" />
<output filename="values-es-rUS/web_contents_delegate_android_strings.xml" lang="es-419" type="android" />
+ <output filename="values-et/web_contents_delegate_android_strings.xml" lang="et" type="android" />
<output filename="values-fa/web_contents_delegate_android_strings.xml" lang="fa" type="android" />
<output filename="values-fi/web_contents_delegate_android_strings.xml" lang="fi" type="android" />
<output filename="values-tl/web_contents_delegate_android_strings.xml" lang="fil" type="android" />
<output filename="values-fr/web_contents_delegate_android_strings.xml" lang="fr" type="android" />
+ <output filename="values-gu/web_contents_delegate_android_strings.xml" lang="gu" type="android" />
+ <output filename="values-iw/web_contents_delegate_android_strings.xml" lang="he" type="android" />
<output filename="values-hi/web_contents_delegate_android_strings.xml" lang="hi" type="android" />
<output filename="values-hr/web_contents_delegate_android_strings.xml" lang="hr" type="android" />
<output filename="values-hu/web_contents_delegate_android_strings.xml" lang="hu" type="android" />
<output filename="values-in/web_contents_delegate_android_strings.xml" lang="id" type="android" />
<output filename="values-it/web_contents_delegate_android_strings.xml" lang="it" type="android" />
- <output filename="values-iw/web_contents_delegate_android_strings.xml" lang="he" type="android" />
<output filename="values-ja/web_contents_delegate_android_strings.xml" lang="ja" type="android" />
+ <output filename="values-kn/web_contents_delegate_android_strings.xml" lang="kn" type="android" />
<output filename="values-ko/web_contents_delegate_android_strings.xml" lang="ko" type="android" />
<output filename="values-lt/web_contents_delegate_android_strings.xml" lang="lt" type="android" />
<output filename="values-lv/web_contents_delegate_android_strings.xml" lang="lv" type="android" />
+ <output filename="values-ml/web_contents_delegate_android_strings.xml" lang="ml" type="android" />
+ <output filename="values-mr/web_contents_delegate_android_strings.xml" lang="mr" type="android" />
+ <output filename="values-ms/web_contents_delegate_android_strings.xml" lang="ms" type="android" />
<output filename="values-nl/web_contents_delegate_android_strings.xml" lang="nl" type="android" />
<output filename="values-nb/web_contents_delegate_android_strings.xml" lang="no" type="android" />
<output filename="values-pl/web_contents_delegate_android_strings.xml" lang="pl" type="android" />
@@ -41,6 +48,8 @@
<output filename="values-sr/web_contents_delegate_android_strings.xml" lang="sr" type="android" />
<output filename="values-sv/web_contents_delegate_android_strings.xml" lang="sv" type="android" />
<output filename="values-sw/web_contents_delegate_android_strings.xml" lang="sw" type="android" />
+ <output filename="values-ta/web_contents_delegate_android_strings.xml" lang="ta" type="android" />
+ <output filename="values-te/web_contents_delegate_android_strings.xml" lang="te" type="android" />
<output filename="values-th/web_contents_delegate_android_strings.xml" lang="th" type="android" />
<output filename="values-tr/web_contents_delegate_android_strings.xml" lang="tr" type="android" />
<output filename="values-uk/web_contents_delegate_android_strings.xml" lang="uk" type="android" />
diff --git a/chromium/components/embedder_support/android/view/content_view_render_view.cc b/chromium/components/embedder_support/android/view/content_view_render_view.cc
index 96965cd03e5..454399868a9 100644
--- a/chromium/components/embedder_support/android/view/content_view_render_view.cc
+++ b/chromium/components/embedder_support/android/view/content_view_render_view.cc
@@ -85,7 +85,7 @@ void ContentViewRenderView::SurfaceCreated(JNIEnv* env,
void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
- compositor_->SetSurface(NULL);
+ compositor_->SetSurface(nullptr, false);
current_surface_format_ = 0;
}
@@ -98,7 +98,7 @@ void ContentViewRenderView::SurfaceChanged(
const JavaParamRef<jobject>& surface) {
if (current_surface_format_ != format) {
current_surface_format_ = format;
- compositor_->SetSurface(surface);
+ compositor_->SetSurface(surface, false /* backed_by_surface_texture */);
}
compositor_->SetWindowBounds(gfx::Size(width, height));
}
diff --git a/chromium/components/error_page/common/error_page_switches.cc b/chromium/components/error_page/common/error_page_switches.cc
index 7d8ef37b885..e83b9c340ee 100644
--- a/chromium/components/error_page/common/error_page_switches.cc
+++ b/chromium/components/error_page/common/error_page_switches.cc
@@ -10,15 +10,5 @@ namespace switches {
// Disables the dinosaur easter egg on the offline interstitial.
const char kDisableDinosaurEasterEgg[] = "disable-dinosaur-easter-egg";
-// Values for the kShowSavedCopy flag.
-const char kDisableShowSavedCopy[] = "disable";
-const char kEnableShowSavedCopyPrimary[] = "primary";
-const char kEnableShowSavedCopySecondary[] = "secondary";
-
-// Command line flag offering a "Show saved copy" option to the user if offline.
-// The various modes are disabled, primary, or secondary. Primary/secondary
-// refers to button placement (for experiment).
-const char kShowSavedCopy[] = "show-saved-copy";
-
} // namespace switches
} // namespace error_page
diff --git a/chromium/components/error_page/common/error_page_switches.h b/chromium/components/error_page/common/error_page_switches.h
index d154656d2f8..0ba162195f4 100644
--- a/chromium/components/error_page/common/error_page_switches.h
+++ b/chromium/components/error_page/common/error_page_switches.h
@@ -11,10 +11,6 @@ namespace error_page {
namespace switches {
extern const char kDisableDinosaurEasterEgg[];
-extern const char kDisableShowSavedCopy[];
-extern const char kEnableShowSavedCopyPrimary[];
-extern const char kEnableShowSavedCopySecondary[];
-extern const char kShowSavedCopy[];
} // namespace switches
} // namespace error_page
diff --git a/chromium/components/error_page/common/localized_error.cc b/chromium/components/error_page/common/localized_error.cc
index 71ece780062..b8978f63cf5 100644
--- a/chromium/components/error_page/common/localized_error.cc
+++ b/chromium/components/error_page/common/localized_error.cc
@@ -858,7 +858,7 @@ void AddSuggestionsDetails(int error_code,
}
std::string HttpErrorCodeToString(int error) {
- return std::string("HTTP ERROR ") + base::IntToString(error);
+ return std::string("HTTP ERROR ") + base::NumberToString(error);
}
} // namespace
@@ -1037,36 +1037,8 @@ void LocalizedError::GetStrings(
AddSuggestionsDetails(error_code, error_strings, options.suggestions,
suggestions_details);
- // Add action buttons.
- const std::string& show_saved_copy_value =
- command_line->GetSwitchValueASCII(error_page::switches::kShowSavedCopy);
- bool show_saved_copy_primary =
- (show_saved_copy_value ==
- error_page::switches::kEnableShowSavedCopyPrimary);
- bool show_saved_copy_secondary =
- (show_saved_copy_value ==
- error_page::switches::kEnableShowSavedCopySecondary);
- bool show_saved_copy_visible =
- (stale_copy_in_cache && !is_post &&
- (show_saved_copy_primary || show_saved_copy_secondary));
-
- if (show_saved_copy_visible) {
- auto show_saved_copy_button = std::make_unique<base::DictionaryValue>();
- show_saved_copy_button->SetString(
- "msg", l10n_util::GetStringUTF16(
- IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY));
- show_saved_copy_button->SetString(
- "title",
- l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY_HELP));
- if (show_saved_copy_primary)
- show_saved_copy_button->SetString("primary", "true");
- error_strings->Set("showSavedCopyButton",
- std::move(show_saved_copy_button));
- }
-
#if defined(OS_ANDROID)
- if (!is_post && !reload_visible && !show_saved_copy_visible &&
- !is_incognito && failed_url.is_valid() &&
+ if (!is_post && !reload_visible && !is_incognito && failed_url.is_valid() &&
failed_url.SchemeIsHTTPOrHTTPS() &&
IsOfflineError(error_domain, error_code)) {
if (!auto_fetch_feature_enabled) {
diff --git a/chromium/components/error_page/common/net_error_info.h b/chromium/components/error_page/common/net_error_info.h
index e0f25b96a1c..a2e3be54afa 100644
--- a/chromium/components/error_page/common/net_error_info.h
+++ b/chromium/components/error_page/common/net_error_info.h
@@ -17,19 +17,21 @@ enum NetworkErrorPageEvent {
NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR = 3, // Reload button clicked
// -> error.
- // Same for the "Show saved copy" button.
- NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_SHOWN = 4,
- NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_CLICKED = 5,
- NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_ERROR = 6,
+ // Obsolete values used for the "Show saved copy" button.
+ // NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_SHOWN = 4,
+ // NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_CLICKED = 5,
+ // NETWORK_ERROR_PAGE_SHOW_SAVED_COPY_BUTTON_ERROR = 6,
NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED = 7, // More button clicked.
NETWORK_ERROR_PAGE_BROWSER_INITIATED_RELOAD = 8, // Reload from browser.
- // Keep track of which button the user chooses when both are shown.
- NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN = 9,
- NETWORK_ERROR_PAGE_BOTH_BUTTONS_RELOAD_CLICKED = 10,
- NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN_SAVED_COPY_CLICKED = 11,
+ // Obsolete values used for when "Show saved copy" and "Reload" buttons were
+ // both shown.
+ //
+ // NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN = 9,
+ // NETWORK_ERROR_PAGE_BOTH_BUTTONS_RELOAD_CLICKED = 10,
+ // NETWORK_ERROR_PAGE_BOTH_BUTTONS_SHOWN_SAVED_COPY_CLICKED = 11,
NETWORK_ERROR_EASTER_EGG_ACTIVATED = 12, // Easter egg activated.
diff --git a/chromium/components/error_page_strings.grdp b/chromium/components/error_page_strings.grdp
index 5e8f8a06631..fcd9f61ae80 100644
--- a/chromium/components/error_page_strings.grdp
+++ b/chromium/components/error_page_strings.grdp
@@ -13,16 +13,6 @@
<message name="IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY" desc="Label for the button on an error page to show a saved entry from the cache">
Show saved copy
</message>
- <if expr="not is_android">
- <message name="IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY_HELP" desc="Explanation for the BUTTON_SHOW_SAVED button">
- Show a saved (i.e. known to be out of date) copy of this page.
- </message>
- </if>
- <if expr="is_android">
- <message name="IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY_HELP" desc="Mobile: Explanation for the BUTTON_SHOW_SAVED button">
- Show saved copy
- </message>
- </if>
<message name="IDS_ERRORPAGE_FUN_DISABLED" desc="Explanation for when easter egg has been disabled by administrator">
The owner of this device turned off the dinosaur game.
</message>
diff --git a/chromium/components/exo/BUILD.gn b/chromium/components/exo/BUILD.gn
index eb7ed1db1fc..731402f98aa 100644
--- a/chromium/components/exo/BUILD.gn
+++ b/chromium/components/exo/BUILD.gn
@@ -23,6 +23,8 @@ source_set("exo") {
"data_source_observer.h",
"display.cc",
"display.h",
+ "frame_sink_resource_manager.cc",
+ "frame_sink_resource_manager.h",
"keyboard_delegate.h",
"keyboard_device_configuration_delegate.h",
"keyboard_observer.h",
diff --git a/chromium/components/exo/buffer.cc b/chromium/components/exo/buffer.cc
index da2361c208a..b6e399316a1 100644
--- a/chromium/components/exo/buffer.cc
+++ b/chromium/components/exo/buffer.cc
@@ -12,6 +12,7 @@
#include <algorithm>
#include <utility>
+#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
@@ -20,7 +21,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
-#include "components/exo/layer_tree_frame_sink_holder.h"
+#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/wm_helper.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/resource_format.h"
@@ -411,7 +412,7 @@ Buffer::Buffer(std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
Buffer::~Buffer() {}
bool Buffer::ProduceTransferableResource(
- LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder,
+ FrameSinkResourceManager* resource_manager,
bool secure_output_only,
viz::TransferableResource* resource) {
TRACE_EVENT1("exo", "Buffer::ProduceTransferableResource", "buffer_id",
@@ -436,7 +437,7 @@ bool Buffer::ProduceTransferableResource(
return false;
}
- resource->id = layer_tree_frame_sink_holder->AllocateResourceId();
+ resource->id = resource_manager->AllocateResourceId();
resource->format = viz::RGBA_8888;
resource->filter = GL_LINEAR;
resource->size = gpu_memory_buffer_->GetSize();
@@ -470,7 +471,7 @@ bool Buffer::ProduceTransferableResource(
// The contents texture will be released when no longer used by the
// compositor.
- layer_tree_frame_sink_holder->SetResourceReleaseCallback(
+ resource_manager->SetResourceReleaseCallback(
resource->id,
base::BindOnce(&Buffer::Texture::ReleaseTexImage,
base::Unretained(contents_texture),
@@ -500,7 +501,7 @@ bool Buffer::ProduceTransferableResource(
// The mailbox texture will be released when no longer used by the
// compositor.
- layer_tree_frame_sink_holder->SetResourceReleaseCallback(
+ resource_manager->SetResourceReleaseCallback(
resource->id,
base::BindOnce(&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 92fc03f9fde..9fbc01eced7 100644
--- a/chromium/components/exo/buffer.h
+++ b/chromium/components/exo/buffer.h
@@ -17,7 +17,7 @@
namespace exo {
-class LayerTreeFrameSinkHolder;
+class FrameSinkResourceManager;
// This class provides the content for a Surface. The mechanism by which a
// client provides and updates the contents is the responsibility of the client
@@ -51,10 +51,9 @@ class Buffer : public base::SupportsWeakPtr<Buffer> {
// buffer. Returns a release callback on success. The release callback should
// be called before a new texture mailbox can be acquired unless
// |non_client_usage| is true.
- bool ProduceTransferableResource(
- LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder,
- bool secure_output_only,
- viz::TransferableResource* resource);
+ bool ProduceTransferableResource(FrameSinkResourceManager* resource_manager,
+ bool secure_output_only,
+ viz::TransferableResource* resource);
// This should be called when the buffer is attached to a Surface.
void OnAttach();
diff --git a/chromium/components/exo/buffer_unittest.cc b/chromium/components/exo/buffer_unittest.cc
index a4e137addd2..3e8e934a0e5 100644
--- a/chromium/components/exo/buffer_unittest.cc
+++ b/chromium/components/exo/buffer_unittest.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/run_loop.h"
#include "components/exo/buffer.h"
+#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/surface_tree_host.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_helper.h"
@@ -65,8 +66,8 @@ TEST_F(BufferTest, ReleaseCallback) {
buffer->OnAttach();
viz::TransferableResource resource;
// Produce a transferable resource for the contents of the buffer.
- bool rv =
- buffer->ProduceTransferableResource(frame_sink_holder, false, &resource);
+ bool rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &resource);
ASSERT_TRUE(rv);
// Release buffer.
@@ -97,8 +98,8 @@ TEST_F(BufferTest, IsLost) {
buffer->OnAttach();
// Acquire a texture transferable resource for the contents of the buffer.
viz::TransferableResource resource;
- bool rv =
- buffer->ProduceTransferableResource(frame_sink_holder, false, &resource);
+ bool rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &resource);
ASSERT_TRUE(rv);
scoped_refptr<viz::ContextProvider> context_provider =
@@ -122,8 +123,8 @@ TEST_F(BufferTest, IsLost) {
// Producing a new texture transferable resource for the contents of the
// buffer.
viz::TransferableResource new_resource;
- rv = buffer->ProduceTransferableResource(frame_sink_holder, false,
- &new_resource);
+ rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &new_resource);
ASSERT_TRUE(rv);
buffer->OnDetach();
@@ -150,8 +151,8 @@ TEST_F(BufferTest, OnLostResources) {
buffer->OnAttach();
// Acquire a texture transferable resource for the contents of the buffer.
viz::TransferableResource resource;
- bool rv =
- buffer->ProduceTransferableResource(frame_sink_holder, false, &resource);
+ bool rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &resource);
ASSERT_TRUE(rv);
static_cast<ui::InProcessContextFactory*>(GetAuraEnv()->context_factory())
@@ -178,8 +179,8 @@ TEST_F(BufferTest, SurfaceTreeHostDestruction) {
buffer->OnAttach();
viz::TransferableResource resource;
// Produce a transferable resource for the contents of the buffer.
- bool rv =
- buffer->ProduceTransferableResource(frame_sink_holder, false, &resource);
+ bool rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &resource);
ASSERT_TRUE(rv);
// Submit frame with resource.
@@ -231,8 +232,8 @@ TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
buffer->OnAttach();
viz::TransferableResource resource;
// Produce a transferable resource for the contents of the buffer.
- bool rv =
- buffer->ProduceTransferableResource(frame_sink_holder, false, &resource);
+ bool rv = buffer->ProduceTransferableResource(
+ frame_sink_holder->resource_manager(), false, &resource);
ASSERT_TRUE(rv);
// Submit frame with resource.
diff --git a/chromium/components/exo/client_controlled_shell_surface.cc b/chromium/components/exo/client_controlled_shell_surface.cc
index 7df8934d9e8..8803c62c31a 100644
--- a/chromium/components/exo/client_controlled_shell_surface.cc
+++ b/chromium/components/exo/client_controlled_shell_surface.cc
@@ -542,10 +542,13 @@ void ClientControlledShellSurface::OnBoundsChangeEvent(
const gfx::Rect& window_bounds,
int bounds_change) {
// 1) Do no update the bounds unless we have geometry from client.
- // 2) Do not update the bounds if window is minimized.
+ // 2) Do not update the bounds if window is minimized unless it
+ // exiting the minimzied state.
// The bounds will be provided by client when unminimized.
if (!geometry().IsEmpty() && !window_bounds.IsEmpty() &&
- !widget_->IsMinimized() && bounds_changed_callback_) {
+ (!widget_->IsMinimized() ||
+ requested_state != ash::mojom::WindowStateType::MINIMIZED) &&
+ bounds_changed_callback_) {
// Sends the client bounds, which matches the geometry
// when frame is enabled.
ash::NonClientFrameViewAsh* frame_view = GetFrameView();
@@ -553,8 +556,15 @@ void ClientControlledShellSurface::OnBoundsChangeEvent(
// The client's geometry uses fullscreen in client controlled,
// (but the surface is placed under the frame), so just use
// the window bounds instead for maximixed state.
+ // Snapped window states in tablet mode also do not include the caption
+ // height.
+ const bool becoming_snapped =
+ requested_state == ash::mojom::WindowStateType::LEFT_SNAPPED ||
+ requested_state == ash::mojom::WindowStateType::RIGHT_SNAPPED;
+ const bool is_tablet_mode =
+ WMHelper::GetInstance()->IsTabletModeWindowManagerEnabled();
gfx::Rect client_bounds =
- widget_->IsMaximized()
+ widget_->IsMaximized() || (becoming_snapped && is_tablet_mode)
? window_bounds
: frame_view->GetClientBoundsForWindowBounds(window_bounds);
gfx::Size current_size = frame_view->GetBoundsForClientView().size();
@@ -904,7 +914,8 @@ bool ClientControlledShellSurface::OnPreWidgetCommit() {
case ash::mojom::WindowStateType::MAXIMIZED:
case ash::mojom::WindowStateType::FULLSCREEN:
- animation_type = ash::wm::ClientControlledState::kAnimationCrossFade;
+ if (!window_state->IsPip())
+ animation_type = ash::wm::ClientControlledState::kAnimationCrossFade;
break;
default:
@@ -922,12 +933,21 @@ bool ClientControlledShellSurface::OnPreWidgetCommit() {
decorator_.reset(); // Remove rounded corners.
}
+ bool wasPip = window_state->IsPip();
+
if (client_controlled_state_->EnterNextState(window_state,
pending_window_state_)) {
client_controlled_state_->set_next_bounds_change_animation_type(
animation_type);
}
+ if (wasPip && !window_state->IsMinimized()) {
+ // As Android doesn't activate PIP tasks after they are expanded, we need
+ // to do it here explicitly.
+ // TODO(937738): Investigate if we can activate PIP windows inside commit.
+ window_state->Activate();
+ }
+
return true;
}
diff --git a/chromium/components/exo/client_controlled_shell_surface_unittest.cc b/chromium/components/exo/client_controlled_shell_surface_unittest.cc
index 275784efaff..eab34b4c886 100644
--- a/chromium/components/exo/client_controlled_shell_surface_unittest.cc
+++ b/chromium/components/exo/client_controlled_shell_surface_unittest.cc
@@ -18,7 +18,9 @@
#include "ash/wm/drag_window_resizer.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/splitview/split_view_controller.h"
+#include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_delegate.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
+#include "ash/wm/tablet_mode/tablet_mode_window_drag_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_resizer.h"
@@ -26,6 +28,7 @@
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "ash/wm/workspace_controller_test_api.h"
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "cc/paint/display_item_list.h"
@@ -1085,8 +1088,50 @@ TEST_F(ClientControlledShellSurfaceTest, ClientIniatedResize) {
ASSERT_FALSE(window_state->is_dragged());
}
+namespace {
+
+class ClientControlledShellSurfaceDragTest : public test::ExoTestBase {
+ public:
+ ClientControlledShellSurfaceDragTest() = default;
+ ~ClientControlledShellSurfaceDragTest() override = default;
+
+ // Sends a gesture scroll sequence to TabletModeAppWindowDragController.
+ void SendGestureEvents(aura::Window* window,
+ const gfx::Point& location,
+ bool fling = false,
+ float velocity = 0.f) {
+ ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
+ window_state->CreateDragDetails(gfx::Point(0, 0), HTCLIENT,
+ ::wm::WINDOW_MOVE_SOURCE_TOUCH);
+ std::unique_ptr<ash::TabletModeWindowDragController> controller_ =
+ std::make_unique<ash::TabletModeWindowDragController>(
+ window_state,
+ std::make_unique<ash::TabletModeBrowserWindowDragDelegate>());
+ controller_->drag_delegate_for_testing()
+ ->set_drag_start_deadline_for_testing(base::Time::Now());
+ controller_->Drag(location, 0);
+ if (fling) {
+ ui::GestureEventDetails details =
+ ui::GestureEventDetails(ui::ET_SCROLL_FLING_START, 0, velocity);
+ ui::GestureEvent event =
+ ui::GestureEvent(location.x(), location.y(), ui::EF_NONE,
+ base::TimeTicks::Now(), details);
+ ui::Event::DispatcherApi(&event).set_target(window);
+ controller_->FlingOrSwipe(&event);
+ } else {
+ controller_->CompleteDrag();
+ }
+ ash::wm::GetWindowState(window)->DeleteDragDetails();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ClientControlledShellSurfaceDragTest);
+};
+
+} // namespace
+
// Test the functionalities of dragging a window from top in tablet mode.
-TEST_F(ClientControlledShellSurfaceTest, DragWindowFromTopInTabletMode) {
+TEST_F(ClientControlledShellSurfaceDragTest, DragWindowFromTopInTabletMode) {
UpdateDisplay("800x600");
ash::Shell* shell = ash::Shell::Get();
shell->tablet_mode_controller()->EnableTabletModeWindowManager(true);
@@ -1105,39 +1150,27 @@ TEST_F(ClientControlledShellSurfaceTest, DragWindowFromTopInTabletMode) {
ASSERT_TRUE(ash::wm::GetWindowState(window)->IsMaximized());
surface->SetFrame(SurfaceFrameType::AUTOHIDE);
surface->Commit();
- ui::test::EventGenerator* event_generator = GetEventGenerator();
// Drag the window by a small amount of distance will maximize the window
// again.
- const gfx::Point start(0, 0);
- gfx::Point end(0, 10);
- event_generator->GestureScrollSequence(
- start, end, base::TimeDelta::FromMilliseconds(100), 2);
+ SendGestureEvents(window, gfx::Point(0, 10));
EXPECT_TRUE(ash::wm::GetWindowState(window)->IsMaximized());
+ EXPECT_FALSE(shell->overview_controller()->IsSelecting());
// FLING the window not inisde preview area with large enough y veloicty
// (larger than kFlingToOverviewThreshold) will drop the window into overview.
- EXPECT_FALSE(shell->overview_controller()->IsSelecting());
- end = gfx::Point(400, 210);
- const base::TimeDelta duration =
- event_generator->CalculateScrollDurationForFlingVelocity(
- start, end,
- ash::TabletModeWindowDragDelegate::kFlingToOverviewThreshold + 10.f,
- 200);
- event_generator->GestureScrollSequence(start, end, duration, 200);
- EXPECT_TRUE(shell->overview_controller()->IsSelecting());
+ SendGestureEvents(
+ window, gfx::Point(400, 10), /*fling=*/true,
+ ash::TabletModeWindowDragDelegate::kFlingToOverviewThreshold + 10.f);
+ ASSERT_TRUE(shell->overview_controller()->IsSelecting());
EXPECT_TRUE(
shell->overview_controller()->overview_session()->IsWindowInOverview(
window));
// Drag the window long enough (pass one fourth of the screen vertical
// height) to snap the window to splitscreen.
- end = gfx::Point(0, 210);
shell->overview_controller()->ToggleOverview();
- EXPECT_FALSE(shell->overview_controller()->IsSelecting());
- EXPECT_TRUE(ash::wm::GetWindowState(window)->IsMaximized());
- event_generator->GestureScrollSequence(
- start, end, base::TimeDelta::FromMilliseconds(100), 20);
+ SendGestureEvents(window, gfx::Point(0, 210));
EXPECT_EQ(ash::wm::GetWindowState(window)->GetStateType(),
ash::mojom::WindowStateType::LEFT_SNAPPED);
}
@@ -1817,6 +1850,35 @@ TEST_F(ClientControlledShellSurfaceDisplayTest,
ash::mojom::WindowStateType::MINIMIZED, 0,
gfx::Rect(0, 0, 100, 100), 0);
ASSERT_EQ(1, bounds_change_count());
+
+ // Send bounds change when exiting minmized.
+ shell_surface->OnBoundsChangeEvent(ash::mojom::WindowStateType::MINIMIZED,
+ ash::mojom::WindowStateType::NORMAL, 0,
+ gfx::Rect(0, 0, 100, 100), 0);
+ ASSERT_EQ(2, bounds_change_count());
+
+ // Snapped, in clamshell mode.
+ ash::NonClientFrameViewAsh* frame_view =
+ static_cast<ash::NonClientFrameViewAsh*>(
+ shell_surface->GetWidget()->non_client_view()->frame_view());
+ surface->SetFrame(SurfaceFrameType::NORMAL);
+ surface->Commit();
+ shell_surface->OnBoundsChangeEvent(ash::mojom::WindowStateType::MINIMIZED,
+ ash::mojom::WindowStateType::RIGHT_SNAPPED,
+ 0, gfx::Rect(0, 0, 100, 100), 0);
+ EXPECT_EQ(3, bounds_change_count());
+ EXPECT_EQ(
+ frame_view->GetClientBoundsForWindowBounds(gfx::Rect(0, 0, 100, 100)),
+ requested_bounds().back());
+ EXPECT_NE(gfx::Rect(0, 0, 100, 100), requested_bounds().back());
+
+ // Snapped, in tablet mode.
+ EnableTabletMode(true);
+ shell_surface->OnBoundsChangeEvent(ash::mojom::WindowStateType::MINIMIZED,
+ ash::mojom::WindowStateType::RIGHT_SNAPPED,
+ 0, gfx::Rect(0, 0, 100, 100), 0);
+ EXPECT_EQ(4, bounds_change_count());
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100), requested_bounds().back());
}
TEST_F(ClientControlledShellSurfaceTest, SetPipWindowBoundsAnimates) {
@@ -1836,9 +1898,11 @@ TEST_F(ClientControlledShellSurfaceTest, SetPipWindowBoundsAnimates) {
ui::ScopedAnimationDurationScaleMode animation_scale_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
+ EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->GetTargetBounds());
+ EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
window->SetBounds(gfx::Rect(10, 10, 256, 256));
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds());
- EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->bounds());
+ EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
}
TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) {
@@ -1856,13 +1920,15 @@ TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) {
shell_surface->GetWidget()->Show();
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
+ EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->GetTargetBounds());
+ EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
ui::ScopedAnimationDurationScaleMode animation_scale_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer(
window, gfx::Point(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE));
resizer->Drag(gfx::Point(10, 10), 0);
- EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds());
- EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->bounds());
+ EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->GetTargetBounds());
+ EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->bounds());
resizer->CompleteDrag();
}
diff --git a/chromium/components/exo/data_offer.cc b/chromium/components/exo/data_offer.cc
index 1882ede3e0f..5eadd45447f 100644
--- a/chromium/components/exo/data_offer.cc
+++ b/chromium/components/exo/data_offer.cc
@@ -4,6 +4,7 @@
#include "components/exo/data_offer.h"
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
@@ -105,7 +106,7 @@ void DataOffer::RemoveObserver(DataOfferObserver* observer) {
observers_.RemoveObserver(observer);
}
-void DataOffer::Accept(const std::string& mime_type) {}
+void DataOffer::Accept(const std::string* mime_type) {}
void DataOffer::Receive(const std::string& mime_type, base::ScopedFD fd) {
const auto data_it = data_.find(mime_type);
diff --git a/chromium/components/exo/data_offer.h b/chromium/components/exo/data_offer.h
index 3475dc554c2..790c906c59a 100644
--- a/chromium/components/exo/data_offer.h
+++ b/chromium/components/exo/data_offer.h
@@ -43,7 +43,7 @@ class DataOffer final : public ui::PropertyHandler {
void RemoveObserver(DataOfferObserver* observer);
// Notifies to the DataOffer that the client can accept |mime type|.
- void Accept(const std::string& mime_type);
+ void Accept(const std::string* mime_type);
// Notifies to the DataOffer that the client start receiving data of
// |mime_type|. DataOffer writes the request data to |fd|.
diff --git a/chromium/components/exo/data_offer_unittest.cc b/chromium/components/exo/data_offer_unittest.cc
index 97f5ef6acc0..465dd05fd6a 100644
--- a/chromium/components/exo/data_offer_unittest.cc
+++ b/chromium/components/exo/data_offer_unittest.cc
@@ -372,5 +372,11 @@ TEST_F(DataOfferTest, SetClipboardData) {
EXPECT_EQ(std::string("Test data"), result);
}
+TEST_F(DataOfferTest, AcceptWithNull) {
+ TestDataOfferDelegate delegate;
+ DataOffer data_offer(&delegate);
+ data_offer.Accept(nullptr);
+}
+
} // namespace
} // namespace exo
diff --git a/chromium/components/exo/data_source.cc b/chromium/components/exo/data_source.cc
index 0cf1cae34fb..5b5b372e844 100644
--- a/chromium/components/exo/data_source.cc
+++ b/chromium/components/exo/data_source.cc
@@ -4,6 +4,7 @@
#include "components/exo/data_source.h"
+#include "base/bind.h"
#include "base/posix/eintr_wrapper.h"
#include "base/task/post_task.h"
#include "components/exo/data_source_delegate.h"
diff --git a/chromium/components/exo/display.h b/chromium/components/exo/display.h
index a1fa2d55677..34fcb3b2303 100644
--- a/chromium/components/exo/display.h
+++ b/chromium/components/exo/display.h
@@ -23,7 +23,7 @@
namespace gfx {
class ClientNativePixmapFactory;
-};
+}
namespace exo {
class ClientControlledShellSurface;
diff --git a/chromium/components/exo/frame_sink_resource_manager.cc b/chromium/components/exo/frame_sink_resource_manager.cc
new file mode 100644
index 00000000000..90be3a6f967
--- /dev/null
+++ b/chromium/components/exo/frame_sink_resource_manager.cc
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/frame_sink_resource_manager.h"
+
+#include <utility>
+
+#include "base/stl_util.h"
+
+namespace exo {
+
+FrameSinkResourceManager::FrameSinkResourceManager() {}
+FrameSinkResourceManager::~FrameSinkResourceManager() {
+ ClearAllCallbacks();
+}
+
+bool FrameSinkResourceManager::HasReleaseCallbackForResource(
+ viz::ResourceId id) {
+ return release_callbacks_.find(id) != release_callbacks_.end();
+}
+void FrameSinkResourceManager::SetResourceReleaseCallback(
+ viz::ResourceId id,
+ viz::ReleaseCallback callback) {
+ DCHECK(!callback.is_null());
+ release_callbacks_[id] = std::move(callback);
+}
+int FrameSinkResourceManager::AllocateResourceId() {
+ return next_resource_id_++;
+}
+
+bool FrameSinkResourceManager::HasNoCallbacks() const {
+ return release_callbacks_.empty();
+}
+
+void FrameSinkResourceManager::ReclaimResource(
+ const viz::ReturnedResource& resource) {
+ auto it = release_callbacks_.find(resource.id);
+ DCHECK(it != release_callbacks_.end());
+ if (it != release_callbacks_.end()) {
+ std::move(it->second).Run(resource.sync_token, resource.lost);
+ release_callbacks_.erase(it);
+ }
+}
+
+void FrameSinkResourceManager::ClearAllCallbacks() {
+ for (auto& callback : release_callbacks_)
+ std::move(callback.second).Run(gpu::SyncToken(), true /* lost */);
+ release_callbacks_.clear();
+}
+
+} // namespace exo
diff --git a/chromium/components/exo/frame_sink_resource_manager.h b/chromium/components/exo/frame_sink_resource_manager.h
new file mode 100644
index 00000000000..c22040825dc
--- /dev/null
+++ b/chromium/components/exo/frame_sink_resource_manager.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_FRAME_SINK_RESOURCE_MANAGER_H_
+#define COMPONENTS_EXO_FRAME_SINK_RESOURCE_MANAGER_H_
+
+#include "base/containers/flat_map.h"
+#include "components/viz/common/resources/release_callback.h"
+#include "components/viz/common/resources/resource_id.h"
+#include "components/viz/common/resources/returned_resource.h"
+
+namespace exo {
+
+// This class manages the resource IDs and active resource callbacks suitable
+// for implementing a frame sink.
+class FrameSinkResourceManager {
+ public:
+ FrameSinkResourceManager();
+ ~FrameSinkResourceManager();
+
+ bool HasReleaseCallbackForResource(viz::ResourceId id);
+ void SetResourceReleaseCallback(viz::ResourceId id,
+ viz::ReleaseCallback callback);
+ int AllocateResourceId();
+
+ bool HasNoCallbacks() const;
+ void ReclaimResource(const viz::ReturnedResource& resource);
+ void ClearAllCallbacks();
+
+ private:
+ // A collection of callbacks used to release resources.
+ using ResourceReleaseCallbackMap =
+ base::flat_map<viz::ResourceId, viz::ReleaseCallback>;
+ ResourceReleaseCallbackMap release_callbacks_;
+
+ // The next resource id the buffer is attached to.
+ int next_resource_id_ = 1;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameSinkResourceManager);
+};
+
+} // namespace exo
+
+#endif // COMPONENTS_EXO_FRAME_SINK_RESOURCE_MANAGER_H_
diff --git a/chromium/components/exo/fullscreen_shell_surface_unittest.cc b/chromium/components/exo/fullscreen_shell_surface_unittest.cc
index c408159d355..d54d580d117 100644
--- a/chromium/components/exo/fullscreen_shell_surface_unittest.cc
+++ b/chromium/components/exo/fullscreen_shell_surface_unittest.cc
@@ -4,6 +4,7 @@
#include "components/exo/fullscreen_shell_surface.h"
+#include "base/bind.h"
#include "components/exo/buffer.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
diff --git a/chromium/components/exo/gaming_seat_unittest.cc b/chromium/components/exo/gaming_seat_unittest.cc
index 922adcb3c01..2ebac9aaf43 100644
--- a/chromium/components/exo/gaming_seat_unittest.cc
+++ b/chromium/components/exo/gaming_seat_unittest.cc
@@ -27,8 +27,8 @@ class MockGamingSeatDelegate : public GamingSeatDelegate {
MOCK_CONST_METHOD1(CanAcceptGamepadEventsForSurface, bool(Surface*));
MOCK_METHOD0(GamepadAdded, GamepadDelegate*());
MOCK_METHOD0(Die, void());
- void OnGamingSeatDestroying(GamingSeat*) override { delete this; };
- ~MockGamingSeatDelegate() { Die(); };
+ void OnGamingSeatDestroying(GamingSeat*) override { delete this; }
+ ~MockGamingSeatDelegate() { Die(); }
};
class MockGamepadDelegate : public GamepadDelegate {
diff --git a/chromium/components/exo/input_method_surface.cc b/chromium/components/exo/input_method_surface.cc
index 3dfc8501048..c5563cba920 100644
--- a/chromium/components/exo/input_method_surface.cc
+++ b/chromium/components/exo/input_method_surface.cc
@@ -8,16 +8,14 @@
#include "components/exo/input_method_surface_manager.h"
#include "components/exo/wm_helper.h"
#include "ui/base/class_property.h"
+#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/accessibility/view_accessibility.h"
-namespace {
-DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(exo::InputMethodSurface*,
- kInputMethodSurface,
- nullptr);
-}
-
-DEFINE_UI_CLASS_PROPERTY_TYPE(exo::InputMethodSurface*);
+DEFINE_UI_CLASS_PROPERTY_KEY(exo::InputMethodSurface*,
+ kInputMethodSurface,
+ nullptr)
+DEFINE_UI_CLASS_PROPERTY_TYPE(exo::InputMethodSurface*)
namespace exo {
@@ -30,7 +28,7 @@ InputMethodSurface::InputMethodSurface(InputMethodSurfaceManager* manager,
ash::kShellWindowId_ArcVirtualKeyboardContainer),
manager_(manager),
input_method_bounds_(),
- default_device_scale_factore_(default_device_scale_factor) {
+ default_device_scale_factor_(default_device_scale_factor) {
SetScale(default_device_scale_factor);
host_window()->SetName("ExoInputMethodSurface");
host_window()->SetProperty(kInputMethodSurface, this);
@@ -74,17 +72,15 @@ void InputMethodSurface::OnSurfaceCommit() {
gfx::Rect new_bounds = root_surface()->hit_test_region().bounds();
if (input_method_bounds_ != new_bounds) {
- input_method_bounds_ = new_bounds;
+ input_method_bounds_ =
+ gfx::ConvertRectToDIP(default_device_scale_factor_, new_bounds);
manager_->OnTouchableBoundsChanged(this);
- gfx::RectF bounds(input_method_bounds_);
- bounds.Scale(1.0 / default_device_scale_factore_);
- GetViewAccessibility().OverrideBounds(bounds);
+ GetViewAccessibility().OverrideBounds(gfx::RectF(input_method_bounds_));
}
}
gfx::Rect InputMethodSurface::GetBounds() const {
- // TODO(crbug.com/912449): This should return bounds in DIP.
return input_method_bounds_;
}
diff --git a/chromium/components/exo/input_method_surface.h b/chromium/components/exo/input_method_surface.h
index 8ceabff4d0d..cb0f1e9a95c 100644
--- a/chromium/components/exo/input_method_surface.h
+++ b/chromium/components/exo/input_method_surface.h
@@ -32,8 +32,9 @@ class InputMethodSurface : public ClientControlledShellSurface {
private:
InputMethodSurfaceManager* const manager_;
bool added_to_manager_ = false;
+ // The bounds of this surface in DIP.
gfx::Rect input_method_bounds_;
- double default_device_scale_factore_;
+ double default_device_scale_factor_;
DISALLOW_COPY_AND_ASSIGN(InputMethodSurface);
};
diff --git a/chromium/components/exo/keyboard.cc b/chromium/components/exo/keyboard.cc
index b03de707050..6555289f623 100644
--- a/chromium/components/exo/keyboard.cc
+++ b/chromium/components/exo/keyboard.cc
@@ -5,6 +5,7 @@
#include "components/exo/keyboard.h"
#include "ash/public/cpp/app_types.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/exo/keyboard_delegate.h"
#include "components/exo/keyboard_device_configuration_delegate.h"
@@ -115,7 +116,10 @@ bool ConsumedByIme(Surface* focus, const ui::KeyEvent* event) {
bool IsVirtualKeyboardEnabled() {
return keyboard::GetAccessibilityKeyboardEnabled() ||
- keyboard::GetTouchKeyboardEnabled();
+ keyboard::GetTouchKeyboardEnabled() ||
+ (keyboard::KeyboardController::HasInstance() &&
+ keyboard::KeyboardController::Get()->IsEnableFlagSet(
+ keyboard::mojom::KeyboardEnableFlag::kCommandLineEnabled));
}
bool IsReservedAccelerator(const ui::KeyEvent* event) {
diff --git a/chromium/components/exo/layer_tree_frame_sink_holder.cc b/chromium/components/exo/layer_tree_frame_sink_holder.cc
index 3ee66542bbe..c223020261b 100644
--- a/chromium/components/exo/layer_tree_frame_sink_holder.cc
+++ b/chromium/components/exo/layer_tree_frame_sink_holder.cc
@@ -29,9 +29,6 @@ LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() {
if (frame_sink_)
frame_sink_->DetachFromClient();
- for (auto& callback : release_callbacks_)
- std::move(callback.second).Run(gpu::SyncToken(), true /* lost */);
-
if (lifetime_manager_)
lifetime_manager_->RemoveObserver(this);
}
@@ -68,7 +65,7 @@ void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed(
// Delete sink holder immediately if not waiting for resources to be
// reclaimed.
- if (holder->release_callbacks_.empty())
+ if (holder->resource_manager_.HasNoCallbacks())
return;
WMHelper::LifetimeManager* lifetime_manager =
@@ -102,22 +99,6 @@ void LayerTreeFrameSinkHolder::DidNotProduceFrame(
frame_sink_->DidNotProduceFrame(ack);
}
-bool LayerTreeFrameSinkHolder::HasReleaseCallbackForResource(
- viz::ResourceId id) {
- return release_callbacks_.find(id) != release_callbacks_.end();
-}
-
-void LayerTreeFrameSinkHolder::SetResourceReleaseCallback(
- viz::ResourceId id,
- viz::ReleaseCallback callback) {
- DCHECK(!callback.is_null());
- release_callbacks_[id] = std::move(callback);
-}
-
-int LayerTreeFrameSinkHolder::AllocateResourceId() {
- return next_resource_id_++;
-}
-
base::WeakPtr<LayerTreeFrameSinkHolder> LayerTreeFrameSinkHolder::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
@@ -138,15 +119,10 @@ void LayerTreeFrameSinkHolder::ReclaimResources(
if (base::ContainsValue(last_frame_resources_, resource.id)) {
continue;
}
- auto it = release_callbacks_.find(resource.id);
- DCHECK(it != release_callbacks_.end());
- if (it != release_callbacks_.end()) {
- std::move(it->second).Run(resource.sync_token, resource.lost);
- release_callbacks_.erase(it);
- }
+ resource_manager_.ReclaimResource(resource);
}
- if (lifetime_manager_ && release_callbacks_.empty())
+ if (lifetime_manager_ && resource_manager_.HasNoCallbacks())
ScheduleDelete();
}
@@ -164,9 +140,7 @@ void LayerTreeFrameSinkHolder::DidPresentCompositorFrame(
void LayerTreeFrameSinkHolder::DidLoseLayerTreeFrameSink() {
last_frame_resources_.clear();
- for (auto& callback : release_callbacks_)
- std::move(callback.second).Run(gpu::SyncToken(), true /* lost */);
- release_callbacks_.clear();
+ resource_manager_.ClearAllCallbacks();
if (lifetime_manager_)
ScheduleDelete();
diff --git a/chromium/components/exo/layer_tree_frame_sink_holder.h b/chromium/components/exo/layer_tree_frame_sink_holder.h
index c6645a828b5..7d9f727b7d0 100644
--- a/chromium/components/exo/layer_tree_frame_sink_holder.h
+++ b/chromium/components/exo/layer_tree_frame_sink_holder.h
@@ -9,6 +9,7 @@
#include "base/containers/flat_map.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
+#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/wm_helper.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/resources/release_callback.h"
@@ -40,12 +41,10 @@ class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
void SubmitCompositorFrame(viz::CompositorFrame frame);
void DidNotProduceFrame(const viz::BeginFrameAck& ack);
- bool HasReleaseCallbackForResource(viz::ResourceId id);
- void SetResourceReleaseCallback(viz::ResourceId id,
- viz::ReleaseCallback callback);
- int AllocateResourceId();
base::WeakPtr<LayerTreeFrameSinkHolder> GetWeakPtr();
+ FrameSinkResourceManager* resource_manager() { return &resource_manager_; }
+
// Overridden from cc::LayerTreeFrameSinkClient:
void SetBeginFrameSource(viz::BeginFrameSource* source) override {}
base::Optional<viz::HitTestRegionList> BuildHitTestData() override;
@@ -73,16 +72,10 @@ class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
// WMHelper::LifetimeManager::Observer:
void OnDestroyed() override;
- // A collection of callbacks used to release resources.
- using ResourceReleaseCallbackMap =
- base::flat_map<viz::ResourceId, viz::ReleaseCallback>;
- ResourceReleaseCallbackMap release_callbacks_;
-
SurfaceTreeHost* surface_tree_host_;
std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_;
- // The next resource id the buffer is attached to.
- int next_resource_id_ = 1;
+ FrameSinkResourceManager resource_manager_;
gfx::Size last_frame_size_in_pixels_;
float last_frame_device_scale_factor_ = 1.0f;
diff --git a/chromium/components/exo/pointer.cc b/chromium/components/exo/pointer.cc
index 00e1934e2f0..c2098b49338 100644
--- a/chromium/components/exo/pointer.cc
+++ b/chromium/components/exo/pointer.cc
@@ -7,14 +7,18 @@
#include <utility>
#include "ash/public/cpp/shell_window_ids.h"
+#include "base/bind.h"
+#include "base/feature_list.h"
#include "components/exo/pointer_delegate.h"
#include "components/exo/pointer_gesture_pinch_delegate.h"
+#include "components/exo/relative_pointer_delegate.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface.h"
#include "components/exo/wm_helper.h"
#include "components/exo/wm_helper_chromeos.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
@@ -36,6 +40,11 @@
#endif
namespace exo {
+
+// Controls Pointer capture in exo/wayland.
+const base::Feature kPointerCapture{"ExoPointerCapture",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
namespace {
// TODO(oshima): Some accessibility features, including large cursors, disable
@@ -90,6 +99,7 @@ Pointer::Pointer(PointerDelegate* delegate)
aura::client::CursorClient* cursor_client = helper->GetCursorClient();
if (cursor_client)
cursor_client->AddObserver(this);
+ helper->AddFocusObserver(this);
}
Pointer::~Pointer() {
@@ -99,6 +109,8 @@ Pointer::~Pointer() {
}
if (pinch_delegate_)
pinch_delegate_->OnPointerDestroying(this);
+ if (relative_pointer_delegate_)
+ relative_pointer_delegate_->OnPointerDestroying(this);
WMHelperChromeOS* helper = WMHelperChromeOS::GetInstance();
helper->RemoveDisplayConfigurationObserver(this);
helper->RemovePreTargetHandler(this);
@@ -109,6 +121,7 @@ Pointer::~Pointer() {
cursor_client->RemoveObserver(this);
if (root_surface())
root_surface()->RemoveSurfaceObserver(this);
+ helper->RemoveFocusObserver(this);
}
void Pointer::SetCursor(Surface* surface, const gfx::Point& hotspot) {
@@ -173,6 +186,89 @@ void Pointer::SetGesturePinchDelegate(PointerGesturePinchDelegate* delegate) {
pinch_delegate_ = delegate;
}
+void Pointer::EnablePointerCapture(RelativePointerDelegate* delegate) {
+ if (!base::FeatureList::IsEnabled(kPointerCapture))
+ return;
+
+ if (!delegate) {
+ DLOG(ERROR) << "Failed to enable pointer capture: "
+ "relative pointer delegate is null";
+ return;
+ }
+
+ // If pointer capture is already enabled, disable it first.
+ if (relative_pointer_delegate_)
+ DisablePointerCapture();
+
+ // TODO(b/124059008): Find the correct window to set capture.
+ aura::Window* active_window = WMHelper::GetInstance()->GetActiveWindow();
+ if (!active_window) {
+ LOG(ERROR) << "Failed to enable pointer capture: "
+ "active window not found";
+ return;
+ }
+ auto* top_level_widget =
+ views::Widget::GetTopLevelWidgetForNativeView(active_window);
+
+ if (!top_level_widget) {
+ LOG(ERROR) << "Failed to enable pointer capture: "
+ "active window does not have associated widget";
+ return;
+ }
+ Surface* root_surface =
+ GetShellMainSurface(top_level_widget->GetNativeWindow());
+ if (!root_surface ||
+ !delegate_->CanAcceptPointerEventsForSurface(root_surface)) {
+ LOG(ERROR) << "Failed to enable pointer capture: "
+ "cannot find window for capture";
+ return;
+ }
+ capture_window_ = root_surface->window();
+
+ auto* capture_client = WMHelper::GetInstance()->GetCaptureClient();
+ capture_client->SetCapture(capture_window_);
+ capture_client->AddObserver(this);
+
+ auto* cursor_client = WMHelper::GetInstance()->GetCursorClient();
+ cursor_client->HideCursor();
+ cursor_client->LockCursor();
+
+ relative_pointer_delegate_ = delegate;
+ location_when_pointer_capture_enabled_ = gfx::ToRoundedPoint(location_);
+
+ if (ShouldMoveToCenter())
+ MoveCursorToCenterOfActiveDisplay();
+}
+
+void Pointer::DisablePointerCapture() {
+ // Early out if pointer capture is not enabled.
+ if (!relative_pointer_delegate_)
+ return;
+
+ auto* capture_client = WMHelper::GetInstance()->GetCaptureClient();
+ capture_client->RemoveObserver(this);
+ if (capture_window_ && capture_window_->HasCapture())
+ capture_client->ReleaseCapture(capture_window_);
+ capture_window_ = nullptr;
+
+ auto* cursor_client = WMHelper::GetInstance()->GetCursorClient();
+ cursor_client->UnlockCursor();
+ cursor_client->ShowCursor();
+
+ aura::Window* focusedWindow = WMHelper::GetInstance()->GetFocusedWindow();
+ aura::Window* root = focusedWindow->GetRootWindow();
+ gfx::Point p = location_when_pointer_capture_enabled_
+ ? *location_when_pointer_capture_enabled_
+ : root->bounds().CenterPoint();
+ root->MoveCursorTo(p);
+
+ focus_surface_ = nullptr;
+ location_when_pointer_capture_enabled_.reset();
+ UpdateCursor();
+
+ relative_pointer_delegate_ = nullptr;
+}
+
////////////////////////////////////////////////////////////////////////////////
// SurfaceDelegate overrides:
@@ -215,6 +311,8 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
if (target != focus_surface_)
SetFocus(target, location_in_target, event->button_flags());
+ gfx::PointF location_in_root = GetLocationInRoot(target, location_in_target);
+
if (!focus_surface_)
return;
@@ -229,12 +327,15 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
// so to avoid generating mouse event jitter we consider the location of
// these events to be the same as |location| if floored values match.
bool same_location = !event->IsSynthesized()
- ? SameLocation(location_in_target, location_)
- : gfx::ToFlooredPoint(location_in_target) ==
+ ? SameLocation(location_in_root, location_)
+ : gfx::ToFlooredPoint(location_in_root) ==
gfx::ToFlooredPoint(location_);
if (!same_location) {
- location_ = location_in_target;
- delegate_->OnPointerMotion(event->time_stamp(), location_);
+ if (relative_pointer_delegate_)
+ HandleRelativePointerMotion(event->time_stamp(), location_in_root);
+ else
+ delegate_->OnPointerMotion(event->time_stamp(), location_in_target);
+ location_ = location_in_root;
delegate_->OnPointerFrame();
}
}
@@ -250,6 +351,11 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) {
}
case ui::ET_SCROLL: {
ui::ScrollEvent* scroll_event = static_cast<ui::ScrollEvent*>(event);
+
+ // Scrolling with 3+ fingers should not be handled since it will be used
+ // to trigger overview mode.
+ if (scroll_event->finger_count() >= 3)
+ break;
delegate_->OnPointerScroll(
event->time_stamp(),
gfx::Vector2dF(scroll_event->x_offset(), scroll_event->y_offset()),
@@ -336,7 +442,17 @@ void Pointer::OnGestureEvent(ui::GestureEvent* event) {
}
////////////////////////////////////////////////////////////////////////////////
-// ui::client::CursorClientObserver overrides:
+// aura::client::CaptureClientObserver overrides:
+
+void Pointer::OnCaptureChanged(aura::Window* lost_capture,
+ aura::Window* gained_capture) {
+ // Note: This observer is only set when pointer capture in enabled.
+ if (relative_pointer_delegate_ && gained_capture != capture_window_)
+ DisablePointerCapture();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// aura::client::CursorClientObserver overrides:
void Pointer::OnCursorSizeChanged(ui::CursorSize cursor_size) {
if (!focus_surface_)
@@ -362,6 +478,15 @@ void Pointer::OnCursorDisplayChanged(const display::Display& display) {
}
////////////////////////////////////////////////////////////////////////////////
+// aura::client::FocusChangeObserver overrides:
+
+void Pointer::OnWindowFocused(aura::Window* gained_focus,
+ aura::Window* lost_focus) {
+ if (relative_pointer_delegate_)
+ DisablePointerCapture();
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ash::WindowTreeHostManager::Observer overrides:
void Pointer::OnDisplayConfigurationChanged() {
@@ -398,7 +523,7 @@ void Pointer::SetFocus(Surface* surface,
// Second generate an enter event if focus moved to a new surface.
if (surface) {
delegate_->OnPointerEnter(surface, location, button_flags);
- location_ = location;
+ location_ = GetLocationInRoot(surface, location);
focus_surface_ = surface;
focus_surface_->AddSurfaceObserver(this);
}
@@ -534,4 +659,56 @@ void Pointer::UpdateCursor() {
}
}
+gfx::PointF Pointer::GetLocationInRoot(Surface* target,
+ gfx::PointF location_in_target) {
+ if (!target || !target->window())
+ return location_in_target;
+ aura::Window* w = target->window();
+ gfx::PointF p(location_in_target.x(), location_in_target.y());
+ aura::Window::ConvertPointToTarget(w, w->GetRootWindow(), &p);
+ return gfx::PointF(p.x(), p.y());
+}
+
+bool Pointer::ShouldMoveToCenter() {
+ // Early out if the pointer doesn't have a surface in focus.
+ if (!focus_surface_)
+ return false;
+
+ gfx::Rect rect =
+ WMHelper::GetInstance()->GetFocusedWindow()->GetRootWindow()->bounds();
+
+ rect.Inset(rect.width() / 6, rect.height() / 6);
+ return !rect.Contains(location_.x(), location_.y());
+}
+
+void Pointer::MoveCursorToCenterOfActiveDisplay() {
+ aura::Window* focusedWindow = WMHelper::GetInstance()->GetFocusedWindow();
+ aura::Window* root = focusedWindow->GetRootWindow();
+ gfx::Point p = root->bounds().CenterPoint();
+ location_synthetic_move_ = p;
+ root->MoveCursorTo(p);
+}
+
+void Pointer::HandleRelativePointerMotion(base::TimeTicks time_stamp,
+ gfx::PointF location_in_root) {
+ if (location_synthetic_move_) {
+ gfx::Point synthetic = *location_synthetic_move_;
+ // Since MoveCursorTo() takes integer coordinates, the resulting move could
+ // have a conversion error of up to 2 due to fractional scale factors.
+ if (std::abs(location_in_root.x() - synthetic.x()) <= 2 &&
+ std::abs(location_in_root.y() - synthetic.y()) <= 2) {
+ // This was a synthetic move event, so do not forward it and clear the
+ // synthetic move.
+ location_synthetic_move_.reset();
+ return;
+ }
+ }
+
+ gfx::PointF delta(location_in_root.x() - location_.x(),
+ location_in_root.y() - location_.y());
+ relative_pointer_delegate_->OnPointerRelativeMotion(time_stamp, delta);
+ if (ShouldMoveToCenter())
+ MoveCursorToCenterOfActiveDisplay();
+}
+
} // namespace exo
diff --git a/chromium/components/exo/pointer.h b/chromium/components/exo/pointer.h
index 1d66994ff01..30d46e04018 100644
--- a/chromium/components/exo/pointer.h
+++ b/chromium/components/exo/pointer.h
@@ -10,12 +10,15 @@
#include "ash/display/window_tree_host_manager.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/unguessable_token.h"
#include "components/exo/surface_observer.h"
#include "components/exo/surface_tree_host.h"
#include "components/exo/wm_helper.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/aura/client/capture_client_observer.h"
#include "ui/aura/client/cursor_client_observer.h"
+#include "ui/aura/client/focus_change_observer.h"
#include "ui/base/cursor/cursor.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
@@ -35,6 +38,7 @@ class MouseEvent;
namespace exo {
class PointerDelegate;
class PointerGesturePinchDelegate;
+class RelativePointerDelegate;
class Surface;
class SurfaceTreeHost;
@@ -43,7 +47,9 @@ class SurfaceTreeHost;
class Pointer : public SurfaceTreeHost,
public SurfaceObserver,
public ui::EventHandler,
+ public aura::client::CaptureClientObserver,
public aura::client::CursorClientObserver,
+ public aura::client::FocusChangeObserver,
public ash::WindowTreeHostManager::Observer {
public:
explicit Pointer(PointerDelegate* delegate);
@@ -68,7 +74,7 @@ class Pointer : public SurfaceTreeHost,
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
- // Overriden from SurfaceObserver:
+ // Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override;
// Overridden from ui::EventHandler:
@@ -76,13 +82,25 @@ class Pointer : public SurfaceTreeHost,
void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
- // Overridden from ui::client::CursorClientObserver:
+ // Overridden from aura::client::CaptureClientObserver:
+ void OnCaptureChanged(aura::Window* lost_capture,
+ aura::Window* gained_capture) override;
+
+ // Overridden from aura::client::CursorClientObserver:
void OnCursorSizeChanged(ui::CursorSize cursor_size) override;
void OnCursorDisplayChanged(const display::Display& display) override;
+ // Overridden from aura::client::FocusChangeObserver;
+ void OnWindowFocused(aura::Window* gained_focus,
+ aura::Window* lost_focus) override;
+
// Overridden from ash::WindowTreeHostManager::Observer:
void OnDisplayConfigurationChanged() override;
+ // Pointer capture toggles:
+ void EnablePointerCapture(RelativePointerDelegate* delegate);
+ void DisablePointerCapture();
+
private:
// Returns the effective target for |event|.
Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const;
@@ -107,18 +125,47 @@ class Pointer : public SurfaceTreeHost,
// Update |cursor_| to |cursor_bitmap_| transformed for the current display.
void UpdateCursor();
+ // Convert the given |location_in_target| to coordinates in the root window.
+ gfx::PointF GetLocationInRoot(Surface* target,
+ gfx::PointF location_in_target);
+
+ // Called to check if cursor should be moved to the center of the window when
+ // sending relative movements.
+ bool ShouldMoveToCenter();
+
+ // Moves the cursor to center of the active display.
+ void MoveCursorToCenterOfActiveDisplay();
+
+ // Process the delta for relative pointer motion.
+ void HandleRelativePointerMotion(base::TimeTicks time_stamp,
+ gfx::PointF location_in_target);
+
// The delegate instance that all events are dispatched to.
PointerDelegate* const delegate_;
// The delegate instance that all pinch related events are dispatched to.
PointerGesturePinchDelegate* pinch_delegate_ = nullptr;
+ // The delegate instance that relative movement events are dispatched to.
+ // Pointer capture is enabled if and only if this is not nullptr.
+ RelativePointerDelegate* relative_pointer_delegate_ = nullptr;
+
// The current focus surface for the pointer.
Surface* focus_surface_ = nullptr;
// The location of the pointer in the current focus surface.
gfx::PointF location_;
+ // The location of the pointer when pointer capture is first enabled.
+ base::Optional<gfx::Point> location_when_pointer_capture_enabled_;
+
+ // If this is not nullptr, a synthetic move was sent and this points to the
+ // location of a generated move that was sent which should not be forwarded.
+ base::Optional<gfx::Point> location_synthetic_move_;
+
+ // The window with input capture.
+ aura::Window* capture_window_ = nullptr;
+
// The position of the pointer surface relative to the pointer location.
gfx::Point hotspot_;
diff --git a/chromium/components/exo/pointer_unittest.cc b/chromium/components/exo/pointer_unittest.cc
index 7e0e51dc974..2b7a8bb647c 100644
--- a/chromium/components/exo/pointer_unittest.cc
+++ b/chromium/components/exo/pointer_unittest.cc
@@ -7,6 +7,7 @@
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/wm/window_positioning_utils.h"
+#include "base/bind.h"
#include "base/run_loop.h"
#include "components/exo/buffer.h"
#include "components/exo/pointer_delegate.h"
@@ -569,6 +570,41 @@ TEST_F(MAYBE_PointerTest, OnPointerScroll) {
pointer.reset();
}
+TEST_F(MAYBE_PointerTest, OnPointerScrollWithThreeFinger) {
+ std::unique_ptr<Surface> surface(new Surface);
+ std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
+ gfx::Size buffer_size(10, 10);
+ std::unique_ptr<Buffer> buffer(
+ new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+ surface->Attach(buffer.get());
+ surface->Commit();
+
+ MockPointerDelegate delegate;
+ std::unique_ptr<Pointer> pointer(new Pointer(&delegate));
+ ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
+ gfx::Point location = surface->window()->GetBoundsInScreen().origin();
+
+ EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface.get()))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(delegate, OnPointerFrame()).Times(2);
+
+ EXPECT_CALL(delegate, OnPointerEnter(surface.get(), gfx::PointF(), 0));
+ generator.MoveMouseTo(location);
+
+ {
+ // Expect no scroll.
+ testing::InSequence sequence;
+ EXPECT_CALL(delegate, OnPointerScrollStop(testing::_));
+ }
+
+ // Three fingers scroll.
+ generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1,
+ 3 /* num_fingers */);
+
+ EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
+ pointer.reset();
+}
+
TEST_F(MAYBE_PointerTest, OnPointerScrollDiscrete) {
std::unique_ptr<Surface> surface(new Surface);
std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
diff --git a/chromium/components/exo/relative_pointer_delegate.h b/chromium/components/exo/relative_pointer_delegate.h
new file mode 100644
index 00000000000..82edd0a19c2
--- /dev/null
+++ b/chromium/components/exo/relative_pointer_delegate.h
@@ -0,0 +1,29 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
+#define COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
+
+#include "base/time/time.h"
+
+namespace exo {
+class Pointer;
+
+// Handles sending relative mouse movements.
+class RelativePointerDelegate {
+ public:
+ // Called at the top of the pointer's destructor, to give observers a
+ // chance to remove themselves.
+ virtual void OnPointerDestroying(Pointer* pointer) = 0;
+
+ virtual void OnPointerRelativeMotion(base::TimeTicks time_stamp,
+ const gfx::PointF& relativeMotion) = 0;
+
+ protected:
+ virtual ~RelativePointerDelegate() {}
+};
+
+} // namespace exo
+
+#endif // COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
diff --git a/chromium/components/exo/seat.cc b/chromium/components/exo/seat.cc
index c7102fb7422..1302b4a3e01 100644
--- a/chromium/components/exo/seat.cc
+++ b/chromium/components/exo/seat.cc
@@ -5,6 +5,7 @@
#include "components/exo/seat.h"
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "components/exo/data_source.h"
#include "components/exo/seat_observer.h"
diff --git a/chromium/components/exo/shell_surface.cc b/chromium/components/exo/shell_surface.cc
index 15513fd1cc3..6a7d3850feb 100644
--- a/chromium/components/exo/shell_surface.cc
+++ b/chromium/components/exo/shell_surface.cc
@@ -523,7 +523,7 @@ void ShellSurface::OnWindowActivated(ActivationReason reason,
////////////////////////////////////////////////////////////////////////////////
// ShellSurface, private:
-void ShellSurface::Configure() {
+void ShellSurface::Configure(bool ends_drag) {
// Delay configure callback if |scoped_configure_| is set.
if (scoped_configure_) {
scoped_configure_->set_needs_configure();
@@ -539,7 +539,7 @@ void ShellSurface::Configure() {
ash::wm::GetWindowState(widget_->GetNativeWindow());
// If surface is being resized, save the resize direction.
- if (window_state->is_dragged())
+ if (window_state->is_dragged() && !ends_drag)
resize_component = window_state->drag_details()->window_component;
}
@@ -621,10 +621,7 @@ void ShellSurface::AttemptToStartDrag(int component) {
void ShellSurface::EndDrag() {
if (resize_component_ != HTCAPTION) {
- // Clear the drag details here as Configure uses it to decide if
- // the window is being dragged.
- ash::wm::GetWindowState(widget_->GetNativeWindow())->DeleteDragDetails();
- Configure();
+ Configure(/*ends_drag=*/true);
}
}
diff --git a/chromium/components/exo/shell_surface.h b/chromium/components/exo/shell_surface.h
index 81f324c4a0c..2e11cfd888f 100644
--- a/chromium/components/exo/shell_surface.h
+++ b/chromium/components/exo/shell_surface.h
@@ -139,8 +139,9 @@ class ShellSurface : public ShellSurfaceBase,
bool OnPreWidgetCommit() override;
void OnPostWidgetCommit() override;
- // Asks the client to configure its surface.
- void Configure();
+ // Asks the client to configure its surface. Optionally, the user can override
+ // the behaviour to check for window dragging by setting ends_drag to true.
+ void Configure(bool ends_drag = false);
void AttemptToStartDrag(int component);
diff --git a/chromium/components/exo/shell_surface_base.cc b/chromium/components/exo/shell_surface_base.cc
index fc34a85fad2..7d6582ca387 100644
--- a/chromium/components/exo/shell_surface_base.cc
+++ b/chromium/components/exo/shell_surface_base.cc
@@ -1108,7 +1108,7 @@ void ShellSurfaceBase::CommitWidget() {
// Prevent window from being activated when hit test region is empty.
bool activatable = activatable_ && HasHitTestRegion();
if (activatable != CanActivate()) {
- set_can_activate(activatable);
+ SetCanActivate(activatable);
// Activate or deactivate window if activation state changed.
if (activatable) {
// Automatically activate only if the window is modal.
diff --git a/chromium/components/exo/shell_surface_unittest.cc b/chromium/components/exo/shell_surface_unittest.cc
index 633808631e6..203261ce893 100644
--- a/chromium/components/exo/shell_surface_unittest.cc
+++ b/chromium/components/exo/shell_surface_unittest.cc
@@ -13,6 +13,7 @@
#include "ash/wm/wm_event.h"
#include "ash/wm/workspace/workspace_window_resizer.h"
#include "ash/wm/workspace_controller_test_api.h"
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/exo/buffer.h"
diff --git a/chromium/components/exo/shell_surface_util.cc b/chromium/components/exo/shell_surface_util.cc
index 973084cab6e..49d304c1d11 100644
--- a/chromium/components/exo/shell_surface_util.cc
+++ b/chromium/components/exo/shell_surface_util.cc
@@ -10,19 +10,20 @@
#include "ui/aura/client/capture_client.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
+#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
namespace exo {
namespace {
-DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
+DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
// Application Id set by the client.
-DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kApplicationIdKey, nullptr);
+DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kApplicationIdKey, nullptr)
// Application Id set by the client.
-DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kStartupIdKey, nullptr);
+DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::string, kStartupIdKey, nullptr)
} // namespace
@@ -72,8 +73,14 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) {
Surface* main_surface = GetShellMainSurface(window);
// Skip if the event is captured by non exo windows.
- if (!main_surface)
- return nullptr;
+ if (!main_surface) {
+ auto* widget = views::Widget::GetTopLevelWidgetForNativeView(window);
+ if (!widget)
+ return nullptr;
+ main_surface = GetShellMainSurface(widget->GetNativeWindow());
+ if (!main_surface)
+ return nullptr;
+ }
while (true) {
aura::Window* focused = window->GetEventHandlerForPoint(
diff --git a/chromium/components/exo/surface.cc b/chromium/components/exo/surface.cc
index ac487b266e0..7495144f88f 100644
--- a/chromium/components/exo/surface.cc
+++ b/chromium/components/exo/surface.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "ash/public/cpp/shell_window_ids.h"
#include "base/callback_helpers.h"
#include "base/containers/adapters.h"
#include "base/logging.h"
@@ -13,8 +14,8 @@
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
-#include "cc/trees/layer_tree_frame_sink.h"
#include "components/exo/buffer.h"
+#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/shell_surface_util.h"
#include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h"
@@ -48,21 +49,21 @@
#include "ui/gfx/transform_util.h"
#include "ui/views/widget/widget.h"
-DEFINE_UI_CLASS_PROPERTY_TYPE(exo::Surface*);
+DEFINE_UI_CLASS_PROPERTY_TYPE(exo::Surface*)
namespace exo {
namespace {
// A property key containing the surface that is associated with
// window. If unset, no surface is associated with window.
-DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kSurfaceKey, nullptr);
+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);
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kStylusOnlyKey, false)
// Surface Id set by the client.
-DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kClientSurfaceIdKey, 0);
+DEFINE_UI_CLASS_PROPERTY_KEY(int32_t, kClientSurfaceIdKey, 0)
// Helper function that returns an iterator to the first entry in |list|
// with |key|.
@@ -128,6 +129,15 @@ class CustomWindowDelegate : public aura::WindowDelegate {
return ui::CursorType::kNull;
}
int GetNonClientComponent(const gfx::Point& point) const override {
+ views::Widget* widget =
+ views::Widget::GetTopLevelWidgetForNativeView(surface_->window());
+ if (widget &&
+ widget->GetNativeView()->parent()->id() ==
+ ash::kShellWindowId_DefaultContainer &&
+ surface_->HitTest(point)) {
+ return HTCLIENT;
+ }
+
return HTNOWHERE;
}
bool ShouldDescendIntoChildForEventHandling(
@@ -659,7 +669,7 @@ void Surface::AppendSurfaceHierarchyCallbacks(
void Surface::AppendSurfaceHierarchyContentsToFrame(
const gfx::Point& origin,
float device_scale_factor,
- LayerTreeFrameSinkHolder* frame_sink_holder,
+ FrameSinkResourceManager* resource_manager,
viz::CompositorFrame* frame) {
// The top most sub-surface is at the front of the RenderPass's quad_list,
// so we need composite sub-surface in reversed order.
@@ -669,17 +679,16 @@ void Surface::AppendSurfaceHierarchyContentsToFrame(
// decendents.
sub_surface->AppendSurfaceHierarchyContentsToFrame(
origin + sub_surface_entry.second.OffsetFromOrigin(),
- device_scale_factor, frame_sink_holder, frame);
+ device_scale_factor, resource_manager, frame);
}
if (needs_update_resource_)
- UpdateResource(frame_sink_holder);
+ UpdateResource(resource_manager);
AppendContentsToFrame(origin, device_scale_factor, frame);
- DCHECK(
- !current_resource_.id ||
- frame_sink_holder->HasReleaseCallbackForResource(current_resource_.id));
+ DCHECK(!current_resource_.id ||
+ resource_manager->HasReleaseCallbackForResource(current_resource_.id));
}
bool Surface::IsSynchronized() const {
@@ -818,12 +827,12 @@ void Surface::BufferAttachment::Reset(base::WeakPtr<Buffer> buffer) {
buffer_ = buffer;
}
-void Surface::UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder) {
+void Surface::UpdateResource(FrameSinkResourceManager* resource_manager) {
DCHECK(needs_update_resource_);
needs_update_resource_ = false;
if (current_buffer_.buffer()) {
if (current_buffer_.buffer()->ProduceTransferableResource(
- frame_sink_holder, state_.only_visible_on_secure_output,
+ resource_manager, state_.only_visible_on_secure_output,
&current_resource_)) {
current_resource_has_alpha_ =
FormatHasAlpha(current_buffer_.buffer()->GetFormat());
@@ -933,13 +942,15 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
viz::TextureDrawQuad* texture_quad =
render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0};
-
+ SkColor background_color = SK_ColorTRANSPARENT;
+ if (current_resource_has_alpha_ && are_contents_opaque)
+ background_color = SK_ColorBLACK; // Avoid writing alpha < 1
texture_quad->SetNew(
- quad_state, quad_rect, quad_rect, !are_contents_opaque,
- current_resource_.id, true /* premultiplied_alpha */,
- uv_crop.origin(), uv_crop.bottom_right(),
- SK_ColorTRANSPARENT /* background_color */, vertex_opacity,
- false /* y_flipped */, false /* nearest_neighbor */,
+ quad_state, quad_rect, quad_rect,
+ /* needs_blending=*/!are_contents_opaque, current_resource_.id,
+ /* premultiplied_alpha=*/true, uv_crop.origin(),
+ uv_crop.bottom_right(), background_color, vertex_opacity,
+ /* y_flipped=*/false, /* nearest_neighbor=*/false,
state_.only_visible_on_secure_output, ui::ProtectedVideoType::kClear);
if (current_resource_.is_overlay_candidate)
texture_quad->set_resource_size_in_pixels(current_resource_.size);
diff --git a/chromium/components/exo/surface.h b/chromium/components/exo/surface.h
index 57893f13997..5b780103ef2 100644
--- a/chromium/components/exo/surface.h
+++ b/chromium/components/exo/surface.h
@@ -39,7 +39,7 @@ class CompositorFrame;
namespace exo {
class Buffer;
-class LayerTreeFrameSinkHolder;
+class FrameSinkResourceManager;
class SurfaceObserver;
class Surface;
@@ -176,7 +176,7 @@ class Surface final : public ui::PropertyHandler {
void AppendSurfaceHierarchyContentsToFrame(
const gfx::Point& origin,
float device_scale_factor,
- LayerTreeFrameSinkHolder* frame_sink_holder,
+ FrameSinkResourceManager* resource_manager,
viz::CompositorFrame* frame);
// Returns true if surface is in synchronized mode.
@@ -288,7 +288,7 @@ class Surface final : public ui::PropertyHandler {
// contents of the attached buffer (or id 0, if no buffer is attached).
// UpdateSurface must be called afterwards to ensure the release callback
// will be called.
- void UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder);
+ void UpdateResource(FrameSinkResourceManager* resource_manager);
// Updates buffer_transform_ to match the current buffer parameters.
void UpdateBufferTransform(bool y_invert);
diff --git a/chromium/components/exo/surface_tree_host.cc b/chromium/components/exo/surface_tree_host.cc
index d069220b120..c93602e175f 100644
--- a/chromium/components/exo/surface_tree_host.cc
+++ b/chromium/components/exo/surface_tree_host.cc
@@ -250,7 +250,7 @@ void SurfaceTreeHost::SubmitCompositorFrame() {
host_window()->GetLocalSurfaceIdAllocation().allocation_time();
root_surface_->AppendSurfaceHierarchyContentsToFrame(
root_surface_origin_, device_scale_factor,
- layer_tree_frame_sink_holder_.get(), &frame);
+ layer_tree_frame_sink_holder_->resource_manager(), &frame);
std::vector<GLbyte*> sync_tokens;
for (auto& resource : frame.resource_list)
diff --git a/chromium/components/exo/surface_unittest.cc b/chromium/components/exo/surface_unittest.cc
index 253196a5a79..7e1cecc0699 100644
--- a/chromium/components/exo/surface_unittest.cc
+++ b/chromium/components/exo/surface_unittest.cc
@@ -77,7 +77,7 @@ void ReleaseBuffer(int* release_buffer_call_count) {
// Instantiate the Boolean which is used to toggle mouse and touch events in
// the parameterized tests.
-INSTANTIATE_TEST_CASE_P(, SurfaceTest, testing::Values(1.0f, 1.25f, 2.0f));
+INSTANTIATE_TEST_SUITE_P(, SurfaceTest, testing::Values(1.0f, 1.25f, 2.0f));
TEST_P(SurfaceTest, Attach) {
gfx::Size buffer_size(256, 256);
@@ -221,9 +221,11 @@ TEST_P(SurfaceTest, MAYBE_SetOpaqueRegion) {
GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
- EXPECT_FALSE(frame.render_pass_list.back()
- ->quad_list.back()
- ->ShouldDrawWithBlending());
+ auto* texture_draw_quad = viz::TextureDrawQuad::MaterialCast(
+ frame.render_pass_list.back()->quad_list.back());
+
+ EXPECT_FALSE(texture_draw_quad->ShouldDrawWithBlending());
+ EXPECT_EQ(SK_ColorBLACK, texture_draw_quad->background_color);
EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
frame.render_pass_list.back()->damage_rect);
}
@@ -238,9 +240,10 @@ TEST_P(SurfaceTest, MAYBE_SetOpaqueRegion) {
GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
ASSERT_EQ(1u, frame.render_pass_list.back()->quad_list.size());
- EXPECT_TRUE(frame.render_pass_list.back()
- ->quad_list.back()
- ->ShouldDrawWithBlending());
+ auto* texture_draw_quad = viz::TextureDrawQuad::MaterialCast(
+ frame.render_pass_list.back()->quad_list.back());
+ EXPECT_TRUE(texture_draw_quad->ShouldDrawWithBlending());
+ EXPECT_EQ(SK_ColorTRANSPARENT, texture_draw_quad->background_color);
EXPECT_EQ(ToPixel(gfx::Rect(0, 0, 1, 1)),
frame.render_pass_list.back()->damage_rect);
}
@@ -904,5 +907,30 @@ TEST_P(SurfaceTest, SetClientSurfaceId) {
EXPECT_EQ(kTestId, surface->GetClientSurfaceId());
}
+TEST_P(SurfaceTest, DestroyWithAttachedBufferReleasesBuffer) {
+ gfx::Size buffer_size(1, 1);
+ auto buffer = std::make_unique<Buffer>(
+ exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
+ auto surface = std::make_unique<Surface>();
+ auto shell_surface = std::make_unique<ShellSurface>(surface.get());
+
+ int release_buffer_call_count = 0;
+ buffer->set_release_callback(base::BindRepeating(
+ &ReleaseBuffer, base::Unretained(&release_buffer_call_count)));
+
+ surface->Attach(buffer.get());
+ surface->Commit();
+ base::RunLoop().RunUntilIdle();
+ // Buffer is still attached at this point.
+ EXPECT_EQ(0, release_buffer_call_count);
+
+ // After the surface is destroyed, we should get a release event for the
+ // attached buffer.
+ shell_surface.reset();
+ surface.reset();
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(1, release_buffer_call_count);
+}
+
} // namespace
} // namespace exo
diff --git a/chromium/components/exo/text_input.cc b/chromium/components/exo/text_input.cc
index f2534c4c42b..02fb7dcdc8e 100644
--- a/chromium/components/exo/text_input.cc
+++ b/chromium/components/exo/text_input.cc
@@ -4,6 +4,9 @@
#include "components/exo/text_input.h"
+#include <algorithm>
+
+#include "base/strings/utf_string_conversions.h"
#include "components/exo/surface.h"
#include "components/exo/wm_helper.h"
#include "third_party/icu/source/common/unicode/uchar.h"
@@ -25,6 +28,14 @@ ui::InputMethod* GetInputMethod(aura::Window* window) {
} // namespace
+size_t OffsetFromUTF8Offset(const base::StringPiece& text, uint32_t offset) {
+ return base::UTF8ToUTF16(text.substr(0, offset)).size();
+}
+
+size_t OffsetFromUTF16Offset(const base::StringPiece16& text, uint32_t offset) {
+ return base::UTF16ToUTF8(text.substr(0, offset)).size();
+}
+
TextInput::TextInput(std::unique_ptr<Delegate> delegate)
: delegate_(std::move(delegate)) {}
@@ -69,8 +80,14 @@ void TextInput::Resync() {
}
void TextInput::SetSurroundingText(const base::string16& text,
- uint32_t cursor_pos) {
- NOTIMPLEMENTED();
+ uint32_t cursor_pos,
+ uint32_t anchor) {
+ surrounding_text_ = text;
+ cursor_pos_ = gfx::Range(cursor_pos);
+ if (anchor < cursor_pos)
+ cursor_pos_->set_start(anchor);
+ else
+ cursor_pos_->set_end(anchor);
}
void TextInput::SetTypeModeFlags(ui::TextInputType type,
@@ -163,37 +180,87 @@ ui::TextInputClient::FocusReason TextInput::GetFocusReason() const {
}
bool TextInput::GetTextRange(gfx::Range* range) const {
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ if (!cursor_pos_)
+ return false;
+ range->set_start(0);
+ if (composition_.text.empty()) {
+ range->set_end(surrounding_text_.size());
+ } else {
+ range->set_end(surrounding_text_.size() - cursor_pos_->length() +
+ composition_.text.size());
+ }
+ return true;
}
bool TextInput::GetCompositionTextRange(gfx::Range* range) const {
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ if (!cursor_pos_ || composition_.text.empty())
+ return false;
+
+ range->set_start(cursor_pos_->start());
+ range->set_end(cursor_pos_->start() + composition_.text.size());
+ return true;
}
bool TextInput::GetEditableSelectionRange(gfx::Range* range) const {
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ if (!cursor_pos_)
+ return false;
+ range->set_start(cursor_pos_->start());
+ range->set_end(cursor_pos_->end());
+ return true;
}
bool TextInput::SetEditableSelectionRange(const gfx::Range& range) {
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ if (surrounding_text_.size() < range.GetMax())
+ return false;
+ delegate_->SetCursor(
+ gfx::Range(OffsetFromUTF16Offset(surrounding_text_, range.start()),
+ OffsetFromUTF16Offset(surrounding_text_, range.end())));
+ return true;
}
bool TextInput::DeleteRange(const gfx::Range& range) {
- // TODO(mukai): call delegate_->DeleteSurroundingText(range) once it's
- // supported.
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ if (surrounding_text_.size() < range.GetMax())
+ return false;
+ delegate_->DeleteSurroundingText(
+ gfx::Range(OffsetFromUTF16Offset(surrounding_text_, range.start()),
+ OffsetFromUTF16Offset(surrounding_text_, range.end())));
+ return true;
}
bool TextInput::GetTextFromRange(const gfx::Range& range,
base::string16* text) const {
- // TODO(mukai): support of surrounding text.
- NOTIMPLEMENTED_LOG_ONCE();
- return false;
+ gfx::Range text_range;
+ if (!GetTextRange(&text_range) || !text_range.Contains(range))
+ return false;
+ if (composition_.text.empty() || range.GetMax() <= cursor_pos_->GetMin()) {
+ text->assign(surrounding_text_, range.GetMin(), range.length());
+ return true;
+ }
+ size_t composition_end = cursor_pos_->GetMin() + composition_.text.size();
+ if (range.GetMin() >= composition_end) {
+ size_t start =
+ range.GetMin() - composition_.text.size() + cursor_pos_->length();
+ text->assign(surrounding_text_, start, range.length());
+ return true;
+ }
+
+ size_t start_in_composition = 0;
+ if (range.GetMin() <= cursor_pos_->GetMin()) {
+ text->assign(surrounding_text_, range.GetMin(),
+ cursor_pos_->GetMin() - range.GetMin());
+ } else {
+ start_in_composition = range.GetMin() - cursor_pos_->GetMin();
+ }
+ if (range.GetMax() <= composition_end) {
+ text->append(composition_.text, start_in_composition,
+ range.GetMax() - cursor_pos_->GetMin() - start_in_composition);
+ } else {
+ text->append(composition_.text, start_in_composition,
+ composition_.text.size() - start_in_composition);
+ text->append(surrounding_text_, cursor_pos_->GetMax(),
+ range.GetMax() - composition_end);
+ }
+ return true;
}
void TextInput::OnInputMethodChanged() {
@@ -214,7 +281,17 @@ bool TextInput::ChangeTextDirectionAndLayoutAlignment(
return true;
}
-void TextInput::ExtendSelectionAndDelete(size_t before, size_t after) {}
+void TextInput::ExtendSelectionAndDelete(size_t before, size_t after) {
+ if (!cursor_pos_)
+ return;
+ uint32_t start =
+ (cursor_pos_->GetMin() < before) ? 0 : (cursor_pos_->GetMin() - before);
+ uint32_t end =
+ std::min(cursor_pos_->GetMax() + after, surrounding_text_.size());
+ delegate_->DeleteSurroundingText(
+ gfx::Range(OffsetFromUTF16Offset(surrounding_text_, start),
+ OffsetFromUTF16Offset(surrounding_text_, end)));
+}
void TextInput::EnsureCaretNotInRect(const gfx::Rect& rect) {}
diff --git a/chromium/components/exo/text_input.h b/chromium/components/exo/text_input.h
index 4a47440954d..b00873a047a 100644
--- a/chromium/components/exo/text_input.h
+++ b/chromium/components/exo/text_input.h
@@ -23,6 +23,9 @@ class KeyboardController;
namespace exo {
class Surface;
+size_t OffsetFromUTF8Offset(const base::StringPiece& text, uint32_t offset);
+size_t OffsetFromUTF16Offset(const base::StringPiece16& text, uint32_t offset);
+
// This class bridges the ChromeOS input method and a text-input context.
class TextInput : public ui::TextInputClient,
public keyboard::KeyboardControllerObserver {
@@ -47,10 +50,11 @@ class TextInput : public ui::TextInputClient,
// Commit |text| to the current text input session.
virtual void Commit(const base::string16& text) = 0;
- // Set the cursor position.
+ // Set the cursor position. The range should be in bytes offset.
virtual void SetCursor(const gfx::Range& selection) = 0;
- // Delete the surrounding text of the current text input.
+ // Delete the surrounding text of the current text input. The range should
+ // be in the bytes offset.
virtual void DeleteSurroundingText(const gfx::Range& range) = 0;
// Sends a key event.
@@ -83,7 +87,9 @@ class TextInput : public ui::TextInputClient,
void Resync();
// Sets the surrounding text in the app.
- void SetSurroundingText(const base::string16& text, uint32_t cursor_pos);
+ void SetSurroundingText(const base::string16& text,
+ uint32_t cursor_pos,
+ uint32_t anchor);
// Sets the text input type, mode, flags, and |should_do_learning|.
void SetTypeModeFlags(ui::TextInputType type,
@@ -148,6 +154,8 @@ class TextInput : public ui::TextInputClient,
int flags_ = ui::TEXT_INPUT_FLAG_NONE;
bool should_do_learning_ = true;
ui::CompositionText composition_;
+ base::string16 surrounding_text_;
+ base::Optional<gfx::Range> cursor_pos_;
base::i18n::TextDirection direction_ = base::i18n::UNKNOWN_DIRECTION;
DISALLOW_COPY_AND_ASSIGN(TextInput);
diff --git a/chromium/components/exo/text_input_unittest.cc b/chromium/components/exo/text_input_unittest.cc
index 2aa5e1a626a..3dc0ed5b5e5 100644
--- a/chromium/components/exo/text_input_unittest.cc
+++ b/chromium/components/exo/text_input_unittest.cc
@@ -4,6 +4,8 @@
#include "components/exo/text_input.h"
+#include <string>
+
#include "base/strings/utf_string_conversions.h"
#include "components/exo/buffer.h"
#include "components/exo/shell_surface.h"
@@ -117,6 +119,16 @@ class TextInputTest : public test::ExoTestBase {
return surface_->window()->GetHost()->GetInputMethod();
}
+ void SetCompositionText(const std::string& utf8) {
+ ui::CompositionText t;
+ t.text = base::UTF8ToUTF16(utf8);
+ t.selection = gfx::Range(1u);
+ t.ime_text_spans.push_back(
+ ui::ImeTextSpan(0, t.text.size(), ui::ImeTextSpan::Thickness::kThick));
+ EXPECT_CALL(*delegate(), SetCompositionText(t)).Times(1);
+ text_input()->SetCompositionText(t);
+ }
+
private:
std::unique_ptr<TextInput> text_input_;
@@ -224,31 +236,17 @@ TEST_F(TextInputTest, CaretBounds) {
}
TEST_F(TextInputTest, CompositionText) {
- ui::CompositionText t;
- t.text = base::ASCIIToUTF16("composition");
- t.selection = gfx::Range(1u);
- t.ime_text_spans.push_back(
- ui::ImeTextSpan(0, t.text.size(), ui::ImeTextSpan::Thickness::kThick));
+ SetCompositionText("composition");
ui::CompositionText empty;
- EXPECT_CALL(*delegate(), SetCompositionText(t)).Times(1);
EXPECT_CALL(*delegate(), SetCompositionText(empty)).Times(1);
-
- text_input()->SetCompositionText(t);
text_input()->ClearCompositionText();
}
TEST_F(TextInputTest, CommitCompositionText) {
- ui::CompositionText t;
- t.text = base::ASCIIToUTF16("composition");
- t.selection = gfx::Range(1u);
- t.ime_text_spans.push_back(
- ui::ImeTextSpan(0, t.text.size(), ui::ImeTextSpan::Thickness::kThick));
-
- EXPECT_CALL(*delegate(), SetCompositionText(t)).Times(1);
- EXPECT_CALL(*delegate(), Commit(t.text)).Times(1);
+ SetCompositionText("composition");
- text_input()->SetCompositionText(t);
+ EXPECT_CALL(*delegate(), Commit(base::UTF8ToUTF16("composition"))).Times(1);
text_input()->ConfirmCompositionText();
}
@@ -275,5 +273,66 @@ TEST_F(TextInputTest, InsertCharNormalKey) {
text_input()->InsertChar(ev);
}
+TEST_F(TextInputTest, SurroundingText) {
+ gfx::Range range;
+ EXPECT_FALSE(text_input()->GetTextRange(&range));
+ EXPECT_FALSE(text_input()->GetCompositionTextRange(&range));
+ EXPECT_FALSE(text_input()->GetEditableSelectionRange(&range));
+ base::string16 got_text;
+ EXPECT_FALSE(text_input()->GetTextFromRange(gfx::Range(0, 1), &got_text));
+
+ base::string16 text = base::UTF8ToUTF16("surrounding\xE3\x80\x80text");
+ text_input()->SetSurroundingText(text, 11, 12);
+
+ EXPECT_TRUE(text_input()->GetTextRange(&range));
+ EXPECT_EQ(gfx::Range(0, text.size()).ToString(), range.ToString());
+
+ EXPECT_FALSE(text_input()->GetCompositionTextRange(&range));
+ EXPECT_TRUE(text_input()->GetEditableSelectionRange(&range));
+ EXPECT_EQ(gfx::Range(11, 12).ToString(), range.ToString());
+ EXPECT_TRUE(text_input()->GetTextFromRange(gfx::Range(11, 12), &got_text));
+ EXPECT_EQ(text.substr(11, 1), got_text);
+
+ // DeleteSurroundingText receives the range in UTF8 -- so (11, 14) range is
+ // expected.
+ EXPECT_CALL(*delegate(), DeleteSurroundingText(gfx::Range(11, 14))).Times(1);
+ text_input()->ExtendSelectionAndDelete(0, 0);
+
+ size_t composition_size = std::string("composition").size();
+ SetCompositionText("composition");
+ EXPECT_TRUE(text_input()->GetCompositionTextRange(&range));
+ EXPECT_EQ(gfx::Range(11, 11 + composition_size).ToString(), range.ToString());
+ EXPECT_TRUE(text_input()->GetTextRange(&range));
+ EXPECT_EQ(gfx::Range(0, text.size() - 1 + composition_size).ToString(),
+ range.ToString());
+ EXPECT_TRUE(text_input()->GetEditableSelectionRange(&range));
+ EXPECT_EQ(gfx::Range(11, 12).ToString(), range.ToString());
+}
+
+TEST_F(TextInputTest, GetTextRange) {
+ base::string16 text = base::UTF8ToUTF16("surrounding text");
+ text_input()->SetSurroundingText(text, 11, 12);
+
+ SetCompositionText("composition");
+
+ const struct {
+ gfx::Range range;
+ std::string expected;
+ } kTestCases[] = {
+ {gfx::Range(0, 3), "sur"},
+ {gfx::Range(10, 13), "gco"},
+ {gfx::Range(10, 23), "gcompositiont"},
+ {gfx::Range(12, 15), "omp"},
+ {gfx::Range(12, 23), "ompositiont"},
+ {gfx::Range(22, 25), "tex"},
+ };
+ for (auto& c : kTestCases) {
+ base::string16 result;
+ EXPECT_TRUE(text_input()->GetTextFromRange(c.range, &result))
+ << c.range.ToString();
+ EXPECT_EQ(base::UTF8ToUTF16(c.expected), result) << c.range.ToString();
+ }
+}
+
} // anonymous namespace
} // namespace exo
diff --git a/chromium/components/exo/wayland/BUILD.gn b/chromium/components/exo/wayland/BUILD.gn
index c8e1c2b7650..50b6275ddaf 100644
--- a/chromium/components/exo/wayland/BUILD.gn
+++ b/chromium/components/exo/wayland/BUILD.gn
@@ -47,6 +47,8 @@ source_set("wayland") {
"wayland_watcher.h",
"wl_compositor.cc",
"wl_compositor.h",
+ "wl_data_device_manager.cc",
+ "wl_data_device_manager.h",
"wl_output.cc",
"wl_output.h",
"wl_seat.cc",
@@ -55,6 +57,16 @@ source_set("wayland") {
"wl_shm.h",
"wl_subcompositor.cc",
"wl_subcompositor.h",
+ "wp_presentation.cc",
+ "wp_presentation.h",
+ "wp_viewporter.cc",
+ "wp_viewporter.h",
+ "zcr_alpha_compositing.cc",
+ "zcr_alpha_compositing.h",
+ "zcr_secure_output.cc",
+ "zcr_secure_output.h",
+ "zcr_stylus.cc",
+ "zcr_stylus.h",
"zcr_vsync_feedback.cc",
"zcr_vsync_feedback.h",
]
@@ -91,6 +103,8 @@ source_set("wayland") {
"zwp_linux_explicit_synchronization.h",
"zwp_pointer_gestures.cc",
"zwp_pointer_gestures.h",
+ "zwp_relative_pointer_manager.cc",
+ "zwp_relative_pointer_manager.h",
"zwp_text_input_manager.cc",
"zwp_text_input_manager.h",
"zxdg_shell.cc",
@@ -116,6 +130,7 @@ source_set("wayland") {
"//third_party/wayland-protocols:notification_shell_protocol",
"//third_party/wayland-protocols:pointer_gestures_protocol",
"//third_party/wayland-protocols:presentation_time_protocol",
+ "//third_party/wayland-protocols:relative_pointer_protocol",
"//third_party/wayland-protocols:remote_shell_protocol",
"//third_party/wayland-protocols:secure_output_protocol",
"//third_party/wayland-protocols:stylus_protocol",
diff --git a/chromium/components/exo/wayland/clients/client_helper.cc b/chromium/components/exo/wayland/clients/client_helper.cc
index 29531c72383..2b8e00e01a2 100644
--- a/chromium/components/exo/wayland/clients/client_helper.cc
+++ b/chromium/components/exo/wayland/clients/client_helper.cc
@@ -54,7 +54,7 @@ DEFAULT_DELETER(zwp_linux_buffer_release_v1,
zwp_linux_buffer_release_v1_destroy)
DEFAULT_DELETER(zwp_fullscreen_shell_v1, zwp_fullscreen_shell_v1_destroy)
DEFAULT_DELETER(zwp_input_timestamps_manager_v1,
- zwp_input_timestamps_manager_v1_destroy);
+ zwp_input_timestamps_manager_v1_destroy)
DEFAULT_DELETER(zwp_input_timestamps_v1, zwp_input_timestamps_v1_destroy)
DEFAULT_DELETER(zwp_linux_buffer_params_v1, zwp_linux_buffer_params_v1_destroy)
DEFAULT_DELETER(zwp_linux_dmabuf_v1, zwp_linux_dmabuf_v1_destroy)
diff --git a/chromium/components/exo/wayland/clients/perftests.cc b/chromium/components/exo/wayland/clients/perftests.cc
index 83ceab6ee01..52acea731ad 100644
--- a/chromium/components/exo/wayland/clients/perftests.cc
+++ b/chromium/components/exo/wayland/clients/perftests.cc
@@ -56,9 +56,9 @@ class WaylandClientBlurPerfTests
DISALLOW_COPY_AND_ASSIGN(WaylandClientBlurPerfTests);
};
-INSTANTIATE_TEST_CASE_P(,
- WaylandClientBlurPerfTests,
- testing::Values(4.0, 15.0));
+INSTANTIATE_TEST_SUITE_P(,
+ WaylandClientBlurPerfTests,
+ testing::Values(4.0, 15.0));
TEST_P(WaylandClientBlurPerfTests, BlurSigma) {
const int kWarmUpFrames = 20;
diff --git a/chromium/components/exo/wayland/clients/rects.cc b/chromium/components/exo/wayland/clients/rects.cc
index cec288626fc..863b9ba59b9 100644
--- a/chromium/components/exo/wayland/clients/rects.cc
+++ b/chromium/components/exo/wayland/clients/rects.cc
@@ -365,7 +365,7 @@ int RectsClient::Run(const ClientBase::InitParams& params,
}
// Set FPS counter text in case it's being shown.
- fps_counter_text = base::UintToString(
+ fps_counter_text = base::NumberToString(
std::round(benchmark_frames / benchmark_interval.InSecondsF()));
benchmark_start_time = wall_time_start;
diff --git a/chromium/components/exo/wayland/server.cc b/chromium/components/exo/wayland/server.cc
index 3948c6fb350..00be35b1440 100644
--- a/chromium/components/exo/wayland/server.cc
+++ b/chromium/components/exo/wayland/server.cc
@@ -14,14 +14,12 @@
#include <keyboard-configuration-unstable-v1-server-protocol.h>
#include <keyboard-extension-unstable-v1-server-protocol.h>
#include <linux-explicit-synchronization-unstable-v1-server-protocol.h>
-#include <linux/input.h>
#include <notification-shell-unstable-v1-server-protocol.h>
#include <pointer-gestures-unstable-v1-server-protocol.h>
#include <presentation-time-server-protocol.h>
+#include <relative-pointer-unstable-v1-server-protocol.h>
#include <remote-shell-unstable-v1-server-protocol.h>
#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-v2-server-protocol.h>
#include <text-input-unstable-v1-server-protocol.h>
@@ -31,78 +29,30 @@
#include <wayland-server-protocol-core.h>
#include <xdg-shell-unstable-v6-server-protocol.h>
-#include <algorithm>
-#include <cstdlib>
-#include <iterator>
-#include <map>
#include <memory>
#include <string>
#include <utility>
-#include <vector>
-#include "base/atomic_sequence_num.h"
-#include "base/bind.h"
-#include "base/cancelable_callback.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/memory/free_deleter.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/exo/buffer.h"
-#include "components/exo/data_device.h"
-#include "components/exo/data_device_delegate.h"
-#include "components/exo/data_offer.h"
-#include "components/exo/data_offer_delegate.h"
-#include "components/exo/data_source.h"
-#include "components/exo/data_source_delegate.h"
#include "components/exo/display.h"
-#include "components/exo/gamepad_delegate.h"
-#include "components/exo/gaming_seat.h"
-#include "components/exo/gaming_seat_delegate.h"
-#include "components/exo/notification.h"
-#include "components/exo/surface.h"
-#include "components/exo/touch.h"
-#include "components/exo/touch_delegate.h"
-#include "components/exo/touch_stylus_delegate.h"
-#include "components/exo/wayland/server_util.h"
#include "components/exo/wayland/wayland_display_output.h"
-#include "components/exo/wayland/wayland_input_delegate.h"
-#include "components/exo/wayland/wayland_touch_delegate.h"
#include "components/exo/wayland/wl_compositor.h"
+#include "components/exo/wayland/wl_data_device_manager.h"
#include "components/exo/wayland/wl_output.h"
#include "components/exo/wayland/wl_seat.h"
#include "components/exo/wayland/wl_shm.h"
#include "components/exo/wayland/wl_subcompositor.h"
+#include "components/exo/wayland/wp_presentation.h"
+#include "components/exo/wayland/wp_viewporter.h"
+#include "components/exo/wayland/zcr_alpha_compositing.h"
+#include "components/exo/wayland/zcr_secure_output.h"
+#include "components/exo/wayland/zcr_stylus.h"
#include "components/exo/wayland/zcr_vsync_feedback.h"
-#include "components/exo/wm_helper.h"
-#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/base/buildflags.h"
-#include "ui/base/class_property.h"
-#include "ui/base/hit_test.h"
-#include "ui/compositor/compositor_vsync_manager.h"
-#include "ui/display/display_switches.h"
-#include "ui/display/manager/display_util.h"
-#include "ui/display/manager/managed_display_info.h"
+#include "ui/display/display.h"
#include "ui/display/screen.h"
-#include "ui/events/keycodes/dom/keycode_converter.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gfx/presentation_feedback.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-#include "ui/wm/core/coordinate_conversion.h"
-#include "ui/wm/core/window_animations.h"
-#include "ui/wm/public/activation_change_observer.h"
#if defined(OS_CHROMEOS)
-#include "components/exo/wayland/wayland_keyboard_delegate.h"
-#include "components/exo/wayland/wayland_pointer_delegate.h"
#include "components/exo/wayland/wl_shell.h"
#include "components/exo/wayland/zaura_shell.h"
#include "components/exo/wayland/zcr_cursor_shapes.h"
@@ -115,18 +65,14 @@
#include "components/exo/wayland/zwp_input_timestamps_manager.h"
#include "components/exo/wayland/zwp_linux_explicit_synchronization.h"
#include "components/exo/wayland/zwp_pointer_gestures.h"
+#include "components/exo/wayland/zwp_relative_pointer_manager.h"
#include "components/exo/wayland/zwp_text_input_manager.h"
#include "components/exo/wayland/zxdg_shell.h"
-#include "components/exo/wm_helper_chromeos.h"
#endif
#if defined(USE_OZONE)
#include <linux-dmabuf-unstable-v1-server-protocol.h>
-
#include "components/exo/wayland/zwp_linux_dmabuf.h"
-#if defined(OS_CHROMEOS)
-#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
-#endif
#endif
#if defined(USE_FULLSCREEN_SHELL)
@@ -134,13 +80,6 @@
#include "components/exo/wayland/zwp_fullscreen_shell.h"
#endif
-#if BUILDFLAG(USE_XKBCOMMON)
-#include <xkbcommon/xkbcommon.h>
-#include "ui/events/keycodes/scoped_xkb.h" // nogncheck
-#endif
-
-DEFINE_UI_CLASS_PROPERTY_TYPE(wl_resource*);
-
namespace exo {
namespace wayland {
namespace switches {
@@ -159,857 +98,6 @@ const base::FilePath::CharType kSocketName[] = FILE_PATH_LITERAL("wayland-0");
// Group used for wayland socket.
const char kWaylandSocketGroup[] = "wayland";
-uint32_t WaylandDataDeviceManagerDndAction(DndAction action) {
- switch (action) {
- case DndAction::kNone:
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
- case DndAction::kCopy:
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
- case DndAction::kMove:
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
- case DndAction::kAsk:
- return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
- }
- NOTREACHED();
-}
-
-uint32_t WaylandDataDeviceManagerDndActions(
- const base::flat_set<DndAction>& dnd_actions) {
- uint32_t actions = 0;
- for (DndAction action : dnd_actions)
- actions |= WaylandDataDeviceManagerDndAction(action);
- return actions;
-}
-
-DndAction DataDeviceManagerDndAction(uint32_t value) {
- switch (value) {
- case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
- return DndAction::kNone;
- case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
- return DndAction::kCopy;
- case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
- return DndAction::kMove;
- case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
- return DndAction::kAsk;
- default:
- NOTREACHED();
- return DndAction::kNone;
- }
-}
-
-base::flat_set<DndAction> DataDeviceManagerDndActions(uint32_t value) {
- base::flat_set<DndAction> actions;
- if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
- actions.insert(DndAction::kCopy);
- if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
- actions.insert(DndAction::kMove);
- if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
- actions.insert(DndAction::kAsk);
- return actions;
-}
-
-// A property key containing a boolean set to true if a viewport is associated
-// with with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasViewportKey, false);
-
-// A property key containing a boolean set to true if a security object is
-// associated with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasSecurityKey, false);
-
-// A property key containing a boolean set to true if a blending object is
-// associated with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasBlendingKey, false);
-
-////////////////////////////////////////////////////////////////////////////////
-// wl_data_source_interface:
-
-class WaylandDataSourceDelegate : public DataSourceDelegate {
- public:
- explicit WaylandDataSourceDelegate(wl_resource* source)
- : data_source_resource_(source) {}
-
- // Overridden from DataSourceDelegate:
- void OnDataSourceDestroying(DataSource* device) override { delete this; }
- void OnTarget(const std::string& mime_type) override {
- wl_data_source_send_target(data_source_resource_, mime_type.c_str());
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- void OnSend(const std::string& mime_type, base::ScopedFD fd) override {
- wl_data_source_send_send(data_source_resource_, mime_type.c_str(),
- fd.get());
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- void OnCancelled() override {
- wl_data_source_send_cancelled(data_source_resource_);
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- void OnDndDropPerformed() override {
- if (wl_resource_get_version(data_source_resource_) >=
- WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) {
- wl_data_source_send_dnd_drop_performed(data_source_resource_);
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- }
- void OnDndFinished() override {
- if (wl_resource_get_version(data_source_resource_) >=
- WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) {
- wl_data_source_send_dnd_finished(data_source_resource_);
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- }
- void OnAction(DndAction dnd_action) override {
- if (wl_resource_get_version(data_source_resource_) >=
- WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
- wl_data_source_send_action(data_source_resource_,
- WaylandDataDeviceManagerDndAction(dnd_action));
- wl_client_flush(wl_resource_get_client(data_source_resource_));
- }
- }
-
- private:
- wl_resource* const data_source_resource_;
-
- DISALLOW_COPY_AND_ASSIGN(WaylandDataSourceDelegate);
-};
-
-void data_source_offer(wl_client* client,
- wl_resource* resource,
- const char* mime_type) {
- GetUserDataAs<DataSource>(resource)->Offer(mime_type);
-}
-
-void data_source_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void data_source_set_actions(wl_client* client,
- wl_resource* resource,
- uint32_t dnd_actions) {
- GetUserDataAs<DataSource>(resource)->SetActions(
- DataDeviceManagerDndActions(dnd_actions));
-}
-
-const struct wl_data_source_interface data_source_implementation = {
- data_source_offer, data_source_destroy, data_source_set_actions};
-
-////////////////////////////////////////////////////////////////////////////////
-// wl_data_offer_interface:
-
-class WaylandDataOfferDelegate : public DataOfferDelegate {
- public:
- explicit WaylandDataOfferDelegate(wl_resource* offer)
- : data_offer_resource_(offer) {}
-
- // Overridden from DataOfferDelegate:
- void OnDataOfferDestroying(DataOffer* device) override { delete this; }
- void OnOffer(const std::string& mime_type) override {
- wl_data_offer_send_offer(data_offer_resource_, mime_type.c_str());
- wl_client_flush(wl_resource_get_client(data_offer_resource_));
- }
- void OnSourceActions(
- const base::flat_set<DndAction>& source_actions) override {
- if (wl_resource_get_version(data_offer_resource_) >=
- WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) {
- wl_data_offer_send_source_actions(
- data_offer_resource_,
- WaylandDataDeviceManagerDndActions(source_actions));
- wl_client_flush(wl_resource_get_client(data_offer_resource_));
- }
- }
- void OnAction(DndAction action) override {
- if (wl_resource_get_version(data_offer_resource_) >=
- WL_DATA_OFFER_ACTION_SINCE_VERSION) {
- wl_data_offer_send_action(data_offer_resource_,
- WaylandDataDeviceManagerDndAction(action));
- wl_client_flush(wl_resource_get_client(data_offer_resource_));
- }
- }
-
- private:
- wl_resource* const data_offer_resource_;
-
- DISALLOW_COPY_AND_ASSIGN(WaylandDataOfferDelegate);
-};
-
-void data_offer_accept(wl_client* client,
- wl_resource* resource,
- uint32_t serial,
- const char* mime_type) {
- GetUserDataAs<DataOffer>(resource)->Accept(mime_type);
-}
-
-void data_offer_receive(wl_client* client,
- wl_resource* resource,
- const char* mime_type,
- int fd) {
- GetUserDataAs<DataOffer>(resource)->Receive(mime_type, base::ScopedFD(fd));
-}
-
-void data_offer_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void data_offer_finish(wl_client* client, wl_resource* resource) {
- GetUserDataAs<DataOffer>(resource)->Finish();
-}
-
-void data_offer_set_actions(wl_client* client,
- wl_resource* resource,
- uint32_t dnd_actions,
- uint32_t preferred_action) {
- GetUserDataAs<DataOffer>(resource)->SetActions(
- DataDeviceManagerDndActions(dnd_actions),
- DataDeviceManagerDndAction(preferred_action));
-}
-
-const struct wl_data_offer_interface data_offer_implementation = {
- data_offer_accept, data_offer_receive, data_offer_finish,
- data_offer_destroy, data_offer_set_actions};
-
-////////////////////////////////////////////////////////////////////////////////
-// wl_data_device_interface:
-
-class WaylandDataDeviceDelegate : public DataDeviceDelegate {
- public:
- WaylandDataDeviceDelegate(wl_client* client, wl_resource* device_resource)
- : client_(client), data_device_resource_(device_resource) {}
-
- // Overridden from DataDeviceDelegate:
- void OnDataDeviceDestroying(DataDevice* device) override { delete this; }
- bool CanAcceptDataEventsForSurface(Surface* surface) override {
- return surface &&
- wl_resource_get_client(GetSurfaceResource(surface)) == client_;
- }
- DataOffer* OnDataOffer() override {
- wl_resource* data_offer_resource =
- wl_resource_create(client_, &wl_data_offer_interface,
- wl_resource_get_version(data_device_resource_), 0);
- std::unique_ptr<DataOffer> data_offer = std::make_unique<DataOffer>(
- new WaylandDataOfferDelegate(data_offer_resource));
- SetDataOfferResource(data_offer.get(), data_offer_resource);
- SetImplementation(data_offer_resource, &data_offer_implementation,
- std::move(data_offer));
-
- wl_data_device_send_data_offer(data_device_resource_, data_offer_resource);
- wl_client_flush(client_);
-
- return GetUserDataAs<DataOffer>(data_offer_resource);
- }
- void OnEnter(Surface* surface,
- const gfx::PointF& point,
- const DataOffer& data_offer) override {
- wl_data_device_send_enter(
- data_device_resource_,
- wl_display_next_serial(wl_client_get_display(client_)),
- GetSurfaceResource(surface), wl_fixed_from_double(point.x()),
- wl_fixed_from_double(point.y()), GetDataOfferResource(&data_offer));
- wl_client_flush(client_);
- }
- void OnLeave() override {
- wl_data_device_send_leave(data_device_resource_);
- wl_client_flush(client_);
- }
- void OnMotion(base::TimeTicks time_stamp, const gfx::PointF& point) override {
- wl_data_device_send_motion(
- data_device_resource_, TimeTicksToMilliseconds(time_stamp),
- wl_fixed_from_double(point.x()), wl_fixed_from_double(point.y()));
- wl_client_flush(client_);
- }
- void OnDrop() override {
- wl_data_device_send_drop(data_device_resource_);
- wl_client_flush(client_);
- }
- void OnSelection(const DataOffer& data_offer) override {
- wl_data_device_send_selection(data_device_resource_,
- GetDataOfferResource(&data_offer));
- wl_client_flush(client_);
- }
-
- private:
- wl_client* const client_;
- wl_resource* const data_device_resource_;
-
- DISALLOW_COPY_AND_ASSIGN(WaylandDataDeviceDelegate);
-};
-
-void data_device_start_drag(wl_client* client,
- wl_resource* resource,
- wl_resource* source_resource,
- wl_resource* origin_resource,
- wl_resource* icon_resource,
- uint32_t serial) {
- GetUserDataAs<DataDevice>(resource)->StartDrag(
- source_resource ? GetUserDataAs<DataSource>(source_resource) : nullptr,
- GetUserDataAs<Surface>(origin_resource),
- icon_resource ? GetUserDataAs<Surface>(icon_resource) : nullptr, serial);
-}
-
-void data_device_set_selection(wl_client* client,
- wl_resource* resource,
- wl_resource* data_source,
- uint32_t serial) {
- GetUserDataAs<DataDevice>(resource)->SetSelection(
- data_source ? GetUserDataAs<DataSource>(data_source) : nullptr, serial);
-}
-
-void data_device_release(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-const struct wl_data_device_interface data_device_implementation = {
- data_device_start_drag, data_device_set_selection, data_device_release};
-
-////////////////////////////////////////////////////////////////////////////////
-// wl_data_device_manager_interface:
-
-void data_device_manager_create_data_source(wl_client* client,
- wl_resource* resource,
- uint32_t id) {
- wl_resource* data_source_resource = wl_resource_create(
- client, &wl_data_source_interface, wl_resource_get_version(resource), id);
- SetImplementation(data_source_resource, &data_source_implementation,
- std::make_unique<DataSource>(
- new WaylandDataSourceDelegate(data_source_resource)));
-}
-
-void data_device_manager_get_data_device(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* seat_resource) {
- Display* display = GetUserDataAs<Display>(resource);
- wl_resource* data_device_resource = wl_resource_create(
- client, &wl_data_device_interface, wl_resource_get_version(resource), id);
- SetImplementation(data_device_resource, &data_device_implementation,
- display->CreateDataDevice(new WaylandDataDeviceDelegate(
- client, data_device_resource)));
-}
-
-const struct wl_data_device_manager_interface
- data_device_manager_implementation = {
- data_device_manager_create_data_source,
- data_device_manager_get_data_device};
-
-const uint32_t data_device_manager_version = 3;
-
-void bind_data_device_manager(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &wl_data_device_manager_interface,
- std::min(version, data_device_manager_version), id);
- wl_resource_set_implementation(resource, &data_device_manager_implementation,
- data, nullptr);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// wp_viewport_interface:
-
-// Implements the viewport interface to a Surface. The "viewport"-state is set
-// to null upon destruction. A window property will be set during the lifetime
-// of this class to prevent multiple instances from being created for the same
-// Surface.
-class Viewport : public SurfaceObserver {
- public:
- explicit Viewport(Surface* surface) : surface_(surface) {
- surface_->AddSurfaceObserver(this);
- surface_->SetProperty(kSurfaceHasViewportKey, true);
- }
- ~Viewport() override {
- if (surface_) {
- surface_->RemoveSurfaceObserver(this);
- surface_->SetCrop(gfx::RectF());
- surface_->SetViewport(gfx::Size());
- surface_->SetProperty(kSurfaceHasViewportKey, false);
- }
- }
-
- void SetSource(const gfx::RectF& rect) {
- if (surface_)
- surface_->SetCrop(rect);
- }
-
- void SetDestination(const gfx::Size& size) {
- if (surface_)
- surface_->SetViewport(size);
- }
-
- // Overridden from SurfaceObserver:
- void OnSurfaceDestroying(Surface* surface) override {
- surface->RemoveSurfaceObserver(this);
- surface_ = nullptr;
- }
-
- private:
- Surface* surface_;
-
- DISALLOW_COPY_AND_ASSIGN(Viewport);
-};
-
-void viewport_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void viewport_set_source(wl_client* client,
- wl_resource* resource,
- wl_fixed_t x,
- wl_fixed_t y,
- wl_fixed_t width,
- wl_fixed_t height) {
- if (x == wl_fixed_from_int(-1) && y == wl_fixed_from_int(-1) &&
- width == wl_fixed_from_int(-1) && height == wl_fixed_from_int(-1)) {
- GetUserDataAs<Viewport>(resource)->SetSource(gfx::RectF());
- return;
- }
-
- if (x < 0 || y < 0 || width <= 0 || height <= 0) {
- wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
- "source rectangle must be non-empty (%dx%d) and"
- "have positive origin (%d,%d)",
- width, height, x, y);
- return;
- }
-
- GetUserDataAs<Viewport>(resource)->SetSource(
- gfx::RectF(wl_fixed_to_double(x), wl_fixed_to_double(y),
- wl_fixed_to_double(width), wl_fixed_to_double(height)));
-}
-
-void viewport_set_destination(wl_client* client,
- wl_resource* resource,
- int32_t width,
- int32_t height) {
- if (width == -1 && height == -1) {
- GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size());
- return;
- }
-
- if (width <= 0 || height <= 0) {
- wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
- "destination size must be positive (%dx%d)", width,
- height);
- return;
- }
-
- GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size(width, height));
-}
-
-const struct wp_viewport_interface viewport_implementation = {
- viewport_destroy, viewport_set_source, viewport_set_destination};
-
-////////////////////////////////////////////////////////////////////////////////
-// wp_viewporter_interface:
-
-void viewporter_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void viewporter_get_viewport(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* surface_resource) {
- Surface* surface = GetUserDataAs<Surface>(surface_resource);
- if (surface->GetProperty(kSurfaceHasViewportKey)) {
- wl_resource_post_error(resource, WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
- "a viewport for that surface already exists");
- return;
- }
-
- wl_resource* viewport_resource = wl_resource_create(
- client, &wp_viewport_interface, wl_resource_get_version(resource), id);
-
- SetImplementation(viewport_resource, &viewport_implementation,
- std::make_unique<Viewport>(surface));
-}
-
-const struct wp_viewporter_interface viewporter_implementation = {
- viewporter_destroy, viewporter_get_viewport};
-
-void bind_viewporter(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &wp_viewporter_interface, 1, id);
-
- wl_resource_set_implementation(resource, &viewporter_implementation, data,
- nullptr);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// presentation_interface:
-
-void HandleSurfacePresentationCallback(
- wl_resource* resource,
- const gfx::PresentationFeedback& feedback) {
- if (feedback.timestamp.is_null()) {
- wp_presentation_feedback_send_discarded(resource);
- } else {
- int64_t presentation_time_us = feedback.timestamp.ToInternalValue();
- int64_t seconds = presentation_time_us / base::Time::kMicrosecondsPerSecond;
- int64_t microseconds =
- presentation_time_us % base::Time::kMicrosecondsPerSecond;
- static_assert(
- static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kVSync) ==
- static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_VSYNC),
- "gfx::PresentationFlags::VSync don't match!");
- static_assert(
- static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kHWClock) ==
- static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK),
- "gfx::PresentationFlags::HWClock don't match!");
- static_assert(
- static_cast<uint32_t>(
- gfx::PresentationFeedback::Flags::kHWCompletion) ==
- static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION),
- "gfx::PresentationFlags::HWCompletion don't match!");
- static_assert(
- static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kZeroCopy) ==
- static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY),
- "gfx::PresentationFlags::ZeroCopy don't match!");
- wp_presentation_feedback_send_presented(
- resource, seconds >> 32, seconds & 0xffffffff,
- microseconds * base::Time::kNanosecondsPerMicrosecond,
- feedback.interval.InMicroseconds() *
- base::Time::kNanosecondsPerMicrosecond,
- 0, 0, feedback.flags);
- }
- wl_client_flush(wl_resource_get_client(resource));
-}
-
-void presentation_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void presentation_feedback(wl_client* client,
- wl_resource* resource,
- wl_resource* surface_resource,
- uint32_t id) {
- wl_resource* presentation_feedback_resource =
- wl_resource_create(client, &wp_presentation_feedback_interface,
- wl_resource_get_version(resource), id);
-
- // base::Unretained is safe as the resource owns the callback.
- auto cancelable_callback = std::make_unique<
- base::CancelableCallback<void(const gfx::PresentationFeedback&)>>(
- base::Bind(&HandleSurfacePresentationCallback,
- base::Unretained(presentation_feedback_resource)));
-
- GetUserDataAs<Surface>(surface_resource)
- ->RequestPresentationCallback(cancelable_callback->callback());
-
- SetImplementation(presentation_feedback_resource, nullptr,
- std::move(cancelable_callback));
-}
-
-const struct wp_presentation_interface presentation_implementation = {
- presentation_destroy, presentation_feedback};
-
-void bind_presentation(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &wp_presentation_interface, 1, id);
-
- wl_resource_set_implementation(resource, &presentation_implementation, data,
- nullptr);
-
- wp_presentation_send_clock_id(resource, CLOCK_MONOTONIC);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// security_interface:
-
-// Implements the security interface to a Surface. The "only visible on secure
-// output"-state is set to false upon destruction. A window property will be set
-// during the lifetime of this class to prevent multiple instances from being
-// created for the same Surface.
-class Security : public SurfaceObserver {
- public:
- explicit Security(Surface* surface) : surface_(surface) {
- surface_->AddSurfaceObserver(this);
- surface_->SetProperty(kSurfaceHasSecurityKey, true);
- }
- ~Security() override {
- if (surface_) {
- surface_->RemoveSurfaceObserver(this);
- surface_->SetOnlyVisibleOnSecureOutput(false);
- surface_->SetProperty(kSurfaceHasSecurityKey, false);
- }
- }
-
- void OnlyVisibleOnSecureOutput() {
- if (surface_)
- surface_->SetOnlyVisibleOnSecureOutput(true);
- }
-
- // Overridden from SurfaceObserver:
- void OnSurfaceDestroying(Surface* surface) override {
- surface->RemoveSurfaceObserver(this);
- surface_ = nullptr;
- }
-
- private:
- Surface* surface_;
-
- DISALLOW_COPY_AND_ASSIGN(Security);
-};
-
-void security_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void security_only_visible_on_secure_output(wl_client* client,
- wl_resource* resource) {
- GetUserDataAs<Security>(resource)->OnlyVisibleOnSecureOutput();
-}
-
-const struct zcr_security_v1_interface security_implementation = {
- security_destroy, security_only_visible_on_secure_output};
-
-////////////////////////////////////////////////////////////////////////////////
-// secure_output_interface:
-
-void secure_output_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void secure_output_get_security(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* surface_resource) {
- Surface* surface = GetUserDataAs<Surface>(surface_resource);
- if (surface->GetProperty(kSurfaceHasSecurityKey)) {
- wl_resource_post_error(resource, ZCR_SECURE_OUTPUT_V1_ERROR_SECURITY_EXISTS,
- "a security object for that surface already exists");
- return;
- }
-
- wl_resource* security_resource =
- wl_resource_create(client, &zcr_security_v1_interface, 1, id);
-
- SetImplementation(security_resource, &security_implementation,
- std::make_unique<Security>(surface));
-}
-
-const struct zcr_secure_output_v1_interface secure_output_implementation = {
- secure_output_destroy, secure_output_get_security};
-
-void bind_secure_output(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &zcr_secure_output_v1_interface, 1, id);
-
- wl_resource_set_implementation(resource, &secure_output_implementation, data,
- nullptr);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// blending_interface:
-
-// Implements the blending interface to a Surface. The "blend mode" and
-// "alpha"-state is set to SrcOver and 1 upon destruction. A window property
-// will be set during the lifetime of this class to prevent multiple instances
-// from being created for the same Surface.
-class Blending : public SurfaceObserver {
- public:
- explicit Blending(Surface* surface) : surface_(surface) {
- surface_->AddSurfaceObserver(this);
- surface_->SetProperty(kSurfaceHasBlendingKey, true);
- }
- ~Blending() override {
- if (surface_) {
- surface_->RemoveSurfaceObserver(this);
- surface_->SetBlendMode(SkBlendMode::kSrcOver);
- surface_->SetAlpha(1.0f);
- surface_->SetProperty(kSurfaceHasBlendingKey, false);
- }
- }
-
- void SetBlendMode(SkBlendMode blend_mode) {
- if (surface_)
- surface_->SetBlendMode(blend_mode);
- }
-
- void SetAlpha(float value) {
- if (surface_)
- surface_->SetAlpha(value);
- }
-
- // Overridden from SurfaceObserver:
- void OnSurfaceDestroying(Surface* surface) override {
- surface->RemoveSurfaceObserver(this);
- surface_ = nullptr;
- }
-
- private:
- Surface* surface_;
-
- DISALLOW_COPY_AND_ASSIGN(Blending);
-};
-
-void blending_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void blending_set_blending(wl_client* client,
- wl_resource* resource,
- uint32_t equation) {
- switch (equation) {
- case ZCR_BLENDING_V1_BLENDING_EQUATION_NONE:
- GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrc);
- break;
- case ZCR_BLENDING_V1_BLENDING_EQUATION_PREMULT:
- GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrcOver);
- break;
- case ZCR_BLENDING_V1_BLENDING_EQUATION_COVERAGE:
- NOTIMPLEMENTED();
- break;
- default:
- DLOG(WARNING) << "Unsupported blending equation: " << equation;
- break;
- }
-}
-
-void blending_set_alpha(wl_client* client,
- wl_resource* resource,
- wl_fixed_t alpha) {
- GetUserDataAs<Blending>(resource)->SetAlpha(wl_fixed_to_double(alpha));
-}
-
-const struct zcr_blending_v1_interface blending_implementation = {
- blending_destroy, blending_set_blending, blending_set_alpha};
-
-////////////////////////////////////////////////////////////////////////////////
-// alpha_compositing_interface:
-
-void alpha_compositing_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-void alpha_compositing_get_blending(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* surface_resource) {
- Surface* surface = GetUserDataAs<Surface>(surface_resource);
- if (surface->GetProperty(kSurfaceHasBlendingKey)) {
- wl_resource_post_error(resource,
- ZCR_ALPHA_COMPOSITING_V1_ERROR_BLENDING_EXISTS,
- "a blending object for that surface already exists");
- return;
- }
-
- wl_resource* blending_resource =
- wl_resource_create(client, &zcr_blending_v1_interface, 1, id);
-
- SetImplementation(blending_resource, &blending_implementation,
- std::make_unique<Blending>(surface));
-}
-
-const struct zcr_alpha_compositing_v1_interface
- alpha_compositing_implementation = {alpha_compositing_destroy,
- alpha_compositing_get_blending};
-
-void bind_alpha_compositing(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &zcr_alpha_compositing_v1_interface, 1, id);
-
- wl_resource_set_implementation(resource, &alpha_compositing_implementation,
- data, nullptr);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// touch_stylus interface:
-
-class WaylandTouchStylusDelegate : public TouchStylusDelegate {
- public:
- WaylandTouchStylusDelegate(wl_resource* resource, Touch* touch)
- : resource_(resource), touch_(touch) {
- touch_->SetStylusDelegate(this);
- }
- ~WaylandTouchStylusDelegate() override {
- if (touch_ != nullptr)
- touch_->SetStylusDelegate(nullptr);
- }
- void OnTouchDestroying(Touch* touch) override { touch_ = nullptr; }
- void OnTouchTool(int touch_id, ui::EventPointerType type) override {
- uint wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_TOUCH;
- if (type == ui::EventPointerType::POINTER_TYPE_PEN)
- wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_PEN;
- else if (type == ui::EventPointerType::POINTER_TYPE_ERASER)
- wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_ERASER;
- zcr_touch_stylus_v2_send_tool(resource_, touch_id, wayland_type);
- }
- void OnTouchForce(base::TimeTicks time_stamp,
- int touch_id,
- float force) override {
- zcr_touch_stylus_v2_send_force(resource_,
- TimeTicksToMilliseconds(time_stamp),
- touch_id, wl_fixed_from_double(force));
- }
- void OnTouchTilt(base::TimeTicks time_stamp,
- int touch_id,
- const gfx::Vector2dF& tilt) override {
- zcr_touch_stylus_v2_send_tilt(
- resource_, TimeTicksToMilliseconds(time_stamp), touch_id,
- wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y()));
- }
-
- private:
- wl_resource* resource_;
- Touch* touch_;
-
- DISALLOW_COPY_AND_ASSIGN(WaylandTouchStylusDelegate);
-};
-
-void touch_stylus_destroy(wl_client* client, wl_resource* resource) {
- wl_resource_destroy(resource);
-}
-
-const struct zcr_touch_stylus_v2_interface touch_stylus_implementation = {
- touch_stylus_destroy};
-
-////////////////////////////////////////////////////////////////////////////////
-// stylus_v2 interface:
-
-void stylus_get_touch_stylus(wl_client* client,
- wl_resource* resource,
- uint32_t id,
- wl_resource* touch_resource) {
- Touch* touch = GetUserDataAs<Touch>(touch_resource);
- if (touch->HasStylusDelegate()) {
- wl_resource_post_error(
- resource, ZCR_STYLUS_V2_ERROR_TOUCH_STYLUS_EXISTS,
- "touch has already been associated with a stylus object");
- return;
- }
-
- wl_resource* stylus_resource =
- wl_resource_create(client, &zcr_touch_stylus_v2_interface, 1, id);
-
- SetImplementation(
- stylus_resource, &touch_stylus_implementation,
- std::make_unique<WaylandTouchStylusDelegate>(stylus_resource, touch));
-}
-
-const struct zcr_stylus_v2_interface stylus_v2_implementation = {
- stylus_get_touch_stylus};
-
-void bind_stylus_v2(wl_client* client,
- void* data,
- uint32_t version,
- uint32_t id) {
- wl_resource* resource =
- wl_resource_create(client, &zcr_stylus_v2_interface, version, id);
- wl_resource_set_implementation(resource, &stylus_v2_implementation, data,
- nullptr);
-}
-
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -1032,7 +120,7 @@ Server::Server(Display* display)
wl_global_create(wl_display_.get(), &zcr_vsync_feedback_v1_interface, 1,
display_, bind_vsync_feedback);
wl_global_create(wl_display_.get(), &wl_data_device_manager_interface,
- data_device_manager_version, display_,
+ kWlDataDeviceManagerVersion, display_,
bind_data_device_manager);
wl_global_create(wl_display_.get(), &wp_viewporter_interface, 1, display_,
bind_viewporter);
@@ -1071,6 +159,9 @@ Server::Server(Display* display)
bind_input_timestamps_manager);
wl_global_create(wl_display_.get(), &zwp_pointer_gestures_v1_interface, 1,
display_, bind_pointer_gestures);
+ wl_global_create(wl_display_.get(),
+ &zwp_relative_pointer_manager_v1_interface, 1, display_,
+ bind_relative_pointer_manager);
wl_global_create(wl_display_.get(), &zwp_text_input_manager_v1_interface, 1,
display_, bind_text_input_manager);
wl_global_create(wl_display_.get(), &zxdg_shell_v6_interface, 1, display_,
diff --git a/chromium/components/exo/wayland/server_util.cc b/chromium/components/exo/wayland/server_util.cc
index 42ef5d7184f..48473ce4914 100644
--- a/chromium/components/exo/wayland/server_util.cc
+++ b/chromium/components/exo/wayland/server_util.cc
@@ -11,6 +11,8 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
+DEFINE_UI_CLASS_PROPERTY_TYPE(wl_resource*)
+
namespace exo {
namespace wayland {
@@ -18,11 +20,11 @@ namespace {
// A property key containing the surface resource that is associated with
// window. If unset, no surface resource is associated with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kSurfaceResourceKey, nullptr);
+DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kSurfaceResourceKey, nullptr)
// A property key containing the data offer resource that is associated with
// data offer object.
-DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kDataOfferResourceKey, nullptr);
+DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*, kDataOfferResourceKey, nullptr)
// Scale the |child_bounds| in such a way that if it should fill the
// |parent_size|'s width/height, it returns the |parent_size_in_pixel|'s
diff --git a/chromium/components/exo/wayland/wl_compositor.cc b/chromium/components/exo/wayland/wl_compositor.cc
index 558c315ccb9..2d7a9e60d15 100644
--- a/chromium/components/exo/wayland/wl_compositor.cc
+++ b/chromium/components/exo/wayland/wl_compositor.cc
@@ -6,6 +6,7 @@
#include <wayland-server-protocol-core.h>
+#include "base/bind.h"
#include "components/exo/buffer.h"
#include "components/exo/display.h"
#include "components/exo/surface.h"
diff --git a/chromium/components/exo/wayland/wl_data_device_manager.cc b/chromium/components/exo/wayland/wl_data_device_manager.cc
new file mode 100644
index 00000000000..cce2c2535b4
--- /dev/null
+++ b/chromium/components/exo/wayland/wl_data_device_manager.cc
@@ -0,0 +1,364 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wl_data_device_manager.h"
+
+#include <wayland-server-protocol-core.h>
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "components/exo/data_device.h"
+#include "components/exo/data_device_delegate.h"
+#include "components/exo/data_offer.h"
+#include "components/exo/data_offer_delegate.h"
+#include "components/exo/data_source.h"
+#include "components/exo/data_source_delegate.h"
+#include "components/exo/display.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+uint32_t WaylandDataDeviceManagerDndAction(DndAction action) {
+ switch (action) {
+ case DndAction::kNone:
+ return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
+ case DndAction::kCopy:
+ return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
+ case DndAction::kMove:
+ return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
+ case DndAction::kAsk:
+ return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
+ }
+ NOTREACHED();
+}
+
+uint32_t WaylandDataDeviceManagerDndActions(
+ const base::flat_set<DndAction>& dnd_actions) {
+ uint32_t actions = 0;
+ for (DndAction action : dnd_actions)
+ actions |= WaylandDataDeviceManagerDndAction(action);
+ return actions;
+}
+
+DndAction DataDeviceManagerDndAction(uint32_t value) {
+ switch (value) {
+ case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
+ return DndAction::kNone;
+ case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
+ return DndAction::kCopy;
+ case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
+ return DndAction::kMove;
+ case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
+ return DndAction::kAsk;
+ default:
+ NOTREACHED();
+ return DndAction::kNone;
+ }
+}
+
+base::flat_set<DndAction> DataDeviceManagerDndActions(uint32_t value) {
+ base::flat_set<DndAction> actions;
+ if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
+ actions.insert(DndAction::kCopy);
+ if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
+ actions.insert(DndAction::kMove);
+ if (value & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
+ actions.insert(DndAction::kAsk);
+ return actions;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// wl_data_source_interface:
+
+class WaylandDataSourceDelegate : public DataSourceDelegate {
+ public:
+ explicit WaylandDataSourceDelegate(wl_resource* source)
+ : data_source_resource_(source) {}
+
+ // Overridden from DataSourceDelegate:
+ void OnDataSourceDestroying(DataSource* device) override { delete this; }
+ void OnTarget(const std::string& mime_type) override {
+ wl_data_source_send_target(data_source_resource_, mime_type.c_str());
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ void OnSend(const std::string& mime_type, base::ScopedFD fd) override {
+ wl_data_source_send_send(data_source_resource_, mime_type.c_str(),
+ fd.get());
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ void OnCancelled() override {
+ wl_data_source_send_cancelled(data_source_resource_);
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ void OnDndDropPerformed() override {
+ if (wl_resource_get_version(data_source_resource_) >=
+ WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) {
+ wl_data_source_send_dnd_drop_performed(data_source_resource_);
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ }
+ void OnDndFinished() override {
+ if (wl_resource_get_version(data_source_resource_) >=
+ WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) {
+ wl_data_source_send_dnd_finished(data_source_resource_);
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ }
+ void OnAction(DndAction dnd_action) override {
+ if (wl_resource_get_version(data_source_resource_) >=
+ WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
+ wl_data_source_send_action(data_source_resource_,
+ WaylandDataDeviceManagerDndAction(dnd_action));
+ wl_client_flush(wl_resource_get_client(data_source_resource_));
+ }
+ }
+
+ private:
+ wl_resource* const data_source_resource_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandDataSourceDelegate);
+};
+
+void data_source_offer(wl_client* client,
+ wl_resource* resource,
+ const char* mime_type) {
+ GetUserDataAs<DataSource>(resource)->Offer(mime_type);
+}
+
+void data_source_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void data_source_set_actions(wl_client* client,
+ wl_resource* resource,
+ uint32_t dnd_actions) {
+ GetUserDataAs<DataSource>(resource)->SetActions(
+ DataDeviceManagerDndActions(dnd_actions));
+}
+
+const struct wl_data_source_interface data_source_implementation = {
+ data_source_offer, data_source_destroy, data_source_set_actions};
+
+////////////////////////////////////////////////////////////////////////////////
+// wl_data_offer_interface:
+
+class WaylandDataOfferDelegate : public DataOfferDelegate {
+ public:
+ explicit WaylandDataOfferDelegate(wl_resource* offer)
+ : data_offer_resource_(offer) {}
+
+ // Overridden from DataOfferDelegate:
+ void OnDataOfferDestroying(DataOffer* device) override { delete this; }
+ void OnOffer(const std::string& mime_type) override {
+ wl_data_offer_send_offer(data_offer_resource_, mime_type.c_str());
+ wl_client_flush(wl_resource_get_client(data_offer_resource_));
+ }
+ void OnSourceActions(
+ const base::flat_set<DndAction>& source_actions) override {
+ if (wl_resource_get_version(data_offer_resource_) >=
+ WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) {
+ wl_data_offer_send_source_actions(
+ data_offer_resource_,
+ WaylandDataDeviceManagerDndActions(source_actions));
+ wl_client_flush(wl_resource_get_client(data_offer_resource_));
+ }
+ }
+ void OnAction(DndAction action) override {
+ if (wl_resource_get_version(data_offer_resource_) >=
+ WL_DATA_OFFER_ACTION_SINCE_VERSION) {
+ wl_data_offer_send_action(data_offer_resource_,
+ WaylandDataDeviceManagerDndAction(action));
+ wl_client_flush(wl_resource_get_client(data_offer_resource_));
+ }
+ }
+
+ private:
+ wl_resource* const data_offer_resource_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandDataOfferDelegate);
+};
+
+void data_offer_accept(wl_client* client,
+ wl_resource* resource,
+ uint32_t serial,
+ const char* mime_type) {
+ if (mime_type == nullptr) {
+ GetUserDataAs<DataOffer>(resource)->Accept(nullptr);
+ return;
+ }
+ const std::string mime_type_string(mime_type);
+ GetUserDataAs<DataOffer>(resource)->Accept(&mime_type_string);
+}
+
+void data_offer_receive(wl_client* client,
+ wl_resource* resource,
+ const char* mime_type,
+ int fd) {
+ GetUserDataAs<DataOffer>(resource)->Receive(mime_type, base::ScopedFD(fd));
+}
+
+void data_offer_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void data_offer_finish(wl_client* client, wl_resource* resource) {
+ GetUserDataAs<DataOffer>(resource)->Finish();
+}
+
+void data_offer_set_actions(wl_client* client,
+ wl_resource* resource,
+ uint32_t dnd_actions,
+ uint32_t preferred_action) {
+ GetUserDataAs<DataOffer>(resource)->SetActions(
+ DataDeviceManagerDndActions(dnd_actions),
+ DataDeviceManagerDndAction(preferred_action));
+}
+
+const struct wl_data_offer_interface data_offer_implementation = {
+ data_offer_accept, data_offer_receive, data_offer_finish,
+ data_offer_destroy, data_offer_set_actions};
+
+////////////////////////////////////////////////////////////////////////////////
+// wl_data_device_interface:
+
+class WaylandDataDeviceDelegate : public DataDeviceDelegate {
+ public:
+ WaylandDataDeviceDelegate(wl_client* client, wl_resource* device_resource)
+ : client_(client), data_device_resource_(device_resource) {}
+
+ // Overridden from DataDeviceDelegate:
+ void OnDataDeviceDestroying(DataDevice* device) override { delete this; }
+ bool CanAcceptDataEventsForSurface(Surface* surface) override {
+ return surface &&
+ wl_resource_get_client(GetSurfaceResource(surface)) == client_;
+ }
+ DataOffer* OnDataOffer() override {
+ wl_resource* data_offer_resource =
+ wl_resource_create(client_, &wl_data_offer_interface,
+ wl_resource_get_version(data_device_resource_), 0);
+ std::unique_ptr<DataOffer> data_offer = std::make_unique<DataOffer>(
+ new WaylandDataOfferDelegate(data_offer_resource));
+ SetDataOfferResource(data_offer.get(), data_offer_resource);
+ SetImplementation(data_offer_resource, &data_offer_implementation,
+ std::move(data_offer));
+
+ wl_data_device_send_data_offer(data_device_resource_, data_offer_resource);
+ wl_client_flush(client_);
+
+ return GetUserDataAs<DataOffer>(data_offer_resource);
+ }
+ void OnEnter(Surface* surface,
+ const gfx::PointF& point,
+ const DataOffer& data_offer) override {
+ wl_data_device_send_enter(
+ data_device_resource_,
+ wl_display_next_serial(wl_client_get_display(client_)),
+ GetSurfaceResource(surface), wl_fixed_from_double(point.x()),
+ wl_fixed_from_double(point.y()), GetDataOfferResource(&data_offer));
+ wl_client_flush(client_);
+ }
+ void OnLeave() override {
+ wl_data_device_send_leave(data_device_resource_);
+ wl_client_flush(client_);
+ }
+ void OnMotion(base::TimeTicks time_stamp, const gfx::PointF& point) override {
+ wl_data_device_send_motion(
+ data_device_resource_, TimeTicksToMilliseconds(time_stamp),
+ wl_fixed_from_double(point.x()), wl_fixed_from_double(point.y()));
+ wl_client_flush(client_);
+ }
+ void OnDrop() override {
+ wl_data_device_send_drop(data_device_resource_);
+ wl_client_flush(client_);
+ }
+ void OnSelection(const DataOffer& data_offer) override {
+ wl_data_device_send_selection(data_device_resource_,
+ GetDataOfferResource(&data_offer));
+ wl_client_flush(client_);
+ }
+
+ private:
+ wl_client* const client_;
+ wl_resource* const data_device_resource_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandDataDeviceDelegate);
+};
+
+void data_device_start_drag(wl_client* client,
+ wl_resource* resource,
+ wl_resource* source_resource,
+ wl_resource* origin_resource,
+ wl_resource* icon_resource,
+ uint32_t serial) {
+ GetUserDataAs<DataDevice>(resource)->StartDrag(
+ source_resource ? GetUserDataAs<DataSource>(source_resource) : nullptr,
+ GetUserDataAs<Surface>(origin_resource),
+ icon_resource ? GetUserDataAs<Surface>(icon_resource) : nullptr, serial);
+}
+
+void data_device_set_selection(wl_client* client,
+ wl_resource* resource,
+ wl_resource* data_source,
+ uint32_t serial) {
+ GetUserDataAs<DataDevice>(resource)->SetSelection(
+ data_source ? GetUserDataAs<DataSource>(data_source) : nullptr, serial);
+}
+
+void data_device_release(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+const struct wl_data_device_interface data_device_implementation = {
+ data_device_start_drag, data_device_set_selection, data_device_release};
+
+////////////////////////////////////////////////////////////////////////////////
+// wl_data_device_manager_interface:
+
+void data_device_manager_create_data_source(wl_client* client,
+ wl_resource* resource,
+ uint32_t id) {
+ wl_resource* data_source_resource = wl_resource_create(
+ client, &wl_data_source_interface, wl_resource_get_version(resource), id);
+ SetImplementation(data_source_resource, &data_source_implementation,
+ std::make_unique<DataSource>(
+ new WaylandDataSourceDelegate(data_source_resource)));
+}
+
+void data_device_manager_get_data_device(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* seat_resource) {
+ Display* display = GetUserDataAs<Display>(resource);
+ wl_resource* data_device_resource = wl_resource_create(
+ client, &wl_data_device_interface, wl_resource_get_version(resource), id);
+ SetImplementation(data_device_resource, &data_device_implementation,
+ display->CreateDataDevice(new WaylandDataDeviceDelegate(
+ client, data_device_resource)));
+}
+
+const struct wl_data_device_manager_interface
+ data_device_manager_implementation = {
+ data_device_manager_create_data_source,
+ data_device_manager_get_data_device};
+
+} // namespace
+
+void bind_data_device_manager(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &wl_data_device_manager_interface,
+ std::min(version, kWlDataDeviceManagerVersion), id);
+ wl_resource_set_implementation(resource, &data_device_manager_implementation,
+ data, nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/wl_data_device_manager.h b/chromium/components/exo/wayland/wl_data_device_manager.h
new file mode 100644
index 00000000000..33b39ff1118
--- /dev/null
+++ b/chromium/components/exo/wayland/wl_data_device_manager.h
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_WL_DATA_DEVICE_MANAGER_H_
+#define COMPONENTS_EXO_WAYLAND_WL_DATA_DEVICE_MANAGER_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+constexpr uint32_t kWlDataDeviceManagerVersion = 3;
+
+void bind_data_device_manager(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_WL_DATA_DEVICE_MANAGER_H_
diff --git a/chromium/components/exo/wayland/wl_shell.cc b/chromium/components/exo/wayland/wl_shell.cc
index 3224caec5b4..1b283e6efa7 100644
--- a/chromium/components/exo/wayland/wl_shell.cc
+++ b/chromium/components/exo/wayland/wl_shell.cc
@@ -8,6 +8,7 @@
#include <wayland-server-protocol-core.h>
#include "ash/public/cpp/shell_window_ids.h"
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "components/exo/display.h"
#include "components/exo/shell_surface.h"
diff --git a/chromium/components/exo/wayland/wp_presentation.cc b/chromium/components/exo/wayland/wp_presentation.cc
new file mode 100644
index 00000000000..d2a4f2d16c7
--- /dev/null
+++ b/chromium/components/exo/wayland/wp_presentation.cc
@@ -0,0 +1,104 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wp_presentation.h"
+
+#include <presentation-time-server-protocol.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "components/exo/wayland/server_util.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// presentation_interface:
+
+void HandleSurfacePresentationCallback(
+ wl_resource* resource,
+ const gfx::PresentationFeedback& feedback) {
+ if (feedback.timestamp.is_null()) {
+ wp_presentation_feedback_send_discarded(resource);
+ } else {
+ int64_t presentation_time_us = feedback.timestamp.ToInternalValue();
+ int64_t seconds = presentation_time_us / base::Time::kMicrosecondsPerSecond;
+ int64_t microseconds =
+ presentation_time_us % base::Time::kMicrosecondsPerSecond;
+ static_assert(
+ static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kVSync) ==
+ static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_VSYNC),
+ "gfx::PresentationFlags::VSync don't match!");
+ static_assert(
+ static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kHWClock) ==
+ static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK),
+ "gfx::PresentationFlags::HWClock don't match!");
+ static_assert(
+ static_cast<uint32_t>(
+ gfx::PresentationFeedback::Flags::kHWCompletion) ==
+ static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION),
+ "gfx::PresentationFlags::HWCompletion don't match!");
+ static_assert(
+ static_cast<uint32_t>(gfx::PresentationFeedback::Flags::kZeroCopy) ==
+ static_cast<uint32_t>(WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY),
+ "gfx::PresentationFlags::ZeroCopy don't match!");
+ wp_presentation_feedback_send_presented(
+ resource, seconds >> 32, seconds & 0xffffffff,
+ microseconds * base::Time::kNanosecondsPerMicrosecond,
+ feedback.interval.InMicroseconds() *
+ base::Time::kNanosecondsPerMicrosecond,
+ 0, 0, feedback.flags);
+ }
+ wl_client_flush(wl_resource_get_client(resource));
+}
+
+void presentation_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void presentation_feedback(wl_client* client,
+ wl_resource* resource,
+ wl_resource* surface_resource,
+ uint32_t id) {
+ wl_resource* presentation_feedback_resource =
+ wl_resource_create(client, &wp_presentation_feedback_interface,
+ wl_resource_get_version(resource), id);
+
+ // base::Unretained is safe as the resource owns the callback.
+ auto cancelable_callback = std::make_unique<
+ base::CancelableCallback<void(const gfx::PresentationFeedback&)>>(
+ base::Bind(&HandleSurfacePresentationCallback,
+ base::Unretained(presentation_feedback_resource)));
+
+ GetUserDataAs<Surface>(surface_resource)
+ ->RequestPresentationCallback(cancelable_callback->callback());
+
+ SetImplementation(presentation_feedback_resource, nullptr,
+ std::move(cancelable_callback));
+}
+
+const struct wp_presentation_interface presentation_implementation = {
+ presentation_destroy, presentation_feedback};
+
+} // namespace
+
+void bind_presentation(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &wp_presentation_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &presentation_implementation, data,
+ nullptr);
+
+ wp_presentation_send_clock_id(resource, CLOCK_MONOTONIC);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/wp_presentation.h b/chromium/components/exo/wayland/wp_presentation.h
new file mode 100644
index 00000000000..1a46a3532af
--- /dev/null
+++ b/chromium/components/exo/wayland/wp_presentation.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
+#define COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_presentation(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_WP_PRESENTATION_H_
diff --git a/chromium/components/exo/wayland/wp_viewporter.cc b/chromium/components/exo/wayland/wp_viewporter.cc
new file mode 100644
index 00000000000..4fa7aa84660
--- /dev/null
+++ b/chromium/components/exo/wayland/wp_viewporter.cc
@@ -0,0 +1,159 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/wp_viewporter.h"
+
+#include <viewporter-server-protocol.h>
+
+#include <memory>
+
+#include "components/exo/surface_observer.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+// A property key containing a boolean set to true if a viewport is associated
+// with with surface object.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasViewportKey, false)
+
+////////////////////////////////////////////////////////////////////////////////
+// wp_viewport_interface:
+
+// Implements the viewport interface to a Surface. The "viewport"-state is set
+// to null upon destruction. A window property will be set during the lifetime
+// of this class to prevent multiple instances from being created for the same
+// Surface.
+class Viewport : public SurfaceObserver {
+ public:
+ explicit Viewport(Surface* surface) : surface_(surface) {
+ surface_->AddSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasViewportKey, true);
+ }
+ ~Viewport() override {
+ if (surface_) {
+ surface_->RemoveSurfaceObserver(this);
+ surface_->SetCrop(gfx::RectF());
+ surface_->SetViewport(gfx::Size());
+ surface_->SetProperty(kSurfaceHasViewportKey, false);
+ }
+ }
+
+ void SetSource(const gfx::RectF& rect) {
+ if (surface_)
+ surface_->SetCrop(rect);
+ }
+
+ void SetDestination(const gfx::Size& size) {
+ if (surface_)
+ surface_->SetViewport(size);
+ }
+
+ // Overridden from SurfaceObserver:
+ void OnSurfaceDestroying(Surface* surface) override {
+ surface->RemoveSurfaceObserver(this);
+ surface_ = nullptr;
+ }
+
+ private:
+ Surface* surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(Viewport);
+};
+
+void viewport_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void viewport_set_source(wl_client* client,
+ wl_resource* resource,
+ wl_fixed_t x,
+ wl_fixed_t y,
+ wl_fixed_t width,
+ wl_fixed_t height) {
+ if (x == wl_fixed_from_int(-1) && y == wl_fixed_from_int(-1) &&
+ width == wl_fixed_from_int(-1) && height == wl_fixed_from_int(-1)) {
+ GetUserDataAs<Viewport>(resource)->SetSource(gfx::RectF());
+ return;
+ }
+
+ if (x < 0 || y < 0 || width <= 0 || height <= 0) {
+ wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
+ "source rectangle must be non-empty (%dx%d) and"
+ "have positive origin (%d,%d)",
+ width, height, x, y);
+ return;
+ }
+
+ GetUserDataAs<Viewport>(resource)->SetSource(
+ gfx::RectF(wl_fixed_to_double(x), wl_fixed_to_double(y),
+ wl_fixed_to_double(width), wl_fixed_to_double(height)));
+}
+
+void viewport_set_destination(wl_client* client,
+ wl_resource* resource,
+ int32_t width,
+ int32_t height) {
+ if (width == -1 && height == -1) {
+ GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size());
+ return;
+ }
+
+ if (width <= 0 || height <= 0) {
+ wl_resource_post_error(resource, WP_VIEWPORT_ERROR_BAD_VALUE,
+ "destination size must be positive (%dx%d)", width,
+ height);
+ return;
+ }
+
+ GetUserDataAs<Viewport>(resource)->SetDestination(gfx::Size(width, height));
+}
+
+const struct wp_viewport_interface viewport_implementation = {
+ viewport_destroy, viewport_set_source, viewport_set_destination};
+
+////////////////////////////////////////////////////////////////////////////////
+// wp_viewporter_interface:
+
+void viewporter_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void viewporter_get_viewport(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* surface_resource) {
+ Surface* surface = GetUserDataAs<Surface>(surface_resource);
+ if (surface->GetProperty(kSurfaceHasViewportKey)) {
+ wl_resource_post_error(resource, WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
+ "a viewport for that surface already exists");
+ return;
+ }
+
+ wl_resource* viewport_resource = wl_resource_create(
+ client, &wp_viewport_interface, wl_resource_get_version(resource), id);
+
+ SetImplementation(viewport_resource, &viewport_implementation,
+ std::make_unique<Viewport>(surface));
+}
+
+const struct wp_viewporter_interface viewporter_implementation = {
+ viewporter_destroy, viewporter_get_viewport};
+
+} // namespace
+
+void bind_viewporter(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &wp_viewporter_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &viewporter_implementation, data,
+ nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/wp_viewporter.h b/chromium/components/exo/wayland/wp_viewporter.h
new file mode 100644
index 00000000000..1b4c158b251
--- /dev/null
+++ b/chromium/components/exo/wayland/wp_viewporter.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
+#define COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_viewporter(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_WP_VIEWPORTER_H_
diff --git a/chromium/components/exo/wayland/zaura_shell.cc b/chromium/components/exo/wayland/zaura_shell.cc
index 560dcf86f94..ea2de9efb87 100644
--- a/chromium/components/exo/wayland/zaura_shell.cc
+++ b/chromium/components/exo/wayland/zaura_shell.cc
@@ -23,7 +23,7 @@ namespace {
// A property key containing a boolean set to true if na aura surface object is
// associated with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasAuraSurfaceKey, false);
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasAuraSurfaceKey, false)
////////////////////////////////////////////////////////////////////////////////
// aura_surface_interface:
diff --git a/chromium/components/exo/wayland/zcr_alpha_compositing.cc b/chromium/components/exo/wayland/zcr_alpha_compositing.cc
new file mode 100644
index 00000000000..414b460099d
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_alpha_compositing.cc
@@ -0,0 +1,141 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/zcr_alpha_compositing.h"
+
+#include <alpha-compositing-unstable-v1-server-protocol.h>
+
+#include "components/exo/surface.h"
+#include "components/exo/surface_observer.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+// A property key containing a boolean set to true if a blending object is
+// associated with surface object.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasBlendingKey, false)
+
+////////////////////////////////////////////////////////////////////////////////
+// blending_interface:
+
+// Implements the blending interface to a Surface. The "blend mode" and
+// "alpha"-state is set to SrcOver and 1 upon destruction. A window property
+// will be set during the lifetime of this class to prevent multiple instances
+// from being created for the same Surface.
+class Blending : public SurfaceObserver {
+ public:
+ explicit Blending(Surface* surface) : surface_(surface) {
+ surface_->AddSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasBlendingKey, true);
+ }
+ ~Blending() override {
+ if (surface_) {
+ surface_->RemoveSurfaceObserver(this);
+ surface_->SetBlendMode(SkBlendMode::kSrcOver);
+ surface_->SetAlpha(1.0f);
+ surface_->SetProperty(kSurfaceHasBlendingKey, false);
+ }
+ }
+
+ void SetBlendMode(SkBlendMode blend_mode) {
+ if (surface_)
+ surface_->SetBlendMode(blend_mode);
+ }
+
+ void SetAlpha(float value) {
+ if (surface_)
+ surface_->SetAlpha(value);
+ }
+
+ // Overridden from SurfaceObserver:
+ void OnSurfaceDestroying(Surface* surface) override {
+ surface->RemoveSurfaceObserver(this);
+ surface_ = nullptr;
+ }
+
+ private:
+ Surface* surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(Blending);
+};
+
+void blending_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void blending_set_blending(wl_client* client,
+ wl_resource* resource,
+ uint32_t equation) {
+ switch (equation) {
+ case ZCR_BLENDING_V1_BLENDING_EQUATION_NONE:
+ GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrc);
+ break;
+ case ZCR_BLENDING_V1_BLENDING_EQUATION_PREMULT:
+ GetUserDataAs<Blending>(resource)->SetBlendMode(SkBlendMode::kSrcOver);
+ break;
+ case ZCR_BLENDING_V1_BLENDING_EQUATION_COVERAGE:
+ NOTIMPLEMENTED();
+ break;
+ default:
+ DLOG(WARNING) << "Unsupported blending equation: " << equation;
+ break;
+ }
+}
+
+void blending_set_alpha(wl_client* client,
+ wl_resource* resource,
+ wl_fixed_t alpha) {
+ GetUserDataAs<Blending>(resource)->SetAlpha(wl_fixed_to_double(alpha));
+}
+
+const struct zcr_blending_v1_interface blending_implementation = {
+ blending_destroy, blending_set_blending, blending_set_alpha};
+
+////////////////////////////////////////////////////////////////////////////////
+// alpha_compositing_interface:
+
+void alpha_compositing_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void alpha_compositing_get_blending(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* surface_resource) {
+ Surface* surface = GetUserDataAs<Surface>(surface_resource);
+ if (surface->GetProperty(kSurfaceHasBlendingKey)) {
+ wl_resource_post_error(resource,
+ ZCR_ALPHA_COMPOSITING_V1_ERROR_BLENDING_EXISTS,
+ "a blending object for that surface already exists");
+ return;
+ }
+
+ wl_resource* blending_resource =
+ wl_resource_create(client, &zcr_blending_v1_interface, 1, id);
+
+ SetImplementation(blending_resource, &blending_implementation,
+ std::make_unique<Blending>(surface));
+}
+
+const struct zcr_alpha_compositing_v1_interface
+ alpha_compositing_implementation = {alpha_compositing_destroy,
+ alpha_compositing_get_blending};
+
+} // namespace
+
+void bind_alpha_compositing(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &zcr_alpha_compositing_v1_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &alpha_compositing_implementation,
+ data, nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/zcr_alpha_compositing.h b/chromium/components/exo/wayland/zcr_alpha_compositing.h
new file mode 100644
index 00000000000..4fdae13e4bd
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_alpha_compositing.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_ZCR_ALPHA_COMPOSITING_H_
+#define COMPONENTS_EXO_WAYLAND_ZCR_ALPHA_COMPOSITING_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_alpha_compositing(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_ZCR_ALPHA_COMPOSITING_H_
diff --git a/chromium/components/exo/wayland/zcr_keyboard_configuration.cc b/chromium/components/exo/wayland/zcr_keyboard_configuration.cc
index aeb1ff2d3f2..d986c54cead 100644
--- a/chromium/components/exo/wayland/zcr_keyboard_configuration.cc
+++ b/chromium/components/exo/wayland/zcr_keyboard_configuration.cc
@@ -8,6 +8,9 @@
#include <wayland-server-core.h>
#include <wayland-server-protocol-core.h>
+#include "ash/ime/ime_controller.h"
+#include "ash/shell.h"
+#include "base/feature_list.h"
#include "components/exo/keyboard.h"
#include "components/exo/keyboard_device_configuration_delegate.h"
#include "components/exo/keyboard_observer.h"
@@ -18,20 +21,31 @@ namespace wayland {
namespace {
+// Send a keyboard layout name instead of XKB contents.
+// TODO(tetsui): Remove when the change becomes default.
+const base::Feature kSendKeyboardLayoutNameFeature{
+ "ExoSendKeyboardLayoutName", base::FEATURE_ENABLED_BY_DEFAULT};
+
////////////////////////////////////////////////////////////////////////////////
// keyboard_device_configuration interface:
class WaylandKeyboardDeviceConfigurationDelegate
: public KeyboardDeviceConfigurationDelegate,
- public KeyboardObserver {
+ public KeyboardObserver,
+ public ash::ImeController::Observer {
public:
WaylandKeyboardDeviceConfigurationDelegate(wl_resource* resource,
Keyboard* keyboard)
: resource_(resource), keyboard_(keyboard) {
keyboard_->SetDeviceConfigurationDelegate(this);
keyboard_->AddObserver(this);
+ ash::ImeController* ime_controller = ash::Shell::Get()->ime_controller();
+ ime_controller->AddObserver(this);
+ OnKeyboardLayoutNameChanged(ime_controller->keyboard_layout_name());
}
+
~WaylandKeyboardDeviceConfigurationDelegate() override {
+ ash::Shell::Get()->ime_controller()->RemoveObserver(this);
if (keyboard_) {
keyboard_->SetDeviceConfigurationDelegate(nullptr);
keyboard_->RemoveObserver(this);
@@ -52,6 +66,16 @@ class WaylandKeyboardDeviceConfigurationDelegate
: ZCR_KEYBOARD_DEVICE_CONFIGURATION_V1_KEYBOARD_TYPE_VIRTUAL);
}
+ // Overridden from ImeController::Observer:
+ void OnCapsLockChanged(bool enabled) override {}
+
+ void OnKeyboardLayoutNameChanged(const std::string& layout_name) override {
+ if (!base::FeatureList::IsEnabled(kSendKeyboardLayoutNameFeature))
+ return;
+ zcr_keyboard_device_configuration_v1_send_layout_change(
+ resource_, layout_name.c_str());
+ }
+
private:
wl_resource* resource_;
Keyboard* keyboard_;
diff --git a/chromium/components/exo/wayland/zcr_notification_shell.cc b/chromium/components/exo/wayland/zcr_notification_shell.cc
index ff6349b2a25..e7470d038f4 100644
--- a/chromium/components/exo/wayland/zcr_notification_shell.cc
+++ b/chromium/components/exo/wayland/zcr_notification_shell.cc
@@ -11,6 +11,7 @@
#include <string>
#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
#include "base/optional.h"
#include "components/exo/notification.h"
#include "components/exo/notification_surface.h"
diff --git a/chromium/components/exo/wayland/zcr_remote_shell.cc b/chromium/components/exo/wayland/zcr_remote_shell.cc
index 4083252822d..713681ff188 100644
--- a/chromium/components/exo/wayland/zcr_remote_shell.cc
+++ b/chromium/components/exo/wayland/zcr_remote_shell.cc
@@ -17,6 +17,7 @@
#include "ash/wm/tablet_mode/tablet_mode_observer.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_state.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/components/exo/wayland/zcr_secure_output.cc b/chromium/components/exo/wayland/zcr_secure_output.cc
new file mode 100644
index 00000000000..c070f6dce62
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_secure_output.cc
@@ -0,0 +1,113 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/zcr_secure_output.h"
+
+#include <secure-output-unstable-v1-server-protocol.h>
+
+#include "components/exo/surface.h"
+#include "components/exo/surface_observer.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+// A property key containing a boolean set to true if a security object is
+// associated with surface object.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasSecurityKey, false)
+
+////////////////////////////////////////////////////////////////////////////////
+// security_interface:
+
+// Implements the security interface to a Surface. The "only visible on secure
+// output"-state is set to false upon destruction. A window property will be set
+// during the lifetime of this class to prevent multiple instances from being
+// created for the same Surface.
+class Security : public SurfaceObserver {
+ public:
+ explicit Security(Surface* surface) : surface_(surface) {
+ surface_->AddSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasSecurityKey, true);
+ }
+ ~Security() override {
+ if (surface_) {
+ surface_->RemoveSurfaceObserver(this);
+ surface_->SetOnlyVisibleOnSecureOutput(false);
+ surface_->SetProperty(kSurfaceHasSecurityKey, false);
+ }
+ }
+
+ void OnlyVisibleOnSecureOutput() {
+ if (surface_)
+ surface_->SetOnlyVisibleOnSecureOutput(true);
+ }
+
+ // Overridden from SurfaceObserver:
+ void OnSurfaceDestroying(Surface* surface) override {
+ surface->RemoveSurfaceObserver(this);
+ surface_ = nullptr;
+ }
+
+ private:
+ Surface* surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(Security);
+};
+
+void security_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void security_only_visible_on_secure_output(wl_client* client,
+ wl_resource* resource) {
+ GetUserDataAs<Security>(resource)->OnlyVisibleOnSecureOutput();
+}
+
+const struct zcr_security_v1_interface security_implementation = {
+ security_destroy, security_only_visible_on_secure_output};
+
+////////////////////////////////////////////////////////////////////////////////
+// secure_output_interface:
+
+void secure_output_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void secure_output_get_security(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* surface_resource) {
+ Surface* surface = GetUserDataAs<Surface>(surface_resource);
+ if (surface->GetProperty(kSurfaceHasSecurityKey)) {
+ wl_resource_post_error(resource, ZCR_SECURE_OUTPUT_V1_ERROR_SECURITY_EXISTS,
+ "a security object for that surface already exists");
+ return;
+ }
+
+ wl_resource* security_resource =
+ wl_resource_create(client, &zcr_security_v1_interface, 1, id);
+
+ SetImplementation(security_resource, &security_implementation,
+ std::make_unique<Security>(surface));
+}
+
+const struct zcr_secure_output_v1_interface secure_output_implementation = {
+ secure_output_destroy, secure_output_get_security};
+
+} // namespace
+
+void bind_secure_output(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &zcr_secure_output_v1_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &secure_output_implementation, data,
+ nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/zcr_secure_output.h b/chromium/components/exo/wayland/zcr_secure_output.h
new file mode 100644
index 00000000000..4da60450521
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_secure_output.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_ZCR_SECURE_OUTPUT_H_
+#define COMPONENTS_EXO_WAYLAND_ZCR_SECURE_OUTPUT_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_secure_output(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_ZCR_SECURE_OUTPUT_H_
diff --git a/chromium/components/exo/wayland/zcr_stylus.cc b/chromium/components/exo/wayland/zcr_stylus.cc
new file mode 100644
index 00000000000..114c9de9382
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_stylus.cc
@@ -0,0 +1,107 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/zcr_stylus.h"
+
+#include <stylus-unstable-v2-server-protocol.h>
+
+#include "components/exo/touch.h"
+#include "components/exo/touch_stylus_delegate.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// touch_stylus interface:
+
+class WaylandTouchStylusDelegate : public TouchStylusDelegate {
+ public:
+ WaylandTouchStylusDelegate(wl_resource* resource, Touch* touch)
+ : resource_(resource), touch_(touch) {
+ touch_->SetStylusDelegate(this);
+ }
+ ~WaylandTouchStylusDelegate() override {
+ if (touch_ != nullptr)
+ touch_->SetStylusDelegate(nullptr);
+ }
+ void OnTouchDestroying(Touch* touch) override { touch_ = nullptr; }
+ void OnTouchTool(int touch_id, ui::EventPointerType type) override {
+ uint wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_TOUCH;
+ if (type == ui::EventPointerType::POINTER_TYPE_PEN)
+ wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_PEN;
+ else if (type == ui::EventPointerType::POINTER_TYPE_ERASER)
+ wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_ERASER;
+ zcr_touch_stylus_v2_send_tool(resource_, touch_id, wayland_type);
+ }
+ void OnTouchForce(base::TimeTicks time_stamp,
+ int touch_id,
+ float force) override {
+ zcr_touch_stylus_v2_send_force(resource_,
+ TimeTicksToMilliseconds(time_stamp),
+ touch_id, wl_fixed_from_double(force));
+ }
+ void OnTouchTilt(base::TimeTicks time_stamp,
+ int touch_id,
+ const gfx::Vector2dF& tilt) override {
+ zcr_touch_stylus_v2_send_tilt(
+ resource_, TimeTicksToMilliseconds(time_stamp), touch_id,
+ wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y()));
+ }
+
+ private:
+ wl_resource* resource_;
+ Touch* touch_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandTouchStylusDelegate);
+};
+
+void touch_stylus_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+const struct zcr_touch_stylus_v2_interface touch_stylus_implementation = {
+ touch_stylus_destroy};
+
+////////////////////////////////////////////////////////////////////////////////
+// stylus_v2 interface:
+
+void stylus_get_touch_stylus(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* touch_resource) {
+ Touch* touch = GetUserDataAs<Touch>(touch_resource);
+ if (touch->HasStylusDelegate()) {
+ wl_resource_post_error(
+ resource, ZCR_STYLUS_V2_ERROR_TOUCH_STYLUS_EXISTS,
+ "touch has already been associated with a stylus object");
+ return;
+ }
+
+ wl_resource* stylus_resource =
+ wl_resource_create(client, &zcr_touch_stylus_v2_interface, 1, id);
+
+ SetImplementation(
+ stylus_resource, &touch_stylus_implementation,
+ std::make_unique<WaylandTouchStylusDelegate>(stylus_resource, touch));
+}
+
+const struct zcr_stylus_v2_interface stylus_v2_implementation = {
+ stylus_get_touch_stylus};
+
+} // namespace
+
+void bind_stylus_v2(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &zcr_stylus_v2_interface, version, id);
+ wl_resource_set_implementation(resource, &stylus_v2_implementation, data,
+ nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/zcr_stylus.h b/chromium/components/exo/wayland/zcr_stylus.h
new file mode 100644
index 00000000000..289f7722dc5
--- /dev/null
+++ b/chromium/components/exo/wayland/zcr_stylus.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_ZCR_STYLUS_H_
+#define COMPONENTS_EXO_WAYLAND_ZCR_STYLUS_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_stylus_v2(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_ZCR_STYLUS_H_
diff --git a/chromium/components/exo/wayland/zcr_stylus_tools.cc b/chromium/components/exo/wayland/zcr_stylus_tools.cc
index 096e91312dc..52532697a2e 100644
--- a/chromium/components/exo/wayland/zcr_stylus_tools.cc
+++ b/chromium/components/exo/wayland/zcr_stylus_tools.cc
@@ -19,7 +19,7 @@ namespace {
// A property key containing a boolean set to true if the stylus_tool
// object is associated with surface object.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasStylusToolKey, false);
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasStylusToolKey, false)
////////////////////////////////////////////////////////////////////////////////
// stylus_tool interface:
diff --git a/chromium/components/exo/wayland/zwp_fullscreen_shell.cc b/chromium/components/exo/wayland/zwp_fullscreen_shell.cc
index 5b1d441fd64..d58ffae1bd3 100644
--- a/chromium/components/exo/wayland/zwp_fullscreen_shell.cc
+++ b/chromium/components/exo/wayland/zwp_fullscreen_shell.cc
@@ -8,6 +8,7 @@
#include <wayland-server-core.h>
#include <wayland-server-protocol-core.h>
+#include "base/bind.h"
#include "components/exo/fullscreen_shell_surface.h"
#include "components/exo/surface.h"
#include "components/exo/wayland/server_util.h"
diff --git a/chromium/components/exo/wayland/zwp_linux_explicit_synchronization.cc b/chromium/components/exo/wayland/zwp_linux_explicit_synchronization.cc
index 27a16ff1457..baccb088ad9 100644
--- a/chromium/components/exo/wayland/zwp_linux_explicit_synchronization.cc
+++ b/chromium/components/exo/wayland/zwp_linux_explicit_synchronization.cc
@@ -19,7 +19,7 @@ namespace {
// associated with the surface object.
DEFINE_UI_CLASS_PROPERTY_KEY(wl_resource*,
kSurfaceSynchronizationResource,
- nullptr);
+ nullptr)
////////////////////////////////////////////////////////////////////////////////
// linux_surface_synchronization_v1 interface:
diff --git a/chromium/components/exo/wayland/zwp_relative_pointer_manager.cc b/chromium/components/exo/wayland/zwp_relative_pointer_manager.cc
new file mode 100644
index 00000000000..fcf9079a936
--- /dev/null
+++ b/chromium/components/exo/wayland/zwp_relative_pointer_manager.cc
@@ -0,0 +1,102 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/zwp_relative_pointer_manager.h"
+
+#include <relative-pointer-unstable-v1-server-protocol.h>
+#include <wayland-server-core.h>
+#include <wayland-server-protocol-core.h>
+
+#include <memory>
+
+#include "components/exo/pointer.h"
+#include "components/exo/relative_pointer_delegate.h"
+#include "components/exo/wayland/server_util.h"
+
+namespace exo {
+namespace wayland {
+
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+// relative_pointer_v1 interface:
+
+class WaylandRelativePointerDelegate : public RelativePointerDelegate {
+ public:
+ WaylandRelativePointerDelegate(wl_resource* resource, Pointer* pointer)
+ : resource_(resource), pointer_(pointer) {
+ pointer_->EnablePointerCapture(this);
+ }
+
+ ~WaylandRelativePointerDelegate() override {
+ if (pointer_)
+ pointer_->DisablePointerCapture();
+ }
+ void OnPointerDestroying(Pointer* pointer) override { pointer_ = nullptr; }
+ void OnPointerRelativeMotion(base::TimeTicks time_stamp,
+ const gfx::PointF& relativeMotion) override {
+ zwp_relative_pointer_v1_send_relative_motion(
+ resource_, // resource
+ 0, // utime_hi
+ TimeTicksToMilliseconds(time_stamp), // utime_lo
+ wl_fixed_from_double(relativeMotion.x()), // dx
+ wl_fixed_from_double(relativeMotion.y()), // dy
+ wl_fixed_from_double(relativeMotion.x()), // dx_unaccel
+ wl_fixed_from_double(relativeMotion.y())); // dy_unaccel
+ }
+
+ private:
+ wl_resource* const resource_;
+ Pointer* pointer_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandRelativePointerDelegate);
+};
+
+void relative_pointer_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+const struct zwp_relative_pointer_v1_interface relative_pointer_impl = {
+ relative_pointer_destroy};
+
+////////////////////////////////////////////////////////////////////////////////
+// relative_pointer_manager_v1 interface:
+
+void relative_pointer_manager_destroy(wl_client* client,
+ wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void relative_pointer_manager_get_relative_pointer(
+ wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* pointer_resource) {
+ Pointer* pointer = GetUserDataAs<Pointer>(pointer_resource);
+ wl_resource* relative_pointer_resource =
+ wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
+ SetImplementation(relative_pointer_resource, &relative_pointer_impl,
+ std::make_unique<WaylandRelativePointerDelegate>(
+ relative_pointer_resource, pointer));
+}
+
+const struct zwp_relative_pointer_manager_v1_interface
+ relative_pointer_manager_impl = {
+ relative_pointer_manager_destroy,
+ relative_pointer_manager_get_relative_pointer};
+
+} // namespace
+
+void bind_relative_pointer_manager(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource = wl_resource_create(
+ client, &zwp_relative_pointer_manager_v1_interface, version, id);
+ wl_resource_set_implementation(resource, &relative_pointer_manager_impl, data,
+ nullptr);
+}
+
+} // namespace wayland
+} // namespace exo
diff --git a/chromium/components/exo/wayland/zwp_relative_pointer_manager.h b/chromium/components/exo/wayland/zwp_relative_pointer_manager.h
new file mode 100644
index 00000000000..a5e87b80dec
--- /dev/null
+++ b/chromium/components/exo/wayland/zwp_relative_pointer_manager.h
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_
+#define COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_
+
+#include <stdint.h>
+
+struct wl_client;
+
+namespace exo {
+namespace wayland {
+
+void bind_relative_pointer_manager(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id);
+
+} // namespace wayland
+} // namespace exo
+
+#endif // COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_ \ No newline at end of file
diff --git a/chromium/components/exo/wayland/zwp_text_input_manager.cc b/chromium/components/exo/wayland/zwp_text_input_manager.cc
index 15ebffff773..73ae15fe38e 100644
--- a/chromium/components/exo/wayland/zwp_text_input_manager.cc
+++ b/chromium/components/exo/wayland/zwp_text_input_manager.cc
@@ -25,14 +25,6 @@ namespace {
////////////////////////////////////////////////////////////////////////////////
// text_input_v1 interface:
-size_t OffsetFromUTF8Offset(const base::StringPiece& text, uint32_t offset) {
- return base::UTF8ToUTF16(text.substr(0, offset)).size();
-}
-
-size_t OffsetFromUTF16Offset(const base::StringPiece16& text, uint32_t offset) {
- return base::UTF16ToUTF8(text.substr(0, offset)).size();
-}
-
class WaylandTextInputDelegate : public TextInput::Delegate {
public:
WaylandTextInputDelegate(wl_resource* text_input) : text_input_(text_input) {}
@@ -107,15 +99,13 @@ class WaylandTextInputDelegate : public TextInput::Delegate {
}
void SetCursor(const gfx::Range& selection) override {
- // TODO(mukai): compute the utf8 offset for |selection| and call
- // zwp_text_input_v1_send_cursor_position.
- NOTIMPLEMENTED();
+ zwp_text_input_v1_send_cursor_position(text_input_, selection.end(),
+ selection.start());
}
void DeleteSurroundingText(const gfx::Range& range) override {
- // TODO(mukai): compute the utf8 offset for |range| and call
- // zwp_text_input_send_delete_surrounding_text.
- NOTIMPLEMENTED();
+ zwp_text_input_v1_send_delete_surrounding_text(text_input_, range.start(),
+ range.length());
}
void SendKey(const ui::KeyEvent& event) override {
@@ -216,7 +206,8 @@ void text_input_set_surrounding_text(wl_client* client,
uint32_t anchor) {
TextInput* text_input = GetUserDataAs<TextInput>(resource);
text_input->SetSurroundingText(base::UTF8ToUTF16(text),
- OffsetFromUTF8Offset(text, cursor));
+ OffsetFromUTF8Offset(text, cursor),
+ OffsetFromUTF8Offset(text, anchor));
}
void text_input_set_content_type(wl_client* client,
diff --git a/chromium/components/exo/wayland/zxdg_shell.cc b/chromium/components/exo/wayland/zxdg_shell.cc
index 73a2cc23b0c..26c1fdc7856 100644
--- a/chromium/components/exo/wayland/zxdg_shell.cc
+++ b/chromium/components/exo/wayland/zxdg_shell.cc
@@ -10,6 +10,7 @@
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "components/exo/display.h"
#include "components/exo/wayland/server_util.h"
diff --git a/chromium/components/exo/wm_helper_chromeos.cc b/chromium/components/exo/wm_helper_chromeos.cc
index 42dd2e93004..435cac17324 100644
--- a/chromium/components/exo/wm_helper_chromeos.cc
+++ b/chromium/components/exo/wm_helper_chromeos.cc
@@ -143,10 +143,8 @@ const display::ManagedDisplayInfo& WMHelperChromeOS::GetDisplayInfo(
const std::vector<uint8_t>& WMHelperChromeOS::GetDisplayIdentificationData(
int64_t display_id) const {
- const auto& displays = ash::Shell::Get()
- ->window_tree_host_manager()
- ->display_configurator()
- ->cached_displays();
+ const auto& displays =
+ ash::Shell::Get()->display_configurator()->cached_displays();
for (display::DisplaySnapshot* display : displays)
if (display->display_id() == display_id)
diff --git a/chromium/components/favicon/content/content_favicon_driver.cc b/chromium/components/favicon/content/content_favicon_driver.cc
index be345ad084e..22443c6b217 100644
--- a/chromium/components/favicon/content/content_favicon_driver.cc
+++ b/chromium/components/favicon/content/content_favicon_driver.cc
@@ -141,7 +141,8 @@ void ContentFaviconDriver::OnFaviconUpdated(
const gfx::Image& image) {
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
- DCHECK(entry && entry->GetURL() == page_url);
+ DCHECK(entry);
+ DCHECK_EQ(entry->GetURL(), page_url);
if (notification_icon_type == FaviconDriverObserver::NON_TOUCH_16_DIP) {
entry->GetFavicon().valid = true;
diff --git a/chromium/components/favicon/core/favicon_handler_unittest.cc b/chromium/components/favicon/core/favicon_handler_unittest.cc
index a30391aac66..190cadf65e1 100644
--- a/chromium/components/favicon/core/favicon_handler_unittest.cc
+++ b/chromium/components/favicon/core/favicon_handler_unittest.cc
@@ -11,6 +11,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
diff --git a/chromium/components/favicon/core/favicon_server_fetcher_params.h b/chromium/components/favicon/core/favicon_server_fetcher_params.h
index 8484239c8ad..2b24a1ffa6c 100644
--- a/chromium/components/favicon/core/favicon_server_fetcher_params.h
+++ b/chromium/components/favicon/core/favicon_server_fetcher_params.h
@@ -24,13 +24,13 @@ class FaviconServerFetcherParams {
~FaviconServerFetcherParams();
- const GURL& page_url() const { return page_url_; };
- favicon_base::IconType icon_type() const { return icon_type_; };
- int min_source_size_in_pixel() const { return min_source_size_in_pixel_; };
- int desired_size_in_pixel() const { return desired_size_in_pixel_; };
+ const GURL& page_url() const { return page_url_; }
+ favicon_base::IconType icon_type() const { return icon_type_; }
+ int min_source_size_in_pixel() const { return min_source_size_in_pixel_; }
+ int desired_size_in_pixel() const { return desired_size_in_pixel_; }
const std::string& google_server_client_param() const {
return google_server_client_param_;
- };
+ }
private:
FaviconServerFetcherParams(const GURL& page_url,
diff --git a/chromium/components/favicon/core/favicon_service_impl.cc b/chromium/components/favicon/core/favicon_service_impl.cc
index ac492c8b136..a95898c04fa 100644
--- a/chromium/components/favicon/core/favicon_service_impl.cc
+++ b/chromium/components/favicon/core/favicon_service_impl.cc
@@ -8,6 +8,7 @@
#include <cmath>
#include <utility>
+#include "base/bind.h"
#include "base/hash.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/favicon/core/large_icon_service.h b/chromium/components/favicon/core/large_icon_service.h
index 5d7d649d03e..46fe89821e3 100644
--- a/chromium/components/favicon/core/large_icon_service.h
+++ b/chromium/components/favicon/core/large_icon_service.h
@@ -98,7 +98,7 @@ class LargeIconService : public KeyedService {
virtual void TouchIconFromGoogleServer(const GURL& icon_url) = 0;
protected:
- LargeIconService(){};
+ LargeIconService() {}
private:
DISALLOW_COPY_AND_ASSIGN(LargeIconService);
diff --git a/chromium/components/favicon/core/large_icon_service_impl.cc b/chromium/components/favicon/core/large_icon_service_impl.cc
index c3ee1568cf9..54244ef2d57 100644
--- a/chromium/components/favicon/core/large_icon_service_impl.cc
+++ b/chromium/components/favicon/core/large_icon_service_impl.cc
@@ -39,6 +39,8 @@ namespace {
using favicon_base::GoogleFaviconServerRequestStatus;
+const char kImageFetcherUmaClient[] = "LargeIconService";
+
// This feature is only used for accessing field trial parameters, not for
// switching on/off the code.
const base::Feature kLargeIconServiceFetchingFeature{
@@ -411,14 +413,15 @@ void OnSetOnDemandFaviconComplete(
void OnFetchIconFromGoogleServerComplete(
FaviconService* favicon_service,
const GURL& page_url,
+ const GURL& server_request_url,
favicon_base::IconType icon_type,
const favicon_base::GoogleFaviconServerCallback& callback,
- const std::string& server_request_url,
const gfx::Image& image,
const image_fetcher::RequestMetadata& metadata) {
if (image.IsEmpty()) {
- DLOG(WARNING) << "large icon server fetch empty " << server_request_url;
- favicon_service->UnableToDownloadFavicon(GURL(server_request_url));
+ DLOG(WARNING) << "large icon server fetch empty "
+ << server_request_url.spec();
+ favicon_service->UnableToDownloadFavicon(server_request_url);
callback.Run(
metadata.http_response_code ==
image_fetcher::RequestMetadata::RESPONSE_CODE_INVALID
@@ -434,7 +437,7 @@ void OnFetchIconFromGoogleServerComplete(
// Otherwise, use the request URL as fallback.
std::string original_icon_url = metadata.content_location_header;
if (original_icon_url.empty()) {
- original_icon_url = server_request_url;
+ original_icon_url = server_request_url.spec();
}
// Write fetched icons to FaviconService's cache, but only if no icon was
@@ -607,13 +610,13 @@ void LargeIconServiceImpl::OnCanSetOnDemandFaviconComplete(
return;
}
- image_fetcher_->SetDataUseServiceName(
- data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE);
+ image_fetcher::ImageFetcherParams params(traffic_annotation,
+ kImageFetcherUmaClient);
image_fetcher_->FetchImage(
- server_request_url.spec(), server_request_url,
+ server_request_url,
base::BindOnce(&OnFetchIconFromGoogleServerComplete, favicon_service_,
- page_url, icon_type, callback),
- traffic_annotation);
+ page_url, server_request_url, icon_type, callback),
+ std::move(params));
}
} // namespace favicon
diff --git a/chromium/components/favicon/core/large_icon_service_impl_unittest.cc b/chromium/components/favicon/core/large_icon_service_impl_unittest.cc
index b7917db79a9..3e93fa1f6ef 100644
--- a/chromium/components/favicon/core/large_icon_service_impl_unittest.cc
+++ b/chromium/components/favicon/core/large_icon_service_impl_unittest.cc
@@ -59,13 +59,13 @@ const SkColor kTestColor = SK_ColorRED;
ACTION_P(PostFetchReply, p0) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(*arg3), arg0, p0,
- image_fetcher::RequestMetadata()));
+ FROM_HERE,
+ base::BindOnce(std::move(*arg2), p0, image_fetcher::RequestMetadata()));
}
ACTION_P2(PostFetchReplyWithMetadata, p0, p1) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(*arg3), arg0, p0, p1));
+ FROM_HERE, base::BindOnce(std::move(*arg2), p0, p1));
}
ACTION_P(PostBoolReplyToArg4, p0) {
@@ -161,7 +161,7 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServer) {
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor))));
EXPECT_CALL(mock_favicon_service_,
@@ -199,7 +199,7 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerForDesktop) {
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(32, 32, kTestColor))));
EXPECT_CALL(mock_favicon_service_,
@@ -242,7 +242,7 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerWithCustomUrl) {
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor))));
EXPECT_CALL(mock_favicon_service_,
@@ -279,7 +279,7 @@ TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServerWithOriginalUrl) {
image_fetcher::RequestMetadata expected_metadata;
expected_metadata.content_location_header = kExpectedOriginalUrl.spec();
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReplyWithMetadata(
gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor)),
@@ -317,7 +317,7 @@ TEST_F(LargeIconServiceTest, ShouldTrimQueryParametersForGoogleServer) {
.WillOnce(PostBoolReplyToArg2(true));
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
CreateTestSkBitmap(64, 64, kTestColor))));
// Verify that the non-trimmed page URL is used when writing to the database.
@@ -342,10 +342,10 @@ TEST_F(LargeIconServiceTest, ShouldNotCheckOnPublicUrls) {
favicon_base::IconType::kTouchIcon, _))
.WillOnce(PostBoolReplyToArg2(true));
// The request has no "check_seen=true"; full URL is tested elsewhere.
- EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(
- _, Property(&GURL::query, Not(HasSubstr("check_seen=true"))),
- _, _, _))
+ EXPECT_CALL(
+ *mock_image_fetcher_,
+ FetchImageAndData_(
+ Property(&GURL::query, Not(HasSubstr("check_seen=true"))), _, _, _))
.WillOnce(PostFetchReply(gfx::Image()));
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
@@ -367,7 +367,7 @@ TEST_F(LargeIconServiceTest, ShouldNotCheckOnPublicUrls) {
TEST_F(LargeIconServiceTest, ShouldNotQueryGoogleServerIfInvalidScheme) {
const GURL kDummyFtpUrl("ftp://www.example.com");
- EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _)).Times(0);
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
@@ -391,7 +391,7 @@ TEST_F(LargeIconServiceTest, ShouldNotQueryGoogleServerIfInvalidScheme) {
TEST_F(LargeIconServiceTest, ShouldNotQueryGoogleServerIfInvalidURL) {
const GURL kDummyInvalidUrl("htt");
- EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _)).Times(0);
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
@@ -427,7 +427,7 @@ TEST_F(LargeIconServiceTest, ShouldReportUnavailableIfFetchFromServerFails) {
base::MockCallback<favicon_base::GoogleFaviconServerCallback> callback;
EXPECT_CALL(*mock_image_fetcher_,
- FetchImageAndData_(_, kExpectedServerUrl, _, _, _))
+ FetchImageAndData_(kExpectedServerUrl, _, _, _))
.WillOnce(PostFetchReply(gfx::Image()));
EXPECT_CALL(mock_favicon_service_,
UnableToDownloadFavicon(kExpectedServerUrl));
@@ -458,7 +458,7 @@ TEST_F(LargeIconServiceTest, ShouldNotGetFromGoogleServerIfUnavailable) {
.WillByDefault(Return(true));
EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
- EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _)).Times(0);
EXPECT_CALL(mock_favicon_service_, SetOnDemandFavicons(_, _, _, _, _))
.Times(0);
@@ -487,7 +487,7 @@ TEST_F(LargeIconServiceTest, ShouldNotGetFromGoogleServerIfCannotSet) {
favicon_base::IconType::kTouchIcon, _))
.WillOnce(PostBoolReplyToArg2(false));
- EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_image_fetcher_, FetchImageAndData_(_, _, _, _)).Times(0);
EXPECT_CALL(mock_favicon_service_, SetOnDemandFavicons(_, _, _, _, _))
.Times(0);
@@ -755,9 +755,9 @@ TEST_P(LargeIconServiceGetterTest, ShouldRecordMatchesDespiteDifferentUrls) {
// Every test will appear with suffix /0 (param false) and /1 (param true), e.g.
// LargeIconServiceGetterTest.FallbackSinceTooPicky/0: get image.
// LargeIconServiceGetterTest.FallbackSinceTooPicky/1: get raw bitmap.
-INSTANTIATE_TEST_CASE_P(, // Empty instatiation name.
- LargeIconServiceGetterTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(, // Empty instatiation name.
+ LargeIconServiceGetterTest,
+ ::testing::Values(false, true));
TEST(LargeIconServiceOrganizationNameTest, ShouldGetOrganizationNameForUma) {
EXPECT_EQ("", LargeIconServiceImpl::GetOrganizationNameForUma(GURL()));
diff --git a/chromium/components/favicon/ios/web_favicon_driver.h b/chromium/components/favicon/ios/web_favicon_driver.h
index 400f83ace5a..8126752ec48 100644
--- a/chromium/components/favicon/ios/web_favicon_driver.h
+++ b/chromium/components/favicon/ios/web_favicon_driver.h
@@ -75,6 +75,8 @@ class WebFaviconDriver : public web::WebStateObserver,
// WebStateDestroyed has been called.
web::WebState* web_state_ = nullptr;
+ WEB_STATE_USER_DATA_KEY_DECL();
+
DISALLOW_COPY_AND_ASSIGN(WebFaviconDriver);
};
diff --git a/chromium/components/favicon/ios/web_favicon_driver.mm b/chromium/components/favicon/ios/web_favicon_driver.mm
index 537f3aad1ca..e3797d28e7c 100644
--- a/chromium/components/favicon/ios/web_favicon_driver.mm
+++ b/chromium/components/favicon/ios/web_favicon_driver.mm
@@ -182,4 +182,6 @@ void WebFaviconDriver::WebStateDestroyed(web::WebState* web_state) {
web_state_ = nullptr;
}
+WEB_STATE_USER_DATA_KEY_IMPL(WebFaviconDriver)
+
} // namespace favicon
diff --git a/chromium/components/feature_engagement/features.gni b/chromium/components/feature_engagement/features.gni
index bfda1bc6289..72eaa1d7d53 100644
--- a/chromium/components/feature_engagement/features.gni
+++ b/chromium/components/feature_engagement/features.gni
@@ -4,7 +4,6 @@
declare_args() {
# In-Product Help is only available in Windows and Linux OS for
- # desktop. Other platforms such as Mac OS currently does not support
- # Views and there have been no strong feelings about CrOS.
+ # desktop.
enable_desktop_in_product_help = is_win || (is_linux && !is_chromeos)
}
diff --git a/chromium/components/feature_engagement/internal/never_availability_model.cc b/chromium/components/feature_engagement/internal/never_availability_model.cc
index 1b4615d8382..03eb01da3ac 100644
--- a/chromium/components/feature_engagement/internal/never_availability_model.cc
+++ b/chromium/components/feature_engagement/internal/never_availability_model.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/optional.h"
#include "base/sequenced_task_runner.h"
diff --git a/chromium/components/feature_engagement/internal/persistent_event_store_unittest.cc b/chromium/components/feature_engagement/internal/persistent_event_store_unittest.cc
index 8297481a1ea..005e9f8515b 100644
--- a/chromium/components/feature_engagement/internal/persistent_event_store_unittest.cc
+++ b/chromium/components/feature_engagement/internal/persistent_event_store_unittest.cc
@@ -6,6 +6,7 @@
#include <map>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/optional.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/feature_engagement/internal/tracker_impl.cc b/chromium/components/feature_engagement/internal/tracker_impl.cc
index 3e8ce5ff19e..e77243a87e1 100644
--- a/chromium/components/feature_engagement/internal/tracker_impl.cc
+++ b/chromium/components/feature_engagement/internal/tracker_impl.cc
@@ -38,7 +38,7 @@
namespace feature_engagement {
namespace {
-const char kFeatureName[] = "FeatureEngagement";
+
const char kEventDBName[] = "EventDB";
const char kAvailabilityDBName[] = "AvailabilityDB";
@@ -99,7 +99,7 @@ Tracker* Tracker::Create(
base::FilePath event_storage_dir =
storage_dir.AppendASCII(std::string(kEventDBName));
auto event_db = db_provider->GetDB<Event>(
- std::string(kFeatureName), std::string(kEventDBName), event_storage_dir,
+ leveldb_proto::ProtoDbType::FEATURE_ENGAGEMENT_EVENT, event_storage_dir,
background_task_runner);
auto event_store =
@@ -124,7 +124,7 @@ Tracker* Tracker::Create(
base::FilePath availability_storage_dir =
storage_dir.AppendASCII(std::string(kAvailabilityDBName));
auto availability_db = db_provider->GetDB<Availability>(
- std::string(kFeatureName), std::string(kAvailabilityDBName),
+ leveldb_proto::ProtoDbType::FEATURE_ENGAGEMENT_AVAILABILITY,
availability_storage_dir, background_task_runner);
auto availability_store_loader = base::BindOnce(
&PersistentAvailabilityStore::LoadAndUpdateStore,
diff --git a/chromium/components/feature_engagement/internal/tracker_impl_unittest.cc b/chromium/components/feature_engagement/internal/tracker_impl_unittest.cc
index 197a10e3e3d..6c422e66289 100644
--- a/chromium/components/feature_engagement/internal/tracker_impl_unittest.cc
+++ b/chromium/components/feature_engagement/internal/tracker_impl_unittest.cc
@@ -117,7 +117,7 @@ class StoreEverythingEventStorageValidator : public EventStorageValidator {
uint32_t event_day,
uint32_t current_day) const override {
return true;
- };
+ }
private:
DISALLOW_COPY_AND_ASSIGN(StoreEverythingEventStorageValidator);
@@ -129,7 +129,7 @@ class TestTimeProvider : public TimeProvider {
~TestTimeProvider() override = default;
// TimeProvider implementation.
- uint32_t GetCurrentDay() const override { return 1u; };
+ uint32_t GetCurrentDay() const override { return 1u; }
private:
DISALLOW_COPY_AND_ASSIGN(TestTimeProvider);
diff --git a/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java b/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
index 2bb5b14efdd..11945112c62 100644
--- a/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
+++ b/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/EventConstants.java
@@ -83,6 +83,11 @@ public final class EventConstants {
public static final String DATA_SAVER_DETAIL_OPENED = "data_saver_overview_opened";
/**
+ * The data saver milestone promo was used (tapped).
+ */
+ public static final String DATA_SAVER_MILESTONE_PROMO_OPENED = "data_saver_milestone_promo";
+
+ /**
* The previews verbose status view was opened.
*/
public static final String PREVIEWS_VERBOSE_STATUS_OPENED = "previews_verbose_status_opened";
@@ -93,11 +98,6 @@ public final class EventConstants {
public static final String PREVIEWS_PAGE_LOADED = "preview_page_load";
/**
- * The download button for a media element was displayed.
- */
- public static final String MEDIA_DOWNLOAD_BUTTON_DISPLAYED = "media_download_button_displayed";
-
- /**
* Contextual Search panel was opened.
*/
public static final String CONTEXTUAL_SEARCH_PANEL_OPENED = "contextual_search_panel_opened";
diff --git a/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
index 8e4cd7e5ec6..b6cc8e03205 100644
--- a/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
+++ b/chromium/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -4,74 +4,101 @@
package org.chromium.components.feature_engagement;
+import android.support.annotation.StringDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* FeatureConstants contains the String name of all base::Feature in-product help features declared
* in //components/feature_engagement/public/feature_constants.h.
*/
-public final class FeatureConstants {
- public static final String DOWNLOAD_PAGE_FEATURE = "IPH_DownloadPage";
- public static final String DOWNLOAD_PAGE_SCREENSHOT_FEATURE = "IPH_DownloadPageScreenshot";
- public static final String DOWNLOAD_HOME_FEATURE = "IPH_DownloadHome";
- public static final String CHROME_DUET_FEATURE = "IPH_ChromeDuet";
- public static final String CHROME_HOME_EXPAND_FEATURE = "IPH_ChromeHomeExpand";
- public static final String CHROME_HOME_PULL_TO_REFRESH_FEATURE = "IPH_ChromeHomePullToRefresh";
- public static final String CONTEXTUAL_SUGGESTIONS_FEATURE = "IPH_ContextualSuggestions";
- public static final String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview";
- public static final String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail";
- public static final String NTP_BUTTON_FEATURE = "IPH_NewTabPageButton";
- public static final String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI";
- public static final String HOMEPAGE_TILE_FEATURE = "IPH_HomepageTile";
-
- public static final String MEDIA_DOWNLOAD_FEATURE = "IPH_MediaDownload";
-
- public static final String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton";
+@StringDef({FeatureConstants.DOWNLOAD_PAGE_FEATURE,
+ FeatureConstants.DOWNLOAD_PAGE_SCREENSHOT_FEATURE, FeatureConstants.DOWNLOAD_HOME_FEATURE,
+ FeatureConstants.CHROME_DUET_FEATURE, FeatureConstants.CHROME_HOME_EXPAND_FEATURE,
+ FeatureConstants.CHROME_HOME_PULL_TO_REFRESH_FEATURE,
+ FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE,
+ FeatureConstants.DATA_SAVER_PREVIEW_FEATURE, FeatureConstants.DATA_SAVER_DETAIL_FEATURE,
+ FeatureConstants.NTP_BUTTON_FEATURE, FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE,
+ FeatureConstants.HOMEPAGE_TILE_FEATURE, FeatureConstants.TRANSLATE_MENU_BUTTON_FEATURE,
+ FeatureConstants.CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE,
+ FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE,
+ FeatureConstants.CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE,
+ FeatureConstants.CONTEXTUAL_SEARCH_OPT_IN_FEATURE,
+ FeatureConstants.DOWNLOAD_SETTINGS_FEATURE,
+ FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE,
+ FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE,
+ FeatureConstants.TAB_GROUPS_QUICKLY_COMPARE_PAGES_FEATURE,
+ FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE,
+ FeatureConstants.TAB_GROUPS_YOUR_TABS_ARE_TOGETHER_FEATURE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface FeatureConstants {
+ String DOWNLOAD_PAGE_FEATURE = "IPH_DownloadPage";
+ String DOWNLOAD_PAGE_SCREENSHOT_FEATURE = "IPH_DownloadPageScreenshot";
+ String DOWNLOAD_HOME_FEATURE = "IPH_DownloadHome";
+ String CHROME_DUET_FEATURE = "IPH_ChromeDuet";
+ String CHROME_HOME_EXPAND_FEATURE = "IPH_ChromeHomeExpand";
+ String CHROME_HOME_PULL_TO_REFRESH_FEATURE = "IPH_ChromeHomePullToRefresh";
+ String CONTEXTUAL_SUGGESTIONS_FEATURE = "IPH_ContextualSuggestions";
+ String DATA_SAVER_PREVIEW_FEATURE = "IPH_DataSaverPreview";
+ String DATA_SAVER_DETAIL_FEATURE = "IPH_DataSaverDetail";
+ String DATA_SAVER_MILESTONE_PROMO_FEATURE = "IPH_DataSaverMilestonePromo";
+ String NTP_BUTTON_FEATURE = "IPH_NewTabPageButton";
+ String PREVIEWS_OMNIBOX_UI_FEATURE = "IPH_PreviewsOmniboxUI";
+ String HOMEPAGE_TILE_FEATURE = "IPH_HomepageTile";
+ String TRANSLATE_MENU_BUTTON_FEATURE = "IPH_TranslateMenuButton";
/**
* An IPH feature that encourages users who search a query from a web page in a new tab, to use
* Contextual Search instead.
*/
- public static final String CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE =
- "IPH_ContextualSearchWebSearch";
+ String CONTEXTUAL_SEARCH_WEB_SEARCH_FEATURE = "IPH_ContextualSearchWebSearch";
/**
* An IPH feature for promoting tap over longpress for activating Contextual Search.
*/
- public static final String CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE =
- "IPH_ContextualSearchPromoteTap";
+ String CONTEXTUAL_SEARCH_PROMOTE_TAP_FEATURE = "IPH_ContextualSearchPromoteTap";
/**
* An IPH feature for encouraging users to open the Contextual Search Panel.
*/
- public static final String CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE =
- "IPH_ContextualSearchPromotePanelOpen";
+ String CONTEXTUAL_SEARCH_PROMOTE_PANEL_OPEN_FEATURE = "IPH_ContextualSearchPromotePanelOpen";
/**
* An IPH feature for encouraging users to opt-in for Contextual Search.
*/
- public static final String CONTEXTUAL_SEARCH_OPT_IN_FEATURE = "IPH_ContextualSearchOptIn";
+ String CONTEXTUAL_SEARCH_OPT_IN_FEATURE = "IPH_ContextualSearchOptIn";
/**
* An IPH feature indicating to users that there are settings for downloads and they are
* accessible through Downloads Home.
*/
- public static final String DOWNLOAD_SETTINGS_FEATURE = "IPH_DownloadSettings";
+ String DOWNLOAD_SETTINGS_FEATURE = "IPH_DownloadSettings";
/**
* An IPH feature informing the users that even though infobar was closed, downloads are still
* continuing in the background.
*/
- public static final String DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE =
- "IPH_DownloadInfoBarDownloadContinuing";
+ String DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE = "IPH_DownloadInfoBarDownloadContinuing";
/**
* An IPH feature that points to the download progress infobar and informs users that downloads
* are now faster than before.
*/
- public static final String DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE =
- "IPH_DownloadInfoBarDownloadsAreFaster";
+ String DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_FEATURE = "IPH_DownloadInfoBarDownloadsAreFaster";
+
+ /**
+ * An IPH feature to prompt the user to long press on pages with links to open them in a group.
+ */
+ String TAB_GROUPS_QUICKLY_COMPARE_PAGES_FEATURE = "IPH_TabGroupsQuicklyComparePages";
+
+ /**
+ * An IPH feature to show when the tabstrip shows to explain what each button does.
+ */
+ String TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE = "IPH_TabGroupsTapToSeeAnotherTab";
/**
- * Do not instantiate.
+ * An IPH feature to show on tab switcher cards with multiple tab thumbnails.
*/
- private FeatureConstants() {}
+ String TAB_GROUPS_YOUR_TABS_ARE_TOGETHER_FEATURE = "IPH_TabGroupsYourTabsTogether";
}
diff --git a/chromium/components/feature_engagement/public/feature_constants.cc b/chromium/components/feature_engagement/public/feature_constants.cc
index 2a70eed40b2..6748da23e6d 100644
--- a/chromium/components/feature_engagement/public/feature_constants.cc
+++ b/chromium/components/feature_engagement/public/feature_constants.cc
@@ -17,6 +17,8 @@ const base::Feature kIPHDummyFeature{"IPH_Dummy",
#if defined(OS_ANDROID)
const base::Feature kIPHDataSaverDetailFeature{
"IPH_DataSaverDetail", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHDataSaverMilestonePromoFeature{
+ "IPH_DataSaverMilestonePromo", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHDataSaverPreviewFeature{
"IPH_DataSaverPreview", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHDownloadHomeFeature{"IPH_DownloadHome",
@@ -31,8 +33,6 @@ const base::Feature kIPHChromeHomeExpandFeature{
"IPH_ChromeHomeExpand", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHChromeHomePullToRefreshFeature{
"IPH_ChromeHomePullToRefresh", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kIPHMediaDownloadFeature{"IPH_MediaDownload",
- base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHContextualSearchWebSearchFeature{
"IPH_ContextualSearchWebSearch", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHContextualSearchPromoteTapFeature{
@@ -57,6 +57,12 @@ const base::Feature kIPHNewTabPageButtonFeature{
"IPH_NewTabPageButton", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHPreviewsOmniboxUIFeature{
"IPH_PreviewsOmniboxUI", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsQuicklyComparePagesFeature{
+ "IPH_TabGroupsQuicklyComparePages", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature{
+ "IPH_TabGroupsTapToSeeAnotherTab", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature{
+ "IPH_TabGroupsYourTabsTogether", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIPHTranslateMenuButtonFeature{
"IPH_TranslateMenuButton", base::FEATURE_ENABLED_BY_DEFAULT};
#endif // defined(OS_ANDROID)
diff --git a/chromium/components/feature_engagement/public/feature_constants.h b/chromium/components/feature_engagement/public/feature_constants.h
index 3fa6fec9bcc..865e504d718 100644
--- a/chromium/components/feature_engagement/public/feature_constants.h
+++ b/chromium/components/feature_engagement/public/feature_constants.h
@@ -22,6 +22,7 @@ extern const base::Feature kIPHDummyFeature;
// org.chromium.components.feature_engagement.FeatureConstants.
#if defined(OS_ANDROID)
extern const base::Feature kIPHDataSaverDetailFeature;
+extern const base::Feature kIPHDataSaverMilestonePromoFeature;
extern const base::Feature kIPHDataSaverPreviewFeature;
extern const base::Feature kIPHDownloadHomeFeature;
extern const base::Feature kIPHDownloadPageFeature;
@@ -29,7 +30,6 @@ extern const base::Feature kIPHDownloadPageScreenshotFeature;
extern const base::Feature kIPHChromeDuetFeature;
extern const base::Feature kIPHChromeHomeExpandFeature;
extern const base::Feature kIPHChromeHomePullToRefreshFeature;
-extern const base::Feature kIPHMediaDownloadFeature;
extern const base::Feature kIPHContextualSearchWebSearchFeature;
extern const base::Feature kIPHContextualSearchPromoteTapFeature;
extern const base::Feature kIPHContextualSearchPromotePanelOpenFeature;
@@ -42,6 +42,9 @@ extern const base::Feature kIPHHomePageButtonFeature;
extern const base::Feature kIPHHomepageTileFeature;
extern const base::Feature kIPHNewTabPageButtonFeature;
extern const base::Feature kIPHPreviewsOmniboxUIFeature;
+extern const base::Feature kIPHTabGroupsQuicklyComparePagesFeature;
+extern const base::Feature kIPHTabGroupsTapToSeeAnotherTabFeature;
+extern const base::Feature kIPHTabGroupsYourTabsAreTogetherFeature;
extern const base::Feature kIPHTranslateMenuButtonFeature;
#endif // defined(OS_ANDROID)
diff --git a/chromium/components/feature_engagement/public/feature_list.cc b/chromium/components/feature_engagement/public/feature_list.cc
index 0d53df5cca0..5dbeefccf9b 100644
--- a/chromium/components/feature_engagement/public/feature_list.cc
+++ b/chromium/components/feature_engagement/public/feature_list.cc
@@ -18,6 +18,7 @@ const base::Feature* const kAllFeatures[] = {
&kIPHDummyFeature, // Ensures non-empty array for all platforms.
#if defined(OS_ANDROID)
&kIPHDataSaverDetailFeature,
+ &kIPHDataSaverMilestonePromoFeature,
&kIPHDataSaverPreviewFeature,
&kIPHDownloadHomeFeature,
&kIPHDownloadPageFeature,
@@ -25,7 +26,6 @@ const base::Feature* const kAllFeatures[] = {
&kIPHChromeDuetFeature,
&kIPHChromeHomeExpandFeature,
&kIPHChromeHomePullToRefreshFeature,
- &kIPHMediaDownloadFeature,
&kIPHContextualSearchWebSearchFeature,
&kIPHContextualSearchPromoteTapFeature,
&kIPHContextualSearchPromotePanelOpenFeature,
@@ -38,6 +38,9 @@ const base::Feature* const kAllFeatures[] = {
&kIPHHomepageTileFeature,
&kIPHNewTabPageButtonFeature,
&kIPHPreviewsOmniboxUIFeature,
+ &kIPHTabGroupsQuicklyComparePagesFeature,
+ &kIPHTabGroupsTapToSeeAnotherTabFeature,
+ &kIPHTabGroupsYourTabsAreTogetherFeature,
&kIPHTranslateMenuButtonFeature,
#endif // defined(OS_ANDROID)
#if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
diff --git a/chromium/components/feature_engagement/public/feature_list.h b/chromium/components/feature_engagement/public/feature_list.h
index b444357c2e3..ae85b1a51ef 100644
--- a/chromium/components/feature_engagement/public/feature_list.h
+++ b/chromium/components/feature_engagement/public/feature_list.h
@@ -48,6 +48,8 @@ namespace {
DEFINE_VARIATION_PARAM(kIPHDummyFeature, "IPH_Dummy");
#if defined(OS_ANDROID)
DEFINE_VARIATION_PARAM(kIPHDataSaverDetailFeature, "IPH_DataSaverDetail");
+DEFINE_VARIATION_PARAM(kIPHDataSaverMilestonePromoFeature,
+ "IPH_DataSaverMilestonePromo");
DEFINE_VARIATION_PARAM(kIPHDataSaverPreviewFeature, "IPH_DataSaverPreview");
DEFINE_VARIATION_PARAM(kIPHDownloadHomeFeature, "IPH_DownloadHome");
DEFINE_VARIATION_PARAM(kIPHDownloadPageFeature, "IPH_DownloadPage");
@@ -57,7 +59,6 @@ DEFINE_VARIATION_PARAM(kIPHChromeDuetFeature, "IPH_ChromeDuet");
DEFINE_VARIATION_PARAM(kIPHChromeHomeExpandFeature, "IPH_ChromeHomeExpand");
DEFINE_VARIATION_PARAM(kIPHChromeHomePullToRefreshFeature,
"IPH_ChromeHomePullToRefresh");
-DEFINE_VARIATION_PARAM(kIPHMediaDownloadFeature, "IPH_MediaDownload");
DEFINE_VARIATION_PARAM(kIPHContextualSearchWebSearchFeature,
"IPH_ContextualSearchWebSearch");
DEFINE_VARIATION_PARAM(kIPHContextualSearchPromoteTapFeature,
@@ -77,6 +78,12 @@ DEFINE_VARIATION_PARAM(kIPHHomePageButtonFeature, "IPH_HomePageButton");
DEFINE_VARIATION_PARAM(kIPHHomepageTileFeature, "IPH_HomepageTile");
DEFINE_VARIATION_PARAM(kIPHNewTabPageButtonFeature, "IPH_NewTabPageButton");
DEFINE_VARIATION_PARAM(kIPHPreviewsOmniboxUIFeature, "IPH_PreviewsOmniboxUI");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsQuicklyComparePagesFeature,
+ "IPH_TabGroupsQuicklyComparePages");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsTapToSeeAnotherTabFeature,
+ "IPH_TabGroupsTapToSeeAnotherTab");
+DEFINE_VARIATION_PARAM(kIPHTabGroupsYourTabsAreTogetherFeature,
+ "IPH_TabGroupsYourTabsTogether");
DEFINE_VARIATION_PARAM(kIPHTranslateMenuButtonFeature,
"IPH_TranslateMenuButton");
#endif // defined(OS_ANDROID)
@@ -104,6 +111,7 @@ constexpr flags_ui::FeatureEntry::FeatureVariation
kIPHDemoModeChoiceVariations[] = {
#if defined(OS_ANDROID)
VARIATION_ENTRY(kIPHDataSaverDetailFeature),
+ VARIATION_ENTRY(kIPHDataSaverMilestonePromoFeature),
VARIATION_ENTRY(kIPHDataSaverPreviewFeature),
VARIATION_ENTRY(kIPHDownloadHomeFeature),
VARIATION_ENTRY(kIPHDownloadPageFeature),
@@ -111,7 +119,6 @@ constexpr flags_ui::FeatureEntry::FeatureVariation
VARIATION_ENTRY(kIPHChromeDuetFeature),
VARIATION_ENTRY(kIPHChromeHomeExpandFeature),
VARIATION_ENTRY(kIPHChromeHomePullToRefreshFeature),
- VARIATION_ENTRY(kIPHMediaDownloadFeature),
VARIATION_ENTRY(kIPHContextualSearchWebSearchFeature),
VARIATION_ENTRY(kIPHContextualSearchPromoteTapFeature),
VARIATION_ENTRY(kIPHContextualSearchPromotePanelOpenFeature),
@@ -124,6 +131,9 @@ constexpr flags_ui::FeatureEntry::FeatureVariation
VARIATION_ENTRY(kIPHHomepageTileFeature),
VARIATION_ENTRY(kIPHNewTabPageButtonFeature),
VARIATION_ENTRY(kIPHPreviewsOmniboxUIFeature),
+ VARIATION_ENTRY(kIPHTabGroupsQuicklyComparePagesFeature),
+ VARIATION_ENTRY(kIPHTabGroupsTapToSeeAnotherTabFeature),
+ VARIATION_ENTRY(kIPHTabGroupsYourTabsAreTogetherFeature),
VARIATION_ENTRY(kIPHTranslateMenuButtonFeature),
#elif BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP)
VARIATION_ENTRY(kIPHBookmarkFeature),
diff --git a/chromium/components/feed/OWNERS b/chromium/components/feed/OWNERS
index 90e498d6f46..2efa28a3bd3 100644
--- a/chromium/components/feed/OWNERS
+++ b/chromium/components/feed/OWNERS
@@ -4,6 +4,5 @@ pnoland@chromium.org
skym@chromium.org
zea@chromium.org
-per-file *Test.java=aluo@chromium.org
# Team: chrome-jardin-team@google.com
# COMPONENT: UI>Browser>ContentSuggestions>Feed
diff --git a/chromium/components/feed/content/feed_host_service.cc b/chromium/components/feed/content/feed_host_service.cc
index d90e7f201ff..91ee7949cbe 100644
--- a/chromium/components/feed/content/feed_host_service.cc
+++ b/chromium/components/feed/content/feed_host_service.cc
@@ -10,14 +10,12 @@ namespace feed {
FeedHostService::FeedHostService(
std::unique_ptr<FeedLoggingMetrics> logging_metrics,
- std::unique_ptr<FeedImageManager> image_manager,
std::unique_ptr<FeedNetworkingHost> networking_host,
std::unique_ptr<FeedSchedulerHost> scheduler_host,
std::unique_ptr<FeedContentDatabase> content_database,
std::unique_ptr<FeedJournalDatabase> journal_database,
std::unique_ptr<FeedOfflineHost> offline_host)
: logging_metrics_(std::move(logging_metrics)),
- image_manager_(std::move(image_manager)),
networking_host_(std::move(networking_host)),
scheduler_host_(std::move(scheduler_host)),
content_database_(std::move(content_database)),
@@ -26,10 +24,6 @@ FeedHostService::FeedHostService(
FeedHostService::~FeedHostService() = default;
-FeedImageManager* FeedHostService::GetImageManager() {
- return image_manager_.get();
-}
-
FeedNetworkingHost* FeedHostService::GetNetworkingHost() {
return networking_host_.get();
}
diff --git a/chromium/components/feed/content/feed_host_service.h b/chromium/components/feed/content/feed_host_service.h
index bae43d5a577..0550994f6bd 100644
--- a/chromium/components/feed/content/feed_host_service.h
+++ b/chromium/components/feed/content/feed_host_service.h
@@ -10,7 +10,6 @@
#include "base/macros.h"
#include "components/feed/content/feed_offline_host.h"
#include "components/feed/core/feed_content_database.h"
-#include "components/feed/core/feed_image_manager.h"
#include "components/feed/core/feed_journal_database.h"
#include "components/feed/core/feed_logging_metrics.h"
#include "components/feed/core/feed_networking_host.h"
@@ -27,7 +26,6 @@ namespace feed {
class FeedHostService : public KeyedService {
public:
FeedHostService(std::unique_ptr<FeedLoggingMetrics> logging_metrics,
- std::unique_ptr<FeedImageManager> image_manager,
std::unique_ptr<FeedNetworkingHost> networking_host,
std::unique_ptr<FeedSchedulerHost> scheduler_host,
std::unique_ptr<FeedContentDatabase> content_database,
@@ -36,7 +34,6 @@ class FeedHostService : public KeyedService {
~FeedHostService() override;
FeedLoggingMetrics* GetLoggingMetrics();
- FeedImageManager* GetImageManager();
FeedNetworkingHost* GetNetworkingHost();
FeedSchedulerHost* GetSchedulerHost();
FeedContentDatabase* GetContentDatabase();
@@ -45,7 +42,6 @@ class FeedHostService : public KeyedService {
private:
std::unique_ptr<FeedLoggingMetrics> logging_metrics_;
- std::unique_ptr<FeedImageManager> image_manager_;
std::unique_ptr<FeedNetworkingHost> networking_host_;
std::unique_ptr<FeedSchedulerHost> scheduler_host_;
std::unique_ptr<FeedContentDatabase> content_database_;
diff --git a/chromium/components/feed/content/feed_offline_host.cc b/chromium/components/feed/content/feed_offline_host.cc
index b47ebda1606..d1b0dfd9da6 100644
--- a/chromium/components/feed/content/feed_offline_host.cc
+++ b/chromium/components/feed/content/feed_offline_host.cc
@@ -25,12 +25,6 @@ using offline_pages::SuggestionsProvider;
namespace {
-// |url| is always set. Sometimes |original_url| is set. If |original_url| is
-// set it is returned by this method, otherwise fall back to |url|.
-const GURL& PreferOriginal(const OfflinePageItem& item) {
- return item.original_url.is_empty() ? item.url : item.original_url;
-}
-
// Aggregates multiple callbacks from OfflinePageModel, storing the offline url.
// When all callbacks have been invoked, tracked by ref counting, then
// |on_completeion_| is finally invoked, sending all results together.
@@ -255,7 +249,7 @@ void FeedOfflineHost::OfflinePageModelLoaded(OfflinePageModel* model) {
void FeedOfflineHost::OfflinePageAdded(OfflinePageModel* model,
const OfflinePageItem& added_page) {
DCHECK(!notify_status_change_.is_null());
- const std::string& url = PreferOriginal(added_page).spec();
+ const std::string& url = added_page.GetOriginalUrl().spec();
CacheOfflinePageUrlAndId(url, added_page.offline_id);
notify_status_change_.Run(url, true);
}
diff --git a/chromium/components/feed/content/feed_offline_host_unittest.cc b/chromium/components/feed/content/feed_offline_host_unittest.cc
index 6d03c1354c7..d2e052ffaa8 100644
--- a/chromium/components/feed/content/feed_offline_host_unittest.cc
+++ b/chromium/components/feed/content/feed_offline_host_unittest.cc
@@ -57,7 +57,7 @@ class TestOfflinePageModel : public StubOfflinePageModel {
std::string name_space) {
OfflinePageItem item;
item.url = GURL(url);
- item.original_url = GURL(original_url);
+ item.original_url_if_different = GURL(original_url);
item.offline_id = offline_id;
item.creation_time = creation_time;
item.client_id = offline_pages::ClientId(name_space, "");
@@ -373,7 +373,7 @@ TEST_F(FeedOfflineHostTest, GetCurrentArticleSuggestionsMultiple) {
TEST_F(FeedOfflineHostTest, OfflinePageAdded) {
OfflinePageItem added_page;
added_page.url = GURL(kUrl1);
- added_page.original_url = GURL(kUrl2);
+ added_page.original_url_if_different = GURL(kUrl2);
added_page.offline_id = 4;
host()->OfflinePageAdded(nullptr, added_page);
diff --git a/chromium/components/feed/core/BUILD.gn b/chromium/components/feed/core/BUILD.gn
index 68e34e068bb..4d7b5a36a2f 100644
--- a/chromium/components/feed/core/BUILD.gn
+++ b/chromium/components/feed/core/BUILD.gn
@@ -16,10 +16,6 @@ source_set("feed_core") {
"feed_content_mutation.h",
"feed_content_operation.cc",
"feed_content_operation.h",
- "feed_image_database.cc",
- "feed_image_database.h",
- "feed_image_manager.cc",
- "feed_image_manager.h",
"feed_journal_database.cc",
"feed_journal_database.h",
"feed_journal_mutation.cc",
@@ -46,7 +42,6 @@ source_set("feed_core") {
"//base",
"//components/feed:feature_list",
"//components/feed/core/proto",
- "//components/image_fetcher/core:core",
"//components/leveldb_proto",
"//net",
"//ui/base/mojo:mojo",
@@ -80,8 +75,6 @@ source_set("core_unit_tests") {
sources = [
"feed_content_database_unittest.cc",
"feed_content_mutation_unittest.cc",
- "feed_image_database_unittest.cc",
- "feed_image_manager_unittest.cc",
"feed_journal_database_unittest.cc",
"feed_journal_mutation_unittest.cc",
"feed_logging_metrics_unittest.cc",
diff --git a/chromium/components/feed/core/feed_content_database.cc b/chromium/components/feed/core/feed_content_database.cc
index 7e06660d433..a9b760aa1e4 100644
--- a/chromium/components/feed/core/feed_content_database.cc
+++ b/chromium/components/feed/core/feed_content_database.cc
@@ -36,6 +36,12 @@ const char kContentDatabaseFolder[] = "content";
const size_t kDatabaseWriteBufferSizeBytes = 64 * 1024; // 64KB
const size_t kDatabaseWriteBufferSizeBytesForLowEndDevice = 32 * 1024; // 32KB
+leveldb::ReadOptions CreateReadOptions() {
+ leveldb::ReadOptions opts;
+ opts.fill_cache = false;
+ return opts;
+}
+
bool DatabaseKeyFilter(const std::unordered_set<std::string>& key_set,
const std::string& key) {
return key_set.find(key) != key_set.end();
@@ -97,6 +103,7 @@ void FeedContentDatabase::LoadContent(const std::vector<std::string>& keys,
storage_database_->LoadEntriesWithFilter(
base::BindRepeating(&DatabaseKeyFilter, std::move(key_set)),
+ CreateReadOptions(), /* target_prefix */ "",
base::BindOnce(&FeedContentDatabase::OnLoadEntriesForLoadContent,
weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
std::move(callback)));
@@ -108,6 +115,7 @@ void FeedContentDatabase::LoadContentByPrefix(const std::string& prefix,
storage_database_->LoadEntriesWithFilter(
base::BindRepeating(&DatabasePrefixFilter, std::move(prefix)),
+ CreateReadOptions(), /* target_prefix */ "",
base::BindOnce(&FeedContentDatabase::OnLoadEntriesForLoadContent,
weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(),
std::move(callback)));
diff --git a/chromium/components/feed/core/feed_content_database_unittest.cc b/chromium/components/feed/core/feed_content_database_unittest.cc
index aa662291b44..3a8a6a06738 100644
--- a/chromium/components/feed/core/feed_content_database_unittest.cc
+++ b/chromium/components/feed/core/feed_content_database_unittest.cc
@@ -6,6 +6,7 @@
#include <map>
+#include "base/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "components/feed/core/feed_content_mutation.h"
diff --git a/chromium/components/feed/core/feed_image_database.cc b/chromium/components/feed/core/feed_image_database.cc
deleted file mode 100644
index 57601876e2e..00000000000
--- a/chromium/components/feed/core/feed_image_database.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_image_database.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/sequenced_task_runner.h"
-#include "base/system/sys_info.h"
-#include "base/task/post_task.h"
-#include "base/task/task_traits.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/clock.h"
-#include "base/time/default_clock.h"
-#include "base/time/time.h"
-#include "components/feed/core/proto/cached_image.pb.h"
-#include "components/feed/core/time_serialization.h"
-#include "components/leveldb_proto/public/proto_database_provider.h"
-
-namespace feed {
-
-namespace {
-// Statistics are logged to UMA with this string as part of histogram name. They
-// can all be found under LevelDB.*.FeedImageDatabase. Changing this needs to
-// synchronize with histograms.xml, AND will also become incompatible with older
-// browsers still reporting the previous values.
-const char kImageDatabaseUMAClientName[] = "FeedImageDatabase";
-
-const char kImageDatabaseFolder[] = "images";
-
-const size_t kDatabaseWriteBufferSizeBytes = 512 * 1024;
-const size_t kDatabaseWriteBufferSizeBytesForLowEndDevice = 128 * 1024;
-} // namespace
-
-FeedImageDatabase::FeedImageDatabase(const base::FilePath& database_dir)
- : FeedImageDatabase(
- database_dir,
- leveldb_proto::ProtoDatabaseProvider::CreateUniqueDB<
- CachedImageProto>(base::CreateSequencedTaskRunnerWithTraits(
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
- base::DefaultClock::GetInstance()) {}
-
-FeedImageDatabase::FeedImageDatabase(
- const base::FilePath& database_dir,
- std::unique_ptr<leveldb_proto::ProtoDatabase<CachedImageProto>>
- image_database,
- base::Clock* clock)
- : database_status_(UNINITIALIZED),
- image_database_(std::move(image_database)),
- clock_(clock),
- weak_ptr_factory_(this) {
- leveldb_env::Options options = leveldb_proto::CreateSimpleOptions();
- if (base::SysInfo::IsLowEndDevice()) {
- options.write_buffer_size = kDatabaseWriteBufferSizeBytesForLowEndDevice;
- } else {
- options.write_buffer_size = kDatabaseWriteBufferSizeBytes;
- }
- base::FilePath image_dir = database_dir.AppendASCII(kImageDatabaseFolder);
- image_database_->Init(
- kImageDatabaseUMAClientName, image_dir, options,
- base::BindOnce(&FeedImageDatabase::OnDatabaseInitialized,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-FeedImageDatabase::~FeedImageDatabase() = default;
-
-bool FeedImageDatabase::IsInitialized() {
- return INITIALIZED == database_status_;
-}
-
-void FeedImageDatabase::SaveImage(const std::string& url,
- const std::string& image_data) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // If database is not ready, ignore the request.
- if (!IsInitialized())
- return;
-
- CachedImageProto image_proto;
- image_proto.set_url(url);
- image_proto.set_data(image_data);
- image_proto.set_last_used_time(ToDatabaseTime(clock_->Now()));
-
- SaveImageImpl(url, image_proto);
-}
-
-void FeedImageDatabase::LoadImage(const std::string& url,
- FeedImageDatabaseCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- switch (database_status_) {
- case INITIALIZED:
- case INIT_FAILURE:
- LoadImageImpl(url, std::move(callback));
- break;
- case UNINITIALIZED:
- pending_image_callbacks_.emplace_back(url, std::move(callback));
- break;
- default:
- NOTREACHED();
- }
-}
-
-void FeedImageDatabase::DeleteImage(const std::string& url) {
- DeleteImageImpl(url, base::BindOnce(&FeedImageDatabase::OnImageUpdated,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void FeedImageDatabase::GarbageCollectImages(
- base::Time expired_time,
- FeedImageDatabaseOperationCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // If database is not initialized yet, ignore the request.
- if (!IsInitialized()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), false));
- return;
- }
-
- image_database_->LoadEntries(base::BindOnce(
- &FeedImageDatabase::GarbageCollectImagesImpl,
- weak_ptr_factory_.GetWeakPtr(), expired_time, std::move(callback)));
-}
-
-void FeedImageDatabase::OnDatabaseInitialized(bool success) {
- DCHECK_EQ(database_status_, UNINITIALIZED);
-
- if (success) {
- database_status_ = INITIALIZED;
- } else {
- database_status_ = INIT_FAILURE;
- DVLOG(1) << "FeedImageDatabase init failed.";
- }
-
- ProcessPendingImageLoads();
-}
-
-void FeedImageDatabase::ProcessPendingImageLoads() {
- DCHECK_NE(database_status_, UNINITIALIZED);
-
- for (auto& image_callback : pending_image_callbacks_)
- LoadImageImpl(image_callback.first, std::move(image_callback.second));
-
- pending_image_callbacks_.clear();
-}
-
-void FeedImageDatabase::SaveImageImpl(std::string url,
- const CachedImageProto& image_proto) {
- auto entries_to_save = std::make_unique<ImageKeyEntryVector>();
- entries_to_save->emplace_back(std::move(url), image_proto);
-
- image_database_->UpdateEntries(
- std::move(entries_to_save), std::make_unique<std::vector<std::string>>(),
- base::BindOnce(&FeedImageDatabase::OnImageUpdated,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void FeedImageDatabase::OnImageLoaded(std::string url,
- FeedImageDatabaseCallback callback,
- bool success,
- std::unique_ptr<CachedImageProto> entry) {
- if (!success || !entry) {
- DVLOG_IF(1, !success) << "FeedImageDatabase load failed.";
- std::move(callback).Run(std::string());
- return;
- }
-
- DCHECK_EQ(url, entry->url());
- std::move(callback).Run(entry->data());
-
- // Update timestamp for image.
- entry->set_last_used_time(ToDatabaseTime(clock_->Now()));
- SaveImageImpl(std::move(url), *entry);
-}
-
-void FeedImageDatabase::LoadImageImpl(const std::string& url,
- FeedImageDatabaseCallback callback) {
- DCHECK_NE(database_status_, UNINITIALIZED);
-
- if (IsInitialized()) {
- image_database_->GetEntry(
- url, base::BindOnce(&FeedImageDatabase::OnImageLoaded,
- weak_ptr_factory_.GetWeakPtr(), url,
- std::move(callback)));
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::string()));
- }
-}
-
-void FeedImageDatabase::OnImageUpdated(bool success) {
- DVLOG_IF(1, !success) << "FeedImageDatabase update failed.";
-}
-
-void FeedImageDatabase::DeleteImageImpl(
- const std::string& url,
- FeedImageDatabaseOperationCallback callback) {
- image_database_->UpdateEntries(
- std::make_unique<ImageKeyEntryVector>(),
- std::make_unique<std::vector<std::string>>(1, url), std::move(callback));
-}
-
-void FeedImageDatabase::GarbageCollectImagesImpl(
- base::Time expired_time,
- FeedImageDatabaseOperationCallback callback,
- bool load_entries_success,
- std::unique_ptr<std::vector<CachedImageProto>> image_entries) {
- if (!load_entries_success) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&FeedImageDatabase::OnGarbageCollectionDone,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(callback), false));
- return;
- }
-
- int64_t expired_database_time = ToDatabaseTime(expired_time);
- auto keys_to_remove = std::make_unique<std::vector<std::string>>();
- for (const CachedImageProto& image : *image_entries) {
- if (image.last_used_time() < expired_database_time) {
- keys_to_remove->emplace_back(image.url());
- }
- }
-
- if (keys_to_remove->empty()) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), true));
- return;
- }
-
- image_database_->UpdateEntries(
- std::make_unique<ImageKeyEntryVector>(), std::move(keys_to_remove),
- base::BindOnce(&FeedImageDatabase::OnGarbageCollectionDone,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void FeedImageDatabase::OnGarbageCollectionDone(
- FeedImageDatabaseOperationCallback callback,
- bool success) {
- DVLOG_IF(1, !success) << "FeedImageDatabase garbage collection failed.";
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), success));
-}
-
-} // namespace feed
diff --git a/chromium/components/feed/core/feed_image_database.h b/chromium/components/feed/core/feed_image_database.h
deleted file mode 100644
index 90c8a39ecc5..00000000000
--- a/chromium/components/feed/core/feed_image_database.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_IMAGE_DATABASE_H_
-#define COMPONENTS_FEED_CORE_FEED_IMAGE_DATABASE_H_
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "components/leveldb_proto/public/proto_database.h"
-
-namespace base {
-class Clock;
-} // namespace base
-
-namespace feed {
-
-class CachedImageProto;
-
-// FeedImageDatabase is leveldb backed store for feed's image data.
-// FeedImageDatabase keeps images identified by URLs.
-// Save and Load operations are asynchronous, every load operation will update
-// last_used_time for the image for garbage collection purpose.
-class FeedImageDatabase {
- public:
- enum State {
- UNINITIALIZED,
- INITIALIZED,
- INIT_FAILURE,
- };
-
- // Returns the resulting raw image data as std::string of a |LoadImage| call.
- using FeedImageDatabaseCallback =
- base::OnceCallback<void(const std::string&)>;
-
- using FeedImageDatabaseOperationCallback = base::OnceCallback<void(bool)>;
-
- // Initializes the database with |database_dir|.
- explicit FeedImageDatabase(const base::FilePath& database_dir);
- // Initializes the database with |database_dir|. Creates storage using the
- // given |image_database| for local storage. Useful for testing.
- FeedImageDatabase(
- const base::FilePath& database_dir,
- std::unique_ptr<leveldb_proto::ProtoDatabase<CachedImageProto>>
- image_database,
- base::Clock* clock);
- ~FeedImageDatabase();
-
- // Returns true if initialization has finished successfully, else false.
- // While this is false, initialization may already started, or initialization
- // failed.
- bool IsInitialized();
-
- // Adds or updates the image data for the |url|.
- // If the database is not initialized or in some error status, the call will
- // be ignored.
- void SaveImage(const std::string& url, const std::string& image_data);
-
- // Loads the image data for the |url| and passes it to |callback|.
- // |callback| will be called in the same thread as this function called.
- // If the image cannot be found in database, or database error, returns an
- // empty CachedImageProto. If the database is not initialized yet, the
- // request will be pending until the database has been initialized.
- void LoadImage(const std::string& url, FeedImageDatabaseCallback callback);
-
- // Deletes the image data for the |url|.
- void DeleteImage(const std::string& url);
-
- // Delete all images whose |last_used_time| is older than |expired_time| and
- // passes the result to |callback|. |callback| will be called in the same
- // thread as this function called. If database is not initialized, or failed
- // to delete expired entry, false will be passed to |callback|.
- void GarbageCollectImages(base::Time expired_time,
- FeedImageDatabaseOperationCallback callback);
-
- private:
- friend class FeedImageDatabaseTest;
-
- using ImageKeyEntryVector =
- leveldb_proto::ProtoDatabase<CachedImageProto>::KeyEntryVector;
-
- // Initialization
- void OnDatabaseInitialized(bool success);
- void ProcessPendingImageLoads();
-
- // Saving
- void SaveImageImpl(std::string url, const CachedImageProto& image_proto);
- void OnImageUpdated(bool success);
-
- // Loading
- void LoadImageImpl(const std::string& url,
- FeedImageDatabaseCallback callback);
- void OnImageLoaded(std::string url,
- FeedImageDatabaseCallback callback,
- bool success,
- std::unique_ptr<CachedImageProto> entry);
-
- // Deleting
- void DeleteImageImpl(const std::string& url,
- FeedImageDatabaseOperationCallback callback);
-
- // Garbage collection
- void GarbageCollectImagesImpl(
- base::Time expired_time,
- FeedImageDatabaseOperationCallback callback,
- bool load_entries_success,
- std::unique_ptr<std::vector<CachedImageProto>> image_entries);
- void OnGarbageCollectionDone(FeedImageDatabaseOperationCallback callback,
- bool success);
-
- State database_status_;
-
- std::unique_ptr<leveldb_proto::ProtoDatabase<CachedImageProto>>
- image_database_;
-
- // Used to access current time, injected for testing.
- base::Clock* clock_;
-
- std::vector<std::pair<std::string, FeedImageDatabaseCallback>>
- pending_image_callbacks_;
-
- // Used to check that functions are called on the correct sequence.
- SEQUENCE_CHECKER(sequence_checker_);
-
- base::WeakPtrFactory<FeedImageDatabase> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FeedImageDatabase);
-};
-
-} // namespace feed
-
-#endif // COMPONENTS_FEED_CORE_FEED_IMAGE_DATABASE_H_
diff --git a/chromium/components/feed/core/feed_image_database_unittest.cc b/chromium/components/feed/core/feed_image_database_unittest.cc
deleted file mode 100644
index 340b8fe19bc..00000000000
--- a/chromium/components/feed/core/feed_image_database_unittest.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_image_database.h"
-
-#include <map>
-
-#include "base/test/scoped_task_environment.h"
-#include "base/test/simple_test_clock.h"
-#include "components/feed/core/proto/cached_image.pb.h"
-#include "components/feed/core/time_serialization.h"
-#include "components/leveldb_proto/testing/fake_db.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using leveldb_proto::test::FakeDB;
-using testing::Mock;
-using testing::_;
-
-namespace feed {
-
-namespace {
-
-// Fixed "now" to make tests more deterministic.
-char kNowString[] = "2018-06-11 15:41";
-
-constexpr char kImageURL[] = "http://pie.com/";
-constexpr char kImageData[] = "pie image";
-
-} // namespace
-
-class FeedImageDatabaseTest : public testing::Test {
- public:
- FeedImageDatabaseTest() : image_db_(nullptr) {
- base::Time now;
- EXPECT_TRUE(base::Time::FromUTCString(kNowString, &now));
- test_clock_.SetNow(now);
- }
-
- void CreateDatabase() {
- // The FakeDBs are owned by |feed_db_|, so clear our pointers before
- // resetting |feed_db_| itself.
- image_db_ = nullptr;
- // Explicitly destroy any existing database before creating a new one.
- feed_db_.reset();
-
- auto image_db =
- std::make_unique<FakeDB<CachedImageProto>>(&image_db_storage_);
-
- image_db_ = image_db.get();
- feed_db_ = std::make_unique<FeedImageDatabase>(
- base::FilePath(), std::move(image_db), &test_clock_);
- }
-
- int64_t GetImageLastUsedTime(const std::string& url) {
- return image_db_storage_[kImageURL].last_used_time();
- }
-
- void InjectImageProto(const std::string& url,
- const std::string& data,
- base::Time time) {
- CachedImageProto image_proto;
- image_proto.set_url(url);
- image_proto.set_data(data);
- image_proto.set_last_used_time(ToDatabaseTime(time));
- image_db_storage_[url] = image_proto;
- }
-
- FakeDB<CachedImageProto>* image_db() { return image_db_; }
- FeedImageDatabase* db() { return feed_db_.get(); }
- base::SimpleTestClock* test_clock() { return &test_clock_; }
-
- void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
-
- MOCK_METHOD1(OnImageLoaded, void(const std::string&));
- MOCK_METHOD1(OnGarbageCollected, void(bool));
-
- private:
- base::test::ScopedTaskEnvironment scoped_task_environment_;
-
- std::map<std::string, CachedImageProto> image_db_storage_;
-
- // Owned by |feed_db_|.
- FakeDB<CachedImageProto>* image_db_;
-
- base::SimpleTestClock test_clock_;
-
- std::unique_ptr<FeedImageDatabase> feed_db_;
-
- DISALLOW_COPY_AND_ASSIGN(FeedImageDatabaseTest);
-};
-
-TEST_F(FeedImageDatabaseTest, Init) {
- ASSERT_FALSE(db());
-
- CreateDatabase();
- EXPECT_FALSE(db()->IsInitialized());
-
- image_db()->InitCallback(true);
-
- EXPECT_TRUE(db()->IsInitialized());
-}
-
-TEST_F(FeedImageDatabaseTest, LoadBeforeInitSuccess) {
- CreateDatabase();
- EXPECT_FALSE(db()->IsInitialized());
-
- // Start an image load before the database is initialized.
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
-
- EXPECT_CALL(*this, OnImageLoaded(_));
-
- image_db()->InitCallback(true);
- EXPECT_TRUE(db()->IsInitialized());
- image_db()->GetCallback(true);
-}
-
-TEST_F(FeedImageDatabaseTest, LoadBeforeInitFailed) {
- CreateDatabase();
- EXPECT_FALSE(db()->IsInitialized());
-
- // Start an image load before the database is initialized.
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
-
- EXPECT_CALL(*this, OnImageLoaded(_));
-
- image_db()->InitCallback(false);
- EXPECT_FALSE(db()->IsInitialized());
- RunUntilIdle();
-}
-
-TEST_F(FeedImageDatabaseTest, LoadAfterInitSuccess) {
- CreateDatabase();
- EXPECT_FALSE(db()->IsInitialized());
-
- EXPECT_CALL(*this, OnImageLoaded(_)).Times(0);
-
- image_db()->InitCallback(true);
- EXPECT_TRUE(db()->IsInitialized());
-
- Mock::VerifyAndClearExpectations(this);
-
- EXPECT_CALL(*this, OnImageLoaded(_));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-}
-
-TEST_F(FeedImageDatabaseTest, LoadAfterInitFailed) {
- CreateDatabase();
- EXPECT_FALSE(db()->IsInitialized());
-
- EXPECT_CALL(*this, OnImageLoaded(_)).Times(0);
-
- image_db()->InitCallback(false);
- EXPECT_FALSE(db()->IsInitialized());
-
- Mock::VerifyAndClearExpectations(this);
-
- EXPECT_CALL(*this, OnImageLoaded(_));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- RunUntilIdle();
-}
-
-TEST_F(FeedImageDatabaseTest, Save) {
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- // Store an image.
- db()->SaveImage(kImageURL, kImageData);
- image_db()->UpdateCallback(true);
-
- // Make sure they're there.
- EXPECT_CALL(*this, OnImageLoaded(kImageData));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-}
-
-TEST_F(FeedImageDatabaseTest, SavePersist) {
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- // Store an image.
- db()->SaveImage(kImageURL, kImageData);
- image_db()->UpdateCallback(true);
-
- // They should still exist after recreating the database.
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- EXPECT_CALL(*this, OnImageLoaded(kImageData));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-}
-
-TEST_F(FeedImageDatabaseTest, LoadUpdatesTime) {
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- // Store an image.
- InjectImageProto(kImageURL, kImageData, base::Time::UnixEpoch());
-
- int64_t old_time = GetImageLastUsedTime(kImageURL);
- // Make sure they're there.
- EXPECT_CALL(*this, OnImageLoaded(kImageData));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
- image_db()->UpdateCallback(true);
- EXPECT_TRUE(old_time != GetImageLastUsedTime(kImageURL));
-}
-
-TEST_F(FeedImageDatabaseTest, Delete) {
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- // Store the image.
- db()->SaveImage(kImageURL, kImageData);
- image_db()->UpdateCallback(true);
-
- // Make sure the image is there.
- EXPECT_CALL(*this, OnImageLoaded(kImageData));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-
- Mock::VerifyAndClearExpectations(this);
-
- // Delete the image.
- db()->DeleteImage(kImageURL);
- image_db()->UpdateCallback(true);
-
- // Make sure the image is gone.
- EXPECT_CALL(*this, OnImageLoaded(std::string()));
- db()->LoadImage(kImageURL,
- base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-}
-
-TEST_F(FeedImageDatabaseTest, GarbageCollectImagesTest) {
- CreateDatabase();
- image_db()->InitCallback(true);
- ASSERT_TRUE(db()->IsInitialized());
-
- base::Time now = test_clock()->Now();
- base::Time expired_time = now - base::TimeDelta::FromDays(30);
- base::Time very_old_time = now - base::TimeDelta::FromDays(100);
-
- // Store images.
- InjectImageProto("url1", "data1", very_old_time);
- InjectImageProto("url2", "data2", now);
- InjectImageProto("url3", "data3", very_old_time);
-
- // Garbage collect all except the second.
- EXPECT_CALL(*this, OnGarbageCollected(true));
- db()->GarbageCollectImages(
- expired_time, base::BindOnce(&FeedImageDatabaseTest::OnGarbageCollected,
- base::Unretained(this)));
- // This will first load all images, then delete the expired ones.
- image_db()->LoadCallback(true);
- image_db()->UpdateCallback(true);
- RunUntilIdle();
-
- // Make sure the images are gone.
- EXPECT_CALL(*this, OnImageLoaded(std::string()));
- db()->LoadImage("url1", base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-
- EXPECT_CALL(*this, OnImageLoaded(std::string()));
- db()->LoadImage("url3", base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-
- // Make sure the second still exists.
- EXPECT_CALL(*this, OnImageLoaded("data2"));
- db()->LoadImage("url2", base::BindOnce(&FeedImageDatabaseTest::OnImageLoaded,
- base::Unretained(this)));
- image_db()->GetCallback(true);
-}
-
-} // namespace feed
diff --git a/chromium/components/feed/core/feed_image_manager.cc b/chromium/components/feed/core/feed_image_manager.cc
deleted file mode 100644
index c7776e417a8..00000000000
--- a/chromium/components/feed/core/feed_image_manager.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feed/core/feed_image_manager.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/timer/elapsed_timer.h"
-#include "components/feed/core/time_serialization.h"
-#include "components/image_fetcher/core/image_decoder.h"
-#include "components/image_fetcher/core/image_fetcher.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/image/image.h"
-
-namespace feed {
-
-namespace {
-
-// Keep in sync with DIMENSION_UNKNOWN in third_party/feed/src/main/java/com/
-// google/android/libraries/feed/host/imageloader/ImageLoaderApi.java.
-const int DIMENSION_UNKNOWN = -1;
-
-const int kDefaultGarbageCollectionExpiredDays = 30;
-const int kLongGarbageCollectionInterval = 12 * 60 * 60; // 12 hours
-const int kShortGarbageCollectionInterval = 5 * 60; // 5 minutes
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
- net::DefineNetworkTrafficAnnotation("feed_image_fetcher", R"(
- semantics {
- sender: "Feed Library Image Fetch"
- description:
- "Retrieves images for content suggestions, for display on the "
- "New Tab page."
- 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: NO
- setting:
- "This can be disabled from the New Tab Page by collapsing the "
- "articles section."
- chrome_policy {
- NTPContentSuggestionsEnabled {
- NTPContentSuggestionsEnabled: false
- }
- }
- })");
-
-void ReportFetchResult(FeedImageFetchResult result) {
- UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Image.FetchResult",
- result);
-}
-
-gfx::Size CreateGfxSize(int width_px, int height_px) {
- DCHECK_GE(width_px, DIMENSION_UNKNOWN);
- DCHECK_GE(height_px, DIMENSION_UNKNOWN);
-
- // Only resize the image when both |width_px| and |height_px| are available.
- if (width_px == DIMENSION_UNKNOWN || height_px == DIMENSION_UNKNOWN) {
- return gfx::Size();
- }
- return gfx::Size(width_px, height_px);
-}
-
-} // namespace
-
-FeedImageManager::FeedImageManager(
- std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
- std::unique_ptr<FeedImageDatabase> image_database)
- : image_garbage_collected_day_(FromDatabaseTime(0)),
- image_fetcher_(std::move(image_fetcher)),
- image_database_(std::move(image_database)),
- weak_ptr_factory_(this) {
- DoGarbageCollectionIfNeeded();
-}
-
-FeedImageManager::~FeedImageManager() {
- StopGarbageCollection();
-}
-
-void FeedImageManager::FetchImage(std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback) {
- DCHECK(image_database_);
-
- FetchImagesFromDatabase(0, std::move(urls), width_px, height_px,
- std::move(callback));
-}
-
-void FeedImageManager::FetchImagesFromDatabase(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback) {
- if (url_index >= urls.size()) {
- // Already reached the last entry. Return an empty image.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), gfx::Image(), -1));
- return;
- }
-
- const std::string& image_id = urls[url_index];
- // Only take the first instance of the url so we get the worst-case time.
- if (url_timers_.find(image_id) == url_timers_.end()) {
- url_timers_.insert(std::make_pair(image_id, base::ElapsedTimer()));
- }
- image_database_->LoadImage(
- image_id,
- base::BindOnce(&FeedImageManager::OnImageFetchedFromDatabase,
- weak_ptr_factory_.GetWeakPtr(), url_index, std::move(urls),
- width_px, height_px, std::move(callback)));
-}
-
-void FeedImageManager::OnImageFetchedFromDatabase(
- size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data) {
- if (image_data.empty()) {
- // Fetching from the DB failed; start a network fetch.
- FetchImageFromNetwork(url_index, std::move(urls), width_px, height_px,
- std::move(callback));
- return;
- }
-
- image_fetcher_->GetImageDecoder()->DecodeImage(
- image_data, CreateGfxSize(width_px, height_px),
- base::BindRepeating(&FeedImageManager::OnImageDecodedFromDatabase,
- weak_ptr_factory_.GetWeakPtr(), url_index,
- std::move(urls), width_px, height_px,
- base::Passed(std::move(callback))));
-}
-
-void FeedImageManager::OnImageDecodedFromDatabase(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const gfx::Image& image) {
- const std::string& image_id = urls[url_index];
- if (image.IsEmpty()) {
- // If decoding the image failed, delete the DB entry.
- image_database_->DeleteImage(image_id);
- FetchImageFromNetwork(url_index, std::move(urls), width_px, height_px,
- std::move(callback));
- return;
- }
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), image, url_index));
-
- // Report success if the url exists.
- // This check is for concurrent access to the same url.
- if (url_timers_.find(image_id) != url_timers_.end()) {
- UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.Image.LoadFromCacheTime",
- url_timers_[image_id].Elapsed());
- ClearUmaTimer(image_id);
- ReportFetchResult(FeedImageFetchResult::kSuccessCached);
- }
-}
-
-void FeedImageManager::FetchImageFromNetwork(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback) {
- const std::string& image_id = urls[url_index];
- GURL url(image_id);
- if (!url.is_valid()) {
- // Report failure.
- ReportFetchResult(FeedImageFetchResult::kFailure);
- ClearUmaTimer(image_id);
-
- // url is not valid, go to next URL.
- FetchImagesFromDatabase(url_index + 1, std::move(urls), width_px, height_px,
- std::move(callback));
- return;
- }
-
- image_fetcher_->FetchImageData(
- url.spec(), url,
- base::BindOnce(&FeedImageManager::OnImageFetchedFromNetwork,
- weak_ptr_factory_.GetWeakPtr(), url_index, std::move(urls),
- width_px, height_px, std::move(callback)),
- kTrafficAnnotation);
-}
-
-void FeedImageManager::OnImageFetchedFromNetwork(
- size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data,
- const image_fetcher::RequestMetadata& request_metadata) {
- if (image_data.empty()) {
- // Report failure.
- ReportFetchResult(FeedImageFetchResult::kFailure);
- ClearUmaTimer(urls[url_index]);
-
- // Fetching image failed, let's move to the next url.
- FetchImagesFromDatabase(url_index + 1, std::move(urls), width_px, height_px,
- std::move(callback));
- return;
- }
-
- image_fetcher_->GetImageDecoder()->DecodeImage(
- image_data, CreateGfxSize(width_px, height_px),
- base::BindRepeating(&FeedImageManager::OnImageDecodedFromNetwork,
- weak_ptr_factory_.GetWeakPtr(), url_index,
- std::move(urls), width_px, height_px,
- base::Passed(std::move(callback)), image_data));
-}
-
-void FeedImageManager::OnImageDecodedFromNetwork(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data,
- const gfx::Image& image) {
- std::string image_id = urls[url_index];
- if (image.IsEmpty()) {
- // Report failure.
- ReportFetchResult(FeedImageFetchResult::kFailure);
- ClearUmaTimer(image_id);
-
- // Decoding failed, let's move to the next url.
- FetchImagesFromDatabase(url_index + 1, std::move(urls), width_px, height_px,
- std::move(callback));
- return;
- }
-
- image_database_->SaveImage(image_id, image_data);
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), image, url_index));
-
- // Report success if the url exists.
- // This check is for concurrent access to the same url.
- if (url_timers_.find(image_id) != url_timers_.end()) {
- UMA_HISTOGRAM_TIMES("ContentSuggestions.Feed.Image.LoadFromNetworkTime",
- url_timers_[image_id].Elapsed());
- ClearUmaTimer(image_id);
- ReportFetchResult(FeedImageFetchResult::kSuccessFetched);
- }
-}
-
-void FeedImageManager::DoGarbageCollectionIfNeeded() {
- // For saving resource purpose(ex. cpu, battery), We round up garbage
- // collection age to day, so we only run GC once a day.
- base::Time to_be_expired =
- base::Time::Now().LocalMidnight() -
- base::TimeDelta::FromDays(kDefaultGarbageCollectionExpiredDays);
- if (image_garbage_collected_day_ != to_be_expired) {
- image_database_->GarbageCollectImages(
- to_be_expired,
- base::BindOnce(&FeedImageManager::OnGarbageCollectionDone,
- weak_ptr_factory_.GetWeakPtr(), to_be_expired));
- }
-}
-
-void FeedImageManager::OnGarbageCollectionDone(base::Time garbage_collected_day,
- bool success) {
- base::TimeDelta gc_delay =
- base::TimeDelta::FromSeconds(kShortGarbageCollectionInterval);
- if (success) {
- if (image_garbage_collected_day_ < garbage_collected_day)
- image_garbage_collected_day_ = garbage_collected_day;
- gc_delay = base::TimeDelta::FromSeconds(kLongGarbageCollectionInterval);
- }
-
- garbage_collection_timer_.Start(
- FROM_HERE, gc_delay, this,
- &FeedImageManager::DoGarbageCollectionIfNeeded);
-}
-
-void FeedImageManager::StopGarbageCollection() {
- garbage_collection_timer_.Stop();
-}
-
-void FeedImageManager::ClearUmaTimer(const std::string& url) {
- url_timers_.erase(url);
-}
-
-} // namespace feed
diff --git a/chromium/components/feed/core/feed_image_manager.h b/chromium/components/feed/core/feed_image_manager.h
deleted file mode 100644
index a900d31aacb..00000000000
--- a/chromium/components/feed/core/feed_image_manager.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEED_CORE_FEED_IMAGE_MANAGER_H_
-#define COMPONENTS_FEED_CORE_FEED_IMAGE_MANAGER_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/containers/flat_map.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "components/feed/core/feed_image_database.h"
-
-namespace base {
-class ElapsedTimer;
-} // namespace base
-
-namespace gfx {
-class Image;
-} // namespace gfx
-
-namespace image_fetcher {
-class ImageFetcher;
-struct RequestMetadata;
-} // namespace image_fetcher
-
-namespace feed {
-
-using ImageFetchedCallback =
- base::OnceCallback<void(const gfx::Image&, size_t)>;
-
-// Enum for the result of the fetch, reported through UMA.
-// New values should be added at the end and things should not be renumbered.
-enum class FeedImageFetchResult {
- kSuccessCached = 0,
- kSuccessFetched = 1,
- kFailure = 2,
- kMaxValue = kFailure,
-};
-
-// FeedImageManager takes care of fetching images from the network and caching
-// them in the database.
-class FeedImageManager {
- public:
- FeedImageManager(std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
- std::unique_ptr<FeedImageDatabase> image_database);
- ~FeedImageManager();
-
- // Fetches an image from |urls|, and resize the image with |width_px| and
- // |height_px|. FeedImageManager will go through URLs in |urls| one by one
- // trying to fetch and decode them in order. If |width_px| and |height_px| are
- // not available/legal, FeedImageManager will not resize the image. Upon
- // success, a decoded image will be passed to |callback| as well as cached
- // locally. |urls| should be supplied in priority order, and the first success
- // will prevent any further processing. Failure to fetch or decode an image
- // will cause FeedImageManager to process the next URL in |urls|. If
- // FeedImageManager failed to fetch and decode all the URLs in |urls|, it will
- // pass an empty image to |callback|. |callback| will be called exactly once.
- void FetchImage(std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback);
-
- private:
- friend class FeedImageManagerTest;
-
- // Database
- void FetchImagesFromDatabase(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback);
- void OnImageFetchedFromDatabase(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data);
- void OnImageDecodedFromDatabase(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const gfx::Image& image);
-
- // Network
- void FetchImageFromNetwork(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback);
- void OnImageFetchedFromNetwork(
- size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data,
- const image_fetcher::RequestMetadata& request_metadata);
- void OnImageDecodedFromNetwork(size_t url_index,
- std::vector<std::string> urls,
- int width_px,
- int height_px,
- ImageFetchedCallback callback,
- const std::string& image_data,
- const gfx::Image& image);
-
- // Garbage collection will be run when FeedImageManager starts up, and then
- // once a day. Garbage collection will remove images, that have not been
- // touched for 30 days.
- void DoGarbageCollectionIfNeeded();
- void OnGarbageCollectionDone(base::Time garbage_collected_day, bool success);
- void StopGarbageCollection();
-
- void ClearUmaTimer(const std::string& url);
-
- // The day which image database already ran garbage collection against on.
- base::Time image_garbage_collected_day_;
-
- base::OneShotTimer garbage_collection_timer_;
-
- std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
- std::unique_ptr<FeedImageDatabase> image_database_;
-
- // Track time it takes to get images.
- base::flat_map<std::string, base::ElapsedTimer> url_timers_;
-
- base::WeakPtrFactory<FeedImageManager> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FeedImageManager);
-};
-
-} // namespace feed
-
-#endif // COMPONENTS_FEED_CORE_FEED_IMAGE_MANAGER_H_
diff --git a/chromium/components/feed/core/feed_image_manager_unittest.cc b/chromium/components/feed/core/feed_image_manager_unittest.cc
index 81ea896fcbd..418724a2dae 100644
--- a/chromium/components/feed/core/feed_image_manager_unittest.cc
+++ b/chromium/components/feed/core/feed_image_manager_unittest.cc
@@ -15,6 +15,7 @@
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/timer/timer.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher_impl.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/chromium/components/feed/core/feed_journal_database.cc b/chromium/components/feed/core/feed_journal_database.cc
index 412ee24d5c1..f061a3d6100 100644
--- a/chromium/components/feed/core/feed_journal_database.cc
+++ b/chromium/components/feed/core/feed_journal_database.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/system/sys_info.h"
#include "base/task/post_task.h"
diff --git a/chromium/components/feed/core/feed_journal_database_unittest.cc b/chromium/components/feed/core/feed_journal_database_unittest.cc
index 85d7cd92de0..47c60b84539 100644
--- a/chromium/components/feed/core/feed_journal_database_unittest.cc
+++ b/chromium/components/feed/core/feed_journal_database_unittest.cc
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "components/feed/core/feed_journal_mutation.h"
diff --git a/chromium/components/feed/core/feed_logging_metrics.cc b/chromium/components/feed/core/feed_logging_metrics.cc
index 9b83b0aafb3..03989b12cfc 100644
--- a/chromium/components/feed/core/feed_logging_metrics.cc
+++ b/chromium/components/feed/core/feed_logging_metrics.cc
@@ -8,6 +8,7 @@
#include <string>
#include <type_traits>
+#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@@ -27,7 +28,11 @@ namespace {
// identical bucket sizes and names with Zine is for comparing Feed with Zine
// easily. After Zine is deprecated, we can change the values if we needed.
+// Constants used as max sample sizes for histograms.
+const int kMaxContentCount = 50;
+const int kMaxFailureCount = 10;
const int kMaxSuggestionsTotal = 50;
+const int kMaxTokenCount = 10;
// Keep in sync with MAX_SUGGESTIONS_PER_SECTION in NewTabPageUma.java.
const int kMaxSuggestionsForArticle = 20;
@@ -35,6 +40,42 @@ const int kMaxSuggestionsForArticle = 20;
const char kHistogramArticlesUsageTimeLocal[] =
"NewTabPage.ContentSuggestions.UsageTimeLocal";
+// Values correspond to
+// third_party/feed/src/src/main/java/com/google/android/libraries/feed/host/
+// logging/SpinnerType.java, enums.xml and histograms.xml.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class SpinnerType {
+ KInitialLoad = 1,
+ KZeroStateRefresh = 2,
+ KMoreButton = 3,
+ KSyntheticToken = 4,
+ KInfiniteFeed = 5,
+ kMaxValue = KInfiniteFeed
+};
+
+// Each suffix here should correspond to an entry under histogram suffix
+// ContentSuggestionCategory in histograms.xml.
+std::string GetSpinnerTypeSuffix(SpinnerType spinner_type) {
+ switch (spinner_type) {
+ case SpinnerType::KInitialLoad:
+ return "InitialLoad";
+ case SpinnerType::KZeroStateRefresh:
+ return "ZeroStateRefresh";
+ case SpinnerType::KMoreButton:
+ return "MoreButton";
+ case SpinnerType::KSyntheticToken:
+ return "SyntheticToken";
+ case SpinnerType::KInfiniteFeed:
+ return "InfiniteFeed";
+ }
+
+ // TODO(https://crbug.com/935602): Handle new values when adding new values on
+ // java side.
+ NOTREACHED();
+ return std::string();
+}
+
// Records ContentSuggestions usage. Therefore the day is sliced into 20min
// buckets. Depending on the current local time the count of the corresponding
// bucket is increased.
@@ -51,6 +92,7 @@ void RecordContentSuggestionsUsage(base::Time now) {
std::string histogram_name(
base::StringPrintf("%s.%s", kHistogramArticlesUsageTimeLocal,
kWeekdayNames[now_exploded.day_of_week]));
+ // Since the |histogram_name| is dynamic, we can't use the regular macro.
base::UmaHistogramExactLinear(histogram_name, bucket, kNumBuckets);
UMA_HISTOGRAM_EXACT_LINEAR(kHistogramArticlesUsageTimeLocal, bucket,
kNumBuckets);
@@ -76,6 +118,37 @@ void RecordSuggestionPageVisited(bool return_to_ntp) {
base::RecordAction(base::UserMetricsAction("MobileNTP.Snippets.VisitEnd"));
}
+void RecordUndoableActionUMA(const std::string& histogram_base,
+ int position,
+ bool committed) {
+ std::string histogram_name =
+ histogram_base + (committed ? ".Commit" : ".Undo");
+
+ // Since the |histogram_name| is dynamic, we can't use the regular macro.
+ base::UmaHistogramExactLinear(histogram_name, position, kMaxSuggestionsTotal);
+}
+
+void CheckURLVisitedDone(int position, bool committed, bool visited) {
+ if (visited) {
+ RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedVisited",
+ position, committed);
+ } else {
+ RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedUnvisited",
+ position, committed);
+ }
+}
+
+void RecordSpinnerTimeUMA(const char* base_name,
+ base::TimeDelta time,
+ int spinner_type) {
+ SpinnerType type = static_cast<SpinnerType>(spinner_type);
+ std::string suffix = GetSpinnerTypeSuffix(type);
+ std::string histogram_name(
+ base::StringPrintf("%s.%s", base_name, suffix.c_str()));
+ base::UmaHistogramTimes(histogram_name, time);
+ base::UmaHistogramTimes(base_name, time);
+}
+
} // namespace
FeedLoggingMetrics::FeedLoggingMetrics(
@@ -178,10 +251,11 @@ void FeedLoggingMetrics::OnSuggestionMenuOpened(int position,
ToUMAScore(score), 11);
}
-void FeedLoggingMetrics::OnSuggestionDismissed(int position, const GURL& url) {
+void FeedLoggingMetrics::OnSuggestionDismissed(int position,
+ const GURL& url,
+ bool committed) {
history_url_check_callback_.Run(
- url, base::BindOnce(&FeedLoggingMetrics::CheckURLVisitedDone,
- weak_ptr_factory_.GetWeakPtr(), position));
+ url, base::BindOnce(&CheckURLVisitedDone, position, committed));
base::RecordAction(base::UserMetricsAction("Suggestions.Content.Dismissed"));
}
@@ -221,25 +295,116 @@ void FeedLoggingMetrics::OnMoreButtonClicked(int position) {
kMaxSuggestionsForArticle + 1);
}
-void FeedLoggingMetrics::OnSpinnerShown(base::TimeDelta shown_time) {
- base::UmaHistogramTimes(
- "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration",
- shown_time);
+void FeedLoggingMetrics::OnNotInterestedInSource(int position, bool committed) {
+ RecordUndoableActionUMA(
+ "ContentSuggestions.Feed.InterestHeader.NotInterestedInSource", position,
+ committed);
}
-void FeedLoggingMetrics::ReportScrolledAfterOpen() {
- base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen"));
+void FeedLoggingMetrics::OnNotInterestedInTopic(int position, bool committed) {
+ RecordUndoableActionUMA(
+ "ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic", position,
+ committed);
}
-void FeedLoggingMetrics::CheckURLVisitedDone(int position, bool visited) {
- if (visited) {
- UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.DismissedVisited",
- position, kMaxSuggestionsTotal);
+void FeedLoggingMetrics::OnSpinnerStarted(int spinner_type) {
+ // TODO(https://crbug.com/935602): Handle new values when adding new values on
+ // java side.
+ SpinnerType type = static_cast<SpinnerType>(spinner_type);
+ UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.FetchPendingSpinner.Shown",
+ type);
+}
+
+void FeedLoggingMetrics::OnSpinnerFinished(base::TimeDelta shown_time,
+ int spinner_type) {
+ RecordSpinnerTimeUMA(
+ "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration", shown_time,
+ spinner_type);
+}
+
+void FeedLoggingMetrics::OnSpinnerDestroyedWithoutCompleting(
+ base::TimeDelta shown_time,
+ int spinner_type) {
+ RecordSpinnerTimeUMA(
+ "ContentSuggestions.Feed.FetchPendingSpinner."
+ "VisibleDurationWithoutCompleting",
+ shown_time, spinner_type);
+}
+
+void FeedLoggingMetrics::OnPietFrameRenderingEvent(
+ std::vector<int> piet_error_codes) {
+ for (auto error_code : piet_error_codes) {
+ base::UmaHistogramSparse(
+ "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode", error_code);
+ }
+}
+
+void FeedLoggingMetrics::OnInternalError(int internal_error) {
+ // TODO(https://crbug.com/935602): The max value here is fragile, figure out
+ // some way to test the @IntDef size.
+ UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.InternalError",
+ internal_error, 10);
+}
+
+void FeedLoggingMetrics::OnTokenCompleted(bool was_synthetic,
+ int content_count,
+ int token_count) {
+ if (was_synthetic) {
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.TokenCompleted.ContentCount2.Synthetic",
+ content_count, kMaxContentCount);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.TokenCompleted.TokenCount.Synthetic",
+ token_count, kMaxTokenCount);
+ } else {
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.TokenCompleted.ContentCount2.NotSynthetic",
+ content_count, kMaxContentCount);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.TokenCompleted.TokenCount.NotSynthetic",
+ token_count, kMaxTokenCount);
+ }
+}
+
+void FeedLoggingMetrics::OnTokenFailedToComplete(bool was_synthetic,
+ int failure_count) {
+ if (was_synthetic) {
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.TokenFailedToCompleted.Synthetic",
+ failure_count, kMaxFailureCount);
} else {
UMA_HISTOGRAM_EXACT_LINEAR(
- "NewTabPage.ContentSuggestions.DismissedUnvisited", position,
- kMaxSuggestionsTotal);
+ "ContentSuggestions.Feed.TokenFailedToCompleted.NotSynthetic",
+ failure_count, kMaxFailureCount);
}
}
+void FeedLoggingMetrics::OnServerRequest(int request_reason) {
+ // TODO(https://crbug.com/935602): The max value here is fragile, figure out
+ // some way to test the @IntDef size.
+ UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ServerRequest.Reason",
+ request_reason, 8);
+}
+
+void FeedLoggingMetrics::OnZeroStateShown(int zero_state_show_reason) {
+ // TODO(https://crbug.com/935602): The max value here is fragile, figure out
+ // some way to test the @IntDef size.
+ UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ZeroStateShown.Reason",
+ zero_state_show_reason, 3);
+}
+
+void FeedLoggingMetrics::OnZeroStateRefreshCompleted(int new_content_count,
+ int new_token_count) {
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.ZeroStateRefreshCompleted.ContentCount",
+ new_content_count, kMaxContentCount);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "ContentSuggestions.Feed.ZeroStateRefreshCompleted.TokenCount",
+ new_token_count, kMaxTokenCount);
+}
+
+void FeedLoggingMetrics::ReportScrolledAfterOpen() {
+ base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen"));
+}
+
} // namespace feed
diff --git a/chromium/components/feed/core/feed_logging_metrics.h b/chromium/components/feed/core/feed_logging_metrics.h
index 994d19f8c5d..2b1984ccce7 100644
--- a/chromium/components/feed/core/feed_logging_metrics.h
+++ b/chromium/components/feed/core/feed_logging_metrics.h
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include <vector>
#include "base/callback.h"
#include "base/macros.h"
@@ -60,7 +61,7 @@ class FeedLoggingMetrics {
base::Time publish_date,
float score);
- void OnSuggestionDismissed(int position, const GURL& url);
+ void OnSuggestionDismissed(int position, const GURL& url, bool committed);
void OnSuggestionSwiped();
@@ -75,13 +76,34 @@ class FeedLoggingMetrics {
void OnMoreButtonClicked(int position);
- void OnSpinnerShown(base::TimeDelta shown_time);
+ void OnNotInterestedInSource(int position, bool committed);
+
+ void OnNotInterestedInTopic(int position, bool committed);
+
+ void OnSpinnerStarted(int spinner_type);
+
+ void OnSpinnerFinished(base::TimeDelta shown_time, int spinner_type);
+
+ void OnSpinnerDestroyedWithoutCompleting(base::TimeDelta shown_time,
+ int spinner_type);
+
+ void OnPietFrameRenderingEvent(std::vector<int> piet_error_codes);
+
+ void OnInternalError(int internal_error);
+
+ void OnTokenCompleted(bool was_synthetic, int content_count, int token_count);
+
+ void OnTokenFailedToComplete(bool was_synthetic, int failure_count);
+
+ void OnServerRequest(int request_reason);
+
+ void OnZeroStateShown(int zero_state_show_reason);
+
+ void OnZeroStateRefreshCompleted(int new_content_count, int new_token_count);
void ReportScrolledAfterOpen();
private:
- void CheckURLVisitedDone(int position, bool visited);
-
const HistoryURLCheckCallback history_url_check_callback_;
// Used to access current time, injected for testing.
diff --git a/chromium/components/feed/core/feed_logging_metrics_unittest.cc b/chromium/components/feed/core/feed_logging_metrics_unittest.cc
index 02436f2738f..37303c0f183 100644
--- a/chromium/components/feed/core/feed_logging_metrics_unittest.cc
+++ b/chromium/components/feed/core/feed_logging_metrics_unittest.cc
@@ -4,6 +4,7 @@
#include "components/feed/core/feed_logging_metrics.h"
+#include "base/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
@@ -149,21 +150,55 @@ TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionWindowOpened) {
/*count=*/4)));
}
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfVisited) {
+TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedCommitIfVisited) {
base::HistogramTester histogram_tester;
- feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl);
+ feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl,
+ true);
EXPECT_THAT(histogram_tester.GetAllSamples(
- "NewTabPage.ContentSuggestions.DismissedVisited"),
+ "NewTabPage.ContentSuggestions.DismissedVisited.Commit"),
ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
}
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfNotVisited) {
+TEST_F(FeedLoggingMetricsTest,
+ ShouldLogOnSuggestionDismissedCommitIfNotVisited) {
base::HistogramTester histogram_tester;
- feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10,
- GURL("http://non_visited.com"));
+ feed_logging_metrics()->OnSuggestionDismissed(
+ /*position=*/10, GURL("http://non_visited.com"), true);
EXPECT_THAT(histogram_tester.GetAllSamples(
- "NewTabPage.ContentSuggestions.DismissedVisited"),
- IsEmpty());
+ "NewTabPage.ContentSuggestions.DismissedUnvisited.Commit"),
+ ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest,
+ ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndVisited) {
+ base::HistogramTester histogram_tester;
+ feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl,
+ false);
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "NewTabPage.ContentSuggestions.DismissedVisited.Undo"),
+ ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest,
+ ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndNotVisited) {
+ base::HistogramTester histogram_tester;
+ feed_logging_metrics()->OnSuggestionDismissed(
+ /*position=*/10, GURL("http://non_visited.com"), false);
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "NewTabPage.ContentSuggestions.DismissedUnvisited.Undo"),
+ ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest, ShouldReportOnPietFrameRenderingEvent) {
+ base::HistogramTester histogram_tester;
+ std::vector<int> error_codes({0, 1, 6, 7});
+ feed_logging_metrics()->OnPietFrameRenderingEvent(error_codes);
+ EXPECT_THAT(histogram_tester.GetAllSamples(
+ "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode"),
+ ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
+ base::Bucket(/*min=*/1, /*count=*/1),
+ base::Bucket(/*min=*/6, /*count=*/1),
+ base::Bucket(/*min=*/7, /*count=*/1)));
}
} // namespace feed
diff --git a/chromium/components/feed/core/feed_networking_host.cc b/chromium/components/feed/core/feed_networking_host.cc
index 046f7c95f2c..27a94812f05 100644
--- a/chromium/components/feed/core/feed_networking_host.cc
+++ b/chromium/components/feed/core/feed_networking_host.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@@ -65,11 +66,12 @@ class NetworkFetch {
private:
void StartAccessTokenFetch();
- void AccessTokenFetchFinished(GoogleServiceAuthError error,
+ void AccessTokenFetchFinished(base::TimeTicks token_start_ticks,
+ GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info);
void StartLoader();
std::unique_ptr<network::SimpleURLLoader> MakeLoader();
- net::HttpRequestHeaders MakeHeaders(const std::string& auth_header) const;
+ void SetRequestHeaders(network::ResourceRequest* request) const;
void PopulateRequestBody(network::SimpleURLLoader* loader);
void OnSimpleLoaderComplete(std::unique_ptr<std::string> response);
@@ -84,7 +86,13 @@ class NetworkFetch {
network::SharedURLLoaderFactory* loader_factory_;
const std::string api_key_;
const base::TickClock* tick_clock_;
- base::TimeTicks start_ticks_;
+
+ // Set when the NetworkFetch is constructed, before token and article fetch.
+ const base::TimeTicks entire_send_start_ticks_;
+
+ // Should be set right before the article fetch, and after the token fetch if
+ // there is one.
+ base::TimeTicks loader_only_start_ticks_;
DISALLOW_COPY_AND_ASSIGN(NetworkFetch);
};
@@ -103,7 +111,7 @@ NetworkFetch::NetworkFetch(const GURL& url,
loader_factory_(loader_factory),
api_key_(api_key),
tick_clock_(tick_clock),
- start_ticks_(tick_clock_->NowTicks()) {}
+ entire_send_start_ticks_(tick_clock_->NowTicks()) {}
void NetworkFetch::Start(FeedNetworkingHost::ResponseCallback done_callback) {
done_callback_ = std::move(done_callback);
@@ -123,20 +131,27 @@ void NetworkFetch::StartAccessTokenFetch() {
token_fetcher_ = std::make_unique<identity::PrimaryAccountAccessTokenFetcher>(
"feed", identity_manager_, scopes,
base::BindOnce(&NetworkFetch::AccessTokenFetchFinished,
- base::Unretained(this)),
+ base::Unretained(this), tick_clock_->NowTicks()),
identity::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
}
void NetworkFetch::AccessTokenFetchFinished(
+ base::TimeTicks token_start_ticks,
GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info) {
UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Network.TokenFetchStatus",
error.state(), GoogleServiceAuthError::NUM_STATES);
+
+ base::TimeDelta token_duration = tick_clock_->NowTicks() - token_start_ticks;
+ UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.TokenDuration",
+ token_duration);
+
access_token_ = access_token_info.token;
StartLoader();
}
void NetworkFetch::StartLoader() {
+ loader_only_start_ticks_ = tick_clock_->NowTicks();
simple_loader_ = MakeLoader();
simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory_, base::BindOnce(&NetworkFetch::OnSimpleLoaderComplete,
@@ -144,12 +159,6 @@ void NetworkFetch::StartLoader() {
}
std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader() {
- std::string auth_header =
- access_token_.empty()
- ? std::string()
- : base::StringPrintf(kAuthorizationRequestHeaderFormat,
- access_token_.c_str());
- net::HttpRequestHeaders headers = MakeHeaders(auth_header);
// TODO(pnoland): Add data use measurement once it's supported for simple
// url loader.
net::NetworkTrafficAnnotationTag traffic_annotation =
@@ -186,8 +195,8 @@ std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader() {
resource_request->load_flags = net::LOAD_BYPASS_CACHE;
resource_request->allow_credentials = false;
- resource_request->headers = headers;
resource_request->method = request_type_;
+ SetRequestHeaders(resource_request.get());
auto simple_loader = network::SimpleURLLoader::Create(
std::move(resource_request), traffic_annotation);
@@ -198,22 +207,23 @@ std::unique_ptr<network::SimpleURLLoader> NetworkFetch::MakeLoader() {
return simple_loader;
}
-net::HttpRequestHeaders NetworkFetch::MakeHeaders(
- const std::string& auth_header) const {
- net::HttpRequestHeaders headers;
- headers.SetHeader(net::HttpRequestHeaders::kContentType, kContentType);
- headers.SetHeader(kContentEncoding, kGzip);
-
- bool is_authorized = !auth_header.empty();
- if (is_authorized)
- headers.SetHeader(net::HttpRequestHeaders::kAuthorization, auth_header);
+void NetworkFetch::SetRequestHeaders(network::ResourceRequest* request) const {
+ request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
+ kContentType);
+ request->headers.SetHeader(kContentEncoding, kGzip);
+
+ variations::SignedIn signed_in_status = variations::SignedIn::kNo;
+ if (!access_token_.empty()) {
+ std::string auth_header = base::StringPrintf(
+ kAuthorizationRequestHeaderFormat, access_token_.c_str());
+ request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
+ auth_header);
+ signed_in_status = variations::SignedIn::kYes;
+ }
- variations::SignedIn signed_in_status =
- is_authorized ? variations::SignedIn::kYes : variations::SignedIn::kNo;
// Add X-Client-Data header with experiment IDs from field trials.
- variations::AppendVariationHeaders(url_, variations::InIncognito::kNo,
- signed_in_status, &headers);
- return headers;
+ variations::AppendVariationsHeader(url_, variations::InIncognito::kNo,
+ signed_in_status, request);
}
void NetworkFetch::PopulateRequestBody(network::SimpleURLLoader* loader) {
@@ -254,9 +264,16 @@ void NetworkFetch::OnSimpleLoaderComplete(
response_body.assign(begin, end);
}
- base::TimeDelta duration = tick_clock_->NowTicks() - start_ticks_;
+ base::TimeDelta entire_send_duration =
+ tick_clock_->NowTicks() - entire_send_start_ticks_;
UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.Duration",
- duration);
+ entire_send_duration);
+
+ base::TimeDelta loader_only_duration =
+ tick_clock_->NowTicks() - loader_only_start_ticks_;
+ // This histogram purposefully matches name and bucket size used in
+ // RemoteSuggestionsFetcherImpl.
+ UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", loader_only_duration);
base::UmaHistogramSparse("ContentSuggestions.Feed.Network.RequestStatusCode",
status_code);
diff --git a/chromium/components/feed/core/feed_networking_host_unittest.cc b/chromium/components/feed/core/feed_networking_host_unittest.cc
index 41aa465a46d..a2267b7ab3f 100644
--- a/chromium/components/feed/core/feed_networking_host_unittest.cc
+++ b/chromium/components/feed/core/feed_networking_host_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/test/bind_test_util.h"
diff --git a/chromium/components/feed/core/feed_scheduler_host.cc b/chromium/components/feed/core/feed_scheduler_host.cc
index f7a488efa63..52e4d45d584 100644
--- a/chromium/components/feed/core/feed_scheduler_host.cc
+++ b/chromium/components/feed/core/feed_scheduler_host.cc
@@ -31,6 +31,33 @@ namespace {
using TriggerType = FeedSchedulerHost::TriggerType;
using UserClass = UserClassifier::UserClass;
+// Enum for the relation between boolean fields the Feed and host both track.
+// Reported through UMA and must match the corresponding definition in
+// enums.xml
+enum class FeedHostMismatch {
+ kNeitherAreSet = 0,
+ kFeedIsSetOnly = 1,
+ kHostIsSetOnly = 2,
+ kBothAreSet = 3,
+ kMaxValue = kBothAreSet,
+};
+
+// Copies boolean args into temps to avoid evaluating them multiple times.
+#define UMA_HISTOGRAM_MISMATCH(name, feed_is_set, host_is_set) \
+ do { \
+ bool copied_feed_is_set = feed_is_set; \
+ bool copied_host_is_set = host_is_set; \
+ FeedHostMismatch status = FeedHostMismatch::kNeitherAreSet; \
+ if (copied_feed_is_set && copied_host_is_set) { \
+ status = FeedHostMismatch::kBothAreSet; \
+ } else if (copied_feed_is_set) { \
+ status = FeedHostMismatch::kFeedIsSetOnly; \
+ } else if (copied_host_is_set) { \
+ status = FeedHostMismatch::kHostIsSetOnly; \
+ } \
+ UMA_HISTOGRAM_ENUMERATION(name, status); \
+ } while (false);
+
struct ParamPair {
std::string name;
double default_value;
@@ -139,6 +166,66 @@ void ReportAgeWithSuffix(const std::string& qualified_trigger,
/*bucket_count=*/50);
}
+void ReportReasonForNotRefreshingByBehavior(
+ NativeRequestBehavior behavior,
+ FeedSchedulerHost::ShouldRefreshResult status) {
+ DCHECK_NE(status, FeedSchedulerHost::kShouldRefresh);
+ switch (behavior) {
+ case kNoRequestWithWait:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "NoRequestWithWait",
+ status);
+ break;
+ case kNoRequestWithContent:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "NoRequestWithContent",
+ status);
+ break;
+ case kNoRequestWithTimeout:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "NoRequestWithTimeout",
+ status);
+ break;
+ case kUnknown:
+ case kRequestWithWait:
+ case kRequestWithContent:
+ case kRequestWithTimeout:
+ NOTREACHED();
+ break;
+ }
+}
+
+void ReportReasonForNotRefreshingByTrigger(
+ FeedSchedulerHost::TriggerType trigger_type,
+ FeedSchedulerHost::ShouldRefreshResult status) {
+ DCHECK_NE(status, FeedSchedulerHost::kShouldRefresh);
+ switch (trigger_type) {
+ case FeedSchedulerHost::TriggerType::kNtpShown:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "RequestByNtpShown",
+ status);
+ break;
+ case FeedSchedulerHost::TriggerType::kForegrounded:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "RequestByForegrounded",
+ status);
+ break;
+ case FeedSchedulerHost::TriggerType::kFixedTimer:
+ UMA_HISTOGRAM_ENUMERATION(
+ "ContentSuggestions.Feed.Scheduler.ShouldRefreshResult."
+ "RequestByFixedTimer",
+ status);
+ break;
+ }
+}
+
+const int kHttpStatusOk = 200;
+
} // namespace
FeedSchedulerHost::FeedSchedulerHost(PrefService* profile_prefs,
@@ -210,22 +297,60 @@ NativeRequestBehavior FeedSchedulerHost::ShouldSessionRequestData(
bool has_content,
base::Time content_creation_date_time,
bool has_outstanding_request) {
- // The scheduler may not always know of outstanding requests, but the Feed
- // should know about them all, and the scheduler should be notified upon
- // completion of all requests. We should never encounter a scenario where only
- // the scheduler thinks there is an outstanding request.
-
- // TODO(skym): Update this to use kTimeoutDurationSeconds.
- // DCHECK(has_outstanding_request || !tracking_oustanding_request_);
+ // Both the Feed and the scheduler track if there are outstanding requests.
+ // It's possible that this data gets out of sync. We treat the Feed as
+ // authoritative and we change our values to match.
+ UMA_HISTOGRAM_MISMATCH("ContentSuggestions.Feed.Scheduler.OutstandingRequest",
+ has_outstanding_request,
+ !outstanding_request_until_.is_null());
+ if (has_outstanding_request == outstanding_request_until_.is_null()) {
+ if (has_outstanding_request) {
+ outstanding_request_until_ =
+ clock_->Now() +
+ base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
+ } else {
+ outstanding_request_until_ = base::Time();
+ }
+ }
- if (outstanding_request_until_.is_null() && has_outstanding_request) {
- outstanding_request_until_ =
- clock_->Now() +
- base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
+ // It seems to be possible for the scheduler's tracking of having content to
+ // get out of sync with the Feed. Root cause is currently unknown, but similar
+ // to outstanding request handling, we can repair with the information we
+ // have.
+ bool scheduler_thinks_has_content =
+ !profile_prefs_->FindPreference(prefs::kLastFetchAttemptTime)
+ ->IsDefaultValue();
+ UMA_HISTOGRAM_MISMATCH("ContentSuggestions.Feed.Scheduler.HasContent",
+ has_content, scheduler_thinks_has_content);
+ if (has_content != scheduler_thinks_has_content) {
+ if (has_content) {
+ profile_prefs_->SetTime(prefs::kLastFetchAttemptTime,
+ content_creation_date_time);
+ } else {
+ profile_prefs_->ClearPref(prefs::kLastFetchAttemptTime);
+ }
+ } else if (has_content) { // && scheduler_thinks_has_content
+ // Split into two histograms so the difference is always positive.
+ base::Time last_attempt =
+ profile_prefs_->GetTime(prefs::kLastFetchAttemptTime);
+ if (content_creation_date_time > last_attempt) {
+ base::TimeDelta difference = (content_creation_date_time - last_attempt);
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "ContentSuggestions.Feed.Scheduler.ContentAgeDifference.FeedIsOlder",
+ difference, base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromDays(7), 100);
+ } else {
+ base::TimeDelta difference = (last_attempt - content_creation_date_time);
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ "ContentSuggestions.Feed.Scheduler.ContentAgeDifference.HostIsOlder",
+ difference, base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromDays(7), 100);
+ }
}
NativeRequestBehavior behavior;
- if (ShouldRefresh(TriggerType::kNtpShown)) {
+ ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kNtpShown);
+ if (kShouldRefresh == refresh_status) {
if (!has_content) {
behavior = kRequestWithWait;
} else if (IsContentStale(content_creation_date_time)) {
@@ -248,6 +373,7 @@ NativeRequestBehavior FeedSchedulerHost::ShouldSessionRequestData(
} else {
behavior = kNoRequestWithContent;
}
+ ReportReasonForNotRefreshingByBehavior(behavior, refresh_status);
}
OnSuggestionsShown();
@@ -262,6 +388,7 @@ void FeedSchedulerHost::OnReceiveNewContent(
base::Time content_creation_date_time) {
profile_prefs_->SetTime(prefs::kLastFetchAttemptTime,
content_creation_date_time);
+ last_fetch_status_ = kHttpStatusOk;
TryRun(std::move(fixed_timer_completion_));
ScheduleFixedTimerWakeUp(GetTriggerThreshold(TriggerType::kFixedTimer));
outstanding_request_until_ = base::Time();
@@ -273,6 +400,7 @@ void FeedSchedulerHost::OnReceiveNewContent(
void FeedSchedulerHost::OnRequestError(int network_response_code) {
profile_prefs_->SetTime(prefs::kLastFetchAttemptTime, clock_->Now());
+ last_fetch_status_ = network_response_code;
TryRun(std::move(fixed_timer_completion_));
outstanding_request_until_ = base::Time();
time_until_first_shown_trigger_reported_ = false;
@@ -282,8 +410,13 @@ void FeedSchedulerHost::OnRequestError(int network_response_code) {
void FeedSchedulerHost::OnForegrounded() {
DCHECK(refresh_callback_);
- if (ShouldRefresh(TriggerType::kForegrounded)) {
+ ShouldRefreshResult refresh_status =
+ ShouldRefresh(TriggerType::kForegrounded);
+ if (kShouldRefresh == refresh_status) {
refresh_callback_.Run();
+ } else {
+ ReportReasonForNotRefreshingByTrigger(TriggerType::kForegrounded,
+ refresh_status);
}
}
@@ -298,7 +431,8 @@ void FeedSchedulerHost::OnFixedTimer(base::OnceClosure on_completion) {
CancelFixedTimerWakeUp();
}
- if (ShouldRefresh(TriggerType::kFixedTimer)) {
+ ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kFixedTimer);
+ if (kShouldRefresh == refresh_status) {
// There shouldn't typically be anything in |fixed_timer_completion_| right
// now, but if there was, run it before we replace it.
TryRun(std::move(fixed_timer_completion_));
@@ -306,6 +440,8 @@ void FeedSchedulerHost::OnFixedTimer(base::OnceClosure on_completion) {
fixed_timer_completion_ = std::move(on_completion);
refresh_callback_.Run();
} else {
+ ReportReasonForNotRefreshingByTrigger(TriggerType::kFixedTimer,
+ refresh_status);
// The task driving this doesn't need to stay around, since no work is being
// done on its behalf.
TryRun(std::move(on_completion));
@@ -343,49 +479,68 @@ bool FeedSchedulerHost::OnArticlesCleared(bool suppress_refreshes) {
suppress_refreshes_until_ =
clock_->Now() +
base::TimeDelta::FromMinutes(kSuppressRefreshDurationMinutes.Get());
- } else if (ShouldRefresh(TriggerType::kNtpShown)) {
+ }
+
+ ShouldRefreshResult refresh_status = ShouldRefresh(TriggerType::kNtpShown);
+ if (kShouldRefresh == refresh_status) {
// Instead of using |refresh_callback_|, instead return our desire to
// refresh back up to our caller. This allows more information to be given
// all at once to the Feed which allows it to act more intelligently.
return true;
+ } else {
+ ReportReasonForNotRefreshingByTrigger(TriggerType::kNtpShown,
+ refresh_status);
}
return false;
}
+UserClassifier* FeedSchedulerHost::GetUserClassifierForDebugging() {
+ return &user_classifier_;
+}
+
+base::Time FeedSchedulerHost::GetSuppressRefreshesUntilForDebugging() const {
+ return suppress_refreshes_until_;
+}
+
+int FeedSchedulerHost::GetLastFetchStatusForDebugging() const {
+ return last_fetch_status_;
+}
+
void FeedSchedulerHost::OnEulaAccepted() {
OnForegrounded();
}
-bool FeedSchedulerHost::ShouldRefresh(TriggerType trigger) {
+FeedSchedulerHost::ShouldRefreshResult FeedSchedulerHost::ShouldRefresh(
+ TriggerType trigger) {
if (clock_->Now() < outstanding_request_until_) {
DVLOG(2) << "Outstanding request stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshOutstandingRequest;
}
if (base::ContainsKey(disabled_triggers_, trigger)) {
DVLOG(2) << "Disabled trigger stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshTriggerDisabled;
}
if (net::NetworkChangeNotifier::IsOffline()) {
DVLOG(2) << "Network is offline stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshNetworkOffline;
}
if (eula_accepted_notifier_ && !eula_accepted_notifier_->IsEulaAccepted()) {
DVLOG(2) << "EULA not being accepted stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshEulaNotAccepted;
}
if (!profile_prefs_->GetBoolean(prefs::kArticlesListVisible)) {
DVLOG(2) << "Articles being hidden stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshArticlesHidden;
}
base::TimeDelta attempt_age =
@@ -407,13 +562,13 @@ bool FeedSchedulerHost::ShouldRefresh(TriggerType trigger) {
if (clock_->Now() < suppress_refreshes_until_) {
DVLOG(2) << "Refresh suppression until " << suppress_refreshes_until_
<< " stopped refresh from trigger " << static_cast<int>(trigger);
- return false;
+ return kDontRefreshRefreshSuppressed;
}
if (attempt_age < GetTriggerThreshold(trigger)) {
DVLOG(2) << "Last attempt age of " << attempt_age
<< " stopped refresh from trigger " << static_cast<int>(trigger);
- return false;
+ return kDontRefreshNotStale;
}
auto throttlerIter = throttlers_.find(user_class);
@@ -421,7 +576,7 @@ bool FeedSchedulerHost::ShouldRefresh(TriggerType trigger) {
!throttlerIter->second->RequestQuota()) {
DVLOG(2) << "Throttler stopped refresh from trigger "
<< static_cast<int>(trigger);
- return false;
+ return kDontRefreshRefreshThrottled;
}
switch (trigger) {
@@ -443,7 +598,7 @@ bool FeedSchedulerHost::ShouldRefresh(TriggerType trigger) {
clock_->Now() +
base::TimeDelta::FromSeconds(kTimeoutDurationSeconds.Get());
- return true;
+ return kShouldRefresh;
}
bool FeedSchedulerHost::IsContentStale(base::Time content_creation_date_time) {
diff --git a/chromium/components/feed/core/feed_scheduler_host.h b/chromium/components/feed/core/feed_scheduler_host.h
index 31469361e43..d2455dec39d 100644
--- a/chromium/components/feed/core/feed_scheduler_host.h
+++ b/chromium/components/feed/core/feed_scheduler_host.h
@@ -60,6 +60,24 @@ class FeedSchedulerHost : web_resource::EulaAcceptedNotifier::Observer {
kMaxValue = kFixedTimer
};
+ // Enum for the status of the refresh, reported through UMA.
+ // If any new values are added, update the corresponding definition in
+ // enums.xml.
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum ShouldRefreshResult {
+ kShouldRefresh = 0,
+ kDontRefreshOutstandingRequest = 1,
+ kDontRefreshTriggerDisabled = 2,
+ kDontRefreshNetworkOffline = 3,
+ kDontRefreshEulaNotAccepted = 4,
+ kDontRefreshArticlesHidden = 5,
+ kDontRefreshRefreshSuppressed = 6,
+ kDontRefreshNotStale = 7,
+ kDontRefreshRefreshThrottled = 8,
+ kMaxValue = kDontRefreshRefreshThrottled,
+ };
+
FeedSchedulerHost(PrefService* profile_prefs,
PrefService* local_state,
base::Clock* clock);
@@ -116,6 +134,15 @@ class FeedSchedulerHost : web_resource::EulaAcceptedNotifier::Observer {
// the return value, and if true, the caller should start a refresh.
bool OnArticlesCleared(bool suppress_refreshes);
+ // Surface user_classifier_ for internals debugging page.
+ UserClassifier* GetUserClassifierForDebugging();
+
+ // Surface suppress_refreshes_until_ for internals debugging page.
+ base::Time GetSuppressRefreshesUntilForDebugging() const;
+
+ // Surface last_fetch_status_ for internals debugging page.
+ int GetLastFetchStatusForDebugging() const;
+
private:
FRIEND_TEST_ALL_PREFIXES(FeedSchedulerHostTest, GetTriggerThreshold);
@@ -126,7 +153,7 @@ class FeedSchedulerHost : web_resource::EulaAcceptedNotifier::Observer {
// If this method is called and returns true we presume the refresh will
// happen, therefore we report metrics respectively and update
// |tracking_oustanding_request_|.
- bool ShouldRefresh(TriggerType trigger);
+ ShouldRefreshResult ShouldRefresh(TriggerType trigger);
// Decides if content whose age is the difference between now and
// |content_creation_date_time| is old enough to be considered stale.
@@ -198,6 +225,9 @@ class FeedSchedulerHost : web_resource::EulaAcceptedNotifier::Observer {
base::flat_map<UserClassifier::UserClass, std::unique_ptr<RefreshThrottler>>
throttlers_;
+ // Status of the last fetch for debugging.
+ int last_fetch_status_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(FeedSchedulerHost);
};
diff --git a/chromium/components/feed/core/feed_scheduler_host_unittest.cc b/chromium/components/feed/core/feed_scheduler_host_unittest.cc
index d7ba47085c6..b7bfaca0f3e 100644
--- a/chromium/components/feed/core/feed_scheduler_host_unittest.cc
+++ b/chromium/components/feed/core/feed_scheduler_host_unittest.cc
@@ -918,6 +918,28 @@ TEST_F(FeedSchedulerHostTest, IncorporatesExternalOustandingRequest) {
// prevent the OnForegrounded() from requesting a refresh.
scheduler()->OnForegrounded();
EXPECT_EQ(0, refresh_call_count());
+
+ EXPECT_EQ(kRequestWithWait,
+ scheduler()->ShouldSessionRequestData(
+ /*has_content*/ false, /*content_creation_date_time*/ Time(),
+ /*has_outstanding_request*/ false));
+}
+
+TEST_F(FeedSchedulerHostTest, IncorporatesExternalHasContent) {
+ Time now = test_clock()->Now();
+ EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
+
+ EXPECT_EQ(kNoRequestWithContent,
+ scheduler()->ShouldSessionRequestData(
+ /*has_content*/ true, now, /*has_outstanding_request*/ false));
+ EXPECT_EQ(now, profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
+
+ // Use has_outstanding_request of true to keep the scheduler from actually
+ // triggering the refresh. We want to track the change to its internal state.
+ EXPECT_EQ(kNoRequestWithWait, scheduler()->ShouldSessionRequestData(
+ /*has_content*/ false, base::Time(),
+ /*has_outstanding_request*/ true));
+ EXPECT_EQ(Time(), profile_prefs()->GetTime(prefs::kLastFetchAttemptTime));
}
TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
@@ -933,7 +955,7 @@ TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
scheduler()->ShouldSessionRequestData(
- /*has_content*/ false, now, /*has_outstanding_request*/ false);
+ /*has_content*/ true, now, /*has_outstanding_request*/ false);
EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
EXPECT_EQ(0U, histogram_tester.GetAllSamples(forgroundedHistogram).size());
@@ -942,7 +964,7 @@ TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
scheduler()->ShouldSessionRequestData(
- /*has_content*/ false, now, /*has_outstanding_request*/ false);
+ /*has_content*/ true, now, /*has_outstanding_request*/ false);
scheduler()->OnForegrounded();
EXPECT_EQ(1, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
EXPECT_EQ(1, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
@@ -952,7 +974,7 @@ TEST_F(FeedSchedulerHostTest, TimeUntilFirstMetrics) {
scheduler()->OnRequestError(0);
scheduler()->ShouldSessionRequestData(
- /*has_content*/ false, now, /*has_outstanding_request*/ false);
+ /*has_content*/ true, now, /*has_outstanding_request*/ false);
scheduler()->OnForegrounded();
EXPECT_EQ(2, histogram_tester.GetBucketCount(ntpOpenedHistogram, 0));
EXPECT_EQ(2, histogram_tester.GetBucketCount(forgroundedHistogram, 0));
diff --git a/chromium/components/feed/core/proto/BUILD.gn b/chromium/components/feed/core/proto/BUILD.gn
index 2dfff8a2e5e..3a0b51b9a76 100644
--- a/chromium/components/feed/core/proto/BUILD.gn
+++ b/chromium/components/feed/core/proto/BUILD.gn
@@ -6,7 +6,6 @@ import("//third_party/protobuf/proto_library.gni")
proto_library("proto") {
sources = [
- "cached_image.proto",
"content_storage.proto",
"journal_storage.proto",
]
diff --git a/chromium/components/feed/core/proto/cached_image.proto b/chromium/components/feed/core/proto/cached_image.proto
deleted file mode 100644
index 960143697eb..00000000000
--- a/chromium/components/feed/core/proto/cached_image.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package feed;
-
-message CachedImageProto {
- // The URL of the original source, ex. https://www.chromium.org/image.png.
- optional string url = 1;
-
- // Raw image data fetched from network.
- optional bytes data = 2;
-
- // Last used time (in microseconds since the origin (or "zero") point.).
- optional int64 last_used_time = 3;
-}
diff --git a/chromium/components/feed/core/user_classifier_unittest.cc b/chromium/components/feed/core/user_classifier_unittest.cc
index 8a8eb0302fe..ddb6895247b 100644
--- a/chromium/components/feed/core/user_classifier_unittest.cc
+++ b/chromium/components/feed/core/user_classifier_unittest.cc
@@ -296,7 +296,7 @@ TEST_P(FeedUserClassifierEventTest,
Eq(rate_after_a_year));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
, // An empty prefix for the parametrized tests names (no need to
// distinguish the only instance we make here).
FeedUserClassifierEventTest,
diff --git a/chromium/components/feedback/anonymizer_tool.cc b/chromium/components/feedback/anonymizer_tool.cc
index 39ea9cdd06d..b5acfd7673c 100644
--- a/chromium/components/feedback/anonymizer_tool.cc
+++ b/chromium/components/feedback/anonymizer_tool.cc
@@ -7,7 +7,7 @@
#include <memory>
#include <utility>
-#include "base/stl_util.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -59,13 +59,46 @@ constexpr const char* kCustomPatternsWithContext[] = {
"(?i-s)(serial\\s*(?:number)?\\s*[:=]\\s*)([0-9a-zA-Z\\-\"]+)()",
};
-// Returns the number of leading bytes that may be kept unsanitized.
-std::string MaybeScrubIPv4Address(const std::string& addr) {
+bool MaybeUnmapAddress(net::IPAddress* addr) {
+ if (!addr->IsIPv4MappedIPv6())
+ return false;
+
+ *addr = net::ConvertIPv4MappedIPv6ToIPv4(*addr);
+ return true;
+}
+
+bool MaybeUntranslateAddress(net::IPAddress* addr) {
+ if (!addr->IsIPv6())
+ return false;
+
+ static const net::IPAddress kTranslated6To4(0, 0x64, 0xff, 0x9b, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0);
+ if (!IPAddressMatchesPrefix(*addr, kTranslated6To4, 96))
+ return false;
+
+ const auto bytes = addr->bytes();
+ *addr = net::IPAddress(bytes[12], bytes[13], bytes[14], bytes[15]);
+ return true;
+}
+
+// If |addr| points to a valid IPv6 address, this function truncates it at /32.
+bool MaybeTruncateIPv6(net::IPAddress* addr) {
+ if (!addr->IsIPv6())
+ return false;
+
+ const auto bytes = addr->bytes();
+ *addr = net::IPAddress(bytes[0], bytes[1], bytes[2], bytes[3], 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0);
+ return true;
+}
+
+// Returns an appropriately scrubbed version of |addr| if applicable.
+std::string MaybeScrubIPAddress(const std::string& addr) {
struct {
net::IPAddress ip_addr;
int prefix_length;
bool scrub;
- } static const kWhitelistedIPv4Ranges[] = {
+ } static const kWhitelistedIPRanges[] = {
// Private.
{net::IPAddress(10, 0, 0, 0), 8, true},
{net::IPAddress(172, 16, 0, 0), 12, true},
@@ -84,20 +117,57 @@ std::string MaybeScrubIPv4Address(const std::string& addr) {
{net::IPAddress(224, 0, 0, 0), 4, true},
// Link local.
{net::IPAddress(169, 254, 0, 0), 16, true},
+ {net::IPAddress(0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 10,
+ true},
// Broadcast.
{net::IPAddress(255, 255, 255, 255), 32, false},
+ // IPv6 loopback, unspecified and non-address strings.
+ {net::IPAddress::IPv6AllZeros(), 112, false},
+ // IPv6 multicast all nodes and routers.
+ {net::IPAddress(0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1),
+ 128, false},
+ {net::IPAddress(0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2),
+ 128, false},
+ {net::IPAddress(0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1),
+ 128, false},
+ {net::IPAddress(0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2),
+ 128, false},
+ // IPv6 other multicast (link and interface local).
+ {net::IPAddress(0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 16,
+ true},
+ {net::IPAddress(0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 16,
+ true},
+
};
net::IPAddress input_addr;
- if (input_addr.AssignFromIPLiteral(addr) && input_addr.IsIPv4()) {
- for (const auto& range : kWhitelistedIPv4Ranges) {
+ if (input_addr.AssignFromIPLiteral(addr) && input_addr.IsValid()) {
+ bool mapped = MaybeUnmapAddress(&input_addr);
+ bool translated = !mapped ? MaybeUntranslateAddress(&input_addr) : false;
+ for (const auto& range : kWhitelistedIPRanges) {
if (IPAddressMatchesPrefix(input_addr, range.ip_addr,
range.prefix_length)) {
- return range.scrub ? base::StringPrintf(
- "%s/%d", range.ip_addr.ToString().c_str(),
- range.prefix_length)
- : addr;
+ std::string prefix;
+ std::string out_addr = addr;
+ if (mapped) {
+ prefix = "M ";
+ out_addr = input_addr.ToString();
+ } else if (translated) {
+ prefix = "T ";
+ out_addr = input_addr.ToString();
+ }
+ if (range.scrub) {
+ out_addr = base::StringPrintf(
+ "%s/%d", range.ip_addr.ToString().c_str(), range.prefix_length);
+ }
+ return base::StrCat({prefix, out_addr});
}
}
+ // |addr| may have been over-aggressively matched as an IPv6 address when
+ // it's really just an arbitrary part of a sentence. If the string is the
+ // same as the coarsely truncated address then keep it because even if
+ // it happens to be a real address, there is no loss of anonymity.
+ if (MaybeTruncateIPv6(&input_addr) && input_addr.ToString() == addr)
+ return addr;
}
return "";
}
@@ -390,7 +460,7 @@ std::string AnonymizerTool::AnonymizeCustomPatternWithContext(
std::string matched_id_as_string = matched_id.as_string();
std::string replacement_id = (*identifier_space)[matched_id_as_string];
if (replacement_id.empty()) {
- replacement_id = base::IntToString(identifier_space->size());
+ replacement_id = base::NumberToString(identifier_space->size());
(*identifier_space)[matched_id_as_string] = replacement_id;
}
@@ -403,6 +473,13 @@ std::string AnonymizerTool::AnonymizeCustomPatternWithContext(
return result;
}
+bool WhitelistMatchedId(re2::StringPiece matched_id) {
+ bool is_safe_chrome_resource =
+ matched_id.starts_with("chrome://resources/") &&
+ !matched_id.contains("?");
+ return is_safe_chrome_resource;
+}
+
std::string AnonymizerTool::AnonymizeCustomPatternWithoutContext(
const std::string& input,
const CustomPatternWithoutContext& pattern,
@@ -418,10 +495,15 @@ std::string AnonymizerTool::AnonymizeCustomPatternWithoutContext(
re2::StringPiece skipped;
re2::StringPiece matched_id;
while (FindAndConsumeAndGetSkipped(&text, *re, &skipped, &matched_id)) {
+ if (WhitelistMatchedId(matched_id)) {
+ skipped.AppendToString(&result);
+ matched_id.AppendToString(&result);
+ continue;
+ }
std::string matched_id_as_string = matched_id.as_string();
std::string replacement_id = (*identifier_space)[matched_id_as_string];
if (replacement_id.empty()) {
- replacement_id = MaybeScrubIPv4Address(matched_id_as_string);
+ replacement_id = MaybeScrubIPAddress(matched_id_as_string);
if (replacement_id != matched_id_as_string) {
// The weird Uint64toString trick is because Windows does not like
// to deal with %zu and a size_t in printf, nor does it support %llu.
diff --git a/chromium/components/feedback/anonymizer_tool_unittest.cc b/chromium/components/feedback/anonymizer_tool_unittest.cc
index 6464e027011..c2f9a6e7d44 100644
--- a/chromium/components/feedback/anonymizer_tool_unittest.cc
+++ b/chromium/components/feedback/anonymizer_tool_unittest.cc
@@ -6,7 +6,6 @@
#include <gtest/gtest.h>
-#include "base/stl_util.h"
#include "base/strings/string_util.h"
namespace feedback {
@@ -132,7 +131,7 @@ TEST_F(AnonymizerToolTest, AnonymizeCustomPatterns) {
EXPECT_EQ("[<IPv6: 2>]",
AnonymizeCustomPatterns("[2001:db8:0:0:0:ff00:42:8329]"));
EXPECT_EQ("[<IPv6: 3>]", AnonymizeCustomPatterns("[2001:db8::ff00:42:8329]"));
- EXPECT_EQ("[<IPv6: 4>]", AnonymizeCustomPatterns("[::1]"));
+ EXPECT_EQ("[<IPv6: 4>]", AnonymizeCustomPatterns("[aa::bb]"));
EXPECT_EQ("<IPv4: 1>", AnonymizeCustomPatterns("192.160.0.1"));
EXPECT_EQ("<URL: 1>",
@@ -228,6 +227,10 @@ TEST_F(AnonymizerToolTest, AnonymizeChunk) {
"192.169.2.120\n" // IP address.
"169.254.0.1\n" // Link local.
"169.200.0.1\n" // IP address.
+ "fe80::\n" // Link local.
+ "fe80::ffff\n" // Link local.
+ "febf:ffff::ffff\n" // Link local.
+ "fecc::1111\n" // IP address.
"224.0.0.24\n" // Multicast.
"240.0.0.0\n" // IP address.
"255.255.255.255\n" // Broadcast.
@@ -243,7 +246,32 @@ TEST_F(AnonymizerToolTest, AnonymizeChunk) {
"11:11;11::11\n" // IP address.
"11::11\n" // IP address.
"11:11:abcdef:0:0:0:0:0\n" // No PII.
- "aa:aa:aa:aa:aa:aa"; // MAC address (BSSID).
+ "::\n" // Unspecified.
+ "::1\n" // Local host.
+ "Instance::Set\n" // Ignore match, no PII.
+ "Instant::ff\n" // Ignore match, no PII.
+ "net::ERR_CONN_TIMEOUT\n" // Ignore match, no PII.
+ "ff01::1\n" // All nodes address (interface local).
+ "ff01::2\n" // All routers (interface local).
+ "ff01::3\n" // Multicast (interface local).
+ "ff02::1\n" // All nodes address (link local).
+ "ff02::2\n" // All routers (link local).
+ "ff02::3\n" // Multicast (link local).
+ "ff02::fb\n" // mDNSv6 (link local).
+ "ff08::fb\n" // mDNSv6.
+ "ff0f::101\n" // All NTP servers.
+ "::ffff:cb0c:10ea\n" // IPv4-mapped IPV6 (IP address).
+ "::ffff:a0a:a0a\n" // IPv4-mapped IPV6 (private class A).
+ "::ffff:a0a:a0a\n" // Intentional duplicate.
+ "::ffff:ac1e:1e1e\n" // IPv4-mapped IPV6 (private class B).
+ "::ffff:c0a8:640a\n" // IPv4-mapped IPV6 (private class C).
+ "::ffff:6473:5c01\n" // IPv4-mapped IPV6 (Chrome).
+ "64:ff9b::a0a:a0a\n" // IPv4-translated 6to4 IPV6 (private class A).
+ "64:ff9b::6473:5c01\n" // IPv4-translated 6to4 IPV6 (Chrome).
+ "::0101:ffff:c0a8:640a\n" // IP address.
+ "aa:aa:aa:aa:aa:aa\n" // MAC address (BSSID).
+ "chrome://resources/foo\n" // Secure chrome resource, whitelisted.
+ "chrome://resources/f?user=bar"; // Potentially PII in parameter.
std::string result =
"aaaaaaaa [SSID=1]aaaaa\n"
"aaaaaaaa<URL: 1>\n"
@@ -268,6 +296,10 @@ TEST_F(AnonymizerToolTest, AnonymizeChunk) {
"<IPv4: 16>\n"
"<169.254.0.0/16: 17>\n"
"<IPv4: 18>\n"
+ "<fe80::/10: 1>\n"
+ "<fe80::/10: 2>\n"
+ "<fe80::/10: 3>\n"
+ "<IPv6: 4>\n"
"<224.0.0.0/4: 19>\n"
"<IPv4: 20>\n"
"255.255.255.255\n"
@@ -280,10 +312,35 @@ TEST_F(AnonymizerToolTest, AnonymizeChunk) {
"255.255.259.255\n"
"255.300.255.255\n"
"aaaa<IPv4: 28>aaa\n"
- "11:11;<IPv6: 1>\n"
- "<IPv6: 1>\n"
+ "11:11;<IPv6: 5>\n"
+ "<IPv6: 5>\n"
"11:11:abcdef:0:0:0:0:0\n"
- "aa:aa:aa:00:00:01";
+ "::\n"
+ "::1\n"
+ "Instance::Set\n"
+ "Instant::ff\n"
+ "net::ERR_CONN_TIMEOUT\n"
+ "ff01::1\n"
+ "ff01::2\n"
+ "<ff01::/16: 13>\n"
+ "ff02::1\n"
+ "ff02::2\n"
+ "<ff02::/16: 16>\n"
+ "<ff02::/16: 17>\n"
+ "<IPv6: 18>\n"
+ "<IPv6: 19>\n"
+ "<IPv6: 20>\n"
+ "<M 10.0.0.0/8: 21>\n"
+ "<M 10.0.0.0/8: 21>\n"
+ "<M 172.16.0.0/12: 22>\n"
+ "<M 192.168.0.0/16: 23>\n"
+ "<M 100.115.92.1: 24>\n"
+ "<T 10.0.0.0/8: 25>\n"
+ "<T 100.115.92.1: 26>\n"
+ "<IPv6: 27>\n"
+ "aa:aa:aa:00:00:01\n"
+ "chrome://resources/foo\n"
+ "<URL: 2>";
EXPECT_EQ(result, anonymizer_.Anonymize(data));
}
diff --git a/chromium/components/feedback/feedback_data.cc b/chromium/components/feedback/feedback_data.cc
index cbdc281af3c..38fab874a1b 100644
--- a/chromium/components/feedback/feedback_data.cc
+++ b/chromium/components/feedback/feedback_data.cc
@@ -27,6 +27,11 @@ namespace {
const char kTraceFilename[] = "tracing.zip";
const char kPerformanceCategoryTag[] = "Performance";
+const base::FilePath::CharType kHistogramsFilename[] =
+ FILE_PATH_LITERAL("histograms.txt");
+
+const char kHistogramsAttachmentName[] = "histograms.zip";
+
} // namespace
FeedbackData::FeedbackData(feedback::FeedbackUploader* uploader)
@@ -34,7 +39,9 @@ FeedbackData::FeedbackData(feedback::FeedbackUploader* uploader)
context_(nullptr),
trace_id_(0),
pending_op_count_(1),
- report_sent_(false) {
+ report_sent_(false),
+ from_assistant_(false),
+ assistant_debug_info_allowed_(false) {
CHECK(uploader_);
}
@@ -72,6 +79,21 @@ void FeedbackData::SetAndCompressSystemInfo(
}
}
+void FeedbackData::SetAndCompressHistograms(
+ std::unique_ptr<std::string> histograms) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!histograms)
+ return;
+ ++pending_op_count_;
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&FeedbackData::CompressFile, this,
+ base::FilePath(kHistogramsFilename),
+ kHistogramsAttachmentName, std::move(histograms)),
+ base::BindOnce(&FeedbackData::OnCompressComplete, this));
+}
+
void FeedbackData::AttachAndCompressFileData(
std::unique_ptr<std::string> attached_filedata) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chromium/components/feedback/feedback_data.h b/chromium/components/feedback/feedback_data.h
index ab3085e102f..46bbc335a74 100644
--- a/chromium/components/feedback/feedback_data.h
+++ b/chromium/components/feedback/feedback_data.h
@@ -34,6 +34,10 @@ class FeedbackData : public FeedbackCommon {
// compression.
void SetAndCompressSystemInfo(std::unique_ptr<SystemLogsMap> sys_info);
+ // Sets the histograms for this instance and kicks off its
+ // compression.
+ void SetAndCompressHistograms(std::unique_ptr<std::string> histograms);
+
// Sets the attached file data and kicks off its compression.
void AttachAndCompressFileData(
std::unique_ptr<std::string> attached_filedata);
@@ -50,6 +54,10 @@ class FeedbackData : public FeedbackCommon {
content::BrowserContext* context() const { return context_; }
const std::string& attached_file_uuid() const { return attached_file_uuid_; }
const std::string& screenshot_uuid() const { return screenshot_uuid_; }
+ bool from_assistant() const { return from_assistant_; }
+ bool assistant_debug_info_allowed() const {
+ return assistant_debug_info_allowed_;
+ }
// Setters
void set_context(content::BrowserContext* context) { context_ = context; }
@@ -63,6 +71,12 @@ class FeedbackData : public FeedbackCommon {
screenshot_uuid_ = uuid;
}
void set_trace_id(int trace_id) { trace_id_ = trace_id; }
+ void set_from_assistant(bool from_assistant) {
+ from_assistant_ = from_assistant;
+ }
+ void set_assistant_debug_info_allowed(bool assistant_debug_info_allowed) {
+ assistant_debug_info_allowed_ = assistant_debug_info_allowed;
+ }
private:
~FeedbackData() override;
@@ -85,6 +99,8 @@ class FeedbackData : public FeedbackCommon {
int pending_op_count_;
bool report_sent_;
+ bool from_assistant_;
+ bool assistant_debug_info_allowed_;
DISALLOW_COPY_AND_ASSIGN(FeedbackData);
};
diff --git a/chromium/components/feedback/feedback_data_unittest.cc b/chromium/components/feedback/feedback_data_unittest.cc
index eca8e22a244..1ca48b66b83 100644
--- a/chromium/components/feedback/feedback_data_unittest.cc
+++ b/chromium/components/feedback/feedback_data_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "components/feedback/feedback_report.h"
@@ -23,6 +24,7 @@ namespace feedback {
namespace {
+constexpr char kHistograms[] = "Histogram Data";
constexpr char kImageData[] = "Image Data";
constexpr char kFileData[] = "File Data";
@@ -96,6 +98,7 @@ class FeedbackDataTest : public testing::Test {
};
TEST_F(FeedbackDataTest, ReportSending) {
+ data_->SetAndCompressHistograms(MakeScoped(kHistograms));
data_->set_image(MakeScoped(kImageData));
data_->AttachAndCompressFileData(MakeScoped(kFileData));
Send();
diff --git a/chromium/components/feedback/feedback_report.cc b/chromium/components/feedback/feedback_report.cc
index ced788fedf0..4b0d80410a4 100644
--- a/chromium/components/feedback/feedback_report.cc
+++ b/chromium/components/feedback/feedback_report.cc
@@ -4,6 +4,7 @@
#include "components/feedback/feedback_report.h"
+#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
diff --git a/chromium/components/feedback/feedback_uploader.cc b/chromium/components/feedback/feedback_uploader.cc
index 20e3caed1c1..90a5b3fd496 100644
--- a/chromium/components/feedback/feedback_uploader.cc
+++ b/chromium/components/feedback/feedback_uploader.cc
@@ -4,6 +4,7 @@
#include "components/feedback/feedback_uploader.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
@@ -168,11 +169,11 @@ void FeedbackUploader::DispatchReport() {
resource_request->method = "POST";
// Tell feedback server about the variation state of this install.
- variations::AppendVariationHeadersUnknownSignedIn(
+ variations::AppendVariationsHeaderUnknownSignedIn(
feedback_post_url_,
context_->IsOffTheRecord() ? variations::InIncognito::kYes
: variations::InIncognito::kNo,
- &resource_request->headers);
+ resource_request.get());
AppendExtraHeadersToUploadRequest(resource_request.get());
diff --git a/chromium/components/feedback/feedback_uploader_dispatch_unittest.cc b/chromium/components/feedback/feedback_uploader_dispatch_unittest.cc
index 7e5186d72f3..00977f67e26 100644
--- a/chromium/components/feedback/feedback_uploader_dispatch_unittest.cc
+++ b/chromium/components/feedback/feedback_uploader_dispatch_unittest.cc
@@ -13,6 +13,7 @@
#include "base/task/task_traits.h"
#include "base/test/bind_test_util.h"
#include "components/feedback/feedback_uploader_factory.h"
+#include "components/variations/net/variations_http_headers.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_http_header_provider.h"
#include "content/public/test/test_browser_context.h"
@@ -97,16 +98,12 @@ TEST_F(FeedbackUploaderDispatchTest, VariationHeaders) {
net::HttpRequestHeaders headers;
test_url_loader_factory()->SetInterceptor(
base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
- headers = request.headers;
+ EXPECT_TRUE(variations::HasVariationsHeader(request));
}));
QueueReport(&uploader, "test");
base::RunLoop().RunUntilIdle();
- std::string value;
- EXPECT_TRUE(headers.GetHeader("X-Client-Data", &value));
- EXPECT_FALSE(value.empty());
-
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
diff --git a/chromium/components/flags_ui/feature_entry.cc b/chromium/components/flags_ui/feature_entry.cc
index e1d703fc00b..ede91139642 100644
--- a/chromium/components/flags_ui/feature_entry.cc
+++ b/chromium/components/flags_ui/feature_entry.cc
@@ -55,7 +55,7 @@ std::string FeatureEntry::NameForOption(int index) const {
type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE);
DCHECK_LT(index, num_options);
return std::string(internal_name) + testing::kMultiSeparator +
- base::IntToString(index);
+ base::NumberToString(index);
}
base::string16 FeatureEntry::DescriptionForOption(int index) const {
diff --git a/chromium/components/flags_ui/flags_state.cc b/chromium/components/flags_ui/flags_state.cc
index 611439768eb..0ae3d7d1eec 100644
--- a/chromium/components/flags_ui/flags_state.cc
+++ b/chromium/components/flags_ui/flags_state.cc
@@ -411,8 +411,6 @@ void FlagsState::SetOriginListFlag(const std::string& internal_name,
std::set<std::string> enabled_entries;
GetSanitizedEnabledFlags(flags_storage, &enabled_entries);
- // const bool enabled =
- // enabled_entries.find(entry->internal_name) != enabled_entries.end();
const bool enabled = base::ContainsKey(enabled_entries, entry->internal_name);
switch_values_[entry->command_line_switch] = value;
DidModifyOriginListFlag(*entry, enabled);
diff --git a/chromium/components/flags_ui/resources/flags.css b/chromium/components/flags_ui/resources/flags.css
index ce18774832f..18bcec2c3d7 100644
--- a/chromium/components/flags_ui/resources/flags.css
+++ b/chromium/components/flags_ui/resources/flags.css
@@ -16,6 +16,8 @@ body {
--color-light-gray: rgba(0, 0, 0, 0.54);
--color-shadow: rgba(0, 0, 0, 0.1);
--ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1);
+ --keyboard-focus-ring: rgba(66, 133, 244, 0.4);
+ --google-blue-400: rgb(102, 157, 246);
--google-blue-500: rgb(66, 133, 244);
--google-blue-700: rgb(51, 103, 214);
--google-gray-100: rgb(245, 245, 245);
@@ -88,12 +90,12 @@ h2 {
#header .flex-container .flex:first-child,
[dir='rtl'] #header .flex-container .flex:last-child {
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
}
#header .flex-container .flex:last-child,
[dir='rtl'] #header .flex-container .flex:first-child {
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
.hidden {
@@ -205,7 +207,7 @@ h2 {
}
[dir='rtl'] .experiment .flex-container .flex:first-child {
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
.experiment p {
@@ -243,7 +245,7 @@ h2 {
.experiment-actions {
flex: 0 0 auto;
padding-inline-start: 5px;
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
width: 150px;
}
@@ -290,7 +292,7 @@ h2 {
margin: 0;
padding: 0;
position: relative;
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
width: 100%;
}
@@ -347,7 +349,8 @@ h2 {
margin-inline-start: -100%;
}
-.selected .tab-content {
+.selected .tab-content,
+.selected .tab-content .template {
display: block;
}
@@ -369,11 +372,11 @@ h2 {
}
#needs-restart .flex:last-child {
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
[dir='rtl'] #needs-restart .flex:last-child {
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
}
#needs-restart.show {
@@ -390,33 +393,33 @@ h2 {
line-height: 1.4;
}
-.experiment-restart-button {
- background: var(--google-blue-700);
+#experiment-restart-button {
+ background: var(--google-blue-500);
border: 0;
border-radius: 3px;
color: white;
font-size: 14px;
padding: 14px 38px;
- text-transform: uppercase;
}
-.experiment-restart-button:active,
-.experiment-restart-button:focus {
- background: var(--google-blue-500);
+#experiment-restart-button:active,
+#experiment-restart-button:focus,
+#experiment-restart-button:hover {
+ background: var(--google-blue-400);
outline: 0;
}
-.experiment-restart-button:hover {
- background: var(--google-blue-500);
+html.focus-outline-visible #experiment-restart-button:focus {
+ box-shadow: 0 0 0 1px var(--keyboard-focus-ring);
}
#version {
color: var(--color-light-gray);
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
[dir='rtl'] #version {
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
}
@media (max-width: 360px) {
@@ -433,7 +436,7 @@ h2 {
text-align: initial;
}
- .experiment-restart-button {
+ #experiment-restart-button {
padding: 8px;
}
@@ -466,7 +469,7 @@ h2 {
.experiment .experiment-actions {
max-width: 100%;
padding-top: 12px;
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
width: 100%;
}
@@ -476,11 +479,11 @@ h2 {
#flagsTemplate > .flex-container:first-child:not('.version') {
flex-direction: column;
- text-align: left;
+ text-align: left; /* csschecker-disable-line left-right */
}
[dir='rtl'] #flagsTemplate > .flex-container:first-child {
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
#flagsTemplate > .flex-container:first-child .flex {
@@ -488,14 +491,14 @@ h2 {
}
[dir='rtl'] #flagsTemplate > .flex-container #version {
- text-align: right;
+ text-align: right; /* csschecker-disable-line left-right */
}
#needs-restart {
padding: 8px 12px;
}
- .experiment-restart-button {
+ #experiment-restart-button {
padding: 8px 16px;
}
diff --git a/chromium/components/flags_ui/resources/flags.html b/chromium/components/flags_ui/resources/flags.html
index 1de2f91fb37..1ce6c979bc6 100644
--- a/chromium/components/flags_ui/resources/flags.html
+++ b/chromium/components/flags_ui/resources/flags.html
@@ -16,6 +16,8 @@
<script src="chrome://resources/js/ios/web_ui.js"></script>
</if>
+<script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
<script src="chrome://resources/js/util.js"></script>
</head>
<body>
@@ -74,6 +76,8 @@
tabindex="4">Available</a>
<div id="tab-content-available" class="tab-content"
role="tabpanel" aria-labelledby="tab-available" aria-hidden="false">
+ </div>
+ <div id="tab-content-available-template" class="template hidden">
<!-- Non default experiments. -->
<div jsselect="supportedFeatures"
jsvalues="id:internal_name; class: is_default ? 'hidden' : 'experiment'"
@@ -205,7 +209,7 @@
<div class="flex restart-notice" jstcache="0">$i18n{flagsRestartNotice}</div>
<div class="flex">
<if expr="not is_ios">
- <button class="experiment-restart-button" type="button" tabindex="9">
+ <button id="experiment-restart-button" type="button" tabindex="9">
<if expr="not chromeos">
Relaunch Now
</if>
diff --git a/chromium/components/flags_ui/resources/flags.js b/chromium/components/flags_ui/resources/flags.js
index c6f320f4952..c993e9696d4 100644
--- a/chromium/components/flags_ui/resources/flags.js
+++ b/chromium/components/flags_ui/resources/flags.js
@@ -15,8 +15,32 @@
* See returnFlagsExperiments() for the structure of this object.
*/
function renderTemplate(experimentalFeaturesData) {
- // This is the javascript code that processes the template:
- jstProcess(new JsEvalContext(experimentalFeaturesData), $('flagsTemplate'));
+ var templateToProcess = jstGetTemplate('tab-content-available-template');
+ var content = $('tab-content-available');
+
+ if (content.childNodes > 0) {
+ // Already processed, use the internal content area template.
+ templateToProcess = content;
+ } else {
+ // Duplicate the template into the content area.
+ // This prevents the misrendering of available flags when the template
+ // is rerendered. Example - resetting flags.
+ content.textContent = '';
+ content.appendChild(templateToProcess);
+ }
+
+ // Process the templates: available / unavailable flags.
+ jstProcess(new JsEvalContext(experimentalFeaturesData), templateToProcess);
+
+ // Unavailable flags are not shown on iOS.
+ var unavailableTemplate = $('tab-content-unavailable');
+ if (unavailableTemplate) {
+ jstProcess(new JsEvalContext(experimentalFeaturesData),
+ $('tab-content-unavailable'));
+ }
+
+ // Update the restart container.
+ jstProcess(new JsEvalContext(experimentalFeaturesData), $('needs-restart'));
// Add handlers to dynamically created HTML elements.
var elements = document.getElementsByClassName('experiment-select');
@@ -44,9 +68,10 @@ function renderTemplate(experimentalFeaturesData) {
};
}
- elements = document.getElementsByClassName('experiment-restart-button');
- for (var i = 0; i < elements.length; ++i) {
- elements[i].onclick = restartBrowser;
+ var element = $('experiment-restart-button');
+ assert(element || cr.isIOS);
+ if (element) {
+ element.onclick = restartBrowser;
}
// Tab panel selection.
@@ -467,8 +492,12 @@ FlagSearch.prototype = {
}
};
-// Get and display the data upon loading.
-document.addEventListener('DOMContentLoaded', requestExperimentalFeaturesData);
+document.addEventListener('DOMContentLoaded', function() {
+ // Get and display the data upon loading.
+ requestExperimentalFeaturesData();
+
+ cr.ui.FocusOutlineManager.forDocument(document);
+});
// Update the highlighted flag when the hash changes.
window.addEventListener('hashchange', highlightReferencedFlag);
diff --git a/chromium/components/google/core/browser/google_url_tracker_unittest.cc b/chromium/components/google/core/browser/google_url_tracker_unittest.cc
index e48252f8b50..12586c2c3e2 100644
--- a/chromium/components/google/core/browser/google_url_tracker_unittest.cc
+++ b/chromium/components/google/core/browser/google_url_tracker_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
diff --git a/chromium/components/google/core/browser/google_util_unittest.cc b/chromium/components/google/core/browser/google_util_unittest.cc
index a6ef4c5a89f..fa417846b7b 100644
--- a/chromium/components/google/core/browser/google_util_unittest.cc
+++ b/chromium/components/google/core/browser/google_util_unittest.cc
@@ -448,3 +448,29 @@ TEST(GoogleUtilTest, YoutubeDomains) {
google_util::DISALLOW_SUBDOMAIN,
google_util::DISALLOW_NON_STANDARD_PORTS));
}
+
+TEST(GoogleUtilTest, GoogleAssociatedDomains) {
+ EXPECT_FALSE(google_util::IsGoogleAssociatedDomainUrl(GURL()));
+
+ EXPECT_FALSE(google_util::IsGoogleAssociatedDomainUrl(GURL("invalid")));
+
+ EXPECT_FALSE(
+ google_util::IsGoogleAssociatedDomainUrl(GURL("https://myblog.com.au")));
+
+ // A typical URL for a Google production API.
+ EXPECT_TRUE(google_util::IsGoogleAssociatedDomainUrl(
+ GURL("https://myapi-pa.googleapis.com/v1/myservice")));
+
+ // A typical URL for a test instance of a Google API.
+ EXPECT_TRUE(google_util::IsGoogleAssociatedDomainUrl(
+ GURL("https://daily0-myapi-pa.sandbox.googleapis.com/v1/myservice")));
+
+ // A Google production API with parameters.
+ EXPECT_TRUE(google_util::IsGoogleAssociatedDomainUrl(
+ GURL("https://myapi-pa.googleapis.com/v1/myservice?k1=v1&k2=v2")));
+
+ // A Google test API with parameters.
+ EXPECT_TRUE(google_util::IsGoogleAssociatedDomainUrl(
+ GURL("https://daily0-myapi-pa.sandbox.googleapis.com/v1/"
+ "myservice?k1=v1&k2=v2")));
+}
diff --git a/chromium/components/google/core/common/google_util.cc b/chromium/components/google/core/common/google_util.cc
index 6f24e216983..491ec0d65a9 100644
--- a/chromium/components/google/core/common/google_util.cc
+++ b/chromium/components/google/core/common/google_util.cc
@@ -288,6 +288,49 @@ bool IsYoutubeDomainUrl(const GURL& url,
nullptr);
}
+bool IsGoogleAssociatedDomainUrl(const GURL& url) {
+ if (IsGoogleDomainUrl(url, ALLOW_SUBDOMAIN, ALLOW_NON_STANDARD_PORTS))
+ return true;
+
+ if (IsYoutubeDomainUrl(url, ALLOW_SUBDOMAIN, ALLOW_NON_STANDARD_PORTS))
+ return true;
+
+ // Some domains don't have international TLD extensions, so testing for them
+ // is very straightforward.
+ static const char* kSuffixesToSetHeadersFor[] = {
+ ".android.com",
+ ".doubleclick.com",
+ ".doubleclick.net",
+ ".ggpht.com",
+ ".googleadservices.com",
+ ".googleapis.com",
+ ".googlesyndication.com",
+ ".googleusercontent.com",
+ ".googlevideo.com",
+ ".gstatic.com",
+ ".litepages.googlezip.net",
+ ".ytimg.com",
+ };
+ const std::string host = url.host();
+ for (size_t i = 0; i < base::size(kSuffixesToSetHeadersFor); ++i) {
+ if (base::EndsWith(host, kSuffixesToSetHeadersFor[i],
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return true;
+ }
+ }
+
+ // Exact hostnames in lowercase to set headers for.
+ static const char* kHostsToSetHeadersFor[] = {
+ "googleweblight.com",
+ };
+ for (size_t i = 0; i < base::size(kHostsToSetHeadersFor); ++i) {
+ if (base::LowerCaseEqualsASCII(host, kHostsToSetHeadersFor[i]))
+ return true;
+ }
+
+ return false;
+}
+
const std::vector<std::string>& GetGoogleRegistrableDomains() {
static base::NoDestructor<std::vector<std::string>>
kGoogleRegisterableDomains([]() {
diff --git a/chromium/components/google/core/common/google_util.h b/chromium/components/google/core/common/google_util.h
index 69b155e28ef..70957e16170 100644
--- a/chromium/components/google/core/common/google_util.h
+++ b/chromium/components/google/core/common/google_util.h
@@ -86,9 +86,8 @@ bool IsGoogleHostname(base::StringPiece host,
// port for its scheme (80 for HTTP, 443 for HTTPS).
//
// Note that this only checks for google.<TLD> domains, but not other Google
-// properties. There is code in variations_http_header_provider.cc that checks
-// for additional Google properties, which can be moved here if more callers
-// are interested in this in the future.
+// properties. If you want to check domains including other Google properties,
+// you can use IsGoogleAssociatedDomainUrl() below.
bool IsGoogleDomainUrl(const GURL& url,
SubdomainPermission subdomain_permission,
PortPermission port_permission);
@@ -106,6 +105,9 @@ bool IsYoutubeDomainUrl(const GURL& url,
SubdomainPermission subdomain_permission,
PortPermission port_permission);
+// True if |url| is hosted by Google.
+bool IsGoogleAssociatedDomainUrl(const GURL& url);
+
// Returns the list of all Google's registerable domains, i.e. domains named
// google.<eTLD> owned by Google.
// TODO(msramek): This is currently only used to ensure the deletion of Google
diff --git a/chromium/components/grpc_support/bidirectional_stream.cc b/chromium/components/grpc_support/bidirectional_stream.cc
index 7a6e43a6056..1d13e638cc5 100644
--- a/chromium/components/grpc_support/bidirectional_stream.cc
+++ b/chromium/components/grpc_support/bidirectional_stream.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
diff --git a/chromium/components/grpc_support/bidirectional_stream_c.cc b/chromium/components/grpc_support/bidirectional_stream_c.cc
index b72e76235ed..8b739a4ccdc 100644
--- a/chromium/components/grpc_support/bidirectional_stream_c.cc
+++ b/chromium/components/grpc_support/bidirectional_stream_c.cc
@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "components/grpc_support/bidirectional_stream.h"
diff --git a/chromium/components/grpc_support/bidirectional_stream_unittest.cc b/chromium/components/grpc_support/bidirectional_stream_unittest.cc
index 4db647a5967..3a8ed4e95f6 100644
--- a/chromium/components/grpc_support/bidirectional_stream_unittest.cc
+++ b/chromium/components/grpc_support/bidirectional_stream_unittest.cc
@@ -707,8 +707,8 @@ TEST_P(BidirectionalStreamTest, FailedResolution) {
bidirectional_stream_destroy(test.stream);
}
-INSTANTIATE_TEST_CASE_P(BidirectionalStreamDelayRequestHeadersUntilFlush,
- BidirectionalStreamTest,
- ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(BidirectionalStreamDelayRequestHeadersUntilFlush,
+ BidirectionalStreamTest,
+ ::testing::Values(true, false));
} // namespace grpc_support
diff --git a/chromium/components/guest_view/browser/guest_view_base.cc b/chromium/components/guest_view/browser/guest_view_base.cc
index e1b85d3a9fa..1bf94187e29 100644
--- a/chromium/components/guest_view/browser/guest_view_base.cc
+++ b/chromium/components/guest_view/browser/guest_view_base.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
@@ -548,7 +549,7 @@ void GuestViewBase::WillAttach(WebContents* embedder_web_contents,
WillAttachToEmbedder();
if (content::GuestMode::IsCrossProcessFrameGuest(web_contents())) {
- web_contents()->AttachToOuterWebContentsFrame(
+ owner_web_contents_->AttachInnerWebContents(
base::WrapUnique<WebContents>(web_contents()), outer_contents_frame);
// TODO(ekaramad): MimeHandlerViewGuest might not need this ACK
// (https://crbug.com/659750).
diff --git a/chromium/components/guest_view/browser/test_guest_view_manager.cc b/chromium/components/guest_view/browser/test_guest_view_manager.cc
index e4b269e57f9..e81907e2cf1 100644
--- a/chromium/components/guest_view/browser/test_guest_view_manager.cc
+++ b/chromium/components/guest_view/browser/test_guest_view_manager.cc
@@ -54,7 +54,7 @@ void TestGuestViewManager::WaitForAllGuestsDeleted() {
void TestGuestViewManager::WaitForLastGuestDeleted() {
// Wait for the last guest that was created to be deleted.
guest_web_contents_watchers_.back()->Wait();
-};
+}
content::WebContents* TestGuestViewManager::WaitForSingleGuestCreated() {
if (!GetNumGuestsActive()) {
diff --git a/chromium/components/guest_view/browser/test_guest_view_manager.h b/chromium/components/guest_view/browser/test_guest_view_manager.h
index 45424a946f8..53f73b61edf 100644
--- a/chromium/components/guest_view/browser/test_guest_view_manager.h
+++ b/chromium/components/guest_view/browser/test_guest_view_manager.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "components/guest_view/browser/guest_view_manager.h"
diff --git a/chromium/components/guest_view/renderer/guest_view_container.cc b/chromium/components/guest_view/renderer/guest_view_container.cc
index 2f3f776e9d9..1a15b9bce56 100644
--- a/chromium/components/guest_view/renderer/guest_view_container.cc
+++ b/chromium/components/guest_view/renderer/guest_view_container.cc
@@ -4,6 +4,7 @@
#include "components/guest_view/renderer/guest_view_container.h"
+#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/gwp_asan/BUILD.gn b/chromium/components/gwp_asan/BUILD.gn
index 48db66c2a3c..5176c8cef6e 100644
--- a/chromium/components/gwp_asan/BUILD.gn
+++ b/chromium/components/gwp_asan/BUILD.gn
@@ -7,7 +7,7 @@ source_set("unit_tests") {
deps = [
"//components/gwp_asan/common:unit_tests",
]
- if (is_win) {
+ if (is_win || is_mac) {
deps += [
"//components/gwp_asan/client:unit_tests",
"//components/gwp_asan/crash_handler:unit_tests",
diff --git a/chromium/components/gwp_asan/buildflags/BUILD.gn b/chromium/components/gwp_asan/buildflags/BUILD.gn
new file mode 100644
index 00000000000..95e986c250a
--- /dev/null
+++ b/chromium/components/gwp_asan/buildflags/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/buildflag_header.gni")
+import("//components/gwp_asan/buildflags/buildflags.gni")
+
+buildflag_header("buildflags") {
+ header = "buildflags.h"
+ flags = [ "ENABLE_GWP_ASAN=$enable_gwp_asan" ]
+}
diff --git a/chromium/components/gwp_asan/buildflags/buildflags.gni b/chromium/components/gwp_asan/buildflags/buildflags.gni
new file mode 100644
index 00000000000..3cb25db90a0
--- /dev/null
+++ b/chromium/components/gwp_asan/buildflags/buildflags.gni
@@ -0,0 +1,10 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/allocator.gni")
+
+declare_args() {
+ # Is the GWP-ASan client enabled for chrome/ on a given platform.
+ enable_gwp_asan = (is_win || is_mac) && use_allocator_shim
+}
diff --git a/chromium/components/gwp_asan/client/guarded_page_allocator.cc b/chromium/components/gwp_asan/client/guarded_page_allocator.cc
index 56fcfaaee51..483c4253c8d 100644
--- a/chromium/components/gwp_asan/client/guarded_page_allocator.cc
+++ b/chromium/components/gwp_asan/client/guarded_page_allocator.cc
@@ -4,11 +4,12 @@
#include "components/gwp_asan/client/guarded_page_allocator.h"
+#include <algorithm>
#include <iterator>
#include <memory>
-#include "base/atomicops.h"
#include "base/bits.h"
+#include "base/debug/stack_trace.h"
#include "base/no_destructor.h"
#include "base/process/process_metrics.h"
#include "base/rand_util.h"
@@ -18,10 +19,31 @@
#include "components/crash/core/common/crash_key.h"
#include "components/gwp_asan/common/allocator_state.h"
#include "components/gwp_asan/common/crash_key_name.h"
+#include "components/gwp_asan/common/pack_stack_trace.h"
+
+#if defined(OS_MACOSX)
+#include <pthread.h>
+#endif
namespace gwp_asan {
namespace internal {
+namespace {
+
+// Report a tid that matches what crashpad collects which may differ from what
+// base::PlatformThread::CurrentId() returns.
+uint64_t ReportTid() {
+#if !defined(OS_MACOSX)
+ return base::PlatformThread::CurrentId();
+#else
+ uint64_t tid = base::kInvalidThreadId;
+ pthread_threadid_np(nullptr, &tid);
+ return tid;
+#endif
+}
+
+} // namespace
+
// TODO: Delete out-of-line constexpr defininitons once C++17 is in use.
constexpr size_t GuardedPageAllocator::kGpaAllocAlignment;
@@ -54,8 +76,8 @@ void GuardedPageAllocator::Init(size_t max_alloced_pages, size_t total_pages) {
std::next(free_slot_ring_buffer_.begin(), total_pages));
}
- slots_ = std::make_unique<AllocatorState::SlotMetadata[]>(total_pages);
- state_.slot_metadata = reinterpret_cast<uintptr_t>(slots_.get());
+ metadata_ = std::make_unique<AllocatorState::SlotMetadata[]>(total_pages);
+ state_.metadata_addr = reinterpret_cast<uintptr_t>(metadata_.get());
}
GuardedPageAllocator::~GuardedPageAllocator() {
@@ -93,7 +115,7 @@ void* GuardedPageAllocator::Allocate(size_t size, size_t align) {
void* alloc = reinterpret_cast<void*>(free_page + offset);
// Initialize slot metadata.
- RecordAllocationInSlot(free_slot, size, alloc);
+ RecordAllocationMetadata(free_slot, size, alloc);
return alloc;
}
@@ -103,21 +125,28 @@ void GuardedPageAllocator::Deallocate(void* ptr) {
const uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
size_t slot = state_.AddrToSlot(state_.GetPageAddr(addr));
- DCHECK_EQ(addr, slots_[slot].alloc_ptr);
+
+ // Check for a call to free() with an incorrect pointer (e.g. the pointer does
+ // not match the allocated pointer.)
+ if (addr != metadata_[slot].alloc_ptr) {
+ state_.free_invalid_address = addr;
+ __builtin_trap();
+ }
+
// Check for double free.
- if (slots_[slot].dealloc.trace_collected) {
- state_.double_free_detected = true;
- base::subtle::MemoryBarrier();
- // Trigger an exception by writing to the inaccessible free()d allocation.
- // We want to crash by accessing the offending allocation in order to signal
- // to the crash handler that this crash is caused by that allocation.
- *reinterpret_cast<char*>(ptr) = 'X';
+ if (metadata_[slot].deallocation_occurred.exchange(true)) {
+ state_.double_free_address = addr;
+ // TODO(https://crbug.com/925447): The other thread may not be done writing
+ // a stack trace so we could spin here until it's read; however, it's also
+ // possible we are racing an allocation in the middle of
+ // RecordAllocationMetadata. For now it's possible a racy double free could
+ // lead to a bad stack trace, but no internal allocator corruption.
__builtin_trap();
}
// Record deallocation stack trace/thread id before marking the page
// inaccessible in case a use-after-free occurs immediately.
- RecordDeallocationInSlot(slot);
+ RecordDeallocationMetadata(slot);
MarkPageInaccessible(reinterpret_cast<void*>(state_.GetPageAddr(addr)));
FreeSlot(slot);
@@ -127,8 +156,8 @@ size_t GuardedPageAllocator::GetRequestedSize(const void* ptr) const {
CHECK(PointerIsMine(ptr));
const uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
size_t slot = state_.AddrToSlot(state_.GetPageAddr(addr));
- DCHECK_EQ(addr, slots_[slot].alloc_ptr);
- return slots_[slot].alloc_size;
+ DCHECK_EQ(addr, metadata_[slot].alloc_ptr);
+ return metadata_[slot].alloc_size;
}
size_t GuardedPageAllocator::RegionSize() const {
@@ -162,29 +191,38 @@ void GuardedPageAllocator::FreeSlot(size_t slot) {
free_slot_start_idx_);
}
-void GuardedPageAllocator::RecordAllocationInSlot(size_t slot,
- size_t size,
- void* ptr) {
- slots_[slot].alloc_size = size;
- slots_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr);
-
- slots_[slot].alloc.tid = base::PlatformThread::CurrentId();
- slots_[slot].alloc.trace_len = base::debug::CollectStackTrace(
- reinterpret_cast<void**>(&slots_[slot].alloc.trace),
- AllocatorState::kMaxStackFrames);
- slots_[slot].alloc.trace_collected = true;
-
- slots_[slot].dealloc.tid = base::kInvalidThreadId;
- slots_[slot].dealloc.trace_len = 0;
- slots_[slot].dealloc.trace_collected = false;
+void GuardedPageAllocator::RecordAllocationMetadata(size_t slot,
+ size_t size,
+ void* ptr) {
+ metadata_[slot].alloc_size = size;
+ metadata_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr);
+
+ void* trace[AllocatorState::kMaxStackFrames];
+ size_t len =
+ base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames);
+ metadata_[slot].alloc.trace_len =
+ Pack(reinterpret_cast<uintptr_t*>(trace), len,
+ metadata_[slot].alloc.packed_trace,
+ sizeof(metadata_[slot].alloc.packed_trace));
+ metadata_[slot].alloc.tid = ReportTid();
+ metadata_[slot].alloc.trace_collected = true;
+
+ metadata_[slot].dealloc.tid = base::kInvalidThreadId;
+ metadata_[slot].dealloc.trace_len = 0;
+ metadata_[slot].dealloc.trace_collected = false;
+ metadata_[slot].deallocation_occurred = false;
}
-void GuardedPageAllocator::RecordDeallocationInSlot(size_t slot) {
- slots_[slot].dealloc.tid = base::PlatformThread::CurrentId();
- slots_[slot].dealloc.trace_len = base::debug::CollectStackTrace(
- reinterpret_cast<void**>(&slots_[slot].dealloc.trace),
- AllocatorState::kMaxStackFrames);
- slots_[slot].dealloc.trace_collected = true;
+void GuardedPageAllocator::RecordDeallocationMetadata(size_t slot) {
+ void* trace[AllocatorState::kMaxStackFrames];
+ size_t len =
+ base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames);
+ metadata_[slot].dealloc.trace_len =
+ Pack(reinterpret_cast<uintptr_t*>(trace), len,
+ metadata_[slot].dealloc.packed_trace,
+ sizeof(metadata_[slot].dealloc.packed_trace));
+ metadata_[slot].dealloc.tid = ReportTid();
+ metadata_[slot].dealloc.trace_collected = true;
}
uintptr_t GuardedPageAllocator::GetCrashKeyAddress() const {
diff --git a/chromium/components/gwp_asan/client/guarded_page_allocator.h b/chromium/components/gwp_asan/client/guarded_page_allocator.h
index e7e3cf66a8a..4ca13eb8da0 100644
--- a/chromium/components/gwp_asan/client/guarded_page_allocator.h
+++ b/chromium/components/gwp_asan/client/guarded_page_allocator.h
@@ -7,6 +7,7 @@
#include <array>
#include <atomic>
+#include <limits>
#include <memory>
#include "base/compiler_specific.h"
@@ -100,8 +101,8 @@ class GWP_ASAN_EXPORT GuardedPageAllocator {
// encapsulates the logic for updating the stack traces and metadata for a
// given slot.
ALWAYS_INLINE
- void RecordAllocationInSlot(size_t slot, size_t size, void* ptr);
- ALWAYS_INLINE void RecordDeallocationInSlot(size_t slot);
+ void RecordAllocationMetadata(size_t slot, size_t size, void* ptr);
+ ALWAYS_INLINE void RecordDeallocationMetadata(size_t slot);
// Allocator state shared with with the crash analyzer.
AllocatorState state_;
@@ -123,17 +124,17 @@ class GWP_ASAN_EXPORT GuardedPageAllocator {
// We dynamically allocate the SlotMetadata array to avoid allocating
// extraneous memory for when total_pages < kGpaMaxPages.
- std::unique_ptr<AllocatorState::SlotMetadata[]> slots_;
+ std::unique_ptr<AllocatorState::SlotMetadata[]> metadata_;
// Required for a singleton to access the constructor.
friend base::NoDestructor<GuardedPageAllocator>;
- DISALLOW_COPY_AND_ASSIGN(GuardedPageAllocator);
-
friend class GuardedPageAllocatorTest;
FRIEND_TEST_ALL_PREFIXES(GuardedPageAllocatorTest,
GetNearestValidPageEdgeCases);
FRIEND_TEST_ALL_PREFIXES(GuardedPageAllocatorTest, GetErrorTypeEdgeCases);
+
+ DISALLOW_COPY_AND_ASSIGN(GuardedPageAllocator);
};
} // namespace internal
diff --git a/chromium/components/gwp_asan/client/guarded_page_allocator_posix.cc b/chromium/components/gwp_asan/client/guarded_page_allocator_posix.cc
index d3e83f1a410..16c6a7a3b05 100644
--- a/chromium/components/gwp_asan/client/guarded_page_allocator_posix.cc
+++ b/chromium/components/gwp_asan/client/guarded_page_allocator_posix.cc
@@ -20,7 +20,7 @@ void GuardedPageAllocator::UnmapRegion() {
CHECK(state_.pages_base_addr);
int err =
munmap(reinterpret_cast<void*>(state_.pages_base_addr), RegionSize());
- DCHECK_EQ(err, 0);
+ DPCHECK(err == 0) << "munmap";
(void)err;
}
@@ -30,8 +30,12 @@ void GuardedPageAllocator::MarkPageReadWrite(void* ptr) {
}
void GuardedPageAllocator::MarkPageInaccessible(void* ptr) {
- int err = mprotect(ptr, state_.page_size, PROT_NONE);
- PCHECK(err == 0) << "mprotect";
+ // mmap() a PROT_NONE page over the address to release it to the system, if
+ // we used mprotect() here the system would count pages in the quarantine
+ // against the RSS.
+ void* err = mmap(ptr, state_.page_size, PROT_NONE,
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+ PCHECK(err == ptr) << "mmap";
}
} // namespace internal
diff --git a/chromium/components/gwp_asan/client/guarded_page_allocator_unittest.cc b/chromium/components/gwp_asan/client/guarded_page_allocator_unittest.cc
index 9d299c300d0..2a17c1a341a 100644
--- a/chromium/components/gwp_asan/client/guarded_page_allocator_unittest.cc
+++ b/chromium/components/gwp_asan/client/guarded_page_allocator_unittest.cc
@@ -6,6 +6,8 @@
#include <array>
#include <set>
+#include <utility>
+#include <vector>
#include "base/bits.h"
#include "base/process/process_metrics.h"
@@ -69,6 +71,13 @@ TEST_F(GuardedPageAllocatorTest, SingleAllocDealloc) {
EXPECT_DEATH(gpa_.Deallocate(buf), "");
}
+TEST_F(GuardedPageAllocatorTest, CrashOnBadDeallocPointer) {
+ EXPECT_DEATH(gpa_.Deallocate(nullptr), "");
+ char* buf = reinterpret_cast<char*>(gpa_.Allocate(8));
+ EXPECT_DEATH(gpa_.Deallocate(buf + 1), "");
+ gpa_.Deallocate(buf);
+}
+
TEST_F(GuardedPageAllocatorTest, PointerIsMine) {
void* buf = gpa_.Allocate(1);
auto malloc_ptr = std::make_unique<char>();
@@ -154,9 +163,9 @@ TEST_P(GuardedPageAllocatorParamTest, AllocDeallocAllPages) {
// Performing death tests post-allocation times out on Windows.
}
}
-INSTANTIATE_TEST_CASE_P(VaryNumPages,
- GuardedPageAllocatorParamTest,
- testing::Values(1, kGpaMaxPages / 2, kGpaMaxPages));
+INSTANTIATE_TEST_SUITE_P(VaryNumPages,
+ GuardedPageAllocatorParamTest,
+ testing::Values(1, kGpaMaxPages / 2, kGpaMaxPages));
class ThreadedAllocCountDelegate : public base::DelegateSimpleThread::Delegate {
public:
diff --git a/chromium/components/gwp_asan/client/guarded_page_allocator_win.cc b/chromium/components/gwp_asan/client/guarded_page_allocator_win.cc
index 0f7883bbab6..62045f430f6 100644
--- a/chromium/components/gwp_asan/client/guarded_page_allocator_win.cc
+++ b/chromium/components/gwp_asan/client/guarded_page_allocator_win.cc
@@ -23,7 +23,7 @@ void GuardedPageAllocator::UnmapRegion() {
CHECK(state_.pages_base_addr);
BOOL err = VirtualFree(reinterpret_cast<void*>(state_.pages_base_addr), 0,
MEM_RELEASE);
- DCHECK(err);
+ DPCHECK(err) << "VirtualFree";
(void)err;
}
diff --git a/chromium/components/gwp_asan/client/gwp_asan.cc b/chromium/components/gwp_asan/client/gwp_asan.cc
index 0258ff82c4a..1f64ea3fe2a 100644
--- a/chromium/components/gwp_asan/client/gwp_asan.cc
+++ b/chromium/components/gwp_asan/client/gwp_asan.cc
@@ -4,12 +4,15 @@
#include "components/gwp_asan/client/gwp_asan.h"
+#include <algorithm>
+#include <limits>
+
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/field_trial_params.h"
-#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "components/gwp_asan/client/guarded_page_allocator.h"
@@ -20,27 +23,46 @@ namespace gwp_asan {
namespace internal {
namespace {
+constexpr int kDefaultMaxAllocations = 7;
+constexpr int kDefaultTotalPages = 30;
+constexpr int kDefaultAllocationSamplingFrequency = 1000;
+constexpr double kDefaultProcessSamplingProbability = 1.0;
+constexpr int kDefaultIncreasedMemoryMultiplier = 4;
+
const base::Feature kGwpAsan{"GwpAsanMalloc",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::FeatureParam<int> kMaxAllocationsParam{&kGwpAsan, "MaxAllocations",
- 6};
+ kDefaultMaxAllocations};
-const base::FeatureParam<int> kTotalPagesParam{&kGwpAsan, "TotalPages", 20};
+const base::FeatureParam<int> kTotalPagesParam{&kGwpAsan, "TotalPages",
+ kDefaultTotalPages};
const base::FeatureParam<int> kAllocationSamplingParam{
- &kGwpAsan, "AllocationSamplingFrequency", 1000};
+ &kGwpAsan, "AllocationSamplingFrequency",
+ kDefaultAllocationSamplingFrequency};
const base::FeatureParam<double> kProcessSamplingParam{
- &kGwpAsan, "ProcessSamplingProbability", 1.0};
+ &kGwpAsan, "ProcessSamplingProbability",
+ kDefaultProcessSamplingProbability};
-bool EnableForMalloc() {
+// The multiplier to increase MaxAllocations/TotalPages in scenarios where we
+// want to perform additional testing (e.g. on canary/dev builds or in the
+// browser process.) The multiplier increase is cumulative when multiple
+// conditions apply.
+const base::FeatureParam<int> kIncreasedMemoryMultiplierParam{
+ &kGwpAsan, "IncreasedMemoryMultiplier", kDefaultIncreasedMemoryMultiplier};
+
+bool EnableForMalloc(bool is_canary_dev, bool is_browser_process) {
if (!base::FeatureList::IsEnabled(kGwpAsan))
return false;
+ static_assert(AllocatorState::kGpaMaxPages <= std::numeric_limits<int>::max(),
+ "kGpaMaxPages out of range");
+ constexpr int kMaxPages = static_cast<int>(AllocatorState::kGpaMaxPages);
+
int total_pages = kTotalPagesParam.Get();
- if (total_pages < 1 ||
- total_pages > base::checked_cast<int>(AllocatorState::kGpaMaxPages)) {
+ if (total_pages < 1 || total_pages > kMaxPages) {
DLOG(ERROR) << "GWP-ASan TotalPages is out-of-range: " << total_pages;
return false;
}
@@ -67,6 +89,33 @@ bool EnableForMalloc() {
return false;
}
+ base::CheckedNumeric<int> multiplier = 1;
+ if (is_canary_dev)
+ multiplier += kIncreasedMemoryMultiplierParam.Get();
+ if (is_browser_process)
+ multiplier += kIncreasedMemoryMultiplierParam.Get();
+
+ if (!multiplier.IsValid() || multiplier.ValueOrDie() < 1 ||
+ multiplier.ValueOrDie() > kMaxPages) {
+ DLOG(ERROR) << "GWP-ASan IncreaseMemoryMultiplier is out-of-range";
+ return false;
+ }
+
+ base::CheckedNumeric<int> total_pages_mult = total_pages;
+ total_pages_mult *= multiplier.ValueOrDie();
+ base::CheckedNumeric<int> max_allocations_mult = max_allocations;
+ max_allocations_mult *= multiplier.ValueOrDie();
+
+ if (!total_pages_mult.IsValid() || !max_allocations_mult.IsValid()) {
+ DLOG(ERROR) << "GWP-ASan multiplier caused out-of-range multiply: "
+ << multiplier.ValueOrDie();
+ return false;
+ }
+
+ total_pages = std::min<int>(total_pages_mult.ValueOrDie(), kMaxPages);
+ max_allocations =
+ std::min<int>(max_allocations_mult.ValueOrDie(), total_pages);
+
if (base::RandDouble() >= process_sampling_probability)
return false;
@@ -77,8 +126,9 @@ bool EnableForMalloc() {
} // namespace
} // namespace internal
-void EnableForMalloc() {
- static bool init_once = internal::EnableForMalloc();
+void EnableForMalloc(bool is_canary_dev, bool is_browser_process) {
+ static bool init_once =
+ internal::EnableForMalloc(is_canary_dev, is_browser_process);
ignore_result(init_once);
}
diff --git a/chromium/components/gwp_asan/client/gwp_asan.h b/chromium/components/gwp_asan/client/gwp_asan.h
index 7f471dd62fd..5f3698cc64d 100644
--- a/chromium/components/gwp_asan/client/gwp_asan.h
+++ b/chromium/components/gwp_asan/client/gwp_asan.h
@@ -10,8 +10,11 @@
namespace gwp_asan {
// Enable GWP-ASan for the current process. This should only be called once per
-// process. This can not be disabled once it has been enabled.
-GWP_ASAN_EXPORT void EnableForMalloc();
+// process. This can not be disabled once it has been enabled. The caller should
+// indicate whether this build is a canary or dev build or if the current
+// process is the browser process. In both cases, GWP-ASan will use more memory.
+GWP_ASAN_EXPORT void EnableForMalloc(bool is_canary_dev,
+ bool is_browser_process);
} // namespace gwp_asan
diff --git a/chromium/components/gwp_asan/client/sampling_allocator_shims.cc b/chromium/components/gwp_asan/client/sampling_allocator_shims.cc
index 07c59be0ffa..5651bd24759 100644
--- a/chromium/components/gwp_asan/client/sampling_allocator_shims.cc
+++ b/chromium/components/gwp_asan/client/sampling_allocator_shims.cc
@@ -4,6 +4,8 @@
#include "components/gwp_asan/client/sampling_allocator_shims.h"
+#include <algorithm>
+
#include "base/allocator/allocator_shim.h"
#include "base/allocator/buildflags.h"
#include "base/compiler_specific.h"
@@ -18,10 +20,7 @@
#include "components/gwp_asan/client/guarded_page_allocator.h"
#if defined(OS_MACOSX)
-// TODO(https://crbug.com/829078): thread_local is not currently supported on
-// macOS; however, it works correctly on other platforms and is noticeably
-// faster.
-#error "macOS does not support thread_local"
+#include <pthread.h>
#endif
namespace gwp_asan {
@@ -40,6 +39,10 @@ class SamplingState {
void Init(size_t sampling_frequency) {
DCHECK_GT(sampling_frequency, 0U);
sampling_frequency_ = sampling_frequency;
+
+#if defined(OS_MACOSX)
+ pthread_key_create(&tls_key_, nullptr);
+#endif
}
// Return true if this allocation should be sampled.
@@ -50,12 +53,11 @@ class SamplingState {
//
// Instead, use zero to mean 'get a new counter value' and one to mean
// that this allocation should be sampled.
- static thread_local size_t tls_counter = 0;
- size_t samples_left = tls_counter;
+ size_t samples_left = GetCounter();
if (UNLIKELY(!samples_left))
samples_left = NextSample();
- tls_counter = samples_left - 1;
+ SetCounter(samples_left - 1);
return (samples_left == 1);
}
@@ -72,6 +74,26 @@ class SamplingState {
return next_sample;
}
+#if !defined(OS_MACOSX)
+ ALWAYS_INLINE size_t GetCounter() { return tls_counter_; }
+ ALWAYS_INLINE void SetCounter(size_t value) { tls_counter_ = value; }
+
+ static thread_local size_t tls_counter_;
+#else
+ // On macOS, the first use of a thread_local variable on a new thread will
+ // cause a malloc(), causing infinite recursion. Instead, use pthread TLS to
+ // store the counter.
+ ALWAYS_INLINE size_t GetCounter() {
+ return reinterpret_cast<size_t>(pthread_getspecific(tls_key_));
+ }
+
+ ALWAYS_INLINE void SetCounter(size_t value) {
+ pthread_setspecific(tls_key_, reinterpret_cast<void*>(value));
+ }
+
+ pthread_key_t tls_key_ = 0;
+#endif
+
size_t sampling_frequency_ = 0;
// Stores the number of allocations we need to skip to reach the end of the
@@ -79,6 +101,10 @@ class SamplingState {
size_t increment_ = 0;
};
+#if !defined(OS_MACOSX)
+thread_local size_t SamplingState::tls_counter_ = 0;
+#endif
+
// By being implemented as a global with inline method definitions, method calls
// and member acceses are inlined and as efficient as possible in the
// performance-sensitive allocation hot-path.
diff --git a/chromium/components/gwp_asan/client/sampling_allocator_shims_unittest.cc b/chromium/components/gwp_asan/client/sampling_allocator_shims_unittest.cc
index 69e459d506f..f74fbf94434 100644
--- a/chromium/components/gwp_asan/client/sampling_allocator_shims_unittest.cc
+++ b/chromium/components/gwp_asan/client/sampling_allocator_shims_unittest.cc
@@ -135,9 +135,10 @@ MULTIPROCESS_TEST_MAIN_WITH_SETUP(
#if defined(OS_POSIX)
EXPECT_TRUE(allocationCheck(
- [&] {
+ [&]() -> void* {
void* ptr;
- posix_memalign(&ptr, page_size, page_size);
+ if (posix_memalign(&ptr, page_size, page_size))
+ return nullptr;
return ptr;
},
&free, &failures));
diff --git a/chromium/components/gwp_asan/common/BUILD.gn b/chromium/components/gwp_asan/common/BUILD.gn
index b8d77a58ec3..dc451bb5554 100644
--- a/chromium/components/gwp_asan/common/BUILD.gn
+++ b/chromium/components/gwp_asan/common/BUILD.gn
@@ -2,11 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//testing/libfuzzer/fuzzer_test.gni")
+
static_library("common") {
sources = [
"allocator_state.cc",
"allocator_state.h",
"crash_key_name.h",
+ "pack_stack_trace.cc",
+ "pack_stack_trace.h",
]
deps = [
@@ -18,6 +22,7 @@ source_set("unit_tests") {
testonly = true
sources = [
"allocator_state_unittest.cc",
+ "pack_stack_trace_unittest.cc",
]
deps = [
":common",
@@ -25,3 +30,21 @@ source_set("unit_tests") {
"//testing/gtest",
]
}
+
+fuzzer_test("pack_stack_trace_unpack_fuzzer") {
+ sources = [
+ "pack_stack_trace_unpack_fuzzer.cc",
+ ]
+ deps = [
+ "//components/gwp_asan/common",
+ ]
+}
+
+fuzzer_test("pack_stack_trace_differential_fuzzer") {
+ sources = [
+ "pack_stack_trace_differential_fuzzer.cc",
+ ]
+ deps = [
+ "//components/gwp_asan/common",
+ ]
+}
diff --git a/chromium/components/gwp_asan/common/allocator_state.cc b/chromium/components/gwp_asan/common/allocator_state.cc
index 94d5b4b8ed7..937b1bb1ebd 100644
--- a/chromium/components/gwp_asan/common/allocator_state.cc
+++ b/chromium/components/gwp_asan/common/allocator_state.cc
@@ -15,6 +15,9 @@ namespace internal {
// TODO: Delete out-of-line constexpr defininitons once C++17 is in use.
constexpr size_t AllocatorState::kGpaMaxPages;
constexpr size_t AllocatorState::kMaxStackFrames;
+constexpr size_t AllocatorState::kMaxPackedTraceLength;
+
+AllocatorState::AllocatorState() {}
AllocatorState::GetMetadataReturnType AllocatorState::GetMetadataForAddress(
uintptr_t exception_address,
@@ -28,7 +31,7 @@ AllocatorState::GetMetadataReturnType AllocatorState::GetMetadataForAddress(
if (slot_idx >= kGpaMaxPages)
return GetMetadataReturnType::kErrorBadSlot;
- *slot_address = slot_metadata + (slot_idx * sizeof(SlotMetadata));
+ *slot_address = metadata_addr + (slot_idx * sizeof(SlotMetadata));
return GetMetadataReturnType::kGwpAsanCrash;
}
@@ -50,7 +53,7 @@ bool AllocatorState::IsValid() const {
pages_end_addr - pages_base_addr != page_size * (total_pages * 2 + 1))
return false;
- if (!slot_metadata)
+ if (!metadata_addr)
return false;
return true;
@@ -88,9 +91,11 @@ size_t AllocatorState::GetNearestSlot(uintptr_t addr) const {
AllocatorState::ErrorType AllocatorState::GetErrorType(uintptr_t addr,
bool allocated,
bool deallocated) const {
+ if (free_invalid_address)
+ return ErrorType::kFreeInvalidAddress;
if (!allocated)
return ErrorType::kUnknown;
- if (double_free_detected)
+ if (double_free_address)
return ErrorType::kDoubleFree;
if (deallocated)
return ErrorType::kUseAfterFree;
@@ -133,5 +138,7 @@ size_t AllocatorState::AddrToSlot(uintptr_t addr) const {
return slot;
}
+AllocatorState::SlotMetadata::SlotMetadata() {}
+
} // namespace internal
} // namespace gwp_asan
diff --git a/chromium/components/gwp_asan/common/allocator_state.h b/chromium/components/gwp_asan/common/allocator_state.h
index 1a3d5a5c658..74de37d1f3f 100644
--- a/chromium/components/gwp_asan/common/allocator_state.h
+++ b/chromium/components/gwp_asan/common/allocator_state.h
@@ -25,6 +25,8 @@
#ifndef COMPONENTS_GWP_ASAN_COMMON_ALLOCATOR_STATE_H_
#define COMPONENTS_GWP_ASAN_COMMON_ALLOCATOR_STATE_H_
+#include <atomic>
+
#include "base/threading/platform_thread.h"
namespace gwp_asan {
@@ -35,9 +37,12 @@ class GuardedPageAllocator;
class AllocatorState {
public:
// Maximum number of pages this class can allocate.
- static constexpr size_t kGpaMaxPages = 128;
+ static constexpr size_t kGpaMaxPages = 256;
// Maximum number of stack trace frames to collect.
static constexpr size_t kMaxStackFrames = 60;
+ // Number of bytes to allocate for packed stack traces. This can hold
+ // approximately kMaxStackFrames under normal conditions.
+ static constexpr size_t kMaxPackedTraceLength = 200;
enum class ErrorType {
kUseAfterFree = 0,
@@ -45,6 +50,7 @@ class AllocatorState {
kBufferOverflow = 2,
kDoubleFree = 3,
kUnknown = 4,
+ kFreeInvalidAddress = 5,
};
enum class GetMetadataReturnType {
@@ -55,14 +61,16 @@ class AllocatorState {
// Structure for storing data about a slot.
struct SlotMetadata {
+ SlotMetadata();
+
// Information saved for allocations and deallocations.
struct AllocationInfo {
// (De)allocation thread id or base::kInvalidThreadId if no (de)allocation
// occurred.
- base::PlatformThreadId tid = base::kInvalidThreadId;
- // Stack trace contents.
- uintptr_t trace[kMaxStackFrames];
- // Stack trace length.
+ uint64_t tid = base::kInvalidThreadId;
+ // Packed stack trace.
+ uint8_t packed_trace[kMaxPackedTraceLength];
+ // Length used to encode the packed stack trace.
size_t trace_len = 0;
// Whether a stack trace has been collected for this (de)allocation.
bool trace_collected = false;
@@ -72,14 +80,15 @@ class AllocatorState {
size_t alloc_size = 0;
// The allocation address.
uintptr_t alloc_ptr = 0;
+ // Used to synchronize whether a deallocation has occurred (e.g. whether a
+ // double free has occurred) between threads.
+ std::atomic<bool> deallocation_occurred{false};
AllocationInfo alloc;
AllocationInfo dealloc;
};
- // TODO(vtsyrklevich): Get rid of inline (requires chromium-style plugin
- // update.)
- inline constexpr AllocatorState();
+ AllocatorState();
// Returns true if address is in memory managed by this class.
inline bool PointerIsMine(uintptr_t addr) const {
@@ -131,16 +140,17 @@ class AllocatorState {
// Pointer to an array of metadata about every allocation, including its size,
// offset, and pointers to the allocation/deallocation stack traces (if
// present.)
- uintptr_t slot_metadata = 0;
+ uintptr_t metadata_addr = 0;
- // Set to true if a double free has occurred.
- bool double_free_detected = false;
+ // Set to the address of a double freed allocation if a double free occurred.
+ uintptr_t double_free_address = 0;
+ // If an invalid pointer has been free()d, this is the address of that invalid
+ // pointer.
+ uintptr_t free_invalid_address = 0;
DISALLOW_COPY_AND_ASSIGN(AllocatorState);
};
-constexpr AllocatorState::AllocatorState() {}
-
// Ensure that the allocator state is a plain-old-data. That way we can safely
// initialize it by copying memory from out-of-process without worrying about
// destructors operating on the fields in an unexpected way.
diff --git a/chromium/components/gwp_asan/common/allocator_state_unittest.cc b/chromium/components/gwp_asan/common/allocator_state_unittest.cc
index 1d029115f48..44cff48e0b3 100644
--- a/chromium/components/gwp_asan/common/allocator_state_unittest.cc
+++ b/chromium/components/gwp_asan/common/allocator_state_unittest.cc
@@ -33,7 +33,7 @@ class AllocatorStateTest : public testing::Test {
end_addr_offset + base + page_size * (total_pages * 2 + 1);
// An invalid address, but it's never dereferenced in AllocatorState.
- state_.slot_metadata = 0x1234;
+ state_.metadata_addr = 0x1234;
}
AllocatorState state_;
@@ -110,5 +110,16 @@ TEST_F(AllocatorStateTest, GetErrorTypeEdgeCases) {
AllocatorState::ErrorType::kBufferOverflow);
}
+// Correctly handle the edge case when a free() occurs on a page that has never
+// been allocated.
+TEST_F(AllocatorStateTest, GetErrorTypeFreeInvalidAddressEdgeCase) {
+ InitializeState(base::GetPageSize(), kGpaMaxPages);
+ EXPECT_TRUE(state_.IsValid());
+
+ state_.free_invalid_address = state_.first_page_addr;
+ EXPECT_EQ(state_.GetErrorType(state_.first_page_addr, false, false),
+ AllocatorState::ErrorType::kFreeInvalidAddress);
+}
+
} // namespace internal
} // namespace gwp_asan
diff --git a/chromium/components/gwp_asan/common/pack_stack_trace.cc b/chromium/components/gwp_asan/common/pack_stack_trace.cc
new file mode 100644
index 00000000000..7ddd27b2ab2
--- /dev/null
+++ b/chromium/components/gwp_asan/common/pack_stack_trace.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/gwp_asan/common/pack_stack_trace.h"
+
+namespace gwp_asan {
+namespace internal {
+
+namespace {
+
+// Encode variable-length integer to |out|, returns 0 if there was not enough
+// space to finish writing it or the length of the encoded integer otherwise.
+size_t VarIntEncode(uintptr_t value, uint8_t* out, size_t out_len) {
+ for (size_t i = 0; i < out_len; i++) {
+ out[i] = value & 0x7f;
+ value >>= 7;
+ if (!value)
+ return i + 1;
+
+ out[i] |= 0x80;
+ }
+
+ return 0;
+}
+
+// Decode a variable-length integer to |out|, returns 0 if reading it failed or
+// the length of the decoded integer otherwise.
+size_t VarIntDecode(const uint8_t* in, size_t in_len, uintptr_t* out) {
+ uintptr_t result = 0;
+ size_t shift = 0;
+ for (size_t i = 0; i < in_len; i++) {
+ result |= static_cast<uintptr_t>(in[i] & 0x7f) << shift;
+ if (in[i] < 0x80) {
+ *out = result;
+ return i + 1;
+ }
+
+ shift += 7;
+ // Disallow overflowing the range of the output integer.
+ if (shift >= sizeof(uintptr_t) * 8)
+ return 0;
+ }
+
+ return 0;
+}
+
+uintptr_t ZigzagEncode(uintptr_t value) {
+ uintptr_t encoded = value << 1;
+ if (static_cast<intptr_t>(value) >= 0)
+ return encoded;
+ return ~encoded;
+}
+
+uintptr_t ZigzagDecode(uintptr_t value) {
+ uintptr_t decoded = value >> 1;
+ if (!(value & 1))
+ return decoded;
+ return ~decoded;
+}
+
+} // namespace
+
+size_t Pack(const uintptr_t* unpacked,
+ size_t unpacked_size,
+ uint8_t* packed,
+ size_t packed_max_size) {
+ size_t idx = 0;
+ for (size_t cur_depth = 0; cur_depth < unpacked_size; cur_depth++) {
+ uintptr_t diff = unpacked[cur_depth];
+ if (cur_depth > 0)
+ diff -= unpacked[cur_depth - 1];
+ size_t encoded_len =
+ VarIntEncode(ZigzagEncode(diff), packed + idx, packed_max_size - idx);
+ if (!encoded_len)
+ break;
+
+ idx += encoded_len;
+ }
+
+ return idx;
+}
+
+size_t Unpack(const uint8_t* packed,
+ size_t packed_size,
+ uintptr_t* unpacked,
+ size_t unpacked_max_size) {
+ size_t cur_depth;
+ size_t idx = 0;
+ for (cur_depth = 0; cur_depth < unpacked_max_size; cur_depth++) {
+ uintptr_t encoded_diff;
+ size_t decoded_len =
+ VarIntDecode(packed + idx, packed_size - idx, &encoded_diff);
+ if (!decoded_len)
+ break;
+ idx += decoded_len;
+
+ unpacked[cur_depth] = ZigzagDecode(encoded_diff);
+ if (cur_depth > 0)
+ unpacked[cur_depth] += unpacked[cur_depth - 1];
+ }
+
+ if (idx != packed_size && cur_depth != unpacked_max_size)
+ return 0;
+
+ return cur_depth;
+}
+
+} // namespace internal
+} // namespace gwp_asan
diff --git a/chromium/components/gwp_asan/common/pack_stack_trace.h b/chromium/components/gwp_asan/common/pack_stack_trace.h
new file mode 100644
index 00000000000..cae0584028e
--- /dev/null
+++ b/chromium/components/gwp_asan/common/pack_stack_trace.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_GWP_ASAN_COMMON_PACK_STACK_TRACE_H_
+#define COMPONENTS_GWP_ASAN_COMMON_PACK_STACK_TRACE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// These routines 'compress' a stack trace by storing a stack trace as a
+// starting address, followed by offsets from the previous pointer. All values
+// are stored using variable-length integers to reduce space. Furthermore, they
+// are zigzag encoded, like in protobuf encoding, to store negative offsets
+// efficiently. On 64-bit platforms this packing can reduce space required to
+// store a stack trace by over 50%.
+
+namespace gwp_asan {
+namespace internal {
+
+// From the stack trace in |unpacked| of length |unpacked_size|, pack it into
+// the buffer |packed| with maximum length |packed_max_size|. The return value
+// is the number of bytes that were written to the output buffer.
+size_t Pack(const uintptr_t* unpacked,
+ size_t unpacked_size,
+ uint8_t* packed,
+ size_t packed_max_size);
+
+// From the packed stack trace in |packed| of length |packed_size|, write the
+// unpacked stack trace of maximum length |unpacked_max_size| into |unpacked|.
+// Returns the number of entries un packed, or 0 on error.
+size_t Unpack(const uint8_t* packed,
+ size_t packed_size,
+ uintptr_t* unpacked,
+ size_t unpacked_max_size);
+
+} // namespace internal
+} // namespace gwp_asan
+
+#endif // COMPONENTS_GWP_ASAN_COMMON_PACK_STACK_TRACE_H_
diff --git a/chromium/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc b/chromium/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc
new file mode 100644
index 00000000000..72c97f5a61f
--- /dev/null
+++ b/chromium/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc
@@ -0,0 +1,47 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/gwp_asan/common/pack_stack_trace.h"
+
+#include <string.h>
+#include <algorithm>
+#include <memory>
+
+// Tests that whatever we give to Pack() is the same as what comes out of
+// Unpack().
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ if (Size < sizeof(size_t) * 2)
+ return 0;
+
+ size_t unpacked_max_size = reinterpret_cast<const size_t*>(Data)[0];
+ size_t packed_max_size = reinterpret_cast<const size_t*>(Data)[1];
+ Data += sizeof(size_t) * 2;
+ Size -= sizeof(size_t) * 2;
+
+ size_t entries = Size / sizeof(uintptr_t);
+
+ // We don't need a buffer large than Size*10 as the longest variable length
+ // encoding of a 64-bit integer is 10 bytes long.)
+ size_t packed_array_size = std::min(Size * 10, packed_max_size);
+ std::unique_ptr<uint8_t[]> packed(new uint8_t[packed_array_size]);
+ size_t packed_out =
+ gwp_asan::internal::Pack(reinterpret_cast<const uintptr_t*>(Data),
+ entries, packed.get(), packed_max_size);
+ if (packed_out > packed_array_size)
+ __builtin_trap();
+
+ size_t unpacked_array_size = std::min(unpacked_max_size, entries);
+ std::unique_ptr<uintptr_t[]> unpacked(new uintptr_t[unpacked_array_size]);
+ size_t unpacked_out = gwp_asan::internal::Unpack(
+ packed.get(), packed_out, unpacked.get(), unpacked_max_size);
+ // We can only be sure there was enough room to pack the entire input when
+ // packed_max_size was larger than the space allocated for packed data.
+ if (packed_max_size > packed_array_size &&
+ unpacked_out != unpacked_array_size)
+ __builtin_trap();
+ if (memcmp(Data, unpacked.get(), unpacked_out * sizeof(uintptr_t)))
+ __builtin_trap();
+ return 0;
+}
diff --git a/chromium/components/gwp_asan/common/pack_stack_trace_unittest.cc b/chromium/components/gwp_asan/common/pack_stack_trace_unittest.cc
new file mode 100644
index 00000000000..98dbfdc0000
--- /dev/null
+++ b/chromium/components/gwp_asan/common/pack_stack_trace_unittest.cc
@@ -0,0 +1,98 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/gwp_asan/common/pack_stack_trace.h"
+
+#include "base/test/gtest_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gwp_asan {
+namespace internal {
+
+TEST(PackTest, TrivialExample) {
+ constexpr size_t kTestEntries = 3;
+
+ uintptr_t test[kTestEntries] = {1, 2, 3};
+ uint8_t packed[8];
+ uintptr_t unpacked[kTestEntries];
+
+ const size_t packed_size = Pack(test, kTestEntries, packed, sizeof(packed));
+ ASSERT_EQ(packed_size, 3U);
+ // ZigzagEncode(1) == 2
+ EXPECT_EQ(packed[0], 2U);
+ EXPECT_EQ(packed[1], 2U);
+ EXPECT_EQ(packed[2], 2U);
+ EXPECT_EQ(Unpack(packed, packed_size, unpacked, kTestEntries), kTestEntries);
+ EXPECT_EQ(unpacked[0], 1U);
+ EXPECT_EQ(unpacked[1], 2U);
+ EXPECT_EQ(unpacked[2], 3U);
+}
+
+TEST(PackTest, DecreasingSequence) {
+ constexpr size_t kTestEntries = 3;
+
+ uintptr_t test[kTestEntries] = {3, 2, 1};
+ uint8_t packed[8];
+ uintptr_t unpacked[kTestEntries];
+
+ const size_t packed_size = Pack(test, kTestEntries, packed, sizeof(packed));
+ ASSERT_EQ(packed_size, 3U);
+ // ZigzagEncode(3) == 6
+ // ZigzagEncode(-1) == 1
+ EXPECT_EQ(packed[0], 6U);
+ EXPECT_EQ(packed[1], 1U);
+ EXPECT_EQ(packed[2], 1U);
+ EXPECT_EQ(Unpack(packed, packed_size, unpacked, kTestEntries), kTestEntries);
+ EXPECT_EQ(unpacked[0], 3U);
+ EXPECT_EQ(unpacked[1], 2U);
+ EXPECT_EQ(unpacked[2], 1U);
+}
+
+TEST(PackTest, MultibyteVarInts) {
+ constexpr size_t kTestEntries = 1;
+
+ uintptr_t test[kTestEntries] = {0x40};
+ uint8_t packed[8];
+ uintptr_t unpacked[kTestEntries];
+
+ const size_t packed_size = Pack(test, kTestEntries, packed, sizeof(packed));
+ ASSERT_EQ(packed_size, 2U);
+ // ZigzagEncode(0x40) == 0x80
+ EXPECT_EQ(packed[0], 0x80U);
+ EXPECT_EQ(packed[1], 0x01U);
+ EXPECT_EQ(Unpack(packed, packed_size, unpacked, kTestEntries), kTestEntries);
+ EXPECT_EQ(unpacked[0], 0x40U);
+}
+
+TEST(PackTest, UnpackFailsOnOutOfBoundsVarInt) {
+ uint8_t packed[11] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x00};
+ uintptr_t unpacked[1];
+
+ EXPECT_EQ(Unpack(packed, 11, unpacked, 1), 0U);
+}
+
+TEST(PackTest, UnpackFailsOnBufferTooSmall) {
+ uint8_t packed[2] = {0x80, 0x00};
+ uintptr_t unpacked[2];
+
+ // Fail
+ EXPECT_EQ(Unpack(packed, 1, unpacked, 1), 0U);
+ // Success
+ EXPECT_EQ(Unpack(packed, 2, unpacked, 1), 1U);
+ EXPECT_EQ(Unpack(packed, 2, unpacked, 2), 1U);
+}
+
+TEST(PackTest, PackFailsOnBufferTooSmall) {
+ uintptr_t test[] = {0x40, 0x41};
+ uint8_t packed[4];
+
+ EXPECT_EQ(Pack(test, 2, packed, 1), 0U);
+ EXPECT_EQ(Pack(test, 2, packed, 2), 2U);
+ EXPECT_EQ(Pack(test, 2, packed, 3), 3U);
+ EXPECT_EQ(Pack(test, 2, packed, 4), 3U);
+}
+
+} // namespace internal
+} // namespace gwp_asan
diff --git a/chromium/components/gwp_asan/common/pack_stack_trace_unpack_fuzzer.cc b/chromium/components/gwp_asan/common/pack_stack_trace_unpack_fuzzer.cc
new file mode 100644
index 00000000000..1f24fad8486
--- /dev/null
+++ b/chromium/components/gwp_asan/common/pack_stack_trace_unpack_fuzzer.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/gwp_asan/common/pack_stack_trace.h"
+
+#include <algorithm>
+#include <memory>
+
+// Tests that Unpack() correctly handles arbitrary inputs.
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
+ // The first sizeof(size_t) bytes of the input are treated as the
+ // unpacked_max_size argument to Unpack.
+ if (Size < sizeof(size_t))
+ return 0;
+
+ size_t unpacked_max_size = *reinterpret_cast<const size_t*>(Data);
+ Data += sizeof(size_t);
+ Size -= sizeof(size_t);
+
+ // This should always be large enough to hold the output.
+ size_t unpacked_array_size = std::min(Size, unpacked_max_size);
+ std::unique_ptr<uintptr_t[]> unpacked(new uintptr_t[unpacked_array_size]);
+ gwp_asan::internal::Unpack(Data, Size, unpacked.get(), unpacked_max_size);
+ return 0;
+}
diff --git a/chromium/components/gwp_asan/crash_handler/crash.proto b/chromium/components/gwp_asan/crash_handler/crash.proto
index 5440f8ef407..6bea260e03e 100644
--- a/chromium/components/gwp_asan/crash_handler/crash.proto
+++ b/chromium/components/gwp_asan/crash_handler/crash.proto
@@ -20,6 +20,7 @@ message Crash {
BUFFER_OVERFLOW = 2;
DOUBLE_FREE = 3;
UNKNOWN = 4;
+ FREE_INVALID_ADDRESS = 5;
}
message AllocationInfo {
@@ -37,4 +38,7 @@ message Crash {
// Records the bounds of the GWP-ASan allocator region.
optional uint64 region_start = 6;
optional uint64 region_size = 7;
+
+ // The invalid address that was free()d, if present.
+ optional uint64 free_invalid_address = 8;
}
diff --git a/chromium/components/gwp_asan/crash_handler/crash_analyzer.cc b/chromium/components/gwp_asan/crash_handler/crash_analyzer.cc
index 0df3958d6af..0644caedcd3 100644
--- a/chromium/components/gwp_asan/crash_handler/crash_analyzer.cc
+++ b/chromium/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -4,9 +4,9 @@
#include "components/gwp_asan/crash_handler/crash_analyzer.h"
-#include <algorithm>
-
#include <stddef.h>
+#include <algorithm>
+#include <string>
#include "base/logging.h"
#include "base/process/process_metrics.h"
@@ -14,6 +14,7 @@
#include "build/build_config.h"
#include "components/gwp_asan/common/allocator_state.h"
#include "components/gwp_asan/common/crash_key_name.h"
+#include "components/gwp_asan/common/pack_stack_trace.h"
#include "components/gwp_asan/crash_handler/crash.pb.h"
#include "third_party/crashpad/crashpad/client/annotation.h"
#include "third_party/crashpad/crashpad/snapshot/cpu_context.h"
@@ -53,15 +54,11 @@ GwpAsanCrashAnalysisResult CrashAnalyzer::GetExceptionInfo(
if (exception->Context()->Is64Bit() != is_64_bit)
return GwpAsanCrashAnalysisResult::kErrorMismatchedBitness;
- crashpad::VMAddress crash_addr = GetAccessAddress(*exception);
- if (!crash_addr)
- return GwpAsanCrashAnalysisResult::kUnrelatedCrash;
-
if (!process_snapshot.Memory())
return GwpAsanCrashAnalysisResult::kErrorNullProcessMemory;
- return AnalyzeCrashedAllocator(*process_snapshot.Memory(), gpa_ptr,
- crash_addr, proto);
+ return AnalyzeCrashedAllocator(*process_snapshot.Memory(), *exception,
+ gpa_ptr, proto);
}
crashpad::VMAddress CrashAnalyzer::GetAllocatorAddress(
@@ -91,8 +88,8 @@ crashpad::VMAddress CrashAnalyzer::GetAllocatorAddress(
GwpAsanCrashAnalysisResult CrashAnalyzer::AnalyzeCrashedAllocator(
const crashpad::ProcessMemory& memory,
+ const crashpad::ExceptionSnapshot& exception,
crashpad::VMAddress gpa_addr,
- crashpad::VMAddress exception_addr,
gwp_asan::Crash* proto) {
AllocatorState unsafe_state;
if (!memory.Read(gpa_addr, sizeof(unsafe_state), &unsafe_state)) {
@@ -106,6 +103,15 @@ GwpAsanCrashAnalysisResult CrashAnalyzer::AnalyzeCrashedAllocator(
}
const AllocatorState& valid_state = unsafe_state;
+ crashpad::VMAddress exception_addr = GetAccessAddress(exception);
+ if (valid_state.double_free_address)
+ exception_addr = valid_state.double_free_address;
+ else if (valid_state.free_invalid_address)
+ exception_addr = valid_state.free_invalid_address;
+
+ if (!exception_addr)
+ return GwpAsanCrashAnalysisResult::kUnrelatedCrash;
+
uintptr_t slot_address;
auto ret = valid_state.GetMetadataForAddress(exception_addr, &slot_address);
if (ret == AllocatorState::GetMetadataReturnType::kErrorBadSlot) {
@@ -133,6 +139,8 @@ GwpAsanCrashAnalysisResult CrashAnalyzer::AnalyzeCrashedAllocator(
proto->set_region_start(valid_state.pages_base_addr);
proto->set_region_size(valid_state.pages_end_addr -
valid_state.pages_base_addr);
+ if (valid_state.free_invalid_address)
+ proto->set_free_invalid_address(valid_state.free_invalid_address);
return GwpAsanCrashAnalysisResult::kGwpAsanCrash;
}
@@ -146,17 +154,26 @@ void CrashAnalyzer::ReadAllocationInfo(
if (!slot_info.trace_len || !slot_info.trace_collected)
return;
- if (slot_info.trace_len > AllocatorState::kMaxStackFrames) {
+ if (slot_info.trace_len > AllocatorState::kMaxPackedTraceLength) {
DLOG(ERROR) << "Stack trace length is corrupted: " << slot_info.trace_len;
return;
}
- // On 32-bit platforms we can't copy directly to
+ uintptr_t unpacked_stack_trace[AllocatorState::kMaxPackedTraceLength];
+ size_t unpacked_len =
+ Unpack(slot_info.packed_trace, slot_info.trace_len, unpacked_stack_trace,
+ AllocatorState::kMaxPackedTraceLength);
+ if (!unpacked_len) {
+ DLOG(ERROR) << "Failed to unpack stack trace.";
+ return;
+ }
+
+ // On 32-bit platforms we can't copy directly into
// proto_info->mutable_stack_trace()->mutable_data().
- proto_info->mutable_stack_trace()->Resize(slot_info.trace_len, 0);
+ proto_info->mutable_stack_trace()->Resize(unpacked_len, 0);
uint64_t* output = proto_info->mutable_stack_trace()->mutable_data();
- for (size_t i = 0; i < slot_info.trace_len; i++)
- output[i] = slot_info.trace[i];
+ for (size_t i = 0; i < unpacked_len; i++)
+ output[i] = unpacked_stack_trace[i];
}
} // namespace internal
diff --git a/chromium/components/gwp_asan/crash_handler/crash_analyzer.h b/chromium/components/gwp_asan/crash_handler/crash_analyzer.h
index 85278ea002f..bfa505580d0 100644
--- a/chromium/components/gwp_asan/crash_handler/crash_analyzer.h
+++ b/chromium/components/gwp_asan/crash_handler/crash_analyzer.h
@@ -76,12 +76,12 @@ class CrashAnalyzer {
// This method implements the underlying logic for GetExceptionInfo(). It
// analyzes the GuardedPageAllocator of the crashing process, and if the
- // exception address is in the GWP-ASan region it fills out the protobuf
+ // exception occurred in the GWP-ASan region it fills out the protobuf
// parameter and returns kGwpAsanCrash.
static GwpAsanCrashAnalysisResult AnalyzeCrashedAllocator(
const crashpad::ProcessMemory& memory,
+ const crashpad::ExceptionSnapshot& exception,
crashpad::VMAddress gpa_addr,
- crashpad::VMAddress exception_addr,
gwp_asan::Crash* proto);
// This method fills out an AllocationInfo protobuf from a
diff --git a/chromium/components/gwp_asan/crash_handler/crash_handler.cc b/chromium/components/gwp_asan/crash_handler/crash_handler.cc
index af9f47cfcd5..925ebde4036 100644
--- a/chromium/components/gwp_asan/crash_handler/crash_handler.cc
+++ b/chromium/components/gwp_asan/crash_handler/crash_handler.cc
@@ -5,9 +5,10 @@
#include "components/gwp_asan/crash_handler/crash_handler.h"
#include <stddef.h>
+#include <memory>
+#include <string>
#include "base/compiler_specific.h"
-#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "components/gwp_asan/crash_handler/crash.pb.h"
@@ -26,7 +27,7 @@ using GwpAsanCrashAnalysisResult = CrashAnalyzer::GwpAsanCrashAnalysisResult;
class BufferExtensionStreamDataSource final
: public crashpad::MinidumpUserExtensionStreamDataSource {
public:
- BufferExtensionStreamDataSource(uint32_t stream_type, Crash& crash);
+ BufferExtensionStreamDataSource(uint32_t stream_type, const Crash& crash);
size_t StreamDataSize() override;
bool ReadStreamData(Delegate* delegate) override;
@@ -39,7 +40,7 @@ class BufferExtensionStreamDataSource final
BufferExtensionStreamDataSource::BufferExtensionStreamDataSource(
uint32_t stream_type,
- Crash& crash)
+ const Crash& crash)
: crashpad::MinidumpUserExtensionStreamDataSource(stream_type) {
bool result = crash.SerializeToString(&data_);
DCHECK(result);
@@ -68,22 +69,13 @@ const char* ErrorToString(Crash_ErrorType type) {
return "double-free";
case Crash::UNKNOWN:
return "unknown";
+ case Crash::FREE_INVALID_ADDRESS:
+ return "free-invalid-address";
default:
return "unexpected error type";
}
}
-#if !defined(NDEBUG)
-void PrintStackTrace(
- const ::google::protobuf::RepeatedField<::google::protobuf::uint64>&
- trace_pb) {
- void* trace_array[trace_pb.size()];
- for (int i = 0; i < trace_pb.size(); i++)
- trace_array[i] = reinterpret_cast<void*>(trace_pb.Get(i));
- base::debug::StackTrace(trace_array, trace_pb.size()).Print();
-}
-#endif
-
std::unique_ptr<crashpad::MinidumpUserExtensionStreamDataSource>
HandleException(const crashpad::ProcessSnapshot& snapshot) {
gwp_asan::Crash proto;
@@ -96,17 +88,10 @@ HandleException(const crashpad::ProcessSnapshot& snapshot) {
LOG(ERROR) << "Detected GWP-ASan crash for allocation at 0x" << std::hex
<< proto.allocation_address() << std::dec << " of type "
<< ErrorToString(proto.error_type());
-
-#if !defined(NDEBUG)
- if (proto.has_deallocation() && proto.deallocation().stack_trace_size() > 0) {
- LOG(ERROR) << "Deallocation stack trace:";
- PrintStackTrace(proto.deallocation().stack_trace());
- }
- if (proto.has_allocation() && proto.allocation().stack_trace_size() > 0) {
- LOG(ERROR) << "Allocation stack trace:";
- PrintStackTrace(proto.allocation().stack_trace());
+ if (proto.has_free_invalid_address()) {
+ LOG(ERROR) << "Invalid address passed to free() is " << std::hex
+ << proto.free_invalid_address() << std::dec;
}
-#endif
return std::make_unique<BufferExtensionStreamDataSource>(
kGwpAsanMinidumpStreamType, proto);
diff --git a/chromium/components/gwp_asan/crash_handler/crash_handler_unittest.cc b/chromium/components/gwp_asan/crash_handler/crash_handler_unittest.cc
index 5a9d3df0029..33c1c86042f 100644
--- a/chromium/components/gwp_asan/crash_handler/crash_handler_unittest.cc
+++ b/chromium/components/gwp_asan/crash_handler/crash_handler_unittest.cc
@@ -4,6 +4,8 @@
#include "components/gwp_asan/crash_handler/crash_handler.h"
+#include <map>
+#include <memory>
#include <string>
#include <vector>
@@ -128,6 +130,10 @@ MULTIPROCESS_TEST_MAIN(CrashingProcess) {
((unsigned char*)ptr)[i] = 0;
} else if (test_name == "UnrelatedException") {
__builtin_trap();
+ } else if (test_name == "FreeInvalidAddress") {
+ void* ptr = gpa->Allocate(kAllocationSize);
+ uintptr_t bad_address = reinterpret_cast<uintptr_t>(ptr) + 1;
+ gpa->Deallocate(reinterpret_cast<void*>(bad_address));
} else {
LOG(ERROR) << "Unknown test name " << test_name;
}
@@ -276,6 +282,12 @@ TEST_F(CrashHandlerTest, MAYBE_DISABLED(Overflow)) {
checkProto(Crash_ErrorType_BUFFER_OVERFLOW, false);
}
+TEST_F(CrashHandlerTest, MAYBE_DISABLED(FreeInvalidAddress)) {
+ ASSERT_TRUE(gwp_asan_found_);
+ checkProto(Crash_ErrorType_FREE_INVALID_ADDRESS, false);
+ EXPECT_TRUE(proto_.has_free_invalid_address());
+}
+
TEST_F(CrashHandlerTest, MAYBE_DISABLED(UnrelatedException)) {
ASSERT_FALSE(gwp_asan_found_);
}
diff --git a/chromium/components/heap_profiling/client_connection_manager.cc b/chromium/components/heap_profiling/client_connection_manager.cc
index 9a281e761e1..59865baf8b4 100644
--- a/chromium/components/heap_profiling/client_connection_manager.cc
+++ b/chromium/components/heap_profiling/client_connection_manager.cc
@@ -4,6 +4,7 @@
#include "components/heap_profiling/client_connection_manager.h"
+#include "base/bind.h"
#include "base/rand_util.h"
#include "base/task/post_task.h"
#include "components/services/heap_profiling/public/cpp/controller.h"
diff --git a/chromium/components/heap_profiling/heap_profiling_test_shim.cc b/chromium/components/heap_profiling/heap_profiling_test_shim.cc
index ca6efeb9edc..bae0523da62 100644
--- a/chromium/components/heap_profiling/heap_profiling_test_shim.cc
+++ b/chromium/components/heap_profiling/heap_profiling_test_shim.cc
@@ -19,8 +19,7 @@ static jlong JNI_HeapProfilingTestShim_Init(JNIEnv* env,
}
HeapProfilingTestShim::HeapProfilingTestShim(JNIEnv* env, jobject obj) {}
-
-HeapProfilingTestShim::~HeapProfilingTestShim() {}
+HeapProfilingTestShim::~HeapProfilingTestShim() = default;
void HeapProfilingTestShim::Destroy(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
@@ -33,6 +32,7 @@ jboolean HeapProfilingTestShim::RunTestForMode(
const base::android::JavaParamRef<jstring>& mode,
jboolean dynamically_start_profiling,
const base::android::JavaParamRef<jstring>& stack_mode,
+ jboolean stream_samples,
jboolean should_sample,
jboolean sample_everything) {
heap_profiling::TestDriver driver;
@@ -42,6 +42,7 @@ jboolean HeapProfilingTestShim::RunTestForMode(
options.stack_mode = heap_profiling::ConvertStringToStackMode(
base::android::ConvertJavaStringToUTF8(stack_mode));
options.profiling_already_started = !dynamically_start_profiling;
+ options.stream_samples = stream_samples;
options.should_sample = should_sample;
options.sample_everything = sample_everything;
return driver.RunTest(options);
diff --git a/chromium/components/heap_profiling/heap_profiling_test_shim.h b/chromium/components/heap_profiling/heap_profiling_test_shim.h
index 134d548ed09..558933c99c8 100644
--- a/chromium/components/heap_profiling/heap_profiling_test_shim.h
+++ b/chromium/components/heap_profiling/heap_profiling_test_shim.h
@@ -23,6 +23,7 @@ class HeapProfilingTestShim {
const base::android::JavaParamRef<jstring>& mode,
jboolean dynamically_start_profiling,
const base::android::JavaParamRef<jstring>& stack_mode,
+ jboolean stream_samples,
jboolean should_sample,
jboolean sample_everything);
diff --git a/chromium/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java b/chromium/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java
index f55ceaf861a..c7f788e5ee0 100644
--- a/chromium/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java
+++ b/chromium/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java
@@ -23,9 +23,9 @@ public class HeapProfilingTestShim {
* rather than native stacks.
*/
public boolean runTestForMode(String mode, boolean dynamicallyStartProfiling, String stackMode,
- boolean shouldSample, boolean sampleEverything) {
+ boolean streamSamples, boolean shouldSample, boolean sampleEverything) {
return nativeRunTestForMode(mNativeHeapProfilingTestShim, mode, dynamicallyStartProfiling,
- stackMode, shouldSample, sampleEverything);
+ stackMode, streamSamples, shouldSample, sampleEverything);
}
/**
@@ -43,6 +43,6 @@ public class HeapProfilingTestShim {
private native long nativeInit();
private native void nativeDestroy(long nativeHeapProfilingTestShim);
private native boolean nativeRunTestForMode(long nativeHeapProfilingTestShim, String mode,
- boolean dynamicallyStartProfiling, String stackMode, boolean shouldSample,
- boolean sampleEverything);
+ boolean dynamicallyStartProfiling, String stackMode, boolean streamSamples,
+ boolean shouldSample, boolean sampleEverything);
}
diff --git a/chromium/components/heap_profiling/supervisor.cc b/chromium/components/heap_profiling/supervisor.cc
index 6351fea333a..54d2ef0642f 100644
--- a/chromium/components/heap_profiling/supervisor.cc
+++ b/chromium/components/heap_profiling/supervisor.cc
@@ -4,6 +4,7 @@
#include "components/heap_profiling/supervisor.h"
+#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
#include "base/task/post_task.h"
@@ -59,24 +60,26 @@ void Supervisor::SetClientConnectionManagerConstructor(
void Supervisor::Start(content::ServiceManagerConnection* connection,
base::OnceClosure closure) {
+ bool stream_samples = !IsInProcessModeEnabled();
Start(connection, GetModeForStartup(), GetStackModeForStartup(),
- GetSamplingRateForStartup(), std::move(closure));
+ stream_samples, GetSamplingRateForStartup(), std::move(closure));
}
void Supervisor::Start(content::ServiceManagerConnection* connection,
Mode mode,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate,
base::OnceClosure closure) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!started_);
base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})
- ->PostTask(FROM_HERE,
- base::BindOnce(&Supervisor::StartServiceOnIOThread,
- base::Unretained(this),
- connection->GetConnector()->Clone(), mode,
- stack_mode, sampling_rate, std::move(closure)));
+ ->PostTask(FROM_HERE, base::BindOnce(&Supervisor::StartServiceOnIOThread,
+ base::Unretained(this),
+ connection->GetConnector()->Clone(),
+ mode, stack_mode, stream_samples,
+ sampling_rate, std::move(closure)));
}
Mode Supervisor::GetMode() {
@@ -179,12 +182,13 @@ void Supervisor::StartServiceOnIOThread(
std::unique_ptr<service_manager::Connector> connector,
Mode mode,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate,
base::OnceClosure closure) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- controller_.reset(
- new Controller(std::move(connector), stack_mode, sampling_rate));
+ controller_.reset(new Controller(std::move(connector), stack_mode,
+ stream_samples, sampling_rate));
base::WeakPtr<Controller> controller_weak_ptr = controller_->GetWeakPtr();
base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI})
diff --git a/chromium/components/heap_profiling/supervisor.h b/chromium/components/heap_profiling/supervisor.h
index b4b85151f6e..592b72e5829 100644
--- a/chromium/components/heap_profiling/supervisor.h
+++ b/chromium/components/heap_profiling/supervisor.h
@@ -72,6 +72,7 @@ class Supervisor {
void Start(content::ServiceManagerConnection* connection,
Mode mode,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate,
base::OnceClosure callback);
@@ -116,6 +117,7 @@ class Supervisor {
std::unique_ptr<service_manager::Connector> connector,
Mode mode,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate,
base::OnceClosure callback);
diff --git a/chromium/components/heap_profiling/test_driver.cc b/chromium/components/heap_profiling/test_driver.cc
index 7a6deccde6a..d8f146ec749 100644
--- a/chromium/components/heap_profiling/test_driver.cc
+++ b/chromium/components/heap_profiling/test_driver.cc
@@ -559,7 +559,7 @@ TestDriver::TestDriver()
base::WaitableEvent::InitialState::NOT_SIGNALED) {
partition_allocator_.init();
}
-TestDriver::~TestDriver() {}
+TestDriver::~TestDriver() = default;
bool TestDriver::RunTest(const Options& options) {
options_ = options;
@@ -631,7 +631,7 @@ bool TestDriver::RunTest(const Options& options) {
}
std::unique_ptr<base::Value> dump_json =
- base::JSONReader::Read(serialized_trace_);
+ base::JSONReader::ReadDeprecated(serialized_trace_);
if (!dump_json) {
LOG(ERROR) << "Failed to deserialize trace.";
return false;
@@ -723,8 +723,8 @@ bool TestDriver::CheckOrStartProfilingOnUIThreadWithAsyncSignalling() {
? (options_.sample_everything ? 2 : kSampleRate)
: 1;
Supervisor::GetInstance()->Start(connection, options_.mode,
- options_.stack_mode, sampling_rate,
- std::move(start_callback));
+ options_.stack_mode, options_.stream_samples,
+ sampling_rate, std::move(start_callback));
return true;
}
@@ -776,8 +776,8 @@ bool TestDriver::CheckOrStartProfilingOnUIThreadWithNestedRunLoops() {
? (options_.sample_everything ? 2 : kSampleRate)
: 1;
Supervisor::GetInstance()->Start(connection, options_.mode,
- options_.stack_mode, sampling_rate,
- std::move(start_callback));
+ options_.stack_mode, options_.stream_samples,
+ sampling_rate, std::move(start_callback));
run_loop->Run();
diff --git a/chromium/components/heap_profiling/test_driver.h b/chromium/components/heap_profiling/test_driver.h
index f897c67204e..03e447b4e3a 100644
--- a/chromium/components/heap_profiling/test_driver.h
+++ b/chromium/components/heap_profiling/test_driver.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/synchronization/waitable_event.h"
+#include "components/services/heap_profiling/public/cpp/settings.h"
#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
namespace base {
@@ -19,8 +20,6 @@ class Value;
namespace heap_profiling {
-enum class Mode;
-
// This class runs tests for the Heap Profiling Service, a cross-platform,
// multi-process component.
//
@@ -45,23 +44,28 @@ class TestDriver {
public:
struct Options {
// The profiling mode to test.
- Mode mode;
+ Mode mode = Mode::kBrowser;
// The stack profiling mode to test.
- mojom::StackMode stack_mode;
+ mojom::StackMode stack_mode = mojom::StackMode::NATIVE_WITHOUT_THREAD_NAMES;
+
+ // Whether the client should stream samples as they are collected through
+ // the provided pipe. When false the samples are accumulated on the client
+ // side and can be retrieved later.
+ bool stream_samples = true;
// Whether the caller has already started profiling with the given mode.
// When false, the test driver is responsible for starting profiling.
- bool profiling_already_started;
+ bool profiling_already_started = false;
// Whether to test sampling.
- bool should_sample;
+ bool should_sample = true;
// When set to true, the internal sampling_rate is set to 2. While this
// doesn't record all allocations, it should record all test allocations
// made in this file with exponentially high probability.
// When set to false, the internal sampling rate is set to 10000.
- bool sample_everything;
+ bool sample_everything = false;
};
TestDriver();
diff --git a/chromium/components/history/core/browser/browsing_history_service.cc b/chromium/components/history/core/browser/browsing_history_service.cc
index 35bce039967..fb64adb1127 100644
--- a/chromium/components/history/core/browser/browsing_history_service.cc
+++ b/chromium/components/history/core/browser/browsing_history_service.cc
@@ -10,6 +10,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
diff --git a/chromium/components/history/core/browser/browsing_history_service_unittest.cc b/chromium/components/history/core/browser/browsing_history_service_unittest.cc
index c7724c9b42e..11f02f97dea 100644
--- a/chromium/components/history/core/browser/browsing_history_service_unittest.cc
+++ b/chromium/components/history/core/browser/browsing_history_service_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
@@ -134,11 +135,11 @@ class TestWebHistoryService : public FakeWebHistoryService {
bool IsPending() override { return false; }
int GetResponseCode() override { return net::HTTP_OK; }
const std::string& GetResponseBody() override { return body_; }
- void SetPostData(const std::string& post_data) override{};
+ void SetPostData(const std::string& post_data) override {}
void SetPostDataAndType(const std::string& post_data,
- const std::string& mime_type) override{};
- void SetUserAgent(const std::string& user_agent) override{};
- void Start() override{};
+ const std::string& mime_type) override {}
+ void SetUserAgent(const std::string& user_agent) override {}
+ void Start() override {}
std::string body_ = "{}";
};
diff --git a/chromium/components/history/core/browser/expire_history_backend.cc b/chromium/components/history/core/browser/expire_history_backend.cc
index 60c3f8a0775..631b25a2ac4 100644
--- a/chromium/components/history/core/browser/expire_history_backend.cc
+++ b/chromium/components/history/core/browser/expire_history_backend.cc
@@ -19,6 +19,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
+#include "base/stl_util.h"
#include "build/build_config.h"
#include "components/history/core/browser/history_backend_client.h"
#include "components/history/core/browser/history_backend_notifier.h"
@@ -183,11 +184,12 @@ void ExpireHistoryBackend::SetDatabases(HistoryDatabase* main_db,
thumb_db_ = thumb_db;
}
-void ExpireHistoryBackend::DeleteURL(const GURL& url) {
- DeleteURLs(std::vector<GURL>(1, url));
+void ExpireHistoryBackend::DeleteURL(const GURL& url, base::Time end_time) {
+ DeleteURLs({url}, end_time);
}
-void ExpireHistoryBackend::DeleteURLs(const std::vector<GURL>& urls) {
+void ExpireHistoryBackend::DeleteURLs(const std::vector<GURL>& urls,
+ base::Time end_time) {
if (!main_db_)
return;
@@ -206,16 +208,24 @@ void ExpireHistoryBackend::DeleteURLs(const std::vector<GURL>& urls) {
// Collect all the visits and delete them. Note that we don't give up if
// there are no visits, since the URL could still have an entry that we
// should delete.
- VisitVector visits;
- main_db_->GetVisitsForURL(url_row.id(), &visits);
-
- DeleteVisitRelatedInfo(visits, &effects);
-
- // We skip ExpireURLsForVisits (since we are deleting from the
- // URL, and not starting with visits in a given time range). We
- // therefore need to call the deletion and favicon update
- // functions manually.
- DeleteOneURL(url_row, is_pinned, &effects);
+ VisitVector visits_to_delete;
+ main_db_->GetVisitsForURL(url_row.id(), &visits_to_delete);
+ size_t total_visits = visits_to_delete.size();
+ if (!end_time.is_null() && !end_time.is_max()) {
+ // Remove all items that should not be deleted from |visits_to_delete|.
+ base::EraseIf(visits_to_delete,
+ [=](auto& v) { return v.visit_time > end_time; });
+ }
+ DeleteVisitRelatedInfo(visits_to_delete, &effects);
+
+ // Remove the URL if all visits have been removed.
+ if (visits_to_delete.size() == total_visits) {
+ // We skip ExpireURLsForVisits (since we are deleting from the
+ // URL, and not starting with visits in a given time range). We
+ // therefore need to call the deletion and favicon update
+ // functions manually.
+ DeleteOneURL(url_row, is_pinned, &effects);
+ }
}
DeleteFaviconsIfPossible(&effects);
diff --git a/chromium/components/history/core/browser/expire_history_backend.h b/chromium/components/history/core/browser/expire_history_backend.h
index 8c95f374da7..98b9205f529 100644
--- a/chromium/components/history/core/browser/expire_history_backend.h
+++ b/chromium/components/history/core/browser/expire_history_backend.h
@@ -72,11 +72,11 @@ class ExpireHistoryBackend {
// will continue until the object is deleted.
void StartExpiringOldStuff(base::TimeDelta expiration_threshold);
- // Deletes everything associated with a URL.
- void DeleteURL(const GURL& url);
+ // Deletes everything associated with a URL until |end_time|.
+ void DeleteURL(const GURL& url, base::Time end_time);
- // Deletes everything associated with each URL in the list.
- void DeleteURLs(const std::vector<GURL>& url);
+ // Deletes everything associated with each URL in the list until |end_time|.
+ void DeleteURLs(const std::vector<GURL>& url, base::Time end_time);
// Removes all visits to restrict_urls (or all URLs if empty) in the given
// time range, updating the URLs accordingly.
diff --git a/chromium/components/history/core/browser/expire_history_backend_unittest.cc b/chromium/components/history/core/browser/expire_history_backend_unittest.cc
index 3a9b995e3fb..983fa3325ea 100644
--- a/chromium/components/history/core/browser/expire_history_backend_unittest.cc
+++ b/chromium/components/history/core/browser/expire_history_backend_unittest.cc
@@ -11,6 +11,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -450,8 +451,9 @@ bool ExpireHistoryTest::IsStringInFile(const base::FilePath& filename,
// Deletes a URL with a favicon that it is the last referencer of, so that it
// should also get deleted.
-// Fails near end of month. http://crbug.com/43586
-TEST_F(ExpireHistoryTest, DISABLED_DeleteURLAndFavicon) {
+// This test failed near end of month.
+// Please comment on http://crbug.com/15724 if it fails again.
+TEST_F(ExpireHistoryTest, DeleteURLAndFavicon) {
URLID url_ids[3];
base::Time visit_times[4];
AddExampleData(url_ids, visit_times);
@@ -468,7 +470,7 @@ TEST_F(ExpireHistoryTest, DISABLED_DeleteURLAndFavicon) {
ASSERT_EQ(1U, visits.size());
// Delete the URL and its dependencies.
- expirer_.DeleteURL(last_row.url());
+ expirer_.DeleteURL(last_row.url(), base::Time::Max());
// All the normal data + the favicon should be gone.
EnsureURLInfoGone(last_row, false);
@@ -476,6 +478,48 @@ TEST_F(ExpireHistoryTest, DISABLED_DeleteURLAndFavicon) {
EXPECT_FALSE(HasFavicon(favicon_id));
}
+// Deletes visits to a URL with a time bound. The url, favicon and the second
+// visit should not get deleted.
+TEST_F(ExpireHistoryTest, DeleteURLWithTimeBound) {
+ URLID url_ids[3];
+ base::Time visit_times[4];
+ AddExampleData(url_ids, visit_times);
+
+ // Remove the first url because it shares the favicon with the second url.
+ URLRow first_row;
+ ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &first_row));
+ expirer_.DeleteURL(first_row.url(), base::Time::Max());
+
+ // Verify things are the way we expect with a URL row, favicon.
+ URLRow second_row;
+ ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &second_row));
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(second_row.url(), favicon_base::IconType::kFavicon);
+ EXPECT_TRUE(HasFavicon(favicon_id));
+
+ VisitVector visits;
+ main_db_->GetVisitsForURL(url_ids[1], &visits);
+ ASSERT_EQ(2U, visits.size());
+
+ // Delete the first visit but not the URL and dependencies.
+ expirer_.DeleteURL(second_row.url(), visits[0].visit_time);
+ // The second visit, URL and favicon should still be there.
+ ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &second_row));
+ VisitVector visits_after_deletion;
+ main_db_->GetVisitsForURL(url_ids[1], &visits_after_deletion);
+ ASSERT_EQ(1U, visits_after_deletion.size());
+ EXPECT_EQ(visits[1].visit_time, visits_after_deletion[0].visit_time);
+ EXPECT_TRUE(GetFavicon(second_row.url(), favicon_base::IconType::kFavicon));
+ EXPECT_TRUE(HasFavicon(favicon_id));
+
+ // Delete the second visit.
+ expirer_.DeleteURL(second_row.url(), visits[1].visit_time);
+ // All the normal data + the favicon should be gone.
+ EnsureURLInfoGone(second_row, false);
+ EXPECT_FALSE(GetFavicon(second_row.url(), favicon_base::IconType::kFavicon));
+ EXPECT_FALSE(HasFavicon(favicon_id));
+}
+
// Deletes a URL with a favicon that other URLs reference, so that the favicon
// should not get deleted. This also tests deleting more than one visit.
TEST_F(ExpireHistoryTest, DeleteURLWithoutFavicon) {
@@ -495,7 +539,7 @@ TEST_F(ExpireHistoryTest, DeleteURLWithoutFavicon) {
EXPECT_EQ(2U, visits.size());
// Delete the URL and its dependencies.
- expirer_.DeleteURL(last_row.url());
+ expirer_.DeleteURL(last_row.url(), base::Time::Max());
// All the normal data except the favicon should be gone.
EnsureURLInfoGone(last_row, false);
@@ -516,7 +560,7 @@ TEST_F(ExpireHistoryTest, DeleteStarredVisitedURL) {
StarURL(url_row.url());
// Attempt to delete the url.
- expirer_.DeleteURL(url_row.url());
+ expirer_.DeleteURL(url_row.url(), base::Time::Max());
// Verify it no longer exists.
GURL url = url_row.url();
@@ -539,7 +583,7 @@ TEST_F(ExpireHistoryTest, DeleteStarredUnvisitedURL) {
StarURL(url);
// Delete it.
- expirer_.DeleteURL(url);
+ expirer_.DeleteURL(url, base::Time::Max());
// The favicon should exist.
favicon_base::FaviconID favicon_id =
@@ -548,7 +592,7 @@ TEST_F(ExpireHistoryTest, DeleteStarredUnvisitedURL) {
// Unstar the URL and try again to delete it.
history_client_.ClearAllBookmarks();
- expirer_.DeleteURL(url);
+ expirer_.DeleteURL(url, base::Time::Max());
// The favicon should be gone.
favicon_id = GetFavicon(url, favicon_base::IconType::kFavicon);
@@ -579,7 +623,7 @@ TEST_F(ExpireHistoryTest, DeleteURLs) {
StarURL(rows[0].url());
// Delete the URLs and their dependencies.
- expirer_.DeleteURLs(urls);
+ expirer_.DeleteURLs(urls, base::Time::Max());
EnsureURLInfoGone(rows[0], false);
EnsureURLInfoGone(rows[1], false);
diff --git a/chromium/components/history/core/browser/history_backend.cc b/chromium/components/history/core/browser/history_backend.cc
index 0ddac915671..82d4cef2588 100644
--- a/chromium/components/history/core/browser/history_backend.cc
+++ b/chromium/components/history/core/browser/history_backend.cc
@@ -14,6 +14,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/files/file_enumerator.h"
#include "base/metrics/histogram_macros.h"
@@ -196,16 +197,18 @@ bool HistoryBackend::IsTypedIncrement(ui::PageTransition transition) {
}
HistoryBackend::HistoryBackend(
- Delegate* delegate,
+ std::unique_ptr<Delegate> delegate,
std::unique_ptr<HistoryBackendClient> backend_client,
scoped_refptr<base::SequencedTaskRunner> task_runner)
- : delegate_(delegate),
+ : delegate_(std::move(delegate)),
scheduled_kill_db_(false),
expirer_(this, backend_client.get(), task_runner),
recent_redirects_(kMaxRedirectCount),
segment_queried_(false),
backend_client_(std::move(backend_client)),
- task_runner_(task_runner) {}
+ task_runner_(task_runner) {
+ DCHECK(delegate_);
+}
HistoryBackend::~HistoryBackend() {
DCHECK(scheduled_commit_.IsCancelled()) << "Deleting without cleanup";
@@ -264,10 +267,6 @@ void HistoryBackend::Closing() {
// Any scheduled commit will have a reference to us, we must make it
// release that reference before we can be destroyed.
CancelScheduledCommit();
-
- // Release our reference to the delegate, this reference will be keeping the
- // history service alive.
- delegate_.reset();
}
#if defined(OS_IOS)
@@ -1132,9 +1131,7 @@ void HistoryBackend::SetKeywordSearchTermsForURL(const GURL& url,
}
db_->SetKeywordSearchTermsForURL(row.id(), keyword_id, term);
-
- if (delegate_)
- delegate_->NotifyKeywordSearchTermUpdated(row, keyword_id, term);
+ delegate_->NotifyKeywordSearchTermUpdated(row, keyword_id, term);
ScheduleCommit();
}
@@ -1155,9 +1152,7 @@ void HistoryBackend::DeleteKeywordSearchTermForURL(const GURL& url) {
if (!url_id)
return;
db_->DeleteKeywordSearchTermForURL(url_id);
-
- if (delegate_)
- delegate_->NotifyKeywordSearchTermDeleted(url_id);
+ delegate_->NotifyKeywordSearchTermDeleted(url_id);
ScheduleCommit();
}
@@ -2419,7 +2414,7 @@ void HistoryBackend::ProcessDBTaskImpl() {
////////////////////////////////////////////////////////////////////////////////
void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) {
- expirer_.DeleteURLs(urls);
+ expirer_.DeleteURLs(urls, base::Time::Max());
db_->GetStartDate(&first_recorded_time_);
// Force a commit, if the user is deleting something for privacy reasons, we
@@ -2428,7 +2423,7 @@ void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) {
}
void HistoryBackend::DeleteURL(const GURL& url) {
- expirer_.DeleteURL(url);
+ expirer_.DeleteURL(url, base::Time::Max());
db_->GetStartDate(&first_recorded_time_);
// Force a commit, if the user is deleting something for privacy reasons, we
@@ -2436,6 +2431,17 @@ void HistoryBackend::DeleteURL(const GURL& url) {
Commit();
}
+void HistoryBackend::DeleteURLsUntil(
+ const std::vector<std::pair<GURL, base::Time>>& urls_and_timestamps) {
+ for (const auto& pair : urls_and_timestamps) {
+ expirer_.DeleteURL(pair.first, pair.second);
+ }
+ db_->GetStartDate(&first_recorded_time_);
+ // Force a commit, if the user is deleting something for privacy reasons, we
+ // want to get it on disk ASAP.
+ Commit();
+}
+
void HistoryBackend::ExpireHistoryBetween(const std::set<GURL>& restrict_urls,
Time begin_time,
Time end_time,
@@ -2550,7 +2556,7 @@ void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) {
// that we can delete all associated icons in the case of deleting an
// unvisited bookmarked URL.
if (visits.empty())
- expirer_.DeleteURL(*i); // There are no more visits; nuke the URL.
+ expirer_.DeleteURL(*i, base::Time::Max());
}
}
@@ -2626,8 +2632,7 @@ void HistoryBackend::ProcessDBTask(
void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls,
const GURL& icon_url) {
- if (delegate_)
- delegate_->NotifyFaviconsChanged(page_urls, icon_url);
+ delegate_->NotifyFaviconsChanged(page_urls, icon_url);
}
void HistoryBackend::NotifyURLVisited(ui::PageTransition transition,
@@ -2637,8 +2642,7 @@ void HistoryBackend::NotifyURLVisited(ui::PageTransition transition,
for (HistoryBackendObserver& observer : observers_)
observer.OnURLVisited(this, transition, row, redirects, visit_time);
- if (delegate_)
- delegate_->NotifyURLVisited(transition, row, redirects, visit_time);
+ delegate_->NotifyURLVisited(transition, row, redirects, visit_time);
}
void HistoryBackend::NotifyURLsModified(const URLRows& changed_urls,
@@ -2646,8 +2650,7 @@ void HistoryBackend::NotifyURLsModified(const URLRows& changed_urls,
for (HistoryBackendObserver& observer : observers_)
observer.OnURLsModified(this, changed_urls, is_from_expiration);
- if (delegate_)
- delegate_->NotifyURLsModified(changed_urls);
+ delegate_->NotifyURLsModified(changed_urls);
}
void HistoryBackend::NotifyURLsDeleted(DeletionInfo deletion_info) {
@@ -2664,8 +2667,7 @@ void HistoryBackend::NotifyURLsDeleted(DeletionInfo deletion_info) {
deletion_info.deleted_rows(), deletion_info.favicon_urls());
}
- if (delegate_)
- delegate_->NotifyURLsDeleted(std::move(deletion_info));
+ delegate_->NotifyURLsDeleted(std::move(deletion_info));
}
// Deleting --------------------------------------------------------------------
diff --git a/chromium/components/history/core/browser/history_backend.h b/chromium/components/history/core/browser/history_backend.h
index 2a125ad697b..c3b1094a340 100644
--- a/chromium/components/history/core/browser/history_backend.h
+++ b/chromium/components/history/core/browser/history_backend.h
@@ -185,7 +185,7 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
// may be null.
//
// This constructor is fast and does no I/O, so can be called at any time.
- HistoryBackend(Delegate* delegate,
+ HistoryBackend(std::unique_ptr<Delegate> delegate,
std::unique_ptr<HistoryBackendClient> backend_client,
scoped_refptr<base::SequencedTaskRunner> task_runner);
@@ -415,9 +415,13 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
// Deleting ------------------------------------------------------------------
- virtual void DeleteURLs(const std::vector<GURL>& urls);
+ void DeleteURLs(const std::vector<GURL>& urls);
- virtual void DeleteURL(const GURL& url);
+ void DeleteURL(const GURL& url);
+
+ // Deletes all visits to urls until the corresponding timestamp.
+ void DeleteURLsUntil(
+ const std::vector<std::pair<GURL, base::Time>>& urls_and_timestamps);
// Calls ExpireHistoryBackend::ExpireHistoryBetween and commits the change.
void ExpireHistoryBetween(const std::set<GURL>& restrict_urls,
diff --git a/chromium/components/history/core/browser/history_backend_db_unittest.cc b/chromium/components/history/core/browser/history_backend_db_unittest.cc
index 9ac52f4ff4c..17fb57fb9f3 100644
--- a/chromium/components/history/core/browser/history_backend_db_unittest.cc
+++ b/chromium/components/history/core/browser/history_backend_db_unittest.cc
@@ -24,6 +24,7 @@
#include <string>
#include <unordered_set>
+#include "base/bind.h"
#include "base/format_macros.h"
#include "base/guid.h"
#include "base/run_loop.h"
diff --git a/chromium/components/history/core/browser/history_backend_unittest.cc b/chromium/components/history/core/browser/history_backend_unittest.cc
index f83a69392e6..69a99967115 100644
--- a/chromium/components/history/core/browser/history_backend_unittest.cc
+++ b/chromium/components/history/core/browser/history_backend_unittest.cc
@@ -254,9 +254,10 @@ class HistoryBackendTestBase : public testing::Test {
if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("BackendTest"),
&test_dir_))
return;
- backend_ = new HistoryBackend(new HistoryBackendTestDelegate(this),
- history_client_.CreateBackendClient(),
- base::ThreadTaskRunnerHandle::Get());
+ backend_ = base::MakeRefCounted<HistoryBackend>(
+ std::make_unique<HistoryBackendTestDelegate>(this),
+ history_client_.CreateBackendClient(),
+ base::ThreadTaskRunnerHandle::Get());
backend_->Init(false, TestHistoryDatabaseParamsForPath(test_dir_));
}
@@ -844,7 +845,7 @@ TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
history_client_.AddBookmark(row2.url());
// Delete url 2.
- backend_->expirer_.DeleteURL(row2.url());
+ backend_->expirer_.DeleteURL(row2.url(), base::Time::Max());
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), nullptr));
VisitVector visits;
backend_->db_->GetVisitsForURL(row2_id, &visits);
@@ -1666,9 +1667,10 @@ TEST_F(HistoryBackendTest, MigrationVisitSource) {
base::FilePath new_history_file = new_history_path.Append(kHistoryFilename);
ASSERT_TRUE(base::CopyFile(old_history_path, new_history_file));
- backend_ = new HistoryBackend(new HistoryBackendTestDelegate(this),
- history_client_.CreateBackendClient(),
- base::ThreadTaskRunnerHandle::Get());
+ backend_ = base::MakeRefCounted<HistoryBackend>(
+ std::make_unique<HistoryBackendTestDelegate>(this),
+ history_client_.CreateBackendClient(),
+ base::ThreadTaskRunnerHandle::Get());
backend_->Init(false, TestHistoryDatabaseParamsForPath(new_history_path));
backend_->Closing();
backend_ = nullptr;
@@ -3360,9 +3362,10 @@ TEST_F(HistoryBackendTest, MigrationVisitDuration) {
base::FilePath new_history_file = new_history_path.Append(kHistoryFilename);
ASSERT_TRUE(base::CopyFile(old_history, new_history_file));
- backend_ = new HistoryBackend(new HistoryBackendTestDelegate(this),
- history_client_.CreateBackendClient(),
- base::ThreadTaskRunnerHandle::Get());
+ backend_ = base::MakeRefCounted<HistoryBackend>(
+ std::make_unique<HistoryBackendTestDelegate>(this),
+ history_client_.CreateBackendClient(),
+ base::ThreadTaskRunnerHandle::Get());
backend_->Init(false, TestHistoryDatabaseParamsForPath(new_history_path));
backend_->Closing();
backend_ = nullptr;
diff --git a/chromium/components/history/core/browser/history_service.cc b/chromium/components/history/core/browser/history_service.cc
index a737d5dd176..5d0faeaa3cf 100644
--- a/chromium/components/history/core/browser/history_service.cc
+++ b/chromium/components/history/core/browser/history_service.cc
@@ -22,6 +22,7 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
+#include "base/feature_list.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
@@ -50,7 +51,6 @@
#include "components/history/core/common/thumbnail_score.h"
#include "components/sync/model/sync_error_factory.h"
#include "components/sync/model_impl/proxy_model_type_controller_delegate.h"
-#include "components/variations/variations_associated_data.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/page_transition_types.h"
@@ -63,6 +63,9 @@ using base::Time;
namespace history {
namespace {
+const base::Feature kHistoryServiceUsesTaskScheduler{
+ "HistoryServiceUsesTaskScheduler", base::FEATURE_DISABLED_BY_DEFAULT};
+
static const char* kHistoryThreadName = "Chrome_HistoryThread";
void RunWithFaviconResults(
@@ -188,9 +191,7 @@ HistoryService::HistoryService() : HistoryService(nullptr, nullptr) {}
HistoryService::HistoryService(std::unique_ptr<HistoryClient> history_client,
std::unique_ptr<VisitDelegate> visit_delegate)
- : thread_(variations::GetVariationParamValue("BrowserScheduler",
- "RedirectHistoryService") ==
- "true"
+ : thread_(base::FeatureList::IsEnabled(kHistoryServiceUsesTaskScheduler)
? nullptr
: new base::Thread(kHistoryThreadName)),
history_client_(std::move(history_client)),
@@ -894,31 +895,8 @@ void HistoryService::Cleanup() {
// Get rid of the in-memory backend.
in_memory_backend_.reset();
- // The backend's destructor must run on the history thread since it is not
- // threadsafe. So this thread must not be the last thread holding a
- // reference to the backend, or a crash could happen.
- //
- // We have a reference to the history backend. There is also an extra
- // reference held by our delegate installed in the backend, which
- // HistoryBackend::Closing will release. This means if we scheduled a call
- // to HistoryBackend::Closing and *then* released our backend reference,
- // there will be a race between us and the backend's Closing function to see
- // who is the last holder of a reference. If the backend thread's Closing
- // manages to run before we release our backend refptr, the last reference
- // will be held by this thread and the destructor will be called from here.
- //
- // Therefore, we create a closure to run the Closing operation first. This
- // holds a reference to the backend. Then we release our reference, then we
- // schedule the task to run. After the task runs, it will delete its
- // reference from the history thread, ensuring everything works properly.
- //
- // TODO(ajwong): Cleanup HistoryBackend lifetime issues.
- // See http://crbug.com/99767.
- base::Closure closing_task =
- base::Bind(&HistoryBackend::Closing, history_backend_);
- ScheduleTask(PRIORITY_NORMAL, closing_task);
- closing_task.Reset();
- backend_task_runner_->ReleaseSoon(FROM_HERE, std::move(history_backend_));
+ ScheduleTask(PRIORITY_NORMAL, base::BindOnce(&HistoryBackend::Closing,
+ std::move(history_backend_)));
}
// Clear |backend_task_runner_| to make sure it's not used after Cleanup().
@@ -954,9 +932,9 @@ bool HistoryService::Init(
}
// Create the history backend.
- scoped_refptr<HistoryBackend> backend(new HistoryBackend(
- new BackendDelegate(weak_ptr_factory_.GetWeakPtr(),
- base::ThreadTaskRunnerHandle::Get()),
+ scoped_refptr<HistoryBackend> backend(base::MakeRefCounted<HistoryBackend>(
+ std::make_unique<BackendDelegate>(weak_ptr_factory_.GetWeakPtr(),
+ base::ThreadTaskRunnerHandle::Get()),
history_client_ ? history_client_->CreateBackendClient() : nullptr,
backend_task_runner_));
history_backend_.swap(backend);
@@ -1127,20 +1105,15 @@ void HistoryService::ExpireHistoryBeforeForTesting(
std::move(callback));
}
-void HistoryService::ExpireLocalAndRemoteHistoryBetween(
+void HistoryService::DeleteLocalAndRemoteHistoryBetween(
WebHistoryService* web_history,
- const std::set<GURL>& restrict_urls,
Time begin_time,
Time end_time,
- bool user_initiated,
base::OnceClosure callback,
base::CancelableTaskTracker* tracker) {
- // TODO(dubroy): This should be factored out into a separate class that
- // dispatches deletions to the proper places.
+ // TODO(crbug.com/929111): This should be factored out into a separate class
+ // that dispatches deletions to the proper places.
if (web_history) {
- // TODO(dubroy): This API does not yet support deletion of specific URLs.
- DCHECK(restrict_urls.empty());
-
delete_directive_handler_.CreateDeleteDirectives(std::set<int64_t>(),
begin_time, end_time);
@@ -1173,12 +1146,50 @@ void HistoryService::ExpireLocalAndRemoteHistoryBetween(
}
}
})");
- web_history->ExpireHistoryBetween(restrict_urls, begin_time, end_time,
- base::Bind(&ExpireWebHistoryComplete),
- partial_traffic_annotation);
+ web_history->ExpireHistoryBetween(
+ /*restrict_urls=*/{}, begin_time, end_time,
+ base::Bind(&ExpireWebHistoryComplete), partial_traffic_annotation);
+ }
+ ExpireHistoryBetween(/*restrict_urls=*/{}, begin_time, end_time,
+ /*user_initiated=*/true, std::move(callback), tracker);
+}
+
+void HistoryService::DeleteLocalAndRemoteUrl(WebHistoryService* web_history,
+ const GURL& url) {
+ DCHECK(url.is_valid());
+ // TODO(crbug.com/929111): This should be factored out into a separate class
+ // that dispatches deletions to the proper places.
+ if (web_history) {
+ delete_directive_handler_.CreateUrlDeleteDirective(url);
+
+ // Attempt online deletion from the history server, but ignore the result.
+ // Deletion directives ensure that the results will eventually be deleted.
+ net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
+ net::DefinePartialNetworkTrafficAnnotation("web_history_delete_url",
+ "web_history_service", R"(
+ semantics {
+ description:
+ "If a user who syncs their browsing history deletes urls from "
+ "history, Chrome sends a request to a google.com "
+ "host to execute the corresponding deletion serverside."
+ trigger:
+ "Deleting urls from browsing history, e.g. by an extension."
+ data:
+ "The selected urls, a version info token to resolve transaction "
+ "conflicts, and an OAuth2 token authenticating the user."
+ }
+ policy {
+ chrome_policy {
+ AllowDeletingBrowserHistory {
+ AllowDeletingBrowserHistory: false
+ }
+ }
+ })");
+ web_history->ExpireHistoryBetween(
+ /*restrict_urls=*/{url}, base::Time(), base::Time::Max(),
+ base::Bind(&ExpireWebHistoryComplete), partial_traffic_annotation);
}
- ExpireHistoryBetween(restrict_urls, begin_time, end_time, user_initiated,
- std::move(callback), tracker);
+ DeleteURL(url);
}
void HistoryService::OnDBLoaded() {
diff --git a/chromium/components/history/core/browser/history_service.h b/chromium/components/history/core/browser/history_service.h
index 69c681257bb..b751f281885 100644
--- a/chromium/components/history/core/browser/history_service.h
+++ b/chromium/components/history/core/browser/history_service.h
@@ -360,14 +360,16 @@ class HistoryService : public syncer::SyncableService, public KeyedService {
// Removes all visits to the given URLs in the specified time range. Calls
// ExpireHistoryBetween() to delete local visits, and handles deletion of
// synced visits if appropriate.
- void ExpireLocalAndRemoteHistoryBetween(WebHistoryService* web_history,
- const std::set<GURL>& restrict_urls,
+ void DeleteLocalAndRemoteHistoryBetween(WebHistoryService* web_history,
base::Time begin_time,
base::Time end_time,
- bool user_initiated,
base::OnceClosure callback,
base::CancelableTaskTracker* tracker);
+ // Removes all visits to the given url. Calls DeleteUrl() to delete local
+ // visits and handles deletion of synced visits if appropriate.
+ void DeleteLocalAndRemoteUrl(WebHistoryService* web_history, const GURL& url);
+
// Processes the given |delete_directive| and sends it to the
// SyncChangeProcessor (if it exists). Returns any error resulting
// from sending the delete directive to sync.
diff --git a/chromium/components/history/core/browser/history_service_unittest.cc b/chromium/components/history/core/browser/history_service_unittest.cc
index 631a6a5e1e1..b98a76d342a 100644
--- a/chromium/components/history/core/browser/history_service_unittest.cc
+++ b/chromium/components/history/core/browser/history_service_unittest.cc
@@ -26,6 +26,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
@@ -616,6 +617,10 @@ class HistoryDBTaskImpl : public HistoryDBTask {
// static
const int HistoryDBTaskImpl::kWantInvokeCount = 2;
+base::Time UnixUsecToTime(int64_t usec) {
+ return base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(usec);
+}
+
} // namespace
TEST_F(HistoryServiceTest, HistoryDBTask) {
@@ -665,8 +670,7 @@ TEST_F(HistoryServiceTest, ProcessLocalDeleteDirectiveSyncOnline) {
const GURL test_url("http://www.google.com/");
for (int64_t i = 1; i <= 10; ++i) {
- base::Time t =
- base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
+ base::Time t = UnixUsecToTime(i);
history_service_->AddPage(test_url, t, nullptr, 0, GURL(),
history::RedirectList(), ui::PAGE_TRANSITION_LINK,
history::SOURCE_BROWSED, false);
@@ -728,8 +732,7 @@ TEST_F(HistoryServiceTest, ProcessGlobalIdDeleteDirective) {
ASSERT_TRUE(history_service_.get());
const GURL test_url("http://www.google.com/");
for (int64_t i = 1; i <= 20; i++) {
- base::Time t =
- base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
+ base::Time t = UnixUsecToTime(i);
history_service_->AddPage(test_url, t, nullptr, 0, GURL(),
history::RedirectList(), ui::PAGE_TRANSITION_LINK,
history::SOURCE_BROWSED, false);
@@ -781,16 +784,11 @@ TEST_F(HistoryServiceTest, ProcessGlobalIdDeleteDirective) {
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
ASSERT_EQ(5, query_url_row_.visit_count());
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1),
- query_url_visits_[0].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(2),
- query_url_visits_[1].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(11),
- query_url_visits_[2].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(12),
- query_url_visits_[3].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(20),
- query_url_visits_[4].visit_time);
+ EXPECT_EQ(UnixUsecToTime(1), query_url_visits_[0].visit_time);
+ EXPECT_EQ(UnixUsecToTime(2), query_url_visits_[1].visit_time);
+ EXPECT_EQ(UnixUsecToTime(11), query_url_visits_[2].visit_time);
+ EXPECT_EQ(UnixUsecToTime(12), query_url_visits_[3].visit_time);
+ EXPECT_EQ(UnixUsecToTime(20), query_url_visits_[4].visit_time);
// Expect two sync changes for deleting processed directives.
const syncer::SyncChangeList& sync_changes = change_processor.changes();
@@ -807,8 +805,7 @@ TEST_F(HistoryServiceTest, ProcessTimeRangeDeleteDirective) {
ASSERT_TRUE(history_service_.get());
const GURL test_url("http://www.google.com/");
for (int64_t i = 1; i <= 10; ++i) {
- base::Time t =
- base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(i);
+ base::Time t = UnixUsecToTime(i);
history_service_->AddPage(test_url, t, nullptr, 0, GURL(),
history::RedirectList(), ui::PAGE_TRANSITION_LINK,
history::SOURCE_BROWSED, false);
@@ -854,12 +851,9 @@ TEST_F(HistoryServiceTest, ProcessTimeRangeDeleteDirective) {
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(QueryURL(history_service_.get(), test_url));
ASSERT_EQ(3, query_url_row_.visit_count());
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(1),
- query_url_visits_[0].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(6),
- query_url_visits_[1].visit_time);
- EXPECT_EQ(base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(7),
- query_url_visits_[2].visit_time);
+ EXPECT_EQ(UnixUsecToTime(1), query_url_visits_[0].visit_time);
+ EXPECT_EQ(UnixUsecToTime(6), query_url_visits_[1].visit_time);
+ EXPECT_EQ(UnixUsecToTime(7), query_url_visits_[2].visit_time);
// Expect two sync changes for deleting processed directives.
const syncer::SyncChangeList& sync_changes = change_processor.changes();
@@ -870,6 +864,74 @@ TEST_F(HistoryServiceTest, ProcessTimeRangeDeleteDirective) {
EXPECT_EQ(2, syncer::SyncDataRemote(sync_changes[1].sync_data()).GetId());
}
+// Create a delete directive for urls. The expected entries should be
+// deleted.
+TEST_F(HistoryServiceTest, ProcessUrlDeleteDirective) {
+ ASSERT_TRUE(history_service_.get());
+ const GURL test_url1("http://www.google.com/");
+ const GURL test_url2("http://maps.google.com/");
+
+ history_service_->AddPage(test_url1, UnixUsecToTime(3), nullptr, 0, GURL(),
+ history::RedirectList(), ui::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ history_service_->AddPage(test_url2, UnixUsecToTime(6), nullptr, 0, GURL(),
+ history::RedirectList(), ui::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+ history_service_->AddPage(test_url1, UnixUsecToTime(10), nullptr, 0, GURL(),
+ history::RedirectList(), ui::PAGE_TRANSITION_LINK,
+ history::SOURCE_BROWSED, false);
+
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url1));
+ ASSERT_EQ(2, query_url_row_.visit_count());
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url2));
+
+ // Delete the first visit of url1 and all visits of url2.
+ syncer::SyncDataList directives;
+ sync_pb::EntitySpecifics entity_specs1;
+ sync_pb::UrlDirective* url_directive =
+ entity_specs1.mutable_history_delete_directive()->mutable_url_directive();
+ url_directive->set_url(test_url1.spec());
+ url_directive->set_end_time_usec(8);
+ directives.push_back(syncer::SyncData::CreateRemoteData(1, entity_specs1));
+ sync_pb::EntitySpecifics entity_specs2;
+ url_directive =
+ entity_specs2.mutable_history_delete_directive()->mutable_url_directive();
+ url_directive->set_url(test_url2.spec());
+ url_directive->set_end_time_usec(8);
+ directives.push_back(syncer::SyncData::CreateRemoteData(2, entity_specs2));
+
+ syncer::FakeSyncChangeProcessor change_processor;
+ EXPECT_FALSE(history_service_
+ ->MergeDataAndStartSyncing(
+ syncer::HISTORY_DELETE_DIRECTIVES, directives,
+ std::unique_ptr<syncer::SyncChangeProcessor>(
+ new syncer::SyncChangeProcessorWrapperForTest(
+ &change_processor)),
+ std::unique_ptr<syncer::SyncErrorFactory>())
+ .error()
+ .IsSet());
+
+ // Inject a task to check status and keep message loop filled before
+ // directive processing finishes.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CheckDirectiveProcessingResult,
+ base::Time::Now() + base::TimeDelta::FromSeconds(10),
+ &change_processor, 2));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(QueryURL(history_service_.get(), test_url1));
+ EXPECT_EQ(UnixUsecToTime(10), query_url_visits_[0].visit_time);
+ EXPECT_FALSE(QueryURL(history_service_.get(), test_url2));
+
+ // Expect a sync change for deleting processed directives.
+ const syncer::SyncChangeList& sync_changes = change_processor.changes();
+ ASSERT_EQ(2u, sync_changes.size());
+ EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[0].change_type());
+ EXPECT_EQ(1, syncer::SyncDataRemote(sync_changes[0].sync_data()).GetId());
+ EXPECT_EQ(syncer::SyncChange::ACTION_DELETE, sync_changes[1].change_type());
+ EXPECT_EQ(2, syncer::SyncDataRemote(sync_changes[1].sync_data()).GetId());
+}
+
// Helper to add a page with specified days back in the past.
void AddPageInThePast(HistoryService* history,
const std::string& url_spec,
diff --git a/chromium/components/history/core/browser/history_types.cc b/chromium/components/history/core/browser/history_types.cc
index a7cc78b4daf..9c853028b0b 100644
--- a/chromium/components/history/core/browser/history_types.cc
+++ b/chromium/components/history/core/browser/history_types.cc
@@ -383,7 +383,7 @@ DeletionInfo::DeletionInfo(const DeletionTimeRange& time_range,
DCHECK(time_range_.IsValid() || !restrict_urls_.has_value());
// If restrict_urls_ is defined, it should be non-empty.
DCHECK(!restrict_urls_.has_value() || !restrict_urls_->empty());
-};
+}
DeletionInfo::~DeletionInfo() = default;
diff --git a/chromium/components/history/core/browser/sync/delete_directive_handler.cc b/chromium/components/history/core/browser/sync/delete_directive_handler.cc
index f5544527f38..25b087c5d50 100644
--- a/chromium/components/history/core/browser/sync/delete_directive_handler.cc
+++ b/chromium/components/history/core/browser/sync/delete_directive_handler.cc
@@ -10,6 +10,7 @@
#include <map>
#include <string>
#include <utility>
+#include <vector>
#include "base/json/json_writer.h"
#include "base/rand_util.h"
@@ -87,6 +88,7 @@ void CheckDeleteDirectiveValid(
delete_directive.global_id_directive();
DCHECK(!delete_directive.has_time_range_directive());
+ DCHECK(!delete_directive.has_url_directive());
DCHECK_NE(global_id_directive.global_id_size(), 0);
if (global_id_directive.has_start_time_usec())
DCHECK_GE(global_id_directive.start_time_usec(), 0);
@@ -104,14 +106,24 @@ void CheckDeleteDirectiveValid(
delete_directive.time_range_directive();
DCHECK(!delete_directive.has_global_id_directive());
+ DCHECK(!delete_directive.has_url_directive());
DCHECK(time_range_directive.has_start_time_usec());
DCHECK(time_range_directive.has_end_time_usec());
DCHECK_GE(time_range_directive.start_time_usec(), 0);
DCHECK_GT(time_range_directive.end_time_usec(), 0);
DCHECK_GT(time_range_directive.end_time_usec(),
time_range_directive.start_time_usec());
+ } else if (delete_directive.has_url_directive()) {
+ const sync_pb::UrlDirective& url_directive =
+ delete_directive.url_directive();
+
+ DCHECK(!delete_directive.has_global_id_directive());
+ DCHECK(!delete_directive.has_time_range_directive());
+ DCHECK(url_directive.has_url());
+ DCHECK_GT(url_directive.end_time_usec(), 0);
} else {
- NOTREACHED() << "Delete directive has no time range or global ID directive";
+ NOTREACHED()
+ << "Delete directive has no time range, global ID or url directive";
}
}
#endif // !defined(NDEBUG)
@@ -151,6 +163,11 @@ class DeleteDirectiveHandler::DeleteDirectiveTask : public HistoryDBTask {
HistoryBackend* history_backend,
const syncer::SyncDataList& time_range_directives);
+ // Process a list of url directives, all history entries matching the
+ // urls are deleted.
+ void ProcessUrlDeleteDirectives(HistoryBackend* history_backend,
+ const syncer::SyncDataList& url_directives);
+
base::WeakPtr<DeleteDirectiveHandler> delete_directive_handler_;
syncer::SyncDataList delete_directives_;
DeleteDirectiveHandler::PostProcessingAction post_processing_action_;
@@ -161,15 +178,17 @@ bool DeleteDirectiveHandler::DeleteDirectiveTask::RunOnDBThread(
HistoryDatabase* db) {
syncer::SyncDataList global_id_directives;
syncer::SyncDataList time_range_directives;
- for (syncer::SyncDataList::const_iterator it = delete_directives_.begin();
- it != delete_directives_.end(); ++it) {
- DCHECK_EQ(it->GetDataType(), syncer::HISTORY_DELETE_DIRECTIVES);
+ syncer::SyncDataList url_directives;
+ for (const auto& sync_data : delete_directives_) {
+ DCHECK_EQ(sync_data.GetDataType(), syncer::HISTORY_DELETE_DIRECTIVES);
const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive =
- it->GetSpecifics().history_delete_directive();
+ sync_data.GetSpecifics().history_delete_directive();
if (delete_directive.has_global_id_directive()) {
- global_id_directives.push_back(*it);
- } else {
- time_range_directives.push_back(*it);
+ global_id_directives.push_back(sync_data);
+ } else if (delete_directive.has_time_range_directive()) {
+ time_range_directives.push_back(sync_data);
+ } else if (delete_directive.has_url_directive()) {
+ url_directives.push_back(sync_data);
}
}
@@ -177,6 +196,7 @@ bool DeleteDirectiveHandler::DeleteDirectiveTask::RunOnDBThread(
std::sort(time_range_directives.begin(), time_range_directives.end(),
TimeRangeLessThan);
ProcessTimeRangeDeleteDirectives(backend, time_range_directives);
+ ProcessUrlDeleteDirectives(backend, url_directives);
return true;
}
@@ -291,6 +311,30 @@ void DeleteDirectiveHandler::DeleteDirectiveTask::
}
}
+void DeleteDirectiveHandler::DeleteDirectiveTask::ProcessUrlDeleteDirectives(
+ HistoryBackend* history_backend,
+ const syncer::SyncDataList& url_directives) {
+ std::vector<std::pair<GURL, base::Time>> deletions;
+ for (const auto& sync_data : url_directives) {
+ const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive =
+ sync_data.GetSpecifics().history_delete_directive();
+ DVLOG(1) << "Processing url directive: "
+ << DeleteDirectiveToString(delete_directive);
+ const sync_pb::UrlDirective& url_directive =
+ delete_directive.url_directive();
+
+ if (!url_directive.has_url() || !url_directive.has_end_time_usec())
+ continue;
+
+ GURL url(url_directive.url());
+ base::Time end_time = UnixUsecToTime(url_directive.end_time_usec());
+ if (url.is_valid())
+ deletions.emplace_back(url, end_time);
+ }
+ if (!deletions.empty())
+ history_backend->DeleteURLsUntil(deletions);
+}
+
DeleteDirectiveHandler::DeleteDirectiveHandler() : weak_ptr_factory_(this) {}
DeleteDirectiveHandler::~DeleteDirectiveHandler() {
@@ -354,6 +398,19 @@ bool DeleteDirectiveHandler::CreateDeleteDirectives(
return !error.IsSet();
}
+bool DeleteDirectiveHandler::CreateUrlDeleteDirective(const GURL& url) {
+ DCHECK(url.is_valid());
+ sync_pb::HistoryDeleteDirectiveSpecifics delete_directive;
+
+ sync_pb::UrlDirective* url_directive =
+ delete_directive.mutable_url_directive();
+ url_directive->set_url(url.spec());
+ url_directive->set_end_time_usec(TimeToUnixUsec(base::Time::Now()));
+
+ syncer::SyncError error = ProcessLocalDeleteDirective(delete_directive);
+ return !error.IsSet();
+}
+
syncer::SyncError DeleteDirectiveHandler::ProcessLocalDeleteDirective(
const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chromium/components/history/core/browser/sync/delete_directive_handler.h b/chromium/components/history/core/browser/sync/delete_directive_handler.h
index 61e0f0705c3..84e058111a4 100644
--- a/chromium/components/history/core/browser/sync/delete_directive_handler.h
+++ b/chromium/components/history/core/browser/sync/delete_directive_handler.h
@@ -17,6 +17,8 @@
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_data.h"
+class GURL;
+
namespace sync_pb {
class HistoryDeleteDirectiveSpecifics;
}
@@ -46,6 +48,8 @@ class DeleteDirectiveHandler {
base::Time begin_time,
base::Time end_time);
+ bool CreateUrlDeleteDirective(const GURL& url);
+
// Sends the given |delete_directive| to SyncChangeProcessor (if it exists).
// Returns any error resulting from sending the delete directive to sync.
// NOTE: the given |delete_directive| is not processed to remove local
diff --git a/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc b/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc
index faf0c238199..38b346737d7 100644
--- a/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc
+++ b/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.cc
@@ -18,10 +18,11 @@ HistoryDeleteDirectivesModelTypeController::
HistoryDeleteDirectivesModelTypeController(
const base::RepeatingClosure& dump_stack,
syncer::SyncService* sync_service,
+ syncer::ModelTypeStoreService* model_type_store_service,
syncer::SyncClient* sync_client)
: SyncableServiceBasedModelTypeController(
syncer::HISTORY_DELETE_DIRECTIVES,
- sync_client->GetModelTypeStoreService()->GetStoreFactory(),
+ model_type_store_service->GetStoreFactory(),
base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType,
base::Unretained(sync_client),
syncer::HISTORY_DELETE_DIRECTIVES),
@@ -42,10 +43,6 @@ void HistoryDeleteDirectivesModelTypeController::LoadModels(
DCHECK(CalledOnValidThread());
DCHECK_EQ(NOT_RUNNING, state());
- if (DisableTypeIfNecessary()) {
- return;
- }
-
sync_service_->AddObserver(this);
SyncableServiceBasedModelTypeController::LoadModels(configure_context,
model_load_callback);
@@ -65,27 +62,8 @@ void HistoryDeleteDirectivesModelTypeController::Stop(
void HistoryDeleteDirectivesModelTypeController::OnStateChanged(
syncer::SyncService* sync) {
DCHECK(CalledOnValidThread());
- DisableTypeIfNecessary();
-}
-
-bool HistoryDeleteDirectivesModelTypeController::DisableTypeIfNecessary() {
- DCHECK(CalledOnValidThread());
-
- if (!sync_service_->IsSyncFeatureActive()) {
- return false;
- }
-
- if (ReadyForStart()) {
- return false;
- }
-
- sync_service_->RemoveObserver(this);
-
- ReportModelError(
- syncer::SyncError::DATATYPE_POLICY_ERROR,
- syncer::ModelError(FROM_HERE,
- "Delete directives not supported with encryption."));
- return true;
+ // Most of these calls will be no-ops but SyncService handles that just fine.
+ sync_service_->ReadyForStartChanged(type());
}
} // namespace browser_sync
diff --git a/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.h b/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.h
index 07910a19aed..93cb9d33661 100644
--- a/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.h
+++ b/chromium/components/history/core/browser/sync/history_delete_directives_model_type_controller.h
@@ -11,6 +11,7 @@
#include "components/sync/driver/syncable_service_based_model_type_controller.h"
namespace syncer {
+class ModelTypeStoreService;
class SyncClient;
class SyncService;
} // namespace syncer
@@ -28,6 +29,7 @@ class HistoryDeleteDirectivesModelTypeController
HistoryDeleteDirectivesModelTypeController(
const base::RepeatingClosure& dump_stack,
syncer::SyncService* sync_service,
+ syncer::ModelTypeStoreService* model_type_store_service,
syncer::SyncClient* sync_client);
~HistoryDeleteDirectivesModelTypeController() override;
@@ -42,10 +44,6 @@ class HistoryDeleteDirectivesModelTypeController
void OnStateChanged(syncer::SyncService* sync) override;
private:
- // Triggers a SingleDataTypeUnrecoverable error and returns true if the
- // type is no longer ready, else does nothing and returns false.
- bool DisableTypeIfNecessary();
-
syncer::SyncService* const sync_service_;
DISALLOW_COPY_AND_ASSIGN(HistoryDeleteDirectivesModelTypeController);
diff --git a/chromium/components/history/core/browser/sync/history_model_worker.cc b/chromium/components/history/core/browser/sync/history_model_worker.cc
index a309b734c62..6ad79312f04 100644
--- a/chromium/components/history/core/browser/sync/history_model_worker.cc
+++ b/chromium/components/history/core/browser/sync/history_model_worker.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "components/history/core/browser/history_db_task.h"
#include "components/history/core/browser/history_service.h"
diff --git a/chromium/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/chromium/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
index 96855200f4c..5f1ce8376fb 100644
--- a/chromium/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
+++ b/chromium/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include "base/big_endian.h"
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -233,7 +234,7 @@ class TestHistoryBackendDelegate : public HistoryBackend::Delegate {
class TestHistoryBackend : public HistoryBackend {
public:
TestHistoryBackend()
- : HistoryBackend(new TestHistoryBackendDelegate(),
+ : HistoryBackend(std::make_unique<TestHistoryBackendDelegate>(),
nullptr,
base::ThreadTaskRunnerHandle::Get()) {}
diff --git a/chromium/components/history/core/browser/visit_database.cc b/chromium/components/history/core/browser/visit_database.cc
index 8b4712cdbbc..81859a9720b 100644
--- a/chromium/components/history/core/browser/visit_database.cc
+++ b/chromium/components/history/core/browser/visit_database.cc
@@ -605,7 +605,7 @@ void VisitDatabase::GetVisitsSource(const VisitVector& visits,
for (size_t j = start_index; j < end_index; j++) {
if (j != start_index)
sql.push_back(',');
- sql.append(base::Int64ToString(visits[j].visit_id));
+ sql.append(base::NumberToString(visits[j].visit_id));
}
sql.append(") ORDER BY id");
sql::Statement statement(GetDB().GetUniqueStatement(sql.c_str()));
diff --git a/chromium/components/history/core/browser/web_history_service.cc b/chromium/components/history/core/browser/web_history_service.cc
index 21e8fa0a775..13b8ffb67ec 100644
--- a/chromium/components/history/core/browser/web_history_service.cc
+++ b/chromium/components/history/core/browser/web_history_service.cc
@@ -281,8 +281,9 @@ class RequestImpl : public WebHistoryService::Request {
// history server.
std::string ServerTimeString(base::Time time) {
if (time < base::Time::UnixEpoch())
- return base::Int64ToString(0);
- return base::Int64ToString((time - base::Time::UnixEpoch()).InMicroseconds());
+ return base::NumberToString(0);
+ return base::NumberToString(
+ (time - base::Time::UnixEpoch()).InMicroseconds());
}
// Returns a URL for querying the history server for a query specified by
@@ -313,8 +314,8 @@ GURL GetQueryUrl(const base::string16& text_query,
}
if (options.max_count) {
- url = net::AppendQueryParameter(
- url, "num", base::IntToString(options.max_count));
+ url = net::AppendQueryParameter(url, "num",
+ base::NumberToString(options.max_count));
}
if (!text_query.empty())
@@ -382,7 +383,7 @@ std::unique_ptr<base::DictionaryValue> WebHistoryService::ReadResponse(
std::unique_ptr<base::DictionaryValue> result;
if (request->GetResponseCode() == net::HTTP_OK) {
std::unique_ptr<base::Value> value =
- base::JSONReader::Read(request->GetResponseBody());
+ base::JSONReader::ReadDeprecated(request->GetResponseBody());
if (value && value->is_dict())
result.reset(static_cast<base::DictionaryValue*>(value.release()));
else
diff --git a/chromium/components/history/core/browser/web_history_service_unittest.cc b/chromium/components/history/core/browser/web_history_service_unittest.cc
index b61d71b069f..07e3f844bc1 100644
--- a/chromium/components/history/core/browser/web_history_service_unittest.cc
+++ b/chromium/components/history/core/browser/web_history_service_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/run_loop.h"
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 87053133e17..a55f68aed48 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
@@ -36,6 +36,8 @@ class WebStateTopSitesObserver
// Underlying TopSites instance, may be null during testing.
TopSites* top_sites_;
+ WEB_STATE_USER_DATA_KEY_DECL();
+
DISALLOW_COPY_AND_ASSIGN(WebStateTopSitesObserver);
};
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 9883b3eac08..7f44e6227a3 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
@@ -53,4 +53,6 @@ void WebStateTopSitesObserver::WebStateDestroyed(web::WebState* web_state) {
web_state->RemoveObserver(this);
}
+WEB_STATE_USER_DATA_KEY_IMPL(WebStateTopSitesObserver)
+
} // namespace history
diff --git a/chromium/components/image_fetcher/OWNERS b/chromium/components/image_fetcher/OWNERS
index e2501f147fd..860cdf7f5a9 100644
--- a/chromium/components/image_fetcher/OWNERS
+++ b/chromium/components/image_fetcher/OWNERS
@@ -1,5 +1,6 @@
fgorski@chromium.org
markusheintz@chromium.org
treib@chromium.org
+wylieb@chromium.org
# COMPONENT: Internals>Images
diff --git a/chromium/components/image_fetcher/core/BUILD.gn b/chromium/components/image_fetcher/core/BUILD.gn
index 68ab5dbae15..e13f0b74b1e 100644
--- a/chromium/components/image_fetcher/core/BUILD.gn
+++ b/chromium/components/image_fetcher/core/BUILD.gn
@@ -15,6 +15,7 @@ static_library("core") {
"image_data_fetcher.cc",
"image_data_fetcher.h",
"image_decoder.h",
+ "image_fetcher.cc",
"image_fetcher.h",
"image_fetcher_impl.cc",
"image_fetcher_impl.h",
diff --git a/chromium/components/image_fetcher/core/cache/BUILD.gn b/chromium/components/image_fetcher/core/cache/BUILD.gn
index acbb6e36606..cb231c6b36d 100644
--- a/chromium/components/image_fetcher/core/cache/BUILD.gn
+++ b/chromium/components/image_fetcher/core/cache/BUILD.gn
@@ -31,6 +31,7 @@ static_library("cache") {
source_set("cache_unit_tests") {
testonly = true
sources = [
+ "cached_image_fetcher_metrics_reporter_unittest.cc",
"image_cache_unittest.cc",
"image_data_store_disk_unittest.cc",
"image_metadata_store_leveldb_unittest.cc",
diff --git a/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.cc b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.cc
index 3524c62f5b0..9f301b0d0a1 100644
--- a/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.cc
+++ b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.cc
@@ -4,37 +4,110 @@
#include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h"
+#include "base/metrics/histogram.h"
#include "base/metrics/histogram_macros.h"
namespace image_fetcher {
+const char CachedImageFetcherMetricsReporter::
+ kCachedImageFetcherInternalUmaClientName[] = "Internal";
+
+namespace {
+
+// 10 seconds in milliseconds.
+const int kMaxReportTimeMs = 10 * 1000;
+
+constexpr char kEventsHistogram[] = "CachedImageFetcher.Events";
+constexpr char kImageLoadFromCacheHistogram[] =
+ "CachedImageFetcher.ImageLoadFromCacheTime";
+constexpr char kImageLoadFromCacheJavaHistogram[] =
+ "CachedImageFetcher.ImageLoadFromCacheTimeJava";
+constexpr char kTotalFetchFromNativeTimeJavaHistogram[] =
+ "CachedImageFetcher.ImageLoadFromNativeTimeJava";
+constexpr char kImageLoadFromNetworkHistogram[] =
+ "CachedImageFetcher.ImageLoadFromNetworkTime";
+constexpr char kImageLoadFromNetworkAfterCacheHitHistogram[] =
+ "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit";
+
+// Returns a raw pointer to a histogram which is owned
+base::HistogramBase* GetTimeHistogram(const std::string& histogram_name,
+ const std::string client_name) {
+ return base::LinearHistogram::FactoryTimeGet(
+ histogram_name + std::string(".") + client_name, base::TimeDelta(),
+ base::TimeDelta::FromMilliseconds(kMaxReportTimeMs),
+ /* one bucket every 20ms. */ kMaxReportTimeMs / 20,
+ base::Histogram::kUmaTargetedHistogramFlag);
+}
+
+} // namespace
+
// static
void CachedImageFetcherMetricsReporter::ReportEvent(
+ const std::string& client_name,
CachedImageFetcherEvent event) {
- UMA_HISTOGRAM_ENUMERATION("CachedImageFetcher.Events", event);
+ DCHECK(!client_name.empty());
+ UMA_HISTOGRAM_ENUMERATION(kEventsHistogram, event);
+ base::LinearHistogram::FactoryGet(
+ kEventsHistogram + std::string(".") + client_name, 0,
+ static_cast<int>(CachedImageFetcherEvent::kMaxValue),
+ static_cast<int>(CachedImageFetcherEvent::kMaxValue),
+ base::Histogram::kUmaTargetedHistogramFlag)
+ ->Add(static_cast<int>(event));
}
// static
void CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime(
+ const std::string& client_name,
base::Time start_time) {
+ DCHECK(!client_name.empty());
base::TimeDelta time_delta = base::Time::Now() - start_time;
- UMA_HISTOGRAM_TIMES("CachedImageFetcher.ImageLoadFromCacheTime", time_delta);
+ UMA_HISTOGRAM_TIMES(kImageLoadFromCacheHistogram, time_delta);
+ GetTimeHistogram(kImageLoadFromCacheHistogram, client_name)
+ ->Add(time_delta.InMilliseconds());
+}
+
+// static
+void CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTimeJava(
+ const std::string& client_name,
+ base::Time start_time) {
+ DCHECK(!client_name.empty());
+ base::TimeDelta time_delta = base::Time::Now() - start_time;
+ UMA_HISTOGRAM_TIMES(kImageLoadFromCacheJavaHistogram, time_delta);
+ GetTimeHistogram(kImageLoadFromCacheJavaHistogram, client_name)
+ ->Add(time_delta.InMilliseconds());
+}
+
+// static
+void CachedImageFetcherMetricsReporter::ReportTotalFetchFromNativeTimeJava(
+ const std::string& client_name,
+ base::Time start_time) {
+ DCHECK(!client_name.empty());
+ base::TimeDelta time_delta = base::Time::Now() - start_time;
+ UMA_HISTOGRAM_TIMES(kTotalFetchFromNativeTimeJavaHistogram, time_delta);
+ GetTimeHistogram(kTotalFetchFromNativeTimeJavaHistogram, client_name)
+ ->Add(time_delta.InMilliseconds());
}
// static
void CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime(
+ const std::string& client_name,
base::Time start_time) {
+ DCHECK(!client_name.empty());
base::TimeDelta time_delta = base::Time::Now() - start_time;
- UMA_HISTOGRAM_TIMES("CachedImageFetcher.ImageLoadFromNetworkTime",
- time_delta);
+ UMA_HISTOGRAM_TIMES(kImageLoadFromNetworkHistogram, time_delta);
+ GetTimeHistogram(kImageLoadFromNetworkHistogram, client_name)
+ ->Add(time_delta.InMilliseconds());
}
// static
void CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit(
+ const std::string& client_name,
base::Time start_time) {
+ DCHECK(!client_name.empty());
base::TimeDelta time_delta = base::Time::Now() - start_time;
- UMA_HISTOGRAM_TIMES("CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit",
- time_delta);
+ UMA_HISTOGRAM_TIMES(kImageLoadFromNetworkAfterCacheHitHistogram, time_delta);
+ GetTimeHistogram(kImageLoadFromNetworkAfterCacheHitHistogram, client_name)
+ ->Add(time_delta.InMilliseconds());
}
// static
diff --git a/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h
index 0717645ef35..edcba5c8ee6 100644
--- a/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h
+++ b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_IMAGE_FETCHER_CORE_CACHE_CACHED_IMAGE_FETCHER_METRICS_REPORTER_H_
#define COMPONENTS_IMAGE_FETCHER_CORE_CACHE_CACHED_IMAGE_FETCHER_METRICS_REPORTER_H_
+#include <string>
+
#include "base/time/time.h"
namespace image_fetcher {
@@ -30,18 +32,34 @@ enum class CachedImageFetcherEvent {
class CachedImageFetcherMetricsReporter {
public:
+ // For use in metrics that aren't client-specific.
+ static const char kCachedImageFetcherInternalUmaClientName[];
+
// Report cache events, used by CachedImageFetcher and composing classes.
- static void ReportEvent(CachedImageFetcherEvent event);
+ static void ReportEvent(const std::string& client_name,
+ CachedImageFetcherEvent event);
// Report the time it takes to load an image from the cache in native code.
- static void ReportImageLoadFromCacheTime(base::Time start_time);
+ static void ReportImageLoadFromCacheTime(const std::string& client_name,
+ base::Time start_time);
+
+ // Report the time it takes to load an image from the cache in java code.
+ static void ReportImageLoadFromCacheTimeJava(const std::string& client_name,
+ base::Time start_time);
+
+ // Report the time it takes to load an image from native code.
+ static void ReportTotalFetchFromNativeTimeJava(const std::string& client_name,
+ base::Time start_time);
// Report the time it takes to load an image from the network.
- static void ReportImageLoadFromNetworkTime(base::Time start_time);
+ static void ReportImageLoadFromNetworkTime(const std::string& client_name,
+ base::Time start_time);
// Report the time it takes to load an image from the network after a cache
// hit.
- static void ReportImageLoadFromNetworkAfterCacheHit(base::Time start_time);
+ static void ReportImageLoadFromNetworkAfterCacheHit(
+ const std::string& client_name,
+ base::Time start_time);
// Report the time between cache evictions.
static void ReportTimeSinceLastCacheLRUEviction(base::Time start_time);
diff --git a/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter_unittest.cc b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter_unittest.cc
new file mode 100644
index 00000000000..60d871bba23
--- /dev/null
+++ b/chromium/components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter_unittest.cc
@@ -0,0 +1,163 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/image_fetcher/core/cache/cached_image_fetcher_metrics_reporter.h"
+
+#include <string>
+
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace image_fetcher {
+
+namespace {
+
+const char kUmaClientName[] = "foo";
+const char kUmaClientNameOther[] = "bar";
+
+const char kCachedImageFetcherEventHistogramName[] =
+ "CachedImageFetcher.Events";
+const char kCacheLoadHistogramName[] =
+ "CachedImageFetcher.ImageLoadFromCacheTime";
+const char kCacheLoadHistogramNameJava[] =
+ "CachedImageFetcher.ImageLoadFromCacheTimeJava";
+constexpr char kTotalFetchFromNativeHistogramNameJava[] =
+ "CachedImageFetcher.ImageLoadFromNativeTimeJava";
+const char kNetworkLoadHistogramName[] =
+ "CachedImageFetcher.ImageLoadFromNetworkTime";
+const char kNetworkLoadAfterCacheHitHistogram[] =
+ "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit";
+const char kTimeSinceLastCacheLRUEviction[] =
+ "CachedImageFetcher.TimeSinceLastCacheLRUEviction";
+
+} // namespace
+
+class CachedImageFetcherMetricsReporterTest : public testing::Test {
+ public:
+ CachedImageFetcherMetricsReporterTest() {}
+ ~CachedImageFetcherMetricsReporterTest() override = default;
+
+ base::HistogramTester& histogram_tester() { return histogram_tester_; }
+
+ private:
+ base::HistogramTester histogram_tester_;
+
+ DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherMetricsReporterTest);
+};
+
+TEST_F(CachedImageFetcherMetricsReporterTest, TestReportEvent) {
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ kUmaClientName, CachedImageFetcherEvent::kCacheHit);
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ kUmaClientNameOther, CachedImageFetcherEvent::kCacheHit);
+ histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName,
+ CachedImageFetcherEvent::kCacheHit, 2);
+ histogram_tester().ExpectBucketCount(
+ std::string(kCachedImageFetcherEventHistogramName)
+ .append(".")
+ .append(kUmaClientName),
+ CachedImageFetcherEvent::kCacheHit, 1);
+ histogram_tester().ExpectBucketCount(
+ std::string(kCachedImageFetcherEventHistogramName)
+ .append(".")
+ .append(kUmaClientNameOther),
+ CachedImageFetcherEvent::kCacheHit, 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportImageLoadFromCacheTime) {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime(
+ kUmaClientName, base::Time());
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime(
+ kUmaClientNameOther, base::Time());
+ histogram_tester().ExpectTotalCount(kCacheLoadHistogramName, 2);
+ histogram_tester().ExpectTotalCount(
+ std::string(kCacheLoadHistogramName).append(".").append(kUmaClientName),
+ 1);
+ histogram_tester().ExpectTotalCount(std::string(kCacheLoadHistogramName)
+ .append(".")
+ .append(kUmaClientNameOther),
+ 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportImageLoadFromCacheTimeJava) {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTimeJava(
+ kUmaClientName, base::Time());
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTimeJava(
+ kUmaClientNameOther, base::Time());
+ histogram_tester().ExpectTotalCount(kCacheLoadHistogramNameJava, 2);
+ histogram_tester().ExpectTotalCount(std::string(kCacheLoadHistogramNameJava)
+ .append(".")
+ .append(kUmaClientName),
+ 1);
+ histogram_tester().ExpectTotalCount(std::string(kCacheLoadHistogramNameJava)
+ .append(".")
+ .append(kUmaClientNameOther),
+ 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportTotalFetchFromNativeTimeJava) {
+ CachedImageFetcherMetricsReporter::ReportTotalFetchFromNativeTimeJava(
+ kUmaClientName, base::Time());
+ CachedImageFetcherMetricsReporter::ReportTotalFetchFromNativeTimeJava(
+ kUmaClientNameOther, base::Time());
+ histogram_tester().ExpectTotalCount(kTotalFetchFromNativeHistogramNameJava,
+ 2);
+ histogram_tester().ExpectTotalCount(
+ std::string(kTotalFetchFromNativeHistogramNameJava)
+ .append(".")
+ .append(kUmaClientName),
+ 1);
+ histogram_tester().ExpectTotalCount(
+ std::string(kTotalFetchFromNativeHistogramNameJava)
+ .append(".")
+ .append(kUmaClientNameOther),
+ 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportImageLoadFromNetworkTime) {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime(
+ kUmaClientName, base::Time());
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime(
+ kUmaClientNameOther, base::Time());
+ histogram_tester().ExpectTotalCount(kNetworkLoadHistogramName, 2);
+ histogram_tester().ExpectTotalCount(
+ std::string(kNetworkLoadHistogramName).append(".").append(kUmaClientName),
+ 1);
+ histogram_tester().ExpectTotalCount(std::string(kNetworkLoadHistogramName)
+ .append(".")
+ .append(kUmaClientNameOther),
+ 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportImageLoadFromNetworkAfterCacheHit) {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit(
+ kUmaClientName, base::Time());
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit(
+ kUmaClientNameOther, base::Time());
+ histogram_tester().ExpectTotalCount(kNetworkLoadAfterCacheHitHistogram, 2);
+ histogram_tester().ExpectTotalCount(
+ std::string(kNetworkLoadAfterCacheHitHistogram)
+ .append(".")
+ .append(kUmaClientName),
+ 1);
+ histogram_tester().ExpectTotalCount(
+ std::string(kNetworkLoadAfterCacheHitHistogram)
+ .append(".")
+ .append(kUmaClientNameOther),
+ 1);
+}
+
+TEST_F(CachedImageFetcherMetricsReporterTest,
+ TestReportTimeSinceLastCacheLRUEviction) {
+ CachedImageFetcherMetricsReporter::ReportTimeSinceLastCacheLRUEviction(
+ base::Time());
+ histogram_tester().ExpectTotalCount(kTimeSinceLastCacheLRUEviction, 1);
+}
+
+} // namespace image_fetcher
diff --git a/chromium/components/image_fetcher/core/cache/image_cache.cc b/chromium/components/image_fetcher/core/cache/image_cache.cc
index 7a880a928e1..14c5babbbac 100644
--- a/chromium/components/image_fetcher/core/cache/image_cache.cc
+++ b/chromium/components/image_fetcher/core/cache/image_cache.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/sha1.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
@@ -137,6 +138,8 @@ void ImageCache::OnDependencyInitialized() {
// TODO(wylieb): Consider delaying eviction as new requests come in via
// separate weak pointers.
CachedImageFetcherMetricsReporter::ReportEvent(
+ CachedImageFetcherMetricsReporter::
+ kCachedImageFetcherInternalUmaClientName,
CachedImageFetcherEvent::kCacheStartupEvictionStarted);
// Once all the queued requests are taken care of, run eviction.
@@ -267,6 +270,8 @@ void ImageCache::ReconcileDataKeys(std::vector<std::string> metadata_keys,
}
CachedImageFetcherMetricsReporter::ReportEvent(
+ CachedImageFetcherMetricsReporter::
+ kCachedImageFetcherInternalUmaClientName,
CachedImageFetcherEvent::kCacheStartupEvictionFinished);
}
diff --git a/chromium/components/image_fetcher/core/cache/image_cache.h b/chromium/components/image_fetcher/core/cache/image_cache.h
index 43acaa8a419..f6e40172c2b 100644
--- a/chromium/components/image_fetcher/core/cache/image_cache.h
+++ b/chromium/components/image_fetcher/core/cache/image_cache.h
@@ -53,7 +53,7 @@ class ImageCache : public base::RefCounted<ImageCache> {
void DeleteImage(std::string url);
private:
- friend class ImageCacheTest;
+ friend class CachedImageFetcherImageCacheTest;
friend class base::RefCounted<ImageCache>;
~ImageCache();
diff --git a/chromium/components/image_fetcher/core/cache/image_cache_unittest.cc b/chromium/components/image_fetcher/core/cache/image_cache_unittest.cc
index 43c39ece4f6..4802da62eff 100644
--- a/chromium/components/image_fetcher/core/cache/image_cache_unittest.cc
+++ b/chromium/components/image_fetcher/core/cache/image_cache_unittest.cc
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
@@ -40,9 +41,9 @@ const int kOverMaxCacheSize = 65 * 1024 * 1024;
} // namespace
-class ImageCacheTest : public testing::Test {
+class CachedImageFetcherImageCacheTest : public testing::Test {
public:
- ImageCacheTest() {}
+ CachedImageFetcherImageCacheTest() {}
void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
@@ -174,15 +175,15 @@ class ImageCacheTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
base::HistogramTester histogram_tester_;
- DISALLOW_COPY_AND_ASSIGN(ImageCacheTest);
+ DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherImageCacheTest);
};
-TEST_F(ImageCacheTest, HashUrlToKeyTest) {
+TEST_F(CachedImageFetcherImageCacheTest, HashUrlToKeyTest) {
ASSERT_EQ(ImageCache::HashUrlToKey("foo"), ImageCache::HashUrlToKey("foo"));
ASSERT_NE(ImageCache::HashUrlToKey("foo"), ImageCache::HashUrlToKey("bar"));
}
-TEST_F(ImageCacheTest, SanityTest) {
+TEST_F(CachedImageFetcherImageCacheTest, SanityTest) {
CreateImageCache();
InitializeImageCache();
@@ -192,7 +193,8 @@ TEST_F(ImageCacheTest, SanityTest) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
image_cache()->DeleteImage(kImageUrl);
@@ -201,11 +203,12 @@ TEST_F(ImageCacheTest, SanityTest) {
EXPECT_CALL(*this, DataCallback(std::string()));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, SaveCallsInitialization) {
+TEST_F(CachedImageFetcherImageCacheTest, SaveCallsInitialization) {
CreateImageCache();
ASSERT_FALSE(IsCacheInitialized());
@@ -216,7 +219,7 @@ TEST_F(ImageCacheTest, SaveCallsInitialization) {
ASSERT_TRUE(IsCacheInitialized());
}
-TEST_F(ImageCacheTest, Save) {
+TEST_F(CachedImageFetcherImageCacheTest, Save) {
CreateImageCache();
InitializeImageCache();
@@ -226,11 +229,12 @@ TEST_F(ImageCacheTest, Save) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, Load) {
+TEST_F(CachedImageFetcherImageCacheTest, Load) {
PrepareImageCache();
auto metadata_before = GetMetadata(kImageUrlHashed);
@@ -238,7 +242,8 @@ TEST_F(ImageCacheTest, Load) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
db()->LoadCallback(true);
db()->UpdateCallback(true);
@@ -248,7 +253,7 @@ TEST_F(ImageCacheTest, Load) {
ASSERT_FALSE(IsMetadataEqual(metadata_before, metadata_after));
}
-TEST_F(ImageCacheTest, LoadReadOnly) {
+TEST_F(CachedImageFetcherImageCacheTest, LoadReadOnly) {
PrepareImageCache();
auto metadata_before = GetMetadata(kImageUrlHashed);
@@ -256,20 +261,22 @@ TEST_F(ImageCacheTest, LoadReadOnly) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
true, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
auto metadata_after = GetMetadata(kImageUrlHashed);
ASSERT_TRUE(IsMetadataEqual(metadata_before, metadata_after));
}
-TEST_F(ImageCacheTest, Delete) {
+TEST_F(CachedImageFetcherImageCacheTest, Delete) {
PrepareImageCache();
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
image_cache()->DeleteImage(kImageUrl);
@@ -278,11 +285,12 @@ TEST_F(ImageCacheTest, Delete) {
EXPECT_CALL(*this, DataCallback(std::string()));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, Eviction) {
+TEST_F(CachedImageFetcherImageCacheTest, Eviction) {
PrepareImageCache();
clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(7));
@@ -292,7 +300,8 @@ TEST_F(ImageCacheTest, Eviction) {
EXPECT_CALL(*this, DataCallback(std::string()));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
histogram_tester().ExpectBucketCount(
@@ -303,7 +312,7 @@ TEST_F(ImageCacheTest, Eviction) {
CachedImageFetcherEvent::kCacheStartupEvictionFinished, 1);
}
-TEST_F(ImageCacheTest, EvictionWhenFull) {
+TEST_F(CachedImageFetcherImageCacheTest, EvictionWhenFull) {
PrepareImageCache();
InjectMetadata(kImageUrl, kOverMaxCacheSize);
clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(6));
@@ -313,11 +322,12 @@ TEST_F(ImageCacheTest, EvictionWhenFull) {
EXPECT_CALL(*this, DataCallback(""));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, EvictionTooSoon) {
+TEST_F(CachedImageFetcherImageCacheTest, EvictionTooSoon) {
PrepareImageCache();
clock()->SetNow(clock()->Now() + base::TimeDelta::FromDays(6));
@@ -326,11 +336,12 @@ TEST_F(ImageCacheTest, EvictionTooSoon) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, EvictionWhenEvictionAlreadyPerformed) {
+TEST_F(CachedImageFetcherImageCacheTest, EvictionWhenEvictionAlreadyPerformed) {
PrepareImageCache();
prefs()->SetTime("cached_image_fetcher_last_startup_eviction_time",
@@ -341,11 +352,12 @@ TEST_F(ImageCacheTest, EvictionWhenEvictionAlreadyPerformed) {
EXPECT_CALL(*this, DataCallback(kImageData));
image_cache()->LoadImage(
false, kImageUrl,
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, Reconciliation) {
+TEST_F(CachedImageFetcherImageCacheTest, Reconciliation) {
CreateImageCache();
InitializeImageCache();
@@ -358,14 +370,15 @@ TEST_F(ImageCacheTest, Reconciliation) {
EXPECT_CALL(*this, DataCallback(std::string()));
image_cache()->LoadImage(
false, "foo",
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
// Metadata should be gone.
ASSERT_FALSE(IsMetadataPresent("bar"));
}
-TEST_F(ImageCacheTest, ReconciliationMismatchData) {
+TEST_F(CachedImageFetcherImageCacheTest, ReconciliationMismatchData) {
CreateImageCache();
InitializeImageCache();
@@ -379,11 +392,12 @@ TEST_F(ImageCacheTest, ReconciliationMismatchData) {
EXPECT_CALL(*this, DataCallback(std::string()));
image_cache()->LoadImage(
false, "bar",
- base::BindOnce(&ImageCacheTest::DataCallback, base::Unretained(this)));
+ base::BindOnce(&CachedImageFetcherImageCacheTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageCacheTest, ReconciliationMismatchMetadata) {
+TEST_F(CachedImageFetcherImageCacheTest, ReconciliationMismatchMetadata) {
CreateImageCache();
InitializeImageCache();
diff --git a/chromium/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc b/chromium/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc
index 26b13ceb335..cd18e10636b 100644
--- a/chromium/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc
+++ b/chromium/components/image_fetcher/core/cache/image_data_store_disk_unittest.cc
@@ -26,9 +26,9 @@ constexpr char kImageKey[] = "key";
constexpr char kImageData[] = "data";
} // namespace
-class ImageDataStoreDiskTest : public testing::Test {
+class CachedImageFetcherImageDataStoreDiskTest : public testing::Test {
public:
- ImageDataStoreDiskTest() {}
+ CachedImageFetcherImageDataStoreDiskTest() {}
void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
void CreateDataStore() {
@@ -39,8 +39,9 @@ class ImageDataStoreDiskTest : public testing::Test {
void InitializeDataStore() {
EXPECT_CALL(*this, OnInitialized());
- data_store()->Initialize(base::BindOnce(
- &ImageDataStoreDiskTest::OnInitialized, base::Unretained(this)));
+ data_store()->Initialize(
+ base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::OnInitialized,
+ base::Unretained(this)));
RunUntilIdle();
}
@@ -61,8 +62,9 @@ class ImageDataStoreDiskTest : public testing::Test {
void AssertDataPresent(const std::string& key, const std::string& data) {
EXPECT_CALL(*this, DataCallback(data));
data_store()->LoadImage(
- key, base::BindOnce(&ImageDataStoreDiskTest::DataCallback,
- base::Unretained(this)));
+ key,
+ base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::DataCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
@@ -90,10 +92,10 @@ class ImageDataStoreDiskTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
- DISALLOW_COPY_AND_ASSIGN(ImageDataStoreDiskTest);
+ DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherImageDataStoreDiskTest);
};
-TEST_F(ImageDataStoreDiskTest, SanityTest) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, SanityTest) {
CreateDataStore();
InitializeDataStore();
@@ -104,7 +106,7 @@ TEST_F(ImageDataStoreDiskTest, SanityTest) {
AssertDataPresent(kImageKey, "");
}
-TEST_F(ImageDataStoreDiskTest, Init) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, Init) {
CreateDataStore();
ASSERT_FALSE(data_store()->IsInitialized());
@@ -112,7 +114,7 @@ TEST_F(ImageDataStoreDiskTest, Init) {
ASSERT_TRUE(data_store()->IsInitialized());
}
-TEST_F(ImageDataStoreDiskTest, InitWithExistingDirectory) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, InitWithExistingDirectory) {
PrepareDataStore(/* initialize */ true);
// Recreating the data store shouldn't wipe the directory.
@@ -122,18 +124,18 @@ TEST_F(ImageDataStoreDiskTest, InitWithExistingDirectory) {
AssertDataPresent(kImageKey);
}
-TEST_F(ImageDataStoreDiskTest, SaveBeforeInit) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, SaveBeforeInit) {
PrepareDataStore(/* initialize */ false);
// No data should be present (empty string).
AssertDataPresent(kImageKey, "");
}
-TEST_F(ImageDataStoreDiskTest, Save) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, Save) {
PrepareDataStore(/* initialize */ true);
AssertDataPresent(kImageKey);
}
-TEST_F(ImageDataStoreDiskTest, DeleteBeforeInit) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, DeleteBeforeInit) {
PrepareDataStore(/* initialize */ false);
DeleteData(kImageKey);
@@ -143,7 +145,7 @@ TEST_F(ImageDataStoreDiskTest, DeleteBeforeInit) {
AssertDataPresent(kImageKey);
}
-TEST_F(ImageDataStoreDiskTest, Delete) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, Delete) {
PrepareDataStore(/* initialize */ true);
DeleteData(kImageKey);
@@ -152,35 +154,39 @@ TEST_F(ImageDataStoreDiskTest, Delete) {
AssertDataPresent(kImageKey, "");
}
-TEST_F(ImageDataStoreDiskTest, GetAllKeysBeforeInit) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, GetAllKeysBeforeInit) {
PrepareDataStore(/* initialize */ false);
// Should return empty vector even though there is a file present.
EXPECT_CALL(*this, KeysCallback(std::vector<std::string>()));
- data_store()->GetAllKeys(base::BindOnce(&ImageDataStoreDiskTest::KeysCallback,
- base::Unretained(this)));
+ data_store()->GetAllKeys(
+ base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::KeysCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageDataStoreDiskTest, GetAllKeys) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest, GetAllKeys) {
PrepareDataStore(/* initialize */ true);
// Should return empty vector even though there is a file present.
EXPECT_CALL(*this, KeysCallback(std::vector<std::string>({kImageKey})));
- data_store()->GetAllKeys(base::BindOnce(&ImageDataStoreDiskTest::KeysCallback,
- base::Unretained(this)));
+ data_store()->GetAllKeys(
+ base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::KeysCallback,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageDataStoreDiskTest, QueuedLoadIsServedBeforeDelete) {
+TEST_F(CachedImageFetcherImageDataStoreDiskTest,
+ QueuedLoadIsServedBeforeDelete) {
CreateDataStore();
InitializeDataStore();
SaveData(kImageKey);
EXPECT_CALL(*this, DataCallback(kImageData));
- data_store()->LoadImage(kImageKey,
- base::BindOnce(&ImageDataStoreDiskTest::DataCallback,
- base::Unretained(this)));
+ data_store()->LoadImage(
+ kImageKey,
+ base::BindOnce(&CachedImageFetcherImageDataStoreDiskTest::DataCallback,
+ base::Unretained(this)));
DeleteData(kImageKey);
RunUntilIdle();
diff --git a/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc b/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc
index db0d293cbe8..d9f438fba9b 100644
--- a/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc
+++ b/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb.cc
@@ -23,6 +23,12 @@ namespace image_fetcher {
namespace {
+leveldb::ReadOptions CreateReadOptions() {
+ leveldb::ReadOptions opts;
+ opts.fill_cache = false;
+ return opts;
+}
+
int64_t ToDatabaseTime(base::Time time) {
return time.since_origin().InMicroseconds();
}
@@ -143,7 +149,8 @@ void ImageMetadataStoreLevelDB::UpdateImageMetadata(const std::string& key) {
}
database_->LoadEntriesWithFilter(
- base::BindRepeating(&KeyMatcherFilter, key),
+ base::BindRepeating(&KeyMatcherFilter, key), CreateReadOptions(),
+ /* target_prefix */ "",
base::BindOnce(&ImageMetadataStoreLevelDB::UpdateImageMetadataImpl,
weak_ptr_factory_.GetWeakPtr()));
}
diff --git a/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc b/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc
index 9c474eb9993..d6971df1041 100644
--- a/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc
+++ b/chromium/components/image_fetcher/core/cache/image_metadata_store_leveldb_unittest.cc
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "components/image_fetcher/core/cache/image_store_types.h"
@@ -29,9 +30,9 @@ constexpr int kImageDataLength = 5;
} // namespace
-class ImageMetadataStoreLevelDBTest : public testing::Test {
+class CachedImageFetcherImageMetadataStoreLevelDBTest : public testing::Test {
public:
- ImageMetadataStoreLevelDBTest() : db_(nullptr) {}
+ CachedImageFetcherImageMetadataStoreLevelDBTest() : db_(nullptr) {}
void CreateDatabase() {
// Reset everything.
@@ -53,7 +54,8 @@ class ImageMetadataStoreLevelDBTest : public testing::Test {
void InitializeDatabase() {
EXPECT_CALL(*this, OnInitialized());
metadata_store()->Initialize(base::BindOnce(
- &ImageMetadataStoreLevelDBTest::OnInitialized, base::Unretained(this)));
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnInitialized,
+ base::Unretained(this)));
db()->InitCallback(true);
RunUntilIdle();
@@ -131,10 +133,10 @@ class ImageMetadataStoreLevelDBTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
- DISALLOW_COPY_AND_ASSIGN(ImageMetadataStoreLevelDBTest);
+ DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherImageMetadataStoreLevelDBTest);
};
-TEST_F(ImageMetadataStoreLevelDBTest, Initialize) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, Initialize) {
CreateDatabase();
EXPECT_FALSE(metadata_store()->IsInitialized());
@@ -142,7 +144,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, Initialize) {
EXPECT_TRUE(metadata_store()->IsInitialized());
}
-TEST_F(ImageMetadataStoreLevelDBTest, SaveBeforeInit) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, SaveBeforeInit) {
CreateDatabase();
EXPECT_FALSE(metadata_store()->IsInitialized());
// Start an image load before the database is initialized.
@@ -154,7 +156,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, SaveBeforeInit) {
ASSERT_FALSE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, Save) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, Save) {
CreateDatabase();
InitializeDatabase();
@@ -163,7 +165,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, Save) {
clock()->Now());
}
-TEST_F(ImageMetadataStoreLevelDBTest, DeleteBeforeInit) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, DeleteBeforeInit) {
PrepareDatabase(false);
metadata_store()->DeleteImageMetadata(kImageKey);
@@ -171,7 +173,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, DeleteBeforeInit) {
ASSERT_TRUE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, Delete) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, Delete) {
// Put some data in the database to start.
CreateDatabase();
InitializeDatabase();
@@ -185,7 +187,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, Delete) {
ASSERT_FALSE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, DeleteDifferentKey) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, DeleteDifferentKey) {
// Put some data in the database to start.
CreateDatabase();
InitializeDatabase();
@@ -199,7 +201,8 @@ TEST_F(ImageMetadataStoreLevelDBTest, DeleteDifferentKey) {
ASSERT_TRUE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataBeforeInit) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ UpdateImageMetadataBeforeInit) {
PrepareDatabase(false);
// Call should be ignored because the store isn't initialized.
@@ -211,7 +214,7 @@ TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataBeforeInit) {
clock()->Now());
}
-TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadata) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, UpdateImageMetadata) {
PrepareDatabase(true);
clock()->SetNow(base::Time() + base::TimeDelta::FromHours(1));
@@ -225,7 +228,8 @@ TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadata) {
clock()->Now());
}
-TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataNoHits) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ UpdateImageMetadataNoHits) {
PrepareDatabase(true);
metadata_store()->UpdateImageMetadata(kOtherImageKey);
@@ -237,7 +241,8 @@ TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataNoHits) {
clock()->Now());
}
-TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataLoadFailed) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ UpdateImageMetadataLoadFailed) {
PrepareDatabase(true);
metadata_store()->UpdateImageMetadata(kOtherImageKey);
@@ -248,17 +253,18 @@ TEST_F(ImageMetadataStoreLevelDBTest, UpdateImageMetadataLoadFailed) {
clock()->Now());
}
-TEST_F(ImageMetadataStoreLevelDBTest, GetAllKeysBeforeInit) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeysBeforeInit) {
PrepareDatabase(false);
// A GC call before the db is initialized should be ignore.
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>()));
metadata_store()->GetAllKeys(base::BindOnce(
- &ImageMetadataStoreLevelDBTest::OnKeysReturned, base::Unretained(this)));
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
RunUntilIdle();
}
-TEST_F(ImageMetadataStoreLevelDBTest, GetAllKeys) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeys) {
PrepareDatabase(true);
metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength);
@@ -267,72 +273,79 @@ TEST_F(ImageMetadataStoreLevelDBTest, GetAllKeys) {
*this,
OnKeysReturned(std::vector<std::string>({kImageKey, kOtherImageKey})));
metadata_store()->GetAllKeys(base::BindOnce(
- &ImageMetadataStoreLevelDBTest::OnKeysReturned, base::Unretained(this)));
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadKeysCallback(true);
}
-TEST_F(ImageMetadataStoreLevelDBTest, GetAllKeysLoadFailed) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetAllKeysLoadFailed) {
PrepareDatabase(true);
metadata_store()->SaveImageMetadata(kOtherImageKey, kImageDataLength);
// A GC call before the db is initialized should be ignore.
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>({})));
metadata_store()->GetAllKeys(base::BindOnce(
- &ImageMetadataStoreLevelDBTest::OnKeysReturned, base::Unretained(this)));
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadKeysCallback(false);
}
-TEST_F(ImageMetadataStoreLevelDBTest, GetEstimatedSize) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GetEstimatedSize) {
PrepareDatabase(true);
EXPECT_EQ(5, metadata_store()->GetEstimatedSize());
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectBeforeInit) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ GarbageCollectBeforeInit) {
PrepareDatabase(false);
// A GC call before the db is initialized should be ignore.
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>()));
RunGarbageCollection(
base::TimeDelta::FromHours(1), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)),
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)),
true, 0);
RunUntilIdle();
ASSERT_TRUE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollect) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GarbageCollect) {
PrepareDatabase(true);
// Calling GC with something to be collected.
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>({kImageKey})));
RunGarbageCollection(
base::TimeDelta::FromHours(1), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)));
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadCallback(true);
db()->UpdateCallback(true);
ASSERT_FALSE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectNoHits) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest, GarbageCollectNoHits) {
PrepareDatabase(true);
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>()));
// Run GC without moving the clock forward, should result in no hits.
RunGarbageCollection(
base::TimeDelta::FromHours(0), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)));
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadCallback(true);
db()->UpdateCallback(true);
ASSERT_TRUE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectWithBytesProvided) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ GarbageCollectWithBytesProvided) {
PrepareDatabase(true);
// Insert an item one our later.
@@ -348,8 +361,9 @@ TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectWithBytesProvided) {
// entry should be gc'd kImageKey, the other should stay kOtherImageKey.
RunGarbageCollection(
base::TimeDelta::FromHours(1), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)),
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)),
true, 5);
db()->LoadCallback(true);
db()->UpdateCallback(true);
@@ -357,7 +371,8 @@ TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectWithBytesProvided) {
ASSERT_FALSE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectNoHitsButBytesProvided) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ GarbageCollectNoHitsButBytesProvided) {
PrepareDatabase(true);
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>({kImageKey})));
@@ -365,8 +380,9 @@ TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectNoHitsButBytesProvided) {
// Run GC with a byte limit of 0, everything should go.
RunGarbageCollection(
base::TimeDelta::FromHours(0), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)),
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)),
true, 0);
db()->LoadCallback(true);
db()->UpdateCallback(true);
@@ -374,26 +390,30 @@ TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectNoHitsButBytesProvided) {
ASSERT_FALSE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectLoadFailed) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ GarbageCollectLoadFailed) {
PrepareDatabase(true);
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>()));
// Run GC but loading the entries failed, should return an empty list.
RunGarbageCollection(
base::TimeDelta::FromHours(1), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)));
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadCallback(false);
ASSERT_TRUE(IsDataPresent(kImageKey));
}
-TEST_F(ImageMetadataStoreLevelDBTest, GarbageCollectUpdateFailed) {
+TEST_F(CachedImageFetcherImageMetadataStoreLevelDBTest,
+ GarbageCollectUpdateFailed) {
PrepareDatabase(true);
EXPECT_CALL(*this, OnKeysReturned(std::vector<std::string>()));
RunGarbageCollection(
base::TimeDelta::FromHours(1), base::TimeDelta::FromHours(1),
- base::BindOnce(&ImageMetadataStoreLevelDBTest::OnKeysReturned,
- base::Unretained(this)));
+ base::BindOnce(
+ &CachedImageFetcherImageMetadataStoreLevelDBTest::OnKeysReturned,
+ base::Unretained(this)));
db()->LoadCallback(true);
db()->UpdateCallback(false);
// Update failed only simlulates the callback, not the actual data behavior.
diff --git a/chromium/components/image_fetcher/core/cached_image_fetcher.cc b/chromium/components/image_fetcher/core/cached_image_fetcher.cc
index b6a5ddf6ec3..1c7b123f433 100644
--- a/chromium/components/image_fetcher/core/cached_image_fetcher.cc
+++ b/chromium/components/image_fetcher/core/cached_image_fetcher.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
@@ -25,17 +26,7 @@ struct CachedImageFetcherRequest {
// The url to be fetched.
const GURL url;
- // An identifier passed back to the caller.
- const std::string id;
-
- // The desired frame size if there are multiple frames to choose from.
- const gfx::Size desired_frame_size;
-
- // The service to track data usage for.
- const DataUseServiceName data_use_service_name;
-
- // Limit the number of bytes to download for the image.
- const base::Optional<int64_t> image_download_limit_bytes;
+ const ImageFetcherParams params;
// Analytic events below.
@@ -58,23 +49,29 @@ void DataCallbackIfPresent(ImageDataFetcherCallback data_callback,
}
void ImageCallbackIfPresent(ImageFetcherCallback image_callback,
- const std::string& id,
const gfx::Image& image,
const image_fetcher::RequestMetadata& metadata) {
if (image_callback.is_null()) {
return;
}
- std::move(image_callback).Run(id, image, metadata);
+ std::move(image_callback).Run(image, metadata);
}
-std::string EncodeSkBitmapToPNG(const SkBitmap& bitmap) {
+std::string EncodeSkBitmapToPNG(const std::string& uma_client_name,
+ const SkBitmap& bitmap) {
std::vector<unsigned char> encoded_data;
bool result = gfx::PNGCodec::Encode(
static_cast<const unsigned char*>(bitmap.getPixels()),
gfx::PNGCodec::FORMAT_RGBA, gfx::Size(bitmap.width(), bitmap.height()),
static_cast<int>(bitmap.rowBytes()), /* discard_transparency */ false,
std::vector<gfx::PNGCodec::Comment>(), &encoded_data);
- return result ? std::string(encoded_data.begin(), encoded_data.end()) : "";
+ if (!result) {
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ uma_client_name, CachedImageFetcherEvent::kTranscodingError);
+ return "";
+ } else {
+ return std::string(encoded_data.begin(), encoded_data.end());
+ }
}
} // namespace
@@ -93,187 +90,196 @@ CachedImageFetcher::CachedImageFetcher(
CachedImageFetcher::~CachedImageFetcher() = default;
-void CachedImageFetcher::SetDataUseServiceName(
- DataUseServiceName data_use_service_name) {
- data_use_service_name_ = data_use_service_name;
-}
-
-void CachedImageFetcher::SetDesiredImageFrameSize(const gfx::Size& size) {
- desired_frame_size_ = size;
-}
-
-void CachedImageFetcher::SetImageDownloadLimit(
- base::Optional<int64_t> max_download_bytes) {
- image_download_limit_bytes_ = max_download_bytes;
-}
-
ImageDecoder* CachedImageFetcher::GetImageDecoder() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return image_fetcher_->GetImageDecoder();
}
void CachedImageFetcher::FetchImageAndData(
- const std::string& id,
const GURL& image_url,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) {
+ ImageFetcherParams params) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(wylieb): Inject a clock for better testability.
CachedImageFetcherRequest request = {
- image_url,
- id,
- desired_frame_size_,
- data_use_service_name_,
- image_download_limit_bytes_,
+ image_url, std::move(params),
/* cache_hit_before_network_request */ false,
/* start_time */ base::Time::Now()};
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ request.params.uma_client_name(), CachedImageFetcherEvent::kImageRequest);
+
// First, try to load the image from the cache, then try the network.
image_cache_->LoadImage(
read_only_, image_url.spec(),
base::BindOnce(&CachedImageFetcher::OnImageFetchedFromCache,
weak_ptr_factory_.GetWeakPtr(), std::move(request),
- traffic_annotation, std::move(image_data_callback),
+ std::move(image_data_callback),
std::move(image_callback)));
-
- CachedImageFetcherMetricsReporter::ReportEvent(
- CachedImageFetcherEvent::kImageRequest);
}
void CachedImageFetcher::OnImageFetchedFromCache(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
std::string image_data) {
if (image_data.empty()) {
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ request.params.uma_client_name(), CachedImageFetcherEvent::kCacheMiss);
+
// Fetching from the DB failed, start a network fetch.
- EnqueueFetchImageFromNetwork(std::move(request), traffic_annotation,
+ EnqueueFetchImageFromNetwork(std::move(request),
std::move(image_data_callback),
std::move(image_callback));
-
- CachedImageFetcherMetricsReporter::ReportEvent(
- CachedImageFetcherEvent::kCacheMiss);
} else {
DataCallbackIfPresent(std::move(image_data_callback), image_data,
RequestMetadata());
- GetImageDecoder()->DecodeImage(
- image_data,
- /* The frame size had already been chosen during fetch. */ gfx::Size(),
- base::BindRepeating(
- &CachedImageFetcher::OnImageDecodedFromCache,
- weak_ptr_factory_.GetWeakPtr(), std::move(request),
- traffic_annotation, base::Passed(std::move(image_data_callback)),
- base::Passed(std::move(image_callback)), image_data));
CachedImageFetcherMetricsReporter::ReportEvent(
- CachedImageFetcherEvent::kCacheHit);
+ request.params.uma_client_name(), CachedImageFetcherEvent::kCacheHit);
+
+ // Only continue with decoding if the user actually asked for an image.
+ if (!image_callback.is_null()) {
+ GetImageDecoder()->DecodeImage(
+ image_data, gfx::Size(),
+ base::BindRepeating(&CachedImageFetcher::OnImageDecodedFromCache,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::move(request),
+ base::Passed(std::move(image_data_callback)),
+ base::Passed(std::move(image_callback))));
+ }
}
}
void CachedImageFetcher::OnImageDecodedFromCache(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
- const std::string& image_data,
const gfx::Image& image) {
if (image.IsEmpty()) {
// Upon failure, fetch from the network.
request.cache_hit_before_network_request = true;
- EnqueueFetchImageFromNetwork(std::move(request), traffic_annotation,
+ EnqueueFetchImageFromNetwork(std::move(request),
std::move(image_data_callback),
std::move(image_callback));
CachedImageFetcherMetricsReporter::ReportEvent(
+ request.params.uma_client_name(),
CachedImageFetcherEvent::kCacheDecodingError);
} else {
- ImageCallbackIfPresent(std::move(image_callback), request.id, image,
- RequestMetadata());
+ ImageCallbackIfPresent(std::move(image_callback), image, RequestMetadata());
CachedImageFetcherMetricsReporter::ReportImageLoadFromCacheTime(
- request.start_time);
+ request.params.uma_client_name(), request.start_time);
}
}
void CachedImageFetcher::EnqueueFetchImageFromNetwork(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&CachedImageFetcher::FetchImageFromNetwork,
weak_ptr_factory_.GetWeakPtr(), std::move(request),
- traffic_annotation, std::move(image_data_callback),
+ std::move(image_data_callback),
std::move(image_callback)));
}
void CachedImageFetcher::FetchImageFromNetwork(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback) {
- std::string id = request.id;
const GURL& url = request.url;
- // Fetch image data and the image itself. The image data will be stored in
- // the image cache, and the image will be returned to the caller.
- image_fetcher_->SetDesiredImageFrameSize(request.desired_frame_size);
- image_fetcher_->SetDataUseServiceName(request.data_use_service_name);
- image_fetcher_->SetImageDownloadLimit(request.image_download_limit_bytes);
- image_fetcher_->FetchImageAndData(
- id, url, std::move(image_data_callback),
- base::BindOnce(&CachedImageFetcher::OnImageFetchedFromNetwork,
- weak_ptr_factory_.GetWeakPtr(), std::move(request),
- std::move(image_callback)),
- traffic_annotation);
+
+ ImageDataFetcherCallback wrapper_data_callback;
+ ImageFetcherCallback wrapper_image_callback;
+
+ bool skip_transcoding = request.params.skip_transcoding();
+ if (skip_transcoding) {
+ wrapper_data_callback =
+ base::BindOnce(&CachedImageFetcher::StoreImageDataWithoutTranscoding,
+ weak_ptr_factory_.GetWeakPtr(), std::move(request),
+ std::move(image_data_callback));
+ } else {
+ // Transcode the image when its downloaded from the network.
+ // 1. Download the data.
+ // 2. Decode the data to a gfx::Image in a utility process.
+ // 3. Encode the data as a PNG in the browser process using base::PostTask.
+ // 3. Cache the result.
+ wrapper_data_callback = std::move(image_data_callback);
+ wrapper_image_callback =
+ base::BindOnce(&CachedImageFetcher::StoreImageDataWithTranscoding,
+ weak_ptr_factory_.GetWeakPtr(), std::move(request),
+ std::move(image_callback));
+ }
+ image_fetcher_->FetchImageAndData(url, std::move(wrapper_data_callback),
+ std::move(wrapper_image_callback),
+ std::move(request.params));
}
-void CachedImageFetcher::OnImageFetchedFromNetwork(
+void CachedImageFetcher::StoreImageDataWithoutTranscoding(
+ CachedImageFetcherRequest request,
+ ImageDataFetcherCallback image_data_callback,
+ const std::string& image_data,
+ const RequestMetadata& request_metadata) {
+ DataCallbackIfPresent(std::move(image_data_callback), image_data,
+ request_metadata);
+
+ if (image_data.empty()) {
+ CachedImageFetcherMetricsReporter::ReportEvent(
+ request.params.uma_client_name(),
+ CachedImageFetcherEvent::kTotalFailure);
+ }
+
+ StoreData(std::move(request), image_data);
+}
+
+void CachedImageFetcher::StoreImageDataWithTranscoding(
CachedImageFetcherRequest request,
ImageFetcherCallback image_callback,
- const std::string& id,
const gfx::Image& image,
const RequestMetadata& request_metadata) {
- // The image has been deocded by the fetcher already, return straight to the
- // caller.
- ImageCallbackIfPresent(std::move(image_callback), request.id, image,
- request_metadata);
+ ImageCallbackIfPresent(std::move(image_callback), image, request_metadata);
+
+ // Report to different histograms depending upon if there was a cache hit.
+ if (request.cache_hit_before_network_request) {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit(
+ request.params.uma_client_name(), request.start_time);
+ } else {
+ CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime(
+ request.params.uma_client_name(), request.start_time);
+ }
// Copy the image data out and store it on disk.
const SkBitmap* bitmap = image.IsEmpty() ? nullptr : image.ToSkBitmap();
// If the bitmap is null or otherwise not ready, skip encoding.
if (bitmap == nullptr || bitmap->isNull() || !bitmap->readyToDraw()) {
- StoreEncodedData(request.url, "");
CachedImageFetcherMetricsReporter::ReportEvent(
+ request.params.uma_client_name(),
CachedImageFetcherEvent::kTotalFailure);
+ StoreData(std::move(request), "");
} else {
+ std::string uma_client_name = request.params.uma_client_name();
// Post a task to another thread to encode the image data downloaded.
base::PostTaskAndReplyWithResult(
- FROM_HERE, base::BindOnce(&EncodeSkBitmapToPNG, *bitmap),
- base::BindOnce(&CachedImageFetcher::StoreEncodedData,
- weak_ptr_factory_.GetWeakPtr(), request.url));
- }
-
- // Report to different histograms depending upon if there was a cache hit.
- if (request.cache_hit_before_network_request) {
- CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkAfterCacheHit(
- request.start_time);
- } else {
- CachedImageFetcherMetricsReporter::ReportImageLoadFromNetworkTime(
- request.start_time);
+ FROM_HERE,
+ base::BindOnce(&EncodeSkBitmapToPNG, uma_client_name, *bitmap),
+ base::BindOnce(&CachedImageFetcher::StoreData,
+ weak_ptr_factory_.GetWeakPtr(), std::move(request)));
}
}
-void CachedImageFetcher::StoreEncodedData(const GURL& url,
- std::string image_data) {
+void CachedImageFetcher::StoreData(CachedImageFetcherRequest request,
+ std::string image_data) {
+ std::string url = request.url.spec();
// If the image is empty, delete the image.
if (image_data.empty()) {
- CachedImageFetcherMetricsReporter::ReportEvent(
- CachedImageFetcherEvent::kTranscodingError);
- image_cache_->DeleteImage(url.spec());
+ image_cache_->DeleteImage(std::move(url));
return;
}
if (!read_only_) {
- image_cache_->SaveImage(url.spec(), std::move(image_data));
+ image_cache_->SaveImage(std::move(url), std::move(image_data));
}
}
diff --git a/chromium/components/image_fetcher/core/cached_image_fetcher.h b/chromium/components/image_fetcher/core/cached_image_fetcher.h
index f40f574c621..3b66032a31a 100644
--- a/chromium/components/image_fetcher/core/cached_image_fetcher.h
+++ b/chromium/components/image_fetcher/core/cached_image_fetcher.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/image_fetcher_types.h"
@@ -37,51 +38,44 @@ class CachedImageFetcher : public ImageFetcher {
~CachedImageFetcher() override;
// ImageFetcher:
- void SetDataUseServiceName(DataUseServiceName data_use_service_name) override;
- void SetDesiredImageFrameSize(const gfx::Size& size) override;
- void SetImageDownloadLimit(
- base::Optional<int64_t> max_download_bytes) override;
- void FetchImageAndData(
- const std::string& id,
- const GURL& image_url,
- ImageDataFetcherCallback image_data_callback,
- ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) override;
+ void FetchImageAndData(const GURL& image_url,
+ ImageDataFetcherCallback image_data_callback,
+ ImageFetcherCallback image_callback,
+ ImageFetcherParams params) override;
ImageDecoder* GetImageDecoder() override;
private:
// Cache
void OnImageFetchedFromCache(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
std::string image_data);
void OnImageDecodedFromCache(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
- const std::string& image_data,
const gfx::Image& image);
// Network
void EnqueueFetchImageFromNetwork(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback);
void FetchImageFromNetwork(
CachedImageFetcherRequest request,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback);
- void OnImageFetchedFromNetwork(CachedImageFetcherRequest request,
- ImageFetcherCallback image_callback,
- const std::string& id,
- const gfx::Image& image,
- const RequestMetadata& request_metadata);
- void StoreEncodedData(const GURL& url, std::string image_data);
+ void StoreImageDataWithoutTranscoding(
+ CachedImageFetcherRequest request,
+ ImageDataFetcherCallback image_data_callback,
+ const std::string& image_data,
+ const RequestMetadata& request_metadata);
+ void StoreImageDataWithTranscoding(CachedImageFetcherRequest request,
+ ImageFetcherCallback image_data_callback,
+ const gfx::Image& image,
+ const RequestMetadata& request_metadata);
+ void StoreData(CachedImageFetcherRequest request, std::string image_data);
// Whether the ImageChache is allowed to be modified in any way from requests
// made by this CachedImageFetcher. This includes updating last used times,
@@ -95,10 +89,9 @@ class CachedImageFetcher : public ImageFetcher {
// When true, operations won't affect the longeivity of valid cache items.
bool read_only_;
- // Capture parameters when ImageFetcher Set* methods are called.
- gfx::Size desired_frame_size_;
- DataUseServiceName data_use_service_name_;
- base::Optional<int64_t> image_download_limit_bytes_;
+ // Used to ensure that operations are performed on the sequence that this
+ // object was created on.
+ SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<CachedImageFetcher> weak_ptr_factory_;
diff --git a/chromium/components/image_fetcher/core/cached_image_fetcher_service.cc b/chromium/components/image_fetcher/core/cached_image_fetcher_service.cc
index f6dc1e7538b..d6fd84f1664 100644
--- a/chromium/components/image_fetcher/core/cached_image_fetcher_service.cc
+++ b/chromium/components/image_fetcher/core/cached_image_fetcher_service.cc
@@ -10,30 +10,28 @@
#include "components/image_fetcher/core/cache/image_cache.h"
#include "components/image_fetcher/core/cached_image_fetcher.h"
#include "components/image_fetcher/core/image_decoder.h"
+#include "components/image_fetcher/core/image_fetcher.h"
#include "components/image_fetcher/core/image_fetcher_impl.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace image_fetcher {
CachedImageFetcherService::CachedImageFetcherService(
- CreateImageDecoderCallback create_image_decoder_fn,
+ std::unique_ptr<ImageDecoder> image_decoder,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
scoped_refptr<ImageCache> image_cache,
bool read_only)
- : create_image_decoder_callback_(create_image_decoder_fn),
- url_loader_factory_(url_loader_factory),
- image_cache_(image_cache),
- read_only_(read_only) {}
+ : cached_image_fetcher_(std::make_unique<CachedImageFetcher>(
+ std::make_unique<ImageFetcherImpl>(std::move(image_decoder),
+ url_loader_factory),
+ image_cache,
+ read_only)),
+ image_cache_(image_cache) {}
CachedImageFetcherService::~CachedImageFetcherService() = default;
-// TODO(wylieb): Store CachedImageFetcher once it's stateless.
-std::unique_ptr<CachedImageFetcher>
-CachedImageFetcherService::CreateCachedImageFetcher() {
- return std::make_unique<CachedImageFetcher>(
- std::make_unique<ImageFetcherImpl>(create_image_decoder_callback_.Run(),
- url_loader_factory_),
- image_cache_, read_only_);
+ImageFetcher* CachedImageFetcherService::GetCachedImageFetcher() {
+ return cached_image_fetcher_.get();
}
scoped_refptr<ImageCache> CachedImageFetcherService::ImageCacheForTesting()
diff --git a/chromium/components/image_fetcher/core/cached_image_fetcher_service.h b/chromium/components/image_fetcher/core/cached_image_fetcher_service.h
index 059cef21718..510d145bf84 100644
--- a/chromium/components/image_fetcher/core/cached_image_fetcher_service.h
+++ b/chromium/components/image_fetcher/core/cached_image_fetcher_service.h
@@ -18,38 +18,31 @@ class SharedURLLoaderFactory;
namespace image_fetcher {
-class CachedImageFetcher;
+class ImageFetcher;
class ImageCache;
class ImageDecoder;
-using CreateImageDecoderCallback =
- base::RepeatingCallback<std::unique_ptr<ImageDecoder>()>;
-
// Keyed service responsible for managing the lifetime of CachedImageFetcher.
// Persists the ImageCache, and uses it to create instances of the
// CachedImageFethcer.
class CachedImageFetcherService : public KeyedService {
public:
explicit CachedImageFetcherService(
- CreateImageDecoderCallback create_image_decoder_callback,
+ std::unique_ptr<ImageDecoder> image_decoder,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
scoped_refptr<ImageCache> image_cache,
bool read_only);
~CachedImageFetcherService() override;
// Create an instance of CachedImageFetcher based on the ImageCache.
- std::unique_ptr<CachedImageFetcher> CreateCachedImageFetcher();
+ ImageFetcher* GetCachedImageFetcher();
scoped_refptr<ImageCache> ImageCacheForTesting() const;
private:
- CreateImageDecoderCallback create_image_decoder_callback_;
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- scoped_refptr<ImageCache> image_cache_;
+ std::unique_ptr<ImageFetcher> cached_image_fetcher_;
- // If true, the CachedImageFetcher will be started in read-only mode. Read-
- // only mode doesn't perform write operations on the cache.
- bool read_only_;
+ scoped_refptr<ImageCache> image_cache_;
DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherService);
};
diff --git a/chromium/components/image_fetcher/core/cached_image_fetcher_unittest.cc b/chromium/components/image_fetcher/core/cached_image_fetcher_unittest.cc
index fec79d67e24..f45400f23d4 100644
--- a/chromium/components/image_fetcher/core/cached_image_fetcher_unittest.cc
+++ b/chromium/components/image_fetcher/core/cached_image_fetcher_unittest.cc
@@ -47,6 +47,8 @@ class FakeImageDecoder;
namespace {
const GURL kImageUrl = GURL("http://gstatic.img.com/foo.jpg");
+
+constexpr char kUmaClientName[] = "TestUma";
constexpr char kImageData[] = "data";
const char kCachedImageFetcherEventHistogramName[] =
@@ -55,16 +57,14 @@ const char kCacheLoadHistogramName[] =
"CachedImageFetcher.ImageLoadFromCacheTime";
const char kNetworkLoadHistogramName[] =
"CachedImageFetcher.ImageLoadFromNetworkTime";
-const char kNetworkLoadAfterCacheHitHistogram[] =
- "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit";
} // namespace
-class ComponentizedCachedImageFetcherTest : public testing::Test {
+class CachedImageFetcherTest : public testing::Test {
public:
- ComponentizedCachedImageFetcherTest() {}
+ CachedImageFetcherTest() {}
- ~ComponentizedCachedImageFetcherTest() override {
+ ~CachedImageFetcherTest() override {
cached_image_fetcher_.reset();
// We need to run until idle after deleting the database, because
// ProtoDatabase deletes the actual LevelDB asynchronously.
@@ -143,7 +143,7 @@ class ComponentizedCachedImageFetcherTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
base::HistogramTester histogram_tester_;
- DISALLOW_COPY_AND_ASSIGN(ComponentizedCachedImageFetcherTest);
+ DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherTest);
};
MATCHER(EmptyImage, "") {
@@ -160,9 +160,7 @@ MATCHER(NonEmptyString, "") {
// TODO(wylieb): Write a test that creates two CachedImageFetcher and tests
// that they both can use what's inside.
-// TODO(wylieb): Rename these tests CachedImageFetcherTest* when ntp_snippets/-
-// remote/cached_image_fetcher has been migrated.
-TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCache) {
+TEST_F(CachedImageFetcherTest, FetchImageFromCache) {
// Save the image in the database.
image_cache()->SaveImage(kImageUrl.spec(), kImageData);
RunUntilIdle();
@@ -171,10 +169,10 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCache) {
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), NonEmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(NonEmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
@@ -186,7 +184,7 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCache) {
CachedImageFetcherEvent::kCacheHit, 1);
}
-TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCacheReadOnly) {
+TEST_F(CachedImageFetcherTest, FetchImageFromCacheReadOnly) {
CreateCachedImageFetcher(/* read_only */ true);
// Save the image in the database.
image_cache()->SaveImage(kImageUrl.spec(), kImageData);
@@ -198,10 +196,10 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCacheReadOnly) {
image_decoder()->SetDecodingValid(false);
base::MockCallback<ImageDataFetcherCallback> data_callback;
base::MockCallback<ImageFetcherCallback> image_callback;
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), EmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(EmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName,
@@ -218,15 +216,15 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImageFromCacheReadOnly) {
image_decoder()->SetDecodingValid(true);
base::MockCallback<ImageDataFetcherCallback> data_callback;
base::MockCallback<ImageFetcherCallback> image_callback;
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), NonEmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(NonEmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
}
}
-TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCache) {
+TEST_F(CachedImageFetcherTest, FetchImagePopulatesCache) {
// Expect the image to be fetched by URL.
{
test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData);
@@ -235,10 +233,10 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCache) {
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(NonEmptyString(), _));
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), NonEmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(NonEmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
@@ -255,7 +253,7 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCache) {
EXPECT_CALL(*this, OnImageLoaded(NonEmptyString()));
image_cache()->LoadImage(
/* read_only */ false, kImageUrl.spec(),
- base::BindOnce(&ComponentizedCachedImageFetcherTest::OnImageLoaded,
+ base::BindOnce(&CachedImageFetcherTest::OnImageLoaded,
base::Unretained(this)));
RunUntilIdle();
}
@@ -267,16 +265,16 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCache) {
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(NonEmptyString(), _));
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), NonEmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(NonEmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
}
}
-TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCacheReadOnly) {
+TEST_F(CachedImageFetcherTest, FetchImagePopulatesCacheReadOnly) {
CreateCachedImageFetcher(/* read_only */ true);
// Expect the image to be fetched by URL.
{
@@ -286,10 +284,10 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCacheReadOnly) {
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(NonEmptyString(), _));
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), NonEmptyImage(), _));
+ EXPECT_CALL(image_callback, Run(NonEmptyImage(), _));
cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ kImageUrl, data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
RunUntilIdle();
@@ -306,32 +304,37 @@ TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCacheReadOnly) {
EXPECT_CALL(*this, OnImageLoaded(std::string()));
image_cache()->LoadImage(
/* read_only */ false, kImageUrl.spec(),
- base::BindOnce(&ComponentizedCachedImageFetcherTest::OnImageLoaded,
+ base::BindOnce(&CachedImageFetcherTest::OnImageLoaded,
base::Unretained(this)));
RunUntilIdle();
}
}
-TEST_F(ComponentizedCachedImageFetcherTest, FetchDecodingErrorDeletesCache) {
- // Save the image in the database.
- image_cache()->SaveImage(kImageUrl.spec(), kImageData);
- RunUntilIdle();
+TEST_F(CachedImageFetcherTest, FetchImageWithoutTranscodingDoesNotDecode) {
+ {
+ test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData);
+ image_decoder()->SetDecodingValid(false);
- image_decoder()->SetDecodingValid(false);
- base::MockCallback<ImageDataFetcherCallback> data_callback;
- base::MockCallback<ImageFetcherCallback> image_callback;
- EXPECT_CALL(data_callback, Run(NonEmptyString(), _));
- EXPECT_CALL(image_callback, Run(kImageUrl.spec(), EmptyImage(), _));
- test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData);
- cached_image_fetcher()->FetchImageAndData(
- kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- RunUntilIdle();
+ base::MockCallback<ImageDataFetcherCallback> data_callback;
+
+ EXPECT_CALL(data_callback, Run(kImageData, _));
+ ImageFetcherParams params(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName);
+ params.set_skip_transcoding_for_testing(true);
+ cached_image_fetcher()->FetchImageAndData(kImageUrl, data_callback.Get(),
+ ImageFetcherCallback(), params);
- histogram_tester().ExpectTotalCount(kNetworkLoadAfterCacheHitHistogram, 1);
- histogram_tester().ExpectBucketCount(
- kCachedImageFetcherEventHistogramName,
- CachedImageFetcherEvent::kTranscodingError, 1);
+ RunUntilIdle();
+ }
+ {
+ test_url_loader_factory()->ClearResponses();
+ base::MockCallback<ImageDataFetcherCallback> data_callback;
+ EXPECT_CALL(data_callback, Run(kImageData, _));
+ cached_image_fetcher()->FetchImageAndData(
+ kImageUrl, data_callback.Get(), ImageFetcherCallback(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kUmaClientName));
+
+ RunUntilIdle();
+ }
}
} // namespace image_fetcher
diff --git a/chromium/components/image_fetcher/core/image_data_fetcher.cc b/chromium/components/image_fetcher/core/image_data_fetcher.cc
index 0c36e848567..855058e51bc 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher.cc
+++ b/chromium/components/image_fetcher/core/image_data_fetcher.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
@@ -15,12 +16,12 @@
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
-using data_use_measurement::DataUseUserData;
-
namespace {
const char kContentLocationHeader[] = "Content-Location";
+const int kDownloadTimeoutSeconds = 30;
+
} // namespace
namespace image_fetcher {
@@ -43,8 +44,7 @@ struct ImageDataFetcher::ImageDataFetcherRequest {
ImageDataFetcher::ImageDataFetcher(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
- : url_loader_factory_(url_loader_factory),
- data_use_service_name_(DataUseUserData::IMAGE_FETCHER_UNTAGGED) {
+ : url_loader_factory_(url_loader_factory) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
@@ -52,12 +52,6 @@ ImageDataFetcher::~ImageDataFetcher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-void ImageDataFetcher::SetDataUseServiceName(
- DataUseServiceName data_use_service_name) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- data_use_service_name_ = data_use_service_name;
-}
-
void ImageDataFetcher::SetImageDownloadLimit(
base::Optional<int64_t> max_download_bytes) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -93,10 +87,6 @@ void ImageDataFetcher::FetchImageData(
net::LOAD_DO_NOT_SEND_AUTH_DATA;
}
- // TODO(https://crbug.com/808498) re-add data use measurement once
- // SimpleURLLoader supports it. Parameter:
- // data_use_service_name_
-
std::unique_ptr<network::SimpleURLLoader> loader =
network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
@@ -104,6 +94,9 @@ void ImageDataFetcher::FetchImageData(
// body will get thrown out anyway, though.
loader->SetAllowHttpErrorResults(true);
+ loader->SetTimeoutDuration(
+ base::TimeDelta::FromSeconds(kDownloadTimeoutSeconds));
+
if (max_download_bytes_.has_value()) {
loader->DownloadToString(
url_loader_factory_.get(),
diff --git a/chromium/components/image_fetcher/core/image_data_fetcher.h b/chromium/components/image_fetcher/core/image_data_fetcher.h
index 0daca9f1c38..f95ef10f50a 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher.h
+++ b/chromium/components/image_fetcher/core/image_data_fetcher.h
@@ -36,9 +36,6 @@ class ImageDataFetcher {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~ImageDataFetcher();
- // Sets a service name against which to track data usage.
- void SetDataUseServiceName(DataUseServiceName data_use_service_name);
-
// Sets an upper limit for image downloads.
// Already running downloads are not affected.
void SetImageDownloadLimit(base::Optional<int64_t> max_download_bytes);
@@ -84,8 +81,6 @@ class ImageDataFetcher {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- DataUseServiceName data_use_service_name_;
-
// Upper limit for the number of bytes to download per image.
base::Optional<int64_t> max_download_bytes_;
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 9a98b40ee39..5e9e29b61a6 100644
--- a/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc
+++ b/chromium/components/image_fetcher/core/image_data_fetcher_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/components/image_fetcher/core/image_fetcher.cc b/chromium/components/image_fetcher/core/image_fetcher.cc
new file mode 100644
index 00000000000..18f6dba7d1d
--- /dev/null
+++ b/chromium/components/image_fetcher/core/image_fetcher.cc
@@ -0,0 +1,23 @@
+// 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/image_fetcher/core/image_fetcher.h"
+
+namespace image_fetcher {
+
+ImageFetcherParams::ImageFetcherParams(
+ const net::NetworkTrafficAnnotationTag network_traffic_annotation_tag,
+ std::string uma_client_name)
+ : network_traffic_annotation_tag_(network_traffic_annotation_tag),
+ uma_client_name_(uma_client_name),
+ skip_transcoding_(false) {}
+
+ImageFetcherParams::ImageFetcherParams(const ImageFetcherParams& params) =
+ default;
+
+ImageFetcherParams::ImageFetcherParams(ImageFetcherParams&& params) = default;
+
+ImageFetcherParams::~ImageFetcherParams() = default;
+
+} // namespace image_fetcher \ No newline at end of file
diff --git a/chromium/components/image_fetcher/core/image_fetcher.h b/chromium/components/image_fetcher/core/image_fetcher.h
index 33fa25dc430..0e699f9149b 100644
--- a/chromium/components/image_fetcher/core/image_fetcher.h
+++ b/chromium/components/image_fetcher/core/image_fetcher.h
@@ -6,22 +6,91 @@
#define COMPONENTS_IMAGE_FETCHER_CORE_IMAGE_FETCHER_H_
#include <string>
+#include <utility>
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
+#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/image_fetcher/core/image_fetcher_types.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
-namespace gfx {
-class Size;
-} // namespace gfx
-
namespace image_fetcher {
class ImageDecoder;
+// Encapsulates image fetching customization options.
+// (required)
+// traffic_annotation
+// Documents what the network traffic is for, gives you free metrics.
+// max_download_size
+// Limits the size of the downloaded image.
+// frame_size
+// If multiple sizes of the image are available on the server, choose the one
+// that's closest to the given size (only useful for .icos). Does NOT resize
+// the downloaded image to the given dimensions.
+class ImageFetcherParams {
+ // Only allow the bridge to access the private function set_skip_transcoding
+ // used for gif download.
+ friend class CachedImageFetcherBridge;
+
+ public:
+ // Sets the UMA client name to report feature-specific metrics. Make sure
+ // |uma_client_name| is also present in histograms.xml.
+ ImageFetcherParams(
+ net::NetworkTrafficAnnotationTag network_traffic_annotation_tag,
+ std::string uma_client_name);
+ ImageFetcherParams(const ImageFetcherParams& params);
+ ImageFetcherParams(ImageFetcherParams&& params);
+
+ ~ImageFetcherParams();
+
+ const net::NetworkTrafficAnnotationTag traffic_annotation() const {
+ return network_traffic_annotation_tag_;
+ }
+
+ void set_max_download_size(base::Optional<int64_t> max_download_bytes) {
+ max_download_bytes_ = max_download_bytes;
+ }
+
+ base::Optional<int64_t> max_download_size() const {
+ return max_download_bytes_;
+ }
+
+ void set_frame_size(gfx::Size desired_frame_size) {
+ desired_frame_size_ = desired_frame_size;
+ }
+
+ gfx::Size frame_size() const { return desired_frame_size_; }
+
+ const std::string& uma_client_name() const { return uma_client_name_; }
+
+ bool skip_transcoding() const { return skip_transcoding_; }
+
+ // Only to be used in unittests.
+ void set_skip_transcoding_for_testing(bool skip_transcoding) {
+ skip_transcoding_ = skip_transcoding;
+ }
+
+ private:
+ void set_skip_transcoding(bool skip_transcoding) {
+ skip_transcoding_ = skip_transcoding;
+ }
+
+ const net::NetworkTrafficAnnotationTag network_traffic_annotation_tag_;
+
+ base::Optional<int64_t> max_download_bytes_;
+ gfx::Size desired_frame_size_;
+ std::string uma_client_name_;
+ // When true, the image fetcher will skip transcoding whenever possible. Only
+ // use this if you've considered the security implications. For instance, in
+ // some java clients we decode GIFs entirely in Java which is safe to do
+ // in-process without transcoding.
+ bool skip_transcoding_;
+};
+
// A class used to fetch server images. It can be called from any thread and the
// callback will be called on the thread which initiated the fetch.
class ImageFetcher {
@@ -29,57 +98,34 @@ class ImageFetcher {
ImageFetcher() {}
virtual ~ImageFetcher() {}
- // Sets a service name against which to track data usage.
- virtual void SetDataUseServiceName(
- DataUseServiceName data_use_service_name) = 0;
-
- // Sets an upper limit for image downloads that is by default disabled.
- // Setting |max_download_bytes| to a negative value will disable the limit.
- // Already running downloads are not affected.
- virtual void SetImageDownloadLimit(
- base::Optional<int64_t> max_download_bytes) = 0;
-
- // Sets the desired size for images with multiple frames (like .ico files).
- // By default, the image fetcher choses smaller images. Override to choose a
- // frame with a size as close as possible to |size| (trying to take one in
- // larger size if there's no precise match). Passing gfx::Size() as
- // |size| is also supported and will result in chosing the smallest available
- // size.
- virtual void SetDesiredImageFrameSize(const gfx::Size& size) = 0;
-
// Fetch an image and optionally decode it. |image_data_callback| is called
// when the image fetch completes, but |image_data_callback| may be empty.
// |image_callback| is called when the image is finished decoding.
// |image_callback| may be empty if image decoding is not required. If a
// callback is provided, it will be called exactly once. On failure, an empty
// string/gfx::Image is returned.
- virtual void FetchImageAndData(
- const std::string& id,
- const GURL& image_url,
- ImageDataFetcherCallback image_data_callback,
- ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) = 0;
+ virtual void FetchImageAndData(const GURL& image_url,
+ ImageDataFetcherCallback image_data_callback,
+ ImageFetcherCallback image_callback,
+ ImageFetcherParams params) = 0;
// Fetch an image and decode it. An empty gfx::Image will be returned to the
// callback in case the image could not be fetched. This is the same as
// calling FetchImageAndData without an |image_data_callback|.
- void FetchImage(const std::string& id,
- const GURL& image_url,
+ void FetchImage(const GURL& image_url,
ImageFetcherCallback callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) {
- FetchImageAndData(id, image_url, ImageDataFetcherCallback(),
- std::move(callback), traffic_annotation);
+ ImageFetcherParams params) {
+ FetchImageAndData(image_url, ImageDataFetcherCallback(),
+ std::move(callback), params);
}
// Just fetch the image data, do not decode. This is the same as
// calling FetchImageAndData without an |image_callback|.
- void FetchImageData(
- const std::string& id,
- const GURL& image_url,
- ImageDataFetcherCallback callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) {
- FetchImageAndData(id, image_url, std::move(callback),
- ImageFetcherCallback(), traffic_annotation);
+ void FetchImageData(const GURL& image_url,
+ ImageDataFetcherCallback callback,
+ ImageFetcherParams params) {
+ FetchImageAndData(image_url, std::move(callback), ImageFetcherCallback(),
+ params);
}
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 4a845a3245f..dd54f64c9ae 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_impl.cc
+++ b/chromium/components/image_fetcher/core/image_fetcher_impl.cc
@@ -28,32 +28,17 @@ ImageFetcherImpl::ImageRequest::ImageRequest(ImageRequest&& other) = default;
ImageFetcherImpl::ImageRequest::~ImageRequest() {}
-void ImageFetcherImpl::SetDataUseServiceName(
- DataUseServiceName data_use_service_name) {
- image_data_fetcher_->SetDataUseServiceName(data_use_service_name);
-}
-
-void ImageFetcherImpl::SetDesiredImageFrameSize(const gfx::Size& size) {
- desired_image_frame_size_ = size;
-}
-
-void ImageFetcherImpl::SetImageDownloadLimit(
- base::Optional<int64_t> max_download_bytes) {
- image_data_fetcher_->SetImageDownloadLimit(max_download_bytes);
-}
-
void ImageFetcherImpl::FetchImageAndData(
- const std::string& id,
const GURL& image_url,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) {
+ ImageFetcherParams params) {
// Before starting to fetch the image. Look for a request in progress for
// |image_url|, and queue if appropriate.
auto it = pending_net_requests_.find(image_url);
if (it == pending_net_requests_.end()) {
ImageRequest request;
- request.id = id;
+ request.id = image_url.spec();
if (image_callback) {
request.image_callbacks.push_back(std::move(image_callback));
}
@@ -62,11 +47,12 @@ void ImageFetcherImpl::FetchImageAndData(
}
pending_net_requests_.emplace(image_url, std::move(request));
+ image_data_fetcher_->SetImageDownloadLimit(params.max_download_size());
image_data_fetcher_->FetchImageData(
image_url,
base::BindOnce(&ImageFetcherImpl::OnImageURLFetched,
- base::Unretained(this), image_url),
- traffic_annotation);
+ base::Unretained(this), image_url, std::move(params)),
+ params.traffic_annotation());
} else {
ImageRequest* request = &it->second;
// Request in progress. Register as an interested callback.
@@ -91,6 +77,7 @@ void ImageFetcherImpl::FetchImageAndData(
}
void ImageFetcherImpl::OnImageURLFetched(const GURL& image_url,
+ ImageFetcherParams params,
const std::string& image_data,
const RequestMetadata& metadata) {
auto it = pending_net_requests_.find(image_url);
@@ -106,7 +93,7 @@ void ImageFetcherImpl::OnImageURLFetched(const GURL& image_url,
if (image_data.empty() || request->image_callbacks.empty()) {
for (auto& callback : request->image_callbacks) {
- std::move(callback).Run(request->id, gfx::Image(), metadata);
+ std::move(callback).Run(gfx::Image(), metadata);
}
pending_net_requests_.erase(it);
return;
@@ -114,7 +101,7 @@ void ImageFetcherImpl::OnImageURLFetched(const GURL& image_url,
request->image_data = image_data;
request->request_metadata = metadata;
image_decoder_->DecodeImage(
- image_data, desired_image_frame_size_,
+ image_data, params.frame_size(),
base::BindRepeating(&ImageFetcherImpl::OnImageDecoded,
base::Unretained(this), image_url, metadata));
}
@@ -129,7 +116,7 @@ void ImageFetcherImpl::OnImageDecoded(const GURL& image_url,
// Run all image callbacks.
for (auto& callback : request->image_callbacks) {
- std::move(callback).Run(request->id, image, metadata);
+ std::move(callback).Run(image, metadata);
}
// Erase the completed ImageRequest.
diff --git a/chromium/components/image_fetcher/core/image_fetcher_impl.h b/chromium/components/image_fetcher/core/image_fetcher_impl.h
index 0b7a2eb2af6..a63c15cb4b9 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_impl.h
+++ b/chromium/components/image_fetcher/core/image_fetcher_impl.h
@@ -38,20 +38,10 @@ class ImageFetcherImpl : public ImageFetcher {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~ImageFetcherImpl() override;
- // Sets a service name against which to track data usage.
- void SetDataUseServiceName(DataUseServiceName data_use_service_name) override;
-
- void SetDesiredImageFrameSize(const gfx::Size& size) override;
-
- void SetImageDownloadLimit(
- base::Optional<int64_t> max_download_bytes) override;
-
- void FetchImageAndData(
- const std::string& id,
- const GURL& image_url,
- ImageDataFetcherCallback image_data_callback,
- ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) override;
+ void FetchImageAndData(const GURL& image_url,
+ ImageDataFetcherCallback image_data_callback,
+ ImageFetcherCallback image_callback,
+ ImageFetcherParams params) override;
ImageDecoder* GetImageDecoder() override;
@@ -79,6 +69,7 @@ class ImageFetcherImpl : public ImageFetcher {
// Processes image URL fetched events. This is the continuation method used
// for creating callbacks that are passed to the ImageDataFetcher.
void OnImageURLFetched(const GURL& image_url,
+ ImageFetcherParams params,
const std::string& image_data,
const RequestMetadata& metadata);
@@ -88,8 +79,6 @@ class ImageFetcherImpl : public ImageFetcher {
const RequestMetadata& metadata,
const gfx::Image& image);
- gfx::Size desired_image_frame_size_;
-
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
std::unique_ptr<ImageDecoder> image_decoder_;
diff --git a/chromium/components/image_fetcher/core/image_fetcher_impl_unittest.cc b/chromium/components/image_fetcher/core/image_fetcher_impl_unittest.cc
index 678ee13553e..61ad10cc020 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_impl_unittest.cc
+++ b/chromium/components/image_fetcher/core/image_fetcher_impl_unittest.cc
@@ -31,10 +31,10 @@ namespace image_fetcher {
namespace {
-const char kFetchID[] = "fetch-1";
-const char kFetchID2[] = "fetch-2";
-const char kImageData[] = "data";
-const char kImageURL[] = "http://image.test/test.png";
+constexpr char kImageData[] = "data";
+constexpr char kImageURL[] = "http://image.test/test.png";
+
+constexpr char kImageUmaName[] = "TestUma";
class ImageFetcherImplTest : public testing::Test {
public:
@@ -77,11 +77,11 @@ TEST_F(ImageFetcherImplTest, FetchImageAndDataSuccess) {
base::MockCallback<ImageDataFetcherCallback> data_callback;
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
- EXPECT_CALL(image_callback, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback, Run(ValidImage(), _));
- image_fetcher()->FetchImageAndData(kFetchID, GURL(kImageURL),
- data_callback.Get(), image_callback.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ image_fetcher()->FetchImageAndData(
+ GURL(kImageURL), data_callback.Get(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
@@ -91,34 +91,34 @@ TEST_F(ImageFetcherImplTest, FetchImageAndData3xSuccess) {
base::MockCallback<ImageDataFetcherCallback> data_callback1;
base::MockCallback<ImageFetcherCallback> image_callback1;
EXPECT_CALL(data_callback1, Run(kImageData, _));
- EXPECT_CALL(image_callback1, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback1, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback2;
base::MockCallback<ImageFetcherCallback> image_callback2;
EXPECT_CALL(data_callback2, Run(kImageData, _));
- EXPECT_CALL(image_callback2, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback2, Run(ValidImage(), _));
// This call happens before the network request completes.
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback3;
base::MockCallback<ImageFetcherCallback> image_callback3;
EXPECT_CALL(data_callback3, Run(kImageData, _));
- EXPECT_CALL(image_callback3, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback3, Run(ValidImage(), _));
image_decoder()->SetBeforeImageDecoded(base::BindLambdaForTesting([&]() {
// This happens after the network request completes.
// Shouldn't need to fetch.
test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND);
image_fetcher()->FetchImageAndData(
- kFetchID2, GURL(kImageURL), data_callback3.Get(), image_callback3.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback3.Get(), image_callback3.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
}));
RunUntilIdle();
@@ -131,20 +131,20 @@ TEST_F(ImageFetcherImplTest, FetchImageAndData2xFail) {
base::MockCallback<ImageDataFetcherCallback> data_callback1;
base::MockCallback<ImageFetcherCallback> image_callback1;
EXPECT_CALL(data_callback1, Run("", _));
- EXPECT_CALL(image_callback1, Run(kFetchID, EmptyImage(), _));
+ EXPECT_CALL(image_callback1, Run(EmptyImage(), _));
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback2;
base::MockCallback<ImageFetcherCallback> image_callback2;
EXPECT_CALL(data_callback2, Run("", _));
- EXPECT_CALL(image_callback2, Run(kFetchID, EmptyImage(), _));
+ EXPECT_CALL(image_callback2, Run(EmptyImage(), _));
image_fetcher()->FetchImageAndData(
- kFetchID2, GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
@@ -156,8 +156,8 @@ TEST_F(ImageFetcherImplTest, FetchOnlyData) {
EXPECT_CALL(data_callback, Run(kImageData, _));
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
@@ -168,15 +168,15 @@ TEST_F(ImageFetcherImplTest, FetchDataThenImage) {
EXPECT_CALL(data_callback, Run(kImageData, _));
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageFetcherCallback> image_callback;
- EXPECT_CALL(image_callback, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
- kFetchID2, GURL(kImageURL), ImageDataFetcherCallback(),
- image_callback.Get(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), ImageDataFetcherCallback(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
@@ -185,11 +185,11 @@ TEST_F(ImageFetcherImplTest, FetchImageThenData) {
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageFetcherCallback> image_callback;
- EXPECT_CALL(image_callback, Run(kFetchID, ValidImage(), _));
+ EXPECT_CALL(image_callback, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
- kFetchID, GURL(kImageURL), ImageDataFetcherCallback(),
- image_callback.Get(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), ImageDataFetcherCallback(), image_callback.Get(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
@@ -199,8 +199,8 @@ TEST_F(ImageFetcherImplTest, FetchImageThenData) {
// Shouldn't need to fetch.
test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND);
image_fetcher()->FetchImageAndData(
- kFetchID2, GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
+ ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
}));
RunUntilIdle();
diff --git a/chromium/components/image_fetcher/core/image_fetcher_types.h b/chromium/components/image_fetcher/core/image_fetcher_types.h
index 84b4986af02..bc67e4cddbe 100644
--- a/chromium/components/image_fetcher/core/image_fetcher_types.h
+++ b/chromium/components/image_fetcher/core/image_fetcher_types.h
@@ -8,7 +8,6 @@
#include <string>
#include "base/callback.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
namespace gfx {
class Image;
@@ -22,16 +21,11 @@ namespace image_fetcher {
struct RequestMetadata;
-using DataUseServiceName = data_use_measurement::DataUseUserData::ServiceName;
-
using ImageFetcherCallback =
- base::OnceCallback<void(const std::string& id,
- const gfx::Image& image,
- const RequestMetadata& metadata)>;
+ base::OnceCallback<void(const gfx::Image& image,
+ const RequestMetadata& request_metadata)>;
-// Callback with the |image_data|. If an error prevented a http response,
-// |request_metadata.response_code| will be RESPONSE_CODE_INVALID.
-// TODO(treib): Use RefCountedBytes to avoid copying.
+// TODO(wylieb): Use RefCountedBytes to avoid copying.
using ImageDataFetcherCallback =
base::OnceCallback<void(const std::string& image_data,
const RequestMetadata& request_metadata)>;
diff --git a/chromium/components/image_fetcher/core/mock_image_fetcher.cc b/chromium/components/image_fetcher/core/mock_image_fetcher.cc
index 644a4fa0321..46ce3a49536 100644
--- a/chromium/components/image_fetcher/core/mock_image_fetcher.cc
+++ b/chromium/components/image_fetcher/core/mock_image_fetcher.cc
@@ -4,6 +4,8 @@
#include "components/image_fetcher/core/mock_image_fetcher.h"
+#include <utility>
+
#include "ui/gfx/geometry/size.h"
namespace image_fetcher {
@@ -12,13 +14,12 @@ MockImageFetcher::MockImageFetcher() {}
MockImageFetcher::~MockImageFetcher() {}
void MockImageFetcher::FetchImageAndData(
- const std::string& id,
const GURL& image_url,
ImageDataFetcherCallback image_data_callback,
ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) {
- FetchImageAndData_(id, image_url, &image_data_callback, &image_callback,
- traffic_annotation);
+ ImageFetcherParams params) {
+ FetchImageAndData_(image_url, &image_data_callback, &image_callback,
+ std::move(params));
}
} // namespace image_fetcher
diff --git a/chromium/components/image_fetcher/core/mock_image_fetcher.h b/chromium/components/image_fetcher/core/mock_image_fetcher.h
index b32deb8b1f7..15b98d78e8c 100644
--- a/chromium/components/image_fetcher/core/mock_image_fetcher.h
+++ b/chromium/components/image_fetcher/core/mock_image_fetcher.h
@@ -9,28 +9,24 @@
#include "testing/gmock/include/gmock/gmock.h"
namespace image_fetcher {
+
class MockImageFetcher : public ImageFetcher {
public:
MockImageFetcher();
~MockImageFetcher() override;
- MOCK_METHOD1(SetDataUseServiceName, void(DataUseServiceName));
- MOCK_METHOD1(SetImageDownloadLimit,
- void(base::Optional<int64_t> max_download_bytes));
- MOCK_METHOD1(SetDesiredImageFrameSize, void(const gfx::Size&));
- MOCK_METHOD5(FetchImageAndData_,
- void(const std::string&,
- const GURL&,
+
+ MOCK_METHOD4(FetchImageAndData_,
+ void(const GURL&,
ImageDataFetcherCallback*,
ImageFetcherCallback*,
- const net::NetworkTrafficAnnotationTag&));
- void FetchImageAndData(
- const std::string& id,
- const GURL& image_url,
- ImageDataFetcherCallback image_data_callback,
- ImageFetcherCallback image_callback,
- const net::NetworkTrafficAnnotationTag& traffic_annotation) override;
+ ImageFetcherParams));
+ void FetchImageAndData(const GURL& image_url,
+ ImageDataFetcherCallback image_data_callback,
+ ImageFetcherCallback image_callback,
+ ImageFetcherParams params) override;
MOCK_METHOD0(GetImageDecoder, image_fetcher::ImageDecoder*());
};
+
} // namespace image_fetcher
#endif // COMPONENTS_IMAGE_FETCHER_CORE_MOCK_IMAGE_FETCHER_H_
diff --git a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h
index 5c302b1870f..133e3fb3f31 100644
--- a/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h
+++ b/chromium/components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h
@@ -20,6 +20,8 @@ class GURL;
namespace image_fetcher {
+using DataUseServiceName = data_use_measurement::DataUseUserData::ServiceName;
+
class IOSImageDataFetcherWrapper {
public:
// The TaskRunner is used to decode the image if it is WebP-encoded.
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 ff24d00e366..627f6801ad2 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
@@ -50,9 +50,7 @@ void IOSImageDataFetcherWrapper::FetchImageDataWebpDecoded(
}
void IOSImageDataFetcherWrapper::SetDataUseServiceName(
- DataUseServiceName data_use_service_name) {
- image_data_fetcher_.SetDataUseServiceName(data_use_service_name);
-}
+ DataUseServiceName data_use_service_name) {}
ImageDataFetcherCallback
IOSImageDataFetcherWrapper::CallbackForImageDataFetcher(
diff --git a/chromium/components/image_fetcher/ios/ios_image_decoder_impl.mm b/chromium/components/image_fetcher/ios/ios_image_decoder_impl.mm
index af4fc5616e5..ae02c3be6bd 100644
--- a/chromium/components/image_fetcher/ios/ios_image_decoder_impl.mm
+++ b/chromium/components/image_fetcher/ios/ios_image_decoder_impl.mm
@@ -44,7 +44,6 @@ class IOSImageDecoderImpl : public ImageDecoder {
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
- ;
// The WeakPtrFactory is used to cancel callbacks if ImageFetcher is
// destroyed during WebP decoding.
diff --git a/chromium/components/infobars/core/infobar.cc b/chromium/components/infobars/core/infobar.cc
index f4dc0b7740a..035d8f1bb53 100644
--- a/chromium/components/infobars/core/infobar.cc
+++ b/chromium/components/infobars/core/infobar.cc
@@ -24,6 +24,8 @@ InfoBar::InfoBar(std::unique_ptr<InfoBarDelegate> delegate)
target_height_(0) {
DCHECK(delegate_ != nullptr);
animation_.SetTweenType(gfx::Tween::LINEAR);
+ if (!gfx::Animation::ShouldRenderRichAnimation())
+ animation_.SetSlideDuration(0);
delegate_->set_infobar(this);
}
diff --git a/chromium/components/invalidation/impl/BUILD.gn b/chromium/components/invalidation/impl/BUILD.gn
index 2ea9beba71e..464843bceaf 100644
--- a/chromium/components/invalidation/impl/BUILD.gn
+++ b/chromium/components/invalidation/impl/BUILD.gn
@@ -19,6 +19,8 @@ static_library("feature_list") {
static_library("impl") {
sources = [
+ "channels_states.cc",
+ "channels_states.h",
"deprecated_invalidator_registrar.cc",
"deprecated_invalidator_registrar.h",
"fcm_invalidation_listener.cc",
@@ -52,8 +54,6 @@ static_library("impl") {
"logger.h",
"mock_ack_handler.cc",
"mock_ack_handler.h",
- "per_user_topic_invalidation_client.cc",
- "per_user_topic_invalidation_client.h",
"per_user_topic_registration_manager.cc",
"per_user_topic_registration_manager.h",
"per_user_topic_registration_request.cc",
@@ -157,7 +157,6 @@ source_set("unit_tests") {
"fcm_network_handler_unittests.cc",
"invalidation_logger_unittest.cc",
"invalidator_registrar_unittest.cc",
- "per_user_topic_invalidation_client_unittest.cc",
"per_user_topic_registration_manager_unittest.cc",
"per_user_topic_registration_request_unittest.cc",
]
diff --git a/chromium/components/invalidation/public/BUILD.gn b/chromium/components/invalidation/public/BUILD.gn
index 6bfae174686..3d559892546 100644
--- a/chromium/components/invalidation/public/BUILD.gn
+++ b/chromium/components/invalidation/public/BUILD.gn
@@ -35,6 +35,7 @@ static_library("public") {
]
deps = [
"//base",
+ "//base:i18n",
]
}
diff --git a/chromium/components/journey/journey_info_fetcher.cc b/chromium/components/journey/journey_info_fetcher.cc
index 22ee9b11c93..7f4d112f54b 100644
--- a/chromium/components/journey/journey_info_fetcher.cc
+++ b/chromium/components/journey/journey_info_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/journey/journey_info_fetcher.h"
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/journey/journey_info_json_request.h"
diff --git a/chromium/components/journey/journey_info_json_request.cc b/chromium/components/journey/journey_info_json_request.cc
index 0c7bb90a35b..5ec8f85092a 100644
--- a/chromium/components/journey/journey_info_json_request.cc
+++ b/chromium/components/journey/journey_info_json_request.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/journey/proto/batch_get_switcher_journey_from_pageload_request.pb.h"
@@ -144,8 +145,6 @@ JourneyInfoJsonRequest::Builder::BuildSimpleURLLoaderHeaders() const {
if (!auth_header_.empty()) {
headers.SetHeader("Authorization", auth_header_);
}
- variations::AppendVariationHeaders(url_, variations::InIncognito::kNo,
- variations::SignedIn::kNo, &headers);
return headers;
}
@@ -160,6 +159,9 @@ JourneyInfoJsonRequest::Builder::BuildSimpleURLLoader() const {
resource_request->load_flags =
net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES;
resource_request->headers = BuildSimpleURLLoaderHeaders();
+ variations::AppendVariationsHeader(url_, variations::InIncognito::kNo,
+ variations::SignedIn::kNo,
+ resource_request.get());
resource_request->method = "POST";
auto simple_loader = network::SimpleURLLoader::Create(
diff --git a/chromium/components/keyed_service/DEPS b/chromium/components/keyed_service/DEPS
index 4153fdbac2b..b1e57475ca9 100644
--- a/chromium/components/keyed_service/DEPS
+++ b/chromium/components/keyed_service/DEPS
@@ -5,5 +5,4 @@ include_rules = [
"+components/pref_registry",
"+components/prefs",
- "+components/user_prefs",
]
diff --git a/chromium/components/keyed_service/OWNERS b/chromium/components/keyed_service/OWNERS
index 39557cd3030..10af5a5b02e 100644
--- a/chromium/components/keyed_service/OWNERS
+++ b/chromium/components/keyed_service/OWNERS
@@ -1 +1,2 @@
blundell@chromium.org
+sdefresne@chromium.org
diff --git a/chromium/components/keyed_service/content/BUILD.gn b/chromium/components/keyed_service/content/BUILD.gn
index deadc76bc67..763dd152023 100644
--- a/chromium/components/keyed_service/content/BUILD.gn
+++ b/chromium/components/keyed_service/content/BUILD.gn
@@ -32,7 +32,6 @@ component("content") {
deps = [
"//base/third_party/dynamic_annotations",
"//components/pref_registry",
- "//components/user_prefs",
"//content/public/browser",
"//content/public/common",
]
diff --git a/chromium/components/keyed_service/content/browser_context_dependency_manager.cc b/chromium/components/keyed_service/content/browser_context_dependency_manager.cc
index e9cf9d391fe..3179ba48f4c 100644
--- a/chromium/components/keyed_service/content/browser_context_dependency_manager.cc
+++ b/chromium/components/keyed_service/content/browser_context_dependency_manager.cc
@@ -85,7 +85,7 @@ BrowserContextDependencyManager::~BrowserContextDependencyManager() {
#ifndef NDEBUG
void BrowserContextDependencyManager::DumpContextDependencies(
- base::SupportsUserData* context) const {
+ void* context) const {
// Whenever we try to build a destruction ordering, we should also dump a
// dependency graph to "/path/to/context/context-dependencies.dot".
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chromium/components/keyed_service/content/browser_context_dependency_manager.h b/chromium/components/keyed_service/content/browser_context_dependency_manager.h
index 8320e2be5dd..bf434adec18 100644
--- a/chromium/components/keyed_service/content/browser_context_dependency_manager.h
+++ b/chromium/components/keyed_service/content/browser_context_dependency_manager.h
@@ -96,7 +96,7 @@ class KEYED_SERVICE_EXPORT BrowserContextDependencyManager
#ifndef NDEBUG
// DependencyManager:
- void DumpContextDependencies(base::SupportsUserData* context) const final;
+ void DumpContextDependencies(void* context) const final;
#endif // NDEBUG
// A list of callbacks to call just before executing
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc
index d37d6c188fc..8076ee3d865 100644
--- a/chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc
+++ b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.cc
@@ -28,11 +28,6 @@ content::BrowserContext* BrowserContextKeyedBaseFactory::GetBrowserContextToUse(
return context;
}
-void BrowserContextKeyedBaseFactory::RegisterUserPrefsOnBrowserContextForTest(
- content::BrowserContext* context) {
- KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
-}
-
bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext()
const {
return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
@@ -47,8 +42,7 @@ void BrowserContextKeyedBaseFactory::BrowserContextDestroyed(
KeyedServiceBaseFactory::ContextDestroyed(context);
}
-base::SupportsUserData* BrowserContextKeyedBaseFactory::GetContextToUse(
- base::SupportsUserData* context) const {
+void* BrowserContextKeyedBaseFactory::GetContextToUse(void* context) const {
AssertContextWasntDestroyed(context);
return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
}
@@ -57,13 +51,11 @@ bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithContext() const {
return ServiceIsCreatedWithBrowserContext();
}
-void BrowserContextKeyedBaseFactory::ContextShutdown(
- base::SupportsUserData* context) {
+void BrowserContextKeyedBaseFactory::ContextShutdown(void* context) {
BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
}
-void BrowserContextKeyedBaseFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+void BrowserContextKeyedBaseFactory::ContextDestroyed(void* context) {
BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
}
@@ -72,17 +64,14 @@ void BrowserContextKeyedBaseFactory::RegisterPrefs(
RegisterProfilePrefs(registry);
}
-void BrowserContextKeyedBaseFactory::SetEmptyTestingFactory(
- base::SupportsUserData* context) {
+void BrowserContextKeyedBaseFactory::SetEmptyTestingFactory(void* context) {
SetEmptyTestingFactory(static_cast<content::BrowserContext*>(context));
}
-bool BrowserContextKeyedBaseFactory::HasTestingFactory(
- base::SupportsUserData* context) {
+bool BrowserContextKeyedBaseFactory::HasTestingFactory(void* context) {
return HasTestingFactory(static_cast<content::BrowserContext*>(context));
}
-void BrowserContextKeyedBaseFactory::CreateServiceNow(
- base::SupportsUserData* context) {
+void BrowserContextKeyedBaseFactory::CreateServiceNow(void* context) {
CreateServiceNow(static_cast<content::BrowserContext*>(context));
}
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_base_factory.h b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.h
index fc5a5d36376..69556d83ebd 100644
--- a/chromium/components/keyed_service/content/browser_context_keyed_base_factory.h
+++ b/chromium/components/keyed_service/content/browser_context_keyed_base_factory.h
@@ -9,7 +9,6 @@
#include "components/keyed_service/core/keyed_service_export.h"
class BrowserContextDependencyManager;
-class PrefService;
namespace content {
class BrowserContext;
@@ -34,17 +33,6 @@ class PrefRegistrySyncable;
// on KeyedServiceBaseFactory instead.
class KEYED_SERVICE_EXPORT BrowserContextKeyedBaseFactory
: public KeyedServiceBaseFactory {
- public:
- // Registers preferences used in this service on the pref service of
- // |context|. This is the public interface and is safe to be called multiple
- // times because testing code can have multiple services of the same type
- // attached to a single |context|. Only test code is allowed to call this
- // method.
- // TODO(gab): This method can be removed entirely when
- // PrefService::DeprecatedGetPrefRegistry() is phased out.
- void RegisterUserPrefsOnBrowserContextForTest(
- content::BrowserContext* context);
-
protected:
BrowserContextKeyedBaseFactory(const char* name,
BrowserContextDependencyManager* manager);
@@ -89,9 +77,8 @@ class KEYED_SERVICE_EXPORT BrowserContextKeyedBaseFactory
virtual void BrowserContextDestroyed(content::BrowserContext* context);
private:
- // Registers any user preferences on this service. This is called by
- // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
- // that wants to register profile-specific preferences.
+ // Registers any user preferences on this service. This should be overriden by
+ // any service that wants to register profile-specific preferences.
virtual void RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {}
@@ -107,15 +94,14 @@ class KEYED_SERVICE_EXPORT BrowserContextKeyedBaseFactory
virtual void CreateServiceNow(content::BrowserContext* context) = 0;
// KeyedServiceBaseFactory:
- base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const final;
+ void* GetContextToUse(void* context) const final;
bool ServiceIsCreatedWithContext() const final;
- void ContextShutdown(base::SupportsUserData* context) final;
- void ContextDestroyed(base::SupportsUserData* context) final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
- void SetEmptyTestingFactory(base::SupportsUserData* context) final;
- bool HasTestingFactory(base::SupportsUserData* context) final;
- void CreateServiceNow(base::SupportsUserData* context) final;
+ void SetEmptyTestingFactory(void* context) final;
+ bool HasTestingFactory(void* context) final;
+ void CreateServiceNow(void* context) final;
};
#endif // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc
index e0d295bbdf6..67cbd36b5c3 100644
--- a/chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.cc
@@ -4,13 +4,14 @@
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
void BrowserContextKeyedServiceFactory::SetTestingFactory(
@@ -19,8 +20,7 @@ void BrowserContextKeyedServiceFactory::SetTestingFactory(
KeyedServiceFactory::TestingFactory wrapped_factory;
if (testing_factory) {
wrapped_factory = base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
+ [](const TestingFactory& testing_factory, void* context) {
return testing_factory.Run(
static_cast<content::BrowserContext*>(context));
},
@@ -34,13 +34,13 @@ KeyedService* BrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
TestingFactory testing_factory) {
DCHECK(testing_factory);
return KeyedServiceFactory::SetTestingFactoryAndUse(
- context, base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
- return testing_factory.Run(
- static_cast<content::BrowserContext*>(context));
- },
- std::move(testing_factory)));
+ context, nullptr /* side_parameter */,
+ base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(
+ static_cast<content::BrowserContext*>(context));
+ },
+ std::move(testing_factory)));
}
BrowserContextKeyedServiceFactory::BrowserContextKeyedServiceFactory(
@@ -55,7 +55,8 @@ BrowserContextKeyedServiceFactory::~BrowserContextKeyedServiceFactory() {
KeyedService* BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
content::BrowserContext* context,
bool create) {
- return KeyedServiceFactory::GetServiceForContext(context, create);
+ return KeyedServiceFactory::GetServiceForContext(
+ context, nullptr /* side_parameter */, create);
}
content::BrowserContext*
@@ -71,12 +72,6 @@ BrowserContextKeyedServiceFactory::GetBrowserContextToUse(
return context;
}
-void
-BrowserContextKeyedServiceFactory::RegisterUserPrefsOnBrowserContextForTest(
- content::BrowserContext* context) {
- KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
-}
-
bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithBrowserContext()
const {
return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
@@ -98,20 +93,19 @@ void BrowserContextKeyedServiceFactory::BrowserContextDestroyed(
std::unique_ptr<KeyedService>
BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(
- base::SupportsUserData* context) const {
+ void* context,
+ void* side_parameter) const {
// TODO(isherman): The wrapped BuildServiceInstanceFor() should return a
// scoped_ptr as well.
return base::WrapUnique(
BuildServiceInstanceFor(static_cast<content::BrowserContext*>(context)));
}
-bool BrowserContextKeyedServiceFactory::IsOffTheRecord(
- base::SupportsUserData* context) const {
+bool BrowserContextKeyedServiceFactory::IsOffTheRecord(void* context) const {
return static_cast<content::BrowserContext*>(context)->IsOffTheRecord();
}
-base::SupportsUserData* BrowserContextKeyedServiceFactory::GetContextToUse(
- base::SupportsUserData* context) const {
+void* BrowserContextKeyedServiceFactory::GetContextToUse(void* context) const {
AssertContextWasntDestroyed(context);
return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
}
@@ -120,13 +114,11 @@ bool BrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext() const {
return ServiceIsCreatedWithBrowserContext();
}
-void BrowserContextKeyedServiceFactory::ContextShutdown(
- base::SupportsUserData* context) {
+void BrowserContextKeyedServiceFactory::ContextShutdown(void* context) {
BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
}
-void BrowserContextKeyedServiceFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+void BrowserContextKeyedServiceFactory::ContextDestroyed(void* context) {
BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
}
@@ -134,3 +126,8 @@ void BrowserContextKeyedServiceFactory::RegisterPrefs(
user_prefs::PrefRegistrySyncable* registry) {
RegisterProfilePrefs(registry);
}
+
+void BrowserContextKeyedServiceFactory::CreateServiceNow(void* context) {
+ KeyedServiceFactory::GetServiceForContext(context,
+ nullptr /* side_parameter */, true);
+}
diff --git a/chromium/components/keyed_service/content/browser_context_keyed_service_factory.h b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.h
index 3b4cce03211..e6ec079b56d 100644
--- a/chromium/components/keyed_service/content/browser_context_keyed_service_factory.h
+++ b/chromium/components/keyed_service/content/browser_context_keyed_service_factory.h
@@ -29,16 +29,6 @@ class BrowserContext;
class KEYED_SERVICE_EXPORT BrowserContextKeyedServiceFactory
: public KeyedServiceFactory {
public:
- // Registers preferences used in this service on the pref service of
- // |context|. This is the public interface and is safe to be called multiple
- // times because testing code can have multiple services of the same type
- // attached to a single |context|. Only test code is allowed to call this
- // method.
- // TODO(gab): This method can be removed entirely when
- // PrefService::DeprecatedGetPrefRegistry() is phased out.
- void RegisterUserPrefsOnBrowserContextForTest(
- content::BrowserContext* context);
-
// A callback that supplies the instance of a KeyedService for a given
// BrowserContext. This is used primarily for testing, where we want to feed
// a specific test double into the BCKSF system.
@@ -125,24 +115,24 @@ class KEYED_SERVICE_EXPORT BrowserContextKeyedServiceFactory
private:
friend class BrowserContextDependencyManagerUnittests;
- // Registers any user preferences on this service. This is called by
- // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
- // that wants to register profile-specific preferences.
+ // Registers any user preferences on this service. This should be overriden by
+ // any service that wants to register profile-specific preferences.
virtual void RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {}
// KeyedServiceFactory:
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const final;
- bool IsOffTheRecord(base::SupportsUserData* context) const final;
+ void* context,
+ void* side_parameter) const final;
+ bool IsOffTheRecord(void* context) const final;
// KeyedServiceBaseFactory:
- base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const final;
+ void* GetContextToUse(void* context) const final;
bool ServiceIsCreatedWithContext() const final;
- void ContextShutdown(base::SupportsUserData* context) final;
- void ContextDestroyed(base::SupportsUserData* context) final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+ void CreateServiceNow(void* context) final;
DISALLOW_COPY_AND_ASSIGN(BrowserContextKeyedServiceFactory);
};
diff --git a/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc
index cab1652bbdb..e6095171827 100644
--- a/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc
+++ b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.cc
@@ -16,8 +16,7 @@ void RefcountedBrowserContextKeyedServiceFactory::SetTestingFactory(
RefcountedKeyedServiceFactory::TestingFactory wrapped_factory;
if (testing_factory) {
wrapped_factory = base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
+ [](const TestingFactory& testing_factory, void* context) {
return testing_factory.Run(
static_cast<content::BrowserContext*>(context));
},
@@ -33,13 +32,13 @@ RefcountedBrowserContextKeyedServiceFactory::SetTestingFactoryAndUse(
TestingFactory testing_factory) {
DCHECK(testing_factory);
return RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
- context, base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
- return testing_factory.Run(
- static_cast<content::BrowserContext*>(context));
- },
- std::move(testing_factory)));
+ context, nullptr /* side_parameter */,
+ base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(
+ static_cast<content::BrowserContext*>(context));
+ },
+ std::move(testing_factory)));
}
RefcountedBrowserContextKeyedServiceFactory::
@@ -57,7 +56,8 @@ scoped_refptr<RefcountedKeyedService>
RefcountedBrowserContextKeyedServiceFactory::GetServiceForBrowserContext(
content::BrowserContext* context,
bool create) {
- return RefcountedKeyedServiceFactory::GetServiceForContext(context, create);
+ return RefcountedKeyedServiceFactory::GetServiceForContext(
+ context, nullptr /* side_parameter */, create);
}
content::BrowserContext*
@@ -95,19 +95,19 @@ void RefcountedBrowserContextKeyedServiceFactory::BrowserContextDestroyed(
scoped_refptr<RefcountedKeyedService>
RefcountedBrowserContextKeyedServiceFactory::BuildServiceInstanceFor(
- base::SupportsUserData* context) const {
+ void* context,
+ void* side_parameter) const {
return BuildServiceInstanceFor(
static_cast<content::BrowserContext*>(context));
}
bool RefcountedBrowserContextKeyedServiceFactory::IsOffTheRecord(
- base::SupportsUserData* context) const {
+ void* context) const {
return static_cast<content::BrowserContext*>(context)->IsOffTheRecord();
}
-base::SupportsUserData*
-RefcountedBrowserContextKeyedServiceFactory::GetContextToUse(
- base::SupportsUserData* context) const {
+void* RefcountedBrowserContextKeyedServiceFactory::GetContextToUse(
+ void* context) const {
AssertContextWasntDestroyed(context);
return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
}
@@ -118,12 +118,12 @@ bool RefcountedBrowserContextKeyedServiceFactory::ServiceIsCreatedWithContext()
}
void RefcountedBrowserContextKeyedServiceFactory::ContextShutdown(
- base::SupportsUserData* context) {
+ void* context) {
BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
}
void RefcountedBrowserContextKeyedServiceFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+ void* context) {
BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
}
diff --git a/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h
index 1580eda812a..0e9090cc1bd 100644
--- a/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h
+++ b/chromium/components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h
@@ -120,23 +120,22 @@ class KEYED_SERVICE_EXPORT RefcountedBrowserContextKeyedServiceFactory
private:
friend class BrowserContextDependencyManagerUnittests;
- // Registers any user preferences on this service. This is called by
- // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
- // that wants to register profile-specific preferences.
+ // Registers any user preferences on this service. This should be overriden by
+ // any service that wants to register profile-specific preferences.
virtual void RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {}
// RefcountedKeyedServiceFactory:
scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const final;
- bool IsOffTheRecord(base::SupportsUserData* context) const final;
+ void* context,
+ void* side_parameter) const final;
+ bool IsOffTheRecord(void* context) const final;
// KeyedServiceBaseFactory:
- base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const final;
+ void* GetContextToUse(void* context) const final;
bool ServiceIsCreatedWithContext() const final;
- void ContextShutdown(base::SupportsUserData* context) final;
- void ContextDestroyed(base::SupportsUserData* context) final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
DISALLOW_COPY_AND_ASSIGN(RefcountedBrowserContextKeyedServiceFactory);
diff --git a/chromium/components/keyed_service/core/BUILD.gn b/chromium/components/keyed_service/core/BUILD.gn
index 863ce7f8577..ae58817db31 100644
--- a/chromium/components/keyed_service/core/BUILD.gn
+++ b/chromium/components/keyed_service/core/BUILD.gn
@@ -24,6 +24,12 @@ component("core") {
"refcounted_keyed_service_factory.cc",
"refcounted_keyed_service_factory.h",
"service_access_type.h",
+ "simple_dependency_manager.cc",
+ "simple_dependency_manager.h",
+ "simple_factory_key.cc",
+ "simple_factory_key.h",
+ "simple_keyed_service_factory.cc",
+ "simple_keyed_service_factory.h",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
@@ -34,7 +40,6 @@ component("core") {
"//base",
"//components/pref_registry",
"//components/prefs",
- "//components/user_prefs",
]
}
diff --git a/chromium/components/keyed_service/core/dependency_manager.cc b/chromium/components/keyed_service/core/dependency_manager.cc
index 093f40a82cf..9395b86e1f3 100644
--- a/chromium/components/keyed_service/core/dependency_manager.cc
+++ b/chromium/components/keyed_service/core/dependency_manager.cc
@@ -35,7 +35,7 @@ void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended,
}
void DependencyManager::RegisterPrefsForServices(
- base::SupportsUserData* context,
+ void* context,
user_prefs::PrefRegistrySyncable* pref_registry) {
std::vector<DependencyNode*> construction_order;
if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
@@ -45,11 +45,11 @@ void DependencyManager::RegisterPrefsForServices(
for (auto* dependency_node : construction_order) {
KeyedServiceBaseFactory* factory =
static_cast<KeyedServiceBaseFactory*>(dependency_node);
- factory->RegisterPrefsIfNecessaryForContext(context, pref_registry);
+ factory->RegisterPrefs(pref_registry);
}
}
-void DependencyManager::CreateContextServices(base::SupportsUserData* context,
+void DependencyManager::CreateContextServices(void* context,
bool is_testing_context) {
MarkContextLive(context);
@@ -74,8 +74,7 @@ void DependencyManager::CreateContextServices(base::SupportsUserData* context,
}
}
-void DependencyManager::DestroyContextServices(
- base::SupportsUserData* context) {
+void DependencyManager::DestroyContextServices(void* context) {
std::vector<DependencyNode*> destruction_order;
if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
NOTREACHED();
@@ -101,8 +100,7 @@ void DependencyManager::DestroyContextServices(
}
}
-void DependencyManager::AssertContextWasntDestroyed(
- base::SupportsUserData* context) const {
+void DependencyManager::AssertContextWasntDestroyed(void* context) const {
if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
#if DCHECK_IS_ON()
NOTREACHED() << "Attempted to access a context that was ShutDown(). "
@@ -116,7 +114,7 @@ void DependencyManager::AssertContextWasntDestroyed(
}
}
-void DependencyManager::MarkContextLive(base::SupportsUserData* context) {
+void DependencyManager::MarkContextLive(void* context) {
dead_context_pointers_.erase(context);
}
diff --git a/chromium/components/keyed_service/core/dependency_manager.h b/chromium/components/keyed_service/core/dependency_manager.h
index 32c1f646447..0f881a95713 100644
--- a/chromium/components/keyed_service/core/dependency_manager.h
+++ b/chromium/components/keyed_service/core/dependency_manager.h
@@ -15,7 +15,6 @@ class KeyedServiceBaseFactory;
namespace base {
class FilePath;
-class SupportsUserData;
}
namespace user_prefs {
@@ -42,7 +41,7 @@ class KEYED_SERVICE_EXPORT DependencyManager {
// Registers preferences for all services via |registry| associated with
// |context| (the association is managed by the embedder). The |context|
// is used as a key to prevent multiple registration during tests.
- void RegisterPrefsForServices(base::SupportsUserData* context,
+ void RegisterPrefsForServices(void* context,
user_prefs::PrefRegistrySyncable* registry);
// Called upon creation of |context| to create services that want to be
@@ -55,24 +54,23 @@ class KEYED_SERVICE_EXPORT DependencyManager {
//
// If |is_testing_context| then the service will not be started unless the
// method KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() return false.
- void CreateContextServices(base::SupportsUserData* context,
- bool is_testing_context);
+ void CreateContextServices(void* context, bool is_testing_context);
// Called upon destruction of |context| to destroy all services associated
// with it.
- void DestroyContextServices(base::SupportsUserData* context);
+ void DestroyContextServices(void* context);
// Runtime assertion called as a part of GetServiceForContext() to check if
// |context| is considered stale. This will NOTREACHED() or
// base::debug::DumpWithoutCrashing() depending on the DCHECK_IS_ON() value.
- void AssertContextWasntDestroyed(base::SupportsUserData* context) const;
+ void AssertContextWasntDestroyed(void* context) const;
// Marks |context| as live (i.e., not stale). This method can be called as a
// safeguard against |AssertContextWasntDestroyed()| checks going off due to
// |context| aliasing an instance from a prior construction (i.e., 0xWhatever
// might be created, be destroyed, and then a new object might be created at
// 0xWhatever).
- void MarkContextLive(base::SupportsUserData* context);
+ void MarkContextLive(void* context);
#ifndef NDEBUG
// Dumps service dependency graph as a Graphviz dot file |dot_file| with a
@@ -86,8 +84,7 @@ class KEYED_SERVICE_EXPORT DependencyManager {
#ifndef NDEBUG
// Hook for subclass to dump the dependency graph of service for |context|.
- virtual void DumpContextDependencies(
- base::SupportsUserData* context) const = 0;
+ virtual void DumpContextDependencies(void* context) const = 0;
#endif // NDEBUG
DependencyGraph dependency_graph_;
@@ -96,7 +93,7 @@ class KEYED_SERVICE_EXPORT DependencyManager {
// These pointers are most likely invalid, but we keep track of their
// locations in memory so we can nicely assert if we're asked to do anything
// with them.
- std::set<base::SupportsUserData*> dead_context_pointers_;
+ std::set<void*> dead_context_pointers_;
};
#endif // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
diff --git a/chromium/components/keyed_service/core/keyed_service_base_factory.cc b/chromium/components/keyed_service/core/keyed_service_base_factory.cc
index 19b7513efa1..fe02e58536b 100644
--- a/chromium/components/keyed_service/core/keyed_service_base_factory.cc
+++ b/chromium/components/keyed_service/core/keyed_service_base_factory.cc
@@ -9,39 +9,6 @@
#include "components/keyed_service/core/dependency_manager.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
-#include "components/user_prefs/user_prefs.h"
-
-void KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(
- base::SupportsUserData* context) {
- TRACE_EVENT0("browser,startup",
- "KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest");
- // Safe timing for pref registration is hard. Previously, we made
- // context responsible for all pref registration on every service
- // that used contexts. Now we don't and there are timing issues.
- //
- // With normal contexts, prefs can simply be registered at
- // DependencyManager::RegisterProfilePrefsForServices time.
- // With incognito contexts, we just never register since incognito
- // contexts share the same pref services with their parent contexts.
- //
- // Testing contexts throw a wrench into the mix, in that some tests will
- // swap out the PrefService after we've registered user prefs on the original
- // PrefService. Test code that does this is responsible for either manually
- // invoking RegisterProfilePrefs() on the appropriate
- // ContextKeyedServiceFactory associated with the prefs they need,
- // or they can use SetTestingFactory() and create a service (since service
- // creation with a factory method causes registration to happen at
- // TestingProfile creation time).
- //
- // Now that services are responsible for declaring their preferences, we have
- // to enforce a uniquenes check here because some tests create one context and
- // multiple services of the same type attached to that context (serially, not
- // parallel) and we don't want to register multiple times on the same context.
- // This is the purpose of RegisterPrefsIfNecessaryForContext() which could be
- // replaced directly by RegisterPrefs() if this method is ever phased out.
- RegisterPrefsIfNecessaryForContext(context,
- GetAssociatedPrefRegistry(context));
-}
KeyedServiceBaseFactory::KeyedServiceBaseFactory(const char* service_name,
DependencyManager* manager)
@@ -58,34 +25,14 @@ void KeyedServiceBaseFactory::DependsOn(KeyedServiceBaseFactory* rhs) {
dependency_manager_->AddEdge(rhs, this);
}
-void KeyedServiceBaseFactory::RegisterPrefsIfNecessaryForContext(
- base::SupportsUserData* context,
- user_prefs::PrefRegistrySyncable* registry) {
- if (!ArePreferencesSetOn(context)) {
- RegisterPrefs(registry);
- MarkPreferencesSetOn(context);
- }
-}
-
-user_prefs::PrefRegistrySyncable*
-KeyedServiceBaseFactory::GetAssociatedPrefRegistry(
- base::SupportsUserData* context) const {
- PrefService* prefs = user_prefs::UserPrefs::Get(context);
- user_prefs::PrefRegistrySyncable* registry =
- static_cast<user_prefs::PrefRegistrySyncable*>(
- prefs->DeprecatedGetPrefRegistry());
- return registry;
-}
-
-void KeyedServiceBaseFactory::AssertContextWasntDestroyed(
- base::SupportsUserData* context) const {
+void KeyedServiceBaseFactory::AssertContextWasntDestroyed(void* context) const {
// TODO(crbug.com/701326): We should DCHECK(CalledOnValidThread()) here, but
// currently some code doesn't do service getting on the main thread.
// This needs to be fixed and DCHECK should be restored here.
dependency_manager_->AssertContextWasntDestroyed(context);
}
-void KeyedServiceBaseFactory::MarkContextLive(base::SupportsUserData* context) {
+void KeyedServiceBaseFactory::MarkContextLive(void* context) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dependency_manager_->MarkContextLive(context);
}
@@ -98,21 +45,8 @@ bool KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() const {
return false;
}
-void KeyedServiceBaseFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+void KeyedServiceBaseFactory::ContextDestroyed(void* context) {
// While object destruction can be customized in ways where the object is
// only dereferenced, this still must run on the UI thread.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- registered_preferences_.erase(context);
-}
-
-bool KeyedServiceBaseFactory::ArePreferencesSetOn(
- base::SupportsUserData* context) const {
- return registered_preferences_.find(context) != registered_preferences_.end();
-}
-
-void KeyedServiceBaseFactory::MarkPreferencesSetOn(
- base::SupportsUserData* context) {
- DCHECK(!ArePreferencesSetOn(context));
- registered_preferences_.insert(context);
}
diff --git a/chromium/components/keyed_service/core/keyed_service_base_factory.h b/chromium/components/keyed_service/core/keyed_service_base_factory.h
index 48c3ca24892..f603dcc19e0 100644
--- a/chromium/components/keyed_service/core/keyed_service_base_factory.h
+++ b/chromium/components/keyed_service/core/keyed_service_base_factory.h
@@ -12,19 +12,14 @@
#include "components/keyed_service/core/keyed_service_export.h"
class DependencyManager;
-class PrefService;
-
-namespace base {
-class SupportsUserData;
-}
namespace user_prefs {
class PrefRegistrySyncable;
}
-// Base class for factories that take a base::SupportsUserData and return some
-// service. Not for direct usage, instead use descendent classes that deal with
-// more specific context objects.
+// Base class for factories that take an opaque pointer and return some service.
+// Not for direct usage, instead use descendent classes that deal with more
+// specific context objects.
//
// This object describes general dependency management between factories while
// direct subclasses react to lifecycle events and implement memory management.
@@ -37,46 +32,23 @@ class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory : public DependencyNode {
KeyedServiceBaseFactory(const char* service_name, DependencyManager* manager);
virtual ~KeyedServiceBaseFactory();
- // Registers preferences used in this service on the pref service associated
- // with |context|. This is safe to be called multiple times because testing
- // code can have multiple services of the same type attached to a single
- // |context|. Only test code is allowed to call this method.
- //
- // TODO(gab): This method can be removed entirely when
- // PrefService::DeprecatedGetPrefRegistry() is phased out.
- void RegisterUserPrefsOnContextForTest(base::SupportsUserData* context);
-
// The main public interface for declaring dependencies between services
// created by factories.
void DependsOn(KeyedServiceBaseFactory* rhs);
// Runtime assertion to check if |context| is considered stale. Should be used
// by subclasses when accessing |context|.
- void AssertContextWasntDestroyed(base::SupportsUserData* context) const;
+ void AssertContextWasntDestroyed(void* context) const;
// Marks |context| as live (i.e., not stale). This method can be called as a
// safeguard against |AssertContextWasntDestroyed()| checks going off due to
// |context| aliasing an instance from a prior construction (i.e., 0xWhatever
// might be created, be destroyed, and then a new object might be created at
// 0xWhatever).
- void MarkContextLive(base::SupportsUserData* context);
-
- // Calls RegisterProfilePrefs() after doing house keeping required to work
- // alongside RegisterUserPrefsOnContextForTest().
- // TODO(gab): This method can be replaced by RegisterProfilePrefs() directly
- // once RegisterUserPrefsOnContextForTest() is phased out.
- void RegisterPrefsIfNecessaryForContext(
- base::SupportsUserData* context,
- user_prefs::PrefRegistrySyncable* registry);
-
- // Returns the |user_pref::PrefRegistrySyncable| associated with |context|.
- // The way they are associated is controlled by the embedder.
- user_prefs::PrefRegistrySyncable* GetAssociatedPrefRegistry(
- base::SupportsUserData* context) const;
+ void MarkContextLive(void* context);
// Finds which context (if any) to use.
- virtual base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const = 0;
+ virtual void* GetContextToUse(void* context) const = 0;
// By default, instance of a service are created lazily when GetForContext()
// is called by the subclass. Some services need to be created as soon as the
@@ -99,14 +71,8 @@ class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory : public DependencyNode {
// service with GetForContext() will NOTREACHED() and code should delete/
// deref/do other final memory management during this phase. The base class
// method *must* be called as the last thing.
- virtual void ContextShutdown(base::SupportsUserData* context) = 0;
- virtual void ContextDestroyed(base::SupportsUserData* context);
-
- // Returns whether the preferences have been registered on this context.
- bool ArePreferencesSetOn(base::SupportsUserData* context) const;
-
- // Mark context has having preferences registered.
- void MarkPreferencesSetOn(base::SupportsUserData* context);
+ virtual void ContextShutdown(void* context) = 0;
+ virtual void ContextDestroyed(void* context);
SEQUENCE_CHECKER(sequence_checker_);
@@ -117,21 +83,19 @@ class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory : public DependencyNode {
// by all the factories of a given type. Unit tests will use their own copy.
DependencyManager* dependency_manager_;
- // Registers any preferences used by this service.
+ // Registers any preferences used by this service. This should be overriden by
+ // any services that want to register context-specific preferences.
virtual void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) {}
// Used by DependencyManager to disable creation of the service when the
// method ServiceIsNULLWhileTesting() returns true.
- virtual void SetEmptyTestingFactory(base::SupportsUserData* context) = 0;
+ virtual void SetEmptyTestingFactory(void* context) = 0;
// Returns true if a testing factory function has been set for |context|.
- virtual bool HasTestingFactory(base::SupportsUserData* context) = 0;
+ virtual bool HasTestingFactory(void* context) = 0;
// Create the service associated with |context|.
- virtual void CreateServiceNow(base::SupportsUserData* context) = 0;
-
- // Contexts that have this service's preferences registered on them.
- std::set<base::SupportsUserData*> registered_preferences_;
+ virtual void CreateServiceNow(void* context) = 0;
// A static string passed in to the constructor. Should be unique across all
// services.
diff --git a/chromium/components/keyed_service/core/keyed_service_factory.cc b/chromium/components/keyed_service/core/keyed_service_factory.cc
index 5fbfc03f700..f490446d2c1 100644
--- a/chromium/components/keyed_service/core/keyed_service_factory.cc
+++ b/chromium/components/keyed_service/core/keyed_service_factory.cc
@@ -21,14 +21,8 @@ KeyedServiceFactory::~KeyedServiceFactory() {
DCHECK(mapping_.empty());
}
-void KeyedServiceFactory::SetTestingFactory(base::SupportsUserData* context,
+void KeyedServiceFactory::SetTestingFactory(void* context,
TestingFactory testing_factory) {
- // Destroying the context may cause us to lose data about whether |context|
- // has our preferences registered on it (since the context object itself
- // isn't dead). See if we need to readd it once we've gone through normal
- // destruction.
- bool add_context = ArePreferencesSetOn(context);
-
// Ensure that |context| is not marked as stale (e.g., due to it aliasing an
// instance that was destroyed in an earlier test) in order to avoid accesses
// to |context| in |BrowserContextShutdown| from causing
@@ -41,23 +35,21 @@ void KeyedServiceFactory::SetTestingFactory(base::SupportsUserData* context,
ContextShutdown(context);
ContextDestroyed(context);
- if (add_context)
- MarkPreferencesSetOn(context);
-
testing_factories_.emplace(context, std::move(testing_factory));
}
KeyedService* KeyedServiceFactory::SetTestingFactoryAndUse(
- base::SupportsUserData* context,
+ void* context,
+ void* side_parameter,
TestingFactory testing_factory) {
DCHECK(testing_factory);
SetTestingFactory(context, std::move(testing_factory));
- return GetServiceForContext(context, true);
+ return GetServiceForContext(context, side_parameter, true);
}
-KeyedService* KeyedServiceFactory::GetServiceForContext(
- base::SupportsUserData* context,
- bool create) {
+KeyedService* KeyedServiceFactory::GetServiceForContext(void* context,
+ void* side_parameter,
+ bool create) {
TRACE_EVENT1("browser,startup", "KeyedServiceFactory::GetServiceForContext",
"service_name", name());
context = GetContextToUse(context);
@@ -81,38 +73,36 @@ KeyedService* KeyedServiceFactory::GetServiceForContext(
auto factory_iterator = testing_factories_.find(context);
if (factory_iterator != testing_factories_.end()) {
if (factory_iterator->second) {
- if (!IsOffTheRecord(context))
- RegisterUserPrefsOnContextForTest(context);
service = factory_iterator->second.Run(context);
}
} else {
- service = BuildServiceInstanceFor(context);
+ service = BuildServiceInstanceFor(context, side_parameter);
}
return Associate(context, std::move(service));
}
KeyedService* KeyedServiceFactory::Associate(
- base::SupportsUserData* context,
+ void* context,
std::unique_ptr<KeyedService> service) {
DCHECK(!base::ContainsKey(mapping_, context));
auto iterator = mapping_.emplace(context, std::move(service)).first;
return iterator->second.get();
}
-void KeyedServiceFactory::Disassociate(base::SupportsUserData* context) {
+void KeyedServiceFactory::Disassociate(void* context) {
auto iterator = mapping_.find(context);
if (iterator != mapping_.end())
mapping_.erase(iterator);
}
-void KeyedServiceFactory::ContextShutdown(base::SupportsUserData* context) {
+void KeyedServiceFactory::ContextShutdown(void* context) {
auto iterator = mapping_.find(context);
if (iterator != mapping_.end() && iterator->second)
iterator->second->Shutdown();
}
-void KeyedServiceFactory::ContextDestroyed(base::SupportsUserData* context) {
+void KeyedServiceFactory::ContextDestroyed(void* context) {
Disassociate(context);
// For unit tests, we also remove the factory function both so we don't
@@ -124,15 +114,10 @@ void KeyedServiceFactory::ContextDestroyed(base::SupportsUserData* context) {
KeyedServiceBaseFactory::ContextDestroyed(context);
}
-void KeyedServiceFactory::SetEmptyTestingFactory(
- base::SupportsUserData* context) {
+void KeyedServiceFactory::SetEmptyTestingFactory(void* context) {
SetTestingFactory(context, TestingFactory());
}
-bool KeyedServiceFactory::HasTestingFactory(base::SupportsUserData* context) {
+bool KeyedServiceFactory::HasTestingFactory(void* context) {
return base::ContainsKey(testing_factories_, context);
}
-
-void KeyedServiceFactory::CreateServiceNow(base::SupportsUserData* context) {
- GetServiceForContext(context, true);
-}
diff --git a/chromium/components/keyed_service/core/keyed_service_factory.h b/chromium/components/keyed_service/core/keyed_service_factory.h
index cc82b150872..b6d8e300959 100644
--- a/chromium/components/keyed_service/core/keyed_service_factory.h
+++ b/chromium/components/keyed_service/core/keyed_service_factory.h
@@ -17,9 +17,9 @@
class DependencyManager;
class KeyedService;
-// Base class for Factories that take a base::SupportsUserData object and return
-// some service on a one-to-one mapping. Each concrete factory that derives from
-// this class *must* be a Singleton (only unit tests don't do that).
+// Base class for Factories that take an opaque pointer and return some service
+// on a one-to-one mapping. Each concrete factory that derives from this class
+// *must* be a Singleton (only unit tests don't do that).
//
// We do this because services depend on each other and we need to control
// shutdown/destruction order. In each derived classes' constructors, the
@@ -33,61 +33,64 @@ class KEYED_SERVICE_EXPORT KeyedServiceFactory
// A callback that supplies the instance of a KeyedService for a given
// |context|. This is used primarily for testing, where we want to feed
// a specific test double into the KeyedServiceFactory system.
- using TestingFactory = base::RepeatingCallback<std::unique_ptr<KeyedService>(
- base::SupportsUserData* context)>;
+ using TestingFactory =
+ base::RepeatingCallback<std::unique_ptr<KeyedService>(void* context)>;
// Associates |testing_factory| with |context| so that |testing_factory| is
// used to create the KeyedService when requested. |testing_factory| can be
// empty to signal that KeyedService should be null. Multiple calls to
// SetTestingFactory() are allowed; previous services will be shut down.
- void SetTestingFactory(base::SupportsUserData* context,
- TestingFactory testing_factory);
+ void SetTestingFactory(void* context, TestingFactory testing_factory);
// Associates |testing_factory| with |context| and immediately returns the
// created KeyedService. Since the factory will be used immediately, it may
// not be empty.
- KeyedService* SetTestingFactoryAndUse(base::SupportsUserData* context,
+ KeyedService* SetTestingFactoryAndUse(void* context,
+ void* side_parameter,
TestingFactory testing_factory);
// Common implementation that maps |context| to some service object. Deals
// with incognito contexts per subclass instructions with GetContextToUse()
// method on the base. If |create| is true, the service will be created
- // using BuildServiceInstanceFor() if it doesn't already exist.
- KeyedService* GetServiceForContext(base::SupportsUserData* context,
+ // using BuildServiceInstanceFor() if it doesn't already exist. Subclasses
+ // could pass |side_parameters| object if needed to create a service object.
+ KeyedService* GetServiceForContext(void* context,
+ void* side_parameter,
bool create);
// Maps |context| to |service| with debug checks to prevent duplication and
// returns a raw pointer to |service|.
- KeyedService* Associate(base::SupportsUserData* context,
- std::unique_ptr<KeyedService> service);
+ KeyedService* Associate(void* context, std::unique_ptr<KeyedService> service);
// Removes the mapping from |context| to a service.
- void Disassociate(base::SupportsUserData* context);
+ void Disassociate(void* context);
- // Returns a new KeyedService that will be associated with |context|.
+ // Returns a new KeyedService that will be associated with |context|. The
+ // |side_parameter| could be nullptr or some object required to create a
+ // service instance.
virtual std::unique_ptr<KeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const = 0;
+ void* context,
+ void* side_parameter) const = 0;
// Returns whether the |context| is off-the-record or not.
- virtual bool IsOffTheRecord(base::SupportsUserData* context) const = 0;
+ virtual bool IsOffTheRecord(void* context) const = 0;
// KeyedServiceBaseFactory:
- void ContextShutdown(base::SupportsUserData* context) override;
- void ContextDestroyed(base::SupportsUserData* context) override;
+ void ContextShutdown(void* context) override;
+ void ContextDestroyed(void* context) override;
- void SetEmptyTestingFactory(base::SupportsUserData* context) override;
- bool HasTestingFactory(base::SupportsUserData* context) override;
- void CreateServiceNow(base::SupportsUserData* context) override;
+ void SetEmptyTestingFactory(void* context) override;
+ bool HasTestingFactory(void* context) override;
private:
friend class DependencyManager;
friend class DependencyManagerUnittests;
// The mapping between a context and its service.
- std::map<base::SupportsUserData*, std::unique_ptr<KeyedService>> mapping_;
+ std::map<void*, std::unique_ptr<KeyedService>> mapping_;
// The mapping between a context and its overridden TestingFactory.
- std::map<base::SupportsUserData*, TestingFactory> testing_factories_;
+ std::map<void*, TestingFactory> testing_factories_;
DISALLOW_COPY_AND_ASSIGN(KeyedServiceFactory);
};
diff --git a/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc
index f7c4f9c642a..a40650f0aa0 100644
--- a/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.cc
@@ -20,14 +20,8 @@ RefcountedKeyedServiceFactory::~RefcountedKeyedServiceFactory() {
}
void RefcountedKeyedServiceFactory::SetTestingFactory(
- base::SupportsUserData* context,
+ void* context,
TestingFactory testing_factory) {
- // Destroying the context may cause us to lose data about whether |context|
- // has our preferences registered on it (since the context object itself
- // isn't dead). See if we need to readd it once we've gone through normal
- // destruction.
- bool add_context = ArePreferencesSetOn(context);
-
// Ensure that |context| is not marked as stale (e.g., due to it aliasing an
// instance that was destroyed in an earlier test) in order to avoid accesses
// to |context| in |ContextShutdown| from causing
@@ -40,25 +34,23 @@ void RefcountedKeyedServiceFactory::SetTestingFactory(
ContextShutdown(context);
ContextDestroyed(context);
- if (add_context)
- MarkPreferencesSetOn(context);
-
testing_factories_.emplace(context, std::move(testing_factory));
}
scoped_refptr<RefcountedKeyedService>
RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
- base::SupportsUserData* context,
+ void* context,
+ void* side_parameter,
TestingFactory testing_factory) {
DCHECK(testing_factory);
SetTestingFactory(context, std::move(testing_factory));
- return GetServiceForContext(context, true);
+ return GetServiceForContext(context, side_parameter, true);
}
scoped_refptr<RefcountedKeyedService>
-RefcountedKeyedServiceFactory::GetServiceForContext(
- base::SupportsUserData* context,
- bool create) {
+RefcountedKeyedServiceFactory::GetServiceForContext(void* context,
+ void* side_parameter,
+ bool create) {
context = GetContextToUse(context);
if (!context)
return nullptr;
@@ -80,27 +72,24 @@ RefcountedKeyedServiceFactory::GetServiceForContext(
auto factory_iterator = testing_factories_.find(context);
if (factory_iterator != testing_factories_.end()) {
if (factory_iterator->second) {
- if (!IsOffTheRecord(context))
- RegisterUserPrefsOnContextForTest(context);
service = factory_iterator->second.Run(context);
}
} else {
- service = BuildServiceInstanceFor(context);
+ service = BuildServiceInstanceFor(context, side_parameter);
}
return Associate(context, std::move(service));
}
scoped_refptr<RefcountedKeyedService> RefcountedKeyedServiceFactory::Associate(
- base::SupportsUserData* context,
+ void* context,
scoped_refptr<RefcountedKeyedService> service) {
DCHECK(!base::ContainsKey(mapping_, context));
auto iterator = mapping_.emplace(context, std::move(service)).first;
return iterator->second;
}
-void RefcountedKeyedServiceFactory::Disassociate(
- base::SupportsUserData* context) {
+void RefcountedKeyedServiceFactory::Disassociate(void* context) {
// We "merely" drop our reference to the service. Hopefully this will cause
// the service to be destroyed. If not, oh well.
auto iterator = mapping_.find(context);
@@ -108,15 +97,13 @@ void RefcountedKeyedServiceFactory::Disassociate(
mapping_.erase(iterator);
}
-void RefcountedKeyedServiceFactory::ContextShutdown(
- base::SupportsUserData* context) {
+void RefcountedKeyedServiceFactory::ContextShutdown(void* context) {
auto iterator = mapping_.find(context);
if (iterator != mapping_.end() && iterator->second.get())
iterator->second->ShutdownOnUIThread();
}
-void RefcountedKeyedServiceFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+void RefcountedKeyedServiceFactory::ContextDestroyed(void* context) {
Disassociate(context);
// For unit tests, we also remove the factory function both so we don't
@@ -128,17 +115,14 @@ void RefcountedKeyedServiceFactory::ContextDestroyed(
KeyedServiceBaseFactory::ContextDestroyed(context);
}
-void RefcountedKeyedServiceFactory::SetEmptyTestingFactory(
- base::SupportsUserData* context) {
+void RefcountedKeyedServiceFactory::SetEmptyTestingFactory(void* context) {
SetTestingFactory(context, TestingFactory());
}
-bool RefcountedKeyedServiceFactory::HasTestingFactory(
- base::SupportsUserData* context) {
+bool RefcountedKeyedServiceFactory::HasTestingFactory(void* context) {
return base::ContainsKey(testing_factories_, context);
}
-void RefcountedKeyedServiceFactory::CreateServiceNow(
- base::SupportsUserData* context) {
- GetServiceForContext(context, true);
+void RefcountedKeyedServiceFactory::CreateServiceNow(void* context) {
+ GetServiceForContext(context, nullptr /* side_parameter */, true);
}
diff --git a/chromium/components/keyed_service/core/refcounted_keyed_service_factory.h b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.h
index 7641934f7b5..07839e500c1 100644
--- a/chromium/components/keyed_service/core/refcounted_keyed_service_factory.h
+++ b/chromium/components/keyed_service/core/refcounted_keyed_service_factory.h
@@ -34,62 +34,63 @@ class KEYED_SERVICE_EXPORT RefcountedKeyedServiceFactory
// a specific test double into the KeyedServiceFactory system.
using TestingFactory =
base::RepeatingCallback<scoped_refptr<RefcountedKeyedService>(
- base::SupportsUserData* context)>;
+ void* context)>;
// Associates |testing_factory| with |context| so that |testing_factory| is
// used to create the KeyedService when requested. |testing_factory| can be
// empty to signal that KeyedService should be null. Multiple calls to
// SetTestingFactory() are allowed; previous services will be shut down.
- void SetTestingFactory(base::SupportsUserData* context,
- TestingFactory testing_factory);
+ void SetTestingFactory(void* context, TestingFactory testing_factory);
// Associates |testing_factory| with |context| and immediately returns the
// created KeyedService. Since the factory will be used immediately, it may
// not be empty.
scoped_refptr<RefcountedKeyedService> SetTestingFactoryAndUse(
- base::SupportsUserData* context,
+ void* context,
+ void* side_parameter,
TestingFactory testing_factory);
// Common implementation that maps |context| to some service object. Deals
// with incognito contexts per subclass instructions with GetContextToUse()
// method on the base. If |create| is true, the service will be created
- // using BuildServiceInstanceFor() if it doesn't already exist.
- scoped_refptr<RefcountedKeyedService> GetServiceForContext(
- base::SupportsUserData* context,
- bool create);
+ // using BuildServiceInstanceFor() if it doesn't already exist. Subclasses
+ // could pass |side_parameters| object if needed to create a service object.
+ scoped_refptr<RefcountedKeyedService>
+ GetServiceForContext(void* context, void* side_parameter, bool create);
// Maps |context| to |service| with debug checks to prevent duplication and
// returns |service|.
scoped_refptr<RefcountedKeyedService> Associate(
- base::SupportsUserData* context,
+ void* context,
scoped_refptr<RefcountedKeyedService> service);
// Removes the mapping from |context| to a service.
- void Disassociate(base::SupportsUserData* context);
+ void Disassociate(void* context);
// Returns a new RefcountedKeyedService that will be associated with
- // |context|.
+ // |context|. The |side_parameter| could be nullptr or some object required
+ // to create a service instance.
virtual scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const = 0;
+ void* context,
+ void* side_parameter) const = 0;
// Returns whether the |context| is off-the-record or not.
- virtual bool IsOffTheRecord(base::SupportsUserData* context) const = 0;
+ virtual bool IsOffTheRecord(void* context) const = 0;
// KeyedServiceBaseFactory:
- void ContextShutdown(base::SupportsUserData* context) override;
- void ContextDestroyed(base::SupportsUserData* context) override;
+ void ContextShutdown(void* context) override;
+ void ContextDestroyed(void* context) override;
- void SetEmptyTestingFactory(base::SupportsUserData* context) override;
- bool HasTestingFactory(base::SupportsUserData* context) override;
- void CreateServiceNow(base::SupportsUserData* context) override;
+ void SetEmptyTestingFactory(void* context) override;
+ bool HasTestingFactory(void* context) override;
+ void CreateServiceNow(void* context) override;
private:
// The mapping between a context and its refcounted service.
- std::map<base::SupportsUserData*, scoped_refptr<RefcountedKeyedService>>
- mapping_;
+ std::map<void*, scoped_refptr<RefcountedKeyedService>> mapping_;
// The mapping between a context and its overridden TestingFactory.
- std::map<base::SupportsUserData*, TestingFactory> testing_factories_;
+ std::map<void*, TestingFactory> testing_factories_;
DISALLOW_COPY_AND_ASSIGN(RefcountedKeyedServiceFactory);
};
diff --git a/chromium/components/keyed_service/core/simple_dependency_manager.cc b/chromium/components/keyed_service/core/simple_dependency_manager.cc
new file mode 100644
index 00000000000..385ca3ac1b3
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_dependency_manager.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/keyed_service/core/simple_dependency_manager.h"
+
+#include "base/no_destructor.h"
+#include "base/trace_event/trace_event.h"
+#include "components/keyed_service/core/simple_factory_key.h"
+
+#ifndef NDEBUG
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+
+namespace {
+
+// Dumps dependency information about our simple keyed services
+// into a dot file in the browser context directory.
+const char kDumpSimpleDependencyGraphFlag[] = "dump-simple-graph";
+
+} // namespace
+#endif // NDEBUG
+
+void SimpleDependencyManager::DestroyKeyedServices(SimpleFactoryKey* key) {
+ DependencyManager::DestroyContextServices(key);
+}
+
+// static
+SimpleDependencyManager* SimpleDependencyManager::GetInstance() {
+ static base::NoDestructor<SimpleDependencyManager> factory;
+ return factory.get();
+}
+
+void SimpleDependencyManager::RegisterProfilePrefsForServices(
+ SimpleFactoryKey* key,
+ user_prefs::PrefRegistrySyncable* pref_registry) {
+ TRACE_EVENT0("browser",
+ "SimpleDependencyManager::RegisterProfilePrefsForServices");
+ RegisterPrefsForServices(key, pref_registry);
+}
+
+void SimpleDependencyManager::CreateServicesForTest(SimpleFactoryKey* key) {
+ TRACE_EVENT0("browser", "SimpleDependencyManager::CreateServices");
+ DependencyManager::CreateContextServices(key, true);
+}
+
+SimpleDependencyManager::SimpleDependencyManager() = default;
+
+SimpleDependencyManager::~SimpleDependencyManager() = default;
+
+#ifndef NDEBUG
+void SimpleDependencyManager::DumpContextDependencies(void* context) const {
+ // Whenever we try to build a destruction ordering, we should also dump a
+ // dependency graph to "/path/to/context/context-dependencies.dot".
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ kDumpSimpleDependencyGraphFlag)) {
+ base::FilePath dot_file =
+ static_cast<const SimpleFactoryKey*>(context)->path().AppendASCII(
+ "simple-dependencies.dot");
+ DumpDependenciesAsGraphviz("SimpleDependencyManager", dot_file);
+ }
+}
+#endif // NDEBUG
diff --git a/chromium/components/keyed_service/core/simple_dependency_manager.h b/chromium/components/keyed_service/core/simple_dependency_manager.h
new file mode 100644
index 00000000000..817a5ed530e
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_dependency_manager.h
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_DEPENDENCY_MANAGER_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_DEPENDENCY_MANAGER_H_
+
+#include "components/keyed_service/core/dependency_manager.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class SimpleFactoryKey;
+
+// A singleton that listens for owners of SimpleFactoryKey' destruction
+// notifications and rebroadcasts them to each SimpleKeyedBaseFactory in a safe
+// order based on the stated dependencies by each service.
+class KEYED_SERVICE_EXPORT SimpleDependencyManager : public DependencyManager {
+ public:
+ SimpleDependencyManager();
+
+ // Called by each owners of SimpleFactoryKey before it is destroyed in order
+ // to destroy all services associated with |key|.
+ void DestroyKeyedServices(SimpleFactoryKey* key);
+
+ static SimpleDependencyManager* GetInstance();
+
+ // Registers profile-specific preferences for all services via |registry|.
+ // |key| is used to prevent multiple registrations on the same BrowserContext
+ // in tests.
+ void RegisterProfilePrefsForServices(
+ SimpleFactoryKey* key,
+ user_prefs::PrefRegistrySyncable* pref_registry);
+
+ // Create services for test BrowserContexts - these contexts will not create
+ // services for any SimpleKeyedBaseFactories that return true from
+ // ServiceIsNULLWhileTesting().
+ void CreateServicesForTest(SimpleFactoryKey* key);
+
+ private:
+ ~SimpleDependencyManager() override;
+
+#ifndef NDEBUG
+ // DependencyManager:
+ void DumpContextDependencies(void* context) const final;
+#endif // NDEBUG
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_DEPENDENCY_MANAGER_H_
diff --git a/chromium/components/keyed_service/core/simple_factory_key.cc b/chromium/components/keyed_service/core/simple_factory_key.cc
new file mode 100644
index 00000000000..17d891c50e4
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_factory_key.cc
@@ -0,0 +1,11 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/keyed_service/core/simple_factory_key.h"
+
+SimpleFactoryKey::SimpleFactoryKey(const base::FilePath& path,
+ SimpleFactoryKey* original_key)
+ : path_(path), original_key_(original_key) {}
+
+SimpleFactoryKey::~SimpleFactoryKey() = default;
diff --git a/chromium/components/keyed_service/core/simple_factory_key.h b/chromium/components/keyed_service/core/simple_factory_key.h
new file mode 100644
index 00000000000..1274adff558
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_factory_key.h
@@ -0,0 +1,37 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_FACTORY_KEY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_FACTORY_KEY_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+// A key used by SimpleKeyedServiceFactory is used to associated the
+// KeyedService instances. It is a way to have KeyedService without depending on
+// a more complex context. It can be mixed with more heavy-weight
+// KeyedServiceFactories if there is a unique mapping between the
+// SimpleFactoryKey and the more complex context. This mapping is the
+// responsibility of the embedder.
+class KEYED_SERVICE_EXPORT SimpleFactoryKey {
+ public:
+ explicit SimpleFactoryKey(const base::FilePath& path,
+ SimpleFactoryKey* original_key = nullptr);
+ ~SimpleFactoryKey();
+
+ const base::FilePath& path() const { return path_; }
+ bool is_off_the_record() const { return original_key_ != nullptr; }
+ SimpleFactoryKey* original_key() { return original_key_; }
+
+ private:
+ base::FilePath path_;
+
+ // Points to the original (non off-the-record) SimpleFactoryKey.
+ SimpleFactoryKey* original_key_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleFactoryKey);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_FACTORY_KEY_H_
diff --git a/chromium/components/keyed_service/core/simple_keyed_service_factory.cc b/chromium/components/keyed_service/core/simple_keyed_service_factory.cc
new file mode 100644
index 00000000000..4582f9c7cda
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_keyed_service_factory.cc
@@ -0,0 +1,114 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/keyed_service/core/simple_keyed_service_factory.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/keyed_service/core/simple_dependency_manager.h"
+#include "components/keyed_service/core/simple_factory_key.h"
+
+void SimpleKeyedServiceFactory::SetTestingFactory(
+ SimpleFactoryKey* key,
+ TestingFactory testing_factory) {
+ KeyedServiceFactory::TestingFactory wrapped_factory;
+ if (testing_factory) {
+ wrapped_factory = base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(static_cast<SimpleFactoryKey*>(context));
+ },
+ std::move(testing_factory));
+ }
+ KeyedServiceFactory::SetTestingFactory(key, std::move(wrapped_factory));
+}
+
+KeyedService* SimpleKeyedServiceFactory::SetTestingFactoryAndUse(
+ SimpleFactoryKey* key,
+ PrefService* prefs,
+ TestingFactory testing_factory) {
+ DCHECK(testing_factory);
+ return KeyedServiceFactory::SetTestingFactoryAndUse(
+ key, prefs,
+ base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(static_cast<SimpleFactoryKey*>(context));
+ },
+ std::move(testing_factory)));
+}
+
+SimpleKeyedServiceFactory::SimpleKeyedServiceFactory(
+ const char* name,
+ SimpleDependencyManager* manager)
+ : KeyedServiceFactory(name, manager) {}
+
+SimpleKeyedServiceFactory::~SimpleKeyedServiceFactory() {}
+
+KeyedService* SimpleKeyedServiceFactory::GetServiceForKey(SimpleFactoryKey* key,
+ PrefService* prefs,
+ bool create) {
+ return KeyedServiceFactory::GetServiceForContext(key, prefs, create);
+}
+
+SimpleFactoryKey* SimpleKeyedServiceFactory::GetKeyToUse(
+ SimpleFactoryKey* key) const {
+ // TODO(crbug.com/701326): This DCHECK should be moved to GetContextToUse().
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ // Safe default for Incognito mode: no service.
+ if (key->is_off_the_record())
+ return nullptr;
+
+ return key;
+}
+
+void SimpleKeyedServiceFactory::SimpleContextShutdown(SimpleFactoryKey* key) {
+ KeyedServiceFactory::ContextShutdown(key);
+}
+
+void SimpleKeyedServiceFactory::SimpleContextDestroyed(SimpleFactoryKey* key) {
+ KeyedServiceFactory::ContextDestroyed(key);
+}
+
+std::unique_ptr<KeyedService>
+SimpleKeyedServiceFactory::BuildServiceInstanceFor(void* context,
+ void* side_parameter) const {
+ return BuildServiceInstanceFor(static_cast<SimpleFactoryKey*>(context),
+ static_cast<PrefService*>(side_parameter));
+}
+
+bool SimpleKeyedServiceFactory::IsOffTheRecord(void* context) const {
+ return static_cast<SimpleFactoryKey*>(context)->is_off_the_record();
+}
+
+void* SimpleKeyedServiceFactory::GetContextToUse(void* context) const {
+ AssertContextWasntDestroyed(context);
+ return GetKeyToUse(static_cast<SimpleFactoryKey*>(context));
+}
+
+bool SimpleKeyedServiceFactory::ServiceIsCreatedWithContext() const {
+ return false;
+}
+
+void SimpleKeyedServiceFactory::ContextShutdown(void* context) {
+ SimpleContextShutdown(static_cast<SimpleFactoryKey*>(context));
+}
+
+void SimpleKeyedServiceFactory::ContextDestroyed(void* context) {
+ SimpleContextDestroyed(static_cast<SimpleFactoryKey*>(context));
+}
+
+void SimpleKeyedServiceFactory::RegisterPrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ RegisterProfilePrefs(registry);
+}
+
+void SimpleKeyedServiceFactory::SetEmptyTestingFactory(void* context) {}
+
+bool SimpleKeyedServiceFactory::HasTestingFactory(void* context) {
+ return false;
+}
+
+void SimpleKeyedServiceFactory::CreateServiceNow(void* context) {}
diff --git a/chromium/components/keyed_service/core/simple_keyed_service_factory.h b/chromium/components/keyed_service/core/simple_keyed_service_factory.h
new file mode 100644
index 00000000000..18584bbb832
--- /dev/null
+++ b/chromium/components/keyed_service/core/simple_keyed_service_factory.h
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_KEYED_SERVICE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_KEYED_SERVICE_FACTORY_H_
+
+#include <memory>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+#include "components/keyed_service/core/keyed_service_factory.h"
+
+class KeyedService;
+class PrefService;
+class SimpleDependencyManager;
+class SimpleFactoryKey;
+
+// Base class for Factories that take a SimpleFactoryKey object and return some
+// service on a one-to-one mapping. Each factory that derives from this class
+// *must* be a Singleton (only unit tests don't do that).
+//
+// We do this because services depend on each other and we need to control
+// shutdown/destruction order. In each derived classes' constructors, the
+// implementors must explicitly state on which services they depend.
+class KEYED_SERVICE_EXPORT SimpleKeyedServiceFactory
+ : public KeyedServiceFactory {
+ public:
+ // A callback that supplies the instance of a KeyedService for a given
+ // SimpleFactoryKey. This is used primarily for testing, where we want to feed
+ // a specific test double into the SKSF system.
+ using TestingFactory = base::RepeatingCallback<std::unique_ptr<KeyedService>(
+ SimpleFactoryKey* key)>;
+
+ // Associates |testing_factory| with |key| so that |testing_factory| is
+ // used to create the KeyedService when requested. |testing_factory| can be
+ // empty to signal that KeyedService should be null. Multiple calls to
+ // SetTestingFactory() are allowed; previous services will be shut down.
+ void SetTestingFactory(SimpleFactoryKey* key, TestingFactory testing_factory);
+
+ // Associates |testing_factory| with |key| and immediately returns the
+ // created KeyedService. Since the factory will be used immediately, it may
+ // not be empty.
+ KeyedService* SetTestingFactoryAndUse(SimpleFactoryKey* key,
+ PrefService* prefs,
+ TestingFactory testing_factory);
+
+ protected:
+ SimpleKeyedServiceFactory(const char* name, SimpleDependencyManager* manager);
+ ~SimpleKeyedServiceFactory() override;
+
+ // Common implementation that maps |key| to some service object. Deals
+ // with incognito contexts per subclass instructions with
+ // GetBrowserContextRedirectedInIncognito() and
+ // GetBrowserContextOwnInstanceInIncognito() through the
+ // GetBrowserContextToUse() method on the base. If |create| is true, the
+ // service will be created using BuildServiceInstanceFor() if it doesn't
+ // already exist.
+ KeyedService* GetServiceForKey(SimpleFactoryKey* key,
+ PrefService* prefs,
+ bool create);
+
+ // Interface for people building a concrete FooServiceFactory: --------------
+
+ // Finds which SimpleFactoryKey (if any) to use.
+ virtual SimpleFactoryKey* GetKeyToUse(SimpleFactoryKey* key) const;
+
+ // Interface for people building a type of SimpleKeyedFactory: -------
+
+ // All subclasses of SimpleKeyedServiceFactory must return a
+ // KeyedService.
+ virtual std::unique_ptr<KeyedService> BuildServiceInstanceFor(
+ SimpleFactoryKey* key,
+ PrefService* prefs) const = 0;
+
+ // A helper object actually listens for notifications about BrowserContext
+ // destruction, calculates the order in which things are destroyed and then
+ // does a two pass shutdown.
+ //
+ // First, SimpleContextShutdown() is called on every ServiceFactory and will
+ // usually call KeyedService::Shutdown(), which gives each
+ // KeyedService a chance to remove dependencies on other
+ // services that it may be holding.
+ //
+ // Secondly, SimpleContextDestroyed() is called on every ServiceFactory
+ // and the default implementation removes it from |mapping_| and deletes
+ // the pointer.
+ virtual void SimpleContextShutdown(SimpleFactoryKey* key);
+ virtual void SimpleContextDestroyed(SimpleFactoryKey* key);
+
+ private:
+ // Registers any user preferences on this service. This is called by
+ // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
+ // that wants to register profile-specific preferences.
+ virtual void RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {}
+
+ // KeyedServiceFactory:
+ std::unique_ptr<KeyedService> BuildServiceInstanceFor(
+ void* context,
+ void* side_parameter) const final;
+ bool IsOffTheRecord(void* context) const final;
+
+ // KeyedServiceBaseFactory:
+ void* GetContextToUse(void* context) const final;
+ bool ServiceIsCreatedWithContext() const final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
+ void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+ void SetEmptyTestingFactory(void* context) final;
+ bool HasTestingFactory(void* context) final;
+ void CreateServiceNow(void* context) final;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleKeyedServiceFactory);
+};
+
+#endif // COMPONENTS_KEYED_SERVICE_CORE_SIMPLE_KEYED_SERVICE_FACTORY_H_
diff --git a/chromium/components/keyed_service/ios/browser_state_dependency_manager.cc b/chromium/components/keyed_service/ios/browser_state_dependency_manager.cc
index 7dcc8d9a720..d9c85772d38 100644
--- a/chromium/components/keyed_service/ios/browser_state_dependency_manager.cc
+++ b/chromium/components/keyed_service/ios/browser_state_dependency_manager.cc
@@ -60,6 +60,5 @@ void BrowserStateDependencyManager::DoCreateBrowserStateServices(
#ifndef NDEBUG
void BrowserStateDependencyManager::DumpContextDependencies(
- base::SupportsUserData* context) const {
-}
+ void* context) const {}
#endif // NDEBUG
diff --git a/chromium/components/keyed_service/ios/browser_state_dependency_manager.h b/chromium/components/keyed_service/ios/browser_state_dependency_manager.h
index 927f9a4e443..96c67436492 100644
--- a/chromium/components/keyed_service/ios/browser_state_dependency_manager.h
+++ b/chromium/components/keyed_service/ios/browser_state_dependency_manager.h
@@ -80,7 +80,7 @@ class KEYED_SERVICE_EXPORT BrowserStateDependencyManager
#ifndef NDEBUG
// DependencyManager:
- void DumpContextDependencies(base::SupportsUserData* context) const final;
+ void DumpContextDependencies(void* context) const final;
#endif // NDEBUG
DISALLOW_COPY_AND_ASSIGN(BrowserStateDependencyManager);
diff --git a/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc
index da2937af100..7f5b11bad3c 100644
--- a/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc
+++ b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.cc
@@ -16,8 +16,7 @@ void BrowserStateKeyedServiceFactory::SetTestingFactory(
KeyedServiceFactory::TestingFactory wrapped_factory;
if (testing_factory) {
wrapped_factory = base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
+ [](const TestingFactory& testing_factory, void* context) {
return testing_factory.Run(static_cast<web::BrowserState*>(context));
},
std::move(testing_factory));
@@ -30,13 +29,13 @@ KeyedService* BrowserStateKeyedServiceFactory::SetTestingFactoryAndUse(
TestingFactory testing_factory) {
DCHECK(testing_factory);
return KeyedServiceFactory::SetTestingFactoryAndUse(
- context, base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
- return testing_factory.Run(
- static_cast<web::BrowserState*>(context));
- },
- std::move(testing_factory)));
+ context, nullptr /* side_parameter */,
+ base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(
+ static_cast<web::BrowserState*>(context));
+ },
+ std::move(testing_factory)));
}
BrowserStateKeyedServiceFactory::BrowserStateKeyedServiceFactory(
@@ -51,7 +50,8 @@ BrowserStateKeyedServiceFactory::~BrowserStateKeyedServiceFactory() {
KeyedService* BrowserStateKeyedServiceFactory::GetServiceForBrowserState(
web::BrowserState* context,
bool create) {
- return KeyedServiceFactory::GetServiceForContext(context, create);
+ return KeyedServiceFactory::GetServiceForContext(
+ context, nullptr /* side_parameter */, create);
}
web::BrowserState* BrowserStateKeyedServiceFactory::GetBrowserStateToUse(
@@ -86,17 +86,16 @@ void BrowserStateKeyedServiceFactory::BrowserStateDestroyed(
std::unique_ptr<KeyedService>
BrowserStateKeyedServiceFactory::BuildServiceInstanceFor(
- base::SupportsUserData* context) const {
+ void* context,
+ void* side_parameter) const {
return BuildServiceInstanceFor(static_cast<web::BrowserState*>(context));
}
-bool BrowserStateKeyedServiceFactory::IsOffTheRecord(
- base::SupportsUserData* context) const {
+bool BrowserStateKeyedServiceFactory::IsOffTheRecord(void* context) const {
return static_cast<web::BrowserState*>(context)->IsOffTheRecord();
}
-base::SupportsUserData* BrowserStateKeyedServiceFactory::GetContextToUse(
- base::SupportsUserData* context) const {
+void* BrowserStateKeyedServiceFactory::GetContextToUse(void* context) const {
AssertContextWasntDestroyed(context);
return GetBrowserStateToUse(static_cast<web::BrowserState*>(context));
}
@@ -105,13 +104,11 @@ bool BrowserStateKeyedServiceFactory::ServiceIsCreatedWithContext() const {
return ServiceIsCreatedWithBrowserState();
}
-void BrowserStateKeyedServiceFactory::ContextShutdown(
- base::SupportsUserData* context) {
+void BrowserStateKeyedServiceFactory::ContextShutdown(void* context) {
BrowserStateShutdown(static_cast<web::BrowserState*>(context));
}
-void BrowserStateKeyedServiceFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+void BrowserStateKeyedServiceFactory::ContextDestroyed(void* context) {
BrowserStateDestroyed(static_cast<web::BrowserState*>(context));
}
@@ -119,3 +116,8 @@ void BrowserStateKeyedServiceFactory::RegisterPrefs(
user_prefs::PrefRegistrySyncable* registry) {
RegisterBrowserStatePrefs(registry);
}
+
+void BrowserStateKeyedServiceFactory::CreateServiceNow(void* context) {
+ KeyedServiceFactory::GetServiceForContext(context,
+ nullptr /* side_parameter */, true);
+}
diff --git a/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h
index a8539aca8c5..95711d32d0e 100644
--- a/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h
+++ b/chromium/components/keyed_service/ios/browser_state_keyed_service_factory.h
@@ -110,24 +110,24 @@ class KEYED_SERVICE_EXPORT BrowserStateKeyedServiceFactory
virtual void BrowserStateDestroyed(web::BrowserState* context);
private:
- // Registers any user preferences on this service. This is called by
- // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
- // that wants to register profile-specific preferences.
+ // Registers any user preferences on this service. This should be overriden by
+ // any service that wants to register profile-specific preferences.
virtual void RegisterBrowserStatePrefs(
user_prefs::PrefRegistrySyncable* registry) {}
// KeyedServiceFactory:
std::unique_ptr<KeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const final;
- bool IsOffTheRecord(base::SupportsUserData* context) const final;
+ void* context,
+ void* side_parameter) const final;
+ bool IsOffTheRecord(void* context) const final;
// KeyedServiceBaseFactory:
- base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const final;
+ void* GetContextToUse(void* context) const final;
bool ServiceIsCreatedWithContext() const final;
- void ContextShutdown(base::SupportsUserData* context) final;
- void ContextDestroyed(base::SupportsUserData* context) final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+ void CreateServiceNow(void* context) final;
DISALLOW_COPY_AND_ASSIGN(BrowserStateKeyedServiceFactory);
};
diff --git a/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc
index b17995462ea..1f838a549ae 100644
--- a/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc
+++ b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.cc
@@ -16,8 +16,7 @@ void RefcountedBrowserStateKeyedServiceFactory::SetTestingFactory(
RefcountedKeyedServiceFactory::TestingFactory wrapped_factory;
if (testing_factory) {
wrapped_factory = base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
+ [](const TestingFactory& testing_factory, void* context) {
return testing_factory.Run(static_cast<web::BrowserState*>(context));
},
std::move(testing_factory));
@@ -32,13 +31,13 @@ RefcountedBrowserStateKeyedServiceFactory::SetTestingFactoryAndUse(
TestingFactory testing_factory) {
DCHECK(testing_factory);
return RefcountedKeyedServiceFactory::SetTestingFactoryAndUse(
- context, base::BindRepeating(
- [](const TestingFactory& testing_factory,
- base::SupportsUserData* context) {
- return testing_factory.Run(
- static_cast<web::BrowserState*>(context));
- },
- std::move(testing_factory)));
+ context, nullptr /* side_parameter*/,
+ base::BindRepeating(
+ [](const TestingFactory& testing_factory, void* context) {
+ return testing_factory.Run(
+ static_cast<web::BrowserState*>(context));
+ },
+ std::move(testing_factory)));
}
RefcountedBrowserStateKeyedServiceFactory::
@@ -56,7 +55,8 @@ scoped_refptr<RefcountedKeyedService>
RefcountedBrowserStateKeyedServiceFactory::GetServiceForBrowserState(
web::BrowserState* context,
bool create) {
- return RefcountedKeyedServiceFactory::GetServiceForContext(context, create);
+ return RefcountedKeyedServiceFactory::GetServiceForContext(
+ context, nullptr /* side_parameter*/, create);
}
web::BrowserState*
@@ -94,18 +94,18 @@ void RefcountedBrowserStateKeyedServiceFactory::BrowserStateDestroyed(
scoped_refptr<RefcountedKeyedService>
RefcountedBrowserStateKeyedServiceFactory::BuildServiceInstanceFor(
- base::SupportsUserData* context) const {
+ void* context,
+ void* side_parameter) const {
return BuildServiceInstanceFor(static_cast<web::BrowserState*>(context));
}
bool RefcountedBrowserStateKeyedServiceFactory::IsOffTheRecord(
- base::SupportsUserData* context) const {
+ void* context) const {
return static_cast<web::BrowserState*>(context)->IsOffTheRecord();
}
-base::SupportsUserData*
-RefcountedBrowserStateKeyedServiceFactory::GetContextToUse(
- base::SupportsUserData* context) const {
+void* RefcountedBrowserStateKeyedServiceFactory::GetContextToUse(
+ void* context) const {
AssertContextWasntDestroyed(context);
return GetBrowserStateToUse(static_cast<web::BrowserState*>(context));
}
@@ -115,13 +115,12 @@ bool RefcountedBrowserStateKeyedServiceFactory::ServiceIsCreatedWithContext()
return ServiceIsCreatedWithBrowserState();
}
-void RefcountedBrowserStateKeyedServiceFactory::ContextShutdown(
- base::SupportsUserData* context) {
+void RefcountedBrowserStateKeyedServiceFactory::ContextShutdown(void* context) {
BrowserStateShutdown(static_cast<web::BrowserState*>(context));
}
void RefcountedBrowserStateKeyedServiceFactory::ContextDestroyed(
- base::SupportsUserData* context) {
+ void* context) {
BrowserStateDestroyed(static_cast<web::BrowserState*>(context));
}
diff --git a/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h
index aa07a95465f..a0da0c05f33 100644
--- a/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h
+++ b/chromium/components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h
@@ -115,23 +115,22 @@ class KEYED_SERVICE_EXPORT RefcountedBrowserStateKeyedServiceFactory
virtual void BrowserStateDestroyed(web::BrowserState* context);
private:
- // Registers any user preferences on this service. This is called by
- // RegisterPrefsIfNecessaryForContext() and should be overriden by any service
- // that wants to register profile-specific preferences.
+ // Registers any user preferences on this service. This should be overriden by
+ // any service that wants to register profile-specific preferences.
virtual void RegisterBrowserStatePrefs(
user_prefs::PrefRegistrySyncable* registry) {}
// RefcountedKeyedServiceFactory:
scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
- base::SupportsUserData* context) const final;
- bool IsOffTheRecord(base::SupportsUserData* context) const final;
+ void* context,
+ void* side_parameter) const final;
+ bool IsOffTheRecord(void* context) const final;
// KeyedServiceBaseFactory:
- base::SupportsUserData* GetContextToUse(
- base::SupportsUserData* context) const final;
+ void* GetContextToUse(void* context) const final;
bool ServiceIsCreatedWithContext() const final;
- void ContextShutdown(base::SupportsUserData* context) final;
- void ContextDestroyed(base::SupportsUserData* context) final;
+ void ContextShutdown(void* context) final;
+ void ContextDestroyed(void* context) final;
void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
DISALLOW_COPY_AND_ASSIGN(RefcountedBrowserStateKeyedServiceFactory);
diff --git a/chromium/components/language/DEPS b/chromium/components/language/DEPS
index 63176428e4b..fcb6de95fa1 100644
--- a/chromium/components/language/DEPS
+++ b/chromium/components/language/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+components/pref_registry",
"+components/prefs",
+ "+components/strings/grit/components_locale_settings.h",
"+third_party/s2cellid",
"-components/language/content",
diff --git a/chromium/components/language/content/browser/geo_language_model_unittest.cc b/chromium/components/language/content/browser/geo_language_model_unittest.cc
index fe0d8b2e23b..1e259ff206d 100644
--- a/chromium/components/language/content/browser/geo_language_model_unittest.cc
+++ b/chromium/components/language/content/browser/geo_language_model_unittest.cc
@@ -4,6 +4,7 @@
#include "components/language/content/browser/geo_language_model.h"
+#include "base/bind.h"
#include "base/macros.h"
#include "base/test/scoped_task_environment.h"
#include "base/timer/timer.h"
diff --git a/chromium/components/language/content/browser/geo_language_provider.cc b/chromium/components/language/content/browser/geo_language_provider.cc
index 1dbf51e9e0a..fd647ef7225 100644
--- a/chromium/components/language/content/browser/geo_language_provider.cc
+++ b/chromium/components/language/content/browser/geo_language_provider.cc
@@ -4,6 +4,7 @@
#include "components/language/content/browser/geo_language_provider.h"
+#include "base/bind.h"
#include "base/memory/singleton.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
@@ -13,6 +14,7 @@
#include "components/prefs/pref_service.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/device/public/mojom/constants.mojom.h"
+#include "services/device/public/mojom/geoposition.mojom.h"
#include "services/device/public/mojom/public_ip_address_geolocation_provider.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
diff --git a/chromium/components/language/content/browser/geo_language_provider_unittest.cc b/chromium/components/language/content/browser/geo_language_provider_unittest.cc
index 8693e600bb0..bc4af9db1fe 100644
--- a/chromium/components/language/content/browser/geo_language_provider_unittest.cc
+++ b/chromium/components/language/content/browser/geo_language_provider_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/language/content/browser/language_code_locator.h b/chromium/components/language/content/browser/language_code_locator.h
index 368392dcbd2..1947d6d7dde 100644
--- a/chromium/components/language/content/browser/language_code_locator.h
+++ b/chromium/components/language/content/browser/language_code_locator.h
@@ -14,7 +14,7 @@ namespace language {
class LanguageCodeLocator {
public:
- virtual ~LanguageCodeLocator(){};
+ virtual ~LanguageCodeLocator() {}
// Get suitable language codes given a coordinate.
// If the latitude, longitude pair is not found, will return an empty vector.
virtual std::vector<std::string> GetLanguageCodes(double latitude,
diff --git a/chromium/components/language/content/browser/test_utils.h b/chromium/components/language/content/browser/test_utils.h
index a0c9593e49e..74310cabe27 100644
--- a/chromium/components/language/content/browser/test_utils.h
+++ b/chromium/components/language/content/browser/test_utils.h
@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/device/public/mojom/geolocation.mojom.h"
+#include "services/device/public/mojom/geoposition.mojom.h"
#include "services/device/public/mojom/public_ip_address_geolocation_provider.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/mojom/connector.mojom.h"
diff --git a/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree.h b/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree.h
index efee31ec319..a7ff935f1f0 100644
--- a/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree.h
+++ b/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree.h
@@ -23,7 +23,7 @@ class S2CellId;
// absent language.
class SerializedLanguageTree {
public:
- virtual ~SerializedLanguageTree(){};
+ virtual ~SerializedLanguageTree() {}
virtual std::string GetLanguageAt(const size_t pos) const = 0;
virtual size_t GetNumLanguages() const = 0;
@@ -42,7 +42,7 @@ class BitsetSerializedLanguageTree : public SerializedLanguageTree {
BitsetSerializedLanguageTree(std::vector<std::string> languages,
std::bitset<numbits> bits)
: languages_(languages), bits_(bits) {}
- ~BitsetSerializedLanguageTree() override{};
+ ~BitsetSerializedLanguageTree() override {}
// SerializedTree implementation
std::string GetLanguageAt(const size_t pos) const override {
diff --git a/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree_datatest.cc b/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree_datatest.cc
index 8e0f876ef6c..c13297e9103 100644
--- a/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree_datatest.cc
+++ b/chromium/components/language/content/browser/ulp_language_code_locator/s2langquadtree_datatest.cc
@@ -38,9 +38,6 @@ const std::map<S2LatLng, std::string> GetData(int rank) {
std::vector<std::string> lines = base::SplitString(
data, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
for (size_t i = 0; i < lines.size(); ++i) {
- // TODO(frechette) Remove once we ensured no empty line in data file.
- if (lines[i].empty())
- continue;
std::vector<std::string> fields = base::SplitString(
lines[i], ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
CHECK_EQ(3u, fields.size());
diff --git a/chromium/components/language/core/browser/BUILD.gn b/chromium/components/language/core/browser/BUILD.gn
index 02acc883e9d..bd59d2b4075 100644
--- a/chromium/components/language/core/browser/BUILD.gn
+++ b/chromium/components/language/core/browser/BUILD.gn
@@ -12,6 +12,8 @@ static_library("browser") {
"language_model.h",
"language_model_manager.cc",
"language_model_manager.h",
+ "language_prefs.cc",
+ "language_prefs.h",
"locale_util.cc",
"locale_util.h",
"pref_names.cc",
@@ -25,6 +27,7 @@ static_library("browser") {
"//components/keyed_service/core",
"//components/pref_registry",
"//components/prefs",
+ "//components/strings",
"//ui/base",
]
}
diff --git a/chromium/components/language/core/browser/heuristic_language_model_unittest.cc b/chromium/components/language/core/browser/heuristic_language_model_unittest.cc
index 3021ae1edf8..073ea950e15 100644
--- a/chromium/components/language/core/browser/heuristic_language_model_unittest.cc
+++ b/chromium/components/language/core/browser/heuristic_language_model_unittest.cc
@@ -341,7 +341,8 @@ TEST(GetHistogramLanguagesTest, FrequencyCutoff) {
// Test with no ULP languages.
TEST(GetUlpLanguagesTest, Empty) {
- const auto dict = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto dict =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 1.0,
"preference": []
@@ -353,7 +354,8 @@ TEST(GetUlpLanguagesTest, Empty) {
// Test that ULP profile of insufficient confidence is ignored.
TEST(GetUlpLanguagesTest, ConfidenceCutoff) {
- const auto dict = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto dict =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 0.5,
"preference": [{"language": "en", "probability": 1.0}]
@@ -367,7 +369,8 @@ TEST(GetUlpLanguagesTest, ConfidenceCutoff) {
// Test that ULP languages of insufficient probability are ignored.
TEST(GetUlpLanguagesTest, ProbabilityCutoff) {
- const auto dict = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto dict =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 1.0,
"preference": [{"language": "en", "probability": 1.00},
@@ -389,24 +392,28 @@ TEST(GetUlpLanguagesTest, ProbabilityCutoff) {
// Test that malformed ULP data is handled gracefully.
TEST(GetUlpLanguagesTest, Malformed) {
- const auto empty = base::DictionaryValue::From(base::JSONReader::Read("{}"));
+ const auto empty =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated("{}"));
EXPECT_THAT(GetUlpLanguages(0.0, 0.0, empty.get()), IsEmpty());
- const auto conf = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto conf =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"preference": [{"language": "en", "probability": 1.00}]
}
})"));
EXPECT_THAT(GetUlpLanguages(0.0, 0.0, conf.get()), IsEmpty());
- const auto no_prefs = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto no_prefs =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 1.0
}
})"));
EXPECT_THAT(GetUlpLanguages(0.0, 0.0, no_prefs.get()), IsEmpty());
- const auto bad_prefs = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto bad_prefs =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 1.0,
"preference": [{"language": "en"}, {"probability": 1.0},
@@ -439,7 +446,8 @@ TEST(HeuristicLanguageModelTest, PrefReading) {
// Set up ULP languages.
registry->RegisterDictionaryPref(ulp_pref);
- const auto ulp_value = base::DictionaryValue::From(base::JSONReader::Read(R"({
+ const auto ulp_value =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(R"({
"reading": {
"confidence": 1.0,
"preference": [{"language": "en-US", "probability": 1.0}]
diff --git a/chromium/components/language/core/browser/language_prefs.cc b/chromium/components/language/core/browser/language_prefs.cc
new file mode 100644
index 00000000000..bc2dc11af14
--- /dev/null
+++ b/chromium/components/language/core/browser/language_prefs.cc
@@ -0,0 +1,29 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/language/core/browser/language_prefs.h"
+
+#include "components/language/core/browser/pref_names.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/strings/grit/components_locale_settings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace language {
+
+const char kFallbackInputMethodLocale[] = "en-US";
+
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterStringPref(language::prefs::kAcceptLanguages,
+ l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES),
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+#if defined(OS_CHROMEOS)
+ registry->RegisterStringPref(language::prefs::kPreferredLanguages,
+ kFallbackInputMethodLocale);
+
+ registry->RegisterStringPref(language::prefs::kPreferredLanguagesSyncable, "",
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+#endif
+}
+
+} // namespace language
diff --git a/chromium/components/language/core/browser/language_prefs.h b/chromium/components/language/core/browser/language_prefs.h
new file mode 100644
index 00000000000..296ed932435
--- /dev/null
+++ b/chromium/components/language/core/browser/language_prefs.h
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_LANGUAGE_CORE_BROWSER_LANGUAGE_PREFS_H_
+#define COMPONENTS_LANGUAGE_CORE_BROWSER_LANGUAGE_PREFS_H_
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+namespace language {
+
+extern const char kFallbackInputMethodLocale[];
+
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+} // namespace language
+
+#endif // COMPONENTS_LANGUAGE_CORE_BROWSER_LANGUAGE_PREFS_H_
diff --git a/chromium/components/language/core/browser/pref_names.cc b/chromium/components/language/core/browser/pref_names.cc
index 875577a326d..f2c821ec16d 100644
--- a/chromium/components/language/core/browser/pref_names.cc
+++ b/chromium/components/language/core/browser/pref_names.cc
@@ -7,6 +7,16 @@
namespace language {
namespace prefs {
+// The value to use for Accept-Languages HTTP header when making an HTTP
+// request.
+const char kAcceptLanguages[] = "intl.accept_languages";
+
+// A string pref (comma-separated list) set to the preferred language IDs
+// (ex. "en-US,fr,ko").
+const char kPreferredLanguages[] = "settings.language.preferred_languages";
+const char kPreferredLanguagesSyncable[] =
+ "settings.language.preferred_languages_syncable";
+
// The JSON representation of the user's language profile. Used as an input to
// the user language model (i.e. for determining which languages a user
// understands).
diff --git a/chromium/components/language/core/browser/pref_names.h b/chromium/components/language/core/browser/pref_names.h
index 56923e276f8..a15a8b9c683 100644
--- a/chromium/components/language/core/browser/pref_names.h
+++ b/chromium/components/language/core/browser/pref_names.h
@@ -8,7 +8,11 @@
namespace language {
namespace prefs {
-// TODO(martis): Add accept language preference here.
+extern const char kAcceptLanguages[];
+
+extern const char kPreferredLanguages[];
+extern const char kPreferredLanguagesSyncable[];
+
extern const char kUserLanguageProfile[];
// The application locale.
diff --git a/chromium/components/language/core/common/BUILD.gn b/chromium/components/language/core/common/BUILD.gn
index 7ee80f982d7..2a11b2eb538 100644
--- a/chromium/components/language/core/common/BUILD.gn
+++ b/chromium/components/language/core/common/BUILD.gn
@@ -6,6 +6,8 @@ static_library("common") {
sources = [
"language_experiments.cc",
"language_experiments.h",
+ "language_util.cc",
+ "language_util.h",
"locale_util.cc",
"locale_util.h",
]
@@ -19,6 +21,7 @@ static_library("common") {
source_set("unit_tests") {
testonly = true
sources = [
+ "language_util_unittest.cc",
"locale_util_unittest.cc",
]
deps = [
diff --git a/chromium/components/language/core/common/language_util.cc b/chromium/components/language/core/common/language_util.cc
new file mode 100644
index 00000000000..f7bf44976c6
--- /dev/null
+++ b/chromium/components/language/core/common/language_util.cc
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/language/core/common/language_util.h"
+
+#include <stddef.h>
+#include <algorithm>
+
+#include "base/stl_util.h"
+#include "components/language/core/common/locale_util.h"
+
+namespace language {
+
+struct LanguageCodePair {
+ // Code used in supporting list of Translate.
+ const char* const translate_language;
+
+ // Code used in Chrome internal.
+ const char* const chrome_language;
+};
+
+// Some languages are treated as same languages in Translate even though they
+// are different to be exact.
+//
+// If this table is updated, please sync this with the synonym table in
+// chrome/browser/resources/settings/languages_page/languages.js.
+const LanguageCodePair kLanguageCodeSimilitudes[] = {
+ {"no", "nb"},
+ {"tl", "fil"},
+};
+
+// Some languages have changed codes over the years and sometimes the older
+// codes are used, so we must see them as synonyms.
+//
+// If this table is updated, please sync this with the synonym table in
+// chrome/browser/resources/settings/languages_page/languages.js.
+const LanguageCodePair kLanguageCodeSynonyms[] = {
+ {"iw", "he"},
+ {"jw", "jv"},
+};
+
+// Some Chinese language codes are compatible with zh-TW or zh-CN in terms of
+// Translate.
+//
+// If this table is updated, please sync this with the synonym table in
+// chrome/browser/resources/settings/languages_page/languages.js.
+const LanguageCodePair kLanguageCodeChineseCompatiblePairs[] = {
+ {"zh-TW", "zh-HK"},
+ {"zh-TW", "zh-MO"},
+ {"zh-CN", "zh-SG"},
+};
+
+void ToTranslateLanguageSynonym(std::string* language) {
+ for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) {
+ if (*language == kLanguageCodeSimilitudes[i].chrome_language) {
+ *language = kLanguageCodeSimilitudes[i].translate_language;
+ return;
+ }
+ }
+
+ std::string main_part, tail_part;
+ language::SplitIntoMainAndTail(*language, &main_part, &tail_part);
+ if (main_part.empty())
+ return;
+
+ // Chinese is a special case: we do not return the main_part only.
+ // There is not a single base language, but two: traditional and simplified.
+ // The kLanguageCodeChineseCompatiblePairs list contains the relation between
+ // various Chinese locales. We need to return the code from that mapping
+ // instead of the main_part.
+ // Note that "zh" does not have any mapping and as such we leave it as is. See
+ // https://crbug/798512 for more info.
+ for (size_t i = 0; i < base::size(kLanguageCodeChineseCompatiblePairs); ++i) {
+ if (*language == kLanguageCodeChineseCompatiblePairs[i].chrome_language) {
+ *language = kLanguageCodeChineseCompatiblePairs[i].translate_language;
+ return;
+ }
+ }
+ if (main_part == "zh") {
+ return;
+ }
+
+ // Apply linear search here because number of items in the list is just four.
+ for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) {
+ if (main_part == kLanguageCodeSynonyms[i].chrome_language) {
+ main_part = std::string(kLanguageCodeSynonyms[i].translate_language);
+ break;
+ }
+ }
+
+ *language = main_part;
+}
+
+void ToChromeLanguageSynonym(std::string* language) {
+ for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) {
+ if (*language == kLanguageCodeSimilitudes[i].translate_language) {
+ *language = kLanguageCodeSimilitudes[i].chrome_language;
+ return;
+ }
+ }
+
+ std::string main_part, tail_part;
+ language::SplitIntoMainAndTail(*language, &main_part, &tail_part);
+ if (main_part.empty())
+ return;
+
+ // Apply liner search here because number of items in the list is just four.
+ for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) {
+ if (main_part == kLanguageCodeSynonyms[i].translate_language) {
+ main_part = std::string(kLanguageCodeSynonyms[i].chrome_language);
+ break;
+ }
+ }
+
+ *language = main_part + tail_part;
+}
+} // namespace language
diff --git a/chromium/components/language/core/common/language_util.h b/chromium/components/language/core/common/language_util.h
new file mode 100644
index 00000000000..453a2709590
--- /dev/null
+++ b/chromium/components/language/core/common/language_util.h
@@ -0,0 +1,24 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_
+#define COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_
+
+#include <string>
+
+namespace language {
+
+// Converts language code synonym to use at Translate server.
+//
+// The same logic exists in
+// chrome/browser/resources/settings/languages_page/languages.js,
+// please keep consistency with the JavaScript file.
+void ToTranslateLanguageSynonym(std::string* language);
+
+// Converts language code synonym to use at Chrome internal.
+void ToChromeLanguageSynonym(std::string* language);
+
+} // namespace language
+
+#endif // COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_
diff --git a/chromium/components/language/core/common/language_util_unittest.cc b/chromium/components/language/core/common/language_util_unittest.cc
new file mode 100644
index 00000000000..20eff9b9aac
--- /dev/null
+++ b/chromium/components/language/core/common/language_util_unittest.cc
@@ -0,0 +1,65 @@
+// 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/language/core/common/language_util.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+typedef testing::Test LanguageUtilTest;
+
+// Tests that synonym language code is converted to one used in supporting list.
+TEST_F(LanguageUtilTest, ToTranslateLanguageSynonym) {
+ std::string language;
+
+ language = std::string("nb");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("no", language);
+
+ // Test all known Chinese cases.
+ language = std::string("zh-HK");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("zh-TW", language);
+ language = std::string("zh-MO");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("zh-TW", language);
+ language = std::string("zh-SG");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("zh-CN", language);
+ language = std::string("zh");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("zh", language);
+
+ // A sub code is not preserved (except for Chinese).
+ language = std::string("he-IL");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("iw", language);
+
+ language = std::string("zh-JP");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("zh-JP", language);
+
+ // Preserve the argument if it doesn't have its synonym.
+ language = std::string("en");
+ language::ToTranslateLanguageSynonym(&language);
+ EXPECT_EQ("en", language);
+}
+
+// Tests that synonym language code is converted to one used in Chrome internal.
+TEST_F(LanguageUtilTest, ToChromeLanguageSynonym) {
+ std::string language;
+
+ language = std::string("no");
+ language::ToChromeLanguageSynonym(&language);
+ EXPECT_EQ("nb", language);
+
+ // Preserve a sub code
+ language = std::string("iw-IL");
+ language::ToChromeLanguageSynonym(&language);
+ EXPECT_EQ("he-IL", language);
+
+ // Preserve the argument if it doesn't have its synonym.
+ language = std::string("en");
+ language::ToChromeLanguageSynonym(&language);
+ EXPECT_EQ("en", language);
+} \ No newline at end of file
diff --git a/chromium/components/language/ios/browser/ios_language_detection_tab_helper.h b/chromium/components/language/ios/browser/ios_language_detection_tab_helper.h
index 9e04a1cca28..181217a69a9 100644
--- a/chromium/components/language/ios/browser/ios_language_detection_tab_helper.h
+++ b/chromium/components/language/ios/browser/ios_language_detection_tab_helper.h
@@ -50,6 +50,8 @@ class IOSLanguageDetectionTabHelper
Callback extra_callback_for_testing_;
+ WEB_STATE_USER_DATA_KEY_DECL();
+
DISALLOW_COPY_AND_ASSIGN(IOSLanguageDetectionTabHelper);
};
diff --git a/chromium/components/language/ios/browser/ios_language_detection_tab_helper.mm b/chromium/components/language/ios/browser/ios_language_detection_tab_helper.mm
index ef99826ae3e..9d4b04db04a 100644
--- a/chromium/components/language/ios/browser/ios_language_detection_tab_helper.mm
+++ b/chromium/components/language/ios/browser/ios_language_detection_tab_helper.mm
@@ -51,4 +51,6 @@ void IOSLanguageDetectionTabHelper::SetExtraCallbackForTesting(
extra_callback_for_testing_ = callback;
}
+WEB_STATE_USER_DATA_KEY_IMPL(IOSLanguageDetectionTabHelper)
+
} // namespace language
diff --git a/chromium/components/leveldb_proto/BUILD.gn b/chromium/components/leveldb_proto/BUILD.gn
index 13e078bf551..fb521c3c645 100644
--- a/chromium/components/leveldb_proto/BUILD.gn
+++ b/chromium/components/leveldb_proto/BUILD.gn
@@ -16,9 +16,12 @@ static_library("leveldb_proto") {
"internal/leveldb_database.h",
"internal/leveldb_proto_feature_list.cc",
"internal/leveldb_proto_feature_list.h",
+ "internal/migration_delegate.cc",
"internal/migration_delegate.h",
- "internal/proto_database_wrapper.cc",
- "internal/proto_database_wrapper.h",
+ "internal/proto_database_impl.cc",
+ "internal/proto_database_impl.h",
+ "internal/proto_database_selector.cc",
+ "internal/proto_database_selector.h",
"internal/proto_leveldb_wrapper.cc",
"internal/proto_leveldb_wrapper.h",
"internal/proto_leveldb_wrapper_metrics.cc",
@@ -29,6 +32,7 @@ static_library("leveldb_proto") {
"internal/shared_proto_database_client.h",
"internal/shared_proto_database_provider.cc",
"internal/shared_proto_database_provider.h",
+ "internal/unique_proto_database.cc",
"internal/unique_proto_database.h",
"public/proto_database.cc",
"public/proto_database.h",
@@ -65,7 +69,7 @@ source_set("test_support") {
source_set("unit_tests") {
testonly = true
sources = [
- "internal/proto_database_wrapper_unittest.cc",
+ "internal/proto_database_impl_unittest.cc",
"internal/shared_proto_database_client_list_unittest.cc",
"internal/shared_proto_database_client_unittest.cc",
"internal/shared_proto_database_unittest.cc",
diff --git a/chromium/components/leveldb_proto/OWNERS b/chromium/components/leveldb_proto/OWNERS
index f473a874c71..a120a02d330 100644
--- a/chromium/components/leveldb_proto/OWNERS
+++ b/chromium/components/leveldb_proto/OWNERS
@@ -1,4 +1,5 @@
mathp@chromium.org
nyquist@chromium.org
+ssid@chromium.org
# COMPONENT: Internals
diff --git a/chromium/components/leveldb_proto/internal/leveldb_database.cc b/chromium/components/leveldb_proto/internal/leveldb_database.cc
index 8736bde8f10..73df41b4450 100644
--- a/chromium/components/leveldb_proto/internal/leveldb_database.cc
+++ b/chromium/components/leveldb_proto/internal/leveldb_database.cc
@@ -39,18 +39,13 @@ bool PrefixStopCallback(const std::string& prefix, const std::string& key) {
return base::StartsWith(key, prefix, base::CompareCase::SENSITIVE);
}
-LevelDB::LevelDB(const char* client_name)
- : open_histogram_(nullptr), destroy_histogram_(nullptr) {
+LevelDB::LevelDB(const char* client_name) : open_histogram_(nullptr) {
// Used in lieu of UMA_HISTOGRAM_ENUMERATION because the histogram name is
// not a constant.
open_histogram_ = base::LinearHistogram::FactoryGet(
std::string("LevelDB.Open.") + client_name, 1,
leveldb_env::LEVELDB_STATUS_MAX, leveldb_env::LEVELDB_STATUS_MAX + 1,
base::Histogram::kUmaTargetedHistogramFlag);
- destroy_histogram_ = base::LinearHistogram::FactoryGet(
- std::string("LevelDB.Destroy.") + client_name, 1,
- leveldb_env::LEVELDB_STATUS_MAX, leveldb_env::LEVELDB_STATUS_MAX + 1,
- base::Histogram::kUmaTargetedHistogramFlag);
approx_memtable_mem_histogram_ = base::LinearHistogram::FactoryGet(
std::string("LevelDB.ApproximateMemTableMemoryUse.") + client_name, 1,
kMaxApproxMemoryUseMB * 1048576, kMaxApproxMemoryUseMB * 4,
@@ -312,8 +307,6 @@ leveldb::Status LevelDB::Destroy() {
leveldb::Status status = leveldb::DestroyDB(path, open_options_);
if (!status.ok())
LOG(WARNING) << "Unable to destroy " << path << ": " << status.ToString();
- if (destroy_histogram_)
- destroy_histogram_->Add(leveldb_env::GetLevelDBStatusUMAValue(status));
return status;
}
diff --git a/chromium/components/leveldb_proto/internal/leveldb_database.h b/chromium/components/leveldb_proto/internal/leveldb_database.h
index 9c6ee6b2a24..049f255a1f9 100644
--- a/chromium/components/leveldb_proto/internal/leveldb_database.h
+++ b/chromium/components/leveldb_proto/internal/leveldb_database.h
@@ -112,7 +112,6 @@ class LevelDB {
base::FilePath database_dir_;
leveldb_env::Options open_options_;
base::HistogramBase* open_histogram_;
- base::HistogramBase* destroy_histogram_;
base::HistogramBase* approx_memtable_mem_histogram_;
DISALLOW_COPY_AND_ASSIGN(LevelDB);
diff --git a/chromium/components/leveldb_proto/internal/migration_delegate.cc b/chromium/components/leveldb_proto/internal/migration_delegate.cc
new file mode 100644
index 00000000000..5ef800d0170
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/migration_delegate.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/leveldb_proto/internal/migration_delegate.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+
+namespace leveldb_proto {
+
+MigrationDelegate::MigrationDelegate() : weak_ptr_factory_(this) {}
+MigrationDelegate::~MigrationDelegate() = default;
+
+void MigrationDelegate::DoMigration(UniqueProtoDatabase* from,
+ UniqueProtoDatabase* to,
+ MigrationCallback callback) {
+ from->LoadKeysAndEntries(base::BindOnce(
+ &MigrationDelegate::OnLoadKeysAndEntries, weak_ptr_factory_.GetWeakPtr(),
+ std::move(callback), base::Unretained(to)));
+}
+
+void MigrationDelegate::OnLoadKeysAndEntries(
+ MigrationCallback callback,
+ UniqueProtoDatabase* to,
+ bool success,
+ std::unique_ptr<KeyValueMap> keys_entries) {
+ if (!success) {
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
+ current_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), false));
+ return;
+ }
+
+ // Convert the std::map we got back into a vector of std::pairs to be used
+ // with UpdateEntries.
+ auto kev = std::make_unique<KeyValueVector>();
+ for (auto const& key_entry : *keys_entries)
+ kev->push_back(key_entry);
+
+ // Save the entries in |to|.
+ to->UpdateEntries(
+ std::move(kev), std::make_unique<KeyVector>(),
+ base::BindOnce(&MigrationDelegate::OnUpdateEntries,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void MigrationDelegate::OnUpdateEntries(MigrationCallback callback,
+ bool success) {
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
+ current_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), success));
+ // TODO (thildebr): For additional insurance, verify the entries match,
+ // although they should if we got a success from UpdateEntries.
+}
+
+} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/migration_delegate.h b/chromium/components/leveldb_proto/internal/migration_delegate.h
index abbb74e32f3..6d6f7cc2e0e 100644
--- a/chromium/components/leveldb_proto/internal/migration_delegate.h
+++ b/chromium/components/leveldb_proto/internal/migration_delegate.h
@@ -5,91 +5,39 @@
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_MIGRATION_DELEGATE_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_MIGRATION_DELEGATE_H_
-#include "base/bind.h"
+#include <memory>
+
#include "base/callback.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
+#include "components/leveldb_proto/internal/unique_proto_database.h"
namespace leveldb_proto {
// Small class that strictly performs the migration functionality of
// SharedProtoDatabase.
-template <typename T>
class MigrationDelegate {
public:
using MigrationCallback = base::OnceCallback<void(bool)>;
MigrationDelegate();
+ ~MigrationDelegate();
// Copies the keys/entries of |from| to |to|, and returns a boolean success
// in |callback|.
- void DoMigration(ProtoDatabase<T>* from,
- ProtoDatabase<T>* to,
+ void DoMigration(UniqueProtoDatabase* from,
+ UniqueProtoDatabase* to,
MigrationCallback callback);
private:
- void OnLoadKeysAndEntries(
- MigrationCallback callback,
- ProtoDatabase<T>* to,
- bool success,
- std::unique_ptr<std::map<std::string, T>> keys_entries);
+ void OnLoadKeysAndEntries(MigrationCallback callback,
+ UniqueProtoDatabase* to,
+ bool success,
+ std::unique_ptr<KeyValueMap> keys_entries);
void OnUpdateEntries(MigrationCallback callback, bool success);
- base::WeakPtrFactory<MigrationDelegate<T>> weak_ptr_factory_;
+ base::WeakPtrFactory<MigrationDelegate> weak_ptr_factory_;
};
-template <typename T>
-MigrationDelegate<T>::MigrationDelegate() : weak_ptr_factory_(this) {}
-
-template <typename T>
-void MigrationDelegate<T>::DoMigration(ProtoDatabase<T>* from,
- ProtoDatabase<T>* to,
- MigrationCallback callback) {
- from->LoadKeysAndEntries(
- base::BindOnce(&MigrationDelegate<T>::OnLoadKeysAndEntries,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback),
- base::Unretained(to)));
-}
-
-template <typename T>
-void MigrationDelegate<T>::OnLoadKeysAndEntries(
- MigrationCallback callback,
- ProtoDatabase<T>* to,
- bool success,
- std::unique_ptr<std::map<std::string, T>> keys_entries) {
- if (!success) {
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
- current_task_runner->PostTask(FROM_HERE,
- base::BindOnce(std::move(callback), false));
- return;
- }
-
- // Convert the std::map we got back into a vector of std::pairs to be used
- // with UpdateEntries.
- auto kev = std::make_unique<typename ProtoDatabase<T>::KeyEntryVector>();
- for (auto const& key_entry : *keys_entries)
- kev->push_back(key_entry);
-
- // Save the entries in |to|.
- to->UpdateEntries(
- std::move(kev), std::make_unique<std::vector<std::string>>(),
- base::BindOnce(&MigrationDelegate<T>::OnUpdateEntries,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-template <typename T>
-void MigrationDelegate<T>::OnUpdateEntries(MigrationCallback callback,
- bool success) {
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
- current_task_runner->PostTask(FROM_HERE,
- base::BindOnce(std::move(callback), success));
- // TODO (thildebr): For additional insurance, verify the entries match,
- // although they should if we got a success from UpdateEntries.
-}
-
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_MIGRATION_DELEGATE_H_ \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_database_impl.cc b/chromium/components/leveldb_proto/internal/proto_database_impl.cc
new file mode 100644
index 00000000000..512f34161ec
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/proto_database_impl.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/leveldb_proto/internal/proto_database_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "components/leveldb_proto/public/proto_database_provider.h"
+
+namespace leveldb_proto {
+
+void GetSharedDBInstance(
+ ProtoDatabaseProvider* db_provider,
+ base::OnceCallback<void(scoped_refptr<SharedProtoDatabase>)> callback) {
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ db_provider->GetSharedDBInstance(std::move(callback),
+ base::SequencedTaskRunnerHandle::Get());
+}
+
+void RunUpdateCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::UpdateCallback callback,
+ bool success) {
+ callback_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), success));
+}
+
+void RunLoadKeysCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::LoadKeysCallback callback,
+ bool success,
+ std::unique_ptr<KeyVector> keys) {
+ callback_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), success, std::move(keys)));
+}
+
+void RunDestroyCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::DestroyCallback callback,
+ bool success) {
+ callback_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(std::move(callback), success));
+}
+} // namespace leveldb_proto \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_database_impl.h b/chromium/components/leveldb_proto/internal/proto_database_impl.h
new file mode 100644
index 00000000000..e2b35f36da9
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/proto_database_impl.h
@@ -0,0 +1,540 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_
+#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/leveldb_proto/internal/proto_database_selector.h"
+#include "components/leveldb_proto/internal/shared_proto_database.h"
+#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
+#include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
+
+namespace leveldb_proto {
+
+class ProtoDatabaseProvider;
+
+// Avoids circular dependencies between ProtoDatabaseImpl and
+// ProtoDatabaseProvider, since we'd need to include the provider header here
+// to use |db_provider_|'s GetSharedDBInstance.
+void GetSharedDBInstance(
+ ProtoDatabaseProvider* db_provider,
+ base::OnceCallback<void(scoped_refptr<SharedProtoDatabase>)> callback);
+
+// Update transactions happen on background task runner and callback runs on the
+// client task runner.
+void RunUpdateCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::UpdateCallback callback,
+ bool success);
+
+// Load transactions happen on background task runner. The loaded keys need to
+// be given to clients on client task runner.
+void RunLoadKeysCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::LoadKeysCallback callback,
+ bool success,
+ std::unique_ptr<KeyVector> keys);
+
+// Helper to run destroy callback on the client task runner.
+void RunDestroyCallback(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::DestroyCallback callback,
+ bool success);
+
+// The ProtoDatabaseImpl<T> implements a ProtoDatabase<T> instance, and allows
+// the underlying ProtoDatabase<T> implementation to change without users of the
+// wrapper needing to know.
+// This allows clients to request a DB instance without knowing whether or not
+// it's a UniqueProtoDatabase or a SharedProtoDatabaseClient.
+template <typename T>
+class ProtoDatabaseImpl : public ProtoDatabase<T> {
+ public:
+ // DEPRECATED. Force usage of unique db. The clients must use Init(name,
+ // db_dir, options, callback) version.
+ ProtoDatabaseImpl(
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+
+ // Internal implementation is free to choose between unique and shared
+ // database to use here (transparently).
+ ProtoDatabaseImpl(ProtoDbType db_type,
+ const base::FilePath& db_dir,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
+
+ virtual ~ProtoDatabaseImpl() = default;
+
+ // DEPRECATED. This is to be used in case of forced unique db behavior.
+ void Init(const char* client_name,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ Callbacks::InitCallback callback) override;
+
+ // This can be used along with a database obtained from new api
+ // Provider::GetDB(). If using the old api to create unique db, then we do not
+ // know the database dir and init will fail.
+ void Init(const std::string& client_name,
+ Callbacks::InitStatusCallback callback) override;
+
+ // Internal only api.
+ void InitWithDatabase(LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ Callbacks::InitStatusCallback callback);
+
+ void UpdateEntries(std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
+ entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback) override;
+
+ void UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
+ entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) override;
+
+ void LoadEntries(
+ typename Callbacks::Internal<T>::LoadCallback callback) override;
+
+ void LoadEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::Internal<T>::LoadCallback callback) override;
+ void LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::Internal<T>::LoadCallback callback) override;
+
+ void LoadKeysAndEntries(
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
+ override;
+
+ void LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
+ override;
+ void LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
+ override;
+ void LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
+ override;
+
+ void LoadKeys(Callbacks::LoadKeysCallback callback) override;
+
+ void GetEntry(const std::string& key,
+ typename Callbacks::Internal<T>::GetCallback callback) override;
+
+ void Destroy(Callbacks::DestroyCallback callback) override;
+
+ void RemoveKeysForTesting(const KeyFilter& key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback);
+
+ // Not thread safe.
+ ProtoDatabaseSelector* db_wrapper_for_testing() { return db_wrapper_.get(); }
+
+ private:
+ friend class ProtoDatabaseImplTest;
+
+ void Init(const std::string& client_name,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback);
+
+ void PostTransaction(base::OnceClosure task);
+
+ ProtoDbType db_type_;
+ scoped_refptr<ProtoDatabaseSelector> db_wrapper_;
+ const bool force_unique_db_;
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ base::FilePath db_dir_;
+
+ std::unique_ptr<base::WeakPtrFactory<ProtoDatabaseImpl<T>>> weak_ptr_factory_;
+};
+
+namespace {
+
+// Update transactions need to serialize the entries to be updated on background
+// task runner. The database can be accessed on same task runner. The caller
+// must wrap the callback using RunUpdateCallback() to ensure the callback runs
+// in client task runner.
+template <typename T>
+void UpdateEntriesFromTaskRunner(
+ std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ scoped_refptr<ProtoDatabaseSelector> db,
+ Callbacks::UpdateCallback callback) {
+ // Serialize the values from Proto to string before passing on to database.
+ auto pairs_to_save = std::make_unique<KeyValueVector>();
+ for (const auto& pair : *entries_to_save) {
+ pairs_to_save->push_back(
+ std::make_pair(pair.first, pair.second.SerializeAsString()));
+ }
+
+ db->UpdateEntries(std::move(pairs_to_save), std::move(keys_to_remove),
+ std::move(callback));
+}
+
+// Update transactions need to serialize the entries to be updated on background
+// task runner. The database can be accessed on same task runner. The caller
+// must wrap the callback using RunUpdateCallback() to ensure the callback runs
+// in client task runner.
+template <typename T>
+void UpdateEntriesWithRemoveFilterFromTaskRunner(
+ std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ scoped_refptr<ProtoDatabaseSelector> db,
+ Callbacks::UpdateCallback callback) {
+ // Serialize the values from Proto to string before passing on to database.
+ auto pairs_to_save = std::make_unique<KeyValueVector>();
+ for (const auto& pair : *entries_to_save) {
+ pairs_to_save->push_back(
+ std::make_pair(pair.first, pair.second.SerializeAsString()));
+ }
+
+ db->UpdateEntriesWithRemoveFilter(std::move(pairs_to_save), delete_key_filter,
+ std::move(callback));
+}
+
+// Load transactions happen on background task runner. The loaded entries need
+// to be parsed into proto in background thread. This wraps the load callback
+// and parses the entries and posts result onto client task runner.
+template <typename T>
+void ParseLoadedEntries(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ typename Callbacks::Internal<T>::LoadCallback callback,
+ bool success,
+ std::unique_ptr<ValueVector> loaded_entries) {
+ auto entries = std::make_unique<std::vector<T>>();
+
+ if (!success || !loaded_entries) {
+ entries.reset();
+ } else {
+ for (const auto& serialized_entry : *loaded_entries) {
+ T entry;
+ if (!entry.ParseFromString(serialized_entry)) {
+ DLOG(WARNING) << "Unable to parse leveldb_proto entry";
+ // TODO(cjhopman): Decide what to do about un-parseable entries.
+ }
+
+ entries->push_back(entry);
+ }
+ }
+
+ callback_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), success, std::move(entries)));
+}
+
+// Load transactions happen on background task runner. The loaded entries need
+// to be parsed into proto in background thread. This wraps the load callback
+// and parses the entries and posts result onto client task runner.
+template <typename T>
+void ParseLoadedKeysAndEntries(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback,
+ bool success,
+ std::unique_ptr<KeyValueMap> loaded_entries) {
+ auto keys_entries = std::make_unique<std::map<std::string, T>>();
+ if (!success || !loaded_entries) {
+ keys_entries.reset();
+ } else {
+ for (const auto& pair : *loaded_entries) {
+ T entry;
+ if (!entry.ParseFromString(pair.second)) {
+ DLOG(WARNING) << "Unable to parse leveldb_proto entry";
+ // TODO(cjhopman): Decide what to do about un-parseable entries.
+ }
+
+ keys_entries->insert(std::make_pair(pair.first, entry));
+ }
+ }
+
+ callback_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), success, std::move(keys_entries)));
+}
+
+// Load transactions happen on background task runner. The loaded entries need
+// to be parsed into proto in background thread. This wraps the load callback
+// and parses the entries and posts result onto client task runner.
+template <typename T>
+void ParseLoadedEntry(
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ typename Callbacks::Internal<T>::GetCallback callback,
+ bool success,
+ std::unique_ptr<std::string> serialized_entry) {
+ auto entry = std::make_unique<T>();
+
+ if (!success || !serialized_entry) {
+ entry.reset();
+ } else if (!entry->ParseFromString(*serialized_entry)) {
+ DLOG(WARNING) << "Unable to parse leveldb_proto entry";
+ success = false;
+ entry.reset();
+ }
+ callback_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), success, std::move(entry)));
+}
+
+} // namespace
+
+template <typename T>
+ProtoDatabaseImpl<T>::ProtoDatabaseImpl(
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner)
+ : db_type_(ProtoDbType::LAST),
+ db_wrapper_(new ProtoDatabaseSelector(db_type_, task_runner, nullptr)),
+ force_unique_db_(true),
+ task_runner_(task_runner),
+ weak_ptr_factory_(
+ std::make_unique<base::WeakPtrFactory<ProtoDatabaseImpl<T>>>(this)) {}
+
+template <typename T>
+ProtoDatabaseImpl<T>::ProtoDatabaseImpl(
+ ProtoDbType db_type,
+ const base::FilePath& db_dir,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
+ : db_type_(db_type),
+ db_wrapper_(new ProtoDatabaseSelector(db_type_,
+ task_runner,
+ std::move(db_provider))),
+ force_unique_db_(false),
+ task_runner_(task_runner),
+ db_dir_(db_dir),
+ weak_ptr_factory_(
+ std::make_unique<base::WeakPtrFactory<ProtoDatabaseImpl<T>>>(this)) {}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::Init(const char* client_uma_name,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ Callbacks::InitCallback callback) {
+ DCHECK(force_unique_db_);
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &ProtoDatabaseSelector::InitUniqueOrShared, db_wrapper_,
+ client_uma_name, database_dir, options,
+ /*use_shared_db=*/false, base::SequencedTaskRunnerHandle::Get(),
+ base::BindOnce(
+ [](Callbacks::InitCallback callback, Enums::InitStatus status) {
+ std::move(callback).Run(status == Enums::InitStatus::kOK);
+ },
+ std::move(callback))));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::Init(
+ const std::string& client_uma_name,
+ typename Callbacks::InitStatusCallback callback) {
+ bool use_shared_db =
+ !force_unique_db_ &&
+ SharedProtoDatabaseClientList::ShouldUseSharedDB(db_type_);
+ Init(client_uma_name, use_shared_db, std::move(callback));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::Init(const std::string& client_name,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback) {
+ auto options = CreateSimpleOptions();
+ // If we're NOT using a shared DB, we want to force creation of the unique one
+ // because that's what we expect to be using moving forward. If we ARE using
+ // the shared DB, we only want to see if there's a unique DB that already
+ // exists and can be opened so that we can perform migration if necessary.
+ options.create_if_missing = !use_shared_db;
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ProtoDatabaseSelector::InitUniqueOrShared, db_wrapper_,
+ client_name, db_dir_, options, use_shared_db,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::InitWithDatabase(
+ LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ Callbacks::InitStatusCallback callback) {
+ DCHECK(force_unique_db_);
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ProtoDatabaseSelector::InitWithDatabase, db_wrapper_,
+ base::Unretained(database), database_dir, options,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::UpdateEntries(
+ std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback) {
+ base::OnceClosure update_task = base::BindOnce(
+ &UpdateEntriesFromTaskRunner<T>, std::move(entries_to_save),
+ std::move(keys_to_remove), db_wrapper_,
+ base::BindOnce(&RunUpdateCallback, base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(update_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) {
+ base::OnceClosure update_task = base::BindOnce(
+ &UpdateEntriesWithRemoveFilterFromTaskRunner<T>,
+ std::move(entries_to_save), delete_key_filter, db_wrapper_,
+ base::BindOnce(&RunUpdateCallback, base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(update_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadEntries(
+ typename Callbacks::Internal<T>::LoadCallback callback) {
+ LoadEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::Internal<T>::LoadCallback callback) {
+ LoadEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
+ std::move(callback));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::Internal<T>::LoadCallback callback) {
+ base::OnceClosure load_task =
+ base::BindOnce(&ProtoDatabaseSelector::LoadEntriesWithFilter, db_wrapper_,
+ key_filter, options, target_prefix,
+ base::BindOnce(&ParseLoadedEntries<T>,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(load_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadKeysAndEntries(
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
+ std::move(callback));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
+ base::OnceClosure load_task =
+ base::BindOnce(&ProtoDatabaseSelector::LoadKeysAndEntriesWithFilter,
+ db_wrapper_, filter, options, target_prefix,
+ base::BindOnce(&ParseLoadedKeysAndEntries<T>,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(load_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
+ base::OnceClosure load_task =
+ base::BindOnce(&ProtoDatabaseSelector::LoadKeysAndEntriesInRange,
+ db_wrapper_, start, end,
+ base::BindOnce(&ParseLoadedKeysAndEntries<T>,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(load_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
+ base::OnceClosure load_task =
+ base::BindOnce(&ProtoDatabaseSelector::LoadKeys, db_wrapper_,
+ base::BindOnce(&RunLoadKeysCallback,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(load_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::GetEntry(
+ const std::string& key,
+ typename Callbacks::Internal<T>::GetCallback callback) {
+ base::OnceClosure get_task =
+ base::BindOnce(&ProtoDatabaseSelector::GetEntry, db_wrapper_, key,
+ base::BindOnce(&ParseLoadedEntry<T>,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(get_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::Destroy(Callbacks::DestroyCallback callback) {
+ base::OnceClosure destroy_task =
+ base::BindOnce(&ProtoDatabaseSelector::Destroy, db_wrapper_,
+ base::BindOnce(&RunDestroyCallback,
+ base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(destroy_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::RemoveKeysForTesting(
+ const KeyFilter& key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ base::OnceClosure update_task = base::BindOnce(
+ &ProtoDatabaseSelector::RemoveKeysForTesting, db_wrapper_, key_filter,
+ target_prefix,
+ base::BindOnce(&RunUpdateCallback, base::SequencedTaskRunnerHandle::Get(),
+ std::move(callback)));
+ PostTransaction(std::move(update_task));
+}
+
+template <typename T>
+void ProtoDatabaseImpl<T>::PostTransaction(base::OnceClosure task) {
+ task_runner_->PostTask(FROM_HERE,
+ base::BindOnce(&ProtoDatabaseSelector::AddTransaction,
+ db_wrapper_, std::move(task)));
+}
+
+} // namespace leveldb_proto
+
+#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_ \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_database_impl_unittest.cc b/chromium/components/leveldb_proto/internal/proto_database_impl_unittest.cc
new file mode 100644
index 00000000000..d095a2ba972
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/proto_database_impl_unittest.cc
@@ -0,0 +1,941 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/leveldb_proto/internal/proto_database_impl.h"
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/task/task_scheduler/task_scheduler.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread.h"
+#include "components/leveldb_proto/internal/leveldb_proto_feature_list.h"
+#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
+#include "components/leveldb_proto/public/proto_database_provider.h"
+#include "components/leveldb_proto/testing/proto/test_db.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace leveldb_proto {
+
+namespace {
+
+const std::string kDefaultClientName = "client";
+const std::string kDefaultClientName2 = "client_2";
+
+} // namespace
+
+// Class used to shortcut the Init method so it returns a specified InitStatus.
+class TestSharedProtoDatabase : public SharedProtoDatabase {
+ public:
+ TestSharedProtoDatabase(const std::string& client_db_id,
+ const base::FilePath& db_dir,
+ Enums::InitStatus use_status)
+ : SharedProtoDatabase::SharedProtoDatabase(client_db_id, db_dir) {
+ use_status_ = use_status;
+ }
+
+ void Init(
+ bool create_if_missing,
+ const std::string& client_db_id,
+ SharedClientInitCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {
+ init_status_ = use_status_;
+
+ CheckCorruptionAndRunInitCallback(client_db_id, std::move(callback),
+ std::move(callback_task_runner),
+ use_status_);
+ }
+
+ private:
+ ~TestSharedProtoDatabase() override {}
+
+ Enums::InitStatus use_status_;
+};
+
+class TestSharedProtoDatabaseClient : public SharedProtoDatabaseClient {
+ public:
+ using SharedProtoDatabaseClient::set_migration_status;
+ using SharedProtoDatabaseClient::SharedProtoDatabaseClient;
+
+ TestSharedProtoDatabaseClient(scoped_refptr<SharedProtoDatabase> shared_db)
+ : SharedProtoDatabaseClient::SharedProtoDatabaseClient(
+ nullptr,
+ ProtoDbType::TEST_DATABASE1,
+ shared_db) {}
+
+ void UpdateClientInitMetadata(
+ SharedDBMetadataProto::MigrationStatus migration_status) override {
+ set_migration_status(migration_status);
+ }
+};
+
+class TestProtoDatabaseProvider : public ProtoDatabaseProvider {
+ public:
+ TestProtoDatabaseProvider(const base::FilePath& profile_dir)
+ : ProtoDatabaseProvider(profile_dir) {}
+ TestProtoDatabaseProvider(const base::FilePath& profile_dir,
+ const scoped_refptr<SharedProtoDatabase>& shared_db)
+ : ProtoDatabaseProvider(profile_dir) {
+ shared_db_ = shared_db;
+ }
+
+ void GetSharedDBInstance(
+ ProtoDatabaseProvider::GetSharedDBInstanceCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {
+ callback_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), shared_db_));
+ }
+
+ private:
+ scoped_refptr<SharedProtoDatabase> shared_db_;
+};
+
+class TestSharedProtoDatabaseProvider : public SharedProtoDatabaseProvider {
+ public:
+ TestSharedProtoDatabaseProvider(
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ base::WeakPtr<ProtoDatabaseProvider> provider_weak_ptr)
+ : SharedProtoDatabaseProvider(std::move(task_runner),
+ std::move(provider_weak_ptr)) {}
+};
+
+class ProtoDatabaseImplTest : public testing::Test {
+ public:
+ void SetUp() override {
+ temp_dir_ = std::make_unique<base::ScopedTempDir>();
+ ASSERT_TRUE(temp_dir_->CreateUniqueTempDir());
+ shared_db_temp_dir_ = std::make_unique<base::ScopedTempDir>();
+ ASSERT_TRUE(shared_db_temp_dir_->CreateUniqueTempDir());
+ test_thread_ = std::make_unique<base::Thread>("test_thread");
+ ASSERT_TRUE(test_thread_->Start());
+ shared_db_ = base::WrapRefCounted(new SharedProtoDatabase(
+ kDefaultClientName, shared_db_temp_dir_->GetPath()));
+ }
+
+ void TearDown() override {
+ temp_dir_.reset();
+ shared_db_temp_dir_.reset();
+ }
+
+ void SetUpExperimentParams(std::map<std::string, std::string> params) {
+ scoped_feature_list_.InitAndEnableFeatureWithParameters(
+ kProtoDBSharedMigration, params);
+ }
+
+ std::unique_ptr<ProtoDatabaseImpl<TestProto>> CreateDBImpl(
+ ProtoDbType db_type,
+ const base::FilePath& db_dir,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ std::unique_ptr<SharedProtoDatabaseProvider> db_provider) {
+ return std::make_unique<ProtoDatabaseImpl<TestProto>>(
+ db_type, db_dir, task_runner, std::move(db_provider));
+ }
+
+ void GetDbAndWait(leveldb_proto::ProtoDatabaseProvider* db_provider,
+ leveldb_proto::ProtoDbType db_type) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ auto db = db_provider->GetDB<TestProto>(db_type, temp_dir.GetPath(),
+ GetTestThreadTaskRunner());
+
+ base::RunLoop run_init;
+
+ // Initialize a database, it should succeed.
+ db->Init(kDefaultClientName,
+ base::BindOnce(
+ [](base::OnceClosure closure,
+ leveldb_proto::Enums::InitStatus status) {
+ std::move(closure).Run();
+ EXPECT_TRUE(status == leveldb_proto::Enums::InitStatus::kOK);
+ },
+ run_init.QuitClosure()));
+
+ run_init.Run();
+ }
+
+ std::unique_ptr<TestProtoDatabaseProvider> CreateProviderNoSharedDB() {
+ // Create a test provider with a test shared DB that will return invalid
+ // operation when a client is requested, level_db returns invalid operation
+ // when a database doesn't exist.
+ return CreateProviderWithTestSharedDB(Enums::InitStatus::kInvalidOperation);
+ }
+
+ std::unique_ptr<TestProtoDatabaseProvider> CreateProviderWithSharedDB() {
+ return std::make_unique<TestProtoDatabaseProvider>(
+ shared_db_temp_dir_->GetPath(), shared_db_);
+ }
+
+ std::unique_ptr<TestProtoDatabaseProvider> CreateProviderWithTestSharedDB(
+ Enums::InitStatus shared_client_init_status) {
+ auto test_shared_db = base::WrapRefCounted(new TestSharedProtoDatabase(
+ kDefaultClientName, shared_db_temp_dir_->GetPath(),
+ shared_client_init_status));
+
+ return std::make_unique<TestProtoDatabaseProvider>(
+ shared_db_temp_dir_->GetPath(), test_shared_db);
+ }
+
+ std::unique_ptr<TestSharedProtoDatabaseProvider> CreateSharedProvider(
+ TestProtoDatabaseProvider* db_provider) {
+ return std::make_unique<TestSharedProtoDatabaseProvider>(
+ GetTestThreadTaskRunner(), db_provider->weak_factory_.GetWeakPtr());
+ }
+
+ // Uses ProtoDatabaseImpl's 3 parameter Init to bypass the check that gets
+ // |use_shared_db|'s value.
+ void InitDBImpl(ProtoDatabaseImpl<TestProto>* db_impl,
+ const std::string& client_name,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback) {
+ db_impl->Init(client_name, use_shared_db, std::move(callback));
+ }
+
+ void InitDBImplAndWait(ProtoDatabaseImpl<TestProto>* db_impl,
+ const std::string& client_name,
+ bool use_shared_db,
+ Enums::InitStatus expect_status) {
+ base::RunLoop init_loop;
+ InitDBImpl(
+ db_impl, client_name, use_shared_db,
+ base::BindOnce(
+ [](base::OnceClosure closure, Enums::InitStatus expect_status,
+ Enums::InitStatus status) {
+ ASSERT_EQ(status, expect_status);
+ std::move(closure).Run();
+ },
+ init_loop.QuitClosure(), expect_status));
+ init_loop.Run();
+ }
+
+ std::unique_ptr<TestSharedProtoDatabaseClient> GetSharedClient() {
+ return std::make_unique<TestSharedProtoDatabaseClient>(shared_db_);
+ }
+
+ void CallOnGetSharedDBClientAndWait(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ Enums::InitStatus unique_db_status,
+ bool use_shared_db,
+ std::unique_ptr<SharedProtoDatabaseClient> shared_db_client,
+ Enums::InitStatus shared_db_status,
+ Enums::InitStatus expect_status) {
+ base::RunLoop init_loop;
+
+ scoped_refptr<ProtoDatabaseSelector> selector(new ProtoDatabaseSelector(
+ ProtoDbType::TEST_DATABASE1, GetTestThreadTaskRunner(), nullptr));
+
+ selector->OnGetSharedDBClient(
+ std::move(unique_db), unique_db_status, use_shared_db,
+ base::BindOnce(
+ [](base::OnceClosure closure, Enums::InitStatus expect_status,
+ Enums::InitStatus status) {
+ ASSERT_EQ(status, expect_status);
+ std::move(closure).Run();
+ },
+ init_loop.QuitClosure(), expect_status),
+ std::move(shared_db_client), shared_db_status);
+
+ init_loop.Run();
+
+ // If the process succeeded then check that the selector has a database set.
+ if (expect_status == Enums::InitStatus::kOK) {
+ ASSERT_NE(selector->db_, nullptr);
+ }
+ }
+
+ // Just uses each entry's key to fill out the id/data fields in TestProto as
+ // well.
+ void AddDataToDBImpl(ProtoDatabaseImpl<TestProto>* db_impl,
+ std::vector<std::string>* entry_keys) {
+ auto data_set =
+ std::make_unique<std::vector<std::pair<std::string, TestProto>>>();
+ for (const auto& key : *entry_keys) {
+ TestProto proto;
+ proto.set_id(key);
+ proto.set_data(key);
+ data_set->emplace_back(std::make_pair(key, proto));
+ }
+
+ base::RunLoop data_loop;
+ db_impl->UpdateEntries(std::move(data_set),
+ std::make_unique<std::vector<std::string>>(),
+ base::BindOnce(
+ [](base::OnceClosure closure, bool success) {
+ ASSERT_TRUE(success);
+ std::move(closure).Run();
+ },
+ data_loop.QuitClosure()));
+ data_loop.Run();
+ }
+
+ void VerifyDataInDBImpl(ProtoDatabaseImpl<TestProto>* db_impl,
+ std::vector<std::string>* entry_keys) {
+ base::RunLoop load_loop;
+ db_impl->LoadKeysAndEntries(base::BindOnce(
+ [](base::OnceClosure closure, std::vector<std::string>* entry_keys,
+ bool success,
+ std::unique_ptr<std::map<std::string, TestProto>> keys_entries) {
+ ASSERT_TRUE(success);
+ ASSERT_EQ(entry_keys->size(), keys_entries->size());
+
+ for (const auto& key : *entry_keys) {
+ ASSERT_TRUE(keys_entries->find(key) != keys_entries->end());
+ }
+ std::move(closure).Run();
+ },
+ load_loop.QuitClosure(), entry_keys));
+ load_loop.Run();
+ }
+
+ void UpdateClientMetadata(
+ SharedDBMetadataProto::MigrationStatus migration_status) {
+ base::RunLoop init_wait;
+ auto client = shared_db_->GetClientForTesting(
+ ProtoDbType::TEST_DATABASE1, /*create_if_missing=*/true,
+ base::BindOnce(
+ [](base::OnceClosure closure, Enums::InitStatus status,
+ SharedDBMetadataProto::MigrationStatus migration_status) {
+ EXPECT_EQ(Enums::kOK, status);
+ std::move(closure).Run();
+ },
+ init_wait.QuitClosure()));
+ init_wait.Run();
+
+ base::RunLoop wait_loop;
+ shared_db_->UpdateClientMetadataAsync(
+ client->client_db_id(), migration_status,
+ base::BindOnce(
+ [](base::OnceClosure closure, bool success) {
+ EXPECT_TRUE(success);
+ std::move(closure).Run();
+ },
+ wait_loop.QuitClosure()));
+ wait_loop.Run();
+ }
+
+ SharedDBMetadataProto::MigrationStatus GetClientMigrationStatus() {
+ SharedDBMetadataProto::MigrationStatus migration_status;
+ base::RunLoop init_wait;
+ auto client = shared_db_->GetClientForTesting(
+ ProtoDbType::TEST_DATABASE1, /*create_if_missing=*/true,
+ base::BindOnce(
+ [](base::OnceClosure closure,
+ SharedDBMetadataProto::MigrationStatus* output,
+ Enums::InitStatus status,
+ SharedDBMetadataProto::MigrationStatus migration_status) {
+ EXPECT_EQ(Enums::kOK, status);
+ *output = migration_status;
+ std::move(closure).Run();
+ },
+ init_wait.QuitClosure(), &migration_status));
+ init_wait.Run();
+
+ return migration_status;
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> GetTestThreadTaskRunner() {
+ return test_thread_->task_runner();
+ }
+
+ base::FilePath temp_dir() { return temp_dir_->GetPath(); }
+
+ private:
+ std::unique_ptr<base::ScopedTempDir> temp_dir_;
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ // Shared database.
+ std::unique_ptr<base::Thread> test_thread_;
+ std::unique_ptr<base::Thread> shared_db_thread_;
+ scoped_refptr<SharedProtoDatabase> shared_db_;
+ std::unique_ptr<base::ScopedTempDir> shared_db_temp_dir_;
+};
+
+TEST_F(ProtoDatabaseImplTest, FailsBothDatabases) {
+ auto db_provider = CreateProviderNoSharedDB();
+ auto shared_db_provider = CreateSharedProvider(db_provider.get());
+ auto db_impl = CreateDBImpl(ProtoDbType::TEST_DATABASE1, temp_dir(),
+ GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider.get()));
+ InitDBImplAndWait(db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kError);
+}
+
+TEST_F(ProtoDatabaseImplTest, Fails_UseShared_NoSharedDB) {
+ auto unique_db =
+ std::make_unique<UniqueProtoDatabase>(GetTestThreadTaskRunner());
+
+ // If a shared DB is requested, and it fails to open for any reason then we
+ // return a failure, the shared DB is opened using create_if_missing = true,
+ // so we shouldn't get a missing DB.
+ CallOnGetSharedDBClientAndWait(
+ std::move(unique_db), // Unique DB opens fine.
+ Enums::InitStatus::kOK,
+ true, // We should be using a shared DB.
+ nullptr, // Shared DB failed to open.
+ Enums::InitStatus::kError, // Shared DB had an IO error.
+ Enums::InitStatus::kError); // Then the DB impl should return an error.
+
+ CallOnGetSharedDBClientAndWait(
+ std::move(unique_db), // Unique DB opens fine.
+ Enums::InitStatus::kOK,
+ true, // We should be using a shared DB.
+ nullptr, // Shared DB failed to open.
+ Enums::InitStatus::kInvalidOperation, // Shared DB doesn't exist.
+ Enums::InitStatus::kError); // Then the DB impl should return an error.
+}
+
+TEST_F(ProtoDatabaseImplTest,
+ SucceedsWithShared_UseShared_HasSharedDB_UniqueNotFound) {
+ auto shared_db_client = GetSharedClient();
+
+ // Migration status is not attempted.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED);
+
+ // If we request a shared DB, the unique DB fails to open because it doesn't
+ // exist and a migration hasn't been attempted then we return the shared DB
+ // and we set the migration status to migrated to shared.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kInvalidOperation, // Unique DB doesn't exist.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kOK); // Then the DB impl should return the shared DB.
+}
+
+TEST_F(ProtoDatabaseImplTest, Fails_UseShared_HasSharedDB_UniqueHadIOError) {
+ auto shared_db_client = GetSharedClient();
+
+ // Migration status is not attempted.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED);
+
+ // If we request a shared DB, the unique DB fails to open because of an IO
+ // error and a migration hasn't been attempted then we throw an error, as the
+ // unique DB could contain data yet to be migrated.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kError, // Unique DB had an IO error.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kError); // Then the DB impl should return an error.
+}
+
+TEST_F(ProtoDatabaseImplTest,
+ SuccedsWithShared_UseShared_HasSharedDB_DataWasMigratedToShared) {
+ auto shared_db_client = GetSharedClient();
+
+ // Database has been migrated to Shared.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
+
+ // If we request a shared DB, the unique DB fails to open for any reason and
+ // the data has been migrated to the shared DB then we can return the shared
+ // DB safely.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kInvalidOperation, // Unique DB doesn't exist.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kOK); // Then the DB impl should use the shared DB.
+
+ shared_db_client = GetSharedClient();
+
+ // Data has been migrated to Shared, Unique DB still exists and should be
+ // removed.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+
+ // This second scenario occurs when the unique DB is marked to be deleted, but
+ // it fails to open, we should also return the unique DB without throwing an
+ // error.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kError, // Unique DB had an IO error.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kOK); // Then the DB impl should use the shared DB.
+}
+
+TEST_F(ProtoDatabaseImplTest,
+ Fails_UseShared_HasSharedDB_DataWasMigratedToUnique) {
+ auto shared_db_client = GetSharedClient();
+
+ // Database has been migrated to Unique.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL);
+
+ // If we request a shared DB, the unique DB fails to open for any reason and
+ // the data has been migrated to the unique DB then we throw an error, as the
+ // unique database may contain data.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kInvalidOperation, // Unique DB doesn't exist.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kError); // Then the DB impl should throw an error.
+
+ shared_db_client = GetSharedClient();
+
+ // Data has been migrated to Unique, but data still exists in Shared DB that
+ // should be removed.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+
+ // This second scenario occurs when the Shared DB still contains data, we
+ // should still throw an error.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kError, // Unique DB had an IO error.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kError); // Then the DB impl should throw an error.
+}
+
+TEST_F(ProtoDatabaseImplTest,
+ SucceedsWithShared_DontUseShared_HasSharedDB_DataWasMigratedToShared) {
+ auto shared_db_client = GetSharedClient();
+
+ // Database has been migrated to Shared.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
+
+ // If we request a unique DB, the unique DB fails to open for any reason and
+ // the data has been migrated to the shared DB then we use the Shared DB.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kInvalidOperation, // Unique DB doesn't exist.
+ false, // We should be using a unique DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kOK); // Then the DB impl should use the shared DB.
+
+ shared_db_client = GetSharedClient();
+
+ // Data has been migrated to Shared, but the Unique DB still exists and needs
+ // to be deleted.
+ shared_db_client->set_migration_status(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+
+ // This second scenario occurs when the unique database is marked to be
+ // deleted, we should still use the shared DB.
+ CallOnGetSharedDBClientAndWait(
+ nullptr, // Unique DB fails to open.
+ Enums::InitStatus::kError, // Unique DB had an IO error.
+ true, // We should be using a shared DB.
+ std::move(shared_db_client), // Shared DB opens fine.
+ Enums::InitStatus::kOK,
+ Enums::InitStatus::kOK); // Then the DB impl should use the shared DB.
+}
+
+TEST_F(ProtoDatabaseImplTest,
+ SucceedsWithUnique_DontUseShared_SharedDBNotFound) {
+ auto unique_db =
+ std::make_unique<UniqueProtoDatabase>(GetTestThreadTaskRunner());
+
+ // If the shared DB client fails to open because it doesn't exist then we can
+ // return the unique DB safely.
+ CallOnGetSharedDBClientAndWait(
+ std::move(unique_db), // Unique DB opens fine.
+ Enums::InitStatus::kOK,
+ false, // We should be using a unique DB.
+ nullptr, // Shared DB failed to open.
+ Enums::InitStatus::kInvalidOperation, // Shared DB doesn't exist.
+ Enums::InitStatus::kOK); // Then the DB impl should return the unique DB.
+}
+
+TEST_F(ProtoDatabaseImplTest, Fails_DontUseShared_SharedDBFailed) {
+ auto unique_db =
+ std::make_unique<UniqueProtoDatabase>(GetTestThreadTaskRunner());
+
+ // If the shared DB client fails to open because of an IO error then we
+ // shouldn't return a database, as the shared DB could contain data not yet
+ // migrated.
+ CallOnGetSharedDBClientAndWait(
+ std::move(unique_db), // Unique DB opens fine.
+ Enums::InitStatus::kOK,
+ false, // We should be using a unique DB.
+ nullptr, // Shared DB failed to open.
+ Enums::InitStatus::kError, // Shared DB had an IO error.
+ Enums::InitStatus::kError); // Then the DB impl should return an error.
+}
+
+TEST_F(ProtoDatabaseImplTest, Fails_UseShared_NoSharedDB_NoUniqueDB) {
+ auto db_provider = CreateProviderNoSharedDB();
+ auto db_impl = CreateDBImpl(ProtoDbType::TEST_DATABASE1, temp_dir(),
+ GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider.get()));
+ InitDBImplAndWait(db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kError);
+}
+
+// Migration tests:
+TEST_F(ProtoDatabaseImplTest, Migration_EmptyDBs_UniqueToShared) {
+ // First we create a unique DB so our second pass has a unique DB available.
+ auto db_provider_noshared = CreateProviderNoSharedDB();
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_noshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ // Kill the DB impl so it doesn't have a lock on the DB anymore.
+ unique_db_impl.reset();
+ base::TaskScheduler::GetInstance()->FlushForTesting();
+
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_EmptyDBs_SharedToUnique) {
+ // First we create a unique DB so our second pass has a unique DB available.
+ auto db_provider = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(ProtoDbType::TEST_DATABASE1, temp_dir(),
+ GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+
+ // As the unique DB doesn't exist then the DB impl sets the migration status
+ // to migrated to shared.
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+
+ auto unique_db_impl = CreateDBImpl(ProtoDbType::TEST_DATABASE1, temp_dir(),
+ GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_UniqueToShared) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a unique DB so our second pass has a unique DB available.
+ auto db_provider_noshared = CreateProviderNoSharedDB();
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_noshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(unique_db_impl.get(), data_set.get());
+ // Kill the DB impl so it doesn't have a lock on the DB anymore.
+ unique_db_impl.reset();
+
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+ VerifyDataInDBImpl(shared_db_impl.get(), data_set.get());
+
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_SharedToUnique) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a shared DB so our second pass has a shared DB available.
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(shared_db_impl.get(), data_set.get());
+
+ // As the unique DB doesn't exist then the DB impl sets the migration status
+ // to migrated to shared.
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ VerifyDataInDBImpl(unique_db_impl.get(), data_set.get());
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_UniqueToShared_UniqueObsolete) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a unique DB so our second pass has a unique DB available.
+ auto db_provider_noshared = CreateProviderNoSharedDB();
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_noshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(unique_db_impl.get(), data_set.get());
+ // Kill the DB impl so it doesn't have a lock on the DB anymore.
+ unique_db_impl.reset();
+
+ UpdateClientMetadata(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+
+ // Unique DB should be deleted in migration. So, shared DB should be clean.
+ data_set->clear();
+ VerifyDataInDBImpl(shared_db_impl.get(), data_set.get());
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_UniqueToShared_SharedObsolete) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a shared DB so our second pass has a shared DB available.
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(shared_db_impl.get(), data_set.get());
+
+ // As there's no unique DB, the DB impl is going to set the state to migrated
+ // to shared.
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+
+ // Force create an unique DB, which was deleted by migration.
+ auto db_provider_noshared = CreateProviderNoSharedDB();
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_noshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ unique_db_impl.reset();
+
+ UpdateClientMetadata(
+ SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+
+ shared_db_impl.reset();
+ db_provider_withshared = CreateProviderWithSharedDB();
+
+ auto shared_db_impl1 = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl1.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+
+ // Shared DB should be deleted in migration. So, shared DB should be clean.
+ data_set->clear();
+ VerifyDataInDBImpl(shared_db_impl1.get(), data_set.get());
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_SharedToUnique_SharedObsolete) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a shared DB so our second pass has a shared DB available.
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(shared_db_impl.get(), data_set.get());
+
+ // As there's no Unique DB, the DB impl changes the migration status to
+ // migrated to shared.
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
+ GetClientMigrationStatus());
+
+ UpdateClientMetadata(
+ SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+
+ // Shared DB should be deleted in migration. So, unique DB should be clean.
+ data_set->clear();
+ VerifyDataInDBImpl(unique_db_impl.get(), data_set.get());
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, Migration_SharedToUnique_UniqueObsolete) {
+ auto data_set = std::make_unique<std::vector<std::string>>();
+ data_set->emplace_back("entry1");
+ data_set->emplace_back("entry2");
+ data_set->emplace_back("entry3");
+
+ // First we create a shared DB so our second pass has a shared DB available.
+ auto db_provider_noshared = CreateProviderNoSharedDB();
+ auto unique_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_noshared.get()));
+ InitDBImplAndWait(unique_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+ AddDataToDBImpl(unique_db_impl.get(), data_set.get());
+
+ UpdateClientMetadata(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+
+ unique_db_impl.reset();
+
+ auto db_provider_withshared = CreateProviderWithSharedDB();
+ auto shared_db_impl = CreateDBImpl(
+ ProtoDbType::TEST_DATABASE1, temp_dir(), GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider_withshared.get()));
+ InitDBImplAndWait(shared_db_impl.get(), kDefaultClientName, false,
+ Enums::InitStatus::kOK);
+
+ // Unique DB should be deleted in migration. So, unique DB should be clean.
+ data_set->clear();
+ VerifyDataInDBImpl(shared_db_impl.get(), data_set.get());
+ EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
+ GetClientMigrationStatus());
+}
+
+TEST_F(ProtoDatabaseImplTest, DestroyShouldWorkWhenUniqueInitFailed) {
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+
+ auto db_provider = CreateProviderNoSharedDB();
+ auto shared_db_provider = CreateSharedProvider(db_provider.get());
+ auto db_impl = CreateDBImpl(ProtoDbType::TEST_DATABASE1, temp_dir.GetPath(),
+ GetTestThreadTaskRunner(),
+ CreateSharedProvider(db_provider.get()));
+
+ // Try to initialize a db and fail.
+ InitDBImplAndWait(db_impl.get(), kDefaultClientName, true,
+ Enums::InitStatus::kError);
+
+ base::RunLoop run_destroy;
+
+ // Call destroy on the db, it should destroy the db directory.
+ db_impl->Destroy(base::BindOnce(
+ [](base::OnceClosure closure, bool success) {
+ std::move(closure).Run();
+ EXPECT_TRUE(success);
+ },
+ run_destroy.QuitClosure()));
+
+ run_destroy.Run();
+
+ // Verify the db is actually destroyed.
+ EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
+}
+
+TEST_F(ProtoDatabaseImplTest, InitUniqueTwiceShouldSucceed) {
+ base::ScopedTempDir temp_dir_profile;
+ ASSERT_TRUE(temp_dir_profile.CreateUniqueTempDir());
+
+ // Both databases will be opened as unique.
+ auto experiment_params = std::map<std::string, std::string>{
+ {"migrate_TEST_DATABASE1", "false"}, {"migrate_TEST_DATABASE2", "false"}};
+ SetUpExperimentParams(experiment_params);
+
+ leveldb_proto::ProtoDatabaseProvider* db_provider =
+ leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath());
+
+ // Initialize a database, it should succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1);
+ // Initialize a second database, it should also succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2);
+}
+
+TEST_F(ProtoDatabaseImplTest, InitUniqueThenSharedShouldSucceed) {
+ base::ScopedTempDir temp_dir_profile;
+ ASSERT_TRUE(temp_dir_profile.CreateUniqueTempDir());
+
+ // First database will open as unique, second DB will open as shared.
+ auto experiment_params = std::map<std::string, std::string>{
+ {"migrate_TEST_DATABASE1", "false"}, {"migrate_TEST_DATABASE2", "true"}};
+ SetUpExperimentParams(experiment_params);
+
+ leveldb_proto::ProtoDatabaseProvider* db_provider =
+ leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath());
+
+ // Initialize a database, it should succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1);
+ // Initialize a second database, it should also succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2);
+}
+
+TEST_F(ProtoDatabaseImplTest, InitSharedThenUniqueShouldSucceed) {
+ base::ScopedTempDir temp_dir_profile;
+ ASSERT_TRUE(temp_dir_profile.CreateUniqueTempDir());
+
+ // First database will open as shared, second DB will open as unique.
+ auto experiment_params = std::map<std::string, std::string>{
+ {"migrate_TEST_DATABASE1", "true"}, {"migrate_TEST_DATABASE2", "false"}};
+ SetUpExperimentParams(experiment_params);
+
+ leveldb_proto::ProtoDatabaseProvider* db_provider =
+ leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath());
+
+ // Initialize a database, it should succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1);
+ // Initialize a second database, it should also succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2);
+}
+
+TEST_F(ProtoDatabaseImplTest, InitSharedTwiceShouldSucceed) {
+ base::ScopedTempDir temp_dir_profile;
+ ASSERT_TRUE(temp_dir_profile.CreateUniqueTempDir());
+
+ // Both databases will open as shared.
+ auto experiment_params = std::map<std::string, std::string>{
+ {"migrate_TEST_DATABASE1", "true"}, {"migrate_TEST_DATABASE2", "true"}};
+ SetUpExperimentParams(experiment_params);
+
+ leveldb_proto::ProtoDatabaseProvider* db_provider =
+ leveldb_proto::ProtoDatabaseProvider::Create(temp_dir_profile.GetPath());
+
+ // Initialize a database, it should succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE1);
+ // Initialize a second database, it should also succeed.
+ GetDbAndWait(db_provider, leveldb_proto::ProtoDbType::TEST_DATABASE2);
+}
+
+} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/proto_database_perftest.cc b/chromium/components/leveldb_proto/internal/proto_database_perftest.cc
index ac2f2caac89..830cca22177 100644
--- a/chromium/components/leveldb_proto/internal/proto_database_perftest.cc
+++ b/chromium/components/leveldb_proto/internal/proto_database_perftest.cc
@@ -24,6 +24,7 @@
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "components/leveldb_proto/internal/leveldb_database.h"
+#include "components/leveldb_proto/internal/proto_database_impl.h"
#include "components/leveldb_proto/internal/unique_proto_database.h"
#include "components/leveldb_proto/testing/proto/test_db.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -97,7 +98,7 @@ class TestDatabase {
TestDatabase(const std::string& name,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::FilePath& path) {
- db_.reset(new UniqueProtoDatabase<TestProto>(task_runner));
+ db_.reset(new ProtoDatabaseImpl<TestProto>(task_runner));
leveldb_env::Options options = leveldb_proto::CreateSimpleOptions();
base::RunLoop run_init_db;
@@ -114,11 +115,11 @@ class TestDatabase {
}
bool is_initialized() const { return is_initialized_; }
- UniqueProtoDatabase<TestProto>* proto_db() const { return db_.get(); }
+ ProtoDatabaseImpl<TestProto>* proto_db() const { return db_.get(); }
private:
bool is_initialized_ = false;
- std::unique_ptr<UniqueProtoDatabase<TestProto>> db_;
+ std::unique_ptr<ProtoDatabaseImpl<TestProto>> db_;
};
} // namespace
@@ -546,7 +547,10 @@ class ProtoDBPerfTest : public testing::Test {
}
bool GetApproximateMemoryUsageOfDB(TestDatabase* db, uint64_t* memory_use) {
- return db->proto_db()->GetApproximateMemoryUse(memory_use);
+ return db->proto_db()
+ ->db_wrapper_for_testing()
+ ->db_for_testing()
+ ->GetApproximateMemoryUse(memory_use);
}
std::map<std::string, std::unique_ptr<TestDatabase>> dbs_;
diff --git a/chromium/components/leveldb_proto/internal/proto_database_selector.cc b/chromium/components/leveldb_proto/internal/proto_database_selector.cc
new file mode 100644
index 00000000000..5edef99ac0f
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/proto_database_selector.cc
@@ -0,0 +1,572 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/leveldb_proto/internal/proto_database_selector.h"
+
+#include <memory>
+#include <utility>
+
+#include "components/leveldb_proto/internal/migration_delegate.h"
+#include "components/leveldb_proto/internal/shared_proto_database.h"
+#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
+#include "components/leveldb_proto/internal/unique_proto_database.h"
+
+namespace leveldb_proto {
+
+namespace {
+
+void RunInitCallbackOnTaskRunner(
+ Callbacks::InitStatusCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ Enums::InitStatus status) {
+ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(callback), status));
+}
+
+} // namespace
+
+ProtoDatabaseSelector::ProtoDatabaseSelector(
+ ProtoDbType db_type,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
+ : db_type_(db_type),
+ task_runner_(task_runner),
+ db_provider_(std::move(db_provider)),
+ migration_delegate_(std::make_unique<MigrationDelegate>()) {
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+}
+
+ProtoDatabaseSelector::~ProtoDatabaseSelector() {
+ if (db_)
+ task_runner_->DeleteSoon(FROM_HERE, std::move(db_));
+}
+
+void ProtoDatabaseSelector::InitWithDatabase(
+ LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::InitStatusCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_)
+ db_ = std::make_unique<UniqueProtoDatabase>(task_runner_);
+
+ unique_database_dir_ = database_dir;
+
+ db_->InitWithDatabase(
+ database, database_dir, options, false,
+ base::BindOnce(&RunInitCallbackOnTaskRunner, std::move(callback),
+ callback_task_runner));
+ OnInitDone();
+}
+
+void ProtoDatabaseSelector::InitUniqueOrShared(
+ const std::string& client_name,
+ base::FilePath db_dir,
+ const leveldb_env::Options& options,
+ bool use_shared_db,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::InitStatusCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ init_status_ = InitStatus::IN_PROGRESS;
+ unique_database_dir_ = db_dir;
+ client_name_ = client_name;
+ auto unique_db =
+ std::make_unique<UniqueProtoDatabase>(db_dir, options, task_runner_);
+ auto* unique_db_ptr = unique_db.get();
+ unique_db_ptr->Init(
+ client_name, base::BindOnce(&ProtoDatabaseSelector::OnInitUniqueDB, this,
+ std::move(unique_db), use_shared_db,
+ base::BindOnce(&RunInitCallbackOnTaskRunner,
+ std::move(callback),
+ callback_task_runner)));
+}
+
+void ProtoDatabaseSelector::OnInitUniqueDB(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ Enums::InitStatus status) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // If the unique DB is corrupt, just return it early with the corruption
+ // status to avoid silently migrating a corrupt database and giving no errors
+ // back.
+ if (status == Enums::InitStatus::kCorrupt) {
+ db_ = std::move(unique_db);
+ std::move(callback).Run(Enums::InitStatus::kCorrupt);
+ OnInitDone();
+ return;
+ }
+
+ // Clear out the unique_db before sending an unusable DB into InitSharedDB,
+ // a nullptr indicates opening a unique DB failed.
+ if (status != Enums::InitStatus::kOK)
+ unique_db.reset();
+
+ // If no SharedProtoDatabaseProvider is set then we use the unique DB (if it
+ // opened correctly).
+ if (!db_provider_) {
+ db_ = std::move(unique_db);
+ std::move(callback).Run(status);
+ OnInitDone();
+ return;
+ }
+
+ // Get the current task runner to ensure the callback is run on the same
+ // callback as the rest, and the WeakPtr checks out on the right sequence.
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ db_provider_->GetDBInstance(
+ base::BindOnce(&ProtoDatabaseSelector::OnInitSharedDB, this,
+ std::move(unique_db), status, use_shared_db,
+ std::move(callback)),
+ task_runner_);
+}
+
+void ProtoDatabaseSelector::OnInitSharedDB(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ Enums::InitStatus unique_db_status,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ scoped_refptr<SharedProtoDatabase> shared_db) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (shared_db) {
+ // If we have a reference to the shared database, try to get a client.
+ shared_db->GetClientAsync(
+ db_type_, use_shared_db,
+ base::BindOnce(&ProtoDatabaseSelector::OnGetSharedDBClient, this,
+ std::move(unique_db), unique_db_status, use_shared_db,
+ std::move(callback)));
+ return;
+ }
+
+ // Otherwise, we just call the OnGetSharedDBClient function with a nullptr
+ // client.
+ OnGetSharedDBClient(std::move(unique_db), unique_db_status, use_shared_db,
+ std::move(callback), nullptr, Enums::InitStatus::kError);
+}
+
+void ProtoDatabaseSelector::OnGetSharedDBClient(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ Enums::InitStatus unique_db_status,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ Enums::InitStatus shared_db_status) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!unique_db && !client) {
+ std::move(callback).Run(Enums::InitStatus::kError);
+ OnInitDone();
+ return;
+ }
+
+ if (!client) {
+ if (use_shared_db) {
+ // If there's no shared client and one is requested we return an error,
+ // because it should be created if missing.
+ std::move(callback).Run(Enums::InitStatus::kError);
+ OnInitDone();
+ return;
+ } else {
+ // ProtoLevelDBWrapper::InitWithDatabase() returns kInvalidOperation when
+ // a database doesn't exist and create_if_missing is false.
+ if (shared_db_status == Enums::InitStatus::kInvalidOperation) {
+ // If the shared DB doesn't exist and a unique DB is requested then we
+ // return the unique DB.
+ db_ = std::move(unique_db);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+ return;
+ } else {
+ // If the shared DB failed to open and a unique DB is requested then we
+ // throw an error, as the shared DB may contain unmigrated data.
+ std::move(callback).Run(Enums::InitStatus::kError);
+ OnInitDone();
+ return;
+ }
+ }
+ }
+
+ if (!unique_db) {
+ switch (client->migration_status()) {
+ case SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED:
+ // ProtoLevelDBWrapper::InitWithDatabase() returns kInvalidOperation
+ // when a database doesn't exist and create_if_missing is false.
+ if (unique_db_status == Enums::kInvalidOperation) {
+ // If the unique DB doesn't exist and the migration status is not
+ // attempted then we set the status to migrated to shared and return
+ // the shared DB. We don't check use_shared_db because we should only
+ // get here when use_shared_db is true, otherwise the unique_db is
+ // opened using create_if_missing
+ client->UpdateClientInitMetadata(
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
+ db_ = std::move(client);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+ return;
+ } else {
+ // If the unique DB failed to open and the migration status is not
+ // attempted then we return an error, as we don't know if the unique
+ // DB contains any data.
+ std::move(callback).Run(Enums::InitStatus::kError);
+ OnInitDone();
+ return;
+ }
+ break;
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL:
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED:
+ // If the unique DB failed to open, but the data is located in shared
+ // then we use the shared DB. We do the same when the unique DB is
+ // marked for deletion because there's no way to delete it.
+ // use_shared_db is ignored because we know the data is in shared DB,
+ // and there's no way to migrate.
+ db_ = std::move(client);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+ return;
+ break;
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL:
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED:
+ // If the unique DB failed to open, and the data is located on it then
+ // we throw an error. We ignore the deletion flag because we want both
+ // databases to be open before we delete the shared DB.
+ std::move(callback).Run(Enums::InitStatus::kError);
+ OnInitDone();
+ return;
+ break;
+ }
+ }
+
+ // Both databases opened correctly. Migrate data and delete old DB if needed.
+ if (use_shared_db) {
+ switch (client->migration_status()) {
+ case SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED:
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL: {
+ // Migrate from unique to shared.
+ UniqueProtoDatabase* from = unique_db.get();
+ UniqueProtoDatabase* to = client.get();
+ migration_delegate_->DoMigration(
+ from, to,
+ base::BindOnce(&ProtoDatabaseSelector::OnMigrationTransferComplete,
+ this, std::move(unique_db), std::move(client),
+ use_shared_db, std::move(callback)));
+ return;
+ }
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL:
+ // Unique db was deleted in previous migration, so nothing to do here.
+ return OnMigrationCleanupComplete(std::move(unique_db),
+ std::move(client), use_shared_db,
+ std::move(callback), true);
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED:
+ // Migration transfer was completed, so just try deleting the unique db.
+ return OnMigrationTransferComplete(std::move(unique_db),
+ std::move(client), use_shared_db,
+ std::move(callback), true);
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED:
+ // Shared db was not deleted in last migration and we want to use shared
+ // db. So, delete stale data, and attempt migration.
+ return DeleteOldDataAndMigrate(std::move(unique_db), std::move(client),
+ use_shared_db, std::move(callback));
+ }
+ } else {
+ switch (client->migration_status()) {
+ case SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED:
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL: {
+ // Migrate from shared to unique.
+ UniqueProtoDatabase* from = client.get();
+ UniqueProtoDatabase* to = unique_db.get();
+ migration_delegate_->DoMigration(
+ from, to,
+ base::BindOnce(&ProtoDatabaseSelector::OnMigrationTransferComplete,
+ this, std::move(unique_db), std::move(client),
+ use_shared_db, std::move(callback)));
+ return;
+ }
+ case SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED:
+ // Unique db was not deleted in last migration and we want to use unique
+ // db. So, delete stale data, and attempt migration.
+ return DeleteOldDataAndMigrate(std::move(unique_db), std::move(client),
+ use_shared_db, std::move(callback));
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL:
+ // Shared db was deleted in previous migration, so nothing to do here.
+ return OnMigrationCleanupComplete(std::move(unique_db),
+ std::move(client), use_shared_db,
+ std::move(callback), true);
+ case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED:
+ // Migration transfer was completed, so just try deleting the shared db.
+ return OnMigrationTransferComplete(std::move(unique_db),
+ std::move(client), use_shared_db,
+ std::move(callback), true);
+ }
+ }
+}
+
+void ProtoDatabaseSelector::DeleteOldDataAndMigrate(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase* to_remove_old_data =
+ use_shared_db ? client.get() : unique_db.get();
+ auto maybe_do_migration =
+ base::BindOnce(&ProtoDatabaseSelector::MaybeDoMigrationOnDeletingOld,
+ this, std::move(unique_db), std::move(client),
+ std::move(callback), use_shared_db);
+
+ to_remove_old_data->UpdateEntriesWithRemoveFilter(
+ std::make_unique<KeyValueVector>(),
+ base::BindRepeating([](const std::string& key) { return true; }),
+ std::move(maybe_do_migration));
+}
+
+void ProtoDatabaseSelector::MaybeDoMigrationOnDeletingOld(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ Callbacks::InitStatusCallback callback,
+ bool use_shared_db,
+ bool delete_success) {
+ if (!delete_success) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // Old data has not been removed from the database we want to use. We also
+ // know that previous attempt of migration failed for same reason. Give up
+ // on this database and use the other.
+ // This update is not necessary since this was the old value. But update to
+ // be clear.
+ client->UpdateClientInitMetadata(
+ use_shared_db
+ ? SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED
+ : SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+ db_ = use_shared_db ? std::move(unique_db) : std::move(client);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+ return;
+ }
+
+ auto* from = use_shared_db ? unique_db.get() : client.get();
+ auto* to = use_shared_db ? client.get() : unique_db.get();
+ migration_delegate_->DoMigration(
+ from, to,
+ base::BindOnce(&ProtoDatabaseSelector::OnMigrationTransferComplete, this,
+ std::move(unique_db), std::move(client), use_shared_db,
+ std::move(callback)));
+}
+
+void ProtoDatabaseSelector::OnMigrationTransferComplete(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ bool success) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (success) {
+ // Call Destroy on the DB we no longer want to use.
+ auto* db_destroy_ptr = use_shared_db ? unique_db.get() : client.get();
+ db_destroy_ptr->Destroy(
+ base::BindOnce(&ProtoDatabaseSelector::OnMigrationCleanupComplete, this,
+ std::move(unique_db), std::move(client), use_shared_db,
+ std::move(callback)));
+ return;
+ }
+
+ // Failing to transfer the old data means that the requested database to be
+ // used could have some bad data. So, mark them to be deleted before use in
+ // the next runs.
+ client->UpdateClientInitMetadata(
+ use_shared_db
+ ? SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED
+ : SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
+ db_ = use_shared_db ? std::move(unique_db) : std::move(client);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+}
+
+void ProtoDatabaseSelector::OnMigrationCleanupComplete(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ bool success) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // We still return true in our callback below because we do have a database as
+ // far as the original caller is concerned. As long as |db_| is assigned, we
+ // return true.
+ if (success) {
+ client->UpdateClientInitMetadata(
+ use_shared_db ? SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL
+ : SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL);
+ } else {
+ client->UpdateClientInitMetadata(
+ use_shared_db
+ ? SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED
+ : SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+ }
+ // Migration transfer was complete. So, we should use the requested database.
+ db_ = use_shared_db ? std::move(client) : std::move(unique_db);
+ std::move(callback).Run(Enums::InitStatus::kOK);
+ OnInitDone();
+}
+
+void ProtoDatabaseSelector::AddTransaction(base::OnceClosure task) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ switch (init_status_) {
+ case InitStatus::IN_PROGRESS:
+ if (pending_tasks_.size() > 10) {
+ std::move(pending_tasks_.front()).Run();
+ pending_tasks_.pop();
+ }
+ pending_tasks_.push(std::move(task));
+ break;
+ case InitStatus::NOT_STARTED:
+ NOTREACHED();
+ FALLTHROUGH;
+ case InitStatus::DONE:
+ std::move(task).Run();
+ break;
+ }
+}
+
+void ProtoDatabaseSelector::UpdateEntries(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_EQ(init_status_, InitStatus::DONE);
+ if (!db_) {
+ std::move(callback).Run(false);
+ return;
+ }
+ db_->UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
+ std::move(callback));
+}
+
+void ProtoDatabaseSelector::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false);
+ return;
+ }
+ db_->UpdateEntriesWithRemoveFilter(std::move(entries_to_save),
+ delete_key_filter, std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadEntries(
+ typename Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadEntries(std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadEntriesWithFilter(key_filter, options, target_prefix,
+ std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadKeysAndEntries(
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadKeysAndEntries(std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadKeysAndEntriesWithFilter(filter, options, target_prefix,
+ std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadKeysAndEntriesInRange(start, end, std::move(callback));
+}
+
+void ProtoDatabaseSelector::LoadKeys(Callbacks::LoadKeysCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->LoadKeys(std::move(callback));
+}
+
+void ProtoDatabaseSelector::GetEntry(const std::string& key,
+ typename Callbacks::GetCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false, nullptr);
+ return;
+ }
+ db_->GetEntry(key, std::move(callback));
+}
+
+void ProtoDatabaseSelector::Destroy(Callbacks::DestroyCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ if (!unique_database_dir_.empty()) {
+ ProtoLevelDBWrapper::Destroy(unique_database_dir_, client_name_,
+ task_runner_, std::move(callback));
+ return;
+ }
+
+ std::move(callback).Run(false);
+ return;
+ }
+
+ db_->Destroy(std::move(callback));
+}
+
+void ProtoDatabaseSelector::RemoveKeysForTesting(
+ const KeyFilter& key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_) {
+ std::move(callback).Run(false);
+ return;
+ }
+ db_->RemoveKeysForTesting(key_filter, target_prefix, std::move(callback));
+}
+
+void ProtoDatabaseSelector::OnInitDone() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ init_status_ = InitStatus::DONE;
+ while (!pending_tasks_.empty()) {
+ task_runner_->PostTask(FROM_HERE, std::move(pending_tasks_.front()));
+ pending_tasks_.pop();
+ }
+}
+
+} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/proto_database_selector.h b/chromium/components/leveldb_proto/internal/proto_database_selector.h
new file mode 100644
index 00000000000..706bd4f4933
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/proto_database_selector.h
@@ -0,0 +1,166 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
+#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
+
+#include <memory>
+#include <string>
+
+#include "base/containers/queue.h"
+#include "base/files/file_path.h"
+#include "base/sequenced_task_runner.h"
+#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
+
+namespace leveldb_proto {
+
+class MigrationDelegate;
+class SharedProtoDatabase;
+class SharedProtoDatabaseClient;
+class SharedProtoDatabaseProvider;
+class UniqueProtoDatabase;
+
+// A wrapper around unique and shared database client. Handles initialization of
+// underlying database as unique or shared as requested.
+// TODO: Discuss the init flow/migration path for unique/shared DB here.
+class ProtoDatabaseSelector
+ : public base::RefCountedThreadSafe<ProtoDatabaseSelector> {
+ public:
+ ProtoDatabaseSelector(
+ ProtoDbType db_type,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
+
+ void InitWithDatabase(
+ LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::InitStatusCallback callback);
+
+ void InitUniqueOrShared(
+ const std::string& client_name,
+ base::FilePath db_dir,
+ const leveldb_env::Options& options,
+ bool use_shared_db,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ Callbacks::InitStatusCallback callback);
+
+ void AddTransaction(base::OnceClosure task);
+
+ // DO NOT USE any of the functions below directly. They should be posted as
+ // transaction tasks using AddTransaction().
+ void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback);
+
+ void UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback);
+
+ void LoadEntries(typename Callbacks::LoadCallback callback);
+
+ void LoadEntriesWithFilter(const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadCallback callback);
+
+ void LoadKeysAndEntries(
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
+
+ void LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
+ void LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
+
+ void LoadKeys(Callbacks::LoadKeysCallback callback);
+
+ void GetEntry(const std::string& key,
+ typename Callbacks::GetCallback callback);
+
+ void Destroy(Callbacks::DestroyCallback callback);
+
+ void RemoveKeysForTesting(const KeyFilter& key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback);
+
+ UniqueProtoDatabase* db_for_testing() { return db_.get(); }
+
+ private:
+ friend class base::RefCountedThreadSafe<ProtoDatabaseSelector>;
+ friend class ProtoDatabaseImplTest;
+
+ enum class InitStatus {
+ NOT_STARTED,
+ IN_PROGRESS,
+ DONE // success or failure.
+ };
+
+ ~ProtoDatabaseSelector();
+
+ void OnInitUniqueDB(std::unique_ptr<UniqueProtoDatabase> db,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ Enums::InitStatus status);
+
+ void OnInitSharedDB(std::unique_ptr<UniqueProtoDatabase> unique_db,
+ Enums::InitStatus unique_db_status,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ scoped_refptr<SharedProtoDatabase> shared_db);
+ void OnGetSharedDBClient(std::unique_ptr<UniqueProtoDatabase> unique_db,
+ Enums::InitStatus unique_db_status,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ Enums::InitStatus shared_db_status);
+ void DeleteOldDataAndMigrate(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback);
+ void MaybeDoMigrationOnDeletingOld(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ Callbacks::InitStatusCallback init_callback,
+ bool use_shared_db,
+ bool delete_success);
+ void OnMigrationTransferComplete(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ bool success);
+ void OnMigrationCleanupComplete(
+ std::unique_ptr<UniqueProtoDatabase> unique_db,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ bool use_shared_db,
+ Callbacks::InitStatusCallback callback,
+ bool success);
+ void OnInitDone();
+
+ ProtoDbType db_type_;
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ const std::unique_ptr<SharedProtoDatabaseProvider> db_provider_;
+ const std::unique_ptr<MigrationDelegate> migration_delegate_;
+
+ InitStatus init_status_ = InitStatus::NOT_STARTED;
+ base::queue<base::OnceClosure> pending_tasks_;
+ std::unique_ptr<UniqueProtoDatabase> db_;
+ base::FilePath unique_database_dir_;
+ std::string client_name_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+};
+
+} // namespace leveldb_proto
+
+#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
diff --git a/chromium/components/leveldb_proto/internal/proto_database_wrapper.cc b/chromium/components/leveldb_proto/internal/proto_database_wrapper.cc
deleted file mode 100644
index abb7b0a69fe..00000000000
--- a/chromium/components/leveldb_proto/internal/proto_database_wrapper.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/leveldb_proto/internal/proto_database_wrapper.h"
-
-#include "components/leveldb_proto/public/proto_database_provider.h"
-
-namespace leveldb_proto {
-
-void GetSharedDBInstance(
- ProtoDatabaseProvider* db_provider,
- base::OnceCallback<void(scoped_refptr<SharedProtoDatabase>)> callback) {
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- db_provider->GetSharedDBInstance(std::move(callback),
- base::SequencedTaskRunnerHandle::Get());
-}
-
-} // namespace leveldb_proto \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_database_wrapper.h b/chromium/components/leveldb_proto/internal/proto_database_wrapper.h
deleted file mode 100644
index 7617b8a3d31..00000000000
--- a/chromium/components/leveldb_proto/internal/proto_database_wrapper.h
+++ /dev/null
@@ -1,707 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_WRAPPER_H_
-#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_WRAPPER_H_
-
-#include "base/files/file_path.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "components/leveldb_proto/internal/migration_delegate.h"
-#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
-#include "components/leveldb_proto/internal/shared_proto_database.h"
-#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
-#include "components/leveldb_proto/internal/unique_proto_database.h"
-#include "components/leveldb_proto/public/proto_database.h"
-#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
-
-namespace leveldb_proto {
-
-class ProtoDatabaseProvider;
-
-// Avoids circular dependencies between ProtoDatabaseWrapper and
-// ProtoDatabaseProvider, since we'd need to include the provider header here
-// to use |db_provider_|'s GetSharedDBInstance.
-void GetSharedDBInstance(
- ProtoDatabaseProvider* db_provider,
- base::OnceCallback<void(scoped_refptr<SharedProtoDatabase>)> callback);
-
-// The ProtoDatabaseWrapper<T> owns a ProtoDatabase<T> instance, and allows the
-// underlying ProtoDatabase<T> implementation to change without users of the
-// wrapper needing to know.
-// This allows clients to request a DB instance without knowing whether or not
-// it's a UniqueDatabase<T> or a SharedProtoDatabaseClient<T>.
-//
-// TODO: Discuss the init flow/migration path for unique/shared DB here.
-template <typename T>
-class ProtoDatabaseWrapper : public UniqueProtoDatabase<T> {
- public:
- ProtoDatabaseWrapper(
- const std::string& client_namespace,
- const std::string& type_prefix,
- const base::FilePath& db_dir,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
-
- virtual ~ProtoDatabaseWrapper() = default;
-
- // This version of Init is for compatibility, since many of the current
- // proto database still use this.
- void Init(const char* client_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitCallback callback) override;
-
- void Init(const std::string& client_name,
- Callbacks::InitStatusCallback callback) override;
-
- void UpdateEntries(std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
- Callbacks::UpdateCallback callback) override;
-
- void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
- const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) override;
- void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) override;
-
- void LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) override;
-
- void LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
- void LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
-
- void LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
-
- void LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
- void LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
- void LoadKeysAndEntriesInRange(
- const std::string& start,
- const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
-
- void LoadKeys(Callbacks::LoadKeysCallback callback) override;
- void LoadKeys(const std::string& target_prefix,
- Callbacks::LoadKeysCallback callback) override;
-
- void GetEntry(const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) override;
-
- void Destroy(Callbacks::DestroyCallback callback) override;
-
- void RunCallbackOnCallingSequence(base::OnceClosure callback);
-
- private:
- friend class ProtoDatabaseWrapperTest;
-
- void Init(const std::string& client_name,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback);
-
- virtual void InitUniqueDB(const std::string& client_name,
- const leveldb_env::Options& options,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback);
- void OnInitUniqueDB(std::unique_ptr<ProtoDatabase<T>> db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- Enums::InitStatus status);
-
- // |unique_db| should contain a nullptr if initializing the DB fails.
- void GetSharedDBClient(std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback);
- void OnInitSharedDB(std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- scoped_refptr<SharedProtoDatabase> shared_db);
- void OnGetSharedDBClient(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client);
- void DeleteOldDataAndMigrate(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback);
- void MaybeDoMigrationOnDeletingOld(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- Callbacks::InitStatusCallback init_callback,
- bool use_shared_db,
- bool delete_success);
- void OnMigrationTransferComplete(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- bool success);
- void OnMigrationCleanupComplete(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- bool success);
-
- std::string client_namespace_;
- std::string type_prefix_;
- base::FilePath db_dir_;
- std::unique_ptr<SharedProtoDatabaseProvider> db_provider_;
-
- std::unique_ptr<ProtoDatabase<T>> db_;
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- std::unique_ptr<MigrationDelegate<T>> migration_delegate_;
-
- std::unique_ptr<base::WeakPtrFactory<ProtoDatabaseWrapper<T>>>
- weak_ptr_factory_;
-};
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::RunCallbackOnCallingSequence(
- base::OnceClosure callback) {
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- std::move(callback));
-}
-
-template <typename T>
-ProtoDatabaseWrapper<T>::ProtoDatabaseWrapper(
- const std::string& client_namespace,
- const std::string& type_prefix,
- const base::FilePath& db_dir,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
- : UniqueProtoDatabase<T>(task_runner) {
- client_namespace_ = client_namespace;
- type_prefix_ = type_prefix;
- db_dir_ = db_dir;
- db_ = nullptr;
- db_provider_ = std::move(db_provider);
- task_runner_ = task_runner;
- migration_delegate_ = std::make_unique<MigrationDelegate<T>>();
- weak_ptr_factory_ =
- std::make_unique<base::WeakPtrFactory<ProtoDatabaseWrapper<T>>>(this);
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::Init(const char* client_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitCallback callback) {
- // We shouldn't be calling this on the wrapper. This function is purely for
- // compatibility right now.
- NOTREACHED();
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::Init(
- const std::string& client_name,
- typename Callbacks::InitStatusCallback callback) {
- bool use_shared_db =
- SharedProtoDatabaseClientList::ShouldUseSharedDB(client_name);
- Init(client_name, use_shared_db, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::Init(const std::string& client_name,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback) {
- auto options = CreateSimpleOptions();
- // If we're NOT using a shared DB, we want to force creation of the unique one
- // because that's what we expect to be using moving forward. If we ARE using
- // the shared DB, we only want to see if there's a unique DB that already
- // exists and can be opened so that we can perform migration if necessary.
- options.create_if_missing = !use_shared_db;
- InitUniqueDB(client_name, options, use_shared_db, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::InitUniqueDB(
- const std::string& client_name,
- const leveldb_env::Options& options,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback) {
- auto unique_db = std::make_unique<UniqueProtoDatabase<T>>(db_dir_, options,
- this->task_runner_);
- auto* unique_db_ptr = unique_db.get();
- unique_db_ptr->Init(
- client_name,
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnInitUniqueDB,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- use_shared_db, std::move(callback)));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::OnInitUniqueDB(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- Enums::InitStatus status) {
- // If the unique DB is corrupt, just return it early with the corruption
- // status to avoid silently migrating a corrupt database and giving no errors
- // back.
- if (status == Enums::InitStatus::kCorrupt) {
- db_ = std::move(unique_db);
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kCorrupt));
- return;
- }
-
- // Clear out the unique_db before sending an unusable DB into InitSharedDB,
- // a nullptr indicates opening a unique DB failed.
- if (status != Enums::InitStatus::kOK)
- unique_db.reset();
-
- GetSharedDBClient(std::move(unique_db), use_shared_db, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::GetSharedDBClient(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback) {
- // Get the current task runner to ensure the callback is run on the same
- // callback as the rest, and the WeakPtr checks out on the right sequence.
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
-
- db_provider_->GetDBInstance(
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnInitSharedDB,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- use_shared_db, std::move(callback)),
- current_task_runner);
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::OnInitSharedDB(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- scoped_refptr<SharedProtoDatabase> shared_db) {
- if (shared_db) {
- // If we have a reference to the shared database, try to get a client.
- shared_db->GetClientAsync<T>(
- client_namespace_, type_prefix_, use_shared_db,
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnGetSharedDBClient,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- use_shared_db, std::move(callback)));
- return;
- }
-
- // Otherwise, we just call the OnGetSharedDBClient function with a nullptr
- // client.
- OnGetSharedDBClient(std::move(unique_db), use_shared_db, std::move(callback),
- nullptr);
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::OnGetSharedDBClient(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client) {
- if (!unique_db && !client) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kError));
- return;
- }
-
- if (!unique_db || !client) {
- // One of two things happened:
- // 1) We failed to get a shared DB instance, so regardless of whether we
- // want to use the shared DB or not, we'll settle for the unique DB.
- // 2) We failed to initialize a unique DB, but got access to the shared DB,
- // so we use that regardless of whether we "should be" or not.
- db_ = client ? std::move(client) : std::move(unique_db);
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kOK));
- return;
- }
-
- ProtoDatabase<T>* from = nullptr;
- ProtoDatabase<T>* to = nullptr;
- if (use_shared_db) {
- switch (client->migration_status()) {
- case SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED:
- case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL:
- from = unique_db.get();
- to = client.get();
- break;
- case SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL:
- // Unique db was deleted in previous migration, so nothing to do here.
- return OnMigrationCleanupComplete(std::move(unique_db),
- std::move(client), use_shared_db,
- std::move(callback), true);
- case SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED:
- // Migration transfer was completed, so just try deleting the unique db.
- return OnMigrationTransferComplete(std::move(unique_db),
- std::move(client), use_shared_db,
- std::move(callback), true);
- case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED:
- // Shared db was not deleted in last migration and we want to use shared
- // db. So, delete stale data, and attempt migration.
- return DeleteOldDataAndMigrate(std::move(unique_db), std::move(client),
- use_shared_db, std::move(callback));
- };
- } else {
- switch (client->migration_status()) {
- case SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED:
- case SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL:
- from = client.get();
- to = unique_db.get();
- break;
- case SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED:
- // Unique db was not deleted in last migration and we want to use unique
- // db. So, delete stale data, and attempt migration.
- return DeleteOldDataAndMigrate(std::move(unique_db), std::move(client),
- use_shared_db, std::move(callback));
- case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL:
- // Shared db was deleted in previous migration, so nothing to do here.
- return OnMigrationCleanupComplete(std::move(unique_db),
- std::move(client), use_shared_db,
- std::move(callback), true);
- case SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED:
- // Migration transfer was completed, so just try deleting the shared db.
- return OnMigrationTransferComplete(std::move(unique_db),
- std::move(client), use_shared_db,
- std::move(callback), true);
- };
- }
-
- // We got access to both the unique DB and a shared DB, meaning we need to
- // attempt migration and give back the right one.
- migration_delegate_->DoMigration(
- from, to,
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnMigrationTransferComplete,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- std::move(client), use_shared_db, std::move(callback)));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::DeleteOldDataAndMigrate(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback) {
- ProtoDatabase<T>* to_remove_old_data =
- use_shared_db ? client.get() : unique_db.get();
- auto maybe_do_migration =
- base::BindOnce(&ProtoDatabaseWrapper<T>::MaybeDoMigrationOnDeletingOld,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- std::move(client), std::move(callback), use_shared_db);
-
- to_remove_old_data->UpdateEntriesWithRemoveFilter(
- std::make_unique<typename Util::Internal<T>::KeyEntryVector>(),
- base::BindRepeating([](const std::string& key) { return true; }),
- std::move(maybe_do_migration));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::MaybeDoMigrationOnDeletingOld(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- Callbacks::InitStatusCallback callback,
- bool use_shared_db,
- bool delete_success) {
- if (!delete_success) {
- // Old data has not been removed from the database we want to use. We also
- // know that previous attempt of migration failed for same reason. Give up
- // on this database and use the other.
- // This update is not necessary since this was the old value. But update to
- // be clear.
- client->UpdateClientInitMetadata(
- use_shared_db
- ? SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED
- : SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
- db_ = use_shared_db ? std::move(unique_db) : std::move(client);
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kOK));
- return;
- }
-
- auto from = use_shared_db ? unique_db.get() : client.get();
- auto to = use_shared_db ? client.get() : unique_db.get();
- migration_delegate_->DoMigration(
- from, to,
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnMigrationTransferComplete,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- std::move(client), use_shared_db, std::move(callback)));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::OnMigrationTransferComplete(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- bool success) {
- if (success) {
- // Call Destroy on the DB we no longer want to use.
- auto* db_destroy_ptr = use_shared_db ? unique_db.get() : client.get();
- db_destroy_ptr->Destroy(
- base::BindOnce(&ProtoDatabaseWrapper<T>::OnMigrationCleanupComplete,
- weak_ptr_factory_->GetWeakPtr(), std::move(unique_db),
- std::move(client), use_shared_db, std::move(callback)));
- return;
- }
-
- // Failing to transfer the old data means that the requested database to be
- // used could have some bad data. So, mark them to be deleted before use in
- // the next runs.
- client->UpdateClientInitMetadata(
- use_shared_db
- ? SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED
- : SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
- db_ = use_shared_db ? std::move(unique_db) : std::move(client);
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kOK));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::OnMigrationCleanupComplete(
- std::unique_ptr<ProtoDatabase<T>> unique_db,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback,
- bool success) {
- // We still return true in our callback below because we do have a database as
- // far as the original caller is concerned. As long as |db_| is assigned, we
- // return true.
- if (success) {
- client->UpdateClientInitMetadata(
- use_shared_db ? SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL
- : SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL);
- } else {
- client->UpdateClientInitMetadata(
- use_shared_db
- ? SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED
- : SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
- }
- // Migration transfer was complete. So, we should use the requested database.
- db_ = use_shared_db ? std::move(client) : std::move(unique_db);
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), Enums::InitStatus::kOK));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::UpdateEntries(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
- Callbacks::UpdateCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(std::move(callback), false));
- return;
- }
-
- db_->UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
- std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(std::move(callback), false));
- return;
- }
-
- db_->UpdateEntriesWithRemoveFilter(std::move(entries_to_save),
- delete_key_filter, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(std::move(callback), false));
- return;
- }
-
- db_->UpdateEntriesWithRemoveFilter(std::move(entries_to_save),
- delete_key_filter, target_prefix,
- std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(
- std::move(callback), false, std::make_unique<std::vector<T>>()));
- return;
- }
-
- db_->LoadEntries(std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(
- std::move(callback), false, std::make_unique<std::vector<T>>()));
- return;
- }
-
- db_->LoadEntriesWithFilter(filter, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(
- std::move(callback), false, std::make_unique<std::vector<T>>()));
- return;
- }
-
- db_->LoadEntriesWithFilter(key_filter, options, target_prefix,
- std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::map<std::string, T>>()));
- return;
- }
-
- db_->LoadKeysAndEntries(std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::map<std::string, T>>()));
- return;
- }
-
- db_->LoadKeysAndEntriesWithFilter(filter, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::map<std::string, T>>()));
- return;
- }
-
- db_->LoadKeysAndEntriesWithFilter(filter, options, target_prefix,
- std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeysAndEntriesInRange(
- const std::string& start,
- const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::map<std::string, T>>()));
- return;
- }
-
- db_->LoadKeysAndEntriesInRange(start, end, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::vector<std::string>>()));
- return;
- }
-
- db_->LoadKeys(std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::LoadKeys(const std::string& target_prefix,
- Callbacks::LoadKeysCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false,
- std::make_unique<std::vector<std::string>>()));
- return;
- }
-
- db_->LoadKeys(target_prefix, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::GetEntry(
- const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(
- base::BindOnce(std::move(callback), false, std::make_unique<T>()));
- return;
- }
-
- db_->GetEntry(key, std::move(callback));
-}
-
-template <typename T>
-void ProtoDatabaseWrapper<T>::Destroy(Callbacks::DestroyCallback callback) {
- if (!db_) {
- RunCallbackOnCallingSequence(base::BindOnce(std::move(callback), false));
- return;
- }
-
- db_->Destroy(std::move(callback));
-}
-
-} // namespace leveldb_proto
-
-#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_WRAPPER_H_ \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_database_wrapper_unittest.cc b/chromium/components/leveldb_proto/internal/proto_database_wrapper_unittest.cc
deleted file mode 100644
index 43e61c4295c..00000000000
--- a/chromium/components/leveldb_proto/internal/proto_database_wrapper_unittest.cc
+++ /dev/null
@@ -1,562 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/leveldb_proto/internal/proto_database_wrapper.h"
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread.h"
-#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
-#include "components/leveldb_proto/public/proto_database_provider.h"
-#include "components/leveldb_proto/testing/proto/test_db.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace leveldb_proto {
-
-namespace {
-
-const std::string kDefaultNamespace = "namespace";
-const std::string kDefaultTypePrefix = "prefix";
-const std::string kDefaultClientName = "client";
-
-} // namespace
-
-class TestProtoDatabaseProvider : public ProtoDatabaseProvider {
- public:
- TestProtoDatabaseProvider(const base::FilePath& profile_dir)
- : ProtoDatabaseProvider(profile_dir) {}
- TestProtoDatabaseProvider(const base::FilePath& profile_dir,
- const scoped_refptr<SharedProtoDatabase>& shared_db)
- : ProtoDatabaseProvider(profile_dir) {
- shared_db_ = shared_db;
- }
-
- void GetSharedDBInstance(
- ProtoDatabaseProvider::GetSharedDBInstanceCallback callback,
- scoped_refptr<base::SequencedTaskRunner> callback_task_runner) override {
- callback_task_runner->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), shared_db_));
- }
-
- private:
- scoped_refptr<SharedProtoDatabase> shared_db_;
-};
-
-class TestSharedProtoDatabaseProvider : public SharedProtoDatabaseProvider {
- public:
- TestSharedProtoDatabaseProvider(
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- base::WeakPtr<ProtoDatabaseProvider> provider_weak_ptr)
- : SharedProtoDatabaseProvider(std::move(task_runner),
- std::move(provider_weak_ptr)) {}
-};
-
-class ProtoDatabaseWrapperTest : public testing::Test {
- public:
- void SetUp() override {
- temp_dir_ = std::make_unique<base::ScopedTempDir>();
- ASSERT_TRUE(temp_dir_->CreateUniqueTempDir());
- shared_db_temp_dir_ = std::make_unique<base::ScopedTempDir>();
- ASSERT_TRUE(shared_db_temp_dir_->CreateUniqueTempDir());
- test_thread_ = std::make_unique<base::Thread>("test_thread");
- ASSERT_TRUE(test_thread_->Start());
- shared_db_ = base::WrapRefCounted(new SharedProtoDatabase(
- kDefaultClientName, shared_db_temp_dir_->GetPath()));
- }
-
- void TearDown() override {
- temp_dir_.reset();
- shared_db_temp_dir_.reset();
- }
-
- std::unique_ptr<ProtoDatabaseWrapper<TestProto>> CreateWrapper(
- const std::string& client_namespace,
- const std::string& type_prefix,
- const base::FilePath& db_dir,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner,
- std::unique_ptr<SharedProtoDatabaseProvider> db_provider) {
- return std::make_unique<ProtoDatabaseWrapper<TestProto>>(
- client_namespace, type_prefix, db_dir, task_runner,
- std::move(db_provider));
- }
-
- std::unique_ptr<TestProtoDatabaseProvider> CreateProviderNoSharedDB() {
- return std::make_unique<TestProtoDatabaseProvider>(
- shared_db_temp_dir_->GetPath());
- }
-
- std::unique_ptr<TestProtoDatabaseProvider> CreateProviderWithSharedDB() {
- return std::make_unique<TestProtoDatabaseProvider>(
- shared_db_temp_dir_->GetPath(), shared_db_);
- }
-
- std::unique_ptr<TestSharedProtoDatabaseProvider> CreateSharedProvider(
- TestProtoDatabaseProvider* db_provider) {
- return std::make_unique<TestSharedProtoDatabaseProvider>(
- GetTestThreadTaskRunner(), db_provider->weak_factory_.GetWeakPtr());
- }
-
- // Uses ProtoDatabaseWrapper's 3 parameter Init to bypass the check that gets
- // |use_shared_db|'s value.
- void InitWrapper(ProtoDatabaseWrapper<TestProto>* wrapper,
- const std::string& client_name,
- bool use_shared_db,
- Callbacks::InitStatusCallback callback) {
- wrapper->Init(client_name, use_shared_db, std::move(callback));
- }
-
- void InitWrapperAndWait(ProtoDatabaseWrapper<TestProto>* wrapper,
- const std::string& client_name,
- bool use_shared_db,
- Enums::InitStatus expect_status) {
- base::RunLoop init_loop;
- InitWrapper(
- wrapper, client_name, use_shared_db,
- base::BindOnce(
- [](base::OnceClosure closure, Enums::InitStatus expect_status,
- Enums::InitStatus status) {
- ASSERT_EQ(status, expect_status);
- std::move(closure).Run();
- },
- init_loop.QuitClosure(), expect_status));
- init_loop.Run();
- }
-
- // Just uses each entry's key to fill out the id/data fields in TestProto as
- // well.
- void AddDataToWrapper(ProtoDatabaseWrapper<TestProto>* wrapper,
- std::vector<std::string>* entry_keys) {
- auto data_set =
- std::make_unique<std::vector<std::pair<std::string, TestProto>>>();
- for (const auto& key : *entry_keys) {
- TestProto proto;
- proto.set_id(key);
- proto.set_data(key);
- data_set->emplace_back(std::make_pair(key, proto));
- }
-
- base::RunLoop data_loop;
- wrapper->UpdateEntries(std::move(data_set),
- std::make_unique<std::vector<std::string>>(),
- base::BindOnce(
- [](base::OnceClosure closure, bool success) {
- ASSERT_TRUE(success);
- std::move(closure).Run();
- },
- data_loop.QuitClosure()));
- data_loop.Run();
- }
-
- void VerifyDataInWrapper(ProtoDatabaseWrapper<TestProto>* wrapper,
- std::vector<std::string>* entry_keys) {
- base::RunLoop load_loop;
- wrapper->LoadKeysAndEntries(base::BindOnce(
- [](base::OnceClosure closure, std::vector<std::string>* entry_keys,
- bool success,
- std::unique_ptr<std::map<std::string, TestProto>> keys_entries) {
- ASSERT_TRUE(success);
- ASSERT_EQ(entry_keys->size(), keys_entries->size());
-
- for (const auto& key : *entry_keys) {
- ASSERT_TRUE(keys_entries->find(key) != keys_entries->end());
- }
- std::move(closure).Run();
- },
- load_loop.QuitClosure(), entry_keys));
- load_loop.Run();
- }
-
- void UpdateClientMetadata(
- SharedDBMetadataProto::MigrationStatus migration_status) {
- base::RunLoop init_wait;
- auto client = shared_db_->GetClientForTesting<TestProto>(
- kDefaultNamespace, kDefaultTypePrefix, /*create_if_missing=*/true,
- base::BindOnce(
- [](base::OnceClosure closure, Enums::InitStatus status,
- SharedDBMetadataProto::MigrationStatus migration_status) {
- EXPECT_EQ(Enums::kOK, status);
- EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
- migration_status);
- std::move(closure).Run();
- },
- init_wait.QuitClosure()));
- init_wait.Run();
-
- base::RunLoop wait_loop;
- shared_db_->UpdateClientMetadataAsync(
- client->client_db_id(), migration_status,
- base::BindOnce(
- [](base::OnceClosure closure, bool success) {
- EXPECT_TRUE(success);
- std::move(closure).Run();
- },
- wait_loop.QuitClosure()));
- wait_loop.Run();
- }
-
- SharedDBMetadataProto::MigrationStatus GetClientMigrationStatus() {
- SharedDBMetadataProto::MigrationStatus migration_status;
- base::RunLoop init_wait;
- auto client = shared_db_->GetClientForTesting<TestProto>(
- kDefaultNamespace, kDefaultTypePrefix, /*create_if_missing=*/true,
- base::BindOnce(
- [](base::OnceClosure closure,
- SharedDBMetadataProto::MigrationStatus* output,
- Enums::InitStatus status,
- SharedDBMetadataProto::MigrationStatus migration_status) {
- EXPECT_EQ(Enums::kOK, status);
- *output = migration_status;
- std::move(closure).Run();
- },
- init_wait.QuitClosure(), &migration_status));
- init_wait.Run();
-
- return migration_status;
- }
-
- scoped_refptr<base::SequencedTaskRunner> GetTestThreadTaskRunner() {
- return test_thread_->task_runner();
- }
-
- base::FilePath temp_dir() { return temp_dir_->GetPath(); }
-
- private:
- std::unique_ptr<base::ScopedTempDir> temp_dir_;
- base::test::ScopedTaskEnvironment scoped_task_environment_;
-
- // Shared database.
- std::unique_ptr<base::Thread> test_thread_;
- std::unique_ptr<base::Thread> shared_db_thread_;
- scoped_refptr<SharedProtoDatabase> shared_db_;
- std::unique_ptr<base::ScopedTempDir> shared_db_temp_dir_;
-};
-
-TEST_F(ProtoDatabaseWrapperTest, FailsBothDatabases) {
- auto db_provider = CreateProviderNoSharedDB();
- auto shared_db_provider = CreateSharedProvider(db_provider.get());
- auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kError);
-}
-
-TEST_F(ProtoDatabaseWrapperTest, SucceedsWithUnique_DontUseShared_NoSharedDB) {
- auto db_provider = CreateProviderNoSharedDB();
- auto shared_db_provider = CreateSharedProvider(db_provider.get());
- auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Fails_UseShared_NoSharedDB_NoUniqueDB) {
- auto db_provider = CreateProviderNoSharedDB();
- auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kError);
-}
-
-TEST_F(ProtoDatabaseWrapperTest, SucceedsWithUnique_UseShared_NoSharedDB) {
- // First we create a unique DB so our second pass has a unique DB available.
- auto db_provider = CreateProviderNoSharedDB();
- auto unique_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- // Kill the wrapper so it doesn't have a lock on the DB anymore.
- unique_wrapper.reset();
-
- auto shared_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
-}
-
-TEST_F(ProtoDatabaseWrapperTest, SucceedsWithShared_UseShared_HasSharedDB) {
- auto db_provider = CreateProviderWithSharedDB();
- auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
-}
-
-TEST_F(ProtoDatabaseWrapperTest, SucceedsWithUnique_DontUseShared_HasSharedDB) {
- auto db_provider = CreateProviderWithSharedDB();
- auto wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
-}
-
-// Migration tests:
-TEST_F(ProtoDatabaseWrapperTest, Migration_EmptyDBs_UniqueToShared) {
- // First we create a unique DB so our second pass has a unique DB available.
- auto db_provider_noshared = CreateProviderNoSharedDB();
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_noshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- // Kill the wrapper so it doesn't have a lock on the DB anymore.
- unique_wrapper.reset();
-
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
-
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_EmptyDBs_SharedToUnique) {
- // First we create a unique DB so our second pass has a unique DB available.
- auto db_provider = CreateProviderWithSharedDB();
- auto shared_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
- EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
- GetClientMigrationStatus());
-
- auto unique_wrapper = CreateWrapper(kDefaultNamespace, kDefaultTypePrefix,
- temp_dir(), GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_UniqueToShared) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a unique DB so our second pass has a unique DB available.
- auto db_provider_noshared = CreateProviderNoSharedDB();
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_noshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- AddDataToWrapper(unique_wrapper.get(), data_set.get());
- // Kill the wrapper so it doesn't have a lock on the DB anymore.
- unique_wrapper.reset();
-
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
- VerifyDataInWrapper(shared_wrapper.get(), data_set.get());
-
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_SharedToUnique) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a shared DB so our second pass has a shared DB available.
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
- AddDataToWrapper(shared_wrapper.get(), data_set.get());
-
- EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
- GetClientMigrationStatus());
-
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- VerifyDataInWrapper(unique_wrapper.get(), data_set.get());
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_UniqueToShared_UniqueObsolete) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a unique DB so our second pass has a unique DB available.
- auto db_provider_noshared = CreateProviderNoSharedDB();
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_noshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- AddDataToWrapper(unique_wrapper.get(), data_set.get());
- // Kill the wrapper so it doesn't have a lock on the DB anymore.
- unique_wrapper.reset();
-
- UpdateClientMetadata(
- SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
-
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
-
- // Unique db should be deleted in migration. So, shared db should be clean.
- data_set->clear();
- VerifyDataInWrapper(shared_wrapper.get(), data_set.get());
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_UniqueToShared_SharedObsolete) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a shared DB so our second pass has a shared DB available.
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
- AddDataToWrapper(shared_wrapper.get(), data_set.get());
-
- // Force create an uniquedb, which was deleted by migration.
- auto db_provider_noshared = CreateProviderNoSharedDB();
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_noshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- unique_wrapper.reset();
- EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
- GetClientMigrationStatus());
-
- UpdateClientMetadata(
- SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
-
- shared_wrapper.reset();
- db_provider_withshared = CreateProviderWithSharedDB();
-
- auto shared_wrapper1 =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper1.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
-
- // Shared db should be deleted in migration. So, shared db should be clean.
- data_set->clear();
- VerifyDataInWrapper(shared_wrapper1.get(), data_set.get());
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_SharedToUnique_SharedObsolete) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a shared DB so our second pass has a shared DB available.
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, true,
- Enums::InitStatus::kOK);
- AddDataToWrapper(shared_wrapper.get(), data_set.get());
-
- EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
- GetClientMigrationStatus());
-
- UpdateClientMetadata(
- SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
-
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
-
- // Shared db should be deleted in migration. So, unique db should be clean.
- data_set->clear();
- VerifyDataInWrapper(unique_wrapper.get(), data_set.get());
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-TEST_F(ProtoDatabaseWrapperTest, Migration_SharedToUnique_UniqueObsolete) {
- auto data_set = std::make_unique<std::vector<std::string>>();
- data_set->emplace_back("entry1");
- data_set->emplace_back("entry2");
- data_set->emplace_back("entry3");
-
- // First we create a shared DB so our second pass has a shared DB available.
- auto db_provider_noshared = CreateProviderNoSharedDB();
- auto unique_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_noshared.get()));
- InitWrapperAndWait(unique_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
- AddDataToWrapper(unique_wrapper.get(), data_set.get());
-
- UpdateClientMetadata(
- SharedDBMetadataProto::MIGRATE_TO_SHARED_UNIQUE_TO_BE_DELETED);
-
- unique_wrapper.reset();
-
- auto db_provider_withshared = CreateProviderWithSharedDB();
- auto shared_wrapper =
- CreateWrapper(kDefaultNamespace, kDefaultTypePrefix, temp_dir(),
- GetTestThreadTaskRunner(),
- CreateSharedProvider(db_provider_withshared.get()));
- InitWrapperAndWait(shared_wrapper.get(), kDefaultClientName, false,
- Enums::InitStatus::kOK);
-
- // Unique db should be deleted in migration. So, unique db should be clean.
- data_set->clear();
- VerifyDataInWrapper(shared_wrapper.get(), data_set.get());
- EXPECT_EQ(SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SUCCESSFUL,
- GetClientMigrationStatus());
-}
-
-} // namespace leveldb_proto \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.cc b/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.cc
index 7a817b3b56a..34758d05986 100644
--- a/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.cc
+++ b/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.cc
@@ -4,10 +4,13 @@
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
+#include <string>
+
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "components/leveldb_proto/internal/leveldb_database.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h"
#include "components/leveldb_proto/public/proto_database.h"
@@ -41,13 +44,25 @@ bool DestroyFromTaskRunner(LevelDB* database, const std::string& client_id) {
return success;
}
+bool DestroyWithDirectoryFromTaskRunner(const base::FilePath& db_dir,
+ const std::string& client_id) {
+ leveldb::Status result = leveldb::DestroyDB(
+ db_dir.AsUTF8Unsafe(), leveldb_proto::CreateSimpleOptions());
+ bool success = result.ok();
+
+ if (!client_id.empty())
+ ProtoLevelDBWrapperMetrics::RecordDestroy(client_id, success);
+
+ return success;
+}
+
void LoadKeysFromTaskRunner(
LevelDB* database,
const std::string& target_prefix,
const std::string& client_id,
Callbacks::LoadKeysCallback callback,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
- auto keys = std::make_unique<std::vector<std::string>>();
+ auto keys = std::make_unique<KeyVector>();
bool success = database->LoadKeys(target_prefix, keys.get());
ProtoLevelDBWrapperMetrics::RecordLoadKeys(client_id, success);
callback_task_runner->PostTask(
@@ -69,6 +84,91 @@ void RemoveKeysFromTaskRunner(
base::BindOnce(std::move(callback), success));
}
+void RunLoadCallback(Callbacks::LoadCallback callback,
+ bool* success,
+ std::unique_ptr<ValueVector> entries) {
+ std::move(callback).Run(*success, std::move(entries));
+}
+
+void RunLoadKeysAndEntriesCallback(
+ Callbacks::LoadKeysAndEntriesCallback callback,
+ bool* success,
+ std::unique_ptr<KeyValueMap> keys_entries) {
+ std::move(callback).Run(*success, std::move(keys_entries));
+}
+
+void RunGetCallback(Callbacks::GetCallback callback,
+ const bool* success,
+ const bool* found,
+ std::unique_ptr<std::string> entry) {
+ std::move(callback).Run(*success, *found ? std::move(entry) : nullptr);
+}
+
+bool UpdateEntriesFromTaskRunner(
+ LevelDB* database,
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ const std::string& client_id) {
+ leveldb::Status status;
+ bool success = database->Save(*entries_to_save, *keys_to_remove, &status);
+ ProtoLevelDBWrapperMetrics::RecordUpdate(client_id, success, status);
+ return success;
+}
+
+bool UpdateEntriesWithRemoveFilterFromTaskRunner(
+ LevelDB* database,
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ const std::string& target_prefix,
+ const std::string& client_id) {
+ leveldb::Status status;
+ bool success = database->UpdateWithRemoveFilter(
+ *entries_to_save, delete_key_filter, target_prefix, &status);
+ ProtoLevelDBWrapperMetrics::RecordUpdate(client_id, success, status);
+ return success;
+}
+
+void LoadKeysAndEntriesFromTaskRunner(LevelDB* database,
+ const KeyFilter& while_callback,
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ const std::string& client_id,
+ bool* success,
+ KeyValueMap* keys_entries) {
+ DCHECK(success);
+ DCHECK(keys_entries);
+ keys_entries->clear();
+
+ *success = database->LoadKeysAndEntriesWhile(filter, keys_entries, options,
+ target_prefix, while_callback);
+
+ ProtoLevelDBWrapperMetrics::RecordLoadKeysAndEntries(client_id, success);
+}
+
+void LoadEntriesFromTaskRunner(LevelDB* database,
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ const std::string& client_id,
+ bool* success,
+ ValueVector* entries) {
+ *success = database->LoadWithFilter(filter, entries, options, target_prefix);
+
+ ProtoLevelDBWrapperMetrics::RecordLoadEntries(client_id, success);
+}
+
+void GetEntryFromTaskRunner(LevelDB* database,
+ const std::string& key,
+ const std::string& client_id,
+ bool* success,
+ bool* found,
+ std::string* entry) {
+ leveldb::Status status;
+ *success = database->Get(key, found, entry, &status);
+
+ ProtoLevelDBWrapperMetrics::RecordGet(client_id, *success, *found, status);
+}
} // namespace
ProtoLevelDBWrapper::ProtoLevelDBWrapper(
@@ -108,6 +208,150 @@ void ProtoLevelDBWrapper::InitWithDatabase(
std::move(callback));
}
+void ProtoLevelDBWrapper::UpdateEntries(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ typename Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::PostTaskAndReplyWithResult(
+ task_runner_.get(), FROM_HERE,
+ base::BindOnce(UpdateEntriesFromTaskRunner, base::Unretained(db_),
+ std::move(entries_to_save), std::move(keys_to_remove),
+ metrics_id_),
+ std::move(callback));
+}
+
+void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UpdateEntriesWithRemoveFilter(std::move(entries_to_save), delete_key_filter,
+ std::string(), std::move(callback));
+}
+
+void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ base::PostTaskAndReplyWithResult(
+ task_runner_.get(), FROM_HERE,
+ base::BindOnce(UpdateEntriesWithRemoveFilterFromTaskRunner,
+ base::Unretained(db_), std::move(entries_to_save),
+ delete_key_filter, target_prefix, metrics_id_),
+ std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadEntries(Callbacks::LoadCallback callback) {
+ LoadEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ Callbacks::LoadCallback callback) {
+ LoadEntriesWithFilter(key_filter, leveldb::ReadOptions(), std::string(),
+ std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ bool* success = new bool(false);
+ auto entries = std::make_unique<ValueVector>();
+ // Get this pointer before |entries| is std::move()'d so we can use it below.
+ auto* entries_ptr = entries.get();
+
+ task_runner_->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(LoadEntriesFromTaskRunner, base::Unretained(db_),
+ key_filter, options, target_prefix, metrics_id_, success,
+ entries_ptr),
+ base::BindOnce(RunLoadCallback, std::move(callback), base::Owned(success),
+ std::move(entries)));
+}
+
+void ProtoLevelDBWrapper::LoadKeysAndEntries(
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& key_filter,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(key_filter, leveldb::ReadOptions(),
+ std::string(), std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWhile(
+ base::BindRepeating(
+ [](const std::string& prefix, const std::string& key) {
+ return base::StartsWith(key, prefix, base::CompareCase::SENSITIVE);
+ },
+ target_prefix),
+ key_filter, options, target_prefix, std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWhile(
+ base::BindRepeating(
+ [](const std::string& range_end, const std::string& key) {
+ return key.compare(range_end) <= 0;
+ },
+ end),
+ KeyFilter(), leveldb::ReadOptions(), start, std::move(callback));
+}
+
+void ProtoLevelDBWrapper::LoadKeysAndEntriesWhile(
+ const KeyFilter& while_callback,
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ bool* success = new bool(false);
+ auto keys_entries = std::make_unique<KeyValueMap>();
+ // Get this pointer before |keys_entries| is std::move()'d so we can use it
+ // below.
+ auto* keys_entries_ptr = keys_entries.get();
+ task_runner_->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(LoadKeysAndEntriesFromTaskRunner, base::Unretained(db_),
+ while_callback, filter, options, target_prefix,
+ metrics_id_, success, keys_entries_ptr),
+ base::BindOnce(RunLoadKeysAndEntriesCallback, std::move(callback),
+ base::Owned(success), std::move(keys_entries)));
+}
+
+void ProtoLevelDBWrapper::GetEntry(const std::string& key,
+ Callbacks::GetCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ bool* success = new bool(false);
+ bool* found = new bool(false);
+ auto entry = std::make_unique<std::string>();
+ // Get this pointer before |entry| is std::move()'d so we can use it below.
+ auto* entry_ptr = entry.get();
+
+ task_runner_->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(GetEntryFromTaskRunner, base::Unretained(db_), key,
+ metrics_id_, success, found, entry_ptr),
+ base::BindOnce(RunGetCallback, std::move(callback), base::Owned(success),
+ base::Owned(found), std::move(entry)));
+}
+
void ProtoLevelDBWrapper::LoadKeys(
typename Callbacks::LoadKeysCallback callback) {
LoadKeys(std::string(), std::move(callback));
@@ -144,6 +388,17 @@ void ProtoLevelDBWrapper::Destroy(Callbacks::DestroyCallback callback) {
std::move(callback));
}
+void ProtoLevelDBWrapper::Destroy(
+ const base::FilePath& db_dir,
+ const std::string& client_id,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ Callbacks::DestroyCallback callback) {
+ base::PostTaskAndReplyWithResult(
+ task_runner.get(), FROM_HERE,
+ base::BindOnce(DestroyWithDirectoryFromTaskRunner, db_dir, client_id),
+ std::move(callback));
+}
+
void ProtoLevelDBWrapper::SetMetricsId(const std::string& id) {
metrics_id_ = id;
}
diff --git a/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.h b/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.h
index 307c0e60ad5..d2d53b93a52 100644
--- a/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.h
+++ b/chromium/components/leveldb_proto/internal/proto_leveldb_wrapper.h
@@ -4,6 +4,7 @@
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_LEVELDB_WRAPPER_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_LEVELDB_WRAPPER_H_
+#include <map>
#include <memory>
#include <string>
#include <utility>
@@ -17,7 +18,6 @@
#include "base/task_runner_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_checker.h"
-#include "components/leveldb_proto/internal/leveldb_database.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper_metrics.h"
#include "components/leveldb_proto/public/proto_database.h"
#include "third_party/leveldatabase/env_chromium.h"
@@ -28,14 +28,25 @@ class FilePath;
namespace leveldb_proto {
-using KeyValueVector = base::StringPairs;
+class LevelDB;
+
+using KeyValueVector = std::vector<std::pair<std::string, std::string>>;
+using KeyValueMap = std::map<std::string, std::string>;
using KeyVector = std::vector<std::string>;
+using ValueVector = std::vector<std::string>;
// When the ProtoDatabase instance is deleted, in-progress asynchronous
// operations will be completed and the corresponding callbacks will be called.
// Construction/calls/destruction should all happen on the same thread.
class ProtoLevelDBWrapper {
public:
+ // Used to destroy database when initialization fails.
+ static void Destroy(
+ const base::FilePath& db_dir,
+ const std::string& client_id,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+ Callbacks::DestroyCallback callback);
+
// All blocking calls/disk access will happen on the provided |task_runner|.
ProtoLevelDBWrapper(
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
@@ -46,79 +57,59 @@ class ProtoLevelDBWrapper {
virtual ~ProtoLevelDBWrapper();
- template <typename T>
- void UpdateEntries(std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
+ void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
std::unique_ptr<KeyVector> keys_to_remove,
Callbacks::UpdateCallback callback);
- template <typename T>
void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback);
- template <typename T>
void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback);
- template <typename T>
- void LoadEntries(typename Callbacks::Internal<T>::LoadCallback callback);
+ void LoadEntries(Callbacks::LoadCallback callback);
- template <typename T>
- void LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- typename Callbacks::Internal<T>::LoadCallback callback);
+ void LoadEntriesWithFilter(const KeyFilter& key_filter,
+ Callbacks::LoadCallback callback);
- template <typename T>
- void LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback);
+ void LoadEntriesWithFilter(const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadCallback callback);
- template <typename T>
- void LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback);
+ void LoadKeysAndEntries(Callbacks::LoadKeysAndEntriesCallback callback);
- template <typename T>
void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback);
+ Callbacks::LoadKeysAndEntriesCallback callback);
- template <typename T>
void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback);
+ Callbacks::LoadKeysAndEntriesCallback callback);
- template <typename T>
- void LoadKeysAndEntriesWhile(
- const KeyFilter& while_callback,
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback);
+ void LoadKeysAndEntriesWhile(const KeyFilter& while_callback,
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadKeysAndEntriesCallback callback);
- template <typename T>
void LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback);
+ Callbacks::LoadKeysAndEntriesCallback callback);
void LoadKeys(Callbacks::LoadKeysCallback callback);
void LoadKeys(const std::string& target_prefix,
Callbacks::LoadKeysCallback callback);
- template <typename T>
- void GetEntry(const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback);
+ void GetEntry(const std::string& key, Callbacks::GetCallback callback);
void RemoveKeys(const KeyFilter& filter,
const std::string& target_prefix,
@@ -159,307 +150,6 @@ class ProtoLevelDBWrapper {
DISALLOW_COPY_AND_ASSIGN(ProtoLevelDBWrapper);
};
-namespace {
-
-template <typename T>
-void RunLoadCallback(typename Callbacks::Internal<T>::LoadCallback callback,
- bool* success,
- std::unique_ptr<std::vector<T>> entries) {
- std::move(callback).Run(*success, std::move(entries));
-}
-
-template <typename T>
-void RunLoadKeysAndEntriesCallback(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback,
- bool* success,
- std::unique_ptr<std::map<std::string, T>> keys_entries) {
- std::move(callback).Run(*success, std::move(keys_entries));
-}
-
-template <typename T>
-void RunGetCallback(typename Callbacks::Internal<T>::GetCallback callback,
- const bool* success,
- const bool* found,
- std::unique_ptr<T> entry) {
- std::move(callback).Run(*success, *found ? std::move(entry) : nullptr);
-}
-
-template <typename T>
-bool UpdateEntriesFromTaskRunner(
- LevelDB* database,
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- std::unique_ptr<KeyVector> keys_to_remove,
- const std::string& client_id) {
- // Serialize the values from Proto to string before passing on to database.
- KeyValueVector pairs_to_save;
- for (const auto& pair : *entries_to_save) {
- pairs_to_save.push_back(
- std::make_pair(pair.first, pair.second.SerializeAsString()));
- }
-
- leveldb::Status status;
- bool success = database->Save(pairs_to_save, *keys_to_remove, &status);
- ProtoLevelDBWrapperMetrics::RecordUpdate(client_id, success, status);
- return success;
-}
-
-template <typename T>
-bool UpdateEntriesWithRemoveFilterFromTaskRunner(
- LevelDB* database,
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- const std::string& client_id) {
- // Serialize the values from Proto to string before passing on to database.
- KeyValueVector pairs_to_save;
- for (const auto& pair : *entries_to_save) {
- pairs_to_save.push_back(
- std::make_pair(pair.first, pair.second.SerializeAsString()));
- }
-
- leveldb::Status status;
- bool success = database->UpdateWithRemoveFilter(
- pairs_to_save, delete_key_filter, target_prefix, &status);
- ProtoLevelDBWrapperMetrics::RecordUpdate(client_id, success, status);
- return success;
-}
-
-template <typename T>
-void LoadKeysAndEntriesFromTaskRunner(LevelDB* database,
- const KeyFilter& while_callback,
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- const std::string& client_id,
- bool* success,
- std::map<std::string, T>* keys_entries) {
- DCHECK(success);
- DCHECK(keys_entries);
- keys_entries->clear();
-
- std::map<std::string, std::string> loaded_entries;
- *success = database->LoadKeysAndEntriesWhile(filter, &loaded_entries, options,
- target_prefix, while_callback);
-
- for (const auto& pair : loaded_entries) {
- T entry;
- if (!entry.ParseFromString(pair.second)) {
- DLOG(WARNING) << "Unable to parse leveldb_proto entry";
- // TODO(cjhopman): Decide what to do about un-parseable entries.
- }
-
- keys_entries->insert(std::make_pair(pair.first, entry));
- }
-
- ProtoLevelDBWrapperMetrics::RecordLoadKeysAndEntries(client_id, success);
-}
-
-template <typename T>
-void LoadEntriesFromTaskRunner(LevelDB* database,
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- const std::string& client_id,
- bool* success,
- std::vector<T>* entries) {
- std::vector<std::string> loaded_entries;
- *success =
- database->LoadWithFilter(filter, &loaded_entries, options, target_prefix);
-
- for (const auto& serialized_entry : loaded_entries) {
- T entry;
- if (!entry.ParseFromString(serialized_entry)) {
- DLOG(WARNING) << "Unable to parse leveldb_proto entry";
- // TODO(cjhopman): Decide what to do about un-parseable entries.
- }
-
- entries->push_back(entry);
- }
-
- ProtoLevelDBWrapperMetrics::RecordLoadEntries(client_id, success);
-}
-
-template <typename T>
-void GetEntryFromTaskRunner(LevelDB* database,
- const std::string& key,
- const std::string& client_id,
- bool* success,
- bool* found,
- T* entry) {
- std::string serialized_entry;
- leveldb::Status status;
- *success = database->Get(key, found, &serialized_entry, &status);
-
- if (*found && !entry->ParseFromString(serialized_entry)) {
- *found = false;
- DLOG(WARNING) << "Unable to parse leveldb_proto entry";
- }
-
- ProtoLevelDBWrapperMetrics::RecordGet(client_id, *success, *found, status);
-}
-
-} // namespace
-
-template <typename T>
-void ProtoLevelDBWrapper::UpdateEntries(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- std::unique_ptr<KeyVector> keys_to_remove,
- typename Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::PostTaskAndReplyWithResult(
- task_runner_.get(), FROM_HERE,
- base::BindOnce(UpdateEntriesFromTaskRunner<T>, base::Unretained(db_),
- std::move(entries_to_save), std::move(keys_to_remove),
- metrics_id_),
- std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- UpdateEntriesWithRemoveFilter<T>(std::move(entries_to_save),
- delete_key_filter, std::string(),
- std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::PostTaskAndReplyWithResult(
- task_runner_.get(), FROM_HERE,
- base::BindOnce(UpdateEntriesWithRemoveFilterFromTaskRunner<T>,
- base::Unretained(db_), std::move(entries_to_save),
- delete_key_filter, target_prefix, metrics_id_),
- std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) {
- LoadEntriesWithFilter<T>(KeyFilter(), std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- LoadEntriesWithFilter<T>(key_filter, leveldb::ReadOptions(), std::string(),
- std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- bool* success = new bool(false);
- auto entries = std::make_unique<std::vector<T>>();
- // Get this pointer before |entries| is std::move()'d so we can use it below.
- auto* entries_ptr = entries.get();
-
- task_runner_->PostTaskAndReply(
- FROM_HERE,
- base::BindOnce(LoadEntriesFromTaskRunner<T>, base::Unretained(db_),
- key_filter, options, target_prefix, metrics_id_, success,
- entries_ptr),
- base::BindOnce(RunLoadCallback<T>, std::move(callback),
- base::Owned(success), std::move(entries)));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWithFilter<T>(KeyFilter(), std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadKeysAndEntriesWithFilter(
- const KeyFilter& key_filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWithFilter<T>(key_filter, leveldb::ReadOptions(),
- std::string(), std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadKeysAndEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWhile<T>(
- base::BindRepeating(
- [](const std::string& prefix, const std::string& key) {
- return base::StartsWith(key, prefix, base::CompareCase::SENSITIVE);
- },
- target_prefix),
- key_filter, options, target_prefix, std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadKeysAndEntriesInRange(
- const std::string& start,
- const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWhile<T>(
- base::BindRepeating(
- [](const std::string& range_end, const std::string& key) {
- return key.compare(range_end) <= 0;
- },
- end),
- KeyFilter(), leveldb::ReadOptions(), start, std::move(callback));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::LoadKeysAndEntriesWhile(
- const KeyFilter& while_callback,
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- bool* success = new bool(false);
- auto keys_entries = std::make_unique<std::map<std::string, T>>();
- // Get this pointer before |keys_entries| is std::move()'d so we can use it
- // below.
- auto* keys_entries_ptr = keys_entries.get();
- task_runner_->PostTaskAndReply(
- FROM_HERE,
- base::BindOnce(LoadKeysAndEntriesFromTaskRunner<T>, base::Unretained(db_),
- while_callback, filter, options, target_prefix,
- metrics_id_, success, keys_entries_ptr),
- base::BindOnce(RunLoadKeysAndEntriesCallback<T>, std::move(callback),
- base::Owned(success), std::move(keys_entries)));
-}
-
-template <typename T>
-void ProtoLevelDBWrapper::GetEntry(
- const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- bool* success = new bool(false);
- bool* found = new bool(false);
- auto entry = std::make_unique<T>();
- // Get this pointer before |entry| is std::move()'d so we can use it below.
- auto* entry_ptr = entry.get();
-
- task_runner_->PostTaskAndReply(
- FROM_HERE,
- base::BindOnce(GetEntryFromTaskRunner<T>, base::Unretained(db_), key,
- metrics_id_, success, found, entry_ptr),
- base::BindOnce(RunGetCallback<T>, std::move(callback),
- base::Owned(success), base::Owned(found),
- std::move(entry)));
-}
-
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_LEVELDB_WRAPPER_H_
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database.cc b/chromium/components/leveldb_proto/internal/shared_proto_database.cc
index 62211004f4a..6c897a905b0 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database.cc
@@ -4,26 +4,29 @@
#include "components/leveldb_proto/internal/shared_proto_database.h"
-#include "base/sequence_checker.h"
+#include <memory>
+#include <utility>
+
+#include "base/bind_helpers.h"
#include "base/sequenced_task_runner.h"
-#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "components/leveldb_proto/internal/leveldb_database.h"
-#include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
-#include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/public/proto_database_provider.h"
namespace leveldb_proto {
namespace {
-const char kMetadataDatabaseName[] = "metadata";
+const char kMetadataDatabaseName[] = "Metadata";
const base::FilePath::CharType kMetadataDatabasePath[] =
FILE_PATH_LITERAL("metadata");
const int kMaxInitMetaDatabaseAttempts = 3;
const char kGlobalMetadataKey[] = "__global";
+const char kSharedProtoDatabaseUmaName[] = "SharedDb";
+
} // namespace
// static
@@ -57,9 +60,9 @@ SharedProtoDatabase::SharedProtoDatabase(const std::string& client_db_id,
db_dir_(db_dir),
db_(std::make_unique<LevelDB>(client_db_id.c_str())),
db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner_)),
- metadata_db_(std::make_unique<LevelDB>(kMetadataDatabaseName)),
metadata_db_wrapper_(
- std::make_unique<ProtoLevelDBWrapper>(task_runner_)) {
+ ProtoDatabaseProvider::CreateUniqueDB<SharedDBMetadataProto>(
+ task_runner_)) {
DETACH_FROM_SEQUENCE(on_task_runner_);
}
@@ -103,7 +106,7 @@ void SharedProtoDatabase::UpdateClientMetadataAsync(
update_entries->emplace_back(
std::make_pair(std::string(client_db_id), write_proto));
- metadata_db_wrapper_->UpdateEntries<SharedDBMetadataProto>(
+ metadata_db_wrapper_->UpdateEntries(
std::move(update_entries), std::make_unique<std::vector<std::string>>(),
std::move(callback));
}
@@ -116,7 +119,7 @@ void SharedProtoDatabase::GetClientMetadataAsync(
// DB, so making this call directly here without PostTasking is safe. In
// addition, GetEntry uses PostTaskAndReply so the callback will be triggered
// on the calling sequence.
- metadata_db_wrapper_->GetEntry<SharedDBMetadataProto>(
+ metadata_db_wrapper_->GetEntry(
std::string(client_db_id),
base::BindOnce(&SharedProtoDatabase::OnGetClientMetadata, this,
client_db_id, std::move(callback),
@@ -193,24 +196,58 @@ void SharedProtoDatabase::Init(
const std::string& client_db_id,
SharedClientInitCallback callback,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner) {
- // If we succeeded previously, just check for corruption status and run init
- // callback.
- if (init_state_ == InitState::kSuccess) {
- CheckCorruptionAndRunInitCallback(client_db_id, std::move(callback),
- std::move(callback_task_runner),
- Enums::InitStatus::kOK);
- return;
+ switch (init_state_) {
+ case InitState::kNotAttempted:
+ outstanding_init_requests_.emplace(std::make_unique<InitRequest>(
+ std::move(callback), std::move(callback_task_runner), client_db_id));
+
+ init_state_ = InitState::kInProgress;
+ // First, try to initialize the metadata database.
+ InitMetadataDatabase(create_if_missing, 0 /* attempt */,
+ false /* corruption */);
+ break;
+
+ case InitState::kInProgress:
+ outstanding_init_requests_.emplace(std::make_unique<InitRequest>(
+ std::move(callback), std::move(callback_task_runner), client_db_id));
+ break;
+
+ // If we succeeded previously, just check for corruption status and run
+ // init callback.
+ case InitState::kSuccess:
+ CheckCorruptionAndRunInitCallback(client_db_id, std::move(callback),
+ std::move(callback_task_runner),
+ Enums::InitStatus::kOK);
+ break;
+
+ // If we previously failed then we run the callback with kError.
+ case InitState::kFailure:
+ RunInitStatusCallbackOnCallingSequence(
+ std::move(callback), std::move(callback_task_runner),
+ Enums::InitStatus::kError,
+ SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED);
+ break;
+
+ case InitState::kNotFound:
+ if (create_if_missing) {
+ // If the shared DB doesn't exist and we should create it if missing,
+ // then we skip initializing the metadata DB and initialize the shared
+ // DB directly.
+ DCHECK(metadata_);
+ outstanding_init_requests_.emplace(std::make_unique<InitRequest>(
+ std::move(callback), std::move(callback_task_runner),
+ client_db_id));
+ InitDatabase(create_if_missing);
+ } else {
+ // If the shared DB doesn't exist and we shouldn't create it if missing,
+ // then we run the callback with kInvalidOperation (which is not found).
+ RunInitStatusCallbackOnCallingSequence(
+ std::move(callback), std::move(callback_task_runner),
+ Enums::InitStatus::kInvalidOperation,
+ SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED);
+ }
+ break;
}
-
- outstanding_init_requests_.emplace(std::make_unique<InitRequest>(
- std::move(callback), std::move(callback_task_runner), client_db_id));
- if (init_state_ == InitState::kInProgress)
- return;
-
- init_state_ = InitState::kInProgress;
- // First, try to initialize the metadata database.
- InitMetadataDatabase(create_if_missing, 0 /* attempt */,
- false /* corruption */);
}
void SharedProtoDatabase::ProcessInitRequests(Enums::InitStatus status) {
@@ -245,9 +282,9 @@ void SharedProtoDatabase::InitMetadataDatabase(bool create_shared_db_if_missing,
base::FilePath metadata_path =
db_dir_.Append(base::FilePath(kMetadataDatabasePath));
- metadata_db_wrapper_->InitWithDatabase(
- metadata_db_.get(), metadata_path, CreateSimpleOptions(),
- true /* destroy_on_corruption */,
+ // TODO: figure out destroy on corruption param
+ metadata_db_wrapper_->Init(
+ kMetadataDatabaseName, metadata_path, CreateSimpleOptions(),
base::BindOnce(&SharedProtoDatabase::OnMetadataInitComplete, this,
create_shared_db_if_missing, attempt, corruption));
}
@@ -256,17 +293,10 @@ void SharedProtoDatabase::OnMetadataInitComplete(
bool create_shared_db_if_missing,
int attempt,
bool corruption,
- Enums::InitStatus metadata_init_status) {
+ bool success) {
DCHECK_CALLED_ON_VALID_SEQUENCE(on_task_runner_);
- if (metadata_init_status == Enums::InitStatus::kCorrupt) {
- // Retry InitMetaDatabase to create the metadata database from scratch.
- InitMetadataDatabase(create_shared_db_if_missing, ++attempt,
- true /* corruption */);
- return;
- }
-
- if (metadata_init_status != Enums::InitStatus::kOK) {
+ if (!success) {
init_state_ = InitState::kFailure;
init_status_ = Enums::InitStatus::kError;
ProcessInitRequests(init_status_);
@@ -276,7 +306,7 @@ void SharedProtoDatabase::OnMetadataInitComplete(
// Read or initialize the corruption count for this DB. If |corruption| is
// true, we initialize the counter to 1 right away so that all DBs are forced
// to treat the shared database as corrupt, we can't know for sure anymore.
- metadata_db_wrapper_->GetEntry<SharedDBMetadataProto>(
+ metadata_db_wrapper_->GetEntry(
std::string(kGlobalMetadataKey),
base::BindOnce(&SharedProtoDatabase::OnGetGlobalMetadata, this,
create_shared_db_if_missing, corruption));
@@ -326,6 +356,7 @@ void SharedProtoDatabase::InitDatabase(bool create_shared_db_if_missing) {
DCHECK_CALLED_ON_VALID_SEQUENCE(on_task_runner_);
auto options = CreateSimpleOptions();
options.create_if_missing = create_shared_db_if_missing;
+ db_wrapper_->SetMetricsId(kSharedProtoDatabaseUmaName);
// |db_wrapper_| uses the same SequencedTaskRunner that Init is called on,
// so OnDatabaseInit will be called on the same sequence after Init.
// This means any callers to Init using the same TaskRunner can guarantee that
@@ -354,8 +385,21 @@ void SharedProtoDatabase::OnDatabaseInit(Enums::InitStatus status) {
}
init_status_ = status;
- init_state_ = status == Enums::InitStatus::kOK ? InitState::kSuccess
- : InitState::kFailure;
+
+ switch (status) {
+ case Enums::InitStatus::kOK:
+ init_state_ = InitState::kSuccess;
+ break;
+ case Enums::InitStatus::kInvalidOperation:
+ init_state_ = InitState::kNotFound;
+ break;
+ case Enums::InitStatus::kError:
+ case Enums::InitStatus::kNotInitialized:
+ case Enums::InitStatus::kCorrupt:
+ init_state_ = InitState::kFailure;
+ break;
+ }
+
ProcessInitRequests(status);
if (init_state_ == InitState::kSuccess) {
@@ -395,14 +439,77 @@ void SharedProtoDatabase::CommitUpdatedGlobalMetadata(
write_proto.CheckTypeAndMergeFrom(*metadata_);
update_entries->emplace_back(
std::make_pair(std::string(kGlobalMetadataKey), write_proto));
- metadata_db_wrapper_->UpdateEntries<SharedDBMetadataProto>(
+ metadata_db_wrapper_->UpdateEntries(
std::move(update_entries), std::make_unique<std::vector<std::string>>(),
std::move(callback));
}
SharedProtoDatabase::~SharedProtoDatabase() {
task_runner_->DeleteSoon(FROM_HERE, std::move(db_));
- task_runner_->DeleteSoon(FROM_HERE, std::move(metadata_db_));
+ task_runner_->DeleteSoon(FROM_HERE, std::move(metadata_db_wrapper_));
+}
+
+void GetClientInitCallback(
+ base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient>,
+ Enums::InitStatus)> callback,
+ std::unique_ptr<SharedProtoDatabaseClient> client,
+ Enums::InitStatus status,
+ SharedDBMetadataProto::MigrationStatus migration_status) {
+ // |current_task_runner| is valid because Init already takes the current
+ // TaskRunner as a parameter and uses that to trigger this callback when it's
+ // finished.
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
+ if (status != Enums::InitStatus::kOK && status != Enums::InitStatus::kCorrupt)
+ client.reset();
+ // Set migration status of client. The metadata database was already updated.
+ if (client)
+ client->set_migration_status(migration_status);
+ current_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), std::move(client), status));
+}
+
+void SharedProtoDatabase::GetClientAsync(
+ ProtoDbType db_type,
+ bool create_if_missing,
+ base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient>,
+ Enums::InitStatus)> callback) {
+ auto client = GetClientInternal(db_type);
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
+ SharedProtoDatabaseClient* client_ptr = client.get();
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SharedProtoDatabase::Init, this, create_if_missing,
+ client_ptr->client_db_id(),
+ base::BindOnce(&GetClientInitCallback, std::move(callback),
+ std::move(client)),
+ std::move(current_task_runner)));
+}
+
+// TODO(thildebr): Need to pass the client name into this call as well, and use
+// it with the pending requests too so we can clean up the database.
+std::unique_ptr<SharedProtoDatabaseClient>
+SharedProtoDatabase::GetClientForTesting(ProtoDbType db_type,
+ bool create_if_missing,
+ SharedClientInitCallback callback) {
+ DCHECK(base::SequencedTaskRunnerHandle::IsSet());
+ auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
+ auto client = GetClientInternal(db_type);
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SharedProtoDatabase::Init, this, create_if_missing,
+ client->client_db_id(), std::move(callback),
+ std::move(current_task_runner)));
+ return client;
+}
+
+std::unique_ptr<SharedProtoDatabaseClient>
+SharedProtoDatabase::GetClientInternal(ProtoDbType db_type) {
+ return base::WrapUnique(new SharedProtoDatabaseClient(
+ std::make_unique<ProtoLevelDBWrapper>(task_runner_, db_.get()), db_type,
+ this));
}
LevelDB* SharedProtoDatabase::GetLevelDBForTesting() const {
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database.h b/chromium/components/leveldb_proto/internal/shared_proto_database.h
index 98107f97fa0..91190ab587d 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database.h
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database.h
@@ -5,24 +5,20 @@
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_H_
-#include <queue>
+#include <memory>
+#include <string>
+#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/containers/queue.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task/post_task.h"
-#include "base/task_runner_util.h"
-#include "components/leveldb_proto/internal/leveldb_database.h"
#include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h"
-#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/internal/shared_proto_database_client.h"
#include "components/leveldb_proto/public/proto_database.h"
namespace leveldb_proto {
-class SharedDBMetadataProto;
-
// Controls a single LevelDB database to be used by many clients, and provides
// a way to get SharedProtoDatabaseClients that allow shared access to the
// underlying single database.
@@ -35,22 +31,18 @@ class SharedProtoDatabase
// Always returns a SharedProtoDatabaseClient pointer, but that should ONLY
// be used if the callback returns success.
- template <typename T>
- std::unique_ptr<SharedProtoDatabaseClient<T>> GetClientForTesting(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ std::unique_ptr<SharedProtoDatabaseClient> GetClientForTesting(
+ ProtoDbType db_type,
bool create_if_missing,
SharedClientInitCallback callback);
// A version of GetClient that returns the client in a callback instead of
// giving back a client instance immediately.
- template <typename T>
void GetClientAsync(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
bool create_if_missing,
- base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient<T>>)>
- callback);
+ base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient>,
+ Enums::InitStatus)> callback);
void GetDatabaseInitStatusAsync(const std::string& client_db_id,
Callbacks::InitStatusCallback callback);
@@ -64,15 +56,24 @@ class SharedProtoDatabase
friend class base::RefCountedThreadSafe<SharedProtoDatabase>;
friend class ProtoDatabaseProvider;
- friend class ProtoDatabaseWrapperTest;
+ friend class ProtoDatabaseImplTest;
friend class SharedProtoDatabaseTest;
friend class SharedProtoDatabaseClientTest;
+ friend class TestSharedProtoDatabase;
enum InitState {
- kNone,
+ // Initialization hasn't been attempted.
+ kNotAttempted,
+ // Initialization is in progress, new requests will be enqueued.
kInProgress,
+ // Initialization successful, new requests will return existing DB.
kSuccess,
+ // Initialization failed, new requests will return InitStatus::kError.
kFailure,
+ // Shared database doesn't exist, new requests with create_if_missing ==
+ // true will attempt to create it, if create_if_missing == false then will
+ // return InitStatus::kInvalidOperation.
+ kNotFound,
};
struct InitRequest {
@@ -99,10 +100,8 @@ class SharedProtoDatabase
void ProcessInitRequests(Enums::InitStatus status);
- template <typename T>
- std::unique_ptr<SharedProtoDatabaseClient<T>> GetClientInternal(
- const std::string& client_namespace,
- const std::string& type_prefix);
+ std::unique_ptr<SharedProtoDatabaseClient> GetClientInternal(
+ ProtoDbType db_type);
void OnGetClientMetadata(
const std::string& client_db_id,
@@ -113,17 +112,18 @@ class SharedProtoDatabase
// |callback_task_runner| should be the same sequence that Init was called
// from.
- void Init(bool create_if_missing,
- const std::string& client_db_id,
- SharedClientInitCallback callback,
- scoped_refptr<base::SequencedTaskRunner> callback_task_runner);
+ virtual void Init(
+ bool create_if_missing,
+ const std::string& client_db_id,
+ SharedClientInitCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner);
void InitMetadataDatabase(bool create_shared_db_if_missing,
int attempt,
bool corruption);
void OnMetadataInitComplete(bool create_shared_db_if_missing,
int attempt,
bool corruption,
- Enums::InitStatus status);
+ bool success);
void OnGetGlobalMetadata(bool create_shared_db_if_missing,
bool corruption,
bool success,
@@ -158,7 +158,7 @@ class SharedProtoDatabase
SEQUENCE_CHECKER(on_task_runner_);
- InitState init_state_ = InitState::kNone;
+ InitState init_state_ = InitState::kNotAttempted;
// This TaskRunner is used to properly sequence Init calls and checks for the
// current init state. When clients request the current InitState as part of
@@ -169,88 +169,18 @@ class SharedProtoDatabase
std::unique_ptr<LevelDB> db_;
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper_;
- std::unique_ptr<LevelDB> metadata_db_;
- std::unique_ptr<ProtoLevelDBWrapper> metadata_db_wrapper_;
+ std::unique_ptr<ProtoDatabase<SharedDBMetadataProto>> metadata_db_wrapper_;
std::unique_ptr<SharedDBMetadataProto> metadata_;
// Used to return to the Init callback in the case of an error, so we can
// report corruptions.
Enums::InitStatus init_status_ = Enums::InitStatus::kNotInitialized;
- std::queue<std::unique_ptr<InitRequest>> outstanding_init_requests_;
+ base::queue<std::unique_ptr<InitRequest>> outstanding_init_requests_;
DISALLOW_COPY_AND_ASSIGN(SharedProtoDatabase);
};
-template <typename T>
-void GetClientInitCallback(
- base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient<T>>)>
- callback,
- std::unique_ptr<SharedProtoDatabaseClient<T>> client,
- Enums::InitStatus status,
- SharedDBMetadataProto::MigrationStatus migration_status) {
- // |current_task_runner| is valid because Init already takes the current
- // TaskRunner as a parameter and uses that to trigger this callback when it's
- // finished.
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
- if (status != Enums::InitStatus::kOK && status != Enums::InitStatus::kCorrupt)
- client.reset();
- // Set migration status of client. The metadata database was already updated.
- if (client)
- client->set_migration_status(migration_status);
- current_task_runner->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(client)));
-}
-
-template <typename T>
-void SharedProtoDatabase::GetClientAsync(
- const std::string& client_namespace,
- const std::string& type_prefix,
- bool create_if_missing,
- base::OnceCallback<void(std::unique_ptr<SharedProtoDatabaseClient<T>>)>
- callback) {
- auto client = GetClientInternal<T>(client_namespace, type_prefix);
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
- SharedProtoDatabaseClient<T>* client_ptr = client.get();
- task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&SharedProtoDatabase::Init, this, create_if_missing,
- client_ptr->client_db_id(),
- base::BindOnce(&GetClientInitCallback<T>,
- std::move(callback), std::move(client)),
- std::move(current_task_runner)));
-}
-
-// TODO(thildebr): Need to pass the client name into this call as well, and use
-// it with the pending requests too so we can clean up the database.
-template <typename T>
-std::unique_ptr<SharedProtoDatabaseClient<T>>
-SharedProtoDatabase::GetClientForTesting(const std::string& client_namespace,
- const std::string& type_prefix,
- bool create_if_missing,
- SharedClientInitCallback callback) {
- DCHECK(base::SequencedTaskRunnerHandle::IsSet());
- auto current_task_runner = base::SequencedTaskRunnerHandle::Get();
- auto client = GetClientInternal<T>(client_namespace, type_prefix);
- task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&SharedProtoDatabase::Init, this, create_if_missing,
- client->client_db_id(), std::move(callback),
- std::move(current_task_runner)));
- return client;
-}
-
-template <typename T>
-std::unique_ptr<SharedProtoDatabaseClient<T>>
-SharedProtoDatabase::GetClientInternal(const std::string& client_namespace,
- const std::string& type_prefix) {
- return base::WrapUnique(new SharedProtoDatabaseClient<T>(
- std::make_unique<ProtoLevelDBWrapper>(task_runner_, db_.get()),
- client_namespace, type_prefix, this));
-}
-
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_H_
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_client.cc b/chromium/components/leveldb_proto/internal/shared_proto_database_client.cc
index 7b126718408..3038bbc7d84 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_client.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_client.cc
@@ -4,14 +4,18 @@
#include "components/leveldb_proto/internal/shared_proto_database_client.h"
+#include <memory>
+#include <utility>
+
#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/internal/shared_proto_database.h"
#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
namespace leveldb_proto {
namespace {
-const char* const* g_obsolete_client_list_for_testing = nullptr;
+const ProtoDbType* g_obsolete_client_list_for_testing = nullptr;
// Holds the db wrapper alive and callback is called at destruction. This class
// is used to post multiple update tasks on |db_wrapper| and keep the instance
@@ -44,9 +48,8 @@ std::string StripPrefix(const std::string& key, const std::string& prefix) {
: key;
}
-std::unique_ptr<std::vector<std::string>> PrefixStrings(
- std::unique_ptr<std::vector<std::string>> strings,
- const std::string& prefix) {
+std::unique_ptr<KeyVector> PrefixStrings(std::unique_ptr<KeyVector> strings,
+ const std::string& prefix) {
for (auto& str : *strings)
str.assign(base::StrCat({prefix, str}));
return strings;
@@ -83,10 +86,10 @@ void DestroyObsoleteSharedProtoDatabaseClients(
scoped_refptr<ObsoleteClientsDbHolder> db_holder =
new ObsoleteClientsDbHolder(std::move(db_wrapper), std::move(callback));
- const char* const* list = g_obsolete_client_list_for_testing
+ const ProtoDbType* list = g_obsolete_client_list_for_testing
? g_obsolete_client_list_for_testing
- : kObsoleteSharedProtoDatabaseClients;
- for (size_t i = 0; list[i] != nullptr; ++i) {
+ : kObsoleteSharedProtoDbTypeClients;
+ for (size_t i = 0; list[i] != ProtoDbType::LAST; ++i) {
// Callback keeps a ref pointer to db_holder alive till the changes are
// done. |db_holder| will be destroyed once all the RemoveKeys() calls
// return.
@@ -99,12 +102,223 @@ void DestroyObsoleteSharedProtoDatabaseClients(
// the prefix contains the client namespace at the beginning.
db_wrapper_ptr->RemoveKeys(
base::BindRepeating([](const std::string& key) { return true; }),
- list[i], std::move(callback_wrapper));
+ SharedProtoDatabaseClient::PrefixForDatabase(list[i]),
+ std::move(callback_wrapper));
}
}
-void SetObsoleteClientListForTesting(const char* const* list) {
+void SetObsoleteClientListForTesting(const ProtoDbType* list) {
g_obsolete_client_list_for_testing = list;
}
+// static
+std::string SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType db_type) {
+ return base::StringPrintf("%d_", static_cast<int>(db_type));
+}
+
+SharedProtoDatabaseClient::SharedProtoDatabaseClient(
+ std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
+ ProtoDbType db_type,
+ const scoped_refptr<SharedProtoDatabase>& parent_db)
+ : UniqueProtoDatabase(std::move(db_wrapper)),
+ prefix_(PrefixForDatabase(db_type)),
+ parent_db_(parent_db),
+ weak_ptr_factory_(this) {
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+}
+
+SharedProtoDatabaseClient::~SharedProtoDatabaseClient() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void SharedProtoDatabaseClient::Init(const std::string& client_uma_name,
+ Callbacks::InitStatusCallback callback) {
+ SetMetricsId(client_uma_name);
+ GetSharedDatabaseInitStatusAsync(prefix_, parent_db_, std::move(callback));
+}
+
+void SharedProtoDatabaseClient::InitWithDatabase(
+ LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ bool destroy_on_corruption,
+ Callbacks::InitStatusCallback callback) {
+ NOTREACHED();
+}
+
+void SharedProtoDatabaseClient::UpdateEntries(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::UpdateEntries(
+ PrefixKeyEntryVector(std::move(entries_to_save), prefix_),
+ PrefixStrings(std::move(keys_to_remove), prefix_), std::move(callback));
+}
+
+void SharedProtoDatabaseClient::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UpdateEntriesWithRemoveFilter(std::move(entries_to_save), delete_key_filter,
+ std::string(), std::move(callback));
+}
+
+void SharedProtoDatabaseClient::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::UpdateEntriesWithRemoveFilter(
+ PrefixKeyEntryVector(std::move(entries_to_save), prefix_),
+ base::BindRepeating(&KeyFilterStripPrefix, delete_key_filter, prefix_),
+ prefix_ + target_prefix, std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadEntries(Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ LoadEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadEntriesWithFilter(
+ const KeyFilter& filter,
+ Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ LoadEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
+ std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::LoadEntriesWithFilter(
+ base::BindRepeating(&KeyFilterStripPrefix, filter, prefix_), options,
+ prefix_ + target_prefix, std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadKeys(Callbacks::LoadKeysCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ LoadKeys(std::string(), std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadKeys(const std::string& target_prefix,
+ Callbacks::LoadKeysCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::LoadKeys(
+ prefix_ + target_prefix,
+ base::BindOnce(&SharedProtoDatabaseClient::StripPrefixLoadKeysCallback,
+ std::move(callback), prefix_));
+}
+
+void SharedProtoDatabaseClient::LoadKeysAndEntries(
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(KeyFilter(), std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ LoadKeysAndEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
+ std::move(callback));
+}
+
+void SharedProtoDatabaseClient::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::LoadKeysAndEntriesWithFilter(
+ base::BindRepeating(&KeyFilterStripPrefix, filter, prefix_), options,
+ prefix_ + target_prefix,
+ base::BindOnce(
+ &SharedProtoDatabaseClient::StripPrefixLoadKeysAndEntriesCallback,
+ std::move(callback), prefix_));
+}
+
+void SharedProtoDatabaseClient::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ Callbacks::LoadKeysAndEntriesCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::LoadKeysAndEntriesInRange(
+ prefix_ + start, prefix_ + end,
+ base::BindOnce(
+ &SharedProtoDatabaseClient::StripPrefixLoadKeysAndEntriesCallback,
+ std::move(callback), prefix_));
+}
+
+void SharedProtoDatabaseClient::GetEntry(const std::string& key,
+ Callbacks::GetCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UniqueProtoDatabase::GetEntry(prefix_ + key, std::move(callback));
+}
+
+void SharedProtoDatabaseClient::Destroy(Callbacks::DestroyCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ UpdateEntriesWithRemoveFilter(
+ std::make_unique<KeyValueVector>(),
+ base::BindRepeating([](const std::string& key) { return true; }),
+ base::BindOnce([](Callbacks::DestroyCallback callback,
+ bool success) { std::move(callback).Run(success); },
+ std::move(callback)));
+}
+
+void SharedProtoDatabaseClient::UpdateClientInitMetadata(
+ SharedDBMetadataProto::MigrationStatus migration_status) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ migration_status_ = migration_status;
+ // Tell the SharedProtoDatabase that we've seen the corruption state so it's
+ // safe to update its records for this client.
+ UpdateClientMetadataAsync(parent_db_, prefix_, migration_status_,
+ base::BindOnce([](bool success) {
+ // TODO(thildebr): Should we do anything special
+ // here? If the shared DB can't update the
+ // client's corruption counter to match its own,
+ // then the client will think it's corrupt on the
+ // next Init as well.
+ }));
+}
+
+// static
+void SharedProtoDatabaseClient::StripPrefixLoadKeysCallback(
+ Callbacks::LoadKeysCallback callback,
+ const std::string& prefix,
+ bool success,
+ std::unique_ptr<leveldb_proto::KeyVector> keys) {
+ auto stripped_keys = std::make_unique<leveldb_proto::KeyVector>();
+ for (auto& key : *keys)
+ stripped_keys->emplace_back(StripPrefix(key, prefix));
+ std::move(callback).Run(success, std::move(stripped_keys));
+}
+
+// static
+void SharedProtoDatabaseClient::StripPrefixLoadKeysAndEntriesCallback(
+ Callbacks::LoadKeysAndEntriesCallback callback,
+ const std::string& prefix,
+ bool success,
+ std::unique_ptr<KeyValueMap> keys_entries) {
+ auto stripped_keys_map = std::make_unique<KeyValueMap>();
+ for (auto& key_entry : *keys_entries) {
+ stripped_keys_map->insert(
+ std::make_pair(StripPrefix(key_entry.first, prefix), key_entry.second));
+ }
+ std::move(callback).Run(success, std::move(stripped_keys_map));
+}
+
+// static
+std::unique_ptr<KeyValueVector> SharedProtoDatabaseClient::PrefixKeyEntryVector(
+ std::unique_ptr<KeyValueVector> kev,
+ const std::string& prefix) {
+ for (auto& key_entry_pair : *kev) {
+ key_entry_pair.first = base::StrCat({prefix, key_entry_pair.first});
+ }
+ return kev;
+}
+
} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_client.h b/chromium/components/leveldb_proto/internal/shared_proto_database_client.h
index e94e4f44eed..46dce07a57f 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_client.h
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_client.h
@@ -5,35 +5,34 @@
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_CLIENT_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_CLIENT_H_
+#include <memory>
+#include <string>
+
+#include "base/bind.h"
#include "base/sequence_checker.h"
-#include "base/sequenced_task_runner.h"
-#include "base/strings/strcat.h"
-#include "base/strings/string_util.h"
-#include "base/threading/sequenced_task_runner_handle.h"
#include "components/leveldb_proto/internal/leveldb_database.h"
#include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h"
-#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/internal/unique_proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
namespace leveldb_proto {
class SharedProtoDatabase;
+// TODO: Move all these as static or member functions in the class.
using ClientCorruptCallback = base::OnceCallback<void(bool)>;
using SharedClientInitCallback =
base::OnceCallback<void(Enums::InitStatus,
SharedDBMetadataProto::MigrationStatus)>;
std::string StripPrefix(const std::string& key, const std::string& prefix);
-std::unique_ptr<std::vector<std::string>> PrefixStrings(
- std::unique_ptr<std::vector<std::string>> strings,
- const std::string& prefix);
+
+std::unique_ptr<KeyVector> PrefixStrings(std::unique_ptr<KeyVector> strings,
+ const std::string& prefix);
+
bool KeyFilterStripPrefix(const KeyFilter& key_filter,
const std::string& prefix,
const std::string& key);
-std::unique_ptr<std::vector<std::string>> PrefixStrings(
- std::unique_ptr<std::vector<std::string>> strings,
- const std::string& prefix);
void GetSharedDatabaseInitStatusAsync(
const std::string& client_db_id,
@@ -54,84 +53,76 @@ void DestroyObsoleteSharedProtoDatabaseClients(
Callbacks::UpdateCallback callback);
// Sets list of client names that are obsolete and will be cleared by next call
-// to DestroyObsoleteSharedProtoDatabaseClients(). |list| is list of c strings
-// with a nullptr to mark the end of list.
-void SetObsoleteClientListForTesting(const char* const* list);
+// to DestroyObsoleteSharedProtoDatabaseClients(). |list| is list of dbs
+// with a |LAST| to mark the end of list.
+void SetObsoleteClientListForTesting(const ProtoDbType* list);
// An implementation of ProtoDatabase<T> that uses a shared LevelDB and task
// runner.
// Should be created, destroyed, and used on the same sequenced task runner.
-template <typename T>
-class SharedProtoDatabaseClient : public ProtoDatabase<T> {
+class SharedProtoDatabaseClient : public UniqueProtoDatabase {
public:
- virtual ~SharedProtoDatabaseClient();
+ static std::string PrefixForDatabase(ProtoDbType db_type);
+
+ ~SharedProtoDatabaseClient() override;
void Init(const std::string& client_uma_name,
Callbacks::InitStatusCallback callback) override;
- void Init(const char* client_uma_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitCallback callback) override;
+ void InitWithDatabase(LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ bool destroy_on_corruption,
+ Callbacks::InitStatusCallback callback) override;
// Overrides for prepending namespace and type prefix to all operations on the
// shared database.
- void UpdateEntries(std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
+ void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
Callbacks::UpdateCallback callback) override;
void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback) override;
void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
- entries_to_save,
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback) override;
- void LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) override;
- void LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
- void LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
+ void LoadEntries(Callbacks::LoadCallback callback) override;
+ void LoadEntriesWithFilter(const KeyFilter& filter,
+ Callbacks::LoadCallback callback) override;
+ void LoadEntriesWithFilter(const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ Callbacks::LoadCallback callback) override;
void LoadKeys(Callbacks::LoadKeysCallback callback) override;
void LoadKeys(const std::string& target_prefix,
Callbacks::LoadKeysCallback callback) override;
void LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ Callbacks::LoadKeysAndEntriesCallback callback) override;
void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ Callbacks::LoadKeysAndEntriesCallback callback) override;
void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ Callbacks::LoadKeysAndEntriesCallback callback) override;
void LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ Callbacks::LoadKeysAndEntriesCallback callback) override;
void GetEntry(const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) override;
+ Callbacks::GetCallback callback) override;
void Destroy(Callbacks::DestroyCallback callback) override;
- typename Callbacks::InitCallback GetInitCallback() const;
+ Callbacks::InitCallback GetInitCallback() const;
const std::string& client_db_id() const { return prefix_; }
@@ -140,7 +131,7 @@ class SharedProtoDatabaseClient : public ProtoDatabase<T> {
migration_status_ = migration_status;
}
- void UpdateClientInitMetadata(SharedDBMetadataProto::MigrationStatus);
+ virtual void UpdateClientInitMetadata(SharedDBMetadataProto::MigrationStatus);
SharedDBMetadataProto::MigrationStatus migration_status() const {
return migration_status_;
@@ -150,12 +141,12 @@ class SharedProtoDatabaseClient : public ProtoDatabase<T> {
friend class SharedProtoDatabase;
friend class SharedProtoDatabaseTest;
friend class SharedProtoDatabaseClientTest;
+ friend class TestSharedProtoDatabaseClient;
// Hide this so clients can only be created by the SharedProtoDatabase.
SharedProtoDatabaseClient(
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
const scoped_refptr<SharedProtoDatabase>& parent_db);
static void StripPrefixLoadKeysCallback(
@@ -164,14 +155,13 @@ class SharedProtoDatabaseClient : public ProtoDatabase<T> {
bool success,
std::unique_ptr<leveldb_proto::KeyVector> keys);
static void StripPrefixLoadKeysAndEntriesCallback(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback,
+ Callbacks::LoadKeysAndEntriesCallback callback,
const std::string& prefix,
bool success,
- std::unique_ptr<std::map<std::string, T>> keys_entries);
+ std::unique_ptr<KeyValueMap> keys_entries);
- static std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- PrefixKeyEntryVector(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> kev,
+ static std::unique_ptr<KeyValueVector> PrefixKeyEntryVector(
+ std::unique_ptr<KeyValueVector> kev,
const std::string& prefix);
SEQUENCE_CHECKER(sequence_checker_);
@@ -183,251 +173,15 @@ class SharedProtoDatabaseClient : public ProtoDatabase<T> {
SharedDBMetadataProto::MigrationStatus migration_status_ =
SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED;
- std::string prefix_;
- std::string client_name_;
+ const std::string prefix_;
scoped_refptr<SharedProtoDatabase> parent_db_;
- std::unique_ptr<UniqueProtoDatabase<T>> unique_db_;
- base::WeakPtrFactory<SharedProtoDatabaseClient<T>> weak_ptr_factory_;
+ base::WeakPtrFactory<SharedProtoDatabaseClient> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(SharedProtoDatabaseClient);
};
-template <typename T>
-SharedProtoDatabaseClient<T>::SharedProtoDatabaseClient(
- std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
- const std::string& client_namespace,
- const std::string& type_prefix,
- const scoped_refptr<SharedProtoDatabase>& parent_db)
- : prefix_(base::JoinString({client_namespace, type_prefix, std::string()},
- "_")),
- parent_db_(parent_db),
- unique_db_(
- std::make_unique<UniqueProtoDatabase<T>>(std::move(db_wrapper))),
- weak_ptr_factory_(this) {
- DETACH_FROM_SEQUENCE(sequence_checker_);
-}
-
-template <typename T>
-SharedProtoDatabaseClient<T>::~SharedProtoDatabaseClient() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::Init(
- const std::string& client_uma_name,
- Callbacks::InitStatusCallback callback) {
- unique_db_->SetMetricsId(client_uma_name);
- GetSharedDatabaseInitStatusAsync(prefix_, parent_db_, std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::Init(const char* client_uma_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitCallback callback) {
- NOTREACHED();
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::UpdateEntries(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
- Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->UpdateEntries(
- PrefixKeyEntryVector(std::move(entries_to_save), prefix_),
- PrefixStrings(std::move(keys_to_remove), prefix_), std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- UpdateEntriesWithRemoveFilter(std::move(entries_to_save), delete_key_filter,
- std::string(), std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->UpdateEntriesWithRemoveFilter(
- PrefixKeyEntryVector(std::move(entries_to_save), prefix_),
- base::BindRepeating(&KeyFilterStripPrefix, delete_key_filter, prefix_),
- prefix_ + target_prefix, std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- LoadEntriesWithFilter(KeyFilter(), std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- LoadEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
- std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadEntriesWithFilter(
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->LoadEntriesWithFilter(
- base::BindRepeating(&KeyFilterStripPrefix, filter, prefix_), options,
- prefix_ + target_prefix, std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeys(
- Callbacks::LoadKeysCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- LoadKeys(std::string(), std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeys(
- const std::string& target_prefix,
- Callbacks::LoadKeysCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->LoadKeys(
- prefix_ + target_prefix,
- base::BindOnce(&SharedProtoDatabaseClient<T>::StripPrefixLoadKeysCallback,
- std::move(callback), prefix_));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWithFilter(KeyFilter(), std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- LoadKeysAndEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
- std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->LoadKeysAndEntriesWithFilter(
- filter, options, prefix_ + target_prefix,
- base::BindOnce(
- &SharedProtoDatabaseClient<T>::StripPrefixLoadKeysAndEntriesCallback,
- std::move(callback), prefix_));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::LoadKeysAndEntriesInRange(
- const std::string& start,
- const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->LoadKeysAndEntriesInRange(
- prefix_ + start, prefix_ + end,
- base::BindOnce(
- &SharedProtoDatabaseClient<T>::StripPrefixLoadKeysAndEntriesCallback,
- std::move(callback), prefix_));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::GetEntry(
- const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- unique_db_->GetEntry(prefix_ + key, std::move(callback));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::Destroy(
- Callbacks::DestroyCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- UpdateEntriesWithRemoveFilter(
- std::make_unique<typename Util::Internal<T>::KeyEntryVector>(),
- base::BindRepeating([](const std::string& key) { return true; }),
- base::BindOnce([](Callbacks::DestroyCallback callback,
- bool success) { std::move(callback).Run(success); },
- std::move(callback)));
-}
-
-template <typename T>
-void SharedProtoDatabaseClient<T>::UpdateClientInitMetadata(
- SharedDBMetadataProto::MigrationStatus migration_status) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- migration_status_ = migration_status;
- // Tell the SharedProtoDatabase that we've seen the corruption state so it's
- // safe to update its records for this client.
- UpdateClientMetadataAsync(parent_db_, prefix_, migration_status_,
- base::BindOnce([](bool success) {
- // TODO(thildebr): Should we do anything special
- // here? If the shared DB can't update the
- // client's corruption counter to match its own,
- // then the client will think it's corrupt on the
- // next Init as well.
- }));
-}
-
-// static
-template <typename T>
-void SharedProtoDatabaseClient<T>::StripPrefixLoadKeysCallback(
- Callbacks::LoadKeysCallback callback,
- const std::string& prefix,
- bool success,
- std::unique_ptr<leveldb_proto::KeyVector> keys) {
- auto stripped_keys = std::make_unique<leveldb_proto::KeyVector>();
- for (auto& key : *keys)
- stripped_keys->emplace_back(StripPrefix(key, prefix));
- std::move(callback).Run(success, std::move(stripped_keys));
-}
-
-// static
-template <typename T>
-void SharedProtoDatabaseClient<T>::StripPrefixLoadKeysAndEntriesCallback(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback,
- const std::string& prefix,
- bool success,
- std::unique_ptr<std::map<std::string, T>> keys_entries) {
- auto stripped_keys_map = std::make_unique<std::map<std::string, T>>();
- for (auto& key_entry : *keys_entries) {
- stripped_keys_map->insert(
- std::make_pair(StripPrefix(key_entry.first, prefix), key_entry.second));
- }
- std::move(callback).Run(success, std::move(stripped_keys_map));
-}
-
-// static
-template <typename T>
-std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
-SharedProtoDatabaseClient<T>::PrefixKeyEntryVector(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> kev,
- const std::string& prefix) {
- for (auto& key_entry_pair : *kev) {
- key_entry_pair.first = base::StrCat({prefix, key_entry_pair.first});
- }
- return kev;
-}
-
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_CLIENT_H_
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc b/chromium/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
index 9583cd7fd88..86e5662c079 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_client_list_unittest.cc
@@ -13,16 +13,16 @@
namespace leveldb_proto {
namespace {
-const char kTestClientName[] = "TestClientName";
+const char kTestClientName[] = "TEST_DATABASE1";
}
class SharedProtoDatabaseClientListTest : public testing::Test {
public:
void SetUpExperimentParam(std::string key, std::string value) {
std::map<std::string, std::string> params = {
- {"migrate_ClientNameFoo", "true"},
+ {"migrate_TEST_DATABASE0", "true"},
{"migrate_" + key, value},
- {"migrate_ClientNameBar", "false"},
+ {"migrate_TEST_DATABASE2", "false"},
};
scoped_feature_list_.InitAndEnableFeatureWithParameters(
@@ -37,18 +37,18 @@ TEST_F(SharedProtoDatabaseClientListTest, ShouldUseSharedDBTest) {
// Parameter value is case sensitive
SetUpExperimentParam(kTestClientName, "true");
- bool use_shared =
- SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+ bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+ ProtoDbType::TEST_DATABASE1);
ASSERT_TRUE(use_shared);
}
TEST_F(SharedProtoDatabaseClientListTest,
ShouldUseSharedDBTest_OnlyWhenParamMatchesName) {
- SetUpExperimentParam("AnotherClientName", "true");
+ SetUpExperimentParam("TEST_DATABASE10", "true");
- bool use_shared =
- SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+ bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+ ProtoDbType::TEST_DATABASE1);
ASSERT_FALSE(use_shared);
}
@@ -57,8 +57,8 @@ TEST_F(SharedProtoDatabaseClientListTest,
ShouldUseSharedDBTest_OnlyWhenParamValueIsTrue) {
SetUpExperimentParam(kTestClientName, "false");
- bool use_shared =
- SharedProtoDatabaseClientList::ShouldUseSharedDB(kTestClientName);
+ bool use_shared = SharedProtoDatabaseClientList::ShouldUseSharedDB(
+ ProtoDbType::TEST_DATABASE1);
ASSERT_FALSE(use_shared);
}
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc b/chromium/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
index 34ccf263d04..e64ba45db0f 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_client_unittest.cc
@@ -4,29 +4,23 @@
#include "components/leveldb_proto/internal/shared_proto_database_client.h"
+#include <set>
+#include <string>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/internal/shared_proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
#include "components/leveldb_proto/testing/proto/test_db.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace leveldb_proto {
-namespace {
-
-const char* kDefaultNamespace = "abc";
-const char* kDefaultNamespace1 = "cde";
-const char* kDefaultNamespace2 = "cfd";
-const char* kDefaultTypePrefix = "tp";
-
-} // namespace
-
class SharedProtoDatabaseClientTest : public testing::Test {
public:
void SetUp() override {
@@ -47,16 +41,14 @@ class SharedProtoDatabaseClientTest : public testing::Test {
LevelDB* GetLevelDB() const { return db_->GetLevelDBForTesting(); }
- template <typename T>
- std::unique_ptr<SharedProtoDatabaseClient<T>> GetClient(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ std::unique_ptr<SharedProtoDatabaseClient> GetClient(
+ ProtoDbType db_type,
bool create_if_missing,
Callbacks::InitStatusCallback callback,
SharedDBMetadataProto::MigrationStatus expected_migration_status =
SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED) {
- return db_->GetClientForTesting<T>(
- client_namespace, type_prefix, create_if_missing,
+ return db_->GetClientForTesting(
+ db_type, create_if_missing,
base::BindOnce(
[](SharedDBMetadataProto::MigrationStatus expected_migration_status,
Callbacks::InitStatusCallback callback, Enums::InitStatus status,
@@ -67,39 +59,36 @@ class SharedProtoDatabaseClientTest : public testing::Test {
expected_migration_status, std::move(callback)));
}
- template <typename T>
- std::unique_ptr<SharedProtoDatabaseClient<T>> GetClientAndWait(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ std::unique_ptr<SharedProtoDatabaseClient> GetClientAndWait(
+ ProtoDbType db_type,
bool create_if_missing,
Enums::InitStatus* status,
SharedDBMetadataProto::MigrationStatus expected_migration_status =
SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED) {
base::RunLoop loop;
- auto client = GetClient<T>(
- client_namespace, type_prefix, create_if_missing,
- base::BindOnce(
- [](Enums::InitStatus* status_out, base::OnceClosure closure,
- Enums::InitStatus status) {
- *status_out = status;
- std::move(closure).Run();
- },
- status, loop.QuitClosure()),
- expected_migration_status);
+ auto client =
+ GetClient(db_type, create_if_missing,
+ base::BindOnce(
+ [](Enums::InitStatus* status_out,
+ base::OnceClosure closure, Enums::InitStatus status) {
+ *status_out = status;
+ std::move(closure).Run();
+ },
+ status, loop.QuitClosure()),
+ expected_migration_status);
loop.Run();
return client;
}
bool ContainsKeys(const leveldb_proto::KeyVector& db_keys,
const leveldb_proto::KeyVector& keys,
- const std::string& client_namespace,
- const std::string& prefix) {
+ ProtoDbType db_type) {
std::set<std::string> key_set(db_keys.begin(), db_keys.end());
for (auto& key : keys) {
auto full_key =
- client_namespace.empty() || prefix.empty()
+ db_type == ProtoDbType::LAST
? key
- : base::JoinString({client_namespace, prefix, key}, "_");
+ : SharedProtoDatabaseClient::PrefixForDatabase(db_type) + key;
if (key_set.find(full_key) == key_set.end())
return false;
}
@@ -107,16 +96,14 @@ class SharedProtoDatabaseClientTest : public testing::Test {
}
bool ContainsEntries(const leveldb_proto::KeyVector& db_keys,
- const std::vector<TestProto>& entries,
- const std::string& client_namespace,
- const std::string& type_prefix) {
+ const ValueVector& entries,
+ ProtoDbType db_type) {
std::set<std::string> entry_id_set;
for (auto& entry : entries)
- entry_id_set.insert(entry.id());
+ entry_id_set.insert(entry);
// Entry IDs don't include the full prefix, so we don't look for that here.
- auto prefix =
- base::JoinString({client_namespace, type_prefix, std::string()}, "_");
+ auto prefix = SharedProtoDatabaseClient::PrefixForDatabase(db_type);
for (auto& key : db_keys) {
if (entry_id_set.find(prefix + key) == entry_id_set.end())
return false;
@@ -124,15 +111,16 @@ class SharedProtoDatabaseClientTest : public testing::Test {
return true;
}
- void UpdateEntries(SharedProtoDatabaseClient<TestProto>* client,
+ void UpdateEntries(SharedProtoDatabaseClient* client,
const leveldb_proto::KeyVector& keys,
const leveldb_proto::KeyVector& keys_to_remove,
bool expect_success) {
- auto entries = std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>();
+ auto entries =
+ std::make_unique<ProtoDatabase<std::string>::KeyEntryVector>();
for (auto& key : keys) {
- TestProto proto;
- proto.set_id(client->prefix_ + key);
- entries->emplace_back(std::make_pair(key, std::move(proto)));
+ std::string value;
+ value = client->prefix_ + key;
+ entries->emplace_back(std::make_pair(key, std::move(value)));
}
auto entries_to_remove = std::make_unique<leveldb_proto::KeyVector>();
@@ -151,16 +139,16 @@ class SharedProtoDatabaseClientTest : public testing::Test {
update_entries_loop.Run();
}
- void UpdateEntriesWithRemoveFilter(
- SharedProtoDatabaseClient<TestProto>* client,
- const leveldb_proto::KeyVector& keys,
- const KeyFilter& delete_key_filter,
- bool expect_success) {
- auto entries = std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>();
+ void UpdateEntriesWithRemoveFilter(SharedProtoDatabaseClient* client,
+ const leveldb_proto::KeyVector& keys,
+ const KeyFilter& delete_key_filter,
+ bool expect_success) {
+ auto entries =
+ std::make_unique<ProtoDatabase<std::string>::KeyEntryVector>();
for (auto& key : keys) {
- TestProto proto;
- proto.set_id(client->prefix_ + key);
- entries->emplace_back(std::make_pair(key, std::move(proto)));
+ std::string value;
+ value = client->prefix_ + key;
+ entries->emplace_back(std::make_pair(key, std::move(value)));
}
base::RunLoop update_entries_loop;
@@ -177,19 +165,19 @@ class SharedProtoDatabaseClientTest : public testing::Test {
// This fills in for all the LoadEntriesX functions because they all call this
// one.
- void LoadEntriesWithFilter(SharedProtoDatabaseClient<TestProto>* client,
+ void LoadEntriesWithFilter(SharedProtoDatabaseClient* client,
const KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
bool expect_success,
- std::unique_ptr<std::vector<TestProto>>* entries) {
+ std::unique_ptr<ValueVector>* entries) {
base::RunLoop load_entries_loop;
client->LoadEntriesWithFilter(
key_filter, options, target_prefix,
base::BindOnce(
- [](std::unique_ptr<std::vector<TestProto>>* entries_ptr,
+ [](std::unique_ptr<ValueVector>* entries_ptr,
base::OnceClosure signal, bool expect_success, bool success,
- std::unique_ptr<std::vector<TestProto>> entries) {
+ std::unique_ptr<ValueVector> entries) {
ASSERT_EQ(success, expect_success);
entries_ptr->reset(entries.release());
std::move(signal).Run();
@@ -198,19 +186,18 @@ class SharedProtoDatabaseClientTest : public testing::Test {
load_entries_loop.Run();
}
- void LoadKeysAndEntriesInRange(
- SharedProtoDatabaseClient<TestProto>* client,
- const std::string& start,
- const std::string& end,
- bool expect_success,
- std::unique_ptr<std::map<std::string, TestProto>>* entries) {
+ void LoadKeysAndEntriesInRange(SharedProtoDatabaseClient* client,
+ const std::string& start,
+ const std::string& end,
+ bool expect_success,
+ std::unique_ptr<KeyValueMap>* entries) {
base::RunLoop load_entries_in_range_loop;
client->LoadKeysAndEntriesInRange(
start, end,
base::BindOnce(
- [](std::unique_ptr<std::map<std::string, TestProto>>* entries_ptr,
+ [](std::unique_ptr<KeyValueMap>* entries_ptr,
base::OnceClosure signal, bool expect_success, bool success,
- std::unique_ptr<std::map<std::string, TestProto>> entries) {
+ std::unique_ptr<KeyValueMap> entries) {
ASSERT_EQ(success, expect_success);
*entries_ptr = std::move(entries);
std::move(signal).Run();
@@ -219,14 +206,13 @@ class SharedProtoDatabaseClientTest : public testing::Test {
load_entries_in_range_loop.Run();
}
- void LoadKeys(SharedProtoDatabaseClient<TestProto>* client,
+ void LoadKeys(SharedProtoDatabaseClient* client,
bool expect_success,
- std::unique_ptr<std::vector<std::string>>* keys) {
+ std::unique_ptr<KeyVector>* keys) {
base::RunLoop load_keys_loop;
client->LoadKeys(base::BindOnce(
- [](std::unique_ptr<std::vector<std::string>>* keys_ptr,
- base::OnceClosure signal, bool expect_success, bool success,
- std::unique_ptr<std::vector<std::string>> keys) {
+ [](std::unique_ptr<KeyVector>* keys_ptr, base::OnceClosure signal,
+ bool expect_success, bool success, std::unique_ptr<KeyVector> keys) {
ASSERT_EQ(success, expect_success);
keys_ptr->reset(keys.release());
std::move(signal).Run();
@@ -235,17 +221,16 @@ class SharedProtoDatabaseClientTest : public testing::Test {
load_keys_loop.Run();
}
- std::unique_ptr<TestProto> GetEntry(
- SharedProtoDatabaseClient<TestProto>* client,
- const std::string& key,
- bool expect_success) {
- std::unique_ptr<TestProto> entry;
+ std::unique_ptr<std::string> GetEntry(SharedProtoDatabaseClient* client,
+ const std::string& key,
+ bool expect_success) {
+ std::unique_ptr<std::string> entry;
base::RunLoop get_key_loop;
client->GetEntry(
key, base::BindOnce(
- [](std::unique_ptr<TestProto>* entry_ptr,
+ [](std::unique_ptr<std::string>* entry_ptr,
base::OnceClosure signal, bool expect_success, bool success,
- std::unique_ptr<TestProto> entry) {
+ std::unique_ptr<std::string> entry) {
ASSERT_EQ(success, expect_success);
entry_ptr->reset(entry.release());
std::move(signal).Run();
@@ -255,8 +240,7 @@ class SharedProtoDatabaseClientTest : public testing::Test {
return entry;
}
- void Destroy(SharedProtoDatabaseClient<TestProto>* client,
- bool expect_success) {
+ void Destroy(SharedProtoDatabaseClient* client, bool expect_success) {
base::RunLoop destroy_loop;
client->Destroy(base::BindOnce(
[](bool expect_success, base::OnceClosure signal, bool success) {
@@ -269,7 +253,7 @@ class SharedProtoDatabaseClientTest : public testing::Test {
// Sets the obsolete client list to given list, runs clean up tasks and waits
// for them to complete.
- void DestroyObsoleteClientsAndWait(const char* const* client_list) {
+ void DestroyObsoleteClientsAndWait(const ProtoDbType* client_list) {
SetObsoleteClientListForTesting(client_list);
base::RunLoop wait_loop;
Callbacks::UpdateCallback wait_callback = base::BindOnce(
@@ -288,7 +272,7 @@ class SharedProtoDatabaseClientTest : public testing::Test {
}
void UpdateMetadataAsync(
- SharedProtoDatabaseClient<TestProto>* client,
+ SharedProtoDatabaseClient* client,
SharedDBMetadataProto::MigrationStatus migration_status) {
base::RunLoop wait_loop;
Callbacks::UpdateCallback wait_callback = base::BindOnce(
@@ -312,9 +296,8 @@ class SharedProtoDatabaseClientTest : public testing::Test {
TEST_F(SharedProtoDatabaseClientTest, InitSuccess) {
auto status = Enums::InitStatus::kError;
- auto client =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
client->Init("client", base::BindOnce([](Enums::InitStatus status) {
@@ -324,9 +307,8 @@ TEST_F(SharedProtoDatabaseClientTest, InitSuccess) {
TEST_F(SharedProtoDatabaseClientTest, InitFail) {
auto status = Enums::InitStatus::kError;
- auto client =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- false /* create_if_missing */, &status);
+ auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ false /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kInvalidOperation);
client->Init("client", base::BindOnce([](Enums::InitStatus status) {
@@ -338,21 +320,19 @@ TEST_F(SharedProtoDatabaseClientTest, InitFail) {
// removes prefixed entries correctly.
TEST_F(SharedProtoDatabaseClientTest, UpdateEntriesAppropriatePrefix) {
auto status = Enums::InitStatus::kError;
- auto client =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list = {"entry1", "entry2", "entry3"};
+ KeyVector key_list = {"entry1", "entry2", "entry3"};
UpdateEntries(client.get(), key_list, leveldb_proto::KeyVector(), true);
// Make sure those entries are in the LevelDB with the appropriate prefix.
- std::vector<std::string> keys;
+ KeyVector keys;
LevelDB* db = GetLevelDB();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 3U);
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
auto remove_keys = {key_list[0]};
// Now try to delete one entry.
@@ -361,56 +341,50 @@ TEST_F(SharedProtoDatabaseClientTest, UpdateEntriesAppropriatePrefix) {
keys.clear();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 2U);
- ASSERT_TRUE(ContainsKeys(keys, {key_list[1], key_list[2]}, kDefaultNamespace,
- kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, {key_list[1], key_list[2]},
+ ProtoDbType::TEST_DATABASE0));
}
TEST_F(SharedProtoDatabaseClientTest,
UpdateEntries_DeletesCorrectClientEntries) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list = {"entry1", "entry2", "entry3"};
+ KeyVector key_list = {"entry1", "entry2", "entry3"};
UpdateEntries(client_a.get(), key_list, leveldb_proto::KeyVector(), true);
UpdateEntries(client_b.get(), key_list, leveldb_proto::KeyVector(), true);
- std::vector<std::string> keys;
+ KeyVector keys;
LevelDB* db = GetLevelDB();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 6U);
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
// Now delete from client_b and ensure only client A's values exist.
UpdateEntries(client_b.get(), leveldb_proto::KeyVector(), key_list, true);
keys.clear();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 3U);
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
}
TEST_F(SharedProtoDatabaseClientTest,
UpdateEntriesWithRemoveFilter_DeletesCorrectEntries) {
auto status = Enums::InitStatus::kError;
- auto client =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list = {"entry1", "entry2", "testentry3"};
+ KeyVector key_list = {"entry1", "entry2", "testentry3"};
UpdateEntries(client.get(), key_list, leveldb_proto::KeyVector(), true);
- std::vector<std::string> keys;
+ KeyVector keys;
LevelDB* db = GetLevelDB();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 3U);
@@ -427,39 +401,36 @@ TEST_F(SharedProtoDatabaseClientTest,
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), 2U);
// Make sure "testentry3" was removed.
- ASSERT_TRUE(ContainsKeys(keys, {"entry1", "entry2"}, kDefaultNamespace,
- kDefaultTypePrefix));
+ ASSERT_TRUE(
+ ContainsKeys(keys, {"entry1", "entry2"}, ProtoDbType::TEST_DATABASE0));
}
TEST_F(SharedProtoDatabaseClientTest, LoadEntriesWithFilter) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list_a = {"entry123", "entry2123", "testentry3"};
+ KeyVector key_list_a = {"entry123", "entry2123", "testentry3"};
UpdateEntries(client_a.get(), key_list_a, leveldb_proto::KeyVector(), true);
- std::vector<std::string> key_list_b = {"testentry124", "entry2124",
- "testentry4"};
+ KeyVector key_list_b = {"testentry124", "entry2124", "testentry4"};
UpdateEntries(client_b.get(), key_list_b, leveldb_proto::KeyVector(), true);
- std::unique_ptr<std::vector<TestProto>> entries;
- LoadEntriesWithFilter(client_a.get(), KeyFilter(), leveldb::ReadOptions(),
- std::string(), true, &entries);
+ std::unique_ptr<ValueVector> entries;
+ LoadEntriesWithFilter(client_a.get(), leveldb_proto::KeyFilter(),
+ leveldb::ReadOptions(), std::string(), true, &entries);
ASSERT_EQ(entries->size(), 3U);
- ASSERT_TRUE(ContainsEntries(key_list_a, *entries, kDefaultNamespace,
- kDefaultTypePrefix));
+ ASSERT_TRUE(
+ ContainsEntries(key_list_a, *entries, ProtoDbType::TEST_DATABASE0));
- LoadEntriesWithFilter(client_b.get(), KeyFilter(), leveldb::ReadOptions(),
- std::string(), true, &entries);
+ LoadEntriesWithFilter(client_b.get(), leveldb_proto::KeyFilter(),
+ leveldb::ReadOptions(), std::string(), true, &entries);
ASSERT_EQ(entries->size(), 3U);
- ASSERT_TRUE(ContainsEntries(key_list_b, *entries, kDefaultNamespace2,
- kDefaultTypePrefix));
+ ASSERT_TRUE(
+ ContainsEntries(key_list_b, *entries, ProtoDbType::TEST_DATABASE2));
// Now test the actual filtering functionality.
LoadEntriesWithFilter(
@@ -470,37 +441,34 @@ TEST_F(SharedProtoDatabaseClientTest, LoadEntriesWithFilter) {
}),
leveldb::ReadOptions(), std::string(), true, &entries);
ASSERT_EQ(entries->size(), 1U);
- ASSERT_TRUE(ContainsEntries({"entry2124"}, *entries, kDefaultNamespace2,
- kDefaultTypePrefix));
+ ASSERT_TRUE(
+ ContainsEntries({"entry2124"}, *entries, ProtoDbType::TEST_DATABASE2));
}
TEST_F(SharedProtoDatabaseClientTest, LoadKeysAndEntriesInRange) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list_a = {"entry0", "entry1", "entry2",
- "entry3", "entry3notinrange", "entry4",
- "entry5"};
+ KeyVector key_list_a = {"entry0", "entry1", "entry2", "entry3",
+ "entry3notinrange", "entry4", "entry5"};
UpdateEntries(client_a.get(), key_list_a, leveldb_proto::KeyVector(), true);
- std::vector<std::string> key_list_b = {"entry2", "entry3", "entry4"};
+ KeyVector key_list_b = {"entry2", "entry3", "entry4"};
UpdateEntries(client_b.get(), key_list_b, leveldb_proto::KeyVector(), true);
- std::unique_ptr<std::map<std::string, TestProto>> keys_and_entries_a;
+ std::unique_ptr<KeyValueMap> keys_and_entries_a;
LoadKeysAndEntriesInRange(client_a.get(), "entry1", "entry3", true,
&keys_and_entries_a);
- std::unique_ptr<std::map<std::string, TestProto>> keys_and_entries_b;
+ std::unique_ptr<KeyValueMap> keys_and_entries_b;
LoadKeysAndEntriesInRange(client_b.get(), "entry0", "entry1", true,
&keys_and_entries_b);
- std::vector<TestProto> entries;
+ ValueVector entries;
for (auto& pair : *keys_and_entries_a) {
entries.push_back(pair.second);
@@ -509,82 +477,73 @@ TEST_F(SharedProtoDatabaseClientTest, LoadKeysAndEntriesInRange) {
ASSERT_EQ(keys_and_entries_a->size(), 3U);
ASSERT_EQ(keys_and_entries_b->size(), 0U);
ASSERT_TRUE(ContainsEntries({"entry1", "entry2", "entry3"}, entries,
- kDefaultNamespace, kDefaultTypePrefix));
+ ProtoDbType::TEST_DATABASE0));
}
TEST_F(SharedProtoDatabaseClientTest, LoadKeys) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list_a = {"entry123", "entry2123", "testentry3",
- "testing"};
+ KeyVector key_list_a = {"entry123", "entry2123", "testentry3", "testing"};
UpdateEntries(client_a.get(), key_list_a, leveldb_proto::KeyVector(), true);
- std::vector<std::string> key_list_b = {"testentry124", "entry2124",
- "testentry4"};
+ KeyVector key_list_b = {"testentry124", "entry2124", "testentry4"};
UpdateEntries(client_b.get(), key_list_b, leveldb_proto::KeyVector(), true);
- std::unique_ptr<std::vector<std::string>> keys;
+ std::unique_ptr<KeyVector> keys;
LoadKeys(client_a.get(), true, &keys);
ASSERT_EQ(keys->size(), 4U);
- ASSERT_TRUE(ContainsKeys(*keys, key_list_a, std::string(), std::string()));
+ ASSERT_TRUE(ContainsKeys(*keys, key_list_a, ProtoDbType::LAST));
LoadKeys(client_b.get(), true, &keys);
ASSERT_EQ(keys->size(), 3U);
- ASSERT_TRUE(ContainsKeys(*keys, key_list_b, std::string(), std::string()));
+ ASSERT_TRUE(ContainsKeys(*keys, key_list_b, ProtoDbType::LAST));
}
TEST_F(SharedProtoDatabaseClientTest, GetEntry) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list = {"a", "b", "c"};
+ KeyVector key_list = {"a", "b", "c"};
// Add the same entries to both because we want to make sure we only get the
// entries from the proper client.
UpdateEntries(client_a.get(), key_list, leveldb_proto::KeyVector(), true);
UpdateEntries(client_b.get(), key_list, leveldb_proto::KeyVector(), true);
- auto a_prefix = base::JoinString(
- {kDefaultNamespace, kDefaultTypePrefix, std::string()}, "_");
- auto b_prefix = base::JoinString(
- {kDefaultNamespace2, kDefaultTypePrefix, std::string()}, "_");
+ auto a_prefix =
+ SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType::TEST_DATABASE0);
+ auto b_prefix =
+ SharedProtoDatabaseClient::PrefixForDatabase(ProtoDbType::TEST_DATABASE2);
for (auto& key : key_list) {
auto entry = GetEntry(client_a.get(), key, true);
- ASSERT_EQ(entry->id(), a_prefix + key);
+ ASSERT_EQ(*entry, a_prefix + key);
entry = GetEntry(client_b.get(), key, true);
- ASSERT_EQ(entry->id(), b_prefix + key);
+ ASSERT_EQ(*entry, b_prefix + key);
}
}
TEST_F(SharedProtoDatabaseClientTest, TestCleanupObsoleteClients) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace1, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE1,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_c =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_c = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> test_keys = {"a", "b", "c"};
+ KeyVector test_keys = {"a", "b", "c"};
UpdateEntries(client_a.get(), test_keys, leveldb_proto::KeyVector(), true);
UpdateEntries(client_b.get(), test_keys, leveldb_proto::KeyVector(), true);
UpdateEntries(client_c.get(), test_keys, leveldb_proto::KeyVector(), true);
@@ -592,30 +551,29 @@ TEST_F(SharedProtoDatabaseClientTest, TestCleanupObsoleteClients) {
// Check that the original list does not clear any data from test DBs.
DestroyObsoleteClientsAndWait(nullptr /* client_list */);
- std::vector<std::string> keys;
+ KeyVector keys;
LevelDB* db = GetLevelDB();
db->LoadKeys(&keys);
EXPECT_EQ(keys.size(), test_keys.size() * 3);
// Mark some DBs obsolete.
- const char* const kObsoleteList1[] = {kDefaultNamespace, kDefaultNamespace1,
- nullptr};
+ const ProtoDbType kObsoleteList1[] = {ProtoDbType::TEST_DATABASE0,
+ ProtoDbType::TEST_DATABASE1,
+ ProtoDbType::LAST};
DestroyObsoleteClientsAndWait(kObsoleteList1);
keys.clear();
db->LoadKeys(&keys);
EXPECT_EQ(keys.size(), test_keys.size());
- EXPECT_FALSE(
- ContainsKeys(keys, test_keys, kDefaultNamespace, kDefaultTypePrefix));
- EXPECT_FALSE(
- ContainsKeys(keys, test_keys, kDefaultNamespace1, kDefaultTypePrefix));
- EXPECT_TRUE(
- ContainsKeys(keys, test_keys, kDefaultNamespace2, kDefaultTypePrefix));
+ EXPECT_FALSE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE0));
+ EXPECT_FALSE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE1));
+ EXPECT_TRUE(ContainsKeys(keys, test_keys, ProtoDbType::TEST_DATABASE2));
// Make all the DBs obsolete.
- const char* const kObsoleteList2[] = {kDefaultNamespace, kDefaultNamespace1,
- kDefaultNamespace2, nullptr};
+ const ProtoDbType kObsoleteList2[] = {
+ ProtoDbType::TEST_DATABASE0, ProtoDbType::TEST_DATABASE1,
+ ProtoDbType::TEST_DATABASE2, ProtoDbType::LAST};
DestroyObsoleteClientsAndWait(kObsoleteList2);
// Nothing should remain.
@@ -626,38 +584,33 @@ TEST_F(SharedProtoDatabaseClientTest, TestCleanupObsoleteClients) {
TEST_F(SharedProtoDatabaseClientTest, TestDestroy) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- std::vector<std::string> key_list = {"a", "b", "c"};
+ KeyVector key_list = {"a", "b", "c"};
// Add the same entries to both because we want to make sure we only destroy
// the entries from the proper client.
UpdateEntries(client_a.get(), key_list, leveldb_proto::KeyVector(), true);
UpdateEntries(client_b.get(), key_list, leveldb_proto::KeyVector(), true);
// Delete only client A.
- std::vector<std::string> keys;
+ KeyVector keys;
LevelDB* db = GetLevelDB();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), key_list.size() * 2);
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace, kDefaultTypePrefix));
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE0));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
Destroy(client_a.get(), true);
// Make sure only client B remains and delete client B.
keys.clear();
db->LoadKeys(&keys);
ASSERT_EQ(keys.size(), key_list.size());
- ASSERT_TRUE(
- ContainsKeys(keys, key_list, kDefaultNamespace2, kDefaultTypePrefix));
+ ASSERT_TRUE(ContainsKeys(keys, key_list, ProtoDbType::TEST_DATABASE2));
Destroy(client_b.get(), true);
// Nothing should remain.
@@ -668,23 +621,20 @@ TEST_F(SharedProtoDatabaseClientTest, TestDestroy) {
TEST_F(SharedProtoDatabaseClientTest, UpdateClientMetadataAsync) {
auto status = Enums::InitStatus::kError;
- auto client_a =
- GetClientAndWait<TestProto>(kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_a = GetClientAndWait(ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
EXPECT_EQ(status, Enums::InitStatus::kOK);
EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
client_a->migration_status());
- auto client_b =
- GetClientAndWait<TestProto>(kDefaultNamespace1, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_b = GetClientAndWait(ProtoDbType::TEST_DATABASE1,
+ true /* create_if_missing */, &status);
EXPECT_EQ(status, Enums::InitStatus::kOK);
EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
client_b->migration_status());
- auto client_c =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_c = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
EXPECT_EQ(status, Enums::InitStatus::kOK);
EXPECT_EQ(SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED,
client_c->migration_status());
@@ -699,19 +649,18 @@ TEST_F(SharedProtoDatabaseClientTest, UpdateClientMetadataAsync) {
client_b.reset();
client_c.reset();
- auto client_d = GetClientAndWait<TestProto>(
- kDefaultNamespace, kDefaultTypePrefix, true /* create_if_missing */,
- &status, SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
+ auto client_d = GetClientAndWait(
+ ProtoDbType::TEST_DATABASE0, true /* create_if_missing */, &status,
+ SharedDBMetadataProto::MIGRATE_TO_SHARED_SUCCESSFUL);
EXPECT_EQ(status, Enums::InitStatus::kOK);
- auto client_e = GetClientAndWait<TestProto>(
- kDefaultNamespace1, kDefaultTypePrefix, true /* create_if_missing */,
- &status, SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
+ auto client_e = GetClientAndWait(
+ ProtoDbType::TEST_DATABASE1, true /* create_if_missing */, &status,
+ SharedDBMetadataProto::MIGRATE_TO_UNIQUE_SHARED_TO_BE_DELETED);
EXPECT_EQ(status, Enums::InitStatus::kOK);
- auto client_f =
- GetClientAndWait<TestProto>(kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ auto client_f = GetClientAndWait(ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
EXPECT_EQ(status, Enums::InitStatus::kOK);
UpdateMetadataAsync(client_d.get(),
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_provider.cc b/chromium/components/leveldb_proto/internal/shared_proto_database_provider.cc
index 2f45ac4efb4..746a5aff92b 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_provider.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_provider.cc
@@ -4,6 +4,7 @@
#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
@@ -27,4 +28,4 @@ void SharedProtoDatabaseProvider::GetDBInstance(
std::move(callback_task_runner)));
}
-} // namespace leveldb_proto \ No newline at end of file
+} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/shared_proto_database_unittest.cc b/chromium/components/leveldb_proto/internal/shared_proto_database_unittest.cc
index d2d2a2335cd..e2a596498b5 100644
--- a/chromium/components/leveldb_proto/internal/shared_proto_database_unittest.cc
+++ b/chromium/components/leveldb_proto/internal/shared_proto_database_unittest.cc
@@ -18,16 +18,11 @@ namespace leveldb_proto {
namespace {
-const std::string kDefaultNamespace = "ns";
-const std::string kDefaultNamespace2 = "ns2";
-const std::string kDefaultTypePrefix = "tp";
-
inline void GetClientFromTaskRunner(SharedProtoDatabase* db,
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
base::OnceClosure closure) {
- db->GetClientForTesting<TestProto>(
- client_namespace, type_prefix, true /* create_if_missing */,
+ db->GetClientForTesting(
+ db_type, true /* create_if_missing */,
base::BindOnce(
[](base::OnceClosure closure, Enums::InitStatus status,
SharedDBMetadataProto::MigrationStatus migration_status) {
@@ -67,16 +62,14 @@ class SharedProtoDatabaseTest : public testing::Test {
return db->init_state_ == SharedProtoDatabase::InitState::kSuccess;
}
- template <typename T>
- std::unique_ptr<SharedProtoDatabaseClient<T>> GetClientAndWait(
+ std::unique_ptr<SharedProtoDatabaseClient> GetClientAndWait(
SharedProtoDatabase* db,
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
bool create_if_missing,
Enums::InitStatus* status) {
base::RunLoop loop;
- auto client = db->GetClientForTesting<T>(
- client_namespace, type_prefix, create_if_missing,
+ auto client = db->GetClientForTesting(
+ db_type, create_if_missing,
base::BindOnce(
[](Enums::InitStatus* status_out, base::OnceClosure closure,
Enums::InitStatus status,
@@ -107,8 +100,8 @@ class SharedProtoDatabaseTest : public testing::Test {
TEST_F(SharedProtoDatabaseTest, CreateClient_SucceedsWithCreate) {
auto status = Enums::InitStatus::kError;
- GetClientAndWait<TestProto>(db(), kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
}
@@ -119,35 +112,35 @@ TEST_F(SharedProtoDatabaseTest, DISABLED_CreateClient_FailsWithoutCreate) {
TEST_F(SharedProtoDatabaseTest, CreateClient_FailsWithoutCreate) {
#endif
auto status = Enums::InitStatus::kError;
- GetClientAndWait<TestProto>(db(), kDefaultNamespace, kDefaultTypePrefix,
- false /* create_if_missing */, &status);
+ GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
+ false /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kInvalidOperation);
}
TEST_F(SharedProtoDatabaseTest,
CreateClient_SucceedsWithoutCreateIfAlreadyCreated) {
auto status = Enums::InitStatus::kError;
- GetClientAndWait<TestProto>(db(), kDefaultNamespace2, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ GetClientAndWait(db(), ProtoDbType::TEST_DATABASE2,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
- GetClientAndWait<TestProto>(db(), kDefaultNamespace, kDefaultTypePrefix,
- false /* create_if_missing */, &status);
+ GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
+ false /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
}
TEST_F(SharedProtoDatabaseTest, GetClient_DifferentThreads) {
auto status = Enums::InitStatus::kError;
- GetClientAndWait<TestProto>(db(), kDefaultNamespace, kDefaultTypePrefix,
- true /* create_if_missing */, &status);
+ GetClientAndWait(db(), ProtoDbType::TEST_DATABASE0,
+ true /* create_if_missing */, &status);
ASSERT_EQ(status, Enums::InitStatus::kOK);
base::Thread t("test_thread");
ASSERT_TRUE(t.Start());
base::RunLoop run_loop;
t.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&GetClientFromTaskRunner,
- base::Unretained(db()), kDefaultNamespace2,
- kDefaultTypePrefix, run_loop.QuitClosure()));
+ FROM_HERE,
+ base::BindOnce(&GetClientFromTaskRunner, base::Unretained(db()),
+ ProtoDbType::TEST_DATABASE2, run_loop.QuitClosure()));
run_loop.Run();
base::RunLoop quit_cooldown;
GetMainThreadTaskRunner()->PostDelayedTask(
@@ -158,7 +151,7 @@ TEST_F(SharedProtoDatabaseTest, GetClient_DifferentThreads) {
// backing LevelDB has been initialized on another thread.
TEST_F(SharedProtoDatabaseTest, TestDBDestructionAfterInit) {
base::RunLoop run_init_loop;
- InitDB(true /* create_if_missing */, kDefaultNamespace,
+ InitDB(true /* create_if_missing */, "TestDatabaseUMA",
base::BindOnce(
[](base::OnceClosure signal, Enums::InitStatus status,
SharedDBMetadataProto::MigrationStatus migration_status) {
diff --git a/chromium/components/leveldb_proto/internal/unique_proto_database.cc b/chromium/components/leveldb_proto/internal/unique_proto_database.cc
new file mode 100644
index 00000000000..753f94cc9b1
--- /dev/null
+++ b/chromium/components/leveldb_proto/internal/unique_proto_database.cc
@@ -0,0 +1,167 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/leveldb_proto/internal/unique_proto_database.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/sequenced_task_runner.h"
+#include "components/leveldb_proto/internal/leveldb_database.h"
+#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
+
+namespace leveldb_proto {
+
+UniqueProtoDatabase::UniqueProtoDatabase(
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner)
+ : db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner)) {}
+
+UniqueProtoDatabase::UniqueProtoDatabase(
+ std::unique_ptr<ProtoLevelDBWrapper> db_wrapper)
+ : db_wrapper_(std::move(db_wrapper)) {}
+
+UniqueProtoDatabase::UniqueProtoDatabase(
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner)
+ : UniqueProtoDatabase(task_runner) {
+ database_dir_ = database_dir;
+ options_ = options;
+}
+
+UniqueProtoDatabase::~UniqueProtoDatabase() {
+ if (db_.get() &&
+ !db_wrapper_->task_runner()->DeleteSoon(FROM_HERE, db_.release())) {
+ DLOG(WARNING) << "Proto database will not be deleted.";
+ }
+}
+
+void UniqueProtoDatabase::Init(const std::string& client_name,
+ Callbacks::InitStatusCallback callback) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ db_ = std::make_unique<LevelDB>(client_name.c_str());
+ db_wrapper_->SetMetricsId(client_name);
+ InitWithDatabase(db_.get(), database_dir_, options_, true,
+ std::move(callback));
+}
+
+void UniqueProtoDatabase::InitWithDatabase(
+ LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ bool destroy_on_corruption,
+ Callbacks::InitStatusCallback callback) {
+ // We set |destroy_on_corruption| to true to preserve the original behaviour
+ // where database corruption led to automatic destruction.
+ db_wrapper_->InitWithDatabase(database, database_dir, options,
+ destroy_on_corruption, std::move(callback));
+}
+
+void UniqueProtoDatabase::UpdateEntries(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback) {
+ db_wrapper_->UpdateEntries(std::move(entries_to_save),
+ std::move(keys_to_remove), std::move(callback));
+}
+
+void UniqueProtoDatabase::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ Callbacks::UpdateCallback callback) {
+ db_wrapper_->UpdateEntriesWithRemoveFilter(
+ std::move(entries_to_save), delete_key_filter, std::move(callback));
+}
+
+void UniqueProtoDatabase::UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
+ const KeyFilter& delete_key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ db_wrapper_->UpdateEntriesWithRemoveFilter(std::move(entries_to_save),
+ delete_key_filter, target_prefix,
+ std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadEntries(
+ typename Callbacks::LoadCallback callback) {
+ db_wrapper_->LoadEntries(std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::LoadCallback callback) {
+ db_wrapper_->LoadEntriesWithFilter(filter, std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadEntriesWithFilter(
+ const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadCallback callback) {
+ db_wrapper_->LoadEntriesWithFilter(key_filter, options, target_prefix,
+ std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeysAndEntries(
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ db_wrapper_->LoadKeysAndEntries(std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ db_wrapper_->LoadKeysAndEntriesWithFilter(filter, std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeysAndEntriesWithFilter(
+ const KeyFilter& filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ db_wrapper_->LoadKeysAndEntriesWithFilter(filter, options, target_prefix,
+ std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::LoadKeysAndEntriesCallback callback) {
+ db_wrapper_->LoadKeysAndEntriesInRange(start, end, std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeys(Callbacks::LoadKeysCallback callback) {
+ db_wrapper_->LoadKeys(std::move(callback));
+}
+
+void UniqueProtoDatabase::LoadKeys(const std::string& target_prefix,
+ Callbacks::LoadKeysCallback callback) {
+ db_wrapper_->LoadKeys(target_prefix, std::move(callback));
+}
+
+void UniqueProtoDatabase::GetEntry(const std::string& key,
+ typename Callbacks::GetCallback callback) {
+ db_wrapper_->GetEntry(key, std::move(callback));
+}
+
+void UniqueProtoDatabase::Destroy(Callbacks::DestroyCallback callback) {
+ db_wrapper_->Destroy(std::move(callback));
+}
+
+void UniqueProtoDatabase::RemoveKeysForTesting(
+ const KeyFilter& key_filter,
+ const std::string& target_prefix,
+ Callbacks::UpdateCallback callback) {
+ db_wrapper_->RemoveKeys(key_filter, target_prefix, std::move(callback));
+}
+
+bool UniqueProtoDatabase::GetApproximateMemoryUse(uint64_t* approx_mem_use) {
+ return db_wrapper_->GetApproximateMemoryUse(approx_mem_use);
+}
+
+void UniqueProtoDatabase::SetMetricsId(const std::string& id) {
+ db_wrapper_->SetMetricsId(id);
+}
+
+} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/internal/unique_proto_database.h b/chromium/components/leveldb_proto/internal/unique_proto_database.h
index 23fdb47748c..8b113361ffd 100644
--- a/chromium/components/leveldb_proto/internal/unique_proto_database.h
+++ b/chromium/components/leveldb_proto/internal/unique_proto_database.h
@@ -5,18 +5,19 @@
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_UNIQUE_PROTO_DATABASE_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_UNIQUE_PROTO_DATABASE_H_
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread_checker.h"
-#include "components/leveldb_proto/internal/leveldb_database.h"
+#include <memory>
+#include <string>
+
+#include "base/bind.h"
+#include "base/sequence_checker.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/public/proto_database.h"
namespace leveldb_proto {
-// An implementation of ProtoDatabase<T> that manages the lifecycle of a unique
-// LevelDB instance.
-template <typename T>
-class UniqueProtoDatabase : public ProtoDatabase<T> {
+// An implementation of ProtoDatabase<std::string> that manages the lifecycle of
+// a unique LevelDB instance.
+class UniqueProtoDatabase {
public:
explicit UniqueProtoDatabase(
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
@@ -28,78 +29,62 @@ class UniqueProtoDatabase : public ProtoDatabase<T> {
const leveldb_env::Options& options,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
- // This version of Init is for compatibility, since many of the current
- // proto database still use this.
- void Init(const char* client_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- typename Callbacks::InitCallback callback) override;
-
- void Init(const std::string& client_name,
- Callbacks::InitStatusCallback callback) override;
+ virtual void Init(const std::string& client_name,
+ Callbacks::InitStatusCallback callback);
- void InitWithDatabase(LevelDB* database,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitStatusCallback callback);
+ virtual void InitWithDatabase(LevelDB* database,
+ const base::FilePath& database_dir,
+ const leveldb_env::Options& options,
+ bool destroy_on_corruption,
+ Callbacks::InitStatusCallback callback);
- void UpdateEntries(std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
- Callbacks::UpdateCallback callback) override;
+ virtual void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
+ std::unique_ptr<KeyVector> keys_to_remove,
+ Callbacks::UpdateCallback callback);
- void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
+ virtual void UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) override;
- void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
+ Callbacks::UpdateCallback callback);
+ virtual void UpdateEntriesWithRemoveFilter(
+ std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
const std::string& target_prefix,
- Callbacks::UpdateCallback callback) override;
+ Callbacks::UpdateCallback callback);
- void LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) override;
+ virtual void LoadEntries(typename Callbacks::LoadCallback callback);
- void LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
- void LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) override;
+ virtual void LoadEntriesWithFilter(const KeyFilter& filter,
+ typename Callbacks::LoadCallback callback);
+ virtual void LoadEntriesWithFilter(const KeyFilter& key_filter,
+ const leveldb::ReadOptions& options,
+ const std::string& target_prefix,
+ typename Callbacks::LoadCallback callback);
- void LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ virtual void LoadKeysAndEntries(
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
- void LoadKeysAndEntriesWithFilter(
+ virtual void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
- void LoadKeysAndEntriesWithFilter(
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
+ virtual void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
- void LoadKeysAndEntriesInRange(
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
+ virtual void LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
- override;
+ typename Callbacks::LoadKeysAndEntriesCallback callback);
- void LoadKeys(Callbacks::LoadKeysCallback callback) override;
- void LoadKeys(const std::string& target_prefix,
- Callbacks::LoadKeysCallback callback) override;
+ virtual void LoadKeys(Callbacks::LoadKeysCallback callback);
+ virtual void LoadKeys(const std::string& target_prefix,
+ Callbacks::LoadKeysCallback callback);
- void GetEntry(const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) override;
+ virtual void GetEntry(const std::string& key,
+ typename Callbacks::GetCallback callback);
- void Destroy(Callbacks::DestroyCallback callback) override;
+ virtual void Destroy(Callbacks::DestroyCallback callback);
void RemoveKeysForTesting(const KeyFilter& key_filter,
const std::string& target_prefix,
@@ -113,210 +98,15 @@ class UniqueProtoDatabase : public ProtoDatabase<T> {
protected:
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper_;
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
private:
- THREAD_CHECKER(thread_checker_);
+ SEQUENCE_CHECKER(sequence_checker_);
base::FilePath database_dir_;
leveldb_env::Options options_;
std::unique_ptr<LevelDB> db_;
};
-template <typename T>
-UniqueProtoDatabase<T>::UniqueProtoDatabase(
- const scoped_refptr<base::SequencedTaskRunner>& task_runner)
- : db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner)) {}
-
-template <typename T>
-UniqueProtoDatabase<T>::UniqueProtoDatabase(
- std::unique_ptr<ProtoLevelDBWrapper> db_wrapper)
- : db_wrapper_(std::move(db_wrapper)) {}
-
-template <typename T>
-UniqueProtoDatabase<T>::UniqueProtoDatabase(
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- const scoped_refptr<base::SequencedTaskRunner>& task_runner)
- : UniqueProtoDatabase<T>(task_runner) {
- database_dir_ = database_dir;
- options_ = options;
-}
-
-template <typename T>
-UniqueProtoDatabase<T>::~UniqueProtoDatabase() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (db_.get() &&
- !db_wrapper_->task_runner()->DeleteSoon(FROM_HERE, db_.release())) {
- DLOG(WARNING) << "Proto database will not be deleted.";
- }
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::Init(const std::string& client_name,
- Callbacks::InitStatusCallback callback) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- db_ = std::make_unique<LevelDB>(client_name.c_str());
- db_wrapper_->SetMetricsId(client_name);
- InitWithDatabase(db_.get(), database_dir_, options_, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::Init(const char* client_name,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitCallback callback) {
- database_dir_ = database_dir;
- options_ = options;
- db_wrapper_->SetMetricsId(client_name);
- Init(std::string(client_name),
- base::BindOnce(
- [](Callbacks::InitCallback callback, Enums::InitStatus status) {
- std::move(callback).Run(status == Enums::InitStatus::kOK);
- },
- std::move(callback)));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::InitWithDatabase(
- LevelDB* database,
- const base::FilePath& database_dir,
- const leveldb_env::Options& options,
- Callbacks::InitStatusCallback callback) {
- // We set |destroy_on_corruption| to true to preserve the original behaviour
- // where database corruption led to automatic destruction.
- db_wrapper_->InitWithDatabase(database, database_dir, options,
- true /* destroy_on_corruption */,
- std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::UpdateEntries(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- std::unique_ptr<std::vector<std::string>> keys_to_remove,
- Callbacks::UpdateCallback callback) {
- db_wrapper_->template UpdateEntries<T>(std::move(entries_to_save),
- std::move(keys_to_remove),
- std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- Callbacks::UpdateCallback callback) {
- db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
- std::move(entries_to_save), delete_key_filter, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
- const KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) {
- db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
- std::move(entries_to_save), delete_key_filter, target_prefix,
- std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadEntries(
- typename Callbacks::Internal<T>::LoadCallback callback) {
- db_wrapper_->template LoadEntries<T>(std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- db_wrapper_->template LoadEntriesWithFilter<T>(filter, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
- const KeyFilter& key_filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadCallback callback) {
- db_wrapper_->template LoadEntriesWithFilter<T>(
- key_filter, options, target_prefix, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeysAndEntries(
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- db_wrapper_->template LoadKeysAndEntries<T>(std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(filter,
- std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
- const KeyFilter& filter,
- const leveldb::ReadOptions& options,
- const std::string& target_prefix,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(
- filter, options, target_prefix, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeysAndEntriesInRange(
- const std::string& start,
- const std::string& end,
- typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
- db_wrapper_->template LoadKeysAndEntriesInRange<T>(start, end,
- std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
- db_wrapper_->LoadKeys(std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::LoadKeys(const std::string& target_prefix,
- Callbacks::LoadKeysCallback callback) {
- db_wrapper_->LoadKeys(target_prefix, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::GetEntry(
- const std::string& key,
- typename Callbacks::Internal<T>::GetCallback callback) {
- db_wrapper_->template GetEntry<T>(key, std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::Destroy(Callbacks::DestroyCallback callback) {
- db_wrapper_->Destroy(std::move(callback));
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::RemoveKeysForTesting(
- const KeyFilter& key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) {
- db_wrapper_->RemoveKeys(key_filter, target_prefix, std::move(callback));
-}
-
-template <typename T>
-bool UniqueProtoDatabase<T>::GetApproximateMemoryUse(uint64_t* approx_mem_use) {
- return db_wrapper_->GetApproximateMemoryUse(approx_mem_use);
-}
-
-template <typename T>
-void UniqueProtoDatabase<T>::SetMetricsId(const std::string& id) {
- db_wrapper_->SetMetricsId(id);
-}
-
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_UNIQUE_PROTO_DATABASE_H_
diff --git a/chromium/components/leveldb_proto/internal/unique_proto_database_unittest.cc b/chromium/components/leveldb_proto/internal/unique_proto_database_unittest.cc
index e9c3c2021a9..71dcb9c7b16 100644
--- a/chromium/components/leveldb_proto/internal/unique_proto_database_unittest.cc
+++ b/chromium/components/leveldb_proto/internal/unique_proto_database_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/leveldb_proto/internal/unique_proto_database.h"
+#include "components/leveldb_proto/public/proto_database.h"
#include <stddef.h>
@@ -21,7 +21,8 @@
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/leveldb_proto/internal/leveldb_database.h"
-#include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/internal/proto_database_impl.h"
+#include "components/leveldb_proto/public/proto_database_provider.h"
#include "components/leveldb_proto/testing/proto/test_db.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -220,8 +221,8 @@ class UniqueProtoDatabaseTest : public testing::Test {
UniqueProtoDatabaseTest()
: options_(MakeMatcher(new OptionsEqMatcher(CreateSimpleOptions()))) {}
void SetUp() override {
- db_.reset(new UniqueProtoDatabase<TestProto>(
- base::ThreadTaskRunnerHandle::Get()));
+ db_ = std::make_unique<ProtoDatabaseImpl<TestProto>>(
+ base::ThreadTaskRunnerHandle::Get());
}
void TearDown() override {
@@ -231,7 +232,7 @@ class UniqueProtoDatabaseTest : public testing::Test {
const Matcher<const Options&> options_;
ScopedTaskEnvironment task_environment_;
- std::unique_ptr<UniqueProtoDatabase<TestProto>> db_;
+ std::unique_ptr<ProtoDatabaseImpl<TestProto>> db_;
};
// Test that UniqueProtoDatabase calls Init on the underlying database and that
@@ -426,6 +427,7 @@ TEST_F(UniqueProtoDatabaseTest, TestDBLoadInRangeSuccess) {
db_->UpdateEntries(std::move(save_entries), std::move(remove_keys),
base::BindOnce(&MockDatabaseCaller::SaveCallback,
base::Unretained(&caller)));
+ base::RunLoop().RunUntilIdle();
EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _))
.WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected)));
@@ -467,6 +469,7 @@ TEST_F(UniqueProtoDatabaseTest, TestDBLoadInRangeSuccessSameKey) {
db_->UpdateEntries(std::move(save_entries), std::move(remove_keys),
base::BindOnce(&MockDatabaseCaller::SaveCallback,
base::Unretained(&caller)));
+ base::RunLoop().RunUntilIdle();
EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _))
.WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected)));
@@ -545,7 +548,9 @@ TEST_F(UniqueProtoDatabaseTest, TestDBRemoveKeys) {
std::move(signal).Run();
},
run_update_entries.QuitClosure());
- db_->RemoveKeysForTesting(
+ ProtoDatabaseImpl<TestProto>* wrapper =
+ reinterpret_cast<ProtoDatabaseImpl<TestProto>*>(db_.get());
+ wrapper->RemoveKeysForTesting(
base::BindRepeating([](const std::string& str) { return true; }),
kTestPrefix, std::move(expect_update_success));
run_update_entries.Run();
@@ -564,15 +569,15 @@ TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBSaveAndLoadKeys) {
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::Thread db_thread("dbthread");
ASSERT_TRUE(db_thread.Start());
- std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
- new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));
-
- MockDatabaseCaller caller;
- EXPECT_CALL(caller, InitCallback(true));
+ std::unique_ptr<ProtoDatabase<TestProto>> db =
+ ProtoDatabaseProvider::CreateUniqueDB<TestProto>(db_thread.task_runner());
+ base::RunLoop init_loop;
db->Init(kTestLevelDBClientName, temp_dir.GetPath(), CreateSimpleOptions(),
- base::BindOnce(&MockDatabaseCaller::InitCallback,
- base::Unretained(&caller)));
+ base::BindOnce([](base::OnceClosure closure,
+ bool success) { std::move(closure).Run(); },
+ init_loop.QuitClosure()));
+ init_loop.Run();
base::RunLoop run_update_entries;
auto expect_update_success = base::BindOnce(
@@ -796,8 +801,8 @@ TEST(UniqueProtoDatabaseThreadingTest, TestDBDestruction) {
base::Thread db_thread("dbthread");
ASSERT_TRUE(db_thread.Start());
- std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
- new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));
+ std::unique_ptr<ProtoDatabase<TestProto>> db =
+ ProtoDatabaseProvider::CreateUniqueDB<TestProto>(db_thread.task_runner());
MockDatabaseCaller caller;
EXPECT_CALL(caller, InitCallback(_));
@@ -830,8 +835,8 @@ TEST(UniqueProtoDatabaseThreadingTest, TestDBDestroy) {
base::Thread db_thread("dbthread");
ASSERT_TRUE(db_thread.Start());
- std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
- new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));
+ std::unique_ptr<ProtoDatabase<TestProto>> db =
+ ProtoDatabaseProvider::CreateUniqueDB<TestProto>(db_thread.task_runner());
MockDatabaseCaller caller;
EXPECT_CALL(caller, InitCallback(_));
@@ -847,13 +852,14 @@ TEST(UniqueProtoDatabaseThreadingTest, TestDBDestroy) {
init_loop.Run();
EXPECT_CALL(caller, DestroyCallback(_));
- db->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback,
- base::Unretained(&caller)));
-
- base::RunLoop run_loop;
- db_thread.task_runner()->PostTaskAndReply(FROM_HERE, base::DoNothing(),
- run_loop.QuitClosure());
- run_loop.Run();
+ base::RunLoop destroy_loop;
+ db->Destroy(base::BindOnce(
+ [](MockDatabaseCaller* caller, base::OnceClosure closure, bool success) {
+ caller->DestroyCallback(success);
+ std::move(closure).Run();
+ },
+ &caller, destroy_loop.QuitClosure()));
+ destroy_loop.Run();
// Verify the db is actually destroyed.
EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
diff --git a/chromium/components/leveldb_proto/public/proto_database.h b/chromium/components/leveldb_proto/public/proto_database.h
index 673343a2344..94cff15794b 100644
--- a/chromium/components/leveldb_proto/public/proto_database.h
+++ b/chromium/components/leveldb_proto/public/proto_database.h
@@ -38,6 +38,14 @@ class Callbacks {
using DestroyCallback = base::OnceCallback<void(bool)>;
using OnCreateCallback = base::OnceCallback<void(ProtoLevelDBWrapper*)>;
+ // TODO(ssid): This should be moved to internal folder.
+ using LoadCallback =
+ base::OnceCallback<void(bool, std::unique_ptr<std::vector<std::string>>)>;
+ using GetCallback =
+ base::OnceCallback<void(bool, std::unique_ptr<std::string>)>;
+ using LoadKeysAndEntriesCallback = base::OnceCallback<
+ void(bool, std::unique_ptr<std::map<std::string, std::string>>)>;
+
template <typename T>
class Internal {
public:
@@ -101,12 +109,6 @@ class ProtoDatabase {
entries_to_save,
const leveldb_proto::KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback) = 0;
- virtual void UpdateEntriesWithRemoveFilter(
- std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
- entries_to_save,
- const leveldb_proto::KeyFilter& delete_key_filter,
- const std::string& target_prefix,
- Callbacks::UpdateCallback callback) = 0;
// Asynchronously loads all entries from the database and invokes |callback|
// when complete.
@@ -149,8 +151,6 @@ class ProtoDatabase {
// Asynchronously loads all keys from the database and invokes |callback| with
// those keys when complete.
virtual void LoadKeys(typename Callbacks::LoadKeysCallback callback) = 0;
- virtual void LoadKeys(const std::string& target_prefix,
- typename Callbacks::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,
diff --git a/chromium/components/leveldb_proto/public/proto_database_provider.cc b/chromium/components/leveldb_proto/public/proto_database_provider.cc
index 7b00dda3ddb..0ce62bc90aa 100644
--- a/chromium/components/leveldb_proto/public/proto_database_provider.cc
+++ b/chromium/components/leveldb_proto/public/proto_database_provider.cc
@@ -4,9 +4,11 @@
#include "components/leveldb_proto/public/proto_database_provider.h"
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/leveldb_proto/internal/shared_proto_database.h"
diff --git a/chromium/components/leveldb_proto/public/proto_database_provider.h b/chromium/components/leveldb_proto/public/proto_database_provider.h
index fa3e1352cab..bd221b0b092 100644
--- a/chromium/components/leveldb_proto/public/proto_database_provider.h
+++ b/chromium/components/leveldb_proto/public/proto_database_provider.h
@@ -8,9 +8,10 @@
#include "base/files/file_path.h"
#include "base/sequenced_task_runner.h"
#include "components/keyed_service/core/keyed_service.h"
-#include "components/leveldb_proto/internal/proto_database_wrapper.h"
+#include "components/leveldb_proto/internal/proto_database_impl.h"
#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
#include "components/leveldb_proto/public/proto_database.h"
+#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
namespace leveldb_proto {
@@ -28,22 +29,18 @@ class ProtoDatabaseProvider : public KeyedService {
template <typename T>
static std::unique_ptr<ProtoDatabase<T>> CreateUniqueDB(
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return std::make_unique<UniqueProtoDatabase<T>>(task_runner);
+ return std::make_unique<ProtoDatabaseImpl<T>>(task_runner);
}
- // |client_namespace| is the unique prefix to be used in the shared database
- // if the database returned is a SharedDatabaseClient<T>. This name must be
- // present in |kCurrentSharedProtoDatabaseClients|. |type_prefix| is a unique
- // prefix within the |client_namespace| to be used in the shared database if
- // the database returned is a SharedProtoDatabaseClient<T>. |unique_db_dir|:
+ // |db_type|: Each database should have a type specified in ProtoDbType enum.
+ // This type is used to index data in the shared database. |unique_db_dir|:
// the subdirectory this database should live in within the profile directory.
// |task_runner|: the SequencedTaskRunner to run all database operations on.
// This isn't used by SharedProtoDatabaseClients since all calls using
// the SharedProtoDatabase will run on its TaskRunner.
template <typename T>
std::unique_ptr<ProtoDatabase<T>> GetDB(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
const base::FilePath& unique_db_dir,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
@@ -55,7 +52,7 @@ class ProtoDatabaseProvider : public KeyedService {
private:
friend class TestProtoDatabaseProvider;
- friend class ProtoDatabaseWrapperTest;
+ friend class ProtoDatabaseImplTest;
ProtoDatabaseProvider(const base::FilePath& profile_dir);
@@ -78,12 +75,11 @@ class ProtoDatabaseProvider : public KeyedService {
template <typename T>
std::unique_ptr<ProtoDatabase<T>> ProtoDatabaseProvider::GetDB(
- const std::string& client_namespace,
- const std::string& type_prefix,
+ ProtoDbType db_type,
const base::FilePath& unique_db_dir,
const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
- return base::WrapUnique(new ProtoDatabaseWrapper<T>(
- client_namespace, type_prefix, unique_db_dir, task_runner,
+ return base::WrapUnique(new ProtoDatabaseImpl<T>(
+ db_type, unique_db_dir, task_runner,
base::WrapUnique(new SharedProtoDatabaseProvider(
creation_sequence_, weak_factory_.GetWeakPtr()))));
}
diff --git a/chromium/components/leveldb_proto/public/shared_proto_database_client_list.cc b/chromium/components/leveldb_proto/public/shared_proto_database_client_list.cc
index ccb7b6e7464..64d46e1455d 100644
--- a/chromium/components/leveldb_proto/public/shared_proto_database_client_list.cc
+++ b/chromium/components/leveldb_proto/public/shared_proto_database_client_list.cc
@@ -15,11 +15,49 @@
namespace leveldb_proto {
+namespace {
+
+std::string PtotoDbTypeToString(ProtoDbType db_type) {
+ switch (db_type) {
+ case ProtoDbType::FEATURE_ENGAGEMENT_EVENT:
+ return "FEATURE_ENGAGEMENT_EVENT";
+ case ProtoDbType::FEATURE_ENGAGEMENT_AVAILABILITY:
+ return "FEATURE_ENGAGEMENT_AVAILABILITY";
+ case ProtoDbType::USAGE_STATS_WEBSITE_EVENT:
+ return "USAGE_STATS_WEBSITE_EVENT";
+ case ProtoDbType::USAGE_STATS_SUSPENSION:
+ return "USAGE_STATS_SUSPENSION";
+ case ProtoDbType::USAGE_STATS_TOKEN_MAPPING:
+ return "USAGE_STATS_TOKEN_MAPPING";
+ case ProtoDbType::LAST:
+ NOTREACHED();
+ break;
+ case ProtoDbType::TEST_DATABASE0:
+ return "TEST_DATABASE0";
+ case ProtoDbType::TEST_DATABASE1:
+ return "TEST_DATABASE1";
+ case ProtoDbType::TEST_DATABASE2:
+ return "TEST_DATABASE2";
+ }
+ return std::string();
+}
+
+constexpr ProtoDbType kWhitelistedListForSharedImpl[]{
+ ProtoDbType::LAST, // Marks the end of list.
+};
+
const char* const kDBNameParamPrefix = "migrate_";
+} // namespace
+
// static
-bool SharedProtoDatabaseClientList::ShouldUseSharedDB(
- const std::string& client_name) {
+bool SharedProtoDatabaseClientList::ShouldUseSharedDB(ProtoDbType db_type) {
+ for (size_t i = 0; kWhitelistedListForSharedImpl[i] != ProtoDbType::LAST;
+ ++i) {
+ if (kWhitelistedListForSharedImpl[i] == db_type)
+ return true;
+ }
+
if (!base::FeatureList::IsEnabled(kProtoDBSharedMigration))
return false;
@@ -27,8 +65,9 @@ bool SharedProtoDatabaseClientList::ShouldUseSharedDB(
if (!base::GetFieldTrialParamsByFeature(kProtoDBSharedMigration, &params))
return false;
+ std::string name = PtotoDbTypeToString(db_type);
return base::GetFieldTrialParamByFeatureAsBool(
- kProtoDBSharedMigration, kDBNameParamPrefix + client_name, false);
+ kProtoDBSharedMigration, kDBNameParamPrefix + name, false);
}
} // namespace leveldb_proto \ No newline at end of file
diff --git a/chromium/components/leveldb_proto/public/shared_proto_database_client_list.h b/chromium/components/leveldb_proto/public/shared_proto_database_client_list.h
index 5fefa7e762d..211a24ab5d9 100644
--- a/chromium/components/leveldb_proto/public/shared_proto_database_client_list.h
+++ b/chromium/components/leveldb_proto/public/shared_proto_database_client_list.h
@@ -13,21 +13,37 @@ namespace leveldb_proto {
const char* const kFeatureEngagementName = "FeatureEngagement";
-// NOTE: The client names should not have partial or complete prefix overlap
-// with any other client name, current or obsolete. Internally the stored data
-// is grouped by the prefix of client name. These names cannot be renamed
-// without adding the old name to obsolete client list and such rename would
-// make the client be treated as a new client.
-const char* const kCurrentSharedProtoDatabaseClients[] = {
- kFeatureEngagementName, nullptr};
-
-const char* const kObsoleteSharedProtoDatabaseClients[] = {
- nullptr // Marks the last element.
+// The enum values are used to index into the shared database. Do not rearrange
+// or reuse the integer values. Add new database types at the end of the enum,
+// and update the string mapping in client_list.cc file.
+enum class ProtoDbType {
+ TEST_DATABASE0 = 0,
+ TEST_DATABASE1 = 1,
+ TEST_DATABASE2 = 2,
+ FEATURE_ENGAGEMENT_EVENT = 3,
+ FEATURE_ENGAGEMENT_AVAILABILITY = 4,
+ USAGE_STATS_WEBSITE_EVENT = 5,
+ USAGE_STATS_SUSPENSION = 6,
+ USAGE_STATS_TOKEN_MAPPING = 7,
+
+ LAST,
+};
+
+// List of databases that were introduced after shared db implementation was
+// created. These will be forced to use shared database implementation.
+constexpr ProtoDbType kWhitelistedDbForSharedImpl[]{
+ ProtoDbType::LAST, // Marks the end of list.
+};
+
+// Add any obsolete databases in this list so that, if the data is no longer
+// needed.
+constexpr ProtoDbType kObsoleteSharedProtoDbTypeClients[] = {
+ ProtoDbType::LAST, // Marks the end of list.
};
class SharedProtoDatabaseClientList {
public:
- static bool ShouldUseSharedDB(const std::string& client_name);
+ static bool ShouldUseSharedDB(ProtoDbType db_type);
};
} // namespace leveldb_proto
diff --git a/chromium/components/leveldb_proto/testing/fake_db.h b/chromium/components/leveldb_proto/testing/fake_db.h
index 9e987a02073..8ab4f2d23c0 100644
--- a/chromium/components/leveldb_proto/testing/fake_db.h
+++ b/chromium/components/leveldb_proto/testing/fake_db.h
@@ -16,14 +16,14 @@
#include "base/files/file_path.h"
#include "base/task/post_task.h"
#include "base/test/test_simple_task_runner.h"
-#include "components/leveldb_proto/internal/unique_proto_database.h"
+#include "components/leveldb_proto/internal/proto_database_impl.h"
#include "components/leveldb_proto/public/proto_database.h"
namespace leveldb_proto {
namespace test {
template <typename T>
-class FakeDB : public UniqueProtoDatabase<T> {
+class FakeDB : public ProtoDatabaseImpl<T> {
using Callback = base::OnceCallback<void(bool)>;
public:
@@ -70,6 +70,11 @@ class FakeDB : public UniqueProtoDatabase<T> {
const std::string& target_prefix,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
override;
+ void LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
+ override;
void LoadKeys(Callbacks::LoadKeysCallback callback) override;
void GetEntry(const std::string& key,
typename Callbacks::Internal<T>::GetCallback callback) override;
@@ -127,8 +132,7 @@ class FakeDB : public UniqueProtoDatabase<T> {
template <typename T>
FakeDB<T>::FakeDB(EntryMap* db)
- : UniqueProtoDatabase<T>(
- base::MakeRefCounted<base::TestSimpleTaskRunner>()) {
+ : ProtoDatabaseImpl<T>(base::MakeRefCounted<base::TestSimpleTaskRunner>()) {
db_ = db;
}
@@ -246,6 +250,22 @@ void FakeDB<T>::LoadKeysAndEntriesWithFilter(
}
template <typename T>
+void FakeDB<T>::LoadKeysAndEntriesInRange(
+ const std::string& start,
+ const std::string& end,
+ typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
+ auto keys_entries = std::make_unique<std::map<std::string, T>>();
+ for (const auto& pair : *db_) {
+ std::string key = pair.first;
+ if (start <= key && key <= end)
+ keys_entries->insert(pair);
+ }
+
+ load_callback_ = base::BindOnce(RunLoadKeysAndEntriesCallback,
+ std::move(callback), std::move(keys_entries));
+}
+
+template <typename T>
void FakeDB<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
std::unique_ptr<std::vector<std::string>> keys(
new std::vector<std::string>());
diff --git a/chromium/components/link_header_util/link_header_util_unittest.cc b/chromium/components/link_header_util/link_header_util_unittest.cc
index 21ce2d424b7..bd69cd91fe9 100644
--- a/chromium/components/link_header_util/link_header_util_unittest.cc
+++ b/chromium/components/link_header_util/link_header_util_unittest.cc
@@ -215,9 +215,9 @@ const SimpleParseTestData simple_parse_tests[] = {
""},
};
-INSTANTIATE_TEST_CASE_P(LinkHeaderTest,
- SimpleParseTest,
- testing::ValuesIn(simple_parse_tests));
+INSTANTIATE_TEST_SUITE_P(LinkHeaderTest,
+ SimpleParseTest,
+ testing::ValuesIn(simple_parse_tests));
} // namespace
diff --git a/chromium/components/management_strings.grdp b/chromium/components/management_strings.grdp
index 9e66e7b7279..60a0008cd6c 100644
--- a/chromium/components/management_strings.grdp
+++ b/chromium/components/management_strings.grdp
@@ -1,11 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Strings for the management disclosure panel
+
+ Disclosing admin capabilities to managed users is an important part of
+ striking a balance between the data needs of admins and the privacy
+ expectations of users.
+
+ Please consult with the privacy team when adding or changing strings.
+-->
+
<grit-part>
- <message name="IDS_MANAGEMENT_TITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment">
- <ph name="PRODUCT_NAME">$1<ex>Chrome OS</ex></ph> management
- </message>
- <message name="IDS_MANAGEMENT_TITLE_BY" desc="Title of chrome://management page, shows when device managed by known organization">
- Device managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>
- </message>
+ <!-- Title of the page -->
+ <if expr="chromeos">
+ <message name="IDS_MANAGEMENT_TITLE_MANAGED" desc="Title of chrome://management page, shows when device is managed by unknown organization">
+ Your <ph name="DEVICE_NAME">$1<ex>Chromebook</ex></ph> is managed
+ </message>
+ <message name="IDS_MANAGEMENT_TITLE_BY" desc="Title of chrome://management page, shows when device managed by known organization">
+ <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> managed by <ph name="ENROLLMENT_DOMAIN">$2<ex>example.com</ex></ph>
+ </message>
+ <message name="IDS_MANAGEMENT_NOT_MANAGED_TITLE" desc="Message indicating that the device is not managed">
+ Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is not managed
+ </message>
+ </if>
+ <if expr="not chromeos">
+ <message name="IDS_MANAGEMENT_TITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment">
+ Your browser is managed
+ </message>
+ <message name="IDS_MANAGEMENT_TITLE_BY" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment">
+ Your browser is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>
+ </message>
+ <message name="IDS_MANAGEMENT_NOT_MANAGED_TITLE" desc="Title of chrome://management page for a browser that is not managed">
+ Your browser is not managed
+ </message>
+ <message name="IDS_MANAGEMENT_BROWSER_NOTICE" desc="Message indicating that the browser is managed by an unknown organization">
+ This browser is managed by a company, school or other organization. Your administrator can change your browser setup remotely. Activity on this device may also be managed outside of Chrome. <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Learn More<ph name="END_LINK">&lt;/a&gt;</ph>
+ </message>
+ <message name="IDS_MANAGEMENT_NOT_MANAGED_NOTICE" desc="Message indicating that the browser is not managed">
+ This browser is not managed by a company or other organization. Activity on this device may be managed outside of Chrome. <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Learn More<ph name="END_LINK">&lt;/a&gt;</ph>
+ </message>
+ <message name="IDS_MANAGEMENT_MANAGEMENT_BY_NOTICE" desc="Message indicating that the browser is managed by a known organization">
+ This browser is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. Your administrator can change your browser setup remotely. Activity on this device may also be managed outside of Chrome. <ph name="BEGIN_LINK">&lt;a target="_blank" href="$2"&gt;</ph>Learn More<ph name="END_LINK">&lt;/a&gt;</ph>
+ </message>
+ </if>
<message name="IDS_MANAGEMENT_DEVICE_NOT_MANAGED" desc="Message indicating that the device is not managed">
Your device is not managed by an administrator.
@@ -23,36 +60,39 @@
Your account is managed by <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph>. This means your administrator may remotely configure your account.
</message>
- <message name="IDS_MANAGEMENT_DEVICE_REPORTING" desc="Title of the types of device reporting section of the page">
- Reporting
- </message>
- <message name="IDS_MANAGEMENT_BROWSER_REPORTING" desc="Title of the types of browser reporting section of the page" translateable="false">
- Browser reporting
- </message>
- <message name="IDS_MANAGEMENT_DEVICE_CONFIGURATION" desc="Message telling users that their administrator has set some specific policies on their device">
- Your device has been configured to:
- </message>
- <message name="IDS_MANAGEMENT_LOG_UPLOAD_ENABLED" desc="Message stating that administrators have access to system logs on user's device.">
- send system logs to the management server
- </message>
- <message name="IDS_MANAGEMENT_REPORT_DEVICE_ACTIVITY_TIMES" desc="Message stating that administrators see device activity times.">
- report time periods when a user is active on the device
- </message>
- <message name="IDS_MANAGEMENT_REPORT_DEVICE_HARDWARE_STATUS" desc="Message stating that administrators see device hardware status.">
- report hardware statistics such as CPU/RAM usage
- </message>
- <message name="IDS_MANAGEMENT_REPORT_DEVICE_NETWORK_INTERFACES" desc="Message stating that administrators see device network interfaces.">
- report list of network interfaces with their types and hardware addresses
- </message>
- <message name="IDS_MANAGEMENT_REPORT_DEVICE_USERS" desc="Message stating that administrators see all users that have used the device recently.">
- report list of device users that have recently logged in
- </message>
+ <if expr="chromeos">
+ <!-- Strings related to device reporting section of the management page -->
+ <message name="IDS_MANAGEMENT_DEVICE_REPORTING" desc="Title of the types of device reporting section of the page">
+ Device
+ </message>
+ <message name="IDS_MANAGEMENT_DEVICE_CONFIGURATION" desc="Message telling users that their administrator has set some specific policies on their device">
+ Your administrator can see:
+ </message>
+ <message name="IDS_MANAGEMENT_REPORT_DEVICE_USERS" desc="Message stating that administrators see all users that have used the device recently.">
+ Who has used the device recently
+ </message>
+ <message name="IDS_MANAGEMENT_REPORT_DEVICE_ACTIVITY_TIMES" desc="Message stating that administrators see device activity times.">
+ Who has used the device recently and when
+ </message>
+ <message name="IDS_MANAGEMENT_REPORT_DEVICE_HARDWARE_STATUS" desc="Message stating that administrators see device hardware status.">
+ Device statistics such as CPU/RAM usage
+ </message>
+ <message name="IDS_MANAGEMENT_LOG_UPLOAD_ENABLED" desc="Message stating that administrators have access to system logs on user's device.">
+ Detailed system logs
+ </message>
+ <message name="IDS_MANAGEMENT_REPORT_DEVICE_NETWORK_INTERFACES" desc="Message stating that administrators see device network interfaces.">
+ Network addresses
+ </message>
+ </if>
<message name="IDS_MANAGEMENT_EXTENSION_REPORTING" desc="Title of the force installed extensions section of the page">
- Extension reporting
+ Extensions
</message>
<message name="IDS_MANAGEMENT_EXTENSIONS_INSTALLED" desc="Message describing that the administrator has installed some powerful extensions on the managed user's browser">
- Your administrators have installed extensions with powerful capabilities.
+ The administrator of this device has installed extensions for additional functions. Extensions have access to some of your data.
+ </message>
+ <message name="IDS_MANAGEMENT_EXTENSIONS_INSTALLED_BY" desc="Message describing that the administrator has installed some powerful extensions on the managed user's browser from a specific domain">
+ <ph name="ENROLLMENT_DOMAIN">$1<ex>example.com</ex></ph> has installed extensions for additional functions. Extensions have access to some of your data.
</message>
<message name="IDS_MANAGEMENT_EXTENSIONS_NAME" desc="Title of a column of the extension table showing the name of the extension">
Name
@@ -64,42 +104,44 @@
<message name="IDS_MANAGEMENT_LOCAL_TRUST_ROOTS" desc="Title of the types of local trust roots section of the page">
Custom root certificates
</message>
- <message name="IDS_MANAGEMENT_TRUST_ROOTS_NOT_CONFIGURED" desc="Message describing that the administrators have not installed certificates" translateable="false">
+ <message name="IDS_MANAGEMENT_TRUST_ROOTS_NOT_CONFIGURED" desc="Message describing that the administrators have not installed certificates">
The contents of websites that you visit is not seen by your administrators
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_MACHINE_NAME" desc="Message explaining that an extension currently reports the user's machine name" translateable="false">
- Report your machine's name
+
+ <message name="IDS_MANAGEMENT_BROWSER_REPORTING" desc="Title of the types of browser reporting section of the page">
+ Browser
+ </message>
+ <message name="IDS_MANAGEMENT_BROWSER_REPORTING_EXPLANATION" desc="Message explaining browser reporting">
+ Your administrator can see:
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_MACHINE_NAME_ADDRESS" desc="Message explaining that an extension currently reports the user's machine name and address" translateable="false">
- Report your machine's name and network address
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_MACHINE_NAME" desc="Message explaining that an extension currently reports the user's machine name">
+ Your device name
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_USERNAME" desc="Message explaining that an extension currently reports the user's username" translateable="false">
- Report you OS and browser usernames
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_MACHINE_NAME_ADDRESS" desc="Message explaining that an extension currently reports the user's machine name and address">
+ Your device name and network address
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_VERSION" desc="Message explaining that an extension currently reports the user's browser and machine version" translateable="false">
- Report software version information about your browser and machine
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_USERNAME" desc="Message explaining that an extension currently reports the user's username">
+ Usernames for your device and browser
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_POLICIES" desc="Message explaining that an extension currently reports the user's enterprise policies" translateable="false">
- Report information about applied enterprise policies
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_VERSION" desc="Message explaining that an extension currently reports the user's browser and machine version">
+ Version information about your device and browser
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_EXTENSIONS_PLUGINS" desc="Message explaining that an extension currently reports the user's exensions and plugins" translateable="false">
- Report installed extensions and plugins
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_EXTENSIONS_PLUGINS" desc="Message explaining that an extension currently reports the user's exensions and plugins">
+ Information about installed extensions and plugins
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_SAFE_BROWSING_WARNINGS" desc="Message explaining that an extension currently reports the user's safe browsing warnings and ignored warnings" translateable="false">
- Report Safe Browsing warnings
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_SAFE_BROWSING_WARNINGS" desc="Message explaining that an extension currently reports the user's safe browsing warnings and ignored warnings">
+ <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Safe Browsing<ph name="END_LINK">&lt;/a&gt;</ph> warnings
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_PERF_CRASH" desc="Message explaining that an extension currently reports the user's performance data and crash report" translateable="false">
- Report performance data and crash reports
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_USER_BROWSING_DATA" desc="Message explaining that an extension currently reports the user's browsing data">
+ Websites you visit and time spent on them
</message>
- <message name="IDS_MANAGEMENT_EXTENSION_REPORT_WEBSITE_USAGE_STATISTICS" desc="Message explaining that an extension currently reports the user's website usage statistics" translateable="false">
- Report how much time you spend on each website
+ <message name="IDS_MANAGEMENT_EXTENSION_REPORT_PERF_CRASH" desc="Message explaining that an extension currently reports the user's performance data and crash report">
+ Performance data and crash reports
</message>
+
<if expr="chromeos">
<message name="IDS_MANAGEMENT_TRUST_ROOTS_CONFIGURED" desc="Message describing that the administrators have installed their own certificates">
Your administrator has configured custom root certificates, which may allow the administrator to see the contents of websites that you visit.
</message>
</if>
- <message name="IDS_MANAGEMENT_DESKTOP_MONITORING_NOTICE" desc="Message explaining that the administrators have ways to monitor users outside of chrome's control" translateable="false">
- Administrators may have other ways of monitoring users, outside of Chrome.
- </message>
</grit-part>
diff --git a/chromium/components/metrics/BUILD.gn b/chromium/components/metrics/BUILD.gn
index 70e8b1b0d02..aab66ed6c86 100644
--- a/chromium/components/metrics/BUILD.gn
+++ b/chromium/components/metrics/BUILD.gn
@@ -118,6 +118,7 @@ jumbo_static_library("metrics") {
"//crypto",
"//extensions/buildflags",
"//third_party/zlib/google:compression_utils",
+ "//url",
]
if (is_chromeos) {
@@ -278,12 +279,10 @@ source_set("child_call_stack_profile_builder") {
public = [
"call_stack_profile_builder.h",
"child_call_stack_profile_collector.h",
- "legacy_call_stack_profile_builder.h",
]
sources = [
"call_stack_profile_builder.cc",
"child_call_stack_profile_collector.cc",
- "legacy_call_stack_profile_builder.cc",
]
public_deps = [
":call_stack_profile_params",
@@ -374,7 +373,6 @@ source_set("unit_tests") {
"field_trials_provider_unittest.cc",
"file_metrics_provider_unittest.cc",
"histogram_encoder_unittest.cc",
- "legacy_call_stack_profile_builder_unittest.cc",
"machine_id_provider_win_unittest.cc",
"metrics_log_manager_unittest.cc",
"metrics_log_store_unittest.cc",
diff --git a/chromium/components/metrics/DEPS b/chromium/components/metrics/DEPS
index 0d4fca0b380..e12ab69fd03 100644
--- a/chromium/components/metrics/DEPS
+++ b/chromium/components/metrics/DEPS
@@ -17,4 +17,5 @@ include_rules = [
"+third_party/metrics_proto",
"+third_party/zlib/google",
"-net",
+ "+url"
]
diff --git a/chromium/components/metrics/call_stack_profile_builder.cc b/chromium/components/metrics/call_stack_profile_builder.cc
index 7db290c3686..cde0fb13095 100644
--- a/chromium/components/metrics/call_stack_profile_builder.cc
+++ b/chromium/components/metrics/call_stack_profile_builder.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <string>
+#include <tuple>
#include <utility>
#include "base/files/file_path.h"
@@ -48,8 +49,10 @@ uint64_t HashModuleFilename(const base::FilePath& filename) {
CallStackProfileBuilder::CallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder,
+ const MetadataRecorder* metadata_recorder,
base::OnceClosure completed_callback)
: work_id_recorder_(work_id_recorder),
+ metadata_recorder_(metadata_recorder),
profile_start_time_(base::TimeTicks::Now()) {
completed_callback_ = std::move(completed_callback);
sampled_profile_.set_process(
@@ -61,6 +64,10 @@ CallStackProfileBuilder::CallStackProfileBuilder(
CallStackProfileBuilder::~CallStackProfileBuilder() = default;
+base::ModuleCache* CallStackProfileBuilder::GetModuleCache() {
+ return &module_cache_;
+}
+
// This function is invoked on the profiler thread while the target thread is
// suspended so must not take any locks, including indirectly through use of
// heap allocation, LOG, CHECK, or DCHECK.
@@ -84,22 +91,21 @@ void CallStackProfileBuilder::OnSampleCompleted(
// keep the frame information even if its module is invalid so we have
// visibility into how often this issue is happening on the server.
CallStackProfile::Location* location = stack.add_frame();
- if (!frame.module.is_valid)
+ if (!frame.module)
continue;
// Dedup modules.
- const base::ModuleCache::Module& module = frame.module;
- auto module_loc = module_index_.find(module.base_address);
+ auto module_loc = module_index_.find(frame.module);
if (module_loc == module_index_.end()) {
- modules_.push_back(module);
+ modules_.push_back(frame.module);
size_t index = modules_.size() - 1;
- module_loc = module_index_.emplace(module.base_address, index).first;
+ module_loc = module_index_.emplace(frame.module, index).first;
}
// Write CallStackProfile::Location protobuf message.
ptrdiff_t module_offset =
reinterpret_cast<const char*>(frame.instruction_pointer) -
- reinterpret_cast<const char*>(module.base_address);
+ reinterpret_cast<const char*>(frame.module->GetBaseAddress());
DCHECK_GE(module_offset, 0);
location->set_address(static_cast<uint64_t>(module_offset));
location->set_module_id_index(module_loc->second);
@@ -127,6 +133,24 @@ void CallStackProfileBuilder::OnSampleCompleted(
stack_sample_proto->set_stack_index(stack_loc->second);
if (is_continued_work_)
stack_sample_proto->set_continued_work(is_continued_work_);
+
+ // TODO(crbug.com/913570): Update metadata recording to not heap allocate
+ // and move to RecordMetadata().
+ if (metadata_recorder_) {
+ uint64_t item_hash;
+ int64_t item_value;
+ std::tie(item_hash, item_value) = metadata_recorder_->GetHashAndValue();
+ int next_item_index = call_stack_profile->metadata_name_hash_size();
+ auto result = metadata_hashes_cache_.emplace(item_hash, next_item_index);
+ if (result.second)
+ call_stack_profile->add_metadata_name_hash(item_hash);
+ CallStackProfile::MetadataItem* item = stack_sample_proto->add_metadata();
+ // TODO(crbug.com/913570): Only add metadata items if different than
+ // the value for the previous sample, per
+ // https://cs.chromium.org/chromium/src/third_party/metrics_proto/call_stack_profile.proto?rcl=8811ddb099&l=108-110.
+ item->set_name_hash_index(result.first->second);
+ item->set_value(item_value);
+ }
}
void CallStackProfileBuilder::OnProfileCompleted(
@@ -140,11 +164,12 @@ void CallStackProfileBuilder::OnProfileCompleted(
call_stack_profile->set_sampling_period_ms(sampling_period.InMilliseconds());
// Write CallStackProfile::ModuleIdentifier protobuf message.
- for (const auto& module : modules_) {
+ for (const auto* module : modules_) {
CallStackProfile::ModuleIdentifier* module_id =
call_stack_profile->add_module_id();
- module_id->set_build_id(module.id);
- module_id->set_name_md5_prefix(HashModuleFilename(module.filename));
+ module_id->set_build_id(module->GetId());
+ module_id->set_name_md5_prefix(
+ HashModuleFilename(module->GetDebugBasename()));
}
PassProfilesToMetricsProvider(std::move(sampled_profile_));
diff --git a/chromium/components/metrics/call_stack_profile_builder.h b/chromium/components/metrics/call_stack_profile_builder.h
index 0f22f1c8498..f06acd807bf 100644
--- a/chromium/components/metrics/call_stack_profile_builder.h
+++ b/chromium/components/metrics/call_stack_profile_builder.h
@@ -7,9 +7,12 @@
#include <limits>
#include <map>
+#include <unordered_map>
+#include <utility>
#include <vector>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/sampling_heap_profiler/module_cache.h"
#include "base/time/time.h"
@@ -36,6 +39,17 @@ class WorkIdRecorder {
WorkIdRecorder& operator=(const WorkIdRecorder&) = delete;
};
+// Records a metadata item to associate with the sample.
+// TODO(crbug.com/913570): Extend to support multiple metadata items per sample.
+class MetadataRecorder {
+ public:
+ MetadataRecorder() = default;
+ virtual ~MetadataRecorder() = default;
+ virtual std::pair<uint64_t, int64_t> GetHashAndValue() const = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(MetadataRecorder);
+};
+
// An instance of the class is meant to be passed to base::StackSamplingProfiler
// to collect profiles. The profiles collected are uploaded via the metrics log.
//
@@ -54,11 +68,13 @@ class CallStackProfileBuilder
explicit CallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder = nullptr,
+ const MetadataRecorder* metadata_recorder = nullptr,
base::OnceClosure completed_callback = base::OnceClosure());
~CallStackProfileBuilder() override;
// base::StackSamplingProfiler::ProfileBuilder:
+ base::ModuleCache* GetModuleCache() override;
void RecordMetadata() override;
void OnSampleCompleted(
std::vector<base::StackSamplingProfiler::Frame> frames) override;
@@ -88,9 +104,14 @@ class CallStackProfileBuilder
const CallStackProfile::Stack* stack2) const;
};
+ // The module cache to use for the duration the sampling associated with this
+ // ProfileBuilder.
+ base::ModuleCache module_cache_;
+
unsigned int last_work_id_ = std::numeric_limits<unsigned int>::max();
bool is_continued_work_ = false;
const WorkIdRecorder* const work_id_recorder_;
+ const MetadataRecorder* const metadata_recorder_;
// The SampledProfile protobuf message which contains the collected stack
// samples.
@@ -99,11 +120,11 @@ class CallStackProfileBuilder
// The indexes of stacks, indexed by stack's address.
std::map<const CallStackProfile::Stack*, int, StackComparer> stack_index_;
- // The indexes of modules, indexed by module's base_address.
- std::map<uintptr_t, size_t> module_index_;
+ // The indexes of modules in the modules_ vector below..
+ std::unordered_map<const base::ModuleCache::Module*, size_t> module_index_;
// The distinct modules in the current profile.
- std::vector<base::ModuleCache::Module> modules_;
+ std::vector<const base::ModuleCache::Module*> modules_;
// Callback made when sampling a profile completes.
base::OnceClosure completed_callback_;
@@ -111,6 +132,9 @@ class CallStackProfileBuilder
// The start time of a profile collection.
const base::TimeTicks profile_start_time_;
+ // Maps metadata hash to index in |metadata_name_hash| array.
+ std::unordered_map<uint64_t, int> metadata_hashes_cache_;
+
DISALLOW_COPY_AND_ASSIGN(CallStackProfileBuilder);
};
diff --git a/chromium/components/metrics/call_stack_profile_builder_unittest.cc b/chromium/components/metrics/call_stack_profile_builder_unittest.cc
index a144f3e49f5..0cc4de02719 100644
--- a/chromium/components/metrics/call_stack_profile_builder_unittest.cc
+++ b/chromium/components/metrics/call_stack_profile_builder_unittest.cc
@@ -17,12 +17,33 @@
#include "third_party/metrics_proto/sampled_profile.pb.h"
using Frame = base::StackSamplingProfiler::Frame;
-using Module = base::ModuleCache::Module;
namespace metrics {
namespace {
+// Stub module for testing.
+class TestModule : public base::ModuleCache::Module {
+ public:
+ TestModule(uintptr_t base_address = 0,
+ const std::string& id = "",
+ const base::FilePath& debug_basename = base::FilePath())
+ : base_address_(base_address), id_(id), debug_basename_(debug_basename) {}
+
+ TestModule(const TestModule&) = delete;
+ TestModule& operator=(const TestModule&) = delete;
+
+ uintptr_t GetBaseAddress() const override { return base_address_; }
+ std::string GetId() const override { return id_; }
+ base::FilePath GetDebugBasename() const override { return debug_basename_; }
+ size_t GetSize() const override { return 0; }
+
+ private:
+ uintptr_t base_address_;
+ std::string id_;
+ base::FilePath debug_basename_;
+};
+
constexpr CallStackProfileParams kProfileParams = {
CallStackProfileParams::BROWSER_PROCESS,
CallStackProfileParams::MAIN_THREAD,
@@ -33,6 +54,7 @@ class TestingCallStackProfileBuilder : public CallStackProfileBuilder {
TestingCallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder = nullptr,
+ const MetadataRecorder* metadata_recorder = nullptr,
base::OnceClosure completed_callback = base::OnceClosure());
~TestingCallStackProfileBuilder() override;
@@ -51,9 +73,11 @@ class TestingCallStackProfileBuilder : public CallStackProfileBuilder {
TestingCallStackProfileBuilder::TestingCallStackProfileBuilder(
const CallStackProfileParams& profile_params,
const WorkIdRecorder* work_id_recorder,
+ const MetadataRecorder* metadata_recorder,
base::OnceClosure completed_callback)
: CallStackProfileBuilder(profile_params,
work_id_recorder,
+ metadata_recorder,
std::move(completed_callback)) {}
TestingCallStackProfileBuilder::~TestingCallStackProfileBuilder() = default;
@@ -71,7 +95,7 @@ TEST(CallStackProfileBuilderTest, ProfilingCompleted) {
EXPECT_CALL(mock_closure, Run()).Times(1);
auto profile_builder = std::make_unique<TestingCallStackProfileBuilder>(
- kProfileParams, nullptr, mock_closure.Get());
+ kProfileParams, nullptr, nullptr, mock_closure.Get());
#if defined(OS_WIN)
uint64_t module_md5 = 0x46C3E4166659AC02ULL;
@@ -82,16 +106,16 @@ TEST(CallStackProfileBuilderTest, ProfilingCompleted) {
#endif
const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
+ TestModule module1(module_base_address1, "1", module_path);
+ Frame frame1 = {module_base_address1 + 0x10, &module1};
const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
+ TestModule module2(module_base_address2, "2", module_path);
+ Frame frame2 = {module_base_address2 + 0x10, &module2};
const uintptr_t module_base_address3 = 0x1010;
- Module module3 = {module_base_address3, "3", module_path};
- Frame frame3 = {module_base_address3 + 0x10, module3};
+ TestModule module3(module_base_address3, "3", module_path);
+ Frame frame3 = {module_base_address3 + 0x10, &module3};
std::vector<Frame> frames1 = {frame1, frame2};
std::vector<Frame> frames2 = {frame3};
@@ -155,19 +179,11 @@ TEST(CallStackProfileBuilderTest, StacksDeduped) {
auto profile_builder =
std::make_unique<TestingCallStackProfileBuilder>(kProfileParams);
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
+ TestModule module1;
+ Frame frame1 = {0x10, &module1};
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
+ TestModule module2;
+ Frame frame2 = {0x20, &module2};
std::vector<Frame> frames = {frame1, frame2};
@@ -201,19 +217,11 @@ TEST(CallStackProfileBuilderTest, StacksNotDeduped) {
auto profile_builder =
std::make_unique<TestingCallStackProfileBuilder>(kProfileParams);
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
+ TestModule module1;
+ Frame frame1 = {0x10, &module1};
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
+ TestModule module2;
+ Frame frame2 = {0x20, &module2};
std::vector<Frame> frames1 = {frame1};
std::vector<Frame> frames2 = {frame2};
@@ -247,9 +255,8 @@ TEST(CallStackProfileBuilderTest, Modules) {
auto profile_builder =
std::make_unique<TestingCallStackProfileBuilder>(kProfileParams);
- const uintptr_t module_base_address1 = 0x1000;
- Module module1; // module1 has no information hence invalid.
- Frame frame1 = {module_base_address1 + 0x10, module1};
+ // A frame with no module.
+ Frame frame1 = {0x1010, nullptr};
const uintptr_t module_base_address2 = 0x1100;
#if defined(OS_WIN)
@@ -259,8 +266,8 @@ TEST(CallStackProfileBuilderTest, Modules) {
uint64_t module_md5 = 0x554838A8451AC36CULL;
base::FilePath module_path("/some/path/to/chrome");
#endif
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
+ TestModule module2(module_base_address2, "2", module_path);
+ Frame frame2 = {module_base_address2 + 0x10, &module2};
std::vector<Frame> frames = {frame1, frame2};
@@ -308,11 +315,9 @@ TEST(CallStackProfileBuilderTest, DedupModules) {
base::FilePath module_path("/some/path/to/chrome");
#endif
- Module module1 = {module_base_address, "1", module_path};
- Frame frame1 = {module_base_address + 0x10, module1};
-
- Module module2 = {module_base_address, "1", module_path};
- Frame frame2 = {module_base_address + 0x20, module2};
+ TestModule module(module_base_address, "1", module_path);
+ Frame frame1 = {module_base_address + 0x10, &module};
+ Frame frame2 = {module_base_address + 0x20, &module};
std::vector<Frame> frames = {frame1, frame2};
@@ -331,8 +336,8 @@ TEST(CallStackProfileBuilderTest, DedupModules) {
ASSERT_EQ(1, profile.stack_size());
ASSERT_EQ(2, profile.stack(0).frame_size());
- // Since module1 and module2 have the same base address, they are considered
- // the same module and therefore deduped.
+ // The two frames share the same module, which should be deduped in the
+ // output.
ASSERT_TRUE(profile.stack(0).frame(0).has_module_id_index());
EXPECT_EQ(0, profile.stack(0).frame(0).module_id_index());
ASSERT_TRUE(profile.stack(0).frame(0).has_address());
@@ -362,14 +367,8 @@ TEST(CallStackProfileBuilderTest, WorkIds) {
auto profile_builder = std::make_unique<TestingCallStackProfileBuilder>(
kProfileParams, &work_id_recorder);
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- Module module = {0x1000, "1", module_path};
- Frame frame = {0x1000 + 0x10, module};
+ TestModule module;
+ Frame frame = {0x10, &module};
// Id 0 means the message loop hasn't been started yet, so the sample should
// not have continued_work set.
@@ -406,4 +405,46 @@ TEST(CallStackProfileBuilderTest, WorkIds) {
EXPECT_TRUE(profile.stack_sample(4).continued_work());
}
+TEST(CallStackProfileBuilderTest, MetadataRecorder) {
+ class TestMetadataRecorder : public MetadataRecorder {
+ public:
+ std::pair<uint64_t, int64_t> GetHashAndValue() const override {
+ return std::make_pair(0x5A105E8B9D40E132ull, current_value);
+ }
+ int64_t current_value;
+ };
+
+ TestMetadataRecorder metadata_recorder;
+ auto profile_builder = std::make_unique<TestingCallStackProfileBuilder>(
+ kProfileParams, nullptr, &metadata_recorder);
+
+ TestModule module;
+ Frame frame = {0x10, &module};
+
+ metadata_recorder.current_value = 5;
+ profile_builder->OnSampleCompleted({frame});
+ metadata_recorder.current_value = 8;
+ profile_builder->OnSampleCompleted({frame});
+
+ profile_builder->OnProfileCompleted(base::TimeDelta::FromMilliseconds(500),
+ base::TimeDelta::FromMilliseconds(100));
+
+ const SampledProfile& proto = profile_builder->test_sampled_profile();
+
+ ASSERT_TRUE(proto.has_call_stack_profile());
+ const CallStackProfile& profile = proto.call_stack_profile();
+
+ ASSERT_EQ(2, profile.stack_sample_size());
+ EXPECT_EQ(1, profile.stack_sample(0).metadata_size());
+ EXPECT_EQ(1, profile.stack_sample(1).metadata_size());
+
+ ASSERT_EQ(1, profile.metadata_name_hash_size());
+ EXPECT_EQ(0x5A105E8B9D40E132ull, profile.metadata_name_hash(0));
+
+ EXPECT_EQ(0, profile.stack_sample(0).metadata(0).name_hash_index());
+ EXPECT_EQ(5, profile.stack_sample(0).metadata(0).value());
+ EXPECT_EQ(0, profile.stack_sample(1).metadata(0).name_hash_index());
+ EXPECT_EQ(8, profile.stack_sample(1).metadata(0).value());
+}
+
} // namespace metrics
diff --git a/chromium/components/metrics/drive_metrics_provider.cc b/chromium/components/metrics/drive_metrics_provider.cc
index bb92915a713..18b1ab141f8 100644
--- a/chromium/components/metrics/drive_metrics_provider.cc
+++ b/chromium/components/metrics/drive_metrics_provider.cc
@@ -50,7 +50,8 @@ DriveMetricsProvider::SeekPenaltyResponse::SeekPenaltyResponse()
DriveMetricsProvider::DriveMetrics
DriveMetricsProvider::GetDriveMetricsOnBackgroundThread(
int local_state_path_key) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::WILL_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::WILL_BLOCK);
DriveMetricsProvider::DriveMetrics metrics;
QuerySeekPenalty(base::FILE_EXE, &metrics.app_drive);
diff --git a/chromium/components/metrics/enabled_state_provider.cc b/chromium/components/metrics/enabled_state_provider.cc
index 31f296437cd..a8ebe039cdc 100644
--- a/chromium/components/metrics/enabled_state_provider.cc
+++ b/chromium/components/metrics/enabled_state_provider.cc
@@ -4,10 +4,18 @@
#include "components/metrics/enabled_state_provider.h"
+#include "base/base_switches.h"
+#include "base/command_line.h"
+
namespace metrics {
bool EnabledStateProvider::IsReportingEnabled() const {
- return IsConsentGiven();
+ // Disable metrics reporting when field trials are forced, as otherwise this
+ // would pollute experiment results in UMA. Note: This is done here and not
+ // in IsConsentGiven() as we do not want this to affect field trial entropy
+ // logic (i.e. high entropy source should still be used if UMA is on).
+ return IsConsentGiven() && !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceFieldTrials);
}
} // namespace metrics
diff --git a/chromium/components/metrics/file_metrics_provider.cc b/chromium/components/metrics/file_metrics_provider.cc
index e9931d0cc6a..49efa12b0a6 100644
--- a/chromium/components/metrics/file_metrics_provider.cc
+++ b/chromium/components/metrics/file_metrics_provider.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/feature_list.h"
@@ -35,9 +36,6 @@ namespace metrics {
namespace {
-const base::Feature kBackgroundIndependentMetrics = {
- "BackgoundIndependentMetrics", base::FEATURE_ENABLED_BY_DEFAULT};
-
// These structures provide values used to define how files are opened and
// accessed. It obviates the need for multiple code-paths within several of
// the methods.
@@ -778,23 +776,15 @@ void FileMetricsProvider::ProvideIndependentMetrics(
SourceInfo* source_ptr = source.get();
DCHECK(source->allocator);
- if (base::FeatureList::IsEnabled(kBackgroundIndependentMetrics)) {
- // Do the actual work as a background task.
- base::PostTaskAndReplyWithResult(
- task_runner_.get(), FROM_HERE,
- base::BindOnce(
- &FileMetricsProvider::ProvideIndependentMetricsOnTaskRunner,
- source_ptr, system_profile_proto, snapshot_manager),
- base::BindOnce(&FileMetricsProvider::ProvideIndependentMetricsCleanup,
- weak_factory_.GetWeakPtr(), std::move(done_callback),
- std::move(source)));
- } else {
- // Do the actual work now, inline (for performance comparisons).
- bool success = ProvideIndependentMetricsOnTaskRunner(
- source_ptr, system_profile_proto, snapshot_manager);
- ProvideIndependentMetricsCleanup(std::move(done_callback),
- std::move(source), success);
- }
+ // Do the actual work as a background task.
+ base::PostTaskAndReplyWithResult(
+ task_runner_.get(), FROM_HERE,
+ base::BindOnce(
+ &FileMetricsProvider::ProvideIndependentMetricsOnTaskRunner,
+ source_ptr, system_profile_proto, snapshot_manager),
+ base::BindOnce(&FileMetricsProvider::ProvideIndependentMetricsCleanup,
+ weak_factory_.GetWeakPtr(), std::move(done_callback),
+ std::move(source)));
}
void FileMetricsProvider::ProvideIndependentMetricsCleanup(
diff --git a/chromium/components/metrics/file_metrics_provider_unittest.cc b/chromium/components/metrics/file_metrics_provider_unittest.cc
index dbbbcba5e97..dd03be8acee 100644
--- a/chromium/components/metrics/file_metrics_provider_unittest.cc
+++ b/chromium/components/metrics/file_metrics_provider_unittest.cc
@@ -6,6 +6,7 @@
#include <functional>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/files/scoped_temp_dir.h"
@@ -267,10 +268,9 @@ class FileMetricsProviderTest : public testing::TestWithParam<bool> {
};
// Run all test cases with both small and large files.
-INSTANTIATE_TEST_CASE_P(SmallAndLargeFiles,
- FileMetricsProviderTest,
- testing::Bool());
-
+INSTANTIATE_TEST_SUITE_P(SmallAndLargeFiles,
+ FileMetricsProviderTest,
+ testing::Bool());
TEST_P(FileMetricsProviderTest, AccessMetrics) {
ASSERT_FALSE(PathExists(metrics_file()));
diff --git a/chromium/components/metrics/legacy_call_stack_profile_builder.cc b/chromium/components/metrics/legacy_call_stack_profile_builder.cc
deleted file mode 100644
index e9acf09977d..00000000000
--- a/chromium/components/metrics/legacy_call_stack_profile_builder.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/metrics/legacy_call_stack_profile_builder.h"
-
-#include <string>
-#include <utility>
-
-#include "base/atomicops.h"
-#include "base/files/file_path.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/no_destructor.h"
-#include "base/stl_util.h"
-#include "components/metrics/call_stack_profile_encoding.h"
-
-namespace metrics {
-
-namespace {
-
-// Only used by child processes.
-base::LazyInstance<ChildCallStackProfileCollector>::Leaky
- g_child_call_stack_profile_collector = LAZY_INSTANCE_INITIALIZER;
-
-base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>&
-GetBrowserProcessReceiverCallbackInstance() {
- static base::NoDestructor<
- base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>>
- instance;
- return *instance;
-}
-
-// Identifies an unknown module.
-const size_t kUnknownModuleIndex = static_cast<size_t>(-1);
-
-// This global variables holds the current system state and is recorded with
-// every captured sample, done on a separate thread which is why updates to
-// this must be atomic. A PostTask to move the the updates to that thread
-// would skew the timing and a lock could result in deadlock if the thread
-// making a change was also being profiled and got stopped.
-static base::subtle::Atomic32 g_process_milestones = 0;
-
-void ChangeAtomicFlags(base::subtle::Atomic32* flags,
- base::subtle::Atomic32 set,
- base::subtle::Atomic32 clear) {
- DCHECK(set != 0 || clear != 0);
- DCHECK_EQ(0, set & clear);
-
- base::subtle::Atomic32 bits = base::subtle::NoBarrier_Load(flags);
- while (true) {
- base::subtle::Atomic32 existing = base::subtle::NoBarrier_CompareAndSwap(
- flags, bits, (bits | set) & ~clear);
- if (existing == bits)
- break;
- bits = existing;
- }
-}
-
-// Provide a mapping from the C++ "enum" definition of various process mile-
-// stones to the equivalent protobuf "enum" definition. This table-lookup
-// conversion allows for the implementation to evolve and still be compatible
-// with the protobuf -- even if there are ever more than 32 defined proto
-// values, though never more than 32 could be in-use in a given C++ version
-// of the code.
-const ProcessPhase
- kProtoPhases[LegacyCallStackProfileBuilder::MILESTONES_MAX_VALUE] = {
- ProcessPhase::MAIN_LOOP_START,
- ProcessPhase::MAIN_NAVIGATION_START,
- ProcessPhase::MAIN_NAVIGATION_FINISHED,
- ProcessPhase::FIRST_NONEMPTY_PAINT,
-
- ProcessPhase::SHUTDOWN_START,
-};
-
-// These functions are used to encode protobufs. --------------------------
-
-// The protobuf expects the MD5 checksum prefix of the module name.
-uint64_t HashModuleFilename(const base::FilePath& filename) {
- const base::FilePath::StringType basename = filename.BaseName().value();
- // Copy the bytes in basename into a string buffer.
- size_t basename_length_in_bytes =
- basename.size() * sizeof(base::FilePath::CharType);
- std::string name_bytes(basename_length_in_bytes, '\0');
- memcpy(&name_bytes[0], &basename[0], basename_length_in_bytes);
- return base::HashMetricName(name_bytes);
-}
-
-// Transcode |sample| into |proto_sample|, using base addresses in |modules| to
-// compute module instruction pointer offsets.
-void CopySampleToProto(const LegacyCallStackProfileBuilder::Sample& sample,
- const std::vector<base::ModuleCache::Module>& modules,
- CallStackProfile::Sample* proto_sample) {
- for (const auto& frame : sample.frames) {
- CallStackProfile::Location* location = proto_sample->add_frame();
- // A frame may not have a valid module. If so, we can't compute the
- // instruction pointer offset, and we don't want to send bare pointers,
- // so leave call_stack_entry empty.
- if (frame.module_index == kUnknownModuleIndex)
- continue;
- int64_t module_offset =
- reinterpret_cast<const char*>(frame.instruction_pointer) -
- reinterpret_cast<const char*>(modules[frame.module_index].base_address);
- DCHECK_GE(module_offset, 0);
- location->set_address(static_cast<uint64_t>(module_offset));
- location->set_module_id_index(frame.module_index);
- }
-}
-
-// Transcode Sample annotations into protobuf fields. The C++ code uses a
-// bit- field with each bit corresponding to an entry in an enumeration
-// while the protobuf uses a repeated field of individual values. Conversion
-// tables allow for arbitrary mapping, though no more than 32 in any given
-// version of the code.
-void CopyAnnotationsToProto(uint32_t new_milestones,
- CallStackProfile::Sample* sample_proto) {
- for (size_t bit = 0; new_milestones != 0 && bit < sizeof(new_milestones) * 8;
- ++bit) {
- const uint32_t flag = 1U << bit;
- if (new_milestones & flag) {
- if (bit >= base::size(kProtoPhases)) {
- NOTREACHED();
- continue;
- }
- sample_proto->add_process_phase(kProtoPhases[bit]);
- new_milestones ^= flag; // Bit is set so XOR will clear it.
- }
- }
-}
-
-} // namespace
-
-// LegacyCallStackProfileBuilder::Frame
-// ---------------------------------------------
-
-LegacyCallStackProfileBuilder::Frame::Frame(uintptr_t instruction_pointer,
- size_t module_index)
- : instruction_pointer(instruction_pointer), module_index(module_index) {}
-
-LegacyCallStackProfileBuilder::Frame::~Frame() = default;
-
-LegacyCallStackProfileBuilder::Frame::Frame()
- : instruction_pointer(0), module_index(kUnknownModuleIndex) {}
-
-// LegacyCallStackProfileBuilder::Sample
-// --------------------------------------------
-
-LegacyCallStackProfileBuilder::Sample::Sample() = default;
-
-LegacyCallStackProfileBuilder::Sample::Sample(const Sample& sample) = default;
-
-LegacyCallStackProfileBuilder::Sample::~Sample() = default;
-
-LegacyCallStackProfileBuilder::Sample::Sample(const Frame& frame) {
- frames.push_back(std::move(frame));
-}
-
-LegacyCallStackProfileBuilder::Sample::Sample(const std::vector<Frame>& frames)
- : frames(frames) {}
-
-LegacyCallStackProfileBuilder::LegacyCallStackProfileBuilder(
- const CallStackProfileParams& profile_params,
- base::OnceClosure completed_callback)
- : process_milestones_(0),
- profile_params_(profile_params),
- profile_start_time_(base::TimeTicks::Now()) {
- completed_callback_ = std::move(completed_callback);
-}
-
-LegacyCallStackProfileBuilder::~LegacyCallStackProfileBuilder() = default;
-
-void LegacyCallStackProfileBuilder::RecordMetadata() {
- // The code inside this method must not do anything that could acquire a
- // mutex, including allocating memory (which includes LOG messages) because
- // that mutex could be held by a stopped thread, thus resulting in deadlock.
- process_milestones_ = base::subtle::NoBarrier_Load(&g_process_milestones);
-}
-
-void LegacyCallStackProfileBuilder::OnSampleCompleted(
- std::vector<base::StackSamplingProfiler::Frame> frames) {
- OnSampleCompleted(std::move(frames), 1);
-}
-
-void LegacyCallStackProfileBuilder::OnSampleCompleted(
- std::vector<base::StackSamplingProfiler::Frame> frames,
- size_t count) {
- Sample sample;
- sample.process_milestones = process_milestones_;
-
- // Assemble sample_ from |frames| first.
- for (const auto& frame : frames) {
- const base::ModuleCache::Module& module(frame.module);
- if (!module.is_valid) {
- sample.frames.emplace_back(frame.instruction_pointer,
- kUnknownModuleIndex);
- continue;
- }
-
- // Dedup modules and cache them in modules_.
- auto loc = module_index_.find(module.base_address);
- if (loc == module_index_.end()) {
- modules_.push_back(module);
- size_t index = modules_.size() - 1;
- loc = module_index_.insert(std::make_pair(module.base_address, index))
- .first;
- }
- sample.frames.emplace_back(frame.instruction_pointer, loc->second);
- }
-
- // Write CallStackProfile::Sample protocol buffer message based on sample.
- int existing_sample_index = -1;
- auto location = sample_index_.find(sample);
- if (location != sample_index_.end())
- existing_sample_index = location->second;
-
- if (existing_sample_index != -1) {
- CallStackProfile::Sample* sample_proto =
- proto_profile_.mutable_deprecated_sample(existing_sample_index);
- sample_proto->set_count(sample_proto->count() + count);
- return;
- }
-
- CallStackProfile::Sample* sample_proto =
- proto_profile_.add_deprecated_sample();
- CopySampleToProto(sample, modules_, sample_proto);
- sample_proto->set_count(count);
- CopyAnnotationsToProto(sample.process_milestones & ~milestones_,
- sample_proto);
- milestones_ = sample.process_milestones;
-
- sample_index_.insert(std::make_pair(
- std::move(sample),
- static_cast<int>(proto_profile_.deprecated_sample_size()) - 1));
-}
-
-// Build a SampledProfile in the protocol buffer message format from the
-// collected sampling data. The message is then passed to
-// CallStackProfileMetricsProvider or ChildCallStackProfileCollector.
-
-// A SampledProfile message (third_party/metrics_proto/sampled_profile.proto)
-// contains a CallStackProfile message
-// (third_party/metrics_proto/call_stack_profile.proto) and associated profile
-// parameters (process/thread/trigger event). A CallStackProfile message
-// contains a set of Sample messages and ModuleIdentifier messages, and other
-// sampling information. One Sample corresponds to a single recorded stack, and
-// the ModuleIdentifiers record those modules associated with the recorded stack
-// frames.
-void LegacyCallStackProfileBuilder::OnProfileCompleted(
- base::TimeDelta profile_duration,
- base::TimeDelta sampling_period) {
- proto_profile_.set_profile_duration_ms(profile_duration.InMilliseconds());
- proto_profile_.set_sampling_period_ms(sampling_period.InMilliseconds());
-
- for (const auto& module : modules_) {
- CallStackProfile::ModuleIdentifier* module_id =
- proto_profile_.add_module_id();
- module_id->set_build_id(module.id);
- module_id->set_name_md5_prefix(HashModuleFilename(module.filename));
- }
-
- // Clear the caches etc.
- modules_.clear();
- module_index_.clear();
- sample_index_.clear();
-
- // Assemble the SampledProfile protocol buffer message and run the associated
- // callback to pass it.
- SampledProfile sampled_profile;
- CallStackProfile* proto_profile =
- sampled_profile.mutable_call_stack_profile();
- *proto_profile = std::move(proto_profile_);
-
- sampled_profile.set_process(
- ToExecutionContextProcess(profile_params_.process));
- sampled_profile.set_thread(ToExecutionContextThread(profile_params_.thread));
- sampled_profile.set_trigger_event(
- ToSampledProfileTriggerEvent(profile_params_.trigger));
-
- PassProfilesToMetricsProvider(std::move(sampled_profile));
-
- // Run the completed callback if there is one.
- if (!completed_callback_.is_null())
- std::move(completed_callback_).Run();
-}
-
-// static
-void LegacyCallStackProfileBuilder::SetBrowserProcessReceiverCallback(
- const base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>&
- callback) {
- GetBrowserProcessReceiverCallbackInstance() = callback;
-}
-
-void LegacyCallStackProfileBuilder::PassProfilesToMetricsProvider(
- SampledProfile sampled_profile) {
- if (profile_params_.process == CallStackProfileParams::BROWSER_PROCESS) {
- GetBrowserProcessReceiverCallbackInstance().Run(profile_start_time_,
- std::move(sampled_profile));
- } else {
- g_child_call_stack_profile_collector.Get()
- .ChildCallStackProfileCollector::Collect(profile_start_time_,
- std::move(sampled_profile));
- }
-}
-
-// static
-void LegacyCallStackProfileBuilder::SetProcessMilestone(int milestone) {
- DCHECK_LE(0, milestone);
- DCHECK_GT(static_cast<int>(sizeof(g_process_milestones) * 8), milestone);
- DCHECK_EQ(0, base::subtle::NoBarrier_Load(&g_process_milestones) &
- (1 << milestone));
- ChangeAtomicFlags(&g_process_milestones, 1 << milestone, 0);
-}
-
-// static
-void LegacyCallStackProfileBuilder::SetParentProfileCollectorForChildProcess(
- metrics::mojom::CallStackProfileCollectorPtr browser_interface) {
- g_child_call_stack_profile_collector.Get().SetParentProfileCollector(
- std::move(browser_interface));
-}
-
-// These operators permit types to be compared and used in a map of Samples.
-
-bool operator==(const LegacyCallStackProfileBuilder::Sample& a,
- const LegacyCallStackProfileBuilder::Sample& b) {
- return a.process_milestones == b.process_milestones && a.frames == b.frames;
-}
-
-bool operator!=(const LegacyCallStackProfileBuilder::Sample& a,
- const LegacyCallStackProfileBuilder::Sample& b) {
- return !(a == b);
-}
-
-bool operator<(const LegacyCallStackProfileBuilder::Sample& a,
- const LegacyCallStackProfileBuilder::Sample& b) {
- if (a.process_milestones != b.process_milestones)
- return a.process_milestones < b.process_milestones;
-
- return a.frames < b.frames;
-}
-
-bool operator==(const LegacyCallStackProfileBuilder::Frame& a,
- const LegacyCallStackProfileBuilder::Frame& b) {
- return a.instruction_pointer == b.instruction_pointer &&
- a.module_index == b.module_index;
-}
-
-bool operator<(const LegacyCallStackProfileBuilder::Frame& a,
- const LegacyCallStackProfileBuilder::Frame& b) {
- if (a.module_index != b.module_index)
- return a.module_index < b.module_index;
-
- return a.instruction_pointer < b.instruction_pointer;
-}
-
-} // namespace metrics
diff --git a/chromium/components/metrics/legacy_call_stack_profile_builder.h b/chromium/components/metrics/legacy_call_stack_profile_builder.h
deleted file mode 100644
index 869569bf35f..00000000000
--- a/chromium/components/metrics/legacy_call_stack_profile_builder.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
-#define COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
-
-#include <map>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/profiler/stack_sampling_profiler.h"
-#include "base/sampling_heap_profiler/module_cache.h"
-#include "base/time/time.h"
-#include "components/metrics/call_stack_profile_params.h"
-#include "components/metrics/child_call_stack_profile_collector.h"
-#include "third_party/metrics_proto/sampled_profile.pb.h"
-
-namespace metrics {
-
-// An instance of the class is meant to be passed to base::StackSamplingProfiler
-// to collect profiles. The profiles collected are uploaded via the metrics log.
-//
-// This uses the legacy Sample encoding rather than the new StackSample
-// encoding.
-class LegacyCallStackProfileBuilder
- : public base::StackSamplingProfiler::ProfileBuilder {
- public:
- // Frame represents an individual sampled stack frame with module information.
- struct Frame {
- Frame(uintptr_t instruction_pointer, size_t module_index);
- ~Frame();
-
- // Default constructor to satisfy IPC macros. Do not use explicitly.
- Frame();
-
- // The sampled instruction pointer within the function.
- uintptr_t instruction_pointer;
-
- // Index of the module in the associated vector of mofules. We don't
- // represent module state directly here to save space.
- size_t module_index;
- };
-
- // Sample represents a set of stack frames with some extra information.
- struct Sample {
- Sample();
- Sample(const Sample& sample);
- ~Sample();
-
- // These constructors are used only during testing.
- Sample(const Frame& frame);
- Sample(const std::vector<Frame>& frames);
-
- // The entire stack frame when the sample is taken.
- std::vector<Frame> frames;
-
- // A bit-field indicating which process milestones have passed. This can be
- // used to tell where in the process lifetime the samples are taken. Just
- // as a "lifetime" can only move forward, these bits mark the milestones of
- // the processes life as they occur. Bits can be set but never reset. The
- // actual definition of the individual bits is left to the user of this
- // module.
- uint32_t process_milestones = 0;
- };
-
- // These milestones of a process lifetime can be passed as process "mile-
- // stones" to LegacyCallStackProfileBuilder::SetProcessMilestone(). Be sure to
- // update the translation constants at the top of the .cc file when this is
- // changed.
- enum Milestones : int {
- MAIN_LOOP_START,
- MAIN_NAVIGATION_START,
- MAIN_NAVIGATION_FINISHED,
- FIRST_NONEMPTY_PAINT,
-
- SHUTDOWN_START,
-
- MILESTONES_MAX_VALUE
- };
-
- // |completed_callback| is made when sampling a profile completes. Other
- // threads, including the UI thread, may block on callback completion so this
- // should run as quickly as possible.
- //
- // IMPORTANT NOTE: The callback is invoked on a thread the profiler
- // constructs, rather than on the thread used to construct the profiler, and
- // thus the callback must be callable on any thread.
- explicit LegacyCallStackProfileBuilder(
- const CallStackProfileParams& profile_params,
- base::OnceClosure completed_callback = base::OnceClosure());
-
- ~LegacyCallStackProfileBuilder() override;
-
- // base::StackSamplingProfiler::ProfileBuilder:
- void RecordMetadata() override;
- void OnSampleCompleted(
- std::vector<base::StackSamplingProfiler::Frame> frames) override;
- void OnProfileCompleted(base::TimeDelta profile_duration,
- base::TimeDelta sampling_period) override;
-
- // The function is used by sampling heap profiler. Its samples already come
- // with different counts.
- void OnSampleCompleted(std::vector<base::StackSamplingProfiler::Frame> frames,
- size_t count);
-
- // Sets the callback to use for reporting browser process profiles. This
- // indirection is required to avoid a dependency on unnecessary metrics code
- // in child processes.
- static void SetBrowserProcessReceiverCallback(
- const base::RepeatingCallback<void(base::TimeTicks, SampledProfile)>&
- callback);
-
- // Sets the current system state that is recorded with each captured stack
- // frame. This is thread-safe so can be called from anywhere. The parameter
- // value should be from an enumeration of the appropriate type with values
- // ranging from 0 to 31, inclusive. This sets bits within Sample field of
- // |process_milestones|. The actual meanings of these bits are defined
- // (globally) by the caller(s).
- static void SetProcessMilestone(int milestone);
-
- // Sets the CallStackProfileCollector interface from |browser_interface|.
- // This function must be called within child processes.
- static void SetParentProfileCollectorForChildProcess(
- metrics::mojom::CallStackProfileCollectorPtr browser_interface);
-
- protected:
- // Test seam.
- virtual void PassProfilesToMetricsProvider(SampledProfile sampled_profile);
-
- private:
- // The collected stack samples in proto buffer message format.
- CallStackProfile proto_profile_;
-
- // The process milestones to use for the next sample.
- uint32_t process_milestones_;
-
- // The indexes of samples, indexed by the sample.
- std::map<Sample, int> sample_index_;
-
- // The indexes of modules, indexed by module's base_address.
- std::map<uintptr_t, size_t> module_index_;
-
- // The distinct modules in the current profile.
- std::vector<base::ModuleCache::Module> modules_;
-
- // The process milestones of a previous sample.
- uint32_t milestones_ = 0;
-
- // Callback made when sampling a profile completes.
- base::OnceClosure completed_callback_;
-
- // The parameters associated with the sampled profile.
- const CallStackProfileParams profile_params_;
-
- // The start time of a profile collection.
- const base::TimeTicks profile_start_time_;
-
- DISALLOW_COPY_AND_ASSIGN(LegacyCallStackProfileBuilder);
-};
-
-} // namespace metrics
-
-#endif // COMPONENTS_METRICS_LEGACY_CALL_STACK_PROFILE_BUILDER_H_
diff --git a/chromium/components/metrics/legacy_call_stack_profile_builder_unittest.cc b/chromium/components/metrics/legacy_call_stack_profile_builder_unittest.cc
deleted file mode 100644
index b713eb934d1..00000000000
--- a/chromium/components/metrics/legacy_call_stack_profile_builder_unittest.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/metrics/legacy_call_stack_profile_builder.h"
-
-#include "base/files/file_path.h"
-#include "base/sampling_heap_profiler/module_cache.h"
-#include "base/test/bind_test_util.h"
-#include "base/test/mock_callback.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "components/metrics/call_stack_profile_params.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/metrics_proto/sampled_profile.pb.h"
-
-using Frame = base::StackSamplingProfiler::Frame;
-using Module = base::ModuleCache::Module;
-
-namespace metrics {
-
-namespace {
-
-constexpr CallStackProfileParams kProfileParams = {
- CallStackProfileParams::BROWSER_PROCESS,
- CallStackProfileParams::MAIN_THREAD,
- CallStackProfileParams::PROCESS_STARTUP};
-
-class TestingLegacyCallStackProfileBuilder
- : public LegacyCallStackProfileBuilder {
- public:
- TestingLegacyCallStackProfileBuilder(
- const CallStackProfileParams& profile_params,
- base::OnceClosure completed_callback = base::OnceClosure());
-
- ~TestingLegacyCallStackProfileBuilder() override;
-
- const SampledProfile& sampled_profile() { return sampled_profile_; }
-
- protected:
- // Overridden for testing.
- void PassProfilesToMetricsProvider(SampledProfile sampled_profile) override;
-
- private:
- // The completed profile.
- SampledProfile sampled_profile_;
-};
-
-TestingLegacyCallStackProfileBuilder::TestingLegacyCallStackProfileBuilder(
- const CallStackProfileParams& profile_params,
- base::OnceClosure completed_callback)
- : LegacyCallStackProfileBuilder(profile_params,
- std::move(completed_callback)) {}
-
-TestingLegacyCallStackProfileBuilder::~TestingLegacyCallStackProfileBuilder() =
- default;
-
-void TestingLegacyCallStackProfileBuilder::PassProfilesToMetricsProvider(
- SampledProfile sampled_profile) {
- sampled_profile_ = std::move(sampled_profile);
-}
-
-} // namespace
-
-TEST(LegacyCallStackProfileBuilderTest, SetProcessMilestone) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
- // The default milestone is 0.
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(std::vector<Frame>());
-
- LegacyCallStackProfileBuilder::SetProcessMilestone(1);
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(std::vector<Frame>());
-
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- const CallStackProfile& profile = proto.call_stack_profile();
-
- ASSERT_EQ(2, profile.deprecated_sample_size());
-
- uint32_t process_milestones = 0;
- for (int i = 0; i < profile.deprecated_sample(0).process_phase().size(); ++i)
- process_milestones |=
- 1U << profile.deprecated_sample(0).process_phase().Get(i);
- EXPECT_EQ(0U, process_milestones);
-
- process_milestones = 0;
- for (int i = 0; i < profile.deprecated_sample(1).process_phase().size(); ++i)
- process_milestones |=
- 1U << profile.deprecated_sample(1).process_phase().Get(i);
- EXPECT_EQ(1U << 1, process_milestones);
-}
-
-TEST(LegacyCallStackProfileBuilderTest, ProfilingCompleted) {
- // Set up a mock completed callback which will be run once.
- base::MockCallback<base::OnceClosure> mock_closure;
- EXPECT_CALL(mock_closure, Run()).Times(1);
-
- auto profile_builder = std::make_unique<TestingLegacyCallStackProfileBuilder>(
- kProfileParams, mock_closure.Get());
-
-#if defined(OS_WIN)
- uint64_t module_md5 = 0x46C3E4166659AC02ULL;
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- uint64_t module_md5 = 0x554838A8451AC36CULL;
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
-
- const uintptr_t module_base_address3 = 0x1010;
- Module module3 = {module_base_address3, "3", module_path};
- Frame frame3 = {module_base_address3 + 0x10, module3};
-
- std::vector<Frame> frames1 = {frame1, frame2};
- std::vector<Frame> frames2 = {frame3};
-
- profile_builder->OnSampleCompleted(frames1);
- profile_builder->OnSampleCompleted(frames2);
- profile_builder->OnProfileCompleted(base::TimeDelta::FromMilliseconds(500),
- base::TimeDelta::FromMilliseconds(100));
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_process());
- ASSERT_EQ(BROWSER_PROCESS, proto.process());
- ASSERT_TRUE(proto.has_thread());
- ASSERT_EQ(MAIN_THREAD, proto.thread());
- ASSERT_TRUE(proto.has_trigger_event());
- ASSERT_EQ(SampledProfile::PROCESS_STARTUP, proto.trigger_event());
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- const CallStackProfile& profile = proto.call_stack_profile();
-
- ASSERT_EQ(2, profile.deprecated_sample_size());
- ASSERT_EQ(2, profile.deprecated_sample(0).frame_size());
- ASSERT_TRUE(profile.deprecated_sample(0).frame(0).has_module_id_index());
- EXPECT_EQ(0, profile.deprecated_sample(0).frame(0).module_id_index());
- ASSERT_TRUE(profile.deprecated_sample(0).frame(1).has_module_id_index());
- EXPECT_EQ(1, profile.deprecated_sample(0).frame(1).module_id_index());
- ASSERT_EQ(1, profile.deprecated_sample(1).frame_size());
- ASSERT_TRUE(profile.deprecated_sample(1).frame(0).has_module_id_index());
- EXPECT_EQ(2, profile.deprecated_sample(1).frame(0).module_id_index());
-
- ASSERT_EQ(3, profile.module_id().size());
- ASSERT_TRUE(profile.module_id(0).has_build_id());
- ASSERT_EQ("1", profile.module_id(0).build_id());
- ASSERT_TRUE(profile.module_id(0).has_name_md5_prefix());
- ASSERT_EQ(module_md5, profile.module_id(0).name_md5_prefix());
- ASSERT_TRUE(profile.module_id(1).has_build_id());
- ASSERT_EQ("2", profile.module_id(1).build_id());
- ASSERT_TRUE(profile.module_id(1).has_name_md5_prefix());
- ASSERT_EQ(module_md5, profile.module_id(1).name_md5_prefix());
- ASSERT_TRUE(profile.module_id(2).has_build_id());
- ASSERT_EQ("3", profile.module_id(2).build_id());
- ASSERT_TRUE(profile.module_id(2).has_name_md5_prefix());
- ASSERT_EQ(module_md5, profile.module_id(2).name_md5_prefix());
-
- ASSERT_TRUE(profile.has_profile_duration_ms());
- EXPECT_EQ(500, profile.profile_duration_ms());
- ASSERT_TRUE(profile.has_sampling_period_ms());
- EXPECT_EQ(100, profile.sampling_period_ms());
-}
-
-TEST(LegacyCallStackProfileBuilderTest, SamplesDeduped) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
-
- std::vector<Frame> frames = {frame1, frame2};
-
- // Two samples are completed with the same frames. They also have the same
- // process milestone therefore they are deduped to one.
- LegacyCallStackProfileBuilder::SetProcessMilestone(0);
-
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames, 42);
-
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames);
-
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_process());
- ASSERT_EQ(BROWSER_PROCESS, proto.process());
- ASSERT_TRUE(proto.has_thread());
- ASSERT_EQ(MAIN_THREAD, proto.thread());
- ASSERT_TRUE(proto.has_trigger_event());
- ASSERT_EQ(SampledProfile::PROCESS_STARTUP, proto.trigger_event());
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- ASSERT_EQ(1, proto.call_stack_profile().deprecated_sample_size());
- ASSERT_EQ(43, proto.call_stack_profile().deprecated_sample(0).count());
- EXPECT_EQ(2, proto.call_stack_profile().deprecated_sample(0).frame_size());
-}
-
-TEST(LegacyCallStackProfileBuilderTest, SamplesNotDeduped) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
-
- std::vector<Frame> frames = {frame1, frame2};
-
- // Two samples are completed with the same frames but different process
- // milestones. They are considered as different samples threfore not deduped.
- LegacyCallStackProfileBuilder::SetProcessMilestone(2);
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames);
-
- LegacyCallStackProfileBuilder::SetProcessMilestone(4);
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames);
-
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_process());
- ASSERT_EQ(BROWSER_PROCESS, proto.process());
- ASSERT_TRUE(proto.has_thread());
- ASSERT_EQ(MAIN_THREAD, proto.thread());
- ASSERT_TRUE(proto.has_trigger_event());
- ASSERT_EQ(SampledProfile::PROCESS_STARTUP, proto.trigger_event());
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- ASSERT_EQ(2, proto.call_stack_profile().deprecated_sample_size());
- EXPECT_EQ(2, proto.call_stack_profile().deprecated_sample(0).frame_size());
- EXPECT_EQ(2, proto.call_stack_profile().deprecated_sample(1).frame_size());
-}
-
-TEST(LegacyCallStackProfileBuilderTest, SamplesDedupedAndNotDeduped) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
-#if defined(OS_WIN)
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- const uintptr_t module_base_address1 = 0x1000;
- Module module1 = {module_base_address1, "1", module_path};
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x20, module2};
-
- std::vector<Frame> frames1 = {frame1, frame2};
- std::vector<Frame> frames2 = {frame2, frame1};
-
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames1, 42);
-
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames1);
-
- profile_builder->RecordMetadata();
- profile_builder->OnSampleCompleted(frames2);
-
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- EXPECT_TRUE(proto.has_process());
- EXPECT_EQ(BROWSER_PROCESS, proto.process());
- EXPECT_TRUE(proto.has_thread());
- EXPECT_EQ(MAIN_THREAD, proto.thread());
- EXPECT_TRUE(proto.has_trigger_event());
- EXPECT_EQ(SampledProfile::PROCESS_STARTUP, proto.trigger_event());
-
- EXPECT_TRUE(proto.has_call_stack_profile());
- ASSERT_EQ(2, proto.call_stack_profile().deprecated_sample_size());
- EXPECT_EQ(43, proto.call_stack_profile().deprecated_sample(0).count());
- ASSERT_EQ(2, proto.call_stack_profile().deprecated_sample(0).frame_size());
- EXPECT_EQ(0x10u,
- proto.call_stack_profile().deprecated_sample(0).frame(0).address());
- EXPECT_EQ(0x20u,
- proto.call_stack_profile().deprecated_sample(0).frame(1).address());
- ASSERT_EQ(2, proto.call_stack_profile().deprecated_sample(1).frame_size());
- EXPECT_EQ(1, proto.call_stack_profile().deprecated_sample(1).count());
- EXPECT_EQ(0x20u,
- proto.call_stack_profile().deprecated_sample(1).frame(0).address());
- EXPECT_EQ(0x10u,
- proto.call_stack_profile().deprecated_sample(1).frame(1).address());
-}
-
-TEST(LegacyCallStackProfileBuilderTest, Modules) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
- const uintptr_t module_base_address1 = 0x1000;
- Module module1; // module1 has no information hence invalid.
- Frame frame1 = {module_base_address1 + 0x10, module1};
-
- const uintptr_t module_base_address2 = 0x1100;
-#if defined(OS_WIN)
- uint64_t module_md5 = 0x46C3E4166659AC02ULL;
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- uint64_t module_md5 = 0x554838A8451AC36CULL;
- base::FilePath module_path("/some/path/to/chrome");
-#endif
- Module module2 = {module_base_address2, "2", module_path};
- Frame frame2 = {module_base_address2 + 0x10, module2};
-
- std::vector<Frame> frames = {frame1, frame2};
-
- profile_builder->OnSampleCompleted(frames);
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- const CallStackProfile& profile = proto.call_stack_profile();
-
- ASSERT_EQ(1, profile.deprecated_sample_size());
- ASSERT_EQ(2, profile.deprecated_sample(0).frame_size());
-
- ASSERT_FALSE(profile.deprecated_sample(0).frame(0).has_module_id_index());
- ASSERT_FALSE(profile.deprecated_sample(0).frame(0).has_address());
-
- ASSERT_TRUE(profile.deprecated_sample(0).frame(1).has_module_id_index());
- EXPECT_EQ(0, profile.deprecated_sample(0).frame(1).module_id_index());
- ASSERT_TRUE(profile.deprecated_sample(0).frame(1).has_address());
- EXPECT_EQ(0x10ULL, profile.deprecated_sample(0).frame(1).address());
-
- ASSERT_EQ(1, profile.module_id().size());
- ASSERT_TRUE(profile.module_id(0).has_build_id());
- ASSERT_EQ("2", profile.module_id(0).build_id());
- ASSERT_TRUE(profile.module_id(0).has_name_md5_prefix());
- ASSERT_EQ(module_md5, profile.module_id(0).name_md5_prefix());
-}
-
-TEST(LegacyCallStackProfileBuilderTest, DedupModules) {
- auto profile_builder =
- std::make_unique<TestingLegacyCallStackProfileBuilder>(kProfileParams);
-
- const uintptr_t module_base_address = 0x1000;
-
-#if defined(OS_WIN)
- uint64_t module_md5 = 0x46C3E4166659AC02ULL;
- base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe");
-#else
- uint64_t module_md5 = 0x554838A8451AC36CULL;
- base::FilePath module_path("/some/path/to/chrome");
-#endif
-
- Module module1 = {module_base_address, "1", module_path};
- Frame frame1 = {module_base_address + 0x10, module1};
-
- Module module2 = {module_base_address, "1", module_path};
- Frame frame2 = {module_base_address + 0x20, module2};
-
- std::vector<Frame> frames = {frame1, frame2};
-
- profile_builder->OnSampleCompleted(frames);
- profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
-
- const SampledProfile& proto = profile_builder->sampled_profile();
-
- ASSERT_TRUE(proto.has_call_stack_profile());
- const CallStackProfile& profile = proto.call_stack_profile();
-
- ASSERT_EQ(1, profile.deprecated_sample_size());
- ASSERT_EQ(2, profile.deprecated_sample(0).frame_size());
-
- // Since module1 and module2 have the same base address, they are considered
- // the same module and therefore deduped.
- ASSERT_TRUE(profile.deprecated_sample(0).frame(0).has_module_id_index());
- EXPECT_EQ(0, profile.deprecated_sample(0).frame(0).module_id_index());
- ASSERT_TRUE(profile.deprecated_sample(0).frame(0).has_address());
- EXPECT_EQ(0x10ULL, profile.deprecated_sample(0).frame(0).address());
-
- ASSERT_TRUE(profile.deprecated_sample(0).frame(1).has_module_id_index());
- EXPECT_EQ(0, profile.deprecated_sample(0).frame(1).module_id_index());
- ASSERT_TRUE(profile.deprecated_sample(0).frame(1).has_address());
- EXPECT_EQ(0x20ULL, profile.deprecated_sample(0).frame(1).address());
-
- ASSERT_EQ(1, profile.module_id().size());
- ASSERT_TRUE(profile.module_id(0).has_build_id());
- ASSERT_EQ("1", profile.module_id(0).build_id());
- ASSERT_TRUE(profile.module_id(0).has_name_md5_prefix());
- ASSERT_EQ(module_md5, profile.module_id(0).name_md5_prefix());
-}
-
-} // namespace metrics
diff --git a/chromium/components/metrics/machine_id_provider_win.cc b/chromium/components/metrics/machine_id_provider_win.cc
index eb7b0d7e8fd..31fe9b46f1f 100644
--- a/chromium/components/metrics/machine_id_provider_win.cc
+++ b/chromium/components/metrics/machine_id_provider_win.cc
@@ -25,7 +25,8 @@ bool MachineIdProvider::HasId() {
// is running from.
// static
std::string MachineIdProvider::GetMachineId() {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
// Use the program's path to get the drive used for the machine id. This means
// that whenever the underlying drive changes, it's considered a new machine.
diff --git a/chromium/components/metrics/metrics_reporting_service.cc b/chromium/components/metrics/metrics_reporting_service.cc
index 56d763f58a2..2df00131c13 100644
--- a/chromium/components/metrics/metrics_reporting_service.cc
+++ b/chromium/components/metrics/metrics_reporting_service.cc
@@ -46,11 +46,11 @@ LogStore* MetricsReportingService::log_store() {
return &metrics_log_store_;
}
-std::string MetricsReportingService::GetUploadUrl() const {
+GURL MetricsReportingService::GetUploadUrl() const {
return client()->GetMetricsServerUrl();
}
-std::string MetricsReportingService::GetInsecureUploadUrl() const {
+GURL MetricsReportingService::GetInsecureUploadUrl() const {
return client()->GetInsecureMetricsServerUrl();
}
diff --git a/chromium/components/metrics/metrics_reporting_service.h b/chromium/components/metrics/metrics_reporting_service.h
index 38961b27a39..3304b045583 100644
--- a/chromium/components/metrics/metrics_reporting_service.h
+++ b/chromium/components/metrics/metrics_reporting_service.h
@@ -46,8 +46,8 @@ class MetricsReportingService : public ReportingService {
private:
// ReportingService:
LogStore* log_store() override;
- std::string GetUploadUrl() const override;
- std::string GetInsecureUploadUrl() const override;
+ GURL GetUploadUrl() const override;
+ GURL GetInsecureUploadUrl() const override;
base::StringPiece upload_mime_type() const override;
MetricsLogUploader::MetricServiceType service_type() const override;
void LogActualUploadInterval(base::TimeDelta interval) override;
diff --git a/chromium/components/metrics/metrics_service.h b/chromium/components/metrics/metrics_service.h
index b5c435af844..a14b5380d2d 100644
--- a/chromium/components/metrics/metrics_service.h
+++ b/chromium/components/metrics/metrics_service.h
@@ -36,6 +36,8 @@
class PrefService;
class PrefRegistrySimple;
+FORWARD_DECLARE_TEST(ChromeMetricsServiceClientTest,
+ TestRegisterMetricsServiceProviders);
namespace base {
class HistogramSamples;
@@ -384,7 +386,8 @@ class MetricsService : public base::HistogramFlattener {
static ShutdownCleanliness clean_shutdown_status_;
FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, IsPluginProcess);
-
+ FRIEND_TEST_ALL_PREFIXES(::ChromeMetricsServiceClientTest,
+ TestRegisterMetricsServiceProviders);
SEQUENCE_CHECKER(sequence_checker_);
// Weak pointers factory used to post task on different threads. All weak
diff --git a/chromium/components/metrics/metrics_service_accessor.cc b/chromium/components/metrics/metrics_service_accessor.cc
index f00d2e8523f..6cfa202800a 100644
--- a/chromium/components/metrics/metrics_service_accessor.cc
+++ b/chromium/components/metrics/metrics_service_accessor.cc
@@ -17,12 +17,7 @@ namespace {
bool g_force_official_enabled_test = false;
bool IsMetricsReportingEnabledForOfficialBuild(PrefService* pref_service) {
- // In official builds, disable metrics when reporting field trials are
- // forced; otherwise, use the value of the user's preference to determine
- // whether to enable metrics reporting.
- return !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceFieldTrials) &&
- pref_service->GetBoolean(prefs::kMetricsReportingEnabled);
+ return pref_service->GetBoolean(prefs::kMetricsReportingEnabled);
}
} // namespace
diff --git a/chromium/components/metrics/metrics_service_client.cc b/chromium/components/metrics/metrics_service_client.cc
index 9719e20491a..a4e7bc0b0ab 100644
--- a/chromium/components/metrics/metrics_service_client.cc
+++ b/chromium/components/metrics/metrics_service_client.cc
@@ -31,12 +31,12 @@ bool MetricsServiceClient::IsUMACellularUploadLogicEnabled() {
return false;
}
-std::string MetricsServiceClient::GetMetricsServerUrl() {
- return kNewMetricsServerUrl;
+GURL MetricsServiceClient::GetMetricsServerUrl() {
+ return GURL(kNewMetricsServerUrl);
}
-std::string MetricsServiceClient::GetInsecureMetricsServerUrl() {
- return kNewMetricsServerUrlInsecure;
+GURL MetricsServiceClient::GetInsecureMetricsServerUrl() {
+ return GURL(kNewMetricsServerUrlInsecure);
}
bool MetricsServiceClient::SyncStateAllowsUkm() {
diff --git a/chromium/components/metrics/metrics_service_client.h b/chromium/components/metrics/metrics_service_client.h
index 621d2d596f6..91e11c71b95 100644
--- a/chromium/components/metrics/metrics_service_client.h
+++ b/chromium/components/metrics/metrics_service_client.h
@@ -16,6 +16,7 @@
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_reporting_default_state.h"
#include "third_party/metrics_proto/system_profile.pb.h"
+#include "url/gurl.h"
namespace base {
class FilePath;
@@ -84,16 +85,16 @@ class MetricsServiceClient {
const base::Closure& done_callback) = 0;
// Get the URL of the metrics server.
- virtual std::string GetMetricsServerUrl();
+ virtual GURL GetMetricsServerUrl();
// Get the fallback HTTP URL of the metrics server.
- virtual std::string GetInsecureMetricsServerUrl();
+ virtual GURL GetInsecureMetricsServerUrl();
// Creates a MetricsLogUploader with the specified parameters (see comments on
// MetricsLogUploader for details).
virtual std::unique_ptr<MetricsLogUploader> CreateUploader(
- base::StringPiece server_url,
- base::StringPiece insecure_server_url,
+ const GURL& server_url,
+ const GURL& insecure_server_url,
base::StringPiece mime_type,
metrics::MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete) = 0;
diff --git a/chromium/components/metrics/metrics_service_unittest.cc b/chromium/components/metrics/metrics_service_unittest.cc
index 320b2d3ee4e..bf84ff375d3 100644
--- a/chromium/components/metrics/metrics_service_unittest.cc
+++ b/chromium/components/metrics/metrics_service_unittest.cc
@@ -346,6 +346,7 @@ TEST_F(MetricsServiceTest, MetricsProvidersInitialized) {
}
TEST_F(MetricsServiceTest, SplitRotation) {
+ EnableMetricsReporting();
TestMetricsServiceClient client;
TestMetricsService service(GetMetricsStateManager(), &client,
GetLocalState());
@@ -396,6 +397,7 @@ TEST_F(MetricsServiceTest, SplitRotation) {
}
TEST_F(MetricsServiceTest, LastLiveTimestamp) {
+ EnableMetricsReporting();
TestMetricsServiceClient client;
TestMetricsService service(GetMetricsStateManager(), &client,
GetLocalState());
diff --git a/chromium/components/metrics/metrics_state_manager.cc b/chromium/components/metrics/metrics_state_manager.cc
index 1adb0203a7c..faad62736fd 100644
--- a/chromium/components/metrics/metrics_state_manager.cc
+++ b/chromium/components/metrics/metrics_state_manager.cc
@@ -144,9 +144,26 @@ MetricsStateManager::MetricsStateManager(
// Set the install date if this is our first run.
int64_t install_date = local_state_->GetInt64(prefs::kInstallDate);
- if (install_date == 0)
+ if (install_date == 0) {
local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
+#if !defined(OS_WIN)
+ // If this is a first run (no install date) and there's no client id, then
+ // generate a provisional client id now. This id will be used for field
+ // trial randomization on first run and will be promoted to become the
+ // client id if UMA is enabled during this session, via the logic in
+ // ForceClientIdCreation().
+ //
+ // Note: We don't do this on Windows because on Windows, there's no UMA
+ // checkbox on first run and instead it comes from the install page. So if
+ // UMA is not enabled at this point, it's unlikely it will be enabled in
+ // the same session since that requires the user to manually do that via
+ // settings page after they unchecked it on the download page.
+ if (client_id_.empty())
+ provisional_client_id_ = base::GenerateGUID();
+#endif // !defined(OS_WIN)
+ }
+
// Delete the cache used by CachingPermutedEntropyProvider, which was removed.
// TODO(crbug/912368): Remove this after it's been deleted from most installs.
local_state_->ClearPref(::variations::prefs::kVariationsPermutedEntropyCache);
@@ -174,6 +191,15 @@ int64_t MetricsStateManager::GetInstallDate() const {
}
void MetricsStateManager::ForceClientIdCreation() {
+ // TODO(asvitkine): Ideally, all tests would actually set up consent properly,
+ // so the command-line check wouldn't be needed here.
+ // Currently, kForceEnableMetricsReporting is used by Java UkmTest and
+ // kMetricsRecordingOnly is used by Chromedriver tests.
+ DCHECK(enabled_state_provider_->IsConsentGiven() ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceEnableMetricsReporting) ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kMetricsRecordingOnly));
{
std::string client_id_from_prefs =
local_state_->GetString(prefs::kMetricsClientID);
@@ -220,8 +246,16 @@ void MetricsStateManager::ForceClientIdCreation() {
return;
}
- // Failing attempts at getting an existing client ID, generate a new one.
- client_id_ = base::GenerateGUID();
+ // If we're here, there was no client ID yet (either in prefs or backup),
+ // so generate a new one. If there's a provisional client id (e.g. UMA
+ // was enabled as part of first run), promote that to the client id,
+ // otherwise (e.g. UMA enabled in a future session), generate a new one.
+ if (provisional_client_id_.empty()) {
+ client_id_ = base::GenerateGUID();
+ } else {
+ client_id_ = provisional_client_id_;
+ provisional_client_id_.clear();
+ }
local_state_->SetString(prefs::kMetricsClientID, client_id_);
// Record the timestamp of when the user opted in to UMA.
@@ -243,7 +277,8 @@ void MetricsStateManager::CheckForClonedInstall() {
std::unique_ptr<const base::FieldTrial::EntropyProvider>
MetricsStateManager::CreateDefaultEntropyProvider() {
- if (enabled_state_provider_->IsConsentGiven()) {
+ if (enabled_state_provider_->IsConsentGiven() ||
+ !provisional_client_id_.empty()) {
UpdateEntropySourceReturnedValue(ENTROPY_SOURCE_HIGH);
return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
new variations::SHA1EntropyProvider(GetHighEntropySource()));
@@ -319,11 +354,12 @@ std::unique_ptr<ClientInfo> MetricsStateManager::LoadClientInfo() {
}
std::string MetricsStateManager::GetHighEntropySource() {
- // This should only be called if UMA is enabled, and if UMA is enabled, then
- // the constructor should have loaded |client_id_|. The user shouldn't be able
- // to enable UMA between the constructor and calling this, because field trial
- // setup happens at Chrome initialization.
- DCHECK(!client_id_.empty());
+ // This should only be called if UMA is enabled or there's a provisional
+ // client id. If UMA is enabled, then the constructor should have loaded
+ // |client_id_|. The user shouldn't be able to enable UMA between the
+ // constructor and calling this, because field trial setup happens at Chrome
+ // initialization. Only one of these is expected to hold a value.
+ DCHECK(client_id_.empty() != provisional_client_id_.empty());
// For metrics reporting-enabled users, we combine the client ID and low
// entropy source to get the final entropy source.
@@ -341,7 +377,9 @@ std::string MetricsStateManager::GetHighEntropySource() {
if (low_entropy_source == kLowEntropySourceNotSet)
low_entropy_source = GetLowEntropySource();
- return client_id_ + base::IntToString(low_entropy_source);
+ const std::string& client_id_to_use =
+ (client_id_.empty() ? provisional_client_id_ : client_id_);
+ return client_id_to_use + base::NumberToString(low_entropy_source);
}
int MetricsStateManager::GetLowEntropySource() {
diff --git a/chromium/components/metrics/metrics_state_manager.h b/chromium/components/metrics/metrics_state_manager.h
index f5cfd995e28..8e57884d1ff 100644
--- a/chromium/components/metrics/metrics_state_manager.h
+++ b/chromium/components/metrics/metrics_state_manager.h
@@ -75,10 +75,11 @@ class MetricsStateManager final {
// Returns the preferred entropy provider used to seed persistent activities
// based on whether or not metrics reporting is permitted on this client.
//
- // If there's consent to report metrics, this method returns an entropy
- // provider that has a high source of entropy, partially based on the client
- // ID. Otherwise, it returns an entropy provider that is based on a low
- // entropy source.
+ // If there's consent to report metrics or this is the first run of Chrome,
+ // this method returns an entropy provider that has a high source of
+ // entropy, partially based on the client ID or provisional client ID.
+ // Otherwise, it returns an entropy provider that is based on a low entropy
+ // source.
std::unique_ptr<const base::FieldTrial::EntropyProvider>
CreateDefaultEntropyProvider();
@@ -118,6 +119,10 @@ class MetricsStateManager final {
CorruptNewLowEntropySources);
FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest,
CorruptOldLowEntropySources);
+ FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest,
+ ProvisionalClientId_PromotedToClientId);
+ FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest,
+ ProvisionalClientId_NotPersisted);
FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetBackup);
FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetMetricsIDs);
@@ -152,10 +157,10 @@ class MetricsStateManager final {
// Loads the client info via |load_client_info_|.
std::unique_ptr<ClientInfo> LoadClientInfo();
- // Returns the high entropy source for this client, which is composed of the
+ // Returns the high entropy source for this client, which is composed of a
// client ID and the low entropy source. This is intended to be unique for
- // each install. UMA must be enabled (and |client_id_| must be set) before
- // calling this.
+ // each install. UMA must be enabled (and |client_id_| must be set) or
+ // |provisional_client_id_| must be set before calling this.
std::string GetHighEntropySource();
// Returns the low entropy source for this client. Generates a new value if
@@ -218,6 +223,14 @@ class MetricsStateManager final {
// The identifier that's sent to the server with the log reports.
std::string client_id_;
+ // A provisional client id that's generated at start up before we know whether
+ // metrics consent has been received from the client. This id becomes the
+ // |client_id_| if consent is given within the same session, or is cleared
+ // otherwise. Does not control transmission of UMA metrics, only used for the
+ // high entropy source used for field trial randomization so that field
+ // trials don't toggle state between first and second run.
+ std::string provisional_client_id_;
+
// The non-identifying low entropy source values. These values seed the
// pseudorandom generators which pick experimental groups. The "old" value is
// thought to be biased in the wild, and is no longer used for experiments
diff --git a/chromium/components/metrics/metrics_state_manager_unittest.cc b/chromium/components/metrics/metrics_state_manager_unittest.cc
index d9edc8de1c1..7c154626d73 100644
--- a/chromium/components/metrics/metrics_state_manager_unittest.cc
+++ b/chromium/components/metrics/metrics_state_manager_unittest.cc
@@ -17,6 +17,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/test/metrics/histogram_tester.h"
+#include "build/build_config.h"
#include "components/metrics/client_info.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_pref_names.h"
@@ -29,6 +30,23 @@
namespace metrics {
+namespace {
+
+// Verifies that the client id follows the expected pattern.
+void VerifyClientId(const std::string& client_id) {
+ EXPECT_EQ(36U, client_id.length());
+
+ for (size_t i = 0; i < client_id.length(); ++i) {
+ char current = client_id[i];
+ if (i == 8 || i == 13 || i == 18 || i == 23)
+ EXPECT_EQ('-', current);
+ else
+ EXPECT_TRUE(isxdigit(current));
+ }
+}
+
+} // namespace
+
class MetricsStateManagerTest : public testing::Test {
public:
MetricsStateManagerTest()
@@ -117,24 +135,32 @@ class MetricsStateManagerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest);
};
-// Ensure the ClientId is formatted as expected.
-TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) {
+TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted_ConsentInitially) {
+ // With consent set initially, client id should be created in the constructor.
+ EnableMetricsReporting();
std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
- state_manager->ForceClientIdCreation();
const std::string client_id = state_manager->client_id();
- EXPECT_EQ(36U, client_id.length());
+ VerifyClientId(client_id);
+}
- for (size_t i = 0; i < client_id.length(); ++i) {
- char current = client_id[i];
- if (i == 8 || i == 13 || i == 18 || i == 23)
- EXPECT_EQ('-', current);
- else
- EXPECT_TRUE(isxdigit(current));
- }
+TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted_ConsentLater) {
+ // With consent set initially, client id should be created on consent grant.
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
+ EXPECT_EQ(std::string(), state_manager->client_id());
+
+ EnableMetricsReporting();
+ state_manager->ForceClientIdCreation();
+ const std::string client_id = state_manager->client_id();
+ VerifyClientId(client_id);
}
TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
+ // Set the install date pref, which makes sure we don't trigger the first run
+ // behavior where a provisional client id is generated and used to return a
+ // high entropy source.
+ prefs_.SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
+
std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
state_manager->CreateDefaultEntropyProvider();
EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
@@ -163,8 +189,10 @@ TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) {
}
TEST_F(MetricsStateManagerTest, HaveNoLowEntropySource) {
+ prefs_.SetString(prefs::kMetricsClientID,
+ "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
+ EnableMetricsReporting();
std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
- state_manager->client_id_ = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
// If we have neither the new nor old low entropy sources in prefs, then the
// new source should be created...
int new_low_source = state_manager->GetLowEntropySource();
@@ -175,17 +203,19 @@ TEST_F(MetricsStateManagerTest, HaveNoLowEntropySource) {
state_manager->GetOldLowEntropySource());
// ...and the high entropy source should include the *new* low entropy source.
std::string high_source = state_manager->GetHighEntropySource();
- EXPECT_TRUE(base::EndsWith(high_source, base::IntToString(new_low_source),
+ EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(new_low_source),
base::CompareCase::SENSITIVE))
<< high_source;
}
TEST_F(MetricsStateManagerTest, HaveOnlyNewLowEntropySource) {
- std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
- state_manager->client_id_ = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
// If we have the new low entropy sources in prefs, but not the old one...
const int new_low_source = 1234;
prefs_.SetInteger(prefs::kMetricsLowEntropySource, new_low_source);
+ prefs_.SetString(prefs::kMetricsClientID,
+ "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
+ EnableMetricsReporting();
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
// ...then the new source should be loaded...
EXPECT_EQ(new_low_source, state_manager->GetLowEntropySource());
// ...but the old source should not be created...
@@ -193,18 +223,20 @@ TEST_F(MetricsStateManagerTest, HaveOnlyNewLowEntropySource) {
state_manager->GetOldLowEntropySource());
// ...and the high entropy source should include the *new* low entropy source.
std::string high_source = state_manager->GetHighEntropySource();
- EXPECT_TRUE(base::EndsWith(high_source, base::IntToString(new_low_source),
+ EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(new_low_source),
base::CompareCase::SENSITIVE))
<< high_source;
}
TEST_F(MetricsStateManagerTest, HaveOnlyOldLowEntropySource) {
- std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
- state_manager->client_id_ = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
// If we have the old low entropy sources in prefs, but not the new one...
const int old_low_source = 5678;
prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, old_low_source);
+ prefs_.SetString(prefs::kMetricsClientID,
+ "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
+ EnableMetricsReporting();
// ...then the new source should be created...
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
int new_low_source = state_manager->GetLowEntropySource();
EXPECT_TRUE(MetricsStateManager::IsValidLowEntropySource(new_low_source))
<< new_low_source;
@@ -212,25 +244,27 @@ TEST_F(MetricsStateManagerTest, HaveOnlyOldLowEntropySource) {
EXPECT_EQ(old_low_source, state_manager->GetOldLowEntropySource());
// ...and the high entropy source should include the *old* low entropy source.
std::string high_source = state_manager->GetHighEntropySource();
- EXPECT_TRUE(base::EndsWith(high_source, base::IntToString(old_low_source),
+ EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(old_low_source),
base::CompareCase::SENSITIVE))
<< high_source;
}
TEST_F(MetricsStateManagerTest, HaveBothLowEntropySources) {
- std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
- state_manager->client_id_ = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
// If we have the new and old low entropy sources in prefs...
const int new_low_source = 1234;
const int old_low_source = 5678;
prefs_.SetInteger(prefs::kMetricsLowEntropySource, new_low_source);
prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, old_low_source);
+ prefs_.SetString(prefs::kMetricsClientID,
+ "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
+ EnableMetricsReporting();
// ...then both should be loaded...
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
EXPECT_EQ(new_low_source, state_manager->GetLowEntropySource());
EXPECT_EQ(old_low_source, state_manager->GetOldLowEntropySource());
// ...and the high entropy source should include the *old* low entropy source.
std::string high_source = state_manager->GetHighEntropySource();
- EXPECT_TRUE(base::EndsWith(high_source, base::IntToString(old_low_source),
+ EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(old_low_source),
base::CompareCase::SENSITIVE))
<< high_source;
}
@@ -273,6 +307,8 @@ TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
const std::string kInitialClientId = "initial client id";
prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);
+ EnableMetricsReporting();
+
// Make sure the initial client id isn't reset by the metrics state manager.
{
std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
@@ -315,6 +351,7 @@ TEST_F(MetricsStateManagerTest, ForceClientIdCreation) {
// Confirm that the initial ForceClientIdCreation call creates the client id
// and backs it up via MockStoreClientInfoBackup.
EXPECT_FALSE(stored_client_info_backup_);
+ EnableMetricsReporting();
state_manager->ForceClientIdCreation();
EXPECT_NE(std::string(), state_manager->client_id());
EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
@@ -330,6 +367,70 @@ TEST_F(MetricsStateManagerTest, ForceClientIdCreation) {
}
}
+#if !defined(OS_WIN)
+TEST_F(MetricsStateManagerTest, ProvisionalClientId_PromotedToClientId) {
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
+
+ // Verify that there was a provisional client id created.
+ std::string provisional_client_id = state_manager->provisional_client_id_;
+ VerifyClientId(provisional_client_id);
+ // No client id should have been stored.
+ EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
+ int low_entropy_source = state_manager->GetLowEntropySource();
+ // The default entropy provider should be the high entropy one.
+ state_manager->CreateDefaultEntropyProvider();
+ EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
+ state_manager->entropy_source_returned());
+
+ // Forcing client id creation should promote the provisional client id to
+ // become the real client id and keep the low entropy source.
+ EnableMetricsReporting();
+ state_manager->ForceClientIdCreation();
+ std::string client_id = state_manager->client_id();
+ EXPECT_EQ(provisional_client_id, client_id);
+ EXPECT_EQ(client_id, prefs_.GetString(prefs::kMetricsClientID));
+ EXPECT_TRUE(state_manager->provisional_client_id_.empty());
+ EXPECT_EQ(low_entropy_source, state_manager->GetLowEntropySource());
+}
+
+TEST_F(MetricsStateManagerTest, ProvisionalClientId_NotPersisted) {
+ std::string provisional_client_id;
+ int low_entropy_source;
+
+ // First run, with a provisional client id.
+ {
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
+ // Verify that there was a provisional client id created.
+ std::string provisional_client_id = state_manager->provisional_client_id_;
+ VerifyClientId(provisional_client_id);
+ // No client id should have been stored.
+ EXPECT_TRUE(
+ prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
+ low_entropy_source = state_manager->GetLowEntropySource();
+ // The default entropy provider should be the high entropy one.
+ state_manager->CreateDefaultEntropyProvider();
+ EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
+ state_manager->entropy_source_returned());
+ }
+
+ // Now, simulate a second run, such that UMA was not turned on during the
+ // first run. This should not result in any client id existing nor any
+ // provisional client id.
+ {
+ std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
+ EXPECT_TRUE(state_manager->provisional_client_id_.empty());
+ EXPECT_TRUE(state_manager->client_id().empty());
+ EXPECT_EQ(low_entropy_source, state_manager->GetLowEntropySource());
+ EXPECT_TRUE(
+ prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
+ // The default entropy provider should be the low entropy one.
+ state_manager->CreateDefaultEntropyProvider();
+ EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
+ state_manager->entropy_source_returned());
+ }
+}
+#endif // !defined(OS_WIN)
+
TEST_F(MetricsStateManagerTest, LoadPrefs) {
ClientInfo client_info;
client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
diff --git a/chromium/components/metrics/net/net_metrics_log_uploader.cc b/chromium/components/metrics/net/net_metrics_log_uploader.cc
index 3b6a5709e6e..9f208fec26e 100644
--- a/chromium/components/metrics/net/net_metrics_log_uploader.cc
+++ b/chromium/components/metrics/net/net_metrics_log_uploader.cc
@@ -5,6 +5,7 @@
#include "components/metrics/net/net_metrics_log_uploader.h"
#include "base/base64.h"
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
@@ -161,7 +162,7 @@ namespace metrics {
NetMetricsLogUploader::NetMetricsLogUploader(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- base::StringPiece server_url,
+ const GURL& server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete)
@@ -173,8 +174,8 @@ NetMetricsLogUploader::NetMetricsLogUploader(
NetMetricsLogUploader::NetMetricsLogUploader(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- base::StringPiece server_url,
- base::StringPiece insecure_server_url,
+ const GURL& server_url,
+ const GURL& insecure_server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete)
diff --git a/chromium/components/metrics/net/net_metrics_log_uploader.h b/chromium/components/metrics/net/net_metrics_log_uploader.h
index c3d889f495f..c7439d7d8ce 100644
--- a/chromium/components/metrics/net/net_metrics_log_uploader.h
+++ b/chromium/components/metrics/net/net_metrics_log_uploader.h
@@ -30,7 +30,7 @@ class NetMetricsLogUploader : public MetricsLogUploader {
// be called with the HTTP response code of the upload or with -1 on an error.
NetMetricsLogUploader(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- base::StringPiece server_url,
+ const GURL& server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete);
@@ -40,8 +40,8 @@ class NetMetricsLogUploader : public MetricsLogUploader {
// to |server_url| fails, requests are encrypted when sent to an HTTP URL.
NetMetricsLogUploader(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- base::StringPiece server_url,
- base::StringPiece insecure_server_url,
+ const GURL& server_url,
+ const GURL& insecure_server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete);
diff --git a/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc b/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
index bf4f6a3a816..484f4900206 100644
--- a/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
+++ b/chromium/components/metrics/net/net_metrics_log_uploader_unittest.cc
@@ -41,8 +41,8 @@ class NetMetricsLogUploaderTest : public testing::Test {
ReportingInfo reporting_info;
reporting_info.set_attempt_count(10);
uploader_.reset(new NetMetricsLogUploader(
- test_shared_url_loader_factory_, "https://dummy_server", "dummy_mime",
- MetricsLogUploader::UMA,
+ test_shared_url_loader_factory_, GURL("https://dummy_server"),
+ "dummy_mime", MetricsLogUploader::UMA,
base::Bind(&NetMetricsLogUploaderTest::OnUploadCompleteReuseUploader,
base::Unretained(this))));
uploader_->UploadLog("initial_dummy_data", "initial_dummy_hash",
@@ -52,7 +52,7 @@ class NetMetricsLogUploaderTest : public testing::Test {
void CreateUploaderAndUploadToSecureURL(const std::string& url) {
ReportingInfo dummy_reporting_info;
uploader_.reset(new NetMetricsLogUploader(
- test_shared_url_loader_factory_, url, "dummy_mime",
+ test_shared_url_loader_factory_, GURL(url), "dummy_mime",
MetricsLogUploader::UMA,
base::Bind(&NetMetricsLogUploaderTest::DummyOnUploadComplete,
base::Unretained(this))));
@@ -63,7 +63,7 @@ class NetMetricsLogUploaderTest : public testing::Test {
void CreateUploaderAndUploadToInsecureURL() {
ReportingInfo dummy_reporting_info;
uploader_.reset(new NetMetricsLogUploader(
- test_shared_url_loader_factory_, "http://dummy_insecure_server",
+ test_shared_url_loader_factory_, GURL("http://dummy_insecure_server"),
"dummy_mime", MetricsLogUploader::UMA,
base::Bind(&NetMetricsLogUploaderTest::DummyOnUploadComplete,
base::Unretained(this))));
diff --git a/chromium/components/metrics/net/network_metrics_provider.cc b/chromium/components/metrics/net/network_metrics_provider.cc
index b585b6ec4c7..228de7a9d25 100644
--- a/chromium/components/metrics/net/network_metrics_provider.cc
+++ b/chromium/components/metrics/net/network_metrics_provider.cc
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
diff --git a/chromium/components/metrics/net/network_metrics_provider_unittest.cc b/chromium/components/metrics/net/network_metrics_provider_unittest.cc
index ef2e586b5bc..d1296a94f93 100644
--- a/chromium/components/metrics/net/network_metrics_provider_unittest.cc
+++ b/chromium/components/metrics/net/network_metrics_provider_unittest.cc
@@ -35,15 +35,27 @@ class NetworkMetricsProviderTest : public testing::Test {
public:
protected:
NetworkMetricsProviderTest()
- : test_thread_bundle_(TestThreadBundle::IO_MAINLOOP) {
+ : test_thread_bundle_(TestThreadBundle::IO_MAINLOOP) {}
+ ~NetworkMetricsProviderTest() override {}
+
+ void SetUp() override {
#if defined(OS_CHROMEOS)
chromeos::DBusThreadManager::Initialize();
chromeos::NetworkHandler::Initialize();
#endif // OS_CHROMEOS
}
+ void TearDown() override {
+#if defined(OS_CHROMEOS)
+ chromeos::NetworkHandler::Shutdown();
+ chromeos::DBusThreadManager::Shutdown();
+#endif // OS_CHROMEOS
+ }
+
private:
TestThreadBundle test_thread_bundle_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkMetricsProviderTest);
};
// Verifies that the effective connection type is correctly set.
diff --git a/chromium/components/metrics/persisted_logs.cc b/chromium/components/metrics/persisted_logs.cc
index 588a75e7e5a..15ef46b0835 100644
--- a/chromium/components/metrics/persisted_logs.cc
+++ b/chromium/components/metrics/persisted_logs.cc
@@ -9,7 +9,6 @@
#include <utility>
#include "base/base64.h"
-#include "base/md5.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
@@ -153,6 +152,9 @@ void PersistedLogs::DiscardStagedLog() {
void PersistedLogs::PersistUnsentLogs() const {
ListPrefUpdate update(local_state_, pref_name_);
+ // TODO(crbug.com/859477): Verify that the preference has been properly
+ // registered.
+ CHECK(update.Get());
WriteLogsToPrefList(update.Get());
}
@@ -163,7 +165,7 @@ void PersistedLogs::LoadPersistedUnsentLogs() {
void PersistedLogs::StoreLog(const std::string& log_data) {
list_.push_back(LogInfo());
list_.back().Init(metrics_.get(), log_data,
- base::Int64ToString(base::Time::Now().ToTimeT()),
+ base::NumberToString(base::Time::Now().ToTimeT()),
signing_key_);
}
diff --git a/chromium/components/metrics/persisted_logs_metrics.h b/chromium/components/metrics/persisted_logs_metrics.h
index e3c58dd1c56..496230c9b6d 100644
--- a/chromium/components/metrics/persisted_logs_metrics.h
+++ b/chromium/components/metrics/persisted_logs_metrics.h
@@ -34,7 +34,7 @@ class PersistedLogsMetrics {
PersistedLogsMetrics() {}
virtual ~PersistedLogsMetrics() {}
- virtual void RecordLogReadStatus(LogReadStatus status){};
+ virtual void RecordLogReadStatus(LogReadStatus status) {}
virtual void RecordCompressionRatio(
size_t compressed_size, size_t original_size) {}
diff --git a/chromium/components/metrics/reporting_service.h b/chromium/components/metrics/reporting_service.h
index 6094fc37ec4..b388b0de10c 100644
--- a/chromium/components/metrics/reporting_service.h
+++ b/chromium/components/metrics/reporting_service.h
@@ -17,6 +17,7 @@
#include "components/metrics/data_use_tracker.h"
#include "components/metrics/metrics_log_uploader.h"
#include "third_party/metrics_proto/reporting_info.pb.h"
+#include "url/gurl.h"
class PrefService;
class PrefRegistrySimple;
@@ -71,15 +72,15 @@ class ReportingService {
static void RegisterPrefs(PrefRegistrySimple* registry);
protected:
- MetricsServiceClient* client() const { return client_; };
+ MetricsServiceClient* client() const { return client_; }
private:
// Retrieves the log store backing this service.
virtual LogStore* log_store() = 0;
// Getters for MetricsLogUploader parameters.
- virtual std::string GetUploadUrl() const = 0;
- virtual std::string GetInsecureUploadUrl() const = 0;
+ virtual GURL GetUploadUrl() const = 0;
+ virtual GURL GetInsecureUploadUrl() const = 0;
virtual base::StringPiece upload_mime_type() const = 0;
virtual MetricsLogUploader::MetricServiceType service_type() const = 0;
diff --git a/chromium/components/metrics/reporting_service_unittest.cc b/chromium/components/metrics/reporting_service_unittest.cc
index 7198ef2f131..31c6f88adbb 100644
--- a/chromium/components/metrics/reporting_service_unittest.cc
+++ b/chromium/components/metrics/reporting_service_unittest.cc
@@ -77,8 +77,8 @@ class TestReportingService : public ReportingService {
private:
// ReportingService:
LogStore* log_store() override { return &log_store_; }
- std::string GetUploadUrl() const override { return kTestUploadUrl; }
- std::string GetInsecureUploadUrl() const override { return kTestUploadUrl; }
+ GURL GetUploadUrl() const override { return GURL(kTestUploadUrl); }
+ GURL GetInsecureUploadUrl() const override { return GURL(kTestUploadUrl); }
base::StringPiece upload_mime_type() const override { return kTestMimeType; }
MetricsLogUploader::MetricServiceType service_type() const override {
return MetricsLogUploader::MetricServiceType::UMA;
diff --git a/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
index 8113de5b94f..a14d23f71df 100644
--- a/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
+++ b/chromium/components/metrics/single_sample_metrics_factory_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "components/metrics/single_sample_metrics_factory_impl.h"
+#include "base/bind.h"
#include "base/metrics/dummy_histogram.h"
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
diff --git a/chromium/components/metrics/stability_metrics_helper.cc b/chromium/components/metrics/stability_metrics_helper.cc
index 6646e32517e..fae139b5015 100644
--- a/chromium/components/metrics/stability_metrics_helper.cc
+++ b/chromium/components/metrics/stability_metrics_helper.cc
@@ -210,12 +210,10 @@ void StabilityMetricsHelper::BrowserUtilityProcessLaunched(
void StabilityMetricsHelper::BrowserUtilityProcessCrashed(
const std::string& metrics_name,
int exit_code) {
- // TODO(wfh): there doesn't appear to be a good way to log these exit_codes
- // without adding something into the stability proto, so for now only log the
- // crash and if the numbers are high enough, logging exit codes can be added
- // later.
uint32_t hash = variations::HashName(metrics_name);
base::UmaHistogramSparse("ChildProcess.Crashed.UtilityProcessHash", hash);
+ base::UmaHistogramSparse("ChildProcess.Crashed.UtilityProcessExitCode",
+ exit_code);
}
void StabilityMetricsHelper::BrowserChildProcessCrashed() {
diff --git a/chromium/components/metrics/test_metrics_service_client.cc b/chromium/components/metrics/test_metrics_service_client.cc
index 4859b4e71f2..a34c5d0e214 100644
--- a/chromium/components/metrics/test_metrics_service_client.cc
+++ b/chromium/components/metrics/test_metrics_service_client.cc
@@ -60,8 +60,8 @@ void TestMetricsServiceClient::CollectFinalMetricsForLog(
}
std::unique_ptr<MetricsLogUploader> TestMetricsServiceClient::CreateUploader(
- base::StringPiece server_url,
- base::StringPiece insecure_server_url,
+ const GURL& server_url,
+ const GURL& insecure_server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete) {
diff --git a/chromium/components/metrics/test_metrics_service_client.h b/chromium/components/metrics/test_metrics_service_client.h
index c495536c402..79eadb5c846 100644
--- a/chromium/components/metrics/test_metrics_service_client.h
+++ b/chromium/components/metrics/test_metrics_service_client.h
@@ -35,8 +35,8 @@ class TestMetricsServiceClient : public MetricsServiceClient {
std::string GetVersionString() override;
void CollectFinalMetricsForLog(const base::Closure& done_callback) override;
std::unique_ptr<MetricsLogUploader> CreateUploader(
- base::StringPiece server_url,
- base::StringPiece insecure_server_url,
+ const GURL& server_url,
+ const GURL& insecure_server_url,
base::StringPiece mime_type,
MetricsLogUploader::MetricServiceType service_type,
const MetricsLogUploader::UploadCallback& on_upload_complete) override;
diff --git a/chromium/components/metrics_services_manager/metrics_services_manager.cc b/chromium/components/metrics_services_manager/metrics_services_manager.cc
index e1ef99e79b5..67244bbbcf5 100644
--- a/chromium/components/metrics_services_manager/metrics_services_manager.cc
+++ b/chromium/components/metrics_services_manager/metrics_services_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
diff --git a/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadCallable.java b/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadCallable.java
index ff4879c348f..6fc616c3ed5 100644
--- a/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadCallable.java
+++ b/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadCallable.java
@@ -24,6 +24,8 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.HttpURLConnection;
import java.util.Locale;
import java.util.concurrent.Callable;
@@ -50,17 +52,15 @@ public class MinidumpUploadCallable implements Callable<Integer> {
@VisibleForTesting
protected static final String CONTENT_TYPE_TMPL = "multipart/form-data; boundary=%s";
- @IntDef({
- UPLOAD_SUCCESS,
- UPLOAD_FAILURE,
- UPLOAD_USER_DISABLED,
- UPLOAD_DISABLED_BY_SAMPLING
- })
- public @interface MinidumpUploadStatus {}
- public static final int UPLOAD_SUCCESS = 0;
- public static final int UPLOAD_FAILURE = 1;
- public static final int UPLOAD_USER_DISABLED = 2;
- public static final int UPLOAD_DISABLED_BY_SAMPLING = 3;
+ @IntDef({MinidumpUploadStatus.SUCCESS, MinidumpUploadStatus.FAILURE,
+ MinidumpUploadStatus.USER_DISABLED, MinidumpUploadStatus.DISABLED_BY_SAMPLING})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MinidumpUploadStatus {
+ int SUCCESS = 0;
+ int FAILURE = 1;
+ int USER_DISABLED = 2;
+ int DISABLED_BY_SAMPLING = 3;
+ }
private final File mFileToUpload;
private final File mLogfile;
@@ -83,7 +83,7 @@ public class MinidumpUploadCallable implements Callable<Integer> {
}
@Override
- public Integer call() {
+ public @MinidumpUploadStatus Integer call() {
if (mPermManager.isUploadEnabledForTests()) {
Log.i(TAG, "Minidump upload enabled for tests, skipping other checks.");
} else if (!CrashFileManager.isForcedUpload(mFileToUpload)) {
@@ -91,44 +91,44 @@ public class MinidumpUploadCallable implements Callable<Integer> {
Log.i(TAG, "Minidump upload is not permitted by user. Marking file as skipped for "
+ "cleanup to prevent future uploads.");
CrashFileManager.markUploadSkipped(mFileToUpload);
- return UPLOAD_USER_DISABLED;
+ return MinidumpUploadStatus.USER_DISABLED;
}
if (!mPermManager.isClientInMetricsSample()) {
Log.i(TAG, "Minidump upload skipped due to sampling. Marking file as skipped for "
+ "cleanup to prevent future uploads.");
CrashFileManager.markUploadSkipped(mFileToUpload);
- return UPLOAD_DISABLED_BY_SAMPLING;
+ return MinidumpUploadStatus.DISABLED_BY_SAMPLING;
}
if (!mPermManager.isNetworkAvailableForCrashUploads()) {
Log.i(TAG, "Minidump cannot currently be uploaded due to network constraints.");
- return UPLOAD_FAILURE;
+ return MinidumpUploadStatus.FAILURE;
}
}
HttpURLConnection connection =
mHttpURLConnectionFactory.createHttpURLConnection(CRASH_URL_STRING);
if (connection == null) {
- return UPLOAD_FAILURE;
+ return MinidumpUploadStatus.FAILURE;
}
FileInputStream minidumpInputStream = null;
try {
if (!configureConnectionForHttpPost(connection)) {
- return UPLOAD_FAILURE;
+ return MinidumpUploadStatus.FAILURE;
}
minidumpInputStream = new FileInputStream(mFileToUpload);
streamCopy(minidumpInputStream, new GZIPOutputStream(connection.getOutputStream()));
boolean success = handleExecutionResponse(connection);
- return success ? UPLOAD_SUCCESS : UPLOAD_FAILURE;
+ return success ? MinidumpUploadStatus.SUCCESS : MinidumpUploadStatus.FAILURE;
} catch (IOException | ArrayIndexOutOfBoundsException e) {
// ArrayIndexOutOfBoundsException due to bad GZIPOutputStream implementation on some
// old sony devices.
// For now just log the stack trace.
Log.w(TAG, "Error while uploading " + mFileToUpload.getName(), e);
- return UPLOAD_FAILURE;
+ return MinidumpUploadStatus.FAILURE;
} finally {
connection.disconnect();
diff --git a/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploaderImpl.java b/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploaderImpl.java
index 7275b67134d..bf228d116fb 100644
--- a/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploaderImpl.java
+++ b/chromium/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploaderImpl.java
@@ -7,6 +7,7 @@ package org.chromium.components.minidump_uploader;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
+import org.chromium.components.minidump_uploader.MinidumpUploadCallable.MinidumpUploadStatus;
import java.io.File;
@@ -103,12 +104,13 @@ public class MinidumpUploaderImpl implements MinidumpUploader {
Log.i(TAG, "Attempting to upload " + minidump.getName());
MinidumpUploadCallable uploadCallable =
createMinidumpUploadCallable(minidump, fileManager.getCrashUploadLogFile());
+ @MinidumpUploadStatus
int uploadResult = uploadCallable.call();
// Record metrics about the upload.
- if (uploadResult == MinidumpUploadCallable.UPLOAD_SUCCESS) {
+ if (uploadResult == MinidumpUploadStatus.SUCCESS) {
mDelegate.recordUploadSuccess(minidump);
- } else if (uploadResult == MinidumpUploadCallable.UPLOAD_FAILURE) {
+ } else if (uploadResult == MinidumpUploadStatus.FAILURE) {
// Only record a failure after we have maxed out the allotted tries.
// Note: Add 1 to include the most recent failure, since the minidump's filename
// is from before the failure.
@@ -135,7 +137,7 @@ public class MinidumpUploaderImpl implements MinidumpUploader {
// incremented, even if the upload failed. This is because a common reason for
// cancelation is loss of network connectivity, which does result in a failure, but
// it's a transient failure rather than something non-recoverable.
- if (uploadResult == MinidumpUploadCallable.UPLOAD_FAILURE) {
+ if (uploadResult == MinidumpUploadStatus.FAILURE) {
String newName = CrashFileManager.tryIncrementAttemptNumber(minidump);
if (newName == null) {
Log.w(TAG, "Failed to increment attempt number of " + minidump);
diff --git a/chromium/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java b/chromium/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java
index f17c05b4180..4ed9c0a8c19 100644
--- a/chromium/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java
+++ b/chromium/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/MinidumpUploadCallableTest.java
@@ -16,6 +16,7 @@ import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.components.minidump_uploader.CrashTestRule.MockCrashReportingPermissionManager;
+import org.chromium.components.minidump_uploader.MinidumpUploadCallable.MinidumpUploadStatus;
import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory;
@@ -217,8 +218,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
Assert.assertTrue(mExpectedFileAfterUpload.exists());
assertValidUploadLogEntry();
}
@@ -241,8 +241,8 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(MinidumpUploadCallable.UPLOAD_USER_DISABLED,
- minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(
+ MinidumpUploadStatus.USER_DISABLED, minidumpUploadCallable.call().intValue());
File expectedSkippedFileAfterUpload = new File(
mTestRule.getCrashDir(), mTestUpload.getName().replace(".dmp", ".skipped"));
@@ -268,7 +268,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(MinidumpUploadCallable.UPLOAD_DISABLED_BY_SAMPLING,
+ Assert.assertEquals(MinidumpUploadStatus.DISABLED_BY_SAMPLING,
minidumpUploadCallable.call().intValue());
File expectedSkippedFileAfterUpload = new File(
@@ -295,8 +295,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_FAILURE, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.FAILURE, minidumpUploadCallable.call().intValue());
Assert.assertFalse(mExpectedFileAfterUpload.exists());
}
@@ -318,8 +317,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
Assert.assertTrue(mExpectedFileAfterUpload.exists());
assertValidUploadLogEntry();
}
@@ -343,8 +341,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
Assert.assertTrue(mExpectedFileAfterUpload.exists());
assertValidUploadLogEntry();
}
@@ -368,8 +365,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
File expectedSkippedFileAfterUpload = new File(
mTestRule.getCrashDir(), mTestUpload.getName().replace(".forced", ".skipped"));
@@ -396,8 +392,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
File expectedSkippedFileAfterUpload = new File(
mTestRule.getCrashDir(), mTestUpload.getName().replace(".forced", ".skipped"));
@@ -424,8 +419,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
File expectedSkippedFileAfterUpload = new File(
mTestRule.getCrashDir(), mTestUpload.getName().replace(".forced", ".skipped"));
@@ -451,8 +445,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_FAILURE, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.FAILURE, minidumpUploadCallable.call().intValue());
Assert.assertFalse(mExpectedFileAfterUpload.exists());
}
@@ -477,8 +470,7 @@ public class MinidumpUploadCallableTest {
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(
- MinidumpUploadCallable.UPLOAD_SUCCESS, minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(MinidumpUploadStatus.SUCCESS, minidumpUploadCallable.call().intValue());
Assert.assertTrue(mExpectedFileAfterUpload.exists());
assertValidUploadLogEntry();
}
@@ -504,8 +496,8 @@ public class MinidumpUploadCallableTest {
new ErrorCodeHttpUrlConnectionFactory(errorCodes[n]);
MinidumpUploadCallable minidumpUploadCallable =
new MockMinidumpUploadCallable(httpURLConnectionFactory, testPermManager);
- Assert.assertEquals(MinidumpUploadCallable.UPLOAD_FAILURE,
- minidumpUploadCallable.call().intValue());
+ Assert.assertEquals(
+ MinidumpUploadStatus.FAILURE, minidumpUploadCallable.call().intValue());
// Note that mTestUpload is not renamed on failure - so we can try to upload that file
// several times during the same test.
}
diff --git a/chromium/components/mirroring/OWNERS b/chromium/components/mirroring/OWNERS
index 6234a6a3dc5..b44d282f535 100644
--- a/chromium/components/mirroring/OWNERS
+++ b/chromium/components/mirroring/OWNERS
@@ -1,4 +1,3 @@
miu@chromium.org
-xjz@chromium.org
# COMPONENT: Internals>Cast>Streaming
diff --git a/chromium/components/mirroring/browser/single_client_video_capture_host.cc b/chromium/components/mirroring/browser/single_client_video_capture_host.cc
index 540c78cfeaa..b67c71eabb2 100644
--- a/chromium/components/mirroring/browser/single_client_video_capture_host.cc
+++ b/chromium/components/mirroring/browser/single_client_video_capture_host.cc
@@ -4,6 +4,7 @@
#include "components/mirroring/browser/single_client_video_capture_host.h"
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_media_capture_id.h"
#include "media/capture/video/video_capture_buffer_pool.h"
@@ -172,6 +173,19 @@ void SingleClientVideoCaptureHost::GetDeviceFormatsInUse(
std::move(callback).Run(media::VideoCaptureFormats());
}
+void SingleClientVideoCaptureHost::OnFrameDropped(
+ int32_t device_id,
+ media::VideoCaptureFrameDropReason reason) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // Ignore this call.
+}
+
+void SingleClientVideoCaptureHost::OnLog(int32_t device_id,
+ const std::string& message) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ // Ignore this call.
+}
+
void SingleClientVideoCaptureHost::OnNewBuffer(
int buffer_id,
media::mojom::VideoBufferHandlePtr buffer_handle) {
@@ -252,6 +266,10 @@ void SingleClientVideoCaptureHost::OnStartedUsingGpuDecode() {
NOTIMPLEMENTED();
}
+void SingleClientVideoCaptureHost::OnStopped() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
void SingleClientVideoCaptureHost::OnDeviceLaunched(
std::unique_ptr<content::LaunchedVideoCaptureDevice> device) {
DVLOG(1) << __func__;
diff --git a/chromium/components/mirroring/browser/single_client_video_capture_host.h b/chromium/components/mirroring/browser/single_client_video_capture_host.h
index 1db62159322..08b4e313257 100644
--- a/chromium/components/mirroring/browser/single_client_video_capture_host.h
+++ b/chromium/components/mirroring/browser/single_client_video_capture_host.h
@@ -65,6 +65,9 @@ class SingleClientVideoCaptureHost final
void GetDeviceFormatsInUse(int32_t device_id,
int32_t session_id,
GetDeviceFormatsInUseCallback callback) override;
+ void OnFrameDropped(int32_t device_id,
+ media::VideoCaptureFrameDropReason reason) override;
+ void OnLog(int32_t device_id, const std::string& message) override;
// media::VideoFrameReceiver implementations
using Buffer = VideoCaptureDevice::Client::Buffer;
@@ -83,6 +86,7 @@ class SingleClientVideoCaptureHost final
void OnLog(const std::string& message) override;
void OnStarted() override;
void OnStartedUsingGpuDecode() override;
+ void OnStopped() override;
void OnDeviceLaunched(
std::unique_ptr<content::LaunchedVideoCaptureDevice> device);
diff --git a/chromium/components/mirroring/browser/single_client_video_capture_host_unittest.cc b/chromium/components/mirroring/browser/single_client_video_capture_host_unittest.cc
index aa119fb0c84..8632066dcf0 100644
--- a/chromium/components/mirroring/browser/single_client_video_capture_host_unittest.cc
+++ b/chromium/components/mirroring/browser/single_client_video_capture_host_unittest.cc
@@ -4,6 +4,7 @@
#include "components/mirroring/browser/single_client_video_capture_host.h"
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/mirroring/service/BUILD.gn b/chromium/components/mirroring/service/BUILD.gn
index 2a907db3127..881987bbec8 100644
--- a/chromium/components/mirroring/service/BUILD.gn
+++ b/chromium/components/mirroring/service/BUILD.gn
@@ -2,14 +2,8 @@
# 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/service_manifest.gni")
import("//testing/test.gni")
-service_manifest("manifest") {
- name = "mirroring"
- source = "manifest.json"
-}
-
component("mirroring_service") {
sources = [
"captured_audio_input.cc",
@@ -120,3 +114,17 @@ source_set("unittests") {
"//testing/gtest",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/mirroring/mojom:constants",
+ "//components/mirroring/mojom:service",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/mirroring/service/OWNERS b/chromium/components/mirroring/service/OWNERS
index 59dfd4b3677..6faeaa4752f 100644
--- a/chromium/components/mirroring/service/OWNERS
+++ b/chromium/components/mirroring/service/OWNERS
@@ -1,2 +1,4 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/mirroring/service/captured_audio_input.cc b/chromium/components/mirroring/service/captured_audio_input.cc
index 3f1d02ff8a3..c86349925ed 100644
--- a/chromium/components/mirroring/service/captured_audio_input.cc
+++ b/chromium/components/mirroring/service/captured_audio_input.cc
@@ -5,6 +5,7 @@
#include "components/mirroring/service/captured_audio_input.h"
#include "base/logging.h"
+#include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace mirroring {
diff --git a/chromium/components/mirroring/service/captured_audio_input_unittest.cc b/chromium/components/mirroring/service/captured_audio_input_unittest.cc
index eaeca84e875..59541baa651 100644
--- a/chromium/components/mirroring/service/captured_audio_input_unittest.cc
+++ b/chromium/components/mirroring/service/captured_audio_input_unittest.cc
@@ -4,10 +4,12 @@
#include "components/mirroring/service/captured_audio_input.h"
+#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "media/base/audio_parameters.h"
+#include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/platform_handle.h"
diff --git a/chromium/components/mirroring/service/fake_video_capture_host.cc b/chromium/components/mirroring/service/fake_video_capture_host.cc
index 201edc79aa3..afb423d1a74 100644
--- a/chromium/components/mirroring/service/fake_video_capture_host.cc
+++ b/chromium/components/mirroring/service/fake_video_capture_host.cc
@@ -6,6 +6,7 @@
#include "base/memory/read_only_shared_memory_region.h"
#include "media/base/video_frame.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
#include "mojo/public/cpp/base/shared_memory_utils.h"
namespace mirroring {
diff --git a/chromium/components/mirroring/service/fake_video_capture_host.h b/chromium/components/mirroring/service/fake_video_capture_host.h
index f74af05876c..179a30f2e90 100644
--- a/chromium/components/mirroring/service/fake_video_capture_host.h
+++ b/chromium/components/mirroring/service/fake_video_capture_host.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_MIRRORING_SERVICE_FAKE_VIDEO_CAPTURE_HOST_H_
#define COMPONENTS_MIRRORING_SERVICE_FAKE_VIDEO_CAPTURE_HOST_H_
+#include <string>
+
#include "media/capture/mojom/video_capture.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -24,6 +26,9 @@ class FakeVideoCaptureHost final : public media::mojom::VideoCaptureHost {
MOCK_METHOD3(Resume,
void(int32_t, int32_t, const media::VideoCaptureParams&));
MOCK_METHOD0(OnStopped, void());
+ MOCK_METHOD2(OnLog, void(int32_t, const std::string&));
+ MOCK_METHOD2(OnFrameDropped,
+ void(int32_t, media::VideoCaptureFrameDropReason));
void Start(int32_t device_id,
int32_t session_id,
diff --git a/chromium/components/mirroring/service/manifest.cc b/chromium/components/mirroring/service/manifest.cc
new file mode 100644
index 00000000000..eda50b24f01
--- /dev/null
+++ b/chromium/components/mirroring/service/manifest.cc
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mirroring/service/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/mirroring/mojom/constants.mojom.h"
+#include "components/mirroring/mojom/mirroring_service.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace mirroring {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("Mirroring Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("utility")
+ .Build())
+ .ExposeCapability("mirroring",
+ service_manager::Manifest::InterfaceList<
+ mojom::MirroringService>())
+ .RequireCapability("content_browser", "gpu_client")
+ .RequireCapability("ui", "gpu_client")
+
+ .Build()};
+ return *manifest;
+}
+
+} // namespace mirroring
diff --git a/chromium/components/mirroring/service/manifest.h b/chromium/components/mirroring/service/manifest.h
new file mode 100644
index 00000000000..26022af19e1
--- /dev/null
+++ b/chromium/components/mirroring/service/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
+#define COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace mirroring {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace mirroring
+
+#endif // COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
diff --git a/chromium/components/mirroring/service/manifest.json b/chromium/components/mirroring/service/manifest.json
deleted file mode 100644
index 882edee016e..00000000000
--- a/chromium/components/mirroring/service/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "mirroring",
- "sandbox_type": "utility",
- "display_name": "Mirroring Service",
- "interface_provider_specs": {
- "service_manager:connector": {
- "requires": {
- "content_browser": [ "gpu_client" ],
- "ui": [ "gpu_client" ]
- },
- "provides": {
- "mirroring": [
- "mirroring.mojom.MirroringService"
- ]
- }
- }
- }
-}
diff --git a/chromium/components/mirroring/service/media_remoter.cc b/chromium/components/mirroring/service/media_remoter.cc
index d9c3b2ac678..3608be14a22 100644
--- a/chromium/components/mirroring/service/media_remoter.cc
+++ b/chromium/components/mirroring/service/media_remoter.cc
@@ -5,6 +5,7 @@
#include "components/mirroring/service/media_remoter.h"
#include "base/base64.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
diff --git a/chromium/components/mirroring/service/media_remoter.h b/chromium/components/mirroring/service/media_remoter.h
index 1910da16496..388a5306bdf 100644
--- a/chromium/components/mirroring/service/media_remoter.h
+++ b/chromium/components/mirroring/service/media_remoter.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "media/cast/cast_config.h"
#include "media/mojo/interfaces/remoting.mojom.h"
+#include "media/mojo/interfaces/remoting_common.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace media {
diff --git a/chromium/components/mirroring/service/message_dispatcher.cc b/chromium/components/mirroring/service/message_dispatcher.cc
index aaf0f0af03c..ebc0fcc2869 100644
--- a/chromium/components/mirroring/service/message_dispatcher.cc
+++ b/chromium/components/mirroring/service/message_dispatcher.cc
@@ -4,9 +4,11 @@
#include "components/mirroring/service/message_dispatcher.h"
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/rand_util.h"
+#include "base/timer/timer.h"
namespace mirroring {
diff --git a/chromium/components/mirroring/service/mirroring_service.cc b/chromium/components/mirroring/service/mirroring_service.cc
index 499529105d5..7d18f84fb08 100644
--- a/chromium/components/mirroring/service/mirroring_service.cc
+++ b/chromium/components/mirroring/service/mirroring_service.cc
@@ -4,6 +4,7 @@
#include "components/mirroring/service/mirroring_service.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "components/mirroring/service/session.h"
#include "services/ws/public/cpp/gpu/gpu.h"
diff --git a/chromium/components/mirroring/service/receiver_response.cc b/chromium/components/mirroring/service/receiver_response.cc
index 6feff42172c..6e15a03b9cb 100644
--- a/chromium/components/mirroring/service/receiver_response.cc
+++ b/chromium/components/mirroring/service/receiver_response.cc
@@ -138,7 +138,8 @@ ReceiverResponse& ReceiverResponse::operator=(
ReceiverResponse&& receiver_response) = default;
bool ReceiverResponse::Parse(const std::string& message_data) {
- std::unique_ptr<base::Value> raw_value = base::JSONReader::Read(message_data);
+ std::unique_ptr<base::Value> raw_value =
+ base::JSONReader::ReadDeprecated(message_data);
if (!raw_value || !raw_value->is_dict() ||
!GetInt(*raw_value, "sessionId", &session_id) ||
!GetInt(*raw_value, "seqNum", &sequence_number) ||
diff --git a/chromium/components/mirroring/service/receiver_response_unittest.cc b/chromium/components/mirroring/service/receiver_response_unittest.cc
index 807a683f48d..1151046993b 100644
--- a/chromium/components/mirroring/service/receiver_response_unittest.cc
+++ b/chromium/components/mirroring/service/receiver_response_unittest.cc
@@ -106,7 +106,7 @@ TEST_F(ReceiverResponseTest, ParseErrorMessage) {
EXPECT_EQ(42, response.error->code);
EXPECT_EQ("it is broke", response.error->description);
std::unique_ptr<base::Value> parsed_details =
- base::JSONReader::Read(response.error->details);
+ base::JSONReader::ReadDeprecated(response.error->details);
ASSERT_TRUE(parsed_details && parsed_details->is_dict());
EXPECT_EQ(2u, parsed_details->DictSize());
int fool_value = 0;
diff --git a/chromium/components/mirroring/service/session.cc b/chromium/components/mirroring/service/session.cc
index 8bd95c58c09..daca22b5a0a 100644
--- a/chromium/components/mirroring/service/session.cc
+++ b/chromium/components/mirroring/service/session.cc
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/rand_util.h"
diff --git a/chromium/components/mirroring/service/session.h b/chromium/components/mirroring/service/session.h
index 7ceef26dacd..c70c62c3d76 100644
--- a/chromium/components/mirroring/service/session.h
+++ b/chromium/components/mirroring/service/session.h
@@ -23,6 +23,7 @@
#include "media/cast/cast_environment.h"
#include "media/cast/net/cast_transport_defines.h"
#include "media/mojo/interfaces/video_encode_accelerator.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
namespace media {
class AudioInputDevice;
diff --git a/chromium/components/mirroring/service/session_monitor.cc b/chromium/components/mirroring/service/session_monitor.cc
index 2ff5610e2de..b0fa6b61144 100644
--- a/chromium/components/mirroring/service/session_monitor.cc
+++ b/chromium/components/mirroring/service/session_monitor.cc
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/stl_util.h"
@@ -46,7 +47,8 @@ bool ParseReceiverSetupInfo(const std::string& response,
base::Value* tags,
std::string* receiver_name) {
DCHECK(tags);
- std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(response);
std::string build_version;
bool is_connected = false;
diff --git a/chromium/components/mirroring/service/session_monitor_unittest.cc b/chromium/components/mirroring/service/session_monitor_unittest.cc
index 4611cb20950..ead85614829 100644
--- a/chromium/components/mirroring/service/session_monitor_unittest.cc
+++ b/chromium/components/mirroring/service/session_monitor_unittest.cc
@@ -186,7 +186,7 @@ class SessionMonitorTest : public mojom::CastMessageChannel,
base::Value ReadStats(const std::string& stats_string) {
std::unique_ptr<base::Value> stats_ptr =
- base::JSONReader::Read(stats_string);
+ base::JSONReader::ReadDeprecated(stats_string);
EXPECT_TRUE(stats_ptr);
base::Value stats = base::Value::FromUniquePtrValue(std::move(stats_ptr));
EXPECT_TRUE(stats.is_list());
diff --git a/chromium/components/mirroring/service/session_unittest.cc b/chromium/components/mirroring/service/session_unittest.cc
index 72bd6d5cd24..5cf0f038a01 100644
--- a/chromium/components/mirroring/service/session_unittest.cc
+++ b/chromium/components/mirroring/service/session_unittest.cc
@@ -99,7 +99,7 @@ class SessionTest : public mojom::ResourceProvider,
EXPECT_TRUE(message->message_namespace == mojom::kWebRtcNamespace ||
message->message_namespace == mojom::kRemotingNamespace);
std::unique_ptr<base::Value> value =
- base::JSONReader::Read(message->json_format_data);
+ base::JSONReader::ReadDeprecated(message->json_format_data);
ASSERT_TRUE(value);
std::string message_type;
EXPECT_TRUE(GetString(*value, "type", &message_type));
diff --git a/chromium/components/mirroring/service/udp_socket_client.cc b/chromium/components/mirroring/service/udp_socket_client.cc
index 96923f88ee8..dfdaf12f607 100644
--- a/chromium/components/mirroring/service/udp_socket_client.cc
+++ b/chromium/components/mirroring/service/udp_socket_client.cc
@@ -4,6 +4,7 @@
#include "components/mirroring/service/udp_socket_client.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "net/base/address_family.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
diff --git a/chromium/components/mirroring/service/video_capture_client.cc b/chromium/components/mirroring/service/video_capture_client.cc
index 5d57fc3258e..5da9e7fd601 100644
--- a/chromium/components/mirroring/service/video_capture_client.cc
+++ b/chromium/components/mirroring/service/video_capture_client.cc
@@ -4,8 +4,10 @@
#include "components/mirroring/service/video_capture_client.h"
+#include "base/bind.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
namespace mirroring {
diff --git a/chromium/components/mirroring/service/video_capture_client_unittest.cc b/chromium/components/mirroring/service/video_capture_client_unittest.cc
index 3f11bf24f30..586e7f6cb58 100644
--- a/chromium/components/mirroring/service/video_capture_client_unittest.cc
+++ b/chromium/components/mirroring/service/video_capture_client_unittest.cc
@@ -4,6 +4,7 @@
#include "components/mirroring/service/video_capture_client.h"
+#include "base/bind.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
@@ -11,6 +12,7 @@
#include "components/mirroring/service/fake_video_capture_host.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_metadata.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
#include "mojo/public/cpp/base/shared_memory_utils.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -135,8 +137,8 @@ TEST_P(VideoCaptureClientTest, Basic) {
OnBufferReady(0, gfx::Size(320, 180));
}
-INSTANTIATE_TEST_CASE_P(,
- VideoCaptureClientTest,
- ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ VideoCaptureClientTest,
+ ::testing::Values(true, false));
} // namespace mirroring
diff --git a/chromium/components/mirroring/service/wifi_status_monitor_unittest.cc b/chromium/components/mirroring/service/wifi_status_monitor_unittest.cc
index d298cf52d17..8fd597a6285 100644
--- a/chromium/components/mirroring/service/wifi_status_monitor_unittest.cc
+++ b/chromium/components/mirroring/service/wifi_status_monitor_unittest.cc
@@ -30,7 +30,7 @@ bool IsNullMessage(const CastMessage& message) {
std::string GetMessageType(const CastMessage& message) {
std::string type;
std::unique_ptr<base::Value> value =
- base::JSONReader::Read(message.json_format_data);
+ base::JSONReader::ReadDeprecated(message.json_format_data);
EXPECT_TRUE(value);
EXPECT_TRUE(GetString(*value, "type", &type));
return type;
diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java
index 84785b31354..dae242dc9b5 100644
--- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java
+++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/FakeModuleInstallerBackend.java
@@ -71,25 +71,65 @@ class FakeModuleInstallerBackend extends ModuleInstallerBackend {
private boolean installInternal(String moduleName) {
Context context = ContextUtils.getApplicationContext();
int versionCode = BuildInfo.getInstance().versionCode;
- // Path where SplitCompat looks for downloaded modules. May change in future releases of
- // the Play Core SDK.
- File dstModuleFile = joinPaths(context.getFilesDir().getPath(), "splitcompat",
- Integer.toString(versionCode), "unverified-splits", moduleName + ".apk");
- File srcModuleFile = joinPaths(MODULES_SRC_DIRECTORY_PATH, moduleName + ".apk");
- // NOTE: Need to give Chrome storage permission for this to work.
- try {
- dstModuleFile.getParentFile().mkdirs();
- } catch (SecurityException e) {
- Log.e(TAG, "Failed to create module dir", e);
+ // Get list of all files at path where SplitCompat looks for downloaded modules.
+ // May change in future releases of the Play Core SDK.
+ File srcModuleDir = new File(MODULES_SRC_DIRECTORY_PATH);
+ if (!srcModuleDir.exists()) {
+ Log.e(TAG, "Modules source directory does not exist");
+ return false;
+ }
+ if (!srcModuleDir.canRead()) {
+ Log.e(TAG, "Cannot read modules source directory");
+ return false;
+ }
+ if (!srcModuleDir.isDirectory()) {
+ Log.e(TAG, "Modules source directory is not a directory");
return false;
}
+ File[] srcModuleFiles = srcModuleDir.listFiles();
+ if (srcModuleFiles == null) {
+ Log.e(TAG, "Cannot get list of files in modules source directory");
+ return false;
+ }
+
+ // Check if any apks for the module are actually installed.
+ boolean no_module_apks_installed = true;
+
+ for (File srcModuleFile : srcModuleFiles) {
+ // Take only source APK files of the specified module.
+ String srcModuleFileName = srcModuleFile.getName();
+ if (srcModuleFileName.endsWith(".apk") && srcModuleFileName.startsWith(moduleName)) {
+ // Construct destination file corresponding to each source file.
+ File dstModuleFile = joinPaths(context.getFilesDir().getPath(), "splitcompat",
+ Integer.toString(versionCode), "unverified-splits", srcModuleFileName);
+
+ // NOTE: Need to give Chrome storage permission for this to work.
+ try {
+ dstModuleFile.getParentFile().mkdirs();
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to create module dir %s", dstModuleFile.getName(), e);
+ return false;
+ }
+
+ try (FileInputStream istream = new FileInputStream(srcModuleFile);
+ FileOutputStream ostream = new FileOutputStream(dstModuleFile)) {
+ ostream.getChannel().transferFrom(
+ istream.getChannel(), 0, istream.getChannel().size());
+ if (srcModuleFileName.equals(moduleName + ".apk")) {
+ // Base apk of the module must be installed for install
+ // to be successful.
+ no_module_apks_installed = false;
+ }
+ } catch (RuntimeException | IOException e) {
+ Log.e(TAG, "Failed to install module apk %s", dstModuleFile.getName(), e);
+ return false;
+ }
+ }
+ }
- try (FileInputStream istream = new FileInputStream(srcModuleFile);
- FileOutputStream ostream = new FileOutputStream(dstModuleFile)) {
- ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.getChannel().size());
- } catch (RuntimeException | IOException e) {
- Log.e(TAG, "Failed to install module", e);
+ if (no_module_apks_installed) {
+ Log.e(TAG, "Did not find any module APKs");
return false;
}
diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java
index 85d1b67997f..879472a2a94 100644
--- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java
+++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/ModuleInstaller.java
@@ -49,6 +49,17 @@ public class ModuleInstaller {
updateCrashKeys();
}
+ /**
+ * Needs to be called in attachBaseContext of the activities that want to have access to
+ * splits prior to application restart.
+ *
+ * For details, see:
+ * https://developer.android.com/reference/com/google/android/play/core/splitcompat/SplitCompat.html#install(android.content.Context)
+ */
+ public static void initActivity(Context context) {
+ SplitCompat.install(context);
+ }
+
/** Writes fully installed and emulated modules to crash keys. */
public static void updateCrashKeys() {
Context context = ContextUtils.getApplicationContext();
diff --git a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java
index 4061ba538bd..d28467b5149 100644
--- a/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java
+++ b/chromium/components/module_installer/android/java/src-impl/org/chromium/components/module_installer/PlayCoreModuleInstallerBackend.java
@@ -25,7 +25,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
/**
* Backend that uses the Play Core SDK to download a module from Play and install it subsequently.
@@ -132,7 +131,7 @@ import java.util.concurrent.TimeUnit;
moduleInfo.second ? "CachedInstallDuration" : "UncachedInstallDuration";
RecordHistogram.recordLongTimesHistogram(
"Android.FeatureModules." + histogramSubname + "." + name,
- installDurationMs, TimeUnit.MILLISECONDS);
+ installDurationMs);
}
}
onFinished(success, moduleNames);
diff --git a/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java
index 65ee45b16b6..5dd14d3090d 100644
--- a/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java
+++ b/chromium/components/module_installer/android/java/src-stub/org/chromium/components/module_installer/ModuleInstaller.java
@@ -4,11 +4,16 @@
package org.chromium.components.module_installer;
+import android.content.Context;
+
import org.chromium.base.VisibleForTesting;
/** Dummy fallback of ModuleInstaller for APK builds. */
public class ModuleInstaller {
public static void init() {}
+
+ public static void initActivity(Context context) {}
+
public static void updateCrashKeys(){};
public static void install(
diff --git a/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java b/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java
index 9df2a242004..720b8e8d235 100644
--- a/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java
+++ b/chromium/components/module_installer/android/java/src-test/org/chromium/components/module_installer/ModuleInstaller.java
@@ -4,6 +4,8 @@
package org.chromium.components.module_installer;
+import android.content.Context;
+
import org.chromium.base.VisibleForTesting;
import java.util.HashSet;
@@ -14,6 +16,9 @@ public class ModuleInstaller {
private static Set<String> sModulesRequestedDeffered = new HashSet<>();
public static void init() {}
+
+ public static void initActivity(Context context) {}
+
public static void updateCrashKeys(){};
public static void install(
diff --git a/chromium/components/nacl/broker/BUILD.gn b/chromium/components/nacl/broker/BUILD.gn
index 4c342b0748f..55b3925f561 100644
--- a/chromium/components/nacl/broker/BUILD.gn
+++ b/chromium/components/nacl/broker/BUILD.gn
@@ -4,7 +4,6 @@
import("//build/config/compiler/compiler.gni")
import("//components/nacl/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
# This file builds nacl64.exe, which is a 64-bit x86 Windows executable
# used only in the 32-bit x86 Windows build. The :broker code runs both
@@ -175,7 +174,15 @@ if (current_cpu == "x86") {
}
}
-service_manifest("nacl_broker_manifest") {
- name = "nacl_broker"
- source = "nacl_broker_manifest.json"
+source_set("nacl_broker_manifest") {
+ sources = [
+ "nacl_broker_manifest.cc",
+ "nacl_broker_manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/nacl/common",
+ "//services/service_manager/public/cpp",
+ ]
}
diff --git a/chromium/components/nacl/loader/BUILD.gn b/chromium/components/nacl/loader/BUILD.gn
index 963c64b9d0c..39bb50e4e90 100644
--- a/chromium/components/nacl/loader/BUILD.gn
+++ b/chromium/components/nacl/loader/BUILD.gn
@@ -6,7 +6,6 @@ import("//build/config/c++/c++.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/nacl/config.gni")
import("//components/nacl/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//testing/test.gni")
assert(enable_nacl)
@@ -321,7 +320,15 @@ if (is_nacl_nonsfi) {
}
}
-service_manifest("nacl_loader_manifest") {
- name = "nacl_loader"
- source = "nacl_loader_manifest.json"
+source_set("nacl_loader_manifest") {
+ sources = [
+ "nacl_loader_manifest.cc",
+ "nacl_loader_manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/nacl/common",
+ "//services/service_manager/public/cpp",
+ ]
}
diff --git a/chromium/components/navigation_interception/intercept_navigation_delegate.cc b/chromium/components/navigation_interception/intercept_navigation_delegate.cc
index 8d2d1d89505..3939a362692 100644
--- a/chromium/components/navigation_interception/intercept_navigation_delegate.cc
+++ b/chromium/components/navigation_interception/intercept_navigation_delegate.cc
@@ -8,8 +8,8 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
+#include "base/bind.h"
#include "base/callback.h"
-#include "components/navigation_interception/intercept_navigation_throttle.h"
#include "components/navigation_interception/navigation_params_android.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_throttle.h"
@@ -69,9 +69,10 @@ InterceptNavigationDelegate* InterceptNavigationDelegate::Get(
// static
std::unique_ptr<content::NavigationThrottle>
InterceptNavigationDelegate::CreateThrottleFor(
- content::NavigationHandle* handle) {
+ content::NavigationHandle* handle,
+ navigation_interception::SynchronyMode mode) {
return std::make_unique<InterceptNavigationThrottle>(
- handle, base::Bind(&CheckIfShouldIgnoreNavigationOnUIThread));
+ handle, base::Bind(&CheckIfShouldIgnoreNavigationOnUIThread), mode);
}
InterceptNavigationDelegate::InterceptNavigationDelegate(
diff --git a/chromium/components/navigation_interception/intercept_navigation_delegate.h b/chromium/components/navigation_interception/intercept_navigation_delegate.h
index 1e7e860a24d..1f5b229d153 100644
--- a/chromium/components/navigation_interception/intercept_navigation_delegate.h
+++ b/chromium/components/navigation_interception/intercept_navigation_delegate.h
@@ -10,6 +10,7 @@
#include "base/android/jni_weak_ref.h"
#include "base/macros.h"
#include "base/supports_user_data.h"
+#include "components/navigation_interception/intercept_navigation_throttle.h"
namespace content {
class NavigationHandle;
@@ -49,7 +50,8 @@ class InterceptNavigationDelegate : public base::SupportsUserData::Data {
// Creates a InterceptNavigationThrottle that will direct all callbacks to
// the InterceptNavigationDelegate.
static std::unique_ptr<content::NavigationThrottle> CreateThrottleFor(
- content::NavigationHandle* handle);
+ content::NavigationHandle* handle,
+ navigation_interception::SynchronyMode mode);
virtual bool ShouldIgnoreNavigation(
const NavigationParams& navigation_params);
diff --git a/chromium/components/navigation_interception/intercept_navigation_throttle.cc b/chromium/components/navigation_interception/intercept_navigation_throttle.cc
index 2b2b89ec12f..bcfea98788f 100644
--- a/chromium/components/navigation_interception/intercept_navigation_throttle.cc
+++ b/chromium/components/navigation_interception/intercept_navigation_throttle.cc
@@ -9,21 +9,25 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"
namespace navigation_interception {
+// Note: this feature is a no-op on non-Android platforms.
const base::Feature InterceptNavigationThrottle::kAsyncCheck{
- "AsyncNavigationIntercept", base::FEATURE_DISABLED_BY_DEFAULT};
+ "AsyncNavigationIntercept", base::FEATURE_ENABLED_BY_DEFAULT};
InterceptNavigationThrottle::InterceptNavigationThrottle(
content::NavigationHandle* navigation_handle,
- CheckCallback should_ignore_callback)
+ CheckCallback should_ignore_callback,
+ SynchronyMode async_mode)
: content::NavigationThrottle(navigation_handle),
should_ignore_callback_(should_ignore_callback),
ui_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ mode_(async_mode),
weak_factory_(this) {}
InterceptNavigationThrottle::~InterceptNavigationThrottle() {
@@ -49,21 +53,7 @@ InterceptNavigationThrottle::WillRedirectRequest() {
}
content::NavigationThrottle::ThrottleCheckResult
-InterceptNavigationThrottle::WillFailRequest() {
- return WillFinish();
-}
-
-content::NavigationThrottle::ThrottleCheckResult
InterceptNavigationThrottle::WillProcessResponse() {
- return WillFinish();
-}
-
-const char* InterceptNavigationThrottle::GetNameForLogging() {
- return "InterceptNavigationThrottle";
-}
-
-content::NavigationThrottle::ThrottleCheckResult
-InterceptNavigationThrottle::WillFinish() {
DCHECK(!deferring_);
if (should_ignore_)
return content::NavigationThrottle::CANCEL_AND_IGNORE;
@@ -76,6 +66,10 @@ InterceptNavigationThrottle::WillFinish() {
return content::NavigationThrottle::PROCEED;
}
+const char* InterceptNavigationThrottle::GetNameForLogging() {
+ return "InterceptNavigationThrottle";
+}
+
content::NavigationThrottle::ThrottleCheckResult
InterceptNavigationThrottle::CheckIfShouldIgnoreNavigation(bool is_redirect) {
if (ShouldCheckAsynchronously()) {
@@ -120,11 +114,13 @@ void InterceptNavigationThrottle::RunCheckAsync(
bool InterceptNavigationThrottle::ShouldCheckAsynchronously() const {
// Do not apply the async optimization for:
+ // - Throttles in non-async mode.
// - POST navigations, to ensure we aren't violating idempotency.
// - Subframe navigations, which aren't observed on Android, and should be
// fast on other platforms.
// - non-http/s URLs, which are more likely to be intercepted.
- return navigation_handle()->IsInMainFrame() &&
+ return mode_ == SynchronyMode::kAsync &&
+ navigation_handle()->IsInMainFrame() &&
!navigation_handle()->IsPost() &&
navigation_handle()->GetURL().SchemeIsHTTPOrHTTPS() &&
base::FeatureList::IsEnabled(kAsyncCheck);
diff --git a/chromium/components/navigation_interception/intercept_navigation_throttle.h b/chromium/components/navigation_interception/intercept_navigation_throttle.h
index 0b154bc01b6..a961826d3c3 100644
--- a/chromium/components/navigation_interception/intercept_navigation_throttle.h
+++ b/chromium/components/navigation_interception/intercept_navigation_throttle.h
@@ -23,6 +23,13 @@ namespace navigation_interception {
class NavigationParams;
+enum class SynchronyMode {
+ // Support async interception in some cases (See ShouldCheckAsynchronously).
+ kAsync,
+ // Only support synchronous interception.
+ kSync
+};
+
// This class allows the provider of the Callback to selectively ignore top
// level navigations. This is a UI thread class.
class InterceptNavigationThrottle : public content::NavigationThrottle {
@@ -35,20 +42,17 @@ class InterceptNavigationThrottle : public content::NavigationThrottle {
static const base::Feature kAsyncCheck;
InterceptNavigationThrottle(content::NavigationHandle* navigation_handle,
- CheckCallback should_ignore_callback);
+ CheckCallback should_ignore_callback,
+ SynchronyMode async_mode);
~InterceptNavigationThrottle() override;
// content::NavigationThrottle implementation:
ThrottleCheckResult WillStartRequest() override;
ThrottleCheckResult WillRedirectRequest() override;
- ThrottleCheckResult WillFailRequest() override;
ThrottleCheckResult WillProcessResponse() override;
const char* GetNameForLogging() override;
private:
- // To be called on either WillFailRequest or WillProcessResponse.
- ThrottleCheckResult WillFinish();
-
ThrottleCheckResult CheckIfShouldIgnoreNavigation(bool is_redirect);
void RunCheckAsync(const NavigationParams& params);
@@ -65,6 +69,8 @@ class InterceptNavigationThrottle : public content::NavigationThrottle {
// Note that the CheckCallback currently has thread affinity on the Java side.
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
+ const SynchronyMode mode_ = SynchronyMode::kSync;
+
// The remaining members are only set for asynchronous checking.
//
// How many outbound pending checks are running. Normally this will be either
diff --git a/chromium/components/navigation_interception/intercept_navigation_throttle_unittest.cc b/chromium/components/navigation_interception/intercept_navigation_throttle_unittest.cc
index d9d493bba77..2f239b173d4 100644
--- a/chromium/components/navigation_interception/intercept_navigation_throttle_unittest.cc
+++ b/chromium/components/navigation_interception/intercept_navigation_throttle_unittest.cc
@@ -75,7 +75,8 @@ class InterceptNavigationThrottleTest
static std::unique_ptr<content::NavigationThrottle> CreateThrottle(
InterceptNavigationThrottle::CheckCallback callback,
content::NavigationHandle* handle) {
- return std::make_unique<InterceptNavigationThrottle>(handle, callback);
+ return std::make_unique<InterceptNavigationThrottle>(
+ handle, callback, navigation_interception::SynchronyMode::kAsync);
}
std::unique_ptr<content::TestNavigationThrottleInserter>
@@ -231,8 +232,8 @@ TEST_P(InterceptNavigationThrottleTest, IgnoreCallbackDeletesNavigation) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(,
- InterceptNavigationThrottleTest,
- testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ InterceptNavigationThrottleTest,
+ testing::Values(true, false));
} // namespace navigation_interception
diff --git a/chromium/components/net_log/net_export_file_writer.cc b/chromium/components/net_log/net_export_file_writer.cc
index e727d4fbeb7..6f26a179bbf 100644
--- a/chromium/components/net_log/net_export_file_writer.cc
+++ b/chromium/components/net_log/net_export_file_writer.cc
@@ -9,6 +9,7 @@
#include <utility>
#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"
diff --git a/chromium/components/net_log/net_export_file_writer_unittest.cc b/chromium/components/net_log/net_export_file_writer_unittest.cc
index 5b88392bb35..f5e6d3d28db 100644
--- a/chromium/components/net_log/net_export_file_writer_unittest.cc
+++ b/chromium/components/net_log/net_export_file_writer_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
@@ -177,7 +178,8 @@ WARN_UNUSED_RESULT ::testing::AssertionResult ReadCompleteLogFile(
return ::testing::AssertionFailure()
<< log_path.value() << " could not be read.";
}
- *root = base::DictionaryValue::From(base::JSONReader::Read(log_string));
+ *root =
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(log_string));
if (!*root) {
return ::testing::AssertionFailure()
<< "Contents of " << log_path.value()
diff --git a/chromium/components/neterror/resources/neterror.css b/chromium/components/neterror/resources/neterror.css
index 5252e1b0647..b33a7eb7a04 100644
--- a/chromium/components/neterror/resources/neterror.css
+++ b/chromium/components/neterror/resources/neterror.css
@@ -721,13 +721,11 @@ html[subframe] body {
/* Styles for platform dependent separation of controls and details button. */
.suggested-left > #control-buttons,
-.suggested-left #stale-load-button,
.suggested-right > #details-button {
float: left;
}
.suggested-right > #control-buttons,
-.suggested-right #stale-load-button,
.suggested-left > #details-button {
float: right;
}
diff --git a/chromium/components/neterror/resources/neterror.html b/chromium/components/neterror/resources/neterror.html
index 1b5e96c556a..2736e6ae0bf 100644
--- a/chromium/components/neterror/resources/neterror.html
+++ b/chromium/components/neterror/resources/neterror.html
@@ -117,12 +117,6 @@
jsselect="reloadButton"
jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId"
jscontent="msg"></button>
- <button id="show-saved-copy-button"
- class="blue-button text-button"
- onclick="showSavedCopyButtonClick()"
- jsselect="showSavedCopyButton"
- jscontent="msg" jsvalues="title:title; .primary:primary">
- </button>
<button id="download-button"
class="blue-button text-button"
onclick="downloadButtonClick()"
diff --git a/chromium/components/neterror/resources/neterror.js b/chromium/components/neterror/resources/neterror.js
index 29f5636e3af..cf35fceca5f 100644
--- a/chromium/components/neterror/resources/neterror.js
+++ b/chromium/components/neterror/resources/neterror.js
@@ -119,12 +119,6 @@ function reloadButtonClick(url) {
}
}
-function showSavedCopyButtonClick() {
- if (window.errorPageController) {
- errorPageController.showSavedCopyButtonClick();
- }
-}
-
function downloadButtonClick() {
if (window.errorPageController) {
errorPageController.downloadButtonClick();
@@ -329,14 +323,10 @@ function onDocumentLoad() {
var controlButtonDiv = document.getElementById('control-buttons');
var reloadButton = document.getElementById('reload-button');
var detailsButton = document.getElementById('details-button');
- var showSavedCopyButton = document.getElementById('show-saved-copy-button');
var downloadButton = document.getElementById('download-button');
var reloadButtonVisible = loadTimeData.valueExists('reloadButton') &&
loadTimeData.getValue('reloadButton').msg;
- var showSavedCopyButtonVisible =
- loadTimeData.valueExists('showSavedCopyButton') &&
- loadTimeData.getValue('showSavedCopyButton').msg;
var downloadButtonVisible = loadTimeData.valueExists('downloadButton') &&
loadTimeData.getValue('downloadButton').msg;
@@ -361,22 +351,11 @@ function onDocumentLoad() {
return;
}
- var primaryButton, secondaryButton;
- if (showSavedCopyButton.primary) {
- primaryButton = showSavedCopyButton;
- secondaryButton = reloadButton;
- } else {
- primaryButton = reloadButton;
- secondaryButton = showSavedCopyButton;
- }
-
// Sets up the proper button layout for the current platform.
if (primaryControlOnLeft) {
buttons.classList.add('suggested-left');
- controlButtonDiv.insertBefore(secondaryButton, primaryButton);
} else {
buttons.classList.add('suggested-right');
- controlButtonDiv.insertBefore(primaryButton, secondaryButton);
}
// Check for Google cached copy suggestion.
@@ -385,7 +364,6 @@ function onDocumentLoad() {
}
if (reloadButton.style.display == 'none' &&
- showSavedCopyButton.style.display == 'none' &&
downloadButton.style.display == 'none') {
detailsButton.classList.add('singular');
}
@@ -394,16 +372,8 @@ function onDocumentLoad() {
loadTimeData.getValue('attemptAutoFetch');
// Show control buttons.
- if (reloadButtonVisible || showSavedCopyButtonVisible ||
- downloadButtonVisible || attemptAutoFetch) {
+ if (reloadButtonVisible || downloadButtonVisible || attemptAutoFetch)
controlButtonDiv.hidden = false;
-
- // Set the secondary button state in the cases of two call to actions.
- if ((reloadButtonVisible || downloadButtonVisible) &&
- showSavedCopyButtonVisible) {
- secondaryButton.classList.add('secondary-button');
- }
- }
}
document.addEventListener('DOMContentLoaded', onDocumentLoad);
diff --git a/chromium/components/network_hints/browser/network_hints_message_filter.cc b/chromium/components/network_hints/browser/network_hints_message_filter.cc
index 299a7f478f0..0a4f910716c 100644
--- a/chromium/components/network_hints/browser/network_hints_message_filter.cc
+++ b/chromium/components/network_hints/browser/network_hints_message_filter.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "components/network_hints/common/network_hints_common.h"
diff --git a/chromium/components/network_hints/renderer/dns_prefetch_queue_unittest.cc b/chromium/components/network_hints/renderer/dns_prefetch_queue_unittest.cc
index 4e8f3ae5e47..d14ff7266aa 100644
--- a/chromium/components/network_hints/renderer/dns_prefetch_queue_unittest.cc
+++ b/chromium/components/network_hints/renderer/dns_prefetch_queue_unittest.cc
@@ -263,4 +263,4 @@ TEST(DnsQueueTest, WrapOnVariousSubstrings) {
EXPECT_FALSE(tester.Pop());
}
-}; // namespace network_hints
+} // namespace network_hints
diff --git a/chromium/components/network_session_configurator/browser/network_session_configurator.cc b/chromium/components/network_session_configurator/browser/network_session_configurator.cc
index b537ddc5ca7..bc5c3dd123f 100644
--- a/chromium/components/network_session_configurator/browser/network_session_configurator.cc
+++ b/chromium/components/network_session_configurator/browser/network_session_configurator.cc
@@ -325,19 +325,42 @@ bool ShouldQuicGoawayOnPathDegrading(
"true");
}
-bool ShouldQuicRaceStaleDNSOnConnection(
+int GetQuicMaxTimeOnNonDefaultNetworkSeconds(
+ const VariationParameters& quic_trial_params) {
+ int value;
+ if (base::StringToInt(
+ GetVariationParam(quic_trial_params,
+ "max_time_on_non_default_network_seconds"),
+ &value)) {
+ return value;
+ }
+ return 0;
+}
+
+bool ShouldQuicMigrateIdleSessions(
const VariationParameters& quic_trial_params) {
return base::LowerCaseEqualsASCII(
- GetVariationParam(quic_trial_params, "race_stale_dns_on_connection"),
- "true");
+ GetVariationParam(quic_trial_params, "migrate_idle_sessions"), "true");
}
-int GetQuicMaxTimeOnNonDefaultNetworkSeconds(
+int GetQuicRetransmittableOnWireTimeoutMilliseconds(
const VariationParameters& quic_trial_params) {
int value;
if (base::StringToInt(
GetVariationParam(quic_trial_params,
- "max_time_on_non_default_network_seconds"),
+ "retransmittable_on_wire_timeout_milliseconds"),
+ &value)) {
+ return value;
+ }
+ return 0;
+}
+
+int GetQuicIdleSessionMigrationPeriodSeconds(
+ const VariationParameters& quic_trial_params) {
+ int value;
+ if (base::StringToInt(
+ GetVariationParam(quic_trial_params,
+ "idle_session_migration_period_seconds"),
&value)) {
return value;
}
@@ -477,8 +500,20 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params);
params->quic_go_away_on_path_degrading =
ShouldQuicGoawayOnPathDegrading(quic_trial_params);
- params->quic_race_stale_dns_on_connection =
- ShouldQuicRaceStaleDNSOnConnection(quic_trial_params);
+ int retransmittable_on_wire_timeout_milliseconds =
+ GetQuicRetransmittableOnWireTimeoutMilliseconds(quic_trial_params);
+ if (retransmittable_on_wire_timeout_milliseconds > 0) {
+ params->quic_retransmittable_on_wire_timeout_milliseconds =
+ retransmittable_on_wire_timeout_milliseconds;
+ }
+ params->quic_migrate_idle_sessions =
+ ShouldQuicMigrateIdleSessions(quic_trial_params);
+ int idle_session_migration_period_seconds =
+ GetQuicIdleSessionMigrationPeriodSeconds(quic_trial_params);
+ if (idle_session_migration_period_seconds > 0) {
+ params->quic_idle_session_migration_period =
+ base::TimeDelta::FromSeconds(idle_session_migration_period_seconds);
+ }
int max_time_on_non_default_network_seconds =
GetQuicMaxTimeOnNonDefaultNetworkSeconds(quic_trial_params);
if (max_time_on_non_default_network_seconds > 0) {
diff --git a/chromium/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/chromium/components/network_session_configurator/browser/network_session_configurator_unittest.cc
index a072f84029b..62ffd531c15 100644
--- a/chromium/components/network_session_configurator/browser/network_session_configurator_unittest.cc
+++ b/chromium/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -121,11 +121,13 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicFromFieldTrialGroup) {
EXPECT_FALSE(params_.quic_estimate_initial_rtt);
EXPECT_FALSE(params_.quic_migrate_sessions_on_network_change_v2);
EXPECT_FALSE(params_.quic_migrate_sessions_early_v2);
- EXPECT_FALSE(params_.quic_race_stale_dns_on_connection);
EXPECT_FALSE(params_.quic_retry_on_alternate_network_before_handshake);
+ EXPECT_FALSE(params_.quic_migrate_idle_sessions);
EXPECT_FALSE(params_.quic_go_away_on_path_degrading);
EXPECT_FALSE(params_.quic_allow_server_migration);
EXPECT_TRUE(params_.quic_host_whitelist.empty());
+ EXPECT_EQ(net::kDefaultRetransmittableOnWireTimeoutMillisecs,
+ params_.quic_retransmittable_on_wire_timeout_milliseconds);
net::HttpNetworkSession::Params default_params;
EXPECT_EQ(default_params.quic_supported_versions,
@@ -223,6 +225,18 @@ TEST_F(NetworkSessionConfiguratorTest,
}
TEST_F(NetworkSessionConfiguratorTest,
+ QuicRetransmittableOnWireTimeoutMillisecondsFieldTrialParams) {
+ std::map<std::string, std::string> field_trial_params;
+ field_trial_params["retransmittable_on_wire_timeout_milliseconds"] = "1000";
+ variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
+ base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
+
+ ParseFieldTrials();
+
+ EXPECT_EQ(1000, params_.quic_retransmittable_on_wire_timeout_milliseconds);
+}
+
+TEST_F(NetworkSessionConfiguratorTest,
QuicIdleConnectionTimeoutSecondsFieldTrialParams) {
std::map<std::string, std::string> field_trial_params;
field_trial_params["idle_connection_timeout_seconds"] = "300";
@@ -376,27 +390,30 @@ TEST_F(NetworkSessionConfiguratorTest,
}
TEST_F(NetworkSessionConfiguratorTest,
- QuicRaceStaleDNSOnCOnnectionFromFieldTrialParams) {
+ QuicGoawayOnPathDegradingFromFieldTrialParams) {
std::map<std::string, std::string> field_trial_params;
- field_trial_params["race_stale_dns_on_connection"] = "true";
+ field_trial_params["go_away_on_path_degrading"] = "true";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
- EXPECT_TRUE(params_.quic_race_stale_dns_on_connection);
+ EXPECT_TRUE(params_.quic_go_away_on_path_degrading);
}
TEST_F(NetworkSessionConfiguratorTest,
- QuicGoawayOnPathDegradingFromFieldTrialParams) {
+ QuicIdleSessionMigrationPeriodFromFieldTrialParams) {
std::map<std::string, std::string> field_trial_params;
- field_trial_params["go_away_on_path_degrading"] = "true";
+ field_trial_params["migrate_idle_sessions"] = "true";
+ field_trial_params["idle_session_migration_period_seconds"] = "15";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
- EXPECT_TRUE(params_.quic_go_away_on_path_degrading);
+ EXPECT_TRUE(params_.quic_migrate_idle_sessions);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(15),
+ params_.quic_idle_session_migration_period);
}
TEST_F(NetworkSessionConfiguratorTest,
diff --git a/chromium/components/network_time/network_time_test_utils.cc b/chromium/components/network_time/network_time_test_utils.cc
index d5016d28bea..984da34c7de 100644
--- a/chromium/components/network_time/network_time_test_utils.cc
+++ b/chromium/components/network_time/network_time_test_utils.cc
@@ -70,7 +70,7 @@ void FieldTrialTest::SetNetworkQueriesWithVariationsService(
std::map<std::string, std::string> params;
params["RandomQueryProbability"] = base::NumberToString(query_probability);
- params["CheckTimeIntervalSeconds"] = base::Int64ToString(360);
+ params["CheckTimeIntervalSeconds"] = base::NumberToString(360);
std::string fetch_behavior_param;
switch (fetch_behavior) {
case NetworkTimeTracker::FETCH_BEHAVIOR_UNKNOWN:
diff --git a/chromium/components/network_time/network_time_test_utils.h b/chromium/components/network_time/network_time_test_utils.h
index 656ed4770db..b99cf7a834b 100644
--- a/chromium/components/network_time/network_time_test_utils.h
+++ b/chromium/components/network_time/network_time_test_utils.h
@@ -14,7 +14,7 @@
namespace base {
namespace test {
class ScopedFeatureList;
-}; // namespace test
+} // namespace test
class FieldTrialList;
} // namespace base
diff --git a/chromium/components/network_time/network_time_tracker.cc b/chromium/components/network_time/network_time_tracker.cc
index 34386ad169f..c4d92f26cf4 100644
--- a/chromium/components/network_time/network_time_tracker.cc
+++ b/chromium/components/network_time/network_time_tracker.cc
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/i18n/time_formatting.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
@@ -173,8 +174,7 @@ void RecordFetchValidHistogram(bool valid) {
// static
void NetworkTimeTracker::RegisterPrefs(PrefRegistrySimple* registry) {
- registry->RegisterDictionaryPref(prefs::kNetworkTimeMapping,
- std::make_unique<base::DictionaryValue>());
+ registry->RegisterDictionaryPref(prefs::kNetworkTimeMapping);
registry->RegisterBooleanPref(prefs::kNetworkTimeQueriesEnabled, true);
}
@@ -514,7 +514,7 @@ bool NetworkTimeTracker::UpdateTimeFromResponse(
return false;
}
data = data.substr(5); // Skips leading )]}'\n
- std::unique_ptr<base::Value> value = base::JSONReader::Read(data);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(data);
if (!value) {
DVLOG(1) << "bad JSON";
RecordFetchValidHistogram(false);
diff --git a/chromium/components/network_time/network_time_tracker_unittest.cc b/chromium/components/network_time/network_time_tracker_unittest.cc
index e6b9b0ffd9f..364efa2d2f6 100644
--- a/chromium/components/network_time/network_time_tracker_unittest.cc
+++ b/chromium/components/network_time/network_time_tracker_unittest.cc
@@ -8,6 +8,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
diff --git a/chromium/components/ntp_snippets/BUILD.gn b/chromium/components/ntp_snippets/BUILD.gn
index c24bf4764fa..2ec8b4fea08 100644
--- a/chromium/components/ntp_snippets/BUILD.gn
+++ b/chromium/components/ntp_snippets/BUILD.gn
@@ -266,6 +266,7 @@ source_set("unit_tests") {
"//components/sync_preferences:test_support",
"//components/ukm:test_support",
"//components/variations:test_support",
+ "//components/variations/net",
"//components/web_resource:web_resource",
"//google_apis/gcm",
"//net:test_support",
diff --git a/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc b/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc
index 1efb4131cde..1705e3ccb8e 100644
--- a/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc
+++ b/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc
@@ -41,7 +41,7 @@ const char kBookmarkLastVisitDateOnDesktopKey[] = "last_visited_desktop";
const char kBookmarkDismissedFromNTP[] = "dismissed_from_ntp";
std::string FormatLastVisitDate(const base::Time& date) {
- return base::Int64ToString(SerializeTime(date));
+ return base::NumberToString(SerializeTime(date));
}
bool ExtractLastVisitDate(const BookmarkNode& node,
diff --git a/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils_unittest.cc b/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils_unittest.cc
index 742edd13b7b..fe05702349e 100644
--- a/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils_unittest.cc
+++ b/chromium/components/ntp_snippets/bookmarks/bookmark_last_visit_utils_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
@@ -54,14 +55,14 @@ void AddBookmarksRecentOnMobile(BookmarkModel* model,
int num,
const base::Time& visit_time) {
AddBookmarks(model, num, kBookmarkLastVisitDateOnMobileKey,
- base::Int64ToString(SerializeTime(visit_time)));
+ base::NumberToString(SerializeTime(visit_time)));
}
void AddBookmarksRecentOnDesktop(BookmarkModel* model,
int num,
const base::Time& visit_time) {
AddBookmarks(model, num, kBookmarkLastVisitDateOnDesktopKey,
- base::Int64ToString(SerializeTime(visit_time)));
+ base::NumberToString(SerializeTime(visit_time)));
}
void AddBookmarksNonVisited(BookmarkModel* model, int num) {
@@ -77,7 +78,7 @@ const BookmarkNode* AddSingleBookmark(BookmarkModel* model,
const BookmarkNode* node =
model->AddURL(model->bookmark_bar_node(), 0, title, GURL(url));
model->SetNodeMetaInfo(node, last_visit_key,
- base::Int64ToString(SerializeTime(visit_time)));
+ base::NumberToString(SerializeTime(visit_time)));
return node;
}
@@ -220,7 +221,7 @@ TEST(RemoveLastVisitedDatesBetween,
model.get(), "http://url-1.com", kBookmarkLastVisitDateOnMobileKey,
delete_begin + base::TimeDelta::FromSeconds(1));
model->SetNodeMetaInfo(node, kBookmarkLastVisitDateOnDesktopKey,
- base::Int64ToString(SerializeTime(
+ base::NumberToString(SerializeTime(
delete_begin - base::TimeDelta::FromSeconds(1))));
ASSERT_THAT(
GetRecentlyVisitedBookmarks(model.get(), 20, base::Time(),
diff --git a/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.cc b/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.cc
index 725bf0596c1..f63cfee580b 100644
--- a/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.cc
+++ b/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.cc
@@ -4,6 +4,7 @@
#include "components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler.h"
+#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
diff --git a/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler_unittest.cc b/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler_unittest.cc
index e799dbc8496..93e43a8fead 100644
--- a/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler_unittest.cc
+++ b/chromium/components/ntp_snippets/breaking_news/breaking_news_gcm_app_handler_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/json/json_reader.h"
#include "base/test/metrics/histogram_tester.h"
@@ -72,7 +73,7 @@ class MockSubscriptionManager : public SubscriptionManager {
class MockInstanceIDDriver : public InstanceIDDriver {
public:
- MockInstanceIDDriver() : InstanceIDDriver(/*gcm_driver=*/nullptr){};
+ MockInstanceIDDriver() : InstanceIDDriver(/*gcm_driver=*/nullptr) {}
~MockInstanceIDDriver() override = default;
MOCK_METHOD1(GetInstanceID, InstanceID*(const std::string& app_id));
@@ -194,7 +195,7 @@ void ParseJson(
const BreakingNewsGCMAppHandler::SuccessCallback& success_callback,
const BreakingNewsGCMAppHandler::ErrorCallback& error_callback) {
base::JSONReader json_reader;
- std::unique_ptr<base::Value> value = json_reader.ReadToValue(json);
+ std::unique_ptr<base::Value> value = json_reader.ReadToValueDeprecated(json);
if (value) {
success_callback.Run(std::move(value));
} else {
diff --git a/chromium/components/ntp_snippets/breaking_news/subscription_json_request.cc b/chromium/components/ntp_snippets/breaking_news/subscription_json_request.cc
index 641a66339f0..8f7856f4347 100644
--- a/chromium/components/ntp_snippets/breaking_news/subscription_json_request.cc
+++ b/chromium/components/ntp_snippets/breaking_news/subscription_json_request.cc
@@ -4,6 +4,7 @@
#include "components/ntp_snippets/breaking_news/subscription_json_request.h"
+#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
@@ -169,8 +170,8 @@ SubscriptionJsonRequest::Builder::BuildURLLoader(
// Add X-Client-Data header with experiment IDs from field trials.
// TODO: We should call AppendVariationHeaders with explicit
// variations::SignedIn::kNo If the auth_header_ is empty
- variations::AppendVariationHeadersUnknownSignedIn(
- url_, variations::InIncognito::kNo, &resource_request->headers);
+ variations::AppendVariationsHeaderUnknownSignedIn(
+ url_, variations::InIncognito::kNo, resource_request.get());
// Log the request for debugging network issues.
DVLOG(1) << "Building a subscription request to " << url_ << ":\n"
diff --git a/chromium/components/ntp_snippets/breaking_news/subscription_json_request_unittest.cc b/chromium/components/ntp_snippets/breaking_news/subscription_json_request_unittest.cc
index 0b84b6643a5..2f09e912247 100644
--- a/chromium/components/ntp_snippets/breaking_news/subscription_json_request_unittest.cc
+++ b/chromium/components/ntp_snippets/breaking_news/subscription_json_request_unittest.cc
@@ -31,7 +31,8 @@ using testing::SaveArg;
// TODO(mamir): Create a test_helper.cc file instead of duplicating all this
// code.
MATCHER_P(EqualsJSON, json, "equals JSON") {
- std::unique_ptr<base::Value> expected = base::JSONReader::Read(json);
+ std::unique_ptr<base::Value> expected =
+ base::JSONReader::ReadDeprecated(json);
if (!expected) {
*result_listener << "INTERNAL ERROR: couldn't parse expected JSON";
return false;
@@ -39,8 +40,9 @@ MATCHER_P(EqualsJSON, json, "equals JSON") {
std::string err_msg;
int err_line, err_col;
- std::unique_ptr<base::Value> actual = base::JSONReader::ReadAndReturnError(
- arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col);
+ std::unique_ptr<base::Value> actual =
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col);
if (!actual) {
*result_listener << "input:" << err_line << ":" << err_col << ": "
<< "parse error: " << err_msg;
diff --git a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.cc b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
index 87bd9c27233..317fe972eca 100644
--- a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
+++ b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.cc
@@ -229,12 +229,12 @@ void SubscriptionManagerImpl::DidUnsubscribe(const std::string& new_token,
}
void SubscriptionManagerImpl::OnPrimaryAccountSet(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
SigninStatusChanged();
}
void SubscriptionManagerImpl::OnPrimaryAccountCleared(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
SigninStatusChanged();
}
diff --git a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.h b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.h
index 9bf77fd7d7f..5090c464052 100644
--- a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.h
+++ b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl.h
@@ -68,8 +68,8 @@ class SubscriptionManagerImpl : public SubscriptionManager,
private:
// identity:IdentityManager::Observer implementation.
- void OnPrimaryAccountSet(const AccountInfo& account_info) override;
- void OnPrimaryAccountCleared(const AccountInfo& account_info) override;
+ void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
+ void OnPrimaryAccountCleared(const CoreAccountInfo& account_info) override;
void SigninStatusChanged();
diff --git a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
index fcafe78b469..a5633d110f0 100644
--- a/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/breaking_news/subscription_manager_impl_unittest.cc
@@ -31,7 +31,7 @@ const char kTestEmail[] = "test@email.com";
const char kAPIKey[] = "fakeAPIkey";
const char kSubscriptionUrl[] = "http://valid-url.test/subscribe";
const char kSubscriptionUrlSignedIn[] = "http://valid-url.test/subscribe";
-;
+
const char kSubscriptionUrlSignedOut[] =
"http://valid-url.test/subscribe?key=fakeAPIkey";
const char kUnsubscriptionUrl[] = "http://valid-url.test/unsubscribe";
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 d6d5a796bba..f0ac042d6f5 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
@@ -135,7 +135,7 @@ base::Optional<Category> GetPromotedCategoryFromVariations() {
std::string GetOptionalCategoryAsString(
const base::Optional<Category>& optional_category) {
if (optional_category.has_value()) {
- return base::IntToString(optional_category->id());
+ return base::NumberToString(optional_category->id());
}
return "None";
}
@@ -293,8 +293,8 @@ ClickBasedCategoryRanker::GetDebugData() {
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)},
+ {base::NumberToString(ranked_category.category.id()),
+ base::NumberToString(ranked_category.clicks)},
/*offsets=*/nullptr));
}
result.push_back(
@@ -510,7 +510,7 @@ void ClickBasedCategoryRanker::StoreOrderToPrefs(
dictionary->SetInteger(kClicksKey, category.clicks);
dictionary->SetString(
kLastDismissedKey,
- base::Int64ToString(SerializeTime(category.last_dismissed)));
+ base::NumberToString(SerializeTime(category.last_dismissed)));
list.Append(std::move(dictionary));
}
pref_service_->Set(prefs::kClickBasedCategoryRankerOrderWithClicks, list);
diff --git a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
index 51fa506fb35..b7fd7c56e3b 100644
--- a/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
+++ b/chromium/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
@@ -86,7 +86,7 @@ class ClickBasedCategoryRankerTest : public testing::Test {
variation_params_manager_.SetVariationParamsWithFeatureAssociations(
kCategoryRanker.name,
{{"click_based_category_ranker-dismissed_category_penalty",
- base::IntToString(value)}},
+ base::NumberToString(value)}},
{kCategoryRanker.name});
}
@@ -94,7 +94,7 @@ class ClickBasedCategoryRankerTest : public testing::Test {
variation_params_manager_.SetVariationParamsWithFeatureAssociations(
kCategoryRanker.name,
{{"click_based_category_ranker-promoted_category",
- base::IntToString(value)}},
+ base::NumberToString(value)}},
{kCategoryRanker.name});
}
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 6a0711a2e99..60647cb0321 100644
--- a/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc
+++ b/chromium/components/ntp_snippets/category_rankers/constant_category_ranker.cc
@@ -96,7 +96,7 @@ ConstantCategoryRanker::GetDebugData() {
std::vector<std::string> category_strings;
for (Category category : ordered_categories_) {
- category_strings.push_back(base::IntToString(category.id()));
+ category_strings.push_back(base::NumberToString(category.id()));
}
result.push_back(CategoryRanker::DebugDataItem(
"Current order", base::JoinString(category_strings, ", ")));
diff --git a/chromium/components/ntp_snippets/content_suggestions_service.cc b/chromium/components/ntp_snippets/content_suggestions_service.cc
index dbfaa373223..b38aee5cf2e 100644
--- a/chromium/components/ntp_snippets/content_suggestions_service.cc
+++ b/chromium/components/ntp_snippets/content_suggestions_service.cc
@@ -522,12 +522,12 @@ void ContentSuggestionsService::OnSuggestionInvalidated(
}
// identity::IdentityManager::Observer implementation
void ContentSuggestionsService::OnPrimaryAccountSet(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
OnSignInStateChanged(/*has_signed_in=*/true);
}
void ContentSuggestionsService::OnPrimaryAccountCleared(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
OnSignInStateChanged(/*has_signed_in=*/false);
}
diff --git a/chromium/components/ntp_snippets/content_suggestions_service.h b/chromium/components/ntp_snippets/content_suggestions_service.h
index aa7b3a0ecd8..7e86d13544f 100644
--- a/chromium/components/ntp_snippets/content_suggestions_service.h
+++ b/chromium/components/ntp_snippets/content_suggestions_service.h
@@ -289,8 +289,8 @@ class ContentSuggestionsService : public KeyedService,
const ContentSuggestion::ID& suggestion_id) override;
// identity::IdentityManager::Observer implementation.
- void OnPrimaryAccountSet(const AccountInfo& account_info) override;
- void OnPrimaryAccountCleared(const AccountInfo& account_info) override;
+ void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
+ void OnPrimaryAccountCleared(const CoreAccountInfo& account_info) override;
// history::HistoryServiceObserver implementation.
void OnURLsDeleted(history::HistoryService* history_service,
diff --git a/chromium/components/ntp_snippets/content_suggestions_service_unittest.cc b/chromium/components/ntp_snippets/content_suggestions_service_unittest.cc
index 67f90939d18..da8bf43d8e3 100644
--- a/chromium/components/ntp_snippets/content_suggestions_service_unittest.cc
+++ b/chromium/components/ntp_snippets/content_suggestions_service_unittest.cc
@@ -175,8 +175,8 @@ class ContentSuggestionsServiceTest : public testing::Test {
// Returns a suggestion instance for testing.
ContentSuggestion CreateSuggestion(Category category, int number) {
return ContentSuggestion(
- category, base::IntToString(number),
- GURL("http://testsuggestion/" + base::IntToString(number)));
+ category, base::NumberToString(number),
+ GURL("http://testsuggestion/" + base::NumberToString(number)));
}
std::vector<ContentSuggestion> CreateSuggestions(
diff --git a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
index 97c4aa26677..5ac6cb447b5 100644
--- a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
+++ b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch.cc
@@ -8,6 +8,7 @@
#include "base/base64.h"
#include "base/base64url.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
@@ -285,9 +286,9 @@ void ContextualSuggestionsFetch::AppendHeaders(
base::Base64UrlEncodePolicy::INCLUDE_PADDING,
&base64_encoded_body);
headers.SetHeader("X-Protobuffer-Request-Payload", base64_encoded_body);
- variations::AppendVariationHeaders(resource_request->url,
- variations::InIncognito::kNo,
- variations::SignedIn::kNo, &headers);
+ variations::AppendVariationsHeader(
+ resource_request->url, variations::InIncognito::kNo,
+ variations::SignedIn::kNo, resource_request);
UMA_HISTOGRAM_COUNTS_1M(
"ContextualSuggestions.FetchRequestProtoSizeKB",
diff --git a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
index c02ed601b12..ee17787efaf 100644
--- a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
+++ b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetch_unittest.cc
@@ -12,6 +12,7 @@
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/ntp_snippets/contextual/contextual_suggestions_features.h"
+#include "components/variations/net/variations_http_headers.h"
#include "components/variations/variations_http_header_provider.h"
#include "services/network/public/cpp/resource_request.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -98,7 +99,7 @@ TEST(ContextualSuggestionsFetch, MakeResourceRequest_VariationsHeader) {
std::unique_ptr<network::ResourceRequest> resource_request =
fetch.MakeResourceRequestForTesting();
- EXPECT_TRUE(resource_request->headers.HasHeader("X-Client-Data"));
+ EXPECT_TRUE(variations::HasVariationsHeader(*resource_request));
}
TEST(ContextualSuggestionsFetch,
@@ -118,7 +119,7 @@ TEST(ContextualSuggestionsFetch,
std::unique_ptr<network::ResourceRequest> resource_request =
fetch.MakeResourceRequestForTesting();
- EXPECT_FALSE(resource_request->headers.HasHeader("X-Client-Data"));
+ EXPECT_FALSE(variations::HasVariationsHeader(*resource_request));
}
} // namespace
diff --git a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
index 9130ab485ab..be21e894c4f 100644
--- a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
+++ b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.cc
@@ -6,6 +6,7 @@
#include "components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl.h"
+#include "base/bind.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace contextual_suggestions {
diff --git a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
index 1b8a993618b..8d4b9411911 100644
--- a/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/contextual/contextual_suggestions_fetcher_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
diff --git a/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc b/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc
index 4cb15e96975..ba332a283b9 100644
--- a/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc
+++ b/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter_unittest.cc
@@ -37,7 +37,7 @@ class TestReporter : public ContextualSuggestionsReporter {
ukm::SourceId GetSourceId() { return source_id_; }
int GetNSetupForPage() { return called_setup_for_page_count_; }
int GetNRecordEvent() { return called_record_event_count_; }
- int GetNFlush() { return called_flush_count_; };
+ int GetNFlush() { return called_flush_count_; }
/* Static variables*/
static int GetReporterDestroyCount() { return reporter_destroy_count_; }
@@ -119,4 +119,4 @@ TEST(ContextualSuggestionsCompositeReporterTest, CheckOwnedDeleted) {
EXPECT_EQ(2, TestReporter::GetReporterDestroyCount());
}
-} // namespace contextual_suggestions \ No newline at end of file
+} // namespace contextual_suggestions
diff --git a/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc b/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc
index 579a8f81407..018c2eb5d55 100644
--- a/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc
+++ b/chromium/components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.cc
@@ -4,7 +4,6 @@
#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_reporter.h"
-#include "base/debug/stack_trace.h"
#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_composite_reporter.h"
#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_debugging_reporter.h"
#include "components/ntp_snippets/contextual/reporting/contextual_suggestions_metrics_reporter.h"
@@ -36,4 +35,4 @@ ContextualSuggestionsReporterProvider::GetDebuggingReporter() {
ContextualSuggestionsReporter::ContextualSuggestionsReporter() = default;
ContextualSuggestionsReporter::~ContextualSuggestionsReporter() = default;
-} // namespace contextual_suggestions \ No newline at end of file
+} // namespace contextual_suggestions
diff --git a/chromium/components/ntp_snippets/features.cc b/chromium/components/ntp_snippets/features.cc
index b3e424fe4cd..a8bd7d16746 100644
--- a/chromium/components/ntp_snippets/features.cc
+++ b/chromium/components/ntp_snippets/features.cc
@@ -31,7 +31,6 @@ const base::Feature* const kAllFeatures[] = {
&kIncreasedVisibility,
&kKeepPrefetchedContentSuggestions,
&kNotificationsFeature,
- &kPublisherFaviconsFromNewServerFeature,
&kRemoteSuggestionsBackendFeature};
const base::Feature kArticleSuggestionsFeature{
@@ -49,10 +48,6 @@ const base::Feature kBreakingNewsPushFeature{"BreakingNewsPush",
const base::Feature kCategoryRanker{"ContentSuggestionsCategoryRanker",
base::FEATURE_ENABLED_BY_DEFAULT};
-const base::Feature kPublisherFaviconsFromNewServerFeature{
- "ContentSuggestionsFaviconsFromNewServer",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kRemoteSuggestionsEmulateM58FetchingSchedule{
"RemoteSuggestionsEmulateM58FetchingSchedule",
base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromium/components/ntp_snippets/features.h b/chromium/components/ntp_snippets/features.h
index bec66958240..239998074fb 100644
--- a/chromium/components/ntp_snippets/features.h
+++ b/chromium/components/ntp_snippets/features.h
@@ -48,9 +48,6 @@ extern const base::Feature kBreakingNewsPushFeature;
// Feature to choose a category ranker.
extern const base::Feature kCategoryRanker;
-// Feature to allow the new Google favicon server for fetching publisher icons.
-extern const base::Feature kPublisherFaviconsFromNewServerFeature;
-
// Feature for simple experimental comparison and validation of changes since
// M58: enabling this brings back the M58 Stable fetching schedule (which is
// suitable for Holdback groups).
diff --git a/chromium/components/ntp_snippets/logger_unittest.cc b/chromium/components/ntp_snippets/logger_unittest.cc
index 595415abd7d..becf0383ac4 100644
--- a/chromium/components/ntp_snippets/logger_unittest.cc
+++ b/chromium/components/ntp_snippets/logger_unittest.cc
@@ -27,7 +27,7 @@ class LoggerTest : public ::testing::Test {
void EnableFeature() {
params_manager_.SetVariationParamsWithFeatureAssociations(
kContentSuggestionsDebugLog.name,
- {{"max_items_count", base::IntToString(kMaxItemsCount)}},
+ {{"max_items_count", base::NumberToString(kMaxItemsCount)}},
{kContentSuggestionsDebugLog.name});
}
diff --git a/chromium/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc b/chromium/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
index 0ee83c6920a..6bd01ecbb9b 100644
--- a/chromium/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
+++ b/chromium/components/ntp_snippets/offline_pages/offline_pages_test_utils.cc
@@ -65,7 +65,7 @@ std::vector<OfflinePageItem>* FakeOfflinePageModel::mutable_items() {
OfflinePageItem CreateDummyOfflinePageItem(
int id,
const offline_pages::ClientId& client_id) {
- std::string id_string = base::IntToString(id);
+ std::string id_string = base::NumberToString(id);
return OfflinePageItem(
GURL("http://dummy.com/" + id_string), id, client_id,
base::FilePath::FromUTF8Unsafe("some/folder/test" + id_string + ".mhtml"),
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 e4937822070..ed383e5ca4f 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
@@ -47,7 +47,7 @@ ReadingListSuggestionsProvider::ReadingListSuggestionsProvider(
scoped_observer_.Add(reading_list_model_);
}
-ReadingListSuggestionsProvider::~ReadingListSuggestionsProvider(){};
+ReadingListSuggestionsProvider::~ReadingListSuggestionsProvider() {}
CategoryStatus ReadingListSuggestionsProvider::GetCategoryStatus(
Category category) {
diff --git a/chromium/components/ntp_snippets/remote/cached_image_fetcher.cc b/chromium/components/ntp_snippets/remote/cached_image_fetcher.cc
index afbdf6f6987..181c4493eeb 100644
--- a/chromium/components/ntp_snippets/remote/cached_image_fetcher.cc
+++ b/chromium/components/ntp_snippets/remote/cached_image_fetcher.cc
@@ -15,7 +15,11 @@
#include "ui/gfx/image/image.h"
namespace ntp_snippets {
+
namespace {
+
+constexpr char kImageFetcherUmaClientName[] = "NtpSnippets";
+
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("remote_suggestions_provider", R"(
semantics {
@@ -50,11 +54,6 @@ CachedImageFetcher::CachedImageFetcher(
thumbnail_requests_throttler_(
pref_service,
RequestThrottler::RequestType::CONTENT_SUGGESTION_THUMBNAIL) {
- // |image_fetcher_| can be null in tests.
- if (image_fetcher_) {
- image_fetcher_->SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_SNIPPETS_THUMBNAILS);
- }
}
CachedImageFetcher::~CachedImageFetcher() {}
@@ -79,6 +78,13 @@ void CachedImageFetcher::OnImageDecodingDone(
std::move(callback).Run(image);
}
+void CachedImageFetcher::OnImageFetchingDone(
+ ImageFetchedCallback callback,
+ const gfx::Image& image,
+ const image_fetcher::RequestMetadata& metadata) {
+ std::move(callback).Run(image);
+}
+
void CachedImageFetcher::OnImageFetchedFromDatabase(
ImageDataFetchedCallback image_data_callback,
ImageFetchedCallback image_callback,
@@ -145,16 +151,18 @@ void CachedImageFetcher::FetchImageFromNetwork(
image_fetcher::ImageFetcherCallback decode_callback;
if (image_callback) {
decode_callback =
- base::BindOnce(&CachedImageFetcher::OnImageDecodingDone,
+ base::BindOnce(&CachedImageFetcher::OnImageFetchingDone,
base::Unretained(this), std::move(image_callback));
}
+ image_fetcher::ImageFetcherParams params(kTrafficAnnotation,
+ kImageFetcherUmaClientName);
image_fetcher_->FetchImageAndData(
- suggestion_id.id_within_category(), url,
+ url,
base::BindOnce(&CachedImageFetcher::SaveImageAndInvokeDataCallback,
base::Unretained(this), suggestion_id.id_within_category(),
std::move(image_data_callback)),
- std::move(decode_callback), kTrafficAnnotation);
+ std::move(decode_callback), std::move(params));
}
void CachedImageFetcher::SaveImageAndInvokeDataCallback(
diff --git a/chromium/components/ntp_snippets/remote/cached_image_fetcher.h b/chromium/components/ntp_snippets/remote/cached_image_fetcher.h
index d1e1c6d55d6..3a2e8ae0452 100644
--- a/chromium/components/ntp_snippets/remote/cached_image_fetcher.h
+++ b/chromium/components/ntp_snippets/remote/cached_image_fetcher.h
@@ -61,6 +61,10 @@ class CachedImageFetcher {
const gfx::Image& image,
const image_fetcher::RequestMetadata& metadata);
+ void OnImageFetchingDone(ImageFetchedCallback callback,
+ const gfx::Image& image,
+ const image_fetcher::RequestMetadata& metadata);
+
void OnImageFetchedFromDatabase(
ImageDataFetchedCallback image_data_callback,
ImageFetchedCallback image_callback,
diff --git a/chromium/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc b/chromium/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc
index ea87c039082..adc052fce2a 100644
--- a/chromium/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/cached_image_fetcher_unittest.cc
@@ -72,9 +72,10 @@ enum class TestType {
// This test is parameterized to run all tests in the three configurations:
// both callbacks used, only image_callback used, only image_data_callback used.
-class CachedImageFetcherTest : public testing::TestWithParam<TestType> {
+class NtpSnippetsCachedImageFetcherTest
+ : public testing::TestWithParam<TestType> {
public:
- CachedImageFetcherTest() {
+ NtpSnippetsCachedImageFetcherTest() {
EXPECT_TRUE(database_dir_.CreateUniqueTempDir());
RequestThrottler::RegisterProfilePrefs(pref_service_.registry());
@@ -95,7 +96,7 @@ class CachedImageFetcherTest : public testing::TestWithParam<TestType> {
EXPECT_TRUE(database_->IsInitialized());
}
- ~CachedImageFetcherTest() override {
+ ~NtpSnippetsCachedImageFetcherTest() override {
cached_image_fetcher_.reset();
database_.reset();
// We need to run until idle after deleting the database, because
@@ -157,10 +158,10 @@ class CachedImageFetcherTest : public testing::TestWithParam<TestType> {
TestingPrefServiceSimple pref_service_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
- DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherTest);
+ DISALLOW_COPY_AND_ASSIGN(NtpSnippetsCachedImageFetcherTest);
};
-TEST_P(CachedImageFetcherTest, FetchImageFromCache) {
+TEST_P(NtpSnippetsCachedImageFetcherTest, FetchImageFromCache) {
// Save the image in the database.
database()->SaveImage(kSnippetID, kImageData);
RunUntilIdle();
@@ -170,7 +171,7 @@ TEST_P(CachedImageFetcherTest, FetchImageFromCache) {
Fetch(kImageData, true);
}
-TEST_P(CachedImageFetcherTest, FetchImagePopulatesCache) {
+TEST_P(NtpSnippetsCachedImageFetcherTest, FetchImagePopulatesCache) {
// Expect the image to be fetched by URL.
{
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
@@ -183,7 +184,7 @@ TEST_P(CachedImageFetcherTest, FetchImagePopulatesCache) {
}
}
-TEST_P(CachedImageFetcherTest, FetchNonExistingImage) {
+TEST_P(NtpSnippetsCachedImageFetcherTest, FetchNonExistingImage) {
const std::string kErrorResponse = "error-response";
test_url_loader_factory()->AddResponse(kImageURL, kErrorResponse,
net::HTTP_NOT_FOUND);
@@ -191,10 +192,10 @@ TEST_P(CachedImageFetcherTest, FetchNonExistingImage) {
Fetch("", false);
}
-INSTANTIATE_TEST_CASE_P(,
- CachedImageFetcherTest,
- testing::Values(TestType::kImageCallback,
- TestType::kImageDataCallback,
- TestType::kBothCallbacks));
+INSTANTIATE_TEST_SUITE_P(,
+ NtpSnippetsCachedImageFetcherTest,
+ testing::Values(TestType::kImageCallback,
+ TestType::kImageDataCallback,
+ TestType::kBothCallbacks));
} // namespace ntp_snippets
diff --git a/chromium/components/ntp_snippets/remote/json_request.cc b/chromium/components/ntp_snippets/remote/json_request.cc
index b59800ee3d3..f2173097548 100644
--- a/chromium/components/ntp_snippets/remote/json_request.cc
+++ b/chromium/components/ntp_snippets/remote/json_request.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/metrics/histogram_functions.h"
@@ -288,8 +289,8 @@ JsonRequest::Builder::BuildResourceRequest() const {
// Add X-Client-Data header with experiment IDs from field trials.
// TODO: We should call AppendVariationHeaders with explicit
// variations::SignedIn::kNo If the auth_header_ is empty
- variations::AppendVariationHeadersUnknownSignedIn(
- url_, variations::InIncognito::kNo, &resource_request->headers);
+ variations::AppendVariationsHeaderUnknownSignedIn(
+ url_, variations::InIncognito::kNo, resource_request.get());
return resource_request;
}
diff --git a/chromium/components/ntp_snippets/remote/json_request_unittest.cc b/chromium/components/ntp_snippets/remote/json_request_unittest.cc
index 5207c2d65c3..863b6450d8a 100644
--- a/chromium/components/ntp_snippets/remote/json_request_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/json_request_unittest.cc
@@ -10,6 +10,7 @@
#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_mock_time_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -37,7 +38,8 @@ using testing::NotNull;
using testing::StrEq;
MATCHER_P(EqualsJSON, json, "equals JSON") {
- std::unique_ptr<base::Value> expected = base::JSONReader::Read(json);
+ std::unique_ptr<base::Value> expected =
+ base::JSONReader::ReadDeprecated(json);
if (!expected) {
*result_listener << "INTERNAL ERROR: couldn't parse expected JSON";
return false;
@@ -45,8 +47,9 @@ MATCHER_P(EqualsJSON, json, "equals JSON") {
std::string err_msg;
int err_line, err_col;
- std::unique_ptr<base::Value> actual = base::JSONReader::ReadAndReturnError(
- arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col);
+ std::unique_ptr<base::Value> actual =
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col);
if (!actual) {
*result_listener << "input:" << err_line << ":" << err_col << ": "
<< "parse error: " << err_msg;
@@ -66,6 +69,8 @@ class JsonRequestTest : public testing::Test {
{ntp_snippets::kArticleSuggestionsFeature.name}),
pref_service_(std::make_unique<TestingPrefServiceSimple>()),
mock_task_runner_(new base::TestMockTimeTaskRunner()),
+ mock_runner_handle_(
+ std::make_unique<base::ThreadTaskRunnerHandle>(mock_task_runner_)),
test_shared_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)) {
@@ -98,6 +103,7 @@ class JsonRequestTest : public testing::Test {
variations::testing::VariationParamsManager params_manager_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_;
+ std::unique_ptr<base::ThreadTaskRunnerHandle> mock_runner_handle_;
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
diff --git a/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
index d70dc347549..f9b5807e083 100644
--- a/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
+++ b/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -19,12 +19,6 @@ bool IsOfflineItemPrefetchedPage(const OfflinePageItem& offline_page_item) {
offline_pages::kSuggestedArticlesNamespace;
}
-const GURL& GetOfflinePageUrl(const OfflinePageItem& offline_page_item) {
- return offline_page_item.original_url != GURL()
- ? offline_page_item.original_url
- : offline_page_item.url;
-}
-
} // namespace
PrefetchedPagesTrackerImpl::PrefetchedPagesTrackerImpl(
@@ -119,7 +113,7 @@ void PrefetchedPagesTrackerImpl::OfflinePagesLoaded(
void PrefetchedPagesTrackerImpl::AddOfflinePage(
const OfflinePageItem& offline_page_item) {
- const GURL& url = GetOfflinePageUrl(offline_page_item);
+ const GURL& url = offline_page_item.GetOriginalUrl();
DCHECK(prefetched_url_counts_.count(url) == 0 ||
prefetched_url_counts_.find(url)->second > 0);
++prefetched_url_counts_[url];
diff --git a/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc b/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
index 5563844a385..f58eaeacc1e 100644
--- a/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
@@ -42,7 +42,7 @@ OfflinePageItem CreateOfflinePageItem(const GURL& url,
static int id = 0;
++id;
return OfflinePageItem(
- url, id, offline_pages::ClientId(name_space, base::IntToString(id)),
+ url, id, offline_pages::ClientId(name_space, base::NumberToString(id)),
base::FilePath::FromUTF8Unsafe(
base::StringPrintf("some/folder/%d.mhtml", id)),
0, base::Time::Now());
@@ -140,7 +140,7 @@ TEST_F(PrefetchedPagesTrackerImplTest, ShouldDeletePrefetchedURLWhenNotified) {
tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
item.offline_id, kSystemDownloadId, item.client_id,
- /*request_origin=*/"", item.original_url));
+ /*request_origin=*/"", item.original_url_if_different));
EXPECT_FALSE(
tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}
@@ -163,7 +163,8 @@ TEST_F(PrefetchedPagesTrackerImplTest,
tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
manually_downloaded_item.offline_id, kSystemDownloadId,
manually_downloaded_item.client_id,
- /*request_origin=*/"", manually_downloaded_item.original_url));
+ /*request_origin=*/"",
+ manually_downloaded_item.original_url_if_different));
EXPECT_TRUE(
tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}
@@ -274,7 +275,7 @@ TEST_F(PrefetchedPagesTrackerImplTest,
tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
first_item.offline_id, kSystemDownloadId, first_item.client_id,
- /*request_origin=*/"", first_item.original_url));
+ /*request_origin=*/"", first_item.original_url_if_different));
// Only one offline page (out of two) has been removed, the remaining one
// should be reported here.
@@ -299,14 +300,14 @@ TEST_F(PrefetchedPagesTrackerImplTest,
tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
first_item.offline_id, kSystemDownloadId, first_item.client_id,
- /*request_origin=*/"", first_item.original_url));
+ /*request_origin=*/"", first_item.original_url_if_different));
ASSERT_TRUE(
tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
second_item.offline_id, kSystemDownloadId, second_item.client_id,
- /*request_origin=*/"", second_item.original_url));
+ /*request_origin=*/"", second_item.original_url_if_different));
// All offline pages have been removed, their absence should be reported here.
EXPECT_FALSE(
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestion_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestion_unittest.cc
index f3e3a2687c5..d7437fbb477 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestion_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestion_unittest.cc
@@ -27,7 +27,7 @@ using ::testing::NotNull;
std::unique_ptr<RemoteSuggestion> SnippetFromContentSuggestionJSON(
const std::string& json,
const base::Time& fetch_date) {
- auto json_value = base::JSONReader::Read(json);
+ auto json_value = base::JSONReader::ReadDeprecated(json);
base::DictionaryValue* json_dict;
if (!json_value->GetAsDictionary(&json_dict)) {
return nullptr;
@@ -210,7 +210,7 @@ std::unique_ptr<base::DictionaryValue> ContentSuggestionSnippet() {
"score": 9001
}
)";
- auto json_value = base::JSONReader::Read(kJsonStr);
+ auto json_value = base::JSONReader::ReadDeprecated(kJsonStr);
base::DictionaryValue* json_dict;
CHECK(json_value->GetAsDictionary(&json_dict));
return json_dict->CreateDeepCopy();
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_database.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_database.cc
index 780b544dce3..72b8d04c682 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_database.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_database.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/system/sys_info.h"
#include "base/task/post_task.h"
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
index b5993fa2f93..256ce45e05e 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
@@ -4,6 +4,7 @@
#include "components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h"
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
@@ -193,6 +194,10 @@ const GURL& RemoteSuggestionsFetcherImpl::GetFetchUrlForDebugging() const {
void RemoteSuggestionsFetcherImpl::FetchSnippets(
const RequestParams& params,
SnippetsAvailableCallback callback) {
+ SnippetsAvailableCallback wrapped_callback = base::BindOnce(
+ &RemoteSuggestionsFetcherImpl::EmitDurationAndInvokeCallback,
+ base::Unretained(this), base::Time::Now(), std::move(callback));
+
if (!params.interactive_request) {
base::UmaHistogramSparse(
"NewTabPage.Snippets.FetchTimeLocal",
@@ -214,11 +219,12 @@ void RemoteSuggestionsFetcherImpl::FetchSnippets(
if (identity_manager_->HasPrimaryAccount()) {
// Signed-in: get OAuth token --> fetch suggestions.
- pending_requests_.emplace(std::move(builder), std::move(callback));
+ pending_requests_.emplace(std::move(builder), std::move(wrapped_callback));
StartTokenRequest();
} else {
// Not signed in: fetch suggestions (without authentication).
- FetchSnippetsNonAuthenticated(std::move(builder), std::move(callback));
+ FetchSnippetsNonAuthenticated(std::move(builder),
+ std::move(wrapped_callback));
}
}
@@ -275,20 +281,29 @@ void RemoteSuggestionsFetcherImpl::StartTokenRequest() {
return;
}
+ base::Time token_start_time = clock_->Now();
identity::ScopeSet scopes{kContentSuggestionsApiScope};
token_fetcher_ = std::make_unique<identity::PrimaryAccountAccessTokenFetcher>(
"ntp_snippets", identity_manager_, scopes,
base::BindOnce(&RemoteSuggestionsFetcherImpl::AccessTokenFetchFinished,
- base::Unretained(this)),
+ base::Unretained(this), token_start_time),
identity::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
}
void RemoteSuggestionsFetcherImpl::AccessTokenFetchFinished(
+ base::Time token_start_time,
GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info) {
DCHECK(token_fetcher_);
token_fetcher_.reset();
+ UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.Network.TokenFetchStatus",
+ error.state(), GoogleServiceAuthError::NUM_STATES);
+
+ base::TimeDelta token_duration = clock_->Now() - token_start_time;
+ UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.TokenDuration",
+ token_duration);
+
if (error.state() != GoogleServiceAuthError::NONE) {
AccessTokenError(error);
return;
@@ -309,7 +324,6 @@ void RemoteSuggestionsFetcherImpl::AccessTokenFetchFinished(
void RemoteSuggestionsFetcherImpl::AccessTokenError(
const GoogleServiceAuthError& error) {
DCHECK_NE(error.state(), GoogleServiceAuthError::NONE);
-
DLOG(ERROR) << "Unable to get token: " << error.ToString();
while (!pending_requests_.empty()) {
@@ -342,7 +356,6 @@ void RemoteSuggestionsFetcherImpl::JsonRequestDone(
UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime",
request->GetFetchDuration());
-
if (!result) {
FetchFinished(OptionalFetchedCategories(), std::move(callback), status_code,
error_details, is_authenticated, access_token);
@@ -396,6 +409,17 @@ void RemoteSuggestionsFetcherImpl::FetchFinished(
std::move(categories));
}
+void RemoteSuggestionsFetcherImpl::EmitDurationAndInvokeCallback(
+ base::Time start_time,
+ SnippetsAvailableCallback callback,
+ Status status,
+ OptionalFetchedCategories fetched_categories) {
+ base::TimeDelta duration = clock_->Now() - start_time;
+ UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.Duration",
+ duration);
+ std::move(callback).Run(status, std::move(fetched_categories));
+}
+
// static
void RemoteSuggestionsFetcherImpl::set_skip_api_key_check_for_testing() {
skip_api_key_check_for_testing_ = true;
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
index e29a7c4aa4e..a7553fd8895 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
@@ -83,7 +83,8 @@ class RemoteSuggestionsFetcherImpl : public RemoteSuggestionsFetcher {
void StartTokenRequest();
- void AccessTokenFetchFinished(GoogleServiceAuthError error,
+ void AccessTokenFetchFinished(base::Time token_start_time,
+ GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info);
void AccessTokenError(const GoogleServiceAuthError& error);
@@ -100,6 +101,11 @@ class RemoteSuggestionsFetcherImpl : public RemoteSuggestionsFetcher {
const std::string& error_details,
bool is_authenticated,
std::string access_token);
+ void EmitDurationAndInvokeCallback(
+ base::Time start_time,
+ SnippetsAvailableCallback callback,
+ Status status,
+ OptionalFetchedCategories fetched_categories);
// Authentication for signed-in users.
identity::IdentityManager* identity_manager_;
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
index 5cd58caecab..f0a0e561ecb 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/json/json_reader.h"
#include "base/optional.h"
@@ -150,7 +151,7 @@ void ParseJson(const std::string& json,
const SuccessCallback& success_callback,
const ErrorCallback& error_callback) {
base::JSONReader json_reader;
- std::unique_ptr<base::Value> value = json_reader.ReadToValue(json);
+ std::unique_ptr<base::Value> value = json_reader.ReadToValueDeprecated(json);
if (value) {
success_callback.Run(std::move(value));
} else {
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 94549ac8463..4c5e4fc8d69 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
@@ -11,6 +11,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
@@ -164,14 +165,13 @@ std::unique_ptr<RemoteSuggestion> CreateTestRemoteSuggestion(
}
void ServeOneByOneImage(
- const std::string& id,
image_fetcher::ImageDataFetcherCallback* image_data_callback,
image_fetcher::ImageFetcherCallback* callback) {
std::move(*image_data_callback)
.Run("1-by-1-image-data", image_fetcher::RequestMetadata());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(*callback), id, gfx::test::CreateImage(1, 1),
+ base::BindOnce(std::move(*callback), gfx::test::CreateImage(1, 1),
image_fetcher::RequestMetadata()));
}
@@ -615,9 +615,9 @@ class RemoteSuggestionsProviderImplTest : public ::testing::Test {
kKeepPrefetchedContentSuggestions.name,
{
{"max_additional_prefetched_suggestions",
- base::IntToString(max_additional_prefetched_suggestions)},
+ base::NumberToString(max_additional_prefetched_suggestions)},
{"max_age_for_additional_prefetched_suggestion_minutes",
- base::IntToString(
+ base::NumberToString(
max_age_for_additional_prefetched_suggestion.InMinutes())},
},
{kKeepPrefetchedContentSuggestions.name});
@@ -668,7 +668,7 @@ class RemoteSuggestionsProviderImplTest : public ::testing::Test {
params_manager_.ClearAllVariationParams();
params_manager_.SetVariationParamsWithFeatureAssociations(
/*trial_name=*/kArticleSuggestionsFeature.name,
- {{"fetch_more_suggestions_count", base::IntToString(count)}},
+ {{"fetch_more_suggestions_count", base::NumberToString(count)}},
{kArticleSuggestionsFeature.name});
}
@@ -1325,8 +1325,8 @@ TEST_F(RemoteSuggestionsProviderImplTest,
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
auto serve_one_by_one_image_callback =
base::BindRepeating(&ServeOneByOneImage);
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(serve_one_by_one_image_callback))));
gfx::Image image = FetchImage(provider.get(), MakeArticleID("id"));
@@ -1397,8 +1397,8 @@ TEST_F(RemoteSuggestionsProviderImplTest,
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
auto serve_one_by_one_image_callback =
base::BindRepeating(&ServeOneByOneImage);
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(serve_one_by_one_image_callback))));
gfx::Image image = FetchImage(provider.get(), MakeArticleID("id"));
@@ -1565,9 +1565,9 @@ TEST_F(RemoteSuggestionsProviderImplTest,
Status::Success(), std::move(fetched_categories));
// Make sure images of both batches are available. This is to sanity check our
// assumptions for the test are right.
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
.Times(2)
- .WillRepeatedly(WithArgs<0, 2, 3>(
+ .WillRepeatedly(WithArgs<1, 2>(
Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage)))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
gfx::Image image = FetchImage(provider.get(), MakeArticleID("http://id-1"));
@@ -1730,8 +1730,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, Dismiss) {
ASSERT_THAT(provider->GetSuggestionsForTesting(articles_category()),
SizeIs(1));
// Load the image to store it in the database.
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage)))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
gfx::Image image =
@@ -1856,8 +1856,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, RemoveExpiredDismissedContent) {
// Load the image to store it in the database.
// TODO(tschumann): Introduce some abstraction to nicely work with image
// fetching expectations.
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage)))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
gfx::Image image = FetchImage(provider.get(), MakeArticleID("http://first/"));
@@ -2122,8 +2122,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ImageReturnedWithTheSameId) {
MockFunction<void(const gfx::Image&)> image_fetched;
{
InSequence s;
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage)))));
EXPECT_CALL(image_fetched, Call(_)).WillOnce(SaveArg<0>(&image));
}
@@ -2258,8 +2258,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldClearOrphanedImagesOnRestart) {
FetchTheseSuggestions(provider.get(), /*interactive_request=*/true,
Status::Success(), std::move(fetched_categories));
- EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _, _))
- .WillOnce(WithArgs<0, 2, 3>(
+ EXPECT_CALL(*image_fetcher(), FetchImageAndData_(_, _, _, _))
+ .WillOnce(WithArgs<1, 2>(
Invoke(CreateFunctor(base::BindRepeating(&ServeOneByOneImage)))));
image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1));
@@ -2498,7 +2498,7 @@ TEST_F(RemoteSuggestionsProviderImplTest,
std::set<std::string> known_ids;
for (int i = 0; i < 200; ++i) {
- known_ids.insert(base::IntToString(i));
+ known_ids.insert(base::NumberToString(i));
}
EXPECT_CALL(*scheduler(), AcquireQuotaForInteractiveFetch())
@@ -3381,7 +3381,7 @@ TEST_F(RemoteSuggestionsProviderImplTest,
FetchedCategoryBuilder category_builder =
FetchedCategoryBuilder().SetCategory(articles_category());
for (int i = 0; i < 10; ++i) {
- const std::string url = "http://other.com/" + base::IntToString(i);
+ const std::string url = "http://other.com/" + base::NumberToString(i);
category_builder.AddSuggestionViaBuilder(
RemoteSuggestionBuilder().AddId(url).SetUrl(url));
}
@@ -3407,7 +3407,7 @@ TEST_F(RemoteSuggestionsProviderImplTest,
for (int i = 0; i < 10; ++i) {
expected.push_back(
Property(&ContentSuggestion::id,
- MakeArticleID("http://other.com/" + base::IntToString(i))));
+ MakeArticleID("http://other.com/" + base::NumberToString(i))));
}
EXPECT_THAT(observer().SuggestionsForCategory(articles_category()),
@@ -3600,7 +3600,7 @@ TEST_F(RemoteSuggestionsProviderImplTest,
FetchedCategoryBuilder category_builder =
FetchedCategoryBuilder().SetCategory(articles_category());
for (int i = 0; i < 10; ++i) {
- const std::string url = "http://other.com/" + base::IntToString(i);
+ const std::string url = "http://other.com/" + base::NumberToString(i);
category_builder.AddSuggestionViaBuilder(
RemoteSuggestionBuilder().AddId(url).SetUrl(url));
}
@@ -3633,7 +3633,7 @@ TEST_F(RemoteSuggestionsProviderImplTest,
for (int i = 0; i < 10; ++i) {
expected.push_back(
Property(&ContentSuggestion::id,
- MakeArticleID("http://other.com/" + base::IntToString(i))));
+ MakeArticleID("http://other.com/" + base::NumberToString(i))));
}
EXPECT_THAT(observer().SuggestionsForCategory(articles_category()),
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 581c2ac2ebb..0225c52c87d 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
@@ -1201,7 +1201,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
ShouldNotRefetchWhileDisplayingBeforeConfigurableDelay) {
constexpr int kStaleHours = 18;
SetVariationParameter("min_age_for_stale_fetch_hours",
- base::IntToString(kStaleHours));
+ base::NumberToString(kStaleHours));
// Activating the provider should schedule the persistent background fetches.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
// First enable the scheduler -- this will trigger the persistent scheduling.
@@ -1230,7 +1230,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
ShouldRefetchWhileDisplayingAfterConfigurableDelay) {
constexpr int kStaleHours = 18;
SetVariationParameter("min_age_for_stale_fetch_hours",
- base::IntToString(kStaleHours));
+ base::NumberToString(kStaleHours));
// Activating the provider should schedule the persistent background fetches.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
// First enable the scheduler -- this will trigger the persistent scheduling.
@@ -1258,7 +1258,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
ShouldNotRefetchWhileDisplayingBeforeFallbackConfigurableDelay) {
constexpr int kStartupHours = 12;
SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
- base::IntToString(kStartupHours));
+ base::NumberToString(kStartupHours));
// Activating the provider should schedule the persistent background fetches.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
// First enable the scheduler -- this will trigger the persistent scheduling.
@@ -1287,7 +1287,7 @@ TEST_F(RemoteSuggestionsSchedulerImplTest,
ShouldRefetchWhileDisplayingAfterFallbackConfigurableDelay) {
constexpr int kStartupHours = 12;
SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
- base::IntToString(kStartupHours));
+ base::NumberToString(kStartupHours));
// Activating the provider should schedule the persistent background fetches.
EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
// First enable the scheduler -- this will trigger the persistent scheduling.
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc
index cbecb839e41..6d2c34d2a74 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "components/ntp_snippets/content_suggestions_metrics.h"
#include "components/ntp_snippets/features.h"
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc
index e83ea6cbcae..86ea8b5349d 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "build/build_config.h"
#include "components/ntp_snippets/features.h"
#include "components/ntp_snippets/ntp_snippets_constants.h"
diff --git a/chromium/components/ntp_snippets/user_classifier_unittest.cc b/chromium/components/ntp_snippets/user_classifier_unittest.cc
index 4c468831aa3..69e685e63de 100644
--- a/chromium/components/ntp_snippets/user_classifier_unittest.cc
+++ b/chromium/components/ntp_snippets/user_classifier_unittest.cc
@@ -293,7 +293,7 @@ TEST_P(UserClassifierMetricTest,
Eq(metric_after_a_year));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
, // An empty prefix for the parametrized tests names (no need to
// distinguish the only instance we make here).
UserClassifierMetricTest,
diff --git a/chromium/components/ntp_tiles/BUILD.gn b/chromium/components/ntp_tiles/BUILD.gn
index f91a1d4ab79..ec5c26da5e8 100644
--- a/chromium/components/ntp_tiles/BUILD.gn
+++ b/chromium/components/ntp_tiles/BUILD.gn
@@ -114,6 +114,7 @@ source_set("unit_tests") {
"//testing/gmock",
"//testing/gtest",
"//ui/base",
+ "//ui/base:test_support",
"//ui/gfx:test_support",
]
}
diff --git a/chromium/components/ntp_tiles/custom_links_manager_impl.cc b/chromium/components/ntp_tiles/custom_links_manager_impl.cc
index 6f7190bec3e..75bca9b0393 100644
--- a/chromium/components/ntp_tiles/custom_links_manager_impl.cc
+++ b/chromium/components/ntp_tiles/custom_links_manager_impl.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "components/ntp_tiles/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
diff --git a/chromium/components/ntp_tiles/custom_links_manager_impl_unittest.cc b/chromium/components/ntp_tiles/custom_links_manager_impl_unittest.cc
index eceabe13b59..88411c62530 100644
--- a/chromium/components/ntp_tiles/custom_links_manager_impl_unittest.cc
+++ b/chromium/components/ntp_tiles/custom_links_manager_impl_unittest.cc
@@ -51,11 +51,13 @@ const char kTestTitle[] = "Test";
const char kTestUrl[] = "http://test.com/";
base::Value::ListStorage FillTestListStorage(const char* url,
- const char* title) {
+ const char* title,
+ const bool is_most_visited) {
base::Value::ListStorage new_link_list;
base::DictionaryValue new_link;
new_link.SetKey("url", base::Value(url));
new_link.SetKey("title", base::Value(title));
+ new_link.SetKey("isMostVisited", base::Value(is_most_visited));
new_link_list.push_back(std::move(new_link));
return new_link_list;
}
@@ -495,6 +497,35 @@ TEST_F(CustomLinksManagerImplTest,
scoped_task_environment_.RunUntilIdle();
}
+TEST_F(CustomLinksManagerImplTest, ShouldDeleteOnHistoryDeletionAfterShutdown) {
+ // Initialize.
+ ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
+ ASSERT_EQ(FillTestLinks(kTestCase2), custom_links_->GetLinks());
+
+ // Simulate shutdown by recreating CustomLinksManagerImpl.
+ custom_links_.reset();
+ custom_links_ =
+ std::make_unique<CustomLinksManagerImpl>(&prefs_, history_service_.get());
+
+ // Set up Most Visited callback.
+ base::MockCallback<base::RepeatingClosure> callback;
+ std::unique_ptr<base::CallbackList<void()>::Subscription> subscription =
+ custom_links_->RegisterCallbackForOnChanged(callback.Get());
+
+ // Delete all Most Visited links.
+ EXPECT_CALL(callback, Run());
+ static_cast<history::HistoryServiceObserver*>(custom_links_.get())
+ ->OnURLsDeleted(
+ history_service_.get(),
+ history::DeletionInfo(history::DeletionTimeRange::AllTime(),
+ /*expired=*/false, history::URLRows(),
+ /*favicon_urls=*/std::set<GURL>(),
+ /*restrict_urls=*/base::nullopt));
+ EXPECT_TRUE(custom_links_->GetLinks().empty());
+
+ scoped_task_environment_.RunUntilIdle();
+}
+
TEST_F(CustomLinksManagerImplTest, ShouldNotDeleteCustomLinkOnHistoryDeletion) {
// Set up Most Visited callback.
base::MockCallback<base::RepeatingClosure> callback;
@@ -648,11 +679,11 @@ TEST_F(CustomLinksManagerImplTest, UpdateListAfterRemoteChange) {
// Modify the preference. This should notify and update the current list of
// links.
EXPECT_CALL(callback, Run());
- prefs_.SetUserPref(
- prefs::kCustomLinksList,
- std::make_unique<base::Value>(FillTestListStorage(kTestUrl, kTestTitle)));
+ prefs_.SetUserPref(prefs::kCustomLinksList,
+ std::make_unique<base::Value>(
+ FillTestListStorage(kTestUrl, kTestTitle, true)));
EXPECT_EQ(std::vector<Link>(
- {Link{GURL(kTestUrl), base::UTF8ToUTF16(kTestTitle), false}}),
+ {Link{GURL(kTestUrl), base::UTF8ToUTF16(kTestTitle), true}}),
custom_links_->GetLinks());
}
@@ -668,9 +699,9 @@ TEST_F(CustomLinksManagerImplTest, InitializeListAfterRemoteChange) {
EXPECT_CALL(callback, Run()).Times(2);
prefs_.SetUserPref(prefs::kCustomLinksInitialized,
std::make_unique<base::Value>(true));
- prefs_.SetUserPref(
- prefs::kCustomLinksList,
- std::make_unique<base::Value>(FillTestListStorage(kTestUrl, kTestTitle)));
+ prefs_.SetUserPref(prefs::kCustomLinksList,
+ std::make_unique<base::Value>(
+ FillTestListStorage(kTestUrl, kTestTitle, false)));
EXPECT_TRUE(custom_links_->IsInitialized());
EXPECT_EQ(std::vector<Link>(
{Link{GURL(kTestUrl), base::UTF8ToUTF16(kTestTitle), false}}),
diff --git a/chromium/components/ntp_tiles/custom_links_store.cc b/chromium/components/ntp_tiles/custom_links_store.cc
index 53f38616622..799e3c60176 100644
--- a/chromium/components/ntp_tiles/custom_links_store.cc
+++ b/chromium/components/ntp_tiles/custom_links_store.cc
@@ -22,6 +22,7 @@ namespace {
const char* kDictionaryKeyUrl = "url";
const char* kDictionaryKeyTitle = "title";
+const char* kDictionaryKeyIsMostVisited = "isMostVisited";
} // namespace
@@ -40,14 +41,20 @@ std::vector<CustomLinksManager::Link> CustomLinksStore::RetrieveLinks() {
for (const base::Value& link : stored_links->GetList()) {
const base::Value* url_value = link.FindKey(kDictionaryKeyUrl);
const base::Value* title_value = link.FindKey(kDictionaryKeyTitle);
+ const base::Value* mv_value = link.FindKey(kDictionaryKeyIsMostVisited);
+
GURL url = GURL(url_value->GetString());
if (!url_value || !title_value || !url.is_valid()) {
ClearLinks();
links.clear();
return links;
}
+ // Assume false if this value was not stored.
+ bool is_most_visited = mv_value ? mv_value->GetBool() : false;
+
links.emplace_back(CustomLinksManager::Link{
- std::move(url), base::UTF8ToUTF16(title_value->GetString())});
+ std::move(url), base::UTF8ToUTF16(title_value->GetString()),
+ is_most_visited});
}
return links;
}
@@ -59,6 +66,8 @@ void CustomLinksStore::StoreLinks(
base::DictionaryValue new_link;
new_link.SetKey(kDictionaryKeyUrl, base::Value(link.url.spec()));
new_link.SetKey(kDictionaryKeyTitle, base::Value(link.title));
+ new_link.SetKey(kDictionaryKeyIsMostVisited,
+ base::Value(link.is_most_visited));
new_link_list.push_back(std::move(new_link));
}
prefs_->Set(prefs::kCustomLinksList, base::Value(std::move(new_link_list)));
diff --git a/chromium/components/ntp_tiles/custom_links_store_unittest.cc b/chromium/components/ntp_tiles/custom_links_store_unittest.cc
index df4f394312d..efa4cfa186f 100644
--- a/chromium/components/ntp_tiles/custom_links_store_unittest.cc
+++ b/chromium/components/ntp_tiles/custom_links_store_unittest.cc
@@ -28,41 +28,42 @@ const char kTestUrl2[] = "http://foo2.com/";
class CustomLinksStoreTest : public testing::Test {
public:
- CustomLinksStoreTest() : custom_links_store_(&prefs_) {
+ CustomLinksStoreTest() {
+ custom_links_store_ = std::make_unique<CustomLinksStore>(&prefs_);
CustomLinksStore::RegisterProfilePrefs(prefs_.registry());
}
protected:
sync_preferences::TestingPrefServiceSyncable prefs_;
- CustomLinksStore custom_links_store_;
+ std::unique_ptr<CustomLinksStore> custom_links_store_;
DISALLOW_COPY_AND_ASSIGN(CustomLinksStoreTest);
};
TEST_F(CustomLinksStoreTest, StoreAndRetrieveLinks) {
std::vector<CustomLinksManager::Link> initial_links({CustomLinksManager::Link{
- GURL(kTestUrl1), base::UTF8ToUTF16(kTestTitle1)}});
+ GURL(kTestUrl1), base::UTF8ToUTF16(kTestTitle1), true}});
- custom_links_store_.StoreLinks(initial_links);
+ custom_links_store_->StoreLinks(initial_links);
std::vector<CustomLinksManager::Link> retrieved_links =
- custom_links_store_.RetrieveLinks();
+ custom_links_store_->RetrieveLinks();
EXPECT_EQ(initial_links, retrieved_links);
}
TEST_F(CustomLinksStoreTest, StoreEmptyList) {
std::vector<CustomLinksManager::Link> populated_links(
- {CustomLinksManager::Link{GURL(kTestUrl1),
- base::UTF8ToUTF16(kTestTitle1)},
- CustomLinksManager::Link{GURL(kTestUrl2),
- base::UTF8ToUTF16(kTestTitle2)}});
+ {CustomLinksManager::Link{GURL(kTestUrl1), base::UTF8ToUTF16(kTestTitle1),
+ false},
+ CustomLinksManager::Link{GURL(kTestUrl2), base::UTF8ToUTF16(kTestTitle2),
+ true}});
- custom_links_store_.StoreLinks(populated_links);
+ custom_links_store_->StoreLinks(populated_links);
std::vector<CustomLinksManager::Link> retrieved_links =
- custom_links_store_.RetrieveLinks();
+ custom_links_store_->RetrieveLinks();
ASSERT_EQ(populated_links, retrieved_links);
- custom_links_store_.StoreLinks(std::vector<CustomLinksManager::Link>());
- retrieved_links = custom_links_store_.RetrieveLinks();
+ custom_links_store_->StoreLinks(std::vector<CustomLinksManager::Link>());
+ retrieved_links = custom_links_store_->RetrieveLinks();
EXPECT_TRUE(retrieved_links.empty());
}
@@ -70,14 +71,33 @@ TEST_F(CustomLinksStoreTest, ClearLinks) {
std::vector<CustomLinksManager::Link> initial_links({CustomLinksManager::Link{
GURL(kTestUrl1), base::UTF8ToUTF16(kTestTitle1)}});
- custom_links_store_.StoreLinks(initial_links);
+ custom_links_store_->StoreLinks(initial_links);
std::vector<CustomLinksManager::Link> retrieved_links =
- custom_links_store_.RetrieveLinks();
+ custom_links_store_->RetrieveLinks();
ASSERT_EQ(initial_links, retrieved_links);
- custom_links_store_.ClearLinks();
- retrieved_links = custom_links_store_.RetrieveLinks();
+ custom_links_store_->ClearLinks();
+ retrieved_links = custom_links_store_->RetrieveLinks();
EXPECT_TRUE(retrieved_links.empty());
}
+TEST_F(CustomLinksStoreTest, LinksSavedAfterShutdown) {
+ std::vector<CustomLinksManager::Link> initial_links(
+ {CustomLinksManager::Link{GURL(kTestUrl1), base::UTF8ToUTF16(kTestTitle1),
+ false},
+ CustomLinksManager::Link{GURL(kTestUrl2), base::UTF8ToUTF16(kTestTitle2),
+ true}});
+
+ custom_links_store_->StoreLinks(initial_links);
+ std::vector<CustomLinksManager::Link> retrieved_links =
+ custom_links_store_->RetrieveLinks();
+ ASSERT_EQ(initial_links, retrieved_links);
+
+ // Simulate shutdown by recreating CustomLinksStore.
+ custom_links_store_.reset();
+ custom_links_store_ = std::make_unique<CustomLinksStore>(&prefs_);
+ retrieved_links = custom_links_store_->RetrieveLinks();
+ EXPECT_EQ(initial_links, retrieved_links);
+}
+
} // namespace ntp_tiles
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl.cc b/chromium/components/ntp_tiles/icon_cacher_impl.cc
index 90b95a2baad..a4a62030462 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl.cc
+++ b/chromium/components/ntp_tiles/icon_cacher_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "components/favicon/core/favicon_server_fetcher_params.h"
@@ -36,6 +37,8 @@ constexpr int kDesiredFrameSize = 128;
constexpr int kDefaultTileIconMinSizePx = 1;
constexpr int kDefaultTileIconDesiredSizePx = 96;
+const char kImageFetcherUmaClient[] = "IconCacher";
+
constexpr char kTileIconMinSizePxFieldParam[] = "min_size";
constexpr char kTileIconDesiredSizePxFieldParam[] = "desired_size";
@@ -79,11 +82,6 @@ IconCacherImpl::IconCacherImpl(
large_icon_service_(large_icon_service),
image_fetcher_(std::move(image_fetcher)),
weak_ptr_factory_(this) {
- image_fetcher_->SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES);
- // For images with multiple frames, prefer one of size 128x128px.
- image_fetcher_->SetDesiredImageFrameSize(
- gfx::Size(kDesiredFrameSize, kDesiredFrameSize));
}
IconCacherImpl::~IconCacherImpl() = default;
@@ -137,18 +135,21 @@ void IconCacherImpl::OnGetFaviconImageForPageURLFinished(
setting: "This feature cannot be disabled in settings."
policy_exception_justification: "Not implemented."
})");
+ image_fetcher::ImageFetcherParams params(traffic_annotation,
+ kImageFetcherUmaClient);
+ // For images with multiple frames, prefer one of size 128x128px.
+ params.set_frame_size(gfx::Size(kDesiredFrameSize, kDesiredFrameSize));
image_fetcher_->FetchImage(
- std::string(), IconURL(site),
+ IconURL(site),
base::BindOnce(&IconCacherImpl::OnPopularSitesFaviconDownloaded,
base::Unretained(this), site,
std::move(preliminary_callback)),
- traffic_annotation);
+ std::move(params));
}
void IconCacherImpl::OnPopularSitesFaviconDownloaded(
PopularSites::Site site,
std::unique_ptr<CancelableImageCallback> preliminary_callback,
- const std::string& id,
const gfx::Image& fetched_image,
const image_fetcher::RequestMetadata& metadata) {
if (fetched_image.IsEmpty()) {
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl.h b/chromium/components/ntp_tiles/icon_cacher_impl.h
index 671b02098e5..25d2deb63bd 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl.h
+++ b/chromium/components/ntp_tiles/icon_cacher_impl.h
@@ -69,7 +69,6 @@ class IconCacherImpl : public IconCacher {
void OnPopularSitesFaviconDownloaded(
PopularSites::Site site,
std::unique_ptr<CancelableImageCallback> preliminary_callback,
- const std::string& id,
const gfx::Image& fetched_image,
const image_fetcher::RequestMetadata& metadata);
diff --git a/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc b/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
index 3bcc854ae07..93f01503355 100644
--- a/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
+++ b/chromium/components/ntp_tiles/icon_cacher_impl_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
@@ -31,17 +32,19 @@
#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/mock_resource_bundle_delegate.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 image_fetcher::ImageFetcherParams;
using ::image_fetcher::MockImageFetcher;
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
-using ::testing::Invoke;
using ::testing::InSequence;
+using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::NiceMock;
using ::testing::Return;
@@ -51,39 +54,9 @@ namespace ntp_tiles {
namespace {
using MockImageDecoder = image_fetcher::MockImageDecoder;
-// This class provides methods to inject an image resource where a real resource
-// would be necessary otherwise. All other methods have return values that allow
-// the normal implementation to proceed.
-class MockResourceDelegate : public ui::ResourceBundle::Delegate {
- public:
- ~MockResourceDelegate() override {}
-
- MOCK_METHOD1(GetImageNamed, gfx::Image(int resource_id));
- MOCK_METHOD1(GetNativeImageNamed, gfx::Image(int resource_id));
-
- MOCK_METHOD2(GetPathForResourcePack,
- base::FilePath(const base::FilePath& pack_path,
- ui::ScaleFactor scale_factor));
-
- MOCK_METHOD2(GetPathForLocalePack,
- base::FilePath(const base::FilePath& pack_path,
- const std::string& locale));
-
- MOCK_METHOD2(LoadDataResourceBytes,
- base::RefCountedMemory*(int resource_id,
- ui::ScaleFactor scale_factor));
-
- MOCK_METHOD3(GetRawDataResource,
- bool(int resource_id,
- ui::ScaleFactor scale_factor,
- base::StringPiece* value));
-
- MOCK_METHOD2(GetLocalizedString, bool(int message_id, base::string16* value));
-};
-
ACTION(FailFetch) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(*arg3), arg0, gfx::Image(),
+ FROM_HERE, base::BindOnce(std::move(*arg2), gfx::Image(),
image_fetcher::RequestMetadata()));
}
@@ -94,9 +67,9 @@ ACTION_P2(DecodeSuccessfully, width, height) {
ACTION_P2(PassFetch, width, height) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(*arg3), arg0,
- gfx::test::CreateImage(width, height),
- image_fetcher::RequestMetadata()));
+ FROM_HERE,
+ base::BindOnce(std::move(*arg2), gfx::test::CreateImage(width, height),
+ image_fetcher::RequestMetadata()));
}
ACTION_P(Quit, run_loop) {
@@ -213,21 +186,14 @@ class IconCacherTestPopularSites : public IconCacherTestBase {
PopularSites::Site site_;
std::unique_ptr<MockImageFetcher> image_fetcher_;
std::unique_ptr<MockImageDecoder> image_decoder_;
- NiceMock<MockResourceDelegate> mock_resource_delegate_;
+ NiceMock<ui::MockResourceBundleDelegate> 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;
- {
- InSequence s;
- EXPECT_CALL(*image_fetcher_,
- SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
- }
+
PreloadIcon(site_.url, site_.large_icon_url,
favicon_base::IconType::kTouchIcon, 128, 128);
IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
@@ -247,11 +213,7 @@ TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchSucceeded) {
{
InSequence s;
EXPECT_CALL(*image_fetcher_,
- SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
- EXPECT_CALL(*image_fetcher_,
- FetchImageAndData_(_, site_.large_icon_url, _, _, _))
+ FetchImageAndData_(site_.large_icon_url, _, _, _))
.WillOnce(PassFetch(128, 128));
EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
}
@@ -273,12 +235,7 @@ TEST_F(IconCacherTestPopularSites, SmallNotCachedAndFetchSucceeded) {
base::RunLoop loop;
{
InSequence s;
- EXPECT_CALL(*image_fetcher_,
- SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
- EXPECT_CALL(*image_fetcher_,
- FetchImageAndData_(_, site_.favicon_url, _, _, _))
+ EXPECT_CALL(*image_fetcher_, FetchImageAndData_(site_.favicon_url, _, _, _))
.WillOnce(PassFetch(128, 128));
EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
}
@@ -297,11 +254,7 @@ TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchFailed) {
{
InSequence s;
EXPECT_CALL(*image_fetcher_,
- SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
- EXPECT_CALL(*image_fetcher_,
- FetchImageAndData_(_, site_.large_icon_url, _, _, _))
+ FetchImageAndData_(site_.large_icon_url, _, _, _))
.WillOnce(FailFetch());
}
@@ -317,9 +270,7 @@ TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchFailed) {
TEST_F(IconCacherTestPopularSites, HandlesEmptyCallbacksNicely) {
base::HistogramTester histogram_tester;
- EXPECT_CALL(*image_fetcher_, SetDataUseServiceName(_));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(_));
- EXPECT_CALL(*image_fetcher_, FetchImageAndData_(_, _, _, _, _))
+ EXPECT_CALL(*image_fetcher_, FetchImageAndData_(_, _, _, _))
.WillOnce(PassFetch(128, 128));
IconCacherImpl cacher(&favicon_service_, nullptr, std::move(image_fetcher_));
cacher.StartFetchPopularSites(site_, base::Closure(), base::Closure());
@@ -352,11 +303,7 @@ TEST_F(IconCacherTestPopularSites, ProvidesDefaultIconAndSucceedsWithFetching) {
{
InSequence s;
EXPECT_CALL(*image_fetcher_,
- SetDataUseServiceName(
- data_use_measurement::DataUseUserData::NTP_TILES));
- EXPECT_CALL(*image_fetcher_, SetDesiredImageFrameSize(gfx::Size(128, 128)));
- EXPECT_CALL(*image_fetcher_,
- FetchImageAndData_(_, site_.large_icon_url, _, _, _))
+ FetchImageAndData_(site_.large_icon_url, _, _, _))
.WillOnce(PassFetch(128, 128));
// Both callback are called async after the request but preliminary has to
@@ -393,13 +340,8 @@ TEST_F(IconCacherTestPopularSites, LargeNotCachedAndFetchPerformedOnlyOnce) {
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_,
- FetchImageAndData_(_, site_.large_icon_url, _, _, _))
+ FetchImageAndData_(site_.large_icon_url, _, _, _))
.WillOnce(PassFetch(128, 128));
// Success will be notified to both requests.
EXPECT_CALL(done, Run()).WillOnce(Return()).WillOnce(Quit(&loop));
@@ -419,16 +361,7 @@ class IconCacherTestMostLikely : public IconCacherTestBase {
: fetcher_for_large_icon_service_(
std::make_unique<::testing::StrictMock<MockImageFetcher>>()),
fetcher_for_icon_cacher_(
- std::make_unique<::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)));
- }
+ std::make_unique<::testing::StrictMock<MockImageFetcher>>()) {}
std::unique_ptr<MockImageFetcher> fetcher_for_large_icon_service_;
std::unique_ptr<MockImageFetcher> fetcher_for_icon_cacher_;
@@ -466,11 +399,9 @@ TEST_F(IconCacherTestMostLikely, NotCachedAndFetchSucceeded) {
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_,
- FetchImageAndData_(_, _, _, _, _))
+ FetchImageAndData_(_, _, _, _))
.WillOnce(PassFetch(128, 128));
EXPECT_CALL(done, Run()).WillOnce(Quit(&loop));
}
@@ -504,11 +435,9 @@ TEST_F(IconCacherTestMostLikely, NotCachedAndFetchFailed) {
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_,
- FetchImageAndData_(_, _, _, _, _))
+ FetchImageAndData_(_, _, _, _))
.WillOnce(FailFetch());
EXPECT_CALL(done, Run()).Times(0);
}
@@ -538,9 +467,7 @@ TEST_F(IconCacherTestMostLikely, NotCachedAndFetchFailed) {
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_,
- FetchImageAndData_(_, _, _, _, _))
+ EXPECT_CALL(*fetcher_for_large_icon_service_, FetchImageAndData_(_, _, _, _))
.WillOnce(PassFetch(128, 128));
favicon::LargeIconServiceImpl large_icon_service(
@@ -573,12 +500,9 @@ TEST_F(IconCacherTestMostLikely, NotCachedAndFetchPerformedOnlyOnce) {
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_,
- FetchImageAndData_(_, _, _, _, _))
+ FetchImageAndData_(_, _, _, _))
.WillOnce(PassFetch(128, 128));
// Success will be notified to both requests.
EXPECT_CALL(done, Run()).WillOnce(Return()).WillOnce(Quit(&loop));
diff --git a/chromium/components/ntp_tiles/json_unsafe_parser.cc b/chromium/components/ntp_tiles/json_unsafe_parser.cc
index 863aa5c4448..e1281f00050 100644
--- a/chromium/components/ntp_tiles/json_unsafe_parser.cc
+++ b/chromium/components/ntp_tiles/json_unsafe_parser.cc
@@ -25,7 +25,7 @@ void JsonUnsafeParser::Parse(const std::string& unsafe_json,
std::string error_msg;
int error_line, error_column;
std::unique_ptr<base::Value> value =
- base::JSONReader::ReadAndReturnError(
+ base::JSONReader::ReadAndReturnErrorDeprecated(
unsafe_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr,
&error_msg, &error_line, &error_column);
if (value) {
diff --git a/chromium/components/ntp_tiles/most_visited_sites.cc b/chromium/components/ntp_tiles/most_visited_sites.cc
index 40c097c8005..8a036163f5e 100644
--- a/chromium/components/ntp_tiles/most_visited_sites.cc
+++ b/chromium/components/ntp_tiles/most_visited_sites.cc
@@ -718,8 +718,7 @@ void MostVisitedSites::BuildCustomLinks(
tile.title = link.title;
tile.url = link.url;
tile.source = TileSource::CUSTOM_LINKS;
- // TODO(crbug.com/773278): Populate |data_generation_time| here in order to
- // log UMA metrics of age.
+ tile.from_most_visited = link.is_most_visited;
tiles.push_back(std::move(tile));
}
diff --git a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
index 67b247c3ad4..e6080d3a3e3 100644
--- a/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
+++ b/chromium/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -14,6 +14,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/callback_list.h"
#include "base/command_line.h"
#include "base/macros.h"
@@ -1014,9 +1015,9 @@ TEST_P(MostVisitedSitesTest, ShouldHandleTopSitesCacheHit) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(MostVisitedSitesTest,
- MostVisitedSitesTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(MostVisitedSitesTest,
+ MostVisitedSitesTest,
+ ::testing::Bool());
TEST(MostVisitedSitesTest, ShouldDeduplicateDomainWithNoWwwDomain) {
EXPECT_TRUE(MostVisitedSites::IsHostOrMobilePageKnown({"www.mobile.de"},
@@ -1514,9 +1515,9 @@ TEST_P(MostVisitedSitesWithCustomLinksTest,
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(MostVisitedSitesWithCustomLinksTest,
- MostVisitedSitesWithCustomLinksTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithCustomLinksTest,
+ MostVisitedSitesWithCustomLinksTest,
+ ::testing::Bool());
#endif
class MostVisitedSitesWithCacheHitTest : public MostVisitedSitesTest {
@@ -1674,9 +1675,9 @@ TEST_P(MostVisitedSitesWithCacheHitTest, ShouldFetchFaviconsIfEnabled) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(MostVisitedSitesWithCacheHitTest,
- MostVisitedSitesWithCacheHitTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithCacheHitTest,
+ MostVisitedSitesWithCacheHitTest,
+ ::testing::Bool());
class MostVisitedSitesWithEmptyCacheTest : public MostVisitedSitesTest {
public:
@@ -1965,9 +1966,9 @@ TEST_P(MostVisitedSitesWithEmptyCacheTest,
}
}
-INSTANTIATE_TEST_CASE_P(MostVisitedSitesWithEmptyCacheTest,
- MostVisitedSitesWithEmptyCacheTest,
- ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(MostVisitedSitesWithEmptyCacheTest,
+ MostVisitedSitesWithEmptyCacheTest,
+ ::testing::Bool());
// This a test for MostVisitedSites::MergeTiles(...) method, and thus has the
// same scope as the method itself. This tests merging popular sites with
diff --git a/chromium/components/ntp_tiles/ntp_tile.cc b/chromium/components/ntp_tiles/ntp_tile.cc
index 73a4fac924d..0df7832f656 100644
--- a/chromium/components/ntp_tiles/ntp_tile.cc
+++ b/chromium/components/ntp_tiles/ntp_tile.cc
@@ -17,7 +17,8 @@ bool operator==(const NTPTile& a, const NTPTile& b) {
return (a.title == b.title) && (a.url == b.url) && (a.source == b.source) &&
(a.title_source == b.title_source) &&
(a.whitelist_icon_path == b.whitelist_icon_path) &&
- (a.favicon_url == b.favicon_url);
+ (a.favicon_url == b.favicon_url) &&
+ (a.from_most_visited == b.from_most_visited);
}
bool operator!=(const NTPTile& a, const NTPTile& b) {
diff --git a/chromium/components/ntp_tiles/ntp_tile.h b/chromium/components/ntp_tiles/ntp_tile.h
index 1b5970f5f21..21caea35afe 100644
--- a/chromium/components/ntp_tiles/ntp_tile.h
+++ b/chromium/components/ntp_tiles/ntp_tile.h
@@ -36,6 +36,10 @@ struct NTPTile {
// a ranking algorithm).
base::Time data_generation_time;
+ // True if this tile is a custom link and was initialized from a Most Visited
+ // item. Used for debugging.
+ bool from_most_visited = false;
+
NTPTile();
NTPTile(const NTPTile&);
~NTPTile();
diff --git a/chromium/components/ntp_tiles/popular_sites_impl.cc b/chromium/components/ntp_tiles/popular_sites_impl.cc
index 5ce49d80545..02380d5d43a 100644
--- a/chromium/components/ntp_tiles/popular_sites_impl.cc
+++ b/chromium/components/ntp_tiles/popular_sites_impl.cc
@@ -214,15 +214,15 @@ void SetDefaultResourceForSite(int index,
#endif
// Creates the list of popular sites based on a snapshot available for mobile.
-std::unique_ptr<base::ListValue> DefaultPopularSites() {
+base::Value DefaultPopularSites() {
#if !defined(OS_ANDROID) && !defined(OS_IOS)
- return std::make_unique<base::ListValue>();
+ return base::Value(base::Value::Type::LIST);
#else
if (!base::FeatureList::IsEnabled(kPopularSitesBakedInContentFeature)) {
- return std::make_unique<base::ListValue>();
+ return base::Value(base::Value::Type::LIST);
}
std::unique_ptr<base::ListValue> sites =
- base::ListValue::From(base::JSONReader::Read(
+ base::ListValue::From(base::JSONReader::ReadDeprecated(
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_DEFAULT_POPULAR_SITES_JSON)));
DCHECK(sites);
@@ -240,7 +240,7 @@ std::unique_ptr<base::ListValue> DefaultPopularSites() {
SetDefaultResourceForSite(index++, icon_resource, sites.get());
}
#endif // GOOGLE_CHROME_BUILD
- return sites;
+ return base::Value::FromUniquePtrValue(std::move(sites));
#endif // OS_ANDROID || OS_IOS
}
diff --git a/chromium/components/ntp_tiles/tile_source.h b/chromium/components/ntp_tiles/tile_source.h
index 165aa71809f..0d26c2a350e 100644
--- a/chromium/components/ntp_tiles/tile_source.h
+++ b/chromium/components/ntp_tiles/tile_source.h
@@ -7,7 +7,8 @@
namespace ntp_tiles {
-// The source of an NTP tile.
+// The source of an NTP tile. Please update webui/ntp-tiles-internals* as well
+// when modifying these values.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.suggestions
enum class TileSource {
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 30a35ba0ce4..fdbadcbc115 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
@@ -100,6 +100,7 @@ void NTPTilesInternalsMessageHandler::HandleRegisterForEvents(
disabled.SetBoolean("topSites", false);
disabled.SetBoolean("suggestionsService", false);
disabled.SetBoolean("popular", false);
+ disabled.SetBoolean("customLinks", false);
disabled.SetBoolean("whitelist", false);
client_->CallJavascriptFunction(
"chrome.ntp_tiles_internals.receiveSourceInfo", disabled);
@@ -208,6 +209,8 @@ void NTPTilesInternalsMessageHandler::SendSourceInfo() {
value.SetBoolean("topSites",
most_visited_sites_->DoesSourceExist(TileSource::TOP_SITES));
+ value.SetBoolean("customLinks", most_visited_sites_->DoesSourceExist(
+ TileSource::CUSTOM_LINKS));
value.SetBoolean("whitelist",
most_visited_sites_->DoesSourceExist(TileSource::WHITELIST));
@@ -257,6 +260,9 @@ void NTPTilesInternalsMessageHandler::SendTiles(
entry->SetInteger("source", static_cast<int>(tile.source));
entry->SetString("whitelistIconPath",
tile.whitelist_icon_path.LossyDisplayName());
+ if (tile.source == TileSource::CUSTOM_LINKS) {
+ entry->SetBoolean("fromMostVisited", tile.from_most_visited);
+ }
auto icon_list = std::make_unique<base::ListValue>();
for (const auto& entry : kIconTypesAndNames) {
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 b83d02cb140..ea76d561e5b 100644
--- a/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
+++ b/chromium/components/ntp_tiles/webui/resources/ntp_tiles_internals.html
@@ -86,6 +86,16 @@ found in the LICENSE file.
<td class="value">no</td>
</tr>
</tbody>
+ <tbody jsselect="customLinks">
+ <tr>
+ <th colspan="2">CUSTOM_LINKS</th>
+ </tr>
+ <tr>
+ <td class="detail">enabled</td>
+ <td class="value" jsdisplay="$this">yes</td>
+ <td class="value" jsdisplay="!$this">no</td>
+ </tr>
+ </tbody>
<tbody jsselect="whitelist">
<tr>
<th colspan="2">WHITELIST</th>
@@ -116,9 +126,10 @@ found in the LICENSE file.
<td class="value" jsdisplay="source == 1">SUGGESTIONS_SERVICE</td>
<td class="value" jsdisplay="source == 2">POPULAR</td>
<td class="value" jsdisplay="source == 3">POPULAR_BAKED_IN</td>
- <td class="value" jsdisplay="source == 4">WHITELIST</td>
- <td class="value" jsdisplay="source == 5">HOMEPAGE</td>
- <td class="value" jsdisplay="source &gt; 5">???</td>
+ <td class="value" jsdisplay="source == 4">CUSTOM_LINKS</td>
+ <td class="value" jsdisplay="source == 5">WHITELIST</td>
+ <td class="value" jsdisplay="source == 6">HOMEPAGE</td>
+ <td class="value" jsdisplay="source &gt; 6">???</td>
</tr>
<tr>
<td class="detail">URL</td>
@@ -132,6 +143,11 @@ found in the LICENSE file.
<span class="value" jsdisplay="onDemand">, on-demand</span>)
</td>
</tr>
+ <tr jsdisplay="fromMostVisited != null">
+ <td class="detail">From Most Visited</td>
+ <td class="value" jsdisplay="fromMostVisited">yes</td>
+ <td class="value" jsdisplay="!fromMostVisited">no</td>
+ </tr>
</tbody>
</table>
</div>
diff --git a/chromium/components/offline_items_collection/core/BUILD.gn b/chromium/components/offline_items_collection/core/BUILD.gn
index 430c73c01ea..e3a512234cb 100644
--- a/chromium/components/offline_items_collection/core/BUILD.gn
+++ b/chromium/components/offline_items_collection/core/BUILD.gn
@@ -21,6 +21,7 @@ static_library("core") {
"offline_item_filter.h",
"offline_item_state.h",
"pending_state.h",
+ "rename_result.h",
"throttled_offline_content_provider.cc",
"throttled_offline_content_provider.h",
]
@@ -118,6 +119,7 @@ if (is_android) {
"offline_item_filter.h",
"offline_item_state.h",
"pending_state.h",
+ "rename_result.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 8daa37af288..67be1b540f8 100644
--- a/chromium/components/offline_items_collection/core/offline_content_aggregator.cc
+++ b/chromium/components/offline_items_collection/core/offline_content_aggregator.cc
@@ -40,7 +40,7 @@ std::string OfflineContentAggregator::CreateUniqueNameSpace(
return prefix;
static int num_registrations = 0;
- return prefix + "_" + base::IntToString(++num_registrations);
+ return prefix + "_" + base::NumberToString(++num_registrations);
}
void OfflineContentAggregator::RegisterProvider(
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 986ba11acf3..e5951e19c79 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
@@ -6,6 +6,7 @@
#include <map>
+#include "base/bind.h"
#include "base/test/bind_test_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/offline_items_collection/core/rename_result.h b/chromium/components/offline_items_collection/core/rename_result.h
new file mode 100644
index 00000000000..3b47c8e974d
--- /dev/null
+++ b/chromium/components/offline_items_collection/core/rename_result.h
@@ -0,0 +1,19 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OFFLINE_ITEMS_COLLECTION_CORE_RENAME_RESULT_H_
+#define COMPONENTS_OFFLINE_ITEMS_COLLECTION_CORE_RENAME_RESULT_H_
+
+// The type of download rename dialog that should by shown by Android.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.offline_items_collection
+enum class RenameResult {
+ SUCCESS = 0, // Rename filename successfully
+ FAILURE_NAME_CONFLICT = 1, // Filename already exists
+ FAILURE_NAME_TOO_LONG = 2, // Illegal file name: too long
+ FAILURE_UNKNOWN = 3, // Unknown
+ kMaxValue = FAILURE_UNKNOWN
+};
+
+#endif // COMPONENTS_OFFLINE_ITEMS_COLLECTION_CORE_RENAME_RESULT_H_
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 6a5ae1c46f8..96f4234e20f 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
@@ -4,6 +4,7 @@
#include "components/offline_items_collection/core/offline_content_aggregator.h"
+#include "base/bind.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
diff --git a/chromium/components/offline_pages/content/background_loader/DEPS b/chromium/components/offline_pages/content/background_loader/DEPS
index d79a7d00f02..b54fdf66a92 100644
--- a/chromium/components/offline_pages/content/background_loader/DEPS
+++ b/chromium/components/offline_pages/content/background_loader/DEPS
@@ -1,4 +1,5 @@
include_rules = [
"+content/public/browser",
"+content/public/test",
+ "+content/public/common/window_container_type.mojom-shared.h",
]
diff --git a/chromium/components/offline_pages/content/background_loader/background_loader_contents_unittest.cc b/chromium/components/offline_pages/content/background_loader/background_loader_contents_unittest.cc
index 768322b3fd7..a139e1286cc 100644
--- a/chromium/components/offline_pages/content/background_loader/background_loader_contents_unittest.cc
+++ b/chromium/components/offline_pages/content/background_loader/background_loader_contents_unittest.cc
@@ -4,8 +4,10 @@
#include "components/offline_pages/content/background_loader/background_loader_contents.h"
+#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/window_container_type.mojom-shared.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -54,9 +56,9 @@ BackgroundLoaderContentsTest::BackgroundLoaderContentsTest()
: download_(false),
delegate_called_(false),
waiter_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED){};
+ base::WaitableEvent::InitialState::NOT_SIGNALED) {}
-BackgroundLoaderContentsTest::~BackgroundLoaderContentsTest(){};
+BackgroundLoaderContentsTest::~BackgroundLoaderContentsTest() {}
void BackgroundLoaderContentsTest::SetUp() {
contents_.reset(new BackgroundLoaderContents());
diff --git a/chromium/components/offline_pages/content/renovations/render_frame_script_injector.cc b/chromium/components/offline_pages/content/renovations/render_frame_script_injector.cc
index e9d1ab841d2..407d1adf36f 100644
--- a/chromium/components/offline_pages/content/renovations/render_frame_script_injector.cc
+++ b/chromium/components/offline_pages/content/renovations/render_frame_script_injector.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/values.h"
diff --git a/chromium/components/offline_pages/core/BUILD.gn b/chromium/components/offline_pages/core/BUILD.gn
index 1c9cf1d0ed6..a553dbc5e41 100644
--- a/chromium/components/offline_pages/core/BUILD.gn
+++ b/chromium/components/offline_pages/core/BUILD.gn
@@ -69,6 +69,8 @@ static_library("core") {
"offline_page_client_policy.h",
"offline_page_item.cc",
"offline_page_item.h",
+ "offline_page_item_utils.cc",
+ "offline_page_item_utils.h",
"offline_page_metadata_store.cc",
"offline_page_metadata_store.h",
"offline_page_model.cc",
@@ -182,6 +184,7 @@ source_set("unit_tests") {
"offline_event_logger_unittest.cc",
"offline_page_archiver_unittest.cc",
"offline_page_feature_unittest.cc",
+ "offline_page_item_utils_unittest.cc",
"offline_page_metadata_store_unittest.cc",
"offline_page_model_event_logger_unittest.cc",
"offline_page_thumbnail_unittest.cc",
diff --git a/chromium/components/offline_pages/core/background/BUILD.gn b/chromium/components/offline_pages/core/background/BUILD.gn
index 069a7144187..3c800d82ef0 100644
--- a/chromium/components/offline_pages/core/background/BUILD.gn
+++ b/chromium/components/offline_pages/core/background/BUILD.gn
@@ -8,8 +8,6 @@ if (is_android) {
static_library("background_offliner") {
sources = [
- "add_request_task.cc",
- "add_request_task.h",
"change_requests_state_task.cc",
"change_requests_state_task.h",
"cleanup_task.cc",
@@ -108,7 +106,6 @@ static_library("test_support") {
source_set("unit_tests") {
testonly = true
sources = [
- "add_request_task_unittest.cc",
"change_requests_state_task_unittest.cc",
"cleanup_task_unittest.cc",
"get_requests_task_unittest.cc",
diff --git a/chromium/components/offline_pages/core/background/add_request_task.cc b/chromium/components/offline_pages/core/background/add_request_task.cc
deleted file mode 100644
index e59f363ca46..00000000000
--- a/chromium/components/offline_pages/core/background/add_request_task.cc
+++ /dev/null
@@ -1,37 +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/offline_pages/core/background/add_request_task.h"
-
-#include "base/bind.h"
-#include "components/offline_pages/core/background/save_page_request.h"
-
-namespace offline_pages {
-
-AddRequestTask::AddRequestTask(RequestQueueStore* store,
- const SavePageRequest& request,
- RequestQueueStore::AddCallback callback)
- : store_(store),
- request_(request),
- callback_(std::move(callback)),
- weak_ptr_factory_(this) {}
-
-AddRequestTask::~AddRequestTask() {}
-
-void AddRequestTask::Run() {
- AddRequest();
-}
-
-void AddRequestTask::AddRequest() {
- store_->AddRequest(request_,
- base::BindOnce(&AddRequestTask::CompleteWithResult,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void AddRequestTask::CompleteWithResult(ItemActionStatus status) {
- std::move(callback_).Run(status);
- TaskComplete();
-}
-
-} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/background/add_request_task.h b/chromium/components/offline_pages/core/background/add_request_task.h
deleted file mode 100644
index 2abf5e54d6a..00000000000
--- a/chromium/components/offline_pages/core/background/add_request_task.h
+++ /dev/null
@@ -1,46 +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_OFFLINE_PAGES_CORE_BACKGROUND_ADD_REQUEST_TASK_H_
-#define COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_ADD_REQUEST_TASK_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "components/offline_pages/core/background/request_queue_store.h"
-#include "components/offline_pages/task/task.h"
-
-namespace offline_pages {
-
-class AddRequestTask : public Task {
- public:
- AddRequestTask(RequestQueueStore* store,
- const SavePageRequest& request,
- RequestQueueStore::AddCallback callback);
- ~AddRequestTask() override;
-
- // Task implementation:
- void Run() override;
-
- private:
- // Step 1: Add the request to the store.
- void AddRequest();
- // Step 2: Calls the callback with result, completes the task.
- void CompleteWithResult(ItemActionStatus status);
-
- // Store from which requests will be read.
- RequestQueueStore* store_;
- // Request to be added.
- SavePageRequest request_;
- // Callback used to return the read results.
- RequestQueueStore::AddCallback callback_;
-
- base::WeakPtrFactory<AddRequestTask> weak_ptr_factory_;
- DISALLOW_COPY_AND_ASSIGN(AddRequestTask);
-};
-
-} // namespace offline_pages
-
-#endif // COMPONENTS_OFFLINE_PAGES_CORE_BACKGROUND_ADD_REQUEST_TASK_H_
diff --git a/chromium/components/offline_pages/core/background/add_request_task_unittest.cc b/chromium/components/offline_pages/core/background/add_request_task_unittest.cc
deleted file mode 100644
index 19b5d1b5e56..00000000000
--- a/chromium/components/offline_pages/core/background/add_request_task_unittest.cc
+++ /dev/null
@@ -1,184 +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/offline_pages/core/background/add_request_task.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/offline_pages/core/background/request_queue_store.h"
-#include "components/offline_pages/core/background/request_queue_task_test_base.h"
-#include "components/offline_pages/core/background/test_request_queue_store.h"
-#include "components/offline_pages/core/offline_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace offline_pages {
-namespace {
-const int64_t kRequestId1 = 42;
-const int64_t kRequestId2 = 44;
-const GURL kUrl1("http://example.com");
-const GURL kUrl2("http://otherexample.com");
-const ClientId kClientId1("download", "1234");
-const ClientId kClientId2("download", "5678");
-
-class AddRequestTaskTest : public RequestQueueTaskTestBase {
- public:
- AddRequestTaskTest();
- ~AddRequestTaskTest() override {}
-
- void ClearResults();
-
- void InitializeStore(RequestQueueStore* store);
-
- void AddRequestDone(ItemActionStatus status);
-
- void GetRequestsCallback(
- bool success,
- std::vector<std::unique_ptr<SavePageRequest>> requests);
-
- bool callback_called() const { return callback_called_; }
-
- ItemActionStatus last_status() const { return status_; }
-
- const std::vector<std::unique_ptr<SavePageRequest>>& last_requests() const {
- return requests_;
- }
-
- protected:
- void InitializeStoreDone(bool success);
-
- bool callback_called_;
- ItemActionStatus status_;
- std::vector<std::unique_ptr<SavePageRequest>> requests_;
-};
-
-AddRequestTaskTest::AddRequestTaskTest()
- : callback_called_(false), status_(ItemActionStatus::NOT_FOUND) {}
-
-void AddRequestTaskTest::ClearResults() {
- callback_called_ = false;
- status_ = ItemActionStatus::NOT_FOUND;
- requests_.clear();
-}
-
-void AddRequestTaskTest::InitializeStore(RequestQueueStore* store) {
- store->Initialize(base::BindOnce(&AddRequestTaskTest::InitializeStoreDone,
- base::Unretained(this)));
- PumpLoop();
-}
-
-void AddRequestTaskTest::AddRequestDone(ItemActionStatus status) {
- status_ = status;
- callback_called_ = true;
-}
-
-void AddRequestTaskTest::GetRequestsCallback(
- bool success,
- std::vector<std::unique_ptr<SavePageRequest>> requests) {
- requests_ = std::move(requests);
-}
-
-void AddRequestTaskTest::InitializeStoreDone(bool success) {
- ASSERT_TRUE(success);
-}
-
-TEST_F(AddRequestTaskTest, AddSingleRequest) {
- InitializeStore(&store_);
- base::Time creation_time = OfflineTimeNow();
- SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
- true);
- AddRequestTask task(&store_, request_1,
- base::BindOnce(&AddRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- task.Run();
- PumpLoop();
- EXPECT_TRUE(callback_called());
- EXPECT_EQ(ItemActionStatus::SUCCESS, last_status());
-
- store_.GetRequests(base::BindOnce(&AddRequestTaskTest::GetRequestsCallback,
- base::Unretained(this)));
- PumpLoop();
- ASSERT_EQ(1ul, last_requests().size());
- EXPECT_EQ(kRequestId1, last_requests().at(0)->request_id());
- EXPECT_EQ(kUrl1, last_requests().at(0)->url());
- EXPECT_EQ(kClientId1, last_requests().at(0)->client_id());
- EXPECT_EQ(creation_time, last_requests().at(0)->creation_time());
- EXPECT_TRUE(last_requests().at(0)->user_requested());
-}
-
-TEST_F(AddRequestTaskTest, AddMultipleRequests) {
- InitializeStore(&store_);
- base::Time creation_time_1 = OfflineTimeNow();
- SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time_1,
- true);
- AddRequestTask task(&store_, request_1,
- base::BindOnce(&AddRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- task.Run();
- PumpLoop();
- EXPECT_TRUE(callback_called());
- EXPECT_EQ(ItemActionStatus::SUCCESS, last_status());
-
- ClearResults();
- base::Time creation_time_2 = OfflineTimeNow();
- SavePageRequest request_2(kRequestId2, kUrl2, kClientId2, creation_time_2,
- true);
- AddRequestTask task_2(&store_, request_2,
- base::BindOnce(&AddRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- task_2.Run();
- PumpLoop();
- EXPECT_TRUE(callback_called());
- EXPECT_EQ(ItemActionStatus::SUCCESS, last_status());
-
- store_.GetRequests(base::BindOnce(&AddRequestTaskTest::GetRequestsCallback,
- base::Unretained(this)));
- PumpLoop();
- ASSERT_EQ(2ul, last_requests().size());
- int request_2_index =
- last_requests().at(0)->request_id() == kRequestId2 ? 0 : 1;
- EXPECT_EQ(kRequestId2, last_requests().at(request_2_index)->request_id());
- EXPECT_EQ(kUrl2, last_requests().at(request_2_index)->url());
- EXPECT_EQ(kClientId2, last_requests().at(request_2_index)->client_id());
- EXPECT_EQ(creation_time_2,
- last_requests().at(request_2_index)->creation_time());
- EXPECT_TRUE(last_requests().at(request_2_index)->user_requested());
-}
-
-TEST_F(AddRequestTaskTest, AddDuplicateRequest) {
- InitializeStore(&store_);
- base::Time creation_time_1 = OfflineTimeNow();
- SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time_1,
- true);
- AddRequestTask task(&store_, request_1,
- base::BindOnce(&AddRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- task.Run();
- PumpLoop();
- EXPECT_TRUE(callback_called());
- EXPECT_EQ(ItemActionStatus::SUCCESS, last_status());
-
- ClearResults();
- base::Time creation_time_2 = OfflineTimeNow();
- // This was has the same request ID.
- SavePageRequest request_2(kRequestId1, kUrl2, kClientId2, creation_time_2,
- true);
- AddRequestTask task_2(&store_, request_2,
- base::BindOnce(&AddRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- task_2.Run();
- PumpLoop();
- EXPECT_TRUE(callback_called());
- EXPECT_EQ(ItemActionStatus::ALREADY_EXISTS, last_status());
-
- store_.GetRequests(base::BindOnce(&AddRequestTaskTest::GetRequestsCallback,
- base::Unretained(this)));
- PumpLoop();
- ASSERT_EQ(1ul, last_requests().size());
-}
-
-} // namespace
-} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/background/change_requests_state_task_unittest.cc b/chromium/components/offline_pages/core/background/change_requests_state_task_unittest.cc
index 83ef6b4e294..d4d876d9e62 100644
--- a/chromium/components/offline_pages/core/background/change_requests_state_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/change_requests_state_task_unittest.cc
@@ -36,7 +36,7 @@ class ChangeRequestsStateTaskTest : public RequestQueueTaskTestBase {
private:
void InitializeStoreDone(bool success);
- void AddRequestDone(ItemActionStatus status);
+ void AddRequestDone(AddRequestResult result);
std::unique_ptr<UpdateRequestsResult> result_;
};
@@ -45,12 +45,12 @@ void ChangeRequestsStateTaskTest::AddItemsToStore() {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
true);
- store_.AddRequest(request_1,
+ store_.AddRequest(request_1, RequestQueue::AddOptions(),
base::BindOnce(&ChangeRequestsStateTaskTest::AddRequestDone,
base::Unretained(this)));
SavePageRequest request_2(kRequestId2, kUrl2, kClientId2, creation_time,
true);
- store_.AddRequest(request_2,
+ store_.AddRequest(request_2, RequestQueue::AddOptions(),
base::BindOnce(&ChangeRequestsStateTaskTest::AddRequestDone,
base::Unretained(this)));
PumpLoop();
@@ -65,8 +65,8 @@ void ChangeRequestsStateTaskTest::InitializeStoreDone(bool success) {
ASSERT_TRUE(success);
}
-void ChangeRequestsStateTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
+void ChangeRequestsStateTaskTest::AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
}
TEST_F(ChangeRequestsStateTaskTest, UpdateWhenStoreEmpty) {
diff --git a/chromium/components/offline_pages/core/background/cleanup_task_unittest.cc b/chromium/components/offline_pages/core/background/cleanup_task_unittest.cc
index e83069c82f2..0b39fbd1693 100644
--- a/chromium/components/offline_pages/core/background/cleanup_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/cleanup_task_unittest.cc
@@ -86,7 +86,9 @@ class CleanupTaskTest : public RequestQueueTaskTestBase {
void SetUp() override;
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
void GetRequestsCallback(
bool success,
@@ -127,10 +129,6 @@ void CleanupTaskTest::SetUp() {
InitializeStore();
}
-void CleanupTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
-
void CleanupTaskTest::GetRequestsCallback(
bool success,
std::vector<std::unique_ptr<SavePageRequest>> requests) {
@@ -143,10 +141,10 @@ void CleanupTaskTest::QueueRequests(const SavePageRequest& request1,
DeviceConditions conditions;
std::set<int64_t> disabled_requests;
// Add test requests on the Queue.
- store_.AddRequest(request1, base::BindOnce(&CleanupTaskTest::AddRequestDone,
- base::Unretained(this)));
- store_.AddRequest(request2, base::BindOnce(&CleanupTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(request1, RequestQueue::AddOptions(),
+ base::BindOnce(&CleanupTaskTest::AddRequestDone));
+ store_.AddRequest(request2, RequestQueue::AddOptions(),
+ base::BindOnce(&CleanupTaskTest::AddRequestDone));
// Pump the loop to give the async queue the opportunity to do the adds.
PumpLoop();
diff --git a/chromium/components/offline_pages/core/background/get_requests_task_unittest.cc b/chromium/components/offline_pages/core/background/get_requests_task_unittest.cc
index afdc4b4bfca..7a804d85893 100644
--- a/chromium/components/offline_pages/core/background/get_requests_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/get_requests_task_unittest.cc
@@ -43,7 +43,9 @@ class GetRequestsTaskTest : public RequestQueueTaskTestBase {
}
private:
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
bool callback_called_ = false;
bool success_ = false;
@@ -54,15 +56,13 @@ void GetRequestsTaskTest::AddItemsToStore(RequestQueueStore* store) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
true);
- store->AddRequest(request_1,
- base::BindOnce(&GetRequestsTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store->AddRequest(request_1, RequestQueue::AddOptions(),
+ base::BindOnce(&GetRequestsTaskTest::AddRequestDone));
creation_time = OfflineTimeNow();
SavePageRequest request_2(kRequestId2, kUrl2, kClientId2, creation_time,
true);
- store->AddRequest(request_2,
- base::BindOnce(&GetRequestsTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store->AddRequest(request_2, RequestQueue::AddOptions(),
+ base::BindOnce(&GetRequestsTaskTest::AddRequestDone));
PumpLoop();
}
@@ -74,10 +74,6 @@ void GetRequestsTaskTest::GetRequestsCallback(
requests_ = std::move(requests);
}
-void GetRequestsTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
-
TEST_F(GetRequestsTaskTest, GetFromEmptyStore) {
InitializeStore();
GetRequestsTask task(&store_,
diff --git a/chromium/components/offline_pages/core/background/mark_attempt_aborted_task_unittest.cc b/chromium/components/offline_pages/core/background/mark_attempt_aborted_task_unittest.cc
index 4a26c34355b..abb19df227e 100644
--- a/chromium/components/offline_pages/core/background/mark_attempt_aborted_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/mark_attempt_aborted_task_unittest.cc
@@ -39,7 +39,7 @@ class MarkAttemptAbortedTaskTest : public RequestQueueTaskTestBase {
protected:
void InitializeStoreDone(bool success);
- void AddRequestDone(ItemActionStatus status);
+ void AddRequestDone(AddRequestResult result);
std::unique_ptr<UpdateRequestsResult> result_;
};
@@ -48,7 +48,7 @@ void MarkAttemptAbortedTaskTest::AddItemToStore(RequestQueueStore* store) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
true);
- store->AddRequest(request_1,
+ store->AddRequest(request_1, RequestQueue::AddOptions(),
base::BindOnce(&MarkAttemptAbortedTaskTest::AddRequestDone,
base::Unretained(this)));
PumpLoop();
@@ -67,8 +67,8 @@ void MarkAttemptAbortedTaskTest::InitializeStoreDone(bool success) {
ASSERT_TRUE(success);
}
-void MarkAttemptAbortedTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
+void MarkAttemptAbortedTaskTest::AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
}
TEST_F(MarkAttemptAbortedTaskTest, MarkAttemptAbortedWhenStoreEmpty) {
diff --git a/chromium/components/offline_pages/core/background/mark_attempt_completed_task_unittest.cc b/chromium/components/offline_pages/core/background/mark_attempt_completed_task_unittest.cc
index cffb86510bd..17f5b0696b6 100644
--- a/chromium/components/offline_pages/core/background/mark_attempt_completed_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/mark_attempt_completed_task_unittest.cc
@@ -32,7 +32,9 @@ class MarkAttemptCompletedTaskTest : public RequestQueueTaskTestBase {
UpdateRequestsResult* last_result() const { return result_.get(); }
private:
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
std::unique_ptr<UpdateRequestsResult> result_;
};
@@ -43,8 +45,8 @@ void MarkAttemptCompletedTaskTest::AddStartedItemToStore() {
true);
request_1.MarkAttemptStarted(OfflineTimeNow());
store_.AddRequest(
- request_1, base::BindOnce(&MarkAttemptCompletedTaskTest::AddRequestDone,
- base::Unretained(this)));
+ request_1, RequestQueue::AddOptions(),
+ base::BindOnce(&MarkAttemptCompletedTaskTest::AddRequestDone));
PumpLoop();
}
@@ -53,9 +55,6 @@ void MarkAttemptCompletedTaskTest::ChangeRequestsStateCallback(
result_ = std::make_unique<UpdateRequestsResult>(std::move(result));
}
-void MarkAttemptCompletedTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
TEST_F(MarkAttemptCompletedTaskTest, MarkAttemptCompletedWhenExists) {
InitializeStore();
diff --git a/chromium/components/offline_pages/core/background/mark_attempt_started_task_unittest.cc b/chromium/components/offline_pages/core/background/mark_attempt_started_task_unittest.cc
index 57ce13e2e49..26616a3e07d 100644
--- a/chromium/components/offline_pages/core/background/mark_attempt_started_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/mark_attempt_started_task_unittest.cc
@@ -33,7 +33,9 @@ class MarkAttemptStartedTaskTest : public RequestQueueTaskTestBase {
UpdateRequestsResult* last_result() const { return result_.get(); }
private:
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
std::unique_ptr<UpdateRequestsResult> result_;
};
@@ -42,9 +44,9 @@ void MarkAttemptStartedTaskTest::AddItemToStore() {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
true);
- store_.AddRequest(request_1,
- base::BindOnce(&MarkAttemptStartedTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(
+ request_1, RequestQueue::AddOptions(),
+ base::BindOnce(&MarkAttemptStartedTaskTest::AddRequestDone));
PumpLoop();
}
@@ -53,9 +55,6 @@ void MarkAttemptStartedTaskTest::ChangeRequestsStateCallback(
result_ = std::make_unique<UpdateRequestsResult>(std::move(result));
}
-void MarkAttemptStartedTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
TEST_F(MarkAttemptStartedTaskTest, MarkAttemptStartedWhenStoreEmpty) {
InitializeStore();
diff --git a/chromium/components/offline_pages/core/background/offliner_client.cc b/chromium/components/offline_pages/core/background/offliner_client.cc
index 8f71b975d50..85967d21341 100644
--- a/chromium/components/offline_pages/core/background/offliner_client.cc
+++ b/chromium/components/offline_pages/core/background/offliner_client.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "components/offline_pages/core/background/save_page_request.h"
namespace offline_pages {
diff --git a/chromium/components/offline_pages/core/background/pending_state_updater.cc b/chromium/components/offline_pages/core/background/pending_state_updater.cc
index bf2e70acc09..6bbd34626f0 100644
--- a/chromium/components/offline_pages/core/background/pending_state_updater.cc
+++ b/chromium/components/offline_pages/core/background/pending_state_updater.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/background/pending_state_updater.h"
+#include "base/bind.h"
#include "components/offline_items_collection/core/pending_state.h"
#include "components/offline_pages/core/background/request_coordinator.h"
diff --git a/chromium/components/offline_pages/core/background/pick_request_task_unittest.cc b/chromium/components/offline_pages/core/background/pick_request_task_unittest.cc
index 545858c9468..41ff45bc332 100644
--- a/chromium/components/offline_pages/core/background/pick_request_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/pick_request_task_unittest.cc
@@ -96,8 +96,6 @@ class PickRequestTaskTest : public RequestQueueTaskTestBase {
void SetUp() override;
- void AddRequestDone(ItemActionStatus status);
-
void RequestPicked(
const SavePageRequest& request,
const std::unique_ptr<std::vector<SavePageRequest>> available_requests,
@@ -157,8 +155,6 @@ void PickRequestTaskTest::TaskCompletionCallback(Task* completed_task) {
task_complete_called_ = true;
}
-void PickRequestTaskTest::AddRequestDone(ItemActionStatus status) {}
-
void PickRequestTaskTest::RequestPicked(
const SavePageRequest& request,
std::unique_ptr<std::vector<SavePageRequest>> available_requests,
@@ -186,12 +182,8 @@ void PickRequestTaskTest::QueueRequests(const SavePageRequest& request1,
DeviceConditions conditions;
std::set<int64_t> disabled_requests;
// Add test requests on the Queue.
- store_.AddRequest(request1,
- base::BindOnce(&PickRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
- store_.AddRequest(request2,
- base::BindOnce(&PickRequestTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(request1, RequestQueue::AddOptions(), base::DoNothing());
+ store_.AddRequest(request2, RequestQueue::AddOptions(), base::DoNothing());
// Pump the loop to give the async queue the opportunity to do the adds.
PumpLoop();
diff --git a/chromium/components/offline_pages/core/background/reconcile_task_unittest.cc b/chromium/components/offline_pages/core/background/reconcile_task_unittest.cc
index 35426df4897..add0f4a7010 100644
--- a/chromium/components/offline_pages/core/background/reconcile_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/reconcile_task_unittest.cc
@@ -45,7 +45,9 @@ class ReconcileTaskTest : public RequestQueueTaskTestBase {
void SetUp() override;
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
void GetRequestsCallback(
bool success,
@@ -78,10 +80,6 @@ void ReconcileTaskTest::SetUp() {
InitializeStore();
}
-void ReconcileTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
-
void ReconcileTaskTest::GetRequestsCallback(
bool success,
std::vector<std::unique_ptr<SavePageRequest>> requests) {
@@ -101,10 +99,10 @@ void ReconcileTaskTest::QueueRequests(const SavePageRequest& request1,
DeviceConditions conditions;
std::set<int64_t> disabled_requests;
// Add test requests on the Queue.
- store_.AddRequest(request1, base::BindOnce(&ReconcileTaskTest::AddRequestDone,
- base::Unretained(this)));
- store_.AddRequest(request2, base::BindOnce(&ReconcileTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(request1, RequestQueue::AddOptions(),
+ base::BindOnce(&ReconcileTaskTest::AddRequestDone));
+ store_.AddRequest(request2, RequestQueue::AddOptions(),
+ base::BindOnce(&ReconcileTaskTest::AddRequestDone));
// Pump the loop to give the async queue the opportunity to do the adds.
PumpLoop();
diff --git a/chromium/components/offline_pages/core/background/remove_requests_task_unittest.cc b/chromium/components/offline_pages/core/background/remove_requests_task_unittest.cc
index 6baf5d67dfc..07fa02711b2 100644
--- a/chromium/components/offline_pages/core/background/remove_requests_task_unittest.cc
+++ b/chromium/components/offline_pages/core/background/remove_requests_task_unittest.cc
@@ -38,7 +38,9 @@ class RemoveRequestsTaskTest : public RequestQueueTaskTestBase {
UpdateRequestsResult* last_result() const { return result_.get(); }
private:
- void AddRequestDone(ItemActionStatus status);
+ static void AddRequestDone(AddRequestResult result) {
+ ASSERT_EQ(AddRequestResult::SUCCESS, result);
+ }
std::unique_ptr<UpdateRequestsResult> result_;
};
@@ -51,14 +53,12 @@ void RemoveRequestsTaskTest::AddRequestsToStore() {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request_1(kRequestId1, kUrl1, kClientId1, creation_time,
true);
- store_.AddRequest(request_1,
- base::BindOnce(&RemoveRequestsTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(request_1, RequestQueue::AddOptions(),
+ base::BindOnce(&RemoveRequestsTaskTest::AddRequestDone));
SavePageRequest request_2(kRequestId2, kUrl2, kClientId2, creation_time,
true);
- store_.AddRequest(request_2,
- base::BindOnce(&RemoveRequestsTaskTest::AddRequestDone,
- base::Unretained(this)));
+ store_.AddRequest(request_2, RequestQueue::AddOptions(),
+ base::BindOnce(&RemoveRequestsTaskTest::AddRequestDone));
PumpLoop();
}
@@ -67,10 +67,6 @@ void RemoveRequestsTaskTest::RemoveRequestsCallback(
result_ = std::make_unique<UpdateRequestsResult>(std::move(result));
}
-void RemoveRequestsTaskTest::AddRequestDone(ItemActionStatus status) {
- ASSERT_EQ(ItemActionStatus::SUCCESS, status);
-}
-
TEST_F(RemoveRequestsTaskTest, RemoveWhenStoreEmpty) {
InitializeStore();
diff --git a/chromium/components/offline_pages/core/background/request_coordinator.cc b/chromium/components/offline_pages/core/background/request_coordinator.cc
index 60a4087de10..7c3c2ebfa95 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
@@ -341,10 +342,11 @@ int64_t RequestCoordinator::SavePageLater(
// Put the request on the request queue.
queue_->AddRequest(
- request, base::BindOnce(&RequestCoordinator::AddRequestResultCallback,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(save_page_later_callback),
- save_page_later_params.availability));
+ request, save_page_later_params.add_options,
+ base::BindOnce(&RequestCoordinator::AddRequestResultCallback,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::move(save_page_later_callback),
+ save_page_later_params.availability));
// Record the network quality when this request is made.
diff --git a/chromium/components/offline_pages/core/background/request_coordinator.h b/chromium/components/offline_pages/core/background/request_coordinator.h
index 1d996ed74a2..058f65be05a 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator.h
+++ b/chromium/components/offline_pages/core/background/request_coordinator.h
@@ -108,6 +108,9 @@ class RequestCoordinator : public KeyedService,
// The origin of the request, if any.
std::string request_origin;
+
+ // Additional options for adding the request.
+ RequestQueue::AddOptions add_options;
};
// Callback specifying which request IDs were actually removed.
diff --git a/chromium/components/offline_pages/core/background/request_coordinator_stub_taco.cc b/chromium/components/offline_pages/core/background/request_coordinator_stub_taco.cc
index 82d545fe948..ab871e32882 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator_stub_taco.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator_stub_taco.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "components/offline_pages/core/background/offliner_stub.h"
#include "components/offline_pages/core/background/request_queue.h"
#include "components/offline_pages/core/background/request_queue_store.h"
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 c12f7a2ab74..7f6b3e8c6c7 100644
--- a/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc
+++ b/chromium/components/offline_pages/core/background/request_coordinator_unittest.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/containers/circular_deque.h"
#include "base/location.h"
#include "base/logging.h"
@@ -497,7 +498,7 @@ void RequestCoordinatorTest::SetupForOfflinerDoneCallbackTest(
// Mark request as started and add it to the queue,
// then wait for callback to finish.
request->MarkAttemptStarted(OfflineTimeNow());
- queue()->AddRequest(*request, base::DoNothing());
+ queue()->AddRequest(*request, RequestQueue::AddOptions(), base::DoNothing());
PumpLoop();
// Override the processing callback for test visiblity.
@@ -522,14 +523,14 @@ void RequestCoordinatorTest::SendOfflinerDoneCallback(
SavePageRequest RequestCoordinatorTest::AddRequest1() {
offline_pages::SavePageRequest request1(kRequestId1, kUrl1, kClientId1,
OfflineTimeNow(), kUserRequested);
- queue()->AddRequest(request1, base::DoNothing());
+ queue()->AddRequest(request1, RequestQueue::AddOptions(), base::DoNothing());
return request1;
}
SavePageRequest RequestCoordinatorTest::AddRequest2() {
offline_pages::SavePageRequest request2(kRequestId2, kUrl2, kClientId2,
OfflineTimeNow(), kUserRequested);
- queue()->AddRequest(request2, base::DoNothing());
+ queue()->AddRequest(request2, RequestQueue::AddOptions(), base::DoNothing());
return request2;
}
@@ -1043,7 +1044,7 @@ TEST_F(RequestCoordinatorTest, SchedulerGetsLeastRestrictiveConditions) {
offline_pages::SavePageRequest request2(kRequestId2, kUrl2, kClientId2,
OfflineTimeNow(), !kUserRequested);
- queue()->AddRequest(request2, base::DoNothing());
+ queue()->AddRequest(request2, RequestQueue::AddOptions(), base::DoNothing());
PumpLoop();
// Trigger the scheduler to schedule for the least restrictive condition.
@@ -1345,7 +1346,7 @@ TEST_F(RequestCoordinatorTest,
// Set request to allow one more completed attempt.
int max_tries = coordinator()->policy()->GetMaxCompletedTries();
request.set_completed_attempt_count(max_tries - 1);
- queue()->AddRequest(request, base::DoNothing());
+ queue()->AddRequest(request, RequestQueue::AddOptions(), base::DoNothing());
PumpLoop();
// Ensure that the new request does not finish - we simulate it being
@@ -1416,7 +1417,7 @@ TEST_F(RequestCoordinatorTest, TimeBudgetExceeded) {
offline_pages::SavePageRequest request2(kRequestId1 + 1, kUrl1, kClientId1,
OfflineTimeNow(), kUserRequested);
request2.set_completed_attempt_count(kAttemptCount);
- queue()->AddRequest(request2, base::DoNothing());
+ queue()->AddRequest(request2, RequestQueue::AddOptions(), base::DoNothing());
PumpLoop();
// Sending the request to the offliner.
@@ -1741,7 +1742,7 @@ TEST_F(RequestCoordinatorTest, SnapshotOnLastTryForScheduledProcessing) {
// be the last retry.
int max_tries = coordinator()->policy()->GetMaxCompletedTries();
request.set_completed_attempt_count(max_tries - 1);
- queue()->AddRequest(request, base::DoNothing());
+ queue()->AddRequest(request, RequestQueue::AddOptions(), base::DoNothing());
PumpLoop();
// Ensure that the new request does not finish - we simulate it being
diff --git a/chromium/components/offline_pages/core/background/request_queue.cc b/chromium/components/offline_pages/core/background/request_queue.cc
index 7b60a88b1b3..b73a2c10e76 100644
--- a/chromium/components/offline_pages/core/background/request_queue.cc
+++ b/chromium/components/offline_pages/core/background/request_queue.cc
@@ -9,7 +9,6 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "components/offline_pages/core/background/add_request_task.h"
#include "components/offline_pages/core/background/change_requests_state_task.h"
#include "components/offline_pages/core/background/get_requests_task.h"
#include "components/offline_pages/core/background/initialize_store_task.h"
@@ -36,29 +35,6 @@ void GetRequestsDone(RequestQueue::GetRequestsCallback callback,
std::move(callback).Run(result, std::move(requests));
}
-// Completes the add request call.
-void AddRequestDone(RequestQueue::AddRequestCallback callback,
- const SavePageRequest& request,
- ItemActionStatus status) {
- AddRequestResult result;
- switch (status) {
- case ItemActionStatus::SUCCESS:
- result = AddRequestResult::SUCCESS;
- break;
- case ItemActionStatus::ALREADY_EXISTS:
- result = AddRequestResult::ALREADY_EXISTS;
- break;
- case ItemActionStatus::STORE_ERROR:
- result = AddRequestResult::STORE_FAILURE;
- break;
- case ItemActionStatus::NOT_FOUND:
- default:
- NOTREACHED();
- return;
- }
- std::move(callback).Run(result, request);
-}
-
} // namespace
RequestQueue::RequestQueue(std::unique_ptr<RequestQueueStore> store)
@@ -77,11 +53,17 @@ void RequestQueue::GetRequests(GetRequestsCallback callback) {
}
void RequestQueue::AddRequest(const SavePageRequest& request,
+ AddOptions options,
AddRequestCallback callback) {
- std::unique_ptr<AddRequestTask> task(new AddRequestTask(
- store_.get(), request,
- base::BindOnce(&AddRequestDone, std::move(callback), request)));
- task_queue_.AddTask(std::move(task));
+ // |callback| receives both |request| and the result, whereas
+ // RequestQueueStore returns only the result. Adapt the callback here.
+ RequestQueueStore::AddCallback adapter = base::BindOnce(
+ [](AddRequestCallback callback, const SavePageRequest& request,
+ AddRequestResult result) { std::move(callback).Run(result, request); },
+ std::move(callback), request);
+ task_queue_.AddTask(std::make_unique<ClosureTask>(base::BindOnce(
+ &RequestQueueStore::AddRequest, base::Unretained(store_.get()), request,
+ std::move(options), std::move(adapter))));
}
void RequestQueue::RemoveRequests(const std::vector<int64_t>& request_ids,
diff --git a/chromium/components/offline_pages/core/background/request_queue.h b/chromium/components/offline_pages/core/background/request_queue.h
index f5b32b3dd45..f29c15ab668 100644
--- a/chromium/components/offline_pages/core/background/request_queue.h
+++ b/chromium/components/offline_pages/core/background/request_queue.h
@@ -52,6 +52,18 @@ class RequestQueue : public TaskQueue::Delegate {
// Callback used by |UdpateRequest|.
typedef base::OnceCallback<void(UpdateRequestResult)> UpdateRequestCallback;
+ struct AddOptions {
+ // If non-zero, the request will only be added to the queue if fewer than
+ // this many requests are already in the queue. This only considers other
+ // requests with the same |client_id.name_space|. If there are too many
+ // requests, |AddRequestResult::REQUEST_QUOTA_HIT| will be returned.
+ int maximum_in_flight_requests_for_namespace = 0;
+
+ // If true, the request will only be added to the queue if the URL being
+ // requested is unique for all active requests from the same namespace.
+ bool disallow_duplicate_requests = false;
+ };
+
explicit RequestQueue(std::unique_ptr<RequestQueueStore> store);
~RequestQueue() override;
@@ -66,7 +78,9 @@ class RequestQueue : public TaskQueue::Delegate {
// In case adding the request violates policy, the result will fail with
// appropriate result. Callback will also return a copy of a request with all
// fields set.
- void AddRequest(const SavePageRequest& request, AddRequestCallback callback);
+ void AddRequest(const SavePageRequest& request,
+ AddOptions options,
+ AddRequestCallback callback);
// Removes the requests matching the |request_ids|. Result is returned through
// |callback|. If a request id cannot be removed, this will still remove the
diff --git a/chromium/components/offline_pages/core/background/request_queue_results.h b/chromium/components/offline_pages/core/background/request_queue_results.h
index 47896340b56..92567a14870 100644
--- a/chromium/components/offline_pages/core/background/request_queue_results.h
+++ b/chromium/components/offline_pages/core/background/request_queue_results.h
@@ -26,6 +26,8 @@ enum class AddRequestResult {
REQUEST_QUOTA_HIT, // Cannot add a request with this namespace, as it has
// reached a quota of active requests.
URL_ERROR, // Cannot save this URL.
+ DUPLICATE_URL, // URL is already being requested from this name_space, and
+ // |disallow_duplicate_requests| was set to true.
};
// GENERATED_JAVA_ENUM_PACKAGE:org.chromium.components.offlinepages.background
diff --git a/chromium/components/offline_pages/core/background/request_queue_store.cc b/chromium/components/offline_pages/core/background/request_queue_store.cc
index 79b89dea2d4..9d74f45b9a5 100644
--- a/chromium/components/offline_pages/core/background/request_queue_store.cc
+++ b/chromium/components/offline_pages/core/background/request_queue_store.cc
@@ -18,6 +18,7 @@
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/offline_pages/core/background/save_page_request.h"
+#include "components/offline_pages/core/offline_page_item_utils.h"
#include "components/offline_pages/core/offline_store_utils.h"
#include "sql/database.h"
#include "sql/statement.h"
@@ -253,7 +254,7 @@ ItemActionStatus DeleteRequestByIdSync(sql::Database* db, int64_t request_id) {
return ItemActionStatus::SUCCESS;
}
-ItemActionStatus InsertSync(sql::Database* db, const SavePageRequest& request) {
+AddRequestResult InsertSync(sql::Database* db, const SavePageRequest& request) {
static const char kSql[] = "INSERT OR IGNORE INTO " REQUEST_QUEUE_TABLE_NAME
" (" REQUEST_QUEUE_FIELDS
") VALUES"
@@ -278,10 +279,10 @@ ItemActionStatus InsertSync(sql::Database* db, const SavePageRequest& request) {
13, static_cast<int64_t>(request.auto_fetch_notification_state()));
if (!statement.Run())
- return ItemActionStatus::STORE_ERROR;
+ return AddRequestResult::STORE_FAILURE;
if (db->GetLastChangeCount() == 0)
- return ItemActionStatus::ALREADY_EXISTS;
- return ItemActionStatus::SUCCESS;
+ return AddRequestResult::ALREADY_EXISTS;
+ return AddRequestResult::SUCCESS;
}
ItemActionStatus UpdateSync(sql::Database* db, const SavePageRequest& request) {
@@ -421,6 +422,43 @@ UpdateRequestsResult GetRequestsByIdsSync(
return result;
}
+AddRequestResult AddRequestSync(sql::Database* db,
+ const SavePageRequest& request,
+ const RequestQueueStore::AddOptions& options) {
+ // If we need to check preconditions, read the set of active requests and
+ // check preconditions.
+ if (options.maximum_in_flight_requests_for_namespace > 0 ||
+ options.disallow_duplicate_requests) {
+ base::Optional<std::vector<std::unique_ptr<SavePageRequest>>> requests =
+ GetAllRequestsSync(db);
+ if (!requests)
+ return AddRequestResult::STORE_FAILURE;
+
+ if (options.maximum_in_flight_requests_for_namespace > 0) {
+ int existing_requests = 0;
+ for (const std::unique_ptr<SavePageRequest>& existing_request :
+ requests.value()) {
+ if (existing_request->client_id().name_space ==
+ request.client_id().name_space)
+ ++existing_requests;
+ }
+ if (existing_requests >= options.maximum_in_flight_requests_for_namespace)
+ return AddRequestResult::REQUEST_QUOTA_HIT;
+ }
+
+ if (options.disallow_duplicate_requests) {
+ for (const std::unique_ptr<SavePageRequest>& existing_request :
+ requests.value()) {
+ if (existing_request->client_id().name_space ==
+ request.client_id().name_space &&
+ EqualsIgnoringFragment(existing_request->url(), request.url()))
+ return AddRequestResult::DUPLICATE_URL;
+ }
+ }
+ }
+ return InsertSync(db, request);
+}
+
UpdateRequestsResult UpdateRequestsSync(
sql::Database* db,
const std::vector<SavePageRequest>& requests) {
@@ -577,17 +615,19 @@ void RequestQueueStore::GetRequestsByIds(
}
void RequestQueueStore::AddRequest(const SavePageRequest& request,
+ AddOptions options,
AddCallback callback) {
if (!CheckDb()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), ItemActionStatus::STORE_ERROR));
+ base::BindOnce(std::move(callback), AddRequestResult::STORE_FAILURE));
return;
}
base::PostTaskAndReplyWithResult(
background_task_runner_.get(), FROM_HERE,
- base::BindOnce(&InsertSync, db_.get(), request), std::move(callback));
+ base::BindOnce(&AddRequestSync, db_.get(), request, options),
+ std::move(callback));
}
void RequestQueueStore::UpdateRequests(
diff --git a/chromium/components/offline_pages/core/background/request_queue_store.h b/chromium/components/offline_pages/core/background/request_queue_store.h
index 1f0005565b0..4cfdf0ad91f 100644
--- a/chromium/components/offline_pages/core/background/request_queue_store.h
+++ b/chromium/components/offline_pages/core/background/request_queue_store.h
@@ -55,8 +55,9 @@ class RequestQueueStore {
bool /* success */,
std::vector<std::unique_ptr<SavePageRequest>> /* requests */)>
GetRequestsCallback;
- typedef base::OnceCallback<void(ItemActionStatus)> AddCallback;
+ typedef base::OnceCallback<void(AddRequestResult)> AddCallback;
using UpdateCallback = RequestQueue::UpdateCallback;
+ using AddOptions = RequestQueue::AddOptions;
RequestQueueStore(
scoped_refptr<base::SequencedTaskRunner> background_task_runner,
@@ -81,7 +82,9 @@ class RequestQueueStore {
// Asynchronously adds request in store. Fails if request with the same
// offline ID already exists.
- void AddRequest(const SavePageRequest& offline_page, AddCallback callback);
+ void AddRequest(const SavePageRequest& offline_page,
+ AddOptions options,
+ AddCallback callback);
// Asynchronously updates requests in store.
void UpdateRequests(const std::vector<SavePageRequest>& requests,
diff --git a/chromium/components/offline_pages/core/background/request_queue_store_unittest.cc b/chromium/components/offline_pages/core/background/request_queue_store_unittest.cc
index f7a4163194a..d96e0416949 100644
--- a/chromium/components/offline_pages/core/background/request_queue_store_unittest.cc
+++ b/chromium/components/offline_pages/core/background/request_queue_store_unittest.cc
@@ -36,7 +36,6 @@ const ClientId kClientId("bookmark", "1234");
const ClientId kClientId2("async", "5678");
const bool kUserRequested = true;
const char kRequestOrigin[] = "abc.xyz";
-
enum class LastResult {
RESULT_NONE,
RESULT_FALSE,
@@ -273,7 +272,7 @@ class RequestQueueStoreTestBase : public testing::Test {
std::vector<std::unique_ptr<SavePageRequest>> requests);
// Callback used for add/update request.
void AddOrUpdateDone(UpdateStatus result);
- void AddRequestDone(ItemActionStatus status);
+ void AddRequestDone(AddRequestResult result);
void UpdateRequestDone(UpdateRequestsResult result);
// Callback used for reset.
void ResetDone(bool result);
@@ -283,7 +282,9 @@ class RequestQueueStoreTestBase : public testing::Test {
const std::vector<std::unique_ptr<SavePageRequest>>& last_requests() const {
return last_requests_;
}
- ItemActionStatus last_add_status() const { return last_add_status_; }
+ base::Optional<AddRequestResult> last_add_result() const {
+ return last_add_result_;
+ }
UpdateRequestsResult* last_update_result() const {
return last_update_result_.get();
@@ -295,7 +296,7 @@ class RequestQueueStoreTestBase : public testing::Test {
private:
LastResult last_result_;
UpdateStatus last_update_status_;
- ItemActionStatus last_add_status_;
+ base::Optional<AddRequestResult> last_add_result_;
std::unique_ptr<UpdateRequestsResult> last_update_result_;
std::vector<std::unique_ptr<SavePageRequest>> last_requests_;
@@ -306,7 +307,6 @@ class RequestQueueStoreTestBase : public testing::Test {
RequestQueueStoreTestBase::RequestQueueStoreTestBase()
: last_result_(LastResult::RESULT_NONE),
last_update_status_(UpdateStatus::FAILED),
- last_add_status_(ItemActionStatus::NOT_FOUND),
task_runner_(new base::TestMockTimeTaskRunner),
task_runner_handle_(task_runner_) {
EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
@@ -324,7 +324,7 @@ void RequestQueueStoreTestBase::PumpLoop() {
void RequestQueueStoreTestBase::ClearResults() {
last_result_ = LastResult::RESULT_NONE;
last_update_status_ = UpdateStatus::FAILED;
- last_add_status_ = ItemActionStatus::NOT_FOUND;
+ last_add_result_ = base::nullopt;
last_requests_.clear();
last_update_result_.reset(nullptr);
}
@@ -352,8 +352,8 @@ void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) {
last_update_status_ = status;
}
-void RequestQueueStoreTestBase::AddRequestDone(ItemActionStatus status) {
- last_add_status_ = status;
+void RequestQueueStoreTestBase::AddRequestDone(AddRequestResult result) {
+ last_add_result_ = result;
}
void RequestQueueStoreTestBase::UpdateRequestDone(UpdateRequestsResult result) {
@@ -414,13 +414,13 @@ class RequestQueueStoreTest : public RequestQueueStoreTestBase {
// Verify a request can be added and retrieved.
SavePageRequest request(kRequestId, kUrl, kClientId, OfflineTimeNow(),
kUserRequested);
- store->AddRequest(request,
+ store->AddRequest(request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
store->GetRequests(base::BindOnce(
&RequestQueueStoreTestBase::GetRequestsDone, base::Unretained(this)));
PumpLoop();
- ASSERT_EQ(ItemActionStatus::SUCCESS, last_add_status());
+ ASSERT_EQ(AddRequestResult::SUCCESS, last_add_result());
ASSERT_EQ(LastResult::RESULT_TRUE, last_result());
ASSERT_EQ(1ul, last_requests().size());
EXPECT_EQ(request, *this->last_requests()[0]);
@@ -524,12 +524,12 @@ TEST_F(RequestQueueStoreTest, GetRequestsByIds) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- store->AddRequest(request1,
+ store->AddRequest(request1, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
kUserRequested);
- store->AddRequest(request2,
+ store->AddRequest(request2, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
this->PumpLoop();
@@ -587,12 +587,12 @@ TEST_F(RequestQueueStoreTest, AddRequest) {
kUserRequested);
request.set_original_url(kUrl2);
- store->AddRequest(request,
+ store->AddRequest(request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
- ASSERT_EQ(ItemActionStatus::NOT_FOUND, this->last_add_status());
+ ASSERT_EQ(base::nullopt, this->last_add_result());
this->PumpLoop();
- ASSERT_EQ(ItemActionStatus::SUCCESS, this->last_add_status());
+ ASSERT_EQ(AddRequestResult::SUCCESS, this->last_add_result());
// Verifying get reqeust results after a request was added.
this->ClearResults();
@@ -606,12 +606,12 @@ TEST_F(RequestQueueStoreTest, AddRequest) {
// Verify it is not possible to add the same request twice.
this->ClearResults();
- store->AddRequest(request,
+ store->AddRequest(request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
- ASSERT_EQ(ItemActionStatus::NOT_FOUND, this->last_add_status());
+ ASSERT_EQ(base::nullopt, this->last_add_result());
this->PumpLoop();
- ASSERT_EQ(ItemActionStatus::ALREADY_EXISTS, this->last_add_status());
+ ASSERT_EQ(AddRequestResult::ALREADY_EXISTS, this->last_add_result());
// Check that there is still only one item in the store.
this->ClearResults();
@@ -627,14 +627,14 @@ TEST_F(RequestQueueStoreTest, AddAndGetRequestsMatch) {
std::unique_ptr<RequestQueueStore> store(this->BuildStore());
this->InitializeStore(store.get());
const SavePageRequest request = GetTestRequest();
- store->AddRequest(request,
+ store->AddRequest(request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
store->GetRequests(base::BindOnce(&RequestQueueStoreTestBase::GetRequestsDone,
base::Unretained(this)));
this->PumpLoop();
- ASSERT_EQ(ItemActionStatus::SUCCESS, this->last_add_status());
+ ASSERT_EQ(AddRequestResult::SUCCESS, this->last_add_result());
ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
ASSERT_EQ(1ul, this->last_requests().size());
EXPECT_EQ(request.ToString(), this->last_requests()[0]->ToString());
@@ -647,7 +647,7 @@ TEST_F(RequestQueueStoreTest, UpdateRequest) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- store->AddRequest(original_request,
+ store->AddRequest(original_request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
this->PumpLoop();
@@ -703,12 +703,12 @@ TEST_F(RequestQueueStoreTest, RemoveRequests) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- store->AddRequest(request1,
+ store->AddRequest(request1, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
kUserRequested);
- store->AddRequest(request2,
+ store->AddRequest(request2, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
this->PumpLoop();
@@ -767,7 +767,7 @@ TEST_F(RequestQueueStoreTest, ResetStore) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- store->AddRequest(original_request,
+ store->AddRequest(original_request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
this->PumpLoop();
@@ -797,7 +797,7 @@ TEST_F(RequestQueueStoreTest, SaveCloseReopenRead) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- store->AddRequest(original_request,
+ store->AddRequest(original_request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueStoreTestBase::AddRequestDone,
base::Unretained(this)));
PumpLoop();
diff --git a/chromium/components/offline_pages/core/background/request_queue_task_test_base.cc b/chromium/components/offline_pages/core/background/request_queue_task_test_base.cc
index df6677d191f..6a358b92fc3 100644
--- a/chromium/components/offline_pages/core/background/request_queue_task_test_base.cc
+++ b/chromium/components/offline_pages/core/background/request_queue_task_test_base.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/offline_pages/core/background/request_queue_task_test_base.h"
+#include "base/bind.h"
namespace offline_pages {
diff --git a/chromium/components/offline_pages/core/background/request_queue_unittest.cc b/chromium/components/offline_pages/core/background/request_queue_unittest.cc
index 2ae4d721411..460db161e66 100644
--- a/chromium/components/offline_pages/core/background/request_queue_unittest.cc
+++ b/chromium/components/offline_pages/core/background/request_queue_unittest.cc
@@ -212,8 +212,9 @@ TEST_F(RequestQueueTest, AddRequest) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
ASSERT_EQ(AddRequestResult::SUCCESS, last_add_result());
ASSERT_TRUE(last_added_request());
@@ -230,8 +231,9 @@ TEST_F(RequestQueueTest, RemoveRequest) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
ASSERT_EQ(kRequestId, last_added_request()->request_id());
@@ -258,14 +260,15 @@ TEST_F(RequestQueueTest, RemoveSeveralRequests) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
ASSERT_EQ(kRequestId, last_added_request()->request_id());
SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
kUserRequested);
- queue()->AddRequest(request2,
+ queue()->AddRequest(request2, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueTest::AddRequestDone,
base::Unretained(this)));
PumpLoop();
@@ -306,8 +309,9 @@ TEST_F(RequestQueueTest, PauseAndResume) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
ASSERT_EQ(kRequestId, last_added_request()->request_id());
@@ -375,14 +379,14 @@ TEST_F(RequestQueueTest, MultipleRequestsAddGetRemove) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request1,
+ queue()->AddRequest(request1, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueTest::AddRequestDone,
base::Unretained(this)));
PumpLoop();
ASSERT_EQ(request1.request_id(), last_added_request()->request_id());
SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
kUserRequested);
- queue()->AddRequest(request2,
+ queue()->AddRequest(request2, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueTest::AddRequestDone,
base::Unretained(this)));
PumpLoop();
@@ -418,8 +422,9 @@ TEST_F(RequestQueueTest, MarkAttemptStarted) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
base::Time before_time = OfflineTimeNow();
@@ -473,8 +478,9 @@ TEST_F(RequestQueueTest, MarkAttemptAborted) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
// Start request.
@@ -521,8 +527,9 @@ TEST_F(RequestQueueTest, MarkAttemptCompleted) {
base::Time creation_time = OfflineTimeNow();
SavePageRequest request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(request, base::BindOnce(&RequestQueueTest::AddRequestDone,
- base::Unretained(this)));
+ queue()->AddRequest(request, RequestQueue::AddOptions(),
+ base::BindOnce(&RequestQueueTest::AddRequestDone,
+ base::Unretained(this)));
PumpLoop();
// Start request.
@@ -555,7 +562,7 @@ TEST_F(RequestQueueTest, CleanStaleRequests) {
SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time,
kUserRequested);
- queue()->AddRequest(original_request,
+ queue()->AddRequest(original_request, RequestQueue::AddOptions(),
base::BindOnce(&RequestQueueTest::AddRequestDone,
base::Unretained(this)));
this->PumpLoop();
diff --git a/chromium/components/offline_pages/core/background/test_request_queue_store.cc b/chromium/components/offline_pages/core/background/test_request_queue_store.cc
index 027e13f6570..572d2b67c5a 100644
--- a/chromium/components/offline_pages/core/background/test_request_queue_store.cc
+++ b/chromium/components/offline_pages/core/background/test_request_queue_store.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/background/test_request_queue_store.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/offline_pages/core/background/request_queue_store.h"
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 1f87fa6ccc0..be9cc069d6b 100644
--- a/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc
+++ b/chromium/components/offline_pages/core/downloads/download_ui_adapter.cc
@@ -11,6 +11,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "components/offline_items_collection/core/fail_state.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/request_notifier.h"
#include "components/offline_pages/core/background/save_page_request.h"
@@ -30,17 +31,22 @@ namespace offline_pages {
namespace {
+bool RequestsMatchesGuid(const std::string& guid,
+ ClientPolicyController* policy_controller,
+ const SavePageRequest& request) {
+ return request.client_id().id == guid &&
+ policy_controller->IsSupportedByDownload(
+ request.client_id().name_space);
+}
+
std::vector<int64_t> FilterRequestsByGuid(
std::vector<std::unique_ptr<SavePageRequest>> requests,
const std::string& guid,
ClientPolicyController* policy_controller) {
std::vector<int64_t> request_ids;
for (const auto& request : requests) {
- if (request->client_id().id == guid &&
- policy_controller->IsSupportedByDownload(
- request->client_id().name_space)) {
+ if (RequestsMatchesGuid(guid, policy_controller, *request))
request_ids.push_back(request->request_id());
- }
}
return request_ids;
}
@@ -195,6 +201,9 @@ void DownloadUIAdapter::OnCompleted(
observer.OnItemRemoved(item.id);
} else {
item.state = offline_items_collection::OfflineItemState::FAILED;
+ // Actual cause could be server or network related, but we need to pick
+ // a fail_state.
+ item.fail_state = offline_items_collection::FailState::SERVER_FAILED;
for (auto& observer : observers_)
observer.OnItemUpdated(item);
}
@@ -389,19 +398,12 @@ void DownloadUIAdapter::RemoveItem(const ContentId& id) {
}
void DownloadUIAdapter::CancelDownload(const ContentId& id) {
- // TODO(fgorski): Clean this up in a way where 2 round trips + GetAllRequests
- // is not necessary. E.g. CancelByGuid(guid) might do the trick.
- request_coordinator_->GetAllRequests(
- base::BindOnce(&DownloadUIAdapter::CancelDownloadContinuation,
- weak_ptr_factory_.GetWeakPtr(), id.id));
-}
-
-void DownloadUIAdapter::CancelDownloadContinuation(
- const std::string& guid,
- std::vector<std::unique_ptr<SavePageRequest>> requests) {
- std::vector<int64_t> request_ids = FilterRequestsByGuid(
- std::move(requests), guid, request_coordinator_->GetPolicyController());
- request_coordinator_->RemoveRequests(request_ids, base::DoNothing());
+ auto predicate =
+ base::BindRepeating(&RequestsMatchesGuid, id.id,
+ // Since RequestCoordinator is calling us back,
+ // binding its policy controller is safe.
+ request_coordinator_->GetPolicyController());
+ request_coordinator_->RemoveRequestsIf(predicate, base::DoNothing());
}
void DownloadUIAdapter::PauseDownload(const ContentId& id) {
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 c75341979aa..c7984bdde73 100644
--- a/chromium/components/offline_pages/core/downloads/download_ui_adapter.h
+++ b/chromium/components/offline_pages/core/downloads/download_ui_adapter.h
@@ -129,9 +129,6 @@ class DownloadUIAdapter : public OfflineContentProvider,
std::unique_ptr<offline_items_collection::OfflineItemVisuals>)>;
// Task callbacks.
- void CancelDownloadContinuation(
- const std::string& guid,
- std::vector<std::unique_ptr<SavePageRequest>> requests);
void PauseDownloadContinuation(
const std::string& guid,
std::vector<std::unique_ptr<SavePageRequest>> requests);
diff --git a/chromium/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc b/chromium/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
index 007bcc0562b..4de15b8cc14 100644
--- a/chromium/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
+++ b/chromium/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
@@ -12,6 +12,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/run_loop.h"
@@ -157,7 +158,7 @@ class MockOfflinePageModel : public StubOfflinePageModel {
if (page.second.client_id.id == guid) {
DeletedPageInfo info(page.second.offline_id, kSystemDownloadId,
page.second.client_id, page.second.request_origin,
- page.second.original_url);
+ page.second.original_url_if_different);
observer_->OfflinePageDeleted(info);
pages.erase(page.first);
return;
diff --git a/chromium/components/offline_pages/core/downloads/offline_item_conversions.cc b/chromium/components/offline_pages/core/downloads/offline_item_conversions.cc
index 1ec2c6e9ed8..7223f834988 100644
--- a/chromium/components/offline_pages/core/downloads/offline_item_conversions.cc
+++ b/chromium/components/offline_pages/core/downloads/offline_item_conversions.cc
@@ -33,8 +33,7 @@ const std::string GetDisplayName(
}
const std::string GetMimeType() {
- return offline_pages::IsOfflinePagesSharingEnabled() ? "multipart/related"
- : "text/html";
+ return "multipart/related";
}
} // namespace
@@ -58,7 +57,7 @@ OfflineItem OfflineItemConversions::CreateOfflineItem(
item.file_path = page.file_path;
item.mime_type = GetMimeType();
item.page_url = page.url;
- item.original_url = page.original_url;
+ item.original_url = page.original_url_if_different;
item.progress.value = 100;
item.progress.max = 100;
item.progress.unit = OfflineItemProgressUnit::PERCENTAGE;
diff --git a/chromium/components/offline_pages/core/downloads/offline_item_conversions_unittest.cc b/chromium/components/offline_pages/core/downloads/offline_item_conversions_unittest.cc
index 50934a34320..3aa47c8e951 100644
--- a/chromium/components/offline_pages/core/downloads/offline_item_conversions_unittest.cc
+++ b/chromium/components/offline_pages/core/downloads/offline_item_conversions_unittest.cc
@@ -39,7 +39,7 @@ TEST(OfflineItemConversionsTest, OfflinePageItemConversion) {
OfflinePageItem offline_page_item(kTestUrl, offline_id, client_id, file_path,
file_size, creation_time);
- offline_page_item.original_url = kTestOriginalUrl;
+ offline_page_item.original_url_if_different = kTestOriginalUrl;
offline_page_item.title = base::UTF8ToUTF16(title);
offline_page_item.last_access_time = last_access_time;
offline_page_item.file_missing_time = base::Time::Now();
@@ -70,18 +70,13 @@ TEST(OfflineItemConversionsTest, OfflinePageItemConversion) {
EXPECT_EQ(FailState::NO_FAILURE, offline_item.fail_state);
EXPECT_EQ(PendingState::NOT_PENDING, offline_item.pending_state);
- // Enabled P2P sharing and flag the item as suggested when creating the
- // OfflineItem. Then check that only the mime type is and is_suggested
- // information changed.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(kOfflinePagesSharingFeature);
+ // Flag the item as suggested when creating the OfflineItem. Then check that
+ // only is_suggested information changed.
OfflineItem offline_item_p2p =
OfflineItemConversions::CreateOfflineItem(offline_page_item, false);
- EXPECT_EQ("text/html", offline_item_p2p.mime_type);
EXPECT_FALSE(offline_item_p2p.is_suggested);
// Change offline_item_p2p to match offline_item and check that it does.
- offline_item_p2p.mime_type = "multipart/related";
offline_item_p2p.is_suggested = true;
EXPECT_EQ(offline_item, offline_item_p2p);
}
@@ -123,16 +118,9 @@ TEST(OfflineItemConversionsTest, SavePageRequestConversion) {
EXPECT_EQ(FailState::NETWORK_FAILED, offline_item.fail_state);
EXPECT_EQ(PendingState::NOT_PENDING, offline_item.pending_state);
- // Disable P2P sharing of offline pages and check that only the mime type is
- // different.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(kOfflinePagesSharingFeature);
+ // Check that the offline item matches one we create.
OfflineItem offline_item_p2p =
OfflineItemConversions::CreateOfflineItem(save_page_request);
- EXPECT_EQ("text/html", offline_item_p2p.mime_type);
-
- // Change offline_item_p2p to match offline_item and check that it does.
- offline_item_p2p.mime_type = "multipart/related";
EXPECT_EQ(offline_item, offline_item_p2p);
}
diff --git a/chromium/components/offline_pages/core/model/add_page_task.cc b/chromium/components/offline_pages/core/model/add_page_task.cc
index f8f601a00f2..cd4e73e862a 100644
--- a/chromium/components/offline_pages/core/model/add_page_task.cc
+++ b/chromium/components/offline_pages/core/model/add_page_task.cc
@@ -57,7 +57,7 @@ ItemActionStatus AddOfflinePageSync(const OfflinePageItem& item,
statement.BindInt64(7, store_utils::ToDatabaseTime(item.last_access_time));
statement.BindInt(8, item.access_count);
statement.BindString16(9, item.title);
- statement.BindString(10, item.original_url.spec());
+ statement.BindString(10, item.original_url_if_different.spec());
statement.BindString(11, item.request_origin);
statement.BindInt64(12, item.system_download_id);
statement.BindInt64(13, store_utils::ToDatabaseTime(item.file_missing_time));
diff --git a/chromium/components/offline_pages/core/model/add_page_task_unittest.cc b/chromium/components/offline_pages/core/model/add_page_task_unittest.cc
index bca504c8c85..dde4408edd3 100644
--- a/chromium/components/offline_pages/core/model/add_page_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/add_page_task_unittest.cc
@@ -95,7 +95,7 @@ TEST_F(AddPageTaskTest, AddPageWithAllFieldsSet) {
kTestFilePath, kTestFileSize, base::Time::Now(),
kTestOrigin);
page.title = kTestTitle;
- page.original_url = kTestUrl2;
+ page.original_url_if_different = kTestUrl2;
page.system_download_id = kTestDownloadId;
page.file_missing_time = base::Time::Now();
page.digest = kTestDigest;
diff --git a/chromium/components/offline_pages/core/model/cleanup_thumbnails_task.cc b/chromium/components/offline_pages/core/model/cleanup_thumbnails_task.cc
index 8e1c40c2726..76b90d2f127 100644
--- a/chromium/components/offline_pages/core/model/cleanup_thumbnails_task.cc
+++ b/chromium/components/offline_pages/core/model/cleanup_thumbnails_task.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/model/cleanup_thumbnails_task.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "components/offline_pages/core/offline_page_metadata_store.h"
#include "components/offline_pages/core/offline_store_utils.h"
diff --git a/chromium/components/offline_pages/core/model/cleanup_thumbnails_task_unittest.cc b/chromium/components/offline_pages/core/model/cleanup_thumbnails_task_unittest.cc
index 0dd76f8743e..2c0a49f45b0 100644
--- a/chromium/components/offline_pages/core/model/cleanup_thumbnails_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/cleanup_thumbnails_task_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind_helpers.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
@@ -41,7 +42,8 @@ class CleanupThumbnailsTaskTest : public ModelTaskTestBase {
TEST_F(CleanupThumbnailsTaskTest, DbConnectionIsNull) {
base::MockCallback<StoreThumbnailTask::CompleteCallback> callback;
EXPECT_CALL(callback, Run(false)).Times(1);
- store()->SetStateForTesting(StoreState::FAILED_LOADING, true);
+ store()->SetInitializationStatusForTesting(
+ SqlStoreBase::InitializationStatus::kFailure, true);
RunTask(std::make_unique<CleanupThumbnailsTask>(
store(), store_utils::FromDatabaseTime(1000), callback.Get()));
}
diff --git a/chromium/components/offline_pages/core/model/clear_digest_task.cc b/chromium/components/offline_pages/core/model/clear_digest_task.cc
index 3b4ca6ba976..e78c0b1d766 100644
--- a/chromium/components/offline_pages/core/model/clear_digest_task.cc
+++ b/chromium/components/offline_pages/core/model/clear_digest_task.cc
@@ -31,7 +31,7 @@ ClearDigestTask::ClearDigestTask(OfflinePageMetadataStore* store,
DCHECK(store_);
}
-ClearDigestTask::~ClearDigestTask(){};
+ClearDigestTask::~ClearDigestTask() {}
void ClearDigestTask::Run() {
store_->Execute(base::BindOnce(&ClearDigestSync, offline_id_),
diff --git a/chromium/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc b/chromium/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
index 4e00e48e7d3..78678f650a4 100644
--- a/chromium/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "components/offline_pages/core/model/model_task_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/components/offline_pages/core/model/delete_page_task.cc b/chromium/components/offline_pages/core/model/delete_page_task.cc
index 4784e4d2b01..159bed38893 100644
--- a/chromium/components/offline_pages/core/model/delete_page_task.cc
+++ b/chromium/components/offline_pages/core/model/delete_page_task.cc
@@ -4,6 +4,8 @@
#include "components/offline_pages/core/model/delete_page_task.h"
+#include <iterator>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -41,14 +43,18 @@ namespace {
// in the SQL query and the result of it can be simply fetched by calling
// statement.Column*(INFO_WRAPPER_COUNT), as it's the last column. For example,
// please take a look at GetCachedDeletedPageInfoWrappersByUrlPredicateSync.
-#define INFO_WRAPPER_FIELDS \
- "offline_id, system_download_id, client_namespace, client_id, file_path, " \
- "request_origin, access_count, creation_time, online_url"
-#define INFO_WRAPPER_FIELD_COUNT 8
+#define INFO_WRAPPER_FIELDS \
+ "offline_id,system_download_id,client_namespace,client_id,file_path," \
+ "request_origin,access_count,creation_time,online_url,original_url"
+#define INFO_WRAPPER_FIELD_COUNT 10
struct DeletedPageInfoWrapper {
- DeletedPageInfoWrapper();
- DeletedPageInfoWrapper(const DeletedPageInfoWrapper& other);
+ DeletedPageInfoWrapper() = default;
+ // Move-only to avoid copies.
+ DeletedPageInfoWrapper(const DeletedPageInfoWrapper& other) = delete;
+ DeletedPageInfoWrapper(DeletedPageInfoWrapper&& other) = default;
+ DeletedPageInfoWrapper& operator=(DeletedPageInfoWrapper&& other) = default;
+
int64_t offline_id;
int64_t system_download_id;
ClientId client_id;
@@ -58,8 +64,22 @@ struct DeletedPageInfoWrapper {
int access_count;
base::Time creation_time;
GURL url;
+ GURL original_url_if_different;
};
+// Consumes |wrapper| and returns an |OfflinePageModel::DeletePageInfo|.
+OfflinePageModel::DeletedPageInfo ExtractPageInfo(
+ DeletedPageInfoWrapper&& wrapper) {
+ OfflinePageModel::DeletedPageInfo info;
+ info.offline_id = wrapper.offline_id;
+ info.system_download_id = wrapper.system_download_id;
+ info.client_id = std::move(wrapper.client_id);
+ info.request_origin = std::move(wrapper.request_origin);
+ info.url = std::move(wrapper.url);
+ info.original_url_if_different = std::move(wrapper.original_url_if_different);
+ return info;
+}
+
DeletedPageInfoWrapper CreateInfoWrapper(const sql::Statement& statement) {
DeletedPageInfoWrapper info_wrapper;
info_wrapper.offline_id = statement.ColumnInt64(0);
@@ -73,13 +93,10 @@ DeletedPageInfoWrapper CreateInfoWrapper(const sql::Statement& statement) {
info_wrapper.creation_time =
store_utils::FromDatabaseTime(statement.ColumnInt64(7));
info_wrapper.url = GURL(statement.ColumnString(8));
+ info_wrapper.original_url_if_different = GURL(statement.ColumnString(9));
return info_wrapper;
}
-DeletedPageInfoWrapper::DeletedPageInfoWrapper() = default;
-DeletedPageInfoWrapper::DeletedPageInfoWrapper(
- const DeletedPageInfoWrapper& other) = default;
-
void ReportDeletePageHistograms(
const std::vector<DeletedPageInfoWrapper>& info_wrappers) {
const int max_minutes = base::TimeDelta::FromDays(365).InMinutes();
@@ -121,7 +138,7 @@ bool DeletePageEntryByOfflineIdSync(sql::Database* db, int64_t offline_id) {
// file is deleted successfully, there will be no such issue.
DeletePageTaskResult DeletePagesByDeletedPageInfoWrappersSync(
sql::Database* db,
- const std::vector<DeletedPageInfoWrapper>& info_wrappers) {
+ std::vector<DeletedPageInfoWrapper> info_wrappers) {
std::vector<OfflinePageModel::DeletedPageInfo> deleted_page_infos;
// If there's no page to delete, return an empty list with SUCCESS.
@@ -131,14 +148,11 @@ DeletePageTaskResult DeletePagesByDeletedPageInfoWrappersSync(
ReportDeletePageHistograms(info_wrappers);
bool any_archive_deleted = false;
- for (const auto& info_wrapper : info_wrappers) {
+ for (auto& info_wrapper : info_wrappers) {
if (DeleteArchiveSync(info_wrapper.file_path)) {
any_archive_deleted = true;
if (DeletePageEntryByOfflineIdSync(db, info_wrapper.offline_id)) {
- deleted_page_infos.emplace_back(
- info_wrapper.offline_id, info_wrapper.system_download_id,
- info_wrapper.client_id, info_wrapper.request_origin,
- info_wrapper.url);
+ deleted_page_infos.push_back(ExtractPageInfo(std::move(info_wrapper)));
}
}
}
@@ -185,10 +199,10 @@ DeletePageTaskResult DeletePagesByOfflineIdsSync(
for (int64_t offline_id : offline_ids) {
DeletedPageInfoWrapper info;
if (GetDeletedPageInfoWrapperByOfflineIdSync(db, offline_id, &info))
- infos.push_back(info);
+ infos.push_back(std::move(info));
}
DeletePageTaskResult result =
- DeletePagesByDeletedPageInfoWrappersSync(db, infos);
+ DeletePagesByDeletedPageInfoWrappersSync(db, std::move(infos));
if (!transaction.Commit())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
@@ -231,11 +245,12 @@ DeletePageTaskResult DeletePagesByClientIdsSync(
for (ClientId client_id : client_ids) {
std::vector<DeletedPageInfoWrapper> temp_infos =
GetDeletedPageInfoWrappersByClientIdSync(db, client_id);
- infos.insert(infos.end(), temp_infos.begin(), temp_infos.end());
+ infos.insert(infos.end(), std::make_move_iterator(temp_infos.begin()),
+ std::make_move_iterator(temp_infos.end()));
}
DeletePageTaskResult result =
- DeletePagesByDeletedPageInfoWrappersSync(db, infos);
+ DeletePagesByDeletedPageInfoWrappersSync(db, std::move(infos));
if (!transaction.Commit())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
@@ -282,11 +297,12 @@ DeletePageTaskResult DeletePagesByClientIdsAndOriginSync(
std::vector<DeletedPageInfoWrapper> temp_infos =
GetDeletedPageInfoWrappersByClientIdAndOriginSync(db, client_id,
origin);
- infos.insert(infos.end(), temp_infos.begin(), temp_infos.end());
+ infos.insert(infos.end(), std::make_move_iterator(temp_infos.begin()),
+ std::make_move_iterator(temp_infos.end()));
}
DeletePageTaskResult result =
- DeletePagesByDeletedPageInfoWrappersSync(db, infos);
+ DeletePagesByDeletedPageInfoWrappersSync(db, std::move(infos));
if (!transaction.Commit())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
@@ -315,7 +331,7 @@ GetCachedDeletedPageInfoWrappersByUrlPredicateSync(
GURL(statement.ColumnString(INFO_WRAPPER_FIELD_COUNT))))
continue;
DeletedPageInfoWrapper info_wrapper = CreateInfoWrapper(statement);
- info_wrappers.push_back(info_wrapper);
+ info_wrappers.push_back(std::move(info_wrapper));
}
}
return info_wrappers;
@@ -331,11 +347,11 @@ DeletePageTaskResult DeleteCachedPagesByUrlPredicateSync(
if (!transaction.Begin())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
- const std::vector<DeletedPageInfoWrapper>& infos =
+ std::vector<DeletedPageInfoWrapper> infos =
GetCachedDeletedPageInfoWrappersByUrlPredicateSync(db, namespaces,
predicate);
DeletePageTaskResult result =
- DeletePagesByDeletedPageInfoWrappersSync(db, infos);
+ DeletePagesByDeletedPageInfoWrappersSync(db, std::move(infos));
if (!transaction.Commit())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
@@ -363,7 +379,7 @@ GetDeletedPageInfoWrappersForPageLimitDeletion(sql::Database* db,
while (statement.Step()) {
DeletedPageInfoWrapper info_wrapper = CreateInfoWrapper(statement);
- info_wrappers.push_back(info_wrapper);
+ info_wrappers.push_back(std::move(info_wrapper));
}
// Since the page information was selected by ascending order of last access
@@ -389,11 +405,11 @@ DeletePageTaskResult DeletePagesForPageLimit(const GURL& url,
if (!transaction.Begin())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
- const std::vector<DeletedPageInfoWrapper>& infos =
+ std::vector<DeletedPageInfoWrapper> infos =
GetDeletedPageInfoWrappersForPageLimitDeletion(db, url, name_space,
limit);
DeletePageTaskResult result =
- DeletePagesByDeletedPageInfoWrappersSync(db, infos);
+ DeletePagesByDeletedPageInfoWrappersSync(db, std::move(infos));
if (!transaction.Commit())
return DeletePageTaskResult(DeletePageResult::STORE_FAILURE, {});
diff --git a/chromium/components/offline_pages/core/model/delete_page_task_unittest.cc b/chromium/components/offline_pages/core/model/delete_page_task_unittest.cc
index 90bc107e153..09a787a3e2b 100644
--- a/chromium/components/offline_pages/core/model/delete_page_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/delete_page_task_unittest.cc
@@ -35,6 +35,10 @@ const GURL kTestUrl2("http://other.page.com");
const int64_t kTestOfflineIdNoMatch = 20170905LL;
const ClientId kTestClientIdNoMatch(kTestNamespace, "20170905");
+GURL OriginalUrl() {
+ return GURL("http://original.com");
+}
+
} // namespace
class DeletePageTaskTest : public ModelTaskTestBase {
@@ -93,6 +97,36 @@ bool DeletePageTaskTest::CheckPageDeleted(const OfflinePageItem& page) {
return !base::PathExists(page.file_path) && !stored_page;
}
+// Delete a page and verify all the information in DeletedPageInfo is accurate.
+TEST_F(DeletePageTaskTest, DeletedPageInfoIsPopulated) {
+ generator()->SetNamespace(kTestNamespace);
+ OfflinePageItem page1 = generator()->CreateItemWithTempFile();
+ page1.url = kTestUrl1;
+ page1.original_url_if_different = OriginalUrl();
+ page1.request_origin = "test-origin";
+ page1.system_download_id = 1234;
+ store_test_util()->InsertItem(page1);
+
+ // Run DeletePageTask for to delete the page.
+ std::vector<int64_t> offline_ids({page1.offline_id});
+ auto task = DeletePageTask::CreateTaskMatchingOfflineIds(
+ store(), delete_page_callback(), offline_ids);
+ RunTask(std::move(task));
+
+ EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_page_result());
+ EXPECT_EQ(1UL, last_deleted_page_infos().size());
+
+ // Verify original_url is returned via DeletedPageInfo.
+ const DeletedPageInfo& info = last_deleted_page_infos()[0];
+ EXPECT_EQ(page1.url, info.url);
+ EXPECT_EQ(page1.client_id, info.client_id);
+ EXPECT_EQ(page1.request_origin, info.request_origin);
+ EXPECT_EQ(page1.system_download_id, info.system_download_id);
+ EXPECT_EQ(page1.offline_id, info.offline_id);
+ EXPECT_EQ(OriginalUrl(), info.original_url_if_different);
+ EXPECT_EQ(OriginalUrl(), info.GetOriginalUrl());
+}
+
TEST_F(DeletePageTaskTest, DeletePageByOfflineId) {
// Add 3 pages and try to delete 2 of them using offline id.
generator()->SetNamespace(kTestNamespace);
diff --git a/chromium/components/offline_pages/core/model/get_pages_task.cc b/chromium/components/offline_pages/core/model/get_pages_task.cc
index 0d47018bab9..61325c5add5 100644
--- a/chromium/components/offline_pages/core/model/get_pages_task.cc
+++ b/chromium/components/offline_pages/core/model/get_pages_task.cc
@@ -54,7 +54,7 @@ OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) {
item.last_access_time = last_access_time;
item.access_count = access_count;
item.title = title;
- item.original_url = original_url;
+ item.original_url_if_different = original_url;
item.request_origin = request_origin;
item.system_download_id = system_download_id;
item.file_missing_time = file_missing_time;
@@ -187,8 +187,8 @@ ReadResult ReadPagesByUrlSync(const GURL& url, sql::Database* db) {
while (statement.Step()) {
OfflinePageItem temp_item = MakeOfflinePageItem(&statement);
if (temp_item.url.ReplaceComponents(remove_fragment) == url_to_match ||
- temp_item.original_url.ReplaceComponents(remove_fragment) ==
- url_to_match) {
+ temp_item.original_url_if_different.ReplaceComponents(
+ remove_fragment) == url_to_match) {
result.pages.push_back(temp_item);
}
}
diff --git a/chromium/components/offline_pages/core/model/get_pages_task_unittest.cc b/chromium/components/offline_pages/core/model/get_pages_task_unittest.cc
index d55772e54ba..d5c2a97f3d7 100644
--- a/chromium/components/offline_pages/core/model/get_pages_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/get_pages_task_unittest.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <utility>
+#include "base/bind.h"
#include "base/time/time.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#include "components/offline_pages/core/model/model_task_test_base.h"
diff --git a/chromium/components/offline_pages/core/model/get_thumbnail_task.cc b/chromium/components/offline_pages/core/model/get_thumbnail_task.cc
index fe0195b8642..d82812222cc 100644
--- a/chromium/components/offline_pages/core/model/get_thumbnail_task.cc
+++ b/chromium/components/offline_pages/core/model/get_thumbnail_task.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/model/get_thumbnail_task.h"
+#include "base/bind.h"
#include "components/offline_pages/core/offline_page_metadata_store.h"
#include "components/offline_pages/core/offline_store_utils.h"
#include "sql/database.h"
diff --git a/chromium/components/offline_pages/core/model/get_thumbnail_task_unittest.cc b/chromium/components/offline_pages/core/model/get_thumbnail_task_unittest.cc
index 448f722605c..a546dff8efb 100644
--- a/chromium/components/offline_pages/core/model/get_thumbnail_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/get_thumbnail_task_unittest.cc
@@ -91,7 +91,8 @@ TEST_F(GetThumbnailTaskTest, DbConnectionIsNull) {
called = true;
EXPECT_FALSE(result);
});
- store()->SetStateForTesting(StoreState::FAILED_LOADING, true);
+ store()->SetInitializationStatusForTesting(
+ SqlStoreBase::InitializationStatus::kFailure, true);
RunTask(std::make_unique<GetThumbnailTask>(store(), 1, std::move(callback)));
diff --git a/chromium/components/offline_pages/core/model/has_thumbnail_task.cc b/chromium/components/offline_pages/core/model/has_thumbnail_task.cc
index 391e1aef59f..9a6bd2b94a6 100644
--- a/chromium/components/offline_pages/core/model/has_thumbnail_task.cc
+++ b/chromium/components/offline_pages/core/model/has_thumbnail_task.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/model/has_thumbnail_task.h"
+#include "base/bind.h"
#include "components/offline_pages/core/offline_page_metadata_store.h"
#include "sql/database.h"
#include "sql/statement.h"
diff --git a/chromium/components/offline_pages/core/model/has_thumbnail_task_unittest.cc b/chromium/components/offline_pages/core/model/has_thumbnail_task_unittest.cc
index f7fe69abc21..0684225ba1d 100644
--- a/chromium/components/offline_pages/core/model/has_thumbnail_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/has_thumbnail_task_unittest.cc
@@ -50,7 +50,8 @@ TEST_F(HasThumbnailTaskTest, DbConnectionIsNull) {
RunTask(
std::make_unique<StoreThumbnailTask>(store(), thumb, base::DoNothing()));
- store()->SetStateForTesting(StoreState::FAILED_LOADING, true);
+ store()->SetInitializationStatusForTesting(
+ SqlStoreBase::InitializationStatus::kFailure, true);
base::MockCallback<ThumbnailExistsCallback> exists_callback;
EXPECT_CALL(exists_callback, Run(false));
RunTask(std::make_unique<HasThumbnailTask>(store(), thumb.offline_id,
diff --git a/chromium/components/offline_pages/core/model/mark_page_accessed_task.cc b/chromium/components/offline_pages/core/model/mark_page_accessed_task.cc
index 9e3de269067..7e25747c134 100644
--- a/chromium/components/offline_pages/core/model/mark_page_accessed_task.cc
+++ b/chromium/components/offline_pages/core/model/mark_page_accessed_task.cc
@@ -82,7 +82,7 @@ MarkPageAccessedTask::MarkPageAccessedTask(OfflinePageMetadataStore* store,
DCHECK(store_);
}
-MarkPageAccessedTask::~MarkPageAccessedTask(){};
+MarkPageAccessedTask::~MarkPageAccessedTask() {}
void MarkPageAccessedTask::Run() {
store_->Execute(
diff --git a/chromium/components/offline_pages/core/model/offline_page_item_generator.cc b/chromium/components/offline_pages/core/model/offline_page_item_generator.cc
index 3cf48e64096..619b017bb56 100644
--- a/chromium/components/offline_pages/core/model/offline_page_item_generator.cc
+++ b/chromium/components/offline_pages/core/model/offline_page_item_generator.cc
@@ -21,12 +21,12 @@ OfflinePageItem OfflinePageItemGenerator::CreateItem() {
item.offline_id = store_utils::GenerateOfflineId();
item.client_id.name_space = namespace_;
if (id_.empty())
- item.client_id.id = base::Int64ToString(item.offline_id);
+ item.client_id.id = base::NumberToString(item.offline_id);
else
item.client_id.id = id_;
item.request_origin = request_origin_;
item.url = url_;
- item.original_url = original_url_;
+ item.original_url_if_different = original_url_;
item.file_size = file_size_;
item.creation_time = creation_time_;
item.last_access_time = last_access_time_;
diff --git a/chromium/components/offline_pages/core/model/offline_page_model_taskified.cc b/chromium/components/offline_pages/core/model/offline_page_model_taskified.cc
index 0cd118222de..9e04bba3013 100644
--- a/chromium/components/offline_pages/core/model/offline_page_model_taskified.cc
+++ b/chromium/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -517,11 +517,10 @@ void OfflinePageModelTaskified::OnCreateArchiveDone(
// the completion of certain action, i.e., authentication, in the middle.
if (skip_clearing_original_url_for_testing_ ||
save_page_params.original_url != offline_page.url) {
- offline_page.original_url = save_page_params.original_url;
+ offline_page.original_url_if_different = save_page_params.original_url;
}
- if (IsOfflinePagesSharingEnabled() &&
- policy_controller_->IsUserRequestedDownload(
+ if (policy_controller_->IsUserRequestedDownload(
offline_page.client_id.name_space)) {
// If the user intentionally downloaded the page, move it to a public place.
// Note: Moving the archiver instance into the callback so it won't be
@@ -772,9 +771,6 @@ void OfflinePageModelTaskified::OnClearCachedPagesDone(
void OfflinePageModelTaskified::PostSelectItemsMarkedForUpgrade() {
// TODO(fgorski): Make storage permission check. Here or later?
// TODO(fgorski): Check disk space here.
- if (!IsOfflinePagesSharingEnabled())
- return;
-
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindRepeating(
diff --git a/chromium/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/chromium/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
index 3f5faa1432a..a92748525c9 100644
--- a/chromium/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
+++ b/chromium/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -378,7 +378,7 @@ TEST_F(OfflinePageModelTaskifiedTest, SavePageSuccessful) {
EXPECT_EQ(0, saved_page_ptr->access_count);
EXPECT_EQ(0, saved_page_ptr->flags);
EXPECT_EQ(kTestTitle, saved_page_ptr->title);
- EXPECT_EQ(kTestUrl2, saved_page_ptr->original_url);
+ EXPECT_EQ(kTestUrl2, saved_page_ptr->original_url_if_different);
EXPECT_EQ("", saved_page_ptr->request_origin);
EXPECT_EQ(kTestDigest, saved_page_ptr->digest);
@@ -439,7 +439,7 @@ TEST_F(OfflinePageModelTaskifiedTest, SavePageSuccessfulWithSameOriginalUrl) {
EXPECT_EQ(kTestUrl, saved_page_ptr->url);
// The original URL should be empty.
- EXPECT_TRUE(saved_page_ptr->original_url.is_empty());
+ EXPECT_TRUE(saved_page_ptr->original_url_if_different.is_empty());
histogram_tester()->ExpectUniqueSample(
"OfflinePages.SavePageCount",
@@ -479,7 +479,7 @@ TEST_F(OfflinePageModelTaskifiedTest, SavePageSuccessfulWithRequestOrigin) {
EXPECT_EQ(0, saved_page_ptr->access_count);
EXPECT_EQ(0, saved_page_ptr->flags);
EXPECT_EQ(kTestTitle, saved_page_ptr->title);
- EXPECT_EQ(kTestUrl2, saved_page_ptr->original_url);
+ EXPECT_EQ(kTestUrl2, saved_page_ptr->original_url_if_different);
EXPECT_EQ(kTestRequestOrigin, saved_page_ptr->request_origin);
histogram_tester()->ExpectUniqueSample(
diff --git a/chromium/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc b/chromium/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
index f903e1eb556..667d5956688 100644
--- a/chromium/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "components/offline_pages/core/model/model_task_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/components/offline_pages/core/model/store_thumbnail_task.cc b/chromium/components/offline_pages/core/model/store_thumbnail_task.cc
index 22194e11b4a..67e0fb572ac 100644
--- a/chromium/components/offline_pages/core/model/store_thumbnail_task.cc
+++ b/chromium/components/offline_pages/core/model/store_thumbnail_task.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/model/store_thumbnail_task.h"
+#include "base/bind.h"
#include "components/offline_pages/core/offline_page_metadata_store.h"
#include "components/offline_pages/core/offline_store_utils.h"
#include "sql/database.h"
diff --git a/chromium/components/offline_pages/core/model/store_thumbnail_task_unittest.cc b/chromium/components/offline_pages/core/model/store_thumbnail_task_unittest.cc
index 7dc95df8452..41527e0a324 100644
--- a/chromium/components/offline_pages/core/model/store_thumbnail_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/store_thumbnail_task_unittest.cc
@@ -69,7 +69,8 @@ TEST_F(StoreThumbnailTaskTest, AlreadyExists) {
}
TEST_F(StoreThumbnailTaskTest, DbConnectionIsNull) {
- store()->SetStateForTesting(StoreState::FAILED_LOADING, true);
+ store()->SetInitializationStatusForTesting(
+ SqlStoreBase::InitializationStatus::kFailure, true);
OfflinePageThumbnail thumb;
thumb.offline_id = 1;
thumb.expiration = store_utils::FromDatabaseTime(1234);
diff --git a/chromium/components/offline_pages/core/model/update_file_path_task.cc b/chromium/components/offline_pages/core/model/update_file_path_task.cc
index c96e77a9a26..a243a2e0576 100644
--- a/chromium/components/offline_pages/core/model/update_file_path_task.cc
+++ b/chromium/components/offline_pages/core/model/update_file_path_task.cc
@@ -58,7 +58,7 @@ UpdateFilePathTask::UpdateFilePathTask(OfflinePageMetadataStore* store,
DCHECK(store_);
}
-UpdateFilePathTask::~UpdateFilePathTask(){};
+UpdateFilePathTask::~UpdateFilePathTask() {}
void UpdateFilePathTask::Run() {
store_->Execute(base::BindOnce(&UpdateFilePathSync, file_path_, offline_id_),
diff --git a/chromium/components/offline_pages/core/model/update_file_path_task_unittest.cc b/chromium/components/offline_pages/core/model/update_file_path_task_unittest.cc
index 136788f174a..8c2e286109a 100644
--- a/chromium/components/offline_pages/core/model/update_file_path_task_unittest.cc
+++ b/chromium/components/offline_pages/core/model/update_file_path_task_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "components/offline_pages/core/model/model_task_test_base.h"
#include "components/offline_pages/core/model/offline_page_item_generator.h"
diff --git a/chromium/components/offline_pages/core/offline_page_archiver_unittest.cc b/chromium/components/offline_pages/core/offline_page_archiver_unittest.cc
index 4740589695b..d9b00d9508c 100644
--- a/chromium/components/offline_pages/core/offline_page_archiver_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_archiver_unittest.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/offline_page_archiver.h"
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
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 08204a4b3e3..b403c153b4f 100644
--- a/chromium/components/offline_pages/core/offline_page_client_policy.h
+++ b/chromium/components/offline_pages/core/offline_page_client_policy.h
@@ -105,7 +105,7 @@ struct OfflinePageClientPolicy {
: name_space(namespace_val),
lifetime_policy(lifetime_policy_val),
pages_allowed_per_url(pages_allowed_per_url_val),
- feature_policy(feature_policy_val){};
+ feature_policy(feature_policy_val) {}
OfflinePageClientPolicy(std::string namespace_val,
LifetimePolicy lifetime_policy_val,
diff --git a/chromium/components/offline_pages/core/offline_page_feature.cc b/chromium/components/offline_pages/core/offline_page_feature.cc
index 7dbaa2ae49b..abc31d12f54 100644
--- a/chromium/components/offline_pages/core/offline_page_feature.cc
+++ b/chromium/components/offline_pages/core/offline_page_feature.cc
@@ -20,18 +20,12 @@ const char kOfflinePagesUseTestingSnapshotDelay[] =
namespace offline_pages {
-const base::Feature kOfflineBookmarksFeature{"OfflineBookmarks",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kOffliningRecentPagesFeature{
"OfflineRecentPages", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kOfflinePagesCTFeature{"OfflinePagesCT",
base::FEATURE_ENABLED_BY_DEFAULT};
-const base::Feature kOfflinePagesSharingFeature{
- "OfflinePagesSharing", base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kOfflinePagesLivePageSharingFeature{
"OfflinePagesLivePageSharing", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -82,10 +76,6 @@ const base::Feature kOnTheFlyMhtmlHashComputationFeature{
const char kPrefetchingOfflinePagesExperimentsOption[] = "exp";
-bool IsOfflineBookmarksEnabled() {
- return base::FeatureList::IsEnabled(kOfflineBookmarksFeature);
-}
-
bool IsOffliningRecentPagesEnabled() {
return base::FeatureList::IsEnabled(kOffliningRecentPagesFeature);
}
@@ -99,10 +89,6 @@ bool IsOfflinePagesCTEnabled() {
return base::FeatureList::IsEnabled(kOfflinePagesCTFeature);
}
-bool IsOfflinePagesSharingEnabled() {
- return base::FeatureList::IsEnabled(kOfflinePagesSharingFeature);
-}
-
bool IsOfflinePagesLivePageSharingEnabled() {
return base::FeatureList::IsEnabled(kOfflinePagesLivePageSharingFeature);
}
diff --git a/chromium/components/offline_pages/core/offline_page_feature.h b/chromium/components/offline_pages/core/offline_page_feature.h
index 1f847d18def..2fba14e1034 100644
--- a/chromium/components/offline_pages/core/offline_page_feature.h
+++ b/chromium/components/offline_pages/core/offline_page_feature.h
@@ -10,11 +10,9 @@
namespace offline_pages {
-extern const base::Feature kOfflineBookmarksFeature;
extern const base::Feature kOffliningRecentPagesFeature;
extern const base::Feature kOfflinePagesSvelteConcurrentLoadingFeature;
extern const base::Feature kOfflinePagesCTFeature;
-extern const base::Feature kOfflinePagesSharingFeature;
extern const base::Feature kOfflinePagesLivePageSharingFeature;
extern const base::Feature kBackgroundLoaderForDownloadsFeature;
extern const base::Feature kPrefetchingOfflinePagesFeature;
@@ -35,18 +33,12 @@ extern const base::Feature kOnTheFlyMhtmlHashComputationFeature;
// pages.
extern const char kPrefetchingOfflinePagesExperimentsOption[];
-// Returns true if saving bookmarked pages for offline viewing is enabled.
-bool IsOfflineBookmarksEnabled();
-
// Returns true if offlining of recent pages (aka 'Last N pages') is enabled.
bool IsOffliningRecentPagesEnabled();
// Returns true if offline CT features are enabled. See crbug.com/620421.
bool IsOfflinePagesCTEnabled();
-// Returns true if offline page sharing is enabled.
-bool IsOfflinePagesSharingEnabled();
-
// Returns true if live page sharing of offline page is enabled.
bool IsOfflinePagesLivePageSharingEnabled();
diff --git a/chromium/components/offline_pages/core/offline_page_feature_unittest.cc b/chromium/components/offline_pages/core/offline_page_feature_unittest.cc
index 84592c2c116..0a80c376562 100644
--- a/chromium/components/offline_pages/core/offline_page_feature_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_feature_unittest.cc
@@ -10,16 +10,6 @@
namespace offline_pages {
-TEST(OfflinePageFeatureTest, OfflineBookmarks) {
- // Enabled by default.
- EXPECT_TRUE(offline_pages::IsOfflineBookmarksEnabled());
-
- // Check if helper method works correctly when the features is disabled.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(kOfflineBookmarksFeature);
- EXPECT_FALSE(offline_pages::IsOfflineBookmarksEnabled());
-}
-
TEST(OfflinePageFeatureTest, OffliningRecentPages) {
// Enabled by default.
EXPECT_TRUE(offline_pages::IsOffliningRecentPagesEnabled());
@@ -30,16 +20,6 @@ TEST(OfflinePageFeatureTest, OffliningRecentPages) {
EXPECT_FALSE(offline_pages::IsOffliningRecentPagesEnabled());
}
-TEST(OfflinePageFeatureTest, OfflinePagesSharing) {
- // Enabled by default.
- EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled());
-
- // Check if helper method works correctly when the features is disabled.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(kOfflinePagesSharingFeature);
- EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled());
-}
-
TEST(OfflinePageFeatureTest, OfflinePagesLivePageSharing) {
// Disabled by default.
EXPECT_FALSE(
diff --git a/chromium/components/offline_pages/core/offline_page_item.cc b/chromium/components/offline_pages/core/offline_page_item.cc
index e32196f15b5..09cad91edfb 100644
--- a/chromium/components/offline_pages/core/offline_page_item.cc
+++ b/chromium/components/offline_pages/core/offline_page_item.cc
@@ -77,7 +77,8 @@ bool OfflinePageItem::operator==(const OfflinePageItem& other) const {
file_size == other.file_size && creation_time == other.creation_time &&
last_access_time == other.last_access_time &&
access_count == other.access_count && title == other.title &&
- flags == other.flags && original_url == other.original_url &&
+ flags == other.flags &&
+ original_url_if_different == other.original_url_if_different &&
request_origin == other.request_origin &&
system_download_id == other.system_download_id &&
file_missing_time == other.file_missing_time &&
diff --git a/chromium/components/offline_pages/core/offline_page_item.h b/chromium/components/offline_pages/core/offline_page_item.h
index dcf7c0245bb..7107e8ecfd7 100644
--- a/chromium/components/offline_pages/core/offline_page_item.h
+++ b/chromium/components/offline_pages/core/offline_page_item.h
@@ -49,6 +49,11 @@ struct OfflinePageItem {
bool operator==(const OfflinePageItem& other) const;
bool operator<(const OfflinePageItem& other) const;
+ const GURL& GetOriginalUrl() const {
+ return original_url_if_different.is_empty() ? url
+ : original_url_if_different;
+ }
+
// The URL of the page. This is the last committed URL. In the case that
// redirects occur, access |original_url| for the original URL.
GURL url;
@@ -76,7 +81,7 @@ struct OfflinePageItem {
Flags flags;
// The original URL of the page if not empty. Otherwise, this is set to empty
// and |url| should be accessed instead.
- GURL original_url;
+ GURL original_url_if_different;
// The app, if any, that the item was saved on behalf of.
// Empty string implies Chrome.
std::string request_origin;
diff --git a/chromium/components/offline_pages/core/offline_page_item_utils.cc b/chromium/components/offline_pages/core/offline_page_item_utils.cc
new file mode 100644
index 00000000000..081a43b4824
--- /dev/null
+++ b/chromium/components/offline_pages/core/offline_page_item_utils.cc
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/core/offline_page_item_utils.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+
+bool EqualsIgnoringFragment(const GURL& lhs, const GURL& rhs) {
+ GURL::Replacements remove_params;
+ remove_params.ClearRef();
+
+ GURL lhs_stripped = lhs.ReplaceComponents(remove_params);
+ GURL rhs_stripped = rhs.ReplaceComponents(remove_params);
+
+ return lhs_stripped == rhs_stripped;
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/offline_page_item_utils.h b/chromium/components/offline_pages/core/offline_page_item_utils.h
new file mode 100644
index 00000000000..51c3c952236
--- /dev/null
+++ b/chromium/components/offline_pages/core/offline_page_item_utils.h
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_ITEM_UTILS_H_
+#define COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_ITEM_UTILS_H_
+
+class GURL;
+
+namespace offline_pages {
+
+// Returns true if two URLs are equal, ignoring the fragment.
+// Because offline page items are stored without fragment, this is appropriate
+// for checking if an offline item's URL matches another URL.
+bool EqualsIgnoringFragment(const GURL& lhs, const GURL& rhs);
+
+} // namespace offline_pages
+#endif // COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_ITEM_UTILS_H_
diff --git a/chromium/components/offline_pages/core/offline_page_item_utils_unittest.cc b/chromium/components/offline_pages/core/offline_page_item_utils_unittest.cc
new file mode 100644
index 00000000000..c1f0340ee8f
--- /dev/null
+++ b/chromium/components/offline_pages/core/offline_page_item_utils_unittest.cc
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/core/offline_page_item_utils.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace offline_pages {
+namespace {
+
+TEST(OfflinePageItemUtils, EqualsIgnoringFragment) {
+ EXPECT_TRUE(EqualsIgnoringFragment(GURL("http://example.com/"),
+ GURL("http://example.com/")));
+ EXPECT_TRUE(EqualsIgnoringFragment(GURL("http://example.com/"),
+ GURL("http://example.com/#test")));
+ EXPECT_TRUE(EqualsIgnoringFragment(GURL("http://example.com/#test"),
+ GURL("http://example.com/")));
+ EXPECT_TRUE(EqualsIgnoringFragment(GURL("http://example.com/#test"),
+ GURL("http://example.com/#test2")));
+ EXPECT_FALSE(EqualsIgnoringFragment(GURL("http://example.com/"),
+ GURL("http://test.com/#test")));
+}
+
+} // namespace
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store.cc b/chromium/components/offline_pages/core/offline_page_metadata_store.cc
index 708b6f52957..94b3720be6b 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store.cc
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store.cc
@@ -4,6 +4,8 @@
#include "components/offline_pages/core/offline_page_metadata_store.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -310,177 +312,100 @@ bool CreateSchema(sql::Database* db) {
}
}
-bool PrepareDirectory(const base::FilePath& path) {
- 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);
-
- return true;
-}
-
-bool InitDatabase(sql::Database* db,
- const base::FilePath& path,
- bool in_memory) {
- db->set_page_size(4096);
- db->set_cache_size(500);
- db->set_histogram_tag("OfflinePageMetadata");
- db->set_exclusive_locking();
-
- if (!in_memory && !PrepareDirectory(path))
- return false;
-
- bool open_db_result = false;
- if (in_memory)
- open_db_result = db->OpenInMemory();
- else
- open_db_result = db->Open(path);
-
- if (!open_db_result) {
- LOG(ERROR) << "Failed to open database, in memory: " << in_memory;
- return false;
+StoreState InitializationStatusToStoreState(
+ SqlStoreBase::InitializationStatus status) {
+ switch (status) {
+ case SqlStoreBase::InitializationStatus::kNotInitialized:
+ return StoreState::NOT_LOADED;
+ case SqlStoreBase::InitializationStatus::kInProgress:
+ return StoreState::INITIALIZING;
+ case SqlStoreBase::InitializationStatus::kSuccess:
+ return StoreState::LOADED;
+ case SqlStoreBase::InitializationStatus::kFailure:
+ return StoreState::FAILED_LOADING;
}
- db->Preload();
-
- return CreateSchema(db);
-}
-
-void CloseDatabaseSync(
- sql::Database* db,
- scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
- base::OnceClosure callback) {
- if (db)
- db->Close();
- callback_runner->PostTask(FROM_HERE, std::move(callback));
}
} // anonymous namespace
-// static
-constexpr base::TimeDelta OfflinePageMetadataStore::kClosingDelay;
-
OfflinePageMetadataStore::OfflinePageMetadataStore(
scoped_refptr<base::SequencedTaskRunner> background_task_runner)
- : background_task_runner_(std::move(background_task_runner)),
- in_memory_(true),
- state_(StoreState::NOT_LOADED),
- weak_ptr_factory_(this),
- closing_weak_ptr_factory_(this) {}
+ : SqlStoreBase("OfflinePageMetadata",
+ std::move(background_task_runner),
+ base::FilePath()) {}
OfflinePageMetadataStore::OfflinePageMetadataStore(
scoped_refptr<base::SequencedTaskRunner> background_task_runner,
const base::FilePath& path)
- : background_task_runner_(std::move(background_task_runner)),
- in_memory_(false),
- db_file_path_(path.AppendASCII("OfflinePages.db")),
- state_(StoreState::NOT_LOADED),
- weak_ptr_factory_(this),
- closing_weak_ptr_factory_(this) {}
-
-OfflinePageMetadataStore::~OfflinePageMetadataStore() {
- if (db_.get() &&
- !background_task_runner_->DeleteSoon(FROM_HERE, db_.release())) {
- DLOG(WARNING) << "SQL database will not be deleted.";
- }
-}
+ : SqlStoreBase("OfflinePageMetadata",
+ std::move(background_task_runner),
+ path.AppendASCII("OfflinePages.db")) {}
-StoreState OfflinePageMetadataStore::GetStateForTesting() const {
- return state_;
+OfflinePageMetadataStore::~OfflinePageMetadataStore() = default;
+
+base::OnceCallback<bool(sql::Database* db)>
+OfflinePageMetadataStore::GetSchemaInitializationFunction() {
+ return base::BindOnce(&CreateSchema);
}
-void OfflinePageMetadataStore::SetStateForTesting(StoreState state,
- bool reset_db) {
- state_ = state;
- if (reset_db)
- db_.reset(nullptr);
+StoreState OfflinePageMetadataStore::GetStateForTesting() const {
+ return InitializationStatusToStoreState(initialization_status_for_testing());
}
-void OfflinePageMetadataStore::InitializeInternal(
- base::OnceClosure pending_command) {
+void OfflinePageMetadataStore::OnOpenStart(base::TimeTicks last_closing_time) {
TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Metadata Store", this, "is reopen",
- !last_closing_time_.is_null());
- DCHECK_EQ(state_, StoreState::NOT_LOADED);
-
- if (!last_closing_time_.is_null()) {
+ !last_closing_time.is_null());
+ if (!last_closing_time.is_null()) {
ReportStoreEvent(OfflinePagesStoreEvent::kReopened);
UMA_HISTOGRAM_CUSTOM_TIMES("OfflinePages.SQLStorage.TimeFromCloseToOpen",
- base::TimeTicks::Now() - last_closing_time_,
+ base::TimeTicks::Now() - last_closing_time,
base::TimeDelta::FromMilliseconds(10),
base::TimeDelta::FromMinutes(10),
50 /* buckets */);
} else {
ReportStoreEvent(OfflinePagesStoreEvent::kOpenedFirstTime);
}
-
- state_ = StoreState::INITIALIZING;
- db_.reset(new sql::Database());
- base::PostTaskAndReplyWithResult(
- background_task_runner_.get(), FROM_HERE,
- base::BindOnce(&InitDatabase, db_.get(), db_file_path_, in_memory_),
- base::BindOnce(&OfflinePageMetadataStore::OnInitializeInternalDone,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(pending_command)));
}
-void OfflinePageMetadataStore::OnInitializeInternalDone(
- base::OnceClosure pending_command,
- bool success) {
+void OfflinePageMetadataStore::OnOpenDone(bool success) {
TRACE_EVENT_ASYNC_STEP_PAST1("offline_pages", "Metadata Store", this,
"Initializing", "succeeded", success);
- // TODO(fgorski): DCHECK initialization is in progress, once we have a
- // relevant value for the store state.
- if (success) {
- state_ = StoreState::LOADED;
- } else {
- state_ = StoreState::FAILED_LOADING;
- db_.reset();
+ if (!success) {
TRACE_EVENT_ASYNC_END0("offline_pages", "Metadata Store", this);
}
+}
- CHECK(!pending_command.is_null());
- std::move(pending_command).Run();
-
- // Execute other pending commands.
- for (auto command_iter = pending_commands_.begin();
- command_iter != pending_commands_.end();) {
- std::move(*command_iter++).Run();
- }
+void OfflinePageMetadataStore::OnTaskBegin(bool is_initialized) {
+ TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Metadata Store: task execution",
+ this, "is store loaded", is_initialized);
+}
- pending_commands_.clear();
+void OfflinePageMetadataStore::OnTaskRunComplete() {
+ // Note: the time recorded for this trace step will include thread hop wait
+ // times to the background thread and back.
+ TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages",
+ "Metadata Store: task execution", this, "Task");
+}
- if (state_ == StoreState::FAILED_LOADING)
- state_ = StoreState::NOT_LOADED;
+void OfflinePageMetadataStore::OnTaskReturnComplete() {
+ TRACE_EVENT_ASYNC_STEP_PAST0(
+ "offline_pages", "Metadata Store: task execution", this, "Callback");
+ TRACE_EVENT_ASYNC_END0("offline_pages", "Metadata Store: task execution",
+ this);
}
-void OfflinePageMetadataStore::CloseInternal() {
- if (state_ != StoreState::LOADED) {
+void OfflinePageMetadataStore::OnCloseStart(
+ InitializationStatus status_before_close) {
+ if (status_before_close != InitializationStatus::kSuccess) {
ReportStoreEvent(OfflinePagesStoreEvent::kCloseSkipped);
return;
}
TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages", "Metadata Store", this, "Open");
- last_closing_time_ = base::TimeTicks::Now();
ReportStoreEvent(OfflinePagesStoreEvent::kClosed);
-
- state_ = StoreState::NOT_LOADED;
- background_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &CloseDatabaseSync, db_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::BindOnce(&OfflinePageMetadataStore::CloseInternalDone,
- weak_ptr_factory_.GetWeakPtr(), std::move(db_))));
}
-void OfflinePageMetadataStore::CloseInternalDone(
- std::unique_ptr<sql::Database> db) {
- db.reset();
+void OfflinePageMetadataStore::OnCloseComplete() {
TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages", "Metadata Store", this,
"Closing");
TRACE_EVENT_ASYNC_END0("offline_pages", "Metadata Store", this);
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 e1df0b8974b..ebfb0d4f71c 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store.h
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store.h
@@ -19,6 +19,7 @@
#include "base/trace_event/trace_event.h"
#include "components/offline_pages/core/offline_page_item.h"
#include "components/offline_pages/core/offline_store_types.h"
+#include "components/offline_pages/task/sql_store_base.h"
namespace base {
class SequencedTaskRunner;
@@ -64,32 +65,8 @@ typedef StoreUpdateResult<OfflinePageItem> OfflinePagesUpdateResult;
// |UpgradeFrom54|.
// * Upgrade should use |UpgradeWithQuery| and simply specify SQL command to
// move data from old table (prefixed by temp_) to the new one.
-class OfflinePageMetadataStore {
+class OfflinePageMetadataStore : public SqlStoreBase {
public:
- // This enum is used in an UMA histogram. Hence the entries here shouldn't
- // be deleted or re-ordered and new ones should be added to the end.
- enum LoadStatus {
- LOAD_SUCCEEDED,
- STORE_INIT_FAILED,
- STORE_LOAD_FAILED,
- DATA_PARSING_FAILED,
-
- // NOTE: always keep this entry at the end.
- LOAD_STATUS_COUNT
- };
-
- typedef base::RepeatingCallback<void(bool /* success */)> ResetCallback;
-
- // Definition of the callback that is going to run the core of the command in
- // the |Execute| method.
- template <typename T>
- using RunCallback = base::OnceCallback<T(sql::Database*)>;
-
- // Definition of the callback used to pass the result back to the caller of
- // |Execute| method.
- template <typename T>
- using ResultCallback = base::OnceCallback<void(T)>;
-
// This is the first version saved in the meta table, which was introduced in
// the store in M65. It is set once a legacy upgrade is run successfully for
// the last time in |UpgradeFromLegacyVersion|.
@@ -97,11 +74,6 @@ class OfflinePageMetadataStore {
static const int kCurrentVersion = 3;
static const int kCompatibleVersion = kFirstPostLegacyVersion;
- // Defines inactivity time of DB after which it is going to be closed.
- // TODO(fgorski): Derive appropriate value in a scientific way.
- static constexpr base::TimeDelta kClosingDelay =
- base::TimeDelta::FromSeconds(20);
-
// TODO(fgorski): Move to private and expose ForTest factory.
// Applies in PrefetchStore as well.
// Creates the store in memory. Should only be used for testing.
@@ -113,126 +85,22 @@ class OfflinePageMetadataStore {
scoped_refptr<base::SequencedTaskRunner> background_task_runner,
const base::FilePath& database_dir);
- ~OfflinePageMetadataStore();
-
- // Executes a |run_callback| on SQL store on the blocking thread, and posts
- // its result back to calling thread through |result_callback|.
- // Calling |Execute| when store is NOT_LOADED will cause the store
- // initialization to start.
- // Store state needs to be LOADED for |run_callback| to run.
- // If initialization fails, |result_callback| is invoked with |default_value|.
- template <typename T>
- void Execute(RunCallback<T> run_callback,
- ResultCallback<T> result_callback,
- T default_value) {
- // TODO(fgorski): Add a proper state indicating in progress initialization
- // and CHECK that state.
-
- if (state_ == StoreState::NOT_LOADED) {
- InitializeInternal(base::BindOnce(
- &OfflinePageMetadataStore::Execute<T>, weak_ptr_factory_.GetWeakPtr(),
- std::move(run_callback), std::move(result_callback),
- std::move(default_value)));
- return;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Metadata Store: task execution",
- this, "is store loaded",
- state_ == StoreState::LOADED);
- // This if allows to run commands later, after store was given a chance to
- // initialize. They would be failing immediately otherwise.
- if (state_ == StoreState::INITIALIZING) {
- pending_commands_.push_back(base::BindOnce(
- &OfflinePageMetadataStore::Execute<T>, weak_ptr_factory_.GetWeakPtr(),
- std::move(run_callback), std::move(result_callback),
- std::move(default_value)));
- TRACE_EVENT_ASYNC_END1("offline_pages", "Metadata Store: task execution",
- this, "postponed", true);
- return;
- }
-
- // Ensure that any scheduled close operations are canceled.
- closing_weak_ptr_factory_.InvalidateWeakPtrs();
-
- sql::Database* db = state_ == StoreState::LOADED ? db_.get() : nullptr;
- if (!db) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(result_callback), std::move(default_value)));
- return;
- }
- base::PostTaskAndReplyWithResult(
- background_task_runner_.get(), FROM_HERE,
- base::BindOnce(std::move(run_callback), db),
- base::BindOnce(&OfflinePageMetadataStore::RescheduleClosing<T>,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(result_callback)));
- }
+ ~OfflinePageMetadataStore() override;
// Helper function used to force incorrect state for testing purposes.
- void SetStateForTesting(StoreState state, bool reset_db);
StoreState GetStateForTesting() const;
- private:
- // Initializes database and calls callback.
- void InitializeInternal(base::OnceClosure pending_command);
-
- // Used to conclude opening/resetting DB connection.
- void OnInitializeInternalDone(base::OnceClosure pending_command,
- bool success);
-
- // Reschedules the closing with a delay. Ensures that |result_callback| is
- // called.
- template <typename T>
- void RescheduleClosing(ResultCallback<T> result_callback, T result) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&OfflinePageMetadataStore::CloseInternal,
- closing_weak_ptr_factory_.GetWeakPtr()),
- kClosingDelay);
-
- // Note: the time recorded for this trace step will include thread hop wait
- // times to the background thread and back.
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "offline_pages", "Metadata Store: task execution", this, "Task");
- std::move(result_callback).Run(std::move(result));
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "offline_pages", "Metadata Store: task execution", this, "Callback");
- TRACE_EVENT_ASYNC_END0("offline_pages", "Metadata Store: task execution",
- this);
- }
-
- // Internal function initiating the closing.
- void CloseInternal();
-
- // Completes the closing. Main purpose is to destroy the db pointer.
- void CloseInternalDone(std::unique_ptr<sql::Database> db);
-
- // Background thread where all SQL access should be run.
- scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
-
- // Whether store is opened in memory (for testing) or using a file.
- bool in_memory_;
-
- // Path to the database on disk.
- base::FilePath db_file_path_;
-
- // Database connection.
- std::unique_ptr<sql::Database> db_;
-
- // State of the store.
- StoreState state_;
-
- // Pending commands.
- std::vector<base::OnceClosure> pending_commands_;
-
- // Time of the last time the store was closed. Kept for metrics reporting.
- base::TimeTicks last_closing_time_;
-
- base::WeakPtrFactory<OfflinePageMetadataStore> weak_ptr_factory_;
- base::WeakPtrFactory<OfflinePageMetadataStore> closing_weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(OfflinePageMetadataStore);
+ protected:
+ // SqlStoreBase:
+ base::OnceCallback<bool(sql::Database* db)> GetSchemaInitializationFunction()
+ override;
+ void OnOpenStart(base::TimeTicks last_open_time) override;
+ void OnOpenDone(bool success) override;
+ void OnTaskBegin(bool is_initialized) override;
+ void OnTaskRunComplete() override;
+ void OnTaskReturnComplete() override;
+ void OnCloseStart(InitializationStatus status_before_close) override;
+ void OnCloseComplete() override;
};
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc b/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc
index 3b400bece5f..6c3d4dbeac8 100644
--- a/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc
+++ b/chromium/components/offline_pages/core/offline_page_metadata_store_unittest.cc
@@ -34,6 +34,7 @@
namespace offline_pages {
namespace {
+using InitializationStatus = SqlStoreBase::InitializationStatus;
#define OFFLINE_PAGES_TABLE_V1 "offlinepages_v1"
@@ -390,7 +391,7 @@ void InjectItemInM62Store(sql::Database* db, const OfflinePageItem& item) {
statement.BindString(7, item.url.spec());
statement.BindString(8, store_utils::ToDatabaseFilePath(item.file_path));
statement.BindString16(9, item.title);
- statement.BindString(10, item.original_url.spec());
+ statement.BindString(10, item.original_url_if_different.spec());
statement.BindString(11, item.request_origin);
statement.BindInt64(12, item.system_download_id);
statement.BindInt(13, store_utils::ToDatabaseTime(item.file_missing_time));
@@ -508,7 +509,7 @@ OfflinePageItem MakeOfflinePageItem(sql::Statement* statement) {
item.last_access_time = last_access_time;
item.access_count = access_count;
item.title = title;
- item.original_url = original_url;
+ item.original_url_if_different = original_url;
item.request_origin = request_origin;
item.system_download_id = system_download_id;
item.file_missing_time = file_missing_time;
@@ -539,7 +540,7 @@ class OfflinePageMetadataStoreTest : public testing::Test {
task_runner_handle_(task_runner_) {
EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
}
- ~OfflinePageMetadataStoreTest() override{};
+ ~OfflinePageMetadataStoreTest() override {}
protected:
void TearDown() override {
@@ -576,7 +577,7 @@ class OfflinePageMetadataStoreTest : public testing::Test {
OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
base::FilePath(kFilePath), kFileSize);
offline_page.title = base::UTF8ToUTF16("a title");
- offline_page.original_url = GURL(kOriginalTestURL);
+ offline_page.original_url_if_different = GURL(kOriginalTestURL);
offline_page.system_download_id = kTestSystemDownloadId;
offline_page.digest = kTestDigest;
@@ -712,7 +713,7 @@ class OfflinePageMetadataStoreTest : public testing::Test {
store_utils::ToDatabaseTime(item.last_access_time));
statement.BindInt(8, item.access_count);
statement.BindString16(9, item.title);
- statement.BindString(10, item.original_url.spec());
+ statement.BindString(10, item.original_url_if_different.spec());
statement.BindString(11, item.request_origin);
statement.BindInt64(12, item.system_download_id);
statement.BindInt64(13,
@@ -789,28 +790,28 @@ TEST_F(OfflinePageMetadataStoreTest, GetOfflinePagesFromInvalidStore) {
// Because execute method is self-healing this part of the test expects a
// positive results now.
- store->SetStateForTesting(StoreState::NOT_LOADED, false);
+ store->SetInitializationStatusForTesting(
+ InitializationStatus::kNotInitialized, false);
EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
- EXPECT_EQ(StoreState::LOADED, store->GetStateForTesting());
-
- store->SetStateForTesting(StoreState::FAILED_LOADING, false);
- EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
- EXPECT_EQ(StoreState::FAILED_LOADING, store->GetStateForTesting());
-
- store->SetStateForTesting(StoreState::FAILED_RESET, false);
- EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
- EXPECT_EQ(StoreState::FAILED_RESET, store->GetStateForTesting());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store->initialization_status_for_testing());
- store->SetStateForTesting(StoreState::LOADED, true);
+ store->SetInitializationStatusForTesting(InitializationStatus::kFailure,
+ false);
EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
+ EXPECT_EQ(InitializationStatus::kFailure,
+ store->initialization_status_for_testing());
- store->SetStateForTesting(StoreState::NOT_LOADED, true);
+ store->SetInitializationStatusForTesting(InitializationStatus::kSuccess,
+ true);
EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
- store->SetStateForTesting(StoreState::FAILED_LOADING, false);
+ store->SetInitializationStatusForTesting(
+ InitializationStatus::kNotInitialized, true);
EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
- store->SetStateForTesting(StoreState::FAILED_RESET, false);
+ store->SetInitializationStatusForTesting(InitializationStatus::kFailure,
+ false);
EXPECT_EQ(0UL, GetOfflinePages(store.get()).size());
}
@@ -896,7 +897,7 @@ TEST_F(OfflinePageMetadataStoreTest, AddRemoveMultipleOfflinePages) {
OfflinePageItem offline_page_2(GURL("https://other.page.com"), 5678LL,
kTestClientId2, file_path_2, 12345,
OfflineTimeNow(), kTestRequestOrigin);
- offline_page_2.original_url = GURL("https://example.com/bar");
+ offline_page_2.original_url_if_different = GURL("https://example.com/bar");
offline_page_2.system_download_id = kTestSystemDownloadId;
offline_page_2.digest = kTestDigest;
diff --git a/chromium/components/offline_pages/core/offline_page_model.h b/chromium/components/offline_pages/core/offline_page_model.h
index cdd0ded2619..8f8b5f50a87 100644
--- a/chromium/components/offline_pages/core/offline_page_model.h
+++ b/chromium/components/offline_pages/core/offline_page_model.h
@@ -71,6 +71,12 @@ class OfflinePageModel : public base::SupportsUserData, public KeyedService {
const ClientId& client_id,
const std::string& request_origin,
const GURL& url);
+
+ const GURL& GetOriginalUrl() const {
+ return original_url_if_different.is_empty() ? url
+ : original_url_if_different;
+ }
+
// The ID of the deleted page.
int64_t offline_id;
// The system download manager id of the deleted page. This will be 0 if
@@ -82,6 +88,9 @@ class OfflinePageModel : public base::SupportsUserData, public KeyedService {
std::string request_origin;
// URL of the page that was deleted.
GURL url;
+ // Originally request URL of the page that was deleted. If this is empty,
+ // the final URL is not different than the original URL.
+ GURL original_url_if_different;
};
// Observer of the OfflinePageModel.
diff --git a/chromium/components/offline_pages/core/offline_page_thumbnail.cc b/chromium/components/offline_pages/core/offline_page_thumbnail.cc
index 5b0fe99d03c..b9f145641d5 100644
--- a/chromium/components/offline_pages/core/offline_page_thumbnail.cc
+++ b/chromium/components/offline_pages/core/offline_page_thumbnail.cc
@@ -37,8 +37,8 @@ std::string OfflinePageThumbnail::ToString() const {
base::Base64Encode(thumbnail, &thumb_data_base64);
std::string s("OfflinePageThumbnail(");
- s.append(base::Int64ToString(offline_id)).append(", ");
- s.append(base::Int64ToString(store_utils::ToDatabaseTime(expiration)))
+ s.append(base::NumberToString(offline_id)).append(", ");
+ s.append(base::NumberToString(store_utils::ToDatabaseTime(expiration)))
.append(", ");
s.append(thumb_data_base64).append(")");
return s;
diff --git a/chromium/components/offline_pages/core/prefetch/fake_suggestions_provider.cc b/chromium/components/offline_pages/core/prefetch/fake_suggestions_provider.cc
index 777ddfe681c..0d1ea88531b 100644
--- a/chromium/components/offline_pages/core/prefetch/fake_suggestions_provider.cc
+++ b/chromium/components/offline_pages/core/prefetch/fake_suggestions_provider.cc
@@ -5,6 +5,7 @@
#include "components/offline_pages/core/prefetch/fake_suggestions_provider.h"
#include <utility>
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
namespace offline_pages {
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
index ea2270f25ab..92b1eb60d3f 100644
--- a/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
+++ b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.cc
@@ -22,6 +22,7 @@ GeneratePageBundleRequest::GeneratePageBundleRequest(
int max_bundle_size_bytes,
const std::vector<std::string>& page_urls,
version_info::Channel channel,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
PrefetchRequestFinishedCallback callback)
: callback_(std::move(callback)), requested_urls_(page_urls) {
@@ -41,7 +42,8 @@ GeneratePageBundleRequest::GeneratePageBundleRequest(
request.SerializeToString(&upload_data);
fetcher_ = PrefetchRequestFetcher::CreateForPost(
- GeneratePageBundleRequestURL(channel), upload_data, url_loader_factory,
+ GeneratePageBundleRequestURL(channel), upload_data, testing_header_value,
+ url_loader_factory,
base::BindOnce(&GeneratePageBundleRequest::OnCompleted,
// Fetcher is owned by this instance.
base::Unretained(this)));
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
index 3c4af0c2b90..e412b5851b0 100644
--- a/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h
+++ b/chromium/components/offline_pages/core/prefetch/generate_page_bundle_request.h
@@ -29,6 +29,7 @@ class GeneratePageBundleRequest {
int max_bundle_size_bytes,
const std::vector<std::string>& page_urls,
version_info::Channel channel,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
PrefetchRequestFinishedCallback callback);
~GeneratePageBundleRequest();
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
index c99ca90ef16..0c6135cf2b1 100644
--- 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
@@ -39,19 +39,21 @@ const int kTestMaxBundleSize = 100000;
class GeneratePageBundleRequestTest : public PrefetchRequestTestBase {
public:
std::unique_ptr<GeneratePageBundleRequest> CreateRequest(
+ const std::string& testing_header_value,
PrefetchRequestFinishedCallback callback) {
std::vector<std::string> page_urls = {kTestURL, kTestURL2};
return std::unique_ptr<GeneratePageBundleRequest>(
new GeneratePageBundleRequest(
kTestUserAgent, kTestGCMID, kTestMaxBundleSize, page_urls,
- kTestChannel, shared_url_loader_factory(), std::move(callback)));
+ kTestChannel, testing_header_value, shared_url_loader_factory(),
+ std::move(callback)));
}
};
TEST_F(GeneratePageBundleRequestTest, RequestData) {
base::MockCallback<PrefetchRequestFinishedCallback> callback;
std::unique_ptr<GeneratePageBundleRequest> request(
- CreateRequest(callback.Get()));
+ CreateRequest("", callback.Get()));
EXPECT_EQ(2UL, request->requested_urls().size());
EXPECT_THAT(request->requested_urls(), Contains(kTestURL));
@@ -94,7 +96,7 @@ TEST_F(GeneratePageBundleRequestTest, ExperimentHeaderInRequestData) {
base::MockCallback<PrefetchRequestFinishedCallback> callback;
std::unique_ptr<GeneratePageBundleRequest> request(
- CreateRequest(callback.Get()));
+ CreateRequest("", callback.Get()));
network::TestURLLoaderFactory::PendingRequest* pending_request =
GetPendingRequest();
DCHECK(pending_request);
@@ -104,10 +106,34 @@ TEST_F(GeneratePageBundleRequestTest, ExperimentHeaderInRequestData) {
GetExperiementHeaderValue(pending_request));
}
+TEST_F(GeneratePageBundleRequestTest, NoTestingHeaderInRequestData) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ // Make a request without the header.
+ std::unique_ptr<GeneratePageBundleRequest> request(
+ CreateRequest("", callback.Get()));
+
+ std::string testing_header;
+ bool has_header = GetPendingRequest()->request.headers.GetHeader(
+ "X-Offline-Prefetch-Testing", &testing_header);
+ EXPECT_FALSE(has_header);
+}
+
+TEST_F(GeneratePageBundleRequestTest, TestingHeaderInRequestData) {
+ base::MockCallback<PrefetchRequestFinishedCallback> callback;
+ // Make a request with the header.
+ std::unique_ptr<GeneratePageBundleRequest> request(
+ CreateRequest("ForceEnable", callback.Get()));
+ std::string testing_header;
+ bool has_header = GetPendingRequest()->request.headers.GetHeader(
+ "X-Offline-Prefetch-Testing", &testing_header);
+ EXPECT_TRUE(has_header);
+ EXPECT_EQ("ForceEnable", testing_header);
+}
+
TEST_F(GeneratePageBundleRequestTest, EmptyResponse) {
base::MockCallback<PrefetchRequestFinishedCallback> callback;
std::unique_ptr<GeneratePageBundleRequest> request(
- CreateRequest(callback.Get()));
+ CreateRequest("", callback.Get()));
PrefetchRequestStatus status;
std::string operation_name;
@@ -126,7 +152,7 @@ TEST_F(GeneratePageBundleRequestTest, EmptyResponse) {
TEST_F(GeneratePageBundleRequestTest, InvalidResponse) {
base::MockCallback<PrefetchRequestFinishedCallback> callback;
std::unique_ptr<GeneratePageBundleRequest> request(
- CreateRequest(callback.Get()));
+ CreateRequest("", callback.Get()));
PrefetchRequestStatus status;
std::string operation_name;
diff --git a/chromium/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc b/chromium/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc
index 130f123bbfa..132a7cac45b 100644
--- a/chromium/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc
+++ b/chromium/components/offline_pages/core/prefetch/mock_prefetch_item_generator.cc
@@ -47,13 +47,14 @@ PrefetchItem MockPrefetchItemGenerator::CreateItem(PrefetchItemState state) {
// Values always set using prefixes.
CHECK(client_namespace_.length());
- new_item.client_id = ClientId(
- client_namespace_, client_id_prefix_ + base::IntToString(item_counter));
- new_item.url = GURL(url_prefix_ + base::IntToString(item_counter));
+ new_item.client_id =
+ ClientId(client_namespace_,
+ client_id_prefix_ + base::NumberToString(item_counter));
+ new_item.url = GURL(url_prefix_ + base::NumberToString(item_counter));
if (title_prefix_.length()) {
new_item.title =
- base::UTF8ToUTF16(title_prefix_ + base::IntToString(item_counter));
+ base::UTF8ToUTF16(title_prefix_ + base::NumberToString(item_counter));
}
if (state == PrefetchItemState::NEW_REQUEST ||
@@ -63,7 +64,7 @@ PrefetchItem MockPrefetchItemGenerator::CreateItem(PrefetchItemState state) {
if (operation_name_prefix_.length()) {
new_item.operation_name =
- operation_name_prefix_ + base::IntToString(item_counter);
+ operation_name_prefix_ + base::NumberToString(item_counter);
}
if (state == PrefetchItemState::AWAITING_GCM ||
@@ -74,12 +75,12 @@ PrefetchItem MockPrefetchItemGenerator::CreateItem(PrefetchItemState state) {
if (archive_body_name_prefix_.length()) {
new_item.archive_body_name =
- archive_body_name_prefix_ + base::IntToString(item_counter);
+ archive_body_name_prefix_ + base::NumberToString(item_counter);
new_item.archive_body_length = item_counter * 100;
}
if (final_url_prefix_.length()) {
new_item.final_archived_url =
- GURL(final_url_prefix_ + base::IntToString(item_counter));
+ GURL(final_url_prefix_ + base::NumberToString(item_counter));
}
if (state == PrefetchItemState::RECEIVED_BUNDLE)
@@ -88,7 +89,7 @@ PrefetchItem MockPrefetchItemGenerator::CreateItem(PrefetchItemState state) {
new_item.guid = base::GenerateGUID();
if (file_path_prefix_.length()) {
new_item.file_path = base::FilePath::FromUTF8Unsafe(
- file_path_prefix_ + base::IntToString(item_counter));
+ file_path_prefix_ + base::NumberToString(item_counter));
}
if (state == PrefetchItemState::DOWNLOADING) {
diff --git a/chromium/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h b/chromium/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
index bb64245d56b..3f1340bad22 100644
--- a/chromium/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
+++ b/chromium/components/offline_pages/core/prefetch/mock_thumbnail_fetcher.h
@@ -14,9 +14,8 @@ class MockThumbnailFetcher : public ThumbnailFetcher {
public:
MockThumbnailFetcher();
~MockThumbnailFetcher() override;
- MOCK_METHOD3(FetchSuggestionImageData,
+ MOCK_METHOD2(FetchSuggestionImageData,
void(const ClientId& client_id,
- bool is_first_attempt,
ImageDataFetchedCallback callback));
};
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
index 1c8b0e1a473..83ef4dff3fa 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -459,7 +459,7 @@ void PrefetchDispatcherImpl::ThumbnailExistenceChecked(
auto complete_callback = base::BindOnce(
&PrefetchDispatcherImpl::ThumbnailFetchComplete, GetWeakPtr(),
offline_id, std::move(remaining_ids), is_first_attempt);
- thumbnail_fetcher->FetchSuggestionImageData(client_id, is_first_attempt,
+ thumbnail_fetcher->FetchSuggestionImageData(client_id,
std::move(complete_callback));
} else {
task_queue_.AddTask(std::make_unique<GetThumbnailInfoTask>(
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
index 9f19cbbd381..2c31ea5224f 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -7,6 +7,8 @@
#include <set>
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
@@ -343,15 +345,13 @@ class PrefetchDispatcherTest : public PrefetchRequestTestBase {
}
void ExpectFetchThumbnail(const std::string& thumbnail_data,
- const bool first_attempt,
const char* client_id) {
ASSERT_TRUE(thumbnail_fetcher_); // This is null in the Feed configuration.
- EXPECT_CALL(
- *thumbnail_fetcher_,
- FetchSuggestionImageData(
- ClientId(kSuggestedArticlesNamespace, client_id), first_attempt, _))
+ EXPECT_CALL(*thumbnail_fetcher_,
+ FetchSuggestionImageData(
+ ClientId(kSuggestedArticlesNamespace, client_id), _))
.WillOnce([&, thumbnail_data](
- const ClientId& client_id, bool first_attempt,
+ const ClientId& client_id,
ThumbnailFetcher::ImageDataFetchedCallback callback) {
task_runner()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), thumbnail_data));
@@ -362,11 +362,11 @@ class PrefetchDispatcherTest : public PrefetchRequestTestBase {
const GURL& thumbnail_url) {
ASSERT_TRUE(thumbnail_image_fetcher_) << "Not configured in kFeed mode";
EXPECT_CALL(*thumbnail_image_fetcher_,
- FetchImageAndData_(std::string(), thumbnail_url, _, _, _))
- .WillOnce([=](const std::string& id, const GURL& image_url,
+ FetchImageAndData_(thumbnail_url, _, _, _))
+ .WillOnce([=](const GURL& image_url,
image_fetcher::ImageDataFetcherCallback* data_callback,
image_fetcher::ImageFetcherCallback* image_callback,
- const net::NetworkTrafficAnnotationTag&) {
+ image_fetcher::ImageFetcherParams params) {
ASSERT_TRUE(image_callback->is_null());
std::move(*data_callback)
.Run(thumbnail_data, image_fetcher::RequestMetadata());
@@ -808,7 +808,7 @@ TEST_F(PrefetchDispatcherTest, FeedNoNetworkRequestsAfterNewURLs) {
TEST_F(PrefetchDispatcherTest, ThumbnailFetchFailure_ItemDownloaded) {
Configure(PrefetchServiceTestTaco::kContentSuggestions);
- ExpectFetchThumbnail("", false, kClientID);
+ ExpectFetchThumbnail("", kClientID);
prefetch_dispatcher()->ItemDownloaded(
kTestOfflineID, ClientId(kSuggestedArticlesNamespace, kClientID));
@@ -820,7 +820,7 @@ TEST_F(PrefetchDispatcherTest, ThumbnailFetchFailure_ItemDownloaded) {
TEST_F(PrefetchDispatcherTest, ThumbnailFetchSuccess_ItemDownloaded) {
Configure(PrefetchServiceTestTaco::kContentSuggestions);
- ExpectFetchThumbnail(kThumbnailData, false, kClientID);
+ ExpectFetchThumbnail(kThumbnailData, kClientID);
prefetch_dispatcher()->ItemDownloaded(
kTestOfflineID, ClientId(kSuggestedArticlesNamespace, kClientID));
RunUntilIdle();
@@ -835,7 +835,7 @@ TEST_F(PrefetchDispatcherTest, ThumbnailAlreadyExists_ItemDownloaded) {
Configure(PrefetchServiceTestTaco::kContentSuggestions);
offline_model_->set_thumbnails({FakeThumbnail(kTestOfflineID)});
- EXPECT_CALL(*thumbnail_fetcher_, FetchSuggestionImageData(_, _, _)).Times(0);
+ EXPECT_CALL(*thumbnail_fetcher_, FetchSuggestionImageData(_, _)).Times(0);
prefetch_dispatcher()->ItemDownloaded(
kTestOfflineID, ClientId(kSuggestedArticlesNamespace, kClientID));
RunUntilIdle();
@@ -857,9 +857,9 @@ TEST_F(PrefetchDispatcherTest,
InSequence in_sequence;
// Case #1.
- ExpectFetchThumbnail(kThumbnailData, true, kClientID1);
+ ExpectFetchThumbnail(kThumbnailData, kClientID1);
// Case #2.
- ExpectFetchThumbnail("", true, kClientID2);
+ ExpectFetchThumbnail("", kClientID2);
// Case #3: thumbnail already exists
offline_model_->set_thumbnails({FakeThumbnail(kTestOfflineID3)});
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
index eec8ae76e3b..20580d7302f 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
@@ -195,8 +195,6 @@ TEST_F(PrefetchDownloadFlowTest, DelayRunningDownloadCleanupTask) {
// Start the prefetch processing pipeline.
BeginBackgroundTask();
- DLOG(ERROR) << "began background task";
-
// The download cleanup task should be created and run. The item should
// finally transit to IMPORTING state.
found_item = store_util()->GetPrefetchItem(item.offline_id);
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl.cc
index 069b3a0c4a1..ed0923b4514 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl.cc
@@ -102,7 +102,7 @@ void PrefetchImporterImpl::ImportArchive(const PrefetchArchiveInfo& archive) {
}
OfflinePageItem offline_page(url, archive.offline_id, archive.client_id,
dest_path, archive.file_size, base::Time::Now());
- offline_page.original_url = original_url;
+ offline_page.original_url_if_different = original_url;
offline_page.title = archive.title;
outstanding_import_offline_ids_.emplace(archive.offline_id);
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
index ab0997e2ec3..80baf72c202 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_importer_impl_unittest.cc
@@ -110,7 +110,8 @@ TEST_F(PrefetchImporterImplTest, ImportSuccess) {
EXPECT_EQ(kTestOfflineID, offline_page_model()->last_added_page().offline_id);
EXPECT_EQ(kTestClientID, offline_page_model()->last_added_page().client_id);
EXPECT_EQ(kTestFinalURL, offline_page_model()->last_added_page().url);
- EXPECT_EQ(kTestURL, offline_page_model()->last_added_page().original_url);
+ EXPECT_EQ(kTestURL,
+ offline_page_model()->last_added_page().original_url_if_different);
EXPECT_EQ(kTestTitle, offline_page_model()->last_added_page().title);
EXPECT_EQ(kTestFileSize, offline_page_model()->last_added_page().file_size);
}
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
index f63ce7aa82e..59f6699545a 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
@@ -73,7 +73,9 @@ void PrefetchNetworkRequestFactoryImpl::MakeGeneratePageBundleRequest(
generate_page_bundle_requests_[request_id] =
std::make_unique<GeneratePageBundleRequest>(
user_agent_, gcm_registration_id, max_bundle_size, url_strings,
- channel_, url_loader_factory_,
+ channel_,
+
+ prefetch_prefs::GetPrefetchTestingHeader(prefs_), url_loader_factory_,
base::BindOnce(
&PrefetchNetworkRequestFactoryImpl::GeneratePageBundleRequestDone,
weak_factory_.GetWeakPtr(), std::move(callback), request_id));
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_prefs.cc b/chromium/components/offline_pages/core/prefetch/prefetch_prefs.cc
index 4253fc699c3..6777439e49b 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_prefs.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_prefs.cc
@@ -16,8 +16,8 @@ namespace {
const char kEnabled[] = "offline_prefetch.enabled";
const char kLimitlessPrefetchingEnabledTimePref[] =
"offline_prefetch.limitless_prefetching_enabled_time";
-
-const bool is_limitless_prefetch_enabled_default = false;
+const char kSendPrefetchTestingHeaderPref[] =
+ "offline_prefetch.testing_header_value";
} // namespace
const char kBackoff[] = "offline_prefetch.backoff";
@@ -27,6 +27,7 @@ void RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(kEnabled, true);
registry->RegisterTimePref(kLimitlessPrefetchingEnabledTimePref,
base::Time());
+ registry->RegisterStringPref(kSendPrefetchTestingHeaderPref, std::string());
}
void SetPrefetchingEnabledInSettings(PrefService* prefs, bool enabled) {
@@ -46,9 +47,6 @@ void SetLimitlessPrefetchingEnabled(PrefService* prefs, bool enabled) {
}
bool IsLimitlessPrefetchingEnabled(PrefService* prefs) {
- if (is_limitless_prefetch_enabled_default)
- return true;
-
base::TimeDelta max_duration;
if (version_info::IsOfficialBuild())
max_duration = base::TimeDelta::FromDays(1);
@@ -63,5 +61,15 @@ bool IsLimitlessPrefetchingEnabled(PrefService* prefs) {
return (now >= enabled_time) && (now < (enabled_time + max_duration));
}
+void SetPrefetchTestingHeader(PrefService* prefs, const std::string& value) {
+ DCHECK(prefs);
+ prefs->SetString(kSendPrefetchTestingHeaderPref, value);
+}
+
+std::string GetPrefetchTestingHeader(PrefService* prefs) {
+ DCHECK(prefs);
+ return prefs->GetString(kSendPrefetchTestingHeaderPref);
+}
+
} // namespace prefetch_prefs
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_prefs.h b/chromium/components/offline_pages/core/prefetch/prefetch_prefs.h
index 7e590cc25ea..4c34e63777a 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_prefs.h
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_prefs.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_PREFS_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_PREFS_H_
+#include <string>
+
class PrefService;
class PrefRegistrySimple;
@@ -28,6 +30,16 @@ void SetLimitlessPrefetchingEnabled(PrefService* prefs, bool enabled);
bool IsLimitlessPrefetchingEnabled(PrefService* prefs);
+// Sets the value of "X-Offline-Prefetch_Testing" to be sent with
+// GeneratePageBundle requests. Sending "ForceEnable" instructs OPS not to apply
+// its country filtering logic, sending "ForceDisable" causes any
+// GeneratePageBundle request to be answered with 403 Forbidden, and omitting
+// the header (by passing |value|="") leaves the server to apply its country
+// filtering logic as usual.
+void SetPrefetchTestingHeader(PrefService* prefs, const std::string& value);
+
+std::string GetPrefetchTestingHeader(PrefService* prefs);
+
} // namespace prefetch_prefs
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_prefs_unittest.cc b/chromium/components/offline_pages/core/prefetch/prefetch_prefs_unittest.cc
index 2ba80778cbb..1a729912824 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_prefs_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_prefs_unittest.cc
@@ -70,4 +70,19 @@ TEST_F(PrefetchPrefsTest, LimitlessPrefetchingEnabled) {
EXPECT_FALSE(prefetch_prefs::IsLimitlessPrefetchingEnabled(prefs()));
}
+TEST_F(PrefetchPrefsTest, TestingHeaderValuePref) {
+ // Should be empty string by default.
+ EXPECT_EQ(std::string(), prefetch_prefs::GetPrefetchTestingHeader(prefs()));
+
+ prefetch_prefs::SetPrefetchTestingHeader(prefs(), "ForceEnable");
+ EXPECT_EQ("ForceEnable", prefetch_prefs::GetPrefetchTestingHeader(prefs()));
+
+ prefetch_prefs::SetPrefetchTestingHeader(prefs(), "ForceDisable");
+ EXPECT_EQ("ForceDisable", prefetch_prefs::GetPrefetchTestingHeader(prefs()));
+
+ // We're not doing any checking/changing of the value (the server does that).
+ prefetch_prefs::SetPrefetchTestingHeader(prefs(), "asdfasdfasdf");
+ EXPECT_EQ("asdfasdfasdf", prefetch_prefs::GetPrefetchTestingHeader(prefs()));
+}
+
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
index 841aab93f0f..2482cb7ec6c 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/offline_pages/core/prefetch/prefetch_server_urls.h"
@@ -32,23 +33,27 @@ std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForGet(
const GURL& url,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
FinishedCallback callback) {
- return base::WrapUnique(new PrefetchRequestFetcher(
- url, std::string(), url_loader_factory, std::move(callback)));
+ return base::WrapUnique(
+ new PrefetchRequestFetcher(url, std::string(), std::string(),
+ url_loader_factory, std::move(callback)));
}
// static
std::unique_ptr<PrefetchRequestFetcher> PrefetchRequestFetcher::CreateForPost(
const GURL& url,
const std::string& message,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
FinishedCallback callback) {
- return base::WrapUnique(new PrefetchRequestFetcher(
- url, message, url_loader_factory, std::move(callback)));
+ return base::WrapUnique(
+ new PrefetchRequestFetcher(url, message, testing_header_value,
+ url_loader_factory, std::move(callback)));
}
PrefetchRequestFetcher::PrefetchRequestFetcher(
const GURL& url,
const std::string& message,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
FinishedCallback callback)
: url_loader_factory_(url_loader_factory), callback_(std::move(callback)) {
@@ -84,6 +89,10 @@ PrefetchRequestFetcher::PrefetchRequestFetcher(
if (!experiment_header.empty())
resource_request->headers.AddHeaderFromString(experiment_header);
+ if (!testing_header_value.empty())
+ resource_request->headers.SetHeader(kPrefetchTestingHeaderName,
+ testing_header_value);
+
if (message.empty())
resource_request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
kRequestContentType);
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
index d025a86847f..357182562aa 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher.h
@@ -34,6 +34,7 @@ class PrefetchRequestFetcher {
static std::unique_ptr<PrefetchRequestFetcher> CreateForPost(
const GURL& url,
const std::string& message,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
FinishedCallback callback);
@@ -47,6 +48,7 @@ class PrefetchRequestFetcher {
PrefetchRequestFetcher(
const GURL& url,
const std::string& message,
+ const std::string& testing_header_value,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
FinishedCallback callback);
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
index 493ffe6932d..45987ca6bcd 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_request_fetcher_unittest.cc
@@ -4,6 +4,7 @@
#include "components/offline_pages/core/prefetch/prefetch_request_fetcher.h"
+#include "base/bind.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"
@@ -73,7 +74,8 @@ PrefetchRequestStatus PrefetchRequestFetcherTest::RunFetcher(
base::MockCallback<PrefetchRequestFetcher::FinishedCallback> callback;
std::unique_ptr<PrefetchRequestFetcher> fetcher =
PrefetchRequestFetcher::CreateForPost(
- kTestURL, kTestMessage, shared_url_loader_factory(), callback.Get());
+ kTestURL, kTestMessage, /*testing_header_value=*/"",
+ shared_url_loader_factory(), callback.Get());
PrefetchRequestStatus status;
std::string data;
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
index beccfb172a2..e0c12405cd3 100644
--- 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
@@ -56,7 +56,7 @@ class GeneratePageBundleRequestBuilder : public RequestBuilder {
std::vector<std::string> pages = {kTestURL, kTestURL2};
fetcher_.reset(new GeneratePageBundleRequest(
kTestUserAgent, kTestGCMID, kTestMaxBundleSize, pages, kTestChannel,
- url_loader_factory, std::move(callback)));
+ /*testing_header_value=*/"", url_loader_factory, std::move(callback)));
}
private:
@@ -280,7 +280,7 @@ typedef testing::Types<GeneratePageBundleRequestDoneOperationBuilder,
GetOperationRequestDoneOperationBuilder,
GetOperationRequestPendingOperationBuilder>
MyTypes;
-TYPED_TEST_CASE(PrefetchRequestOperationResponseTest, MyTypes);
+TYPED_TEST_SUITE(PrefetchRequestOperationResponseTest, MyTypes);
TYPED_TEST(PrefetchRequestOperationResponseTest, EmptyOperation) {
EXPECT_EQ(PrefetchRequestStatus::kShouldRetryWithBackoff,
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.cc b/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.cc
index 818ab80c6af..5e847224487 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.cc
@@ -14,6 +14,7 @@ namespace offline_pages {
const char kPrefetchServer[] = "https://offlinepages-pa.googleapis.com/";
const char kPrefetchExperimentHeaderName[] = "X-Offline-Prefetch-Experiment";
const char kPrefetchOperationHeaderName[] = "X-Offline-Prefetch-Operation";
+const char kPrefetchTestingHeaderName[] = "X-Offline-Prefetch-Testing";
namespace {
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.h b/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.h
index c42eab8ac59..f2e96b39059 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.h
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_server_urls.h
@@ -14,6 +14,7 @@ namespace offline_pages {
extern const char kPrefetchServer[];
extern const char kPrefetchExperimentHeaderName[];
extern const char kPrefetchOperationHeaderName[];
+extern const char kPrefetchTestingHeaderName[];
// Returns the URL to send a request to generate page bundle.
GURL GeneratePageBundleRequestURL(version_info::Channel channel);
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc
index c15fba58576..309c0948614 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.cc
@@ -38,7 +38,7 @@ PrefetchServiceImpl::PrefetchServiceImpl(
std::unique_ptr<PrefetchBackgroundTaskHandler>
prefetch_background_task_handler,
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher,
- std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher)
+ image_fetcher::ImageFetcher* thumbnail_image_fetcher)
: offline_metrics_collector_(std::move(offline_metrics_collector)),
prefetch_dispatcher_(std::move(dispatcher)),
prefetch_gcm_handler_(std::move(gcm_handler)),
@@ -51,7 +51,7 @@ PrefetchServiceImpl::PrefetchServiceImpl(
std::move(prefetch_background_task_handler)),
suggested_articles_observer_(std::move(suggested_articles_observer)),
thumbnail_fetcher_(std::move(thumbnail_fetcher)),
- thumbnail_image_fetcher_(std::move(thumbnail_image_fetcher)) {
+ thumbnail_image_fetcher_(thumbnail_image_fetcher) {
prefetch_dispatcher_->SetService(this);
prefetch_downloader_->SetPrefetchService(this);
prefetch_gcm_handler_->SetService(this);
@@ -152,7 +152,7 @@ ThumbnailFetcher* PrefetchServiceImpl::GetThumbnailFetcher() {
}
image_fetcher::ImageFetcher* PrefetchServiceImpl::GetThumbnailImageFetcher() {
- return thumbnail_image_fetcher_.get();
+ return thumbnail_image_fetcher_;
}
void PrefetchServiceImpl::Shutdown() {
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h
index 93fa2ef8519..40f3dfbfe56 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service_impl.h
@@ -31,7 +31,7 @@ class PrefetchServiceImpl : public PrefetchService {
std::unique_ptr<PrefetchImporter> prefetch_importer,
std::unique_ptr<PrefetchBackgroundTaskHandler> background_task_handler,
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher,
- std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher_);
+ image_fetcher::ImageFetcher* thumbnail_image_fetcher_);
~PrefetchServiceImpl() override;
@@ -83,7 +83,8 @@ class PrefetchServiceImpl : public PrefetchService {
// Zine/Feed: only non-null when using Zine.
std::unique_ptr<SuggestedArticlesObserver> suggested_articles_observer_;
std::unique_ptr<ThumbnailFetcher> thumbnail_fetcher_;
- std::unique_ptr<image_fetcher::ImageFetcher> thumbnail_image_fetcher_;
+ // Owned by CachedImageFetcherService.
+ image_fetcher::ImageFetcher* thumbnail_image_fetcher_;
// Zine/Feed: only non-null when using Feed.
SuggestionsProvider* suggestions_provider_ = nullptr;
diff --git a/chromium/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc b/chromium/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
index 80ed22e4c27..02ed318e618 100644
--- a/chromium/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
+++ b/chromium/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
@@ -201,7 +201,7 @@ void PrefetchServiceTestTaco::CreatePrefetchService() {
std::move(suggested_articles_observer_), std::move(prefetch_downloader_),
std::move(prefetch_importer_),
std::move(prefetch_background_task_handler_),
- std::move(thumbnail_fetcher_), std::move(thumbnail_image_fetcher_));
+ std::move(thumbnail_fetcher_), thumbnail_image_fetcher_.get());
}
std::unique_ptr<PrefetchService>
diff --git a/chromium/components/offline_pages/core/prefetch/store/prefetch_store.cc b/chromium/components/offline_pages/core/prefetch/store/prefetch_store.cc
index d28e193d79a..064e3b652be 100644
--- a/chromium/components/offline_pages/core/prefetch/store/prefetch_store.cc
+++ b/chromium/components/offline_pages/core/prefetch/store/prefetch_store.cc
@@ -4,6 +4,8 @@
#include "components/offline_pages/core/prefetch/store/prefetch_store.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -23,164 +25,86 @@ namespace {
const char kPrefetchStoreFileName[] = "PrefetchStore.db";
-bool PrepareDirectory(const base::FilePath& path) {
- base::File::Error error = base::File::FILE_OK;
- if (!base::DirectoryExists(path.DirName())) {
- if (!base::CreateDirectoryAndGetError(path.DirName(), &error)) {
- LOG(ERROR) << "Failed to create prefetch db directory: "
- << base::File::ErrorToString(error);
- return false;
- }
- }
- return true;
-}
-
-// TODO(fgorski): This function and this part of the system in general could
-// benefit from a better status code reportable through UMA to better capture
-// the reason for failure, aiding the process of repeated attempts to
-// open/initialize the database.
-bool InitializeSync(sql::Database* db,
- const base::FilePath& path,
- bool in_memory) {
- // These values are default.
- db->set_page_size(4096);
- db->set_cache_size(500);
- db->set_histogram_tag("PrefetchStore");
- db->set_exclusive_locking();
-
- if (!in_memory && !PrepareDirectory(path))
- return false;
-
- bool open_db_result = false;
- if (in_memory)
- open_db_result = db->OpenInMemory();
- else
- open_db_result = db->Open(path);
-
- if (!open_db_result) {
- LOG(ERROR) << "Failed to open database, in memory: " << in_memory;
- return false;
- }
- db->Preload();
-
- return PrefetchStoreSchema::CreateOrUpgradeIfNeeded(db);
-}
-
-void CloseDatabaseSync(
- sql::Database* db,
- scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
- base::OnceClosure callback) {
- if (db)
- db->Close();
- callback_runner->PostTask(FROM_HERE, std::move(callback));
-}
-
void ReportStoreEvent(OfflinePagesStoreEvent event) {
UMA_HISTOGRAM_ENUMERATION("OfflinePages.PrefetchStore.StoreEvent", event);
}
} // namespace
-// static
-constexpr base::TimeDelta PrefetchStore::kClosingDelay;
-
PrefetchStore::PrefetchStore(
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
- : blocking_task_runner_(std::move(blocking_task_runner)),
- in_memory_(true),
- db_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)),
- initialization_status_(InitializationStatus::NOT_INITIALIZED),
- weak_ptr_factory_(this),
- closing_weak_ptr_factory_(this) {}
+ : SqlStoreBase("PrefetchStore",
+ std::move(blocking_task_runner),
+ base::FilePath()) {}
PrefetchStore::PrefetchStore(
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
const base::FilePath& path)
- : blocking_task_runner_(std::move(blocking_task_runner)),
- db_file_path_(path.AppendASCII(kPrefetchStoreFileName)),
- in_memory_(false),
- db_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)),
- initialization_status_(InitializationStatus::NOT_INITIALIZED),
- weak_ptr_factory_(this),
- closing_weak_ptr_factory_(this) {}
+ : SqlStoreBase("PrefetchStore",
+ std::move(blocking_task_runner),
+ path.AppendASCII(kPrefetchStoreFileName)) {}
-PrefetchStore::~PrefetchStore() {}
+PrefetchStore::~PrefetchStore() = default;
-void PrefetchStore::Initialize(base::OnceClosure pending_command) {
- TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Prefetch Store", this, "is reopen",
- !last_closing_time_.is_null());
- DCHECK_EQ(initialization_status_, InitializationStatus::NOT_INITIALIZED);
- initialization_status_ = InitializationStatus::INITIALIZING;
+base::OnceCallback<bool(sql::Database* db)>
+PrefetchStore::GetSchemaInitializationFunction() {
+ return base::BindOnce(&PrefetchStoreSchema::CreateOrUpgradeIfNeeded);
+}
- if (!last_closing_time_.is_null()) {
+void PrefetchStore::OnOpenStart(base::TimeTicks last_closing_time) {
+ TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Prefetch Store", this, "is reopen",
+ !last_closing_time.is_null());
+ if (!last_closing_time.is_null()) {
ReportStoreEvent(OfflinePagesStoreEvent::kReopened);
UMA_HISTOGRAM_CUSTOM_TIMES("OfflinePages.PrefetchStore.TimeFromCloseToOpen",
- base::TimeTicks::Now() - last_closing_time_,
+ base::TimeTicks::Now() - last_closing_time,
base::TimeDelta::FromMilliseconds(10),
base::TimeDelta::FromMinutes(10),
50 /* buckets */);
} else {
ReportStoreEvent(OfflinePagesStoreEvent::kOpenedFirstTime);
}
-
- // This is how we reset a pointer and provide deleter. This is necessary to
- // ensure that we can close the store more than once.
- db_ = DatabaseUniquePtr(new sql::Database,
- base::OnTaskRunnerDeleter(blocking_task_runner_));
-
- base::PostTaskAndReplyWithResult(
- blocking_task_runner_.get(), FROM_HERE,
- base::BindOnce(&InitializeSync, db_.get(), db_file_path_, in_memory_),
- base::BindOnce(&PrefetchStore::OnInitializeDone,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(pending_command)));
}
-void PrefetchStore::OnInitializeDone(base::OnceClosure pending_command,
- bool success) {
+void PrefetchStore::OnOpenDone(bool success) {
// TODO(carlosk): Add initializing error reporting here.
TRACE_EVENT_ASYNC_STEP_PAST1("offline_pages", "Prefetch Store", this,
"Initializing", "succeeded", success);
- DCHECK_EQ(initialization_status_, InitializationStatus::INITIALIZING);
- if (success) {
- initialization_status_ = InitializationStatus::SUCCESS;
- } else {
- initialization_status_ = InitializationStatus::FAILURE;
- db_.reset();
+ if (!success) {
TRACE_EVENT_ASYNC_END0("offline_pages", "Prefetch Store", this);
}
+}
- CHECK(!pending_command.is_null());
- std::move(pending_command).Run();
+void PrefetchStore::OnTaskBegin(bool is_initialized) {
+ TRACE_EVENT_ASYNC_BEGIN1("offline_pages", "Prefetch Store: task execution",
+ this, "is store loaded", is_initialized);
+}
- // Once pending commands are empty, we get back to NOT_INITIALIZED state, to
- // make it possible to retry initialization next time a DB operation is
- // attempted.
- if (initialization_status_ == InitializationStatus::FAILURE)
- initialization_status_ = InitializationStatus::NOT_INITIALIZED;
+void PrefetchStore::OnTaskRunComplete() {
+ // Note: the time recorded for this trace step will include thread hop wait
+ // times to the background thread and back.
+ TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages",
+ "Prefetch Store: task execution", this, "Task");
}
-void PrefetchStore::CloseInternal() {
- if (initialization_status_ != InitializationStatus::SUCCESS) {
+void PrefetchStore::OnTaskReturnComplete() {
+ TRACE_EVENT_ASYNC_STEP_PAST0(
+ "offline_pages", "Prefetch Store: task execution", this, "Callback");
+ TRACE_EVENT_ASYNC_END0("offline_pages", "Prefetch Store: task execution",
+ this);
+}
+
+void PrefetchStore::OnCloseStart(InitializationStatus initialization_status) {
+ if (initialization_status != InitializationStatus::kSuccess) {
ReportStoreEvent(OfflinePagesStoreEvent::kCloseSkipped);
return;
}
TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages", "Prefetch Store", this, "Open");
- last_closing_time_ = base::TimeTicks::Now();
ReportStoreEvent(OfflinePagesStoreEvent::kClosed);
-
- initialization_status_ = InitializationStatus::NOT_INITIALIZED;
- blocking_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &CloseDatabaseSync, db_.get(), base::ThreadTaskRunnerHandle::Get(),
- base::BindOnce(&PrefetchStore::CloseInternalDone,
- weak_ptr_factory_.GetWeakPtr(), std::move(db_))));
}
-void PrefetchStore::CloseInternalDone(DatabaseUniquePtr db) {
- db.reset();
+void PrefetchStore::OnCloseComplete() {
TRACE_EVENT_ASYNC_STEP_PAST0("offline_pages", "Prefetch Store", this,
"Closing");
TRACE_EVENT_ASYNC_END0("offline_pages", "Prefetch Store", this);
diff --git a/chromium/components/offline_pages/core/prefetch/store/prefetch_store.h b/chromium/components/offline_pages/core/prefetch/store/prefetch_store.h
index b9bcecb1fd8..5d80e181e4d 100644
--- a/chromium/components/offline_pages/core/prefetch/store/prefetch_store.h
+++ b/chromium/components/offline_pages/core/prefetch/store/prefetch_store.h
@@ -16,6 +16,7 @@
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "components/offline_pages/task/sql_store_base.h"
namespace sql {
class Database;
@@ -23,13 +24,6 @@ class Database;
namespace offline_pages {
-enum class InitializationStatus {
- NOT_INITIALIZED,
- INITIALIZING,
- SUCCESS,
- FAILURE,
-};
-
// PrefetchStore is a front end to SQLite store hosting prefetch related
// items.
//
@@ -39,23 +33,8 @@ enum class InitializationStatus {
//
// Store has a set of auxiliary functions meant to be used on the blocking
// thread. They can be found in prefetch_store_sql_utils file.
-class PrefetchStore {
+class PrefetchStore : public SqlStoreBase {
public:
- // Definition of the callback that is going to run the core of the command in
- // the |Execute| method.
- template <typename T>
- using RunCallback = base::OnceCallback<T(sql::Database*)>;
-
- // Definition of the callback used to pass the result back to the caller of
- // |Execute| method.
- template <typename T>
- using ResultCallback = base::OnceCallback<void(T)>;
-
- // Defines inactivity time of DB after which it is going to be closed.
- // TODO(fgorski): Derive appropriate value in a scientific way.
- static constexpr base::TimeDelta kClosingDelay =
- base::TimeDelta::FromSeconds(20);
-
// Creates an instance of |PrefetchStore| with an in-memory SQLite database.
explicit PrefetchStore(
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
@@ -65,122 +44,24 @@ class PrefetchStore {
PrefetchStore(scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
const base::FilePath& database_dir);
- ~PrefetchStore();
-
- // Executes a |run_callback| on SQL store on the blocking thread, and posts
- // its result back to calling thread through |result_callback|.
- // Calling |Execute| when store is NOT_INITIALIZED will cause the store
- // initialization to start.
- // Store initialization status needs to be SUCCESS for run_callback to run.
- // If initialization fails, |result_callback| is invoked with |default_value|.
- template <typename T>
- void Execute(RunCallback<T> run_callback,
- ResultCallback<T> result_callback,
- T default_value) {
- CHECK_NE(initialization_status_, InitializationStatus::INITIALIZING);
-
- if (initialization_status_ == InitializationStatus::NOT_INITIALIZED) {
- Initialize(base::BindOnce(
- &PrefetchStore::Execute<T>, weak_ptr_factory_.GetWeakPtr(),
- std::move(run_callback), std::move(result_callback),
- std::move(default_value)));
- return;
- }
-
- TRACE_EVENT_ASYNC_BEGIN1(
- "offline_pages", "Prefetch Store: task execution", this,
- "is store loaded",
- initialization_status_ == InitializationStatus::SUCCESS);
- // Ensure that any scheduled close operations are canceled.
- closing_weak_ptr_factory_.InvalidateWeakPtrs();
-
- sql::Database* db = initialization_status_ == InitializationStatus::SUCCESS
- ? db_.get()
- : nullptr;
- if (!db) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(result_callback), std::move(default_value)));
- } else {
- base::PostTaskAndReplyWithResult(
- blocking_task_runner_.get(), FROM_HERE,
- base::BindOnce(std::move(run_callback), db),
- base::BindOnce(&PrefetchStore::RescheduleClosing<T>,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(result_callback)));
- }
- }
-
- // Gets the initialization status of the store.
- InitializationStatus initialization_status() const {
- return initialization_status_;
- }
+ ~PrefetchStore() override;
static const char* GetTableCreationSqlForTesting();
+ protected:
+ // SqlStoreBase:
+ base::OnceCallback<bool(sql::Database* db)> GetSchemaInitializationFunction()
+ override;
+ void OnOpenStart(base::TimeTicks last_open_time) override;
+ void OnOpenDone(bool success) override;
+ void OnTaskBegin(bool is_initialized) override;
+ void OnTaskRunComplete() override;
+ void OnTaskReturnComplete() override;
+ void OnCloseStart(InitializationStatus status_before_close) override;
+ void OnCloseComplete() override;
+
private:
friend class PrefetchStoreTestUtil;
-
- using DatabaseUniquePtr =
- std::unique_ptr<sql::Database, base::OnTaskRunnerDeleter>;
-
- // Used internally to initialize connection.
- void Initialize(base::OnceClosure pending_command);
-
- // Used to conclude opening/resetting DB connection.
- void OnInitializeDone(base::OnceClosure pending_command, bool success);
-
- // Reschedules the closing with a delay. Ensures that |result_callback| is
- // called.
- template <typename T>
- void RescheduleClosing(ResultCallback<T> result_callback, T result) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&PrefetchStore::CloseInternal,
- closing_weak_ptr_factory_.GetWeakPtr()),
- kClosingDelay);
-
- // Note: the time recorded for this trace step will include thread hop wait
- // times to the background thread and back.
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "offline_pages", "Prefetch Store: task execution", this, "Task");
- std::move(result_callback).Run(std::move(result));
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "offline_pages", "Prefetch Store: task execution", this, "Callback");
- TRACE_EVENT_ASYNC_END0("offline_pages", "Prefetch Store: task execution",
- this);
- }
-
- // Internal function initiating the closing.
- void CloseInternal();
-
- // Completes the closing. Main purpose is to destroy the db pointer.
- void CloseInternalDone(DatabaseUniquePtr db);
-
- // Background thread where all SQL access should be run.
- scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
-
- // Path to the database on disk.
- base::FilePath db_file_path_;
-
- // Only open the store in memory. Used for testing.
- bool in_memory_;
-
- // Database connection.
- std::unique_ptr<sql::Database, base::OnTaskRunnerDeleter> db_;
-
- // Initialization status of the store.
- InitializationStatus initialization_status_;
-
- // Time of the last time the store was closed. Kept for metrics reporting.
- base::TimeTicks last_closing_time_;
-
- // Weak pointer to control the callback.
- base::WeakPtrFactory<PrefetchStore> weak_ptr_factory_;
- // Weak pointer to cancel closing of the store.
- base::WeakPtrFactory<PrefetchStore> closing_weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PrefetchStore);
};
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc b/chromium/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
index 1f7209691ff..f0247ff5188 100644
--- a/chromium/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
+++ b/chromium/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
@@ -344,7 +344,8 @@ bool PrefetchStoreTestUtil::SetPrefetchQuota(int64_t available_quota) {
}
void PrefetchStoreTestUtil::SimulateInitializationError() {
- store_->initialization_status_ = InitializationStatus::FAILURE;
+ store_->SetInitializationStatusForTesting(
+ SqlStoreBase::InitializationStatus::kFailure, false);
}
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc b/chromium/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
index a44a80c277e..fd440315b51 100644
--- a/chromium/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
+++ b/chromium/components/offline_pages/core/prefetch/store/prefetch_store_unittest.cc
@@ -17,6 +17,8 @@
#include "testing/gtest/include/gtest/gtest.h"
namespace offline_pages {
+namespace {
+using InitializationStatus = SqlStoreBase::InitializationStatus;
class PrefetchStoreTest : public testing::Test {
public:
@@ -88,17 +90,19 @@ TEST_F(PrefetchStoreTest, CloseStore) {
PrefetchItem item1(
item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
EXPECT_TRUE(store_util()->InsertPrefetchItem(item1));
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
task_runner()->FastForwardBy(PrefetchStore::kClosingDelay);
- EXPECT_EQ(InitializationStatus::NOT_INITIALIZED,
- store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kNotInitialized,
+ store()->initialization_status_for_testing());
// Should initialize the store again.
PrefetchItem item2(
item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
EXPECT_TRUE(store_util()->InsertPrefetchItem(item2));
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
}
TEST_F(PrefetchStoreTest, CloseStorePostponed) {
@@ -106,30 +110,35 @@ TEST_F(PrefetchStoreTest, CloseStorePostponed) {
PrefetchItem item1(
item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
EXPECT_TRUE(store_util()->InsertPrefetchItem(item1));
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
task_runner()->FastForwardBy(PrefetchStore::kClosingDelay / 2);
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
// Should postpone closing.
PrefetchItem item2(
item_generator()->CreateItem(PrefetchItemState::NEW_REQUEST));
EXPECT_TRUE(store_util()->InsertPrefetchItem(item2));
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
// This adds up to more than kClosingDelay after the first call, which means
// the closing would trigger, it does not however, since second call caused it
// to be postponed.
task_runner()->FastForwardBy(2 * PrefetchStore::kClosingDelay / 3);
// Store should still be initialized.
- EXPECT_EQ(InitializationStatus::SUCCESS, store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kSuccess,
+ store()->initialization_status_for_testing());
// There is still a pending task to close the store.
EXPECT_TRUE(task_runner()->HasPendingTask());
// After this step the store should be closed.
task_runner()->FastForwardBy(PrefetchStore::kClosingDelay);
- EXPECT_EQ(InitializationStatus::NOT_INITIALIZED,
- store()->initialization_status());
+ EXPECT_EQ(InitializationStatus::kNotInitialized,
+ store()->initialization_status_for_testing());
}
+} // namespace
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.cc b/chromium/components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.cc
index 00a170778a1..c0f191d0cd5 100644
--- a/chromium/components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.cc
+++ b/chromium/components/offline_pages/core/prefetch/tasks/get_thumbnail_info_task.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "components/offline_pages/core/prefetch/store/prefetch_store.h"
#include "sql/database.h"
#include "sql/statement.h"
diff --git a/chromium/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc b/chromium/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc
index b3cf8b27e74..79db779b3a6 100644
--- a/chromium/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc
+++ b/chromium/components/offline_pages/core/prefetch/tasks/page_bundle_update_task.cc
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
#include "components/offline_pages/core/prefetch/prefetch_service.h"
diff --git a/chromium/components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc b/chromium/components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc
index 3874c2759a2..54566cd0867 100644
--- a/chromium/components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc
+++ b/chromium/components/offline_pages/core/prefetch/thumbnail_fetch_by_url.cc
@@ -12,8 +12,11 @@
namespace offline_pages {
namespace {
-net::NetworkTrafficAnnotationTag TrafficAnnotation() {
- return net::DefineNetworkTrafficAnnotation("prefetch_thumbnail", R"(
+
+constexpr char kImageFetcherUmaClientName[] = "OfflinePages";
+
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("prefetch_thumbnail", R"(
semantics {
sender: "Offline Pages Prefetch"
description:
@@ -38,7 +41,6 @@ net::NetworkTrafficAnnotationTag TrafficAnnotation() {
}
}
})");
-}
} // namespace
@@ -52,9 +54,13 @@ void FetchThumbnailByURL(
const image_fetcher::RequestMetadata& request_metadata) {
std::move(callback).Run(image_data);
};
- fetcher->FetchImageData(/*id=*/std::string(), thumbnail_url,
+
+ image_fetcher::ImageFetcherParams params(kTrafficAnnotation,
+ kImageFetcherUmaClientName);
+
+ fetcher->FetchImageData(thumbnail_url,
base::BindOnce(forward_callback, std::move(callback)),
- TrafficAnnotation());
+ std::move(params));
}
} // namespace offline_pages
diff --git a/chromium/components/offline_pages/core/prefetch/thumbnail_fetcher.h b/chromium/components/offline_pages/core/prefetch/thumbnail_fetcher.h
index a4c8093cd66..2963ae5e55c 100644
--- a/chromium/components/offline_pages/core/prefetch/thumbnail_fetcher.h
+++ b/chromium/components/offline_pages/core/prefetch/thumbnail_fetcher.h
@@ -21,25 +21,6 @@ class ThumbnailFetcher {
using ImageDataFetchedCallback =
base::OnceCallback<void(const std::string& image_data)>;
- // Status of thumbnail fetch for UMA, exposed for tests only.
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
- enum class FetchCompleteStatus {
- // Fetch returned a good thumbnail on the 1st attempt.
- kFirstAttemptSuccess,
- // Fetch returned no thumbnail on the 1st attempt.
- kFirstAttemptEmptyImage,
- // Fetch returned a very large thumbnail we will not use on the 1st attempt.
- kFirstAttemptTooLarge,
- // Fetch returned a good thumbnail on the 2nd attempt.
- kSecondAttemptSuccess,
- // Fetch returned no thumbnail on the 2nd attempt.
- kSecondAttemptEmptyImage,
- // Fetch returned a very large thumbnail we will not use on the 2nd attempt.
- kSecondAttemptTooLarge,
- // Must be updated when adding a new value.
- kMaxValue = kSecondAttemptTooLarge,
- };
// Thumbnails larger than 200KB are not retained. Thumbnails are typically
// around 10KB.
static constexpr int64_t kMaxThumbnailSize = 200000;
@@ -53,7 +34,6 @@ class ThumbnailFetcher {
// completes. |image_data| is empty if the fetch failed, otherwise it will
// be raw image data that may be decoded with image_fetcher::ImageDecoder.
virtual void FetchSuggestionImageData(const ClientId& client_id,
- bool is_first_attempt,
ImageDataFetchedCallback callback) = 0;
};
diff --git a/chromium/components/offline_pages/task/BUILD.gn b/chromium/components/offline_pages/task/BUILD.gn
index fa6a891b47a..14e59c2f093 100644
--- a/chromium/components/offline_pages/task/BUILD.gn
+++ b/chromium/components/offline_pages/task/BUILD.gn
@@ -10,6 +10,8 @@ static_library("task") {
sources = [
"closure_task.cc",
"closure_task.h",
+ "sql_store_base.cc",
+ "sql_store_base.h",
"task.cc",
"task.h",
"task_queue.cc",
@@ -18,6 +20,7 @@ static_library("task") {
deps = [
"//base",
+ "//sql",
]
}
diff --git a/chromium/components/offline_pages/task/DEPS b/chromium/components/offline_pages/task/DEPS
new file mode 100644
index 00000000000..6fff87d325a
--- /dev/null
+++ b/chromium/components/offline_pages/task/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+sql",
+]
diff --git a/chromium/components/offline_pages/task/sql_store_base.cc b/chromium/components/offline_pages/task/sql_store_base.cc
new file mode 100644
index 00000000000..d1552d4b338
--- /dev/null
+++ b/chromium/components/offline_pages/task/sql_store_base.cc
@@ -0,0 +1,201 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/offline_pages/task/sql_store_base.h"
+
+#include <iterator>
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/sequenced_task_runner.h"
+#include "base/trace_event/trace_event.h"
+
+namespace offline_pages {
+namespace {
+
+bool PrepareDirectory(const base::FilePath& path) {
+ base::File::Error error = base::File::FILE_OK;
+ if (!base::DirectoryExists(path.DirName())) {
+ if (!base::CreateDirectoryAndGetError(path.DirName(), &error)) {
+ DLOG(ERROR) << "Failed to create prefetch db directory: "
+ << base::File::ErrorToString(error);
+ return false;
+ }
+ }
+ return true;
+}
+
+// TODO(fgorski): This function and this part of the system in general could
+// benefit from a better status code reportable through UMA to better capture
+// the reason for failure, aiding the process of repeated attempts to
+// open/initialize the database.
+bool InitializeSync(
+ sql::Database* db,
+ const base::FilePath& path,
+ const std::string& histogram_tag,
+ base::OnceCallback<bool(sql::Database*)> initialize_schema) {
+ // These values are default.
+ db->set_page_size(4096);
+ db->set_cache_size(500);
+ db->set_histogram_tag(histogram_tag);
+ db->set_exclusive_locking();
+ const bool in_memory = path.empty();
+ if (!in_memory && !PrepareDirectory(path))
+ return false;
+
+ bool open_db_result = false;
+ if (in_memory)
+ open_db_result = db->OpenInMemory();
+ else
+ open_db_result = db->Open(path);
+
+ if (!open_db_result) {
+ DLOG(ERROR) << "Failed to open database, in memory: " << in_memory;
+ return false;
+ }
+ db->Preload();
+
+ return std::move(initialize_schema).Run(db);
+}
+
+void CloseDatabaseSync(
+ sql::Database* db,
+ scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
+ base::OnceClosure callback) {
+ if (db)
+ db->Close();
+ callback_runner->PostTask(FROM_HERE, std::move(callback));
+}
+
+} // namespace
+
+// static
+constexpr base::TimeDelta SqlStoreBase::kClosingDelay;
+
+SqlStoreBase::SqlStoreBase(
+ const std::string& histogram_tag,
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner,
+ const base::FilePath& file_path)
+ : background_task_runner_(background_task_runner),
+ histogram_tag_(histogram_tag),
+ db_file_path_(file_path),
+ db_(nullptr, base::OnTaskRunnerDeleter(background_task_runner_)),
+ weak_ptr_factory_(this),
+ closing_weak_ptr_factory_(this) {}
+
+SqlStoreBase::~SqlStoreBase() = default;
+
+void SqlStoreBase::SetInitializationStatusForTesting(
+ InitializationStatus initialization_status,
+ bool reset_db) {
+ initialization_status_ = initialization_status;
+ if (reset_db)
+ db_.reset(nullptr);
+}
+
+void SqlStoreBase::Initialize(base::OnceClosure pending_command) {
+ OnOpenStart(last_closing_time_);
+
+ DCHECK_EQ(initialization_status_, InitializationStatus::kNotInitialized);
+ initialization_status_ = InitializationStatus::kInProgress;
+
+ // This is how we reset a pointer and provide deleter. This is necessary to
+ // ensure that we can close the store more than once.
+ db_ = DatabaseUniquePtr(new sql::Database,
+ base::OnTaskRunnerDeleter(background_task_runner_));
+
+ base::PostTaskAndReplyWithResult(
+ background_task_runner_.get(), FROM_HERE,
+ base::BindOnce(&InitializeSync, db_.get(), db_file_path_, histogram_tag_,
+ GetSchemaInitializationFunction()),
+ base::BindOnce(&SqlStoreBase::InitializeDone,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::move(pending_command)));
+}
+
+void SqlStoreBase::InitializeDone(base::OnceClosure pending_command,
+ bool success) {
+ DCHECK_EQ(initialization_status_, InitializationStatus::kInProgress);
+ if (success) {
+ initialization_status_ = InitializationStatus::kSuccess;
+ } else {
+ initialization_status_ = InitializationStatus::kFailure;
+ db_.reset();
+ }
+
+ CHECK(!pending_command.is_null());
+ std::move(pending_command).Run();
+ for (auto command_iter = std::make_move_iterator(pending_commands_.begin());
+ command_iter != std::make_move_iterator(pending_commands_.end());
+ ++command_iter) {
+ (*command_iter).Run();
+ }
+ pending_commands_.clear();
+
+ // Once pending commands are empty, we get back to kNotInitialized state, to
+ // make it possible to retry initialization next time a DB operation is
+ // attempted.
+ if (initialization_status_ == InitializationStatus::kFailure)
+ initialization_status_ = InitializationStatus::kNotInitialized;
+
+ OnOpenDone(success);
+}
+
+void SqlStoreBase::ExecuteInternal(base::OnceClosure command) {
+ if (initialization_status_ == InitializationStatus::kInProgress) {
+ pending_commands_.push_back(std::move(command));
+ return;
+ }
+
+ if (initialization_status_ == InitializationStatus::kNotInitialized) {
+ Initialize(std::move(command));
+ return;
+ }
+
+ std::move(command).Run();
+}
+
+sql::Database* SqlStoreBase::ExecuteBegin() {
+ OnTaskBegin(initialization_status_ == InitializationStatus::kSuccess);
+ // Ensure that any scheduled close operations are canceled.
+ closing_weak_ptr_factory_.InvalidateWeakPtrs();
+
+ return initialization_status_ == InitializationStatus::kSuccess ? db_.get()
+ : nullptr;
+}
+
+void SqlStoreBase::CloseInternal() {
+ OnCloseStart(initialization_status_);
+
+ last_closing_time_ = base::TimeTicks::Now();
+
+ initialization_status_ = InitializationStatus::kNotInitialized;
+ background_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CloseDatabaseSync, db_.get(), base::ThreadTaskRunnerHandle::Get(),
+ base::BindOnce(&SqlStoreBase::CloseInternalDone,
+ weak_ptr_factory_.GetWeakPtr(), std::move(db_))));
+}
+
+void SqlStoreBase::RescheduleClosingBefore() {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&SqlStoreBase::CloseInternal,
+ closing_weak_ptr_factory_.GetWeakPtr()),
+ kClosingDelay);
+
+ // Note: the time recorded for this trace step will include thread hop wait
+ // times to the background thread and back.
+ OnTaskRunComplete();
+}
+
+void SqlStoreBase::CloseInternalDone(DatabaseUniquePtr db) {
+ db.reset();
+ OnCloseComplete();
+}
+
+} // namespace offline_pages
diff --git a/chromium/components/offline_pages/task/sql_store_base.h b/chromium/components/offline_pages/task/sql_store_base.h
new file mode 100644
index 00000000000..18ea55e08eb
--- /dev/null
+++ b/chromium/components/offline_pages/task/sql_store_base.h
@@ -0,0 +1,190 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OFFLINE_PAGES_TASK_SQL_STORE_BASE_H_
+#define COMPONENTS_OFFLINE_PAGES_TASK_SQL_STORE_BASE_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/memory/weak_ptr.h"
+#include "base/task_runner_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "sql/database.h"
+
+namespace offline_pages {
+
+// Maintains an SQLite database and permits safe access.
+// Opens the database only when queried. Automatically closes the database
+// if it's not being used.
+// This is a base class, and must be overridden to configure the database
+// schema.
+class SqlStoreBase {
+ public:
+ enum class InitializationStatus {
+ kNotInitialized,
+ kInProgress,
+ kSuccess,
+ kFailure,
+ };
+
+ // Definition of the callback that is going to run the core of the command in
+ // the |Execute| method.
+ template <typename T>
+ using RunCallback = base::OnceCallback<T(sql::Database*)>;
+
+ // Definition of the callback used to pass the result back to the caller of
+ // |Execute| method.
+ template <typename T>
+ using ResultCallback = base::OnceCallback<void(T)>;
+
+ // Defines inactivity time of DB after which it is going to be closed.
+ // TODO(crbug.com/933369): Derive appropriate value in a scientific way.
+ static constexpr base::TimeDelta kClosingDelay =
+ base::TimeDelta::FromSeconds(20);
+
+ // If |file_path| is empty, this constructs an in-memory database.
+ SqlStoreBase(const std::string& histogram_tag,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ const base::FilePath& file_path);
+ virtual ~SqlStoreBase();
+
+ // Gets the initialization status of the store.
+ InitializationStatus initialization_status_for_testing() const {
+ return initialization_status_;
+ }
+
+ // Executes a |run_callback| on SQL store on the blocking sequence, and posts
+ // its result back to calling thread through |result_callback|.
+ // Calling |Execute| when store is kNotInitialized will cause the store
+ // initialization to start.
+ // Store initialization status needs to be kSuccess for run_callback to run.
+ // If initialization fails, |result_callback| is invoked with |default_value|.
+ template <typename T>
+ void Execute(RunCallback<T> run_callback,
+ ResultCallback<T> result_callback,
+ T default_value) {
+ ExecuteInternal(
+ base::BindOnce(&SqlStoreBase::ExecuteAfterInitialized<T>,
+ weak_ptr_factory_.GetWeakPtr(), std::move(run_callback),
+ std::move(result_callback), std::move(default_value)));
+ }
+
+ void SetInitializationStatusForTesting(
+ InitializationStatus initialization_status,
+ bool reset_db);
+
+ protected:
+ // Returns a function that installs the latest schema to |db| (if necessary),
+ // and returns whether the database was successfully verified to have the
+ // current schema. |GetSchemaInitializationFunction| is called on the main
+ // thread, but the returned function is executed on the blocking sequence.
+ virtual base::OnceCallback<bool(sql::Database* db)>
+ GetSchemaInitializationFunction() = 0;
+
+ // Optional tracing methods. The derived class may implement tracing events
+ // with these methods.
+
+ // Called on attempt to open the database. |last_closing_time| is the time
+ // since the last time the database was closed, or null if the database was
+ // not previously opened since creation of this.
+ virtual void OnOpenStart(base::TimeTicks last_closing_time) {}
+ // Called when done attempting to open the database.
+ virtual void OnOpenDone(bool success) {}
+ // Called before a task is executed through |Execute()|.
+ virtual void OnTaskBegin(bool is_initialized) {}
+ // Called after calling the |run_callback| in |Execute()|.
+ virtual void OnTaskRunComplete() {}
+ // Called after calling the |result_callback| in |Execute()|.
+ virtual void OnTaskReturnComplete() {}
+ // Called when starting to close the database.
+ virtual void OnCloseStart(InitializationStatus status_before_close) {}
+ // Called after closing the database.
+ virtual void OnCloseComplete() {}
+
+ private:
+ using DatabaseUniquePtr =
+ std::unique_ptr<sql::Database, base::OnTaskRunnerDeleter>;
+
+ void Initialize(base::OnceClosure pending_command);
+ void InitializeDone(base::OnceClosure pending_command, bool success);
+
+ void ExecuteInternal(base::OnceClosure command);
+ sql::Database* ExecuteBegin();
+
+ template <typename T>
+ void ExecuteAfterInitialized(RunCallback<T> run_callback,
+ ResultCallback<T> result_callback,
+ T default_value) {
+ DCHECK_NE(initialization_status_, InitializationStatus::kNotInitialized);
+ DCHECK_NE(initialization_status_, InitializationStatus::kInProgress);
+ sql::Database* db = ExecuteBegin();
+ if (!db) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(result_callback), std::move(default_value)));
+ return;
+ }
+ base::PostTaskAndReplyWithResult(
+ background_task_runner_.get(), FROM_HERE,
+ base::BindOnce(std::move(run_callback), db),
+ base::BindOnce(&SqlStoreBase::RescheduleClosing<T>,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::move(result_callback)));
+ }
+
+ // Reschedules the closing with a delay. Ensures that |result_callback| is
+ // called.
+ template <typename T>
+ void RescheduleClosing(ResultCallback<T> result_callback, T result) {
+ RescheduleClosingBefore();
+ std::move(result_callback).Run(std::move(result));
+ OnTaskReturnComplete();
+ }
+
+ void RescheduleClosingBefore();
+
+ // Internal function initiating the closing.
+ void CloseInternal();
+
+ // Completes the closing. Main purpose is to destroy the db pointer.
+ void CloseInternalDone(DatabaseUniquePtr db);
+
+ // Background thread where all SQL access should be run.
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
+
+ // Histogram tag for the sqlite database.
+ std::string histogram_tag_;
+
+ // Path to the database on disk. If empty, the database is in memory only.
+ base::FilePath db_file_path_;
+
+ // Database connection.
+ DatabaseUniquePtr db_;
+
+ // Pending commands.
+ std::vector<base::OnceClosure> pending_commands_;
+
+ // State of initialization.
+ InitializationStatus initialization_status_ =
+ InitializationStatus::kNotInitialized;
+
+ // Time of the last time the store was closed. Kept for metrics reporting.
+ base::TimeTicks last_closing_time_;
+
+ base::WeakPtrFactory<SqlStoreBase> weak_ptr_factory_;
+ base::WeakPtrFactory<SqlStoreBase> closing_weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SqlStoreBase);
+};
+
+} // namespace offline_pages
+
+#endif // COMPONENTS_OFFLINE_PAGES_TASK_SQL_STORE_BASE_H_
diff --git a/chromium/components/omnibox/browser/BUILD.gn b/chromium/components/omnibox/browser/BUILD.gn
index a60bf739348..1d20ae58c7f 100644
--- a/chromium/components/omnibox/browser/BUILD.gn
+++ b/chromium/components/omnibox/browser/BUILD.gn
@@ -30,13 +30,16 @@ aggregate_vector_icons("omnibox_vector_icons") {
"answer_when_is.icon",
"blank.icon",
"bookmark.icon",
+ "calculator.icon",
"clear.icon",
"drive_docs.icon",
"drive_forms.icon",
+ "drive_image.icon",
"drive_logo.icon",
+ "drive_pdf.icon",
"drive_sheets.icon",
"drive_slides.icon",
- "calculator.icon",
+ "drive_video.icon",
"extension_app.icon",
"find_in_page.icon",
"http.icon",
@@ -48,6 +51,7 @@ aggregate_vector_icons("omnibox_vector_icons") {
"open_in_new.icon",
"page.icon",
"pedal.icon",
+ "plus.icon",
"product.icon",
"star_active.icon",
"star.icon",
@@ -94,8 +98,8 @@ jumbo_static_library("browser") {
"bookmark_provider.h",
"builtin_provider.cc",
"builtin_provider.h",
- "clipboard_url_provider.cc",
- "clipboard_url_provider.h",
+ "clipboard_provider.cc",
+ "clipboard_provider.h",
"contextual_suggestions_service.cc",
"contextual_suggestions_service.h",
"document_provider.cc",
@@ -158,6 +162,8 @@ jumbo_static_library("browser") {
"omnibox_pref_names.h",
"omnibox_view.cc",
"omnibox_view.h",
+ "on_device_head_serving.cc",
+ "on_device_head_serving.h",
"scored_history_match.cc",
"scored_history_match.h",
"search_provider.cc",
@@ -348,6 +354,7 @@ bundle_data("unit_tests_bundle_data") {
"//components/test/data/omnibox/Shortcuts.v0.sql",
"//components/test/data/omnibox/in_memory_url_index_test.sql",
"//components/test/data/omnibox/in_memory_url_index_test_limited.sql",
+ "//components/test/data/omnibox/on_device_head_test_model.bin",
]
outputs = [
"{{bundle_resources_dir}}/" +
@@ -367,7 +374,7 @@ source_set("unit_tests") {
"base_search_provider_unittest.cc",
"bookmark_provider_unittest.cc",
"builtin_provider_unittest.cc",
- "clipboard_url_provider_unittest.cc",
+ "clipboard_provider_unittest.cc",
"contextual_suggestions_service_unittest.cc",
"document_provider_unittest.cc",
"favicon_cache_unittest.cc",
@@ -386,6 +393,7 @@ source_set("unit_tests") {
"omnibox_pedal_unittest.cc",
"omnibox_popup_model_unittest.cc",
"omnibox_view_unittest.cc",
+ "on_device_head_serving_unittest.cc",
"scored_history_match_unittest.cc",
"search_suggestion_parser_unittest.cc",
"shortcuts_backend_unittest.cc",
@@ -422,6 +430,7 @@ source_set("unit_tests") {
"//testing/gmock",
"//testing/gtest",
"//ui/base:test_support",
+ "//ui/gfx:test_support",
"//url",
]
}
diff --git a/chromium/components/omnibox/common/BUILD.gn b/chromium/components/omnibox/common/BUILD.gn
index 3e0af71eee4..482cd7a07fc 100644
--- a/chromium/components/omnibox/common/BUILD.gn
+++ b/chromium/components/omnibox/common/BUILD.gn
@@ -4,6 +4,11 @@
source_set("common") {
sources = [
+ "omnibox_features.cc",
+ "omnibox_features.h",
"omnibox_focus_state.h",
]
+ deps = [
+ "//base",
+ ]
}
diff --git a/chromium/components/omnibox_strings.grdp b/chromium/components/omnibox_strings.grdp
index 661d9db8519..c48496740ca 100644
--- a/chromium/components/omnibox_strings.grdp
+++ b/chromium/components/omnibox_strings.grdp
@@ -7,21 +7,31 @@
<message name="IDS_EMPTY_KEYWORD_VALUE" desc="Shown in the location bar drop down when the user enters a string that matches a chrome keyword, but they haven't entered any text following the chrome keyword">
&lt;Type search term&gt;
</message>
- <message name="IDS_LINK_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the link has been extracted from the user's clipboard. [Length: 21em]">
- Link you copied
- </message>
- <message name="IDS_TEXT_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the text has been extracted from the user's clipboard.">
- Text you copied
- </message>
+ <if expr="use_titlecase">
+ <message name="IDS_LINK_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the link has been extracted from the user's clipboard." meaning="Length: 35em">
+ Link You Copied
+ </message>
+ <message name="IDS_TEXT_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the text has been extracted from the user's clipboard." meaning="Length: 35em">
+ Text You Copied
+ </message>
+ <message name="IDS_IMAGE_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the image has been extracted from the user's clipboard." meaning="Length: 35em">
+ Image You Copied
+ </message>
+ </if>
+ <if expr="not use_titlecase">
+ <message name="IDS_LINK_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the link has been extracted from the user's clipboard." meaning="Length: 21em">
+ Link you copied
+ </message>
+ <message name="IDS_TEXT_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the text has been extracted from the user's clipboard." meaning="Length: 21em">
+ Text you copied
+ </message>
+ <message name="IDS_IMAGE_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the image has been extracted from the user's clipboard." meaning="Length: 21em">
+ Image you copied
+ </message>
+ </if>
<message name="IDS_COPIED_TEXT_FROM_CLIPBOARD" desc="The actual text the user copied, surrounded by quotation marks.">
&quot;<ph name="TEXT">$1<ex>search string</ex></ph>&quot;
</message>
- <message name="IDS_IMAGE_FROM_CLIPBOARD" desc="The label in the omnibox dropdown explaining that the image has been extracted from the user's clipboard.">
- Image you copied
- </message>
- <message name="IDS_SEARCH_WEB_FOR_IMAGE" desc="Description for performing a search by image">
- Search <ph name="SEARCH_ENGINE">$1<ex>Google</ex></ph> for Image
- </message>
<message name="IDS_SECURE_CONNECTION_EV" desc="Short text shown in the location bar when the connection is secure with an EV cert.">
<ph name="ORGANIZATION">$1<ex>Paypal Inc.</ex></ph> [<ph name="COUNTRY">$2<ex>US</ex></ph>]
</message>
@@ -194,8 +204,14 @@
<message name="IDS_ACC_AUTOCOMPLETE_BOOKMARK" desc="Text for screenreaders describing a URL from a bookmark.">
<ph name="LOCATION_TITLE">$2<ex>The Chromium Projects</ex></ph> <ph name="SHORT_URL">$1<ex>www.chromium.org</ex> bookmark</ph>
</message>
- <message name="IDS_ACC_AUTOCOMPLETE_CLIPBOARD" desc="Text for screenreaders describing a URL from a clipboard.">
- <ph name="LOCATION_TITLE">$2<ex>The Chromium Projects</ex></ph> <ph name="SHORT_URL">$1<ex>www.chromium.org</ex> location from clipboard</ph>
+ <message name="IDS_ACC_AUTOCOMPLETE_CLIPBOARD_IMAGE" desc="Text for screenreaders describing an image from a clipboard.">
+ Search for clipboard image
+ </message>
+ <message name="IDS_ACC_AUTOCOMPLETE_CLIPBOARD_TEXT" desc="Text for screenreaders describing text from a clipboard.">
+ Search for clipboard text, <ph name="TEXT">$2<ex>Paris, france</ex></ph>
+ </message>
+ <message name="IDS_ACC_AUTOCOMPLETE_CLIPBOARD_URL" desc="Text for screenreaders describing a URL from a clipboard.">
+ Search for clipboard URL, <ph name="SHORT_URL">$2<ex>www.chromium.org</ex></ph>
</message>
<message name="IDS_ACC_SEARCH_ICON" desc="Text for screenreaders describing a search icon image.">
Search icon
diff --git a/chromium/components/open_from_clipboard/BUILD.gn b/chromium/components/open_from_clipboard/BUILD.gn
index 8df293dc5fc..0b05b9de6d0 100644
--- a/chromium/components/open_from_clipboard/BUILD.gn
+++ b/chromium/components/open_from_clipboard/BUILD.gn
@@ -11,6 +11,7 @@ static_library("open_from_clipboard") {
]
deps = [
+ ":feature_flags",
":open_from_clipboard_impl",
"//base",
"//components/variations",
@@ -28,6 +29,16 @@ static_library("open_from_clipboard") {
}
}
+source_set("feature_flags") {
+ sources = [
+ "clipboard_recent_content_features.cc",
+ "clipboard_recent_content_features.h",
+ ]
+ deps = [
+ "//base",
+ ]
+}
+
# Helper classes used by "open_from_clipboard" target. These classes must have
# no dependencies on "//base:i18n".
source_set("open_from_clipboard_impl") {
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content.cc b/chromium/components/open_from_clipboard/clipboard_recent_content.cc
index fc040be2dae..11cb69c6832 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content.cc
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content.cc
@@ -6,6 +6,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
+#include "components/open_from_clipboard/clipboard_recent_content_features.h"
#include "components/variations/variations_associated_data.h"
#include "url/url_constants.h"
@@ -33,18 +34,9 @@ void ClipboardRecentContent::SetInstance(
// static
base::TimeDelta ClipboardRecentContent::MaximumAgeOfClipboard() {
- // Identify the current setting for this parameter from the omnibox field
- // trial.
- std::string value_str = variations::GetVariationParamValue(
- "OmniboxBundledExperimentV1", "ClipboardURLMaximumAge");
- // If the parameter is not set, use a 1 hour timeout.
- if (value_str.empty())
- return base::TimeDelta::FromHours(1);
- // This is a best-effort conversion; we trust the hand-crafted parameters
- // downloaded from the server to be perfect. There's no need for handle
- // errors smartly.
- int value;
- // The value in the parameter is stored in seconds.
- base::StringToInt(value_str, &value);
+ // Identify the current setting for this parameter from the feature, using
+ // 3600 seconds (1 hour) as a default if the parameter is not set.
+ int value = variations::GetVariationParamByFeatureAsInt(
+ kClipboardMaximumAge, kClipboardMaximumAgeParam, 3600);
return base::TimeDelta::FromSeconds(value);
}
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content_features.cc b/chromium/components/open_from_clipboard/clipboard_recent_content_features.cc
new file mode 100644
index 00000000000..5082125308a
--- /dev/null
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content_features.cc
@@ -0,0 +1,11 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/open_from_clipboard/clipboard_recent_content_features.h"
+
+const char kClipboardMaximumAgeParam[] = "UIClipboardMaximumAge";
+
+// Feature used to determine the maximum age of clipboard content.
+const base::Feature kClipboardMaximumAge{"ClipboardMaximumAge",
+ base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content_features.h b/chromium/components/open_from_clipboard/clipboard_recent_content_features.h
new file mode 100644
index 00000000000..4b405155eee
--- /dev/null
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content_features.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OPEN_FROM_CLIPBOARD_CLIPBOARD_RECENT_CONTENT_FEATURES_H_
+#define COMPONENTS_OPEN_FROM_CLIPBOARD_CLIPBOARD_RECENT_CONTENT_FEATURES_H_
+
+#include "base/feature_list.h"
+
+// Parameter name for the ClipboardMaximumAge experiment.
+extern const char kClipboardMaximumAgeParam[];
+
+extern const base::Feature kClipboardMaximumAge;
+
+#endif // COMPONENTS_OPEN_FROM_CLIPBOARD_CLIPBOARD_RECENT_CONTENT_FEATURES_H_
diff --git a/chromium/components/open_from_clipboard/clipboard_recent_content_impl_ios.h b/chromium/components/open_from_clipboard/clipboard_recent_content_impl_ios.h
index 0cc789aef4c..f89630024fe 100644
--- a/chromium/components/open_from_clipboard/clipboard_recent_content_impl_ios.h
+++ b/chromium/components/open_from_clipboard/clipboard_recent_content_impl_ios.h
@@ -40,7 +40,7 @@
// not been suppresed. Otherwise, returns nil.
- (NSString*)recentTextFromClipboard;
-// Returns the copied string if the clipboard contains a recent string that has
+// Returns the copied image if the clipboard contains a recent image that has
// not been suppressed. Otherwise, returns nil.
- (UIImage*)recentImageFromClipboard;
diff --git a/chromium/components/optimization_guide/OWNERS b/chromium/components/optimization_guide/OWNERS
index 52c14e4b75f..fd70f95f7d4 100644
--- a/chromium/components/optimization_guide/OWNERS
+++ b/chromium/components/optimization_guide/OWNERS
@@ -1 +1,3 @@
file://components/previews/OWNERS
+
+# COMPONENT: Blink>Previews
diff --git a/chromium/components/optimization_guide/optimization_guide_service.h b/chromium/components/optimization_guide/optimization_guide_service.h
index 92b8fbb0cdf..a971643dbcb 100644
--- a/chromium/components/optimization_guide/optimization_guide_service.h
+++ b/chromium/components/optimization_guide/optimization_guide_service.h
@@ -40,13 +40,13 @@ class OptimizationGuideService {
// Virtual so it can be mocked out in tests.
virtual void MaybeUpdateHintsComponent(const HintsComponentInfo& info);
- private:
// If the hints component version in |info| is greater than that in
// |hints_component_info_|, updates |hints_component_info_| and dispatches it
// to all observers. In the case where the version is not greater, it does
// nothing.
void MaybeUpdateHintsComponentOnUIThread(const HintsComponentInfo& info);
+ private:
// Runner for indexing tasks.
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/components/optimization_guide/proto/hints.proto b/chromium/components/optimization_guide/proto/hints.proto
index 63c3f35037b..b896e5d9b61 100644
--- a/chromium/components/optimization_guide/proto/hints.proto
+++ b/chromium/components/optimization_guide/proto/hints.proto
@@ -7,6 +7,103 @@ option optimize_for = LITE_RUNTIME;
package optimization_guide.proto;
+// Information about the hint that the client already has for a host.
+message MatchedHintInfo {
+ // Describes the granularity of the key field.
+ optional KeyRepresentation key_representation = 1;
+ // The key of the hint currently used for the host.
+ optional string key = 2;
+ // The version of the hint for this key already stored on the client.
+ optional int64 version = 3;
+}
+
+message HostInfo {
+ // Host that the client is requesting information for.
+ optional string host = 1;
+ // Information about the hint that the client already has for the host.
+ optional MatchedHintInfo matched_hint = 2;
+}
+
+// Request to return a set of hints that guide what optimizations to perform
+// on those hosts.
+message GetHintsRequest {
+ // Information about the set of hosts to retrieve hints for.
+ repeated HostInfo hosts = 1;
+
+ // The set of optimization types that the requesting client can support
+ // and perform.
+ //
+ // It is guaranteed that the response will only contain hints for
+ // optimizations present in this set.
+ repeated OptimizationType supported_optimizations = 2;
+
+ // Context in which this request is made.
+ optional RequestContext context = 3;
+}
+
+// Response to the GetHints request.
+message GetHintsResponse {
+ // An ordered list containing hints for key/optimization combinations.
+ //
+ // It is guaranteed that there will only be a single hint per key and key
+ // representation combination. These hints are intended to apply to a full
+ // page. It is expected that the client will use the Hint record with the
+ // most specific key that matches the main frame URL.
+ //
+ // Note, this list may contain multiple hints that apply to a page. For
+ // example, if there are hints for (HOST_SUFFIX,cnn.com) and
+ // (HOST_SUFFIX,sports.cnn.com), these may both apply to
+ // sports.cnn.com/foo. In this case, the client is expected to use the
+ // hints from (HOST_SUFFIX,sports.cnn.com).
+ repeated Hint hints = 1;
+
+ // The maximum duration in which the hints provided in this response should
+ // be retained in the client cache.
+ optional Duration max_cache_duration = 2;
+
+ // A set of hint keys to remove from the client cache.
+ //
+ // It is guaranteed that all entries in this list were provided by the client
+ // in the corresponding request's |hosts.matched_hint| fields.
+ //
+ // It is expected for the client to immediately stop using all hints contained
+ // in this field. Hints that are not present in |hints| or in this field
+ // should adhere to the client cache's existing expiration policy.
+ repeated MatchedHintInfo hints_to_remove = 3;
+}
+
+// A Duration represents a signed, fixed-length span of time represented
+// as a count of seconds and fractions of seconds at nanosecond
+// resolution. It is independent of any calendar and concepts like "day"
+// or "month". It is related to Timestamp in that the difference between
+// two Timestamp values is a Duration and it can be added or subtracted
+// from a Timestamp. Range is approximately +-10,000 years.
+// This is local definition matching server side duration.proto definition.
+message Duration {
+ // Signed seconds of the span of time. Must be from -315,576,000,000
+ // to +315,576,000,000 inclusive.
+ optional int64 seconds = 1;
+
+ // Signed fractions of a second at nanosecond resolution of the span
+ // of time. Durations less than one second are represented with a 0
+ // `seconds` field and a positive or negative `nanos` field. For durations
+ // of one second or more, a non-zero value for the `nanos` field must be
+ // of the same sign as the `seconds` field. Must be from -999,999,999
+ // to +999,999,999 inclusive.
+ optional int32 nanos = 2;
+}
+
+// Context in which the hints are requested.
+enum RequestContext {
+ reserved 1;
+ // Context not specified.
+ CONTEXT_UNSPECIFIED = 0;
+ // Requesting hints on page navigation.
+ CONTEXT_PAGE_NAVIGATION = 2;
+ // Requesting hints as part of a batch update.
+ CONTEXT_BATCH_UPDATE = 3;
+}
+
enum OptimizationType {
TYPE_UNSPECIFIED = 0;
// This optimization blocks JavaScript on the page.
diff --git a/chromium/components/optimization_guide/test_hints_component_creator.cc b/chromium/components/optimization_guide/test_hints_component_creator.cc
index b96412647fb..40c66b7841e 100644
--- a/chromium/components/optimization_guide/test_hints_component_creator.cc
+++ b/chromium/components/optimization_guide/test_hints_component_creator.cc
@@ -156,7 +156,7 @@ void TestHintsComponentCreator::WriteConfigToFile(
optimization_guide::HintsComponentInfo
TestHintsComponentCreator::WriteConfigToFileAndReturnHintsComponentInfo(
const optimization_guide::proto::Configuration& config) {
- std::string version_string = base::IntToString(next_component_version_++);
+ std::string version_string = base::NumberToString(next_component_version_++);
base::FilePath file_path = GetFilePath(version_string);
WriteConfigToFile(file_path, config);
return optimization_guide::HintsComponentInfo(base::Version(version_string),
diff --git a/chromium/components/os_crypt/key_storage_kwallet_unittest.cc b/chromium/components/os_crypt/key_storage_kwallet_unittest.cc
index 9f9b7da6d44..2525d210adf 100644
--- a/chromium/components/os_crypt/key_storage_kwallet_unittest.cc
+++ b/chromium/components/os_crypt/key_storage_kwallet_unittest.cc
@@ -262,9 +262,9 @@ class KeyStorageKWalletFailuresTest
DISALLOW_COPY_AND_ASSIGN(KeyStorageKWalletFailuresTest);
};
-INSTANTIATE_TEST_CASE_P(,
- KeyStorageKWalletFailuresTest,
- ::testing::Values(CANNOT_READ, CANNOT_CONTACT));
+INSTANTIATE_TEST_SUITE_P(,
+ KeyStorageKWalletFailuresTest,
+ ::testing::Values(CANNOT_READ, CANNOT_CONTACT));
TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureOpen) {
EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)).WillOnce(Return(GetParam()));
diff --git a/chromium/components/os_crypt/key_storage_linux_unittest.cc b/chromium/components/os_crypt/key_storage_linux_unittest.cc
index 0f8f667b661..2ffc6c73c34 100644
--- a/chromium/components/os_crypt/key_storage_linux_unittest.cc
+++ b/chromium/components/os_crypt/key_storage_linux_unittest.cc
@@ -42,9 +42,9 @@ TEST_F(KeyStorageLinuxTest, SkipPostingToSameTaskRunner) {
new base::TestSimpleTaskRunner());
FakeKeyStorageLinux key_storage(task_runner.get());
- task_runner->PostTask(FROM_HERE,
- base::Bind(base::IgnoreResult(&KeyStorageLinux::GetKey),
- base::Unretained(&key_storage)));
+ task_runner->PostTask(
+ FROM_HERE, base::BindOnce(base::IgnoreResult(&KeyStorageLinux::GetKey),
+ base::Unretained(&key_storage)));
// This should not deadlock.
task_runner->RunUntilIdle();
diff --git a/chromium/components/os_crypt/kwallet_dbus_unittest.cc b/chromium/components/os_crypt/kwallet_dbus_unittest.cc
index 53efb7663a1..e5c6e608ea2 100644
--- a/chromium/components/os_crypt/kwallet_dbus_unittest.cc
+++ b/chromium/components/os_crypt/kwallet_dbus_unittest.cc
@@ -119,10 +119,11 @@ class KWalletDBusTest
DISALLOW_COPY_AND_ASSIGN(KWalletDBusTest);
};
-INSTANTIATE_TEST_CASE_P(,
- KWalletDBusTest,
- ::testing::Values(base::nix::DESKTOP_ENVIRONMENT_KDE4,
- base::nix::DESKTOP_ENVIRONMENT_KDE5));
+INSTANTIATE_TEST_SUITE_P(
+ ,
+ KWalletDBusTest,
+ ::testing::Values(base::nix::DESKTOP_ENVIRONMENT_KDE4,
+ base::nix::DESKTOP_ENVIRONMENT_KDE5));
// Matches a method call to the specified dbus target.
MATCHER_P2(Calls, interface, member, "") {
diff --git a/chromium/components/os_crypt/libsecret_util_linux.cc b/chromium/components/os_crypt/libsecret_util_linux.cc
index 6288334542f..75877434873 100644
--- a/chromium/components/os_crypt/libsecret_util_linux.cc
+++ b/chromium/components/os_crypt/libsecret_util_linux.cc
@@ -191,5 +191,5 @@ void LibsecretAttributesBuilder::Append(const std::string& name,
void LibsecretAttributesBuilder::Append(const std::string& name,
int64_t value) {
- Append(name, base::Int64ToString(value));
+ Append(name, base::NumberToString(value));
}
diff --git a/chromium/components/os_crypt/os_crypt_linux_unittest.cc b/chromium/components/os_crypt/os_crypt_linux_unittest.cc
index 58d6da381c9..b6792d7dd8f 100644
--- a/chromium/components/os_crypt/os_crypt_linux_unittest.cc
+++ b/chromium/components/os_crypt/os_crypt_linux_unittest.cc
@@ -20,7 +20,7 @@ class OSCryptLinuxTest : public testing::Test {
public:
OSCryptLinuxTest() : key_("something") { key_ptr_ = &key_; }
- ~OSCryptLinuxTest() override { key_ptr_ = nullptr; };
+ ~OSCryptLinuxTest() override { key_ptr_ = nullptr; }
void SetUp() override {
OSCryptMockerLinux::SetUp();
diff --git a/chromium/components/os_crypt/os_crypt_unittest.cc b/chromium/components/os_crypt/os_crypt_unittest.cc
index 753d3fc45a4..b25cc28e324 100644
--- a/chromium/components/os_crypt/os_crypt_unittest.cc
+++ b/chromium/components/os_crypt/os_crypt_unittest.cc
@@ -152,7 +152,7 @@ class OSCryptConcurrencyTest : public testing::Test {
public:
OSCryptConcurrencyTest() { OSCryptMocker::SetUp(); }
- ~OSCryptConcurrencyTest() override { OSCryptMocker::TearDown(); };
+ ~OSCryptConcurrencyTest() override { OSCryptMocker::TearDown(); }
private:
DISALLOW_COPY_AND_ASSIGN(OSCryptConcurrencyTest);
diff --git a/chromium/components/page_image_annotation/content/renderer/BUILD.gn b/chromium/components/page_image_annotation/content/renderer/BUILD.gn
index a96c4d039ce..2c4b39bbedb 100644
--- a/chromium/components/page_image_annotation/content/renderer/BUILD.gn
+++ b/chromium/components/page_image_annotation/content/renderer/BUILD.gn
@@ -21,6 +21,10 @@ static_library("renderer") {
"//third_party/blink/public/common",
"//url",
]
+
+ public_deps = [
+ "//third_party/blink/public:blink_headers",
+ ]
}
source_set("unit_tests") {
diff --git a/chromium/components/page_image_annotation/core/page_annotator.cc b/chromium/components/page_image_annotation/core/page_annotator.cc
index 46611fcc7f2..5a63ecac420 100644
--- a/chromium/components/page_image_annotation/core/page_annotator.cc
+++ b/chromium/components/page_image_annotation/core/page_annotator.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/page_image_annotation/core/page_annotator.h"
+#include "base/bind.h"
namespace page_image_annotation {
diff --git a/chromium/components/page_image_annotation/core/page_annotator_unittest.cc b/chromium/components/page_image_annotation/core/page_annotator_unittest.cc
index a2c84cb2fee..571b1f4c208 100644
--- a/chromium/components/page_image_annotation/core/page_annotator_unittest.cc
+++ b/chromium/components/page_image_annotation/core/page_annotator_unittest.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/test/scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -180,8 +181,13 @@ TEST(PageAnnotatorTest, Annotation) {
// Expect success and failure to be reported.
const auto error = ia_mojom::AnnotateImageResult::NewErrorCode(
ia_mojom::AnnotateImageError::kCanceled);
+
+ // Can't use an initializer list since it performs copies.
+ std::vector<ia_mojom::AnnotationPtr> annotations;
+ annotations.push_back(ia_mojom::Annotation::New(
+ ia_mojom::AnnotationType::kOcr, 1.0, "text from image"));
const auto success =
- ia_mojom::AnnotateImageResult::NewOcrText("text from image");
+ ia_mojom::AnnotateImageResult::NewAnnotations(std::move(annotations));
ASSERT_THAT(test_annotator.callbacks_, SizeIs(3));
std::move(test_annotator.callbacks_[0]).Run(error.Clone());
diff --git a/chromium/components/page_info_strings.grdp b/chromium/components/page_info_strings.grdp
index 584fbf8e70a..d07378756ff 100644
--- a/chromium/components/page_info_strings.grdp
+++ b/chromium/components/page_info_strings.grdp
@@ -187,16 +187,13 @@
<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>
<message name="IDS_PAGE_INFO_COOKIES_BUTTON_TEXT" desc="The label on a button in the Page Information Window that, when clicked, opens a dialog where cookies can be managed by the user.">
Cookies <ph name="NUM_COOKIES">$1<ex>(4 in use)</ex></ph>
</message>
<message name="IDS_PAGE_INFO_NUM_COOKIES_PARENTHESIZED" desc="The label of the counts for allowed cookies that are in use on the page. This text will be used in IDS_PAGE_INFO_COOKIES_BUTTON_TEXT.">
({NUM_COOKIES, plural, =1 {1 in use} other {# in use}})
</message>
- <message name="IDS_PAGE_INFO_COOKIES_TOOLTIP" desc="The text of the tooltip on IDS_PAGE_INFO_NUM_COOKIES.">
+ <message name="IDS_PAGE_INFO_COOKIES_TOOLTIP" desc="The text of the tooltip on IDS_PAGE_INFO_NUM_COOKIES_PARENTHESIZED.">
Show cookies
</message>
</if>
@@ -322,15 +319,21 @@
</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_USB_DEVICE_SECONDARY_LABEL" desc="The label displayed underneath IDS_PAGE_INFO_USB_DEVICE_LABEL to inform the user that the device name listed is a USB device.">
+ <message name="IDS_PAGE_INFO_USB_DEVICE_SECONDARY_LABEL" desc="The label displayed underneath the device name to inform the user that the item refers to a USB device.">
USB device
</message>
+ <message name="IDS_PAGE_INFO_USB_DEVICE_ALLOWED_BY_POLICY_LABEL" desc="The label displayed underneath the device name to inform the user that the item listed is refering to a USB device explicitly allowed by the user's enterprise policy.">
+ USB device allowed by your administrator
+ </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>
+ <message name="IDS_PAGE_INFO_SERIAL_PORT_SECONDARY_LABEL" desc="The label displayed underneath the port name to inform the user that the permission listed refers to a serial port.">
+ Serial port
+ </message>
+ <message name="IDS_PAGE_INFO_DELETE_SERIAL_PORT" desc="The tooltip displayed when hovering over the button that will remove permission to access a serial port 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.">
diff --git a/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_PRESENTING_TEXT.png.sha1 b/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_PRESENTING_TEXT.png.sha1
new file mode 100644
index 00000000000..1fe9f0a7997
--- /dev/null
+++ b/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_PRESENTING_TEXT.png.sha1
@@ -0,0 +1 @@
+8b44ae50871a8eea88d7d23cfca728fa3bee84ee \ No newline at end of file
diff --git a/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_TURN_OFF_BUTTON_TEXT.png.sha1 b/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_TURN_OFF_BUTTON_TEXT.png.sha1
new file mode 100644
index 00000000000..8a6cffa754e
--- /dev/null
+++ b/chromium/components/page_info_strings_grdp/IDS_PAGE_INFO_VR_TURN_OFF_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+8101a37c9611483f8eb5becad5e96b8e8424f986 \ No newline at end of file
diff --git a/chromium/components/pairing/BUILD.gn b/chromium/components/pairing/BUILD.gn
index 0d176de43d0..ee1b97074bf 100644
--- a/chromium/components/pairing/BUILD.gn
+++ b/chromium/components/pairing/BUILD.gn
@@ -31,7 +31,7 @@ source_set("pairing") {
deps = [
":proto",
"//base",
- "//chromeos:chromeos_constants",
+ "//chromeos/constants",
"//device/bluetooth",
"//net",
"//services/device/public/mojom",
diff --git a/chromium/components/pairing/bluetooth_host_pairing_controller.cc b/chromium/components/pairing/bluetooth_host_pairing_controller.cc
index b575592420c..12e76ad69a1 100644
--- a/chromium/components/pairing/bluetooth_host_pairing_controller.cc
+++ b/chromium/components/pairing/bluetooth_host_pairing_controller.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/hash.h"
#include "base/location.h"
#include "base/logging.h"
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 654b456f37b..58d56380e96 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
@@ -104,8 +104,8 @@ void ContentPasswordManagerDriverFactory::DidFinishNavigation(
if (!navigation_handle->HasCommitted())
return;
- frame_driver_map_.find(navigation_handle->GetRenderFrameHost())
- ->second->DidNavigateFrame(navigation_handle);
+ if (auto* driver = GetDriverForFrame(navigation_handle->GetRenderFrameHost()))
+ driver->DidNavigateFrame(navigation_handle);
}
void ContentPasswordManagerDriverFactory::RequestSendLoggingAvailability() {
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 96e9768b9fa..21c0629d7be 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
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -242,8 +243,8 @@ TEST_F(ContentPasswordManagerDriverTest, NotInformAboutBlacklistedForm) {
driver->FillPasswordForm(fill_data);
}
-INSTANTIATE_TEST_CASE_P(,
- ContentPasswordManagerDriverTest,
- testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ ContentPasswordManagerDriverTest,
+ testing::Values(true, false));
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/BUILD.gn b/chromium/components/password_manager/core/browser/BUILD.gn
index b1ffce2df8a..8cb6e2e4bc3 100644
--- a/chromium/components/password_manager/core/browser/BUILD.gn
+++ b/chromium/components/password_manager/core/browser/BUILD.gn
@@ -170,8 +170,6 @@ jumbo_static_library("browser") {
"sync/password_sync_bridge.h",
"sync/password_syncable_service.cc",
"sync/password_syncable_service.h",
- "sync/password_syncable_service_based_model_type_controller.cc",
- "sync/password_syncable_service_based_model_type_controller.h",
"sync_credentials_filter.cc",
"sync_credentials_filter.h",
"ui/credential_provider_interface.h",
@@ -375,6 +373,7 @@ bundle_data("unit_tests_bundle_data") {
"//components/test/data/password_manager/login_db_v2.sql",
"//components/test/data/password_manager/login_db_v20.sql",
"//components/test/data/password_manager/login_db_v21.sql",
+ "//components/test/data/password_manager/login_db_v22.sql",
"//components/test/data/password_manager/login_db_v2_broken.sql",
"//components/test/data/password_manager/login_db_v3.sql",
"//components/test/data/password_manager/login_db_v3_broken.sql",
diff --git a/chromium/components/password_manager/core/browser/DEPS b/chromium/components/password_manager/core/browser/DEPS
index 305b6738188..d17be605b2b 100644
--- a/chromium/components/password_manager/core/browser/DEPS
+++ b/chromium/components/password_manager/core/browser/DEPS
@@ -10,6 +10,7 @@ include_rules = [
"+components/sync/driver",
"+components/sync/engine",
"+components/sync/model_impl",
+ "+components/sync/test",
"+components/sync_preferences",
"+components/url_formatter",
"+components/variations",
diff --git a/chromium/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc b/chromium/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc
index 953fb245cc5..b23f1cd1c5f 100644
--- a/chromium/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc
+++ b/chromium/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc
@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
diff --git a/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetch_throttler.cc b/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetch_throttler.cc
index cd3c41f8b6d..0cf9dcee72d 100644
--- a/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetch_throttler.cc
+++ b/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetch_throttler.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/sequenced_task_runner.h"
diff --git a/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc b/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc
index f3c09a256ec..293e7fc256f 100644
--- a/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc
+++ b/chromium/components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc
@@ -11,6 +11,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_api.pb.h"
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 36a3a7a3aef..cc70f91fe89 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
@@ -4,6 +4,7 @@
#include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -15,11 +16,11 @@
#include "components/autofill/core/common/signatures_util.h"
#include "components/password_manager/core/browser/log_manager.h"
#include "components/password_manager/core/browser/password_form_manager.h"
+#include "components/password_manager/core/browser/password_form_metrics_recorder.h"
#include "components/password_manager/core/browser/password_manager.h"
using autofill::AutofillUploadContents;
using base::NumberToString;
-using base::UintToString;
namespace password_manager {
@@ -77,6 +78,13 @@ std::string VoteTypeToString(
}
}
+std::string FormSignatureToDebugString(autofill::FormSignature form_signature) {
+ return base::StrCat(
+ {NumberToString(form_signature), " - ",
+ NumberToString(
+ PasswordFormMetricsRecorder::HashFormSignature(form_signature))});
+}
+
} // namespace
BrowserSavePasswordProgressLogger::BrowserSavePasswordProgressLogger(
@@ -93,7 +101,7 @@ void BrowserSavePasswordProgressLogger::LogFormSignatures(
autofill::FormStructure form_structure(form.form_data);
std::string message = GetStringFromID(label) + ": {\n";
message += GetStringFromID(STRING_FORM_SIGNATURE) + ": " +
- ScrubNonDigit(form_structure.FormSignatureAsStr()) + "\n";
+ FormSignatureToDebugString(form_structure.form_signature()) + "\n";
message += GetStringFromID(STRING_SIGNON_REALM) + ": " +
ScrubURL(GURL(form.signon_realm)) + "\n";
message +=
@@ -112,7 +120,7 @@ void BrowserSavePasswordProgressLogger::LogFormStructure(
const autofill::FormStructure& form_structure) {
std::string message = GetStringFromID(label) + ": {\n";
message += GetStringFromID(STRING_FORM_SIGNATURE) + ": " +
- ScrubNonDigit(form_structure.FormSignatureAsStr()) + "\n";
+ FormSignatureToDebugString(form_structure.form_signature()) + "\n";
message += GetStringFromID(STRING_ORIGIN) + ": " +
ScrubURL(form_structure.source_url()) + "\n";
message += GetStringFromID(STRING_ACTION) + ": " +
@@ -145,7 +153,8 @@ std::string BrowserSavePasswordProgressLogger::FormStructureToFieldsLogString(
ScrubNonDigit(field->FieldSignatureAsStr()) +
", type=" + ScrubElementID(field->form_control_type);
- field_info += ", renderer_id = " + UintToString(field->unique_renderer_id);
+ field_info +=
+ ", renderer_id = " + NumberToString(field->unique_renderer_id);
if (!field->autocomplete_attribute.empty())
field_info +=
@@ -217,8 +226,9 @@ void BrowserSavePasswordProgressLogger::LogFormData(
StringID label,
const autofill::FormData& form) {
std::string message = GetStringFromID(label) + ": {\n";
- message += GetStringFromID(STRING_FORM_SIGNATURE) + ": " +
- NumberToString(autofill::CalculateFormSignature(form)) + "\n";
+ message +=
+ GetStringFromID(STRING_FORM_SIGNATURE) + ": " +
+ FormSignatureToDebugString(autofill::CalculateFormSignature(form)) + "\n";
message +=
GetStringFromID(STRING_ORIGIN) + ": " + ScrubURL(form.origin) + "\n";
message +=
@@ -234,7 +244,7 @@ void BrowserSavePasswordProgressLogger::LogFormData(
if (form.is_form_tag) {
message +=
- "Form renderer id: " + UintToString(form.unique_renderer_id) + "\n";
+ "Form renderer id: " + NumberToString(form.unique_renderer_id) + "\n";
}
// Log fields.
@@ -250,7 +260,7 @@ void BrowserSavePasswordProgressLogger::LogFormData(
std::string field_info =
ScrubElementID(field.name) +
": type=" + ScrubElementID(field.form_control_type) +
- ", renderer_id = " + UintToString(field.unique_renderer_id) + ", " +
+ ", renderer_id = " + NumberToString(field.unique_renderer_id) + ", " +
is_visible + ", " + is_empty + autocomplete + "\n";
message += field_info;
}
diff --git a/chromium/components/password_manager/core/browser/credential_manager_impl.cc b/chromium/components/password_manager/core/browser/credential_manager_impl.cc
index d1a97d4a100..363f5fc9b3b 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_impl.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_impl.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/user_metrics.h"
#include "components/password_manager/core/browser/credential_manager_logger.h"
#include "components/password_manager/core/browser/form_fetcher_impl.h"
diff --git a/chromium/components/password_manager/core/browser/credential_manager_password_form_manager.cc b/chromium/components/password_manager/core/browser/credential_manager_password_form_manager.cc
index e1bdd71165c..7779e0c40ff 100644
--- a/chromium/components/password_manager/core/browser/credential_manager_password_form_manager.cc
+++ b/chromium/components/password_manager/core/browser/credential_manager_password_form_manager.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/threading/sequenced_task_runner_handle.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 ea4f5daf6f1..9179e89ec6f 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
@@ -10,6 +10,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/user_metrics.h"
#include "base/stl_util.h"
#include "components/autofill/core/common/password_form.h"
diff --git a/chromium/components/password_manager/core/browser/credentials_filter.h b/chromium/components/password_manager/core/browser/credentials_filter.h
index f65c1fb63b4..13b83d6c9ca 100644
--- a/chromium/components/password_manager/core/browser/credentials_filter.h
+++ b/chromium/components/password_manager/core/browser/credentials_filter.h
@@ -19,11 +19,6 @@ class CredentialsFilter {
CredentialsFilter() {}
virtual ~CredentialsFilter() {}
- // Removes from |results| all forms which should be ignored for any password
- // manager-related purposes, and returns the rest.
- virtual std::vector<std::unique_ptr<autofill::PasswordForm>> FilterResults(
- std::vector<std::unique_ptr<autofill::PasswordForm>> results) const = 0;
-
// Should |form| be offered to be saved?
virtual bool ShouldSave(const autofill::PasswordForm& form) const = 0;
diff --git a/chromium/components/password_manager/core/browser/export/password_manager_exporter.cc b/chromium/components/password_manager/core/browser/export/password_manager_exporter.cc
index 477fef05f1d..d3a13e438d0 100644
--- a/chromium/components/password_manager/core/browser/export/password_manager_exporter.cc
+++ b/chromium/components/password_manager/core/browser/export/password_manager_exporter.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
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 b1a6672aee8..cbc8c0a60f8 100644
--- a/chromium/components/password_manager/core/browser/form_fetcher_impl.cc
+++ b/chromium/components/password_manager/core/browser/form_fetcher_impl.cc
@@ -320,9 +320,6 @@ void FormFetcherImpl::ProcessPasswordStoreResults(
const size_t original_count = non_federated_.size();
- non_federated_ =
- client_->GetStoreResultFilter()->FilterResults(std::move(non_federated_));
-
filtered_count_ = original_count - non_federated_.size();
weak_non_federated_ = MakeWeakCopies(non_federated_);
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 d0975d27457..d58868223c0 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
@@ -75,14 +75,6 @@ class NameFilter : public StubCredentialsFilter {
~NameFilter() override = default;
- std::vector<std::unique_ptr<PasswordForm>> FilterResults(
- std::vector<std::unique_ptr<PasswordForm>> results) const override {
- base::EraseIf(results, [this](const std::unique_ptr<PasswordForm>& form) {
- return !ShouldSave(*form);
- });
- return results;
- }
-
bool ShouldSave(const PasswordForm& form) const override {
return form.username_value != name_;
}
@@ -381,11 +373,12 @@ TEST_F(FormFetcherImplTest, Filtered) {
results.push_back(std::make_unique<PasswordForm>(federated));
results.push_back(std::make_unique<PasswordForm>(non_federated1));
results.push_back(std::make_unique<PasswordForm>(non_federated2));
- // Non-federated results should have been filtered: no "user" here.
- constexpr size_t kNumFiltered = 1u;
+ // Expect that nothing got filtered out, since CredentialsFilter no longer
+ // filters things out:
EXPECT_CALL(consumer_,
- ProcessMatches(UnorderedElementsAre(Pointee(non_federated2)),
- kNumFiltered));
+ ProcessMatches(UnorderedElementsAre(Pointee(non_federated1),
+ Pointee(non_federated2)),
+ 0U));
form_fetcher_->OnGetPasswordStoreResults(std::move(results));
EXPECT_EQ(FormFetcher::State::NOT_WAITING, form_fetcher_->GetState());
// However, federated results should not be filtered.
diff --git a/chromium/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/chromium/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index 7fcc6d6fbd1..1b0eaa1ddd7 100644
--- a/chromium/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/chromium/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -109,7 +109,7 @@ uint32_t GetUniqueId() {
// Use to add a number suffix which is unique in the scope of the test.
base::string16 StampUniqueSuffix(const char* base_str) {
return ASCIIToUTF16(base_str) + ASCIIToUTF16("_") +
- base::UintToString16(GetUniqueId());
+ base::NumberToString16(GetUniqueId());
}
// Describes which renderer IDs are expected for username/password fields
diff --git a/chromium/components/password_manager/core/browser/form_parsing/ios_form_parser_unittest.cc b/chromium/components/password_manager/core/browser/form_parsing/ios_form_parser_unittest.cc
index 69c9001341d..f492f870e58 100644
--- a/chromium/components/password_manager/core/browser/form_parsing/ios_form_parser_unittest.cc
+++ b/chromium/components/password_manager/core/browser/form_parsing/ios_form_parser_unittest.cc
@@ -19,7 +19,7 @@ using autofill::FormData;
using autofill::FormFieldData;
using autofill::PasswordForm;
using base::ASCIIToUTF16;
-using base::UintToString16;
+using base::NumberToString16;
namespace password_manager {
@@ -78,8 +78,8 @@ FormData GetFormData(const FormParsingTestCase& test_form) {
FormFieldData field;
// An exact id is not important, set id such that different fields have
// different id.
- field.name_attribute = ASCIIToUTF16("field_name") + UintToString16(i);
- field.id_attribute = ASCIIToUTF16("field_id") + UintToString16(i);
+ field.name_attribute = ASCIIToUTF16("field_name") + NumberToString16(i);
+ field.id_attribute = ASCIIToUTF16("field_id") + NumberToString16(i);
// The fuzzing infrastructure doez not run on iOS, so the iOS specific parts of
// PasswordForm are also built on fuzzer enabled platforms.
@@ -98,7 +98,7 @@ FormData GetFormData(const FormParsingTestCase& test_form) {
} else if (!field_data.is_empty) {
// An exact value is not important, set a value with simple pattern, such
// that different fields have different values.
- field.value = ASCIIToUTF16("field_value") + UintToString16(i);
+ field.value = ASCIIToUTF16("field_value") + NumberToString16(i);
}
if (field_data.autocomplete_attribute)
field.autocomplete_attribute = field_data.autocomplete_attribute;
diff --git a/chromium/components/password_manager/core/browser/http_credentials_cleaner.cc b/chromium/components/password_manager/core/browser/http_credentials_cleaner.cc
index 5d5920b156c..8a118b7967f 100644
--- a/chromium/components/password_manager/core/browser/http_credentials_cleaner.cc
+++ b/chromium/components/password_manager/core/browser/http_credentials_cleaner.cc
@@ -4,6 +4,7 @@
#include "components/password_manager/core/browser/http_credentials_cleaner.h"
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "components/password_manager/core/browser/http_password_store_migrator.h"
#include "components/password_manager/core/browser/password_manager_util.h"
diff --git a/chromium/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/chromium/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
index b5e72c63a33..953610cd6d3 100644
--- a/chromium/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
+++ b/chromium/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -239,9 +239,9 @@ TEST_P(HttpCredentialCleanerTest, ReportHttpMigrationMetrics) {
scoped_task_environment.RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(,
- HttpCredentialCleanerTest,
- ::testing::ValuesIn(kCases));
+INSTANTIATE_TEST_SUITE_P(,
+ HttpCredentialCleanerTest,
+ ::testing::ValuesIn(kCases));
TEST(HttpCredentialCleaner, StartCleanUpTest) {
for (bool should_start_clean_up : {false, true}) {
diff --git a/chromium/components/password_manager/core/browser/http_password_store_migrator.cc b/chromium/components/password_manager/core/browser/http_password_store_migrator.cc
index 4c28d456fd8..b20b4bbffb2 100644
--- a/chromium/components/password_manager/core/browser/http_password_store_migrator.cc
+++ b/chromium/components/password_manager/core/browser/http_password_store_migrator.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
diff --git a/chromium/components/password_manager/core/browser/import/csv_reader.cc b/chromium/components/password_manager/core/browser/import/csv_reader.cc
index 249ad094cd4..8eb0d0eb889 100644
--- a/chromium/components/password_manager/core/browser/import/csv_reader.cc
+++ b/chromium/components/password_manager/core/browser/import/csv_reader.cc
@@ -16,24 +16,27 @@
namespace {
// Returns all the characters from the start of |input| until the first '\n',
-// '\r' (exclusive) or the end of |input|. Cuts the returned part (inclusive the
-// line breaks) from |input|. Skips blocks of matching quotes. Examples:
+// "\r\n" (exclusive) or the end of |input|. Cuts the returned part (inclusive
+// the line breaks) from |input|. Skips blocks of matching quotes. Examples:
// old input -> returned value, new input
// "ab\ncd" -> "ab", "cd"
-// "\r\n" -> "", "\n"
+// "\r\n" -> "", ""
// "abcd" -> "abcd", ""
+// "\r" -> "\r", ""
// "a\"\n\"b" -> "a\"\n\"b", ""
base::StringPiece ConsumeLine(base::StringPiece* input) {
DCHECK(input);
DCHECK(!input->empty());
bool inside_quotes = false;
+ bool last_char_was_CR = false;
for (size_t current = 0; current < input->size(); ++current) {
- switch ((*input)[current]) {
+ char c = (*input)[current];
+ switch (c) {
case '\n':
- case '\r':
if (!inside_quotes) {
- base::StringPiece ret(input->data(), current);
+ const size_t eol_start = last_char_was_CR ? current - 1 : current;
+ base::StringPiece ret(input->data(), eol_start);
*input = input->substr(current + 1);
return ret;
}
@@ -44,6 +47,7 @@ base::StringPiece ConsumeLine(base::StringPiece* input) {
default:
break;
}
+ last_char_was_CR = (c == '\r');
}
// The whole |*input| is one line.
@@ -296,12 +300,8 @@ bool CSVTable::ReadCSV(base::StringPiece csv) {
records_.clear();
column_names_.clear();
- // Normalize EOL sequences so that we uniformly use a single LF character.
- std::string normalized_csv(csv);
- base::ReplaceSubstringsAfterOffset(&normalized_csv, 0, "\r\n", "\n");
-
// Read header row.
- CSVParser parser(normalized_csv);
+ CSVParser parser(csv);
if (!parser.HasMoreRows()) {
// The empty CSV is a special case. It can be seen as having one row, with a
// single field, which is an empty string.
@@ -316,10 +316,9 @@ bool CSVTable::ReadCSV(base::StringPiece csv) {
while (parser.HasMoreRows()) {
if (!parser.ParseNextCSVRow(&fields))
return false;
- // If there are more line-breaking characters ('\r' or '\n') in sequence,
- // the row parser will see an empty row in between each successive two of
- // those. Discard such results, because those are useless for importing
- // passwords.
+ // If there are more line-breaking characters in sequence, the row parser
+ // will see an empty row in between each successive two of those. Discard
+ // such results, because those are useless for importing passwords.
if (fields.size() == 1 && fields[0].empty())
continue;
diff --git a/chromium/components/password_manager/core/browser/import/csv_reader.h b/chromium/components/password_manager/core/browser/import/csv_reader.h
index d05c537dcde..48ebe5ad92f 100644
--- a/chromium/components/password_manager/core/browser/import/csv_reader.h
+++ b/chromium/components/password_manager/core/browser/import/csv_reader.h
@@ -25,8 +25,7 @@ class CSVTable {
// defined in RFC 4180, with the following limitations/relaxations:
// * The input should be UTF-8 encoded. No code points should be escaped.
// * The first line must be a header that contains the column names.
- // * Records may be separated by either LF or CRLF sequences. Each CRLF will
- // be converted to LF characters inside quotes.
+ // * Records may be separated by either LF or CRLF sequences.
// * Inconsistent number of fields within records is handled gracefully.
// Extra fields are ignored. Missing fields will have no corresponding
// key-value pair in the record.
diff --git a/chromium/components/password_manager/core/browser/import/csv_reader_unittest.cc b/chromium/components/password_manager/core/browser/import/csv_reader_unittest.cc
index a69ccd6085f..f981540b4b6 100644
--- a/chromium/components/password_manager/core/browser/import/csv_reader_unittest.cc
+++ b/chromium/components/password_manager/core/browser/import/csv_reader_unittest.cc
@@ -104,7 +104,7 @@ TEST(CSVReaderTest, Positive) {
"\",\",\",,\"\n",
{"left", "right"},
{{{"left", "A\rB"}, {"right", "B\nC"}},
- {{"left", "C\nD"}, {"right", "D\n"}},
+ {{"left", "C\r\nD"}, {"right", "D\n"}},
{{"left", ","}, {"right", ",,"}}},
},
{
@@ -143,11 +143,19 @@ TEST(CSVReaderTest, Positive) {
{{"left", ""}, {"middle", ""}, {"right", "gamma"}}},
},
{
- "CRLFTreatedAsAndConvertedToLF",
+ "CRLFTreatedAsLF",
"left,right\r\n"
"\"\r\",\"\r\n\"\r\n",
{"left", "right"},
- {{{"left", "\r"}, {"right", "\n"}}},
+ {{{"left", "\r"}, {"right", "\r\n"}}},
+ },
+ {
+ "CRAloneIgnored",
+ "left,right\r"
+ "A,B\r\n"
+ "1,2,3",
+ {"left", "right\rA", "B"},
+ {{{"B", "3"}, {"left", "1"}, {"right\rA", "2"}}},
},
{
"LastValueForRepeatedColumnNamesIsPreserved",
@@ -167,13 +175,13 @@ TEST(CSVReaderTest, Positive) {
"foo,bar\n"
"\n"
"a,b\n"
- "\r"
+ "\r\n"
"c,d\r\r\r\r\r\r\r\r\n"
"e,f",
{"foo", "bar"},
{
{{"bar", "b"}, {"foo", "a"}},
- {{"bar", "d"}, {"foo", "c"}},
+ {{"bar", "d\r\r\r\r\r\r\r"}, {"foo", "c"}},
{{"bar", "f"}, {"foo", "e"}},
},
},
diff --git a/chromium/components/password_manager/core/browser/login_database.cc b/chromium/components/password_manager/core/browser/login_database.cc
index 0fd9e5e432e..de4f10e0a2b 100644
--- a/chromium/components/password_manager/core/browser/login_database.cc
+++ b/chromium/components/password_manager/core/browser/login_database.cc
@@ -25,6 +25,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/common/password_form.h"
@@ -52,7 +53,7 @@ using autofill::PasswordForm;
namespace password_manager {
// The current version number of the login database schema.
-const int kCurrentVersionNumber = 21;
+const int kCurrentVersionNumber = 22;
// The oldest version of the schema such that a legacy Chrome client using that
// version can still read/write the current database.
const int kCompatibleVersionNumber = 19;
@@ -374,6 +375,16 @@ void LogPasswordReuseMetrics(const std::vector<std::string>& signon_realms) {
}
}
+bool ClearAllSyncMetadata(sql::Database* db) {
+ sql::Statement s1(
+ db->GetCachedStatement(SQL_FROM_HERE, "DELETE FROM sync_model_metadata"));
+
+ sql::Statement s2(db->GetCachedStatement(
+ SQL_FROM_HERE, "DELETE FROM sync_entities_metadata"));
+
+ return s1.Run() && s2.Run();
+}
+
// Seals the version of the given builders. This is method should be always used
// to seal versions of all builder to make sure all builders are at the same
// version.
@@ -488,6 +499,9 @@ void InitializeBuilders(SQLTableBuilders builders) {
builders.sync_model_metadata->AddColumn("model_metadata", "VARCHAR NOT NULL");
SealVersion(builders, /*expected_version=*/21u);
+ // Version 22. Changes in Sync metadata encryption.
+ SealVersion(builders, /*expected_version=*/22u);
+
DCHECK_EQ(static_cast<size_t>(COLUMN_NUM), builders.logins->NumberOfColumns())
<< "Adjust LoginDatabaseTableColumns if you change column definitions "
"here.";
@@ -527,6 +541,13 @@ bool MigrateLogins(unsigned current_version,
return false;
}
+ // Sync Metadata tables have been introduced in version 21. It is enough to
+ // drop all data because Sync would populate the tables properly at startup.
+ if (current_version == 21) {
+ if (!ClearAllSyncMetadata(db))
+ return false;
+ }
+
return true;
}
@@ -1073,15 +1094,20 @@ bool LoginDatabase::RemoveLogin(const PasswordForm& form,
bool LoginDatabase::RemoveLoginByPrimaryKey(int primary_key,
PasswordStoreChangeList* changes) {
- PrimaryKeyToFormMap key_to_form_map;
+ PasswordForm form;
if (changes) {
changes->clear();
sql::Statement s1(db_.GetCachedStatement(
SQL_FROM_HERE, "SELECT * FROM logins WHERE id = ?"));
s1.BindInt(0, primary_key);
- if (!StatementToForms(&s1, nullptr, &key_to_form_map)) {
+ if (!s1.Step()) {
return false;
}
+ int db_primary_key = -1;
+ EncryptionResult result = InitPasswordFormFromStatement(
+ s1, /*decrypt_and_fill_password_value=*/false, &db_primary_key, &form);
+ DCHECK_EQ(result, ENCRYPTION_RESULT_SUCCESS);
+ DCHECK_EQ(db_primary_key, primary_key);
}
#if defined(OS_IOS)
@@ -1095,8 +1121,8 @@ bool LoginDatabase::RemoveLoginByPrimaryKey(int primary_key,
return false;
}
if (changes) {
- changes->emplace_back(PasswordStoreChange::REMOVE,
- *key_to_form_map[primary_key], primary_key);
+ changes->emplace_back(PasswordStoreChange::REMOVE, std::move(form),
+ primary_key);
}
return true;
}
@@ -1189,11 +1215,11 @@ bool LoginDatabase::GetAutoSignInLogins(
sql::Statement s(
db_.GetCachedStatement(SQL_FROM_HERE, autosignin_statement_.c_str()));
PrimaryKeyToFormMap key_to_form_map;
- bool result = StatementToForms(&s, nullptr, &key_to_form_map);
+ FormRetrievalResult result = StatementToForms(&s, nullptr, &key_to_form_map);
for (auto& pair : key_to_form_map) {
forms->push_back(std::move(pair.second));
}
- return result;
+ return result == FormRetrievalResult::kSuccess;
}
bool LoginDatabase::DisableAutoSignInForOrigin(const GURL& origin) {
@@ -1207,17 +1233,20 @@ bool LoginDatabase::DisableAutoSignInForOrigin(const GURL& origin) {
LoginDatabase::EncryptionResult LoginDatabase::InitPasswordFormFromStatement(
const sql::Statement& s,
+ bool decrypt_and_fill_password_value,
int* primary_key,
PasswordForm* form) const {
std::string encrypted_password;
s.ColumnBlobAsString(COLUMN_PASSWORD_VALUE, &encrypted_password);
base::string16 decrypted_password;
- EncryptionResult encryption_result =
- DecryptedString(encrypted_password, &decrypted_password);
- if (encryption_result != ENCRYPTION_RESULT_SUCCESS) {
- VLOG(0) << "Password decryption failed, encryption_result is "
- << encryption_result;
- return encryption_result;
+ if (decrypt_and_fill_password_value) {
+ EncryptionResult encryption_result =
+ DecryptedString(encrypted_password, &decrypted_password);
+ if (encryption_result != ENCRYPTION_RESULT_SUCCESS) {
+ VLOG(0) << "Password decryption failed, encryption_result is "
+ << encryption_result;
+ return encryption_result;
+ }
}
*primary_key = s.ColumnInt(COLUMN_ID);
@@ -1354,10 +1383,10 @@ bool LoginDatabase::GetLogins(
PSL_DOMAIN_MATCH_COUNT);
}
PrimaryKeyToFormMap key_to_form_map;
- bool success = StatementToForms(
+ FormRetrievalResult result = StatementToForms(
&s, should_PSL_matching_apply || should_federated_apply ? &form : nullptr,
&key_to_form_map);
- if (!success) {
+ if (result != FormRetrievalResult::kSuccess) {
return false;
}
for (auto& pair : key_to_form_map) {
@@ -1394,7 +1423,7 @@ bool LoginDatabase::GetLoginsForSameOrganizationName(
s.BindString(0, signon_realms_with_same_organization_name_regexp);
PrimaryKeyToFormMap key_to_form_map;
- bool success = StatementToForms(&s, nullptr, &key_to_form_map);
+ FormRetrievalResult result = StatementToForms(&s, nullptr, &key_to_form_map);
for (auto& pair : key_to_form_map) {
forms->push_back(std::move(pair.second));
}
@@ -1409,7 +1438,7 @@ bool LoginDatabase::GetLoginsForSameOrganizationName(
return candidate_form_organization_name != organization_name;
});
- return success;
+ return result == FormRetrievalResult::kSuccess;
}
bool LoginDatabase::GetLoginsCreatedBetween(
@@ -1424,7 +1453,8 @@ bool LoginDatabase::GetLoginsCreatedBetween(
s.BindInt64(1, end.is_null() ? std::numeric_limits<int64_t>::max()
: end.ToInternalValue());
- return StatementToForms(&s, nullptr, key_to_form_map);
+ return StatementToForms(&s, nullptr, key_to_form_map) ==
+ FormRetrievalResult::kSuccess;
}
bool LoginDatabase::GetLoginsSyncedBetween(
@@ -1440,10 +1470,12 @@ bool LoginDatabase::GetLoginsSyncedBetween(
end.is_null() ? base::Time::Max().ToInternalValue()
: end.ToInternalValue());
- return StatementToForms(&s, nullptr, key_to_form_map);
+ return StatementToForms(&s, nullptr, key_to_form_map) ==
+ FormRetrievalResult::kSuccess;
}
-bool LoginDatabase::GetAllLogins(PrimaryKeyToFormMap* key_to_form_map) {
+FormRetrievalResult LoginDatabase::GetAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) {
DCHECK(key_to_form_map);
key_to_form_map->clear();
@@ -1476,7 +1508,8 @@ bool LoginDatabase::GetAllLoginsWithBlacklistSetting(
PrimaryKeyToFormMap key_to_form_map;
- if (!StatementToForms(&s, nullptr, &key_to_form_map)) {
+ if (StatementToForms(&s, nullptr, &key_to_form_map) !=
+ FormRetrievalResult::kSuccess) {
return false;
}
@@ -1568,6 +1601,23 @@ std::string LoginDatabase::GetEncryptedPassword(
return encrypted_password;
}
+std::unique_ptr<syncer::MetadataBatch> LoginDatabase::GetAllSyncMetadata() {
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch =
+ GetAllSyncEntityMetadata();
+ if (metadata_batch == nullptr) {
+ return nullptr;
+ }
+
+ std::unique_ptr<sync_pb::ModelTypeState> model_type_state =
+ GetModelTypeState();
+ if (model_type_state == nullptr) {
+ return nullptr;
+ }
+
+ metadata_batch->SetModelTypeState(*model_type_state);
+ return metadata_batch;
+}
+
bool LoginDatabase::UpdateSyncMetadata(
syncer::ModelType model_type,
const std::string& storage_key,
@@ -1581,13 +1631,20 @@ bool LoginDatabase::UpdateSyncMetadata(
return false;
}
+ std::string encrypted_metadata;
+ if (!OSCrypt::EncryptString(metadata.SerializeAsString(),
+ &encrypted_metadata)) {
+ DLOG(ERROR) << "Cannot encrypt the sync metadata";
+ return false;
+ }
+
sql::Statement s(
db_.GetCachedStatement(SQL_FROM_HERE,
"INSERT OR REPLACE INTO sync_entities_metadata "
"(storage_key, metadata) VALUES(?, ?)"));
s.BindInt(0, storage_key_int);
- s.BindString(1, metadata.SerializeAsString());
+ s.BindString(1, encrypted_metadata);
return s.Run();
}
@@ -1663,25 +1720,7 @@ int LoginDatabase::GetPrimaryKey(const PasswordForm& form) const {
}
std::unique_ptr<syncer::MetadataBatch>
-LoginDatabase::GetAllSyncMetadataForTesting() {
- std::unique_ptr<syncer::MetadataBatch> metadata_batch =
- GetAllSyncEntityMetadataForTesting();
- if (metadata_batch == nullptr) {
- return nullptr;
- }
-
- std::unique_ptr<sync_pb::ModelTypeState> model_type_state =
- GetModelTypeStateForTesting();
- if (model_type_state == nullptr) {
- return nullptr;
- }
-
- metadata_batch->SetModelTypeState(*model_type_state);
- return metadata_batch;
-}
-
-std::unique_ptr<syncer::MetadataBatch>
-LoginDatabase::GetAllSyncEntityMetadataForTesting() {
+LoginDatabase::GetAllSyncEntityMetadata() {
auto metadata_batch = std::make_unique<syncer::MetadataBatch>();
sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE,
"SELECT storage_key, metadata FROM "
@@ -1689,9 +1728,17 @@ LoginDatabase::GetAllSyncEntityMetadataForTesting() {
while (s.Step()) {
std::string storage_key = s.ColumnString(0);
- std::string serialized_metadata = s.ColumnString(1);
+ std::string encrypted_serialized_metadata = s.ColumnString(1);
+ std::string decrypted_serialized_metadata;
+ if (!OSCrypt::DecryptString(encrypted_serialized_metadata,
+ &decrypted_serialized_metadata)) {
+ DLOG(WARNING) << "Failed to decrypt PASSWORD model type "
+ "sync_pb::EntityMetadata.";
+ return nullptr;
+ }
+
sync_pb::EntityMetadata entity_metadata;
- if (entity_metadata.ParseFromString(serialized_metadata)) {
+ if (entity_metadata.ParseFromString(decrypted_serialized_metadata)) {
metadata_batch->AddMetadata(storage_key, entity_metadata);
} else {
DLOG(WARNING) << "Failed to deserialize PASSWORD model type "
@@ -1705,8 +1752,7 @@ LoginDatabase::GetAllSyncEntityMetadataForTesting() {
return metadata_batch;
}
-std::unique_ptr<sync_pb::ModelTypeState>
-LoginDatabase::GetModelTypeStateForTesting() {
+std::unique_ptr<sync_pb::ModelTypeState> LoginDatabase::GetModelTypeState() {
auto state = std::make_unique<sync_pb::ModelTypeState>();
sql::Statement s(db_.GetCachedStatement(
SQL_FROM_HERE,
@@ -1726,7 +1772,7 @@ LoginDatabase::GetModelTypeStateForTesting() {
return nullptr;
}
-bool LoginDatabase::StatementToForms(
+FormRetrievalResult LoginDatabase::StatementToForms(
sql::Statement* statement,
const PasswordStore::FormDigest* matched_form,
PrimaryKeyToFormMap* key_to_form_map) {
@@ -1738,10 +1784,11 @@ bool LoginDatabase::StatementToForms(
while (statement->Step()) {
auto new_form = std::make_unique<PasswordForm>();
int primary_key = -1;
- EncryptionResult result =
- InitPasswordFormFromStatement(*statement, &primary_key, new_form.get());
+ EncryptionResult result = InitPasswordFormFromStatement(
+ *statement, /*decrypt_and_fill_password_value=*/true, &primary_key,
+ new_form.get());
if (result == ENCRYPTION_RESULT_SERVICE_FAILURE)
- return false;
+ return FormRetrievalResult::kEncrytionServiceFailure;
if (result == ENCRYPTION_RESULT_ITEM_FAILURE) {
if (IsUsingCleanupMechanism())
forms_to_be_deleted.push_back(GetFormForRemoval(*statement));
@@ -1802,8 +1849,8 @@ bool LoginDatabase::StatementToForms(
#endif
if (!statement->Succeeded())
- return false;
- return true;
+ return FormRetrievalResult::kDbError;
+ return FormRetrievalResult::kSuccess;
}
void LoginDatabase::InitializeStatementStrings(const SQLTableBuilder& builder) {
@@ -1829,9 +1876,8 @@ void LoginDatabase::InitializeStatementStrings(const SQLTableBuilder& builder) {
all_column_names + ") VALUES " +
right_amount_of_placeholders;
DCHECK(update_statement_.empty());
- update_statement_ = "UPDATE OR REPLACE logins SET " +
- all_nonunique_key_column_names + " WHERE " +
- all_unique_key_column_names;
+ update_statement_ = "UPDATE logins SET " + all_nonunique_key_column_names +
+ " WHERE " + all_unique_key_column_names;
DCHECK(delete_statement_.empty());
delete_statement_ = "DELETE FROM logins WHERE " + all_unique_key_column_names;
DCHECK(delete_by_id_statement_.empty());
diff --git a/chromium/components/password_manager/core/browser/login_database.h b/chromium/components/password_manager/core/browser/login_database.h
index 7fceb881ced..f7d8fcce0cf 100644
--- a/chromium/components/password_manager/core/browser/login_database.h
+++ b/chromium/components/password_manager/core/browser/login_database.h
@@ -17,10 +17,10 @@
#include "build/build_config.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_change.h"
+#include "components/password_manager/core/browser/password_store_sync.h"
#include "components/password_manager/core/browser/psl_matching_helper.h"
#include "components/password_manager/core/browser/statistics_table.h"
#include "components/sync/model/metadata_batch.h"
-#include "components/sync/model/sync_metadata_store.h"
#include "components/sync/protocol/model_type_state.pb.h"
#include "sql/database.h"
#include "sql/meta_table.h"
@@ -43,7 +43,7 @@ extern const int kCompatibleVersionNumber;
// Interface to the database storage of login information, intended as a helper
// for PasswordStore on platforms that need internal storage of some or all of
// the login information.
-class LoginDatabase : public syncer::SyncMetadataStore {
+class LoginDatabase : public PasswordStoreSync::MetadataStore {
public:
explicit LoginDatabase(const base::FilePath& db_path);
~LoginDatabase() override;
@@ -145,7 +145,8 @@ class LoginDatabase : public syncer::SyncMetadataStore {
WARN_UNUSED_RESULT;
// Gets the complete list of all credentials.
- bool GetAllLogins(PrimaryKeyToFormMap* key_to_form_map) WARN_UNUSED_RESULT;
+ FormRetrievalResult GetAllLogins(PrimaryKeyToFormMap* key_to_form_map)
+ WARN_UNUSED_RESULT;
// Gets the complete list of not blacklisted credentials.
bool GetAutofillableLogins(
@@ -180,7 +181,8 @@ class LoginDatabase : public syncer::SyncMetadataStore {
// empty string if the row for this |form| is not found.
std::string GetEncryptedPassword(const autofill::PasswordForm& form) const;
- // syncer::SyncMetadataStore implementation.
+ // PasswordStoreSync::MetadataStore implementation.
+ std::unique_ptr<syncer::MetadataBatch> GetAllSyncMetadata() override;
bool UpdateSyncMetadata(syncer::ModelType model_type,
const std::string& storage_key,
const sync_pb::EntityMetadata& metadata) override;
@@ -197,9 +199,6 @@ class LoginDatabase : public syncer::SyncMetadataStore {
bool BeginTransaction();
bool CommitTransaction();
- // Returns all the stored sync metadata. Returns null in case of failure.
- std::unique_ptr<syncer::MetadataBatch> GetAllSyncMetadataForTesting();
-
StatisticsTable& stats_table() { return stats_table_; }
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -257,11 +256,15 @@ class LoginDatabase : public syncer::SyncMetadataStore {
// Fills |form| from the values in the given statement (which is assumed to be
// of the form used by the Get*Logins methods). Fills the corresponding DB
- // primary key in |primary_key|. Returns the EncryptionResult from decrypting
- // the password in |s|; if not ENCRYPTION_RESULT_SUCCESS, |form| is not
- // filled.
+ // primary key in |primary_key|. If |decrypt_and_fill_password_value| is set
+ // to true, it tries to decrypt the stored password and returns the
+ // EncryptionResult from decrypting the password in |s|; if not
+ // ENCRYPTION_RESULT_SUCCESS, |form| is not filled. If
+ // |decrypt_and_fill_password_value| is set to false, it always returns
+ // ENCRYPTION_RESULT_SUCCESS.
EncryptionResult InitPasswordFormFromStatement(
const sql::Statement& s,
+ bool decrypt_and_fill_password_value,
int* primary_key,
autofill::PasswordForm* form) const WARN_UNUSED_RESULT;
@@ -287,22 +290,23 @@ class LoginDatabase : public syncer::SyncMetadataStore {
// Reads all the stored sync entities metadata in a MetadataBatch. Returns
// nullptr in case of failure.
- std::unique_ptr<syncer::MetadataBatch> GetAllSyncEntityMetadataForTesting();
+ std::unique_ptr<syncer::MetadataBatch> GetAllSyncEntityMetadata();
// Reads the stored ModelTypeState. Returns nullptr in case of failure.
- std::unique_ptr<sync_pb::ModelTypeState> GetModelTypeStateForTesting();
+ std::unique_ptr<sync_pb::ModelTypeState> GetModelTypeState();
- // Overwrites |forms| with credentials retrieved from |statement|. If
- // |matched_form| is not null, filters out all results but those PSL-matching
+ // Overwrites |key_to_form_map| with credentials retrieved from |statement|.
+ // If |matched_form| is not null, filters out all results but those
+ // PSL-matching
// |*matched_form| or federated credentials for it. If feature for recovering
// passwords is enabled, it removes all passwords that couldn't be decrypted
// when encryption was available from the database. On success returns true.
// |key_to_form_map| must not be null and will be used to return the results.
// The key of the map is the DB primary key.
- bool StatementToForms(sql::Statement* statement,
- const PasswordStore::FormDigest* matched_form,
- PrimaryKeyToFormMap* key_to_form_map)
- WARN_UNUSED_RESULT;
+ FormRetrievalResult StatementToForms(
+ sql::Statement* statement,
+ const PasswordStore::FormDigest* matched_form,
+ PrimaryKeyToFormMap* key_to_form_map) WARN_UNUSED_RESULT;
// Initializes all the *_statement_ data members with appropriate SQL
// fragments based on |builder|.
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 762df3e474c..93f83e81684 100644
--- a/chromium/components/password_manager/core/browser/login_database_unittest.cc
+++ b/chromium/components/password_manager/core/browser/login_database_unittest.cc
@@ -19,6 +19,7 @@
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.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"
#include "components/autofill/core/common/password_form.h"
@@ -276,7 +277,7 @@ TEST_F(LoginDatabaseTest, Logins) {
EXPECT_TRUE(db().GetAutofillableLogins(&result));
EXPECT_EQ(0U, result.size());
- EXPECT_TRUE(db().GetAllLogins(&key_to_form_map));
+ EXPECT_EQ(db().GetAllLogins(&key_to_form_map), FormRetrievalResult::kSuccess);
EXPECT_EQ(0U, key_to_form_map.size());
// Example password form.
@@ -293,7 +294,7 @@ TEST_F(LoginDatabaseTest, Logins) {
EXPECT_EQ(form, *result[0]);
result.clear();
- EXPECT_TRUE(db().GetAllLogins(&key_to_form_map));
+ EXPECT_EQ(db().GetAllLogins(&key_to_form_map), FormRetrievalResult::kSuccess);
EXPECT_EQ(1U, key_to_form_map.size());
EXPECT_EQ(form, *key_to_form_map[1]);
key_to_form_map.clear();
@@ -426,6 +427,9 @@ TEST_F(LoginDatabaseTest, RemoveLoginsByPrimaryKey) {
EXPECT_EQ(form, *result[0]);
result.clear();
+ // RemoveLoginByPrimaryKey() doesn't decrypt or fill the password value.
+ form.password_value = ASCIIToUTF16("");
+
EXPECT_TRUE(db().RemoveLoginByPrimaryKey(primary_key, &change_list));
EXPECT_EQ(RemoveChangeForForm(form), change_list);
EXPECT_TRUE(db().GetAutofillableLogins(&result));
@@ -1874,7 +1878,7 @@ TEST_F(LoginDatabaseTest, PasswordReuseMetrics) {
TEST_F(LoginDatabaseTest, NoMetadata) {
std::unique_ptr<syncer::MetadataBatch> metadata_batch =
- db().GetAllSyncMetadataForTesting();
+ db().GetAllSyncMetadata();
ASSERT_THAT(metadata_batch, testing::NotNull());
EXPECT_EQ(0u, metadata_batch->TakeAllMetadata().size());
EXPECT_EQ(sync_pb::ModelTypeState().SerializeAsString(),
@@ -1901,7 +1905,7 @@ TEST_F(LoginDatabaseTest, GetAllSyncMetadata) {
db().UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey2, metadata));
std::unique_ptr<syncer::MetadataBatch> metadata_batch =
- db().GetAllSyncMetadataForTesting();
+ db().GetAllSyncMetadata();
ASSERT_THAT(metadata_batch, testing::NotNull());
EXPECT_TRUE(metadata_batch->GetModelTypeState().initial_sync_done());
@@ -1917,7 +1921,7 @@ TEST_F(LoginDatabaseTest, GetAllSyncMetadata) {
model_type_state.set_initial_sync_done(false);
EXPECT_TRUE(db().UpdateModelTypeState(syncer::PASSWORDS, model_type_state));
- metadata_batch = db().GetAllSyncMetadataForTesting();
+ metadata_batch = db().GetAllSyncMetadata();
ASSERT_THAT(metadata_batch, testing::NotNull());
EXPECT_FALSE(metadata_batch->GetModelTypeState().initial_sync_done());
}
@@ -1939,7 +1943,7 @@ TEST_F(LoginDatabaseTest, WriteThenDeleteSyncMetadata) {
EXPECT_TRUE(db().ClearSyncMetadata(syncer::PASSWORDS, kStorageKey));
std::unique_ptr<syncer::MetadataBatch> metadata_batch =
- db().GetAllSyncMetadataForTesting();
+ db().GetAllSyncMetadata();
ASSERT_THAT(metadata_batch, testing::NotNull());
// It shouldn't be there any more.
@@ -1949,7 +1953,7 @@ TEST_F(LoginDatabaseTest, WriteThenDeleteSyncMetadata) {
// Now delete the model type state.
EXPECT_TRUE(db().ClearModelTypeState(syncer::PASSWORDS));
- metadata_batch = db().GetAllSyncMetadataForTesting();
+ metadata_batch = db().GetAllSyncMetadata();
ASSERT_THAT(metadata_batch, testing::NotNull());
EXPECT_EQ(sync_pb::ModelTypeState().SerializeAsString(),
@@ -2192,15 +2196,15 @@ TEST_P(LoginDatabaseMigrationTestBroken, Broken) {
MigrationToVCurrent(base::StringPrintf("login_db_v%d_broken.sql", version()));
}
-INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
- LoginDatabaseMigrationTest,
- testing::Range(1, kCurrentVersionNumber + 1));
-INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
- LoginDatabaseMigrationTestV9,
- testing::Values(9));
-INSTANTIATE_TEST_CASE_P(MigrationToVCurrent,
- LoginDatabaseMigrationTestBroken,
- testing::Range(1, 4));
+INSTANTIATE_TEST_SUITE_P(MigrationToVCurrent,
+ LoginDatabaseMigrationTest,
+ testing::Range(1, kCurrentVersionNumber + 1));
+INSTANTIATE_TEST_SUITE_P(MigrationToVCurrent,
+ LoginDatabaseMigrationTestV9,
+ testing::Values(9));
+INSTANTIATE_TEST_SUITE_P(MigrationToVCurrent,
+ LoginDatabaseMigrationTestBroken,
+ testing::Range(1, 4));
class LoginDatabaseUndecryptableLoginsTest : public testing::Test {
protected:
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 34378066272..9c116d6849d 100644
--- a/chromium/components/password_manager/core/browser/mock_password_store.h
+++ b/chromium/components/password_manager/core/browser/mock_password_store.h
@@ -90,9 +90,9 @@ class MockPasswordStore : public PasswordStore {
#endif
MOCK_METHOD0(BeginTransaction, bool());
MOCK_METHOD0(CommitTransaction, bool());
- MOCK_METHOD1(ReadAllLogins, bool(PrimaryKeyToFormMap*));
+ MOCK_METHOD1(ReadAllLogins, FormRetrievalResult(PrimaryKeyToFormMap*));
MOCK_METHOD1(RemoveLoginByPrimaryKeySync, PasswordStoreChangeList(int));
- MOCK_METHOD0(GetMetadataStore, syncer::SyncMetadataStore*());
+ MOCK_METHOD0(GetMetadataStore, PasswordStoreSync::MetadataStore*());
PasswordStoreSync* GetSyncInterface() { return this; }
diff --git a/chromium/components/password_manager/core/browser/new_password_form_manager.cc b/chromium/components/password_manager/core/browser/new_password_form_manager.cc
index 8d4fb9e2ee9..dde59b3d302 100644
--- a/chromium/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/chromium/components/password_manager/core/browser/new_password_form_manager.cc
@@ -4,6 +4,7 @@
#include "components/password_manager/core/browser/new_password_form_manager.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
@@ -613,6 +614,11 @@ bool NewPasswordFormManager::ProvisionallySave(
void NewPasswordFormManager::ProcessServerPredictions(
const std::map<FormSignature, FormPredictions>& predictions) {
+ if (parser_.predictions()) {
+ // This method might be called multiple times. No need to process
+ // predictions again.
+ return;
+ }
FormSignature observed_form_signature =
CalculateFormSignature(observed_form_);
auto it = predictions.find(observed_form_signature);
diff --git a/chromium/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/chromium/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index f12d540d1cb..a77139b9602 100644
--- a/chromium/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -338,6 +338,7 @@ class NewPasswordFormManagerTest : public testing::Test {
MockPasswordManagerClient client_;
MockPasswordManagerDriver driver_;
scoped_refptr<TestMockTimeTaskRunner> task_runner_;
+
// Define |fetcher_| before |form_manager_|, because the former needs to
// outlive the latter.
std::unique_ptr<FakeFormFetcher> fetcher_;
@@ -562,6 +563,11 @@ TEST_F(NewPasswordFormManagerTest, ServerPredictionsWithinDelay) {
// Expect filling without delay on receiving server predictions.
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(1);
form_manager_->ProcessServerPredictions(predictions);
+ Mock::VerifyAndClearExpectations(&driver_);
+
+ // Expect no filling on receving predictions again.
+ EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
+ form_manager_->ProcessServerPredictions(predictions);
}
// Tests that NewPasswordFormManager fills after some delay even without
diff --git a/chromium/components/password_manager/core/browser/password_autofill_manager.cc b/chromium/components/password_manager/core/browser/password_autofill_manager.cc
index fffc97a4f59..a677a974145 100644
--- a/chromium/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/chromium/components/password_manager/core/browser/password_autofill_manager.cc
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
@@ -115,7 +116,7 @@ void AppendSuggestionIfMatching(
: autofill::Suggestion::SUBSTRING_MATCH;
suggestion.custom_icon = custom_icon;
// The UI code will pick up an icon from the resources based on the string.
- suggestion.icon = base::ASCIIToUTF16("globeIcon");
+ suggestion.icon = "globeIcon";
suggestions->push_back(suggestion);
}
}
diff --git a/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc
index 0cad85ab99f..37fafdca45a 100644
--- a/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -5,6 +5,7 @@
#include "components/password_manager/core/browser/password_autofill_manager.h"
#include <memory>
+#include <string>
#include "base/command_line.h"
#include "base/compiler_specific.h"
@@ -12,6 +13,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/metrics/user_action_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/popup_item_ids.h"
@@ -19,7 +21,7 @@
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/common/autofill_constants.h"
-#include "components/autofill/core/common/autofill_switches.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/favicon/core/test/mock_favicon_service.h"
@@ -133,13 +135,11 @@ std::vector<base::string16> GetSuggestionList(
return credentials;
}
-std::vector<base::string16> GetIconsList(std::vector<std::string> icons) {
- std::vector<base::string16> ret(icons.size());
- std::transform(icons.begin(), icons.end(), ret.begin(), &base::ASCIIToUTF16);
+std::vector<std::string> GetIconsList(std::vector<std::string> icons) {
// On older Android versions the item "Manage passwords" is absent.
if (!IsPreLollipopAndroid())
- ret.push_back(base::string16());
- return ret;
+ icons.push_back(std::string());
+ return icons;
}
} // namespace
@@ -430,9 +430,9 @@ TEST_F(PasswordAutofillManagerTest, FillSuggestionPasswordField) {
// Verify that typing "foo" into the username field will match usernames
// "foo.bar@example.com", "bar.foo@example.com" and "example@foo.com".
TEST_F(PasswordAutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- autofill::switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(
+ autofill::features::kAutofillTokenPrefixMatching);
std::unique_ptr<TestPasswordManagerClient> client(
new TestPasswordManagerClient);
@@ -466,9 +466,9 @@ TEST_F(PasswordAutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
// Verify that typing "oo" into the username field will not match any usernames
// "foo.bar@example.com", "bar.foo@example.com" or "example@foo.com".
TEST_F(PasswordAutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- autofill::switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(
+ autofill::features::kAutofillTokenPrefixMatching);
std::unique_ptr<TestPasswordManagerClient> client(
new TestPasswordManagerClient);
@@ -500,9 +500,9 @@ TEST_F(PasswordAutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
// tokens.
TEST_F(PasswordAutofillManagerTest,
MatchingContentsWithSuggestionTokenSeparator) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- autofill::switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(
+ autofill::features::kAutofillTokenPrefixMatching);
std::unique_ptr<TestPasswordManagerClient> client(
new TestPasswordManagerClient);
@@ -539,9 +539,9 @@ TEST_F(PasswordAutofillManagerTest,
// i.e. prefix matched followed by substring matched.
TEST_F(PasswordAutofillManagerTest,
DisplaySuggestionsWithPrefixesPrecedeSubstringMatched) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- autofill::switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(
+ autofill::features::kAutofillTokenPrefixMatching);
std::unique_ptr<TestPasswordManagerClient> client(
new TestPasswordManagerClient);
diff --git a/chromium/components/password_manager/core/browser/password_manager.cc b/chromium/components/password_manager/core/browser/password_manager.cc
index 983d9e6167c..9cf66f8796a 100644
--- a/chromium/components/password_manager/core/browser/password_manager.cc
+++ b/chromium/components/password_manager/core/browser/password_manager.cc
@@ -479,7 +479,8 @@ void PasswordManager::ProvisionallySavePassword(
return;
}
- bool should_block = ShouldBlockPasswordForSameOriginButDifferentScheme(form);
+ bool should_block =
+ ShouldBlockPasswordForSameOriginButDifferentScheme(form.origin);
metrics_util::LogShouldBlockPasswordForSameOriginButDifferentScheme(
should_block);
if (should_block) {
@@ -670,7 +671,8 @@ void PasswordManager::ShowManualFallbackForSaving(
const PasswordForm& password_form) {
if (!client_->GetPasswordStore()->IsAbleToSavePasswords() ||
!client_->IsSavingAndFillingEnabled(password_form.origin) ||
- ShouldBlockPasswordForSameOriginButDifferentScheme(password_form) ||
+ ShouldBlockPasswordForSameOriginButDifferentScheme(
+ password_form.origin) ||
!client_->GetStoreResultFilter()->ShouldSave(password_form))
return;
@@ -900,8 +902,17 @@ NewPasswordFormManager* PasswordManager::ProvisionallySaveForm(
// PasswordToSave in NewPasswordFormManager DCHECKs that the password is never
// empty.
- // TODO(https://crbug.com/831123): Add the
- // ShouldBlockPasswordForSameOriginButDifferentScheme check.
+ const GURL& origin = submitted_form.origin;
+ bool should_block =
+ ShouldBlockPasswordForSameOriginButDifferentScheme(origin);
+ metrics_util::LogShouldBlockPasswordForSameOriginButDifferentScheme(
+ should_block);
+ if (should_block) {
+ RecordProvisionalSaveFailure(
+ PasswordManagerMetricsRecorder::SAVING_ON_HTTP_AFTER_HTTPS, origin,
+ logger.get());
+ return nullptr;
+ }
NewPasswordFormManager* matched_manager =
GetMatchedManager(driver, submitted_form);
@@ -930,6 +941,11 @@ NewPasswordFormManager* PasswordManager::ProvisionallySaveForm(
manager->set_not_submitted();
}
+ // Cache the user-visible URL (i.e., the one seen in the omnibox). Once the
+ // post-submit navigation concludes, we compare the landing URL against the
+ // cached and report the difference through UMA.
+ main_frame_url_ = client_->GetMainFrameURL();
+
return matched_manager;
}
@@ -958,6 +974,31 @@ void PasswordManager::NotifyStorePasswordCalled() {
DropFormManagers();
}
+#if defined(OS_IOS)
+void PasswordManager::PresaveGeneratedPassword(
+ PasswordManagerDriver* driver,
+ const FormData& form,
+ const base::string16& generated_password,
+ const base::string16& generation_element,
+ bool is_manually_triggered) {
+ // TODO(https://crbug.com/886583): Implement it.
+}
+
+void PasswordManager::UpdateGeneratedPasswordOnUserInput(
+ PasswordManagerDriver* driver,
+ const base::string16& form_identifier,
+ const base::string16& field_identifier,
+ const base::string16& field_value) {
+ // TODO(https://crbug.com/886583): Implement it.
+}
+
+void PasswordManager::OnPasswordNoLongerGenerated(
+ PasswordManagerDriver* driver) {
+ // TODO(https://crbug.com/886583): Implement it.
+}
+
+#endif
+
void PasswordManager::ProvisionallySaveManager(
const PasswordForm& form,
PasswordFormManager* matched_manager,
@@ -1006,12 +1047,10 @@ bool PasswordManager::IsAutomaticSavePromptAvailable() {
}
bool PasswordManager::ShouldBlockPasswordForSameOriginButDifferentScheme(
- const PasswordForm& form) const {
+ const GURL& origin) const {
const GURL& old_origin = main_frame_url_.GetOrigin();
- const GURL& new_origin = form.origin.GetOrigin();
- return old_origin.host_piece() == new_origin.host_piece() &&
- old_origin.SchemeIsCryptographic() &&
- !new_origin.SchemeIsCryptographic();
+ return old_origin.host_piece() == origin.host_piece() &&
+ old_origin.SchemeIsCryptographic() && !origin.SchemeIsCryptographic();
}
void PasswordManager::OnPasswordFormsRendered(
@@ -1159,10 +1198,10 @@ void PasswordManager::OnLoginSuccessful() {
}
if (ShouldPromptUserToSavePassword(*submitted_manager)) {
- bool empty_password =
+ bool empty_username =
submitted_manager->GetPendingCredentials().username_value.empty();
UMA_HISTOGRAM_BOOLEAN("PasswordManager.EmptyUsernames.OfferedToSave",
- empty_password);
+ empty_username);
if (logger)
logger->LogMessage(Logger::STRING_DECISION_ASK);
bool update_password = submitted_manager->IsPasswordUpdate();
@@ -1181,13 +1220,11 @@ void PasswordManager::OnLoginSuccessful() {
submitted_manager->GetPendingCredentials());
}
- if (submitted_manager->HasGeneratedPassword()) {
+ if (submitted_manager->HasGeneratedPassword())
client_->AutomaticPasswordSave(MoveOwnedSubmittedManager());
- } else {
- provisional_save_manager_.reset();
- owned_submitted_form_manager_.reset();
- }
}
+ provisional_save_manager_.reset();
+ owned_submitted_form_manager_.reset();
}
void PasswordManager::MaybeSavePasswordHash(
diff --git a/chromium/components/password_manager/core/browser/password_manager.h b/chromium/components/password_manager/core/browser/password_manager.h
index e6a68abc704..be1f968ace9 100644
--- a/chromium/components/password_manager/core/browser/password_manager.h
+++ b/chromium/components/password_manager/core/browser/password_manager.h
@@ -191,6 +191,36 @@ class PasswordManager : public LoginModel, public FormSubmissionObserver {
// Notifies that Credential Management API function store() is called.
void NotifyStorePasswordCalled();
+#if defined(OS_IOS)
+ // TODO(https://crbug.com/866444): Use these methods instead olds ones when
+ // the old parser is gone.
+
+ // Presaves the form with |generated_password|. This function is called once
+ // when the user accepts the generated password. The password was generated in
+ // the field with identifier |generation_element|. |driver| corresponds to the
+ // |form| parent frame.
+ void PresaveGeneratedPassword(PasswordManagerDriver* driver,
+ const autofill::FormData& form,
+ const base::string16& generated_password,
+ const base::string16& generation_element,
+ bool is_manually_triggered);
+
+ // Updates the presaved credential with the generated password when the user
+ // types in field with |field_identifier|, which is in form with
+ // |form_identifier| and the field value is |field_value|. |driver|
+ // corresponds to the form parent frame.
+ void UpdateGeneratedPasswordOnUserInput(
+ PasswordManagerDriver* driver,
+ const base::string16& form_identifier,
+ const base::string16& field_identifier,
+ const base::string16& field_value);
+
+ // Stops treating a password as generated. |driver| corresponds to the
+ // form parent frame.
+ void OnPasswordNoLongerGenerated(PasswordManagerDriver* driver);
+
+#endif
+
private:
FRIEND_TEST_ALL_PREFIXES(
PasswordManagerTest,
@@ -208,11 +238,11 @@ class PasswordManager : public LoginModel, public FormSubmissionObserver {
bool IsAutomaticSavePromptAvailable();
// Returns true if there already exists a provisionally saved password form
- // from the same origin as |form|, but with a different and secure scheme.
+ // from the origin |origin|, but with a different and secure scheme.
// This prevents a potential attack where users can be tricked into saving
// unwanted credentials, see http://crbug.com/571580 for details.
bool ShouldBlockPasswordForSameOriginButDifferentScheme(
- const autofill::PasswordForm& form) const;
+ const GURL& origin) const;
// Called when the login was deemed successful. It handles the special case
// when the provisionally saved password is a sync credential, and otherwise
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 bc1afc3ed62..66061fe601b 100644
--- a/chromium/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_unittest.cc
@@ -1252,14 +1252,13 @@ TEST_F(PasswordManagerTest,
false},
};
- PasswordForm form = MakeSimpleForm();
for (const auto& test_case : kTestData) {
SCOPED_TRACE(testing::Message("#test_case = ") << (&test_case - kTestData));
manager()->main_frame_url_ = GURL(test_case.old_origin);
- form.origin = GURL(test_case.new_origin);
+ GURL origin = GURL(test_case.new_origin);
EXPECT_EQ(
test_case.result,
- manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(origin));
}
}
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 8b6725ee148..48ebe366ada 100644
--- a/chromium/components/password_manager/core/browser/password_manager_util.cc
+++ b/chromium/components/password_manager/core/browser/password_manager_util.cc
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/stl_util.h"
#include "base/time/time.h"
diff --git a/chromium/components/password_manager/core/browser/password_store.cc b/chromium/components/password_manager/core/browser/password_store.cc
index f7bcf270f70..2cc35f36c1b 100644
--- a/chromium/components/password_manager/core/browser/password_store.cc
+++ b/chromium/components/password_manager/core/browser/password_store.cc
@@ -10,6 +10,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/debug/dump_without_crashing.h"
#include "base/location.h"
#include "base/macros.h"
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 c518a89ff00..961f67b5ecd 100644
--- a/chromium/components/password_manager/core/browser/password_store_default.cc
+++ b/chromium/components/password_manager/core/browser/password_store_default.cc
@@ -8,6 +8,7 @@
#include <set>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "components/password_manager/core/browser/password_store_change.h"
@@ -238,9 +239,12 @@ bool PasswordStoreDefault::CommitTransaction() {
return false;
}
-bool PasswordStoreDefault::ReadAllLogins(PrimaryKeyToFormMap* key_to_form_map) {
+FormRetrievalResult PasswordStoreDefault::ReadAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) {
DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
- return login_db_ && login_db_->GetAllLogins(key_to_form_map);
+ if (!login_db_)
+ return FormRetrievalResult::kDbError;
+ return login_db_->GetAllLogins(key_to_form_map);
}
PasswordStoreChangeList PasswordStoreDefault::RemoveLoginByPrimaryKeySync(
@@ -253,7 +257,7 @@ PasswordStoreChangeList PasswordStoreDefault::RemoveLoginByPrimaryKeySync(
return PasswordStoreChangeList();
}
-syncer::SyncMetadataStore* PasswordStoreDefault::GetMetadataStore() {
+PasswordStoreSync::MetadataStore* PasswordStoreDefault::GetMetadataStore() {
return login_db_.get();
}
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 ecc4e98a1c6..e3d7a920813 100644
--- a/chromium/components/password_manager/core/browser/password_store_default.h
+++ b/chromium/components/password_manager/core/browser/password_store_default.h
@@ -87,9 +87,10 @@ class PasswordStoreDefault : public PasswordStore {
// Implements PasswordStoreSync interface.
bool BeginTransaction() override;
bool CommitTransaction() override;
- bool ReadAllLogins(PrimaryKeyToFormMap* key_to_form_map) override;
+ FormRetrievalResult ReadAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) override;
PasswordStoreChangeList RemoveLoginByPrimaryKeySync(int primary_key) override;
- syncer::SyncMetadataStore* GetMetadataStore() override;
+ PasswordStoreSync::MetadataStore* GetMetadataStore() override;
inline bool DeleteAndRecreateDatabaseFile() {
return login_db_->DeleteAndRecreateDatabaseFile();
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 28e69ac917f..7323fe8d4df 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
@@ -158,9 +158,9 @@ base::FilePath PasswordStoreDefaultTestDelegate::test_login_db_file_path()
} // anonymous namespace
-INSTANTIATE_TYPED_TEST_CASE_P(Default,
- PasswordStoreOriginTest,
- PasswordStoreDefaultTestDelegate);
+INSTANTIATE_TYPED_TEST_SUITE_P(Default,
+ PasswordStoreOriginTest,
+ PasswordStoreDefaultTestDelegate);
TEST(PasswordStoreDefaultTest, NonASCIIData) {
PasswordStoreDefaultTestDelegate delegate;
diff --git a/chromium/components/password_manager/core/browser/password_store_origin_unittest.h b/chromium/components/password_manager/core/browser/password_store_origin_unittest.h
index f83d6b3fa30..80ea3ae345c 100644
--- a/chromium/components/password_manager/core/browser/password_store_origin_unittest.h
+++ b/chromium/components/password_manager/core/browser/password_store_origin_unittest.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "base/time/time.h"
@@ -58,7 +59,7 @@ class PasswordStoreOriginTest : public testing::Test {
T delegate_;
};
-TYPED_TEST_CASE_P(PasswordStoreOriginTest);
+TYPED_TEST_SUITE_P(PasswordStoreOriginTest);
TYPED_TEST_P(PasswordStoreOriginTest,
RemoveLoginsByURLAndTimeImpl_AllFittingOriginAndTime) {
@@ -161,7 +162,7 @@ TYPED_TEST_P(PasswordStoreOriginTest,
this->delegate_.store()->RemoveObserver(&observer);
}
-REGISTER_TYPED_TEST_CASE_P(
+REGISTER_TYPED_TEST_SUITE_P(
PasswordStoreOriginTest,
RemoveLoginsByURLAndTimeImpl_AllFittingOriginAndTime,
RemoveLoginsByURLAndTimeImpl_SomeFittingOriginAndTime,
diff --git a/chromium/components/password_manager/core/browser/password_store_signin_notifier.cc b/chromium/components/password_manager/core/browser/password_store_signin_notifier.cc
index 2b05ae50315..217c067056a 100644
--- a/chromium/components/password_manager/core/browser/password_store_signin_notifier.cc
+++ b/chromium/components/password_manager/core/browser/password_store_signin_notifier.cc
@@ -13,17 +13,6 @@ PasswordStoreSigninNotifier::PasswordStoreSigninNotifier() {}
PasswordStoreSigninNotifier::~PasswordStoreSigninNotifier() {}
-void PasswordStoreSigninNotifier::NotifySignin(const std::string& username,
- const std::string& password) {
- // After the full roll out of DICE, |password| may be empty
- // if user clicks "Sync as ..." button in the sign-in promotion bubble.
- if (store_ && !password.empty()) {
- store_->SaveGaiaPasswordHash(
- username, base::UTF8ToUTF16(password),
- metrics_util::SyncPasswordHashChange::SAVED_ON_CHROME_SIGNIN);
- }
-}
-
void PasswordStoreSigninNotifier::NotifySignedOut(const std::string& username,
bool primary_account) {
if (!store_)
diff --git a/chromium/components/password_manager/core/browser/password_store_signin_notifier.h b/chromium/components/password_manager/core/browser/password_store_signin_notifier.h
index ce3a8593276..9c237c54fcc 100644
--- a/chromium/components/password_manager/core/browser/password_store_signin_notifier.h
+++ b/chromium/components/password_manager/core/browser/password_store_signin_notifier.h
@@ -30,9 +30,6 @@ class PasswordStoreSigninNotifier {
protected:
void set_store(PasswordStore* store) { store_ = store; }
- // Passes sign-in to |store_|.
- void NotifySignin(const std::string& username, const std::string& password);
-
// Passes signed-out to |store_|.
void NotifySignedOut(const std::string& username, bool primary_account);
diff --git a/chromium/components/password_manager/core/browser/password_store_sync.h b/chromium/components/password_manager/core/browser/password_store_sync.h
index d570401bab5..3b698f235c6 100644
--- a/chromium/components/password_manager/core/browser/password_store_sync.h
+++ b/chromium/components/password_manager/core/browser/password_store_sync.h
@@ -12,13 +12,14 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "components/password_manager/core/browser/password_store_change.h"
+#include "components/sync/model/sync_metadata_store.h"
namespace autofill {
struct PasswordForm;
}
namespace syncer {
-class SyncMetadataStore;
+class MetadataBatch;
}
namespace password_manager {
@@ -35,12 +36,30 @@ enum class DatabaseCleanupResult {
kEncryptionUnavailable,
};
+// Result values for retrieving form from the store.
+enum class FormRetrievalResult {
+ // Success.
+ kSuccess,
+ // Database error.
+ kDbError,
+ // A service-level failure (e.g., on a platform using a keyring, the keyring
+ // is temporarily unavailable).
+ kEncrytionServiceFailure,
+};
+
// PasswordStore interface for PasswordSyncableService. It provides access to
// synchronous methods of PasswordStore which shouldn't be accessible to other
// classes. These methods are to be called on the PasswordStore background
// thread only.
class PasswordStoreSync {
public:
+ class MetadataStore : public syncer::SyncMetadataStore {
+ public:
+ // Read all the stored metadata for passwords and fill |metadata_batch|
+ // with it.
+ virtual std::unique_ptr<syncer::MetadataBatch> GetAllSyncMetadata() = 0;
+ };
+
PasswordStoreSync();
// TODO(http://crbug.com/925307) Move the following 2 APIs to PasswordStore
@@ -59,8 +78,8 @@ class PasswordStoreSync {
// Overwrites |key_to_form_map| with a map from the DB primary key to the
// corresponding form for all stored credentials. Returns true on success.
- virtual bool ReadAllLogins(PrimaryKeyToFormMap* key_to_form_map)
- WARN_UNUSED_RESULT = 0;
+ virtual FormRetrievalResult ReadAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) WARN_UNUSED_RESULT = 0;
// Deletes logins that cannot be decrypted.
virtual DatabaseCleanupResult DeleteUndecryptableLogins() = 0;
@@ -95,7 +114,7 @@ class PasswordStoreSync {
// Returns a SyncMetadataStore that sync machinery would use to persist the
// sync metadata.
- virtual syncer::SyncMetadataStore* GetMetadataStore() = 0;
+ virtual MetadataStore* GetMetadataStore() = 0;
protected:
virtual ~PasswordStoreSync();
diff --git a/chromium/components/password_manager/core/browser/site_affiliation/asset_link_data.cc b/chromium/components/password_manager/core/browser/site_affiliation/asset_link_data.cc
index e20be71968e..345de85e362 100644
--- a/chromium/components/password_manager/core/browser/site_affiliation/asset_link_data.cc
+++ b/chromium/components/password_manager/core/browser/site_affiliation/asset_link_data.cc
@@ -53,7 +53,7 @@ AssetLinkData::~AssetLinkData() = default;
AssetLinkData& AssetLinkData::operator=(AssetLinkData&& other) = default;
bool AssetLinkData::Parse(const std::string& data) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(data);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(data);
if (!value || !value->is_list())
return false;
const base::Value::ListStorage& list_storage = value->GetList();
diff --git a/chromium/components/password_manager/core/browser/stub_credentials_filter.cc b/chromium/components/password_manager/core/browser/stub_credentials_filter.cc
index 7d47155e3a2..e00176f5e05 100644
--- a/chromium/components/password_manager/core/browser/stub_credentials_filter.cc
+++ b/chromium/components/password_manager/core/browser/stub_credentials_filter.cc
@@ -10,13 +10,6 @@ StubCredentialsFilter::StubCredentialsFilter() = default;
StubCredentialsFilter::~StubCredentialsFilter() = default;
-std::vector<std::unique_ptr<autofill::PasswordForm>>
-StubCredentialsFilter::FilterResults(
- std::vector<std::unique_ptr<autofill::PasswordForm>> results) const {
- FilterResultsPtr(&results);
- return results;
-}
-
bool StubCredentialsFilter::ShouldSave(
const autofill::PasswordForm& form) const {
return true;
@@ -40,7 +33,4 @@ bool StubCredentialsFilter::IsSyncAccountEmail(
return false;
}
-void StubCredentialsFilter::FilterResultsPtr(
- std::vector<std::unique_ptr<autofill::PasswordForm>>* results) const {}
-
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/stub_credentials_filter.h b/chromium/components/password_manager/core/browser/stub_credentials_filter.h
index f56d01f4302..4a6d98e3acd 100644
--- a/chromium/components/password_manager/core/browser/stub_credentials_filter.h
+++ b/chromium/components/password_manager/core/browser/stub_credentials_filter.h
@@ -19,9 +19,6 @@ class StubCredentialsFilter : public CredentialsFilter {
~StubCredentialsFilter() override;
// CredentialsFilter
- std::vector<std::unique_ptr<autofill::PasswordForm>> FilterResults(
- std::vector<std::unique_ptr<autofill::PasswordForm>> results)
- const override;
bool ShouldSave(const autofill::PasswordForm& form) const override;
bool ShouldSaveGaiaPasswordHash(
const autofill::PasswordForm& form) const override;
@@ -31,12 +28,6 @@ class StubCredentialsFilter : public CredentialsFilter {
const PasswordFormManagerInterface& form_manager) const override;
bool IsSyncAccountEmail(const std::string& username) const override;
- // A version of FilterResult without moveable arguments, which cannot be
- // mocked in GMock. StubCredentialsFilter::FilterResults(arg) calls
- // FilterResultsPtr(&arg).
- virtual void FilterResultsPtr(
- std::vector<std::unique_ptr<autofill::PasswordForm>>* results) const;
-
private:
DISALLOW_COPY_AND_ASSIGN(StubCredentialsFilter);
};
diff --git a/chromium/components/password_manager/core/browser/sync/password_model_type_controller.cc b/chromium/components/password_manager/core/browser/sync/password_model_type_controller.cc
index 71de60d8b71..db4dab36c56 100644
--- a/chromium/components/password_manager/core/browser/sync/password_model_type_controller.cc
+++ b/chromium/components/password_manager/core/browser/sync/password_model_type_controller.cc
@@ -4,6 +4,8 @@
#include "components/password_manager/core/browser/sync/password_model_type_controller.h"
+#include <utility>
+
#include "components/sync/base/model_type.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
@@ -14,10 +16,10 @@ namespace password_manager {
PasswordModelTypeController::PasswordModelTypeController(
std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate_on_disk,
syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client)
+ const base::RepeatingClosure& state_changed_callback)
: ModelTypeController(syncer::PASSWORDS, std::move(delegate_on_disk)),
sync_service_(sync_service),
- sync_client_(sync_client) {}
+ state_changed_callback_(state_changed_callback) {}
PasswordModelTypeController::~PasswordModelTypeController() = default;
@@ -27,7 +29,7 @@ void PasswordModelTypeController::LoadModels(
DCHECK(CalledOnValidThread());
sync_service_->AddObserver(this);
ModelTypeController::LoadModels(configure_context, model_load_callback);
- sync_client_->GetPasswordStateChangedCallback().Run();
+ state_changed_callback_.Run();
}
void PasswordModelTypeController::Stop(syncer::ShutdownReason shutdown_reason,
@@ -35,12 +37,12 @@ void PasswordModelTypeController::Stop(syncer::ShutdownReason shutdown_reason,
DCHECK(CalledOnValidThread());
sync_service_->RemoveObserver(this);
ModelTypeController::Stop(shutdown_reason, std::move(callback));
- sync_client_->GetPasswordStateChangedCallback().Run();
+ state_changed_callback_.Run();
}
void PasswordModelTypeController::OnStateChanged(syncer::SyncService* sync) {
DCHECK(CalledOnValidThread());
- sync_client_->GetPasswordStateChangedCallback().Run();
+ state_changed_callback_.Run();
}
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/sync/password_model_type_controller.h b/chromium/components/password_manager/core/browser/sync/password_model_type_controller.h
index 3531bece301..2593dab2ae9 100644
--- a/chromium/components/password_manager/core/browser/sync/password_model_type_controller.h
+++ b/chromium/components/password_manager/core/browser/sync/password_model_type_controller.h
@@ -5,13 +5,15 @@
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_MODEL_TYPE_CONTROLLER_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_MODEL_TYPE_CONTROLLER_H_
+#include <memory>
+
+#include "base/callback.h"
#include "base/macros.h"
#include "components/sync/driver/model_type_controller.h"
#include "components/sync/driver/sync_service_observer.h"
namespace syncer {
class ModelTypeControllerDelegate;
-class SyncClient;
class SyncService;
} // namespace syncer
@@ -24,7 +26,7 @@ class PasswordModelTypeController : public syncer::ModelTypeController,
PasswordModelTypeController(
std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate_on_disk,
syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client);
+ const base::RepeatingClosure& state_changed_callback);
~PasswordModelTypeController() override;
// DataTypeController overrides.
@@ -38,7 +40,7 @@ class PasswordModelTypeController : public syncer::ModelTypeController,
private:
syncer::SyncService* const sync_service_;
- syncer::SyncClient* const sync_client_;
+ const base::RepeatingClosure state_changed_callback_;
DISALLOW_COPY_AND_ASSIGN(PasswordModelTypeController);
};
diff --git a/chromium/components/password_manager/core/browser/sync/password_model_worker.cc b/chromium/components/password_manager/core/browser/sync/password_model_worker.cc
index 7acd62e4cbc..d69b0cd93f0 100644
--- a/chromium/components/password_manager/core/browser/sync/password_model_worker.cc
+++ b/chromium/components/password_manager/core/browser/sync/password_model_worker.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "components/password_manager/core/browser/password_store.h"
namespace browser_sync {
diff --git a/chromium/components/password_manager/core/browser/sync/password_sync_bridge.cc b/chromium/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 9faaed81680..8fc6902e26a 100644
--- a/chromium/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/chromium/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -4,13 +4,19 @@
#include "components/password_manager/core/browser/sync/password_sync_bridge.h"
+#include <unordered_set>
+
+#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/password_store_sync.h"
+#include "components/password_manager/core/common/password_manager_features.h"
+#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_type_change_processor.h"
+#include "components/sync/model/mutable_data_batch.h"
+#include "components/sync/model_impl/in_memory_metadata_change_list.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
#include "net/base/escape.h"
#include "url/gurl.h"
@@ -52,6 +58,43 @@ sync_pb::PasswordSpecifics SpecificsFromPassword(
return specifics;
}
+autofill::PasswordForm PasswordFromEntityChange(
+ const syncer::EntityChange& entity_change,
+ base::Time sync_time) {
+ DCHECK(entity_change.data().specifics.has_password());
+ const sync_pb::PasswordSpecificsData& password_data =
+ entity_change.data().specifics.password().client_only_encrypted_data();
+
+ autofill::PasswordForm password;
+ password.scheme =
+ static_cast<autofill::PasswordForm::Scheme>(password_data.scheme());
+ password.signon_realm = password_data.signon_realm();
+ password.origin = GURL(password_data.origin());
+ password.action = GURL(password_data.action());
+ password.username_element =
+ base::UTF8ToUTF16(password_data.username_element());
+ password.password_element =
+ base::UTF8ToUTF16(password_data.password_element());
+ password.username_value = base::UTF8ToUTF16(password_data.username_value());
+ password.password_value = base::UTF8ToUTF16(password_data.password_value());
+ password.preferred = password_data.preferred();
+ password.date_created = base::Time::FromDeltaSinceWindowsEpoch(
+ // Use FromDeltaSinceWindowsEpoch because create_time_us has
+ // always used the Windows epoch.
+ base::TimeDelta::FromMicroseconds(password_data.date_created()));
+ password.blacklisted_by_user = password_data.blacklisted();
+ password.type =
+ static_cast<autofill::PasswordForm::Type>(password_data.type());
+ password.times_used = password_data.times_used();
+ password.display_name = base::UTF8ToUTF16(password_data.display_name());
+ password.icon_url = GURL(password_data.avatar_url());
+ password.federation_origin =
+ url::Origin::Create(GURL(password_data.federation_url()));
+ password.date_synced = sync_time;
+
+ return password;
+}
+
std::unique_ptr<syncer::EntityData> CreateEntityData(
const autofill::PasswordForm& form) {
auto entity_data = std::make_unique<syncer::EntityData>();
@@ -60,6 +103,69 @@ std::unique_ptr<syncer::EntityData> CreateEntityData(
return entity_data;
}
+int ParsePrimaryKey(const std::string& storage_key) {
+ int primary_key = 0;
+ bool success = base::StringToInt(storage_key, &primary_key);
+ DCHECK(success)
+ << "Invalid storage key. Failed to convert the storage key to "
+ "an integer";
+ return primary_key;
+}
+
+// Returns true iff |password_specifics| and |password_form| are equal
+// memberwise.
+bool AreLocalAndRemotePasswordsEqual(
+ const sync_pb::PasswordSpecificsData& password_specifics,
+ const autofill::PasswordForm& password_form) {
+ return (password_form.scheme == password_specifics.scheme() &&
+ password_form.signon_realm == password_specifics.signon_realm() &&
+ password_form.origin.spec() == password_specifics.origin() &&
+ password_form.action.spec() == password_specifics.action() &&
+ base::UTF16ToUTF8(password_form.username_element) ==
+ password_specifics.username_element() &&
+ base::UTF16ToUTF8(password_form.password_element) ==
+ password_specifics.password_element() &&
+ base::UTF16ToUTF8(password_form.username_value) ==
+ password_specifics.username_value() &&
+ base::UTF16ToUTF8(password_form.password_value) ==
+ password_specifics.password_value() &&
+ password_form.preferred == password_specifics.preferred() &&
+ password_form.date_created ==
+ base::Time::FromDeltaSinceWindowsEpoch(
+ base::TimeDelta::FromMicroseconds(
+ password_specifics.date_created())) &&
+ password_form.blacklisted_by_user ==
+ password_specifics.blacklisted() &&
+ password_form.type == password_specifics.type() &&
+ password_form.times_used == password_specifics.times_used() &&
+ base::UTF16ToUTF8(password_form.display_name) ==
+ password_specifics.display_name() &&
+ password_form.icon_url.spec() == password_specifics.avatar_url() &&
+ url::Origin::Create(GURL(password_specifics.federation_url()))
+ .Serialize() == password_form.federation_origin.Serialize());
+}
+
+bool ShouldRecoverPasswordsDuringMerge() {
+ return base::FeatureList::IsEnabled(
+ features::kRecoverPasswordsForSyncUsers) &&
+ !base::FeatureList::IsEnabled(features::kDeleteCorruptedPasswords);
+}
+
+// A simple class for scoping a password store sync transaction. This does not
+// support rollback since the password store sync doesn't either.
+class ScopedStoreTransaction {
+ public:
+ explicit ScopedStoreTransaction(PasswordStoreSync* store) : store_(store) {
+ store_->BeginTransaction();
+ }
+ ~ScopedStoreTransaction() { store_->CommitTransaction(); }
+
+ private:
+ PasswordStoreSync* store_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedStoreTransaction);
+};
+
} // namespace
PasswordSyncBridge::PasswordSyncBridge(
@@ -68,6 +174,21 @@ PasswordSyncBridge::PasswordSyncBridge(
: ModelTypeSyncBridge(std::move(change_processor)),
password_store_sync_(password_store_sync) {
DCHECK(password_store_sync_);
+ // The metadata store could be null if the login database initialization
+ // fails.
+ if (!password_store_sync_->GetMetadataStore()) {
+ this->change_processor()->ReportError(
+ {FROM_HERE, "Password metadata store isn't available."});
+ return;
+ }
+ std::unique_ptr<syncer::MetadataBatch> batch =
+ password_store_sync_->GetMetadataStore()->GetAllSyncMetadata();
+ if (!batch) {
+ this->change_processor()->ReportError(
+ {FROM_HERE, "Failed reading passwords metadata from password store."});
+ return;
+ }
+ this->change_processor()->ModelReadyToSync(std::move(batch));
}
PasswordSyncBridge::~PasswordSyncBridge() = default;
@@ -86,8 +207,11 @@ void PasswordSyncBridge::ActOnPasswordStoreChanges(
return; // Sync processor not yet ready, don't sync.
}
- // TODO(mamir):ActOnPasswordStoreChanges() can be called from
- // ApplySyncChanges(). Do nothing in this case.
+ // ActOnPasswordStoreChanges() can be called from ApplySyncChanges(). Do
+ // nothing in this case.
+ if (is_processing_remote_sync_changes_) {
+ return;
+ }
syncer::SyncMetadataStoreChangeList metadata_change_list(
password_store_sync_->GetMetadataStore(), syncer::PASSWORDS);
@@ -109,38 +233,356 @@ void PasswordSyncBridge::ActOnPasswordStoreChanges(
}
}
-void PasswordSyncBridge::OnSyncStarting(
- const syncer::DataTypeActivationRequest& request) {
- NOTIMPLEMENTED();
-}
-
std::unique_ptr<syncer::MetadataChangeList>
PasswordSyncBridge::CreateMetadataChangeList() {
- NOTIMPLEMENTED();
- return nullptr;
+ return std::make_unique<syncer::InMemoryMetadataChangeList>();
}
base::Optional<syncer::ModelError> PasswordSyncBridge::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
- NOTIMPLEMENTED();
+ // This method merges the local and remote passwords based on their client
+ // tags. For a form |F|, there are three cases to handle:
+ // 1. |F| exists only in the local model --> |F| should be Put() in the change
+ // processor.
+ // 2. |F| exists only in the remote model --> |F| should be AddLoginSync() to
+ // the local password store.
+ // 3. |F| exists in both the local and the remote models --> both versions
+ // should be merged by accepting the most recently created one, and update
+ // local and remote models accordingly.
+
+ base::AutoReset<bool> processing_changes(&is_processing_remote_sync_changes_,
+ true);
+
+ // Read all local passwords.
+ PrimaryKeyToFormMap key_to_local_form_map;
+ FormRetrievalResult read_result =
+ password_store_sync_->ReadAllLogins(&key_to_local_form_map);
+
+ if (read_result == FormRetrievalResult::kDbError) {
+ return syncer::ModelError(FROM_HERE,
+ "Failed to load entries from password store.");
+ }
+ if (read_result == FormRetrievalResult::kEncrytionServiceFailure) {
+ if (!ShouldRecoverPasswordsDuringMerge()) {
+ return syncer::ModelError(FROM_HERE,
+ "Failed to load entries from password store. "
+ "Encryption service failure.");
+ }
+ base::Optional<syncer::ModelError> cleanup_result_error =
+ CleanupPasswordStore();
+ if (cleanup_result_error) {
+ return cleanup_result_error;
+ }
+ // Clean up done successfully, try to read again.
+ read_result = password_store_sync_->ReadAllLogins(&key_to_local_form_map);
+ if (read_result != FormRetrievalResult::kSuccess) {
+ return syncer::ModelError(
+ FROM_HERE,
+ "Failed to load entries from password store after cleanup.");
+ }
+ }
+ DCHECK_EQ(read_result, FormRetrievalResult::kSuccess);
+
+ // Collect the client tags of remote passwords and the corresponding
+ // EntityChange. Note that |entity_data| only contains client tag *hashes*.
+ std::map<std::string, const syncer::EntityChange*>
+ client_tag_to_remote_entity_change_map;
+ for (const syncer::EntityChange& entity_change : entity_data) {
+ client_tag_to_remote_entity_change_map[GetClientTag(entity_change.data())] =
+ &entity_change;
+ }
+
+ // This is used to keep track of all the changes applied to the password
+ // store to notify other observers of the password store.
+ PasswordStoreChangeList password_store_changes;
+ base::Optional<syncer::ModelError> error;
+ {
+ ScopedStoreTransaction transaction(password_store_sync_);
+ const base::Time time_now = base::Time::Now();
+ // For any local password that doesn't exist in the remote passwords, issue
+ // a change_processor()->Put(). For any local password that exists in the
+ // remote passwords, both should be merged by picking the most recently
+ // created version. Password comparison is done by comparing the client
+ // tags. In addition, collect the client tags of local passwords.
+ std::unordered_set<std::string> client_tags_of_local_passwords;
+ for (const auto& pair : key_to_local_form_map) {
+ const int primary_key = pair.first;
+ const autofill::PasswordForm& local_password_form = *pair.second;
+ std::unique_ptr<syncer::EntityData> local_form_entity_data =
+ CreateEntityData(local_password_form);
+ const std::string client_tag_of_local_password =
+ GetClientTag(*local_form_entity_data);
+ client_tags_of_local_passwords.insert(client_tag_of_local_password);
+
+ if (client_tag_to_remote_entity_change_map.count(
+ client_tag_of_local_password) == 0) {
+ // Local password doesn't exist in the remote model, Put() it in the
+ // processor.
+ change_processor()->Put(
+ /*storage_key=*/base::NumberToString(primary_key),
+ std::move(local_form_entity_data), metadata_change_list.get());
+ continue;
+ }
+
+ // Local password exists in the remote model as well. A merge is required.
+ const syncer::EntityChange& remote_entity_change =
+ *client_tag_to_remote_entity_change_map[client_tag_of_local_password];
+ const sync_pb::PasswordSpecificsData& remote_password_specifics =
+ remote_entity_change.data()
+ .specifics.password()
+ .client_only_encrypted_data();
+
+ // First, we need to inform the processor about the storage key anyway.
+ change_processor()->UpdateStorageKey(remote_entity_change.data(),
+ /*storage_key=*/
+ base::NumberToString(primary_key),
+ metadata_change_list.get());
+
+ if (AreLocalAndRemotePasswordsEqual(remote_password_specifics,
+ local_password_form)) {
+ // Passwords are identical, nothing else to do.
+ continue;
+ }
+
+ // Passwords aren't identical, pick the most recently created one.
+ if (base::Time::FromDeltaSinceWindowsEpoch(
+ base::TimeDelta::FromMicroseconds(
+ remote_password_specifics.date_created())) <
+ local_password_form.date_created) {
+ // The local password is more recent, update the processor.
+ change_processor()->Put(
+ /*storage_key=*/base::NumberToString(primary_key),
+ std::move(local_form_entity_data), metadata_change_list.get());
+ } else {
+ // The remote password is more recent, update the local model.
+ PasswordStoreChangeList changes =
+ password_store_sync_->UpdateLoginSync(PasswordFromEntityChange(
+ remote_entity_change, /*sync_time=*/time_now));
+ DCHECK_LE(changes.size(), 1U);
+ if (changes.empty()) {
+ return syncer::ModelError(
+ FROM_HERE, "Failed to update an entry in the password store.");
+ }
+ DCHECK(changes[0].primary_key() == primary_key);
+ password_store_changes.push_back(changes[0]);
+ }
+ }
+
+ // At this point, we have processed all local passwords. In addition, we
+ // also have processed all remote passwords that exist in the local model.
+ // What's remaining is to process remote passwords that don't exist in the
+ // local model.
+
+ // For any remote password that doesn't exist in the local passwords, issue
+ // a password_store_sync_->AddLoginSync() and invoke the
+ // change_processor()->UpdateStorageKey(). Password comparison is done by
+ // comparing the client tags.
+ for (const syncer::EntityChange& entity_change : entity_data) {
+ const std::string client_tag_of_remote_password =
+ GetClientTag(entity_change.data());
+ if (client_tags_of_local_passwords.count(client_tag_of_remote_password) !=
+ 0) {
+ // Passwords in both local and remote models have been processed
+ // already.
+ continue;
+ }
+
+ PasswordStoreChangeList changes = password_store_sync_->AddLoginSync(
+ PasswordFromEntityChange(entity_change, /*sync_time=*/time_now));
+
+ // TODO(crbug.com/939302): It's not yet clear if the DCHECK_LE below is
+ // legit. However, recent crashes suggest that 2 changes are returned
+ // when trying to AddLoginSync (details are in the bug). Once this is
+ // resolved, we should update the call the UpdateStorageKey() if
+ // necessary and remove unnecessary DCHECKs below.
+ // DCHECK_LE(changes.size(), 1U);
+ DCHECK_LE(changes.size(), 2U);
+ if (changes.empty()) {
+ return syncer::ModelError(
+ FROM_HERE, "Failed to add an entry in the password store.");
+ }
+
+ if (changes.size() == 1) {
+ DCHECK_EQ(changes[0].type(), PasswordStoreChange::ADD);
+ } else {
+ // There must be 2 changes.
+ DCHECK_EQ(changes[0].type(), PasswordStoreChange::REMOVE);
+ DCHECK_EQ(changes[1].type(), PasswordStoreChange::ADD);
+ }
+
+ change_processor()->UpdateStorageKey(
+ entity_change.data(),
+ /*storage_key=*/
+ base::NumberToString(changes.back().primary_key()),
+ metadata_change_list.get());
+
+ password_store_changes.insert(password_store_changes.end(),
+ changes.begin(), changes.end());
+ }
+
+ // Persist the metadata changes.
+ // TODO(mamir): add some test coverage for the metadata persistence.
+ syncer::SyncMetadataStoreChangeList sync_metadata_store_change_list(
+ password_store_sync_->GetMetadataStore(), syncer::PASSWORDS);
+ // |metadata_change_list| must have been created via
+ // CreateMetadataChangeList() so downcasting is safe.
+ static_cast<syncer::InMemoryMetadataChangeList*>(metadata_change_list.get())
+ ->TransferChangesTo(&sync_metadata_store_change_list);
+ error = sync_metadata_store_change_list.TakeError();
+ } // End of scoped transaction.
+
+ if (!password_store_changes.empty()) {
+ // It could be the case that there are no remote passwords. In such case,
+ // there would be no changes to the password store other than the sync
+ // metadata changes, and no need to notify observers since they aren't
+ // interested in changes to sync metadata.
+ password_store_sync_->NotifyLoginsChanged(password_store_changes);
+ }
+
return base::nullopt;
}
base::Optional<syncer::ModelError> PasswordSyncBridge::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_changes) {
- NOTIMPLEMENTED();
- return base::nullopt;
+ base::AutoReset<bool> processing_changes(&is_processing_remote_sync_changes_,
+ true);
+
+ const base::Time time_now = base::Time::Now();
+
+ // This is used to keep track of all the changes applied to the password store
+ // to notify other observers of the password store.
+ PasswordStoreChangeList password_store_changes;
+ base::Optional<syncer::ModelError> error;
+ {
+ ScopedStoreTransaction transaction(password_store_sync_);
+
+ for (const syncer::EntityChange& entity_change : entity_changes) {
+ PasswordStoreChangeList changes;
+ switch (entity_change.type()) {
+ case syncer::EntityChange::ACTION_ADD:
+ changes = password_store_sync_->AddLoginSync(
+ PasswordFromEntityChange(entity_change, /*sync_time=*/time_now));
+ // If the addition has been successful, inform the processor about the
+ // assigned storage key. AddLoginSync() might return multiple changes
+ // and the last one should be the one representing the actual addition
+ // in the DB.
+ if (changes.empty()) {
+ return syncer::ModelError(
+ FROM_HERE, "Failed to add an entry to the password store.");
+ }
+ // TODO(crbug.com/939302): It's not yet clear if the DCHECK_LE below
+ // is legit. However, recent crashes suggest that 2 changes are
+ // returned when trying to AddLoginSync (details are in the bug). Once
+ // this is resolved, we should update the call the UpdateStorageKey()
+ // if necessary and remove unnecessary DCHECKs below.
+ // DCHECK_EQ(1U, changes.size());
+ DCHECK_LE(changes.size(), 2U);
+ if (changes.size() == 1) {
+ DCHECK_EQ(changes[0].type(), PasswordStoreChange::ADD);
+ } else {
+ // There must be 2 changes.
+ DCHECK_EQ(changes[0].type(), PasswordStoreChange::REMOVE);
+ DCHECK_EQ(changes[1].type(), PasswordStoreChange::ADD);
+ }
+
+ change_processor()->UpdateStorageKey(
+ entity_change.data(),
+ /*storage_key=*/
+ base::NumberToString(changes.back().primary_key()),
+ metadata_change_list.get());
+ break;
+ case syncer::EntityChange::ACTION_UPDATE:
+ changes = password_store_sync_->UpdateLoginSync(
+ PasswordFromEntityChange(entity_change, /*sync_time=*/time_now));
+ if (changes.empty()) {
+ return syncer::ModelError(
+ FROM_HERE, "Failed to update an entry in the password store.");
+ }
+ DCHECK_EQ(1U, changes.size());
+ DCHECK(changes[0].primary_key() ==
+ ParsePrimaryKey(entity_change.storage_key()));
+ break;
+ case syncer::EntityChange::ACTION_DELETE: {
+ int primary_key = ParsePrimaryKey(entity_change.storage_key());
+ changes =
+ password_store_sync_->RemoveLoginByPrimaryKeySync(primary_key);
+ if (changes.empty()) {
+ return syncer::ModelError(
+ FROM_HERE,
+ "Failed to delete an entry from the password store.");
+ }
+ DCHECK_EQ(1U, changes.size());
+ DCHECK_EQ(changes[0].primary_key(), primary_key);
+ break;
+ }
+ }
+ password_store_changes.insert(password_store_changes.end(),
+ changes.begin(), changes.end());
+ }
+
+ // Persist the metadata changes.
+ // TODO(mamir): add some test coverage for the metadata persistence.
+ syncer::SyncMetadataStoreChangeList sync_metadata_store_change_list(
+ password_store_sync_->GetMetadataStore(), syncer::PASSWORDS);
+ // |metadata_change_list| must have been created via
+ // CreateMetadataChangeList() so downcasting is safe.
+ static_cast<syncer::InMemoryMetadataChangeList*>(metadata_change_list.get())
+ ->TransferChangesTo(&sync_metadata_store_change_list);
+ error = sync_metadata_store_change_list.TakeError();
+ } // End of scoped transaction.
+
+ if (!password_store_changes.empty()) {
+ // It could be the case that there are no password store changes, and all
+ // changes are only metadata changes. In such case, no need to notify
+ // observers since they aren't interested in changes to sync metadata.
+ password_store_sync_->NotifyLoginsChanged(password_store_changes);
+ }
+ return error;
}
void PasswordSyncBridge::GetData(StorageKeyList storage_keys,
DataCallback callback) {
- NOTIMPLEMENTED();
+ // This method is called only when there are uncommitted changes on startup.
+ // There are more efficient implementations, but since this method is rarely
+ // called, simplicity is preferred over efficiency.
+ PrimaryKeyToFormMap key_to_form_map;
+ if (password_store_sync_->ReadAllLogins(&key_to_form_map) !=
+ FormRetrievalResult::kSuccess) {
+ change_processor()->ReportError(
+ {FROM_HERE, "Failed to load entries from the password store."});
+ return;
+ }
+
+ auto batch = std::make_unique<syncer::MutableDataBatch>();
+ for (const std::string& storage_key : storage_keys) {
+ int primary_key = ParsePrimaryKey(storage_key);
+ if (key_to_form_map.count(primary_key) != 0) {
+ batch->Put(storage_key, CreateEntityData(*key_to_form_map[primary_key]));
+ }
+ }
+ std::move(callback).Run(std::move(batch));
}
void PasswordSyncBridge::GetAllDataForDebugging(DataCallback callback) {
- NOTIMPLEMENTED();
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ PrimaryKeyToFormMap key_to_form_map;
+ if (password_store_sync_->ReadAllLogins(&key_to_form_map) !=
+ FormRetrievalResult::kSuccess) {
+ change_processor()->ReportError(
+ {FROM_HERE, "Failed to load entries from the password store."});
+ return;
+ }
+
+ auto batch = std::make_unique<syncer::MutableDataBatch>();
+ for (const auto& pair : key_to_form_map) {
+ autofill::PasswordForm form = *pair.second;
+ form.password_value = base::UTF8ToUTF16("hidden");
+ batch->Put(base::NumberToString(pair.first), CreateEntityData(form));
+ }
+ std::move(callback).Run(std::move(batch));
}
std::string PasswordSyncBridge::GetClientTag(
@@ -168,11 +610,28 @@ bool PasswordSyncBridge::SupportsGetStorageKey() const {
return false;
}
-syncer::ModelTypeSyncBridge::StopSyncResponse
-PasswordSyncBridge::ApplyStopSyncChanges(
+void PasswordSyncBridge::ApplyStopSyncChanges(
std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list) {
- NOTIMPLEMENTED();
- return ModelTypeSyncBridge::StopSyncResponse::kModelNoLongerReadyToSync;
+ // TODO(crbug.com/902349): Implement disable-sync case by a more robust
+ // implementation, via a dedicated method in PasswordStoreSync.
+ ModelTypeSyncBridge::ApplyStopSyncChanges(
+ std::move(delete_metadata_change_list));
+}
+
+base::Optional<syncer::ModelError> PasswordSyncBridge::CleanupPasswordStore() {
+ DatabaseCleanupResult cleanup_result =
+ password_store_sync_->DeleteUndecryptableLogins();
+ switch (cleanup_result) {
+ case DatabaseCleanupResult::kSuccess:
+ break;
+ case DatabaseCleanupResult::kEncryptionUnavailable:
+ return syncer::ModelError(
+ FROM_HERE, "Failed to get encryption key during database cleanup.");
+ case DatabaseCleanupResult::kItemFailure:
+ case DatabaseCleanupResult::kDatabaseUnavailable:
+ return syncer::ModelError(FROM_HERE, "Failed to cleanup database.");
+ }
+ return base::nullopt;
}
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/sync/password_sync_bridge.h b/chromium/components/password_manager/core/browser/sync/password_sync_bridge.h
index 7757a192c7c..bc7def137d9 100644
--- a/chromium/components/password_manager/core/browser/sync/password_sync_bridge.h
+++ b/chromium/components/password_manager/core/browser/sync/password_sync_bridge.h
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "components/password_manager/core/browser/password_store_change.h"
+#include "components/password_manager/core/browser/password_store_sync.h"
#include "components/sync/model/model_type_sync_bridge.h"
namespace syncer {
@@ -41,8 +42,6 @@ class PasswordSyncBridge : public syncer::ModelTypeSyncBridge {
void ActOnPasswordStoreChanges(const PasswordStoreChangeList& changes);
// ModelTypeSyncBridge implementation.
- void OnSyncStarting(
- const syncer::DataTypeActivationRequest& request) override;
std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
override;
base::Optional<syncer::ModelError> MergeSyncData(
@@ -56,14 +55,24 @@ class PasswordSyncBridge : public syncer::ModelTypeSyncBridge {
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
bool SupportsGetStorageKey() const override;
- ModelTypeSyncBridge::StopSyncResponse ApplyStopSyncChanges(
- std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list)
- override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
private:
+ // On MacOS it may happen that some passwords cannot be decrypted due to
+ // modification of encryption key in Keychain (https://crbug.com/730625). This
+ // method deletes those logins from the store. So during merge, the data in
+ // sync will be added to the password store. This should be called during
+ // MergeSyncData().
+ base::Optional<syncer::ModelError> CleanupPasswordStore();
+
// Password store responsible for persistence.
PasswordStoreSync* const password_store_sync_;
+ // True if processing remote sync changes is in progress. Used to ignore
+ // password store changes notifications while processing remote sync changes.
+ bool is_processing_remote_sync_changes_ = false;
+
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(PasswordSyncBridge);
diff --git a/chromium/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/chromium/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
index 08af623f40a..40a5e9bb5cc 100644
--- a/chromium/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
+++ b/chromium/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -4,10 +4,21 @@
#include "components/password_manager/core/browser/sync/password_sync_bridge.h"
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/bind_test_util.h"
#include "components/password_manager/core/browser/password_store_sync.h"
+#include "components/sync/model/data_batch.h"
+#include "components/sync/model/entity_change.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
+#include "components/sync/model_impl/in_memory_metadata_change_list.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
+#include "components/sync/test/test_matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,20 +28,33 @@ namespace {
using testing::_;
using testing::Eq;
+using testing::Invoke;
+using testing::NotNull;
using testing::Return;
+using testing::UnorderedElementsAre;
constexpr char kSignonRealm1[] = "abc";
constexpr char kSignonRealm2[] = "def";
constexpr char kSignonRealm3[] = "xyz";
-// |*args| must be of type EntityData.
-MATCHER_P(HasSignonRealm, expected_signon_realm, "") {
+// |*arg| must be of type EntityData.
+MATCHER_P(EntityDataHasSignonRealm, expected_signon_realm, "") {
return arg->specifics.password()
.client_only_encrypted_data()
.signon_realm() == expected_signon_realm;
}
-// |*args| must be of type SyncMetadataStoreChangeList.
+// |*arg| must be of type PasswordForm.
+MATCHER_P(FormHasSignonRealm, expected_signon_realm, "") {
+ return arg.signon_realm == expected_signon_realm;
+}
+
+// |*arg| must be of type PasswordStoreChange.
+MATCHER_P(ChangeHasPrimaryKey, expected_primary_key, "") {
+ return arg.primary_key() == expected_primary_key;
+}
+
+// |*arg| must be of type SyncMetadataStoreChangeList.
MATCHER_P(IsSyncMetadataStoreChangeListWithStore, expected_metadata_store, "") {
return static_cast<const syncer::SyncMetadataStoreChangeList*>(arg)
->GetMetadataStoreForTesting() == expected_metadata_store;
@@ -53,17 +77,103 @@ sync_pb::PasswordSpecifics CreateSpecifics(const std::string& origin,
return password_specifics.password();
}
+sync_pb::PasswordSpecifics CreateSpecificsWithSignonRealm(
+ const std::string& signon_realm) {
+ return CreateSpecifics("http://www.origin.com", "username_element",
+ "username_value", "password_element", signon_realm);
+}
+
autofill::PasswordForm MakePasswordForm(const std::string& signon_realm) {
autofill::PasswordForm form;
+ form.origin = GURL("http://www.origin.com");
+ form.username_element = base::UTF8ToUTF16("username_element");
+ form.username_value = base::UTF8ToUTF16("username_value");
+ form.password_element = base::UTF8ToUTF16("password_element");
form.signon_realm = signon_realm;
return form;
}
-class MockSyncMetadataStore : public syncer::SyncMetadataStore {
+// Creates an EntityData/EntityDataPtr around a copy of the given specifics.
+syncer::EntityDataPtr SpecificsToEntity(
+ const sync_pb::PasswordSpecifics& specifics) {
+ syncer::EntityData data;
+ // These tests do not care about the tag hash, but EntityData and friends
+ // cannot differentiate between the default EntityData object if the hash
+ // is unset, which causes pass/copy operations to no-op and things start to
+ // break, so we throw in a junk value and forget about it.
+ data.client_tag_hash = "junk";
+ *data.specifics.mutable_password() = specifics;
+ return data.PassToPtr();
+}
+
+// A mini database class the supports Add/Update/Remove functionality. It also
+// supports an auto increment primary key that starts from 1. It will be used to
+// empower the MockPasswordStoreSync be forwarding all database calls to an
+// instance of this class.
+class FakeDatabase {
+ public:
+ FakeDatabase() = default;
+ ~FakeDatabase() = default;
+
+ FormRetrievalResult ReadAllLogins(PrimaryKeyToFormMap* map) {
+ map->clear();
+ for (const auto& pair : data_) {
+ map->emplace(pair.first,
+ std::make_unique<autofill::PasswordForm>(*pair.second));
+ }
+ return FormRetrievalResult::kSuccess;
+ }
+
+ PasswordStoreChangeList AddLogin(const autofill::PasswordForm& form) {
+ data_[primary_key_] = std::make_unique<autofill::PasswordForm>(form);
+ return {
+ PasswordStoreChange(PasswordStoreChange::ADD, form, primary_key_++)};
+ }
+
+ PasswordStoreChangeList AddLoginForPrimaryKey(
+ int primary_key,
+ const autofill::PasswordForm& form) {
+ DCHECK_EQ(0U, data_.count(primary_key));
+ data_[primary_key] = std::make_unique<autofill::PasswordForm>(form);
+ return {PasswordStoreChange(PasswordStoreChange::ADD, form, primary_key)};
+ }
+
+ PasswordStoreChangeList UpdateLogin(const autofill::PasswordForm& form) {
+ int key = GetPrimaryKey(form);
+ DCHECK_NE(-1, key);
+ data_[key] = std::make_unique<autofill::PasswordForm>(form);
+ return {PasswordStoreChange(PasswordStoreChange::UPDATE, form, key)};
+ }
+
+ PasswordStoreChangeList RemoveLogin(int key) {
+ DCHECK_NE(0U, data_.count(key));
+ autofill::PasswordForm form = *data_[key];
+ data_.erase(key);
+ return {PasswordStoreChange(PasswordStoreChange::REMOVE, form, key)};
+ }
+
+ private:
+ int GetPrimaryKey(const autofill::PasswordForm& form) const {
+ for (const auto& pair : data_) {
+ if (ArePasswordFormUniqueKeyEqual(*pair.second, form)) {
+ return pair.first;
+ }
+ }
+ return -1;
+ }
+
+ int primary_key_ = 1;
+ PrimaryKeyToFormMap data_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeDatabase);
+};
+
+class MockSyncMetadataStore : public PasswordStoreSync::MetadataStore {
public:
MockSyncMetadataStore() = default;
~MockSyncMetadataStore() = default;
+ MOCK_METHOD0(GetAllSyncMetadata, std::unique_ptr<syncer::MetadataBatch>());
MOCK_METHOD3(UpdateSyncMetadata,
bool(syncer::ModelType,
const std::string&,
@@ -83,7 +193,7 @@ class MockPasswordStoreSync : public PasswordStoreSync {
bool(std::vector<std::unique_ptr<autofill::PasswordForm>>*));
MOCK_METHOD1(FillBlacklistLogins,
bool(std::vector<std::unique_ptr<autofill::PasswordForm>>*));
- MOCK_METHOD1(ReadAllLogins, bool(PrimaryKeyToFormMap*));
+ MOCK_METHOD1(ReadAllLogins, FormRetrievalResult(PrimaryKeyToFormMap*));
MOCK_METHOD1(RemoveLoginByPrimaryKeySync, PasswordStoreChangeList(int));
MOCK_METHOD0(DeleteUndecryptableLogins, DatabaseCleanupResult());
MOCK_METHOD1(AddLoginSync,
@@ -95,19 +205,40 @@ class MockPasswordStoreSync : public PasswordStoreSync {
MOCK_METHOD1(NotifyLoginsChanged, void(const PasswordStoreChangeList&));
MOCK_METHOD0(BeginTransaction, bool());
MOCK_METHOD0(CommitTransaction, bool());
- MOCK_METHOD0(GetMetadataStore, syncer::SyncMetadataStore*());
+ MOCK_METHOD0(GetMetadataStore, PasswordStoreSync::MetadataStore*());
};
} // namespace
class PasswordSyncBridgeTest : public testing::Test {
public:
- PasswordSyncBridgeTest()
- : bridge_(mock_processor_.CreateForwardingProcessor(),
- &mock_password_store_sync_) {
+ PasswordSyncBridgeTest() {
ON_CALL(mock_password_store_sync_, GetMetadataStore())
.WillByDefault(testing::Return(&mock_sync_metadata_store_sync_));
-
+ ON_CALL(mock_password_store_sync_, ReadAllLogins(_))
+ .WillByDefault(Invoke(&fake_db_, &FakeDatabase::ReadAllLogins));
+ ON_CALL(mock_password_store_sync_, AddLoginSync(_))
+ .WillByDefault(Invoke(&fake_db_, &FakeDatabase::AddLogin));
+ ON_CALL(mock_password_store_sync_, UpdateLoginSync(_))
+ .WillByDefault(Invoke(&fake_db_, &FakeDatabase::UpdateLogin));
+ ON_CALL(mock_password_store_sync_, RemoveLoginByPrimaryKeySync(_))
+ .WillByDefault(Invoke(&fake_db_, &FakeDatabase::RemoveLogin));
+
+ bridge_ = std::make_unique<PasswordSyncBridge>(
+ mock_processor_.CreateForwardingProcessor(),
+ &mock_password_store_sync_);
+
+ // It's the responsibility of the PasswordStoreSync to inform the bridge
+ // about changes in the password store. The bridge notifies the
+ // PasswordStoreSync about the new changes even if they are initiated by the
+ // bridge itself.
+ ON_CALL(mock_password_store_sync_, NotifyLoginsChanged(_))
+ .WillByDefault(
+ Invoke(bridge(), &PasswordSyncBridge::ActOnPasswordStoreChanges));
+
+ ON_CALL(mock_sync_metadata_store_sync_, GetAllSyncMetadata())
+ .WillByDefault(
+ []() { return std::make_unique<syncer::MetadataBatch>(); });
ON_CALL(mock_sync_metadata_store_sync_, UpdateSyncMetadata(_, _, _))
.WillByDefault(testing::Return(true));
ON_CALL(mock_sync_metadata_store_sync_, ClearSyncMetadata(_, _))
@@ -120,21 +251,46 @@ class PasswordSyncBridgeTest : public testing::Test {
~PasswordSyncBridgeTest() override {}
- PasswordSyncBridge* bridge() { return &bridge_; }
+ base::Optional<sync_pb::PasswordSpecifics> GetDataFromBridge(
+ const std::string& storage_key) {
+ std::unique_ptr<syncer::DataBatch> batch;
+ bridge_->GetData({storage_key},
+ base::BindLambdaForTesting(
+ [&](std::unique_ptr<syncer::DataBatch> in_batch) {
+ batch = std::move(in_batch);
+ }));
+ EXPECT_THAT(batch, NotNull());
+ if (!batch || !batch->HasNext()) {
+ return base::nullopt;
+ }
+ const syncer::KeyAndData& data_pair = batch->Next();
+ EXPECT_THAT(data_pair.first, Eq(storage_key));
+ EXPECT_FALSE(batch->HasNext());
+ return data_pair.second->specifics.password();
+ }
+
+ FakeDatabase* fake_db() { return &fake_db_; }
+
+ PasswordSyncBridge* bridge() { return bridge_.get(); }
syncer::MockModelTypeChangeProcessor& mock_processor() {
return mock_processor_;
}
+ MockSyncMetadataStore* mock_sync_metadata_store_sync() {
+ return &mock_sync_metadata_store_sync_;
+ }
+
MockPasswordStoreSync* mock_password_store_sync() {
return &mock_password_store_sync_;
}
private:
+ FakeDatabase fake_db_;
testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
testing::NiceMock<MockSyncMetadataStore> mock_sync_metadata_store_sync_;
testing::NiceMock<MockPasswordStoreSync> mock_password_store_sync_;
- PasswordSyncBridge bridge_;
+ std::unique_ptr<PasswordSyncBridge> bridge_;
};
TEST_F(PasswordSyncBridgeTest, ShouldComputeClientTagHash) {
@@ -159,13 +315,13 @@ TEST_F(PasswordSyncBridgeTest, ShouldForwardLocalChangesToTheProcessor) {
PasswordStoreChange::UPDATE, MakePasswordForm(kSignonRealm2), /*id=*/2));
changes.push_back(PasswordStoreChange(
PasswordStoreChange::REMOVE, MakePasswordForm(kSignonRealm3), /*id=*/3));
- syncer::SyncMetadataStore* store =
+ PasswordStoreSync::MetadataStore* store =
mock_password_store_sync()->GetMetadataStore();
EXPECT_CALL(mock_processor(),
- Put("1", HasSignonRealm(kSignonRealm1),
+ Put("1", EntityDataHasSignonRealm(kSignonRealm1),
IsSyncMetadataStoreChangeListWithStore(store)));
EXPECT_CALL(mock_processor(),
- Put("2", HasSignonRealm(kSignonRealm2),
+ Put("2", EntityDataHasSignonRealm(kSignonRealm2),
IsSyncMetadataStoreChangeListWithStore(store)));
EXPECT_CALL(mock_processor(),
Delete("3", IsSyncMetadataStoreChangeListWithStore(store)));
@@ -191,4 +347,372 @@ TEST_F(PasswordSyncBridgeTest,
bridge()->ActOnPasswordStoreChanges(changes);
}
+TEST_F(PasswordSyncBridgeTest, ShouldApplyEmptySyncChangesWithoutError) {
+ base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(), syncer::EntityChangeList());
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldApplyMetadataWithEmptySyncChanges) {
+ const std::string kStorageKey = "1";
+ const std::string kServerId = "TestServerId";
+ sync_pb::EntityMetadata metadata;
+ metadata.set_server_id(kServerId);
+ auto metadata_change_list =
+ std::make_unique<syncer::InMemoryMetadataChangeList>();
+ metadata_change_list->UpdateMetadata(kStorageKey, metadata);
+
+ EXPECT_CALL(*mock_password_store_sync(), NotifyLoginsChanged(_)).Times(0);
+
+ EXPECT_CALL(*mock_sync_metadata_store_sync(),
+ UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey, _));
+
+ base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
+ std::move(metadata_change_list), syncer::EntityChangeList());
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteCreation) {
+ ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(true));
+ // Since this remote creation is the first entry in the FakeDatabase, it will
+ // be assigned a primary key 1.
+ const std::string kStorageKey = "1";
+
+ sync_pb::PasswordSpecifics specifics =
+ CreateSpecificsWithSignonRealm(kSignonRealm1);
+
+ testing::InSequence in_sequence;
+ EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
+ EXPECT_CALL(*mock_password_store_sync(),
+ AddLoginSync(FormHasSignonRealm(kSignonRealm1)));
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kStorageKey, _));
+ EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
+ EXPECT_CALL(
+ *mock_password_store_sync(),
+ NotifyLoginsChanged(UnorderedElementsAre(ChangeHasPrimaryKey(1))));
+
+ // Processor shouldn't be notified about remote changes.
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"", SpecificsToEntity(specifics))});
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteUpdate) {
+ const int kPrimaryKey = 1000;
+ const std::string kStorageKey = "1000";
+ // Add the form to the DB.
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey,
+ MakePasswordForm(kSignonRealm1));
+
+ sync_pb::PasswordSpecifics specifics =
+ CreateSpecificsWithSignonRealm(kSignonRealm1);
+
+ testing::InSequence in_sequence;
+ EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
+ EXPECT_CALL(*mock_password_store_sync(),
+ UpdateLoginSync(FormHasSignonRealm(kSignonRealm1)));
+ EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
+ EXPECT_CALL(*mock_password_store_sync(),
+ NotifyLoginsChanged(
+ UnorderedElementsAre(ChangeHasPrimaryKey(kPrimaryKey))));
+
+ // Processor shouldn't be notified about remote changes.
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, _, _)).Times(0);
+
+ base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateUpdate(kStorageKey,
+ SpecificsToEntity(specifics))});
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteDeletion) {
+ const int kPrimaryKey = 1000;
+ const std::string kStorageKey = "1000";
+ // Add the form to the DB.
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey,
+ MakePasswordForm(kSignonRealm1));
+
+ testing::InSequence in_sequence;
+ EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
+ EXPECT_CALL(*mock_password_store_sync(),
+ RemoveLoginByPrimaryKeySync(kPrimaryKey));
+ EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
+ EXPECT_CALL(*mock_password_store_sync(),
+ NotifyLoginsChanged(
+ UnorderedElementsAre(ChangeHasPrimaryKey(kPrimaryKey))));
+
+ // Processor shouldn't be notified about remote changes.
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+
+ base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateDelete(kStorageKey)});
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldGetDataForStorageKey) {
+ const int kPrimaryKey1 = 1000;
+ const int kPrimaryKey2 = 1001;
+ const std::string kPrimaryKeyStr1 = "1000";
+ const std::string kPrimaryKeyStr2 = "1001";
+ autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
+ autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);
+
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);
+
+ base::Optional<sync_pb::PasswordSpecifics> optional_specifics =
+ GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr1);
+ ASSERT_TRUE(optional_specifics.has_value());
+ EXPECT_EQ(
+ kSignonRealm1,
+ optional_specifics.value().client_only_encrypted_data().signon_realm());
+
+ optional_specifics = GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr2);
+ ASSERT_TRUE(optional_specifics.has_value());
+ EXPECT_EQ(kSignonRealm2,
+ optional_specifics->client_only_encrypted_data().signon_realm());
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldNotGetDataForNonExistingStorageKey) {
+ const std::string kPrimaryKeyStr = "1";
+
+ base::Optional<sync_pb::PasswordSpecifics> optional_specifics =
+ GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr);
+ EXPECT_FALSE(optional_specifics.has_value());
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldMergeSyncRemoteAndLocalPasswords) {
+ ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(true));
+ // Setup the test to have Form 1 and Form 2 stored locally, and Form 2 and
+ // Form 3 coming as remote changes. We will assign primary keys for Form 1 and
+ // Form 2. Form 3 will arrive as remote creation, and FakeDatabase will assign
+ // it primary key 1.
+ const int kPrimaryKey1 = 1000;
+ const int kPrimaryKey2 = 1001;
+ const int kExpectedPrimaryKey3 = 1;
+ const std::string kPrimaryKeyStr1 = "1000";
+ const std::string kPrimaryKeyStr2 = "1001";
+ const std::string kExpectedPrimaryKeyStr3 = "1";
+ autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
+ autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);
+ autofill::PasswordForm form3 = MakePasswordForm(kSignonRealm3);
+ sync_pb::PasswordSpecifics specifics1 =
+ CreateSpecificsWithSignonRealm(kSignonRealm1);
+ sync_pb::PasswordSpecifics specifics2 =
+ CreateSpecificsWithSignonRealm(kSignonRealm2);
+ sync_pb::PasswordSpecifics specifics3 =
+ CreateSpecificsWithSignonRealm(kSignonRealm3);
+
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);
+
+ // Form 1 will be added to the change processor. The local version of Form 2
+ // isn't more recent than the remote version, therefore it will be updated in
+ // the password sync store using the remote version. Form 3 will be added to
+ // the password store sync.
+
+ // Interactions should happen in this order:
+ // +--> Put(1) ------------------------------------+
+ // | |
+ // |--> UpdateStorageKey(2) -----------------------|
+ // Begin() --| |--> Commit()
+ // |--> UpdateLoginSync(3) ------------------------|
+ // | |
+ // +--> AddLoginSync (4) ---> UpdateStorageKey(4)--+
+
+ testing::Sequence s1, s2, s3, s4;
+ EXPECT_CALL(*mock_password_store_sync(), BeginTransaction())
+ .InSequence(s1, s2, s3, s4);
+ EXPECT_CALL(mock_processor(),
+ Put(kPrimaryKeyStr1, EntityDataHasSignonRealm(kSignonRealm1), _))
+ .InSequence(s1);
+
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kPrimaryKeyStr2, _))
+ .InSequence(s2);
+
+ EXPECT_CALL(*mock_password_store_sync(),
+ UpdateLoginSync(FormHasSignonRealm(kSignonRealm2)))
+ .InSequence(s3);
+
+ EXPECT_CALL(*mock_password_store_sync(),
+ AddLoginSync(FormHasSignonRealm(kSignonRealm3)))
+ .InSequence(s4);
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kExpectedPrimaryKeyStr3, _))
+ .InSequence(s4);
+
+ EXPECT_CALL(*mock_password_store_sync(), CommitTransaction())
+ .InSequence(s1, s2, s3, s4);
+
+ EXPECT_CALL(*mock_password_store_sync(),
+ NotifyLoginsChanged(UnorderedElementsAre(
+ ChangeHasPrimaryKey(kPrimaryKey2),
+ ChangeHasPrimaryKey(kExpectedPrimaryKey3))))
+ .InSequence(s1, s2, s3, s4);
+
+ // Processor shouldn't be informed about Form 2 or Form 3.
+ EXPECT_CALL(mock_processor(), Put(kPrimaryKeyStr2, _, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kExpectedPrimaryKeyStr3, _, _)).Times(0);
+
+ base::Optional<syncer::ModelError> error = bridge()->MergeSyncData(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"", SpecificsToEntity(specifics2)),
+ syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"", SpecificsToEntity(specifics3))});
+ EXPECT_FALSE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest,
+ ShouldMergeSyncRemoteAndLocalPasswordsChoosingTheMoreRecent) {
+ // Setup the test to have Form 1 and Form 2 stored locally and remotely. Local
+ // Form 1 is more recent than the remote one. Remote Form 2 is more recent
+ // than the local one. We will assign primary keys for Form 1 and Form 2 in
+ // the local DB.
+ base::Time now = base::Time::Now();
+ base::Time yesterday = now - base::TimeDelta::FromDays(1);
+ const int kPrimaryKey1 = 1000;
+ const int kPrimaryKey2 = 1001;
+ const std::string kPrimaryKeyStr1 = "1000";
+ const std::string kPrimaryKeyStr2 = "1001";
+
+ // Local form 1 is more recent than the remote.
+ autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
+ form1.date_created = now;
+ sync_pb::PasswordSpecifics specifics1 =
+ CreateSpecificsWithSignonRealm(kSignonRealm1);
+ specifics1.mutable_client_only_encrypted_data()->set_date_created(
+ yesterday.ToDeltaSinceWindowsEpoch().InMicroseconds());
+
+ // Remote form 2 is more recent than the local.
+ autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);
+ form2.date_created = yesterday;
+ sync_pb::PasswordSpecifics specifics2 =
+ CreateSpecificsWithSignonRealm(kSignonRealm2);
+ specifics2.mutable_client_only_encrypted_data()->set_date_created(
+ now.ToDeltaSinceWindowsEpoch().InMicroseconds());
+
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);
+
+ // The processor should be informed about the storage keys of both passwords.
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kPrimaryKeyStr1, _));
+ EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kPrimaryKeyStr2, _));
+
+ // Since local Form 1 is more recent, it will be put() in the processor.
+ EXPECT_CALL(mock_processor(),
+ Put(kPrimaryKeyStr1, EntityDataHasSignonRealm(kSignonRealm1), _));
+
+ // Since the remote Form 2 is more recent, it will be updated in the password
+ // store.
+ EXPECT_CALL(*mock_password_store_sync(),
+ UpdateLoginSync(FormHasSignonRealm(kSignonRealm2)));
+
+ base::Optional<syncer::ModelError> error = bridge()->MergeSyncData(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"", SpecificsToEntity(specifics1)),
+ syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"", SpecificsToEntity(specifics2))});
+ EXPECT_FALSE(error);
+}
+
+// This tests that if reading logins from the store fails,
+// ShouldMergeSync() would return an error without crashing.
+TEST_F(PasswordSyncBridgeTest,
+ ShouldMergeSyncRemoteAndLocalPasswordsWithErrorWhenStoreReadFails) {
+ // Simulate a failed ReadAllLogins() by returning a kDbError.
+ ON_CALL(*mock_password_store_sync(), ReadAllLogins(_))
+ .WillByDefault(testing::Return(FormRetrievalResult::kDbError));
+ base::Optional<syncer::ModelError> error =
+ bridge()->MergeSyncData(bridge()->CreateMetadataChangeList(), {});
+ EXPECT_TRUE(error);
+}
+
+// This tests that if adding logins to the store fails,
+// ShouldMergeSync() would return an error without crashing.
+TEST_F(PasswordSyncBridgeTest,
+ ShouldMergeSyncRemoteAndLocalPasswordsWithErrorWhenStoreAddFails) {
+ // Simulate a failed AddLoginSync() by returning an empty change list.
+ ON_CALL(*mock_password_store_sync(), AddLoginSync(_))
+ .WillByDefault(testing::Return(PasswordStoreChangeList()));
+
+ base::Optional<syncer::ModelError> error = bridge()->MergeSyncData(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateAdd(
+ /*storage_key=*/"",
+ SpecificsToEntity(CreateSpecificsWithSignonRealm(kSignonRealm1)))});
+ EXPECT_TRUE(error);
+}
+
+TEST_F(PasswordSyncBridgeTest, ShouldGetAllDataForDebuggingWithHiddenPassword) {
+ const int kPrimaryKey1 = 1000;
+ const int kPrimaryKey2 = 1001;
+ autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
+ autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);
+
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
+ fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);
+
+ std::unique_ptr<syncer::DataBatch> batch;
+
+ bridge()->GetAllDataForDebugging(base::BindLambdaForTesting(
+ [&](std::unique_ptr<syncer::DataBatch> in_batch) {
+ batch = std::move(in_batch);
+ }));
+
+ ASSERT_THAT(batch, NotNull());
+ EXPECT_TRUE(batch->HasNext());
+ while (batch->HasNext()) {
+ const syncer::KeyAndData& data_pair = batch->Next();
+ EXPECT_EQ("hidden", data_pair.second->specifics.password()
+ .client_only_encrypted_data()
+ .password_value());
+ }
+}
+
+TEST_F(PasswordSyncBridgeTest,
+ ShouldCallModelReadyUponConstructionWithMetadata) {
+ ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata())
+ .WillByDefault([&]() {
+ sync_pb::ModelTypeState model_type_state;
+ model_type_state.set_initial_sync_done(true);
+ auto metadata_batch = std::make_unique<syncer::MetadataBatch>();
+ metadata_batch->SetModelTypeState(model_type_state);
+ metadata_batch->AddMetadata("storage_key", sync_pb::EntityMetadata());
+ return metadata_batch;
+ });
+
+ EXPECT_CALL(mock_processor(), ModelReadyToSync(MetadataBatchContains(
+ /*state=*/syncer::HasInitialSyncDone(),
+ /*entities=*/testing::SizeIs(1))));
+
+ PasswordSyncBridge bridge(mock_processor().CreateForwardingProcessor(),
+ mock_password_store_sync());
+}
+
+// Tests that in case ReadAllLogins() during initial merge returns encryption
+// service failure, the bridge would try to do a DB clean up.
+TEST_F(PasswordSyncBridgeTest, ShouldDeleteUndecryptableLoginsDuringMerge) {
+ ON_CALL(*mock_password_store_sync(), DeleteUndecryptableLogins())
+ .WillByDefault(Return(DatabaseCleanupResult::kSuccess));
+
+ // We should try to read first, and simulate an encryption failure. Then,
+ // cleanup the database and try to read again which should be successful now.
+ EXPECT_CALL(*mock_password_store_sync(), ReadAllLogins(_))
+ .WillOnce(Return(FormRetrievalResult::kEncrytionServiceFailure))
+ .WillOnce(Return(FormRetrievalResult::kSuccess));
+ EXPECT_CALL(*mock_password_store_sync(), DeleteUndecryptableLogins());
+
+ base::Optional<syncer::ModelError> error =
+ bridge()->MergeSyncData(bridge()->CreateMetadataChangeList(), {});
+ EXPECT_FALSE(error);
+}
+
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.cc b/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.cc
deleted file mode 100644
index 4f866c6ee30..00000000000
--- a/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h"
-
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/sequence_checker.h"
-#include "components/password_manager/core/browser/password_store.h"
-#include "components/sync/base/cryptographer.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/driver/sync_client.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/sync/engine/sync_encryption_handler.h"
-
-namespace password_manager {
-
-namespace {
-
-// A SyncEncryptionHandler::Observer implementation that simply posts
-// OnCryptographerStateChanged events to another task runner. This object is
-// needed because its handed over to the sync thread, where the authoritative
-// cryptographer lives. This class allows receiving cryptographer updates
-// directly from the sync thread to the model thread (password's background
-// thread).
-class OnCryptographerStateChangedProxy
- : public syncer::SyncEncryptionHandler::Observer {
- public:
- // |cb| will be run on |task_runner|.
- OnCryptographerStateChangedProxy(
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- const base::RepeatingCallback<
- void(std::unique_ptr<syncer::Cryptographer>)>& cb)
- : task_runner_(std::move(task_runner)), cb_(cb) {
- DCHECK(task_runner_);
- DCHECK(cb_);
- }
-
- void OnPassphraseRequired(
- syncer::PassphraseRequiredReason reason,
- const syncer::KeyDerivationParams& key_derivation_params,
- const sync_pb::EncryptedData& pending_keys) override {}
-
- void OnPassphraseAccepted() override {}
-
- void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
- syncer::BootstrapTokenType type) override {}
-
- void OnEncryptedTypesChanged(syncer::ModelTypeSet encrypted_types,
- bool encrypt_everything) override {}
-
- void OnEncryptionComplete() override {}
-
- void OnCryptographerStateChanged(
- syncer::Cryptographer* cryptographer) override {
- // We make a copy of |cryptographer| since it's not thread-safe.
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(cb_, std::make_unique<syncer::Cryptographer>(
- *cryptographer)));
- }
-
- void OnPassphraseTypeChanged(syncer::PassphraseType type,
- base::Time passphrase_time) override {}
-
- void OnLocalSetPassphraseEncryption(
- const syncer::SyncEncryptionHandler::NigoriState& nigori_state) override {
- }
-
- private:
- const scoped_refptr<base::SequencedTaskRunner> task_runner_;
- const base::RepeatingCallback<void(std::unique_ptr<syncer::Cryptographer>)>
- cb_;
-
- DISALLOW_COPY_AND_ASSIGN(OnCryptographerStateChangedProxy);
-};
-
-} // namespace
-
-// Created and constructed on any thread, but otherwise used exclusively on a
-// single sequence (the model sequence).
-class PasswordSyncableServiceBasedModelTypeController::ModelCryptographerImpl
- : public syncer::SyncableServiceBasedBridge::ModelCryptographer {
- public:
- ModelCryptographerImpl() { DETACH_FROM_SEQUENCE(sequence_checker_); }
-
- void OnCryptographerStateChanged(
- std::unique_ptr<syncer::Cryptographer> cryptographer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(cryptographer);
- cryptographer_ = std::move(cryptographer);
- }
-
- base::Optional<syncer::ModelError> Decrypt(
- sync_pb::EntitySpecifics* specifics) override {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(cryptographer_);
- DCHECK(cryptographer_->is_ready());
-
- const sync_pb::PasswordSpecifics& password_specifics =
- specifics->password();
- DCHECK(password_specifics.has_encrypted());
-
- const sync_pb::EncryptedData& encrypted = password_specifics.encrypted();
- if (!cryptographer_->CanDecrypt(encrypted)) {
- return syncer::ModelError(FROM_HERE, "Cannot decrypt password");
- }
-
- sync_pb::EntitySpecifics unencrypted_password;
- if (!cryptographer_->Decrypt(encrypted,
- unencrypted_password.mutable_password()
- ->mutable_client_only_encrypted_data())) {
- return syncer::ModelError(FROM_HERE, "Failed to decrypt password");
- }
-
- unencrypted_password.Swap(specifics);
- return base::nullopt;
- }
-
- base::Optional<syncer::ModelError> Encrypt(
- sync_pb::EntitySpecifics* specifics) override {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(cryptographer_);
- DCHECK(cryptographer_->is_ready());
-
- const sync_pb::PasswordSpecificsData& data =
- specifics->password().client_only_encrypted_data();
-
- // We populate password metadata regardless of passphrase type, but it may
- // be cleared out later in NonBlockingTypeCommitContribution if an explicit
- // passphrase is used.
- sync_pb::EntitySpecifics encrypted_password;
- if (specifics->password().unencrypted_metadata().url() !=
- data.signon_realm()) {
- encrypted_password.mutable_password()
- ->mutable_unencrypted_metadata()
- ->set_url(data.signon_realm());
- }
-
- if (!cryptographer_->Encrypt(
- data, encrypted_password.mutable_password()->mutable_encrypted())) {
- return syncer::ModelError(FROM_HERE, "Failed to encrypt password");
- }
-
- encrypted_password.Swap(specifics);
- return base::nullopt;
- }
-
- private:
- ~ModelCryptographerImpl() override = default;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- std::unique_ptr<syncer::Cryptographer> cryptographer_;
-};
-
-PasswordSyncableServiceBasedModelTypeController::
- PasswordSyncableServiceBasedModelTypeController(
- syncer::OnceModelTypeStoreFactory store_factory,
- const base::RepeatingClosure& dump_stack,
- scoped_refptr<PasswordStore> password_store,
- syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client)
- : PasswordSyncableServiceBasedModelTypeController(
- std::move(store_factory),
- dump_stack,
- std::move(password_store),
- sync_service,
- sync_client,
- base::MakeRefCounted<ModelCryptographerImpl>()) {}
-
-PasswordSyncableServiceBasedModelTypeController::
- ~PasswordSyncableServiceBasedModelTypeController() = default;
-
-void PasswordSyncableServiceBasedModelTypeController::LoadModels(
- const syncer::ConfigureContext& configure_context,
- const ModelLoadCallback& model_load_callback) {
- DCHECK(CalledOnValidThread());
- sync_service_->AddObserver(this);
- NonUiSyncableServiceBasedModelTypeController::LoadModels(configure_context,
- model_load_callback);
- sync_client_->GetPasswordStateChangedCallback().Run();
-}
-
-void PasswordSyncableServiceBasedModelTypeController::Stop(
- syncer::ShutdownReason shutdown_reason,
- StopCallback callback) {
- DCHECK(CalledOnValidThread());
- sync_service_->RemoveObserver(this);
- NonUiSyncableServiceBasedModelTypeController::Stop(shutdown_reason,
- std::move(callback));
- sync_client_->GetPasswordStateChangedCallback().Run();
-}
-
-std::unique_ptr<syncer::SyncEncryptionHandler::Observer>
-PasswordSyncableServiceBasedModelTypeController::GetEncryptionObserverProxy() {
- DCHECK(CalledOnValidThread());
- return std::make_unique<OnCryptographerStateChangedProxy>(
- background_task_runner_,
- base::BindRepeating(&ModelCryptographerImpl::OnCryptographerStateChanged,
- model_cryptographer_));
-}
-
-void PasswordSyncableServiceBasedModelTypeController::OnStateChanged(
- syncer::SyncService* sync) {
- DCHECK(CalledOnValidThread());
- sync_client_->GetPasswordStateChangedCallback().Run();
-}
-
-PasswordSyncableServiceBasedModelTypeController::
- PasswordSyncableServiceBasedModelTypeController(
- syncer::OnceModelTypeStoreFactory store_factory,
- const base::RepeatingClosure& dump_stack,
- scoped_refptr<PasswordStore> password_store,
- syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client,
- scoped_refptr<ModelCryptographerImpl> model_cryptographer)
- : NonUiSyncableServiceBasedModelTypeController(
- syncer::PASSWORDS,
- std::move(store_factory),
- base::BindRepeating(&PasswordStore::GetPasswordSyncableService,
- password_store),
- dump_stack,
- password_store->GetBackgroundTaskRunner(),
- model_cryptographer),
- background_task_runner_(password_store->GetBackgroundTaskRunner()),
- model_cryptographer_(model_cryptographer),
- sync_service_(sync_service),
- sync_client_(sync_client) {
- DCHECK(sync_service_);
- DCHECK(sync_client_);
- DCHECK(model_cryptographer_);
-}
-
-} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h b/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h
deleted file mode 100644
index 67c5171643b..00000000000
--- a/chromium/components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_
-#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_
-
-#include <memory>
-
-#include "base/callback_forward.h"
-#include "base/macros.h"
-#include "components/sync/driver/non_ui_syncable_service_based_model_type_controller.h"
-#include "components/sync/driver/sync_service_observer.h"
-
-namespace syncer {
-class SyncClient;
-class SyncService;
-} // namespace syncer
-
-namespace password_manager {
-
-class PasswordStore;
-
-// A class that manages the startup and shutdown of password sync.
-class PasswordSyncableServiceBasedModelTypeController
- : public syncer::NonUiSyncableServiceBasedModelTypeController,
- public syncer::SyncServiceObserver {
- public:
- // |password_store| must not be null and is used to persist the encrypted
- // copy of sync's data and metadata, sync-ed with |password_store|.
- // |dump_stack| is called when a unrecoverable error occurs. |sync_client|
- // must not be null.
- PasswordSyncableServiceBasedModelTypeController(
- syncer::OnceModelTypeStoreFactory store_factory,
- const base::RepeatingClosure& dump_stack,
- scoped_refptr<PasswordStore> password_store,
- syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client);
- ~PasswordSyncableServiceBasedModelTypeController() override;
-
- // DataTypeController overrides.
- void LoadModels(const syncer::ConfigureContext& configure_context,
- const ModelLoadCallback& model_load_callback) override;
- void Stop(syncer::ShutdownReason shutdown_reason,
- StopCallback callback) override;
- std::unique_ptr<syncer::SyncEncryptionHandler::Observer>
- GetEncryptionObserverProxy() override;
-
- // SyncServiceObserver overrides.
- void OnStateChanged(syncer::SyncService* sync) override;
-
- private:
- class ModelCryptographerImpl;
-
- // Constructor overload to make sure |ModelCryptographerImpl| gets constructed
- // before the base class.
- PasswordSyncableServiceBasedModelTypeController(
- syncer::OnceModelTypeStoreFactory store_factory,
- const base::RepeatingClosure& dump_stack,
- scoped_refptr<PasswordStore> password_store,
- syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client,
- scoped_refptr<ModelCryptographerImpl> model_cryptographer);
-
- const scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
- const scoped_refptr<ModelCryptographerImpl> model_cryptographer_;
- syncer::SyncService* const sync_service_;
- syncer::SyncClient* const sync_client_;
-
- DISALLOW_COPY_AND_ASSIGN(PasswordSyncableServiceBasedModelTypeController);
-};
-
-} // namespace password_manager
-
-#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SYNC_PASSWORD_SYNCABLE_SERVICE_BASED_MODEL_TYPE_CONTROLLER_H_
diff --git a/chromium/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc b/chromium/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
index 5088b717cf4..502c4387685 100644
--- a/chromium/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
+++ b/chromium/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/components/password_manager/core/browser/sync_credentials_filter.cc b/chromium/components/password_manager/core/browser/sync_credentials_filter.cc
index f8390243dc0..963ec6d34a3 100644
--- a/chromium/components/password_manager/core/browser/sync_credentials_filter.cc
+++ b/chromium/components/password_manager/core/browser/sync_credentials_filter.cc
@@ -21,24 +21,6 @@ using autofill::PasswordForm;
namespace password_manager {
-namespace {
-
-// Returns true if the last loaded page was for transactional re-auth on a
-// Google property.
-bool LastLoadWasTransactionalReauthPage(const GURL& last_load_url) {
- if (last_load_url.GetOrigin() !=
- GaiaUrls::GetInstance()->gaia_url().GetOrigin())
- return false;
-
- // TODO(crbug.com/543085): GAIA stops using the "rart" URL param, and instead
- // includes a hidden form field with name "rart". "rart" is the transactional
- // reauth paramter.
- std::string ignored_value;
- return net::GetValueForKeyInQuery(last_load_url, "rart", &ignored_value);
-}
-
-} // namespace
-
SyncCredentialsFilter::SyncCredentialsFilter(
const PasswordManagerClient* client,
SyncServiceFactoryFunction sync_service_factory_function,
@@ -49,32 +31,6 @@ SyncCredentialsFilter::SyncCredentialsFilter(
SyncCredentialsFilter::~SyncCredentialsFilter() {}
-std::vector<std::unique_ptr<PasswordForm>> SyncCredentialsFilter::FilterResults(
- std::vector<std::unique_ptr<PasswordForm>> results) const {
- const AutofillForSyncCredentialsState autofill_sync_state =
- GetAutofillForSyncCredentialsState();
-
- if (autofill_sync_state != DISALLOW_SYNC_CREDENTIALS &&
- (autofill_sync_state != DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH ||
- !LastLoadWasTransactionalReauthPage(
- client_->GetLastCommittedEntryURL()))) {
- return results;
- }
-
- auto begin_of_removed =
- std::partition(results.begin(), results.end(),
- [this](const std::unique_ptr<PasswordForm>& form) {
- return ShouldSave(*form);
- });
-
- UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
- begin_of_removed != results.end());
-
- results.erase(begin_of_removed, results.end());
-
- return results;
-}
-
bool SyncCredentialsFilter::ShouldSave(
const autofill::PasswordForm& form) const {
return !client_->IsIncognito() &&
@@ -118,37 +74,4 @@ void SyncCredentialsFilter::ReportFormLoginSuccess(
}
}
-// static
-SyncCredentialsFilter::AutofillForSyncCredentialsState
-SyncCredentialsFilter::GetAutofillForSyncCredentialsState() {
- bool protect_sync_credential_enabled =
- base::FeatureList::IsEnabled(features::kProtectSyncCredential);
- bool protect_sync_credential_on_reauth_enabled =
- base::FeatureList::IsEnabled(features::kProtectSyncCredentialOnReauth);
-
- if (protect_sync_credential_enabled) {
- if (protect_sync_credential_on_reauth_enabled) {
- // Both the features are enabled, do not ever fill the sync credential.
- return DISALLOW_SYNC_CREDENTIALS;
- }
-
- // Only 'ProtectSyncCredentialOnReauth' feature is kept disabled. This
- // is "illegal", emit a warning and do not ever fill the sync credential.
- LOG(WARNING) << "This is illegal! Feature "
- "'ProtectSyncCredentialOnReauth' cannot be kept "
- "disabled if 'protect-sync-credential' feature is enabled. "
- "We shall not ever fill the sync credential is such cases.";
- return DISALLOW_SYNC_CREDENTIALS;
- }
-
- if (protect_sync_credential_on_reauth_enabled) {
- // Only 'ProtectSyncCredentialOnReauth' feature is kept enabled, fill
- // the sync credential everywhere but on reauth.
- return DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
- }
-
- // Both the features are disabled, fill the sync credential everywhere.
- return ALLOW_SYNC_CREDENTIALS;
-}
-
} // namespace password_manager
diff --git a/chromium/components/password_manager/core/browser/sync_credentials_filter.h b/chromium/components/password_manager/core/browser/sync_credentials_filter.h
index c1f08a7fb33..09bfe3b63f1 100644
--- a/chromium/components/password_manager/core/browser/sync_credentials_filter.h
+++ b/chromium/components/password_manager/core/browser/sync_credentials_filter.h
@@ -41,9 +41,6 @@ class SyncCredentialsFilter : public CredentialsFilter {
~SyncCredentialsFilter() override;
// CredentialsFilter
- std::vector<std::unique_ptr<autofill::PasswordForm>> FilterResults(
- std::vector<std::unique_ptr<autofill::PasswordForm>> results)
- const override;
bool ShouldSave(const autofill::PasswordForm& form) const override;
bool ShouldSaveGaiaPasswordHash(
const autofill::PasswordForm& form) const override;
@@ -54,15 +51,6 @@ class SyncCredentialsFilter : public CredentialsFilter {
bool IsSyncAccountEmail(const std::string& username) const override;
private:
- enum AutofillForSyncCredentialsState {
- ALLOW_SYNC_CREDENTIALS,
- DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH,
- DISALLOW_SYNC_CREDENTIALS,
- };
-
- // Determines autofill state based on experiment and flag values.
- static AutofillForSyncCredentialsState GetAutofillForSyncCredentialsState();
-
const PasswordManagerClient* const client_;
const SyncServiceFactoryFunction sync_service_factory_function_;
diff --git a/chromium/components/password_manager/core/browser/sync_credentials_filter_unittest.cc b/chromium/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
index 925aad8a6b9..a6ea8318f8b 100644
--- a/chromium/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
+++ b/chromium/components/password_manager/core/browser/sync_credentials_filter_unittest.cc
@@ -15,9 +15,7 @@
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/metrics/histogram_tester.h"
#include "base/test/metrics/user_action_tester.h"
-#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/fake_form_fetcher.h"
#include "components/password_manager/core/browser/mock_password_store.h"
@@ -30,7 +28,6 @@
#include "components/password_manager/core/common/password_manager_features.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"
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
@@ -50,19 +47,6 @@ const char kFilledAndLoginActionName[] =
const char kEnterpriseURL[] = "https://enterprise.test/";
#endif // SYNC_PASSWORD_REUSE_DETECTION_ENABLED
-void DisallowSyncOnReauth(base::test::ScopedFeatureList* feature_list) {
- feature_list->InitFromCommandLine(
- features::kProtectSyncCredentialOnReauth.name,
- features::kProtectSyncCredential.name);
-}
-
-void DisallowSync(base::test::ScopedFeatureList* feature_list) {
- feature_list->InitFromCommandLine(
- features::kProtectSyncCredential.name + std::string(",") +
- features::kProtectSyncCredentialOnReauth.name,
- std::string());
-}
-
class FakePasswordManagerClient : public StubPasswordManagerClient {
public:
FakePasswordManagerClient()
@@ -114,25 +98,10 @@ class FakePasswordManagerClient : public StubPasswordManagerClient {
DISALLOW_COPY_AND_ASSIGN(FakePasswordManagerClient);
};
-bool IsFormFiltered(const CredentialsFilter* filter, const PasswordForm& form) {
- std::vector<std::unique_ptr<PasswordForm>> vector;
- vector.push_back(std::make_unique<PasswordForm>(form));
- vector = filter->FilterResults(std::move(vector));
- return vector.empty();
-}
-
} // namespace
class CredentialsFilterTest : public SyncUsernameTestBase {
public:
- struct TestCase {
- enum { SYNCING_PASSWORDS, NOT_SYNCING_PASSWORDS } password_sync;
- PasswordForm form;
- const char* const last_committed_entry_url;
- enum { FORM_FILTERED, FORM_NOT_FILTERED } is_form_filtered;
- enum { NO_HISTOGRAM, HISTOGRAM_REPORTED } histogram_reported;
- };
-
// Flag for creating a PasswordFormManager, deciding its IsNewLogin() value.
enum class LoginState { NEW, EXISTING };
@@ -154,24 +123,6 @@ class CredentialsFilterTest : public SyncUsernameTestBase {
fetcher_.Fetch();
}
- void CheckFilterResultsTestCase(const TestCase& test_case) {
- DCHECK(identity_manager()->HasPrimaryAccount());
-
- SetSyncingPasswords(test_case.password_sync == TestCase::SYNCING_PASSWORDS);
- client_.set_last_committed_entry_url(test_case.last_committed_entry_url);
- base::HistogramTester tester;
- const bool expected_is_form_filtered =
- test_case.is_form_filtered == TestCase::FORM_FILTERED;
- EXPECT_EQ(expected_is_form_filtered,
- IsFormFiltered(&filter_, test_case.form));
- if (test_case.histogram_reported == TestCase::HISTOGRAM_REPORTED) {
- tester.ExpectUniqueSample("PasswordManager.SyncCredentialFiltered",
- expected_is_form_filtered, 1);
- } else {
- tester.ExpectTotalCount("PasswordManager.SyncCredentialFiltered", 0);
- }
- }
-
// Makes |form_manager_| provisionally save |pending_|. Depending on
// |login_state| being NEW or EXISTING, prepares |form_manager_| in a state in
// which |pending_| looks like a new or existing credential, respectively.
@@ -196,149 +147,6 @@ class CredentialsFilterTest : public SyncUsernameTestBase {
SyncCredentialsFilter filter_;
};
-TEST_F(CredentialsFilterTest, FilterResults_AllowAll_NonSyncingAccount) {
- FakeSigninAs("another_user@example.org");
-
- CheckFilterResultsTestCase(
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_NOT_FILTERED, TestCase::NO_HISTOGRAM});
-}
-
-TEST_F(CredentialsFilterTest, FilterResults_AllowAll_SyncingAccount) {
- FakeSigninAs("user@example.org");
-
- // By default, sync username is not filtered at all.
- const TestCase kTestCases[] = {
- // Reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_NOT_FILTERED, TestCase::NO_HISTOGRAM},
-
- // Slightly invalid reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/addlogin?rart", // Missing rart value.
- TestCase::FORM_NOT_FILTERED, TestCase::NO_HISTOGRAM},
-
- // Non-reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?param=123",
- TestCase::FORM_NOT_FILTERED, TestCase::NO_HISTOGRAM},
-
- // Non-GAIA "reauth" URL.
- {TestCase::SYNCING_PASSWORDS, SimpleNonGaiaForm("user@example.org"),
- "https://site.com/login?rart=678", TestCase::FORM_NOT_FILTERED,
- TestCase::NO_HISTOGRAM},
- };
-
- for (size_t i = 0; i < base::size(kTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "i=" << i);
- CheckFilterResultsTestCase(kTestCases[i]);
- }
-}
-
-TEST_F(CredentialsFilterTest,
- FilterResults_DisallowSyncOnReauth_NonSyncingAccount) {
- FakeSigninAs("another_user@example.org");
-
- // Only 'ProtectSyncCredentialOnReauth' feature is kept enabled, fill the
- // sync credential everywhere but on reauth.
- base::test::ScopedFeatureList scoped_feature_list;
- DisallowSyncOnReauth(&scoped_feature_list);
-
- CheckFilterResultsTestCase(
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_NOT_FILTERED, TestCase::HISTOGRAM_REPORTED});
-}
-
-TEST_F(CredentialsFilterTest,
- FilterResults_DisallowSyncOnReauth_SyncingAccount) {
- FakeSigninAs("user@example.org");
-
- // Only 'ProtectSyncCredentialOnReauth' feature is kept enabled, fill the
- // sync credential everywhere but on reauth.
- base::test::ScopedFeatureList scoped_feature_list;
- DisallowSyncOnReauth(&scoped_feature_list);
-
- const TestCase kTestCases[] = {
- // Reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_FILTERED, TestCase::HISTOGRAM_REPORTED},
-
- // Slightly invalid reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/addlogin?rart", // Missing rart value.
- TestCase::FORM_FILTERED, TestCase::HISTOGRAM_REPORTED},
-
- // Non-reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?param=123",
- TestCase::FORM_NOT_FILTERED, TestCase::NO_HISTOGRAM},
-
- // Non-GAIA "reauth" URL.
- {TestCase::SYNCING_PASSWORDS, SimpleNonGaiaForm("user@example.org"),
- "https://site.com/login?rart=678", TestCase::FORM_NOT_FILTERED,
- TestCase::NO_HISTOGRAM},
- };
-
- for (size_t i = 0; i < base::size(kTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "i=" << i);
- CheckFilterResultsTestCase(kTestCases[i]);
- }
-}
-
-TEST_F(CredentialsFilterTest, FilterResults_DisallowSync_NonSyncingAccount) {
- FakeSigninAs("another_user@example.org");
-
- // Both features are kept enabled, should cause sync credential to be
- // filtered.
- base::test::ScopedFeatureList scoped_feature_list;
- DisallowSync(&scoped_feature_list);
-
- CheckFilterResultsTestCase(
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_NOT_FILTERED, TestCase::HISTOGRAM_REPORTED});
-}
-
-TEST_F(CredentialsFilterTest, FilterResults_DisallowSync_SyncingAccount) {
- FakeSigninAs("user@example.org");
-
- // Both features are kept enabled, should cause sync credential to be
- // filtered.
- base::test::ScopedFeatureList scoped_feature_list;
- DisallowSync(&scoped_feature_list);
-
- const TestCase kTestCases[] = {
- // Reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?rart=123&continue=blah",
- TestCase::FORM_FILTERED, TestCase::HISTOGRAM_REPORTED},
-
- // Slightly invalid reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/addlogin?rart", // Missing rart value.
- TestCase::FORM_FILTERED, TestCase::HISTOGRAM_REPORTED},
-
- // Non-reauth URL.
- {TestCase::SYNCING_PASSWORDS, SimpleGaiaForm("user@example.org"),
- "https://accounts.google.com/login?param=123", TestCase::FORM_FILTERED,
- TestCase::HISTOGRAM_REPORTED},
-
- // Non-GAIA "reauth" URL.
- {TestCase::SYNCING_PASSWORDS, SimpleNonGaiaForm("user@example.org"),
- "https://site.com/login?rart=678", TestCase::FORM_NOT_FILTERED,
- TestCase::HISTOGRAM_REPORTED},
- };
-
- for (size_t i = 0; i < base::size(kTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "i=" << i);
- CheckFilterResultsTestCase(kTestCases[i]);
- }
-}
-
TEST_F(CredentialsFilterTest, ReportFormLoginSuccess_ExistingSyncCredentials) {
FakeSigninAs("user@gmail.com");
SetSyncingPasswords(true);
@@ -425,26 +233,6 @@ TEST_F(CredentialsFilterTest, ShouldSave_SyncCredential_NotSyncingPasswords) {
EXPECT_TRUE(filter_.ShouldSave(form));
}
-TEST_F(CredentialsFilterTest, ShouldFilterOneForm) {
- // Both features are kept enabled, should cause sync credential to be
- // filtered.
- base::test::ScopedFeatureList scoped_feature_list;
- DisallowSync(&scoped_feature_list);
-
- std::vector<std::unique_ptr<PasswordForm>> results;
- results.push_back(
- std::make_unique<PasswordForm>(SimpleGaiaForm("test1@gmail.com")));
- results.push_back(
- std::make_unique<PasswordForm>(SimpleGaiaForm("test2@gmail.com")));
-
- FakeSigninAs("test1@gmail.com");
-
- results = filter_.FilterResults(std::move(results));
-
- ASSERT_EQ(1u, results.size());
- EXPECT_EQ(SimpleGaiaForm("test2@gmail.com"), *results[0]);
-}
-
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
TEST_F(CredentialsFilterTest, ShouldSaveGaiaPasswordHash) {
PasswordForm gaia_form = SimpleGaiaForm("user@gmail.org");
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 d6d88485f4e..80ba9bd04df 100644
--- a/chromium/components/password_manager/core/browser/test_password_store.cc
+++ b/chromium/components/password_manager/core/browser/test_password_store.cc
@@ -220,9 +220,10 @@ bool TestPasswordStore::CommitTransaction() {
return true;
}
-bool TestPasswordStore::ReadAllLogins(PrimaryKeyToFormMap* key_to_form_map) {
+FormRetrievalResult TestPasswordStore::ReadAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) {
NOTIMPLEMENTED();
- return true;
+ return FormRetrievalResult::kSuccess;
}
PasswordStoreChangeList TestPasswordStore::RemoveLoginByPrimaryKeySync(
@@ -231,7 +232,8 @@ PasswordStoreChangeList TestPasswordStore::RemoveLoginByPrimaryKeySync(
return PasswordStoreChangeList();
}
-syncer::SyncMetadataStore* TestPasswordStore::GetMetadataStore() {
+PasswordStoreSync::MetadataStore* TestPasswordStore::GetMetadataStore() {
+ NOTIMPLEMENTED();
return nullptr;
}
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 a7c6d71bb83..ba764c4e757 100644
--- a/chromium/components/password_manager/core/browser/test_password_store.h
+++ b/chromium/components/password_manager/core/browser/test_password_store.h
@@ -90,9 +90,10 @@ class TestPasswordStore : public PasswordStore {
// PasswordStoreSync interface.
bool BeginTransaction() override;
bool CommitTransaction() override;
- bool ReadAllLogins(PrimaryKeyToFormMap* key_to_form_map) override;
+ FormRetrievalResult ReadAllLogins(
+ PrimaryKeyToFormMap* key_to_form_map) override;
PasswordStoreChangeList RemoveLoginByPrimaryKeySync(int primary_key) override;
- syncer::SyncMetadataStore* GetMetadataStore() override;
+ PasswordStoreSync::MetadataStore* GetMetadataStore() override;
private:
PasswordMap stored_passwords_;
diff --git a/chromium/components/password_manager/core/browser/votes_uploader.cc b/chromium/components/password_manager/core/browser/votes_uploader.cc
index b52b9cd206a..334955d36d2 100644
--- a/chromium/components/password_manager/core/browser/votes_uploader.cc
+++ b/chromium/components/password_manager/core/browser/votes_uploader.cc
@@ -155,8 +155,8 @@ void VotesUploader::SendVotesOnSave(
if (pending_credentials->times_used == 0) {
UploadPasswordVote(*pending_credentials, submitted_form, autofill::PASSWORD,
std::string());
- if (has_username_correction_vote_) {
- UploadPasswordVote(username_correction_vote_, submitted_form,
+ if (username_correction_vote_) {
+ UploadPasswordVote(*username_correction_vote_, submitted_form,
autofill::USERNAME,
FormStructure(observed).FormSignatureAsStr());
}
@@ -448,13 +448,12 @@ void VotesUploader::SetKnownValueFlag(
bool VotesUploader::FindUsernameInOtherPossibleUsernames(
const PasswordForm& match,
const base::string16& username) {
- DCHECK(!has_username_correction_vote_);
+ DCHECK(!username_correction_vote_);
for (const ValueElementPair& pair : match.other_possible_usernames) {
if (pair.first == username) {
username_correction_vote_ = match;
- username_correction_vote_.username_element = pair.second;
- has_username_correction_vote_ = true;
+ username_correction_vote_->username_element = pair.second;
return true;
}
}
diff --git a/chromium/components/password_manager/core/browser/votes_uploader.h b/chromium/components/password_manager/core/browser/votes_uploader.h
index a8318d18bf2..c02d45d12a7 100644
--- a/chromium/components/password_manager/core/browser/votes_uploader.h
+++ b/chromium/components/password_manager/core/browser/votes_uploader.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/strings/string16.h"
+#include "base/optional.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/proto/server.pb.h"
#include "components/autofill/core/common/password_form.h"
@@ -173,13 +174,11 @@ class VotesUploader {
// If the user typed username that doesn't match any saved credentials, but
// matches an entry from |other_possible_usernames| of a saved credential,
- // then |has_username_correction_vote_| is set to true and
- // |username_correction_vote_| stores the credential with matched username.
+ // |username_correction_vote_| stores the credential with matched username.
// The matched credential is copied to |username_correction_vote_|, but
// |username_correction_vote_.username_element| is set to the name of the
- // field where matched username was found.
- bool has_username_correction_vote_ = false;
- autofill::PasswordForm username_correction_vote_;
+ // field where the matched username was found.
+ base::Optional<autofill::PasswordForm> username_correction_vote_;
// Whether the password values have been shown to the user on the save prompt.
bool has_passwords_revealed_vote_ = false;
diff --git a/chromium/components/password_manager/core/browser/votes_uploader_unittest.cc b/chromium/components/password_manager/core/browser/votes_uploader_unittest.cc
index e073296d726..cbe12bfa800 100644
--- a/chromium/components/password_manager/core/browser/votes_uploader_unittest.cc
+++ b/chromium/components/password_manager/core/browser/votes_uploader_unittest.cc
@@ -97,7 +97,7 @@ class VotesUploaderTest : public testing::Test {
protected:
base::string16 GetFieldNameByIndex(size_t index) {
- return ASCIIToUTF16("field") + base::UintToString16(index);
+ return ASCIIToUTF16("field") + base::NumberToString16(index);
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
diff --git a/chromium/components/password_manager/core/common/credential_manager_types.cc b/chromium/components/password_manager/core/common/credential_manager_types.cc
index d9f9a74e986..f5fa75fb42c 100644
--- a/chromium/components/password_manager/core/common/credential_manager_types.cc
+++ b/chromium/components/password_manager/core/common/credential_manager_types.cc
@@ -20,7 +20,7 @@ std::string CredentialTypeToString(CredentialType value) {
return "CredentialType::CREDENTIAL_TYPE_FEDERATED";
}
return "Unknown CredentialType value: " +
- base::IntToString(static_cast<int>(value));
+ base::NumberToString(static_cast<int>(value));
}
std::ostream& operator<<(std::ostream& os, CredentialType value) {
diff --git a/chromium/components/password_manager/core/common/password_manager_features.cc b/chromium/components/password_manager/core/common/password_manager_features.cc
index 86209a55322..8c0e968788e 100644
--- a/chromium/components/password_manager/core/common/password_manager_features.cc
+++ b/chromium/components/password_manager/core/common/password_manager_features.cc
@@ -6,6 +6,8 @@
namespace password_manager {
+// NOTE: It is strongly recommended to use UpperCamelCase style for feature
+// names, e.g. "MyGreatFeature".
namespace features {
// Enable affiliation based matching, so that credentials stored for an Android
@@ -14,6 +16,11 @@ namespace features {
const base::Feature kAffiliationBasedMatching = {
"AffiliationBasedMatching", base::FEATURE_ENABLED_BY_DEFAULT};
+// Enables the editing of passwords in chrome://settings/passwords, i.e. the
+// Desktop passwords settings page.
+const base::Feature kEditPasswordsInDesktopSettings = {
+ "EditPasswordsInDesktopSettings", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Recovers lost passwords on Mac by deleting the ones that cannot be decrypted
// with the present encryption key from the Keychain.
const base::Feature kDeleteCorruptedPasswords = {
@@ -29,15 +36,6 @@ const base::Feature kPasswordGenerationRequirementsDomainOverrides = {
"PasswordGenerationRequirementsDomainOverrides",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Disallow autofilling of the sync credential.
-const base::Feature kProtectSyncCredential = {
- "protect-sync-credential", base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Disallow autofilling of the sync credential only for transactional reauth
-// pages.
-const base::Feature kProtectSyncCredentialOnReauth = {
- "ProtectSyncCredentialOnReauth", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Controls the ability to import passwords from Chrome's settings page.
const base::Feature kPasswordImport = {"PasswordImport",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -80,6 +78,11 @@ const base::Feature kNewPasswordFormParsingForSaving = {
const base::Feature kOnlyNewParser = {"only-new-password-form-parsing",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether to offer manual password generation in the accessory sheet
+// on Android.
+const base::Feature kManualPasswordGenerationAndroid{
+ "ManualPasswordGenerationAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Performs a one-off migration (with retries) from a native backend into
// logindb. Passwords are served from the new location.
const base::Feature kMigrateLinuxToLoginDB = {
diff --git a/chromium/components/password_manager/core/common/password_manager_features.h b/chromium/components/password_manager/core/common/password_manager_features.h
index 59ae47e4499..c0e0db5a3ce 100644
--- a/chromium/components/password_manager/core/common/password_manager_features.h
+++ b/chromium/components/password_manager/core/common/password_manager_features.h
@@ -18,20 +18,20 @@ namespace features {
// alongside the definition of their values in the .cc file.
extern const base::Feature kAffiliationBasedMatching;
+extern const base::Feature kEditPasswordsInDesktopSettings;
extern const base::Feature kDeleteCorruptedPasswords;
extern const base::Feature kHtmlBasedUsernameDetector;
extern const base::Feature kPasswordGenerationRequirementsDomainOverrides;
extern const base::Feature kFillOnAccountSelect;
extern const base::Feature kFillOnAccountSelectHttp;
extern const base::Feature kGooglePasswordManager;
+extern const base::Feature kManualPasswordGenerationAndroid;
extern const base::Feature kMigrateLinuxToLoginDB;
extern const base::Feature kNewPasswordFormParsing;
extern const base::Feature kNewPasswordFormParsingForSaving;
extern const base::Feature kOnlyNewParser;
extern const base::Feature kPasswordImport;
extern const base::Feature kPasswordsKeyboardAccessory;
-extern const base::Feature kProtectSyncCredential;
-extern const base::Feature kProtectSyncCredentialOnReauth;
extern const base::Feature kRecoverPasswordsForSyncUsers;
// Field trial and corresponding parameters.
diff --git a/chromium/components/password_manager/core/common/passwords_directory_util_ios.cc b/chromium/components/password_manager/core/common/passwords_directory_util_ios.cc
index 9bc99e88bf4..c27880de5fe 100644
--- a/chromium/components/password_manager/core/common/passwords_directory_util_ios.cc
+++ b/chromium/components/password_manager/core/common/passwords_directory_util_ios.cc
@@ -16,7 +16,8 @@ namespace password_manager {
namespace {
// Synchronously deletes passwords directoy.
void DeletePasswordsDirectorySync() {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::FilePath downloads_directory;
if (GetPasswordsDirectory(&downloads_directory)) {
// It is assumed that deleting the directory always succeeds.
diff --git a/chromium/components/password_manager/ios/password_form_helper.h b/chromium/components/password_manager/ios/password_form_helper.h
index f6df76fe2de..f74c69a97fe 100644
--- a/chromium/components/password_manager/ios/password_form_helper.h
+++ b/chromium/components/password_manager/ios/password_form_helper.h
@@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
namespace autofill {
struct PasswordForm;
struct PasswordFormFillData;
+struct FormData;
} // namespace autofill
namespace password_manager {
@@ -89,6 +90,14 @@ class WebState;
completionHandler:
(nullable void (^)(BOOL))completionHandler;
+// Finds the password form named |formName| and calls
+// |completionHandler| with the populated |FormData| data structure. |found| is
+// YES if the current form was found successfully, NO otherwise.
+- (void)extractPasswordFormData:(NSString*)formName
+ completionHandler:
+ (void (^)(BOOL found,
+ const autofill::FormData& form))completionHandler;
+
// Creates a instance with the given WebState, observer and delegate.
- (instancetype)initWithWebState:(web::WebState*)webState
delegate:
diff --git a/chromium/components/password_manager/ios/password_form_helper.mm b/chromium/components/password_manager/ios/password_form_helper.mm
index dad1a809137..82dcf3fb000 100644
--- a/chromium/components/password_manager/ios/password_form_helper.mm
+++ b/chromium/components/password_manager/ios/password_form_helper.mm
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/bind.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "components/autofill/core/common/form_data.h"
@@ -423,4 +424,43 @@ constexpr char kCommandPrefix[] = "passwordForm";
}];
}
+// Finds the password form named |formName| and calls
+// |completionHandler| with the populated |FormData| data structure. |found| is
+// YES if the current form was found successfully, NO otherwise.
+- (void)extractPasswordFormData:(NSString*)formName
+ completionHandler:(void (^)(BOOL found, const FormData& form))
+ completionHandler {
+ DCHECK(completionHandler);
+
+ if (!_webState) {
+ return;
+ }
+
+ GURL pageURL;
+ if (!GetPageURLAndCheckTrustLevel(_webState, &pageURL)) {
+ completionHandler(NO, FormData());
+ return;
+ }
+
+ id extractFormDataCompletionHandler = ^(NSString* jsonString) {
+ std::unique_ptr<base::Value> formValue = autofill::ParseJson(jsonString);
+ if (!formValue) {
+ completionHandler(NO, FormData());
+ return;
+ }
+
+ FormData formData;
+ if (!autofill::ExtractFormData(*formValue, false, base::string16(), pageURL,
+ pageURL.GetOrigin(), &formData)) {
+ completionHandler(NO, FormData());
+ return;
+ }
+
+ completionHandler(YES, formData);
+ };
+
+ [self.jsPasswordManager extractForm:formName
+ completionHandler:extractFormDataCompletionHandler];
+}
+
@end
diff --git a/chromium/components/password_manager/ios/password_form_helper_unittest.mm b/chromium/components/password_manager/ios/password_form_helper_unittest.mm
index cec663fbd7f..b7e21338f15 100644
--- a/chromium/components/password_manager/ios/password_form_helper_unittest.mm
+++ b/chromium/components/password_manager/ios/password_form_helper_unittest.mm
@@ -10,6 +10,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/ios/wait_util.h"
+#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/password_manager/core/browser/log_manager.h"
#include "components/password_manager/core/browser/stub_password_manager_client.h"
@@ -30,6 +31,7 @@
NS_ASSUME_NONNULL_BEGIN
+using autofill::FormData;
using autofill::PasswordForm;
using autofill::PasswordFormFillData;
using base::test::ios::kWaitForJSCompletionTimeout;
@@ -733,6 +735,53 @@ TEST_F(PasswordFormHelperTest, FindAndFillMultiplePasswordForms) {
result);
}
+// Tests that extractPasswordFormData extracts wanted form on page with mutiple
+// forms.
+TEST_F(PasswordFormHelperTest, ExtractPasswordFormData) {
+ MockJsPasswordManager* mockJsPasswordManager = [[MockJsPasswordManager alloc]
+ initWithReceiver:web_state()->GetJSInjectionReceiver()];
+ [helper_ setJsPasswordManager:mockJsPasswordManager];
+ LoadHtml(@"<form><input id='u1' type='text' name='un1'>"
+ "<input id='p1' type='password' name='pw1'></form>"
+ "<form><input id='u2' type='text' name='un2'>"
+ "<input id='p2' type='password' name='pw2'></form>"
+ "<form><input id='u3' type='text' name='un3'>"
+ "<input id='p3' type='password' name='pw3'></form>");
+ __block int call_counter = 0;
+ __block int success_counter = 0;
+ __block FormData result = FormData();
+ [helper_ extractPasswordFormData:base::SysUTF8ToNSString(GetFormId(1))
+ completionHandler:^(BOOL complete, const FormData& form) {
+ ++call_counter;
+ if (complete) {
+ ++success_counter;
+ result = form;
+ }
+ }];
+ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{
+ return call_counter == 1;
+ }));
+ EXPECT_EQ(1, success_counter);
+ EXPECT_EQ(result.name, base::ASCIIToUTF16(GetFormId(1)));
+
+ call_counter = 0;
+ success_counter = 0;
+ result = FormData();
+
+ [helper_ extractPasswordFormData:@"unknown"
+ completionHandler:^(BOOL complete, const FormData& form) {
+ ++call_counter;
+ if (complete) {
+ ++success_counter;
+ result = form;
+ }
+ }];
+ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{
+ return call_counter == 1;
+ }));
+ EXPECT_EQ(0, success_counter);
+}
+
} // namespace
NS_ASSUME_NONNULL_END
diff --git a/chromium/components/password_manager/ios/resources/password_controller.js b/chromium/components/password_manager/ios/resources/password_controller.js
index 6ec544fd9f1..7599dc17fc3 100644
--- a/chromium/components/password_manager/ios/resources/password_controller.js
+++ b/chromium/components/password_manager/ios/resources/password_controller.js
@@ -210,7 +210,7 @@ __gCrWeb.passwords['fillPasswordForm'] = function(
* @param {string} confirmPasswordIdentifier The id of confirm password element
* to fill.
* @param {string} password The password to fill.
- * @return {boolean} Whether a password field has been filled.
+ * @return {boolean} Whether new password field has been filled.
*/
__gCrWeb.passwords['fillPasswordFormWithGeneratedPassword'] = function(
formName, newPasswordIdentifier, confirmPasswordIdentifier, password) {
@@ -220,15 +220,18 @@ __gCrWeb.passwords['fillPasswordFormWithGeneratedPassword'] = function(
var inputs = getFormInputElements_(form);
var newPasswordField =
findInputByFieldIdentifier_(inputs, newPasswordIdentifier);
- if (newPasswordField) {
- newPasswordField.value = password;
+ if (!newPasswordField)
+ return false;
+ // Avoid resetting if same value, as it moves cursor to the end.
+ if (newPasswordField.value != password) {
+ __gCrWeb.fill.setInputElementValue(password, newPasswordField);
}
var confirmPasswordField =
findInputByFieldIdentifier_(inputs, confirmPasswordIdentifier);
- if (confirmPasswordField) {
- confirmPasswordField.value = password;
+ if (confirmPasswordField && confirmPasswordField.value != password) {
+ __gCrWeb.fill.setInputElementValue(password, confirmPasswordField);
}
- return !!newPasswordField || !!confirmPasswordField;
+ return true;
};
/**
@@ -271,19 +274,12 @@ var fillPasswordFormWithData_ = function(
// requested username, fill the form.
if (usernameInput.readOnly) {
if (usernameInput.value == username) {
- passwordInput.value = password;
+ __gCrWeb.fill.setInputElementValue(password, passwordInput);
filled = true;
}
} else {
- // Setting input fields via .value assignment does not trigger all
- // the events that a web site can observe. This has the effect of
- // certain web sites rejecting an autofilled sign in form as not
- // signed in because the user didn't actually "typed" into the field.
- // Adding the .focus() works around this problems.
- usernameInput.focus();
- usernameInput.value = username;
- passwordInput.focus();
- passwordInput.value = password;
+ __gCrWeb.fill.setInputElementValue(username, usernameInput);
+ __gCrWeb.fill.setInputElementValue(password, passwordInput);
filled = true;
}
}
diff --git a/chromium/components/payments/content/BUILD.gn b/chromium/components/payments/content/BUILD.gn
index 0ac86834c8f..0c55166d4cf 100644
--- a/chromium/components/payments/content/BUILD.gn
+++ b/chromium/components/payments/content/BUILD.gn
@@ -9,6 +9,8 @@ jumbo_static_library("content") {
"can_make_payment_query_factory.cc",
"can_make_payment_query_factory.h",
"content_payment_request_delegate.h",
+ "initialization_task.cc",
+ "initialization_task.h",
"payment_request.cc",
"payment_request.h",
"payment_request_converter.cc",
diff --git a/chromium/components/payments/content/android/payment_manifest_downloader_android.cc b/chromium/components/payments/content/android/payment_manifest_downloader_android.cc
index 519a45ab55c..9c64a430068 100644
--- a/chromium/components/payments/content/android/payment_manifest_downloader_android.cc
+++ b/chromium/components/payments/content/android/payment_manifest_downloader_android.cc
@@ -8,6 +8,7 @@
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
#include "components/payments/content/developer_console_logger.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
diff --git a/chromium/components/payments/content/content_payment_request_delegate.h b/chromium/components/payments/content/content_payment_request_delegate.h
index efa368aadfa..ac5c967548a 100644
--- a/chromium/components/payments/content/content_payment_request_delegate.h
+++ b/chromium/components/payments/content/content_payment_request_delegate.h
@@ -36,6 +36,10 @@ class ContentPaymentRequestDelegate : public PaymentRequestDelegate {
virtual void EmbedPaymentHandlerWindow(
const GURL& url,
PaymentHandlerOpenWindowCallback callback) = 0;
+
+ // Returns whether user interaction is enabled. (False when showing a
+ // spinner.)
+ virtual bool IsInteractive() const = 0;
};
} // namespace payments
diff --git a/chromium/components/payments/content/initialization_task.cc b/chromium/components/payments/content/initialization_task.cc
new file mode 100644
index 00000000000..900cc000715
--- /dev/null
+++ b/chromium/components/payments/content/initialization_task.cc
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/payments/content/initialization_task.h"
+
+namespace payments {
+
+InitializationTask::Observer::~Observer() = default;
+
+InitializationTask::InitializationTask() = default;
+
+InitializationTask::~InitializationTask() = default;
+
+void InitializationTask::AddInitializationObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void InitializationTask::RemoveInitializationObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void InitializationTask::NotifyInitialized() {
+ DCHECK(!has_notified_);
+ has_notified_ = true;
+ for (Observer& observer : observers_) {
+ observer.OnInitialized(this);
+ }
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/content/initialization_task.h b/chromium/components/payments/content/initialization_task.h
new file mode 100644
index 00000000000..16c094ca0dd
--- /dev/null
+++ b/chromium/components/payments/content/initialization_task.h
@@ -0,0 +1,105 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PAYMENTS_CONTENT_INITIALIZATION_TASK_H_
+#define COMPONENTS_PAYMENTS_CONTENT_INITIALIZATION_TASK_H_
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+
+namespace payments {
+
+// An interface for a task that takes time to initialize. Useful for monitoring
+// initialization of several asynchronous tasks.
+//
+// Sample usage:
+//
+// class Foo : public InitializationTask {
+// public:
+// Foo() {}
+//
+// ~Foo() override {}
+//
+// // InitializationTask:
+// bool IsInitialized() override {
+// return is_initialized_;
+// }
+//
+// void SomeAction() {
+// is_initialized_ = true;
+// NotifyInitialized();
+// }
+//
+// private:
+// bool is_initialized_ = false;
+// };
+class InitializationTask {
+ public:
+ // An interface for an observer of an initialization task.
+ //
+ // Sample usage:
+ //
+ // class Bar : public InitializationTask::Observer {
+ // public:
+ // explicit Bar(Foo* foo) : foo_(foo) {
+ // if (foo_->IsInitialized()) {
+ // UseFoo();
+ // } else {
+ // foo_->AddInitializationObserver(this);
+ // }
+ // }
+ //
+ // ~Bar() override {}
+ //
+ // // InitializationTask::Observer:
+ // void OnInitialized(InitializationTask* initialization_task) override {
+ // initialization_task->RemoveInitializationObserver(this);
+ // UseFoo();
+ // }
+ //
+ // void UseFoo() {
+ // foo_->DoSomethingInteresting();
+ // }
+ //
+ // private:
+ // // Not owned. Must outlive Bar.
+ // Foo* foo_;
+ // };
+ class Observer : public base::CheckedObserver {
+ public:
+ ~Observer() override;
+
+ // Called when the observed task has initialized.
+ virtual void OnInitialized(InitializationTask* initialization_task) = 0;
+ };
+
+ InitializationTask();
+ virtual ~InitializationTask();
+
+ // Add the |observer| to be notified of initialization.
+ void AddInitializationObserver(Observer* observer);
+
+ // Remove the |observer| of initialization.
+ void RemoveInitializationObserver(Observer* observer);
+
+ // Notify all observers of initialization. Should be called at most once.
+ void NotifyInitialized();
+
+ // Whether the task has initialized.
+ virtual bool IsInitialized() const = 0;
+
+ private:
+ // The list of observers for this initialization task.
+ base::ObserverList<Observer> observers_;
+
+ // Whether NotifyInitialized() has been called.
+ bool has_notified_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(InitializationTask);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_INITIALIZATION_TASK_H_
diff --git a/chromium/components/payments/content/installable_payment_app_crawler.cc b/chromium/components/payments/content/installable_payment_app_crawler.cc
index 3998fd428ae..5366e09f15b 100644
--- a/chromium/components/payments/content/installable_payment_app_crawler.cc
+++ b/chromium/components/payments/content/installable_payment_app_crawler.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_context.h"
diff --git a/chromium/components/payments/content/payment_request.cc b/chromium/components/payments/content/payment_request.cc
index 799564f0e7f..3ae1a628bde 100644
--- a/chromium/components/payments/content/payment_request.cc
+++ b/chromium/components/payments/content/payment_request.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/stl_util.h"
#include "components/payments/content/can_make_payment_query_factory.h"
@@ -31,6 +32,7 @@
namespace {
+using ::payments::mojom::CanMakePaymentQueryResult;
using ::payments::mojom::HasEnrolledInstrumentQueryResult;
} // namespace
@@ -266,12 +268,6 @@ void PaymentRequest::UpdateWith(mojom::PaymentDetailsPtr details) {
return;
}
- if (!details->total) {
- log_.Error("Missing total");
- OnConnectionTerminated();
- return;
- }
-
spec_->UpdateWith(std::move(details));
}
@@ -356,7 +352,7 @@ void PaymentRequest::Complete(mojom::PaymentComplete result) {
}
}
-void PaymentRequest::CanMakePayment() {
+void PaymentRequest::CanMakePayment(bool legacy_mode) {
if (!IsInitialized()) {
log_.Error("Attempted canMakePayment without initialization");
OnConnectionTerminated();
@@ -370,15 +366,16 @@ void PaymentRequest::CanMakePayment() {
if (!delegate_->GetPrefService()->GetBoolean(kCanMakePaymentEnabled) ||
!state_) {
- CanMakePaymentCallback(/*can_make_payment=*/false);
+ CanMakePaymentCallback(legacy_mode, /*can_make_payment=*/false);
} else {
state_->CanMakePayment(
+ legacy_mode,
base::BindOnce(&PaymentRequest::CanMakePaymentCallback,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr(), legacy_mode));
}
}
-void PaymentRequest::HasEnrolledInstrument() {
+void PaymentRequest::HasEnrolledInstrument(bool per_method_quota) {
if (!IsInitialized()) {
log_.Error("Attempted hasEnrolledInstrument without initialization");
OnConnectionTerminated();
@@ -392,11 +389,12 @@ void PaymentRequest::HasEnrolledInstrument() {
if (!delegate_->GetPrefService()->GetBoolean(kCanMakePaymentEnabled) ||
!state_) {
- HasEnrolledInstrumentCallback(/*has_enrolled_instrument=*/false);
+ HasEnrolledInstrumentCallback(per_method_quota,
+ /*has_enrolled_instrument=*/false);
} else {
state_->HasEnrolledInstrument(
base::BindOnce(&PaymentRequest::HasEnrolledInstrumentCallback,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr(), per_method_quota));
}
}
@@ -452,6 +450,13 @@ void PaymentRequest::OnPaymentResponseAvailable(
return;
}
+ // If currently interactive, show the processing spinner. Autofill payment
+ // instruments request a CVC, so they are always interactive at this point. A
+ // payment handler may elect to be non-interactive by not showing a
+ // confirmation page to the user.
+ if (delegate_->IsInteractive())
+ delegate_->ShowProcessingSpinner();
+
client_->OnPaymentResponse(std::move(response));
}
@@ -554,24 +559,46 @@ void PaymentRequest::RecordFirstAbortReason(
}
}
-void PaymentRequest::CanMakePaymentCallback(bool can_make_payment) {
- client_->OnCanMakePayment(
- can_make_payment ? mojom::CanMakePaymentQueryResult::CAN_MAKE_PAYMENT
- : mojom::CanMakePaymentQueryResult::CANNOT_MAKE_PAYMENT);
+void PaymentRequest::CanMakePaymentCallback(bool legacy_mode,
+ bool can_make_payment) {
+ // Only need to enforce query quota in legacy mode. Per-method quota not
+ // supported.
+ if (legacy_mode && spec_ &&
+ !CanMakePaymentQueryFactory::GetInstance()
+ ->GetForContext(web_contents_->GetBrowserContext())
+ ->CanQuery(top_level_origin_, frame_origin_,
+ spec_->stringified_method_data(),
+ /*per_method_quota=*/false)) {
+ if (OriginSecurityChecker::IsOriginLocalhostOrFile(frame_origin_)) {
+ client_->OnCanMakePayment(
+ can_make_payment
+ ? CanMakePaymentQueryResult::WARNING_CAN_MAKE_PAYMENT
+ : CanMakePaymentQueryResult::WARNING_CANNOT_MAKE_PAYMENT);
+ } else {
+ client_->OnCanMakePayment(
+ CanMakePaymentQueryResult::QUERY_QUOTA_EXCEEDED);
+ }
+ } else {
+ client_->OnCanMakePayment(
+ can_make_payment
+ ? mojom::CanMakePaymentQueryResult::CAN_MAKE_PAYMENT
+ : mojom::CanMakePaymentQueryResult::CANNOT_MAKE_PAYMENT);
+ }
- // TODO(https://crbug.com/915907): emit JourneyLogger event once the event
- // names are updated.
+ journey_logger_.SetCanMakePaymentValue(can_make_payment);
if (observer_for_testing_)
observer_for_testing_->OnCanMakePaymentReturned();
}
void PaymentRequest::HasEnrolledInstrumentCallback(
+ bool per_method_quota,
bool has_enrolled_instrument) {
- if (!spec_ || CanMakePaymentQueryFactory::GetInstance()
- ->GetForContext(web_contents_->GetBrowserContext())
- ->CanQuery(top_level_origin_, frame_origin_,
- spec_->stringified_method_data())) {
+ if (!spec_ ||
+ CanMakePaymentQueryFactory::GetInstance()
+ ->GetForContext(web_contents_->GetBrowserContext())
+ ->CanQuery(top_level_origin_, frame_origin_,
+ spec_->stringified_method_data(), per_method_quota)) {
RespondToHasEnrolledInstrumentQuery(has_enrolled_instrument,
/*warn_localhost_or_file=*/false);
} else if (OriginSecurityChecker::IsOriginLocalhostOrFile(frame_origin_)) {
@@ -600,7 +627,7 @@ void PaymentRequest::RespondToHasEnrolledInstrumentQuery(
client_->OnHasEnrolledInstrument(has_enrolled_instrument ? positive
: negative);
- journey_logger_.SetCanMakePaymentValue(has_enrolled_instrument);
+ journey_logger_.SetHasEnrolledInstrumentValue(has_enrolled_instrument);
}
} // namespace payments
diff --git a/chromium/components/payments/content/payment_request.h b/chromium/components/payments/content/payment_request.h
index 1752553ad08..ef4236b6c78 100644
--- a/chromium/components/payments/content/payment_request.h
+++ b/chromium/components/payments/content/payment_request.h
@@ -74,8 +74,8 @@ class PaymentRequest : public mojom::PaymentRequest,
void NoUpdatedPaymentDetails() override;
void Abort() override;
void Complete(mojom::PaymentComplete result) override;
- void CanMakePayment() override;
- void HasEnrolledInstrument() override;
+ void CanMakePayment(bool legacy_mode) override;
+ void HasEnrolledInstrument(bool per_method_quota) override;
// PaymentRequestSpec::Observer:
void OnSpecUpdated() override {}
@@ -144,11 +144,12 @@ class PaymentRequest : public mojom::PaymentRequest,
// The callback for PaymentRequestState::CanMakePayment. Checks for query
// quota and may send QUERY_QUOTA_EXCEEDED.
- void CanMakePaymentCallback(bool can_make_payment);
+ void CanMakePaymentCallback(bool legacy_mode, bool can_make_payment);
// The callback for PaymentRequestState::HasEnrolledInstrument. Checks for
// query quota and may send QUERY_QUOTA_EXCEEDED.
- void HasEnrolledInstrumentCallback(bool has_enrolled_instrument);
+ void HasEnrolledInstrumentCallback(bool per_method_quota,
+ bool has_enrolled_instrument);
// The callback for PaymentRequestState::AreRequestedMethodsSupported.
void AreRequestedMethodsSupportedCallback(bool methods_supported);
diff --git a/chromium/components/payments/content/payment_request_spec.cc b/chromium/components/payments/content/payment_request_spec.cc
index c3406df5ee6..d1312bc614f 100644
--- a/chromium/components/payments/content/payment_request_spec.cc
+++ b/chromium/components/payments/content/payment_request_spec.cc
@@ -102,10 +102,12 @@ void PaymentRequestSpec::UpdateWith(mojom::PaymentDetailsPtr details) {
DCHECK(details_);
if (details->total)
details_->total = std::move(details->total);
- details_->display_items = std::move(details->display_items);
+ if (!details->display_items.empty())
+ details_->display_items = std::move(details->display_items);
if (details->shipping_options)
details_->shipping_options = std::move(details->shipping_options);
- details_->modifiers = std::move(details->modifiers);
+ if (!details->modifiers.empty())
+ details_->modifiers = std::move(details->modifiers);
details_->error = std::move(details->error);
if (details->shipping_address_errors)
details_->shipping_address_errors =
@@ -193,7 +195,6 @@ bool PaymentRequestSpec::has_shipping_address_error() const {
details_->shipping_address_errors->postal_code.empty() &&
details_->shipping_address_errors->recipient.empty() &&
details_->shipping_address_errors->region.empty() &&
- details_->shipping_address_errors->region_code.empty() &&
details_->shipping_address_errors->sorting_code.empty());
}
@@ -357,7 +358,7 @@ void PaymentRequestSpec::UpdateSelectedShippingOption(bool after_update) {
selected_shipping_option_ = nullptr;
selected_shipping_option_error_.clear();
- if (details_->shipping_options->empty()) {
+ if (details_->shipping_options->empty() || !details_->error.empty()) {
// No options are provided by the merchant.
if (after_update) {
// This is after an update, which means that the selected address is not
diff --git a/chromium/components/payments/content/payment_request_state.cc b/chromium/components/payments/content/payment_request_state.cc
index 1d9f2423400..c86818e98cd 100644
--- a/chromium/components/payments/content/payment_request_state.cc
+++ b/chromium/components/payments/content/payment_request_state.cc
@@ -8,6 +8,7 @@
#include <set>
#include <utility>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_country.h"
@@ -148,8 +149,10 @@ void PaymentRequestState::FinishedGetAllSWPaymentInstruments() {
NotifyOnGetAllPaymentInstrumentsFinished();
// Fulfill the pending CanMakePayment call.
- if (can_make_payment_callback_)
- CheckCanMakePayment(std::move(can_make_payment_callback_));
+ if (can_make_payment_callback_) {
+ CheckCanMakePayment(can_make_payment_legacy_mode_,
+ std::move(can_make_payment_callback_));
+ }
// Fulfill the pending HasEnrolledInstrument call.
if (has_enrolled_instrument_callback_)
@@ -199,22 +202,38 @@ void PaymentRequestState::OnSpecUpdated() {
UpdateIsReadyToPayAndNotifyObservers();
}
-void PaymentRequestState::CanMakePayment(StatusCallback callback) {
+void PaymentRequestState::CanMakePayment(bool legacy_mode,
+ StatusCallback callback) {
if (!get_all_instruments_finished_) {
DCHECK(!can_make_payment_callback_);
can_make_payment_callback_ = std::move(callback);
+ can_make_payment_legacy_mode_ = legacy_mode;
return;
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&PaymentRequestState::CheckCanMakePayment,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+ FROM_HERE, base::BindOnce(&PaymentRequestState::CheckCanMakePayment,
+ weak_ptr_factory_.GetWeakPtr(), legacy_mode,
+ std::move(callback)));
}
-void PaymentRequestState::CheckCanMakePayment(StatusCallback callback) {
+void PaymentRequestState::CheckCanMakePayment(bool legacy_mode,
+ StatusCallback callback) {
DCHECK(get_all_instruments_finished_);
- std::move(callback).Run(are_requested_methods_supported_);
+ if (!legacy_mode) {
+ std::move(callback).Run(are_requested_methods_supported_);
+ return;
+ }
+
+ // Legacy mode: fall back to also checking if an instrument is enrolled.
+ bool can_make_payment_value = false;
+ for (const auto& instrument : available_instruments_) {
+ if (instrument->IsValidForCanMakePayment()) {
+ can_make_payment_value = true;
+ break;
+ }
+ }
+ std::move(callback).Run(can_make_payment_value);
}
void PaymentRequestState::HasEnrolledInstrument(StatusCallback callback) {
@@ -231,6 +250,7 @@ void PaymentRequestState::HasEnrolledInstrument(StatusCallback callback) {
}
void PaymentRequestState::CheckHasEnrolledInstrument(StatusCallback callback) {
+ DCHECK(get_all_instruments_finished_);
bool has_enrolled_instrument_value = false;
for (const auto& instrument : available_instruments_) {
if (instrument->IsValidForCanMakePayment()) {
@@ -433,6 +453,10 @@ autofill::AddressNormalizer* PaymentRequestState::GetAddressNormalizer() {
return payment_request_delegate_->GetAddressNormalizer();
}
+bool PaymentRequestState::IsInitialized() const {
+ return get_all_instruments_finished_;
+}
+
void PaymentRequestState::PopulateProfileCache() {
std::vector<autofill::AutofillProfile*> profiles =
personal_data_manager_->GetProfilesToSuggest();
@@ -536,6 +560,7 @@ void PaymentRequestState::UpdateIsReadyToPayAndNotifyObservers() {
void PaymentRequestState::NotifyOnGetAllPaymentInstrumentsFinished() {
for (auto& observer : observers_)
observer.OnGetAllPaymentInstrumentsFinished();
+ NotifyInitialized();
}
void PaymentRequestState::NotifyOnSelectedInformationChanged() {
diff --git a/chromium/components/payments/content/payment_request_state.h b/chromium/components/payments/content/payment_request_state.h
index 892379897ae..cc9dadfbebe 100644
--- a/chromium/components/payments/content/payment_request_state.h
+++ b/chromium/components/payments/content/payment_request_state.h
@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/observer_list.h"
#include "components/autofill/core/browser/address_normalizer.h"
+#include "components/payments/content/initialization_task.h"
#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_response_helper.h"
#include "components/payments/content/service_worker_payment_app_factory.h"
@@ -39,7 +40,8 @@ class ServiceWorkerPaymentInstrument;
// what the merchant has specified, as input into the "is ready to pay"
// computation.
class PaymentRequestState : public PaymentResponseHelper::Delegate,
- public PaymentRequestSpec::Observer {
+ public PaymentRequestSpec::Observer,
+ public InitializationTask {
public:
// Any class call add itself as Observer via AddObserver() and receive
// notification about the state changing.
@@ -99,7 +101,8 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate,
// Checks whether support for the specified payment methods exist, either
// because the user has a registered payment handler or because the browser
// can do just-in-time registration for a suitable payment handler.
- void CanMakePayment(StatusCallback callback);
+ // If |legacy_mode| is true, then also checks that an instrument is enrolled.
+ void CanMakePayment(bool legacy_mode, StatusCallback callback);
// Checks whether the user has at least one instrument that satisfies the
// specified supported payment methods asynchronously.
@@ -218,6 +221,9 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate,
autofill::AddressNormalizer* GetAddressNormalizer();
+ // InitializationTask:
+ bool IsInitialized() const override;
+
private:
// Fetches the Autofill Profiles for this user from the PersonalDataManager,
// and stores copies of them, owned by this PaymentRequestState, in
@@ -263,7 +269,7 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate,
// Checks whether support for the specified payment methods exists and call
// the |callback| to return the result.
- void CheckCanMakePayment(StatusCallback callback);
+ void CheckCanMakePayment(bool legacy_mode, StatusCallback callback);
// Checks whether the user has at least one instrument that satisfies the
// specified supported payment methods and call the |callback| to return the
@@ -292,6 +298,10 @@ class PaymentRequestState : public PaymentResponseHelper::Delegate,
autofill::PersonalDataManager* personal_data_manager_;
JourneyLogger* journey_logger_;
+ // Whether |can_make_payment_callback_| expects the legacy canMakePayment
+ // semantic. Only meaningful when |can_make_payment_callback_| is present.
+ bool can_make_payment_legacy_mode_ = false;
+
StatusCallback can_make_payment_callback_;
StatusCallback has_enrolled_instrument_callback_;
StatusCallback are_requested_methods_supported_callback_;
diff --git a/chromium/components/payments/content/payment_request_state_unittest.cc b/chromium/components/payments/content/payment_request_state_unittest.cc
index 5659ff9a9ec..e53508be935 100644
--- a/chromium/components/payments/content/payment_request_state_unittest.cc
+++ b/chromium/components/payments/content/payment_request_state_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/guid.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/utf_string_conversions.h"
@@ -56,7 +57,7 @@ class PaymentRequestStateTest : public testing::Test,
// PaymentRequestState::Delegate:
void OnPaymentResponseAvailable(mojom::PaymentResponsePtr response) override {
payment_response_ = std::move(response);
- };
+ }
void OnShippingOptionIdSelected(std::string shipping_option_id) override {}
void OnShippingAddressSelected(mojom::PaymentAddressPtr address) override {
selected_shipping_address_ = std::move(address);
@@ -139,20 +140,26 @@ class PaymentRequestStateTest : public testing::Test,
autofill::CreditCard credit_card_visa_;
};
-TEST_F(PaymentRequestStateTest, HasEnrolledInstrument) {
+TEST_F(PaymentRequestStateTest, CanMakePayment) {
// Default options.
RecreateStateWithOptions(mojom::PaymentOptions::New());
- // HasEnrolledInstrument returns true because the method data requires Visa,
+ // Legacy CanMakePayment returns true because the method data requires Visa,
// and the user has a Visa card on file.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_TRUE(has_enrolled_instrument);
}));
// CanMakePayment returns true because the requested method is supported.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(/*legacy_mode=*/false,
+ base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
TEST_F(PaymentRequestStateTest, CanMakePayment_NoEnrolledInstrument) {
@@ -165,8 +172,12 @@ TEST_F(PaymentRequestStateTest, CanMakePayment_NoEnrolledInstrument) {
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns false because the method data requires
+ // Legacy CanMakePayment returns false because the method data requires
// MasterCard, and the user doesn't have such an instrument.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_FALSE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_FALSE(has_enrolled_instrument);
@@ -174,8 +185,10 @@ TEST_F(PaymentRequestStateTest, CanMakePayment_NoEnrolledInstrument) {
// CanMakePayment returns true because the requested method is supported, even
// though the payment instrument is not ready to pay.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(/*legacy_mode=*/false,
+ base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
TEST_F(PaymentRequestStateTest, CanMakePayment_UnsupportedPaymentMethod) {
@@ -187,8 +200,12 @@ TEST_F(PaymentRequestStateTest, CanMakePayment_UnsupportedPaymentMethod) {
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns false because the method data requires
+ // Legacy CanMakePayment returns false because the method data requires
// MasterCard, and the user doesn't have such an instrument.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_FALSE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_FALSE(has_enrolled_instrument);
@@ -196,11 +213,13 @@ TEST_F(PaymentRequestStateTest, CanMakePayment_UnsupportedPaymentMethod) {
// CanMakePayment returns true because the requested method is supported, even
// though the payment instrument is not ready to pay.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_FALSE(can_make_payment); }));
+ state()->CanMakePayment(/*legacy_mode=*/false,
+ base::BindOnce([](bool can_make_payment) {
+ EXPECT_FALSE(can_make_payment);
+ }));
}
-TEST_F(PaymentRequestStateTest, HasEnrolledInstrument_OnlyBasicCard) {
+TEST_F(PaymentRequestStateTest, CanMakePayment_OnlyBasicCard) {
// The method data supports everything in basic-card.
mojom::PaymentMethodDataPtr entry = mojom::PaymentMethodData::New();
entry->supported_method = "basic-card";
@@ -210,20 +229,25 @@ TEST_F(PaymentRequestStateTest, HasEnrolledInstrument_OnlyBasicCard) {
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns true because the method data supports
+ // Legacy CanMakePayment returns true because the method data supports
// everything, and the user has at least one instrument.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_TRUE(has_enrolled_instrument);
}));
// CanMakePayment returns true because the requested method is supported.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(
+ /*legacy_mode=*/false, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
-TEST_F(PaymentRequestStateTest,
- HasEnrolledInstrument_BasicCard_SpecificAvailable) {
+TEST_F(PaymentRequestStateTest, CanMakePayment_BasicCard_SpecificAvailable) {
// The method data supports visa through basic-card.
mojom::PaymentMethodDataPtr entry = mojom::PaymentMethodData::New();
entry->supported_method = "basic-card";
@@ -234,20 +258,26 @@ TEST_F(PaymentRequestStateTest,
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns true because the method data supports visa,
+ // Legacy CanMakePayment returns true because the method data supports visa,
// and the user has a Visa instrument.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_TRUE(has_enrolled_instrument);
}));
// CanMakePayment returns true because the requested method is supported.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(
+ /*legacy_mode=*/false, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
TEST_F(PaymentRequestStateTest,
- HasEnrolledInstrument_BasicCard_SpecificAvailableButInvalid) {
+ CanMakePayment_BasicCard_SpecificAvailableButInvalid) {
// The method data supports jcb through basic-card.
mojom::PaymentMethodDataPtr entry = mojom::PaymentMethodData::New();
entry->supported_method = "basic-card";
@@ -258,8 +288,12 @@ TEST_F(PaymentRequestStateTest,
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns false because the method data supports jcb,
+ // Legacy CanMakePayment returns false because the method data supports jcb,
// and the user has a JCB instrument, but it's invalid.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_FALSE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_FALSE(has_enrolled_instrument);
@@ -267,12 +301,13 @@ TEST_F(PaymentRequestStateTest,
// CanMakePayment returns true because the requested method is supported, even
// though there is no enrolled instrument.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(
+ /*legacy_mode=*/false, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
-TEST_F(PaymentRequestStateTest,
- HasEnrolledInstrument_BasicCard_SpecificUnavailable) {
+TEST_F(PaymentRequestStateTest, CanMakePayment_BasicCard_SpecificUnavailable) {
// The method data supports mastercard through basic-card.
mojom::PaymentMethodDataPtr entry = mojom::PaymentMethodData::New();
entry->supported_method = "basic-card";
@@ -283,8 +318,12 @@ TEST_F(PaymentRequestStateTest,
mojom::PaymentDetails::New(),
std::move(method_data));
- // HasEnrolledInstrument returns false because the method data supports
+ // Legacy CanMakePayment returns false because the method data supports
// mastercard, and the user doesn't have such an instrument.
+ state()->CanMakePayment(
+ /*legacy_mode=*/true, base::BindOnce([](bool can_make_payment) {
+ EXPECT_FALSE(can_make_payment);
+ }));
state()->HasEnrolledInstrument(
base::BindOnce([](bool has_enrolled_instrument) {
EXPECT_FALSE(has_enrolled_instrument);
@@ -292,8 +331,10 @@ TEST_F(PaymentRequestStateTest,
// CanMakePayment returns true because the requested method is supported, even
// though there is no enrolled instrument.
- state()->CanMakePayment(base::BindOnce(
- [](bool can_make_payment) { EXPECT_TRUE(can_make_payment); }));
+ state()->CanMakePayment(
+ /*legacy_mode=*/false, base::BindOnce([](bool can_make_payment) {
+ EXPECT_TRUE(can_make_payment);
+ }));
}
TEST_F(PaymentRequestStateTest, ReadyToPay_DefaultSelections) {
@@ -405,7 +446,6 @@ TEST_F(PaymentRequestStateTest, SelectedShippingAddressMessage_Normalized) {
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);
@@ -431,7 +471,6 @@ TEST_F(PaymentRequestStateTest, JaLatnShippingAddress) {
"jon.doe@exampl.com", "Example Inc",
"Roppongi", "6 Chrome-10-1", "Tokyo", "",
"106-6126", "JP", "+81363849000");
- profile.set_language_code("ja-Latn");
state()->SetSelectedShippingProfile(&profile);
EXPECT_EQ(0, num_on_selected_information_changed_called());
@@ -459,8 +498,6 @@ TEST_F(PaymentRequestStateTest, JaLatnShippingAddress) {
EXPECT_EQ("", selected_shipping_address()->dependent_locality);
EXPECT_EQ("106-6126", selected_shipping_address()->postal_code);
EXPECT_EQ("", selected_shipping_address()->sorting_code);
- EXPECT_EQ("ja", selected_shipping_address()->language_code);
- EXPECT_EQ("Latn", selected_shipping_address()->script_code);
EXPECT_EQ("Example Inc", selected_shipping_address()->organization);
EXPECT_EQ("Jon V. Doe", selected_shipping_address()->recipient);
EXPECT_EQ("+81363849000", selected_shipping_address()->phone);
diff --git a/chromium/components/payments/content/payment_response_helper_unittest.cc b/chromium/components/payments/content/payment_response_helper_unittest.cc
index 5d3e9143999..c28795f9dcb 100644
--- a/chromium/components/payments/content/payment_response_helper_unittest.cc
+++ b/chromium/components/payments/content/payment_response_helper_unittest.cc
@@ -45,7 +45,7 @@ class PaymentResponseHelperTest : public testing::Test,
// PaymentRequestState::Delegate:
void OnPaymentResponseReady(mojom::PaymentResponsePtr response) override {
payment_response_ = std::move(response);
- };
+ }
// Convenience method to create a PaymentRequestSpec with specified |details|
// and |method_data|.
@@ -121,7 +121,6 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_SupportedMethod) {
"\"city\":\"Elysium\","
"\"country\":\"US\","
"\"dependentLocality\":\"\","
- "\"languageCode\":\"\","
"\"organization\":\"Underworld\","
"\"phone\":\"16502111111\","
"\"postalCode\":\"91111\","
@@ -160,7 +159,6 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_BasicCard) {
"\"city\":\"Elysium\","
"\"country\":\"US\","
"\"dependentLocality\":\"\","
- "\"languageCode\":\"\","
"\"organization\":\"Underworld\","
"\"phone\":\"16502111111\","
"\"postalCode\":\"91111\","
@@ -204,7 +202,6 @@ TEST_F(PaymentResponseHelperTest, GeneratePaymentResponse_ShippingAddress) {
EXPECT_EQ("", response()->shipping_address->dependent_locality);
EXPECT_EQ("91111", response()->shipping_address->postal_code);
EXPECT_EQ("", response()->shipping_address->sorting_code);
- EXPECT_EQ("", response()->shipping_address->language_code);
EXPECT_EQ("Underworld", response()->shipping_address->organization);
EXPECT_EQ("John H. Doe", response()->shipping_address->recipient);
EXPECT_EQ("16502111111", response()->shipping_address->phone);
diff --git a/chromium/components/payments/content/service_worker_payment_app_factory.cc b/chromium/components/payments/content/service_worker_payment_app_factory.cc
index a2b396b05df..8248544dc0e 100644
--- a/chromium/components/payments/content/service_worker_payment_app_factory.cc
+++ b/chromium/components/payments/content/service_worker_payment_app_factory.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/components/payments/content/service_worker_payment_instrument.cc b/chromium/components/payments/content/service_worker_payment_instrument.cc
index 1f4da98c108..24976c02adf 100644
--- a/chromium/components/payments/content/service_worker_payment_instrument.cc
+++ b/chromium/components/payments/content/service_worker_payment_instrument.cc
@@ -4,6 +4,9 @@
#include "components/payments/content/service_worker_payment_instrument.h"
+#include <utility>
+
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -12,6 +15,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/payment_app_provider.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
#include "ui/gfx/image/image_skia.h"
#include "url/origin.h"
@@ -35,6 +39,7 @@ ServiceWorkerPaymentInstrument::ServiceWorkerPaymentInstrument(
delegate_(nullptr),
payment_request_delegate_(payment_request_delegate),
can_make_payment_result_(false),
+ has_enrolled_instrument_result_(false),
needs_installation_(false),
weak_ptr_factory_(this) {
DCHECK(browser_context_);
@@ -69,6 +74,7 @@ ServiceWorkerPaymentInstrument::ServiceWorkerPaymentInstrument(
delegate_(nullptr),
payment_request_delegate_(payment_request_delegate),
can_make_payment_result_(false),
+ has_enrolled_instrument_result_(false),
needs_installation_(true),
web_contents_(web_contents),
installable_web_app_info_(std::move(installable_payment_app_info)),
@@ -106,21 +112,21 @@ void ServiceWorkerPaymentInstrument::ValidateCanMakePayment(
ValidateCanMakePaymentCallback callback) {
// Returns true for payment app that needs installation.
if (needs_installation_) {
- OnCanMakePayment(std::move(callback), true);
+ OnCanMakePaymentEventSkipped(std::move(callback));
return;
}
// Returns true if we are in incognito (avoiding sending the event to the
// payment handler).
if (payment_request_delegate_->IsIncognito()) {
- OnCanMakePayment(std::move(callback), true);
+ OnCanMakePaymentEventSkipped(std::move(callback));
return;
}
// Do not send CanMakePayment event to payment apps that have not been
// explicitly verified.
if (!stored_payment_app_info_->has_explicitly_verified_methods) {
- OnCanMakePayment(std::move(callback), true);
+ OnCanMakePaymentEventSkipped(std::move(callback));
return;
}
@@ -130,15 +136,16 @@ void ServiceWorkerPaymentInstrument::ValidateCanMakePayment(
// This could only happen if this instrument only supports non-url based
// payment methods of the payment request, then return true
// and do not send CanMakePaymentEvent to the payment app.
- OnCanMakePayment(std::move(callback), true);
+ OnCanMakePaymentEventSkipped(std::move(callback));
return;
}
content::PaymentAppProvider::GetInstance()->CanMakePayment(
browser_context_, stored_payment_app_info_->registration_id,
std::move(event_data),
- base::BindOnce(&ServiceWorkerPaymentInstrument::OnCanMakePayment,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+ base::BindOnce(
+ &ServiceWorkerPaymentInstrument::OnCanMakePaymentEventResponded,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
mojom::CanMakePaymentEventDataPtr
@@ -183,13 +190,31 @@ ServiceWorkerPaymentInstrument::CreateCanMakePaymentEventData() {
return event_data;
}
-void ServiceWorkerPaymentInstrument::OnCanMakePayment(
+void ServiceWorkerPaymentInstrument::OnCanMakePaymentEventSkipped(
+ ValidateCanMakePaymentCallback callback) {
+ can_make_payment_result_ = true;
+ has_enrolled_instrument_result_ = false;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), this, can_make_payment_result_));
+}
+
+void ServiceWorkerPaymentInstrument::OnCanMakePaymentEventResponded(
ValidateCanMakePaymentCallback callback,
bool result) {
- can_make_payment_result_ = result;
-
+ // If hasEnrolledInstrument is supported, always return true for
+ // canMakePayment for any matching payment handler.
+ if (base::FeatureList::IsEnabled(
+ ::features::kPaymentRequestHasEnrolledInstrument)) {
+ can_make_payment_result_ = true;
+ has_enrolled_instrument_result_ = result;
+ } else {
+ can_make_payment_result_ = result;
+ has_enrolled_instrument_result_ = result;
+ }
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), this, result));
+ FROM_HERE,
+ base::BindOnce(std::move(callback), this, can_make_payment_result_));
}
void ServiceWorkerPaymentInstrument::InvokePaymentApp(Delegate* delegate) {
@@ -282,6 +307,10 @@ bool ServiceWorkerPaymentInstrument::IsValidForCanMakePayment() const {
// This instrument should not be used when can_make_payment_result_ is false,
// so this interface should not be invoked.
DCHECK(can_make_payment_result_);
+ if (base::FeatureList::IsEnabled(
+ ::features::kPaymentRequestHasEnrolledInstrument)) {
+ return has_enrolled_instrument_result_;
+ }
return true;
}
diff --git a/chromium/components/payments/content/service_worker_payment_instrument.h b/chromium/components/payments/content/service_worker_payment_instrument.h
index e8ca8b45dec..2d8559c6b09 100644
--- a/chromium/components/payments/content/service_worker_payment_instrument.h
+++ b/chromium/components/payments/content/service_worker_payment_instrument.h
@@ -55,7 +55,7 @@ class ServiceWorkerPaymentInstrument : public PaymentInstrument {
// Validates whether this payment instrument can be used for this payment
// request. It fires CanMakePaymentEvent to the payment app to do validation.
- // The result is returned through callback.If the returned result is false,
+ // The result is returned through callback. If the returned result is false,
// then this instrument should not be used for this payment request. This
// interface must be called before any other interfaces in this class.
void ValidateCanMakePayment(ValidateCanMakePaymentCallback callback);
@@ -84,7 +84,9 @@ class ServiceWorkerPaymentInstrument : public PaymentInstrument {
mojom::PaymentRequestEventDataPtr CreatePaymentRequestEventData();
mojom::CanMakePaymentEventDataPtr CreateCanMakePaymentEventData();
- void OnCanMakePayment(ValidateCanMakePaymentCallback callback, bool result);
+ void OnCanMakePaymentEventSkipped(ValidateCanMakePaymentCallback callback);
+ void OnCanMakePaymentEventResponded(ValidateCanMakePaymentCallback callback,
+ bool result);
content::BrowserContext* browser_context_;
GURL top_origin_;
@@ -102,6 +104,7 @@ class ServiceWorkerPaymentInstrument : public PaymentInstrument {
// PaymentAppProvider::CanMakePayment result of this payment instrument.
bool can_make_payment_result_;
+ bool has_enrolled_instrument_result_;
// Below variables are used for installable ServiceWorkerPaymentInstrument
// specifically.
diff --git a/chromium/components/payments/content/service_worker_payment_instrument_unittest.cc b/chromium/components/payments/content/service_worker_payment_instrument_unittest.cc
index 17f4b836d66..76d9f6232c9 100644
--- a/chromium/components/payments/content/service_worker_payment_instrument_unittest.cc
+++ b/chromium/components/payments/content/service_worker_payment_instrument_unittest.cc
@@ -8,8 +8,10 @@
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "components/payments/core/payment_request_delegate.h"
#include "content/public/browser/stored_payment_app.h"
+#include "content/public/common/content_features.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -239,6 +241,23 @@ TEST_F(ServiceWorkerPaymentInstrumentTest, CreateCanMakePaymentEvent) {
"https://bobpay.com");
}
+// Test the case when CanMakePaymentEvent cannot be fired. The instrument should
+// be considered valid, but not ready for payment.
+TEST_F(ServiceWorkerPaymentInstrumentTest, ValidateCanMakePayment) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ features::kPaymentRequestHasEnrolledInstrument);
+
+ // CanMakePaymentEvent is not fired because this test instrument does not have
+ // any explicitly verified methods.
+ CreateServiceWorkerPaymentInstrument(/*with_url_method=*/true);
+ GetInstrument()->ValidateCanMakePayment(
+ base::BindOnce([](ServiceWorkerPaymentInstrument*, bool result) {
+ EXPECT_TRUE(result);
+ }));
+ EXPECT_FALSE(GetInstrument()->IsValidForCanMakePayment());
+}
+
// Test modifiers can be matched based on capabilities.
TEST_F(ServiceWorkerPaymentInstrumentTest, IsValidForModifier) {
CreateServiceWorkerPaymentInstrument(true);
diff --git a/chromium/components/payments/content/test_content_payment_request_delegate.cc b/chromium/components/payments/content/test_content_payment_request_delegate.cc
index 2b76cd4560d..aaeabd5df42 100644
--- a/chromium/components/payments/content/test_content_payment_request_delegate.cc
+++ b/chromium/components/payments/content/test_content_payment_request_delegate.cc
@@ -103,6 +103,10 @@ void TestContentPaymentRequestDelegate::EmbedPaymentHandlerWindow(
const GURL& url,
PaymentHandlerOpenWindowCallback callback) {}
+bool TestContentPaymentRequestDelegate::IsInteractive() const {
+ return true;
+}
+
autofill::TestAddressNormalizer*
TestContentPaymentRequestDelegate::test_address_normalizer() {
return core_delegate_.test_address_normalizer();
diff --git a/chromium/components/payments/content/test_content_payment_request_delegate.h b/chromium/components/payments/content/test_content_payment_request_delegate.h
index dae7dbc960a..10ee9d93126 100644
--- a/chromium/components/payments/content/test_content_payment_request_delegate.h
+++ b/chromium/components/payments/content/test_content_payment_request_delegate.h
@@ -48,6 +48,7 @@ class TestContentPaymentRequestDelegate : public ContentPaymentRequestDelegate {
void EmbedPaymentHandlerWindow(
const GURL& url,
PaymentHandlerOpenWindowCallback callback) override;
+ bool IsInteractive() const override;
autofill::TestAddressNormalizer* test_address_normalizer();
void DelayFullCardRequestCompletion();
diff --git a/chromium/components/payments/content/utility/payment_manifest_parser_unittest.cc b/chromium/components/payments/content/utility/payment_manifest_parser_unittest.cc
index d86e491fd3a..5ec89b1de38 100644
--- a/chromium/components/payments/content/utility/payment_manifest_parser_unittest.cc
+++ b/chromium/components/payments/content/utility/payment_manifest_parser_unittest.cc
@@ -21,7 +21,7 @@ void ExpectUnableToParsePaymentMethodManifest(const std::string& input) {
std::vector<url::Origin> actual_supported_origins;
bool actual_all_origins_supported = false;
- std::unique_ptr<base::Value> value = base::JSONReader::Read(input);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(input);
PaymentManifestParser::ParsePaymentMethodManifestIntoVectors(
std::move(value), ErrorLogger(), &actual_web_app_urls,
@@ -42,7 +42,7 @@ void ExpectParsedPaymentMethodManifest(
std::vector<url::Origin> actual_supported_origins;
bool actual_all_origins_supported = false;
- std::unique_ptr<base::Value> value = base::JSONReader::Read(input);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(input);
PaymentManifestParser::ParsePaymentMethodManifestIntoVectors(
std::move(value), ErrorLogger(), &actual_web_app_urls,
@@ -276,7 +276,7 @@ TEST(PaymentManifestParserTest,
// Web app manifest parsing:
void ExpectUnableToParseWebAppManifest(const std::string& input) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(input);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(input);
std::vector<WebAppManifestSection> sections;
PaymentManifestParser::ParseWebAppManifestIntoVector(
std::move(value), ErrorLogger(), &sections);
@@ -288,7 +288,7 @@ void ExpectParsedWebAppManifest(
const std::string& expected_id,
int64_t expected_min_version,
const std::vector<std::vector<uint8_t>>& expected_fingerprints) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(input);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(input);
std::vector<WebAppManifestSection> sections;
EXPECT_TRUE(PaymentManifestParser::ParseWebAppManifestIntoVector(
std::move(value), ErrorLogger(), &sections));
@@ -690,7 +690,7 @@ TEST(PaymentManifestParserTest, TwoDifferentSignaturesWellFormed) {
}
TEST(PaymentManifestParserTest, TwoRelatedApplicationsWellFormed) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(
"{"
" \"related_applications\": [{"
" \"platform\": \"play\", "
@@ -744,7 +744,7 @@ TEST(PaymentManifestParserTest, TwoRelatedApplicationsWellFormed) {
// Web app installation information parsing:
void ExpectUnableToParseInstallInfo(const std::string& input) {
- auto value = base::JSONReader::Read(input);
+ auto value = base::JSONReader::ReadDeprecated(input);
auto installation_info = std::make_unique<WebAppInstallationInfo>();
auto icons =
std::make_unique<std::vector<PaymentManifestParser::WebAppIcon>>();
@@ -756,7 +756,7 @@ void ExpectParsedInstallInfo(
const std::string& input,
const WebAppInstallationInfo& expected_installation_info,
const std::vector<PaymentManifestParser::WebAppIcon>& expected_icons) {
- auto value = base::JSONReader::Read(input);
+ auto value = base::JSONReader::ReadDeprecated(input);
WebAppInstallationInfo actual_installation_info;
std::vector<PaymentManifestParser::WebAppIcon> actual_icons;
EXPECT_TRUE(PaymentManifestParser::ParseWebAppInstallationInfoIntoStructs(
diff --git a/chromium/components/payments/content/utility/payment_method_manifest_parser_fuzzer.cc b/chromium/components/payments/content/utility/payment_method_manifest_parser_fuzzer.cc
index a250b5d8373..14f1e5128c6 100644
--- a/chromium/components/payments/content/utility/payment_method_manifest_parser_fuzzer.cc
+++ b/chromium/components/payments/content/utility/payment_method_manifest_parser_fuzzer.cc
@@ -30,7 +30,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bool all_origins_supported;
base::StringPiece json_data(reinterpret_cast<const char*>(data), size);
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json_data);
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(json_data);
payments::ErrorLogger log;
log.DisableInTest();
diff --git a/chromium/components/payments/content/utility/payment_web_app_manifest_parser_fuzzer.cc b/chromium/components/payments/content/utility/payment_web_app_manifest_parser_fuzzer.cc
index d0b6ac6c8f1..d8c0d1beb99 100644
--- a/chromium/components/payments/content/utility/payment_web_app_manifest_parser_fuzzer.cc
+++ b/chromium/components/payments/content/utility/payment_web_app_manifest_parser_fuzzer.cc
@@ -16,7 +16,8 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string json_data(reinterpret_cast<const char*>(data), size);
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json_data);
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(json_data);
payments::ErrorLogger log;
log.DisableInTest();
diff --git a/chromium/components/payments/core/can_make_payment_query.cc b/chromium/components/payments/core/can_make_payment_query.cc
index 181bb669ac7..b7a41bb6465 100644
--- a/chromium/components/payments/core/can_make_payment_query.cc
+++ b/chromium/components/payments/core/can_make_payment_query.cc
@@ -15,8 +15,6 @@
#include "components/payments/core/features.h"
#include "url/gurl.h"
-#include "base/logging.h"
-
namespace payments {
namespace {
@@ -48,52 +46,75 @@ CanMakePaymentQuery::~CanMakePaymentQuery() {}
bool CanMakePaymentQuery::CanQuery(
const GURL& top_level_origin,
const GURL& frame_origin,
- const std::map<std::string, std::set<std::string>>& query) {
- if (base::FeatureList::IsEnabled(
+ const std::map<std::string, std::set<std::string>>& query,
+ bool per_method_quota) {
+ // Check both with and without per-method quota, so that both queries are
+ // recorded in case if two different tabs of the same website run with and
+ // without the origin trial.
+ bool can_query_with_per_method_quota =
+ CanQueryWithPerMethodQuota(top_level_origin, frame_origin, query);
+
+ bool can_query_without_per_method_quota =
+ CanQueryWithoutPerMethodQuota(top_level_origin, frame_origin, query);
+
+ if (per_method_quota ||
+ base::FeatureList::IsEnabled(
features::kWebPaymentsPerMethodCanMakePaymentQuota)) {
- bool can_query = true;
- for (const auto& method_and_params : query) {
- std::string method = method_and_params.first;
- std::set<std::string> params = method_and_params.second;
- SimpleNormalize(&method, &params);
-
- const std::string id =
- frame_origin.spec() + ":" + top_level_origin.spec() + ":" + method;
-
- auto it = per_method_queries_.find(id);
- if (it == per_method_queries_.end()) {
- auto timer = std::make_unique<base::OneShotTimer>();
- timer->Start(
- FROM_HERE, base::TimeDelta::FromMinutes(30),
- base::BindOnce(
- &CanMakePaymentQuery::ExpireQuotaForFrameOriginAndMethod,
- base::Unretained(this), id));
- timers_.insert(std::make_pair(id, std::move(timer)));
- per_method_queries_.insert(std::make_pair(id, params));
- continue;
- }
-
- can_query &= it->second == params;
- }
+ return can_query_with_per_method_quota;
+ }
+
+ return can_query_without_per_method_quota;
+}
+
+bool CanMakePaymentQuery::CanQueryWithPerMethodQuota(
+ const GURL& top_level_origin,
+ const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query) {
+ bool can_query = true;
+ for (const auto& method_and_params : query) {
+ std::string method = method_and_params.first;
+ std::set<std::string> params = method_and_params.second;
+ SimpleNormalize(&method, &params);
- return can_query;
- } else {
- const std::string id = frame_origin.spec() + ":" + top_level_origin.spec();
+ const std::string id =
+ frame_origin.spec() + ":" + top_level_origin.spec() + ":" + method;
- const auto& it = queries_.find(id);
- if (it == queries_.end()) {
+ auto it = per_method_queries_.find(id);
+ if (it == per_method_queries_.end()) {
auto timer = std::make_unique<base::OneShotTimer>();
- timer->Start(
- FROM_HERE, base::TimeDelta::FromMinutes(30),
- base::BindOnce(&CanMakePaymentQuery::ExpireQuotaForFrameOrigin,
- base::Unretained(this), id));
+ timer->Start(FROM_HERE, base::TimeDelta::FromMinutes(30),
+ base::BindOnce(
+ &CanMakePaymentQuery::ExpireQuotaForFrameOriginAndMethod,
+ base::Unretained(this), id));
timers_.insert(std::make_pair(id, std::move(timer)));
- queries_.insert(std::make_pair(id, query));
- return true;
+ per_method_queries_.insert(std::make_pair(id, params));
+ continue;
}
- return it->second == query;
+ can_query &= it->second == params;
}
+
+ return can_query;
+}
+
+bool CanMakePaymentQuery::CanQueryWithoutPerMethodQuota(
+ const GURL& top_level_origin,
+ const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query) {
+ const std::string id = frame_origin.spec() + ":" + top_level_origin.spec();
+
+ const auto& it = queries_.find(id);
+ if (it == queries_.end()) {
+ auto timer = std::make_unique<base::OneShotTimer>();
+ timer->Start(FROM_HERE, base::TimeDelta::FromMinutes(30),
+ base::BindOnce(&CanMakePaymentQuery::ExpireQuotaForFrameOrigin,
+ base::Unretained(this), id));
+ timers_.insert(std::make_pair(id, std::move(timer)));
+ queries_.insert(std::make_pair(id, query));
+ return true;
+ }
+
+ return it->second == query;
}
void CanMakePaymentQuery::ExpireQuotaForFrameOrigin(const std::string& id) {
diff --git a/chromium/components/payments/core/can_make_payment_query.h b/chromium/components/payments/core/can_make_payment_query.h
index 6c9e6002c47..8c7be07f56b 100644
--- a/chromium/components/payments/core/can_make_payment_query.h
+++ b/chromium/components/payments/core/can_make_payment_query.h
@@ -42,15 +42,23 @@ class CanMakePaymentQuery : public KeyedService {
// also allowed.
bool CanQuery(const GURL& top_level_origin,
const GURL& frame_origin,
- const std::map<std::string, std::set<std::string>>& query);
+ const std::map<std::string, std::set<std::string>>& query,
+ bool per_method_quota);
private:
+ bool CanQueryWithPerMethodQuota(
+ const GURL& top_level_origin,
+ const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query);
+ bool CanQueryWithoutPerMethodQuota(
+ const GURL& top_level_origin,
+ const GURL& frame_origin,
+ const std::map<std::string, std::set<std::string>>& query);
void ExpireQuotaForFrameOrigin(const std::string& id);
void ExpireQuotaForFrameOriginAndMethod(const std::string& id);
// A mapping of an identififer to the timer that, when fired, allows the frame
- // to invoke canMakePayment() with different payment methods specific
- // parameters.
+ // to invoke canMakePayment() with the same identifier again.
std::map<std::string, std::unique_ptr<base::OneShotTimer>> timers_;
// A mapping of frame origin and top level origin to its last query. Each
diff --git a/chromium/components/payments/core/can_make_payment_query_unittest.cc b/chromium/components/payments/core/can_make_payment_query_unittest.cc
index ca4be0d8d23..90d7a1b381d 100644
--- a/chromium/components/payments/core/can_make_payment_query_unittest.cc
+++ b/chromium/components/payments/core/can_make_payment_query_unittest.cc
@@ -4,9 +4,7 @@
#include "components/payments/core/can_make_payment_query.h"
-#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
-#include "components/payments/core/features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -26,9 +24,11 @@ class CanMakePaymentQueryTest : public ::testing::Test {
TEST_F(CanMakePaymentQueryTest,
SameHttpsOriginCannotQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("https://example.com"),
- GURL("https://example.com"), {{"amex", {}}}));
+ GURL("https://example.com"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_FALSE(guard_.CanQuery(GURL("https://example.com"),
- GURL("https://example.com"), {{"visa", {}}}));
+ GURL("https://example.com"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// A localhost website is not allowed to query all of the networks of the cards
@@ -36,9 +36,11 @@ TEST_F(CanMakePaymentQueryTest,
TEST_F(CanMakePaymentQueryTest,
SameLocalhostOriginCannotQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("http://localhost:8080"),
- GURL("http://localhost:8080"), {{"amex", {}}}));
+ GURL("http://localhost:8080"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_FALSE(guard_.CanQuery(GURL("http://localhost:8080"),
- GURL("http://localhost:8080"), {{"visa", {}}}));
+ GURL("http://localhost:8080"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// A file website is not allowed to query all of the networks of the cards in
@@ -46,9 +48,11 @@ TEST_F(CanMakePaymentQueryTest,
TEST_F(CanMakePaymentQueryTest,
SameFileOriginCannotQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("file:///tmp/test.html"),
- GURL("file:///tmp/test.html"), {{"amex", {}}}));
+ GURL("file:///tmp/test.html"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_FALSE(guard_.CanQuery(GURL("file:///tmp/test.html"),
- GURL("file:///tmp/test.html"), {{"visa", {}}}));
+ GURL("file:///tmp/test.html"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// Different HTTPS websites are allowed to query different card networks in
@@ -56,9 +60,11 @@ TEST_F(CanMakePaymentQueryTest,
TEST_F(CanMakePaymentQueryTest,
DifferentHttpsOriginsCanQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("https://example.com"),
- GURL("https://example.com"), {{"amex", {}}}));
+ GURL("https://example.com"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(guard_.CanQuery(GURL("https://not-example.com"),
- GURL("https://not-example.com"), {{"visa", {}}}));
+ GURL("https://not-example.com"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// Different localhost websites are allowed to query different card networks in
@@ -66,9 +72,11 @@ TEST_F(CanMakePaymentQueryTest,
TEST_F(CanMakePaymentQueryTest,
DifferentLocalhostOriginsCanQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("http://localhost:8080"),
- GURL("http://localhost:8080"), {{"amex", {}}}));
+ GURL("http://localhost:8080"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(guard_.CanQuery(GURL("http://localhost:9090"),
- GURL("http://localhost:9090"), {{"visa", {}}}));
+ GURL("http://localhost:9090"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// Different file websites are allowed to query different card networks in
@@ -76,31 +84,32 @@ TEST_F(CanMakePaymentQueryTest,
TEST_F(CanMakePaymentQueryTest,
DifferentFileOriginsCanQueryTwoDifferentCardNetworks) {
EXPECT_TRUE(guard_.CanQuery(GURL("file:///tmp/test.html"),
- GURL("file:///tmp/test.html"), {{"amex", {}}}));
+ GURL("file:///tmp/test.html"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(guard_.CanQuery(GURL("file:///tmp/not-test.html"),
- GURL("file:///tmp/not-test.html"),
- {{"visa", {}}}));
+ GURL("file:///tmp/not-test.html"), {{"visa", {}}},
+ /*per_method_quota=*/true));
}
// The same website is not allowed to query the same payment method with
// different parameters.
TEST_F(CanMakePaymentQueryTest,
SameOriginCannotQueryBasicCardWithTwoDifferentCardNetworks) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(
- features::kWebPaymentsPerMethodCanMakePaymentQuota);
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"basic-card", {"{supportedNetworks: ['visa']}"}},
- {"https://alicepay.com", {"{alicePayParameter: 1}"}}}));
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"basic-card", {"{supportedNetworks: ['visa']}"}},
- {"https://bobpay.com", {"{bobPayParameter: 2}"}}}));
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/true));
EXPECT_FALSE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"basic-card", {"{supportedNetworks: ['amex']}"}},
- {"https://bobpay.com", {"{bobPayParameter: 2}"}}}));
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/true));
}
// Two different websites are allowed to query the same payment method with
@@ -109,64 +118,145 @@ TEST_F(CanMakePaymentQueryTest,
DifferentOriginsCanQueryBasicCardWithTwoDifferentCardNetworks) {
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
- {{"basic-card", {"{supportedNetworks: ['visa']}"}}}));
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(guard_.CanQuery(
GURL("https://not-example.com"), GURL("https://not-example.com"),
- {{"basic-card", {"{supportedNetworks: ['amex']}"}}}));
+ {{"basic-card", {"{supportedNetworks: ['amex']}"}}},
+ /*per_method_quota=*/true));
}
// A website can query several different payment methods, as long as each
// payment method is queried with the same payment-method-specific data.
TEST_F(CanMakePaymentQueryTest,
SameOriginCanQuerySeveralDifferentPaymentMethodIdentifiers) {
- base::test::ScopedFeatureList features;
- features.InitAndEnableFeature(
- features::kWebPaymentsPerMethodCanMakePaymentQuota);
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"basic-card", {"{supportedNetworks: ['visa']}"}},
- {"https://alicepay.com", {"{alicePayParameter: 1}"}}}));
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"https://alicepay.com", {"{alicePayParameter: 1}"}},
- {"https://bobpay.com", {"{bobPayParameter: 2}"}}}));
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/true));
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"https://bobpay.com", {"{bobPayParameter: 2}"}},
- {"basic-card", {"{supportedNetworks: ['visa']}"}}}));
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/true));
}
// A website cannot query several different payment methods without the
-// per-method query feature, even if method-specific data remains unchanged.
+// per-method quota, even if method-specific data remains unchanged.
TEST_F(CanMakePaymentQueryTest,
SameOriginCannotQueryDifferentMethodsWithoutPerMethodQuota) {
- base::test::ScopedFeatureList features;
- features.InitAndDisableFeature(
- features::kWebPaymentsPerMethodCanMakePaymentQuota);
EXPECT_TRUE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"basic-card", {"{supportedNetworks: ['visa']}"}},
- {"https://alicepay.com", {"{alicePayParameter: 1}"}}}));
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/false));
EXPECT_FALSE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"https://alicepay.com", {"{alicePayParameter: 1}"}},
- {"https://bobpay.com", {"{bobPayParameter: 2}"}}}));
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/false));
EXPECT_FALSE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
{{"https://bobpay.com", {"{bobPayParameter: 2}"}},
- {"basic-card", {"{supportedNetworks: ['visa']}"}}}));
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/false));
+}
+
+// An instance of a website with per-method quota enabled (e.g., through an
+// origin trial) can query different payment methods, as long as each payment
+// method is queried with the same method-specific data. Another instance of the
+// same website (e.g., in a different tab) without the per-method quota feature
+// cannot query different payment methods.
+TEST_F(CanMakePaymentQueryTest, SameWebsiteDifferentQuotaPolicy) {
+ // First instance of https://example.com has per-method quota feature enabled
+ // and so can query different payment methods, as long as the method-specific
+ // data stays the same.
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}},
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/true));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://alicepay.com", {"{alicePayParameter: 1}"}},
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/true));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://bobpay.com", {"{bobPayParameter: 2}"}},
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/true));
+
+ // Second instance of https://example.com has per-method quota feature
+ // disabled and so can only repeat the first query.
+ EXPECT_FALSE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://alicepay.com", {"{alicePayParameter: 1}"}},
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/false));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}},
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/false));
+ EXPECT_FALSE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://bobpay.com", {"{bobPayParameter: 2}"}},
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/false));
+
+ // The two website queries can be interleaved any number of times in any order
+ // with the same results.
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}},
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/true));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://bobpay.com", {"{bobPayParameter: 2}"}},
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/true));
+ EXPECT_FALSE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://alicepay.com", {"{alicePayParameter: 1}"}},
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/false));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}},
+ {"https://alicepay.com", {"{alicePayParameter: 1}"}}},
+ /*per_method_quota=*/false));
+ EXPECT_TRUE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://alicepay.com", {"{alicePayParameter: 1}"}},
+ {"https://bobpay.com", {"{bobPayParameter: 2}"}}},
+ /*per_method_quota=*/true));
+ EXPECT_FALSE(
+ guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
+ {{"https://bobpay.com", {"{bobPayParameter: 2}"}},
+ {"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/false));
}
// A website is not allowed to query all of the networks of the cards in user's
-// autofill database, even if they vary the format of the query.
+// autofill database, even if the website varies the format of the query.
TEST_F(
CanMakePaymentQueryTest,
SameOriginCannotQueryDifferentCardNetworksAndTypesUsingDifferentFormats) {
EXPECT_TRUE(guard_.CanQuery(GURL("https://example.com"),
- GURL("https://example.com"), {{"amex", {}}}));
+ GURL("https://example.com"), {{"amex", {}}},
+ /*per_method_quota=*/true));
EXPECT_FALSE(
guard_.CanQuery(GURL("https://example.com"), GURL("https://example.com"),
- {{"basic-card", {"{supportedNetworks: ['visa']}"}}}));
+ {{"basic-card", {"{supportedNetworks: ['visa']}"}}},
+ /*per_method_quota=*/true));
}
} // namespace
diff --git a/chromium/components/payments/core/currency_formatter_unittest.cc b/chromium/components/payments/core/currency_formatter_unittest.cc
index fa76a7ecfab..491dd19a2bd 100644
--- a/chromium/components/payments/core/currency_formatter_unittest.cc
+++ b/chromium/components/payments/core/currency_formatter_unittest.cc
@@ -55,7 +55,7 @@ TEST_P(PaymentsCurrencyFormatterTest, IsValidCurrencyFormat) {
formatter.formatted_currency_code());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CurrencyAmounts,
PaymentsCurrencyFormatterTest,
testing::Values(
diff --git a/chromium/components/payments/core/features.cc b/chromium/components/payments/core/features.cc
index 47cd23d6847..e96ce47e8ef 100644
--- a/chromium/components/payments/core/features.cc
+++ b/chromium/components/payments/core/features.cc
@@ -15,15 +15,19 @@ const base::Feature kWebPaymentsNativeApps{"WebPaymentsNativeApps",
base::FEATURE_DISABLED_BY_DEFAULT};
#endif
+// TODO(rouslan): Remove this.
const base::Feature kWebPaymentsMethodSectionOrderV2{
"WebPaymentsMethodSectionOrderV2", base::FEATURE_DISABLED_BY_DEFAULT};
+// TODO(rouslan): Remove this.
const base::Feature kWebPaymentsModifiers{"WebPaymentsModifiers",
base::FEATURE_ENABLED_BY_DEFAULT};
+// TODO(rouslan): Remove this.
const base::Feature kWebPaymentsSingleAppUiSkip{
"WebPaymentsSingleAppUiSkip", base::FEATURE_ENABLED_BY_DEFAULT};
+// TODO(rouslan): Remove this.
const base::Feature kWebPaymentsJustInTimePaymentApp{
"WebPaymentsJustInTimePaymentApp", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromium/components/payments/core/journey_logger.cc b/chromium/components/payments/core/journey_logger.cc
index 307337f6742..8b7ed73ae8e 100644
--- a/chromium/components/payments/core/journey_logger.cc
+++ b/chromium/components/payments/core/journey_logger.cc
@@ -98,6 +98,14 @@ void JourneyLogger::SetCanMakePaymentValue(bool value) {
: EVENT_CAN_MAKE_PAYMENT_FALSE);
}
+void JourneyLogger::SetHasEnrolledInstrumentValue(bool value) {
+ if (is_incognito_)
+ return;
+
+ SetEventOccurred(value ? EVENT_HAS_ENROLLED_INSTRUMENT_TRUE
+ : EVENT_HAS_ENROLLED_INSTRUMENT_FALSE);
+}
+
void JourneyLogger::SetEventOccurred(Event event) {
events_ |= event;
}
diff --git a/chromium/components/payments/core/journey_logger.h b/chromium/components/payments/core/journey_logger.h
index 7db5ce3a8af..87e94f205f8 100644
--- a/chromium/components/payments/core/journey_logger.h
+++ b/chromium/components/payments/core/journey_logger.h
@@ -91,6 +91,11 @@ class JourneyLogger {
EVENT_SELECTED_CREDIT_CARD = 1 << 18,
EVENT_SELECTED_GOOGLE = 1 << 19,
EVENT_SELECTED_OTHER = 1 << 20,
+ // hasEnrolledInstrument was called with a result of "true" or "false",
+ // respectively. An absence of both events means hasEnrolledInstrument was
+ // not called, or the user was in incognito mode.
+ EVENT_HAS_ENROLLED_INSTRUMENT_TRUE = 1 << 21,
+ EVENT_HAS_ENROLLED_INSTRUMENT_FALSE = 1 << 22,
EVENT_ENUM_MAX = 2097152,
};
@@ -140,10 +145,14 @@ class JourneyLogger {
int number,
bool has_valid_suggestion);
- // Records the fact that the merchant called CanMakePayment and records it's
+ // Records the fact that the merchant called CanMakePayment and records its
// return value.
void SetCanMakePaymentValue(bool value);
+ // Records the fact that the merchant called HasEnrolledInstrument and records
+ // its return value.
+ void SetHasEnrolledInstrumentValue(bool value);
+
// Records that an event occurred.
void SetEventOccurred(Event event);
diff --git a/chromium/components/payments/core/payment_address.cc b/chromium/components/payments/core/payment_address.cc
index e316b5e0f6f..78cfdd026d4 100644
--- a/chromium/components/payments/core/payment_address.cc
+++ b/chromium/components/payments/core/payment_address.cc
@@ -16,7 +16,6 @@ static const char kAddressAddressLine[] = "addressLine";
static const char kAddressCity[] = "city";
static const char kAddressCountry[] = "country";
static const char kAddressDependentLocality[] = "dependentLocality";
-static const char kAddressLanguageCode[] = "languageCode";
static const char kAddressOrganization[] = "organization";
static const char kAddressPhone[] = "phone";
static const char kAddressPostalCode[] = "postalCode";
@@ -41,7 +40,6 @@ std::unique_ptr<base::DictionaryValue> PaymentAddressToDictionaryValue(
result->SetString(kAddressDependentLocality, address.dependent_locality);
result->SetString(kAddressPostalCode, address.postal_code);
result->SetString(kAddressSortingCode, address.sorting_code);
- result->SetString(kAddressLanguageCode, address.language_code);
result->SetString(kAddressOrganization, address.organization);
result->SetString(kAddressRecipient, address.recipient);
result->SetString(kAddressPhone, address.phone);
diff --git a/chromium/components/payments/core/payment_address_unittest.cc b/chromium/components/payments/core/payment_address_unittest.cc
index 82efff3c6c5..17d7555cc44 100644
--- a/chromium/components/payments/core/payment_address_unittest.cc
+++ b/chromium/components/payments/core/payment_address_unittest.cc
@@ -71,13 +71,6 @@ TEST(PaymentRequestTest, PaymentAddressEquality) {
address2.sorting_code = "14390";
EXPECT_TRUE(address1.Equals(address2));
- address1.language_code = "fr";
- EXPECT_FALSE(address1.Equals(address2));
- address2.language_code = "zh-HK";
- EXPECT_FALSE(address1.Equals(address2));
- address2.language_code = "fr";
- EXPECT_TRUE(address1.Equals(address2));
-
address1.organization = "The Willy Wonka Candy Company";
EXPECT_FALSE(address1.Equals(address2));
address2.organization = "Sears";
diff --git a/chromium/components/payments/core/payment_details_validation_unittest.cc b/chromium/components/payments/core/payment_details_validation_unittest.cc
index 2dc3629d6ce..51cfa727063 100644
--- a/chromium/components/payments/core/payment_details_validation_unittest.cc
+++ b/chromium/components/payments/core/payment_details_validation_unittest.cc
@@ -44,7 +44,7 @@ class PaymentDetailsValidationTest
: public ::testing::TestWithParam<PaymentDetailsValidationTestCase> {};
TEST_P(PaymentDetailsValidationTest, Test) {
- auto value = base::JSONReader::Read(GetParam().details);
+ auto value = base::JSONReader::ReadDeprecated(GetParam().details);
ASSERT_NE(nullptr, value.get()) << "Should be in JSON format";
auto dictionary = base::DictionaryValue::From(std::move(value));
ASSERT_NE(nullptr, dictionary.get()) << "Should be a dictionary";
@@ -56,7 +56,7 @@ TEST_P(PaymentDetailsValidationTest, Test) {
EXPECT_EQ(GetParam().expect_valid, ValidatePaymentDetails(details, &unused));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
TestCases,
PaymentDetailsValidationTest,
::testing::Values(PaymentDetailsValidationTestCase(R"(
diff --git a/chromium/components/payments/core/payment_instrument.h b/chromium/components/payments/core/payment_instrument.h
index c444def14d0..1098e34501a 100644
--- a/chromium/components/payments/core/payment_instrument.h
+++ b/chromium/components/payments/core/payment_instrument.h
@@ -52,6 +52,7 @@ class PaymentInstrument {
virtual base::string16 GetMissingInfoLabel() const = 0;
// Returns whether the instrument is valid for the purposes of responding to
// canMakePayment.
+ // TODO(crbug.com/915907): rename to IsValidForHasEnrolledInstrument.
virtual bool IsValidForCanMakePayment() const = 0;
// Records the use of this payment instrument.
virtual void RecordUse() = 0;
diff --git a/chromium/components/payments/core/payment_manifest_downloader.cc b/chromium/components/payments/core/payment_manifest_downloader.cc
index 999976a5562..5bd147cfe9d 100644
--- a/chromium/components/payments/core/payment_manifest_downloader.cc
+++ b/chromium/components/payments/core/payment_manifest_downloader.cc
@@ -7,6 +7,7 @@
#include <unordered_map>
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/optional.h"
#include "base/stl_util.h"
diff --git a/chromium/components/payments/core/payment_manifest_downloader_unittest.cc b/chromium/components/payments/core/payment_manifest_downloader_unittest.cc
index 5443e87bcab..421c5e43109 100644
--- a/chromium/components/payments/core/payment_manifest_downloader_unittest.cc
+++ b/chromium/components/payments/core/payment_manifest_downloader_unittest.cc
@@ -4,6 +4,7 @@
#include "components/payments/core/payment_manifest_downloader.h"
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/payments/core/payment_request_data_util.cc b/chromium/components/payments/core/payment_request_data_util.cc
index 12a624b6e1b..21006b10171 100644
--- a/chromium/components/payments/core/payment_request_data_util.cc
+++ b/chromium/components/payments/core/payment_request_data_util.cc
@@ -56,13 +56,6 @@ mojom::PaymentAddressPtr GetPaymentAddressFromAutofillProfile(
payment_address->recipient =
base::UTF16ToUTF8(profile.GetInfo(autofill::NAME_FULL, app_locale));
- // The autofill profile |language_code| is the BCP-47 language tag (e.g.,
- // "ja-Latn"), which can be split into a language code (e.g., "ja") and a
- // script code (e.g., "Latn").
- PaymentsValidators::SplitLanguageTag(profile.language_code(),
- &payment_address->language_code,
- &payment_address->script_code);
-
// TODO(crbug.com/705945): Format phone number according to spec.
payment_address->phone =
base::UTF16ToUTF8(profile.GetRawInfo(autofill::PHONE_HOME_WHOLE_NUMBER));
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 ec4e86e53d3..9186ad13ae4 100644
--- a/chromium/components/payments/core/payment_request_data_util_unittest.cc
+++ b/chromium/components/payments/core/payment_request_data_util_unittest.cc
@@ -35,7 +35,6 @@ TEST(PaymentRequestDataUtilTest, GetPaymentAddressFromAutofillProfile) {
"\"city\":\"Elysium\","
"\"country\":\"US\","
"\"dependentLocality\":\"\","
- "\"languageCode\":\"\","
"\"organization\":\"Underworld\","
"\"phone\":\"16502111111\","
"\"postalCode\":\"91111\","
@@ -63,7 +62,6 @@ TEST(PaymentRequestDataUtilTest, GetBasicCardResponseFromAutofillCreditCard) {
"\"city\":\"Elysium\","
"\"country\":\"US\","
"\"dependentLocality\":\"\","
- "\"languageCode\":\"\","
"\"organization\":\"Underworld\","
"\"phone\":\"16502111111\","
"\"postalCode\":\"91111\","
diff --git a/chromium/components/payments/core/payments_validators.cc b/chromium/components/payments/core/payments_validators.cc
index b90b0db9a07..bd5669f9710 100644
--- a/chromium/components/payments/core/payments_validators.cc
+++ b/chromium/components/payments/core/payments_validators.cc
@@ -59,47 +59,6 @@ bool PaymentsValidators::IsValidCountryCodeFormat(
}
// static
-bool PaymentsValidators::IsValidLanguageCodeFormat(
- const std::string& code,
- std::string* optional_error_message) {
- if (RE2::FullMatch(code, "([a-z]{2,3})?"))
- return true;
-
- if (optional_error_message)
- *optional_error_message =
- "'" + code +
- "' is not a valid BCP-47 language code, should be "
- "2-3 lower case letters [a-z]";
-
- return false;
-}
-
-// static
-bool PaymentsValidators::IsValidScriptCodeFormat(
- const std::string& code,
- std::string* optional_error_message) {
- if (RE2::FullMatch(code, "([A-Z][a-z]{3})?"))
- return true;
-
- if (optional_error_message)
- *optional_error_message =
- "'" + code +
- "' is not a valid ISO 15924 script code, should be "
- "an upper case letter [A-Z] followed by 3 lower "
- "case letters [a-z]";
-
- return false;
-}
-
-// static
-void PaymentsValidators::SplitLanguageTag(const std::string& tag,
- std::string* language_code,
- std::string* script_code) {
- RE2::FullMatch(tag, "^([a-z]{2})(-([A-Z][a-z]{3}))?(-[A-Za-z]+)*$",
- language_code, (void*)nullptr, script_code);
-}
-
-// static
bool PaymentsValidators::IsValidErrorMsgFormat(
const std::string& error,
std::string* optional_error_message) {
@@ -123,13 +82,11 @@ bool PaymentsValidators::IsValidAddressErrorsFormat(
IsValidErrorMsgFormat(errors->country, optional_error_message) &&
IsValidErrorMsgFormat(errors->dependent_locality,
optional_error_message) &&
- IsValidErrorMsgFormat(errors->language_code, optional_error_message) &&
IsValidErrorMsgFormat(errors->organization, optional_error_message) &&
IsValidErrorMsgFormat(errors->phone, optional_error_message) &&
IsValidErrorMsgFormat(errors->postal_code, optional_error_message) &&
IsValidErrorMsgFormat(errors->recipient, optional_error_message) &&
IsValidErrorMsgFormat(errors->region, optional_error_message) &&
- IsValidErrorMsgFormat(errors->region_code, optional_error_message) &&
IsValidErrorMsgFormat(errors->sorting_code, optional_error_message);
}
diff --git a/chromium/components/payments/core/payments_validators.h b/chromium/components/payments/core/payments_validators.h
index 6570d388ae7..1d4879651b0 100644
--- a/chromium/components/payments/core/payments_validators.h
+++ b/chromium/components/payments/core/payments_validators.h
@@ -28,19 +28,6 @@ class PaymentsValidators {
static bool IsValidCountryCodeFormat(const std::string& code,
std::string* optional_error_message);
- // Returns true if |code| is a valid ISO 639 language code.
- static bool IsValidLanguageCodeFormat(const std::string& code,
- std::string* optional_error_message);
-
- // Returns true if |code| is a valid ISO 15924 script code.
- static bool IsValidScriptCodeFormat(const std::string& code,
- std::string* optional_error_message);
-
- // Splits BCP-57 |tag| into |language_code| and |script_code|.
- static void SplitLanguageTag(const std::string& tag,
- std::string* language_code,
- std::string* script_code);
-
// Returns false if |error| is too long (greater than 2048).
static bool IsValidErrorMsgFormat(const std::string& code,
std::string* optional_error_message);
diff --git a/chromium/components/payments/core/payments_validators_unittest.cc b/chromium/components/payments/core/payments_validators_unittest.cc
index 3e09be788cd..502b3a255f4 100644
--- a/chromium/components/payments/core/payments_validators_unittest.cc
+++ b/chromium/components/payments/core/payments_validators_unittest.cc
@@ -5,6 +5,7 @@
#include "components/payments/core/payments_validators.h"
#include <ostream> // NOLINT
+
#include "testing/gtest/include/gtest/gtest.h"
namespace payments {
@@ -43,7 +44,7 @@ TEST_P(PaymentsCurrencyValidatorTest, IsValidCurrencyCodeFormat) {
GetParam().code, nullptr));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CurrencyCodes,
PaymentsCurrencyValidatorTest,
testing::Values(
@@ -94,7 +95,7 @@ TEST_P(PaymentsAmountValidatorTest, IsValidAmountFormat) {
nullptr));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
Amounts,
PaymentsAmountValidatorTest,
testing::Values(TestCase("0", true),
@@ -139,117 +140,15 @@ TEST_P(PaymentsRegionValidatorTest, IsValidCountryCodeFormat) {
GetParam().input, nullptr));
}
-INSTANTIATE_TEST_CASE_P(CountryCodes,
- PaymentsRegionValidatorTest,
- testing::Values(TestCase("US", true),
- // Invalid country code formats
- TestCase("U1", false),
- TestCase("U", false),
- TestCase("us", false),
- TestCase("USA", false),
- TestCase("", false)));
-
-class PaymentsLanguageValidatorTest : public testing::TestWithParam<TestCase> {
-};
-
-TEST_P(PaymentsLanguageValidatorTest, IsValidLanguageCodeFormat) {
- std::string error_message;
- EXPECT_EQ(GetParam().expected_valid,
- payments::PaymentsValidators::IsValidLanguageCodeFormat(
- GetParam().input, &error_message))
- << error_message;
- EXPECT_EQ(GetParam().expected_valid, error_message.empty()) << error_message;
-
- EXPECT_EQ(GetParam().expected_valid,
- payments::PaymentsValidators::IsValidLanguageCodeFormat(
- GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_CASE_P(LanguageCodes,
- PaymentsLanguageValidatorTest,
- testing::Values(TestCase("", true),
- TestCase("en", true),
- TestCase("eng", true),
- // Invalid language code formats
- TestCase("e1", false),
- TestCase("en1", false),
- TestCase("e", false),
- TestCase("engl", false),
- TestCase("EN", false)));
-
-class PaymentsScriptValidatorTest : public testing::TestWithParam<TestCase> {};
-
-TEST_P(PaymentsScriptValidatorTest, IsValidScriptCodeFormat) {
- std::string error_message;
- EXPECT_EQ(GetParam().expected_valid,
- payments::PaymentsValidators::IsValidScriptCodeFormat(
- GetParam().input, &error_message))
- << error_message;
- EXPECT_EQ(GetParam().expected_valid, error_message.empty()) << error_message;
-
- EXPECT_EQ(GetParam().expected_valid,
- payments::PaymentsValidators::IsValidScriptCodeFormat(
- GetParam().input, nullptr));
-}
-
-INSTANTIATE_TEST_CASE_P(ScriptCodes,
- PaymentsScriptValidatorTest,
- testing::Values(TestCase("", true),
- TestCase("Latn", true),
- // Invalid script code formats
- TestCase("Lat1", false),
- TestCase("1lat", false),
- TestCase("Latin", false),
- TestCase("Lat", false),
- TestCase("latn", false),
- TestCase("LATN", false)));
-
-struct LanguageTagTestCase {
- LanguageTagTestCase(const char* language_tag,
- const char* expected_language_code,
- const char* expected_script_code)
- : language_tag(language_tag),
- expected_language_code(expected_language_code),
- expected_script_code(expected_script_code) {}
- ~LanguageTagTestCase() {}
-
- const char* language_tag;
- const char* expected_language_code;
- const char* expected_script_code;
-};
-
-class PaymentsLanguageTagSplitTest
- : public testing::TestWithParam<LanguageTagTestCase> {};
-
-TEST_P(PaymentsLanguageTagSplitTest, Test) {
- std::string language_code;
- std::string script_code;
-
- PaymentsValidators::SplitLanguageTag(GetParam().language_tag, &language_code,
- &script_code);
-
- EXPECT_EQ(GetParam().expected_language_code, language_code);
- EXPECT_EQ(GetParam().expected_script_code, script_code);
- EXPECT_TRUE(
- PaymentsValidators::IsValidLanguageCodeFormat(language_code, nullptr));
- EXPECT_TRUE(
- PaymentsValidators::IsValidScriptCodeFormat(script_code, nullptr));
-}
-
-INSTANTIATE_TEST_CASE_P(
- LanguageTags,
- PaymentsLanguageTagSplitTest,
- testing::Values(LanguageTagTestCase("", "", ""),
- LanguageTagTestCase("ja", "ja", ""),
- LanguageTagTestCase("ja-Latn", "ja", "Latn"),
- LanguageTagTestCase("ja-Latn-JP", "ja", "Latn"),
- LanguageTagTestCase("ja-JP", "ja", ""),
- LanguageTagTestCase("Latn", "", ""),
- LanguageTagTestCase("JP", "", ""),
- LanguageTagTestCase("en", "en", ""),
- LanguageTagTestCase("en-Latn", "en", "Latn"),
- LanguageTagTestCase("en-Latn-US", "en", "Latn"),
- LanguageTagTestCase("en-US", "en", "")));
+INSTANTIATE_TEST_SUITE_P(CountryCodes,
+ PaymentsRegionValidatorTest,
+ testing::Values(TestCase("US", true),
+ // Invalid country code formats
+ TestCase("U1", false),
+ TestCase("U", false),
+ TestCase("us", false),
+ TestCase("USA", false),
+ TestCase("", false)));
struct ValidationErrorsTestCase {
explicit ValidationErrorsTestCase(bool expected_valid)
@@ -262,13 +161,11 @@ struct ValidationErrorsTestCase {
const char* m_shipping_address_city = "";
const char* m_shipping_address_country = "";
const char* m_shipping_address_dependent_locality = "";
- const char* m_shipping_address_language_code = "";
const char* m_shipping_address_organization = "";
const char* m_shipping_address_phone = "";
const char* m_shipping_address_postal_code = "";
const char* m_shipping_address_recipient = "";
const char* m_shipping_address_region = "";
- const char* m_shipping_address_region_code = "";
const char* m_shipping_address_sorting_code = "";
bool expected_valid;
};
@@ -296,13 +193,11 @@ mojom::PaymentValidationErrorsPtr toPaymentValidationErrors(
shipping_address->country = test_case.m_shipping_address_country;
shipping_address->dependent_locality =
test_case.m_shipping_address_dependent_locality;
- shipping_address->language_code = test_case.m_shipping_address_language_code;
shipping_address->organization = test_case.m_shipping_address_organization;
shipping_address->phone = test_case.m_shipping_address_phone;
shipping_address->postal_code = test_case.m_shipping_address_postal_code;
shipping_address->recipient = test_case.m_shipping_address_recipient;
shipping_address->region = test_case.m_shipping_address_region;
- shipping_address->region_code = test_case.m_shipping_address_region_code;
shipping_address->sorting_code = test_case.m_shipping_address_sorting_code;
errors->payer = std::move(payer);
@@ -326,7 +221,7 @@ TEST_P(PaymentsErrorMessageValidatorTest,
<< error_message;
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PaymentValidationErrorss,
PaymentsErrorMessageValidatorTest,
testing::Values(
@@ -342,9 +237,6 @@ INSTANTIATE_TEST_CASE_P(
VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
"test",
true),
- VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
- "test",
- true),
VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
"test",
true),
@@ -352,7 +244,6 @@ INSTANTIATE_TEST_CASE_P(
VALIDATION_ERRORS_TEST_CASE(shipping_address_postal_code, "test", true),
VALIDATION_ERRORS_TEST_CASE(shipping_address_recipient, "test", true),
VALIDATION_ERRORS_TEST_CASE(shipping_address_region, "test", true),
- VALIDATION_ERRORS_TEST_CASE(shipping_address_region_code, "test", true),
VALIDATION_ERRORS_TEST_CASE(shipping_address_sorting_code,
"test",
true),
@@ -374,9 +265,6 @@ INSTANTIATE_TEST_CASE_P(
VALIDATION_ERRORS_TEST_CASE(shipping_address_dependent_locality,
LongString2049(),
false),
- VALIDATION_ERRORS_TEST_CASE(shipping_address_language_code,
- LongString2049(),
- false),
VALIDATION_ERRORS_TEST_CASE(shipping_address_organization,
LongString2049(),
false),
@@ -392,9 +280,6 @@ INSTANTIATE_TEST_CASE_P(
VALIDATION_ERRORS_TEST_CASE(shipping_address_region,
LongString2049(),
false),
- VALIDATION_ERRORS_TEST_CASE(shipping_address_region_code,
- LongString2049(),
- false),
VALIDATION_ERRORS_TEST_CASE(shipping_address_sorting_code,
LongString2049(),
false)));
diff --git a/chromium/components/payments/mojom/payment_request_data.mojom b/chromium/components/payments/mojom/payment_request_data.mojom
index e1e008c3ca2..cbe693dbbbb 100644
--- a/chromium/components/payments/mojom/payment_request_data.mojom
+++ b/chromium/components/payments/mojom/payment_request_data.mojom
@@ -17,15 +17,6 @@ struct PaymentAddress {
string dependent_locality;
string postal_code;
string sorting_code;
-
- // Optional shortest ISO 639 language code. Two or three lower case ASCII
- // letters.
- string language_code;
-
- // Optional ISO 15924 script code. Four ASCII letters. The first letter is
- // upper case; the rest are lower case.
- string script_code;
-
string organization;
string recipient;
string phone;
@@ -68,12 +59,10 @@ struct AddressErrors {
string city;
string country;
string dependent_locality;
- string language_code;
string organization;
string phone;
string postal_code;
string recipient;
string region;
- string region_code;
string sorting_code;
};
diff --git a/chromium/components/pdf/browser/pdf_web_contents_helper.cc b/chromium/components/pdf/browser/pdf_web_contents_helper.cc
index 02d00b80381..c48ca415ef5 100644
--- a/chromium/components/pdf/browser/pdf_web_contents_helper.cc
+++ b/chromium/components/pdf/browser/pdf_web_contents_helper.cc
@@ -6,9 +6,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"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/referrer_type_converters.h"
@@ -83,6 +81,10 @@ void PDFWebContentsHelper::SelectionChanged(const gfx::PointF& left,
DidScroll();
}
+void PDFWebContentsHelper::SetPluginCanSave(bool can_save) {
+ client_->SetPluginCanSave(web_contents(), can_save);
+}
+
void PDFWebContentsHelper::DidScroll() {
if (!touch_selection_controller_client_manager_)
InitTouchSelectionClientManager();
@@ -149,7 +151,7 @@ PDFWebContentsHelper::CreateDrawable() {
void PDFWebContentsHelper::OnManagerWillDestroy(
content::TouchSelectionControllerClientManager* manager) {
- DCHECK(manager == touch_selection_controller_client_manager_);
+ DCHECK_EQ(touch_selection_controller_client_manager_, manager);
manager->RemoveObserver(this);
touch_selection_controller_client_manager_ = nullptr;
}
diff --git a/chromium/components/pdf/browser/pdf_web_contents_helper.h b/chromium/components/pdf/browser/pdf_web_contents_helper.h
index 2150fc0a1f4..53713fedf97 100644
--- a/chromium/components/pdf/browser/pdf_web_contents_helper.h
+++ b/chromium/components/pdf/browser/pdf_web_contents_helper.h
@@ -6,9 +6,7 @@
#define COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_H_
#include <memory>
-#include <string>
-#include "base/callback.h"
#include "base/macros.h"
#include "components/pdf/common/pdf.mojom.h"
#include "content/public/browser/touch_selection_controller_client_manager.h"
@@ -67,6 +65,7 @@ class PDFWebContentsHelper
private:
friend class content::WebContentsUserData<PDFWebContentsHelper>;
+
PDFWebContentsHelper(content::WebContents* web_contents,
std::unique_ptr<PDFWebContentsHelperClient> client);
@@ -84,6 +83,7 @@ class PDFWebContentsHelper
int32_t left_height,
const gfx::PointF& right,
int32_t right_height) override;
+ void SetPluginCanSave(bool can_save) override;
content::WebContentsFrameBindingSet<mojom::PdfService> pdf_service_bindings_;
std::unique_ptr<PDFWebContentsHelperClient> const client_;
diff --git a/chromium/components/pdf/browser/pdf_web_contents_helper_client.h b/chromium/components/pdf/browser/pdf_web_contents_helper_client.h
index 9a6ae89eea6..fcf515e3c44 100644
--- a/chromium/components/pdf/browser/pdf_web_contents_helper_client.h
+++ b/chromium/components/pdf/browser/pdf_web_contents_helper_client.h
@@ -5,10 +5,6 @@
#ifndef COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_CLIENT_H_
#define COMPONENTS_PDF_BROWSER_PDF_WEB_CONTENTS_HELPER_CLIENT_H_
-#include "base/callback.h"
-#include "base/strings/string16.h"
-#include "ipc/ipc_message.h"
-
namespace content {
class WebContents;
}
@@ -25,6 +21,10 @@ class PDFWebContentsHelperClient {
virtual void OnPDFHasUnsupportedFeature(content::WebContents* contents) = 0;
virtual void OnSaveURL(content::WebContents* contents) = 0;
+
+ // Sets whether the PDF plugin can handle file saving internally.
+ virtual void SetPluginCanSave(content::WebContents* contents,
+ bool can_save) = 0;
};
} // namespace pdf
diff --git a/chromium/components/pdf/common/pdf.mojom b/chromium/components/pdf/common/pdf.mojom
index 4bb4f9e2be8..45ae635d3f2 100644
--- a/chromium/components/pdf/common/pdf.mojom
+++ b/chromium/components/pdf/common/pdf.mojom
@@ -36,4 +36,7 @@ interface PdfService {
// current selection.
SelectionChanged(gfx.mojom.PointF left, int32 left_height,
gfx.mojom.PointF right, int32 right_height);
+
+ // Notifies the embedder know the plugin can handle save commands internally.
+ SetPluginCanSave(bool can_save);
};
diff --git a/chromium/components/pdf/renderer/pdf_accessibility_tree.h b/chromium/components/pdf/renderer/pdf_accessibility_tree.h
index 5cafb5098c9..1d6ef4e276f 100644
--- a/chromium/components/pdf/renderer/pdf_accessibility_tree.h
+++ b/chromium/components/pdf/renderer/pdf_accessibility_tree.h
@@ -23,7 +23,7 @@ class RendererPpapiHost;
namespace gfx {
class Transform;
-};
+}
namespace pdf {
diff --git a/chromium/components/pdf/renderer/pepper_pdf_host.cc b/chromium/components/pdf/renderer/pepper_pdf_host.cc
index b92eb608610..d24105340e7 100644
--- a/chromium/components/pdf/renderer/pepper_pdf_host.cc
+++ b/chromium/components/pdf/renderer/pepper_pdf_host.cc
@@ -111,6 +111,8 @@ int32_t PepperPDFHost::OnResourceMessageReceived(
OnHostMsgSetAccessibilityPageInfo)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SelectionChanged,
OnHostMsgSelectionChanged)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetPluginCanSave,
+ OnHostMsgSetPluginCanSave)
PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
@@ -300,6 +302,17 @@ int32_t PepperPDFHost::OnHostMsgSelectionChanged(
return PP_OK;
}
+int32_t PepperPDFHost::OnHostMsgSetPluginCanSave(
+ ppapi::host::HostMessageContext* context,
+ bool can_save) {
+ mojom::PdfService* service = GetRemotePdfService();
+ if (!service)
+ return PP_ERROR_FAILED;
+
+ service->SetPluginCanSave(can_save);
+ return PP_OK;
+}
+
void PepperPDFHost::CreatePdfAccessibilityTreeIfNeeded() {
if (!pdf_accessibility_tree_) {
pdf_accessibility_tree_ =
diff --git a/chromium/components/pdf/renderer/pepper_pdf_host.h b/chromium/components/pdf/renderer/pepper_pdf_host.h
index 7d23e8ed318..0bfc7397b8d 100644
--- a/chromium/components/pdf/renderer/pepper_pdf_host.h
+++ b/chromium/components/pdf/renderer/pepper_pdf_host.h
@@ -123,6 +123,8 @@ class PepperPDFHost : public ppapi::host::ResourceHost,
int32_t left_height,
const PP_FloatPoint& right,
int32_t right_height);
+ int32_t OnHostMsgSetPluginCanSave(ppapi::host::HostMessageContext* context,
+ bool can_save);
void CreatePdfAccessibilityTreeIfNeeded();
diff --git a/chromium/components/pdf_strings.grdp b/chromium/components/pdf_strings.grdp
index 05d00fc0944..5810537bb82 100644
--- a/chromium/components/pdf_strings.grdp
+++ b/chromium/components/pdf_strings.grdp
@@ -61,10 +61,24 @@
other {Page #}}
</message>
<if expr="chromeos">
+ <message name="IDS_PDF_DISCARD_FORM_CHANGES" desc="Title for a dialog that informs the user that the changes they have made to a form will be lost if they continue">
+ Discard changes?
+ </message>
+ <message name="IDS_PDF_DISCARD_FORM_CHANGES_DETAIL" desc="Warning message in dialog that informs the user that the changes they have made to a form will be lost if they continue">
+ Form changes will be lost. Are you sure you want to continue?
+ </message>
+ <message name="IDS_PDF_KEEP_EDITING" desc="Button label for the button that lets the user return and keep editing the changes they made">
+ Keep editing
+ </message>
+ <message name="IDS_PDF_DISCARD" desc="Button label for the button that lets the user discard their unneeded changes">
+ Discard
+ </message>
<message name="IDS_PDF_ANNOTATION_ANNOTATE" desc="Button tooltip for entering the 'Annotation mode' which allows writing, drawing and highlighting of the PDF document">
Annotate
</message>
-
+ <message name="IDS_PDF_ANNOTATION_UNAVAILABLE" desc="Button tooltip to explain that 'Annotation mode' which allows writing, drawing and highlighting of the PDF document is not available">
+ Annotation not available
+ </message>
<message name="IDS_PDF_ANNOTATION_DOCUMENT_TOO_LARGE" desc="Button tooltip to indicate why 'Annotation mode' which allows writing, drawing and highlighting of the PDF document is not available due to the document being too large">
Document is too large to be annotated
</message>
@@ -84,6 +98,15 @@
<message name="IDS_PDF_ANNOTATION_ERASER" desc="Button tooltip for selecting a tool that erases strokes that were drawn on top of the PDF document">
Eraser
</message>
+ <message name="IDS_PDF_ANNOTATION_UNDO" desc="Button tooltip for undoing an annotation edit (drawing a stroke, erasing a stroke)">
+ Undo
+ </message>
+ <message name="IDS_PDF_ANNOTATION_REDO" desc="Button tooltip for redoing an annotation edit (drawing a stroke, erasing a stroke)">
+ Redo
+ </message>
+ <message name="IDS_PDF_ANNOTATION_EXPAND" desc="Button tooltip for expanding the color palette to show more colors">
+ Expand
+ </message>
<message name="IDS_PDF_ANNOTATION_COLOR_BLACK" desc="Button tooltip for selecting the Black color for drawing on top of the PDF document">
Black
diff --git a/chromium/components/plugins/renderer/webview_plugin.cc b/chromium/components/plugins/renderer/webview_plugin.cc
index 4bed940cf49..509d298ea64 100644
--- a/chromium/components/plugins/renderer/webview_plugin.cc
+++ b/chromium/components/plugins/renderer/webview_plugin.cc
@@ -69,7 +69,10 @@ WebViewPlugin* WebViewPlugin::Create(content::RenderView* render_view,
WebViewPlugin* plugin = new WebViewPlugin(render_view, delegate, preferences);
// Loading may synchronously access |delegate| which could be
// uninitialized just yet, so load in another task.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ plugin->web_view_helper_.main_frame()->GetTaskRunner(
+ blink::TaskType::kInternalDefault);
+ task_runner->PostTask(
FROM_HERE,
base::BindOnce(&WebViewPlugin::LoadHTML,
plugin->weak_factory_.GetWeakPtr(), html_data, url));
@@ -272,6 +275,11 @@ WebViewPlugin::WebViewHelper::WebViewHelper(WebViewPlugin* plugin,
mojo::MakeRequest(&document_interface_broker).PassMessagePipe(), nullptr);
// The created WebFrameWidget is owned by the |web_frame|.
WebFrameWidget::CreateForMainFrame(this, web_frame);
+
+ // The WebFrame created here was already attached to the Page as its
+ // main frame, and the WebFrameWidget has been initialized, so we can call
+ // WebViewImpl's DidAttachLocalMainFrame().
+ web_view_->DidAttachLocalMainFrame(this);
}
WebViewPlugin::WebViewHelper::~WebViewHelper() {
diff --git a/chromium/components/plugins/renderer/webview_plugin.h b/chromium/components/plugins/renderer/webview_plugin.h
index 9ee3812ed6b..db94a09799e 100644
--- a/chromium/components/plugins/renderer/webview_plugin.h
+++ b/chromium/components/plugins/renderer/webview_plugin.h
@@ -166,6 +166,7 @@ class WebViewPlugin : public blink::WebPlugin,
bool CanHandleGestureEvent() override;
bool CanUpdateLayout() override;
blink::WebScreenInfo GetScreenInfo() override;
+ void DidInvalidateRect(const blink::WebRect&) override;
// WebWidgetClient methods:
void SetToolTipText(const blink::WebString&,
@@ -175,7 +176,6 @@ class WebViewPlugin : public blink::WebPlugin,
blink::WebDragOperationsMask,
const SkBitmap&,
const gfx::Point&) override;
- void DidInvalidateRect(const blink::WebRect&) override;
void DidChangeCursor(const blink::WebCursorInfo& cursor) override;
void ScheduleAnimation() override;
std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory()
diff --git a/chromium/components/policy/BUILD.gn b/chromium/components/policy/BUILD.gn
index 6d776e3c22f..01ddddf09f5 100644
--- a/chromium/components/policy/BUILD.gn
+++ b/chromium/components/policy/BUILD.gn
@@ -294,9 +294,7 @@ proto_library("cloud_policy_proto_generated_compile_proto") {
component_build_force_source_set = true
defines = [ "POLICY_PROTO_COMPILATION" ]
- deps = [
- ":cloud_policy_code_generate",
- ]
+ proto_deps = [ ":cloud_policy_code_generate" ]
}
# This target builds the "full" protobuf, used for tests only.
@@ -320,10 +318,9 @@ proto_library("chrome_settings_proto_generated_compile_proto") {
component_build_force_source_set = true
defines = [ "POLICY_CHROME_SETTINGS_PROTO_COMPILATION" ]
- deps = [
- ":cloud_policy_code_generate",
- ":cloud_policy_proto_generated_compile",
- ]
+ proto_deps = [ ":cloud_policy_code_generate" ]
+
+ link_deps = [ ":cloud_policy_proto_generated_compile" ]
}
static_library("generated") {
diff --git a/chromium/components/policy/content/BUILD.gn b/chromium/components/policy/content/BUILD.gn
index 630c91fc8c3..faf39e86ecc 100644
--- a/chromium/components/policy/content/BUILD.gn
+++ b/chromium/components/policy/content/BUILD.gn
@@ -21,6 +21,7 @@ jumbo_source_set("content") {
"//components/policy/core/browser",
"//components/prefs",
"//components/safe_search_api",
+ "//components/safe_search_api:safe_search_client",
"//components/user_prefs:user_prefs",
"//content/public/browser",
"//net",
@@ -38,6 +39,7 @@ source_set("unit_tests") {
"//components/keyed_service/content",
"//components/policy/core/browser",
"//components/safe_search_api",
+ "//components/safe_search_api:safe_search_client",
"//components/safe_search_api:test_support",
"//components/sync_preferences:test_support",
"//components/user_prefs:user_prefs",
diff --git a/chromium/components/policy/core/common/BUILD.gn b/chromium/components/policy/core/common/BUILD.gn
index f90054855ba..b2da3a21441 100644
--- a/chromium/components/policy/core/common/BUILD.gn
+++ b/chromium/components/policy/core/common/BUILD.gn
@@ -90,6 +90,7 @@ jumbo_source_set("internal") {
"config_dir_policy_loader.h",
"configuration_policy_provider.cc",
"configuration_policy_provider.h",
+ "extension_policy_migrator.cc",
"extension_policy_migrator.h",
"external_data_fetcher.cc",
"external_data_fetcher.h",
@@ -156,6 +157,7 @@ jumbo_source_set("internal") {
"//components/crash/core/common:crash_key", # Remove once https://crbug.com/685996 is fixed.
"//components/data_use_measurement/core",
"//components/prefs",
+ "//components/strings",
"//components/version_info",
"//extensions/buildflags",
"//google_apis",
@@ -294,6 +296,7 @@ jumbo_static_library("test_support") {
"//components/account_id",
"//components/policy:generated",
"//components/policy/proto",
+ "//components/strings",
"//crypto",
"//net",
"//services/network/public/cpp",
diff --git a/chromium/components/policy/proto/BUILD.gn b/chromium/components/policy/proto/BUILD.gn
index 7d6cb62f12b..a7039ac9e50 100644
--- a/chromium/components/policy/proto/BUILD.gn
+++ b/chromium/components/policy/proto/BUILD.gn
@@ -23,7 +23,10 @@ proto_library("proto_internal") {
]
if (is_chromeos) {
- sources += [ "chrome_device_policy.proto" ]
+ sources += [
+ "chrome_device_policy.proto",
+ "install_attributes.proto",
+ ]
}
if (!is_android && !is_ios) {
diff --git a/chromium/components/policy_strings.grdp b/chromium/components/policy_strings.grdp
index 492691fdf0d..5b77f55261c 100644
--- a/chromium/components/policy_strings.grdp
+++ b/chromium/components/policy_strings.grdp
@@ -183,7 +183,7 @@
This computer is not detected as enterprise managed so policy can only automatically install extensions hosted on the Chrome Webstore. The Chrome Webstore update URL is "<ph name="CWS_UPDATE_URL">$1<ex>https://clients2.google.com/service/update2/crx</ex></ph>".
</message>
<message name="IDS_POLICY_HOMEPAGE_LOCATION_ERROR" desc="The text displayed in the status column when the homepage URL given by the HomepageLocation policy is invalid.">
- Invalid URL. Must be a URL with a standard scheme.
+ Invalid URL. Must be a URL with a standard scheme, e.g http://example.com or https://example.com.
</message>
<message name="IDS_POLICY_PROXY_MODE_DISABLED_ERROR" desc="The text displayed in the status column when use of a proxy is disabled but a proxy configuration is given.">
Use of a proxy is disabled but an explicit proxy configuration is specified.
@@ -246,72 +246,6 @@ Additional details:
Unknown policy.
</message>
- <!-- chrome://policy-tool -->
- <message name="IDS_POLICY_TOOL_CANCEL_RENAME" desc="Button to cancel the dialog that appears in rename session.">
- Cancel
- </message>
- <message name="IDS_POLICY_TOOL_CONFIRM_RENAME" desc="Button that confirm a rename session.">
- Confirm
- </message>
- <message name="IDS_POLICY_TOOL_TITLE" desc="Admin page title and the title of the section that lists policies.">
- Policy management
- </message>
- <message name="IDS_EXPORT_POLICIES_LINUX" desc="Button that exports the current session policy
- in linux format.">
- Export Linux
- </message>
- <message name="IDS_EXPORT_POLICIES_MAC" desc="Button that exports the current session policy
- in mac format (.plist).">
- Export MacOS
- </message>
- <message name="IDS_POLICY_TOOL_EDIT" desc="Label for the button to change policy value in current session.">
- Edit
- </message>
- <message name="IDS_POLICY_TOOL_SAVE" desc="Label for the button to save policy value after editing it.">
- Save
- </message>
- <message name="IDS_POLICY_TOOL_LOAD_SESSION" desc="Label for the button that loads specified session.">
- Load session
- </message>
- <message name="IDS_POLICY_TOOL_REMOVE_SESSION" desc="Label for the button that removes specified session.">
- Remove
- </message>
- <message name="IDS_POLICY_TOOL_RENAME_SESSION" desc="Label for the button that renames specified session.">
- Rename
- </message>
- <message name="IDS_POLICY_TOOL_SESSION_NAME_PLACEHOLDER" desc="Placeholder for the input field that lets the user change policy management sessions.">
- Session name
- </message>
- <message name="IDS_POLICY_TOOL_INVALID_TYPE" desc="The text displayed in the status column when the value type doesn't match the actual policy type.">
- The policy type is invalid.
- </message>
- <message name="IDS_POLICY_TOOL_SAVING_DISABLED" desc="A message that is shown to the user when there is some problem that prevents saving the session to disk.">
- There was a problem accessing the session files. Saving to disk is currently disabled. Please reload the page to try again.
- </message>
- <message name="IDS_POLICY_TOOL_INVALID_SESSION_NAME" desc="A message that is shown to the user when the entered session name is invalid.">
- Please enter a valid session name.
- </message>
- <message name="IDS_POLICY_TOOL_ENABLE_EDITING" desc="Label for the button to reset the current session to enable editing policy values.">
- Reset
- </message>
- <message name="IDS_POLICY_TOOL_CORRUPTED_FILE" desc="A message that is shown to the user when the session file is corrupted.">
- The file seems to be corrupted. Click the 'Reset' button to reset the session.
- </message>
- <message name="IDS_POLICY_TOOL_DELETE_FAILED" desc="A message that is shown to the user when deleting the session fails because the session name that is sent from Javascript is invalid.">
- The session with this name is not valid for deletion.
- </message>
- <message name="IDS_POLICY_TOOL_SESSION_NOT_EXIST" desc="A message that is shown to the user when
- the selected session name does not exist.">
- The selected session does not exist.
- </message>
- <message name="IDS_POLICY_TOOL_SESSION_EXIST" desc="A message that is show to the user when
- there is another session with the same name in a renaming session.">
- This session name already exists.
- </message>
- <message name="IDS_POLICY_TOOL_RENAME_FAILED" desc="A message that is shown to the user when
- renaming the session fails because the function that rename the file failed.">
- Failed to rename the session.
- </message>
<!-- chrome://policy -->
<message name="IDS_POLICY_TITLE" desc="Page title and the title of the section that lists policies.">
Policies
@@ -379,12 +313,33 @@ Additional details:
<message name="IDS_POLICY_NOT_SPECIFIED" desc="Indicates if that device attribute has not specified yet.">
Not Specified
</message>
+ <message name="IDS_POLICY_LABEL_PUSH_POLICIES" desc="Label to indicates the policies can be pushed or not to chrome.">
+ Policies push:
+ </message>
+ <message name="IDS_POLICY_PUSH_POLICIES_ON" desc="Indicates the policies can be pushed to chrome.">
+ On
+ </message>
+ <message name="IDS_POLICY_PUSH_POLICIES_OFF" desc="Indicates the policies cannot be pushed to chrome.">
+ Off
+ </message>
<message name="IDS_POLICY_NEVER_FETCHED" desc="Indicates that a policy fetch was never performed before.">
Never
</message>
<message name="IDS_POLICY_LABEL_REFRESH_INTERVAL" desc="Label for the refresh interval in the policy status boxes.">
Fetch interval:
</message>
+ <message name="IDS_POLICY_LABEL_MESSAGES" desc="Label for the messages row in the policy table.">
+ Messages
+ </message>
+ <message name="IDS_POLICY_LABEL_CONFLICT" desc="Label for the conflict row in the policy table.">
+ Conflict
+ </message>
+ <message name="IDS_POLICY_LABEL_WARNING_AND_CONFLICT" desc="Label for the conflict row in the policy table when there are warnings and conflicts.">
+ Warnings, Conflict
+ </message>
+ <message name="IDS_POLICY_LABEL_VALUE" desc="Label for the value row in the policy table.">
+ Value
+ </message>
<message name="IDS_POLICY_LABEL_STATUS" desc="Label for the actual status in the policy status boxes.">
Status:
</message>
@@ -412,11 +367,14 @@ Additional details:
<message name="IDS_POLICY_HEADER_SOURCE" desc="Table header for the column in policy table that contains the policy source.">
Source
</message>
- <message name="IDS_POLICY_SHOW_EXPANDED_VALUE" desc="Text for the link that shows the policy value. Used when the policy value is too long to be always visible.">
- Show value
+ <message name="IDS_POLICY_HEADER_WARNING" desc="Table header for the column in the policy table that contains the policy warnings.">
+ Warning
+ </message>
+ <message name="IDS_POLICY_SHOW_MORE" desc="Text for the link that expands and shows the are full value, conflicts and warnings rows of a policy.">
+ Show more
</message>
- <message name="IDS_POLICY_HIDE_EXPANDED_VALUE" desc="Text for the link that hides the policy value. Used when the policy value is too long to be always visible.">
- Hide value
+ <message name="IDS_POLICY_SHOW_LESS" desc="Text for the link that collapses and hides the are full value, conflicts and warnings rows of a policy.">
+ Show less
</message>
<message name="IDS_POLICY_LEARN_MORE" desc="Help text for learn-more link for known chrome policies.">
Learn more about <ph name="POLICY_NAME">$1<ex>AllowDinosaurEasterEgg</ex></ph> policy
@@ -482,4 +440,13 @@ Additional details:
<message name="IDS_POLICY_HIDE_EXPANDED_STATUS" desc="Text for the link that hides the policy status. Used when the policy status is too long to be always visible.">
Hide status
</message>
+ <message name="IDS_POLICY_CONFLICT_SAME_VALUE" desc="Text explaining that a policy had conflicting sources, but with the same values.">
+ Warning: More than one source is present for the policy, but the values are the same.
+ </message>
+ <message name="IDS_POLICY_CONFLICT_DIFF_VALUE" desc="Text explaining that a policy had conflicting sources and values.">
+ Warning: More than one source with conflicting values is present for this policy!
+ </message>
+ <message name="IDS_POLICY_BLOCKED" desc="Text explaining that a policy is blocked, therefore ignored.">
+ This policy is blocked, its value will be ignored.
+ </message>
</grit-part>
diff --git a/chromium/components/pref_registry/pref_registry_syncable.cc b/chromium/components/pref_registry/pref_registry_syncable.cc
index f458cf7f074..a7b4fe9d5b4 100644
--- a/chromium/components/pref_registry/pref_registry_syncable.cc
+++ b/chromium/components/pref_registry/pref_registry_syncable.cc
@@ -23,7 +23,6 @@ void PrefRegistrySyncable::SetSyncableRegistrationCallback(
}
void PrefRegistrySyncable::OnPrefRegistered(const std::string& path,
- base::Value* default_value,
uint32_t flags) {
// Tests that |flags| does not contain both SYNCABLE_PREF and
// SYNCABLE_PRIORITY_PREF flags at the same time.
diff --git a/chromium/components/pref_registry/pref_registry_syncable.h b/chromium/components/pref_registry/pref_registry_syncable.h
index d8e7c457b33..9533e155a85 100644
--- a/chromium/components/pref_registry/pref_registry_syncable.h
+++ b/chromium/components/pref_registry/pref_registry_syncable.h
@@ -14,10 +14,6 @@
#include "base/macros.h"
#include "components/prefs/pref_registry_simple.h"
-namespace base {
-class Value;
-}
-
// TODO(tfarina): Change this namespace to pref_registry.
namespace user_prefs {
@@ -89,7 +85,6 @@ class PrefRegistrySyncable : public PrefRegistrySimple {
// PrefRegistrySimple overrides.
void OnPrefRegistered(const std::string& path,
- base::Value* default_value,
uint32_t flags) override;
SyncableRegistrationCallback callback_;
diff --git a/chromium/components/prefs/default_pref_store.cc b/chromium/components/prefs/default_pref_store.cc
index 25e36b97c76..d8d13ec0050 100644
--- a/chromium/components/prefs/default_pref_store.cc
+++ b/chromium/components/prefs/default_pref_store.cc
@@ -33,14 +33,13 @@ bool DefaultPrefStore::HasObservers() const {
return observers_.might_have_observers();
}
-void DefaultPrefStore::SetDefaultValue(const std::string& key,
- std::unique_ptr<Value> value) {
+void DefaultPrefStore::SetDefaultValue(const std::string& key, Value value) {
DCHECK(!GetValue(key, nullptr));
prefs_.SetValue(key, std::move(value));
}
void DefaultPrefStore::ReplaceDefaultValue(const std::string& key,
- std::unique_ptr<Value> value) {
+ Value value) {
DCHECK(GetValue(key, nullptr));
bool notify = prefs_.SetValue(key, std::move(value));
if (notify) {
diff --git a/chromium/components/prefs/default_pref_store.h b/chromium/components/prefs/default_pref_store.h
index 3607a35dd32..17ba3ec7a5b 100644
--- a/chromium/components/prefs/default_pref_store.h
+++ b/chromium/components/prefs/default_pref_store.h
@@ -32,13 +32,11 @@ class COMPONENTS_PREFS_EXPORT DefaultPrefStore : public PrefStore {
// Sets a |value| for |key|. Should only be called if a value has not been
// set yet; otherwise call ReplaceDefaultValue().
- void SetDefaultValue(const std::string& key,
- std::unique_ptr<base::Value> value);
+ void SetDefaultValue(const std::string& key, base::Value value);
// Replaces the the value for |key| with a new value. Should only be called
// if a value has alreday been set; otherwise call SetDefaultValue().
- void ReplaceDefaultValue(const std::string& key,
- std::unique_ptr<base::Value> value);
+ void ReplaceDefaultValue(const std::string& key, base::Value value);
const_iterator begin() const;
const_iterator end() const;
diff --git a/chromium/components/prefs/default_pref_store_unittest.cc b/chromium/components/prefs/default_pref_store_unittest.cc
index 20bbba3a87f..bc40c4ca5c8 100644
--- a/chromium/components/prefs/default_pref_store_unittest.cc
+++ b/chromium/components/prefs/default_pref_store_unittest.cc
@@ -52,18 +52,15 @@ TEST(DefaultPrefStoreTest, NotifyPrefValueChanged) {
std::string kPrefKey("pref_key");
// Setting a default value shouldn't send a change notification.
- pref_store->SetDefaultValue(kPrefKey,
- std::unique_ptr<Value>(new Value("foo")));
+ pref_store->SetDefaultValue(kPrefKey, Value("foo"));
EXPECT_EQ(0, observer.change_count());
// Replacing the default value should send a change notification...
- pref_store->ReplaceDefaultValue(kPrefKey,
- std::unique_ptr<Value>(new Value("bar")));
+ pref_store->ReplaceDefaultValue(kPrefKey, Value("bar"));
EXPECT_EQ(1, observer.change_count());
// But only if the value actually changed.
- pref_store->ReplaceDefaultValue(kPrefKey,
- std::unique_ptr<Value>(new Value("bar")));
+ pref_store->ReplaceDefaultValue(kPrefKey, Value("bar"));
EXPECT_EQ(1, observer.change_count());
}
diff --git a/chromium/components/prefs/in_memory_pref_store.cc b/chromium/components/prefs/in_memory_pref_store.cc
index a0a9c35d47b..2201d247325 100644
--- a/chromium/components/prefs/in_memory_pref_store.cc
+++ b/chromium/components/prefs/in_memory_pref_store.cc
@@ -47,14 +47,15 @@ void InMemoryPrefStore::SetValue(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
DCHECK(value);
- if (prefs_.SetValue(key, std::move(value)))
+ if (prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value))))
ReportValueChanged(key, flags);
}
void InMemoryPrefStore::SetValueSilently(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
- prefs_.SetValue(key, std::move(value));
+ DCHECK(value);
+ prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value)));
}
void InMemoryPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
diff --git a/chromium/components/prefs/json_pref_store_unittest.cc b/chromium/components/prefs/json_pref_store_unittest.cc
index d4e7870c1f6..a7bd474f7bd 100644
--- a/chromium/components/prefs/json_pref_store_unittest.cc
+++ b/chromium/components/prefs/json_pref_store_unittest.cc
@@ -285,7 +285,7 @@ void RunBasicJsonPrefStoreTest(
pref_store->SetValue(
kLongIntPref,
- std::make_unique<Value>(base::Int64ToString(214748364842LL)),
+ std::make_unique<Value>(base::NumberToString(214748364842LL)),
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
EXPECT_TRUE(actual->GetAsString(&string_value));
@@ -538,15 +538,15 @@ TEST_P(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
&scoped_task_environment_);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithoutCallback,
JsonPrefStoreTest,
::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithCallback,
JsonPrefStoreTest,
::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithSynchronousCallback,
JsonPrefStoreTest,
::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
@@ -694,15 +694,15 @@ TEST_P(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) {
ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithoutCallback,
JsonPrefStoreLossyWriteTest,
::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithReply,
JsonPrefStoreLossyWriteTest,
::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
WithNotify,
JsonPrefStoreLossyWriteTest,
::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
diff --git a/chromium/components/prefs/pref_member_unittest.cc b/chromium/components/prefs/pref_member_unittest.cc
index abdfeab7940..a7d4a5ea962 100644
--- a/chromium/components/prefs/pref_member_unittest.cc
+++ b/chromium/components/prefs/pref_member_unittest.cc
@@ -29,8 +29,7 @@ void RegisterTestPrefs(PrefRegistrySimple* registry) {
registry->RegisterIntegerPref(kIntPref, 0);
registry->RegisterDoublePref(kDoublePref, 0.0);
registry->RegisterStringPref(kStringPref, "default");
- registry->RegisterListPref(kStringListPref,
- std::make_unique<base::ListValue>());
+ registry->RegisterListPref(kStringListPref);
}
class GetPrefValueHelper
diff --git a/chromium/components/prefs/pref_registry.cc b/chromium/components/prefs/pref_registry.cc
index 89709c19a63..9f36c2faeff 100644
--- a/chromium/components/prefs/pref_registry.cc
+++ b/chromium/components/prefs/pref_registry.cc
@@ -44,24 +44,21 @@ void PrefRegistry::SetDefaultPrefValue(const std::string& pref_name,
DCHECK(value.type() == current_value->type())
<< "Wrong type for new default: " << pref_name;
- defaults_->ReplaceDefaultValue(
- pref_name, base::Value::ToUniquePtrValue(std::move(value)));
+ defaults_->ReplaceDefaultValue(pref_name, std::move(value));
}
-void PrefRegistry::SetDefaultForeignPrefValue(
- const std::string& path,
- std::unique_ptr<base::Value> default_value,
- uint32_t flags) {
+void PrefRegistry::SetDefaultForeignPrefValue(const std::string& path,
+ base::Value default_value,
+ uint32_t flags) {
auto erased = foreign_pref_keys_.erase(path);
DCHECK_EQ(1u, erased);
RegisterPreference(path, std::move(default_value), flags);
}
-void PrefRegistry::RegisterPreference(
- const std::string& path,
- std::unique_ptr<base::Value> default_value,
- uint32_t flags) {
- base::Value::Type orig_type = default_value->type();
+void PrefRegistry::RegisterPreference(const std::string& path,
+ base::Value default_value,
+ uint32_t flags) {
+ base::Value::Type orig_type = default_value.type();
DCHECK(orig_type != base::Value::Type::NONE &&
orig_type != base::Value::Type::BINARY) <<
"invalid preference type: " << orig_type;
@@ -70,11 +67,11 @@ void PrefRegistry::RegisterPreference(
DCHECK(!base::ContainsKey(registration_flags_, path))
<< "Trying to register a previously registered pref: " << path;
- base::Value* default_value_raw = default_value.get();
defaults_->SetDefaultValue(path, std::move(default_value));
if (flags != NO_REGISTRATION_FLAGS)
registration_flags_[path] = flags;
- OnPrefRegistered(path, default_value_raw, flags);
+
+ OnPrefRegistered(path, flags);
}
void PrefRegistry::RegisterForeignPref(const std::string& path) {
@@ -83,5 +80,4 @@ void PrefRegistry::RegisterForeignPref(const std::string& path) {
}
void PrefRegistry::OnPrefRegistered(const std::string& path,
- base::Value* default_value,
uint32_t flags) {}
diff --git a/chromium/components/prefs/pref_registry.h b/chromium/components/prefs/pref_registry.h
index a4d08280e01..065bd657689 100644
--- a/chromium/components/prefs/pref_registry.h
+++ b/chromium/components/prefs/pref_registry.h
@@ -7,7 +7,6 @@
#include <stdint.h>
-#include <memory>
#include <set>
#include <unordered_map>
@@ -81,7 +80,7 @@ class COMPONENTS_PREFS_EXPORT PrefRegistry
// Sets the default value and flags of a previously-registered foreign pref
// value.
void SetDefaultForeignPrefValue(const std::string& path,
- std::unique_ptr<base::Value> default_value,
+ base::Value default_value,
uint32_t flags);
const std::set<std::string>& foreign_pref_keys() const {
@@ -95,12 +94,11 @@ class COMPONENTS_PREFS_EXPORT PrefRegistry
// Used by subclasses to register a default value and registration flags for
// a preference. |flags| is a bitmask of |PrefRegistrationFlags|.
void RegisterPreference(const std::string& path,
- std::unique_ptr<base::Value> default_value,
+ base::Value default_value,
uint32_t flags);
// Allows subclasses to hook into pref registration.
virtual void OnPrefRegistered(const std::string& path,
- base::Value* default_value,
uint32_t flags);
scoped_refptr<DefaultPrefStore> defaults_;
diff --git a/chromium/components/prefs/pref_registry_simple.cc b/chromium/components/prefs/pref_registry_simple.cc
index e0d7a95c909..bab05dd5927 100644
--- a/chromium/components/prefs/pref_registry_simple.cc
+++ b/chromium/components/prefs/pref_registry_simple.cc
@@ -16,76 +16,68 @@ PrefRegistrySimple::~PrefRegistrySimple() = default;
void PrefRegistrySimple::RegisterBooleanPref(const std::string& path,
bool default_value,
uint32_t flags) {
- RegisterPreference(path, std::make_unique<base::Value>(default_value), flags);
+ RegisterPreference(path, base::Value(default_value), flags);
}
void PrefRegistrySimple::RegisterIntegerPref(const std::string& path,
int default_value,
uint32_t flags) {
- RegisterPreference(path, std::make_unique<base::Value>(default_value), flags);
+ RegisterPreference(path, base::Value(default_value), flags);
}
void PrefRegistrySimple::RegisterDoublePref(const std::string& path,
double default_value,
uint32_t flags) {
- RegisterPreference(path, std::make_unique<base::Value>(default_value), flags);
+ RegisterPreference(path, base::Value(default_value), flags);
}
void PrefRegistrySimple::RegisterStringPref(const std::string& path,
const std::string& default_value,
uint32_t flags) {
- RegisterPreference(path, std::make_unique<base::Value>(default_value), flags);
+ RegisterPreference(path, base::Value(default_value), flags);
}
void PrefRegistrySimple::RegisterFilePathPref(
const std::string& path,
const base::FilePath& default_value,
uint32_t flags) {
- RegisterPreference(path, std::make_unique<base::Value>(default_value.value()),
- flags);
+ RegisterPreference(path, base::Value(default_value.value()), flags);
}
void PrefRegistrySimple::RegisterListPref(const std::string& path,
uint32_t flags) {
- RegisterPreference(
- path, std::make_unique<base::Value>(base::Value::Type::LIST), flags);
+ RegisterPreference(path, base::Value(base::Value::Type::LIST), flags);
}
-void PrefRegistrySimple::RegisterListPref(
- const std::string& path,
- std::unique_ptr<base::Value> default_value,
- uint32_t flags) {
+void PrefRegistrySimple::RegisterListPref(const std::string& path,
+ base::Value default_value,
+ uint32_t flags) {
RegisterPreference(path, std::move(default_value), flags);
}
void PrefRegistrySimple::RegisterDictionaryPref(const std::string& path,
uint32_t flags) {
- RegisterPreference(
- path, std::make_unique<base::Value>(base::Value::Type::DICTIONARY),
- flags);
+ RegisterPreference(path, base::Value(base::Value::Type::DICTIONARY), flags);
}
-void PrefRegistrySimple::RegisterDictionaryPref(
- const std::string& path,
- std::unique_ptr<base::Value> default_value,
- uint32_t flags) {
+void PrefRegistrySimple::RegisterDictionaryPref(const std::string& path,
+ base::Value default_value,
+ uint32_t flags) {
RegisterPreference(path, std::move(default_value), flags);
}
void PrefRegistrySimple::RegisterInt64Pref(const std::string& path,
int64_t default_value,
uint32_t flags) {
- RegisterPreference(
- path, std::make_unique<base::Value>(base::Int64ToString(default_value)),
- flags);
+ RegisterPreference(path, base::Value(base::NumberToString(default_value)),
+ flags);
}
void PrefRegistrySimple::RegisterUint64Pref(const std::string& path,
uint64_t default_value,
uint32_t flags) {
- RegisterPreference(
- path, std::make_unique<base::Value>(base::NumberToString(default_value)),
- flags);
+ RegisterPreference(path, base::Value(base::NumberToString(default_value)),
+ flags);
}
void PrefRegistrySimple::RegisterTimePref(const std::string& path,
diff --git a/chromium/components/prefs/pref_registry_simple.h b/chromium/components/prefs/pref_registry_simple.h
index 1f0021dd549..b167e942905 100644
--- a/chromium/components/prefs/pref_registry_simple.h
+++ b/chromium/components/prefs/pref_registry_simple.h
@@ -51,14 +51,14 @@ class COMPONENTS_PREFS_EXPORT PrefRegistrySimple : public PrefRegistry {
uint32_t flags = NO_REGISTRATION_FLAGS);
void RegisterListPref(const std::string& path,
- std::unique_ptr<base::Value> default_value,
+ base::Value default_value,
uint32_t flags = NO_REGISTRATION_FLAGS);
void RegisterDictionaryPref(const std::string& path,
uint32_t flags = NO_REGISTRATION_FLAGS);
void RegisterDictionaryPref(const std::string& path,
- std::unique_ptr<base::Value> default_value,
+ base::Value default_value,
uint32_t flags = NO_REGISTRATION_FLAGS);
void RegisterInt64Pref(const std::string& path,
diff --git a/chromium/components/prefs/pref_service.cc b/chromium/components/prefs/pref_service.cc
index deb571065e7..f10814d918e 100644
--- a/chromium/components/prefs/pref_service.cc
+++ b/chromium/components/prefs/pref_service.cc
@@ -491,7 +491,7 @@ void PrefService::SetFilePath(const std::string& path,
void PrefService::SetInt64(const std::string& path, int64_t value) {
SetUserPrefValue(path,
- std::make_unique<base::Value>(base::Int64ToString(value)));
+ std::make_unique<base::Value>(base::NumberToString(value)));
}
int64_t PrefService::GetInt64(const std::string& path) const {
diff --git a/chromium/components/prefs/pref_service_factory.cc b/chromium/components/prefs/pref_service_factory.cc
index ef39b03f5a2..cc8e52d887e 100644
--- a/chromium/components/prefs/pref_service_factory.cc
+++ b/chromium/components/prefs/pref_service_factory.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/sequenced_task_runner.h"
#include "components/prefs/default_pref_store.h"
#include "components/prefs/json_pref_store.h"
diff --git a/chromium/components/prefs/pref_service_unittest.cc b/chromium/components/prefs/pref_service_unittest.cc
index dfc51f6dfa4..3bdcf351fc4 100644
--- a/chromium/components/prefs/pref_service_unittest.cc
+++ b/chromium/components/prefs/pref_service_unittest.cc
@@ -7,6 +7,7 @@
#include <string>
+#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -380,7 +381,6 @@ TEST(PrefServiceTest, WriteablePrefStoreFlags) {
for (size_t i = 0; i < base::size(kRegistrationToWriteFlags); ++i) {
RegistrationToWriteFlags entry = kRegistrationToWriteFlags[i];
registry->RegisterDictionaryPref(entry.pref_name,
- std::make_unique<base::DictionaryValue>(),
entry.registration_flags);
SCOPED_TRACE("Currently testing pref with name: " +
diff --git a/chromium/components/prefs/pref_value_map.cc b/chromium/components/prefs/pref_value_map.cc
index 6ff02b6d216..b932eef526a 100644
--- a/chromium/components/prefs/pref_value_map.cc
+++ b/chromium/components/prefs/pref_value_map.cc
@@ -38,12 +38,6 @@ bool PrefValueMap::GetValue(const std::string& key, base::Value** value) {
return true;
}
-bool PrefValueMap::SetValue(const std::string& key,
- std::unique_ptr<base::Value> value) {
- DCHECK(value);
- return SetValue(key, base::Value::FromUniquePtrValue(std::move(value)));
-}
-
bool PrefValueMap::SetValue(const std::string& key, base::Value value) {
base::Value& existing_value = prefs_[key];
if (value == existing_value)
diff --git a/chromium/components/prefs/pref_value_map.h b/chromium/components/prefs/pref_value_map.h
index 8188cb1aa85..6a9b4b656c5 100644
--- a/chromium/components/prefs/pref_value_map.h
+++ b/chromium/components/prefs/pref_value_map.h
@@ -34,11 +34,6 @@ class COMPONENTS_PREFS_EXPORT PrefValueMap {
bool GetValue(const std::string& key, const base::Value** value) const;
bool GetValue(const std::string& key, base::Value** value);
- // Sets a new |value| for |key|. |value| must be non-null. Returns true if the
- // value changed.
- // DEPRECATED. Use |SetValue(const std::string&, base::Value)| instead.
- bool SetValue(const std::string& key, std::unique_ptr<base::Value> value);
-
// Sets a new |value| for |key|. Returns true if the value changed.
bool SetValue(const std::string& key, base::Value value);
diff --git a/chromium/components/prefs/pref_value_map_unittest.cc b/chromium/components/prefs/pref_value_map_unittest.cc
index f3b05f7af3f..7d2f05c04e3 100644
--- a/chromium/components/prefs/pref_value_map_unittest.cc
+++ b/chromium/components/prefs/pref_value_map_unittest.cc
@@ -16,9 +16,9 @@ TEST(PrefValueMapTest, SetValue) {
EXPECT_FALSE(map.GetValue("key", &result));
EXPECT_FALSE(result);
- EXPECT_TRUE(map.SetValue("key", std::make_unique<Value>("test")));
- EXPECT_FALSE(map.SetValue("key", std::make_unique<Value>("test")));
- EXPECT_TRUE(map.SetValue("key", std::make_unique<Value>("hi mom!")));
+ EXPECT_TRUE(map.SetValue("key", Value("test")));
+ EXPECT_FALSE(map.SetValue("key", Value("test")));
+ EXPECT_TRUE(map.SetValue("key", Value("hi mom!")));
EXPECT_TRUE(map.GetValue("key", &result));
EXPECT_TRUE(Value("hi mom!").Equals(result));
@@ -26,7 +26,7 @@ TEST(PrefValueMapTest, SetValue) {
TEST(PrefValueMapTest, GetAndSetIntegerValue) {
PrefValueMap map;
- ASSERT_TRUE(map.SetValue("key", std::make_unique<Value>(5)));
+ ASSERT_TRUE(map.SetValue("key", Value(5)));
int int_value = 0;
EXPECT_TRUE(map.GetInteger("key", &int_value));
@@ -39,7 +39,7 @@ TEST(PrefValueMapTest, GetAndSetIntegerValue) {
TEST(PrefValueMapTest, SetDoubleValue) {
PrefValueMap map;
- ASSERT_TRUE(map.SetValue("key", std::make_unique<Value>(5.5)));
+ ASSERT_TRUE(map.SetValue("key", Value(5.5)));
const Value* result = nullptr;
ASSERT_TRUE(map.GetValue("key", &result));
@@ -52,7 +52,7 @@ TEST(PrefValueMapTest, RemoveValue) {
PrefValueMap map;
EXPECT_FALSE(map.RemoveValue("key"));
- EXPECT_TRUE(map.SetValue("key", std::make_unique<Value>("test")));
+ EXPECT_TRUE(map.SetValue("key", Value("test")));
EXPECT_TRUE(map.GetValue("key", nullptr));
EXPECT_TRUE(map.RemoveValue("key"));
@@ -63,7 +63,7 @@ TEST(PrefValueMapTest, RemoveValue) {
TEST(PrefValueMapTest, Clear) {
PrefValueMap map;
- EXPECT_TRUE(map.SetValue("key", std::make_unique<Value>("test")));
+ EXPECT_TRUE(map.SetValue("key", Value("test")));
EXPECT_TRUE(map.GetValue("key", nullptr));
map.Clear();
@@ -73,9 +73,9 @@ TEST(PrefValueMapTest, Clear) {
TEST(PrefValueMapTest, GetDifferingKeys) {
PrefValueMap reference;
- EXPECT_TRUE(reference.SetValue("b", std::make_unique<Value>("test")));
- EXPECT_TRUE(reference.SetValue("c", std::make_unique<Value>("test")));
- EXPECT_TRUE(reference.SetValue("e", std::make_unique<Value>("test")));
+ EXPECT_TRUE(reference.SetValue("b", Value("test")));
+ EXPECT_TRUE(reference.SetValue("c", Value("test")));
+ EXPECT_TRUE(reference.SetValue("e", Value("test")));
PrefValueMap check;
std::vector<std::string> differing_paths;
@@ -87,9 +87,9 @@ TEST(PrefValueMapTest, GetDifferingKeys) {
expected_differing_paths.push_back("e");
EXPECT_EQ(expected_differing_paths, differing_paths);
- EXPECT_TRUE(check.SetValue("a", std::make_unique<Value>("test")));
- EXPECT_TRUE(check.SetValue("c", std::make_unique<Value>("test")));
- EXPECT_TRUE(check.SetValue("d", std::make_unique<Value>("test")));
+ EXPECT_TRUE(check.SetValue("a", Value("test")));
+ EXPECT_TRUE(check.SetValue("c", Value("test")));
+ EXPECT_TRUE(check.SetValue("d", Value("test")));
reference.GetDifferingKeys(&check, &differing_paths);
expected_differing_paths.clear();
@@ -102,14 +102,14 @@ TEST(PrefValueMapTest, GetDifferingKeys) {
TEST(PrefValueMapTest, SwapTwoMaps) {
PrefValueMap first_map;
- EXPECT_TRUE(first_map.SetValue("a", std::make_unique<Value>("test")));
- EXPECT_TRUE(first_map.SetValue("b", std::make_unique<Value>("test")));
- EXPECT_TRUE(first_map.SetValue("c", std::make_unique<Value>("test")));
+ EXPECT_TRUE(first_map.SetValue("a", Value("test")));
+ EXPECT_TRUE(first_map.SetValue("b", Value("test")));
+ EXPECT_TRUE(first_map.SetValue("c", Value("test")));
PrefValueMap second_map;
- EXPECT_TRUE(second_map.SetValue("d", std::make_unique<Value>("test")));
- EXPECT_TRUE(second_map.SetValue("e", std::make_unique<Value>("test")));
- EXPECT_TRUE(second_map.SetValue("f", std::make_unique<Value>("test")));
+ EXPECT_TRUE(second_map.SetValue("d", Value("test")));
+ EXPECT_TRUE(second_map.SetValue("e", Value("test")));
+ EXPECT_TRUE(second_map.SetValue("f", Value("test")));
first_map.Swap(&second_map);
diff --git a/chromium/components/prefs/scoped_user_pref_update_unittest.cc b/chromium/components/prefs/scoped_user_pref_update_unittest.cc
index 0fcfbd69f33..fa1dc71ae45 100644
--- a/chromium/components/prefs/scoped_user_pref_update_unittest.cc
+++ b/chromium/components/prefs/scoped_user_pref_update_unittest.cc
@@ -81,12 +81,13 @@ TEST_F(ScopedUserPrefUpdateTest, NeverTouchAnything) {
}
TEST_F(ScopedUserPrefUpdateTest, UpdatingListPrefWithDefaults) {
- auto defaults = std::make_unique<base::ListValue>();
- defaults->GetList().emplace_back("firstvalue");
- defaults->GetList().emplace_back("secondvalue");
+ base::Value::ListStorage defaults;
+ defaults.emplace_back("firstvalue");
+ defaults.emplace_back("secondvalue");
std::string pref_name = "mypref";
- prefs_.registry()->RegisterListPref(pref_name, std::move(defaults));
+ prefs_.registry()->RegisterListPref(pref_name,
+ base::Value(std::move(defaults)));
EXPECT_EQ(2u, prefs_.GetList(pref_name)->GetList().size());
ListPrefUpdate update(&prefs_, pref_name);
@@ -95,9 +96,9 @@ TEST_F(ScopedUserPrefUpdateTest, UpdatingListPrefWithDefaults) {
}
TEST_F(ScopedUserPrefUpdateTest, UpdatingDictionaryPrefWithDefaults) {
- auto defaults = std::make_unique<base::DictionaryValue>();
- defaults->SetKey("firstkey", base::Value("value"));
- defaults->SetKey("secondkey", base::Value("value"));
+ base::Value defaults(base::Value::Type::DICTIONARY);
+ defaults.SetKey("firstkey", base::Value("value"));
+ defaults.SetKey("secondkey", base::Value("value"));
std::string pref_name = "mypref";
prefs_.registry()->RegisterDictionaryPref(pref_name, std::move(defaults));
diff --git a/chromium/components/prefs/testing_pref_store.cc b/chromium/components/prefs/testing_pref_store.cc
index 16257da8d8b..438040784eb 100644
--- a/chromium/components/prefs/testing_pref_store.cc
+++ b/chromium/components/prefs/testing_pref_store.cc
@@ -54,7 +54,8 @@ bool TestingPrefStore::IsInitializationComplete() const {
void TestingPrefStore::SetValue(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
- if (prefs_.SetValue(key, std::move(value))) {
+ DCHECK(value);
+ if (prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value)))) {
committed_ = false;
NotifyPrefValueChanged(key);
}
@@ -63,9 +64,9 @@ 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)))
+ DCHECK(value);
+ CheckPrefIsSerializable(key, *value);
+ if (prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value))))
committed_ = false;
}
diff --git a/chromium/components/prefs/value_map_pref_store.cc b/chromium/components/prefs/value_map_pref_store.cc
index c31d7c771cc..79c201758f9 100644
--- a/chromium/components/prefs/value_map_pref_store.cc
+++ b/chromium/components/prefs/value_map_pref_store.cc
@@ -36,7 +36,8 @@ bool ValueMapPrefStore::HasObservers() const {
void ValueMapPrefStore::SetValue(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
- if (prefs_.SetValue(key, std::move(value))) {
+ DCHECK(value);
+ if (prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value)))) {
for (Observer& observer : observers_)
observer.OnPrefValueChanged(key);
}
@@ -63,7 +64,8 @@ void ValueMapPrefStore::ReportValueChanged(const std::string& key,
void ValueMapPrefStore::SetValueSilently(const std::string& key,
std::unique_ptr<base::Value> value,
uint32_t flags) {
- prefs_.SetValue(key, std::move(value));
+ DCHECK(value);
+ prefs_.SetValue(key, base::Value::FromUniquePtrValue(std::move(value)));
}
ValueMapPrefStore::~ValueMapPrefStore() {}
diff --git a/chromium/components/previews/DEPS b/chromium/components/previews/DEPS
new file mode 100644
index 00000000000..ba62364303c
--- /dev/null
+++ b/chromium/components/previews/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+ # Previews is a layered component; subdirectories must introduce
+ # allowances of //content dependencies as appropriate.
+ "-components",
+ "-components/data_reduction_proxy/",
+ "-components/previews/content",
+] \ No newline at end of file
diff --git a/chromium/components/previews/content/BUILD.gn b/chromium/components/previews/content/BUILD.gn
index f19eb77774b..fb3f705af8e 100644
--- a/chromium/components/previews/content/BUILD.gn
+++ b/chromium/components/previews/content/BUILD.gn
@@ -9,8 +9,8 @@ static_library("content") {
"hint_cache_leveldb_store.cc",
"hint_cache_leveldb_store.h",
"hint_cache_store.h",
- "previews_content_util.cc",
- "previews_content_util.h",
+ "hints_fetcher.cc",
+ "hints_fetcher.h",
"previews_decider_impl.cc",
"previews_decider_impl.h",
"previews_hints.cc",
@@ -19,6 +19,7 @@ static_library("content") {
"previews_hints_util.h",
"previews_optimization_guide.cc",
"previews_optimization_guide.h",
+ "previews_top_host_provider.h",
"previews_ui_service.cc",
"previews_ui_service.h",
"previews_user_data.cc",
@@ -45,7 +46,6 @@ source_set("unit_tests") {
sources = [
"hint_cache_leveldb_store_unittest.cc",
"hint_cache_unittest.cc",
- "previews_content_util_unittest.cc",
"previews_decider_impl_unittest.cc",
"previews_hints_unittest.cc",
"previews_hints_util_unittest.cc",
diff --git a/chromium/components/previews/content/DEPS b/chromium/components/previews/content/DEPS
index 579b2e9b73e..9c35d75a9c4 100644
--- a/chromium/components/previews/content/DEPS
+++ b/chromium/components/previews/content/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+components/blacklist/opt_out_blacklist",
"+components/leveldb_proto",
"+components/optimization_guide",
+ "+components/previews/core",
"+components/url_matcher",
"+components/variations",
"+content/public/common",
diff --git a/chromium/components/previews/content/hint_cache_leveldb_store.cc b/chromium/components/previews/content/hint_cache_leveldb_store.cc
index 1ceb98e281d..3a35fbef5ee 100644
--- a/chromium/components/previews/content/hint_cache_leveldb_store.cc
+++ b/chromium/components/previews/content/hint_cache_leveldb_store.cc
@@ -4,6 +4,7 @@
#include "components/previews/content/hint_cache_leveldb_store.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
diff --git a/chromium/components/previews/content/hints_fetcher.cc b/chromium/components/previews/content/hints_fetcher.cc
new file mode 100644
index 00000000000..c6b81fee3f4
--- /dev/null
+++ b/chromium/components/previews/content/hints_fetcher.cc
@@ -0,0 +1,63 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/previews/content/hints_fetcher.h"
+
+#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
+#include "components/optimization_guide/proto/hints.pb.h"
+#include "components/previews/content/hint_cache.h"
+#include "components/previews/core/previews_experiments.h"
+
+namespace previews {
+
+HintsFetcher::HintsFetcher(HintCache* hint_cache) : hint_cache_(hint_cache) {}
+
+HintsFetcher::~HintsFetcher() {}
+
+void HintsFetcher::FetchHintsForHosts(const std::vector<std::string>& hosts) {
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ GetRemoteHints(hosts);
+}
+
+void HintsFetcher::GetRemoteHints(const std::vector<std::string>& hosts) {
+ get_hints_request_ =
+ std::make_unique<optimization_guide::proto::GetHintsRequest>();
+
+ // Add all the optimizations supported by the current version of Chrome,
+ // regardless of whether the session is in holdback for either of them.
+ get_hints_request_->add_supported_optimizations(
+ optimization_guide::proto::NOSCRIPT);
+ get_hints_request_->add_supported_optimizations(
+ optimization_guide::proto::RESOURCE_LOADING);
+ static_assert(static_cast<int>(PreviewsType::LITE_PAGE_REDIRECT) + 1 ==
+ static_cast<int>(PreviewsType::LAST),
+ "PreviewsType has been updated, make sure OnePlatform hints "
+ "are not affected");
+
+ get_hints_request_->set_context(
+ optimization_guide::proto::CONTEXT_BATCH_UPDATE);
+
+ for (const auto& host : hosts) {
+ optimization_guide::proto::HostInfo* host_info =
+ get_hints_request_->add_hosts();
+ host_info->set_host(host);
+ }
+}
+
+void HintsFetcher::HandleResponse(const std::string& config_data,
+ int status,
+ int response_code) {}
+
+void HintsFetcher::OnURLLoadComplete(
+ std::unique_ptr<std::string> response_body) {}
+
+bool HintsFetcher::ParseGetHintsResponseAndApplyHints(
+ const optimization_guide::proto::GetHintsResponse& get_hints_response) {
+ ALLOW_UNUSED_LOCAL(hint_cache_);
+ return false;
+}
+
+} // namespace previews
diff --git a/chromium/components/previews/content/hints_fetcher.h b/chromium/components/previews/content/hints_fetcher.h
new file mode 100644
index 00000000000..37c49236604
--- /dev/null
+++ b/chromium/components/previews/content/hints_fetcher.h
@@ -0,0 +1,78 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PREVIEWS_CONTENT_HINTS_FETCHER_H_
+#define COMPONENTS_PREVIEWS_CONTENT_HINTS_FETCHER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/sequence_checker.h"
+#include "components/optimization_guide/proto/hints.pb.h"
+#include "components/previews/core/previews_experiments.h"
+#include "url/gurl.h"
+
+namespace previews {
+
+class HintCache;
+
+// A class to handle OnePlatform client requests for optimization hints from
+// the remote Optimization Guide Service.
+//
+// When Chrome starts up, if the client's OnePlatform hints have not been
+// updated in over day, this class will be triggered to fetch new hints from the
+// remote Optimization Guide Service. Owner must ensure that |hint_cache|
+// remains alive for the lifetime of |HintsFetcher|.
+class HintsFetcher {
+ public:
+ explicit HintsFetcher(HintCache* hint_cache);
+ ~HintsFetcher();
+
+ // Handles any configuration or checking needed and then
+ // initiates the fetch of OnePlatform Hints.
+ void FetchHintsForHosts(const std::vector<std::string>& hosts);
+
+ private:
+ // Creates the GetHintsResponse proto and executes the SimpleURLLoader request
+ // to the remote Optimization Guide Service with the |get_hints_request_|.
+ void GetRemoteHints(const std::vector<std::string>& hosts);
+
+ // Handles the response from the remote Optimization Guide Service.
+ // |response| is the response body, |status| is the
+ // |net::Error| of the response, and response_code is the HTTP
+ // response code (if available).
+ void HandleResponse(const std::string& response,
+ int status,
+ int response_code);
+
+ // URL loader completion callback.
+ void OnURLLoadComplete(std::unique_ptr<std::string> response_body);
+
+ // Parses the hints component of |get_hints_response| and applies it to
+ // |hints_|. Returns true if |get_hints_response| was successfully
+ // parsed and applied.
+ bool ParseGetHintsResponseAndApplyHints(
+ const optimization_guide::proto::GetHintsResponse& get_hints_response);
+
+ // Used to hold the GetHintsRequest being constructed and sent as a remote
+ // request.
+ std::unique_ptr<optimization_guide::proto::GetHintsRequest>
+ get_hints_request_;
+
+ // The URL for the remote Optimization Guide Service.
+ const GURL oneplatform_service_url_;
+
+ // The caller must ensure that the |hints_| outlives this instance.
+ HintCache* hint_cache_ = nullptr;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(HintsFetcher);
+};
+
+} // namespace previews
+
+#endif // COMPONENTS_PREVIEWS_CONTENT_HINTS_FETCHER_H_
diff --git a/chromium/components/previews/content/previews_content_util.cc b/chromium/components/previews/content/previews_content_util.cc
deleted file mode 100644
index 09cda2dcbd8..00000000000
--- a/chromium/components/previews/content/previews_content_util.cc
+++ /dev/null
@@ -1,228 +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/previews/content/previews_content_util.h"
-
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
-#include "components/previews/content/previews_user_data.h"
-#include "components/previews/core/previews_lite_page_redirect.h"
-
-namespace previews {
-
-bool HasEnabledPreviews(content::PreviewsState previews_state) {
- return previews_state != content::PREVIEWS_UNSPECIFIED &&
- !(previews_state & content::PREVIEWS_OFF) &&
- !(previews_state & content::PREVIEWS_NO_TRANSFORM);
-}
-
-content::PreviewsState DetermineAllowedClientPreviewsState(
- previews::PreviewsUserData* previews_data,
- const GURL& url,
- bool is_reload,
- bool is_redirect,
- bool is_data_saver_user,
- previews::PreviewsDecider* previews_decider) {
- content::PreviewsState previews_state = content::PREVIEWS_UNSPECIFIED;
-
- // Record whether the hint cache has a matching entry for this pre-commit URL.
- previews_decider->LogHintCacheMatch(url, false /* is_committed */);
-
- if (!previews::params::ArePreviewsAllowed()) {
- return previews_state;
- }
-
- if (!url.SchemeIsHTTPOrHTTPS()) {
- return previews_state;
- }
-
- // Offline previews state should not be updated during a redirect. The Offline
- // Previews URLLoader will not receive an updated PreviewsState, so the state
- // should stay consistent throughout the navigation.
- if (is_redirect) {
- // Record that the navigation was redirected.
- previews_data->set_is_redirect(true);
- // Keep the same OFFLINE previews bit as the original URL.
- previews_state |=
- (previews_data->allowed_previews_state() & content::OFFLINE_PAGE_ON);
- } else if (previews_decider->ShouldAllowPreviewAtNavigationStart(
- previews_data, url, is_reload,
- previews::PreviewsType::OFFLINE)) {
- previews_state |= content::OFFLINE_PAGE_ON;
- }
-
- // Only offline previews can be shown for non-data saver users.
- if (!is_data_saver_user)
- return previews_state;
-
- // Check PageHint preview types first.
-
- bool should_load_page_hints = false;
- if (previews_decider->ShouldAllowPreviewAtNavigationStart(
- previews_data, url, is_reload,
- previews::PreviewsType::RESOURCE_LOADING_HINTS)) {
- previews_state |= content::RESOURCE_LOADING_HINTS_ON;
- should_load_page_hints = true;
- }
- if (previews_decider->ShouldAllowPreviewAtNavigationStart(
- previews_data, url, is_reload, previews::PreviewsType::NOSCRIPT)) {
- previews_state |= content::NOSCRIPT_ON;
- should_load_page_hints = true;
- }
- bool has_page_hints = false;
- if (should_load_page_hints) {
- // Initiate load of any applicable page hint details.
- has_page_hints = previews_decider->LoadPageHints(url);
- }
-
- // Note: this is for the beginning of navigation so we should not
- // check for https here (since an http request may redirect to https).
- if ((!has_page_hints || params::LitePagePreviewsOverridePageHints()) &&
- previews_decider->ShouldAllowPreviewAtNavigationStart(
- previews_data, url, is_reload,
- previews::PreviewsType::LITE_PAGE_REDIRECT)) {
- previews_state |= content::LITE_PAGE_REDIRECT_ON;
- }
-
- if (previews::params::IsClientLoFiEnabled() &&
- previews_decider->ShouldAllowPreviewAtNavigationStart(
- previews_data, url, is_reload, previews::PreviewsType::LOFI)) {
- previews_state |= content::CLIENT_LOFI_ON;
- }
-
- return previews_state;
-}
-
-void LogCommittedPreview(previews::PreviewsUserData* previews_data,
- PreviewsType type) {
- net::EffectiveConnectionType navigation_ect = previews_data->navigation_ect();
- UMA_HISTOGRAM_ENUMERATION("Previews.Triggered.EffectiveConnectionType2",
- navigation_ect,
- net::EFFECTIVE_CONNECTION_TYPE_LAST);
- base::UmaHistogramEnumeration(
- base::StringPrintf("Previews.Triggered.EffectiveConnectionType2.%s",
- GetStringNameForType(type).c_str()),
- navigation_ect, net::EFFECTIVE_CONNECTION_TYPE_LAST);
-}
-
-content::PreviewsState DetermineCommittedClientPreviewsState(
- previews::PreviewsUserData* previews_data,
- const GURL& url,
- content::PreviewsState previews_state,
- const previews::PreviewsDecider* previews_decider) {
- bool is_https = url.SchemeIs(url::kHttpsScheme);
-
- // Record whether the hint cache has a matching entry for this committed URL.
- previews_decider->LogHintCacheMatch(url, true /* is_committed */);
-
- // Check if an offline preview was actually served.
- if (previews_data && previews_data->offline_preview_used()) {
- DCHECK(previews_state & content::OFFLINE_PAGE_ON);
- LogCommittedPreview(previews_data, PreviewsType::OFFLINE);
- return content::OFFLINE_PAGE_ON;
- }
- previews_state &= ~content::OFFLINE_PAGE_ON;
-
- // If a server preview is set, retain only the bits determined for the server.
- // |previews_state| must already have been updated for server previews from
- // the main frame response headers (so if they are set here, then they are
- // the specify the committed preview). Note: for Server LoFi we keep the
- // Client LoFi bit on so that it is applied to both HTTP and HTTPS images.
- if (previews_state &
- (content::SERVER_LITE_PAGE_ON | content::SERVER_LOFI_ON)) {
- LogCommittedPreview(previews_data, PreviewsType::LITE_PAGE);
- return previews_state & (content::SERVER_LITE_PAGE_ON |
- content::SERVER_LOFI_ON | content::CLIENT_LOFI_ON);
- }
-
- if (previews_data && previews_data->cache_control_no_transform_directive()) {
- if (HasEnabledPreviews(previews_state)) {
- UMA_HISTOGRAM_ENUMERATION(
- "Previews.CacheControlNoTransform.BlockedPreview",
- GetMainFramePreviewsType(previews_state),
- previews::PreviewsType::LAST);
- }
- return content::PREVIEWS_OFF;
- }
-
- // Check if a LITE_PAGE_REDIRECT preview was actually served.
- if (previews_state & content::LITE_PAGE_REDIRECT_ON) {
- if (IsLitePageRedirectPreviewURL(url)) {
- LogCommittedPreview(previews_data, PreviewsType::LITE_PAGE_REDIRECT);
- return content::LITE_PAGE_REDIRECT_ON;
- }
- previews_state &= ~content::LITE_PAGE_REDIRECT_ON;
- }
- DCHECK(!IsLitePageRedirectPreviewURL(url));
-
- // Make priority decision among allowed client preview types that can be
- // decided at Commit time.
- if (previews_state & content::RESOURCE_LOADING_HINTS_ON) {
- // Resource loading hints was chosen for the original URL but only continue
- // with it if the committed URL has HTTPS scheme and is allowed by decider.
- if (is_https && previews_decider &&
- previews_decider->ShouldCommitPreview(
- previews_data, url,
- previews::PreviewsType::RESOURCE_LOADING_HINTS)) {
- LogCommittedPreview(previews_data, PreviewsType::RESOURCE_LOADING_HINTS);
- return content::RESOURCE_LOADING_HINTS_ON;
- }
- // Remove RESOURCE_LOADING_HINTS_ON from |previews_state| since we decided
- // not to commit to it.
- previews_state = previews_state & ~content::RESOURCE_LOADING_HINTS_ON;
- }
-
- if (previews_state & content::NOSCRIPT_ON) {
- // NoScript was chosen for the original URL but only continue with it
- // if the committed URL has HTTPS scheme and is allowed by decider.
- if (is_https && previews_decider &&
- previews_decider->ShouldCommitPreview(
- previews_data, url, previews::PreviewsType::NOSCRIPT)) {
- LogCommittedPreview(previews_data, PreviewsType::NOSCRIPT);
- return content::NOSCRIPT_ON;
- }
- // Remove NOSCRIPT_ON from |previews_state| since we decided not to
- // commit to it.
- previews_state = previews_state & ~content::NOSCRIPT_ON;
- }
- if (previews_state & content::CLIENT_LOFI_ON) {
- LogCommittedPreview(previews_data, PreviewsType::LOFI);
- return content::CLIENT_LOFI_ON;
- }
-
- if (!previews_state) {
- return content::PREVIEWS_OFF;
- }
-
- DCHECK(previews_state == content::PREVIEWS_OFF ||
- previews_state == content::PREVIEWS_UNSPECIFIED);
- return content::PREVIEWS_OFF;
-}
-
-previews::PreviewsType GetMainFramePreviewsType(
- content::PreviewsState previews_state) {
- // The order is important here.
- if (previews_state & content::OFFLINE_PAGE_ON)
- return previews::PreviewsType::OFFLINE;
- if (previews_state & content::LITE_PAGE_REDIRECT_ON)
- return previews::PreviewsType::LITE_PAGE_REDIRECT;
- if (previews_state & content::SERVER_LITE_PAGE_ON)
- return previews::PreviewsType::LITE_PAGE;
- if (previews_state & content::SERVER_LOFI_ON)
- return previews::PreviewsType::LOFI;
- if (previews_state & content::RESOURCE_LOADING_HINTS_ON)
- return previews::PreviewsType::RESOURCE_LOADING_HINTS;
- if (previews_state & content::NOSCRIPT_ON)
- return previews::PreviewsType::NOSCRIPT;
- if (previews_state & content::CLIENT_LOFI_ON)
- return previews::PreviewsType::LOFI;
-
- DCHECK_EQ(content::PREVIEWS_UNSPECIFIED,
- previews_state & ~content::CLIENT_LOFI_AUTO_RELOAD &
- ~content::PREVIEWS_NO_TRANSFORM & ~content::PREVIEWS_OFF);
- return previews::PreviewsType::NONE;
-}
-
-} // namespace previews
diff --git a/chromium/components/previews/content/previews_content_util.h b/chromium/components/previews/content/previews_content_util.h
deleted file mode 100644
index 7a3460588a6..00000000000
--- a/chromium/components/previews/content/previews_content_util.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_PREVIEWS_CONTENT_PREVIEWS_CONTENT_UTIL_H_
-#define COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_CONTENT_UTIL_H_
-
-#include "components/previews/core/previews_decider.h"
-#include "content/public/common/previews_state.h"
-
-namespace previews {
-
-// Returns whether |previews_state| has any enabled previews.
-bool HasEnabledPreviews(content::PreviewsState previews_state);
-
-// Returns the bitmask of enabled client-side previews for |url| and the
-// current effective network connection given |previews_decider|.
-// This handles the mapping of previews::PreviewsType enum values to bitmask
-// definitions for content::PreviewsState.
-// |is_reload| is used to eliminate certain preview types, and |previews_data|
-// is populated with relevant information.
-content::PreviewsState DetermineAllowedClientPreviewsState(
- previews::PreviewsUserData* previews_data,
- const GURL& url,
- bool is_reload,
- bool is_redirect,
- bool is_data_saver_user,
- previews::PreviewsDecider* previews_decider);
-
-// Returns an updated PreviewsState given |previews_state| that has already
-// been updated wrt server previews. This should be called at Navigation Commit
-// time. It will defer to any server preview set, otherwise it chooses which
-// client preview bits to retain for processing the main frame response.
-content::PreviewsState DetermineCommittedClientPreviewsState(
- previews::PreviewsUserData* previews_data,
- const GURL& url,
- content::PreviewsState previews_state,
- const previews::PreviewsDecider* previews_decider);
-
-// Returns the effective PreviewsType known on a main frame basis given the
-// |previews_state| bitmask for the committed main frame. This uses the same
-// previews precendence consideration as |DetermineCommittedClientPreviewsState|
-// in case it is called on a PreviewsState value that has not been filtered
-// through that method.
-previews::PreviewsType GetMainFramePreviewsType(
- content::PreviewsState previews_state);
-
-} // namespace previews
-
-#endif // COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_CONTENT_UTIL_H_
diff --git a/chromium/components/previews/content/previews_content_util_unittest.cc b/chromium/components/previews/content/previews_content_util_unittest.cc
deleted file mode 100644
index 6abf0c4b66c..00000000000
--- a/chromium/components/previews/content/previews_content_util_unittest.cc
+++ /dev/null
@@ -1,490 +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/previews/content/previews_content_util.h"
-
-#include <memory>
-#include <vector>
-
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/scoped_task_environment.h"
-#include "components/previews/content/previews_user_data.h"
-#include "components/previews/core/previews_experiments.h"
-#include "components/previews/core/previews_features.h"
-#include "content/public/common/previews_state.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace previews {
-
-namespace {
-
-// A test implementation of PreviewsDecider that simply returns whether the
-// preview type feature is enabled (ignores ECT and blacklist considerations).
-class PreviewEnabledPreviewsDecider : public PreviewsDecider {
- public:
- PreviewEnabledPreviewsDecider() {}
- ~PreviewEnabledPreviewsDecider() override {}
-
- bool ShouldAllowPreviewAtNavigationStart(PreviewsUserData* previews_data,
- const GURL& url,
- bool is_reload,
- PreviewsType type) const override {
- return IsEnabled(type);
- }
-
- bool ShouldCommitPreview(PreviewsUserData* previews_data,
- const GURL& url,
- PreviewsType type) const override {
- EXPECT_TRUE(type == PreviewsType::NOSCRIPT ||
- type == PreviewsType::RESOURCE_LOADING_HINTS);
- return IsEnabled(type);
- }
-
- bool LoadPageHints(const GURL& url) override {
- return url.host_piece().ends_with("hintcachedhost.com");
- }
-
- bool GetResourceLoadingHints(
- const GURL& url,
- std::vector<std::string>* out_resource_patterns_to_block) const override {
- return false;
- }
-
- void LogHintCacheMatch(const GURL& url, bool is_committed) const override {}
-
- private:
- bool IsEnabled(PreviewsType type) const {
- switch (type) {
- case previews::PreviewsType::OFFLINE:
- return params::IsOfflinePreviewsEnabled();
- case previews::PreviewsType::LOFI:
- return params::IsClientLoFiEnabled();
- case previews::PreviewsType::DEPRECATED_AMP_REDIRECTION:
- return false;
- case previews::PreviewsType::NOSCRIPT:
- return params::IsNoScriptPreviewsEnabled();
- case previews::PreviewsType::RESOURCE_LOADING_HINTS:
- return params::IsResourceLoadingHintsEnabled();
- case previews::PreviewsType::LITE_PAGE_REDIRECT:
- return params::IsLitePageServerPreviewsEnabled();
- case PreviewsType::LITE_PAGE:
- case PreviewsType::NONE:
- case PreviewsType::UNSPECIFIED:
- case PreviewsType::LAST:
- break;
- }
- NOTREACHED();
- return false;
- }
-};
-
-class PreviewsContentUtilTest : public testing::Test {
- public:
- PreviewsContentUtilTest() {}
- ~PreviewsContentUtilTest() override {}
-
- PreviewsDecider* enabled_previews_decider() {
- return &enabled_previews_decider_;
- }
-
- protected:
- base::test::ScopedTaskEnvironment task_environment_;
-
- private:
- PreviewEnabledPreviewsDecider enabled_previews_decider_;
-};
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStatePreviewsDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "ClientLoFi,ResourceLoadingHints,NoScriptPreviews" /* enable_features */,
- "Previews" /* disable_features */);
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- EXPECT_EQ(content::PREVIEWS_UNSPECIFIED,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_EQ(content::PREVIEWS_UNSPECIFIED,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateDataSaverDisabled) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "Previews,ClientLoFi,ResourceLoadingHints,NoScriptPreviews",
- {} /* disable_features */);
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- EXPECT_EQ(content::OFFLINE_PAGE_ON | content::CLIENT_LOFI_ON |
- content::RESOURCE_LOADING_HINTS_ON | content::NOSCRIPT_ON,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- is_data_saver_user = false;
- EXPECT_EQ(content::OFFLINE_PAGE_ON,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateOfflineAndRedirects) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "Previews,ClientLoFi,ResourceLoadingHints,NoScriptPreviews",
- {} /* disable_features */);
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = false;
- EXPECT_EQ(content::OFFLINE_PAGE_ON,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_FALSE(user_data.is_redirect());
- user_data.set_allowed_previews_state(content::OFFLINE_PAGE_ON);
- is_redirect = true;
- EXPECT_EQ(content::OFFLINE_PAGE_ON,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_TRUE(user_data.is_redirect());
- user_data.set_allowed_previews_state(content::PREVIEWS_OFF);
- EXPECT_EQ(content::PREVIEWS_UNSPECIFIED,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- is_redirect = false;
- EXPECT_EQ(content::OFFLINE_PAGE_ON,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest, DetermineAllowedClientPreviewsStateClientLoFi) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine("Previews,ClientLoFi", std::string());
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- EXPECT_TRUE(content::CLIENT_LOFI_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_TRUE(content::CLIENT_LOFI_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateResourceLoadingHints) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine("Previews,ResourceLoadingHints",
- std::string());
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- EXPECT_LT(
- 0, content::RESOURCE_LOADING_HINTS_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_LT(
- 0, content::RESOURCE_LOADING_HINTS_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateNoScriptAndClientLoFi) {
- // Enable both Client LoFi and NoScript.
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "Previews,ClientLoFi,NoScriptPreviews", std::string());
-
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- // Verify both are enabled.
- EXPECT_TRUE((content::NOSCRIPT_ON | content::CLIENT_LOFI_ON) &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_TRUE((content::NOSCRIPT_ON | content::CLIENT_LOFI_ON) &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-
- // Verify non-HTTP[S] URL has no previews enabled.
- EXPECT_EQ(content::PREVIEWS_UNSPECIFIED,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("data://someblob"), is_reload, is_redirect,
- is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateLitePageRedirect) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine("Previews,LitePageServerPreviews",
- std::string());
-
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- // Verify preview is enabled on HTTP and HTTPS.
- EXPECT_TRUE(content::LITE_PAGE_REDIRECT_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
- EXPECT_TRUE(content::LITE_PAGE_REDIRECT_ON &
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("http://www.google.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider()));
-
- // Verify non-HTTP[S] URL has no previews enabled.
- EXPECT_EQ(content::PREVIEWS_UNSPECIFIED,
- previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("data://someblob"), is_reload, is_redirect,
- is_data_saver_user, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineAllowedClientPreviewsStateLitePageRedirectAndPageHintPreviews) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "Previews,LitePageServerPreviews,ResourceLoadingHints,NoScriptPreviews",
- std::string());
-
- PreviewsUserData user_data(1);
- bool is_reload = false;
- bool is_redirect = false;
- bool is_data_saver_user = true;
- // Verify Lite Page Redirect enabled for host without page hints.
- content::PreviewsState ps1 = previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.google.com"), is_reload, is_redirect,
- is_data_saver_user, enabled_previews_decider());
- EXPECT_TRUE(ps1 & content::LITE_PAGE_REDIRECT_ON);
- EXPECT_TRUE(ps1 & content::RESOURCE_LOADING_HINTS_ON);
- EXPECT_TRUE(ps1 & content::NOSCRIPT_ON);
-
- // Verify only page hint client previews enabled with known page hints.
- content::PreviewsState ps2 = previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.hintcachedhost.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider());
- EXPECT_FALSE(ps2 & content::LITE_PAGE_REDIRECT_ON);
- EXPECT_TRUE(ps2 & content::RESOURCE_LOADING_HINTS_ON);
- EXPECT_TRUE(ps2 & content::NOSCRIPT_ON);
-
- {
- // Now set parameter to override page hints.
- std::map<std::string, std::string> parameters;
- parameters["override_pagehints"] = "true";
- base::test::ScopedFeatureList nested_feature_list;
- nested_feature_list.InitAndEnableFeatureWithParameters(
- features::kLitePageServerPreviews, parameters);
-
- // Verify Lite Page Redirect now enabled for host with page hints.
- content::PreviewsState ps = previews::DetermineAllowedClientPreviewsState(
- &user_data, GURL("https://www.hintcachedhost.com"), is_reload,
- is_redirect, is_data_saver_user, enabled_previews_decider());
- EXPECT_TRUE(ps & content::LITE_PAGE_REDIRECT_ON);
- EXPECT_TRUE(ps & content::RESOURCE_LOADING_HINTS_ON);
- EXPECT_TRUE(ps & content::NOSCRIPT_ON);
- }
-}
-
-TEST_F(PreviewsContentUtilTest, DetermineCommittedClientPreviewsState) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine(
- "Previews,ClientLoFi,NoScriptPreviews,ResourceLoadingHints",
- std::string());
- PreviewsUserData user_data(1);
- user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_2G);
- base::HistogramTester histogram_tester;
-
- // Server bits take precedence over NoScript:
- EXPECT_EQ(content::SERVER_LITE_PAGE_ON | content::SERVER_LOFI_ON |
- content::CLIENT_LOFI_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::SERVER_LITE_PAGE_ON | content::SERVER_LOFI_ON |
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON,
- enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.LitePage",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 1);
-
- content::PreviewsState lite_page_redirect_enabled =
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON |
- content::RESOURCE_LOADING_HINTS_ON | content::LITE_PAGE_REDIRECT_ON;
-
- // LITE_PAGE_REDIRECT takes precedence over NoScript, Resource Loading Hints,
- // and Client LoFi when the committed URL is for the lite page previews
- // server.
- EXPECT_EQ(
- content::LITE_PAGE_REDIRECT_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://litepages.googlezip.net/?u=google.com"),
- lite_page_redirect_enabled, enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.LitePageRedirect",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 2);
-
- // Verify LITE_PAGE_REDIRECT_ON not committed for non-lite-page-sever URL.
- EXPECT_NE(content::LITE_PAGE_REDIRECT_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- lite_page_redirect_enabled, enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.ResourceLoadingHints",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 3);
-
- // NoScript has precedence over Client LoFi - kept for committed HTTPS:
- EXPECT_EQ(content::NOSCRIPT_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON,
- enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.NoScript",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 4);
-
- // Try different navigation ECT value.
- user_data.set_navigation_ect(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
-
- // RESOURCE_LOADING_HINTS has precedence over Client LoFi and NoScript.
- EXPECT_EQ(content::RESOURCE_LOADING_HINTS_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON |
- content::RESOURCE_LOADING_HINTS_ON,
- enabled_previews_decider()));
- histogram_tester.ExpectBucketCount(
- "Previews.Triggered.EffectiveConnectionType2.ResourceLoadingHints",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 5);
-
- // NoScript has precedence over Client LoFi - except for committed HTTP:
- EXPECT_EQ(content::CLIENT_LOFI_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("http://www.google.com"),
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON |
- content::RESOURCE_LOADING_HINTS_ON,
- enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.LoFi",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G), 1);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 6);
-
- // Only Client LoFi:
- EXPECT_EQ(content::CLIENT_LOFI_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::CLIENT_LOFI_ON, enabled_previews_decider()));
- histogram_tester.ExpectUniqueSample(
- "Previews.Triggered.EffectiveConnectionType2.LoFi",
- static_cast<int>(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G), 2);
- histogram_tester.ExpectTotalCount(
- "Previews.Triggered.EffectiveConnectionType2", 7);
-
- // Only NoScript:
- EXPECT_EQ(content::NOSCRIPT_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::NOSCRIPT_ON, enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest,
- DetermineCommittedClientPreviewsStateNoScriptCheckIfStillAllowed) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitFromCommandLine("Previews,ClientLoFi",
- "NoScriptPreviews");
- PreviewsUserData user_data(1);
- // NoScript not allowed at commit time so Client LoFi chosen:
- EXPECT_EQ(content::CLIENT_LOFI_ON,
- previews::DetermineCommittedClientPreviewsState(
- &user_data, GURL("https://www.google.com"),
- content::CLIENT_LOFI_ON | content::NOSCRIPT_ON |
- content::RESOURCE_LOADING_HINTS_ON,
- enabled_previews_decider()));
-}
-
-TEST_F(PreviewsContentUtilTest, GetMainFramePreviewsType) {
- // Simple cases:
- EXPECT_EQ(previews::PreviewsType::LITE_PAGE,
- previews::GetMainFramePreviewsType(content::SERVER_LITE_PAGE_ON));
- EXPECT_EQ(previews::PreviewsType::LOFI,
- previews::GetMainFramePreviewsType(content::SERVER_LOFI_ON));
- EXPECT_EQ(previews::PreviewsType::NOSCRIPT,
- previews::GetMainFramePreviewsType(content::NOSCRIPT_ON));
- EXPECT_EQ(
- previews::PreviewsType::RESOURCE_LOADING_HINTS,
- previews::GetMainFramePreviewsType(content::RESOURCE_LOADING_HINTS_ON));
- EXPECT_EQ(previews::PreviewsType::LOFI,
- previews::GetMainFramePreviewsType(content::CLIENT_LOFI_ON));
- EXPECT_EQ(previews::PreviewsType::LITE_PAGE_REDIRECT,
- previews::GetMainFramePreviewsType(content::LITE_PAGE_REDIRECT_ON));
-
- // NONE cases:
- EXPECT_EQ(previews::PreviewsType::NONE,
- previews::GetMainFramePreviewsType(content::PREVIEWS_UNSPECIFIED));
- EXPECT_EQ(previews::PreviewsType::NONE,
- previews::GetMainFramePreviewsType(content::PREVIEWS_NO_TRANSFORM));
-
- // Precedence cases when server preview is available:
- EXPECT_EQ(previews::PreviewsType::LITE_PAGE,
- previews::GetMainFramePreviewsType(
- content::SERVER_LITE_PAGE_ON | content::SERVER_LOFI_ON |
- content::NOSCRIPT_ON | content::CLIENT_LOFI_ON |
- content::RESOURCE_LOADING_HINTS_ON));
- EXPECT_EQ(previews::PreviewsType::LOFI,
- previews::GetMainFramePreviewsType(
- content::SERVER_LOFI_ON | content::NOSCRIPT_ON |
- content::CLIENT_LOFI_ON | content::RESOURCE_LOADING_HINTS_ON));
-
- // Precedence cases when server preview is not available:
- EXPECT_EQ(previews::PreviewsType::NOSCRIPT,
- previews::GetMainFramePreviewsType(content::NOSCRIPT_ON |
- content::CLIENT_LOFI_ON));
- EXPECT_EQ(previews::PreviewsType::RESOURCE_LOADING_HINTS,
- previews::GetMainFramePreviewsType(
- content::NOSCRIPT_ON | content::CLIENT_LOFI_ON |
- content::RESOURCE_LOADING_HINTS_ON));
- EXPECT_EQ(
- previews::PreviewsType::LITE_PAGE_REDIRECT,
- previews::GetMainFramePreviewsType(
- content::NOSCRIPT_ON | content::CLIENT_LOFI_ON |
- content::RESOURCE_LOADING_HINTS_ON | content::LITE_PAGE_REDIRECT_ON));
-}
-
-} // namespace
-
-} // namespace previews
diff --git a/chromium/components/previews/content/previews_decider_impl.cc b/chromium/components/previews/content/previews_decider_impl.cc
index 47034fa9941..62109e3811f 100644
--- a/chromium/components/previews/content/previews_decider_impl.cc
+++ b/chromium/components/previews/content/previews_decider_impl.cc
@@ -45,31 +45,6 @@ void LogPreviewsEligibilityReason(PreviewsEligibilityReason status,
->Add(static_cast<int>(status));
}
-bool AllowedOnReload(PreviewsType type) {
- if (base::FeatureList::IsEnabled(features::kPreviewsDisallowedOnReloads))
- return false;
-
- switch (type) {
- // These types return new content on refresh.
- case PreviewsType::LITE_PAGE:
- case PreviewsType::LITE_PAGE_REDIRECT:
- case PreviewsType::LOFI:
- case PreviewsType::NOSCRIPT:
- case PreviewsType::RESOURCE_LOADING_HINTS:
- return true;
- // Loading these types will always be stale when refreshed.
- case PreviewsType::OFFLINE:
- return false;
- case PreviewsType::NONE:
- case PreviewsType::UNSPECIFIED:
- case PreviewsType::DEPRECATED_AMP_REDIRECTION:
- case PreviewsType::LAST:
- break;
- }
- NOTREACHED();
- return false;
-}
-
bool ShouldCheckOptimizationHints(PreviewsType type) {
switch (type) {
// These types may have server optimization hints.
@@ -94,7 +69,7 @@ bool ShouldCheckOptimizationHints(PreviewsType type) {
// Returns true if ECT should be checked for |type| only at the commit time. If
// true is returned, then ECT need not be checked at the navigation time.
-bool CheckForUnknownECTOnlyAtCommitTime(PreviewsType type) {
+bool CheckECTOnlyAtCommitTime(PreviewsType type) {
switch (type) {
case PreviewsType::NOSCRIPT:
case PreviewsType::RESOURCE_LOADING_HINTS:
@@ -209,9 +184,6 @@ void PreviewsDeciderImpl::AddPreviewNavigation(const GURL& url,
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::Time time =
previews_black_list_->AddPreviewNavigation(url, opt_out, type);
- if (opt_out) {
- last_opt_out_time_ = time;
- }
LogPreviewNavigation(url, opt_out, type, time, page_id);
}
@@ -278,29 +250,20 @@ PreviewsEligibilityReason PreviewsDeciderImpl::DeterminePreviewEligibility(
if (url.has_username() || url.has_password())
return PreviewsEligibilityReason::URL_HAS_BASIC_AUTH;
- // Trigger the USER_RECENTLY_OPTED_OUT rule when a reload on a preview has
- // occurred recently.
- if (recent_preview_reload_time_ &&
- recent_preview_reload_time_.value() + params::SingleOptOutDuration() >
- clock_->Now()) {
- return PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT;
- }
+ // Skip blacklist checks if the blacklist is ignored.
+ if (!blacklist_ignored_) {
+ if (!previews_black_list_)
+ return PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE;
+ passed_reasons->push_back(PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE);
- // In the case that the user has chosen to ignore the normal blacklist rules
- // (flags or interventions-internals), a preview should still not be served
- // for 5 seconds after the last opt out. This allows "show original" to
- // function correctly as the start of that navigation will be within 5 seconds
- // (we don't yet re-evaluate on redirects, so this is sufficient).
- if (blacklist_ignored_) {
- if (clock_->Now() < last_opt_out_time_ + base::TimeDelta::FromSeconds(5)) {
+ // Trigger the USER_RECENTLY_OPTED_OUT rule when a reload on a preview has
+ // occurred recently. No need to push_back the eligibility reason as it will
+ // be added in IsLoadedAndAllowed as the first check.
+ if (recent_preview_reload_time_ &&
+ recent_preview_reload_time_.value() + params::SingleOptOutDuration() >
+ clock_->Now()) {
return PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT;
}
- passed_reasons->push_back(
- PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT);
- } else if (!previews_black_list_) {
- return PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE;
- } else {
- passed_reasons->push_back(PreviewsEligibilityReason::BLACKLIST_UNAVAILABLE);
// The blacklist will disallow certain hosts for periods of time based on
// user's opting out of the preview.
@@ -322,9 +285,8 @@ PreviewsEligibilityReason PreviewsDeciderImpl::DeterminePreviewEligibility(
// hints. This defers checking ECT for server previews because the server will
// perform its own ECT check and for previews with hints because the hints may
// specify variable ECT thresholds for slow page hints.
- if (!is_drp_server_preview && !ShouldCheckOptimizationHints(type)) {
- if (effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN &&
- !CheckForUnknownECTOnlyAtCommitTime(type)) {
+ if (!is_drp_server_preview && !CheckECTOnlyAtCommitTime(type)) {
+ if (effective_connection_type_ == net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
return PreviewsEligibilityReason::NETWORK_QUALITY_UNAVAILABLE;
}
passed_reasons->push_back(
@@ -347,11 +309,10 @@ PreviewsEligibilityReason PreviewsDeciderImpl::DeterminePreviewEligibility(
passed_reasons->push_back(PreviewsEligibilityReason::NETWORK_NOT_SLOW);
}
- // 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 (!AllowedOnReload(type) && is_reload) {
+ if (is_reload) {
return PreviewsEligibilityReason::RELOAD_DISALLOWED;
}
+
passed_reasons->push_back(PreviewsEligibilityReason::RELOAD_DISALLOWED);
// Check server whitelist/blacklist, if provided.
@@ -500,7 +461,7 @@ PreviewsDeciderImpl::ShouldCommitPreviewPerOptimizationHints(
// connectivity as null. See https://crbug.com/838969. So, we do not trigger
// previews when |ect| is net::EFFECTIVE_CONNECTION_TYPE_OFFLINE.
net::EffectiveConnectionType ect = previews_data->navigation_ect();
- if (CheckForUnknownECTOnlyAtCommitTime(type) &&
+ if (CheckECTOnlyAtCommitTime(type) &&
ect == net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
// Update the |ect| to the current value.
ect = effective_connection_type_;
diff --git a/chromium/components/previews/content/previews_decider_impl.h b/chromium/components/previews/content/previews_decider_impl.h
index 37788904bfd..11595db9798 100644
--- a/chromium/components/previews/content/previews_decider_impl.h
+++ b/chromium/components/previews/content/previews_decider_impl.h
@@ -131,6 +131,10 @@ class PreviewsDeciderImpl : public PreviewsDecider,
void SetEffectiveConnectionType(
net::EffectiveConnectionType effective_connection_type);
+ PreviewsOptimizationGuide* previews_opt_guide() const {
+ return previews_opt_guide_.get();
+ }
+
// When a preview is reloaded, this is called. No Previews are allowed for
// params::SingleOptOutDuration after that reload is reported.
void AddPreviewReload();
@@ -181,10 +185,6 @@ class PreviewsDeciderImpl : public PreviewsDecider,
std::unique_ptr<PreviewsBlackList> previews_black_list_;
- // Only used when the blacklist has been disabled to allow "Show Original" to
- // function as expected. The time of the most recent opt out event.
- base::Time last_opt_out_time_;
-
// Holds optimization guidance from the server.
std::unique_ptr<PreviewsOptimizationGuide> previews_opt_guide_;
diff --git a/chromium/components/previews/content/previews_decider_impl_unittest.cc b/chromium/components/previews/content/previews_decider_impl_unittest.cc
index 78f2b17804a..169906d35e1 100644
--- a/chromium/components/previews/content/previews_decider_impl_unittest.cc
+++ b/chromium/components/previews/content/previews_decider_impl_unittest.cc
@@ -36,6 +36,7 @@
#include "components/blacklist/opt_out_blacklist/opt_out_blacklist_item.h"
#include "components/blacklist/opt_out_blacklist/opt_out_store.h"
#include "components/optimization_guide/optimization_guide_service.h"
+#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_ui_service.h"
#include "components/previews/content/previews_user_data.h"
#include "components/previews/core/previews_black_list.h"
@@ -129,6 +130,17 @@ class TestPreviewsBlackList : public PreviewsBlackList {
PreviewsEligibilityReason status_;
};
+// A test class implementation to enable testing of previews_decider_impl.
+class TestPreviewsTopHostProvider : public PreviewsTopHostProvider {
+ public:
+ TestPreviewsTopHostProvider() {}
+ ~TestPreviewsTopHostProvider() override {}
+
+ std::vector<std::string> GetTopHosts(size_t max_sites) const override {
+ return std::vector<std::string>();
+ }
+};
+
// Stub class of PreviewsOptimizationGuide to control IsWhitelisted and
// IsBlacklisted outcomes when testing PreviewsDeciderImpl.
class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide {
@@ -136,10 +148,12 @@ class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide {
TestPreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
- const base::FilePath& test_path)
+ const base::FilePath& test_path,
+ PreviewsTopHostProvider* previews_top_host_provider)
: PreviewsOptimizationGuide(optimization_guide_service,
ui_task_runner,
- test_path) {}
+ test_path,
+ previews_top_host_provider) {}
~TestPreviewsOptimizationGuide() override {}
// PreviewsOptimizationGuide:
@@ -383,7 +397,7 @@ class PreviewsDeciderImplTest : public testing::Test {
std::make_unique<TestPreviewsOptimizationGuide>(
&optimization_guide_service_,
scoped_task_environment_.GetMainThreadTaskRunner(),
- temp_dir_.GetPath()),
+ temp_dir_.GetPath(), &previews_top_host_provider_),
base::BindRepeating(&IsPreviewFieldTrialEnabled),
std::make_unique<PreviewsLogger>(), std::move(allowed_types),
&network_quality_tracker_));
@@ -416,6 +430,7 @@ class PreviewsDeciderImplTest : public testing::Test {
base::FieldTrialList field_trial_list_;
TestPreviewsDeciderImpl* previews_decider_impl_;
optimization_guide::OptimizationGuideService optimization_guide_service_;
+ TestPreviewsTopHostProvider previews_top_host_provider_;
std::unique_ptr<TestPreviewsUIService> ui_service_;
network::TestNetworkQualityTracker network_quality_tracker_;
};
@@ -625,9 +640,7 @@ TEST_F(PreviewsDeciderImplTest, TestDisallowOfflineOnReload) {
TEST_F(PreviewsDeciderImplTest, TestDisallowLoFiOnReloadWithExperiment) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
- {features::kPreviews, features::kClientLoFi,
- features::kPreviewsDisallowedOnReloads},
- {});
+ {features::kPreviews, features::kClientLoFi}, {});
InitializeUIService();
ReportEffectiveConnectionType(net::EFFECTIVE_CONNECTION_TYPE_2G);
@@ -645,28 +658,6 @@ TEST_F(PreviewsDeciderImplTest, TestDisallowLoFiOnReloadWithExperiment) {
static_cast<int>(PreviewsEligibilityReason::RELOAD_DISALLOWED), 1);
}
-TEST_F(PreviewsDeciderImplTest, TestAllowLoFiOnReloadWithoutExperiment) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- {features::kPreviews, features::kClientLoFi},
- {features::kPreviewsDisallowedOnReloads});
- InitializeUIService();
-
- ReportEffectiveConnectionType(net::EFFECTIVE_CONNECTION_TYPE_2G);
-
- PreviewsUserData user_data(kDefaultPageId);
-
- base::HistogramTester histogram_tester;
- previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
- &user_data, GURL("https://www.google.com"), true, PreviewsType::LOFI);
- histogram_tester.ExpectBucketCount(
- "Previews.EligibilityReason",
- static_cast<int>(PreviewsEligibilityReason::RELOAD_DISALLOWED), 0);
- histogram_tester.ExpectBucketCount(
- "Previews.EligibilityReason.LoFi",
- static_cast<int>(PreviewsEligibilityReason::RELOAD_DISALLOWED), 0);
-}
-
TEST_F(PreviewsDeciderImplTest, TestAllowOffline) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kPreviews);
@@ -823,7 +814,7 @@ TEST_F(PreviewsDeciderImplTest, MissingHostDisallowed) {
&user_data, GURL("file:///sdcard"), false, PreviewsType::LOFI));
}
-TEST_F(PreviewsDeciderImplTest, ClientLoFiAllowedOnReload) {
+TEST_F(PreviewsDeciderImplTest, ClientLoFiDisallowedOnReload) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kPreviews, features::kClientLoFi}, {});
@@ -836,11 +827,11 @@ TEST_F(PreviewsDeciderImplTest, ClientLoFiAllowedOnReload) {
PreviewsUserData user_data(kDefaultPageId);
base::HistogramTester histogram_tester;
- EXPECT_TRUE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
+ EXPECT_FALSE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
&user_data, GURL("https://www.google.com"), true, PreviewsType::LOFI));
histogram_tester.ExpectUniqueSample(
"Previews.EligibilityReason.LoFi",
- static_cast<int>(PreviewsEligibilityReason::ALLOWED), 1);
+ static_cast<int>(PreviewsEligibilityReason::RELOAD_DISALLOWED), 1);
}
TEST_F(PreviewsDeciderImplTest, NoScriptFeatureDefaultBehavior) {
@@ -1145,7 +1136,7 @@ TEST_F(PreviewsDeciderImplTest, LitePageRedirectDisallowedByServerBlacklist) {
1);
}
-TEST_F(PreviewsDeciderImplTest, ResourceLoadingHintsDisallowedByDefault) {
+TEST_F(PreviewsDeciderImplTest, ResourceLoadingHintsAllowedByDefault) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kPreviews, features::kOptimizationHints}, {});
@@ -1153,9 +1144,16 @@ TEST_F(PreviewsDeciderImplTest, ResourceLoadingHintsDisallowedByDefault) {
base::HistogramTester histogram_tester;
PreviewsUserData user_data(kDefaultPageId);
- EXPECT_FALSE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
- &user_data, GURL("https://www.google.com"), false,
- PreviewsType::RESOURCE_LOADING_HINTS));
+
+#if defined(OS_ANDROID)
+ bool expected = true;
+#else // !defined(OS_ANDROID)
+ bool expected = false;
+#endif // defined(OS_ANDROID)
+ EXPECT_EQ(expected,
+ previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
+ &user_data, GURL("https://www.google.com"), false,
+ PreviewsType::RESOURCE_LOADING_HINTS));
}
TEST_F(PreviewsDeciderImplTest,
@@ -1518,7 +1516,7 @@ TEST_F(PreviewsDeciderImplTest, LogDecisionMadeBlacklistStatusesIgnore) {
}
}
-TEST_F(PreviewsDeciderImplTest, IgnoreFlagStillHasFiveSecondRule) {
+TEST_F(PreviewsDeciderImplTest, IgnoreFlagDoesNotCheckBlacklist) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kPreviews, features::kClientLoFi}, {});
@@ -1531,21 +1529,10 @@ TEST_F(PreviewsDeciderImplTest, IgnoreFlagStillHasFiveSecondRule) {
EXPECT_TRUE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
&user_data, GURL("https://www.google.com"), false, PreviewsType::LOFI));
- previews_decider_impl()->AddPreviewNavigation(
- GURL("http://wwww.somedomain.com"), true, PreviewsType::LOFI, 1);
-
- EXPECT_FALSE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
- &user_data, GURL("https://www.google.com"), false, PreviewsType::LOFI));
- EXPECT_EQ(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT,
- ui_service()->decision_reasons().back());
-
- clock_.Advance(base::TimeDelta::FromSeconds(6));
+ previews_decider_impl()->AddPreviewReload();
EXPECT_TRUE(previews_decider_impl()->ShouldAllowPreviewAtNavigationStart(
&user_data, GURL("https://www.google.com"), false, PreviewsType::LOFI));
- EXPECT_THAT(
- ui_service()->decision_passed_reasons().back(),
- ::testing::Contains(PreviewsEligibilityReason::USER_RECENTLY_OPTED_OUT));
}
TEST_F(PreviewsDeciderImplTest, ReloadsTriggerFiveMinuteRule) {
diff --git a/chromium/components/previews/content/previews_hints.cc b/chromium/components/previews/content/previews_hints.cc
index c6b31fd2494..ab7bdf4b0de 100644
--- a/chromium/components/previews/content/previews_hints.cc
+++ b/chromium/components/previews/content/previews_hints.cc
@@ -125,6 +125,21 @@ base::Optional<PreviewsType> ConvertProtoOptimizationTypeToPreviewsType(
}
}
+// Returns whether the optimization type is enabled on this client.
+bool IsEnabledOptimizationType(
+ optimization_guide::proto::OptimizationType optimization_type) {
+ switch (optimization_type) {
+ case optimization_guide::proto::TYPE_UNSPECIFIED:
+ return false;
+ case optimization_guide::proto::NOSCRIPT:
+ return previews::params::IsNoScriptPreviewsEnabled();
+ case optimization_guide::proto::RESOURCE_LOADING:
+ return previews::params::IsResourceLoadingHintsEnabled();
+ case optimization_guide::proto::LITE_PAGE_REDIRECT:
+ return previews::params::IsLitePageServerPreviewsEnabled();
+ }
+}
+
net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
optimization_guide::proto::EffectiveConnectionType proto_ect) {
switch (proto_ect) {
@@ -434,19 +449,25 @@ bool PreviewsHints::IsWhitelisted(
for (const auto& optimization :
matched_page_hint->whitelisted_optimizations()) {
+ // Skip over any disabled experimental optimizations.
+ if (IsDisabledExperimentalOptimization(optimization)) {
+ continue;
+ }
+ if (!IsEnabledOptimizationType(optimization.optimization_type())) {
+ continue;
+ }
+ // Client should use this first whitelisted optimization it has enabled.
if (ConvertProtoOptimizationTypeToPreviewsType(
- optimization.optimization_type()) == type) {
- if (IsDisabledExperimentalOptimization(optimization)) {
- continue;
- }
- // Found whitelisted optimization.
- *out_inflation_percent = optimization.inflation_percent();
- if (matched_page_hint->has_max_ect_trigger()) {
- *out_ect_threshold = ConvertProtoEffectiveConnectionType(
- matched_page_hint->max_ect_trigger());
- }
- return true;
+ optimization.optimization_type()) != type) {
+ return false;
}
+ // |type| is the first whitelisted optimization this client supports.
+ *out_inflation_percent = optimization.inflation_percent();
+ if (matched_page_hint->has_max_ect_trigger()) {
+ *out_ect_threshold = ConvertProtoEffectiveConnectionType(
+ matched_page_hint->max_ect_trigger());
+ }
+ return true;
}
return false;
diff --git a/chromium/components/previews/content/previews_hints_unittest.cc b/chromium/components/previews/content/previews_hints_unittest.cc
index 9fa246bedb0..1b9c24ea004 100644
--- a/chromium/components/previews/content/previews_hints_unittest.cc
+++ b/chromium/components/previews/content/previews_hints_unittest.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -458,7 +459,10 @@ TEST_F(PreviewsHintsTest, IsWhitelistedOutParams) {
}
TEST_F(PreviewsHintsTest,
- IsWhitelistedForNoScriptInPageHintsWithResourceLoadingHintsDisabled) {
+ IsWhitelistedForSecondOptimizationNoScriptWithFirstDisabled) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures({features::kNoScriptPreviews},
+ {features::kResourceLoadingHints});
optimization_guide::proto::Configuration config;
optimization_guide::proto::Hint* hint1 = config.add_hints();
@@ -467,11 +471,50 @@ TEST_F(PreviewsHintsTest,
// Page hint with NOSCRIPT optimization
optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
- page_hint1->set_page_pattern("/has_noscript/");
- optimization_guide::proto::Optimization* optimization_with_inflation_percent =
+ page_hint1->set_page_pattern("/has_multiple_optimizations/");
+ optimization_guide::proto::Optimization* optimization1 =
page_hint1->add_whitelisted_optimizations();
- optimization_with_inflation_percent->set_optimization_type(
- optimization_guide::proto::NOSCRIPT);
+ optimization1->set_optimization_type(
+ optimization_guide::proto::RESOURCE_LOADING);
+ optimization_guide::proto::Optimization* optimization2 =
+ page_hint1->add_whitelisted_optimizations();
+ optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);
+
+ ParseConfig(config);
+
+ int inflation_percent = 0;
+ net::EffectiveConnectionType ect_threshold =
+ net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+ EXPECT_TRUE(MaybeLoadHintAndCheckIsWhitelisted(
+ GURL("https://www.somedomain.org/has_multiple_optimizations/"),
+ PreviewsType::NOSCRIPT, &inflation_percent, &ect_threshold));
+ EXPECT_FALSE(MaybeLoadHintAndCheckIsWhitelisted(
+ GURL("https://www.somedomain.org/has_multiple_optimizations/"),
+ PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent,
+ &ect_threshold));
+}
+
+TEST_F(PreviewsHintsTest,
+ IsWhitelistedForSecondOptimizationResourceLoadingWithFirstDisabled) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures({features::kResourceLoadingHints},
+ {features::kNoScriptPreviews});
+ optimization_guide::proto::Configuration config;
+
+ optimization_guide::proto::Hint* hint1 = config.add_hints();
+ hint1->set_key("somedomain.org");
+ hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
+
+ // Page hint with NOSCRIPT optimization
+ optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
+ page_hint1->set_page_pattern("/has_multiple_optimizations/");
+ optimization_guide::proto::Optimization* optimization1 =
+ page_hint1->add_whitelisted_optimizations();
+ optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);
+ optimization_guide::proto::Optimization* optimization2 =
+ page_hint1->add_whitelisted_optimizations();
+ optimization2->set_optimization_type(
+ optimization_guide::proto::RESOURCE_LOADING);
ParseConfig(config);
@@ -479,8 +522,12 @@ TEST_F(PreviewsHintsTest,
net::EffectiveConnectionType ect_threshold =
net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
EXPECT_TRUE(MaybeLoadHintAndCheckIsWhitelisted(
- GURL("https://www.somedomain.org/has_noscript/"), PreviewsType::NOSCRIPT,
- &inflation_percent, &ect_threshold));
+ GURL("https://www.somedomain.org/has_multiple_optimizations/"),
+ PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent,
+ &ect_threshold));
+ EXPECT_FALSE(MaybeLoadHintAndCheckIsWhitelisted(
+ GURL("https://www.somedomain.org/has_multiple_optimizations/"),
+ PreviewsType::NOSCRIPT, &inflation_percent, &ect_threshold));
}
TEST_F(PreviewsHintsTest, IsWhitelistedForExperimentalPreview) {
diff --git a/chromium/components/previews/content/previews_optimization_guide.cc b/chromium/components/previews/content/previews_optimization_guide.cc
index 4c1f93733c6..5d0dd359dc2 100644
--- a/chromium/components/previews/content/previews_optimization_guide.cc
+++ b/chromium/components/previews/content/previews_optimization_guide.cc
@@ -8,15 +8,17 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_macros_local.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/previews/content/hint_cache_leveldb_store.h"
+#include "components/previews/content/hints_fetcher.h"
#include "components/previews/content/previews_hints.h"
#include "components/previews/content/previews_hints_util.h"
+#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_user_data.h"
#include "components/previews/core/previews_constants.h"
#include "components/previews/core/previews_switches.h"
@@ -81,7 +83,8 @@ ParseHintsProtoFromCommandLine() {
PreviewsOptimizationGuide::PreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
- const base::FilePath& profile_path)
+ const base::FilePath& profile_path,
+ PreviewsTopHostProvider* previews_top_host_provider)
: optimization_guide_service_(optimization_guide_service),
ui_task_runner_(ui_task_runner),
background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
@@ -89,6 +92,7 @@ PreviewsOptimizationGuide::PreviewsOptimizationGuide(
hint_cache_(std::make_unique<HintCache>(
std::make_unique<HintCacheLevelDBStore>(profile_path,
background_task_runner_))),
+ previews_top_host_provider_(previews_top_host_provider),
ui_weak_ptr_factory_(this) {
DCHECK(optimization_guide_service_);
hint_cache_->Initialize(
@@ -210,11 +214,27 @@ void PreviewsOptimizationGuide::OnHintCacheInitialized() {
if (manual_config) {
// Allow |UpdateHints| to block startup so that the first navigation gets
// the hints when a command line hint proto is provided.
- UpdateHints(PreviewsHints::CreateFromHintsConfiguration(
- std::move(manual_config),
- hint_cache_->MaybeCreateComponentUpdateData(
- base::Version(kManualConfigComponentVersion))));
+ UpdateHints(base::OnceClosure(),
+ PreviewsHints::CreateFromHintsConfiguration(
+ std::move(manual_config),
+ hint_cache_->MaybeCreateComponentUpdateData(
+ base::Version(kManualConfigComponentVersion))));
}
+
+ // If user is eligible for platform hints, currently controlled by a feature
+ // flag |kPreviewsOnePlatformHints|, start the OnePlatform client request.
+ // TODO(mcrouse): Add a check for user specific state in addition to the
+ // feature state:
+ // (1) Data saver should be enabled
+ // (2) Infobar notification does not need to be shown to the user.
+
+ if (previews::params::IsOnePlatformHintsEnabled()) {
+ // TODO(mcrouse): We will likely need to an async call and likely
+ // within a timer that will call GetOnePlatformClientHints().
+ // This is a temporary call for testing.
+ GetOnePlatformClientHints();
+ }
+
// Register as an observer regardless of hint proto override usage. This is
// needed as a signal during testing.
optimization_guide_service_->AddObserver(this);
@@ -243,10 +263,34 @@ void PreviewsOptimizationGuide::OnHintsComponentAvailable(
base::BindOnce(&PreviewsHints::CreateFromHintsComponent, info,
hint_cache_->MaybeCreateComponentUpdateData(info.version)),
base::BindOnce(&PreviewsOptimizationGuide::UpdateHints,
- ui_weak_ptr_factory_.GetWeakPtr()));
+ ui_weak_ptr_factory_.GetWeakPtr(),
+ std::move(next_update_closure_)));
+}
+
+void PreviewsOptimizationGuide::GetOnePlatformClientHints() {
+ std::vector<std::string> top_hosts = previews_top_host_provider_->GetTopHosts(
+ previews::params::MaxOnePlatformUpdateHosts());
+ DCHECK_GE(previews::params::MaxOnePlatformUpdateHosts(), top_hosts.size());
+
+ LOCAL_HISTOGRAM_COUNTS_100("Previews.HintsFetcher.GetHintsRequest.HostCount",
+ top_hosts.size());
+
+ if (!hintsfetcher_) {
+ hintsfetcher_ = std::make_unique<HintsFetcher>(hint_cache_.get());
+ }
+
+ hintsfetcher_->FetchHintsForHosts(top_hosts);
+
+ // TODO(mcrouse) to build SimpleURLLoader to perform request from service
+ // for per-user client hints.
+ // Pass callback for when URLLoader request is successful to call
+ // PreviewOptimizationGuide::OnOnePlatformClientHintsReceived().
+
+ OnOnePlatformHintsReceived();
}
void PreviewsOptimizationGuide::UpdateHints(
+ base::OnceClosure update_closure,
std::unique_ptr<PreviewsHints> hints) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
hints_ = std::move(hints);
@@ -254,14 +298,19 @@ void PreviewsOptimizationGuide::UpdateHints(
hints_->Initialize(
hint_cache_.get(),
base::BindOnce(&PreviewsOptimizationGuide::OnHintsUpdated,
- ui_weak_ptr_factory_.GetWeakPtr()));
+ ui_weak_ptr_factory_.GetWeakPtr(),
+ std::move(update_closure)));
} else {
- OnHintsUpdated();
+ OnHintsUpdated(std::move(update_closure));
}
}
-void PreviewsOptimizationGuide::OnHintsUpdated() {
+void PreviewsOptimizationGuide::OnHintsUpdated(
+ base::OnceClosure update_closure) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
+ if (!update_closure.is_null())
+ std::move(update_closure).Run();
+
// Record the result of updating the hints. This is used as a signal for the
// hints being fully processed in testing.
LOCAL_HISTOGRAM_BOOLEAN(
@@ -269,4 +318,16 @@ void PreviewsOptimizationGuide::OnHintsUpdated() {
hints_ != NULL);
}
+void PreviewsOptimizationGuide::ListenForNextUpdateForTesting(
+ base::OnceClosure next_update_closure) {
+ DCHECK(next_update_closure_.is_null())
+ << "Only one update closure is supported at a time";
+ next_update_closure_ = std::move(next_update_closure);
+}
+
+void PreviewsOptimizationGuide::OnOnePlatformHintsReceived() {
+ // TODO(mcrouse): Once hints reseponse received from server, will need to
+ // update the cache and store.
+}
+
} // namespace previews
diff --git a/chromium/components/previews/content/previews_optimization_guide.h b/chromium/components/previews/content/previews_optimization_guide.h
index 6b300a9bb3f..22c68618794 100644
--- a/chromium/components/previews/content/previews_optimization_guide.h
+++ b/chromium/components/previews/content/previews_optimization_guide.h
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -32,7 +33,9 @@ class Hint;
namespace previews {
+class HintsFetcher;
class PreviewsHints;
+class PreviewsTopHostProvider;
class PreviewsUserData;
// A Previews optimization guide that makes decisions guided by hints received
@@ -41,10 +44,12 @@ class PreviewsOptimizationGuide
: public optimization_guide::OptimizationGuideServiceObserver {
public:
// The embedder guarantees |optimization_guide_service| outlives |this|.
+ // The embedder guarantees that |previews_top_host_provider_| outlives |this|.
PreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
- const base::FilePath& profile_path);
+ const base::FilePath& profile_path,
+ PreviewsTopHostProvider* previews_top_host_provider);
~PreviewsOptimizationGuide() override;
@@ -90,6 +95,10 @@ class PreviewsOptimizationGuide
PreviewsHints* GetHintsForTesting() { return hints_.get(); }
+ // |next_update_closure| is called the next time OnHintsComponentAvailable is
+ // called and the corresponding hints have been updated.
+ void ListenForNextUpdateForTesting(base::OnceClosure next_update_closure);
+
private:
// Callback run after the hint cache is fully initialized. At this point, the
// PreviewsOptimizationGuide is ready to process components from the
@@ -97,17 +106,29 @@ class PreviewsOptimizationGuide
void OnHintCacheInitialized();
// Updates the hints to the latest hints sent by the Component Updater.
- void UpdateHints(std::unique_ptr<PreviewsHints> hints);
+ // |update_closure| is called once the hints are updated.
+ void UpdateHints(base::OnceClosure update_closure,
+ std::unique_ptr<PreviewsHints> hints);
// Called when the hints have been fully updated with the latest hints from
// the Component Updater. This is used as a signal during tests.
- void OnHintsUpdated();
+ // |update_closure| is called immediately if not null.
+ void OnHintsUpdated(base::OnceClosure update_closure);
// Callback when a hint is loaded.
void OnLoadedHint(base::OnceClosure callback,
const GURL& document_url,
const optimization_guide::proto::Hint* loaded_hint) const;
+ // Method to request OnePlatform client hints for user's sites with top
+ // engagement scores and creates a remote request using |hints_fetcher_| On
+ // request success OnOnePlatformHintsReceived callback will be called.
+ void GetOnePlatformClientHints();
+
+ // Called when the response from the OnePlatform Guide Service is handled and
+ // stored by the |hints_fetcher_|. received.
+ void OnOnePlatformHintsReceived();
+
// The OptimizationGuideService that this guide is listening to. Not owned.
optimization_guide::OptimizationGuideService* optimization_guide_service_;
@@ -126,6 +147,16 @@ class PreviewsOptimizationGuide
// The current hints used for this optimization guide.
std::unique_ptr<PreviewsHints> hints_;
+ // Used in testing to subscribe to an update event in this class.
+ base::OnceClosure next_update_closure_;
+
+ // HintsFetcher handles the request to update Hints from OnePlatform Guide
+ // Service.
+ std::unique_ptr<HintsFetcher> hintsfetcher_;
+
+ // TopHostProvider that this guide can query. Not owned.
+ PreviewsTopHostProvider* previews_top_host_provider_ = nullptr;
+
// Used to get |weak_ptr_| to self on the UI thread.
base::WeakPtrFactory<PreviewsOptimizationGuide> ui_weak_ptr_factory_;
diff --git a/chromium/components/previews/content/previews_optimization_guide_unittest.cc b/chromium/components/previews/content/previews_optimization_guide_unittest.cc
index aca9b7cd247..9cff687444c 100644
--- a/chromium/components/previews/content/previews_optimization_guide_unittest.cc
+++ b/chromium/components/previews/content/previews_optimization_guide_unittest.cc
@@ -24,6 +24,7 @@
#include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
+#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_user_data.h"
#include "components/previews/core/bloom_filter.h"
#include "components/previews/core/previews_experiments.h"
@@ -66,6 +67,17 @@ class TestOptimizationGuideService
bool remove_observer_called_;
};
+// A test class implementation for unit testing previews_optimization_guide.
+class TestPreviewsTopHostProvider : public PreviewsTopHostProvider {
+ public:
+ TestPreviewsTopHostProvider() {}
+ ~TestPreviewsTopHostProvider() override {}
+
+ std::vector<std::string> GetTopHosts(size_t max_sites) const override {
+ return std::vector<std::string>();
+ }
+};
+
class PreviewsOptimizationGuideTest : public testing::Test {
public:
PreviewsOptimizationGuideTest() {}
@@ -105,7 +117,9 @@ class PreviewsOptimizationGuideTest : public testing::Test {
scoped_task_environment_.GetMainThreadTaskRunner());
guide_ = std::make_unique<PreviewsOptimizationGuide>(
optimization_guide_service_.get(),
- scoped_task_environment_.GetMainThreadTaskRunner(), temp_dir());
+ scoped_task_environment_.GetMainThreadTaskRunner(), temp_dir(),
+ previews_top_host_provider_.get());
+
// Add observer is called after the HintCache is fully initialized,
// indicating that the PreviewsOptimizationGuide is ready to process hints.
while (!optimization_guide_service_->AddObserverCalled()) {
@@ -177,6 +191,7 @@ class PreviewsOptimizationGuideTest : public testing::Test {
std::unique_ptr<PreviewsOptimizationGuide> guide_;
std::unique_ptr<TestOptimizationGuideService> optimization_guide_service_;
+ std::unique_ptr<TestPreviewsTopHostProvider> previews_top_host_provider_;
// Flag set when the OnLoadOptimizationHints callback runs. This indicates
// that MaybeLoadOptimizationHints() has completed its processing.
@@ -360,9 +375,12 @@ TEST_F(PreviewsOptimizationGuideTest, IsWhitelistedWithoutHints) {
TEST_F(PreviewsOptimizationGuideTest,
ProcessHintsForNoScriptPageHintsPopulatedCorrectly) {
- optimization_guide::proto::Configuration config;
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
// Configure somedomain.org with 2 page patterns, different ECT thresholds.
+ optimization_guide::proto::Configuration config;
optimization_guide::proto::Hint* hint1 = config.add_hints();
hint1->set_key("somedomain.org");
hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
@@ -421,6 +439,10 @@ TEST_F(PreviewsOptimizationGuideTest,
TEST_F(PreviewsOptimizationGuideTest,
ProcessHintsWithValidCommandLineOverride) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
+
optimization_guide::proto::Configuration config;
optimization_guide::proto::Hint* hint = config.add_hints();
hint->set_key("somedomain.org");
@@ -452,6 +474,10 @@ TEST_F(PreviewsOptimizationGuideTest,
TEST_F(PreviewsOptimizationGuideTest,
ProcessHintsWithValidCommandLineOverrideAndPreexistingData) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
+
InitializeFixedCountResourceLoadingHints();
EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
@@ -612,7 +638,8 @@ TEST_F(
PreviewsOptimizationGuideTest,
ProcessHintsWhitelistForNoScriptAndResourceLoadingHintsPopulatedCorrectly) {
base::test::ScopedFeatureList scoped_list;
- scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
// Add first hint.
optimization_guide::proto::Configuration config;
@@ -744,12 +771,12 @@ void PreviewsOptimizationGuideTest::DoExperimentFlagTest(
base::Optional<std::string> experiment_name,
bool expect_enabled) {
base::test::ScopedFeatureList scoped_list;
- scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);
-
- optimization_guide::proto::Configuration config;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
// Create a hint with two optimizations. One may be marked experimental
// depending on test configuration. The other is never marked experimental.
+ optimization_guide::proto::Configuration config;
optimization_guide::proto::Hint* hint1 = config.add_hints();
hint1->set_key("facebook.com");
hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
@@ -764,8 +791,6 @@ void PreviewsOptimizationGuideTest::DoExperimentFlagTest(
optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);
// RESOURCE_LOADING is not marked experimental.
- optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints();
- page_hint2->set_page_pattern("*");
optimization_guide::proto::Optimization* optimization2 =
page_hint1->add_whitelisted_optimizations();
optimization2->set_optimization_type(
@@ -798,9 +823,10 @@ void PreviewsOptimizationGuideTest::DoExperimentFlagTest(
// RESOURCE_LOADING_HINTS for facebook should always be enabled.
ect_threshold = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
- EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
- &user_data, GURL("https://m.facebook.com"),
- PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
+ EXPECT_EQ(!expect_enabled,
+ MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
+ &user_data, GURL("https://m.facebook.com"),
+ PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
// Twitter's NOSCRIPT should always be enabled; RESOURCE_LOADING_HINTS is not
// configured and should be disabled.
@@ -914,6 +940,9 @@ TEST_F(PreviewsOptimizationGuideTest,
}
TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithExistingSentinel) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
base::HistogramTester histogram_tester;
// Create valid config.
@@ -957,6 +986,9 @@ TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithExistingSentinel) {
}
TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithInvalidSentinelFile) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
base::HistogramTester histogram_tester;
// Create valid config.
@@ -1000,6 +1032,9 @@ TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithInvalidSentinelFile) {
}
TEST_F(PreviewsOptimizationGuideTest, SkipHintProcessingForSameConfigVersion) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
base::HistogramTester histogram_tester;
optimization_guide::proto::Configuration config1;
@@ -1054,6 +1089,9 @@ TEST_F(PreviewsOptimizationGuideTest, SkipHintProcessingForSameConfigVersion) {
TEST_F(PreviewsOptimizationGuideTest,
SkipHintProcessingForEarlierConfigVersion) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
base::HistogramTester histogram_tester;
optimization_guide::proto::Configuration config1;
@@ -1108,6 +1146,9 @@ TEST_F(PreviewsOptimizationGuideTest,
TEST_F(PreviewsOptimizationGuideTest, ProcessMultipleNewConfigs) {
base::HistogramTester histogram_tester;
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitWithFeatures(
+ {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
optimization_guide::proto::Configuration config1;
optimization_guide::proto::Hint* hint1 = config1.add_hints();
diff --git a/chromium/components/previews/content/previews_top_host_provider.h b/chromium/components/previews/content/previews_top_host_provider.h
new file mode 100644
index 00000000000..d4c20c0271e
--- /dev/null
+++ b/chromium/components/previews/content/previews_top_host_provider.h
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
+#define COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
+
+#include <string>
+#include <vector>
+
+namespace previews {
+
+// A class to handle querying for the top hosts for a user.
+class PreviewsTopHostProvider {
+ public:
+ // Returns a vector of at most |max_sites| top hosts, the order of hosts is
+ // not guaranteed.
+ virtual std::vector<std::string> GetTopHosts(size_t max_sites) const = 0;
+
+ protected:
+ PreviewsTopHostProvider() {}
+ virtual ~PreviewsTopHostProvider() {}
+};
+
+} // namespace previews
+
+#endif // COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
diff --git a/chromium/components/previews/content/previews_ui_service_unittest.cc b/chromium/components/previews/content/previews_ui_service_unittest.cc
index b2cb480e069..5c327e48852 100644
--- a/chromium/components/previews/content/previews_ui_service_unittest.cc
+++ b/chromium/components/previews/content/previews_ui_service_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/components/previews/content/proto/BUILD.gn b/chromium/components/previews/content/proto/BUILD.gn
index 8bc279bc72f..5a75c08ba7c 100644
--- a/chromium/components/previews/content/proto/BUILD.gn
+++ b/chromium/components/previews/content/proto/BUILD.gn
@@ -4,25 +4,11 @@
import("//third_party/protobuf/proto_library.gni")
-copy("hints_header_include") {
- sources = [
- "hints_header_include.h",
- ]
- outputs = [
- "$root_gen_dir" + "/components/previews/content/proto/hints.pb.h",
- ]
- deps = [
- "//components/optimization_guide/proto:optimization_guide_proto",
- ]
-}
-
proto_library("hint_cache_proto") {
import_dirs = [ "//components/optimization_guide/proto" ]
sources = [
"hint_cache.proto",
]
- deps = [
- ":hints_header_include",
- "//components/optimization_guide/proto:optimization_guide_proto",
- ]
+ link_deps =
+ [ "//components/optimization_guide/proto:optimization_guide_proto" ]
}
diff --git a/chromium/components/previews/content/proto/hints_header_include.h b/chromium/components/previews/content/proto/hints_header_include.h
deleted file mode 100644
index 3abb1368b2b..00000000000
--- a/chromium/components/previews/content/proto/hints_header_include.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_PREVIEWS_CONTENT_PROTO_HINTS_HEADER_INCLUDE_H_
-#define COMPONENTS_PREVIEWS_CONTENT_PROTO_HINTS_HEADER_INCLUDE_H_
-
-// This is a bridge to include the generated proto header for the
-// optimization_guide proto.
-#include "components/optimization_guide/proto/hints.pb.h"
-
-#endif // COMPONENTS_PREVIEWS_CONTENT_PROTO_HINTS_HEADER_INCLUDE_H_
diff --git a/chromium/components/previews/core/bloom_filter.h b/chromium/components/previews/core/bloom_filter.h
index cbf74b6504d..f820d87aff9 100644
--- a/chromium/components/previews/core/bloom_filter.h
+++ b/chromium/components/previews/core/bloom_filter.h
@@ -42,7 +42,7 @@ class BloomFilter {
void Add(const std::string& str);
// Returns the bit array data of this Bloom filter as vector of bytes.
- const ByteVector& bytes() const { return bytes_; };
+ const ByteVector& bytes() const { return bytes_; }
private:
// Number of bits to set for each added string.
diff --git a/chromium/components/previews/core/previews_black_list_unittest.cc b/chromium/components/previews/core/previews_black_list_unittest.cc
index 28265e4f67a..5db93c2a27f 100644
--- a/chromium/components/previews/core/previews_black_list_unittest.cc
+++ b/chromium/components/previews/core/previews_black_list_unittest.cc
@@ -123,32 +123,32 @@ class PreviewsBlackListTest : public testing::Test {
void SetHostThresholdParam(int per_host_threshold) {
params_["per_host_opt_out_threshold"] =
- base::IntToString(per_host_threshold);
+ base::NumberToString(per_host_threshold);
}
void SetHostIndifferentThresholdParam(int host_indifferent_threshold) {
params_["host_indifferent_opt_out_threshold"] =
- base::IntToString(host_indifferent_threshold);
+ base::NumberToString(host_indifferent_threshold);
}
void SetHostDurationParam(int duration_in_days) {
params_["per_host_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
+ base::NumberToString(duration_in_days);
}
void SetHostIndifferentDurationParam(int duration_in_days) {
params_["host_indifferent_black_list_duration_in_days"] =
- base::IntToString(duration_in_days);
+ base::NumberToString(duration_in_days);
}
void SetSingleOptOutDurationParam(int single_opt_out_duration) {
params_["single_opt_out_duration_in_seconds"] =
- base::IntToString(single_opt_out_duration);
+ base::NumberToString(single_opt_out_duration);
}
void SetMaxHostInBlackListParam(size_t max_hosts_in_blacklist) {
params_["max_hosts_in_blacklist"] =
- base::IntToString(max_hosts_in_blacklist);
+ base::NumberToString(max_hosts_in_blacklist);
}
protected:
diff --git a/chromium/components/previews/core/previews_experiments.cc b/chromium/components/previews/core/previews_experiments.cc
index b31b9bf479d..cc909ec269e 100644
--- a/chromium/components/previews/core/previews_experiments.cc
+++ b/chromium/components/previews/core/previews_experiments.cc
@@ -111,6 +111,11 @@ size_t MaxInMemoryHostsInBlackList() {
"max_hosts_in_blacklist", 100);
}
+size_t MaxOnePlatformUpdateHosts() {
+ return GetFieldTrialParamByFeatureAsInt(features::kPreviewsOnePlatformHints,
+ "max_oneplatform_update_hosts", 30);
+}
+
int PerHostBlackListOptOutThreshold() {
return GetParamValueAsInt(kClientSidePreviewsFieldTrial,
"per_host_opt_out_threshold", 2);
@@ -327,6 +332,10 @@ bool IsOptimizationHintsEnabled() {
return base::FeatureList::IsEnabled(features::kOptimizationHints);
}
+bool IsOnePlatformHintsEnabled() {
+ return base::FeatureList::IsEnabled(features::kPreviewsOnePlatformHints);
+}
+
int NoScriptPreviewsInflationPercent() {
// The default value was determined from lab experiment data of whitelisted
// URLs. It may be improved once there is enough UKM live experiment data
diff --git a/chromium/components/previews/core/previews_experiments.h b/chromium/components/previews/core/previews_experiments.h
index 406233b08ba..378e7abdcc4 100644
--- a/chromium/components/previews/core/previews_experiments.h
+++ b/chromium/components/previews/core/previews_experiments.h
@@ -68,6 +68,10 @@ size_t MaxStoredHistoryLengthForHostIndifferentBlackList();
// The maximum number of hosts allowed in the in memory black list.
size_t MaxInMemoryHostsInBlackList();
+// The maximum number of hosts requested by the client to the OnePlatform
+// Service.
+size_t MaxOnePlatformUpdateHosts();
+
// The number of recent navigations that were opted out of for a given host that
// would trigger that host to be blacklisted.
int PerHostBlackListOptOutThreshold();
@@ -167,6 +171,10 @@ size_t GetMaxPageHintsInMemoryThreshhold();
// Whether server optimization hints are enabled.
bool IsOptimizationHintsEnabled();
+// Returns true if the feature to fetch user-specific hints using
+// the OnePlatform API is enabled.
+bool IsOnePlatformHintsEnabled();
+
// For estimating NoScript data savings, this is the percentage factor to
// multiple by the network bytes for inflating the original_bytes count.
int NoScriptPreviewsInflationPercent();
diff --git a/chromium/components/previews/core/previews_features.cc b/chromium/components/previews/core/previews_features.cc
index f440cb1cbeb..4e8ce0ebfce 100644
--- a/chromium/components/previews/core/previews_features.cc
+++ b/chromium/components/previews/core/previews_features.cc
@@ -74,8 +74,14 @@ const base::Feature kOptimizationHintsExperiments{
"OptimizationHintsExperiments", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables the application of the resource loading hints when loading resources.
-const base::Feature kResourceLoadingHints{"ResourceLoadingHints",
- base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kResourceLoadingHints {
+ "ResourceLoadingHints",
+#if defined(OS_ANDROID)
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else // !defined(OS_ANDROID)
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif // defined(OS_ANDROID)
+};
// Enables client redirects to a server-rendered lite page preview.
const base::Feature kLitePageServerPreviews{"LitePageServerPreviews",
@@ -90,10 +96,6 @@ const base::Feature kAndroidOmniboxPreviewsBadge{
const base::Feature kSlowPageTriggering{"PreviewsSlowPageTriggering",
base::FEATURE_DISABLED_BY_DEFAULT};
-// A feature to prevent previews on all reloads.
-const base::Feature kPreviewsDisallowedOnReloads{
- "PreviewsDisallowedOnReloads", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Allows HTTPS previews to be served via a URLLoader when network service is
// enabled.
const base::Feature kHTTPSServerPreviewsUsingURLLoader{
@@ -108,5 +110,9 @@ const base::Feature kDataSaverLiteModeRebranding{
const base::Feature kPreviewsReloadsAreSoftOptOuts{
"PreviewsReloadsAreSoftOptOuts", base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables using the OnePlatform Client Hints requests.
+const base::Feature kPreviewsOnePlatformHints{
+ "PreviewsOnePlatformHints", 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
index 99a43ac5095..7da9ed7e022 100644
--- a/chromium/components/previews/core/previews_features.h
+++ b/chromium/components/previews/core/previews_features.h
@@ -22,10 +22,10 @@ extern const base::Feature kResourceLoadingHints;
extern const base::Feature kLitePageServerPreviews;
extern const base::Feature kAndroidOmniboxPreviewsBadge;
extern const base::Feature kSlowPageTriggering;
-extern const base::Feature kPreviewsDisallowedOnReloads;
extern const base::Feature kHTTPSServerPreviewsUsingURLLoader;
extern const base::Feature kDataSaverLiteModeRebranding;
extern const base::Feature kPreviewsReloadsAreSoftOptOuts;
+extern const base::Feature kPreviewsOnePlatformHints;
} // namespace features
} // namespace previews
diff --git a/chromium/components/previews/core/previews_logger_unittest.cc b/chromium/components/previews/core/previews_logger_unittest.cc
index 4e768548cd6..4fe3cfdff90 100644
--- a/chromium/components/previews/core/previews_logger_unittest.cc
+++ b/chromium/components/previews/core/previews_logger_unittest.cc
@@ -70,7 +70,7 @@ class TestPreviewsLoggerObserver : public PreviewsLoggerObserver {
// Expose the received MessageLogs for testing.
const std::vector<PreviewsLogger::MessageLog>& messages() const {
return messages_;
- };
+ }
// Expose blacklist events info for testing.
const std::unordered_map<std::string, base::Time>& blacklisted_hosts() {
diff --git a/chromium/components/print_media_strings.grdp b/chromium/components/print_media_strings.grdp
new file mode 100644
index 00000000000..7dd8e5debcd
--- /dev/null
+++ b/chromium/components/print_media_strings.grdp
@@ -0,0 +1,497 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <if expr="enable_print_preview">
+ <message name="PRINT_PREVIEW_MEDIA_ASME_F_28X40IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``E1''">
+ E1
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_2A0_1189X1682MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``2A0''">
+ 2A0
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A0_841X1189MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A0''">
+ A0
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A10_26X37MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A10''">
+ A10
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A1_594X841MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A1''">
+ A1
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A2_420X594MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A2''">
+ A2
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A3_297X420MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A3''">
+ A3
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A4_210X297MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A4''">
+ A4
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A4_EXTRA_235_5X322_3MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A4-Extra''">
+ A4-Extra
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A4_TAB_225X297MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A4-Tab''">
+ A4-Tab
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A5_148X210MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A5''">
+ A5
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A5_EXTRA_174X235MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A5-Extra''">
+ A5-Extra
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A6_105X148MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A6''">
+ A6
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A7_74X105MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A7''">
+ A7
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A8_52X74MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A8''">
+ A8
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_A9_37X52MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``A9''">
+ A9
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B0_1000X1414MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B0''">
+ B0
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B10_31X44MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B10''">
+ B10
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B1_707X1000MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B1''">
+ B1
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B2_500X707MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B2''">
+ B2
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B3_353X500MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B3''">
+ B3
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B4_250X353MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B4 (Envelope)''">
+ B4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B5_176X250MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B5 (Envelope)''">
+ B5 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B5_EXTRA_201X276MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B5-Extra''">
+ B5-Extra
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B6C4_125X324MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B6/C4 (Envelope)''">
+ B6/C4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B6_125X176MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B6 (Envelope)''">
+ B6 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B7_88X125MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B7''">
+ B7
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B8_62X88MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B8''">
+ B8
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_B9_44X62MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``B9''">
+ B9
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C0_917X1297MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C0 (Envelope)''">
+ C0 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C10_28X40MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C10 (Envelope)''">
+ C10 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C1_648X917MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C1 (Envelope)''">
+ C1 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C2_458X648MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C2 (Envelope)''">
+ C2 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C3_324X458MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C3 (Envelope)''">
+ C3 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C4_229X324MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C4 (Envelope)''">
+ C4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C5_162X229MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C5 (Envelope)''">
+ C5 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C6C5_114X229MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C6/C5 (Envelope)''">
+ C6/C5 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C6_114X162MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C6 (Envelope)''">
+ C6 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C7C6_81X162MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C7/C6 (Envelope)''">
+ C7/C6 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C7_81X114MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C7 (Envelope)''">
+ C7 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C8_57X81MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C8 (Envelope)''">
+ C8 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_C9_40X57MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``C9 (Envelope)''">
+ C9 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ISO_DL_110X220MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Designated-Long''">
+ Designated-Long
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JIS_EXEC_216X330MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Exec''">
+ Exec
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU2_111_1X146MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Chou2 (Envelope)''">
+ Chou2 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU3_120X235MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Chou3 (Envelope)''">
+ Chou3 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_CHOU4_90X205MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Chou4 (Envelope)''">
+ Chou4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_HAGAKI_100X148MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Hagaki (Postcard)''">
+ Hagaki (Postcard)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_KAHU_240X322_1MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Kahu (Envelope)''">
+ Kahu (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_KAKU2_240X332MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Kaku2 (Envelope)''">
+ Kaku2 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_OUFUKU_148X200MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Postcard)''">
+ Postcard)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_JPN_YOU4_105X235MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``You4 (Envelope)''">
+ You4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_10X11_10X11IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``10x11''">
+ 10x11
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_10X13_10X13IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``10x13 (Envelope)''">
+ 10x13 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_10X14_10X14IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``10x14 (Envelope)''">
+ 10x14 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_10X15_10X15IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``10x15 (Envelope)''">
+ 10x15 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_11X12_11X12IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``11x12''">
+ 11x12
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_11X15_11X15IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``11x15''">
+ 11x15
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_12X19_12X19IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``12x19''">
+ 12x19
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_5X7_5X7IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``5x7''">
+ 5x7
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_6X9_6X9IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``6x9 (Envelope)''">
+ 6x9 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_7X9_7X9IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``7x9 (Envelope)''">
+ 7x9 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_9X11_9X11IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``9x11 (Envelope)''">
+ 9x11 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_A2_4_375X5_75IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``A2 (Envelope)''">
+ A2 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_A_9X12IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Architecture-A (Envelope)''">
+ Architecture-A (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_B_12X18IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Architecture-B''">
+ Architecture-B
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_C_18X24IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Architecture-C''">
+ Architecture-C
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_D_24X36IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Architecture-D''">
+ Architecture-D
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_ARCH_E_36X48IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Architecture-E''">
+ Architecture-E
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_B_PLUS_12X19_17IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``B-Plus''">
+ B-Plus
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_C5_6_5X9_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``C5 (Envelope)''">
+ C5 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_C_17X22IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Engineering-C''">
+ Engineering-C
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_D_22X34IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Engineering-D''">
+ Engineering-D
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_EDP_11X14IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Edp''">
+ Edp
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_EUR_EDP_12X14IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``European-Edp''">
+ European-Edp
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_E_34X44IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Engineering-E''">
+ Engineering-E
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_FANFOLD_EUR_8_5X12IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Fanfold-European''">
+ Fanfold-European
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_FANFOLD_US_11X14_875IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Fanfold-Us''">
+ Fanfold-Us
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_FOOLSCAP_8_5X13IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Foolscap''">
+ Foolscap
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_F_44X68IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``F''">
+ F
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_GOVT_LEGAL_8X13IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Government-Legal''">
+ Government-Legal
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_GOVT_LETTER_8X10IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Government-Letter''">
+ Government-Letter
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_3X5_3X5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Index-3x5''">
+ Index-3x5
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_4X6IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Index-4x6 (Postcard)''">
+ Index-4x6 (Postcard)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_EXT_6X8IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Index-4x6-Ext''">
+ Index-4x6-Ext
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_INDEX_5X8_5X8IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Index-5x8''">
+ Index-5x8
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_INVOICE_5_5X8_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Statement''">
+ Statement
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LEDGER_11X17IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Ledger''">
+ Ledger
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LEGAL_8_5X14IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Legal''">
+ Legal
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LEGAL_EXTRA_9_5X15IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Legal-Extra''">
+ Legal-Extra
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_8_5X11IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Letter''">
+ Letter
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_EXTRA_9_5X12IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Letter-Extra''">
+ Letter-Extra
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_LETTER_PLUS_8_5X12_69IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Letter-Plus''">
+ Letter-Plus
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_10_4_125X9_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Comm-10 (Envelope)''">
+ Comm-10 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_11_4_5X10_375IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Number-11 (Envelope)''">
+ Number-11 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_12_4_75X11IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Number-12 (Envelope)''">
+ Number-12 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_NUMBER_14_5X11_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Number-14 (Envelope)''">
+ Number-14 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_PERSONAL_3_625X6_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Personal (Envelope)''">
+ Personal (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_SUPER_A_8_94X14IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Super-A''">
+ Super-A
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_SUPER_B_13X19IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Super-B''">
+ Super-B
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_NA_WIDE_FORMAT_30X42IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Wide-Format''">
+ Wide-Format
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_DAI_PA_KAI_275X395MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Dai-Pa-Kai''">
+ Dai-Pa-Kai
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_FOLIO_SP_215X315MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Folio-Sp''">
+ Folio-Sp
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_INVITE_220X220MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Invite (Envelope)''">
+ Invite (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_ITALIAN_110X230MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Italian (Envelope)''">
+ Italian (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_JUURO_KU_KAI_198X275MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Juuro-Ku-Kai''">
+ Juuro-Ku-Kai
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_LARGE_PHOTO_200X300"
+ desc="In Title Case: Media size shown to user in print preview for media ``Large-Photo''">
+ Large-Photo
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_PA_KAI_267X389MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Pa-Kai''">
+ Pa-Kai
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_POSTFIX_114X229MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Postfix (Envelope)''">
+ Postfix (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_OM_SMALL_PHOTO_100X150MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Small-Photo''">
+ Small-Photo
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_10_324X458MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc10 (Envelope)''">
+ Prc10 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_16K_146X215MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc-16K''">
+ Prc-16K
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_1_102X165MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc1 (Envelope)''">
+ Prc1 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_2_102X176MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc2 (Envelope)''">
+ Prc2 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_32K_97X151MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc-32K''">
+ Prc-32K
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_3_125X176MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc3 (Envelope)''">
+ Prc3 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_4_110X208MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc4 (Envelope)''">
+ Prc4 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_5_110X220MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc5 (Envelope)''">
+ Prc5 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_6_120X320MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc6 (Envelope)''">
+ Prc6 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_7_160X230MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc7 (Envelope)''">
+ Prc7 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_PRC_8_120X309MM"
+ desc="In Title Case: Media size shown to user in print preview for media ``Prc8 (Envelope)''">
+ Prc8 (Envelope)
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ROC_16K_7_75X10_75IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Roc-16K''">
+ Roc-16K
+ </message>
+ <message name="PRINT_PREVIEW_MEDIA_ROC_8K_10_75X15_5IN"
+ desc="In Title Case: Media size shown to user in print preview for media ``Roc-8K''">
+ Roc-8K
+ </message>
+ </if>
+</grit-part>
diff --git a/chromium/components/printing/browser/BUILD.gn b/chromium/components/printing/browser/BUILD.gn
index 9e4b076d9ec..f2298ec5470 100644
--- a/chromium/components/printing/browser/BUILD.gn
+++ b/chromium/components/printing/browser/BUILD.gn
@@ -2,6 +2,19 @@
# 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")
+
+declare_args() {
+ # For now, we only enable print media localization on Chrome OS.
+ enable_print_media_l10n = is_chromeos
+}
+
+buildflag_header("printing_buildflags") {
+ header = "printing_buildflags.h"
+
+ flags = [ "PRINT_MEDIA_L10N_ENABLED=$enable_print_media_l10n" ]
+}
+
static_library("browser") {
sources = [
"features.cc",
@@ -17,6 +30,7 @@ static_library("browser") {
]
public_deps = [
+ ":printing_buildflags",
"//content/public/browser",
]
@@ -39,6 +53,13 @@ static_library("browser") {
"printer_capabilities_mac.mm",
]
}
+
+ if (enable_print_media_l10n) {
+ sources += [
+ "print_media_l10n.cc",
+ "print_media_l10n.h",
+ ]
+ }
}
source_set("unit_tests") {
@@ -58,4 +79,8 @@ source_set("unit_tests") {
if (is_mac) {
sources += [ "printer_capabilities_mac_unittest.mm" ]
}
+
+ if (enable_print_media_l10n) {
+ sources += [ "print_media_l10n_unittest.cc" ]
+ }
}
diff --git a/chromium/components/printing/browser/print_media_l10n.cc b/chromium/components/printing/browser/print_media_l10n.cc
new file mode 100644
index 00000000000..ca19d2631a8
--- /dev/null
+++ b/chromium/components/printing/browser/print_media_l10n.cc
@@ -0,0 +1,206 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/printing/browser/print_media_l10n.h"
+
+#include <map>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace printing {
+
+namespace {
+
+// Return the resource ID of a media name specified by |vendor_id|
+// if any is found - else return -1. The static map contained here
+// is intended to reach all translated media names - see
+// print_media_resources.grd.
+int VendorIdToTranslatedId(const std::string& vendor_id) {
+ static const base::NoDestructor<std::map<std::string, int>> media_map({
+ {"asme_f_28x40in", PRINT_PREVIEW_MEDIA_ASME_F_28X40IN},
+ {"iso_2a0_1189x1682mm", PRINT_PREVIEW_MEDIA_ISO_2A0_1189X1682MM},
+ {"iso_a0_841x1189mm", PRINT_PREVIEW_MEDIA_ISO_A0_841X1189MM},
+ {"iso_a10_26x37mm", PRINT_PREVIEW_MEDIA_ISO_A10_26X37MM},
+ {"iso_a1_594x841mm", PRINT_PREVIEW_MEDIA_ISO_A1_594X841MM},
+ {"iso_a2_420x594mm", PRINT_PREVIEW_MEDIA_ISO_A2_420X594MM},
+ {"iso_a3_297x420mm", PRINT_PREVIEW_MEDIA_ISO_A3_297X420MM},
+ {"iso_a4-extra_235.5x322.3mm",
+ PRINT_PREVIEW_MEDIA_ISO_A4_EXTRA_235_5X322_3MM},
+ {"iso_a4-tab_225x297mm", PRINT_PREVIEW_MEDIA_ISO_A4_TAB_225X297MM},
+ {"iso_a4_210x297mm", PRINT_PREVIEW_MEDIA_ISO_A4_210X297MM},
+ {"iso_a5-extra_174x235mm", PRINT_PREVIEW_MEDIA_ISO_A5_EXTRA_174X235MM},
+ {"iso_a5_148x210mm", PRINT_PREVIEW_MEDIA_ISO_A5_148X210MM},
+ {"iso_a6_105x148mm", PRINT_PREVIEW_MEDIA_ISO_A6_105X148MM},
+ {"iso_a7_74x105mm", PRINT_PREVIEW_MEDIA_ISO_A7_74X105MM},
+ {"iso_a8_52x74mm", PRINT_PREVIEW_MEDIA_ISO_A8_52X74MM},
+ {"iso_a9_37x52mm", PRINT_PREVIEW_MEDIA_ISO_A9_37X52MM},
+ {"iso_b0_1000x1414mm", PRINT_PREVIEW_MEDIA_ISO_B0_1000X1414MM},
+ {"iso_b10_31x44mm", PRINT_PREVIEW_MEDIA_ISO_B10_31X44MM},
+ {"iso_b1_707x1000mm", PRINT_PREVIEW_MEDIA_ISO_B1_707X1000MM},
+ {"iso_b2_500x707mm", PRINT_PREVIEW_MEDIA_ISO_B2_500X707MM},
+ {"iso_b3_353x500mm", PRINT_PREVIEW_MEDIA_ISO_B3_353X500MM},
+ {"iso_b4_250x353mm", PRINT_PREVIEW_MEDIA_ISO_B4_250X353MM},
+ {"iso_b5-extra_201x276mm", PRINT_PREVIEW_MEDIA_ISO_B5_EXTRA_201X276MM},
+ {"iso_b5_176x250mm", PRINT_PREVIEW_MEDIA_ISO_B5_176X250MM},
+ {"iso_b6_125x176mm", PRINT_PREVIEW_MEDIA_ISO_B6_125X176MM},
+ {"iso_b6c4_125x324mm", PRINT_PREVIEW_MEDIA_ISO_B6C4_125X324MM},
+ {"iso_b7_88x125mm", PRINT_PREVIEW_MEDIA_ISO_B7_88X125MM},
+ {"iso_b8_62x88mm", PRINT_PREVIEW_MEDIA_ISO_B8_62X88MM},
+ {"iso_b9_44x62mm", PRINT_PREVIEW_MEDIA_ISO_B9_44X62MM},
+ {"iso_c0_917x1297mm", PRINT_PREVIEW_MEDIA_ISO_C0_917X1297MM},
+ {"iso_c10_28x40mm", PRINT_PREVIEW_MEDIA_ISO_C10_28X40MM},
+ {"iso_c1_648x917mm", PRINT_PREVIEW_MEDIA_ISO_C1_648X917MM},
+ {"iso_c2_458x648mm", PRINT_PREVIEW_MEDIA_ISO_C2_458X648MM},
+ {"iso_c3_324x458mm", PRINT_PREVIEW_MEDIA_ISO_C3_324X458MM},
+ {"iso_c4_229x324mm", PRINT_PREVIEW_MEDIA_ISO_C4_229X324MM},
+ {"iso_c5_162x229mm", PRINT_PREVIEW_MEDIA_ISO_C5_162X229MM},
+ {"iso_c6_114x162mm", PRINT_PREVIEW_MEDIA_ISO_C6_114X162MM},
+ {"iso_c6c5_114x229mm", PRINT_PREVIEW_MEDIA_ISO_C6C5_114X229MM},
+ {"iso_c7_81x114mm", PRINT_PREVIEW_MEDIA_ISO_C7_81X114MM},
+ {"iso_c7c6_81x162mm", PRINT_PREVIEW_MEDIA_ISO_C7C6_81X162MM},
+ {"iso_c8_57x81mm", PRINT_PREVIEW_MEDIA_ISO_C8_57X81MM},
+ {"iso_c9_40x57mm", PRINT_PREVIEW_MEDIA_ISO_C9_40X57MM},
+ {"iso_dl_110x220mm", PRINT_PREVIEW_MEDIA_ISO_DL_110X220MM},
+ {"jis_exec_216x330mm", PRINT_PREVIEW_MEDIA_JIS_EXEC_216X330MM},
+ {"jpn_chou2_111.1x146mm", PRINT_PREVIEW_MEDIA_JPN_CHOU2_111_1X146MM},
+ {"jpn_chou3_120x235mm", PRINT_PREVIEW_MEDIA_JPN_CHOU3_120X235MM},
+ {"jpn_chou4_90x205mm", PRINT_PREVIEW_MEDIA_JPN_CHOU4_90X205MM},
+ {"jpn_hagaki_100x148mm", PRINT_PREVIEW_MEDIA_JPN_HAGAKI_100X148MM},
+ {"jpn_kahu_240x322.1mm", PRINT_PREVIEW_MEDIA_JPN_KAHU_240X322_1MM},
+ {"jpn_kaku2_240x332mm", PRINT_PREVIEW_MEDIA_JPN_KAKU2_240X332MM},
+ {"jpn_oufuku_148x200mm", PRINT_PREVIEW_MEDIA_JPN_OUFUKU_148X200MM},
+ {"jpn_you4_105x235mm", PRINT_PREVIEW_MEDIA_JPN_YOU4_105X235MM},
+ {"na_10x11_10x11in", PRINT_PREVIEW_MEDIA_NA_10X11_10X11IN},
+ {"na_10x13_10x13in", PRINT_PREVIEW_MEDIA_NA_10X13_10X13IN},
+ {"na_10x14_10x14in", PRINT_PREVIEW_MEDIA_NA_10X14_10X14IN},
+ {"na_10x15_10x15in", PRINT_PREVIEW_MEDIA_NA_10X15_10X15IN},
+ {"na_11x12_11x12in", PRINT_PREVIEW_MEDIA_NA_11X12_11X12IN},
+ {"na_11x15_11x15in", PRINT_PREVIEW_MEDIA_NA_11X15_11X15IN},
+ {"na_12x19_12x19in", PRINT_PREVIEW_MEDIA_NA_12X19_12X19IN},
+ {"na_5x7_5x7in", PRINT_PREVIEW_MEDIA_NA_5X7_5X7IN},
+ {"na_6x9_6x9in", PRINT_PREVIEW_MEDIA_NA_6X9_6X9IN},
+ {"na_7x9_7x9in", PRINT_PREVIEW_MEDIA_NA_7X9_7X9IN},
+ {"na_9x11_9x11in", PRINT_PREVIEW_MEDIA_NA_9X11_9X11IN},
+ {"na_a2_4.375x5.75in", PRINT_PREVIEW_MEDIA_NA_A2_4_375X5_75IN},
+ {"na_arch-a_9x12in", PRINT_PREVIEW_MEDIA_NA_ARCH_A_9X12IN},
+ {"na_arch-b_12x18in", PRINT_PREVIEW_MEDIA_NA_ARCH_B_12X18IN},
+ {"na_arch-c_18x24in", PRINT_PREVIEW_MEDIA_NA_ARCH_C_18X24IN},
+ {"na_arch-d_24x36in", PRINT_PREVIEW_MEDIA_NA_ARCH_D_24X36IN},
+ {"na_arch-e_36x48in", PRINT_PREVIEW_MEDIA_NA_ARCH_E_36X48IN},
+ {"na_b-plus_12x19.17in", PRINT_PREVIEW_MEDIA_NA_B_PLUS_12X19_17IN},
+ {"na_c5_6.5x9.5in", PRINT_PREVIEW_MEDIA_NA_C5_6_5X9_5IN},
+ {"na_c_17x22in", PRINT_PREVIEW_MEDIA_NA_C_17X22IN},
+ {"na_d_22x34in", PRINT_PREVIEW_MEDIA_NA_D_22X34IN},
+ {"na_e_34x44in", PRINT_PREVIEW_MEDIA_NA_E_34X44IN},
+ {"na_edp_11x14in", PRINT_PREVIEW_MEDIA_NA_EDP_11X14IN},
+ {"na_eur-edp_12x14in", PRINT_PREVIEW_MEDIA_NA_EUR_EDP_12X14IN},
+ {"na_f_44x68in", PRINT_PREVIEW_MEDIA_NA_F_44X68IN},
+ {"na_fanfold-eur_8.5x12in", PRINT_PREVIEW_MEDIA_NA_FANFOLD_EUR_8_5X12IN},
+ {"na_fanfold-us_11x14.875in",
+ PRINT_PREVIEW_MEDIA_NA_FANFOLD_US_11X14_875IN},
+ {"na_foolscap_8.5x13in", PRINT_PREVIEW_MEDIA_NA_FOOLSCAP_8_5X13IN},
+ {"na_govt-legal_8x13in", PRINT_PREVIEW_MEDIA_NA_GOVT_LEGAL_8X13IN},
+ {"na_govt-letter_8x10in", PRINT_PREVIEW_MEDIA_NA_GOVT_LETTER_8X10IN},
+ {"na_index-3x5_3x5in", PRINT_PREVIEW_MEDIA_NA_INDEX_3X5_3X5IN},
+ {"na_index-4x6-ext_6x8in", PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_EXT_6X8IN},
+ {"na_index-4x6_4x6in", PRINT_PREVIEW_MEDIA_NA_INDEX_4X6_4X6IN},
+ {"na_index-5x8_5x8in", PRINT_PREVIEW_MEDIA_NA_INDEX_5X8_5X8IN},
+ {"na_invoice_5.5x8.5in", PRINT_PREVIEW_MEDIA_NA_INVOICE_5_5X8_5IN},
+ {"na_ledger_11x17in", PRINT_PREVIEW_MEDIA_NA_LEDGER_11X17IN},
+ {"na_legal-extra_9.5x15in", PRINT_PREVIEW_MEDIA_NA_LEGAL_EXTRA_9_5X15IN},
+ {"na_legal_8.5x14in", PRINT_PREVIEW_MEDIA_NA_LEGAL_8_5X14IN},
+ {"na_letter-extra_9.5x12in",
+ PRINT_PREVIEW_MEDIA_NA_LETTER_EXTRA_9_5X12IN},
+ {"na_letter-plus_8.5x12.69in",
+ PRINT_PREVIEW_MEDIA_NA_LETTER_PLUS_8_5X12_69IN},
+ {"na_letter_8.5x11in", PRINT_PREVIEW_MEDIA_NA_LETTER_8_5X11IN},
+ {"na_number-10_4.125x9.5in",
+ PRINT_PREVIEW_MEDIA_NA_NUMBER_10_4_125X9_5IN},
+ {"na_number-11_4.5x10.375in",
+ PRINT_PREVIEW_MEDIA_NA_NUMBER_11_4_5X10_375IN},
+ {"na_number-12_4.75x11in", PRINT_PREVIEW_MEDIA_NA_NUMBER_12_4_75X11IN},
+ {"na_number-14_5x11.5in", PRINT_PREVIEW_MEDIA_NA_NUMBER_14_5X11_5IN},
+ {"na_personal_3.625x6.5in", PRINT_PREVIEW_MEDIA_NA_PERSONAL_3_625X6_5IN},
+ {"na_super-a_8.94x14in", PRINT_PREVIEW_MEDIA_NA_SUPER_A_8_94X14IN},
+ {"na_super-b_13x19in", PRINT_PREVIEW_MEDIA_NA_SUPER_B_13X19IN},
+ {"na_wide-format_30x42in", PRINT_PREVIEW_MEDIA_NA_WIDE_FORMAT_30X42IN},
+ {"om_dai-pa-kai_275x395mm", PRINT_PREVIEW_MEDIA_OM_DAI_PA_KAI_275X395MM},
+ {"om_folio-sp_215x315mm", PRINT_PREVIEW_MEDIA_OM_FOLIO_SP_215X315MM},
+ {"om_invite_220x220mm", PRINT_PREVIEW_MEDIA_OM_INVITE_220X220MM},
+ {"om_italian_110x230mm", PRINT_PREVIEW_MEDIA_OM_ITALIAN_110X230MM},
+ {"om_juuro-ku-kai_198x275mm",
+ PRINT_PREVIEW_MEDIA_OM_JUURO_KU_KAI_198X275MM},
+ {"om_large-photo_200x300", PRINT_PREVIEW_MEDIA_OM_LARGE_PHOTO_200X300},
+ {"om_pa-kai_267x389mm", PRINT_PREVIEW_MEDIA_OM_PA_KAI_267X389MM},
+ {"om_postfix_114x229mm", PRINT_PREVIEW_MEDIA_OM_POSTFIX_114X229MM},
+ {"om_small-photo_100x150mm",
+ PRINT_PREVIEW_MEDIA_OM_SMALL_PHOTO_100X150MM},
+ {"prc_10_324x458mm", PRINT_PREVIEW_MEDIA_PRC_10_324X458MM},
+ {"prc_16k_146x215mm", PRINT_PREVIEW_MEDIA_PRC_16K_146X215MM},
+ {"prc_1_102x165mm", PRINT_PREVIEW_MEDIA_PRC_1_102X165MM},
+ {"prc_2_102x176mm", PRINT_PREVIEW_MEDIA_PRC_2_102X176MM},
+ {"prc_32k_97x151mm", PRINT_PREVIEW_MEDIA_PRC_32K_97X151MM},
+ {"prc_3_125x176mm", PRINT_PREVIEW_MEDIA_PRC_3_125X176MM},
+ {"prc_4_110x208mm", PRINT_PREVIEW_MEDIA_PRC_4_110X208MM},
+ {"prc_5_110x220mm", PRINT_PREVIEW_MEDIA_PRC_5_110X220MM},
+ {"prc_6_120x320mm", PRINT_PREVIEW_MEDIA_PRC_6_120X320MM},
+ {"prc_7_160x230mm", PRINT_PREVIEW_MEDIA_PRC_7_160X230MM},
+ {"prc_8_120x309mm", PRINT_PREVIEW_MEDIA_PRC_8_120X309MM},
+ {"roc_16k_7.75x10.75in", PRINT_PREVIEW_MEDIA_ROC_16K_7_75X10_75IN},
+ {"roc_8k_10.75x15.5in", PRINT_PREVIEW_MEDIA_ROC_8K_10_75X15_5IN},
+ });
+
+ auto it = media_map->find(vendor_id);
+ return it != media_map->end() ? it->second : -1;
+}
+
+std::string SplitMediaName(const base::StringPiece& vendor_id) {
+ // <name>_<width>x<height>{in,mm}
+ // e.g. na_letter_8.5x11in, iso_a4_210x297mm
+ std::vector<base::StringPiece> pieces = base::SplitStringPiece(
+ vendor_id, "_", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (pieces.size() < 2)
+ return std::string();
+
+ // Append all tokens split out of the vendor ID. The last token is
+ // usually the <width>x<height> token, so skip it.
+ pieces.pop_back();
+ return base::JoinString(pieces, " ");
+}
+
+} // namespace
+
+std::string LocalizePaperDisplayName(const std::string& vendor_id) {
+ std::string localized;
+ // We can't do anything without a vendor ID.
+ if (vendor_id.empty()) {
+ return localized;
+ }
+
+ int translation_id = VendorIdToTranslatedId(vendor_id);
+ // If we can't get a localized media name, we do our best to parse it
+ // on our own.
+ if (translation_id < 0) {
+ localized = SplitMediaName(base::StringPiece(vendor_id));
+ } else {
+ localized = l10n_util::GetStringUTF8(translation_id);
+ }
+
+ // If we still don't have a sane display name, fall back on showing
+ // the vendor ID.
+ if (localized.empty()) {
+ VLOG(1) << "No display name for " << vendor_id;
+ localized = vendor_id;
+ }
+ return localized;
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/browser/print_media_l10n.h b/chromium/components/printing/browser/print_media_l10n.h
new file mode 100644
index 00000000000..e012b990709
--- /dev/null
+++ b/chromium/components/printing/browser/print_media_l10n.h
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_
+#define COMPONENTS_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_
+
+#include <string>
+
+namespace printing {
+
+// Map a paper vendor ID to a localized name.
+std::string LocalizePaperDisplayName(const std::string& vendor_id);
+
+} // namespace printing
+
+#endif // COMPONENTS_PRINTING_BROWSER_PRINT_MEDIA_L10N_H_
diff --git a/chromium/components/printing/browser/print_media_l10n_unittest.cc b/chromium/components/printing/browser/print_media_l10n_unittest.cc
new file mode 100644
index 00000000000..226d365b818
--- /dev/null
+++ b/chromium/components/printing/browser/print_media_l10n_unittest.cc
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This test is only built and run on platforms allowing print media
+// localization.
+
+#include <string>
+#include <vector>
+
+#include "components/printing/browser/print_media_l10n.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace printing {
+
+// Verify that we localize some common names.
+TEST(PrintMediaL10N, LocalizeSomeCommonNames) {
+ const struct {
+ const char* vendor_id;
+ const char* expected_localized_name;
+ } kTestCases[] = {
+ {"na_c_17x22in", "Engineering-C"},
+ {"iso_a0_841x1189mm", "A0"},
+ {"iso_a1_594x841mm", "A1"},
+ {"iso_a4_210x297mm", "A4"},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ EXPECT_EQ(LocalizePaperDisplayName(test_case.vendor_id),
+ test_case.expected_localized_name);
+ }
+}
+
+// Verify that we attempt to split and prettify a vendor ID for which
+// we don't have a localization.
+TEST(PrintMediaL10N, DoWithoutCommonName) {
+ const struct {
+ const char* vendor_id;
+ const char* expected_localized_name;
+ } kTestCases[] = {
+ {"lorem_ipsum_8x10in", "lorem ipsum"},
+ {"q_e_d_130x200mm", "q e d"},
+ };
+
+ for (const auto& test_case : kTestCases) {
+ EXPECT_EQ(LocalizePaperDisplayName(test_case.vendor_id),
+ test_case.expected_localized_name);
+ }
+}
+
+// Verify that we return the vendor ID itself
+// 1. when we don't have a localization and
+// 2. when we don't see it split into at least 2 tokens (for name and
+// dimensions).
+TEST(PrintMediaL10N, FallbackToVendorId) {
+ const std::string no_dim = "I-BE-NAME-SANS-DIMENSIONS";
+ EXPECT_EQ(LocalizePaperDisplayName(no_dim), no_dim);
+}
+
+} // namespace printing
diff --git a/chromium/components/printing/browser/printer_capabilities.cc b/chromium/components/printing/browser/printer_capabilities.cc
index 382db0a3da6..833a0498582 100644
--- a/chromium/components/printing/browser/printer_capabilities.cc
+++ b/chromium/components/printing/browser/printer_capabilities.cc
@@ -15,7 +15,9 @@
#include "base/threading/scoped_blocking_call.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "build/buildflag.h"
#include "components/crash/core/common/crash_keys.h"
+#include "components/printing/browser/printing_buildflags.h"
#include "components/printing/common/cloud_print_cdd_conversion.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
@@ -28,19 +30,36 @@
#include "ui/base/l10n/l10n_util.h"
#endif
+#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
+#include "components/printing/browser/print_media_l10n.h"
+#endif
+
namespace printing {
const char kPrinter[] = "printer";
namespace {
+#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
+// Iterate on the Papers of a given printer |info| and set the
+// display_name members, localizing where possible.
+void PopulateAllPaperDisplayNames(PrinterSemanticCapsAndDefaults* info) {
+ info->default_paper.display_name =
+ LocalizePaperDisplayName(info->default_paper.vendor_id);
+ for (PrinterSemanticCapsAndDefaults::Paper& paper : info->papers) {
+ paper.display_name = LocalizePaperDisplayName(paper.vendor_id);
+ }
+}
+#endif // BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
+
// Returns a dictionary representing printer capabilities as CDD. Returns
// an empty dictionary if a dictionary could not be generated.
base::Value GetPrinterCapabilitiesOnBlockingPoolThread(
const std::string& device_name,
const PrinterSemanticCapsAndDefaults::Papers& additional_papers,
scoped_refptr<PrintBackend> print_backend) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
DCHECK(!device_name.empty());
scoped_refptr<PrintBackend> backend =
print_backend ? print_backend
@@ -61,6 +80,9 @@ base::Value GetPrinterCapabilitiesOnBlockingPoolThread(
return base::Value(base::Value::Type::DICTIONARY);
}
+#if BUILDFLAG(PRINT_MEDIA_L10N_ENABLED)
+ PopulateAllPaperDisplayNames(&info);
+#endif
info.papers.insert(info.papers.end(), additional_papers.begin(),
additional_papers.end());
return cloud_print::PrinterSemanticCapsAndDefaultsToCdd(info);
@@ -114,7 +136,8 @@ base::Value GetSettingsOnBlockingPool(
const PrinterBasicInfo& basic_info,
const PrinterSemanticCapsAndDefaults::Papers& additional_papers,
scoped_refptr<PrintBackend> print_backend) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
const auto printer_name_description =
GetPrinterNameAndDescription(basic_info);
diff --git a/chromium/components/printing/browser/printer_capabilities_mac.mm b/chromium/components/printing/browser/printer_capabilities_mac.mm
index 3d790c38d91..dfba8d3b817 100644
--- a/chromium/components/printing/browser/printer_capabilities_mac.mm
+++ b/chromium/components/printing/browser/printer_capabilities_mac.mm
@@ -42,7 +42,8 @@ PrinterSemanticCapsAndDefaults::Papers GetMacCustomPaperSizesFromFile(
base::scoped_nsobject<NSDictionary> custom_papers_dict;
{
- base::ScopedBlockingCall scoped_block(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_block(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
custom_papers_dict.reset([[NSDictionary alloc]
initWithContentsOfFile:base::mac::FilePathToNSString(path)]);
}
diff --git a/chromium/components/printing/common/cloud_print_cdd_conversion.cc b/chromium/components/printing/common/cloud_print_cdd_conversion.cc
index 6c43195d948..42593aab7b2 100644
--- a/chromium/components/printing/common/cloud_print_cdd_conversion.cc
+++ b/chromium/components/printing/common/cloud_print_cdd_conversion.cc
@@ -21,15 +21,15 @@ cloud_devices::printer::DuplexType ToCloudDuplexType(
printing::DuplexMode mode) {
switch (mode) {
case printing::SIMPLEX:
- return cloud_devices::printer::NO_DUPLEX;
+ return cloud_devices::printer::DuplexType::NO_DUPLEX;
case printing::LONG_EDGE:
- return cloud_devices::printer::LONG_EDGE;
+ return cloud_devices::printer::DuplexType::LONG_EDGE;
case printing::SHORT_EDGE:
- return cloud_devices::printer::SHORT_EDGE;
+ return cloud_devices::printer::DuplexType::SHORT_EDGE;
default:
NOTREACHED();
}
- return cloud_devices::printer::NO_DUPLEX;
+ return cloud_devices::printer::DuplexType::NO_DUPLEX;
}
} // namespace
@@ -65,13 +65,14 @@ base::Value PrinterSemanticCapsAndDefaultsToCdd(
ColorCapability color;
if (semantic_info.color_default || semantic_info.color_changeable) {
- Color standard_color(STANDARD_COLOR);
- standard_color.vendor_id = base::IntToString(semantic_info.color_model);
+ Color standard_color(ColorType::STANDARD_COLOR);
+ standard_color.vendor_id = base::NumberToString(semantic_info.color_model);
color.AddDefaultOption(standard_color, semantic_info.color_default);
}
if (!semantic_info.color_default || semantic_info.color_changeable) {
- Color standard_monochrome(STANDARD_MONOCHROME);
- standard_monochrome.vendor_id = base::IntToString(semantic_info.bw_model);
+ Color standard_monochrome(ColorType::STANDARD_MONOCHROME);
+ standard_monochrome.vendor_id =
+ base::NumberToString(semantic_info.bw_model);
color.AddDefaultOption(standard_monochrome, !semantic_info.color_default);
}
color.SaveTo(&description);
@@ -135,11 +136,17 @@ base::Value PrinterSemanticCapsAndDefaultsToCdd(
}
OrientationCapability orientation;
- orientation.AddDefaultOption(PORTRAIT, true);
- orientation.AddOption(LANDSCAPE);
- orientation.AddOption(AUTO_ORIENTATION);
+ orientation.AddDefaultOption(OrientationType::PORTRAIT, true);
+ orientation.AddOption(OrientationType::LANDSCAPE);
+ orientation.AddOption(OrientationType::AUTO_ORIENTATION);
orientation.SaveTo(&description);
+#if defined(OS_CHROMEOS)
+ PinCapability pin;
+ pin.set_value(semantic_info.pin_supported);
+ pin.SaveTo(&description);
+#endif // defined(OS_CHROMEOS)
+
return std::move(description).ToValue();
}
diff --git a/chromium/components/printing/renderer/BUILD.gn b/chromium/components/printing/renderer/BUILD.gn
index abdfe5fb6e9..a3e925a14c5 100644
--- a/chromium/components/printing/renderer/BUILD.gn
+++ b/chromium/components/printing/renderer/BUILD.gn
@@ -6,11 +6,17 @@ static_library("renderer") {
sources = [
"print_render_frame_helper.cc",
"print_render_frame_helper.h",
- "print_render_frame_helper_android.cc",
"print_render_frame_helper_linux.cc",
"print_render_frame_helper_mac.mm",
]
+ if (is_android) {
+ # Add back the Linux file which Android shares.
+ set_sources_assignment_filter([])
+ sources += [ "print_render_frame_helper_linux.cc" ]
+ set_sources_assignment_filter(sources_assignment_filter)
+ }
+
deps = [
"//base",
"//components/printing/common",
diff --git a/chromium/components/printing/renderer/print_render_frame_helper.cc b/chromium/components/printing/renderer/print_render_frame_helper.cc
index d51abda693d..40ea9d21b07 100644
--- a/chromium/components/printing/renderer/print_render_frame_helper.cc
+++ b/chromium/components/printing/renderer/print_render_frame_helper.cc
@@ -13,6 +13,7 @@
#include <utility>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/i18n/rtl.h"
#include "base/json/json_writer.h"
#include "base/location.h"
@@ -36,7 +37,6 @@
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "printing/buildflags/buildflags.h"
#include "printing/metafile_skia.h"
-#include "printing/metafile_skia_wrapper.h"
#include "printing/units.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
@@ -93,10 +93,10 @@ enum PrintPreviewHelperEvents {
PREVIEW_EVENT_MAX,
};
-const double kMinDpi = 1.0;
+constexpr double kMinDpi = 1.0;
// Also set in third_party/WebKit/Source/core/page/PrintContext.h
-const float kPrintingMinimumShrinkFactor = 1.33333333f;
+constexpr float kPrintingMinimumShrinkFactor = 1.33333333f;
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
bool g_is_preview_enabled = true;
@@ -134,9 +134,8 @@ int GetDPI(const PrintMsg_Print_Params* print_params) {
bool PrintMsg_Print_Params_IsValid(const PrintMsg_Print_Params& params) {
return !params.content_size.IsEmpty() && !params.page_size.IsEmpty() &&
!params.printable_area.IsEmpty() && params.document_cookie &&
- !params.dpi.IsEmpty() && params.dpi.width() > kMinDpi &&
- params.dpi.height() > kMinDpi && params.margin_top >= 0 &&
- params.margin_left >= 0 && params.document_cookie != 0;
+ params.dpi.width() > kMinDpi && params.dpi.height() > kMinDpi &&
+ params.margin_top >= 0 && params.margin_left >= 0;
}
// Helper function to check for fit to page
@@ -181,7 +180,7 @@ PrintMsg_Print_Params GetCssPrintParams(
// Invalid page size and/or margins. We just use the default setting.
if (new_content_width < 1 || new_content_height < 1) {
- CHECK(frame != nullptr);
+ CHECK(frame);
page_css_params = GetCssPrintParams(nullptr, page_index, page_params);
return page_css_params;
}
@@ -624,9 +623,9 @@ void FrameReference::Reset(blink::WebLocalFrame* frame) {
}
blink::WebLocalFrame* FrameReference::GetFrame() {
- if (view_ == nullptr || frame_ == nullptr)
+ if (!view_ || !frame_)
return nullptr;
- for (blink::WebFrame* frame = view_->MainFrame(); frame != nullptr;
+ for (blink::WebFrame* frame = view_->MainFrame(); frame;
frame = frame->TraverseNext()) {
if (frame == frame_)
return frame_;
@@ -1068,9 +1067,9 @@ bool PrintRenderFrameHelper::IsScriptInitiatedPrintAllowed(
scripting_throttler_.IsAllowed(frame);
}
-void PrintRenderFrameHelper::DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void PrintRenderFrameHelper::DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) {
is_loading_ = true;
}
@@ -1547,7 +1546,7 @@ void PrintRenderFrameHelper::OnPrintFrameContent(
metafile.GetVectorCanvasForNewPage(area_size, gfx::Rect(area_size), 1.0f);
DCHECK(canvas);
- MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, &metafile);
+ canvas->SetPrintingMetafile(&metafile);
// This subframe doesn't need to fit to the page size, thus we are not using
// printing layout for it. It just prints with the specified size.
@@ -2094,7 +2093,7 @@ void PrintRenderFrameHelper::PrintPageInternal(
if (!canvas)
return;
- MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
+ canvas->SetPrintingMetafile(metafile);
if (params.display_header_footer) {
#if defined(OS_WIN)
diff --git a/chromium/components/printing/renderer/print_render_frame_helper.h b/chromium/components/printing/renderer/print_render_frame_helper.h
index 34690801675..c4effb05d16 100644
--- a/chromium/components/printing/renderer/print_render_frame_helper.h
+++ b/chromium/components/printing/renderer/print_render_frame_helper.h
@@ -184,8 +184,9 @@ class PrintRenderFrameHelper
// RenderFrameObserver implementation.
void OnDestruct() override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) override;
void DidFailProvisionalLoad(const blink::WebURLError& error) override;
void DidFinishLoad() override;
void ScriptedPrint(bool user_initiated) override;
diff --git a/chromium/components/printing/renderer/print_render_frame_helper_android.cc b/chromium/components/printing/renderer/print_render_frame_helper_android.cc
deleted file mode 100644
index 93c43822921..00000000000
--- a/chromium/components/printing/renderer/print_render_frame_helper_android.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// All the necessary logic already lives in print_render_frame_helper_linux.cc.
-// We need a separate file for Android due to build/filename_rules.gypi rules.
-#include "components/printing/renderer/print_render_frame_helper_linux.cc"
diff --git a/chromium/components/printing/renderer/print_render_frame_helper_linux.cc b/chromium/components/printing/renderer/print_render_frame_helper_linux.cc
index 9317bf92e1b..e92009cfe95 100644
--- a/chromium/components/printing/renderer/print_render_frame_helper_linux.cc
+++ b/chromium/components/printing/renderer/print_render_frame_helper_linux.cc
@@ -12,7 +12,6 @@
#include "components/printing/common/print_messages.h"
#include "printing/buildflags/buildflags.h"
#include "printing/metafile_skia.h"
-#include "printing/metafile_skia_wrapper.h"
namespace printing {
diff --git a/chromium/components/printing/renderer/print_render_frame_helper_mac.mm b/chromium/components/printing/renderer/print_render_frame_helper_mac.mm
index 6357237e76f..4471e2c1bee 100644
--- a/chromium/components/printing/renderer/print_render_frame_helper_mac.mm
+++ b/chromium/components/printing/renderer/print_render_frame_helper_mac.mm
@@ -15,7 +15,6 @@
#include "components/printing/common/print_messages.h"
#include "printing/buildflags/buildflags.h"
#include "printing/metafile_skia.h"
-#include "printing/metafile_skia_wrapper.h"
#include "printing/page_size_margins.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -58,7 +57,7 @@ void PrintRenderFrameHelper::PrintPageInternal(
if (!canvas)
return;
- MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
+ canvas->SetPrintingMetafile(metafile);
if (params.display_header_footer) {
PrintHeaderAndFooter(canvas, page_number + 1, page_count, *frame,
final_scale_factor, page_layout_in_points, params);
diff --git a/chromium/components/proxy_config/pref_proxy_config_tracker_impl.cc b/chromium/components/proxy_config/pref_proxy_config_tracker_impl.cc
index 924105e82c8..82c2af0464c 100644
--- a/chromium/components/proxy_config/pref_proxy_config_tracker_impl.cc
+++ b/chromium/components/proxy_config/pref_proxy_config_tracker_impl.cc
@@ -236,17 +236,15 @@ PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig(
// static
void PrefProxyConfigTrackerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
- registry->RegisterDictionaryPref(
- proxy_config::prefs::kProxy,
- std::make_unique<base::Value>(ProxyConfigDictionary::CreateSystem()));
+ registry->RegisterDictionaryPref(proxy_config::prefs::kProxy,
+ ProxyConfigDictionary::CreateSystem());
}
// static
void PrefProxyConfigTrackerImpl::RegisterProfilePrefs(
PrefRegistrySimple* registry) {
- registry->RegisterDictionaryPref(
- proxy_config::prefs::kProxy,
- std::make_unique<base::Value>(ProxyConfigDictionary::CreateSystem()));
+ registry->RegisterDictionaryPref(proxy_config::prefs::kProxy,
+ ProxyConfigDictionary::CreateSystem());
registry->RegisterBooleanPref(proxy_config::prefs::kUseSharedProxies, false);
}
diff --git a/chromium/components/query_parser/query_parser.cc b/chromium/components/query_parser/query_parser.cc
index 0686489b3f8..5654c858845 100644
--- a/chromium/components/query_parser/query_parser.cc
+++ b/chromium/components/query_parser/query_parser.cc
@@ -72,7 +72,7 @@ class QueryNodeWord : public QueryNode {
const base::string16& word() const { return word_; }
- bool literal() const { return literal_; };
+ bool literal() const { return literal_; }
void set_literal(bool literal) { literal_ = literal; }
// QueryNode:
diff --git a/chromium/components/query_parser/snippet_unittest.cc b/chromium/components/query_parser/snippet_unittest.cc
index 0d0b6e61c91..a5ca15723c1 100644
--- a/chromium/components/query_parser/snippet_unittest.cc
+++ b/chromium/components/query_parser/snippet_unittest.cc
@@ -20,18 +20,20 @@ namespace {
// A sample document to compute snippets of.
// The \x bits after the first "Google" are UTF-8 of U+2122 TRADE MARK SIGN,
// and are useful for verifying we don't screw up in UTF-8/UTF-16 conversion.
-const char* kSampleDocument = "Google\xe2\x84\xa2 Terms of Service "
-"Welcome to Google! "
-"1. Your relationship with Google "
-"1.1 Your use of Google's products, software, services and web sites "
-"(referred to collectively as the \"Services\" in this document and excluding "
-"any services provided to you by Google under a separate written agreement) "
-"is subject to the terms of a legal agreement between you and Google. "
-"\"Google\" means Google Inc., whose principal place of business is at 1600 "
-"Amphitheatre Parkway, Mountain View, CA 94043, United States. This document "
-"explains how the agreement is made up, and sets out some of the terms of "
-"that agreement.";
-};
+const char kSampleDocument[] =
+ "Google\xe2\x84\xa2 Terms of Service "
+ "Welcome to Google! "
+ "1. Your relationship with Google "
+ "1.1 Your use of Google's products, software, services and web sites "
+ "(referred to collectively as the \"Services\" in this document and "
+ "excluding any services provided to you by Google under a separate "
+ " written agreement) is subject to the terms of a legal agreement "
+ "between you and Google. \"Google\" means Google Inc., whose principal "
+ "place of business is at 1600 Amphitheatre Parkway, Mountain View, "
+ "CA 94043, United States. This document explains how the agreement is "
+ "made up, and sets out some of the terms of that agreement.";
+
+} // namespace
// Thai sample taken from http://www.google.co.th/intl/th/privacy.html
// TODO(jungshik) : Add more samples (e.g. Hindi) after porting
diff --git a/chromium/components/quirks/quirks_client.cc b/chromium/components/quirks/quirks_client.cc
index e7d227c8380..c202a8eca8c 100644
--- a/chromium/components/quirks/quirks_client.cc
+++ b/chromium/components/quirks/quirks_client.cc
@@ -5,6 +5,7 @@
#include "components/quirks/quirks_client.h"
#include "base/base64.h"
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h"
@@ -188,7 +189,7 @@ void QuirksClient::Retry() {
bool QuirksClient::ParseResult(const std::string& result, std::string* data) {
std::string data64;
const base::DictionaryValue* dict;
- std::unique_ptr<base::Value> json = base::JSONReader::Read(result);
+ std::unique_ptr<base::Value> json = base::JSONReader::ReadDeprecated(result);
if (!json || !json->GetAsDictionary(&dict) ||
!dict->GetString("icc", &data64)) {
VLOG(1) << "Failed to parse JSON icc data";
diff --git a/chromium/components/quirks/quirks_manager.cc b/chromium/components/quirks/quirks_manager.cc
index f595dd91185..ff4c2c4c042 100644
--- a/chromium/components/quirks/quirks_manager.cc
+++ b/chromium/components/quirks/quirks_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
diff --git a/chromium/components/rappor/bloom_filter.h b/chromium/components/rappor/bloom_filter.h
index f2500289618..0245b73455e 100644
--- a/chromium/components/rappor/bloom_filter.h
+++ b/chromium/components/rappor/bloom_filter.h
@@ -30,7 +30,7 @@ class BloomFilter {
void SetString(const std::string& str);
// Returns the current value of the Bloom filter's bit array.
- const ByteVector& bytes() const { return bytes_; };
+ const ByteVector& bytes() const { return bytes_; }
private:
// Stores the byte array of the Bloom filter.
diff --git a/chromium/components/rappor/log_uploader.cc b/chromium/components/rappor/log_uploader.cc
index cf6b7e9bb1f..cee35a966d8 100644
--- a/chromium/components/rappor/log_uploader.cc
+++ b/chromium/components/rappor/log_uploader.cc
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
diff --git a/chromium/components/rappor/log_uploader_interface.h b/chromium/components/rappor/log_uploader_interface.h
index d3bbab54340..2b60137191d 100644
--- a/chromium/components/rappor/log_uploader_interface.h
+++ b/chromium/components/rappor/log_uploader_interface.h
@@ -9,8 +9,8 @@ namespace rappor {
class LogUploaderInterface {
public:
- LogUploaderInterface() {};
- virtual ~LogUploaderInterface() {};
+ LogUploaderInterface() {}
+ virtual ~LogUploaderInterface() {}
// Begin uploading logs.
virtual void Start() = 0;
diff --git a/chromium/components/rappor/log_uploader_unittest.cc b/chromium/components/rappor/log_uploader_unittest.cc
index 56c87cf9e1a..ab761a88c1b 100644
--- a/chromium/components/rappor/log_uploader_unittest.cc
+++ b/chromium/components/rappor/log_uploader_unittest.cc
@@ -12,7 +12,6 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -67,23 +66,19 @@ class LogUploaderTest : public testing::Test {
public:
LogUploaderTest()
: scoped_task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI),
- test_shared_loader_factory_(
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_)) {}
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
protected:
// Required for base::ThreadTaskRunnerHandle::Get().
base::test::ScopedTaskEnvironment scoped_task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
- scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
private:
DISALLOW_COPY_AND_ASSIGN(LogUploaderTest);
};
TEST_F(LogUploaderTest, Success) {
- TestLogUploader uploader(test_shared_loader_factory_);
+ TestLogUploader uploader(test_url_loader_factory_.GetSafeWeakWrapper());
test_url_loader_factory_.AddResponse(kTestServerURL, "");
uploader.QueueLog("log1");
@@ -93,7 +88,7 @@ TEST_F(LogUploaderTest, Success) {
}
TEST_F(LogUploaderTest, Rejection) {
- TestLogUploader uploader(test_shared_loader_factory_);
+ TestLogUploader uploader(test_url_loader_factory_.GetSafeWeakWrapper());
network::ResourceResponseHead response_head;
std::string headers("HTTP/1.1 400 Bad Request\nContent-type: text/html\n\n");
@@ -110,7 +105,7 @@ TEST_F(LogUploaderTest, Rejection) {
}
TEST_F(LogUploaderTest, Failure) {
- TestLogUploader uploader(test_shared_loader_factory_);
+ TestLogUploader uploader(test_url_loader_factory_.GetSafeWeakWrapper());
network::ResourceResponseHead response_head;
std::string headers(
diff --git a/chromium/components/rappor/test_rappor_service.cc b/chromium/components/rappor/test_rappor_service.cc
index a561f9985b1..0852efc2d1c 100644
--- a/chromium/components/rappor/test_rappor_service.cc
+++ b/chromium/components/rappor/test_rappor_service.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/rappor/byte_vector_utils.h"
diff --git a/chromium/components/reading_list/core/proto/BUILD.gn b/chromium/components/reading_list/core/proto/BUILD.gn
index 927a5eea83e..e6d9f535599 100644
--- a/chromium/components/reading_list/core/proto/BUILD.gn
+++ b/chromium/components/reading_list/core/proto/BUILD.gn
@@ -8,7 +8,4 @@ proto_library("proto") {
sources = [
"reading_list.proto",
]
- deps = [
- "//components/sync/protocol",
- ]
}
diff --git a/chromium/components/reading_list/core/reading_list_entry.cc b/chromium/components/reading_list/core/reading_list_entry.cc
index 281c2f46082..e346848a103 100644
--- a/chromium/components/reading_list/core/reading_list_entry.cc
+++ b/chromium/components/reading_list/core/reading_list_entry.cc
@@ -51,7 +51,7 @@ const net::BackoffEntry::Policy ReadingListEntry::kBackoffPolicy = {
ReadingListEntry::ReadingListEntry(const GURL& url,
const std::string& title,
const base::Time& now)
- : ReadingListEntry(url, title, now, nullptr){};
+ : ReadingListEntry(url, title, now, nullptr) {}
ReadingListEntry::ReadingListEntry(const GURL& url,
const std::string& title,
diff --git a/chromium/components/resources/security_interstitials_resources.grdp b/chromium/components/resources/security_interstitials_resources.grdp
index f63276794c0..d290349f370 100644
--- a/chromium/components/resources/security_interstitials_resources.grdp
+++ b/chromium/components/resources/security_interstitials_resources.grdp
@@ -8,5 +8,4 @@
<include name="IDR_SECURITY_INTERSTITIAL_CONNECTION_HELP_HTML" file="../security_interstitials/content/resources/connection_help.html" compress="gzip" type="BINDATA" />
<include name="IDR_SECURITY_INTERSTITIAL_CONNECTION_HELP_CSS" file="../security_interstitials/content/resources/connection_help.css" compress="gzip" type="BINDATA" />
<include name="IDR_SECURITY_INTERSTITIAL_CONNECTION_HELP_JS" file="../security_interstitials/content/resources/connection_help.js" compress="gzip" type="BINDATA" />
- <include name="IDR_SECURITY_INTERSTITIAL_ORIGIN_POLICY_HTML" compress="gzip" file="../security_interstitials/core/browser/resources/interstitial_origin_policy.html" type="BINDATA" />
</grit-part>
diff --git a/chromium/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiHandler.java b/chromium/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiHandler.java
index 3eb1b24514f..328863ba98c 100644
--- a/chromium/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiHandler.java
+++ b/chromium/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiHandler.java
@@ -26,12 +26,14 @@ public interface SafeBrowsingApiHandler {
}
// Possible values for resultStatus. Native side has the same definitions.
+ @IntDef({SafeBrowsingResult.INTERNAL_ERROR, SafeBrowsingResult.SUCCESS,
+ SafeBrowsingResult.TIMEOUT})
@Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_INTERNAL_ERROR, STATUS_SUCCESS, STATUS_TIMEOUT})
- @interface SafeBrowsingResult {}
- static final int STATUS_INTERNAL_ERROR = -1;
- static final int STATUS_SUCCESS = 0;
- static final int STATUS_TIMEOUT = 1;
+ @interface SafeBrowsingResult {
+ int INTERNAL_ERROR = -1;
+ int SUCCESS = 0;
+ int TIMEOUT = 1;
+ }
/**
* Verifies that SafeBrowsingApiHandler can operate and initializes if feasible.
diff --git a/chromium/components/safe_browsing/android/remote_database_manager.cc b/chromium/components/safe_browsing/android/remote_database_manager.cc
index 111dd428a7d..ca7fb5da795 100644
--- a/chromium/components/safe_browsing/android/remote_database_manager.cc
+++ b/chromium/components/safe_browsing/android/remote_database_manager.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -118,7 +119,7 @@ RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() {
if (ints_str.empty()) {
// By default, we check all types except a few.
static_assert(content::RESOURCE_TYPE_LAST_TYPE ==
- content::RESOURCE_TYPE_PLUGIN_RESOURCE + 1,
+ content::RESOURCE_TYPE_NAVIGATION_PRELOAD + 1,
"Decide if new resource type should be skipped on mobile.");
for (int t_int = 0; t_int < content::RESOURCE_TYPE_LAST_TYPE; t_int++) {
content::ResourceType t = static_cast<content::ResourceType>(t_int);
@@ -294,6 +295,11 @@ safe_browsing::ThreatSource RemoteSafeBrowsingDatabaseManager::GetThreatSource()
}
std::string RemoteSafeBrowsingDatabaseManager::GetSafetyNetId() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(IsSupported());
+ if (!enabled_)
+ return std::string();
+
SafeBrowsingApiHandler* api_handler = SafeBrowsingApiHandler::GetInstance();
DCHECK(api_handler) << "SafeBrowsingApiHandler was never constructed";
return api_handler->GetSafetyNetId();
diff --git a/chromium/components/safe_browsing/android/remote_database_manager_unittest.cc b/chromium/components/safe_browsing/android/remote_database_manager_unittest.cc
index 95857ded54f..b127a5d4030 100644
--- a/chromium/components/safe_browsing/android/remote_database_manager_unittest.cc
+++ b/chromium/components/safe_browsing/android/remote_database_manager_unittest.cc
@@ -23,7 +23,7 @@ namespace {
class TestSafeBrowsingApiHandler : public SafeBrowsingApiHandler {
public:
- std::string GetSafetyNetId() const override { return ""; }
+ std::string GetSafetyNetId() override { return ""; }
void StartURLCheck(std::unique_ptr<URLCheckCallbackMeta> callback,
const GURL& url,
const SBThreatTypeSet& threat_types) override {}
diff --git a/chromium/components/safe_browsing/android/safe_browsing_api_handler.h b/chromium/components/safe_browsing/android/safe_browsing_api_handler.h
index 04385c27b6b..c82a765f649 100644
--- a/chromium/components/safe_browsing/android/safe_browsing_api_handler.h
+++ b/chromium/components/safe_browsing/android/safe_browsing_api_handler.h
@@ -30,7 +30,7 @@ class SafeBrowsingApiHandler {
URLCheckCallbackMeta;
// Returns the Safety Net ID of the device.
- virtual std::string GetSafetyNetId() const = 0;
+ virtual std::string GetSafetyNetId() = 0;
// Makes Native->Java call and invokes callback when check is done.
virtual void StartURLCheck(std::unique_ptr<URLCheckCallbackMeta> callback,
const GURL& url,
diff --git a/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc b/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
index 40d85d39d7f..f6580534bac 100644
--- a/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
+++ b/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -10,6 +10,7 @@
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
+#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
@@ -223,17 +224,14 @@ bool SafeBrowsingApiHandlerBridge::CheckApiIsSupported() {
return j_api_handler_.obj() != nullptr;
}
-std::string SafeBrowsingApiHandlerBridge::GetSafetyNetId() const {
+std::string SafeBrowsingApiHandlerBridge::GetSafetyNetId() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool feature_enabled =
base::FeatureList::IsEnabled(kTelemetryForApkDownloads);
DCHECK(feature_enabled);
- if (!feature_enabled)
- return "";
-
static std::string safety_net_id;
- if (safety_net_id.empty()) {
+ if (feature_enabled && CheckApiIsSupported() && safety_net_id.empty()) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> jsafety_net_id =
Java_SafeBrowsingApiBridge_getSafetyNetId(env, j_api_handler_);
diff --git a/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.h b/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.h
index 99262aafe88..bc8da6f6fb4 100644
--- a/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.h
+++ b/chromium/components/safe_browsing/android/safe_browsing_api_handler_bridge.h
@@ -25,7 +25,7 @@ class SafeBrowsingApiHandlerBridge : public SafeBrowsingApiHandler {
SafeBrowsingApiHandlerBridge();
~SafeBrowsingApiHandlerBridge() override;
- std::string GetSafetyNetId() const override;
+ std::string GetSafetyNetId() override;
// Makes Native->Java call to check the URL against Safe Browsing lists.
void StartURLCheck(std::unique_ptr<URLCheckCallbackMeta> callback,
diff --git a/chromium/components/safe_browsing/android/safe_browsing_api_handler_util.cc b/chromium/components/safe_browsing/android/safe_browsing_api_handler_util.cc
index f7a2f12c306..944db05b2ec 100644
--- a/chromium/components/safe_browsing/android/safe_browsing_api_handler_util.cc
+++ b/chromium/components/safe_browsing/android/safe_browsing_api_handler_util.cc
@@ -207,7 +207,8 @@ UmaRemoteCallResult ParseJsonFromGMSCore(const std::string& metadata_str,
return UMA_STATUS_JSON_EMPTY;
// Pick out the "matches" list.
- std::unique_ptr<base::Value> value = base::JSONReader::Read(metadata_str);
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadDeprecated(metadata_str);
const base::ListValue* matches = nullptr;
if (!value.get() || !value->is_dict() ||
!(static_cast<base::DictionaryValue*>(value.get()))
diff --git a/chromium/components/safe_browsing/base_ui_manager.cc b/chromium/components/safe_browsing/base_ui_manager.cc
index 6c2d4f8f2f9..0da8eba3ed6 100644
--- a/chromium/components/safe_browsing/base_ui_manager.cc
+++ b/chromium/components/safe_browsing/base_ui_manager.cc
@@ -33,7 +33,7 @@ const void* const kWhitelistKey = &kWhitelistKey;
class WhitelistUrlSet : public base::SupportsUserData::Data {
public:
WhitelistUrlSet() {}
- bool Contains(const GURL url, SBThreatType* threat_type) {
+ bool Contains(const GURL& url, SBThreatType* threat_type) {
auto found = map_.find(url);
if (found == map_.end())
return false;
@@ -47,7 +47,7 @@ class WhitelistUrlSet : public base::SupportsUserData::Data {
pending_.erase(url);
}
void Remove(const GURL& url) { map_.erase(url); }
- void Insert(const GURL url, SBThreatType threat_type) {
+ void Insert(const GURL& url, SBThreatType threat_type) {
if (Contains(url, nullptr))
return;
map_[url] = threat_type;
@@ -61,7 +61,7 @@ class WhitelistUrlSet : public base::SupportsUserData::Data {
*threat_type = found->second.first;
return true;
}
- void InsertPending(const GURL url, SBThreatType threat_type) {
+ void InsertPending(const GURL& url, SBThreatType threat_type) {
if (pending_.find(url) != pending_.end()) {
pending_[url].first = threat_type;
pending_[url].second++;
diff --git a/chromium/components/safe_browsing/browser/BUILD.gn b/chromium/components/safe_browsing/browser/BUILD.gn
index 9b88876e5a9..7d3a7b2ae48 100644
--- a/chromium/components/safe_browsing/browser/BUILD.gn
+++ b/chromium/components/safe_browsing/browser/BUILD.gn
@@ -3,8 +3,9 @@
# found in the LICENSE file.
import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
-source_set("browser") {
+jumbo_source_set("browser") {
sources = [
"base_parallel_resource_throttle.cc",
"base_parallel_resource_throttle.h",
diff --git a/chromium/components/safe_browsing/browser/base_parallel_resource_throttle.cc b/chromium/components/safe_browsing/browser/base_parallel_resource_throttle.cc
index 5b74f3b9476..2f06d0cea81 100644
--- a/chromium/components/safe_browsing/browser/base_parallel_resource_throttle.cc
+++ b/chromium/components/safe_browsing/browser/base_parallel_resource_throttle.cc
@@ -79,7 +79,7 @@ BaseParallelResourceThrottle::BaseParallelResourceThrottle(
content::ResourceType resource_type,
scoped_refptr<UrlCheckerDelegate> url_checker_delegate)
: request_(request), resource_type_(resource_type) {
- const content::ResourceRequestInfo* info =
+ content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request_);
auto throttle = BrowserURLLoaderThrottle::MaybeCreate(
std::move(url_checker_delegate), info->GetWebContentsGetterForRequest());
@@ -118,7 +118,7 @@ void BaseParallelResourceThrottle::WillStartRequest(bool* defer) {
resource_request.load_flags = request_->load_flags();
resource_request.resource_type = resource_type_;
- const content::ResourceRequestInfo* info =
+ content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request_);
resource_request.has_user_gesture = info && info->HasUserGesture();
diff --git a/chromium/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc b/chromium/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc
index df742bcc58b..1cbb84f61e1 100644
--- a/chromium/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc
+++ b/chromium/components/safe_browsing/browser/base_parallel_resource_throttle_unittest.cc
@@ -178,7 +178,8 @@ class BaseParallelResourceThrottleTest : public testing::Test {
TRAFFIC_ANNOTATION_FOR_TESTS);
content::ResourceRequestInfo::AllocateForTesting(
request_.get(), content::RESOURCE_TYPE_MAIN_FRAME, nullptr, -1, -1, -1,
- true, true, true, content::PREVIEWS_OFF, nullptr);
+ true, content::ResourceInterceptPolicy::kAllowAll, true,
+ content::PREVIEWS_OFF, nullptr);
database_manager_ = new TestDatabaseManager();
url_checker_delegate_ = new TestUrlCheckerDelegate(database_manager_);
diff --git a/chromium/components/safe_browsing/browser/browser_url_loader_throttle.cc b/chromium/components/safe_browsing/browser/browser_url_loader_throttle.cc
index 75500c453e4..a90c39a578a 100644
--- a/chromium/components/safe_browsing/browser/browser_url_loader_throttle.cc
+++ b/chromium/components/safe_browsing/browser/browser_url_loader_throttle.cc
@@ -4,14 +4,13 @@
#include "components/safe_browsing/browser/browser_url_loader_throttle.h"
-#include "base/feature_list.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h"
#include "components/safe_browsing/browser/url_checker_delegate.h"
#include "components/safe_browsing/common/safebrowsing_constants.h"
#include "components/safe_browsing/common/utils.h"
-#include "components/safe_browsing/features.h"
#include "net/log/net_log_event_type.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
@@ -146,11 +145,8 @@ void BrowserURLLoaderThrottle::OnCompleteCheck(bool slow_check,
url_checker_.reset();
pending_checks_ = 0;
pending_slow_checks_ = 0;
- delegate_->CancelWithError(
- base::FeatureList::IsEnabled(kCommittedSBInterstitials)
- ? net::ERR_BLOCKED_BY_CLIENT
- : net::ERR_ABORTED,
- kCustomCancelReasonForURLLoader);
+ delegate_->CancelWithError(GetNetErrorCodeForSafeBrowsing(),
+ kCustomCancelReasonForURLLoader);
}
}
diff --git a/chromium/components/safe_browsing/browser/mojo_safe_browsing_impl.cc b/chromium/components/safe_browsing/browser/mojo_safe_browsing_impl.cc
index d8e0b323411..05c442d22fa 100644
--- a/chromium/components/safe_browsing/browser/mojo_safe_browsing_impl.cc
+++ b/chromium/components/safe_browsing/browser/mojo_safe_browsing_impl.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <vector>
+#include "base/bind.h"
#include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
diff --git a/chromium/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc b/chromium/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
index 36b2c058571..19c025b9825 100644
--- a/chromium/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
+++ b/chromium/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
@@ -4,11 +4,11 @@
#include "components/safe_browsing/browser/safe_browsing_url_checker_impl.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "components/safe_browsing/browser/url_checker_delegate.h"
-#include "components/safe_browsing/features.h"
#include "components/safe_browsing/web_ui/constants.h"
#include "components/security_interstitials/content/unsafe_resource.h"
#include "content/public/browser/browser_task_traits.h"
@@ -138,9 +138,7 @@ void SafeBrowsingUrlCheckerImpl::OnCheckBrowseUrlResult(
threat_type == SB_THREAT_TYPE_SAFE ? "safe" : "unsafe");
if (threat_type == SB_THREAT_TYPE_SAFE ||
- threat_type == SB_THREAT_TYPE_SUSPICIOUS_SITE ||
- (!base::FeatureList::IsEnabled(safe_browsing::kBillingInterstitial) &&
- threat_type == SB_THREAT_TYPE_BILLING)) {
+ threat_type == SB_THREAT_TYPE_SUSPICIOUS_SITE) {
state_ = STATE_NONE;
if (threat_type == SB_THREAT_TYPE_SUSPICIOUS_SITE) {
diff --git a/chromium/components/safe_browsing/browser/threat_details_cache.cc b/chromium/components/safe_browsing/browser/threat_details_cache.cc
index c8fca755997..8ad043b68da 100644
--- a/chromium/components/safe_browsing/browser/threat_details_cache.cc
+++ b/chromium/components/safe_browsing/browser/threat_details_cache.cc
@@ -17,7 +17,7 @@
#include "components/safe_browsing/browser/threat_details_cache.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
@@ -203,7 +203,7 @@ void ThreatDetailsCacheCollector::ReadResponse(
!current_load_->ResponseInfo()->proxy_server.is_direct();
if (!was_fetched_via_proxy) {
pb_response->set_remote_ip(
- current_load_->ResponseInfo()->socket_address.ToString());
+ current_load_->ResponseInfo()->remote_endpoint.ToString());
}
}
diff --git a/chromium/components/safe_browsing/common/BUILD.gn b/chromium/components/safe_browsing/common/BUILD.gn
index 74480a7e79d..b95721309fb 100644
--- a/chromium/components/safe_browsing/common/BUILD.gn
+++ b/chromium/components/safe_browsing/common/BUILD.gn
@@ -20,6 +20,7 @@ source_set("common") {
"//components/policy/core/browser:browser",
"//components/prefs:prefs",
"//components/safe_browsing:csd_proto",
+ "//components/safe_browsing:features",
"//crypto:crypto",
"//ipc",
"//url/ipc:url_ipc",
diff --git a/chromium/components/safe_browsing/common/safebrowsing_constants.cc b/chromium/components/safe_browsing/common/safebrowsing_constants.cc
index 0281893f133..b3d8400b44c 100644
--- a/chromium/components/safe_browsing/common/safebrowsing_constants.cc
+++ b/chromium/components/safe_browsing/common/safebrowsing_constants.cc
@@ -4,6 +4,9 @@
#include "components/safe_browsing/common/safebrowsing_constants.h"
+#include "components/safe_browsing/features.h"
+#include "net/base/net_errors.h"
+
namespace safe_browsing {
const base::FilePath::CharType kSafeBrowsingBaseFilename[] =
@@ -13,25 +16,15 @@ const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
const base::FilePath::CharType kChannelIDFile[] =
FILE_PATH_LITERAL(" Channel IDs");
-// The default URL prefix where browser fetches chunk updates, hashes,
-// and reports safe browsing hits and malware details.
-const char kSbDefaultURLPrefix[] =
- "https://safebrowsing.google.com/safebrowsing";
-
-// The backup URL prefix used when there are issues establishing a connection
-// with the server at the primary URL.
-const char kSbBackupConnectErrorURLPrefix[] =
- "https://alt1-safebrowsing.google.com/safebrowsing";
-
-// The backup URL prefix used when there are HTTP-specific issues with the
-// server at the primary URL.
-const char kSbBackupHttpErrorURLPrefix[] =
- "https://alt2-safebrowsing.google.com/safebrowsing";
-
-// The backup URL prefix used when there are local network specific issues.
-const char kSbBackupNetworkErrorURLPrefix[] =
- "https://alt3-safebrowsing.google.com/safebrowsing";
+// The URL for the Safe Browsing page.
+const char kSafeBrowsingUrl[] = "https://safebrowsing.google.com/";
const char kCustomCancelReasonForURLLoader[] = "SafeBrowsing";
+int GetNetErrorCodeForSafeBrowsing() {
+ return base::FeatureList::IsEnabled(safe_browsing::kCommittedSBInterstitials)
+ ? net::ERR_BLOCKED_BY_CLIENT
+ : net::ERR_ABORTED;
+}
+
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/common/safebrowsing_constants.h b/chromium/components/safe_browsing/common/safebrowsing_constants.h
index a339a81d466..8e64e7ca0de 100644
--- a/chromium/components/safe_browsing/common/safebrowsing_constants.h
+++ b/chromium/components/safe_browsing/common/safebrowsing_constants.h
@@ -15,26 +15,17 @@ extern const base::FilePath::CharType kSafeBrowsingBaseFilename[];
extern const base::FilePath::CharType kCookiesFile[];
extern const base::FilePath::CharType kChannelIDFile[];
-// The default URL prefix where browser fetches chunk updates, hashes,
-// and reports safe browsing hits and malware details.
-extern const char kSbDefaultURLPrefix[];
-
-// The backup URL prefix used when there are issues establishing a connection
-// with the server at the primary URL.
-extern const char kSbBackupConnectErrorURLPrefix[];
-
-// The backup URL prefix used when there are HTTP-specific issues with the
-// server at the primary URL.
-extern const char kSbBackupHttpErrorURLPrefix[];
-
-// The backup URL prefix used when there are local network specific issues.
-extern const char kSbBackupNetworkErrorURLPrefix[];
+// The URL for the Safe Browsing page.
+extern const char kSafeBrowsingUrl[];
// When a network::mojom::URLLoader is cancelled because of SafeBrowsing, this
// custom cancellation reason could be used to notify the implementation side.
// Please see network::mojom::URLLoader::kClientDisconnectReason for more
// details.
extern const char kCustomCancelReasonForURLLoader[];
+
+// Returns the error_code to use when Safe Browsing blocks a request.
+int GetNetErrorCodeForSafeBrowsing();
}
#endif // COMPONENTS_SAFE_BROWSING_COMMON_SAFEBROWSING_CONSTANTS_H_
diff --git a/chromium/components/safe_browsing/db/BUILD.gn b/chromium/components/safe_browsing/db/BUILD.gn
index 12485fbfbe0..acda1f22002 100644
--- a/chromium/components/safe_browsing/db/BUILD.gn
+++ b/chromium/components/safe_browsing/db/BUILD.gn
@@ -2,8 +2,8 @@
# 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")
import("//testing/libfuzzer/fuzzer_test.gni")
+import("//third_party/protobuf/proto_library.gni")
proto_library("safebrowsing_proto") {
sources = [
@@ -15,9 +15,7 @@ proto_library("v4_store_proto") {
sources = [
"v4_store.proto",
]
- deps = [
- ":safebrowsing_proto",
- ]
+ link_deps = [ ":safebrowsing_proto" ]
}
proto_library("metadata_proto") {
@@ -482,3 +480,15 @@ fuzzer_test("v4_get_hash_protocol_manager_fuzzer") {
":v4_get_hash_protocol_manager",
]
}
+
+fuzzer_test("v4_store_fuzzer") {
+ sources = [
+ "v4_store_fuzzer.cc",
+ ]
+ deps = [
+ ":v4_protocol_manager_util",
+ ":v4_store",
+ ":v4_test_util",
+ "//base/test:test_support",
+ ]
+}
diff --git a/chromium/components/safe_browsing/db/database_manager.cc b/chromium/components/safe_browsing/db/database_manager.cc
index e9ddc2ee0e3..966ea6c6529 100644
--- a/chromium/components/safe_browsing/db/database_manager.cc
+++ b/chromium/components/safe_browsing/db/database_manager.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "components/safe_browsing/db/v4_get_hash_protocol_manager.h"
diff --git a/chromium/components/safe_browsing/db/v4_database.cc b/chromium/components/safe_browsing/db/v4_database.cc
index eaa3839ced3..47a2071b998 100644
--- a/chromium/components/safe_browsing/db/v4_database.cc
+++ b/chromium/components/safe_browsing/db/v4_database.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
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 9b5fc517180..4fac2f2c1e6 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
@@ -7,6 +7,7 @@
#include <utility>
#include "base/base64url.h"
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
diff --git a/chromium/components/safe_browsing/db/v4_get_hash_protocol_manager_unittest.cc b/chromium/components/safe_browsing/db/v4_get_hash_protocol_manager_unittest.cc
index 46f0067c739..e8697a9ee7f 100644
--- a/chromium/components/safe_browsing/db/v4_get_hash_protocol_manager_unittest.cc
+++ b/chromium/components/safe_browsing/db/v4_get_hash_protocol_manager_unittest.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -38,7 +39,7 @@ struct KeyValue {
std::string value;
explicit KeyValue(const std::string key, const std::string value)
- : key(key), value(value){};
+ : key(key), value(value) {}
explicit KeyValue(const KeyValue& other) = default;
private:
@@ -51,11 +52,11 @@ struct ResponseInfo {
std::vector<KeyValue> key_values;
explicit ResponseInfo(FullHash full_hash, ListIdentifier list_id)
- : full_hash(full_hash), list_id(list_id){};
+ : full_hash(full_hash), list_id(list_id) {}
explicit ResponseInfo(const ResponseInfo& other)
: full_hash(other.full_hash),
list_id(other.list_id),
- key_values(other.key_values){};
+ key_values(other.key_values) {}
private:
ResponseInfo();
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 b87ae494d06..936689bf028 100644
--- a/chromium/components/safe_browsing/db/v4_local_database_manager.cc
+++ b/chromium/components/safe_browsing/db/v4_local_database_manager.cc
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_util.h"
@@ -644,8 +645,8 @@ void V4LocalDatabaseManager::GetSeverestThreatTypeAndMetadata(
StoresToCheck V4LocalDatabaseManager::GetStoresForFullHashRequests() {
StoresToCheck stores_for_full_hash;
- for (auto it : list_infos_) {
- stores_for_full_hash.insert(it.list_id());
+ for (const auto& info : list_infos_) {
+ stores_for_full_hash.insert(info.list_id());
}
return stores_for_full_hash;
}
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 f6a2f7a979c..cc8ec5cfcf8 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 <utility>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/components/safe_browsing/db/v4_rice.cc b/chromium/components/safe_browsing/db/v4_rice.cc
index 1a3f83f8185..547a40206f9 100644
--- a/chromium/components/safe_browsing/db/v4_rice.cc
+++ b/chromium/components/safe_browsing/db/v4_rice.cc
@@ -273,7 +273,7 @@ uint32_t V4RiceDecoder::GetBitsFromCurrentWord(
current_word_ = current_word_ >> num_requested_bits;
current_word_bit_index_ += num_requested_bits;
return x;
-};
+}
std::string V4RiceDecoder::DebugString() const {
// Calculates the total number of bits that we have read from the buffer,
diff --git a/chromium/components/safe_browsing/db/v4_store.cc b/chromium/components/safe_browsing/db/v4_store.cc
index b54b6805ec0..d7859a7672b 100644
--- a/chromium/components/safe_browsing/db/v4_store.cc
+++ b/chromium/components/safe_browsing/db/v4_store.cc
@@ -175,7 +175,7 @@ void RecordStoreWriteResult(StoreWriteResult result) {
}
// Returns the name of the temporary file used to buffer data for
-// |filename|. Exported for unit tests.
+// |filename|.
const base::FilePath TemporaryFileForFilename(const base::FilePath& filename) {
return base::FilePath(filename.value() + FILE_PATH_LITERAL("_new"));
}
@@ -351,8 +351,6 @@ ApplyUpdateResult V4Store::ProcessUpdate(
// Calculate the checksum asynchronously later and if it doesn't match,
// reset the store.
expected_checksum_ = expected_checksum;
-
- apply_update_result = APPLY_UPDATE_SUCCESS;
} else {
apply_update_result = MergeUpdate(hash_prefix_map_old, hash_prefix_map,
raw_removals, expected_checksum);
@@ -746,14 +744,14 @@ StoreWriteResult V4Store::WriteToDisk(const Checksum& checksum) {
*(lur->mutable_checksum()) = checksum;
lur->set_new_client_state(state_);
lur->set_response_type(ListUpdateResponse::FULL_UPDATE);
- for (auto map_iter : hash_prefix_map_) {
+ for (const auto& entry : hash_prefix_map_) {
ThreatEntrySet* additions = lur->add_additions();
// TODO(vakh): Write RICE encoded hash prefixes on disk. Not doing so
// currently since it takes a long time to decode them on startup, which
// blocks resource load. See: http://crbug.com/654819
additions->set_compression_type(RAW);
- additions->mutable_raw_hashes()->set_prefix_size(map_iter.first);
- additions->mutable_raw_hashes()->set_raw_hashes(map_iter.second);
+ additions->mutable_raw_hashes()->set_prefix_size(entry.first);
+ additions->mutable_raw_hashes()->set_raw_hashes(entry.second);
}
// Attempt writing to a temporary file first and at the end, swap the files.
@@ -767,10 +765,12 @@ StoreWriteResult V4Store::WriteToDisk(const Checksum& checksum) {
file_format_string.size());
if (file_format_string.size() != written) {
+ base::DeleteFile(new_filename, /*recursive=*/false);
return UNEXPECTED_BYTES_WRITTEN_FAILURE;
}
if (!base::Move(new_filename, store_path_)) {
+ base::DeleteFile(new_filename, /*recursive=*/false);
return UNABLE_TO_RENAME_FAILURE;
}
diff --git a/chromium/components/safe_browsing/db/v4_store.h b/chromium/components/safe_browsing/db/v4_store.h
index 3812af04d7c..466e8afcf37 100644
--- a/chromium/components/safe_browsing/db/v4_store.h
+++ b/chromium/components/safe_browsing/db/v4_store.h
@@ -296,6 +296,7 @@ class V4Store {
FRIEND_TEST_ALL_PREFIXES(V4StorePerftest, StressTest);
friend class V4StoreTest;
+ friend class V4StoreFuzzer;
// If |prefix_size| is within expected range, and |raw_hashes_length| is a
// multiple of prefix_size, then it sets the string of length
diff --git a/chromium/components/safe_browsing/db/v4_store_fuzzer.cc b/chromium/components/safe_browsing/db/v4_store_fuzzer.cc
new file mode 100644
index 00000000000..0f0c84b65b1
--- /dev/null
+++ b/chromium/components/safe_browsing/db/v4_store_fuzzer.cc
@@ -0,0 +1,132 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/test/test_simple_task_runner.h"
+#include "components/safe_browsing/db/v4_protocol_manager_util.h"
+#include "components/safe_browsing/db/v4_store.h"
+#include "components/safe_browsing/db/v4_test_util.h"
+
+namespace safe_browsing {
+
+const PrefixSize kMinHashPrefixLengthForFuzzing = kMinHashPrefixLength;
+const PrefixSize kMaxHashPrefixLengthForFuzzing = 8;
+
+class V4StoreFuzzer {
+ public:
+ static int FuzzMergeUpdate(const uint8_t* data, size_t size) {
+ // |prefix_map_old| represents the existing state of the |V4Store|.
+ HashPrefixMap prefix_map_old;
+ // |prefix_map_additions| represents the update being applied.
+ HashPrefixMap prefix_map_additions;
+
+ // Pass 1:
+ // Add a prefix_size->[prefixes] pair in |prefix_map_old|.
+ PopulateHashPrefixMap(&data, &size, &prefix_map_old);
+ // Add a prefix_size->[prefixes] pair in |prefix_map_additions|.
+ PopulateHashPrefixMap(&data, &size, &prefix_map_additions);
+
+ // Pass 2:
+ // Add a prefix_size->[prefixes] pair in |prefix_map_old|.
+ // If the prefix_size is the same as that added in |prefix_map_old| during
+ // Pass 1, the older list of prefixes is lost.
+ PopulateHashPrefixMap(&data, &size, &prefix_map_old);
+ // Add a prefix_size->[prefixes] pair in |prefix_map_additions|.
+ // If the prefix_size is the same as that added in |prefix_map_additions|
+ // during Pass 1, the older list of prefixes is lost.
+ PopulateHashPrefixMap(&data, &size, &prefix_map_additions);
+
+ auto store = std::make_unique<TestV4Store>(
+ base::MakeRefCounted<base::TestSimpleTaskRunner>(), base::FilePath());
+ // Assume no removals.
+ google::protobuf::RepeatedField<google::protobuf::int32> raw_removals;
+ // Empty checksum indicates that the checksum calculation should be skipped.
+ std::string empty_checksum;
+ store->MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals,
+ empty_checksum);
+#ifndef NDEBUG
+ DisplayHashPrefixMapDetails(store->hash_prefix_map_);
+#endif
+
+ return 0;
+ }
+
+ private:
+ // Add a prefix_size->[prefixes] pair in |hash_prefix_map|.
+ // Ensures that length of [prefixes] is a multiple of prefix_size.
+ // If the map already contains a pair with key prefix_size, the existing value
+ // is discarded.
+ // Here's a summary of how the input is parsed:
+ // * First uint8_t is the |prefix_size| to be added.
+ // * Next uint8_t is the length of the list of prefixes.
+ // * It is adjusted to be no greater than the remaining size of |data|.
+ // * It is adjusted to be a multiple of |prefix_size|.
+ // * It is called as |prefixes_list_size|.
+ // * Next |prefixes_list_size| bytes are added to |hash_prefix_map|
+ // as a list of prefixes of size |prefix_size|.
+ static void PopulateHashPrefixMap(const uint8_t** data,
+ size_t* size,
+ HashPrefixMap* hash_prefix_map) {
+ uint8_t datum;
+ if (!GetDatum(data, size, &datum))
+ return;
+
+ // Prefix size is defined to be between |kMinHashPrefixLength| and
+ // |kMaxHashPrefixLength| but we are going to limit them to smaller sizes so
+ // that we have a higher chance of actually populating the
+ // |hash_prefix_map| for smaller inputs.
+ PrefixSize prefix_size = kMinHashPrefixLengthForFuzzing +
+ (datum % (kMaxHashPrefixLengthForFuzzing -
+ kMinHashPrefixLengthForFuzzing + 1));
+
+ if (!GetDatum(data, size, &datum))
+ return;
+ // This |datum| tells us how long should the list of prefixes be.
+ // It can't be larger than the remaining buffer.
+ if (*size < datum) {
+ datum = *size;
+ }
+ // For the list of prefixes to be inserted into |hash_prefix_map|, its size
+ // needs to be a multiple of |prefix_size|. Otherwise
+ // |V4Store::AddUnlumpedHashes| would simply discard the input and it'll
+ // never reach |MergeUpdate|.
+ size_t prefixes_list_size = (datum / prefix_size) * prefix_size;
+ std::string prefixes(*data, *data + prefixes_list_size);
+ *size -= prefixes_list_size;
+ *data += prefixes_list_size;
+ V4Store::AddUnlumpedHashes(prefix_size, prefixes, hash_prefix_map);
+#ifndef NDEBUG
+ DisplayHashPrefixMapDetails(*hash_prefix_map);
+#endif
+ }
+
+ static bool GetDatum(const uint8_t** data, size_t* size, uint8_t* datum) {
+ if (*size == 0)
+ return false;
+ *datum = *data[0];
+ (*data)++;
+ (*size)--;
+ return true;
+ }
+
+ static void DisplayHashPrefixMapDetails(
+ const HashPrefixMap& hash_prefix_map) {
+ for (const auto& pair : hash_prefix_map) {
+ PrefixSize prefix_size = pair.first;
+ size_t prefixes_length = pair.second.length();
+ DVLOG(5) << __FUNCTION__ << " : " << prefix_size << " : "
+ << prefixes_length;
+ }
+ }
+};
+
+} // namespace safe_browsing
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return safe_browsing::V4StoreFuzzer::FuzzMergeUpdate(data, size);
+}
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 094430b1ee6..5067d1f7b45 100644
--- a/chromium/components/safe_browsing/db/v4_update_protocol_manager.cc
+++ b/chromium/components/safe_browsing/db/v4_update_protocol_manager.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/base64url.h"
+#include "base/bind.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
diff --git a/chromium/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc b/chromium/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc
index b0213c44e66..55c967e39fa 100644
--- a/chromium/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc
+++ b/chromium/components/safe_browsing/db/v4_update_protocol_manager_unittest.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/safe_browsing/features.cc b/chromium/components/safe_browsing/features.cc
index f00d697bedd..fc733ada3f9 100644
--- a/chromium/components/safe_browsing/features.cc
+++ b/chromium/components/safe_browsing/features.cc
@@ -22,11 +22,6 @@ namespace safe_browsing {
const base::Feature kAdSamplerTriggerFeature{"SafeBrowsingAdSamplerTrigger",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Controls the billing interstitial UI.
-// TODO(http://crbug.com/933807): remove this base::Feature after a full launch.
-const base::Feature kBillingInterstitial{"BillingInterstitial",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// If enabled in pre-network-service world, SafeBrowsing URL checks are done by
// applying SafeBrowsing's URLLoaderThrottle subclasses to ThrottlingURLLoader.
//
@@ -75,7 +70,6 @@ constexpr struct {
bool probabilistically_enabled;
} kExperimentalFeatures[]{
{&kAdSamplerTriggerFeature, false},
- {&kBillingInterstitial, true},
{&kCheckByURLLoaderThrottle, true},
{&kCommittedSBInterstitials, true},
{&kForceEnableResetPasswordWebUI, true},
diff --git a/chromium/components/safe_browsing/features.h b/chromium/components/safe_browsing/features.h
index 81a9b2a901c..840086071d9 100644
--- a/chromium/components/safe_browsing/features.h
+++ b/chromium/components/safe_browsing/features.h
@@ -21,9 +21,6 @@ namespace safe_browsing {
// Features list
extern const base::Feature kAdSamplerTriggerFeature;
-// Controls the billing interstitial UI.
-extern const base::Feature kBillingInterstitial;
-
extern const base::Feature kCheckByURLLoaderThrottle;
// Controls if safe browsing interstitials are implemented as committed
diff --git a/chromium/components/safe_browsing/password_protection/BUILD.gn b/chromium/components/safe_browsing/password_protection/BUILD.gn
index c9303ffc5e5..2fc42406e35 100644
--- a/chromium/components/safe_browsing/password_protection/BUILD.gn
+++ b/chromium/components/safe_browsing/password_protection/BUILD.gn
@@ -11,6 +11,8 @@ source_set("password_protection") {
"password_protection_request.h",
"password_protection_service.cc",
"password_protection_service.h",
+ "visual_utils.cc",
+ "visual_utils.h",
]
public_deps = [
@@ -60,6 +62,7 @@ source_set("password_protection_unittest") {
if (!is_android && !is_ios) {
sources = [
"password_protection_service_unittest.cc",
+ "visual_utils_unittest.cc",
]
deps = [
":mock_password_protection",
diff --git a/chromium/components/safe_browsing/password_protection/DEPS b/chromium/components/safe_browsing/password_protection/DEPS
index 9fb70becb51..8c7bb1ddabb 100644
--- a/chromium/components/safe_browsing/password_protection/DEPS
+++ b/chromium/components/safe_browsing/password_protection/DEPS
@@ -11,5 +11,6 @@ include_rules = [
"+services/network/public",
"+services/network/test",
"+ui/gfx/geometry",
+ "+third_party/skia/include",
]
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 4c170547615..7402f85b3a9 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_request.cc
+++ b/chromium/components/safe_browsing/password_protection/password_protection_request.cc
@@ -6,14 +6,19 @@
#include <memory>
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/password_manager/core/browser/password_reuse_detector.h"
#include "components/safe_browsing/db/whitelist_checker_client.h"
#include "components/safe_browsing/password_protection/password_protection_navigation_throttle.h"
+#include "components/safe_browsing/password_protection/visual_utils.h"
#include "components/safe_browsing/web_ui/safe_browsing_ui.h"
+#include "components/zoom/zoom_controller.h"
#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
@@ -34,6 +39,20 @@ namespace {
// the size of the report. UMA suggests 99.9% will have < 200 domains.
const int kMaxReusedDomains = 200;
+// Parameters chosen to ensure privacy is preserved by visual features.
+const int kMinWidthForVisualFeatures = 576;
+const int kMinHeightForVisualFeatures = 576;
+const float kMaxZoomForVisualFeatures = 2.0;
+
+std::unique_ptr<VisualFeatures> ExtractVisualFeatures(
+ const SkBitmap& screenshot) {
+ auto features = std::make_unique<VisualFeatures>();
+ visual_utils::GetHistogramForImage(screenshot,
+ features->mutable_color_histogram());
+ visual_utils::GetBlurredImage(screenshot, features->mutable_image());
+ return features;
+}
+
} // namespace
PasswordProtectionRequest::PasswordProtectionRequest(
@@ -138,7 +157,7 @@ void PasswordProtectionRequest::CheckCachedVerdicts() {
if (verdict != LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED)
Finish(RequestOutcome::RESPONSE_ALREADY_CACHED, std::move(cached_response));
else
- SendRequest();
+ FillRequestProto();
}
void PasswordProtectionRequest::FillRequestProto() {
@@ -211,11 +230,59 @@ void PasswordProtectionRequest::FillRequestProto() {
default:
NOTREACHED();
}
+
+ if (trigger_type_ == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE &&
+ password_protection_service_->IsExtendedReporting() &&
+ zoom::ZoomController::GetZoomLevelForWebContents(web_contents_) <=
+ kMaxZoomForVisualFeatures &&
+ request_proto_->content_area_width() >= kMinWidthForVisualFeatures &&
+ request_proto_->content_area_height() >= kMinHeightForVisualFeatures) {
+ CollectVisualFeatures();
+ } else {
+ SendRequest();
+ }
+}
+
+void PasswordProtectionRequest::CollectVisualFeatures() {
+ content::RenderWidgetHostView* view =
+ web_contents_ ? web_contents_->GetRenderWidgetHostView() : nullptr;
+
+ if (!view)
+ SendRequest();
+
+ visual_feature_start_time_ = base::TimeTicks::Now();
+
+ view->CopyFromSurface(
+ gfx::Rect(), gfx::Size(),
+ base::BindOnce(&PasswordProtectionRequest::OnScreenshotTaken,
+ GetWeakPtr()));
+}
+
+void PasswordProtectionRequest::OnScreenshotTaken(const SkBitmap& screenshot) {
+ // Do the feature extraction on a worker thread, to avoid blocking the UI.
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ base::BindOnce(&ExtractVisualFeatures, screenshot),
+ base::BindOnce(&PasswordProtectionRequest::OnVisualFeatureCollectionDone,
+ GetWeakPtr()));
+}
+
+void PasswordProtectionRequest::OnVisualFeatureCollectionDone(
+ std::unique_ptr<VisualFeatures> visual_features) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ request_proto_->mutable_visual_features()->Swap(visual_features.get());
+
+ UMA_HISTOGRAM_TIMES("PasswordProtection.VisualFeatureExtractionDuration",
+ base::TimeTicks::Now() - visual_feature_start_time_);
+
+ SendRequest();
}
void PasswordProtectionRequest::SendRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- FillRequestProto();
web_ui_token_ =
WebUIInfoSingleton::GetInstance()->AddToPGPings(*request_proto_);
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 db3faa828e5..ffed9df51e8 100644
--- a/chromium/components/safe_browsing/password_protection/password_protection_request.h
+++ b/chromium/components/safe_browsing/password_protection/password_protection_request.h
@@ -10,7 +10,9 @@
#include "base/task/cancelable_task_tracker.h"
#include "components/safe_browsing/password_protection/metrics_util.h"
#include "components/safe_browsing/password_protection/password_protection_service.h"
+#include "components/safe_browsing/proto/csd.pb.h"
#include "content/public/browser/browser_thread.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include <vector>
@@ -134,6 +136,16 @@ class PasswordProtectionRequest
// Fill |request_proto_| with appropriate values.
void FillRequestProto();
+ // Collects visual features from the current login page.
+ void CollectVisualFeatures();
+
+ // Processes the screenshot of the login page into visual features.
+ void OnScreenshotTaken(const SkBitmap& bitmap);
+
+ // Called when the visual feature extraction is complete.
+ void OnVisualFeatureCollectionDone(
+ std::unique_ptr<VisualFeatures> visual_features);
+
// Initiates network request to Safe Browsing backend.
void SendRequest();
@@ -200,6 +212,9 @@ class PasswordProtectionRequest
// If a request is sent, this is the token returned by the WebUI.
int web_ui_token_;
+ // When we start extracting visual features.
+ base::TimeTicks visual_feature_start_time_;
+
base::WeakPtrFactory<PasswordProtectionRequest> weakptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PasswordProtectionRequest);
};
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 9d540347f1b..29c60f102d0 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
@@ -20,6 +20,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
@@ -27,6 +28,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
+using testing::AnyNumber;
using testing::ElementsAre;
using testing::Return;
using PasswordReuseEvent =
@@ -104,7 +106,7 @@ class TestPasswordProtectionService : public MockPasswordProtectionService {
class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
public:
- PasswordProtectionServiceTest(){};
+ PasswordProtectionServiceTest() {}
LoginReputationClientResponse CreateVerdictProto(
LoginReputationClientResponse::VerdictType verdict,
@@ -263,6 +265,7 @@ class PasswordProtectionServiceTest : public ::testing::TestWithParam<bool> {
scoped_refptr<PasswordProtectionRequest> request_;
base::HistogramTester histograms_;
content::TestBrowserContext browser_context_;
+ content::RenderViewHostTestEnabler rvh_test_enabler_;
};
TEST_P(PasswordProtectionServiceTest, TestParseInvalidVerdictEntry) {
@@ -1333,11 +1336,35 @@ TEST_P(PasswordProtectionServiceTest, TestPingsForAboutBlank) {
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 1);
}
-INSTANTIATE_TEST_CASE_P(Regular,
- PasswordProtectionServiceTest,
- ::testing::Values(false));
-INSTANTIATE_TEST_CASE_P(SBER,
- PasswordProtectionServiceTest,
- ::testing::Values(true));
+TEST_P(PasswordProtectionServiceTest,
+ TestVisualFeaturesPopulatedInOnFocusPing) {
+ LoginReputationClientResponse expected_response =
+ CreateVerdictProto(LoginReputationClientResponse::PHISHING, 10 * kMinute,
+ GURL("about:blank").host());
+ test_url_loader_factory_.AddResponse(url_.spec(),
+ expected_response.SerializeAsString());
+ EXPECT_CALL(*password_protection_service_, GetCurrentContentAreaSize())
+ .Times(AnyNumber())
+ .WillOnce(Return(gfx::Size(1000, 1000)));
+ password_protection_service_->StartRequest(
+ GetWebContents(), GURL("about:blank"), GURL(), GURL(),
+ PasswordReuseEvent::SAVED_PASSWORD, {"example.com"},
+ LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
+ base::RunLoop().RunUntilIdle();
+
+ bool is_sber = GetParam();
+ if (is_sber) {
+ ASSERT_NE(nullptr, password_protection_service_->GetLatestRequestProto());
+ EXPECT_TRUE(password_protection_service_->GetLatestRequestProto()
+ ->has_visual_features());
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(Regular,
+ PasswordProtectionServiceTest,
+ ::testing::Values(false));
+INSTANTIATE_TEST_SUITE_P(SBER,
+ PasswordProtectionServiceTest,
+ ::testing::Values(true));
} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/password_protection/visual_utils.cc b/chromium/components/safe_browsing/password_protection/visual_utils.cc
new file mode 100644
index 00000000000..7ccde23cda9
--- /dev/null
+++ b/chromium/components/safe_browsing/password_protection/visual_utils.cc
@@ -0,0 +1,176 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unordered_map>
+#include <vector>
+
+#include "components/safe_browsing/password_protection/visual_utils.h"
+
+#include "base/logging.h"
+#include "base/numerics/checked_math.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkPixmap.h"
+
+namespace safe_browsing {
+namespace visual_utils {
+
+namespace {
+
+// WARNING: The following parameters are highly privacy and performance
+// sensitive. These should not be changed without thorough review.
+const int kPHashDownsampleWidth = 288;
+const int kPHashDownsampleHeight = 288;
+const int kPHashBlockSize = 6;
+
+} // namespace
+
+// A QuantizedColor takes the highest 3 bits of R, G, and B, and concatenates
+// them.
+QuantizedColor SkColorToQuantizedColor(SkColor color) {
+ return (SkColorGetR(color) >> 5) << 6 | (SkColorGetG(color) >> 5) << 3 |
+ (SkColorGetB(color) >> 5);
+}
+
+int GetQuantizedR(QuantizedColor color) {
+ return color >> 6;
+}
+
+int GetQuantizedG(QuantizedColor color) {
+ return (color >> 3) & 7;
+}
+
+int GetQuantizedB(QuantizedColor color) {
+ return color & 7;
+}
+
+bool GetHistogramForImage(const SkBitmap& image,
+ VisualFeatures::ColorHistogram* histogram) {
+ if (image.drawsNothing())
+ return false;
+
+ std::unordered_map<QuantizedColor, int> color_to_count;
+ std::unordered_map<QuantizedColor, double> color_to_total_x;
+ std::unordered_map<QuantizedColor, double> color_to_total_y;
+ for (int x = 0; x < image.width(); x++) {
+ for (int y = 0; y < image.height(); y++) {
+ QuantizedColor color = SkColorToQuantizedColor(image.getColor(x, y));
+ color_to_count[color]++;
+ color_to_total_x[color] += static_cast<float>(x) / image.width();
+ color_to_total_y[color] += static_cast<float>(y) / image.height();
+ }
+ }
+
+ int normalization_factor;
+ if (!base::CheckMul(image.width(), image.height())
+ .AssignIfValid(&normalization_factor))
+ return false;
+
+ for (const auto& entry : color_to_count) {
+ const QuantizedColor& color = entry.first;
+ int count = entry.second;
+
+ VisualFeatures::ColorHistogramBin* bin = histogram->add_bins();
+ bin->set_weight(static_cast<float>(count) / normalization_factor);
+ bin->set_centroid_x(color_to_total_x[color] / count);
+ bin->set_centroid_y(color_to_total_y[color] / count);
+ bin->set_quantized_r(GetQuantizedR(color));
+ bin->set_quantized_g(GetQuantizedG(color));
+ bin->set_quantized_b(GetQuantizedB(color));
+ }
+
+ return true;
+}
+
+bool GetBlurredImage(const SkBitmap& image,
+ VisualFeatures::BlurredImage* blurred_image) {
+ if (image.drawsNothing())
+ return false;
+
+ // Use the Rec. 2020 color space, in case the user input is wide-gamut.
+ sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB(
+ {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0},
+ SkNamedGamut::kRec2020);
+
+ // We scale down twice, once with medium quality, then with a block mean
+ // average to be consistent with the backend.
+ // TODO(drubery): Investigate whether this is necessary for performance or
+ // not.
+ SkImageInfo downsampled_info =
+ SkImageInfo::Make(kPHashDownsampleWidth, kPHashDownsampleHeight,
+ SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, rec2020);
+ SkBitmap downsampled;
+ if (!downsampled.tryAllocPixels(downsampled_info))
+ return false;
+ image.pixmap().scalePixels(downsampled.pixmap(),
+ SkFilterQuality::kMedium_SkFilterQuality);
+
+ std::unique_ptr<SkBitmap> blurred =
+ BlockMeanAverage(downsampled, kPHashBlockSize);
+
+ blurred_image->set_width(blurred->width());
+ blurred_image->set_height(blurred->height());
+ blurred_image->clear_data();
+
+ const uint32_t* rgba = blurred->getAddr32(0, 0);
+ for (int i = 0; i < blurred->width() * blurred->height(); i++) {
+ // Data is stored in BGR order.
+ *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 0) & 0xff);
+ *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 8) & 0xff);
+ *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 16) & 0xff);
+ }
+
+ return true;
+}
+
+std::unique_ptr<SkBitmap> BlockMeanAverage(const SkBitmap& image,
+ int block_size) {
+ // Compute the number of blocks in the target image, rounding up to account
+ // for partial blocks.
+ int num_blocks_high =
+ std::ceil(static_cast<float>(image.height()) / block_size);
+ int num_blocks_wide =
+ std::ceil(static_cast<float>(image.width()) / block_size);
+
+ SkImageInfo target_info = SkImageInfo::Make(
+ num_blocks_wide, num_blocks_high, SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, image.refColorSpace());
+ auto target = std::make_unique<SkBitmap>();
+ if (!target->tryAllocPixels(target_info))
+ return target;
+
+ for (int block_x = 0; block_x < num_blocks_wide; block_x++) {
+ for (int block_y = 0; block_y < num_blocks_high; block_y++) {
+ int r_total = 0, g_total = 0, b_total = 0, sample_count = 0;
+
+ // Compute boundary for the current block, taking into account the
+ // possibility of partial blocks near the edges.
+ int x_start = block_x * block_size;
+ int x_end = std::min(x_start + block_size, image.width());
+
+ int y_start = block_y * block_size;
+ int y_end = std::min(y_start + block_size, image.height());
+ for (int i = x_start; i < x_end; i++) {
+ for (int j = y_start; j < y_end; j++) {
+ r_total += SkColorGetR(image.getColor(i, j));
+ g_total += SkColorGetG(image.getColor(i, j));
+ b_total += SkColorGetB(image.getColor(i, j));
+ sample_count++;
+ }
+ }
+
+ int r_mean = r_total / sample_count;
+ int g_mean = g_total / sample_count;
+ int b_mean = b_total / sample_count;
+
+ *target->getAddr32(block_x, block_y) =
+ (255 << 24) | (b_mean << 16) | (g_mean << 8) | (r_mean << 0);
+ }
+ }
+
+ return target;
+}
+
+} // namespace visual_utils
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/password_protection/visual_utils.h b/chromium/components/safe_browsing/password_protection/visual_utils.h
new file mode 100644
index 00000000000..1026e65a6c3
--- /dev/null
+++ b/chromium/components/safe_browsing/password_protection/visual_utils.h
@@ -0,0 +1,45 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_VISUAL_UTILS_H_
+#define COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_VISUAL_UTILS_H_
+
+#include <string>
+
+#include "components/safe_browsing/proto/csd.pb.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace safe_browsing {
+namespace visual_utils {
+
+using QuantizedColor = uint32_t;
+
+// Utility methods for working with QuantizedColors.
+QuantizedColor SkColorToQuantizedColor(SkColor color);
+int GetQuantizedR(QuantizedColor color);
+int GetQuantizedG(QuantizedColor color);
+int GetQuantizedB(QuantizedColor color);
+
+// Computes the color histogram for the image. This buckets the pixels according
+// to their QuantizedColor, then reports their weight and centroid.
+bool GetHistogramForImage(const SkBitmap& image,
+ VisualFeatures::ColorHistogram* histogram);
+
+// Computes the BlurredImage for the given input image. This involves
+// downsampling the image to a certain fixed resolution, then blurring
+// by taking an average over fixed-size blocks of pixels.
+bool GetBlurredImage(const SkBitmap& image,
+ VisualFeatures::BlurredImage* blurred_image);
+
+// Downsizes an image by averaging all the pixels in the source image that
+// contribute to the target image. Groups pixels into squares of size
+// |block_size|, potentially with partial blocks at the edge. The output
+// image has pixels the average of the pixels in each block.
+std::unique_ptr<SkBitmap> BlockMeanAverage(const SkBitmap& image,
+ int block_size);
+
+} // namespace visual_utils
+} // namespace safe_browsing
+
+#endif // COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_VISUAL_UTILS_H_
diff --git a/chromium/components/safe_browsing/password_protection/visual_utils_unittest.cc b/chromium/components/safe_browsing/password_protection/visual_utils_unittest.cc
new file mode 100644
index 00000000000..97920ad328c
--- /dev/null
+++ b/chromium/components/safe_browsing/password_protection/visual_utils_unittest.cc
@@ -0,0 +1,256 @@
+// Copyright 2017 The Chromium 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/password_protection/visual_utils.h"
+
+#include "base/test/test_discardable_memory_allocator.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace safe_browsing {
+namespace visual_utils {
+
+namespace {
+
+// Pixel value constants, all in BGR order.
+const unsigned int kWhite = 0xffffffff;
+const unsigned int kBlack = 0xff000000;
+const unsigned int kRed = 0xff0000ff;
+const unsigned int kGreen = 0xff00ff00;
+const unsigned int kBlue = 0xffff0000;
+
+} // namespace
+
+using ::testing::FloatEq;
+
+class VisualUtilsTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ base::DiscardableMemoryAllocator::SetInstance(&test_allocator_);
+
+ sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB(
+ {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0},
+ SkNamedGamut::kRec2020);
+ SkImageInfo bitmap_info =
+ SkImageInfo::Make(1000, 1000, SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, rec2020);
+
+ ASSERT_TRUE(bitmap_.tryAllocPixels(bitmap_info));
+ }
+
+ void TearDown() override {
+ base::DiscardableMemoryAllocator::SetInstance(nullptr);
+ }
+
+ // A test bitmap to work with. Initialized to be 1000x1000 in the Rec 2020
+ // color space.
+ SkBitmap bitmap_;
+
+ private:
+ // A DiscardableMemoryAllocator is needed for certain Skia operations.
+ base::TestDiscardableMemoryAllocator test_allocator_;
+};
+
+TEST_F(VisualUtilsTest, TestSkColorToQuantizedColor) {
+ // Test quantization
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 31)), 0u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 32)), 1u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 31, 0)), 0u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 32, 0)), 8u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(31, 0, 0)), 0u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(32, 0, 0)), 64u);
+
+ // Test composition of RGB quantized values
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 0)), 0u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 255)), 7u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 255, 255)), 63u);
+ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(255, 255, 255)), 511u);
+}
+
+TEST_F(VisualUtilsTest, GetQuantizedR) {
+ EXPECT_EQ(GetQuantizedR(0), 0);
+ EXPECT_EQ(GetQuantizedR(64), 1);
+ EXPECT_EQ(GetQuantizedR(448), 7);
+}
+
+TEST_F(VisualUtilsTest, GetQuantizedG) {
+ EXPECT_EQ(GetQuantizedG(0), 0);
+ EXPECT_EQ(GetQuantizedG(8), 1);
+ EXPECT_EQ(GetQuantizedG(56), 7);
+}
+
+TEST_F(VisualUtilsTest, GetQuantizedB) {
+ EXPECT_EQ(GetQuantizedB(0), 0);
+ EXPECT_EQ(GetQuantizedB(1), 1);
+ EXPECT_EQ(GetQuantizedB(7), 7);
+}
+
+TEST_F(VisualUtilsTest, GetHistogramForImageWhite) {
+ VisualFeatures::ColorHistogram histogram;
+ SkBitmap bitmap;
+
+ // Draw white over half the image
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ ASSERT_TRUE(GetHistogramForImage(bitmap_, &histogram));
+ ASSERT_EQ(histogram.bins_size(), 1);
+ EXPECT_THAT(histogram.bins(0).centroid_x(),
+ FloatEq(0.4995)); // All pixels are the same color, so centroid_x
+ // is (0+1+...+999)/1000/1000 = 0.4995
+ EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.4995));
+ EXPECT_EQ(histogram.bins(0).quantized_r(), 7);
+ EXPECT_EQ(histogram.bins(0).quantized_g(), 7);
+ EXPECT_EQ(histogram.bins(0).quantized_b(), 7);
+ EXPECT_THAT(histogram.bins(0).weight(), FloatEq(1.0));
+}
+
+TEST_F(VisualUtilsTest, GetHistogramForImageHalfWhiteHalfBlack) {
+ VisualFeatures::ColorHistogram histogram;
+
+ // Draw white over half the image
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 500; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ // Draw black over half the image.
+ for (int x = 0; x < 1000; x++)
+ for (int y = 500; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kBlack;
+
+ ASSERT_TRUE(GetHistogramForImage(bitmap_, &histogram));
+ ASSERT_EQ(histogram.bins_size(), 2);
+
+ EXPECT_THAT(histogram.bins(0).centroid_x(), FloatEq(0.4995));
+ EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.7495));
+ EXPECT_EQ(histogram.bins(0).quantized_r(), 0);
+ EXPECT_EQ(histogram.bins(0).quantized_g(), 0);
+ EXPECT_EQ(histogram.bins(0).quantized_b(), 0);
+ EXPECT_THAT(histogram.bins(0).weight(), FloatEq(0.5));
+
+ EXPECT_THAT(histogram.bins(1).centroid_x(), FloatEq(0.4995));
+ EXPECT_THAT(histogram.bins(1).centroid_y(), FloatEq(0.2495));
+ EXPECT_EQ(histogram.bins(1).quantized_r(), 7);
+ EXPECT_EQ(histogram.bins(1).quantized_g(), 7);
+ EXPECT_EQ(histogram.bins(1).quantized_b(), 7);
+ EXPECT_THAT(histogram.bins(1).weight(), FloatEq(0.5));
+}
+
+TEST_F(VisualUtilsTest, BlurImageWhite) {
+ VisualFeatures::BlurredImage blurred;
+
+ // Draw white over the image
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred));
+ ASSERT_EQ(48, blurred.width());
+ ASSERT_EQ(48, blurred.height());
+ ASSERT_EQ(3u * 48u * 48u, blurred.data().size());
+ for (size_t i = 0; i < 48u * 48u; i++) {
+ EXPECT_EQ('\xff', blurred.data()[3 * i]);
+ EXPECT_EQ('\xff', blurred.data()[3 * i + 1]);
+ EXPECT_EQ('\xff', blurred.data()[3 * i + 2]);
+ }
+}
+
+TEST_F(VisualUtilsTest, BlurImageRed) {
+ VisualFeatures::BlurredImage blurred;
+
+ // Draw red over the image.
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kRed;
+
+ ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred));
+ ASSERT_EQ(48, blurred.width());
+ ASSERT_EQ(48, blurred.height());
+ ASSERT_EQ(3u * 48u * 48u, blurred.data().size());
+ for (size_t i = 0; i < 48u * 48u; i++) {
+ EXPECT_EQ('\xff', blurred.data()[3 * i]);
+ EXPECT_EQ('\x00', blurred.data()[3 * i + 1]);
+ EXPECT_EQ('\x00', blurred.data()[3 * i + 2]);
+ }
+}
+
+TEST_F(VisualUtilsTest, BlurImageHalfWhiteHalfBlack) {
+ VisualFeatures::BlurredImage blurred;
+
+ // Draw black over half the image.
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 500; y++)
+ *bitmap_.getAddr32(x, y) = kBlack;
+
+ // Draw white over half the image
+ for (int x = 0; x < 1000; x++)
+ for (int y = 500; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred));
+ ASSERT_EQ(48, blurred.width());
+ ASSERT_EQ(48, blurred.height());
+ ASSERT_EQ(3u * 48u * 48u, blurred.data().size());
+ // The middle blocks may have been blurred to something between white and
+ // black, so only verify the first 22 and last 22 rows.
+ for (size_t i = 0; i < 22u * 48u; i++) {
+ EXPECT_EQ('\x00', blurred.data()[3 * i]);
+ EXPECT_EQ('\x00', blurred.data()[3 * i + 1]);
+ EXPECT_EQ('\x00', blurred.data()[3 * i + 2]);
+ }
+
+ for (size_t i = 26u * 48u; i < 48u * 48u; i++) {
+ EXPECT_EQ('\xff', blurred.data()[3 * i]);
+ EXPECT_EQ('\xff', blurred.data()[3 * i + 1]);
+ EXPECT_EQ('\xff', blurred.data()[3 * i + 2]);
+ }
+}
+
+TEST_F(VisualUtilsTest, BlockMeanAverageOneBlock) {
+ // Draw black over half the image.
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 500; y++)
+ *bitmap_.getAddr32(x, y) = kBlack;
+
+ // Draw white over half the image
+ for (int x = 0; x < 1000; x++)
+ for (int y = 500; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ std::unique_ptr<SkBitmap> blocks = BlockMeanAverage(bitmap_, 1000);
+ ASSERT_EQ(1, blocks->width());
+ ASSERT_EQ(1, blocks->height());
+ EXPECT_EQ(blocks->getColor(0, 0), SkColorSetRGB(127, 127, 127));
+}
+
+TEST_F(VisualUtilsTest, BlockMeanAveragePartialBlocks) {
+ // Draw a white, red, green, and blue box with the expected block sizes.
+ for (int x = 0; x < 600; x++)
+ for (int y = 0; y < 600; y++)
+ *bitmap_.getAddr32(x, y) = kWhite;
+
+ for (int x = 600; x < 1000; x++)
+ for (int y = 0; y < 600; y++)
+ *bitmap_.getAddr32(x, y) = kRed;
+
+ for (int x = 0; x < 600; x++)
+ for (int y = 600; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kGreen;
+
+ for (int x = 600; x < 1000; x++)
+ for (int y = 600; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = kBlue;
+
+ std::unique_ptr<SkBitmap> blocks = BlockMeanAverage(bitmap_, 600);
+ ASSERT_EQ(2, blocks->width());
+ ASSERT_EQ(2, blocks->height());
+ EXPECT_EQ(*blocks->getAddr32(0, 0), kWhite);
+ EXPECT_EQ(*blocks->getAddr32(1, 0), kRed);
+ EXPECT_EQ(*blocks->getAddr32(0, 1), kGreen);
+ EXPECT_EQ(*blocks->getAddr32(1, 1), kBlue);
+}
+
+} // namespace visual_utils
+} // namespace safe_browsing
diff --git a/chromium/components/safe_browsing/ping_manager.cc b/chromium/components/safe_browsing/ping_manager.cc
index 3510d8b6cfd..80c81740e2b 100644
--- a/chromium/components/safe_browsing/ping_manager.cc
+++ b/chromium/components/safe_browsing/ping_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
diff --git a/chromium/components/safe_browsing/proto/PRESUBMIT.py b/chromium/components/safe_browsing/proto/PRESUBMIT.py
index 0e7381237a4..1b4c0c8258c 100644
--- a/chromium/components/safe_browsing/proto/PRESUBMIT.py
+++ b/chromium/components/safe_browsing/proto/PRESUBMIT.py
@@ -3,18 +3,29 @@
# found in the LICENSE file.
def CheckChangeOnUpload(input_api, output_api):
+ results = []
+
# Warn if the proto file is not modified without also modifying
- # the WebUI.
+ # the WebUI and extension API idl file.
proto_path = 'components/safe_browsing/proto/csd.proto'
web_ui_path = 'components/safe_browsing/web_ui/safe_browsing_ui.cc'
+ idl_path = 'chrome/common/extensions/api/safe_browsing_private.idl'
- if proto_path in input_api.change.LocalPaths() and \
- not web_ui_path in input_api.change.LocalPaths():
- return [
- output_api.PresubmitPromptWarning(
- 'You modified the one or more of the CSD protos in: \n'
- ' ' + proto_path + '\n'
- 'without changing the WebUI in: \n'
- ' ' + web_ui_path + '\n')
- ]
- return []
+ if proto_path in input_api.change.LocalPaths():
+ if web_ui_path not in input_api.change.LocalPaths():
+ results.append(
+ output_api.PresubmitPromptWarning(
+ 'You modified the one or more of the CSD protos in: \n'
+ ' ' + proto_path + '\n'
+ 'without changing the WebUI in: \n'
+ ' ' + web_ui_path + '\n')
+ )
+ if idl_path not in input_api.change.LocalPaths():
+ results.append(
+ output_api.PresubmitPromptWarning(
+ 'You modified the one or more of the CSD protos in: \n'
+ ' ' + proto_path + '\n'
+ 'without changing the API definition in: \n'
+ ' ' + idl_path + '\n')
+ )
+ return results
diff --git a/chromium/components/safe_browsing/proto/csd.proto b/chromium/components/safe_browsing/proto/csd.proto
index a7216fd7fde..9848d836c13 100644
--- a/chromium/components/safe_browsing/proto/csd.proto
+++ b/chromium/components/safe_browsing/proto/csd.proto
@@ -399,10 +399,9 @@ message VisualFeatures {
}
// Blurred, downsampled image of the current page.
+ // Using Rec 2020 color space:
+ // https://en.wikipedia.org/wiki/Rec._2020
optional BlurredImage image = 2;
-
- // The final pHash for the current page.
- optional bytes phash = 3;
}
message ClientMalwareResponse {
@@ -682,7 +681,12 @@ message ClientDownloadRequest {
// protection for Advanced Protection users.
optional bool request_ap_verdicts = 67;
- // next available tag number: 68;
+ // For archives files the number of files and directories contained within the
+ // archive.
+ optional int32 archive_file_count = 68;
+ optional int32 archive_directory_count = 69;
+
+ // next available tag number: 70;
}
message ReferrerChainOptions {
diff --git a/chromium/components/safe_browsing/renderer/renderer_url_loader_throttle.cc b/chromium/components/safe_browsing/renderer/renderer_url_loader_throttle.cc
index fdc9a0c366b..05ffb7d19fa 100644
--- a/chromium/components/safe_browsing/renderer/renderer_url_loader_throttle.cc
+++ b/chromium/components/safe_browsing/renderer/renderer_url_loader_throttle.cc
@@ -4,12 +4,11 @@
#include "components/safe_browsing/renderer/renderer_url_loader_throttle.h"
-#include "base/feature_list.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "components/safe_browsing/common/safebrowsing_constants.h"
#include "components/safe_browsing/common/utils.h"
-#include "components/safe_browsing/features.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
@@ -186,11 +185,8 @@ void RendererURLLoaderThrottle::OnCompleteCheckInternal(
notifier_bindings_.reset();
pending_checks_ = 0;
pending_slow_checks_ = 0;
- delegate_->CancelWithError(
- base::FeatureList::IsEnabled(kCommittedSBInterstitials)
- ? net::ERR_BLOCKED_BY_CLIENT
- : net::ERR_ABORTED,
- kCustomCancelReasonForURLLoader);
+ delegate_->CancelWithError(GetNetErrorCodeForSafeBrowsing(),
+ kCustomCancelReasonForURLLoader);
}
}
diff --git a/chromium/components/safe_browsing/renderer/threat_dom_details.cc b/chromium/components/safe_browsing/renderer/threat_dom_details.cc
index 2b688bc8f2b..076a8a1c663 100644
--- a/chromium/components/safe_browsing/renderer/threat_dom_details.cc
+++ b/chromium/components/safe_browsing/renderer/threat_dom_details.cc
@@ -9,6 +9,7 @@
#include <string>
#include <unordered_set>
+#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
diff --git a/chromium/components/safe_browsing/triggers/ad_sampler_trigger.cc b/chromium/components/safe_browsing/triggers/ad_sampler_trigger.cc
index f9ebe191e78..f293bd02d44 100644
--- a/chromium/components/safe_browsing/triggers/ad_sampler_trigger.cc
+++ b/chromium/components/safe_browsing/triggers/ad_sampler_trigger.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
diff --git a/chromium/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc b/chromium/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
index ee7183309cf..121c1c09f82 100644
--- a/chromium/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
+++ b/chromium/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
@@ -238,7 +238,7 @@ TEST(AdSamplerTriggerTestFinch, FrequencyDenominatorFeature) {
std::map<std::string, std::string> feature_params;
feature_params[std::string(
safe_browsing::kAdSamplerFrequencyDenominatorParam)] =
- base::IntToString(kDenominatorInt);
+ base::NumberToString(kDenominatorInt);
base::AssociateFieldTrialParams(safe_browsing::kAdSamplerTriggerFeature.name,
"Group", feature_params);
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
diff --git a/chromium/components/safe_browsing/triggers/suspicious_site_trigger.cc b/chromium/components/safe_browsing/triggers/suspicious_site_trigger.cc
index 59354d7cd23..ad16a774127 100644
--- a/chromium/components/safe_browsing/triggers/suspicious_site_trigger.cc
+++ b/chromium/components/safe_browsing/triggers/suspicious_site_trigger.cc
@@ -4,6 +4,7 @@
#include "components/safe_browsing/triggers/suspicious_site_trigger.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
diff --git a/chromium/components/safe_browsing/triggers/trigger_manager.cc b/chromium/components/safe_browsing/triggers/trigger_manager.cc
index b6a088d1aef..071ebcfd30b 100644
--- a/chromium/components/safe_browsing/triggers/trigger_manager.cc
+++ b/chromium/components/safe_browsing/triggers/trigger_manager.cc
@@ -4,6 +4,7 @@
#include "components/safe_browsing/triggers/trigger_manager.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/base_ui_manager.h"
diff --git a/chromium/components/safe_browsing/triggers/trigger_throttler.cc b/chromium/components/safe_browsing/triggers/trigger_throttler.cc
index 49458e3c8c9..c80d3eab603 100644
--- a/chromium/components/safe_browsing/triggers/trigger_throttler.cc
+++ b/chromium/components/safe_browsing/triggers/trigger_throttler.cc
@@ -228,7 +228,7 @@ void TriggerThrottler::WriteTriggerEventsToPref() {
base::DictionaryValue trigger_dict;
for (const auto& trigger_item : trigger_events_) {
base::Value* pref_timestamps = trigger_dict.SetKey(
- base::IntToString(static_cast<int>(trigger_item.first)),
+ base::NumberToString(static_cast<int>(trigger_item.first)),
base::Value(base::Value::Type::LIST));
for (const base::Time timestamp : trigger_item.second) {
pref_timestamps->GetList().push_back(base::Value(timestamp.ToDoubleT()));
diff --git a/chromium/components/safe_browsing/triggers/trigger_throttler.h b/chromium/components/safe_browsing/triggers/trigger_throttler.h
index 321fc8b5b8c..10cbcf6f72c 100644
--- a/chromium/components/safe_browsing/triggers/trigger_throttler.h
+++ b/chromium/components/safe_browsing/triggers/trigger_throttler.h
@@ -47,7 +47,7 @@ enum class TriggerType {
struct TriggerTypeHash {
std::size_t operator()(TriggerType trigger_type) const {
return static_cast<std::size_t>(trigger_type);
- };
+ }
};
// A map for storing a list of event timestamps for different trigger types.
diff --git a/chromium/components/safe_browsing/web_ui/resources/safe_browsing.html b/chromium/components/safe_browsing/web_ui/resources/safe_browsing.html
index 096c6953efa..0eac83a6883 100644
--- a/chromium/components/safe_browsing/web_ui/resources/safe_browsing.html
+++ b/chromium/components/safe_browsing/web_ui/resources/safe_browsing.html
@@ -8,7 +8,6 @@
<link rel="stylesheet" href="chrome://resources/css/tabs.css">
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/cr.js"></script>
- <script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/js/cr/ui.js"></script>
<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
@@ -18,16 +17,16 @@
<div id="header">
<h1 id="sb-title">Safe Browsing</h1>
</div>
- <tabbox>
+ <tabbox id='tabbox'>
<tabs>
- <tab>Preferences</tab>
- <tab>Database Manager</tab>
- <tab>Hash Cache</tab>
- <tab>ClientSafeBrowsingReportRequests</tab>
- <tab>Download Protection</tab>
- <tab>Password Protection</tab>
- <tab>Referrer Chain</tab>
- <tab>Log Messages</tab>
+ <tab id="preferences">Preferences</tab>
+ <tab id="db-manager">Database Manager</tab>
+ <tab id="hash-cache">Hash Cache</tab>
+ <tab id="csbrr">ClientSafeBrowsingReportRequests</tab>
+ <tab id="download-protection">Download Protection</tab>
+ <tab id="password-protection">Password Protection</tab>
+ <tab id="referrer-chain">Referrer Chain</tab>
+ <tab id="log">Log Messages</tab>
</tabs>
<tabpanels>
<tabpanel>
@@ -98,7 +97,6 @@
</tabpanel>
</tabpanels>
</tabbox>
- <script src="chrome://resources/js/i18n_template.js"></script>
<script src="safe_browsing.js"></script>
</body>
</html>
diff --git a/chromium/components/safe_browsing/web_ui/resources/safe_browsing.js b/chromium/components/safe_browsing/web_ui/resources/safe_browsing.js
index b3437777459..3e0f2765a37 100644
--- a/chromium/components/safe_browsing/web_ui/resources/safe_browsing.js
+++ b/chromium/components/safe_browsing/web_ui/resources/safe_browsing.js
@@ -88,6 +88,20 @@ cr.define('safe_browsing', function() {
});
$('get-referrer-chain-form').addEventListener('submit', addReferrerChain);
+
+ // Allow tabs to be navigated to by anchor.
+ showTab(window.location.hash.substr(1));
+ window.onhashchange = function () {
+ showTab(window.location.hash.substr(1));
+ };
+
+ // When the tab updates, update the anchor
+ $('tabbox').addEventListener('selectedChange', function() {
+ var tabbox = $('tabbox');
+ var tabs = tabbox.querySelector('tabs').children;
+ var selectedTab = tabs[tabbox.selectedIndex];
+ window.location.hash = selectedTab.id;
+ }, true);
}
function addExperiments(result) {
@@ -223,6 +237,12 @@ cr.define('safe_browsing', function() {
});
}
+ function showTab(tabId) {
+ if ($(tabId)) {
+ $(tabId).selected = "selected";
+ }
+ }
+
return {
addSentCSBRRsInfo: addSentCSBRRsInfo,
addSentClientDownloadRequestsInfo: addSentClientDownloadRequestsInfo,
diff --git a/chromium/components/safe_browsing/web_ui/safe_browsing_ui.cc b/chromium/components/safe_browsing/web_ui/safe_browsing_ui.cc
index 55ba0060d7c..46bd9ceac7d 100644
--- a/chromium/components/safe_browsing/web_ui/safe_browsing_ui.cc
+++ b/chromium/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -12,6 +12,7 @@
#include "base/base64.h"
#include "base/base64url.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/i18n/time_formatting.h"
#include "base/json/json_string_value_serializer.h"
@@ -38,13 +39,12 @@
#endif
using base::Time;
+using sync_pb::GaiaPasswordReuse;
using PasswordCaptured = sync_pb::UserEventSpecifics::GaiaPasswordCaptured;
-using PasswordReuseLookup =
- sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup;
-using PasswordReuseDetected =
- sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseDetected;
-using PasswordReuseDialogInteraction = sync_pb::UserEventSpecifics::
- GaiaPasswordReuse::PasswordReuseDialogInteraction;
+using PasswordReuseLookup = sync_pb::GaiaPasswordReuse::PasswordReuseLookup;
+using PasswordReuseDetected = sync_pb::GaiaPasswordReuse::PasswordReuseDetected;
+using PasswordReuseDialogInteraction =
+ sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction;
namespace safe_browsing {
WebUIInfoSingleton::WebUIInfoSingleton() = default;
@@ -488,6 +488,11 @@ std::string SerializeClientDownloadRequest(const ClientDownloadRequest& cdr) {
dict.SetBoolean("request_ap_verdicts", cdr.request_ap_verdicts());
+ dict.SetInteger("archive_file_count", cdr.archive_file_count());
+ dict.SetInteger("archive_directory_count", cdr.archive_directory_count());
+
+ dict.SetBoolean("request_ap_verdicts", cdr.request_ap_verdicts());
+
base::Value* request_tree = &dict;
std::string request_serialized;
JSONStringValueSerializer serializer(&request_serialized);
@@ -606,8 +611,7 @@ base::DictionaryValue SerializePGEvent(
base::Value(event_trigger));
}
- sync_pb::UserEventSpecifics::GaiaPasswordReuse reuse =
- event.gaia_password_reuse_event();
+ GaiaPasswordReuse reuse = event.gaia_password_reuse_event();
if (reuse.has_reuse_detected()) {
event_dict.SetPath({"reuse_detected", "status", "enabled"},
base::Value(reuse.reuse_detected().status().enabled()));
diff --git a/chromium/components/safe_search_api/BUILD.gn b/chromium/components/safe_search_api/BUILD.gn
index 7883ba3f7bf..2c3b2ff11b7 100644
--- a/chromium/components/safe_search_api/BUILD.gn
+++ b/chromium/components/safe_search_api/BUILD.gn
@@ -6,11 +6,26 @@ source_set("safe_search_api") {
sources = [
"url_checker.cc",
"url_checker.h",
+ "url_checker_client.h",
]
deps = [
"//base",
"//components/google/core/common",
+ "//url",
+ ]
+}
+
+source_set("safe_search_client") {
+ sources = [
+ "safe_search/safe_search_url_checker_client.cc",
+ "safe_search/safe_search_url_checker_client.h",
+ ]
+
+ deps = [
+ ":safe_search_api",
+ "//base",
+ "//components/google/core/common",
"//google_apis",
"//net",
"//services/network/public/cpp",
@@ -21,11 +36,14 @@ source_set("safe_search_api") {
source_set("test_support") {
testonly = true
sources = [
+ "fake_url_checker_client.cc",
+ "fake_url_checker_client.h",
"stub_url_checker.cc",
"stub_url_checker.h",
]
deps = [
":safe_search_api",
+ ":safe_search_client",
"//base",
"//base/test:test_support",
"//net",
@@ -39,14 +57,19 @@ source_set("test_support") {
source_set("unit_tests") {
testonly = true
sources = [
+ "safe_search/safe_search_url_checker_client_unittest.cc",
"url_checker_unittest.cc",
]
deps = [
":safe_search_api",
+ ":safe_search_client",
":test_support",
"//base",
"//base/test:test_support",
"//net",
+ "//net/traffic_annotation:test_support",
+ "//services/network:test_support",
+ "//services/network/public/cpp",
"//testing/gmock",
"//testing/gtest",
"//url",
diff --git a/chromium/components/safe_search_api/OWNERS b/chromium/components/safe_search_api/OWNERS
index 009f486a1d8..408a9bdabdd 100644
--- a/chromium/components/safe_search_api/OWNERS
+++ b/chromium/components/safe_search_api/OWNERS
@@ -1 +1,2 @@
+michaelpg@chromium.org
treib@chromium.org
diff --git a/chromium/components/safe_search_api/fake_url_checker_client.cc b/chromium/components/safe_search_api/fake_url_checker_client.cc
new file mode 100644
index 00000000000..c7a5a5c3fba
--- /dev/null
+++ b/chromium/components/safe_search_api/fake_url_checker_client.cc
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_search_api/fake_url_checker_client.h"
+
+#include <utility>
+
+#include "base/callback.h"
+
+namespace safe_search_api {
+
+FakeURLCheckerClient::FakeURLCheckerClient() = default;
+
+FakeURLCheckerClient::~FakeURLCheckerClient() = default;
+
+void FakeURLCheckerClient::CheckURL(const GURL& url,
+ ClientCheckCallback callback) {
+ url_ = url;
+ DCHECK(!callback_);
+ callback_ = std::move(callback);
+}
+
+void FakeURLCheckerClient::RunCallback(ClientClassification classification) {
+ std::move(callback_).Run(url_, classification);
+}
+
+} // namespace safe_search_api
diff --git a/chromium/components/safe_search_api/fake_url_checker_client.h b/chromium/components/safe_search_api/fake_url_checker_client.h
new file mode 100644
index 00000000000..9c1d971f9c8
--- /dev/null
+++ b/chromium/components/safe_search_api/fake_url_checker_client.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_
+#define COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_
+
+#include "base/callback.h"
+#include "components/safe_search_api/url_checker_client.h"
+
+namespace safe_search_api {
+
+// Helper class with fake URLCheckerClient for use with URLChecker. This
+// lets tests control the response the URLChecker will receive from the
+// URLCheckerClient. Used to test URLChecker.
+class FakeURLCheckerClient : public URLCheckerClient {
+ public:
+ FakeURLCheckerClient();
+ ~FakeURLCheckerClient() override;
+
+ // Fake override that simply holds references of |url| and |callback|.
+ //
+ // See RunCallback() method documentation below on how to run the callback.
+ void CheckURL(const GURL& url, ClientCheckCallback callback) override;
+
+ // Run the callback function input by the last call of CheckURL() with the
+ // result input with the last call of SetResult().
+ void RunCallback(ClientClassification classification);
+
+ private:
+ ClientCheckCallback callback_;
+ GURL url_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeURLCheckerClient);
+};
+
+} // namespace safe_search_api
+
+#endif // COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_
diff --git a/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.cc b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.cc
new file mode 100644
index 00000000000..617a494c87e
--- /dev/null
+++ b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.cc
@@ -0,0 +1,160 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
+
+#include <utility>
+
+#include "base/callback.h"
+#include "base/json/json_reader.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/optional.h"
+#include "base/stl_util.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/google/core/common/google_util.h"
+#include "net/base/escape.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request_status.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/url_constants.h"
+
+namespace safe_search_api {
+
+namespace {
+
+const char kSafeSearchApiUrl[] =
+ "https://safesearch.googleapis.com/v1:classify";
+const char kDataContentType[] = "application/x-www-form-urlencoded";
+const char kDataFormat[] = "key=%s&urls=%s&region_code=%s";
+
+// Builds the POST data for SafeSearch API requests.
+std::string BuildRequestData(const std::string& api_key,
+ const GURL& url,
+ const std::string& region_code) {
+ std::string query = net::EscapeQueryParamValue(url.spec(), true);
+ return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str(),
+ region_code.c_str());
+}
+
+// Parses a SafeSearch API |response| and stores the result in |is_porn|,
+// returns true on success. Otherwise, returns false and doesn't set |is_porn|.
+bool ParseResponse(const std::string& response, bool* is_porn) {
+ base::Optional<base::Value> optional_value = base::JSONReader::Read(response);
+ const base::DictionaryValue* dict = nullptr;
+ if (!optional_value || !optional_value.value().GetAsDictionary(&dict)) {
+ DLOG(WARNING) << "ParseResponse failed to parse global dictionary";
+ return false;
+ }
+ const base::ListValue* classifications_list = nullptr;
+ if (!dict->GetList("classifications", &classifications_list)) {
+ DLOG(WARNING) << "ParseResponse failed to parse classifications list";
+ return false;
+ }
+ if (classifications_list->GetSize() != 1) {
+ DLOG(WARNING) << "ParseResponse expected exactly one result";
+ return false;
+ }
+ const base::DictionaryValue* classification_dict = nullptr;
+ if (!classifications_list->GetDictionary(0, &classification_dict)) {
+ DLOG(WARNING) << "ParseResponse failed to parse classification dict";
+ return false;
+ }
+ classification_dict->GetBoolean("pornography", is_porn);
+ return true;
+}
+
+} // namespace
+
+struct SafeSearchURLCheckerClient::Check {
+ Check(const GURL& url,
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader,
+ ClientCheckCallback callback);
+ ~Check();
+
+ GURL url;
+ ClientCheckCallback callback;
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader;
+ base::TimeTicks start_time;
+};
+
+SafeSearchURLCheckerClient::Check::Check(
+ const GURL& url,
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader,
+ ClientCheckCallback callback)
+ : url(url),
+ callback(std::move(callback)),
+ simple_url_loader(std::move(simple_url_loader)),
+ start_time(base::TimeTicks::Now()) {}
+
+SafeSearchURLCheckerClient::Check::~Check() = default;
+
+SafeSearchURLCheckerClient::SafeSearchURLCheckerClient(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation,
+ const std::string& country,
+ const std::string& api_key)
+ : url_loader_factory_(std::move(url_loader_factory)),
+ traffic_annotation_(traffic_annotation),
+ country_(country),
+ api_key_(api_key) {}
+
+SafeSearchURLCheckerClient::~SafeSearchURLCheckerClient() = default;
+
+void SafeSearchURLCheckerClient::CheckURL(const GURL& url,
+ ClientCheckCallback callback) {
+ DVLOG(1) << "Checking URL " << url;
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = GURL(kSafeSearchApiUrl);
+ resource_request->method = "POST";
+ resource_request->load_flags =
+ net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
+ network::SimpleURLLoader::Create(std::move(resource_request),
+ traffic_annotation_);
+ simple_url_loader->AttachStringForUpload(
+ BuildRequestData(api_key_, url, country_), kDataContentType);
+ checks_in_progress_.push_front(std::make_unique<Check>(
+ url, std::move(simple_url_loader), std::move(callback)));
+ auto it = checks_in_progress_.begin();
+ network::SimpleURLLoader* loader = it->get()->simple_url_loader.get();
+ loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory_.get(),
+ base::BindOnce(&SafeSearchURLCheckerClient::OnSimpleLoaderComplete,
+ base::Unretained(this), it));
+}
+
+void SafeSearchURLCheckerClient::OnSimpleLoaderComplete(
+ CheckList::iterator it,
+ std::unique_ptr<std::string> response_body) {
+ std::unique_ptr<Check> check = std::move(*it);
+
+ checks_in_progress_.erase(it);
+
+ if (!response_body) {
+ DLOG(WARNING) << "URL request failed! Letting through...";
+ std::move(check->callback).Run(check->url, ClientClassification::kUnknown);
+ return;
+ }
+
+ ClientClassification classification = ClientClassification::kUnknown;
+ bool is_porn = false;
+ if (ParseResponse(*response_body, &is_porn)) {
+ classification = is_porn ? ClientClassification::kRestricted
+ : ClientClassification::kAllowed;
+ }
+
+ // TODO(msramek): Consider moving this to SupervisedUserResourceThrottle.
+ UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay",
+ base::TimeTicks::Now() - check->start_time);
+
+ std::move(check->callback).Run(check->url, classification);
+}
+
+} // namespace safe_search_api
diff --git a/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.h b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.h
new file mode 100644
index 00000000000..49af799f4d1
--- /dev/null
+++ b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client.h
@@ -0,0 +1,65 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_
+#define COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "components/safe_search_api/url_checker_client.h"
+#include "google_apis/google_api_keys.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+
+namespace network {
+class SharedURLLoaderFactory;
+} // namespace network
+
+namespace safe_search_api {
+
+// This class uses the SafeSearch API to check the SafeSearch classification
+// of the content on a given URL and returns the result asynchronously
+// via a callback.
+class SafeSearchURLCheckerClient : public URLCheckerClient {
+ public:
+ // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g.,
+ // "us". Optional
+ SafeSearchURLCheckerClient(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+ const net::NetworkTrafficAnnotationTag& traffic_annotation,
+ const std::string& country = std::string(),
+ const std::string& api_key = google_apis::GetAPIKey());
+
+ ~SafeSearchURLCheckerClient() override;
+
+ // Checks whether an |url| is restricted according to SafeSearch.
+ //
+ // On failure, the |callback| function is called with |url| as the first
+ // parameter, and UNKNOWN as the second.
+ void CheckURL(const GURL& url, ClientCheckCallback callback) override;
+
+ private:
+ struct Check;
+
+ using CheckList = std::list<std::unique_ptr<Check>>;
+
+ void OnSimpleLoaderComplete(CheckList::iterator it,
+ std::unique_ptr<std::string> response_body);
+
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+ const net::NetworkTrafficAnnotationTag traffic_annotation_;
+ const std::string country_;
+ const std::string api_key_;
+
+ CheckList checks_in_progress_;
+
+ DISALLOW_COPY_AND_ASSIGN(SafeSearchURLCheckerClient);
+};
+
+} // namespace safe_search_api
+
+#endif // COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_
diff --git a/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc
new file mode 100644
index 00000000000..d42e3f06bec
--- /dev/null
+++ b/chromium/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc
@@ -0,0 +1,136 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/json/json_writer.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::_;
+
+namespace safe_search_api {
+
+namespace {
+
+constexpr char kSafeSearchApiUrl[] =
+ "https://safesearch.googleapis.com/v1:classify";
+
+std::string BuildResponse(bool is_porn) {
+ base::DictionaryValue dict;
+ auto classification_dict = std::make_unique<base::DictionaryValue>();
+ if (is_porn)
+ classification_dict->SetBoolean("pornography", is_porn);
+ auto classifications_list = std::make_unique<base::ListValue>();
+ classifications_list->Append(std::move(classification_dict));
+ dict.SetWithoutPathExpansion("classifications",
+ std::move(classifications_list));
+ std::string result;
+ base::JSONWriter::Write(dict, &result);
+ return result;
+}
+
+const char* kURLs[] = {
+ "http://www.randomsite1.com", "http://www.randomsite2.com",
+ "http://www.randomsite3.com", "http://www.randomsite4.com",
+ "http://www.randomsite5.com", "http://www.randomsite6.com",
+ "http://www.randomsite7.com", "http://www.randomsite8.com",
+ "http://www.randomsite9.com",
+};
+
+} // namespace
+
+class SafeSearchURLCheckerClientTest : public testing::Test {
+ public:
+ SafeSearchURLCheckerClientTest()
+ : next_url_(0),
+ test_shared_loader_factory_(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &test_url_loader_factory_)) {
+ checker_ = std::make_unique<SafeSearchURLCheckerClient>(
+ test_shared_loader_factory_, TRAFFIC_ANNOTATION_FOR_TESTS);
+ }
+
+ MOCK_METHOD2(OnCheckDone,
+ void(const GURL& url, ClientClassification classification));
+
+ protected:
+ GURL GetNewURL() {
+ CHECK(next_url_ < base::size(kURLs));
+ return GURL(kURLs[next_url_++]);
+ }
+
+ void CheckURL(const GURL& url) {
+ checker_->CheckURL(
+ url, base::BindOnce(&SafeSearchURLCheckerClientTest::OnCheckDone,
+ base::Unretained(this)));
+ }
+
+ void WaitForResponse() { base::RunLoop().RunUntilIdle(); }
+
+ void SetUpFailedResponse() { SetUpResponse(net::ERR_ABORTED, std::string()); }
+
+ void SetUpResponse(net::Error error, const std::string& response) {
+ network::URLLoaderCompletionStatus status(error);
+ status.decoded_body_length = response.size();
+ test_url_loader_factory_.AddResponse(GURL(kSafeSearchApiUrl),
+ network::ResourceResponseHead(),
+ response, status);
+ }
+
+ // This method should only be used for Classification kAllowed and kRestricted
+ void SetUpValidResponse(ClientClassification classification) {
+ bool is_porn = classification == ClientClassification::kRestricted;
+ SetUpResponse(net::OK, BuildResponse(is_porn));
+ }
+
+ void SendValidResponse(const GURL& url, ClientClassification classification) {
+ SetUpValidResponse(classification);
+ CheckURL(url);
+ WaitForResponse();
+ }
+
+ void SendFailedResponse(const GURL& url) {
+ SetUpFailedResponse();
+ CheckURL(url);
+ WaitForResponse();
+ }
+
+ size_t next_url_;
+ base::test::ScopedTaskEnvironment task_environment_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
+ std::unique_ptr<SafeSearchURLCheckerClient> checker_;
+};
+
+TEST_F(SafeSearchURLCheckerClientTest, Simple) {
+ {
+ GURL url(GetNewURL());
+ EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kAllowed));
+ SendValidResponse(url, ClientClassification::kAllowed);
+ }
+ {
+ GURL url(GetNewURL());
+ EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kRestricted));
+ SendValidResponse(url, ClientClassification::kRestricted);
+ }
+ {
+ GURL url(GetNewURL());
+ EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kUnknown));
+ SendFailedResponse(url);
+ }
+}
+
+} // namespace safe_search_api
diff --git a/chromium/components/safe_search_api/stub_url_checker.cc b/chromium/components/safe_search_api/stub_url_checker.cc
index 0871c75ee19..eeaa36b7f11 100644
--- a/chromium/components/safe_search_api/stub_url_checker.cc
+++ b/chromium/components/safe_search_api/stub_url_checker.cc
@@ -4,8 +4,11 @@
#include "components/safe_search_api/stub_url_checker.h"
+#include <utility>
+
#include "base/json/json_writer.h"
#include "base/values.h"
+#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h"
#include "components/safe_search_api/url_checker.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -43,9 +46,10 @@ StubURLChecker::StubURLChecker()
StubURLChecker::~StubURLChecker() = default;
std::unique_ptr<URLChecker> StubURLChecker::BuildURLChecker(size_t cache_size) {
- return std::make_unique<URLChecker>(test_shared_loader_factory_,
- TRAFFIC_ANNOTATION_FOR_TESTS,
- std::string(), cache_size);
+ return std::make_unique<URLChecker>(
+ std::make_unique<SafeSearchURLCheckerClient>(
+ test_shared_loader_factory_, TRAFFIC_ANNOTATION_FOR_TESTS),
+ cache_size);
}
void StubURLChecker::SetUpValidResponse(bool is_porn) {
diff --git a/chromium/components/safe_search_api/url_checker.cc b/chromium/components/safe_search_api/url_checker.cc
index 42fc599ff1a..fbc4db52039 100644
--- a/chromium/components/safe_search_api/url_checker.cc
+++ b/chromium/components/safe_search_api/url_checker.cc
@@ -6,7 +6,9 @@
#include <string>
#include <utility>
+#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
@@ -18,63 +20,14 @@
#include "base/time/time.h"
#include "base/values.h"
#include "components/google/core/common/google_util.h"
-#include "google_apis/google_api_keys.h"
-#include "net/base/escape.h"
-#include "net/base/load_flags.h"
-#include "net/url_request/url_request_status.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/simple_url_loader.h"
-#include "url/url_constants.h"
namespace safe_search_api {
namespace {
-const char kSafeSearchApiUrl[] =
- "https://safesearch.googleapis.com/v1:classify";
-const char kDataContentType[] = "application/x-www-form-urlencoded";
-const char kDataFormat[] = "key=%s&urls=%s&region_code=%s";
-
const size_t kDefaultCacheSize = 1000;
const size_t kDefaultCacheTimeoutSeconds = 3600;
-// Builds the POST data for SafeSearch API requests.
-std::string BuildRequestData(const std::string& api_key,
- const GURL& url,
- const std::string& region_code) {
- std::string query = net::EscapeQueryParamValue(url.spec(), true);
- return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str(),
- region_code.c_str());
-}
-
-// Parses a SafeSearch API |response| and stores the result in |is_porn|.
-// On errors, returns false and doesn't set |is_porn|.
-bool ParseResponse(const std::string& response, bool* is_porn) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
- const base::DictionaryValue* dict = nullptr;
- if (!value || !value->GetAsDictionary(&dict)) {
- DLOG(WARNING) << "ParseResponse failed to parse global dictionary";
- return false;
- }
- const base::ListValue* classifications_list = nullptr;
- if (!dict->GetList("classifications", &classifications_list)) {
- DLOG(WARNING) << "ParseResponse failed to parse classifications list";
- return false;
- }
- if (classifications_list->GetSize() != 1) {
- DLOG(WARNING) << "ParseResponse expected exactly one result";
- return false;
- }
- const base::DictionaryValue* classification_dict = nullptr;
- if (!classifications_list->GetDictionary(0, &classification_dict)) {
- DLOG(WARNING) << "ParseResponse failed to parse classification dict";
- return false;
- }
- classification_dict->GetBoolean("pornography", is_porn);
- return true;
-}
-
} // namespace
// Consider all URLs within a google domain to be safe.
@@ -82,24 +35,14 @@ const base::Feature kAllowAllGoogleUrls{"SafeSearchAllowAllGoogleURLs",
base::FEATURE_DISABLED_BY_DEFAULT};
struct URLChecker::Check {
- Check(const GURL& url,
- std::unique_ptr<network::SimpleURLLoader> simple_url_loader,
- CheckCallback callback);
+ Check(const GURL& url, CheckCallback callback);
~Check();
GURL url;
- std::unique_ptr<network::SimpleURLLoader> simple_url_loader;
std::vector<CheckCallback> callbacks;
- base::TimeTicks start_time;
};
-URLChecker::Check::Check(
- const GURL& url,
- std::unique_ptr<network::SimpleURLLoader> simple_url_loader,
- CheckCallback callback)
- : url(url),
- simple_url_loader(std::move(simple_url_loader)),
- start_time(base::TimeTicks::Now()) {
+URLChecker::Check::Check(const GURL& url, CheckCallback callback) : url(url) {
callbacks.push_back(std::move(callback));
}
@@ -115,36 +58,12 @@ URLChecker::CheckResult::CheckResult(Classification classification,
uncertain(uncertain),
timestamp(base::TimeTicks::Now()) {}
-URLChecker::URLChecker(
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country)
- : URLChecker(std::move(url_loader_factory),
- traffic_annotation,
- country,
- kDefaultCacheSize) {}
-
-URLChecker::URLChecker(
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country,
- size_t cache_size)
- : URLChecker(std::move(url_loader_factory),
- traffic_annotation,
- country,
- cache_size,
- google_apis::GetAPIKey()) {}
-
-URLChecker::URLChecker(
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country,
- size_t cache_size,
- const std::string& api_key)
- : url_loader_factory_(std::move(url_loader_factory)),
- traffic_annotation_(traffic_annotation),
- country_(country),
- api_key_(api_key),
+URLChecker::URLChecker(std::unique_ptr<URLCheckerClient> async_checker)
+ : URLChecker(std::move(async_checker), kDefaultCacheSize) {}
+
+URLChecker::URLChecker(std::unique_ptr<URLCheckerClient> async_checker,
+ size_t cache_size)
+ : async_checker_(std::move(async_checker)),
cache_(cache_size),
cache_timeout_(
base::TimeDelta::FromSeconds(kDefaultCacheTimeoutSeconds)) {}
@@ -193,54 +112,30 @@ bool URLChecker::CheckURL(const GURL& url, CheckCallback callback) {
}
}
- DVLOG(1) << "Checking URL " << url;
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = GURL(kSafeSearchApiUrl);
- resource_request->method = "POST";
- resource_request->load_flags =
- net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
- std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
- network::SimpleURLLoader::Create(std::move(resource_request),
- traffic_annotation_);
- simple_url_loader->AttachStringForUpload(
- BuildRequestData(api_key_, url, country_), kDataContentType);
auto it = checks_in_progress_.insert(
checks_in_progress_.begin(),
- std::make_unique<Check>(url, std::move(simple_url_loader),
- std::move(callback)));
- network::SimpleURLLoader* loader = it->get()->simple_url_loader.get();
- loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- url_loader_factory_.get(),
- base::BindOnce(&URLChecker::OnSimpleLoaderComplete,
- base::Unretained(this), std::move(it)));
+ std::make_unique<Check>(url, std::move(callback)));
+ async_checker_->CheckURL(url,
+ base::BindOnce(&URLChecker::OnAsyncCheckComplete,
+ base::Unretained(this), it));
+
return false;
}
-void URLChecker::OnSimpleLoaderComplete(
- CheckList::iterator it,
- std::unique_ptr<std::string> response_body) {
- Check* check = it->get();
+void URLChecker::OnAsyncCheckComplete(CheckList::iterator it,
+ const GURL& url,
+ ClientClassification api_classification) {
+ bool uncertain = api_classification == ClientClassification::kUnknown;
- GURL url = check->url;
- std::vector<CheckCallback> callbacks = std::move(check->callbacks);
- base::TimeTicks start_time = check->start_time;
- checks_in_progress_.erase(it);
-
- if (!response_body) {
- DLOG(WARNING) << "URL request failed! Letting through...";
- for (size_t i = 0; i < callbacks.size(); i++)
- std::move(callbacks[i]).Run(url, Classification::SAFE, true);
- return;
+ // Fallback to a |SAFE| classification when the result is not explicitly
+ // marked as restricted.
+ Classification classification = Classification::SAFE;
+ if (api_classification == ClientClassification::kRestricted) {
+ classification = Classification::UNSAFE;
}
- bool is_porn = false;
- bool uncertain = !ParseResponse(*response_body, &is_porn);
- Classification classification =
- is_porn ? Classification::UNSAFE : Classification::SAFE;
-
- // TODO(msramek): Consider moving this to SupervisedUserResourceThrottle.
- UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay",
- base::TimeTicks::Now() - start_time);
+ std::vector<CheckCallback> callbacks = std::move(it->get()->callbacks);
+ checks_in_progress_.erase(it);
cache_.Put(url, CheckResult(classification, uncertain));
diff --git a/chromium/components/safe_search_api/url_checker.h b/chromium/components/safe_search_api/url_checker.h
index cbde568162d..d47999d00a8 100644
--- a/chromium/components/safe_search_api/url_checker.h
+++ b/chromium/components/safe_search_api/url_checker.h
@@ -5,23 +5,15 @@
#ifndef COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_H_
#define COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_H_
-#include <stddef.h>
-
+#include <list>
#include <memory>
-#include <vector>
#include "base/callback_forward.h"
#include "base/containers/mru_cache.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "components/safe_search_api/url_checker_client.h"
#include "url/gurl.h"
-namespace network {
-class SharedURLLoaderFactory;
-} // namespace network
-
namespace base {
struct Feature;
}
@@ -34,29 +26,22 @@ enum class Classification { SAFE, UNSAFE };
// Visible for testing.
extern const base::Feature kAllowAllGoogleUrls;
-// This class uses the SafeSearch API to check the SafeSearch classification
-// of the content on a given URL and returns the result asynchronously
-// via a callback.
+// This class uses one implementation of URLCheckerClient to check the
+// classification of the content on a given URL and returns the result
+// asynchronously via a callback. It is also responsible for the synchronous
+// logic such as caching, the injected URLCheckerClient is who makes the
+// async request.
class URLChecker {
public:
- // Returns whether |url| should be blocked. Called from CheckURL.
+ // Used to report whether |url| should be blocked. Called from CheckURL.
using CheckCallback = base::OnceCallback<
void(const GURL&, Classification classification, bool /* uncertain */)>;
- // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g.,
- // "us".
- URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country);
- URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country,
+ explicit URLChecker(std::unique_ptr<URLCheckerClient> async_checker);
+
+ URLChecker(std::unique_ptr<URLCheckerClient> async_checker,
size_t cache_size);
- URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const net::NetworkTrafficAnnotationTag& traffic_annotation,
- const std::string& country,
- size_t cache_size,
- const std::string& api_key);
+
~URLChecker();
// Returns whether |callback| was run synchronously.
@@ -76,14 +61,11 @@ class URLChecker {
};
using CheckList = std::list<std::unique_ptr<Check>>;
- void OnSimpleLoaderComplete(CheckList::iterator it,
- std::unique_ptr<std::string> response_body);
-
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- const net::NetworkTrafficAnnotationTag traffic_annotation_;
- const std::string country_;
- const std::string api_key_;
+ void OnAsyncCheckComplete(CheckList::iterator it,
+ const GURL& url,
+ ClientClassification classification);
+ std::unique_ptr<URLCheckerClient> async_checker_;
CheckList checks_in_progress_;
base::MRUCache<GURL, CheckResult> cache_;
diff --git a/chromium/components/safe_search_api/url_checker_client.h b/chromium/components/safe_search_api/url_checker_client.h
new file mode 100644
index 00000000000..98f75f17b66
--- /dev/null
+++ b/chromium/components/safe_search_api/url_checker_client.h
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_
+#define COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_
+
+#include "base/callback_forward.h"
+#include "url/gurl.h"
+
+namespace safe_search_api {
+
+// The client representation of a URL classification by the service for the user
+// in the request context.
+enum class ClientClassification { kAllowed, kRestricted, kUnknown };
+
+// Interface to make the server request and check an URL.
+class URLCheckerClient {
+ public:
+ // Used to report whether |url| should be blocked. Called from CheckURL.
+ using ClientCheckCallback =
+ base::OnceCallback<void(const GURL&,
+ ClientClassification classification)>;
+
+ virtual ~URLCheckerClient() = default;
+
+ // Checks whether an |url| is restricted for the user in the request context.
+ //
+ // On success, the |callback| function is called with |url| as the first
+ // parameter, the result as second.
+ //
+ // Refer to the implementation class for documentation about error handling.
+ virtual void CheckURL(const GURL& url, ClientCheckCallback callback) = 0;
+};
+
+} // namespace safe_search_api
+
+#endif // COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_
diff --git a/chromium/components/safe_search_api/url_checker_unittest.cc b/chromium/components/safe_search_api/url_checker_unittest.cc
index a663392612f..362fde4d781 100644
--- a/chromium/components/safe_search_api/url_checker_unittest.cc
+++ b/chromium/components/safe_search_api/url_checker_unittest.cc
@@ -10,15 +10,13 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
-#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/safe_search_api/stub_url_checker.h"
-#include "net/base/net_errors.h"
+#include "components/safe_search_api/fake_url_checker_client.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -39,12 +37,29 @@ const char* kURLs[] = {
"http://www.randomsite9.com",
};
+ClientClassification ToAPIClassification(Classification classification,
+ bool uncertain) {
+ if (uncertain) {
+ return ClientClassification::kUnknown;
+ }
+ switch (classification) {
+ case Classification::SAFE:
+ return ClientClassification::kAllowed;
+ case Classification::UNSAFE:
+ return ClientClassification::kRestricted;
+ }
+}
+
} // namespace
class SafeSearchURLCheckerTest : public testing::Test {
public:
- SafeSearchURLCheckerTest()
- : next_url_(0), checker_(stub_url_checker_.BuildURLChecker(kCacheSize)) {}
+ SafeSearchURLCheckerTest() : next_url_(0) {
+ std::unique_ptr<FakeURLCheckerClient> fake_client =
+ std::make_unique<FakeURLCheckerClient>();
+ fake_client_ = fake_client.get();
+ checker_ = std::make_unique<URLChecker>(std::move(fake_client), kCacheSize);
+ }
MOCK_METHOD3(OnCheckDone,
void(const GURL& url,
@@ -65,25 +80,16 @@ class SafeSearchURLCheckerTest : public testing::Test {
return cached;
}
- void WaitForResponse() { base::RunLoop().RunUntilIdle(); }
-
- bool SendValidResponse(const GURL& url, bool is_porn) {
- stub_url_checker_.SetUpValidResponse(is_porn);
- bool result = CheckURL(url);
- WaitForResponse();
- return result;
- }
-
- bool SendFailedResponse(const GURL& url) {
- stub_url_checker_.SetUpFailedResponse();
+ bool SendResponse(const GURL& url,
+ Classification classification,
+ bool uncertain) {
bool result = CheckURL(url);
- WaitForResponse();
+ fake_client_->RunCallback(ToAPIClassification(classification, uncertain));
return result;
}
size_t next_url_;
- base::test::ScopedTaskEnvironment task_environment_;
- StubURLChecker stub_url_checker_;
+ FakeURLCheckerClient* fake_client_;
std::unique_ptr<URLChecker> checker_;
};
@@ -91,17 +97,17 @@ TEST_F(SafeSearchURLCheckerTest, Simple) {
{
GURL url(GetNewURL());
EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url, false));
+ ASSERT_FALSE(SendResponse(url, Classification::SAFE, false));
}
{
GURL url(GetNewURL());
EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false));
- ASSERT_FALSE(SendValidResponse(url, true));
+ ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false));
}
{
GURL url(GetNewURL());
EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, true));
- ASSERT_FALSE(SendFailedResponse(url));
+ ASSERT_FALSE(SendResponse(url, Classification::SAFE, true));
}
}
@@ -114,12 +120,11 @@ TEST_F(SafeSearchURLCheckerTest, Cache) {
// Populate the cache.
EXPECT_CALL(*this, OnCheckDone(url1, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url1, false));
+ ASSERT_FALSE(SendResponse(url1, Classification::SAFE, false));
EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url2, false));
+ ASSERT_FALSE(SendResponse(url2, Classification::SAFE, false));
- // Now we should get results synchronously, without a network request.
- stub_url_checker_.ClearResponses();
+ // Now we should get results synchronously, without a request to the api.
EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false));
ASSERT_TRUE(CheckURL(url2));
EXPECT_CALL(*this, OnCheckDone(url1, Classification::SAFE, false));
@@ -127,21 +132,20 @@ TEST_F(SafeSearchURLCheckerTest, Cache) {
// Now |url2| is the LRU and should be evicted on the next check.
EXPECT_CALL(*this, OnCheckDone(url3, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url3, false));
+ ASSERT_FALSE(SendResponse(url3, Classification::SAFE, false));
EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url2, false));
+ ASSERT_FALSE(SendResponse(url2, Classification::SAFE, false));
}
TEST_F(SafeSearchURLCheckerTest, CoalesceRequestsToSameURL) {
GURL url(GetNewURL());
// Start two checks for the same URL.
- stub_url_checker_.SetUpValidResponse(false);
ASSERT_FALSE(CheckURL(url));
ASSERT_FALSE(CheckURL(url));
// A single response should answer both of those checks
EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false)).Times(2);
- WaitForResponse();
+ fake_client_->RunCallback(ToAPIClassification(Classification::SAFE, false));
}
TEST_F(SafeSearchURLCheckerTest, CacheTimeout) {
@@ -150,12 +154,12 @@ TEST_F(SafeSearchURLCheckerTest, CacheTimeout) {
checker_->SetCacheTimeoutForTesting(base::TimeDelta::FromSeconds(0));
EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false));
- ASSERT_FALSE(SendValidResponse(url, false));
+ ASSERT_FALSE(SendResponse(url, Classification::SAFE, false));
// Since the cache timeout is zero, the cache entry should be invalidated
// immediately.
EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false));
- ASSERT_FALSE(SendValidResponse(url, true));
+ ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false));
}
TEST_F(SafeSearchURLCheckerTest, AllowAllGoogleURLs) {
@@ -182,19 +186,13 @@ TEST_F(SafeSearchURLCheckerTest, NoAllowAllGoogleURLs) {
feature_list.InitAndDisableFeature(kAllowAllGoogleUrls);
{
GURL url("https://sites.google.com/porn");
- EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, _));
- stub_url_checker_.SetUpValidResponse(true);
- bool cache_hit = CheckURL(url);
- ASSERT_FALSE(cache_hit);
- WaitForResponse();
+ EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false));
+ ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false));
}
{
GURL url("https://youtube.com/porn");
- EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, _));
- stub_url_checker_.SetUpValidResponse(true);
- bool cache_hit = CheckURL(url);
- ASSERT_FALSE(cache_hit);
- WaitForResponse();
+ EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false));
+ ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false));
}
}
diff --git a/chromium/components/scheduling_metrics/task_duration_metric_reporter.h b/chromium/components/scheduling_metrics/task_duration_metric_reporter.h
index b2a9b818b05..84a7d5689c6 100644
--- a/chromium/components/scheduling_metrics/task_duration_metric_reporter.h
+++ b/chromium/components/scheduling_metrics/task_duration_metric_reporter.h
@@ -35,7 +35,7 @@ class TaskDurationMetricReporter {
static_cast<int>(TaskClass::kCount),
static_cast<int>(TaskClass::kCount) + 1,
1000 * 1000,
- base::HistogramBase::kUmaTargetedHistogramFlag)){};
+ base::HistogramBase::kUmaTargetedHistogramFlag)) {}
void RecordTask(TaskClass task_class, base::TimeDelta duration) {
DCHECK_LT(static_cast<int>(task_class),
diff --git a/chromium/components/search_engines/default_search_manager.cc b/chromium/components/search_engines/default_search_manager.cc
index 07f30687e40..ffe8ec2a91f 100644
--- a/chromium/components/search_engines/default_search_manager.cc
+++ b/chromium/components/search_engines/default_search_manager.cc
@@ -109,8 +109,9 @@ void DefaultSearchManager::RegisterProfilePrefs(
void DefaultSearchManager::AddPrefValueToMap(
std::unique_ptr<base::DictionaryValue> value,
PrefValueMap* pref_value_map) {
+ DCHECK(value);
pref_value_map->SetValue(kDefaultSearchProviderDataPrefName,
- std::move(value));
+ base::Value::FromUniquePtrValue(std::move(value)));
}
// static
diff --git a/chromium/components/search_engines/default_search_manager_unittest.cc b/chromium/components/search_engines/default_search_manager_unittest.cc
index 05f596b484c..1f7a1f9b828 100644
--- a/chromium/components/search_engines/default_search_manager_unittest.cc
+++ b/chromium/components/search_engines/default_search_manager_unittest.cc
@@ -80,7 +80,7 @@ void SetPolicy(sync_preferences::TestingPrefServiceSyncable* prefs,
class DefaultSearchManagerTest : public testing::Test {
public:
- DefaultSearchManagerTest() {};
+ DefaultSearchManagerTest() {}
void SetUp() override {
pref_service_.reset(new sync_preferences::TestingPrefServiceSyncable);
diff --git a/chromium/components/search_engines/default_search_policy_handler.cc b/chromium/components/search_engines/default_search_policy_handler.cc
index 68863ccc606..e521899cb1e 100644
--- a/chromium/components/search_engines/default_search_policy_handler.cc
+++ b/chromium/components/search_engines/default_search_policy_handler.cc
@@ -173,7 +173,7 @@ void DefaultSearchPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
// Set the fields which are not specified by the policy to default values.
dict->SetString(DefaultSearchManager::kID,
- base::Int64ToString(kInvalidTemplateURLID));
+ base::NumberToString(kInvalidTemplateURLID));
dict->SetInteger(DefaultSearchManager::kPrepopulateID, 0);
dict->SetString(DefaultSearchManager::kSyncGUID, std::string());
dict->SetString(DefaultSearchManager::kOriginatingURL, std::string());
@@ -278,7 +278,7 @@ void DefaultSearchPolicyHandler::EnsureListPrefExists(
base::Value* value;
base::ListValue* list_value;
if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
- prefs->SetValue(path, std::make_unique<base::ListValue>());
+ prefs->SetValue(path, base::Value(base::Value::Type::LIST));
}
} // namespace policy
diff --git a/chromium/components/search_engines/keyword_table.cc b/chromium/components/search_engines/keyword_table.cc
index a5d99229a67..8278864b0f0 100644
--- a/chromium/components/search_engines/keyword_table.cc
+++ b/chromium/components/search_engines/keyword_table.cc
@@ -474,7 +474,7 @@ bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s,
data->alternate_urls.clear();
base::JSONReader json_reader;
std::unique_ptr<base::Value> value(
- json_reader.ReadToValue(s.ColumnString(15)));
+ json_reader.ReadToValueDeprecated(s.ColumnString(15)));
base::ListValue* alternate_urls_value;
if (value.get() && value->GetAsList(&alternate_urls_value)) {
std::string alternate_url;
diff --git a/chromium/components/search_engines/prepopulated_engines.json b/chromium/components/search_engines/prepopulated_engines.json
index 64e8cb51c35..cabb7597170 100644
--- a/chromium/components/search_engines/prepopulated_engines.json
+++ b/chromium/components/search_engines/prepopulated_engines.json
@@ -28,7 +28,7 @@
// Increment this if you change the data in ways that mean users with
// existing data should get a new version. Otherwise, existing data may
// continue to be used and updates made here will not always appear.
- "kCurrentDataVersion": 110
+ "kCurrentDataVersion": 113
},
// The following engines are included in country lists and are added to the
@@ -69,9 +69,9 @@
"favicon_url": "https://www.bing.com/sa/simg/bing_p_rr_teal_min.ico",
"search_url": "https://www.bing.com/search?q={searchTerms}&PC=U316&FORM=CHROMN",
"suggest_url": "https://www.bing.com/osjson.aspx?query={searchTerms}&language={language}&PC=U316",
- "image_url": "https://www.bing.com/images/detail/search?iss=sbi&FORM=CHROMI#enterInsights",
+ "image_url": "https://www.bing.com/images/detail/search?iss=sbiupload&FORM=CHROMI#enterInsights",
"new_tab_url": "https://www.bing.com/chrome/newtab",
- "image_url_post_params": "imgurl={google:imageURL}",
+ "image_url_post_params": "imageBin={google:imageThumbnailBase64}",
"type": "SEARCH_ENGINE_BING",
"id": 3
},
@@ -150,15 +150,6 @@
"id": 67
},
- "parsijoo": {
- "name": "پارسی جو",
- "keyword": "parsijoo.ir",
- "favicon_url": "https://cdn.parsijoo.ir/content3/images/1.0/favicon.ico",
- "search_url": "https://parsijoo.ir/web?q={searchTerms}",
- "type": "SEARCH_ENGINE_PARSIJOO",
- "id": 93
- },
-
"qwant": {
"name": "Qwant",
"keyword": "qwant.com",
diff --git a/chromium/components/search_engines/search_engine_data_type_controller.cc b/chromium/components/search_engines/search_engine_data_type_controller.cc
index 7dc0df59e2f..d1627a535bc 100644
--- a/chromium/components/search_engines/search_engine_data_type_controller.cc
+++ b/chromium/components/search_engines/search_engine_data_type_controller.cc
@@ -4,6 +4,7 @@
#include "components/search_engines/search_engine_data_type_controller.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
namespace browser_sync {
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 145e0c370db..52f9c3e3f49 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
@@ -18,9 +18,8 @@
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/data_type_controller_mock.h"
#include "components/sync/driver/fake_generic_change_processor.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/driver/fake_sync_service.h"
-#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/model/fake_syncable_service.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,25 +32,20 @@ using testing::SetArgPointee;
namespace browser_sync {
namespace {
-class SyncSearchEngineDataTypeControllerTest : public testing::Test,
- public syncer::FakeSyncClient {
+class SyncSearchEngineDataTypeControllerTest : public testing::Test {
public:
SyncSearchEngineDataTypeControllerTest()
- : syncer::FakeSyncClient(&profile_sync_factory_),
- template_url_service_(nullptr, 0),
+ : template_url_service_(nullptr, 0),
search_engine_dtc_(base::RepeatingClosure(),
&sync_service_,
- this,
+ &sync_client_,
&template_url_service_) {
// Disallow the TemplateURLService from loading until
// PreloadTemplateURLService() is called .
template_url_service_.set_disable_load(true);
- }
- // FakeSyncClient overrides.
- base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
- syncer::ModelType type) override {
- return syncable_service_.AsWeakPtr();
+ ON_CALL(sync_client_, GetSyncableServiceForType(syncer::SEARCH_ENGINES))
+ .WillByDefault(testing::Return(syncable_service_.AsWeakPtr()));
}
void TearDown() override {
@@ -67,10 +61,9 @@ class SyncSearchEngineDataTypeControllerTest : public testing::Test,
void SetStartExpectations() {
search_engine_dtc_.SetGenericChangeProcessorFactoryForTest(
- base::WrapUnique<syncer::GenericChangeProcessorFactory>(
- new syncer::FakeGenericChangeProcessorFactory(
- std::make_unique<syncer::FakeGenericChangeProcessor>(
- syncer::SEARCH_ENGINES, this))));
+ std::make_unique<syncer::FakeGenericChangeProcessorFactory>(
+ std::make_unique<syncer::FakeGenericChangeProcessor>(
+ syncer::SEARCH_ENGINES)));
EXPECT_CALL(model_load_callback_, Run(_, _));
}
@@ -87,11 +80,11 @@ class SyncSearchEngineDataTypeControllerTest : public testing::Test,
base::test::ScopedTaskEnvironment task_environment_;
syncer::FakeSyncService sync_service_;
TemplateURLService template_url_service_;
- SearchEngineDataTypeController search_engine_dtc_;
- syncer::SyncApiComponentFactoryMock profile_sync_factory_;
syncer::FakeSyncableService syncable_service_;
+ testing::NiceMock<syncer::SyncClientMock> sync_client_;
syncer::StartCallbackMock start_callback_;
syncer::ModelLoadCallbackMock model_load_callback_;
+ SearchEngineDataTypeController search_engine_dtc_;
};
TEST_F(SyncSearchEngineDataTypeControllerTest, StartURLServiceReady) {
diff --git a/chromium/components/search_engines/template_url.cc b/chromium/components/search_engines/template_url.cc
index 159004bb141..1895362558f 100644
--- a/chromium/components/search_engines/template_url.cc
+++ b/chromium/components/search_engines/template_url.cc
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/base64.h"
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/i18n/case_conversion.h"
@@ -662,6 +663,9 @@ bool TemplateURLRef::ParseParameter(size_t start,
} else if (parameter == "google:imageThumbnail") {
replacements->push_back(
Replacement(TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL, start));
+ } else if (parameter == "google:imageThumbnailBase64") {
+ replacements->push_back(
+ Replacement(TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL_BASE64, start));
} else if (parameter == "google:imageURL") {
replacements->push_back(Replacement(TemplateURLRef::GOOGLE_IMAGE_URL,
start));
@@ -1010,18 +1014,18 @@ std::string TemplateURLRef::HandleReplacements(
case GOOGLE_INPUT_TYPE:
DCHECK(!i->is_post_param);
- HandleReplacement(
- "oit", base::IntToString(search_terms_args.input_type), *i, &url);
+ HandleReplacement("oit",
+ base::NumberToString(search_terms_args.input_type),
+ *i, &url);
break;
case GOOGLE_CONTEXTUAL_SEARCH_VERSION:
if (search_terms_args.contextual_search_params.version >= 0) {
HandleReplacement(
"ctxs",
- base::IntToString(
+ base::NumberToString(
search_terms_args.contextual_search_params.version),
- *i,
- &url);
+ *i, &url);
}
break;
@@ -1034,17 +1038,17 @@ std::string TemplateURLRef::HandleReplacements(
if (params.contextual_cards_version > 0) {
args.push_back("ctxsl_coca=" +
- base::IntToString(params.contextual_cards_version));
+ base::NumberToString(params.contextual_cards_version));
}
if (!params.home_country.empty())
args.push_back("ctxs_hc=" + params.home_country);
if (params.previous_event_id != 0) {
args.push_back("ctxsl_pid=" +
- base::Int64ToString(params.previous_event_id));
+ base::NumberToString(params.previous_event_id));
}
if (params.previous_event_results != 0) {
args.push_back("ctxsl_per=" +
- base::IntToString(params.previous_event_results));
+ base::NumberToString(params.previous_event_results));
}
HandleReplacement(std::string(), base::JoinString(args, "&"), *i, &url);
@@ -1064,8 +1068,9 @@ std::string TemplateURLRef::HandleReplacements(
if (search_terms_args.page_classification !=
metrics::OmniboxEventProto::INVALID_SPEC) {
HandleReplacement(
- "pgcl", base::IntToString(search_terms_args.page_classification),
- *i, &url);
+ "pgcl",
+ base::NumberToString(search_terms_args.page_classification), *i,
+ &url);
}
break;
@@ -1156,6 +1161,16 @@ std::string TemplateURLRef::HandleReplacements(
post_params_[i->index].content_type = "image/jpeg";
break;
+ case GOOGLE_IMAGE_THUMBNAIL_BASE64: {
+ std::string base64_thumbnail_content;
+ base::Base64Encode(search_terms_args.image_thumbnail_content,
+ &base64_thumbnail_content);
+ HandleReplacement(std::string(), base64_thumbnail_content, *i, &url);
+ if (i->is_post_param)
+ post_params_[i->index].content_type = "image/jpeg";
+ break;
+ }
+
case GOOGLE_IMAGE_URL:
if (search_terms_args.image_url.is_valid()) {
HandleReplacement(
@@ -1165,19 +1180,19 @@ std::string TemplateURLRef::HandleReplacements(
case GOOGLE_IMAGE_ORIGINAL_WIDTH:
if (!search_terms_args.image_original_size.IsEmpty()) {
- HandleReplacement(
- std::string(),
- base::IntToString(search_terms_args.image_original_size.width()),
- *i, &url);
+ HandleReplacement(std::string(),
+ base::NumberToString(
+ search_terms_args.image_original_size.width()),
+ *i, &url);
}
break;
case GOOGLE_IMAGE_ORIGINAL_HEIGHT:
if (!search_terms_args.image_original_size.IsEmpty()) {
- HandleReplacement(
- std::string(),
- base::IntToString(search_terms_args.image_original_size.height()),
- *i, &url);
+ HandleReplacement(std::string(),
+ base::NumberToString(
+ search_terms_args.image_original_size.height()),
+ *i, &url);
}
break;
diff --git a/chromium/components/search_engines/template_url.h b/chromium/components/search_engines/template_url.h
index dab9956742c..21c68f029f1 100644
--- a/chromium/components/search_engines/template_url.h
+++ b/chromium/components/search_engines/template_url.h
@@ -329,6 +329,7 @@ class TemplateURLRef {
GOOGLE_IMAGE_ORIGINAL_WIDTH,
GOOGLE_IMAGE_SEARCH_SOURCE,
GOOGLE_IMAGE_THUMBNAIL,
+ GOOGLE_IMAGE_THUMBNAIL_BASE64,
GOOGLE_IMAGE_URL,
GOOGLE_INPUT_TYPE,
GOOGLE_IOS_SEARCH_LANGUAGE,
diff --git a/chromium/components/search_engines/template_url_data_util.cc b/chromium/components/search_engines/template_url_data_util.cc
index 91bdafe74f3..b03157ea349 100644
--- a/chromium/components/search_engines/template_url_data_util.cc
+++ b/chromium/components/search_engines/template_url_data_util.cc
@@ -114,7 +114,7 @@ std::unique_ptr<TemplateURLData> TemplateURLDataFromDictionary(
std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
const TemplateURLData& data) {
auto url_dict = std::make_unique<base::DictionaryValue>();
- url_dict->SetString(DefaultSearchManager::kID, base::Int64ToString(data.id));
+ url_dict->SetString(DefaultSearchManager::kID, base::NumberToString(data.id));
url_dict->SetString(DefaultSearchManager::kShortName, data.short_name());
url_dict->SetString(DefaultSearchManager::kKeyword, data.keyword());
url_dict->SetInteger(DefaultSearchManager::kPrepopulateID,
@@ -145,14 +145,15 @@ std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
url_dict->SetBoolean(DefaultSearchManager::kSafeForAutoReplace,
data.safe_for_autoreplace);
- url_dict->SetString(DefaultSearchManager::kDateCreated,
- base::Int64ToString(data.date_created.ToInternalValue()));
+ url_dict->SetString(
+ DefaultSearchManager::kDateCreated,
+ base::NumberToString(data.date_created.ToInternalValue()));
url_dict->SetString(
DefaultSearchManager::kLastModified,
- base::Int64ToString(data.last_modified.ToInternalValue()));
+ base::NumberToString(data.last_modified.ToInternalValue()));
url_dict->SetString(
DefaultSearchManager::kLastVisited,
- base::Int64ToString(data.last_visited.ToInternalValue()));
+ base::NumberToString(data.last_visited.ToInternalValue()));
url_dict->SetInteger(DefaultSearchManager::kUsageCount, data.usage_count);
auto alternate_urls = std::make_unique<base::ListValue>();
diff --git a/chromium/components/search_engines/template_url_fetcher.cc b/chromium/components/search_engines/template_url_fetcher.cc
index eafa853b734..d136273e179 100644
--- a/chromium/components/search_engines/template_url_fetcher.cc
+++ b/chromium/components/search_engines/template_url_fetcher.cc
@@ -4,6 +4,7 @@
#include "components/search_engines/template_url_fetcher.h"
+#include "base/bind.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chromium/components/search_engines/template_url_prepopulate_data.cc b/chromium/components/search_engines/template_url_prepopulate_data.cc
index e8042c05028..5fd11a9daa8 100644
--- a/chromium/components/search_engines/template_url_prepopulate_data.cc
+++ b/chromium/components/search_engines/template_url_prepopulate_data.cc
@@ -398,7 +398,6 @@ const PrepopulatedEngine* const engines_IR[] = {
&google,
&bing,
&yahoo,
- &parsijoo,
};
// Iceland
@@ -902,7 +901,6 @@ const PrepopulatedEngine* const kAllEngines[] = {
&google,
&mail_ru,
&naver,
- &parsijoo,
&qwant,
&seznam,
&sogou,
diff --git a/chromium/components/search_engines/template_url_service.cc b/chromium/components/search_engines/template_url_service.cc
index 2f84d322981..e0ef9dc1c28 100644
--- a/chromium/components/search_engines/template_url_service.cc
+++ b/chromium/components/search_engines/template_url_service.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/debug/crash_logging.h"
#include "base/format_macros.h"
diff --git a/chromium/components/search_engines/template_url_service_util_unittest.cc b/chromium/components/search_engines/template_url_service_util_unittest.cc
index 527d8d57dfe..644696f0b41 100644
--- a/chromium/components/search_engines/template_url_service_util_unittest.cc
+++ b/chromium/components/search_engines/template_url_service_util_unittest.cc
@@ -38,7 +38,7 @@ std::unique_ptr<TemplateURL> CreatePrepopulateTemplateURL(
*CreatePrepopulateTemplateURLData(prepopulate_id, keyword, id));
}
-}; // namespace
+} // namespace
TEST(TemplateURLServiceUtilTest, RemoveDuplicatePrepopulateIDs) {
std::vector<std::unique_ptr<TemplateURLData>> prepopulated_turls;
diff --git a/chromium/components/search_engines/template_url_unittest.cc b/chromium/components/search_engines/template_url_unittest.cc
index 8a4efdf3f5d..b4a4c96c3b9 100644
--- a/chromium/components/search_engines/template_url_unittest.cc
+++ b/chromium/components/search_engines/template_url_unittest.cc
@@ -4,6 +4,7 @@
#include <stddef.h>
+#include "base/base64.h"
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/i18n/case_conversion.h"
@@ -172,7 +173,8 @@ TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
const char kValidPostParamsString[] =
"image_content={google:imageThumbnail},image_url={google:imageURL},"
"sbisrc={google:imageSearchSource},language={language},empty_param=,"
- "constant_param=constant,width={google:imageOriginalWidth}";
+ "constant_param=constant,width={google:imageOriginalWidth},"
+ "base64_image_content={google:imageThumbnailBase64}";
const char KImageSearchURL[] = "http://foo.com/sbi";
TemplateURLData data;
@@ -220,7 +222,7 @@ TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
url.image_url_ref().replacements_;
const TemplateURLRef::PostParams& post_params =
url.image_url_ref().post_params_;
- EXPECT_EQ(7U, post_params.size());
+ EXPECT_EQ(8U, post_params.size());
for (auto i = post_params.begin(); i != post_params.end(); ++i) {
auto j = replacements.begin();
for (; j != replacements.end(); ++j) {
@@ -228,9 +230,9 @@ TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
static_cast<size_t>(i - post_params.begin())) {
switch (j->type) {
case TemplateURLRef::GOOGLE_IMAGE_ORIGINAL_WIDTH:
- ExpectPostParamIs(*i, "width",
- base::IntToString(
- search_args.image_original_size.width()));
+ ExpectPostParamIs(
+ *i, "width",
+ base::NumberToString(search_args.image_original_size.width()));
break;
case TemplateURLRef::GOOGLE_IMAGE_SEARCH_SOURCE:
ExpectPostParamIs(*i, "sbisrc",
@@ -241,6 +243,14 @@ TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
search_args.image_thumbnail_content,
"image/jpeg");
break;
+ case TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL_BASE64: {
+ std::string base64_image_content;
+ base::Base64Encode(search_args.image_thumbnail_content,
+ &base64_image_content);
+ ExpectPostParamIs(*i, "base64_image_content", base64_image_content,
+ "image/jpeg");
+ break;
+ }
case TemplateURLRef::GOOGLE_IMAGE_URL:
ExpectPostParamIs(*i, "image_url", search_args.image_url.spec());
break;
diff --git a/chromium/components/search_provider_logos/google_logo_api.cc b/chromium/components/search_provider_logos/google_logo_api.cc
index 2ef1c087c36..fc0e3e98ee2 100644
--- a/chromium/components/search_provider_logos/google_logo_api.cc
+++ b/chromium/components/search_provider_logos/google_logo_api.cc
@@ -150,8 +150,9 @@ std::unique_ptr<EncodedLogo> ParseDoodleLogoResponse(
std::string error_string;
int error_line;
int error_col;
- std::unique_ptr<base::Value> value = base::JSONReader::ReadAndReturnError(
- response_sp, 0, &error_code, &error_string, &error_line, &error_col);
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ response_sp, 0, &error_code, &error_string, &error_line, &error_col);
if (!value) {
LOG(WARNING) << error_string << " at " << error_line << ":" << error_col;
return nullptr;
diff --git a/chromium/components/search_provider_logos/logo_cache.cc b/chromium/components/search_provider_logos/logo_cache.cc
index f3508053863..c4bccf9b2bc 100644
--- a/chromium/components/search_provider_logos/logo_cache.cc
+++ b/chromium/components/search_provider_logos/logo_cache.cc
@@ -65,7 +65,7 @@ void SetTimeValue(base::DictionaryValue& dict,
const std::string& key,
const base::Time& time) {
int64_t internal_time_value = time.ToInternalValue();
- dict.SetString(key, base::Int64ToString(internal_time_value));
+ dict.SetString(key, base::NumberToString(internal_time_value));
}
LogoType LogoTypeFromString(base::StringPiece type) {
@@ -172,7 +172,7 @@ std::unique_ptr<EncodedLogo> LogoCache::GetCachedLogo() {
std::unique_ptr<LogoMetadata> LogoCache::LogoMetadataFromString(
const std::string& str,
int* logo_num_bytes) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(str);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(str);
base::DictionaryValue* dict;
if (!value || !value->GetAsDictionary(&dict))
return nullptr;
diff --git a/chromium/components/search_provider_logos/logo_service_impl.cc b/chromium/components/search_provider_logos/logo_service_impl.cc
index e2a2de7c4f9..543ec27d400 100644
--- a/chromium/components/search_provider_logos/logo_service_impl.cc
+++ b/chromium/components/search_provider_logos/logo_service_impl.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/macros.h"
diff --git a/chromium/components/search_provider_logos/logo_service_impl_unittest.cc b/chromium/components/search_provider_logos/logo_service_impl_unittest.cc
index 66d559a9197..cef9272f3cc 100644
--- a/chromium/components/search_provider_logos/logo_service_impl_unittest.cc
+++ b/chromium/components/search_provider_logos/logo_service_impl_unittest.cc
@@ -72,12 +72,6 @@ namespace {
using MockLogoCallback = base::MockCallback<LogoCallback>;
using MockEncodedLogoCallback = base::MockCallback<EncodedLogoCallback>;
-#if defined(OS_CHROMEOS)
-using SigninManagerForTest = FakeSigninManagerBase;
-#else
-using SigninManagerForTest = FakeSigninManager;
-#endif // OS_CHROMEOS
-
scoped_refptr<base::RefCountedString> EncodeBitmapAsPNG(
const SkBitmap& bitmap) {
scoped_refptr<base::RefCountedMemory> png_bytes =
diff --git a/chromium/components/search_provider_logos/switches.cc b/chromium/components/search_provider_logos/switches.cc
index cbb86d84212..0ee18289cfc 100644
--- a/chromium/components/search_provider_logos/switches.cc
+++ b/chromium/components/search_provider_logos/switches.cc
@@ -9,6 +9,12 @@ namespace switches {
// Overrides the URL used to fetch the current Google Doodle.
// Example: https://www.google.com/async/ddljson
+// Testing? Try:
+// https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_android0.json
+// https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_android1.json
+// https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_android2.json
+// https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_android3.json
+// https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_android4.json
const char kGoogleDoodleUrl[] = "google-doodle-url";
// Use a static URL for the logo of the default search engine.
@@ -16,6 +22,9 @@ const char kGoogleDoodleUrl[] = "google-doodle-url";
const char kSearchProviderLogoURL[] = "search-provider-logo-url";
// Overrides the Doodle URL to use for third-party search engines.
+// Testing? Try:
+// https://www.gstatic.com/chrome/ntp/doodle_test/third_party_simple.json
+// https://www.gstatic.com/chrome/ntp/doodle_test/third_party_animated.json
const char kThirdPartyDoodleURL[] = "third-party-doodle-url";
} // namespace switches
diff --git a/chromium/components/security_interstitials/content/BUILD.gn b/chromium/components/security_interstitials/content/BUILD.gn
index 7d1a57ea2e2..e26ccdd5567 100644
--- a/chromium/components/security_interstitials/content/BUILD.gn
+++ b/chromium/components/security_interstitials/content/BUILD.gn
@@ -6,6 +6,8 @@ static_library("security_interstitial_page") {
sources = [
"connection_help_ui.cc",
"connection_help_ui.h",
+ "origin_policy_interstitial_page.cc",
+ "origin_policy_interstitial_page.h",
"origin_policy_ui.cc",
"origin_policy_ui.h",
"security_interstitial_controller_client.cc",
diff --git a/chromium/components/security_interstitials/content/origin_policy_interstitial_page.cc b/chromium/components/security_interstitials/content/origin_policy_interstitial_page.cc
new file mode 100644
index 00000000000..3697645af24
--- /dev/null
+++ b/chromium/components/security_interstitials/content/origin_policy_interstitial_page.cc
@@ -0,0 +1,130 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/security_interstitials/content/origin_policy_interstitial_page.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/strings/grit/components_strings.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/origin_policy_commands.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace security_interstitials {
+
+OriginPolicyInterstitialPage::OriginPolicyInterstitialPage(
+ content::WebContents* web_contents,
+ const GURL& request_url,
+ std::unique_ptr<SecurityInterstitialControllerClient> controller,
+ content::OriginPolicyErrorReason error_reason)
+ : SecurityInterstitialPage(web_contents,
+ request_url,
+ std::move(controller)),
+ error_reason_(error_reason) {}
+
+OriginPolicyInterstitialPage::~OriginPolicyInterstitialPage() {}
+
+void OriginPolicyInterstitialPage::OnInterstitialClosing() {}
+
+bool OriginPolicyInterstitialPage::ShouldCreateNewNavigation() const {
+ return false;
+}
+
+void OriginPolicyInterstitialPage::PopulateInterstitialStrings(
+ base::DictionaryValue* load_time_data) {
+ load_time_data->SetString("type", "ORIGIN_POLICY");
+
+ // User may choose to ignore the warning & proceed to the site.
+ load_time_data->SetBoolean("overridable", true);
+
+ // Custom messages depending on the OriginPolicyErrorReason:
+ int explanation_paragraph_id = IDS_ORIGIN_POLICY_EXPLANATION_OTHER;
+ switch (error_reason_) {
+ case content::OriginPolicyErrorReason::kCannotLoadPolicy:
+ explanation_paragraph_id = IDS_ORIGIN_POLICY_EXPLANATION_CANNOT_LOAD;
+ break;
+ case content::OriginPolicyErrorReason::kPolicyShouldNotRedirect:
+ explanation_paragraph_id =
+ IDS_ORIGIN_POLICY_EXPLANATION_SHOULD_NOT_REDIRECT;
+ break;
+ case content::OriginPolicyErrorReason::kOther:
+ explanation_paragraph_id = IDS_ORIGIN_POLICY_EXPLANATION_OTHER;
+ break;
+ }
+
+ // Variables in IDR_SECURITY_INTERSTITIAL_HTML / interstitial_large.html,
+ // resources defined in security_interstitials_strings.grdp.
+ const struct {
+ const char* name;
+ int id;
+ } messages[] = {
+ {"closeDetails", IDS_ORIGIN_POLICY_CLOSE},
+ {"explanationParagraph", explanation_paragraph_id},
+ {"finalParagraph", IDS_ORIGIN_POLICY_FINAL_PARAGRAPH},
+ {"heading", IDS_ORIGIN_POLICY_HEADING},
+ {"openDetails", IDS_ORIGIN_POLICY_DETAILS},
+ {"primaryButtonText", IDS_ORIGIN_POLICY_BUTTON},
+ {"primaryParagraph", IDS_ORIGIN_POLICY_INFO},
+ {"recurrentErrorParagraph", IDS_ORIGIN_POLICY_INFO2},
+ {"tabTitle", IDS_ORIGIN_POLICY_TITLE},
+ };
+ // We interpolate _all_ strings with URL ($1) and origin ($2).
+ const std::vector<base::string16> message_params = {
+ base::ASCIIToUTF16(request_url().spec()),
+ base::ASCIIToUTF16(url::Origin::Create(request_url()).Serialize()),
+ };
+ for (const auto& message : messages) {
+ load_time_data->SetString(
+ message.name,
+ base::ReplaceStringPlaceholders(l10n_util::GetStringUTF16(message.id),
+ message_params, nullptr));
+ };
+
+ // Selectively enable certain UI elements.
+ load_time_data->SetBoolean(
+ "hide_primary_button",
+ !web_contents()->GetController().CanGoBack() ||
+ load_time_data->FindStringKey("primaryButtonText")->empty());
+ load_time_data->SetBoolean(
+ "show_recurrent_error_paragraph",
+ !load_time_data->FindStringKey("recurrentErrorParagraph")->empty());
+}
+
+void OriginPolicyInterstitialPage::CommandReceived(const std::string& command) {
+ // The command string we get passed in is interstitial_commands.mojom turned
+ // into a number turned into a string.
+ //
+ // TODO(carlosil): After non-committed insterstitials have been removed this
+ // should be cleaned up to use enum values (or somesuch).
+ if (command == "0") {
+ OnDontProceed();
+ } else if (command == "1") {
+ OnProceed();
+ } else if (command == "2") {
+ // "Advanced" button, which shows extra text. This is handled within
+ // the page.
+ } else {
+ NOTREACHED();
+ }
+}
+
+void OriginPolicyInterstitialPage::OnProceed() {
+ content::OriginPolicyAddExceptionFor(request_url());
+ web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
+}
+
+void OriginPolicyInterstitialPage::OnDontProceed() {
+ // "Go Back" / "Don't Proceed" button should be disabled if we can't go back.
+ DCHECK(web_contents()->GetController().CanGoBack());
+ web_contents()->GetController().GoBack();
+}
+
+} // namespace security_interstitials
diff --git a/chromium/components/security_interstitials/content/origin_policy_interstitial_page.h b/chromium/components/security_interstitials/content/origin_policy_interstitial_page.h
new file mode 100644
index 00000000000..87d43c3aebc
--- /dev/null
+++ b/chromium/components/security_interstitials/content/origin_policy_interstitial_page.h
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_ORIGIN_POLICY_INTERSTITIAL_PAGE_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_ORIGIN_POLICY_INTERSTITIAL_PAGE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "components/security_interstitials/content/security_interstitial_controller_client.h"
+#include "components/security_interstitials/content/security_interstitial_page.h"
+#include "content/public/browser/interstitial_page_delegate.h"
+#include "content/public/browser/origin_policy_error_reason.h"
+
+#include "url/gurl.h"
+
+namespace content {
+class WebContents;
+} // namespace content
+
+namespace security_interstitials {
+class SecurityInterstitialControllerClient;
+
+class OriginPolicyInterstitialPage : public SecurityInterstitialPage {
+ public:
+ OriginPolicyInterstitialPage(
+ content::WebContents* web_contents,
+ const GURL& request_url,
+ std::unique_ptr<SecurityInterstitialControllerClient> controller,
+ content::OriginPolicyErrorReason error_reason);
+
+ ~OriginPolicyInterstitialPage() override;
+
+ void OnInterstitialClosing() override;
+
+ void CommandReceived(const std::string& command) override;
+ void OnProceed() override;
+ void OnDontProceed() override;
+
+ protected:
+ bool ShouldCreateNewNavigation() const override;
+ void PopulateInterstitialStrings(base::DictionaryValue*) override;
+
+ private:
+ content::OriginPolicyErrorReason error_reason_;
+
+ DISALLOW_COPY_AND_ASSIGN(OriginPolicyInterstitialPage);
+};
+
+} // namespace security_interstitials
+
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_ORIGIN_POLICY_INTERSTITIAL_PAGE_H_
diff --git a/chromium/components/security_interstitials/content/origin_policy_ui.cc b/chromium/components/security_interstitials/content/origin_policy_ui.cc
index 9f83d411439..5ed3836f778 100644
--- a/chromium/components/security_interstitials/content/origin_policy_ui.cc
+++ b/chromium/components/security_interstitials/content/origin_policy_ui.cc
@@ -4,36 +4,60 @@
#include "components/security_interstitials/content/origin_policy_ui.h"
-#include "components/grit/components_resources.h"
-#include "third_party/zlib/google/compression_utils.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/template_expressions.h"
+#include <string>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/optional.h"
+#include "components/security_interstitials/content/origin_policy_interstitial_page.h"
+#include "components/security_interstitials/content/security_interstitial_tab_helper.h"
+#include "components/security_interstitials/core/metrics_helper.h"
+#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"
-#include "url/origin.h"
namespace security_interstitials {
-base::Optional<std::string> OriginPolicyUI::GetErrorPage(
+namespace {
+
+std::unique_ptr<SecurityInterstitialPage> GetErrorPageImpl(
+ content::OriginPolicyErrorReason error_reason,
+ content::WebContents* web_contents,
+ const GURL& url) {
+ MetricsHelper::ReportDetails report_details;
+ report_details.metric_prefix = "origin_policy";
+ std::unique_ptr<SecurityInterstitialControllerClient> controller =
+ std::make_unique<SecurityInterstitialControllerClient>(
+ web_contents,
+ std::make_unique<MetricsHelper>(url, report_details, nullptr),
+ nullptr, /* pref service: can be null */
+ "", GURL());
+ return std::make_unique<security_interstitials::OriginPolicyInterstitialPage>(
+ web_contents, url, std::move(controller), error_reason);
+}
+
+} // namespace
+
+base::Optional<std::string> OriginPolicyUI::GetErrorPageAsHTML(
+ content::OriginPolicyErrorReason error_reason,
+ content::NavigationHandle* handle) {
+ DCHECK(handle);
+ std::unique_ptr<SecurityInterstitialPage> page(GetErrorPageImpl(
+ error_reason, handle->GetWebContents(), handle->GetURL()));
+ std::string html = page->GetHTMLContents();
+
+ // The page object is "associated" with the web contents, and this is how
+ // the interstitial infrastructure will find this instance again.
+ security_interstitials::SecurityInterstitialTabHelper::AssociateBlockingPage(
+ handle->GetWebContents(), handle->GetNavigationId(), std::move(page));
+
+ return html;
+}
+
+SecurityInterstitialPage* OriginPolicyUI::GetBlockingPage(
content::OriginPolicyErrorReason error_reason,
- const url::Origin& origin,
+ content::WebContents* web_contents,
const GURL& url) {
- const base::StringPiece raw_interstitial_page_resource =
- ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_SECURITY_INTERSTITIAL_ORIGIN_POLICY_HTML);
-
- // The resource is gzip compressed.
- std::string interstitial_page_resource;
- interstitial_page_resource.resize(
- compression::GetUncompressedSize(raw_interstitial_page_resource));
- base::StringPiece buffer(interstitial_page_resource.c_str(),
- interstitial_page_resource.size());
- CHECK(compression::GzipUncompress(raw_interstitial_page_resource, buffer));
-
- ui::TemplateReplacements params;
- params["url"] = url.spec();
- params["origin"] = origin.Serialize();
-
- return ui::ReplaceTemplateExpressions(interstitial_page_resource, params);
+ return GetErrorPageImpl(error_reason, web_contents, url).release();
}
} // namespace security_interstitials
diff --git a/chromium/components/security_interstitials/content/origin_policy_ui.h b/chromium/components/security_interstitials/content/origin_policy_ui.h
index 6f8fbd43c15..06a27c51e7c 100644
--- a/chromium/components/security_interstitials/content/origin_policy_ui.h
+++ b/chromium/components/security_interstitials/content/origin_policy_ui.h
@@ -7,26 +7,36 @@
#include <memory>
+#include <string>
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string16.h"
class GURL;
-namespace url {
-class Origin;
-} // namespace url
+
namespace content {
+class NavigationHandle;
+class WebContents;
enum class OriginPolicyErrorReason;
} // namespace content
namespace security_interstitials {
+class SecurityInterstitialPage;
// A helper class to build the error page for Origin Policy errors.
class OriginPolicyUI {
public:
- static base::Optional<std::string> GetErrorPage(
+ // Create the error page for the given NavigationHandle.
+ // This is intended to implement the ContentBrowserClient interface.
+ static base::Optional<std::string> GetErrorPageAsHTML(
+ content::OriginPolicyErrorReason error_reason,
+ content::NavigationHandle* handle);
+
+ // Create the error page instance for the given WebContents + URL.
+ // This is intended for use by debug functions (like chrome:://interstitials).
+ static SecurityInterstitialPage* GetBlockingPage(
content::OriginPolicyErrorReason error_reason,
- const url::Origin& origin,
+ content::WebContents* web_contents,
const GURL& url);
};
diff --git a/chromium/components/security_interstitials/content/security_interstitial_page.cc b/chromium/components/security_interstitials/content/security_interstitial_page.cc
index f81a05e15fc..bebef319828 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_page.cc
+++ b/chromium/components/security_interstitials/content/security_interstitial_page.cc
@@ -66,6 +66,10 @@ void SecurityInterstitialPage::DontCreateViewForTesting() {
create_view_ = false;
}
+bool SecurityInterstitialPage::ShouldDisplayURL() const {
+ return true;
+}
+
std::string SecurityInterstitialPage::GetHTMLContents() {
base::DictionaryValue load_time_data;
PopulateInterstitialStrings(&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 0855d45e1e9..7450fb03daf 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_page.h
+++ b/chromium/components/security_interstitials/content/security_interstitial_page.h
@@ -50,6 +50,10 @@ class SecurityInterstitialPage : public content::InterstitialPageDelegate {
// to e.g. update metrics.
virtual void OnInterstitialClosing() = 0;
+ // Whether a URL should be displayed on this interstitial page. This is
+ // respected by committed interstitials only.
+ virtual bool ShouldDisplayURL() const;
+
protected:
// Returns true if the interstitial should create a new navigation entry.
virtual bool ShouldCreateNewNavigation() const = 0;
diff --git a/chromium/components/security_interstitials/content/security_interstitial_tab_helper.cc b/chromium/components/security_interstitials/content/security_interstitial_tab_helper.cc
index 09710085b2d..4458f5dbe62 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_tab_helper.cc
+++ b/chromium/components/security_interstitials/content/security_interstitial_tab_helper.cc
@@ -60,6 +60,15 @@ void SecurityInterstitialTabHelper::AssociateBlockingPage(
helper->SetBlockingPage(navigation_id, std::move(blocking_page));
}
+bool SecurityInterstitialTabHelper::ShouldDisplayURL() const {
+ CHECK(IsDisplayingInterstitial());
+ return blocking_page_for_currently_committed_navigation_->ShouldDisplayURL();
+}
+
+bool SecurityInterstitialTabHelper::IsDisplayingInterstitial() const {
+ return blocking_page_for_currently_committed_navigation_ != nullptr;
+}
+
security_interstitials::SecurityInterstitialPage*
SecurityInterstitialTabHelper::
GetBlockingPageForCurrentlyCommittedNavigationForTesting() {
diff --git a/chromium/components/security_interstitials/content/security_interstitial_tab_helper.h b/chromium/components/security_interstitials/content/security_interstitial_tab_helper.h
index bafc5e673c4..62dbb0d3d95 100644
--- a/chromium/components/security_interstitials/content/security_interstitial_tab_helper.h
+++ b/chromium/components/security_interstitials/content/security_interstitial_tab_helper.h
@@ -43,6 +43,12 @@ class SecurityInterstitialTabHelper
std::unique_ptr<security_interstitials::SecurityInterstitialPage>
blocking_page);
+ // Determines whether a URL should be shown on the current navigation page.
+ bool ShouldDisplayURL() const;
+
+ // Whether this tab helper is tracking a currently-displaying interstitial.
+ bool IsDisplayingInterstitial() const;
+
security_interstitials::SecurityInterstitialPage*
GetBlockingPageForCurrentlyCommittedNavigationForTesting();
diff --git a/chromium/components/security_interstitials/content/unsafe_resource.cc b/chromium/components/security_interstitials/content/unsafe_resource.cc
index f9693b52796..f9ed7717418 100644
--- a/chromium/components/security_interstitials/content/unsafe_resource.cc
+++ b/chromium/components/security_interstitials/content/unsafe_resource.cc
@@ -22,7 +22,7 @@ content::WebContents* GetWebContentsByFrameID(int render_process_id,
return content::WebContents::FromRenderFrameHost(render_frame_host);
}
-}; // namespace
+} // namespace
UnsafeResource::UnsafeResource()
: is_subresource(false),
diff --git a/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h
index c8fe2e6fb6d..18e057ed551 100644
--- a/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h
+++ b/chromium/components/security_interstitials/core/base_safe_browsing_error_ui.h
@@ -140,7 +140,7 @@ class BaseSafeBrowsingErrorUI {
const std::string app_locale() const { return app_locale_; }
- ControllerClient* controller() { return controller_; };
+ ControllerClient* controller() { return controller_; }
GURL request_url() const { return request_url_; }
GURL main_frame_url() const { return main_frame_url_; }
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/1x/info.png b/chromium/components/security_interstitials/core/browser/resources/images/1x/info.png
new file mode 100644
index 00000000000..d771d656440
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/1x/info.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/images/2x/info.png b/chromium/components/security_interstitials/core/browser/resources/images/2x/info.png
new file mode 100644
index 00000000000..711fb09a621
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/images/2x/info.png
Binary files differ
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_large.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_large.html
index 56d4eb1c3fe..62ee7c467fa 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_large.html
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_large.html
@@ -10,6 +10,7 @@
<link rel="stylesheet" href="../../common/resources/interstitial_common.css">
<link rel="stylesheet" href="interstitial_badclock.css">
<link rel="stylesheet" href="interstitial_captiveportal.css">
+ <link rel="stylesheet" href="interstitial_lookalikeurl.css">
<link rel="stylesheet" href="interstitial_safebrowsing.css">
<link rel="stylesheet" href="interstitial_ssl.css">
<script src="../../../../../ui/webui/resources/js/util.js"></script>
@@ -25,7 +26,7 @@
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
- <h1>$i18n{heading}</h1>
+ <h1>$i18nRaw{heading}</h1>
<p>$i18nRaw{primaryParagraph}</p>
<div id="debugging">
<div id="error-code" class="error-code"></div>
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_large.js b/chromium/components/security_interstitials/core/browser/resources/interstitial_large.js
index 8756cab8c6b..eb4d75e2bb5 100644
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_large.js
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_large.js
@@ -68,6 +68,7 @@ function setupEvents() {
var ssl = interstitialType == 'SSL';
var captivePortal = interstitialType == 'CAPTIVE_PORTAL';
var badClock = ssl && loadTimeData.getBoolean('bad_clock');
+ var lookalike = interstitialType == 'LOOKALIKE';
var billing = interstitialType == 'SAFEBROWSING' &&
loadTimeData.getBoolean('billing');
var hidePrimaryButton = loadTimeData.getBoolean('hide_primary_button');
@@ -82,6 +83,8 @@ function setupEvents() {
$('body').classList.add('captive-portal');
} else if (billing) {
$('body').classList.add('safe-browsing-billing');
+ } else if (lookalike) {
+ $('body').classList.add('lookalike-url');
} else {
$('body').classList.add('safe-browsing');
// Override the default theme color.
@@ -110,15 +113,38 @@ function setupEvents() {
break;
case 'SAFEBROWSING':
+ case 'ORIGIN_POLICY':
sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
break;
+ case 'LOOKALIKE':
+ // Primary button is hidden for lookalike URL interstitial.
+ break;
+
default:
throw 'Invalid interstitial type';
}
});
}
+ if (lookalike) {
+ var proceed_button = 'proceed-button';
+ var dont_proceed_link = 'dont-proceed-link';
+ $('primary-button').classList.add(HIDDEN_CLASS);
+ $(proceed_button).classList.remove(HIDDEN_CLASS);
+
+ $(proceed_button).textContent =
+ loadTimeData.getString('proceedButtonText');
+
+ $(proceed_button).addEventListener('click', function(event) {
+ sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
+ });
+
+ $(dont_proceed_link).addEventListener('click', function(event) {
+ sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
+ });
+ }
+
if (overridable) {
var overrideElement = billing ? 'proceed-button' : 'proceed-link';
// Captive portal page isn't overridable.
@@ -156,8 +182,8 @@ function setupEvents() {
});
}
- if (captivePortal || billing) {
- // Captive portal and billing pages don't have details button.
+ if (captivePortal || billing || lookalike) {
+ // Captive portal, billing and lookalike pages don't have details button.
$('details-button').classList.add('hidden');
} else {
$('details-button').addEventListener('click', function(event) {
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_lookalikeurl.css b/chromium/components/security_interstitials/core/browser/resources/interstitial_lookalikeurl.css
new file mode 100644
index 00000000000..56e60afed62
--- /dev/null
+++ b/chromium/components/security_interstitials/core/browser/resources/interstitial_lookalikeurl.css
@@ -0,0 +1,14 @@
+/* Copyright 2019 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+.lookalike-url a {
+ color: var(--google-blue-700);
+ text-decoration: none;
+}
+
+.lookalike-url .icon {
+ background-image: -webkit-image-set(
+ url(images/1x/info.png) 1x,
+ url(images/2x/info.png) 2x);
+}
diff --git a/chromium/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html b/chromium/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html
deleted file mode 100644
index d47e55686b2..00000000000
--- a/chromium/components/security_interstitials/core/browser/resources/interstitial_origin_policy.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!doctype html>
-<html>
-<head>
- <title>Origin Policy Error</title>
-</head>
-<body>
- <p>The server has requested that an
- <a href="https://github.com/WICG/origin-policy">Origin Policy</a>
- is applied to this origin, but it is not currently serving a suitable
- policy.</p>
- <p><ul>
- <li>You're trying to go to: $i18n{url}</li>
- <li>The policy applies to: $i18n{origin}</li>
- </ul></p>
-</body>
-</html>
diff --git a/chromium/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/chromium/components/security_interstitials/core/browser/resources/list_of_interstitials.html
index 5bdf2bc50c1..950702c32c2 100644
--- a/chromium/components/security_interstitials/core/browser/resources/list_of_interstitials.html
+++ b/chromium/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -117,5 +117,19 @@
</a>
</li>
</ul>
+ <h3>Origin Policy</h3>
+ <ul>
+ <li>
+ <a href="origin_policy">
+ Origin Policy Error
+ </a>
+ </li>
+ </ul>
+ <h3>Lookalike URL Warnings</h3>
+ <ul>
+ <li>
+ <a href="lookalike">Lookalike URL</a>
+ </li>
+ </ul>
</body>
</html>
diff --git a/chromium/components/security_interstitials/core/common/resources/interstitial_common.css b/chromium/components/security_interstitials/core/common/resources/interstitial_common.css
index e25f12a9067..48255f63b40 100644
--- a/chromium/components/security_interstitials/core/common/resources/interstitial_common.css
+++ b/chromium/components/security_interstitials/core/common/resources/interstitial_common.css
@@ -22,6 +22,7 @@ button {
.bad-clock button,
.captive-portal button,
+.lookalike-url button,
.main-frame-blocked button,
.neterror button,
.offline button,
diff --git a/chromium/components/security_interstitials/core/controller_client.h b/chromium/components/security_interstitials/core/controller_client.h
index 603bd595aea..a18a597fe53 100644
--- a/chromium/components/security_interstitials/core/controller_client.h
+++ b/chromium/components/security_interstitials/core/controller_client.h
@@ -75,6 +75,7 @@ class ControllerClient {
// Close the error and go back to the previous page. This applies to
// situations where navigation is blocked before committing.
+ // TODO(crbug.com/928901) - rename this to NavigateAway or similar.
virtual void GoBack() = 0;
// Whether it is possible to go 'Back to safety'.
virtual bool CanGoBack() = 0;
diff --git a/chromium/components/security_interstitials/core/metrics_helper.cc b/chromium/components/security_interstitials/core/metrics_helper.cc
index 75e442c46fe..48dc619d0d3 100644
--- a/chromium/components/security_interstitials/core/metrics_helper.cc
+++ b/chromium/components/security_interstitials/core/metrics_helper.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
diff --git a/chromium/components/security_interstitials_strings.grdp b/chromium/components/security_interstitials_strings.grdp
index d76cefd344c..581d17ffad5 100644
--- a/chromium/components/security_interstitials_strings.grdp
+++ b/chromium/components/security_interstitials_strings.grdp
@@ -64,6 +64,20 @@
Applications that can cause this error include antivirus, firewall, and web-filtering or proxy software.
</message>
+ <!-- Lookalike URL warning -->
+ <message name="IDS_LOOKALIKE_URL_TITLE" desc="Tab title. Context: the requested URL looks like a more popular URL.">
+ Did you mean?
+ </message>
+ <message name="IDS_LOOKALIKE_URL_HEADING" desc="Large heading. Context: the error page that's shown when the requested URL looks like a more popular URL.">
+ Did you mean &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN">$1<ex>example.com</ex></ph>&lt;/a&gt;?
+ </message>
+ <message name="IDS_LOOKALIKE_URL_IGNORE" desc="Button text. Context: the error page that's shown when the requested URL looks like a more popular URL. This button continues on to the originally-requested URL.">
+ Ignore
+ </message>
+ <message name="IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH" desc="Main paragraph of an error message. Context: the error page that's shown when the requested URL looks like a more popular URL.">
+ The link you originally opened is unusual
+ </message>
+
<!-- Clock errors -->
<message name="IDS_CLOCK_ERROR_TITLE" desc="Tab title. Context: the browser can't load a page because the device's clock is wrong.">
Clock error
@@ -380,4 +394,54 @@
<message name="IDS_BILLING_PROCEED_BUTTON" desc="The text for the billing interstitial proceed button.">
Proceed
</message>
+
+ <!-- Origin Policy Error Interstial -->
+ <message name="IDS_ORIGIN_POLICY_TITLE"
+ desc="Title of the Origin Policy Error interstitial.">
+ Origin Policy Error
+ </message>
+ <message name="IDS_ORIGIN_POLICY_HEADING"
+ desc="The large heading at the top of the Origin Policy Error Interstitial">
+ Blocked according to <ph name="ORIGIN">$2</ph>'s security policy.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_INFO"
+ desc="The primary explanatory paragraph for the Origin Policy Error interstitial.">
+ The site <ph name="ORIGIN">$2</ph> has requested that a security policy
+ will apply to all its request, and this policy presently deems the site
+ unsafe.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_INFO2" desc="The second paragrpah of the text of the Origin Policy Error Interstitial. (Presently intentionally left blank.)" />
+ <message name="IDS_ORIGIN_POLICY_BUTTON"
+ desc="The text for the Origin Policy Error Interstitial button that takes the user back to the previous page">
+ Back to safety.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_DETAILS"
+ desc="The text for the Origin Policy Error Interstitial button that contains additional information.">
+ Advanced
+ </message>
+ <message name="IDS_ORIGIN_POLICY_EXPLANATION_CANNOT_LOAD" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for the case where the policy could not be loaded.">
+ The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
+ a security policy will be applied to all requests to it. But it has now
+ failed to deliver a policy, which prevents the browser from fulfilling
+ your request for <ph name="SITE">$1</ph>.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_EXPLANATION_SHOULD_NOT_REDIRECT" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for the case where the policy request was met with a 'redirect' response.">
+ The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
+ a security policy will be applied to all requests to it. But instead of
+ delivering a policy it has redirected the browser elsewhere, which prevents
+ the browser from fulfilling your request for <ph name="SITE">$1</ph>.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_EXPLANATION_OTHER" desc="The text of the Origin Policy Error Interstitial that will be displayed when the user presses the 'Advanced' button for additional information, for cases other than redirect or load error.">
+ The server you are going to, <ph name="ORIGIN">$2</ph>, has requested that
+ a security policy will be applied to all requests to it. But it has now
+ delivered an invalid policy, which prevents the browser from
+ fulfilling your request for <ph name="SITE">$1</ph>.
+ </message>
+ <message name="IDS_ORIGIN_POLICY_FINAL_PARAGRAPH"
+ desc="The text of the Origin Policy Error Interstitial that a user can click to proceed to the site, despite the error.">
+ <ph name="BEGIN_LINK">&lt;a href="#" id="proceed-link"&gt;</ph>Proceed to <ph name="SITE">$1<ex>example.com</ex></ph> (unsafe)<ph name="END_LINK">&lt;/a&gt;</ph>
+ </message>
+ <message name="IDS_ORIGIN_POLICY_CLOSE" desc="The text of the Origin Policy Error Interstitial that will hide the 'advanced' section again.">
+ Hide advanced
+ </message>
</grit-part>
diff --git a/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1 b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1
new file mode 100644
index 00000000000..981ff931476
--- /dev/null
+++ b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_HEADING.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d \ No newline at end of file
diff --git a/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1 b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1
new file mode 100644
index 00000000000..981ff931476
--- /dev/null
+++ b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_IGNORE.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d \ No newline at end of file
diff --git a/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1 b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1
new file mode 100644
index 00000000000..981ff931476
--- /dev/null
+++ b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d \ No newline at end of file
diff --git a/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1 b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1
new file mode 100644
index 00000000000..981ff931476
--- /dev/null
+++ b/chromium/components/security_interstitials_strings_grdp/IDS_LOOKALIKE_URL_TITLE.png.sha1
@@ -0,0 +1 @@
+fbe2d6cd6009517b71a7413b08b6419c5e20674d \ No newline at end of file
diff --git a/chromium/components/security_state/content/content_utils.cc b/chromium/components/security_state/content/content_utils.cc
index dfda31fba88..55878368fcc 100644
--- a/chromium/components/security_state/content/content_utils.cc
+++ b/chromium/components/security_state/content/content_utils.cc
@@ -64,7 +64,7 @@ void ExplainHTTPSecurity(
if (security_info.security_level == security_state::DANGEROUS &&
!security_info.scheme_is_cryptographic) {
security_style_explanations->summary =
- l10n_util::GetStringUTF8(IDS_EDITED_NONSECURE_SUMMARY);
+ l10n_util::GetStringUTF8(IDS_HTTP_NONSECURE_SUMMARY);
if (security_info.insecure_input_events.insecure_field_edited) {
security_style_explanations->insecure_explanations.push_back(
content::SecurityStyleExplanation(
diff --git a/chromium/components/security_state/core/BUILD.gn b/chromium/components/security_state/core/BUILD.gn
index 8ccd5b9dcef..676f699722e 100644
--- a/chromium/components/security_state/core/BUILD.gn
+++ b/chromium/components/security_state/core/BUILD.gn
@@ -16,8 +16,6 @@ jumbo_static_library("core") {
"insecure_input_event_data.h",
"security_state.cc",
"security_state.h",
- "security_state_ui.cc",
- "security_state_ui.h",
]
public_deps = [
diff --git a/chromium/components/security_state/core/security_state_ui.cc b/chromium/components/security_state/core/security_state_ui.cc
deleted file mode 100644
index e91560ae975..00000000000
--- a/chromium/components/security_state/core/security_state_ui.cc
+++ /dev/null
@@ -1,29 +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/security_state/core/security_state_ui.h"
-
-namespace security_state {
-
-bool ShouldAlwaysShowIcon(SecurityLevel security_level) {
- // Enumerate all |SecurityLevel| values for compile-time enforcement that all
- // cases are explicitly handled.
- switch (security_level) {
- case NONE:
- return false;
- case HTTP_SHOW_WARNING:
- case EV_SECURE:
- case SECURE:
- case SECURE_WITH_POLICY_INSTALLED_CERT:
- case DANGEROUS:
- return true;
- case SECURITY_LEVEL_COUNT:
- NOTREACHED();
- return false;
- }
- NOTREACHED();
- return false;
-}
-
-} // namespace security_state
diff --git a/chromium/components/security_state/core/security_state_ui.h b/chromium/components/security_state/core/security_state_ui.h
deleted file mode 100644
index 035091f7789..00000000000
--- a/chromium/components/security_state/core/security_state_ui.h
+++ /dev/null
@@ -1,21 +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_SECURITY_STATE_SECURITY_STATE_UI_H_
-#define COMPONENTS_SECURITY_STATE_SECURITY_STATE_UI_H_
-
-#include "components/security_state/core/security_state.h"
-
-// Provides helper methods that encapsulate platform-independent security UI
-// logic.
-namespace security_state {
-
-// On some (mobile) form factors, the security indicator icon is hidden to save
-// UI space. This returns whether the icon should always be shown for the given
-// |security_level|, i.e. whether to override the hiding behaviour.
-bool ShouldAlwaysShowIcon(SecurityLevel security_level);
-
-} // namespace security_state
-
-#endif // COMPONENTS_SECURITY_STATE_SECURITY_STATE_UI_H_
diff --git a/chromium/components/security_state_strings.grdp b/chromium/components/security_state_strings.grdp
index 75f1f9f5632..86284919d11 100644
--- a/chromium/components/security_state_strings.grdp
+++ b/chromium/components/security_state_strings.grdp
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<grit-part>
<!-- Strings describing Chrome security policy for DevTools security panel -->
- <message name="IDS_EDITED_NONSECURE_SUMMARY" desc="Main summary for an HTTP page where a user has entered data in a form field." translateable="false">
+ <message name="IDS_HTTP_NONSECURE_SUMMARY" desc="Main summary for where the site is non-secure HTTP." translateable="false">
This page is insecure (unencrypted HTTP).
</message>
<message name="IDS_EDITED_NONSECURE" desc="Summary phrase for a security problem where the site is non-secure (HTTP) and user has entered data in a form field." translateable="false">
diff --git a/chromium/components/send_tab_to_self/BUILD.gn b/chromium/components/send_tab_to_self/BUILD.gn
index b6bca20fcde..900b9b2ff26 100644
--- a/chromium/components/send_tab_to_self/BUILD.gn
+++ b/chromium/components/send_tab_to_self/BUILD.gn
@@ -11,16 +11,20 @@ static_library("send_tab_to_self") {
"send_tab_to_self_model.cc",
"send_tab_to_self_model.h",
"send_tab_to_self_model_observer.h",
- "send_tab_to_self_service.cc",
- "send_tab_to_self_service.h",
+ "send_tab_to_self_sync_service.cc",
+ "send_tab_to_self_sync_service.h",
]
deps = [
"//base",
"//components/keyed_service/core",
+ "//components/send_tab_to_self/proto:send_tab_to_self_proto",
"//components/sync",
"//components/version_info",
"//url",
]
+ public_deps = [
+ "//components/send_tab_to_self/proto:send_tab_to_self_proto",
+ ]
}
source_set("unit_tests") {
@@ -33,6 +37,7 @@ source_set("unit_tests") {
":send_tab_to_self",
"//base",
"//base/test:test_support",
+ "//components/send_tab_to_self/proto:send_tab_to_self_proto",
"//components/sync",
"//components/sync:test_support_driver",
"//components/sync:test_support_model",
diff --git a/chromium/components/send_tab_to_self/OWNERS b/chromium/components/send_tab_to_self/OWNERS
index a49acc9eff2..cbbc50e63a9 100644
--- a/chromium/components/send_tab_to_self/OWNERS
+++ b/chromium/components/send_tab_to_self/OWNERS
@@ -1,6 +1,5 @@
hansberry@chromium.org
jeffreycohen@chromium.org
sebsg@chromium.org
-tgupta@chromium.org
# COMPONENT: UI>Browser>Sharing
diff --git a/chromium/components/send_tab_to_self/proto/BUILD.gn b/chromium/components/send_tab_to_self/proto/BUILD.gn
new file mode 100644
index 00000000000..afe1e5551ed
--- /dev/null
+++ b/chromium/components/send_tab_to_self/proto/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/protobuf/proto_library.gni")
+
+proto_library("send_tab_to_self_proto") {
+ import_dirs = [ "//components/sync/protocol" ]
+ sources = [
+ "send_tab_to_self.proto",
+ ]
+ link_deps = [ "//components/sync/protocol:protocol" ]
+}
diff --git a/chromium/components/send_tab_to_self/proto/DEPS b/chromium/components/send_tab_to_self/proto/DEPS
new file mode 100644
index 00000000000..60ba8970ee0
--- /dev/null
+++ b/chromium/components/send_tab_to_self/proto/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+components/sync/protocol",
+]
diff --git a/chromium/components/send_tab_to_self/proto/send_tab_to_self.proto b/chromium/components/send_tab_to_self/proto/send_tab_to_self.proto
new file mode 100644
index 00000000000..61d75042fb8
--- /dev/null
+++ b/chromium/components/send_tab_to_self/proto/send_tab_to_self.proto
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Sync protocol datatype extension for the send tab to self entries.
+
+syntax = "proto2";
+
+import "send_tab_to_self_specifics.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+package send_tab_to_self;
+
+// Local Send tab to self entry. This proto contains the fields stored locally
+// for a send tab to self entry.
+message SendTabToSelfLocal {
+ // The Send tab to self specifics proto.
+ optional sync_pb.SendTabToSelfSpecifics specifics = 1;
+
+ // Has the notification for this proto been dismissed.
+ optional bool notification_dismissed = 2;
+}
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_bridge.cc b/chromium/components/send_tab_to_self/send_tab_to_self_bridge.cc
index 549d5134413..ac7c5e4ea24 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_bridge.cc
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -10,6 +10,7 @@
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/time/clock.h"
+#include "components/send_tab_to_self/proto/send_tab_to_self.pb.h"
#include "components/sync/device_info/device_info.h"
#include "components/sync/device_info/local_device_info_provider.h"
#include "components/sync/model/entity_change.h"
@@ -17,23 +18,48 @@
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_type_change_processor.h"
#include "components/sync/model/mutable_data_batch.h"
-#include "components/sync/model_impl/in_memory_metadata_change_list.h"
#include "components/sync/protocol/model_type_state.pb.h"
namespace send_tab_to_self {
+namespace {
+
+using syncer::ModelTypeStore;
+
+// Converts a time field from sync protobufs to a time object.
+base::Time ProtoTimeToTime(int64_t proto_t) {
+ return base::Time::FromDeltaSinceWindowsEpoch(
+ base::TimeDelta::FromMicroseconds(proto_t));
+}
+
+// Allocate a EntityData and copies |specifics| into it.
+std::unique_ptr<syncer::EntityData> CopyToEntityData(
+ const sync_pb::SendTabToSelfSpecifics& specifics) {
+ auto entity_data = std::make_unique<syncer::EntityData>();
+ *entity_data->specifics.mutable_send_tab_to_self() = specifics;
+ entity_data->non_unique_name = specifics.url();
+ entity_data->creation_time = ProtoTimeToTime(specifics.shared_time_usec());
+ return entity_data;
+}
+
+} // namespace
+
SendTabToSelfBridge::SendTabToSelfBridge(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
syncer::LocalDeviceInfoProvider* local_device_info_provider,
- base::Clock* clock)
+ base::Clock* clock,
+ syncer::OnceModelTypeStoreFactory create_store_callback)
: ModelTypeSyncBridge(std::move(change_processor)),
+ clock_(clock),
local_device_info_provider_(local_device_info_provider),
- clock_(clock) {
- DCHECK(local_device_info_provider_);
+ weak_ptr_factory_(this) {
+ DCHECK(local_device_info_provider);
DCHECK(clock_);
- auto batch = std::make_unique<syncer::MetadataBatch>();
- this->change_processor()->ModelReadyToSync(std::move(batch));
- // TODO(jeffreycohen): Create a local store and read meta data from it.
+
+ std::move(create_store_callback)
+ .Run(syncer::SEND_TAB_TO_SELF,
+ base::BindOnce(&SendTabToSelfBridge::OnStoreCreated,
+ weak_ptr_factory_.GetWeakPtr()));
}
SendTabToSelfBridge::~SendTabToSelfBridge() {
@@ -41,12 +67,13 @@ SendTabToSelfBridge::~SendTabToSelfBridge() {
std::unique_ptr<syncer::MetadataChangeList>
SendTabToSelfBridge::CreateMetadataChangeList() {
- return std::make_unique<syncer::InMemoryMetadataChangeList>();
+ return ModelTypeStore::WriteBatch::CreateMetadataChangeList();
}
base::Optional<syncer::ModelError> SendTabToSelfBridge::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
+ DCHECK(entries_.empty());
return ApplySyncChanges(std::move(metadata_change_list),
std::move(entity_data));
}
@@ -54,49 +81,73 @@ base::Optional<syncer::ModelError> SendTabToSelfBridge::MergeSyncData(
base::Optional<syncer::ModelError> SendTabToSelfBridge::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_changes) {
+ std::vector<const SendTabToSelfEntry*> added;
+ std::vector<std::string> removed;
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch =
+ store_->CreateWriteBatch();
+
for (syncer::EntityChange& change : entity_changes) {
+ const std::string& guid = change.storage_key();
if (change.type() == syncer::EntityChange::ACTION_DELETE) {
- entries_.erase(change.storage_key());
+ if (entries_.find(guid) != entries_.end()) {
+ entries_.erase(change.storage_key());
+ batch->DeleteData(guid);
+ removed.push_back(change.storage_key());
+ }
} else {
+ // syncer::EntityChange::ACTION_UPDATE is not supported by this bridge
+ DCHECK(change.type() == syncer::EntityChange::ACTION_ADD);
+
const sync_pb::SendTabToSelfSpecifics& specifics =
change.data().specifics.send_tab_to_self();
- // TODO(jeffreycohen): FromProto expects a valid entry. External data
- // needs to be sanitized before it's passed through.
+
std::unique_ptr<SendTabToSelfEntry> entry =
SendTabToSelfEntry::FromProto(specifics, clock_->Now());
// This entry is new. Add it to the model.
+ added.push_back(entry.get());
+ SendTabToSelfLocal entry_pb = entry->AsLocalProto();
entries_[entry->GetGUID()] = std::move(entry);
+
+ // Write to the store.
+ batch->WriteData(guid, entry_pb.SerializeAsString());
}
}
- if (!entity_changes.empty()) {
- NotifySendTabToSelfModelChanged();
+
+ batch->TakeMetadataChangesFrom(std::move(metadata_change_list));
+ Commit(std::move(batch));
+
+ if (!removed.empty()) {
+ NotifyRemoteSendTabToSelfEntryDeleted(removed);
+ }
+ if (!added.empty()) {
+ NotifyRemoteSendTabToSelfEntryAdded(added);
}
+
return base::nullopt;
}
void SendTabToSelfBridge::GetData(StorageKeyList storage_keys,
DataCallback callback) {
- syncer::InMemoryMetadataChangeList metadata_change_list;
+ auto batch = std::make_unique<syncer::MutableDataBatch>();
for (const std::string& guid : storage_keys) {
const SendTabToSelfEntry* entry = GetEntryByGUID(guid);
if (!entry) {
continue;
}
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> specifics =
- entry->AsProto();
- auto entity_data = std::make_unique<syncer::EntityData>();
- *entity_data->specifics.mutable_send_tab_to_self() = *specifics;
- entity_data->non_unique_name = specifics->url();
- change_processor()->Put(specifics->guid(), std::move(entity_data),
- &metadata_change_list);
+ batch->Put(guid, CopyToEntityData(entry->AsLocalProto().specifics()));
}
+ std::move(callback).Run(std::move(batch));
}
void SendTabToSelfBridge::GetAllDataForDebugging(DataCallback callback) {
- // TODO(jeffreycohen): Add once we have a batch model.
- NOTIMPLEMENTED();
+ auto batch = std::make_unique<syncer::MutableDataBatch>();
+ for (const auto& it : entries_) {
+ batch->Put(it.first,
+ CopyToEntityData(it.second->AsLocalProto().specifics()));
+ }
+ std::move(callback).Run(std::move(batch));
}
std::string SendTabToSelfBridge::GetClientTag(
@@ -123,12 +174,19 @@ void SendTabToSelfBridge::DeleteAllEntries() {
DCHECK_EQ(0ul, entries_.size());
return;
}
- syncer::InMemoryMetadataChangeList metadata_change_list;
- for (const auto& key : GetAllGuids()) {
- change_processor()->Delete(key, &metadata_change_list);
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch =
+ store_->CreateWriteBatch();
+
+ std::vector<std::string> all_guids = GetAllGuids();
+
+ for (const auto& guid : all_guids) {
+ change_processor()->Delete(guid, batch->GetMetadataChangeList());
+ batch->DeleteData(guid);
}
entries_.clear();
+
+ NotifyRemoteSendTabToSelfEntryDeleted(all_guids);
}
const SendTabToSelfEntry* SendTabToSelfBridge::GetEntryByGUID(
@@ -142,43 +200,188 @@ const SendTabToSelfEntry* SendTabToSelfBridge::GetEntryByGUID(
const SendTabToSelfEntry* SendTabToSelfBridge::AddEntry(
const GURL& url,
- const std::string& title,
- base::Time navigation_time) {
+ const std::string& title) {
if (!change_processor()->IsTrackingMetadata()) {
return nullptr;
}
std::string guid = base::GenerateGUID();
- // TODO(jeffreycohen) Handle the fact that local device info may not be
- // guaranteed in production code as it may take some time to get initialized.
- DCHECK(local_device_info_provider_->GetLocalDeviceInfo());
-
// Assure that we don't have a guid collision.
DCHECK_EQ(GetEntryByGUID(guid), nullptr);
std::string trimmed_title = base::CollapseWhitespaceASCII(title, false);
- std::string device_name =
- local_device_info_provider_->GetLocalDeviceInfo()->client_name();
- auto entry = std::make_unique<SendTabToSelfEntry>(
- guid, url, trimmed_title, clock_->Now(), navigation_time, device_name);
+ // TODO(crbug.com/938102) Use history service to find most recent navigation
+ // time for url.
+ base::Time navigation_time = clock_->Now();
- syncer::InMemoryMetadataChangeList metadata_change_list;
+ auto entry = std::make_unique<SendTabToSelfEntry>(
+ guid, url, trimmed_title, clock_->Now(), navigation_time,
+ local_device_name_);
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch =
+ store_->CreateWriteBatch();
// This entry is new. Add it to the store and model.
- auto entity_data = std::make_unique<syncer::EntityData>();
- *entity_data->specifics.mutable_send_tab_to_self() = *entry->AsProto();
- entity_data->non_unique_name = entry->GetURL().spec();
- entity_data->creation_time = entry->GetSharedTime();
+ auto entity_data = CopyToEntityData(entry->AsLocalProto().specifics());
+
+ change_processor()->Put(guid, std::move(entity_data),
+ batch->GetMetadataChangeList());
+
+ const SendTabToSelfEntry* result =
+ entries_.emplace(guid, std::move(entry)).first->second.get();
+ SendTabToSelfLocal specifics = result->AsLocalProto();
+
+ batch->WriteData(guid, specifics.SerializeAsString());
+
+ Commit(std::move(batch));
+ return result;
+}
+
+void SendTabToSelfBridge::DeleteEntry(const std::string& guid) {
+ // Assure that an entry with that guid exists.
+ if (GetEntryByGUID(guid) == nullptr) {
+ return;
+ }
+
+ DCHECK(change_processor()->IsTrackingMetadata());
+
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch =
+ store_->CreateWriteBatch();
+ change_processor()->Delete(guid, batch->GetMetadataChangeList());
+
+ entries_.erase(guid);
+ batch->DeleteData(guid);
+ Commit(std::move(batch));
+}
- change_processor()->Put(guid, std::move(entity_data), &metadata_change_list);
+void SendTabToSelfBridge::DismissEntry(const std::string& guid) {
+ SendTabToSelfEntry* entry = GetMutableEntryByGUID(guid);
+ // Assure that an entry with that guid exists.
+ if (!entry) {
+ return;
+ }
+ entry->SetNotificationDismissed(true);
+
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch =
+ store_->CreateWriteBatch();
+
+ batch->WriteData(guid, entry->AsLocalProto().SerializeAsString());
+ Commit(std::move(batch));
+}
- return entries_.emplace(guid, std::move(entry)).first->second.get();
+// static
+std::unique_ptr<syncer::ModelTypeStore>
+SendTabToSelfBridge::DestroyAndStealStoreForTest(
+ std::unique_ptr<SendTabToSelfBridge> bridge) {
+ return std::move(bridge->store_);
}
-void SendTabToSelfBridge::NotifySendTabToSelfModelChanged() {
- for (SendTabToSelfModelObserver& observer : observers_)
- observer.SendTabToSelfModelChanged();
+void SendTabToSelfBridge::NotifyRemoteSendTabToSelfEntryAdded(
+ const std::vector<const SendTabToSelfEntry*>& new_entries) {
+ for (SendTabToSelfModelObserver& observer : observers_) {
+ observer.EntriesAddedRemotely(new_entries);
+ }
+}
+
+void SendTabToSelfBridge::NotifyRemoteSendTabToSelfEntryDeleted(
+ const std::vector<std::string>& guids) {
+ for (SendTabToSelfModelObserver& observer : observers_) {
+ observer.EntriesRemovedRemotely(guids);
+ }
+}
+
+void SendTabToSelfBridge::NotifySendTabToSelfModelLoaded() {
+ for (SendTabToSelfModelObserver& observer : observers_) {
+ observer.SendTabToSelfModelLoaded();
+ }
+}
+
+void SendTabToSelfBridge::OnStoreCreated(
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore> store) {
+ if (error) {
+ change_processor()->ReportError(*error);
+ return;
+ }
+
+ store_ = std::move(store);
+ store_->ReadAllData(base::BindOnce(&SendTabToSelfBridge::OnReadAllData,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SendTabToSelfBridge::OnReadAllData(
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> record_list) {
+ if (error) {
+ change_processor()->ReportError(*error);
+ return;
+ }
+
+ for (const syncer::ModelTypeStore::Record& r : *record_list) {
+ auto specifics = std::make_unique<SendTabToSelfLocal>();
+ if (specifics->ParseFromString(r.value)) {
+ entries_[specifics->specifics().guid()] =
+ SendTabToSelfEntry::FromLocalProto(*specifics, clock_->Now());
+ } else {
+ change_processor()->ReportError(
+ {FROM_HERE, "Failed to deserialize specifics."});
+ return;
+ }
+ }
+
+ if (local_device_info_provider_->GetLocalDeviceInfo()) {
+ OnDeviceProviderInitialized();
+ } else {
+ device_subscription_ =
+ local_device_info_provider_->RegisterOnInitializedCallback(
+ base::BindRepeating(
+ &SendTabToSelfBridge::OnDeviceProviderInitialized,
+ base::Unretained(this)));
+ }
+}
+
+void SendTabToSelfBridge::OnDeviceProviderInitialized() {
+ device_subscription_.reset();
+ local_device_name_ =
+ local_device_info_provider_->GetLocalDeviceInfo()->client_name();
+
+ // now that all of the providers are ready we can read the metadata.
+ store_->ReadAllMetadata(base::BindOnce(
+ &SendTabToSelfBridge::OnReadAllMetadata, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SendTabToSelfBridge::OnReadAllMetadata(
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch) {
+ if (error) {
+ change_processor()->ReportError(*error);
+ return;
+ }
+ change_processor()->ModelReadyToSync(std::move(metadata_batch));
+ NotifySendTabToSelfModelLoaded();
+}
+
+void SendTabToSelfBridge::OnCommit(
+ const base::Optional<syncer::ModelError>& error) {
+ if (error) {
+ change_processor()->ReportError(*error);
+ }
+}
+
+void SendTabToSelfBridge::Commit(
+ std::unique_ptr<ModelTypeStore::WriteBatch> batch) {
+ store_->CommitWriteBatch(std::move(batch),
+ base::BindOnce(&SendTabToSelfBridge::OnCommit,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+SendTabToSelfEntry* SendTabToSelfBridge::GetMutableEntryByGUID(
+ const std::string& guid) const {
+ auto it = entries_.find(guid);
+ if (it == entries_.end()) {
+ return nullptr;
+ }
+ return it->second.get();
}
} // namespace send_tab_to_self
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_bridge.h b/chromium/components/send_tab_to_self/send_tab_to_self_bridge.h
index 9cfc7e23475..d4a2ef86c92 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_bridge.h
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_bridge.h
@@ -12,13 +12,15 @@
#include <vector>
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "components/send_tab_to_self/send_tab_to_self_entry.h"
#include "components/send_tab_to_self/send_tab_to_self_model.h"
#include "components/sync/base/model_type.h"
+#include "components/sync/device_info/local_device_info_provider.h"
+#include "components/sync/model/model_type_store.h"
#include "components/sync/model/model_type_sync_bridge.h"
namespace syncer {
-class LocalDeviceInfoProvider;
class ModelTypeChangeProcessor;
} // namespace syncer
@@ -38,7 +40,8 @@ class SendTabToSelfBridge : public syncer::ModelTypeSyncBridge,
SendTabToSelfBridge(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
syncer::LocalDeviceInfoProvider* local_device_info_provider,
- base::Clock* clock);
+ base::Clock* clock,
+ syncer::OnceModelTypeStoreFactory create_store_callback);
~SendTabToSelfBridge() override;
// syncer::ModelTypeSyncBridge overrides.
@@ -61,21 +64,74 @@ class SendTabToSelfBridge : public syncer::ModelTypeSyncBridge,
const SendTabToSelfEntry* GetEntryByGUID(
const std::string& guid) const override;
const SendTabToSelfEntry* AddEntry(const GURL& url,
- const std::string& title,
- base::Time navigation_time) override;
+ const std::string& title) override;
+
+ void DeleteEntry(const std::string& guid) override;
+ void DismissEntry(const std::string& guid) override;
+
+ // For testing only.
+ static std::unique_ptr<syncer::ModelTypeStore> DestroyAndStealStoreForTest(
+ std::unique_ptr<SendTabToSelfBridge> bridge);
private:
using SendTabToSelfEntries =
std::map<std::string, std::unique_ptr<SendTabToSelfEntry>>;
- // Notify all observers of a change;
- void NotifySendTabToSelfModelChanged();
+ // Notify all observers of any added |entries| when they are added the the
+ // model via sync.
+ void NotifyRemoteSendTabToSelfEntryAdded(
+ const std::vector<const SendTabToSelfEntry*>& new_entries);
+
+ // Notify all observers when the entries with |guids| have been removed from
+ // the model via sync.
+ void NotifyRemoteSendTabToSelfEntryDeleted(
+ const std::vector<std::string>& guids);
+
+ // Notify all observers that the model is loaded;
+ void NotifySendTabToSelfModelLoaded();
+
+ // Methods used as callbacks given to DataTypeStore.
+ void OnStoreCreated(const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore> store);
+ void OnReadAllData(
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> record_list);
+
+ // Used as callback given to LocalDeviceInfoProvider.
+ void OnDeviceProviderInitialized();
+
+ void OnReadAllMetadata(const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch);
+ void OnCommit(const base::Optional<syncer::ModelError>& error);
+
+ // Persists the changes in the given aggregators
+ void Commit(std::unique_ptr<syncer::ModelTypeStore::WriteBatch> batch);
+
+ // Returns a specific entry for editing. Returns null if the entry does not
+ // exist.
+ SendTabToSelfEntry* GetMutableEntryByGUID(const std::string& guid) const;
// |entries_| is keyed by GUIDs.
SendTabToSelfEntries entries_;
- const syncer::LocalDeviceInfoProvider* const local_device_info_provider_;
+
+ // |clock_| isn't owned.
const base::Clock* const clock_;
+ // |local_device_info_provider_| isn't owned.
+ syncer::LocalDeviceInfoProvider* const local_device_info_provider_;
+
+ std::string local_device_name_;
+
+ // In charge of actually persisting changes to disk, or loading previous data.
+ std::unique_ptr<syncer::ModelTypeStore> store_;
+
+ // Used to listen for provider initialization. If the provider is already
+ // initialized during our constructor then the subscription is never used.
+ std::unique_ptr<syncer::LocalDeviceInfoProvider::Subscription>
+ device_subscription_;
+
+ base::WeakPtrFactory<SendTabToSelfBridge> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfBridge);
};
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/chromium/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
index ac447adfdc6..206c9a2ba7b 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -10,12 +10,18 @@
#include "base/bind.h"
#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
+#include "components/send_tab_to_self/proto/send_tab_to_self.pb.h"
#include "components/sync/device_info/local_device_info_provider_mock.h"
+#include "components/sync/model/entity_change.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
+#include "components/sync/model/model_type_store_test_util.h"
#include "components/sync/model_impl/in_memory_metadata_change_list.h"
+#include "components/sync/protocol/model_type_state.pb.h"
+#include "components/sync/test/test_matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -24,16 +30,69 @@ namespace send_tab_to_self {
namespace {
using testing::_;
+using testing::IsEmpty;
+using testing::Return;
+using testing::SizeIs;
+
+const char kGuidFormat[] = "guid %d";
+const char kURLFormat[] = "https://www.url%d.com/";
+const char kTitleFormat[] = "title %d";
+const char kDeviceFormat[] = "device %d";
+
+sync_pb::SendTabToSelfSpecifics CreateSpecifics(
+ int suffix,
+ base::Time shared_time = base::Time::Now(),
+ base::Time navigation_time = base::Time::Now()) {
+ sync_pb::SendTabToSelfSpecifics specifics;
+ specifics.set_guid(base::StringPrintf(kGuidFormat, suffix));
+ specifics.set_url(base::StringPrintf(kURLFormat, suffix));
+ specifics.set_device_name(base::StringPrintf(kDeviceFormat, suffix));
+ specifics.set_title(base::StringPrintf(kTitleFormat, suffix));
+ specifics.set_shared_time_usec(
+ shared_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+ specifics.set_navigation_time_usec(
+ navigation_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+ return specifics;
+}
+
+sync_pb::ModelTypeState StateWithEncryption(
+ const std::string& encryption_key_name) {
+ sync_pb::ModelTypeState state;
+ state.set_encryption_key_name(encryption_key_name);
+ return state;
+}
+class MockSendTabToSelfModelObserver : public SendTabToSelfModelObserver {
+ public:
+ MOCK_METHOD0(SendTabToSelfModelLoaded, void());
+ MOCK_METHOD1(EntriesAddedRemotely,
+ void(const std::vector<const SendTabToSelfEntry*>&));
+
+ MOCK_METHOD1(EntriesRemovedRemotely, void(const std::vector<std::string>&));
+};
class SendTabToSelfBridgeTest : public testing::Test {
protected:
SendTabToSelfBridgeTest()
- : bridge_(mock_processor_.CreateForwardingProcessor(),
- &provider_,
- &clock_) {
+ : store_(syncer::ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()) {
provider_.Initialize("cache_guid", "machine");
- ON_CALL(mock_processor_, IsTrackingMetadata())
- .WillByDefault(testing::Return(true));
+ ON_CALL(mock_processor_, IsTrackingMetadata()).WillByDefault(Return(true));
+ }
+
+ // Initialized the bridge based on the current local device and store. Can
+ // only be called once per run, as it passes |store_|.
+ void InitializeBridge() {
+ bridge_ = std::make_unique<SendTabToSelfBridge>(
+ mock_processor_.CreateForwardingProcessor(), &provider_, &clock_,
+ syncer::ModelTypeStoreTestUtil::MoveStoreToFactory(std::move(store_)));
+ bridge_->AddObserver(&mock_observer_);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void ShutdownBridge() {
+ bridge_->RemoveObserver(&mock_observer_);
+ store_ =
+ SendTabToSelfBridge::DestroyAndStealStoreForTest(std::move(bridge_));
+ base::RunLoop().RunUntilIdle();
}
base::Time AdvanceAndGetTime() {
@@ -42,12 +101,12 @@ class SendTabToSelfBridgeTest : public testing::Test {
}
syncer::EntityDataPtr MakeEntityData(const SendTabToSelfEntry& entry) {
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> specifics =
- entry.AsProto();
+ SendTabToSelfLocal specifics = entry.AsLocalProto();
auto entity_data = std::make_unique<syncer::EntityData>();
- *(entity_data->specifics.mutable_send_tab_to_self()) = *specifics;
+ *(entity_data->specifics.mutable_send_tab_to_self()) =
+ specifics.specifics();
entity_data->non_unique_name = entry.GetURL().spec();
// The client_tag_hash field is unused by the send_tab_to_self_bridge, but
// is required for a valid entity_data.
@@ -55,15 +114,41 @@ class SendTabToSelfBridgeTest : public testing::Test {
return entity_data->PassToPtr();
}
+ // Helper method to reduce duplicated code between tests. Wraps the given
+ // specifics objects in an EntityData and EntityChange of type ACTION_ADD, and
+ // returns an EntityChangeList containing them all. Order is maintained.
+ syncer::EntityChangeList EntityAddList(
+ const std::vector<sync_pb::SendTabToSelfSpecifics>& specifics_list) {
+ syncer::EntityChangeList changes;
+ for (const auto& specifics : specifics_list) {
+ auto entity_data = std::make_unique<syncer::EntityData>();
+
+ *(entity_data->specifics.mutable_send_tab_to_self()) = specifics;
+ entity_data->non_unique_name = specifics.url();
+ // The client_tag_hash field is unused by the send_tab_to_self_bridge, but
+ // is required for a valid entity_data.
+ entity_data->client_tag_hash = "someclienttaghash";
+
+ changes.push_back(syncer::EntityChange::CreateAdd(
+ specifics.guid(), entity_data->PassToPtr()));
+ }
+ return changes;
+ }
+
// For Model Tests.
void AddSampleEntries() {
- // Adds timer to avoid having two entries with the same shared timestamp.
- bridge_.AddEntry(GURL("http://a.com"), "a", AdvanceAndGetTime());
- bridge_.AddEntry(GURL("http://b.com"), "b", AdvanceAndGetTime());
- bridge_.AddEntry(GURL("http://c.com"), "c", AdvanceAndGetTime());
- bridge_.AddEntry(GURL("http://d.com"), "d", AdvanceAndGetTime());
+ bridge_->AddEntry(GURL("http://a.com"), "a");
+ bridge_->AddEntry(GURL("http://b.com"), "b");
+ bridge_->AddEntry(GURL("http://c.com"), "c");
+ bridge_->AddEntry(GURL("http://d.com"), "d");
}
+ syncer::MockModelTypeChangeProcessor* processor() { return &mock_processor_; }
+
+ SendTabToSelfBridge* bridge() { return bridge_.get(); }
+ MockSendTabToSelfModelObserver* mock_observer() { return &mock_observer_; }
+
+ private:
base::SimpleTestClock clock_;
// In memory model type store needs to be able to post tasks.
@@ -71,21 +156,28 @@ class SendTabToSelfBridgeTest : public testing::Test {
syncer::LocalDeviceInfoProviderMock provider_;
- syncer::MockModelTypeChangeProcessor mock_processor_;
+ std::unique_ptr<syncer::ModelTypeStore> store_;
- SendTabToSelfBridge bridge_;
+ testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
+
+ std::unique_ptr<SendTabToSelfBridge> bridge_;
+
+ testing::NiceMock<MockSendTabToSelfModelObserver> mock_observer_;
- private:
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfBridgeTest);
};
TEST_F(SendTabToSelfBridgeTest, CheckEmpties) {
- EXPECT_EQ(0ul, bridge_.GetAllGuids().size());
+ InitializeBridge();
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(_)).Times(0);
+ EXPECT_EQ(0ul, bridge()->GetAllGuids().size());
AddSampleEntries();
- EXPECT_EQ(4ul, bridge_.GetAllGuids().size());
+ EXPECT_EQ(4ul, bridge()->GetAllGuids().size());
}
TEST_F(SendTabToSelfBridgeTest, SyncAddOneEntry) {
+ InitializeBridge();
syncer::EntityChangeList remote_input;
SendTabToSelfEntry entry("guid1", GURL("http://www.example.com/"), "title",
@@ -95,14 +187,33 @@ TEST_F(SendTabToSelfBridgeTest, SyncAddOneEntry) {
syncer::EntityChange::CreateAdd("guid1", MakeEntityData(entry)));
auto metadata_change_list =
std::make_unique<syncer::InMemoryMetadataChangeList>();
- bridge_.MergeSyncData(std::move(metadata_change_list), remote_input);
- EXPECT_EQ(1ul, bridge_.GetAllGuids().size());
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(SizeIs(1)));
+ bridge()->MergeSyncData(std::move(metadata_change_list), remote_input);
+ EXPECT_EQ(1ul, bridge()->GetAllGuids().size());
+}
+
+TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesAddTwoSpecifics) {
+ InitializeBridge();
+
+ const sync_pb::SendTabToSelfSpecifics specifics1 = CreateSpecifics(1);
+ const sync_pb::SendTabToSelfSpecifics specifics2 = CreateSpecifics(2);
+
+ sync_pb::ModelTypeState state = StateWithEncryption("ekn");
+ std::unique_ptr<syncer::MetadataChangeList> metadata_changes =
+ bridge()->CreateMetadataChangeList();
+ metadata_changes->UpdateModelTypeState(state);
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(SizeIs(2)));
+
+ auto error = bridge()->ApplySyncChanges(
+ std::move(metadata_changes), EntityAddList({specifics1, specifics2}));
+ EXPECT_FALSE(error);
}
TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesOneAdd) {
+ InitializeBridge();
SendTabToSelfEntry entry("guid1", GURL("http://www.example.com/"), "title",
AdvanceAndGetTime(), AdvanceAndGetTime(), "device");
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> specifics = entry.AsProto();
syncer::EntityChangeList add_changes;
@@ -110,28 +221,136 @@ TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesOneAdd) {
syncer::EntityChange::CreateAdd("guid1", MakeEntityData(entry)));
auto metadata_change_list =
std::make_unique<syncer::InMemoryMetadataChangeList>();
- bridge_.ApplySyncChanges(std::move(metadata_change_list), add_changes);
- EXPECT_EQ(1ul, bridge_.GetAllGuids().size());
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(SizeIs(1)));
+ bridge()->ApplySyncChanges(std::move(metadata_change_list), add_changes);
+ EXPECT_EQ(1ul, bridge()->GetAllGuids().size());
}
// Tests that the send tab to self entry is correctly removed.
TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesOneDeletion) {
+ InitializeBridge();
SendTabToSelfEntry entry("guid1", GURL("http://www.example.com/"), "title",
AdvanceAndGetTime(), AdvanceAndGetTime(), "device");
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> specifics = entry.AsProto();
syncer::EntityChangeList add_changes;
add_changes.push_back(
syncer::EntityChange::CreateAdd("guid1", MakeEntityData(entry)));
- auto metadata_change_list =
- std::make_unique<syncer::InMemoryMetadataChangeList>();
- bridge_.ApplySyncChanges(std::move(metadata_change_list), add_changes);
- EXPECT_EQ(1ul, bridge_.GetAllGuids().size());
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(SizeIs(1)));
+ bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(), add_changes);
+ EXPECT_EQ(1ul, bridge()->GetAllGuids().size());
syncer::EntityChangeList delete_changes;
delete_changes.push_back(syncer::EntityChange::CreateDelete("guid1"));
- bridge_.ApplySyncChanges(std::move(metadata_change_list), delete_changes);
- EXPECT_EQ(0ul, bridge_.GetAllGuids().size());
+
+ EXPECT_CALL(*mock_observer(), EntriesRemovedRemotely(SizeIs(1)));
+ bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
+ delete_changes);
+ EXPECT_EQ(0ul, bridge()->GetAllGuids().size());
+}
+
+TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesEmpty) {
+ InitializeBridge();
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(_)).Times(0);
+
+ auto error = bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
+ syncer::EntityChangeList());
+ EXPECT_FALSE(error);
+}
+
+TEST_F(SendTabToSelfBridgeTest, AddEntryAndRestartBridge) {
+ InitializeBridge();
+
+ const sync_pb::SendTabToSelfSpecifics specifics = CreateSpecifics(1);
+ sync_pb::ModelTypeState state = StateWithEncryption("ekn");
+ std::unique_ptr<syncer::MetadataChangeList> metadata_changes =
+ bridge()->CreateMetadataChangeList();
+ metadata_changes->UpdateModelTypeState(state);
+
+ auto error = bridge()->ApplySyncChanges(std::move(metadata_changes),
+ EntityAddList({specifics}));
+ ASSERT_FALSE(error);
+
+ ShutdownBridge();
+
+ EXPECT_CALL(*processor(),
+ ModelReadyToSync(MetadataBatchContains(
+ syncer::HasEncryptionKeyName(state.encryption_key_name()),
+ /*entities=*/IsEmpty())));
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(_)).Times(0);
+ InitializeBridge();
+
+ std::vector<std::string> guids = bridge()->GetAllGuids();
+ ASSERT_EQ(1ul, guids.size());
+ EXPECT_EQ(specifics.url(),
+ bridge()->GetEntryByGUID(guids[0])->GetURL().spec());
+}
+
+TEST_F(SendTabToSelfBridgeTest, ApplySyncChangesInMemory) {
+ InitializeBridge();
+
+ const sync_pb::SendTabToSelfSpecifics specifics = CreateSpecifics(1);
+ std::unique_ptr<syncer::MetadataChangeList> metadata_changes =
+ bridge()->CreateMetadataChangeList();
+
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(SizeIs(1)));
+
+ auto error_on_add = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(), EntityAddList({specifics}));
+
+ EXPECT_FALSE(error_on_add);
+
+ EXPECT_EQ(1ul, bridge()->GetAllGuids().size());
+
+ EXPECT_CALL(*mock_observer(), EntriesRemovedRemotely(SizeIs(1)));
+
+ auto error_on_delete = bridge()->ApplySyncChanges(
+ bridge()->CreateMetadataChangeList(),
+ {syncer::EntityChange::CreateDelete(specifics.guid())});
+
+ EXPECT_FALSE(error_on_delete);
+ EXPECT_EQ(0ul, bridge()->GetAllGuids().size());
+}
+
+TEST_F(SendTabToSelfBridgeTest, ApplyDeleteNonexistent) {
+ InitializeBridge();
+ EXPECT_CALL(*mock_observer(), EntriesAddedRemotely(_)).Times(0);
+
+ std::unique_ptr<syncer::MetadataChangeList> metadata_changes =
+ bridge()->CreateMetadataChangeList();
+
+ EXPECT_CALL(*processor(), Delete(_, _)).Times(0);
+ auto error =
+ bridge()->ApplySyncChanges(std::move(metadata_changes),
+ {syncer::EntityChange::CreateDelete("guid")});
+ EXPECT_FALSE(error);
+}
+
+TEST_F(SendTabToSelfBridgeTest, PreserveDissmissalAfterRestartBridge) {
+ InitializeBridge();
+
+ const sync_pb::SendTabToSelfSpecifics specifics = CreateSpecifics(1);
+ std::unique_ptr<syncer::MetadataChangeList> metadata_changes =
+ bridge()->CreateMetadataChangeList();
+
+ auto error = bridge()->ApplySyncChanges(std::move(metadata_changes),
+ EntityAddList({specifics}));
+ ASSERT_FALSE(error);
+
+ EXPECT_CALL(*processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*processor(), Delete(_, _)).Times(0);
+
+ bridge()->DismissEntry(specifics.guid());
+
+ ShutdownBridge();
+
+ InitializeBridge();
+
+ std::vector<std::string> guids = bridge()->GetAllGuids();
+ ASSERT_EQ(1ul, guids.size());
+ EXPECT_TRUE(bridge()->GetEntryByGUID(guids[0])->GetNotificationDismissed());
}
} // namespace
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_entry.cc b/chromium/components/send_tab_to_self/send_tab_to_self_entry.cc
index 6fc811f4568..f8e7eacf2e8 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_entry.cc
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_entry.cc
@@ -4,13 +4,32 @@
#include "components/send_tab_to_self/send_tab_to_self_entry.h"
+#include <memory>
+
#include "base/guid.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "components/send_tab_to_self/proto/send_tab_to_self.pb.h"
#include "components/sync/protocol/send_tab_to_self_specifics.pb.h"
namespace send_tab_to_self {
+namespace {
+
+// Converts a time object to the format used in sync protobufs (ms since the
+// Windows epoch).
+int64_t TimeToProtoTime(const base::Time t) {
+ return t.ToDeltaSinceWindowsEpoch().InMicroseconds();
+}
+
+// Converts a time field from sync protobufs to a time object.
+base::Time ProtoTimeToTime(int64_t proto_t) {
+ return base::Time::FromDeltaSinceWindowsEpoch(
+ base::TimeDelta::FromMicroseconds(proto_t));
+}
+
+} // namespace
+
SendTabToSelfEntry::SendTabToSelfEntry(const std::string& guid,
const GURL& url,
const std::string& title,
@@ -22,7 +41,8 @@ SendTabToSelfEntry::SendTabToSelfEntry(const std::string& guid,
title_(title),
device_name_(device_name),
shared_time_(shared_time),
- original_navigation_time_(original_navigation_time) {
+ original_navigation_time_(original_navigation_time),
+ notification_dismissed_(false) {
DCHECK(!guid_.empty());
DCHECK(url_.is_valid());
}
@@ -53,20 +73,29 @@ const std::string& SendTabToSelfEntry::GetDeviceName() const {
return device_name_;
}
-std::unique_ptr<sync_pb::SendTabToSelfSpecifics> SendTabToSelfEntry::AsProto()
- const {
- auto pb_entry = std::make_unique<sync_pb::SendTabToSelfSpecifics>();
+void SendTabToSelfEntry::SetNotificationDismissed(bool notification_dismissed) {
+ notification_dismissed_ = notification_dismissed;
+}
+
+bool SendTabToSelfEntry::GetNotificationDismissed() const {
+ return notification_dismissed_;
+}
+
+SendTabToSelfLocal SendTabToSelfEntry::AsLocalProto() const {
+ SendTabToSelfLocal local_entry;
+ auto* pb_entry = local_entry.mutable_specifics();
pb_entry->set_guid(GetGUID());
pb_entry->set_title(GetTitle());
pb_entry->set_url(GetURL().spec());
- pb_entry->set_shared_time_usec(
- GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds());
+ pb_entry->set_shared_time_usec(TimeToProtoTime(GetSharedTime()));
pb_entry->set_navigation_time_usec(
- GetOriginalNavigationTime().ToDeltaSinceWindowsEpoch().InMicroseconds());
+ TimeToProtoTime(GetOriginalNavigationTime()));
pb_entry->set_device_name(GetDeviceName());
- return pb_entry;
+ local_entry.set_notification_dismissed(GetNotificationDismissed());
+
+ return local_entry;
}
std::unique_ptr<SendTabToSelfEntry> SendTabToSelfEntry::FromProto(
@@ -78,16 +107,14 @@ std::unique_ptr<SendTabToSelfEntry> SendTabToSelfEntry::FromProto(
GURL url(pb_entry.url());
DCHECK(url.is_valid());
- base::Time shared_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::TimeDelta::FromMicroseconds(pb_entry.shared_time_usec()));
+ base::Time shared_time = ProtoTimeToTime(pb_entry.shared_time_usec());
if (shared_time > now) {
shared_time = now;
}
base::Time navigation_time;
if (pb_entry.has_navigation_time_usec()) {
- navigation_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::TimeDelta::FromMicroseconds(pb_entry.navigation_time_usec()));
+ navigation_time = ProtoTimeToTime(pb_entry.navigation_time_usec());
}
return std::make_unique<SendTabToSelfEntry>(guid, url, pb_entry.title(),
@@ -95,4 +122,13 @@ std::unique_ptr<SendTabToSelfEntry> SendTabToSelfEntry::FromProto(
pb_entry.device_name());
}
+std::unique_ptr<SendTabToSelfEntry> SendTabToSelfEntry::FromLocalProto(
+ const SendTabToSelfLocal& local_entry,
+ base::Time now) {
+ std::unique_ptr<SendTabToSelfEntry> to_return =
+ FromProto(local_entry.specifics(), now);
+ to_return->SetNotificationDismissed(local_entry.notification_dismissed());
+ return to_return;
+}
+
} // namespace send_tab_to_self
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_entry.h b/chromium/components/send_tab_to_self/send_tab_to_self_entry.h
index ab0b98e7ee8..6b8011d1969 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_entry.h
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_entry.h
@@ -17,9 +17,12 @@ class SendTabToSelfSpecifics;
namespace send_tab_to_self {
+class SendTabToSelfLocal;
+
// A tab that is being shared. The URL is a unique identifier for an entry, as
// such it should not be empty and is the only thing considered when comparing
// entries.
+// The java version of this class: SendTabToSelfEntry.java
class SendTabToSelfEntry {
public:
// Creates a SendTabToSelf entry. |url| and |title| are the main fields of the
@@ -48,9 +51,13 @@ class SendTabToSelfEntry {
// The name of the device that originated the sent tab.
const std::string& GetDeviceName() const;
+ // The state of this entry's notification: if it has been |dismissed|.
+ void SetNotificationDismissed(bool notification_dismissed);
+ bool GetNotificationDismissed() const;
+
// Returns a protobuf encoding the content of this SendTabToSelfEntry for
- // sync.
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> AsProto() const;
+ // local storage.
+ SendTabToSelfLocal AsLocalProto() const;
// Creates a SendTabToSelfEntry from the protobuf format.
// If creation time is not set, it will be set to |now|.
@@ -58,6 +65,12 @@ class SendTabToSelfEntry {
const sync_pb::SendTabToSelfSpecifics& pb_entry,
base::Time now);
+ // Creates a SendTabToSelfEntry from the protobuf format.
+ // If creation time is not set, it will be set to |now|.
+ static std::unique_ptr<SendTabToSelfEntry> FromLocalProto(
+ const SendTabToSelfLocal& pb_entry,
+ base::Time now);
+
private:
std::string guid_;
GURL url_;
@@ -65,6 +78,7 @@ class SendTabToSelfEntry {
std::string device_name_;
base::Time shared_time_;
base::Time original_navigation_time_;
+ bool notification_dismissed_;
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfEntry);
};
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc b/chromium/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
index ba55592a0bd..a1006016d30 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/test/simple_test_tick_clock.h"
+#include "components/send_tab_to_self/proto/send_tab_to_self.pb.h"
#include "components/sync/protocol/send_tab_to_self_specifics.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,6 +24,20 @@ bool IsEqualForTesting(const SendTabToSelfEntry& a,
a.GetOriginalNavigationTime() == b.GetOriginalNavigationTime();
}
+bool IsEqualForTesting(const SendTabToSelfEntry& entry,
+ const sync_pb::SendTabToSelfSpecifics& specifics) {
+ return (
+ entry.GetGUID() == specifics.guid() &&
+ entry.GetURL() == specifics.url() &&
+ entry.GetTitle() == specifics.title() &&
+ entry.GetDeviceName() == specifics.device_name() &&
+ specifics.shared_time_usec() ==
+ entry.GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds() &&
+ specifics.navigation_time_usec() == entry.GetOriginalNavigationTime()
+ .ToDeltaSinceWindowsEpoch()
+ .InMicroseconds());
+}
+
TEST(SendTabToSelfEntry, CompareEntries) {
const SendTabToSelfEntry e1("1", GURL("http://example.com"), "bar",
base::Time::FromTimeT(10),
@@ -54,18 +69,8 @@ TEST(SendTabToSelfEntry, AsProto) {
SendTabToSelfEntry entry("1", GURL("http://example.com"), "bar",
base::Time::FromTimeT(10), base::Time::FromTimeT(10),
"device");
- base::Time shared_time = entry.GetSharedTime();
- base::Time navigation_time = entry.GetSharedTime();
-
- std::unique_ptr<sync_pb::SendTabToSelfSpecifics> pb_entry(entry.AsProto());
- EXPECT_EQ(pb_entry->url(), "http://example.com/");
- EXPECT_EQ(pb_entry->title(), "bar");
- EXPECT_EQ(pb_entry->shared_time_usec(),
- shared_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
-
- EXPECT_EQ(pb_entry->navigation_time_usec(),
- navigation_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
- EXPECT_EQ(pb_entry->device_name(), "device");
+ SendTabToSelfLocal pb_entry(entry.AsLocalProto());
+ EXPECT_TRUE(IsEqualForTesting(entry, pb_entry.specifics()));
}
// Tests that the send tab to self entry is correctly parsed from
@@ -83,16 +88,7 @@ TEST(SendTabToSelfEntry, FromProto) {
std::unique_ptr<SendTabToSelfEntry> entry(
SendTabToSelfEntry::FromProto(*pb_entry, base::Time::FromTimeT(10)));
- EXPECT_EQ(entry->GetGUID(), "1");
- EXPECT_EQ(entry->GetURL().spec(), "http://example.com/");
- EXPECT_EQ(entry->GetTitle(), "title");
- EXPECT_EQ(entry->GetDeviceName(), "device");
- EXPECT_EQ(entry->GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds(),
- 1);
- EXPECT_EQ(entry->GetOriginalNavigationTime()
- .ToDeltaSinceWindowsEpoch()
- .InMicroseconds(),
- 1);
+ EXPECT_TRUE(IsEqualForTesting(*entry, *pb_entry));
}
} // namespace
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_model.h b/chromium/components/send_tab_to_self/send_tab_to_self_model.h
index 6ae0a69dc53..6909d298560 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_model.h
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_model.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_H_
#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_H_
+#include <string>
#include <vector>
#include "base/observer_list.h"
@@ -32,10 +33,20 @@ class SendTabToSelfModel {
const std::string& guid) const = 0;
// Adds |url| at the top of the entries. The entry title will be a
- // trimmed copy of |title|.
+ // trimmed copy of |title|. Allows clients to modify the state of the model
+ // as driven by user behaviors.
+ // If the creation is successful this returns a pointer to the resulting
+ // Entry. Otherwise this will return nullptr.
virtual const SendTabToSelfEntry* AddEntry(const GURL& url,
- const std::string& title,
- base::Time navigation_time) = 0;
+ const std::string& title) = 0;
+
+ // Remove entry with |guid| from entries. Allows clients to modify the state
+ // of the model as driven by user behaviors.
+ virtual void DeleteEntry(const std::string& guid) = 0;
+
+ // Dismiss entry with |guid| from entries. Allows clients to modify the state
+ // of the model as driven by user behaviors.
+ virtual void DismissEntry(const std::string& guid) = 0;
// Observer registration methods. The model will remove all observers upon
// destruction automatically.
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_model_observer.h b/chromium/components/send_tab_to_self/send_tab_to_self_model_observer.h
index 54c471c9fbf..78589b614c9 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_model_observer.h
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_model_observer.h
@@ -5,8 +5,13 @@
#ifndef COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_OBSERVER_H_
#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_MODEL_OBSERVER_H_
+#include <string>
+#include <vector>
+
namespace send_tab_to_self {
+class SendTabToSelfEntry;
+
// Observer for the Send Tab To Self model. In the observer methods care should
// be taken to not modify the model.
class SendTabToSelfModelObserver {
@@ -18,8 +23,13 @@ class SendTabToSelfModelObserver {
// is unsafe to use the model.
virtual void SendTabToSelfModelLoaded() = 0;
- // Invoked when elements of the model are added, removed, or updated.
- virtual void SendTabToSelfModelChanged() = 0;
+ // Invoked when elements of the model are added or removed. This is the
+ // mechanism for the sync server to push changes in the state of the model to
+ // clients.
+ virtual void EntriesAddedRemotely(
+ const std::vector<const SendTabToSelfEntry*>& new_entries) = 0;
+ virtual void EntriesRemovedRemotely(
+ const std::vector<std::string>& guids) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfModelObserver);
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_service.cc b/chromium/components/send_tab_to_self/send_tab_to_self_sync_service.cc
index 49916b60bf5..64de49151a7 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_service.cc
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_sync_service.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/send_tab_to_self/send_tab_to_self_service.h"
+#include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
#include "base/bind.h"
#include "base/time/default_clock.h"
@@ -10,28 +10,33 @@
#include "components/send_tab_to_self/send_tab_to_self_model.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/device_info/local_device_info_provider.h"
+#include "components/sync/model/model_type_store.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
namespace send_tab_to_self {
-SendTabToSelfService::SendTabToSelfService(
+SendTabToSelfSyncService::SendTabToSelfSyncService() = default;
+
+SendTabToSelfSyncService::SendTabToSelfSyncService(
version_info::Channel channel,
- syncer::LocalDeviceInfoProvider* local_device_info_provider) {
+ syncer::LocalDeviceInfoProvider* local_device_info_provider,
+ syncer::OnceModelTypeStoreFactory create_store_callback) {
bridge_ = std::make_unique<send_tab_to_self::SendTabToSelfBridge>(
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::SEND_TAB_TO_SELF,
base::BindRepeating(&syncer::ReportUnrecoverableError, channel)),
- local_device_info_provider, base::DefaultClock::GetInstance());
+ local_device_info_provider, base::DefaultClock::GetInstance(),
+ std::move(create_store_callback));
}
-SendTabToSelfService::~SendTabToSelfService() = default;
+SendTabToSelfSyncService::~SendTabToSelfSyncService() = default;
-SendTabToSelfModel* SendTabToSelfService::GetSendTabToSelfModel() {
+SendTabToSelfModel* SendTabToSelfSyncService::GetSendTabToSelfModel() {
return bridge_.get();
}
base::WeakPtr<syncer::ModelTypeControllerDelegate>
-SendTabToSelfService::GetControllerDelegate() {
+SendTabToSelfSyncService::GetControllerDelegate() {
return bridge_->change_processor()->GetControllerDelegate();
}
diff --git a/chromium/components/send_tab_to_self/send_tab_to_self_service.h b/chromium/components/send_tab_to_self/send_tab_to_self_sync_service.h
index 44941a2933a..3d85da0c053 100644
--- a/chromium/components/send_tab_to_self/send_tab_to_self_service.h
+++ b/chromium/components/send_tab_to_self/send_tab_to_self_sync_service.h
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SERVICE_H_
-#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SERVICE_H_
+#ifndef COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SYNC_SERVICE_H_
+#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SYNC_SERVICE_H_
#include <memory>
#include <string>
#include "base/memory/weak_ptr.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "components/sync/model/model_type_store_service.h"
#include "components/version_info/channel.h"
namespace syncer {
@@ -22,24 +23,29 @@ class SendTabToSelfBridge;
class SendTabToSelfModel;
// KeyedService responsible for send tab to self sync.
-class SendTabToSelfService : public KeyedService {
+class SendTabToSelfSyncService : public KeyedService {
public:
- SendTabToSelfService(
+ SendTabToSelfSyncService(
version_info::Channel channel,
- syncer::LocalDeviceInfoProvider* local_device_info_provider);
- ~SendTabToSelfService() override;
+ syncer::LocalDeviceInfoProvider* local_device_info_provider,
+ syncer::OnceModelTypeStoreFactory create_store_callback);
+ ~SendTabToSelfSyncService() override;
- SendTabToSelfModel* GetSendTabToSelfModel();
+ virtual SendTabToSelfModel* GetSendTabToSelfModel();
// For ProfileSyncService to initialize the controller.
base::WeakPtr<syncer::ModelTypeControllerDelegate> GetControllerDelegate();
+ protected:
+ // Default constructor for unit tests
+ SendTabToSelfSyncService();
+
private:
std::unique_ptr<SendTabToSelfBridge> bridge_;
- DISALLOW_COPY_AND_ASSIGN(SendTabToSelfService);
+ DISALLOW_COPY_AND_ASSIGN(SendTabToSelfSyncService);
};
} // namespace send_tab_to_self
-#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SERVICE_H_
+#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_SYNC_SERVICE_H_
diff --git a/chromium/components/services/filesystem/BUILD.gn b/chromium/components/services/filesystem/BUILD.gn
index 21d8a9f500d..b251f7e948f 100644
--- a/chromium/components/services/filesystem/BUILD.gn
+++ b/chromium/components/services/filesystem/BUILD.gn
@@ -2,9 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//services/catalog/public/tools/catalog.gni")
import("//services/service_manager/public/cpp/service_executable.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//testing/test.gni")
static_library("lib") {
@@ -52,11 +50,6 @@ if (!is_ios) {
]
}
- service_manifest("manifest") {
- name = "filesystem"
- source = "manifest.json"
- }
-
test("filesystem_service_unittests") {
sources = [
"directory_impl_unittest.cc",
@@ -66,9 +59,9 @@ if (!is_ios) {
]
deps = [
- ":filesystem_service_unittests_catalog_source",
"//base",
"//base/test:test_support",
+ "//components/services/filesystem/public/cpp:manifest",
"//components/services/filesystem/public/interfaces",
"//mojo/core/test:run_all_unittests",
"//mojo/public/cpp/bindings",
@@ -82,20 +75,4 @@ if (!is_ios) {
":filesystem",
]
}
-
- service_manifest("test_manifest") {
- name = "filesystem_service_unittests"
- source = "test_manifest.json"
- }
-
- catalog("filesystem_service_unittests_catalog") {
- embedded_services = [ ":test_manifest" ]
- standalone_services = [ ":manifest" ]
- }
-
- catalog_cpp_source("filesystem_service_unittests_catalog_source") {
- testonly = true
- catalog = ":filesystem_service_unittests_catalog"
- generated_function_name = "filesystem::test::CreateTestCatalog"
- }
}
diff --git a/chromium/components/services/filesystem/OWNERS b/chromium/components/services/filesystem/OWNERS
deleted file mode 100644
index 21beb1aaa89..00000000000
--- a/chromium/components/services/filesystem/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
-
-per-file test_manifest.json=set noparent
-per-file test_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/filesystem/directory_impl_unittest.cc b/chromium/components/services/filesystem/directory_impl_unittest.cc
index ef2a1aeed6e..3a5c9c3ea40 100644
--- a/chromium/components/services/filesystem/directory_impl_unittest.cc
+++ b/chromium/components/services/filesystem/directory_impl_unittest.cc
@@ -10,6 +10,7 @@
#include "base/stl_util.h"
#include "components/services/filesystem/files_test_base.h"
+#include "components/services/filesystem/public/interfaces/directory.mojom.h"
namespace filesystem {
namespace {
diff --git a/chromium/components/services/filesystem/file_impl_unittest.cc b/chromium/components/services/filesystem/file_impl_unittest.cc
index 1aab2bb3459..f43e304220a 100644
--- a/chromium/components/services/filesystem/file_impl_unittest.cc
+++ b/chromium/components/services/filesystem/file_impl_unittest.cc
@@ -9,6 +9,7 @@
#include "base/files/file.h"
#include "components/services/filesystem/files_test_base.h"
+#include "components/services/filesystem/public/interfaces/directory.mojom.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/type_converter.h"
diff --git a/chromium/components/services/filesystem/file_system_app.cc b/chromium/components/services/filesystem/file_system_app.cc
index 8775ba4b0ed..61eee42c4e7 100644
--- a/chromium/components/services/filesystem/file_system_app.cc
+++ b/chromium/components/services/filesystem/file_system_app.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
diff --git a/chromium/components/services/filesystem/files_test_base.cc b/chromium/components/services/filesystem/files_test_base.cc
index 1429cfd5ba9..349bedf591d 100644
--- a/chromium/components/services/filesystem/files_test_base.cc
+++ b/chromium/components/services/filesystem/files_test_base.cc
@@ -6,17 +6,25 @@
#include <utility>
-#include "components/services/filesystem/filesystem_service_unittests_catalog_source.h"
+#include "components/services/filesystem/public/cpp/manifest.h"
#include "components/services/filesystem/public/interfaces/directory.mojom.h"
#include "components/services/filesystem/public/interfaces/types.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
namespace filesystem {
+const char kTestServiceName[] = "filesystem_service_unittests";
+
FilesTestBase::FilesTestBase()
- : test_service_manager_(test::CreateTestCatalog()),
- test_service_(test_service_manager_.RegisterTestInstance(
- "filesystem_service_unittests")) {}
+ : test_service_manager_(
+ {GetManifest(),
+ service_manager::ManifestBuilder()
+ .WithServiceName(kTestServiceName)
+ .RequireCapability("filesystem", "filesystem:filesystem")
+ .Build()}),
+ test_service_(
+ test_service_manager_.RegisterTestInstance(kTestServiceName)) {}
FilesTestBase::~FilesTestBase() {}
diff --git a/chromium/components/services/filesystem/manifest.json b/chromium/components/services/filesystem/manifest.json
deleted file mode 100644
index 5e2e1647432..00000000000
--- a/chromium/components/services/filesystem/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "filesystem",
- "display_name": "File System Service",
- "sandbox_type": "none",
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "filesystem:filesystem": [ "filesystem.mojom.FileSystem" ]
- },
- "requires": {
- "*": [ "app" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/filesystem/public/cpp/BUILD.gn b/chromium/components/services/filesystem/public/cpp/BUILD.gn
new file mode 100644
index 00000000000..e72b73223cb
--- /dev/null
+++ b/chromium/components/services/filesystem/public/cpp/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/filesystem/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/filesystem/public/cpp/OWNERS b/chromium/components/services/filesystem/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/filesystem/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/filesystem/public/cpp/manifest.cc b/chromium/components/services/filesystem/public/cpp/manifest.cc
new file mode 100644
index 00000000000..b27bfe37984
--- /dev/null
+++ b/chromium/components/services/filesystem/public/cpp/manifest.cc
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/filesystem/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/filesystem/public/interfaces/file_system.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace filesystem {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName("filesystem")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("none")
+ .Build())
+ .ExposeCapability(
+ "filesystem:filesystem",
+ service_manager::Manifest::InterfaceList<mojom::FileSystem>())
+ .Build()};
+ return *manifest;
+}
+
+} // namespace filesystem
diff --git a/chromium/components/services/filesystem/public/cpp/manifest.h b/chromium/components/services/filesystem/public/cpp/manifest.h
new file mode 100644
index 00000000000..2009ebf1cc0
--- /dev/null
+++ b/chromium/components/services/filesystem/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_FILESYSTEM_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_FILESYSTEM_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace filesystem {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace filesystem
+
+#endif // COMPONENTS_SERVICES_FILESYSTEM_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/filesystem/test_manifest.json b/chromium/components/services/filesystem/test_manifest.json
deleted file mode 100644
index 219c700d3ad..00000000000
--- a/chromium/components/services/filesystem/test_manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "filesystem_service_unittests",
- "display_name": "Filesystem Service Unittests",
- "interface_provider_specs": {
- "service_manager:connector": {
- "requires": {
- "filesystem": [ "filesystem:filesystem" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/font/BUILD.gn b/chromium/components/services/font/BUILD.gn
index 1c1e289f0d3..891bf031771 100644
--- a/chromium/components/services/font/BUILD.gn
+++ b/chromium/components/services/font/BUILD.gn
@@ -4,9 +4,7 @@
import("//build/config/features.gni")
import("//ppapi/buildflags/buildflags.gni")
-import("//services/catalog/public/tools/catalog.gni")
import("//services/service_manager/public/cpp/service_executable.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//testing/test.gni")
source_set("lib") {
@@ -70,21 +68,16 @@ service_executable("font_service") {
]
}
-service_manifest("manifest") {
- name = "font_service"
- source = "manifest.json"
-}
-
test("font_service_unittests") {
sources = [
"font_loader_unittest.cc",
]
deps = [
- ":font_service_unittests_catalog_source",
"//base",
"//base/test:test_support",
"//components/services/font/public/cpp",
+ "//components/services/font/public/cpp:manifest",
"//components/services/font/public/interfaces",
"//mojo/core/test:run_all_unittests",
"//mojo/public/cpp/bindings",
@@ -107,19 +100,3 @@ test("font_service_unittests") {
":font_service",
]
}
-
-service_manifest("test_manifest") {
- name = "font_service_unittests"
- source = "test_manifest.json"
-}
-
-catalog("font_service_unittests_catalog") {
- embedded_services = [ ":test_manifest" ]
- standalone_services = [ ":manifest" ]
-}
-
-catalog_cpp_source("font_service_unittests_catalog_source") {
- testonly = true
- catalog = ":font_service_unittests_catalog"
- generated_function_name = "font_service::test::CreateTestCatalog"
-}
diff --git a/chromium/components/services/font/OWNERS b/chromium/components/services/font/OWNERS
index 3d43cf0bd5f..f196c8221df 100644
--- a/chromium/components/services/font/OWNERS
+++ b/chromium/components/services/font/OWNERS
@@ -1,6 +1 @@
drott@chromium.org
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
-per-file test_manifest.json=set noparent
-per-file test_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/font/font_loader_unittest.cc b/chromium/components/services/font/font_loader_unittest.cc
index d7ec44d0ed4..c7984dbb6f5 100644
--- a/chromium/components/services/font/font_loader_unittest.cc
+++ b/chromium/components/services/font/font_loader_unittest.cc
@@ -7,12 +7,13 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
-#include "components/services/font/font_service_unittests_catalog_source.h"
#include "components/services/font/public/cpp/font_loader.h"
+#include "components/services/font/public/cpp/manifest.h"
#include "components/services/font/public/interfaces/constants.mojom.h"
#include "components/services/font/public/interfaces/font_service.mojom.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
#include "services/service_manager/public/cpp/test/test_service.h"
#include "services/service_manager/public/cpp/test/test_service_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -56,12 +57,19 @@ std::string GetPostscriptNameFromFile(base::File& font_file) {
}
#endif
+const char kTestServiceName[] = "font_service_unittests";
+
class FontLoaderTest : public testing::Test {
public:
FontLoaderTest()
- : test_service_manager_(test::CreateTestCatalog()),
- test_service_(test_service_manager_.RegisterTestInstance(
- "font_service_unittests")),
+ : test_service_manager_(
+ {GetManifest(),
+ service_manager::ManifestBuilder()
+ .WithServiceName(kTestServiceName)
+ .RequireCapability(mojom::kServiceName, "font_service")
+ .Build()}),
+ test_service_(
+ test_service_manager_.RegisterTestInstance(kTestServiceName)),
font_loader_(test_service_.connector()) {}
~FontLoaderTest() override = default;
diff --git a/chromium/components/services/font/font_service_app.cc b/chromium/components/services/font/font_service_app.cc
index 61a04625147..18d940cc760 100644
--- a/chromium/components/services/font/font_service_app.cc
+++ b/chromium/components/services/font/font_service_app.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
diff --git a/chromium/components/services/font/fontconfig_matching.cc b/chromium/components/services/font/fontconfig_matching.cc
index 0f8bc78cfde..8b2f3b11297 100644
--- a/chromium/components/services/font/fontconfig_matching.cc
+++ b/chromium/components/services/font/fontconfig_matching.cc
@@ -64,9 +64,15 @@ FontConfigLocalMatching::FindFontBySpecifiedName(
FcPattern* current = font_set->fonts[0];
- FcChar8* c_filename;
- if (FcPatternGetString(current, FC_FILE, 0, &c_filename) != FcResultMatch)
+ const char* c_filename;
+ if (FcPatternGetString(current, FC_FILE, 0,
+ reinterpret_cast<FcChar8**>(const_cast<char**>(
+ &c_filename))) != FcResultMatch) {
return base::nullopt;
+ }
+ const char* sysroot =
+ reinterpret_cast<const char*>(FcConfigGetSysRoot(nullptr));
+ const std::string filename = std::string(sysroot ? sysroot : "") + c_filename;
// We only want to return sfnt (TrueType) based fonts. We don't have a
// very good way of detecting this so we'll filter based on the
@@ -78,8 +84,8 @@ FontConfigLocalMatching::FindFontBySpecifiedName(
// None of the extensions matched.
break;
}
- if (base::EndsWith(std::string(reinterpret_cast<char*>(c_filename)),
- kSFNTExtensions[j], base::CompareCase::SENSITIVE)) {
+ if (base::EndsWith(filename, kSFNTExtensions[j],
+ base::CompareCase::SENSITIVE)) {
is_sfnt = true;
break;
}
@@ -88,7 +94,7 @@ FontConfigLocalMatching::FindFontBySpecifiedName(
if (!is_sfnt)
return base::nullopt;
- base::FilePath font_file_path(reinterpret_cast<const char*>(c_filename));
+ base::FilePath font_file_path(filename);
base::File verify_file_exists(font_file_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!verify_file_exists.IsValid())
diff --git a/chromium/components/services/font/manifest.json b/chromium/components/services/font/manifest.json
deleted file mode 100644
index 8af075897b6..00000000000
--- a/chromium/components/services/font/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "font_service",
- "display_name": "Font Service",
- "sandbox_type": "none",
- "options" : {
- "instance_sharing" : "shared_instance_across_users"
- },
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "font_service": [ "font_service.mojom.FontService" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/font/ppapi_fontconfig_matching.cc b/chromium/components/services/font/ppapi_fontconfig_matching.cc
index 42f40e7469c..731779843bd 100644
--- a/chromium/components/services/font/ppapi_fontconfig_matching.cc
+++ b/chromium/components/services/font/ppapi_fontconfig_matching.cc
@@ -170,6 +170,10 @@ int MatchFontFaceWithFallback(const std::string& face,
int good_enough_index = -1;
bool good_enough_index_set = false;
+ const char* c_filename;
+ const char* c_sysroot =
+ reinterpret_cast<const char*>(FcConfigGetSysRoot(nullptr));
+ const std::string sysroot = c_sysroot ? c_sysroot : "";
if (font_set) {
for (int i = 0; i < font_set->nfont; ++i) {
FcPattern* current = font_set->fonts[i];
@@ -183,11 +187,12 @@ int MatchFontFaceWithFallback(const std::string& face,
continue;
}
- FcChar8* c_filename;
- if (FcPatternGetString(current, FC_FILE, 0, &c_filename) !=
- FcResultMatch) {
+ if (FcPatternGetString(current, FC_FILE, 0,
+ reinterpret_cast<FcChar8**>(const_cast<char**>(
+ &c_filename))) != FcResultMatch) {
continue;
}
+ const std::string filename = sysroot + c_filename;
// We only want to return sfnt (TrueType) based fonts. We don't have a
// very good way of detecting this so we'll filter based on the
@@ -200,8 +205,8 @@ int MatchFontFaceWithFallback(const std::string& face,
// None of the extensions matched.
break;
}
- if (base::EndsWith(std::string(reinterpret_cast<char*>(c_filename)),
- kSFNTExtensions[j], base::CompareCase::SENSITIVE)) {
+ if (base::EndsWith(filename, kSFNTExtensions[j],
+ base::CompareCase::SENSITIVE)) {
is_sfnt = true;
break;
}
@@ -236,8 +241,7 @@ int MatchFontFaceWithFallback(const std::string& face,
continue;
}
- font_fd =
- HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY));
+ font_fd = HANDLE_EINTR(open(filename.c_str(), O_RDONLY));
if (font_fd >= 0)
break;
}
@@ -247,9 +251,12 @@ int MatchFontFaceWithFallback(const std::string& face,
// We didn't find a font that we liked, so we fallback to something
// acceptable.
FcPattern* current = font_set->fonts[good_enough_index];
- FcChar8* c_filename;
- FcPatternGetString(current, FC_FILE, 0, &c_filename);
- font_fd = HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY));
+ if (!FcPatternGetString(
+ current, FC_FILE, 0,
+ reinterpret_cast<FcChar8**>(const_cast<char**>(&c_filename)))) {
+ const std::string filename = sysroot + c_filename;
+ font_fd = HANDLE_EINTR(open(filename.c_str(), O_RDONLY));
+ }
}
if (font_set)
diff --git a/chromium/components/services/font/public/cpp/BUILD.gn b/chromium/components/services/font/public/cpp/BUILD.gn
index da5ce239c02..e553167a534 100644
--- a/chromium/components/services/font/public/cpp/BUILD.gn
+++ b/chromium/components/services/font/public/cpp/BUILD.gn
@@ -22,3 +22,16 @@ source_set("cpp") {
"//skia",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/font/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/font/public/cpp/OWNERS b/chromium/components/services/font/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/font/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/font/public/cpp/font_loader.cc b/chromium/components/services/font/public/cpp/font_loader.cc
index 7fca69775c9..6342887e7b3 100644
--- a/chromium/components/services/font/public/cpp/font_loader.cc
+++ b/chromium/components/services/font/public/cpp/font_loader.cc
@@ -22,25 +22,20 @@ FontLoader::FontLoader(service_manager::Connector* connector) {
FontLoader::~FontLoader() {}
-void FontLoader::Shutdown() {
- thread_->Stop();
- thread_ = nullptr;
-}
-
bool FontLoader::matchFamilyName(const char family_name[],
SkFontStyle requested,
FontIdentity* out_font_identifier,
SkString* out_family_name,
SkFontStyle* out_style) {
- TRACE_EVENT1("font_service", "FontServiceThread::MatchFamilyName",
- "family_name", family_name);
+ TRACE_EVENT1("fonts", "FontServiceThread::MatchFamilyName", "family_name",
+ TRACE_STR_COPY(family_name));
return thread_->MatchFamilyName(family_name, requested, out_font_identifier,
out_family_name, out_style);
}
SkStreamAsset* FontLoader::openStream(const FontIdentity& identity) {
- TRACE_EVENT2("font_loader", "FontLoader::openStream", "identity",
- identity.fID, "name", identity.fString.c_str());
+ TRACE_EVENT2("fonts", "FontLoader::openStream", "identity", identity.fID,
+ "name", TRACE_STR_COPY(identity.fString.c_str()));
{
base::AutoLock lock(lock_);
auto mapped_font_files_it = mapped_font_files_.find(identity.fID);
@@ -110,8 +105,8 @@ void FontLoader::MatchFontWithFallback(std::string family,
}
void FontLoader::OnMappedFontFileDestroyed(internal::MappedFontFile* f) {
- TRACE_EVENT1("font_loader", "FontLoader::OnMappedFontFileDestroyed",
- "identity", f->font_id());
+ TRACE_EVENT1("fonts", "FontLoader::OnMappedFontFileDestroyed", "identity",
+ f->font_id());
base::AutoLock lock(lock_);
mapped_font_files_.erase(f->font_id());
}
diff --git a/chromium/components/services/font/public/cpp/font_loader.h b/chromium/components/services/font/public/cpp/font_loader.h
index 602d5f924d5..96fc2b28511 100644
--- a/chromium/components/services/font/public/cpp/font_loader.h
+++ b/chromium/components/services/font/public/cpp/font_loader.h
@@ -37,9 +37,6 @@ class FontLoader : public SkFontConfigInterface,
explicit FontLoader(service_manager::Connector* connector);
~FontLoader() override;
- // Shuts down the background thread.
- void Shutdown();
-
// SkFontConfigInterface:
bool matchFamilyName(const char family_name[],
SkFontStyle requested,
diff --git a/chromium/components/services/font/public/cpp/font_service_thread.cc b/chromium/components/services/font/public/cpp/font_service_thread.cc
index d18ed963f40..5e39791b273 100644
--- a/chromium/components/services/font/public/cpp/font_service_thread.cc
+++ b/chromium/components/services/font/public/cpp/font_service_thread.cc
@@ -9,36 +9,35 @@
#include "base/bind.h"
#include "base/files/file.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "components/services/font/public/cpp/mapped_font_file.h"
namespace font_service {
namespace internal {
-namespace {
-const char kFontThreadName[] = "Font_Proxy_Thread";
-} // namespace
-
FontServiceThread::FontServiceThread(mojom::FontServicePtr font_service)
- : base::Thread(kFontThreadName),
- font_service_info_(font_service.PassInterface()),
+ : font_service_info_(font_service.PassInterface()),
+ task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+ {base::TaskPriority::USER_VISIBLE, base::MayBlock()})),
weak_factory_(this) {
- DETACH_FROM_THREAD(thread_checker_);
- Start();
+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&FontServiceThread::Init,
+ weak_factory_.GetWeakPtr()));
}
+FontServiceThread::~FontServiceThread() {}
+
bool FontServiceThread::MatchFamilyName(
const char family_name[],
SkFontStyle requested_style,
SkFontConfigInterface::FontIdentity* out_font_identity,
SkString* out_family_name,
SkFontStyle* out_style) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
-
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
bool out_valid = false;
// This proxies to the other thread, which proxies to mojo. Only on the reply
// from mojo do we return from this.
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FontServiceThread::MatchFamilyNameImpl, this, &done_event,
family_name, requested_style, &out_valid,
@@ -55,10 +54,10 @@ bool FontServiceThread::FallbackFontForCharacter(
std::string* out_family_name,
bool* out_is_bold,
bool* out_is_italic) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
bool out_valid = false;
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FontServiceThread::FallbackFontForCharacterImpl, this,
&done_event, character, std::move(locale), &out_valid,
@@ -76,10 +75,10 @@ bool FontServiceThread::FontRenderStyleForStrike(
bool is_bold,
float device_scale_factor,
font_service::mojom::FontRenderStylePtr* out_font_render_style) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
bool out_valid = false;
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FontServiceThread::FontRenderStyleForStrikeImpl, this,
&done_event, family, size, is_italic, is_bold,
@@ -91,10 +90,10 @@ bool FontServiceThread::FontRenderStyleForStrike(
bool FontServiceThread::MatchFontByPostscriptNameOrFullFontName(
std::string postscript_name_or_full_font_name,
mojom::FontIdentityPtr* out_identity) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
bool out_valid = false;
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&FontServiceThread::MatchFontByPostscriptNameOrFullFontNameImpl, this,
@@ -111,9 +110,9 @@ void FontServiceThread::MatchFontWithFallback(
uint32_t charset,
uint32_t fallback_family_type,
base::File* out_font_file_handle) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FontServiceThread::MatchFontWithFallbackImpl, this,
&done_event, std::move(family), is_bold, is_italic,
@@ -123,13 +122,13 @@ void FontServiceThread::MatchFontWithFallback(
scoped_refptr<MappedFontFile> FontServiceThread::OpenStream(
const SkFontConfigInterface::FontIdentity& identity) {
- DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
base::File stream_file;
// This proxies to the other thread, which proxies to mojo. Only on the
// reply from mojo do we return from this.
base::WaitableEvent done_event;
- task_runner()->PostTask(
+ task_runner_->PostTask(
FROM_HERE, base::BindOnce(&FontServiceThread::OpenStreamImpl, this,
&done_event, &stream_file, identity.fID));
done_event.Wait();
@@ -148,10 +147,6 @@ scoped_refptr<MappedFontFile> FontServiceThread::OpenStream(
return mapped_font_file;
}
-FontServiceThread::~FontServiceThread() {
- Stop();
-}
-
void FontServiceThread::MatchFamilyNameImpl(
base::WaitableEvent* done_event,
const char family_name[],
@@ -160,7 +155,7 @@ void FontServiceThread::MatchFamilyNameImpl(
SkFontConfigInterface::FontIdentity* out_font_identity,
SkString* out_family_name,
SkFontStyle* out_style) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (font_service_.encountered_error()) {
*out_valid = false;
@@ -192,7 +187,8 @@ void FontServiceThread::OnMatchFamilyNameComplete(
mojom::FontIdentityPtr font_identity,
const std::string& family_name,
mojom::TypefaceStylePtr style) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*out_valid = !font_identity.is_null();
@@ -214,7 +210,8 @@ void FontServiceThread::OnMatchFamilyNameComplete(
void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event,
base::File* output_file,
const uint32_t id_number) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
if (font_service_.encountered_error()) {
done_event->Signal();
return;
@@ -229,7 +226,8 @@ void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event,
void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event,
base::File* output_file,
base::File file) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*output_file = std::move(file);
done_event->Signal();
@@ -244,7 +242,7 @@ void FontServiceThread::FallbackFontForCharacterImpl(
std::string* out_family_name,
bool* out_is_bold,
bool* out_is_italic) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (font_service_.encountered_error()) {
*out_valid = false;
@@ -271,7 +269,8 @@ void FontServiceThread::OnFallbackFontForCharacterComplete(
const std::string& family_name,
bool is_bold,
bool is_italic) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*out_valid = !font_identity.is_null();
@@ -293,7 +292,7 @@ void FontServiceThread::FontRenderStyleForStrikeImpl(
float device_scale_factor,
bool* out_valid,
mojom::FontRenderStylePtr* out_font_render_style) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (font_service_.encountered_error()) {
*out_valid = false;
@@ -313,7 +312,8 @@ void FontServiceThread::OnFontRenderStyleForStrikeComplete(
bool* out_valid,
mojom::FontRenderStylePtr* out_font_render_style,
mojom::FontRenderStylePtr font_render_style) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*out_valid = !font_render_style.is_null();
@@ -328,7 +328,7 @@ void FontServiceThread::MatchFontByPostscriptNameOrFullFontNameImpl(
bool* out_valid,
std::string postscript_name_or_full_font_name,
mojom::FontIdentityPtr* out_font_identity) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (font_service_.encountered_error()) {
*out_valid = false;
@@ -349,7 +349,8 @@ void FontServiceThread::OnMatchFontByPostscriptNameOrFullFontNameComplete(
bool* out_valid,
mojom::FontIdentityPtr* out_font_identity,
mojom::FontIdentityPtr font_identity) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*out_valid = !font_identity.is_null();
@@ -367,7 +368,8 @@ void FontServiceThread::MatchFontWithFallbackImpl(
uint32_t charset,
uint32_t fallback_family_type,
base::File* out_font_file_handle) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
*out_font_file_handle = base::File();
if (font_service_.encountered_error()) {
done_event->Signal();
@@ -384,7 +386,8 @@ void FontServiceThread::OnMatchFontWithFallbackComplete(
base::WaitableEvent* done_event,
base::File* out_font_file_handle,
base::File file) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
pending_waitable_events_.erase(done_event);
*out_font_file_handle = std::move(file);
@@ -405,9 +408,5 @@ void FontServiceThread::Init() {
weak_factory_.GetWeakPtr()));
}
-void FontServiceThread::CleanUp() {
- font_service_.reset();
-}
-
} // namespace internal
} // namespace font_service
diff --git a/chromium/components/services/font/public/cpp/font_service_thread.h b/chromium/components/services/font/public/cpp/font_service_thread.h
index 186a9042807..33fe6bd7876 100644
--- a/chromium/components/services/font/public/cpp/font_service_thread.h
+++ b/chromium/components/services/font/public/cpp/font_service_thread.h
@@ -12,8 +12,6 @@
#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
#include "components/services/font/public/interfaces/font_service.mojom.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
@@ -31,8 +29,8 @@ class MappedFontFile;
// of this mismatch, we create a thread which owns the mojo pipe, sends and
// receives messages. The multiple threads which call through FontLoader class
// do blocking message calls to this thread.
-class FontServiceThread : public base::Thread,
- public base::RefCountedThreadSafe<FontServiceThread> {
+// TODO(936569): Rename FontServiceThread since it's no longer a thread.
+class FontServiceThread : public base::RefCountedThreadSafe<FontServiceThread> {
public:
explicit FontServiceThread(mojom::FontServicePtr font_service);
@@ -72,7 +70,9 @@ class FontServiceThread : public base::Thread,
private:
friend class base::RefCountedThreadSafe<FontServiceThread>;
- ~FontServiceThread() override;
+ virtual ~FontServiceThread();
+
+ void Init();
// Methods which run on the FontServiceThread. The public MatchFamilyName
// calls this method, this method calls the mojo interface, and sets up the
@@ -169,17 +169,13 @@ class FontServiceThread : public base::Thread,
// thread.
void OnFontServiceConnectionError();
- // base::Thread
- void Init() override;
- void CleanUp() override;
-
// This member is used to safely pass data from one thread to another. It is
// set in the constructor and is consumed in Init().
- mojo::InterfacePtrInfo<mojom::FontService> font_service_info_;
+ mojom::FontServicePtrInfo font_service_info_;
// This member is set in Init(). It takes |font_service_info_|, which is
// non-thread bound, and binds it to the newly created thread.
- mojo::InterfacePtr<mojom::FontService> font_service_;
+ mojom::FontServicePtr font_service_;
// All WaitableEvents supplied to OpenStreamImpl() and the other *Impl()
// functions are added here while waiting on the response from the
@@ -190,8 +186,7 @@ class FontServiceThread : public base::Thread,
// never received.
std::set<base::WaitableEvent*> pending_waitable_events_;
- THREAD_CHECKER(thread_checker_);
-
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
base::WeakPtrFactory<FontServiceThread> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FontServiceThread);
diff --git a/chromium/components/services/font/public/cpp/manifest.cc b/chromium/components/services/font/public/cpp/manifest.cc
new file mode 100644
index 00000000000..dc6e07ceb10
--- /dev/null
+++ b/chromium/components/services/font/public/cpp/manifest.cc
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/font/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/font/public/interfaces/constants.mojom.h"
+#include "components/services/font/public/interfaces/font_service.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace font_service {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("Font Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("none")
+ .WithInstanceSharingPolicy(
+ service_manager::Manifest::
+ InstanceSharingPolicy::kSharedAcrossGroups)
+ .Build())
+ .ExposeCapability(
+ "font_service",
+ service_manager::Manifest::InterfaceList<mojom::FontService>())
+ .Build()};
+ return *manifest;
+}
+
+} // namespace font_service
diff --git a/chromium/components/services/font/public/cpp/manifest.h b/chromium/components/services/font/public/cpp/manifest.h
new file mode 100644
index 00000000000..1c2c50154ee
--- /dev/null
+++ b/chromium/components/services/font/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_FONT_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_FONT_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace font_service {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace font_service
+
+#endif // COMPONENTS_SERVICES_FONT_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/font/test_manifest.json b/chromium/components/services/font/test_manifest.json
deleted file mode 100644
index a9689872f50..00000000000
--- a/chromium/components/services/font/test_manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "font_service_unittests",
- "display_name": "Font Service Unittests",
- "interface_provider_specs": {
- "service_manager:connector": {
- "requires": {
- "font_service": [ "font_service" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/heap_profiling/BUILD.gn b/chromium/components/services/heap_profiling/BUILD.gn
index 6c187318d9c..a319417b299 100644
--- a/chromium/components/services/heap_profiling/BUILD.gn
+++ b/chromium/components/services/heap_profiling/BUILD.gn
@@ -2,7 +2,6 @@
# 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/service_manifest.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
static_library("heap_profiling") {
@@ -62,11 +61,6 @@ source_set("unit_tests") {
]
}
-service_manifest("manifest") {
- name = "heap_profiling"
- source = "heap_profiling_manifest.json"
-}
-
fuzzer_test("profiling_fuzzer") {
sources = [
"stream_fuzzer.cc",
diff --git a/chromium/components/services/heap_profiling/OWNERS b/chromium/components/services/heap_profiling/OWNERS
index 80cbc1b2709..987c0c88a4a 100644
--- a/chromium/components/services/heap_profiling/OWNERS
+++ b/chromium/components/services/heap_profiling/OWNERS
@@ -1,4 +1 @@
erikchen@chromium.org
-
-per-file heap_profiling_manifest.json=set noparent
-per-file heap_profiling_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/heap_profiling/allocation_tracker.cc b/chromium/components/services/heap_profiling/allocation_tracker.cc
index 97bb4ea2b19..01fe57c02fc 100644
--- a/chromium/components/services/heap_profiling/allocation_tracker.cc
+++ b/chromium/components/services/heap_profiling/allocation_tracker.cc
@@ -4,6 +4,7 @@
#include "components/services/heap_profiling/allocation_tracker.h"
+#include "base/bind.h"
#include "base/callback.h"
#include "base/json/string_escape.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/services/heap_profiling/connection_manager.cc b/chromium/components/services/heap_profiling/connection_manager.cc
index 2a115e11843..d3965bfefd7 100644
--- a/chromium/components/services/heap_profiling/connection_manager.cc
+++ b/chromium/components/services/heap_profiling/connection_manager.cc
@@ -5,6 +5,7 @@
#include "components/services/heap_profiling/connection_manager.h"
#include "base/bind.h"
+#include "base/json/string_escape.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/metrics/histogram_macros.h"
@@ -74,13 +75,15 @@ struct ConnectionManager::Connection {
scoped_refptr<ReceiverPipe> p,
mojom::ProcessType process_type,
uint32_t sampling_rate,
- mojom::StackMode stack_mode)
+ mojom::StackMode stack_mode,
+ bool stream_samples)
: thread(base::StringPrintf("Sender %lld thread",
static_cast<long long>(pid))),
client(std::move(client)),
pipe(p),
process_type(process_type),
stack_mode(stack_mode),
+ stream_samples(stream_samples),
tracker(std::move(complete_cb), backtrace_storage),
sampling_rate(sampling_rate) {}
@@ -103,6 +106,7 @@ struct ConnectionManager::Connection {
scoped_refptr<StreamParser> parser;
mojom::ProcessType process_type;
mojom::StackMode stack_mode;
+ bool stream_samples;
// Danger: This lives on the |thread| member above. The connection manager
// lives on the I/O thread, so accesses to the variable must be synchronized.
@@ -147,25 +151,25 @@ void ConnectionManager::OnNewConnection(base::ProcessId pid,
// when the user is attempting to manually start profiling for processes, so
// we ignore this edge case.
- scoped_refptr<ReceiverPipe> new_pipe = new ReceiverPipe(
+ scoped_refptr<ReceiverPipe> new_pipe = base::MakeRefCounted<ReceiverPipe>(
mojo::UnwrapPlatformHandle(std::move(receiver_pipe_end)));
// The allocation tracker will call this on a background thread, so thunk
// back to the current thread with weak pointers.
- AllocationTracker::CompleteCallback complete_cb =
- base::BindOnce(&ConnectionManager::OnConnectionCompleteThunk,
- base::MessageLoopCurrent::Get()->task_runner(),
- weak_factory_.GetWeakPtr(), pid);
+ AllocationTracker::CompleteCallback complete_cb = base::BindOnce(
+ &ConnectionManager::OnConnectionCompleteThunk,
+ base::ThreadTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr(), pid);
auto connection = std::make_unique<Connection>(
std::move(complete_cb), &backtrace_storage_, pid, std::move(client),
- new_pipe, process_type, params->sampling_rate, params->stack_mode);
+ new_pipe, process_type, params->sampling_rate, params->stack_mode,
+ params->stream_samples);
base::Thread::Options options;
options.message_loop_type = base::MessageLoop::TYPE_IO;
connection->thread.StartWithOptions(options);
- connection->parser = new StreamParser(&connection->tracker);
+ connection->parser = base::MakeRefCounted<StreamParser>(&connection->tracker);
new_pipe->SetReceiver(connection->thread.task_runner(), connection->parser);
connection->thread.task_runner()->PostTask(
@@ -182,9 +186,8 @@ std::vector<base::ProcessId> ConnectionManager::GetConnectionPids() {
base::AutoLock lock(connections_lock_);
std::vector<base::ProcessId> results;
results.reserve(connections_.size());
- for (const auto& pair : connections_) {
+ for (const auto& pair : connections_)
results.push_back(pair.first);
- }
return results;
}
@@ -248,19 +251,23 @@ void ConnectionManager::DumpProcessesForTracing(
tracking->vm_regions = std::move(vm_regions);
tracking->results.reserve(connections_.size());
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- base::MessageLoopCurrent::Get()->task_runner();
-
for (auto& it : connections_) {
base::ProcessId pid = it.first;
Connection* connection = it.second.get();
+ if (!connection->stream_samples) {
+ connection->client->RetrieveHeapProfile(base::BindOnce(
+ &ConnectionManager::HeapProfileRetrieved, weak_factory_.GetWeakPtr(),
+ tracking, pid, connection->process_type, keep_small_allocations,
+ strip_path_from_mapped_files, connection->sampling_rate));
+ continue;
+ }
int barrier_id = next_barrier_id_++;
// Register for callback before requesting the dump so we don't race for the
// signal. The callback will be issued on the allocation tracker thread so
// need to thunk back to the I/O thread.
connection->tracker.SnapshotOnBarrier(
- barrier_id, task_runner,
+ barrier_id, base::ThreadTaskRunnerHandle::Get(),
base::BindOnce(&ConnectionManager::DoDumpOneProcessForTracing,
weak_factory_.GetWeakPtr(), tracking, pid,
connection->process_type, keep_small_allocations,
@@ -270,6 +277,66 @@ void ConnectionManager::DumpProcessesForTracing(
}
}
+void ConnectionManager::HeapProfileRetrieved(
+ scoped_refptr<DumpProcessesForTracingTracking> tracking,
+ base::ProcessId pid,
+ mojom::ProcessType process_type,
+ bool keep_small_allocations,
+ bool strip_path_from_mapped_files,
+ uint32_t sampling_rate,
+ mojom::HeapProfilePtr profile) {
+ AllocationCountMap counts;
+ AllocationTracker::ContextMap context_map;
+ AllocationTracker::AddressToStringMap string_map;
+ BacktraceStorage backtrace_storage;
+ BacktraceStorage::Lock backtrace_storage_lock(&backtrace_storage);
+
+ bool success = true;
+ for (const mojom::HeapProfileSamplePtr& sample : profile->samples) {
+ int context_id = 0;
+ if (sample->context_id) {
+ auto it = profile->strings.find(sample->context_id);
+ if (it == profile->strings.end()) {
+ success = false;
+ break;
+ }
+ const std::string& context = it->second;
+ // Escape the strings early, to simplify exporting a heap dump.
+ std::string escaped_context;
+ base::EscapeJSONString(context, false /* put_in_quotes */,
+ &escaped_context);
+ context_id = context_map
+ .emplace(std::move(escaped_context),
+ static_cast<int>(context_map.size() + 1))
+ .first->second;
+ }
+ const Backtrace* backtrace = backtrace_storage.Insert(
+ std::vector<Address>(sample->stack.begin(), sample->stack.end()));
+ AllocatorType allocator = static_cast<AllocatorType>(sample->allocator);
+ if (allocator >= AllocatorType::kCount) {
+ success = false;
+ break;
+ }
+ AllocationEvent alloc(allocator, Address(0), sample->size, backtrace,
+ context_id);
+ ++counts[alloc];
+ }
+
+ for (const auto& str : profile->strings) {
+ std::string quoted_string;
+ // Escape the strings before saving them, to simplify exporting a heap dump.
+ base::EscapeJSONString(str.second, false /* put_in_quotes */,
+ &quoted_string);
+ string_map.emplace(str.first, std::move(quoted_string));
+ }
+
+ DCHECK(success);
+ DoDumpOneProcessForTracing(
+ tracking, pid, process_type, keep_small_allocations,
+ strip_path_from_mapped_files, sampling_rate, success, std::move(counts),
+ std::move(context_map), std::move(string_map));
+}
+
void ConnectionManager::DoDumpOneProcessForTracing(
scoped_refptr<DumpProcessesForTracingTracking> tracking,
base::ProcessId pid,
@@ -360,9 +427,8 @@ void ConnectionManager::DoDumpOneProcessForTracing(
task_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback),
std::move(buffer)));
-
},
- reply_size, base::MessageLoopCurrent::Get()->task_runner(),
+ reply_size, base::ThreadTaskRunnerHandle::Get(),
std::move(finished_callback)));
}
diff --git a/chromium/components/services/heap_profiling/connection_manager.h b/chromium/components/services/heap_profiling/connection_manager.h
index 97dd66dbb6d..6571f9f565a 100644
--- a/chromium/components/services/heap_profiling/connection_manager.h
+++ b/chromium/components/services/heap_profiling/connection_manager.h
@@ -15,6 +15,7 @@
#include "base/process/process_handle.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
+#include "base/timer/timer.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/services/heap_profiling/allocation_event.h"
@@ -87,6 +88,15 @@ class ConnectionManager {
struct Connection;
struct DumpProcessesForTracingTracking;
+ void HeapProfileRetrieved(
+ scoped_refptr<DumpProcessesForTracingTracking> tracking,
+ base::ProcessId pid,
+ mojom::ProcessType process_type,
+ bool keep_small_allocations,
+ bool strip_path_from_mapped_files,
+ uint32_t sampling_rate,
+ mojom::HeapProfilePtr profile);
+
void DoDumpOneProcessForTracing(
scoped_refptr<DumpProcessesForTracingTracking> tracking,
base::ProcessId pid,
diff --git a/chromium/components/services/heap_profiling/heap_profiling_manifest.json b/chromium/components/services/heap_profiling/heap_profiling_manifest.json
deleted file mode 100644
index 38bb3c5ee50..00000000000
--- a/chromium/components/services/heap_profiling/heap_profiling_manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "heap_profiling",
- "display_name": "Heap Profiling Service",
- "sandbox_type": "profiling",
- "options" : {
- "instance_sharing" : "shared_instance_across_users"
- },
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "profiling": [ "heap_profiling.mojom.ProfilingService" ],
- "heap_profiler": [ "memory_instrumentation.mojom.HeapProfiler" ]
- },
- "requires": {
- "*": [ "app" ],
- "resource_coordinator": [ "heap_profiler_helper" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/heap_profiling/heap_profiling_service.cc b/chromium/components/services/heap_profiling/heap_profiling_service.cc
index 56a36c6f6b9..3d43108bec2 100644
--- a/chromium/components/services/heap_profiling/heap_profiling_service.cc
+++ b/chromium/components/services/heap_profiling/heap_profiling_service.cc
@@ -4,7 +4,12 @@
#include "components/services/heap_profiling/heap_profiling_service.h"
+#include <memory>
+
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/task/post_task.h"
+#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
@@ -16,7 +21,32 @@ HeapProfilingService::HeapProfilingService(
service_manager::mojom::ServiceRequest request)
: service_binding_(this, std::move(request)) {}
-HeapProfilingService::~HeapProfilingService() {}
+HeapProfilingService::~HeapProfilingService() = default;
+
+// static
+base::RepeatingCallback<void(service_manager::mojom::ServiceRequest)>
+HeapProfilingService::GetServiceFactory() {
+ return base::BindRepeating(
+ [](service_manager::mojom::ServiceRequest request) {
+ // base::WithBaseSyncPrimitives() and thus DEDICATED are needed
+ // because the thread owned by ConnectionManager::Connection is doing
+ // blocking Join during dectruction.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {base::TaskPriority::BEST_EFFORT,
+ base::WithBaseSyncPrimitives()},
+ base::SingleThreadTaskRunnerThreadMode::DEDICATED);
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](service_manager::mojom::ServiceRequest request) {
+ service_manager::Service::RunAsyncUntilTermination(
+ std::make_unique<heap_profiling::HeapProfilingService>(
+ std::move(request)));
+ },
+ std::move(request)));
+ });
+}
void HeapProfilingService::OnStart() {
registry_.AddInterface(
diff --git a/chromium/components/services/heap_profiling/heap_profiling_service.h b/chromium/components/services/heap_profiling/heap_profiling_service.h
index 661c55738a0..ecdefe255fd 100644
--- a/chromium/components/services/heap_profiling/heap_profiling_service.h
+++ b/chromium/components/services/heap_profiling/heap_profiling_service.h
@@ -34,6 +34,9 @@ class HeapProfilingService
explicit HeapProfilingService(service_manager::mojom::ServiceRequest request);
~HeapProfilingService() override;
+ static base::RepeatingCallback<void(service_manager::mojom::ServiceRequest)>
+ GetServiceFactory();
+
// Lifescycle events that occur after the service has started to spinup.
void OnStart() override;
void OnBindInterface(const service_manager::BindSourceInfo& source_info,
diff --git a/chromium/components/services/heap_profiling/json_exporter.cc b/chromium/components/services/heap_profiling/json_exporter.cc
index 9a03102d04a..8d87039d9c7 100644
--- a/chromium/components/services/heap_profiling/json_exporter.cc
+++ b/chromium/components/services/heap_profiling/json_exporter.cc
@@ -160,7 +160,7 @@ void WriteHeapsV2Footer(std::ostream& out) {
}
void WriteMemoryMaps(const ExportParams& params, std::ostream& out) {
- base::trace_event::TracedValue traced_value;
+ base::trace_event::TracedValue traced_value(0, /*force_json=*/true);
memory_instrumentation::TracingObserver::MemoryMapsAsValueInto(
params.maps, &traced_value, params.strip_path_from_mapped_files);
out << "\"process_mmaps\":" << traced_value.ToString();
diff --git a/chromium/components/services/heap_profiling/json_exporter_unittest.cc b/chromium/components/services/heap_profiling/json_exporter_unittest.cc
index df61b5f3329..a31c9a5c861 100644
--- a/chromium/components/services/heap_profiling/json_exporter_unittest.cc
+++ b/chromium/components/services/heap_profiling/json_exporter_unittest.cc
@@ -167,7 +167,8 @@ TEST(ProfilingJsonExporterTest, Simple) {
// JSON should parse.
base::JSONReader reader(base::JSON_PARSE_RFC);
- std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str());
+ std::unique_ptr<base::Value> root =
+ reader.ReadToValueDeprecated(stream.str());
ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code())
<< reader.GetErrorMessage();
ASSERT_TRUE(root);
@@ -320,7 +321,8 @@ TEST(ProfilingJsonExporterTest, Sampling) {
// JSON should parse.
base::JSONReader reader(base::JSON_PARSE_RFC);
- std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str());
+ std::unique_ptr<base::Value> root =
+ reader.ReadToValueDeprecated(stream.str());
ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code())
<< reader.GetErrorMessage();
ASSERT_TRUE(root);
@@ -392,7 +394,8 @@ TEST(ProfilingJsonExporterTest, SimpleWithFilteredAllocations) {
// JSON should parse.
base::JSONReader reader(base::JSON_PARSE_RFC);
- std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str());
+ std::unique_ptr<base::Value> root =
+ reader.ReadToValueDeprecated(stream.str());
ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code())
<< reader.GetErrorMessage();
ASSERT_TRUE(root);
@@ -463,7 +466,8 @@ TEST(ProfilingJsonExporterTest, MemoryMaps) {
// JSON should parse.
base::JSONReader reader(base::JSON_PARSE_RFC);
- std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str());
+ std::unique_ptr<base::Value> root =
+ reader.ReadToValueDeprecated(stream.str());
ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code())
<< reader.GetErrorMessage();
ASSERT_TRUE(root);
@@ -523,7 +527,8 @@ TEST(ProfilingJsonExporterTest, Context) {
// JSON should parse.
base::JSONReader reader(base::JSON_PARSE_RFC);
- std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str());
+ std::unique_ptr<base::Value> root =
+ reader.ReadToValueDeprecated(stream.str());
ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code())
<< reader.GetErrorMessage();
ASSERT_TRUE(root);
diff --git a/chromium/components/services/heap_profiling/public/cpp/BUILD.gn b/chromium/components/services/heap_profiling/public/cpp/BUILD.gn
index 44606b2ec67..01439b40fb6 100644
--- a/chromium/components/services/heap_profiling/public/cpp/BUILD.gn
+++ b/chromium/components/services/heap_profiling/public/cpp/BUILD.gn
@@ -50,3 +50,17 @@ source_set("unit_tests") {
"//testing/gtest",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/heap_profiling/public/mojom",
+ "//services/resource_coordinator/public/mojom",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/heap_profiling/public/cpp/OWNERS b/chromium/components/services/heap_profiling/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/heap_profiling/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/heap_profiling/public/cpp/client.cc b/chromium/components/services/heap_profiling/public/cpp/client.cc
index 86f6f86f4fd..39cd6c1de57 100644
--- a/chromium/components/services/heap_profiling/public/cpp/client.cc
+++ b/chromium/components/services/heap_profiling/public/cpp/client.cc
@@ -5,6 +5,7 @@
#include "components/services/heap_profiling/public/cpp/client.h"
#include "base/allocator/allocator_interception_mac.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/platform_file.h"
#include "base/metrics/field_trial_params.h"
@@ -127,6 +128,10 @@ void Client::FlushMemlogPipe(uint32_t barrier_id) {
SamplingProfilerWrapper::FlushPipe(barrier_id);
}
+void Client::RetrieveHeapProfile(RetrieveHeapProfileCallback callback) {
+ std::move(callback).Run(sampling_profiler_->RetrieveHeapProfile());
+}
+
void Client::StartProfilingInternal(mojom::ProfilingParamsPtr params) {
sampling_profiler_->StartProfiling(sender_pipe_.get(), std::move(params));
}
diff --git a/chromium/components/services/heap_profiling/public/cpp/client.h b/chromium/components/services/heap_profiling/public/cpp/client.h
index e06103c7bcb..23abac2a493 100644
--- a/chromium/components/services/heap_profiling/public/cpp/client.h
+++ b/chromium/components/services/heap_profiling/public/cpp/client.h
@@ -27,6 +27,7 @@ class Client : public mojom::ProfilingClient {
// mojom::ProfilingClient overrides:
void StartProfiling(mojom::ProfilingParamsPtr params) override;
void FlushMemlogPipe(uint32_t barrier_id) override;
+ void RetrieveHeapProfile(RetrieveHeapProfileCallback callback) override;
void BindToInterface(mojom::ProfilingClientRequest request);
diff --git a/chromium/components/services/heap_profiling/public/cpp/controller.cc b/chromium/components/services/heap_profiling/public/cpp/controller.cc
index afb483300bd..8ab69c561a5 100644
--- a/chromium/components/services/heap_profiling/public/cpp/controller.cc
+++ b/chromium/components/services/heap_profiling/public/cpp/controller.cc
@@ -16,10 +16,12 @@ namespace heap_profiling {
Controller::Controller(std::unique_ptr<service_manager::Connector> connector,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate)
: connector_(std::move(connector)),
sampling_rate_(sampling_rate),
stack_mode_(stack_mode),
+ stream_samples_(stream_samples),
weak_factory_(this) {
DCHECK_NE(sampling_rate, 0u);
@@ -50,6 +52,7 @@ void Controller::StartProfilingClient(mojom::ProfilingClientPtr client,
mojom::ProfilingParamsPtr params = mojom::ProfilingParams::New();
params->sampling_rate = sampling_rate_;
+ params->stream_samples = stream_samples_;
params->sender_pipe = mojo::WrapPlatformHandle(pipes.PassSender());
params->stack_mode = stack_mode_;
heap_profiling_service_->AddProfilingClient(
diff --git a/chromium/components/services/heap_profiling/public/cpp/controller.h b/chromium/components/services/heap_profiling/public/cpp/controller.h
index ab077b0d919..969f89e17d1 100644
--- a/chromium/components/services/heap_profiling/public/cpp/controller.h
+++ b/chromium/components/services/heap_profiling/public/cpp/controller.h
@@ -42,6 +42,7 @@ class Controller {
// named |sampling_interval|.
Controller(std::unique_ptr<service_manager::Connector> connector,
mojom::StackMode stack_mode,
+ bool stream_samples,
uint32_t sampling_rate);
~Controller();
@@ -71,6 +72,7 @@ class Controller {
// The same sampling rate and stack mode is used for each client.
const uint32_t sampling_rate_ = 1;
const mojom::StackMode stack_mode_;
+ const bool stream_samples_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<Controller> weak_factory_;
diff --git a/chromium/components/services/heap_profiling/public/cpp/manifest.cc b/chromium/components/services/heap_profiling/public/cpp/manifest.cc
new file mode 100644
index 00000000000..bd3e16b60ab
--- /dev/null
+++ b/chromium/components/services/heap_profiling/public/cpp/manifest.cc
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/heap_profiling/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/heap_profiling/public/mojom/constants.mojom.h"
+#include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h"
+#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
+#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace heap_profiling {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("Heap Profiling Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("profiling")
+ .WithInstanceSharingPolicy(
+ service_manager::Manifest::
+ InstanceSharingPolicy::kSharedAcrossGroups)
+ .Build())
+ .ExposeCapability("profiling",
+ service_manager::Manifest::InterfaceList<
+ mojom::ProfilingService>())
+ .ExposeCapability("heap_profiler",
+ service_manager::Manifest::InterfaceList<
+ memory_instrumentation::mojom::HeapProfiler>())
+ .RequireCapability(resource_coordinator::mojom::kServiceName,
+ "heap_profiler_helper")
+ .Build()};
+ return *manifest;
+}
+
+} // namespace heap_profiling
diff --git a/chromium/components/services/heap_profiling/public/cpp/manifest.h b/chromium/components/services/heap_profiling/public/cpp/manifest.h
new file mode 100644
index 00000000000..96f7f0c8e3b
--- /dev/null
+++ b/chromium/components/services/heap_profiling/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace heap_profiling {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace heap_profiling
+
+#endif // COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc b/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc
index 83bb8270f44..01885d7a7ce 100644
--- a/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc
+++ b/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc
@@ -4,33 +4,21 @@
#include "components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h"
-#include "base/allocator/buildflags.h"
+#include <unordered_set>
+#include <utility>
+
#include "base/atomicops.h"
-#include "base/compiler_specific.h"
-#include "base/debug/debugging_buildflags.h"
#include "base/debug/stack_trace.h"
#include "base/lazy_instance.h"
#include "base/no_destructor.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
+#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include "base/synchronization/lock.h"
-#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_local_storage.h"
#include "base/trace_event/heap_profiler_event_filter.h"
#include "base/trace_event/memory_dump_manager.h"
-#include "build/build_config.h"
-
-#if defined(OS_POSIX)
-#include <pthread.h>
-#endif
-
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#include <sys/prctl.h>
-#endif
-
-#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
- defined(OFFICIAL_BUILD)
-#include "base/trace_event/cfi_backtrace_android.h"
-#endif
+#include "components/services/heap_profiling/public/cpp/sender_pipe.h"
+#include "components/services/heap_profiling/public/cpp/stream.h"
using base::trace_event::AllocationContext;
using base::trace_event::AllocationContextTracker;
@@ -71,9 +59,6 @@ constexpr int kTimeoutMs = 10000;
// The allocator shim needs to retain some additional state for each thread.
struct ShimState {
- // The pointer must be valid for the lifetime of the process.
- const char* thread_name = nullptr;
-
// If we are using pseudo stacks, we need to inform the profiling service of
// the address to string mapping. To avoid a global lock, we keep a
// thread-local unordered_set of every address that has been sent from the
@@ -94,66 +79,13 @@ base::ThreadLocalStorage::Slot& ShimStateTLS() {
// already guards against that.
ShimState* GetShimState() {
ShimState* state = static_cast<ShimState*>(ShimStateTLS().Get());
-
if (!state) {
state = new ShimState();
ShimStateTLS().Set(state);
}
-
return state;
}
-// Set the thread name, which is a pointer to a leaked string, to ensure
-// validity forever.
-void SetCurrentThreadName(const char* name) {
- GetShimState()->thread_name = name;
-}
-
-// If a thread name has been set from ThreadIdNameManager, use that. Otherwise,
-// gets the thread name from kernel if available or returns a string with id.
-// This function intentionally leaks the allocated strings since they are used
-// to tag allocations even after the thread dies.
-const char* GetAndLeakThreadName() {
- const char* thread_name =
- base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
- if (thread_name && strcmp(thread_name, "") != 0)
- return thread_name;
-
- // prctl requires 16 bytes, snprintf requires 19, pthread_getname_np requires
- // 64 on macOS, see PlatformThread::SetName in platform_thread_mac.mm.
- constexpr size_t kBufferLen = 64;
- char name[kBufferLen];
-#if defined(OS_LINUX) || defined(OS_ANDROID)
- // If the thread name is not set, try to get it from prctl. Thread name might
- // not be set in cases where the thread started before heap profiling was
- // enabled.
- int err = prctl(PR_GET_NAME, name);
- if (!err) {
- return strdup(name);
- }
-#elif defined(OS_MACOSX)
- int err = pthread_getname_np(pthread_self(), name, kBufferLen);
- if (err == 0 && name[0] != '\0') {
- return strdup(name);
- }
-#endif // defined(OS_LINUX) || defined(OS_ANDROID)
-
- // Use tid if we don't have a thread name.
- snprintf(name, sizeof(name), "Thread %lu",
- static_cast<unsigned long>(base::PlatformThread::CurrentId()));
- return strdup(name);
-}
-
-// Returns the thread name, looking it up if necessary.
-const char* GetOrSetThreadName() {
- const char* thread_name = GetShimState()->thread_name;
- if (UNLIKELY(!thread_name)) {
- thread_name = GetAndLeakThreadName();
- GetShimState()->thread_name = thread_name;
- }
- return thread_name;
-}
-
class SendBuffer {
public:
SendBuffer() : buffer_(new char[SenderPipe::kPipeSize]) {}
@@ -341,7 +273,7 @@ class FrameSerializer {
} // namespace
void InitTLSSlot() {
- base::PoissonAllocationSampler::Init();
+ base::SamplingHeapProfiler::Init();
ignore_result(ShimStateTLS());
}
@@ -374,8 +306,7 @@ void InitAllocationRecorder(SenderPipe* sender_pipe,
if (params->stack_mode == mojom::StackMode::NATIVE_WITH_THREAD_NAMES) {
g_include_thread_names = true;
- base::ThreadIdNameManager::GetInstance()->InstallSetNameCallback(
- base::BindRepeating(&SetCurrentThreadName));
+ base::SamplingHeapProfiler::Get()->SetRecordThreadNames(true);
}
switch (params->stack_mode) {
@@ -405,11 +336,10 @@ void SamplingProfilerWrapper::FlushBuffersAndClosePipe() {
g_sender_pipe->Close();
}
+namespace {
+
void SerializeFramesFromAllocationContext(FrameSerializer* serializer,
const char** context) {
- // Allocation context is tracked in TLS. Return nothing if TLS was destroyed.
- if (ScopedAllowAlloc::HasTLSBeenDestroyed())
- return;
auto* tracker = AllocationContextTracker::GetInstanceForCurrentThread();
if (!tracker)
return;
@@ -425,40 +355,15 @@ void SerializeFramesFromAllocationContext(FrameSerializer* serializer,
void SerializeFramesFromBacktrace(FrameSerializer* serializer,
const char** context) {
- // Skip 3 top frames related to the profiler itself, e.g.:
- // base::debug::StackTrace::StackTrace
- // heap_profiling::RecordAndSendAlloc
- // sampling_heap_profiler::PoissonAllocationSampler::DoRecordAlloc
- size_t skip_frames = 3;
-#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
- defined(OFFICIAL_BUILD)
- const void* frames[kMaxStackEntries - 1];
- size_t frame_count =
- base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()->Unwind(
- frames, kMaxStackEntries - 1);
-#elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
- const void* frames[kMaxStackEntries - 1];
- size_t frame_count = base::debug::TraceStackFramePointers(
- frames, kMaxStackEntries - 1, skip_frames);
- skip_frames = 0;
-#else
- // Fall-back to capturing the stack with base::debug::StackTrace,
- // which is likely slower, but more reliable.
- base::debug::StackTrace stack_trace(kMaxStackEntries - 1);
- size_t frame_count = 0u;
- const void* const* frames = stack_trace.Addresses(&frame_count);
-#endif
-
- skip_frames = std::min(skip_frames, frame_count);
- serializer->AddAllInstructionPointers(frame_count - skip_frames,
- frames + skip_frames);
-
- // Both thread name and task context require access to TLS.
- if (ScopedAllowAlloc::HasTLSBeenDestroyed())
- return;
+ void* frames[kMaxStackEntries];
+ size_t frames_count;
+ const void** first_frame =
+ const_cast<const void**>(base::SamplingHeapProfiler::CaptureStackTrace(
+ frames, kMaxStackEntries - 1, &frames_count));
+ serializer->AddAllInstructionPointers(frames_count, first_frame);
if (g_include_thread_names) {
- const char* thread_name = GetOrSetThreadName();
+ const char* thread_name = base::SamplingHeapProfiler::CachedThreadName();
serializer->AddCString(thread_name);
}
@@ -470,13 +375,54 @@ void SerializeFramesFromBacktrace(FrameSerializer* serializer,
}
}
+// Notifies the test clients that allocation hooks have been initialized.
+void AllocatorHooksHaveBeenInitialized() {
+ base::AutoLock lock(g_on_init_allocator_shim_lock_.Get());
+ g_initialized_ = true;
+ if (!g_on_init_allocator_shim_callback_.Get())
+ return;
+ g_on_init_allocator_shim_task_runner_.Get()->PostTask(
+ FROM_HERE, std::move(*g_on_init_allocator_shim_callback_.Pointer()));
+}
+
+AllocatorType ConvertType(base::PoissonAllocationSampler::AllocatorType type) {
+ static_assert(static_cast<uint32_t>(
+ base::PoissonAllocationSampler::AllocatorType::kMax) ==
+ static_cast<uint32_t>(AllocatorType::kCount),
+ "AllocatorType lengths do not match.");
+ switch (type) {
+ case base::PoissonAllocationSampler::AllocatorType::kMalloc:
+ return AllocatorType::kMalloc;
+ case base::PoissonAllocationSampler::AllocatorType::kPartitionAlloc:
+ return AllocatorType::kPartitionAlloc;
+ case base::PoissonAllocationSampler::AllocatorType::kBlinkGC:
+ return AllocatorType::kOilpan;
+ default:
+ NOTREACHED();
+ return AllocatorType::kMalloc;
+ }
+}
+
+} // namespace
+
// Creates allocation info record, populates it with current call stack,
// thread name, allocator type and sends out to the client. Safe to call this
// method after TLS is destroyed.
-void RecordAndSendAlloc(AllocatorType type,
- void* address,
- size_t sz,
- const char* context) {
+void SamplingProfilerWrapper::SampleAdded(
+ void* address,
+ size_t size,
+ size_t total,
+ base::PoissonAllocationSampler::AllocatorType type,
+ const char* context) {
+ // CaptureStack (on Android) and AllocationContext (all OSes) may use TLS.
+ // Bail out if it has been destroyed.
+ if (ScopedAllowAlloc::HasTLSBeenDestroyed())
+ return;
+
+ // The PoissonAllocationSampler that invokes this method guarantees
+ // non-reentrancy, i.e. no allocations made within the scope of SampleAdded
+ // will produce a sample.
+ DCHECK(base::PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted());
SendBuffer* send_buffers = g_send_buffers.Read();
if (!send_buffers)
return;
@@ -507,9 +453,9 @@ void RecordAndSendAlloc(AllocatorType type,
size_t context_len = context ? strnlen(context, kMaxContextLen) : 0;
alloc_packet->op = kAllocPacketType;
- alloc_packet->allocator = type;
+ alloc_packet->allocator = ConvertType(type);
alloc_packet->address = (uint64_t)address;
- alloc_packet->size = sz;
+ alloc_packet->size = size;
alloc_packet->stack_len = static_cast<uint32_t>(serializer.count());
alloc_packet->context_byte_len = static_cast<uint32_t>(context_len);
@@ -524,7 +470,8 @@ void RecordAndSendAlloc(AllocatorType type,
// Creates the record for free operation and sends it out to the client. Safe
// to call this method after TLS is destroyed.
-void RecordAndSendFree(void* address) {
+void SamplingProfilerWrapper::SampleRemoved(void* address) {
+ DCHECK(base::PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted());
SendBuffer* send_buffers = g_send_buffers.Read();
if (!send_buffers)
return;
@@ -564,71 +511,67 @@ bool SetOnInitAllocatorShimCallbackForTesting(
return false;
}
-namespace {
-
-// Notifies the test clients that allocation hooks have been initialized.
-void AllocatorHooksHaveBeenInitialized() {
- base::AutoLock lock(g_on_init_allocator_shim_lock_.Get());
- g_initialized_ = true;
- if (!g_on_init_allocator_shim_callback_.Get())
- return;
- g_on_init_allocator_shim_task_runner_.Get()->PostTask(
- FROM_HERE, std::move(*g_on_init_allocator_shim_callback_.Pointer()));
-}
-
-AllocatorType ConvertType(base::PoissonAllocationSampler::AllocatorType type) {
- static_assert(static_cast<uint32_t>(
- base::PoissonAllocationSampler::AllocatorType::kMax) ==
- static_cast<uint32_t>(AllocatorType::kCount),
- "AllocatorType lengths do not match.");
- switch (type) {
- case base::PoissonAllocationSampler::AllocatorType::kMalloc:
- return AllocatorType::kMalloc;
- case base::PoissonAllocationSampler::AllocatorType::kPartitionAlloc:
- return AllocatorType::kPartitionAlloc;
- case base::PoissonAllocationSampler::AllocatorType::kBlinkGC:
- return AllocatorType::kOilpan;
- default:
- NOTREACHED();
- return AllocatorType::kMalloc;
- }
-}
-
-} // namespace
-
-SamplingProfilerWrapper::SamplingProfilerWrapper() {
- base::PoissonAllocationSampler::Get()->AddSamplesObserver(this);
-}
-
-SamplingProfilerWrapper::~SamplingProfilerWrapper() {
- base::PoissonAllocationSampler::Get()->RemoveSamplesObserver(this);
-}
-
void SamplingProfilerWrapper::StartProfiling(SenderPipe* sender_pipe,
mojom::ProfilingParamsPtr params) {
size_t sampling_rate = params->sampling_rate;
+ stream_samples_ = params->stream_samples;
InitAllocationRecorder(sender_pipe, std::move(params));
- auto* sampler = base::PoissonAllocationSampler::Get();
- sampler->SetSamplingInterval(sampling_rate);
- sampler->Start();
+ if (stream_samples_) {
+ auto* sampler = base::PoissonAllocationSampler::Get();
+ sampler->SetSamplingInterval(sampling_rate);
+ sampler->AddSamplesObserver(this);
+ } else {
+ auto* profiler = base::SamplingHeapProfiler::Get();
+ profiler->SetSamplingInterval(sampling_rate);
+ profiler->Start();
+ }
AllocatorHooksHaveBeenInitialized();
}
void SamplingProfilerWrapper::StopProfiling() {
- base::PoissonAllocationSampler::Get()->Stop();
-}
-
-void SamplingProfilerWrapper::SampleAdded(
- void* address,
- size_t size,
- size_t total,
- base::PoissonAllocationSampler::AllocatorType type,
- const char* context) {
- RecordAndSendAlloc(ConvertType(type), address, size, context);
+ if (stream_samples_)
+ base::PoissonAllocationSampler::Get()->RemoveSamplesObserver(this);
+ else
+ base::SamplingHeapProfiler::Get()->Stop();
}
-void SamplingProfilerWrapper::SampleRemoved(void* address) {
- RecordAndSendFree(address);
+mojom::HeapProfilePtr SamplingProfilerWrapper::RetrieveHeapProfile() {
+ DCHECK(!stream_samples_);
+ auto* profiler = base::SamplingHeapProfiler::Get();
+ std::vector<base::SamplingHeapProfiler::Sample> samples =
+ profiler->GetSamples(/*profile_id=*/0);
+ // It's important to retrieve strings after samples, as otherwise it could
+ // miss a string referenced by a sample.
+ std::vector<const char*> strings = profiler->GetStrings();
+ mojom::HeapProfilePtr profile = mojom::HeapProfile::New();
+ profile->samples.reserve(samples.size());
+ std::unordered_set<const char*> thread_names;
+ for (const auto& sample : samples) {
+ auto mojo_sample = mojom::HeapProfileSample::New();
+ mojo_sample->allocator =
+ static_cast<uint32_t>(ConvertType(sample.allocator));
+ mojo_sample->size = sample.size;
+ mojo_sample->context_id = reinterpret_cast<uintptr_t>(sample.context);
+ mojo_sample->stack.reserve(sample.stack.size() +
+ (g_include_thread_names ? 1 : 0));
+ mojo_sample->stack.insert(
+ mojo_sample->stack.end(),
+ reinterpret_cast<const uintptr_t*>(sample.stack.data()),
+ reinterpret_cast<const uintptr_t*>(sample.stack.data() +
+ sample.stack.size()));
+ if (g_include_thread_names) {
+ mojo_sample->stack.push_back(
+ reinterpret_cast<uintptr_t>(sample.thread_name));
+ thread_names.insert(sample.thread_name);
+ }
+ profile->samples.push_back(std::move(mojo_sample));
+ }
+ profile->strings.reserve(strings.size() + thread_names.size());
+ for (const char* string : strings)
+ profile->strings.emplace(reinterpret_cast<uintptr_t>(string), string);
+ for (const char* string : thread_names)
+ profile->strings.emplace(reinterpret_cast<uintptr_t>(string), string);
+ return profile;
}
} // namespace heap_profiling
diff --git a/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h b/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h
index bee5c7217c7..d6bff9c1b64 100644
--- a/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h
+++ b/chromium/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h
@@ -5,13 +5,15 @@
#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_SAMPLING_PROFILER_WRAPPER_H_
#define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_SAMPLING_PROFILER_WRAPPER_H_
+#include <vector>
+
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
-#include "components/services/heap_profiling/public/cpp/sender_pipe.h"
-#include "components/services/heap_profiling/public/cpp/stream.h"
#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
namespace heap_profiling {
+class SenderPipe;
+
// Initializes the TLS slot globally. This will be called early in Chrome's
// lifecycle to prevent re-entrancy from occurring while trying to set up the
// TLS slot, which is the entity that's supposed to prevent re-entrancy.
@@ -30,9 +32,6 @@ bool SetOnInitAllocatorShimCallbackForTesting(
class SamplingProfilerWrapper
: private base::PoissonAllocationSampler::SamplesObserver {
public:
- SamplingProfilerWrapper();
- ~SamplingProfilerWrapper() override;
-
void StartProfiling(SenderPipe* sender_pipe,
mojom::ProfilingParamsPtr params);
void StopProfiling();
@@ -44,6 +43,8 @@ class SamplingProfilerWrapper
// logging process so it knows when this operation is complete.
static void FlushPipe(uint32_t barrier_id);
+ mojom::HeapProfilePtr RetrieveHeapProfile();
+
private:
// base::PoissonAllocationSampler::SamplesObserver
void SampleAdded(void* address,
@@ -52,6 +53,8 @@ class SamplingProfilerWrapper
base::PoissonAllocationSampler::AllocatorType,
const char* context) override;
void SampleRemoved(void* address) override;
+
+ bool stream_samples_ = false;
};
} // namespace heap_profiling
diff --git a/chromium/components/services/heap_profiling/public/cpp/settings.cc b/chromium/components/services/heap_profiling/public/cpp/settings.cc
index 07d6d138d8e..9a454a466f5 100644
--- a/chromium/components/services/heap_profiling/public/cpp/settings.cc
+++ b/chromium/components/services/heap_profiling/public/cpp/settings.cc
@@ -23,18 +23,16 @@ namespace {
const char kOOPHeapProfilingFeatureStackMode[] = "stack-mode";
const char kOOPHeapProfilingFeatureSampling[] = "sampling";
const char kOOPHeapProfilingFeatureSamplingRate[] = "sampling-rate";
+const char kOOPHeapProfilingFeatureInProcess[] = "in-process";
const uint32_t kDefaultSamplingRate = 100000;
const bool kDefaultShouldSample = true;
+const bool kDefaultInProcessMode = false;
bool RecordAllAllocationsForStartup() {
- const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
- if (cmdline->HasSwitch(kMemlogSampling))
- return false;
-
return !base::GetFieldTrialParamByFeatureAsBool(
kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureSampling,
- /*default_value=*/kDefaultShouldSample);
+ kDefaultShouldSample);
}
} // namespace
@@ -146,7 +144,14 @@ uint32_t GetSamplingRateForStartup() {
return base::GetFieldTrialParamByFeatureAsInt(
kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureSamplingRate,
- /*default_value=*/kDefaultSamplingRate);
+ kDefaultSamplingRate);
+}
+
+bool IsInProcessModeEnabled() {
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(kMemlogInProcess) ||
+ base::GetFieldTrialParamByFeatureAsBool(
+ kOOPHeapProfilingFeature, kOOPHeapProfilingFeatureInProcess,
+ kDefaultInProcessMode);
}
bool IsBackgroundHeapProfilingEnabled() {
diff --git a/chromium/components/services/heap_profiling/public/cpp/settings.h b/chromium/components/services/heap_profiling/public/cpp/settings.h
index 10ed1d0a955..1629cd3b8da 100644
--- a/chromium/components/services/heap_profiling/public/cpp/settings.h
+++ b/chromium/components/services/heap_profiling/public/cpp/settings.h
@@ -59,6 +59,7 @@ mojom::StackMode ConvertStringToStackMode(const std::string& input);
// recorded every N bytes of allocated objects.
uint32_t GetSamplingRateForStartup();
+bool IsInProcessModeEnabled();
bool IsBackgroundHeapProfilingEnabled();
bool ShouldKeepSmallAllocations();
diff --git a/chromium/components/services/heap_profiling/public/cpp/switches.cc b/chromium/components/services/heap_profiling/public/cpp/switches.cc
index 4f17ee31312..00792820b29 100644
--- a/chromium/components/services/heap_profiling/public/cpp/switches.cc
+++ b/chromium/components/services/heap_profiling/public/cpp/switches.cc
@@ -7,6 +7,7 @@
namespace heap_profiling {
const char kMemlog[] = "memlog";
+const char kMemlogInProcess[] = "memlog-in-process";
const char kMemlogKeepSmallAllocations[] = "memlog-keep-small-allocations";
const char kMemlogModeAll[] = "all";
const char kMemlogModeAllRenderers[] = "all-renderers";
@@ -17,7 +18,6 @@ const char kMemlogModeMinimal[] = "minimal";
const char kMemlogModeRendererSampling[] = "renderer-sampling";
const char kMemlogModeUtilityAndBrowser[] = "utility-and-browser";
const char kMemlogModeUtilitySampling[] = "utility-sampling";
-const char kMemlogSampling[] = "memlog-sampling";
const char kMemlogSamplingRate[] = "memlog-sampling-rate";
const char kMemlogStackMode[] = "memlog-stack-mode";
const char kMemlogStackModeMixed[] = "mixed";
diff --git a/chromium/components/services/heap_profiling/public/cpp/switches.h b/chromium/components/services/heap_profiling/public/cpp/switches.h
index 582ea2a9397..a61a089fc5b 100644
--- a/chromium/components/services/heap_profiling/public/cpp/switches.h
+++ b/chromium/components/services/heap_profiling/public/cpp/switches.h
@@ -8,6 +8,7 @@
namespace heap_profiling {
extern const char kMemlog[];
+extern const char kMemlogInProcess[];
extern const char kMemlogKeepSmallAllocations[];
extern const char kMemlogModeAll[];
extern const char kMemlogModeAllRenderers[];
@@ -18,7 +19,6 @@ extern const char kMemlogModeMinimal[];
extern const char kMemlogModeRendererSampling[];
extern const char kMemlogModeUtilityAndBrowser[];
extern const char kMemlogModeUtilitySampling[];
-extern const char kMemlogSampling[];
extern const char kMemlogSamplingRate[];
extern const char kMemlogStackMode[];
extern const char kMemlogStackModeMixed[];
diff --git a/chromium/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom b/chromium/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom
index 8b98d6915e8..6a96077761e 100644
--- a/chromium/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom
+++ b/chromium/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom
@@ -23,6 +23,12 @@ enum StackMode {
// A wrapper for parameters that affect each client's implementation of
// profiling.
struct ProfilingParams {
+ // When |stream_samples| is true the samples are streamed through the
+ // provided |sender_pipe|. Otherwise, the samples are stored on
+ // the client side during recording and can be retrieved using
+ // |ProfilingClient.RetrieveHeapProfile| method.
+ bool stream_samples;
+
// The client should record allocations into |memlog_sender_pipe|.
handle sender_pipe;
@@ -37,17 +43,48 @@ struct ProfilingParams {
uint32 sampling_rate;
};
+// A single memory allocation sample.
+struct HeapProfileSample {
+ // Allocator type.
+ uint32 allocator;
+
+ // The size in bytes accounted for the sample.
+ uint64 size;
+
+ // Id of the context string.
+ uint64 context_id;
+
+ // Program stack in top to bottom order recorded for the allocation.
+ // Each element of the |stack| is either a PC memory address or a string
+ // if it is among the |strings| map items of |HeapProfile|.
+ array<uint64> stack;
+};
+
+// Heap profile data. Can be retrieved from the client with
+// |RetrieveHeapProfile| method.
+struct HeapProfile {
+ // Samples recorded for the profile.
+ array<HeapProfileSample> samples;
+
+ // Strings used within the profile.
+ map<uint64, string> strings;
+};
+
// This interface is implemented by "memlog clients" (profiled processes that
// can send memory allocation events to the profiling process). These functions
// are called by the profiling process to control the senders.
interface ProfilingClient {
- // Start recording allocations and sending them to the profiling process via
- // |params.sender_pipe|. There is currently no mechanism to stop recording
- // allocations.
+ // Start recording allocations.
+ // Collected allocations are either streamed to the profiling process via
+ // |params.sender_pipe|, or accumulated in the profiled process depending on
+ // the |params.use_in_process_storage|.
+ // There is currently no mechanism to stop recording allocations.
StartProfiling(ProfilingParams params);
// Flushes the memlog pipe associated with this client. A barrier packet is
// set over the memlog pipe with the given identifier. This allows the
// receiver to synchronize with the flush.
FlushMemlogPipe(uint32 barrier_id);
+
+ RetrieveHeapProfile() => (HeapProfile profile);
};
diff --git a/chromium/components/services/heap_profiling/receiver_pipe_win.cc b/chromium/components/services/heap_profiling/receiver_pipe_win.cc
index cba6a69c6f9..d2945bdde2f 100644
--- a/chromium/components/services/heap_profiling/receiver_pipe_win.cc
+++ b/chromium/components/services/heap_profiling/receiver_pipe_win.cc
@@ -20,13 +20,13 @@ ReceiverPipe::ReceiverPipe(mojo::PlatformHandle handle)
: ReceiverPipeBase(std::move(handle)),
read_buffer_(new char[SenderPipe::kPipeSize]) {
ZeroOverlapped();
- base::MessageLoopCurrentForIO::Get()->RegisterIOHandler(
- handle_.GetHandle().Get(), this);
}
-ReceiverPipe::~ReceiverPipe() {}
+ReceiverPipe::~ReceiverPipe() = default;
void ReceiverPipe::StartReadingOnIOThread() {
+ base::MessageLoopCurrentForIO::Get()->RegisterIOHandler(
+ handle_.GetHandle().Get(), this);
ReadUntilBlocking();
}
diff --git a/chromium/components/services/leveldb/BUILD.gn b/chromium/components/services/leveldb/BUILD.gn
index 29c62d45f6b..9f2629fd30a 100644
--- a/chromium/components/services/leveldb/BUILD.gn
+++ b/chromium/components/services/leveldb/BUILD.gn
@@ -2,9 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//services/catalog/public/tools/catalog.gni")
import("//services/service_manager/public/cpp/service_executable.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//testing/test.gni")
static_library("lib") {
@@ -48,11 +46,6 @@ service_executable("leveldb") {
]
}
-service_manifest("manifest") {
- name = "leveldb"
- source = "manifest.json"
-}
-
test("leveldb_service_unittests") {
sources = [
"leveldb_mojo_unittest.cc",
@@ -61,11 +54,12 @@ test("leveldb_service_unittests") {
]
deps = [
- ":leveldb_service_unittests_catalog_source",
"//base",
"//base/test:test_support",
+ "//components/services/filesystem/public/cpp:manifest",
"//components/services/filesystem/public/interfaces",
"//components/services/leveldb/public/cpp",
+ "//components/services/leveldb/public/cpp:manifest",
"//components/services/leveldb/public/interfaces",
"//mojo/core/test:run_all_unittests",
"//mojo/public/cpp/bindings",
@@ -81,22 +75,3 @@ test("leveldb_service_unittests") {
"//components/services/filesystem:filesystem",
]
}
-
-service_manifest("test_manifest") {
- name = "leveldb_service_unittests"
- source = "test_manifest.json"
-}
-
-catalog("leveldb_service_unittests_catalog") {
- embedded_services = [ ":test_manifest" ]
- standalone_services = [
- ":manifest",
- "//components/services/filesystem:manifest",
- ]
-}
-
-catalog_cpp_source("leveldb_service_unittests_catalog_source") {
- testonly = true
- catalog = ":leveldb_service_unittests_catalog"
- generated_function_name = "leveldb::test::CreateTestCatalog"
-}
diff --git a/chromium/components/services/leveldb/OWNERS b/chromium/components/services/leveldb/OWNERS
index be35d981929..f1bfd1eb7c5 100644
--- a/chromium/components/services/leveldb/OWNERS
+++ b/chromium/components/services/leveldb/OWNERS
@@ -1,13 +1,7 @@
mek@chromium.org
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
-
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
-per-file test_manifest.json=set noparent
-per-file test_manifest.json=file://ipc/SECURITY_OWNERS
-
per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/leveldb/env_mojo.cc b/chromium/components/services/leveldb/env_mojo.cc
index 0273420c76c..fc656fefc05 100644
--- a/chromium/components/services/leveldb/env_mojo.cc
+++ b/chromium/components/services/leveldb/env_mojo.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
diff --git a/chromium/components/services/leveldb/leveldb_app.cc b/chromium/components/services/leveldb/leveldb_app.cc
index 63ae0a96fb9..5713b75855c 100644
--- a/chromium/components/services/leveldb/leveldb_app.cc
+++ b/chromium/components/services/leveldb/leveldb_app.cc
@@ -4,6 +4,7 @@
#include "components/services/leveldb/leveldb_app.h"
+#include "base/bind.h"
#include "base/task/post_task.h"
#include "components/services/leveldb/leveldb_service_impl.h"
diff --git a/chromium/components/services/leveldb/leveldb_service_impl.cc b/chromium/components/services/leveldb/leveldb_service_impl.cc
index 5df44221211..757c5d6e826 100644
--- a/chromium/components/services/leveldb/leveldb_service_impl.cc
+++ b/chromium/components/services/leveldb/leveldb_service_impl.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "components/services/leveldb/env_mojo.h"
#include "components/services/leveldb/leveldb_database_impl.h"
diff --git a/chromium/components/services/leveldb/leveldb_service_unittest.cc b/chromium/components/services/leveldb/leveldb_service_unittest.cc
index 6fea47d1ff5..79b57e36683 100644
--- a/chromium/components/services/leveldb/leveldb_service_unittest.cc
+++ b/chromium/components/services/leveldb/leveldb_service_unittest.cc
@@ -7,13 +7,15 @@
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
+#include "components/services/filesystem/public/cpp/manifest.h"
#include "components/services/filesystem/public/interfaces/directory.mojom.h"
#include "components/services/filesystem/public/interfaces/file_system.mojom.h"
#include "components/services/filesystem/public/interfaces/types.mojom.h"
-#include "components/services/leveldb/leveldb_service_unittests_catalog_source.h"
+#include "components/services/leveldb/public/cpp/manifest.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
#include "services/service_manager/public/cpp/test/test_service.h"
#include "services/service_manager/public/cpp/test/test_service_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -134,12 +136,20 @@ void LevelDBSyncOpenInMemory(mojom::LevelDBService* leveldb,
run_loop.Run();
}
+const char kTestServiceName[] = "leveldb_service_unittests";
+
class LevelDBServiceTest : public testing::Test {
public:
LevelDBServiceTest()
- : test_service_manager_(test::CreateTestCatalog()),
- test_service_(test_service_manager_.RegisterTestInstance(
- "leveldb_service_unittests")) {}
+ : test_service_manager_(
+ {GetManifest(), filesystem::GetManifest(),
+ service_manager::ManifestBuilder()
+ .WithServiceName(kTestServiceName)
+ .RequireCapability("filesystem", "filesystem:filesystem")
+ .RequireCapability("leveldb", "leveldb:leveldb")
+ .Build()}),
+ test_service_(
+ test_service_manager_.RegisterTestInstance(kTestServiceName)) {}
~LevelDBServiceTest() override = default;
protected:
diff --git a/chromium/components/services/leveldb/manifest.json b/chromium/components/services/leveldb/manifest.json
deleted file mode 100644
index 41102cc4aef..00000000000
--- a/chromium/components/services/leveldb/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "leveldb",
- "display_name": "LevelDB Service",
- "sandbox_type": "none",
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "leveldb:leveldb": [ "leveldb.mojom.LevelDBService" ]
- },
- "requires": {
- "*": [ "app" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/leveldb/public/cpp/BUILD.gn b/chromium/components/services/leveldb/public/cpp/BUILD.gn
index aab9403a9ab..af0830e5920 100644
--- a/chromium/components/services/leveldb/public/cpp/BUILD.gn
+++ b/chromium/components/services/leveldb/public/cpp/BUILD.gn
@@ -17,3 +17,16 @@ static_library("cpp") {
"//third_party/leveldatabase",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/leveldb/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/leveldb/public/cpp/OWNERS b/chromium/components/services/leveldb/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/leveldb/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/leveldb/public/cpp/manifest.cc b/chromium/components/services/leveldb/public/cpp/manifest.cc
new file mode 100644
index 00000000000..fc81f0c4ec7
--- /dev/null
+++ b/chromium/components/services/leveldb/public/cpp/manifest.cc
@@ -0,0 +1,28 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/leveldb/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace leveldb {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName("leveldb")
+ .WithDisplayName("LevelDB Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("none")
+ .Build())
+ .ExposeCapability(
+ "leveldb:leveldb",
+ service_manager::Manifest::InterfaceList<mojom::LevelDBService>())
+ .Build()};
+ return *manifest;
+}
+
+} // namespace leveldb
diff --git a/chromium/components/services/leveldb/public/cpp/manifest.h b/chromium/components/services/leveldb/public/cpp/manifest.h
new file mode 100644
index 00000000000..09d6c6ae495
--- /dev/null
+++ b/chromium/components/services/leveldb/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace leveldb {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace leveldb
+
+#endif // COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/leveldb/remote_iterator_unittest.cc b/chromium/components/services/leveldb/remote_iterator_unittest.cc
index a209a461f5d..4e482fe6d64 100644
--- a/chromium/components/services/leveldb/remote_iterator_unittest.cc
+++ b/chromium/components/services/leveldb/remote_iterator_unittest.cc
@@ -8,10 +8,11 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
-#include "components/services/leveldb/leveldb_service_unittests_catalog_source.h"
+#include "components/services/leveldb/public/cpp/manifest.h"
#include "components/services/leveldb/public/cpp/remote_iterator.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
#include "services/service_manager/public/cpp/test/test_service.h"
#include "services/service_manager/public/cpp/test/test_service_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -42,12 +43,18 @@ base::Callback<void(const base::UnguessableToken&)> CaptureToken(
quit_closure);
}
+const char kTestServiceName[] = "leveldb_service_unittests";
+
class RemoteIteratorTest : public testing::Test {
public:
RemoteIteratorTest()
- : test_service_manager_(test::CreateTestCatalog()),
- test_service_(test_service_manager_.RegisterTestInstance(
- "leveldb_service_unittests")) {}
+ : test_service_manager_(
+ {GetManifest(), service_manager::ManifestBuilder()
+ .WithServiceName(kTestServiceName)
+ .RequireCapability("leveldb", "leveldb:leveldb")
+ .Build()}),
+ test_service_(
+ test_service_manager_.RegisterTestInstance(kTestServiceName)) {}
~RemoteIteratorTest() override = default;
protected:
diff --git a/chromium/components/services/leveldb/test_manifest.json b/chromium/components/services/leveldb/test_manifest.json
deleted file mode 100644
index 30a2da69e75..00000000000
--- a/chromium/components/services/leveldb/test_manifest.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "leveldb_service_unittests",
- "display_name": "LevelDB Service Unittests",
- "interface_provider_specs": {
- "service_manager:connector": {
- "requires": {
- "filesystem": [ "filesystem:filesystem" ],
- "leveldb": [ "leveldb:leveldb" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/patch/BUILD.gn b/chromium/components/services/patch/BUILD.gn
index 2a0a6036417..eb94d27dadb 100644
--- a/chromium/components/services/patch/BUILD.gn
+++ b/chromium/components/services/patch/BUILD.gn
@@ -2,8 +2,6 @@
# 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/service_manifest.gni")
-
source_set("lib") {
sources = [
"file_patcher_impl.cc",
@@ -24,8 +22,3 @@ source_set("lib") {
"//services/service_manager/public/cpp",
]
}
-
-service_manifest("manifest") {
- name = "patch_service"
- source = "manifest.json"
-}
diff --git a/chromium/components/services/patch/OWNERS b/chromium/components/services/patch/OWNERS
index f232b6d2197..ec81839d0ad 100644
--- a/chromium/components/services/patch/OWNERS
+++ b/chromium/components/services/patch/OWNERS
@@ -1,5 +1,2 @@
sorin@chromium.org
waffles@chromium.org
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/patch/manifest.json b/chromium/components/services/patch/manifest.json
deleted file mode 100644
index 75cb068adc8..00000000000
--- a/chromium/components/services/patch/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "patch_service",
- "display_name": "Patch Service",
- "sandbox_type": "utility",
- "options" : {
- "instance_sharing" : "shared_instance_across_users"
- },
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "patch_file": [ "patch.mojom.FilePatcher" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/patch/public/cpp/BUILD.gn b/chromium/components/services/patch/public/cpp/BUILD.gn
index d5322180fc1..8f9c19776bc 100644
--- a/chromium/components/services/patch/public/cpp/BUILD.gn
+++ b/chromium/components/services/patch/public/cpp/BUILD.gn
@@ -15,3 +15,16 @@ source_set("cpp") {
"//services/service_manager/public/cpp",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/patch/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/patch/public/cpp/OWNERS b/chromium/components/services/patch/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/patch/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/patch/public/cpp/manifest.cc b/chromium/components/services/patch/public/cpp/manifest.cc
new file mode 100644
index 00000000000..087aa256e7b
--- /dev/null
+++ b/chromium/components/services/patch/public/cpp/manifest.cc
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/patch/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/patch/public/interfaces/constants.mojom.h"
+#include "components/services/patch/public/interfaces/file_patcher.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace patch {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("Patch Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("utility")
+ .WithInstanceSharingPolicy(
+ service_manager::Manifest::
+ InstanceSharingPolicy::kSharedAcrossGroups)
+ .Build())
+ .ExposeCapability(
+ "patch_file",
+ service_manager::Manifest::InterfaceList<mojom::FilePatcher>())
+
+ .Build()};
+ return *manifest;
+}
+
+} // namespace patch
diff --git a/chromium/components/services/patch/public/cpp/manifest.h b/chromium/components/services/patch/public/cpp/manifest.h
new file mode 100644
index 00000000000..d476dc235c4
--- /dev/null
+++ b/chromium/components/services/patch/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace patch {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace patch
+
+#endif // COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/pdf_compositor/BUILD.gn b/chromium/components/services/pdf_compositor/BUILD.gn
index 6b42b0080a7..c21b77aebce 100644
--- a/chromium/components/services/pdf_compositor/BUILD.gn
+++ b/chromium/components/services/pdf_compositor/BUILD.gn
@@ -3,7 +3,6 @@
# found in the LICENSE file.
import("//printing/buildflags/buildflags.gni")
-import("//services/service_manager/public/service_manifest.gni")
static_library("pdf_compositor") {
sources = [
@@ -33,11 +32,6 @@ static_library("pdf_compositor") {
]
}
-service_manifest("pdf_compositor_manifest") {
- name = "pdf_compositor"
- source = "pdf_compositor_manifest.json"
-}
-
if (enable_basic_printing) {
source_set("unit_tests") {
testonly = true
diff --git a/chromium/components/services/pdf_compositor/OWNERS b/chromium/components/services/pdf_compositor/OWNERS
index 5f7d2e53888..9b08c6620bd 100644
--- a/chromium/components/services/pdf_compositor/OWNERS
+++ b/chromium/components/services/pdf_compositor/OWNERS
@@ -1,4 +1 @@
file://printing/OWNERS
-
-per-file pdf_compositor_manifest.json=set noparent
-per-file pdf_compositor_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/pdf_compositor/pdf_compositor_impl_unittest.cc b/chromium/components/services/pdf_compositor/pdf_compositor_impl_unittest.cc
index a03c4cc0401..7f52160ac73 100644
--- a/chromium/components/services/pdf_compositor/pdf_compositor_impl_unittest.cc
+++ b/chromium/components/services/pdf_compositor/pdf_compositor_impl_unittest.cc
@@ -5,6 +5,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/services/pdf_compositor/pdf_compositor_manifest.json b/chromium/components/services/pdf_compositor/pdf_compositor_manifest.json
deleted file mode 100644
index ffe276ba270..00000000000
--- a/chromium/components/services/pdf_compositor/pdf_compositor_manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "pdf_compositor",
- "display_name": "PDF Compositor Service",
- "sandbox_type": "pdf_compositor",
- "options" : {
- "instance_sharing" : "shared_instance_across_users"
- },
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "compositor": [ "printing.mojom.PdfCompositor" ]
- },
- "requires": {
- "*": [ "app" ],
- "content_browser": [ "sandbox_support" ],
- "ui": [ "discardable_memory" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/pdf_compositor/pdf_compositor_service.cc b/chromium/components/services/pdf_compositor/pdf_compositor_service.cc
index cc1adf05927..d7a44dc5e28 100644
--- a/chromium/components/services/pdf_compositor/pdf_compositor_service.cc
+++ b/chromium/components/services/pdf_compositor/pdf_compositor_service.cc
@@ -8,6 +8,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/memory/discardable_memory.h"
#include "build/build_config.h"
diff --git a/chromium/components/services/pdf_compositor/pdf_compositor_service_unittest.cc b/chromium/components/services/pdf_compositor/pdf_compositor_service_unittest.cc
index 506c0299be7..08827082817 100644
--- a/chromium/components/services/pdf_compositor/pdf_compositor_service_unittest.cc
+++ b/chromium/components/services/pdf_compositor/pdf_compositor_service_unittest.cc
@@ -5,6 +5,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/run_loop.h"
diff --git a/chromium/components/services/pdf_compositor/public/cpp/BUILD.gn b/chromium/components/services/pdf_compositor/public/cpp/BUILD.gn
index 1e558aa68cd..426a93438a4 100644
--- a/chromium/components/services/pdf_compositor/public/cpp/BUILD.gn
+++ b/chromium/components/services/pdf_compositor/public/cpp/BUILD.gn
@@ -21,3 +21,16 @@ source_set("factory") {
"//services/service_manager/public/cpp",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/pdf_compositor/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/pdf_compositor/public/cpp/OWNERS b/chromium/components/services/pdf_compositor/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/pdf_compositor/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/pdf_compositor/public/cpp/manifest.cc b/chromium/components/services/pdf_compositor/public/cpp/manifest.cc
new file mode 100644
index 00000000000..87c2108e74f
--- /dev/null
+++ b/chromium/components/services/pdf_compositor/public/cpp/manifest.cc
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/pdf_compositor/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace printing {
+
+const service_manager::Manifest& GetPdfCompositorManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("PDF Compositor Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("pdf_compositor")
+ .WithInstanceSharingPolicy(
+ service_manager::Manifest::
+ InstanceSharingPolicy::kSharedAcrossGroups)
+ .Build())
+ .ExposeCapability(
+ "compositor",
+ service_manager::Manifest::InterfaceList<mojom::PdfCompositor>())
+ .RequireCapability("content_browser", "app")
+ .RequireCapability("content_browser", "sandbox_support")
+ .RequireCapability("ui", "discardable_memory")
+ .Build()};
+ return *manifest;
+}
+
+} // namespace printing
diff --git a/chromium/components/services/pdf_compositor/public/cpp/manifest.h b/chromium/components/services/pdf_compositor/public/cpp/manifest.h
new file mode 100644
index 00000000000..52b57fcbc5d
--- /dev/null
+++ b/chromium/components/services/pdf_compositor/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace printing {
+
+const service_manager::Manifest& GetPdfCompositorManifest();
+
+} // namespace printing
+
+#endif // COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/unzip/BUILD.gn b/chromium/components/services/unzip/BUILD.gn
index 020a9498165..28ce03493fc 100644
--- a/chromium/components/services/unzip/BUILD.gn
+++ b/chromium/components/services/unzip/BUILD.gn
@@ -2,8 +2,6 @@
# 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/service_manifest.gni")
-
source_set("lib") {
sources = [
"unzip_service.cc",
@@ -55,8 +53,3 @@ source_set("unit_tests") {
"//testing/gtest",
]
}
-
-service_manifest("manifest") {
- name = "unzip_service"
- source = "manifest.json"
-}
diff --git a/chromium/components/services/unzip/OWNERS b/chromium/components/services/unzip/OWNERS
index bd74fe691c3..ec81839d0ad 100644
--- a/chromium/components/services/unzip/OWNERS
+++ b/chromium/components/services/unzip/OWNERS
@@ -1,4 +1,2 @@
sorin@chromium.org
waffles@chromium.org
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/unzip/manifest.json b/chromium/components/services/unzip/manifest.json
deleted file mode 100644
index ab7040601ec..00000000000
--- a/chromium/components/services/unzip/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "unzip_service",
- "display_name": "Unzip Service",
- "sandbox_type": "utility",
- "options" : {
- "instance_sharing" : "shared_instance_across_users"
- },
- "interface_provider_specs": {
- "service_manager:connector": {
- "provides": {
- "unzip_file": [ "unzip.mojom.Unzipper" ]
- }
- }
- }
-}
diff --git a/chromium/components/services/unzip/public/cpp/BUILD.gn b/chromium/components/services/unzip/public/cpp/BUILD.gn
index 78470fe9569..8deacf719eb 100644
--- a/chromium/components/services/unzip/public/cpp/BUILD.gn
+++ b/chromium/components/services/unzip/public/cpp/BUILD.gn
@@ -31,3 +31,16 @@ static_library("test_support") {
"//services/service_manager/public/cpp/test:test_support",
]
}
+
+source_set("manifest") {
+ sources = [
+ "manifest.cc",
+ "manifest.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/services/unzip/public/interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
diff --git a/chromium/components/services/unzip/public/cpp/OWNERS b/chromium/components/services/unzip/public/cpp/OWNERS
new file mode 100644
index 00000000000..6faeaa4752f
--- /dev/null
+++ b/chromium/components/services/unzip/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/services/unzip/public/cpp/manifest.cc b/chromium/components/services/unzip/public/cpp/manifest.cc
new file mode 100644
index 00000000000..a6ec2adb1e9
--- /dev/null
+++ b/chromium/components/services/unzip/public/cpp/manifest.cc
@@ -0,0 +1,32 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/unzip/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/unzip/public/interfaces/constants.mojom.h"
+#include "components/services/unzip/public/interfaces/unzipper.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace unzip {
+
+const service_manager::Manifest& GetManifest() {
+ static base::NoDestructor<service_manager::Manifest> manifest{
+ service_manager::ManifestBuilder()
+ .WithServiceName(mojom::kServiceName)
+ .WithDisplayName("Unzip Service")
+ .WithOptions(service_manager::ManifestOptionsBuilder()
+ .WithSandboxType("utility")
+ .WithInstanceSharingPolicy(
+ service_manager::Manifest::
+ InstanceSharingPolicy::kSharedAcrossGroups)
+ .Build())
+ .ExposeCapability(
+ "unzip_file",
+ service_manager::Manifest::InterfaceList<mojom::Unzipper>())
+ .Build()};
+ return *manifest;
+}
+
+} // namespace unzip
diff --git a/chromium/components/services/unzip/public/cpp/manifest.h b/chromium/components/services/unzip/public/cpp/manifest.h
new file mode 100644
index 00000000000..b17b2a186bd
--- /dev/null
+++ b/chromium/components/services/unzip/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace unzip {
+
+const service_manager::Manifest& GetManifest();
+
+} // namespace unzip
+
+#endif // COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromium/components/services/unzip/public/cpp/test_unzip_service.cc b/chromium/components/services/unzip/public/cpp/test_unzip_service.cc
index b884659603c..9f54cf61220 100644
--- a/chromium/components/services/unzip/public/cpp/test_unzip_service.cc
+++ b/chromium/components/services/unzip/public/cpp/test_unzip_service.cc
@@ -4,6 +4,8 @@
#include "components/services/unzip/public/cpp/test_unzip_service.h"
+#include "components/services/filesystem/public/interfaces/directory.mojom.h"
+
namespace unzip {
CrashyUnzipService::CrashyUnzipService(
diff --git a/chromium/components/services/unzip/unzipper_impl.cc b/chromium/components/services/unzip/unzipper_impl.cc
index 65356c3478e..370b5397d61 100644
--- a/chromium/components/services/unzip/unzipper_impl.cc
+++ b/chromium/components/services/unzip/unzipper_impl.cc
@@ -7,9 +7,11 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "components/services/filesystem/public/interfaces/directory.mojom.h"
#include "third_party/zlib/google/zip.h"
#include "third_party/zlib/google/zip_reader.h"
diff --git a/chromium/components/sessions/core/session_service_commands.cc b/chromium/components/sessions/core/session_service_commands.cc
index 1de12aae6fb..1a58d0544ec 100644
--- a/chromium/components/sessions/core/session_service_commands.cc
+++ b/chromium/components/sessions/core/session_service_commands.cc
@@ -24,16 +24,24 @@ static const SessionCommand::id_type kCommandSetTabWindow = 0;
// OBSOLETE Superseded by kCommandSetWindowBounds3.
// static const SessionCommand::id_type kCommandSetWindowBounds = 1;
static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2;
+
+// OBSOLETE: Preserved for backward compatibility. Using
+// kCommandTabNavigationPathPruned instead
static const SessionCommand::id_type
kCommandTabNavigationPathPrunedFromBack = 5;
+
static const SessionCommand::id_type kCommandUpdateTabNavigation = 6;
static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7;
static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8;
static const SessionCommand::id_type kCommandSetWindowType = 9;
// OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration.
// static const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
+
+// OBSOLETE: Preserved for backward compatibility. Using
+// kCommandTabNavigationPathPruned instead
static const SessionCommand::id_type
kCommandTabNavigationPathPrunedFromFront = 11;
+
static const SessionCommand::id_type kCommandSetPinnedState = 12;
static const SessionCommand::id_type kCommandSetExtensionAppID = 13;
static const SessionCommand::id_type kCommandSetWindowBounds3 = 14;
@@ -47,6 +55,7 @@ static const SessionCommand::id_type kCommandLastActiveTime = 21;
// OBSOLETE Superseded by kCommandSetWindowWorkspace2.
// static const SessionCommand::id_type kCommandSetWindowWorkspace = 22;
static const SessionCommand::id_type kCommandSetWindowWorkspace2 = 23;
+static const SessionCommand::id_type kCommandTabNavigationPathPruned = 24;
namespace {
@@ -93,6 +102,14 @@ using WindowTypePayload = IDAndIndexPayload;
using TabNavigationPathPrunedFromFrontPayload = IDAndIndexPayload;
+struct TabNavigationPathPrunedPayload {
+ SessionID::id_type id;
+ // Index starting which |count| entries were removed.
+ int32_t index;
+ // Number of entries removed.
+ int32_t count;
+};
+
struct PinnedStatePayload {
SessionID::id_type tab_id;
bool pinned_state;
@@ -310,6 +327,31 @@ void AddTabsToWindows(IdToSessionTab* tabs, IdToSessionWindow* windows) {
tabs->clear();
}
+void ProcessTabNavigationPathPrunedCommand(
+ TabNavigationPathPrunedPayload& payload,
+ SessionTab* tab) {
+ // Update the selected navigation index.
+ if (tab->current_navigation_index >= payload.index &&
+ tab->current_navigation_index < payload.index + payload.count) {
+ tab->current_navigation_index = payload.index - 1;
+ } else if (tab->current_navigation_index >= payload.index + payload.count) {
+ tab->current_navigation_index =
+ tab->current_navigation_index - payload.count;
+ } // Else no change if selected index is before payload.index
+
+ tab->navigations.erase(
+ FindClosestNavigationWithIndex(&(tab->navigations), payload.index),
+ FindClosestNavigationWithIndex(&(tab->navigations),
+ payload.index + payload.count));
+
+ // And update the index of existing navigations.
+ for (auto& entry : tab->navigations) {
+ if (entry.index() < payload.index)
+ continue;
+ entry.set_index(entry.index() - payload.count);
+ }
+}
+
// Creates tabs and windows from the commands specified in |data|. The created
// tabs and windows are added to |tabs| and |windows| respectively, with the
// id of the active window set in |active_window_id|. It is up to the caller
@@ -409,6 +451,7 @@ bool CreateTabsAndWindows(
}
SessionTab* tab =
GetTab(SessionID::FromSerializedValue(payload.id), tabs);
+
tab->navigations.erase(
FindClosestNavigationWithIndex(&(tab->navigations), payload.index),
tab->navigations.end());
@@ -416,27 +459,34 @@ bool CreateTabsAndWindows(
}
case kCommandTabNavigationPathPrunedFromFront: {
- TabNavigationPathPrunedFromFrontPayload payload;
+ TabNavigationPathPrunedFromFrontPayload prune_front_payload;
+ if (!command->GetPayload(&prune_front_payload,
+ sizeof(prune_front_payload)) ||
+ prune_front_payload.index <= 0) {
+ DVLOG(1) << "Failed reading command " << command->id();
+ return true;
+ }
+ SessionTab* tab = GetTab(
+ SessionID::FromSerializedValue(prune_front_payload.id), tabs);
+
+ TabNavigationPathPrunedPayload payload;
+ payload.index = 0;
+ payload.count = prune_front_payload.index;
+ ProcessTabNavigationPathPrunedCommand(payload, tab);
+ break;
+ }
+
+ case kCommandTabNavigationPathPruned: {
+ TabNavigationPathPrunedPayload payload;
if (!command->GetPayload(&payload, sizeof(payload)) ||
- payload.index <= 0) {
+ payload.index < 0 || payload.count <= 0) {
DVLOG(1) << "Failed reading command " << command->id();
return true;
}
SessionTab* tab =
GetTab(SessionID::FromSerializedValue(payload.id), tabs);
- // Update the selected navigation index.
- tab->current_navigation_index =
- std::max(-1, tab->current_navigation_index - payload.index);
-
- // And update the index of existing navigations.
- for (auto i = tab->navigations.begin(); i != tab->navigations.end();) {
- i->set_index(i->index() - payload.index);
- if (i->index() < 0)
- i = tab->navigations.erase(i);
- else
- ++i;
- }
+ ProcessTabNavigationPathPrunedCommand(payload, tab);
break;
}
@@ -764,26 +814,16 @@ std::unique_ptr<SessionCommand> CreateSetWindowWorkspaceCommand(
return command;
}
-std::unique_ptr<SessionCommand> CreateTabNavigationPathPrunedFromBackCommand(
+std::unique_ptr<SessionCommand> CreateTabNavigationPathPrunedCommand(
const SessionID& tab_id,
+ int index,
int count) {
- TabNavigationPathPrunedFromBackPayload payload = { 0 };
+ TabNavigationPathPrunedPayload payload = {0};
payload.id = tab_id.id();
- payload.index = count;
- std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
- kCommandTabNavigationPathPrunedFromBack, sizeof(payload));
- memcpy(command->contents(), &payload, sizeof(payload));
- return command;
-}
-
-std::unique_ptr<SessionCommand> CreateTabNavigationPathPrunedFromFrontCommand(
- const SessionID& tab_id,
- int count) {
- TabNavigationPathPrunedFromFrontPayload payload = { 0 };
- payload.id = tab_id.id();
- payload.index = count;
+ payload.index = index;
+ payload.count = count;
std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
- kCommandTabNavigationPathPrunedFromFront, sizeof(payload));
+ kCommandTabNavigationPathPruned, sizeof(payload));
memcpy(command->contents(), &payload, sizeof(payload));
return command;
}
diff --git a/chromium/components/sessions/core/session_service_commands.h b/chromium/components/sessions/core/session_service_commands.h
index 1e3a1746c08..0ed6fa72662 100644
--- a/chromium/components/sessions/core/session_service_commands.h
+++ b/chromium/components/sessions/core/session_service_commands.h
@@ -54,11 +54,9 @@ CreateSessionStorageAssociatedCommand(
SESSIONS_EXPORT std::unique_ptr<SessionCommand> CreateSetActiveWindowCommand(
const SessionID& window_id);
SESSIONS_EXPORT std::unique_ptr<SessionCommand>
-CreateTabNavigationPathPrunedFromBackCommand(const SessionID& tab_id,
- int count);
-SESSIONS_EXPORT std::unique_ptr<SessionCommand>
-CreateTabNavigationPathPrunedFromFrontCommand(const SessionID& tab_id,
- int count);
+CreateTabNavigationPathPrunedCommand(const SessionID& tab_id,
+ int index,
+ int count);
SESSIONS_EXPORT std::unique_ptr<SessionCommand>
CreateUpdateTabNavigationCommand(
const SessionID& tab_id,
diff --git a/chromium/components/signin/core/browser/BUILD.gn b/chromium/components/signin/core/browser/BUILD.gn
index d85aaee4e6e..c6ea76398ed 100644
--- a/chromium/components/signin/core/browser/BUILD.gn
+++ b/chromium/components/signin/core/browser/BUILD.gn
@@ -22,6 +22,8 @@ buildflag_header("signin_buildflags") {
# both by IdentityManager and by its clients.
static_library("shared") {
sources = [
+ "account_consistency_method.cc",
+ "account_consistency_method.h",
"account_info.cc",
"account_info.h",
"account_info_util.cc",
@@ -64,8 +66,6 @@ static_library("shared") {
# not add code to this target without consulting with blundell@chromium.org.
static_library("internals") {
sources = [
- "account_consistency_method.cc",
- "account_consistency_method.h",
"account_fetcher_service.cc",
"account_fetcher_service.h",
"account_info_fetcher.cc",
@@ -78,12 +78,12 @@ static_library("internals") {
"device_id_helper.h",
"gaia_cookie_manager_service.cc",
"gaia_cookie_manager_service.h",
+ "oauth2_token_service_delegate_android.cc",
+ "oauth2_token_service_delegate_android.h",
"profile_oauth2_token_service.cc",
"profile_oauth2_token_service.h",
"signin_client.cc",
"signin_client.h",
- "signin_internals_util.cc",
- "signin_internals_util.h",
"signin_manager.cc",
"signin_manager.h",
"signin_manager_base.cc",
@@ -134,16 +134,18 @@ static_library("browser") {
"dice_account_reconcilor_delegate.h",
"dice_header_helper.cc",
"dice_header_helper.h",
+ "mice_account_reconcilor_delegate.cc",
+ "mice_account_reconcilor_delegate.h",
"mirror_account_reconcilor_delegate.cc",
"mirror_account_reconcilor_delegate.h",
"mutable_profile_oauth2_token_service_delegate.cc",
"mutable_profile_oauth2_token_service_delegate.h",
- "oauth2_token_service_delegate_android.cc",
- "oauth2_token_service_delegate_android.h",
"signin_error_controller.cc",
"signin_error_controller.h",
"signin_header_helper.cc",
"signin_header_helper.h",
+ "signin_internals_util.cc",
+ "signin_internals_util.h",
"signin_investigator.cc",
"signin_investigator.h",
"signin_status_metrics_provider.cc",
@@ -152,8 +154,6 @@ static_library("browser") {
"signin_status_metrics_provider_base.h",
"signin_status_metrics_provider_delegate.cc",
"signin_status_metrics_provider_delegate.h",
- "signin_tracker.cc",
- "signin_tracker.h",
"webdata/token_service_table.cc",
"webdata/token_service_table.h",
"webdata/token_web_data.cc",
@@ -170,7 +170,6 @@ static_library("browser") {
"//components/account_id",
"//components/content_settings/core/browser",
"//components/content_settings/core/common",
- "//components/invalidation/public",
"//components/keyed_service/core",
"//components/prefs",
"//google_apis",
@@ -209,10 +208,6 @@ static_library("browser") {
"dice_header_helper.h",
]
}
-
- if (is_android) {
- deps += [ "android:jni_headers" ]
- }
}
# This target contains test support that backs the test support for
@@ -223,14 +218,10 @@ static_library("browser") {
static_library("internals_test_support") {
testonly = true
sources = [
- "fake_account_fetcher_service.cc",
- "fake_account_fetcher_service.h",
- "fake_gaia_cookie_manager_service.cc",
- "fake_gaia_cookie_manager_service.h",
"fake_profile_oauth2_token_service.cc",
"fake_profile_oauth2_token_service.h",
- "fake_signin_manager.cc",
- "fake_signin_manager.h",
+ "test_image_decoder.cc",
+ "test_image_decoder.h",
# TODO(https://crbug.com/907782): Move list_accounts_test_utils to
# //services/identity/public/cpp once FakeGCMS no longer depends on it.
@@ -270,6 +261,7 @@ source_set("unit_tests") {
"dice_account_reconcilor_delegate_unittest.cc",
"gaia_cookie_manager_service_unittest.cc",
"identity_utils_unittest.cc",
+ "mice_account_reconcilor_delegate_unittest.cc",
"mutable_profile_oauth2_token_service_delegate_unittest.cc",
"signin_error_controller_unittest.cc",
"signin_header_helper_unittest.cc",
@@ -277,7 +269,6 @@ source_set("unit_tests") {
"signin_manager_unittest.cc",
"signin_metrics_unittest.cc",
"signin_status_metrics_provider_unittest.cc",
- "signin_tracker_unittest.cc",
"ubertoken_fetcher_impl_unittest.cc",
"webdata/token_service_table_unittest.cc",
]
@@ -289,6 +280,7 @@ source_set("unit_tests") {
"//base/test:test_support",
"//components/content_settings/core/browser",
"//components/image_fetcher/core",
+ "//components/image_fetcher/core:test_support",
"//components/os_crypt:test_support",
"//components/prefs",
"//components/prefs:test_support",
@@ -300,6 +292,7 @@ source_set("unit_tests") {
"//services/identity/public/cpp:test_support",
"//testing/gmock",
"//testing/gtest",
+ "//ui/gfx:test_support",
]
if (is_chromeos) {
@@ -316,8 +309,9 @@ source_set("unit_tests") {
}
if (is_android) {
- java_cpp_enum("investigated_scenario_java") {
+ java_cpp_enum("signin_enums_javagen") {
sources = [
+ "signin_header_helper.h",
"signin_investigator.h",
]
}
diff --git a/chromium/components/signin/core/browser/DEPS b/chromium/components/signin/core/browser/DEPS
index 26ab35f5881..51f30132111 100644
--- a/chromium/components/signin/core/browser/DEPS
+++ b/chromium/components/signin/core/browser/DEPS
@@ -2,9 +2,7 @@ include_rules = [
"+components/account_id",
"+components/data_use_measurement/core",
"+components/image_fetcher/core",
- "+components/invalidation/public",
"+components/metrics",
- "+google/cacheinvalidation",
"+jni",
"+mojo/public",
"+services/identity/public",
diff --git a/chromium/components/signin/core/browser/about_signin_internals.cc b/chromium/components/signin/core/browser/about_signin_internals.cc
index ad8dd0679f8..b3965c089db 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.cc
+++ b/chromium/components/signin/core/browser/about_signin_internals.cc
@@ -8,8 +8,6 @@
#include <algorithm>
#include <tuple>
-#include <utility>
-#include <vector>
#include "base/command_line.h"
#include "base/hash.h"
@@ -21,13 +19,12 @@
#include "build/build_config.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_switches.h"
#include "google_apis/gaia/oauth2_token_service_delegate.h"
#include "net/base/backoff_entry.h"
+#include "services/identity/public/cpp/accounts_in_cookie_jar_info.h"
+#include "services/identity/public/cpp/diagnostics_provider.h"
#include "services/identity/public/cpp/identity_manager.h"
namespace {
@@ -180,18 +177,12 @@ std::string GetAccountConsistencyDescription(
} // anonymous namespace
AboutSigninInternals::AboutSigninInternals(
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker,
identity::IdentityManager* identity_manager,
SigninErrorController* signin_error_controller,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency)
- : token_service_(token_service),
- account_tracker_(account_tracker),
- identity_manager_(identity_manager),
+ : identity_manager_(identity_manager),
client_(nullptr),
signin_error_controller_(signin_error_controller),
- cookie_manager_service_(cookie_manager_service),
account_consistency_(account_consistency) {}
AboutSigninInternals::~AboutSigninInternals() {}
@@ -302,16 +293,12 @@ void AboutSigninInternals::Initialize(SigninClient* client) {
signin_error_controller_->AddObserver(this);
identity_manager_->AddObserver(this);
identity_manager_->AddDiagnosticsObserver(this);
- token_service_->AddDiagnosticsObserver(this);
- cookie_manager_service_->AddObserver(this);
}
void AboutSigninInternals::Shutdown() {
signin_error_controller_->RemoveObserver(this);
identity_manager_->RemoveObserver(this);
identity_manager_->RemoveDiagnosticsObserver(this);
- token_service_->RemoveDiagnosticsObserver(this);
- cookie_manager_service_->RemoveObserver(this);
}
void AboutSigninInternals::NotifyObservers() {
@@ -319,19 +306,16 @@ void AboutSigninInternals::NotifyObservers() {
return;
std::unique_ptr<base::DictionaryValue> signin_status_value =
- signin_status_.ToValue(account_tracker_, identity_manager_,
- signin_error_controller_, token_service_,
- cookie_manager_service_, client_,
- account_consistency_);
+ signin_status_.ToValue(identity_manager_, signin_error_controller_,
+ client_, account_consistency_);
for (auto& observer : signin_observers_)
observer.OnSigninStateChanged(signin_status_value.get());
}
std::unique_ptr<base::DictionaryValue> AboutSigninInternals::GetSigninStatus() {
- return signin_status_.ToValue(
- account_tracker_, identity_manager_, signin_error_controller_,
- token_service_, cookie_manager_service_, client_, account_consistency_);
+ return signin_status_.ToValue(identity_manager_, signin_error_controller_,
+ client_, account_consistency_);
}
void AboutSigninInternals::OnAccessTokenRequested(
@@ -349,10 +333,10 @@ void AboutSigninInternals::OnAccessTokenRequested(
NotifyObservers();
}
-void AboutSigninInternals::OnFetchAccessTokenComplete(
+void AboutSigninInternals::OnAccessTokenRequestCompleted(
const std::string& account_id,
const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes,
+ const identity::ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) {
TokenInfo* token = signin_status_.FindToken(account_id, consumer_id, scopes);
@@ -368,7 +352,7 @@ void AboutSigninInternals::OnFetchAccessTokenComplete(
NotifyObservers();
}
-void AboutSigninInternals::OnRefreshTokenAvailableFromSource(
+void AboutSigninInternals::OnRefreshTokenUpdatedForAccountFromSource(
const std::string& account_id,
bool is_refresh_token_valid,
const std::string& source) {
@@ -382,7 +366,7 @@ void AboutSigninInternals::OnRefreshTokenAvailableFromSource(
signin_status_.AddRefreshTokenEvent(event);
}
-void AboutSigninInternals::OnRefreshTokenRevokedFromSource(
+void AboutSigninInternals::OnRefreshTokenRemovedForAccountFromSource(
const std::string& account_id,
const std::string& source) {
RefreshTokenEvent event;
@@ -404,9 +388,9 @@ void AboutSigninInternals::OnEndBatchOfRefreshTokenStateChanges() {
NotifyObservers();
}
-void AboutSigninInternals::OnAccessTokenRemoved(
+void AboutSigninInternals::OnAccessTokenRemovedFromCache(
const std::string& account_id,
- const OAuth2TokenService::ScopeSet& scopes) {
+ const identity::ScopeSet& scopes) {
for (const std::unique_ptr<TokenInfo>& token :
signin_status_.token_info_map[account_id]) {
if (token->scopes == scopes)
@@ -436,31 +420,31 @@ void AboutSigninInternals::OnPrimaryAccountSigninFailed(
}
void AboutSigninInternals::OnPrimaryAccountSet(
- const AccountInfo& primary_account_info) {
+ const CoreAccountInfo& primary_account_info) {
NotifyObservers();
}
void AboutSigninInternals::OnPrimaryAccountCleared(
- const AccountInfo& primary_account_info) {
+ const CoreAccountInfo& primary_account_info) {
NotifyObservers();
}
-void AboutSigninInternals::OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const std::vector<gaia::ListedAccount>& signed_out_account,
+void AboutSigninInternals::OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) {
if (error.state() != GoogleServiceAuthError::NONE)
return;
auto cookie_info = std::make_unique<base::ListValue>();
- for (size_t i = 0; i < gaia_accounts.size(); ++i) {
- AddCookieEntry(cookie_info.get(), gaia_accounts[i].raw_email,
- gaia_accounts[i].gaia_id,
- gaia_accounts[i].valid ? "Valid" : "Invalid");
+ for (const auto& signed_in_account :
+ accounts_in_cookie_jar_info.signed_in_accounts) {
+ AddCookieEntry(cookie_info.get(), signed_in_account.raw_email,
+ signed_in_account.gaia_id,
+ signed_in_account.valid ? "Valid" : "Invalid");
}
- if (gaia_accounts.size() == 0) {
+ if (accounts_in_cookie_jar_info.signed_in_accounts.size() == 0) {
AddCookieEntry(cookie_info.get(), "No Accounts Present.", std::string(),
std::string());
}
@@ -472,9 +456,8 @@ void AboutSigninInternals::OnGaiaAccountsInCookieUpdated(
observer.OnCookieAccountsFetched(&cookie_status);
}
-AboutSigninInternals::TokenInfo::TokenInfo(
- const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes)
+AboutSigninInternals::TokenInfo::TokenInfo(const std::string& consumer_id,
+ const identity::ScopeSet& scopes)
: consumer_id(consumer_id),
scopes(scopes),
request_time(base::Time::Now()),
@@ -537,7 +520,7 @@ AboutSigninInternals::TokenInfo::ToValue() const {
}
AboutSigninInternals::RefreshTokenEvent::RefreshTokenEvent()
- : timestamp(base::Time::Now()){};
+ : timestamp(base::Time::Now()) {}
std::string AboutSigninInternals::RefreshTokenEvent::GetTypeAsString() const {
switch (type) {
@@ -560,7 +543,7 @@ AboutSigninInternals::SigninStatus::~SigninStatus() {}
AboutSigninInternals::TokenInfo* AboutSigninInternals::SigninStatus::FindToken(
const std::string& account_id,
const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes) {
+ const identity::ScopeSet& scopes) {
for (const std::unique_ptr<TokenInfo>& token : token_info_map[account_id]) {
if (token->consumer_id == consumer_id && token->scopes == scopes)
return token.get();
@@ -578,11 +561,8 @@ void AboutSigninInternals::SigninStatus::AddRefreshTokenEvent(
std::unique_ptr<base::DictionaryValue>
AboutSigninInternals::SigninStatus::ToValue(
- AccountTrackerService* account_tracker,
identity::IdentityManager* identity_manager,
SigninErrorController* signin_error_controller,
- ProfileOAuth2TokenService* token_service,
- GaiaCookieManagerService* cookie_manager_service,
SigninClient* signin_client,
signin::AccountConsistencyMethod account_consistency) {
auto signin_status = std::make_unique<base::DictionaryValue>();
@@ -599,7 +579,8 @@ AboutSigninInternals::SigninStatus::ToValue(
basic_info, "Signin Status",
identity_manager->HasPrimaryAccount() ? "Signed In" : "Not Signed In");
OAuth2TokenServiceDelegate::LoadCredentialsState load_tokens_state =
- token_service->GetDelegate()->load_credentials_state();
+ identity_manager->GetDiagnosticsProvider()
+ ->GetDetailedStateOfLoadingOfRefreshTokens();
AddSectionEntry(basic_info, "TokenService Load Status",
TokenServiceLoadCredentialsStateToLabel(load_tokens_state));
@@ -608,9 +589,11 @@ AboutSigninInternals::SigninStatus::ToValue(
AddSectionEntry(basic_info,
SigninStatusFieldToLabel(signin_internals_util::ACCOUNT_ID),
account_id);
- AddSectionEntry(basic_info,
- SigninStatusFieldToLabel(signin_internals_util::GAIA_ID),
- account_tracker->GetAccountInfo(account_id).gaia);
+ AddSectionEntry(
+ basic_info, SigninStatusFieldToLabel(signin_internals_util::GAIA_ID),
+ identity_manager
+ ->FindAccountInfoForAccountWithRefreshTokenByAccountId(account_id)
+ ->gaia);
AddSectionEntry(basic_info,
SigninStatusFieldToLabel(signin_internals_util::USERNAME),
identity_manager->GetPrimaryAccountInfo().email);
@@ -618,7 +601,10 @@ AboutSigninInternals::SigninStatus::ToValue(
const std::string error_account_id =
signin_error_controller->error_account_id();
const std::string error_username =
- account_tracker->GetAccountInfo(error_account_id).email;
+ identity_manager
+ ->FindAccountInfoForAccountWithRefreshTokenByAccountId(
+ error_account_id)
+ ->email;
AddSectionEntry(basic_info, "Auth Error",
signin_error_controller->auth_error().ToString());
AddSectionEntry(basic_info, "Auth Error Account Id", error_account_id);
@@ -646,13 +632,13 @@ AboutSigninInternals::SigninStatus::ToValue(
.second);
}
- const net::BackoffEntry* cookie_manager_backoff_entry =
- cookie_manager_service->GetBackoffEntry();
+ base::TimeDelta cookie_requests_delay =
+ identity_manager->GetDiagnosticsProvider()
+ ->GetDelayBeforeMakingCookieRequests();
- if (cookie_manager_backoff_entry->ShouldRejectRequest()) {
+ if (cookie_requests_delay > base::TimeDelta()) {
base::Time next_retry_time =
- base::Time::NowFromSystemTime() +
- cookie_manager_backoff_entry->GetTimeUntilRelease();
+ base::Time::NowFromSystemTime() + cookie_requests_delay;
std::string next_retry_time_as_str =
base::UTF16ToUTF8(
@@ -664,14 +650,13 @@ AboutSigninInternals::SigninStatus::ToValue(
"");
}
- const net::BackoffEntry* token_service_backoff_entry = token_service->
- GetDelegateBackoffEntry();
+ base::TimeDelta token_requests_delay =
+ identity_manager->GetDiagnosticsProvider()
+ ->GetDelayBeforeMakingAccessTokenRequests();
- if (token_service_backoff_entry &&
- token_service_backoff_entry->ShouldRejectRequest()) {
+ if (token_requests_delay > base::TimeDelta()) {
base::Time next_retry_time =
- base::Time::NowFromSystemTime() +
- token_service_backoff_entry->GetTimeUntilRelease();
+ base::Time::NowFromSystemTime() + token_requests_delay;
std::string next_retry_time_as_str =
base::UTF16ToUTF8(
@@ -696,25 +681,30 @@ AboutSigninInternals::SigninStatus::ToValue(
signin_status->Set("token_info", std::move(token_info));
// Account info section
- auto account_info = std::make_unique<base::ListValue>();
- const std::vector<std::string>& accounts_in_token_service =
- token_service->GetAccounts();
- if (accounts_in_token_service.size() == 0) {
+ auto account_info_section = std::make_unique<base::ListValue>();
+ const std::vector<AccountInfo>& accounts_with_refresh_tokens =
+ identity_manager->GetAccountsWithRefreshTokens();
+ if (accounts_with_refresh_tokens.size() == 0) {
auto no_token_entry = std::make_unique<base::DictionaryValue>();
no_token_entry->SetString("accountId", "No token in Token Service.");
- account_info->Append(std::move(no_token_entry));
+ account_info_section->Append(std::move(no_token_entry));
} else {
- for (const std::string& account_id : accounts_in_token_service) {
+ for (const AccountInfo account_info : accounts_with_refresh_tokens) {
auto entry = std::make_unique<base::DictionaryValue>();
- entry->SetString("accountId", account_id);
+ entry->SetString("accountId", account_info.account_id);
+ // TODO(https://crbug.com/919793): Remove this field once the token
+ // service is internally consistent on all platforms.
entry->SetBoolean("hasRefreshToken",
- token_service->RefreshTokenIsAvailable(account_id));
- entry->SetBoolean("hasAuthError",
- token_service->RefreshTokenHasError(account_id));
- account_info->Append(std::move(entry));
+ identity_manager->HasAccountWithRefreshToken(
+ account_info.account_id));
+ entry->SetBoolean(
+ "hasAuthError",
+ identity_manager->HasAccountWithRefreshTokenInPersistentErrorState(
+ account_info.account_id));
+ account_info_section->Append(std::move(entry));
}
}
- signin_status->Set("accountInfo", std::move(account_info));
+ signin_status->Set("accountInfo", std::move(account_info_section));
// Refresh token events section
auto refresh_token_events_value = std::make_unique<base::ListValue>();
diff --git a/chromium/components/signin/core/browser/about_signin_internals.h b/chromium/components/signin/core/browser/about_signin_internals.h
index 5ce029fbc09..89a1b42ac98 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.h
+++ b/chromium/components/signin/core/browser/about_signin_internals.h
@@ -9,24 +9,24 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
+#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/values.h"
#include "components/keyed_service/core/keyed_service.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_error_controller.h"
-#include "google_apis/gaia/oauth2_token_service.h"
+#include "components/signin/core/browser/signin_internals_util.h"
#include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/scope_set.h"
namespace identity {
-class IdentityManager;
+struct AccountsInCookieJarInfo;
}
-class AccountTrackerService;
class PrefRegistrySimple;
-class ProfileOAuth2TokenService;
class SigninClient;
// Many values in SigninStatus are also associated with a timestamp.
@@ -37,8 +37,6 @@ using TimedSigninStatusValue = std::pair<std::string, std::string>;
// to propagate to about:signin-internals via SigninInternalsUI.
class AboutSigninInternals
: public KeyedService,
- public OAuth2TokenService::DiagnosticsObserver,
- public GaiaCookieManagerService::Observer,
SigninErrorController::Observer,
identity::IdentityManager::Observer,
identity::IdentityManager::DiagnosticsObserver {
@@ -53,11 +51,8 @@ class AboutSigninInternals
virtual void OnCookieAccountsFetched(const base::DictionaryValue* info) = 0;
};
- AboutSigninInternals(ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker,
- identity::IdentityManager* identity_manager,
+ AboutSigninInternals(identity::IdentityManager* identity_manager,
SigninErrorController* signin_error_controller,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency);
~AboutSigninInternals() override;
@@ -96,17 +91,15 @@ class AboutSigninInternals
// }
std::unique_ptr<base::DictionaryValue> GetSigninStatus();
- // GaiaCookieManagerService::Observer implementations.
- void OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
+ // identity::IdentityManager::Observer implementations.
+ void OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override;
private:
// Encapsulates diagnostic information about tokens for different services.
struct TokenInfo {
- TokenInfo(const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes);
+ TokenInfo(const std::string& consumer_id, const identity::ScopeSet& scopes);
~TokenInfo();
std::unique_ptr<base::DictionaryValue> ToValue() const;
@@ -116,8 +109,8 @@ class AboutSigninInternals
// Called when the token is invalidated.
void Invalidate();
- std::string consumer_id; // service that requested the token.
- OAuth2TokenService::ScopeSet scopes; // Scoped that are requested.
+ std::string consumer_id; // service that requested the token.
+ identity::ScopeSet scopes; // Scoped that are requested.
base::Time request_time;
base::Time receive_time;
base::Time expiration_time;
@@ -160,7 +153,7 @@ class AboutSigninInternals
TokenInfo* FindToken(const std::string& account_id,
const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes);
+ const identity::ScopeSet& scopes);
void AddRefreshTokenEvent(const RefreshTokenEvent& event);
@@ -182,11 +175,8 @@ class AboutSigninInternals
// }],
// }
std::unique_ptr<base::DictionaryValue> ToValue(
- AccountTrackerService* account_tracker,
identity::IdentityManager* identity_manager,
SigninErrorController* signin_error_controller,
- ProfileOAuth2TokenService* token_service,
- GaiaCookieManagerService* cookie_manager_service_,
SigninClient* signin_client,
signin::AccountConsistencyMethod account_consistency);
};
@@ -195,30 +185,30 @@ class AboutSigninInternals
void OnAccessTokenRequested(const std::string& account_id,
const std::string& consumer_id,
const identity::ScopeSet& scopes) override;
-
- // OAuth2TokenService::DiagnosticsObserver implementations.
- void OnFetchAccessTokenComplete(const std::string& account_id,
- const std::string& consumer_id,
- const OAuth2TokenService::ScopeSet& scopes,
- GoogleServiceAuthError error,
- base::Time expiration_time) override;
- void OnAccessTokenRemoved(
+ void OnAccessTokenRequestCompleted(const std::string& account_id,
+ const std::string& consumer_id,
+ const identity::ScopeSet& scopes,
+ GoogleServiceAuthError error,
+ base::Time expiration_time) override;
+ void OnAccessTokenRemovedFromCache(const std::string& account_id,
+ const identity::ScopeSet& scopes) override;
+ void OnRefreshTokenUpdatedForAccountFromSource(
+ const std::string& account_id,
+ bool is_refresh_token_valid,
+ const std::string& source) override;
+ void OnRefreshTokenRemovedForAccountFromSource(
const std::string& account_id,
- const OAuth2TokenService::ScopeSet& scopes) override;
- void OnRefreshTokenAvailableFromSource(const std::string& account_id,
- bool is_refresh_token_valid,
- const std::string& source) override;
- void OnRefreshTokenRevokedFromSource(const std::string& account_id,
- const std::string& source) override;
+ const std::string& source) override;
// IdentityManager::Observer implementations.
void OnRefreshTokensLoaded() override;
void OnEndBatchOfRefreshTokenStateChanges() override;
void OnPrimaryAccountSigninFailed(
const GoogleServiceAuthError& error) override;
- void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
+ void OnPrimaryAccountSet(
+ const CoreAccountInfo& primary_account_info) override;
void OnPrimaryAccountCleared(
- const AccountInfo& primary_account_info) override;
+ const CoreAccountInfo& primary_account_info) override;
void NotifyTimedSigninFieldValueChanged(
const signin_internals_util::TimedSigninStatusField& field,
@@ -229,12 +219,6 @@ class AboutSigninInternals
// SigninErrorController::Observer implementation
void OnErrorChanged() override;
- // Weak pointer to the token service.
- ProfileOAuth2TokenService* token_service_;
-
- // Weak pointer to the account tracker.
- AccountTrackerService* account_tracker_;
-
// Weak pointer to the identity manager.
identity::IdentityManager* identity_manager_;
@@ -244,9 +228,6 @@ class AboutSigninInternals
// Weak pointer to the SigninErrorController
SigninErrorController* signin_error_controller_;
- // Weak pointer to the GaiaCookieManagerService
- GaiaCookieManagerService* cookie_manager_service_;
-
// Encapsulates the actual signin and token related values.
// Most of the values are mirrored in the prefs for persistence.
SigninStatus signin_status_;
diff --git a/chromium/components/signin/core/browser/account_consistency_method.cc b/chromium/components/signin/core/browser/account_consistency_method.cc
index f5ac55760ec..b0b031ae515 100644
--- a/chromium/components/signin/core/browser/account_consistency_method.cc
+++ b/chromium/components/signin/core/browser/account_consistency_method.cc
@@ -15,6 +15,11 @@ bool AccountConsistencyMethodGreaterOrEqual(AccountConsistencyMethod a,
}
} // namespace
+#if defined(OS_ANDROID)
+const base::Feature kMiceFeature{"MobileIdentityConsistency",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
bool DiceMethodGreaterOrEqual(AccountConsistencyMethod a,
AccountConsistencyMethod b) {
DCHECK_NE(AccountConsistencyMethod::kMirror, a);
diff --git a/chromium/components/signin/core/browser/account_consistency_method.h b/chromium/components/signin/core/browser/account_consistency_method.h
index bee4dc36835..c46becfe07d 100644
--- a/chromium/components/signin/core/browser/account_consistency_method.h
+++ b/chromium/components/signin/core/browser/account_consistency_method.h
@@ -9,8 +9,17 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_CONSISTENCY_METHOD_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_CONSISTENCY_METHOD_H_
+#include "base/feature_list.h"
+#include "build/build_config.h"
+
namespace signin {
+#if defined(OS_ANDROID)
+// Mice is similar to Mirror but also works when the user is not opted into
+// Sync.
+extern const base::Feature kMiceFeature;
+#endif
+
// TODO(https://crbug.com/777774): Cleanup this enum and remove related
// functions once Dice is fully rolled out, and/or Mirror code is removed on
// desktop.
diff --git a/chromium/components/signin/core/browser/account_fetcher_service.cc b/chromium/components/signin/core/browser/account_fetcher_service.cc
index 23a8aa36d01..c8a2ac09a8f 100644
--- a/chromium/components/signin/core/browser/account_fetcher_service.cc
+++ b/chromium/components/signin/core/browser/account_fetcher_service.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/trace_event/trace_event.h"
@@ -40,6 +41,8 @@ bool AccountSupportsUserInfo(const std::string& account_id) {
} // namespace
+const char kImageFetcherUmaClient[] = "AccountFetcherService";
+
// This pref used to be in the AccountTrackerService, hence its string value.
const char AccountFetcherService::kLastUpdatePref[] =
"account_tracker_service_last_update";
@@ -47,20 +50,7 @@ const char AccountFetcherService::kLastUpdatePref[] =
const int AccountFetcherService::kAccountImageDownloadSize = 64;
// AccountFetcherService implementation
-AccountFetcherService::AccountFetcherService()
- : account_tracker_service_(nullptr),
- token_service_(nullptr),
- signin_client_(nullptr),
- invalidation_service_(nullptr),
- network_fetches_enabled_(false),
- profile_loaded_(false),
- refresh_tokens_loaded_(false),
- shutdown_called_(false),
-#if defined(OS_ANDROID)
- child_info_request_(nullptr),
-#endif
- scheduled_refresh_enabled_(true) {
-}
+AccountFetcherService::AccountFetcherService() = default;
AccountFetcherService::~AccountFetcherService() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -102,7 +92,6 @@ void AccountFetcherService::Shutdown() {
// unregistered during the lifetime of the invalidation service.
child_info_request_.reset();
#endif
- invalidation_service_ = nullptr;
shutdown_called_ = true;
}
@@ -110,28 +99,32 @@ bool AccountFetcherService::IsAllUserInfoFetched() const {
return user_info_requests_.empty();
}
-void AccountFetcherService::FetchUserInfoBeforeSignin(
+void AccountFetcherService::ForceRefreshOfAccountInfo(
const std::string& account_id) {
DCHECK(network_fetches_enabled_);
RefreshAccountInfo(account_id, false);
}
-void AccountFetcherService::SetupInvalidationsOnProfileLoad(
- invalidation::InvalidationService* invalidation_service) {
- DCHECK(!invalidation_service_);
- DCHECK(!profile_loaded_);
+void AccountFetcherService::OnNetworkInitialized() {
+ DCHECK(!network_initialized_);
DCHECK(!network_fetches_enabled_);
#if defined(OS_ANDROID)
DCHECK(!child_info_request_);
#endif
- invalidation_service_ = invalidation_service;
- profile_loaded_ = true;
+ network_initialized_ = true;
MaybeEnableNetworkFetches();
}
void AccountFetcherService::EnableNetworkFetchesForTest() {
- SetupInvalidationsOnProfileLoad(nullptr);
- OnRefreshTokensLoaded();
+ if (!network_initialized_)
+ OnNetworkInitialized();
+
+ if (!refresh_tokens_loaded_)
+ OnRefreshTokensLoaded();
+}
+
+void AccountFetcherService::EnableAccountRemovalForTest() {
+ enable_account_removal_for_test_ = true;
}
void AccountFetcherService::RefreshAllAccountInfo(bool only_fetch_if_invalid) {
@@ -169,7 +162,7 @@ void AccountFetcherService::UpdateChildInfo() {
void AccountFetcherService::MaybeEnableNetworkFetches() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!profile_loaded_ || !refresh_tokens_loaded_)
+ if (!network_initialized_ || !refresh_tokens_loaded_)
return;
if (!network_fetches_enabled_) {
network_fetches_enabled_ = true;
@@ -191,8 +184,6 @@ void AccountFetcherService::RefreshAllAccountsAndScheduleNext() {
}
void AccountFetcherService::ScheduleNextRefresh() {
- if (!scheduled_refresh_enabled_)
- return;
DCHECK(!timer_.IsRunning());
DCHECK(network_fetches_enabled_);
@@ -321,9 +312,11 @@ void AccountFetcherService::FetchAccountImage(const std::string& account_id) {
GURL image_url_with_size(signin::GetAvatarImageURLWithOptions(
picture_url, kAccountImageDownloadSize, true /* no_silhouette */));
auto callback = base::BindRepeating(&AccountFetcherService::OnImageFetched,
- base::Unretained(this));
- GetOrCreateImageFetcher()->FetchImage(account_id, image_url_with_size,
- callback, traffic_annotation);
+ base::Unretained(this), account_id);
+ image_fetcher::ImageFetcherParams params(traffic_annotation,
+ kImageFetcherUmaClient);
+ GetOrCreateImageFetcher()->FetchImage(image_url_with_size, callback,
+ std::move(params));
}
void AccountFetcherService::OnUserInfoFetchFailure(
@@ -360,8 +353,14 @@ void AccountFetcherService::OnRefreshTokenRevoked(
account_id);
DVLOG(1) << "REVOKED " << account_id;
- if (!network_fetches_enabled_)
+ // Short-circuit out if network fetches are not enabled.
+ if (!network_fetches_enabled_) {
+ if (enable_account_removal_for_test_) {
+ account_tracker_service_->StopTrackingAccount(account_id);
+ }
return;
+ }
+
user_info_requests_.erase(account_id);
#if defined(OS_ANDROID)
UpdateChildInfo();
diff --git a/chromium/components/signin/core/browser/account_fetcher_service.h b/chromium/components/signin/core/browser/account_fetcher_service.h
index 7ced83d8402..621c0a170e5 100644
--- a/chromium/components/signin/core/browser/account_fetcher_service.h
+++ b/chromium/components/signin/core/browser/account_fetcher_service.h
@@ -38,10 +38,6 @@ class ImageDecoder;
class ImageFetcherImpl;
} // namespace image_fetcher
-namespace invalidation {
-class InvalidationService;
-}
-
class AccountFetcherService : public KeyedService,
public OAuth2TokenService::Observer {
public:
@@ -70,20 +66,27 @@ class AccountFetcherService : public KeyedService,
// there are still unfininshed fetchers.
virtual bool IsAllUserInfoFetched() const;
- void FetchUserInfoBeforeSignin(const std::string& account_id);
+ void ForceRefreshOfAccountInfo(const std::string& account_id);
AccountTrackerService* account_tracker_service() const {
return account_tracker_service_;
}
- // It is important that network fetches are not enabled until the profile is
- // loaded independent of when we inject the invalidation service.
- // See http://crbug.com/441399 for more context.
- void SetupInvalidationsOnProfileLoad(
- invalidation::InvalidationService* invalidation_service);
+ // It is important that network fetches are not enabled until the network is
+ // initialized. See http://crbug.com/441399 for more context.
+ void OnNetworkInitialized();
+ // Force-enables network fetches. For use in testing contexts. Use this only
+ // if also controlling the URLLoaderFactory used to make network requests
+ // (via |signin_client|).
void EnableNetworkFetchesForTest();
+ // Force-enables account removals in response to refresh token revocations.
+ // For use in testing contexts. Safer to use than
+ // EnableNetworkFetchesForTest(), as invoking this method does not result in
+ // network requests.
+ void EnableAccountRemovalForTest();
+
#if defined(OS_ANDROID)
// Called by ChildAccountInfoFetcherAndroid.
void SetIsChildAccount(const std::string& account_id, bool is_child_account);
@@ -112,9 +115,9 @@ class AccountFetcherService : public KeyedService,
// Virtual so that tests can override the network fetching behaviour.
// Further the two fetches are managed by a different refresh logic and
// thus, can not be combined.
- virtual void StartFetchingUserInfo(const std::string& account_id);
+ void StartFetchingUserInfo(const std::string& account_id);
#if defined(OS_ANDROID)
- virtual void StartFetchingChildInfo(const std::string& account_id);
+ void StartFetchingChildInfo(const std::string& account_id);
// If there is more than one account in a profile, we forcibly reset the
// child status for an account to be false.
@@ -139,25 +142,22 @@ class AccountFetcherService : public KeyedService,
const gfx::Image& image,
const image_fetcher::RequestMetadata& image_metadata);
- AccountTrackerService* account_tracker_service_; // Not owned.
- OAuth2TokenService* token_service_; // Not owned.
- SigninClient* signin_client_; // Not owned.
- invalidation::InvalidationService* invalidation_service_; // Not owned.
- bool network_fetches_enabled_;
- bool profile_loaded_;
- bool refresh_tokens_loaded_;
+ AccountTrackerService* account_tracker_service_ = nullptr; // Not owned.
+ OAuth2TokenService* token_service_ = nullptr; // Not owned.
+ SigninClient* signin_client_ = nullptr; // Not owned.
+ bool network_fetches_enabled_ = false;
+ bool network_initialized_ = false;
+ bool refresh_tokens_loaded_ = false;
+ bool shutdown_called_ = false;
+ bool enable_account_removal_for_test_ = false;
base::Time last_updated_;
base::OneShotTimer timer_;
- bool shutdown_called_;
#if defined(OS_ANDROID)
std::string child_request_account_id_;
std::unique_ptr<ChildAccountInfoFetcherAndroid> child_info_request_;
#endif
- // Only disabled in tests.
- bool scheduled_refresh_enabled_;
-
// Holds references to account info fetchers keyed by account_id.
std::unordered_map<std::string, std::unique_ptr<AccountInfoFetcher>>
user_info_requests_;
diff --git a/chromium/components/signin/core/browser/account_info.cc b/chromium/components/signin/core/browser/account_info.cc
index 8fc78378066..c089abf4033 100644
--- a/chromium/components/signin/core/browser/account_info.cc
+++ b/chromium/components/signin/core/browser/account_info.cc
@@ -40,6 +40,24 @@ const char kNoHostedDomainFound[] = "NO_HOSTED_DOMAIN";
// This must be a string which can never be a valid picture URL.
const char kNoPictureURLFound[] = "NO_PICTURE_URL";
+CoreAccountInfo::CoreAccountInfo() = default;
+
+CoreAccountInfo::~CoreAccountInfo() = default;
+
+CoreAccountInfo::CoreAccountInfo(const CoreAccountInfo& other) = default;
+
+CoreAccountInfo::CoreAccountInfo(CoreAccountInfo&& other) noexcept = default;
+
+CoreAccountInfo& CoreAccountInfo::operator=(const CoreAccountInfo& other) =
+ default;
+
+CoreAccountInfo& CoreAccountInfo::operator=(CoreAccountInfo&& other) noexcept =
+ default;
+
+bool CoreAccountInfo::IsEmpty() const {
+ return account_id.empty() && email.empty() && gaia.empty();
+}
+
AccountInfo::AccountInfo() = default;
AccountInfo::~AccountInfo() = default;
@@ -53,9 +71,9 @@ AccountInfo& AccountInfo::operator=(const AccountInfo& other) = default;
AccountInfo& AccountInfo::operator=(AccountInfo&& other) noexcept = default;
bool AccountInfo::IsEmpty() const {
- return account_id.empty() && email.empty() && gaia.empty() &&
- hosted_domain.empty() && full_name.empty() && given_name.empty() &&
- locale.empty() && picture_url.empty();
+ return CoreAccountInfo::IsEmpty() && hosted_domain.empty() &&
+ full_name.empty() && given_name.empty() && locale.empty() &&
+ picture_url.empty();
}
bool AccountInfo::IsValid() const {
@@ -86,10 +104,9 @@ bool AccountInfo::UpdateWith(const AccountInfo& other) {
return modified;
}
-AccountId AccountIdFromAccountInfo(const AccountInfo& account_info) {
- if (account_info.IsEmpty())
+AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info) {
+ if (account_info.email.empty() || account_info.gaia.empty())
return EmptyAccountId();
- DCHECK(!account_info.email.empty() && !account_info.gaia.empty());
return AccountId::FromUserEmailGaiaId(account_info.email, account_info.gaia);
}
diff --git a/chromium/components/signin/core/browser/account_info.h b/chromium/components/signin/core/browser/account_info.h
index 9be08af8f5f..fa581f0ca88 100644
--- a/chromium/components/signin/core/browser/account_info.h
+++ b/chromium/components/signin/core/browser/account_info.h
@@ -16,22 +16,41 @@ extern const char kNoHostedDomainFound[];
// Value representing no picture URL associated with an account.
extern const char kNoPictureURLFound[];
-// Information about a specific account.
-struct AccountInfo {
+// Stores the basic information about an account that is always known
+// about the account (from the moment it is added to the system until
+// it is removed). It will unfrequently, if ever, change.
+struct CoreAccountInfo {
+ CoreAccountInfo();
+ ~CoreAccountInfo();
+
+ CoreAccountInfo(const CoreAccountInfo& other);
+ CoreAccountInfo(CoreAccountInfo&& other) noexcept;
+
+ CoreAccountInfo& operator=(const CoreAccountInfo& other);
+ CoreAccountInfo& operator=(CoreAccountInfo&& other) noexcept;
+
+ std::string account_id;
+ std::string gaia;
+ std::string email;
+
+ bool is_under_advanced_protection = false;
+
+ // Returns true if all fields in the account info are empty.
+ bool IsEmpty() const;
+};
+
+// Stores all the information known about an account. Part of the information
+// may only become available asynchronously.
+struct AccountInfo : public CoreAccountInfo {
AccountInfo();
~AccountInfo();
- // Copy/move constructors and assignment operators are defined out-of-line
- // as they are identified as complex by clang plugin.
AccountInfo(const AccountInfo& other);
AccountInfo(AccountInfo&& other) noexcept;
AccountInfo& operator=(const AccountInfo& other);
AccountInfo& operator=(AccountInfo&& other) noexcept;
- std::string account_id; // The account ID used by OAuth2TokenService.
- std::string gaia;
- std::string email;
std::string full_name;
std::string given_name;
std::string hosted_domain;
@@ -39,7 +58,6 @@ struct AccountInfo {
std::string picture_url;
gfx::Image account_image;
bool is_child_account = false;
- bool is_under_advanced_protection = false;
// Returns true if all fields in the account info are empty.
bool IsEmpty() const;
@@ -53,6 +71,6 @@ struct AccountInfo {
};
// Returns AccountID populated from |account_info|.
-AccountId AccountIdFromAccountInfo(const AccountInfo& account_info);
+AccountId AccountIdFromAccountInfo(const CoreAccountInfo& account_info);
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_INFO_H_
diff --git a/chromium/components/signin/core/browser/account_investigator.cc b/chromium/components/signin/core/browser/account_investigator.cc
index 239b372330e..3389166b3a2 100644
--- a/chromium/components/signin/core/browser/account_investigator.cc
+++ b/chromium/components/signin/core/browser/account_investigator.cc
@@ -32,7 +32,7 @@ namespace {
const char kSignedInHashPrefix[] = "i";
const char kSignedOutHashPrefix[] = "o";
-bool AreSame(const AccountInfo& info, const ListedAccount& account) {
+bool AreSame(const CoreAccountInfo& info, const ListedAccount& account) {
return info.account_id == account.id;
}
@@ -73,32 +73,20 @@ void AccountInvestigator::Shutdown() {
timer_.Stop();
}
-void AccountInvestigator::OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {
- // This hook isn't particularly useful for us. Most cookie jar changes fly by
- // without invoking this method, and some sign ins cause this method can get
- // called serveral times.
-}
-
void AccountInvestigator::OnAccountsInCookieUpdated(
const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) {
- OnGaiaAccountsInCookieUpdated(accounts_in_cookie_jar_info.signed_in_accounts,
- accounts_in_cookie_jar_info.signed_out_accounts,
- error);
-}
-
-void AccountInvestigator::OnGaiaAccountsInCookieUpdated(
- const std::vector<ListedAccount>& signed_in_accounts,
- const std::vector<ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error) {
if (error != GoogleServiceAuthError::AuthErrorNone()) {
// If we are pending periodic reporting, leave the flag set, and we will
// continue next time the ListAccounts call succeeds.
return;
}
+ const std::vector<ListedAccount>& signed_in_accounts(
+ accounts_in_cookie_jar_info.signed_in_accounts);
+ const std::vector<ListedAccount>& signed_out_accounts(
+ accounts_in_cookie_jar_info.signed_out_accounts);
+
// Handling this is tricky. We could be here because there was a change. We
// could be here because we tried to do periodic reporting but there wasn't
// a valid cached ListAccounts response ready for us. Or even both of these
@@ -168,7 +156,7 @@ std::string AccountInvestigator::HashAccounts(
// static
AccountRelation AccountInvestigator::DiscernRelation(
- const AccountInfo& info,
+ const CoreAccountInfo& info,
const std::vector<ListedAccount>& signed_in_accounts,
const std::vector<ListedAccount>& signed_out_accounts) {
if (signed_in_accounts.empty() && signed_out_accounts.empty()) {
diff --git a/chromium/components/signin/core/browser/account_investigator.h b/chromium/components/signin/core/browser/account_investigator.h
index dd6b6661f7a..0d8acc738fa 100644
--- a/chromium/components/signin/core/browser/account_investigator.h
+++ b/chromium/components/signin/core/browser/account_investigator.h
@@ -13,7 +13,7 @@
#include "components/keyed_service/core/keyed_service.h"
#include "services/identity/public/cpp/identity_manager.h"
-struct AccountInfo;
+struct CoreAccountInfo;
class PrefRegistrySimple;
class PrefService;
@@ -55,20 +55,10 @@ class AccountInvestigator : public KeyedService,
void Shutdown() override;
// identity::IdentityManager::Observer:
- void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) override;
void OnAccountsInCookieUpdated(
const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override;
- // Internal implementation of OnAccountsInCookieUpdated. It is public given
- // that it is called directly by unittests.
- void OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& signed_in_accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error);
-
private:
friend class AccountInvestigatorTest;
@@ -88,7 +78,7 @@ class AccountInvestigator : public KeyedService,
// potentially signed into Chrome account, to the various account(s) in the
// given cookie jar.
static signin_metrics::AccountRelation DiscernRelation(
- const AccountInfo& info,
+ const CoreAccountInfo& info,
const std::vector<gaia::ListedAccount>& signed_in_accounts,
const std::vector<gaia::ListedAccount>& signed_out_accounts);
diff --git a/chromium/components/signin/core/browser/account_investigator_unittest.cc b/chromium/components/signin/core/browser/account_investigator_unittest.cc
index d8eaca6d908..e6f5b19c144 100644
--- a/chromium/components/signin/core/browser/account_investigator_unittest.cc
+++ b/chromium/components/signin/core/browser/account_investigator_unittest.cc
@@ -19,6 +19,7 @@
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_environment.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::HistogramTester;
@@ -262,31 +263,40 @@ TEST_F(AccountInvestigatorTest, SharedCookieJarReportWithAccount) {
TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedError) {
const HistogramTester histogram_tester;
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
+ /*accounts_are_fresh=*/true, just_one, no_accounts};
GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_UNAVAILABLE);
- investigator()->OnGaiaAccountsInCookieUpdated(just_one, no_accounts, error);
- EXPECT_EQ(0u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());
+ investigator()->OnAccountsInCookieUpdated(accounts_in_cookie_jar_info, error);
+ EXPECT_EQ(
+ 0u, histogram_tester.GetTotalCountsForPrefix("Signin.CookieJar.").size());
}
TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedOnChange) {
const HistogramTester histogram_tester;
- investigator()->OnGaiaAccountsInCookieUpdated(
- just_one, no_accounts, GoogleServiceAuthError::AuthErrorNone());
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
+ /*accounts_are_fresh=*/true, just_one, no_accounts};
+ investigator()->OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
ExpectSharedReportHistograms(ReportingType::ON_CHANGE, histogram_tester,
nullptr, 1, 0, 1, nullptr, false);
}
TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedSigninOnly) {
// Initial update to simulate the update on first-time-run.
- investigator()->OnGaiaAccountsInCookieUpdated(
- no_accounts, no_accounts, GoogleServiceAuthError::AuthErrorNone());
+ investigator()->OnAccountsInCookieUpdated(
+ identity::AccountsInCookieJarInfo(),
+ GoogleServiceAuthError::AuthErrorNone());
const HistogramTester histogram_tester;
identity_test_env()->SetPrimaryAccount("1@mail.com");
pref_service()->SetString(prefs::kGaiaCookieHash,
Hash(just_one, no_accounts));
- investigator()->OnGaiaAccountsInCookieUpdated(
- just_one, no_accounts, GoogleServiceAuthError::AuthErrorNone());
- EXPECT_EQ(1u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
+ /*accounts_are_fresh=*/true, just_one, no_accounts};
+ investigator()->OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
+ EXPECT_EQ(
+ 1u, histogram_tester.GetTotalCountsForPrefix("Signin.CookieJar.").size());
ExpectRelationReport(ReportingType::ON_CHANGE, histogram_tester,
AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT);
}
@@ -295,15 +305,19 @@ TEST_F(AccountInvestigatorTest,
OnGaiaAccountsInCookieUpdatedSigninSignOutOfContent) {
const HistogramTester histogram_tester;
identity_test_env()->SetPrimaryAccount("1@mail.com");
- investigator()->OnGaiaAccountsInCookieUpdated(
- just_one, no_accounts, GoogleServiceAuthError::AuthErrorNone());
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
+ /*accounts_are_fresh=*/true, just_one, no_accounts};
+ investigator()->OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
ExpectRelationReport(ReportingType::ON_CHANGE, histogram_tester,
AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT);
// Simulate a sign out of the content area.
const HistogramTester histogram_tester2;
- investigator()->OnGaiaAccountsInCookieUpdated(
- no_accounts, just_one, GoogleServiceAuthError::AuthErrorNone());
+ accounts_in_cookie_jar_info = {/*accounts_are_fresh=*/true, no_accounts,
+ just_one};
+ investigator()->OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
const AccountRelation expected_relation =
AccountRelation::NO_SIGNED_IN_SINGLE_SIGNED_OUT_MATCH;
ExpectSharedReportHistograms(ReportingType::ON_CHANGE, histogram_tester2,
@@ -336,7 +350,8 @@ TEST_F(AccountInvestigatorTest, TryPeriodicReportStale) {
const HistogramTester histogram_tester;
TryPeriodicReport();
EXPECT_TRUE(*periodic_pending());
- EXPECT_EQ(0u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());
+ EXPECT_EQ(
+ 0u, histogram_tester.GetTotalCountsForPrefix("Signin.CookieJar.").size());
std::string email("f@bar.com");
identity_test_env()->SetCookieAccounts(
@@ -348,7 +363,7 @@ TEST_F(AccountInvestigatorTest, TryPeriodicReportStale) {
}
TEST_F(AccountInvestigatorTest, TryPeriodicReportEmpty) {
- identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
+ identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(true);
const HistogramTester histogram_tester;
TryPeriodicReport();
diff --git a/chromium/components/signin/core/browser/account_reconcilor.cc b/chromium/components/signin/core/browser/account_reconcilor.cc
index 0393eb4ddda..75aa3602385 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <iterator>
+#include <set>
#include <utility>
#include "base/bind.h"
@@ -27,6 +28,8 @@
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/identity/public/cpp/accounts_cookie_mutator.h"
+#include "services/identity/public/cpp/accounts_in_cookie_jar_info.h"
#include "services/identity/public/cpp/accounts_mutator.h"
using signin::AccountReconcilorDelegate;
@@ -117,19 +120,17 @@ bool RevokeAllSecondaryTokens(
}
// Returns true if current array of existing accounts in cookie is different
-// from the desired one.
+// from the desired one. If this returns false, the multilogin call would be a
+// no-op.
bool AccountsNeedUpdate(
const signin::MultiloginParameters& parameters,
const std::vector<gaia::ListedAccount>& existing_accounts) {
if (parameters.mode ==
- gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER) {
- // In UPDATE mode accounts_to_send are guaranteed to be not empty.
- DCHECK(!parameters.accounts_to_send.empty());
- if (existing_accounts.empty())
- return true;
- // In UPDATE mode update is needed id syncing account is not first.
- if (existing_accounts[0].id != parameters.accounts_to_send[0])
- return true;
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER &&
+ !existing_accounts.empty() && !parameters.accounts_to_send.empty() &&
+ existing_accounts[0].id != parameters.accounts_to_send[0]) {
+ // In UPDATE mode update is needed if first accounts don't match.
+ return true;
}
// Maybe some accounts in cookies are not valid and need refreshing.
std::set<std::string> accounts_to_send_set(
@@ -187,14 +188,11 @@ AccountReconcilor::ScopedSyncedDataDeletion::~ScopedSyncedDataDeletion() {
AccountReconcilor::AccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate)
: delegate_(std::move(delegate)),
identity_manager_(identity_manager),
client_(client),
- cookie_manager_service_(cookie_manager_service),
registered_with_identity_manager_(false),
- registered_with_cookie_manager_service_(false),
registered_with_content_settings_(false),
is_reconcile_started_(false),
first_execution_(true),
@@ -216,13 +214,22 @@ AccountReconcilor::~AccountReconcilor() {
VLOG(1) << "AccountReconcilor::~AccountReconcilor";
// Make sure shutdown was called first.
DCHECK(!registered_with_identity_manager_);
- DCHECK(!registered_with_cookie_manager_service_);
+}
+
+void AccountReconcilor::RegisterWithAllDependencies() {
+ RegisterWithContentSettings();
+ RegisterWithIdentityManager();
+}
+
+void AccountReconcilor::UnregisterWithAllDependencies() {
+ UnregisterWithIdentityManager();
+ UnregisterWithContentSettings();
}
void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) {
VLOG(1) << "AccountReconcilor::Initialize";
if (delegate_->IsReconcileEnabled()) {
- EnableReconcile();
+ RegisterWithAllDependencies();
// Start a reconcile if the tokens are already loaded.
if (start_reconcile_if_tokens_available && IsIdentityManagerReady())
@@ -237,17 +244,17 @@ void AccountReconcilor::SetIsWKHTTPSystemCookieStoreEnabled(bool is_enabled) {
#endif // defined(OS_IOS)
void AccountReconcilor::EnableReconcile() {
- DCHECK(delegate_->IsReconcileEnabled());
- RegisterWithCookieManagerService();
- RegisterWithContentSettings();
- RegisterWithIdentityManager();
+ RegisterWithAllDependencies();
+#if !defined(OS_IOS)
+ // TODO(droger): Investigate why this breaks tests on iOS.
+ if (IsIdentityManagerReady())
+ StartReconcile();
+#endif // !defined(OS_IOS)
}
void AccountReconcilor::DisableReconcile(bool logout_all_accounts) {
AbortReconcile();
- UnregisterWithCookieManagerService();
- UnregisterWithIdentityManager();
- UnregisterWithContentSettings();
+ UnregisterWithAllDependencies();
if (logout_all_accounts)
PerformLogoutAllAccountsAction();
@@ -301,27 +308,6 @@ void AccountReconcilor::UnregisterWithIdentityManager() {
registered_with_identity_manager_ = false;
}
-void AccountReconcilor::RegisterWithCookieManagerService() {
- VLOG(1) << "AccountReconcilor::RegisterWithCookieManagerService";
- // During re-auth, the reconcilor will get a callback about successful signin
- // even when the profile is already connected. Avoid re-registering
- // with the helper since this will DCHECK.
- if (registered_with_cookie_manager_service_)
- return;
-
- cookie_manager_service_->AddObserver(this);
- registered_with_cookie_manager_service_ = true;
-}
-
-void AccountReconcilor::UnregisterWithCookieManagerService() {
- VLOG(1) << "AccountReconcilor::UnregisterWithCookieManagerService";
- if (!registered_with_cookie_manager_service_)
- return;
-
- cookie_manager_service_->RemoveObserver(this);
- registered_with_cookie_manager_service_ = false;
-}
-
signin_metrics::AccountReconcilorState AccountReconcilor::GetState() {
if (!is_reconcile_started_) {
return (error_during_last_reconcile_.state() !=
@@ -380,7 +366,7 @@ void AccountReconcilor::OnRefreshTokensLoaded() {
}
void AccountReconcilor::OnErrorStateOfRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info,
+ const CoreAccountInfo& account_info,
const GoogleServiceAuthError& error) {
// Gaia cookies may be invalidated server-side and the client does not get any
// notification when this happens.
@@ -390,7 +376,7 @@ void AccountReconcilor::OnErrorStateOfRefreshTokenUpdatedForAccount(
// This should cover well the Mirror and Desktop Identity Consistency cases as
// the cookies are always bound to the refresh tokens in these cases.
if (error != GoogleServiceAuthError::AuthErrorNone())
- cookie_manager_service_->TriggerListAccounts();
+ identity_manager_->GetAccountsCookieMutator()->TriggerCookieJarUpdate();
}
void AccountReconcilor::PerformMergeAction(const std::string& account_id) {
@@ -400,18 +386,29 @@ void AccountReconcilor::PerformMergeAction(const std::string& account_id) {
return;
}
VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id;
- cookie_manager_service_->AddAccountToCookie(account_id,
- delegate_->GetGaiaApiSource());
+ identity_manager_->GetAccountsCookieMutator()->AddAccountToCookie(
+ account_id, delegate_->GetGaiaApiSource(),
+ base::BindOnce(&AccountReconcilor::OnAddAccountToCookieCompleted,
+ weak_factory_.GetWeakPtr()));
}
void AccountReconcilor::PerformSetCookiesAction(
const signin::MultiloginParameters& parameters) {
reconcile_is_noop_ = false;
+ if (!delegate_->IsAccountConsistencyEnforced()) {
+ OnSetAccountsInCookieCompleted(GoogleServiceAuthError::AuthErrorNone());
+ return;
+ }
VLOG(1) << "AccountReconcilor::PerformSetCookiesAction: "
<< base::JoinString(parameters.accounts_to_send, " ");
// TODO (https://crbug.com/890321): pass mode to GaiaCookieManagerService.
- cookie_manager_service_->SetAccountsInCookie(parameters.accounts_to_send,
- delegate_->GetGaiaApiSource());
+ //
+ // Using Unretained is safe here because the CookieManagerService outlives
+ // the AccountReconcilor.
+ identity_manager_->GetAccountsCookieMutator()->SetAccountsInCookie(
+ parameters.accounts_to_send, delegate_->GetGaiaApiSource(),
+ base::BindOnce(&AccountReconcilor::OnSetAccountsInCookieCompleted,
+ base::Unretained(this)));
}
void AccountReconcilor::PerformLogoutAllAccountsAction() {
@@ -419,7 +416,8 @@ void AccountReconcilor::PerformLogoutAllAccountsAction() {
if (!delegate_->IsAccountConsistencyEnforced())
return;
VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction";
- cookie_manager_service_->LogOutAllAccounts(delegate_->GetGaiaApiSource());
+ identity_manager_->GetAccountsCookieMutator()->LogOutAllAccounts(
+ delegate_->GetGaiaApiSource());
}
void AccountReconcilor::StartReconcile() {
@@ -472,11 +470,13 @@ void AccountReconcilor::StartReconcile() {
return;
}
- // Rely on the GCMS to manage calls to and responses from ListAccounts.
- std::vector<gaia::ListedAccount> gaia_accounts;
- if (cookie_manager_service_->ListAccounts(&gaia_accounts, nullptr)) {
- OnGaiaAccountsInCookieUpdated(
- gaia_accounts, std::vector<gaia::ListedAccount>(),
+ // Rely on the IdentityManager to manage calls to and responses from
+ // ListAccounts.
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar =
+ identity_manager_->GetAccountsInCookieJar();
+ if (accounts_in_cookie_jar.accounts_are_fresh) {
+ OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar,
GoogleServiceAuthError(GoogleServiceAuthError::NONE));
}
}
@@ -499,14 +499,26 @@ void AccountReconcilor::FinishReconcileWithMultiloginEndpoint(
DCHECK(is_reconcile_started_);
if (AccountsNeedUpdate(parameters_for_multilogin, gaia_accounts)) {
- // Reconcilor has to do some calls to gaia. is_reconcile_started_ is true
- // and any StartReconcile() calls that are made in the meantime will be
- // aborted until OnSetAccountsInCookieCompleted is called and
- // is_reconcile_started_ is set to false.
- set_accounts_in_progress_ = true;
- PerformSetCookiesAction(parameters_for_multilogin);
- DCHECK(is_reconcile_started_);
+ if (parameters_for_multilogin.mode ==
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER &&
+ parameters_for_multilogin.accounts_to_send.empty()) {
+ // UPDATE mode does not support empty list of accounts, call logout
+ // instead.
+ PerformLogoutAllAccountsAction();
+ gaia_accounts.clear();
+ OnSetAccountsInCookieCompleted(GoogleServiceAuthError::AuthErrorNone());
+ DCHECK(!is_reconcile_started_);
+ } else {
+ // Reconcilor has to do some calls to gaia. is_reconcile_started_ is true
+ // and any StartReconcile() calls that are made in the meantime will be
+ // aborted until OnSetAccountsInCookieCompleted is called and
+ // is_reconcile_started_ is set to false.
+ set_accounts_in_progress_ = true;
+ PerformSetCookiesAction(parameters_for_multilogin);
+ DCHECK(is_reconcile_started_);
+ }
} else {
+ // Nothing to do, accounts already match.
OnSetAccountsInCookieCompleted(GoogleServiceAuthError::AuthErrorNone());
DCHECK(!is_reconcile_started_);
}
@@ -529,11 +541,12 @@ void AccountReconcilor::FinishReconcileWithMultiloginEndpoint(
first_execution_ = false;
}
-void AccountReconcilor::OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error) {
- VLOG(1) << "AccountReconcilor::OnGaiaAccountsInCookieUpdated: "
+void AccountReconcilor::OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+ const GoogleServiceAuthError& error) {
+ const std::vector<gaia::ListedAccount>& accounts(
+ accounts_in_cookie_jar_info.signed_in_accounts);
+ VLOG(1) << "AccountReconcilor::OnAccountsInCookieUpdated: "
<< "CookieJar " << accounts.size() << " accounts, "
<< "Reconcilor's state is " << is_reconcile_started_ << ", "
<< "Error was " << error.ToString();
@@ -586,9 +599,11 @@ void AccountReconcilor::OnGaiaAccountsInCookieUpdated(
signin_metrics::SourceForRefreshTokenOperation::
kAccountReconcilor_GaiaCookiesUpdated);
+ std::vector<std::string> chrome_accounts =
+ LoadValidAccountsFromTokenService();
+
if (delegate_->ShouldAbortReconcileIfPrimaryHasError() &&
- identity_manager_->HasAccountWithRefreshTokenInPersistentErrorState(
- primary_account)) {
+ !base::ContainsValue(chrome_accounts, primary_account)) {
VLOG(1) << "Primary account has error, abort.";
DCHECK(is_reconcile_started_);
AbortReconcile();
@@ -596,16 +611,15 @@ void AccountReconcilor::OnGaiaAccountsInCookieUpdated(
}
if (IsMultiloginEndpointEnabled()) {
- FinishReconcileWithMultiloginEndpoint(primary_account,
- LoadValidAccountsFromTokenService(),
+ FinishReconcileWithMultiloginEndpoint(primary_account, chrome_accounts,
std::move(verified_gaia_accounts));
} else {
- FinishReconcile(primary_account, LoadValidAccountsFromTokenService(),
+ FinishReconcile(primary_account, chrome_accounts,
std::move(verified_gaia_accounts));
}
}
-void AccountReconcilor::OnGaiaCookieDeletedByUserAction() {
+void AccountReconcilor::OnAccountsCookieDeletedByUserAction() {
if (!delegate_->ShouldRevokeTokensOnCookieDeleted())
return;
@@ -660,7 +674,7 @@ std::vector<std::string> AccountReconcilor::LoadValidAccountsFromTokenService()
void AccountReconcilor::OnReceivedManageAccountsResponse(
signin::GAIAServiceType service_type) {
if (service_type == signin::GAIA_SERVICE_TYPE_ADDSESSION) {
- cookie_manager_service_->TriggerListAccounts();
+ identity_manager_->GetAccountsCookieMutator()->TriggerCookieJarUpdate();
}
}
@@ -728,16 +742,15 @@ void AccountReconcilor::FinishReconcile(
// For each account known to chrome, PerformMergeAction() if the account is
// not already in the cookie jar or its state is invalid, or signal merge
// completed otherwise. Make a copy of |add_to_cookie_| since calls to
- // SignalComplete() will change the array.
+ // OnAddAccountToCookieCompleted() will change the array.
std::vector<std::string> add_to_cookie_copy = add_to_cookie_;
int added_to_cookie = 0;
for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) {
if (gaia_accounts.end() !=
std::find_if(gaia_accounts.begin(), gaia_accounts.end(),
AccountEqualToFunc(AccountForId(add_to_cookie_copy[i])))) {
- cookie_manager_service_->SignalComplete(
- add_to_cookie_copy[i],
- GoogleServiceAuthError::AuthErrorNone());
+ OnAddAccountToCookieCompleted(add_to_cookie_copy[i],
+ GoogleServiceAuthError::AuthErrorNone());
} else {
PerformMergeAction(add_to_cookie_copy[i]);
if (original_gaia_accounts.end() ==
@@ -950,5 +963,10 @@ bool AccountReconcilor::IsMultiloginEndpointEnabled() const {
if (!is_wkhttp_system_cookie_store_enabled_)
return false;
#endif // defined(OS_IOS)
+
+#if defined(OS_ANDROID)
+ if (base::FeatureList::IsEnabled(signin::kMiceFeature))
+ return true; // Mice is only implemented with multilogin.
+#endif
return base::FeatureList::IsEnabled(kUseMultiloginEndpoint);
}
diff --git a/chromium/components/signin/core/browser/account_reconcilor.h b/chromium/components/signin/core/browser/account_reconcilor.h
index 6cf7cbd91ce..dc29c94663f 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.h
+++ b/chromium/components/signin/core/browser/account_reconcilor.h
@@ -23,7 +23,6 @@
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "components/signin/core/browser/signin_metrics.h"
@@ -41,7 +40,6 @@ class SigninClient;
class AccountReconcilor : public KeyedService,
public content_settings::Observer,
- public GaiaCookieManagerService::Observer,
public identity::IdentityManager::Observer {
public:
// When an instance of this class exists, the account reconcilor is suspended.
@@ -96,7 +94,6 @@ class AccountReconcilor : public KeyedService,
AccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate);
~AccountReconcilor() override;
@@ -138,7 +135,7 @@ class AccountReconcilor : public KeyedService,
friend class AccountReconcilorTest;
friend class DiceBrowserTestBase;
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorEndpointParamTest,
- SigninManagerRegistration);
+ IdentityManagerRegistration);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorEndpointParamTest, Reauth);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorEndpointParamTest,
ProfileAlreadyConnected);
@@ -226,6 +223,7 @@ class AccountReconcilor : public KeyedService,
DelegateTimeoutIsNotCalled);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
DelegateTimeoutIsNotCalledIfTimeoutIsNotReached);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, MultiloginLogout);
void set_timer_for_testing(std::unique_ptr<base::OneShotTimer> timer);
@@ -234,6 +232,8 @@ class AccountReconcilor : public KeyedService,
}
// Register and unregister with dependent services.
+ void RegisterWithAllDependencies();
+ void UnregisterWithAllDependencies();
void RegisterWithIdentityManager();
void UnregisterWithIdentityManager();
void RegisterWithCookieManagerService();
@@ -273,30 +273,27 @@ class AccountReconcilor : public KeyedService,
ContentSettingsType content_type,
const std::string& resource_identifier) override;
- // Overridden from GaiaGookieManagerService::Observer.
- void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) override;
- void OnSetAccountsInCookieCompleted(
- const GoogleServiceAuthError& error) override;
- void OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error) override;
- void OnGaiaCookieDeletedByUserAction() override;
// Overridden from identity::IdentityManager::Observer.
void OnEndBatchOfRefreshTokenStateChanges() override;
void OnRefreshTokensLoaded() override;
void OnErrorStateOfRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info,
+ const CoreAccountInfo& account_info,
+ const GoogleServiceAuthError& error) override;
+ void OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override;
+ void OnAccountsCookieDeletedByUserAction() override;
void FinishReconcileWithMultiloginEndpoint(
const std::string& primary_account,
const std::vector<std::string>& chrome_accounts,
std::vector<gaia::ListedAccount>&& gaia_accounts);
+ void OnAddAccountToCookieCompleted(const std::string& account_id,
+ const GoogleServiceAuthError& error);
+ void OnSetAccountsInCookieCompleted(const GoogleServiceAuthError& error);
+
// Lock related methods.
void IncrementLockCount();
void DecrementLockCount();
@@ -317,11 +314,7 @@ class AccountReconcilor : public KeyedService,
// The SigninClient associated with this reconcilor.
SigninClient* client_;
- // The GaiaCookieManagerService associated with this reconcilor.
- GaiaCookieManagerService* cookie_manager_service_;
-
bool registered_with_identity_manager_;
- bool registered_with_cookie_manager_service_;
bool registered_with_content_settings_;
// True while the reconcilor is busy checking or managing the accounts in
diff --git a/chromium/components/signin/core/browser/account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
index c1eb4e2a0f6..0f642b6d1bc 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -100,10 +100,14 @@ AccountReconcilorDelegate::ReorderChromeAccountsForReconcile(
if (first_account_it == ordered_accounts.end()) {
// The first account was not already in the cookies, add it in the first
// empty spot, or at the end if there is no available spot.
- first_account_it = ordered_accounts.insert(
- std::find(ordered_accounts.begin(), ordered_accounts.end(),
- std::string()),
- first_account);
+ first_account_it = std::find(ordered_accounts.begin(),
+ ordered_accounts.end(), std::string());
+ if (first_account_it == ordered_accounts.end()) {
+ first_account_it =
+ ordered_accounts.insert(first_account_it, first_account);
+ } else {
+ *first_account_it = first_account;
+ }
chrome_accounts_set.erase(first_account);
}
std::iter_swap(ordered_accounts.begin(), first_account_it);
diff --git a/chromium/components/signin/core/browser/account_reconcilor_delegate_unittest.cc b/chromium/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
index 84c1dedd0b9..c8bdedf51de 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_delegate_unittest.cc
@@ -45,6 +45,8 @@ static const AccountReconcilorDelegateTestParam kReorderParams[] = {
// Cookie was lost.
{ "A", "", 'A', "A" },
{ "ABCD", "", 'A', "ABCD" },
+ // B kept in place.
+ { "ADB", "CB", 'A', "ABD" },
// ACEG kept in place.
{ "ABCDEFGH", "ACEG", 'A', "ACEGBDFH" },
// C kept in place, but not B.
@@ -141,8 +143,8 @@ TEST_P(AccountReconcilorDelegateTest, ReorderChromeAccountsForReconcile) {
GaiaAccountsFromString(order_as_string)));
}
-INSTANTIATE_TEST_CASE_P(,
- AccountReconcilorDelegateTest,
- ::testing::ValuesIn(kReorderParams));
+INSTANTIATE_TEST_SUITE_P(,
+ AccountReconcilorDelegateTest,
+ ::testing::ValuesIn(kReorderParams));
} // namespace signin
diff --git a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
index 0ac578b3a55..ea32943df60 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -19,17 +19,13 @@
#include "base/time/time.h"
#include "base/timer/mock_timer.h"
#include "build/build_config.h"
+#include "components/image_fetcher/core/fake_image_decoder.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/signin/core/browser/account_consistency_method.h"
#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_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/list_accounts_test_utils.h"
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_buildflags.h"
-#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/signin/core/browser/signin_pref_names.h"
#include "components/signin/core/browser/test_signin_client.h"
@@ -51,28 +47,6 @@
namespace {
-#if defined(OS_CHROMEOS)
-using FakeSigninManagerForTesting = FakeSigninManagerBase;
-#else
-using FakeSigninManagerForTesting = FakeSigninManager;
-#endif
-
-// TestSigninClient keeping track of the dice migration.
-class DiceTestSigninClient : public TestSigninClient {
- public:
- explicit DiceTestSigninClient(PrefService* prefs) : TestSigninClient(prefs) {}
-
- void SetReadyForDiceMigration(bool ready) override {
- is_ready_for_dice_migration_ = ready;
- }
-
- bool is_ready_for_dice_migration() { return is_ready_for_dice_migration_; }
-
- private:
- bool is_ready_for_dice_migration_ = false;
- DISALLOW_COPY_AND_ASSIGN(DiceTestSigninClient);
-};
-
// An AccountReconcilorDelegate that records all calls (Spy pattern).
class SpyReconcilorDelegate : public signin::AccountReconcilorDelegate {
public:
@@ -122,12 +96,10 @@ class DummyAccountReconcilorWithDelegate : public AccountReconcilor {
DummyAccountReconcilorWithDelegate(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency)
: AccountReconcilor(
identity_manager,
client,
- cookie_manager_service,
CreateAccountReconcilorDelegate(client,
identity_manager,
account_consistency)) {
@@ -142,12 +114,10 @@ class DummyAccountReconcilorWithDelegate : public AccountReconcilor {
DummyAccountReconcilorWithDelegate(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountReconcilorDelegate* delegate)
: AccountReconcilor(
identity_manager,
client,
- cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate>(delegate)) {
#if defined(OS_IOS)
SetIsWKHTTPSystemCookieStoreEnabled(true);
@@ -187,13 +157,11 @@ class MockAccountReconcilor
explicit MockAccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency);
explicit MockAccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate);
MOCK_METHOD1(PerformMergeAction, void(const std::string& account_id));
@@ -205,23 +173,19 @@ class MockAccountReconcilor
MockAccountReconcilor::MockAccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency)
: testing::StrictMock<DummyAccountReconcilorWithDelegate>(
identity_manager,
client,
- cookie_manager_service,
account_consistency) {}
MockAccountReconcilor::MockAccountReconcilor(
identity::IdentityManager* identity_manager,
SigninClient* client,
- GaiaCookieManagerService* cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate)
: testing::StrictMock<DummyAccountReconcilorWithDelegate>(
identity_manager,
client,
- cookie_manager_service,
delegate.release()) {}
struct Cookie {
@@ -234,7 +198,7 @@ struct Cookie {
};
// Converts CookieParams to ListedAccounts.
-gaia::ListedAccount ListedAccounfFromCookieParams(
+gaia::ListedAccount ListedAccountFromCookieParams(
const signin::CookieParams& params,
const std::string& account_id) {
gaia::ListedAccount listed_account;
@@ -251,18 +215,14 @@ gaia::ListedAccount ListedAccounfFromCookieParams(
} // namespace
class AccountReconcilorTest : public ::testing::Test {
- public:
+ protected:
AccountReconcilorTest();
~AccountReconcilorTest() override;
identity::IdentityTestEnvironment* identity_test_env() {
return &identity_test_env_;
}
- DiceTestSigninClient* test_signin_client() { return &test_signin_client_; }
- AccountTrackerService* account_tracker() { return &account_tracker_; }
- FakeGaiaCookieManagerService* cookie_manager_service() {
- return &cookie_manager_service_;
- }
+ TestSigninClient* test_signin_client() { return &test_signin_client_; }
base::HistogramTester* histogram_tester() { return &histogram_tester_; }
MockAccountReconcilor* GetMockReconcilor();
@@ -276,17 +236,16 @@ class AccountReconcilorTest : public ::testing::Test {
std::string SeedAccountInfo(const std::string& gaia_id,
const std::string& username);
- void SimulateAddAccountToCookieCompleted(
- GaiaCookieManagerService::Observer* observer,
- const std::string& account_id,
- const GoogleServiceAuthError& error);
+ void SimulateAddAccountToCookieCompleted(AccountReconcilor* reconcilor,
+ const std::string& account_id,
+ const GoogleServiceAuthError& error);
void SimulateCookieContentSettingsChanged(
content_settings::Observer* observer,
const ContentSettingsPattern& primary_pattern);
void SimulateSetAccountsInCookieCompleted(
- GaiaCookieManagerService::Observer* observer,
+ AccountReconcilor* reconcilor,
const GoogleServiceAuthError& error);
void SetAccountConsistency(signin::AccountConsistencyMethod method);
@@ -295,16 +254,13 @@ class AccountReconcilorTest : public ::testing::Test {
void DeleteReconcilor() { mock_reconcilor_.reset(); }
+ network::TestURLLoaderFactory test_url_loader_factory_;
+
private:
base::test::ScopedTaskEnvironment task_environment_;
signin::AccountConsistencyMethod account_consistency_;
sync_preferences::TestingPrefServiceSyncable pref_service_;
- DiceTestSigninClient test_signin_client_;
- FakeProfileOAuth2TokenService token_service_;
- AccountTrackerService account_tracker_;
- network::TestURLLoaderFactory test_url_loader_factory_;
- FakeGaiaCookieManagerService cookie_manager_service_;
- FakeSigninManagerForTesting signin_manager_;
+ TestSigninClient test_signin_client_;
identity::IdentityTestEnvironment identity_test_env_;
std::unique_ptr<MockAccountReconcilor> mock_reconcilor_;
base::HistogramTester histogram_tester_;
@@ -341,43 +297,25 @@ class AccountReconcilorMethodParamTest
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorMethodParamTest);
};
-INSTANTIATE_TEST_CASE_P(Dice_Mirror,
- AccountReconcilorMethodParamTest,
- ::testing::Values(
+INSTANTIATE_TEST_SUITE_P(Dice_Mirror,
+ AccountReconcilorMethodParamTest,
+ ::testing::Values(
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
- signin::AccountConsistencyMethod::kDice,
+ signin::AccountConsistencyMethod::kDice,
#endif
- signin::AccountConsistencyMethod::kMirror));
+ signin::AccountConsistencyMethod::kMirror));
AccountReconcilorTest::AccountReconcilorTest()
: account_consistency_(signin::AccountConsistencyMethod::kDisabled),
test_signin_client_(&pref_service_),
- token_service_(&pref_service_),
- cookie_manager_service_(&token_service_,
- &test_signin_client_,
- &test_url_loader_factory_),
-#if defined(OS_CHROMEOS)
- signin_manager_(&test_signin_client_, &token_service_, &account_tracker_),
-#else
- signin_manager_(&test_signin_client_,
- &token_service_,
- &account_tracker_,
- &cookie_manager_service_),
-#endif
- identity_test_env_(&account_tracker_,
- &token_service_,
- &signin_manager_,
- &cookie_manager_service_) {
- AccountTrackerService::RegisterPrefs(pref_service_.registry());
- ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry());
- SigninManagerBase::RegisterProfilePrefs(pref_service_.registry());
- SigninManagerBase::RegisterPrefs(pref_service_.registry());
+ identity_test_env_(&test_url_loader_factory_,
+ &pref_service_,
+ account_consistency_,
+ &test_signin_client_) {
pref_service_.registry()->RegisterBooleanPref(
prefs::kTokenServiceDiceCompatible, false);
- account_tracker_.Initialize(&pref_service_, base::FilePath());
- cookie_manager_service_.SetListAccountsResponseHttpNotFound();
- signin_manager_.Initialize(nullptr);
+ signin::SetListAccountsResponseHttpNotFound(&test_url_loader_factory_);
// The reconcilor should not be built before the test can set the account
// consistency method.
@@ -388,7 +326,7 @@ MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor() {
if (!mock_reconcilor_) {
mock_reconcilor_ = std::make_unique<MockAccountReconcilor>(
identity_test_env_.identity_manager(), &test_signin_client_,
- &cookie_manager_service_, account_consistency_);
+ account_consistency_);
}
return mock_reconcilor_.get();
@@ -398,7 +336,7 @@ MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor(
std::unique_ptr<signin::AccountReconcilorDelegate> delegate) {
mock_reconcilor_ = std::make_unique<MockAccountReconcilor>(
identity_test_env_.identity_manager(), &test_signin_client_,
- &cookie_manager_service_, std::move(delegate));
+ std::move(delegate));
return mock_reconcilor_.get();
}
@@ -406,11 +344,7 @@ MockAccountReconcilor* AccountReconcilorTest::GetMockReconcilor(
AccountReconcilorTest::~AccountReconcilorTest() {
if (mock_reconcilor_)
mock_reconcilor_->Shutdown();
- signin_manager_.Shutdown();
- cookie_manager_service_.Shutdown();
- account_tracker_.Shutdown();
test_signin_client_.Shutdown();
- token_service_.Shutdown();
}
AccountInfo AccountReconcilorTest::ConnectProfileToAccount(
@@ -423,26 +357,31 @@ AccountInfo AccountReconcilorTest::ConnectProfileToAccount(
std::string AccountReconcilorTest::PickAccountIdForAccount(
const std::string& gaia_id,
const std::string& username) {
- return account_tracker()->PickAccountIdForAccount(gaia_id, username);
+ return identity_test_env()->identity_manager()->LegacyPickAccountIdForAccount(
+ gaia_id, username);
}
std::string AccountReconcilorTest::SeedAccountInfo(
const std::string& gaia_id,
const std::string& username) {
- return account_tracker()->SeedAccountInfo(gaia_id, username);
+ AccountInfo account_info;
+ account_info.gaia = gaia_id;
+ account_info.email = username;
+ return identity_test_env()->identity_manager()->LegacySeedAccountInfo(
+ account_info);
}
void AccountReconcilorTest::SimulateAddAccountToCookieCompleted(
- GaiaCookieManagerService::Observer* observer,
+ AccountReconcilor* reconcilor,
const std::string& account_id,
const GoogleServiceAuthError& error) {
- observer->OnAddAccountToCookieCompleted(account_id, error);
+ reconcilor->OnAddAccountToCookieCompleted(account_id, error);
}
void AccountReconcilorTest::SimulateSetAccountsInCookieCompleted(
- GaiaCookieManagerService::Observer* observer,
+ AccountReconcilor* reconcilor,
const GoogleServiceAuthError& error) {
- observer->OnSetAccountsInCookieCompleted(error);
+ reconcilor->OnSetAccountsInCookieCompleted(error);
}
void AccountReconcilorTest::SimulateCookieContentSettingsChanged(
@@ -650,8 +589,9 @@ class AccountReconcilorTestTable
cookie.is_valid, false /* signed_out */,
true /* verified */});
}
- cookie_manager_service()->SetListAccountsResponseWithParams(cookie_params);
- cookie_manager_service()->set_list_accounts_stale_for_testing(true);
+ signin::SetListAccountsResponseWithParams(cookie_params,
+ &test_url_loader_factory_);
+ identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
}
std::string GaiaIdForAccountKey(char account_key) {
@@ -663,11 +603,7 @@ class AccountReconcilorTestTable
#if !defined(OS_CHROMEOS)
-// This method requires the use of the |TestSigninClient| to be created from the
-// |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
-// method with an empty implementation. On MacOS, the normal implementation
-// causes the try_bots to time out.
-TEST_P(AccountReconcilorMirrorEndpointParamTest, SigninManagerRegistration) {
+TEST_P(AccountReconcilorMirrorEndpointParamTest, IdentityManagerRegistration) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
ASSERT_FALSE(reconcilor->IsRegisteredWithIdentityManager());
@@ -681,10 +617,6 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, SigninManagerRegistration) {
ASSERT_FALSE(reconcilor->IsRegisteredWithIdentityManager());
}
-// This method requires the use of the |TestSigninClient| to be created from the
-// |ChromeSigninClientFactory| because it overrides the |GoogleSigninSucceeded|
-// method with an empty implementation. On MacOS, the normal implementation
-// causes the try_bots to time out.
TEST_P(AccountReconcilorMirrorEndpointParamTest, Reauth) {
const std::string email = "user@gmail.com";
AccountInfo account_info = ConnectProfileToAccount(email);
@@ -752,7 +684,8 @@ const std::vector<AccountReconcilorTestTableParam> kDiceParams = {
// The syntax is:
// - Tokens:
// A, B, C: Accounts for which we have a token in Chrome.
- // *: The next account is the main Chrome account (i.e. in SigninManager).
+ // *: The next account is the main Chrome account (i.e. in
+ // IdentityManager).
// x: The next account has a token error.
// - API calls:
// U: Multilogin with mode UPDATE
@@ -856,6 +789,7 @@ const std::vector<AccountReconcilorTestTableParam> kDiceParams = {
{ "*xA", "xA", IsFirstReconcile::kBoth, "", "*xA", "xA", "", "*xA", "xA"},
{ "*xA", "xB", IsFirstReconcile::kBoth, "", "*xA", "xB", "", "*xA", "xB"},
{ "*xAB", "xAB", IsFirstReconcile::kBoth, "", "*xAB", "xAB", "", "*xAB", "xAB"},
+ { "*AxB", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA"},
// Appending a new cookie after the invalid one.
{ "B", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB"},
{ "xAB", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB"},
@@ -891,7 +825,7 @@ const std::vector<AccountReconcilorTestTableParam> kDiceParams = {
{ "", "xAxB", IsFirstReconcile::kNotFirst, "", "", "xAxB", "", "", "xAxB"},
{ "", "xBxA", IsFirstReconcile::kNotFirst, "", "", "xBxA", "", "", "xBxA"},
{ "*A", "A", IsFirstReconcile::kNotFirst, "", "*A", "A", "", "*A", "A"},
- { "*A", "xBA", IsFirstReconcile::kNotFirst, "XA", "*A", "A", "", "*A", "xBA"},
+ { "*A", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA"},
{ "*A", "AxB", IsFirstReconcile::kNotFirst, "", "*A", "AxB", "", "*A", "AxB"},
{ "A", "A", IsFirstReconcile::kNotFirst, "", "A", "A", "", "A", "A"},
{ "A", "xBA", IsFirstReconcile::kNotFirst, "", "A", "xBA", "", "A", "xBA"},
@@ -934,8 +868,8 @@ TEST_P(AccountReconcilorTestTable, TableRowTest) {
if (token.is_authenticated) {
account_id = ConnectProfileToAccount(token.email).account_id;
} else {
- account_id = SeedAccountInfo(token.gaia_id, token.email);
- identity_test_env()->SetRefreshTokenForAccount(account_id);
+ account_id =
+ identity_test_env()->MakeAccountAvailable(token.email).account_id;
}
if (token.has_error) {
identity::UpdatePersistentErrorOfRefreshTokenForAccount(
@@ -951,7 +885,7 @@ TEST_P(AccountReconcilorTestTable, TableRowTest) {
ConfigureCookieManagerService(cookies);
// Call list accounts now so that the next call completes synchronously.
- cookie_manager_service()->ListAccounts(nullptr, nullptr);
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
base::RunLoop().RunUntilIdle();
// Setup expectations.
@@ -1018,7 +952,7 @@ TEST_P(AccountReconcilorTestTable, TableRowTest) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
DiceTable,
AccountReconcilorTestTable,
::testing::ValuesIn(GenerateTestCasesFromParams(kDiceParams)));
@@ -1053,8 +987,8 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
if (token.is_authenticated) {
account_id = ConnectProfileToAccount(token.email).account_id;
} else {
- account_id = SeedAccountInfo(token.gaia_id, token.email);
- identity_test_env()->SetRefreshTokenForAccount(account_id);
+ account_id =
+ identity_test_env()->MakeAccountAvailable(token.email).account_id;
}
if (token.has_error) {
identity::UpdatePersistentErrorOfRefreshTokenForAccount(
@@ -1071,7 +1005,7 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
std::vector<Cookie> cookies_after_reconcile = cookies;
// Call list accounts now so that the next call completes synchronously.
- cookie_manager_service()->ListAccounts(nullptr, nullptr);
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
base::RunLoop().RunUntilIdle();
// Setup expectations.
@@ -1122,7 +1056,7 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
DiceTableMultilogin,
AccountReconcilorTestDiceMultilogin,
::testing::ValuesIn(GenerateTestCasesFromParams(kDiceParams)));
@@ -1155,7 +1089,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceTokenServiceRegistration) {
ASSERT_TRUE(reconcilor->IsRegisteredWithIdentityManager());
// Reconcilor should not logout all accounts from the cookies when
- // SigninManager signs out.
+ // the primary account is cleared in IdentityManager.
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(::testing::_))
.Times(0);
@@ -1169,7 +1103,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileWithoutSignin) {
// Add a token in Chrome but do not sign in.
const std::string account_id =
identity_test_env()->MakeAccountAvailable("user@gmail.com").account_id;
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
@@ -1201,7 +1135,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileWithoutSignin) {
// cookie.
TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileNoop) {
// No Chrome account and no cookie.
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
@@ -1235,8 +1169,9 @@ TEST_P(AccountReconcilorDiceEndpointParamTest,
// Add accounts 2 and 3 to the Gaia cookie.
const std::string account_id_3 = SeedAccountInfo("9999", "foo@gmail.com");
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
- account_info_2.email, account_info_2.gaia, "foo@gmail.com", "9999");
+ signin::SetListAccountsResponseTwoAccounts(
+ account_info_2.email, account_info_2.gaia, "foo@gmail.com", "9999",
+ &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
testing::InSequence mock_sequence;
@@ -1281,9 +1216,9 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
AccountInfo account_info_2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com");
const std::string account_id_2 = account_info_2.account_id;
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ signin::SetListAccountsResponseTwoAccounts(
account_info_2.email, account_info_2.gaia, account_info_1.email,
- account_info_1.gaia);
+ account_info_1.gaia, &test_url_loader_factory_);
auto* identity_manager = identity_test_env()->identity_manager();
std::vector<AccountInfo> accounts =
@@ -1310,8 +1245,8 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
}
// Delete the cookies.
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
- cookie_manager_service()->set_list_accounts_stale_for_testing(true);
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
+ identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
if (!IsMultiloginEnabled()) {
// Reconcile again and check that account_id_2 is added first.
@@ -1353,9 +1288,10 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
// Checks that the reconcilor does not log out unverified accounts.
TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountNoop) {
// Add a unverified account to the Gaia cookie.
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
+ signin::SetListAccountsResponseOneAccountWithParams(
{"user@gmail.com", "12345", true /* valid */, false /* signed_out */,
- false /* verified */});
+ false /* verified */},
+ &test_url_loader_factory_);
// Check that nothing happens.
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
@@ -1375,9 +1311,10 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountNoop) {
// a new account to the Gaia cookie.
TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountMerge) {
// Add a unverified account to the Gaia cookie.
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
+ signin::SetListAccountsResponseOneAccountWithParams(
{"user@gmail.com", "12345", true /* valid */, false /* signed_out */,
- false /* verified */});
+ false /* verified */},
+ &test_url_loader_factory_);
// Add a token to Chrome.
const std::string chrome_account_id =
@@ -1424,8 +1361,8 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceMigrationAfterNoop) {
// Chrome account is consistent with the cookie.
AccountInfo account_info =
identity_test_env()->MakeAccountAvailable("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
// Dice is not enabled by default.
EXPECT_FALSE(reconcilor->delegate_->IsAccountConsistencyEnforced());
@@ -1454,8 +1391,8 @@ TEST_P(AccountReconcilorDiceEndpointParamTest,
// Chrome account is consistent with the cookie.
AccountInfo account_info =
identity_test_env()->MakeAccountAvailable("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
// Dice is not enabled by default.
EXPECT_FALSE(reconcilor->delegate_->IsAccountConsistencyEnforced());
@@ -1484,7 +1421,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceNoMigrationAfterReconcile) {
// Add a token in Chrome.
const std::string account_id =
ConnectProfileToAccount("user@gmail.com").account_id;
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
// Dice is not enabled by default.
@@ -1526,7 +1463,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, MigrationClearSecondaryTokens) {
ConnectProfileToAccount("user@gmail.com").account_id;
const std::string account_id_2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com").account_id;
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
auto* identity_manager = identity_test_env()->identity_manager();
ASSERT_TRUE(identity_manager->HasAccountWithRefreshToken(account_id_1));
@@ -1576,7 +1513,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, MigrationClearAllTokens) {
identity_test_env()->MakeAccountAvailable("user@gmail.com").account_id;
const std::string account_id_2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com").account_id;
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
auto* identity_manager = identity_test_env()->identity_manager();
ASSERT_TRUE(identity_manager->HasAccountWithRefreshToken(account_id_1));
@@ -1598,9 +1535,9 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, MigrationClearAllTokens) {
EXPECT_TRUE(test_signin_client()->is_ready_for_dice_migration());
}
-INSTANTIATE_TEST_CASE_P(TestDiceEndpoint,
- AccountReconcilorDiceEndpointParamTest,
- ::testing::ValuesIn({false, true}));
+INSTANTIATE_TEST_SUITE_P(TestDiceEndpoint,
+ AccountReconcilorDiceEndpointParamTest,
+ ::testing::ValuesIn({false, true}));
TEST_F(AccountReconcilorTest, DiceDeleteCookie) {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
@@ -1629,7 +1566,7 @@ TEST_F(AccountReconcilorTest, DiceDeleteCookie) {
{
std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion =
reconcilor->GetScopedSyncDataDeletion();
- reconcilor->OnGaiaCookieDeletedByUserAction();
+ reconcilor->OnAccountsCookieDeletedByUserAction();
EXPECT_TRUE(
identity_manager->HasAccountWithRefreshToken(primary_account_id));
EXPECT_FALSE(
@@ -1640,7 +1577,7 @@ TEST_F(AccountReconcilorTest, DiceDeleteCookie) {
}
identity_test_env()->SetRefreshTokenForAccount(secondary_account_id);
- reconcilor->OnGaiaCookieDeletedByUserAction();
+ reconcilor->OnAccountsCookieDeletedByUserAction();
// Without scoped deletion, the primary token is also invalidated.
EXPECT_TRUE(identity_manager->HasAccountWithRefreshToken(primary_account_id));
@@ -1668,7 +1605,7 @@ TEST_F(AccountReconcilorTest, DiceDeleteCookie) {
{
std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion =
reconcilor->GetScopedSyncDataDeletion();
- reconcilor->OnGaiaCookieDeletedByUserAction();
+ reconcilor->OnAccountsCookieDeletedByUserAction();
EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_REJECTED_BY_CLIENT,
identity_manager
@@ -1685,7 +1622,8 @@ const std::vector<AccountReconcilorTestTableParam> kMirrorParams = {
// The syntax is:
// - Tokens:
// A, B, C: Accounts for which we have a token in Chrome.
- // *: The next account is the main Chrome account (i.e. in SigninManager).
+ // *: The next account is the main Chrome account (i.e. in
+ // IdentityManager).
// x: The next account has a token error.
// - Cookies:
// A, B, C: Accounts in the Gaia cookie (returned by ListAccounts).
@@ -1751,8 +1689,8 @@ TEST_P(AccountReconcilorTestMirrorMultilogin, TableRowTest) {
if (token.is_authenticated) {
account_id = ConnectProfileToAccount(token.email).account_id;
} else {
- account_id = SeedAccountInfo(token.gaia_id, token.email);
- identity_test_env()->SetRefreshTokenForAccount(account_id);
+ account_id =
+ identity_test_env()->MakeAccountAvailable(token.email).account_id;
}
if (token.has_error) {
identity::UpdatePersistentErrorOfRefreshTokenForAccount(
@@ -1768,7 +1706,7 @@ TEST_P(AccountReconcilorTestMirrorMultilogin, TableRowTest) {
ConfigureCookieManagerService(cookies);
// Call list accounts now so that the next call completes synchronously.
- cookie_manager_service()->ListAccounts(nullptr, nullptr);
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
base::RunLoop().RunUntilIdle();
// Setup expectations.
@@ -1823,7 +1761,7 @@ TEST_P(AccountReconcilorTestMirrorMultilogin, TableRowTest) {
base::RunLoop().RunUntilIdle();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
DiceTableMirrorMultilogin,
AccountReconcilorTestMirrorMultilogin,
::testing::ValuesIn(GenerateTestCasesFromParams(kMirrorParams)));
@@ -1833,7 +1771,7 @@ INSTANTIATE_TEST_CASE_P(
TEST_P(AccountReconcilorMirrorEndpointParamTest, TokensNotLoaded) {
const std::string account_id =
ConnectProfileToAccount("user@gmail.com").account_id;
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
identity_test_env()->ResetToAccountsNotYetLoadedFromDiskState();
AccountReconcilor* reconcilor = GetMockReconcilor();
@@ -1844,7 +1782,7 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, TokensNotLoaded) {
// can start as long as the token service is not empty.
ASSERT_FALSE(reconcilor->is_reconcile_started_);
// When tokens are loaded, reconcile starts automatically.
- identity_test_env()->identity_manager()->LegacyLoadCredentials(account_id);
+ identity_test_env()->ReloadAccountsFromDisk();
#endif
if (!IsMultiloginEnabled()) {
@@ -1872,9 +1810,10 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, TokensNotLoaded) {
TEST_P(AccountReconcilorMirrorEndpointParamTest, GetAccountsFromCookieSuccess) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
const std::string account_id = account_info.account_id;
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
+ signin::SetListAccountsResponseOneAccountWithParams(
{account_info.email, account_info.gaia, false /* valid */,
- false /* signed_out */, true /* verified */});
+ false /* signed_out */, true /* verified */},
+ &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
@@ -1895,18 +1834,17 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, GetAccountsFromCookieSuccess) {
base::RunLoop().RunUntilIdle();
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
- std::vector<gaia::ListedAccount> accounts;
- std::vector<gaia::ListedAccount> signed_out_accounts;
- ASSERT_TRUE(
- cookie_manager_service()->ListAccounts(&accounts, &signed_out_accounts));
- ASSERT_EQ(1u, accounts.size());
- ASSERT_EQ(account_id, accounts[0].id);
- ASSERT_EQ(0u, signed_out_accounts.size());
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info =
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+ ASSERT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
+ ASSERT_EQ(1u, accounts_in_cookie_jar_info.signed_in_accounts.size());
+ ASSERT_EQ(account_id, accounts_in_cookie_jar_info.signed_in_accounts[0].id);
+ ASSERT_EQ(0u, accounts_in_cookie_jar_info.signed_out_accounts.size());
}
TEST_P(AccountReconcilorMirrorEndpointParamTest, GetAccountsFromCookieFailure) {
ConnectProfileToAccount("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseWebLoginRequired();
+ signin::SetListAccountsResponseWebLoginRequired(&test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -1916,12 +1854,11 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, GetAccountsFromCookieFailure) {
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
base::RunLoop().RunUntilIdle();
- std::vector<gaia::ListedAccount> accounts;
- std::vector<gaia::ListedAccount> signed_out_accounts;
- ASSERT_FALSE(
- cookie_manager_service()->ListAccounts(&accounts, &signed_out_accounts));
- ASSERT_EQ(0u, accounts.size());
- ASSERT_EQ(0u, signed_out_accounts.size());
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info =
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+ ASSERT_FALSE(accounts_in_cookie_jar_info.accounts_are_fresh);
+ ASSERT_EQ(0u, accounts_in_cookie_jar_info.signed_in_accounts.size());
+ ASSERT_EQ(0u, accounts_in_cookie_jar_info.signed_out_accounts.size());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_ERROR, reconcilor->GetState());
@@ -1936,8 +1873,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
account_info.email, account_info.gaia, false /* valid */,
false /* signed_out */, true /* verified */};
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
- cookie_params);
+ signin::SetListAccountsResponseOneAccountWithParams(
+ cookie_params, &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
@@ -1958,9 +1895,11 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
// Add extra cookie change notification. Reconcilor should ignore it.
gaia::ListedAccount listed_account =
- ListedAccounfFromCookieParams(cookie_params, account_id);
- reconcilor->OnGaiaAccountsInCookieUpdated(
- {listed_account}, {}, GoogleServiceAuthError::AuthErrorNone());
+ ListedAccountFromCookieParams(cookie_params, account_id);
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
+ /*accounts_are_fresh=*/true, {listed_account}, {}};
+ reconcilor->OnAccountsInCookieUpdated(
+ accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
base::RunLoop().RunUntilIdle();
@@ -1981,8 +1920,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileNoop) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
reconcilor->StartReconcile();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2015,7 +1954,9 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
base::RunLoop().RunUntilIdle();
std::vector<gaia::ListedAccount> accounts;
// This will be the first call to ListAccounts.
- ASSERT_FALSE(cookie_manager_service()->ListAccounts(&accounts, nullptr));
+ identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info =
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+ ASSERT_FALSE(accounts_in_cookie_jar_info.accounts_are_fresh);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -2095,14 +2036,15 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
// token service, will be considered the same as "dots@gmail.com" as returned
// by gaia::ParseListAccountsData().
TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileNoopWithDots) {
- if (account_tracker()->GetMigrationState() !=
- AccountTrackerService::MIGRATION_NOT_STARTED) {
+ if (identity_test_env()->identity_manager()->GetAccountIdMigrationState() !=
+ identity::IdentityManager::AccountIdMigrationState::
+ MIGRATION_NOT_STARTED) {
return;
}
AccountInfo account_info = ConnectProfileToAccount("Dot.S@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -2121,9 +2063,9 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileNoopMultiple) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
AccountInfo account_info_2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com");
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ signin::SetListAccountsResponseTwoAccounts(
account_info.email, account_info.gaia, account_info_2.email,
- account_info_2.gaia);
+ account_info_2.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -2145,8 +2087,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileAddToCookie) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
const std::string account_id = account_info.account_id;
identity_test_env()->SetRefreshTokenForAccount(account_id);
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
const std::string account_id2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com").account_id;
@@ -2193,11 +2135,10 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileAddToCookie) {
}
TEST_F(AccountReconcilorTest, AuthErrorTriggersListAccount) {
- class TestGaiaCookieObserver : public GaiaCookieManagerService::Observer {
+ class TestGaiaCookieObserver : public identity::IdentityManager::Observer {
public:
- void OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
+ void OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override {
cookies_updated_ = true;
}
@@ -2220,12 +2161,12 @@ TEST_F(AccountReconcilorTest, AuthErrorTriggersListAccount) {
const std::string account_id = account_info.account_id;
identity_test_env()->SetRefreshTokenForAccount(account_id);
TestGaiaCookieObserver observer;
- cookie_manager_service()->AddObserver(&observer);
+ identity_test_env()->identity_manager()->AddObserver(&observer);
AccountReconcilor* reconcilor = GetMockReconcilor();
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
if (account_consistency == signin::AccountConsistencyMethod::kDice) {
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
.Times(1);
@@ -2244,20 +2185,20 @@ TEST_F(AccountReconcilorTest, AuthErrorTriggersListAccount) {
EXPECT_TRUE(observer.cookies_updated_);
testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
- cookie_manager_service()->RemoveObserver(&observer);
+ identity_test_env()->identity_manager()->RemoveObserver(&observer);
}
#if !defined(OS_CHROMEOS)
-// This test does not run on ChromeOS because it calls
-// FakeSigninManagerForTesting::SignOut() which doesn't exist for ChromeOS.
+// This test does not run on ChromeOS because it clears the primary account,
+// which is not a flow that exists on ChromeOS.
TEST_P(AccountReconcilorMirrorEndpointParamTest,
SignoutAfterErrorDoesNotRecordUma) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
const std::string account_id = account_info.account_id;
identity_test_env()->SetRefreshTokenForAccount(account_id);
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
const std::string account_id2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com").account_id;
@@ -2305,8 +2246,9 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
const std::string account_id = account_info.account_id;
identity_test_env()->SetRefreshTokenForAccount(account_id);
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
- account_info.email, account_info.gaia, "other@gmail.com", "12345");
+ signin::SetListAccountsResponseTwoAccounts(
+ account_info.email, account_info.gaia, "other@gmail.com", "12345",
+ &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
@@ -2352,8 +2294,9 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, TokenErrorOnPrimary) {
identity_test_env()->identity_manager(), account_info.account_id,
GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
- account_info.email, account_info.gaia, "other@gmail.com", "67890");
+ signin::SetListAccountsResponseTwoAccounts(
+ account_info.email, account_info.gaia, "other@gmail.com", "67890",
+ &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
reconcilor->StartReconcile();
@@ -2371,8 +2314,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
const std::string account_id2 = account_info2.account_id;
const std::string account_id3 = SeedAccountInfo("34567", "third@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
@@ -2410,10 +2353,10 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
}
// Do another pass after I've added a third account to the token service
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ signin::SetListAccountsResponseTwoAccounts(
account_info.email, account_info.gaia, account_info2.email,
- account_info2.gaia);
- cookie_manager_service()->set_list_accounts_stale_for_testing(true);
+ account_info2.gaia, &test_url_loader_factory_);
+ identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
// This will cause the reconcilor to fire.
identity_test_env()->SetRefreshTokenForAccount(account_id3);
@@ -2462,9 +2405,9 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileBadPrimary) {
AccountInfo account_info2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com");
const std::string account_id2 = account_info2.account_id;
- cookie_manager_service()->SetListAccountsResponseTwoAccounts(
+ signin::SetListAccountsResponseTwoAccounts(
account_info2.email, account_info2.gaia, account_info.email,
- account_info.gaia);
+ account_info.gaia, &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
@@ -2508,8 +2451,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileBadPrimary) {
TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileOnlyOnce) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -2524,8 +2467,8 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, StartReconcileOnlyOnce) {
TEST_P(AccountReconcilorMirrorEndpointParamTest, Lock) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -2602,11 +2545,12 @@ TEST_P(AccountReconcilorMethodParamTest,
AccountInfo account_info2 =
identity_test_env()->MakeAccountAvailable("other@gmail.com");
const std::string account_id2 = account_info2.account_id;
- cookie_manager_service()->SetListAccountsResponseWithParams(
+ signin::SetListAccountsResponseWithParams(
{{account_info.email, account_info.gaia, false /* valid */,
false /* signed_out */, true /* verified */},
{account_info2.email, account_info2.gaia, true /* valid */,
- false /* signed_out */, true /* verified */}});
+ false /* signed_out */, true /* verified */}},
+ &test_url_loader_factory_);
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
@@ -2627,9 +2571,10 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest,
AddAccountToCookieCompletedWithBogusAccount) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
const std::string account_id = account_info.account_id;
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
+ signin::SetListAccountsResponseOneAccountWithParams(
{account_info.email, account_info.gaia, false /* valid */,
- false /* signed_out */, true /* verified */});
+ false /* signed_out */, true /* verified */},
+ &test_url_loader_factory_);
if (!IsMultiloginEnabled()) {
EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
@@ -2682,9 +2627,10 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, NoLoopWithBadPrimary) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
}
// The primary account is in auth error, so it is not in the cookie.
- cookie_manager_service()->SetListAccountsResponseOneAccountWithParams(
+ signin::SetListAccountsResponseOneAccountWithParams(
{account_info2.email, account_info2.gaia, false /* valid */,
- false /* signed_out */, true /* verified */});
+ false /* signed_out */, true /* verified */},
+ &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
@@ -2735,7 +2681,7 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, WontMergeAccountsWithError) {
GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
// The cookie starts empty.
- cookie_manager_service()->SetListAccountsResponseNoAccounts();
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
// Since the cookie jar starts empty, the reconcilor should attempt to merge
// accounts into it. However, it should only try accounts not in auth
@@ -2797,8 +2743,8 @@ TEST_F(AccountReconcilorTest, DelegateTimeoutIsCalled) {
// valid timeout.
TEST_P(AccountReconcilorMirrorEndpointParamTest, DelegateTimeoutIsNotCalled) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
auto timer0 = std::make_unique<base::MockOneShotTimer>();
@@ -2810,14 +2756,14 @@ TEST_P(AccountReconcilorMirrorEndpointParamTest, DelegateTimeoutIsNotCalled) {
EXPECT_FALSE(timer->IsRunning());
}
-INSTANTIATE_TEST_CASE_P(TestMirrorEndpoint,
- AccountReconcilorMirrorEndpointParamTest,
- ::testing::ValuesIn({false, true}));
+INSTANTIATE_TEST_SUITE_P(TestMirrorEndpoint,
+ AccountReconcilorMirrorEndpointParamTest,
+ ::testing::ValuesIn({false, true}));
TEST_F(AccountReconcilorTest, DelegateTimeoutIsNotCalledIfTimeoutIsNotReached) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
- cookie_manager_service()->SetListAccountsResponseOneAccount(
- account_info.email, account_info.gaia);
+ signin::SetListAccountsResponseOneAccount(
+ account_info.email, account_info.gaia, &test_url_loader_factory_);
auto spy_delegate0 = std::make_unique<SpyReconcilorDelegate>();
SpyReconcilorDelegate* spy_delegate = spy_delegate0.get();
AccountReconcilor* reconcilor = GetMockReconcilor(std::move(spy_delegate0));
@@ -2851,3 +2797,45 @@ TEST_F(AccountReconcilorTest, LockDestructionOrder) {
DeleteReconcilor();
// |lock| is destroyed after the reconcilor, this should not crash.
}
+
+// Checks that multilogin with empty list of accounts in UPDATE mode is changed
+// into a Logout call.
+TEST_F(AccountReconcilorTest, MultiloginLogout) {
+ // Delegate implementation always returning UPDATE mode with no accounts.
+ class MultiloginLogoutDelegate : public signin::AccountReconcilorDelegate {
+ bool IsReconcileEnabled() const override { return true; }
+ bool IsAccountConsistencyEnforced() const override { return true; }
+ std::vector<std::string> GetChromeAccountsForReconcile(
+ const std::vector<std::string>& chrome_accounts,
+ const std::string& primary_account,
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const gaia::MultiloginMode mode) const override {
+ return {};
+ }
+ gaia::MultiloginMode CalculateModeForReconcile(
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const std::string primary_account,
+ bool first_execution,
+ bool primary_has_error) const override {
+ return gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER;
+ }
+ };
+
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(kUseMultiloginEndpoint);
+ MockAccountReconcilor* reconcilor =
+ GetMockReconcilor(std::make_unique<MultiloginLogoutDelegate>());
+ signin::SetListAccountsResponseOneAccount("user@gmail.com", "123456",
+ &test_url_loader_factory_);
+
+ // Logout call to Gaia.
+ EXPECT_CALL(*reconcilor, PerformLogoutAllAccountsAction());
+ // No multilogin call.
+ EXPECT_CALL(*reconcilor, PerformSetCookiesAction(testing::_)).Times(0);
+
+ reconcilor->StartReconcile();
+ ASSERT_TRUE(reconcilor->is_reconcile_started_);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(reconcilor->is_reconcile_started_);
+ ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
+}
diff --git a/chromium/components/signin/core/browser/account_tracker_service.cc b/chromium/components/signin/core/browser/account_tracker_service.cc
index 0526b0e94c6..05be0c6698f 100644
--- a/chromium/components/signin/core/browser/account_tracker_service.cc
+++ b/chromium/components/signin/core/browser/account_tracker_service.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
@@ -70,7 +71,8 @@ void RemoveDeprecatedServiceFlags(PrefService* pref_service) {
// Reads a PNG image from disk and decodes it. If the reading/decoding attempt
// was unsuccessful, an empty image is returned.
gfx::Image ReadImage(const base::FilePath& image_path) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
if (!base::PathExists(image_path))
return gfx::Image();
@@ -86,7 +88,8 @@ gfx::Image ReadImage(const base::FilePath& image_path) {
// Saves |png_data| to disk at |image_path|.
void SaveImage(scoped_refptr<base::RefCountedMemory> png_data,
const base::FilePath& image_path) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
// Make sure the destination directory exists.
base::FilePath dir = image_path.DirName();
if (!base::DirectoryExists(dir) && !base::CreateDirectory(dir)) {
diff --git a/chromium/components/signin/core/browser/account_tracker_service.h b/chromium/components/signin/core/browser/account_tracker_service.h
index c60a555a0ba..3e81b78086a 100644
--- a/chromium/components/signin/core/browser/account_tracker_service.h
+++ b/chromium/components/signin/core/browser/account_tracker_service.h
@@ -33,6 +33,10 @@ namespace base {
class DictionaryValue;
}
+namespace identity {
+class IdentityTestEnvironment;
+}
+
// AccountTrackerService is a KeyedService that retrieves and caches GAIA
// information about Google Accounts.
class AccountTrackerService : public KeyedService {
@@ -133,7 +137,7 @@ class AccountTrackerService : public KeyedService {
private:
friend class AccountFetcherService;
- friend class FakeAccountFetcherService;
+ friend class identity::IdentityTestEnvironment;
void NotifyAccountUpdated(const AccountInfo& account_info);
void NotifyAccountUpdateFailed(const std::string& account_id);
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 2aac21e39b0..885ab88a7e7 100644
--- a/chromium/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/chromium/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -21,8 +21,8 @@
#include "components/signin/core/browser/account_info.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/avatar_icon_util.h"
-#include "components/signin/core/browser/fake_account_fetcher_service.h"
#include "components/signin/core/browser/signin_pref_names.h"
+#include "components/signin/core/browser/test_image_decoder.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "google_apis/gaia/gaia_oauth_client.h"
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
index 3feda0e0544..fab8d04c380 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -38,7 +38,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
@@ -89,8 +88,7 @@ public class AccountManagerFacade {
new AtomicReference<>();
private final CountDownLatch mPopulateAccountCacheLatch = new CountDownLatch(1);
private final CachedMetrics.TimesHistogramSample mPopulateAccountCacheWaitingTimeHistogram =
- new CachedMetrics.TimesHistogramSample(
- "Signin.AndroidPopulateAccountCacheWaitingTime", TimeUnit.MILLISECONDS);
+ new CachedMetrics.TimesHistogramSample("Signin.AndroidPopulateAccountCacheWaitingTime");
private final ArrayList<Runnable> mCallbacksWaitingForCachePopulation = new ArrayList<>();
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
index a431cc2dbde..07b9957c531 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
@@ -17,7 +17,6 @@ import org.chromium.base.task.AsyncTask;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.TimeUnit;
/**
* Android wrapper of AccountTrackerService which provides access from the java layer.
@@ -145,8 +144,7 @@ public class AccountTrackerService {
}
RecordHistogram.recordTimesHistogram("Signin.AndroidGetAccountIdsTime",
- SystemClock.elapsedRealtime() - seedingStartTime,
- TimeUnit.MILLISECONDS);
+ SystemClock.elapsedRealtime() - seedingStartTime);
return accountIdNameMap;
}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
index c513524f51c..d7220206927 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -40,7 +40,6 @@ import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.metrics.RecordHistogram;
import java.io.IOException;
-import java.util.concurrent.TimeUnit;
/**
* Default implementation of {@link AccountManagerDelegate} which delegates all calls to the
@@ -183,7 +182,7 @@ public class SystemAccountManagerDelegate implements AccountManagerDelegate {
/**
* Records a histogram value for how long time an action has taken using
- * {@link RecordHistogram#recordTimesHistogram(String, long, TimeUnit))} iff the browser
+ * {@link RecordHistogram#recordTimesHistogram(String, long))} if the browser
* process has been initialized.
*
* @param histogramName the name of the histogram.
@@ -191,7 +190,7 @@ public class SystemAccountManagerDelegate implements AccountManagerDelegate {
*/
protected static void recordElapsedTimeHistogram(String histogramName, long elapsedMs) {
if (!LibraryLoader.getInstance().isInitialized()) return;
- RecordHistogram.recordTimesHistogram(histogramName, elapsedMs, TimeUnit.MILLISECONDS);
+ RecordHistogram.recordTimesHistogram(histogramName, elapsedMs);
}
// No permission is needed on 23+ and Chrome always has MANAGE_ACCOUNTS permission on lower APIs
diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
index d31cd384942..b29f613963c 100644
--- a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
@@ -6,10 +6,12 @@
#include <vector>
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "build/build_config.h"
#include "components/google/core/common/google_util.h"
#include "components/signin/core/browser/cookie_settings_util.h"
#include "google_apis/gaia/gaia_auth_util.h"
@@ -167,14 +169,17 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
const GURL& url,
const std::string& account_id,
int profile_mode_mask) {
-// If we are not on Chrome OS, an empty |account_id| corresponds to the user not
-// signed in to Chrome. Do NOT enforce account consistency otherwise users will
-// not be able to use Google services at all. Therefore, send an empty header.
+// If we are on mobile, an empty |account_id| corresponds to the user not signed
+// into Sync. Do not enforce account consistency, unless Mice is enabled on
+// Android.
// On Chrome OS, an empty |account_id| corresponds to Public Sessions, Guest
// Sessions and Active Directory logins. Guest Sessions have already been
// filtered upstream and we want to enforce account consistency in Public
// Sessions and Active Directory logins.
-#if !defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+ if (account_id.empty() && !base::FeatureList::IsEnabled(kMiceFeature))
+ return std::string();
+#elif !defined(OS_CHROMEOS)
if (account_id.empty())
return std::string();
#endif
@@ -188,7 +193,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
}
parts.push_back(
base::StringPrintf("%s=%s", kProfileModeAttrName,
- base::IntToString(profile_mode_mask).c_str()));
+ base::NumberToString(profile_mode_mask).c_str()));
bool is_mirror_enabled =
account_consistency_ == AccountConsistencyMethod::kMirror;
parts.push_back(base::StringPrintf("%s=%s", kEnableAccountConsistencyAttrName,
diff --git a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
index 5b053f49f0e..ddb4f9e3da4 100644
--- a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
@@ -85,7 +85,7 @@ std::string DiceAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
// out of their other accounts.
// It's only possible when the reconcilor will not perform a logout, because
// that account cannot be rebuilt.
- if (!primary_account_has_token && !gaia_accounts[0].valid && !will_logout)
+ if (!first_gaia_account_has_token && !gaia_accounts[0].valid && !will_logout)
return first_gaia_account;
if (first_execution) {
diff --git a/chromium/components/signin/core/browser/dice_header_helper.cc b/chromium/components/signin/core/browser/dice_header_helper.cc
index 4a7c91f9f36..eac6a7c18b4 100644
--- a/chromium/components/signin/core/browser/dice_header_helper.cc
+++ b/chromium/components/signin/core/browser/dice_header_helper.cc
@@ -49,11 +49,8 @@ DiceAction GetDiceActionFromHeader(const std::string& value) {
} // namespace
-DiceHeaderHelper::DiceHeaderHelper(bool signed_in_with_auth_error,
- AccountConsistencyMethod account_consistency)
- : SigninHeaderHelper("Dice"),
- signed_in_with_auth_error_(signed_in_with_auth_error),
- account_consistency_(account_consistency) {}
+DiceHeaderHelper::DiceHeaderHelper(AccountConsistencyMethod account_consistency)
+ : SigninHeaderHelper("Dice"), account_consistency_(account_consistency) {}
// static
DiceResponseParams DiceHeaderHelper::BuildDiceSigninResponseParams(
@@ -199,8 +196,6 @@ bool DiceHeaderHelper::IsUrlEligibleForRequestHeader(const GURL& url) {
std::string DiceHeaderHelper::BuildRequestHeader(
const std::string& sync_account_id,
const std::string& device_id) {
- DCHECK(!(sync_account_id.empty() && signed_in_with_auth_error_));
-
std::vector<std::string> parts;
parts.push_back(base::StringPrintf("version=%s", kDiceProtocolVersion));
parts.push_back("client_id=" +
diff --git a/chromium/components/signin/core/browser/dice_header_helper.h b/chromium/components/signin/core/browser/dice_header_helper.h
index 9797ed0a0d3..cd725f274e1 100644
--- a/chromium/components/signin/core/browser/dice_header_helper.h
+++ b/chromium/components/signin/core/browser/dice_header_helper.h
@@ -21,8 +21,7 @@ extern const char kDiceProtocolVersion[];
// SigninHeaderHelper implementation managing the Dice header.
class DiceHeaderHelper : public SigninHeaderHelper {
public:
- explicit DiceHeaderHelper(bool signed_in_with_auth_error,
- AccountConsistencyMethod account_consistency);
+ explicit DiceHeaderHelper(AccountConsistencyMethod account_consistency);
~DiceHeaderHelper() override {}
// Returns the parameters contained in the X-Chrome-ID-Consistency-Response
@@ -53,7 +52,6 @@ class DiceHeaderHelper : public SigninHeaderHelper {
// SigninHeaderHelper implementation:
bool IsUrlEligibleForRequestHeader(const GURL& url) override;
- bool signed_in_with_auth_error_;
AccountConsistencyMethod account_consistency_;
DISALLOW_COPY_AND_ASSIGN(DiceHeaderHelper);
diff --git a/chromium/components/signin/core/browser/fake_account_fetcher_service.cc b/chromium/components/signin/core/browser/fake_account_fetcher_service.cc
deleted file mode 100644
index c855b354b10..00000000000
--- a/chromium/components/signin/core/browser/fake_account_fetcher_service.cc
+++ /dev/null
@@ -1,49 +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/signin/core/browser/fake_account_fetcher_service.h"
-
-#include "base/values.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "ui/gfx/image/image_unittest_util.h"
-
-FakeAccountFetcherService::FakeAccountFetcherService() {}
-
-void FakeAccountFetcherService::FakeUserInfoFetchSuccess(
- const std::string& account_id,
- const std::string& email,
- const std::string& gaia,
- const std::string& hosted_domain,
- const std::string& full_name,
- const std::string& given_name,
- const std::string& locale,
- const std::string& picture_url) {
- base::DictionaryValue user_info;
- user_info.SetString("id", gaia);
- user_info.SetString("email", email);
- user_info.SetString("hd", hosted_domain);
- user_info.SetString("name", full_name);
- user_info.SetString("given_name", given_name);
- user_info.SetString("locale", locale);
- user_info.SetString("picture", picture_url);
- account_tracker_service()->SetAccountInfoFromUserInfo(account_id, &user_info);
-}
-
-void FakeAccountFetcherService::StartFetchingUserInfo(
- const std::string& account_id) {
- // In tests, don't do actual network fetch.
-}
-
-TestImageDecoder::TestImageDecoder() = default;
-
-TestImageDecoder::~TestImageDecoder() = default;
-
-void TestImageDecoder::DecodeImage(
- const std::string& image_data,
- const gfx::Size& desired_image_frame_size,
- const image_fetcher::ImageDecodedCallback& callback) {
- callback.Run(image_data.empty() ? gfx::Image()
- : gfx::test::CreateImage(64, 64));
-}
diff --git a/chromium/components/signin/core/browser/fake_account_fetcher_service.h b/chromium/components/signin/core/browser/fake_account_fetcher_service.h
deleted file mode 100644
index 9e1298f2d43..00000000000
--- a/chromium/components/signin/core/browser/fake_account_fetcher_service.h
+++ /dev/null
@@ -1,65 +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_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "components/image_fetcher/core/image_decoder.h"
-#include "components/signin/core/browser/account_fetcher_service.h"
-
-class KeyedService;
-
-// AccountTrackerService is a KeyedService that retrieves and caches GAIA
-// information about Google Accounts. This fake class can be used in tests
-// to prevent AccountTrackerService from sending network requests.
-class FakeAccountFetcherService : public AccountFetcherService {
- public:
- void FakeUserInfoFetchSuccess(const std::string& email,
- const std::string& gaia,
- const std::string& hosted_domain,
- const std::string& full_name,
- const std::string& given_name,
- const std::string& locale,
- const std::string& picture_url);
- void FakeUserInfoFetchSuccess(const std::string& account_id,
- const std::string& email,
- const std::string& gaia,
- const std::string& hosted_domain,
- const std::string& full_name,
- const std::string& given_name,
- const std::string& locale,
- const std::string& picture_url);
-
- FakeAccountFetcherService();
-
- private:
- void StartFetchingUserInfo(const std::string& account_id) override;
-
- DISALLOW_COPY_AND_ASSIGN(FakeAccountFetcherService);
-};
-
-// This dummy class implements |image_fetcher::ImageDecoder|, and is passed
-// as an argument to |AccountFetcherService::Initialize|.
-class TestImageDecoder : public image_fetcher::ImageDecoder {
- public:
- TestImageDecoder();
- ~TestImageDecoder() override;
-
- // image_fetcher::Decoder implementation:
-
- // If |image_data| is non-empty, a blank 64x64 image is passed to callback.
- // Otherwise an empty image is passed.
- void DecodeImage(
- const std::string& image_data,
- const gfx::Size& desired_image_frame_size,
- const image_fetcher::ImageDecodedCallback& callback) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TestImageDecoder);
-};
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_
diff --git a/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.cc b/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.cc
deleted file mode 100644
index e37588f3941..00000000000
--- a/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.cc
+++ /dev/null
@@ -1,99 +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/signin/core/browser/fake_gaia_cookie_manager_service.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "components/signin/core/browser/list_accounts_test_utils.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "google_apis/gaia/gaia_urls.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
-
-namespace {
-// Factory method to return a SharedURLLoaderFactory of our choosing.
-scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory(
- scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory) {
- return shared_url_loader_factory;
-}
-} // namespace
-
-FakeGaiaCookieManagerService::FakeGaiaCookieManagerService(
- OAuth2TokenService* token_service,
- SigninClient* client)
- : GaiaCookieManagerService(
- token_service,
- client,
- base::BindRepeating(&SigninClient::GetURLLoaderFactory,
- base::Unretained(client))) {}
-
-FakeGaiaCookieManagerService::FakeGaiaCookieManagerService(
- OAuth2TokenService* token_service,
- SigninClient* client,
- network::TestURLLoaderFactory* test_url_loader_factory)
- : FakeGaiaCookieManagerService(
- token_service,
- client,
- test_url_loader_factory,
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- test_url_loader_factory)) {}
-
-FakeGaiaCookieManagerService::FakeGaiaCookieManagerService(
- OAuth2TokenService* token_service,
- SigninClient* client,
- network::TestURLLoaderFactory* test_url_loader_factory,
- scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
- shared_url_loader_factory)
- : GaiaCookieManagerService(token_service,
- client,
- base::BindRepeating(&GetSharedURLLoaderFactory,
- shared_url_loader_factory)),
- test_url_loader_factory_(test_url_loader_factory),
- shared_url_loader_factory_(shared_url_loader_factory) {}
-
-FakeGaiaCookieManagerService::~FakeGaiaCookieManagerService() {
- if (shared_url_loader_factory_)
- shared_url_loader_factory_->Detach();
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseHttpNotFound() {
- signin::SetListAccountsResponseHttpNotFound(test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseWebLoginRequired() {
- signin::SetListAccountsResponseWebLoginRequired(test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseWithParams(
- const std::vector<signin::CookieParams>& params) {
- signin::SetListAccountsResponseWithParams(params, test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseNoAccounts() {
- signin::SetListAccountsResponseNoAccounts(test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseOneAccount(
- const std::string& email,
- const std::string& gaia_id) {
- signin::SetListAccountsResponseOneAccount(email, gaia_id,
- test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseOneAccountWithParams(
- const signin::CookieParams& params) {
- signin::SetListAccountsResponseOneAccountWithParams(params,
- test_url_loader_factory_);
-}
-
-void FakeGaiaCookieManagerService::SetListAccountsResponseTwoAccounts(
- const std::string& email1,
- const std::string& gaia_id1,
- const std::string& email2,
- const std::string& gaia_id2) {
- signin::SetListAccountsResponseTwoAccounts(email1, gaia_id1, email2, gaia_id2,
- test_url_loader_factory_);
-}
diff --git a/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.h b/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.h
deleted file mode 100644
index 9da87b92636..00000000000
--- a/chromium/components/signin/core/browser/fake_gaia_cookie_manager_service.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_SIGNIN_CORE_BROWSER_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
-#include "components/signin/core/browser/list_accounts_test_utils.h"
-#include "services/network/test/test_url_loader_factory.h"
-
-namespace network {
-class WeakWrapperSharedURLLoaderFactory;
-}
-
-class FakeGaiaCookieManagerService : public GaiaCookieManagerService {
- public:
- // Convenience constructor overload which uses the SharedURLLoaderFactory from
- // SigninClient.
- FakeGaiaCookieManagerService(OAuth2TokenService* token_service,
- SigninClient* client);
-
- // Constructor overload for tests that want to use a TestURLLoaderFactory for
- // cookie related requests.
- FakeGaiaCookieManagerService(
- OAuth2TokenService* token_service,
- SigninClient* client,
- network::TestURLLoaderFactory* test_url_loader_factory);
-
- ~FakeGaiaCookieManagerService() override;
-
- void SetListAccountsResponseHttpNotFound();
- void SetListAccountsResponseWebLoginRequired();
- void SetListAccountsResponseWithParams(
- const std::vector<signin::CookieParams>& params);
-
- // Helper methods, equivalent to calling SetListAccountsResponseWithParams().
- void SetListAccountsResponseNoAccounts();
- void SetListAccountsResponseOneAccount(const std::string& email,
- const std::string& gaia_id);
- void SetListAccountsResponseOneAccountWithParams(
- const signin::CookieParams& params);
- void SetListAccountsResponseTwoAccounts(const std::string& email1,
- const std::string& gaia_id1,
- const std::string& email2,
- const std::string& gaia_id2);
-
- private:
- // Internal constructor which does the actual construction.
- FakeGaiaCookieManagerService(
- OAuth2TokenService* token_service,
- SigninClient* client,
- network::TestURLLoaderFactory* test_url_loader_factory,
- scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
- shared_url_loader_factory);
-
- // Provides a fake response for calls to /ListAccounts.
- // Owned by the client if passed in via the constructor that takes in this
- // pointer; null otherwise.
- network::TestURLLoaderFactory* test_url_loader_factory_ = nullptr;
-
- scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
- shared_url_loader_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeGaiaCookieManagerService);
-};
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_GAIA_COOKIE_MANAGER_SERVICE_H_
diff --git a/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.cc b/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.cc
index 511bfc94914..4d2899e7550 100644
--- a/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.cc
+++ b/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.cc
@@ -112,12 +112,6 @@ void FakeProfileOAuth2TokenService::IssueTokenForAllPendingRequests(
GoogleServiceAuthError::AuthErrorNone(), token_response);
}
-void FakeProfileOAuth2TokenService::UpdateAuthErrorForTesting(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {
- ProfileOAuth2TokenService::UpdateAuthError(account_id, error);
-}
-
void FakeProfileOAuth2TokenService::CompleteRequests(
const std::string& account_id,
bool all_scopes,
@@ -134,6 +128,12 @@ void FakeProfileOAuth2TokenService::CompleteRequests(
bool scope_matches = all_scopes || it->scopes == scope;
bool account_matches = account_id.empty() || account_id == it->account_id;
if (account_matches && scope_matches) {
+ for (auto& diagnostic_observer : GetDiagnicsObservers()) {
+ diagnostic_observer.OnFetchAccessTokenComplete(
+ account_id, it->request->GetConsumerId(), scope, error,
+ base::Time());
+ }
+
it->request->InformConsumer(
error, OAuth2AccessTokenConsumer::TokenResponse(
token_response.access_token,
@@ -189,7 +189,7 @@ void FakeProfileOAuth2TokenService::FetchOAuth2Token(
FROM_HERE,
base::BindOnce(&FakeProfileOAuth2TokenService::CompleteRequests,
weak_ptr_factory_.GetWeakPtr(), account_id,
- /*all_scoped=*/true, ScopeSet(),
+ /*all_scoped=*/true, scopes,
GoogleServiceAuthError::AuthErrorNone(),
OAuth2AccessTokenConsumer::TokenResponse(
"access_token", base::Time::Max(), std::string())));
diff --git a/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.h b/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.h
index a6e37a49785..be71e20267d 100644
--- a/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.h
+++ b/chromium/components/signin/core/browser/fake_profile_oauth2_token_service.h
@@ -99,10 +99,6 @@ class FakeProfileOAuth2TokenService : public ProfileOAuth2TokenService {
auto_post_fetch_response_on_message_loop_ = auto_post_response;
}
- // Calls ProfileOAuth2TokenService::UpdateAuthError(). Exposed for testing.
- void UpdateAuthErrorForTesting(const std::string& account_id,
- const GoogleServiceAuthError& error);
-
protected:
// OAuth2TokenService overrides.
void CancelAllRequests() override;
diff --git a/chromium/components/signin/core/browser/fake_signin_manager.cc b/chromium/components/signin/core/browser/fake_signin_manager.cc
deleted file mode 100644
index 8fe75e3c647..00000000000
--- a/chromium/components/signin/core/browser/fake_signin_manager.cc
+++ /dev/null
@@ -1,153 +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 "components/signin/core/browser/fake_signin_manager.h"
-
-#include "base/callback_helpers.h"
-#include "build/build_config.h"
-#include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/browser/signin_metrics.h"
-#include "components/signin/core/browser/signin_pref_names.h"
-
-FakeSigninManagerBase::FakeSigninManagerBase(
- SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service)
- : SigninManagerBase(client, token_service, account_tracker_service) {}
-
-FakeSigninManagerBase::~FakeSigninManagerBase() {}
-
-void FakeSigninManagerBase::SignIn(const std::string& account_id) {
- SetAuthenticatedAccountId(account_id);
-}
-
-#if !defined(OS_CHROMEOS)
-
-FakeSigninManager::FakeSigninManager(
- SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service,
- GaiaCookieManagerService* cookie_manager_service)
- : FakeSigninManager(client,
- token_service,
- account_tracker_service,
- cookie_manager_service,
- signin::AccountConsistencyMethod::kDisabled) {}
-
-FakeSigninManager::FakeSigninManager(
- SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service,
- GaiaCookieManagerService* cookie_manager_service,
- signin::AccountConsistencyMethod account_consistency)
- : SigninManager(client,
- token_service,
- account_tracker_service,
- cookie_manager_service,
- account_consistency),
- token_service_(token_service) {}
-
-FakeSigninManager::~FakeSigninManager() {}
-
-void FakeSigninManager::StartSignInWithRefreshToken(
- const std::string& refresh_token,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password,
- OAuthTokenFetchedCallback oauth_fetched_callback) {
- set_auth_in_progress(
- account_tracker_service()->SeedAccountInfo(gaia_id, username));
- set_password(password);
- username_ = username;
-
- possibly_invalid_gaia_id_.assign(gaia_id);
- possibly_invalid_email_.assign(username);
-
- if (!oauth_fetched_callback.is_null())
- std::move(oauth_fetched_callback).Run(refresh_token);
-}
-
-void FakeSigninManager::CompletePendingSignin() {
- SetAuthenticatedAccountId(GetAccountIdForAuthInProgress());
- set_auth_in_progress(std::string());
- FireGoogleSigninSucceeded();
-}
-
-void FakeSigninManager::SignIn(const std::string& gaia_id,
- const std::string& username,
- const std::string& password) {
- StartSignInWithRefreshToken(std::string(), gaia_id, username, password,
- OAuthTokenFetchedCallback());
- CompletePendingSignin();
-}
-
-void FakeSigninManager::ForceSignOut() {
- // SigninClients should always allow sign-out for
- // |FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TESTS|.
- SignOut(signin_metrics::FORCE_SIGNOUT_ALWAYS_ALLOWED_FOR_TEST,
- signin_metrics::SignoutDelete::IGNORE_METRIC);
-}
-
-void FakeSigninManager::FailSignin(const GoogleServiceAuthError& error) {
- for (auto& observer : observer_list_)
- observer.GoogleSigninFailed(error);
-}
-
-void FakeSigninManager::OnSignoutDecisionReached(
- signin_metrics::ProfileSignout signout_source_metric,
- signin_metrics::SignoutDelete signout_delete_metric,
- RemoveAccountsOption remove_option,
- SigninClient::SignoutDecision signout_decision) {
- if (!IsAuthenticated()) {
- if (AuthInProgress()) {
- // If the user is in the process of signing in, then treat a call to
- // SignOut as a cancellation request.
- GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
- HandleAuthError(error);
- } else {
- // Clean up our transient data and exit if we aren't signed in.
- // This avoids a perf regression from clearing out the TokenDB if
- // SignOut() is invoked on startup to clean up any incomplete previous
- // signin attempts.
- ClearTransientSigninData();
- }
- return;
- }
-
- // TODO(crbug.com/887756): Consider moving this higher up, or document why
- // the above blocks are exempt from the |signout_decision| early return.
- if (signout_decision == SigninClient::SignoutDecision::DISALLOW_SIGNOUT)
- return;
-
- set_auth_in_progress(std::string());
- set_password(std::string());
- AccountInfo account_info = GetAuthenticatedAccountInfo();
- const std::string account_id = GetAuthenticatedAccountId();
- const std::string username = account_info.email;
- authenticated_account_id_.clear();
- switch (remove_option) {
- case RemoveAccountsOption::kRemoveAllAccounts:
- if (token_service_)
- token_service_->RevokeAllCredentials();
- break;
- case RemoveAccountsOption::kRemoveAuthenticatedAccountIfInError:
- if (token_service_ && token_service_->RefreshTokenHasError(account_id))
- token_service_->RevokeCredentials(account_id);
- break;
- case RemoveAccountsOption::kKeepAllAccounts:
- // Do nothing.
- break;
- }
- ClearAuthenticatedAccountId();
- client_->GetPrefs()->ClearPref(prefs::kGoogleServicesHostedDomain);
- client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId);
- client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
- client_->GetPrefs()->ClearPref(prefs::kSignedInTime);
-
- FireGoogleSignedOut(account_info);
-}
-
-#endif // !defined (OS_CHROMEOS)
diff --git a/chromium/components/signin/core/browser/fake_signin_manager.h b/chromium/components/signin/core/browser/fake_signin_manager.h
deleted file mode 100644
index 5c7de4a6737..00000000000
--- a/chromium/components/signin/core/browser/fake_signin_manager.h
+++ /dev/null
@@ -1,85 +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.
-
-#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_SIGNIN_MANAGER_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_SIGNIN_MANAGER_H_
-
-#include <memory>
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "build/build_config.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "components/signin/core/browser/signin_metrics.h"
-
-// SigninManager to use for testing.
-
-class FakeSigninManagerBase : public SigninManagerBase {
- public:
- FakeSigninManagerBase(SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service);
- ~FakeSigninManagerBase() override;
-
- void SignIn(const std::string& account_id);
-};
-
-#if !defined(OS_CHROMEOS)
-
-// A signin manager that bypasses actual authentication routines with servers
-// and accepts the credentials provided to StartSignIn.
-class FakeSigninManager : public SigninManager {
- public:
- FakeSigninManager(SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service,
- GaiaCookieManagerService* cookie_manager_service);
-
- FakeSigninManager(SigninClient* client,
- ProfileOAuth2TokenService* token_service,
- AccountTrackerService* account_tracker_service,
- GaiaCookieManagerService* cookie_manager_service,
- signin::AccountConsistencyMethod account_consistency);
-
- ~FakeSigninManager() override;
-
- void set_auth_in_progress(const std::string& account_id) {
- possibly_invalid_account_id_ = account_id;
- }
-
- void set_password(const std::string& password) { password_ = password; }
-
- void SignIn(const std::string& gaia_id,
- const std::string& username,
- const std::string& password);
-
- void ForceSignOut();
-
- void FailSignin(const GoogleServiceAuthError& error);
-
- void StartSignInWithRefreshToken(
- const std::string& refresh_token,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password,
- OAuthTokenFetchedCallback oauth_fetched_callback) override;
-
- void CompletePendingSignin() override;
-
- protected:
- void OnSignoutDecisionReached(
- signin_metrics::ProfileSignout signout_source_metric,
- signin_metrics::SignoutDelete signout_delete_metric,
- RemoveAccountsOption remove_option,
- SigninClient::SignoutDecision signout_decision) override;
-
- // Username specified in StartSignInWithRefreshToken() call.
- std::string username_;
-
- ProfileOAuth2TokenService* token_service_;
-};
-
-#endif // !defined (OS_CHROMEOS)
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_SIGNIN_MANAGER_H_
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 b9aa8215508..3f4b2061495 100644
--- a/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -9,14 +9,17 @@
#include <queue>
#include <set>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/threading/thread_task_runner_handle.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/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_metrics.h"
@@ -152,35 +155,75 @@ GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
: request_type_(request_type), account_ids_(account_ids), source_(source) {}
GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
- const GaiaCookieManagerService::GaiaCookieRequest& other)
- : request_type_(other.request_type()),
- account_ids_(other.account_ids()),
- source_(other.source()) {}
+ GaiaCookieRequestType request_type,
+ const std::vector<std::string>& account_ids,
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback callback)
+ : request_type_(request_type),
+ account_ids_(account_ids),
+ source_(source),
+ set_accounts_in_cookie_completed_callback_(std::move(callback)) {}
+
+GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
+ GaiaCookieRequestType request_type,
+ const std::vector<std::string>& account_ids,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback callback)
+ : request_type_(request_type),
+ account_ids_(account_ids),
+ source_(source),
+ add_account_to_cookie_completed_callback_(std::move(callback)) {}
GaiaCookieManagerService::GaiaCookieRequest::~GaiaCookieRequest() {}
+GaiaCookieManagerService::GaiaCookieRequest::GaiaCookieRequest(
+ GaiaCookieRequest&&) = default;
+
+GaiaCookieManagerService::GaiaCookieRequest&
+GaiaCookieManagerService::GaiaCookieRequest::operator=(GaiaCookieRequest&&) =
+ default;
+
const std::string GaiaCookieManagerService::GaiaCookieRequest::GetAccountID() {
DCHECK_EQ(request_type_, GaiaCookieRequestType::ADD_ACCOUNT);
DCHECK_EQ(1u, account_ids_.size());
return account_ids_[0];
}
+void GaiaCookieManagerService::GaiaCookieRequest::
+ RunSetAccountsInCookieCompletedCallback(
+ const GoogleServiceAuthError& error) {
+ if (set_accounts_in_cookie_completed_callback_)
+ std::move(set_accounts_in_cookie_completed_callback_).Run(error);
+}
+
+void GaiaCookieManagerService::GaiaCookieRequest::
+ RunAddAccountToCookieCompletedCallback(
+ const std::string& account_id,
+ const GoogleServiceAuthError& error) {
+ if (add_account_to_cookie_completed_callback_)
+ std::move(add_account_to_cookie_completed_callback_).Run(account_id, error);
+}
+
// static
GaiaCookieManagerService::GaiaCookieRequest
GaiaCookieManagerService::GaiaCookieRequest::CreateAddAccountRequest(
const std::string& account_id,
- gaia::GaiaSource source) {
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback callback) {
return GaiaCookieManagerService::GaiaCookieRequest(
- GaiaCookieRequestType::ADD_ACCOUNT, {account_id}, source);
+ GaiaCookieRequestType::ADD_ACCOUNT, {account_id}, source,
+ std::move(callback));
}
// static
GaiaCookieManagerService::GaiaCookieRequest
GaiaCookieManagerService::GaiaCookieRequest::CreateSetAccountsRequest(
const std::vector<std::string>& account_ids,
- gaia::GaiaSource source) {
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback callback) {
return GaiaCookieManagerService::GaiaCookieRequest(
- GaiaCookieRequestType::SET_ACCOUNTS, account_ids, source);
+ GaiaCookieRequestType::SET_ACCOUNTS, account_ids, source,
+ std::move(callback));
}
// static
@@ -246,7 +289,7 @@ void GaiaCookieManagerService::ExternalCcResultFetcher::TimeoutForTests() {
void GaiaCookieManagerService::ExternalCcResultFetcher::
OnGetCheckConnectionInfoSuccess(const std::string& data) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(data);
+ std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(data);
const base::ListValue* list;
if (!value || !value->GetAsList(&list)) {
CleanupTransientState();
@@ -474,19 +517,22 @@ void GaiaCookieManagerService::Shutdown() {
void GaiaCookieManagerService::SetAccountsInCookie(
const std::vector<std::string>& account_ids,
- gaia::GaiaSource source) {
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback
+ set_accounts_in_cookies_completed_callback) {
VLOG(1) << "GaiaCookieManagerService::SetAccountsInCookie: "
<< base::JoinString(account_ids, " ");
+ requests_.push_back(GaiaCookieRequest::CreateSetAccountsRequest(
+ account_ids, source,
+ std::move(set_accounts_in_cookies_completed_callback)));
if (!signin_client_->AreSigninCookiesAllowed()) {
OnSetAccountsFinished(
GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
return;
}
- requests_.push_back(
- GaiaCookieRequest::CreateSetAccountsRequest(account_ids, source));
if (requests_.size() == 1) {
fetcher_retries_ = 0;
- signin_client_->DelayNetworkCall(base::Bind(
+ signin_client_->DelayNetworkCall(base::BindOnce(
&GaiaCookieManagerService::StartFetchingAccessTokensForMultilogin,
base::Unretained(this)));
}
@@ -515,39 +561,47 @@ void GaiaCookieManagerService::SetAccountsInCookieWithTokens() {
void GaiaCookieManagerService::AddAccountToCookieInternal(
const std::string& account_id,
- gaia::GaiaSource source) {
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback) {
DCHECK(!account_id.empty());
+ requests_.push_back(GaiaCookieRequest::CreateAddAccountRequest(
+ account_id, source, std::move(completion_callback)));
+
if (!signin_client_->AreSigninCookiesAllowed()) {
- SignalComplete(account_id, GoogleServiceAuthError(
- GoogleServiceAuthError::REQUEST_CANCELED));
+ SignalAddToCookieComplete(
+ requests_.begin(),
+ GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
return;
}
- requests_.push_back(
- GaiaCookieRequest::CreateAddAccountRequest(account_id, source));
if (requests_.size() == 1) {
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingUbertoken,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingUbertoken,
+ base::Unretained(this)));
}
}
-void GaiaCookieManagerService::AddAccountToCookie(const std::string& account_id,
- gaia::GaiaSource source) {
+void GaiaCookieManagerService::AddAccountToCookie(
+ const std::string& account_id,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback) {
VLOG(1) << "GaiaCookieManagerService::AddAccountToCookie: " << account_id;
access_token_ = std::string();
- AddAccountToCookieInternal(account_id, source);
+ AddAccountToCookieInternal(account_id, source,
+ std::move(completion_callback));
}
void GaiaCookieManagerService::AddAccountToCookieWithToken(
const std::string& account_id,
const std::string& access_token,
- gaia::GaiaSource source) {
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback) {
VLOG(1) << "GaiaCookieManagerService::AddAccountToCookieWithToken: "
<< account_id;
DCHECK(!access_token.empty());
access_token_ = access_token;
- AddAccountToCookieInternal(account_id, source);
+ AddAccountToCookieInternal(account_id, source,
+ std::move(completion_callback));
}
bool GaiaCookieManagerService::ListAccounts(
@@ -574,8 +628,8 @@ void GaiaCookieManagerService::TriggerListAccounts() {
fetcher_retries_ = 0;
requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingListAccounts,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingListAccounts,
+ base::Unretained(this)));
} else if (std::find_if(requests_.begin(), requests_.end(),
[](const GaiaCookieRequest& request) {
return request.request_type() == LIST_ACCOUNTS;
@@ -608,12 +662,12 @@ void GaiaCookieManagerService::LogOutAllAccounts(gaia::GaiaSource source) {
// We have a pending log in request for an account followed by
// a signout.
GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
- SignalComplete(it->GetAccountID(), error);
+ SignalAddToCookieComplete(it, error);
}
// Keep all requests except for ADD_ACCOUNTS.
if (it->request_type() != GaiaCookieRequestType::ADD_ACCOUNT)
- requests_to_keep.push_back(*it);
+ requests_to_keep.push_back(std::move(*it));
// Verify a LOG_OUT isn't already queued.
if (it->request_type() == GaiaCookieRequestType::LOG_OUT)
@@ -627,8 +681,9 @@ void GaiaCookieManagerService::LogOutAllAccounts(gaia::GaiaSource source) {
// Remove all but the executing request. Re-add all requests being kept.
if (requests_.size() > 1) {
requests_.erase(requests_.begin() + 1, requests_.end());
- requests_.insert(requests_.end(), requests_to_keep.begin(),
- requests_to_keep.end());
+ requests_.insert(requests_.end(),
+ std::make_move_iterator(requests_to_keep.begin()),
+ std::make_move_iterator(requests_to_keep.end()));
}
}
@@ -636,7 +691,7 @@ void GaiaCookieManagerService::LogOutAllAccounts(gaia::GaiaSource source) {
requests_.push_back(GaiaCookieRequest::CreateLogOutRequest(source));
if (requests_.size() == 1) {
fetcher_retries_ = 0;
- signin_client_->DelayNetworkCall(base::Bind(
+ signin_client_->DelayNetworkCall(base::BindOnce(
&GaiaCookieManagerService::StartGaiaLogOut, base::Unretained(this)));
}
}
@@ -663,6 +718,16 @@ GaiaCookieManagerService::GetURLLoaderFactory() {
return shared_url_loader_factory_getter_.Run();
}
+void GaiaCookieManagerService::MarkListAccountsStale() {
+ list_accounts_stale_ = true;
+#if defined(OS_IOS)
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GaiaCookieManagerService::ForceOnCookieChangeProcessing,
+ weak_ptr_factory_.GetWeakPtr()));
+#endif // defined(OS_IOS)
+}
+
void GaiaCookieManagerService::OnCookieChange(
const net::CanonicalCookie& cookie,
network::mojom::CookieChangeCause cause) {
@@ -686,8 +751,8 @@ void GaiaCookieManagerService::OnCookieChange(
requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
fetcher_retries_ = 0;
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingListAccounts,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingListAccounts,
+ base::Unretained(this)));
}
}
@@ -698,20 +763,27 @@ void GaiaCookieManagerService::OnCookieListenerConnectionError() {
InitCookieListener();
}
-void GaiaCookieManagerService::SignalComplete(
- const std::string& account_id,
+void GaiaCookieManagerService::SignalAddToCookieComplete(
+ const base::circular_deque<GaiaCookieRequest>::iterator& request,
const GoogleServiceAuthError& error) {
- // Its possible for the observer to delete |this| object. Don't access
- // access any members after this calling the observer. This method should
- // be the last call in any other method.
- for (auto& observer : observer_list_)
- observer.OnAddAccountToCookieCompleted(account_id, error);
+ // SignalAddToCookieComplete is called in two circumstances:
+ //
+ // - normal flow: this happens when SignalAddToCookieComplete is called at
+ // the end of processing a ADD_ACCOUNT request.
+ //
+ // - during a LogOut operation: When logging out, any queue request to
+ // ADD_ACCOUNT is canceled (which implies that it is possible to run the
+ // completion callback of a request that it not front of the queue).
+
+ request->RunAddAccountToCookieCompletedCallback(request->GetAccountID(),
+ error);
}
void GaiaCookieManagerService::SignalSetAccountsComplete(
const GoogleServiceAuthError& error) {
- for (auto& observer : observer_list_)
- observer.OnSetAccountsInCookieCompleted(error);
+ DCHECK(requests_.front().request_type() ==
+ GaiaCookieRequestType::SET_ACCOUNTS);
+ requests_.front().RunSetAccountsInCookieCompletedCallback(error);
}
void GaiaCookieManagerService::OnUbertokenFetchComplete(
@@ -722,8 +794,8 @@ void GaiaCookieManagerService::OnUbertokenFetchComplete(
const std::string account_id = requests_.front().GetAccountID();
VLOG(1) << "Failed to retrieve ubertoken"
<< " account=" << account_id << " error=" << error.ToString();
+ SignalAddToCookieComplete(requests_.begin(), error);
HandleNextRequest();
- SignalComplete(account_id, error);
return;
}
@@ -741,8 +813,8 @@ void GaiaCookieManagerService::OnUbertokenFetchComplete(
}
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingMergeSession,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingMergeSession,
+ base::Unretained(this)));
}
void GaiaCookieManagerService::OnTokenFetched(const std::string& account_id,
@@ -752,8 +824,8 @@ void GaiaCookieManagerService::OnTokenFetched(const std::string& account_id,
fetcher_retries_ = 0;
token_requests_.clear();
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::SetAccountsInCookieWithTokens,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::SetAccountsInCookieWithTokens,
+ base::Unretained(this)));
}
}
@@ -783,9 +855,9 @@ void GaiaCookieManagerService::OnGetTokenFailure(
FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(),
base::BindOnce(
&SigninClient::DelayNetworkCall, base::Unretained(signin_client_),
- base::Bind(&GaiaCookieManagerService::
- StartFetchingAccessTokenForMultilogin,
- base::Unretained(this), request->GetAccountId())));
+ base::BindOnce(&GaiaCookieManagerService::
+ StartFetchingAccessTokenForMultilogin,
+ base::Unretained(this), request->GetAccountId())));
return;
}
RecordGetAccessTokenFinished(error);
@@ -798,10 +870,10 @@ void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) {
DCHECK(requests_.front().request_type() ==
GaiaCookieRequestType::ADD_ACCOUNT);
- list_accounts_stale_ = true;
-
+ MarkListAccountsStale();
+ SignalAddToCookieComplete(requests_.begin(),
+ GoogleServiceAuthError::AuthErrorNone());
HandleNextRequest();
- SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
fetcher_backoff_.InformOfRequest(true);
uber_token_ = std::string();
@@ -823,8 +895,8 @@ void GaiaCookieManagerService::OnMergeSessionFailure(
FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(),
base::BindOnce(
&SigninClient::DelayNetworkCall, base::Unretained(signin_client_),
- base::Bind(&GaiaCookieManagerService::StartFetchingMergeSession,
- base::Unretained(this))));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingMergeSession,
+ base::Unretained(this))));
return;
}
@@ -832,8 +904,8 @@ void GaiaCookieManagerService::OnMergeSessionFailure(
UMA_HISTOGRAM_ENUMERATION("OAuth2Login.MergeSessionFailure", error.state(),
GoogleServiceAuthError::NUM_STATES);
+ SignalAddToCookieComplete(requests_.begin(), error);
HandleNextRequest();
- SignalComplete(account_id, error);
}
void GaiaCookieManagerService::OnOAuthMultiloginFinished(
@@ -859,8 +931,9 @@ void GaiaCookieManagerService::OnOAuthMultiloginFinished(
FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(),
base::BindOnce(
&SigninClient::DelayNetworkCall, base::Unretained(signin_client_),
- base::Bind(&GaiaCookieManagerService::SetAccountsInCookieWithTokens,
- base::Unretained(this))));
+ base::BindOnce(
+ &GaiaCookieManagerService::SetAccountsInCookieWithTokens,
+ base::Unretained(this))));
return;
}
// If Gaia responded with status: "INVALID_TOKENS", we have to mark tokens as
@@ -938,8 +1011,8 @@ void GaiaCookieManagerService::OnListAccountsFailure(
FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(),
base::BindOnce(
&SigninClient::DelayNetworkCall, base::Unretained(signin_client_),
- base::Bind(&GaiaCookieManagerService::StartFetchingListAccounts,
- base::Unretained(this))));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingListAccounts,
+ base::Unretained(this))));
return;
}
@@ -956,12 +1029,8 @@ void GaiaCookieManagerService::OnLogOutSuccess() {
VLOG(1) << "GaiaCookieManagerService::OnLogOutSuccess";
RecordLogoutRequestState(LogoutRequestState::kSuccess);
- list_accounts_stale_ = true;
+ MarkListAccountsStale();
fetcher_backoff_.InformOfRequest(true);
- for (auto& observer : observer_list_) {
- observer.OnLogOutAccountsFromCookieCompleted(
- GoogleServiceAuthError(GoogleServiceAuthError::NONE));
- }
HandleNextRequest();
}
@@ -982,8 +1051,6 @@ void GaiaCookieManagerService::OnLogOutFailure(
return;
}
- for (auto& observer : observer_list_)
- observer.OnLogOutAccountsFromCookieCompleted(error);
HandleNextRequest();
}
@@ -1064,14 +1131,12 @@ void GaiaCookieManagerService::StartFetchingListAccounts() {
void GaiaCookieManagerService::OnSetAccountsFinished(
const GoogleServiceAuthError& error) {
- // Set ListAccounts result to stale manually because on iOS
- // GaiaCookieManagerService is not notified about changes in cookie storage.
- list_accounts_stale_ = true;
+ MarkListAccountsStale();
access_tokens_.clear();
token_requests_.clear();
cookies_to_set_.clear();
- HandleNextRequest();
SignalSetAccountsComplete(error);
+ HandleNextRequest();
}
void GaiaCookieManagerService::OnCookieSet(const std::string& cookie_name,
@@ -1106,7 +1171,7 @@ void GaiaCookieManagerService::StartSettingCookies(
&GaiaCookieManagerService::OnCookieSet,
weak_ptr_factory_.GetWeakPtr(), cookie.Name(), cookie.Domain());
cookie_manager->SetCanonicalCookie(
- cookie, true, true,
+ cookie, "https", true,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback),
false));
} else {
@@ -1141,27 +1206,27 @@ void GaiaCookieManagerService::HandleNextRequest() {
case GaiaCookieRequestType::ADD_ACCOUNT:
DCHECK_EQ(1u, requests_.front().account_ids().size());
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingUbertoken,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingUbertoken,
+ base::Unretained(this)));
break;
case GaiaCookieRequestType::SET_ACCOUNTS:
DCHECK(!requests_.front().account_ids().empty());
- signin_client_->DelayNetworkCall(base::Bind(
+ signin_client_->DelayNetworkCall(base::BindOnce(
&GaiaCookieManagerService::StartFetchingAccessTokensForMultilogin,
base::Unretained(this)));
break;
case GaiaCookieRequestType::LOG_OUT:
DCHECK(requests_.front().account_ids().empty());
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartGaiaLogOut,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartGaiaLogOut,
+ base::Unretained(this)));
break;
case GaiaCookieRequestType::LIST_ACCOUNTS:
DCHECK(requests_.front().account_ids().empty());
uber_token_fetcher_.reset();
signin_client_->DelayNetworkCall(
- base::Bind(&GaiaCookieManagerService::StartFetchingListAccounts,
- base::Unretained(this)));
+ base::BindOnce(&GaiaCookieManagerService::StartFetchingListAccounts,
+ base::Unretained(this)));
break;
}
}
diff --git a/chromium/components/signin/core/browser/gaia_cookie_manager_service.h b/chromium/components/signin/core/browser/gaia_cookie_manager_service.h
index 0e62a0bdbb0..ee2a8c5e56c 100644
--- a/chromium/components/signin/core/browser/gaia_cookie_manager_service.h
+++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -81,11 +81,18 @@ class GaiaCookieManagerService : public KeyedService,
SET_ACCOUNTS
};
+ typedef base::OnceCallback<void(const GoogleServiceAuthError& error)>
+ SetAccountsInCookieCompletedCallback;
+ typedef base::OnceCallback<void(const std::string& account_id,
+ const GoogleServiceAuthError& error)>
+ AddAccountToCookieCompletedCallback;
+
// Contains the information and parameters for any request.
class GaiaCookieRequest {
public:
- GaiaCookieRequest(const GaiaCookieRequest& other);
~GaiaCookieRequest();
+ GaiaCookieRequest(GaiaCookieRequest&&);
+ GaiaCookieRequest& operator=(GaiaCookieRequest&&);
GaiaCookieRequestType request_type() const { return request_type_; }
const std::vector<std::string>& account_ids() const { return account_ids_; }
@@ -95,45 +102,50 @@ class GaiaCookieManagerService : public KeyedService,
const std::string GetAccountID();
gaia::GaiaSource source() const { return source_; }
+ void RunSetAccountsInCookieCompletedCallback(
+ const GoogleServiceAuthError& error);
+ void RunAddAccountToCookieCompletedCallback(
+ const std::string& account_id,
+ const GoogleServiceAuthError& error);
+
static GaiaCookieRequest CreateAddAccountRequest(
const std::string& account_id,
- gaia::GaiaSource source);
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback callback);
static GaiaCookieRequest CreateLogOutRequest(gaia::GaiaSource source);
static GaiaCookieRequest CreateListAccountsRequest();
static GaiaCookieRequest CreateSetAccountsRequest(
const std::vector<std::string>& account_ids,
- gaia::GaiaSource source);
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback callback);
private:
GaiaCookieRequest(GaiaCookieRequestType request_type,
const std::vector<std::string>& account_ids,
gaia::GaiaSource source);
+ GaiaCookieRequest(GaiaCookieRequestType request_type,
+ const std::vector<std::string>& account_ids,
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback callback);
+ GaiaCookieRequest(GaiaCookieRequestType request_type,
+ const std::vector<std::string>& account_ids,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback callback);
+
+ GaiaCookieRequestType request_type_;
+ std::vector<std::string> account_ids_;
+ gaia::GaiaSource source_;
+
+ SetAccountsInCookieCompletedCallback
+ set_accounts_in_cookie_completed_callback_;
+ AddAccountToCookieCompletedCallback
+ add_account_to_cookie_completed_callback_;
- const GaiaCookieRequestType request_type_;
- const std::vector<std::string> account_ids_;
- const gaia::GaiaSource source_;
+ DISALLOW_COPY_AND_ASSIGN(GaiaCookieRequest);
};
class Observer {
public:
- // Called whenever a merge session is completed. The account that was
- // merged is given by |account_id|. If |error| is equal to
- // GoogleServiceAuthError::AuthErrorNone() then the merge succeeded.
- virtual void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {}
-
- // Called whenever setting cookies is completed. If |error| is equal to
- // GoogleServiceAuthError::AuthErrorNone() then the call succeeded although
- // there still might be some cookies that failed to be set.
- virtual void OnSetAccountsInCookieCompleted(
- const GoogleServiceAuthError& error) {}
-
- // Called whenever a logout is completed. If |error| is equal to
- // GoogleServiceAuthError::AuthErrorNone() then the logout succeeded.
- virtual void OnLogOutAccountsFromCookieCompleted(
- const GoogleServiceAuthError& error) {}
-
// Called whenever the GaiaCookieManagerService's list of GAIA accounts is
// updated. The GCMS monitors the APISID cookie and triggers a /ListAccounts
// call on change. The GCMS will also call ListAccounts upon the first call
@@ -235,17 +247,23 @@ class GaiaCookieManagerService : public KeyedService,
void InitCookieListener();
void Shutdown() override;
- void AddAccountToCookie(const std::string& account_id,
- gaia::GaiaSource source);
- void AddAccountToCookieWithToken(const std::string& account_id,
- const std::string& access_token,
- gaia::GaiaSource source);
+ void AddAccountToCookie(
+ const std::string& account_id,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback);
+ void AddAccountToCookieWithToken(
+ const std::string& account_id,
+ const std::string& access_token,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback);
// Takes list of account_ids and sets the cookie for these accounts regardless
// of the current cookie state. Removes the accounts that are not in
// account_ids and add the missing ones.
void SetAccountsInCookie(const std::vector<std::string>& account_ids,
- gaia::GaiaSource source);
+ gaia::GaiaSource source,
+ SetAccountsInCookieCompletedCallback
+ set_accounts_in_cookies_completed_callback);
// Takes list of account_ids from the front request, matches them with a
// corresponding stored access_token and calls StartMultilogin.
@@ -280,12 +298,6 @@ class GaiaCookieManagerService : public KeyedService,
// Signout all accounts.
void LogOutAllAccounts(gaia::GaiaSource source);
- // Call observers when merge session completes. This public so that callers
- // that know that a given account is already in the cookie jar can simply
- // inform the observers.
- void SignalComplete(const std::string& account_id,
- const GoogleServiceAuthError& error);
-
// Call observers when setting accounts in cookie completes.
void SignalSetAccountsComplete(const GoogleServiceAuthError& error);
@@ -304,8 +316,6 @@ class GaiaCookieManagerService : public KeyedService,
// Returns a non-NULL pointer to its instance of net::BackoffEntry
const net::BackoffEntry* GetBackoffEntry() { return &fetcher_backoff_; }
- scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
-
// Ubertoken fetch completion callback. Called by unittests directly.
void OnUbertokenFetchComplete(GoogleServiceAuthError error,
const std::string& uber_token);
@@ -324,6 +334,17 @@ class GaiaCookieManagerService : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(GaiaCookieManagerServiceTest,
MultiloginFailureInvalidGaiaCredentialsDesktop);
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
+
+ // Calls the AddAccountToCookie completion callback.
+ void SignalAddToCookieComplete(
+ const base::circular_deque<GaiaCookieRequest>::iterator& request,
+ const GoogleServiceAuthError& error);
+
+ // Marks the list account being staled, and for iOS only, it triggers to fetch
+ // the list of accounts (on iOS there is no OnCookieChange() notification).
+ void MarkListAccountsStale();
+
// Overridden from network::mojom::CookieChangeListner. If the cookie relates
// to a GAIA APISID cookie, then we call ListAccounts and fire
// OnGaiaAccountsInCookieUpdated.
@@ -359,8 +380,10 @@ class GaiaCookieManagerService : public KeyedService,
virtual void OnSetAccountsFinished(const GoogleServiceAuthError& error);
// Helper method for AddAccountToCookie* methods.
- void AddAccountToCookieInternal(const std::string& account_id,
- gaia::GaiaSource source);
+ void AddAccountToCookieInternal(
+ const std::string& account_id,
+ gaia::GaiaSource source,
+ AddAccountToCookieCompletedCallback completion_callback);
// Helper function to trigger fetching retry in case of failure for only
// failed account id. Virtual for testing purposes.
diff --git a/chromium/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc b/chromium/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
index 2cbf0fc474f..04b96f426dc 100644
--- a/chromium/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
+++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -16,6 +17,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
+#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -33,6 +35,9 @@
namespace {
+using MockAddAccountToCookieCompletedCallback = base::MockCallback<
+ GaiaCookieManagerService::AddAccountToCookieCompletedCallback>;
+
class MockObserver : public GaiaCookieManagerService::Observer {
public:
explicit MockObserver(GaiaCookieManagerService* helper) : helper_(helper) {
@@ -41,8 +46,6 @@ class MockObserver : public GaiaCookieManagerService::Observer {
~MockObserver() override { helper_->RemoveObserver(this); }
- MOCK_METHOD2(OnAddAccountToCookieCompleted,
- void(const std::string&, const GoogleServiceAuthError&));
MOCK_METHOD3(OnGaiaAccountsInCookieUpdated,
void(const std::vector<gaia::ListedAccount>&,
const std::vector<gaia::ListedAccount>&,
@@ -253,10 +256,13 @@ TEST_F(GaiaCookieManagerServiceTest, Success) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc1@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token");
}
@@ -266,10 +272,12 @@ TEST_F(GaiaCookieManagerServiceTest, FailedMergeSession) {
base::HistogramTester histograms;
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed, Run("acc1@gmail.com", error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionFailure(&helper, error());
// Persistent error incurs no further retries.
DCHECK(!helper.is_running());
@@ -282,10 +290,12 @@ TEST_F(GaiaCookieManagerServiceTest, AddAccountCookiesDisabled) {
MockObserver observer(&helper);
signin_client()->set_are_signin_cookies_allowed(false);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", canceled()));
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc1@gmail.com", canceled()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
}
TEST_F(GaiaCookieManagerServiceTest, MergeSessionRetried) {
@@ -298,10 +308,13 @@ TEST_F(GaiaCookieManagerServiceTest, MergeSessionRetried) {
EXPECT_CALL(helper, StartFetchingUbertoken());
EXPECT_CALL(helper, StartFetchingMergeSession());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc1@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionFailure(&helper, canceled());
DCHECK(helper.is_running());
Advance(test_task_runner, helper.GetBackoffEntry()->GetTimeUntilRelease());
@@ -320,10 +333,13 @@ TEST_F(GaiaCookieManagerServiceTest, MergeSessionRetriedTwice) {
EXPECT_CALL(helper, StartFetchingUbertoken());
EXPECT_CALL(helper, StartFetchingMergeSession()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc1@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionFailure(&helper, canceled());
DCHECK(helper.is_running());
Advance(test_task_runner, helper.GetBackoffEntry()->GetTimeUntilRelease());
@@ -341,10 +357,12 @@ TEST_F(GaiaCookieManagerServiceTest, FailedUbertoken) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed, Run("acc1@gmail.com", error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateUbertokenFailure(&helper, error());
}
@@ -370,7 +388,9 @@ TEST_F(GaiaCookieManagerServiceTest, AccessTokenSuccess) {
const std::vector<std::string> account_ids = {account_id1, account_id2};
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
RequestMockImpl request1(account_id1);
RequestMockImpl request2(account_id2);
@@ -414,7 +434,9 @@ TEST_F(GaiaCookieManagerServiceTest,
const std::vector<std::string> account_ids = {account_id1, account_id2};
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
RequestMockImpl request1(account_id1);
RequestMockImpl request2(account_id2);
@@ -452,7 +474,9 @@ TEST_F(GaiaCookieManagerServiceTest, AccessTokenFailurePersistentError) {
const std::vector<std::string> account_ids = {account_id1, account_id2};
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
RequestMockImpl request1(account_id1);
RequestMockImpl request2(account_id2);
@@ -513,7 +537,9 @@ TEST_F(GaiaCookieManagerServiceTest, FetcherRetriesZeroedBetweenCalls) {
const std::vector<std::string> account_ids = {account_id1, account_id2};
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
RequestMockImpl request1(account_id1);
RequestMockImpl request2(account_id2);
@@ -608,7 +634,9 @@ TEST_F(GaiaCookieManagerServiceTest, MultiloginSuccessAndCookiesSet) {
.Times(1);
// Needed to insert request in the queue.
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
helper.StartFetchingMultiLogin(accounts);
@@ -643,7 +671,9 @@ TEST_F(GaiaCookieManagerServiceTest, MultiloginFailurePersistentError) {
EXPECT_CALL(helper, OnSetAccountsFinished(error)).Times(1);
// Needed to insert request in the queue.
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
helper.StartFetchingMultiLogin(accounts);
@@ -681,7 +711,9 @@ TEST_F(GaiaCookieManagerServiceTest, MultiloginFailureMaxRetriesReached) {
EXPECT_CALL(helper, OnSetAccountsFinished(error)).Times(1);
// Needed to insert request in the queue.
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
helper.StartFetchingMultiLogin(accounts);
@@ -773,7 +805,9 @@ TEST_F(GaiaCookieManagerServiceTest,
.Times(1);
// Needed to insert request in the queue.
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
// Both requests for access tokens are successful but they could be returned
// from cache and be stale.
@@ -854,7 +888,9 @@ TEST_F(GaiaCookieManagerServiceTest,
EXPECT_CALL(helper, OnSetAccountsFinished(error)).Times(1);
// Needed to insert request in the queue.
- helper.SetAccountsInCookie(account_ids, gaia::GaiaSource::kChrome);
+ helper.SetAccountsInCookie(
+ account_ids, gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::SetAccountsInCookieCompletedCallback());
// Both requests for access tokens are successful but they could be returned
// from cache and be stale.
@@ -878,13 +914,18 @@ TEST_F(GaiaCookieManagerServiceTest, ContinueAfterSuccess) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1,
+ add_account_to_cookie_completed2;
+ EXPECT_CALL(add_account_to_cookie_completed1,
+ Run("acc1@gmail.com", no_error()));
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
SimulateMergeSessionSuccess(&helper, "token1");
SimulateMergeSessionSuccess(&helper, "token2");
}
@@ -894,13 +935,17 @@ TEST_F(GaiaCookieManagerServiceTest, ContinueAfterFailure1) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", error()));
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1,
+ add_account_to_cookie_completed2;
+ EXPECT_CALL(add_account_to_cookie_completed1, Run("acc1@gmail.com", error()));
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
SimulateMergeSessionFailure(&helper, error());
SimulateMergeSessionSuccess(&helper, "token2");
}
@@ -910,13 +955,17 @@ TEST_F(GaiaCookieManagerServiceTest, ContinueAfterFailure2) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", error()));
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1,
+ add_account_to_cookie_completed2;
+ EXPECT_CALL(add_account_to_cookie_completed1, Run("acc1@gmail.com", error()));
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
SimulateUbertokenFailure(&helper, error());
SimulateMergeSessionSuccess(&helper, "token2");
}
@@ -926,19 +975,25 @@ TEST_F(GaiaCookieManagerServiceTest, AllRequestsInMultipleGoes) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(4);
- EXPECT_CALL(observer, OnAddAccountToCookieCompleted(_, no_error())).Times(4);
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed, Run(_, no_error())).Times(4);
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token2");
SimulateMergeSessionSuccess(&helper, "token3");
- helper.AddAccountToCookie("acc4@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc4@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token4");
}
@@ -948,11 +1003,14 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsNoQueue) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
@@ -965,11 +1023,14 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsFails) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
@@ -983,11 +1044,14 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsAfterOneAddInQueue) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
SimulateMergeSessionSuccess(&helper, "token1");
@@ -999,15 +1063,20 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsAfterTwoAddsInQueue) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", canceled()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1,
+ add_account_to_cookie_completed2;
+ EXPECT_CALL(add_account_to_cookie_completed1,
+ Run("acc1@gmail.com", no_error()));
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", canceled()));
+
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
// The Log Out should prevent this AddAccount from being fetched.
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
SimulateMergeSessionSuccess(&helper, "token1");
@@ -1019,11 +1088,14 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsTwice) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
+ EXPECT_CALL(add_account_to_cookie_completed,
+ Run("acc2@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
@@ -1037,16 +1109,22 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsBeforeAdd) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc3@gmail.com", no_error()));
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed2,
+ add_account_to_cookie_completed3;
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", no_error()));
+ EXPECT_CALL(add_account_to_cookie_completed3,
+ Run("acc3@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed3.Get());
SimulateLogOutSuccess(&helper);
// After LogOut the MergeSession should be fetched.
@@ -1058,19 +1136,24 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsBeforeLogoutAndAdd) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", no_error()));
EXPECT_CALL(helper, StartFetchingLogOut());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc3@gmail.com", no_error()));
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed2,
+ add_account_to_cookie_completed3;
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", no_error()));
+ EXPECT_CALL(add_account_to_cookie_completed3,
+ Run("acc3@gmail.com", no_error()));
+
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
// Second LogOut will never be fetched.
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed3.Get());
SimulateLogOutSuccess(&helper);
// After LogOut the MergeSession should be fetched.
@@ -1082,24 +1165,29 @@ TEST_F(GaiaCookieManagerServiceTest, PendingSigninThenSignout) {
MockObserver observer(&helper);
// From the first Signin.
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1;
+ EXPECT_CALL(add_account_to_cookie_completed1,
+ Run("acc1@gmail.com", no_error()));
// From the sign out and then re-sign in.
EXPECT_CALL(helper, StartFetchingLogOut());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc3@gmail.com", no_error()));
+
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed3;
+ EXPECT_CALL(add_account_to_cookie_completed3,
+ Run("acc3@gmail.com", no_error()));
// Total sign in 2 times, not enforcing ordered sequences.
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
SimulateMergeSessionSuccess(&helper, "token1");
SimulateLogOutSuccess(&helper);
- helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc3@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed3.Get());
SimulateMergeSessionSuccess(&helper, "token3");
}
@@ -1108,14 +1196,18 @@ TEST_F(GaiaCookieManagerServiceTest, CancelSignIn) {
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetchingUbertoken());
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc2@gmail.com", canceled()));
- EXPECT_CALL(observer,
- OnAddAccountToCookieCompleted("acc1@gmail.com", no_error()));
+ MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed1,
+ add_account_to_cookie_completed2;
+ EXPECT_CALL(add_account_to_cookie_completed1,
+ Run("acc1@gmail.com", no_error()));
+ EXPECT_CALL(add_account_to_cookie_completed2,
+ Run("acc2@gmail.com", canceled()));
EXPECT_CALL(helper, StartFetchingLogOut());
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed1.Get());
+ helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome,
+ add_account_to_cookie_completed2.Get());
helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
SimulateMergeSessionSuccess(&helper, "token1");
@@ -1355,7 +1447,9 @@ TEST_F(GaiaCookieManagerServiceTest, UbertokenSuccessFetchesExternalCC) {
InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
EXPECT_CALL(helper, StartFetchingUbertoken());
- helper.AddAccountToCookie("acc1@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie(
+ "acc1@gmail.com", gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::AddAccountToCookieCompletedCallback());
ASSERT_FALSE(IsLoadPending());
SimulateUbertokenSuccess(&helper, "token");
@@ -1377,7 +1471,9 @@ TEST_F(GaiaCookieManagerServiceTest, UbertokenSuccessFetchesExternalCCOnce) {
helper.external_cc_result_fetcher_for_testing()->Start();
EXPECT_CALL(helper, StartFetchingUbertoken());
- helper.AddAccountToCookie("acc2@gmail.com", gaia::GaiaSource::kChrome);
+ helper.AddAccountToCookie(
+ "acc2@gmail.com", gaia::GaiaSource::kChrome,
+ GaiaCookieManagerService::AddAccountToCookieCompletedCallback());
// There is already a ExternalCCResultFetch underway. This will trigger
// StartFetchingMergeSession.
EXPECT_CALL(helper, StartFetchingMergeSession());
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc
new file mode 100644
index 00000000000..65d58865fbc
--- /dev/null
+++ b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc
@@ -0,0 +1,73 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
+
+#include "base/logging.h"
+#include "components/signin/core/browser/account_reconcilor.h"
+
+namespace signin {
+
+MiceAccountReconcilorDelegate::MiceAccountReconcilorDelegate() = default;
+
+MiceAccountReconcilorDelegate::~MiceAccountReconcilorDelegate() = default;
+
+bool MiceAccountReconcilorDelegate::IsReconcileEnabled() const {
+ return true;
+}
+
+bool MiceAccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
+ return true;
+}
+
+gaia::GaiaSource MiceAccountReconcilorDelegate::GetGaiaApiSource() const {
+ return gaia::GaiaSource::kAccountReconcilorMirror;
+}
+
+std::string MiceAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
+ const std::vector<std::string>& chrome_accounts,
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const std::string& primary_account,
+ bool first_execution,
+ bool will_logout) const {
+ // This flow is deprecated and will be removed when multilogin is fully
+ // launched.
+ NOTREACHED() << "Mice requires multilogin";
+ return std::string();
+}
+
+std::vector<std::string>
+MiceAccountReconcilorDelegate::GetChromeAccountsForReconcile(
+ const std::vector<std::string>& chrome_accounts,
+ const std::string& primary_account,
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const gaia::MultiloginMode mode) const {
+ if (chrome_accounts.empty())
+ return {};
+
+ // First account, by priority order:
+ // - primary account
+ // - first account on the device.
+ // Warning: As a result, the reconciliation may change the default Gaia
+ // account. It should be ensured that this is not surprising for the user.
+ std::string new_first_account =
+ base::ContainsValue(chrome_accounts, primary_account)
+ ? primary_account
+ : chrome_accounts[0];
+
+ // Minimize account shuffling and ensure that the number of accounts does not
+ // exceed the limit.
+ return ReorderChromeAccountsForReconcile(chrome_accounts, new_first_account,
+ gaia_accounts);
+}
+
+gaia::MultiloginMode MiceAccountReconcilorDelegate::CalculateModeForReconcile(
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const std::string primary_account,
+ bool first_execution,
+ bool primary_has_error) const {
+ return gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER;
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h
new file mode 100644
index 00000000000..bdb4f3c817a
--- /dev/null
+++ b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "components/signin/core/browser/account_reconcilor_delegate.h"
+
+namespace signin {
+
+// AccountReconcilorDelegate specialized for Mice.
+class MiceAccountReconcilorDelegate : public AccountReconcilorDelegate {
+ public:
+ MiceAccountReconcilorDelegate();
+ ~MiceAccountReconcilorDelegate() override;
+
+ private:
+ // AccountReconcilorDelegate:
+ bool IsReconcileEnabled() const override;
+ bool IsAccountConsistencyEnforced() const override;
+ gaia::GaiaSource GetGaiaApiSource() const override;
+ std::string GetFirstGaiaAccountForReconcile(
+ const std::vector<std::string>& chrome_accounts,
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const std::string& primary_account,
+ bool first_execution,
+ bool will_logout) const override;
+ std::vector<std::string> GetChromeAccountsForReconcile(
+ const std::vector<std::string>& chrome_accounts,
+ const std::string& primary_account,
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const gaia::MultiloginMode mode) const override;
+ gaia::MultiloginMode CalculateModeForReconcile(
+ const std::vector<gaia::ListedAccount>& gaia_accounts,
+ const std::string primary_account,
+ bool first_execution,
+ bool primary_has_error) const override;
+
+ DISALLOW_COPY_AND_ASSIGN(MiceAccountReconcilorDelegate);
+};
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc
new file mode 100644
index 00000000000..001637f6376
--- /dev/null
+++ b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
+
+#include <vector>
+
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace signin {
+
+namespace {
+
+// Returns a gaia::ListedAccount with the specified account id.
+gaia::ListedAccount BuildTestListedAccount(const std::string account_id,
+ bool valid) {
+ gaia::ListedAccount account;
+ account.id = account_id;
+ account.valid = valid;
+ return account;
+}
+
+} // namespace
+
+TEST(MiceAccountReconcilorDelegate, CalculateParametersForMultilogin) {
+ MiceAccountReconcilorDelegate mice_delegate;
+
+ const gaia::ListedAccount kA = BuildTestListedAccount("A", /*valid=*/true);
+ const gaia::ListedAccount kB = BuildTestListedAccount("B", /*valid=*/false);
+
+ struct TestParams {
+ std::vector<std::string> chrome_accounts;
+ std::string primary_account;
+ std::vector<gaia::ListedAccount> gaia_accounts;
+
+ std::vector<std::string> expected_accounts;
+ };
+
+ // clang-format off
+ TestParams cases[] = {
+ // chrome_accounts, primary_account, gaia_accounts, expected_accounts
+ {{}, "", {}, {}},
+ {{}, "", {kA, kB}, {}},
+ {{"A"}, "", {}, {"A"}},
+ {{"A"}, "", {kA, kB}, {"A"}},
+ {{"A"}, "", {kB, kA}, {"A"}},
+ {{"A", "B"}, "", {}, {"A", "B"}},
+ {{"A", "B"}, "", {kA}, {"A", "B"}},
+ {{"A", "B"}, "", {kB}, {"A", "B"}},
+ {{"B", "C"}, "", {kA}, {"B", "C"}},
+ {{"A", "B"}, "", {kA, kB}, {"A", "B"}},
+ {{"A", "B"}, "", {kB, kA}, {"A", "B"}},
+ {{"B", "C"}, "", {kA, kB}, {"B", "C"}},
+ // Tests the reordering: B remains in 2nd place.
+ {{"C", "D", "B"}, "", {kA, kB}, {"C", "B", "D"}},
+ // With primary account.
+ {{"A", "B"}, "B", {}, {"B", "A"}},
+ {{"B", "A"}, "A", {kB, kA}, {"A", "B"}},
+ {{"A", "B"}, "B", {kB, kA}, {"B", "A"}},
+ };
+ // clang-format on
+
+ for (const auto& test : cases) {
+ MultiloginParameters multilogin_parameters =
+ mice_delegate.CalculateParametersForMultilogin(
+ test.chrome_accounts, test.primary_account, test.gaia_accounts,
+ false, false);
+ EXPECT_EQ(gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ multilogin_parameters.mode);
+ EXPECT_EQ(test.expected_accounts, multilogin_parameters.accounts_to_send);
+ }
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
index 63a3cb4d74d..dec959175c4 100644
--- a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
@@ -59,15 +59,15 @@ MirrorAccountReconcilorDelegate::GetChromeAccountsForReconcile(
gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
return ReorderChromeAccountsForReconcile(chrome_accounts, primary_account,
gaia_accounts);
- }
+}
void MirrorAccountReconcilorDelegate::OnPrimaryAccountSet(
- const AccountInfo& primary_account_info) {
+ const CoreAccountInfo& primary_account_info) {
reconcilor()->EnableReconcile();
}
void MirrorAccountReconcilorDelegate::OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) {
+ const CoreAccountInfo& previous_primary_account_info) {
reconcilor()->DisableReconcile(true /* logout_all_gaia_accounts */);
}
diff --git a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
index 05f9f72069a..a13904754a1 100644
--- a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
+++ b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
@@ -47,9 +47,10 @@ class MirrorAccountReconcilorDelegate
const gaia::MultiloginMode mode) const override;
// IdentityManager::Observer:
- void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
+ void OnPrimaryAccountSet(
+ const CoreAccountInfo& primary_account_info) override;
void OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) override;
+ const CoreAccountInfo& previous_primary_account_info) override;
identity::IdentityManager* identity_manager_;
diff --git a/chromium/components/signin/core/browser/mutable_profile_oauth2_token_service_delegate_unittest.cc b/chromium/components/signin/core/browser/mutable_profile_oauth2_token_service_delegate_unittest.cc
index b9b8e588287..df7b61bc268 100644
--- a/chromium/components/signin/core/browser/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/chromium/components/signin/core/browser/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -95,7 +95,6 @@ class MutableProfileOAuth2TokenServiceDelegateTest
token_available_count_(0),
token_revoked_count_(0),
tokens_loaded_count_(0),
- start_batch_changes_(0),
end_batch_changes_(0),
auth_error_changed_count_(0),
revoke_all_tokens_on_load_(false) {}
@@ -197,8 +196,6 @@ class MutableProfileOAuth2TokenServiceDelegateTest
}
void OnRefreshTokensLoaded() override { ++tokens_loaded_count_; }
- void OnStartBatchChanges() override { ++start_batch_changes_; }
-
void OnEndBatchChanges() override { ++end_batch_changes_; }
void OnAuthErrorChanged(const std::string& account_id,
@@ -221,7 +218,6 @@ class MutableProfileOAuth2TokenServiceDelegateTest
token_available_count_ = 0;
token_revoked_count_ = 0;
tokens_loaded_count_ = 0;
- start_batch_changes_ = 0;
end_batch_changes_ = 0;
auth_error_changed_count_ = 0;
}
@@ -271,7 +267,6 @@ class MutableProfileOAuth2TokenServiceDelegateTest
int token_available_count_;
int token_revoked_count_;
int tokens_loaded_count_;
- int start_batch_changes_;
int end_batch_changes_;
int auth_error_changed_count_;
bool revoke_all_tokens_on_load_;
@@ -297,7 +292,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) {
// Legacy tokens get discarded, but the old refresh token is kept.
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_TRUE(
oauth2_service_delegate_->RefreshTokenIsAvailable(main_account_id));
@@ -328,7 +322,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) {
// token is present it is not overwritten.
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(1, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(main_refresh_token,
oauth2_service_delegate_->GetRefreshToken(main_account_id));
@@ -345,7 +338,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) {
.refresh_token);
oauth2_service_delegate_->RevokeAllCredentials();
- EXPECT_EQ(2, start_batch_changes_);
EXPECT_EQ(2, end_batch_changes_);
}
@@ -361,7 +353,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_2));
oauth2_service_delegate_->UpdateCredentials(account_id_1, refresh_token_1);
oauth2_service_delegate_->UpdateCredentials(account_id_2, refresh_token_2);
- EXPECT_EQ(2, start_batch_changes_);
EXPECT_EQ(2, end_batch_changes_);
EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(account_id_1));
@@ -369,7 +360,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
ResetObserverCounts();
oauth2_service_delegate_->RevokeCredentials(account_id_1);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
ExpectOneTokenRevokedNotification();
@@ -380,7 +370,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(0, token_available_count_);
EXPECT_EQ(1, token_revoked_count_);
EXPECT_EQ(0, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
ResetObserverCounts();
}
@@ -421,7 +410,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_MISSING),
oauth2_service_delegate_->GetAuthError("account_id"));
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(1, auth_error_changed_count_);
@@ -445,7 +433,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
oauth2_service_delegate_->UpdateCredentials("account_id", "refresh_token");
oauth2_service_delegate_->UpdateCredentials("account_id2", "refresh_token2");
oauth2_service_delegate_->refresh_tokens_.clear();
- EXPECT_EQ(2, start_batch_changes_);
EXPECT_EQ(2, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
ResetObserverCounts();
@@ -461,7 +448,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(0, token_revoked_count_);
EXPECT_EQ(1, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
ResetObserverCounts();
@@ -473,7 +459,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(0, token_available_count_);
EXPECT_EQ(2, token_revoked_count_);
EXPECT_EQ(0, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(0, auth_error_changed_count_);
ResetObserverCounts();
@@ -497,7 +482,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
base::RunLoop().RunUntilIdle();
EXPECT_EQ(OAuth2TokenServiceDelegate::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS,
oauth2_service_delegate_->load_credentials_state());
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(0, auth_error_changed_count_);
ExpectOneTokensLoadedNotification();
@@ -510,7 +494,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
oauth2_service_delegate_->UpdateCredentials("account_id", "refresh_token");
oauth2_service_delegate_->UpdateCredentials("account_id2", "refresh_token2");
oauth2_service_delegate_->refresh_tokens_.clear();
- EXPECT_EQ(2, start_batch_changes_);
EXPECT_EQ(2, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
ResetObserverCounts();
@@ -524,7 +507,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(0, token_revoked_count_);
EXPECT_EQ(1, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
ResetObserverCounts();
@@ -536,7 +518,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(0, token_available_count_);
EXPECT_EQ(2, token_revoked_count_);
EXPECT_EQ(0, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(0, auth_error_changed_count_);
ResetObserverCounts();
@@ -570,7 +551,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(0, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
@@ -612,7 +592,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(0, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(2, auth_error_changed_count_);
EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
@@ -654,7 +633,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
EXPECT_EQ(1, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(1, auth_error_changed_count_);
EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable(
@@ -688,7 +666,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_EQ(1, auth_error_changed_count_);
@@ -728,7 +705,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
// No tokens were loaded.
EXPECT_EQ(1, tokens_loaded_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(0, token_available_count_);
EXPECT_EQ(2, token_revoked_count_);
EXPECT_EQ(1, end_batch_changes_);
@@ -1186,7 +1162,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GaiaIdMigration) {
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
std::vector<std::string> accounts = oauth2_service_delegate_->GetAccounts();
@@ -1204,7 +1179,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, GaiaIdMigration) {
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(email));
@@ -1250,7 +1224,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(2, token_available_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
std::vector<std::string> accounts = oauth2_service_delegate_->GetAccounts();
@@ -1270,7 +1243,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(2, token_available_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_FALSE(oauth2_service_delegate_->RefreshTokenIsAvailable(email1));
@@ -1298,7 +1270,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
EXPECT_EQ(1, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_TRUE(
oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
@@ -1322,7 +1293,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest,
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(2, token_available_count_);
EXPECT_EQ(0, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_TRUE(
oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
@@ -1475,7 +1445,6 @@ TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ClearTokensOnStartup) {
EXPECT_EQ(1, tokens_loaded_count_);
EXPECT_EQ(1, token_available_count_);
EXPECT_EQ(1, token_revoked_count_);
- EXPECT_EQ(1, start_batch_changes_);
EXPECT_EQ(1, end_batch_changes_);
EXPECT_TRUE(
oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
diff --git a/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.cc b/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.cc
index 0d872ed9d62..4f1df012a79 100644
--- a/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.cc
+++ b/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.cc
@@ -8,10 +8,12 @@
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
+#include "components/signin/core/browser/account_consistency_method.h"
#include "components/signin/core/browser/account_info.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
@@ -129,7 +131,8 @@ std::string AndroidAccessTokenFetcher::CombineScopes(
} // namespace
-bool OAuth2TokenServiceDelegateAndroid::is_testing_profile_ = false;
+bool OAuth2TokenServiceDelegateAndroid::
+ disable_interaction_with_system_accounts_ = false;
OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid(
AccountTrackerService* account_tracker_service)
@@ -158,7 +161,7 @@ OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid(
Java_OAuth2TokenService_saveStoredAccounts(env, java_accounts);
}
- if (!is_testing_profile_) {
+ if (!disable_interaction_with_system_accounts_) {
Java_OAuth2TokenService_validateAccounts(AttachCurrentThread(), java_ref_,
JNI_TRUE);
}
@@ -309,16 +312,17 @@ void OAuth2TokenServiceDelegateAndroid::ValidateAccounts(
std::vector<std::string> refreshed_ids;
std::vector<std::string> revoked_ids;
- bool currently_signed_in =
+ bool keep_accounts =
ValidateAccounts(signed_in_account_id, prev_ids, curr_ids, &refreshed_ids,
&revoked_ids, force_notifications);
ScopedBatchChange batch(this);
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobjectArray> java_accounts;
- if (currently_signed_in) {
+ if (keep_accounts) {
java_accounts = base::android::ToJavaArrayOfStrings(env, curr_ids);
} else {
+ DCHECK(!base::FeatureList::IsEnabled(signin::kMiceFeature));
java_accounts =
base::android::ToJavaArrayOfStrings(env, std::vector<std::string>());
}
@@ -361,8 +365,9 @@ bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts(
std::vector<std::string>* refreshed_ids,
std::vector<std::string>* revoked_ids,
bool force_notifications) {
- bool currently_signed_in = base::ContainsValue(curr_ids, signed_in_id);
- if (currently_signed_in) {
+ bool keep_accounts = base::FeatureList::IsEnabled(signin::kMiceFeature) ||
+ base::ContainsValue(curr_ids, signed_in_id);
+ if (keep_accounts) {
// Revoke token for ids that have been removed from the device.
for (const std::string& prev_id : prev_ids) {
if (prev_id == signed_in_id)
@@ -375,7 +380,8 @@ bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts(
}
// Refresh token for new ids or all ids if |force_notifications|.
- if (force_notifications || !base::ContainsValue(prev_ids, signed_in_id)) {
+ if (!signed_in_id.empty() &&
+ (force_notifications || !base::ContainsValue(prev_ids, signed_in_id))) {
// Always fire the primary signed in account first.
DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:"
<< "refreshed=" << signed_in_id;
@@ -391,6 +397,7 @@ bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts(
}
}
} else {
+ // Revoke all ids.
if (base::ContainsValue(prev_ids, signed_in_id)) {
DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:"
<< "revoked=" << signed_in_id;
@@ -404,7 +411,7 @@ bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts(
revoked_ids->push_back(prev_id);
}
}
- return currently_signed_in;
+ return keep_accounts;
}
void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenAvailable(
@@ -478,7 +485,8 @@ void OAuth2TokenServiceDelegateAndroid::LoadCredentials(
const std::string& primary_account_id) {
DCHECK_EQ(LOAD_CREDENTIALS_NOT_STARTED, load_credentials_state());
set_load_credentials_state(LOAD_CREDENTIALS_IN_PROGRESS);
- if (primary_account_id.empty()) {
+ if (primary_account_id.empty() &&
+ !base::FeatureList::IsEnabled(signin::kMiceFeature)) {
FireRefreshTokensLoaded();
return;
}
@@ -490,6 +498,13 @@ void OAuth2TokenServiceDelegateAndroid::LoadCredentials(
}
}
+void OAuth2TokenServiceDelegateAndroid::ReloadAccountsFromSystem(
+ const std::string& primary_account_id) {
+ // ValidateAccounts() effectively synchronizes the accounts in the Token
+ // Service with those present at the system level.
+ ValidateAccounts(primary_account_id, /*force_notifications=*/true);
+}
+
std::string OAuth2TokenServiceDelegateAndroid::MapAccountIdToAccountName(
const std::string& account_id) const {
return account_tracker_service_->GetAccountInfo(account_id).email;
diff --git a/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.h b/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.h
index 9ecb1dbbdd3..3f8ced91674 100644
--- a/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.h
+++ b/chromium/components/signin/core/browser/oauth2_token_service_delegate_android.h
@@ -42,7 +42,9 @@ class OAuth2TokenServiceDelegateAndroid : public OAuth2TokenServiceDelegate {
// Called by the TestingProfile class to disable account validation in
// tests. This prevents the token service from trying to look up system
// accounts which requires special permission.
- static void set_is_testing_profile() { is_testing_profile_ = true; }
+ static void set_disable_interaction_with_system_accounts() {
+ disable_interaction_with_system_accounts_ = true;
+ }
// OAuth2TokenServiceDelegate overrides:
bool RefreshTokenIsAvailable(const std::string& account_id) const override;
@@ -74,6 +76,8 @@ class OAuth2TokenServiceDelegateAndroid : public OAuth2TokenServiceDelegate {
void LoadCredentials(const std::string& primary_account_id) override;
+ void ReloadAccountsFromSystem(const std::string& primary_account_id) override;
+
protected:
OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
const std::string& account_id,
@@ -105,10 +109,9 @@ class OAuth2TokenServiceDelegateAndroid : public OAuth2TokenServiceDelegate {
RT_LOADED
};
- // Return whether |signed_in_id| is valid and we have access
- // to all the tokens in |curr_ids|. If |force_notifications| is true,
- // TokenAvailable notifications will be sent anyway, even if the account was
- // already known.
+ // Return whether accounts are valid and we have access to all the tokens in
+ // |curr_ids|. If |force_notifications| is true, TokenAvailable notifications
+ // will be sent anyway, even if the account was already known.
bool ValidateAccounts(const std::string& signed_in_id,
const std::vector<std::string>& prev_ids,
const std::vector<std::string>& curr_ids,
@@ -124,7 +127,7 @@ class OAuth2TokenServiceDelegateAndroid : public OAuth2TokenServiceDelegate {
AccountTrackerService* account_tracker_service_;
RefreshTokenLoadStatus fire_refresh_token_loaded_;
- static bool is_testing_profile_;
+ static bool disable_interaction_with_system_accounts_;
DISALLOW_COPY_AND_ASSIGN(OAuth2TokenServiceDelegateAndroid);
};
diff --git a/chromium/components/signin/core/browser/profile_oauth2_token_service.h b/chromium/components/signin/core/browser/profile_oauth2_token_service.h
index c7c4ae65f87..55bd353fcb0 100644
--- a/chromium/components/signin/core/browser/profile_oauth2_token_service.h
+++ b/chromium/components/signin/core/browser/profile_oauth2_token_service.h
@@ -103,6 +103,12 @@ class ProfileOAuth2TokenService : public OAuth2TokenService,
all_credentials_loaded_ = loaded;
}
+ // Exposes the ability to update auth errors to tests.
+ void UpdateAuthErrorForTesting(const std::string& account_id,
+ const GoogleServiceAuthError& error) {
+ UpdateAuthError(account_id, error);
+ }
+
private:
friend class identity::IdentityManager;
diff --git a/chromium/components/signin/core/browser/resources/signin_index.html b/chromium/components/signin/core/browser/resources/signin_index.html
index 6d5db22669a..835d2d2c565 100644
--- a/chromium/components/signin/core/browser/resources/signin_index.html
+++ b/chromium/components/signin/core/browser/resources/signin_index.html
@@ -5,7 +5,7 @@
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
- <script src="chrome://signin-internals/strings.js"></script>
+ <script src="strings.js"></script>
<if expr="is_ios">
<!-- TODO(crbug.com/487000): Remove this once injected by the web layer. -->
<script src="chrome://resources/js/ios/web_ui.js"></script>
@@ -109,8 +109,7 @@
</div>
</div>
- <script src="chrome://resources/js/i18n_template.js"></script>
<script src="chrome://resources/js/jstemplate_compiled.js"></script>
- <script src="chrome://signin-internals/signin_internals.js"></script>
+ <script src="signin_internals.js"></script>
</body>
</html>
diff --git a/chromium/components/signin/core/browser/signin_client.h b/chromium/components/signin/core/browser/signin_client.h
index 6b4391045c9..0b288a6213c 100644
--- a/chromium/components/signin/core/browser/signin_client.h
+++ b/chromium/components/signin/core/browser/signin_client.h
@@ -61,11 +61,6 @@ class SigninClient : public KeyedService {
// Signin component is being used.
virtual std::string GetProductVersion() = 0;
- // Called after Google signin has succeeded and GetUserInfo has returned.
- virtual void PostSignedIn(const std::string& account_id,
- const std::string& username,
- const std::string& password) {}
-
// Called before Google sign-out started. Implementers must run the
// |on_signout_decision_reached|, passing a SignoutDecision to allow/disallow
// sign-out to continue. When to disallow sign-out is implementation specific.
@@ -92,7 +87,7 @@ class SigninClient : public KeyedService {
content_settings::Observer* observer) = 0;
// Execute |callback| if and when there is a network connection.
- virtual void DelayNetworkCall(const base::Closure& callback) = 0;
+ virtual void DelayNetworkCall(base::OnceClosure callback) = 0;
// Creates a new platform-specific GaiaAuthFetcher.
virtual std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher(
@@ -100,9 +95,6 @@ class SigninClient : public KeyedService {
gaia::GaiaSource source,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) = 0;
- // Called once the credentials has been copied to another SigninManager.
- virtual void AfterCredentialsCopied() {}
-
// Schedules migration to happen at next startup.
virtual void SetReadyForDiceMigration(bool is_ready) {}
};
diff --git a/chromium/components/signin/core/browser/signin_error_controller.cc b/chromium/components/signin/core/browser/signin_error_controller.cc
index 6f1859ea21e..21c5c29f3c4 100644
--- a/chromium/components/signin/core/browser/signin_error_controller.cc
+++ b/chromium/components/signin/core/browser/signin_error_controller.cc
@@ -115,13 +115,13 @@ void SigninErrorController::OnEndBatchOfRefreshTokenStateChanges() {
}
void SigninErrorController::OnErrorStateOfRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info,
+ const CoreAccountInfo& account_info,
const GoogleServiceAuthError& error) {
Update();
}
void SigninErrorController::OnPrimaryAccountSet(
- const AccountInfo& primary_account_info) {
+ const CoreAccountInfo& primary_account_info) {
// Ignore updates to the primary account if not in PRIMARY_ACCOUNT mode.
if (account_mode_ != AccountMode::PRIMARY_ACCOUNT)
return;
@@ -130,7 +130,7 @@ void SigninErrorController::OnPrimaryAccountSet(
}
void SigninErrorController::OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) {
+ const CoreAccountInfo& previous_primary_account_info) {
// Ignore updates to the primary account if not in PRIMARY_ACCOUNT mode.
if (account_mode_ != AccountMode::PRIMARY_ACCOUNT)
return;
diff --git a/chromium/components/signin/core/browser/signin_error_controller.h b/chromium/components/signin/core/browser/signin_error_controller.h
index 334e426db23..6edab303012 100644
--- a/chromium/components/signin/core/browser/signin_error_controller.h
+++ b/chromium/components/signin/core/browser/signin_error_controller.h
@@ -67,11 +67,12 @@ class SigninErrorController : public KeyedService,
// identity::IdentityManager::Observer:
void OnEndBatchOfRefreshTokenStateChanges() override;
void OnErrorStateOfRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info,
+ const CoreAccountInfo& account_info,
const GoogleServiceAuthError& error) override;
- void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
+ void OnPrimaryAccountSet(
+ const CoreAccountInfo& primary_account_info) override;
void OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) override;
+ const CoreAccountInfo& previous_primary_account_info) override;
const AccountMode account_mode_;
identity::IdentityManager* identity_manager_;
diff --git a/chromium/components/signin/core/browser/signin_header_helper.cc b/chromium/components/signin/core/browser/signin_header_helper.cc
index 741ffbbf9b7..3be4ed58894 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper.cc
@@ -107,7 +107,7 @@ std::string BuildMirrorRequestCookieIfPossible(
}
SigninHeaderHelper::SigninHeaderHelper(const std::string& histogram_suffix)
- : histogram_suffix_(histogram_suffix){};
+ : histogram_suffix_(histogram_suffix) {}
SigninHeaderHelper::~SigninHeaderHelper() = default;
bool SigninHeaderHelper::AppendOrRemoveRequestHeader(
@@ -188,15 +188,12 @@ bool AppendOrRemoveDiceRequestHeader(
const GURL& redirect_url,
const std::string& account_id,
bool sync_enabled,
- bool sync_has_auth_error,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
const std::string& device_id) {
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
const GURL& url = redirect_url.is_empty() ? request->GetUrl() : redirect_url;
- DiceHeaderHelper dice_helper(
- !account_id.empty() && sync_has_auth_error && sync_enabled,
- account_consistency);
+ DiceHeaderHelper dice_helper(account_consistency);
std::string dice_header_value;
if (dice_helper.ShouldBuildRequestHeader(url, cookie_settings)) {
dice_header_value = dice_helper.BuildRequestHeader(
diff --git a/chromium/components/signin/core/browser/signin_header_helper.h b/chromium/components/signin/core/browser/signin_header_helper.h
index ceaad2fc77f..fdeb38a4abd 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.h
+++ b/chromium/components/signin/core/browser/signin_header_helper.h
@@ -40,6 +40,8 @@ extern const char kDiceResponseHeader[];
// The ServiceType specified by Gaia in the response header accompanying the 204
// response. This indicates the action Chrome is supposed to lead the user to
// perform.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin
enum GAIAServiceType {
GAIA_SERVICE_TYPE_NONE = 0, // No Gaia response header.
GAIA_SERVICE_TYPE_SIGNOUT, // Logout all existing sessions.
@@ -235,7 +237,6 @@ bool AppendOrRemoveDiceRequestHeader(
const GURL& redirect_url,
const std::string& account_id,
bool sync_enabled,
- bool sync_has_auth_error,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
const std::string& device_id);
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 1697fd9bcd2..1002e880621 100644
--- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -9,7 +9,9 @@
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
+#include "build/build_config.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/prefs/pref_member.h"
#include "components/signin/core/browser/account_consistency_method.h"
@@ -68,8 +70,7 @@ class SigninHeaderHelperTest : public testing::Test {
&request_adapter, GURL(), account_id, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT);
AppendOrRemoveDiceRequestHeader(&request_adapter, GURL(), account_id,
- sync_enabled_, sync_has_auth_error_,
- account_consistency_,
+ sync_enabled_, account_consistency_,
cookie_settings_.get(), device_id_);
return url_request;
}
@@ -115,7 +116,6 @@ class SigninHeaderHelperTest : public testing::Test {
base::test::ScopedTaskEnvironment task_environment_;
bool sync_enabled_ = false;
- bool sync_has_auth_error_ = false;
std::string device_id_ = kTestDeviceId;
AccountConsistencyMethod account_consistency_ =
AccountConsistencyMethod::kDisabled;
@@ -141,12 +141,29 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
// Tests that no Mirror request is returned when the user is not signed in (no
// account id), for non Chrome OS platforms.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
+#if defined(OS_ANDROID)
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(kMiceFeature);
+#endif
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", "");
}
#endif
+#if defined(OS_ANDROID)
+// Tests that Mirror request is returned on Android with Mice.
+TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdMice) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(kMiceFeature);
+ account_consistency_ = AccountConsistencyMethod::kMirror;
+ CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "",
+ "mode=0,enable_account_consistency=true");
+ CheckMirrorCookieRequest(GURL("https://docs.google.com"), "",
+ "mode=0:enable_account_consistency=true");
+}
+#endif
+
// Tests that no Mirror request is returned when the cookies aren't allowed to
// be set.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
diff --git a/chromium/components/signin/core/browser/signin_manager.cc b/chromium/components/signin/core/browser/signin_manager.cc
index 5ac21878b9b..79b00b7f0c3 100644
--- a/chromium/components/signin/core/browser/signin_manager.cc
+++ b/chromium/components/signin/core/browser/signin_manager.cc
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -16,7 +17,6 @@
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/identity_utils.h"
-#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/signin/core/browser/signin_pref_names.h"
#include "google_apis/gaia/gaia_auth_util.h"
@@ -32,112 +32,13 @@ SigninManager::SigninManager(
GaiaCookieManagerService* cookie_manager_service,
signin::AccountConsistencyMethod account_consistency)
: SigninManagerBase(client, token_service, account_tracker_service),
- type_(SIGNIN_TYPE_NONE),
cookie_manager_service_(cookie_manager_service),
account_consistency_(account_consistency),
- signin_manager_signed_in_(false),
- user_info_fetched_by_account_tracker_(false),
weak_pointer_factory_(this) {}
SigninManager::~SigninManager() {}
-std::string SigninManager::SigninTypeToString(SigninManager::SigninType type) {
- switch (type) {
- case SIGNIN_TYPE_NONE:
- return "No Signin";
- case SIGNIN_TYPE_WITH_REFRESH_TOKEN:
- return "With refresh token";
- case SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN:
- return "Without refresh token";
- }
-
- NOTREACHED();
- return std::string();
-}
-
-bool SigninManager::PrepareForSignin(SigninType type,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password) {
- std::string account_id =
- account_tracker_service()->PickAccountIdForAccount(gaia_id, username);
- DCHECK(!account_id.empty());
- DCHECK(possibly_invalid_account_id_.empty() ||
- possibly_invalid_account_id_ == account_id);
-
- if (!IsAllowedUsername(username)) {
- // Account is not allowed by admin policy.
- HandleAuthError(
- GoogleServiceAuthError(GoogleServiceAuthError::ACCOUNT_DISABLED));
- return false;
- }
-
- // This attempt is either 1) the user trying to establish initial sync, or
- // 2) trying to refresh credentials for an existing username. If it is 2, we
- // need to try again, but take care to leave state around tracking that the
- // user has successfully signed in once before with this username, so that on
- // restart we don't think sync setup has never completed.
- ClearTransientSigninData();
- type_ = type;
- possibly_invalid_account_id_.assign(account_id);
- possibly_invalid_gaia_id_.assign(gaia_id);
- possibly_invalid_email_.assign(username);
- password_.assign(password);
- signin_manager_signed_in_ = false;
- user_info_fetched_by_account_tracker_ = false;
- return true;
-}
-
-void SigninManager::StartSignInWithRefreshToken(
- const std::string& refresh_token,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password,
- OAuthTokenFetchedCallback callback) {
- DCHECK(!IsAuthenticated());
- SigninType signin_type = refresh_token.empty()
- ? SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN
- : SIGNIN_TYPE_WITH_REFRESH_TOKEN;
- if (!PrepareForSignin(signin_type, gaia_id, username, password)) {
- return;
- }
-
- // Store the refresh token.
- temp_refresh_token_ = refresh_token;
-
- if (!callback.is_null()) {
- // Callback present, let the caller complete the pending sign-in.
- std::move(callback).Run(temp_refresh_token_);
- } else {
- // No callback, so just complete the pending signin.
- CompletePendingSignin();
- }
-}
-
-void SigninManager::CopyCredentialsFrom(const SigninManager& source) {
- DCHECK_NE(this, &source);
- possibly_invalid_account_id_ = source.possibly_invalid_account_id_;
- possibly_invalid_gaia_id_ = source.possibly_invalid_gaia_id_;
- possibly_invalid_email_ = source.possibly_invalid_email_;
- temp_refresh_token_ = source.temp_refresh_token_;
- password_ = source.password_;
- source.signin_client()->AfterCredentialsCopied();
-}
-
-void SigninManager::ClearTransientSigninData() {
- DCHECK(IsInitialized());
-
- possibly_invalid_account_id_.clear();
- possibly_invalid_gaia_id_.clear();
- possibly_invalid_email_.clear();
- password_.clear();
- type_ = SIGNIN_TYPE_NONE;
- temp_refresh_token_.clear();
-}
-
void SigninManager::HandleAuthError(const GoogleServiceAuthError& error) {
- ClearTransientSigninData();
-
for (auto& observer : observer_list_)
observer.GoogleSigninFailed(error);
}
@@ -186,18 +87,6 @@ void SigninManager::OnSignoutDecisionReached(
signin_metrics::LogSignout(signout_source_metric, signout_delete_metric);
if (!IsAuthenticated()) {
- if (AuthInProgress()) {
- // If the user is in the process of signing in, then treat a call to
- // SignOut as a cancellation request.
- GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
- HandleAuthError(error);
- } else {
- // Clean up our transient data and exit if we aren't signed in.
- // This avoids a perf regression from clearing out the TokenDB if
- // SignOut() is invoked on startup to clean up any incomplete previous
- // signin attempts.
- ClearTransientSigninData();
- }
return;
}
@@ -208,8 +97,6 @@ void SigninManager::OnSignoutDecisionReached(
return;
}
- ClearTransientSigninData();
-
AccountInfo account_info = GetAuthenticatedAccountInfo();
const std::string account_id = GetAuthenticatedAccountId();
const std::string username = account_info.email;
@@ -268,11 +155,9 @@ void SigninManager::FinalizeInitBeforeLoadingRefreshTokens(
base::Bind(&SigninManager::OnSigninAllowedPrefChanged,
base::Unretained(this)));
- std::string account_id =
- signin_client()->GetPrefs()->GetString(prefs::kGoogleServicesAccountId);
- std::string user = account_id.empty() ? std::string() :
- account_tracker_service()->GetAccountInfo(account_id).email;
- if (!account_id.empty() && (!IsAllowedUsername(user) || !IsSigninAllowed())) {
+ AccountInfo account_info = GetAuthenticatedAccountInfo();
+ if (!account_info.account_id.empty() &&
+ (!IsAllowedUsername(account_info.email) || !IsSigninAllowed())) {
// User is signed in, but the username is invalid or signin is no longer
// allowed, so the user must be sign out.
//
@@ -294,8 +179,6 @@ void SigninManager::FinalizeInitBeforeLoadingRefreshTokens(
signin_metrics::SignoutDelete::IGNORE_METRIC);
}
- account_tracker_service()->AddObserver(this);
-
// It is important to only load credentials after starting to observe the
// token service.
token_service()->AddObserver(this);
@@ -303,7 +186,6 @@ void SigninManager::FinalizeInitBeforeLoadingRefreshTokens(
void SigninManager::Shutdown() {
token_service()->RemoveObserver(this);
- account_tracker_service()->RemoveObserver(this);
local_state_pref_registrar_.RemoveAll();
SigninManagerBase::Shutdown();
}
@@ -327,7 +209,7 @@ void SigninManager::SetSigninAllowed(bool allowed) {
}
void SigninManager::OnSigninAllowedPrefChanged() {
- if (!IsSigninAllowed() && (IsAuthenticated() || AuthInProgress()))
+ if (!IsSigninAllowed() && IsAuthenticated())
SignOut(signin_metrics::SIGNOUT_PREF_CHANGED,
signin_metrics::SignoutDelete::IGNORE_METRIC);
}
@@ -348,92 +230,31 @@ bool SigninManager::IsAllowedUsername(const std::string& username) const {
return identity::IsUsernameAllowedByPattern(username, pattern);
}
-bool SigninManager::AuthInProgress() const {
- return !possibly_invalid_account_id_.empty();
-}
-
-const std::string& SigninManager::GetAccountIdForAuthInProgress() const {
- return possibly_invalid_account_id_;
-}
-
-const std::string& SigninManager::GetGaiaIdForAuthInProgress() const {
- return possibly_invalid_gaia_id_;
-}
-
-const std::string& SigninManager::GetUsernameForAuthInProgress() const {
- return possibly_invalid_email_;
-}
-
-void SigninManager::MergeSigninCredentialIntoCookieJar() {
- if (account_consistency_ == signin::AccountConsistencyMethod::kMirror)
- return;
-
- if (!IsAuthenticated())
- return;
-
- cookie_manager_service_->AddAccountToCookie(GetAuthenticatedAccountId(),
- gaia::GaiaSource::kSigninManager);
-}
-
-void SigninManager::CompletePendingSignin() {
- DCHECK(!possibly_invalid_account_id_.empty());
- OnSignedIn();
-
- DCHECK(IsAuthenticated());
-
- if (!temp_refresh_token_.empty()) {
- std::string account_id = GetAuthenticatedAccountId();
- token_service()->UpdateCredentials(
- account_id, temp_refresh_token_,
- signin_metrics::SourceForRefreshTokenOperation::
- kSigninManager_LegacyPreDiceSigninFlow);
- temp_refresh_token_.clear();
- }
- MergeSigninCredentialIntoCookieJar();
-}
-
void SigninManager::OnExternalSigninCompleted(const std::string& username) {
AccountInfo info =
account_tracker_service()->FindAccountInfoByEmail(username);
DCHECK(!info.gaia.empty());
DCHECK(!info.email.empty());
- possibly_invalid_account_id_ = info.account_id;
- possibly_invalid_gaia_id_ = info.gaia;
- possibly_invalid_email_ = info.email;
- OnSignedIn();
-}
-void SigninManager::OnSignedIn() {
bool reauth_in_progress = IsAuthenticated();
signin_client()->GetPrefs()->SetInt64(
prefs::kSignedInTime,
base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
- SetAuthenticatedAccountInfo(possibly_invalid_gaia_id_,
- possibly_invalid_email_);
- const std::string gaia_id = possibly_invalid_gaia_id_;
-
- possibly_invalid_account_id_.clear();
- possibly_invalid_gaia_id_.clear();
- possibly_invalid_email_.clear();
- signin_manager_signed_in_ = true;
+ SetAuthenticatedAccountInfo(info.gaia, info.email);
if (!reauth_in_progress)
FireGoogleSigninSucceeded();
signin_metrics::LogSigninProfile(signin_client()->IsFirstRun(),
signin_client()->GetInstallDate());
-
- PostSignedIn();
}
void SigninManager::FireGoogleSigninSucceeded() {
const AccountInfo account_info = GetAuthenticatedAccountInfo();
- for (auto& observer : observer_list_) {
+ for (auto& observer : observer_list_)
observer.GoogleSigninSucceeded(account_info);
- observer.GoogleSigninSucceededWithPassword(account_info, password_);
- }
}
void SigninManager::FireGoogleSignedOut(const AccountInfo& account_info) {
@@ -442,28 +263,6 @@ void SigninManager::FireGoogleSignedOut(const AccountInfo& account_info) {
}
}
-void SigninManager::PostSignedIn() {
- if (!signin_manager_signed_in_ || !user_info_fetched_by_account_tracker_)
- return;
-
- signin_client()->PostSignedIn(GetAuthenticatedAccountId(),
- GetAuthenticatedAccountInfo().email, password_);
- password_.clear();
-}
-
-void SigninManager::OnAccountUpdated(const AccountInfo& info) {
- if (!info.IsValid())
- return;
-
- user_info_fetched_by_account_tracker_ = true;
- PostSignedIn();
-}
-
-void SigninManager::OnAccountUpdateFailed(const std::string& account_id) {
- user_info_fetched_by_account_tracker_ = true;
- PostSignedIn();
-}
-
void SigninManager::OnRefreshTokensLoaded() {
token_service()->RemoveObserver(this);
diff --git a/chromium/components/signin/core/browser/signin_manager.h b/chromium/components/signin/core/browser/signin_manager.h
index cf3bbc158b3..edeebef8ea3 100644
--- a/chromium/components/signin/core/browser/signin_manager.h
+++ b/chromium/components/signin/core/browser/signin_manager.h
@@ -6,11 +6,6 @@
// which user is signed in. See SigninManagerBase for full description of
// responsibilities. The class defined in this file provides functionality
// required by all platforms except Chrome OS.
-//
-// When a user is signed in, a ClientLogin request is run on their behalf.
-// Auth tokens are fetched from Google and the results are stored in the
-// TokenService.
-// TODO(tim): Bug 92948, 226464. ClientLogin is all but gone from use.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_MANAGER_H_
@@ -40,7 +35,6 @@
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_client.h"
-#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "net/cookies/canonical_cookie.h"
@@ -54,16 +48,8 @@ class IdentityManager;
} // namespace identity
class SigninManager : public SigninManagerBase,
- public AccountTrackerService::Observer,
public OAuth2TokenService::Observer {
public:
- // The callback invoked once the OAuth token has been fetched during signin,
- // but before the profile transitions to the "signed-in" state. This allows
- // callers to load policy and prompt the user appropriately before completing
- // signin. The callback is passed the just-fetched OAuth login refresh token.
- using OAuthTokenFetchedCallback =
- base::OnceCallback<void(const std::string&)>;
-
// Used to remove accounts from the token service and the account tracker.
enum class RemoveAccountsOption {
// Do not remove accounts.
@@ -93,25 +79,6 @@ class SigninManager : public SigninManagerBase,
// are actually SigninManager instances.
static SigninManager* FromSigninManagerBase(SigninManagerBase* manager);
- // Attempt to sign in this user with a refresh token.
- // If |refresh_token| is not empty, then SigninManager will add it to the
- // |token_service_| when the sign-in flow is completed.
- // If non-null, the passed |oauth_fetched_callback| callback is invoked once
- // sign-in has been completed.
- // The callback should invoke SignOut() or CompletePendingSignin() to either
- // continue or cancel the in-process signin.
- virtual void StartSignInWithRefreshToken(
- const std::string& refresh_token,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password,
- OAuthTokenFetchedCallback oauth_fetched_callback);
-
- // Copies auth credentials from one SigninManager to this one. This is used
- // when creating a new profile during the signin process to transfer the
- // in-progress credentials to the new profile.
- virtual void CopyCredentialsFrom(const SigninManager& source);
-
// Signs a user out, removing the preference, erasing all keys
// associated with the authenticated user, and canceling all auth in progress.
// On mobile and on desktop pre-DICE, this also removes all accounts from
@@ -144,21 +111,12 @@ class SigninManager : public SigninManagerBase,
void Shutdown() override;
- // If applicable, merge the signed in account into the cookie jar.
- void MergeSigninCredentialIntoCookieJar();
-
- // Invoked from an OAuthTokenFetchedCallback to complete user signin.
- virtual void CompletePendingSignin();
-
// Invoked from SigninManagerAndroid to indicate that the sign-in process
// has completed for the email |username|. SigninManager assumes that
// |username| can be used to look up the corresponding account_id and gaia_id
// for this email.
void OnExternalSigninCompleted(const std::string& username);
- // Returns true if there's a signin in progress.
- bool AuthInProgress() const override;
-
// Returns whether sign-in is allowed.
// TODO(crbug.com/806778): Remove method in super-class.
bool IsSigninAllowed() const override;
@@ -166,18 +124,6 @@ class SigninManager : public SigninManagerBase,
// Sets whether sign-in is allowed or not.
void SetSigninAllowed(bool allowed);
- // If an authentication is in progress, return the account id being
- // authenticated. Returns an empty string if no auth is in progress.
- const std::string& GetAccountIdForAuthInProgress() const;
-
- // If an authentication is in progress, return the gaia id being
- // authenticated. Returns an empty string if no auth is in progress.
- const std::string& GetGaiaIdForAuthInProgress() const;
-
- // If an authentication is in progress, return the username being
- // authenticated. Returns an empty string if no auth is in progress.
- const std::string& GetUsernameForAuthInProgress() const;
-
protected:
// The sign out process which is started by SigninClient::PreSignOut()
virtual void OnSignoutDecisionReached(
@@ -187,55 +133,19 @@ class SigninManager : public SigninManagerBase,
SigninClient::SignoutDecision signout_decision);
private:
- enum SigninType {
- SIGNIN_TYPE_NONE,
- SIGNIN_TYPE_WITH_REFRESH_TOKEN,
- SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN
- };
-
- std::string SigninTypeToString(SigninType type);
- friend class FakeSigninManager;
friend class identity::IdentityManager;
FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, Prohibited);
FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, TestAlternateWildcard);
- // Called to setup the transient signin data during one of the
- // StartSigninXXX methods. |type| indicates which of the methods is being
- // used to perform the signin while |username| and |password| identify the
- // account to be signed in. Returns false and generates an auth error if the
- // passed |username| is not allowed by policy. |gaia_id| is the obfuscated
- // gaia id corresponding to |username|.
- bool PrepareForSignin(SigninType type,
- const std::string& gaia_id,
- const std::string& username,
- const std::string& password);
-
- // Persists |account_id| as the currently signed-in account, and triggers
- // a sign-in success notification.
- void OnSignedIn();
-
// Send all observers |GoogleSigninSucceeded| notifications.
void FireGoogleSigninSucceeded();
// Send all observers |GoogleSignedOut| notifications.
void FireGoogleSignedOut(const AccountInfo& account_info);
- // Waits for the AccountTrackerService, then sends GoogleSigninSucceeded to
- // the client and clears the local password.
- void PostSignedIn();
-
- // AccountTrackerService::Observer:
- void OnAccountUpdated(const AccountInfo& info) override;
- void OnAccountUpdateFailed(const std::string& account_id) override;
-
// OAuth2TokenService::Observer:
void OnRefreshTokensLoaded() override;
- // Called when a new request to re-authenticate a user is in progress.
- // Will clear in memory data but leaves the db as such so when the browser
- // restarts we can use the old token(which might throw a password error).
- void ClearTransientSigninData();
-
// Called to handle an error from a GAIA auth fetch. Sets the last error
// to |error|, sends out a notification of login failure and clears the
// transient signin data.
@@ -252,20 +162,6 @@ class SigninManager : public SigninManagerBase,
// Returns true if the passed username is allowed by policy.
bool IsAllowedUsername(const std::string& username) const;
- std::string possibly_invalid_account_id_;
- std::string possibly_invalid_gaia_id_;
- std::string possibly_invalid_email_;
- std::string password_; // This is kept empty whenever possible.
-
- // The type of sign being performed. This value is valid only between a call
- // to one of the StartSigninXXX methods and when the sign in is either
- // successful or not.
- SigninType type_;
-
- // Temporarily saves the oauth2 refresh token. It will be passed to the
- // token service so that it does not need to mint new ones.
- std::string temp_refresh_token_;
-
// Object used to use the token to push a GAIA cookie into the cookie jar.
GaiaCookieManagerService* cookie_manager_service_;
@@ -278,12 +174,6 @@ class SigninManager : public SigninManagerBase,
signin::AccountConsistencyMethod account_consistency_;
- // Two gate conditions for when PostSignedIn should be called. Verify
- // that the SigninManager has reached OnSignedIn() and the AccountTracker
- // has completed calling GetUserInfo.
- bool signin_manager_signed_in_;
- bool user_info_fetched_by_account_tracker_;
-
base::WeakPtrFactory<SigninManager> weak_pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(SigninManager);
diff --git a/chromium/components/signin/core/browser/signin_manager_base.cc b/chromium/components/signin/core/browser/signin_manager_base.cc
index 6012474fe02..a6538b36674 100644
--- a/chromium/components/signin/core/browser/signin_manager_base.cc
+++ b/chromium/components/signin/core/browser/signin_manager_base.cc
@@ -51,8 +51,7 @@ void SigninManagerBase::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(prefs::kGoogleServicesUserAccountId,
std::string());
registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
- registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList,
- std::make_unique<base::ListValue>());
+ registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
registry->RegisterInt64Pref(prefs::kSignedInTime,
base::Time().ToInternalValue());
@@ -230,15 +229,6 @@ bool SigninManagerBase::IsAuthenticated() const {
return !authenticated_account_id_.empty();
}
-bool SigninManagerBase::AuthInProgress() const {
- // SigninManagerBase never kicks off auth processes itself.
- return false;
-}
-
-void SigninManagerBase::Shutdown() {
- on_shutdown_callback_list_.Notify();
-}
-
void SigninManagerBase::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
diff --git a/chromium/components/signin/core/browser/signin_manager_base.h b/chromium/components/signin/core/browser/signin_manager_base.h
index f75a647f315..b3857e38a5a 100644
--- a/chromium/components/signin/core/browser/signin_manager_base.h
+++ b/chromium/components/signin/core/browser/signin_manager_base.h
@@ -35,7 +35,6 @@
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_member.h"
#include "components/signin/core/browser/account_info.h"
-#include "components/signin/core/browser/signin_internals_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
class AccountTrackerService;
@@ -55,22 +54,6 @@ class SigninManagerBase : public KeyedService {
// This method is not called during a reauth.
virtual void GoogleSigninSucceeded(const AccountInfo& account_info) {}
- // Called when a user signs into Google services such as sync. Also passes
- // the password of the Google account that was used to sign in.
- // This method is not called during a reauth.
- //
- // Observers should override |GoogleSigninSucceeded| if they are not
- // interested in the password thas was used during the sign-in.
- //
- // Note: The password is always empty on mobile as the user signs in to
- // Chrome with accounts that were added to the device, so Chrome does not
- // have access to the password.
- // DEPRECATED: password will be empty if login is using DICE workflow; the
- // method will be removed once all login is using the DICE workflow.
- virtual void GoogleSigninSucceededWithPassword(
- const AccountInfo& account_info,
- const std::string& password) {}
-
// Called when the currently signed-in user for a user has been signed out.
virtual void GoogleSignedOut(const AccountInfo& account_info) {}
@@ -78,10 +61,8 @@ class SigninManagerBase : public KeyedService {
virtual ~Observer() {}
private:
- // SigninManagers that fire |GoogleSigninSucceededWithPassword|
- // notifications.
+ // SigninManagers that fire notifications.
friend class SigninManager;
- friend class FakeSigninManager;
};
// On non-ChromeOS platforms, SigninManagerBase should only be instantiated
@@ -144,31 +125,15 @@ class SigninManagerBase : public KeyedService {
// Returns true if there is an authenticated user.
bool IsAuthenticated() const;
- // Returns true if there's a signin in progress.
- virtual bool AuthInProgress() const;
-
- // KeyedService implementation.
- void Shutdown() override;
-
// Methods to register or remove observers of signin.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- // Gives access to the SigninClient instance associated with this instance.
+ protected:
SigninClient* signin_client() const { return client_; }
ProfileOAuth2TokenService* token_service() const { return token_service_; }
- // Adds a callback that will be called when this instance is shut down.Not
- // intended for general usage, but rather for usage only by the Identity
- // Service implementation during the time period of conversion of Chrome to
- // use the Identity Service.
- std::unique_ptr<base::CallbackList<void()>::Subscription>
- RegisterOnShutdownCallback(const base::Closure& cb) {
- return on_shutdown_callback_list_.Add(cb);
- }
-
- protected:
AccountTrackerService* account_tracker_service() const {
return account_tracker_service_;
}
@@ -197,9 +162,6 @@ class SigninManagerBase : public KeyedService {
base::ObserverList<Observer, true>::Unchecked observer_list_;
private:
- friend class FakeSigninManagerBase;
- friend class FakeSigninManager;
-
// Added only to allow SigninManager to call the SigninManagerBase
// constructor while disallowing any ad-hoc subclassing of
// SigninManagerBase.
diff --git a/chromium/components/signin/core/browser/signin_manager_unittest.cc b/chromium/components/signin/core/browser/signin_manager_unittest.cc
index 5cb99d8efd2..1751a43de76 100644
--- a/chromium/components/signin/core/browser/signin_manager_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_manager_unittest.cc
@@ -21,13 +21,13 @@
#include "components/signin/core/browser/account_consistency_method.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/device_id_helper.h"
-#include "components/signin/core/browser/fake_account_fetcher_service.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
+#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_pref_names.h"
+#include "components/signin/core/browser/test_image_decoder.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "google_apis/gaia/fake_oauth2_token_service_delegate.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/cookies/cookie_monster.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -40,14 +40,12 @@ class TestSigninManagerObserver : public SigninManagerBase::Observer {
TestSigninManagerObserver()
: num_failed_signins_(0),
num_successful_signins_(0),
- num_successful_signins_with_password_(0),
num_signouts_(0) {}
~TestSigninManagerObserver() override {}
int num_failed_signins_;
int num_successful_signins_;
- int num_successful_signins_with_password_;
int num_signouts_;
private:
@@ -60,11 +58,6 @@ class TestSigninManagerObserver : public SigninManagerBase::Observer {
num_successful_signins_++;
}
- void GoogleSigninSucceededWithPassword(const AccountInfo& account_info,
- const std::string& password) override {
- num_successful_signins_with_password_++;
- }
-
void GoogleSignedOut(const AccountInfo& account_info) override {
num_signouts_++;
}
@@ -76,7 +69,8 @@ class SigninManagerTest : public testing::Test {
public:
SigninManagerTest()
: test_signin_client_(&user_prefs_),
- token_service_(&user_prefs_),
+ token_service_(&user_prefs_,
+ std::make_unique<FakeOAuth2TokenServiceDelegate>()),
cookie_manager_service_(&token_service_, &test_signin_client_),
account_consistency_(signin::AccountConsistencyMethod::kDisabled) {
AccountFetcherService::RegisterPrefs(user_prefs_.registry());
@@ -105,7 +99,7 @@ class SigninManagerTest : public testing::Test {
TestSigninClient* signin_client() { return &test_signin_client_; }
AccountTrackerService* account_tracker() { return &account_tracker_; }
- FakeAccountFetcherService* account_fetcher() { return &account_fetcher_; }
+ AccountFetcherService* account_fetcher() { return &account_fetcher_; }
PrefService* prefs() { return &user_prefs_; }
// Seed the account tracker with information from logged in user. Normally
@@ -145,23 +139,17 @@ class SigninManagerTest : public testing::Test {
// Should go into token service and stop.
EXPECT_EQ(1, test_observer_.num_successful_signins_);
- EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
EXPECT_EQ(0, test_observer_.num_failed_signins_);
}
- void CompleteSigninCallback(const std::string& oauth_token) {
- oauth_tokens_fetched_.push_back(oauth_token);
- manager_->CompletePendingSignin();
- }
-
base::test::ScopedTaskEnvironment task_environment_;
sync_preferences::TestingPrefServiceSyncable user_prefs_;
TestingPrefServiceSimple local_state_;
TestSigninClient test_signin_client_;
- FakeProfileOAuth2TokenService token_service_;
+ ProfileOAuth2TokenService token_service_;
AccountTrackerService account_tracker_;
GaiaCookieManagerService cookie_manager_service_;
- FakeAccountFetcherService account_fetcher_;
+ AccountFetcherService account_fetcher_;
std::unique_ptr<SigninManager> manager_;
TestSigninManagerObserver test_observer_;
std::vector<std::string> oauth_tokens_fetched_;
@@ -169,73 +157,11 @@ class SigninManagerTest : public testing::Test {
signin::AccountConsistencyMethod account_consistency_;
};
-TEST_F(SigninManagerTest, SignInWithRefreshToken) {
- CreateSigninManager();
- EXPECT_FALSE(manager_->IsAuthenticated());
-
- std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
- manager_->StartSignInWithRefreshToken(
- "rt", "gaia_id", "user@gmail.com", "password",
- SigninManager::OAuthTokenFetchedCallback());
-
- ExpectSignInWithRefreshTokenSuccess();
-
- // Should persist across resets.
- ShutDownManager();
- CreateSigninManager();
- EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
-}
-
-TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
- CreateSigninManager();
- EXPECT_FALSE(manager_->IsAuthenticated());
-
- // Since the password is empty, must verify the gaia cookies first.
- manager_->StartSignInWithRefreshToken(
- "rt", "gaia_id", "user@gmail.com", "password",
- base::BindOnce(&SigninManagerTest::CompleteSigninCallback,
- base::Unretained(this)));
-
- ExpectSignInWithRefreshTokenSuccess();
- ASSERT_EQ(1U, oauth_tokens_fetched_.size());
- EXPECT_EQ(oauth_tokens_fetched_[0], "rt");
-}
-
-TEST_F(SigninManagerTest, SignInWithRefreshTokenCallsPostSignout) {
- CreateSigninManager();
- EXPECT_FALSE(manager_->IsAuthenticated());
-
- std::string gaia_id = "12345";
- std::string email = "user@google.com";
-
- account_tracker()->SeedAccountInfo(gaia_id, email);
- account_fetcher()->OnRefreshTokensLoaded();
-
- ASSERT_TRUE(signin_client()->get_signed_in_password().empty());
-
- manager_->StartSignInWithRefreshToken(
- "rt1", gaia_id, email, "password",
- SigninManager::OAuthTokenFetchedCallback());
-
- // PostSignedIn is not called until the AccountTrackerService returns.
- ASSERT_EQ("", signin_client()->get_signed_in_password());
-
- account_fetcher()->FakeUserInfoFetchSuccess(
- account_tracker()->PickAccountIdForAccount(gaia_id, email), email,
- gaia_id, "google.com", "full_name", "given_name", "locale",
- "http://www.google.com");
-
- // AccountTracker and SigninManager are both done and PostSignedIn was called.
- ASSERT_EQ("password", signin_client()->get_signed_in_password());
-
- ExpectSignInWithRefreshTokenSuccess();
-}
-
TEST_F(SigninManagerTest, SignOut) {
CreateSigninManager();
- manager_->StartSignInWithRefreshToken(
- "rt", "gaia_id", "user@gmail.com", "password",
- SigninManager::OAuthTokenFetchedCallback());
+ std::string main_account_id =
+ AddToAccountTracker("account_id", "user@gmail.com");
+ manager_->OnExternalSigninCompleted("user@gmail.com");
manager_->SignOut(signin_metrics::SIGNOUT_TEST,
signin_metrics::SignoutDelete::IGNORE_METRIC);
EXPECT_FALSE(manager_->IsAuthenticated());
@@ -391,12 +317,10 @@ TEST_F(SigninManagerTest, ExternalSignIn) {
EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
EXPECT_EQ(0, test_observer_.num_successful_signins_);
- EXPECT_EQ(0, test_observer_.num_successful_signins_with_password_);
std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
manager_->OnExternalSigninCompleted("user@gmail.com");
EXPECT_EQ(1, test_observer_.num_successful_signins_);
- EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
EXPECT_EQ(0, test_observer_.num_failed_signins_);
EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
@@ -407,19 +331,16 @@ TEST_F(SigninManagerTest, ExternalSignIn_ReauthShouldNotSendNotification) {
EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
EXPECT_EQ(0, test_observer_.num_successful_signins_);
- EXPECT_EQ(0, test_observer_.num_successful_signins_with_password_);
std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
manager_->OnExternalSigninCompleted("user@gmail.com");
EXPECT_EQ(1, test_observer_.num_successful_signins_);
- EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
EXPECT_EQ(0, test_observer_.num_failed_signins_);
EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
manager_->OnExternalSigninCompleted("user@gmail.com");
EXPECT_EQ(1, test_observer_.num_successful_signins_);
- EXPECT_EQ(1, test_observer_.num_successful_signins_with_password_);
EXPECT_EQ(0, test_observer_.num_failed_signins_);
EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId());
@@ -427,10 +348,10 @@ TEST_F(SigninManagerTest, ExternalSignIn_ReauthShouldNotSendNotification) {
TEST_F(SigninManagerTest, SigninNotAllowed) {
std::string user("user@google.com");
- user_prefs_.SetString(prefs::kGoogleServicesAccountId, user);
+ std::string account_id = AddToAccountTracker("gaia_id", user);
+ user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id);
user_prefs_.SetBoolean(prefs::kSigninAllowed, false);
CreateSigninManager();
- AddToAccountTracker("gaia_id", user);
// Currently signing in is prohibited by policy, so should be signed out.
EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email);
EXPECT_EQ("", manager_->GetAuthenticatedAccountId());
diff --git a/chromium/components/signin/core/browser/signin_metrics.cc b/chromium/components/signin/core/browser/signin_metrics.cc
index 7c0bf8613fa..d2cdbef05ed 100644
--- a/chromium/components/signin/core/browser/signin_metrics.cc
+++ b/chromium/components/signin/core/browser/signin_metrics.cc
@@ -764,25 +764,6 @@ void LogSigninConfirmHistogramValue(ConfirmationUsage action) {
HISTOGRAM_CONFIRM_MAX);
}
-void LogXDevicePromoEligible(CrossDevicePromoEligibility metric) {
- UMA_HISTOGRAM_ENUMERATION(
- "Signin.XDevicePromo.Eligibility", metric,
- NUM_CROSS_DEVICE_PROMO_ELIGIBILITY_METRICS);
-}
-
-void LogXDevicePromoInitialized(CrossDevicePromoInitialized metric) {
- UMA_HISTOGRAM_ENUMERATION(
- "Signin.XDevicePromo.Initialized", metric,
- NUM_CROSS_DEVICE_PROMO_INITIALIZED_METRICS);
-}
-
-void LogBrowsingSessionDuration(const base::Time& previous_activity_time) {
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Signin.XDevicePromo.BrowsingSessionDuration",
- (base::Time::Now() - previous_activity_time).InMinutes(), 1,
- base::TimeDelta::FromDays(30).InMinutes(), 50);
-}
-
void LogAccountReconcilorStateOnGaiaResponse(AccountReconcilorState state) {
UMA_HISTOGRAM_ENUMERATION("Signin.AccountReconcilorState.OnGaiaResponse",
state, ACCOUNT_RECONCILOR_HISTOGRAM_COUNT);
diff --git a/chromium/components/signin/core/browser/signin_metrics.h b/chromium/components/signin/core/browser/signin_metrics.h
index dcd0aebc082..60f64b9f54a 100644
--- a/chromium/components/signin/core/browser/signin_metrics.h
+++ b/chromium/components/signin/core/browser/signin_metrics.h
@@ -209,43 +209,6 @@ enum AccountReauth {
HISTOGRAM_REAUTH_MAX
};
-// Enum values used for "Signin.XDevicePromo.Eligible" histogram, which tracks
-// the reasons for which a profile is or is not eligible for the promo.
-enum CrossDevicePromoEligibility {
- // The user is eligible for the promo.
- ELIGIBLE,
- // The profile has previously opted out of the promo.
- OPTED_OUT,
- // The profile is already signed in.
- SIGNED_IN,
- // The profile does not have a single, peristent GAIA cookie.
- NOT_SINGLE_GAIA_ACCOUNT,
- // Yet to determine how many devices the user has.
- UNKNOWN_COUNT_DEVICES,
- // An error was returned trying to determine the account's devices.
- ERROR_FETCHING_DEVICE_ACTIVITY,
- // The call to get device activity was throttled, and never executed.
- THROTTLED_FETCHING_DEVICE_ACTIVITY,
- // The user has no devices.
- ZERO_DEVICES,
- // The user has no device that was recently active.
- NO_ACTIVE_DEVICES,
- // Always last enumerated type.
- NUM_CROSS_DEVICE_PROMO_ELIGIBILITY_METRICS
-};
-
-// Enum reasons the CrossDevicePromo couldn't initialize, or that it succeeded.
-enum CrossDevicePromoInitialized {
- // The promo was initialized successfully.
- INITIALIZED,
- // The profile is opted out, so the promo didn't initialize.
- UNINITIALIZED_OPTED_OUT,
- // Unable to read the variations configuration.
- NO_VARIATIONS_CONFIG,
- // Always the last enumerated type.
- NUM_CROSS_DEVICE_PROMO_INITIALIZED_METRICS
-};
-
// Enum values used for "Signin.AccountReconcilorState.OnGaiaResponse"
// histogram, which records the state of the AccountReconcilor when GAIA returns
// a specific response.
@@ -417,12 +380,6 @@ void LogAuthError(const GoogleServiceAuthError& auth_error);
void LogSigninConfirmHistogramValue(ConfirmationUsage action);
-void LogXDevicePromoEligible(CrossDevicePromoEligibility metric);
-
-void LogXDevicePromoInitialized(CrossDevicePromoInitialized metric);
-
-void LogBrowsingSessionDuration(const base::Time& previous_activity_time);
-
// Records the AccountReconcilor |state| when GAIA returns a specific response.
// If |state| is different than ACCOUNT_RECONCILOR_OK it means the user will
// be shown a different set of accounts in the content-area and the settings UI.
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider.cc b/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
index 56d2db40df0..5bc15bf236d 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
@@ -12,7 +12,6 @@
#include "base/metrics/histogram.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "components/signin/core/browser/signin_manager.h"
SigninStatusMetricsProvider::SigninStatusMetricsProvider(
std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate,
@@ -29,8 +28,8 @@ SigninStatusMetricsProvider::SigninStatusMetricsProvider(
// Postpone the initialization until all threads are created.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&SigninStatusMetricsProvider::Initialize,
- weak_ptr_factory_.GetWeakPtr()));
+ FROM_HERE, base::BindOnce(&SigninStatusMetricsProvider::Initialize,
+ weak_ptr_factory_.GetWeakPtr()));
}
SigninStatusMetricsProvider::~SigninStatusMetricsProvider() {}
@@ -53,30 +52,30 @@ SigninStatusMetricsProvider::CreateInstance(
new SigninStatusMetricsProvider(std::move(delegate), false));
}
-void SigninStatusMetricsProvider::OnSigninManagerCreated(
- SigninManagerBase* manager) {
- // Whenever a new profile is created, a new SigninManagerBase will be created
+void SigninStatusMetricsProvider::OnIdentityManagerCreated(
+ identity::IdentityManager* identity_manager) {
+ // Whenever a new profile is created, a new IdentityManager will be created
// for it. This ensures that all sign-in or sign-out actions of all opened
// profiles are being monitored.
- scoped_observer_.Add(manager);
+ scoped_observer_.Add(identity_manager);
// If the status is unknown, it means this is the first created
- // SigninManagerBase and the corresponding profile should be the only opened
+ // IdentityManager and the corresponding profile should be the only opened
// profile.
if (signin_status() == UNKNOWN_SIGNIN_STATUS) {
- size_t signed_in_count = manager->IsAuthenticated() ? 1 : 0;
+ size_t signed_in_count = identity_manager->HasPrimaryAccount() ? 1 : 0;
UpdateInitialSigninStatus(1, signed_in_count);
}
}
-void SigninStatusMetricsProvider::OnSigninManagerShutdown(
- SigninManagerBase* manager) {
- if (scoped_observer_.IsObserving(manager))
- scoped_observer_.Remove(manager);
+void SigninStatusMetricsProvider::OnIdentityManagerShutdown(
+ identity::IdentityManager* identity_manager) {
+ if (scoped_observer_.IsObserving(identity_manager))
+ scoped_observer_.Remove(identity_manager);
}
-void SigninStatusMetricsProvider::GoogleSigninSucceeded(
- const AccountInfo& account_info) {
+void SigninStatusMetricsProvider::OnPrimaryAccountSet(
+ const CoreAccountInfo& account_info) {
SigninStatus recorded_signin_status = signin_status();
if (recorded_signin_status == ALL_PROFILES_NOT_SIGNED_IN) {
UpdateSigninStatus(MIXED_SIGNIN_STATUS);
@@ -87,8 +86,8 @@ void SigninStatusMetricsProvider::GoogleSigninSucceeded(
}
}
-void SigninStatusMetricsProvider::GoogleSignedOut(
- const AccountInfo& account_info) {
+void SigninStatusMetricsProvider::OnPrimaryAccountCleared(
+ const CoreAccountInfo& account_info) {
SigninStatus recorded_signin_status = signin_status();
if (recorded_signin_status == ALL_PROFILES_SIGNED_IN) {
UpdateSigninStatus(MIXED_SIGNIN_STATUS);
@@ -102,13 +101,14 @@ void SigninStatusMetricsProvider::GoogleSignedOut(
void SigninStatusMetricsProvider::Initialize() {
delegate_->Initialize();
- // Start observing all already-created SigninManagers.
- for (SigninManager* manager : delegate_->GetSigninManagersForAllAccounts()) {
+ // Start observing all already-created IdentityManagers.
+ for (identity::IdentityManager* manager :
+ delegate_->GetIdentityManagersForAllAccounts()) {
DCHECK(!scoped_observer_.IsObserving(manager));
scoped_observer_.Add(manager);
}
- // It is possible that when this object is created, no SigninManager is
+ // It is possible that when this object is created, no IdentityManager is
// created yet, for example, when Chrome is opened for the first time after
// installation on desktop, or when Chrome on Android is loaded into memory.
if (delegate_->GetStatusOfAllAccounts().num_accounts == 0) {
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider.h b/chromium/components/signin/core/browser/signin_status_metrics_provider.h
index f01dfe5f9ef..1a027dcc951 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider.h
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.h
@@ -14,9 +14,9 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "build/build_config.h"
-#include "components/signin/core/browser/signin_manager_base.h"
#include "components/signin/core/browser/signin_status_metrics_provider_base.h"
#include "components/signin/core/browser/signin_status_metrics_provider_delegate.h"
+#include "services/identity/public/cpp/identity_manager.h"
namespace metrics {
class ChromeUserMetricsExtension;
@@ -28,7 +28,7 @@ class SigninStatusMetricsProviderDelegate;
// record the value into a histogram before UMA log is uploaded on platform
// Windows, Linux, Mac and Android.
class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
- public SigninManagerBase::Observer {
+ public identity::IdentityManager::Observer {
public:
~SigninStatusMetricsProvider() override;
@@ -40,11 +40,11 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
static std::unique_ptr<SigninStatusMetricsProvider> CreateInstance(
std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate);
- // Update the sign-in status when a SigninManager is created.
- void OnSigninManagerCreated(SigninManagerBase* manager);
+ // Update the sign-in status when a IdentityManager is created.
+ void OnIdentityManagerCreated(identity::IdentityManager* identity_manager);
- // Update the sign-in status when a SigninManager is shut down.
- void OnSigninManagerShutdown(SigninManagerBase* manager);
+ // Update the sign-in status when a IdentityManager is shut down.
+ void OnIdentityManagerShutdown(identity::IdentityManager* identity_manager);
// Updates the initial sign-in status. For testing purpose only.
void UpdateInitialSigninStatusForTesting(size_t total_count,
@@ -57,8 +57,9 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest,
UpdateInitialSigninStatus);
FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest,
- GoogleSigninSucceeded);
- FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest, GoogleSignedOut);
+ OnPrimaryAccountSet);
+ FRIEND_TEST_ALL_PREFIXES(SigninStatusMetricsProviderTest,
+ OnPrimaryAccountCleared);
// The boolean |is_test| indicates whether or not this is an instance for
// testing purpose. If so, skip the initialization. Except for testing
@@ -68,9 +69,9 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate,
bool is_test);
- // SigninManagerBase::Observer:
- void GoogleSigninSucceeded(const AccountInfo& account_info) override;
- void GoogleSignedOut(const AccountInfo& account_info) override;
+ // IdentityManager::Observer:
+ void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
+ void OnPrimaryAccountCleared(const CoreAccountInfo& account_info) override;
// Obtain sign-in status and add observers.
void Initialize();
@@ -87,9 +88,9 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate_;
- // Used to track the SigninManagers that this instance is observing so that
+ // Used to track the IdentityManagers that this instance is observing so that
// this instance can be removed as an observer on its destruction.
- ScopedObserver<SigninManagerBase, SigninManagerBase::Observer>
+ ScopedObserver<identity::IdentityManager, identity::IdentityManager::Observer>
scoped_observer_;
// Whether the instance is for testing or not.
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider_delegate.h b/chromium/components/signin/core/browser/signin_status_metrics_provider_delegate.h
index f1c778b1904..763a8b7ccda 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider_delegate.h
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider_delegate.h
@@ -12,9 +12,12 @@
#include "base/macros.h"
#include "build/build_config.h"
-class SigninManager;
class SigninStatusMetricsProvider;
+namespace identity {
+class IdentityManager;
+}
+
// Provides information relating to the status of accounts in the embedder: how
// many there are, how many are open, and how many are signed in. Note that
// "open" is an embedder-defined concept; in some embedders, all accounts are
@@ -44,8 +47,9 @@ class SigninStatusMetricsProviderDelegate {
// Returns the status of all accounts.
virtual AccountsStatus GetStatusOfAllAccounts() = 0;
- // Returns the SigninManager instance (if any) associated with each account.
- virtual std::vector<SigninManager*> GetSigninManagersForAllAccounts() = 0;
+ // Returns the IdentityManager instance (if any) associated with each account.
+ virtual std::vector<identity::IdentityManager*>
+ GetIdentityManagersForAllAccounts() = 0;
protected:
SigninStatusMetricsProvider* owner() { return owner_; }
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc b/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
index 203e98a724c..974ad479504 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
@@ -22,34 +22,34 @@ TEST(SigninStatusMetricsProviderTest, UpdateInitialSigninStatus) {
metrics_provider.GetSigninStatusForTesting());
}
-TEST(SigninStatusMetricsProviderTest, GoogleSigninSucceeded) {
+TEST(SigninStatusMetricsProviderTest, OnPrimaryAccountSet) {
SigninStatusMetricsProvider metrics_provider(nullptr, true);
// Initial status is all signed out and then one of the profiles is signed in.
metrics_provider.UpdateInitialSigninStatus(2, 0);
- metrics_provider.GoogleSigninSucceeded(AccountInfo());
+ metrics_provider.OnPrimaryAccountSet(AccountInfo());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
// Initial status is mixed and then one of the profiles is signed in.
metrics_provider.UpdateInitialSigninStatus(2, 1);
- metrics_provider.GoogleSigninSucceeded(AccountInfo());
+ metrics_provider.OnPrimaryAccountSet(AccountInfo());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
}
-TEST(SigninStatusMetricsProviderTest, GoogleSignedOut) {
+TEST(SigninStatusMetricsProviderTest, OnPrimaryAccountCleared) {
SigninStatusMetricsProvider metrics_provider(nullptr, true);
// Initial status is all signed in and then one of the profiles is signed out.
metrics_provider.UpdateInitialSigninStatus(2, 2);
- metrics_provider.GoogleSignedOut(AccountInfo());
+ metrics_provider.OnPrimaryAccountCleared(AccountInfo());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
// Initial status is mixed and then one of the profiles is signed out.
metrics_provider.UpdateInitialSigninStatus(2, 1);
- metrics_provider.GoogleSignedOut(AccountInfo());
+ metrics_provider.OnPrimaryAccountCleared(AccountInfo());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
}
diff --git a/chromium/components/signin/core/browser/signin_tracker.cc b/chromium/components/signin/core/browser/signin_tracker.cc
deleted file mode 100644
index 230b49eb9db..00000000000
--- a/chromium/components/signin/core/browser/signin_tracker.cc
+++ /dev/null
@@ -1,46 +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/signin/core/browser/signin_tracker.h"
-
-#include "google_apis/gaia/gaia_constants.h"
-
-SigninTracker::SigninTracker(identity::IdentityManager* identity_manager,
- Observer* observer)
- : identity_manager_(identity_manager), observer_(observer) {
- Initialize();
-}
-
-SigninTracker::~SigninTracker() {
- identity_manager_->RemoveObserver(this);
-}
-
-void SigninTracker::Initialize() {
- DCHECK(observer_);
- identity_manager_->AddObserver(this);
-}
-
-void SigninTracker::OnPrimaryAccountSet(const AccountInfo& account_info) {
- if (identity_manager_->HasAccountWithRefreshToken(account_info.account_id))
- observer_->SigninSuccess();
-}
-
-void SigninTracker::OnPrimaryAccountSigninFailed(
- const GoogleServiceAuthError& error) {
- observer_->SigninFailed(error);
-}
-
-void SigninTracker::OnRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info) {
- if (account_info.account_id != identity_manager_->GetPrimaryAccountId())
- return;
-
- observer_->SigninSuccess();
-}
-
-void SigninTracker::OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {
- observer_->AccountAddedToCookie(error);
-}
diff --git a/chromium/components/signin/core/browser/signin_tracker.h b/chromium/components/signin/core/browser/signin_tracker.h
deleted file mode 100644
index 0e6e8c5bb35..00000000000
--- a/chromium/components/signin/core/browser/signin_tracker.h
+++ /dev/null
@@ -1,96 +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_SIGNIN_CORE_BROWSER_SIGNIN_TRACKER_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_TRACKER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "services/identity/public/cpp/identity_manager.h"
-
-// The signin flow logic is spread across several classes with varying
-// responsibilities:
-//
-// SigninTracker (this class) - This class listens to notifications from the
-// IdentityManager services and coalesces them into
-// notifications for the UI layer. This is the class that encapsulates the logic
-// that determines whether a user is fully logged in or not, and exposes
-// callbacks so various pieces of the UI (OneClickSyncStarter) can track the
-// current startup state.
-//
-// SyncSetupHandler - This class is primarily responsible for interacting with
-// the web UI for performing system login and sync configuration. Receives
-// callbacks from the UI when the user wishes to initiate a login, and
-// translates system state (login errors, etc) into the appropriate calls into
-// the UI to reflect this status to the user.
-//
-// LoginUIService - Our desktop UI flows rely on having only a single login flow
-// visible to the user at once. This is achieved via LoginUIService
-// (a KeyedService that keeps track of the currently visible
-// login UI).
-//
-// IdentityManager - Records the currently-logged-in user and handles all
-// interaction with the GAIA backend during the signin process. Unlike
-// SigninTracker, IdentityManager only knows about the GAIA login state and is
-// not aware of the state of any signed in services.
-// What is more, IdentityManager also maintains and manages OAuth2 tokens for
-// the accounts connected to this profile.
-// Last, the IdentityManager is also responsible for adding or removing cookies
-// from the cookie jar from the browser process. A single source of information
-// about GAIA cookies in the cookie jar that are fetchable via /ListAccounts.
-//
-// ProfileSyncService - Provides the external API for interacting with the
-// sync framework. Listens for notifications for tokens to know when to startup
-// sync, and provides an Observer interface to notify the UI layer of changes
-// in sync state so they can be reflected in the UI.
-class SigninTracker : public identity::IdentityManager::Observer {
- public:
- class Observer {
- public:
- // The signin attempt failed, and the cause is passed in |error|.
- virtual void SigninFailed(const GoogleServiceAuthError& error) = 0;
-
- // The signin attempt succeeded.
- virtual void SigninSuccess() = 0;
-
- // The signed in account has been added into the content area cookie jar.
- // This will be called only after a call to SigninSuccess().
- virtual void AccountAddedToCookie(const GoogleServiceAuthError& error) = 0;
- };
-
- // Creates a SigninTracker that tracks the signin status on the passed
- // classes, and notifies the |observer| on status changes. All of the
- // instances with the exception of |account_reconcilor| must be non-null and
- // must outlive the SigninTracker. |account_reconcilor| will be used if it is
- // non-null.
- SigninTracker(identity::IdentityManager* identity_manager,
- Observer* observer);
- ~SigninTracker() override;
-
- // identity::IdentityManager::Observer implementation.
- void OnPrimaryAccountSet(const AccountInfo& account_info) override;
- void OnPrimaryAccountSigninFailed(
- const GoogleServiceAuthError& error) override;
- void OnRefreshTokenUpdatedForAccount(
- const AccountInfo& account_info) override;
- void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) override;
-
- private:
- // Initializes this by adding notifications and observers.
- void Initialize();
-
- // The classes whose collective signin status we are tracking.
- identity::IdentityManager* identity_manager_;
-
- // Weak pointer to the observer we call when the signin state changes.
- Observer* observer_;
-
- DISALLOW_COPY_AND_ASSIGN(SigninTracker);
-};
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_TRACKER_H_
diff --git a/chromium/components/signin/core/browser/signin_tracker_unittest.cc b/chromium/components/signin/core/browser/signin_tracker_unittest.cc
deleted file mode 100644
index e6114a3729c..00000000000
--- a/chromium/components/signin/core/browser/signin_tracker_unittest.cc
+++ /dev/null
@@ -1,89 +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 "components/signin/core/browser/signin_tracker.h"
-
-#include "base/compiler_specific.h"
-#include "base/test/scoped_task_environment.h"
-#include "build/build_config.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-#include "services/identity/public/cpp/identity_test_environment.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Mock;
-using ::testing::Return;
-using ::testing::ReturnRef;
-
-namespace {
-
-#if defined(OS_CHROMEOS)
-using FakeSigninManagerForTesting = FakeSigninManagerBase;
-#else
-using FakeSigninManagerForTesting = FakeSigninManager;
-#endif // OS_CHROMEOS
-
-class MockObserver : public SigninTracker::Observer {
- public:
- MockObserver() {}
- ~MockObserver() {}
-
- MOCK_METHOD1(SigninFailed, void(const GoogleServiceAuthError&));
- MOCK_METHOD0(SigninSuccess, void(void));
- MOCK_METHOD1(AccountAddedToCookie, void(const GoogleServiceAuthError&));
-};
-
-} // namespace
-
-class SigninTrackerTest : public testing::Test {
- public:
- SigninTrackerTest() {
- tracker_ = std::make_unique<SigninTracker>(
- identity_test_env_.identity_manager(), &observer_);
- }
-
- ~SigninTrackerTest() override { tracker_.reset(); }
-
- base::test::ScopedTaskEnvironment task_environment_;
- std::unique_ptr<SigninTracker> tracker_;
- identity::IdentityTestEnvironment identity_test_env_;
- MockObserver observer_;
-};
-
-#if !defined(OS_CHROMEOS)
-TEST_F(SigninTrackerTest, SignInFails) {
- const GoogleServiceAuthError error(
- GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
-
- // Signin failure should result in a SigninFailed callback.
- EXPECT_CALL(observer_, SigninSuccess()).Times(0);
- EXPECT_CALL(observer_, SigninFailed(error));
-
- // Mimic calling IdentityManager::GoogleSigninFailed().
- tracker_->OnPrimaryAccountSigninFailed(error);
-}
-#endif // !defined(OS_CHROMEOS)
-
-TEST_F(SigninTrackerTest, SignInSucceeds) {
- EXPECT_CALL(observer_, SigninSuccess());
- EXPECT_CALL(observer_, SigninFailed(_)).Times(0);
-
- std::string email = "user@gmail.com";
- identity_test_env_.MakePrimaryAccountAvailable(email);
-}
-
-#if !defined(OS_CHROMEOS)
-TEST_F(SigninTrackerTest, SignInSucceedsWithExistingAccount) {
- EXPECT_CALL(observer_, SigninSuccess());
- EXPECT_CALL(observer_, SigninFailed(_)).Times(0);
-
- std::string email = "user@gmail.com";
- AccountInfo account_info = identity_test_env_.MakeAccountAvailable(email);
- identity_test_env_.SetPrimaryAccount(account_info.email);
-}
-#endif
diff --git a/chromium/components/signin/core/browser/test_image_decoder.cc b/chromium/components/signin/core/browser/test_image_decoder.cc
new file mode 100644
index 00000000000..225b413af3d
--- /dev/null
+++ b/chromium/components/signin/core/browser/test_image_decoder.cc
@@ -0,0 +1,23 @@
+// 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/signin/core/browser/test_image_decoder.h"
+
+#include "base/values.h"
+#include "build/build_config.h"
+#include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "ui/gfx/image/image_unittest_util.h"
+
+TestImageDecoder::TestImageDecoder() = default;
+
+TestImageDecoder::~TestImageDecoder() = default;
+
+void TestImageDecoder::DecodeImage(
+ const std::string& image_data,
+ const gfx::Size& desired_image_frame_size,
+ const image_fetcher::ImageDecodedCallback& callback) {
+ callback.Run(image_data.empty() ? gfx::Image()
+ : gfx::test::CreateImage(64, 64));
+}
diff --git a/chromium/components/signin/core/browser/test_image_decoder.h b/chromium/components/signin/core/browser/test_image_decoder.h
new file mode 100644
index 00000000000..311099d2847
--- /dev/null
+++ b/chromium/components/signin/core/browser/test_image_decoder.h
@@ -0,0 +1,35 @@
+// 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_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "components/image_fetcher/core/image_decoder.h"
+#include "components/signin/core/browser/account_fetcher_service.h"
+
+// This dummy class implements |image_fetcher::ImageDecoder|, and is passed
+// as an argument to |AccountFetcherService::Initialize|.
+class TestImageDecoder : public image_fetcher::ImageDecoder {
+ public:
+ TestImageDecoder();
+ ~TestImageDecoder() override;
+
+ // image_fetcher::Decoder implementation:
+
+ // If |image_data| is non-empty, a blank 64x64 image is passed to callback.
+ // Otherwise an empty image is passed.
+ void DecodeImage(
+ const std::string& image_data,
+ const gfx::Size& desired_image_frame_size,
+ const image_fetcher::ImageDecodedCallback& callback) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestImageDecoder);
+};
+
+#endif // COMPONENTS_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_
diff --git a/chromium/components/signin/core/browser/test_signin_client.cc b/chromium/components/signin/core/browser/test_signin_client.cc
index c137b2f3483..237beae6d9b 100644
--- a/chromium/components/signin/core/browser/test_signin_client.cc
+++ b/chromium/components/signin/core/browser/test_signin_client.cc
@@ -9,47 +9,15 @@
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/test/test_cookie_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace {
-class FakeCookieManager : public network::mojom::CookieManager {
- public:
- void SetCanonicalCookie(const net::CanonicalCookie& cookie,
- bool secure_source,
- bool modify_http_only,
- SetCanonicalCookieCallback callback) override;
- void GetAllCookies(GetAllCookiesCallback callback) override {}
- void GetCookieList(const GURL& url,
- const net::CookieOptions& cookie_options,
- GetCookieListCallback callback) override {}
- void DeleteCanonicalCookie(const net::CanonicalCookie& cookie,
- DeleteCanonicalCookieCallback callback) override {}
- void DeleteCookies(network::mojom::CookieDeletionFilterPtr filter,
- DeleteCookiesCallback callback) override {}
- void AddCookieChangeListener(
- const GURL& url,
- const std::string& name,
- network::mojom::CookieChangeListenerPtr listener) override {}
- void AddGlobalChangeListener(
- network::mojom::CookieChangeListenerPtr notification_pointer) override {}
- void CloneInterface(
- network::mojom::CookieManagerRequest new_interface) override {}
- void FlushCookieStore(FlushCookieStoreCallback callback) override {}
- void SetContentSettings(
- const std::vector<::ContentSettingPatternSource>& settings) override {}
- void SetForceKeepSessionState() override {}
- void BlockThirdPartyCookies(bool block) override {}
-};
-} // namespace
-
TestSigninClient::TestSigninClient(PrefService* pref_service)
- : shared_factory_(
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_)),
- pref_service_(pref_service),
+ : pref_service_(pref_service),
are_signin_cookies_allowed_(true),
network_calls_delayed_(false),
- is_signout_allowed_(true) {}
+ is_signout_allowed_(true),
+ is_ready_for_dice_migration_(false) {}
TestSigninClient::~TestSigninClient() {}
@@ -59,20 +27,6 @@ PrefService* TestSigninClient::GetPrefs() {
return pref_service_;
}
-void FakeCookieManager::SetCanonicalCookie(
- const net::CanonicalCookie& cookie,
- bool secure_source,
- bool modify_http_only,
- SetCanonicalCookieCallback callback) {
- std::move(callback).Run(false);
-}
-
-void TestSigninClient::PostSignedIn(const std::string& account_id,
- const std::string& username,
- const std::string& password) {
- signed_in_password_ = password;
-}
-
void TestSigninClient::PreSignOut(
base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached,
signin_metrics::ProfileSignout signout_source_metric) {
@@ -83,12 +37,12 @@ void TestSigninClient::PreSignOut(
scoped_refptr<network::SharedURLLoaderFactory>
TestSigninClient::GetURLLoaderFactory() {
- return shared_factory_;
+ return test_url_loader_factory_.GetSafeWeakWrapper();
}
network::mojom::CookieManager* TestSigninClient::GetCookieManager() {
if (!cookie_manager_)
- cookie_manager_ = std::make_unique<FakeCookieManager>();
+ cookie_manager_ = std::make_unique<network::TestCookieManager>();
return cookie_manager_.get();
}
@@ -124,11 +78,11 @@ void TestSigninClient::RemoveContentSettingsObserver(
content_settings::Observer* observer) {
}
-void TestSigninClient::DelayNetworkCall(const base::Closure& callback) {
+void TestSigninClient::DelayNetworkCall(base::OnceClosure callback) {
if (network_calls_delayed_) {
- delayed_network_calls_.push_back(callback);
+ delayed_network_calls_.push_back(std::move(callback));
} else {
- callback.Run();
+ std::move(callback).Run();
}
}
@@ -145,3 +99,7 @@ void TestSigninClient::PreGaiaLogout(base::OnceClosure callback) {
std::move(callback).Run();
}
}
+
+void TestSigninClient::SetReadyForDiceMigration(bool ready) {
+ is_ready_for_dice_migration_ = ready;
+}
diff --git a/chromium/components/signin/core/browser/test_signin_client.h b/chromium/components/signin/core/browser/test_signin_client.h
index d401d854023..103cf5999e4 100644
--- a/chromium/components/signin/core/browser/test_signin_client.h
+++ b/chromium/components/signin/core/browser/test_signin_client.h
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/callback_forward.h"
@@ -38,27 +39,23 @@ class TestSigninClient : public SigninClient {
// once there is a unit test that requires it.
PrefService* GetPrefs() override;
- // Trace that this was called.
- void PostSignedIn(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
-
// Allow or disallow continuation of sign-out depending on value of
// |is_signout_allowed_|;
void PreSignOut(
base::OnceCallback<void(SignoutDecision)> on_signout_decision_reached,
signin_metrics::ProfileSignout signout_source_metric) override;
- std::string get_signed_in_password() { return signed_in_password_; }
-
// Returns the empty string.
std::string GetProductVersion() override;
// Wraps the test_url_loader_factory().
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
- // Returns FakeCookieManager.
network::mojom::CookieManager* GetCookieManager() override;
+ void set_cookie_manager(
+ std::unique_ptr<network::mojom::CookieManager> cookie_manager) {
+ cookie_manager_ = std::move(cookie_manager);
+ }
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
@@ -70,6 +67,8 @@ class TestSigninClient : public SigninClient {
void set_is_signout_allowed(bool value) { is_signout_allowed_ = value; }
+ bool is_ready_for_dice_migration() { return is_ready_for_dice_migration_; }
+
// When |value| is true, network calls posted through DelayNetworkCall() are
// delayed indefinitely.
// When |value| is false, all pending calls are unblocked, and new calls are
@@ -84,27 +83,26 @@ class TestSigninClient : public SigninClient {
content_settings::Observer* observer) override;
void RemoveContentSettingsObserver(
content_settings::Observer* observer) override;
- void DelayNetworkCall(const base::Closure& callback) override;
+ void DelayNetworkCall(base::OnceClosure callback) override;
std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcher(
GaiaAuthConsumer* consumer,
gaia::GaiaSource source,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
override;
void PreGaiaLogout(base::OnceClosure callback) override;
+ void SetReadyForDiceMigration(bool ready) override;
private:
network::TestURLLoaderFactory test_url_loader_factory_;
- scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
PrefService* pref_service_;
std::unique_ptr<network::mojom::CookieManager> cookie_manager_;
bool are_signin_cookies_allowed_;
bool network_calls_delayed_;
bool is_signout_allowed_;
- std::vector<base::OnceClosure> delayed_network_calls_;
+ bool is_ready_for_dice_migration_;
- // Pointer to be filled by PostSignedIn.
- std::string signed_in_password_;
+ std::vector<base::OnceClosure> delayed_network_calls_;
DISALLOW_COPY_AND_ASSIGN(TestSigninClient);
};
diff --git a/chromium/components/signin/core/browser/ubertoken_fetcher_impl.cc b/chromium/components/signin/core/browser/ubertoken_fetcher_impl.cc
index 53c3f7dd5ec..deae759eca5 100644
--- a/chromium/components/signin/core/browser/ubertoken_fetcher_impl.cc
+++ b/chromium/components/signin/core/browser/ubertoken_fetcher_impl.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
diff --git a/chromium/components/signin/core/browser/ubertoken_fetcher_impl_unittest.cc b/chromium/components/signin/core/browser/ubertoken_fetcher_impl_unittest.cc
index b9ce26d86f9..0dbf5eb1662 100644
--- a/chromium/components/signin/core/browser/ubertoken_fetcher_impl_unittest.cc
+++ b/chromium/components/signin/core/browser/ubertoken_fetcher_impl_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/components/signin/core/browser/webdata/token_web_data.cc b/chromium/components/signin/core/browser/webdata/token_web_data.cc
index 4637762f589..cc38acaa09b 100644
--- a/chromium/components/signin/core/browser/webdata/token_web_data.cc
+++ b/chromium/components/signin/core/browser/webdata/token_web_data.cc
@@ -67,7 +67,7 @@ class TokenWebDataBackend
TokenResult::TokenResult()
: db_result(TokenServiceTable::TOKEN_DB_RESULT_SQL_INVALID_STATEMENT) {}
TokenResult::TokenResult(const TokenResult& other) = default;
-TokenResult::~TokenResult(){};
+TokenResult::~TokenResult() {}
TokenWebData::TokenWebData(
scoped_refptr<WebDatabaseService> wdbs,
diff --git a/chromium/components/signin/ios/browser/BUILD.gn b/chromium/components/signin/ios/browser/BUILD.gn
index 088e53e3f0b..07fd4e192ae 100644
--- a/chromium/components/signin/ios/browser/BUILD.gn
+++ b/chromium/components/signin/ios/browser/BUILD.gn
@@ -8,8 +8,6 @@ source_set("browser") {
"account_consistency_service.h",
"account_consistency_service.mm",
"manage_accounts_delegate.h",
- "merge_session_observer_bridge.h",
- "merge_session_observer_bridge.mm",
"profile_oauth2_token_service_ios_delegate.h",
"profile_oauth2_token_service_ios_delegate.mm",
"profile_oauth2_token_service_ios_provider.h",
@@ -77,7 +75,6 @@ source_set("unit_tests") {
":test_support",
"//components/prefs:test_support",
"//components/signin/core/browser",
- "//components/signin/core/browser:internals_test_support",
"//components/sync_preferences:test_support",
"//ios/web",
"//ios/web/public/test",
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.h b/chromium/components/signin/ios/browser/account_consistency_service.h
index e7ebe2345e7..e70f21b52c8 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.h
+++ b/chromium/components/signin/ios/browser/account_consistency_service.h
@@ -17,7 +17,6 @@
#include "base/time/time.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/keyed_service/core/keyed_service.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/ios/browser/active_state_manager.h"
#import "components/signin/ios/browser/manage_accounts_delegate.h"
#import "services/identity/public/cpp/identity_manager.h"
@@ -29,7 +28,6 @@ class WebStatePolicyDecider;
}
class AccountReconcilor;
-class SigninClient;
@class AccountConsistencyNavigationDelegate;
@class WKWebView;
@@ -40,7 +38,6 @@ class SigninClient;
//
// This is currently only used when WKWebView is enabled.
class AccountConsistencyService : public KeyedService,
- public GaiaCookieManagerService::Observer,
public identity::IdentityManager::Observer,
public ActiveStateManager::Observer {
public:
@@ -50,10 +47,9 @@ class AccountConsistencyService : public KeyedService,
AccountConsistencyService(
web::BrowserState* browser_state,
+ PrefService* prefs,
AccountReconcilor* account_reconcilor,
scoped_refptr<content_settings::CookieSettings> cookie_settings,
- GaiaCookieManagerService* gaia_cookie_manager_service,
- SigninClient* signin_client,
identity::IdentityManager* identity_manager);
~AccountConsistencyService() override;
@@ -146,19 +142,13 @@ class AccountConsistencyService : public KeyedService,
// Adds CHROME_CONNECTED cookies on all the main Google domains.
void AddChromeConnectedCookies();
- // GaiaCookieManagerService::Observer implementation.
- void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) override;
- void OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error) override;
-
// IdentityManager::Observer implementation.
- void OnPrimaryAccountSet(const AccountInfo& account_info) override;
+ void OnPrimaryAccountSet(const CoreAccountInfo& account_info) override;
void OnPrimaryAccountCleared(
- const AccountInfo& previous_account_info) override;
+ const CoreAccountInfo& previous_account_info) override;
+ void OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+ const GoogleServiceAuthError& error) override;
// ActiveStateManager::Observer implementation.
void OnActive() override;
@@ -166,17 +156,14 @@ class AccountConsistencyService : public KeyedService,
// Browser state associated with the service, used to create WKWebViews.
web::BrowserState* browser_state_;
+ // Used to update kDomainsWithCookiePref.
+ PrefService* prefs_;
// Service managing accounts reconciliation, notified of GAIA responses with
// the X-Chrome-Manage-Accounts header
AccountReconcilor* account_reconcilor_;
// Cookie settings currently in use for |browser_state_|, used to check if
// setting CHROME_CONNECTED cookies is valid.
scoped_refptr<content_settings::CookieSettings> cookie_settings_;
- // Service managing the Gaia cookies, observed to be notified of the state of
- // reconciliation.
- GaiaCookieManagerService* gaia_cookie_manager_service_;
- // Signin client, used to access prefs.
- SigninClient* signin_client_;
// Identity manager, observed to be notified of primary account signin and
// signout events.
identity::IdentityManager* identity_manager_;
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.mm b/chromium/components/signin/ios/browser/account_consistency_service.mm
index f4de0d48b49..bc6244f97e0 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service.mm
@@ -6,6 +6,7 @@
#import <WebKit/WebKit.h>
+#include "base/bind.h"
#include "base/logging.h"
#import "base/mac/foundation_util.h"
#include "base/macros.h"
@@ -15,7 +16,6 @@
#include "components/prefs/scoped_user_pref_update.h"
#include "components/signin/core/browser/account_consistency_method.h"
#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/core/browser/signin_client.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "ios/web/public/browser_state.h"
#include "ios/web/public/web_state/web_state_policy_decider.h"
@@ -217,19 +217,16 @@ AccountConsistencyService::CookieRequest::CookieRequest(
AccountConsistencyService::AccountConsistencyService(
web::BrowserState* browser_state,
+ PrefService* prefs,
AccountReconcilor* account_reconcilor,
scoped_refptr<content_settings::CookieSettings> cookie_settings,
- GaiaCookieManagerService* gaia_cookie_manager_service,
- SigninClient* signin_client,
identity::IdentityManager* identity_manager)
: browser_state_(browser_state),
+ prefs_(prefs),
account_reconcilor_(account_reconcilor),
cookie_settings_(cookie_settings),
- gaia_cookie_manager_service_(gaia_cookie_manager_service),
- signin_client_(signin_client),
identity_manager_(identity_manager),
applying_cookie_requests_(false) {
- gaia_cookie_manager_service_->AddObserver(this);
identity_manager_->AddObserver(this);
ActiveStateManager::FromBrowserState(browser_state_)->AddObserver(this);
LoadFromPrefs();
@@ -325,14 +322,13 @@ void AccountConsistencyService::RemoveChromeConnectedCookieFromDomain(
void AccountConsistencyService::LoadFromPrefs() {
const base::DictionaryValue* dict =
- signin_client_->GetPrefs()->GetDictionary(kDomainsWithCookiePref);
+ prefs_->GetDictionary(kDomainsWithCookiePref);
for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
last_cookie_update_map_[it.key()] = base::Time();
}
}
void AccountConsistencyService::Shutdown() {
- gaia_cookie_manager_service_->RemoveObserver(this);
identity_manager_->RemoveObserver(this);
ActiveStateManager::FromBrowserState(browser_state_)->RemoveObserver(this);
ResetWKWebView();
@@ -396,8 +392,7 @@ void AccountConsistencyService::FinishedApplyingCookieRequest(bool success) {
CookieRequest& request = cookie_requests_.front();
if (success) {
DictionaryPrefUpdate update(
- signin_client_->GetPrefs(),
- AccountConsistencyService::kDomainsWithCookiePref);
+ prefs_, AccountConsistencyService::kDomainsWithCookiePref);
switch (request.request_type) {
case ADD_CHROME_CONNECTED_COOKIE:
// Add request.domain to prefs, use |true| as a dummy value (that is
@@ -471,37 +466,32 @@ void AccountConsistencyService::OnBrowsingDataRemoved() {
cookie_requests_.clear();
last_cookie_update_map_.clear();
base::DictionaryValue dict;
- signin_client_->GetPrefs()->Set(kDomainsWithCookiePref, dict);
+ prefs_->Set(kDomainsWithCookiePref, dict);
// APISID cookie has been removed, notify the GCMS.
- gaia_cookie_manager_service_->ForceOnCookieChangeProcessing();
-}
-
-void AccountConsistencyService::OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {
- AddChromeConnectedCookies();
-}
-
-void AccountConsistencyService::OnGaiaAccountsInCookieUpdated(
- const std::vector<gaia::ListedAccount>& accounts,
- const std::vector<gaia::ListedAccount>& signed_out_accounts,
- const GoogleServiceAuthError& error) {
- AddChromeConnectedCookies();
+ // TODO(https://crbug.com/930582) : Remove the need to expose this method
+ // or move it to the network::CookieManager.
+ identity_manager_->ForceTriggerOnCookieChange();
}
void AccountConsistencyService::OnPrimaryAccountSet(
- const AccountInfo& account_info) {
+ const CoreAccountInfo& account_info) {
AddChromeConnectedCookies();
}
void AccountConsistencyService::OnPrimaryAccountCleared(
- const AccountInfo& previous_account_info) {
+ const CoreAccountInfo& previous_account_info) {
// There is not need to remove CHROME_CONNECTED cookies on |GoogleSignedOut|
// events as these cookies will be removed by the GaiaCookieManagerServer
// right before fetching the Gaia logout request.
}
+void AccountConsistencyService::OnAccountsInCookieUpdated(
+ const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+ const GoogleServiceAuthError& error) {
+ AddChromeConnectedCookies();
+}
+
void AccountConsistencyService::OnActive() {
// |browser_state_| is now active. There might be some pending cookie requests
// to apply.
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 1a7a24a2303..45d33c881e4 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -13,12 +13,7 @@
#include "base/values.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/fake_gaia_cookie_manager_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/gaia_cookie_manager_service.h"
-#include "components/signin/core/browser/signin_pref_names.h"
+#include "components/signin/core/browser/list_accounts_test_utils.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "ios/web/public/test/fakes/test_browser_state.h"
@@ -27,6 +22,7 @@
#include "ios/web/public/web_state/web_state_policy_decider.h"
#import "services/identity/public/cpp/identity_manager.h"
#import "services/identity/public/cpp/identity_test_environment.h"
+#include "services/identity/public/cpp/test_identity_manager_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -58,16 +54,14 @@ class FakeAccountConsistencyService : public AccountConsistencyService {
public:
FakeAccountConsistencyService(
web::BrowserState* browser_state,
+ PrefService* prefs,
AccountReconcilor* account_reconcilor,
scoped_refptr<content_settings::CookieSettings> cookie_settings,
- GaiaCookieManagerService* gaia_cookie_manager_service,
- SigninClient* signin_client,
identity::IdentityManager* identity_manager)
: AccountConsistencyService(browser_state,
+ prefs,
account_reconcilor,
cookie_settings,
- gaia_cookie_manager_service,
- signin_client,
identity_manager) {}
private:
@@ -87,30 +81,10 @@ class MockAccountReconcilor : public AccountReconcilor {
: AccountReconcilor(
nullptr,
client,
- nullptr,
std::make_unique<signin::AccountReconcilorDelegate>()) {}
MOCK_METHOD1(OnReceivedManageAccountsResponse, void(signin::GAIAServiceType));
};
-// Mock GaiaCookieManagerService to catch call to ForceOnCookieChangeProcessing.
-// It isn't an actual mock as it is not desirable to extend a Mock from a Fake.
-class CustomGaiaCookieManagerService : public FakeGaiaCookieManagerService {
- public:
- CustomGaiaCookieManagerService()
- : FakeGaiaCookieManagerService(nullptr, nullptr),
- calls_to_force_on_cookie_change_processing_(0) {}
-
- uint8_t CallsToForceOnCookieChangeProcessing() {
- return calls_to_force_on_cookie_change_processing_;
- }
-
- private:
- void ForceOnCookieChangeProcessing() override {
- calls_to_force_on_cookie_change_processing_++;
- };
- uint8_t calls_to_force_on_cookie_change_processing_;
-};
-
// TestWebState that allows control over its policy decider.
class TestWebState : public web::TestWebState {
public:
@@ -152,24 +126,14 @@ class AccountConsistencyServiceTest : public PlatformTest {
PlatformTest::SetUp();
ActiveStateManager::FromBrowserState(&browser_state_)->SetActive(true);
AccountConsistencyService::RegisterPrefs(prefs_.registry());
- AccountTrackerService::RegisterPrefs(prefs_.registry());
- ProfileOAuth2TokenService::RegisterProfilePrefs(prefs_.registry());
content_settings::CookieSettings::RegisterProfilePrefs(prefs_.registry());
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
- SigninManagerBase::RegisterProfilePrefs(prefs_.registry());
web_view_load_expection_count_ = 0;
- gaia_cookie_manager_service_.reset(new CustomGaiaCookieManagerService());
signin_client_.reset(new TestSigninClient(&prefs_));
- account_tracker_service_.Initialize(&prefs_, base::FilePath());
- token_service_.reset(new FakeProfileOAuth2TokenService(&prefs_));
- signin_manager_.reset(
- new FakeSigninManager(signin_client_.get(), token_service_.get(),
- &account_tracker_service_, nullptr));
- signin_manager_->Initialize(nullptr);
identity_test_env_.reset(new identity::IdentityTestEnvironment(
- &account_tracker_service_, token_service_.get(), signin_manager_.get(),
- gaia_cookie_manager_service_.get()));
+ &test_url_loader_factory_, &prefs_,
+ signin::AccountConsistencyMethod::kDisabled, signin_client_.get()));
settings_map_ = new HostContentSettingsMap(
&prefs_, false /* incognito_profile */, false /* guest_profile */,
false /* store_last_modified */,
@@ -215,18 +179,19 @@ class AccountConsistencyServiceTest : public PlatformTest {
account_consistency_service_->Shutdown();
}
account_consistency_service_.reset(new FakeAccountConsistencyService(
- &browser_state_, account_reconcilor_.get(), cookie_settings_,
- gaia_cookie_manager_service_.get(), signin_client_.get(),
+ &browser_state_, &prefs_, account_reconcilor_.get(), cookie_settings_,
identity_test_env_->identity_manager()));
}
void SignIn() {
- signin_manager_->SignIn("12345", "user@gmail.com", "password");
+ identity::MakePrimaryAccountAvailable(
+ identity_test_env_->identity_manager(), "user@gmail.com");
EXPECT_EQ(0, web_view_load_expection_count_);
}
void SignOutAndSimulateGaiaCookieManagerServiceLogout() {
- signin_manager_->ForceSignOut();
+ identity::ClearPrimaryAccount(identity_test_env_->identity_manager(),
+ identity::ClearPrimaryAccountPolicy::DEFAULT);
SimulateGaiaCookieManagerServiceLogout(true);
}
@@ -268,18 +233,16 @@ class AccountConsistencyServiceTest : public PlatformTest {
// Creates test threads, necessary for ActiveStateManager that needs a UI
// thread.
web::TestWebThreadBundle thread_bundle_;
- AccountTrackerService account_tracker_service_;
web::TestBrowserState browser_state_;
sync_preferences::TestingPrefServiceSyncable prefs_;
TestWebState web_state_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+
std::unique_ptr<identity::IdentityTestEnvironment> identity_test_env_;
// AccountConsistencyService being tested. Actually a
// FakeAccountConsistencyService to be able to use a mock web view.
std::unique_ptr<AccountConsistencyService> account_consistency_service_;
std::unique_ptr<TestSigninClient> signin_client_;
- std::unique_ptr<FakeProfileOAuth2TokenService> token_service_;
- std::unique_ptr<FakeSigninManager> signin_manager_;
- std::unique_ptr<CustomGaiaCookieManagerService> gaia_cookie_manager_service_;
std::unique_ptr<MockAccountReconcilor> account_reconcilor_;
scoped_refptr<HostContentSettingsMap> settings_map_;
scoped_refptr<content_settings::CookieSettings> cookie_settings_;
@@ -468,11 +431,20 @@ TEST_F(AccountConsistencyServiceTest, DomainsClearedOnBrowsingDataRemoved) {
prefs_.GetDictionary(AccountConsistencyService::kDomainsWithCookiePref);
EXPECT_EQ(2u, dict->size());
+ // Sets Response to get IdentityManager::Observer::OnAccountsInCookieUpdated
+ // through GaiaCookieManagerService::OnCookieChange.
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
+
+ base::RunLoop run_loop;
+ identity_test_env_->identity_manager_observer()
+ ->SetOnAccountsInCookieUpdatedCallback(run_loop.QuitClosure());
+ // OnBrowsingDataRemoved triggers IdentityManager::ForceTriggerOnCookieChange
+ // and finally IdentityManager::Observer::OnAccountsInCookieUpdated is called.
account_consistency_service_->OnBrowsingDataRemoved();
+ run_loop.Run();
+
dict =
prefs_.GetDictionary(AccountConsistencyService::kDomainsWithCookiePref);
- EXPECT_EQ(
- 1u, gaia_cookie_manager_service_->CallsToForceOnCookieChangeProcessing());
EXPECT_EQ(0u, dict->size());
}
@@ -485,9 +457,18 @@ TEST_F(AccountConsistencyServiceTest, DomainsClearedOnBrowsingDataRemoved2) {
AddPageLoadedExpectation(kGoogleUrl, false /* continue_navigation */);
SimulateGaiaCookieManagerServiceLogout(false);
+
+ // Sets Response to get IdentityManager::Observer::OnAccountsInCookieUpdated
+ // through GaiaCookieManagerService::OnCookieChange.
+ signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
+
+ base::RunLoop run_loop;
+ identity_test_env_->identity_manager_observer()
+ ->SetOnAccountsInCookieUpdatedCallback(run_loop.QuitClosure());
+ // OnBrowsingDataRemoved triggers IdentityManager::ForceTriggerOnCookieChange
+ // and finally IdentityManager::Observer::OnAccountsInCookieUpdated is called.
account_consistency_service_->OnBrowsingDataRemoved();
- EXPECT_EQ(
- 1u, gaia_cookie_manager_service_->CallsToForceOnCookieChangeProcessing());
+ run_loop.Run();
EXPECT_TRUE(remove_cookie_callback_called_);
}
diff --git a/chromium/components/signin/ios/browser/active_state_manager.h b/chromium/components/signin/ios/browser/active_state_manager.h
index f4bf4e37136..a132530e92c 100644
--- a/chromium/components/signin/ios/browser/active_state_manager.h
+++ b/chromium/components/signin/ios/browser/active_state_manager.h
@@ -51,7 +51,7 @@ class ActiveStateManager {
virtual void RemoveObserver(Observer* observer) = 0;
protected:
- virtual ~ActiveStateManager(){};
+ virtual ~ActiveStateManager() {}
};
#endif // COMPONENTS_SIGNIN_IOS_BROWSER_ACTIVE_STATE_MANAGER_H_
diff --git a/chromium/components/signin/ios/browser/merge_session_observer_bridge.h b/chromium/components/signin/ios/browser/merge_session_observer_bridge.h
deleted file mode 100644
index ec9b10439d1..00000000000
--- a/chromium/components/signin/ios/browser/merge_session_observer_bridge.h
+++ /dev/null
@@ -1,44 +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_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_
-#define COMPONENTS_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_
-
-#import <Foundation/Foundation.h>
-
-#include <string>
-
-#include "base/macros.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
-
-class GoogleServiceAuthError;
-
-@protocol MergeSessionObserverBridgeDelegate
-
-// Informs the delegate that the merge session operation for |account_id| has
-// finished. If there was an error, it will be described in |error|.
-- (void)onMergeSessionCompleted:(const std::string&)account_id
- error:(const GoogleServiceAuthError&)error;
-
-@end
-
-// C++ class to monitor merge session status in Objective C type.
-class MergeSessionObserverBridge : public GaiaCookieManagerService::Observer {
- public:
- MergeSessionObserverBridge(id<MergeSessionObserverBridgeDelegate> delegate,
- GaiaCookieManagerService* cookie_manager_service);
- ~MergeSessionObserverBridge() override;
-
- void OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) override;
-
- private:
- __weak id<MergeSessionObserverBridgeDelegate> delegate_;
- GaiaCookieManagerService* cookie_manager_service_;
-
- DISALLOW_COPY_AND_ASSIGN(MergeSessionObserverBridge);
-};
-
-#endif // COMPONENTS_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_
diff --git a/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm b/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm
deleted file mode 100644
index ee30039d09a..00000000000
--- a/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm
+++ /dev/null
@@ -1,31 +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/signin/ios/browser/merge_session_observer_bridge.h"
-
-#include "base/logging.h"
-#include "google_apis/gaia/google_service_auth_error.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-MergeSessionObserverBridge::MergeSessionObserverBridge(
- id<MergeSessionObserverBridgeDelegate> delegate,
- GaiaCookieManagerService* cookie_manager_service)
- : delegate_(delegate), cookie_manager_service_(cookie_manager_service) {
- DCHECK(delegate);
- DCHECK(cookie_manager_service);
- cookie_manager_service_->AddObserver(this);
-}
-
-MergeSessionObserverBridge::~MergeSessionObserverBridge() {
- cookie_manager_service_->RemoveObserver(this);
-}
-
-void MergeSessionObserverBridge::OnAddAccountToCookieCompleted(
- const std::string& account_id,
- const GoogleServiceAuthError& error) {
- [delegate_ onMergeSessionCompleted:account_id error:error];
-}
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h
index 69168d83eee..8815bc9f0d3 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h
@@ -49,6 +49,10 @@ class ProfileOAuth2TokenServiceIOSDelegate : public OAuth2TokenServiceDelegate {
// Subsequent calls to |RefreshTokenIsAvailable| will return |false|.
void RevokeAllCredentials() override;
+ void AddAccountFromSystem(const std::string& account_id) override;
+
+ void ReloadAccountsFromSystem(const std::string& primary_account_id) override;
+
// Reloads accounts from the provider. Fires |OnRefreshTokenAvailable| for
// each new account. Fires |OnRefreshTokenRevoked| for each account that was
// removed.
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
index ad6e03de3a7..d931066f992 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
@@ -270,6 +270,19 @@ void ProfileOAuth2TokenServiceIOSDelegate::RevokeAllCredentials() {
ClearExcludedSecondaryAccounts();
}
+void ProfileOAuth2TokenServiceIOSDelegate::AddAccountFromSystem(
+ const std::string& account_id) {
+ AddOrUpdateAccount(account_id);
+}
+
+void ProfileOAuth2TokenServiceIOSDelegate::ReloadAccountsFromSystem(
+ const std::string& primary_account_id) {
+ if (primary_account_id.empty())
+ return;
+
+ ReloadCredentials(primary_account_id);
+}
+
OAuth2AccessTokenFetcher*
ProfileOAuth2TokenServiceIOSDelegate::CreateAccessTokenFetcher(
const std::string& account_id,
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 aec0b1cc31e..38767190d58 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
@@ -73,7 +73,7 @@ class ProfileOAuth2TokenServiceIOSDelegateTest
void OnGetTokenFailure(const GoogleServiceAuthError& error) override {
++access_token_failure_;
last_access_token_error_ = error;
- };
+ }
// OAuth2TokenService::Observer implementation.
void OnRefreshTokenAvailable(const std::string& account_id) override {
diff --git a/chromium/components/signin/ios/browser/wait_for_network_callback_helper.cc b/chromium/components/signin/ios/browser/wait_for_network_callback_helper.cc
index fcec9a5f1d1..f1f4637d0a0 100644
--- a/chromium/components/signin/ios/browser/wait_for_network_callback_helper.cc
+++ b/chromium/components/signin/ios/browser/wait_for_network_callback_helper.cc
@@ -4,6 +4,8 @@
#include "components/signin/ios/browser/wait_for_network_callback_helper.h"
+#include <utility>
+
WaitForNetworkCallbackHelper::WaitForNetworkCallbackHelper() {
net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
}
@@ -17,17 +19,16 @@ void WaitForNetworkCallbackHelper::OnNetworkChanged(
if (net::NetworkChangeNotifier::IsOffline())
return;
- for (const base::Closure& callback : delayed_callbacks_)
- callback.Run();
+ for (base::OnceClosure& callback : delayed_callbacks_)
+ std::move(callback).Run();
delayed_callbacks_.clear();
}
-void WaitForNetworkCallbackHelper::HandleCallback(
- const base::Closure& callback) {
+void WaitForNetworkCallbackHelper::HandleCallback(base::OnceClosure callback) {
if (net::NetworkChangeNotifier::IsOffline()) {
- delayed_callbacks_.push_back(callback);
+ delayed_callbacks_.push_back(std::move(callback));
} else {
- callback.Run();
+ std::move(callback).Run();
}
}
diff --git a/chromium/components/signin/ios/browser/wait_for_network_callback_helper.h b/chromium/components/signin/ios/browser/wait_for_network_callback_helper.h
index 6e775134f0c..08d1fa195b2 100644
--- a/chromium/components/signin/ios/browser/wait_for_network_callback_helper.h
+++ b/chromium/components/signin/ios/browser/wait_for_network_callback_helper.h
@@ -25,10 +25,10 @@ class WaitForNetworkCallbackHelper
// If offline, saves the |callback| to be called later when online. Otherwise,
// invokes immediately.
- void HandleCallback(const base::Closure& callback);
+ void HandleCallback(base::OnceClosure callback);
private:
- std::list<base::Closure> delayed_callbacks_;
+ std::list<base::OnceClosure> delayed_callbacks_;
DISALLOW_COPY_AND_ASSIGN(WaitForNetworkCallbackHelper);
};
diff --git a/chromium/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java b/chromium/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java
index 25728da96ee..e65096c9a61 100644
--- a/chromium/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java
+++ b/chromium/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java
@@ -18,7 +18,6 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.metrics.RecordHistogram;
import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
/**
* JNI interface for native SpellCheckerSessionBridge to use Android's spellchecker.
@@ -141,8 +140,7 @@ public class SpellCheckerSessionBridge implements SpellCheckerSessionListener {
convertListToArray(offsets), convertListToArray(lengths),
suggestions.toArray(new String[suggestions.size()][]));
- RecordHistogram.recordTimesHistogram("SpellCheck.Android.Latency",
- mStopMs - mStartMs, TimeUnit.MILLISECONDS);
+ RecordHistogram.recordTimesHistogram("SpellCheck.Android.Latency", mStopMs - mStartMs);
}
/**
diff --git a/chromium/components/spellcheck/browser/spell_check_host_impl.cc b/chromium/components/spellcheck/browser/spell_check_host_impl.cc
index a056b1e171a..d5482a500a4 100644
--- a/chromium/components/spellcheck/browser/spell_check_host_impl.cc
+++ b/chromium/components/spellcheck/browser/spell_check_host_impl.cc
@@ -63,14 +63,6 @@ void SpellCheckHostImpl::RequestTextCheck(const base::string16& text,
#endif
}
-void SpellCheckHostImpl::ToggleSpellCheck(bool enabled, bool checked) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-#if defined(OS_ANDROID)
- if (!enabled)
- session_bridge_.DisconnectSession();
-#endif
-}
-
void SpellCheckHostImpl::CheckSpelling(const base::string16& word,
int route_id,
CheckSpellingCallback callback) {
@@ -89,3 +81,10 @@ void SpellCheckHostImpl::FillSuggestionList(
std::move(callback).Run(std::vector<base::string16>());
}
#endif // BUILDFLAG(USE_BROWSER_SPELLCHECKER)
+
+#if defined(OS_ANDROID)
+void SpellCheckHostImpl::DisconnectSessionBridge() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ session_bridge_.DisconnectSession();
+}
+#endif
diff --git a/chromium/components/spellcheck/browser/spell_check_host_impl.h b/chromium/components/spellcheck/browser/spell_check_host_impl.h
index a419ef809b0..f2a1d66e18f 100644
--- a/chromium/components/spellcheck/browser/spell_check_host_impl.h
+++ b/chromium/components/spellcheck/browser/spell_check_host_impl.h
@@ -45,7 +45,6 @@ class SpellCheckHostImpl : public spellcheck::mojom::SpellCheckHost {
void RequestTextCheck(const base::string16& text,
int route_id,
RequestTextCheckCallback callback) override;
- void ToggleSpellCheck(bool enabled, bool checked) override;
void CheckSpelling(const base::string16& word,
int route_id,
CheckSpellingCallback callback) override;
@@ -53,6 +52,11 @@ class SpellCheckHostImpl : public spellcheck::mojom::SpellCheckHost {
FillSuggestionListCallback callback) override;
#endif // BUILDFLAG(USE_BROWSER_SPELLCHECKER)
+#if defined(OS_ANDROID)
+ // spellcheck::mojom::SpellCheckHost:
+ void DisconnectSessionBridge() override;
+#endif
+
private:
#if defined(OS_ANDROID)
// Android-specific object used to query the Android spellchecker.
diff --git a/chromium/components/spellcheck/browser/spellcheck_host_metrics.cc b/chromium/components/spellcheck/browser/spellcheck_host_metrics.cc
index bfd92be5ddf..1565b64a2c2 100644
--- a/chromium/components/spellcheck/browser/spellcheck_host_metrics.cc
+++ b/chromium/components/spellcheck/browser/spellcheck_host_metrics.cc
@@ -8,6 +8,7 @@
#include "base/md5.h"
#include "base/metrics/histogram_macros.h"
+#include "base/numerics/safe_conversions.h"
SpellCheckHostMetrics::SpellCheckHostMetrics()
: misspelled_word_count_(0),
@@ -18,7 +19,7 @@ SpellCheckHostMetrics::SpellCheckHostMetrics()
last_suggestion_show_count_(-1),
replaced_word_count_(0),
last_replaced_word_count_(-1),
- last_unique_word_count_(-1),
+ last_unique_word_count_(0),
start_time_(base::TimeTicks::Now()) {
const uint64_t kHistogramTimerDurationInMinutes = 30;
recording_timer_.Start(FROM_HERE,
@@ -32,7 +33,8 @@ SpellCheckHostMetrics::~SpellCheckHostMetrics() {
// static
void SpellCheckHostMetrics::RecordCustomWordCountStats(size_t count) {
- UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CustomWords", count);
+ UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CustomWords",
+ base::saturated_cast<int>(count));
}
void SpellCheckHostMetrics::RecordEnabledStats(bool enabled) {
@@ -79,7 +81,7 @@ void SpellCheckHostMetrics::OnHistogramTimerExpired() {
size_t checked_words_per_hour = spellchecked_word_count_ *
base::TimeDelta::FromHours(1).InSeconds() / since_start.InSeconds();
UMA_HISTOGRAM_COUNTS_1M("SpellCheck.CheckedWordsPerHour",
- checked_words_per_hour);
+ base::saturated_cast<int>(checked_words_per_hour));
}
}
@@ -133,10 +135,11 @@ void SpellCheckHostMetrics::RecordWordCounts() {
last_replaced_word_count_ = replaced_word_count_;
}
- if (((int)checked_word_hashes_.size()) != last_unique_word_count_) {
- DCHECK((int)checked_word_hashes_.size() > last_unique_word_count_);
- UMA_HISTOGRAM_COUNTS_1M("SpellCheck.UniqueWords",
- checked_word_hashes_.size());
+ if (checked_word_hashes_.size() != last_unique_word_count_) {
+ DCHECK(checked_word_hashes_.size() > last_unique_word_count_);
+ UMA_HISTOGRAM_COUNTS_1M(
+ "SpellCheck.UniqueWords",
+ base::saturated_cast<int>(checked_word_hashes_.size()));
last_unique_word_count_ = checked_word_hashes_.size();
}
diff --git a/chromium/components/spellcheck/browser/spellcheck_host_metrics.h b/chromium/components/spellcheck/browser/spellcheck_host_metrics.h
index 795e2587ac3..08e1e401aec 100644
--- a/chromium/components/spellcheck/browser/spellcheck_host_metrics.h
+++ b/chromium/components/spellcheck/browser/spellcheck_host_metrics.h
@@ -85,7 +85,7 @@ class SpellCheckHostMetrics {
int last_replaced_word_count_;
// Last recorded number of unique words.
- int last_unique_word_count_;
+ size_t last_unique_word_count_;
// Time when first spellcheck happened.
base::TimeTicks start_time_;
diff --git a/chromium/components/spellcheck/browser/spellchecker_session_bridge_android.cc b/chromium/components/spellcheck/browser/spellchecker_session_bridge_android.cc
index 3a303d4811a..ab3b84d977e 100644
--- a/chromium/components/spellcheck/browser/spellchecker_session_bridge_android.cc
+++ b/chromium/components/spellcheck/browser/spellchecker_session_bridge_android.cc
@@ -55,10 +55,10 @@ void SpellCheckerSessionBridge::RequestTextCheck(
}
// RequestTextCheck API call arrives at the SpellCheckHost before
- // ToggleSpellCheck when the user focuses an input field that already
+ // DisconnectSessionBridge when the user focuses an input field that already
// contains completed text. We need to initialize the spellchecker here
- // rather than in response to ToggleSpellCheck so that the existing text
- // will be spellchecked immediately.
+ // rather than in response to DisconnectSessionBridge so that the existing
+ // text will be spellchecked immediately.
if (java_object_.is_null()) {
java_object_.Reset(Java_SpellCheckerSessionBridge_create(
base::android::AttachCurrentThread(),
diff --git a/chromium/components/spellcheck/browser/spelling_service_client.cc b/chromium/components/spellcheck/browser/spelling_service_client.cc
index f151fedb876..b772a58c374 100644
--- a/chromium/components/spellcheck/browser/spelling_service_client.cc
+++ b/chromium/components/spellcheck/browser/spelling_service_client.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <memory>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/string_escape.h"
#include "base/logging.h"
@@ -245,7 +246,8 @@ bool SpellingServiceClient::ParseResponse(
// }
std::unique_ptr<base::DictionaryValue> value(
static_cast<base::DictionaryValue*>(
- base::JSONReader::Read(data, base::JSON_ALLOW_TRAILING_COMMAS)
+ base::JSONReader::ReadDeprecated(data,
+ base::JSON_ALLOW_TRAILING_COMMAS)
.release()));
if (!value || !value->is_dict())
return false;
diff --git a/chromium/components/spellcheck/common/spellcheck.mojom b/chromium/components/spellcheck/common/spellcheck.mojom
index 5587d26fc62..828724bd713 100644
--- a/chromium/components/spellcheck/common/spellcheck.mojom
+++ b/chromium/components/spellcheck/common/spellcheck.mojom
@@ -57,9 +57,9 @@ interface SpellCheckHost {
RequestTextCheck(mojo_base.mojom.String16 text, int32 route_id) =>
(array<SpellCheckResult> results);
- // Toggles the enabled state of the platform-specific spell checker.
- [EnableIf=USE_BROWSER_SPELLCHECKER]
- ToggleSpellCheck(bool enabled, bool checked);
+ // Disconnects the Android spell checker session bridge.
+ [EnableIf=is_android]
+ DisconnectSessionBridge();
// Checks the correctness of a word with a platform-specific spell checker.
// TODO(groby): This needs to originate from SpellcheckProvider.
diff --git a/chromium/components/spellcheck/common/spellcheck_common.cc b/chromium/components/spellcheck/common/spellcheck_common.cc
index fe89924743f..cf8eb4f8a81 100644
--- a/chromium/components/spellcheck/common/spellcheck_common.cc
+++ b/chromium/components/spellcheck/common/spellcheck_common.cc
@@ -33,6 +33,7 @@ static constexpr LanguageRegion kSupportedSpellCheckerLanguages[] = {
{"bg", "bg-BG"},
{"ca", "ca-ES"},
{"cs", "cs-CZ"},
+ {"cy", "cy-GB"},
{"da", "da-DK"},
{"de", "de-DE"},
{"el", "el-GR"},
@@ -122,6 +123,9 @@ base::FilePath GetVersionedFileName(base::StringPiece input_language,
// March 2016: Initial check-in of Persian
{"fa-IR", "-7-0"},
+
+ // Feb 2019: Initial check-in of Welsh.
+ {"cy-GB", "-1-0"},
};
// Generate the bdict file name using default version string or special
diff --git a/chromium/components/spellcheck/renderer/BUILD.gn b/chromium/components/spellcheck/renderer/BUILD.gn
index f5db20fe148..d993ecf6727 100644
--- a/chromium/components/spellcheck/renderer/BUILD.gn
+++ b/chromium/components/spellcheck/renderer/BUILD.gn
@@ -57,10 +57,6 @@ source_set("renderer") {
if (!is_android) {
deps += [ "//third_party/hunspell" ]
}
-
- if (is_win) {
- cflags = [ "/wd4267" ] # conversion from 'size_t' to 'int' on x64 (crbug.com/633312)
- }
}
source_set("unit_tests") {
@@ -105,8 +101,4 @@ source_set("unit_tests") {
if (is_mac && !is_ios) {
deps += [ "//third_party/hunspell" ]
}
-
- if (is_win) {
- cflags = [ "/wd4267" ] # conversion from 'size_t' to 'int' on x64 (crbug.com/633312)
- }
}
diff --git a/chromium/components/spellcheck/renderer/custom_dictionary_engine.cc b/chromium/components/spellcheck/renderer/custom_dictionary_engine.cc
index e00b7ec178d..0e2fe22e797 100644
--- a/chromium/components/spellcheck/renderer/custom_dictionary_engine.cc
+++ b/chromium/components/spellcheck/renderer/custom_dictionary_engine.cc
@@ -35,15 +35,12 @@ void CustomDictionaryEngine::OnCustomDictionaryChanged(
dictionary_.erase(base::UTF8ToUTF16(word));
}
-bool CustomDictionaryEngine::SpellCheckWord(
- const base::string16& text,
- int misspelling_start,
- int misspelling_len) {
+bool CustomDictionaryEngine::SpellCheckWord(const base::string16& text,
+ size_t misspelling_start,
+ size_t misspelling_len) {
// The text to be checked is empty on OSX(async) right now.
// TODO(groby): Fix as part of async hook-up. (http://crbug.com/178241)
- return
- misspelling_start >= 0 &&
- misspelling_len > 0 &&
- size_t(misspelling_start + misspelling_len) <= text.length() &&
- dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0;
+ return misspelling_len > 0 &&
+ misspelling_start + misspelling_len <= text.length() &&
+ dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0;
}
diff --git a/chromium/components/spellcheck/renderer/custom_dictionary_engine.h b/chromium/components/spellcheck/renderer/custom_dictionary_engine.h
index 52e37e6d179..33af5010db1 100644
--- a/chromium/components/spellcheck/renderer/custom_dictionary_engine.h
+++ b/chromium/components/spellcheck/renderer/custom_dictionary_engine.h
@@ -26,8 +26,8 @@ class CustomDictionaryEngine {
// |misspelling_start| and |misspelling_len| to indicate a misspelling.
// Returns true if there are no misspellings, otherwise returns false.
bool SpellCheckWord(const base::string16& text,
- int misspelling_start,
- int misspelling_len);
+ size_t misspelling_start,
+ size_t misspelling_len);
// Update custom dictionary words.
void OnCustomDictionaryChanged(const std::set<std::string>& words_added,
diff --git a/chromium/components/spellcheck/renderer/spellcheck.cc b/chromium/components/spellcheck/renderer/spellcheck.cc
index 67e8aa823ea..7ffa31648d8 100644
--- a/chromium/components/spellcheck/renderer/spellcheck.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck.cc
@@ -244,11 +244,11 @@ void SpellCheck::AddSpellcheckLanguage(base::File file,
bool SpellCheck::SpellCheckWord(
const base::char16* text_begin,
- int position_in_text,
- int text_length,
+ size_t position_in_text,
+ size_t text_length,
int tag,
- int* misspelling_start,
- int* misspelling_len,
+ size_t* misspelling_start,
+ size_t* misspelling_len,
std::vector<base::string16>* optional_suggestions) {
DCHECK(text_length >= position_in_text);
DCHECK(misspelling_start && misspelling_len) << "Out vars must be given.";
@@ -260,10 +260,10 @@ bool SpellCheck::SpellCheckWord(
// These are for holding misspelling or skippable word positions and lengths
// between calls to SpellcheckLanguage::SpellCheckWord.
- int possible_misspelling_start;
- int possible_misspelling_len;
+ size_t possible_misspelling_start;
+ size_t possible_misspelling_len;
// The longest sequence of text that all languages agree is skippable.
- int agreed_skippable_len;
+ size_t agreed_skippable_len;
// A vector of vectors containing spelling suggestions from different
// languages.
std::vector<std::vector<base::string16>> suggestions_list;
@@ -356,8 +356,8 @@ bool SpellCheck::SpellCheckParagraph(
// position and length of the first misspelled word and returns false when
// the text includes misspelled words. Therefore, we just repeat calling the
// function until it returns true to check the whole text.
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
while (position_in_text <= length) {
if (SpellCheckWord(text.c_str(), position_in_text, length, kNoTag,
&misspelling_start, &misspelling_length, nullptr)) {
@@ -369,7 +369,8 @@ bool SpellCheck::SpellCheckParagraph(
text, misspelling_start, misspelling_length)) {
textcheck_results.push_back(
WebTextCheckingResult(blink::kWebTextDecorationTypeSpelling,
- misspelling_start, misspelling_length));
+ base::checked_cast<int>(misspelling_start),
+ base::checked_cast<int>(misspelling_length)));
}
position_in_text = misspelling_start + misspelling_length;
}
@@ -485,8 +486,8 @@ void SpellCheck::CreateTextCheckingResults(
// Double-check misspelled words with out spellchecker and attach grammar
// markers to them if our spellchecker tells us they are correct words,
// i.e. they are probably contextually-misspelled words.
- int unused_misspelling_start = 0;
- int unused_misspelling_length = 0;
+ size_t unused_misspelling_start = 0;
+ size_t unused_misspelling_length = 0;
if (decoration == SpellCheckResult::SPELLING &&
SpellCheckWord(misspelled_word.c_str(), kNoOffset,
misspelled_word.length(), kNoTag,
diff --git a/chromium/components/spellcheck/renderer/spellcheck.h b/chromium/components/spellcheck/renderer/spellcheck.h
index 44c11686fca..e12e4f9218f 100644
--- a/chromium/components/spellcheck/renderer/spellcheck.h
+++ b/chromium/components/spellcheck/renderer/spellcheck.h
@@ -86,11 +86,11 @@ class SpellCheck : public base::SupportsWeakPtr<SpellCheck>,
// If optional_suggestions is NULL, suggested words will not be looked up.
// Note that doing suggest lookups can be slow.
bool SpellCheckWord(const base::char16* text_begin,
- int position_in_text,
- int text_length,
+ size_t position_in_text,
+ size_t text_length,
int tag,
- int* misspelling_start,
- int* misspelling_len,
+ size_t* misspelling_start,
+ size_t* misspelling_len,
std::vector<base::string16>* optional_suggestions);
// SpellCheck a paragraph.
diff --git a/chromium/components/spellcheck/renderer/spellcheck_language.cc b/chromium/components/spellcheck/renderer/spellcheck_language.cc
index a518c43cac6..391e36a9481 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_language.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_language.cc
@@ -34,16 +34,16 @@ bool SpellcheckLanguage::InitializeIfNeeded() {
SpellcheckLanguage::SpellcheckWordResult SpellcheckLanguage::SpellCheckWord(
const base::char16* text_begin,
- int position_in_text,
- int text_length,
+ size_t position_in_text,
+ size_t text_length,
int tag,
- int* skip_or_misspelling_start,
- int* skip_or_misspelling_len,
+ size_t* skip_or_misspelling_start,
+ size_t* skip_or_misspelling_len,
std::vector<base::string16>* optional_suggestions) {
- int remaining_text_len = text_length - position_in_text;
- DCHECK(remaining_text_len >= 0);
+ DCHECK_GE(text_length, position_in_text);
DCHECK(skip_or_misspelling_start && skip_or_misspelling_len)
<< "Out vars must be given.";
+ size_t remaining_text_len = text_length - position_in_text;
// Do nothing if we need to delay initialization. (Rather than blocking,
// report the word as correctly spelled.)
@@ -60,8 +60,8 @@ SpellcheckLanguage::SpellcheckWordResult SpellcheckLanguage::SpellCheckWord(
return IS_CORRECT; // No input means always spelled correctly.
base::string16 word;
- int word_start;
- int word_length;
+ size_t word_start;
+ size_t word_length;
if (!text_iterator_.IsInitialized() &&
!text_iterator_.Initialize(&character_attributes_, true)) {
// We failed to initialize text_iterator_, return as spelled correctly.
@@ -126,8 +126,8 @@ bool SpellcheckLanguage::IsValidContraction(const base::string16& contraction,
contraction_iterator_.SetText(contraction.c_str(), contraction.length());
base::string16 word;
- int word_start;
- int word_length;
+ size_t word_start;
+ size_t word_length;
DCHECK(platform_spelling_engine_);
for (SpellcheckWordIterator::WordIteratorStatus status =
diff --git a/chromium/components/spellcheck/renderer/spellcheck_language.h b/chromium/components/spellcheck/renderer/spellcheck_language.h
index 98bcf601244..082ce801bbb 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_language.h
+++ b/chromium/components/spellcheck/renderer/spellcheck_language.h
@@ -58,15 +58,15 @@ class SpellcheckLanguage {
// |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to
// the position and length of the misspelled word. In addition, finds the
// suggested words for a given misspelled word and puts them into
- // |*optional_suggestions|. If optional_suggestions is NULL, suggested words
- // will not be looked up. Note that doing suggest lookups can be slow.
+ // |*optional_suggestions|. If optional_suggestions is nullptr, suggested
+ // words will not be looked up. Note that doing suggest lookups can be slow.
SpellcheckWordResult SpellCheckWord(
const base::char16* text_begin,
- int position_in_text,
- int text_length,
+ size_t position_in_text,
+ size_t text_length,
int tag,
- int* skip_or_misspelling_start,
- int* skip_or_misspelling_len,
+ size_t* skip_or_misspelling_start,
+ size_t* skip_or_misspelling_len,
std::vector<base::string16>* optional_suggestions);
// Initialize |spellcheck_| if that hasn't happened yet.
diff --git a/chromium/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc b/chromium/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
index f3567981ed3..62bbdace258 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
@@ -31,8 +31,8 @@ struct SpellcheckTestCase {
// A string of text for checking.
const wchar_t* input;
// The position and the length of the first misspelled word, if any.
- int expected_misspelling_start;
- int expected_misspelling_length;
+ size_t expected_misspelling_start;
+ size_t expected_misspelling_length;
};
base::FilePath GetHunspellDirectory() {
@@ -82,8 +82,8 @@ class MultilingualSpellCheckTest : public testing::Test {
ReinitializeSpellCheck(languages);
for (size_t i = 0; i < num_test_cases; ++i) {
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
static_cast<blink::WebTextCheckClient*>(provider())
->CheckSpelling(blink::WebString::FromUTF16(
base::WideToUTF16(test_cases[i].input)),
@@ -225,8 +225,8 @@ TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckSuggestions) {
// A string of text for checking.
const wchar_t* input;
// The position and the length of the first invalid word.
- int expected_misspelling_start;
- int expected_misspelling_length;
+ size_t expected_misspelling_start;
+ size_t expected_misspelling_length;
// A comma separated string of suggested words that should occur, in their
// expected order.
const wchar_t* expected_suggestions;
@@ -240,8 +240,8 @@ TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckSuggestions) {
for (size_t i = 0; i < base::size(kTestCases); ++i) {
blink::WebVector<blink::WebString> suggestions;
- int misspelling_start;
- int misspelling_length;
+ size_t misspelling_start;
+ size_t misspelling_length;
static_cast<blink::WebTextCheckClient*>(provider())
->CheckSpelling(
blink::WebString::FromUTF16(base::WideToUTF16(kTestCases[i].input)),
diff --git a/chromium/components/spellcheck/renderer/spellcheck_provider.cc b/chromium/components/spellcheck/renderer/spellcheck_provider.cc
index 67b3a96eb0d..17bbd9c65b5 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_provider.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_provider.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
#include "components/spellcheck/common/spellcheck_result.h"
#include "components/spellcheck/renderer/spellcheck.h"
@@ -144,15 +145,18 @@ void SpellCheckProvider::RequestTextChecking(
}
void SpellCheckProvider::FocusedNodeChanged(const blink::WebNode& unused) {
-#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
+#if defined(OS_ANDROID)
+ if (!spell_check_host_.is_bound())
+ return;
+
WebLocalFrame* frame = render_frame()->GetWebFrame();
WebElement element = frame->GetDocument().IsNull()
? WebElement()
: frame->GetDocument().FocusedElement();
bool enabled = !element.IsNull() && element.IsEditable();
- bool checked = enabled && IsSpellCheckingEnabled();
- GetSpellCheckHost().ToggleSpellCheck(enabled, checked);
-#endif // USE_BROWSER_SPELLCHECKER
+ if (!enabled)
+ GetSpellCheckHost().DisconnectSessionBridge();
+#endif // defined(OS_ANDROID)
}
bool SpellCheckProvider::IsSpellCheckingEnabled() const {
@@ -161,8 +165,8 @@ bool SpellCheckProvider::IsSpellCheckingEnabled() const {
void SpellCheckProvider::CheckSpelling(
const WebString& text,
- int& offset,
- int& length,
+ size_t& offset,
+ size_t& length,
WebVector<WebString>* optional_suggestions) {
base::string16 word = text.Utf16();
std::vector<base::string16> suggestions;
@@ -176,9 +180,11 @@ void SpellCheckProvider::CheckSpelling(
suggestions.begin(), suggestions.end(), web_suggestions.begin(),
[](const base::string16& s) { return WebString::FromUTF16(s); });
*optional_suggestions = web_suggestions;
- UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check.suggestions", word.size());
+ UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check.suggestions",
+ base::saturated_cast<int>(word.size()));
} else {
- UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check", word.size());
+ UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.check",
+ base::saturated_cast<int>(word.size()));
// If optional_suggestions is not requested, the API is called
// for marking. So we use this for counting markable words.
GetSpellCheckHost().NotifyChecked(word, 0 < length);
@@ -189,7 +195,8 @@ void SpellCheckProvider::RequestCheckingOfText(
const WebString& text,
WebTextCheckingCompletion* completion) {
RequestTextChecking(text.Utf16(), completion);
- UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.async", text.length());
+ UMA_HISTOGRAM_COUNTS_1M("SpellCheck.api.async",
+ base::saturated_cast<int>(text.length()));
}
#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
@@ -226,11 +233,10 @@ void SpellCheckProvider::OnRespondSpellingService(
}
#endif
-bool SpellCheckProvider::HasWordCharacters(
- const base::string16& text,
- int index) const {
+bool SpellCheckProvider::HasWordCharacters(const base::string16& text,
+ size_t index) const {
const base::char16* data = text.data();
- int length = text.length();
+ size_t length = text.length();
while (index < length) {
uint32_t code = 0;
U16_NEXT(data, index, length, code);
diff --git a/chromium/components/spellcheck/renderer/spellcheck_provider.h b/chromium/components/spellcheck/renderer/spellcheck_provider.h
index 2a5f671212c..392186af91c 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_provider.h
+++ b/chromium/components/spellcheck/renderer/spellcheck_provider.h
@@ -90,8 +90,8 @@ class SpellCheckProvider
bool IsSpellCheckingEnabled() const override;
void CheckSpelling(
const blink::WebString& text,
- int& offset,
- int& length,
+ size_t& offset,
+ size_t& length,
blink::WebVector<blink::WebString>* optional_suggestions) override;
void RequestCheckingOfText(
const blink::WebString& text,
@@ -106,7 +106,7 @@ class SpellCheckProvider
// Returns whether |text| has word characters, i.e. whether a spellchecker
// needs to check this text.
- bool HasWordCharacters(const base::string16& text, int index) const;
+ bool HasWordCharacters(const base::string16& text, size_t index) const;
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
void OnRespondTextCheck(
diff --git a/chromium/components/spellcheck/renderer/spellcheck_provider_test.cc b/chromium/components/spellcheck/renderer/spellcheck_provider_test.cc
index 94fb1eb4273..4eb50cf95ae 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_provider_test.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_provider_test.cc
@@ -109,10 +109,6 @@ void TestingSpellCheckProvider::RequestTextCheck(
text_check_requests_.push_back(std::make_pair(text, std::move(callback)));
}
-void TestingSpellCheckProvider::ToggleSpellCheck(bool, bool) {
- NOTREACHED();
-}
-
void TestingSpellCheckProvider::CheckSpelling(const base::string16&,
int,
CheckSpellingCallback) {
@@ -125,6 +121,12 @@ void TestingSpellCheckProvider::FillSuggestionList(const base::string16&,
}
#endif // BUILDFLAG(USE_BROWSER_SPELLCHECKER)
+#if defined(OS_ANDROID)
+void TestingSpellCheckProvider::DisconnectSessionBridge() {
+ NOTREACHED();
+}
+#endif
+
void TestingSpellCheckProvider::SetLastResults(
const base::string16 last_request,
blink::WebVector<blink::WebTextCheckingResult>& last_results) {
diff --git a/chromium/components/spellcheck/renderer/spellcheck_provider_test.h b/chromium/components/spellcheck/renderer/spellcheck_provider_test.h
index 9e8534e46b3..65e4558cb0d 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_provider_test.h
+++ b/chromium/components/spellcheck/renderer/spellcheck_provider_test.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/strings/string16.h"
+#include "build/build_config.h"
#include "components/spellcheck/renderer/empty_local_interface_provider.h"
#include "components/spellcheck/renderer/spellcheck_provider.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -88,7 +89,6 @@ class TestingSpellCheckProvider : public SpellCheckProvider,
void RequestTextCheck(const base::string16&,
int,
RequestTextCheckCallback) override;
- void ToggleSpellCheck(bool, bool) override;
using SpellCheckProvider::CheckSpelling;
void CheckSpelling(const base::string16&,
int,
@@ -97,6 +97,10 @@ class TestingSpellCheckProvider : public SpellCheckProvider,
FillSuggestionListCallback) override;
#endif
+#if defined(OS_ANDROID)
+ void DisconnectSessionBridge() override;
+#endif
+
// Message loop (if needed) to deliver the SpellCheckHost request flow.
std::unique_ptr<base::MessageLoop> loop_;
diff --git a/chromium/components/spellcheck/renderer/spellcheck_unittest.cc b/chromium/components/spellcheck/renderer/spellcheck_unittest.cc
index 947ef734f83..0d84e856691 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_unittest.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -188,8 +188,8 @@ TEST_F(SpellCheckTest, SpellCheckStrings_EN_US) {
// * false: the input string has one or more invalid words.
bool expected_result;
// The position and the length of the first invalid word.
- int misspelling_start;
- int misspelling_length;
+ size_t misspelling_start;
+ size_t misspelling_length;
} kTestCases[] = {
// Empty strings.
{L"", true},
@@ -406,12 +406,11 @@ TEST_F(SpellCheckTest, SpellCheckStrings_EN_US) {
size_t input_length = 0;
if (kTestCases[i].input)
input_length = wcslen(kTestCases[i].input);
- int misspelling_start;
- int misspelling_length;
+ size_t misspelling_start;
+ size_t misspelling_length;
bool result = spell_check()->SpellCheckWord(
- base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset,
- static_cast<int>(input_length), kNoTag, &misspelling_start,
- &misspelling_length, nullptr);
+ base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset, input_length,
+ kNoTag, &misspelling_start, &misspelling_length, nullptr);
EXPECT_EQ(kTestCases[i].expected_result, result);
EXPECT_EQ(kTestCases[i].misspelling_start, misspelling_start);
@@ -455,12 +454,11 @@ TEST_F(SpellCheckTest, SpellCheckSuggestions_EN_US) {
size_t input_length = 0;
if (test_case.input)
input_length = wcslen(test_case.input);
- int misspelling_start;
- int misspelling_length;
+ size_t misspelling_start;
+ size_t misspelling_length;
bool result = spell_check()->SpellCheckWord(
- base::WideToUTF16(test_case.input).c_str(), kNoOffset,
- static_cast<int>(input_length), kNoTag, &misspelling_start,
- &misspelling_length, &suggestions);
+ base::WideToUTF16(test_case.input).c_str(), kNoOffset, input_length,
+ kNoTag, &misspelling_start, &misspelling_length, &suggestions);
// Check for spelling.
EXPECT_EQ(test_case.expected_result, result);
@@ -830,12 +828,11 @@ TEST_F(SpellCheckTest, SpellCheckText) {
if (kTestCases[i].input)
input_length = wcslen(kTestCases[i].input);
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
bool result = spell_check()->SpellCheckWord(
- base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset,
- static_cast<int>(input_length), kNoTag, &misspelling_start,
- &misspelling_length, nullptr);
+ base::WideToUTF16(kTestCases[i].input).c_str(), kNoOffset, input_length,
+ kNoTag, &misspelling_start, &misspelling_length, nullptr);
EXPECT_TRUE(result)
<< "\""
@@ -844,8 +841,8 @@ TEST_F(SpellCheckTest, SpellCheckText) {
<< "\" is misspelled in "
<< kTestCases[i].language
<< ".";
- EXPECT_EQ(0, misspelling_start);
- EXPECT_EQ(0, misspelling_length);
+ EXPECT_EQ(0u, misspelling_start);
+ EXPECT_EQ(0u, misspelling_length);
}
}
@@ -887,14 +884,14 @@ TEST_F(SpellCheckTest, MisspelledWords) {
ReinitializeSpellCheck(kTestCases[i].language);
base::string16 word(base::WideToUTF16(kTestCases[i].input));
- int word_length = static_cast<int>(word.length());
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t word_length = word.length();
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
bool result = spell_check()->SpellCheckWord(
word.c_str(), kNoOffset, word_length, kNoTag, &misspelling_start,
&misspelling_length, nullptr);
EXPECT_FALSE(result);
- EXPECT_EQ(0, misspelling_start);
+ EXPECT_EQ(0u, misspelling_start);
EXPECT_EQ(word_length, misspelling_length);
}
}
@@ -1298,12 +1295,12 @@ TEST_F(SpellCheckTest, EnglishWords) {
if (kTestCases[i].input)
input_length = strlen(kTestCases[i].input);
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
bool result = spell_check()->SpellCheckWord(
base::ASCIIToUTF16(kTestCases[i].input).c_str(), kNoOffset,
- static_cast<int>(input_length), kNoTag, &misspelling_start,
- &misspelling_length, nullptr);
+ input_length, kNoTag, &misspelling_start, &misspelling_length,
+ nullptr);
EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].input <<
" in " << kLocales[j];
@@ -1342,12 +1339,12 @@ TEST_F(SpellCheckTest, NoSuggest) {
// First check that the NOSUGGEST flag didn't mark this word as not being in
// the dictionary.
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
bool result = spell_check()->SpellCheckWord(
base::ASCIIToUTF16(test_case.suggestion).c_str(), kNoOffset,
- static_cast<int>(suggestion_length), kNoTag, &misspelling_start,
- &misspelling_length, nullptr);
+ suggestion_length, kNoTag, &misspelling_start, &misspelling_length,
+ nullptr);
EXPECT_EQ(test_case.should_pass, result)
<< test_case.suggestion << " in " << test_case.locale;
@@ -1360,7 +1357,7 @@ TEST_F(SpellCheckTest, NoSuggest) {
input_length = strlen(test_case.input);
result = spell_check()->SpellCheckWord(
base::ASCIIToUTF16(test_case.input).c_str(), kNoOffset,
- static_cast<int>(input_length), kNoTag, &misspelling_start,
+ input_length, kNoTag, &misspelling_start,
&misspelling_length, &suggestions);
// Input word should be a misspelling.
EXPECT_FALSE(result) << test_case.input << " is not a misspelling in "
@@ -1443,8 +1440,8 @@ TEST_F(SpellCheckTest, LogicalSuggestions) {
};
for (size_t i = 0; i < base::size(kTestCases); ++i) {
- int misspelling_start = 0;
- int misspelling_length = 0;
+ size_t misspelling_start = 0;
+ size_t misspelling_length = 0;
std::vector<base::string16> suggestions;
EXPECT_FALSE(spell_check()->SpellCheckWord(
base::ASCIIToUTF16(kTestCases[i].misspelled).c_str(),
@@ -1505,13 +1502,14 @@ TEST_F(SpellCheckTest, FillSuggestions_OneLanguageManySuggestions) {
suggestions_list.resize(1);
for (int i = 0; i < spellcheck::kMaxSuggestions + 2; ++i)
- suggestions_list[0].push_back(base::ASCIIToUTF16(base::IntToString(i)));
+ suggestions_list[0].push_back(base::ASCIIToUTF16(base::NumberToString(i)));
FillSuggestions(suggestions_list, &suggestion_results);
ASSERT_EQ(static_cast<size_t>(spellcheck::kMaxSuggestions),
suggestion_results.size());
for (int i = 0; i < spellcheck::kMaxSuggestions; ++i)
- EXPECT_EQ(base::ASCIIToUTF16(base::IntToString(i)), suggestion_results[i]);
+ EXPECT_EQ(base::ASCIIToUTF16(base::NumberToString(i)),
+ suggestion_results[i]);
}
TEST_F(SpellCheckTest, FillSuggestions_RemoveDuplicates) {
@@ -1538,7 +1536,7 @@ TEST_F(SpellCheckTest, FillSuggestions_TwoLanguages) {
suggestions_list.resize(2);
for (size_t i = 0; i < 2; ++i) {
- std::string prefix = base::IntToString(i);
+ std::string prefix = base::NumberToString(i);
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo"));
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar"));
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz"));
@@ -1562,7 +1560,7 @@ TEST_F(SpellCheckTest, FillSuggestions_ThreeLanguages) {
suggestions_list.resize(3);
for (size_t i = 0; i < 3; ++i) {
- std::string prefix = base::IntToString(i);
+ std::string prefix = base::NumberToString(i);
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo"));
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar"));
suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz"));
diff --git a/chromium/components/spellcheck/renderer/spellcheck_worditerator.cc b/chromium/components/spellcheck/renderer/spellcheck_worditerator.cc
index 00351e19010..8fe8a6df381 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_worditerator.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_worditerator.cc
@@ -364,8 +364,8 @@ bool SpellcheckWordIterator::SetText(const base::char16* text, size_t length) {
SpellcheckWordIterator::WordIteratorStatus SpellcheckWordIterator::GetNextWord(
base::string16* word_string,
- int* word_start,
- int* word_length) {
+ size_t* word_start,
+ size_t* word_length) {
DCHECK(!!text_);
word_string->clear();
@@ -414,8 +414,8 @@ void SpellcheckWordIterator::Reset() {
iterator_.reset();
}
-bool SpellcheckWordIterator::Normalize(int input_start,
- int input_length,
+bool SpellcheckWordIterator::Normalize(size_t input_start,
+ size_t input_length,
base::string16* output_string) const {
// We use NFKC (Normalization Form, Compatible decomposition, followed by
// canonical Composition) defined in Unicode Standard Annex #15 to normalize
@@ -424,7 +424,8 @@ bool SpellcheckWordIterator::Normalize(int input_start,
// spellchecker and we need manual normalization as well. The normalized
// text does not have to be NUL-terminated since its characters are copied to
// string16, which adds a NUL character when we need.
- icu::UnicodeString input(FALSE, &text_[input_start], input_length);
+ icu::UnicodeString input(FALSE, &text_[input_start],
+ base::checked_cast<int32_t>(input_length));
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString output;
icu::Normalizer::normalize(input, UNORM_NFKC, 0, output, status);
diff --git a/chromium/components/spellcheck/renderer/spellcheck_worditerator.h b/chromium/components/spellcheck/renderer/spellcheck_worditerator.h
index ea2f038c1de..cf3d6cf1efb 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_worditerator.h
+++ b/chromium/components/spellcheck/renderer/spellcheck_worditerator.h
@@ -165,8 +165,10 @@ class SpellcheckWordIterator {
// length into |word_string|, |word_start|, and |word_length| respectively.
//
// - Returns IS_END_OF_TEXT if the iterator has reached the end of |text_|.
- SpellcheckWordIterator::WordIteratorStatus
- GetNextWord(base::string16* word_string, int* word_start, int* word_length);
+ SpellcheckWordIterator::WordIteratorStatus GetNextWord(
+ base::string16* word_string,
+ size_t* word_start,
+ size_t* word_length);
// Releases all the resources attached to this object.
void Reset();
@@ -179,8 +181,8 @@ class SpellcheckWordIterator {
// alternative characters supported by our spellchecker. This function also
// calls SpellcheckWordIterator::OutputChar() to filter out false-positive
// characters.
- bool Normalize(int input_start,
- int input_length,
+ bool Normalize(size_t input_start,
+ size_t input_length,
base::string16* output_string) const;
// The pointer to the input string from which we are extracting words.
diff --git a/chromium/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc b/chromium/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
index e415d5e9bca..4ab4c4f3ac3 100644
--- a/chromium/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
+++ b/chromium/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
@@ -35,8 +35,8 @@ base::string16 GetRulesForLanguage(const std::string& language) {
WordIteratorStatus GetNextNonSkippableWord(SpellcheckWordIterator* iterator,
base::string16* word_string,
- int* word_start,
- int* word_length) {
+ size_t* word_start,
+ size_t* word_length) {
WordIteratorStatus status = SpellcheckWordIterator::IS_SKIPPABLE;
while (status == SpellcheckWordIterator::IS_SKIPPABLE)
status = iterator->GetNextWord(word_string, word_start, word_length);
@@ -174,7 +174,7 @@ TEST(SpellcheckWordIteratorTest, SplitWord) {
base::string16(1, ' '), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
base::string16 actual_word;
- int actual_start, actual_len;
+ size_t actual_start, actual_len;
size_t index = 0;
for (SpellcheckWordIterator::WordIteratorStatus status =
iterator.GetNextWord(&actual_word, &actual_start, &actual_len);
@@ -210,13 +210,13 @@ TEST(SpellcheckWordIteratorTest, RuleSetConsistency) {
// iterator.GetNextWord() calls get stuck in an infinite loop. Therefore, this
// test succeeds if this call returns without timeouts.
base::string16 actual_word;
- int actual_start, actual_len;
+ size_t actual_start, actual_len;
WordIteratorStatus status = GetNextNonSkippableWord(
&iterator, &actual_word, &actual_start, &actual_len);
EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_END_OF_TEXT, status);
- EXPECT_EQ(0, actual_start);
- EXPECT_EQ(0, actual_len);
+ EXPECT_EQ(0u, actual_start);
+ EXPECT_EQ(0u, actual_len);
}
// Vertify our SpellcheckWordIterator can treat ASCII numbers as word characters
@@ -274,7 +274,7 @@ TEST(SpellcheckWordIteratorTest, TreatNumbersAsWordCharacters) {
EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length()));
base::string16 actual_word;
- int actual_start, actual_len;
+ size_t actual_start, actual_len;
WordIteratorStatus status = GetNextNonSkippableWord(
&iterator, &actual_word, &actual_start, &actual_len);
@@ -319,15 +319,14 @@ TEST(SpellcheckWordIteratorTest, TypographicalApostropheIsPartOfWord) {
EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length()));
base::string16 actual_word;
- int actual_start, actual_len;
+ size_t actual_start, actual_len;
WordIteratorStatus status = GetNextNonSkippableWord(
&iterator, &actual_word, &actual_start, &actual_len);
EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status);
EXPECT_EQ(expected_word, actual_word);
- EXPECT_LE(0, actual_start);
- EXPECT_EQ(expected_word.length(),
- static_cast<base::string16::size_type>(actual_len));
+ EXPECT_LE(0u, actual_start);
+ EXPECT_EQ(expected_word.length(), actual_len);
}
}
diff --git a/chromium/components/ssl_errors/error_classification_unittest.cc b/chromium/components/ssl_errors/error_classification_unittest.cc
index ea281edf34f..6161d194b4d 100644
--- a/chromium/components/ssl_errors/error_classification_unittest.cc
+++ b/chromium/components/ssl_errors/error_classification_unittest.cc
@@ -6,6 +6,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/strings/string_split.h"
#include "base/test/metrics/histogram_tester.h"
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 8125f38ea87..5884adad31f 100644
--- a/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/chromium/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -21,7 +21,6 @@
#include "base/threading/platform_thread.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
-#include "components/metrics/legacy_call_stack_profile_builder.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/startup_metric_utils/browser/pref_names.h"
@@ -293,7 +292,8 @@ std::string GetSameVersionStartupCountSuffix() {
DCHECK_GE(g_startups_with_current_version, 1);
if (g_startups_with_current_version > kMaxSameVersionCountRecorded)
return ".Over";
- return std::string(".") + base::IntToString(g_startups_with_current_version);
+ return std::string(".") +
+ base::NumberToString(g_startups_with_current_version);
}
// Returns the system uptime on process launch.
@@ -578,8 +578,6 @@ void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
RecordHardFaultHistogram();
// Record timing of the browser message-loop start time.
- metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
- metrics::LegacyCallStackProfileBuilder::MAIN_LOOP_START);
if (!is_first_run && !g_process_creation_ticks.is_null()) {
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserMessageLoopStartTime",
@@ -701,8 +699,6 @@ void RecordFirstWebContentsNonEmptyPaint(
if (!ShouldLogStartupHistogram())
return;
- metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
- metrics::LegacyCallStackProfileBuilder::FIRST_NONEMPTY_PAINT);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.NonEmptyPaint2",
g_process_creation_ticks, now);
@@ -726,8 +722,6 @@ void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks,
if (!ShouldLogStartupHistogram())
return;
- metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
- metrics::LegacyCallStackProfileBuilder::MAIN_NAVIGATION_START);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100,
"Startup.FirstWebContents.MainNavigationStart", g_process_creation_ticks,
@@ -757,8 +751,6 @@ void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks) {
if (!ShouldLogStartupHistogram())
return;
- metrics::LegacyCallStackProfileBuilder::SetProcessMilestone(
- metrics::LegacyCallStackProfileBuilder::MAIN_NAVIGATION_FINISHED);
UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT(
UMA_HISTOGRAM_LONG_TIMES_100,
"Startup.FirstWebContents.MainNavigationFinished",
diff --git a/chromium/components/storage_monitor/image_capture_device.mm b/chromium/components/storage_monitor/image_capture_device.mm
index e199aa039db..d0fea0272a7 100644
--- a/chromium/components/storage_monitor/image_capture_device.mm
+++ b/chromium/components/storage_monitor/image_capture_device.mm
@@ -4,6 +4,7 @@
#import "components/storage_monitor/image_capture_device.h"
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
diff --git a/chromium/components/storage_monitor/image_capture_device_manager_unittest.mm b/chromium/components/storage_monitor/image_capture_device_manager_unittest.mm
index df886190499..a0f39249d48 100644
--- a/chromium/components/storage_monitor/image_capture_device_manager_unittest.mm
+++ b/chromium/components/storage_monitor/image_capture_device_manager_unittest.mm
@@ -286,7 +286,7 @@ TEST_F(ImageCaptureDeviceManagerTest, TestAttachDetach) {
DetachDevice(&manager, device);
devices = monitor_->GetAllAvailableStorages();
ASSERT_EQ(0U, devices.size());
-};
+}
TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) {
ImageCaptureDeviceManager manager;
diff --git a/chromium/components/storage_monitor/media_storage_util.cc b/chromium/components/storage_monitor/media_storage_util.cc
index 42adaf3d6b8..ee054d8780f 100644
--- a/chromium/components/storage_monitor/media_storage_util.cc
+++ b/chromium/components/storage_monitor/media_storage_util.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/logging.h"
diff --git a/chromium/components/storage_monitor/media_storage_util_unittest.cc b/chromium/components/storage_monitor/media_storage_util_unittest.cc
index 1ede541f9da..142c54c7097 100644
--- a/chromium/components/storage_monitor/media_storage_util_unittest.cc
+++ b/chromium/components/storage_monitor/media_storage_util_unittest.cc
@@ -4,6 +4,7 @@
#include <string>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
diff --git a/chromium/components/storage_monitor/mtab_watcher_linux.cc b/chromium/components/storage_monitor/mtab_watcher_linux.cc
index ff7c787c6f3..5a53b71133f 100644
--- a/chromium/components/storage_monitor/mtab_watcher_linux.cc
+++ b/chromium/components/storage_monitor/mtab_watcher_linux.cc
@@ -57,7 +57,8 @@ MtabWatcherLinux::~MtabWatcherLinux() {
void MtabWatcherLinux::ReadMtab() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
FILE* fp = setmntent(mtab_path_.value().c_str(), "r");
if (!fp)
diff --git a/chromium/components/storage_monitor/mtp_manager_client_chromeos.cc b/chromium/components/storage_monitor/mtp_manager_client_chromeos.cc
index 1d4beaa622a..a52b3ebf8ec 100644
--- a/chromium/components/storage_monitor/mtp_manager_client_chromeos.cc
+++ b/chromium/components/storage_monitor/mtp_manager_client_chromeos.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "components/storage_monitor/storage_info.h"
#include "components/storage_monitor/storage_info_utils.h"
diff --git a/chromium/components/storage_monitor/portable_device_watcher_win.cc b/chromium/components/storage_monitor/portable_device_watcher_win.cc
index 20d7cef05c4..96756d680ed 100644
--- a/chromium/components/storage_monitor/portable_device_watcher_win.cc
+++ b/chromium/components/storage_monitor/portable_device_watcher_win.cc
@@ -13,6 +13,7 @@
#include <portabledevice.h>
#include <wrl/client.h>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/stl_util.h"
@@ -316,7 +317,8 @@ base::string16 GetDeviceNameOnBlockingThread(
IPortableDeviceManager* portable_device_manager,
const base::string16& pnp_device_id) {
DCHECK(portable_device_manager);
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::string16 name;
GetFriendlyName(pnp_device_id, portable_device_manager, &name) ||
GetDeviceDescription(pnp_device_id, portable_device_manager, &name) ||
@@ -330,7 +332,8 @@ bool GetDeviceStorageObjectsOnBlockingThread(
const base::string16& pnp_device_id,
PortableDeviceWatcherWin::StorageObjects* storage_objects) {
DCHECK(storage_objects);
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
Microsoft::WRL::ComPtr<IPortableDevice> device;
if (!SetUp(pnp_device_id, &device))
return false;
@@ -370,7 +373,8 @@ bool GetDeviceInfoOnBlockingThread(
DCHECK(portable_device_manager);
DCHECK(device_details);
DCHECK(!pnp_device_id.empty());
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
device_details->name = GetDeviceNameOnBlockingThread(portable_device_manager,
pnp_device_id);
if (IsMassStoragePortableDevice(pnp_device_id, device_details->name))
@@ -386,7 +390,8 @@ bool GetDeviceInfoOnBlockingThread(
// returns true and fills in |portable_device_mgr|. On failure, returns false.
bool GetPortableDeviceManager(
Microsoft::WRL::ComPtr<IPortableDeviceManager>* portable_device_mgr) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
HRESULT hr = ::CoCreateInstance(
__uuidof(PortableDeviceManager), nullptr, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(portable_device_mgr->GetAddressOf()));
@@ -405,7 +410,8 @@ bool GetPortableDeviceManager(
bool EnumerateAttachedDevicesOnBlockingThread(
PortableDeviceWatcherWin::Devices* devices) {
DCHECK(devices);
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
Microsoft::WRL::ComPtr<IPortableDeviceManager> portable_device_mgr;
if (!GetPortableDeviceManager(&portable_device_mgr))
return false;
@@ -440,7 +446,8 @@ bool HandleDeviceAttachedEventOnBlockingThread(
const base::string16& pnp_device_id,
PortableDeviceWatcherWin::DeviceDetails* device_details) {
DCHECK(device_details);
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
Microsoft::WRL::ComPtr<IPortableDeviceManager> portable_device_mgr;
if (!GetPortableDeviceManager(&portable_device_mgr))
return false;
diff --git a/chromium/components/storage_monitor/storage_info_utils.cc b/chromium/components/storage_monitor/storage_info_utils.cc
index 0f94ea57eea..601abe38321 100644
--- a/chromium/components/storage_monitor/storage_info_utils.cc
+++ b/chromium/components/storage_monitor/storage_info_utils.cc
@@ -58,8 +58,8 @@ std::string GetDeviceIdFromStorageInfo(
// Some devices have multiple data stores. Therefore, include storage id as
// part of unique id along with vendor, model and volume information.
- const std::string vendor_id = base::UintToString(storage_info.vendor_id);
- const std::string model_id = base::UintToString(storage_info.product_id);
+ const std::string vendor_id = base::NumberToString(storage_info.vendor_id);
+ const std::string model_id = base::NumberToString(storage_info.product_id);
return StorageInfo::MakeDeviceId(
StorageInfo::MTP_OR_PTP,
kVendorModelVolumeStoragePrefix + vendor_id + ":" + model_id + ":" +
diff --git a/chromium/components/storage_monitor/storage_monitor.h b/chromium/components/storage_monitor/storage_monitor.h
index 250a5ed1de5..f7f88e6f17c 100644
--- a/chromium/components/storage_monitor/storage_monitor.h
+++ b/chromium/components/storage_monitor/storage_monitor.h
@@ -21,7 +21,7 @@
#include "services/service_manager/public/cpp/connector.h"
#if defined(OS_CHROMEOS)
-#include "services/device/public/mojom/mtp_manager.mojom.h"
+#include "services/device/public/mojom/mtp_manager.mojom-forward.h"
#endif
class MediaFileSystemRegistryTest;
diff --git a/chromium/components/storage_monitor/storage_monitor_chromeos.cc b/chromium/components/storage_monitor/storage_monitor_chromeos.cc
index cfb65cf5924..9bcee56e6a7 100644
--- a/chromium/components/storage_monitor/storage_monitor_chromeos.cc
+++ b/chromium/components/storage_monitor/storage_monitor_chromeos.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
diff --git a/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc b/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
index 2ecc82cd4e8..65b86366213 100644
--- a/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_chromeos_unittest.cc
@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
diff --git a/chromium/components/storage_monitor/storage_monitor_linux.cc b/chromium/components/storage_monitor/storage_monitor_linux.cc
index 4a07af229d7..bc5fe100295 100644
--- a/chromium/components/storage_monitor/storage_monitor_linux.cc
+++ b/chromium/components/storage_monitor/storage_monitor_linux.cc
@@ -18,6 +18,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/kill.h"
@@ -115,7 +116,8 @@ uint64_t GetDeviceStorageSize(const base::FilePath& device_path,
// Gets the device information using udev library.
std::unique_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path,
const base::FilePath& mount_point) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
DCHECK(!device_path.empty());
std::unique_ptr<StorageInfo> storage_info;
@@ -189,7 +191,7 @@ void BounceMtabUpdateToStorageMonitorTaskRunner(
const MtabWatcherLinux::UpdateMtabCallback& callback,
const MtabWatcherLinux::MountPointDeviceMap& new_mtab) {
storage_monitor_task_runner->PostTask(FROM_HERE,
- base::Bind(callback, new_mtab));
+ base::BindOnce(callback, new_mtab));
}
MtabWatcherLinux* CreateMtabWatcherLinuxOnMtabWatcherTaskRunner(
@@ -205,7 +207,8 @@ MtabWatcherLinux* CreateMtabWatcherLinuxOnMtabWatcherTaskRunner(
StorageMonitor::EjectStatus EjectPathOnBlockingTaskRunner(
const base::FilePath& path,
const base::FilePath& device) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
// Note: Linux LSB says umount should exist in /bin.
static const char kUmountBinary[] = "/bin/umount";
diff --git a/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc b/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
index f68726743e7..0f05e6e8935 100644
--- a/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_linux_unittest.cc
@@ -14,6 +14,7 @@
#include <memory>
#include <string>
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
diff --git a/chromium/components/storage_monitor/storage_monitor_mac.mm b/chromium/components/storage_monitor/storage_monitor_mac.mm
index bfa8536b593..a57b21258e3 100644
--- a/chromium/components/storage_monitor/storage_monitor_mac.mm
+++ b/chromium/components/storage_monitor/storage_monitor_mac.mm
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include "base/bind.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
@@ -53,7 +54,8 @@ StorageInfo::Type GetDeviceType(bool is_removable, bool has_dcim) {
StorageInfo BuildStorageInfo(
CFDictionaryRef dict, std::string* bsd_name) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
CFStringRef device_bsd_name = base::mac::GetValueFromDictionary<CFStringRef>(
dict, kDADiskDescriptionMediaBSDNameKey);
@@ -305,7 +307,7 @@ void StorageMonitorMac::EjectDevice(
options->callback = callback;
options->disk = std::move(disk);
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
- base::Bind(EjectDisk, options));
+ base::BindOnce(EjectDisk, options));
}
// static
diff --git a/chromium/components/storage_monitor/storage_monitor_mac_unittest.mm b/chromium/components/storage_monitor/storage_monitor_mac_unittest.mm
index fcbeeeaa494..eb6e34030d5 100644
--- a/chromium/components/storage_monitor/storage_monitor_mac_unittest.mm
+++ b/chromium/components/storage_monitor/storage_monitor_mac_unittest.mm
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -61,9 +62,9 @@ class StorageMonitorMacTest : public testing::Test {
void UpdateDisk(StorageInfo info, StorageMonitorMac::UpdateType update_type) {
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
- base::Bind(&StorageMonitorMac::UpdateDisk,
- base::Unretained(monitor_.get()), update_type,
- base::Owned(new std::string("dummy_bsd_name")), info));
+ base::BindOnce(&StorageMonitorMac::UpdateDisk,
+ base::Unretained(monitor_.get()), update_type,
+ base::Owned(new std::string("dummy_bsd_name")), info));
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/components/storage_monitor/storage_monitor_unittest.cc b/chromium/components/storage_monitor/storage_monitor_unittest.cc
index 68df1fe1db2..3bf96fb7441 100644
--- a/chromium/components/storage_monitor/storage_monitor_unittest.cc
+++ b/chromium/components/storage_monitor/storage_monitor_unittest.cc
@@ -4,6 +4,7 @@
#include "components/storage_monitor/storage_monitor.h"
+#include "base/bind.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/test_media_transfer_protocol_manager_chromeos.cc b/chromium/components/storage_monitor/test_media_transfer_protocol_manager_chromeos.cc
index bd425bed05a..f669570ed88 100644
--- a/chromium/components/storage_monitor/test_media_transfer_protocol_manager_chromeos.cc
+++ b/chromium/components/storage_monitor/test_media_transfer_protocol_manager_chromeos.cc
@@ -9,6 +9,8 @@
#include <vector>
#include "base/no_destructor.h"
+#include "services/device/public/mojom/mtp_file_entry.mojom.h"
+#include "services/device/public/mojom/mtp_storage_info.mojom.h"
namespace storage_monitor {
diff --git a/chromium/components/storage_monitor/test_storage_monitor.cc b/chromium/components/storage_monitor/test_storage_monitor.cc
index b13eee16e4d..501aeec03e4 100644
--- a/chromium/components/storage_monitor/test_storage_monitor.cc
+++ b/chromium/components/storage_monitor/test_storage_monitor.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "build/build_config.h"
diff --git a/chromium/components/storage_monitor/test_storage_monitor.h b/chromium/components/storage_monitor/test_storage_monitor.h
index ead83604607..d851e1495c0 100644
--- a/chromium/components/storage_monitor/test_storage_monitor.h
+++ b/chromium/components/storage_monitor/test_storage_monitor.h
@@ -12,6 +12,10 @@
#include "build/build_config.h"
#include "components/storage_monitor/storage_monitor.h"
+#if defined(OS_CHROMEOS)
+#include "services/device/public/mojom/mtp_manager.mojom.h"
+#endif
+
namespace storage_monitor {
class TestStorageMonitor : public StorageMonitor {
diff --git a/chromium/components/storage_monitor/volume_mount_watcher_win.cc b/chromium/components/storage_monitor/volume_mount_watcher_win.cc
index d388d48b451..8d4f3b1a036 100644
--- a/chromium/components/storage_monitor/volume_mount_watcher_win.cc
+++ b/chromium/components/storage_monitor/volume_mount_watcher_win.cc
@@ -15,6 +15,7 @@
#include <algorithm>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -226,7 +227,7 @@ void EjectDeviceInThreadPool(
device != device.DirName()) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_FAILURE));
+ base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
return;
}
base::SStringPrintf(&volume_name, L"\\\\.\\%lc:", drive_letter);
@@ -238,7 +239,7 @@ void EjectDeviceInThreadPool(
if (!volume_handle.IsValid()) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_FAILURE));
+ base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
return;
}
@@ -260,15 +261,15 @@ void EjectDeviceInThreadPool(
// transient disk lock.
task_runner->PostDelayedTask(
FROM_HERE,
- base::Bind(&EjectDeviceInThreadPool,
- device, callback, task_runner, iteration + 1),
+ base::BindOnce(&EjectDeviceInThreadPool, device, callback,
+ task_runner, iteration + 1),
kLockRetryInterval);
return;
}
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_IN_USE));
+ base::BindOnce(callback, StorageMonitor::EJECT_IN_USE));
return;
}
@@ -284,8 +285,9 @@ void EjectDeviceInThreadPool(
if (!dismounted) {
DeviceIoControl(volume_handle.Get(), FSCTL_UNLOCK_VOLUME, nullptr, 0,
nullptr, 0, &bytes_returned, nullptr);
- base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_OK));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback, StorageMonitor::EJECT_OK));
return;
}
@@ -297,7 +299,7 @@ void EjectDeviceInThreadPool(
&bytes_returned, nullptr)) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_FAILURE));
+ base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
return;
}
@@ -306,12 +308,12 @@ void EjectDeviceInThreadPool(
0, nullptr, 0, &bytes_returned, nullptr)) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_FAILURE));
+ base::BindOnce(callback, StorageMonitor::EJECT_FAILURE));
return;
}
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
- base::Bind(callback, StorageMonitor::EJECT_OK));
+ base::BindOnce(callback, StorageMonitor::EJECT_OK));
}
} // namespace
@@ -361,9 +363,9 @@ void VolumeMountWatcherWin::AddDevicesOnUIThread(
pending_device_checks_.insert(removable_devices[i]);
device_info_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd,
- removable_devices[i], GetDeviceDetailsCallback(),
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd,
+ removable_devices[i], GetDeviceDetailsCallback(),
+ weak_factory_.GetWeakPtr()));
}
}
@@ -376,15 +378,15 @@ void VolumeMountWatcherWin::RetrieveInfoForDeviceAndAdd(
if (!get_device_details_callback.Run(device_path, &info)) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(&VolumeMountWatcherWin::DeviceCheckComplete, volume_watcher,
- device_path));
+ base::BindOnce(&VolumeMountWatcherWin::DeviceCheckComplete,
+ volume_watcher, device_path));
return;
}
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
- base::Bind(&VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread,
- volume_watcher, device_path, info));
+ base::BindOnce(&VolumeMountWatcherWin::HandleDeviceAttachEventOnUIThread,
+ volume_watcher, device_path, info));
}
void VolumeMountWatcherWin::DeviceCheckComplete(
@@ -533,8 +535,8 @@ void VolumeMountWatcherWin::EjectDevice(
}
device_info_task_runner_->PostTask(
- FROM_HERE, base::Bind(&EjectDeviceInThreadPool, device, callback,
- device_info_task_runner_, 0));
+ FROM_HERE, base::BindOnce(&EjectDeviceInThreadPool, device, callback,
+ device_info_task_runner_, 0));
}
} // namespace storage_monitor
diff --git a/chromium/components/strings/BUILD.gn b/chromium/components/strings/BUILD.gn
index ffdbb787a87..0317fd69c36 100644
--- a/chromium/components/strings/BUILD.gn
+++ b/chromium/components/strings/BUILD.gn
@@ -13,17 +13,20 @@ if (is_android) {
"java/res/values-am/components_strings.xml",
"java/res/values-ar/components_strings.xml",
"java/res/values-bg/components_strings.xml",
+ "java/res/values-bn/components_strings.xml",
"java/res/values-ca/components_strings.xml",
"java/res/values-cs/components_strings.xml",
"java/res/values-da/components_strings.xml",
"java/res/values-de/components_strings.xml",
"java/res/values-el/components_strings.xml",
"java/res/values-en-rGB/components_strings.xml",
- "java/res/values-es-rUS/components_strings.xml",
"java/res/values-es/components_strings.xml",
+ "java/res/values-es-rUS/components_strings.xml",
+ "java/res/values-et/components_strings.xml",
"java/res/values-fa/components_strings.xml",
"java/res/values-fi/components_strings.xml",
"java/res/values-fr/components_strings.xml",
+ "java/res/values-gu/components_strings.xml",
"java/res/values-hi/components_strings.xml",
"java/res/values-hr/components_strings.xml",
"java/res/values-hu/components_strings.xml",
@@ -31,9 +34,13 @@ if (is_android) {
"java/res/values-it/components_strings.xml",
"java/res/values-iw/components_strings.xml",
"java/res/values-ja/components_strings.xml",
+ "java/res/values-kn/components_strings.xml",
"java/res/values-ko/components_strings.xml",
"java/res/values-lt/components_strings.xml",
"java/res/values-lv/components_strings.xml",
+ "java/res/values-ml/components_strings.xml",
+ "java/res/values-mr/components_strings.xml",
+ "java/res/values-ms/components_strings.xml",
"java/res/values-nb/components_strings.xml",
"java/res/values-nl/components_strings.xml",
"java/res/values-pl/components_strings.xml",
@@ -46,6 +53,8 @@ if (is_android) {
"java/res/values-sr/components_strings.xml",
"java/res/values-sv/components_strings.xml",
"java/res/values-sw/components_strings.xml",
+ "java/res/values-ta/components_strings.xml",
+ "java/res/values-te/components_strings.xml",
"java/res/values-th/components_strings.xml",
"java/res/values-tl/components_strings.xml",
"java/res/values-tr/components_strings.xml",
@@ -121,17 +130,20 @@ if (is_android) {
"java/res/values-am/components_locale_settings.xml",
"java/res/values-ar/components_locale_settings.xml",
"java/res/values-bg/components_locale_settings.xml",
+ "java/res/values-bn/components_locale_settings.xml",
"java/res/values-ca/components_locale_settings.xml",
"java/res/values-cs/components_locale_settings.xml",
"java/res/values-da/components_locale_settings.xml",
"java/res/values-de/components_locale_settings.xml",
"java/res/values-el/components_locale_settings.xml",
"java/res/values-en-rGB/components_locale_settings.xml",
- "java/res/values-es-rUS/components_locale_settings.xml",
"java/res/values-es/components_locale_settings.xml",
+ "java/res/values-es-rUS/components_locale_settings.xml",
+ "java/res/values-et/components_locale_settings.xml",
"java/res/values-fa/components_locale_settings.xml",
"java/res/values-fi/components_locale_settings.xml",
"java/res/values-fr/components_locale_settings.xml",
+ "java/res/values-gu/components_locale_settings.xml",
"java/res/values-hi/components_locale_settings.xml",
"java/res/values-hr/components_locale_settings.xml",
"java/res/values-hu/components_locale_settings.xml",
@@ -139,9 +151,13 @@ if (is_android) {
"java/res/values-it/components_locale_settings.xml",
"java/res/values-iw/components_locale_settings.xml",
"java/res/values-ja/components_locale_settings.xml",
+ "java/res/values-kn/components_locale_settings.xml",
"java/res/values-ko/components_locale_settings.xml",
"java/res/values-lt/components_locale_settings.xml",
"java/res/values-lv/components_locale_settings.xml",
+ "java/res/values-ml/components_locale_settings.xml",
+ "java/res/values-mr/components_locale_settings.xml",
+ "java/res/values-ms/components_locale_settings.xml",
"java/res/values-nb/components_locale_settings.xml",
"java/res/values-nl/components_locale_settings.xml",
"java/res/values-pl/components_locale_settings.xml",
@@ -154,6 +170,8 @@ if (is_android) {
"java/res/values-sr/components_locale_settings.xml",
"java/res/values-sv/components_locale_settings.xml",
"java/res/values-sw/components_locale_settings.xml",
+ "java/res/values-ta/components_locale_settings.xml",
+ "java/res/values-te/components_locale_settings.xml",
"java/res/values-th/components_locale_settings.xml",
"java/res/values-tl/components_locale_settings.xml",
"java/res/values-tr/components_locale_settings.xml",
diff --git a/chromium/components/strings/components_chromium_strings_hi.xtb b/chromium/components/strings/components_chromium_strings_hi.xtb
index 6a59ea8701d..103afffe993 100644
--- a/chromium/components/strings/components_chromium_strings_hi.xtb
+++ b/chromium/components/strings/components_chromium_strings_hi.xtb
@@ -1,7 +1,7 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
-<translation id="130631256467250065">अगली बार अपना डिवाइस पुन: प्रारंभ करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
+<translation id="130631256467250065">अगली बार अपना डिवाइस फिर से प्रारंभ करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
<translation id="1838412507805038478">क्रोमियम ने सत्‍यापित किया है कि इस वेबसाइट का प्रमाणपत्र <ph name="ISSUER" /> ने जारी किया है.</translation>
<translation id="275588974610408078">क्रोमियम में क्रैश की रिपोर्ट करना उपलब्ध नहीं है.</translation>
<translation id="3064346599913645280">आप एक सुरक्षित Chromium पेज देख रहे हैं</translation>
@@ -27,17 +27,17 @@
&gt;
<ph name="PROXIES_TITLE" />
पर जाएं और सुनिश्चित करें कि आपका कॉन्फ़िगरेशन "कोई प्रॉक्सी नहीं" या "प्रत्यक्ष" पर सेट है.</translation>
-<translation id="6613594504749178791">अगली बार आपके द्वारा क्रोमियम पुन: लॉन्‍च करने पर आपके परिवर्तन प्रभावी होंगे.</translation>
+<translation id="6613594504749178791">अगली बार आपके द्वारा क्रोमियम फिर से लॉन्‍च करने पर आपके परिवर्तन प्रभावी होंगे.</translation>
<translation id="7861509383340276692">क्रोमियम
मेनू &gt;
<ph name="SETTINGS_TITLE" />
&gt;
<ph name="ADVANCED_TITLE" />
पर जाएं और "<ph name="NO_PREFETCH_DESCRIPTION" />" का चयन हटाएं.
- यदि इससे समस्‍या हल नहीं होती, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन: चुनने की
+ अगर इससे समस्‍या हल नहीं होती, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को फिर से चुनने की
अनुशंसा करते हैं.</translation>
<translation id="8187289872471304532">यहां
- ऐप्स &gt; सिस्टम प्राथमिकताएं &gt; नेटवर्क &gt; उन्नत &gt; प्रॉक्सी
+ ऐप्स &gt; सिस्टम प्राथमिकताएं &gt; नेटवर्क &gt; बेहतर &gt; प्रॉक्सी
पर जाएं और चयनित प्रॉक्सी का चयन ना करें.</translation>
<translation id="8684913864886094367">क्रोमियम सही तरीके से बंद नहीं हुआ.</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_chromium_strings_ja.xtb b/chromium/components/strings/components_chromium_strings_ja.xtb
index 707aa6884d7..43dcec06ddf 100644
--- a/chromium/components/strings/components_chromium_strings_ja.xtb
+++ b/chromium/components/strings/components_chromium_strings_ja.xtb
@@ -1,7 +1,7 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
-<translation id="130631256467250065">変更内容は、次回の端末の起動時に反映されます。</translation>
+<translation id="130631256467250065">変更内容は、次回のデバイスの起動時に反映されます。</translation>
<translation id="1838412507805038478">このウェブサイトの証明書が <ph name="ISSUER" /> 発行のものであることが Chromium で確認されました。</translation>
<translation id="275588974610408078">Chromium では、障害レポートをご利用いただけません。</translation>
<translation id="3064346599913645280">保護された Chromium ページを表示しています</translation>
diff --git a/chromium/components/strings/components_google_chrome_strings_hi.xtb b/chromium/components/strings/components_google_chrome_strings_hi.xtb
index 7f5e55978b1..d888e56e718 100644
--- a/chromium/components/strings/components_google_chrome_strings_hi.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_hi.xtb
@@ -2,11 +2,11 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
<translation id="1016765312371154165">Chrome सही तरीके से बंद नहीं हुआ था.</translation>
-<translation id="130631256467250065">अगली बार अपना डिवाइस पुन: प्रारंभ करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</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>
+<translation id="3140883423282498090">आपके द्वारा अगली बार Google Chrome को फिर से लॉन्‍च करने पर आपके परिवर्तन प्रभावी हो जाएंगे.</translation>
+<translation id="3444832043240812445">अगर आप <ph name="BEGIN_LINK" />क्रैश रिपोर्टिंग सक्षम<ph name="END_LINK" /> करते हैं तो यह पृष्‍ठ केवल आपके हाल ही के क्रैश की जानकारी प्रदर्शित करेगा.</translation>
<translation id="3875312571075912821">Chrome को अपनी फ़ायरवॉल और एंटीवायरस सेटिंग में
नेटवर्क एक्सेस करने दें.</translation>
<translation id="4010643444566880169">Chrome OS ने अपना आरंभिक सेटअप पूर्ण नहीं किया है.</translation>
@@ -25,7 +25,7 @@
&gt;
<ph name="ADVANCED_TITLE" />
पर जाएं और "<ph name="NO_PREFETCH_DESCRIPTION" />" का चयन हटाएं
- यदि इससे समस्या का समाधान नहीं होता, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को पुन: चुनने
+ अगर इससे समस्या का समाधान नहीं होता, तो बेहतर प्रदर्शन के लिए हम इस विकल्‍प को फिर से चुनने
की अनुशंसा करते हैं.</translation>
<translation id="6855094794438142393">यहां
Chrome मेनू &gt;
@@ -38,6 +38,6 @@
LAN सेटिंग में जाएं
और "अपने LAN के लिए किसी प्रॉक्सी सर्वर का उपयोग करें" का चयन ना करें.</translation>
<translation id="8187289872471304532">यहां
- ऐप्स &gt; सिस्टम प्राथमिकताएं &gt; नेटवर्क &gt; उन्नत &gt; प्रॉक्सी
+ ऐप्स &gt; सिस्टम प्राथमिकताएं &gt; नेटवर्क &gt; बेहतर &gt; प्रॉक्सी
पर जाएं और चयनित प्रॉक्सी का चयन ना करें.</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/strings/components_google_chrome_strings_ja.xtb b/chromium/components/strings/components_google_chrome_strings_ja.xtb
index df9d88bbc30..f95b453627b 100644
--- a/chromium/components/strings/components_google_chrome_strings_ja.xtb
+++ b/chromium/components/strings/components_google_chrome_strings_ja.xtb
@@ -2,7 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
<translation id="1016765312371154165">Chrome は正しく終了しませんでした。</translation>
-<translation id="130631256467250065">変更内容は、次回の端末の起動時に反映されます。</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>
diff --git a/chromium/components/strings/components_strings_am.xtb b/chromium/components/strings/components_strings_am.xtb
index 9871664bc5c..2dffb2c0041 100644
--- a/chromium/components/strings/components_strings_am.xtb
+++ b/chromium/components/strings/components_strings_am.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="am">
-<translation id="1005145902654145231">ክፍለ-ጊዜውን ዳግም መሰየም አልተሳካም።</translation>
<translation id="1008557486741366299">አሁን አይደለም</translation>
<translation id="1010200102790553230">በኋላ ላይ ገጽ ጫን</translation>
<translation id="1015730422737071372">ተጨማሪ ዝርዝሮችን ያቅርቡ</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">ያልታወቀ ስም</translation>
<translation id="1050038467049342496">ሌሎች መተግበሪያዎችን ይዝጉ</translation>
<translation id="1055184225775184556">&amp;አክልን ቀልብስ</translation>
+<translation id="1056898198331236512">ማስጠንቀቂያ</translation>
<translation id="1058479211578257048">ካርዶችን በማቀመጥ ላይ...</translation>
<translation id="10614374240317010">በጭራሽ አልተቀመጠም</translation>
+<translation id="1062160989074299343">Prc10 (የደብዳቤ ፖስታ)</translation>
<translation id="106701514854093668">የዴስክቶፕ ዕልባቶች</translation>
<translation id="1074497978438210769">ደህንነቱ አልተጠበቀም</translation>
<translation id="1080116354587839789">ከስፋቱ ጋር አመጣጥን</translation>
+<translation id="1086953900555227778">መረጃ ጠቋሚ-5x8</translation>
<translation id="1088860948719068836">በካርድ ላይ ስም ያክሉ</translation>
<translation id="1089439967362294234">የይለፍ ቃል ቀይር</translation>
<translation id="109743633954054152">የይለፍ ቃላትን በChrome ቅንብሮች ውስጥ ያቀናብሩ</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">ማስጠንቀቂያዎች ድርጣቢያዎች የእነርሱን ደህንነት በሚያዘምኑበት ጊዜ የተለመዱ ሊሆኑ ይችላሉ። ይህ በቅርቡ መሻሻል አለበት።</translation>
<translation id="1126551341858583091">የአካባቢያዊ ማከማቻው መጠን <ph name="CRASH_SIZE" /> ነው።</translation>
<translation id="112840717907525620">የመምሪያ መሸጎጫ እሺ</translation>
+<translation id="1131264053432022307">እርስዎ የቀዱት ምስል</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ሳይታሰብ ግንኙነቱን ዘግቷል።</translation>
<translation id="1161325031994447685">ከWi-Fi ጋር ዳግም በማገናኘት</translation>
<translation id="1165039591588034296">ስህተት</translation>
-<translation id="1173894706177603556">ዳግም ሰይም</translation>
<translation id="1175364870820465910">&amp;አትም…</translation>
<translation id="1181037720776840403">አስወግድ</translation>
<translation id="1197088940767939838">ብርቱካናማ</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">የእርስዎ የመሣሪያ ስም</translation>
<translation id="124116460088058876">ተጨማሪ ቋንቋዎች</translation>
<translation id="1250759482327835220">በሚቀጥለው ጊዜ በበለጠ ፍጥነት ለመክፈል ካርድዎን እና የማስከፈያ አድራሻዎን በGoogle መለያዎ ላይ ያስቀምጡ።</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />፣ <ph name="TYPE_2" /> (ሰምሯል)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">የትእዛዝ መስመር ልዩነቶች</translation>
<translation id="129553762522093515">በቅርብ ጊዜ የተዘጉ</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ኩኪዎችዎን ማጽዳት ይሞክሩ<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">የተመረጠው ክፍለ-ጊዜ የለም።</translation>
+<translation id="1320233736580025032">Prc1 (የደብዳቤ ፖስታ)</translation>
+<translation id="132301787627749051">የቅንጥብ ሰሌዳ ምስልን ይፈልጉ</translation>
<translation id="1323433172918577554">ተጨማሪ አሳይ</translation>
<translation id="132390688737681464">አድራሻዎችን አስቀምጥ እና ሙላ</translation>
<translation id="1333989956347591814">የእርስዎ እንቅስቃሴ ለሚከተሉት <ph name="BEGIN_EMPHASIS" />አሁንም የሚታይ ሊሆን ይችላል<ph name="END_EMPHASIS" />፦
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">የመውሰጃ አድራሻ</translation>
<translation id="1348198688976932919">ቀጥሎ እየመጣ ያለው ጣቢያ አደገኛ መተግበሪያዎችን በውስጡ ይዟል</translation>
<translation id="1348779747280417563">ስም ያረጋግጡ</translation>
+<translation id="1357195169723583938">በቅርቡ ይህን መሣሪያ ማን እና መቼ እንደተጠቀመ</translation>
+<translation id="1364822246244961190">ይህ መመሪያ ታግዷል፣ እሴቱ ችላ ይባላል።</translation>
<translation id="1374468813861204354">የቀረቡ የጥቆማ አስተያየቶች</translation>
+<translation id="1374692235857187091">መረጃ ጠቋሚ-4x6 (ፖስታ ካርድ)</translation>
<translation id="1375198122581997741">ስለ ስሪት</translation>
<translation id="1376836354785490390">ያነሰ አሳይ</translation>
<translation id="1377321085342047638">የካርድ ቁጥር</translation>
<translation id="138218114945450791">ፈካ ያለ ሰማያዊ</translation>
+<translation id="1382194467192730611">በእርስዎ አስተዳዳሪ የተፈቀደ የዩኤስቢ መሣሪያ</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ምንም ውሂብ አልላከም።</translation>
+<translation id="140316286225361634">የ<ph name="ORIGIN" /> ጣቢያ የደህንነት መመሪያ
+ በእሱ ጥያቄ እንዲተገበር ጠይቋል፣ እና ይህ መመሪያ በአሁኑ ጊዜ ጣቢያው
+ ደህንነቱ ያልተጠበቀ እንደሆነ ይቆጥረዋል።</translation>
<translation id="1405567553485452995">ፈካ ያለ አረንጓዴ</translation>
<translation id="1407135791313364759">ሁሉንም ክፈት</translation>
<translation id="1413809658975081374">የግላዊነት ስህተት</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">አዎ</translation>
<translation id="1430915738399379752">አትም</translation>
<translation id="1455413310270022028">ማጥፊያ</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">ተጨማሪ አሳይ</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">የመላኪያ አድራሻ ይምረጡ</translation>
+<translation id="1492194039220927094">የመመሪያዎች ግፊት፦</translation>
<translation id="1501859676467574491">ከእርስዎ የGoogle መለያ ካርዶችን አሳይ</translation>
-<translation id="1506687042165942984">የዚህን ገጽ የተቀመጠ (ለምሳሌ ቀኑ ያለፈበት እንደሆነ የታወቀ) ቅጂን አሳይ።</translation>
<translation id="1507202001669085618">&lt;p&gt;መስመር ላይ መሆን ከመቻልዎ በፊት በመለያ መግባት የሚያስፈልግበት የWi-Fi መግቢያ እየተጠቀሙ ከሆኑ ይህን ስህተት ይመለከታሉ።&lt;/p&gt;
&lt;p&gt;ይህን ስህተት ለመፍታት ለመክፈት እየሞከሩ ባለው ገጽ ላይ &lt;strong&gt;ተገናኝ&lt;/strong&gt;ን ጠቅ ያድርጉ።&lt;/p&gt;</translation>
<translation id="1517433312004943670">ስልክ ቁጥር ያስፈልጋል</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">የግንብ ቀን</translation>
<translation id="1521655867290435174">Google ሉሆች</translation>
<translation id="1527263332363067270">ግንኙነትን በመጠበቅ ላይ…</translation>
+<translation id="1529521330346880926">10x15 (የደብዳቤ ፖስታ)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">ይህ ገጽ እንዲህ ይላል፦</translation>
<translation id="153384715582417236">ለአሁን ያለው ይኸው ነው</translation>
<translation id="154408704832528245">የማድረሻ አድራሻ ይምረጡ</translation>
<translation id="1549470594296187301">ይህን ባህሪ ለመጠቀም ጃቫስክሪፕት መንቃት አለበት።</translation>
+<translation id="155039086686388498">ምሕንድስና-D</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="1569487616857761740">የጊዜ ማብቂያ ቀን ያስገቡ</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">ይህን ድረ-ገጽ በማሳየት ላይ ሳለ የሆነ ችግር ተፈጥሯል።</translation>
<translation id="1592005682883173041">አካባቢያዊ የውሂብ መድረሻ</translation>
<translation id="1594030484168838125">ምረጥ</translation>
<translation id="161042844686301425">ውሃ ሰማያዊ</translation>
-<translation id="1618822247301510817">እርስዎ የቀዱት ምስል</translation>
<translation id="1620510694547887537">ካሜራ</translation>
<translation id="1623104350909869708">ይህ ገጽ ተጨማሪ መገናኛዎችን እንዳይፈጥር አግድ</translation>
+<translation id="16338877384480380">ስነ-ሕንጻ-B</translation>
<translation id="1634051627998691300">ክፍለ-ጊዜን አብቃ</translation>
<translation id="1639239467298939599">በመጫን ላይ</translation>
<translation id="1640180200866533862">የተጠቃሚ መምሪያዎች</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> የእርስዎን መረጃ ለመጠበቅ በመደበኝነት ምስጠራ ይጠቀማል። Google Chrome አሁን ከ<ph name="SITE" /> ጋር ለመገናኘት ሲሞክር ድር ጣቢያው ያልተለመዱ እና ትክክል ያልሆኑ ምስክርነቶችን መልሷል። ይህ አንድ አጥቂ <ph name="SITE" />ን አስመስሎ ለመቅረብ ሲሞክር ነው ወይም አንድ የWi-Fi መግቢያ ገጽ ግንኙነቱን ሲያቋረጥ ሊከሰት ይችላል። Google Chrome ማንኛውም የውሂብ ልውውጥ ከመካሄዱ በፊት ግንኙነቱን ስላቋረጠው የእርስዎ መረጃ ደህንነት አሁንም የተጠበቀ ነው።</translation>
<translation id="168841957122794586">የአገልጋይ እውቅና ማረጋገጫው ደካማ የሆነ ባለስውር መረጃ ቁልፍ ነው ያለው።</translation>
<translation id="1697532407822776718">በቃ ጨርሰዋል!</translation>
+<translation id="1703835215927279855">ደብዳቤ</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="1715874602234207">F</translation>
<translation id="1718029547804390981">ሰነድ ለመብራራት ከልክ በላይ ትልቅ ነው</translation>
<translation id="1721312023322545264">ይህን ጣቢያ ለመጎብኘት ከ<ph name="NAME" /> ፈቃድ ያስፈልገዎታል</translation>
<translation id="1721424275792716183">* መስክ ያስፈልጋል</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">የሥርዓት አስተዳዳሪውን ለማነጋገር ይሞክሩ።</translation>
<translation id="1740951997222943430">ትክክለኛ የአገልግሎት ማብቂያ ወር ያስገቡ</translation>
<translation id="1743520634839655729">በሚቀጥለው ጊዜ በበለጠ ፍጥነት ለመክፈል ካርድዎን እና የማስከፈያ አድራሻዎን በGoogle መለያዎ እና በዚህ መሣሪያ ላይ ያስቀምጡ።</translation>
+<translation id="1745880797583122200">የእርስዎ አሳሽ ይተዳደራል</translation>
<translation id="17513872634828108">ትሮችን ክፈት</translation>
<translation id="1753706481035618306">የገጽ ቁጥር</translation>
<translation id="1763864636252898013">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በመሣሪያዎ ስርዓተ ክወና የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">እባክዎ የማመሳሰል ይለፍ ሐረግዎን ያዘምኑ።</translation>
<translation id="1787142507584202372">የእርስዎ ክፍት ትሮች እዚህ ይመጣሉ</translation>
<translation id="1791429645902722292">Google ዘመናዊ ቁልፍ</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">የካርድ ያዢው ስም</translation>
<translation id="1821930232296380041">ልክ ያልሆነ ጥያቄ ወይም የጥያቄ ልኬቶች</translation>
+<translation id="1822540298136254167">እርስዎ የሚጎበኟቸው ጣቢያዎች እና በእነሱ ላይ የሚያጠፉት ጊዜ</translation>
<translation id="1826516787628120939">በመፈተሸ ላይ</translation>
<translation id="1834321415901700177">ይህ ጣቢያ ጎጂ ፕሮግራሞችን ይዟል</translation>
<translation id="1839551713262164453">የመመሪያ እሴቶችን ማረጋገጥ ከስህተቶች ጋር አልተሳካም</translation>
@@ -180,6 +202,7 @@
<translation id="1981206234434200693">የChrome የአሰሳ ታሪክ ውሂብን አጽዳ</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{እና 1 ተጨማሪ}one{እና # ተጨማሪ}other{እና # ተጨማሪ}}</translation>
<translation id="2003709556000175978">የእርስዎን የይለፍ ቃል አሁኑኑ ዳግም ያቀናብሩ</translation>
+<translation id="20053308747750172">የሚሄዱበት አገልጋይ <ph name="ORIGIN" /> ለጠየቁ ሁሉ የደህንነት መመሪያ እንዲተገበር ጠይቋል። ነገር ግን አሁን ልክ ያልሆነ መመሪያ ልኳል፣ ይህም አሳሹ የ<ph name="SITE" /> ጥያቄዎን እንዳያሟላ ይከለክለዋል።</translation>
<translation id="2025186561304664664">ተኪ ወደ ራስ-ውቅር ተዋቅሯል።</translation>
<translation id="2030481566774242610"><ph name="LINK" />ን ማለትዎ ነው?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />ወኪሉን እና ኬላውን መፈተሽ<ph name="END_LINK" /></translation>
@@ -196,6 +219,7 @@
<translation id="2096368010154057602">መመሪያ</translation>
<translation id="2102134110707549001">ጠንካራ የይለፍ ቃል ጠቁም...</translation>
<translation id="2108755909498034140">ኮምፒውተርዎን ዳግም ያስጀምሩት</translation>
+<translation id="2111256659903765347">ልዕለ-A</translation>
<translation id="2113977810652731515">ካርታ</translation>
<translation id="2114841414352855701">በ<ph name="POLICY_NAME" /> ስለተሻረ ችላ ተብሏል።</translation>
<translation id="213826338245044447">የተንቀሳቃሽ ስልክ ዕልባቶች</translation>
@@ -206,6 +230,7 @@
<translation id="2154484045852737596">ካርትን ያርትዑ</translation>
<translation id="2166049586286450108">ሙሉ የአስተዳደር መድረሻ</translation>
<translation id="2166378884831602661">ይህ ጣቢያ ደህንነቱ አስተማማኝ የሆነ ግንኙነት ማቅረብ አይችልም</translation>
+<translation id="2169984857010174799">Kaku2 (የደብዳቤ ፖስታ)</translation>
<translation id="2181821976797666341">መምሪያዎች</translation>
<translation id="2183608646556468874">ስልክ ቁጥር</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 አድራሻ}one{# አድራሻዎች}other{# አድራሻዎች}}</translation>
@@ -223,11 +248,15 @@
<translation id="2270484714375784793">ስልክ ቁጥር</translation>
<translation id="2283340219607151381">አድራሻዎችን አስቀምጥ እና ሙላ</translation>
<translation id="2292556288342944218">የእርስዎ የበየነመረብ መዳረሻ ታግዷል</translation>
+<translation id="2294558542833290837">መጀመሪያ የከፈቱት አገናኝ ያልተለመደ ነው</translation>
+<translation id="2297722699537546652">B5 (የደብዳቤ ፖስታ)</translation>
+<translation id="2310021320168182093">Chou2 (የደብዳቤ ፖስታ)</translation>
<translation id="2316887270356262533">እስከ 1 ሜባ ቦታ ድረስ ያስለቅቃል። አንዳንድ ጣቢያዎች በሚቀጥለው ጉብኝትዎ ላይ ይበልጥ በዝግታ ሊጫኑ ይችላሉ።</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> የተጠቃሚ ስም እና የይለፍ ቃል ያስፈልገዋል።</translation>
<translation id="2317583587496011522">ዴቢት ካርዶች ተቀባይነት አላቸው።</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />፣ በ<ph name="EXPIRATION_DATE_ABBR" /> አገልግሎት ጊዜው ያበቃል</translation>
<translation id="2337852623177822836">ቅንብር በአስተዳዳሪዎ ነው ቁጥጥር የሚደረግበት</translation>
+<translation id="2346319942568447007">እርስዎ የቀዱት ምስል</translation>
<translation id="2349790679044093737">VR ክፍለ ጊዜ ገቢር ነው</translation>
<translation id="2354001756790975382">ሌላ እልባቶች</translation>
<translation id="2354430244986887761">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ጎጂ መተግበሪያዎችን አግኝቷል<ph name="END_LINK" />።</translation>
@@ -239,29 +268,34 @@
<translation id="2365563543831475020">በ<ph name="CRASH_TIME" /> ላይ የተያዘው የብልሽት ሪፖርት አልተሰቀለም</translation>
<translation id="2367567093518048410">ደረጃ</translation>
<translation id="2378238891085281592">እርስዎ የግል ሆነዋል</translation>
+<translation id="2380886658946992094">የሕግ</translation>
<translation id="2384307209577226199">የንግድ ድርጅት ነባሪ</translation>
<translation id="2386255080630008482">የአገልጋይ እውቅና ማረጋገጫ ተሽሯል።</translation>
<translation id="2392959068659972793">ምንም እሴት ያልተዋቀረላቸው መምሪያዎችን አሳይ</translation>
<translation id="239429038616798445">ይህ የመላኪያ ዘዴ አይገኝም። የተለየ ዘዴ ይሞክሩ።</translation>
<translation id="2396249848217231973">&amp;ስረዛን ቀልብስ</translation>
+<translation id="2410754574180102685">መንግስት-የህግ</translation>
<translation id="2413528052993050574">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው ተሽሮ ሊሆን ይችላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="2418081434543109369">የሚሄዱበት አገልጋይ <ph name="ORIGIN" /> ለጠየቁ ሁሉ የደህንነት መመሪያ እንዲተገበር ጠይቋል። ነገር ግን አሁን መመሪያ ሊያደርስ አልቻለም፣ ይህም አሳሹ የ<ph name="SITE" /> ጥያቄዎን እንዳያማላ ይከለክለዋል።</translation>
<translation id="244665789865330679">የእርስዎ መሣሪያ እና መለያ በ<ph name="ENROLLMENT_DOMAIN" /> ነው የሚተዳደረው። ይህ ማለት የእርስዎ አስተዳዳሪ የእርስዎን መሣሪያ እና መለያ በርቀት ሊያዋቅር ይችላል ማለት ነው።</translation>
<translation id="2463193859425327265">መነሻ ገጹን ቀይር</translation>
<translation id="2463739503403862330">ሙላ</translation>
+<translation id="2465402087343596252">ስነ-ሕንጻ-E</translation>
<translation id="2465655957518002998">የማድረሻ ዘዴ ይምረጡ</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />የአውታረ መረብ መመርመሪያን በማሄድ ላይ<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ይህን ገጽ መተርጎም</translation>
<translation id="2479410451996844060">ልክ ያልሆነ የፍለጋ ዩአርኤል።</translation>
<translation id="2482878487686419369">ማስታወቂያዎች</translation>
<translation id="248348093745724435">የማሽን መመሪያዎች</translation>
+<translation id="2485387744899240041">የእርስዎ መሣሪያ እና አሳሽ የተጠቃሚ ስሞች</translation>
<translation id="2491120439723279231">የአገልጋይ እውቅና ማረጋገጫ ስህተቶችን ይዟል።</translation>
+<translation id="2493640343870896922">ደብዳቤ-ፕላስ</translation>
<translation id="2495083838625180221">JSON ተንታኝ</translation>
<translation id="2495093607237746763">ምልክት ከተደረገበት Chromium ለተሻለ የቅጽ አሞላል ፍጥነት የካርድዎን ቅጂ በዚህ መሣሪያ ላይ ያከማቻል።</translation>
<translation id="2498091847651709837">አዲስ ካርድ ቃኝ</translation>
<translation id="2501278716633472235">ወደ ኋላ ተመለስ</translation>
<translation id="2503184589641749290">ተቀባይነት ያላቸው የዴቢት እና የቅድመ-ክፍያ ካርዶች</translation>
<translation id="2515629240566999685">በእርስዎ አካባቢ ያለውን ሲግናል መፈተሽ</translation>
-<translation id="2516852381693169964"><ph name="SEARCH_ENGINE" />ን ለምስል ፈልግ</translation>
<translation id="2523886232349826891">በዚህ መሣሪያ ላይ ብቻ ይቀመጣል</translation>
<translation id="2524461107774643265">ተጨማሪ መረጃ ያክሉ</translation>
<translation id="2536110899380797252">አድራሻ ያክሉ</translation>
@@ -273,6 +307,7 @@
<translation id="2587841377698384444">የማውጫ የኤፒአይ መታወቂያ፦</translation>
<translation id="2597378329261239068">ይህ ሰነድ በይለፍ ቃል የተጠበቀ ነው። እባክዎ የይለፍ ቃል ያስገቡ።</translation>
<translation id="2609632851001447353">ልዩነቶች</translation>
+<translation id="2618023639789766142">C10 (የደብዳቤ ፖስታ)</translation>
<translation id="2625385379895617796">የእርስዎ ሰዓት ገና የወደፊት ነው</translation>
<translation id="2634124572758952069">የ<ph name="HOST_NAME" /> አገልጋይ አይፒ አድራሻ ሊገኝ አልቻለም።</translation>
<translation id="2639739919103226564">ሁኔታ፦</translation>
@@ -282,7 +317,9 @@
<translation id="2666117266261740852">ሌሎች ትሮችን ወይም መተግበሪያዎችን ይዝጉ</translation>
<translation id="267371737713284912">ለመቀልበስ <ph name="MODIFIER_KEY_DESCRIPTION" />ን ይጫኑ</translation>
<translation id="2674170444375937751">እርግጠኛ ነዎት እነዚህን ገጾች ከታሪክዎ መሰረዝ ይፈልጋሉ?</translation>
+<translation id="2676271551327853224">ROC 8K</translation>
<translation id="2677748264148917807">ለቅቀህ ውጣ</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">ተቀባይነት ያላቸው ካርዶች</translation>
<translation id="2702801445560668637">የንባብ ዝርዝር</translation>
<translation id="2704283930420550640">ዋጋ ከቅርጸት ጋር አይዛመድም።</translation>
@@ -299,7 +336,6 @@
<translation id="2742870351467570537">የተመረጡትን ንጥሎች አስወግድ</translation>
<translation id="277133753123645258">የመላኪያ ዘዴ</translation>
<translation id="277499241957683684">የሚጎድል የመሣሪያ መዝገብ</translation>
-<translation id="2781030394888168909">MacOSን ወደ ውጭ ይላኩ</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">ግንኙነቱ ዳግም እንዲጀምር ተደርጓል።</translation>
<translation id="2788784517760473862">ተቀባይነት ያላቸው ክሬዲት ካርዶች</translation>
@@ -311,8 +347,10 @@
<translation id="2826760142808435982">ግንኙነቱ የተመሰጠረ እና <ph name="CIPHER" />ን በመጠቀም የተረጋገጠ ነው፣ እና <ph name="KX" />ን እንደ የቁልፍ መቀያየሪያ ስልት ይጠቀምበታል።</translation>
<translation id="2835170189407361413">ቅጽ አጽዳ</translation>
<translation id="2847118875340931228">ማንነት የማያሳውቅ መስኮት ክፈት</translation>
+<translation id="2850739647070081192">ግብዣ (የደብዳቤ ፖስታ)</translation>
<translation id="2851634818064021665">ይህን ጣቢያ ለመጎብኘት ፈቃድ ያስፈልገዎታል</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">ካርድ ይቀመጥ?</translation>
<translation id="2903493209154104877">አድራሻዎች</translation>
<translation id="290376772003165898">ገጽ በ<ph name="LANGUAGE" /> አይደለም?</translation>
@@ -322,6 +360,7 @@
<translation id="2925673989565098301">የማድረሻ ስልት</translation>
<translation id="2928905813689894207">ክፍያ የሚጠየቅበት አድራሻ</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">መንግስት-ደብዳቤ</translation>
<translation id="2941952326391522266">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በ<ph name="DOMAIN2" /> ነው የተሰጠው። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="2948083400971632585">ከቅንብሮች ገጽ ሆነው ማናቸውንም ለግንኙነት የተዋቀሩ ተኪዎችን ማሰናከል ይችላሉ።</translation>
<translation id="2955913368246107853">አግኝ አሞሌን ዝጋ</translation>
@@ -338,11 +377,14 @@
<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="3023071826883856138">You4 (የደብዳቤ ፖስታ)</translation>
<translation id="3024663005179499861">የተሳሳተ የመምሪያ አይነት</translation>
<translation id="3037605927509011580">ውይ፣ ተሰናከለ!</translation>
<translation id="3041612393474885105">የሰርቲፊኬት መረጃ</translation>
+<translation id="3060227939791841287">C9 (የደብዳቤ ፖስታ)</translation>
<translation id="3064966200440839136">በውጫዊ ማከማቻ በኩል ለማጫወት ማንነት ከማያሳውቅ ሁነታ በመውጣት ላይ። ይቀጥል?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ምንም}=1{1 የይለፍ ቃል}one{# የይለፍ ቃሎች}other{# የይለፍ ቃሎች}}</translation>
+<translation id="3095940652251934233">መግለጫ</translation>
<translation id="3096100844101284527">የመውሰጃ አድራሻ ያክሉ</translation>
<translation id="3105172416063519923">የእሴት መታወቂያ፦</translation>
<translation id="3109728660330352905">ይህን ገጽ ለማየት ፍቃድ የለዎትም።</translation>
@@ -363,20 +405,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> በ<ph name="SERVER_NAME" /> ላይ</translation>
<translation id="320323717674993345">ክፍያን ሰርዝ</translation>
<translation id="3207960819495026254">ዕልባት ተደርጎበታል</translation>
-<translation id="3209375525920864198">እባክዎ የሚሠራ የክፍለ-ጊዜ ስም ያስገቡ።</translation>
+<translation id="321912867715453276">ማስጠንቀቂያ፦ ለመመሪያው ከአንድ በላይ ምንጭ ይገኛል፣ ነገር ግን እሴቶቹ ተመሳሳይ ናቸው።</translation>
<translation id="3225919329040284222">አገልጋዩ አብረው የተሰሩ የሚጠበቁ ማሟያዎችን የማያሟላ የእውቅና ማረጋገጫ ነው ያቀረበው። እነዚህ የሚጠበቁ ማሟያዎች እርስዎን ለመጠበቅ ለተረጋገጡ ከፍተኛ ደህንነት ላላቸው ድር ጣቢያዎች ተካትተዋል።</translation>
<translation id="3226128629678568754">ገጹን ለመጫን የሚያስፈልገው ውሂብ ዳግም ለማስገባት የዳግም ጫን አዝራሩን ይጫኑ።</translation>
<translation id="3227137524299004712">ማይክሮፎን</translation>
<translation id="3228969707346345236">ገጹ አስቀድሞ በ<ph name="LANGUAGE" /> ስለሆነ ትርጉሙ አልተሳካም።</translation>
+<translation id="3229041911291329567">የእርስዎ መሣሪያ እና አሳሽ የስሪት መረጃ</translation>
<translation id="323107829343500871">የ<ph name="CREDIT_CARD" /> ሲቪሲ ያስገቡ</translation>
<translation id="3234666976984236645">ሁልጊዜ በዚህ ጣቢያ ላይ ያለ አስፈላጊ ይዘትን አግኝ</translation>
<translation id="3254409185687681395">ለእዚህ ገጽ ዕልባት አብጅ</translation>
<translation id="3270847123878663523">&amp;ዳግም ደርድርን ቀልብስ</translation>
+<translation id="3274521967729236597">ፓ-ካይ</translation>
<translation id="3282497668470633863">በካርድ ላይ ስም ያክሉ</translation>
<translation id="3287510313208355388">መስመር ላይ ሲሆኑ ያውርዱ</translation>
<translation id="3293642807462928945">ስለ<ph name="POLICY_NAME" /> መመሪያው ተጨማሪ ይወቁ</translation>
<translation id="3303855915957856445">ምንም የፍለጋ ውጤቶች አልተገኙም</translation>
-<translation id="3305707030755673451">የእርስዎ ውሂብ <ph name="TIME" /> ላይ በእርስዎ የስምረት የይለፍ ቃል ተመስጥሯል። ስምረትን ለመጀመር ያስገቡት።</translation>
<translation id="3320021301628644560">የመክፈያ አድራሻ አክል</translation>
<translation id="3324983252691184275">ክሪምሶን</translation>
<translation id="3338095232262050444">ደህንነቱ የተጠበቀ ነው</translation>
@@ -404,9 +447,11 @@
<translation id="3427342743765426898">&amp;አርትዕን ድገም</translation>
<translation id="342781501876943858">Chromium የእርስዎን ይለፍ ቃል በሌሎች ጣቢያዎች ላይ ዳግም ከተጠቀሙበት እንደገና እንዲያዋቅሩት ይመክራል።</translation>
<translation id="3431636764301398940">ይህን ካርድ ወደዚህ መሣሪያ አስቀምጥ</translation>
+<translation id="3443726618221119081">ጁሮ-ኩ-ካይ</translation>
<translation id="3447661539832366887">የዚህ መሣሪያ ባለቤት የዳይኖሰር ጨዋታውን አጥፍቶታል።</translation>
<translation id="3447884698081792621">የእውቅና ማረጋገጫን አሳይ (በ<ph name="ISSUER" /> የሚሰጥ)</translation>
<translation id="3452404311384756672">የሚመጣው በየ፦</translation>
+<translation id="3456231139987291353">ቁጥር-11 (የደብዳቤ ፖስታ)</translation>
<translation id="3461824795358126837">ማድመቂያ</translation>
<translation id="3462200631372590220">የላቁ ደብቅ</translation>
<translation id="3467763166455606212">የካርድ ያዥ ስም ያስፈልጋል</translation>
@@ -429,20 +474,23 @@
<translation id="358285529439630156">የክሬዲት እና የቅድመ-ክፍያ ካርዶች ተቀባይነት አላቸው።</translation>
<translation id="3582930987043644930">ስም ያክሉ</translation>
<translation id="3583757800736429874">&amp;ውሰድን ድገም</translation>
+<translation id="35866233670761917">እርስዎ የሚጎበኙዋቸው የድር ጣቢያዎች ይዘቶች በእርስዎ አስተዳዳሪዎች የሚታዩ አይሆንም</translation>
<translation id="3586931643579894722">ዝርዝር ደብቅ</translation>
+<translation id="3592413004129370115">ጣልያንኛ (የደብዳቤ ፖስታ)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />፣ <ph name="DOMAIN" />፣ <ph name="TIME" /></translation>
<translation id="3614103345592970299">መጠን 2</translation>
<translation id="3615877443314183785">ትክክለኛ የአገልግሎት ማብቂያ ቀን ያስገቡ</translation>
<translation id="36224234498066874">የአሰሳ ውሂብ አስወግድ…</translation>
<translation id="362276910939193118">ሙሉ ታሪክ አሳይ</translation>
-<translation id="3623476034248543066">እሴት አሳይ</translation>
<translation id="3630155396527302611">አውታረ መረቡ እንዲደርስ የተፈቀደለት መሣሪያ ነው ተብሎ አስቀድሞ ከተዘረዘረ ከዝርዝሩ
አስወግደው እንደገና ለማከል ይሞክሩ።</translation>
+<translation id="3640766068866876100">መረጃ ጠቋሚ-4x6-Ext</translation>
<translation id="3650584904733503804">ማረጋገጥ ተሳክቷል</translation>
<translation id="3655670868607891010">ይህንን በተደጋጋሚነት የሚያዩ ከሆኑ <ph name="HELP_LINK" />ን ይሞክሩ።</translation>
<translation id="3658742229777143148">ክለሳ</translation>
<translation id="366077651725703012">ክሬዲት ካርድን አዘምን</translation>
<translation id="3676592649209844519">የመሣሪያ መታወቂያ፦</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ለማለት ፈልገው ነው?</translation>
<translation id="3678029195006412963">ጥያቄ ሊፈረም አልተቻለም</translation>
<translation id="3678529606614285348">ገጹን ማንነት በማያሳውቅ አዲስ መስኮት ውስጥ ይክፈቱ (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">የብልሽት ሪፖርት <ph name="CRASH_TIME" /> ላይ ተይዟል፣ <ph name="UPLOAD_TIME" /> ላይ ተሰቅሏል</translation>
@@ -450,13 +498,14 @@
<translation id="3704162925118123524">እየተጠቀሙ ያሉት አውታረ መረብ በመለያ መግቢያ ገጹን እንዲጎበኙ ሊጠይቅዎት ይችላል።</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">በመጫን ላይ…</translation>
+<translation id="3709599264800900598">እርስዎ የቀዱት ጽሑፍ</translation>
<translation id="3712624925041724820">ሁሉም ፍቃዶች ተሞክረዋል</translation>
<translation id="3714780639079136834">የሞባይል ውሂብ ወይም Wi-Fi ማብራት</translation>
<translation id="3715597595485130451">ከWi-Fi ጋር ይገናኙ</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ወኪሉን፣ ኬላውን እና የዲኤንኤስ ውቅረትን መፈተሽ<ph name="END_LINK" /></translation>
<translation id="372429172604983730">ይህን ስህተት ሊያስከትሉ የሚችሉ መተግበሪያዎች ጸረ-ቫይረስ፣ ኬላ እና ድር ማጣሪያ ተኪ ሶፍትዌር ያካትታሉ።</translation>
+<translation id="373042150751172459">B4 (የደብዳቤ ፖስታ)</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="3745099705178523657">ካረጋገጡ በኋላ የGoogle መለያዎ ካርድ ዝርዝሮች ለዚህ ጣቢያ ይጋራሉ።</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>
@@ -469,10 +518,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">በ<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> ላይ የአገልግሎት ጊዜው ያበቃል</translation>
<translation id="3789155188480882154">መጠን 16</translation>
+<translation id="3797522431967816232">Prc3 (የደብዳቤ ፖስታ)</translation>
<translation id="3807873520724684969">ጎጂ ይዘት ታግዷል።</translation>
<translation id="3810973564298564668">አቀናብር</translation>
<translation id="382518646247711829">ተኪ አገልጋይ የሚጠቀሙ ከሆኑ...</translation>
<translation id="3828924085048779000">ባዶ የይለፍ ሐረግ አይፈቀድም።</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ለተጨማሪ ተግባራት ቅጥያዎችን ጭኗል። ቅጥያዎች የአንዳንድ ውሂብዎ መዳረሻ አላቸው።</translation>
<translation id="385051799172605136">ተመለስ</translation>
<translation id="3858027520442213535">ቀን እና ሰዓትን አዘምን</translation>
<translation id="3884278016824448484">የሚጋጭ የመሣሪያ ለዪ</translation>
@@ -480,6 +531,7 @@
<translation id="3886446263141354045">ይህን ጣቢያ የመድረስ ጥያቄዎ ለ<ph name="NAME" /> ተልኳል</translation>
<translation id="3890664840433101773">ኢሜይል ያክሉ</translation>
<translation id="3901925938762663762">ካርዱ አገልግሎት ጊዜው አብቅቷል</translation>
+<translation id="3906600011954732550">B5-ተጨማሪ</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">ሁልጊዜ በዚህ ጣቢያ ላይ ጠይቅ</translation>
<translation id="3949571496842715403">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት ዕውቅና ማረጋገጫው የርዕሰ ጒዳይ አማራጭ ስሞችን አይጠቅስም። ይህ በተሳሳተ ውቅረት የተከሰተ ወይም አጥቂ የእርስዎን ግንኙነት አቋርጦ እየገባ ስለሆነ ሊሆን ይችላል።</translation>
@@ -490,11 +542,13 @@
<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="3984550557525787191">ይህ የክፍለ-ጊዜ ስም አስቀድሞ አለ።</translation>
<translation id="3987940399970879459">ከ1 ሜባ ያነሰ</translation>
+<translation id="4008849406247176967">ማስጠንቀቂያ፦ ለዚህ መመሪያ የሚጋጩ እሴቶች ያላቸው ከአንድ በላይ ምንጮች አሉ!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 ድረ-ገጽ በአቅራቢያ}one{# ድረ-ገጾች በአቅራቢያ}other{# ድረ-ገጾች በአቅራቢያ}}</translation>
<translation id="4030383055268325496">&amp;አክልን ቀልብስ</translation>
+<translation id="4032320456957708163">የእርስዎ አሳሽ በ<ph name="ENROLLMENT_DOMAIN" /> የሚተዳደር ነው</translation>
<translation id="4058922952496707368">ቁልፍ «<ph name="SUBKEY" />»፦ <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (የደብዳቤ ፖስታ)</translation>
<translation id="4067947977115446013">የሚሰራ አድራሻ ያስገቡ</translation>
<translation id="4072486802667267160">የእርስዎን ትዕዛዝ መሥራት ላይ የሆነ ስህተት ነበር። እባክዎ እንደገና ይሞክሩ።</translation>
<translation id="4075732493274867456">ደንበኛው እና አገልጋዩ የተለመደ የኤስኤስኤል ፕሮቶኮል ስሪት ወይም የስነ መሰውር ጥቅል አይደግፉም።</translation>
@@ -514,10 +568,12 @@
<translation id="4159784952369912983">ሐምራዊ</translation>
<translation id="4165986682804962316">የጣቢያ ቅንብሮች</translation>
<translation id="4171400957073367226">መጥፎ የማረጋገጫ ፊርማ</translation>
+<translation id="4173315687471669144">ፉልስካፕ</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ተጨማሪ ንጥል}one{<ph name="ITEM_COUNT" /> ተጨማሪ ንጥሎች}other{<ph name="ITEM_COUNT" /> ተጨማሪ ንጥሎች}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ውሰድን ድገም</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />የኬላ እና የጸረ-ቫይረስ ውቅረቶችን መፈተሽ<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (የደብዳቤ ፖስታ)</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="4221630205957821124">&lt;h4&gt;ደረጃ 1፦ ወደ መግቢያው ይግቡ&lt;/h4&gt;
@@ -549,58 +605,79 @@
<translation id="4277028893293644418">የይለፍ ቃል ዳግም አቀናብር</translation>
<translation id="4280429058323657511">፣ አገልግሎቱ የሚያበቃው በ<ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{ይህ ካርድ በእርስዎ የGoogle መለያ ላይ ተቀምጧል}one{እነዚህ ካርዶች በእርስዎ የGoogle መለያ ላይ ተቀምጠዋል}other{እነዚህ ካርዶች በእርስዎ የGoogle መለያ ላይ ተቀምጠዋል}}</translation>
+<translation id="42981349822642051">ዘርጋ</translation>
+<translation id="4302965934281694568">Chou3 (የደብዳቤ ፖስታ)</translation>
<translation id="4305817255990598646">ቀይር</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">አግድ (ነባሪ)</translation>
+<translation id="4318566738941496689">የእርስዎ መሣሪያ ስም እና የአውታረ መረብ አድራሻ</translation>
<translation id="4325863107915753736">ጽሑፉን ማግኘት አልተቻለም</translation>
<translation id="4326324639298822553">የእርስዎን የአገልግሎት ማብቂያ ቀን ይመልከቱ እና እንደገና ይሞክሩ</translation>
<translation id="4331708818696583467">ደህንነቱ አልተጠበቀም</translation>
<translation id="4340982228985273705">ይህ ኮምፒውተር እንደ በድርጅት የሚተዳደር ሆኖ አይታይም፣ ስለዚህ መመሪያ በChrome የድር ማከማቻ ላይ የሚስተናገዱ ቅጥያዎችን ብቻ በራስ-ሰር ነው መጫን የሚችለው። የChrome ድር ማከማቻው ዝማኔ ዩአርኤል «<ph name="CWS_UPDATE_URL" />» ነው።</translation>
<translation id="4346197816712207223">ተቀባይነት ያላቸው ክሬዲት ካርዶች</translation>
+<translation id="4346833872170306413">ROC 8K</translation>
<translation id="4356973930735388585">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች መረጃዎን (ለምሳሌ፦ ፎቶዎች፣ የይለፍ ቃላት፣ መልዕክቶች እና ክሬዲት ካርዶች) ሊሰርቁ ወይም ሊሰርዙ የሚችሉ አደገኛ ፕሮግራሞችን በኮምፒውተርዎ ላይ ለመጫን ሊሞክሩ ይችላሉ።</translation>
<translation id="4358461427845829800">የመክፈያ ዘዴዎችን ያቀናብሩ...</translation>
+<translation id="4367563149485757821">ቁጥር-12 (የደብዳቤ ፖስታ)</translation>
+<translation id="4372516964750095882">ፋንፎልድ-አሜሪካ</translation>
<translation id="4372948949327679948">የተጠበቀው የ<ph name="VALUE_TYPE" /> ዋጋ ነው።</translation>
<translation id="4377125064752653719"><ph name="DOMAIN" />ን ለመድረስ ሞክረዋል፣ ነገር ግን አገልጋዩ ያቀረበው የእውቅና ማረጋገጫ በሰጪው ተሽሯል። ይህ ማለት አገልጋዩ ያቀረበው የደህንነት ምስክርነቶች ፈጽሞ ሊታመኑ አይገባም። ከአጥቂ ጋር እየተገናኙ ሊሆን ይችላል።</translation>
<translation id="4378154925671717803">ስልክ</translation>
<translation id="4406896451731180161">የፍለጋ ውጤቶች</translation>
-<translation id="4406972042435603828">የእርስዎ አስተዳዳሪዎች ኃይለኛ ችሎታዎች ያላቸው ቅጥያዎችን ጭነዋል።</translation>
<translation id="4408413947728134509">ኩኪዎች <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">የመውሰጃ አድራሻ</translation>
<translation id="4424024547088906515">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በChrome የሚታመን አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="443121186588148776">የመለያ ወደብ</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> የመግቢያ እውቅና ማረጋገጫዎን አልተቀበለም፣ ወይም ገና አልተሰጠዎት ይሆናል።</translation>
<translation id="4434045419905280838">ብቅ-ባዮች እና አቅጣጫ ማዞሮች</translation>
+<translation id="4435702339979719576">የፖስታ ካርድ)</translation>
<translation id="443673843213245140">የተኪ መጠቀም ተሰናክሏል ግን ግልጽ የሆነ የተኪ ውቅር ተገልጿል።</translation>
<translation id="445100540951337728">ተቀባይነት ያላቸው ዴቢት ካርዶች</translation>
+<translation id="4466881336512663640">የቅጽ ለውጦች ይጠፋሉ። እርግጠኛ ነዎት መቀጠል ይፈልጋሉ?</translation>
<translation id="4482953324121162758">ይህ ጣቢያ አይተረጎምም።</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">ልክ ያልሆነ ዩአርኤል። ደረጃውን የጠበቀ ቅርጸ አጻጻፍ ያለው ዩአርኤል መሆን አለበት፣ ለምሳሌ፦ http://example.com ወይም https://example.com.</translation>
+<translation id="4503882053543859973">ስነ-ሕንጻ-D</translation>
<translation id="4506176782989081258">የማረጋገጥ ስህተት፦ <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">የሥርዓት አስተዳዳሪውን ማነጋገር</translation>
<translation id="450710068430902550">ከአስተዳዳሪ ጋር ማጋራት</translation>
+<translation id="4510487217173779431">Chou4 (የደብዳቤ ፖስታ)</translation>
<translation id="4515275063822566619">ካርዶች እና አድራሻዎች ከChrome እና ከGoogle መለያዎ (<ph name="ACCOUNT_EMAIL" />) የተገኙ ናቸው። በ<ph name="BEGIN_LINK" />ቅንብሮች<ph name="END_LINK" /> ውስጥ ሊያቀናብሯቸው ይችላሉ።</translation>
+<translation id="4517607026994743406">Comm-10 (የደብዳቤ ፖስታ)</translation>
<translation id="4522570452068850558">ዝርዝሮች</translation>
<translation id="4524805452350978254">ካርዶችን አቀናብር</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ብልጭታ</translation>
<translation id="4558551763791394412">ቅጥያዎችዎን አሰናክለው ይሞክሩ።</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">መላኪያ</translation>
+<translation id="4579056131138995126">የግል (የደብዳቤ ፖስታ)</translation>
<translation id="4582204425268416675">ካርድ አስወግድ</translation>
<translation id="4587425331216688090">አድራሻ ከChrome ይወገድ?</translation>
<translation id="4592951414987517459">ወደ የእርስዎ <ph name="DOMAIN" /> ግንኙነት ዘመናዊ የምስጠራ ጥቅል በመጠቀም ተመስጥሯል።</translation>
<translation id="4594403342090139922">&amp;ሰርዝን ቀልብስ</translation>
<translation id="4597348597567598915">መጠን 8</translation>
+<translation id="4600854749408232102">C6/C5 (የደብዳቤ ፖስታ)</translation>
<translation id="4646534391647090355">አሁን ወደዚያ ውሰደኝ</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው ስህተቶች አሉበት። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="467809019005607715">Google ስላይዶች</translation>
<translation id="4690462567478992370">ልክ ያልሆነ የእውቅና ማረጋገጫ መጠቀም አቁም</translation>
+<translation id="4691835149146451662">ስነ-ሕንጻ-A (የደብዳቤ ፖስታ)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">የእርስዎ ግንኙነት ተቋርጧል</translation>
<translation id="471880041731876836">ይህን ጣቢያ የመጎብኘት ፈቃድ የለዎትም</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />የWindows አውታረ መረብ መመርመሪያን በማሄድ ላይ<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">መምሪያዎችን ዳግም ጫን</translation>
<translation id="4728558894243024398">መድረክ</translation>
+<translation id="4731967714531604179">Prc2 (የደብዳቤ ፖስታ)</translation>
<translation id="4736825316280949806">Chromiumን ዳግም ያስጀምሩት</translation>
<translation id="473775607612524610">አዘምን</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> የፍለጋ አስተያየት ጥቆማ</translation>
<translation id="4742407542027196863">የይለፍ ቃላትን ያስተዳድሩ...</translation>
<translation id="4744603770635761495">የሚፈጸም ዱካ</translation>
+<translation id="4746351372139058112">መልዕክቶች</translation>
<translation id="4750917950439032686">የእርስዎ መረጃ (ለምሳሌ፦ የይለፍ ቃሎች ወይም የክሬዲት ካርድ ቁጥሮች) ወደዚህ ጣቢያ በሚላክበት ጊዜ የግል ነው።</translation>
<translation id="4756388243121344051">&amp;ታሪክ</translation>
<translation id="4758311279753947758">የእውቂያ መረጃን ያክሉ</translation>
@@ -608,9 +685,9 @@
<translation id="4764776831041365478"><ph name="URL" /> ላይ ያለው ድረ-ገጽ ለጊዜው የማይሰራ ወይም እስከመጨረሻው ወደ አዲስ የድር አድራሻ ተዛውሮ ሊሆን ይችላል።</translation>
<translation id="4771973620359291008">ያልታወቀ ስህተት ተከስቷል።</translation>
<translation id="4785689107224900852">ወደዚህ ትር ቀይር</translation>
-<translation id="4792143361752574037">የክፍለ-ጊዜ ፋይሎችን መድረስ ላይ አንድ ችግር ነበር። ወደ ዲስክ ማስቀመጥ በአሁኑ ጊዜ ተሰናክሏል። እንደገና ለመሞከር እባክዎ ገጹን ዳግም ይጫኑት።</translation>
<translation id="4798078619018708837">የካርድ ዝርዝሮችዎን ለማዘመን የ<ph name="CREDIT_CARD" /> ማብቂያ ቀን እና CVC ያስገቡ። ካረጋገጡ በኋላ የGoogle መለያ ካርድ ዝርዝሮችዎ ለዚህ ጣቢያ ይጋራል።</translation>
<translation id="4800132727771399293">የእርስዎን የአገልግሎት ማብቂያ ቀን እና CVC ይፈትሹ እና እንደገና ይሞክሩ</translation>
+<translation id="480334179571489655">የምንጭ መመሪያ ስህተት</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>
@@ -625,7 +702,6 @@
<translation id="4881695831933465202">ክፈት</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>
@@ -634,15 +710,15 @@
<translation id="4943872375798546930">ውጤቶች የሉም</translation>
<translation id="4950898438188848926">የትር መቀየሪያ አዝራር፣ ወደ ክፍቱ ትር <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> ለመቀየር Enterን ይጫኑ</translation>
<translation id="495170559598752135">እርምጃዎች</translation>
-<translation id="495832697253704892">ቅጥያን ሪፖርት ማድረግ</translation>
+<translation id="4955242332710481440">A5-ተጨማሪ</translation>
<translation id="4958444002117714549">ዝርዝሩን ዘርጋ</translation>
<translation id="4974590756084640048">ማስጠንቀቂያዎችን ዳግም አንቃ</translation>
+<translation id="4984339528288761049">Prc5 (የደብዳቤ ፖስታ)</translation>
<translation id="4989163558385430922">ሁሉንም ይመልከቱ</translation>
<translation id="4989809363548539747">ይህ ተሰኪ አይደገፍም</translation>
-<translation id="4996230189582812866">ሪፖርት ማድረግ</translation>
<translation id="5002932099480077015">የነቃ እንደሆነ Chrome ለበለጠ ፈጣን ቅጽ አሞላል ሲባል በዚህ መሳሪያ ላይ ያለው የካርድዎን ቅጂ ያከማቻል።</translation>
-<translation id="5014174725590676422">በChrome ውስጥ Google ረዳት የመጀመሪያ ማሄድ ማያ ገጽ ይታያል</translation>
<translation id="5015510746216210676">የማሽን ስም፦</translation>
+<translation id="5017554619425969104">እርስዎ የቀዱት ጽሑፍ</translation>
<translation id="5018422839182700155">ይህን ገጽ መክፈት አልተቻለም</translation>
<translation id="5019198164206649151">የመጠባበቂያ ማከማቻ በመጥፎ ሁኔታ ላይ</translation>
<translation id="5023310440958281426">የአስተዳዳሪዎ መመሪያዎችን ያረጋግጡ</translation>
@@ -652,35 +728,51 @@
<translation id="5034369478845443529">ከባቢያዊ ዓውድ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">ፍቀድ</translation>
<translation id="5040262127954254034">ግላዊነት</translation>
+<translation id="5043480802608081735">የቀዱት አገናኝ</translation>
<translation id="5045550434625856497">ትክክል ያልሆነ የይለፍ ቃል</translation>
<translation id="5056549851600133418">ለእርስዎ የሚሆኑ ጽሑፎች</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />የወኪሉን አድራሻ መፈተሽ<ph name="END_LINK" /></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="5097099694988056070">እንደ የሲፒዩ/ራም አጠቃቀም ያለ የመሣሪያ ስታቲስቲክስ</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">የእርስዎ መሣሪያ በ<ph name="ENROLLMENT_DOMAIN" /> የሚተዳደር ስሲሆን የእርስዎ መለያ በ<ph name="ACCOUNT_DOMAIN" /> ይተዳደራል። ይህ ማለት የእርስዎ አስተዳዳሪዎች በርቀት የእርስዎን መሣሪያና መለያ ሊያዋቅሩት ይችላሉ ማለት ነው።</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">የአውሮፓ-Edp</translation>
<translation id="5115563688576182185">(64-ቢት)</translation>
-<translation id="5128122789703661928">ይህ ስም ያለው ክፍለ-ጊዜ ለስረዛ ልክ ያልሆነ ነው።</translation>
+<translation id="5125394840236832993">B-ፕላስ</translation>
<translation id="5135404736266831032">አድራሻዎችን ያቀናብሩ...</translation>
+<translation id="5138227688689900538">ያነሰ አሳይ</translation>
<translation id="5141240743006678641">የተመሳሰሉ የይለፍ ቃላት ከGoogle ምስክርነቶችዎ ጋር ያመሳስሉ</translation>
<translation id="5145883236150621069">የስህተት ኮድ በመምሪያው ምላሽ ውስጥ አለ</translation>
+<translation id="515292512908731282">C4 (የደብዳቤ ፖስታ)</translation>
<translation id="5159010409087891077">ገጹን ማንነት በማያሳውቅ አዲስ መስኮት ውስጥ ይክፈቱ (⇧⌘N)</translation>
<translation id="516920405563544094">የ<ph name="CREDIT_CARD" /> CVC ያስገቡ። ካረጋገጡ በኋላ የGoogle መለያዎ ካርድ ዝርዝሮች ለዚህ ጣቢያ ይጋራሉ።</translation>
<translation id="5169827969064885044">የድርጅት መለያዎን መዳረሻ ሊያጡ ወይም የማንነት ስርቆት ሊያጋጥመዎት ይችላሉ። Chrome የይለፍ ቃልዎን አሁን እንዲቀይሩ ይመክራል።</translation>
<translation id="5171045022955879922">ይፈልጉ ወይም ዩአርኤል ይጻፉ</translation>
+<translation id="5171689220826475070">ፋንፎልድ-አውሮፓ</translation>
<translation id="5172758083709347301">ማሽን</translation>
<translation id="5179510805599951267">በ<ph name="ORIGINAL_LANGUAGE" /> አይደለም? ይህን ስህተት ሪፖርት ያድርጉ</translation>
<translation id="5190835502935405962">የዕልባቶች አሞሌ</translation>
-<translation id="5200263511887412697">በቅርቡ በመለያ የገቡ የመሣሪያ ተጠቃሚዎች ዝርዝርን ሪፖርት አድርግ</translation>
+<translation id="519422657042045905">ማብራሪያ አይገኝም</translation>
<translation id="5201306358585911203">በዚህ ድረ-ገጽ ላይ ያለ የተካተተ ገጽ እንዲህ ይላል፦</translation>
<translation id="5205222826937269299">ስም ያስፈልጋል</translation>
<translation id="5215116848420601511">Google Payን የሚጠቀሙ የመክፈያ ዘዴዎች እና አድራሻዎች</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ኢሜይል ያስፈልጋል</translation>
<translation id="5230733896359313003">የሚላክበት አድራሻ</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">«ከአውታረ መረብ ጋር ይገናኙ»</translation>
<translation id="5251803541071282808">ደመና</translation>
+<translation id="5252000469029418751">C7 (የደብዳቤ ፖስታ)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">የአውታረ መረብ አድራሻዎች</translation>
<translation id="5285570108065881030">ሁሉንም የተቀመጡ የይለፍ ቃላት አሳይ</translation>
<translation id="5287240709317226393">ኩኪዎችን አሳይ</translation>
<translation id="5288108484102287882">የመመሪያ እሴቶችን ማረጋገጥ ማስጠንቀቂያዎችን አስነስቷል</translation>
@@ -692,7 +784,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />፣ <ph name="MATCH_POSITION" /> ከ<ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">የእውቂያ መረጃ ይምረጡ</translation>
<translation id="5327248766486351172">ስም</translation>
+<translation id="5329858041417644019">የእርስዎ አሳሽ አይተዳደርም</translation>
<translation id="5332219387342487447">የመላኪያ መንገድ</translation>
+<translation id="5334013548165032829">ዝርዝር የስርዓት ምዝግብ ማስታወሻዎች</translation>
<translation id="5344579389779391559">ይህ ገጽ እርስዎን ገንዘብ ለማስከፈል ሊሞክር ይችላል</translation>
<translation id="5355557959165512791">የዕውቅና ማረጋገጫው ስለተሻረ <ph name="SITE" />ን መጎብኘት አይችሉም። የአውታረ መረብ ስህተቶች እና ጥቃቶች አብዛኛው ጊዜ ጊዜያዊ ብቻ ናቸው፣ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላል።</translation>
<translation id="536296301121032821">የመምሪያ ቅንብሮችን ማከማቸት አልተሳካም</translation>
@@ -700,6 +794,7 @@
<translation id="5377026284221673050">«የእርስዎ ሰዓት ቀርቷል» ወይም «የእርስዎ ሰዓት ቀድሟል» ወይም «&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;»</translation>
<translation id="5384855140246857529">ካርዶችዎን በሁሉም መሣሪያዎችዎ ላይ ለመጠቀም በመለያ ይግቡና ስምረትን ያብሩ።</translation>
<translation id="5386426401304769735">የዚህ ጣቢያ የዕውቅና ማረጋገጫ ሰንሰለቱ SHA-1 በመጠቀም የተፈረመ የዕውቅና ማረጋገጫን ያካትታል።</translation>
+<translation id="538659543871111977">A4-ትር</translation>
<translation id="540969355065856584">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በዚህ ጊዜ ላይ የሚሰራ አይደለም። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
<translation id="5421136146218899937">የአሰሳ ውሂብ አጽዳ…</translation>
<translation id="5430298929874300616">ዕልባት አስወግድ</translation>
@@ -710,6 +805,7 @@
<translation id="5457113250005438886">ልክ ያልሆነ</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;አርትዕን ድገም</translation>
+<translation id="5478437291406423475">B6/C4 (የደብዳቤ ፖስታ)</translation>
<translation id="5481076368049295676">ይህ ይዘት በእርስዎ መሣሪያ ላይ መረጃዎን የሚሰርቅ ወይም የሚሰርዝ አደገኛ ሶፍትዌርን ለመጫን ሊሞክር ይችል ይሆናል። <ph name="BEGIN_LINK" />የሆነው ሆኖ አሳይ<ph name="END_LINK" /></translation>
<translation id="54817484435770891">የሚሰራ አድራሻ ያስገቡ</translation>
<translation id="5490432419156082418">አድራሻዎች እና ተጨማሪ</translation>
@@ -717,10 +813,12 @@
<ph name="LINE_BREAK" />
የእርስዎን የስርዓት አስተዳዳሪ ለማነጋገር ይሞክሩ።</translation>
<translation id="549333378215107354">መጠን 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">የተዳደሩ እልባቶች</translation>
<translation id="5510766032865166053">ተወስዶ ወይም ተሰርዞ ሊሆን ይችላል።</translation>
<translation id="5523118979700054094">የመምሪያ ስም</translation>
<translation id="552553974213252141">ጽሑፉ በትክክል ነው የወጣው?</translation>
+<translation id="553484882784876924">Prc6 (የደብዳቤ ፖስታ)</translation>
<translation id="5540224163453853">የተጠየቀውን ጽሑፍ ማግኘት አልተቻለም።</translation>
<translation id="5541546772353173584">ኢሜይል ያክሉ</translation>
<translation id="5545756402275714221">ለእርስዎ የሚሆኑ ጽሑፎች</translation>
@@ -735,15 +833,21 @@
<translation id="5595485650161345191">አድራሻ አርትዕ</translation>
<translation id="5598944008576757369">የመክፈያ ዘዴ ይምረጡ</translation>
<translation id="560412284261940334">አስተዳደር አይደገፍም</translation>
+<translation id="5605670050355397069">ሌጀር</translation>
+<translation id="5607240918979444548">ስነ-ሕንጻ-C</translation>
<translation id="5610142619324316209">ግንኙነቱን መፈተሽ</translation>
<translation id="5610807607761827392">ካርዶችን እና አድራሻዎችን በ<ph name="BEGIN_LINK" />ቅንብሮች<ph name="END_LINK" /> ውስጥ ማቀናበር ይችላሉ።</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> እርስዎን በጣም ብዙ ጊዜ ወደ ሌላ ቦታ መርተዎታል።</translation>
<translation id="5629630648637658800">የመምሪያ ቅንብሮችን መጫን አልተሳካም</translation>
<translation id="5631439013527180824">ልክ ያልሆነ የመሣሪያ አስተዳደር ማስመሰያ</translation>
+<translation id="5632627355679805402">የእርስዎ ውሂብ ከ<ph name="TIME" /> ጀምሮ በእርስዎ <ph name="BEGIN_LINK" />የGoogle ይለፍ ቃል<ph name="END_LINK" /> የተመሠጠረ ነው። ማሳመር ለመጀመር ያስገቡት።</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="563324245173044180">አታላይ ይዘት ታግዷል።</translation>
<translation id="5659593005791499971">ኢሜይል</translation>
+<translation id="5663614846592581799">9x11 (የደብዳቤ ፖስታ)</translation>
+<translation id="5663955426505430495">የዚህ መሣሪያ አስተዳዳሪ ለተጨማሪ ተግባራት ቅጥያዎችን ጭኗል። ቅጥያዎች የአንዳንድ ውሂብዎ መዳረሻ አላቸው።</translation>
<translation id="5675650730144413517">ይህ ገጽ እየሠራ አይደለም</translation>
+<translation id="5684874026226664614">ውይ። ይህ ገጽ ሊተረጎም አይችልም።</translation>
<translation id="5685654322157854305">የመላኪያ አድራሻ ያክሉ</translation>
<translation id="5689199277474810259">ወደ JSON ላክ</translation>
<translation id="5689516760719285838">አካባቢ</translation>
@@ -752,38 +856,39 @@
<translation id="5710435578057952990">የዚህ ድረ-ገጽ ማንነት አልተረጋገጠም።</translation>
<translation id="5719499550583120431">የቅድመ-ክፍያ ካርዶች ተቀባይነት አላቸው።</translation>
<translation id="5720705177508910913">የአሁኑ ተጠቃሚ</translation>
+<translation id="5728056243719941842">C5 (የደብዳቤ ፖስታ)</translation>
<translation id="5730040223043577876">Chrome የእርስዎን ይለፍ ቃል በሌሎች ጣቢያዎች ላይ ዳግም ከተጠቀሙበት እንደገና እንዲያዋቅሩት ይመክራል።</translation>
<translation id="5732392974455271431">የእርስዎ ወላጆች እገዳውን ሊያነሱልዎ ይችላሉ</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{ካርድ በGoogle መለያዎ ውስጥ ያስቀምጡ}one{ካርዶችን ወደ የእርስዎ የGoogle መለያ ያስቀምጡ}other{ካርዶችን ወደ የእርስዎ የGoogle መለያ ያስቀምጡ}}</translation>
<translation id="5763042198335101085">ትክክለኛ የኢሜይል አድራሻ ያስገቡ</translation>
<translation id="5765072501007116331">የማድረሻ ዘዴዎችን እና መስፈርቶችን ለመመልከት አድራሻ ይምረጡ</translation>
-<translation id="5770114862687765385">ፋይሉ የተበላሸ ይመስላል። ክፍለ-ጊዜውን ዳግም ለማስጀመር የ«ዳግም አዝራር» አዝራሩን ጠቅ ያድርጉት።</translation>
<translation id="5778550464785688721">MIDI መሣሪያዎች ሙሉ ቁጥጥር</translation>
<translation id="578305955206182703">አምበር</translation>
<translation id="57838592816432529">ድምጽ ይዝጉ</translation>
<translation id="5784606427469807560">የእርስዎን ካርድ ማረጋገጥ ላይ አንድ ችግር ነበር። የበይነመረብ ግንኙነትዎን ይፈትሹት እና እንደገና ይሞክሩ።</translation>
<translation id="5785756445106461925">በተጨማሪ፣ ይህ ገጽ ደህንነታቸው ያልተጠበቀ ሌሎች ንብረቶችን አካትቷል። እነዚህ ንብረቶች በሽግግር ወቅት በሌሎች ሊታዩ ይችላሉ፣ እናም የገጹን መልክ ለመለወጥ በአጥቂዎች ሊቀየሩ ይችላሉ።</translation>
<translation id="5786044859038896871">የካርድዎን መረጃ መሙላት ይፈልጋሉ?</translation>
+<translation id="5798290721819630480">ለውጦች ይወገዱ?</translation>
<translation id="5798683403665926540">በChrome ቅንብሮች ውስጥ መነሻ ገጽን ይቀይሩ</translation>
<translation id="5803412860119678065">የእርስዎን <ph name="CARD_DETAIL" /> መሙላት ይፈልጋሉ?</translation>
<translation id="5804241973901381774">ፍቃዶች</translation>
<translation id="5810442152076338065">ወደ <ph name="DOMAIN" /> ግንኙነትዎ ፍጹማዊ ስነ መሰውር ጥቅል በመጠቀም የተመሳጠረ ነው።</translation>
<translation id="5813119285467412249">&amp;አክልን ድገም</translation>
<translation id="5838278095973806738">በአጥቂዎች ሊሰረቅ ስለሚችል በዚህ ጣቢያ ላይ ማናቸውም አደጋን ሊያስከትል የሚችል መረጃ (ለምሳሌ፦ የይለፍ ቃሎች ወይም የክሬዲት ካርዶች) ማስገባት የለብዎትም።</translation>
+<translation id="5860033963881614850">አጥፋ</translation>
<translation id="5863847714970149516">ከፊት ያለው ገጽ እርስዎን ገንዘብ ለማስከፈል ሊሞክር ይችላል</translation>
<translation id="5866257070973731571">ስልክ ቁጥር ያክሉ</translation>
<translation id="5869405914158311789">ይህ ጣቢያ ሊደረስበት አይችልም</translation>
<translation id="5869522115854928033">የተቀመጡ የይለፍ ቃሎች</translation>
<translation id="5887400589839399685">ካርድ ተቀምጧል</translation>
-<translation id="5893718151540690985">የአውታረ መረብ በይነገጾች ዝርዝርን ከአይነቶቻቸው እና የሃርድዌር አድራሻዎቻቸው ጋር ሪፖርት አድርግ</translation>
<translation id="5893752035575986141">ክሬዲት ካርዶች ተቀባይነት አላቸው።</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="5916664084637901428">በርቷል</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">ወደ Google መለያ ካርድ ይቀመጥ?</translation>
<translation id="5922853866070715753">በቃ ሊያልቅ ነው</translation>
<translation id="5932224571077948991">ጣቢያ ረባሽ ወይም አሳሳች ማስታወቂያዎችን ያሳያል</translation>
-<translation id="5939518447894949180">ዳግም አስጀምር</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" />ን በመክፈት ላይ…</translation>
<translation id="5951495562196540101">በሸማች መለያ መመዝገብ አይቻልም (የጥቅል ፈቃድ ይገኛል)።</translation>
<translation id="5967592137238574583">የዕውቂያ መረጃን ያርትዑ</translation>
@@ -791,6 +896,7 @@
<translation id="5975083100439434680">አሳንስ</translation>
<translation id="5977489021191000276">የእርስዎ መሣሪያ በአስተዳዳሪ አይተዳደርም።</translation>
<translation id="5977976211062815271">በዚህ መሣሪያ ላይ</translation>
+<translation id="5980920751713728343">መረጃ ጠቋሚ-3x5</translation>
<translation id="598637245381783098">የክፍያ መተግበሪያን መክፈት አይቻልም</translation>
<translation id="5989320800837274978">ቋሚ ተኪ አገልጋዮችም ሆኑ የ.pac ስክሪፕት ዩአርኤል አልተገለጹም።</translation>
<translation id="5990559369517809815">ወደ አገልጋዩ የተላኩ ጥያቄዎች በአንድ ቅጥያ ታግደዋል።</translation>
@@ -801,8 +907,8 @@
<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="6033927989869462158">እንደ የሲፒዩ/ራም አጠቃቀም ያሉ የሃርድዌር ስታቲስቲክስን ሪፖርት አድርግ</translation>
<translation id="6034000775414344507">ፈካ ያለ ግራጫ</translation>
+<translation id="6034283069659657473">10x14 (የደብዳቤ ፖስታ)</translation>
<translation id="6039846035001940113">ችግሩ ከቀጠለ የጣቢያ ባለቤቱን ያነጋግሩ።</translation>
<translation id="6040143037577758943">ዝጋ</translation>
<translation id="6044573915096792553">መጠን 12</translation>
@@ -811,10 +917,10 @@
<translation id="6051221802930200923"><ph name="SITE" /> የዕውቅና ማረጋገጫ ሚስማር መሰካትን ስለሚጠቀም ድር ጣቢያውን አሁን መጎብኘት አይችሉም። የአውታረ መረብ ስህተቶች እና ጥቃቶች ብዙውን ጊዜ ጊዜያዊ ስለሆኑ ይህ ገጽ በኋላ ላይ ሊሠራ ይችላል።</translation>
<translation id="6058977677006700226">በሁሉም የእርስዎ መሣሪያዎች ላይ የእርስዎ ኮርዶች ጥቅም ላይ ይዋሉ?</translation>
<translation id="6059925163896151826">የዩኤስቢ መሣሪያዎች</translation>
-<translation id="6071091556643036997">የመመሪያው አይነት ልክ ያልሆነ ነው።</translation>
<translation id="6080696365213338172">በአስተዳዳሪ የቀረበ የእውቅና ማረጋገጫ በመጠቀም ይዘት ደርሰዋል። ለ<ph name="DOMAIN" /> የሚያቀርቡት ውሂብ በአስተዳዳሪዎ ሊያዝ ይችላል።</translation>
<translation id="6094273045989040137">አብራራ</translation>
<translation id="610911394827799129">የእርስዎ Google መለያ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ላይ ሌሎች የአሰሳ ታሪክ ዓይነቶች ሊኖረው ይችላል።</translation>
+<translation id="6132597952260690497">ስለተጫኑ ቅጥያዎች እና ተሰኪዎች መረጃ</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ምንም}=1{1 የይለፍ ቃል (የተሰመረ)}one{# የይለፍ ቃሎች (የተሰመሩ)}other{# የይለፍ ቃሎች (የተሰመሩ)}}</translation>
<translation id="6146055958333702838">ማናቸውም ገመዶችን ይፈትሹና እየተጠቀሙ ሊሆኑ የሚችሏቸውን ማንኛውም ራውተሮች፣
ሞደሞችን ወይም ሌላ አውታረ መረብ መሣሪያዎችን ዳግም ያስጀምሩ።</translation>
@@ -849,15 +955,21 @@
<translation id="6337133576188860026">ከ<ph name="SIZE" /> ያነሰ ቦታ ያስለቅቃል። አንዳንድ ጣቢያዎች በሚቀጥለው ጉብኝትዎ ላይ ይበልጥ በዝግታ ሊጫኑ ይችላሉ።</translation>
<translation id="6337534724793800597">መምሪያዎችን በስም አጣራ</translation>
<translation id="6358450015545214790">እነዚህ ምን ማለት ናቸው?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">ሊሆኑ የሚችሉ ክፍያ መጠየቂያዎች እየመጡ ነው።</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 ሌላ የአስተያየት ጥቆማ}one{# ሌሎች የአስተያየት ጥቆማዎች}other{# ሌሎች የአስተያየት ጥቆማዎች}}</translation>
<translation id="6387754724289022810">በሚቀጥለው ጊዜ በበለጠ ፍጥነት ለመክፈል ካርድዎን እና የማስከፈያ አድራሻዎን በGoogle መለያዎ እና በዚህ መሣሪያ ላይ ያስቀምጡ።</translation>
+<translation id="6390662030813198813">ምሕንድስና-E</translation>
<translation id="6404511346730675251">ዕልባት አርትዕ</translation>
+<translation id="6406765186087300643">C0 (የደብዳቤ ፖስታ)</translation>
<translation id="6410264514553301377">የ<ph name="CREDIT_CARD" /> የአገልግሎት ማብቂያ ቀን እና ሲቪሲ ያስገቡ</translation>
<translation id="6414888972213066896">ይህን ጣቢያ መጎብኘት ችግር ካለው ወላጅዎን ጠይቀዋል</translation>
<translation id="6417515091412812850">የእውቅና ማረጋገጫው ተሽሮ እንደሆነ ማረጋገጥ አልተቻለም።</translation>
<translation id="6433490469411711332">የዕውቂያ መረጃን ያርትዑ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ማገናኘት አሻፈረኝ ብሏል።</translation>
+<translation id="6434309073475700221">አስወግድ</translation>
+<translation id="6446163441502663861">ካሁ (የደብዳቤ ፖስታ)</translation>
<translation id="6446608382365791566">ተጨማሪ መረጃ ያክሉ</translation>
<translation id="6447842834002726250">ኩኪዎች</translation>
<translation id="6451458296329894277">እንደገና ለማስገባት የማረጋገጫ ቅጽ</translation>
@@ -870,11 +982,17 @@
<translation id="6508722015517270189">Chromeን ዳግም ያስጀምሩት</translation>
<translation id="6529602333819889595">&amp;ሰርዝን ድገም</translation>
<translation id="6534179046333460208">የአካላዊ ድር ጥቆማዎች</translation>
+<translation id="6556866813142980365">ድገም</translation>
<translation id="6563469144985748109">የእርስዎ አስተዳዳሪ ገና አላጸደቁትም</translation>
<translation id="6569060085658103619">የቅጥያ ገጽ እየተመለከቱ ነው</translation>
+<translation id="6578796323535178455">C2 (የደብዳቤ ፖስታ)</translation>
<translation id="6579990219486187401">ፈዛዛ ሮዝ</translation>
+<translation id="6583674473685352014">B6 (የደንዳቤ ፖስታ)</translation>
+<translation id="6587923378399804057">እርስዎ የቀዱት አገናኝ</translation>
+<translation id="6591833882275308647">የእርስዎ <ph name="DEVICE_TYPE" /> የሚተዳደር አይደለም</translation>
<translation id="6596325263575161958">የምስጠራ አማራጮች</translation>
<translation id="6604181099783169992">የእንቅስቃሴ ወይም የብርሃን ዳሳሾች</translation>
+<translation id="6609880536175561541">Prc7 (የደብዳቤ ፖስታ)</translation>
<translation id="6624427990725312378">የዕውቂያ መረጃ</translation>
<translation id="6626291197371920147">የሚሰራ የካርድ ቁጥር ያክሉ</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> ፍለጋ</translation>
@@ -883,6 +1001,7 @@
<translation id="6644283850729428850">ይህ መመሪያ ተቋርጧል።</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ምንም}=1{ከ1 ጣቢያ (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}one{ከ# ጣቢያዎች (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}other{ከ# ጣቢያዎች (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}}</translation>
<translation id="6657585470893396449">የይለፍ ቃል፦</translation>
+<translation id="6670613747977017428">ወደ ደህንነት ተመለስ።</translation>
<translation id="6671697161687535275">የአስተያየት ጥቆማ ከChromium ይወገድ?</translation>
<translation id="6685834062052613830">ዘግተው ይውጡ እና ቅንብርን ያጠናቅቁ</translation>
<translation id="6710213216561001401">ቀዳሚ</translation>
@@ -890,12 +1009,15 @@
<translation id="671076103358959139">የምዝገባ ማስመሰያ፦</translation>
<translation id="6711464428925977395">በተኪ አገልጋዩ ላይ የሆነ ችግር አለ ወይም አድራሻው ትክክል አይደለም።</translation>
<translation id="6723740634201835758">በእርስዎ የGoogle መለያ ውስጥ</translation>
+<translation id="6738516213925468394">የእርስዎ ውሂብ በ<ph name="TIME" /> ላይ በእርስዎ <ph name="BEGIN_LINK" />የስምረት ይለፍ ሐረግ<ph name="END_LINK" /> ተመስጥሯል። ስምረትን ለመጀመር ያስገቡት።</translation>
<translation id="674375294223700098">ያልታወቀ የአገልጋይ እውቅና ማረጋገጫ ስህተት።</translation>
<translation id="6744009308914054259">ግንኙነትን እየተጠባበቁ ሳሉ የመስመር ውጪ ጽሑፎችን ለማንበብ ውርዶችን መጎብኘት ይችላሉ።</translation>
<translation id="6753269504797312559">የመምሪያ እሴት</translation>
<translation id="6757797048963528358">የእርስዎ መሣሪያ ተኝቷል።</translation>
+<translation id="6768213884286397650">ሃጋኪ (ፖስታ ካርድ)</translation>
<translation id="6778737459546443941">የእርስዎ ወላጅ ገና አላጸደቁትም</translation>
<translation id="67862343314499040">ወይን ጠጅ</translation>
+<translation id="6786747875388722282">ቅጥያዎች</translation>
<translation id="679355240208270552">ነባሪው ፍለጋ በመምሪያ ስላልነቃ ችላ ተብሏል።</translation>
<translation id="681021252041861472">የሚያስፈልግ መስክ</translation>
<translation id="6810899417690483278">የብጁነት መታወቂያ</translation>
@@ -928,10 +1050,12 @@
<translation id="6965978654500191972">መሣሪያ</translation>
<translation id="6970216967273061347">ወረዳ</translation>
<translation id="6973656660372572881">ሁለቱም ቋሚ ተኪ አገልጋዮች እና የ.pac ስክሪፕት ዩአርኤል ተገልጸዋል።</translation>
+<translation id="6973932557599545801">ከእንግዲህ ላግዝ አልችልም፣ እባክዎ በራስዎ ይቀጥሉ።</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">ድምጸ-ከል አድርግ (ነባሪ)</translation>
<translation id="6984479912851154518">በውጫዊ ማከማቻ በኩል ለማጫወት ከግል ሁነታ በመውጣት ላይ። ይቀጥል?</translation>
<translation id="6989763994942163495">የላቁ ቅንብሮችን አሳይ...</translation>
+<translation id="6993898126790112050">6x9 (የደብዳቤ ፖስታ)</translation>
<translation id="6996312675313362352">ሁልጊዜ <ph name="ORIGINAL_LANGUAGE" />ን ተርጉም</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">እነዚህ ክፍያዎች የአንድ ጊዜ ወይም ተደጋጋሚ፣ እና የማያስታውቁ ሊሆኑ ይችላሉ።</translation>
@@ -947,28 +1071,33 @@
<translation id="7108338896283013870">ደብቅ</translation>
<translation id="7108819624672055576">በቅጥያ የተፈቀደ</translation>
<translation id="7111012039238467737">(የሚሰራ)</translation>
+<translation id="7118618213916969306">የቅንጥብ ሰሌዳ ዩአርኤል <ph name="SHORT_URL" /> ይፈልጉ</translation>
<translation id="7119414471315195487">ሌሎች ትሮችን ወይም ፕሮግራሞችን ይዝጉ</translation>
<translation id="7129409597930077180">ወደዚህ አድራሻ መላክ አይቻልም። የተለየ አድራሻ ይምረጡ።</translation>
<translation id="7135130955892390533">ሁኔታን አሳይ</translation>
<translation id="7138472120740807366">የማድረሻ ስልት</translation>
<translation id="7139724024395191329">ኤሚሬት</translation>
+<translation id="7152423860607593928">ቁጥር-14 (የደብዳቤ ፖስታ)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ፈዘዝ ያለ ወይን ጠጅ</translation>
-<translation id="7158980942472052083">ልክ ያልሆነ ዩአርኤል። መደበኛ ዕቅድ ያለው ዩአርኤል መሆን አለበት።</translation>
<translation id="717330890047184534">የGaia መታወቂያ፦</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">የሚሄዱበት አገልጋይ <ph name="ORIGIN" /> ለጠየቁ ሁሉ የደህንነት መመሪያ እንዲተገበር ጠይቋል። ነገር ግን መመሪያን ከማድረስ ይልቅ አሳሹን ወደ ሌላ ቦታ አዙሮታል፣ ይህም አሳሹ የ<ph name="SITE" /> ጥያቄዎን ከማሟላት ይከለክለዋል።</translation>
<translation id="7179323680825933600">የመክፈያ ዘዴዎችን አስቀምጥ እና ሙላ</translation>
<translation id="7180611975245234373">አድስ</translation>
<translation id="7182878459783632708">ምንም መምሪያዎች አልተዋቀሩም</translation>
<translation id="7186367841673660872">ይህ ገጽ ከ<ph name="ORIGINAL_LANGUAGE" />ወደ<ph name="LANGUAGE_LANGUAGE" />ተተርጉሟል</translation>
<translation id="7192203810768312527">እስከ <ph name="SIZE" /> ያስለቅቃል። አንዳንድ ጣቢያዎች በሚቀጥለው ጉብኝትዎ ላይ ይበልጥ በዝግታ ሊጫኑ ይችላሉ።</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">የእርስዎ አስተዳዳሪ እነዚህን መመልከት ይችላል፦</translation>
+<translation id="7202346780273620635">ደብዳቤ-ተጨማሪ</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> የደህንነት መስፈርቶችን አያከብርም።</translation>
<translation id="721197778055552897">ስለዚህ ችግር <ph name="BEGIN_LINK" />ተጨማሪ ለመረዳት<ph name="END_LINK" /> ።</translation>
<translation id="7219179957768738017">ግንኙነቱ <ph name="SSL_VERSION" />ን ይጠቀማል።</translation>
<translation id="7220786058474068424">በማስሄድ ላይ</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />፤ <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">ፊት ያለው ጣቢያ ተንኮል-አዘል ዌር አለው</translation>
+<translation id="724766306220616965">ማስጠንቀቂያዎች፣ ግጭት</translation>
<translation id="724975217298816891">የካርድ ዝርዝሮችዎን ለማዘመን የ<ph name="CREDIT_CARD" /> ጊዜ ማለፊያ ቀን እና ሲቪሲ ያስገቡ። አንዴ ካረጋገጡ በኋላ የካርድ ዝርዝሮችዎ ለዚህ ጣቢያ ይጋራሉ።</translation>
<translation id="7251437084390964440">የአውታረ መረብ ውቅረቱ የኦኤንሲ መስፈርቱን አያሟላም። አንዳንድ የውቅረቱ ክፍሎች ላይመጡ ይችላሉ።
ተጨማሪ ዝርዝሮች፦
@@ -981,11 +1110,14 @@
<translation id="7300012071106347854">በራ ያለ ውሃ ሰማያዊ</translation>
<translation id="7302712225291570345">«<ph name="TEXT" />»</translation>
<translation id="7309308571273880165">በ<ph name="CRASH_TIME" /> ላይ የተነሳ የብልሽት ሪፖርት (ሰቀላ በተጠቃሚ ተጠይቆ ነበር፣ ሆኖም ግን እስካሁን አልተሰቀለም)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />የጥንቃቄ አሰሳ<ph name="END_LINK" /> ማስጠንቀቂያዎች</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">የግንኙነት እገዛ</translation>
<translation id="7334320624316649418">&amp;ማስተካከልን ድገም</translation>
<translation id="733923710415886693">የአገልጋዩ የእውቅና ማረጋገጫ በእውቅና ማረጋገጫ ግልጽነት በኩል አልተገለጸም።</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-ተጨማሪ</translation>
<translation id="7353601530677266744">የትእዛዝ መስመር</translation>
-<translation id="7365061714576910172">በLinux ወደ ውጭ ላክ</translation>
<translation id="7372973238305370288">የፍለጋ ውጤት</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">አይ</translation>
@@ -993,6 +1125,7 @@
<translation id="7381288752349550461">የሚተዳደር ክፍለ-ጊዜን መሻር</translation>
<translation id="7390545607259442187">ካርድ ያረጋግጡ</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">የእርስዎ <ph name="DEVICE_NAME" /> የሚተዳደር ነው</translation>
<translation id="7407424307057130981">&lt;p&gt;በWindows ኮምፒውተርዎ ላይ የSuperfish ሶፍትዌር ካለዎት ይህን ስህተት ያዩታል።&lt;/p&gt;
&lt;p&gt;ወደ ድሩ መሄድ እንዲችሉ ሶፍትዌሩን ለጊዜው ለማሰናከል እነዚህን ደረጃዎች ይከተሉ። የአስተዳዳሪ ልዩ መብቶች ያስፈልገዎታል።&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1136,7 @@
&lt;li&gt;&lt;strong&gt;ተግብር&lt;/strong&gt;ን ጠቅ ያድርጉ፣ ከዚያ &lt;strong&gt;እሺ&lt;/strong&gt;ን ጠቅ ያድርጉ
&lt;li&gt;እንዴት ሶፍትዌሩን ከኮምፒውተርዎ እስከመጨረሻው ማስወገድ እንደሚችሉ ለማወቅ &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;የChrome እገዛ ማዕከል&lt;/a&gt;ን ይጎብኙ
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">የ<ph name="PRODUCT_NAME" /> አስተዳደር</translation>
+<translation id="741007362987735528">ሰፊ-ቅርጸት</translation>
<translation id="7416351320495623771">የይለፍ ቃላትን ያስተዳድሩ...</translation>
<translation id="7419106976560586862">የመገለጫ ዱካ</translation>
<translation id="7437289804838430631">የእውቂያ መረጃ አክል</translation>
@@ -1012,22 +1145,24 @@
<translation id="7442725080345379071">ፈዘዝ ያለ ብርትኳናማ</translation>
<translation id="7444046173054089907">ይህ ጣቢያ ታግዷል</translation>
<translation id="7445762425076701745">የተገናኙት የአገልጋይ ማንነት ሙሉ ለሙሉ ሊረጋገጥ አልቻለም። ስሙ በአውታረ መረብዎ ውስጥ ብቻ ልክ ከሆነ አገልጋይ ጋር ነው የተገናኙት፣ እና ባለቤትነቱ በውጫዊ የእውቅና ማረጋገጫ ሊረጋገጥ አይችልም። አንዳንድ የእውቅና ማረጋገጫ ባለስልጣናት ይሁን ብለው ለእነዚህ ስሞች የእውቅና ማረጋገጫዎች መስጠታቸው የማይቀር እንደመሆኑ መጠን፣ ከአጥቂ ሳይሆን ከታሰበው ድር ጣቢያ ጋር መገናኘትዎን የሚረጋገጥበት ምንም መንገድ የለም።</translation>
-<translation id="7449109375006139765">የስርዓት ምዝግብ ማስታወሻዎችን ወደ የአስተዳደር አገልጋዩ ይላኩ</translation>
<translation id="7451311239929941790">ስለዚህ ችግር <ph name="BEGIN_LINK" />ይበልጥ በመረዳት ላይ<ph name="END_LINK" />።</translation>
<translation id="7455133967321480974">ሁለንተናዊ ነባሪውን ተጠቀም (አግድ)</translation>
<translation id="7460618730930299168">ማያ ገጹ አቀራረብ እርስዎ ከመረጡት የተለየ ነው። ይቀጥል?</translation>
<translation id="7473891865547856676">አይ፣ አመሰግናለሁ</translation>
-<translation id="7475525192983021547">አንድ ተጠቃሚ በመሣሪያው ላይ ገቢር ሲሆን ክፍለ-ጊዜዎችን ሪፖርት አድርግ</translation>
<translation id="7481312909269577407">ወደ ፊት</translation>
<translation id="7485870689360869515">ምንም ውሂብ አልተገኘም።</translation>
+<translation id="7498234416455752244">አርትዖቱን ቀጥል</translation>
<translation id="7508255263130623398">የተመላሽ መመሪያ መሣሪያ መታወቂያ ባዶ ነው ወይም ከአሁኑ የመሣሪያ መታወቂያ ጋር አይዛመድም</translation>
<translation id="7508870219247277067">አቮካዶ አረንጓዴ</translation>
<translation id="7511955381719512146">እየተጠቀሙበት ያለው Wi-Fi <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ን እንዲጎበኙ ሊጠይቅዎት ይችላል።</translation>
<translation id="7514365320538308">አውርድ</translation>
<translation id="7518003948725431193">ለዚህ የድር አድራሻ ምንም ድረ-ገጽ አልተገኘም፦ <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (የደብዳቤ ፖስታ)</translation>
<translation id="7521387064766892559">ጃቫስክሪፕት</translation>
<translation id="7526934274050461096">ከዚሃ ጣቢያ ጋር ያለዎት ግንኙነት የግል አይደለም</translation>
+<translation id="7535087603100972091">እሴት</translation>
<translation id="7537536606612762813">ግዴታ</translation>
+<translation id="7538364083937897561">A2 (የደብዳቤ ፖስታ)</translation>
<translation id="7542403920425041731">አንዴ ካረጋገጡ በኋላ የካርድ ዝርዝሮችዎ ለዚህ ጣቢያ ይጋራሉ።</translation>
<translation id="7542995811387359312">ይህ ቅጽ ደህንነቱ የተጠበቀ ግንኙነት ስለማይጠቀም የክሬዲት ካርድ ራስ-መሙላት ተሰናክሏል።</translation>
<translation id="7543525346216957623">የእርስዎን ወላጅ ይጠይቁ</translation>
@@ -1036,8 +1171,8 @@
<translation id="7552846755917812628">የሚከተሉትን ጠቃሚ ምክሮች ይሞክሩ፦</translation>
<translation id="7554791636758816595">አዲስ ትር</translation>
<translation id="7564049878696755256">የ<ph name="ORG_NAME" /> መለያዎን መዳረሻ ሊያጡ ወይም የማንነት ስርቆት ሊያጋጥመዎት ይችላሉ። Chrome የይለፍ ቃልዎን አሁን እንዲቀይሩ ይመክራል።</translation>
-<translation id="7566125604157659769">እርስዎ የቀዱት ጽሑፍ</translation>
<translation id="7567204685887185387">ይህ አገልጋይ <ph name="DOMAIN" /> መሆኑን ሊያረጋግጥ አልቻለም፤ የደህንነት እውቅና ማረጋገጫው በተጭበረበረ ሁኔታ ተሰጥቶ ሊሆን ይችላል። ይሄ በተሳሳተ አወቃቀር ወይም አንድ አጥቂ ግንኙነትዎን በመጥለፉ የተከሰተ ሊሆን ይችላል።</translation>
+<translation id="7568105740864181217">ይህ አሳሽ በኩባንያ፣ ትምህርት ቤት ወይም በሌላ ድርጅት የሚተዳደር ነው። የእርስዎ አስተዳዳሪ በርቀት የአሳሽዎን ውቅረት መቀየር ይችላል። በዚህ መሣሪያ ላይ ያለ እንቅስቃሴ እንዲሁም ከChrome ውጭ ሊተዳደር ይችላል። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">ክሬዲት ካርድ ከChrome ይወገድ?</translation>
<translation id="7569983096843329377">ጥቁር</translation>
<translation id="7578104083680115302">Google ላይ ያስቀመጧቸውን ካርዶች በመጠቀም በሁሉም መሣሪያዎች ላይ በጣቢያዎችና መተግበሪያዎች ላይ በፍጥነት ይክፈሉ።</translation>
@@ -1048,6 +1183,7 @@
<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="7633909222644580952">የአፈጻጸም ውሂብ እና የብልሽት ሪፖርቶች</translation>
<translation id="7637571805876720304">ክሬዲት ካርድ ከChromium ይወገድ?</translation>
<translation id="7639968568612851608">ጠቆር ያለ ግራጫ</translation>
<translation id="765676359832457558">የላቁ ቅንብሮችን ደብቅ...</translation>
@@ -1057,9 +1193,11 @@
<translation id="7667346355482952095">የተመለሰው የመመሪያ ማስመሰያ ባዶ ነው ወይም ከአሁኑ ማስመሰያ ጋር አይዛመድም</translation>
<translation id="7668654391829183341">ያልታወቀ መሣሪያ</translation>
<translation id="7669271284792375604">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች እርስዎ የአሰሳ ተሞክሮዎን ሊጎዱ (ለምሳሌ፦ መነሻ ገጽዎን በመቀየር ወይም በሚጎበኟቸው ጣቢያዎች ላይ ተጨማሪ ማስታወቂያዎችን በማሳየት) የሚችሉ ፕሮግራሞችን እንዲጭኑ ለማታለል ሊሞክሩ ይችላሉ።</translation>
+<translation id="7676643023259824263">የቅንጥብ ሰሌዳ ጽሑፍ <ph name="TEXT" /> ይፈልጉ</translation>
<translation id="7681101578153515023">የፍለጋ ፕሮግራም ቀይር</translation>
<translation id="7682287625158474539">ዕቃን የማጓጓዝ ስራ</translation>
<translation id="7687186412095877299">የክፍያ ቅጾችን በተቀመጡ የመክፈያ ዘዴዎችዎ ይሞላቸዋል</translation>
+<translation id="7697066736081121494">Prc8 (የደብዳቤ ፖስታ)</translation>
<translation id="769721561045429135">አሁን ላይ በዚህ መሣሪያ ላይ ብቻ ጥቅም ላይ ሊውሉ የሚችሉ ካርዶች አልዎት ካርዶችን መገምገም ለመቀጠል ጠቅ ያድርጉ።</translation>
<translation id="7699293099605015246">ጽሑፎች አሁን አይገኙም</translation>
<translation id="7701040980221191251">ምንም</translation>
@@ -1071,11 +1209,13 @@
<translation id="774634243536837715">አደገኛ ይዘት ታግዷል።</translation>
<translation id="7752995774971033316">አይቀናበርም</translation>
<translation id="7755287808199759310">የእርስዎ ወላጅ እገዳውን ሊያነሱልዎ ይችላሉ</translation>
+<translation id="7757555340166475417">ዳይ ፓ ካይ</translation>
<translation id="7758069387465995638">የኬላ ወይም የፀረ-ቫይረስ ሶፍትዌር ግንኙነቱን አግዶት ሊሆን ይችላል።</translation>
<translation id="7759163816903619567">የማሳያ ጎራ፦</translation>
<translation id="7761701407923456692">የአገልጋይ እውቅና ማረጋገጫ ከዩ አር ኤሉ ጋር አይዛመድም።</translation>
<translation id="7763386264682878361">የክፍያ ዝርዝር ሰነድ ተንታኝ</translation>
<translation id="7764225426217299476">አድራሻ አክል</translation>
+<translation id="7770259615151589601">የተሰየመ-ረጅም</translation>
<translation id="777702478322588152">መስተዳድር</translation>
<translation id="7791543448312431591">አክል</translation>
<translation id="7793809570500803535"><ph name="SITE" /> ላይ ያለው ድረ-ገጽ ለጊዜው የማይሰራ ወይም እስከመጨረሻው ወደ አዲስ የድር አድራሻ ተዛውሮ ሊሆን ይችላል።</translation>
@@ -1087,8 +1227,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">የአስተያየት ጥቆማ ከChrome ይወገድ?</translation>
<translation id="7815407501681723534">ለ«<ph name="SEARCH_STRING" />» <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> ተገኝተዋል።</translation>
-<translation id="7818867226424560206">የመምሪያ አስተዳደር</translation>
<translation id="782886543891417279">እየተጠቀሙበት ያለው Wi-Fi (<ph name="WIFI_NAME" />) በመለያ መግቢያ ገጹን እንዲጎበኙ ሊጠይቅዎት ይችላል።</translation>
+<translation id="7836231406687464395">Postfix (የደብዳቤ ፖስታ)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ምንም}=1{1 መተግበሪያ (<ph name="EXAMPLE_APP_1" />)}=2{2 መተግበሪያዎች (<ph name="EXAMPLE_APP_1" />፣ <ph name="EXAMPLE_APP_2" />)}one{# መተግበሪያዎች (<ph name="EXAMPLE_APP_1" />፣ <ph name="EXAMPLE_APP_2" />፣ <ph name="AND_MORE" />)}other{# መተግበሪያዎች (<ph name="EXAMPLE_APP_1" />፣ <ph name="EXAMPLE_APP_2" />፣ <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">ሆኖም ግን የማይታዩ አይደሉም። ማንነት የማያሳውቅ ሁነታ መጠቀም የእርስዎን አሰሳ፣ የበይነመረብ አገልግሎት አቅራቢ ወይም የሚጎበኟቸው ድር ጣቢያዎች ከአሰሪዎ አይደብቃቸውም።</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1237,7 @@
<translation id="7878562273885520351">የእርስዎ ይለፍ ቃል ተሰርቆ ሊሆን ይችላል</translation>
<translation id="7882421473871500483">ቡናማ</translation>
<translation id="7887683347370398519">የእርስዎን CVC ይፈትሹ እና እንደገና ይሞክሩ</translation>
-<translation id="7893255318348328562">የክፍለ-ጊዜ ስም</translation>
+<translation id="7904208859782148177">C3 (የደብዳቤ ፖስታ)</translation>
<translation id="79338296614623784">የሚሰራ ስልክ ቁጥር ያስገቡ</translation>
<translation id="7935318582918952113">የDOM ማጣሪያ</translation>
<translation id="7937554595067888181">በ<ph name="EXPIRATION_DATE_ABBR" /> ላይ አገልግሎት ጊዜው ያበቃል</translation>
@@ -1107,21 +1247,25 @@
<translation id="7951415247503192394">(32-ቢት)</translation>
<translation id="7956713633345437162">የተንቀሳቃሽ ስልክ ዕልባቶች</translation>
<translation id="7961015016161918242">በፍጹም</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">አልተጠቀሰም</translation>
<translation id="800218591365569300">የማህደረ ትውስታ ቦታን ለማስለቀቅ ሌሎች ትሮችን ወይም ፕሮግራሞችን ዘግተው ይሞክሩ።</translation>
+<translation id="8004582292198964060">አሳሽ</translation>
<translation id="8009225694047762179">የይለፍ ቃላትን ያቀናብሩ</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{ይህ ካርድ እና የክፍያ መጠየቂያ አድራሻው ይቀመጣሉ። በመለያ ወደ <ph name="USER_EMAIL" /> ሲገቡ ሊጠቀሙበት ይችላሉ።}one{እነዚህ ካርዶች እና የክፍያ መጠየቂያ አድራሻዎቻቸው ይቀመጣሉ። በመለያ ወደ <ph name="USER_EMAIL" /> ሲገቡ ሊጠቀሙባቸው ይችላሉ።}other{እነዚህ ካርዶች እና የክፍያ መጠየቂያ አድራሻዎቻቸው ይቀመጣሉ። በመለያ ወደ <ph name="USER_EMAIL" /> ሲገቡ ሊጠቀሙባቸው ይችላሉ።}}</translation>
<translation id="8012647001091218357">በዚህ ጊዜ ላይ ወላጆችህን መድረስ አልቻልንም። እባክህ እንደገና ሞክር።</translation>
<translation id="8025119109950072390">በዚህ ጣቢያ ላይ ያሉ አጥቂዎች እርስዎ እንደ ሶፍትዌር መጫን ወይም የግል መረጃዎን (ለምሳሌ፦ የይለፍ ቃላት፣ ስልክ ቁጥሮች ወይም ክሬዲት ካርዶች) አሳልፈው እንዲሰጡ ያሉ አደገኛ ነገር እንዲያደርጉ ሊያታልሉዎት ይችላሉ።</translation>
<translation id="8034522405403831421">ይህ ገጽ በ<ph name="SOURCE_LANGUAGE" /> ነው። ወደ <ph name="TARGET_LANGUAGE" /> ይተርጎም?</translation>
<translation id="8035152190676905274">ብዕር</translation>
+<translation id="8037117624646282037">በቅርቡ ማን ይህን መሣሪያ እንደተጠቀመ</translation>
<translation id="8037357227543935929">ጠይቅ (ነባሪ)</translation>
<translation id="803771048473350947">ፋይል</translation>
<translation id="8041089156583427627">ግብረ መልስ ላክ</translation>
<translation id="8041940743680923270">ሁለንተናዊ ነባሪውን ተጠቀሙ (ጠይቅ)</translation>
<translation id="8042918947222776840">የመውሰጃ ዘዴ ይምረጡ</translation>
<translation id="8057711352706143257">«<ph name="SOFTWARE_NAME" />» በአግባቡ አልተዋቀረም። «<ph name="SOFTWARE_NAME" />»ን ማራገፍ አብዛኛው ጊዜ ችግሩን ይፈታዋል። <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">የእርስዎ መሣሪያ ለሚከተሉት ተዋቅሯል፦</translation>
+<translation id="8066955247577885446">ይቅርታ፣ የሆነ ችግር ተፈጥሯል።</translation>
+<translation id="8074253406171541171">10x13 (የደብዳቤ ፖስታ)</translation>
<translation id="8078141288243656252">በሚሸከርከርበት ጊዜ ማብራራት አይችልም</translation>
<translation id="8079031581361219619">ጣቢያ ዳግም ይጫን?</translation>
<translation id="8088680233425245692">ጽሑፉን ማየት አልተቻለም።</translation>
@@ -1130,11 +1274,12 @@
<translation id="8091372947890762290">ማግበር በአገልጋዩ ላይ በመጠባበቅ ላይ ነው</translation>
<translation id="8092774999298748321">ደማቅ ሐምራዊ</translation>
<translation id="8094917007353911263">እየተጠቀሙበት ያለው አውታረ መረብ <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ን እንዲጎበኙ ሊጠይቅዎት ይችላል።</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">ልክ ያልኾኑት ካርዶች ተወግደዋል</translation>
<translation id="8103161714697287722">የክፍያ ስልት</translation>
<translation id="8118489163946903409">የመክፈያ ዘዴ</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> በ<ph name="ENROLLMENT_DOMAIN" /> የሚተዳደር ነው</translation>
<translation id="8127301229239896662">«<ph name="SOFTWARE_NAME" />» በእርስዎ ኮምፒውተር ወይም አውታረ መረብ ላይ በአግባቡ አልተጫነም። አስተዳዳሪዎ ይህን ችግር እንዲፈታ ይጠይቁ።</translation>
-<translation id="8130693978878176684">ከእንግዲህ ላግዝ አልችልም፣ እባክዎ በራስዎ ይቀጥሉ።</translation>
<translation id="8131740175452115882">አረጋግጥ</translation>
<translation id="8149426793427495338">የእርስዎ ኮምፒውተ ተኝቷል።</translation>
<translation id="8150722005171944719"><ph name="URL" /> ላይ ያለው ፋይል የሚነበብ አይደለም። ተወግዶ፣ ተወስዶ ወይም የፋይል ፍቃዶቹ መዳረሻ እየከለከሉ ሊሆኑ ይችላሉ።</translation>
@@ -1144,8 +1289,11 @@
<translation id="8197543752516192074">ገጽን ተርጉም</translation>
<translation id="8201077131113104583">የማይሰራ የURL ዝማኔ ለቅጥያ ከመታወቂያ «<ph name="EXTENSION_ID" />» ጋር።</translation>
<translation id="8202097416529803614">የትዕዛዝ ማጠቃለያ</translation>
+<translation id="8202370299023114387">ግጭት</translation>
+<translation id="8206978196348664717">Prc4 (የደብዳቤ ፖስታ)</translation>
<translation id="8211406090763984747">ግንኙነት ደኅንነቱ የተጠበቀ ነው</translation>
<translation id="8218327578424803826">የተመደበ መገኛ አካባቢ፦</translation>
+<translation id="8220146938470311105">C7/C6 (የደብዳቤ ፖስታ)</translation>
<translation id="8225771182978767009">ይህን ኮምፒውተር ያቀናበረው ሰው ይህን ጣቢያ ለማገድ መርጧል።</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />፣ <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">ገጹን ማንነት በማያሳውቅ አዲስ ትር ውስጥ ይክፈቱ</translation>
@@ -1157,14 +1305,16 @@
<translation id="825929999321470778">ሁሉንም የተቀመጡ የይለፍ ቃላትን አሳይ</translation>
<translation id="8261506727792406068">ሰርዝ</translation>
<translation id="8267698848189296333">እንደ <ph name="USERNAME" /> በመግባት ላይ</translation>
+<translation id="8278457561961988242">ይህ አሳሽ በ<ph name="ENROLLMENT_DOMAIN" /> የሚተዳደር ነው። የእርስዎ አስተዳዳሪ የአሳሽዎን ውቅረት በርቀት ሊቀይሩት ይችላሉ። በዚህ መሣሪያ ላይ ያለ እንቅስቃሴ እንዲሁም ከChrome ውጭ ሊተዳደር ይችላል። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">ትልቅ-ፎቶ</translation>
<translation id="8286036467436129157">ግባ</translation>
<translation id="8288807391153049143">የእውቅና ማረጋገጫን አሳይ</translation>
<translation id="8289355894181816810">ይሄ ምን ማለት እንደሆነ እርግጠኛ ካልሆኑ የአውታረ መረብ አስተዳዳሪዎን ያግኙ።</translation>
<translation id="8293206222192510085">እልባት ያክሉ</translation>
<translation id="8294431847097064396">ምንጭ</translation>
<translation id="8298115750975731693">እየተጠቀሙበት ያለው Wi-Fi (<ph name="WIFI_NAME" />) <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ን እንዲጎበኙ ሊጠይቅዎት ይችላል።</translation>
+<translation id="8307358339886459768">ትንሽ-ፎቶ</translation>
<translation id="8308427013383895095">በአውታረመረብ ግንኙነት ችግር ምክንያት የትርጉም ስራው ተሰናክሏል።</translation>
-<translation id="8311129316111205805">ክፍለ-ጊዜን ጫን</translation>
<translation id="8332188693563227489">የ<ph name="HOST_NAME" /> መዳረሻ ተከልክሏል</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">በእርስዎ ደህንነት ላይ የሚያመጣቸውን ስጋቶች ከተረዱ አደገኛ ፕሮግራሞቹ ከመወገዳቸው በፊት <ph name="BEGIN_LINK" />ይህን ጣቢያ መጎብኘት<ph name="END_LINK" /> ይችላሉ።</translation>
@@ -1182,7 +1332,6 @@
<translation id="8416694386774425977">የአውታረ መረቡ ውቅረት ልክ ያልሆነ እና ሊመጣ የማይችል ነው።
ተጨማሪ ዝርዝሮች፦
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">መሣሪያ የሚተዳደረው በ<ph name="ENROLLMENT_DOMAIN" /> ነው</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">ለውጥ</translation>
<translation id="8428213095426709021">ቅንብሮች</translation>
@@ -1210,9 +1359,11 @@
<translation id="860043288473659153">የካርድ ያዢ ስም</translation>
<translation id="861775596732816396">መጠን 4</translation>
<translation id="8620436878122366504">የእርስዎ ወላጆች ገና አላጸደቁትም</translation>
+<translation id="8622948367223941507">የህግ-ተጨማሪ</translation>
<translation id="8625384913736129811">ይህን ካርድ ወደዚህ መሣሪያ አስቀምጥ</translation>
<translation id="8663226718884576429">የትዕዛዝ ማጠቃለያ፣ <ph name="TOTAL_LABEL" />፣ ተጨማሪ ዝርዝሮች</translation>
<translation id="8680536109547170164"><ph name="QUERY" />፣ መልስ፣ <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">PRC 16K</translation>
<translation id="8703575177326907206">ከ<ph name="DOMAIN" /> ጋር ያለዎት ግንኙነት አልተመሰጠረም</translation>
<translation id="8718314106902482036">ክፍያ አልተጠናቀቀም</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />፣ <ph name="DESCRIPTION" />፣ የፍለጋ ጥቆማ ሐሳብ</translation>
@@ -1226,6 +1377,7 @@
<translation id="8761567432415473239">Google የጥንቃቄ አሰሳ በቅርብ ጊዜ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ጎጂ ፕሮግርራሞችን አግኝቷል<ph name="END_LINK" />።</translation>
<translation id="8763927697961133303">የዩኤስቢ መሣሪያ</translation>
<translation id="8768895707659403558">የእርስዎን ዕልባቶችን በሁሉም መሣሪያዎችዎ ላይ ለመጠቀም <ph name="SIGN_IN_LINK" />።</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ሰርዝን ድገም</translation>
<translation id="8792621596287649091">የ<ph name="ORG_NAME" /> መለያዎን መዳረሻ ሊያጡ ወይም የማንነት ስርቆት ሊያጋጥመዎት ይችላሉ። Chromium የይለፍ ቃልዎን አሁን እንዲቀይሩ ይመክራል።</translation>
<translation id="8800988563907321413">በአቅራቢያዎ ያሉ የአስተያየት ጥቆማዎች እዚህ ይመጣሉ</translation>
@@ -1236,10 +1388,12 @@
<translation id="885730110891505394">ከGoogle ጋር ማጋራት</translation>
<translation id="8858065207712248076">Chrome የእርስዎን የ<ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> ይለፍ ቃል በሌሎች ጣቢያዎች ላይ ዳግም ከተጠቀሙበት እንደገና እንዲያዋቅሩት ይመክራል።</translation>
<translation id="8866481888320382733">የመምሪያ ቅንብሮችን መተንተን ላይ ስህተት</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">በቅርብ ጊዜ የተዘጉ</translation>
<translation id="8874824191258364635">የሚሰራ የካርድ ቁጥር ያስገቡ</translation>
<translation id="8891727572606052622">ልክ ያልሆነ የተኪ ሁነታ።</translation>
<translation id="8903921497873541725">አጉላ</translation>
+<translation id="890485472659500557">ምሕንድስና-C</translation>
<translation id="8931333241327730545">ይህን ካርድ በእርስዎ የGoogle መለያ ላይ ማስቀመጥ ይፈልጋሉ?</translation>
<translation id="8932102934695377596">የእርስዎ ሰዓት ወደ ኋላ ቀርቷል</translation>
<translation id="893332455753468063">ስም ያክሉ</translation>
@@ -1247,13 +1401,13 @@
<translation id="894185898663964645">የእርስዎ አስተዳዳሪ ብጁ የስር እውቅና ማረጋገጫዎችን አዋቅረዋል፣ እነዚህም አስተዳዳሪው እርስዎ የሚጎበኟቸው የድር ጣቢያዎች ይዘትን እንዲመለከቱ ያስችላቸዋል።</translation>
<translation id="8943282376843390568">ሎሚ ቀለም</translation>
<translation id="8957210676456822347">የተያዥ መግቢያ ፈቀዳ</translation>
+<translation id="8966619695390250636">ይህን ለማለት ፈልገው ነው?</translation>
<translation id="8968766641738584599">ካርድ አስቀምጥ</translation>
<translation id="8971063699422889582">የአገልጋይ እውቅና ማረጋገጫ ጊዜው አልፎበታል።</translation>
<translation id="8975012916872825179">እንደ ስልክ ቁጥሮች፣ ኢሜይል አድራሻዎች እና የመላኪያ አድራሻዎች ያሉ መረጃዎችን ያካትታል</translation>
<translation id="8978053250194585037">Google የጥንቃቄ አሰሳ በቅርቡ በ<ph name="SITE" /> ላይ <ph name="BEGIN_LINK" />ማስገር አግኝቷል<ph name="END_LINK" />። የማስገር ጣቢያዎች እርስዎን ለማታለል ሌሎች ድር ጣቢያዎች እንደሆኑ ያስመስላሉ።</translation>
<translation id="8983003182662520383">Google Payን የሚጠቀሙ የመክፈያ ዘዴዎች እና አድራሻዎች</translation>
<translation id="8987927404178983737">ወር</translation>
-<translation id="8988408250700415532">የሆነ ነገር ተሳስቷል። የእርስዎን ትዕዛዝ በድር ጣቢያው ላይ መቀጠል ይችላሉ።</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ቀጥሎ ያለው ጣቢያ ጎጂ ፕሮግራሙች አሉት</translation>
<translation id="8997023839087525404">አገልጋዩ የእውቅና ማረጋገጫ ግልጽነት መመሪያውን በመጠቀም በይፋ ያልተገለጸ የእውቅና ማረጋገጫን አቅርቧል። ይህ ለአንዳንድ የእውቅና ማረጋገጫዎች ሊታመኑ የሚችሉ መሆናቸውን ለማረጋገጥ እና ከአጥቂዎች ጥበቃ ለማድረግ እንዲቻል አስፈላጊ ነው።</translation>
@@ -1263,6 +1417,7 @@
<translation id="9011424611726486705">የጣቢያ ቅንብሮችን ክፈት</translation>
<translation id="9020200922353704812">የካርድ ማስከፈያ አድራሻ ያስፈልጋል</translation>
<translation id="9020542370529661692">ይህ ገጽ ወደ <ph name="TARGET_LANGUAGE" /> ተተርጉሟል</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(ልክ ያልሆነ)</translation>
<translation id="9035022520814077154">የደህንነት ጥበቃ ስህተት</translation>
<translation id="9038649477754266430">ገጾችን ይበልጥ በፍጥነት ለመጫን የግመታ አገልግሎትን ይጠቀሙ</translation>
@@ -1274,11 +1429,11 @@
<translation id="9065745800631924235">የ<ph name="TEXT" /> ፍለጋ ከታሪክ</translation>
<translation id="9069693763241529744">በቅጥያ ታግዷል</translation>
<translation id="9076283476770535406">ለአዋቂ ብቻ የሚሆን ይዘት ሊኖረው ይችላል</translation>
+<translation id="9076630408993835509">ይህ አሳሽ በኩባንያ ወይም ሌላ ድርጅት አይተዳደርም። በዚህ መሣሪያ ላይ ያለ እንቅስቃሴ ከChrome ውጭ ሊተዳደር ይይችላል። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">ተጨማሪ መረጃ ያስፈልጋል</translation>
<translation id="9080712759204168376">የትዕዛዝ ማጠቃለያ</translation>
<translation id="9103872766612412690"><ph name="SITE" /> የእርስዎን መረጃ ለመጠበቅ በመደበኝነት ምስጠራን ይጠቀማል። Chromium አሁን ከ<ph name="SITE" /> ጋር ለመገናኘት ሲሞክር ድር ጣቢያው ያልተለመዱ እና ትክክል ያልሆኑ ምስክርነቶችን መልሷል። ይህ አንድ አጥቂ <ph name="SITE" />ን አስመስሎ ለመቅረብ ሲሞክር ነው ወይም አንድ የWi-Fi መግቢያ ገጽ ግንኙነቱን ሲቋረጥ ሊከሰት ይችላል። Chromium ማንኛውም የውሂብ ልውውጥ ከመካሄዱ በፊት ግንኙነቱን ስላቋረጠው አሁንም የእርስዎ መረጃ ደህንነት የተጠበቀ ነው።</translation>
<translation id="9106062320799175032">የመክፈያ አድራሻ ያክሉ</translation>
-<translation id="9110718169272311511">በChrome ውስጥ Google ረዳት ከማያ ገጹ ግርጌ አጠገብ ይታያል</translation>
<translation id="9114524666733003316">ካርድን በማረጋገጥ ላይ...</translation>
<translation id="9128870381267983090">ከአውታረ መረብ ጋር ይገናኙ</translation>
<translation id="9137013805542155359">የመጀመሪያውን አሳይ</translation>
@@ -1287,6 +1442,7 @@
<translation id="9148507642005240123">&amp;አርትዕን ቀልብስ</translation>
<translation id="9154194610265714752">የተዘመነ</translation>
<translation id="9157595877708044936">በማዋቀር ላይ…</translation>
+<translation id="9158625974267017556">C6 (የደብዳቤ ፖስታ)</translation>
<translation id="9168814207360376865">የተቀመጡ የመክፈያ ዘዴዎች ካልዎት ጣቢያዎች እንዲፈትሹ ይፍቀዱ</translation>
<translation id="9169664750068251925">ሁልጊዜ በዚህ ጣቢያ ላይ አግድ</translation>
<translation id="9170848237812810038">&amp;ቀልብስ</translation>
@@ -1301,10 +1457,12 @@
<translation id="9219103736887031265">ምስሎች</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ቅጽን አጽዳ</translation>
+<translation id="936474030629450166">ልዕለ-B</translation>
<translation id="936602727769022409">የGoogle መለያዎን መዳረሻ ሊያጡ ይችላሉ። Chromium የይለፍ ቃልዎን አሁኑኑ እንዲቀይሩት ይመክራል። በመለያ እንዲገቡ ይጠየቃሉ።</translation>
<translation id="939736085109172342">አዲስ ዓቃፊ</translation>
<translation id="945855313015696284">ከዚህ በታች ያለውን መረጃ ይፈትሹ እና ማናቸውንም ልክ ያልሆኑ ካርዶች ይሰርዙ</translation>
<translation id="951104842009476243">ተቀባይነት ያላቸው የዴቢት እና የቅድመ-ክፍያ ካርዶች</translation>
+<translation id="958202389743790697">በ<ph name="ORIGIN" /> የደህንነት መመሪያ መሠረት ታግዷል።</translation>
<translation id="962484866189421427">ይህ ይዘት የሆነ ሌላ ነገር እንደሆኑ የሚያስመስሉ አጭበርባሪ መተግበሪያዎችን ወይም እርስዎን ለመከታተል ጥቅም ላይ ሊውል የሚችል ውሂብን የሚሰበስቡ መተግበሪያዎችን ለመጫን ሊሞክር ይችል ይሆናል። <ph name="BEGIN_LINK" />የሆነው ሆኖ አሳይ<ph name="END_LINK" /></translation>
<translation id="969892804517981540">ይፋ ግንባታ</translation>
<translation id="973773823069644502">የማድረሻ አድራሻ ያክሉ</translation>
@@ -1313,6 +1471,7 @@
<translation id="984275831282074731">የመክፈያ ዘዴዎች</translation>
<translation id="985199708454569384">&lt;p&gt;የእርስዎ ኮምፒውተር ወይም የተንቀሳቃሽ መሣሪያ ውሂብና ሰዓት ትክክል ካልሆኑ ይህን ስህተት ያዩታል።&lt;/p&gt;
&lt;p&gt;ስህተቱን ለማስተካከል የመሣሪያዎን ሰዓት ይክፈቱ። ሰዓቱ እና ቀኑ ትክክል መሆኑን ያረጋግጡ።&lt;/p&gt;</translation>
+<translation id="985956168329721395">PRC 16K</translation>
<translation id="988159990683914416">የገንቢዎች ግንባታ</translation>
<translation id="989988560359834682">አድራሻ ያርትዑ</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ar.xtb b/chromium/components/strings/components_strings_ar.xtb
index 9a745884c8b..c573e520e70 100644
--- a/chromium/components/strings/components_strings_ar.xtb
+++ b/chromium/components/strings/components_strings_ar.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
-<translation id="1005145902654145231">تعذّرت إعادة تسمية الجلسة.</translation>
<translation id="1008557486741366299">ليس الآن</translation>
<translation id="1010200102790553230">تحميل الصفحة لاحقًا</translation>
<translation id="1015730422737071372">تقديم تفاصيل إضافية</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">اسم غير معروف</translation>
<translation id="1050038467049342496">إغلاق التطبيقات الأخرى</translation>
<translation id="1055184225775184556">تراجع عن الإ&amp;ضافة</translation>
+<translation id="1056898198331236512">تحذير</translation>
<translation id="1058479211578257048">جارٍ حفظ البطاقات...</translation>
<translation id="10614374240317010">المواقع التي لن تحفظ كلمات المرور أبدًا</translation>
+<translation id="1062160989074299343">‏Prc10 (مغلف)</translation>
<translation id="106701514854093668">الإشارات المرجعية على سطح المكتب</translation>
<translation id="1074497978438210769">غير آمن</translation>
<translation id="1080116354587839789">ملاءمة مع العرض</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">إضافة الاسم الوارد في البطاقة</translation>
<translation id="1089439967362294234">تغيير كلمة المرور</translation>
<translation id="109743633954054152">‏إدارة كلمات المرور في إعدادات Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">قد يكثر ظهور التحذيرات أثناء إجراء مواقع الويب لتحديثات الأمان، لكنّ هذه المسألة ستتحسَّن قريبًا.</translation>
<translation id="1126551341858583091">يمثل الحجم على مساحة التخزين المحلية <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">ذاكرة التخزين المؤقت للسياسة بحالة جيدة</translation>
+<translation id="1131264053432022307">الصورة التي نسختها</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885">أغلق <ph name="HOST_NAME" /> الاتصال على نحو غير متوقع.</translation>
<translation id="1161325031994447685">‏إعادة الاتصال بـ Wi-Fi</translation>
<translation id="1165039591588034296">خطأ</translation>
-<translation id="1173894706177603556">إعادة تسمية</translation>
<translation id="1175364870820465910">ط&amp;باعة...</translation>
<translation id="1181037720776840403">إزالة</translation>
<translation id="1197088940767939838">برتقالي</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">اسم الجهاز</translation>
<translation id="124116460088058876">مزيد من اللغات</translation>
<translation id="1250759482327835220">‏للدفع بشكلٍ أسرع في المرة القادمة، يمكنك حفظ البطاقة والاسم وعنوان إرسال الفواتير في حسابك على Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />، <ph name="TYPE_2" /> (تمت المزامنة)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">صيغ سطر الأوامر</translation>
<translation id="129553762522093515">المغلقة حديثًا</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />جرّب محو ملفات تعريف الارتباط<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">الجلسة المختارة غير موجودة.</translation>
+<translation id="1320233736580025032">‏Prc1 (مغلف)</translation>
+<translation id="132301787627749051">البحث عن صورة الحافظة</translation>
<translation id="1323433172918577554">إظهار مزيد من الأقسام</translation>
<translation id="132390688737681464">حفظ العناوين وملؤها</translation>
<translation id="1333989956347591814">قد يظل <ph name="BEGIN_EMPHASIS" />نشاطك مرئيًا<ph name="END_EMPHASIS" /> للجهات التالية:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">عنوان الاستلام</translation>
<translation id="1348198688976932919">يحتوي موقع الويب المقصود على تطبيقات خطيرة</translation>
<translation id="1348779747280417563">تأكيد الاسم</translation>
+<translation id="1357195169723583938">الأشخاص الذين استخدموا الجهاز مؤخرًا ووقت استخدمه</translation>
+<translation id="1364822246244961190">يتم حظر هذه السياسة وسيتم تجاهل قيمتها.</translation>
<translation id="1374468813861204354">اقتراحات</translation>
+<translation id="1374692235857187091">‏Index-4x6 (بطاقة بريدية)</translation>
<translation id="1375198122581997741">معلومات عن الإصدار</translation>
<translation id="1376836354785490390">إظهار أقسام أقل</translation>
<translation id="1377321085342047638">رقم البطاقة</translation>
<translation id="138218114945450791">أزرق فاتح</translation>
+<translation id="1382194467192730611">‏سماح المشرف بجهاز USB</translation>
<translation id="139305205187523129">لم يرسل <ph name="HOST_NAME" /> أي بيانات.</translation>
+<translation id="140316286225361634">طلب الموقع الإلكتروني <ph name="ORIGIN" /> تطبيق سياسة الأمان
+ على جميع طلباته، وتعتبر هذه السياسة الموقع الإلكتروني
+ غير آمن حاليًا.</translation>
<translation id="1405567553485452995">أخضر فاتح</translation>
<translation id="1407135791313364759">فتح الكل</translation>
<translation id="1413809658975081374">خطأ في الخصوصية</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">نعم</translation>
<translation id="1430915738399379752">طباعة</translation>
<translation id="1455413310270022028">ممحاة</translation>
+<translation id="1463543813647160932">7x5</translation>
+<translation id="1472675084647422956">عرض المزيد</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">اختيار عنوان الشحن</translation>
+<translation id="1492194039220927094">إرسال السياسات:</translation>
<translation id="1501859676467574491">‏عرض البطاقات من حسابك على Google</translation>
-<translation id="1506687042165942984">عرض نسخة محفوظة (أي معروف أنها منتهية) من هذه الصفحة.</translation>
<translation id="1507202001669085618">‏&lt;p&gt;سيظهر هذا الخطأ عند استخدام بوابة شبكة Wi-Fi تتطلّب تسجيل الدخول قبل الاتصال بالإنترنت.&lt;/p&gt;
&lt;p&gt;لإصلاح الخطأ، انقر على &lt;strong&gt;"اتصال"&lt;/strong&gt; في الصفحة التي تحاول فتحها.&lt;/p&gt;</translation>
<translation id="1517433312004943670">رقم الهاتف مطلوب</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">تاريخ الإصدار</translation>
<translation id="1521655867290435174">‏جداول بيانات Google</translation>
<translation id="1527263332363067270">في انتظار الاتصال بالإنترنت…</translation>
+<translation id="1529521330346880926">‏10x15 (مغلف)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">تعرض هذه الصفحة</translation>
<translation id="153384715582417236">هذا كل شيء الآن</translation>
<translation id="154408704832528245">اختيار عنوان التسليم للمستخدم</translation>
<translation id="1549470594296187301">‏يجب تفعيل JavaScript لاستخدام هذه الميزة.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">إدخال تاريخ انتهاء الصلاحية</translation>
<translation id="1581080074034554886">‏رمز التحقق من البطاقة (CVC)</translation>
<translation id="1583429793053364125">حدث خطأ ما أثناء عرض صفحة الويب هذه.</translation>
<translation id="1592005682883173041">الوصول إلى البيانات المحلية</translation>
<translation id="1594030484168838125">اختيار</translation>
<translation id="161042844686301425">سماوي</translation>
-<translation id="1618822247301510817">الصورة التي نسختها</translation>
<translation id="1620510694547887537">الكاميرا</translation>
<translation id="1623104350909869708">منع هذه الصفحة من إنشاء مربعات حوار إضافية.</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">إنهاء الجلسة</translation>
<translation id="1639239467298939599">جارٍ التحميل.</translation>
<translation id="1640180200866533862">سياسات المستخدم</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">‏يستخدم <ph name="SITE" /> التشفير عادة لحماية معلوماتك. عندما حاول Google Chrome الاتصال بموقع <ph name="SITE" /> هذه المرة، أرجَع موقع الويب بيانات اعتماد غير عادية وغير صحيحة. وقد يحدث هذا عندما يحاول أحد المهاجمين التظاهر بأنه موقع <ph name="SITE" />، أو إذا قاطعت شاشة تسجيل دخول Wi-Fi الاتصال. ولكن لا تزال معلوماتك آمنة نظرًا لأن Google Chrome أوقَف الاتصال قبل تبادل أي بيانات.</translation>
<translation id="168841957122794586">تحتوي شهادة الخادم على مفتاح تشفير ضعيف.</translation>
<translation id="1697532407822776718">أنت الآن على أتم استعداد.</translation>
+<translation id="1703835215927279855">خطاب</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="1715874602234207">F</translation>
<translation id="1718029547804390981">حجم المستند كبير جدًا بحيث تتعذّر إضافة تعليق توضيحي إليه</translation>
<translation id="1721312023322545264">أنت بحاجة لإذن من <ph name="NAME" /> لزيارة هذا الموقع</translation>
<translation id="1721424275792716183">* هناك حقل مطلوب</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">جرّب الاتصال بمشرف النظام.</translation>
<translation id="1740951997222943430">أدخِل شهر انتهاء صلاحية صحيح</translation>
<translation id="1743520634839655729">‏للدفع بشكلٍ أسرع في المرة القادمة، يمكنك حفظ البطاقة والاسم وعنوان إرسال الفواتير في حسابك على Google وفي هذا الجهاز.</translation>
+<translation id="1745880797583122200">إدارة متصفِّحك</translation>
<translation id="17513872634828108">علامات التبويب المفتوحة</translation>
<translation id="1753706481035618306">رقم الصفحة</translation>
<translation id="1763864636252898013">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من خلال نظام تشغيل جهازك. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">يُرجى تحديث عبارة مرور المزامنة.</translation>
<translation id="1787142507584202372">تظهر علامات التبويب المفتوحة هنا</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">اسم حامل البطاقة</translation>
<translation id="1821930232296380041">طلب غير صالح، أو معلمات طلب غير صالحة</translation>
+<translation id="1822540298136254167">مواقع الويب التي تزورها والوقت المُستغرق في تصفُّحها</translation>
<translation id="1826516787628120939">حساب شيكات</translation>
<translation id="1834321415901700177">يحتوي هذا الموقع على برامج ضارة</translation>
<translation id="1839551713262164453">لقد تعذّر التحقق من قيم السياسة مع ظهور أخطاء.</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">‏محو بيانات سجلّ التصفُّح على Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{وتطبيق آخر}zero{و# تطبيق آخر}two{وتطبيقان (#) آخران}few{و# تطبيقات أخرى}many{و# تطبيقًا آخر}other{و# تطبيق آخر}}</translation>
<translation id="2003709556000175978">إعادة تعيين كلمة المرورالآن</translation>
+<translation id="20053308747750172">لقد طلب الخادم الذي تنتقل إليه، <ph name="ORIGIN" />، أن
+ يتم تطبيق سياسة الأمان على جميع الطلبات المقدَّمة إليه. ولكن تم عرض
+ سياسة غير صالحة الآن، التي تمنع المتصفَّح من
+ توصيل الطلب لموقع <ph name="SITE" />.</translation>
<translation id="2025186561304664664">تم تعيين الخادم الوكيل على التهيئة التلقائية.</translation>
<translation id="2030481566774242610">هل تقصد <ph name="LINK" />؟</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />التحقق من الخادم الوكيل والجدار الناري<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">القسم</translation>
<translation id="2102134110707549001">اقتراح كلمة مرور قوية…</translation>
<translation id="2108755909498034140">إعادة تشغيل جهاز الكمبيوتر</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">البطاقة</translation>
<translation id="2114841414352855701">تم تجاهلها نظرًا لتجاوزها بواسطة <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">الإشارات المرجعية على الجوّال</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">تعديل البطاقة</translation>
<translation id="2166049586286450108">الوصول الكامل للمشرف</translation>
<translation id="2166378884831602661">لا يمكن لموقع الويب هذا توفير اتصال آمن</translation>
+<translation id="2169984857010174799">‏Kaku2 (مغلف)</translation>
<translation id="2181821976797666341">السياسات</translation>
<translation id="2183608646556468874">رقم الهاتف</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{عنوان واحد}zero{# عنوان}two{عنوانان (#)}few{# عناوين}many{# عنوانًا}other{# عنوان}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">رقم الهاتف</translation>
<translation id="2283340219607151381">حفظ العناوين وملؤها</translation>
<translation id="2292556288342944218">تم حظر دخولك إلى الإنترنت</translation>
+<translation id="2294558542833290837">الرابط الذي فتحته أصلاً غير معتاد</translation>
+<translation id="2297722699537546652">‏B5 (مغلف)</translation>
+<translation id="2310021320168182093">‏Chou2 (مغلف)</translation>
<translation id="2316887270356262533">سيتم توفير أقل من 1 ميغابايت. وقد يتم تحميل بعض المواقع بشكل أبطأ عند زيارتها في المرة القادمة.</translation>
<translation id="2317259163369394535">يتطلَّب <ph name="DOMAIN" /> اسم مستخدم وكلمة مرور.</translation>
<translation id="2317583587496011522">يتم قبول بطاقات السحب الآلي.</translation>
<translation id="2330137317877982892">تنتهي صلاحية <ph name="CREDIT_CARD" /> في <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">يتم التحكّم في الإعداد من قبل المشرف</translation>
+<translation id="2346319942568447007">الصورة التي نسختها</translation>
<translation id="2349790679044093737">‏جلسة VR نشطة</translation>
<translation id="2354001756790975382">الإشارات الأخرى</translation>
<translation id="2354430244986887761">‏عثر ‏‫التصفح الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />على تطبيقات ضارة<ph name="END_LINK" /> في <ph name="SITE" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">لم يتم تحميل تقرير الأعطال الذي تم الحصول عليه في <ph name="CRASH_TIME" /></translation>
<translation id="2367567093518048410">المستوى</translation>
<translation id="2378238891085281592">الانتقال إلى التصفّح المتخفي</translation>
+<translation id="2380886658946992094">قانوني</translation>
<translation id="2384307209577226199">السياسة تلقائية في المؤسسة ويمكن إلغاؤها</translation>
<translation id="2386255080630008482">تم إبطال شهادة الخادم.</translation>
<translation id="2392959068659972793">عرض السياسات التي لم يتم تعيين قيم لها</translation>
<translation id="239429038616798445">طريقة الشحن هذه غير متاحة، جرِّب طريقة أخرى.</translation>
<translation id="2396249848217231973">تراجع عن الحذ&amp;ف</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان ربما تم إلغاء صلاحيتها. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
+<translation id="2418081434543109369">لقد طلب الخادم الذي تنتقل إليه، <ph name="ORIGIN" />، أن
+ يتم تطبيق سياسة الأمان على جميع الطلبات المقدَّمة إليه. لكن
+ تعذّر الآن عرض سياسة تمنع المتصفِّح من توصيل
+ طلبك لموقع <ph name="SITE" />.</translation>
<translation id="244665789865330679">يدير <ph name="ENROLLMENT_DOMAIN" /> جهازك وحسابك. وهذا يعني أنه قد يضبط مشرفك جهازك وحسابك عن بُعد.</translation>
<translation id="2463193859425327265">تغيير الصفحة الرئيسية</translation>
<translation id="2463739503403862330">ملء</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">اختيار طريقة التسليم للمستخدم</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />تشغيل بيانات تشخيص الشبكة<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ترجم هذه الصفحة</translation>
<translation id="2479410451996844060">‏عنوان URL للبحث غير صالح.</translation>
<translation id="2482878487686419369">الإشعارات</translation>
<translation id="248348093745724435">سياسات الأجهزة</translation>
+<translation id="2485387744899240041">أسماء المستخدمين لجهازك ومتصفِّحك</translation>
<translation id="2491120439723279231">تحتوي شهادة الخادم على أخطاء.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">‏محلل JSON اللغوي</translation>
<translation id="2495093607237746763">‏عند وضع علامة على هذا الخيار، سيخزّن Chromium نسخة من بطاقتك على هذا الجهاز لتعبئة النماذج بشكل أسرع.</translation>
<translation id="2498091847651709837">فحص بطاقة جديدة</translation>
<translation id="2501278716633472235">الرجوع</translation>
<translation id="2503184589641749290">بطاقات السحب الآلي وبطاقات الدفع المسبق المقبولة</translation>
<translation id="2515629240566999685">التحقّق من اتصال الإنترنت في منطقتك</translation>
-<translation id="2516852381693169964">بحث على <ph name="SEARCH_ENGINE" /> عن صورة</translation>
<translation id="2523886232349826891">سيتم حفظ البطاقة على هذا الجهاز فقط</translation>
<translation id="2524461107774643265">إضافة مزيد من المعلومات</translation>
<translation id="2536110899380797252">إضافة عنوان</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">رقم تعريف واجهة برمجة التطبيقات الدليل:</translation>
<translation id="2597378329261239068">هذا المستند محمي بكلمة المرور. يُرجى إدخال كلمة مرور.</translation>
<translation id="2609632851001447353">الاختلافات</translation>
+<translation id="2618023639789766142">‏C10 (مغلف)</translation>
<translation id="2625385379895617796">توقيت ساعتك متقدم عن الوقت الحالي</translation>
<translation id="2634124572758952069">‏تعذّر العثور على عنوان IP لخادم <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">الحالة:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">إغلاق علامات التبويب والتطبيقات الأخرى</translation>
<translation id="267371737713284912">اضغط على <ph name="MODIFIER_KEY_DESCRIPTION" /> للتراجع</translation>
<translation id="2674170444375937751">هل تريد فعلًا حذف هذه الصفحات من السجل؟</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">الخروج</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">البطاقات المقبولة</translation>
<translation id="2702801445560668637">قائمة القراءة</translation>
<translation id="2704283930420550640">القيمة لا تطابق التنسيق.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">إزالة العناصر المحددة</translation>
<translation id="277133753123645258">طريقة الشحن</translation>
<translation id="277499241957683684">سجِلّ الجهاز مفقود</translation>
-<translation id="2781030394888168909">‏تصدير نظام التشغيل MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">تمت إعادة تعيين الاتصال.</translation>
<translation id="2788784517760473862">بطاقات الائتمان المقبولة</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">تم تشفير الاتصال ومصادقته باستخدام <ph name="CIPHER" />، ويستخدم <ph name="KX" /> كآلية التبادل الرئيسية.</translation>
<translation id="2835170189407361413">محو النموذج</translation>
<translation id="2847118875340931228">فتح نافذة التصفُّح المتخفي</translation>
+<translation id="2850739647070081192">دعوة (مغلف)</translation>
<translation id="2851634818064021665">يلزمك الحصول على إذن لزيارة هذا الموقع</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">هل تريد حفظ البطاقة؟</translation>
<translation id="2903493209154104877">العناوين</translation>
<translation id="290376772003165898">أليست الصفحة باللغة <ph name="LANGUAGE" />؟</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">طريقة التسليم</translation>
<translation id="2928905813689894207">عنوان إرسال الفواتير</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{<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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان من <ph name="DOMAIN2" />. وربما سبب ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="2948083400971632585">يمكنك إيقاف أي خوادم وكيلة تمت تهيئتها لاتصال من صفحة الإعدادات.</translation>
<translation id="2955913368246107853">إغلاق شريط البحث</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">‏You4 (مغلف)</translation>
<translation id="3024663005179499861">نوع السياسة غير صحيح</translation>
<translation id="3037605927509011580">عذرًا!</translation>
<translation id="3041612393474885105">معلومات الشهادة</translation>
+<translation id="3060227939791841287">‏C9 (مغلف)</translation>
<translation id="3064966200440839136">ستتم مغادرة وضع التصفح المتخفي للدفع عبر تطبيق خارجي. هل تريد المتابعة؟</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{بدون}=1{كلمة مرور واحدة}two{كلمتا مرور (#)}few{# كلمات مرور}many{# كلمة مرور}other{# كلمة مرور}}</translation>
+<translation id="3095940652251934233">كشف</translation>
<translation id="3096100844101284527">إضافة عنوان الاستلام من المستخدم</translation>
<translation id="3105172416063519923">رقم تعريف الأصل:</translation>
<translation id="3109728660330352905">ليس لديك إذن بعرض هذه الصفحة.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> على <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">إلغاء الدفع</translation>
<translation id="3207960819495026254">تمت إضافتها إلى الإشارات المرجعية.</translation>
-<translation id="3209375525920864198">يُرجى إدخال اسم صالح للجلسة.</translation>
+<translation id="321912867715453276">تحذير: يتوفَّر أكثر من مصدر للسياسة، لكن القيم هي نفسها.</translation>
<translation id="3225919329040284222">قدم الخادم شهادة لا تتطابق مع التوقعات المضمّنة. تم تضمين هذه التوقعات للحصول على مواقع ويب موثوقة وآمنة جدًا لتوفير الحماية لك.</translation>
<translation id="3226128629678568754">اضغط على زر إعادة التحميل لإعادة إرسال البيانات المطلوبة لتحميل الصفحة.</translation>
<translation id="3227137524299004712">الميكروفون</translation>
<translation id="3228969707346345236">تعذّرت الترجمة لأن الصفحة باللغة <ph name="LANGUAGE" /> فعلاً.</translation>
+<translation id="3229041911291329567">معلومات الإصدار حول جهازك ومتصفِّحك</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">إضافة الاسم الوارد في البطاقة</translation>
<translation id="3287510313208355388">التنزيل عند الاتصال بالإنترنت</translation>
<translation id="3293642807462928945">مزيد من المعلومات عن سياسة <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">لم يتم العثور على أي نتائج بحث</translation>
-<translation id="3305707030755673451">تم تشفير بياناتك باستخدام عبارة مرور المزامنة في <ph name="TIME" />. أدخلها لبدء المزامنة.</translation>
<translation id="3320021301628644560">إضافة عنوان إرسال الفواتير</translation>
<translation id="3324983252691184275">قرمزي</translation>
<translation id="3338095232262050444">آمن</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">إعادة الت&amp;حرير</translation>
<translation id="342781501876943858">‏يُوصي Chromium بإعادة تحديد كلمة المرور في حال إعادة استخدامها في مواقع ويب أخرى.</translation>
<translation id="3431636764301398940">حفظ هذه البطاقة إلى هذا الجهاز</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">أوقف مالك هذا الجهاز تشغيل لعبة الديناصور.</translation>
<translation id="3447884698081792621">عرض الشهادة (من إصدار <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">الفاصل الزمني للجلب:</translation>
+<translation id="3456231139987291353">‏Number-11 (مغلف)</translation>
<translation id="3461824795358126837">أداة تمييز</translation>
<translation id="3462200631372590220">الإخفاء (خيار متقدم)</translation>
<translation id="3467763166455606212">اسم حامل البطاقة مطلوب</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">يتم قبول بطاقات الائتمان وبطاقات الدفع المسبق.</translation>
<translation id="3582930987043644930">إضافة اسم</translation>
<translation id="3583757800736429874">إ&amp;عادة النقل</translation>
+<translation id="35866233670761917">لا يطّلع المشرفون على محتوى مواقع الويب التي تزورها.</translation>
<translation id="3586931643579894722">إخفاء التفاصيل</translation>
+<translation id="3592413004129370115">‏Italian (مغلف)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />، و<ph name="DOMAIN" />، و<ph name="TIME" /></translation>
<translation id="3614103345592970299">الحجم 2</translation>
<translation id="3615877443314183785">أدخِل تاريخ انتهاء صلاحية صحيحًا</translation>
<translation id="36224234498066874">محو بيانات التصفّح...</translation>
<translation id="362276910939193118">عرض السجلّ بكامله</translation>
-<translation id="3623476034248543066">عرض القيمة</translation>
<translation id="3630155396527302611">إذا تم بالفعل إدراج صفحة الويب كبرنامج مسموح له بالدخول إلى الشبكة، فجرّب
إزالتها من القائمة وإضافتها مرةً أخرى.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">تم التحقق بنجاح</translation>
<translation id="3655670868607891010">إذا تكرّر هذا الأمر، ننصحك بالاطّلاع على هذه <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">التعديل</translation>
<translation id="366077651725703012">تحديث بطاقة الائتمان</translation>
<translation id="3676592649209844519">معرِّف الجهاز:</translation>
+<translation id="3677008721441257057">‏هل كنت تقصد &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;؟</translation>
<translation id="3678029195006412963">تعذر توقيع الطلب</translation>
<translation id="3678529606614285348">‏يمكنك فتح الصفحة في نافذة جديدة للتصفح المتخفي (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">تم تسجيل تقرير الأعطال في <ph name="CRASH_TIME" />، وتم تحميله في <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">قد تتطلب الشبكة التي تستخدمها زيارة صفحة تسجيل الدخول.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">جارٍ التحميل...</translation>
+<translation id="3709599264800900598">النص الذي نسخته</translation>
<translation id="3712624925041724820">التراخيص مستنفذة</translation>
<translation id="3714780639079136834">‏تشغيل بيانات شبكة الجوّال أو Wi-Fi</translation>
<translation id="3715597595485130451">‏الاتصال بـ Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />التحقق من تهيئة الخادم الوكيل والجدار الناري ونظام أسماء النطاقات<ph name="END_LINK" /></translation>
<translation id="372429172604983730">تتضمن التطبيقات التي يمكن أن تسبب ذلك الخطأ برنامج مكافحة الفيروسات والجدار الناري وبرنامج تصفية الويب أو برنامج الخادم الوكيل.</translation>
+<translation id="373042150751172459">‏B4 (مغلف)</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="3745099705178523657">‏بعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حسابك على Google مع هذا الموقع الإلكتروني.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">تنتهي في <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">الحجم 16</translation>
+<translation id="3797522431967816232">‏Prc3 (مغلف)</translation>
<translation id="3807873520724684969">تم حظر المحتوى الضار.</translation>
<translation id="3810973564298564668">إدارة محرّكات البحث</translation>
<translation id="382518646247711829">إذا كنت تستخدم خادمًا وكيلاً...</translation>
<translation id="3828924085048779000">غير مسموح باستخدام عبارة مرور فارغة.</translation>
+<translation id="3831915413245941253">ثبّت <ph name="ENROLLMENT_DOMAIN" /> الإضافات للوظائف الإضافية. يمكن للإضافات الوصول إلى بعض بياناتك.</translation>
<translation id="385051799172605136">الرجوع إلى الوراء</translation>
<translation id="3858027520442213535">تحديث التاريخ والوقت</translation>
<translation id="3884278016824448484">معرف جهاز متضارب</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">تمّ إرسال طلبك للدخول إلى هذا الموقع إلى <ph name="NAME" /></translation>
<translation id="3890664840433101773">إضافة بريد إلكتروني</translation>
<translation id="3901925938762663762">انتهت صلاحية البطاقة</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">السؤال دائمًا على موقع الويب هذا</translation>
<translation id="3949571496842715403">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />؛ بل إن شهادة الأمان التابعة له لا تُحدّد الأسماء البديلة للمضيفات. وربما يكون السبب في ذلك وجود خطأ في التهيئة أو اعتراض أحد المهاجمين للاتصال.</translation>
@@ -491,11 +549,13 @@
<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="3984550557525787191">اسم الجلسة هذا موجود من قبل.</translation>
<translation id="3987940399970879459">أقل من ميغابايت واحد</translation>
+<translation id="4008849406247176967">تحذير: يتوفَّر أكثر من مصدر واحد يتضمّن قيمًا متضاربة لهذه السياسة.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{صفحة ويب واحدة مجاورة}zero{# صفحات ويب مجاورة}two{صفحتا ويب (#) مجاورتان}few{# صفحات ويب مجاورة}many{# صفحة ويب مجاورة}other{# صفحة ويب مجاورة}}</translation>
<translation id="4030383055268325496">تراجع عن الإ&amp;ضافة</translation>
+<translation id="4032320456957708163">إدارة متصفِّحك من خلال <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">المفتاح "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">‏C1 (مغلف)</translation>
<translation id="4067947977115446013">إضافة عنوان صالح</translation>
<translation id="4072486802667267160">حدث خطأ أثناء معالجة طلبك. يُرجى إعادة المحاولة.</translation>
<translation id="4075732493274867456">لا يدعم كل من العميل والخادم مجموعة تشفير أو إصدار بروتوكول طبقة المقابس الآمنة الشائع.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">أرجواني</translation>
<translation id="4165986682804962316">إعدادات المواقع</translation>
<translation id="4171400957073367226">توقيع تحقق سيئ</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{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="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">إ&amp;عادة النقل</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />التحقق من عمليات تهيئة الجدار الناري وبرامج مكافحة الفيروسات<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">‏7x9 (مغلف)</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="4221630205957821124">‏&lt;h4&gt;الخطوة 1: تسجيل الدخول إلى البوابة&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">إعادة تعيين كلمة المرور</translation>
<translation id="4280429058323657511">، تاريخ انتهاء الصلاحية <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{‏تم حفظ هذه البطاقة في حسابك على Google}zero{‏تم حفظ هذه البطاقات في حسابك على Google}two{‏تم حفظ هاتين البطاقتين في حسابك على Google}few{‏تم حفظ هذه البطاقات في حسابك على Google}many{‏تم حفظ هذه البطاقات في حسابك على Google}other{‏تم حفظ هذه البطاقات في حسابك على Google}}</translation>
+<translation id="42981349822642051">توسيع</translation>
+<translation id="4302965934281694568">‏Chou3 (مغلف)</translation>
<translation id="4305817255990598646">تبديل</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">حظر (تلقائي)</translation>
+<translation id="4318566738941496689">اسم جهازك وعنوان الشبكة</translation>
<translation id="4325863107915753736">تعذّر العثور على المقالة</translation>
<translation id="4326324639298822553">تحقق من تاريخ انتهاء الصلاحية وأعِد المحاولة مرة أخرى</translation>
<translation id="4331708818696583467">غير آمن</translation>
<translation id="4340982228985273705">‏لا يتم رصد جهاز الكمبيوتر هذا كمؤسسة مُدارة حتى تتمكن السياسة فقط من التثبيت التلقائي للإضافات التي تمت استضافتها في سوق Chrome الإلكتروني. ويكون عنوان URL للتحديث في سوق Chrome الإلكتروني هو "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">بطاقات الائتمان المقبولة</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">قد يحاول المهاجمون الموجودون على هذا الموقع تثبيت برامج خطيرة على الكمبيوتر التابع لك تسرق معلوماتك أو تحذفها (على سبيل المثال، الصور وكلمات المرور والرسائل وبطاقات الائتمان).</translation>
<translation id="4358461427845829800">إدارة طرق الدفع...</translation>
+<translation id="4367563149485757821">‏Number-12 (مغلف)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">القيمة <ph name="VALUE_TYPE" /> المتوقعة.</translation>
<translation id="4377125064752653719">لقد حاولت الوصول إلى <ph name="DOMAIN" />، ولكن جهة إصدار الشهادة التي قدمها الخادم قد أبطلت الشهادة. وهذا يعني أن بيانات اعتماد الأمان التي قدمها الخادم يجب عدم الوثوق بها مطلقًا. فقد تكون على اتصال بأحد المهاجمين.</translation>
<translation id="4378154925671717803">هاتف</translation>
<translation id="4406896451731180161">نتائج البحث</translation>
-<translation id="4406972042435603828">ثبّت المشرفون الإضافات التي تتضمّن إمكانات فعَّالة.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> من ملفات تعريف الارتباط</translation>
<translation id="4415426530740016218">عنوان الاستلام</translation>
<translation id="4424024547088906515">‏هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان غير موثوقة من قبل Chrome. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض الاتصال.</translation>
+<translation id="443121186588148776">منفذ تسلسلي</translation>
<translation id="4432688616882109544">لم يقبل <ph name="HOST_NAME" /> شهادة تسجيل الدخول أو من المحتمل ألا يكون قد تم تقديم واحدة.</translation>
<translation id="4434045419905280838">النوافذ المنبثقة وإعادة التوجيه</translation>
+<translation id="4435702339979719576">بطاقة بريدية)</translation>
<translation id="443673843213245140">تم إيقاف استخدام الخادم الوكيل ولكن تم تحديد تهيئة صريحة للخادم الوكيل.</translation>
<translation id="445100540951337728">بطاقات السحب الآلي المقبولة</translation>
+<translation id="4466881336512663640">سيتم فقدان تغييرات النموذج. هل تريد فعلاً المتابعة؟</translation>
<translation id="4482953324121162758">لن تتم ترجمة هذا الموقع.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">‏عنوان URL غير صحيح. يجب أن يحتوي عنوان URL على نظام قياسي، مثل http://example.com أو https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">خطأ في عملية التحقق: <ph name="VALIDATION_ERROR" />.</translation>
<translation id="4506599922270137252">الاتصال بمشرف النظام</translation>
<translation id="450710068430902550">المشاركة مع المشرف</translation>
+<translation id="4510487217173779431">‏Chou4 (مغلف)</translation>
<translation id="4515275063822566619">‏يتم أخذ البطاقات والعناوين من Chrome وحسابك على Google (<ph name="ACCOUNT_EMAIL" />)، ويمكنك إدارتها في <ph name="BEGIN_LINK" />الإعدادات<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">‏Comm-10 (مغلف)</translation>
<translation id="4522570452068850558">التفاصيل</translation>
<translation id="4524805452350978254">إدارة البطاقات</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">الفلاش</translation>
<translation id="4558551763791394412">جرّب إيقاف الإضافات.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">التسليم</translation>
+<translation id="4579056131138995126">شخصي (مغلف)</translation>
<translation id="4582204425268416675">إزالة البطاقة</translation>
<translation id="4587425331216688090">‏هل تريد إزالة العنوان من Chrome؟</translation>
<translation id="4592951414987517459">يتم ترميز اتصالك بالنطاق <ph name="DOMAIN" /> باستخدام مجموعة تشفير حديثة.</translation>
<translation id="4594403342090139922">تراجع عن الحذ&amp;ف</translation>
<translation id="4597348597567598915">الحجم 8</translation>
+<translation id="4600854749408232102">‏C6/C5 (مغلف)</translation>
<translation id="4646534391647090355">الانتقال الآن</translation>
<translation id="4668929960204016307">،</translation>
<translation id="467662567472608290">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان تحتوي على أخطاء. وربما يكون السبب في ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
<translation id="467809019005607715">‏العروض التقديمية من Google</translation>
<translation id="4690462567478992370">التوقف عن استخدام شهادة غير صالحة</translation>
+<translation id="4691835149146451662">‏Architecture-A (مغلف)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" />‏ <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">تم قطع اتصالك</translation>
<translation id="471880041731876836">ليس لديك إذن لزيارة هذا الموقع</translation>
<translation id="4722547256916164131">‏<ph name="BEGIN_LINK" />تشغيل بيانات تشخيص شبكة Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">إعادة تحميل السياسات</translation>
<translation id="4728558894243024398">النظام الأساسي</translation>
+<translation id="4731967714531604179">‏Prc2 (مغلف)</translation>
<translation id="4736825316280949806">‏إعادة تشغيل Chromium</translation>
<translation id="473775607612524610">تحديث</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> اقتراحات البحث</translation>
<translation id="4742407542027196863">إدارة كلمات المرور…</translation>
<translation id="4744603770635761495">المسار التنفيذي</translation>
+<translation id="4746351372139058112">الرسائل</translation>
<translation id="4750917950439032686">ستكون معلوماتك (مثل كلمات المرور أو أرقام بطاقة الائتمان) خاصة عند إرسالها إلى هذا الموقع.</translation>
<translation id="4756388243121344051">ال&amp;سجل</translation>
<translation id="4758311279753947758">إضافة معلومات الاتصال</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">قد تكون صفحة الويب على العنوان <ph name="URL" /> غير متاحة مؤقتًا أو قد يكون تم نقلها نهائيًا إلى عنوان ويب جديد.</translation>
<translation id="4771973620359291008">حدث خطأ غير محدّد.</translation>
<translation id="4785689107224900852">التبديل إلى علامة التبويب هذه</translation>
-<translation id="4792143361752574037">حدثت مشكلة أثناء الوصول إلى ملفات الجلسة. ويتم حاليًا إيقاف الحفظ إلى القرص. يُرجى إعادة تحميل الصفحة للمحاولة مرة أخرى.</translation>
<translation id="4798078619018708837">‏يمكنك إدخال تاريخ انتهاء الصلاحية ورمز التحقُّق من البطاقة (CVC) لبطاقة <ph name="CREDIT_CARD" /> لتحديث تفاصيلها. وبعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حسابك على Google مع هذا الموقع الإلكتروني.</translation>
<translation id="4800132727771399293">‏تحقق من تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) وأعد المحاولة مرة أخرى.</translation>
+<translation id="480334179571489655">خطأ في سياسة المصدر</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">فتح</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">لا نتائج</translation>
<translation id="4950898438188848926">‏زر التبديل بين علامات التبويب، اضغط على Enter للتبديل إلى علامة التبويب المفتوحة هذه <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">إجراءات</translation>
-<translation id="495832697253704892">إعداد التقارير الخاصة بالإضافات</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">توسيع القائمة</translation>
<translation id="4974590756084640048">إعادة تفعيل التحذيرات</translation>
+<translation id="4984339528288761049">‏Prc5 (مغلف)</translation>
<translation id="4989163558385430922">عرض الكل</translation>
<translation id="4989809363548539747">هذا المكوِّن الإضافي غير مدعوم</translation>
-<translation id="4996230189582812866">إعداد التقارير</translation>
<translation id="5002932099480077015">‏إذا تم التمكين، سيخزن Chrome نسخة من بطاقتك على هذا الجهاز لملء النموذج بشكل أسرع.</translation>
-<translation id="5014174725590676422">‏يتم عرض شاشة التشغيل الأولى "لمساعد Google" على Chrome</translation>
<translation id="5015510746216210676">اسم الجهاز:</translation>
+<translation id="5017554619425969104">النص الذي نسخته</translation>
<translation id="5018422839182700155">يتعذّر فتح هذه الصفحة</translation>
<translation id="5019198164206649151">التخزين المساعد في حالة سيئة</translation>
<translation id="5023310440958281426">التحقق من سياسات المشرف</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">السياق المحلي <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">سماح</translation>
<translation id="5040262127954254034">الخصوصية</translation>
+<translation id="5043480802608081735">الرابط الذي نسخته</translation>
<translation id="5045550434625856497">كلمة مرور غير صحيحة</translation>
<translation id="5056549851600133418">مقالات لك</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />التحقق من عنوان الخادم الوكيل<ph name="END_LINK" /></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="5097099694988056070">‏إحصاءات الأجهزة، مثل استخدام وحدة المعالجة المركزية (CPU)/ذاكرة الوصول العشوائي (RAM)</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">يدير <ph name="ENROLLMENT_DOMAIN" /> جهازك ويدير<ph name="ACCOUNT_DOMAIN" /> حسابك. وهذا يعني أنه قد يضبط المشرفون جهازك وحسابك عن بُعد.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 بت)</translation>
-<translation id="5128122789703661928">الجلسة التي تحمل هذا الاسم غير صالحة للحذف.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">إدارة العناوين...</translation>
+<translation id="5138227688689900538">عرض أقل</translation>
<translation id="5141240743006678641">‏تشفير كلمات المرور المتزامنة باستخدام بيانات اعتماد Google</translation>
<translation id="5145883236150621069">يوجد رمز خطأ في استجابة السياسة</translation>
+<translation id="515292512908731282">‏C4 (مغلف)</translation>
<translation id="5159010409087891077">‏يمكنك فتح الصفحة في نافذة جديدة للتصفح المتخفي (⇧⌘N)</translation>
<translation id="516920405563544094">‏يمكنك إدخال رمز التحقُّق من البطاقة (CVC) لبطاقة <ph name="CREDIT_CARD" />. وبعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حسابك على Google مع هذا الموقع الإلكتروني.</translation>
<translation id="5169827969064885044">‏قد تفقد إمكانية الوصول إلى حساب مؤسستك أو تتعرَّض لسرقة هويتك. لذا، يوصي Chrome بتغيير كلمة مرورك الآن.</translation>
<translation id="5171045022955879922">‏البحث أو إدخال عنوان URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">الجهاز</translation>
<translation id="5179510805599951267">هل الصفحة ليست باللغة <ph name="ORIGINAL_LANGUAGE" />؟ الإبلاغ عن هذا الخطأ</translation>
<translation id="5190835502935405962">شريط الإشارات</translation>
-<translation id="5200263511887412697">الإبلاغ عن قائمة مستخدمي الأجهزة الذين سجّلوا الدخول مؤخرًا</translation>
+<translation id="519422657042045905">التعليق التوضيحي غير متوفِّر</translation>
<translation id="5201306358585911203">تعرض صفحة مضمّنة في هذه الصفحة</translation>
<translation id="5205222826937269299">الاسم مطلوب</translation>
<translation id="5215116848420601511">‏طرق الدفع والعناوين باستخدام Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">البريد الإلكتروني مطلوب</translation>
<translation id="5230733896359313003">عنوان الشحن</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"الاتصال بالشبكة"</translation>
<translation id="5251803541071282808">السحاب</translation>
+<translation id="5252000469029418751">‏C7 (مغلف)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">عناوين الشبكة</translation>
<translation id="5285570108065881030">عرض جميع كلمات المرور المحفوظة</translation>
<translation id="5287240709317226393">عرض ملفات تعريف الارتباط</translation>
<translation id="5288108484102287882">لقد أدى التحقُّق من قيم السياسة إلى ظهور تحذيرات.</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />، <ph name="MATCH_POSITION" /> من <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">اختيار معلومات الاتصال</translation>
<translation id="5327248766486351172">الاسم</translation>
+<translation id="5329858041417644019">متصفِّحك غير مُدار</translation>
<translation id="5332219387342487447">طريقة الشحن</translation>
+<translation id="5334013548165032829">سجلّات النظام التفصيلية</translation>
<translation id="5344579389779391559">قد تُحاول هذه الصفحة تحصيل رسوم منك</translation>
<translation id="5355557959165512791">لا يمكنك زيارة <ph name="SITE" /> الآن لأنه تم إبطال شهادته. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصفحة في وقت على الأرجح.</translation>
<translation id="536296301121032821">تعذّر تخزين إعدادات السياسة</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">‏""توقيت ساعتك متأخِّر" أو "توقيت ساعتك متقدِّم" أو "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">لاستخدام بطاقاتك على جميع الأجهزة، يُرجى تسجيل الدخول وتفعيل المزامنة.</translation>
<translation id="5386426401304769735">‏تتضمن سلسلة الشهادات لهذا الموقع شهادة موقعة باستخدام SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">لم يتمكن هذا الخادم من إثبات أنه <ph name="DOMAIN" />؛ بل إن شهادة الأمان الخاصة به غير صالحة حاليًا. وربما يكون السبب في ذلك وجود خطأ في التكوين أو اعترض أحد المهاجمين للاتصال.</translation>
<translation id="5421136146218899937">محو بيانات التصفّح...</translation>
<translation id="5430298929874300616">إزالة إشارة مرجعية</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">غير صالحة</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<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="5470861586879999274">إعادة الت&amp;حرير</translation>
+<translation id="5478437291406423475">‏B6/C4 (مغلف)</translation>
<translation id="5481076368049295676">قد يحاول هذا المحتوى تثبيت برامج خطيرة على جهازك تسرق معلوماتك أو تحذفها. <ph name="BEGIN_LINK" />عرض على أي حال<ph name="END_LINK" /></translation>
<translation id="54817484435770891">إضافة عنوان صالح</translation>
<translation id="5490432419156082418">العناوين والمزيد</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
حاول الاتصال بمشرف النظام.</translation>
<translation id="549333378215107354">الحجم 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">الإشارات المرجعية المُدارة</translation>
<translation id="5510766032865166053">ربما يكون تم نقله أو حذفه.</translation>
<translation id="5523118979700054094">اسم السياسة</translation>
<translation id="552553974213252141">هل تم استخراج النص بشكل صحيح؟</translation>
+<translation id="553484882784876924">‏Prc6 (مغلف)</translation>
<translation id="5540224163453853">تعذر العثور على المقالة المطلوبة</translation>
<translation id="5541546772353173584">إضافة البريد الإلكتروني</translation>
<translation id="5545756402275714221">مقالات لك</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">تعديل العنوان</translation>
<translation id="5598944008576757369">اختيار طريقة الدفع</translation>
<translation id="560412284261940334">الإدارة غير متوفرة</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">التحقق من الاتصال</translation>
<translation id="5610807607761827392">يمكنك إدارة البطاقات والعناوين في <ph name="BEGIN_LINK" />الإعدادات<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996">أعاد <ph name="HOST_NAME" /> توجيهك مرات كثيرة جدًا.</translation>
<translation id="5629630648637658800">تعذّر تحميل إعدادات السياسة</translation>
<translation id="5631439013527180824">الرمز المميز لإدارة الجهاز غير صالح</translation>
+<translation id="5632627355679805402">‏تم تشفير بياناتك باستخدام <ph name="BEGIN_LINK" />كلمة مرور Google<ph name="END_LINK" /> اعتبارًا من. <ph name="TIME" />. يُرجى إدخالها لبدء المزامنة.</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="563324245173044180">تم حظر المحتوى المُضلّل.</translation>
<translation id="5659593005791499971">البريد الإلكتروني</translation>
+<translation id="5663614846592581799">‏9x11 (مغلف)</translation>
+<translation id="5663955426505430495">ثبَّت مشرف هذا الجهاز الإضافات للوظائف الإضافية. يمكن للإضافات الوصول إلى بعض بياناتك.</translation>
<translation id="5675650730144413517">يتعذّر على هذه الصفحة العمل</translation>
+<translation id="5684874026226664614">عفوًا. تعذرت ترجمة هذه الصفحة.</translation>
<translation id="5685654322157854305">إضافة عنوان الشحن</translation>
<translation id="5689199277474810259">‏تصدير إلى JSON</translation>
<translation id="5689516760719285838">الموقع الجغرافي</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">لم يتمّ التحقق من هوية هذا الموقع.</translation>
<translation id="5719499550583120431">يتم قبول بطاقات الدفع المسبق.</translation>
<translation id="5720705177508910913">المستخدم الحالي</translation>
+<translation id="5728056243719941842">‏C5 (مغلف)</translation>
<translation id="5730040223043577876">‏يُوصي Chrome بإعادة تحديد كلمة المرور في حال إعادة استخدامها في مواقع ويب أخرى.</translation>
<translation id="5732392974455271431">يمكن لوالديك إلغاء الحظر لك</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{‏حفظ بطاقة واحدة في حسابك على Google}zero{‏حفظ بطاقات في حسابك على Google}two{‏حفظ بطاقتين في حسابك على Google}few{‏حفظ بطاقات في حسابك على Google}many{‏حفظ بطاقات في حسابك على Google}other{‏حفظ بطاقات في حسابك على Google}}</translation>
<translation id="5763042198335101085">أدخِل عنوان بريد إلكتروني صحيحًا</translation>
<translation id="5765072501007116331">لعرض طرق التسليم ومتطلباته، حدِّد عنوانًا</translation>
-<translation id="5770114862687765385">يبدو أن الملف تالف. انقر على الزر "إعادة تعيين" لإعادة تعيين الجلسة.</translation>
<translation id="5778550464785688721">‏التحكم الكامل في MIDI</translation>
<translation id="578305955206182703">كهرمان</translation>
<translation id="57838592816432529">كتم الصوت</translation>
<translation id="5784606427469807560">حدثت مشكلة أثناء التأكد من بطاقتك. تحقق من اتصالك بالإنترنت وأعد المحاولة.</translation>
<translation id="5785756445106461925">إضافة إلى ذلك، تتضمن هذه الصفحة موارد أخرى غير آمنة. ويستطيع الآخرون مشاهدة هذه الموارد أثناء نقلها، كما يستطيع أي مهاجم تعديلها لتغيير مظهر الصفحة.</translation>
<translation id="5786044859038896871">هل تريد ملء معلومات بطاقتك؟</translation>
+<translation id="5798290721819630480">هل تريد تجاهل التغييرات؟</translation>
<translation id="5798683403665926540">‏تغيير الصفحة الرئيسية في إعدادات Chrome</translation>
<translation id="5803412860119678065">هل تريد ملء <ph name="CARD_DETAIL" />؟</translation>
<translation id="5804241973901381774">الأذونات</translation>
<translation id="5810442152076338065">يتم ترميز اتصالك بالنطاق <ph name="DOMAIN" /> باستخدام مجموعة تشفير قديمة.</translation>
<translation id="5813119285467412249">إعا&amp;دة الإضافة</translation>
<translation id="5838278095973806738">يجب عدم إدخال معلومات حسّاسة على هذا الموقع (مثل كلمات المرور أو بطاقات الائتمان) لأنه قد تتم سرقتها من قِبل المهاجمين.</translation>
+<translation id="5860033963881614850">غير مفعّل</translation>
<translation id="5863847714970149516">قد تحاول الصفحة التالية تحصيل رسوم منك</translation>
<translation id="5866257070973731571">إضافة رقم الهاتف</translation>
<translation id="5869405914158311789">لا يمكن الوصول إلى موقع الويب هذا</translation>
<translation id="5869522115854928033">كلمات المرور المحفوظة</translation>
<translation id="5887400589839399685">تم حفظ البطاقة</translation>
-<translation id="5893718151540690985">الإبلاغ عن قائمة بواجهات الشبكات مع تحديد أنواعها وعناوين الأجهزة</translation>
<translation id="5893752035575986141">يتم قبول بطاقات الائتمان.</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="5916664084637901428">مفعّل</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">‏هل تريد حفظ البطاقة في حساب Google؟</translation>
<translation id="5922853866070715753">أوشكْت على الانتهاء.</translation>
<translation id="5932224571077948991">يعرض موقع الويب إعلانات مضلِّلة أو غير مرغوب فيها</translation>
-<translation id="5939518447894949180">إعادة الضبط</translation>
<translation id="5946937721014915347">جارٍ فتح <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">لا يمكن التسجيل باستخدام حساب المستهلك (الترخيص المجمّع متوفّر).</translation>
<translation id="5967592137238574583">تعديل معلومات الاتصال</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">تصغير</translation>
<translation id="5977489021191000276">لا يدير جهازك أيّ مشرف.</translation>
<translation id="5977976211062815271">على هذا الجهاز</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">لا يمكن فتح تطبيق الدفع</translation>
<translation id="5989320800837274978">‏لم يتم تحديد أي من الخوادم الوكيلة الثابتة ولا عنوان URL للنص البرمجي pac.</translation>
<translation id="5990559369517809815">تم حظر الطلبات المقدمة إلى الخادم بواسطة إحدى الإضافات.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">‏الإبلاغ عن إحصاءات الأجهزة مثل استخدام وحدة المعالجة المركزية (CPU)/ ذاكرة الوصول العشوائي (RAM)</translation>
<translation id="6034000775414344507">رمادي فاتح</translation>
+<translation id="6034283069659657473">‏10x14 (مغلف)</translation>
<translation id="6039846035001940113">في حال استمرت المشكلة، اتصل بمالك الموقع.</translation>
<translation id="6040143037577758943">إغلاق</translation>
<translation id="6044573915096792553">الحجم 12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">لا يمكنك زيارة <ph name="SITE" /> في الوقت الحالي لأن الموقع يستخدم أداة التحقق من صحة الشهادات. أخطاء الشبكة والهجمات عليها عادةً ما تكون مؤقتة، لذا ستعمل هذه الصفحة في وقت لاحق على الأرجح.</translation>
<translation id="6058977677006700226">هل تستخدم بطاقاتك على جميع أجهزتك؟</translation>
<translation id="6059925163896151826">‏أجهزة USB</translation>
-<translation id="6071091556643036997">نوع السياسة غير صالح.</translation>
<translation id="6080696365213338172">لقد دخلت إلى المحتوى باستخدام شهادة وفرها المشرف. ويمكن أن يعترض المشرف طريق البيانات التي تقدمها إلى <ph name="DOMAIN" />.</translation>
<translation id="6094273045989040137">إضافة تعليق توضيحي</translation>
<translation id="610911394827799129">‏قد يتضمّن حسابك على Google نماذج أخرى من سجلّ التصفّح على <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">معلومات حول المكوّنات الإضافية والإضافات المُثبّتة</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{بدون}=1{ كلمة مرور واحدة (تمت مزامنتها)}two{كلمتا مرور (#) (تمت مزامنتهما)}few{# كلمات مرور (تمت مزامنتها)}many{# كلمة مرور (تمت مزامنتها)}other{# كلمة مرور (تمت مزامنتها)}}</translation>
<translation id="6146055958333702838">تحقق من أي كابلات وأعد تشغيل أي أجهزة توجيه أو أجهزة مودم أو أجهزة شبكة
أخرى ربما تستخدمها.</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">سيتم توفير أقل من <ph name="SIZE" />. وقد يتم تحميل بعض مواقع الويب بشكل أبطأ عند زيارتها في المرة القادمة.</translation>
<translation id="6337534724793800597">تصفية السياسات بحسب الاسم</translation>
<translation id="6358450015545214790">ماذا تعني هذه الأقسام؟</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">رسوم محتملة في انتظارك.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{اقتراح واحد آخر}zero{# اقتراح آخر}two{اقتراحان آخران (#)}few{# اقتراحات أخرى}many{# اقتراحًا آخر}other{# اقتراح آخر}}</translation>
<translation id="6387754724289022810">‏للدفع بشكلٍ أسرع في المرة القادمة، يجب حفظ تفاصيل البطاقة المصرفية وعنوان إرسال الفواتير في حسابك على Google وعلى هذا الجهاز.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">تعديل الإشارة المرجعية</translation>
+<translation id="6406765186087300643">‏C0 (مغلف)</translation>
<translation id="6410264514553301377">‏أدخِل تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">لقد سألت والديك ما إذا كانت زيارة هذا الموقع مناسبةً لك</translation>
<translation id="6417515091412812850">تعذر التحقق مما إذا كانت الشهادة قد تم إبطالها.</translation>
<translation id="6433490469411711332">تعديل معلومات الاتصال</translation>
<translation id="6433595998831338502">رفض <ph name="HOST_NAME" /> الاتصال.</translation>
+<translation id="6434309073475700221">إلغاء</translation>
+<translation id="6446163441502663861">‏Kahu (مغلف)</translation>
<translation id="6446608382365791566">إضافة مزيد من المعلومات</translation>
<translation id="6447842834002726250">ملفّات تعريف الارتباط</translation>
<translation id="6451458296329894277">تأكيد إعادة إرسال النموذج</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">‏إعادة تشغيل Chrome</translation>
<translation id="6529602333819889595">إعادة الح&amp;ذف</translation>
<translation id="6534179046333460208">اقتراحات الشبكة المادية</translation>
+<translation id="6556866813142980365">إعادة</translation>
<translation id="6563469144985748109">لم يوافق عليه مديرك حتى الآن</translation>
<translation id="6569060085658103619">أنت تعرض صفحة إضافة</translation>
+<translation id="6578796323535178455">‏C2 (مغلف)</translation>
<translation id="6579990219486187401">وردي فاتح</translation>
+<translation id="6583674473685352014">‏B6 (مغلف)</translation>
+<translation id="6587923378399804057">الرابط الذي نسخته</translation>
+<translation id="6591833882275308647">لا تتم إدارة <ph name="DEVICE_TYPE" /></translation>
<translation id="6596325263575161958">خيارات التشفير</translation>
<translation id="6604181099783169992">أجهزة استشعار الإضاءة والحركة</translation>
+<translation id="6609880536175561541">‏Prc7 (مغلف)</translation>
<translation id="6624427990725312378">معلومات الاتصال</translation>
<translation id="6626291197371920147">إضافة رقم بطاقة صالح</translation>
<translation id="6628463337424475685">بحث <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">تم تجاهل هذه السياسة.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{بدون}=1{‏من موقع ويب واحد (لن يتم تسجيل خروجك من حسابك على Google)}two{‏من موقعي ويب (#) (لن يتم تسجيل خروجك من حسابك على Google)}few{‏من # مواقع ويب (لن يتم تسجيل خروجك من حسابك على Google)}many{‏من # موقع ويب (لن يتم تسجيل خروجك من حسابك على Google)}other{‏من # موقع ويب (لن يتم تسجيل خروجك من حسابك على Google)}}</translation>
<translation id="6657585470893396449">كلمة المرور</translation>
+<translation id="6670613747977017428">الرجوع</translation>
<translation id="6671697161687535275">‏هل تريد إزالة اقتراح النموذج من Chromium؟</translation>
<translation id="6685834062052613830">الخروج وإكمال الإعداد</translation>
<translation id="6710213216561001401">السابق</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">الرمز المميّز للتسجيل:</translation>
<translation id="6711464428925977395">هناك خطأ ما في الخادم الوكيل، أو العنوان غير صحيح.</translation>
<translation id="6723740634201835758">‏في حسابك على Google</translation>
+<translation id="6738516213925468394">تم تشفير بياناتك باستخدام <ph name="BEGIN_LINK" />عبارة مرور المزامنة<ph name="END_LINK" /> في <ph name="TIME" />. يُرجى إدخالها لبدء المزامنة.</translation>
<translation id="674375294223700098">حدث خطأ غير معروف في شهادة الخادم.</translation>
<translation id="6744009308914054259">أثناء انتظار اتصال، يمكنك الانتقال إلى "التنزيلات" للاطِّلاع على المقالات بلا اتصال بالإنترنت.</translation>
<translation id="6753269504797312559">قيمة السياسة</translation>
<translation id="6757797048963528358">خضع جهازك إلى وضع السكون.</translation>
+<translation id="6768213884286397650">‏Hagaki (بطاقة بريدية)</translation>
<translation id="6778737459546443941">لم يوافق عليه والداك حتى الآن</translation>
<translation id="67862343314499040">بنفسجي</translation>
+<translation id="6786747875388722282">الإضافات</translation>
<translation id="679355240208270552">تم التجاهل نظرًا لأنه لم يتم تفعيل البحث التلقائي بواسطة السياسة.</translation>
<translation id="681021252041861472">الحقل مطلوب</translation>
<translation id="6810899417690483278">رقم تعريف التخصيص</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">جهاز</translation>
<translation id="6970216967273061347">حي</translation>
<translation id="6973656660372572881">‏تم تحديد كل من الخوادم الوكيلة الثابتة وعنوان URL للنص البرمجي pac.</translation>
+<translation id="6973932557599545801">عذرًا، لا يمكنني مساعدتك، يُرجى المتابعة بنفسك.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">كتم الصوت (تلقائي)</translation>
<translation id="6984479912851154518">ستتم مغادرة وضع التصفّح المتخفي للدفع عبر تطبيق خارجي. هل تريد المتابعة؟</translation>
<translation id="6989763994942163495">عرض الإعدادات المتقدمة...</translation>
+<translation id="6993898126790112050">‏6x9 (مغلف)</translation>
<translation id="6996312675313362352">ترجمة اللغة <ph name="ORIGINAL_LANGUAGE" /> دائمًا</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">قد يتمّ تحصيل هذه الرسوم لمرة واحدة أو بشكل متكرر، وقد تكون غير واضحة.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">إخفاء</translation>
<translation id="7108819624672055576">تم السماح بواسطة إحدى الإضافات</translation>
<translation id="7111012039238467737">(صالح)</translation>
+<translation id="7118618213916969306">‏البحث عن عنوان URL للحافظة، <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">إغلاق علامات التبويب أو البرامج الأخرى</translation>
<translation id="7129409597930077180">لا يمكن الشحن على هذا العنوان. حدِّد عنوانًا آخر.</translation>
<translation id="7135130955892390533">عرض الحالة</translation>
<translation id="7138472120740807366">طريقة التسليم</translation>
<translation id="7139724024395191329">إمارة</translation>
+<translation id="7152423860607593928">‏Number-14 (مغلف)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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" /> أخريان}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="7153618581592392745">بنفسجي فاتح</translation>
-<translation id="7158980942472052083">‏عنوان URL غير صالح. يجب أن يكون عنوان URL يحتوي على نظام قياسي.</translation>
<translation id="717330890047184534">‏معرّف GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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" />) آخران}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="7177397715882417099">لقد طلب الخادم الذي تنتقل إليه، <ph name="ORIGIN" />، أن
+ يتم تطبيق سياسة الأمان على جميع الطلبات المقدَّمة إليه. ولكن بدلاً من
+ عرض السياسة، تمت إعادة توجيه المتصفِّح إلى مكان آخر، ما يمنع
+ المتصفِّح من توصيل الطلب لموقع <ph name="SITE" />.</translation>
<translation id="7179323680825933600">حفظ طرق الدفع وملؤها</translation>
<translation id="7180611975245234373">إعادة التحميل</translation>
<translation id="7182878459783632708">لم يتم تعيين أي سياسات</translation>
<translation id="7186367841673660872">تمت ترجمة هذه الصفحة من اللغة<ph name="ORIGINAL_LANGUAGE" />إلى اللغة<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">يوفِّر <ph name="SIZE" />. قد يتم تحميل بعض مواقع الويب بشكل أبطأ عند زيارتها في المرة القادمة.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">يمكن للمشرف الاطِّلاع على ما يلي:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">لا يلتزم <ph name="HOST_NAME" /> بمعايير الأمان.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /> حول هذه المشكلة.</translation>
<translation id="7219179957768738017">الاتصال يستخدم <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">جارٍ المعالجة</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />، <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">يحتوي موقع الويب المقصود على برامج ضارة</translation>
+<translation id="724766306220616965">التحذيرات والتعارضات</translation>
<translation id="724975217298816891">‏أدخل تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /> لتحديث تفاصيل بطاقتك. بعد تأكيدك، ستتم مشاركة تفاصيل بطاقتك مع هذا الموقع.</translation>
<translation id="7251437084390964440">‏لا تتوافق تهيئة الشبكة مع معيار ONC. وقد لا تُستورَد أجزاء من التهيئة.
التفاصيل الإضافية:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">أزرق كوبالت</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">تقرير الأعطال الذي تم الحصول عليه في <ph name="CRASH_TIME" /> (التحميل مطلوب بواسطة المستخدم، لم يتم التحميل بعد)</translation>
+<translation id="7313965965371928911">تحذيرات <ph name="BEGIN_LINK" />التصفُّح الآمن<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">المساعدة بشأن الاتصال</translation>
<translation id="7334320624316649418">إعادة إ&amp;جراء الترتيب</translation>
<translation id="733923710415886693">لم يتم الكشف عن شهادة الخادم عن طريق شهادة الشفافية.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">سطر الأوامر</translation>
-<translation id="7365061714576910172">‏تصدير Linux</translation>
<translation id="7372973238305370288">نتيجة البحث</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" />‏ - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">لا</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">إلغاء الجلسة المُدارة</translation>
<translation id="7390545607259442187">التأكد من البطاقة</translation>
<translation id="7400418766976504921">‏عنوان URL</translation>
+<translation id="7403591733719184120">إدارة <ph name="DEVICE_NAME" /></translation>
<translation id="7407424307057130981">‏&lt;p&gt;سيظهر هذا الخطأ إذا كان لديك برنامج Superfish على جهاز الكمبيوتر المزوَّد بنظام التشغيل Windows.&lt;/p&gt;
&lt;p&gt;يُرجى اتِّباع الخطوات التالية لإيقاف البرنامج مؤقّتًا ليتسنى لك الوصول إلى الويب. ستحتاج إلى امتيازات المُشرف لإجراء ذلك.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;انقر على &lt;strong&gt;"تطبيق"&lt;/strong&gt;، ثم على &lt;strong&gt;"موافق"&lt;/strong&gt;
&lt;li&gt;انتقِل إلى &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;مركز مساعدة Chrome&lt;/a&gt; لمعرفة كيفية إزالة البرنامج من جهاز الكمبيوتر نهائيًا
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">إدارة <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">إدارة كلمات المرور…</translation>
<translation id="7419106976560586862">مسار الملف الشخصي</translation>
<translation id="7437289804838430631">إضافة معلومات الاتصال</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">برتقالي فاتح</translation>
<translation id="7444046173054089907">تم حظر هذا الموقع</translation>
<translation id="7445762425076701745">لا يمكن التحقق بصورة كاملة من صحة هوية الخادم الذي تتصل به. فأنت متصل بخادم باستخدام اسم صالح فقط ضمن شبكتك، والذي لن يتمكن المرجع المصدق الخارجي من التحقق من ملكيته. وحيث إن بعض المراجع المصدقة تُصدر الشهادات لهذه الأسماء على أي حال، فليست هناك طريقة للتأكد من أنك متصل بموقع الويب المقصود وليس بأحد المهاجمين.</translation>
-<translation id="7449109375006139765">إرسال سجلَّات النظام إلى خادم الإدارة</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /> حول هذه المشكلة.</translation>
<translation id="7455133967321480974">استخدام الإعداد التلقائي العمومي (حظر)</translation>
<translation id="7460618730930299168">يختلف هذا الفحص عن اختيارك. هل تريد المتابعة؟</translation>
<translation id="7473891865547856676">لا، شكرًا</translation>
-<translation id="7475525192983021547">الإبلاغ عن الفترات الزمنية التي يكون المستخدم فيها نشطًا على الجهاز</translation>
<translation id="7481312909269577407">إلى الأمام</translation>
<translation id="7485870689360869515">لم يتم العثور على بيانات.</translation>
+<translation id="7498234416455752244">متابعة التعديل</translation>
<translation id="7508255263130623398">رقم تعريف الجهاز المعروض للسياسة فارغ أو لا يتطابق مع رقم تعريف الجهاز الحالي</translation>
<translation id="7508870219247277067">أخضر مصفر</translation>
<translation id="7511955381719512146">‏قد يتتطلب Wi-Fi الذي تستخدمه زيارة <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">تنزيل</translation>
<translation id="7518003948725431193">لم يتم العثور على أي صفحة ويب لعنوان الويب:<ph name="URL" /></translation>
+<translation id="7520302887438682816">‏C8 (مغلف)</translation>
<translation id="7521387064766892559">جافا سكريبت</translation>
<translation id="7526934274050461096">اتصالك بموقع الويب هذا لا يتمتع بخصوصية</translation>
+<translation id="7535087603100972091">القيمة</translation>
<translation id="7537536606612762813">إلزامية</translation>
+<translation id="7538364083937897561">‏A2 (مغلف)</translation>
<translation id="7542403920425041731">بعد تأكيدك، ستتم مشاركة تفاصيل بطاقتك مع موقع الويب هذا.</translation>
<translation id="7542995811387359312">تم إيقاف الملء التلقائي لبطاقة الائتمان لأن هذا النموذج لا يستخدم اتصالاً آمنًا.</translation>
<translation id="7543525346216957623">اسأل والديك</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">جرّب النصائح التالية:</translation>
<translation id="7554791636758816595">علامة تبويب جديدة</translation>
<translation id="7564049878696755256">‏قد تفقد إمكانية الوصول إلى حسابك على <ph name="ORG_NAME" /> أو تتعرض لسرقة هويتك. لذا يوصي Chrome بتغيير كلمة مرورك الآن.</translation>
-<translation id="7566125604157659769">النص الذي نسخته</translation>
<translation id="7567204685887185387">هذا الخادم لم يتمكن من إثبات أن ذلك <ph name="DOMAIN" />؛ بل إنه شهادة أمان تم إصدارها عن طريق الاحتيال. وربما يكون سبب ذلك خطأ في التكوين أو مهاجمًا يعترض اتصالك.</translation>
+<translation id="7568105740864181217">‏تتم إدارة هذا المتصفِّح من خلال شركة أو مؤسسة تعليمية أو مؤسسة أخرى. يمكن لمشرفك تغيير إعداد المتصفِّح عن بُعد. قد تتم أيضًا إدارة النشاط على هذا الجهاز خارج Chrome. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">‏هل تريد إزالة بطاقة الائتمان من Chrome؟</translation>
<translation id="7569983096843329377">أسود</translation>
<translation id="7578104083680115302">‏الدفع سريعًا على المواقع والتطبيقات على جميع الأجهزة باستخدام البطاقات التي حفظتها في Google.</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">تقارير الأعطال وبيانات الأداء</translation>
<translation id="7637571805876720304">‏هل تريد إزالة بطاقة الائتمان من Chromium؟</translation>
<translation id="7639968568612851608">رمادي داكن</translation>
<translation id="765676359832457558">إخفاء الإعدادات المتقدمة...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">الرمز المميز المعروض للسياسة خاليًا أو لا يتطابق مع الرمز المميز الحالي</translation>
<translation id="7668654391829183341">جهاز غير معروف</translation>
<translation id="7669271284792375604">قد يحاول المهاجمون في هذا الموقع خداعك من خلال تثبيت برامج تضر بتجربة التصفح (على سبيل المثال، من خلال تغيير صفحتك الرئيسية أو عرض إعلانات إضافية على المواقع التي تزورها).</translation>
+<translation id="7676643023259824263">البحث عن نص الحافظة،<ph name="TEXT" /></translation>
<translation id="7681101578153515023">تغيير محرّك البحث</translation>
<translation id="7682287625158474539">الشحن</translation>
<translation id="7687186412095877299">تعبئة نماذج الدفع باستخدام طرق الدفع المحفوظة</translation>
+<translation id="7697066736081121494">‏Prc8 (مغلف)</translation>
<translation id="769721561045429135">تمتلك حتى الآن بطاقات يمكنك استخدامها فقط على هذا الجهاز. انقر على "متابعة" لمراجعة البطاقات</translation>
<translation id="7699293099605015246">المقالات غير متاحة الآن</translation>
<translation id="7701040980221191251">لا يوجد</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">تم حظر المحتوى الخطير.</translation>
<translation id="7752995774971033316">غير مُدار</translation>
<translation id="7755287808199759310">قد يلغي والداك الحظر لك</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ربما حظر الجدار الناري أو برامج مكافحة الفيروسات الاتصال.</translation>
<translation id="7759163816903619567">نطاق العرض:</translation>
<translation id="7761701407923456692">‏لا تتطابق شهادة الخادم مع عنوان URL.</translation>
<translation id="7763386264682878361">المحلل اللغوي لبيان الدفع</translation>
<translation id="7764225426217299476">إضافة عنوان</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">المديرية</translation>
<translation id="7791543448312431591">إضافة</translation>
<translation id="7793809570500803535">قد تكون صفحة الويب على العنوان <ph name="SITE" /> غير متاحة مؤقتًا أو تم نقلها نهائيًا إلى عنوان ويب جديد.</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">‏هل تريد إزالة اقتراح النموذج من Chrome؟</translation>
<translation id="7815407501681723534">تم العثور على <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> لـ "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">إدارة السياسات</translation>
<translation id="782886543891417279">‏قد يتطلب Wi-Fi الذي تستخدمه (<ph name="WIFI_NAME" />) زيارة صفحة تسجيل الدخول.</translation>
+<translation id="7836231406687464395">‏Postfix (مغلف)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{لا تتوفَّر تطبيقات}=1{تطبيق واحد (<ph name="EXAMPLE_APP_1" />)}=2{تطبيقان (<ph name="EXAMPLE_APP_1" />، و<ph name="EXAMPLE_APP_2" />)}few{# تطبيقات (<ph name="EXAMPLE_APP_1" />، و<ph name="EXAMPLE_APP_2" />، و<ph name="AND_MORE" /> من التطبيقات الأخرى)}many{# تطبيقات (<ph name="EXAMPLE_APP_1" />، و<ph name="EXAMPLE_APP_2" />، و<ph name="AND_MORE" /> من التطبيقات الأخرى)}other{# تطبيقات (<ph name="EXAMPLE_APP_1" />، و<ph name="EXAMPLE_APP_2" />، و<ph name="AND_MORE" /> من التطبيقات الأخرى)}}</translation>
<translation id="785549533363645510">ومع ذلك، أنت غير مرئي. لا يخفي الانتقال إلى وضع التخفي التصفح من صاحب العمل أو مزود خدمة الإنترنت أو المواقع التي تزورها.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">من المحتمل أنه تم اختراق كلمة مرورك</translation>
<translation id="7882421473871500483">بني</translation>
<translation id="7887683347370398519">‏تحقق من رمز التحقق من البطاقة (CVC) ثم أعد المحاولة.</translation>
-<translation id="7893255318348328562">اسم الجلسة</translation>
+<translation id="7904208859782148177">‏C3 (مغلف)</translation>
<translation id="79338296614623784">أدخِل رقم هاتف صحيحًا</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">تنتهي الصلاحية في <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(32 بت)</translation>
<translation id="7956713633345437162">الإشارات المرجعية على الجوّال</translation>
<translation id="7961015016161918242">مطلقًا</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">غير محدد</translation>
<translation id="800218591365569300">جرّب إغلاق علامات التبويب أو البرامج الأخرى لتفريغ مساحة من الذاكرة.</translation>
+<translation id="8004582292198964060">المتصفّح</translation>
<translation id="8009225694047762179">إدارة كلمات المرور</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{سيتم حفظ هذه البطاقة وعنوان إرسال الفواتير. ستتمكَّن من استخدامها عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}zero{سيتم حفظ هذه البطاقات وعناوين إرسال الفواتير. ستتمكَّن من استخدامها عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}two{سيتم حفظ هاتين البطاقتين وعنواني إرسال الفواتير. ستتمكَّن من استخدامهما عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}few{سيتم حفظ هذه البطاقات وعناوين إرسال الفواتير. ستتمكَّن من استخدامها عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}many{سيتم حفظ هذه البطاقات وعناوين إرسال الفواتير. ستتمكَّن من استخدامها عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}other{سيتم حفظ هذه البطاقات وعناوين إرسال الفواتير. ستتمكَّن من استخدامها عند تسجيل الدخول إلى <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">لم نتمكن من الوصول إلى والديك في الوقت الحالي. يُرجى إعادة المحاولة مرة أخرى.</translation>
<translation id="8025119109950072390">قد يحاول المهاجمون على هذا الموقع خداعك لاتّخاذ إجراءات خطيرة مثل تثبيت برامج معيّنة أو كشف معلوماتك الشخصية (مثل كلمات المرور أو أرقام الهواتف أو بطاقات الائتمان).</translation>
<translation id="8034522405403831421">هذه الصفحة باللغة <ph name="SOURCE_LANGUAGE" />. هل تريد ترجمتها إلى اللغة <ph name="TARGET_LANGUAGE" />؟</translation>
<translation id="8035152190676905274">قلم</translation>
+<translation id="8037117624646282037">الأشخاص الذين استخدموا الجهاز مؤخرًا</translation>
<translation id="8037357227543935929">الطلب (تلقائي)</translation>
<translation id="803771048473350947">ملف</translation>
<translation id="8041089156583427627">إرسال تعليقات</translation>
<translation id="8041940743680923270">استخدام الإعداد التلقائي العمومي (طلب)</translation>
<translation id="8042918947222776840">اختيار طريقة الاستلام من المستخدم</translation>
<translation id="8057711352706143257">لم تتم تهيئة "<ph name="SOFTWARE_NAME" />" بشكل صحيح. يؤدي عادةً إلغاء تثبيت "<ph name="SOFTWARE_NAME" />" إلى إصلاح المشكلة. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">تم ضبط جهازك لإجراء ما يلي:</translation>
+<translation id="8066955247577885446">عذرًا، حدث خطأ.</translation>
+<translation id="8074253406171541171">‏10x13 (مغلف)</translation>
<translation id="8078141288243656252">لا يمكن إضافة تعليق توضيحي عند تدوير المستند</translation>
<translation id="8079031581361219619">هل تريد إعادة تحميل الموقع؟</translation>
<translation id="8088680233425245692">تعذّر عرض المقالة.</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">التفعيل قيد الانتظار في الخادم</translation>
<translation id="8092774999298748321">أرجواني داكن</translation>
<translation id="8094917007353911263">قد تتطلب الشبكة التي تستخدمها زيارة <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">تمت إزالة البطاقات غير الصالحة</translation>
<translation id="8103161714697287722">طريقة الدفع</translation>
<translation id="8118489163946903409">طريقة الدفع</translation>
+<translation id="8123836779274890062">إدارة <ph name="DEVICE_TYPE" /> عن طريق <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">لم يتم تثبيت "<ph name="SOFTWARE_NAME" />" بطريقة صحيحة على جهاز الكمبيوتر أو الشبكة. اطلب من مشرف تقنية المعلومات حل هذه المشكلة.</translation>
-<translation id="8130693978878176684">لا يمكنني مساعدتك بعد ذلك، يُرجى المتابعة بنفسك.</translation>
<translation id="8131740175452115882">التأكيد</translation>
<translation id="8149426793427495338">خضع جهاز الكمبيوتر إلى وضع السكون.</translation>
<translation id="8150722005171944719">الملف الموجود على <ph name="URL" /> غير قابل للقراءة. ربما تمت إزالته، أو ربما تكون أذونات الملف هي التي تمنع الدخول.</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">ترجمة الصفحة</translation>
<translation id="8201077131113104583">‏عنوان URL لتحديث الإضافة التي تحتوي على رقم التعريف "<ph name="EXTENSION_ID" />" غير صالح.</translation>
<translation id="8202097416529803614">ملخص الطلب</translation>
+<translation id="8202370299023114387">تعارض</translation>
+<translation id="8206978196348664717">‏Prc4 (مغلف)</translation>
<translation id="8211406090763984747">الاتصال بموقع الويب هذا آمن</translation>
<translation id="8218327578424803826">الموقع الذي تم تعيينه:</translation>
+<translation id="8220146938470311105">‏C7/C6 (مغلف)</translation>
<translation id="8225771182978767009">اختار الشخص الذي أعد جهاز الكمبيوتر حظر موقع الويب هذا.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />، <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">يمكنك فتح الصفحة في علامة تبويب جديدة للتصفح المتخفي</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">عرض جميع كلمات المرور المحفوظة</translation>
<translation id="8261506727792406068">حذف</translation>
<translation id="8267698848189296333">تسجيل الدخول باسم <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">‏تتم إدارة هذا المتصفِّح من خلال <ph name="ENROLLMENT_DOMAIN" />. ويمكن لمشرفك تغيير إعداد المتصفِّح عن بُعد. قد تتم أيضًا إدارة النشاط على هذا الجهاز خارج Chrome. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">تسجيل الدخول</translation>
<translation id="8288807391153049143">عرض الشهادة</translation>
<translation id="8289355894181816810">اتصل بمشرف الشبكة إذا لم تكن متأكدًا مما يعنيه هذا.</translation>
<translation id="8293206222192510085">إضافة إشارة مرجعية</translation>
<translation id="8294431847097064396">المصدر</translation>
<translation id="8298115750975731693">‏قد يتتطلب Wi-Fi الذي تستخدمه (<ph name="WIFI_NAME" />) زيارة <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">تعذّرت الترجمة بسبب حدوث مشكلة في الاتصال بالشبكة.</translation>
-<translation id="8311129316111205805">تحميل الجلسة</translation>
<translation id="8332188693563227489">تم رفض الدخول إلى <ph name="HOST_NAME" />.</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">إذا كنت على دراية بالمخاطر التي تهدد أمانك، يمكنك <ph name="BEGIN_LINK" />زيارة هذا الموقع<ph name="END_LINK" /> قبل أن تتم إزالة البرامج الضارة.</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">تهيئة الشبكة غير صالحة ويتعذّر استيرادها.
التفاصيل الإضافية:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">جهاز مُدار من خلال <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">تغيير</translation>
<translation id="8428213095426709021">الإعدادات</translation>
@@ -1211,9 +1369,11 @@
<translation id="860043288473659153">اسم حامل البطاقة</translation>
<translation id="861775596732816396">الحجم 4</translation>
<translation id="8620436878122366504">لم يوافق عليه والداك حتى الآن</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">حفظ هذه البطاقة إلى هذا الجهاز</translation>
<translation id="8663226718884576429">ملخّص الطلب و<ph name="TOTAL_LABEL" /> وتفاصيل إضافية</translation>
<translation id="8680536109547170164"><ph name="QUERY" />، إجابة، <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">الاتصال بالموقع <ph name="DOMAIN" /> غير محميّ بنظام تشفير.</translation>
<translation id="8718314106902482036">لم تكتمل عملية الدفع</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />، <ph name="DESCRIPTION" />، اقتراح البحث</translation>
@@ -1227,6 +1387,7 @@
<translation id="8761567432415473239">‏عثر ‏‫التصفح الآمن من Google‬ مؤخرًا <ph name="BEGIN_LINK" />على برامج ضارة<ph name="END_LINK" /> في <ph name="SITE" />.</translation>
<translation id="8763927697961133303">‏جهاز USB</translation>
<translation id="8768895707659403558">لاستخدام بطاقاتك على جميع أجهزتك، <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">إعادة الح&amp;ذف</translation>
<translation id="8792621596287649091">‏قد تفقد إمكانية الوصول إلى حسابك على <ph name="ORG_NAME" /> أو تتعرض لسرقة هويتك. لذا يوصي Chromium بتغيير كلمة مرورك الآن.</translation>
<translation id="8800988563907321413">تظهر اقتراحاتك "المجاورة" هنا</translation>
@@ -1237,10 +1398,12 @@
<translation id="885730110891505394">‏مشاركة مع Google</translation>
<translation id="8858065207712248076">‏يُوصي Chrome بإعادة تحديد كلمة المرور <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> في حال إعادة استخدامها في مواقع ويب أخرى.</translation>
<translation id="8866481888320382733">خطأ في إعدادات تحليل السياسة</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">العناصر المغلقة مؤخرًا</translation>
<translation id="8874824191258364635">أدخِل رقم بطاقة صحيحًا</translation>
<translation id="8891727572606052622">وضع الخادم الوكيل غير صالح.</translation>
<translation id="8903921497873541725">تكبير</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">‏هل تريد حفظ هذه البطاقة إلى حسابك في Google؟</translation>
<translation id="8932102934695377596">توقيت ساعتك متأخر عن الوقت الحالي</translation>
<translation id="893332455753468063">إضافة اسم</translation>
@@ -1248,13 +1411,13 @@
<translation id="894185898663964645">ضبط مشرفك شهادات الجذر المُخصّصة والتي قد تسمح للمشرف بالتعرُّف على محتوى مواقع الويب التي تزورها.</translation>
<translation id="8943282376843390568">ليموني</translation>
<translation id="8957210676456822347">تفويض المدخل المقيد</translation>
+<translation id="8966619695390250636">هل كنت تقصد؟</translation>
<translation id="8968766641738584599">حفظ البطاقة</translation>
<translation id="8971063699422889582">انتهت صلاحية شهادة الخادم.</translation>
<translation id="8975012916872825179">تتضمّن معلومات مثل أرقام الهواتف وعناوين البريد الإلكتروني وعناوين الشحن.</translation>
<translation id="8978053250194585037">‏رصد التصفح الآمن من Google عن وجود‬ <ph name="BEGIN_LINK" />تصيّد احتيالي<ph name="END_LINK" /> مؤخرًا على موقع <ph name="SITE" />، إذ تتظاهر مواقع التصيد الاحتيالي بكونها مواقع ويب أخرى لخداعك.</translation>
<translation id="8983003182662520383">‏طرق الدفع والعناوين باستخدام Google Pay</translation>
<translation id="8987927404178983737">شهر</translation>
-<translation id="8988408250700415532">حدث خطأ. يمكنك إتمام طلبك على الموقع الإلكتروني.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" />‏ [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">تحتوي مقدمة الموقع على برامج ضارة</translation>
<translation id="8997023839087525404">قدم الخادم شهادة لم يتم الكشف عنها علنًا باستخدام سياسة شهادة الشفافية. وهذا ضروري لبعض الشهادات، لضمان أنها جديرة بالثقة ومحمية من المهاجمين.</translation>
@@ -1264,6 +1427,7 @@
<translation id="9011424611726486705">فتح إعدادات الموقع</translation>
<translation id="9020200922353704812">عنوان إرسال الفواتير للبطاقة مطلوب</translation>
<translation id="9020542370529661692">تمت ترجمة هذه الصفحة إلى <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(غير صالحة)</translation>
<translation id="9035022520814077154">خطأ متعلق بالأمان</translation>
<translation id="9038649477754266430">استخدام إحدى خدمات التوقع لتحميل الصفحات بسرعة أكبر</translation>
@@ -1275,11 +1439,11 @@
<translation id="9065745800631924235">البحث عن <ph name="TEXT" /> من السجلّ.</translation>
<translation id="9069693763241529744">تم الحظر بواسطة إحدى الإضافات</translation>
<translation id="9076283476770535406">قد يتضمن محتوى للبالغين</translation>
+<translation id="9076630408993835509">‏لا تتم إدارة هذا المتصفِّح من خلال شركة أو مؤسسة أخرى. قد تتم إدارة النشاط على هذا الجهاز خارج Chrome. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">مطلوب مزيد من المعلومات</translation>
<translation id="9080712759204168376">ملخص الطلبات</translation>
<translation id="9103872766612412690">‏يستخدم <ph name="SITE" /> التشفير عادة لحماية معلوماتك. عندما حاول Chromium الاتصال بموقع <ph name="SITE" /> هذه المرة، أرجَع موقع الويب بيانات اعتماد غير عادية وغير صحيحة. وقد يحدث هذا عندما يحاول أحد المهاجمين التظاهر بأنه موقع <ph name="SITE" />، أو إذا قاطعت شاشة تسجيل دخول Wi-Fi الاتصال. ولكن لا تزال معلوماتك آمنة نظرًا لأن Chromium أوقَفَ الاتصال قبل تبادل أي بيانات.</translation>
<translation id="9106062320799175032">إضافة عنوان إرسال الفواتير</translation>
-<translation id="9110718169272311511">‏يتوفَّر "مساعد Google" على Chrome بالقرب من أسفل الشاشة</translation>
<translation id="9114524666733003316">جارٍ التحقق من البطاقة...</translation>
<translation id="9128870381267983090">الاتصال بالشبكة</translation>
<translation id="9137013805542155359">إظهار الصفحة الأصلية</translation>
@@ -1288,6 +1452,7 @@
<translation id="9148507642005240123">تراجع عن ا&amp;لتحرير</translation>
<translation id="9154194610265714752">تم التحديث</translation>
<translation id="9157595877708044936">جارٍ الإعداد...</translation>
+<translation id="9158625974267017556">‏C6 (مغلف)</translation>
<translation id="9168814207360376865">السماح لمواقع الويب بالتحقُّق ممّا إذا كانت لديك طرق دفع محفوظة أم لا</translation>
<translation id="9169664750068251925">الحظر دومًا على هذا الموقع</translation>
<translation id="9170848237812810038">&amp;إلغاء</translation>
@@ -1302,10 +1467,12 @@
<translation id="9219103736887031265">الصور</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">محو النموذج</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">‏قد لا تتمكّن من الوصول إلى حسابك على Google. لذا ينصح Chromium بتغيير كلمة مرورك الآن. وسيُطلَب منك تسجيل الدخول.</translation>
<translation id="939736085109172342">مجلد جديد</translation>
<translation id="945855313015696284">يجب التحقُّق من المعلومات الواردة أدناه وحذف أي بطاقات غير صالحة</translation>
<translation id="951104842009476243">بطاقات السحب الآلي وبطاقات الدفع المسبق المقبولة</translation>
+<translation id="958202389743790697">تم الحظر وفقًا لسياسة أمان <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">قد يحاول هذا المحتوى تثبيت تطبيقات مضللة تظهر كبرامج أخرى أو تجمع بيانات قد تُستخدم لتتبعك. <ph name="BEGIN_LINK" />العرض على أي حال<ph name="END_LINK" /></translation>
<translation id="969892804517981540">البنية الرسمية</translation>
<translation id="973773823069644502">إضافة عنوان التسليم للمستخدم</translation>
@@ -1314,6 +1481,7 @@
<translation id="984275831282074731">طرق الدفع</translation>
<translation id="985199708454569384">‏&lt;p&gt;سيظهر هذا الخطأ إذا كان التاريخ والوقت غير دقيقَيْن في جهاز الكمبيوتر أو الجهاز الجوّال.&lt;/p&gt;
&lt;p&gt;لإصلاح الخطأ، افتح ساعة الجهاز وتأكد من صحة التاريخ والوقت.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">بنية المطوِّر</translation>
<translation id="989988560359834682">تعديل العنوان</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_bg.xtb b/chromium/components/strings/components_strings_bg.xtb
index 49aa403173e..8586f95717d 100644
--- a/chromium/components/strings/components_strings_bg.xtb
+++ b/chromium/components/strings/components_strings_bg.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bg">
-<translation id="1005145902654145231">Преименуването на сесията не бе успешно.</translation>
<translation id="1008557486741366299">Не сега</translation>
<translation id="1010200102790553230">Зареждане на страницата по-късно</translation>
<translation id="1015730422737071372">Въвеждане на допълнителни подробности</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">неизвестно име</translation>
<translation id="1050038467049342496">Затворете другите приложения.</translation>
<translation id="1055184225775184556">&amp;Отмяна на добавянето</translation>
+<translation id="1056898198331236512">Предупреждение</translation>
<translation id="1058479211578257048">Картите се запазват...</translation>
<translation id="10614374240317010">Незапазвани никога</translation>
+<translation id="1062160989074299343">Prc10 (плик)</translation>
<translation id="106701514854093668">Настолни отметки</translation>
<translation id="1074497978438210769">Няма защита</translation>
<translation id="1080116354587839789">Побиране на ширина</translation>
+<translation id="1086953900555227778">Index-5 x 8</translation>
<translation id="1088860948719068836">Добавяне на името на картодържателя</translation>
<translation id="1089439967362294234">Промяна на паролата</translation>
<translation id="109743633954054152">Управлявайте паролите от настройките на Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Възможно е да виждате предупреждения често, докато уебсайтовете актуализират мерките си за сигурност. Това би трябвало скоро да се подобри.</translation>
<translation id="1126551341858583091">Размерът на локалното хранилище е <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Кешът на правилото е в добро състояние</translation>
+<translation id="1131264053432022307">Копирано от вас изображение</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> неочаквано прекрати връзката.</translation>
<translation id="1161325031994447685">Свържете се отново с Wi-Fi.</translation>
<translation id="1165039591588034296">Грешка</translation>
-<translation id="1173894706177603556">Преименуване</translation>
<translation id="1175364870820465910">&amp;Печат...</translation>
<translation id="1181037720776840403">Премахване</translation>
<translation id="1197088940767939838">оранжево</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Името на устройството ви</translation>
<translation id="124116460088058876">Още езици</translation>
<translation id="1250759482327835220">За да платите по-бързо следващия път, запазете картата, името и адреса си за фактуриране в профила си в Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (синхронизирани)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Варианти във формат за командния ред</translation>
<translation id="129553762522093515">Наскоро затворени</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Опитайте да изчистите „бисквитките“ си<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Избраната сесия не съществува.</translation>
+<translation id="1320233736580025032">Prc1 (плик)</translation>
+<translation id="132301787627749051">Търсене на изображението от буферната памет</translation>
<translation id="1323433172918577554">Показване на още</translation>
<translation id="132390688737681464">Запазване и попълване на адреси</translation>
<translation id="1333989956347591814">Активността ви <ph name="BEGIN_EMPHASIS" />може да остане видима<ph name="END_EMPHASIS" /> за:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Адрес за вземане</translation>
<translation id="1348198688976932919">На хоризонта се задава сайт с опасни приложения</translation>
<translation id="1348779747280417563">Потвърждаване на името</translation>
+<translation id="1357195169723583938">Кой е използвал устройството наскоро и кога</translation>
+<translation id="1364822246244961190">Това правило е блокирано, стойността му ще бъде пренебрегната.</translation>
<translation id="1374468813861204354">предложения</translation>
+<translation id="1374692235857187091">Index-4 x 6 (пощенска картичка)</translation>
<translation id="1375198122581997741">Всичко за версията</translation>
<translation id="1376836354785490390">Показване на по-малко</translation>
<translation id="1377321085342047638">№ на картата</translation>
<translation id="138218114945450791">светлосиньо</translation>
+<translation id="1382194467192730611">USB устройството е разрешено от администратора</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> не изпрати данни.</translation>
+<translation id="140316286225361634">Сайтът <ph name="ORIGIN" /> е поискал за всички негови заявки
+да е в сила правило за сигурност, според което понастоящем той е
+опасен.</translation>
<translation id="1405567553485452995">светлозелено</translation>
<translation id="1407135791313364759">Отваряне на всички</translation>
<translation id="1413809658975081374">Грешка, свързана в поверителността</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Печат</translation>
<translation id="1455413310270022028">Гума</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Показване на още</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Избиране на адрес за доставка</translation>
+<translation id="1492194039220927094">Разпространение на правилата:</translation>
<translation id="1501859676467574491">Показване на картите от профила ви в Google</translation>
-<translation id="1506687042165942984">Показване на запазено копие на тази страница (за което е известно, че не е актуално).</translation>
<translation id="1507202001669085618">&lt;p&gt;Ще виждате това съобщение за грешка, ако използвате портал за Wi-Fi, където трябва да влезете в профил, преди да можете да преминете онлайн.&lt;/p&gt;
&lt;p&gt;За да отстраните грешката, кликнете върху &lt;strong&gt;Свързване&lt;/strong&gt; на страницата, която опитвате да отворите.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Телефонният номер е задължителен</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Дата на версията</translation>
<translation id="1521655867290435174">Google Таблици</translation>
<translation id="1527263332363067270">Изчаква се връзка…</translation>
+<translation id="1529521330346880926">10 x 15 (плик)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Тази страница изпраща съобщение</translation>
<translation id="153384715582417236">Това е всичко засега</translation>
<translation id="154408704832528245">Избиране на адрес за бърза доставка</translation>
<translation id="1549470594296187301">Трябва да активирате JavaScript, за да използвате тази функция.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Въведете дата на валидност</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Възникна проблем при показването на тази уеб страница.</translation>
<translation id="1592005682883173041">Достъп до локални данни</translation>
<translation id="1594030484168838125">Избор</translation>
<translation id="161042844686301425">синьозелено</translation>
-<translation id="1618822247301510817">Копирано от вас изображение</translation>
<translation id="1620510694547887537">Камера</translation>
<translation id="1623104350909869708">Да не се създават допълнителни диалогови прозорци от тази страница</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Прекратяване на сесията</translation>
<translation id="1639239467298939599">Зарежда се</translation>
<translation id="1640180200866533862">Правила за потребителите</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">Обикновено <ph name="SITE" /> използва шифроване за защита на информацията ви. Когато Google Chrome опита да установи връзка с/ъс <ph name="SITE" /> този път, уебсайтът върна необичайни и неправилни идентификационни данни. Това може да се случи, когато извършител на атака пробва да се представи за <ph name="SITE" /> или връзката е прекъсната от екран за вход в Wi-Fi. Информацията ви продължава да е защитена, тъй като Chrome спря връзката, преди да бъдат обменени данни.</translation>
<translation id="168841957122794586">Сертификатът на сървъра съдържа слаб криптографски ключ.</translation>
<translation id="1697532407822776718">Готово!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е от утре. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}other{Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Сертификатът му за сигурност е от # дни в бъдещето. Това може да се дължи на неправилно конфигуриране или на прехващане на връзката ви от извършител на атака.}}</translation>
<translation id="1710259589646384581">ОС</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">Документът е твърде голям за добавяне на пояснения</translation>
<translation id="1721312023322545264">Необходимо ви е разрешение от <ph name="NAME" />, за да посетите този сайт</translation>
<translation id="1721424275792716183">* Полето е задължително</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Свържете се със системния администратор.</translation>
<translation id="1740951997222943430">Въведете валиден месец на изтичане</translation>
<translation id="1743520634839655729">За да платите по-бързо следващия път, запазете картата, името и адреса си за фактуриране в профила си в Google и на това устройство.</translation>
+<translation id="1745880797583122200">Браузърът ви е управляван</translation>
<translation id="17513872634828108">Отворени раздели</translation>
<translation id="1753706481035618306">Номер на страницата</translation>
<translation id="1763864636252898013">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; операционната система на устройството ви няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Моля, актуализирайте пропуска си за синхронизиране.</translation>
<translation id="1787142507584202372">Тук ще се показват отворените ви раздели</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Име на титуляря на картата</translation>
<translation id="1821930232296380041">Заявката или параметрите й са невалидни</translation>
+<translation id="1822540298136254167">Уебсайтовете, които посещавате, и колко време прекарвате на тях</translation>
<translation id="1826516787628120939">Извършва се проверка</translation>
<translation id="1834321415901700177">Този сайт съдържа опасни програми</translation>
<translation id="1839551713262164453">Проверката на стойностите на правилата не бе успешна – възникнаха грешки</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Изчистване на данните за историята на сърфиране в Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{и още 1}other{и още #}}</translation>
<translation id="2003709556000175978">Задайте повторно паролата си сега</translation>
+<translation id="20053308747750172">Сървърът, който отваряте (<ph name="ORIGIN" />), е поискал
+за всички заявки към него да се прилага правило за сигурност. Сега обаче той
+предостави невалидно правило, което не позволява на браузъра
+да изпълни заявката ви за <ph name="SITE" />.</translation>
<translation id="2025186561304664664">За прокси сървъра е зададена автоматична конфигурация.</translation>
<translation id="2030481566774242610">Може би имахте предвид <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Проверете прокси сървъра и защитната стена<ph name="END_LINK" />.</translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Департамент</translation>
<translation id="2102134110707549001">Предложение за надеждна парола…</translation>
<translation id="2108755909498034140">Рестартирайте компютъра си.</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Карта</translation>
<translation id="2114841414352855701">Бе пренебрегнато, защото бе отменено от <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Мобилни отметки</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Редактиране на картата</translation>
<translation id="2166049586286450108">Пълен администраторски достъп</translation>
<translation id="2166378884831602661">Този сайт не може да осигури защитена връзка</translation>
+<translation id="2169984857010174799">Kaku2 (плик)</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2183608646556468874">Телефонен номер</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адрес}other{# адреса}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Телефонен номер</translation>
<translation id="2283340219607151381">Запазване и попълване на адреси</translation>
<translation id="2292556288342944218">Достъпът ви до интернет е блокиран</translation>
+<translation id="2294558542833290837">Първоначално отворената от вас връзка е необичайна</translation>
+<translation id="2297722699537546652">B5 (плик)</translation>
+<translation id="2310021320168182093">Chou2 (плик)</translation>
<translation id="2316887270356262533">Ще освободите по-малко от 1 МБ. Някои сайтове може да се заредят по-бавно при следващото ви посещение.</translation>
<translation id="2317259163369394535">Изискват се потребителско име и парола за <ph name="DOMAIN" />.</translation>
<translation id="2317583587496011522">Приемат се дебитни карти.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, изтича на <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Настройката се контролира от администратора ви</translation>
+<translation id="2346319942568447007">Копирано от вас изображение</translation>
<translation id="2349790679044093737">Има активна сесия за VR</translation>
<translation id="2354001756790975382">Други отметки</translation>
<translation id="2354430244986887761">Google Безопасно сърфиране наскоро <ph name="BEGIN_LINK" />откри опасни приложения<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Сигналът за срив, записан в/ъв <ph name="CRASH_TIME" />, не бе качен</translation>
<translation id="2367567093518048410">Ниво</translation>
<translation id="2378238891085281592">Преминахте в режим на частно сърфиране</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Зададено по подразбиране в корпоративна среда</translation>
<translation id="2386255080630008482">Сертификатът на сървъра е анулиран.</translation>
<translation id="2392959068659972793">Да се показват правилата без зададена стойност</translation>
<translation id="239429038616798445">Този начин на доставка не се поддържа. Опитайте с друг.</translation>
<translation id="2396249848217231973">&amp;Отмяна на изтриването</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е сертификатът му за сигурност да е оттеглен. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="2418081434543109369">Сървърът, който отваряте (<ph name="ORIGIN" />), е поискал
+за всички заявки към него да се прилага правило за сигурност. Той обаче
+не успя да предостави правило, така че браузърът не може да изпълни
+заявката ви за <ph name="SITE" />.</translation>
<translation id="244665789865330679">Устройството и профилът ви се управляват от <ph name="ENROLLMENT_DOMAIN" />. Това значи, че администраторът ви може да ги конфигурира отдалечено.</translation>
<translation id="2463193859425327265">Промяна на началната страница</translation>
<translation id="2463739503403862330">Попълване</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Избиране на начин на бърза доставка</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Стартирайте мрежова диагностика<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Превод на тази страница</translation>
<translation id="2479410451996844060">Невалиден URL адрес за търсене.</translation>
<translation id="2482878487686419369">Известия</translation>
<translation id="248348093745724435">Правила за компютъра</translation>
+<translation id="2485387744899240041">Потребителските имена за устройството и браузъра ви</translation>
<translation id="2491120439723279231">Сертификатът на сървъра съдържа грешки.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">Синтактичен анализ на JSON</translation>
<translation id="2495093607237746763">Ако поставите отметка, Chromium ще съхранява на това устройство копие на картата ви с цел по-бързо попълване на формуляри.</translation>
<translation id="2498091847651709837">Сканиране на нова карта</translation>
<translation id="2501278716633472235">Назад</translation>
<translation id="2503184589641749290">Приемани дебитни и предплатени карти</translation>
<translation id="2515629240566999685">Проверете сигнала в района.</translation>
-<translation id="2516852381693169964">Търсене на изображението чрез <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Запазено само на това устройство</translation>
<translation id="2524461107774643265">Добавяне на още информация</translation>
<translation id="2536110899380797252">Добавяне на адрес</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">ID на API за директории:</translation>
<translation id="2597378329261239068">Този документ е защитен с парола. Моля, въведете я.</translation>
<translation id="2609632851001447353">Вариации</translation>
+<translation id="2618023639789766142">C10 (плик)</translation>
<translation id="2625385379895617796">Часовникът ви е напред</translation>
<translation id="2634124572758952069">IP адресът на сървъра на <ph name="HOST_NAME" /> не можа да бъде намерен.</translation>
<translation id="2639739919103226564">Състояние:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Затворете другите раздели или приложения.</translation>
<translation id="267371737713284912">натиснете <ph name="MODIFIER_KEY_DESCRIPTION" /> за отмяна</translation>
<translation id="2674170444375937751">Наистина ли искате да изтриете тези страници от историята си?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Излизане</translation>
+<translation id="2684561033061424857">11 x 12</translation>
<translation id="2699302886720511147">Приемани карти</translation>
<translation id="2702801445560668637">Списък за четене</translation>
<translation id="2704283930420550640">Стойността не съответства на формата.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Премахване на избраните елементи</translation>
<translation id="277133753123645258">Начин на доставка</translation>
<translation id="277499241957683684">Липсващ запис за устройството</translation>
-<translation id="2781030394888168909">Експортиране за Mac OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Връзката бе възстановена.</translation>
<translation id="2788784517760473862">Приемани кредитни карти</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">Връзката е шифрована и удостоверена посредством <ph name="CIPHER" /> и използва <ph name="KX" /> като механизъм за обмен на ключове.</translation>
<translation id="2835170189407361413">Изчистване на формуляра</translation>
<translation id="2847118875340931228">Отваряне на прозорец в режим „инкогнито“</translation>
+<translation id="2850739647070081192">Invite (плик)</translation>
<translation id="2851634818064021665">Необходимо ви е разрешение, за да посетите този сайт</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Да се запази ли картата?</translation>
<translation id="2903493209154104877">Адреси</translation>
<translation id="290376772003165898">Страницата не е на <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Начин на бърза доставка</translation>
<translation id="2928905813689894207">Адрес за фактуриране</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; сертификатът му за сигурност е от <ph name="DOMAIN2" />. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="2948083400971632585">Можете да деактивирате всички конфигурирани за дадена връзка прокси сървъри от страницата „Настройки“.</translation>
<translation id="2955913368246107853">Затваряне на лентата за търсене</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (плик)</translation>
<translation id="3024663005179499861">Грешен тип на правилото</translation>
<translation id="3037605927509011580">Ужас!</translation>
<translation id="3041612393474885105">Информация за сертификата</translation>
+<translation id="3060227939791841287">C9 (плик)</translation>
<translation id="3064966200440839136">Ще напуснете режим „инкогнито“, за да платите във външно приложение. Искате ли да продължите?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{Няма}=1{1 парола}other{# пароли}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Добавяне на адрес за вземане</translation>
<translation id="3105172416063519923">ID на актива:</translation>
<translation id="3109728660330352905">Нямате пълномощия за преглед на тази страница.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> на <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Анулиране на плащането</translation>
<translation id="3207960819495026254">С отметка</translation>
-<translation id="3209375525920864198">Моля, въведете валидно име на сесия.</translation>
+<translation id="321912867715453276">Предупреждение: Съществува повече от един източник за правилото, но стойностите са едни и същи.</translation>
<translation id="3225919329040284222">Сървърът предостави сертификат, който не съответства на вградените очаквания. Те са включени за определени уебсайтове с голяма степен на сигурност, за да ви предпазим.</translation>
<translation id="3226128629678568754">Натиснете бутона за презареждане, за да изпратите отново данните, необходими за отварянето на страницата.</translation>
<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Преводът не бе успешен, защото страницата вече е на <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Информацията за версията на устройството и браузъра</translation>
<translation id="323107829343500871">Въведете кода за проверка за <ph name="CREDIT_CARD" /></translation>
<translation id="3234666976984236645">Важното съдържание на този сайт да се открива винаги</translation>
<translation id="3254409185687681395">Запазване на отметка към тази страница</translation>
<translation id="3270847123878663523">&amp;Отмяна на пренареждането</translation>
+<translation id="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Добавяне на името на картодържателя</translation>
<translation id="3287510313208355388">Изтегляне, когато съм онлайн</translation>
<translation id="3293642807462928945">Научете повече за правилото <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Няма намерени резултати от търсенето</translation>
-<translation id="3305707030755673451">На <ph name="TIME" /> данните ви бяха шифровани с пропуска ви за синхронизиране. Въведете го, за да стартирате синхронизирането.</translation>
<translation id="3320021301628644560">Добавяне на адреса за фактуриране</translation>
<translation id="3324983252691184275">пурпурно</translation>
<translation id="3338095232262050444">Има защита</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Възстановяване на редактирането</translation>
<translation id="342781501876943858">Chromium препоръчва да зададете повторно паролата си, ако сте я използвали и на други сайтове.</translation>
<translation id="3431636764301398940">Запазване на картата на това устройство</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Собственикът на това устройство е изключил играта с динозавъра.</translation>
<translation id="3447884698081792621">Показване на сертификата (издаден от <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Интервал на извличане:</translation>
+<translation id="3456231139987291353">Number-11 (плик)</translation>
<translation id="3461824795358126837">Маркер за открояване</translation>
<translation id="3462200631372590220">Скриване на подробностите</translation>
<translation id="3467763166455606212">Трябва да въведете името на титуляря на картата</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Приемат се кредитни и предплатени карти.</translation>
<translation id="3582930987043644930">Добавете име</translation>
<translation id="3583757800736429874">&amp;Възстановяване на преместването</translation>
+<translation id="35866233670761917">Съдържанието на посещаваните от вас уебсайтове не е видимо за администраторите</translation>
<translation id="3586931643579894722">Скриване на подробностите</translation>
+<translation id="3592413004129370115">Italian (плик)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Размер 2</translation>
<translation id="3615877443314183785">Въведете валидна дата на изтичане</translation>
<translation id="36224234498066874">Изчистване на данните за сърфирането...</translation>
<translation id="362276910939193118">Цялата история</translation>
-<translation id="3623476034248543066">Показване на стойността</translation>
<translation id="3630155396527302611">Ако браузърът вече е в списъка с програми с разрешен достъп до мрежата, опитайте
да го премахнете оттам и да го добавите отново.</translation>
+<translation id="3640766068866876100">Index-4 x 6-Ext</translation>
<translation id="3650584904733503804">Потвърждаването е успешно</translation>
<translation id="3655670868607891010">Ако виждате това често, опитайте <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Ревизия</translation>
<translation id="366077651725703012">Актуализиране на кредитната карта</translation>
<translation id="3676592649209844519">Идент. № на устройството:</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ли искате да отворите?</translation>
<translation id="3678029195006412963">Заявката не можа да бъде подписана</translation>
<translation id="3678529606614285348">Отворете страницата в нов прозорец в режим „инкогнито“ (Ctrl-Shift-N).</translation>
<translation id="3679803492151881375">Сигналът за срив е записан в/ъв <ph name="CRASH_TIME" /> и качен в/ъв <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Използваната от вас мрежа може да изисква да посетите страницата й за вход.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> „<ph name="TITLE" />“ <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Зарежда се...</translation>
+<translation id="3709599264800900598">Копиран от вас текст</translation>
<translation id="3712624925041724820">Лицензите са изчерпани</translation>
<translation id="3714780639079136834">Включете мобилните данни или Wi-Fi.</translation>
<translation id="3715597595485130451">Свързване с Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Проверете конфигурацията на прокси сървъра, защитната стена и DNS<ph name="END_LINK" />.</translation>
<translation id="372429172604983730">Тази грешка може да се дължи на приложение, като например антивирусна програма или софтуер за защитна стена или за филтриране на съдържание в мрежата.</translation>
+<translation id="373042150751172459">B4 (плик)</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="3745099705178523657">След като потвърдите картата си, данните за нея от профила ви в Google ще бъдат споделени с този сайт.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Изтича на <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Размер 16</translation>
+<translation id="3797522431967816232">Prc3 (плик)</translation>
<translation id="3807873520724684969">Блокирано бе вредно съдържание.</translation>
<translation id="3810973564298564668">Управление</translation>
<translation id="382518646247711829">Ако използвате прокси сървър...</translation>
<translation id="3828924085048779000">Не може пропускът да не се попълни.</translation>
+<translation id="3831915413245941253">От <ph name="ENROLLMENT_DOMAIN" /> са инсталирани разширения за допълнителни функции. Разширенията имат достъп до част от данните ви.</translation>
<translation id="385051799172605136">Назад</translation>
<translation id="3858027520442213535">Актуализиране на датата и часа</translation>
<translation id="3884278016824448484">Идентификационният номер на устройството е несъвместим</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">Заявката ви за достъп до този сайт бе изпратена до <ph name="NAME" /></translation>
<translation id="3890664840433101773">Добавяне на имейл адрес</translation>
<translation id="3901925938762663762">Картата е с изтекла валидност</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> – <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Винаги да се извежда запитване за този сайт</translation>
<translation id="3949571496842715403">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. В сертификата му за сигурност не са посочени алтернативни имена на обекта. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака.</translation>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{Няма}=1{От 1 сайт }other{От # сайта }}</translation>
<translation id="397105322502079400">Изчислява се...</translation>
<translation id="3973234410852337861">Хостът <ph name="HOST_NAME" /> е блокиран</translation>
-<translation id="3984550557525787191">Вече съществува сесия с това име.</translation>
<translation id="3987940399970879459">По-малко от 1 МБ</translation>
+<translation id="4008849406247176967">Предупреждение: Съществува повече от един източник с несъвместими стойности за това правило!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 уеб страница в близост}other{# уеб страници в близост}}</translation>
<translation id="4030383055268325496">&amp;Отмяна на добавянето</translation>
+<translation id="4032320456957708163">Браузърът ви се управлява от <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Ключ „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (плик)</translation>
<translation id="4067947977115446013">Добавяне на валиден адрес</translation>
<translation id="4072486802667267160">При обработването на поръчката ви възникна грешка. Моля, опитайте отново.</translation>
<translation id="4075732493274867456">Клиентът и сървърът не поддържат обща версия или пакет за шифроване за протокола SSL.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">лилаво</translation>
<translation id="4165986682804962316">Настройки за сайта</translation>
<translation id="4171400957073367226">Невалиден подпис за потвърждаване</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{още <ph name="ITEM_COUNT" /> елемент}other{още <ph name="ITEM_COUNT" /> елемента}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> – <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;Възстановяване на преместването</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Проверете конфигурацията на защитната стена и антивирусния софтуер<ph name="END_LINK" />.</translation>
+<translation id="4215751373031079683">7 x 9 (плик)</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="4221630205957821124">&lt;h4&gt;Стъпка 1: Влезте в портала&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Повторно задаване на паролата</translation>
<translation id="4280429058323657511">, изтича: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Тази карта е запазена в профила ви в Google}other{Тези карти са запазени в профила ви в Google}}</translation>
+<translation id="42981349822642051">Разгъване</translation>
+<translation id="4302965934281694568">Chou3 (плик)</translation>
<translation id="4305817255990598646">Превключване</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Блокиране (по подразбиране)</translation>
+<translation id="4318566738941496689">Името и мрежовия адрес на устройството ви</translation>
<translation id="4325863107915753736">Намирането на статията не бе успешно</translation>
<translation id="4326324639298822553">Проверете датата на валидност и опитайте отново</translation>
<translation id="4331708818696583467">Няма защита</translation>
<translation id="4340982228985273705">Този компютър не се управлява корпоративно, така че правилото може да инсталира автоматично само разширения от уеб магазина на Chrome. URL адресът за актуализация за уеб магазина на Chrome е <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Приемани кредитни карти</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Извършители на атака, използващи този сайт, може да опитат да инсталират опасни програми на компютъра ви, които крадат или изтриват информацията ви (например снимки, пароли, съобщения и номера на кредитни карти).</translation>
<translation id="4358461427845829800">Управление на начините на плащане...</translation>
+<translation id="4367563149485757821">Number-12 (плик)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">Очаквана е стойност от тип <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">Направихте опит да се свържете с/ъс <ph name="DOMAIN" />, но сървърът предoстави сертификат, анулиран от издателя си. Това означава, че в никакъв случай не трябва да се доверявате на представените от сървъра идентификационни данни за сигурност. Възможно е да сте се свързали с извършител на атака.</translation>
<translation id="4378154925671717803">Телефон</translation>
<translation id="4406896451731180161">резултата от търсенето</translation>
-<translation id="4406972042435603828">Администраторите ви са инсталирали разширения с големи възможности.</translation>
<translation id="4408413947728134509">„Бисквитки“ <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Адрес за вземане</translation>
<translation id="4424024547088906515">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; Chrome няма доверие на сертификата му за сигурност. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="443121186588148776">Сериен порт</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> не прие сертификата ви за вход или е възможно да не е предоставен такъв.</translation>
<translation id="4434045419905280838">Изскач. прозорци и пренасочвания</translation>
+<translation id="4435702339979719576">пощенска картичка)</translation>
<translation id="443673843213245140">Използването на прокси сървър е деактивирано, но е посочена изрична негова конфигурация.</translation>
<translation id="445100540951337728">Приемани дебитни карти</translation>
+<translation id="4466881336512663640">Промените във формуляра ще бъдат заличени. Наистина ли искате да продължите?</translation>
<translation id="4482953324121162758">Този сайт няма да се превежда.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Невалиден URL адрес. Трябва да е URL адрес със стандартна схема, напр. http://example.com или https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Грешка при потвърждаването: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Свържете се със системния администратор.</translation>
<translation id="450710068430902550">Споделяне с администратор</translation>
+<translation id="4510487217173779431">Chou4 (плик)</translation>
<translation id="4515275063822566619">Картите и адресите са от Chrome и профила ви в Google (<ph name="ACCOUNT_EMAIL" />). Можете да ги управлявате от <ph name="BEGIN_LINK" />настройките<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (плик)</translation>
<translation id="4522570452068850558">Подробности</translation>
<translation id="4524805452350978254">Управление на картите</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Опитайте да деактивирате разширенията.</translation>
+<translation id="4559332380232738994">10 x 11</translation>
<translation id="457875822857220463">Бърза доставка</translation>
+<translation id="4579056131138995126">Personal (плик)</translation>
<translation id="4582204425268416675">Премахване на картата</translation>
<translation id="4587425331216688090">Адресът да се премахне ли от Chrome?</translation>
<translation id="4592951414987517459">Връзката ви с/ъс <ph name="DOMAIN" /> е шифрована със съвременен криптографски пакет.</translation>
<translation id="4594403342090139922">&amp;Отмяна на изтриването</translation>
<translation id="4597348597567598915">Размер 8</translation>
+<translation id="4600854749408232102">C6/C5 (плик)</translation>
<translation id="4646534391647090355">Към изтеглянията</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; сертификатът му за сигурност съдържа грешки. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
<translation id="467809019005607715">Google Презентации</translation>
<translation id="4690462567478992370">Спиране на използването на невалиден сертификат</translation>
+<translation id="4691835149146451662">Architecture-A (плик)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Връзката ви бе прекъсната</translation>
<translation id="471880041731876836">Нямате разрешение да посетите този сайт</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Стартирайте мрежова диагностика в Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Презареждане на правилата</translation>
<translation id="4728558894243024398">Платформа</translation>
+<translation id="4731967714531604179">Prc2 (плик)</translation>
<translation id="4736825316280949806">Рестартирайте Chromium.</translation>
<translation id="473775607612524610">Актуализиране</translation>
<translation id="4738601419177586157">Предложение за търсене на „<ph name="TEXT" />“</translation>
<translation id="4742407542027196863">Управление на паролите…</translation>
<translation id="4744603770635761495">Път към изпълнимия файл</translation>
+<translation id="4746351372139058112">Messages</translation>
<translation id="4750917950439032686">Информацията ви (например пароли или номера на кредитни карти) е частна, когато се изпраща до този сайт.</translation>
<translation id="4756388243121344051">&amp;История</translation>
<translation id="4758311279753947758">Добавяне на информация за връзка</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">До уеб страницата на адрес <ph name="URL" /> може временно да няма достъп или да е преместена за постоянно на нов уеб адрес.</translation>
<translation id="4771973620359291008">Възникна неизвестна грешка.</translation>
<translation id="4785689107224900852">Превключване към този раздел</translation>
-<translation id="4792143361752574037">Възникна проблем при осъществяването на достъп до файловете от сесията. Понастоящем запазването на диска е деактивирано. Моля, презаредете страницата, за да опитате отново.</translation>
<translation id="4798078619018708837">Въведете датата на валидност и кода за проверка за <ph name="CREDIT_CARD" />, за да актуализирате данните за картата си. След като я потвърдите, данните за нея от профила ви в Google ще бъдат споделени с този сайт.</translation>
<translation id="4800132727771399293">Прегледайте датата на валидност и кода за проверка и оптитайте отново</translation>
+<translation id="480334179571489655">Грешка поради правило на източника</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Отваряне</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Няма резултати</translation>
<translation id="4950898438188848926">Бутон за превключване между раздели. Натиснете Enter, за да преминете към отворения раздел – <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Действия</translation>
-<translation id="495832697253704892">Отчитане на разширенията</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Разгъване на списъка</translation>
<translation id="4974590756084640048">Повторно активиране на предупрежденията</translation>
+<translation id="4984339528288761049">Prc5 (плик)</translation>
<translation id="4989163558385430922">Преглед на всички</translation>
<translation id="4989809363548539747">Тази приставка не се поддържа</translation>
-<translation id="4996230189582812866">Отчитане</translation>
<translation id="5002932099480077015">Ако настройката е активирана, копие на картата ви ще се съхранява в Chrome на това устройство с цел по-бързо попълване на формуляри.</translation>
-<translation id="5014174725590676422">Показан е екранът при първо стартиране на Google Асистент в Chrome</translation>
<translation id="5015510746216210676">Име на компютъра:</translation>
+<translation id="5017554619425969104">Копиран от вас текст</translation>
<translation id="5018422839182700155">Тази страница не може да се отвори</translation>
<translation id="5019198164206649151">Допълнителното хранилище е в лошо състояние</translation>
<translation id="5023310440958281426">Проверете правилата на администратора</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Локално контекстно меню <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Разрешаване</translation>
<translation id="5040262127954254034">Поверителност</translation>
+<translation id="5043480802608081735">Копирана от вас връзка</translation>
<translation id="5045550434625856497">Грешна парола</translation>
<translation id="5056549851600133418">Статии за вас</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Проверете адреса на прокси сървъра<ph name="END_LINK" />.</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="5097099694988056070">Статистически данни за устройството, например за използването на процесора/RAM паметта</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Устройството ви се управлява от <ph name="ENROLLMENT_DOMAIN" />, а профилът ви се управлява от <ph name="ACCOUNT_DOMAIN" />. Това означава, че администраторите може отдалечено да конфигурират устройството и профила ви.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 бита)</translation>
-<translation id="5128122789703661928">Сесията с това име не е валидна за изтриване.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Управление на адресите...</translation>
+<translation id="5138227688689900538">Показване на по-малко</translation>
<translation id="5141240743006678641">Синхронизираните пароли да се шифроват с идентификационните ви данни за Google</translation>
<translation id="5145883236150621069">В отговора за правилото присъства код на грешка</translation>
+<translation id="515292512908731282">C4 (плик)</translation>
<translation id="5159010409087891077">Отворете страницата в нов прозорец в режим „инкогнито“ (⇧⌘N).</translation>
<translation id="516920405563544094">Въведете кода за проверка за <ph name="CREDIT_CARD" />. След като потвърдите картата си, данните за нея от профила ви в Google ще бъдат споделени с този сайт.</translation>
<translation id="5169827969064885044">Възможно е да загубите достъп до профила си в организацията или самоличността ви да бъде открадната. Chrome препоръчва да промените паролата си сега.</translation>
<translation id="5171045022955879922">Търсете или въведете URL адрес</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Машината</translation>
<translation id="5179510805599951267">Не е на <ph name="ORIGINAL_LANGUAGE" />? Подайте сигнал за тази грешка</translation>
<translation id="5190835502935405962">Лента на отметките</translation>
-<translation id="5200263511887412697">съставя списък с потребителите на устройството, които наскоро са влизали в профилите си</translation>
+<translation id="519422657042045905">Няма достъп до режима за пояснения</translation>
<translation id="5201306358585911203">Страница, вградена в тази страница, изпраща съобщение</translation>
<translation id="5205222826937269299">Името е задължително</translation>
<translation id="5215116848420601511">Начини на плащане и адреси посредством Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Имейл адресът е задължителен</translation>
<translation id="5230733896359313003">Адрес за доставка</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12 x 19</translation>
<translation id="5250209940322997802">„Свързване с мрежа“</translation>
<translation id="5251803541071282808">Облак</translation>
+<translation id="5252000469029418751">C7 (плик)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Мрежовите адреси</translation>
<translation id="5285570108065881030">Показване на всички запазени пароли</translation>
<translation id="5287240709317226393">Показване на „бисквитките“</translation>
<translation id="5288108484102287882">При проверката на стойностите на правилата възникнаха предупреждения</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> от <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Избиране на информация за връзка</translation>
<translation id="5327248766486351172">Име</translation>
+<translation id="5329858041417644019">Браузърът ви не се управлява</translation>
<translation id="5332219387342487447">Начин за доставка</translation>
+<translation id="5334013548165032829">Подробните системни регистрационни файлове</translation>
<translation id="5344579389779391559">Тази страница може да опита да ви таксува пари</translation>
<translation id="5355557959165512791">В момента не можете да посетите сайта <ph name="SITE" />, защото сертификатът му е анулиран. Обикновено грешките в мрежата и атаките срещу нея са временни, така че тази страница вероятно ще работи по-късно.</translation>
<translation id="536296301121032821">Съхраняването на настройките за правилото не бе успешно</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">„Часовникът ви е назад“, „Часовникът ви е напред“ или „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;“</translation>
<translation id="5384855140246857529">За да използвате картите си на всичките си устройства, влезте в профила си и включете синхронизирането.</translation>
<translation id="5386426401304769735">Веригата от сертификати за този сайт съдържа сертификат, подписан с SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">Сървърът не можа да докаже, че е <ph name="DOMAIN" />. Понастоящем сертификатът му за сигурност не е валиден. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от извършител на атака.</translation>
<translation id="5421136146218899937">Изчистване на данните за сърфирането...</translation>
<translation id="5430298929874300616">Премахване на отметката</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Невалидно</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Възстановяване на редактирането</translation>
+<translation id="5478437291406423475">B6/C4 (плик)</translation>
<translation id="5481076368049295676">Въпросното съдържание може да се опита да инсталира опасен софтуер на устройството ви, който да открадне или изтрие информацията ви. <ph name="BEGIN_LINK" />Показване въпреки това<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Добавяне на валиден адрес</translation>
<translation id="5490432419156082418">Адреси и др.</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Опитайте да се свържете със системния си администратор.</translation>
<translation id="549333378215107354">Размер 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Управлявани отметки</translation>
<translation id="5510766032865166053">Възможно е да е преместен или изтрит.</translation>
<translation id="5523118979700054094">Име на правилото</translation>
<translation id="552553974213252141">Текстът правилно ли бе извлечен?</translation>
+<translation id="553484882784876924">Prc6 (плик)</translation>
<translation id="5540224163453853">Заявената статия не можа да бъде намерена.</translation>
<translation id="5541546772353173584">Добавяне на имейл адрес</translation>
<translation id="5545756402275714221">Статии за вас</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Редактиране на адреса</translation>
<translation id="5598944008576757369">Избиране на начин на плащане</translation>
<translation id="560412284261940334">Управлението не се поддържа</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">Проверете връзката.</translation>
<translation id="5610807607761827392">Можете да управлявате картите и адресите от <ph name="BEGIN_LINK" />настройките<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> ви пренасочи твърде много пъти.</translation>
<translation id="5629630648637658800">Зареждането на настройките за правилото не бе успешно</translation>
<translation id="5631439013527180824">Невалидно означение за управление на устройството</translation>
+<translation id="5632627355679805402">Данните ви са шифровани с <ph name="BEGIN_LINK" />паролата ви за Google<ph name="END_LINK" /> от <ph name="TIME" />. Въведете я, за да стартирате синхронизирането.</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="563324245173044180">Блокирахме измамно съдържание.</translation>
<translation id="5659593005791499971">Имейл</translation>
+<translation id="5663614846592581799">9 x 11 (плик)</translation>
+<translation id="5663955426505430495">Администраторът на това устройство е инсталирал разширения за допълнителни функции. Разширенията имат достъп до част от данните ви.</translation>
<translation id="5675650730144413517">Тази страница не работи</translation>
+<translation id="5684874026226664614">Ами сега! Тази страница не можа да се преведе.</translation>
<translation id="5685654322157854305">Добавяне на адрес за доставка</translation>
<translation id="5689199277474810259">Експортиране във формат JSON</translation>
<translation id="5689516760719285838">Местоположение</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Самоличността на този уебсайт не е потвърдена.</translation>
<translation id="5719499550583120431">Приемат се предплатени карти.</translation>
<translation id="5720705177508910913">Текущият потребител</translation>
+<translation id="5728056243719941842">C5 (плик)</translation>
<translation id="5730040223043577876">Chrome препоръчва да зададете повторно паролата си, ако сте я използвали и на други сайтове.</translation>
<translation id="5732392974455271431">Родителите ви могат да го отблокират за вас</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Запазване на картата в профила ви в Google}other{Запазване на картите в профила ви в Google}}</translation>
<translation id="5763042198335101085">Въведете валиден имейл адрес</translation>
<translation id="5765072501007116331">За да видите начините на бърза доставка и изискванията, изберете адрес</translation>
-<translation id="5770114862687765385">Файлът изглежда е повреден. Кликнете върху бутона за повторно задаване, за да рестартирате сесията.</translation>
<translation id="5778550464785688721">Пълен контрол над MIDI устройства</translation>
<translation id="578305955206182703">кехлибарено</translation>
<translation id="57838592816432529">Заглушаване</translation>
<translation id="5784606427469807560">При потвърждаването на картата ви възникна проблем. Проверете връзката си с интернет и опитайте отново.</translation>
<translation id="5785756445106461925">Освен това тази страница включва други ресурси, които не са защитени. Докато се предават, те могат да бъдат видени от други хора и да бъдат модифицирани от извършител на атака, така че да се промени изгледът на страницата.</translation>
<translation id="5786044859038896871">Искате ли да се попълнят данните за кредитната ви карта?</translation>
+<translation id="5798290721819630480">Да се отхвърлят ли промените?</translation>
<translation id="5798683403665926540">Променете началната страница от настройките на Chrome</translation>
<translation id="5803412860119678065">Искате ли да се попълнят данните за <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Разрешения</translation>
<translation id="5810442152076338065">Връзката ви с/ъс <ph name="DOMAIN" /> е шифрована с остарял криптографски пакет.</translation>
<translation id="5813119285467412249">&amp;Възстановяване на добавянето</translation>
<translation id="5838278095973806738">Не ви препоръчваме да въвеждате поверителна информация в този сайт (например пароли или номера на кредитни карти), тъй като може да бъде открадната от извършители на атаки.</translation>
+<translation id="5860033963881614850">Изключено</translation>
<translation id="5863847714970149516">На страницата, която искате да посетите, е възможно да ви бъдат удържани средства</translation>
<translation id="5866257070973731571">Добавяне на телефонен номер</translation>
<translation id="5869405914158311789">Няма достъп до този сайт</translation>
<translation id="5869522115854928033">Запазени пароли</translation>
<translation id="5887400589839399685">Картата бе запазена</translation>
-<translation id="5893718151540690985">съставя списък с мрежовите интерфейси, включващ типовете и хардуерните им адреси</translation>
<translation id="5893752035575986141">Приемат се кредитни карти.</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="5916664084637901428">Включено</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Картата да се запази ли в профила в Google?</translation>
<translation id="5922853866070715753">Почти готово</translation>
<translation id="5932224571077948991">На сайта се показват натрапчиви или подвеждащи реклами</translation>
-<translation id="5939518447894949180">Нулиране</translation>
<translation id="5946937721014915347">Отваря се <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Не е възможно регистриране с профил на потребител (налице е лиценз в пакет).</translation>
<translation id="5967592137238574583">Редактиране на информацията за връзка</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Намаляване на мащаба</translation>
<translation id="5977489021191000276">Устройството ви не се управлява от администратор.</translation>
<translation id="5977976211062815271">На това устройство</translation>
+<translation id="5980920751713728343">Index-3 x 5</translation>
<translation id="598637245381783098">Приложението за плащане не може да се отвори</translation>
<translation id="5989320800837274978">Не са посочени нито фиксирани прокси сървъри, нито URL адрес на скрипт във формат .pac.</translation>
<translation id="5990559369517809815">Заявките към сървъра са блокирани от разширение.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">отчита статистически данни за хардуера, като използване на централния процесор и RAM паметта</translation>
<translation id="6034000775414344507">светлосиво</translation>
+<translation id="6034283069659657473">10 x 14 (плик)</translation>
<translation id="6039846035001940113">Ако проблемът не бъде отстранен, свържете се със собственика на сайта.</translation>
<translation id="6040143037577758943">Затваряне</translation>
<translation id="6044573915096792553">Размер 12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">В момента не можете да посетите <ph name="SITE" />, защото уебсайтът използва метод за допълнително потвърждаване на сертификатите. Обикновено грешките в мрежата и атаките срещу нея са временни, така че тази страница вероятно ще работи по-късно.</translation>
<translation id="6058977677006700226">Искате ли да използвате картите си на всичките си устройства?</translation>
<translation id="6059925163896151826">USB устройства</translation>
-<translation id="6071091556643036997">Типът на правилата е невалиден.</translation>
<translation id="6080696365213338172">Осъществихте достъп до съдържанието посредством осигурен от администратора сертификат. Данните, които предоставите на <ph name="DOMAIN" />, могат да бъдат прихванати от администратора ви.</translation>
<translation id="6094273045989040137">Добавяне на пояснения</translation>
<translation id="610911394827799129">В профила ви в Google може да има други видове история на сърфиране, съхранявани на адрес <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Информация за инсталираните разширения и приставки</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{Няма}=1{1 парола (синхронизирана)}other{# пароли (синхронизирани)}}</translation>
<translation id="6146055958333702838">Проверете всички кабели и рестартирайте маршрутизаторите, модемите или другите мрежови
устройства, които може да използвате.</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Ще освободите по-малко от <ph name="SIZE" />. Някои сайтове може да се заредят по-бавно при следващото ви посещение.</translation>
<translation id="6337534724793800597">Филтриране на правилата по име</translation>
<translation id="6358450015545214790">Какво означават тези неща?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Възможно е таксуване.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{още 1 предложение}other{още # предложения}}</translation>
<translation id="6387754724289022810">За да платите по-бързо следващия път, запазете картата и адреса си за фактуриране в профила си в Google и на това устройство.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Редактиране на отметката</translation>
+<translation id="6406765186087300643">C0 (плик)</translation>
<translation id="6410264514553301377">Въвеждане на датата на валидност и кода за проверка за <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Попитахте родителя си дали може да посетите този сайт</translation>
<translation id="6417515091412812850">Не може да се провери дали сертификатът е анулиран.</translation>
<translation id="6433490469411711332">Редактиране на информацията за връзка</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> отказа да установи връзка.</translation>
+<translation id="6434309073475700221">Отхвърляне</translation>
+<translation id="6446163441502663861">Kahu (плик)</translation>
<translation id="6446608382365791566">Добавяне на още информация</translation>
<translation id="6447842834002726250">„Бисквитки“</translation>
<translation id="6451458296329894277">Потвърдете повторното изпращане на формуляра</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Рестартирайте Chrome.</translation>
<translation id="6529602333819889595">&amp;Възстановяване на изтриването</translation>
<translation id="6534179046333460208">Предложения от Физическата мрежа</translation>
+<translation id="6556866813142980365">Възстановяване</translation>
<translation id="6563469144985748109">Мениджърът ви все още не е одобрил заявката</translation>
<translation id="6569060085658103619">Преглеждате страница на разширение</translation>
+<translation id="6578796323535178455">C2 (плик)</translation>
<translation id="6579990219486187401">светлорозово</translation>
+<translation id="6583674473685352014">B6 (плик)</translation>
+<translation id="6587923378399804057">Копирана от вас връзка</translation>
+<translation id="6591833882275308647">Устройството ви <ph name="DEVICE_TYPE" /> не е управлявано</translation>
<translation id="6596325263575161958">Опции за шифроване</translation>
<translation id="6604181099783169992">Сензори за движение или светлина</translation>
+<translation id="6609880536175561541">Prc7 (плик)</translation>
<translation id="6624427990725312378">Информация за връзка</translation>
<translation id="6626291197371920147">Добавяне на валиден номер на карта</translation>
<translation id="6628463337424475685">Търсене с/ъс <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Това правило е оттеглено.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Няма}=1{От 1 сайт (няма да излезете от профила си в Google)}other{От # сайта (няма да излезете от профила си в Google)}}</translation>
<translation id="6657585470893396449">Парола</translation>
+<translation id="6670613747977017428">Назад към безопасната страница.</translation>
<translation id="6671697161687535275">Предложението за формуляри да се премахне ли от Chromium?</translation>
<translation id="6685834062052613830">Излизане от профила и завършване на настройването</translation>
<translation id="6710213216561001401">Предишна</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Означение за регистриране:</translation>
<translation id="6711464428925977395">Нещо не е наред с прокси сървъра или адресът е неправилен.</translation>
<translation id="6723740634201835758">В профила ви в Google</translation>
+<translation id="6738516213925468394">На <ph name="TIME" /> данните ви бяха шифровани с <ph name="BEGIN_LINK" />пропуска ви за синхронизиране<ph name="END_LINK" />. Въведете го, за да стартирате синхронизирането.</translation>
<translation id="674375294223700098">Неизвестна грешка в сертификата на сървъра.</translation>
<translation id="6744009308914054259">Докато чакате да се установи връзка, можете да посетите страницата „Изтегляния“, за да четете офлайн статии.</translation>
<translation id="6753269504797312559">Стойност за правилото</translation>
<translation id="6757797048963528358">Устройството ви премина в спящ режим.</translation>
+<translation id="6768213884286397650">Hagaki (пощенска картичка)</translation>
<translation id="6778737459546443941">Родителят ви все още не е одобрил заявката</translation>
<translation id="67862343314499040">виолетово</translation>
+<translation id="6786747875388722282">Разширения</translation>
<translation id="679355240208270552">Бе пренебрегнато, защото основното търсене не е активирано чрез правило.</translation>
<translation id="681021252041861472">Задължително поле</translation>
<translation id="6810899417690483278">Идент. № на персонализирането</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Устройство</translation>
<translation id="6970216967273061347">Окръг</translation>
<translation id="6973656660372572881">Посочени са както фиксирани прокси сървъри, така и URL адрес на скрипт във формат .pac.</translation>
+<translation id="6973932557599545801">За съжаление, не мога да помогна. Моля, продължете ръчно.</translation>
<translation id="6979158407327259162">Google Диск</translation>
<translation id="6979440798594660689">Заглушаване (стандартно)</translation>
<translation id="6984479912851154518">Ще напуснете режима на частно сърфиране, за да платите във външно приложение. Искате ли да продължите?</translation>
<translation id="6989763994942163495">Показване на разширените настройки...</translation>
+<translation id="6993898126790112050">6 x 9 (плик)</translation>
<translation id="6996312675313362352">Винаги да се превежда от <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Тези таксувания може да са еднократни или повтарящи се и е възможно да не са явни.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Скриване</translation>
<translation id="7108819624672055576">Разрешено от разширение</translation>
<translation id="7111012039238467737">(валиден)</translation>
+<translation id="7118618213916969306">Търсене на URL адреса от буферната памет, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">Затворете другите раздели или програми.</translation>
<translation id="7129409597930077180">Този адрес за доставка не се поддържа. Изберете друг.</translation>
<translation id="7135130955892390533">Показване на състоянието</translation>
<translation id="7138472120740807366">Начин на бърза доставка</translation>
<translation id="7139724024395191329">Емирство</translation>
+<translation id="7152423860607593928">Number-14 (плик)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">лавандулово</translation>
-<translation id="7158980942472052083">Невалиден URL адрес. Адресът трябва да бъде със стандартна схема.</translation>
<translation id="717330890047184534">Идентификатор в GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Сървърът, който отваряте (<ph name="ORIGIN" />), е поискал
+за всички заявки към него да се прилага правило за сигурност. Вместо обаче
+да предостави правило, той е пренасочил браузъра другаде, което не позволява
+на Chrome да изпълни заявката ви за <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Запазване и попълване на начини на плащане</translation>
<translation id="7180611975245234373">Опресняване</translation>
<translation id="7182878459783632708">Няма зададени правила</translation>
<translation id="7186367841673660872">Тази страница е преведена от<ph name="ORIGINAL_LANGUAGE" />на<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Ще освободите <ph name="SIZE" />. Някои сайтове може да се заредят по-бавно при следващото ви посещение.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Администраторът ви може да вижда:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> не се придържа към стандартите за сигурност.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /> за този проблем.</translation>
<translation id="7219179957768738017">Връзката използва <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Обработва се</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">На хоризонта се задава сайт със злонамерен софтуер</translation>
+<translation id="724766306220616965">Предупреждения, несъвместимост</translation>
<translation id="724975217298816891">Въведете датата на валидност и кода за проверка за <ph name="CREDIT_CARD" />, за да актуализирате данните за картата си. След като я потвърдите, те ще бъдат споделени с този сайт.</translation>
<translation id="7251437084390964440">Конфигурацията на мрежата не спазва стандарта на ONC. Възможно е части от нея да не са импортирани.
Допълнителни подробности:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">кобалтовосиньо</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />“</translation>
<translation id="7309308571273880165">Сигнал за срив, записан в/ъв <ph name="CRASH_TIME" /> (потребителят е заявил качване, което още не е извършено)</translation>
+<translation id="7313965965371928911">Предупреждения от <ph name="BEGIN_LINK" />Безопасно сърфиране<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Помощ при проблеми с връзката</translation>
<translation id="7334320624316649418">&amp;Възстановяване на пренареждането</translation>
<translation id="733923710415886693">Сертификатът на сървъра не е разкрит чрез Прозрачност на сертификатите.</translation>
+<translation id="734600844861828519">11 x 15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Команден ред</translation>
-<translation id="7365061714576910172">Експортиране за Linux</translation>
<translation id="7372973238305370288">резултат от търсенето</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Не</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">Принудително зададено поради управлявана сесия</translation>
<translation id="7390545607259442187">Потвърждаване на картата</translation>
<translation id="7400418766976504921">URL адрес</translation>
+<translation id="7403591733719184120">Устройството ви <ph name="DEVICE_NAME" /> е управлявано</translation>
<translation id="7407424307057130981">&lt;p&gt;Ще виждате това съобщение за грешка, ако софтуерът Superfish е инсталиран на компютъра ви с Windows.&lt;/p&gt;
&lt;p&gt;Изпълнете следните стъпки, за да деактивирате временно софтуера, така че да можете да се свържете с мрежата. Ще са ви необходими администраторски права.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;Кликнете върху &lt;strong&gt;Приложи&lt;/strong&gt; и след това – върху &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Посетете &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Помощния център на Chrome&lt;/a&gt;, за да научите как да премахнете за постоянно софтуера от компютъра си.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Управление на <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Управление на паролите…</translation>
<translation id="7419106976560586862">Път на потребителския профил</translation>
<translation id="7437289804838430631">Добавяне на информация за връзка</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">светлооранжево</translation>
<translation id="7444046173054089907">Този сайт е блокиран</translation>
<translation id="7445762425076701745">Идентичността на сървъра, към който сте свързани, не може да бъде потвърдена изцяло. Свързани сте към сървър чрез име, което е валидно само във вашата мрежа и чиято собственост няма начин да се потвърди от външен сертифициращ орган. Тъй като някои сертифициращи органи въпреки това издават сертификати за такива имена, не е възможно да се гарантира, че сте свързани към желания сайт, а не към атакуващ.</translation>
-<translation id="7449109375006139765">изпраща системните регистрационни файлове до сървъра за управление</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /> за този проблем.</translation>
<translation id="7455133967321480974">Използване на глобалната стандартна стойност (блокиране)</translation>
<translation id="7460618730930299168">Прожекцията е различна от избраната от вас. Искате ли да продължите?</translation>
<translation id="7473891865547856676">Не, благодаря</translation>
-<translation id="7475525192983021547">отчита периодите от време, когато потребителят е активен на устройството</translation>
<translation id="7481312909269577407">Препращане</translation>
<translation id="7485870689360869515">Няма намерени данни.</translation>
+<translation id="7498234416455752244">Продължаване с редактирането</translation>
<translation id="7508255263130623398">Върнатият от правилата идентификационен номер на устройството е празен или не съответства на текущия</translation>
<translation id="7508870219247277067">авокадовозелено</translation>
<translation id="7511955381719512146">Използваната от вас Wi-Fi мрежа може да изисква да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Изтегляне</translation>
<translation id="7518003948725431193">Не е намерена уеб страница за уеб адреса: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (плик)</translation>
<translation id="7521387064766892559">Javascript</translation>
<translation id="7526934274050461096">Връзката ви с този сайт не е частна</translation>
+<translation id="7535087603100972091">Стойност</translation>
<translation id="7537536606612762813">Задължително</translation>
+<translation id="7538364083937897561">A2 (плик)</translation>
<translation id="7542403920425041731">След като потвърдите картата си, данните за нея ще бъдат споделени с този сайт.</translation>
<translation id="7542995811387359312">Автоматичното попълване на кредитната карта е деактивирано, защото този формуляр не използва защитена връзка.</translation>
<translation id="7543525346216957623">Попитайте родителя си</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">Изпробвайте следните съвети:</translation>
<translation id="7554791636758816595">Нов раздел</translation>
<translation id="7564049878696755256">Възможно е да загубите достъп до профила си в/ъв <ph name="ORG_NAME" /> или самоличността ви да бъде открадната. Chrome препоръчва да промените паролата си сега.</translation>
-<translation id="7566125604157659769">Копиран от вас текст</translation>
<translation id="7567204685887185387">Сървърът не можа да докаже, че е <ph name="DOMAIN" />; възможно е сертификатът му за сигурност да е издаден измамнически. Това може да се дължи на неправилно конфигуриране или на прихващане на връзката ви от атакуващ.</translation>
+<translation id="7568105740864181217">Този браузър се управлява от дружество, учебно заведение или друга организация. Администраторът ви може отдалечено да променя настройките на браузъра. Възможно е активността на това устройство да се управлява и извън Chrome. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Кредитната карта да се премахне ли от Chrome?</translation>
<translation id="7569983096843329377">черно</translation>
<translation id="7578104083680115302">Извършвайте бързи плащания в сайтове и приложения от всякакви устройства посредством картите, които сте запазили в Google.</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">Данни за ефективността и сигнали за сривове</translation>
<translation id="7637571805876720304">Кредитната карта да се премахне ли от Chromium?</translation>
<translation id="7639968568612851608">тъмносиво</translation>
<translation id="765676359832457558">Скриване на разширените настройки...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">Върнатото означение за правилата е празно или не съответства на текущото</translation>
<translation id="7668654391829183341">Неизвестно устройство</translation>
<translation id="7669271284792375604">Извършителите на атаки, използващи този сайт, може да опитат да ви подведат да инсталирате програми, които вредят на сърфирането ви (например, като променят началната ви страница или показват допълнителни реклами в посещаваните от вас сайтове).</translation>
+<translation id="7676643023259824263">Търсене на текста от буферната памет, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Промяна на търсещата машина</translation>
<translation id="7682287625158474539">Адрес за доставка</translation>
<translation id="7687186412095877299">Попълване на платежни формуляри със запазените от вас начини на плащане</translation>
+<translation id="7697066736081121494">Prc8 (плик)</translation>
<translation id="769721561045429135">В момента имате карти, които могат да се използват само на това устройство. Кликнете върху „Напред“, за да ги прегледате.</translation>
<translation id="7699293099605015246">В момента няма статии</translation>
<translation id="7701040980221191251">Няма</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">Блокирахме опасно съдържание.</translation>
<translation id="7752995774971033316">Не се управлява</translation>
<translation id="7755287808199759310">Родителят ви може да го отблокира за вас</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Възможно е връзката да е блокирана от защитна стена или антивирусен софтуер.</translation>
<translation id="7759163816903619567">Показван домейн:</translation>
<translation id="7761701407923456692">Сертификатът на сървъра не съответства на URL адреса.</translation>
<translation id="7763386264682878361">Инструмент за синтактичен анализ на манифести за плащания</translation>
<translation id="7764225426217299476">Добавяне на адрес</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Добавяне</translation>
<translation id="7793809570500803535">Възможно е временно да няма достъп до уеб страницата на адрес <ph name="SITE" /> или тя да е преместена за постоянно на нов уеб адрес.</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Предложението за формуляри да се премахне ли от Chrome?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> за „<ph name="SEARCH_STRING" />“</translation>
-<translation id="7818867226424560206">Управление на правилата</translation>
<translation id="782886543891417279">Използваната от вас Wi-Fi мрежа (<ph name="WIFI_NAME" />) може да изисква да посетите страницата й за вход.</translation>
+<translation id="7836231406687464395">Postfix (плик)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Няма}=1{1 приложение (<ph name="EXAMPLE_APP_1" />)}=2{2 приложения (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# приложения (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Сърфирането ви обаче не е невидимо. При преминаване в режим „инкогнито“ то не се скрива от работодателя ви и от доставчика ви на интернет услуги, нито от уебсайтовете, които посещавате.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">Възможно е паролата ви да е компрометирана</translation>
<translation id="7882421473871500483">кафяво</translation>
<translation id="7887683347370398519">Прегледайте кода за проверка и опитайте отново</translation>
-<translation id="7893255318348328562">Име на сесията</translation>
+<translation id="7904208859782148177">C3 (плик)</translation>
<translation id="79338296614623784">Въведете валиден телефонен номер</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Изтича на <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(32 бита)</translation>
<translation id="7956713633345437162">Мобилни отметки</translation>
<translation id="7961015016161918242">Никога</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Не е посочено</translation>
<translation id="800218591365569300">Затворете другите раздели или програми, за да освободите памет.</translation>
+<translation id="8004582292198964060">Браузър</translation>
<translation id="8009225694047762179">Управление на паролите</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Тази карта и адресът й за фактуриране ще бъдат запазени. Ще можете да я използвате, когато сте влезли в профила <ph name="USER_EMAIL" />.}other{Тези карти и адресите им за фактуриране ще бъдат запазени. Ще можете да ги използвате, когато сте влезли в профила <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">Не можахме да се свържем с родителите ви. Моля, опитайте отново.</translation>
<translation id="8025119109950072390">Извършителите на атаки, използващи този сайт, може да ви подведат да направите нещо опасно, като например да инсталирате софтуер или да разкриете лична информация (например пароли, телефонни номера или номера на кредитни карти).</translation>
<translation id="8034522405403831421">Тази страница е на <ph name="SOURCE_LANGUAGE" />. Да се преведе ли на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Писалка</translation>
+<translation id="8037117624646282037">Кой е използвал устройството наскоро</translation>
<translation id="8037357227543935929">Извеждане на запитване (по подразбиране)</translation>
<translation id="803771048473350947">Файл</translation>
<translation id="8041089156583427627">Изпращане на отзивите</translation>
<translation id="8041940743680923270">Използване на глобалната стандартна стойност (запитване)</translation>
<translation id="8042918947222776840">Избиране на начин на вземане</translation>
<translation id="8057711352706143257">Софтуерът <ph name="SOFTWARE_NAME" /> не е конфигуриран правилно. Обикновено проблемът се отстранява с деинсталиране на <ph name="SOFTWARE_NAME" />. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Устройството ви е конфигурирано да:</translation>
+<translation id="8066955247577885446">За съжаление, нещо се обърка.</translation>
+<translation id="8074253406171541171">10 x 13 (плик)</translation>
<translation id="8078141288243656252">Добавянето на пояснения не е възможно, когато документът е завъртян</translation>
<translation id="8079031581361219619">Искате ли да презаредите сайта?</translation>
<translation id="8088680233425245692">Преглеждането на статията не бе успешно.</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">В сървъра се изчаква активиране</translation>
<translation id="8092774999298748321">наситено лилаво</translation>
<translation id="8094917007353911263">Използваната от вас мрежа може да изисква да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Невалидните карти са премахнати</translation>
<translation id="8103161714697287722">Начин на плащане</translation>
<translation id="8118489163946903409">Начин на плащане</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> се управлява от <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> не се инсталира правилно на компютъра ви или в мрежата. Помолете системния си администратор да реши този проблем.</translation>
-<translation id="8130693978878176684">Не мога да помогна повече. Моля, продължете ръчно.</translation>
<translation id="8131740175452115882">Потвърждаване</translation>
<translation id="8149426793427495338">Компютърът ви премина в спящ режим.</translation>
<translation id="8150722005171944719">Файлът на адрес <ph name="URL" /> не може да бъде прочетен. Възможно е да е премахнат, преместен или разрешенията му да предотвратяват достъпа.</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">Превод на страницата</translation>
<translation id="8201077131113104583">Невалиден URL адрес за актуализиране на разширението с идентификационен номер <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Обобщена информация за поръчката</translation>
+<translation id="8202370299023114387">Конфликт</translation>
+<translation id="8206978196348664717">Prc4 (плик)</translation>
<translation id="8211406090763984747">Връзката е защитена</translation>
<translation id="8218327578424803826">Зададено местоположение:</translation>
+<translation id="8220146938470311105">C7/C6 (плик)</translation>
<translation id="8225771182978767009">Човекът, който е настроил компютъра, е блокирал този сайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> и <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">Отворете страницата в нов раздел в режим „инкогнито“.</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">Показване на всички запазени пароли</translation>
<translation id="8261506727792406068">Изтриване</translation>
<translation id="8267698848189296333">Влизате като <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Този браузър се управлява от <ph name="ENROLLMENT_DOMAIN" />. Администраторът ви може да променя отдалечено настройките му. Възможно е активността на това устройство да се управлява и извън Chrome. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Вход</translation>
<translation id="8288807391153049143">Показване на сертификата</translation>
<translation id="8289355894181816810">Свържете се със системния си администратор, ако не сте сигурни какво означава това.</translation>
<translation id="8293206222192510085">Добавяне на отметка</translation>
<translation id="8294431847097064396">Източник</translation>
<translation id="8298115750975731693">Използваната от вас Wi-Fi мрежа (<ph name="WIFI_NAME" />) може да изисква да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Преводът не бе успешен поради проблем с връзката към мрежата.</translation>
-<translation id="8311129316111205805">Зареждане на сесията</translation>
<translation id="8332188693563227489">Достъпът до <ph name="HOST_NAME" /> бе отказан</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">Ако разбирате рисковете за сигурността си, може <ph name="BEGIN_LINK" />да посетите този сайт<ph name="END_LINK" /> преди премахването на опасните програми.</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">Конфигурацията на мрежата е невалидна и не можа да се импортира.
Допълнителни подробности:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Устройството се управлява от <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" />, <ph name="SECOND_LABEL" />, <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Промяна</translation>
<translation id="8428213095426709021">Настройки</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">Име на титуляря на картата</translation>
<translation id="861775596732816396">Размер 4</translation>
<translation id="8620436878122366504">Родителите ви все още не са одобрили заявката</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Запазване на картата на това устройство</translation>
<translation id="8663226718884576429">Обобщение на поръчката, <ph name="TOTAL_LABEL" />, още подробности</translation>
<translation id="8680536109547170164">„<ph name="QUERY" />“, отговор: „<ph name="ANSWER" />“</translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Връзката ви с <ph name="DOMAIN" /> не е шифрована.</translation>
<translation id="8718314106902482036">Плащането не е завършено</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, предложение за търсене</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google Безопасно сърфиране наскоро <ph name="BEGIN_LINK" />откри опасни програми<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="8763927697961133303">USB устройство</translation>
<translation id="8768895707659403558">За да използвате картите си на всичките си устройства, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Възстановяване на изтриването</translation>
<translation id="8792621596287649091">Възможно е да загубите достъп до профила си в/ъв <ph name="ORG_NAME" /> или самоличността ви да бъде открадната. Chromium препоръчва да промените паролата си сега.</translation>
<translation id="8800988563907321413">Тук ще се показват предложения за неща в близост</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">Споделяне с Google</translation>
<translation id="8858065207712248076">Chrome препоръчва да зададете повторно паролата си за <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, ако сте я използвали и на други сайтове.</translation>
<translation id="8866481888320382733">Грешка при синтактичния анализ на настройките за правилото</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Наскоро затворени</translation>
<translation id="8874824191258364635">Въведете валиден номер на карта</translation>
<translation id="8891727572606052622">Невалиден режим на прокси сървъра.</translation>
<translation id="8903921497873541725">Увеличаване на мащаба</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Искате ли да запазите тази карта в профила си в Google?</translation>
<translation id="8932102934695377596">Часовникът ви е назад</translation>
<translation id="893332455753468063">Добавяне на име</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">Администраторът ви е конфигурирал персонализирани основни сертификати, което може да му позволи да вижда съдържанието на посещаваните от вас уебсайтове.</translation>
<translation id="8943282376843390568">лимоненозелено</translation>
<translation id="8957210676456822347">Упълномощаване в портал за удостоверяване</translation>
+<translation id="8966619695390250636">Това ли имахте предвид?</translation>
<translation id="8968766641738584599">Запазване на картата</translation>
<translation id="8971063699422889582">Сертификатът на сървъра е с изтекла валидност.</translation>
<translation id="8975012916872825179">Включва информация като телефонни номера, имейл адреси и адреси за доставка</translation>
<translation id="8978053250194585037">Google Безопасно сърфиране наскоро <ph name="BEGIN_LINK" />откри фишинг<ph name="END_LINK" /> на <ph name="SITE" />. Сайтовете за фишинг се представят за други уебсайтове с цел да ви подведат.</translation>
<translation id="8983003182662520383">Начини на плащане и адреси посредством Google Pay</translation>
<translation id="8987927404178983737">Месец</translation>
-<translation id="8988408250700415532">Нещо се обърка. Можете да завършите поръчката си на уебсайта.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">На хоризонта се задава сайт с опасни програми</translation>
<translation id="8997023839087525404">Сървърът предостави сертификат, който не е разкрит публично чрез правило в Прозрачност на сертификатите. Това се изисква за някои сертификати с цел защита срещу хакери и за да е сигурно, че може да им се има доверие.</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">Отваряне на настройките за сайтове</translation>
<translation id="9020200922353704812">Свързаният с картата адрес за фактуриране е задължителен</translation>
<translation id="9020542370529661692">Тази страница е преведена на <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(невалиден)</translation>
<translation id="9035022520814077154">Грешка в сигурността</translation>
<translation id="9038649477754266430">Използване на услуга за предвиждане с цел по-бързо зареждане на страниците</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">Търсене на „<ph name="TEXT" />“ от историята</translation>
<translation id="9069693763241529744">Блокирано от разширение</translation>
<translation id="9076283476770535406">Възможно е да има съдържание за пълнолетни</translation>
+<translation id="9076630408993835509">Този браузър не се управлява от дружество или друга организация. Възможно е активността на устройството да се управлява извън Chrome. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Изисква се още информация</translation>
<translation id="9080712759204168376">Обобщена информация за поръчката</translation>
<translation id="9103872766612412690">Обикновено <ph name="SITE" /> използва шифроване за защита на информацията ви. Когато Chromium опита да установи връзка с/ъс <ph name="SITE" /> този път, уебсайтът върна необичайни и неправилни идентификационни данни. Това може да се случи, когато извършител на атака пробва да се представи за <ph name="SITE" /> или връзката е прекъсната от екран за вход в Wi-Fi. Информацията ви продължава да е защитена, тъй като Chromium спря връзката, преди да бъдат обменени данни.</translation>
<translation id="9106062320799175032">Добавяне на адрес за фактуриране</translation>
-<translation id="9110718169272311511">Функцията Google Асистент в Chrome е достъпна в долната част на екрана</translation>
<translation id="9114524666733003316">Картата се потвърждава...</translation>
<translation id="9128870381267983090">Свързване към мрежа</translation>
<translation id="9137013805542155359">Показване на оригинала</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;Отмяна на редактирането</translation>
<translation id="9154194610265714752">Актуализирано</translation>
<translation id="9157595877708044936">Настройва се...</translation>
+<translation id="9158625974267017556">C6 (плик)</translation>
<translation id="9168814207360376865">Разрешаване на сайтовете да проверяват дали имате запазени начини на плащане</translation>
<translation id="9169664750068251925">Блокиране винаги на този сайт</translation>
<translation id="9170848237812810038">&amp;Отмяна</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">Изображения</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ИЗЧИСТВАНЕ НА ФОРМУЛЯРА</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Възможно е да загубите достъп до профила си в Google. Chromium препоръчва да промените паролата си сега. Ще получите подкана за влизане в профила си.</translation>
<translation id="939736085109172342">Нова папка</translation>
<translation id="945855313015696284">Проверете информацията по-долу и изтрийте невалидните карти</translation>
<translation id="951104842009476243">Приемани дебитни и предплатени карти</translation>
+<translation id="958202389743790697">Блокирано съгласно правилото за сигурност на <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Въпросното съдържание може да се опита да инсталира измамни приложения, които се представят за нещо друго или събират данни, които може да се използват за проследяването ви. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Официално издание</translation>
<translation id="973773823069644502">Добавяне на адрес за бърза доставка</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">Начини на плащане</translation>
<translation id="985199708454569384">&lt;p&gt;Ще виждате това съобщение за грешка, ако датата и часът на компютъра или мобилното ви устройство не са верни.&lt;/p&gt;
&lt;p&gt;За да отстраните грешката, отворете часовника на устройството си и сверете датата и часа.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Компилирана програма за програмисти</translation>
<translation id="989988560359834682">Редактиране на адреса</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_bn.xtb b/chromium/components/strings/components_strings_bn.xtb
index 12165f1ffff..a95af9f1ffa 100644
--- a/chromium/components/strings/components_strings_bn.xtb
+++ b/chromium/components/strings/components_strings_bn.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
-<translation id="1005145902654145231">সেশনটির নতুন নাম দেওয়া যায়নি।</translation>
<translation id="1008557486741366299">এখনই নয়</translation>
<translation id="1010200102790553230">পৃষ্ঠা পরে দেখার জন্য লোড করে রাখুন</translation>
<translation id="1015730422737071372">অতিরিক্ত বিবরণ দিন</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">অজানা নাম</translation>
<translation id="1050038467049342496">অন্যান্য অ্যাপ্লিকেশানগুলি বন্ধ করুন</translation>
<translation id="1055184225775184556">&amp;যোগ করাকে পূর্বাবস্থায় ফেরান</translation>
+<translation id="1056898198331236512">সতর্কতা</translation>
<translation id="1058479211578257048">কার্ড সেভ করা হচ্ছে...</translation>
<translation id="10614374240317010">কখনও সংরক্ষিত হয়নি</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">ডেস্কটপ বুকমার্ক</translation>
<translation id="1074497978438210769">সুরক্ষিত নয়</translation>
<translation id="1080116354587839789">প্রস্থের মধ্যে আঁটান</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">কার্ডে নাম যোগ করুন</translation>
<translation id="1089439967362294234">পাসওয়ার্ড পরিবর্তন করুন</translation>
<translation id="109743633954054152">Chrome সেটিংসে পাসওয়ার্ড পরিচালনা করুন</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">ওয়েবসাইটগুলির নিরাপত্তা আপডেট করার সময় সতর্কতা দেখানো খুবই স্বভাবিক। এটি শীঘ্রই উন্নত করা উচিত।</translation>
<translation id="1126551341858583091">স্থানীয় সঞ্চয়স্থানের আকার হলো <ph name="CRASH_SIZE" />।</translation>
<translation id="112840717907525620">নীতি ক্যাশেটি ঠিক আছে</translation>
+<translation id="1131264053432022307">আপনার কপি করা ছবি</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> অপ্রত্যাশিতভাবে সংযোগ বন্ধ করেছে।</translation>
<translation id="1161325031994447685">ওয়াই-ফাই এ আবার সংযুক্ত করে দেখুন</translation>
<translation id="1165039591588034296">ত্রুটি</translation>
-<translation id="1173894706177603556">পুনঃনামকরণ</translation>
<translation id="1175364870820465910">&amp;প্রিন্ট...</translation>
<translation id="1181037720776840403">সরান</translation>
<translation id="1197088940767939838">কমলা</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">আপনার ডিভাইসের নাম</translation>
<translation id="124116460088058876">আরও ভাষা</translation>
<translation id="1250759482327835220">পরেরবার আরও দ্রুত পেমেন্ট করা জন্য আপনার কার্ড, নাম এবং বিলিং ঠিকানাটি Google অ্যাকাউন্টে সেভ করে রাখুন।</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (সিঙ্ক হয়েছে)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">কম্যান্ড-লাইন ভেরিয়েশন</translation>
<translation id="129553762522093515">সম্প্রতি বন্ধ হয়েছে</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />আপনার কুকিজ সাফ করে দেখুন<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">বেছে নেওয়া সেশনটির অস্তিত্ব নেই।</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">ক্লিপবোর্ডে ছবির জন্য সার্চ করুন</translation>
<translation id="1323433172918577554">আরও দেখুন</translation>
<translation id="132390688737681464">অ্যাড্রেসগুলি পূরণ করে সেভ করুন</translation>
<translation id="1333989956347591814">এগুলিতে আপনার অ্যাক্টিভিটি <ph name="BEGIN_EMPHASIS" />এখনও দেখা যেতে পারে<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">যে ঠিকানা থেকে নিতে হবে</translation>
<translation id="1348198688976932919">যে সাইট খুলতে চলেছেন সেটিতে বিপজ্জনক অ্যাপ আছে</translation>
<translation id="1348779747280417563">নাম কনফার্ম করুন</translation>
+<translation id="1357195169723583938">সম্প্রতি ডিভাইসটি কে এবং কখন ব্যবহার করেছেন</translation>
+<translation id="1364822246244961190">এই নীতি ব্লক করা আছে তাই এর মান কাজ করবে না।</translation>
<translation id="1374468813861204354">প্রস্তাবনাগুলি</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">ভার্সন সম্পর্কে</translation>
<translation id="1376836354785490390">কম দেখুন</translation>
<translation id="1377321085342047638">কার্ড নম্বর</translation>
<translation id="138218114945450791">হালকা নীল</translation>
+<translation id="1382194467192730611">আপনার অ্যাডমিনিস্ট্রেটর ইউএসবি ডিভাইস ব্যবহার করার অনুমতি দিয়েছেন</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> কোনো তথ্য পাঠায়নি।</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> সাইটটি অনুরোধ জানিয়েছে যে সাইটের সব অনুরোধের জন্যই
+ নিরাপত্তা সংক্রান্ত নীতি প্রযুক্ত হবে এবং এই নীতি বর্তমানে
+ সাইটটিকে নিরাপদ নয় বলে মনে করছে।</translation>
<translation id="1405567553485452995">হালকা সবুজ</translation>
<translation id="1407135791313364759">সব খুলুন</translation>
<translation id="1413809658975081374">গোপনীয়তা ত্রুটি</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">হ্যাঁ</translation>
<translation id="1430915738399379752">প্রিন্ট</translation>
<translation id="1455413310270022028">ইরেজার</translation>
+<translation id="1463543813647160932">৫x৭</translation>
+<translation id="1472675084647422956">আরও দেখান</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">শিপিং ঠিকানা বেছে নিন</translation>
+<translation id="1492194039220927094">নীতি সংক্রান্ত পুশ:</translation>
<translation id="1501859676467574491">আপনার Google Account থেকে কার্ড দেখুন</translation>
-<translation id="1506687042165942984">এই পৃষ্ঠার একটি সংরক্ষিত প্রতিলিপি (অর্থাৎ,তারিখ সীমার বাইরে হিসাবে পরিচিত) প্রদর্শন করুন৷</translation>
<translation id="1507202001669085618">&lt;p&gt;আপনি যদি এমন কোনও ওয়াই-ফাই পোর্টাল ব্যবহার করেন যেখানে অনলাইন হওয়ার জন্য সাইন-ইন করতে হয়, তাহলে এই সমস্যাটি হতে পারে।&lt;/p&gt;
&lt;p&gt;এই সমস্যার সমাধান করতে, যে পৃষ্ঠাটি খুলতে চান সেটিতে &lt;strong&gt;কানেক্ট করুন&lt;/strong&gt; বোতামে ক্লিক করুন।&lt;/p&gt;</translation>
<translation id="1517433312004943670">ফোন নম্বর আবশ্যক</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">নির্মাণের তারিখ</translation>
<translation id="1521655867290435174">Google পত্রক</translation>
<translation id="1527263332363067270">সংযোগের জন্য অপেক্ষা করা হচ্ছে...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">এই পৃষ্ঠায় এটি দেখানো হচ্ছে</translation>
<translation id="153384715582417236">এখন এই পর্যন্তই</translation>
<translation id="154408704832528245">ডেলিভারি ঠিকানা বেছে নিন</translation>
<translation id="1549470594296187301">এই বৈশিষ্ট্যটি ব্যবহার করার জন্য JavaScript সক্ষম করা প্রয়োজন।</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">মেয়াদ শেষ হওয়ার তারিখ লিখুন</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">এই ওয়েবপৃষ্ঠাটি দেখানোর সময় কোনো সমস্যা হয়েছে।</translation>
<translation id="1592005682883173041">স্থানীয় ডেটা অ্যাক্সেস</translation>
<translation id="1594030484168838125">বেছে নিন</translation>
<translation id="161042844686301425">নীলাভ</translation>
-<translation id="1618822247301510817">আপনি কপি করেছেন এমন ছবি</translation>
<translation id="1620510694547887537">ক্যামেরা</translation>
<translation id="1623104350909869708">এই পৃষ্ঠাটিকে অতিরিক্ত কথোপকথন তৈরি করা থেকে বাধা দিন</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">সেশন শেষ করুন</translation>
<translation id="1639239467298939599">লোড হচ্ছে</translation>
<translation id="1640180200866533862">ব্যবহারকারীর নীতিসমূহ</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> সাধারণত আপনার তথ্য সুরক্ষিত রাখতে এনক্রিপশন ব্যবহার করে। এবার যখন Google Chrome <ph name="SITE" />-এর সাথে সংযোগ স্থাপন করার চেষ্টা করেছে, তখন ওয়েবসাইটটি অস্বাভাবিক এবং ভুল সার্টিফিকেট পাঠিয়েছে। হয় একজন আক্রমণকারী <ph name="SITE" /> হওয়ার ভান করছে অথবা কোনও ওয়াই-ফাই সাইন-ইন স্ক্রিণ সংযোগকে বাধা দেওয়া হয়েছে। আপনার তথ্য এখনো নিরাপদ আছে কারণ কোনও ডেটা আদানপ্রদানের আগেই Google Chrome সংযোগটিকে বন্ধ করে দিয়েছে।</translation>
<translation id="168841957122794586">সার্ভার সার্টিফিকেটে একটি দুর্বল ক্রিপ্টোগ্রাফিক কী আছে৷</translation>
<translation id="1697532407822776718">আপনার সমস্ত সেট আছে!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">ব্যাখ্যার জন্য ডকুমেন্টের সাইজ বেশি বড়</translation>
<translation id="1721312023322545264">এই সাইটে যেতে আপনাকে <ph name="NAME" /> এর কাছ থেকে অনুমতি নিতে হবে</translation>
<translation id="1721424275792716183">* এই ফিল্ডে কিছু লেখা প্রয়োজন</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">সিস্টেম প্রশাসকের সাথে যোগাযোগ করে দেখুন।</translation>
<translation id="1740951997222943430">মেয়াদ শেষ হওয়ার মাসের সঠিক মান লিখুন</translation>
<translation id="1743520634839655729">পরেরবার আরও দ্রুত পেমেন্ট করা জন্য আপনার কার্ড, নাম এবং বিলিং ঠিকানাটি Google অ্যাকাউন্টে এবং এই ডিভাইসে সেভ করে রাখুন।</translation>
+<translation id="1745880797583122200">আপনার ব্রাউজারটি ম্যানেজ করা হচ্ছে</translation>
<translation id="17513872634828108">খোলা ট্যাব</translation>
<translation id="1753706481035618306">পৃষ্ঠা সংখ্যা</translation>
<translation id="1763864636252898013">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেটটি আপনার ডিভােইসের নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">দয়া করে আপনার সিঙ্ক পাসফ্রেজ আপডেট করুন৷</translation>
<translation id="1787142507584202372">আপনার খোলা ট্যাবগুলি এখানে দেখা যাবে</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">কার্ড হোল্ডারের নাম</translation>
<translation id="1821930232296380041">অবৈধ অনুরোধ বা অনুরোধ মাপকাঠিগুলি</translation>
+<translation id="1822540298136254167">আপনি যে ওয়েবসাইটগুলি দেখেন এবং দেখার জন্য সময় খরচ করেন</translation>
<translation id="1826516787628120939">চেক করা হচ্ছে</translation>
<translation id="1834321415901700177">এই সাইটটিতে ক্ষতিকর প্রোগ্রাম রয়েছে</translation>
<translation id="1839551713262164453">নীতির মূল্য যাচাইকরণে সমস্যা হওয়ার জন্য যাচাই করা যায়নি</translation>
@@ -181,6 +203,10 @@
<translation id="1981206234434200693">Chrome-এর ব্রাউজিং ইতিহাসের ডেটা মুছুন</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{এবং আরও ১টি}one{এবং আরও #টি}other{এবং আরও #টি}}</translation>
<translation id="2003709556000175978">আপনার পাসওয়ার্ড রিসেট করুন</translation>
+<translation id="20053308747750172">আপনি যে সার্ভারে যাচ্ছেন, <ph name="ORIGIN" />, সেটিতে করা যেকোনও অনুরোধের জন্যই একটি নিরাপত্তা নীতি
+ প্রযুক্ত হবে বলে সেটি জানাচ্ছে। কিন্তু এখন এটি
+ একটি ভুল নীতি পাঠিয়েছে বলে ব্রাউজার আপনার অনুরোধ করা <ph name="SITE" />
+ দেখাতে পারছে না।</translation>
<translation id="2025186561304664664">স্বতঃ কনফিগার করতে প্রক্সি সেট করা হয়৷</translation>
<translation id="2030481566774242610">আপনি কি <ph name="LINK" /> বোঝাতে চেয়েছিলেন?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />প্রক্সি এবং ফায়ারওয়াল পরীক্ষা করে দেখুন<ph name="END_LINK" /></translation>
@@ -197,6 +223,7 @@
<translation id="2096368010154057602">বিভাগ</translation>
<translation id="2102134110707549001">শক্তিশালী পাসওয়ার্ড সাজেস্ট করুন…</translation>
<translation id="2108755909498034140">আপনার কম্পিউটার পুনরায় চালু করুন</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">কার্ড</translation>
<translation id="2114841414352855701">এড়িয়ে যাওয়া হয়েছে কারণ এটি <ph name="POLICY_NAME" />-দ্বারা ওভাররাইড করা হয়েছিল৷</translation>
<translation id="213826338245044447">মোবাইল বুকমার্ক</translation>
@@ -207,6 +234,7 @@
<translation id="2154484045852737596">কার্ড সম্পাদনা করুন</translation>
<translation id="2166049586286450108">পূর্ণ প্রশাসক অ্যাক্সেস</translation>
<translation id="2166378884831602661">এই সাইটটি একটি সুরক্ষিত সংযোগ দিতে পারছে না</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">নীতিসমূহ</translation>
<translation id="2183608646556468874">ফোন নম্বর</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{১টি ঠিকানা}one{ #টি ঠিকানা}other{ #টি ঠিকানা}}</translation>
@@ -224,11 +252,15 @@
<translation id="2270484714375784793">ফোন নম্বর</translation>
<translation id="2283340219607151381">অ্যাড্রেস পূরণ করে সেভ করুন</translation>
<translation id="2292556288342944218">আপনার ইন্টারনেট অ্যাক্সেস অবরুদ্ধ করা হয়েছে</translation>
+<translation id="2294558542833290837">আপনি আসলে যে লিঙ্কটি খুলেছেন, সেটি অস্বাভাবিক</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">১ MB এর চেয়ে কম জায়গা খালি করে। পরের বার যখন দেখবেন তখন কিছু সাইট লোড হতে দেরি হতে পারে।</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> এর জন্য একটি ইউজারনেম এবং পাসওয়ার্ড প্রয়োজন।</translation>
<translation id="2317583587496011522">ডেবিট কার্ড গ্রহণ করা হয়।</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />-এর মেয়াদ, <ph name="EXPIRATION_DATE_ABBR" /> তারিখে শেষ হবে</translation>
<translation id="2337852623177822836">সেটিংস আপনার প্রশাসক নিয়ন্ত্রণ করে</translation>
+<translation id="2346319942568447007">আপনার কপি করা ছবি</translation>
<translation id="2349790679044093737">ভিআর (VR) সেশন চালু রয়েছে</translation>
<translation id="2354001756790975382">অন্য বুকমার্কস</translation>
<translation id="2354430244986887761">Google নিরাপদ ব্রাউজিং সম্প্রতি <ph name="SITE" /> এ <ph name="BEGIN_LINK" />ক্ষতিকারক অ্যাপ<ph name="END_LINK" /> খুঁজে পেয়েছে।</translation>
@@ -240,29 +272,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> এ ক্যাপচার করা ক্র্যাশ প্রতিবেদন আপলোড করা হয়নি</translation>
<translation id="2367567093518048410">স্তর</translation>
<translation id="2378238891085281592">আপনি ব্যক্তিগত মোডে চলে গেছেন</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">এন্টারপ্রাইজ ডিফল্ট</translation>
<translation id="2386255080630008482">সার্ভারের সার্টিফিকেটটি প্রত্যাহার করা হয়েছে৷</translation>
<translation id="2392959068659972793">কোনো মান সেট করা নেই এমন নীতিগুলি দেখান</translation>
<translation id="239429038616798445">এই পদ্ধতিতে শিপিং করা যাবে না। অন্য পদ্ধতি ব্যবহার করুন।</translation>
<translation id="2396249848217231973">&amp;মুছে ফেলাকে পূর্বাবস্থায় ফেরান</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেট প্রত্যাহার করা হতে পারে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="2418081434543109369">আপনি যে সার্ভারে যাচ্ছেন, <ph name="ORIGIN" />, সেটিতে করা যেকোনও অনুরোধের জন্যই একটি নিরাপত্তা নীতি
+ প্রযুক্ত হবে বলে সেটি জানাচ্ছে। কিন্তু এটি
+ নীতি পাঠাতে পারেনি বলে ব্রাউজার আপনার অনুরোধ করা
+ <ph name="SITE" /> দেখাতে পারছে না।</translation>
<translation id="244665789865330679">আপনার ডিভাইস ও আপনার অ্যাকাউন্ট <ph name="ENROLLMENT_DOMAIN" />-এর দ্বারা পরিচালিত হয়। অর্থাৎ, অ্যাডমিনিস্ট্রেটর দূর থেকে আপনার ডিভাইস ও অ্যাকাউন্ট কনফিগার করতে পারেন।</translation>
<translation id="2463193859425327265">হোম পৃষ্ঠা পরিবর্তন করুন</translation>
<translation id="2463739503403862330">পূরণ করুন</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">ডেলিভারি পদ্ধতি বেছে নিন</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />নেটওয়ার্ক ডায়গনিস্টিক্স চালান<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">এই পৃষ্ঠাটি অনুবাদ করুন</translation>
<translation id="2479410451996844060">অবৈধ সার্চের URL৷</translation>
<translation id="2482878487686419369">বিজ্ঞপ্তিগুলি</translation>
<translation id="248348093745724435">মেশিনের নীতি</translation>
+<translation id="2485387744899240041">আপনার ডিভাইস এবং ব্রাউজারের জন্য ইউজারনেম</translation>
<translation id="2491120439723279231">সার্ভারের সার্টিফিকেটে ত্রুটি আছে৷</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON বিশ্লেষক</translation>
<translation id="2495093607237746763">টিক চিহ্ণ দেওয়া থাকলে, ফর্ম পূরনের কাজ দ্রুত করতে Chromium এই ডিভাইসে আপনার কার্ডের একটি প্রতিলিপি সঞ্চয় করবে।</translation>
<translation id="2498091847651709837">নতুন কার্ড স্ক্যান করুন</translation>
<translation id="2501278716633472235">ফিরে যান</translation>
<translation id="2503184589641749290">ডেবিট ও প্রিপেড কার্ড গ্রহণ করা হয়</translation>
<translation id="2515629240566999685">আপনার এলাকায় সংকেত পরীক্ষা করে দেখুন</translation>
-<translation id="2516852381693169964">ছবির জন্য <ph name="SEARCH_ENGINE" /> খুঁজুন</translation>
<translation id="2523886232349826891">শুধুমাত্র এই ডিভাইসে সেভ করা যাবে</translation>
<translation id="2524461107774643265">আরও তথ্য যোগ করুন</translation>
<translation id="2536110899380797252">ঠিকানা যোগ করুন</translation>
@@ -274,6 +314,7 @@
<translation id="2587841377698384444">ডিরেক্টরি API আইডি:</translation>
<translation id="2597378329261239068">এই দস্তাবেজটি পাসওয়ার্ড সুরক্ষিত৷ দয়া করে একটি পাসওয়ার্ড লিখুন৷</translation>
<translation id="2609632851001447353">বৈচিত্রতা</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">আপনার ঘড়ির সময় অনেকটা এগিয়ে</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" />এর সার্ভার IP অ্যাড্রেস পাওয়া যায়নি।</translation>
<translation id="2639739919103226564">স্থিতি: </translation>
@@ -283,7 +324,9 @@
<translation id="2666117266261740852">অন্যান্য ট্যাব বা অ্যাপ্লিকেশানগুলি বন্ধ করুন</translation>
<translation id="267371737713284912">পূর্বাবস্থায় ফিরে যেতে <ph name="MODIFIER_KEY_DESCRIPTION" /> টিপুন</translation>
<translation id="2674170444375937751">আপনি কি আপনার ইতিহাস থেকে এই পৃষ্ঠাগুলি মোছার বিষয়ে নিশ্চিত?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">ছেড়ে চলে যান</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">এই কার্ডগুলি গ্রহণ করা হয়</translation>
<translation id="2702801445560668637">পড়ার তালিকা</translation>
<translation id="2704283930420550640">বিন্যাসের সাথে মূল্য মেলে না৷</translation>
@@ -300,7 +343,6 @@
<translation id="2742870351467570537">নির্বাচিত আইটেমগুলি সরান</translation>
<translation id="277133753123645258">শিপিংয়ের পদ্ধতি</translation>
<translation id="277499241957683684">ডিভাইস রেকর্ড অনুপস্থিত</translation>
-<translation id="2781030394888168909">MacOS এক্সপোর্ট করুন</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">সংযোগ পুনঃসেট করা হয়েছে৷</translation>
<translation id="2788784517760473862">ক্রেডিট কার্ড গ্রহণ করা হয়</translation>
@@ -312,8 +354,10 @@
<translation id="2826760142808435982"><ph name="CIPHER" /> ব্যবহার করে এই সংযোগটি এনক্রিপ্টেড এবং প্রমাণীকৃত করা হয়েছে এবং কী এক্সচেঞ্জ প্রক্রিয়া হিসাবে <ph name="KX" /> ব্যবহার করে৷</translation>
<translation id="2835170189407361413">ফর্ম সাফ করুন</translation>
<translation id="2847118875340931228">ছদ্মবেশী উইন্ডো খুলুন</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">এই সাইট দেখার জন্য আপনার অনুমতির প্রয়োজন</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">কার্ড সেভ করবেন?</translation>
<translation id="2903493209154104877">ঠিকানা</translation>
<translation id="290376772003165898">পৃষ্ঠাটি <ph name="LANGUAGE" /> ভাষায় নয়?</translation>
@@ -323,6 +367,7 @@
<translation id="2925673989565098301">ডেলিভারির পদ্ধতি</translation>
<translation id="2928905813689894207">বিলিংয়ের ঠিকানা</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেট <ph name="DOMAIN2" /> থেকে পাওয়া। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="2948083400971632585">আপনি সেটিংস পৃষ্ঠা থেকে সংযোগের জন্য কনফিগার করা যেকোনো প্রক্সি নিষ্ক্রিয় করতে পারেন৷</translation>
<translation id="2955913368246107853">খোঁজ দণ্ড বন্ধ করুন</translation>
@@ -339,11 +384,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">নীতির ভুল প্রকার</translation>
<translation id="3037605927509011580">ইস!</translation>
<translation id="3041612393474885105">সার্টিফিকেট তথ্য</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">বহিরাগত অ্যাপ্লিকেশানের মাধ্যমে অর্থপ্রদান করার জন্য ছদ্মবেশী মোড থেকে বেরিয়ে যাচ্ছে। চালিয়ে যাবেন?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{কিছুই নয়}=1{১টি পাসওয়ার্ড}one{#টি পাসওয়ার্ড}other{#টি পাসওয়ার্ড}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">পিক-আপের ঠিকানা যোগ করুন</translation>
<translation id="3105172416063519923">সম্পদ আইডি:</translation>
<translation id="3109728660330352905">আপনার এই পৃষ্ঠাটি দেখার জন্য অনুমোদন নেই।</translation>
@@ -365,20 +413,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> এ <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">পেমেন্ট বাতিল করুন</translation>
<translation id="3207960819495026254">বুকমার্ক করা হয়েছে</translation>
-<translation id="3209375525920864198">অনুগ্রহ করে একটি সঠিক সেশনের নাম লিখুন।</translation>
+<translation id="321912867715453276">সতর্কতা: এই নীতির জন্য একই মান সহ একাধিক উৎস রয়েছে।</translation>
<translation id="3225919329040284222">সার্ভারটি এমন একটি সার্টিফিকেট উপস্থাপনা করেছে যা বিল্ট-ইন প্রত্যাশাগুলির সাথে মেলে না৷ এই প্রত্যাশাগুলি আপনাকে সুরক্ষিত করতে কিছু নিশ্চিত, উচ্চ সুরক্ষার ওয়েবসাইটের জন্য অন্তর্ভুক্ত৷</translation>
<translation id="3226128629678568754">পৃষ্ঠাটি লোড করতে প্রয়োজনীয় ডেটেটি আবার জমা দিতে আবার লোড করার বোতামটি টিপুন৷</translation>
<translation id="3227137524299004712">মাইক্রোফোন</translation>
<translation id="3228969707346345236">পৃষ্ঠাটি ইতিমধ্যে <ph name="LANGUAGE" />-এ থাকার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
+<translation id="3229041911291329567">আপনার ডিভাইস এবং ব্রাউজারের ভার্সন সম্বন্ধীয় তথ্য</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">কার্ডে থাকা নাম যোগ করুন</translation>
<translation id="3287510313208355388">যখন অনলাইন হবেন তখন ডাউনলোড করবেন</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> নীতি সম্পর্কে আরও জানুন</translation>
<translation id="3303855915957856445">কোনো সার্চ ফলাফল পাওয়া যায়নি</translation>
-<translation id="3305707030755673451">আপনার ডেটা আপনার সিঙ্ক পাসফ্রেজ দিয়ে <ph name="TIME" /> এ এনক্রিপ্ট করা হয়েছে। সিঙ্ক শুরু করার জন্য এটি লিখুন।</translation>
<translation id="3320021301628644560">বিলিংয়ের ঠিকানা যোগ করুন</translation>
<translation id="3324983252691184275">টকটকে লাল</translation>
<translation id="3338095232262050444">সুরক্ষিত</translation>
@@ -406,9 +455,11 @@
<translation id="3427342743765426898">&amp;সম্পাদনাকে আবার করুন</translation>
<translation id="342781501876943858">Chromium-এর নীতি অনুযায়ী আপনার পাসওয়ার্ড বদলে ফেলা উচিত যদি আপনি সেটি অন্য কোনও সাইটে ব্যবহার করে থাকেন।</translation>
<translation id="3431636764301398940">এই ডিভাইসে এই কার্ডটি সেভ করুন</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">এই ডিভাইসের মালিক ডাইনোসর গেমটি বন্ধ করেছেন৷</translation>
<translation id="3447884698081792621">সার্টিফিকেট দেখান (<ph name="ISSUER" /> এর দ্বারা জারি করা)</translation>
<translation id="3452404311384756672">বিরামকাল প্রাপ্ত করুন:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">হাইলাইটার</translation>
<translation id="3462200631372590220">উন্নত করার বিশদ বিবরণ, লুকান</translation>
<translation id="3467763166455606212">কার্ডহোল্ডারের নাম প্রয়োজন</translation>
@@ -431,20 +482,23 @@
<translation id="358285529439630156">ক্রেডিট এবং প্রিপেড কার্ড গ্রহণ করা হয়।</translation>
<translation id="3582930987043644930">নাম যোগ করুন</translation>
<translation id="3583757800736429874">&amp;সরানোর কাজটি আবার করুন</translation>
+<translation id="35866233670761917">আপনি যে ওয়েবসাইটগুলিতে যান সেগুলির কন্টেন্ট অ্যাডমিনিস্ট্রেটর দেখতে পান না</translation>
<translation id="3586931643579894722">বিশদ বিবরণ লুকান</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">সাইজ ২</translation>
<translation id="3615877443314183785">মেয়াদ শেষ হওয়ার তারিখের সঠিক মান লিখুন</translation>
<translation id="36224234498066874">ব্রাউজ করা ডেটা সাফ করুন...</translation>
<translation id="362276910939193118">সম্পূর্ণ ইতিহাস দেখুন</translation>
-<translation id="3623476034248543066">মান দেখান</translation>
<translation id="3630155396527302611">নেটওয়ার্ক অ্যাক্সেস করতে এটি যদি ইতোমধ্যে মঞ্জুরিকৃত প্রোগ্রাম হিসাবে তালিকাতে থাকে, তাহলে
তালিকাটি থেকে এটি সরানোর চেষ্টা করে আবার যোগ করে দেখুন।</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">বৈধতা যাচাইকরণ সফল হয়েছে</translation>
<translation id="3655670868607891010">আপনি যদি এটি প্রায়শই দেখতে পান, তাহলে <ph name="HELP_LINK" /> চেষ্টা করে দেখুন৷</translation>
<translation id="3658742229777143148">পুনর্বিবেচনা</translation>
<translation id="366077651725703012">ক্রেডিট কার্ড আপডেট করুন</translation>
<translation id="3676592649209844519">ডিভাইস আইডি:</translation>
+<translation id="3677008721441257057">আপনি কি &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; বোঝাতে চাইছেন?</translation>
<translation id="3678029195006412963">অনুরোধটি স্বাক্ষরিত করা যায়নি</translation>
<translation id="3678529606614285348">নতুন ছদ্মবেশী উইন্ডোতে (Ctrl-Shift-N) করে একটি পৃষ্ঠা খুলুন</translation>
<translation id="3679803492151881375">ক্র্যাশ প্রতিবেদন <ph name="CRASH_TIME" /> এ ক্যাপচার করা হয়েছে, <ph name="UPLOAD_TIME" /> এ আপলোড করা হয়েছে</translation>
@@ -452,13 +506,14 @@
<translation id="3704162925118123524">আপনি যে নেটওয়ার্কটি ব্যবহার করছেন সেটির জন্য অপনাকে এটির লগ ইন পৃষ্ঠাতে যেতে হতে পরে৷</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">লোড হচ্ছে...</translation>
+<translation id="3709599264800900598">আপনার কপি করা টেক্সট</translation>
<translation id="3712624925041724820">লাইসেন্সগুলির মেয়াদ শেষ হয়ে গেছে</translation>
<translation id="3714780639079136834">মোবাইল ডেটা বা ওয়াই-ফাই চালু করে দেখুন</translation>
<translation id="3715597595485130451">ওয়াই-ফাইতে কানেক্ট করুন</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />প্রক্সি, ফায়ারওয়াল এবং DNS কনফিগারেশন পরীক্ষা করে দেখুন<ph name="END_LINK" /></translation>
<translation id="372429172604983730">অ্যান্টিভাইরাস, ফায়ারওয়াল এবং ওয়েব-ফিল্টারিং বা প্রক্সি সফ্টওয়্যারের মতো অ্যাপ্লিকেশন এই ধরণের ত্রুটির কারণ হতে পারে।</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">আপনি কনফার্ম করার পর আপনার Google অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</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>
@@ -471,10 +526,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> এ মেয়াদ শেষ হবে</translation>
<translation id="3789155188480882154">সাইজ ১৬</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">ক্ষতিকর কন্টেন্ট ব্লক করা হয়েছে।</translation>
<translation id="3810973564298564668">পরিচালনা</translation>
<translation id="382518646247711829">যদি আপনি একটি প্রক্সি সার্ভার ব্যবহার করেন...</translation>
<translation id="3828924085048779000">ফাঁকা পাসফ্রেজের অনুমতি নেই৷</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> অতিরিক্ত ক্রিয়াকলাপের জন্য এক্সটেনশন ইনস্টল করেছে। এক্সটেনশন আপনার কিছু ডেটা অ্যাক্সেস করতে পারে।</translation>
<translation id="385051799172605136">ফিরুন</translation>
<translation id="3858027520442213535">তারিখ এবং সময় আপডেট করুন</translation>
<translation id="3884278016824448484">পরস্পর বিরোধী ডিভাইস সনাক্তকারী</translation>
@@ -482,6 +539,7 @@
<translation id="3886446263141354045">এই সাইটটি অ্যাক্সেস করার জন্য আপনার অনুরোধ <ph name="NAME" />কে পাঠানো হয়েছে</translation>
<translation id="3890664840433101773">ইমেল আইডি যোগ করুন</translation>
<translation id="3901925938762663762">কার্ডটির মেয়াদ শেষ হয়েছে</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">এই সাইটে সর্বদা জিজ্ঞাসা করুন</translation>
<translation id="3949571496842715403">এই সার্ভারটিকে <ph name="DOMAIN" /> হিসাবে প্রমাণ করা যায়নি; এটির নিরাপত্তা সার্টিফিকেটে সাবজেক্ট অল্টারনেটিভ নেম্স নির্দিষ্ট করা নেই। কনফিগারেশনের কোনও সমস্যা অথবা আপনার সংযোগে কোনও আক্রমণকারী আড়ি পাতার কারণে এটি হয়ে থাকতে পারে।</translation>
@@ -492,11 +550,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{কিছুই নয়}=1{১টি সাইট থেকে }one{#টি সাইট থেকে }other{#টি সাইট থেকে }}</translation>
<translation id="397105322502079400">গণনা করা হচ্ছে...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> অবরুদ্ধ হয়ে রয়েছে</translation>
-<translation id="3984550557525787191">এই নামের সেশন আগে থেকেই আছে।</translation>
<translation id="3987940399970879459">১ MB এর কম</translation>
+<translation id="4008849406247176967">সতর্কতা: এই নীতির জন্য পরস্পরবিরোধী মান সহ একাধিক উৎস রয়েছে!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{আশেপাশের ১টি ওয়েবপৃষ্ঠা}one{আশেপাশের #টি ওয়েবপৃষ্ঠা}other{আশেপাশের #টি ওয়েবপৃষ্ঠা}}</translation>
<translation id="4030383055268325496">&amp;যোগ করাকে পূর্বাবস্থায় ফেরান</translation>
+<translation id="4032320456957708163"><ph name="ENROLLMENT_DOMAIN" /> আপনার ব্রাউজার ম্যানেজ করে</translation>
<translation id="4058922952496707368">কী "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">সঠিক ঠিকানা যোগ করুন</translation>
<translation id="4072486802667267160">আপনার অর্ডার প্রক্রিয়া করার সময় একটি সমস্যা হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।</translation>
<translation id="4075732493274867456">ক্লায়েন্ট ও সার্ভারটি কোনো অভিন্ন SSL প্রোটোকল সংস্করণ বা সাইফার স্যুট সমর্থন করে না।</translation>
@@ -516,10 +576,12 @@
<translation id="4159784952369912983">বেগুনি</translation>
<translation id="4165986682804962316">সাইটের সেটিংস</translation>
<translation id="4171400957073367226">খারাপ যাচাইকরণের স্বাক্ষর</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{আরও <ph name="ITEM_COUNT" />টি আইটেম}one{আরও <ph name="ITEM_COUNT" />টি আইটেম}other{আরও <ph name="ITEM_COUNT" />টি আইটেম}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;সরানোর কাজটি আবার করুন</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ফায়ারওয়াল এবং অ্যান্টিভাইরাস কনফিগারেশন পরীক্ষা করে দেখুন<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;ধাপ ১: পোর্টালে সাইন-ইন করুন&lt;/h4&gt;
@@ -551,58 +613,79 @@
<translation id="4277028893293644418">পাসওয়ার্ড রিসেট করুন</translation>
<translation id="4280429058323657511">, মেয়াদ শেষ <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{এই কার্ডটি আপনার Google অ্যাকাউন্টে সেভ করা হয়েছে}one{এই কার্ডগুলি আপনার Google অ্যাকাউন্টে সেভ করা হয়েছে}other{এই কার্ডগুলি আপনার Google অ্যাকাউন্টে সেভ করা হয়েছে}}</translation>
+<translation id="42981349822642051">প্রসারিত করুন</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">পাল্টান</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">অবরুদ্ধ করুন (ডিফল্ট)</translation>
+<translation id="4318566738941496689">আপনার ডিভাইসের নাম এবং নেটওয়ার্ক ঠিকানা</translation>
<translation id="4325863107915753736">নিবন্ধ খুঁজে পেতে ব্যর্থ হয়েছে</translation>
<translation id="4326324639298822553">আপনার মেয়াদ শেষের তারিখ পরীক্ষা করে আবার চেষ্টা করুন</translation>
<translation id="4331708818696583467">সুরক্ষিত নয়</translation>
<translation id="4340982228985273705">এই কম্পিউটারটি এন্টারপ্রাইজ স্তরে পরিচালনা করা হচ্ছে হিসেবে শনাক্ত করা যায়নি, তাই নীতিটি শুধুমাত্র Chrome ওয়েব স্টোরে হোস্ট করা এক্সটেনশন নিজে থেকে ইনস্টল করতে পারবে। Chrome ওয়েব স্টোর আপডেটের ইউআরএল হল "<ph name="CWS_UPDATE_URL" />"।</translation>
<translation id="4346197816712207223">এই ক্রেডিট কার্ডগুলি গ্রহণ করা হয়</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">এই সাইটে আক্রমণকারীরা আপনার কম্পিউটারে ক্ষতিকারক প্রোগ্রাম ইনস্টল করতে পারে যা আপনার তথ্য (যেমন, ফটো, পাসওয়ার্ড, মেসেজ এবং ক্রেডিট কার্ড) চুরি করতে বা মুছে দিতে পারে।</translation>
<translation id="4358461427845829800">পেমেন্ট পদ্ধতিগুলি পরিচালনা করুন...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">প্রত্যাশিত <ph name="VALUE_TYPE" /> মান৷</translation>
<translation id="4377125064752653719">আপনি <ph name="DOMAIN" />-এ পৌঁছানোর প্রচেষ্টা করেছেন, তবে সার্ভারটি যে সার্টিফিকেটটি উপস্থাপন করেছে সেটির জারিকর্তা সেটিকে প্রত্যাহার করেছে৷ এর অর্থ হ'ল সার্ভারটি যে সুরক্ষা প্রমানপত্র উপস্থাপন করেছে তা কোনওমতেই বিশ্বাসযোগ্য নয়৷ হতে পারে আপনি একজন আক্রমণকারীর সাথে যোগাযোগ করছেন৷</translation>
<translation id="4378154925671717803">ফোন</translation>
<translation id="4406896451731180161">সার্চের ফলাফলগুলি</translation>
-<translation id="4406972042435603828">আপনার অ্যাডমিনিস্ট্রেটর শক্তিশালী ক্ষমতা আছে এমন এক্সটেনশন ইনস্টল করেছেন।</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" />টি কুকিজ</translation>
<translation id="4415426530740016218">পিক-আপের ঠিকানা</translation>
<translation id="4424024547088906515">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেট Chrome এর নিকট বিশ্বাসযোগ্য নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="443121186588148776">সিরিয়াল পোর্ট</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> আপনার লগ-ইন সার্টিফিকেটটি স্বীকার করেনি, অথবা কোনো সার্টিফিকেট দেওয়া হয়নি।</translation>
<translation id="4434045419905280838">পপ-আপ এবং রিডাইরেক্ট</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">প্রক্সির ব্যবহার অক্ষম করা হয়েছে কিন্তু কোনো স্পষ্ট প্রক্সি কনফিগারেশান নির্দিষ্ট করা হয়েছে৷</translation>
<translation id="445100540951337728">ডেবিট কার্ড গ্রহণ করা হয়</translation>
+<translation id="4466881336512663640">ফর্মে করা পরিবর্তনগুলি সেভ হবে না। আপনি কি চালিয়ে যেতে চান?</translation>
<translation id="4482953324121162758">এই সাইটটি অনুবাদ করা হবে না।</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">ইউআরএলটি সঠিক নয়। অবশ্যই স্ট্যান্ডার্ড স্কিম সহ ইউআরএল হতে হবে, যেমন http://example.com বা https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">যাচাইকরণের ত্রুটি: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">সিস্টেম প্রশাসকের সাথে যোগাযোগ করে দেখুন</translation>
<translation id="450710068430902550">প্রশাসকের সাথে ভাগ করছে</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">কার্ড ও ঠিকানাগুলি Chrome এবং আপনার Google অ্যাকাউন্ট (<ph name="ACCOUNT_EMAIL" />) থেকে এসেছে। আপনি <ph name="BEGIN_LINK" />সেটিংস<ph name="END_LINK" /> এ গিয়ে সেগুলি পরিচালনা করতে পারবেন।</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">বিশদ বিবরণ</translation>
<translation id="4524805452350978254">কার্ড ম্যানেজ করুন</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ফ্ল্যাশ</translation>
<translation id="4558551763791394412">আপনার এক্সটেনশানগুলি অক্ষম করে দেখুন।</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">পৌঁছে দেওয়া</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">কার্ডটি সরিয়ে দিন</translation>
<translation id="4587425331216688090">Chrome থেকে ঠিকানা সরাবেন?</translation>
<translation id="4592951414987517459">একটি আধুনিক সাইফার স্যুট ব্যবহার করে <ph name="DOMAIN" />-এ আপনার সংযোগ এনক্রিপ্ট করা হয়েছে।</translation>
<translation id="4594403342090139922">&amp;মুছে ফেলাকে পূর্বাবস্থায় ফেরান</translation>
<translation id="4597348597567598915">সাইজ ৮</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">আমাকে এখনই সেখানে নিয়ে চলুন</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেটে কিছু ত্রুটি আছে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="467809019005607715">Google স্লাইড্স</translation>
<translation id="4690462567478992370">কোনও ভুল সার্টিফিকেট ব্যবহার করা বন্ধ করুন</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">আপনার সংযোগ বাধাপ্রাপ্ত হয়েছে</translation>
<translation id="471880041731876836">এই সাইট দেখার অনুমতি আপনার নেই</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows নেটওয়ার্ক ডায়গনিস্টিক্স চালান<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">নীতিগুলি পুনঃলোড করুন</translation>
<translation id="4728558894243024398">প্ল্যাটফর্ম</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Chromium পুনরায় চালু করুন</translation>
<translation id="473775607612524610">আপডেট করুন</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> সার্চ সাজেশন</translation>
<translation id="4742407542027196863">পাসওয়ার্ডগুলি পরিচালনা করুন…</translation>
<translation id="4744603770635761495">সম্পাদনযোগ্য পথ</translation>
+<translation id="4746351372139058112">বার্তাগুলি</translation>
<translation id="4750917950439032686">আপনার তথ্য (উদাহরণস্বরূপ, পাসওয়ার্ড বা ক্রেডিট কার্ড নম্বর) যখন এই সাইটে পাঠানো হয় তখন সেটি ব্যক্তিগত থাকে।</translation>
<translation id="4756388243121344051">&amp;ইতিহাস</translation>
<translation id="4758311279753947758">পরিচিতির তথ্য জুড়ুন</translation>
@@ -610,9 +693,9 @@
<translation id="4764776831041365478"><ph name="URL" />-এ ওয়েবপৃষ্ঠাটি হতে পারে অস্থায়ীভাবে ডাউন আছে অথবা হতে পারে এটি স্থায়ীভাবে কোনো নতুন ওয়েব ঠিকানাতে সরানো হয়েছে৷</translation>
<translation id="4771973620359291008">একটি অজানা ত্রুটি ঘটেছে৷</translation>
<translation id="4785689107224900852">এই ট্যাবে পরিবর্তন করুন</translation>
-<translation id="4792143361752574037">সেশন ফাইলগুলি অ্যাক্সেস করার ক্ষেত্রে সমস্যা ছিল। ডিস্কে সেভ করা এখন অক্ষম করা আছে। আবার চেষ্টা করার জন্য, অনুগ্রহ করে পৃষ্ঠাটিকে আবার লোড করুন।</translation>
<translation id="4798078619018708837">আপনার কার্ডের বিবরণ আপডেট করতে <ph name="CREDIT_CARD" />-এর মেয়াদ শেষের তারিখ এবং সিভিসি লিখুন। আপনি কনফার্ম করার পর আপনার Google অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</translation>
<translation id="4800132727771399293">আপনার মেয়াদ শেষের তারিখ এবং CVC পরীক্ষা করুন এবং আবার চেষ্টা করুন</translation>
+<translation id="480334179571489655">আসল নীতি সংক্রান্ত সমস্যা</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>
@@ -627,7 +710,6 @@
<translation id="4881695831933465202">খুলুন</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>
@@ -636,15 +718,15 @@
<translation id="4943872375798546930">কোন ফলাফল নেই</translation>
<translation id="4950898438188848926">একটি ট্যাব থেকে অন্য ট্যাবে যাওয়ার বোতাম, খোলা ট্যাবে যেতে এন্টার টিপুন, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">ক্রিয়াসমূহ</translation>
-<translation id="495832697253704892">এক্সটেনশন রিপোর্ট করা</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">তালিকা প্রসারিত করুন</translation>
<translation id="4974590756084640048">সতর্কবার্তাগুলি পুনঃসক্ষম করুন</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">সবগুলি দেখুন</translation>
<translation id="4989809363548539747">এই প্লাগ ইন সমর্থিত নয়</translation>
-<translation id="4996230189582812866">জানানো</translation>
<translation id="5002932099480077015">সক্রিয় করা হলে, ফর্ম পূরনের কাজ দ্রুত করতে Chrome এই ডিভাইসে আপনার কার্ডের একটি প্রতিলিপি সংরক্ষণ করবে।</translation>
-<translation id="5014174725590676422">Chrome প্রথমবার চালানোর সময়ে Google অ্যাসিস্ট্যান্ট কীভাবে কাজ করবে তা দেখানো হয়েছে</translation>
<translation id="5015510746216210676">মেশিনের নাম:</translation>
+<translation id="5017554619425969104">আপনার কপি করা টেক্সট</translation>
<translation id="5018422839182700155">এই পৃষ্ঠাটি খোলা যাচ্ছে না</translation>
<translation id="5019198164206649151">ব্যাকিং স্টোরটি ত্রুটিপূর্ণ অবস্থায় আছে</translation>
<translation id="5023310440958281426">আপনার প্রশাসকের নীতিগুলি দেখুন</translation>
@@ -654,35 +736,51 @@
<translation id="5034369478845443529">স্থানীয় প্রসঙ্গ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">অনুমতি দিন</translation>
<translation id="5040262127954254034">গোপনীয়তা</translation>
+<translation id="5043480802608081735">আপনার কপি করা লিঙ্ক</translation>
<translation id="5045550434625856497">ভুল পাসওয়ার্ড</translation>
<translation id="5056549851600133418">আপনার জন্য নিবন্ধগুলি</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />প্রক্সি ঠিকানা পরীক্ষা করে দেখুন<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM ব্যবহারের মতো ডিভাইসের পরিসংখ্যান</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">আপনার ডিভাইস <ph name="ENROLLMENT_DOMAIN" /> ও আপনার অ্যাকাউন্ট <ph name="ACCOUNT_DOMAIN" />-এর দ্বারা পরিচালিত হয়। অর্থাৎ, অ্যাডমিনিস্ট্রেটর দূর থেকে আপনার ডিভাইস ও অ্যাকাউন্ট কনফিগার করতে পারেন।</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(৬৪-বিট)</translation>
-<translation id="5128122789703661928">এই নামের সেশনটি মুছে ফেলার জন্য সঠিক নয়।</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">ঠিকানাগুলি পরিচালনা করুন...</translation>
+<translation id="5138227688689900538">কম দেখুন</translation>
<translation id="5141240743006678641">আপনার Google সার্টিফিকেটের সাথে সিঙ্ক করা পাসওয়ার্ডগুলি এনক্রিপ্ট করুন৷</translation>
<translation id="5145883236150621069">নীতি প্রতিক্রিয়ার মধ্যে ত্রুটি কোড উপস্থিত</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">নতুন ছদ্মবেশী উইন্ডোতে (⇧⌘N) করে একটি পৃষ্ঠা খুলুন</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" />-এর জন্য সিভিসি লিখুন। আপনি কনফার্ম করার পর আপনার Google অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</translation>
<translation id="5169827969064885044">আপনি নিজের প্রতিষ্ঠানের অ্যাকাউন্টের অ্যাক্সেস হারাতে পারেন অথবা আপনার পরিচয় চুরি হয়ে যেতে পারে। Chrome এখনই আপনার পাসওয়ার্ড পরিবর্তন করার আর্জি জানাচ্ছে।</translation>
<translation id="5171045022955879922">খুঁজুন বা URL লিখুন</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">যন্ত্র</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />-এ নেই? এই ত্রুটি রিপোর্ট করুন</translation>
<translation id="5190835502935405962">বুকমার্ক দণ্ড</translation>
-<translation id="5200263511887412697">ডিভাইসে সম্প্রতি লগ-ইন করেছেন এমন ব্যবহারকারীর একটি সূচি প্রদান করে</translation>
+<translation id="519422657042045905">ব্যাখ্যা নেই</translation>
<translation id="5201306358585911203">এই পৃষ্ঠার এম্বেডেড করা একটি পৃষ্ঠায় এটি দেখানো হচ্ছে</translation>
<translation id="5205222826937269299">নাম প্রয়োজন</translation>
<translation id="5215116848420601511">Google Pay ব্যবহার করে এমন পেমেন্টের পদ্ধতি এবং ঠিকানা</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ইমেল আইডি প্রয়োজন</translation>
<translation id="5230733896359313003">শিপিংয়ের ঠিকানা</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"নেটওয়ার্কে কানেক্ট করুন"</translation>
<translation id="5251803541071282808">ক্লাউড</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">নেটওয়ার্ক ঠিকানা</translation>
<translation id="5285570108065881030">সেভ করা সমস্ত পাসওয়ার্ড দেখান</translation>
<translation id="5287240709317226393">কুকিজ দেখান</translation>
<translation id="5288108484102287882">নীতির মূল্য যাচাইকরণ থেকে সতর্কতা পাওয়া গেছে</translation>
@@ -694,7 +792,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> এর মধ্যে <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">পরিচিতির তথ্য বেছে নিন</translation>
<translation id="5327248766486351172">নাম</translation>
+<translation id="5329858041417644019">আপনার ব্রাউজারটি ম্যানেজ করা হয়নি</translation>
<translation id="5332219387342487447">শিপিংয়ের মাধ্যম</translation>
+<translation id="5334013548165032829">বিস্তারিত সিস্টেম লগ</translation>
<translation id="5344579389779391559">এই পৃষ্ঠাতে আপনাকে চার্জ করা হতে পারে</translation>
<translation id="5355557959165512791">ওয়েবসাইটটির সার্টিফিকেট তুলে নেওয়ার কারণে আপনি এখন <ph name="SITE" /> এ যেতে পারবেন না। নেটওয়ার্ক সমস্যা এবং আক্রমণ সাধারণত সাময়িকভাবে হয়, তাই এই পৃষ্ঠাটি সম্ভবত পরে কাজ করবে।</translation>
<translation id="536296301121032821">নীতি সেটিংস সংরক্ষণ করতে ব্যর্থ হয়েছে</translation>
@@ -702,6 +802,7 @@
<translation id="5377026284221673050">"আপনার ঘড়ি লেটে চলছে" অথবা "আপনার ঘড়ি ফাস্ট আছে" অথবা "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">সমস্ত ডিভাইসে আপনার কার্ড ব্যবহার করতে, সাইন-ইন করে সিঙ্ক চালু করুন।</translation>
<translation id="5386426401304769735">এই সাইটের সার্টিফিকেট শৃঙ্খলে SHA-1 ব্যবহার করে স্বাক্ষর করা একটি সার্টিফিকেট রয়েছে।</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেট এই সময়ে বৈধ নয়। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
<translation id="5421136146218899937">ব্রাউজিং ডেটা সাফ করুন...</translation>
<translation id="5430298929874300616">বুকমার্ক সরান</translation>
@@ -712,6 +813,7 @@
<translation id="5457113250005438886">অবৈধ</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;সম্পাদনাকে আবার করুন</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">এই কন্টেন্ট আপনার ডিভাইসে এমন বিপজ্জনক সফ্টওয়্যার ইনস্টল করার চেষ্টা করতে পারে যা আপনার তথ্য চুরি করে বা মুছে দেয়। <ph name="BEGIN_LINK" />তবুও এটি দেখতে চাই<ph name="END_LINK" /></translation>
<translation id="54817484435770891">বৈধ ঠিকানা যোগ করুন</translation>
<translation id="5490432419156082418">ঠিকানা এবং আরও অনেককিছু</translation>
@@ -719,10 +821,12 @@
<ph name="LINE_BREAK" />
আপনার সিস্টেম প্রশাসকের সাথে যোগাযোগের চেষ্টা করুন।</translation>
<translation id="549333378215107354">সাইজ ৩</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">পরিচালিত বুকমার্কগুলি</translation>
<translation id="5510766032865166053">এটি হয়ত সরানো বা মুছে ফেলা হয়েছে।</translation>
<translation id="5523118979700054094">নীতি নাম</translation>
<translation id="552553974213252141">পাঠ্য কি সঠিকভাবে প্রাপ্ত হয়েছে?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">অনুরোধকৃত নিবন্ধ খুঁজে পাওয়া যায়নি৷</translation>
<translation id="5541546772353173584">ইমেল আইডি যোগ করুন</translation>
<translation id="5545756402275714221">আপনার জন্য নিবন্ধ</translation>
@@ -737,15 +841,21 @@
<translation id="5595485650161345191">ঠিকানা সম্পাদনা করুন</translation>
<translation id="5598944008576757369">পেমেন্টের পদ্ধতি বেছে নিন</translation>
<translation id="560412284261940334">পরিচালনা সমর্থিত নয়</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">সংযোগ পরীক্ষা করে দেখুন</translation>
<translation id="5610807607761827392">আপনি <ph name="BEGIN_LINK" />সেটিংস<ph name="END_LINK" /> থেকে কার্ড এবং ঠিকানাগুলি পরিচালনা করতে পারেন।</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> আপনাকে অনেক বেশিবার পুনঃনির্দেশিত করেছে।</translation>
<translation id="5629630648637658800">নীতি সেটিংস লোড করতে ব্যর্থ হয়েছে</translation>
<translation id="5631439013527180824">অবৈধ ডিভাইস পরিচালনা টোকেন</translation>
+<translation id="5632627355679805402"><ph name="TIME" />-এ আপনার <ph name="BEGIN_LINK" />Google পাসওয়ার্ড<ph name="END_LINK" /> দিয়ে ডেটা এনক্রিপ্ট করা হয়েছিল। সিঙ্ক শুরু করতে এটি লিখুন।</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="563324245173044180">প্রতারণামূলক কন্টেন্ট ব্লক করা হয়েছে।</translation>
<translation id="5659593005791499971">ইমেল আইডি</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">এই ডিভাইসের অ্যাডমিনিস্ট্রেটর অতিরিক্ত ক্রিয়াকলাপের জন্য এক্সটেনশন ইনস্টল করেছেন। এক্সটেনশন আপনার কিছু ডেটা অ্যাক্সেস করতে পারে।</translation>
<translation id="5675650730144413517">এই পৃষ্ঠাটি কাজ করছে না</translation>
+<translation id="5684874026226664614">ওহো৷ এই পৃষ্ঠাটির অনুবাদ করা যাবে না৷</translation>
<translation id="5685654322157854305">শিপিং ঠিকানা যোগ করুন</translation>
<translation id="5689199277474810259">JSON এ রপ্তানি করুন</translation>
<translation id="5689516760719285838">লোকেশন</translation>
@@ -754,38 +864,39 @@
<translation id="5710435578057952990">এই ওয়েবসাইটির পরিচয় যাচাই করা হয় নি৷</translation>
<translation id="5719499550583120431">প্রিপেড কার্ড গ্রহণ করা হয়।</translation>
<translation id="5720705177508910913">বর্তমান ব্যবহারকারী</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome-এর নীতি অনুযায়ী আপনার পাসওয়ার্ড বদলে ফেলা উচিত যদি আপনি সেটি অন্য কোনও সাইটে ব্যবহার করে থাকেন।</translation>
<translation id="5732392974455271431">আপনার পিতামাতা এটি আপনার জন্য অবরোধ মুক্ত করতে পারবেন</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Google অ্যাকাউন্টে কার্ড সেভ করুন}one{Google অ্যাকাউন্টে কার্ড সেভ করুন}other{Google অ্যাকাউন্টে কার্ড সেভ করুন}}</translation>
<translation id="5763042198335101085">একটি সঠিক ইমেল আইডি লিখুন</translation>
<translation id="5765072501007116331">ডেলিভারির পদ্ধতি এবং প্রয়োজনীয়তাগুলি দেখতে একটি ঠিকানা বেছে নিন</translation>
-<translation id="5770114862687765385">ফাইলটি ত্রুটিপূর্ণ বলে মনে হচ্ছে। সেশনটি রিসেট করার জন্য 'রিসেট' বোতামে ক্লিক করুন।</translation>
<translation id="5778550464785688721">MIDI ডিভাইসসমূহ পূর্ণ নিয়ন্ত্রণ</translation>
<translation id="578305955206182703">হলুদাভ বাদামি</translation>
<translation id="57838592816432529">মিউট করুন</translation>
<translation id="5784606427469807560">আপনার কার্ডটি নিশ্চিত করতে একটি সমস্যা হয়েছিল৷আপনার ইন্টারনেট সংযোগ পরীক্ষা করে আবার চেষ্টা করুন৷</translation>
<translation id="5785756445106461925">উপরন্তু, এই পৃষ্ঠাতে অন্যান্য সংস্থান অন্তর্ভুক্ত রয়েছে যা নিরাপদ নয়৷ এই সংস্থানগুলি ট্রানজিটের সময় অন্যরা দেখতে পাবে এবং পৃষ্ঠাটির চেহারাটি পরিবর্তন করতে কোনও আক্রমণকারী এর পরিবর্তন করতে পারেন৷</translation>
<translation id="5786044859038896871">আপনি কি আপনার কার্ডের তথ্য পূরণ করতে চান?</translation>
+<translation id="5798290721819630480">পরিবর্তনগুলি খারিজ করবেন?</translation>
<translation id="5798683403665926540">Chrome সেটিংসে হোম পৃষ্ঠা পরিবর্তন করুন</translation>
<translation id="5803412860119678065">আপনি কি আপনার <ph name="CARD_DETAIL" /> এর তথ্য পূরণ করতে চান?</translation>
<translation id="5804241973901381774">অনুমতিগুলি</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" />-এ আপনার সংযোগ একটি অপ্রচলিত সাইফার স্যুট ব্যবহার করে এনক্রিপ্ট করা হয়েছে৷</translation>
<translation id="5813119285467412249">&amp;যোগ করাকে পুনরায় করুন</translation>
<translation id="5838278095973806738">এই সাইটে আপনার কোনো সংবেদনশীল তথ্য দেওয়া উচিত হবে না (উদাহরণস্বরূপ, পাসওয়ার্ড বা ক্রেডিট কার্ড) কারণ আক্রমণকারীরা এগুলি চুরি করতে পারে।</translation>
+<translation id="5860033963881614850">বন্ধ করুন</translation>
<translation id="5863847714970149516">পরের পৃষ্ঠাতে আপনাকে চার্জ করা হতে পারে</translation>
<translation id="5866257070973731571">ফোন নম্বর যোগ করুন</translation>
<translation id="5869405914158311789">এই সাইটটিতে পৌছানো যাচ্ছে না</translation>
<translation id="5869522115854928033">সংরক্ষিত পাসওয়ার্ড</translation>
<translation id="5887400589839399685">কার্ড সেভ করা হয়েছে</translation>
-<translation id="5893718151540690985">ধরন ও হার্ডওয়্যার ঠিকানা সহ নেটওয়ার্ক ইন্টারফেসের একটি সূচি দেখায়</translation>
<translation id="5893752035575986141">ক্রেডিট কার্ড গ্রহণ করা হয়।</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="5916664084637901428">চালু</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google অ্যাকাউন্টে কার্ড সেভ করবেন?</translation>
<translation id="5922853866070715753">প্রায় শেষ</translation>
<translation id="5932224571077948991">সাইট ব্যাঘাত সৃষ্টিকারী বা বিভ্রান্তিকর বিজ্ঞাপন দেখায়</translation>
-<translation id="5939518447894949180">রিসেট করুন</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> খুলছে…</translation>
<translation id="5951495562196540101">ক্রেতার অ্যাকাউন্টের মাধ্যমে এনরোল করা যাচ্ছে না (প্যাকেজ লাইসেন্স পাওয়া যাবে)৷</translation>
<translation id="5967592137238574583">পরিচিতির তথ্য সম্পাদনা করুন</translation>
@@ -793,6 +904,7 @@
<translation id="5975083100439434680">জুম কমান</translation>
<translation id="5977489021191000276">কোনও অ্যাডমিনিস্ট্রেটর আপনার ডিভাইস পরিচালনা করেন না।</translation>
<translation id="5977976211062815271">এই ডিভাইসে</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">পেমেন্ট অ্যাপ খোলা যাচ্ছে না</translation>
<translation id="5989320800837274978">কোনো নির্ধারিত প্রক্সি সার্ভার অথবা একটি.pac স্ক্রিপ্ট UR সুর্নিদিষ্টভাবে উল্লেখ করা হয়নি৷</translation>
<translation id="5990559369517809815">সার্ভারে অনুরোধগুলি একটি এক্সটেনশন দিয়ে ব্লক করা আছে৷</translation>
@@ -803,8 +915,8 @@
<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="6033927989869462158">CPU/RAM ব্যবহারের মতো হার্ডওয়্যার পরিসংখ্যান অ্যাডমিনিস্ট্রেটরকে দেখায়</translation>
<translation id="6034000775414344507">হালকা ধূসর</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">যদি সমস্যাটি চলতে থাকে তবে সাইট মালিকের সাথে যোগাযোগ করুন।</translation>
<translation id="6040143037577758943">বন্ধ</translation>
<translation id="6044573915096792553">সাইজ ১২</translation>
@@ -813,10 +925,10 @@
<translation id="6051221802930200923">ওয়েবসাইটটি পিন করা সার্টিফিকেট ব্যবহার করার কারণে আপনি এখন <ph name="SITE" /> এ যেতে পারবেন না। নেটওয়ার্ক সমস্যা এবং আক্রমণ সাধারণত সাময়িকভাবে হয়, তাই এই পৃষ্ঠাটি সম্ভবত পরে কাজ করবে।</translation>
<translation id="6058977677006700226">আপনার সমস্ত ডিভাইসে কার্ডগুলি ব্যবহার করবেন?</translation>
<translation id="6059925163896151826">USB ডিভাইসগুলি</translation>
-<translation id="6071091556643036997">নীতির এই ধরনটি ব্যবহার করা যাবে না।</translation>
<translation id="6080696365213338172">অ্যাডমিনিস্ট্রেটরের দ্বারা সরবরাহ করা সার্টিফিকেট ব্যবহার করে আপনি কন্টেন্ট ব্যবহার করেছেন৷ <ph name="DOMAIN" />-কে আপনি যে ডেটা সরবরাহ করেন তাতে আপনার অ্যাডমিনিস্ট্রেটর বাধা দিতে পারে৷</translation>
<translation id="6094273045989040137">ব্যাখ্যা করুন</translation>
<translation id="610911394827799129"><ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> এ আপনার Google অ্যাকাউন্টের অন্যান্য ধরনের ব্রাউজিংয়ের ইতিহাস থাকতে পারে</translation>
+<translation id="6132597952260690497">ইনস্টল করা এক্সটেনশন এবং প্লাগ-ইন সম্বন্ধীয় তথ্য</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{কিছুই নয়}=1{১টি পাসওয়ার্ড (সিঙ্ক করা হয়েছে)}one{#টি পাসওয়ার্ড (সিঙ্ক করা হয়েছে)}other{#টি পাসওয়ার্ড (সিঙ্ক করা হয়েছে)}}</translation>
<translation id="6146055958333702838">সব কেবল পরীক্ষা করুন এবং আপনি ব্যবহার করছেন এমন যেকোনো রাউটার, মডেম বা অন্যান্য নেটওয়ার্ক ডিভাইসগুলি আবার চালু করুন।</translation>
<translation id="614940544461990577">এটি করে দেখুন:</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> জায়গা খালি করে। পরের বার যখন দেখবেন তখন কিছু সাইট লোড হতে দেরি হতে পারে।</translation>
<translation id="6337534724793800597">নাম অনুসারে ফিল্টারগুলি বাছাই করুন</translation>
<translation id="6358450015545214790">এর অর্থ কী?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">চালিয়ে গেলে চার্জ দিতে হতে পারে।</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{আরও ১টি প্রস্তাব}one{অন্যান্য #টি প্রস্তাব}other{অন্যান্য #টি প্রস্তাব}}</translation>
<translation id="6387754724289022810">পরের বার আরও দ্রুত পেমেন্ট করা জন্য আপনার এই কার্ড এবং বিলিং ঠিকানাটি Google অ্যাকাউন্টে এবং এই ডিভাইসে সেভ করে রাখুন।</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">বুকমার্ক সম্পাদনা করুন</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> এর মেয়াদ শেষের তারিখ এবং CVC লিখুন</translation>
<translation id="6414888972213066896">এই সাইটটি ঘুরে দেখা ঠিক হবে কিনা সেই বিষয়ে আপনি আপনার পিতামাতাকে জিজ্ঞাসা করেছেন</translation>
<translation id="6417515091412812850">সার্টিফিকেটকরণটি প্রত্যাহার করা হয়েছে কিনা তা যাচাইয়ে অক্ষম৷</translation>
<translation id="6433490469411711332">পরিচিতি তথ্য সম্পাদনা করুন</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> সংযোগ করতে প্রত্যাখ্যান করেছে।</translation>
+<translation id="6434309073475700221">বাতিল</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">আরও তথ্য যোগ করুন</translation>
<translation id="6447842834002726250">কুকিজ</translation>
<translation id="6451458296329894277">ফর্ম পুনঃজমা নিশ্চিত করুন</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Chrome পুনরায় চালু করুন</translation>
<translation id="6529602333819889595">&amp;মুছে ফেলাকে আবার করুন</translation>
<translation id="6534179046333460208">বাস্তবিক ওয়েব প্রস্তাবনাগুলি</translation>
+<translation id="6556866813142980365">আবার করুন</translation>
<translation id="6563469144985748109">আপনার পরিচালক এখনও এটি অনুমোদন করেন নি</translation>
<translation id="6569060085658103619">আপনি একটি এক্সটেনশন পৃষ্ঠা দেখছেন</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">হালকা গোলাপি</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">আপনার কপি করা লিঙ্ক</translation>
+<translation id="6591833882275308647">আপনার <ph name="DEVICE_TYPE" /> ম্যানেজ করা হয়নি</translation>
<translation id="6596325263575161958">এনক্রিপশন বিকল্পগুলি</translation>
<translation id="6604181099783169992">মোশন বা হাল্কা সেন্সর</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">পরিচিতির তথ্য</translation>
<translation id="6626291197371920147">বৈধ কার্ড নম্বর যোগ করুন</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> সার্চ</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">এই নীতিটি অসমর্থিত হয়েছে৷</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{কিছুই নয়}=1{১টি সাইট থেকে (আপনাকে আপনার Google অ্যাকাউন্ট থেকে সাইন-আউট করা হবে না)}one{#টি সাইট থেকে (আপনাকে আপনার Google অ্যাকাউন্ট থেকে সাইন-আউট করা হবে না)}other{#টি সাইট থেকে (আপনাকে আপনার Google অ্যাকাউন্ট থেকে সাইন-আউট করা হবে না)}}</translation>
<translation id="6657585470893396449">পাসওয়ার্ড</translation>
+<translation id="6670613747977017428">সুরক্ষিত জায়গায় ফিরুন।</translation>
<translation id="6671697161687535275">Chromium থেকে ফর্ম প্রস্তাবনা সরাবেন?</translation>
<translation id="6685834062052613830">প্রস্থান করুন করে সেটআপ সম্পূর্ণ করুন</translation>
<translation id="6710213216561001401">পূর্ববর্তী</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">নথিভুক্ত করার জন্য টোকেন:</translation>
<translation id="6711464428925977395">প্রক্সী সার্ভারের কোনো সমস্যা হয়েছে, অথবা ঠিকানাটি ভুল।</translation>
<translation id="6723740634201835758">আপনার Google অ্যাকাউন্টে</translation>
+<translation id="6738516213925468394"><ph name="TIME" />-এ আপনার <ph name="BEGIN_LINK" />সিঙ্ক পাসফ্রেজ<ph name="END_LINK" /> দিয়ে ডেটা এনক্রিপ্ট করা হয়েছিল। সিঙ্ক শুরু করতে সেটি লিখুন।</translation>
<translation id="674375294223700098">অজানা সার্ভার সার্টিফিকেট ত্রুটি৷</translation>
<translation id="6744009308914054259">কানেকশনের জন্য অপেক্ষা করার সময়, আপনি ডাউনলোডে গিয়ে অফলাইন নিবন্ধগুলি পড়তে পারেন।</translation>
<translation id="6753269504797312559">নীতি মান</translation>
<translation id="6757797048963528358">আপনার ডিভাইস নিদ্রা মোডে গিয়েছে।</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">আপনার পিতামাতা এখনও এটি অনুমোদন করেন নি</translation>
<translation id="67862343314499040">বেগুনি</translation>
+<translation id="6786747875388722282">এক্সটেনশানসমূহ</translation>
<translation id="679355240208270552">নীতি অনুযায়ী ডিফল্ট সার্চ সক্ষম করা হয়নি তাই উপেক্ষা করা হয়েছে৷</translation>
<translation id="681021252041861472">এই ফিল্ডটি ফাঁকা রাখা যাবে না</translation>
<translation id="6810899417690483278">কাস্টমাইজেশন আইডি</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">ডিভাইস</translation>
<translation id="6970216967273061347">জেলা</translation>
<translation id="6973656660372572881">স্থির প্রক্সি সার্ভার এবং .pac স্ক্রিপ্ট URL-এর উভয়ই নির্দিষ্ট আছে৷</translation>
+<translation id="6973932557599545801">আমি সাহায্য করতে পারছি না, নিজের মতো করে এগিয়ে যান।</translation>
<translation id="6979158407327259162">Google ড্রাইভ</translation>
<translation id="6979440798594660689">মিউট (ডিফল্ট)</translation>
<translation id="6984479912851154518">এক্সটার্নাল অ্যাপ্লিকেশনের মাধ্যমে পেমেন্ট করার জন্য ব্যক্তিগত মোড থেকে বেরিয়ে যাচ্ছে। চালিয়ে যেতে চান?</translation>
<translation id="6989763994942163495">উন্নত সেটিংস দেখান ...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> ভাষায় থাকলে সবসময় অনুবাদ করা হবে</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">এই চার্জটি একবার করা হতে পারে অথবা বারবার করা হতে পারে এবং স্পষ্টভাবে তথ্য নাও থাকতে পারে।</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">লুকান</translation>
<translation id="7108819624672055576">একটি এক্সটেনশন দ্বারা অনুমোদিত</translation>
<translation id="7111012039238467737">(সঠিক)</translation>
+<translation id="7118618213916969306">ক্লিপবোর্ড ইউআরএল <ph name="SHORT_URL" /> সার্চ করুন</translation>
<translation id="7119414471315195487">অন্যান্য ট্যাব বা প্রোগ্রাম বন্ধ করুন</translation>
<translation id="7129409597930077180">এই ঠিকানায় শিপিং করা যাবে না। অন্য ঠিকানা বেছে নিন।</translation>
<translation id="7135130955892390533">স্ট্যাটাস দেখুন</translation>
<translation id="7138472120740807366">ডেলিভারির পদ্ধতি</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ল্যাভেণ্ডার</translation>
-<translation id="7158980942472052083">ভুল ইউআরএল ইউআরএলে স্ট্যান্ডার্ড স্কিম থাকতে হবে।</translation>
<translation id="717330890047184534">Gaia আইডি:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">আপনি যে সার্ভারে যাচ্ছেন, <ph name="ORIGIN" />, সেটিতে করা যেকোনও অনুরোধের জন্যই একটি নিরাপত্তা নীতি
+ প্রযুক্ত হবে বলে সেটি জানাচ্ছে। কিন্তু এটি
+ নীতি পাঠানোর পরিবর্তে ব্রাউজারকে অন্য কোথাও রিডাইরেক্ট করে দিয়েছে বলে
+ ব্রাউজার আপনার অনুরোধ করা <ph name="SITE" /> দেখাতে পারছে না।</translation>
<translation id="7179323680825933600">পেমেন্টের পদ্ধতিগুলি সেভ করুন এবং আপনা-আপনি পূরণ করুন</translation>
<translation id="7180611975245234373">রিফ্রেশ করুন</translation>
<translation id="7182878459783632708">কোন নীতি সেট করা নেই</translation>
<translation id="7186367841673660872">এই পৃষ্ঠাটি<ph name="ORIGINAL_LANGUAGE" />থেকে<ph name="LANGUAGE_LANGUAGE" />তে অনুবাদ করা হয়েছে</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> জায়গা খালি করে। পরের বার যখন দেখবেন তখন কিছু সাইট লোড হতে দেরি হতে পারে।</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">আপনার অ্যাডমিনিস্ট্রেটর দেখতে পাবেন:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> নিরাপত্তা মান মেনে চলে না।</translation>
<translation id="721197778055552897">এই সমস্যাটি সম্পর্কে <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" />৷</translation>
<translation id="7219179957768738017">এই সংযোগটি <ph name="SSL_VERSION" />টি ব্যবহার করে</translation>
<translation id="7220786058474068424">প্রক্রিয়ায় রয়েছে</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">এই সাইটটিতে ম্যালওয়্যার আছে</translation>
+<translation id="724766306220616965">সতর্কতা, দ্বন্দ্ব</translation>
<translation id="724975217298816891">আপনার কার্ডের বিবরণ আপডেট করার জন্য মেয়াদ শেষের তারিখ এবং <ph name="CREDIT_CARD" /> এর CVC লিখুন। আপনি নিশ্চিত করলে, আপনার কার্ডের বিবরণ এই সাইটের সাথে শেয়ার করা হবে।</translation>
<translation id="7251437084390964440">নেটওয়ার্ক কনফিগারেশন ONC মানদণ্ড মেনে চলছে না। কনফিগারেশনের কিছু অংশ ইমপোর্ট করা নাও হতে পারে৷
অতিরিক্ত বিবরণ:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">কোবাল্ট নীল</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />-এ ক্র্যাশ প্রতিবেদন ক্যাপচার করা হয়েছে (ব্যবহারকারীর আপলোডের অনুরোধ করেছেন, এখনও আপলোড করা হয়নি)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" /> সংক্রান্ত সতর্কতা</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">কানেকশন সহায়তা</translation>
<translation id="7334320624316649418">&amp;পুনর্বিন্যাসকে আবার করুন</translation>
<translation id="733923710415886693">সার্ভারের সার্টিফিকেটটি সার্টিফিকেটের স্বচ্ছতার মাধ্যমে প্রকাশ করা হয়নি।</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">কম্যান্ড লাইন</translation>
-<translation id="7365061714576910172">Linux এক্সপোর্ট করুন</translation>
<translation id="7372973238305370288">ফলাফল খুঁজুন</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">না</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">ম্যানেজ করা সেশন ওভাররাইড</translation>
<translation id="7390545607259442187">কার্ড নিশ্চিত করুন</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">আপনার <ph name="DEVICE_NAME" /> ম্যানেজ করা হচ্ছে</translation>
<translation id="7407424307057130981">&lt;p&gt;আপনার Windows কম্পিউটারে Superfish সফ্টওয়্যারটি ইনস্টল করা থাকলে এই সমস্যাটি হবে।&lt;/p&gt;
&lt;p&gt;ইন্টারনেটে কানেক্ট করার জন্য এই সফ্টওয়্যারটি সাময়িকভাবে বন্ধ রাখতে এই ধাপগুলি অনুসরণ করুন। এর জন্য অ্যাডমিনিস্ট্রেটরের সুবিধা থাকতে হবে।&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;&lt;strong&gt;প্রয়োগ করুন&lt;/strong&gt;-এ ক্লিক করে, &lt;strong&gt;ঠিক আছে&lt;/strong&gt;বোতামে ক্লিক করুন
&lt;li&gt;কম্পিউটার থেকে সফ্টওয়্যারটি স্থায়ীভাবে সরিয়ে দেওয়ার পদ্ধতি জানতে &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome সহায়তা কেন্দ্রে&lt;/a&gt; যান
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> ম্যানেজমেন্ট</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">পাসওয়ার্ডগুলি পরিচালনা করুন…</translation>
<translation id="7419106976560586862">প্রোফাইল পথ</translation>
<translation id="7437289804838430631">পরিচিতির তথ্য যোগ করুন</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">হালকা কমলা</translation>
<translation id="7444046173054089907">সাইটটি অবরুদ্ধ</translation>
<translation id="7445762425076701745">আপনি যে সার্ভারে সংযুক্ত রয়েছে সেটিকে সম্পূর্ণ যাচাই করতে পারা যায় না৷ আপনি নামগুলি দিয়ে এমন একটি সার্ভারে সংযুক্ত রয়েছেন যা আপনার নেটওয়ার্কে বৈধ, যেটি একটি বাহ্যিক শংসাকরণ কর্তৃপক্ষ যার এটির মালিকানা যাচাই করার কোনও উপায় নেই৷ কিছু সার্টিফিকেট কর্তৃপক্ষ এই নামগুলি নির্বিচারে সার্টিফিকেটগুলি ইস্যু করবে, আপনি উদ্দিষ্ট ওয়েবসাইটে সংযুক্ত রয়েছেন কোনও আক্রমণকারীতে নয় তা নিশ্চিত করার কোনও উপায় নেই৷</translation>
-<translation id="7449109375006139765">ম্যানেজমেন্ট সার্ভারে সিস্টেম লগ পাঠান</translation>
<translation id="7451311239929941790">এই সমস্যা সম্পর্কে <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" />।</translation>
<translation id="7455133967321480974">বিশ্বব্যাপী ডিফল্ট ব্যবহার করুন (অবরোধ করুন)</translation>
<translation id="7460618730930299168">আপনি যা বেছে নিয়েছেন তার থেকে স্ক্রিনিংটি আলাদা। এগিয়ে যাবেন?</translation>
<translation id="7473891865547856676">না থাক</translation>
-<translation id="7475525192983021547">কোনও ব্যবহারকারীর ডিভাইস ব্যবহার করার সময়কাল দেখায়</translation>
<translation id="7481312909269577407">ফরওয়ার্ড</translation>
<translation id="7485870689360869515">কোনো ডেটা পাওয়া যায়নি৷</translation>
+<translation id="7498234416455752244">এডিট করতে থাকুন</translation>
<translation id="7508255263130623398">ফিরে পাওয়া নীতির ডিভাইস আইডি খালি অথবা বর্তমান ডিভাইস আইডির সাথে মিলছে না</translation>
<translation id="7508870219247277067">অ্যাভোকাডো সবুজ</translation>
<translation id="7511955381719512146">আপনি যে ওয়াই-ফাই-টি ব্যবহার করছেন সেটির জন্য অপনাকে <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />-তে যেতে হতে পারে৷</translation>
<translation id="7514365320538308">ডাউনলোড করুন</translation>
<translation id="7518003948725431193">এই ওয়েব ঠিকানার কোনও ওয়েবপৃষ্ঠা পাওয়া যায় নি: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">এই সাইটে আপনার সংযোগ ব্যক্তিগত নয়</translation>
+<translation id="7535087603100972091">মান</translation>
<translation id="7537536606612762813">বাধ্যতামূলক</translation>
+<translation id="7538364083937897561">A2 (Envelope)</translation>
<translation id="7542403920425041731">আপনি নিশ্চিত করলে আপনার কার্ডের বিবরণ এই সাইটের সাথে শেয়ার করা হবে।</translation>
<translation id="7542995811387359312">স্বয়ংক্রিয় ক্রেডিট কার্ড পূরণটি অক্ষম রয়েছে কারণ এই ফর্মটি কোনও সুরক্ষিত সংযোগ ব্যবহার করে না৷</translation>
<translation id="7543525346216957623">আপনার বাবা-মাকে জিজ্ঞাসা করুন</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">নিম্নোল্লিখিত টিপ্স ব্যবহার করে দেখুন:</translation>
<translation id="7554791636758816595">নতুন ট্যাব</translation>
<translation id="7564049878696755256">আপনি নিজের <ph name="ORG_NAME" /> অ্যাকাউন্টের অ্যাক্সেস হারাতে পারেন অথবা আপনার পরিচয় চুরি হয়ে যেতে পারে। Chrome এখনই আপনার পাসওয়ার্ড পরিবর্তন করার আর্জি জানাচ্ছে।</translation>
-<translation id="7566125604157659769">আপনি কপি করেছেন এমন টেক্সট</translation>
<translation id="7567204685887185387">এই সার্ভার প্রমাণ করতে পারেনি যে এটি <ph name="DOMAIN" />; এর নিরাপত্তা সার্টিফিকেট প্রতারণাপূর্ণভাবে ইস্যু করা হয়ে থাকতে পারে। কোনো ভুল কনফিগারেশনের কারণে অথবা কোনো আক্রমণকারী আপনার সংযোগ মাঝপথে আটকে দিচ্ছে বলে এমনটা হতে পারে।</translation>
+<translation id="7568105740864181217">এই ব্রাউজারটি কোনও কোম্পানি, স্কুল বা অন্য কোনও সংস্থা ম্যানেজ করে। আপনার অ্যাডমিনিস্ট্রেটর রিমোট লোকেশন থেকে আপনার ব্রাউজারের সেট-আপ পরিবর্তন করতে পারেন। এই ডিভাইসের অ্যাক্টিভিটি Chrome-এর বাইরে থেকে ম্যানেজ করা হতে পারে। <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome থেকে ক্রেডিট কার্ড সরাবেন?</translation>
<translation id="7569983096843329377">কালো</translation>
<translation id="7578104083680115302">আপনি Google এর সাথে সংরক্ষণ করেছেন এমন কার্ড ব্যবহার করে ডিভাইস জুড়ে সাইট এবং অ্যাপ্লিকেশানগুলিতে দ্রুত অর্থ পরিশোধ করুন।</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">পারফর্ম্যান্সের ডেটা ও ক্র্যাশ রিপোর্ট</translation>
<translation id="7637571805876720304">Chromium থেকে ক্রেডিট কার্ড সরাবেন?</translation>
<translation id="7639968568612851608">গাঢ় ধূসর</translation>
<translation id="765676359832457558">উন্নত সেটিংস লুকান...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">ফিরে পাওয়া নীতির টোকেন খালি অথবা বর্তমান টোকেনের সঙ্গে মেলে না</translation>
<translation id="7668654391829183341">অজানা ডিভাইস</translation>
<translation id="7669271284792375604">এই সাইটে থাকা আক্রমণকারীরা কৌশলে আপনাকে দিয়ে এমন প্রোগ্রাম ইনস্টল করাতে পারে যা আপনার ব্রাউজিং অভিজ্ঞতার জন্য ক্ষতিকর হতে পারে (উদাহরণস্বরূপ, আপনার হোমপৃষ্ঠা পরিবর্তন করা বা আপনার পরিদর্শিত সাইটগুলিতে অতিরিক্ত বিজ্ঞাপন দেখানো)৷</translation>
+<translation id="7676643023259824263">ক্লিপবোর্ড টেক্সট <ph name="TEXT" /> সার্চ করুন</translation>
<translation id="7681101578153515023">সার্চ ইঞ্জিন পরিবর্তন করুন</translation>
<translation id="7682287625158474539">শিপিং</translation>
<translation id="7687186412095877299">আপনার সেভ করা পেমেন্ট পদ্ধতি দিয়ে পেমেন্ট ফর্ম পূরণ করে</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">এই মুহূর্তে, আপনার কাছে থাকা কার্ডগুলি শুধুমাত্র এই ডিভাইসে ব্যবহার করা যেতে পারে। কার্ডগুলির পর্যালোচনা চালিয়ে যেতে ক্লিক করুন।</translation>
<translation id="7699293099605015246">নিবন্ধ এখন পাওয়া যাবে না</translation>
<translation id="7701040980221191251">কিছুই নয়</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">বিপজ্জনক কন্টেন্ট ব্লক করা হয়েছে।</translation>
<translation id="7752995774971033316">অপরিচালিত</translation>
<translation id="7755287808199759310">আপনার পিতামাতা এটি আপনার জন্য অবরোধ মুক্ত করতে পারবেন</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ফায়ারওয়াল বা অ্যান্টিভাইরাস সফটওয়্যার সংযোগকে অবরুদ্ধ করে থাকতে পারে।</translation>
<translation id="7759163816903619567">ডিসপ্লে ডোমেন:</translation>
<translation id="7761701407923456692">সার্ভারের সার্টিফিকেট ইউআরএল-এর সাথে মেলে না৷</translation>
<translation id="7763386264682878361">পেমেন্ট ম্যানিফেস্ট বিশ্লেষক</translation>
<translation id="7764225426217299476">ঠিকানা যোগ করুন</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">জেলা</translation>
<translation id="7791543448312431591">জুড়ুন</translation>
<translation id="7793809570500803535"><ph name="SITE" />-এ থাকা ওয়েবপৃষ্ঠাটি অস্থায়ীভাবে ডাউন থাকতে পারে অথবা এটিকে স্থায়ীভাবে কোনো নতুন ওয়েব ঠিকানাতে সরানো হয়েছে৷</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome থেকে ফর্ম প্রস্তাবনা সরাবেন?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' এর জন্য <ph name="NUMBER_OF_RESULTS" />টি <ph name="SEARCH_RESULTS" /> খুঁজে পাওয়া গেছে</translation>
-<translation id="7818867226424560206">নীতি পরিচালনা</translation>
<translation id="782886543891417279">আপনি যে (<ph name="WIFI_NAME" />) Wi-Fiটি ব্যবহার করছেন সেটির জন্য অপনাকে এটির লগ ইন পৃষ্ঠাতে যেতে হতে পরে৷</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{একটিও নয়}=1{১টি অ্যাপ (<ph name="EXAMPLE_APP_1" />)}=2{২টি অ্যাপ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{#টি অ্যাপ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{#টি অ্যাপ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">আপনি অবশ্য অদৃশ্য থাকবেন না। ছদ্মবেশী মোডে গেলেও তা আপনার নিয়োগকর্তা, আপনার ইন্টারনেট পরিষেবা প্রদানকারী অথবা আপনার পরিদর্শন করা ওয়েবসাইট থেকে আপনার ব্রাউজিংকে আড়াল করবে না।</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">আপনার পাসওয়ার্ড অন্য কেউ পরিবর্তন করার চেষ্টা করেছে</translation>
<translation id="7882421473871500483">খয়েরি</translation>
<translation id="7887683347370398519">আপনার CVC পরীক্ষা করুন এবং আবার চেষ্টা করুন</translation>
-<translation id="7893255318348328562">সেশনের নাম</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">একটি সঠিক ফোন নম্বর লিখুন</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" /> তারিখে মেয়াদ শেষ হবে</translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(৩২-বিট)</translation>
<translation id="7956713633345437162">মোবাইল বুকমার্ক</translation>
<translation id="7961015016161918242">কখনই নয়</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">নির্দিষ্ট করে উল্লেখ করা নেই</translation>
<translation id="800218591365569300">মেমরি ফাঁকা করতে অন্যান্য ট্যাব বা প্রোগ্রাম বন্ধ করার চেষ্টা করুন।</translation>
+<translation id="8004582292198964060">ব্রাউজার</translation>
<translation id="8009225694047762179">পাসওয়ার্ড পরিচালনা করুন</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{এই কার্ড ও সেটির বিলিং ঠিকানা সেভ করা হবে। <ph name="USER_EMAIL" />-এ সাইন-ইন করে থাকা অবস্থায় আপনি সেটি ব্যবহার করতে পারবেন।}one{এই কার্ডগুলি ও সেগুলির বিলিং ঠিকানা সেভ করা হবে। <ph name="USER_EMAIL" />-এ সাইন-ইন করে থাকা অবস্থায় আপনি সেগুলি ব্যবহার করতে পারবেন।}other{এই কার্ডগুলি ও সেগুলির বিলিং ঠিকানা সেভ করা হবে। <ph name="USER_EMAIL" />-এ সাইন-ইন করে থাকা অবস্থায় আপনি সেগুলি ব্যবহার করতে পারবেন।}}</translation>
<translation id="8012647001091218357">এই মুহূর্তে আমরা আপনার পিতামাতার কাছে পৌঁছাতে পারিনি৷ অনুগ্রহ করে আবার চেষ্টা করুন৷</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="8034522405403831421">এই পৃষ্ঠাটি <ph name="SOURCE_LANGUAGE" /> ভাষায় রয়েছে৷ এটিকে <ph name="TARGET_LANGUAGE" /> ভাষায় অনুবাদ করবেন?</translation>
<translation id="8035152190676905274">কলম</translation>
+<translation id="8037117624646282037">সম্প্রতি ডিভাইসটি কে ব্যবহার করেছেন</translation>
<translation id="8037357227543935929">জিজ্ঞাসা করুন (ডিফল্ট)</translation>
<translation id="803771048473350947">ফাইল</translation>
<translation id="8041089156583427627">প্রতিক্রিয়া পাঠান</translation>
<translation id="8041940743680923270">বিশ্বব্যাপী ডিফল্ট ব্যবহার করুন (জানতে চান)</translation>
<translation id="8042918947222776840">পিক-আপের পদ্ধতি বেছে নিন</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" সঠিকভাবে কনফিগার হয়নি। সাধারণত "<ph name="SOFTWARE_NAME" />" আন-ইনস্টল করা হলে সমস্যার সমাধান হয়ে যায়। <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">আপনার ডিভাইসে এই নীতিগুলি সেট করা হয়েছে:</translation>
+<translation id="8066955247577885446">কিছু সমস্যা হয়েছে।</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">ঘূর্ণনের সময় ব্যাখ্যা করা যাবে না</translation>
<translation id="8079031581361219619">সাইটটি আবার লোড করবেন?</translation>
<translation id="8088680233425245692">নিবন্ধ দেখতে ব্যর্থ হয়েছে৷</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">সার্ভারে সক্রিয়করণ বাকি আছে</translation>
<translation id="8092774999298748321">গাঢ় বেগুনি</translation>
<translation id="8094917007353911263">আপনি যে নেটওয়ার্কটি ব্যবহার করছেন সেটির জন্য অপনাকে <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />-তে যেতে হতে পারে৷</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">সঠিক নয় এমন কার্ডগুলি মুছে ফেলা হয়েছে</translation>
<translation id="8103161714697287722">পেমেন্টের পদ্ধতি</translation>
<translation id="8118489163946903409">পেমেন্টের পদ্ধতি</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> <ph name="ENROLLMENT_DOMAIN" /> ম্যানেজ করে</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" আপনার কম্পিউটার বা নেটওয়ার্কে সঠিক ভাবে ইনস্টল করা হয়নি। আপনার IT প্রশাসককে এই সমস্যাটি সমাধান করতে বলুন।</translation>
-<translation id="8130693978878176684">আমি আর সাহায্য করতে পারব না, নিজের মতো করে এগিয়ে যান।</translation>
<translation id="8131740175452115882">নিশ্চিত হন</translation>
<translation id="8149426793427495338">আপনার কম্পিউটারটি নিদ্রা মোডে গিয়েছে।</translation>
<translation id="8150722005171944719"><ph name="URL" />এ ফাইলটি পাঠযোগ্য নয়৷ এটা মুছে ফেলা হয়েছে পারে, সরিয়ে দেওয়া হয়েছে, অথবা ফাইল অনুমতি প্রবেশাধিকার প্রতিরোধ করতে পারে৷</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">পৃষ্ঠাটি অনুবাদ করুন</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" আইডি যুক্ত এক্সটেনশনের আপডেট করার ইউআরএলটি ভুল।</translation>
<translation id="8202097416529803614">অর্ডারের সারসংক্ষেপ</translation>
+<translation id="8202370299023114387">দ্বন্দ্ব</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">কানেকশনটি নিরাপদ</translation>
<translation id="8218327578424803826">নির্ধারিত লোকেশন:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</translation>
<translation id="8225771182978767009">এই কম্পিউটার যিনি সেট আপ করেছেন তিনি এই সাইটটি অবরুদ্ধ করার বিষয়টি চয়ন করেছেন।</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">নতুন ছদ্মবেশী ট্যাবে একটি পৃষ্ঠা খুলুন</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">সেভ করা সমস্ত পাসওয়ার্ড দেখান</translation>
<translation id="8261506727792406068">মুছুন</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> হিসেবে প্রবেশ করুন করছেন</translation>
+<translation id="8278457561961988242">এই ব্রাউজারটি <ph name="ENROLLMENT_DOMAIN" /> ম্যানেজ করছে। আপনার অ্যাডমিনিস্ট্রেটর রিমোট লোকেশন থেকে আপনার ব্রাউজারের সেট-আপ পরিবর্তন করতে পারেন। এই ডিভাইসের অ্যাক্টিভিটি Chrome-এর বাইরে থেকে ম্যানেজ করা হতে পারে। <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">প্রবেশ করুন</translation>
<translation id="8288807391153049143">সার্টিফিকেট দেখান</translation>
<translation id="8289355894181816810">যদি আপনি এর অর্থের ব্যাপারে নিশ্চিত না হন তাহলে আপনার নেটওয়ার্ক প্রশাসকের সঙ্গে যোগাযোগ করুন৷</translation>
<translation id="8293206222192510085">বুকমার্ক যুক্ত করুন</translation>
<translation id="8294431847097064396">উৎস</translation>
<translation id="8298115750975731693">আপনি যে (<ph name="WIFI_NAME" />) Wi-Fiটি ব্যবহার করছেন সেটির জন্য অপনাকে <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> তে যেতে হতে পারে৷</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">নেটওয়ার্ক সংযোগে কোন সমস্যা হওয়ার কারণে অনুবাদ ব্যর্থ হয়েছে৷</translation>
-<translation id="8311129316111205805">সেশন লোড করুন</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> এ অ্যাক্সেস অস্বীকার করা হয়েছে</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">আপনি যদি আপনার নিরাপত্তার ঝুঁকিগুলি বুঝতে পারেন, তাহলে ক্ষতিকারক প্রোগ্রাম সরানোর আগে আপনি <ph name="BEGIN_LINK" />এই সাইটে যেতে পারেন<ph name="END_LINK" />৷</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">নেটওয়ার্ক কনফিগারেশনটি সঠিক নয় এবং ইমপোর্ট করা যায়নি৷
অতিরিক্ত বিবরণ:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" />-এর দ্বারা পরিচালিত ডিভাইস</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">পরিবর্তন</translation>
<translation id="8428213095426709021">সেটিংস</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">কার্ডধারকের নাম</translation>
<translation id="861775596732816396">সাইজ ৪</translation>
<translation id="8620436878122366504">আপনার পিতামাতা এখনও এটি অনুমোদন করেন নি</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">এই ডিভাইসে এই কার্ডটি সেভ করুন</translation>
<translation id="8663226718884576429">অর্ডারের সারসংক্ষেপ, <ph name="TOTAL_LABEL" />, আরও বিবরণ</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, উত্তর, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" />-এ আপনার কানেকশন এনক্রিপ্ট হয় নি৷</translation>
<translation id="8718314106902482036">পেমেন্ট করা যায়নি</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, সার্চ সাজেশন</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google নিরাপদ ব্রাউজিং সম্প্রতি <ph name="SITE" /> এ <ph name="BEGIN_LINK" />ক্ষতিকারক প্রোগ্রামগুলি খুঁজে পেয়েছে<ph name="END_LINK" />৷</translation>
<translation id="8763927697961133303">USB ডিভাইস</translation>
<translation id="8768895707659403558">আপনার সমস্ত ডিভাইসে কার্ড ব্যবহার করতে, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;মুছে ফেলাকে আবার করুন</translation>
<translation id="8792621596287649091">আপনি নিজের <ph name="ORG_NAME" /> অ্যাকাউন্টের অ্যাক্সেস হারাতে পারেন অথবা আপনার পরিচয় চুরি হয়ে যেতে পারে। Chromium এখনই আপনার পাসওয়ার্ড পরিবর্তন করার আর্জি জানাচ্ছে।</translation>
<translation id="8800988563907321413">আপনার জন্য আশেপাশের প্রস্তাবনাগুলি এখানে দেখা যাবে</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">Google এর সাথে ভাগ করছে</translation>
<translation id="8858065207712248076">Chrome-এর নীতি অনুযায়ী আপনার <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> পাসওয়ার্ড বদলে ফেলা উচিত যদি আপনি সেটি অন্য কোনও সাইটে ব্যবহার করে থাকেন।</translation>
<translation id="8866481888320382733">নীতি সেটিংস বিশ্লেষণ করার সময় ত্রুটি</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">সম্প্রতি বন্ধ হয়েছে</translation>
<translation id="8874824191258364635">একটি সঠিক কার্ড নম্বর লিখুন</translation>
<translation id="8891727572606052622">প্রক্সি মোড অবৈধ৷</translation>
<translation id="8903921497873541725">জুম বাড়ান</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">আপনি কি আপনার Google অ্যাকাউন্টে এই কার্ড সংরক্ষণ করতে চান?</translation>
<translation id="8932102934695377596">আপনার ঘড়ির সময় পিছিয়ে রয়েছে</translation>
<translation id="893332455753468063">নাম যোগ করুন</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">আপনার অ্যাডমিনিস্ট্রেটর কাস্টম রুট সার্টিফিকেট কনফিগার করেছেন, যার ফলে আপনি যে ওয়েবসাইটে যাচ্ছেন সেটির কন্টেন্ট তিনি দেখতে পেতে পারেন।</translation>
<translation id="8943282376843390568">লাইম</translation>
<translation id="8957210676456822347">ক্যাপটিভ পোর্টাল অনুমোদন</translation>
+<translation id="8966619695390250636">আপনি কি এটি বলতে চাইছেন?</translation>
<translation id="8968766641738584599">কার্ড সেভ করুন</translation>
<translation id="8971063699422889582">সার্ভারের সার্টিফিকেটের মেয়াদ ফুরিয়েছে৷</translation>
<translation id="8975012916872825179">ফোন নম্বর, ইমেল আইডি এবং শিপিং ঠিকানার মতো তথ্য এতে আছে</translation>
<translation id="8978053250194585037">Google Safe Browsing সম্প্রতি <ph name="SITE" /> এ <ph name="BEGIN_LINK" />ফিশিং শনাক্ত করেছে<ph name="END_LINK" />। ফিশিং সাইটগুলি আপনাকে প্রতারিত করার জন্য অন্যান্য সাইট যেমন হয় সেইরকম ভান করে।</translation>
<translation id="8983003182662520383">Google Pay ব্যবহার করে এমন পেমেন্টের পদ্ধতি এবং ঠিকানা</translation>
<translation id="8987927404178983737">মাস</translation>
-<translation id="8988408250700415532">কোনও সমস্যা হয়েছে। আপনি ওয়েবসাইট থেকে এই অর্ডারটি দিতে পারেন।</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">সামনের সাইটটিতে ক্ষতিকর প্রোগ্রামগুলি রয়েছে</translation>
<translation id="8997023839087525404">সার্ভারটি এমন একটি সার্টিফিকেট উপস্থাপন করেছে যেটি সার্টিফিকেটের স্বচ্ছতার নীতি ব্যবহার করে সর্বজনীনভাবে প্রকাশ করা হয়নি। এটা কিছু সার্টিফিকেটের জন্য একটি আবশ্যকতা, যাতে করে সেগুলির বিশ্বাসযোগ্যত করা যায় এবং আক্রমণকারীদের বিরুদ্ধে সুরক্ষা নেওয়া যায়।</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">সাইট সেটিংস খুলুন</translation>
<translation id="9020200922353704812">কার্ডের বিলিং ঠিকানা প্রয়োজন</translation>
<translation id="9020542370529661692">এই পৃষ্ঠাটি <ph name="TARGET_LANGUAGE" /> এ অনুবাদ করা হয়েছে</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(সঠিক নয়)</translation>
<translation id="9035022520814077154">নিরাপত্তা ত্রুটি</translation>
<translation id="9038649477754266430">পৃষ্ঠা আরও দ্রুত লোড করার জন্য কোনো পূর্বাভাষ পরিষেবা ব্যবহার করুন</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">ইতিহাসে <ph name="TEXT" /> সার্চ</translation>
<translation id="9069693763241529744">একটি এক্সটেনশন ব্লক করেছে</translation>
<translation id="9076283476770535406">এতে প্রাপ্তবয়স্কদের সামগ্রী থাকতে পারে</translation>
+<translation id="9076630408993835509">কোনও কোম্পানি বা অন্য কোনও সংস্থা এই ব্রাউজারটি ম্যানেজ করে না। এই ডিভাইসের অ্যাক্টিভিটি Chrome-এর বাইরে থেকে ম্যানেজ করা হতে পারে। <ph name="BEGIN_LINK" />আরও জানুন<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">আরও তথ্য প্রয়োজন</translation>
<translation id="9080712759204168376">অর্ডারের সারসংক্ষেপ</translation>
<translation id="9103872766612412690"><ph name="SITE" /> সাধারণত আপনার তথ্য সুরক্ষিত রাখতে এনক্রিপশন ব্যবহার করে। এবার Chromium, <ph name="SITE" />-এর সাথে কানেক্ট করার চেষ্টা করলে ওয়েবসাইটটি অস্বাভাবিক এবং ভুল ক্রেডেনশিয়াল পাঠিয়ে দেয়। হয় একজন আক্রমণকারী <ph name="SITE" /> হতে চাইছে অথবা একটি ওয়াই-ফাই সাইন-ইন স্ক্রিন কানেকশনকে বাধা দিয়েছে। আপনার তথ্য এখনো নিরাপদ আছে কারণ কোনো ডেটা আদানপ্রদানের আগেই Chromium কানেকশন বন্ধ করে দিয়েছে।</translation>
<translation id="9106062320799175032">বিলিংয়ের ঠিকানা যোগ করুন</translation>
-<translation id="9110718169272311511">Chrome-এর নিচের অংশ থেকে Google অ্যাসিস্ট্যান্ট অ্যাক্সেস করা যাবে</translation>
<translation id="9114524666733003316">কার্ড নিশ্চিত করা হচ্ছে...</translation>
<translation id="9128870381267983090">নেটওয়ার্কে সংযোগ করুন</translation>
<translation id="9137013805542155359">প্রকৃত রূপ দেখান</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;সম্পাদনাকে পূর্বাবস্থায় ফেরান</translation>
<translation id="9154194610265714752">আপডেট রয়েছে</translation>
<translation id="9157595877708044936">সেট আপ হচ্ছে...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">আপনি কোনও পেমেন্ট পদ্ধতি সেভ করেছেন কিনা তা সাইটগুলিকে যাচাই করতে দিন</translation>
<translation id="9169664750068251925">এই সাইটে সর্বদা অবরোধ করুন</translation>
<translation id="9170848237812810038">&amp;পূর্বাবস্থায় ফিরুন</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">ছবিগুলি</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ফর্ম সাফ করুন</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">আপনি আপনার Google অ্যাকাউন্টে অ্যাক্সেস হারাতে পারেন। Chromium-এর প্রস্তাব হল যে আপনি আপনার পাসওয়ার্ড এখনই পরিবর্তন করুন। আপনাকে আবার সাইন-ইন করতে বলা হবে।</translation>
<translation id="939736085109172342">নতুন ফোল্ডার</translation>
<translation id="945855313015696284">নিচে দেওয়া তথ্য পরীক্ষা করুন এবং কোনও ভুল কার্ড থাকলে তা মুছে ফেলুন</translation>
<translation id="951104842009476243">এই ডেবিট ও প্রিপেড কার্ডগুলি গ্রহণ করা হয়</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" />-এর নিরাপত্তা সংক্রান্ত নীতি অনুযায়ী ব্লক করা হয়েছে।</translation>
<translation id="962484866189421427">এই কন্টেন্টটি প্রতারণামূলক অ্যাপ ইনস্টল করে দিতে পারে যেগুলি অন্যান্য আপের থেকে আলাদা করা যায় না অথবা যেগুলি এমন ডেটা সংগ্রহ করে যা দিয়ে আপনার উপরে নজর রাখা যাবে। <ph name="BEGIN_LINK" />তবুও এটি দেখতে চাই<ph name="END_LINK" /></translation>
<translation id="969892804517981540">অফিসিয়াল বিল্ড</translation>
<translation id="973773823069644502">ডেলিভারি ঠিকানা যোগ করুন</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">পেমেন্ট পদ্ধতি</translation>
<translation id="985199708454569384">&lt;p&gt;আপনার কম্পিউটার অথবা মোবাইল ডিভাইসে সঠিক তারিখ এবং সময় সেট করা না থাকলে এই সমস্যাটি হতে পারে।&lt;/p&gt;
&lt;p&gt;এই সমস্যার সমাধান করতে, ডিভাইসের ঘড়িতে যান। সঠিক তারিখ এবং সময় সেট করুন।&lt;/p&gt;</translation>
+<translation id="985956168329721395">PRC-32K</translation>
<translation id="988159990683914416">ডেভেলপার বিল্ড</translation>
<translation id="989988560359834682">ঠিকানা সম্পাদনা করুন</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ca.xtb b/chromium/components/strings/components_strings_ca.xtb
index 2b9ee564e50..de2d3b75ddb 100644
--- a/chromium/components/strings/components_strings_ca.xtb
+++ b/chromium/components/strings/components_strings_ca.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ca">
-<translation id="1005145902654145231">No s'ha pogut canviar el nom de la sessió.</translation>
<translation id="1008557486741366299">Ara no</translation>
<translation id="1010200102790553230">Carrega la pàgina més tard</translation>
<translation id="1015730422737071372">Proporcioneu més informació</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nom desconegut</translation>
<translation id="1050038467049342496">Tanca altres aplicacions</translation>
<translation id="1055184225775184556">&amp;Desfés l'addició</translation>
+<translation id="1056898198331236512">Advertiment</translation>
<translation id="1058479211578257048">S'estan desant les targetes...</translation>
<translation id="10614374240317010">Contrasenyes que no es desen mai</translation>
+<translation id="1062160989074299343">Prc10 (sobre)</translation>
<translation id="106701514854093668">Adreces d'interès d'escriptori</translation>
<translation id="1074497978438210769">No segur</translation>
<translation id="1080116354587839789">Ajusta a l'amplada</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Afegeix el titular de la targeta</translation>
<translation id="1089439967362294234">Canvia la contrasenya</translation>
<translation id="109743633954054152">Gestiona les contrasenyes a la configuració de Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">És probable que rebis advertiments mentre s'actualitza la seguretat als llocs web, però això millorarà aviat.</translation>
<translation id="1126551341858583091">La mida de l'emmagatzematge local és de <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">La memòria cau de la política està en bon estat</translation>
+<translation id="1131264053432022307">Imatge que has copiat</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ha tancat la connexió de manera inesperada.</translation>
<translation id="1161325031994447685">Torna't a connectar a la xarxa Wi-Fi.</translation>
<translation id="1165039591588034296">Error</translation>
-<translation id="1173894706177603556">Canvia el nom</translation>
<translation id="1175364870820465910">&amp;Imprimeix...</translation>
<translation id="1181037720776840403">Suprimeix</translation>
<translation id="1197088940767939838">Taronja</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Nom del teu dispositiu</translation>
<translation id="124116460088058876">Més idiomes</translation>
<translation id="1250759482327835220">Perquè la propera vegada puguis pagar més ràpidament, desa la targeta, el nom i l'adreça de facturació al Compte de Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (informació sincronitzada)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variacions de la línia d'ordres</translation>
<translation id="129553762522093515">Tancades recentment</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Esborreu les galetes<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">La sessió seleccionada no existeix.</translation>
+<translation id="1320233736580025032">Prc1 (sobre)</translation>
+<translation id="132301787627749051">Cerca la imatge del porta-retalls</translation>
<translation id="1323433172918577554">Mostra'n més</translation>
<translation id="132390688737681464">Desa i emplena les adreces</translation>
<translation id="1333989956347591814">És possible que la teva activitat <ph name="BEGIN_EMPHASIS" />continuï sent visible<ph name="END_EMPHASIS" /> en:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Adreça de recollida</translation>
<translation id="1348198688976932919">Aquest lloc web conté aplicacions perilloses</translation>
<translation id="1348779747280417563">Confirma el nom</translation>
+<translation id="1357195169723583938">Qui ha utilitzat el dispositiu recentment i quan</translation>
+<translation id="1364822246244961190">Aquesta política està bloquejada i, per tant, se n'ignorarà el valor.</translation>
<translation id="1374468813861204354">suggeriments</translation>
+<translation id="1374692235857187091">Index-4x6 (postal)</translation>
<translation id="1375198122581997741">Quan a la versió</translation>
<translation id="1376836354785490390">Mostra'n menys</translation>
<translation id="1377321085342047638">Número de targeta</translation>
<translation id="138218114945450791">Blau clar</translation>
+<translation id="1382194467192730611">Dispositiu USB permès per l'administrador</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no ha enviat dades.</translation>
+<translation id="140316286225361634">El lloc web <ph name="ORIGIN" /> ha sol·licitat que s'apliqui una política de seguretat a totes les seves sol·licituds, però en aquest moment aquesta política considera que el lloc web no és segur.</translation>
<translation id="1405567553485452995">Verd clar</translation>
<translation id="1407135791313364759">Obre-les totes</translation>
<translation id="1413809658975081374">Error de privadesa</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Imprimeix</translation>
<translation id="1455413310270022028">Goma d'esborrar</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Mostra'n més</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Tria l'adreça d'enviament</translation>
+<translation id="1492194039220927094">Tramesa automàtica de les polítiques:</translation>
<translation id="1501859676467574491">Mostra les targetes del Compte de Google</translation>
-<translation id="1506687042165942984">Mostra una còpia desada (és a dir, no actualitzada) d'aquesta pàgina.</translation>
<translation id="1507202001669085618">&lt;p&gt;Aquest error es mostra si utilitzeu un portal Wi-Fi en què cal que inicieu la sessió per connectar-vos a Internet.&lt;/p&gt;
&lt;p&gt;Per solucionar l'error, feu clic a &lt;strong&gt;Connecta&lt;/strong&gt; a la pàgina que proveu d'obrir.</translation>
<translation id="1517433312004943670">El número de telèfon és obligatori</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Data de creació</translation>
<translation id="1521655867290435174">Fulls de càlcul de Google</translation>
<translation id="1527263332363067270">S'està esperant que hi hagi connexió…</translation>
+<translation id="1529521330346880926">10x15 (sobre)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Aquesta pàgina diu</translation>
<translation id="153384715582417236">De moment, això és tot</translation>
<translation id="154408704832528245">Tria l'adreça d'entrega</translation>
<translation id="1549470594296187301">Heu d'activar el JavaScript per utilitzar aquesta funció.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Introdueix la data de caducitat</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imatge que has copiat</translation>
<translation id="1620510694547887537">Càmera</translation>
<translation id="1623104350909869708">Impedeix que aquesta pàgina creï diàlegs addicionals.</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Finalitza la sessió</translation>
<translation id="1639239467298939599">S'està carregant</translation>
<translation id="1640180200866533862">Polítiques d'usuari</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">El certificat de servidor conté una clau criptogràfica dèbil.</translation>
<translation id="1697532407822776718">Ja esteu a punt</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">No es poden afegir anotacions a aquest fitxer perquè és massa gran</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>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Proveu de contactar amb l'administrador del sistema.</translation>
<translation id="1740951997222943430">Introdueix un mes de caducitat vàlid</translation>
<translation id="1743520634839655729">Perquè la propera vegada puguis pagar més ràpidament, desa la targeta, el nom i l'adreça de facturació al Compte de Google i en aquest dispositiu.</translation>
+<translation id="1745880797583122200">El navegador està gestionat</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Actualitzeu la frase de contrasenya de sincronització.</translation>
<translation id="1787142507584202372">Les pestanyes obertes es mostren aquí</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nom del titular de la targeta</translation>
<translation id="1821930232296380041">Sol·licitud o paràmetres de la sol·licitud no vàlids</translation>
+<translation id="1822540298136254167">Els llocs web que visites i el temps que hi passes</translation>
<translation id="1826516787628120939">S'està comprovant</translation>
<translation id="1834321415901700177">Aquest lloc conté programes perjudicials</translation>
<translation id="1839551713262164453">S'han produït errors a la validació dels valors de la política</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Esborra les dades de l'historial de navegació de Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{i 1 aplicació més}other{i # aplicacions més}}</translation>
<translation id="2003709556000175978">Restableix la contrasenya ara</translation>
+<translation id="20053308747750172">El servidor de destinació, <ph name="ORIGIN" />, ha sol·licitat que s'apliqui una política de seguretat a totes les sol·licituds que rebi. Però ara ha proporcionat una política que no és vàlida, de manera que el navegador no pot completar la sol·licitud que has fet per a <ph name="SITE" />.</translation>
<translation id="2025186561304664664">El servidor intermediari està definit perquè es configuri automàticament.</translation>
<translation id="2030481566774242610">Volíeu dir <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Comproveu el servidor intermediari i el tallafoc<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Departament</translation>
<translation id="2102134110707549001">Suggereix una contrasenya segura…</translation>
<translation id="2108755909498034140">Reinicia l'ordinador</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Targeta</translation>
<translation id="2114841414352855701">S'ha ignorat perquè <ph name="POLICY_NAME" /> l'ha substituït.</translation>
<translation id="213826338245044447">Adreces d'interès per a mòbils</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (sobre)</translation>
<translation id="2181821976797666341">Polítiques</translation>
<translation id="2183608646556468874">Número de telèfon</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adreça}other{# adreces}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Número de telèfon</translation>
<translation id="2283340219607151381">Desa i emplena les adreces</translation>
<translation id="2292556288342944218">El vostre accés a Internet està bloquejat</translation>
+<translation id="2294558542833290837">L'enllaç que has obert en un primer moment és poc habitual</translation>
+<translation id="2297722699537546652">B5 (sobre)</translation>
+<translation id="2310021320168182093">Chou2 (sobre)</translation>
<translation id="2316887270356262533">Allibera menys d'1 MB. És possible que alguns llocs web es carreguin més a poc a poc la propera vegada que els visitis.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requereix un nom d'usuari i una contrasenya.</translation>
<translation id="2317583587496011522">S'accepten targetes de dèbit.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, data de caducitat: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">L'administrador controla l'opció de configuració</translation>
+<translation id="2346319942568447007">Imatge que has copiat</translation>
<translation id="2349790679044093737">Hi ha una sessió de realitat virtual activa</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>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">L'informe d'error capturat (<ph name="CRASH_TIME" />) no s'ha penjat</translation>
<translation id="2367567093518048410">Nivell</translation>
<translation id="2378238891085281592">Has passat al mode privat</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">El servidor de destinació, <ph name="ORIGIN" />, ha sol·licitat que s'apliqui una política de seguretat a totes les sol·licituds que rebi. Però no ha proporcionat cap política, de manera que el navegador no pot completar la sol·licitud que has fet per a <ph name="SITE" />.</translation>
<translation id="244665789865330679">El dispositiu i el compte estan gestionats per <ph name="ENROLLMENT_DOMAIN" />. Això vol dir que l'administrador pot configurar el dispositiu i el compte de manera remota.</translation>
<translation id="2463193859425327265">Canvia la pàgina d'inici</translation>
<translation id="2463739503403862330">Emplena</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Tria el mètode d'entrega</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar el Diagnòstic de xarxa<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Tradueix aquesta pàgina</translation>
<translation id="2479410451996844060">URL de cerca no vàlid.</translation>
<translation id="2482878487686419369">Notificacions</translation>
<translation id="248348093745724435">Polítiques de l'ordinador</translation>
+<translation id="2485387744899240041">Noms d'usuari del dispositiu i del navegador</translation>
<translation id="2491120439723279231">El certificat del servidor conté errors.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Escaneja una targeta nova</translation>
<translation id="2501278716633472235">Torna</translation>
<translation id="2503184589641749290">Targetes de dèbit i de prepagament acceptades</translation>
<translation id="2515629240566999685">Comprova el senyal a la teva zona.</translation>
-<translation id="2516852381693169964">Cerca "imatge" a <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Només es desarà en aquest dispositiu</translation>
<translation id="2524461107774643265">Afegeix més informació</translation>
<translation id="2536110899380797252">Afegeix una adreça</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (sobre)</translation>
<translation id="2625385379895617796">El rellotge està avançat</translation>
<translation id="2634124572758952069">No s'ha trobat l'adreça IP del servidor de l'amfitrió <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Estat:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Tanca altres pestanyes o aplicacions</translation>
<translation id="267371737713284912">prem <ph name="MODIFIER_KEY_DESCRIPTION" /> per desfer l'acció</translation>
<translation id="2674170444375937751">Confirmes que vols suprimir aquestes pàgines de l'historial?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Surt</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Targetes acceptades</translation>
<translation id="2702801445560668637">Llista de lectura</translation>
<translation id="2704283930420550640">El valor no coincideix amb el format.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Suprimeix els elements seleccionats</translation>
<translation id="277133753123645258">Mètode d'enviament</translation>
<translation id="277499241957683684">Falta el registre del dispositiu</translation>
-<translation id="2781030394888168909">Exporta a MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">S'ha restablert la connexió.</translation>
<translation id="2788784517760473862">Targetes de crèdit acceptades</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Obre una finestra d'incògnit</translation>
+<translation id="2850739647070081192">Invite (sobre)</translation>
<translation id="2851634818064021665">Necessites permís per visitar aquest lloc web</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Vols desar la targeta?</translation>
<translation id="2903493209154104877">Adreces</translation>
<translation id="290376772003165898">La pàgina no està en <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Mètode d'entrega</translation>
<translation id="2928905813689894207">Adreça de facturació</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (sobre)</translation>
<translation id="3024663005179499861">Tipus de política incorrecte</translation>
<translation id="3037605927509011580">Vaja!</translation>
<translation id="3041612393474885105">Informació del certificat</translation>
+<translation id="3060227939791841287">C9 (sobre)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Afegeix l'adreça de recollida</translation>
<translation id="3105172416063519923">Identificador de l'element:</translation>
<translation id="3109728660330352905">No teniu permís per veure aquesta pàgina.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> a <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancel·la el pagament</translation>
<translation id="3207960819495026254">S'ha afegit a les adreces d'interès.</translation>
-<translation id="3209375525920864198">Introdueix un nom de sessió vàlid.</translation>
+<translation id="321912867715453276">Advertiment: hi ha més d'un origen en aquesta política, però els valors són els mateixos.</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="3229041911291329567">Informació sobre la versió del dispositiu i del navegador</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Afegeix el titular de la targeta</translation>
<translation id="3287510313208355388">Baixa quan estigui en línia</translation>
<translation id="3293642807462928945">Més informació sobre la política <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">No s'ha trobat cap resultat de la cerca</translation>
-<translation id="3305707030755673451">Les vostres dades es van encriptar el dia <ph name="TIME" /> amb la vostra frase de contrasenya de sincronització. Introduïu-la per començar la sincronització.</translation>
<translation id="3320021301628644560">Afegeix una adreça de facturació</translation>
<translation id="3324983252691184275">Carmesí</translation>
<translation id="3338095232262050444">Segur</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;Refés la modificació</translation>
<translation id="342781501876943858">Chromium et recomana que restableixis la contrasenya si l'has fet servir en altres llocs web.</translation>
<translation id="3431636764301398940">Desa aquesta targeta al dispositiu</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">El propietari d'aquest dispositiu ha desactivat el joc de dinosaures.</translation>
<translation id="3447884698081792621">Mostra el certificat (emès per <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Obtén l'interval:</translation>
+<translation id="3456231139987291353">Number-11 (sobre)</translation>
<translation id="3461824795358126837">Retolador fluorescent</translation>
<translation id="3462200631372590220">Amaga la configuració avançada</translation>
<translation id="3467763166455606212">El nom del titular de la targeta és obligatori</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">S'accepten targetes de crèdit i de prepagament.</translation>
<translation id="3582930987043644930">Afegeix el nom</translation>
<translation id="3583757800736429874">&amp;Refés el moviment</translation>
+<translation id="35866233670761917">Els administradors no veuen el contingut dels llocs web que visites</translation>
<translation id="3586931643579894722">Oculta els detalls</translation>
+<translation id="3592413004129370115">Italian (sobre)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Mida 2</translation>
<translation id="3615877443314183785">Introdueix una data de caducitat vàlida</translation>
<translation id="36224234498066874">Esborra dades de navegació</translation>
<translation id="362276910939193118">Mostra l'historial complet</translation>
-<translation id="3623476034248543066">Mostra el valor</translation>
<translation id="3630155396527302611">Si ja està inclòs a la llista de programes autoritzats per accedir a la xarxa, proveu
de suprimir-lo de la llista i torneu-lo a afegir.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validació correcta</translation>
<translation id="3655670868607891010">Si aquest missatge apareix sovint, proveu aquests <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisió</translation>
<translation id="366077651725703012">Actualitza la targeta de crèdit</translation>
<translation id="3676592649209844519">Identificador del dispositiu:</translation>
+<translation id="3677008721441257057">Volies dir &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">La sol·licitud no s'ha pogut signar</translation>
<translation id="3678529606614285348">Obre la pàgina en una finestra d'incògnit nova (Ctrl+Maj+N)</translation>
<translation id="3679803492151881375">Informe d'error generat el <ph name="CRASH_TIME" /> i enviat el <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +497,14 @@
<translation id="3704162925118123524">És possible que la xarxa que esteu fent servir requereixi que visiteu la pàgina d'inici de sessió.</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="3709599264800900598">Text que has copiat</translation>
<translation id="3712624925041724820">Llicències exhaurides</translation>
<translation id="3714780639079136834">Activa les dades mòbils o la Wi-Fi.</translation>
<translation id="3715597595485130451">Connexió a xarxes Wi-Fi</translation>
<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="372429172604983730">Entre les aplicacions que poden provocar aquest error hi ha l'antivirus, el tallafoc i el programari de filtratge web o del servidor intermediari.</translation>
+<translation id="373042150751172459">B4 (sobre)</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="3745099705178523657">Un cop confirmada, la informació de la targeta del Compte de Google es compartirà amb aquest lloc web.</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>
@@ -470,10 +517,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Data de caducitat: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Mida 16</translation>
+<translation id="3797522431967816232">Prc3 (sobre)</translation>
<translation id="3807873520724684969">S'ha bloquejat contingut perjudicial.</translation>
<translation id="3810973564298564668">Gestiona</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="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ha instal·lat extensions per obtenir funcions addicionals. Les extensions tenen accés a algunes de les teves dades.</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>
@@ -481,6 +530,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Pregunta sempre en aquest lloc</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>
@@ -491,11 +541,13 @@
<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="3984550557525787191">Aquest nom de sessió ja existeix.</translation>
<translation id="3987940399970879459">Menys d'1 MB</translation>
+<translation id="4008849406247176967">Advertiment: hi ha més d'un origen amb valors conflictius en aquesta política.</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="4030383055268325496">&amp;Desfés l'addició</translation>
+<translation id="4032320456957708163"><ph name="ENROLLMENT_DOMAIN" /> gestiona el teu navegador</translation>
<translation id="4058922952496707368">Tecla "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (sobre)</translation>
<translation id="4067947977115446013">Afegeix una adreça vàlida</translation>
<translation id="4072486802667267160">S’ha produït un error en processar la comanda. Torna-ho a provar.</translation>
<translation id="4075732493274867456">El client i el servidor no admeten cap versió de protocol SSL ni cap sistema de xifratge comuns.</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">Porpra</translation>
<translation id="4165986682804962316">Configuració del lloc web</translation>
<translation id="4171400957073367226">La signatura de verificació és incorrecta</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element més}other{<ph name="ITEM_COUNT" /> elements més}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (sobre)</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="4221630205957821124">&lt;h4&gt;Pas 1: inicieu la sessió al portal&lt;/h4&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">Restableix la contrasenya</translation>
<translation id="4280429058323657511">, caduca el dia <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Aquesta targeta s'ha desat al Compte de Google}other{Aquestes targetes s'han desat al Compte de Google}}</translation>
+<translation id="42981349822642051">Desplega</translation>
+<translation id="4302965934281694568">Chou3 (sobre)</translation>
<translation id="4305817255990598646">Canvia</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloqueja (opció predeterminada)</translation>
+<translation id="4318566738941496689">El nom i l'adreça de xarxa del dispositiu</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="4340982228985273705">No ens consta que aquest ordinador estigui gestionat per una empresa. Per tant, la política només pot instal·lar automàticament extensions allotjades a Chrome Web Store. L'URL d'actualització de Chrome Web Store és <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Targetes de crèdit acceptades</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gestiona les formes de pagament...</translation>
+<translation id="4367563149485757821">Number-12 (sobre)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telèfon</translation>
<translation id="4406896451731180161">resultats de la cerca</translation>
-<translation id="4406972042435603828">Els administradors han instal·lat extensions amb funcions molt potents.</translation>
<translation id="4408413947728134509">Galetes <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Adreça de recollida</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="443121186588148776">Port en sèrie</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="4434045419905280838">Finestres emergents i redireccions</translation>
+<translation id="4435702339979719576">Postal)</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="445100540951337728">Targetes de dèbit acceptades</translation>
+<translation id="4466881336512663640">Es perdran els canvis fets al formulari. Confirmes que vols continuar?</translation>
<translation id="4482953324121162758">Aquest lloc web no es traduirà.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">L'URL no és vàlid. Ha de tenir un esquema estàndard, com ara "http://example.com" o "https://example.com".</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (sobre)</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="4517607026994743406">Comm-10 (sobre)</translation>
<translation id="4522570452068850558">Detalls</translation>
<translation id="4524805452350978254">Gestiona les targetes</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Desactiveu les extensions</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Entrega</translation>
+<translation id="4579056131138995126">Personal (sobre)</translation>
<translation id="4582204425268416675">Suprimeix la targeta</translation>
<translation id="4587425331216688090">Voleu suprimir l'adreça de Chrome?</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="4597348597567598915">Mida 8</translation>
+<translation id="4600854749408232102">C6/C5 (sobre)</translation>
<translation id="4646534391647090355">Porta-m'hi ara</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="467809019005607715">Presentacions de Google</translation>
<translation id="4690462567478992370">Deixa de fer servir un certificat no vàlid</translation>
+<translation id="4691835149146451662">Architecture-A (sobre)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">La connexió s'ha interromput</translation>
<translation id="471880041731876836">No tens permís per visitar aquest lloc web</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executa el Diagnòstic de xarxa de Windows<ph name="END_LINK" />.</translation>
<translation id="4726672564094551039">Torna a carregar les polítiques</translation>
<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4731967714531604179">Prc2 (sobre)</translation>
<translation id="4736825316280949806">Reinicia Chromium</translation>
<translation id="473775607612524610">Actualitza</translation>
<translation id="4738601419177586157">Suggeriment de cerca de <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Gestiona les contrasenyes…</translation>
<translation id="4744603770635761495">Camí executable</translation>
+<translation id="4746351372139058112">Missatges</translation>
<translation id="4750917950439032686">La teva informació (com ara les contrasenyes o els números de targeta de crèdit) es considera privada quan s'envia a aquest lloc.</translation>
<translation id="4756388243121344051">&amp;Historial</translation>
<translation id="4758311279753947758">Afegiu informació de contacte</translation>
@@ -609,9 +684,9 @@
<translation id="4764776831041365478">És possible que la pàgina web <ph name="URL" /> estigui temporalment fora de servei o s'hagi traslladat permanentment a una adreça web nova.</translation>
<translation id="4771973620359291008">S'ha produït un error desconegut.</translation>
<translation id="4785689107224900852">Canvia a aquesta pestanya</translation>
-<translation id="4792143361752574037">Hi ha hagut un problema en accedir als fitxers de la sessió. En aquests moments no es poden desar al disc. Torna a carregar la pàgina per provar-ho de nou.</translation>
<translation id="4798078619018708837">Introdueix la data de caducitat i el CVC de la targeta <ph name="CREDIT_CARD" /> per actualitzar-ne la informació. Un cop confirmada, la informació de la targeta del Compte de Google es compartirà amb aquest lloc web.</translation>
<translation id="4800132727771399293">Comproveu la data de caducitat i el CVC i torneu-ho a provar</translation>
+<translation id="480334179571489655">Error de la política d'origen</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>
@@ -626,7 +701,6 @@
<translation id="4881695831933465202">Obre</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>
@@ -635,15 +709,15 @@
<translation id="4943872375798546930">No hi ha resultats</translation>
<translation id="4950898438188848926">Botó per canviar de pestanya; prem Retorn per canviar a la pestanya oberta, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Accions</translation>
-<translation id="495832697253704892">Informes d'extensions</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Desplega la llista</translation>
<translation id="4974590756084640048">Torna a activar els advertiments</translation>
+<translation id="4984339528288761049">Prc5 (sobre)</translation>
<translation id="4989163558385430922">Mostra-ho tot</translation>
<translation id="4989809363548539747">Aquest connector no és compatible</translation>
-<translation id="4996230189582812866">Informes</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="5014174725590676422">Es mostra la pantalla de la primera execució de l'Assistent de Google a Chrome</translation>
<translation id="5015510746216210676">Nom de l'ordinador:</translation>
+<translation id="5017554619425969104">Text que has copiat</translation>
<translation id="5018422839182700155">No es pot obrir aquesta pàgina</translation>
<translation id="5019198164206649151">L'emmagatzematge de la còpia de seguretat està en mal estat</translation>
<translation id="5023310440958281426">Consulteu les polítiques de l'administrador</translation>
@@ -653,35 +727,51 @@
<translation id="5034369478845443529">Context local <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permet</translation>
<translation id="5040262127954254034">Privadesa</translation>
+<translation id="5043480802608081735">Enllaç que has copiat</translation>
<translation id="5045550434625856497">Contrasenya incorrecta</translation>
<translation id="5056549851600133418">Articles que et poden interessar</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comproveu l'adreça del servidor intermediari<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">En aquest moment el certificat del servidor no és vàlid.</translation>
<translation id="5087580092889165836">Afegeix 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="5097099694988056070">Estadístiques del dispositiu, com ara l'ús de CPU o RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">El dispositiu està gestionat per <ph name="ENROLLMENT_DOMAIN" /> i el compte, per <ph name="ACCOUNT_DOMAIN" />. Això vol dir que els administradors poden configurar tant el dispositiu com el compte de manera remota.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bits)</translation>
-<translation id="5128122789703661928">La sessió amb aquest nom no es pot suprimir.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gestiona les adreces...</translation>
+<translation id="5138227688689900538">Mostra'n menys</translation>
<translation id="5141240743006678641">Encripta contrasenyes sincronitzades amb les vostres credencials de Google</translation>
<translation id="5145883236150621069">Hi ha un codi d'error en la resposta a la política</translation>
+<translation id="515292512908731282">C4 (sobre)</translation>
<translation id="5159010409087891077">Obre la pàgina en una finestra d'incògnit nova (⇧⌘N)</translation>
<translation id="516920405563544094">Introdueix el CVC de la targeta <ph name="CREDIT_CARD" />. Un cop confirmada, la informació de la targeta del Compte de Google es compartirà amb aquest lloc web.</translation>
<translation id="5169827969064885044">Podries perdre l'accés al compte de la teva organització o ser víctima d'un robatori d'identitat. Chrome et recomana que canviïs la contrasenya ara.</translation>
<translation id="5171045022955879922">Cerqueu o escriviu l'URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Automàtica</translation>
<translation id="5179510805599951267">No està escrita en <ph name="ORIGINAL_LANGUAGE" />? Informa d'aquest error</translation>
<translation id="5190835502935405962">Barra d'adreces d'interès</translation>
-<translation id="5200263511887412697">informa de la llista d'usuaris del dispositiu que han iniciat la sessió recentment</translation>
+<translation id="519422657042045905">L'anotació no està disponible</translation>
<translation id="5201306358585911203">Una pàgina inserida en aquesta pàgina diu</translation>
<translation id="5205222826937269299">El nom és obligatori</translation>
<translation id="5215116848420601511">Formes de pagament i adreces que fan servir Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">El correu electrònic és obligatori</translation>
<translation id="5230733896359313003">Adreça d'enviament</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Connecteu-vos a la xarxa"</translation>
<translation id="5251803541071282808">Núvol</translation>
+<translation id="5252000469029418751">C7 (sobre)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Adreces de xarxa</translation>
<translation id="5285570108065881030">Mostra totes les contrasenyes desades</translation>
<translation id="5287240709317226393">Mostra les galetes</translation>
<translation id="5288108484102287882">La validació dels valors de la política ha generat advertiments</translation>
@@ -693,7 +783,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> de <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Tria la informació de contacte</translation>
<translation id="5327248766486351172">Nom</translation>
+<translation id="5329858041417644019">El navegador no està gestionat</translation>
<translation id="5332219387342487447">Mètode d'enviament</translation>
+<translation id="5334013548165032829">Registres detallats del sistema</translation>
<translation id="5344579389779391559">És possible que aquesta pàgina provi de fer-te algun càrrec</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>
@@ -701,6 +793,7 @@
<translation id="5377026284221673050">"El rellotge està endarrerit", "El rellotge està avançat" o "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Per utilitzar les targetes en tots els dispositius, inicia la sessió i activa la sincronització.</translation>
<translation id="5386426401304769735">La cadena de certificats d'aquest lloc conté un certificat que s'ha signat amb SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +804,7 @@
<translation id="5457113250005438886">No vàlides</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Refés la modificació</translation>
+<translation id="5478437291406423475">B6/C4 (sobre)</translation>
<translation id="5481076368049295676">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="54817484435770891">Afegeix una adreça vàlida</translation>
<translation id="5490432419156082418">Adreces i més</translation>
@@ -718,10 +812,12 @@
<ph name="LINE_BREAK" />
Proveu de contactar amb l'administrador del sistema.</translation>
<translation id="549333378215107354">Mida 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Adreces d'interès gestionades</translation>
<translation id="5510766032865166053">És possible que s'hagi mogut o s'hagi suprimit.</translation>
<translation id="5523118979700054094">Nom de la política</translation>
<translation id="552553974213252141">S'ha extret correctament el text?</translation>
+<translation id="553484882784876924">Prc6 (sobre)</translation>
<translation id="5540224163453853">No s'ha pogut trobar l'article sol·licitat.</translation>
<translation id="5541546772353173584">Afegeix un correu electrònic</translation>
<translation id="5545756402275714221">Articles que et poden interessar</translation>
@@ -736,15 +832,21 @@
<translation id="5595485650161345191">Edita l'adreça</translation>
<translation id="5598944008576757369">Selecciona una forma de pagament</translation>
<translation id="560412284261940334">Gestió no compatible</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> us ha redirigit massa vegades.</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="5632627355679805402">Les teves dades s'han encriptat amb la <ph name="BEGIN_LINK" />contrasenya de Google<ph name="END_LINK" /> a partir del dia <ph name="TIME" />. Introdueix-la per començar la sincronització.</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="563324245173044180">S'ha bloquejat el contingut enganyós.</translation>
<translation id="5659593005791499971">Correu electrònic</translation>
+<translation id="5663614846592581799">9x11 (sobre)</translation>
+<translation id="5663955426505430495">L'administrador del dispositiu ha instal·lat extensions per obtenir funcions addicionals. Les extensions tenen accés a algunes de les teves dades.</translation>
<translation id="5675650730144413517">Aquesta pàgina no funciona</translation>
+<translation id="5684874026226664614">Aquesta pàgina no s'ha pogut traduir.</translation>
<translation id="5685654322157854305">Afegeix una adreça d'enviament</translation>
<translation id="5689199277474810259">Exporta a JSON</translation>
<translation id="5689516760719285838">Ubicació</translation>
@@ -753,38 +855,39 @@
<translation id="5710435578057952990">La identitat d'aquest lloc web no ha estat verificada.</translation>
<translation id="5719499550583120431">S'accepten targetes de prepagament.</translation>
<translation id="5720705177508910913">Usuari actual</translation>
+<translation id="5728056243719941842">C5 (sobre)</translation>
<translation id="5730040223043577876">Chrome et recomana que restableixis la contrasenya si l'has fet servir en altres llocs web.</translation>
<translation id="5732392974455271431">Els teus pares te'l poden desbloquejar</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Desa la targeta al Compte de Google}other{Desa targetes al Compte de Google}}</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="5770114862687765385">Sembla que el fitxer està malmès. Fes clic al botó Restableix per restablir la sessió.</translation>
<translation id="5778550464785688721">Control total dels dispositius MIDI</translation>
<translation id="578305955206182703">Ambre</translation>
<translation id="57838592816432529">Silencia</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>
+<translation id="5798290721819630480">Vols descartar els canvis?</translation>
<translation id="5798683403665926540">Canvia la pàgina d'inici a la configuració de Chrome</translation>
<translation id="5803412860119678065">Vols emplenar la informació de la teva targeta <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permisos</translation>
<translation id="5810442152076338065">La connexió a <ph name="DOMAIN" /> s'ha encriptat amb un sistema de xifratge obsolet.</translation>
<translation id="5813119285467412249">&amp;Refés l'addició</translation>
<translation id="5838278095973806738">No introdueixis informació sensible en aquest lloc web (com ara contrasenyes o targetes de crèdit), ja que alguns atacants podrien robar-la.</translation>
+<translation id="5860033963881614850">Desactivat</translation>
<translation id="5863847714970149516">És possible que aquesta pàgina provi de fer-te algun càrrec</translation>
<translation id="5866257070973731571">Afegeix un número de telèfon</translation>
<translation id="5869405914158311789">No es pot accedir a aquest lloc web</translation>
<translation id="5869522115854928033">Contrasenyes desades</translation>
<translation id="5887400589839399685">S'ha desat la targeta</translation>
-<translation id="5893718151540690985">informa de la llista d'interfícies de xarxa amb els seus tipus i adreces de maquinari</translation>
<translation id="5893752035575986141">S'accepten targetes de crèdit.</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="5916664084637901428">Activat</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vols desar la targeta al Compte de Google?</translation>
<translation id="5922853866070715753">Ja queda poc</translation>
<translation id="5932224571077948991">El lloc web mostra anuncis intrusius o enganyosos</translation>
-<translation id="5939518447894949180">Restableix</translation>
<translation id="5946937721014915347">S'està obrint <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">El dispositiu no es pot inscriure amb un compte de consumidor (hi ha una llicència associada disponible).</translation>
<translation id="5967592137238574583">Edita la informació de contacte</translation>
@@ -792,6 +895,7 @@
<translation id="5975083100439434680">Redueix</translation>
<translation id="5977489021191000276">El dispositiu no està gestionat per cap administrador.</translation>
<translation id="5977976211062815271">En aquest dispositiu</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">No es pot obrir l'aplicació de pagament</translation>
<translation id="5989320800837274978">No s'especifiquen servidors intermediaris ni URL d'script .pac.</translation>
<translation id="5990559369517809815">Una extensió ha bloquejat les peticions al servidor.</translation>
@@ -802,8 +906,8 @@
<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 d'altres o que recullin 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="6033927989869462158">informa d'estadístiques del maquinari com ara l'ús de CPU o de RAM.</translation>
<translation id="6034000775414344507">Gris clar</translation>
+<translation id="6034283069659657473">10x14 (sobre)</translation>
<translation id="6039846035001940113">Si el problema continua, contacta amb el propietari del lloc web.</translation>
<translation id="6040143037577758943">Tanca</translation>
<translation id="6044573915096792553">Mida 12</translation>
@@ -812,10 +916,10 @@
<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="6058977677006700226">Vols utilitzar les targetes en tots els dispositius?</translation>
<translation id="6059925163896151826">Dispositius USB</translation>
-<translation id="6071091556643036997">El tipus de política no és vàlid.</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="6094273045989040137">Anota</translation>
<translation id="610911394827799129">A <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> trobaràs altres maneres d'explorar l'historial de navegació del teu Compte de Google</translation>
+<translation id="6132597952260690497">Informació sobre les extensions i els connectors instal·lats</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>
@@ -850,15 +954,21 @@
<translation id="6337133576188860026">Allibera menys de <ph name="SIZE" />. És possible que alguns llocs web es carreguin més a poc a poc la propera vegada que els visitis.</translation>
<translation id="6337534724793800597">Filtra les polítiques pel nom</translation>
<translation id="6358450015545214790">Què vol dir tot això?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Aquest lloc web et pot fer càrrecs.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 suggeriment més}other{# suggeriments més}}</translation>
<translation id="6387754724289022810">Perquè la propera vegada puguis pagar més ràpidament, desa la targeta i l'adreça de facturació al compte de Google i en aquest dispositiu.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Edita l'adreça d'interès</translation>
+<translation id="6406765186087300643">C0 (sobre)</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="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="6434309073475700221">Descarta</translation>
+<translation id="6446163441502663861">Kahu (sobre)</translation>
<translation id="6446608382365791566">Afegeix més informació</translation>
<translation id="6447842834002726250">Galetes</translation>
<translation id="6451458296329894277">Confirma el reenviament del formulari</translation>
@@ -871,11 +981,17 @@
<translation id="6508722015517270189">Reinicia Chrome</translation>
<translation id="6529602333819889595">&amp;Refés la supressió</translation>
<translation id="6534179046333460208">Suggeriments del Web físic</translation>
+<translation id="6556866813142980365">Refés</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="6578796323535178455">C2 (sobre)</translation>
<translation id="6579990219486187401">Rosa clar</translation>
+<translation id="6583674473685352014">B6 (sobre)</translation>
+<translation id="6587923378399804057">Enllaç que has copiat</translation>
+<translation id="6591833882275308647">El dispositiu <ph name="DEVICE_TYPE" /> no està gestionat</translation>
<translation id="6596325263575161958">Opcions d'encriptació</translation>
<translation id="6604181099783169992">Sensors de moviment o de llum</translation>
+<translation id="6609880536175561541">Prc7 (sobre)</translation>
<translation id="6624427990725312378">Informació de contacte</translation>
<translation id="6626291197371920147">Afegeix un número de targeta vàlid</translation>
<translation id="6628463337424475685">Cerca de <ph name="ENGINE" /></translation>
@@ -884,6 +1000,7 @@
<translation id="6644283850729428850">Aquesta política ha quedat obsoleta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Cap}=1{D'1 lloc web (no se't tancarà la sessió del Compte de Google)}other{De # llocs web (no se't tancarà la sessió del Compte de Google)}}</translation>
<translation id="6657585470893396449">Contrasenya</translation>
+<translation id="6670613747977017428">Torna a una pàgina segura.</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>
@@ -891,12 +1008,15 @@
<translation id="671076103358959139">Testimoni d'inscripció:</translation>
<translation id="6711464428925977395">Hi ha hagut algun problema amb el servidor intermediari o l'adreça no és correcta.</translation>
<translation id="6723740634201835758">Al teu Compte de Google</translation>
+<translation id="6738516213925468394">Les teves dades es van encriptar el dia <ph name="TIME" /> amb la teva <ph name="BEGIN_LINK" />frase de contrasenya de sincronització<ph name="END_LINK" />. Introdueix-la per començar la sincronització.</translation>
<translation id="674375294223700098">Error de certificat del servidor desconegut.</translation>
<translation id="6744009308914054259">Mentre esperes a tenir connexió, pots visitar Baixades per llegir articles sense connexió.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositiu ha entrat en mode de repòs.</translation>
+<translation id="6768213884286397650">Hagaki (postal)</translation>
<translation id="6778737459546443941">El teu pare o la teva mare encara no ho han aprovat</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Extensions</translation>
<translation id="679355240208270552">S'ha ignorat perquè la política no ha activat la cerca predeterminada.</translation>
<translation id="681021252041861472">Camp obligatori</translation>
<translation id="6810899417690483278">Identificador de personalització</translation>
@@ -929,10 +1049,12 @@
<translation id="6965978654500191972">Dispositiu</translation>
<translation id="6970216967273061347">Districte</translation>
<translation id="6973656660372572881">S'especifiquen tant els servidors intermediaris fixos com un URL d'script .pac.</translation>
+<translation id="6973932557599545801">Em sap greu, però no et puc ajudar. Continua pel teu compte.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Silencia (opció predeterminada)</translation>
<translation id="6984479912851154518">Per pagar amb una aplicació externa sortiràs del mode privat. Vols continuar?</translation>
<translation id="6989763994942163495">Mostra la configuració avançada...</translation>
+<translation id="6993898126790112050">6x9 (sobre)</translation>
<translation id="6996312675313362352">Tradueix sempre el text en <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Aquests càrrecs poden ser únics o periòdics i és possible que no s'indiquin d'una manera evident.</translation>
@@ -948,28 +1070,33 @@
<translation id="7108338896283013870">Amaga</translation>
<translation id="7108819624672055576">Permès per una extensió</translation>
<translation id="7111012039238467737">(Vàlid)</translation>
+<translation id="7118618213916969306">Cerca l'URL (<ph name="SHORT_URL" />) del porta-retalls</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="7135130955892390533">Mostra l'estat</translation>
<translation id="7138472120740807366">Mètode d'entrega</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (sobre)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">L'URL no és vàlid. Ha de tenir un esquema estàndard.</translation>
<translation id="717330890047184534">Identificador de Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">El servidor de destinació, <ph name="ORIGIN" />, ha sol·licitat que s'apliqui una política de seguretat a totes les sol·licituds que rebi. Però en comptes de proporcionar una política, ha redirigit el navegador a una altra destinació, de manera que el navegador no pot completar la sol·licitud que has fet per a <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Desa i emplena les formes de pagament</translation>
<translation id="7180611975245234373">Actualitza</translation>
<translation id="7182878459783632708">Cap política definida</translation>
<translation id="7186367841673660872">Aquesta pàgina s'ha traduït de:<ph name="ORIGINAL_LANGUAGE" />a:<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Allibera <ph name="SIZE" />. És possible que alguns llocs es carreguin més a poc a poc la propera vegada que els visitis.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">L'administrador pot veure el següent:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> no compleix la normativa de seguretat.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /> sobre aquest problema.</translation>
<translation id="7219179957768738017">La connexió utilitza <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">S'està processant</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Aquest lloc web conté programari maliciós</translation>
+<translation id="724766306220616965">Advertiments i conflictes</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="7251437084390964440">La configuració de la xarxa no compleix l'estàndard ONC. Pot ser que algunes opcions de configuració no s'hagin importat.
Detalls addicionals:
@@ -982,11 +1109,14 @@ Detalls addicionals:
<translation id="7300012071106347854">Blau elèctric</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">S'ha capturat un informe d'error (<ph name="CRASH_TIME" />) (pujada sol·licitada per l'usuari, encara no s'ha dut a terme)</translation>
+<translation id="7313965965371928911">Advertiments de <ph name="BEGIN_LINK" />Navegació segura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ajuda amb la connexió</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Línia d'ordres</translation>
-<translation id="7365061714576910172">Exporta en format Linux</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>
@@ -994,6 +1124,7 @@ Detalls addicionals:
<translation id="7381288752349550461">Substitució de la sessió gestionada</translation>
<translation id="7390545607259442187">Confirma la targeta</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">El dispositiu <ph name="DEVICE_NAME" /> està gestionat</translation>
<translation id="7407424307057130981">&lt;p&gt;Aquest error es mostra si teniu el programari Superfish en un ordinador Windows.&lt;/p&gt;
&lt;p&gt;Seguiu aquests passos per desactivar temporalment el programari perquè pugueu accedir al web. Per fer-ho, necessitareu privilegis d'administrador.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1135,7 @@ Detalls addicionals:
&lt;li&gt;Feu clic a &lt;strong&gt;Aplica&lt;/strong&gt; i, a continuació, a &lt;strong&gt;D'acord&lt;/strong&gt;.
&lt;li&gt;Visiteu el &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centre d'ajuda de Chrome&lt;/a&gt; per obtenir informació sobre com podeu suprimir permanentment el programari de l'ordinador.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestió de: <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Gestiona les contrasenyes…</translation>
<translation id="7419106976560586862">Camí del perfil</translation>
<translation id="7437289804838430631">Afegeix informació de contacte</translation>
@@ -1013,22 +1144,24 @@ Detalls addicionals:
<translation id="7442725080345379071">Taronja clar</translation>
<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="7449109375006139765">envia registres del sistema al servidor de gestió</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="7460618730930299168">La projecció no és com havies seleccionat. Vols continuar?</translation>
<translation id="7473891865547856676">No, gràcies</translation>
-<translation id="7475525192983021547">informa dels períodes de temps en què un usuari està actiu al dispositiu</translation>
<translation id="7481312909269577407">Endavant</translation>
<translation id="7485870689360869515">No s'han trobat dades.</translation>
+<translation id="7498234416455752244">Continua editant</translation>
<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="7508870219247277067">Verd alvocat</translation>
<translation id="7511955381719512146">És possible que la xarxa Wi-Fi que esteu fent servir requereixi que visiteu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (sobre)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">La connexió amb aquest lloc no és privada</translation>
+<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatòria</translation>
+<translation id="7538364083937897561">A2 (sobre)</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>
@@ -1037,8 +1170,8 @@ Detalls addicionals:
<translation id="7552846755917812628">Prova els consells següents:</translation>
<translation id="7554791636758816595">Pestanya nova</translation>
<translation id="7564049878696755256">Podries perdre l'accés al compte de <ph name="ORG_NAME" /> o tenir problemes de suplantació d'identitat. Chrome et recomana que canviïs la contrasenya ara.</translation>
-<translation id="7566125604157659769">Text que has copiat</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="7568105740864181217">Una empresa, un centre educatiu o una altra organització gestiona aquest navegador. L'administrador pot modificar la configuració del navegador de manera remota. És possible que l'activitat d'aquest dispositiu també es gestioni fora de Chrome. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></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>
@@ -1049,6 +1182,7 @@ Detalls addicionals:
<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="7633909222644580952">Dades de rendiment i informes d'errors</translation>
<translation id="7637571805876720304">Voleu suprimir la targeta de crèdit de Chromium?</translation>
<translation id="7639968568612851608">Gris fosc</translation>
<translation id="765676359832457558">Amaga la configuració avançada...</translation>
@@ -1058,9 +1192,11 @@ Detalls addicionals:
<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="7676643023259824263">Cerca el text (<ph name="TEXT" />) del porta-retalls</translation>
<translation id="7681101578153515023">Canvia el motor de cerca</translation>
<translation id="7682287625158474539">Enviament</translation>
<translation id="7687186412095877299">Emplena els formularis amb les formes de pagament desades</translation>
+<translation id="7697066736081121494">Prc8 (sobre)</translation>
<translation id="769721561045429135">En aquest moment tens targetes que només es poden fer servir en aquest dispositiu. Fes clic a Continua per consultar les targetes.</translation>
<translation id="7699293099605015246">En aquests moments no hi ha articles disponibles</translation>
<translation id="7701040980221191251">Cap</translation>
@@ -1072,11 +1208,13 @@ Detalls addicionals:
<translation id="774634243536837715">S'ha bloquejat el contingut perillós.</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="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">És possible que l'antivirus o el tallafoc hagi bloquejat la connexió.</translation>
<translation id="7759163816903619567">Domini de publicació:</translation>
<translation id="7761701407923456692">El certificat del servidor no coincideix amb l'URL.</translation>
<translation id="7763386264682878361">Analitzador de fitxers de manifest de pagament</translation>
<translation id="7764225426217299476">Afegeix una adreça</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Afegeix</translation>
<translation id="7793809570500803535">És possible que la pàgina web <ph name="SITE" /> estigui temporalment fora de servei o s'hagi traslladat permanentment a una adreça web nova.</translation>
@@ -1088,8 +1226,8 @@ Detalls addicionals:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Voleu suprimir el suggeriment de formulari de Chrome?</translation>
<translation id="7815407501681723534">S'han trobat <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> per a "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Gestió de polítiques</translation>
<translation id="782886543891417279">És possible que la xarxa Wi-Fi (<ph name="WIFI_NAME" />) que esteu fent servir requereixi que visiteu la seva pàgina d'inici de sessió.</translation>
+<translation id="7836231406687464395">Postfix (sobre)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Cap}=1{1 aplicació (<ph name="EXAMPLE_APP_1" />)}=2{2 aplicacions (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# aplicacions (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Tanmateix, no sou invisible. La vostra empresa, el vostre proveïdor de serveis d'Internet i els llocs web que visiteu poden veure la vostra navegació d'incògnit.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1236,7 @@ Detalls addicionals:
<translation id="7878562273885520351">La teva contrasenya pot estar en perill</translation>
<translation id="7882421473871500483">Marró</translation>
<translation id="7887683347370398519">Comproveu el CVC i torneu-ho a provar</translation>
-<translation id="7893255318348328562">Nom de la sessió</translation>
+<translation id="7904208859782148177">C3 (sobre)</translation>
<translation id="79338296614623784">Introdueix un número de telèfon vàlid</translation>
<translation id="7935318582918952113">Destil·lador DOM</translation>
<translation id="7937554595067888181">Data de caducitat: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1246,25 @@ Detalls addicionals:
<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="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">No especificat</translation>
<translation id="800218591365569300">Prova de tancar altres pestanyes o programes per alliberar memòria.</translation>
+<translation id="8004582292198964060">Navegador</translation>
<translation id="8009225694047762179">Gestiona les contrasenyes</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Aquesta targeta i l'adreça de facturació associada es desaran. La podràs utilitzar quan tinguis la sessió iniciada a <ph name="USER_EMAIL" />.}other{Aquestes targetes i les adreces de facturació associades es desaran. Les podràs utilitzar quan tinguis la sessió iniciada a <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Aquesta pàgina està escrita en <ph name="SOURCE_LANGUAGE" />. Vols traduir-la a <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Bolígraf</translation>
+<translation id="8037117624646282037">Qui ha utilitzat el dispositiu recentment</translation>
<translation id="8037357227543935929">Pregunta (opció predeterminada)</translation>
<translation id="803771048473350947">Fitxer</translation>
<translation id="8041089156583427627">Envia suggeriments</translation>
<translation id="8041940743680923270">Utilitza l'opció predeterminada global (Pregunta)</translation>
<translation id="8042918947222776840">Tria un mètode de recollida</translation>
<translation id="8057711352706143257"><ph name="SOFTWARE_NAME" /> no s'ha configurat correctament. Normalment el problema se soluciona desinstal·lant <ph name="SOFTWARE_NAME" />. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">El dispositiu s'ha configurat de la manera següent:</translation>
+<translation id="8066955247577885446">S'ha produït un error.</translation>
+<translation id="8074253406171541171">10x13 (sobre)</translation>
<translation id="8078141288243656252">No es poden fer anotacions en un document girat</translation>
<translation id="8079031581361219619">Vols tornar a carregar el lloc web?</translation>
<translation id="8088680233425245692">No s'ha pogut consultar l'article.</translation>
@@ -1131,11 +1273,12 @@ Detalls addicionals:
<translation id="8091372947890762290">L'activació està pendent al servidor</translation>
<translation id="8092774999298748321">Porpra intens</translation>
<translation id="8094917007353911263">És possible que la xarxa que esteu fent servir requereixi que visiteu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Les targetes que no eren vàlides s'han suprimit</translation>
<translation id="8103161714697287722">Mètode de pagament</translation>
<translation id="8118489163946903409">Mètode de pagament</translation>
+<translation id="8123836779274890062"><ph name="ENROLLMENT_DOMAIN" /> gestiona <ph name="DEVICE_TYPE" /></translation>
<translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> no s'ha instal·lat correctament a l'ordinador o a la xarxa. Demana a l'administrador de TI que resolgui aquest problema.</translation>
-<translation id="8130693978878176684">Ja no et puc ajudar més. Continua pel teu compte.</translation>
<translation id="8131740175452115882">Confirma</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>
@@ -1145,8 +1288,11 @@ Detalls addicionals:
<translation id="8197543752516192074">Tradueix la pàgina</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="8202370299023114387">Conflicte</translation>
+<translation id="8206978196348664717">Prc4 (sobre)</translation>
<translation id="8211406090763984747">La connexió és segura</translation>
<translation id="8218327578424803826">Ubicació assignada:</translation>
+<translation id="8220146938470311105">C7/C6 (sobre)</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="8238581221633243064">Obre la pàgina en una pestanya d'incògnit nova</translation>
@@ -1158,14 +1304,16 @@ Detalls addicionals:
<translation id="825929999321470778">Mostra totes les contrasenyes desades</translation>
<translation id="8261506727792406068">Suprimeix</translation>
<translation id="8267698848189296333">S'està iniciant la sessió com a <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242"><ph name="ENROLLMENT_DOMAIN" /> gestiona el navegador. L'administrador pot modificar la configuració del navegador de manera remota. És possible que l'activitat d'aquest dispositiu també es gestioni fora de Chrome. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Inicia la sessió</translation>
<translation id="8288807391153049143">Mostra el certificat</translation>
<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="8298115750975731693">És possible que la xarxa Wi-Fi (<ph name="WIFI_NAME" />) que esteu fent servir requereixi que visiteu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">No s'ha pogut executar la traducció a causa d'un problema amb la connexió de xarxa.</translation>
-<translation id="8311129316111205805">Carrega la sessió</translation>
<translation id="8332188693563227489">S'ha rebutjat l'accés a <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1331,6 @@ Detalls addicionals:
<translation id="8416694386774425977">La configuració de la xarxa no és vàlida i no s'ha pogut importar.
Detalls addicionals:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositiu gestionat per <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Canvia</translation>
<translation id="8428213095426709021">Configuració</translation>
@@ -1210,9 +1357,11 @@ Detalls addicionals:
<translation id="860043288473659153">Nom del titular de la targeta</translation>
<translation id="861775596732816396">Mida 4</translation>
<translation id="8620436878122366504">Els teus pares encara no ho han aprovat</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Desa aquesta targeta al dispositiu</translation>
<translation id="8663226718884576429">Resum de la comanda, <ph name="TOTAL_LABEL" />, més detalls</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, resposta, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">La teva connexió a <ph name="DOMAIN" /> no està xifrada.</translation>
<translation id="8718314106902482036">No s'ha completat el pagament</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, suggeriment de cerca</translation>
@@ -1226,6 +1375,7 @@ Detalls addicionals:
<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="8763927697961133303">Dispositiu USB</translation>
<translation id="8768895707659403558">Per utilitzar les targetes en tots els dispositius, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Refés la supressió</translation>
<translation id="8792621596287649091">Podries perdre l'accés al compte de <ph name="ORG_NAME" /> o tenir problemes de suplantació d'identitat. Chromium et recomana que canviïs la contrasenya ara.</translation>
<translation id="8800988563907321413">Els suggeriments més propers es mostren aquí</translation>
@@ -1236,10 +1386,12 @@ Detalls addicionals:
<translation id="885730110891505394">Comparteix informació amb Google</translation>
<translation id="8858065207712248076">Chrome et recomana que restableixis la contrasenya per a <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> si l'has fet servir en altres llocs web.</translation>
<translation id="8866481888320382733">S'ha produït un error en analitzar la configuració de la política</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Tancades recentment</translation>
<translation id="8874824191258364635">Introdueix un número de targeta vàlid</translation>
<translation id="8891727572606052622">El mode de servidor intermediari no és vàlid.</translation>
<translation id="8903921497873541725">Amplia</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Voleu desar aquesta targeta al vostre compte de Google?</translation>
<translation id="8932102934695377596">El rellotge està endarrerit</translation>
<translation id="893332455753468063">Afegeix un nom</translation>
@@ -1247,13 +1399,13 @@ Detalls addicionals:
<translation id="894185898663964645">L'administrador ha configurat certificats arrel personalitzats, que li poden permetre veure el contingut dels llocs web que visites.</translation>
<translation id="8943282376843390568">Verd llima</translation>
<translation id="8957210676456822347">Autorització de portals captius</translation>
+<translation id="8966619695390250636">Volies dir?</translation>
<translation id="8968766641738584599">Desa la targeta</translation>
<translation id="8971063699422889582">El certificat del servidor ha caducat.</translation>
<translation id="8975012916872825179">Inclou informació com ara números de telèfon, adreces electròniques i adreces d'enviament</translation>
<translation id="8978053250194585037">Navegació segura de Google ha <ph name="BEGIN_LINK" />detectat recentment activitat de pesca de credencials<ph name="END_LINK" /> a <ph name="SITE" />. Els llocs web de pesca de credencials es fan passar per altres llocs web per enganyar-te.</translation>
<translation id="8983003182662520383">Formes de pagament i adreces que fan servir Google Pay</translation>
<translation id="8987927404178983737">Mes</translation>
-<translation id="8988408250700415532">S'ha produït un error. Pots finalitzar la comanda al lloc web.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Aquest lloc web 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>
@@ -1263,6 +1415,7 @@ Detalls addicionals:
<translation id="9011424611726486705">Obre la configuració del lloc web</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(No vàlid)</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>
@@ -1274,11 +1427,11 @@ Detalls addicionals:
<translation id="9065745800631924235">Cerca de <ph name="TEXT" /> des de l'historial</translation>
<translation id="9069693763241529744">Bloquejat per una extensió</translation>
<translation id="9076283476770535406">Pot incloure contingut no apte per a menors</translation>
+<translation id="9076630408993835509">Cap empresa ni cap altra organització supervisa aquest navegador. És possible que l'activitat d'aquest dispositiu es gestioni fora de Chrome. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Necessitem més informació</translation>
<translation id="9080712759204168376">Resum de la comanda</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>
<translation id="9106062320799175032">Afegeix una adreça de facturació</translation>
-<translation id="9110718169272311511">L'Assistent de Google a Chrome està disponible a la part inferior de la pantalla</translation>
<translation id="9114524666733003316">S'està confirmant la targeta...</translation>
<translation id="9128870381267983090">Connecta't a la xarxa</translation>
<translation id="9137013805542155359">Mostra l'original</translation>
@@ -1287,6 +1440,7 @@ Detalls addicionals:
<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="9158625974267017556">C6 (sobre)</translation>
<translation id="9168814207360376865">Permet que els llocs web comprovin si tens formes de pagament desades</translation>
<translation id="9169664750068251925">Bloqueja sempre en aquest lloc</translation>
<translation id="9170848237812810038">&amp;Desfés</translation>
@@ -1301,10 +1455,12 @@ Detalls addicionals:
<translation id="9219103736887031265">Imatges</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ESBORRA EL FORMULARI</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Podries perdre l'accés al Compte de Google. Chromium et recomana que canviïs la contrasenya ara. Se't demanarà que iniciïs la sessió.</translation>
<translation id="939736085109172342">Carpeta nova</translation>
<translation id="945855313015696284">Consulta la informació següent i suprimeix les targetes que no siguin vàlides</translation>
<translation id="951104842009476243">Targetes de dèbit i de prepagament acceptades</translation>
+<translation id="958202389743790697">S'ha bloquejat d'acord amb la política de seguretat de: <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Pot ser que aquest contingut provi d'instal·lar aplicacions enganyoses que es facin passar per d'altres o que recullin dades que podrien utilitzar-se per fer un seguiment de la teva activitat. <ph name="BEGIN_LINK" />Mostra igualment<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Muntatge oficial</translation>
<translation id="973773823069644502">Afegeix una adreça d'entrega</translation>
@@ -1313,6 +1469,7 @@ Detalls addicionals:
<translation id="984275831282074731">Formes de pagament</translation>
<translation id="985199708454569384">&lt;p&gt;Aquest error es mostra si la data i l'hora de l'ordinador o del dispositiu mòbil són incorrectes.&lt;/p&gt;
&lt;p&gt;Per solucionar l'error, obriu el rellotge del dispositiu i comproveu que la data i l'hora siguin correctes.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Muntatge del desenvolupador</translation>
<translation id="989988560359834682">Edita l'adreça</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_cs.xtb b/chromium/components/strings/components_strings_cs.xtb
index 69253c29018..a988784fb78 100644
--- a/chromium/components/strings/components_strings_cs.xtb
+++ b/chromium/components/strings/components_strings_cs.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
-<translation id="1005145902654145231">Přejmenování návštěvy se nezdařilo.</translation>
<translation id="1008557486741366299">Teď ne</translation>
<translation id="1010200102790553230">Načíst stránku později</translation>
<translation id="1015730422737071372">Zadejte další podrobnosti</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">neznámé jméno</translation>
<translation id="1050038467049342496">Zavřete ostatní aplikace</translation>
<translation id="1055184225775184556">&amp;Vrátit přidání zpět</translation>
+<translation id="1056898198331236512">Upozornění</translation>
<translation id="1058479211578257048">Ukládání karet...</translation>
<translation id="10614374240317010">Nikdy se neukládají</translation>
+<translation id="1062160989074299343">Prc10 (obálka)</translation>
<translation id="106701514854093668">Záložky v PC</translation>
<translation id="1074497978438210769">Nezabezpečeno</translation>
<translation id="1080116354587839789">Přizpůsobit na šířku</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Přidání jména na kartě</translation>
<translation id="1089439967362294234">Změnit heslo</translation>
<translation id="109743633954054152">Hesla můžete spravovat v nastavení Chromu</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Během aktualizace zabezpečení na webech mohou být upozornění běžná. Brzy by se to mělo zlepšit.</translation>
<translation id="1126551341858583091">Velikost místního úložiště je <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Mezipaměť zásady je v pořádku</translation>
+<translation id="1131264053432022307">Obrázek, který jste zkopírovali</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Přejmenovat</translation>
<translation id="1175364870820465910">Tisk...</translation>
<translation id="1181037720776840403">Odebrat</translation>
<translation id="1197088940767939838">Oranžová</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Název zařízení</translation>
<translation id="124116460088058876">Další jazyky</translation>
<translation id="1250759482327835220">Abyste příště mohli zaplatit rychleji, uložte si kartu, jméno a fakturační adresu do účtu Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronizováno)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Varianty pro příkazový řádek</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="1314614906530272393">Vybraná návštěvy neexistuje.</translation>
+<translation id="1320233736580025032">Prc1 (obálka)</translation>
+<translation id="132301787627749051">Vyhledat obrázek ve schránce</translation>
<translation id="1323433172918577554">Zobrazit více</translation>
<translation id="132390688737681464">Ukládat a vyplňovat adresy</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:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Adresa vyzvednutí</translation>
<translation id="1348198688976932919">Web, na který se chystáte přejít, obsahuje nebezpečné aplikace</translation>
<translation id="1348779747280417563">Potvrdit jméno</translation>
+<translation id="1357195169723583938">Kdo zařízení v poslední době používal a kdy</translation>
+<translation id="1364822246244961190">Tato zásada je blokována, její hodnota bude ignorována.</translation>
<translation id="1374468813861204354">návrhy</translation>
+<translation id="1374692235857187091">Index-4x6 (pohlednice)</translation>
<translation id="1375198122581997741">O verzi aplikace</translation>
<translation id="1376836354785490390">Zobrazit méně</translation>
<translation id="1377321085342047638">Číslo karty</translation>
<translation id="138218114945450791">Světle modrá</translation>
+<translation id="1382194467192730611">Zařízení USB povolené administrátorem</translation>
<translation id="139305205187523129">Web <ph name="HOST_NAME" /> neodeslal žádná data.</translation>
+<translation id="140316286225361634">Web <ph name="ORIGIN" /> požádal, aby se na všechny jeho požadavky uplatňovaly bezpečnostní zásady, a podle těchto zásad není považován za bezpečný.</translation>
<translation id="1405567553485452995">Světle zelená</translation>
<translation id="1407135791313364759">Otevřít vše</translation>
<translation id="1413809658975081374">Chyba ochrany soukromí</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Ano</translation>
<translation id="1430915738399379752">Tisk</translation>
<translation id="1455413310270022028">Guma</translation>
+<translation id="1463543813647160932">5:7</translation>
+<translation id="1472675084647422956">Zobrazit více</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Vybrat dodací adresu</translation>
+<translation id="1492194039220927094">Přenesení zásad:</translation>
<translation id="1501859676467574491">Zobrazit karty z vašeho účtu Google</translation>
-<translation id="1506687042165942984">Zobrazí uloženou (tj. neaktuální) kopii této stránky</translation>
<translation id="1507202001669085618">&lt;p&gt;Tato chyba se zobrazí při použití portálu Wi-Fi, na kterém je třeba se před přístupem na internet přihlásit.&lt;/p&gt;
&lt;p&gt;Chybu odstraníte tím, že na stránce, kterou se snažíte otevřít, kliknete na &lt;strong&gt;Připojení&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Je vyžadováno telefonní číslo</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Datum sestavení</translation>
<translation id="1521655867290435174">Tabulky Google</translation>
<translation id="1527263332363067270">Čeká se na připojení…</translation>
+<translation id="1529521330346880926">10x15 (obálka)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Tato stránka říká</translation>
<translation id="153384715582417236">To je prozatím vše</translation>
<translation id="154408704832528245">Vybrat adresu doručení</translation>
<translation id="1549470594296187301">Chcete-li tuto funkci použít, musí být aktivován JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Zadejte datum vypršení platnosti</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Obrázek, který jste zkopírovali</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Bránit této stránce ve vytváření dalších dialogových oken</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Ukončit relaci</translation>
<translation id="1639239467298939599">Načítání</translation>
<translation id="1640180200866533862">Zásady pro uživatele</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">Certifikát serveru obsahuje slabý kryptografický klíč.</translation>
<translation id="1697532407822776718">Vše je nastaveno!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument je na přidání označení a poznámek příliš velký</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>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Zkuste kontaktovat administrátora systému.</translation>
<translation id="1740951997222943430">Zadejte platný měsíc vypršení platnosti</translation>
<translation id="1743520634839655729">Abyste příště mohli zaplatit rychleji, uložte si kartu, jméno a fakturační adresu do účtu Google a do tohoto zařízení.</translation>
+<translation id="1745880797583122200">Váš prohlížeč je spravován</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Aktualizujte prosím heslovou frázi pro synchronizaci.</translation>
<translation id="1787142507584202372">Zde se zobrazí otevřené karty</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Jméno držitele karty</translation>
<translation id="1821930232296380041">Neplatný požadavek nebo parametry požadavku</translation>
+<translation id="1822540298136254167">Navštívené weby a na nich strávený čas</translation>
<translation id="1826516787628120939">Probíhá kontrola</translation>
<translation id="1834321415901700177">Tento web obsahuje škodlivé programy</translation>
<translation id="1839551713262164453">Ověření hodnot zásad selhalo s chybami</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Vymazat z Chromu údaje o historii procházení</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{a 1 další}few{a # další}many{a # další}other{a # dalších}}</translation>
<translation id="2003709556000175978">Resetujte heslo</translation>
+<translation id="20053308747750172">Server, na který přecházíte (<ph name="ORIGIN" />), požádal, aby se na všechny na něj odesílané požadavky vztahovaly bezpečnostní zásady. Nyní však dodal neplatné zásady, které prohlížeči znemožňují splnit váš požadavek na web <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy server je nastaven na automatickou konfiguraci.</translation>
<translation id="2030481566774242610">Měli jste na mysli <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Zkontrolovat proxy server a firewall<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Department</translation>
<translation id="2102134110707549001">Navrhnout silné heslo…</translation>
<translation id="2108755909498034140">Restartujte počítač</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Karta</translation>
<translation id="2114841414352855701">Zásada ignorována, protože bylo přepsána zásadou <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobilní záložky</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (obálka)</translation>
<translation id="2181821976797666341">Zásady</translation>
<translation id="2183608646556468874">Telefonní číslo</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}few{# adresy}many{# adresy}other{# adres}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Telefonní číslo</translation>
<translation id="2283340219607151381">Ukládat a vyplňovat adresy</translation>
<translation id="2292556288342944218">Vaše připojení k internetu je blokováno</translation>
+<translation id="2294558542833290837">Odkaz, který jste původně otevřeli, je neobvyklý</translation>
+<translation id="2297722699537546652">B5 (obálka)</translation>
+<translation id="2310021320168182093">Chou2 (obálka)</translation>
<translation id="2316887270356262533">Uvolní více než 1 MB. Je možné, že se některé weby při příští návštěvě budou načítat pomaleji.</translation>
<translation id="2317259163369394535">Doména <ph name="DOMAIN" /> vyžaduje zadání uživatelského jména a hesla.</translation>
<translation id="2317583587496011522">Obchodník přijímá debetní karty.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, platnost vyprší <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Nastavení je spravováno administrátorem</translation>
+<translation id="2346319942568447007">Obrázek, který jste zkopírovali</translation>
<translation id="2349790679044093737">Relace VR je aktivní</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>
@@ -239,29 +266,34 @@
<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="2378238891085281592">Jste v soukromém režimu</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Server, na který přecházíte (<ph name="ORIGIN" />), požádal, aby se na všechny na něj odesílané požadavky vztahovaly bezpečnostní zásady. Nyní však zásady nedodal, a prohlížeč proto váš požadavek na web <ph name="SITE" /> nemůže splnit.</translation>
<translation id="244665789865330679">Vaše zařízení a účet jsou spravovány doménou <ph name="ENROLLMENT_DOMAIN" />. To znamená, že je může vzdáleně konfigurovat váš administrátor.</translation>
<translation id="2463193859425327265">Změnit domovskou stránku</translation>
<translation id="2463739503403862330">Vyplnit</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Vybrat způsob doručení</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Spustit Diagnostiku sítě<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Přeložit tuto stránku</translation>
<translation id="2479410451996844060">Neplatná adresa URL vyhledávání.</translation>
<translation id="2482878487686419369">Oznámení</translation>
<translation id="248348093745724435">Zásady zařízení</translation>
+<translation id="2485387744899240041">Uživatelská jména pro zařízení a prohlížeč</translation>
<translation id="2491120439723279231">Certifikát serveru obsahuje chyby.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Naskenovat novou kartu</translation>
<translation id="2501278716633472235">Zpět</translation>
<translation id="2503184589641749290">Přijímané debetní a předplacené karty</translation>
<translation id="2515629240566999685">Zkontrolovat, zda máte dostatečně silný signál</translation>
-<translation id="2516852381693169964">Vyhledat obrázek pomocí vyhledávače <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Uloženo pouze do tohoto zařízení</translation>
<translation id="2524461107774643265">Přidání dalších informací</translation>
<translation id="2536110899380797252">Přidat adresu</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (obálka)</translation>
<translation id="2625385379895617796">Vaše hodiny jdou napřed</translation>
<translation id="2634124572758952069">IP adresa serveru <ph name="HOST_NAME" /> nebyla nalezena.</translation>
<translation id="2639739919103226564">Stav:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Zavřete ostatní karty nebo aplikace</translation>
<translation id="267371737713284912">akci vrátíte zpět stisknutím kombinace kláves <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Jste si jisti, že chcete tyto stránky odstranit ze své historie?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Odejít</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Přijímané karty</translation>
<translation id="2702801445560668637">Seznam četby</translation>
<translation id="2704283930420550640">Hodnota neodpovídá formátu.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Odstranit vybrané položky</translation>
<translation id="277133753123645258">Způsob dopravy</translation>
<translation id="277499241957683684">Chybějící záznam zařízení</translation>
-<translation id="2781030394888168909">Exportovat pro MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Připojení bylo resetováno.</translation>
<translation id="2788784517760473862">Přijímané kreditní karty</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Otevřít anonymní okno</translation>
+<translation id="2850739647070081192">Invite (obálka)</translation>
<translation id="2851634818064021665">K návštěvě tohoto webu potřebujete povolení</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Uložit kartu?</translation>
<translation id="2903493209154104877">Adresy</translation>
<translation id="290376772003165898">Není stránka v jazyce <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Způsob doručení</translation>
<translation id="2928905813689894207">Fakturační adresa</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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ší}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> dalších}}</translation>
+<translation id="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (obálka)</translation>
<translation id="3024663005179499861">Chybný typ zásady</translation>
<translation id="3037605927509011580">Aj, chyba!</translation>
<translation id="3041612393474885105">Informace o certifikátu</translation>
+<translation id="3060227939791841287">C9 (obálka)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Přidat adresu vyzvednutí</translation>
<translation id="3105172416063519923">ID díla:</translation>
<translation id="3109728660330352905">K zobrazení této stránky nemáte oprávnění.</translation>
@@ -361,20 +401,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na serveru <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Zrušit platbu</translation>
<translation id="3207960819495026254">Přidáno do záložek</translation>
-<translation id="3209375525920864198">Zadejte prosím platný název návštěvy.</translation>
+<translation id="321912867715453276">Upozornění: Pro zásadu je k dispozici několik zdrojů, ale hodnoty jsou stejné.</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="3229041911291329567">Informace o verzi zařízení a prohlížeče</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Přidání jména na kartě</translation>
<translation id="3287510313208355388">Stáhnout, až bude zařízení online</translation>
<translation id="3293642807462928945">Další informace o zásadě <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nebyly nalezeny žádné výsledky</translation>
-<translation id="3305707030755673451">Vaše data byla <ph name="TIME" /> zašifrována pomocí heslové fráze pro synchronizaci. Chcete-li zahájit synchronizaci, zadejte ji.</translation>
<translation id="3320021301628644560">Přidání fakturační adresy</translation>
<translation id="3324983252691184275">Karmínová</translation>
<translation id="3338095232262050444">Zabezpečeno</translation>
@@ -402,9 +443,11 @@
<translation id="3427342743765426898">&amp;Opakovat úpravy</translation>
<translation id="342781501876943858">Pokud jste heslo použili na jiném webu, doporučujeme vám ho resetovat.</translation>
<translation id="3431636764301398940">Uložit tuto kartu do zařízení</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Vlastník tohoto zařízení hru s dinosaurem vypnul.</translation>
<translation id="3447884698081792621">Zobrazit certifikát (vydavatel: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Interval načtení:</translation>
+<translation id="3456231139987291353">Number-11 (obálka)</translation>
<translation id="3461824795358126837">Zvýrazňovač</translation>
<translation id="3462200631372590220">Skrýt rozšířené</translation>
<translation id="3467763166455606212">Je nutné zadat jméno držitele karty</translation>
@@ -427,19 +470,22 @@
<translation id="358285529439630156">Obchodník přijímá kreditní a předplacené karty.</translation>
<translation id="3582930987043644930">Přidejte jméno</translation>
<translation id="3583757800736429874">&amp;Opakovat přesunutí</translation>
+<translation id="35866233670761917">Vaši administrátoři nevidí obsah webů, které navštěvujete</translation>
<translation id="3586931643579894722">Skrýt podrobnosti</translation>
+<translation id="3592413004129370115">Italian (obálka)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Velikost 2</translation>
<translation id="3615877443314183785">Zadejte platné datum vypršení platnosti</translation>
<translation id="36224234498066874">Smazat údaje o prohlížení...</translation>
<translation id="362276910939193118">Zobrazit celou historii</translation>
-<translation id="3623476034248543066">Zobrazit hodnotu</translation>
<translation id="3630155396527302611">Pokud je program v seznamu programů s oprávněním přistupovat k síti již uveden, zkuste jej ze seznamu odebrat a znovu přidat.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Ověření proběhlo úspěšně</translation>
<translation id="3655670868607891010">Pokud se vám tato stránka zobrazuje často, zkuste využít tyto <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Verze</translation>
<translation id="366077651725703012">Aktualizace platební karty</translation>
<translation id="3676592649209844519">ID zařízení:</translation>
+<translation id="3677008721441257057">Měli jste na mysli &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Požadavek nebylo možné podepsat</translation>
<translation id="3678529606614285348">Otevřete stránku v novém anonymním okně (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Zpráva o selhání pořízená <ph name="CRASH_TIME" /> byla nahrána <ph name="UPLOAD_TIME" /></translation>
@@ -447,13 +493,14 @@
<translation id="3704162925118123524">Síť, kterou používáte, může vyžadovat, abyste navštívili její stránku přihlášení.</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="3709599264800900598">Zkopírovaný text</translation>
<translation id="3712624925041724820">Byly vyčerpány licence</translation>
<translation id="3714780639079136834">Zapnout mobilní datové připojení nebo Wi-Fi</translation>
<translation id="3715597595485130451">Připojení k síti Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Zkontrolovat proxy server, firewall a konfiguraci DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Tuto chybu mohou způsobovat aplikace, jako jsou antivirové programy, firewally a software na filtrování nebo zprostředkování webového provozu.</translation>
+<translation id="373042150751172459">B4 (obálka)</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" /> teď 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="3745099705178523657">Po potvrzení budou údaje o kartě z vašeho účtu Google poskytnuty tomuto webu.</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>
@@ -466,10 +513,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Platnost do: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Velikost 16</translation>
+<translation id="3797522431967816232">Prc3 (obálka)</translation>
<translation id="3807873520724684969">Byl zablokován škodlivý obsah.</translation>
<translation id="3810973564298564668">Spravovat</translation>
<translation id="382518646247711829">Pokud používáte proxy server...</translation>
<translation id="3828924085048779000">Prázdná heslová fráze není povolena.</translation>
+<translation id="3831915413245941253">Z domény <ph name="ENROLLMENT_DOMAIN" />do tohoto zařízení byla nainstalována rozšíření pro dodatečné funkce. Rozšíření mají přístup k některým vašim datům.</translation>
<translation id="385051799172605136">Zpět</translation>
<translation id="3858027520442213535">Aktualizovat datum a čas</translation>
<translation id="3884278016824448484">Konfliktní identifikátor zařízení</translation>
@@ -477,6 +526,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Na tomto webu se vždy zeptat</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>
@@ -487,11 +537,13 @@
<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="3984550557525787191">Tento název návštěvy již existuje.</translation>
<translation id="3987940399970879459">Méně než 1 MB</translation>
+<translation id="4008849406247176967">Upozornění: Pro tuto zásadu je přítomno několik zdrojů s konfliktními hodnotami.</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="4030383055268325496">&amp;Vrátit přidání zpět</translation>
+<translation id="4032320456957708163">Prohlížeč je spravován doménou <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Klíč <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (obálka)</translation>
<translation id="4067947977115446013">Přidejte platnou adresu</translation>
<translation id="4072486802667267160">Při zpracování objednávky došlo k chybě. Zkuste to prosím znovu.</translation>
<translation id="4075732493274867456">Klient a server nepodporují společnou verzi protokolu SSL nebo šifrovací sadu.</translation>
@@ -511,10 +563,12 @@
<translation id="4159784952369912983">Nachová</translation>
<translation id="4165986682804962316">Nastavení webu</translation>
<translation id="4171400957073367226">Chybný ověřovací podpis</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> další položka}few{<ph name="ITEM_COUNT" /> další položky}many{<ph name="ITEM_COUNT" /> další položky}other{<ph name="ITEM_COUNT" /> dalších položek}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (obálka)</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="4221630205957821124">&lt;h4&gt;Krok 1: Přihlaste se do portálu&lt;/h4&gt;
@@ -546,58 +600,79 @@
<translation id="4277028893293644418">Resetovat heslo</translation>
<translation id="4280429058323657511">s platností do <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Tato karta byla uložena do vašeho učtu Google}few{Tyto karty byly uloženy do vašeho účtu Google.}many{Tyto karty byly uloženy do vašeho účtu Google.}other{Tyto karty byly uloženy do vašeho účtu Google.}}</translation>
+<translation id="42981349822642051">Rozbalit</translation>
+<translation id="4302965934281694568">Chou3 (obálka)</translation>
<translation id="4305817255990598646">Přepínač</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokovat (výchozí)</translation>
+<translation id="4318566738941496689">Název zařízení a síťová adresa</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="4340982228985273705">Tento počítač nebyl rozpoznán jako spravovaný organizací, proto lze pomocí zásad automaticky instalovat pouze rozšíření hostovaná v Internetovém obchodě Chrome. Adresa URL Internetového obchodu Chrome pro aktualizace je <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Přijímané kreditní karty</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Spravovat platební metody...</translation>
+<translation id="4367563149485757821">Number-12 (obálka)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">výsledky vyhledávání</translation>
-<translation id="4406972042435603828">Vaši administrátoři nainstalovali rozšíření s rozsáhlými funkcemi.</translation>
<translation id="4408413947728134509">Soubory cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Adresa vyzvednutí</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="443121186588148776">Sériový port</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="4434045419905280838">Vyskakovací okna a přesměrování</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Využití proxy serveru je zakázáno, je však určena explicitní konfigurace proxy serveru.</translation>
<translation id="445100540951337728">Přijímané debetní karty</translation>
+<translation id="4466881336512663640">Změny ve formuláři budou ztraceny. Opravdu chcete pokračovat?</translation>
<translation id="4482953324121162758">Tento web se nebude překládat.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Neplatná adresa URL. Je třeba použít adresu URL se standardním schématem, např. http://example.com nebo https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (obálka)</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="4517607026994743406">Comm-10 (obálka)</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
<translation id="4524805452350978254">Spravovat karty</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Zkuste zakázat rozšíření.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Doručení</translation>
+<translation id="4579056131138995126">Personal (obálka)</translation>
<translation id="4582204425268416675">Odebrat kartu</translation>
<translation id="4587425331216688090">Odstranit adresu z Chromu?</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="4597348597567598915">Velikost 8</translation>
+<translation id="4600854749408232102">C6/C5 (obálka)</translation>
<translation id="4646534391647090355">Zobrazit</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="467809019005607715">Prezentace Google</translation>
<translation id="4690462567478992370">Přestat používat neplatný certifikát</translation>
+<translation id="4691835149146451662">Architecture-A (obálka)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Připojení bylo přerušeno</translation>
<translation id="471880041731876836">K návštěvě tohoto webu nemáte povolení</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Spustit Diagnostiku sítě systému Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Znovu načíst zásady</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">Prc2 (obálka)</translation>
<translation id="4736825316280949806">Restartujte Chromium</translation>
<translation id="473775607612524610">Aktualizovat</translation>
<translation id="4738601419177586157">Návrh vyhledávacího dotazu <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Spravovat hesla…</translation>
<translation id="4744603770635761495">Spustitelná cesta</translation>
+<translation id="4746351372139058112">Zprávy</translation>
<translation id="4750917950439032686">Vaše údaje (například hesla nebo čísla platebních karet) jsou při odesílání na tento web soukromé.</translation>
<translation id="4756388243121344051">Historie</translation>
<translation id="4758311279753947758">Přidat kontaktní údaje</translation>
@@ -605,9 +680,9 @@
<translation id="4764776831041365478">Webové stránky na adrese <ph name="URL" /> jsou možná dočasně nedostupné nebo mohly být přemístěny na novou webovou adresu.</translation>
<translation id="4771973620359291008">Došlo k neznámé chybě.</translation>
<translation id="4785689107224900852">Přejít na tuto kartu</translation>
-<translation id="4792143361752574037">Při pokusu o přístup k souborům došlo k chybě. Ukládání na disk je v současné době zakázáno. Chcete-li to zkusit znovu, obnovte stránku.</translation>
<translation id="4798078619018708837">Chcete-li aktualizovat údaje o kartě, zadejte datum vypršení platnosti a kód CVC karty <ph name="CREDIT_CARD" />. Po potvrzení budou údaje o kartě z vašeho účtu Google poskytnuty tomuto webu.</translation>
<translation id="4800132727771399293">Zkontrolujte datum vypršení platnosti a kód CVC a zkuste to znovu.</translation>
+<translation id="480334179571489655">Chyba zásad ohledně původu</translation>
<translation id="4803924862070940586"><ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
<translation id="4807049035289105102">Web <ph name="SITE" /> teď 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>
@@ -622,7 +697,6 @@
<translation id="4881695831933465202">Otevřít</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>
@@ -631,15 +705,15 @@
<translation id="4943872375798546930">Žádné výsledky</translation>
<translation id="4950898438188848926">Tlačítko přepínání karet. Stisknutím klávesy Enter přejdete na otevřenou kartu (<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />)</translation>
<translation id="495170559598752135">Akce</translation>
-<translation id="495832697253704892">Hlášení rozšíření</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Rozbalit seznam</translation>
<translation id="4974590756084640048">Znovu zapnout upozornění</translation>
+<translation id="4984339528288761049">Prc5 (obálka)</translation>
<translation id="4989163558385430922">Zobrazit vše</translation>
<translation id="4989809363548539747">Tento plugin není podporován</translation>
-<translation id="4996230189582812866">Hlášení</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="5014174725590676422">Je zobrazena obrazovka prvního spuštění Asistenta Google v Chromu</translation>
<translation id="5015510746216210676">Název počítače:</translation>
+<translation id="5017554619425969104">Zkopírovaný text</translation>
<translation id="5018422839182700155">Tuto stránku nelze otevřít</translation>
<translation id="5019198164206649151">Záložní úložiště je ve špatném stavu</translation>
<translation id="5023310440958281426">Zkontrolujte zásady svého správce</translation>
@@ -649,35 +723,51 @@
<translation id="5034369478845443529">Místní kontext <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Povolit</translation>
<translation id="5040262127954254034">Ochrana soukromí</translation>
+<translation id="5043480802608081735">Zkopírovaný odkaz</translation>
<translation id="5045550434625856497">Nesprávné heslo</translation>
<translation id="5056549851600133418">Články pro vás</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Zkontrolovat adresu proxy serveru<ph name="END_LINK" /></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="5097099694988056070">Statistiky zařízení, například využití CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Vaše zařízení spravuje doména <ph name="ENROLLMENT_DOMAIN" /> a váš účet doména <ph name="ACCOUNT_DOMAIN" />. To znamená, že administrátoři vaše zařízení a účet mohou vzdáleně nakonfigurovat.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64bitový)</translation>
-<translation id="5128122789703661928">Relace s tímto názvem není pro smazání platná.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Spravovat adresy...</translation>
+<translation id="5138227688689900538">Zobrazit méně</translation>
<translation id="5141240743006678641">Šifrovat synchronizovaná hesla pomocí hesla k účtu Google</translation>
<translation id="5145883236150621069">Odpověď zásady obsahuje kód chyby</translation>
+<translation id="515292512908731282">C4 (obálka)</translation>
<translation id="5159010409087891077">Otevřete stránku v novém anonymním okně (⇧⌘N)</translation>
<translation id="516920405563544094">Zadejte kód CVC karty <ph name="CREDIT_CARD" />. Po potvrzení budou údaje o kartě z vašeho účtu Google poskytnuty tomuto webu.</translation>
<translation id="5169827969064885044">Mohli byste ztratit přístup k účtu organizace nebo by mohlo dojít k odcizení vaší identity. Chrome doporučuje okamžitě změnit heslo.</translation>
<translation id="5171045022955879922">Vyhledávejte či zadejte URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Počítač</translation>
<translation id="5179510805599951267">Nejedná se o jazyk <ph name="ORIGINAL_LANGUAGE" />? Nahlaste tuto chybu.</translation>
<translation id="5190835502935405962">Lišta záložek</translation>
-<translation id="5200263511887412697">hlásit seznam uživatelů zařízení, kteří se nedávno přihlásili.</translation>
+<translation id="519422657042045905">Poznámky nejsou k dispozici</translation>
<translation id="5201306358585911203">Stránka vložená na této stránce říká</translation>
<translation id="5205222826937269299">Je nutné zadat jméno</translation>
<translation id="5215116848420601511">Platební metody a adresy pomocí služby Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Je nutné zadat e-mail</translation>
<translation id="5230733896359313003">Dodací adresa</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">Připojit k síti</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (obálka)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Síťové adresy</translation>
<translation id="5285570108065881030">Zobrazit všechna uložená hesla</translation>
<translation id="5287240709317226393">Zobrazit soubory cookie</translation>
<translation id="5288108484102287882">Ověření hodnot zásad vygenerovalo upozornění</translation>
@@ -689,7 +779,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> z <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Vybrat kontaktní údaje</translation>
<translation id="5327248766486351172">Jméno</translation>
+<translation id="5329858041417644019">Prohlížeč není spravován</translation>
<translation id="5332219387342487447">Způsob dopravy</translation>
+<translation id="5334013548165032829">Podrobné systémové protokoly</translation>
<translation id="5344579389779391559">Tato stránka se vám může pokusit naúčtovat poplatky</translation>
<translation id="5355557959165512791">Web <ph name="SITE" /> teď 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>
@@ -697,6 +789,7 @@
<translation id="5377026284221673050">Vaše hodiny se zpožďují, Vaše hodiny jdou napřed nebo &lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;</translation>
<translation id="5384855140246857529">Chcete-li své karty používat na všech zařízeních, přihlaste se a zapněte synchronizaci.</translation>
<translation id="5386426401304769735">Řetězec certifikátů tohoto webu obsahuje certifikát podepsaný algoritmem SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -707,6 +800,7 @@
<translation id="5457113250005438886">Neplatné</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Opakovat úpravy</translation>
+<translation id="5478437291406423475">B6/C4 (obálka)</translation>
<translation id="5481076368049295676">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="54817484435770891">Přidejte platnou adresu</translation>
<translation id="5490432419156082418">Adresy a další</translation>
@@ -714,10 +808,12 @@
<ph name="LINE_BREAK" />
Kontaktujte administrátora systému.</translation>
<translation id="549333378215107354">Velikost 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Spravované záložky</translation>
<translation id="5510766032865166053">Soubor mohl být přesunut nebo smazán.</translation>
<translation id="5523118979700054094">Název zásady</translation>
<translation id="552553974213252141">Byl text extrahován správně?</translation>
+<translation id="553484882784876924">Prc6 (obálka)</translation>
<translation id="5540224163453853">Požadovaný článek nebyl nalezen.</translation>
<translation id="5541546772353173584">Přidání e-mailu</translation>
<translation id="5545756402275714221">Články pro vás</translation>
@@ -732,15 +828,21 @@ Kontaktujte administrátora systému.</translation>
<translation id="5595485650161345191">Upravit adresu</translation>
<translation id="5598944008576757369">Vybrat platební metodu</translation>
<translation id="560412284261940334">Správa není podporována</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Web <ph name="HOST_NAME" /> vás přesměroval příliš mnohokrát.</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="5632627355679805402">Vaše údaje byly zašifrovány pomocí <ph name="BEGIN_LINK" />hesla účtu Google<ph name="END_LINK" /> ze dne <ph name="TIME" />. Chcete-li spustit synchronizaci, zadejte jej.</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="563324245173044180">Byl zablokován klamavý obsah.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (obálka)</translation>
+<translation id="5663955426505430495">Administrátor tohoto zařízení nainstaloval rozšíření pro dodatečné funkce. Rozšíření mají přístup k některým vašim datům.</translation>
<translation id="5675650730144413517">Tato stránka nefunguje</translation>
+<translation id="5684874026226664614">Jejda. Tuto stránku se nepodařilo přeložit.</translation>
<translation id="5685654322157854305">Přidat dodací adresu</translation>
<translation id="5689199277474810259">Exportovat do formátu JSON</translation>
<translation id="5689516760719285838">Poloha</translation>
@@ -749,38 +851,39 @@ Kontaktujte administrátora systému.</translation>
<translation id="5710435578057952990">Identita těchto webových stránek nebyla ověřena.</translation>
<translation id="5719499550583120431">Obchodník přijímá předplacené karty.</translation>
<translation id="5720705177508910913">Aktuální uživatel</translation>
+<translation id="5728056243719941842">C5 (obálka)</translation>
<translation id="5730040223043577876">Pokud jste heslo použili na jiném webu, doporučujeme vám ho resetovat.</translation>
<translation id="5732392974455271431">Rodiče ti jej mohou odblokovat.</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Uložit kartu do účtu Google}few{Uložit karty do účtu Google}many{Uložit karty do účtu Google}other{Uložit karty do účtu Google}}</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="5770114862687765385">Soubor se zdá být poškozený. Relaci resetujete kliknutím na tlačítko Resetovat.</translation>
<translation id="5778550464785688721">Úplná kontrola zařízení MIDI</translation>
<translation id="578305955206182703">Žlutohnědá</translation>
<translation id="57838592816432529">Ztlumit</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>
+<translation id="5798290721819630480">Zahodit změny?</translation>
<translation id="5798683403665926540">Domovskou stránku změníte v nastavení Chromu</translation>
<translation id="5803412860119678065">Chcete vyplnit informace o kartě <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Oprávnění</translation>
<translation id="5810442152076338065">Vaše připojení k doméně <ph name="DOMAIN" /> je šifrováno za použití zastaralé šifrovací sady.</translation>
<translation id="5813119285467412249">&amp;Opakovat přidání</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="5860033963881614850">Vypnuto</translation>
<translation id="5863847714970149516">Následující stránka se vám může pokusit naúčtovat poplatky</translation>
<translation id="5866257070973731571">Přidání telefonního čísla</translation>
<translation id="5869405914158311789">Tento web není dostupný</translation>
<translation id="5869522115854928033">Uložená hesla</translation>
<translation id="5887400589839399685">Karta byla uložena</translation>
-<translation id="5893718151540690985">hlásit seznam síťových rozhraní s informacemi o typu a hardwarových adresách</translation>
<translation id="5893752035575986141">Obchodník přijímá kreditní karty.</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="5916664084637901428">Zapnuto</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Uložit kartu do účtu Google?</translation>
<translation id="5922853866070715753">Téměř dokončeno</translation>
<translation id="5932224571077948991">Web zobrazuje rušivé nebo zavádějící reklamy</translation>
-<translation id="5939518447894949180">Resetovat</translation>
<translation id="5946937721014915347">Otevírání webu <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Pomocí běžného uživatelského účtu se nelze zaregistrovat (je k dispozici licence v balíčku).</translation>
<translation id="5967592137238574583">Úprava kontaktních údajů</translation>
@@ -788,6 +891,7 @@ Kontaktujte administrátora systému.</translation>
<translation id="5975083100439434680">Oddálit</translation>
<translation id="5977489021191000276">Vaše zařízení není spravováno administrátorem.</translation>
<translation id="5977976211062815271">V tomto zařízení</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Platební aplikaci nelze otevřít</translation>
<translation id="5989320800837274978">Nejsou určeny pevně dané servery proxy ani adresa URL skriptu PAC.</translation>
<translation id="5990559369517809815">Žádosti na tento server jsou blokovány rozšířením.</translation>
@@ -798,8 +902,8 @@ Kontaktujte administrátora systému.</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="6033927989869462158">hlásit statistiky hardwaru, například využití CPU/RAM</translation>
<translation id="6034000775414344507">Světle šedá</translation>
+<translation id="6034283069659657473">10x14 (obálka)</translation>
<translation id="6039846035001940113">Pokud problém přetrvává, kontaktujte vlastníka webu.</translation>
<translation id="6040143037577758943">Zavřít</translation>
<translation id="6044573915096792553">Velikost 12</translation>
@@ -808,10 +912,10 @@ Kontaktujte administrátora systému.</translation>
<translation id="6051221802930200923">Web <ph name="SITE" /> teď 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="6058977677006700226">Chcete své karty používat na všech svých zařízeních?</translation>
<translation id="6059925163896151826">Zařízení USB</translation>
-<translation id="6071091556643036997">Typ zásady je neplatný.</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="6094273045989040137">Přidat značky a poznámky</translation>
<translation id="610911394827799129">Na stránce <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> mohou být k dispozici další druhy historie prohlížení zaznamenané ve vašem účtu Google.</translation>
+<translation id="6132597952260690497">Informace o nainstalovaných rozšířeních a pluginech</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>
@@ -845,15 +949,21 @@ Kontaktujte administrátora systému.</translation>
<translation id="6337133576188860026">Uvolní méně než <ph name="SIZE" />. Je možné, že se některé weby při příští návštěvě budou načítat pomaleji.</translation>
<translation id="6337534724793800597">Filtrovat zásady podle názvu</translation>
<translation id="6358450015545214790">Nápověda</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Pozor na možné poplatky na webu, který se chystáte navštívit</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 další návrh}few{# další návrhy}many{# dalšího návrhu}other{# dalších návrhů}}</translation>
<translation id="6387754724289022810">Abyste příště mohli zaplatit rychleji, uložte si kartu a fakturační adresu do účtu Google a do tohoto zařízení.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Upravit záložku</translation>
+<translation id="6406765186087300643">C0 (obálka)</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="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="6434309073475700221">Zahodit</translation>
+<translation id="6446163441502663861">Kahu (obálka)</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>
@@ -866,11 +976,17 @@ Kontaktujte administrátora systému.</translation>
<translation id="6508722015517270189">Restartujte Chrome</translation>
<translation id="6529602333819889595">&amp;Opakovat smazání</translation>
<translation id="6534179046333460208">Návrhy fyzického webu</translation>
+<translation id="6556866813142980365">Opakovat</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="6578796323535178455">C2 (obálka)</translation>
<translation id="6579990219486187401">Světle růžová</translation>
+<translation id="6583674473685352014">B6 (obálka)</translation>
+<translation id="6587923378399804057">Zkopírovaný odkaz</translation>
+<translation id="6591833882275308647">Vaše zařízení <ph name="DEVICE_TYPE" /> není spravováno</translation>
<translation id="6596325263575161958">Možnosti šifrování</translation>
<translation id="6604181099783169992">Senzory pohybu nebo světla</translation>
+<translation id="6609880536175561541">Prc7 (obálka)</translation>
<translation id="6624427990725312378">Kontaktní údaje</translation>
<translation id="6626291197371920147">Přidání platného čísla karty</translation>
<translation id="6628463337424475685">Vyhledávání <ph name="ENGINE" /></translation>
@@ -879,6 +995,7 @@ Kontaktujte administrátora systému.</translation>
<translation id="6644283850729428850">Tato zásada se již nepoužívá.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Žádné}=1{Z 1 webu (nebudete odhlášeni z účtu Google)}few{Ze # webů (nebudete odhlášeni z účtu Google)}many{Z # webu (nebudete odhlášeni z účtu Google)}other{Z # webů (nebudete odhlášeni z účtu Google)}}</translation>
<translation id="6657585470893396449">Heslo</translation>
+<translation id="6670613747977017428">Zpět do bezpečí</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>
@@ -886,12 +1003,15 @@ Kontaktujte administrátora systému.</translation>
<translation id="671076103358959139">Registrační token:</translation>
<translation id="6711464428925977395">Došlo k chybě proxy serveru nebo jste zadali nesprávnou adresu.</translation>
<translation id="6723740634201835758">V účtu Google</translation>
+<translation id="6738516213925468394">Vaše data byla <ph name="TIME" /> zašifrována pomocí <ph name="BEGIN_LINK" />heslové fráze pro synchronizaci<ph name="END_LINK" />. Chcete-li zahájit synchronizaci, zadejte ji.</translation>
<translation id="674375294223700098">Neznámá chyba certifikátu serveru.</translation>
<translation id="6744009308914054259">Zatímco čekáte na připojení, v sekci Stažené soubory si můžete přečíst offline články.</translation>
<translation id="6753269504797312559">Hodnota zásady</translation>
<translation id="6757797048963528358">Zařízení přešlo do režimu spánku.</translation>
+<translation id="6768213884286397650">Hagaki (pohlednice)</translation>
<translation id="6778737459546443941">Rodič ti přístup na web dosud neschválil.</translation>
<translation id="67862343314499040">Fialová</translation>
+<translation id="6786747875388722282">Rozšíření</translation>
<translation id="679355240208270552">Ignorováno, protože v zásadách výchozí vyhledávání není aktivováno.</translation>
<translation id="681021252041861472">Povinné pole</translation>
<translation id="6810899417690483278">ID přizpůsobení</translation>
@@ -924,10 +1044,12 @@ Kontaktujte administrátora systému.</translation>
<translation id="6965978654500191972">Zařízení</translation>
<translation id="6970216967273061347">Okres</translation>
<translation id="6973656660372572881">Určeny jsou pevně dané servery proxy i adresa URL skriptu PAC.</translation>
+<translation id="6973932557599545801">Pardon, nedokážu vám pomoct. Je to na vás.</translation>
<translation id="6979158407327259162">Disk Google</translation>
<translation id="6979440798594660689">Ztlumit (výchozí)</translation>
<translation id="6984479912851154518">Chystáte se opustit soukromý režim, abyste mohli zaplatit v externí aplikaci. Chcete pokračovat?</translation>
<translation id="6989763994942163495">Zobrazit rozšířená nastavení...</translation>
+<translation id="6993898126790112050">6x9 (obálka)</translation>
<translation id="6996312675313362352">Jazyk <ph name="ORIGINAL_LANGUAGE" /> vždy překládat</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Může se jednat o jednorázové nebo opakované poplatky, které nemusejí být jasně patrné.</translation>
@@ -943,28 +1065,33 @@ Kontaktujte administrátora systému.</translation>
<translation id="7108338896283013870">Skrýt</translation>
<translation id="7108819624672055576">Povoleno rozšířením</translation>
<translation id="7111012039238467737">(platný)</translation>
+<translation id="7118618213916969306">Vyhledat adresu URL ve schránce, <ph name="SHORT_URL" /></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="7135130955892390533">Zobrazit stav</translation>
<translation id="7138472120740807366">Způsob doručení</translation>
<translation id="7139724024395191329">Emirát</translation>
+<translation id="7152423860607593928">Number-14 (obálka)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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ší}other{<ph name="PAYMENT_METHOD_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> dalších}}</translation>
<translation id="7153618581592392745">Levandulová</translation>
-<translation id="7158980942472052083">Neplatná adresa URL. Je třeba použít adresu URL se standardním schématem.</translation>
<translation id="717330890047184534">ID Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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ší}other{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> dalších}}</translation>
+<translation id="7177397715882417099">Server, na který přecházíte (<ph name="ORIGIN" />), požádal, aby se na všechny na něj odesílané požadavky vztahovaly bezpečnostní zásady. Server však namísto poskytnutí zásad přesměroval prohlížeč jinam. Prohlížeč proto váš požadavek na web <ph name="SITE" /> nemůže splnit.</translation>
<translation id="7179323680825933600">Ukládat a vyplňovat platební metody</translation>
<translation id="7180611975245234373">Obnovit</translation>
<translation id="7182878459783632708">Nebyly nastaveny žádné zásady</translation>
<translation id="7186367841673660872">Tato stránka byla přeložena z jazyka<ph name="ORIGINAL_LANGUAGE" />do jazyka<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Uvolní <ph name="SIZE" />. Je možné, že se některé weby při příští návštěvě budou načítat pomaleji.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administrátor má přístup k následujícím údajům:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Web <ph name="HOST_NAME" /> nevyhovuje bezpečnostním standardům.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /> o tomto problému.</translation>
<translation id="7219179957768738017">Připojení používá protokol <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Zpracovávání</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />, <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Webové stránky, které chcete otevřít, obsahují malware</translation>
+<translation id="724766306220616965">Upozornění, konflikt</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="7251437084390964440">Konfigurace sítě neodpovídá standardu ONC. Může se stát, že některé části konfigurace nebudou importovány. Další podrobnosti:
<ph name="DEBUG_INFO" /></translation>
@@ -976,11 +1103,14 @@ Kontaktujte administrátora systému.</translation>
<translation id="7300012071106347854">Sytě modrá</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />“</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="7313965965371928911">Upozornění <ph name="BEGIN_LINK" />Bezpečného prohlížení<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Pomoc s připojením</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Příkazový řádek</translation>
-<translation id="7365061714576910172">Exportovat ve formátu pro Linux</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>
@@ -988,6 +1118,7 @@ Kontaktujte administrátora systému.</translation>
<translation id="7381288752349550461">Přepsání spravované návštěvy</translation>
<translation id="7390545607259442187">Ověření karty</translation>
<translation id="7400418766976504921">Adresa URL</translation>
+<translation id="7403591733719184120">Vaše zařízení <ph name="DEVICE_NAME" /> je spravováno</translation>
<translation id="7407424307057130981">&lt;p&gt;Tato chyba se zobrazuje, pokud v počítači se systémem Windows máte software Superfish.&lt;/p&gt;
&lt;p&gt;Abyste se mohli dostat na web, podle těchto pokynů tento software dočasně zakažte. Budete potřebovat administrátorská práva.&lt;/p&gt;
&lt;ol&gt;
@@ -998,7 +1129,7 @@ Kontaktujte administrátora systému.</translation>
&lt;li&gt;Klikněte na &lt;strong&gt;Použít&lt;/strong&gt; a poté na &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Informace o tom, jak tento software trvale odstranit z počítače, naleznete v &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;centru nápovědy prohlížeče Chrome&lt;/a&gt;.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Správa prohlížeče <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Spravovat hesla…</translation>
<translation id="7419106976560586862">Cesta k profilu</translation>
<translation id="7437289804838430631">Přidat kontaktní údaje</translation>
@@ -1007,22 +1138,24 @@ Kontaktujte administrátora systému.</translation>
<translation id="7442725080345379071">Světle oranžová</translation>
<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="7449109375006139765">odesílat systémové protokoly na server správy</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="7460618730930299168">Přehrává se jiný obsah, než jste vybrali. Pokračovat?</translation>
<translation id="7473891865547856676">Ne, děkuji</translation>
-<translation id="7475525192983021547">hlásit časová období, kdy uživatel zařízení aktivně používá</translation>
<translation id="7481312909269577407">Vpřed</translation>
<translation id="7485870689360869515">Nebyla nalezena žádná data.</translation>
+<translation id="7498234416455752244">Pokračovat v úpravách</translation>
<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="7508870219247277067">Žlutozelená</translation>
<translation id="7511955381719512146">Síť Wi-Fi, kterou používáte, může vyžadovat, abyste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (obálka)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Připojení k tomuto webu není soukromé</translation>
+<translation id="7535087603100972091">Hodnota</translation>
<translation id="7537536606612762813">Povinná</translation>
+<translation id="7538364083937897561">A2 (obálka)</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>
@@ -1031,8 +1164,8 @@ Kontaktujte administrátora systému.</translation>
<translation id="7552846755917812628">Vyzkoušejte následující tipy:</translation>
<translation id="7554791636758816595">Nová karta</translation>
<translation id="7564049878696755256">Mohli byste ztratit přístup k účtu <ph name="ORG_NAME" /> nebo by mohlo dojít k odcizení vaší identity. Doporučujeme vám okamžitě změnit heslo.</translation>
-<translation id="7566125604157659769">Zkopírovaný text</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="7568105740864181217">Tento prohlížeč spravuje společnost, škola nebo jiná organizace. Administrátor může nastavení prohlížeče vzdáleně změnit. Aktivita na tomto zařízení může být spravována také mimo Chrome. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></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>
@@ -1043,6 +1176,7 @@ Kontaktujte administrátora systému.</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="7633909222644580952">Údaje o výkonu a přehledy selhání</translation>
<translation id="7637571805876720304">Odstranit platební kartu z prohlížeče Chromium?</translation>
<translation id="7639968568612851608">Tmavě šedá</translation>
<translation id="765676359832457558">Skrýt rozšířená nastavení...</translation>
@@ -1052,9 +1186,11 @@ Kontaktujte administrátora systému.</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="7676643023259824263">Vyhledat text ve schránce (<ph name="TEXT" />)</translation>
<translation id="7681101578153515023">Změnit vyhledávač</translation>
<translation id="7682287625158474539">Doprava</translation>
<translation id="7687186412095877299">Vyplní platební formuláře údaji pro uložené platební metody</translation>
+<translation id="7697066736081121494">Prc8 (obálka)</translation>
<translation id="769721561045429135">V současné době máte karty, které lze používat jen na tomto zařízení. Chcete-li karty zkontrolovat, klikněte na Pokračovat.</translation>
<translation id="7699293099605015246">Články momentálně nejsou dostupné</translation>
<translation id="7701040980221191251">Žádné</translation>
@@ -1066,11 +1202,13 @@ Kontaktujte administrátora systému.</translation>
<translation id="774634243536837715">Byl zablokován nebezpečný obsah.</translation>
<translation id="7752995774971033316">Nespravováno</translation>
<translation id="7755287808199759310">Rodič ti jej může odblokovat.</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Připojení mohlo být zablokováno firewallem nebo antivirovým softwarem.</translation>
<translation id="7759163816903619567">Zobrazovaná doména:</translation>
<translation id="7761701407923456692">Certifikát serveru neodpovídá adrese URL.</translation>
<translation id="7763386264682878361">Analyzátor manifestů plateb</translation>
<translation id="7764225426217299476">Přidat adresu</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Přidat</translation>
<translation id="7793809570500803535">Webové stránky na adrese <ph name="SITE" /> jsou možná dočasně nedostupné nebo mohly být přemístěny na novou webovou adresu.</translation>
@@ -1082,8 +1220,8 @@ Kontaktujte administrátora systému.</translation>
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Odstranit návrh položky formuláře z Chromu?</translation>
<translation id="7815407501681723534">Nalezené <ph name="SEARCH_RESULTS" /> pro dotaz „<ph name="SEARCH_STRING" />“: <ph name="NUMBER_OF_RESULTS" /></translation>
-<translation id="7818867226424560206">Správa zásad</translation>
<translation id="782886543891417279">Síť Wi-Fi, kterou používáte (<ph name="WIFI_NAME" />), může vyžadovat, abyste navštívili její stránku přihlášení.</translation>
+<translation id="7836231406687464395">Postfix (obálka)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Žádné}=1{1 aplikace (<ph name="EXAMPLE_APP_1" />)}=2{2 aplikace (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}few{# aplikace (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}many{# aplikace (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# aplikací (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">To neznamená, že jste neviditelní. Anonymní režim neskryje vaši aktivitu před vaším zaměstnavatelem, poskytovatelem internetových služeb ani webovými stránkami, které navštívíte.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1092,7 +1230,7 @@ Kontaktujte administrátora systému.</translation>
<translation id="7878562273885520351">Heslo může být prolomeno</translation>
<translation id="7882421473871500483">Hnědá</translation>
<translation id="7887683347370398519">Zkontrolujte kód CVC a zkuste to znovu</translation>
-<translation id="7893255318348328562">Název návštěvy</translation>
+<translation id="7904208859782148177">C3 (obálka)</translation>
<translation id="79338296614623784">Zadejte platné telefonní číslo</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Platnost vyprší <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1102,21 +1240,25 @@ Kontaktujte administrátora systému.</translation>
<translation id="7951415247503192394">(32bitový)</translation>
<translation id="7956713633345437162">Mobilní záložky</translation>
<translation id="7961015016161918242">Nikdy</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Prohlížeč</translation>
<translation id="8009225694047762179">Spravovat hesla</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Tato karta a její fakturační adresa se uloží. Budete ji moci používat, když budete přihlášeni k účtu <ph name="USER_EMAIL" />.}few{Tyto karty a jejich fakturační adresy se uloží. Budete je moci používat, když budete přihlášeni k účtu <ph name="USER_EMAIL" />.}many{Tyto karty a jejich fakturační adresy se uloží. Budete je moci používat, když budete přihlášeni k účtu <ph name="USER_EMAIL" />.}other{Tyto karty a jejich fakturační adresy se uloží. Budete je moci používat, když budete přihlášeni k účtu <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Stránka je v jazyce <ph name="SOURCE_LANGUAGE" />. Chcete ji přeložit do jazyka <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pero</translation>
+<translation id="8037117624646282037">Kdo toto zařízení v poslední době používal</translation>
<translation id="8037357227543935929">Zeptat se (výchozí)</translation>
<translation id="803771048473350947">Soubor</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="8042918947222776840">Vybrat způsob vyzvednutí</translation>
<translation id="8057711352706143257">Software <ph name="SOFTWARE_NAME" /> není nakonfigurován správně. Tento problém lze obvykle vyřešit odinstalováním softwaru <ph name="SOFTWARE_NAME" />. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Ve vašem zařízení byly nastaveny tyto zásady:</translation>
+<translation id="8066955247577885446">Lituji, něco se pokazilo.</translation>
+<translation id="8074253406171541171">10x13 (obálka)</translation>
<translation id="8078141288243656252">Když je dokument otočený, nelze do něj přidávat značky a poznámky</translation>
<translation id="8079031581361219619">Načíst web znovu?</translation>
<translation id="8088680233425245692">Zobrazení článku se nezdařilo.</translation>
@@ -1125,11 +1267,12 @@ Kontaktujte administrátora systému.</translation>
<translation id="8091372947890762290">Čeká se na aktivaci na serveru</translation>
<translation id="8092774999298748321">Tmavě nachová</translation>
<translation id="8094917007353911263">Síť, kterou používáte, může vyžadovat, abyste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Neplatné karty byly odstraněny</translation>
<translation id="8103161714697287722">Platební metoda</translation>
<translation id="8118489163946903409">Platební metoda</translation>
+<translation id="8123836779274890062">Zařízení <ph name="DEVICE_TYPE" /> spravované doménou <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Software <ph name="SOFTWARE_NAME" /> na počítači nebo v síti nebyl nainstalován správně. Požádejte administrátora IT o vyřešení tohoto problému.</translation>
-<translation id="8130693978878176684">Dále vám pomoci nemůžu, pokračujte sami.</translation>
<translation id="8131740175452115882">Potvrdit</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>
@@ -1139,8 +1282,11 @@ Kontaktujte administrátora systému.</translation>
<translation id="8197543752516192074">Přeložit stránku</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (obálka)</translation>
<translation id="8211406090763984747">Připojení je zabezpečené</translation>
<translation id="8218327578424803826">Přiřazené místo:</translation>
+<translation id="8220146938470311105">C7/C6 (obálka)</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="8238581221633243064">Otevřete stránku na nové anonymní kartě</translation>
@@ -1152,14 +1298,16 @@ Kontaktujte administrátora systému.</translation>
<translation id="825929999321470778">Zobrazit všechna uložená hesla</translation>
<translation id="8261506727792406068">Smazat</translation>
<translation id="8267698848189296333">Přihlašování pomocí účtu <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Tento prohlížeč je spravován organizací <ph name="ENROLLMENT_DOMAIN" />. Administrátor může nastavení prohlížeče vzdáleně změnit. Aktivita na tomto zařízení může být spravována také mimo Chrome. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Přihlásit se</translation>
<translation id="8288807391153049143">Zobrazit certifikát</translation>
<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="8298115750975731693">Síť Wi-Fi, kterou používáte (<ph name="WIFI_NAME" />), může vyžadovat, abyste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Překlad se nezdařil kvůli problému s připojením k síti.</translation>
-<translation id="8311129316111205805">Načíst relaci</translation>
<translation id="8332188693563227489">Přístup k webu <ph name="HOST_NAME" /> byl odepřen</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1177,7 +1325,6 @@ Kontaktujte administrátora systému.</translation>
<translation id="8416694386774425977">Konfigurace sítě je neplatná a nelze ji importovat.
Další podrobnosti:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Zařízení spravuje organizace <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Změnit</translation>
<translation id="8428213095426709021">Nastavení</translation>
@@ -1205,9 +1352,11 @@ Další podrobnosti:
<translation id="860043288473659153">Jméno držitele karty</translation>
<translation id="861775596732816396">Velikost 4</translation>
<translation id="8620436878122366504">Rodiče přístup dosud neschválili.</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Uložit tuto kartu do zařízení</translation>
<translation id="8663226718884576429">Shrnutí objednávky, <ph name="TOTAL_LABEL" />, další podrobnosti</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, odpověď, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Vaše spojení se serverem <ph name="DOMAIN" /> není šifrované.</translation>
<translation id="8718314106902482036">Platba nebyla dokončena</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, návrh vyhledávacího dotazu</translation>
@@ -1221,6 +1370,7 @@ Další podrobnosti:
<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="8763927697961133303">Zařízení USB</translation>
<translation id="8768895707659403558">Chcete-li své karty používat na všech zařízeních, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Opakovat smazání</translation>
<translation id="8792621596287649091">Mohli byste ztratit přístup k účtu <ph name="ORG_NAME" /> nebo by mohlo dojít k odcizení vaší identity. Doporučujeme vám okamžitě změnit heslo.</translation>
<translation id="8800988563907321413">Zde se zobrazí návrhy funkce Nablízku</translation>
@@ -1231,10 +1381,12 @@ Další podrobnosti:
<translation id="885730110891505394">Sdílení s Googlem</translation>
<translation id="8858065207712248076">Pokud jste heslo organizace <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> použili na jiném webu, doporučujeme vám ho resetovat.</translation>
<translation id="8866481888320382733">Při analýze nastavení zásady došlo k chybě</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nedávno zavřené</translation>
<translation id="8874824191258364635">Zadejte platné číslo karty</translation>
<translation id="8891727572606052622">Neplatný režim proxy serveru.</translation>
<translation id="8903921497873541725">Přiblížit</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Přidání jména</translation>
@@ -1242,13 +1394,13 @@ Další podrobnosti:
<translation id="894185898663964645">Váš administrátor nakonfiguroval vlastní kořenové certifikáty, které mu mohou umožnit zobrazit obsah webů, jež navštěvujete.</translation>
<translation id="8943282376843390568">Limetková</translation>
<translation id="8957210676456822347">Autorizace captive portálu</translation>
+<translation id="8966619695390250636">Měli jste na mysli:</translation>
<translation id="8968766641738584599">Uložit kartu</translation>
<translation id="8971063699422889582">Platnost certifikátu serveru vypršela.</translation>
<translation id="8975012916872825179">Zahrnuje informace jako telefonní čísla, e-mailové adresy a dodací adresy</translation>
<translation id="8978053250194585037">Služba Bezpečné prohlížení Google nedávno na webu <ph name="SITE" /> <ph name="BEGIN_LINK" />zjistila phishing<ph name="END_LINK" />. Phishingové weby se vás snaží oklamat tím, že se vydávají za jiné weby.</translation>
<translation id="8983003182662520383">Platební metody a adresy pomocí služby Google Pay</translation>
<translation id="8987927404178983737">Měsíc</translation>
-<translation id="8988408250700415532">Něco se pokazilo. Objednávku můžete dokončit na webu.</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>
@@ -1258,6 +1410,7 @@ Další podrobnosti:
<translation id="9011424611726486705">Otevřít nastavení webu</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(neplatný)</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>
@@ -1269,11 +1422,11 @@ Další podrobnosti:
<translation id="9065745800631924235">vyhledávání <ph name="TEXT" /> z historie</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="9076630408993835509">Tento prohlížeč není spravován administrátorem ani jinou organizací. Aktivita na tomto zařízení může být spravována mimo Chrome. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Jsou potřeba další informace</translation>
<translation id="9080712759204168376">Přehled objednávky</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>
<translation id="9106062320799175032">Přidání fakturační adresy</translation>
-<translation id="9110718169272311511">Asistent Google v Chromu je k dispozici v dolní části obrazovky</translation>
<translation id="9114524666733003316">Ověřování karty...</translation>
<translation id="9128870381267983090">Připojit k síti</translation>
<translation id="9137013805542155359">Zobrazit originál</translation>
@@ -1282,6 +1435,7 @@ Další podrobnosti:
<translation id="9148507642005240123">&amp;Vrátit úpravy zpět</translation>
<translation id="9154194610265714752">Aktualizováno</translation>
<translation id="9157595877708044936">Nastavování...</translation>
+<translation id="9158625974267017556">C6 (obálka)</translation>
<translation id="9168814207360376865">Povolit webům zjišťovat, zda máte uložené platební metody</translation>
<translation id="9169664750068251925">Blokovat vždy na tomto webu</translation>
<translation id="9170848237812810038">Z&amp;pět</translation>
@@ -1296,10 +1450,12 @@ Další podrobnosti:
<translation id="9219103736887031265">Obrázky</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">VYMAZAT FORMULÁŘ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Mohli byste ztratit přístup k účtu Google. Chromium doporučuje okamžitě změnit heslo. Budete vyzváni k přihlášení.</translation>
<translation id="939736085109172342">Nová složka</translation>
<translation id="945855313015696284">Zkontrolujte níže uvedené informace a vymažte neplatné karty</translation>
<translation id="951104842009476243">Přijímané debetní a předplacené karty</translation>
+<translation id="958202389743790697">Zablokováno na základě bezpečnostních zásad webu <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Tento obsah by se mohl pokusit instalovat klamavé aplikace, které se vydávají za něco jiného nebo shromažďují data ke sledování vaší aktivity. <ph name="BEGIN_LINK" />Přesto zobrazit<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Oficiální sestavení</translation>
<translation id="973773823069644502">Přidat adresu doručení</translation>
@@ -1308,6 +1464,7 @@ Další podrobnosti:
<translation id="984275831282074731">Platební metody</translation>
<translation id="985199708454569384">&lt;p&gt;Tato chyba se zobrazuje, pokud máte v počítači nebo mobilním zařízení nastaveno nepřesné datum a čas.&lt;/p&gt;
&lt;p&gt;Chcete-li tuto chybu odstranit, otevřete v zařízení hodiny. Zkontrolujte, zda jsou datum a čas nastaveny správně.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Vývojářské sestavení</translation>
<translation id="989988560359834682">Upravit adresu</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_da.xtb b/chromium/components/strings/components_strings_da.xtb
index c51d0bdd4a0..00afb73f04a 100644
--- a/chromium/components/strings/components_strings_da.xtb
+++ b/chromium/components/strings/components_strings_da.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="da">
-<translation id="1005145902654145231">Sessionen kunne ikke omdøbes.</translation>
<translation id="1008557486741366299">Ikke nu</translation>
<translation id="1010200102790553230">Indlæs side senere</translation>
<translation id="1015730422737071372">Angiv yderligere oplysninger</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">ukendt navn</translation>
<translation id="1050038467049342496">Luk andre apps</translation>
<translation id="1055184225775184556">&amp;Fortryd tilføjelse</translation>
+<translation id="1056898198331236512">Advarsel</translation>
<translation id="1058479211578257048">Gemmer kort...</translation>
<translation id="10614374240317010">Gemmes aldrig</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Bogmærker på pc</translation>
<translation id="1074497978438210769">Ikke sikker</translation>
<translation id="1080116354587839789">Tilpas til bredden</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Tilføj navn på kort</translation>
<translation id="1089439967362294234">Skift adgangskode</translation>
<translation id="109743633954054152">Administrer adgangskoder i indstillingerne for Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Advarsler kan almindeligt forekomme, når websites opdaterer deres sikkerhed. Dette forbedres snart.</translation>
<translation id="1126551341858583091">Størrelsen på den lokale lagerplads er <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache for politik er OK</translation>
+<translation id="1131264053432022307">Billede, du har kopieret</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Omdøb</translation>
<translation id="1175364870820465910">&amp;Udskriv...</translation>
<translation id="1181037720776840403">Fjern</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Navnet på din enhed</translation>
<translation id="124116460088058876">Flere sprog</translation>
<translation id="1250759482327835220">Gem dit kort, dit navn og din faktureringsadresse på din Google-konto for at betale hurtigere næste gang.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkroniseret)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variationer i kommandolinjer</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="1314614906530272393">Den valgte session findes ikke.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Søg efter billede i udklipsholderen</translation>
<translation id="1323433172918577554">Se flere</translation>
<translation id="132390688737681464">Gem og udfyld adresser</translation>
<translation id="1333989956347591814">Din aktivitet <ph name="BEGIN_EMPHASIS" />er muligvis stadig synlig<ph name="END_EMPHASIS" /> for:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Afhentningsadresse</translation>
<translation id="1348198688976932919">Det website, du er på vej til, indeholder farlige apps</translation>
<translation id="1348779747280417563">Bekræft navn</translation>
+<translation id="1357195169723583938">Hvem der senest har brugt enheden og hvornår</translation>
+<translation id="1364822246244961190">Denne politik er blokeret, og dens værdi ignoreres.</translation>
<translation id="1374468813861204354">forslag</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Om version</translation>
<translation id="1376836354785490390">Se færre</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="138218114945450791">Lyseblå</translation>
+<translation id="1382194467192730611">USB-enheden er tilladt af din administrator</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> har ikke sendt nogen data.</translation>
+<translation id="140316286225361634">Websitet <ph name="ORIGIN" /> har anmodet om, at der skal gælde en
+ sikkerhedspolitik for alle dets anmodninger, og denne politik vurderer, at websitet er
+ usikkert.</translation>
<translation id="1405567553485452995">Lysegrøn</translation>
<translation id="1407135791313364759">Åbn alle</translation>
<translation id="1413809658975081374">Fejl i forbindelse med beskyttelse af personlige oplysninger</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Udskriv</translation>
<translation id="1455413310270022028">Viskelæder</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Vis mere</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Vælg leveringsadresse</translation>
+<translation id="1492194039220927094">Underretning om politikker:</translation>
<translation id="1501859676467574491">Vis kort fra din Google-konto</translation>
-<translation id="1506687042165942984">Vis en gemt (dvs. forældet) kopi af denne side.</translation>
<translation id="1507202001669085618">&lt;p&gt;Denne fejl vises, hvis du bruger en Wi-Fi-portal, hvor du skal logge ind, før du kan komme på nettet.&lt;/p&gt;
&lt;p&gt;Du kan rette fejlen ved at klikke på &lt;strong&gt;Opret forbindelse&lt;/strong&gt; på den side, du forsøger at åbne.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonnummer er påkrævet</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Versionsdato</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">Venter på forbindelse…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Denne side siger</translation>
<translation id="153384715582417236">Det var det hele indtil videre</translation>
<translation id="154408704832528245">Vælg leveringsadresse</translation>
<translation id="1549470594296187301">JavaScript skal være aktiveret, før du kan bruge denne funktion.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Angiv udløbsdato</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Billede, du har kopieret</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Undgå, at denne side opretter yderligere dialogbokse</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Afslut session</translation>
<translation id="1639239467298939599">Indlæser...</translation>
<translation id="1640180200866533862">Brugerpolitikker</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Servercertifikatet indeholder en svag kryptografisk nøgle.</translation>
<translation id="1697532407822776718">Fuldført</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokumenterne er for store til at blive annoteret</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Prøv at kontakte systemadministratoren.</translation>
<translation id="1740951997222943430">Angiv en gyldig udløbsmåned</translation>
<translation id="1743520634839655729">Gem dit kort, dit navn og din faktureringsadresse på din Google-konto og denne enhed for at betale hurtigere næste gang.</translation>
+<translation id="1745880797583122200">Din browser administreres</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Opdater din adgangssætning til synkronisering.</translation>
<translation id="1787142507584202372">Dine åbne faner vises her</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kortindehaverens navn</translation>
<translation id="1821930232296380041">Ugyldig anmodning eller anmodningsparametre</translation>
+<translation id="1822540298136254167">Hvilke websites du besøger, og hvor lang tid du bruger på dem</translation>
<translation id="1826516787628120939">Kontrollerer</translation>
<translation id="1834321415901700177">Dette website indeholder skadelige programmer</translation>
<translation id="1839551713262164453">Validering af politikværdier mislykkedes med fejl</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Ryd data fra Chromes browserhistorik</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{og 1 mere}one{og # mere}other{og # mere}}</translation>
<translation id="2003709556000175978">Nulstil din adgangskode nu</translation>
+<translation id="20053308747750172">Den server, du er på vej til, <ph name="ORIGIN" />, har anmodet om, at
+ der anvendes en sikkerhedspolitik for alle anmodninger, der sendes til den. Den har dog nu
+ leveret en ugyldig politik, som forhindrer browseren i at
+ opfylde din anmodning for <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxyen konfigureres automatisk.</translation>
<translation id="2030481566774242610">Mente du <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Kontrollere din proxy og din firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Afdeling</translation>
<translation id="2102134110707549001">Foreslå stærk adgangskode…</translation>
<translation id="2108755909498034140">Genstart computeren</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kort</translation>
<translation id="2114841414352855701">Ignoreret, da den blev tilsidesat af <ph name="POLICY_NAME" /> .</translation>
<translation id="213826338245044447">Bogmærker på mobil</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Politikker</translation>
<translation id="2183608646556468874">Telefonnummer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}one{# adresse}other{# adresser}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2283340219607151381">Gem og udfyld adresser</translation>
<translation id="2292556288342944218">Din internetadgang er blokeret</translation>
+<translation id="2294558542833290837">Det link, du oprindeligt åbnede, er usædvanligt</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Frigiver over 1 MB. Nogle websites indlæses muligvis langsommere under dit næste besøg.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> kræver et brugernavn og en adgangskode.</translation>
<translation id="2317583587496011522">Debetkort accepteres.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, udløber <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Indstillingen styres af din administrator</translation>
+<translation id="2346319942568447007">Billede, du har kopieret</translation>
<translation id="2349790679044093737">VR-sessionen er aktiv</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Nedbrudsrapporten, der blev registreret <ph name="CRASH_TIME" />, blev ikke uploadet</translation>
<translation id="2367567093518048410">Niveau</translation>
<translation id="2378238891085281592">Du er nu i privat tilstand</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Den server, du er på vej til, <ph name="ORIGIN" />, har anmodet om, at
+ der anvendes en sikkerhedspolitik for alle anmodninger, der sendes til den. Det er dog nu
+ mislykkedes at levere en politik, hvilket forhindrer browseren i at opfylde
+ din anmodning til <ph name="SITE" />.</translation>
<translation id="244665789865330679">Din enhed og konto administreres af <ph name="ENROLLMENT_DOMAIN" />. Dette betyder, at din administrator kan konfigurere din enhed og konto via fjernadgang.</translation>
<translation id="2463193859425327265">Skift startside</translation>
<translation id="2463739503403862330">Udfyld</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Vælg leveringsmetode</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Køre Netværksdiagnosticering<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Oversæt denne side</translation>
<translation id="2479410451996844060">Ugyldig søgewebadresse.</translation>
<translation id="2482878487686419369">Notifikationer</translation>
<translation id="248348093745724435">Maskinpolitikker</translation>
+<translation id="2485387744899240041">Brugernavne for din enhed og browser</translation>
<translation id="2491120439723279231">Serverens certifikat indeholder fejl.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Scan et nyt kort</translation>
<translation id="2501278716633472235">Gå tilbage</translation>
<translation id="2503184589641749290">Accepterede debetkort og forudbetalte kort</translation>
<translation id="2515629240566999685">Tjekke signalet i dit område</translation>
-<translation id="2516852381693169964">Søg efter billedet på <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Gemmes kun på denne enhed</translation>
<translation id="2524461107774643265">Tilføj flere oplysninger</translation>
<translation id="2536110899380797252">Tilføj adresse</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Id for Directory API:</translation>
<translation id="2597378329261239068">Dette dokument er adgangskodebeskyttet. Angiv en adgangskode.</translation>
<translation id="2609632851001447353">Varianter</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">Dit ur er foran</translation>
<translation id="2634124572758952069">IP-adressen på serveren for <ph name="HOST_NAME" /> kunne ikke findes.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Luk andre faner eller apps</translation>
<translation id="267371737713284912">tryk på <ph name="MODIFIER_KEY_DESCRIPTION" /> for at fortryde</translation>
<translation id="2674170444375937751">Er du sikker på, at du vil slette disse sider fra din historik?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Forlad</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Accepterede kort</translation>
<translation id="2702801445560668637">Læseliste</translation>
<translation id="2704283930420550640">Værdien stemmer ikke overens med formatet.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Fjern valgte elementer</translation>
<translation id="277133753123645258">Forsendelsesmetode</translation>
<translation id="277499241957683684">Manglende enhedsregistrering</translation>
-<translation id="2781030394888168909">Eksportér MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Forbindelsen blev nulstillet.</translation>
<translation id="2788784517760473862">Accepterede kreditkort</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Åbn inkognitovindue</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Du skal have tilladelse til at besøge dette website</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Vil du gemme kortet?</translation>
<translation id="2903493209154104877">Adresser</translation>
<translation id="290376772003165898">Er siden ikke på <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Leveringsmetode</translation>
<translation id="2928905813689894207">Faktureringsadresse</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<translation id="3008447029300691911">Angiv 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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Forkert politiktype</translation>
<translation id="3037605927509011580">Øv, surt!</translation>
<translation id="3041612393474885105">Certifikatoplysninger</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Erklæring</translation>
<translation id="3096100844101284527">Tilføj afhentningsadresse</translation>
<translation id="3105172416063519923">Aktiv-id:</translation>
<translation id="3109728660330352905">Du har ikke tilladelse til at se denne side.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> på <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Annuller betaling</translation>
<translation id="3207960819495026254">Gemt som bogmærke</translation>
-<translation id="3209375525920864198">Angiv et gyldigt sessionsnavn.</translation>
+<translation id="321912867715453276">Advarsel! Der er mere end én kilde for politikken, men værdierne er de samme.</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="3229041911291329567">Versionsoplysninger om din enhed og browser</translation>
<translation id="323107829343500871">Angiv 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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Tilføj navn på kort</translation>
<translation id="3287510313208355388">Download, når du er online</translation>
<translation id="3293642807462928945">Få flere oplysninger om politikken <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Der blev ikke fundet nogen søgeresultater</translation>
-<translation id="3305707030755673451">Dine data blev krypteret med din adgangssætning til synkronisering d. <ph name="TIME" />. Angiv adgangssætningen for at starte synkroniseringen.</translation>
<translation id="3320021301628644560">Tilføj faktureringsadresse</translation>
<translation id="3324983252691184275">Højrød</translation>
<translation id="3338095232262050444">Sikker</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Annuller fortryd redigering</translation>
<translation id="342781501876943858">Chromium anbefaler, at du nulstiller din adgangskode, hvis du har brugt den på andre websites.</translation>
<translation id="3431636764301398940">Gem dette kort på denne enhed</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Ejeren af denne enhed har lukket dinosaurspillet.</translation>
<translation id="3447884698081792621">Vis certifikat (udstedt af <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Hent interval:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Overstregningstusch</translation>
<translation id="3462200631372590220">Skjul avanceret</translation>
<translation id="3467763166455606212">Kortindehavers navn skal angives</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kreditkort og forudbetalte kort accepteres.</translation>
<translation id="3582930987043644930">Tilføj navn</translation>
<translation id="3583757800736429874">&amp;Annuller fortryd flytning</translation>
+<translation id="35866233670761917">Indholdet på de websites, du besøger, er ikke set af dine administratorer</translation>
<translation id="3586931643579894722">Skjul oplysninger</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Størrelse 2</translation>
<translation id="3615877443314183785">Angiv en gyldig udløbsdato</translation>
<translation id="36224234498066874">Ryd browserdata...</translation>
<translation id="362276910939193118">Vis hele historikken</translation>
-<translation id="3623476034248543066">Vis værdi</translation>
<translation id="3630155396527302611">Hvis programmet allerede står på listen over programmer, der har adgang til netværket, kan du prøve
at fjerne det fra listen og tilføje det igen.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Valideringen er fuldført</translation>
<translation id="3655670868607891010">Hvis du ser dette jævnligt, kan du prøve <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revision</translation>
<translation id="366077651725703012">Opdater betalingskort</translation>
<translation id="3676592649209844519">Enheds-id:</translation>
+<translation id="3677008721441257057">Mente du &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Anmodningen kunne ikke signeres</translation>
<translation id="3678529606614285348">Åbn siden i et nyt inkognitovindue (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Nedbrud registreret <ph name="CRASH_TIME" />, uploadet <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Det netværk, du bruger, kan kræve, at du går til netværkets loginside.</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="3709599264800900598">Tekst, du har kopieret</translation>
<translation id="3712624925041724820">Licenserne er opbrugt</translation>
<translation id="3714780639079136834">Tænde for mobildata eller Wi-Fi</translation>
<translation id="3715597595485130451">Opret forbindelse til Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Tjekke proxy-, firewall- og DNS-konfigurationen<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Apps, der kan forårsage denne fejl, er blandt andet antivirus-, firewall- og webfiltrerings- eller proxysoftware.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Når du bekræfter, deles kortoplysningerne på din Google-konto med dette website.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Udløber <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Størrelse 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Skadeligt indhold blokeres.</translation>
<translation id="3810973564298564668">Valgmuligheder</translation>
<translation id="382518646247711829">Hvis du bruger en proxyserver...</translation>
<translation id="3828924085048779000">Tomme adgangssætninger er ikke tilladt.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> har installeret udvidelser til yderligere funktioner. Udvidelser har adgang til nogle af dine data.</translation>
<translation id="385051799172605136">Tilbage</translation>
<translation id="3858027520442213535">Opdater dato og tid</translation>
<translation id="3884278016824448484">Modstridende enheds-id</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">Din anmodning om adgang til dette website er blevet sendt til <ph name="NAME" />.</translation>
<translation id="3890664840433101773">Tilføj mail</translation>
<translation id="3901925938762663762">Kortet er udløbet</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Spørg altid på dette website</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Dette sessionsnavn findes allerede.</translation>
<translation id="3987940399970879459">Mindre end 1 MB</translation>
+<translation id="4008849406247176967">Advarsel! Der er mere end én kilde med modstridende værdier for denne politik.</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="4030383055268325496">&amp;Fortryd tilføjelse</translation>
+<translation id="4032320456957708163">Din browser administreres af <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Nøgle "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Tilføj gyldig adresse</translation>
<translation id="4072486802667267160">Der opstod en fejl under behandlingen af din ordre. Prøv igen.</translation>
<translation id="4075732493274867456">Klienten og serveren understøtter ikke en fælles SSL-protokolversion eller et fælles krypteringsprogram.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Lilla</translation>
<translation id="4165986682804962316">Indstillinger for websites</translation>
<translation id="4171400957073367226">Ugyldig verifikationssignatur</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element mere}one{<ph name="ITEM_COUNT" /> element mere}other{<ph name="ITEM_COUNT" /> elementer mere}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Trin 1: Log ind på portalen&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Nulstil adgangskoden</translation>
<translation id="4280429058323657511">udløber <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Kortet er gemt på din Google-konto}one{Kortet er gemt på din Google-konto}other{Kortene er gemt på din Google-konto}}</translation>
+<translation id="42981349822642051">Udvid</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Skift</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloker (standardindstilling)</translation>
+<translation id="4318566738941496689">Din enheds navn og netværksadresse</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="4340982228985273705">Denne computer registreres ikke som virksomhedsadministreret, så politikken kan kun automatisk installere udvidelser, der hostes i Chrome Webshop. Opdateringswebadressen til Chrome Webshop er "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Accepterede kreditkort</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Administrer betalingsmetoder...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">søgeresultater</translation>
-<translation id="4406972042435603828">Dine administratorer har installeret udvidelser med effektive funktioner.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Afhentningsadresse</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="443121186588148776">Serieport</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> accepterede ikke dit logincertifikat, eller der er ikke angivet et.</translation>
<translation id="4434045419905280838">Pop op-vinduer og omdirigeringer</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Brug af en proxy er deaktiveret, men en eksplicit proxykonfiguration er angivet.</translation>
<translation id="445100540951337728">Accepterede debetkort</translation>
+<translation id="4466881336512663640">Du mister eventuelle formularændringer. Er du sikker på, at du vil fortsætte?</translation>
<translation id="4482953324121162758">Dette website kan ikke oversættes.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Webadressen er ugyldig. Webadressen skal indeholde et standardskema, f.eks. http://eksempel.dk eller https://eksempel.dk.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">Kort og adresser stammer 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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Detaljer</translation>
<translation id="4524805452350978254">Administrer kort</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prøv at deaktivere dine udvidelser.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Levering</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Fjern kort</translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</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="4597348597567598915">Størrelse 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Før mig dertil nu</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Stop med at bruge et ugyldigt certifikat</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Din forbindelse blev afbrudt</translation>
<translation id="471880041731876836">Du har ikke tilladelse til at besøge dette website</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Køre Windows Netværksdiagnosticering<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Opdater politikker</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Genstart Chromium</translation>
<translation id="473775607612524610">Opdater</translation>
<translation id="4738601419177586157"><ph name="TEXT" />-søgeforslag</translation>
<translation id="4742407542027196863">Administrer adgangskoder…</translation>
<translation id="4744603770635761495">Eksekverbar sti</translation>
+<translation id="4746351372139058112">Beskeder</translation>
<translation id="4750917950439032686">Dine oplysninger (f.eks. adgangskoder eller kreditkortnumre) er private, når de sendes til dette website.</translation>
<translation id="4756388243121344051">&amp;Historik</translation>
<translation id="4758311279753947758">Tilføj kontaktoplysninger</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Websiden på <ph name="URL" /> kan være midlertidigt nede, eller også er den permanent flyttet til en ny webadresse.</translation>
<translation id="4771973620359291008">Der er opstået en ukendt fejl.</translation>
<translation id="4785689107224900852">Skift til denne fane</translation>
-<translation id="4792143361752574037">Der var ikke adgang til sessionsfilerne. Det er i øjeblikket ikke muligt at gemme på disken. Genindlæs siden for at prøve igen.</translation>
<translation id="4798078619018708837">Opdater dine kortoplysninger ved at indtaste udløbsdatoen og kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles kortoplysningerne på din Google-konto med dette website.</translation>
<translation id="4800132727771399293">Kontrollér, om din kontrolkode og udløbsdato er korrekte, og prøv igen.</translation>
+<translation id="480334179571489655">Fejl i politik med samme oprindelse</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Åbn</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Ingen resultater</translation>
<translation id="4950898438188848926">Knap til faneskift. Tryk på Enter for at skifte til den åbne fane, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Handlinger</translation>
-<translation id="495832697253704892">Udvidelsers rapportering</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Udvid liste</translation>
<translation id="4974590756084640048">Genaktiver advarsler</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Se alle</translation>
<translation id="4989809363548539747">Dette plugin understøttes ikke</translation>
-<translation id="4996230189582812866">Rapportering</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="5014174725590676422">Skærmen for førstegangsbrug af Google Assistent i Chrome vises</translation>
<translation id="5015510746216210676">Maskinnavn:</translation>
+<translation id="5017554619425969104">Tekst, du har kopieret</translation>
<translation id="5018422839182700155">Denne side kan ikke åbnes</translation>
<translation id="5019198164206649151">Sikkerhedskopien er fejlbehæftet</translation>
<translation id="5023310440958281426">Læs din administrators politikker</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Lokal kontekst <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Tillad</translation>
<translation id="5040262127954254034">Privatliv</translation>
+<translation id="5043480802608081735">Link, du har kopieret</translation>
<translation id="5045550434625856497">Ugyldig adgangskode</translation>
<translation id="5056549851600133418">Artikler til dig</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Tjekke proxy-adressen<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Serverens certifikatet er ikke gyldigt i øjeblikket.</translation>
<translation id="5087580092889165836">Tilføj kort</translation>
<translation id="5089810972385038852">Stat</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="5097099694988056070">Enhedsstatistik som f.eks. CPU/RAM-forbrug</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Din enhed administreres af <ph name="ENROLLMENT_DOMAIN" />, og din konto administreres af <ph name="ACCOUNT_DOMAIN" />. Dette betyder, at dine administratorer kan konfigurere din enhed og konto via fjernadgang.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">Sessionen med dette navn kan ikke slettes.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Administrer adresser...</translation>
+<translation id="5138227688689900538">Vis færre</translation>
<translation id="5141240743006678641">Krypter synkroniserede adgangskoder med dine Google-loginoplysninger</translation>
<translation id="5145883236150621069">Fejlkode til stede i politiksvar</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Åbn siden i et nyt inkognitovindue (⇧⌘N)</translation>
<translation id="516920405563544094">Angiv kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles kortoplysningerne på din Google-konto med dette website.</translation>
<translation id="5169827969064885044">Du kan miste adgangen til din organisations konto eller udsættes for identitetstyveri. Chrome anbefaler, at du skifter din adgangskode nu.</translation>
<translation id="5171045022955879922">Søg, eller angiv webadresse</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Maskine</translation>
<translation id="5179510805599951267">Ikke på <ph name="ORIGINAL_LANGUAGE" />? Rapporter denne fejl</translation>
<translation id="5190835502935405962">Bogmærkelinje</translation>
-<translation id="5200263511887412697">rapportér en liste over enhedsbrugere, der har logget ind for nylig</translation>
+<translation id="519422657042045905">Annotering er ikke tilgængelig</translation>
<translation id="5201306358585911203">En integreret side på denne side siger</translation>
<translation id="5205222826937269299">Navn påkrævet</translation>
<translation id="5215116848420601511">Betalingsmetoder og adresser, der bruger Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Mail påkrævet</translation>
<translation id="5230733896359313003">Leveringsadresse</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Opret forbindelse til netværk"</translation>
<translation id="5251803541071282808">Skyen</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Netværksadresser</translation>
<translation id="5285570108065881030">Se alle gemte adgangskoder</translation>
<translation id="5287240709317226393">Vis cookies</translation>
<translation id="5288108484102287882">Validering af politikværdier har genereret advarsler</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> af <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Vælg kontaktoplysninger</translation>
<translation id="5327248766486351172">Navn</translation>
+<translation id="5329858041417644019">Din browser administreres ikke</translation>
<translation id="5332219387342487447">Leveringsmetode</translation>
+<translation id="5334013548165032829">Detaljerede systemlogfiler</translation>
<translation id="5344579389779391559">Denne side forsøger muligvis at opkræve penge af dig</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Dit ur er bagud" eller "Dit ur er forud" eller "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Log ind, og aktivér synkronisering for at bruge dine kort på alle enheder.</translation>
<translation id="5386426401304769735">Certifikatkæden for dette website indeholder et certifikat, der er signeret med SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Ugyldig</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Annuller fortryd redigering</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Tilføj gyldig adresse</translation>
<translation id="5490432419156082418">Adresser m.m.</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Prøv at kontakte din systemadministrator.</translation>
<translation id="549333378215107354">Størrelse 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Administrerede bogmærker</translation>
<translation id="5510766032865166053">Den kan være blevet flyttet eller slettet.</translation>
<translation id="5523118979700054094">Navn på politik</translation>
<translation id="552553974213252141">Blev teksten trukket korrekt ud?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Den anmodede artikel blev ikke fundet.</translation>
<translation id="5541546772353173584">Tilføj mail</translation>
<translation id="5545756402275714221">Artikler til dig</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Rediger adresse</translation>
<translation id="5598944008576757369">Vælg betalingsmetode</translation>
<translation id="560412284261940334">Administration er ikke understøttet</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> omdirigerede dig for mange gange.</translation>
<translation id="5629630648637658800">Der kunne ikke indlæses indstillinger for politik</translation>
<translation id="5631439013527180824">Ugyldigt token for enhedsadministration</translation>
+<translation id="5632627355679805402">Dine data er krypteret med din <ph name="BEGIN_LINK" />Google-adgangskode<ph name="END_LINK" /> fra <ph name="TIME" />. Angiv den for at starte synkroniseringen.</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="563324245173044180">Vildledende indhold er blokeret.</translation>
<translation id="5659593005791499971">Mail</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">Administratoren af enheden har installeret udvidelser til yderligere funktioner. Udvidelser har adgang til nogle af dine data.</translation>
<translation id="5675650730144413517">Denne side virker ikke</translation>
+<translation id="5684874026226664614">Ups! Denne side kunne ikke oversættes.</translation>
<translation id="5685654322157854305">Tilføj leveringsadresse</translation>
<translation id="5689199277474810259">Eksportér i JSON</translation>
<translation id="5689516760719285838">Placering</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Dette websites identitet er ikke blevet bekræftet.</translation>
<translation id="5719499550583120431">Forudbetalte kort accepteres.</translation>
<translation id="5720705177508910913">Aktuel bruger</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome anbefaler, at du nulstiller din adgangskode, hvis du har brugt den på andre websites.</translation>
<translation id="5732392974455271431">Dine forældre kan fjerne blokeringen for dig</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Gem kortet på din Google-konto}one{Gem kortet på din Google-konto}other{Gem kortene på din Google-konto}}</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="5770114862687765385">Filen ser ud til at være beskadiget. Klik på knappen "Nulstil" for at nulstille sessionen.</translation>
<translation id="5778550464785688721">Fuld kontrol over MIDI</translation>
<translation id="578305955206182703">Ravgul</translation>
<translation id="57838592816432529">Slå lyden fra</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>
+<translation id="5798290721819630480">Vil du kassere ændringerne?</translation>
<translation id="5798683403665926540">Skift startside i indstillingerne for Chrome</translation>
<translation id="5803412860119678065">Skal <ph name="CARD_DETAIL" /> udfyldes?</translation>
<translation id="5804241973901381774">Tilladelser</translation>
<translation id="5810442152076338065">Din forbindelse til <ph name="DOMAIN" /> er krypteret ved hjælp af en forældet krypteringspakke.</translation>
<translation id="5813119285467412249">&amp;Annuller fortryd tilføjelse</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="5860033963881614850">Fra</translation>
<translation id="5863847714970149516">Siden forude kan forsøge at opkræve dig penge</translation>
<translation id="5866257070973731571">Tilføj telefonnummer</translation>
<translation id="5869405914158311789">Der kan ikke oprettes forbindelse til dette website</translation>
<translation id="5869522115854928033">Gemte adgangskoder</translation>
<translation id="5887400589839399685">Kortet er gemt</translation>
-<translation id="5893718151540690985">rapportér en liste over netværksgrænseflader med deres typer og hardwareadresser</translation>
<translation id="5893752035575986141">Kreditkort accepteres.</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="5916664084637901428">Til</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vil du gemme kortet på din Google-konto?</translation>
<translation id="5922853866070715753">Næsten færdig</translation>
<translation id="5932224571077948991">Websitet viser påtrængende eller vildledende annoncer</translation>
-<translation id="5939518447894949180">Nulstil</translation>
<translation id="5946937721014915347">Åbner <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Det er ikke muligt at tilmelde sig med en forbrugerkonto (mulighed for tilknyttet licens ).</translation>
<translation id="5967592137238574583">Rediger kontaktoplysninger</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Zoom ud</translation>
<translation id="5977489021191000276">Din enhed administreres ikke af en administrator.</translation>
<translation id="5977976211062815271">På denne enhed</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Betalingsappen kan ikke åbnes</translation>
<translation id="5989320800837274978">Der er hverken angivet faste proxyservere eller en .pac-scriptwebadresse.</translation>
<translation id="5990559369517809815">Anmodninger til serveren er blokeret af en udvidelse.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">rapportér hardwarestatistik såsom CPU-/RAM-forbrug</translation>
<translation id="6034000775414344507">Lysegrå</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Kontakt ejeren af websitet, hvis problemet fortsætter.</translation>
<translation id="6040143037577758943">Luk</translation>
<translation id="6044573915096792553">Størrelse 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Vil du bruge kortene på alle dine enheder?</translation>
<translation id="6059925163896151826">USB-enheder</translation>
-<translation id="6071091556643036997">Politiktypen er ugyldig.</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="6094273045989040137">Annoter</translation>
<translation id="610911394827799129">Din Google-konto kan have andre former for browserhistorik på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Oplysninger om installerede udvidelser og plugins</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Frigiver mindre end <ph name="SIZE" />. Nogle websites indlæses muligvis langsommere under dit næste besøg.</translation>
<translation id="6337534724793800597">Filtrér politikker efter navn</translation>
<translation id="6358450015545214790">Hvad betyder dette?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Potentielle debiteringer forude</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 andet forslag}one{# andet forslag}other{# andre forslag}}</translation>
<translation id="6387754724289022810">Gem dit kort og din faktureringsadresse på din Google-konto og denne enhed for at betale hurtigere næste gang.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Rediger bogmærke</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377">Angiv 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="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="6434309073475700221">Kasser</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Tilføj flere oplysninger</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Bekræft genindsendelse af formular</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Genstart Chrome</translation>
<translation id="6529602333819889595">&amp;Annuller fortryd slet</translation>
<translation id="6534179046333460208">Forslag til Fysisk web</translation>
+<translation id="6556866813142980365">Gør det igen</translation>
<translation id="6563469144985748109">Din administrator har ikke godkendt det endnu</translation>
<translation id="6569060085658103619">Du ser en udvidelsesside</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Lys pink</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link, du har kopieret</translation>
+<translation id="6591833882275308647">Din <ph name="DEVICE_TYPE" /> administreres ikke</translation>
<translation id="6596325263575161958">Krypteringsmuligheder</translation>
<translation id="6604181099783169992">Bevægelses- eller lyssensorer</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Kontaktoplysninger</translation>
<translation id="6626291197371920147">Tilføj gyldigt kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> -søgning</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Denne politik er forældet.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Fra 1 website (du logges ikke ud af din Google-konto)}one{Fra # website (du logges ikke ud af din Google-konto)}other{Fra # websites (du logges ikke ud af din Google-konto)}}</translation>
<translation id="6657585470893396449">Adgangskode</translation>
+<translation id="6670613747977017428">Gå tilbage i sikkerhed</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Tilmeldingstoken:</translation>
<translation id="6711464428925977395">Der er noget galt med proxyserveren, eller adressen er forkert.</translation>
<translation id="6723740634201835758">På din Google-konto</translation>
+<translation id="6738516213925468394">Dine data blev krypteret med din <ph name="BEGIN_LINK" />adgangssætning til synkronisering<ph name="END_LINK" /> <ph name="TIME" />. Indtast adgangssætningen for at starte synkroniseringen.</translation>
<translation id="674375294223700098">Ukendt fejl i servercertifikatet.</translation>
<translation id="6744009308914054259">Mens du venter på en forbindelse, kan du gå til Downloads for at læse artikler offline.</translation>
<translation id="6753269504797312559">Politikkens værdi</translation>
<translation id="6757797048963528358">Din enhed gik i dvale.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Din forælder har ikke godkendt det endnu</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Udvidelser</translation>
<translation id="679355240208270552">Ignoreret, fordi en standardsøgemaskine ikke er aktiveret af politikken.</translation>
<translation id="681021252041861472">Skal udfyldes</translation>
<translation id="6810899417690483278">Tilpasnings-id</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Enhed</translation>
<translation id="6970216967273061347">Distrikt</translation>
<translation id="6973656660372572881">Både faste proxyservere og en webadresse for .pac-script angives.</translation>
+<translation id="6973932557599545801">Jeg kan desværre ikke hjælpe. Fortsæt på egen hånd.</translation>
<translation id="6979158407327259162">Google Drev</translation>
<translation id="6979440798594660689">Slå lyden fra (standard)</translation>
<translation id="6984479912851154518">Du forlader privat tilstand for at betale via en ekstern app. Vil du fortsætte?</translation>
<translation id="6989763994942163495">Vis avancerede indstillinger...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Oversæt altid <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Disse debiteringer kan være enkeltstående eller gentagne og fremgår muligvis ikke tydeligt.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Skjul</translation>
<translation id="7108819624672055576">Tilladt med en udvidelse</translation>
<translation id="7111012039238467737">(gyldigt)</translation>
+<translation id="7118618213916969306">Søg efter webadresse til udklipsholderen, <ph name="SHORT_URL" /></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="7135130955892390533">Vis status</translation>
<translation id="7138472120740807366">Leveringsmetode</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendelblå</translation>
-<translation id="7158980942472052083">Webadressen er ugyldig. Webadessen skal have et standardskema.</translation>
<translation id="717330890047184534">Gaia-id:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Den server, du er på vej til, <ph name="ORIGIN" />, har anmodet om, at
+ der anvendes en sikkerhedspolitik for alle anmodninger, der sendes til den. I stedet for at
+ levere en politik har den omdirigeret browseren til et andet sted, hvilket forhindrer
+ browseren i at opfylde din anmodning for <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Gem og udfyld betalingsmetoder</translation>
<translation id="7180611975245234373">Opdater</translation>
<translation id="7182878459783632708">Ingen politikker er indstillet</translation>
<translation id="7186367841673660872">Denne side er oversat fra<ph name="ORIGINAL_LANGUAGE" />til<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Frigør <ph name="SIZE" />. Nogle websites indlæses muligvis langsommere, næste gang du besøger websitet.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Din administrator kan se:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> overholder ikke sikkerhedsstandarderne.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /> om dette problem.</translation>
<translation id="7219179957768738017">Forbindelsen bruger <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Behandler</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Det site, du er på vej til, indeholder malware</translation>
+<translation id="724766306220616965">Advarsler, konflikt</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="7251437084390964440">Netværkskonfigurationen overholder ikke ONC-standarden. Dele af konfiguration kan muligvis ikke importeres.
Yderligere oplysninger:
@@ -982,11 +1120,14 @@ Yderligere oplysninger:
<translation id="7300012071106347854">Koboltblå</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Nedbrudsrapport registreret <ph name="CRASH_TIME" /> (upload, som brugeren anmodede om, er endnu ikke uploadet)</translation>
+<translation id="7313965965371928911">Advarsler fra <ph name="BEGIN_LINK" />Beskyttet browsing<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Hjælp til at oprette forbindelse</translation>
<translation id="7334320624316649418">&amp;Annuller fortryd omarrangering</translation>
<translation id="733923710415886693">Servercertifikatet blev ikke fremvist via Certifikatsgennemsigtighed.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Kommandolinje</translation>
-<translation id="7365061714576910172">Eksportér Linux</translation>
<translation id="7372973238305370288">søgeresultat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nej</translation>
@@ -994,6 +1135,7 @@ Yderligere oplysninger:
<translation id="7381288752349550461">Tilsidesættelse af administreret session</translation>
<translation id="7390545607259442187">Bekræft kort</translation>
<translation id="7400418766976504921">Webadresse</translation>
+<translation id="7403591733719184120">Din <ph name="DEVICE_NAME" /> administreres</translation>
<translation id="7407424307057130981">&lt;p&gt;Denne fejl vises, hvis du har Superfish-software på din Windows-computer.&lt;/p&gt;
&lt;p&gt;Følg denne vejledning for at deaktivere softwaren midlertidigt, så du kan komme på nettet. Du skal have administratorrettigheder.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Yderligere oplysninger:
&lt;li&gt;Klik på &lt;strong&gt;Anvend&lt;/strong&gt;, og klik derefter på &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Gå til &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Hjælp til Chrome&lt;/a&gt; for at se, hvordan du permanent fjerner softwaren fra din computer
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Administration af <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Administrer adgangskoder…</translation>
<translation id="7419106976560586862">Profilsti</translation>
<translation id="7437289804838430631">Tilføj kontaktoplysninger</translation>
@@ -1013,22 +1155,24 @@ Yderligere oplysninger:
<translation id="7442725080345379071">Lys orange</translation>
<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="7449109375006139765">send systemlogfiler til administrationsserveren</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="7460618730930299168">Screeningen stemmer ikke overens med det, du har valgt. Vil du fortsætte?</translation>
<translation id="7473891865547856676">Nej tak</translation>
-<translation id="7475525192983021547">rapportér tidsperioder, hvor en bruger er aktiv på enheden</translation>
<translation id="7481312909269577407">Frem</translation>
<translation id="7485870689360869515">Der blev ikke fundet nogen data.</translation>
+<translation id="7498234416455752244">Fortsæt redigering</translation>
<translation id="7508255263130623398">Det returnerede enheds-id for politikken er tomt eller stemmer ikke overens med det nuværende enheds-id</translation>
<translation id="7508870219247277067">Avocadogrøn</translation>
<translation id="7511955381719512146">Det Wi-Fi-netværk, du bruger, kan kræve, at du går til <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">Ingen webside fundet på webadressen: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Din forbindelse til dette website er ikke privat</translation>
+<translation id="7535087603100972091">Værdi</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1037,8 +1181,8 @@ Yderligere oplysninger:
<translation id="7552846755917812628">Prøv de følgende tips:</translation>
<translation id="7554791636758816595">Ny fane</translation>
<translation id="7564049878696755256">Du kan miste adgangen til din <ph name="ORG_NAME" />-konto eller udsættes for identitetstyveri. Chrome anbefaler, at du skifter din adgangskode nu.</translation>
-<translation id="7566125604157659769">Tekst, du har kopieret</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="7568105740864181217">Denne browser administreres af en virksomhed, skole eller en anden organisation. Din administrator kan ændre konfigurationen af din browser via fjernadgang. Aktivitet på denne enhed administreres muligvis også uden for Chrome. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Yderligere oplysninger:
<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. Angiv adgangskoden i feltet nedenfor.</translation>
+<translation id="7633909222644580952">Effektivitetsdata og nedbrudsrapporter</translation>
<translation id="7637571805876720304">Vil du fjerne kreditkortet fra Chromium?</translation>
<translation id="7639968568612851608">Mørkegrå</translation>
<translation id="765676359832457558">Skjul avancerede indstillinger...</translation>
@@ -1058,9 +1203,11 @@ Yderligere oplysninger:
<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="7676643023259824263">Søg efter tekst i udklipsholderen, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Skift søgemaskine</translation>
<translation id="7682287625158474539">Forsendelse</translation>
<translation id="7687186412095877299">Udfylder betalingsformularer med dine gemte betalingsmetoder</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">Lige nu har du kort, som kun kan bruges på denne enhed. Klik på Fortsæt for at se kortene.</translation>
<translation id="7699293099605015246">Der er ingen tilgængelige artikler lige nu</translation>
<translation id="7701040980221191251">Ingen</translation>
@@ -1072,11 +1219,13 @@ Yderligere oplysninger:
<translation id="774634243536837715">Farligt indhold er blokeret.</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
<translation id="7755287808199759310">Din forælder kan fjerne blokeringen for dig</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Firewall- eller antivirussoftware kan have blokeret forbindelsen.</translation>
<translation id="7759163816903619567">Vist domæne:</translation>
<translation id="7761701407923456692">Serverens certifikat passer ikke til webadressen.</translation>
<translation id="7763386264682878361">Værktøj til parsing af betalingsmanifester</translation>
<translation id="7764225426217299476">Tilføj adresse</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Præfektur</translation>
<translation id="7791543448312431591">Tilføj</translation>
<translation id="7793809570500803535">Websitet på <ph name="SITE" /> kan være midlertidigt nede, eller også er den permanent flyttet til en ny webadresse.</translation>
@@ -1088,8 +1237,8 @@ Yderligere oplysninger:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Vil du fjerne formularforslaget fra Chrome?</translation>
<translation id="7815407501681723534">Der blev fundet <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> for "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Administration af politikker</translation>
<translation id="782886543891417279">Det Wi-Fi-netværk, du bruger (<ph name="WIFI_NAME" />), kan kræve, at du går til netværkets loginside.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ingen}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Du er dog ikke usynlig. Inkognitotilstand skjuler ikke din browserhistorik over for din arbejdsgiver, din internetudbyder eller de websites, du besøger.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Yderligere oplysninger:
<translation id="7878562273885520351">Din adgangskode kan være kompromitteret</translation>
<translation id="7882421473871500483">Brun</translation>
<translation id="7887683347370398519">Kontrollér, om din kontrolkode er korrekt, og prøv igen.</translation>
-<translation id="7893255318348328562">Sessionsnavn</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Angiv et gyldigt telefonnummer</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Udløber <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Yderligere oplysninger:
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Bogmærker på mobil</translation>
<translation id="7961015016161918242">Aldrig</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Administrer adgangskoder</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Kortet og faktureringsadressen gemmes. Du kan bruge dem, når du er logget ind på <ph name="USER_EMAIL" />.}one{Kortet og faktureringsadressen gemmes. Du kan bruge dem, når du er logget ind på <ph name="USER_EMAIL" />.}other{Kortene og faktureringsadresserne gemmes. Du kan bruge dem, når du er logget ind på <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Denne side er på <ph name="SOURCE_LANGUAGE" />. Vil du oversætte den til <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pen</translation>
+<translation id="8037117624646282037">Hvem der senest har brugt enheden</translation>
<translation id="8037357227543935929">Spørg (standardindstilling)</translation>
<translation id="803771048473350947">Fil</translation>
<translation id="8041089156583427627">Send feedback</translation>
<translation id="8041940743680923270">Brug global standard (spørg)</translation>
<translation id="8042918947222776840">Vælg afhentningsmetode</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" er ikke konfigureret korrekt. Problemet kan normalt løses ved at afinstallere "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Din enhed er konfigureret til:</translation>
+<translation id="8066955247577885446">Der opstod en fejl.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Der kan ikke annoteres ved rotering</translation>
<translation id="8079031581361219619">Vil du genindlæse websitet?</translation>
<translation id="8088680233425245692">Artiklen kunne ikke vises.</translation>
@@ -1131,11 +1284,12 @@ Yderligere oplysninger:
<translation id="8091372947890762290">Aktivering afventer serveren</translation>
<translation id="8092774999298748321">Mørkelilla</translation>
<translation id="8094917007353911263">Det netværk, du bruger, kan kræve, at du går til <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">De ugyldige kort er fjernet</translation>
<translation id="8103161714697287722">Betalingsmetode</translation>
<translation id="8118489163946903409">Betalingsmetode</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> administreres af <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" blev ikke korrekt installeret på computeren eller netværket. Bed din IT-administrator om at løse problemet.</translation>
-<translation id="8130693978878176684">Jeg kan desværre ikke hjælpe mere. Fortsæt på egen hånd.</translation>
<translation id="8131740175452115882">Bekræft</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>
@@ -1145,8 +1299,11 @@ Yderligere oplysninger:
<translation id="8197543752516192074">Oversæt side</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">Forbindelsen er sikker</translation>
<translation id="8218327578424803826">Tildelt placering:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Åbn siden på en ny inkognitofane</translation>
@@ -1158,14 +1315,16 @@ Yderligere oplysninger:
<translation id="825929999321470778">Se alle gemte adgangskoder</translation>
<translation id="8261506727792406068">Slet</translation>
<translation id="8267698848189296333">Logger ind som <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Denne browser administreres af <ph name="ENROLLMENT_DOMAIN" />. Din administrator kan ændre konfigurationen af din browser via fjernadgang. Aktivitet på denne enhed administreres muligvis også uden for Chrome. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Log ind</translation>
<translation id="8288807391153049143">Vis certifikat</translation>
<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="8298115750975731693">Det Wi-Fi-netværk, du bruger (<ph name="WIFI_NAME" />), kan kræve, at du går til <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Oversættelsen mislykkedes på grund af problemer med netværksforbindelsen.</translation>
-<translation id="8311129316111205805">Indlæs session</translation>
<translation id="8332188693563227489">Adgangen til <ph name="HOST_NAME" /> blev nægtet</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Yderligere oplysninger:
<translation id="8416694386774425977">Netværkskonfigurationen er ugyldig og kunne ikke importeres.
Yderligere oplysninger:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Enheden administreres af <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Skift</translation>
<translation id="8428213095426709021">Indstillinger</translation>
@@ -1211,9 +1369,11 @@ Yderligere oplysninger:
<translation id="860043288473659153">Kortholderens navn</translation>
<translation id="861775596732816396">Størrelse 4</translation>
<translation id="8620436878122366504">Dine forældre har ikke godkendt det endnu</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Gem dette kort på denne enhed</translation>
<translation id="8663226718884576429">Ordreoversigt, <ph name="TOTAL_LABEL" />, flere oplysninger</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, svar, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Din forbindelse til <ph name="DOMAIN" /> er ikke krypteret.</translation>
<translation id="8718314106902482036">Betalingen blev ikke fuldført</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, søgeforslag</translation>
@@ -1227,6 +1387,7 @@ Yderligere oplysninger:
<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="8763927697961133303">USB-enhed</translation>
<translation id="8768895707659403558"><ph name="SIGN_IN_LINK" /> for at bruge dine kort på alle dine enheder.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Annuller fortryd sletning</translation>
<translation id="8792621596287649091">Du kan miste adgangen til din <ph name="ORG_NAME" />-konto eller udsættes for identitetstyveri. Chromium anbefaler, at du skifter din adgangskode nu.</translation>
<translation id="8800988563907321413">Her vises de forslag, der er tæt på dig</translation>
@@ -1237,10 +1398,12 @@ Yderligere oplysninger:
<translation id="885730110891505394">Deling med Google</translation>
<translation id="8858065207712248076">Chrome anbefaler, at du nulstiller din adgangskode til <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, hvis du har brugt den på andre websites.</translation>
<translation id="8866481888320382733">Der opstod en fejl ved parsing af indstillinger for politik</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Senest lukkede</translation>
<translation id="8874824191258364635">Angiv et gyldigt kortnummer</translation>
<translation id="8891727572606052622">Ugyldig proxytilstand.</translation>
<translation id="8903921497873541725">Zoom ind</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Vil du gemme dette kort på din Google-konto?</translation>
<translation id="8932102934695377596">Dit ur er bagud</translation>
<translation id="893332455753468063">Tilføj navn</translation>
@@ -1248,13 +1411,13 @@ Yderligere oplysninger:
<translation id="894185898663964645">Din administrator har konfigureret tilpassede rodcertifikater, hvilket kan give administratoren mulighed for at se indholdet på de websites, du besøger.</translation>
<translation id="8943282376843390568">Limegrøn</translation>
<translation id="8957210676456822347">Godkendelse af captive portal</translation>
+<translation id="8966619695390250636">Mente du?</translation>
<translation id="8968766641738584599">Gem kort</translation>
<translation id="8971063699422889582">Serverens certifikat er udløbet.</translation>
<translation id="8975012916872825179">Omfatter oplysninger såsom telefonnumre, mailadresser og leveringsadresser</translation>
<translation id="8978053250194585037">Google Beskyttet browsing <ph name="BEGIN_LINK" />registrerede phishing<ph name="END_LINK" /> på <ph name="SITE" /> for nylig. Phishing-websites udgiver sig for at være andre websites med det formål at narre dig.</translation>
<translation id="8983003182662520383">Betalingsmetoder og adresser, der bruger Google Pay</translation>
<translation id="8987927404178983737">Måned</translation>
-<translation id="8988408250700415532">Der opstod en fejl. Du kan gennemføre bestillingen på websitet.</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>
@@ -1264,6 +1427,7 @@ Yderligere oplysninger:
<translation id="9011424611726486705">Åbn indstillinger for website</translation>
<translation id="9020200922353704812">Kortets faktureringsadresse er obligatorisk</translation>
<translation id="9020542370529661692">Denne side er oversat til <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(ugyldigt)</translation>
<translation id="9035022520814077154">Sikkerhedsfejl</translation>
<translation id="9038649477754266430">Brug en forudsigelsestjeneste til hurtigere sideindlæsning</translation>
@@ -1275,11 +1439,11 @@ Yderligere oplysninger:
<translation id="9065745800631924235">Søgningen <ph name="TEXT" /> i historikken</translation>
<translation id="9069693763241529744">Blokeret af en udvidelse</translation>
<translation id="9076283476770535406">Der er muligvis indhold for voksne på websitet</translation>
+<translation id="9076630408993835509">Denne browser administreres ikke af en virksomhed eller en anden organisation. Aktivitet på denne enhed administreres muligvis uden for Chrome. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Flere oplysninger kræves</translation>
<translation id="9080712759204168376">Bestillingsoversigt</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>
<translation id="9106062320799175032">Tilføj faktureringsadresse</translation>
-<translation id="9110718169272311511">Google Assistent i Chrome er tilgængelig nederst på skærmen</translation>
<translation id="9114524666733003316">Bekræfter kort...</translation>
<translation id="9128870381267983090">Opret forbindelse til netværk</translation>
<translation id="9137013805542155359">Vis oprindelig</translation>
@@ -1288,6 +1452,7 @@ Yderligere oplysninger:
<translation id="9148507642005240123">&amp;Fortryd redigering</translation>
<translation id="9154194610265714752">Opdateret</translation>
<translation id="9157595877708044936">Konfigurerer...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Tillad, at websites tjekker, om du har nogen gemte betalingsmetoder</translation>
<translation id="9169664750068251925">Bloker altid på dette website</translation>
<translation id="9170848237812810038">&amp;Fortryd</translation>
@@ -1302,10 +1467,12 @@ Yderligere oplysninger:
<translation id="9219103736887031265">Billeder</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">RYD FORMULAREN</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Du kan miste adgangen til din Google-konto. Chromium anbefaler, at du skifter din adgangskode nu. Du bliver bedt om at logge ind.</translation>
<translation id="939736085109172342">Ny mappe</translation>
<translation id="945855313015696284">Se oplysningerne nedenfor, og slet eventuelle ugyldige kort</translation>
<translation id="951104842009476243">Accepterede betalingskort og forudbetalte kort</translation>
+<translation id="958202389743790697">Blokeret i overensstemmelse med sikkerhedspolitikken for <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Dette indhold kan forsøge at 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_LINK" />Vis alligevel<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Officiel version</translation>
<translation id="973773823069644502">Tilføj leveringsadresse</translation>
@@ -1314,6 +1481,7 @@ Yderligere oplysninger:
<translation id="984275831282074731">Betalingsmetoder</translation>
<translation id="985199708454569384">&lt;p&gt;Denne fejlmeddelelse vises, hvis dato og klokkeslæt på din computer eller mobilenhed er forkerte.&lt;/p&gt;
&lt;p&gt;Ret fejlen ved at åbne uret på din enhed. Sørg for, at dato og klokkeslæt er indstillet korrekt.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Udviklerversion</translation>
<translation id="989988560359834682">Rediger adresse</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_de.xtb b/chromium/components/strings/components_strings_de.xtb
index 03175d4ef68..884b750b380 100644
--- a/chromium/components/strings/components_strings_de.xtb
+++ b/chromium/components/strings/components_strings_de.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="de">
-<translation id="1005145902654145231">Die Sitzung konnte nicht umbenannt werden.</translation>
<translation id="1008557486741366299">Jetzt nicht</translation>
<translation id="1010200102790553230">Seite später laden</translation>
<translation id="1015730422737071372">Weitere Details angeben</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">Unbekannter Name</translation>
<translation id="1050038467049342496">Andere Apps schließen</translation>
<translation id="1055184225775184556">&amp;Hinzufügen rückgängig machen</translation>
+<translation id="1056898198331236512">Warnung</translation>
<translation id="1058479211578257048">Karten werden gespeichert…</translation>
<translation id="10614374240317010">Nie speichern für…</translation>
+<translation id="1062160989074299343">Prc10 (Umschlag)</translation>
<translation id="106701514854093668">Desktop-Lesezeichen</translation>
<translation id="1074497978438210769">Nicht sicher</translation>
<translation id="1080116354587839789">An Breite anpassen</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Angabe für "Name auf der Karte" hinzufügen</translation>
<translation id="1089439967362294234">Passwort ändern</translation>
<translation id="109743633954054152">Passwörter in den Chrome-Einstellungen verwalten</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Wenn die Sicherheitsfunktionen von Websites aktualisiert werden, können Warnungen häufiger auftreten. Dies sollte sich bald verbessern.</translation>
<translation id="1126551341858583091">Die Größe auf dem lokalen Speicher ist <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Richtlinien-Cache einwandfrei</translation>
+<translation id="1131264053432022307">Von Ihnen kopiertes Bild</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Umbenennen</translation>
<translation id="1175364870820465910">&amp;Drucken...</translation>
<translation id="1181037720776840403">Entfernen</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Gerätename</translation>
<translation id="124116460088058876">Weitere Sprachen</translation>
<translation id="1250759482327835220">Damit Zahlungen zukünftig schneller abgewickelt werden können, speichern Sie Ihre Kreditkartendaten, Ihren Namen und Ihre Rechnungsadresse in Ihrem Google-Konto.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronisiert)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Befehlszeilen-Varianten</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="1314614906530272393">Die ausgewählte Sitzung existiert nicht.</translation>
+<translation id="1320233736580025032">Prc1 (Umschlag)</translation>
+<translation id="132301787627749051">Nach Bild aus Zwischenablage suchen</translation>
<translation id="1323433172918577554">Mehr anzeigen</translation>
<translation id="132390688737681464">Adressen speichern und ausfüllen</translation>
<translation id="1333989956347591814">Ihre Aktivitäten <ph name="BEGIN_EMPHASIS" />sind eventuell weiterhin sichtbar<ph name="END_EMPHASIS" /> für:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Abholadresse</translation>
<translation id="1348198688976932919">Die Website, die Sie aufrufen möchten, enthält gefährliche Apps</translation>
<translation id="1348779747280417563">Namen bestätigen</translation>
+<translation id="1357195169723583938">Letzte Nutzer dieses Geräts und Zeitpunkt der Verwendung</translation>
+<translation id="1364822246244961190">Diese Richtlinie ist blockiert und ihr Wert wird deshalb ignoriert.</translation>
<translation id="1374468813861204354">Vorschläge</translation>
+<translation id="1374692235857187091">Index-4x6 (Postkarte)</translation>
<translation id="1375198122581997741">Informationen zur Version</translation>
<translation id="1376836354785490390">Weniger anzeigen</translation>
<translation id="1377321085342047638">Kartennummer</translation>
<translation id="138218114945450791">Hellblau</translation>
+<translation id="1382194467192730611">USB-Gerät wurde von Ihrem Administrator zugelassen</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> hat keine Daten gesendet.</translation>
+<translation id="140316286225361634">Die Website <ph name="ORIGIN" /> verlangt, dass für alle ihre Anfragen eine Sicherheitsrichtlinie gilt. Gemäß dieser Richtlinie wird die Website derzeit als unsicher betrachtet.</translation>
<translation id="1405567553485452995">Hellgrün</translation>
<translation id="1407135791313364759">Alle öffnen</translation>
<translation id="1413809658975081374">Datenschutzfehler</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Drucken</translation>
<translation id="1455413310270022028">Radierer</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Mehr anzeigen</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Versandadresse auswählen</translation>
+<translation id="1492194039220927094">Richtlinien übernehmen:</translation>
<translation id="1501859676467574491">Zeigen Sie Karten von Ihrem Google-Konto</translation>
-<translation id="1506687042165942984">Zeigt eine gespeicherte (veraltete) Kopie dieser Seite an</translation>
<translation id="1507202001669085618">&lt;p&gt;Diese Fehlermeldung wird angezeigt, wenn Sie ein WLAN-Portal verwenden, bei dem eine Anmeldung erforderlich ist, bevor Sie online gehen können.&lt;/p&gt;
&lt;p&gt;Klicken Sie auf der Seite, die Sie öffnen möchten, auf &lt;strong&gt;Verbinden&lt;/strong&gt;, um den Fehler zu beheben.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonnummer erforderlich</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Build-Datum</translation>
<translation id="1521655867290435174">Google Tabellen</translation>
<translation id="1527263332363067270">Warten auf Verbindung…</translation>
+<translation id="1529521330346880926">10x15 (Umschlag)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Auf dieser Seite wird Folgendes angezeigt</translation>
<translation id="153384715582417236">Das ist im Moment alles</translation>
<translation id="154408704832528245">Lieferadresse auswählen</translation>
<translation id="1549470594296187301">Für diese Funktion muss JavaScript aktiviert sein.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Ablaufdatum eingeben</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Von Ihnen kopiertes Bild</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Keine weiteren Dialogfelder auf dieser Seite zulassen</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Sitzung beenden</translation>
<translation id="1639239467298939599">Wird geladen...</translation>
<translation id="1640180200866533862">Nutzerrichtlinien</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">Das Serverzertifikat weist einen schwachen kryptografischen Schlüssel auf.</translation>
<translation id="1697532407822776718">Fertig!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Das Dokument kann aufgrund seiner Größe nicht mit Anmerkungen versehen werden</translation>
<translation id="1721312023322545264">Du benötigst die Berechtigung von <ph name="NAME" />, um diese Website zu besuchen</translation>
<translation id="1721424275792716183">* Pflichtfeld</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Setzen Sie sich mit dem Systemadministrator in Verbindung.</translation>
<translation id="1740951997222943430">Geben Sie einen gültigen Ablaufmonat ein</translation>
<translation id="1743520634839655729">Damit Zahlungen zukünftig schneller abgewickelt werden können, speichern Sie Ihre Kreditkartendaten, Ihren Namen und Ihre Rechnungsadresse in Ihrem Google-Konto und auf diesem Gerät.</translation>
+<translation id="1745880797583122200">Ihr Browser wird verwaltet</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Synchronisierungs-Passphrase aktualisieren</translation>
<translation id="1787142507584202372">Hier werden Ihre offenen Tabs angezeigt</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Name des Karteninhabers</translation>
<translation id="1821930232296380041">Anfrage oder Anfrageparameter ungültig</translation>
+<translation id="1822540298136254167">Von Ihnen besuchte Websites und Dauer des Besuchs</translation>
<translation id="1826516787628120939">Überprüfung läuft</translation>
<translation id="1834321415901700177">Diese Website enthält schädliche Programme</translation>
<translation id="1839551713262164453">Die Validierung der Richtlinienwerte hat Fehler ergeben und ist fehlgeschlagen</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Chrome-Browserverlauf löschen</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{und 1 weitere}other{und # weitere}}</translation>
<translation id="2003709556000175978">Jetzt Passwort zurücksetzen</translation>
+<translation id="20053308747750172">Der Server <ph name="ORIGIN" />, zu dem Sie gehen, verlangt, dass auf alle an ihn gerichteten Anfragen eine Sicherheitsrichtlinie angewendet wird. Jetzt hat er aber eine ungültige Richtlinie bereitgestellt, was den Browser daran hindert, Ihre Anfrage für <ph name="SITE" /> auszuführen.</translation>
<translation id="2025186561304664664">Proxy ist auf automatische Konfiguration eingestellt.</translation>
<translation id="2030481566774242610">Meinten Sie <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Proxy und Firewall prüfen<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Abteilung</translation>
<translation id="2102134110707549001">Starkes Passwort vorschlagen…</translation>
<translation id="2108755909498034140">Computer neu starten</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Karte</translation>
<translation id="2114841414352855701">Wird ignoriert, da sie von <ph name="POLICY_NAME" /> außer Kraft gesetzt wurde.</translation>
<translation id="213826338245044447">Mobile Lesezeichen</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (Umschlag)</translation>
<translation id="2181821976797666341">Richtlinien</translation>
<translation id="2183608646556468874">Telefonnummer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 Adresse}other{# Adressen}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2283340219607151381">Adressen speichern und ausfüllen</translation>
<translation id="2292556288342944218">Ihre Internetverbindung ist gesperrt</translation>
+<translation id="2294558542833290837">Der Link, den Sie ursprünglich geöffnet haben, ist ungewöhnlich</translation>
+<translation id="2297722699537546652">B5 (Umschlag)</translation>
+<translation id="2310021320168182093">Chou2 (Umschlag)</translation>
<translation id="2316887270356262533">Es werden weniger als 1 MB Speicherplatz freigegeben. Manche Websites werden beim nächsten Öffnen eventuell langsamer geladen.</translation>
<translation id="2317259163369394535">Für <ph name="DOMAIN" /> sind ein Nutzername und ein Passwort erforderlich.</translation>
<translation id="2317583587496011522">Debitkarten werden akzeptiert.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, läuft am <ph name="EXPIRATION_DATE_ABBR" /> ab</translation>
<translation id="2337852623177822836">Einstellung wird von Ihrem Administrator gesteuert</translation>
+<translation id="2346319942568447007">Von Ihnen kopiertes Bild</translation>
<translation id="2349790679044093737">VR-Sitzung ist aktiv</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>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">Absturzbericht erfasst am <ph name="CRASH_TIME" />, wurde nicht hochgeladen</translation>
<translation id="2367567093518048410">Ebene</translation>
<translation id="2378238891085281592">Sie befinden sich jetzt im privaten Modus</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Der Server <ph name="ORIGIN" />, zu dem Sie gehen, verlangt, dass auf alle an ihn gerichteten Anfragen eine Sicherheitsrichtlinie angewendet wird. Aber er hat keine Richtlinie bereitgestellt, was den Browser daran hindert, Ihre Anfrage für <ph name="SITE" /> auszuführen.</translation>
<translation id="244665789865330679">Ihr Gerät und Ihr Konto werden durch <ph name="ENROLLMENT_DOMAIN" /> verwaltet. Dies bedeutet, dass der Administrator Ihr Gerät und Ihr Konto per Remotezugriff konfigurieren kann.</translation>
<translation id="2463193859425327265">Startseite ändern</translation>
<translation id="2463739503403862330">Ausfüllen</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Lieferoption auswählen</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Netzwerkdiagnose ausführen<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Diese Seite übersetzen</translation>
<translation id="2479410451996844060">Ungültige Such-URL</translation>
<translation id="2482878487686419369">Benachrichtigungen</translation>
<translation id="248348093745724435">Computerrichtlinien</translation>
+<translation id="2485387744899240041">Nutzernamen für Ihr Gerät und Ihren Browser</translation>
<translation id="2491120439723279231">Das Serverzertifikat enthält Fehler.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Neue Karte scannen</translation>
<translation id="2501278716633472235">Zurück</translation>
<translation id="2503184589641749290">Akzeptierte Debit- und Prepaidkarten</translation>
<translation id="2515629240566999685">Signal an Ihrem Standort prüfen</translation>
-<translation id="2516852381693169964">Mit <ph name="SEARCH_ENGINE" /> nach Bild suchen</translation>
<translation id="2523886232349826891">Nur auf diesem Gerät gespeichert</translation>
<translation id="2524461107774643265">Weitere Informationen hinzufügen</translation>
<translation id="2536110899380797252">Adresse hinzufügen</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (Umschlag)</translation>
<translation id="2625385379895617796">Ihre Uhr geht vor</translation>
<translation id="2634124572758952069">Die Server-IP-Adresse von <ph name="HOST_NAME" /> wurde nicht gefunden.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Andere Tabs oder Apps schließen</translation>
<translation id="267371737713284912">Zum Rückgängigmachen <ph name="MODIFIER_KEY_DESCRIPTION" /> drücken</translation>
<translation id="2674170444375937751">Möchten Sie diese Seiten wirklich aus dem Verlauf löschen?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Verlassen</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Akzeptierte Karten</translation>
<translation id="2702801445560668637">Leseliste</translation>
<translation id="2704283930420550640">Wert stimmt nicht mit dem Format überein.</translation>
@@ -295,11 +330,10 @@
<translation id="2728127805433021124">Das Serverzertifikat ist mit einem schwachen Signaturalgorithmus signiert.</translation>
<translation id="2730326759066348565"><ph name="BEGIN_LINK" />Verbindungsdiagnose ausführen<ph name="END_LINK" /></translation>
<translation id="2738330467931008676">Abholadresse auswählen</translation>
-<translation id="2740531572673183784">OK</translation>
+<translation id="2740531572673183784">Ok</translation>
<translation id="2742870351467570537">Ausgewählte Einträge entfernen</translation>
<translation id="277133753123645258">Versandart</translation>
<translation id="277499241957683684">Fehlender Gerätedatensatz</translation>
-<translation id="2781030394888168909">Im Mac OS-Format exportieren</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Verbindung wurde zurückgesetzt.</translation>
<translation id="2788784517760473862">Akzeptierte Kreditkarten</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Inkognitofenster öffnen</translation>
-<translation id="2851634818064021665">Sie benötigen eine Berechtigung, um auf diese Website zuzugreifen</translation>
+<translation id="2850739647070081192">Invite (Umschlag)</translation>
+<translation id="2851634818064021665">Du benötigst eine Berechtigung, um auf diese Website zuzugreifen</translation>
<translation id="2856444702002559011">Hacker könnten versuchen, Ihre Daten von <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> zu stehlen, zum Beispiel Passwörter, Nachrichten oder Kreditkartendaten. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Karte speichern?</translation>
<translation id="2903493209154104877">Adressen</translation>
<translation id="290376772003165898">Diese Seite ist nicht auf <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Lieferoption</translation>
<translation id="2928905813689894207">Rechnungsadresse</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (Umschlag)</translation>
<translation id="3024663005179499861">Falscher Richtlinientyp</translation>
<translation id="3037605927509011580">Oh nein!</translation>
<translation id="3041612393474885105">Zertifikatinformationen</translation>
+<translation id="3060227939791841287">C9 (Umschlag)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Abholadresse hinzufügen</translation>
<translation id="3105172416063519923">Geräte-ID:</translation>
<translation id="3109728660330352905">Sie sind nicht zum Aufrufen dieser Seite autorisiert.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> auf <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Zahlung abbrechen</translation>
<translation id="3207960819495026254">Mit einem Lesezeichen versehen</translation>
-<translation id="3209375525920864198">Bitte geben Sie einen gültigen Sitzungsnamen ein.</translation>
+<translation id="321912867715453276">Warnung: Für die Richtlinie sind mehrere Quelle vorhanden, aber die Werte sind dieselben.</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 noch einmal 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="3229041911291329567">Versionsinformationen zu Ihrem Gerät und Browser</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Angabe für "Name auf der Karte" hinzufügen</translation>
<translation id="3287510313208355388">Herunterladen, sobald eine Internetverbindung besteht</translation>
<translation id="3293642807462928945">Weitere Informationen zur "<ph name="POLICY_NAME" />"-Richtlinie</translation>
<translation id="3303855915957856445">Keine Suchergebnisse gefunden</translation>
-<translation id="3305707030755673451">Ihre Daten wurden am <ph name="TIME" /> mit Ihrer Synchronisierungspassphrase verschlüsselt. Geben Sie diese ein, um die Synchronisierung zu starten.</translation>
<translation id="3320021301628644560">Rechnungsadresse hinzufügen</translation>
<translation id="3324983252691184275">Purpur</translation>
<translation id="3338095232262050444">Sicher</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;Bearbeiten wiederholen</translation>
<translation id="342781501876943858">Chromium empfiehlt, Ihr Passwort zurückzusetzen, wenn Sie es auf anderen Websites verwendet haben.</translation>
<translation id="3431636764301398940">Diese Karte für dieses Gerät speichern</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Der Eigentümer dieses Geräts hat das Dinosaurier-Spiel deaktiviert.</translation>
<translation id="3447884698081792621">Zertifikat anzeigen (ausgestellt von <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Abrufintervall:</translation>
+<translation id="3456231139987291353">Number-11 (Umschlag)</translation>
<translation id="3461824795358126837">Textmarker</translation>
<translation id="3462200631372590220">Erweiterte Informationen ausblenden</translation>
<translation id="3467763166455606212">Name des Karteninhabers erforderlich</translation>
@@ -429,19 +472,22 @@
<translation id="358285529439630156">Kredit- und Prepaidkarten werden akzeptiert.</translation>
<translation id="3582930987043644930">Namen hinzufügen</translation>
<translation id="3583757800736429874">&amp;Verschieben wiederholen</translation>
+<translation id="35866233670761917">Die Inhalte der von Ihnen besuchten Websites können nicht von den Administratoren eingesehen werden</translation>
<translation id="3586931643579894722">Details ausblenden</translation>
+<translation id="3592413004129370115">Italian (Umschlag)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Größe 2</translation>
<translation id="3615877443314183785">Geben Sie ein gültiges Ablaufdatum ein</translation>
<translation id="36224234498066874">Browserdaten löschen...</translation>
<translation id="362276910939193118">Gesamtverlauf anzeigen</translation>
-<translation id="3623476034248543066">Wert zeigen</translation>
<translation id="3630155396527302611">Falls das Programm schon in der Liste mit erlaubtem Netzwerkzugriff eingetragen ist, entfernen Sie es aus der Liste und fügen Sie es noch einmal hinzu.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Überprüfung erfolgreich</translation>
<translation id="3655670868607891010">Sollte Ihnen diese Meldung häufiger angezeigt werden, sehen Sie sich unsere <ph name="HELP_LINK" /> an.</translation>
<translation id="3658742229777143148">Überarbeitung</translation>
<translation id="366077651725703012">Kreditkarte aktualisieren</translation>
<translation id="3676592649209844519">Geräte-ID:</translation>
+<translation id="3677008721441257057">Meinten Sie vielleicht &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Anfrage konnte nicht signiert werden</translation>
<translation id="3678529606614285348">Seite in einem neuen Inkognitofenster öffnen (Strg + Umschalttaste + N)</translation>
<translation id="3679803492151881375">Absturz am <ph name="CRASH_TIME" /> erfasst und am <ph name="UPLOAD_TIME" /> hochgeladen</translation>
@@ -449,13 +495,14 @@
<translation id="3704162925118123524">Eventuell müssen Sie die Anmeldeseite des verwendeten Netzwerks aufrufen.</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="3709599264800900598">Von Ihnen kopierter Text</translation>
<translation id="3712624925041724820">Lizenzen aufgebraucht</translation>
<translation id="3714780639079136834">Mobile Daten oder WLAN aktivieren</translation>
<translation id="3715597595485130451">WLAN-Verbindung herstellen</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Proxy, Firewall und DNS-Konfiguration prüfen<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Anwendungen, die diesen Fehler verursachen können, sind Antivirensoftware, Firewalls, Webfilter- oder Proxy-Software.</translation>
+<translation id="373042150751172459">B4 (Umschlag)</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 mir 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="3745099705178523657">Nach erfolgter Bestätigung werden die Kartendetails Ihres Google-Kontos an diese Website weitergegeben.</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örtern, Telefonnummern oder Kreditkartendetails zu bewegen. <ph name="BEGIN_LEARN_MORE_LINK" />Weitere Informationen<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -468,10 +515,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Ablaufdatum: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Größe 16</translation>
+<translation id="3797522431967816232">Prc3 (Umschlag)</translation>
<translation id="3807873520724684969">Schädliche Inhalte blockiert.</translation>
<translation id="3810973564298564668">Verwalten</translation>
<translation id="382518646247711829">Falls Sie einen Proxyserver verwenden...</translation>
<translation id="3828924085048779000">Eine leere Passphrase ist nicht zulässig.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> hat Erweiterungen für zusätzliche Funktionen installiert. Diese Erweiterungen können auf einige Ihrer Daten zugreifen.</translation>
<translation id="385051799172605136">Zurück</translation>
<translation id="3858027520442213535">Datum und Uhrzeit aktualisieren</translation>
<translation id="3884278016824448484">In Konflikt stehende Gerätekennung</translation>
@@ -479,6 +528,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> – <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Auf dieser Website immer fragen</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>
@@ -489,11 +539,13 @@
<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="3984550557525787191">Dieser Sitzungsname existiert bereits.</translation>
<translation id="3987940399970879459">Weniger als 1 MB</translation>
+<translation id="4008849406247176967">Warnung: Für diese Richtlinie sind mehrere Quellen mit in Konflikt stehenden Werten vorhanden.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 Webseite in der Nähe}other{# Webseiten in der Nähe}}</translation>
<translation id="4030383055268325496">&amp;Hinzufügen rückgängig machen</translation>
+<translation id="4032320456957708163">Ihr Browser wird von <ph name="ENROLLMENT_DOMAIN" /> verwaltet</translation>
<translation id="4058922952496707368">Schlüssel "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Umschlag)</translation>
<translation id="4067947977115446013">Gültige Adresse hinzufügen</translation>
<translation id="4072486802667267160">Bei der Verarbeitung Ihrer Bestellung ist ein Fehler aufgetreten. Bitte versuchen Sie es noch einmal.</translation>
<translation id="4075732493274867456">Client und Server unterstützen keine gemeinsame SSL-Protokollversion oder Verschlüsselungssammlung.</translation>
@@ -513,10 +565,12 @@
<translation id="4159784952369912983">Lila</translation>
<translation id="4165986682804962316">Website-Einstellungen</translation>
<translation id="4171400957073367226">Ungültige Bestätigungssignatur</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> weiteres Element}other{<ph name="ITEM_COUNT" /> weitere Elemente}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Umschlag)</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="4221630205957821124">&lt;h4&gt;Schritt 1: Beim Portal anmelden&lt;/h4&gt;
@@ -548,58 +602,79 @@
<translation id="4277028893293644418">Passwort zurücksetzen</translation>
<translation id="4280429058323657511">Gültig bis: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Diese Karte wurde in Ihrem Google-Konto gespeichert}other{Diese Karten wurden in Ihrem Google-Konto gespeichert}}</translation>
+<translation id="42981349822642051">Maximieren</translation>
+<translation id="4302965934281694568">Chou3 (Umschlag)</translation>
<translation id="4305817255990598646">Wechseln</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blockieren (Standardeinstellung)</translation>
+<translation id="4318566738941496689">Gerätename und Netzwerkadresse</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="4340982228985273705">Dieser Computer wird nicht als von einem Unternehmen verwaltet erkannt, sodass nur Erweiterungen, die im Chrome Web Store gehostet sind, automatisch durch die Richtlinie installiert werden können. Die Update-URL des Chrome Web Store lautet "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Akzeptierte Kreditkarten</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Zahlungsmethoden verwalten…</translation>
+<translation id="4367563149485757821">Number-12 (Umschlag)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">Suchergebnisse</translation>
-<translation id="4406972042435603828">Ihre Administratoren haben Erweiterungen mit leistungsstarken Funktionen installiert.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Abholadresse</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="443121186588148776">Serieller Port</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> hat Ihr Anmeldezertifikat nicht akzeptiert oder es wurde keines bereitgestellt.</translation>
<translation id="4434045419905280838">Pop-ups und Weiterleitungen</translation>
+<translation id="4435702339979719576">Postkarte)</translation>
<translation id="443673843213245140">Die Proxy-Nutzung ist deaktiviert, es ist jedoch eine explizite Proxy-Konfiguration festgelegt.</translation>
<translation id="445100540951337728">Akzeptierte Debitkarten</translation>
+<translation id="4466881336512663640">Änderungen im Formular gehen verloren. Möchten Sie den Vorgang wirklich fortsetzen?</translation>
<translation id="4482953324121162758">Diese Website wird nicht übersetzt.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Ungültige URL. Dies muss eine URL mit einem Standardschema sein, z. B. "http://example.com" oder "https://example.com".</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Umschlag)</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="4517607026994743406">Comm-10 (Umschlag)</translation>
<translation id="4522570452068850558">Details</translation>
<translation id="4524805452350978254">Karten verwalten</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Deaktivieren Sie Ihre Erweiterungen.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Lieferung</translation>
+<translation id="4579056131138995126">Personal (Umschlag)</translation>
<translation id="4582204425268416675">Karte entfernen</translation>
<translation id="4587425331216688090">Adresse aus Chrome entfernen?</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="4597348597567598915">Größe 8</translation>
+<translation id="4600854749408232102">C6/C5 (Umschlag)</translation>
<translation id="4646534391647090355">Jetzt aufrufen</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="467809019005607715">Google Präsentationen</translation>
<translation id="4690462567478992370">Ungültiges Zertifikat nicht mehr verwenden</translation>
+<translation id="4691835149146451662">Architecture-A (Umschlag)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Die Verbindung wurde unterbrochen</translation>
<translation id="471880041731876836">Sie sind nicht berechtigt, auf diese Website zuzugreifen</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows-Netzwerkdiagnose ausführen<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Richtlinien neu laden</translation>
<translation id="4728558894243024398">Plattform</translation>
+<translation id="4731967714531604179">Prc2 (Umschlag)</translation>
<translation id="4736825316280949806">Chromium neu starten</translation>
<translation id="473775607612524610">Aktualisieren</translation>
<translation id="4738601419177586157">Suchvorschlag: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Passwörter verwalten…</translation>
<translation id="4744603770635761495">Ausführbarer Pfad</translation>
+<translation id="4746351372139058112">Nachrichten</translation>
<translation id="4750917950439032686">Ihre Daten wie Passwörter oder Kreditkartennummern sind privat, wenn Sie sie an diese Website senden.</translation>
<translation id="4756388243121344051">&amp;Verlauf</translation>
<translation id="4758311279753947758">Kontaktdaten hinzufügen</translation>
@@ -607,9 +682,9 @@
<translation id="4764776831041365478">Die Webseite unter <ph name="URL" /> ist eventuell vorübergehend nicht verfügbar oder wurde dauerhaft an eine neue Webadresse verschoben.</translation>
<translation id="4771973620359291008">Ein unbekannter Fehler ist aufgetreten.</translation>
<translation id="4785689107224900852">Zu diesem Tab wechseln</translation>
-<translation id="4792143361752574037">Beim Zugreifen auf die Sitzungsdateien ist ein Problem aufgetreten. Momentan können keine Dateien auf der Festplatte gespeichert werden. Bitte laden Sie die Seite neu und versuchen Sie es noch einmal.</translation>
<translation id="4798078619018708837">Geben Sie das Ablaufdatum und die Kartenprüfnummer (CVC) für <ph name="CREDIT_CARD" /> ein, um Ihre Kartendetails zu aktualisieren. Nach erfolgter Bestätigung werden die Kartendetails Ihres Google-Kontos an diese Website weitergegeben.</translation>
<translation id="4800132727771399293">Prüfen Sie Ihr Ablaufdatum und Ihren CVC und versuchen Sie es dann erneut.</translation>
+<translation id="480334179571489655">Fehler bezüglich Ursprungsrichtlinie</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>
@@ -624,7 +699,6 @@
<translation id="4881695831933465202">Öffnen</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>
@@ -633,15 +707,15 @@
<translation id="4943872375798546930">Keine Ergebnisse</translation>
<translation id="4950898438188848926">Schaltfläche zum Wechseln von Tabs, Eingabetaste drücken, um zum offenen Tab "<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />" zu wechseln</translation>
<translation id="495170559598752135">Aktionen</translation>
-<translation id="495832697253704892">Berichte zu Erweiterungen</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Liste einblenden</translation>
<translation id="4974590756084640048">Warnmeldungen wieder aktivieren</translation>
+<translation id="4984339528288761049">Prc5 (Umschlag)</translation>
<translation id="4989163558385430922">Alle ansehen</translation>
<translation id="4989809363548539747">Dieses Plug-in wird nicht unterstützt</translation>
-<translation id="4996230189582812866">Berichte</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="5014174725590676422">Bildschirm für die erste Ausführung von Google Assistant für Chrome wird angezeigt</translation>
<translation id="5015510746216210676">Computername:</translation>
+<translation id="5017554619425969104">Von Ihnen kopierter Text</translation>
<translation id="5018422839182700155">Diese Seite kann nicht geöffnet werden</translation>
<translation id="5019198164206649151">Sicherungsspeicher ist fehlerhaft.</translation>
<translation id="5023310440958281426">Informieren Sie sich über die von Ihrem Administrator festgelegten Richtlinien.</translation>
@@ -651,35 +725,51 @@
<translation id="5034369478845443529">Lokaler Kontext: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Zulassen</translation>
<translation id="5040262127954254034">Datenschutz</translation>
+<translation id="5043480802608081735">Von Ihnen kopierter Link</translation>
<translation id="5045550434625856497">Falsches Passwort</translation>
<translation id="5056549851600133418">Artikel für mich</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Proxyadresse prüfen<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Das Serverzertifikat ist zurzeit ungültig.</translation>
<translation id="5087580092889165836">Karte hinzufügen</translation>
<translation id="5089810972385038852">Bundesstaat</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="5097099694988056070">Gerätestatistiken, z. B. CPU/RAM-Nutzung</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Ihr Gerät wird durch <ph name="ENROLLMENT_DOMAIN" /> und Ihr Konto durch <ph name="ACCOUNT_DOMAIN" /> verwaltet. Das bedeutet, dass die Administratoren Ihr Gerät und Ihr Konto per Remotezugriff konfigurieren können.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-Bit)</translation>
-<translation id="5128122789703661928">Die Sitzung mit diesem Namen kann nicht gelöscht werden.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Adressen verwalten…</translation>
+<translation id="5138227688689900538">Weniger anzeigen</translation>
<translation id="5141240743006678641">Synchronisierte Passwörter mit Ihren Google-Anmeldeinformationen verschlüsseln</translation>
<translation id="5145883236150621069">Fehlercode in der Richtlinienantwort</translation>
+<translation id="515292512908731282">C4 (Umschlag)</translation>
<translation id="5159010409087891077">Seite in einem neuen Inkognitofenster öffnen (⇧⌘N)</translation>
<translation id="516920405563544094">Geben Sie die Kartenprüfnummer (CVC) für <ph name="CREDIT_CARD" /> ein. Nach erfolgter Bestätigung werden die Kartendetails Ihres Google-Kontos an diese Website weitergegeben.</translation>
<translation id="5169827969064885044">Sie könnten den Zugriff auf das Konto Ihres Unternehmens verlieren oder zum Opfer von Identitätsdiebstahl werden. Chrome empfiehlt Ihnen, Ihr Passwort jetzt zu ändern.</translation>
<translation id="5171045022955879922">Suchen oder URL eingeben</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Computer</translation>
<translation id="5179510805599951267">Nicht auf <ph name="ORIGINAL_LANGUAGE" />? Diesen Fehler melden</translation>
<translation id="5190835502935405962">Lesezeichenleiste</translation>
-<translation id="5200263511887412697">erstellt eine Liste der Gerätenutzer, die sich kürzlich angemeldet haben</translation>
+<translation id="519422657042045905">Anmerkungsmodus nicht verfügbar</translation>
<translation id="5201306358585911203">Auf einer in dieser Seite eingebetteten Seite wird Folgendes angezeigt</translation>
<translation id="5205222826937269299">Name erforderlich</translation>
<translation id="5215116848420601511">Bei Google Pay gespeicherte Zahlungsmethoden und Adressen</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-Mail-Adresse erforderlich</translation>
<translation id="5230733896359313003">Versandadresse</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Mit Netzwerk verbinden"</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Umschlag)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Netzwerkadressen</translation>
<translation id="5285570108065881030">Alle gespeicherten Passwörter anzeigen</translation>
<translation id="5287240709317226393">Cookies anzeigen</translation>
<translation id="5288108484102287882">Die Validierung der Richtlinienwerte hat Warnungen ergeben</translation>
@@ -691,7 +781,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> von <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Kontaktdaten auswählen</translation>
<translation id="5327248766486351172">Name</translation>
+<translation id="5329858041417644019">Ihr Browser wird nicht verwaltet</translation>
<translation id="5332219387342487447">Versandart</translation>
+<translation id="5334013548165032829">Detaillierte Systemprotokolle</translation>
<translation id="5344579389779391559">Auf dieser Seite wird möglicherweise versucht, Ihnen etwas in Rechnung zu stellen</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>
@@ -699,6 +791,7 @@
<translation id="5377026284221673050">"Ihre Uhr geht nach", "Ihre Uhr geht vor" oder "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Wenn Sie Ihre Karten auf allen Geräten verwenden möchten, melden Sie sich an und aktivieren Sie die Synchronisierung.</translation>
<translation id="5386426401304769735">Die Zertifikatskette für diese Website enthält ein Zertifikat mit SHA-1-Signatur.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -709,6 +802,7 @@
<translation id="5457113250005438886">Ungültig</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Bearbeiten wiederholen</translation>
+<translation id="5478437291406423475">B6/C4 (Umschlag)</translation>
<translation id="5481076368049295676">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="54817484435770891">Gültige Adresse hinzufügen</translation>
<translation id="5490432419156082418">AutoFill-Einstellungen</translation>
@@ -716,10 +810,12 @@
<ph name="LINE_BREAK" />
Wenden Sie sich an Ihren Systemadministrator.</translation>
<translation id="549333378215107354">Größe 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Verwaltete Lesezeichen</translation>
<translation id="5510766032865166053">Eventuell wurde sie verschoben oder gelöscht.</translation>
<translation id="5523118979700054094">Richtlinienname</translation>
<translation id="552553974213252141">Wurde der Text korrekt extrahiert?</translation>
+<translation id="553484882784876924">Prc6 (Umschlag)</translation>
<translation id="5540224163453853">Der gewünschte Artikel wurde nicht gefunden.</translation>
<translation id="5541546772353173584">E-Mail-Adresse hinzufügen</translation>
<translation id="5545756402275714221">Artikel für mich</translation>
@@ -734,15 +830,21 @@
<translation id="5595485650161345191">Adresse bearbeiten</translation>
<translation id="5598944008576757369">Zahlungsmethode auswählen</translation>
<translation id="560412284261940334">Verwaltung wird nicht unterstützt.</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> hat Sie zu oft weitergeleitet.</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="5632627355679805402">Ihre Daten sind seit dem <ph name="TIME" /> mit Ihrem <ph name="BEGIN_LINK" />Google-Passwort<ph name="END_LINK" /> verschlüsselt. Geben Sie dieses ein, um die Synchronisierung zu starten.</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="563324245173044180">Betrügerische Inhalte blockiert.</translation>
<translation id="5659593005791499971">E-Mail-Adresse</translation>
+<translation id="5663614846592581799">9x11 (Umschlag)</translation>
+<translation id="5663955426505430495">Der Administrator dieses Geräts hat Erweiterungen für zusätzliche Funktionen installiert. Diese Erweiterungen können auf einige Ihrer Daten zugreifen.</translation>
<translation id="5675650730144413517">Diese Seite funktioniert nicht</translation>
+<translation id="5684874026226664614">Hoppla! Diese Seite konnte nicht übersetzt werden.</translation>
<translation id="5685654322157854305">Versandadresse hinzufügen</translation>
<translation id="5689199277474810259">Als JSON exportieren</translation>
<translation id="5689516760719285838">Ort</translation>
@@ -751,38 +853,39 @@
<translation id="5710435578057952990">Die Identität dieser Website wurde nicht verifiziert.</translation>
<translation id="5719499550583120431">Prepaidkarten werden akzeptiert.</translation>
<translation id="5720705177508910913">Aktueller Nutzer</translation>
+<translation id="5728056243719941842">C5 (Umschlag)</translation>
<translation id="5730040223043577876">Chrome empfiehlt, Ihr Passwort zurückzusetzen, wenn Sie es auf anderen Websites verwendet haben.</translation>
<translation id="5732392974455271431">Deine Eltern können die Blockierung aufheben</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Karte in Ihrem Google-Konto speichern}other{Karten in Ihrem Google-Konto speichern}}</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="5770114862687765385">Die Datei scheint beschädigt zu sein. Klicken Sie auf die Schaltfläche "Zurücksetzen", um die Sitzung zurückzusetzen.</translation>
<translation id="5778550464785688721">MIDI-Geräte: volle Kontrolle</translation>
<translation id="578305955206182703">Bernsteingelb</translation>
<translation id="57838592816432529">Stummschalten</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>
+<translation id="5798290721819630480">Änderungen verwerfen?</translation>
<translation id="5798683403665926540">Startseite in den Chrome-Einstellungen ändern</translation>
<translation id="5803412860119678065">Möchten Sie die Daten Ihrer <ph name="CARD_DETAIL" /> eingeben?</translation>
<translation id="5804241973901381774">Berechtigungen</translation>
<translation id="5810442152076338065">Ihre Verbindung zu <ph name="DOMAIN" /> ist mit einer veralteten Codier-Suite verschlüsselt.</translation>
<translation id="5813119285467412249">&amp;Hinzufügen wiederholen</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="5860033963881614850">Aus</translation>
<translation id="5863847714970149516">Auf der nächsten Seite wird möglicherweise versucht, Ihnen etwas in Rechnung zu stellen</translation>
<translation id="5866257070973731571">Telefonnummer hinzufügen</translation>
<translation id="5869405914158311789">Die Website ist nicht erreichbar</translation>
<translation id="5869522115854928033">Gespeicherte Passwörter</translation>
<translation id="5887400589839399685">Karte gespeichert</translation>
-<translation id="5893718151540690985">meldet eine Liste der Netzwerkschnittstellen mit deren Typen und Hardwareadressen</translation>
<translation id="5893752035575986141">Kreditkarten werden akzeptiert.</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="5916664084637901428">An</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Karte im Google-Konto speichern?</translation>
<translation id="5922853866070715753">Fast fertig</translation>
<translation id="5932224571077948991">Website zeigt aufdringliche oder irreführende Werbung an</translation>
-<translation id="5939518447894949180">Zurücksetzen</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> wird geöffnet…</translation>
<translation id="5951495562196540101">Registrierung mit Kundenkonto nicht möglich (Paketlizenz verfügbar).</translation>
<translation id="5967592137238574583">Kontaktdaten bearbeiten</translation>
@@ -790,6 +893,7 @@
<translation id="5975083100439434680">Verkleinern</translation>
<translation id="5977489021191000276">Ihr Gerät wird nicht von einem Administrator verwaltet.</translation>
<translation id="5977976211062815271">Auf diesem Gerät</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Fehler beim Öffnen der Zahlungs-App</translation>
<translation id="5989320800837274978">Weder feste Proxyserver noch eine PAC-Skript-URL sind festgelegt.</translation>
<translation id="5990559369517809815">Anfragen an den Server wurden durch eine Erweiterung blockiert.</translation>
@@ -800,8 +904,8 @@
<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 erfassen, 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="6033927989869462158">meldet Hardwarestatistiken wie die CPU/RAM-Nutzung</translation>
<translation id="6034000775414344507">Hellgrau</translation>
+<translation id="6034283069659657473">10x14 (Umschlag)</translation>
<translation id="6039846035001940113">Falls das Problem weiterhin besteht, wenden Sie sich an den Inhaber der Website.</translation>
<translation id="6040143037577758943">Schließen</translation>
<translation id="6044573915096792553">Größe 12</translation>
@@ -810,10 +914,10 @@
<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="6058977677006700226">Karten auf allen Ihren Geräten nutzen?</translation>
<translation id="6059925163896151826">USB-Geräte</translation>
-<translation id="6071091556643036997">Der Richtlinientyp ist ungültig.</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="6094273045989040137">Anmerkung hinzufügen</translation>
<translation id="610911394827799129">Unter <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> sind möglicherweise weitere Arten von Browserverlaufsdaten für Ihr Google-Konto gespeichert.</translation>
+<translation id="6132597952260690497">Informationen zu installierten Erweiterungen und Plug-ins</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>
@@ -848,15 +952,21 @@
<translation id="6337133576188860026">Es werden weniger als <ph name="SIZE" /> Speicherplatz freigegeben. Manche Websites werden beim nächsten Öffnen eventuell langsamer geladen.</translation>
<translation id="6337534724793800597">Richtlinien nach Name filtern</translation>
<translation id="6358450015545214790">Was bedeuten diese Hinweise?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Warnung vor möglichen Kosten.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 weiterer Vorschlag}other{# weitere Vorschläge}}</translation>
<translation id="6387754724289022810">Damit Zahlungen zukünftig schneller abgewickelt werden können, speichern Sie Ihre Kreditkartendaten und Ihre Rechnungsadresse in Ihrem Google-Konto und auf diesem Gerät.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Lesezeichen bearbeiten</translation>
+<translation id="6406765186087300643">C0 (Umschlag)</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="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="6434309073475700221">Verwerfen</translation>
+<translation id="6446163441502663861">Kahu (Umschlag)</translation>
<translation id="6446608382365791566">Weitere Informationen hinzufügen</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Erneute Formular-Übermittlung bestätigen</translation>
@@ -869,11 +979,17 @@
<translation id="6508722015517270189">Chrome neu starten</translation>
<translation id="6529602333819889595">&amp;Löschen wiederholen</translation>
<translation id="6534179046333460208">Physical Web-Vorschläge</translation>
+<translation id="6556866813142980365">Wiederholen</translation>
<translation id="6563469144985748109">Der Administrator hat die Berechtigung noch nicht erteilt</translation>
<translation id="6569060085658103619">Dies ist eine Erweiterungsseite</translation>
+<translation id="6578796323535178455">C2 (Umschlag)</translation>
<translation id="6579990219486187401">Hellrosa</translation>
+<translation id="6583674473685352014">B6 (Umschlag)</translation>
+<translation id="6587923378399804057">Von Ihnen kopierter Link</translation>
+<translation id="6591833882275308647">Ihr <ph name="DEVICE_TYPE" /> wird nicht verwaltet</translation>
<translation id="6596325263575161958">Verschlüsselungsoptionen</translation>
<translation id="6604181099783169992">Bewegungs- oder Lichtsensoren</translation>
+<translation id="6609880536175561541">Prc7 (Umschlag)</translation>
<translation id="6624427990725312378">Kontaktdaten</translation>
<translation id="6626291197371920147">Gültige Kartennummer hinzufügen</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />-Suche</translation>
@@ -882,6 +998,7 @@
<translation id="6644283850729428850">Diese Richtlinie ist veraltet.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Keine}=1{1 Website (Anmeldung in Google-Konto bleibt erhalten)}other{# Websites (Anmeldung in Google-Konto bleibt erhalten)}}</translation>
<translation id="6657585470893396449">Passwort</translation>
+<translation id="6670613747977017428">Zurück zu sicherer Website.</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>
@@ -889,12 +1006,15 @@
<translation id="671076103358959139">Registrierungstoken:</translation>
<translation id="6711464428925977395">Mit dem Proxyserver ist ein Problem aufgetreten oder die Adresse ist falsch.</translation>
<translation id="6723740634201835758">Im Google-Konto</translation>
+<translation id="6738516213925468394">Ihre Daten wurden am <ph name="TIME" /> mit Ihrer <ph name="BEGIN_LINK" />Synchronisierungspassphrase<ph name="END_LINK" /> verschlüsselt. Geben Sie diese ein, um die Synchronisierung zu starten.</translation>
<translation id="674375294223700098">Fehler wegen unbekanntem Serverzertifikat</translation>
<translation id="6744009308914054259">Während Sie auf eine Verbindung warten, können Sie "Downloads" aufrufen und Offline-Artikel lesen.</translation>
<translation id="6753269504797312559">Wert der Richtlinie</translation>
<translation id="6757797048963528358">Ihr Gerät ist im Ruhemodus.</translation>
+<translation id="6768213884286397650">Hagaki (Postkarte)</translation>
<translation id="6778737459546443941">Dein Elternteil hat die Berechtigung noch nicht erteilt</translation>
<translation id="67862343314499040">Violett</translation>
+<translation id="6786747875388722282">Erweiterungen</translation>
<translation id="679355240208270552">Ignoriert, da die Standardsuchmaschine durch die Richtlinie deaktiviert ist.</translation>
<translation id="681021252041861472">Pflichtfeld</translation>
<translation id="6810899417690483278">Personalisierungs-ID</translation>
@@ -923,14 +1043,16 @@
<translation id="6957624206566198865">Seite in Inkognito-Fenster öffnen</translation>
<translation id="6957887021205513506">Das Zertifikat des Servers ist möglicherweise eine Fälschung.</translation>
<translation id="6964255747740675745">Netzwerkkonfiguration konnte nicht geparst werden (ungültige JSON-Datei).</translation>
-<translation id="6965382102122355670">OK</translation>
+<translation id="6965382102122355670">Ok</translation>
<translation id="6965978654500191972">Gerät</translation>
<translation id="6970216967273061347">Bezirk</translation>
<translation id="6973656660372572881">Sowohl feste Proxyserver als auch eine PAC-Skript-URL sind festgelegt.</translation>
+<translation id="6973932557599545801">Ich kann Ihnen leider nicht helfen. Bitte fahren Sie alleine fort.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Stummschalten (Standard)</translation>
<translation id="6984479912851154518">Der private Modus wird beendet, um über eine externe Anwendung zu zahlen. Weiter?</translation>
<translation id="6989763994942163495">Erweiterte Einstellungen anzeigen</translation>
+<translation id="6993898126790112050">6x9 (Umschlag)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> immer übersetzen</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Diese Belastungen können einmalig oder wiederkehrend sein und sind vielleicht nicht offensichtlich.</translation>
@@ -946,28 +1068,33 @@
<translation id="7108338896283013870">Ausblenden</translation>
<translation id="7108819624672055576">Von einer Erweiterung zugelassen</translation>
<translation id="7111012039238467737">(Gültig)</translation>
+<translation id="7118618213916969306">Nach URL aus Zwischenablage suchen, <ph name="SHORT_URL" /></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="7135130955892390533">Status anzeigen</translation>
<translation id="7138472120740807366">Lieferoption</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (Umschlag)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendel</translation>
-<translation id="7158980942472052083">Ungültige URL. Dies muss eine URL mit einem Standardschema sein.</translation>
<translation id="717330890047184534">GAIA-ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Der Server <ph name="ORIGIN" />, zu dem Sie gehen, verlangt, dass auf alle an ihn gerichteten Anfragen eine Sicherheitsrichtlinie angewendet wird. Aber statt eine Richtlinie bereitzustellen, hat er den Browser weitergeleitet, was den Browser daran hindert, Ihre Anfrage für <ph name="SITE" /> auszuführen.</translation>
<translation id="7179323680825933600">Zahlungsmethoden speichern und ausfüllen</translation>
<translation id="7180611975245234373">Aktualisieren</translation>
<translation id="7182878459783632708">Keine Richtlinien festgelegt</translation>
<translation id="7186367841673660872">Diese Seite wurde von<ph name="ORIGINAL_LANGUAGE" />in<ph name="LANGUAGE_LANGUAGE" />übersetzt.</translation>
<translation id="7192203810768312527">Freigabe von <ph name="SIZE" /> Speicherplatz. Manche Websites werden beim nächsten Öffnen eventuell langsamer geladen.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Ihr Administrator hat Zugriff auf:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> erfüllt die Sicherheitsstandards nicht.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /> zu diesem Problem.</translation>
<translation id="7219179957768738017">Die Verbindung verwendet <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Verarbeitung läuft</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Malware auf nachfolgender Website</translation>
+<translation id="724766306220616965">Warnmeldungen, Konflikte</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="7251437084390964440">Die Netzwerkkonfiguration entspricht nicht dem ONC-Standard. Die Konfiguration wird unter Umständen nicht vollständig importiert.
Weitere Details:
@@ -980,11 +1107,14 @@ Weitere Details:
<translation id="7300012071106347854">Kobaltblau</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Absturzbericht erfasst: <ph name="CRASH_TIME" /> (Upload wurde vom Nutzer angefordert, aber noch nicht abgeschlossen)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" />-Warnmeldungen</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Hilfe bei der Verbindungsherstellung</translation>
<translation id="7334320624316649418">&amp;Neu anordnen wiederholen</translation>
<translation id="733923710415886693">Das Serverzertifikat wurde nicht über die Zertifikatstransparenz offengelegt.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Befehlszeile</translation>
-<translation id="7365061714576910172">Im Linux-Format exportieren</translation>
<translation id="7372973238305370288">Suchergebnis</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nein</translation>
@@ -992,6 +1122,7 @@ Weitere Details:
<translation id="7381288752349550461">Überschreibung verwalteter Sitzung</translation>
<translation id="7390545607259442187">Karte bestätigen</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Ihr <ph name="DEVICE_NAME" /> wird verwaltet</translation>
<translation id="7407424307057130981">&lt;p&gt;Sie erhalten diese Fehlermeldung, wenn auf Ihrem Windows-Computer Superfish-Software installiert ist.&lt;/p&gt;
&lt;p&gt;Gehen Sie folgendermaßen vor, um die Software vorübergehend zu deaktivieren und auf das Web zuzugreifen. Wenn Sie die Software deaktivieren möchten, benötigen Sie Administratorrechte.&lt;/p&gt;
&lt;ol&gt;
@@ -999,10 +1130,10 @@ Weitere Details:
&lt;li&gt;Wählen Sie &lt;strong&gt;VisualDiscovery&lt;/strong&gt; aus.
&lt;li&gt;Wählen Sie unter &lt;strong&gt;Starttyp&lt;/strong&gt; die Option &lt;strong&gt;Deaktiviert&lt;/strong&gt; aus.
&lt;li&gt;Klicken Sie unter &lt;strong&gt;Dienststatus&lt;/strong&gt; auf &lt;strong&gt;Beenden&lt;/strong&gt;.
- &lt;li&gt;Klicken Sie auf &lt;strong&gt;Übernehmen&lt;/strong&gt; und dann auf &lt;strong&gt;OK&lt;/strong&gt;.
+ &lt;li&gt;Klicken Sie auf &lt;strong&gt;Übernehmen&lt;/strong&gt; und dann auf &lt;strong&gt;Ok&lt;/strong&gt;.
&lt;li&gt;In der &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome-Hilfe&lt;/a&gt; finden Sie eine Anleitung dazu, wie Sie die Software von Ihrem Computer entfernen.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" />-Verwaltung</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Passwörter verwalten…</translation>
<translation id="7419106976560586862">Profilpfad</translation>
<translation id="7437289804838430631">Kontaktdaten hinzufügen</translation>
@@ -1011,22 +1142,24 @@ Weitere Details:
<translation id="7442725080345379071">Helles Orange</translation>
<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 Eigentümerschaft 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="7449109375006139765">Systemprotokolle an den Verwaltungsserver senden</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="7460618730930299168">Die Filmvorführung entspricht nicht Ihrer Auswahl. Möchten Sie fortfahren?</translation>
<translation id="7473891865547856676">Nein danke</translation>
-<translation id="7475525192983021547">meldet die Zeiträume, in denen ein Nutzer auf dem Gerät aktiv ist</translation>
<translation id="7481312909269577407">Vorwärts</translation>
<translation id="7485870689360869515">Keine Daten gefunden</translation>
+<translation id="7498234416455752244">Weiter bearbeiten</translation>
<translation id="7508255263130623398">Zurückgegebene Geräte-ID der Richtlinie ist leer oder entspricht nicht der aktuellen Geräte-ID</translation>
<translation id="7508870219247277067">Avocadogrün</translation>
<translation id="7511955381719512146">Unter Umständen erfordert das verwendete WLAN, dass Sie <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> aufrufen.</translation>
<translation id="7514365320538308">Herunterladen</translation>
<translation id="7518003948725431193">Für folgende Webadresse wurde keine Webseite gefunden: <ph name="URL" />.</translation>
+<translation id="7520302887438682816">C8 (Umschlag)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Die Verbindung zu dieser Website ist nicht sicher</translation>
+<translation id="7535087603100972091">Wert</translation>
<translation id="7537536606612762813">Verbindlich</translation>
+<translation id="7538364083937897561">A2 (Umschlag)</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>
@@ -1035,8 +1168,8 @@ Weitere Details:
<translation id="7552846755917812628">Probieren Sie folgende Tipps aus:</translation>
<translation id="7554791636758816595">Neuer Tab</translation>
<translation id="7564049878696755256">Sie könnten den Zugriff auf Ihr <ph name="ORG_NAME" />-Konto verlieren oder zum Opfer von Identitätsdiebstahl werden. Chrome empfiehlt Ihnen, Ihr Passwort jetzt zu ändern.</translation>
-<translation id="7566125604157659769">Von Ihnen kopierter Text</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="7568105740864181217">Dieser Browser wird von einem Unternehmen, einer Bildungseinrichtung oder einer anderen Organisation verwaltet. Ihr Administrator kann die Browsereinstellungen per Remotezugriff ändern. Aktivitäten auf diesem Gerät können auch außerhalb von Chrome verwaltet werden. <ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /></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>
@@ -1047,6 +1180,7 @@ Weitere Details:
<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="7633909222644580952">Leistungsdaten und Absturzberichte</translation>
<translation id="7637571805876720304">Kreditkarte aus Chromium entfernen?</translation>
<translation id="7639968568612851608">Dunkelgrau</translation>
<translation id="765676359832457558">Erweiterte Einstellungen ausblenden</translation>
@@ -1056,9 +1190,11 @@ Weitere Details:
<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="7676643023259824263">Nach Text aus Zwischenablage suchen: <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Suchmaschine ändern</translation>
<translation id="7682287625158474539">Versand</translation>
<translation id="7687186412095877299">Zahlungsformulare werden mit Ihren gespeicherten Zahlungsmethoden ausgefüllt</translation>
+<translation id="7697066736081121494">Prc8 (Umschlag)</translation>
<translation id="769721561045429135">Derzeit können bestimmte Karten nur auf diesem Gerät verwendet werden. Klicken Sie auf "Weiter", um sich die Karten anzusehen.</translation>
<translation id="7699293099605015246">Momentan sind keine Artikel verfügbar</translation>
<translation id="7701040980221191251">Keine</translation>
@@ -1070,11 +1206,13 @@ Weitere Details:
<translation id="774634243536837715">Gefährliche Inhalte blockiert.</translation>
<translation id="7752995774971033316">Nicht verwaltet</translation>
<translation id="7755287808199759310">Deine Eltern können die Blockierung aufheben</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Möglicherweise wurde die Verbindung von einer Firewall oder Antivirensoftware blockiert.</translation>
<translation id="7759163816903619567">Anzeigebereich</translation>
<translation id="7761701407923456692">Das Serverzertifikat stimmt nicht mit der URL überein.</translation>
<translation id="7763386264682878361">Zahlungsmanifest-Parser</translation>
<translation id="7764225426217299476">Adresse hinzufügen</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Präfektur</translation>
<translation id="7791543448312431591">Hinzufügen</translation>
<translation id="7793809570500803535">Die Webseite unter <ph name="SITE" /> ist möglicherweise vorübergehend nicht verfügbar oder dauerhaft unter einer neuen URL zu erreichen.</translation>
@@ -1086,8 +1224,8 @@ Weitere Details:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Vorschlag für das Formular aus Chrome entfernen?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> für "<ph name="SEARCH_STRING" />" gefunden</translation>
-<translation id="7818867226424560206">Richtlinienverwaltung</translation>
<translation id="782886543891417279">Unter Umständen müssen Sie die Anmeldeseite des verwendeten WLAN-Netzwerken (<ph name="WIFI_NAME" />) aufrufen.</translation>
+<translation id="7836231406687464395">Postfix (Umschlag)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Keine}=1{1 App (<ph name="EXAMPLE_APP_1" />)}=2{2 Apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# Apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Sie sind jedoch nicht unsichtbar. Der Inkognitomodus verhindert nicht, dass Informationen zu Ihren Webaktivitäten von Ihrem Arbeitgeber, Ihrem Internetanbieter oder den von Ihnen besuchten Websites erfasst werden.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1096,7 +1234,7 @@ Weitere Details:
<translation id="7878562273885520351">Ihr Passwort könnte gefährdet sein</translation>
<translation id="7882421473871500483">Braun</translation>
<translation id="7887683347370398519">Prüfen Sie Ihren CVC und versuchen Sie es dann erneut.</translation>
-<translation id="7893255318348328562">Sitzungsname</translation>
+<translation id="7904208859782148177">C3 (Umschlag)</translation>
<translation id="79338296614623784">Geben Sie eine gültige Telefonnummer ein</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Läuft am <ph name="EXPIRATION_DATE_ABBR" /> ab</translation>
@@ -1106,21 +1244,25 @@ Weitere Details:
<translation id="7951415247503192394">(32-Bit)</translation>
<translation id="7956713633345437162">Mobile Lesezeichen</translation>
<translation id="7961015016161918242">Nie</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Passwort verwalten</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Diese Karte und die entsprechende Rechnungsadresse werden gespeichert. Sie können sie nutzen, wenn Sie in <ph name="USER_EMAIL" /> angemeldet sind.}other{Diese Karten und die entsprechenden Rechnungsadressen werden gespeichert. Sie können sie nutzen, wenn Sie in <ph name="USER_EMAIL" /> angemeldet sind.}}</translation>
<translation id="8012647001091218357">Wir können deine Eltern momentan nicht erreichen. Bitte versuche es später noch einmal.</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="8034522405403831421">Diese Seite ist auf <ph name="SOURCE_LANGUAGE" />. In folgende Sprache übersetzen: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Stift</translation>
+<translation id="8037117624646282037">Nutzer, die das Gerät vor Kurzem verwendet haben</translation>
<translation id="8037357227543935929">Nachfragen (Standardeinstellung)</translation>
<translation id="803771048473350947">Datei</translation>
<translation id="8041089156583427627">Feedback geben</translation>
<translation id="8041940743680923270">Globalen Standard verwenden (Fragen)</translation>
<translation id="8042918947222776840">Abholoption auswählen</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" ist nicht ordnungsgemäß konfiguriert. Durch die Deinstallation von "<ph name="SOFTWARE_NAME" />" sollte das Problem behoben werden. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Ihr Gerät wurde so konfiguriert:</translation>
+<translation id="8066955247577885446">Ein Fehler ist aufgetreten.</translation>
+<translation id="8074253406171541171">10x13 (Umschlag)</translation>
<translation id="8078141288243656252">Anmerkungen bei gedrehtem Dokument nicht möglich</translation>
<translation id="8079031581361219619">Website neu laden?</translation>
<translation id="8088680233425245692">Der Artikel kann nicht angezeigt werden.</translation>
@@ -1129,11 +1271,12 @@ Weitere Details:
<translation id="8091372947890762290">Aktivierung auf dem Server steht noch aus.</translation>
<translation id="8092774999298748321">Dunkellila</translation>
<translation id="8094917007353911263">Unter Umständen erfordert das von Ihnen verwendete Netzwerk, dass Sie <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> aufrufen.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Die ungültigen Karten wurden entfernt</translation>
<translation id="8103161714697287722">Zahlungsmethode</translation>
<translation id="8118489163946903409">Zahlungsmethode</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> verwaltet von <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" war nicht ordnungsgemäß auf Ihrem Computer oder im Netzwerk installiert. Bitten Sie Ihren IT-Administrator, das Problem zu lösen.</translation>
-<translation id="8130693978878176684">Ich kann nicht mehr helfen. Bitte fahren Sie alleine fort.</translation>
<translation id="8131740175452115882">Bestätigen</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>
@@ -1143,8 +1286,11 @@ Weitere Details:
<translation id="8197543752516192074">Seite übersetzen</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (Umschlag)</translation>
<translation id="8211406090763984747">Verbindung ist sicher</translation>
<translation id="8218327578424803826">Zugewiesener Standort:</translation>
+<translation id="8220146938470311105">C7/C6 (Umschlag)</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="8238581221633243064">Seite in einem neuen Inkognito-Tab öffnen</translation>
@@ -1156,14 +1302,16 @@ Weitere Details:
<translation id="825929999321470778">Alle gespeicherten Passwörter anzeigen</translation>
<translation id="8261506727792406068">Löschen</translation>
<translation id="8267698848189296333">Als <ph name="USERNAME" /> anmelden</translation>
+<translation id="8278457561961988242">Dieser Browser wird von <ph name="ENROLLMENT_DOMAIN" /> verwaltet. Ihr Administrator kann die Browsereinstellungen per Remotezugriff ändern. Aktivitäten auf diesem Gerät können auch außerhalb von Chrome verwaltet werden. <ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Anmelden</translation>
<translation id="8288807391153049143">Zertifikat anzeigen</translation>
<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="8298115750975731693">Unter Umständen erfordert das verwendete WLAN (<ph name="WIFI_NAME" />), dass Sie <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> aufrufen.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Die Übersetzung ist aufgrund eines Problems mit der Netzwerkverbindung fehlgeschlagen.</translation>
-<translation id="8311129316111205805">Sitzung laden</translation>
<translation id="8332188693563227489">Der Zugriff auf <ph name="HOST_NAME" /> wurde verweigert</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1181,7 +1329,6 @@ Weitere Details:
<translation id="8416694386774425977">Die Netzwerkkonfiguration ist ungültig und konnte nicht importiert werden.
Weitere Details:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Gerät verwaltet durch <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" />, <ph name="SECOND_LABEL" />, <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Ändern</translation>
<translation id="8428213095426709021">Einstellungen</translation>
@@ -1209,9 +1356,11 @@ Weitere Details:
<translation id="860043288473659153">Name des Karteninhabers</translation>
<translation id="861775596732816396">Größe 4</translation>
<translation id="8620436878122366504">Deine Eltern haben die Berechtigung noch nicht erteilt</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Diese Karte für dieses Gerät speichern</translation>
<translation id="8663226718884576429">Bestellübersicht, <ph name="TOTAL_LABEL" />, weitere Details</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, Antwort, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Die Verbindung zu <ph name="DOMAIN" /> ist nicht verschlüsselt.</translation>
<translation id="8718314106902482036">Zahlung nicht abgeschlossen</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, Suchvorschlag</translation>
@@ -1225,6 +1374,7 @@ Weitere Details:
<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="8763927697961133303">USB-Gerät</translation>
<translation id="8768895707659403558">Karten auf allen Ihren Geräten nutzen: <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Löschen wiederholen</translation>
<translation id="8792621596287649091">Sie könnten den Zugriff auf Ihr <ph name="ORG_NAME" />-Konto verlieren oder zum Opfer von Identitätsdiebstahl werden. Chromium empfiehlt Ihnen, Ihr Passwort jetzt zu ändern.</translation>
<translation id="8800988563907321413">Hier werden Ihre Vorschläge in der Nähe angezeigt</translation>
@@ -1235,10 +1385,12 @@ Weitere Details:
<translation id="885730110891505394">Datenfreigabe an Google</translation>
<translation id="8858065207712248076">Chrome empfiehlt, Ihr Passwort für <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> zurückzusetzen, wenn Sie es auf anderen Websites verwendet haben.</translation>
<translation id="8866481888320382733">Fehler beim Parsen der Richtlinieneinstellungen</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Kürzlich geschlossen</translation>
<translation id="8874824191258364635">Geben Sie eine gültige Kartennummer ein</translation>
<translation id="8891727572606052622">Ungültiger Proxymodus</translation>
<translation id="8903921497873541725">Vergrößern</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Namen hinzufügen</translation>
@@ -1246,13 +1398,13 @@ Weitere Details:
<translation id="894185898663964645">Ihr Administrator hat benutzerdefinierte Root-Zertifikate konfiguriert, mit denen er unter Umständen die Inhalte der von Ihnen besuchten Websites sehen kann.</translation>
<translation id="8943282376843390568">Limone</translation>
<translation id="8957210676456822347">Erfassungsportal-Autorisierung</translation>
+<translation id="8966619695390250636">Meinten Sie dies?</translation>
<translation id="8968766641738584599">Karte speichern</translation>
<translation id="8971063699422889582">Das Serverzertifikat ist abgelaufen.</translation>
<translation id="8975012916872825179">Enthält Informationen wie Telefonnummern, E-Mail-Adressen und Lieferadressen</translation>
<translation id="8978053250194585037">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Phishingaktivitäten<ph name="END_LINK" /> auf <ph name="SITE" /> festgestellt. Phishingwebsites geben sich als andere Websites aus, um Sie zu täuschen.</translation>
<translation id="8983003182662520383">Bei Google Pay gespeicherte Zahlungsmethoden und Adressen</translation>
<translation id="8987927404178983737">Monat</translation>
-<translation id="8988408250700415532">Ein Fehler ist aufgetreten. Sie können Ihre Bestellung auf der Website abschließen.</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>
@@ -1262,6 +1414,7 @@ Weitere Details:
<translation id="9011424611726486705">Website-Einstellungen öffnen</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Ungültig)</translation>
<translation id="9035022520814077154">Sicherheitsfehler</translation>
<translation id="9038649477754266430">Vorhersagefunktion zum schnelleren Laden von Seiten verwenden
@@ -1274,11 +1427,11 @@ Weitere Details:
<translation id="9065745800631924235">"<ph name="TEXT" />" im Verlauf suchen</translation>
<translation id="9069693763241529744">Von einer Erweiterung blockiert</translation>
<translation id="9076283476770535406">Eventuell enthält sie nicht jugendfreie Inhalte</translation>
+<translation id="9076630408993835509">Dieser Browser wird nicht von einem Unternehmen oder einer anderen Organisation verwaltet. Aktivitäten auf diesem Gerät werden eventuell außerhalb von Chrome verwaltet. <ph name="BEGIN_LINK" />Weitere Informationen<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Weitere Informationen erforderlich</translation>
<translation id="9080712759204168376">Bestellübersicht</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>
<translation id="9106062320799175032">Rechnungsadresse hinzufügen</translation>
-<translation id="9110718169272311511">Google Assistant für Chrome ist unten auf dem Bildschirm verfügbar</translation>
<translation id="9114524666733003316">Karte wird bestätigt…</translation>
<translation id="9128870381267983090">Mit Netzwerk verbinden</translation>
<translation id="9137013805542155359">Original anzeigen</translation>
@@ -1287,6 +1440,7 @@ Weitere Details:
<translation id="9148507642005240123">&amp;Bearbeiten rückgängig machen</translation>
<translation id="9154194610265714752">Aktualisiert</translation>
<translation id="9157595877708044936">Einrichtung läuft...</translation>
+<translation id="9158625974267017556">C6 (Umschlag)</translation>
<translation id="9168814207360376865">Websites die Abfrage gespeicherter Zahlungsmethoden erlauben</translation>
<translation id="9169664750068251925">Auf dieser Website immer blockieren</translation>
<translation id="9170848237812810038">&amp;Rückgängig</translation>
@@ -1301,10 +1455,12 @@ Weitere Details:
<translation id="9219103736887031265">Bilder</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">Formular leeren</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Sie könnten den Zugriff auf Ihr Google-Konto verlieren. Chromium empfiehlt Ihnen, Ihr Passwort jetzt zu ändern. Sie werden dazu aufgefordert, sich anzumelden.</translation>
<translation id="939736085109172342">Neuer Ordner</translation>
<translation id="945855313015696284">Lesen Sie sich die unten stehenden Informationen durch und löschen Sie ungültige Karten</translation>
<translation id="951104842009476243">Akzeptierte Debit- und Prepaidkarten</translation>
+<translation id="958202389743790697">Gemäß der Sicherheitsrichtlinie von <ph name="ORIGIN" /> blockiert.</translation>
<translation id="962484866189421427">Dieser Inhalt könnte betrügerische Apps installieren, die scheinbar einem anderen Zweck dienen oder Daten erfassen, um Sie auszuspionieren. <ph name="BEGIN_LINK" />Trotzdem zeigen<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Offizieller Build</translation>
<translation id="973773823069644502">Lieferadresse hinzufügen</translation>
@@ -1313,6 +1469,7 @@ Weitere Details:
<translation id="984275831282074731">Zahlungsmethoden</translation>
<translation id="985199708454569384">&lt;p&gt;Diese Fehlermeldung wird angezeigt, wenn das Datum bzw. die Uhrzeit auf Ihrem Computer oder Mobilgerät nicht korrekt ist.&lt;/p&gt;
&lt;p&gt;Korrigieren Sie in den Geräteeinstellungen die Uhrzeit und das Datum, um den Fehler zu beheben.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Entwickler-Build</translation>
<translation id="989988560359834682">Adresse bearbeiten</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_el.xtb b/chromium/components/strings/components_strings_el.xtb
index 54e8981bccf..a08b489c0b8 100644
--- a/chromium/components/strings/components_strings_el.xtb
+++ b/chromium/components/strings/components_strings_el.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="el">
-<translation id="1005145902654145231">Η μετονομασία της περιόδου λειτουργίας απέτυχε.</translation>
<translation id="1008557486741366299">Όχι τώρα</translation>
<translation id="1010200102790553230">Φόρτωση σελίδας αργότερα</translation>
<translation id="1015730422737071372">Καταχωρίστε επιπλέον λεπτομέρειες</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">άγνωστο όνομα</translation>
<translation id="1050038467049342496">Κλείστε τις άλλες εφαρμογές</translation>
<translation id="1055184225775184556">&amp;Αναίρεση προσθήκης</translation>
+<translation id="1056898198331236512">Προειδοποίηση</translation>
<translation id="1058479211578257048">Αποθήκευση καρτών…</translation>
<translation id="10614374240317010">Δεν έχει αποθηκευθεί ποτέ</translation>
+<translation id="1062160989074299343">Prc10 (Φάκελος)</translation>
<translation id="106701514854093668">Σελιδοδείκτες επιτραπέζιου υπολογιστή</translation>
<translation id="1074497978438210769">Μη ασφαλής</translation>
<translation id="1080116354587839789">Προσαρμογή στο πλάτος</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Προσθήκη ονόματος στην κάρτα</translation>
<translation id="1089439967362294234">Αλλαγή κωδικού πρόσβασης</translation>
<translation id="109743633954054152">Διαχείριση κωδικών πρόσβασης στις ρυθμίσεις του Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Οι προειδοποιήσεις μπορεί να είναι συνήθεις ενώ οι ιστότοποι ενημερώνουν την ασφάλειά τους. Αυτό αναμένεται να βελτιωθεί σύντομα.</translation>
<translation id="1126551341858583091">Το μέγεθος του τοπικού αποθηκευτικού χώρου είναι <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Η προσωρινή μνήμη της πολιτικής είναι εντάξει</translation>
+<translation id="1131264053432022307">Εικόνα που αντιγράψατε</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> τερμάτισε απροσδόκητα τη σύνδεση.</translation>
<translation id="1161325031994447685">Επανασυνδεθείτε στο Wi-Fi</translation>
<translation id="1165039591588034296">Σφάλμα</translation>
-<translation id="1173894706177603556">Μετονομασία</translation>
<translation id="1175364870820465910">&amp;Εκτύπωση...</translation>
<translation id="1181037720776840403">Κατάργηση</translation>
<translation id="1197088940767939838">Πορτοκαλί</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Το όνομα της συσκευής σας</translation>
<translation id="124116460088058876">Περισσότερες γλώσσες</translation>
<translation id="1250759482327835220">Για πιο γρήγορες πληρωμές στο μέλλον, αποθηκεύστε τα στοιχεία της κάρτας σας, το όνομα και τη διεύθυνση χρέωσης στον Λογαριασμό σας Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (συγχρονισμένο)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Παραλλαγές γραμμής εντολών</translation>
<translation id="129553762522093515">Έκλεισαν πρόσφατα</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Δοκιμάστε να διαγράψετε τα cookie σας<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Η επιλεγμένη περίοδος λειτουργίας δεν υπάρχει.</translation>
+<translation id="1320233736580025032">Prc1 (Φάκελος)</translation>
+<translation id="132301787627749051">Αναζήτηση εικόνας στο πρόχειρο</translation>
<translation id="1323433172918577554">Εμφάνιση περισσότερων</translation>
<translation id="132390688737681464">Αποθήκευση και συμπλήρωση διευθύνσεων</translation>
<translation id="1333989956347591814">Η δραστηριότητά σας <ph name="BEGIN_EMPHASIS" />μπορεί να εξακολουθήσει να είναι ορατή<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Διεύθυνση παραλαβής</translation>
<translation id="1348198688976932919">Ο ιστότοπος που πρόκειται να επισκεφτείτε περιέχει επικίνδυνες εφαρμογές</translation>
<translation id="1348779747280417563">Επιβεβαίωση ονόματος</translation>
+<translation id="1357195169723583938">Ποιοι χρησιμοποίησαν πρόσφατα τη συσκευή και πότε τη χρησιμοποίησαν</translation>
+<translation id="1364822246244961190">Αυτή η πολιτική έχει αποκλειστεί, η τιμή της παραβλέπεται.</translation>
<translation id="1374468813861204354">προτάσεις</translation>
+<translation id="1374692235857187091">Index-4x6 (Ταχυδρομική κάρτα)</translation>
<translation id="1375198122581997741">Σχετικά με την έκδοση</translation>
<translation id="1376836354785490390">Εμφάνιση λιγότερων</translation>
<translation id="1377321085342047638">Αρ.κάρτας</translation>
<translation id="138218114945450791">Ανοιχτό μπλε</translation>
+<translation id="1382194467192730611">Συσκευή USB που επιτρέπεται από τον διαχειριστή σας</translation>
<translation id="139305205187523129">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> δεν έστειλε δεδομένα.</translation>
+<translation id="140316286225361634">Ο ιστότοπος <ph name="ORIGIN" /> ζήτησε να ισχύει μια πολιτική ασφαλείας
+ για όλα τα αιτήματά του και αυτή η πολιτική καθιστά προς το παρόν τον ιστότοπο
+ μη ασφαλή.</translation>
<translation id="1405567553485452995">Ανοιχτό πράσινο</translation>
<translation id="1407135791313364759">Άνοιγμα όλων</translation>
<translation id="1413809658975081374">Σφάλμα απορρήτου</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ναι</translation>
<translation id="1430915738399379752">Εκτύπωση</translation>
<translation id="1455413310270022028">Γόμα</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Εμφάνιση περισσότερων</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Επιλογή διεύθυνσης αποστολής</translation>
+<translation id="1492194039220927094">Προώθηση πολιτικών:</translation>
<translation id="1501859676467574491">Εμφάνιση καρτών από τον Λογαριασμό σας Google</translation>
-<translation id="1506687042165942984">Εμφάνιση ενός αποθηκευμένου αντιγράφου (π.χ. επιβεβαιωμένες μη ενημερωμένες εκδόσεις) αυτής της σελίδας.</translation>
<translation id="1507202001669085618">&lt;p&gt;Αυτό το σφάλμα παρουσιάζεται εάν χρησιμοποιείτε μια πύλη Wi-Fi στην οποία πρέπει να συνδέεστε, για να μπορέσετε να περιηγηθείτε στο διαδίκτυο.&lt;/p&gt;
&lt;p&gt;Για να διορθώσετε το σφάλμα, κάντε κλικ στο κουμπί &lt;strong&gt;Σύνδεση&lt;/strong&gt; στη σελίδα που προσπαθείτε να ανοίξετε.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Απαιτείται αριθμός τηλεφώνου</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Ημερομηνία κατασκευής</translation>
<translation id="1521655867290435174">Υπολογιστικά φύλλα Google</translation>
<translation id="1527263332363067270">Αναμονή για σύνδεση…</translation>
+<translation id="1529521330346880926">10x15 (Φάκελος)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Αυτή η σελίδα λέει</translation>
<translation id="153384715582417236">Αυτά προς το παρόν</translation>
<translation id="154408704832528245">Επιλογή διεύθυνσης παράδοσης</translation>
<translation id="1549470594296187301">Θα πρέπει να ενεργοποιηθεί η JavaScript για τη χρήση αυτής της λειτουργίας.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Εισαγωγή ημερομηνίας λήξης</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Παρουσιάστηκε πρόβλημα κατά την εμφάνιση αυτής της ιστοσελίδας.</translation>
<translation id="1592005682883173041">Πρόσβαση σε τοπικά δεδομένα</translation>
<translation id="1594030484168838125">Επιλογή</translation>
<translation id="161042844686301425">Κυανό</translation>
-<translation id="1618822247301510817">Εικόνα που αντιγράψατε</translation>
<translation id="1620510694547887537">Κάμερα</translation>
<translation id="1623104350909869708">Αποτροπή δημιουργίας πρόσθετων παραθύρων διαλόγου από αυτήν τη σελίδα</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Λήξη περιόδου λειτουργίας</translation>
<translation id="1639239467298939599">Γίνεται φόρτωση</translation>
<translation id="1640180200866533862">Πολιτικές χρηστών</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">Κανονικά, ο ιστότοπος <ph name="SITE" /> χρησιμοποιεί κρυπτογράφηση για να προστατεύει τα στοιχεία σας. Όταν το Google Chrome επιχείρησε πρόσφατα να συνδεθεί στο <ph name="SITE" />, ο ιστότοπος ανταποκρίθηκε δημιουργώντας ασυνήθιστα και εσφαλμένα διαπιστευτήρια. Αυτό μπορεί να συμβεί όταν κάποιος εισβολέας προσπαθεί να υποκριθεί ότι είναι ο ιστότοπος <ph name="SITE" /> ή όταν κάποια οθόνη σύνδεσης Wi-Fi έχει διακόψει τη σύνδεσή σας. Τα στοιχεία σας εξακολουθούν να είναι ασφαλή επειδή το Google Chrome διέκοψε τη σύνδεση πριν από την ανταλλαγή δεδομένων.</translation>
<translation id="168841957122794586">Το πιστοποιητικό διακομιστή περιέχει ένα αδύναμο κρυπτογραφικό κλειδί.</translation>
<translation id="1697532407822776718">Είστε έτοιμοι!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημερομηνία του πιστοποιητικού ασφαλείας του υποτίθεται ότι είναι αυριανή. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.}other{Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι το <ph name="DOMAIN" />. Η ημερομηνία του πιστοποιητικού ασφαλείας του υποτίθεται ότι είναι από # ημέρες μετά. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">Το έγγραφο είναι πάρα πολύ μεγάλο για σχολιασμό.</translation>
<translation id="1721312023322545264">Για να επισκεφτείτε αυτήν τη σελίδα, χρειάζεστε άδεια από τον διαχειριστή <ph name="NAME" /></translation>
<translation id="1721424275792716183">* Το πεδίο είναι υποχρεωτικό</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Προσπαθήστε να επικοινωνήσετε με το διαχειριστή συστήματος.</translation>
<translation id="1740951997222943430">Εισαγάγετε έναν έγκυρο μήνα λήξης</translation>
<translation id="1743520634839655729">Για πιο γρήγορες πληρωμές στο μέλλον, αποθηκεύστε τα στοιχεία της κάρτας σας, το όνομα και τη διεύθυνση χρέωσης στον Λογαριασμό σας Google και σε αυτήν τη συσκευή.</translation>
+<translation id="1745880797583122200">Το πρόγραμμα περιήγησής σας είναι διαχειριζόμενο</translation>
<translation id="17513872634828108">Ανοικτές καρτέλες</translation>
<translation id="1753706481035618306">Αριθμός σελίδας</translation>
<translation id="1763864636252898013">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από το λειτουργικό σύστημα της συσκευής σας. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Ενημερώστε την κωδική φράση πρόσβασης συγχρονισμού.</translation>
<translation id="1787142507584202372">Οι ανοιχτές καρτέλες σας εμφανίζονται εδώ</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Όνομα κατόχου κάρτας</translation>
<translation id="1821930232296380041">Μη έγκυρο αίτημα ή παράμετροι αιτήματος</translation>
+<translation id="1822540298136254167">Οι ιστότοποι που επισκέπτεστε και ο χρόνος χρήσης τους</translation>
<translation id="1826516787628120939">Έλεγχος</translation>
<translation id="1834321415901700177">Αυτός ο ιστότοπος περιέχει κακόβουλα προγράμματα</translation>
<translation id="1839551713262164453">Η επικύρωση των τιμών πολιτικής απέτυχε αφού παρουσίασε σφάλματα</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Διαγραφή δεδομένων ιστορικού περιήγησης Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{και άλλο 1 άτομο}other{και άλλα # άτομα}}</translation>
<translation id="2003709556000175978">Επαναφέρετε τον κωδικό πρόσβασής σας τώρα</translation>
+<translation id="20053308747750172">Ο διακομιστής στον οποίο μεταβαίνετε, <ph name="ORIGIN" />, έχει ζητήσει να εφαρμόζεται
+ μια πολιτική ασφαλείας σε όλα τα αιτήματα προς αυτόν. Αλλά
+ παρέδωσε μια μη έγκυρη πολιτική, η οποία εμποδίζει το πρόγραμμα περιήγησης
+ να εκπληρώσει το αίτημά σας για τον ιστότοπο <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Ο διακομιστής μεσολάβησης έχει ρυθμιστεί σε αυτόματη διαμόρφωση.</translation>
<translation id="2030481566774242610">Μήπως εννοείτε <ph name="LINK" />;</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Ελέγξτε το διακομιστή μεσολάβησης και το τείχος προστασίας<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Διαμέρισμα</translation>
<translation id="2102134110707549001">Πρόταση για ισχυρό κωδικό πρόσβασης…</translation>
<translation id="2108755909498034140">Επανεκκινήστε τον υπολογιστή σας</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Παιχνίδια με κάρτες</translation>
<translation id="2114841414352855701">Αγνοήθηκε επειδή αντικαταστάθηκε από την πολιτική <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Σελιδοδείκτες κινητής συσκευής</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Επεξεργασία κάρτας</translation>
<translation id="2166049586286450108">Πλήρης πρόσβαση διαχειριστή</translation>
<translation id="2166378884831602661">Αυτός ο ιστότοπος δεν μπορεί να προσφέρει ασφαλή σύνδεση</translation>
+<translation id="2169984857010174799">Kaku2 (Φάκελος)</translation>
<translation id="2181821976797666341">Πολιτικές</translation>
<translation id="2183608646556468874">Αριθμός τηλεφώνου</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 διεύθυνση}other{# διευθύνσεις}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Αριθμός τηλεφώνου</translation>
<translation id="2283340219607151381">Αποθήκευση και συμπλήρωση διευθύνσεων</translation>
<translation id="2292556288342944218">Η πρόσβασή σας στο διαδίκτυο είναι αποκλεισμένη</translation>
+<translation id="2294558542833290837">Ο σύνδεσμος που ανοίξατε αρχικά δεν είναι συνηθισμένος</translation>
+<translation id="2297722699537546652">B5 (Φάκελος)</translation>
+<translation id="2310021320168182093">Chou2 (Φάκελος)</translation>
<translation id="2316887270356262533">Απελευθερώνει λιγότερο από 1 MB. Ορισμένοι ιστότοποι μπορεί να φορτωθούν πιο αργά κατά την επόμενη επίσκεψή σας.</translation>
<translation id="2317259163369394535">Ο τομέας <ph name="DOMAIN" /> απαιτεί ένα όνομα χρήστη και έναν κωδικό πρόσβασης.</translation>
<translation id="2317583587496011522">Οι χρεωστικές κάρτες γίνονται δεκτές.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, λήγει στις <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Η ρύθμιση ελέγχεται από τον διαχειριστή σας</translation>
+<translation id="2346319942568447007">Εικόνα που αντιγράψατε</translation>
<translation id="2349790679044093737">Η περίοδος λειτουργίας VR είναι ενεργή</translation>
<translation id="2354001756790975382">Άλλοι σελιδοδείκτες</translation>
<translation id="2354430244986887761">Η Ασφαλής περιήγηση Google πρόσφατα <ph name="BEGIN_LINK" />εντόπισε επιβλαβείς εφαρμογές<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Οι αναφορές σφαλμάτων που καταγράφηκαν <ph name="CRASH_TIME" /> δεν έχουν μεταφορτωθεί</translation>
<translation id="2367567093518048410">Επίπεδο</translation>
<translation id="2378238891085281592">Πραγματοποιείτε ιδιωτική περιήγηση</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Προεπιλογή επιχείρησης</translation>
<translation id="2386255080630008482">Το πιστοποιητικό του διακομιστή ανακλήθηκε.</translation>
<translation id="2392959068659972793">Εμφάνιση πολιτικών χωρίς τιμή που να έχει οριστεί.</translation>
<translation id="239429038616798445">Αυτός ο τρόπος αποστολής δεν είναι διαθέσιμος. Δοκιμάστε έναν άλλο τρόπο.</translation>
<translation id="2396249848217231973">&amp;Αναίρεση διαγραφής</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">Ο διακομιστής δεν κατάφερε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μπορεί να έχει ανακληθεί. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
+<translation id="2418081434543109369">Ο διακομιστής στον οποίο μεταβαίνετε, <ph name="ORIGIN" />, έχει ζητήσει να εφαρμόζεται
+ μια πολιτική ασφαλείας σε όλα τα αιτήματα προς αυτόν. Αλλά
+ απέτυχε να παραδώσει μια πολιτική, γεγονός που εμποδίζει το πρόγραμμα περιήγησης να εκπληρώσει
+ το αίτημά σας για τον ιστότοπο <ph name="SITE" />.</translation>
<translation id="244665789865330679">Η διαχείριση της συσκευής και του λογαριασμού γίνεται από τον τομέα <ph name="ENROLLMENT_DOMAIN" />. Αυτό σημαίνει ότι ο διαχειριστής σας μπορεί να διαμορφώσει απομακρυσμένα τη συσκευή και τον λογαριασμό σας.</translation>
<translation id="2463193859425327265">Αλλαγή αρχικής σελίδας</translation>
<translation id="2463739503403862330">Συμπλήρωση</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Επιλογή τρόπου παράδοσης</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Να εκτελέσετε τον Διαγνωστικό έλεγχο δικτύου<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Μετάφραση αυτής της σελίδας</translation>
<translation id="2479410451996844060">Μη έγκυρη διεύθυνση URL αναζήτησης.</translation>
<translation id="2482878487686419369">Ειδοποιήσεις</translation>
<translation id="248348093745724435">Πολιτικές συσκευής</translation>
+<translation id="2485387744899240041">Τα ονόματα χρήστη για τη συσκευή και το πρόγραμμα περιήγησής σας</translation>
<translation id="2491120439723279231">Το πιστοποιητικό του διακομιστή περιέχει σφάλματα.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">Συντακτικός αναλυτής JSON</translation>
<translation id="2495093607237746763">Εάν επιλεγεί, το Chromium θα αποθηκεύσει ένα αντίγραφο της κάρτας σας σε αυτήν τη συσκευή για ταχύτερη συμπλήρωση φορμών.</translation>
<translation id="2498091847651709837">Σάρωση νέας κάρτας</translation>
<translation id="2501278716633472235">Επιστροφή</translation>
<translation id="2503184589641749290">Αποδεκτές χρεωστικές και προπληρωμένες κάρτες</translation>
<translation id="2515629240566999685">Ελέγξτε το σήμα στην περιοχή σας.</translation>
-<translation id="2516852381693169964">Αναζήτηση σε <ph name="SEARCH_ENGINE" /> για εικόνα</translation>
<translation id="2523886232349826891">Αποθηκεύτηκε μόνο σε αυτήν τη συσκευή</translation>
<translation id="2524461107774643265">Προσθήκη περισσότερων πληροφοριών</translation>
<translation id="2536110899380797252">Προσθήκη διεύθυνσης</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Αναγνωριστικό API καταλόγου:</translation>
<translation id="2597378329261239068">Αυτό το έγγραφο προστατεύεται με κωδικό πρόσβασης. Πληκτρολογήστε έναν κωδικό πρόσβασης.</translation>
<translation id="2609632851001447353">Παραλλαγές</translation>
+<translation id="2618023639789766142">C10 (Φάκελος)</translation>
<translation id="2625385379895617796">Το ρολόι σας πάει μπροστά</translation>
<translation id="2634124572758952069">Δεν ήταν δυνατή η εύρεση της διεύθυνσης IP διακομιστή του κεντρικού υπολογιστή <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Κατάσταση:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Κλείστε τις άλλες καρτέλες ή εφαρμογές</translation>
<translation id="267371737713284912">πατήστε <ph name="MODIFIER_KEY_DESCRIPTION" /> για αναίρεση</translation>
<translation id="2674170444375937751">Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτές τις σελίδες από το ιστορικό σας;</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Αποχώρηση</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Αποδεκτές κάρτες</translation>
<translation id="2702801445560668637">Λίστα ανάγνωσης</translation>
<translation id="2704283930420550640">Η τιμή δεν συμφωνεί με τη μορφή.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Κατάργηση επιλεγμένων στοιχείων</translation>
<translation id="277133753123645258">Τρόπος αποστολής</translation>
<translation id="277499241957683684">Λείπει κάποιο αρχείο συσκευής</translation>
-<translation id="2781030394888168909">Εξαγωγή για MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Έγινε επαναφορά της σύνδεσης.</translation>
<translation id="2788784517760473862">Αποδεκτές πιστωτικές κάρτες</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">Η κρυπτογράφηση και ο έλεγχος ταυτότητας της σύνδεσης γίνονται με <ph name="CIPHER" /> και χρησιμοποιεί το <ph name="KX" /> ως μηχανισμό ανταλλαγής κλειδιών.</translation>
<translation id="2835170189407361413">Διαγραφή φόρμας</translation>
<translation id="2847118875340931228">Άνοιγμα παραθύρου για ανώνυμη περιήγηση</translation>
+<translation id="2850739647070081192">Invite (Φάκελος)</translation>
<translation id="2851634818064021665">Απαιτείται άδεια για να επισκεφτείτε αυτόν τον ιστότοπο</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Αποθήκευση κάρτας;</translation>
<translation id="2903493209154104877">Διευθύνσεις</translation>
<translation id="290376772003165898">Η σελίδα δεν είναι στα <ph name="LANGUAGE" />;</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Τρόπος προβολής</translation>
<translation id="2928905813689894207">Διεύθυνση χρέωσης</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του είναι από το <ph name="DOMAIN2" />. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="2948083400971632585">Μπορείτε να απενεργοποιήσετε τυχόν διακομιστές μεσολάβησης που έχουν διαμορφωθεί για μια σύνδεση από τη σελίδα ρυθμίσεων.</translation>
<translation id="2955913368246107853">Κλείσιμο γραμμής εύρεσης</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Φάκελος)</translation>
<translation id="3024663005179499861">Λανθασμένος τύπος πολιτικής</translation>
<translation id="3037605927509011580">Όπα! Κάτι πήγε στραβά!</translation>
<translation id="3041612393474885105">Πληροφορίες πιστοποιητικού</translation>
+<translation id="3060227939791841287">C9 (Φάκελος)</translation>
<translation id="3064966200440839136">Αποχώρηση από την κατάσταση ανώνυμης περιήγησης για πληρωμή μέσω εξωτερικής εφαρμογής. Συνέχεια;</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{Κανένας}=1{1 κωδικός πρόσβασης}other{# κωδικοί πρόσβασης}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Προσθήκη διεύθυνσης παραλαβής</translation>
<translation id="3105172416063519923">Αναγνωριστικό στοιχείο:</translation>
<translation id="3109728660330352905">Δεν έχετε εξουσιοδότηση για την προβολή αυτής της σελίδας.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> στο <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Ακύρωση πληρωμής</translation>
<translation id="3207960819495026254">Προστέθηκε στους σελιδοδείκτες</translation>
-<translation id="3209375525920864198">Εισαγάγετε ένα έγκυρο όνομα περιόδου λειτουργίας.</translation>
+<translation id="321912867715453276">Προειδοποίηση: Υπάρχουν πάνω από μία πηγές για την πολιτική, αλλά οι τιμές είναι ίδιες.</translation>
<translation id="3225919329040284222">Ο διακομιστής παρουσίασε ένα πιστοποιητικό που δεν αντιστοιχεί στις ενσωματωμένες προϋποθέσεις. Αυτές οι προϋποθέσεις συμπεριλαμβάνονται σε συγκεκριμένους ιστότοπους υψηλής ασφάλειας για την προστασία σας.</translation>
<translation id="3226128629678568754">Πατήστε το κουμπί της επανάληψης φόρτωσης για να υποβάλετε ξανά τα δεδομένα που απαιτούνται για τη φόρτωση της σελίδας.</translation>
<translation id="3227137524299004712">Μικρόφωνο</translation>
<translation id="3228969707346345236">Η μετάφραση απέτυχε επειδή η σελίδα είναι ήδη στα <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Πληροφορίες έκδοσης σχετικά με τη συσκευή και το πρόγραμμα περιήγησης</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Προσθήκη ονόματος στην κάρτα</translation>
<translation id="3287510313208355388">Να γίνει λήψη όταν πραγματοποιηθεί σύνδεση</translation>
<translation id="3293642807462928945">Μάθετε περισσότερα σχετικά με την πολιτική <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Δεν βρέθηκαν αποτελέσματα αναζήτησης</translation>
-<translation id="3305707030755673451">Τα δεδομένα σας κρυπτογραφήθηκαν με τη δική σας φράση πρόσβασης συγχρονισμού στις <ph name="TIME" />. Πληκτρολογήστε την για να ξεκινήσει ο συγχρονισμός.</translation>
<translation id="3320021301628644560">Προσθήκη διεύθυνσης χρέωσης</translation>
<translation id="3324983252691184275">Βαθύ κόκκινο</translation>
<translation id="3338095232262050444">Ασφαλές</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Επανάληψη επεξεργασίας</translation>
<translation id="342781501876943858">Το Chromium συνιστά την επαναφορά του κωδικού πρόσβασης, εάν τον έχετε χρησιμοποιήσει και σε άλλους ιστοτόπους.</translation>
<translation id="3431636764301398940">Αποθήκευση αυτής της κάρτας στη συγκεκριμένη συσκευή</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Ο κάτοχος αυτής της συσκευής απενεργοποίησε το παιχνίδι με τους δεινοσαύρους.</translation>
<translation id="3447884698081792621">Εμφάνιση πιστοποιητικού (εκδόθηκε από <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Διάστημα ανάκτησης:</translation>
+<translation id="3456231139987291353">Number-11 (Φάκελος)</translation>
<translation id="3461824795358126837">Μαρκαδόρος υπογράμμισης</translation>
<translation id="3462200631372590220">Απόκρυψη σύνθετων</translation>
<translation id="3467763166455606212">Απαιτείται το όνομα κατόχου κάρτας</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Οι πιστωτικές και προπληρωμένες κάρτες γίνονται δεκτές.</translation>
<translation id="3582930987043644930">Προσθήκη ονόματος</translation>
<translation id="3583757800736429874">&amp;Επανάληψη μετακίνησης</translation>
+<translation id="35866233670761917">Τα περιεχόμενα των ιστοτόπων που επισκέπτεστε δεν προβάλλονται στους διαχειριστές σας</translation>
<translation id="3586931643579894722">Απόκρυψη λεπτομερειών</translation>
+<translation id="3592413004129370115">Italian (Φάκελος)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Μέγεθος 2</translation>
<translation id="3615877443314183785">Εισαγάγετε μια έγκυρη ημερομηνία λήξης</translation>
<translation id="36224234498066874">Διαγραφή δεδομένων περιήγησης…</translation>
<translation id="362276910939193118">Εμφάνιση πλήρους ιστορικού</translation>
-<translation id="3623476034248543066">Εμφάνιση τιμής</translation>
<translation id="3630155396527302611">Εάν έχει ήδη καταχωριστεί ως πρόγραμμα στο οποίο επιτρέπεται η πρόσβαση στο δίκτυο, δοκιμάστε
να το καταργήσετε από τη λίστα και να το προσθέσετε ξανά.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Επιτυχής επικύρωση</translation>
<translation id="3655670868607891010">Αν αυτό το μήνυμα εμφανίζεται συχνά, μπορείτε να βρείτε βοήθεια εδώ <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Αναθεώρηση</translation>
<translation id="366077651725703012">Ενημέρωση πιστωτικής κάρτας</translation>
<translation id="3676592649209844519">Αναγνωριστικό συσκευής:</translation>
+<translation id="3677008721441257057">Μήπως εννοούσατε &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;;</translation>
<translation id="3678029195006412963">Δεν ήταν δυνατή η έγκριση του αιτήματος</translation>
<translation id="3678529606614285348">Ανοίξτε τη σελίδα σε ένα νέο παράθυρο ανώνυμης περιήγησης (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Η αναφορά σφαλμάτων καταγράφηκε στις <ph name="CRASH_TIME" /> και μεταφορτώθηκε στις <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Το δίκτυο που χρησιμοποιείτε ενδέχεται να σας ζητήσει να επισκεφτείτε τη σελίδα σύνδεσης του.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Φόρτωση...</translation>
+<translation id="3709599264800900598">Κείμενο που αντιγράψατε</translation>
<translation id="3712624925041724820">Οι άδειες έχουν εξαντληθεί</translation>
<translation id="3714780639079136834">Ενεργοποιήστε τα δεδομένα κινητής τηλεφωνίας ή το Wi-Fi.</translation>
<translation id="3715597595485130451">Σύνδεση σε Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Ελέγξτε το διακομιστή μεσολάβησης, το τείχος προστασίας και τη διαμόρφωση DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Οι εφαρμογές που μπορούν να προκαλέσουν αυτό το σφάλμα περιλαμβάνουν λογισμικό προστασίας από ιούς, τείχος προστασίας και λογισμικό φιλτραρίσματος ιστού ή λογισμικό διακομιστή μεσολάβησης.</translation>
+<translation id="373042150751172459">B4 (Φάκελος)</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="3745099705178523657">Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον Λογαριασμό Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Λήγει <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Μέγεθος 16</translation>
+<translation id="3797522431967816232">Prc3 (Φάκελος)</translation>
<translation id="3807873520724684969">Το επιβλαβές περιεχόμενο αποκλείστηκε.</translation>
<translation id="3810973564298564668">Διαχείριση</translation>
<translation id="382518646247711829">Εάν χρησιμοποιείτε διακομιστή μεσολάβησης…</translation>
<translation id="3828924085048779000">Δεν επιτρέπεται να είναι κενή η φράση πρόσβασης.</translation>
+<translation id="3831915413245941253">Ο τομέας <ph name="ENROLLMENT_DOMAIN" /> εγκατέστησε επεκτάσεις για επιπλέον λειτουργίες. Οι επεκτάσεις έχουν πρόσβαση σε κάποια από τα δεδομένα σας.</translation>
<translation id="385051799172605136">Πίσω</translation>
<translation id="3858027520442213535">Ενημέρωση ημερομηνίας και ώρας</translation>
<translation id="3884278016824448484">Αναγνωριστικό συσκευής που προκαλεί διένεξη</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">Το αίτημά σας για να αποκτήσετε πρόσβαση σε αυτόν τον ιστότοπο έχει σταλεί στον/η(ν) <ph name="NAME" /></translation>
<translation id="3890664840433101773">Προσθήκη διεύθυνσης ηλεκτρονικού ταχυδρομείου</translation>
<translation id="3901925938762663762">Η κάρτα έχει λήξει</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Να γίνεται πάντα ερώτηση σε αυτόν τον ιστότοπο</translation>
<translation id="3949571496842715403">Αυτός ο διακομιστής δεν μπορεί να αποδείξει ότι είναι ο τομέας <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας δεν προσδιορίζει Εναλλακτικά ονόματα θέματος. Αυτό μπορεί να οφείλεται σε εσφαλμένη διαμόρφωση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{Κανένα}=1{Από 1 ιστότοπο }other{Από # ιστοτόπους }}</translation>
<translation id="397105322502079400">Υπολογισμός…</translation>
<translation id="3973234410852337861">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> είναι αποκλεισμένος</translation>
-<translation id="3984550557525787191">Αυτό το όνομα περιόδου λειτουργίας υπάρχει ήδη.</translation>
<translation id="3987940399970879459">Λιγότερα από 1 MB</translation>
+<translation id="4008849406247176967">Προειδοποίηση: Υπάρχουν πάνω από μία πηγές με τιμές σε διένεξη για αυτήν την πολιτική!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 ιστοσελίδα σε κοντινή απόσταση}other{# ιστοσελίδες σε κοντινή απόσταση}}</translation>
<translation id="4030383055268325496">&amp;Αναίρεση προσθήκης</translation>
+<translation id="4032320456957708163">Το πρόγραμμα περιήγησής σας είναι διαχειριζόμενο από τον τομέα <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Κλειδί "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Φάκελος)</translation>
<translation id="4067947977115446013">Προσθήκη έγκυρης διεύθυνσης</translation>
<translation id="4072486802667267160">Προέκυψε σφάλμα κατά την επεξεργασία της παραγγελίας σας. Δοκιμάστε ξανά.</translation>
<translation id="4075732493274867456">Η εφαρμογή πελάτης και ο διακομιστής δεν υποστηρίζουν κάποια κοινή έκδοση πρωτοκόλλου SSL ή σουίτα κρυπτογράφησης.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Μοβ</translation>
<translation id="4165986682804962316">Ρυθμίσεις ιστότοπου</translation>
<translation id="4171400957073367226">Εσφαλμένη υπογραφή επαλήθευσης</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ακόμη στοιχείο}other{<ph name="ITEM_COUNT" /> ακόμη στοιχεία}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;Επανάληψη μετακίνησης</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Ελέγξτε τις διαμορφώσεις του τείχους προστασίας και της προστασίας από ιούς<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Φάκελος)</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="4221630205957821124">&lt;h4&gt;Βήμα 1: Συνδεθείτε στην πύλη&lt;/h4&gt;
@@ -551,58 +613,79 @@
<translation id="4277028893293644418">Επαναφορά κωδικού πρόσβασης</translation>
<translation id="4280429058323657511">, λήξη <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Αυτή η κάρτα αποθηκεύτηκε στον Λογαριασμό σας Google}other{Αυτές οι κάρτες αποθηκεύτηκαν στον Λογαριασμό σας Google}}</translation>
+<translation id="42981349822642051">Επέκταση</translation>
+<translation id="4302965934281694568">Chou3 (Φάκελος)</translation>
<translation id="4305817255990598646">Εναλλαγή</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Αποκλεισμός (προεπιλογή)</translation>
+<translation id="4318566738941496689">Το όνομα της συσκευής και η διεύθυνση δικτύου σας</translation>
<translation id="4325863107915753736">Αποτυχία εύρεσης άρθρου</translation>
<translation id="4326324639298822553">Ελέγξτε την ημερομηνία λήξης σας και δοκιμάστε ξανά</translation>
<translation id="4331708818696583467">Μη ασφαλές</translation>
<translation id="4340982228985273705">Αυτός ο υπολογιστής δεν έχει εντοπιστεί ως διαχειριζόμενος από επιχείρηση. Συνεπώς, η πολιτική μπορεί να εγκαθιστά αυτόματα μόνο επεκτάσεις οι οποίες φιλοξενούνται στο Chrome Webstore. Το URL ενημέρωσης του Chrome Webstore είναι το "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Αποδεκτές πιστωτικές κάρτες</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Οι εισβολείς σε αυτόν τον ιστότοπο μπορεί να επιχειρήσουν να εγκαταστήσουν επικίνδυνα προγράμματα στον υπολογιστή σας, τα οποία μπορούν να υποκλέψουν ή να διαγράψουν τα δεδομένα σας (για παράδειγμα, φωτογραφίες, κωδικούς πρόσβασης, μηνύματα και στοιχεία πιστωτικών καρτών).</translation>
<translation id="4358461427845829800">Διαχείριση τρόπων πληρωμής…</translation>
+<translation id="4367563149485757821">Number-12 (Φάκελος)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">Αναμενόμενη τιμή <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">Προσπαθήσατε να μεταβείτε στον τομέα <ph name="DOMAIN" />, όμως το πιστοποιητικό που παρουσιάστηκε από το διακομιστή ανακλήθηκε από τον εκδότη του. Αυτό σημαίνει ότι τα διαπιστευτήρια ασφαλείας που παρουσιάστηκαν από το διακομιστή δεν πρέπει σε καμία περίπτωση να θεωρηθούν αξιόπιστα. Ενδέχεται να επικοινωνείτε με κάποιον εισβολέα.</translation>
<translation id="4378154925671717803">Τηλέφωνο</translation>
<translation id="4406896451731180161">αποτελέσματα αναζήτησης</translation>
-<translation id="4406972042435603828">Οι διαχειριστές σας έχουν εγκαταστήσει επεκτάσεις με ισχυρές δυνατότητες.</translation>
<translation id="4408413947728134509">Cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Διεύθυνση παραλαβής</translation>
<translation id="4424024547088906515">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν θεωρείται έμπιστο από τον Chrome. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
+<translation id="443121186588148776">Σειριακή θύρα</translation>
<translation id="4432688616882109544">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> δεν αποδέχτηκε το πιστοποιητικό σύνδεσής σας ή μπορεί να μην διατέθηκε πιστοποιητικό σύνδεσης.</translation>
<translation id="4434045419905280838">Αναδυόμενα παράθυρα και ανακατευθύνσεις</translation>
+<translation id="4435702339979719576">Ταχυδρομική κάρτα)</translation>
<translation id="443673843213245140">Η χρήση ενός διακομιστή μεσολάβησης είναι απενεργοποιημένη, αλλά έχει καθοριστεί μια ρητή διαμόρφωση διακομιστή μεσολάβησης.</translation>
<translation id="445100540951337728">Αποδεκτές χρεωστικές κάρτες</translation>
+<translation id="4466881336512663640">Οι αλλαγές που πραγματοποιήθηκαν στη φόρμα θα χαθούν. Είστε βέβαιοι ότι θέλετε να συνεχίσετε;</translation>
<translation id="4482953324121162758">Αυτός ο ιστότοπος δεν θα μεταφραστεί.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Μη έγκυρο URL. Πρέπει να είναι ένα URL με βασική μορφή, π.χ. http://example.com ή https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Σφάλμα επικύρωσης: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Επικοινωνήστε με το διαχειριστή συστήματος</translation>
<translation id="450710068430902550">Κοινοποίηση στο διαχειριστή</translation>
+<translation id="4510487217173779431">Chou4 (Φάκελος)</translation>
<translation id="4515275063822566619">Οι κάρτες και οι διευθύνσεις προέρχονται από το Chrome και τον Λογαριασμό σας Google (<ph name="ACCOUNT_EMAIL" />). Μπορείτε να τις διαχειριστείτε στις <ph name="BEGIN_LINK" />Ρυθμίσεις<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (Φάκελος)</translation>
<translation id="4522570452068850558">Λεπτομέρειες</translation>
<translation id="4524805452350978254">Διαχείριση καρτών</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Δοκιμάστε να απενεργοποιήσετε τις επεκτάσεις σας.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Παράδοση</translation>
+<translation id="4579056131138995126">Προσωπικό (Φάκελος)</translation>
<translation id="4582204425268416675">Κατάργηση κάρτας</translation>
<translation id="4587425331216688090">Κατάργηση διεύθυνσης από το Chrome;</translation>
<translation id="4592951414987517459">Η σύνδεσή σας στο <ph name="DOMAIN" /> κρυπτογραφείται χρησιμοποιώντας ένα σύγχρονο πρόγραμμα κρυπτογράφησης.</translation>
<translation id="4594403342090139922">&amp;Αναίρεση διαγραφής</translation>
<translation id="4597348597567598915">Μέγεθος 8</translation>
+<translation id="4600854749408232102">C6/C5 (Φάκελος)</translation>
<translation id="4646534391647090355">Μετάβαση εκεί τώρα</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">Ο διακομιστής δεν κατάφερε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του περιέχει σφάλματα. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
<translation id="467809019005607715">Παρουσιάσεις Google</translation>
<translation id="4690462567478992370">Διακοπή χρήσης μη έγκυρου πιστοποιητικού</translation>
+<translation id="4691835149146451662">Architecture-A (Φάκελος)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Η σύνδεσή σας διακόπηκε</translation>
<translation id="471880041731876836">Δεν έχετε άδεια να επισκεφτείτε αυτόν τον ιστότοπο</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Να εκτελέσετε τον Διαγνωστικό έλεγχο δικτύου των Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Επανάληψη φόρτωσης πολιτικών</translation>
<translation id="4728558894243024398">Πλατφόρμα</translation>
+<translation id="4731967714531604179">Prc2 (Φάκελος)</translation>
<translation id="4736825316280949806">Επανεκκινήστε το Chromium</translation>
<translation id="473775607612524610">Ενημέρωση</translation>
<translation id="4738601419177586157">Πρόταση αναζήτησης <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Διαχείριση κωδικών πρόσβασης…</translation>
<translation id="4744603770635761495">Διαδρομή εκτελέσιμου</translation>
+<translation id="4746351372139058112">Μηνύματα</translation>
<translation id="4750917950439032686">Οι πληροφορίες σας (για παράδειγμα, οι κωδικοί πρόσβασης ή οι αριθμοί πιστωτικών καρτών) είναι ιδιωτικές κατά την αποστολή σε αυτόν τον ιστότοπο.</translation>
<translation id="4756388243121344051">&amp;Ιστορικό</translation>
<translation id="4758311279753947758">Προσθήκη στοιχείων επικοινωνίας</translation>
@@ -610,9 +693,9 @@
<translation id="4764776831041365478">Η ιστοσελίδα στη διεύθυνση <ph name="URL" /> μπορεί να βρίσκεται προσωρινά εκτός λειτουργίας ή ίσως έχει μεταφερθεί μόνιμα σε νέα διεύθυνση ιστού.</translation>
<translation id="4771973620359291008">Παρουσιάστηκε άγνωστο σφάλμα.</translation>
<translation id="4785689107224900852">Εναλλαγή σε αυτήν την καρτέλα</translation>
-<translation id="4792143361752574037">Παρουσιάστηκε κάποιο πρόβλημα κατά την πρόσβαση στα αρχεία περιόδου λειτουργίας. Η αποθήκευση στον δίσκο είναι προς το παρόν απενεργοποιημένη. Επαναλάβετε τη φόρτωση της σελίδας για να δοκιμάσετε ξανά.</translation>
<translation id="4798078619018708837">Καταχωρίστε την ημερομηνία λήξης και τον κωδικό CVC για την πιστωτική κάρτα <ph name="CREDIT_CARD" />, προκειμένου να ενημερώσετε τα στοιχεία της κάρτας σας. Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον Λογαριασμό Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation>
<translation id="4800132727771399293">Ελέγξτε την ημερομηνία λήξης και τον κωδικό σας CVC και δοκιμάστε ξανά</translation>
+<translation id="480334179571489655">Σφάλμα πολιτικής προέλευσης</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>
@@ -627,7 +710,6 @@
<translation id="4881695831933465202">Άνοιγμα</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>
@@ -636,15 +718,15 @@
<translation id="4943872375798546930">Δεν υπάρχουν αποτελέσματα</translation>
<translation id="4950898438188848926">Κουμπί εναλλαγής καρτέλας, πατήστε Enter για μετάβαση στην ανοιχτή καρτέλα, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Ενέργειες</translation>
-<translation id="495832697253704892">Επέκταση αναφοράς</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Ανάπτυξη λίστας</translation>
<translation id="4974590756084640048">Επανενεργοποίηση προειδοποιήσεων</translation>
+<translation id="4984339528288761049">Prc5 (Φάκελος)</translation>
<translation id="4989163558385430922">Εμφάνιση όλων</translation>
<translation id="4989809363548539747">Αυτή η προσθήκη δεν υποστηρίζεται</translation>
-<translation id="4996230189582812866">Αναφορές</translation>
<translation id="5002932099480077015">Εάν ενεργοποιηθεί, το Chrome θα αποθηκεύσει ένα αντίγραφο της κάρτας σας σε αυτήν τη συσκευή για ταχύτερη συμπλήρωση φορμών.</translation>
-<translation id="5014174725590676422">Εμφανίζεται ο Βοηθός Google στην η οθόνη πρώτης εκτέλεσης του Chrome</translation>
<translation id="5015510746216210676">Όνομα συσκευής:</translation>
+<translation id="5017554619425969104">Κείμενο που αντιγράψατε</translation>
<translation id="5018422839182700155">Δεν είναι δυνατό το άνοιγμα αυτής της σελίδας</translation>
<translation id="5019198164206649151">Η αποθήκευση αντιγράφων ασφαλείας είναι σε κακή κατάσταση</translation>
<translation id="5023310440958281426">Ελέγξτε τις πολιτικές του διαχειριστή</translation>
@@ -654,35 +736,51 @@
<translation id="5034369478845443529">Τοπικό περιβάλλον <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Επιτρέπεται</translation>
<translation id="5040262127954254034">Απόρρητο</translation>
+<translation id="5043480802608081735">Σύνδεσμος που αντιγράψατε</translation>
<translation id="5045550434625856497">Λανθασμένος κωδικός πρόσβασης</translation>
<translation id="5056549851600133418">Άρθρα για εσάς</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Ελέγξτε τη διεύθυνση του διακομιστή μεσολάβησης<ph name="END_LINK" /></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="5097099694988056070">Στατιστικά στοιχεία συσκευής, όπως χρήση CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Η διαχείριση της συσκευής γίνεται από <ph name="ENROLLMENT_DOMAIN" /> και η διαχείριση του λογαριασμού σας γίνεται από <ph name="ACCOUNT_DOMAIN" />. Αυτό σημαίνει ότι οι διαχειριστές σας μπορούν να διαμορφώσουν απομακρυσμένα τη συσκευή και τον λογαριασμό σας.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">Η περίοδος σύνδεσης με αυτό το όνομα δεν είναι έγκυρη για διαγραφή.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Διαχείριση διευθύνσεων…</translation>
+<translation id="5138227688689900538">Εμφάνιση λιγότερων</translation>
<translation id="5141240743006678641">Κρυπτογραφήστε συγχρονισμένους κωδικούς πρόσβασης με τα διαπιστευτήριά σας Google.</translation>
<translation id="5145883236150621069">Βρέθηκε κωδικός σφάλματος στην απόκριση πολιτικής</translation>
+<translation id="515292512908731282">C4 (Φάκελος)</translation>
<translation id="5159010409087891077">Ανοίξτε τη σελίδα σε ένα νέο παράθυρο ανώνυμης περιήγησης (⇧⌘N)</translation>
<translation id="516920405563544094">Εισαγάγετε τον κωδικό CVC για την πιστωτική κάρτα <ph name="CREDIT_CARD" />. Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον Λογαριασμό Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation>
<translation id="5169827969064885044">Υπάρχει κίνδυνος να χάσετε την πρόσβαση στον λογαριασμό της επιχείρησής σας ή να σας κλέψουν τη διαδικτυακή σας ταυτότητα. Το Chrome συνιστά να αλλάξετε τον κωδικό πρόσβασής σας τώρα.</translation>
<translation id="5171045022955879922">Αναζήτηση ή πληκτρολόγηση διεύθυνσης URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Υπολογιστής</translation>
<translation id="5179510805599951267">Δεν είναι στα <ph name="ORIGINAL_LANGUAGE" />; Αναφέρετε αυτό το σφάλμα</translation>
<translation id="5190835502935405962">Γραμμή σελιδοδεικτών</translation>
-<translation id="5200263511887412697">αναφορά λίστας συσκευών που χρησιμοποίησαν πρόσφατα οι χρήστες για να συνδεθούν</translation>
+<translation id="519422657042045905">Ο σχολιασμός δεν διατίθεται</translation>
<translation id="5201306358585911203">Μια ενσωματωμένη σελίδα σε αυτήν τη σελίδα λέει</translation>
<translation id="5205222826937269299">Απαιτείται όνομα</translation>
<translation id="5215116848420601511">Τρόποι πληρωμής και διευθύνσεις που χρησιμοποιούν το Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Απαιτείται διεύθυνση ηλεκτρονικού ταχυδρομείου</translation>
<translation id="5230733896359313003">Διεύθυνση αποστολής</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Σύνδεση σε δίκτυο"</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Φάκελος)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Διευθύνσεις δικτύου</translation>
<translation id="5285570108065881030">Εμφάνιση όλων των αποθηκευμένων κωδικών πρόσβασης</translation>
<translation id="5287240709317226393">Εμφάνιση cookie</translation>
<translation id="5288108484102287882">Η επικύρωση των τιμών πολιτικής είχε ως αποτέλεσμα την εμφάνιση προειδοποιήσεων</translation>
@@ -694,7 +792,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> από <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Επιλογή στοιχείων επικοινωνίας</translation>
<translation id="5327248766486351172">Όνομα</translation>
+<translation id="5329858041417644019">Το πρόγραμμα περιήγησής σας δεν είναι διαχειριζόμενο</translation>
<translation id="5332219387342487447">Μέθοδος αποστολής</translation>
+<translation id="5334013548165032829">Λεπτομερή αρχεία καταγραφής συστήματος</translation>
<translation id="5344579389779391559">Αυτή η σελίδα μπορεί να προσπαθήσει να σας χρεώσει</translation>
<translation id="5355557959165512791">Δεν μπορείτε να επισκεφτείτε τον ιστότοπο <ph name="SITE" /> αυτήν τη στιγμή επειδή το πιστοποιητικό έχει ανακληθεί. Τα σφάλματα δικτύου και οι επιθέσεις είναι συνήθως προσωρινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουργήσει αργότερα.</translation>
<translation id="536296301121032821">Αποτυχία αποθήκευσης ρυθμίσεων πολιτικής</translation>
@@ -702,6 +802,7 @@
<translation id="5377026284221673050">"Το ρολόι σας πάει πίσω" ή "Το ρολόι σας πάει μπροστά" ή "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Για να χρησιμοποιείτε τις κάρτες σας σε όλες τις συσκευές, συνδεθείτε και ενεργοποιήστε τον συγχρονισμό.</translation>
<translation id="5386426401304769735">Η αλυσίδα πιστοποιητικού για αυτόν τον ιστότοπο περιέχει ένα πιστοποιητικό το οποίο είναι υπογεγραμμένο με χρήση SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">Αυτός ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του δεν είναι έγκυρο αυτήν τη στιγμή. Αυτό μπορεί να οφείλεται σε εσφαλμένη ρύθμιση ή σε κάποιον εισβολέα που παρεμβαίνει στη σύνδεσή σας.</translation>
<translation id="5421136146218899937">Διαγραφή δεδομένων περιήγησης...</translation>
<translation id="5430298929874300616">Κατάργηση σελιδοδείκτη</translation>
@@ -712,6 +813,7 @@
<translation id="5457113250005438886">Μη έγκυρο</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Επανάληψη επεξεργασίας</translation>
+<translation id="5478437291406423475">B6/C4 (Φάκελος)</translation>
<translation id="5481076368049295676">Αυτό το περιεχόμενο μπορεί να προσπαθήσει να εγκαταστήσει επικίνδυνο λογισμικό στη συσκευή σας το οποίο κλέβει ή διαγράφει τα στοιχεία σας. <ph name="BEGIN_LINK" />Εμφάνιση ούτως ή άλλως<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Προσθήκη έγκυρης διεύθυνσης</translation>
<translation id="5490432419156082418">Διευθύνσεις και άλλα</translation>
@@ -719,10 +821,12 @@
<ph name="LINE_BREAK" />
Δοκιμάστε να επικοινωνήσετε με το διαχειριστή δικτύου σας.</translation>
<translation id="549333378215107354">Μέγεθος 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Διαχειριζόμενοι σελιδοδείκτες</translation>
<translation id="5510766032865166053">Ενδέχεται να έχει μετακινηθεί ή να έχει διαγραφεί.</translation>
<translation id="5523118979700054094">Όνομα πολιτικής</translation>
<translation id="552553974213252141">Έγινε σωστή εξαγωγή του κειμένου;</translation>
+<translation id="553484882784876924">Prc6 (Φάκελος)</translation>
<translation id="5540224163453853">Δεν ήταν δυνατή η εύρεση του άρθρου που ζητήσατε.</translation>
<translation id="5541546772353173584">Προσθήκη διεύθυνσης ηλεκτρονικού ταχυδρομείου</translation>
<translation id="5545756402275714221">Άρθρα για εσάς</translation>
@@ -737,15 +841,21 @@
<translation id="5595485650161345191">Επεξεργασία διεύθυνσης</translation>
<translation id="5598944008576757369">Επιλογή τρόπου πληρωμής</translation>
<translation id="560412284261940334">Η διαχείριση δεν υποστηρίζεται</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">Ελέγξτε τη σύνδεση</translation>
<translation id="5610807607761827392">Μπορείτε να διαχειριστείτε τις κάρτες και τις διευθύνσεις στις <ph name="BEGIN_LINK" />Ρυθμίσεις<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> έκανε πάρα πολλές ανακατευθύνσεις.</translation>
<translation id="5629630648637658800">Αποτυχία φόρτωσης ρυθμίσεων πολιτικής</translation>
<translation id="5631439013527180824">Μη έγκυρο διακριτικό διαχείρισης συσκευής</translation>
+<translation id="5632627355679805402">Τα δεδομένα σας κρυπτογραφήθηκαν με τον <ph name="BEGIN_LINK" />κωδικό πρόσβασης Google<ph name="END_LINK" /> στις <ph name="TIME" />. Καταχωρίστε τον, για να ξεκινήσει ο συγχρονισμός.</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="563324245173044180">Το παραπλανητικό περιεχόμενο αποκλείστηκε.</translation>
<translation id="5659593005791499971">Διεύθυνση ηλεκτρονικού ταχυδρομείου</translation>
+<translation id="5663614846592581799">9x11 (Φάκελος)</translation>
+<translation id="5663955426505430495">Ο διαχειριστής αυτής της συσκευής εγκατέστησε επεκτάσεις για επιπλέον λειτουργίες. Οι επεκτάσεις έχουν πρόσβαση σε κάποια από τα δεδομένα σας.</translation>
<translation id="5675650730144413517">Αυτή η σελίδα δεν λειτουργεί</translation>
+<translation id="5684874026226664614">Ωχ. Δεν ήταν δυνατή η μετάφραση αυτής της σελίδας.</translation>
<translation id="5685654322157854305">Προσθήκη διεύθυνσης αποστολής</translation>
<translation id="5689199277474810259">Εξαγωγή σε JSON</translation>
<translation id="5689516760719285838">Τοποθεσία</translation>
@@ -754,38 +864,39 @@
<translation id="5710435578057952990">Η ταυτότητα αυτού του ιστότοπου δεν έχει επαληθευτεί.</translation>
<translation id="5719499550583120431">Οι προπληρωμένες κάρτες γίνονται δεκτές.</translation>
<translation id="5720705177508910913">Τρέχων χρήστης</translation>
+<translation id="5728056243719941842">C5 (Φάκελος)</translation>
<translation id="5730040223043577876">Το Chrome συνιστά την επαναφορά του κωδικού πρόσβασης, εάν τον έχετε χρησιμοποιήσει και σε άλλους ιστοτόπους.</translation>
<translation id="5732392974455271431">Οι γονείς σου μπορούν να καταργήσουν τον αποκλεισμό του</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Αποθήκευση κάρτας στον Λογαριασμό Google}other{Αποθήκευση καρτών στον Λογαριασμό Google}}</translation>
<translation id="5763042198335101085">Εισαγάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου</translation>
<translation id="5765072501007116331">Για να δείτε τρόπους και απαιτήσεις παράδοσης, επιλέξτε μια διεύθυνση</translation>
-<translation id="5770114862687765385">Το αρχείο φαίνεται να είναι κατεστραμμένο. Κάντε κλικ στο κουμπί "Επαναφορά" για να επαναφέρετε την περίοδο λειτουργίας.</translation>
<translation id="5778550464785688721">Πλήρης έλεγχος συσκευών MIDI</translation>
<translation id="578305955206182703">Καφεκίτρινο</translation>
<translation id="57838592816432529">Σίγαση</translation>
<translation id="5784606427469807560">Παρουσιάστηκε κάποιο πρόβλημα κατά την επιβεβαίωση της κάρτας σας. Ελέγξτε τη σύνδεσή σας στο διαδίκτυο και δοκιμάστε ξανά.</translation>
<translation id="5785756445106461925">Επίσης, αυτή η σελίδα περιέχει άλλους πόρους, οι οποίοι δεν είναι ασφαλείς. Αυτοί οι πόροι μπορούν να προβληθούν από άλλους χρήστες κατά τη μετάβαση και μπορούν να τροποποιηθούν από έναν εισβολέα ώστε να αλλάξει η εμφάνιση της σελίδας.</translation>
<translation id="5786044859038896871">Θέλετε να συμπληρωθούν τα στοιχεία της κάρτας σας;</translation>
+<translation id="5798290721819630480">Απόρριψη αλλαγών;</translation>
<translation id="5798683403665926540">Αλλαγή αρχικής σελίδας στις ρυθμίσεις του Chrome</translation>
<translation id="5803412860119678065">Θέλετε να συμπληρωθούν τα στοιχεία της κάρτας <ph name="CARD_DETAIL" />;</translation>
<translation id="5804241973901381774">Άδειες</translation>
<translation id="5810442152076338065">Η σύνδεσή σας στο <ph name="DOMAIN" /> κρυπτογραφείται χρησιμοποιώντας ένα απαρχαιωμένο πρόγραμμα κρυπτογράφησης.</translation>
<translation id="5813119285467412249">&amp;Επανάληψη προσθήκης</translation>
<translation id="5838278095973806738">Δεν θα πρέπει να εισαγάγετε ευαίσθητες πληροφορίες σε αυτόν τον ιστότοπο (για παράδειγμα, κωδικούς πρόσβασης ή πιστωτικές κάρτες), επειδή ενδέχεται να υποκλαπούν από εισβολείς.</translation>
+<translation id="5860033963881614850">Απενεργοποιημένη</translation>
<translation id="5863847714970149516">Η σελίδα που ακολουθεί μπορεί να προσπαθήσει να σας χρεώσει</translation>
<translation id="5866257070973731571">Προσθήκη αριθμού τηλεφώνου</translation>
<translation id="5869405914158311789">Δεν είναι δυνατή η πρόσβαση σε αυτόν τον ιστότοπο</translation>
<translation id="5869522115854928033">Αποθηκευμένοι κωδικοί πρόσβασης</translation>
<translation id="5887400589839399685">Η κάρτα αποθηκεύτηκε</translation>
-<translation id="5893718151540690985">αναφορά λίστας των διεπαφών δικτύου με τον τύπο τους και τις διευθύνσεις υλικού</translation>
<translation id="5893752035575986141">Οι πιστωτικές κάρτες γίνονται δεκτές.</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="5916664084637901428">Ενεργό</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Αποθήκευση κάρτας στον Λογαριασμό Google;</translation>
<translation id="5922853866070715753">Σχεδόν ολοκληρώθηκε</translation>
<translation id="5932224571077948991">Ο ιστότοπος εμφανίζει παρεμβατικές ή παραπλανητικές διαφημίσεις</translation>
-<translation id="5939518447894949180">Επαναφορά</translation>
<translation id="5946937721014915347">Άνοιγμα <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Δεν είναι δυνατή η εγγραφή με λογαριασμό καταναλωτή (διατίθεται σχετική άδεια).</translation>
<translation id="5967592137238574583">Επεξεργασία στοιχείων επικοινωνίας</translation>
@@ -793,6 +904,7 @@
<translation id="5975083100439434680">Σμίκρυνση</translation>
<translation id="5977489021191000276">Η διαχείριση της συσκευής σας δεν γίνεται από έναν διαχειριστή.</translation>
<translation id="5977976211062815271">Σε αυτήν τη συσκευή</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Δεν είναι δυνατό το άνοιγμα της εφαρμογής πληρωμής</translation>
<translation id="5989320800837274978">Δεν προσδιορίζονται ούτε οι σταθεροί διακομιστές μεσολάβησης ούτε μια διεύθυνση URL σεναρίου .pac.</translation>
<translation id="5990559369517809815">Τα αιτήματα για τον διακομιστή έχουν αποκλειστεί από μια επέκταση.</translation>
@@ -803,8 +915,8 @@
<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="6033927989869462158">αναφορά στατιστικών στοιχείων εξοπλισμού όπως της χρήσης CPU/RAM</translation>
<translation id="6034000775414344507">Ανοιχτό γκρι</translation>
+<translation id="6034283069659657473">10x14 (Φάκελος)</translation>
<translation id="6039846035001940113">Εάν το πρόβλημα παραμείνει, επικοινωνήστε με τον κάτοχο του ιστοτόπου.</translation>
<translation id="6040143037577758943">Κλείσιμο</translation>
<translation id="6044573915096792553">Μέγεθος 12</translation>
@@ -813,10 +925,10 @@
<translation id="6051221802930200923">Δεν μπορείτε να επισκεφτείτε το <ph name="SITE" /> αυτήν τη στιγμή επειδή ο ιστότοπος χρησιμοποιεί certificate pinning (κλείδωμα πιστοποιητικών). Τα σφάλματα δικτύου και οι επιθέσεις είναι συνήθως προσωρινά, συνεπώς αυτή η σελίδα πιθανότατα θα λειτουργήσει αργότερα.</translation>
<translation id="6058977677006700226">Χρήση των καρτών σας σε όλες τις συσκευές σας;</translation>
<translation id="6059925163896151826">Συσκευές USB</translation>
-<translation id="6071091556643036997">Ο τύπος πολιτικής δεν είναι έγκυρος.</translation>
<translation id="6080696365213338172">Η πρόσβασή σας στο περιεχόμενο πραγματοποιήθηκε με τη χρήση ενός πιστοποιητικού που παρασχέθηκε από διαχειριστή. Τα δεδομένα που παρέχετε στο <ph name="DOMAIN" /> μπορεί να ελέγχονται από το διαχειριστή σας.</translation>
<translation id="6094273045989040137">Σχολιασμός</translation>
<translation id="610911394827799129">Ο Λογαριασμός Google ενδέχεται να διαθέτει άλλες μορφές ιστορικού περιήγησης στη διεύθυνση <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Πληροφορίες σχετικά με εγκατεστημένες επεκτάσεις και προσθήκες</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{Κανένας}=1{1 κωδικός πρόσβασης (συγχρονισμένος)}other{# κωδικοί πρόσβασης (συγχρονισμένοι)}}</translation>
<translation id="6146055958333702838">Ελέγξτε τυχόν καλώδια και επανεκκινήστε δρομολογητές, μόντεμ ή άλλες συσκευές
του δικτύου που ενδεχομένως χρησιμοποιείτε.</translation>
@@ -851,15 +963,21 @@
<translation id="6337133576188860026">Απελευθερώνει λιγότερο από <ph name="SIZE" />. Ορισμένοι ιστότοποι μπορεί να φορτωθούν πιο αργά κατά την επόμενη επίσκεψή σας.</translation>
<translation id="6337534724793800597">Φιλτράρισμα πολιτικών με βάση το όνομα</translation>
<translation id="6358450015545214790">Τι σημαίνουν αυτά;</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Ακολουθούν πιθανές χρεώσεις.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 πρόταση ακόμα}other{# προτάσεις ακόμα}}</translation>
<translation id="6387754724289022810">Για πιο γρήγορες πληρωμές, αποθηκεύστε τα στοιχεία της κάρτας και τη διεύθυνση χρέωσης στον Λογαριασμό σας Google και σε αυτήν τη συσκευή.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Επεξεργασία σελιδοδείκτη</translation>
+<translation id="6406765186087300643">C0 (Φάκελος)</translation>
<translation id="6410264514553301377">Εισαγάγετε την ημερομηνία λήξης και τον κωδικό CVC για την κάρτα <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ρώτησες τους γονείς σου εάν σου επιτρέπουν να επισκεφτείς αυτόν τον ιστότοπο</translation>
<translation id="6417515091412812850">Δεν είναι δυνατόν να ελεγχθεί αν το πιστοποιητικό έχει ακυρωθεί.</translation>
<translation id="6433490469411711332">Επεξεργασία στοιχείων επαφής</translation>
<translation id="6433595998831338502">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> απέρριψε τη σύνδεση.</translation>
+<translation id="6434309073475700221">Απόρριψη</translation>
+<translation id="6446163441502663861">Kahu (Φάκελος)</translation>
<translation id="6446608382365791566">Προσθήκη περισσότερων πληροφοριών</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Επιβεβαίωση νέας υποβολής φόρμας</translation>
@@ -872,11 +990,17 @@
<translation id="6508722015517270189">Επανεκκινήστε το Chrome</translation>
<translation id="6529602333819889595">&amp;Επανάληψη διαγραφής</translation>
<translation id="6534179046333460208">Προτάσεις Φυσικού δικτύου</translation>
+<translation id="6556866813142980365">Επανάληψη ενέργειας</translation>
<translation id="6563469144985748109">Ο διαχειριστής σας δεν τον έχει εγκρίνει ακόμα</translation>
<translation id="6569060085658103619">Βλέπετε μια σελίδα επέκτασης</translation>
+<translation id="6578796323535178455">C2 (Φάκελος)</translation>
<translation id="6579990219486187401">Ανοιχτό ροζ</translation>
+<translation id="6583674473685352014">B6 (Φάκελος)</translation>
+<translation id="6587923378399804057">Σύνδεσμος που αντιγράψατε</translation>
+<translation id="6591833882275308647">Η συσκευή <ph name="DEVICE_TYPE" /> δεν είναι διαχειριζόμενη</translation>
<translation id="6596325263575161958">Επιλογές κρυπτογράφησης</translation>
<translation id="6604181099783169992">Αισθητήρες κίνησης ή φωτός</translation>
+<translation id="6609880536175561541">Prc7 (Φάκελος)</translation>
<translation id="6624427990725312378">Στοιχεία επικοινωνίας</translation>
<translation id="6626291197371920147">Προσθήκη έγκυρου αριθμού κάρτας</translation>
<translation id="6628463337424475685">Αναζήτηση <ph name="ENGINE" /></translation>
@@ -885,6 +1009,7 @@
<translation id="6644283850729428850">Αυτή η πολιτική έχει αποσυρθεί.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Κανένας}=1{Από 1 ιστότοπο (δεν θα αποσυνδεθείτε από τον Λογαριασμό σας Google)}other{Από # ιστοτόπους (δεν θα αποσυνδεθείτε από τον Λογαριασμό σας Google)}}</translation>
<translation id="6657585470893396449">Κωδικός πρόσβασης</translation>
+<translation id="6670613747977017428">Επιστροφή στην ασφάλεια.</translation>
<translation id="6671697161687535275">Να καταργηθεί η πρόταση φόρμας από το Chromium;</translation>
<translation id="6685834062052613830">Αποσυνδεθείτε και ολοκληρώστε την εγκατάσταση</translation>
<translation id="6710213216561001401">Προηγούμενο</translation>
@@ -892,12 +1017,15 @@
<translation id="671076103358959139">Διακριτικό εγγραφής:</translation>
<translation id="6711464428925977395">Υπάρχει κάποιο πρόβλημα με το διακομιστή μεσολάβησης ή η διεύθυνση είναι εσφαλμένη.</translation>
<translation id="6723740634201835758">Στον Λογαριασμό σας Google</translation>
+<translation id="6738516213925468394">Τα δεδομένα σας κρυπτογραφήθηκαν με τη <ph name="BEGIN_LINK" />φράση πρόσβασης συγχρονισμού<ph name="END_LINK" /> στις <ph name="TIME" />. Καταχωρίστε την, για να ξεκινήσει ο συγχρονισμός.</translation>
<translation id="674375294223700098">Άγνωστο σφάλμα πιστοποιητικού διακομιστή</translation>
<translation id="6744009308914054259">Ενώ περιμένετε για την επίτευξη κάποιας σύνδεσης, μπορείτε να μεταβείτε στις Λήψεις, για να διαβάσετε άρθρα εκτός σύνδεσης.</translation>
<translation id="6753269504797312559">Τιμή πολιτικής</translation>
<translation id="6757797048963528358">Η συσκευή σας τέθηκε σε αδράνεια.</translation>
+<translation id="6768213884286397650">Hagaki (Ταχυδρομική κάρτα)</translation>
<translation id="6778737459546443941">Ο γονέας σου δεν τον έχει εγκρίνει ακόμα</translation>
<translation id="67862343314499040">Βιολετί</translation>
+<translation id="6786747875388722282">Επεκτάσεις</translation>
<translation id="679355240208270552">Έγινε παράβλεψη επειδή η προεπιλεγμένη αναζήτηση δεν έχει ενεργοποιηθεί από την πολιτική.</translation>
<translation id="681021252041861472">Υποχρεωτικό πεδίο</translation>
<translation id="6810899417690483278">Αναγνωριστικό προσαρμογής</translation>
@@ -930,10 +1058,12 @@
<translation id="6965978654500191972">Συσκευή</translation>
<translation id="6970216967273061347">Περιφέρεια</translation>
<translation id="6973656660372572881">Καθορίζονται τόσο οι σταθεροί διακομιστές μεσολάβησης όσο και μια διεύθυνση URL σεναρίου .pac.</translation>
+<translation id="6973932557599545801">Δυστυχώς, δεν μπορώ να σας βοηθήσω, θα πρέπει να συνεχίσετε μόνοι σας.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Σίγαση (προεπιλογή)</translation>
<translation id="6984479912851154518">Αποχώρηση από την κατάσταση ιδιωτικής περιήγησης για πληρωμή μέσω εξωτερικής εφαρμογής. Συνέχεια;</translation>
<translation id="6989763994942163495">Εμφάνιση σύνθετων ρυθμίσεων…</translation>
+<translation id="6993898126790112050">6x9 (Φάκελος)</translation>
<translation id="6996312675313362352">Να μεταφράζονται πάντα τα <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Αυτές οι χρεώσεις μπορεί να είναι εφάπαξ ή επαναλαμβανόμενες και ίσως να μην είναι εμφανείς.</translation>
@@ -949,28 +1079,36 @@
<translation id="7108338896283013870">Απόκρυψη</translation>
<translation id="7108819624672055576">Επιτρέπεται από μια επέκταση</translation>
<translation id="7111012039238467737">(Έγκυρο)</translation>
+<translation id="7118618213916969306">Αναζήτηση URL στο πρόχειρο, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">Κλείστε τις άλλες καρτέλες ή τα προγράμματα</translation>
<translation id="7129409597930077180">Δεν είναι δυνατή η αποστολή σε αυτήν τη διεύθυνση. Επιλέξτε μια άλλη διεύθυνση.</translation>
<translation id="7135130955892390533">Εμφάνιση κατάστασης</translation>
<translation id="7138472120740807366">Μέθοδος προβολής</translation>
<translation id="7139724024395191329">Εμιράτο</translation>
+<translation id="7152423860607593928">Number-14 (Φάκελος)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Λιλά</translation>
-<translation id="7158980942472052083">Μη έγκυρο URL. Πρέπει να είναι URL με τυπικό σχήμα.</translation>
<translation id="717330890047184534">Αναγνωριστικό Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Ο διακομιστής στον οποίο μεταβαίνετε, <ph name="ORIGIN" />, έχει ζητήσει να εφαρμόζεται
+ μια πολιτική ασφαλείας σε όλα τα αιτήματα προς αυτόν. Αλλά αντί να
+ παραδώσει μια πολιτική, έκανε ανακατεύθυνση του προγράμματος περιήγησης σε άλλο σημείο, γεγονός που εμποδίζει
+ το πρόγραμμα περιήγησης να εκπληρώσει το αίτημά σας για τον ιστότοπο <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Αποθήκευση και συμπλήρωση τρόπων πληρωμής</translation>
<translation id="7180611975245234373">Ανανέωση</translation>
<translation id="7182878459783632708">Δεν έχουν οριστεί πολιτικές</translation>
<translation id="7186367841673660872">Αυτή η σελίδα έχει μεταφραστεί από τα<ph name="ORIGINAL_LANGUAGE" />στα<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Απελευθερώνει <ph name="SIZE" />. Ορισμένοι ιστότοποι μπορεί να φορτωθούν πιο αργά κατά την επόμενη επίσκεψή σας.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Ο διαχειριστής σας μπορεί να βλέπει:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> δεν συμμορφώνεται με τα πρότυπα ασφάλειας.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /> σχετικά με αυτό το πρόβλημα.</translation>
<translation id="7219179957768738017">Στη σύνδεση χρησιμοποιείται <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Επεξεργασία</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />, <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Ο ιστότοπος μετάβασης περιέχει κακόβουλο λογισμικό</translation>
+<translation id="724766306220616965">Προειδοποιήσεις, διένεξη</translation>
<translation id="724975217298816891">Εισαγάγετε την ημερομηνία λήξης και τον κωδικό CVC για την πιστωτική κάρτα <ph name="CREDIT_CARD" />, προκειμένου να ενημερώσετε τα στοιχεία της κάρτας σας. Μετά την επιβεβαίωση, θα κοινοποιηθούν τα στοιχεία της κάρτας σας με αυτόν τον ιστότοπο.</translation>
<translation id="7251437084390964440">Η διαμόρφωση δικτύου δεν συμμορφώνεται με το πρότυπο ONC. Ορισμένα τμήματα αυτής της διαμόρφωσης μπορεί να μην εισαχθούν
Πρόσθετες λεπτομέρειες:
@@ -983,11 +1121,14 @@
<translation id="7300012071106347854">Βαθύ μπλε</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Αναφορά σφαλμάτων που καταγράφηκε στις <ph name="CRASH_TIME" /> (η μεταφόρτωση ζητήθηκε από τον χρήστη, δεν έχει μεταφορτωθεί ακόμη)</translation>
+<translation id="7313965965371928911">Προειδοποιήσεις <ph name="BEGIN_LINK" />Ασφαλούς περιήγησης<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Βοήθεια σύνδεσης</translation>
<translation id="7334320624316649418">&amp;Επανάληψη αναδιάταξης</translation>
<translation id="733923710415886693">Το πιστοποιητικό του διακομιστή δεν αποκαλύφθηκε μέσω της Διαφάνειας πιστοποιητικών.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Γραμμή εντολών</translation>
-<translation id="7365061714576910172">Εξαγωγή Linux</translation>
<translation id="7372973238305370288">αποτέλεσμα αναζήτησης</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Όχι</translation>
@@ -995,6 +1136,7 @@
<translation id="7381288752349550461">Παράκαμψη διαχειριζόμενης περιόδου σύνδεσης</translation>
<translation id="7390545607259442187">Επιβεβαίωση κάρτας</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Η συσκευή <ph name="DEVICE_NAME" /> είναι διαχειριζόμενη</translation>
<translation id="7407424307057130981">&lt;p&gt;Το σφάλμα θα εμφανιστεί, εάν έχετε λογισμικό Superfish στον υπολογιστή σας με Windows.&lt;/p&gt;
&lt;p&gt;Ακολουθήστε αυτά τα βήματα, για να απενεργοποιήσετε προσωρινά το λογισμικό, προκειμένου να συνδεθείτε στον ιστό. Θα πρέπει να έχετε δικαιώματα διαχειριστή.&lt;/p&gt;
&lt;ol&gt;
@@ -1005,7 +1147,7 @@
&lt;li&gt;Κάντε κλικ στο κουμπί &lt;strong&gt;Εφαρμογή&lt;/strong&gt; και, έπειτα, στο κουμπί &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Επισκεφτείτε το &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Κέντρο βοήθειας του Chrome&lt;/a&gt;, για να μάθετε πώς μπορείτε να καταργήσετε οριστικά το λογισμικό από τον υπολογιστή σας
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Διαχείριση <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Διαχείριση κωδικών πρόσβασης…</translation>
<translation id="7419106976560586862">Διαδρομή προφίλ</translation>
<translation id="7437289804838430631">Προσθήκη στοιχείων επικοινωνίας</translation>
@@ -1014,22 +1156,24 @@
<translation id="7442725080345379071">Ανοιχτό πορτοκαλί</translation>
<translation id="7444046173054089907">Αυτός ο ιστότοπος είναι αποκλεισμένος</translation>
<translation id="7445762425076701745">Η ταυτότητα του διακομιστή στον οποίο έχετε συνδεθεί δεν μπορεί να επικυρωθεί πλήρως. Είστε συδεδεμένοι σε ένα διακομιστή χρησιμοποιώντας ένα όνομα που είναι έγκυρο μόνο εντός του δικτύου σας, την κατοχή του οποίου δεν έχει τρόπο να επικυρώσει μια εξωτερική αρχή πιστοποίησης. Καθώς ορισμένες αρχές πιστοποιητικών εκδίδουν πιστοποιητικά για αυτά τα ονόματα ούτως ή άλλως, δεν υπάρχει τρόπος να βεβαιωθείτε ότι είστε συνδεδεμένοι στον ιστότοπο που επιθυμείτε και όχι σε έναν εισβολέα.</translation>
-<translation id="7449109375006139765">αποστολή αρχείων καταγραφής συστήματος στον διακομιστή διαχείρισης</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Να μάθετε περισσότερα<ph name="END_LINK" /> σχετικά με αυτό το πρόβλημα.</translation>
<translation id="7455133967321480974">Χρήση καθολικής προεπιλεγμένης ρύθμισης (Αποκλεισμός)</translation>
<translation id="7460618730930299168">Η προβολή είναι διαφορετική από αυτήν που έχετε επιλέξει. Θέλετε να συνεχίσετε;</translation>
<translation id="7473891865547856676">Όχι, ευχαριστώ</translation>
-<translation id="7475525192983021547">αναφορά χρονικών περιόδων στις οποίες ένας χρήστης είναι ενεργός στη συσκευή</translation>
<translation id="7481312909269577407">Προώθηση</translation>
<translation id="7485870689360869515">Δεν βρέθηκαν δεδομένα</translation>
+<translation id="7498234416455752244">Συνέχιση επεξεργασίας</translation>
<translation id="7508255263130623398">Η εμφανιζόμενη συσκευή πολιτικής είναι κενή ή δεν αντιστοιχεί στο τρέχον αναγνωριστικό συσκευής</translation>
<translation id="7508870219247277067">Πράσινο αβοκάντο</translation>
<translation id="7511955381719512146">Το Wi-Fi που χρησιμοποιείτε ενδέχεται να σας ζητήσει να επισκεφτείτε τη διεύθυνση <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Λήψη</translation>
<translation id="7518003948725431193">Δεν βρέθηκε καμία ιστοσελίδα για τη διεύθυνση ιστού:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Φάκελος)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Η σύνδεσή σας σε αυτόν τον ιστότοπο δεν είναι ιδιωτική</translation>
+<translation id="7535087603100972091">Τιμή</translation>
<translation id="7537536606612762813">Υποχρεωτική</translation>
+<translation id="7538364083937897561">A2 (Φάκελος)</translation>
<translation id="7542403920425041731">Μετά την επιβεβαίωση, τα στοιχεία της κάρτας θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation>
<translation id="7542995811387359312">Η αυτόματη συμπλήρωση πιστωτικής κάρτας έχει απενεργοποιηθεί, επειδή αυτή η φόρμα δεν χρησιμοποιεί ασφαλή σύνδεση.</translation>
<translation id="7543525346216957623">Ζητήστε την άδεια του γονέα σας</translation>
@@ -1038,8 +1182,8 @@
<translation id="7552846755917812628">Δοκιμάστε τις παρακάτω συμβουλές:</translation>
<translation id="7554791636758816595">Νέα καρτέλα</translation>
<translation id="7564049878696755256">Μπορεί να χάσετε την πρόσβαση στον λογαριασμό σας <ph name="ORG_NAME" /> ή να πέσετε θύμα κλοπής στοιχείων ταυτότητας. Το Chrome συνιστά να αλλάξετε τον κωδικό πρόσβασής σας τώρα.</translation>
-<translation id="7566125604157659769">Κείμενο που αντιγράψατε</translation>
<translation id="7567204685887185387">Ο διακομιστής δεν μπόρεσε να αποδείξει ότι είναι <ph name="DOMAIN" />. Το πιστοποιητικό ασφαλείας του μπορεί να εκδόθηκε παράνομα. Αυτό μπορεί να οφείλεται σε λανθασμένη ρύθμιση ή σε κάποιον τρίτο που επιτίθεται στη σύνδεσή σας.</translation>
+<translation id="7568105740864181217">Η διαχείριση αυτού του προγράμματος περιήγησης πραγματοποιείται από μια εταιρεία, κάποιο σχολείο ή άλλον οργανισμό. Ο διαχειριστής σας μπορεί να αλλάξει τη ρύθμιση του προγράμματος περιήγησής σας απομακρυσμένα. Η διαχείριση της δραστηριότητας σε αυτήν τη συσκευή μπορεί επίσης να πραγματοποιηθεί εκτός Chrome. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Κατάργηση πιστωτικής κάρτας από το Chrome;</translation>
<translation id="7569983096843329377">Μαύρο</translation>
<translation id="7578104083680115302">Κάντε γρήγορες πληρωμές σε ιστότοπους και εφαρμογές σε διαφορετικές συσκευές χρησιμοποιώντας κάρτες που έχετε αποθηκεύσει στο Google.</translation>
@@ -1050,6 +1194,7 @@
<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="7633909222644580952">Δεδομένα απόδοσης και αναφορές σφαλμάτων</translation>
<translation id="7637571805876720304">Να καταργηθεί η πιστωτική κάρτα από το Chromium;</translation>
<translation id="7639968568612851608">Σκούρο γκρι</translation>
<translation id="765676359832457558">Απόκρυψη σύνθετων ρυθμίσεων…</translation>
@@ -1059,9 +1204,11 @@
<translation id="7667346355482952095">Το εμφανιζόμενο διακριτικό πολιτικής είναι κενό ή δεν αντιστοιχεί στο τρέχον διακριτικό</translation>
<translation id="7668654391829183341">Άγνωστη συσκευή</translation>
<translation id="7669271284792375604">Οι εισβολείς σε αυτόν τον ιστότοπο μπορεί να επιχειρήσουν να σας ξεγελάσουν, έτσι ώστε να εγκαταστήσετε προγράμματα που βλάπτουν την εμπειρία περιήγησής σας (για παράδειγμα, αλλάζοντας την αρχική σελίδα σας ή εμφανίζοντας επιπλέον διαφημίσεις στους ιστότοπους που επισκέπτεστε).</translation>
+<translation id="7676643023259824263">Αναζήτηση κειμένου σε πρόχειρο, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Αλλαγή μηχανής αναζήτησης</translation>
<translation id="7682287625158474539">Αποστολή</translation>
<translation id="7687186412095877299">Συμπληρώνει φόρμες πληρωμής με τους αποθηκευμένους τρόπους πληρωμής σας</translation>
+<translation id="7697066736081121494">Prc8 (Φάκελος)</translation>
<translation id="769721561045429135">Αυτήν τη στιγμή, έχετε κάρτες που μπορούν να χρησιμοποιηθούν μόνο σε αυτήν τη συσκευή. Κάντε κλικ στη Συνέχεια για να ελέγξετε τις κάρτες.</translation>
<translation id="7699293099605015246">Δεν υπάρχουν διαθέσιμα άρθρα αυτήν τη στιγμή</translation>
<translation id="7701040980221191251">Καμία</translation>
@@ -1073,11 +1220,13 @@
<translation id="774634243536837715">Το επικίνδυνο περιεχόμενο αποκλείστηκε.</translation>
<translation id="7752995774971033316">Χωρίς διαχείριση</translation>
<translation id="7755287808199759310">Ο γονέας σας μπορεί να καταργήσει τον αποκλεισμό του για εσάς</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Το τείχος προστασίας ή το λογισμικό προστασίας από ιούς ενδέχεται να έχει αποκλείσει τη σύνδεση.</translation>
<translation id="7759163816903619567">Τομέας προβολής:</translation>
<translation id="7761701407923456692">Το πιστοποιητικό του διακομιστή δεν συμφωνεί με τη διεύθυνση URL.</translation>
<translation id="7763386264682878361">Συντακτικός αναλυτής διακήρυξης πληρωμών</translation>
<translation id="7764225426217299476">Προσθήκη διεύθυνσης</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Νομός</translation>
<translation id="7791543448312431591">Προσθήκη</translation>
<translation id="7793809570500803535">Η ιστοσελίδα στη διεύθυνση <ph name="SITE" /> μπορεί να βρίσκεται προσωρινά εκτός λειτουργίας ή ίσως έχει μεταφερθεί μόνιμα σε νέα διεύθυνση ιστού.</translation>
@@ -1089,8 +1238,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Κατάργηση πρότασης φόρμας από το Chrome;</translation>
<translation id="7815407501681723534">Βρέθηκαν <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> για τον όρο αναζήτησης "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Διαχείριση πολιτικών</translation>
<translation id="782886543891417279">Το Wi-Fi που χρησιμοποιείτε (<ph name="WIFI_NAME" />) ενδέχεται να σας ζητήσει να επισκεφτείτε τη σελίδα σύνδεσής του.</translation>
+<translation id="7836231406687464395">Postfix (Φάκελος)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Κανένα}=1{1 εφαρμογή (<ph name="EXAMPLE_APP_1" />)}=2{2 εφαρμογές (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# εφαρμογές (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Ωστόσο, δεν είστε αόρατος/η. Με την κατάσταση ανώνυμης περιήγησης δεν μπορείτε να αποκρύψετε τα στοιχεία της περιήγησής σας από τους εργοδότες σας, τον πάροχο υπηρεσιών διαδικτύου που χρησιμοποιείτε ή τους ιστότοπους που επισκέπτεστε.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1099,7 +1248,7 @@
<translation id="7878562273885520351">Ο κωδικός πρόσβασής σας μπορεί να έχει παραβιαστεί</translation>
<translation id="7882421473871500483">Καφέ</translation>
<translation id="7887683347370398519">Ελέγξτε τον κωδικό σας CVC και δοκιμάστε ξανά</translation>
-<translation id="7893255318348328562">Όνομα περιόδου λειτουργίας</translation>
+<translation id="7904208859782148177">C3 (Φάκελος)</translation>
<translation id="79338296614623784">Εισαγάγετε έναν έγκυρο αριθμό τηλεφώνου</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Λήγει στις <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1109,21 +1258,25 @@
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Σελιδοδείκτες κινητής συσκευής</translation>
<translation id="7961015016161918242">Ποτέ</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Δεν καθορίστηκε</translation>
<translation id="800218591365569300">Δοκιμάστε να κλείσετε τις άλλες καρτέλες ή τα άλλα προγράμματα για να απελευθερώσετε μνήμη.</translation>
+<translation id="8004582292198964060">Πρόγραμμα περιήγησης</translation>
<translation id="8009225694047762179">Διαχείριση Κωδικός πρόσβασης</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Αυτή η κάρτα και η διεύθυνση χρέωσής της θα αποθηκευτούν. Θα μπορείτε να τη χρησιμοποιείτε όταν συνδέεστε στον λογαριασμό <ph name="USER_EMAIL" />.}other{Αυτές οι κάρτες και οι διευθύνσεις χρέωσής τους θα αποθηκευτούν. Θα μπορείτε να τις χρησιμοποιείτε όταν συνδέεστε στον λογαριασμό <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">Δεν ήταν δυνατή η επικοινωνία με τους γονείς σας αυτήν τη στιγμή. Δοκιμάστε ξανά.</translation>
<translation id="8025119109950072390">Οι εισβολείς σε αυτόν τον ιστότοπο μπορεί να σας ξεγελάσουν και να κάνετε κάτι επικίνδυνο, όπως να εγκαταστήσετε κάποιο λογισμικό ή να αποκαλύψετε προσωπικά σας στοιχεία (για παράδειγμα, κωδικούς πρόσβασης, αριθμούς τηλεφώνου ή πιστωτικές κάρτες).</translation>
<translation id="8034522405403831421">Αυτή η σελίδα είναι στα <ph name="SOURCE_LANGUAGE" />. Μετάφρασή της στα <ph name="TARGET_LANGUAGE" />;</translation>
<translation id="8035152190676905274">Πένα</translation>
+<translation id="8037117624646282037">Ποιοι χρησιμοποίησαν πρόσφατα τη συσκευή</translation>
<translation id="8037357227543935929">Να γίνεται ερώτηση (προεπιλογή)</translation>
<translation id="803771048473350947">Αρχείο</translation>
<translation id="8041089156583427627">Αποστολή σχολίων</translation>
<translation id="8041940743680923270">Χρήση καθολικής προεπιλεγμένης ρύθμισης (Ερώτηση)</translation>
<translation id="8042918947222776840">Επιλογή τρόπου παραλαβής</translation>
<translation id="8057711352706143257">Το λογισμικό "<ph name="SOFTWARE_NAME" />" δεν έχει διαμορφωθεί σωστά. Το πρόβλημα διορθώνεται συνήθως με την απεγκατάσταση του λογισμικού "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Η συσκευή σας έχει διαμορφωθεί ως εξής:</translation>
+<translation id="8066955247577885446">Δυστυχώς, παρουσιάστηκε κάποιο πρόβλημα.</translation>
+<translation id="8074253406171541171">10x13 (Φάκελος)</translation>
<translation id="8078141288243656252">Δεν είναι δυνατός ο σχολιασμός μετά από περιστροφή</translation>
<translation id="8079031581361219619">Να επαναληφθεί η φόρτωση του ιστοτόπου;</translation>
<translation id="8088680233425245692">Αποτυχία προβολής άρθρου.</translation>
@@ -1132,11 +1285,12 @@
<translation id="8091372947890762290">Η ενεργοποίηση στο διακομιστή εκκρεμεί</translation>
<translation id="8092774999298748321">Βαθύ μοβ</translation>
<translation id="8094917007353911263">Το δίκτυο που χρησιμοποιείτε ενδέχεται να σας ζητήσει να επισκεφτείτε τη διεύθυνση <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Οι μη έγκυρες κάρτες καταργήθηκαν</translation>
<translation id="8103161714697287722">Τρόπος πληρωμής</translation>
<translation id="8118489163946903409">Τρόπος πληρωμής</translation>
+<translation id="8123836779274890062">Η συσκευή <ph name="DEVICE_TYPE" /> είναι διαχειριζόμενη από τον τομέα <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Το λογισμικό "<ph name="SOFTWARE_NAME" />" δεν εγκαταστάθηκε σωστά στον υπολογιστή ή στο δίκτυό σας. Ζητήστε από τον διαχειριστή IT να επιλύσει αυτό το πρόβλημα.</translation>
-<translation id="8130693978878176684">Δεν μπορώ να σας βοηθήσω περισσότερο, θα πρέπει να συνεχίσετε μόνοι σας.</translation>
<translation id="8131740175452115882">Επιβεβαίωση</translation>
<translation id="8149426793427495338">Ο υπολογιστής σας τέθηκε σε αδράνεια.</translation>
<translation id="8150722005171944719">Δεν είναι δυνατή η ανάγνωση του αρχείου στη διεύθυνση <ph name="URL" />. Ενδέχεται να καταργήθηκε, να μετακινήθηκε ή τα δικαιώματα αρχείου μπορεί να μην επιτρέπουν την πρόσβαση.</translation>
@@ -1146,8 +1300,11 @@
<translation id="8197543752516192074">Μετάφραση σελίδας</translation>
<translation id="8201077131113104583">Η διεύθυνση URL ενημέρωσης για την επέκταση με αναγνωριστικό ID "<ph name="EXTENSION_ID" />", δεν είναι έγκυρη.</translation>
<translation id="8202097416529803614">Σύνοψη παραγγελίας</translation>
+<translation id="8202370299023114387">Διένεξη</translation>
+<translation id="8206978196348664717">Prc4 (Φάκελος)</translation>
<translation id="8211406090763984747">Η σύνδεση είναι ασφαλής</translation>
<translation id="8218327578424803826">Εκχωρημένη τοποθεσία:</translation>
+<translation id="8220146938470311105">C7/C6 (Φάκελος)</translation>
<translation id="8225771182978767009">Το άτομο που ρύθμισε αυτόν τον υπολογιστή επέλεξε να αποκλείσει αυτόν τον ιστότοπο.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">Ανοίξτε τη σελίδα σε μια νέα καρτέλα ανώνυμης περιήγησης</translation>
@@ -1159,14 +1316,16 @@
<translation id="825929999321470778">Εμφάνιση όλων των αποθηκευμένων κωδικών πρόσβασης</translation>
<translation id="8261506727792406068">Διαγραφή</translation>
<translation id="8267698848189296333">Σύνδεση ως <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Αυτό το πρόγραμμα περιήγησης είναι διαχειριζόμενο από τον τομέα <ph name="ENROLLMENT_DOMAIN" />. Ο διαχειριστής σας μπορεί να αλλάξει τη ρύθμιση του προγράμματος περιήγησης απομακρυσμένα. Η διαχείριση της δραστηριότητας σε αυτήν τη συσκευή μπορεί επίσης να πραγματοποιηθεί εκτός Chrome. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Σύνδεση</translation>
<translation id="8288807391153049143">Εμφάνιση πιστοποιητικού</translation>
<translation id="8289355894181816810">Επικοινωνήστε με το διαχειριστή του δικτύου σας εάν δεν είστε βέβαιοι για το τι σημαίνει αυτό.</translation>
<translation id="8293206222192510085">Προσθήκη σελιδοδείκτη</translation>
<translation id="8294431847097064396">Πηγή</translation>
<translation id="8298115750975731693">Το Wi-Fi που χρησιμοποιείτε (<ph name="WIFI_NAME" />) ενδέχεται να σας ζητήσει να επισκεφτείτε τη διεύθυνση <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Η μετάφραση απέτυχε λόγω προβλήματος με τη σύνδεση δικτύου.</translation>
-<translation id="8311129316111205805">Φόρτωση περιόδου λειτουργίας</translation>
<translation id="8332188693563227489">Απορρίφθηκε η πρόσβαση στο κεντρικό υπολογιστή <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">Εάν κατανοείτε τους κινδύνους για την ασφάλειά σας, μπορείτε να <ph name="BEGIN_LINK" />επισκεφτείτε αυτόν τον ιστότοπο<ph name="END_LINK" /> πριν από την κατάργηση των επικίνδυνων προγραμμάτων.</translation>
@@ -1184,7 +1343,6 @@
<translation id="8416694386774425977">Η διαμόρφωση δικτύου είναι μη έγκυρη και δεν ήταν δυνατή η εισαγωγή της.
Πρόσθετες λεπτομέρειες:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Η διαχείριση της συσκευής γίνεται από <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Αλλαγή</translation>
<translation id="8428213095426709021">Ρυθμίσεις</translation>
@@ -1212,9 +1370,11 @@
<translation id="860043288473659153">Όνομα κατόχου κάρτας</translation>
<translation id="861775596732816396">Μέγεθος 4</translation>
<translation id="8620436878122366504">Οι γονείς σας δεν τον έχουν εγκρίνει ακόμα</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Αποθήκευση αυτής της κάρτας στη συγκεκριμένη συσκευή</translation>
<translation id="8663226718884576429">Σύνοψη παραγγελίας, <ph name="TOTAL_LABEL" />, Περισσότερες λεπτομέρειες</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, απάντηση, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Η σύνδεσή σας με τον τομέα <ph name="DOMAIN" /> δεν είναι κρυπτογραφημένη.</translation>
<translation id="8718314106902482036">Η πληρωμή δεν ολοκληρώθηκε</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, πρόταση αναζήτησης</translation>
@@ -1228,6 +1388,7 @@
<translation id="8761567432415473239">Η ασφαλής περιήγηση Google <ph name="BEGIN_LINK" />εντόπισε επιβλαβή προγράμματα<ph name="END_LINK" /> πρόσφατα στο <ph name="SITE" />.</translation>
<translation id="8763927697961133303">Συσκευή USB</translation>
<translation id="8768895707659403558">Για να χρησιμοποιείτε τις κάρτες σας σε όλες τις συσκευές σας, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Επανάληψη διαγραφής</translation>
<translation id="8792621596287649091">Μπορεί να χάσετε την πρόσβαση στον λογαριασμό σας <ph name="ORG_NAME" /> ή να πέσετε θύμα κλοπής στοιχείων ταυτότητας. Το Chromium συνιστά να αλλάξετε τον κωδικό πρόσβασής σας τώρα.</translation>
<translation id="8800988563907321413">Οι προτάσεις σε κοντινή απόσταση εμφανίζονται εδώ</translation>
@@ -1238,10 +1399,12 @@
<translation id="885730110891505394">Κοινοποίηση στις υπηρεσίες της Google</translation>
<translation id="8858065207712248076">Το Chrome συνιστά την επαναφορά του κωδικού πρόσβασης <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> εάν τον έχετε χρησιμοποιήσει και σε άλλους ιστοτόπους.</translation>
<translation id="8866481888320382733">Σφάλμα ανάλυσης ρυθμίσεων πολιτικής</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Έκλεισαν πρόσφατα</translation>
<translation id="8874824191258364635">Εισαγάγετε έναν έγκυρο αριθμό κάρτας</translation>
<translation id="8891727572606052622">Μη έγκυρη λειτουργία διακομιστή μεσολάβησης.</translation>
<translation id="8903921497873541725">Μεγέθυνση</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Θέλετε να αποθηκεύσετε αυτήν την κάρτα στο Λογαριασμό σας Google;</translation>
<translation id="8932102934695377596">Το ρολόι σας πάει πίσω</translation>
<translation id="893332455753468063">Προσθήκη ονόματος</translation>
@@ -1249,13 +1412,13 @@
<translation id="894185898663964645">Ο διαχειριστής σας έχει διαμορφώσει προσαρμοσμένα πιστοποιητικά ρίζας, τα οποία ενδέχεται να επιτρέπουν στον διαχειριστή να βλέπει το περιεχόμενο των ιστοτόπων που επισκέπτεστε.</translation>
<translation id="8943282376843390568">Λάιμ</translation>
<translation id="8957210676456822347">Εξουσιοδότηση πύλης υποδοχής</translation>
+<translation id="8966619695390250636">Μήπως εννοείτε;</translation>
<translation id="8968766641738584599">Αποθήκευση κάρτας</translation>
<translation id="8971063699422889582">Το πιστοποιητικό του διακομιστή έχει λήξει.</translation>
<translation id="8975012916872825179">Περιλαμβάνει πληροφορίες, όπως αριθμούς τηλεφώνου, διευθύνσεις ηλεκτρονικού ταχυδρομείου και διευθύνσεις αποστολής</translation>
<translation id="8978053250194585037">Πρόσφατα, η Ασφαλής περιήγηση Google <ph name="BEGIN_LINK" />εντόπισε εκδηλώσεις ηλεκτρονικού ψαρέματος (phishing)<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι ηλεκτρονικού ψαρέματος (phishing) παρουσιάζονται ψευδώς σαν άλλου τύπου ιστότοποι, για να σας εξαπατήσουν.</translation>
<translation id="8983003182662520383">Τρόποι πληρωμής και διευθύνσεις που χρησιμοποιούν το Google Pay</translation>
<translation id="8987927404178983737">Μήνας</translation>
-<translation id="8988408250700415532">Παρουσιάστηκε κάποιο πρόβλημα. Μπορείτε να ολοκληρώσετε την παραγγελία σας στον ιστότοπο.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Ο ιστότοπος που πρόκειται να επισκεφτείτε περιέχει κακόβουλα προγράμματα</translation>
<translation id="8997023839087525404">Ο διακομιστής παρουσίασε ένα πιστοποιητικό το οποίο δεν αποκαλύφθηκε δημοσίως με χρήση της πολιτικής Διαφάνειας πιστοποιητικών. Αυτό απαιτείται για ορισμένα πιστοποιητικά, προκειμένου να διασφαλιστεί ότι είναι αξιόπιστα και παρέχουν προστασία ενάντια σε εισβολείς.</translation>
@@ -1265,6 +1428,7 @@
<translation id="9011424611726486705">Άνοιγμα ρυθμίσεων ιστοτόπου</translation>
<translation id="9020200922353704812">Απαιτείται διεύθυνση χρέωσης της κάρτας</translation>
<translation id="9020542370529661692">Αυτή η σελίδα έχει μεταφραστεί στα <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Μη έγκυρο)</translation>
<translation id="9035022520814077154">Σφάλμα ασφάλειας</translation>
<translation id="9038649477754266430">Χρήση μιας υπηρεσίας πρόβλεψης για ταχύτερη φόρτωση σελίδων</translation>
@@ -1276,11 +1440,11 @@
<translation id="9065745800631924235">Αναζήτηση <ph name="TEXT" /> από το ιστορικό</translation>
<translation id="9069693763241529744">Αποκλείστηκε από μια επέκταση</translation>
<translation id="9076283476770535406">Μπορεί να διαθέτει περιεχόμενο για ενηλίκους</translation>
+<translation id="9076630408993835509">Αυτός ο ιστότοπος δεν είναι διαχειριζόμενος από κάποια εταιρεία ή άλλον οργανισμό. Η διαχείριση της δραστηριότητας σε αυτήν τη συσκευή μπορεί να πραγματοποιηθεί εκτός Chrome. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Απαιτούνται περισσότερες πληροφορίες</translation>
<translation id="9080712759204168376">Σύνοψη παραγγελίας</translation>
<translation id="9103872766612412690">Κανονικά, ο ιστότοπος <ph name="SITE" /> χρησιμοποιεί κρυπτογράφηση για να προστατεύει τα στοιχεία σας. Όταν το Chromium επιχείρησε πρόσφατα να συνδεθεί στο <ph name="SITE" />, ο ιστότοπος ανταποκρίθηκε δημιουργώντας ασυνήθιστα και εσφαλμένα διαπιστευτήρια. Αυτό μπορεί να συμβεί όταν κάποιος εισβολέας προσπαθεί να υποκριθεί ότι είναι ο ιστότοπος <ph name="SITE" /> ή όταν κάποια οθόνη σύνδεσης Wi-Fi έχει διακόψει τη σύνδεσή σας. Τα στοιχεία σας εξακολουθούν να είναι ασφαλή επειδή το Chromium διέκοψε τη σύνδεση πριν από την ανταλλαγή δεδομένων.</translation>
<translation id="9106062320799175032">Προσθήκη διεύθυνσης χρέωσης</translation>
-<translation id="9110718169272311511">Ο Βοηθός Google στο Chrome είναι διαθέσιμος κοντά στο κάτω μέρος της οθόνης</translation>
<translation id="9114524666733003316">Επιβεβαίωση κάρτας…</translation>
<translation id="9128870381267983090">Σύνδεση σε δίκτυο</translation>
<translation id="9137013805542155359">Εμφάνιση πρωτοτύπου</translation>
@@ -1289,6 +1453,7 @@
<translation id="9148507642005240123">&amp;Αναίρεση επεξεργασίας</translation>
<translation id="9154194610265714752">Ενημερώθηκε</translation>
<translation id="9157595877708044936">Ρύθμιση...</translation>
+<translation id="9158625974267017556">C6 (Φάκελος)</translation>
<translation id="9168814207360376865">Να επιτρέπεται σε ιστοτόπους να ελέγχουν αν έχετε αποθηκεύσει τρόπους πληρωμής</translation>
<translation id="9169664750068251925">Να γίνεται πάντα αποκλεισμός σε αυτόν τον ιστότοπο</translation>
<translation id="9170848237812810038">Αναί&amp;ρεση</translation>
@@ -1303,10 +1468,12 @@
<translation id="9219103736887031265">Εικόνες</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ΔΙΑΓΡΑΦΗ ΦΟΡΜΑΣ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Μπορεί να χάσετε την πρόσβαση στον Λογαριασμό σας Google. Το Chromium συνιστά να αλλάξετε τον κωδικό πρόσβασής σας τώρα. Θα σας ζητηθεί να συνδεθείτε.</translation>
<translation id="939736085109172342">Νέος φάκελος</translation>
<translation id="945855313015696284">Ελέγξτε τις πληροφορίες παρακάτω και διαγράψτε τυχόν μη έγκυρες κάρτες</translation>
<translation id="951104842009476243">Αποδεκτές χρεωστικές και προπληρωμένες κάρτες</translation>
+<translation id="958202389743790697">Αποκλείστηκε σύμφωνα με την πολιτική ασφαλείας του <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Αυτό το περιεχόμενο μπορεί να επιχειρήσει να εγκαταστήσει παραπλανητικές εφαρμογές που προσποιούνται ότι είναι κάτι άλλο ή συλλέγουν δεδομένα τα οποία μπορεί να χρησιμοποιηθούν για την παρακολούθησή σας. <ph name="BEGIN_LINK" />Να εμφανίζεται ούτως ή άλλως<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Επίσημη έκδοση</translation>
<translation id="973773823069644502">Προσθήκη διεύθυνσης παράδοσης</translation>
@@ -1315,6 +1482,7 @@
<translation id="984275831282074731">Τρόποι πληρωμής</translation>
<translation id="985199708454569384">&lt;p&gt;Αυτό το σφάλμα θα εμφανιστεί εάν η ημερομηνία και η ώρα του υπολογιστή ή της κινητής συσκευής σας είναι ανακριβείς.&lt;/p&gt;
&lt;p&gt;Για να διορθώσετε το σφάλμα, ανοίξτε το ρολόι της συσκευής. Βεβαιωθείτε ότι η ώρα και η ημερομηνία είναι σωστές.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Έκδοση προγραμματιστή</translation>
<translation id="989988560359834682">Επεξεργασία διεύθυνσης</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_en-GB.xtb b/chromium/components/strings/components_strings_en-GB.xtb
index 7769328c7f1..2ccfe6773d7 100644
--- a/chromium/components/strings/components_strings_en-GB.xtb
+++ b/chromium/components/strings/components_strings_en-GB.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="en-GB">
-<translation id="1005145902654145231">Failed to rename the session.</translation>
<translation id="1008557486741366299">Not Now</translation>
<translation id="1010200102790553230">Load page later</translation>
<translation id="1015730422737071372">Provide additional details.</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">unknown name</translation>
<translation id="1050038467049342496">Close other apps</translation>
<translation id="1055184225775184556">&amp;Undo Add</translation>
+<translation id="1056898198331236512">Warning</translation>
<translation id="1058479211578257048">Saving cards...</translation>
<translation id="10614374240317010">Never saved</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Desktop Bookmarks</translation>
<translation id="1074497978438210769">Not secure</translation>
<translation id="1080116354587839789">Fit to width</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Add Name on Card</translation>
<translation id="1089439967362294234">Change Password</translation>
<translation id="109743633954054152">Manage passwords in Chrome settings</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Warnings may be common while websites update their security. This should improve soon.</translation>
<translation id="1126551341858583091">The size on the local storage is <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Policy cache OK</translation>
+<translation id="1131264053432022307">Image that you copied</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Rename</translation>
<translation id="1175364870820465910">&amp;Print...</translation>
<translation id="1181037720776840403">Remove</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Your device name</translation>
<translation id="124116460088058876">More languages</translation>
<translation id="1250759482327835220">To pay faster next time, save your card, name and billing address to your Google Account.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synced)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Command-line variations</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="1314614906530272393">The selected session does not exist.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Search for clipboard image</translation>
<translation id="1323433172918577554">Show More</translation>
<translation id="132390688737681464">Save and Fill Addresses</translation>
<translation id="1333989956347591814">Your activity <ph name="BEGIN_EMPHASIS" />might still be visible<ph name="END_EMPHASIS" /> to:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Pickup address</translation>
<translation id="1348198688976932919">The site ahead contains dangerous apps</translation>
<translation id="1348779747280417563">Confirm name</translation>
+<translation id="1357195169723583938">Who has used the device recently and when</translation>
+<translation id="1364822246244961190">This policy is blocked; its value will be ignored.</translation>
<translation id="1374468813861204354">suggestions</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">About Version</translation>
<translation id="1376836354785490390">Show Less</translation>
<translation id="1377321085342047638">Card Number</translation>
<translation id="138218114945450791">Light blue</translation>
+<translation id="1382194467192730611">USB device allowed by your administrator</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> didn’t send any data.</translation>
+<translation id="140316286225361634">The site <ph name="ORIGIN" /> has requested that a security policy will apply to all its request, and this policy presently deems the site unsafe.</translation>
<translation id="1405567553485452995">Light green</translation>
<translation id="1407135791313364759">Open all</translation>
<translation id="1413809658975081374">Privacy error</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Yes</translation>
<translation id="1430915738399379752">Print</translation>
<translation id="1455413310270022028">Eraser</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Show more</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Choose delivery address</translation>
+<translation id="1492194039220927094">Policies push:</translation>
<translation id="1501859676467574491">Show cards from your Google Account</translation>
-<translation id="1506687042165942984">Show a saved (i.e. known to be out of date) copy of this page.</translation>
<translation id="1507202001669085618">&lt;p&gt;You'll see this error if you're using a Wi-Fi portal where you have to sign in before you can get online.&lt;/p&gt;
&lt;p&gt;To fix the error, click &lt;strong&gt;Connect&lt;/strong&gt; on the page that you're trying to open.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Phone number required</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Build Date</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">Waiting for connection…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">This page says</translation>
<translation id="153384715582417236">That’s all for now</translation>
<translation id="154408704832528245">Choose delivery address</translation>
<translation id="1549470594296187301">JavaScript must be enabled to use this feature.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Enter expiry date</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Image that you copied</translation>
<translation id="1620510694547887537">Camera</translation>
<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">End session</translation>
<translation id="1639239467298939599">Loading</translation>
<translation id="1640180200866533862">User policies</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">The server certificate contains a weak cryptographic key.</translation>
<translation id="1697532407822776718">You're all set!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Document is too large to be annotated</translation>
<translation id="1721312023322545264">You need permission from <ph name="NAME" /> to visit this site</translation>
<translation id="1721424275792716183">* Field is required</translation>
@@ -144,7 +161,8 @@
<translation id="1734864079702812349">Amex</translation>
<translation id="1734878702283171397">Try contacting the system admin.</translation>
<translation id="1740951997222943430">Enter a valid expiry month</translation>
-<translation id="1743520634839655729">To pay faster next time, save your card, name and billing address to your Google Accountand to this device.</translation>
+<translation id="1743520634839655729">To pay faster next time, save your card, name and billing address to your Google Account and to this device.</translation>
+<translation id="1745880797583122200">Your browser is managed</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Please update your sync passphrase.</translation>
<translation id="1787142507584202372">Your open tabs appear here</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Cardholder Name</translation>
<translation id="1821930232296380041">Invalid request or request parameters</translation>
+<translation id="1822540298136254167">Websites that you visit and time spent on them</translation>
<translation id="1826516787628120939">Checking</translation>
<translation id="1834321415901700177">This site contains harmful programs</translation>
<translation id="1839551713262164453">Validation of policy values has failed with errors</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Clear Chrome's browsing history data</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{and 1 more}other{and # more}}</translation>
<translation id="2003709556000175978">Reset your password now</translation>
+<translation id="20053308747750172">The server that you are going to, <ph name="ORIGIN" />, has requested that a security policy will be applied to all requests to it. But it has now delivered an invalid policy, which prevents the browser from fulfilling your request for <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy is set to auto-configured.</translation>
<translation id="2030481566774242610">Did you mean <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Checking the proxy and the firewall<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Department</translation>
<translation id="2102134110707549001">Suggest strong password…</translation>
<translation id="2108755909498034140">Restart your computer</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Card</translation>
<translation id="2114841414352855701">Ignored because it was overridden by <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobile Bookmarks</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Policies</translation>
<translation id="2183608646556468874">Phone Number</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 address}other{# addresses}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Phone number</translation>
<translation id="2283340219607151381">Save and fill addresses</translation>
<translation id="2292556288342944218">Your Internet access is blocked</translation>
+<translation id="2294558542833290837">The link that you originally opened is unusual</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Frees up less than 1 MB. Some sites may load more slowly on your next visit.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requires a username and password.</translation>
<translation id="2317583587496011522">Debit cards are accepted.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, expires on <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Setting controlled by your administrator</translation>
+<translation id="2346319942568447007">Image that you copied</translation>
<translation id="2349790679044093737">VR session is active</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>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">Crash report captured on <ph name="CRASH_TIME" /> was not uploaded</translation>
<translation id="2367567093518048410">Level</translation>
<translation id="2378238891085281592">You’ve gone private</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">The server that you are going to, <ph name="ORIGIN" />, has requested that a security policy will be applied to all requests to it. But it has now failed to deliver a policy, which prevents the browser from fulfilling your request for <ph name="SITE" />.</translation>
<translation id="244665789865330679">Your device and account is managed by <ph name="ENROLLMENT_DOMAIN" />. This means that your administrator may remotely configure your device and account.</translation>
<translation id="2463193859425327265">Change home page</translation>
<translation id="2463739503403862330">Fill in</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Choose delivery method</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Running Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Translate this page</translation>
<translation id="2479410451996844060">Invalid search URL.</translation>
<translation id="2482878487686419369">Notifications</translation>
<translation id="248348093745724435">Machine policies</translation>
+<translation id="2485387744899240041">Usernames for your device and browser</translation>
<translation id="2491120439723279231">Server's certificate contains errors.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Scan new card</translation>
<translation id="2501278716633472235">Go back</translation>
<translation id="2503184589641749290">Accepted debit and prepaid cards</translation>
<translation id="2515629240566999685">Checking the signal in your area</translation>
-<translation id="2516852381693169964">Search <ph name="SEARCH_ENGINE" /> for image</translation>
<translation id="2523886232349826891">Saved on this device only</translation>
<translation id="2524461107774643265">Add More Information</translation>
<translation id="2536110899380797252">Add Address</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">Your clock is ahead</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" />’s server IP address could not be found.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Close other tabs or apps</translation>
<translation id="267371737713284912">press <ph name="MODIFIER_KEY_DESCRIPTION" /> to undo</translation>
<translation id="2674170444375937751">Are you sure that you want to delete these pages from your history?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Leave</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Accepted Cards</translation>
<translation id="2702801445560668637">Reading List</translation>
<translation id="2704283930420550640">Value doesn't match format.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Remove selected items</translation>
<translation id="277133753123645258">Delivery method</translation>
<translation id="277499241957683684">Missing device record</translation>
-<translation id="2781030394888168909">Export MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">The connection was reset.</translation>
<translation id="2788784517760473862">Accepted credit cards</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Open incognito window</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">You need permission to visit this site</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Save card?</translation>
<translation id="2903493209154104877">Addresses</translation>
<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Delivery Method</translation>
<translation id="2928905813689894207">Billing Address</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Wrong policy type</translation>
<translation id="3037605927509011580">Aw, Snap!</translation>
<translation id="3041612393474885105">Certificate Information</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Add pickup address</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3109728660330352905">You don't have authorisation to view this page.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> on <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancel payment</translation>
<translation id="3207960819495026254">Bookmarked</translation>
-<translation id="3209375525920864198">Please enter a valid session name.</translation>
+<translation id="321912867715453276">Warning: More than one source is present for the policy, but the values are the same.</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="3229041911291329567">Version information about your device and browser</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Add name on card</translation>
<translation id="3287510313208355388">Download when online</translation>
<translation id="3293642807462928945">Learn more about <ph name="POLICY_NAME" /> policy</translation>
<translation id="3303855915957856445">No search results found</translation>
-<translation id="3305707030755673451">Your data was encrypted with your sync passphrase on <ph name="TIME" />. Enter it to start sync.</translation>
<translation id="3320021301628644560">Add billing address</translation>
<translation id="3324983252691184275">Crimson</translation>
<translation id="3338095232262050444">Secure</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;Redo Edit</translation>
<translation id="342781501876943858">Chromium recommends resetting your password if you reused it on other sites.</translation>
<translation id="3431636764301398940">Save this card to this device</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">The owner of this device turned off the dinosaur game.</translation>
<translation id="3447884698081792621">Show certificate (issued by <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Fetch interval:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Highlighter</translation>
<translation id="3462200631372590220">Hide advanced</translation>
<translation id="3467763166455606212">Cardholder name required</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">Credit and prepaid cards are accepted.</translation>
<translation id="3582930987043644930">Add name</translation>
<translation id="3583757800736429874">&amp;Redo Move</translation>
+<translation id="35866233670761917">The contents of websites that you visit is not seen by your administrators</translation>
<translation id="3586931643579894722">Hide details</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Size 2</translation>
<translation id="3615877443314183785">Enter a valid expiry date</translation>
<translation id="36224234498066874">Clear Browsing Data...</translation>
<translation id="362276910939193118">Show Full History</translation>
-<translation id="3623476034248543066">Show value</translation>
<translation id="3630155396527302611">If it is already listed as a program allowed to access the network, try
removing it from the list and adding it again.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validation successful</translation>
<translation id="3655670868607891010">If you're seeing this frequently, try these <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revision</translation>
<translation id="366077651725703012">Update credit card</translation>
<translation id="3676592649209844519">Device ID:</translation>
+<translation id="3677008721441257057">Did you mean &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Request could not be signed</translation>
<translation id="3678529606614285348">Open page in a new Incognito window (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Crash report captured on <ph name="CRASH_TIME" />, uploaded on <ph name="UPLOAD_TIME" /></translation>
@@ -451,29 +497,32 @@
<translation id="3704162925118123524">The network that you are using may require you to visit its log-in page.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Loading...</translation>
+<translation id="3709599264800900598">Text that you copied</translation>
<translation id="3712624925041724820">Licenses exhausted</translation>
<translation id="3714780639079136834">Turning on mobile data or Wi-Fi</translation>
<translation id="3715597595485130451">Connect to Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Checking the proxy, firewall and DNS configuration<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Applications that can cause this error include antivirus, firewall and web-filtering or proxy software.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Once you confirm, card details from your Google Accountwill be shared with this site.</translation>
+<translation id="3745099705178523657">Once you confirm, card details from your Google Account will be shared with this site.</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="3761718714832595332">Hide status</translation>
<translation id="3765032636089507299">The Safe Browsing page is under construction.</translation>
-<translation id="3778403066972421603">Do you want to save this card to yourGoogle Accountand on this device?</translation>
+<translation id="3778403066972421603">Do you want to save this card to your Google Account and on this device?</translation>
<translation id="3781428340399460090">Hot pink</translation>
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expires <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Size 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Harmful content blocked.</translation>
<translation id="3810973564298564668">Manage</translation>
<translation id="382518646247711829">If you use a proxy server...</translation>
<translation id="3828924085048779000">Empty passphrase is not allowed.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> has installed extensions for additional functions. Extensions have access to some of your data.</translation>
<translation id="385051799172605136">Back</translation>
<translation id="3858027520442213535">Update date and time</translation>
<translation id="3884278016824448484">Conflicting device identifier</translation>
@@ -481,6 +530,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Always ask on this site</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>
@@ -491,11 +541,13 @@
<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="3984550557525787191">This session name already exists.</translation>
<translation id="3987940399970879459">Less than 1 MB</translation>
+<translation id="4008849406247176967">Warning: More than one source with conflicting values is present for this policy.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 web page nearby}other{# web pages nearby}}</translation>
<translation id="4030383055268325496">&amp;Undo add</translation>
+<translation id="4032320456957708163">Your browser is managed by <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Key "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Add Valid Address</translation>
<translation id="4072486802667267160">There was an error processing your order. Please try again.</translation>
<translation id="4075732493274867456">The client and server don't support a common SSL protocol version or cipher suite.</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">Purple</translation>
<translation id="4165986682804962316">Site settings</translation>
<translation id="4171400957073367226">Bad verification signature</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> more item}other{<ph name="ITEM_COUNT" /> more items}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Step 1: Sign in to the portal&lt;/h4&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">Reset password</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{This card has been saved in your Google Account}other{These cards have been saved in your Google Account}}</translation>
+<translation id="42981349822642051">Expand</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Switch</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Block (default)</translation>
+<translation id="4318566738941496689">Your device name and network address</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="4340982228985273705">This computer is not detected as enterprise managed, so policy can only automatically install extensions hosted on the Chrome Web Store. The Chrome Web Store update URL is '<ph name="CWS_UPDATE_URL" />'.</translation>
<translation id="4346197816712207223">Accepted Credit Cards</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Manage payment methods...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Phone</translation>
<translation id="4406896451731180161">search results</translation>
-<translation id="4406972042435603828">Your administrators have installed extensions with powerful capabilities.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Pickup Address</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="443121186588148776">Serial port</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> didn’t accept your login certificate, or one may not have been provided.</translation>
<translation id="4434045419905280838">Pop-ups and redirects</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Use of a proxy is disabled but an explicit proxy configuration is specified.</translation>
<translation id="445100540951337728">Accepted debit cards</translation>
+<translation id="4466881336512663640">Form changes will be lost. Are you sure that you want to continue?</translation>
<translation id="4482953324121162758">This site will not be translated.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Invalid URL. Must be a URL with a standard scheme, e.g. http://example.com or https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Details</translation>
<translation id="4524805452350978254">Manage cards</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Try disabling your extensions.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Delivery</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Remove card</translation>
<translation id="4587425331216688090">Remove address from Chrome?</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="4597348597567598915">Size 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Take me there now</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Stop using an invalid certificate</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Your connection was interrupted</translation>
<translation id="471880041731876836">You don't have permission to visit this site</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Running Windows Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Reload policies</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Restart Chromium</translation>
<translation id="473775607612524610">Update</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> search suggestion</translation>
<translation id="4742407542027196863">Manage passwords…</translation>
<translation id="4744603770635761495">Executable Path</translation>
+<translation id="4746351372139058112">Messages</translation>
<translation id="4750917950439032686">Your information (for example, passwords or credit card numbers) is private when it is sent to this site.</translation>
<translation id="4756388243121344051">&amp;History</translation>
<translation id="4758311279753947758">Add contact info</translation>
@@ -609,9 +684,9 @@
<translation id="4764776831041365478">The web page at <ph name="URL" /> might be temporarily down or it may have moved permanently to a new web address.</translation>
<translation id="4771973620359291008">An unknown error has occurred.</translation>
<translation id="4785689107224900852">Switch to this tab</translation>
-<translation id="4792143361752574037">There was a problem accessing the session files. Saving to disk is currently disabled. Please reload the page to try again.</translation>
-<translation id="4798078619018708837">Enter the expiry date and CVC for <ph name="CREDIT_CARD" /> to update your card details. Once you confirm, card details from your Google Accountwill be shared with this site.</translation>
+<translation id="4798078619018708837">Enter the expiry date and CVC for <ph name="CREDIT_CARD" /> to update your card details. Once you confirm, card details from your Google Account will be shared with this site.</translation>
<translation id="4800132727771399293">Check your expiration date and CVC and try again</translation>
+<translation id="480334179571489655">Origin Policy Error</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>
@@ -626,7 +701,6 @@
<translation id="4881695831933465202">Open</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>
@@ -635,15 +709,15 @@
<translation id="4943872375798546930">No results</translation>
<translation id="4950898438188848926">Tab switch button, press Enter to switch to the open tab, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Actions</translation>
-<translation id="495832697253704892">Extension reporting</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Expand list</translation>
<translation id="4974590756084640048">Re-enable warnings</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">See all</translation>
<translation id="4989809363548539747">This plug-in is not supported</translation>
-<translation id="4996230189582812866">Reporting</translation>
<translation id="5002932099480077015">If enabled, Chrome will store a copy of your card on this device for faster form filling.</translation>
-<translation id="5014174725590676422">Google Assistant in Chrome first run screen is shown</translation>
<translation id="5015510746216210676">Machine Name:</translation>
+<translation id="5017554619425969104">Text that you copied</translation>
<translation id="5018422839182700155">Can't open this page</translation>
<translation id="5019198164206649151">Backing store in bad state</translation>
<translation id="5023310440958281426">Check your administrator's policies</translation>
@@ -653,35 +727,51 @@
<translation id="5034369478845443529">Local Context <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Allow</translation>
<translation id="5040262127954254034">Privacy</translation>
+<translation id="5043480802608081735">Link that you copied</translation>
<translation id="5045550434625856497">Incorrect password</translation>
<translation id="5056549851600133418">Articles for you</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Checking the proxy address<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Server's certificate is not valid at this time.</translation>
<translation id="5087580092889165836">Add card</translation>
<translation id="5089810972385038852">State</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="5097099694988056070">Device statistics such as CPU/RAM usage</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Your device is managed by <ph name="ENROLLMENT_DOMAIN" /> and your account is managed by <ph name="ACCOUNT_DOMAIN" />. This means that your administrators may remotely configure your device and account.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">The session with this name is not valid for deletion.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Manage addresses...</translation>
+<translation id="5138227688689900538">Show less</translation>
<translation id="5141240743006678641">Encrypt synced passwords with your Google credentials</translation>
<translation id="5145883236150621069">Error code present in the policy response</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Open page in a new Incognito window (⇧⌘N)</translation>
-<translation id="516920405563544094">Enter the CVC for <ph name="CREDIT_CARD" />. Once you confirm, card details from yourGoogle Accountwill be shared with this site.</translation>
+<translation id="516920405563544094">Enter the CVC for <ph name="CREDIT_CARD" />. Once you confirm, card details from your Google Account will be shared with this site.</translation>
<translation id="5169827969064885044">You could lose access to your organisation's account or experience identity theft. Chrome recommends changing your password now.</translation>
<translation id="5171045022955879922">Search or type URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Machine</translation>
<translation id="5179510805599951267">Not in <ph name="ORIGINAL_LANGUAGE" />? Report this error</translation>
<translation id="5190835502935405962">Bookmarks Bar</translation>
-<translation id="5200263511887412697">report list of device users that have recently logged in</translation>
+<translation id="519422657042045905">Annotation not available</translation>
<translation id="5201306358585911203">An embedded page on this page says</translation>
<translation id="5205222826937269299">Name required</translation>
<translation id="5215116848420601511">Payment methods and addresses using Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Email (required)</translation>
<translation id="5230733896359313003">Delivery Address</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">'Connect to network'</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Network addresses</translation>
<translation id="5285570108065881030">Show all saved passwords</translation>
<translation id="5287240709317226393">Show cookies</translation>
<translation id="5288108484102287882">Validation of policy values has raised warnings</translation>
@@ -693,7 +783,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> of <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Choose contact info</translation>
<translation id="5327248766486351172">Name</translation>
+<translation id="5329858041417644019">Your browser is not managed</translation>
<translation id="5332219387342487447">Delivery Method</translation>
+<translation id="5334013548165032829">Detailed system logs</translation>
<translation id="5344579389779391559">This page may try to charge you money</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>
@@ -701,6 +793,7 @@
<translation id="5377026284221673050">'Your clock is behind' or 'Your clock is ahead' or "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">To get your cards on all devices, sign in and turn on sync.</translation>
<translation id="5386426401304769735">The certificate chain for this site contains a certificate signed using SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +804,7 @@
<translation id="5457113250005438886">Invalid</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Redo edit</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Add valid address</translation>
<translation id="5490432419156082418">Addresses and more</translation>
@@ -718,10 +812,12 @@
<ph name="LINE_BREAK" />
Try contacting your system administrator.</translation>
<translation id="549333378215107354">Size 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Managed bookmarks</translation>
<translation id="5510766032865166053">It may have been moved or deleted.</translation>
<translation id="5523118979700054094">Policy name</translation>
<translation id="552553974213252141">Was the text extracted correctly?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Could not find the requested article.</translation>
<translation id="5541546772353173584">Add Email</translation>
<translation id="5545756402275714221">Articles for You</translation>
@@ -736,15 +832,21 @@
<translation id="5595485650161345191">Edit address</translation>
<translation id="5598944008576757369">Choose payment method</translation>
<translation id="560412284261940334">Management not supported</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> redirected you too many times.</translation>
<translation id="5629630648637658800">Failed to load policy settings</translation>
<translation id="5631439013527180824">Invalid device management token</translation>
+<translation id="5632627355679805402">Your data was encrypted with your <ph name="BEGIN_LINK" />Google password<ph name="END_LINK" /> as of <ph name="TIME" />. Enter it to start sync.</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="563324245173044180">Deceptive content blocked.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">The administrator of this device has installed extensions for additional functions. Extensions have access to some of your data.</translation>
<translation id="5675650730144413517">This page isn’t working</translation>
+<translation id="5684874026226664614">Oops. This page could not be translated.</translation>
<translation id="5685654322157854305">Add delivery address</translation>
<translation id="5689199277474810259">Export to JSON</translation>
<translation id="5689516760719285838">Location</translation>
@@ -753,38 +855,39 @@
<translation id="5710435578057952990">The identity of this website has not been verified.</translation>
<translation id="5719499550583120431">Prepaid cards are accepted.</translation>
<translation id="5720705177508910913">Current user</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome recommends resetting your password if you reused it on other sites.</translation>
<translation id="5732392974455271431">Your parents can unblock it for you</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Save card in your Google Account}other{Save cards in your Google Account}}</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="5770114862687765385">The file seems to be corrupted. Click the 'Reset' button to reset the session.</translation>
<translation id="5778550464785688721">MIDI devices full control</translation>
<translation id="578305955206182703">Amber</translation>
<translation id="57838592816432529">Mute</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>
+<translation id="5798290721819630480">Discard changes?</translation>
<translation id="5798683403665926540">Change home page in Chrome settings</translation>
<translation id="5803412860119678065">Do you want to fill in your <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permissions</translation>
<translation id="5810442152076338065">Your connection to <ph name="DOMAIN" /> is encrypted using an obsolete cipher suite.</translation>
<translation id="5813119285467412249">&amp;Redo Add</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="5860033963881614850">Off</translation>
<translation id="5863847714970149516">The page ahead may try to charge you money</translation>
<translation id="5866257070973731571">Add Phone Number</translation>
<translation id="5869405914158311789">This site can’t be reached</translation>
<translation id="5869522115854928033">Saved passwords</translation>
<translation id="5887400589839399685">Card saved</translation>
-<translation id="5893718151540690985">report list of network interfaces with their types and hardware addresses</translation>
<translation id="5893752035575986141">Credit cards are accepted.</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="5916664084637901428">On</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Save card to Google Account?</translation>
<translation id="5922853866070715753">Almost finished</translation>
<translation id="5932224571077948991">Site shows intrusive or misleading ads</translation>
-<translation id="5939518447894949180">Reset</translation>
<translation id="5946937721014915347">Opening <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Can't enrol with consumer account (packaged licence available).</translation>
<translation id="5967592137238574583">Edit Contact Info</translation>
@@ -792,6 +895,7 @@
<translation id="5975083100439434680">Zoom out</translation>
<translation id="5977489021191000276">Your device is not managed by an administrator.</translation>
<translation id="5977976211062815271">On this device</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Can’t open payment app</translation>
<translation id="5989320800837274978">Neither fixed proxy servers nor a .pac script URL are specified.</translation>
<translation id="5990559369517809815">Requests to the server have been blocked by an extension.</translation>
@@ -802,8 +906,8 @@
<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="6033927989869462158">report hardware statistics such as CPU/RAM usage</translation>
<translation id="6034000775414344507">Light grey</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">If the problem continues, contact the site owner.</translation>
<translation id="6040143037577758943">Close</translation>
<translation id="6044573915096792553">Size 12</translation>
@@ -812,10 +916,10 @@
<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="6058977677006700226">Use your cards on all your devices?</translation>
<translation id="6059925163896151826">USB devices</translation>
-<translation id="6071091556643036997">The policy type is invalid.</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="6094273045989040137">Annotate</translation>
<translation id="610911394827799129">Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Information about installed extensions and plugins</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>
@@ -850,15 +954,21 @@
<translation id="6337133576188860026">Frees up less than <ph name="SIZE" />. Some sites may load more slowly on your next visit.</translation>
<translation id="6337534724793800597">Filter policies by name</translation>
<translation id="6358450015545214790">What do these mean?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Potential charges ahead.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 other suggestion}other{# other suggestions}}</translation>
<translation id="6387754724289022810">To pay faster next time, save your card and billing address to your Google Account and to this device.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Edit bookmark</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Discard</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Add more information</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirm Form Resubmission</translation>
@@ -871,11 +981,17 @@
<translation id="6508722015517270189">Restart Chrome</translation>
<translation id="6529602333819889595">&amp;Redo Delete</translation>
<translation id="6534179046333460208">Physical Web suggestions</translation>
+<translation id="6556866813142980365">Redo</translation>
<translation id="6563469144985748109">Your manager hasn't approved it yet</translation>
<translation id="6569060085658103619">You're viewing an extension page</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Light pink</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link that you copied</translation>
+<translation id="6591833882275308647">Your <ph name="DEVICE_TYPE" /> is not managed</translation>
<translation id="6596325263575161958">Encryption options</translation>
<translation id="6604181099783169992">Motion or light sensors</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Contact Info</translation>
<translation id="6626291197371920147">Add valid card number</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Search</translation>
@@ -884,19 +1000,23 @@
<translation id="6644283850729428850">This policy has been deprecated.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{None}=1{From 1 site (you won't be signed out of your Google Account)}other{From # sites (you won't be signed out of your Google Account)}}</translation>
<translation id="6657585470893396449">Password</translation>
+<translation id="6670613747977017428">Back to safety.</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="671076103358959139">Enrolment Token:</translation>
<translation id="6711464428925977395">There is something wrong with the proxy server or the address is incorrect.</translation>
-<translation id="6723740634201835758">In yourGoogle Account</translation>
+<translation id="6723740634201835758">In your Google Account</translation>
+<translation id="6738516213925468394">Your data was encrypted with your <ph name="BEGIN_LINK" />sync passphrase<ph name="END_LINK" /> on <ph name="TIME" />. Enter it to start sync.</translation>
<translation id="674375294223700098">Unknown server certificate error.</translation>
<translation id="6744009308914054259">While waiting for a connection, you can visit Downloads to read offline articles.</translation>
<translation id="6753269504797312559">Policy Value</translation>
<translation id="6757797048963528358">Your device went to sleep.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Your parent hasn't approved it yet</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Extensions</translation>
<translation id="679355240208270552">Ignored because default search is not enabled by policy.</translation>
<translation id="681021252041861472">Required Field</translation>
<translation id="6810899417690483278">Customisation ID</translation>
@@ -915,7 +1035,7 @@
<translation id="6897140037006041989">User Agent</translation>
<translation id="6903319715792422884">Help improve Safe Browsing by sending some <ph name="BEGIN_WHITEPAPER_LINK" />system information and page content<ph name="END_WHITEPAPER_LINK" /> to Google. <ph name="PRIVACY_PAGE_LINK" /></translation>
<translation id="6915804003454593391">User:</translation>
-<translation id="6934672428414710184">This name is from yourGoogle Account</translation>
+<translation id="6934672428414710184">This name is from your Google Account</translation>
<translation id="6939583532829045966">Your device is managed by <ph name="ENROLLMENT_DOMAIN" />. This means that your administrator may remotely configure your device.</translation>
<translation id="6944692733090228304">You entered your password on a site that’s not managed by <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />. To protect your account, don’t reuse your password on other apps and sites.</translation>
<translation id="6945221475159498467">Select</translation>
@@ -929,10 +1049,12 @@
<translation id="6965978654500191972">Device</translation>
<translation id="6970216967273061347">District</translation>
<translation id="6973656660372572881">Both fixed proxy servers and a .pac script URL are specified.</translation>
+<translation id="6973932557599545801">Sorry I'm not able to help. Please continue on your own.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Mute (default)</translation>
<translation id="6984479912851154518">Leaving private mode to pay via an external application. Continue?</translation>
<translation id="6989763994942163495">+ Show advanced settings</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Always translate <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">These charges could be one-off or recurring and may not be obvious.</translation>
@@ -948,28 +1070,33 @@
<translation id="7108338896283013870">Hide</translation>
<translation id="7108819624672055576">Allowed by an extension</translation>
<translation id="7111012039238467737">(Valid)</translation>
+<translation id="7118618213916969306">Search for clipboard URL, <ph name="SHORT_URL" /></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="7135130955892390533">Show status</translation>
<translation id="7138472120740807366">Delivery method</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavender</translation>
-<translation id="7158980942472052083">Invalid URL. Must be a URL with a standard scheme.</translation>
<translation id="717330890047184534">Gaia ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">The server that you are going to, <ph name="ORIGIN" />, has requested that a security policy will be applied to all requests to it. But instead of delivering a policy, it has redirected the browser elsewhere, which prevents the browser from fulfilling your request for <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Save and fill payment methods</translation>
<translation id="7180611975245234373">Refresh</translation>
<translation id="7182878459783632708">No policies set</translation>
<translation id="7186367841673660872">This page has been translated from<ph name="ORIGINAL_LANGUAGE" />to<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Frees up <ph name="SIZE" />. Some sites may load more slowly on your next visit.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Your administrator can see:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> doesn't adhere to security standards.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Learn more<ph name="END_LINK" /> about this problem.</translation>
<translation id="7219179957768738017">The connection uses <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Processing</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">The site ahead contains malware</translation>
+<translation id="724766306220616965">Warnings, Conflict</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="7251437084390964440">The network configuration doesn't comply to the ONC standard. Parts of the configuration may not be imported.
Additional details:
@@ -982,11 +1109,14 @@ Additional details:
<translation id="7300012071106347854">Cobalt blue</translation>
<translation id="7302712225291570345">'<ph name="TEXT" />'</translation>
<translation id="7309308571273880165">Crash report captured on <ph name="CRASH_TIME" /> (upload requested by user, not yet uploaded)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" /> warnings</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Connection Help</translation>
<translation id="7334320624316649418">&amp;Redo reorder</translation>
<translation id="733923710415886693">The server's certificate was not disclosed via Certificate Transparency.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Command Line</translation>
-<translation id="7365061714576910172">Export Linux</translation>
<translation id="7372973238305370288">search result</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nope</translation>
@@ -994,6 +1124,7 @@ Additional details:
<translation id="7381288752349550461">Managed session override</translation>
<translation id="7390545607259442187">Confirm Card</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Your <ph name="DEVICE_NAME" /> is managed</translation>
<translation id="7407424307057130981">&lt;p&gt;You'll see this error if you have Superfish software on your Windows computer.&lt;/p&gt;
&lt;p&gt;Follow these steps to temporarily disable the software so that you can get on the web. You'll need administrator privileges.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1135,7 @@ Additional details:
&lt;li&gt;Click &lt;strong&gt;Apply&lt;/strong&gt;, then click &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Visit the &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome help centre&lt;/a&gt; to find out how to permanently remove the software from your computer
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> management</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Manage passwords...</translation>
<translation id="7419106976560586862">Profile Path</translation>
<translation id="7437289804838430631">Add contact info</translation>
@@ -1013,22 +1144,24 @@ Additional details:
<translation id="7442725080345379071">Light orange</translation>
<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="7449109375006139765">send system logs to the management server</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="7460618730930299168">The screening is different from what you selected. Continue?</translation>
<translation id="7473891865547856676">No, thanks</translation>
-<translation id="7475525192983021547">report time periods when a user is active on the device</translation>
<translation id="7481312909269577407">Forward</translation>
<translation id="7485870689360869515">No data found.</translation>
+<translation id="7498234416455752244">Keep editing</translation>
<translation id="7508255263130623398">Returned policy device ID is empty or doesn't match current device ID</translation>
<translation id="7508870219247277067">Avocado green</translation>
<translation id="7511955381719512146">The Wi-Fi that you are using may require you to visit <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">No web page was found for the web address: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Your connection to this site is not private</translation>
+<translation id="7535087603100972091">Value</translation>
<translation id="7537536606612762813">Mandatory</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1037,8 +1170,8 @@ Additional details:
<translation id="7552846755917812628">Try the following tips:</translation>
<translation id="7554791636758816595">New Tab</translation>
<translation id="7564049878696755256">You could lose access to your <ph name="ORG_NAME" /> account or experience identity theft. Chrome recommends changing your password now.</translation>
-<translation id="7566125604157659769">Text that you copied</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="7568105740864181217">This browser is managed by a company, school or other organisation. Your administrator can change your browser setup remotely. Activity on this device may also be managed outside of Chrome. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></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>
@@ -1049,6 +1182,7 @@ Additional details:
<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="7633909222644580952">Performance data and crash reports</translation>
<translation id="7637571805876720304">Remove credit card from Chromium?</translation>
<translation id="7639968568612851608">Dark grey</translation>
<translation id="765676359832457558">Hide advanced settings ...</translation>
@@ -1058,9 +1192,11 @@ Additional details:
<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="7676643023259824263">Search for clipboard text, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Change search engine</translation>
<translation id="7682287625158474539">Shipping</translation>
<translation id="7687186412095877299">Fills in payment forms with your saved payment methods</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">At the moment, you have cards that can only be used on this device. Click Continue to review cards.</translation>
<translation id="7699293099605015246">Articles aren't available at the moment.</translation>
<translation id="7701040980221191251">None</translation>
@@ -1072,11 +1208,13 @@ Additional details:
<translation id="774634243536837715">Dangerous content blocked.</translation>
<translation id="7752995774971033316">Unmanaged</translation>
<translation id="7755287808199759310">Your parent can unblock it for you</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Firewall or antivirus software may have blocked the connection.</translation>
<translation id="7759163816903619567">Display domain:</translation>
<translation id="7761701407923456692">Server's certificate does not match the URL.</translation>
<translation id="7763386264682878361">Payment Manifest Parser</translation>
<translation id="7764225426217299476">Add address</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefecture</translation>
<translation id="7791543448312431591">Add</translation>
<translation id="7793809570500803535">The web page at <ph name="SITE" /> might be temporarily down or it may have been moved permanently to a new web address.</translation>
@@ -1088,8 +1226,8 @@ Additional details:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Remove form suggestion from Chrome?</translation>
<translation id="7815407501681723534">Found <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> for '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Policy management</translation>
<translation id="782886543891417279">The Wi-Fi that you are using (<ph name="WIFI_NAME" />) may require you to visit its login page.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{None}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1236,7 @@ Additional details:
<translation id="7878562273885520351">Your password may be compromised</translation>
<translation id="7882421473871500483">Brown</translation>
<translation id="7887683347370398519">Check your CVC and try again</translation>
-<translation id="7893255318348328562">Session name</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Enter a valid phone number</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Expires on <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1246,25 @@ Additional details:
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Mobile bookmarks</translation>
<translation id="7961015016161918242">Never</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Not Specified</translation>
<translation id="800218591365569300">Try closing other tabs or programmes to free up memory.</translation>
+<translation id="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Manage Passwords</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{This card and its billing address will be saved. You'll be able to use it when signed in to <ph name="USER_EMAIL" />.}other{These cards and their billing addresses will be saved. You'll be able to use them when signed in to <ph name="USER_EMAIL" />.}}</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="8034522405403831421">This page is in <ph name="SOURCE_LANGUAGE" />. Translate it to <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pen</translation>
+<translation id="8037117624646282037">Who has used the device recently</translation>
<translation id="8037357227543935929">Ask (default)</translation>
<translation id="803771048473350947">File</translation>
<translation id="8041089156583427627">Send Feedback</translation>
<translation id="8041940743680923270">Use global default (Ask)</translation>
<translation id="8042918947222776840">Choose pickup method</translation>
<translation id="8057711352706143257">'<ph name="SOFTWARE_NAME" />' isn’t configured correctly. Uninstalling '<ph name="SOFTWARE_NAME" />' usually fixes the problem. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Your device has been configured to:</translation>
+<translation id="8066955247577885446">Sorry, something went wrong.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Cannot annotate when rotated</translation>
<translation id="8079031581361219619">Reload site?</translation>
<translation id="8088680233425245692">Failed to view article.</translation>
@@ -1131,22 +1273,26 @@ Additional details:
<translation id="8091372947890762290">Activation is pending on the server</translation>
<translation id="8092774999298748321">Deep purple</translation>
<translation id="8094917007353911263">The network that you are using may require you to visit <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">The invalid cards have been removed</translation>
<translation id="8103161714697287722">Payment Method</translation>
<translation id="8118489163946903409">Payment method</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> managed by <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">'<ph name="SOFTWARE_NAME" />' wasn’t installed properly on your computer or network. Ask your IT administrator to resolve this issue.</translation>
-<translation id="8130693978878176684">I cannot help anymore. Please continue on your own.</translation>
<translation id="8131740175452115882">Confirm</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="8175796834047840627">Chrome is offering to save your cards in your Google Accountbecause you are signed in. You can change this behaviour in settings.</translation>
+<translation id="8175796834047840627">Chrome is offering to save your cards in your Google Account because you are signed in. You can change this behaviour in settings.</translation>
<translation id="8184538546369750125">Use global default (Allow)</translation>
<translation id="8194797478851900357">&amp;Undo Move</translation>
<translation id="8197543752516192074">Translate page</translation>
<translation id="8201077131113104583">Invalid update URL for extension with ID "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Order summary</translation>
+<translation id="8202370299023114387">Conflict</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">Connection is secure</translation>
<translation id="8218327578424803826">Assigned Location:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Open page in a new Incognito tab</translation>
@@ -1158,14 +1304,16 @@ Additional details:
<translation id="825929999321470778">Show All Saved Passwords</translation>
<translation id="8261506727792406068">Delete</translation>
<translation id="8267698848189296333">Signing in as <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">This browser is managed by <ph name="ENROLLMENT_DOMAIN" />. Your administrator can change your browser setup remotely. Activity on this device may also be managed outside of Chrome. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Sign In</translation>
<translation id="8288807391153049143">Show certificate</translation>
<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="8298115750975731693">The Wi-Fi that you are using (<ph name="WIFI_NAME" />) may require you to visit <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">The translation failed because of a problem with the network connection.</translation>
-<translation id="8311129316111205805">Load session</translation>
<translation id="8332188693563227489">Access to <ph name="HOST_NAME" /> was denied</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1331,6 @@ Additional details:
<translation id="8416694386774425977">The network configuration is invalid and couldn't be imported.
Additional details:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Device managed by <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Change</translation>
<translation id="8428213095426709021">Settings</translation>
@@ -1210,9 +1357,11 @@ Additional details:
<translation id="860043288473659153">Cardholder name</translation>
<translation id="861775596732816396">Size 4</translation>
<translation id="8620436878122366504">Your parents haven't approved it yet</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Save This Card to This Device</translation>
<translation id="8663226718884576429">Order Summary, <ph name="TOTAL_LABEL" />, More Details</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, answer, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Your connection to <ph name="DOMAIN" /> is not encrypted.</translation>
<translation id="8718314106902482036">Payment not completed</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, search suggestion</translation>
@@ -1226,6 +1375,7 @@ Additional details:
<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="8763927697961133303">USB device</translation>
<translation id="8768895707659403558">To use your cards on all your devices, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Redo delete</translation>
<translation id="8792621596287649091">You could lose access to your <ph name="ORG_NAME" /> account or experience identity theft. Chromium recommends changing your password now.</translation>
<translation id="8800988563907321413">Your nearby suggestions appear here</translation>
@@ -1236,10 +1386,12 @@ Additional details:
<translation id="885730110891505394">Sharing with Google</translation>
<translation id="8858065207712248076">Chrome recommends resetting your <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> password if you reused it on other sites.</translation>
<translation id="8866481888320382733">Error parsing policy settings</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Recently Closed</translation>
<translation id="8874824191258364635">Enter a valid card number</translation>
<translation id="8891727572606052622">Invalid proxy mode.</translation>
<translation id="8903921497873541725">Zoom in</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Add Name</translation>
@@ -1247,13 +1399,13 @@ Additional details:
<translation id="894185898663964645">Your administrator has configured custom root certificates, which may allow the administrator to see the contents of websites that you visit.</translation>
<translation id="8943282376843390568">Lime</translation>
<translation id="8957210676456822347">Captive Portal Authorisation</translation>
+<translation id="8966619695390250636">Did you mean?</translation>
<translation id="8968766641738584599">Save card</translation>
<translation id="8971063699422889582">Server's certificate has expired.</translation>
<translation id="8975012916872825179">Includes information such as phone numbers, email addresses and delivery addresses</translation>
<translation id="8978053250194585037">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected phishing<ph name="END_LINK" /> on <ph name="SITE" />. Phishing sites pretend to be other websites to trick you.</translation>
<translation id="8983003182662520383">Payment methods and addresses using Google Pay</translation>
<translation id="8987927404178983737">Month</translation>
-<translation id="8988408250700415532">Something went wrong. You can finish your order on the website.</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>
@@ -1263,6 +1415,7 @@ Additional details:
<translation id="9011424611726486705">Open site settings</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Invalid)</translation>
<translation id="9035022520814077154">Security error</translation>
<translation id="9038649477754266430">Use a prediction service to load pages more quickly</translation>
@@ -1274,11 +1427,11 @@ Additional details:
<translation id="9065745800631924235"><ph name="TEXT" /> search from history</translation>
<translation id="9069693763241529744">Blocked by an extension</translation>
<translation id="9076283476770535406">It may have mature content</translation>
+<translation id="9076630408993835509">This browser is not managed by a company or other organisation. Activity on this device may be managed outside of Chrome. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">More information required</translation>
<translation id="9080712759204168376">Order Summary</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>
<translation id="9106062320799175032">Add Billing Address</translation>
-<translation id="9110718169272311511">Google Assistant in Chrome is available near bottom of the screen</translation>
<translation id="9114524666733003316">Confirming card...</translation>
<translation id="9128870381267983090">Connect to network</translation>
<translation id="9137013805542155359">Show original</translation>
@@ -1287,6 +1440,7 @@ Additional details:
<translation id="9148507642005240123">&amp;Undo edit</translation>
<translation id="9154194610265714752">Updated</translation>
<translation id="9157595877708044936">Setting up...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Allow sites to check if you have payment methods saved</translation>
<translation id="9169664750068251925">Always block on this site</translation>
<translation id="9170848237812810038">&amp;Undo</translation>
@@ -1301,10 +1455,12 @@ Additional details:
<translation id="9219103736887031265">Images</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">You could lose access to your Google Account. Chromium recommends changing your password now. You'll be asked to sign in.</translation>
<translation id="939736085109172342">New folder</translation>
<translation id="945855313015696284">Check the info below and delete any invalid cards</translation>
<translation id="951104842009476243">Accepted Debit and Prepaid Cards</translation>
+<translation id="958202389743790697">Blocked according to <ph name="ORIGIN" />'s security policy.</translation>
<translation id="962484866189421427">This content might try to install deceptive apps that pretend to be something else or collect data that may be used to track you. <ph name="BEGIN_LINK" />Show anyway<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Official Build</translation>
<translation id="973773823069644502">Add delivery address</translation>
@@ -1313,6 +1469,7 @@ Additional details:
<translation id="984275831282074731">Payment methods</translation>
<translation id="985199708454569384">&lt;p&gt;You'll see this error if your computer or mobile device's date and time are inaccurate.&lt;/p&gt;
&lt;p&gt;To fix the error, open your device's clock. Make sure that the time and date are correct.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Developer Build</translation>
<translation id="989988560359834682">Edit Address</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_es-419.xtb b/chromium/components/strings/components_strings_es-419.xtb
index 7dedc6346f4..d8fc7b4d242 100644
--- a/chromium/components/strings/components_strings_es-419.xtb
+++ b/chromium/components/strings/components_strings_es-419.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es-419">
-<translation id="1005145902654145231">No se pudo cambiar el nombre de la sesión.</translation>
<translation id="1008557486741366299">Ahora no</translation>
<translation id="1010200102790553230">Cargar la página más tarde</translation>
<translation id="1015730422737071372">Proporciona más detalles</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nombre desconocido</translation>
<translation id="1050038467049342496">Cierra las demás apps.</translation>
<translation id="1055184225775184556">&amp;Deshacer Agregar</translation>
+<translation id="1056898198331236512">Advertencia</translation>
<translation id="1058479211578257048">Guardando tarjetas…</translation>
<translation id="10614374240317010">Nunca guardado</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Favoritos de escritorio</translation>
<translation id="1074497978438210769">No seguro</translation>
<translation id="1080116354587839789">Ajustar al ancho</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Agregar el nombre en la tarjeta</translation>
<translation id="1089439967362294234">Cambiar contraseña</translation>
<translation id="109743633954054152">Administra las contraseñas en la configuración de Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Las advertencias pueden ser habituales cuando las páginas web actualizan su seguridad. Esto debería mejorar pronto.</translation>
<translation id="1126551341858583091">El tamaño del almacenamiento local es <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Caché de política correcta</translation>
+<translation id="1131264053432022307">Imagen que copiaste</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Cambiar nombre</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Quitar</translation>
<translation id="1197088940767939838">Naranja</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Tu nombre de dispositivo</translation>
<translation id="124116460088058876">Más idiomas</translation>
<translation id="1250759482327835220">Para realizar pagos de forma más rápida la próxima vez, guarda tu tarjeta, nombre y dirección de facturación en tu cuenta de Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variaciones en la línea de comandos</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="1314614906530272393">La sesión seleccionada no existe.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Buscar imagen del portapapeles</translation>
<translation id="1323433172918577554">Mostrar más</translation>
<translation id="132390688737681464">Guardar y completar direcciones</translation>
<translation id="1333989956347591814">Es posible que tu actividad <ph name="BEGIN_EMPHASIS" />todavía sea visible<ph name="END_EMPHASIS" /> para:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Dirección de retiro</translation>
<translation id="1348198688976932919">El siguiente sitio incluye apps peligrosas</translation>
<translation id="1348779747280417563">Confirmar el nombre</translation>
+<translation id="1357195169723583938">Quién usó el dispositivo recientemente y cuándo</translation>
+<translation id="1364822246244961190">Como esta política está bloqueada, se omitirá su valor.</translation>
<translation id="1374468813861204354">sugerencias</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Acerca de la versión</translation>
<translation id="1376836354785490390">Mostrar menos</translation>
<translation id="1377321085342047638">N. tarjeta</translation>
<translation id="138218114945450791">Celeste</translation>
+<translation id="1382194467192730611">El dispositivo USB que permite tu administrador</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no envió ningún dato.</translation>
+<translation id="140316286225361634">El sitio <ph name="ORIGIN" /> solicitó que se aplicara una política de seguridad
+ a todas las solicitudes. Esta política actualmente considera que el sitio
+ no es seguro.</translation>
<translation id="1405567553485452995">Verde claro</translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Error de privacidad</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455413310270022028">Borrador</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Mostrar más</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Elegir dirección de envío</translation>
+<translation id="1492194039220927094">Notificaciones push de políticas:</translation>
<translation id="1501859676467574491">Mostrar tarjetas de tu Cuenta de Google</translation>
-<translation id="1506687042165942984">Se muestra una copia guardada (es decir, desactualizada) de la página.</translation>
<translation id="1507202001669085618">&lt;p&gt;Se muestra este error si usas un portal Wi-Fi donde debes acceder para establecer la conexión.&lt;/p&gt;
&lt;p&gt;Para solucionar el error, haz clic en &lt;strong&gt;Conectar&lt;/strong&gt; en la página que deseas abrir.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Se requiere el número de teléfono</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Fecha de compilación</translation>
<translation id="1521655867290435174">Hojas de cálculo de Google</translation>
<translation id="1527263332363067270">Esperando conexión…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Esta página dice</translation>
<translation id="153384715582417236">Eso es todo por ahora</translation>
<translation id="154408704832528245">Elegir dirección de entrega</translation>
<translation id="1549470594296187301">JavaScript debe estar habilitado para usar esta función.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Ingresa una fecha de vencimiento</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Se produjo un error cuando se mostraba 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="1618822247301510817">Se copió la imagen</translation>
<translation id="1620510694547887537">Cámara</translation>
<translation id="1623104350909869708">Evitar que esta página cree cuadros de diálogo adicionales</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Finalizar sesión</translation>
<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
<translation id="1697532407822776718">¡Listo!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">El documento es demasiado grande para contener anotaciones</translation>
<translation id="1721312023322545264">Necesitas permiso de <ph name="NAME" /> para visitar este sitio</translation>
<translation id="1721424275792716183">* El campo es obligatorio</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Intenta comunicarte con el administrador del sistema.</translation>
<translation id="1740951997222943430">Ingresa una fecha de vencimiento válida</translation>
<translation id="1743520634839655729">Para realizar pagos de forma más rápida la próxima vez, guarda tu tarjeta, nombre y dirección de facturación en tu cuenta de Google y en este dispositivo.</translation>
+<translation id="1745880797583122200">Tu navegador está administrado</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>
@@ -152,8 +172,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nombre del titular de la tarjeta</translation>
<translation id="1821930232296380041">Solicitud o parámetros de solicitud no válidos</translation>
+<translation id="1822540298136254167">Los sitios web que visitas y el tiempo que pasas en ellos</translation>
<translation id="1826516787628120939">Comprobando</translation>
<translation id="1834321415901700177">Este sitio contiene programas dañinos</translation>
<translation id="1839551713262164453">Se produjeron errores en la validación de los valores de la política</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Borrar datos del historial de navegación de Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{y 1 más}other{y # más}}</translation>
<translation id="2003709556000175978">Restablecer tu contraseña ahora</translation>
+<translation id="20053308747750172">El servidor <ph name="ORIGIN" /> al que te diriges solicitó
+ que se aplicara una política de seguridad a todas las solicitudes. Sin embargo, ahora
+ entregó una política no válida que impide que el navegador
+ cumpla con tu solicitud para <ph name="SITE" />.</translation>
<translation id="2025186561304664664">El proxy se estableció en configuración automática.</translation>
<translation id="2030481566774242610">¿Quisiste decir: <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Comprobar el proxy y el firewall<ph name="END_LINK" />.</translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departamento</translation>
<translation id="2102134110707549001">Sugerir contraseña segura…</translation>
<translation id="2108755909498034140">Reinicia la computadora.</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Tarjeta</translation>
<translation id="2114841414352855701">Se ignoró porque fue anulada por <ph name="POLICY_NAME" /> .</translation>
<translation id="213826338245044447">Favoritos del celular</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2183608646556468874">Número de teléfono</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 dirección}other{# direcciones}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Número de teléfono</translation>
<translation id="2283340219607151381">Guardar y completar direcciones</translation>
<translation id="2292556288342944218">Se bloqueó tu acceso a Internet</translation>
+<translation id="2294558542833290837">El vínculo que abriste originalmente no es común</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Esta acción libera menos de 1 MB. Es posible que algunos sitios se carguen más lento en tu próxima visita.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> requiere un nombre de usuario y una contraseña.</translation>
<translation id="2317583587496011522">Se aceptan tarjetas de débito.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, fecha de vencimiento: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Configuración controlada por tu administrador</translation>
+<translation id="2346319942568447007">Imagen que copiaste</translation>
<translation id="2349790679044093737">La sesión de RV está en curso</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Estás en modo privado</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">El servidor <ph name="ORIGIN" /> al que te diriges solicitó
+ que se aplicara una política de seguridad a todas las solicitudes. Sin embargo, ahora
+ no pudo entregar una política, lo que impide que el navegador cumpla con
+ tu solicitud para <ph name="SITE" />.</translation>
<translation id="244665789865330679">Tu dispositivo y cuenta se administran mediante el dominio <ph name="ENROLLMENT_DOMAIN" />. Esto significa que tu administrador puede configurarlos de forma remota.</translation>
<translation id="2463193859425327265">Cambiar página principal</translation>
<translation id="2463739503403862330">Llenar</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Elegir método de entrega</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ejecución del Diagnóstico de red<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traducir esta página</translation>
<translation id="2479410451996844060">URL de búsqueda no válida</translation>
<translation id="2482878487686419369">Notificaciones</translation>
<translation id="248348093745724435">Políticas de la máquina</translation>
+<translation id="2485387744899240041">Nombres de usuario para tu dispositivo y navegador</translation>
<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Escanear tarjeta nueva</translation>
<translation id="2501278716633472235">Ir atrás</translation>
<translation id="2503184589641749290">Tarjetas de débito y prepago aceptadas</translation>
<translation id="2515629240566999685">Verificar la señal en tu área.</translation>
-<translation id="2516852381693169964">Buscar imagen en <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Solo se guardará en este dispositivo</translation>
<translation id="2524461107774643265">Agregar más información</translation>
<translation id="2536110899380797252">Agregar dirección</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">El reloj está adelantado</translation>
<translation id="2634124572758952069">No se pudo encontrar la dirección IP del servidor de <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Estado:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Cierra las demás pestañas o apps.</translation>
<translation id="267371737713284912">presiona <ph name="MODIFIER_KEY_DESCRIPTION" /> para deshacer</translation>
<translation id="2674170444375937751">¿Estás seguro de que deseas eliminar estas páginas del historial?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Abandonar</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Tarjetas aceptadas</translation>
<translation id="2702801445560668637">Lista de lectura</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Eliminar elementos seleccionados</translation>
<translation id="277133753123645258">Método de envío</translation>
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
-<translation id="2781030394888168909">Exportar para Mac OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Se ha restablecido la conexión.</translation>
<translation id="2788784517760473862">Tarjetas de crédito aceptadas</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Abrir ventana de incógnito</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Necesitas permiso para visitar este sitio</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">¿Quieres guardar la tarjeta?</translation>
<translation id="2903493209154104877">Direcciones</translation>
<translation id="290376772003165898">¿La página no está en <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Método de entrega</translation>
<translation id="2928905813689894207">Dirección de facturación</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3037605927509011580">¡Oh, no!</translation>
<translation id="3041612393474885105">Información sobre el certificado</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Agregar dirección de retiro</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">No tienes autorización para ver esta página.</translation>
@@ -365,20 +413,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> en <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancelar pago</translation>
<translation id="3207960819495026254">Agregada a favoritos</translation>
-<translation id="3209375525920864198">Ingresa un nombre de sesión válido.</translation>
+<translation id="321912867715453276">Advertencia: Hay más de una fuente para esta política, pero los valores son los mismos.</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="3229041911291329567">Información de versión sobre tu dispositivo y navegador</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Agregar el nombre en la tarjeta</translation>
<translation id="3287510313208355388">Descargar cuando haya conexión</translation>
<translation id="3293642807462928945">Más información sobre la política <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">No se encontraron resultados en la búsqueda</translation>
-<translation id="3305707030755673451">Tus datos se encriptaron con tu frase de contraseña para sincronización el <ph name="TIME" />. Debes ingresarla para iniciar la sincronización.</translation>
<translation id="3320021301628644560">Agregar dirección de facturación</translation>
<translation id="3324983252691184275">Carmesí</translation>
<translation id="3338095232262050444">Seguro</translation>
@@ -406,9 +455,11 @@
<translation id="3427342743765426898">&amp;Rehacer Editar</translation>
<translation id="342781501876943858">Chromium te recomienda que restablezcas tu contraseña si la volviste a usar en otros sitios.</translation>
<translation id="3431636764301398940">Guardar esta tarjeta para este dispositivo</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">El propietario del dispositivo desactivó el juego de dinosaurios.</translation>
<translation id="3447884698081792621">Mostrar certificado (emitido por <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Obtener intervalo:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Resaltador</translation>
<translation id="3462200631372590220">Ocultar detalles avanzados</translation>
<translation id="3467763166455606212">Se requiere el nombre del titular de la tarjeta</translation>
@@ -431,20 +482,23 @@
<translation id="358285529439630156">Se aceptan tarjetas de crédito y prepago.</translation>
<translation id="3582930987043644930">Agregar nombre</translation>
<translation id="3583757800736429874">&amp;Rehacer Mover</translation>
+<translation id="35866233670761917">Tus administradores no ven los contenidos de los sitios web que visitas</translation>
<translation id="3586931643579894722">Ocultar detalles</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Tamaño 2</translation>
<translation id="3615877443314183785">Ingresa una fecha de vencimiento válida</translation>
<translation id="36224234498066874">Borrar datos de navegación...</translation>
<translation id="362276910939193118">Mostrar historial completo</translation>
-<translation id="3623476034248543066">Mostrar valor</translation>
<translation id="3630155396527302611">Si ya está incluido como un programa con permiso para acceder a la red, intenta
quitarlo de la lista y agregarlo de nuevo.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validación correcta</translation>
<translation id="3655670868607891010">Si este mensaje aparece con frecuencia, haz clic aquí: <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisión</translation>
<translation id="366077651725703012">Actualizar tarjeta de crédito</translation>
<translation id="3676592649209844519">ID de dispositivo:</translation>
+<translation id="3677008721441257057">¿Quisiste decir &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">La solicitud no se pudo firmar</translation>
<translation id="3678529606614285348">Abre la página en una nueva ventana de incógnito (Ctrl-mayúscula-N).</translation>
<translation id="3679803492151881375">El informe de fallos se capturó el <ph name="CRASH_TIME" /> y se cargó el <ph name="UPLOAD_TIME" /></translation>
@@ -452,13 +506,14 @@
<translation id="3704162925118123524">Es posible que la red que estás usando requiera que visites la página de acceso.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Cargando...</translation>
+<translation id="3709599264800900598">Texto que copiaste</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
<translation id="3714780639079136834">Activar los datos móviles o la conexión Wi-Fi.</translation>
<translation id="3715597595485130451">Conectar a Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Comprobar la configuración del proxy, firewall o DNS<ph name="END_LINK" />.</translation>
<translation id="372429172604983730">Las apps que pueden causar este error incluyen antivirus, firewall, filtros web o software proxy.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Después de que confirmes esta acción, los datos de tu Cuenta de Google se compartirán con este sitio.</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>
@@ -471,10 +526,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Vencimiento: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Tamaño 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Se bloqueó el contenido dañino</translation>
<translation id="3810973564298564668">Administrar</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="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> instaló extensiones para funciones adicionales. Las extensiones tienen acceso a algunos de tus datos.</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>
@@ -482,6 +539,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Preguntar siempre en este sitio</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>
@@ -492,11 +550,13 @@
<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="3984550557525787191">El nombre de la sesión ya existe.</translation>
<translation id="3987940399970879459">Menos de 1 MB</translation>
+<translation id="4008849406247176967">Advertencia: Hay más de una fuente con valores en conflicto para esta política.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 página web cercana}other{# páginas web cercanas}}</translation>
<translation id="4030383055268325496">&amp;Deshacer Agregar</translation>
+<translation id="4032320456957708163"><ph name="ENROLLMENT_DOMAIN" /> administra tu navegador</translation>
<translation id="4058922952496707368">Clave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Agregar una dirección válida</translation>
<translation id="4072486802667267160">Se produjo un error al procesar tu pedido. Vuelve a intentarlo.</translation>
<translation id="4075732493274867456">El cliente y el servidor no admiten un conjunto de cifrado o una versión de protocolo SSL en común.</translation>
@@ -516,10 +576,12 @@
<translation id="4159784952369912983">Púrpura</translation>
<translation id="4165986682804962316">Configuración del sitio</translation>
<translation id="4171400957073367226">La firma de verificación no es válida.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elemento más}other{<ph name="ITEM_COUNT" /> elementos más}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Paso 1: Accede al portal&lt;/h4&gt;
@@ -551,58 +613,79 @@
<translation id="4277028893293644418">Restablecer contraseña</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Se guardó esta tarjeta en tu Cuenta de Google}other{Se guardaron estas tarjetas en tu Cuenta de Google}}</translation>
+<translation id="42981349822642051">Expandir</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Cambiar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloquear (predeterminado)</translation>
+<translation id="4318566738941496689">Tu nombre de dispositivo y la dirección de red</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="4340982228985273705">Esta computadora no se detectó como una empresa administrada, por lo que la política solo puede instalar automáticamente las extensiones alojadas en Chrome Web Store. La URL de actualización de Chrome Web Store es "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Tarjetas de crédito aceptadas</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Administrar formas de pago…</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Teléfono</translation>
<translation id="4406896451731180161">resultados de búsqueda</translation>
-<translation id="4406972042435603828">Tus administradores instalaron extensiones con potentes capacidades.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Dirección de retiro</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="443121186588148776">Puerto en serie</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="4434045419905280838">Ventanas emergentes y redirec.</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Se inhabilitó el uso de un proxy, pero se especificó una configuración explícita de proxy.</translation>
<translation id="445100540951337728">Tarjetas de débito aceptadas</translation>
+<translation id="4466881336512663640">Se perderán los cambios del formulario. ¿Confirmas que deseas continuar?</translation>
<translation id="4482953324121162758">Este sitio no se traducirá.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">La URL no es válida. Debe ser una URL con un esquema estándar, p. ej., http://ejemplo.com o https://ejemplo.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Detalles</translation>
<translation id="4524805452350978254">Administrar tarjetas</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Intenta inhabilitar tus extensiones.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Entrega</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Quitar tarjeta</translation>
<translation id="4587425331216688090">¿Confirmas que quieres quitar la dirección de Chrome?</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="4597348597567598915">Tamaño 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Ir ahora</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="467809019005607715">Presentaciones de Google</translation>
<translation id="4690462567478992370">Dejar de usar un certificado no válido</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Se interrumpió la conexión</translation>
<translation id="471880041731876836">No tienes permiso para visitar este sitio</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Ejecución del Diagnóstico de red de Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Volver a cargar políticas</translation>
<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Reinicia Chromium.</translation>
<translation id="473775607612524610">Actualizar</translation>
<translation id="4738601419177586157">Sugerencia de búsqueda: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Administrar contraseñas…</translation>
<translation id="4744603770635761495">Ruta ejecutable</translation>
+<translation id="4746351372139058112">Mensajes</translation>
<translation id="4750917950439032686">Tu información (p. ej., contraseñas o números de tarjetas de crédito) es privada cuando se envía a este sitio.</translation>
<translation id="4756388243121344051">&amp;Historial</translation>
<translation id="4758311279753947758">Agregar información de contacto</translation>
@@ -610,9 +693,9 @@
<translation id="4764776831041365478">Es posible que la página web en <ph name="URL" /> no funcione temporalmente o se haya trasladado de manera permanente a una nueva dirección web.</translation>
<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4785689107224900852">Cambiar a esta pestaña</translation>
-<translation id="4792143361752574037">Se produjo un error al acceder a los archivos de la sesión. Por el momento, no se pueden guardar en el disco. Vuelve a cargar la página para intentarlo de nuevo.</translation>
<translation id="4798078619018708837">Ingresa la fecha de vencimiento y el CVC de la tarjeta <ph name="CREDIT_CARD" /> para actualizar los datos. Después de confirmar esta acción, esos datos en tu Cuenta de Google se compartirán con este sitio.</translation>
<translation id="4800132727771399293">Verifica la fecha de vencimiento y el CVC, y vuelve a intentarlo.</translation>
+<translation id="480334179571489655">Error en la política de origen</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>
@@ -627,7 +710,6 @@
<translation id="4881695831933465202">Abrir</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>
@@ -636,15 +718,15 @@
<translation id="4943872375798546930">Sin resultados</translation>
<translation id="4950898438188848926">Botón para cambiar de pestaña; presiona Intro para cambiar a la pestaña abierta <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Acciones</translation>
-<translation id="495832697253704892">Informe de las extensiones</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Mostrar lista</translation>
<translation id="4974590756084640048">Volver a habilitar las advertencias</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Ver todo</translation>
<translation id="4989809363548539747">Este complemento no es compatible</translation>
-<translation id="4996230189582812866">Informes</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="5014174725590676422">Se muestra la pantalla de primera ejecución del Asistente de Google en Chrome</translation>
<translation id="5015510746216210676">Nombre de la máquina:</translation>
+<translation id="5017554619425969104">Texto que copiaste</translation>
<translation id="5018422839182700155">No se puede abrir esta página</translation>
<translation id="5019198164206649151">La memoria auxiliar se encuentra en mal estado.</translation>
<translation id="5023310440958281426">Revisa las políticas del administrador.</translation>
@@ -654,35 +736,51 @@
<translation id="5034369478845443529">Contexto local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidad</translation>
+<translation id="5043480802608081735">Vínculo que copiaste</translation>
<translation id="5045550434625856497">Contraseña incorrecta</translation>
<translation id="5056549851600133418">Artículos para ti</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comprobar la dirección de proxy<ph name="END_LINK" />.</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="5097099694988056070">Estadísticas del dispositivo, como el uso de CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Tu dispositivo y tu cuenta se administran mediante el dominio <ph name="ENROLLMENT_DOMAIN" /> y el <ph name="ACCOUNT_DOMAIN" /> respectivamente. Esto significa que tus administradores pueden configurarlos de forma remota.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bits)</translation>
-<translation id="5128122789703661928">La sesión con este nombre no se puede borrar.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Administrar direcciones…</translation>
+<translation id="5138227688689900538">Mostrar menos</translation>
<translation id="5141240743006678641">Encriptar contraseñas sincronizadas con tus credenciales de Google</translation>
<translation id="5145883236150621069">Código de error en la respuesta de la política</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Abre la página en una nueva ventana de incógnito (⇧⌘N).</translation>
<translation id="516920405563544094">Ingresa el CVC de la tarjeta <ph name="CREDIT_CARD" />. Después de confirmarla, los datos de la tarjeta en tu Cuenta de Google se compartirán con este sitio.</translation>
<translation id="5169827969064885044">Es posible que hayas perdido el acceso a la cuenta de tu organización o sufrido un robo de identidad. Chrome te recomienda que cambies la contraseña ahora.</translation>
<translation id="5171045022955879922">Buscar o escribir URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Equipo</translation>
<translation id="5179510805599951267">¿No está en <ph name="ORIGINAL_LANGUAGE" />? Informa este error</translation>
<translation id="5190835502935405962">Barra de favoritos</translation>
-<translation id="5200263511887412697">enviar una lista con los usuarios de dispositivos que accedieron recientemente</translation>
+<translation id="519422657042045905">La anotación no está disponible</translation>
<translation id="5201306358585911203">Una página incorporada en esta página dice</translation>
<translation id="5205222826937269299">Nombre (obligatorio)</translation>
<translation id="5215116848420601511">Formas de pago y direcciones con Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Correo electrónico (obligatorio)</translation>
<translation id="5230733896359313003">Dirección de envío</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Conectarse a una red"</translation>
<translation id="5251803541071282808">Nube</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Direcciones de red</translation>
<translation id="5285570108065881030">Mostrar todas las contraseñas guardadas</translation>
<translation id="5287240709317226393">Mostrar cookies</translation>
<translation id="5288108484102287882">La validación de los valores de la política generó advertencias</translation>
@@ -694,7 +792,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> de <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Seleccionar información de contacto</translation>
<translation id="5327248766486351172">Nombre</translation>
+<translation id="5329858041417644019">Tu navegador no está administrado</translation>
<translation id="5332219387342487447">Método de envío</translation>
+<translation id="5334013548165032829">Registros detallados del sistema</translation>
<translation id="5344579389779391559">Es posible que esta página intente cobrarte dinero</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>
@@ -702,6 +802,7 @@
<translation id="5377026284221673050">"El reloj está atrasado", "El reloj está adelantado" o "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Para usar tus tarjetas en todos los dispositivos, accede a tu cuenta y activa la sincronización.</translation>
<translation id="5386426401304769735">La cadena del certificado de este sitio web contiene un certificado que se firmó con SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -712,6 +813,7 @@
<translation id="5457113250005438886">Sin validez</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Rehacer Editar</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">Es posible que este contenido intente instalar software peligroso que robe o borre tu información en tu dispositivo . <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Agregar una dirección válida</translation>
<translation id="5490432419156082418">Direcciones y más</translation>
@@ -719,10 +821,12 @@
<ph name="LINE_BREAK" />
Intenta contactar al administrador de tu sistema.</translation>
<translation id="549333378215107354">Tamaño 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Favoritos administrados</translation>
<translation id="5510766032865166053">Es posible que lo hayan movido o borrado.</translation>
<translation id="5523118979700054094">Nombre de la política</translation>
<translation id="552553974213252141">¿Se extrajo el texto correctamente?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">No se pudo encontrar el artículo solicitado.</translation>
<translation id="5541546772353173584">Agregar correo electrónico</translation>
<translation id="5545756402275714221">Artículos para ti</translation>
@@ -737,15 +841,21 @@
<translation id="5595485650161345191">Editar dirección</translation>
<translation id="5598944008576757369">Seleccionar forma de pago</translation>
<translation id="560412284261940334">No se admite la administración.</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> te redireccionó demasiadas veces.</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="5632627355679805402">Tus datos se encriptaron con tu <ph name="BEGIN_LINK" />contraseña de Google<ph name="END_LINK" /> el <ph name="TIME" />. Ingresa la contraseña para iniciar la sincronización.</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="563324245173044180">Se bloqueó contenido engañoso.</translation>
<translation id="5659593005791499971">Correo electrónico</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">El administrador de este dispositivo instaló extensiones para funciones adicionales. Las extensiones tienen acceso a algunos de tus datos.</translation>
<translation id="5675650730144413517">Esta página no funciona</translation>
+<translation id="5684874026226664614">No se puede traducir esta página.</translation>
<translation id="5685654322157854305">Agregar dirección de envío</translation>
<translation id="5689199277474810259">Exportar a JSON</translation>
<translation id="5689516760719285838">Ubicación</translation>
@@ -754,38 +864,39 @@
<translation id="5710435578057952990">No se ha verificado la identidad de este sitio web.</translation>
<translation id="5719499550583120431">Se aceptan tarjetas de prepago.</translation>
<translation id="5720705177508910913">Usuario actual</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome te recomienda que restablezcas tu contraseña si la volviste a usar en otros sitios.</translation>
<translation id="5732392974455271431">Tus padres pueden desbloquearlo por ti</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Guarda la tarjeta en tu Cuenta de Google}other{Guarda las tarjetas en tu Cuenta de Google}}</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="5770114862687765385">Es posible que el archivo esté dañado. Haz clic en "Restablecer" para reiniciar la sesión.</translation>
<translation id="5778550464785688721">Control total de dispositivos MIDI</translation>
<translation id="578305955206182703">Ámbar</translation>
<translation id="57838592816432529">Silenciar</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>
+<translation id="5798290721819630480">¿Descartas los cambios?</translation>
<translation id="5798683403665926540">Cambia la página principal en la configuración de Chrome</translation>
<translation id="5803412860119678065">¿Deseas llenar los campos con la información de tu tarjeta <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permisos</translation>
<translation id="5810442152076338065">Tu conexión a <ph name="DOMAIN" /> está encriptada con un conjunto de cifrado obsoleto.</translation>
<translation id="5813119285467412249">&amp;Rehacer Agregar</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="5860033963881614850">Desactivado</translation>
<translation id="5863847714970149516">Es posible que la página siguiente intente cobrarte dinero</translation>
<translation id="5866257070973731571">Agregar número de teléfono</translation>
<translation id="5869405914158311789">No se puede acceder a este sitio</translation>
<translation id="5869522115854928033">Contraseñas almacenadas</translation>
<translation id="5887400589839399685">Tarjeta guardada</translation>
-<translation id="5893718151540690985">informar una lista de las interfaces de red con sus tipos y direcciones de hardware</translation>
<translation id="5893752035575986141">Se aceptan tarjetas de crédito.</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="5916664084637901428">Activada</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">¿Quieres guardar la tarjeta en la Cuenta de Google?</translation>
<translation id="5922853866070715753">Ya casi</translation>
<translation id="5932224571077948991">El sitio muestra anuncios intrusivos o engañosos</translation>
-<translation id="5939518447894949180">Restablecer</translation>
<translation id="5946937721014915347">Abriendo <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">No se puede realizar la inscripción con una cuenta personal (licencia de paquete disponible).</translation>
<translation id="5967592137238574583">Editar la información de contacto</translation>
@@ -793,6 +904,7 @@
<translation id="5975083100439434680">Alejar</translation>
<translation id="5977489021191000276">Tu dispositivo no está administrado.</translation>
<translation id="5977976211062815271">En este dispositivo</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">No se puede abrir la app de pago</translation>
<translation id="5989320800837274978">No se especifican servidores proxy fijos ni URL de secuencias de comandos .pac.</translation>
<translation id="5990559369517809815">Una extensión bloqueó las solicitudes al servidor.</translation>
@@ -803,8 +915,8 @@
<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="6033927989869462158">informar las estadísticas sobre hardware, como el uso de CPU y RAM</translation>
<translation id="6034000775414344507">Gris claro</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Si el problema persiste, comunícate con el propietario del sitio.</translation>
<translation id="6040143037577758943">Cerrar</translation>
<translation id="6044573915096792553">Tamaño 12</translation>
@@ -813,10 +925,10 @@
<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="6058977677006700226">¿Quieres usar tus tarjetas en todos los dispositivos?</translation>
<translation id="6059925163896151826">Dispositivos USB</translation>
-<translation id="6071091556643036997">El tipo de política no es válido.</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="6094273045989040137">Agregar anotación</translation>
<translation id="610911394827799129">Es posible que tu cuenta de Google tenga otros formularios del historial de navegación en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Información sobre las extensiones y los complementos instalados</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>
@@ -851,15 +963,21 @@
<translation id="6337133576188860026">Esta acción libera menos de <ph name="SIZE" />. Es posible que algunos sitios se carguen más lento en tu próxima visita.</translation>
<translation id="6337534724793800597">Filtrar políticas por nombre</translation>
<translation id="6358450015545214790">¿Qué significa esto?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Es posible que se cobren cargos.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 sugerencia más}other{# sugerencias más}}</translation>
<translation id="6387754724289022810">Para realizar pagos de forma más rápida la próxima vez, guarda tu tarjeta y dirección de facturación en tu cuenta de Google y en este dispositivo.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Editar marcador</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Rechazar</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Agregar más información</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar reenvío del formulario</translation>
@@ -872,11 +990,17 @@
<translation id="6508722015517270189">Reinicia Chrome.</translation>
<translation id="6529602333819889595">&amp;Rehacer Eliminar</translation>
<translation id="6534179046333460208">Sugerencias de la Web física</translation>
+<translation id="6556866813142980365">Rehacer</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="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Rosa claro</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Vínculo que copiaste</translation>
+<translation id="6591833882275308647">Tu <ph name="DEVICE_TYPE" /> no está administrado.</translation>
<translation id="6596325263575161958">Opciones de encriptación</translation>
<translation id="6604181099783169992">Sensores de luz o movimiento</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Información de contacto</translation>
<translation id="6626291197371920147">Agregar un número de tarjeta válido</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Búsqueda</translation>
@@ -885,6 +1009,7 @@
<translation id="6644283850729428850">Esta política no ha sido aprobada.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ninguno}=1{De 1 sitio (no saldrás de tu cuenta de Google)}other{De # sitios (no saldrás de tu cuenta de Google)}}</translation>
<translation id="6657585470893396449">Contraseña</translation>
+<translation id="6670613747977017428">Volver a la versión segura</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>
@@ -892,12 +1017,15 @@
<translation id="671076103358959139">Token de inscripción:</translation>
<translation id="6711464428925977395">Hay un error en el servidor proxy o la dirección es incorrecta.</translation>
<translation id="6723740634201835758">En tu Cuenta de Google</translation>
+<translation id="6738516213925468394">Tus datos se encriptaron con la <ph name="BEGIN_LINK" />frase de contraseña de sincronización<ph name="END_LINK" /> el <ph name="TIME" />. Ingresa la frase para iniciar la sincronización.</translation>
<translation id="674375294223700098">Error de certificado de servidor desconocido.</translation>
<translation id="6744009308914054259">Mientras esperas a que se restablezca la conexión, puedes visitar Descargas para leer artículos sin conexión.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositivo se suspendió.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Uno de tus padres aún no lo aprobó</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Extensiones</translation>
<translation id="679355240208270552">Se ignora porque la búsqueda predeterminada no está habilitada según la política.</translation>
<translation id="681021252041861472">Campo obligatorio</translation>
<translation id="6810899417690483278">ID de personalización</translation>
@@ -930,10 +1058,12 @@
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">Distrito</translation>
<translation id="6973656660372572881">Se especifican servidores proxy fijos y URL de secuencias de comandos .pac.</translation>
+<translation id="6973932557599545801">No puedo ayudarte. Continúa por tu cuenta.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Silenciar (predeterminado)</translation>
<translation id="6984479912851154518">Saldrás del modo privado para pagar mediante una aplicación externa. ¿Deseas continuar?</translation>
<translation id="6989763994942163495">Mostrar configuración avanzada...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Siempre traducir <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Estos cargos pueden ser únicos o recurrentes, y es posible que no sean evidentes.</translation>
@@ -949,28 +1079,36 @@
<translation id="7108338896283013870">Ocultar</translation>
<translation id="7108819624672055576">Permitido por una extensión</translation>
<translation id="7111012039238467737">(Válido)</translation>
+<translation id="7118618213916969306">Buscar la URL <ph name="SHORT_URL" /> del portapapeles</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="7135130955892390533">Mostrar estado</translation>
<translation id="7138472120740807366">Método de entrega</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">La URL no es válida. Debes usar una URL con un esquema estándar.</translation>
<translation id="717330890047184534">ID de GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">El servidor <ph name="ORIGIN" /> al que te diriges solicitó
+ que se aplicara una política de seguridad a todas las solicitudes. Sin embargo, en lugar de
+ entregar una política, redirigió al navegador a otro sitio, lo que impide que
+ el navegador cumpla con tu solicitud para el sitio <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Guardar y completar formas de pago</translation>
<translation id="7180611975245234373">Actualizar</translation>
<translation id="7182878459783632708">No hay políticas establecidas.</translation>
<translation id="7186367841673660872">Esta página se tradujo de<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Esta acción libera hasta <ph name="SIZE" />. Es posible que algunos sitios carguen más lento en tu próxima visita.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Tu administrador puede ver lo siguiente:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> no cumple con las normas de seguridad.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /> acerca de este problema.</translation>
<translation id="7219179957768738017">La conexión usa <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Procesando</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Este sitio web contiene software malicioso</translation>
+<translation id="724766306220616965">Advertencias, Conflicto</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="7251437084390964440">La configuración de red no cumple con el estándar ONC. Es posible que no se importen algunas partes de la configuración.
Detalles adicionales:
@@ -983,11 +1121,14 @@ Detalles adicionales:
<translation id="7300012071106347854">Azul cobalto</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Advertencias de <ph name="BEGIN_LINK" />Navegación segura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ayuda con la conexión</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Línea de comandos</translation>
-<translation id="7365061714576910172">Exportar Linux</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>
@@ -995,6 +1136,7 @@ Detalles adicionales:
<translation id="7381288752349550461">Anulación de sesión administrada</translation>
<translation id="7390545607259442187">Confirmar tarjeta</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Tu <ph name="DEVICE_NAME" /> está administrado</translation>
<translation id="7407424307057130981">&lt;p&gt;Se muestra este error si tienes el software Superfish en tu computadora con Windows.&lt;/p&gt;
&lt;p&gt;Realiza estos pasos para inhabilitar el software de forma temporal a fin de que puedas acceder a la Web. Necesitarás privilegios de administrador.&lt;/p&gt;
&lt;ol&gt;
@@ -1005,7 +1147,7 @@ Detalles adicionales:
&lt;li&gt;Haz clic en &lt;strong&gt;Aplicar&lt;/strong&gt; y, luego, en &lt;strong&gt;Aceptar&lt;/strong&gt;.
&lt;li&gt;Visita el &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centro de ayuda de Chrome&lt;/a&gt; para obtener información sobre cómo quitar el software de forma permanente de tu computadora.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Administración de <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Administrar contraseñas…</translation>
<translation id="7419106976560586862">Ruta del perfil</translation>
<translation id="7437289804838430631">Agregar información de contacto</translation>
@@ -1014,22 +1156,24 @@ Detalles adicionales:
<translation id="7442725080345379071">Naranja claro</translation>
<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="7449109375006139765">enviar registros del sistema al servidor de administración</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="7460618730930299168">La proyección es diferente a tu selección. ¿Quieres continuar?</translation>
<translation id="7473891865547856676">No, gracias</translation>
-<translation id="7475525192983021547">informar los períodos en el que un usuario utiliza el dispositivo</translation>
<translation id="7481312909269577407">Reenviar</translation>
<translation id="7485870689360869515">No se encontró ningún dato.</translation>
+<translation id="7498234416455752244">Seguir editando</translation>
<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="7508870219247277067">Verde aguacate</translation>
<translation id="7511955381719512146">Es posible que la red Wi-Fi que estás usando requiera que accedas a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Tu conexión con este sitio no es privada</translation>
+<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatoria</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1038,8 +1182,8 @@ Detalles adicionales:
<translation id="7552846755917812628">Intenta las siguientes sugerencias:</translation>
<translation id="7554791636758816595">Nueva pestaña</translation>
<translation id="7564049878696755256">Es posible que hayas perdido el acceso a tu cuenta de <ph name="ORG_NAME" /> o sufrido un robo de identidad. Chrome te recomienda que cambies la contraseña ahora.</translation>
-<translation id="7566125604157659769">Texto que copiaste</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="7568105740864181217">Este navegador está administrado por una empresa, institución educativa o alguna otra organización. Tu administrador puede cambiar la configuración de tu navegador de forma remota. Es posible que la actividad en este dispositivo también se administre fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></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>
@@ -1050,6 +1194,7 @@ Detalles adicionales:
<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="7633909222644580952">Informes sobre fallos y datos de rendimiento</translation>
<translation id="7637571805876720304">¿Confirmas que quieres quitar la tarjeta de crédito de Chromium?</translation>
<translation id="7639968568612851608">Gris oscuro</translation>
<translation id="765676359832457558">Ocultar configuración avanzada...</translation>
@@ -1059,9 +1204,11 @@ Detalles adicionales:
<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="7676643023259824263">Buscar el texto <ph name="TEXT" /> en el portapapeles</translation>
<translation id="7681101578153515023">Cambiar motor de búsqueda</translation>
<translation id="7682287625158474539">Envío</translation>
<translation id="7687186412095877299">Completa los formularios de pago con la información que tengas guardada</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">En este momento, tienes tarjetas que pueden usarse solo en este dispositivo. Haz clic en Continuar para revisar las tarjetas.</translation>
<translation id="7699293099605015246">Los artículos no están disponibles en este momento</translation>
<translation id="7701040980221191251">Ninguno</translation>
@@ -1073,11 +1220,13 @@ Detalles adicionales:
<translation id="774634243536837715">Se bloqueó contenido peligroso.</translation>
<translation id="7752995774971033316">Sin administrar</translation>
<translation id="7755287808199759310">Uno de tus padres puede desbloquearlo por ti</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Es posible que un software antivirus o un firewall hayan bloqueado la conexión.</translation>
<translation id="7759163816903619567">Dominio para mostrar:</translation>
<translation id="7761701407923456692">El certificado del servidor no coincide con la dirección URL.</translation>
<translation id="7763386264682878361">Analizador del manifiesto de pagos</translation>
<translation id="7764225426217299476">Agregar dirección</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Agregar</translation>
<translation id="7793809570500803535">Es posible que la página web en <ph name="SITE" /> no funcione temporalmente o se haya trasladado de manera permanente a una nueva dirección web.</translation>
@@ -1089,8 +1238,8 @@ Detalles adicionales:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">¿Confirmas que quieres quitar la sugerencia de formulario de Chrome?</translation>
<translation id="7815407501681723534">Se encontraron <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> para "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Administración de políticas</translation>
<translation id="782886543891417279">Es posible que la red Wi-Fi que estás usando (<ph name="WIFI_NAME" />) requiera que visites la página de acceso.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ninguna}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Sin embargo, no eres invisible. El modo de navegación de incógnito no oculta tu navegación de tu empleador, de tu proveedor de servicios de Internet, ni de los sitios web que visitas.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1099,7 +1248,7 @@ Detalles adicionales:
<translation id="7878562273885520351">Es posible que tu contraseña esté en peligro</translation>
<translation id="7882421473871500483">Marrón</translation>
<translation id="7887683347370398519">Verifica tu CVC y vuelve a intentarlo.</translation>
-<translation id="7893255318348328562">Nombre de sesión</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Ingresa un número de teléfono válido</translation>
<translation id="7935318582918952113">Filtro de DOM</translation>
<translation id="7937554595067888181">Fecha de vencimiento: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1109,21 +1258,25 @@ Detalles adicionales:
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Favoritos del celular</translation>
<translation id="7961015016161918242">Nunca</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Navegador</translation>
<translation id="8009225694047762179">Administrar contraseñas</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Se guardará esta tarjeta y su dirección de facturación. Podrás usarla cuando accedas a <ph name="USER_EMAIL" />.}other{Se guardarán estas tarjetas y sus direcciones de facturación. Podrás usarlas cuando accedas a <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Esta página está en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Lápiz</translation>
+<translation id="8037117624646282037">Quién usó el dispositivo recientemente</translation>
<translation id="8037357227543935929">Preguntar (predeterminado)</translation>
<translation id="803771048473350947">Archivo</translation>
<translation id="8041089156583427627">Enviar comentario</translation>
<translation id="8041940743680923270">Usar configuración global predeterminada (Preguntar)</translation>
<translation id="8042918947222776840">Elegir método de retiro</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" no se configuró correctamente. Prueba desinstalar "<ph name="SOFTWARE_NAME" />" para corregir el problema. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Tu dispositivo se configuró para:</translation>
+<translation id="8066955247577885446">Se produjo un error.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">No se pueden realizar anotaciones cuando el documento está rotado</translation>
<translation id="8079031581361219619">¿Deseas volver a cargar el sitio?</translation>
<translation id="8088680233425245692">Error al visualizar artículo</translation>
@@ -1132,11 +1285,12 @@ Detalles adicionales:
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
<translation id="8092774999298748321">Púrpura oscuro</translation>
<translation id="8094917007353911263">Es posible que la red que estás usando requiera que accedas a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Se quitaron las tarjetas no válidas</translation>
<translation id="8103161714697287722">Forma de pago</translation>
<translation id="8118489163946903409">Forma de pago</translation>
+<translation id="8123836779274890062">Administrado por <ph name="DEVICE_TYPE" /> (<ph name="ENROLLMENT_DOMAIN" />)</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" no se instaló correctamente en tu computadora o red. Solicita al administrador de IT que corrija este problema.</translation>
-<translation id="8130693978878176684">No puedo ayudarte más. Continúa por tus propios medios.</translation>
<translation id="8131740175452115882">Confirmar</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>
@@ -1146,8 +1300,11 @@ Detalles adicionales:
<translation id="8197543752516192074">Traducir página</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="8202370299023114387">Conflicto</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">La conexión es segura</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Abre la página en una nueva pestaña de incógnito.</translation>
@@ -1159,14 +1316,16 @@ Detalles adicionales:
<translation id="825929999321470778">Mostrar todas las contraseñas guardadas</translation>
<translation id="8261506727792406068">Borrar</translation>
<translation id="8267698848189296333">Acceder como <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242"><ph name="ENROLLMENT_DOMAIN" /> administra este navegador. Tu administrador puede cambiar la configuración de tu navegador de forma remota. Es posible que la actividad en este dispositivo también se administre fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Iniciar sesión</translation>
<translation id="8288807391153049143">Mostrar certificado</translation>
<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="8298115750975731693">Es posible que la red Wi-Fi que estás usando (<ph name="WIFI_NAME" />) requiera que accedas a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</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="8311129316111205805">Cargar sesión</translation>
<translation id="8332188693563227489">Se denegó el acceso a <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1184,7 +1343,6 @@ Detalles adicionales:
<translation id="8416694386774425977">La configuración de red no es válida y no se pudo importar.
Detalles adicionales:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositivo administrado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Cambiar</translation>
<translation id="8428213095426709021">Configuración</translation>
@@ -1212,9 +1370,11 @@ Detalles adicionales:
<translation id="860043288473659153">Nombre del titular de la tarjeta</translation>
<translation id="861775596732816396">Tamaño 4</translation>
<translation id="8620436878122366504">Tus padres aún no lo aprobaron</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Guardar esta tarjeta para este dispositivo</translation>
<translation id="8663226718884576429">Resumen del pedido, <ph name="TOTAL_LABEL" />, Más detalles</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, respuesta, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Tu conexión a <ph name="DOMAIN" /> no está cifrada.</translation>
<translation id="8718314106902482036">No se completó el pago</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sugerencia de búsqueda</translation>
@@ -1228,6 +1388,7 @@ Detalles adicionales:
<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="8763927697961133303">Dispositivo USB</translation>
<translation id="8768895707659403558">Para usar tus tarjetas en todos los dispositivos, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Rehacer Eliminar</translation>
<translation id="8792621596287649091">Es posible que hayas perdido el acceso a tu cuenta de <ph name="ORG_NAME" /> o sufrido un robo de identidad. Chromium te recomienda que cambies la contraseña ahora.</translation>
<translation id="8800988563907321413">Las sugerencias de la sección Cercanas aparecen aquí</translation>
@@ -1238,10 +1399,12 @@ Detalles adicionales:
<translation id="885730110891505394">Compartir con Google</translation>
<translation id="8858065207712248076">Chrome te recomienda que restablezcas la contraseña de <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> si la volviste a usar en otros sitios.</translation>
<translation id="8866481888320382733">Error al analizar la configuración de la política</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Cerrado recientemente</translation>
<translation id="8874824191258364635">Ingresa un número de tarjeta válido</translation>
<translation id="8891727572606052622">Modo proxy no válido</translation>
<translation id="8903921497873541725">Acercar</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">¿Quieres guardar esta tarjeta en tu cuenta de Google?</translation>
<translation id="8932102934695377596">El reloj está atrasado</translation>
<translation id="893332455753468063">Agregar nombre</translation>
@@ -1249,13 +1412,13 @@ Detalles adicionales:
<translation id="894185898663964645">Tu administrador configuró certificados raíz personalizados, lo que le permite ver el contenido de los sitios web que visites.</translation>
<translation id="8943282376843390568">Verde lima</translation>
<translation id="8957210676456822347">Autorización de portal cautivo</translation>
+<translation id="8966619695390250636">¿Quisiste decir…?</translation>
<translation id="8968766641738584599">Guardar la tarjeta</translation>
<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8975012916872825179">Incluye información, como números de teléfono, direcciones de correo electrónico y direcciones de envío</translation>
<translation id="8978053250194585037">Recientemente, la navegación segura de Google <ph name="BEGIN_LINK" />detectó un intento de suplantación de identidad (phishing)<ph name="END_LINK" /> en <ph name="SITE" />. Los sitios de suplantación de identidad imitan a otros sitios web para engañarte.</translation>
<translation id="8983003182662520383">Formas de pago y direcciones con Google Pay</translation>
<translation id="8987927404178983737">Mes</translation>
-<translation id="8988408250700415532">Se produjo un error. Puedes finalizar el pedido en el sitio web.</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>
@@ -1265,6 +1428,7 @@ Detalles adicionales:
<translation id="9011424611726486705">Abrir la configuración del sitio</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(No válido)</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>
@@ -1276,11 +1440,11 @@ Detalles adicionales:
<translation id="9065745800631924235">Búsqueda de <ph name="TEXT" /> desde el historial</translation>
<translation id="9069693763241529744">Bloqueado por una extensión</translation>
<translation id="9076283476770535406">Es posible que incluya contenido para adultos</translation>
+<translation id="9076630408993835509">Este navegador no está administrado por una empresa ni por otra organización. Es posible que la actividad en este dispositivo se administre fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Se requiere más información</translation>
<translation id="9080712759204168376">Resumen del pedido</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>
<translation id="9106062320799175032">Agregar dirección de facturación</translation>
-<translation id="9110718169272311511">El Asistente de Google en Chrome está disponible cerca de la parte inferior de la pantalla</translation>
<translation id="9114524666733003316">Confirmando tarjeta…</translation>
<translation id="9128870381267983090">Conectarse a una red</translation>
<translation id="9137013805542155359">Mostrar original</translation>
@@ -1289,6 +1453,7 @@ Detalles adicionales:
<translation id="9148507642005240123">&amp;Deshacer Editar</translation>
<translation id="9154194610265714752">Actualizado</translation>
<translation id="9157595877708044936">Configurando...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Permitir que los sitios determinen si tienes formas de pago guardadas</translation>
<translation id="9169664750068251925">Bloquear siempre en este sitio</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
@@ -1303,10 +1468,12 @@ Detalles adicionales:
<translation id="9219103736887031265">Imágenes</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">BORRAR FORMULARIO</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Podrías perder el acceso a tu Cuenta de Google. Chromium te recomienda cambiar la contraseña ahora. Deberás acceder a la cuenta.</translation>
<translation id="939736085109172342">Nueva carpeta</translation>
<translation id="945855313015696284">Comprueba la información que se muestra a continuación y borra las tarjetas que no sean válidas</translation>
<translation id="951104842009476243">Tarjetas de débito y prepago aceptadas</translation>
+<translation id="958202389743790697">Se bloqueó conforme a la política de seguridad de <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Este contenido podría intentar instalar apps engañosas que se hagan pasar por otro tipo de contenido o que recopilen datos que se usen para rastrearte. <ph name="BEGIN_LINK" />Mostrar de todos modos<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Build oficial</translation>
<translation id="973773823069644502">Agregar dirección de entrega</translation>
@@ -1315,6 +1482,7 @@ Detalles adicionales:
<translation id="984275831282074731">Formas de pago</translation>
<translation id="985199708454569384">&lt;p&gt;Este error se muestra si la fecha y hora de tu computadora o dispositivo móvil son incorrectas.&lt;/p&gt;
&lt;p&gt;Para solucionar el error, abre el reloj del dispositivo y asegúrate de que la fecha y hora sean correctas.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Build para desarrolladores</translation>
<translation id="989988560359834682">Modificar dirección</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_es.xtb b/chromium/components/strings/components_strings_es.xtb
index e728fbeed2b..14186129bdf 100644
--- a/chromium/components/strings/components_strings_es.xtb
+++ b/chromium/components/strings/components_strings_es.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es">
-<translation id="1005145902654145231">No se ha podido cambiar el nombre de la sesión.</translation>
<translation id="1008557486741366299">Ahora no</translation>
<translation id="1010200102790553230">Cargar la página más tarde</translation>
<translation id="1015730422737071372">Proporciónanos más detalles</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nombre desconocido</translation>
<translation id="1050038467049342496">Cierra otras aplicaciones</translation>
<translation id="1055184225775184556">&amp;Deshacer acción de añadir</translation>
+<translation id="1056898198331236512">Advertencia</translation>
<translation id="1058479211578257048">Guardando tarjetas…</translation>
<translation id="10614374240317010">Contraseñas que nunca se guardan</translation>
+<translation id="1062160989074299343">Prc10 (sobre)</translation>
<translation id="106701514854093668">Marcadores del ordenador</translation>
<translation id="1074497978438210769">No es seguro</translation>
<translation id="1080116354587839789">Se ajusta al ancho</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Añade el nombre de la tarjeta</translation>
<translation id="1089439967362294234">Cambiar contraseña</translation>
<translation id="109743633954054152">Gestiona contraseñas en la configuración de Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Es probable que se muestren advertencias mientras se actualiza la seguridad de los sitios web, pero pronto se solucionará.</translation>
<translation id="1126551341858583091">El tamaño del almacenamiento local es de <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Caché de política correcta</translation>
+<translation id="1131264053432022307">Imagen copiada</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Cambiar nombre</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Quitar</translation>
<translation id="1197088940767939838">Naranja</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">El nombre de tu dispositivo</translation>
<translation id="124116460088058876">Más idiomas</translation>
<translation id="1250759482327835220">Para pagar más rápido la próxima vez, guarda tu tarjeta, tu nombre y tu dirección de facturación en tu cuenta de Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variaciones de la línea de comandos</translation>
<translation id="129553762522093515">Cerrado recientemente</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Borrar las cookies<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">La sesión seleccionada no existe.</translation>
+<translation id="1320233736580025032">Prc1 (sobre)</translation>
+<translation id="132301787627749051">Buscar imagen del portapapeles</translation>
<translation id="1323433172918577554">Mostrar más</translation>
<translation id="132390688737681464">Guardar y autocompletar direcciones</translation>
<translation id="1333989956347591814">Es posible que tu actividad <ph name="BEGIN_EMPHASIS" />todavía sea visible<ph name="END_EMPHASIS" /> para:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Dirección de recogida</translation>
<translation id="1348198688976932919">El sitio web al que vas a acceder contiene aplicaciones peligrosas</translation>
<translation id="1348779747280417563">Confirmar nombre</translation>
+<translation id="1357195169723583938">Quién ha utilizado este dispositivo recientemente y cuándo</translation>
+<translation id="1364822246244961190">Esta política está bloqueada, su valor será ignorado.</translation>
<translation id="1374468813861204354">sugerencias</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Información de la versión</translation>
<translation id="1376836354785490390">Mostrar menos</translation>
<translation id="1377321085342047638">Número de tarjeta</translation>
<translation id="138218114945450791">Azul claro</translation>
+<translation id="1382194467192730611">Dispositivo USB autorizado por tu administrador</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> no ha enviado ningún dato.</translation>
+<translation id="140316286225361634">El sitio web <ph name="ORIGIN" /> ha solicitado que se aplique una política de seguridad a todas sus solicitudes, y esta política considera que el sitio web no es seguro.</translation>
<translation id="1405567553485452995">Verde claro</translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Error de privacidad</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Sí</translation>
<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455413310270022028">Borrador</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Mostrar más</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Seleccionar dirección de envío</translation>
+<translation id="1492194039220927094">Envío de políticas:</translation>
<translation id="1501859676467574491">Mostrar las tarjetas de tu cuenta de Google</translation>
-<translation id="1506687042165942984">Muestra una copia guardada (es decir, no actualizada) de esta página.</translation>
<translation id="1507202001669085618">&lt;p&gt;Este error se muestra si utilizas un portal Wi‑Fi en el que debes iniciar sesión antes de conectarte a Internet.&lt;/p&gt;
&lt;p&gt;Para solucionar el problema, haz clic en &lt;strong&gt;Conectar&lt;/strong&gt; en la página que intentas abrir.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Número de teléfono requerido</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Fecha de compilación</translation>
<translation id="1521655867290435174">Hojas de cálculo de Google</translation>
<translation id="1527263332363067270">Esperando conexión…</translation>
+<translation id="1529521330346880926">10x15 (sobre)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Esta página dice</translation>
<translation id="153384715582417236">Eso es todo por ahora</translation>
<translation id="154408704832528245">Seleccionar dirección de entrega</translation>
<translation id="1549470594296187301">JavaScript debe estar habilitado para utilizar esta función.</translation>
+<translation id="155039086686388498">Engineering-D</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;Configuración&lt;/strong&gt;.&lt;/p&gt;</translation>
+<translation id="1569487616857761740">Introducir fecha de vencimiento</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imagen copiada</translation>
<translation id="1620510694547887537">Cámara</translation>
<translation id="1623104350909869708">Evitar que esta página cree cuadros de diálogo adicionales</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Finalizar sesión</translation>
<translation id="1639239467298939599">Cargando</translation>
<translation id="1640180200866533862">Políticas de usuario</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">El certificado del servidor contiene una clave criptográfica no segura.</translation>
<translation id="1697532407822776718">¡Listo!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">El documento es demasiado grande para poder añadir anotaciones</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>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Intenta ponerte en contacto con el administrador del sistema.</translation>
<translation id="1740951997222943430">Introduce un mes de vencimiento válido</translation>
<translation id="1743520634839655729">Para pagar más rápido la próxima vez, guarda tu tarjeta, tu nombre y tu dirección de facturación en tu cuenta de Google y en este dispositivo.</translation>
+<translation id="1745880797583122200">Tu navegador está administrado</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>
@@ -152,8 +170,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nombre del titular de la tarjeta</translation>
<translation id="1821930232296380041">Parámetros de solicitud o solicitud no válidos</translation>
+<translation id="1822540298136254167">Sitios web que visitas y el tiempo que pasas en ellos</translation>
<translation id="1826516787628120939">Comprobando</translation>
<translation id="1834321415901700177">Este sitio web contiene programas dañinos</translation>
<translation id="1839551713262164453">No se ha podido hacer la validación de los valores de la política porque se han producido errores</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Borrar los datos del historial de navegación de Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{y una más}other{y # más}}</translation>
<translation id="2003709556000175978">Cambia tu contraseña ahora</translation>
+<translation id="20053308747750172">El servidor al que te diriges, <ph name="ORIGIN" />, ha solicitado que se aplique una política de seguridad a todas las solicitudes que reciba. Sin embargo, acaba de proporcionar una política no válida que impide al navegador procesar la solicitud de <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Se ha establecido que el proxy se configure automáticamente.</translation>
<translation id="2030481566774242610">¿Querías decir <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Comprobar el proxy y el cortafuegos<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Departamento</translation>
<translation id="2102134110707549001">Sugerir contraseña segura…</translation>
<translation id="2108755909498034140">Reinicia el ordenador</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Tarjeta</translation>
<translation id="2114841414352855701">Se ha ignorado la política porque la anula <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Marcadores del móvil</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (sobre)</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2183608646556468874">N.º de teléfono</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{Una dirección}other{# direcciones}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Número de teléfono</translation>
<translation id="2283340219607151381">Guardar y autocompletar direcciones</translation>
<translation id="2292556288342944218">Tu acceso a Internet está bloqueado</translation>
+<translation id="2294558542833290837">El enlace que has abierto es inusual</translation>
+<translation id="2297722699537546652">B5 (sobre)</translation>
+<translation id="2310021320168182093">Chou2 (sobre)</translation>
<translation id="2316887270356262533">Libera menos de 1 MB. Algunos sitios web pueden tardar más en cargarse la próxima vez que accedas a ellos.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> necesita un nombre de usuario y una contraseña.</translation>
<translation id="2317583587496011522">Se aceptan tarjetas de débito.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />; fecha de caducidad: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Configuración controlada por el administrador</translation>
+<translation id="2346319942568447007">Imagen copiada</translation>
<translation id="2349790679044093737">La sesión de realidad virtual está activa</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>
@@ -239,29 +266,34 @@
<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="2378238891085281592">Has entrado en modo privado.</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">El servidor al que te diriges, <ph name="ORIGIN" />, ha solicitado que se aplique una política de seguridad a todas las solicitudes que reciba. Sin embargo, no ha proporcionado ninguna política, lo que impide al navegador procesar tu solicitud de <ph name="SITE" />.</translation>
<translation id="244665789865330679"><ph name="ENROLLMENT_DOMAIN" /> gestiona tu dispositivo y tu cuenta. Esto significa que el administrador puede configurar tu dispositivo y tu cuenta de manera remota.</translation>
<translation id="2463193859425327265">Cambiar página de inicio</translation>
<translation id="2463739503403862330">Rellenar</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Seleccionar método de entrega</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ejecutar Diagnósticos de red<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traducir esta página</translation>
<translation id="2479410451996844060">La URL de búsqueda no es válida.</translation>
<translation id="2482878487686419369">Notificaciones</translation>
<translation id="248348093745724435">Políticas del equipo</translation>
+<translation id="2485387744899240041">Nombres de usuario de tu dispositivo y navegador</translation>
<translation id="2491120439723279231">El certificado del servidor contiene errores.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Escanear nueva tarjeta</translation>
<translation id="2501278716633472235">Volver</translation>
<translation id="2503184589641749290">Tarjetas prepago y de débito aceptadas</translation>
<translation id="2515629240566999685">Comprobar la señal en tu zona</translation>
-<translation id="2516852381693169964">Buscar imagen en <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Solo se guardará en este dispositivo</translation>
<translation id="2524461107774643265">Añade más información</translation>
<translation id="2536110899380797252">Añadir dirección</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (sobre)</translation>
<translation id="2625385379895617796">Tu reloj está adelantado</translation>
<translation id="2634124572758952069">No se ha podido encontrar la dirección IP del servidor de <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Estado:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Cierra otras pestañas o aplicaciones</translation>
<translation id="267371737713284912">pulsa <ph name="MODIFIER_KEY_DESCRIPTION" /> para deshacer</translation>
<translation id="2674170444375937751">¿Seguro que quieres eliminar estas páginas del historial?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Salir</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Tarjetas aceptadas</translation>
<translation id="2702801445560668637">Lista de lectura</translation>
<translation id="2704283930420550640">El valor no coincide con el formato.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Eliminar elementos seleccionados</translation>
<translation id="277133753123645258">Método de envío</translation>
<translation id="277499241957683684">Falta un registro de dispositivo.</translation>
-<translation id="2781030394888168909">Exportar para MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Se ha restablecido la conexión.</translation>
<translation id="2788784517760473862">Tarjetas de crédito aceptadas</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Abrir una ventana de incógnito</translation>
+<translation id="2850739647070081192">Invite (sobre)</translation>
<translation id="2851634818064021665">Necesitas permiso para acceder a este sitio web</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">¿Quieres guardar la tarjeta?</translation>
<translation id="2903493209154104877">Direcciones</translation>
<translation id="290376772003165898">¿La página no está en <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Método de entrega</translation>
<translation id="2928905813689894207">Dirección de facturación</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (sobre)</translation>
<translation id="3024663005179499861">Tipo de política incorrecto</translation>
<translation id="3037605927509011580">¡Vaya!</translation>
<translation id="3041612393474885105">Datos del certificado</translation>
+<translation id="3060227939791841287">C9 (sobre)</translation>
<translation id="3064966200440839136">Saldrás del modo de 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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Añadir dirección de recogida</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">No tienes autorización para ver esta página.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> de <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancelar pago</translation>
<translation id="3207960819495026254">Añadido a marcadores</translation>
-<translation id="3209375525920864198">Introduce un nombre de sesión válido.</translation>
+<translation id="321912867715453276">Advertencia: Esta política tiene más de una fuente, pero los valores son los mismos.</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="3229041911291329567">Información de la versión del dispositivo y del navegador</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Añadir un nombre de la tarjeta</translation>
<translation id="3287510313208355388">Descargar cuando haya conexión</translation>
<translation id="3293642807462928945">Más información sobre la política <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">No se han encontrado resultados de búsqueda</translation>
-<translation id="3305707030755673451">Tus datos se cifraron con tu frase de contraseña de sincronización el <ph name="TIME" />. Introdúcela para iniciar la sincronización.</translation>
<translation id="3320021301628644560">Añadir dirección de facturación</translation>
<translation id="3324983252691184275">Carmesí</translation>
<translation id="3338095232262050444">Es seguro</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;Rehacer edición</translation>
<translation id="342781501876943858">Chromium te recomienda que cambies tu contraseña si la has vuelto a utilizar en otros sitios web.</translation>
<translation id="3431636764301398940">Guardar esta tarjeta en el dispositivo</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">El propietario de este dispositivo ha desactivado el juego del dinosaurio.</translation>
<translation id="3447884698081792621">Mostrar certificado (emitido por <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Intervalo de comprobación:</translation>
+<translation id="3456231139987291353">Number-11 (sobre)</translation>
<translation id="3461824795358126837">Rotulador</translation>
<translation id="3462200631372590220">Ocultar configuración avanzada</translation>
<translation id="3467763166455606212">El nombre del titular de la tarjeta es obligatorio</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">Se aceptan tarjetas prepago y de crédito.</translation>
<translation id="3582930987043644930">Añade un nombre</translation>
<translation id="3583757800736429874">&amp;Rehacer movimiento</translation>
+<translation id="35866233670761917">Los administradores no pueden ver el contenido de los sitios web que visitas</translation>
<translation id="3586931643579894722">Ocultar detalles</translation>
+<translation id="3592413004129370115">Italian (sobre)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Tamaño 2</translation>
<translation id="3615877443314183785">Introduce una fecha de vencimiento válida</translation>
<translation id="36224234498066874">Borrar datos de navegación...</translation>
<translation id="362276910939193118">Mostrar historial completo</translation>
-<translation id="3623476034248543066">Mostrar valor</translation>
<translation id="3630155396527302611">Si ya está incluido como programa autorizado para acceder a la red,
elimínalo de la lista y vuelve a añadirlo.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validación correcta</translation>
<translation id="3655670868607891010">Si este mensaje aparece con frecuencia, prueba a solucionarlo con estas <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisión</translation>
<translation id="366077651725703012">Actualizar tarjeta de crédito</translation>
<translation id="3676592649209844519">ID del dispositivo:</translation>
+<translation id="3677008721441257057">Quizás quisiste decir: &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;</translation>
<translation id="3678029195006412963">No se ha podido firmar la solicitud</translation>
<translation id="3678529606614285348">Abre una página en una nueva ventana de incógnito (Ctrl + Mayús + N).</translation>
<translation id="3679803492151881375">Informe sobre fallos registrado el <ph name="CRASH_TIME" /> y subido el <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +497,14 @@
<translation id="3704162925118123524">La red que estás utilizando puede requerir el acceso a su página de inicio de sesión.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Cargando...</translation>
+<translation id="3709599264800900598">Texto copiado</translation>
<translation id="3712624925041724820">Licencias agotadas</translation>
<translation id="3714780639079136834">Activar los datos móviles o la conexión Wi-Fi</translation>
<translation id="3715597595485130451">Conectarse a una red Wi-Fi</translation>
<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="372429172604983730">Entre las aplicaciones que pueden provocar este error se incluyen software cortafuegos, antivirus, proxy y de filtrado web.</translation>
+<translation id="373042150751172459">B4 (sobre)</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="3745099705178523657">Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de Google se compartirá con este sitio web.</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>
@@ -470,10 +517,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Vencimiento: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Tamaño 16</translation>
+<translation id="3797522431967816232">Prc3 (sobre)</translation>
<translation id="3807873520724684969">Contenido dañino bloqueado.</translation>
<translation id="3810973564298564668">Gestionar</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="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ha instalado extensiones que aportan funciones adicionales. Las extensiones tienen acceso a algunos de tus datos.</translation>
<translation id="385051799172605136">Atrás</translation>
<translation id="3858027520442213535">Actualizar fecha y hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo en conflicto</translation>
@@ -481,6 +530,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Preguntar siempre en este sitio web</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>
@@ -491,11 +541,13 @@
<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="3984550557525787191">Este nombre de sesión ya existe.</translation>
<translation id="3987940399970879459">Menos de 1 MB</translation>
+<translation id="4008849406247176967">Advertencia: Esta política tiene más de una fuente con valores en conflicto.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ 1 página web cercana}other{ # páginas web cercanas}}</translation>
<translation id="4030383055268325496">&amp;Deshacer acción de añadir</translation>
+<translation id="4032320456957708163">El navegador lo administra <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Clave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (sobre)</translation>
<translation id="4067947977115446013">Añade una dirección válida</translation>
<translation id="4072486802667267160">Se ha producido un error al procesar el pedido. Vuelve a intentarlo.</translation>
<translation id="4075732493274867456">El cliente y el servidor no son compatibles con la misma versión de protocolo SSL o de cifrado.</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">Morado</translation>
<translation id="4165986682804962316">Configuración del sitio web</translation>
<translation id="4171400957073367226">La firma de verificación no es válida</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> elemento más}other{<ph name="ITEM_COUNT" /> elementos más}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (sobre)</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="4221630205957821124">&lt;h4&gt;Paso 1: Inicia sesión en el portal&lt;/h4&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">Cambiar contraseña</translation>
<translation id="4280429058323657511">Vcto. <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Se ha guardado esta tarjeta en tu cuenta de Google}other{Se han guardado estas tarjetas en tu cuenta de Google}}</translation>
+<translation id="42981349822642051">Mostrar</translation>
+<translation id="4302965934281694568">Chou3 (sobre)</translation>
<translation id="4305817255990598646">Cambiar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloquear (predeterminado)</translation>
+<translation id="4318566738941496689">El nombre de tu dispositivo y la dirección de red</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="4340982228985273705">No se ha detectado que este ordenador esté administrado por la empresa, por lo que la política solo puede instalar automáticamente extensiones alojadas en Chrome Webstore. La URL de actualización de Chrome Webstore es "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Tarjetas de crédito aceptadas</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gestiona tus métodos de pago...</translation>
+<translation id="4367563149485757821">Number-12 (sobre)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Teléfono</translation>
<translation id="4406896451731180161">resultados de la búsqueda</translation>
-<translation id="4406972042435603828">Tus administradores han instalado extensiones que incluyen funciones muy potentes.</translation>
<translation id="4408413947728134509">Cookies: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Dirección de recogida</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="443121186588148776">Puerto serie</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="4434045419905280838">Ventanas emergentes y redirecciones</translation>
+<translation id="4435702339979719576">Postcard)</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="445100540951337728">Tarjetas de débito aceptadas</translation>
+<translation id="4466881336512663640">Se perderán los cambios realizados en el formulario. ¿Seguro que quieres continuar?</translation>
<translation id="4482953324121162758">Este sitio web no se traducirá.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">La URL no es válida. Debe ser una URL con una estructura estándar, como "http://example.com" o "https://example.com".</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (sobre)</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="4517607026994743406">Comm-10 (sobre)</translation>
<translation id="4522570452068850558">Detalles</translation>
<translation id="4524805452350978254">Gestionar tarjetas</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Inhabilita las extensiones.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Envío</translation>
+<translation id="4579056131138995126">Personal (sobre)</translation>
<translation id="4582204425268416675">Eliminar tarjeta</translation>
<translation id="4587425331216688090">¿Eliminar dirección de Chrome?</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="4597348597567598915">Tamaño 8</translation>
+<translation id="4600854749408232102">C6/C5 (sobre)</translation>
<translation id="4646534391647090355">Ir allí ahora</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="467809019005607715">Presentaciones de Google</translation>
<translation id="4690462567478992370">Dejar de utilizar un certificado no válido</translation>
+<translation id="4691835149146451662">Architecture-A (sobre)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Se ha interrumpido la conexión</translation>
<translation id="471880041731876836">No tienes permiso para acceder a este sitio web</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Ejecutar Diagnósticos de red de Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Volver a cargar políticas</translation>
<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4731967714531604179">Prc2 (sobre)</translation>
<translation id="4736825316280949806">Reinicia Chromium</translation>
<translation id="473775607612524610">Actualizar</translation>
<translation id="4738601419177586157">Sugerencia de búsqueda de <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Gestionar contraseñas…</translation>
<translation id="4744603770635761495">Ruta del ejecutable</translation>
+<translation id="4746351372139058112">Mensajes</translation>
<translation id="4750917950439032686">Tu información (por ejemplo, las contraseñas o los números de las tarjetas de crédito) es privada cuando se envía a este sitio web.</translation>
<translation id="4756388243121344051">&amp;Historial</translation>
<translation id="4758311279753947758">Añadir información de contacto</translation>
@@ -609,9 +684,9 @@
<translation id="4764776831041365478">Es posible que la página web <ph name="URL" /> esté temporalmente inactiva o que se haya trasladado definitivamente a otra dirección.</translation>
<translation id="4771973620359291008">Se ha producido un error desconocido.</translation>
<translation id="4785689107224900852">Cambiar a esta pestaña</translation>
-<translation id="4792143361752574037">No se ha podido acceder a los archivos de la sesión. La opción para guardar contenido en el disco está inhabilitada. Vuelve a cargar la página para intentarlo de nuevo.</translation>
<translation id="4798078619018708837">Introduce la fecha de vencimiento y el CVC de <ph name="CREDIT_CARD" /> para actualizar la información de tu tarjeta. Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de Google se compartirá con este sitio web.</translation>
<translation id="4800132727771399293">Comprueba la fecha de caducidad y el código CVC, y vuelve a intentarlo</translation>
+<translation id="480334179571489655">Error de política de origen</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>
@@ -626,7 +701,6 @@
<translation id="4881695831933465202">Abrir</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>
@@ -635,15 +709,15 @@
<translation id="4943872375798546930">Sin resultados</translation>
<translation id="4950898438188848926">Botón de cambio de pestaña; pulsa Intro para cambiar a la pestaña abierta, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Acciones</translation>
-<translation id="495832697253704892">Informes de extensiones</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Expandir lista</translation>
<translation id="4974590756084640048">Volver a habilitar advertencias</translation>
+<translation id="4984339528288761049">Prc5 (sobre)</translation>
<translation id="4989163558385430922">Ver todo</translation>
<translation id="4989809363548539747">Este complemento no es compatible</translation>
-<translation id="4996230189582812866">Informes</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="5014174725590676422">Se muestra la primera pantalla de ejecución del Asistente de Google en Chrome</translation>
<translation id="5015510746216210676">Nombre del equipo:</translation>
+<translation id="5017554619425969104">Texto copiado</translation>
<translation id="5018422839182700155">No se puede abrir esta página</translation>
<translation id="5019198164206649151">El almacén secundario está en mal estado.</translation>
<translation id="5023310440958281426">Consulta las políticas del administrador</translation>
@@ -653,35 +727,51 @@
<translation id="5034369478845443529">Contexto local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidad</translation>
+<translation id="5043480802608081735">Enlace copiado</translation>
<translation id="5045550434625856497">Contraseña incorrecta</translation>
<translation id="5056549851600133418">Artículos recomendados para ti</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Comprobar la dirección del proxy<ph name="END_LINK" /></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/provincia</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="5097099694988056070">Estadísticas del dispositivo, como uso de CPU y RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465"><ph name="ENROLLMENT_DOMAIN" /> gestiona tu dispositivo y <ph name="ACCOUNT_DOMAIN" />, tu cuenta. Esto significa que los administradores pueden configurar de manera remota tu dispositivo y tu cuenta.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bits)</translation>
-<translation id="5128122789703661928">No se puede eliminar la sesión con este nombre.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gestiona tus direcciones...</translation>
+<translation id="5138227688689900538">Mostrar menos</translation>
<translation id="5141240743006678641">Cifrar contraseñas sincronizadas con tus credenciales de Google</translation>
<translation id="5145883236150621069">Código de error presente en respuesta de la política</translation>
+<translation id="515292512908731282">C4 (sobre)</translation>
<translation id="5159010409087891077">Abre una página en una nueva ventana de incógnito (⇧ + ⌘ + N)</translation>
<translation id="516920405563544094">Introduce el CVC de <ph name="CREDIT_CARD" />. Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de Google se compartirá con este sitio web.</translation>
<translation id="5169827969064885044">Podrías perder el acceso a la cuenta de tu organización o tener problemas de suplantación de identidad. Chrome te recomienda que cambies tu contraseña ahora.</translation>
<translation id="5171045022955879922">Busca o escribe una URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Equipo</translation>
<translation id="5179510805599951267">¿Esta página no está escrita en <ph name="ORIGINAL_LANGUAGE" />? Informa de este error.</translation>
<translation id="5190835502935405962">Barra de marcadores</translation>
-<translation id="5200263511887412697">permite informar de la lista de usuarios del dispositivo que han iniciado sesión recientemente</translation>
+<translation id="519422657042045905">No están disponibles las anotaciones</translation>
<translation id="5201306358585911203">Una página insertada en esta dice</translation>
<translation id="5205222826937269299">Nombre obligatorio</translation>
<translation id="5215116848420601511">Métodos de pago y direcciones con Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Correo electrónico obligatorio</translation>
<translation id="5230733896359313003">Dirección de envío</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Conectarse a la red"</translation>
<translation id="5251803541071282808">Nube</translation>
+<translation id="5252000469029418751">C7 (sobre)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Direcciones de red</translation>
<translation id="5285570108065881030">Mostrar todas las contraseñas guardadas</translation>
<translation id="5287240709317226393">Mostrar cookies</translation>
<translation id="5288108484102287882">La validación de los valores de las políticas ha generado advertencias</translation>
@@ -693,7 +783,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> de <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Seleccionar información de contacto</translation>
<translation id="5327248766486351172">Nombre</translation>
+<translation id="5329858041417644019">Tu navegador no está administrado</translation>
<translation id="5332219387342487447">Método de envío</translation>
+<translation id="5334013548165032829">Registros detallados del sistema</translation>
<translation id="5344579389779391559">Es posible que esta página intente aplicar algún cargo</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>
@@ -701,6 +793,7 @@
<translation id="5377026284221673050">"Tu reloj está atrasado" o "Tu reloj está adelantado" o "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Para utilizar las tarjetas en todos tus dispositivos, inicia sesión y activa la sincronización.</translation>
<translation id="5386426401304769735">La cadena de certificados de este sitio web contiene un certificado firmado con SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +804,7 @@
<translation id="5457113250005438886">No válido</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Rehacer edición</translation>
+<translation id="5478437291406423475">B6/C4 (sobre)</translation>
<translation id="5481076368049295676">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="54817484435770891">Añadir dirección válida</translation>
<translation id="5490432419156082418">Direcciones y más</translation>
@@ -718,10 +812,12 @@
<ph name="LINE_BREAK" />
Ponte en contacto con el administrador del sistema.</translation>
<translation id="549333378215107354">Tamaño 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Marcadores administrados</translation>
<translation id="5510766032865166053">Es posible que se haya movido o eliminado.</translation>
<translation id="5523118979700054094">Nombre de la política</translation>
<translation id="552553974213252141">¿Se ha extraído el texto correctamente?</translation>
+<translation id="553484882784876924">Prc6 (sobre)</translation>
<translation id="5540224163453853">No se ha podido encontrar el artículo solicitado.</translation>
<translation id="5541546772353173584">Añade un correo electrónico</translation>
<translation id="5545756402275714221">Artículos recomendados para ti</translation>
@@ -736,15 +832,21 @@
<translation id="5595485650161345191">Editar dirección</translation>
<translation id="5598944008576757369">Seleccionar método de pago</translation>
<translation id="560412284261940334">Administración no admitida</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">La página <ph name="HOST_NAME" /> te ha redirigido demasiadas veces.</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="5632627355679805402">Tus datos están cifrados con tu <ph name="BEGIN_LINK" />contraseña de Google<ph name="END_LINK" /> desde el <ph name="TIME" />. Introdúcela para iniciar la sincronización.</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="563324245173044180">Contenido engañoso bloqueado.</translation>
<translation id="5659593005791499971">Correo electrónico</translation>
+<translation id="5663614846592581799">9x11 (sobre)</translation>
+<translation id="5663955426505430495">El administrador de este dispositivo ha instalado extensiones que aportan funciones adicionales. Las extensiones tienen acceso a algunos de tus datos.</translation>
<translation id="5675650730144413517">Esta página no funciona</translation>
+<translation id="5684874026226664614">¡Vaya! No se ha podido traducir esta página.</translation>
<translation id="5685654322157854305">Añadir dirección de envío</translation>
<translation id="5689199277474810259">Exportar a JSON</translation>
<translation id="5689516760719285838">Ubicación</translation>
@@ -753,38 +855,39 @@
<translation id="5710435578057952990">No se ha verificado la identidad de este sitio web.</translation>
<translation id="5719499550583120431">Se aceptan tarjetas prepago.</translation>
<translation id="5720705177508910913">Usuario actual</translation>
+<translation id="5728056243719941842">C5 (sobre)</translation>
<translation id="5730040223043577876">Chrome te recomienda que cambies tu contraseña si la has vuelto a utilizar en otros sitios web.</translation>
<translation id="5732392974455271431">Tus padres pueden desbloquearlo</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Guarda la tarjeta en tu cuenta de Google}other{Guarda las tarjetas en tu cuenta de Google}}</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="5770114862687765385">Parece que el archivo está dañado. Haz clic en el botón Recuperar para recuperar la sesión.</translation>
<translation id="5778550464785688721">Control total de dispositivos MIDI</translation>
<translation id="578305955206182703">Ámbar</translation>
<translation id="57838592816432529">Silenciar</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>
+<translation id="5798290721819630480">¿Quieres descartar los cambios?</translation>
<translation id="5798683403665926540">Cambia la página de inicio en la configuración de Chrome</translation>
<translation id="5803412860119678065">¿Quieres rellenar la información de <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permisos</translation>
<translation id="5810442152076338065">Tu conexión con <ph name="DOMAIN" /> está cifrada con un conjunto de cifrado obsoleto.</translation>
<translation id="5813119285467412249">&amp;Rehacer acción de añadir</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="5860033963881614850">No</translation>
<translation id="5863847714970149516">Es posible que la página a la que vas a acceder intente aplicar algún cargo</translation>
<translation id="5866257070973731571">Añade un número de teléfono</translation>
<translation id="5869405914158311789">No se puede acceder a este sitio web</translation>
<translation id="5869522115854928033">Contraseñas guardadas</translation>
<translation id="5887400589839399685">Tarjeta guardada</translation>
-<translation id="5893718151540690985">permite informar de la lista de interfaces de red con sus tipos y sus direcciones de hardware</translation>
<translation id="5893752035575986141">Se aceptan tarjetas de crédito.</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="5916664084637901428">Activar</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">¿Quieres guardar la tarjeta en tu cuenta de Google?</translation>
<translation id="5922853866070715753">Casi hemos acabado</translation>
<translation id="5932224571077948991">El sitio web muestra anuncios invasivos o engañosos</translation>
-<translation id="5939518447894949180">Restablecer</translation>
<translation id="5946937721014915347">Abriendo <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">No te puedes registrar con una cuenta de consumidor (hay una licencia asociada disponible).</translation>
<translation id="5967592137238574583">Edita la información de contacto</translation>
@@ -792,6 +895,7 @@
<translation id="5975083100439434680">Reducir</translation>
<translation id="5977489021191000276">Tu dispositivo no está gestionado por un administrador.</translation>
<translation id="5977976211062815271">En este dispositivo</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">No se ha podido abrir la aplicación de pago</translation>
<translation id="5989320800837274978">No se han especificado servidores proxy fijos ni una URL de secuencia de comandos .pac.</translation>
<translation id="5990559369517809815">Una extensión ha bloqueado el envío de solicitudes al servidor.</translation>
@@ -802,8 +906,8 @@
<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="6033927989869462158">permite informar de estadísticas de hardware, como el uso de CPU y memoria RAM</translation>
<translation id="6034000775414344507">Gris claro</translation>
+<translation id="6034283069659657473">10x14 (sobre)</translation>
<translation id="6039846035001940113">Si el problema persiste, ponte en contacto con el propietario del sitio web.</translation>
<translation id="6040143037577758943">Cerrar</translation>
<translation id="6044573915096792553">Tamaño 12</translation>
@@ -812,10 +916,10 @@
<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="6058977677006700226">¿Quieres usar las tarjetas en todos tus dispositivos?</translation>
<translation id="6059925163896151826">Dispositivos USB</translation>
-<translation id="6071091556643036997">El tipo de política no es válido.</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="6094273045989040137">Anotar</translation>
<translation id="610911394827799129">Es posible que tu cuenta de Google tenga otros tipos de historial de navegación en la página <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Información de las extensiones y complementos instalados</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>
@@ -850,15 +954,21 @@
<translation id="6337133576188860026">Libera menos de <ph name="SIZE" />. Algunos sitios web pueden tardar más en cargarse la próxima vez que accedas a ellos.</translation>
<translation id="6337534724793800597">Filtrar políticas por nombre</translation>
<translation id="6358450015545214790">¿Necesitas ayuda?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Es posible que se cobren cargos en el futuro.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{Una sugerencia más}other{# sugerencias más}}</translation>
<translation id="6387754724289022810">Para pagar más rápido la próxima vez, guarda tu tarjeta y tu dirección de facturación en tu cuenta de Google y en este dispositivo.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Editar marcador</translation>
+<translation id="6406765186087300643">C0 (sobre)</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="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="6434309073475700221">Rechazar</translation>
+<translation id="6446163441502663861">Kahu (sobre)</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>
@@ -871,11 +981,17 @@
<translation id="6508722015517270189">Reinicia Chrome</translation>
<translation id="6529602333819889595">&amp;Rehacer eliminación</translation>
<translation id="6534179046333460208">Sugerencias de la Web física</translation>
+<translation id="6556866813142980365">Rehacer</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="6578796323535178455">C2 (sobre)</translation>
<translation id="6579990219486187401">Rosa claro</translation>
+<translation id="6583674473685352014">B6 (sobre)</translation>
+<translation id="6587923378399804057">Enlace copiado</translation>
+<translation id="6591833882275308647">Tu <ph name="DEVICE_TYPE" /> no está administrado</translation>
<translation id="6596325263575161958">Opciones de cifrado</translation>
<translation id="6604181099783169992">Sensores de luz o movimiento</translation>
+<translation id="6609880536175561541">Prc7 (sobre)</translation>
<translation id="6624427990725312378">Información de contacto</translation>
<translation id="6626291197371920147">Añadir un número de tarjeta válido</translation>
<translation id="6628463337424475685">Búsqueda de <ph name="ENGINE" /></translation>
@@ -884,6 +1000,7 @@
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ninguno}=1{De 1 sitio web (no se cerrará la sesión en tu cuenta de Google)}other{De # sitios web (no se cerrará la sesión en tu cuenta de Google)}}</translation>
<translation id="6657585470893396449">Contraseña</translation>
+<translation id="6670613747977017428">Volver para estar a salvo.</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>
@@ -891,12 +1008,15 @@
<translation id="671076103358959139">Token de registro:</translation>
<translation id="6711464428925977395">Se ha producido un error con el servidor proxy o la dirección es incorrecta.</translation>
<translation id="6723740634201835758">De tu cuenta de Google</translation>
+<translation id="6738516213925468394">Tus datos están cifrados con tu <ph name="BEGIN_LINK" />frase de contraseña de sincronización<ph name="END_LINK" /> desde el <ph name="TIME" />. Introdúcela para iniciar la sincronización.</translation>
<translation id="674375294223700098">Error de certificado de servidor desconocido</translation>
<translation id="6744009308914054259">Mientras esperas a que haya conexión, puedes ir a Descargas para leer artículos sin conexión.</translation>
<translation id="6753269504797312559">Valor de la política</translation>
<translation id="6757797048963528358">El dispositivo se ha suspendido.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Uno de tus padres aún no lo ha aprobado</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Extensiones</translation>
<translation id="679355240208270552">Se ha ignorado el valor porque se ha establecido una política que inhabilita la búsqueda predeterminada.</translation>
<translation id="681021252041861472">Campo obligatorio</translation>
<translation id="6810899417690483278">ID de personalización</translation>
@@ -929,10 +1049,12 @@
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">Distrito</translation>
<translation id="6973656660372572881">Se especifican tanto servidores proxy fijos como una URL de secuencia de comandos .pac.</translation>
+<translation id="6973932557599545801">Lo siento, no puedo ayudarte. Puedes continuar por tu cuenta.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Silenciar (predeterminado)</translation>
<translation id="6984479912851154518">Saldrás del modo privado para hacer un pago en una aplicación externa. ¿Quieres continuar?</translation>
<translation id="6989763994942163495">Mostrar configuración avanzada...</translation>
+<translation id="6993898126790112050">6x9 (sobre)</translation>
<translation id="6996312675313362352">Traducir siempre del <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Estos cargos pueden ser únicos o periódicos, y es posible que no se indiquen de una forma evidente.</translation>
@@ -948,28 +1070,33 @@
<translation id="7108338896283013870">Ocultar</translation>
<translation id="7108819624672055576">Permitido por una extensión</translation>
<translation id="7111012039238467737">(válido)</translation>
+<translation id="7118618213916969306">Buscar la URL <ph name="SHORT_URL" /> del portapapeles</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="7135130955892390533">Mostrar estado</translation>
<translation id="7138472120740807366">Método de entrega</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7152423860607593928">Number-14 (sobre)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">La URL no es válida. Debe ser una URL con un esquema estándar.</translation>
<translation id="717330890047184534">ID de GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">El servidor al que te diriges, <ph name="ORIGIN" />, ha solicitado que se aplique una política de seguridad a todas las solicitudes que reciba. Sin embargo, en lugar de proporcionar una política, ha redirigido el navegador a otro sitio web, lo que impide que el navegador procese tu solicitud de <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Guardar y autocompletar métodos de pago</translation>
<translation id="7180611975245234373">Actualizar</translation>
<translation id="7182878459783632708">No hay políticas establecidas.</translation>
<translation id="7186367841673660872">Esta página se ha traducido del<ph name="ORIGINAL_LANGUAGE" />al<ph name="LANGUAGE_LANGUAGE" />.</translation>
<translation id="7192203810768312527">Libera <ph name="SIZE" />. Algunos sitios web pueden tardar más en cargarse la próxima vez que accedas a ellos.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">El administrador puede consultar lo siguiente:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">La página <ph name="HOST_NAME" /> no cumple los estándares de seguridad.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /> sobre este problema.</translation>
<translation id="7219179957768738017">La conexión utiliza <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Procesando pago</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">El sitio web al que vas a acceder contiene software malicioso</translation>
+<translation id="724766306220616965">Advertencias, conflicto</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="7251437084390964440">La configuración de red no cumple el estándar ONC. Es posible que no se importen algunas partes de la configuración.
Más información:
@@ -982,11 +1109,14 @@ Más información:
<translation id="7300012071106347854">Azul cobalto</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Advertencias de <ph name="BEGIN_LINK" />Navegación Segura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ayuda de conexión</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Línea de comandos</translation>
-<translation id="7365061714576910172">Exportar Linux</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>
@@ -994,6 +1124,7 @@ Más información:
<translation id="7381288752349550461">Anulación de la sesión administrada</translation>
<translation id="7390545607259442187">Confirmar tarjeta</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Tu <ph name="DEVICE_NAME" /> está administrado</translation>
<translation id="7407424307057130981">&lt;p&gt;Este error se muestra si tu ordenador Windows tiene software SuperFish.&lt;/p&gt;
&lt;p&gt;Sigue estos pasos para inhabilitar temporalmente este software en tu ordenador y acceder a Internet. Necesitarás privilegios de administrador.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1135,7 @@ Más información:
&lt;li&gt;Haz clic en &lt;strong&gt;Aplicar&lt;/strong&gt; y, a continuación, en &lt;strong&gt;Aceptar&lt;/strong&gt;
&lt;li&gt;Visita el &lt;a href="https://support.google.com/chrome/answer/6098869?hl=es"&gt;Centro de Ayuda de Chrome&lt;/a&gt; para consultar cómo eliminar el software de forma permanente de tu ordenador
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestión de <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Gestionar contraseñas…</translation>
<translation id="7419106976560586862">Ruta del perfil</translation>
<translation id="7437289804838430631">Añade la información de contacto</translation>
@@ -1013,22 +1144,24 @@ Más información:
<translation id="7442725080345379071">Naranja claro</translation>
<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="7449109375006139765">permite enviar los registros del sistema al servidor de administración</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="7460618730930299168">El filtro es distinto al que has seleccionado. ¿Quieres continuar?</translation>
<translation id="7473891865547856676">No, gracias</translation>
-<translation id="7475525192983021547">permite informar de los periodos durante los que un usuario está activo en el dispositivo</translation>
<translation id="7481312909269577407">Adelante</translation>
<translation id="7485870689360869515">No se han encontrado datos.</translation>
+<translation id="7498234416455752244">Seguir editando</translation>
<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="7508870219247277067">Verde aguacate</translation>
<translation id="7511955381719512146">La red Wi-Fi que estás utilizando puede requerir que accedas a la página <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (sobre)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Tu conexión con este sitio web no es privada</translation>
+<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obligatoria</translation>
+<translation id="7538364083937897561">A2 (sobre)</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>
@@ -1037,8 +1170,8 @@ Más información:
<translation id="7552846755917812628">Prueba los siguientes consejos:</translation>
<translation id="7554791636758816595">Nueva pestaña</translation>
<translation id="7564049878696755256">Podrías perder el acceso a tu cuenta de <ph name="ORG_NAME" /> o tener problemas de suplantación de identidad. Chrome te recomienda que cambies tu contraseña ahora.</translation>
-<translation id="7566125604157659769">Texto copiado</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="7568105740864181217">Este navegador lo administra una empresa, un centro educativo u otra organización. El administrador puede modificar la configuración del navegador de manera remota. Es posible que también se administre la actividad de este dispositivo fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></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>
@@ -1049,6 +1182,7 @@ Más información:
<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="7633909222644580952">Datos de rendimiento e informes sobre fallos</translation>
<translation id="7637571805876720304">¿Quitar tarjeta de crédito de Chromium?</translation>
<translation id="7639968568612851608">Gris oscuro</translation>
<translation id="765676359832457558">Ocultar configuración avanzada...</translation>
@@ -1058,12 +1192,14 @@ Más información:
<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="7676643023259824263">Buscar texto <ph name="TEXT" /> del portapapeles</translation>
<translation id="7681101578153515023">Cambiar motor de búsqueda</translation>
<translation id="7682287625158474539">Dirección de envío</translation>
<translation id="7687186412095877299">Rellena formularios de pago con tus métodos de pago guardados</translation>
+<translation id="7697066736081121494">Prc8 (sobre)</translation>
<translation id="769721561045429135">Tienes tarjetas que solo se pueden usar en este dispositivo. Haz clic en Continuar para revisarlas.</translation>
<translation id="7699293099605015246">Los artículos no están disponibles en este momento</translation>
-<translation id="7701040980221191251">Ninguno</translation>
+<translation id="7701040980221191251">No hay</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>
@@ -1072,11 +1208,13 @@ Más información:
<translation id="774634243536837715">Contenido peligroso bloqueado.</translation>
<translation id="7752995774971033316">No administrado</translation>
<translation id="7755287808199759310">Uno de tus padres puede desbloquearlo</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Puede que el cortafuegos o el software antivirus hayan bloqueado la conexión.</translation>
<translation id="7759163816903619567">Dominio visible:</translation>
<translation id="7761701407923456692">El certificado del servidor no coincide con la URL.</translation>
<translation id="7763386264682878361">Analizador de archivos de manifiesto de pagos</translation>
<translation id="7764225426217299476">Añadir dirección</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefectura</translation>
<translation id="7791543448312431591">Añadir</translation>
<translation id="7793809570500803535">Es posible que la página web de <ph name="SITE" /> esté temporalmente inactiva o que se haya trasladado definitivamente a otra dirección web.</translation>
@@ -1088,8 +1226,8 @@ Más información:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">¿Eliminar sugerencia de formulario de Chrome?</translation>
<translation id="7815407501681723534">Se han encontrado <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> de <ph name="SEARCH_STRING" /></translation>
-<translation id="7818867226424560206">Gestión de políticas</translation>
<translation id="782886543891417279">La red Wi-Fi que estás utilizando (<ph name="WIFI_NAME" />) puede requerir que accedas a su página de inicio de sesión.</translation>
+<translation id="7836231406687464395">Postfix (sobre)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ninguna}=1{1 aplicación (<ph name="EXAMPLE_APP_1" />)}=2{2 aplicaciones (<ph name="EXAMPLE_APP_1" /> y <ph name="EXAMPLE_APP_2" />)}other{# aplicaciones (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Ten en cuenta que tus acciones no serán totalmente invisibles. El uso del modo de incógnito no te permite ocultar tu actividad de navegación a tu empresa, a tu proveedor de servicios de Internet o a los sitios web que visites.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1236,7 @@ Más información:
<translation id="7878562273885520351">Es posible que tu contraseña se haya vulnerado</translation>
<translation id="7882421473871500483">Marrón</translation>
<translation id="7887683347370398519">Comprueba el código CVC y vuelve a intentarlo</translation>
-<translation id="7893255318348328562">Nombre de sesión</translation>
+<translation id="7904208859782148177">C3 (sobre)</translation>
<translation id="79338296614623784">Introduce un número de teléfono válido</translation>
<translation id="7935318582918952113">Extractor de DOM</translation>
<translation id="7937554595067888181">Fecha de caducidad: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1246,25 @@ Más información:
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Marcadores del móvil</translation>
<translation id="7961015016161918242">Nunca</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Sin especificar</translation>
<translation id="800218591365569300">Prueba a cerrar otros programas o pestañas para liberar memoria.</translation>
+<translation id="8004582292198964060">Navegador</translation>
<translation id="8009225694047762179">Administrar contraseñas</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Se guardará la tarjeta y su dirección de facturación. Podrás utilizarla cuando inicies sesión como <ph name="USER_EMAIL" />.}other{Se guardarán las tarjetas y sus direcciones de facturación. Podrás utilizarlas cuando inicies sesión como <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Esta página está escrita en <ph name="SOURCE_LANGUAGE" />. ¿Quieres traducirla al <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Bolígrafo</translation>
+<translation id="8037117624646282037">Quién ha usado este dispositivo recientemente</translation>
<translation id="8037357227543935929">Preguntar (predeterminado)</translation>
<translation id="803771048473350947">Archivo</translation>
<translation id="8041089156583427627">Enviar</translation>
<translation id="8041940743680923270">Utilizar valor predeterminado global (Preguntar)</translation>
<translation id="8042918947222776840">Seleccionar método de recogida</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" no se ha configurado correctamente. Normalmente, el problema se soluciona al desinstalar "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Tu dispositivo se ha configurado de la siguiente manera:</translation>
+<translation id="8066955247577885446">Se ha producido un error.</translation>
+<translation id="8074253406171541171">10x13 (sobre)</translation>
<translation id="8078141288243656252">No se pueden añadir anotaciones a los documentos girados</translation>
<translation id="8079031581361219619">¿Quieres volver a cargar el sitio web?</translation>
<translation id="8088680233425245692">Se ha producido un error al ver el artículo.</translation>
@@ -1131,11 +1273,12 @@ Más información:
<translation id="8091372947890762290">La activación está pendiente en el servidor.</translation>
<translation id="8092774999298748321">Morado intenso</translation>
<translation id="8094917007353911263">La red que estás utilizando puede requerir que accedas a la página <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Se han eliminado las tarjetas no válidas</translation>
<translation id="8103161714697287722">Método de pago</translation>
<translation id="8118489163946903409">Método de pago</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> administrado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" no se ha instalado correctamente en tu ordenador o red. Ponte en contacto con el administrador de TI para resolver el problema.</translation>
-<translation id="8130693978878176684">Ya no puedo ayudarte. Puedes continuar por tu cuenta.</translation>
<translation id="8131740175452115882">Confirmar</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>
@@ -1145,8 +1288,11 @@ Más información:
<translation id="8197543752516192074">Traducir página</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="8202370299023114387">Conflicto</translation>
+<translation id="8206978196348664717">Prc4 (sobre)</translation>
<translation id="8211406090763984747">La conexión es segura</translation>
<translation id="8218327578424803826">Ubicación asignada:</translation>
+<translation id="8220146938470311105">C7/C6 (sobre)</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="8238581221633243064">Abre una página en una nueva pestaña de incógnito</translation>
@@ -1158,14 +1304,16 @@ Más información:
<translation id="825929999321470778">Mostrar todas las contraseñas guardadas</translation>
<translation id="8261506727792406068">Eliminar</translation>
<translation id="8267698848189296333">Iniciando sesión como <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Este navegador lo administra <ph name="ENROLLMENT_DOMAIN" />. El administrador puede modificar la configuración del navegador de forma remota. Es posible que también se administre la actividad de este dispositivo fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Iniciar sesión</translation>
<translation id="8288807391153049143">Mostrar certificado</translation>
<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="8298115750975731693">La red Wi-Fi que estás utilizando (<ph name="WIFI_NAME" />) puede requerir que accedas a la página <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</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="8311129316111205805">Cargar sesión</translation>
<translation id="8332188693563227489">Se ha denegado el acceso a <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1331,6 @@ Más información:
<translation id="8416694386774425977">La configuración de red no es válida y no se ha podido importar.
Más información:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositivo gestionado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Cambiar</translation>
<translation id="8428213095426709021">Configuración</translation>
@@ -1210,9 +1357,11 @@ Más información:
<translation id="860043288473659153">Nombre del titular de la tarjeta</translation>
<translation id="861775596732816396">Tamaño 4</translation>
<translation id="8620436878122366504">Tus padres aún no lo han aprobado</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Guardar esta tarjeta en el dispositivo</translation>
<translation id="8663226718884576429">Resumen del pedido: <ph name="TOTAL_LABEL" /> (más detalles)</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, respuesta: <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Tu conexión a <ph name="DOMAIN" /> no está cifrada.</translation>
<translation id="8718314106902482036">El pago no se ha completado</translation>
<translation id="8719263113926255150">Sugerencia de búsqueda: <ph name="ENTITY" />, <ph name="DESCRIPTION" /></translation>
@@ -1226,6 +1375,7 @@ Más información:
<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="8763927697961133303">Dispositivo USB</translation>
<translation id="8768895707659403558">Para utilizar las tarjetas en todos tus dispositivos, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Rehacer eliminación</translation>
<translation id="8792621596287649091">Podrías perder el acceso a tu cuenta de <ph name="ORG_NAME" /> o tener problemas de suplantación de identidad. Chromium te recomienda que cambies tu contraseña ahora.</translation>
<translation id="8800988563907321413">Las sugerencias de la sección Cercanas aparecen aquí</translation>
@@ -1236,10 +1386,12 @@ Más información:
<translation id="885730110891505394">Compartir con Google</translation>
<translation id="8858065207712248076">Chrome te recomienda que cambies tu contraseña de <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> si la has vuelto a utilizar en otros sitios web.</translation>
<translation id="8866481888320382733">Error al analizar la configuración de la política</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Cerrado recientemente</translation>
<translation id="8874824191258364635">Introduce un número de tarjeta válido</translation>
<translation id="8891727572606052622">El modo de proxy no es válido.</translation>
<translation id="8903921497873541725">Acercar</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">¿Quieres guardar esta tarjeta en tu cuenta de Google?</translation>
<translation id="8932102934695377596">Tu reloj está atrasado</translation>
<translation id="893332455753468063">Añade un nombre</translation>
@@ -1247,13 +1399,13 @@ Más información:
<translation id="894185898663964645">Tu administrador ha configurado certificados raíz personalizados que permiten al administrador ver el contenido de los sitios web que visites.</translation>
<translation id="8943282376843390568">Lima</translation>
<translation id="8957210676456822347">Autorización de portal cautivo</translation>
+<translation id="8966619695390250636">Quizás quisiste decir:</translation>
<translation id="8968766641738584599">Guardar tarjeta</translation>
<translation id="8971063699422889582">El certificado del servidor ha caducado.</translation>
<translation id="8975012916872825179">Incluye información como números de teléfono, direcciones de correo electrónico y direcciones de envío</translation>
<translation id="8978053250194585037">La función Navegación Segura de Google <ph name="BEGIN_LINK" />ha detectado phishing<ph name="END_LINK" /> en <ph name="SITE" />. Los sitios web de phishing suplantan la identidad de otros sitios web para engañarte.</translation>
<translation id="8983003182662520383">Métodos de pago y direcciones con Google Pay</translation>
<translation id="8987927404178983737">Mes</translation>
-<translation id="8988408250700415532">Se ha producido un error. Puedes finalizar el pedido en el sitio web.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">El sitio web 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>
@@ -1263,6 +1415,7 @@ Más información:
<translation id="9011424611726486705">Abrir ajustes de sitios web</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(no válido)</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>
@@ -1274,11 +1427,11 @@ Más información:
<translation id="9065745800631924235">Búsqueda de <ph name="TEXT" /> en el historial</translation>
<translation id="9069693763241529744">Bloqueado por una extensión</translation>
<translation id="9076283476770535406">Es posible que incluya contenido para adultos</translation>
+<translation id="9076630408993835509">Este navegador no lo administra ninguna empresa ni organización. Es posible que se administre la actividad de este dispositivo fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Se necesita más información</translation>
<translation id="9080712759204168376">Resumen del pedido</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>
<translation id="9106062320799175032">Añade una dirección de facturación</translation>
-<translation id="9110718169272311511">En Chrome, el Asistente de Google está disponible en la parte inferior de la pantalla</translation>
<translation id="9114524666733003316">Confirmando tarjeta...</translation>
<translation id="9128870381267983090">Conectarse a la red</translation>
<translation id="9137013805542155359">Mostrar original</translation>
@@ -1287,6 +1440,7 @@ Más información:
<translation id="9148507642005240123">&amp;Deshacer edición</translation>
<translation id="9154194610265714752">Actualizado</translation>
<translation id="9157595877708044936">Configurando...</translation>
+<translation id="9158625974267017556">C6 (sobre)</translation>
<translation id="9168814207360376865">Permitir a los sitios web saber si tienes métodos de pago guardados</translation>
<translation id="9169664750068251925">Bloquear siempre en este sitio</translation>
<translation id="9170848237812810038">&amp;Deshacer</translation>
@@ -1301,10 +1455,12 @@ Más información:
<translation id="9219103736887031265">Imágenes</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">BORRAR FORMULARIO</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Podrías perder el acceso a tu cuenta de Google. Chromium te recomienda que cambies la contraseña ahora. Se te pedirá que inicies sesión.</translation>
<translation id="939736085109172342">Nueva carpeta</translation>
<translation id="945855313015696284">Comprueba la información que aparece a continuación y elimina las tarjetas no válidas</translation>
<translation id="951104842009476243">Tarjetas prepago y de débito aceptadas</translation>
+<translation id="958202389743790697">Se ha bloqueado según la política de seguridad de <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Este contenido podría intentar 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_LINK" />Mostrar de todos modos<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Build oficial</translation>
<translation id="973773823069644502">Añadir dirección de entrega</translation>
@@ -1313,6 +1469,7 @@ Más información:
<translation id="984275831282074731">Métodos de pago</translation>
<translation id="985199708454569384">&lt;p&gt;Este error se muestra si la fecha y la hora de tu ordenador o tu dispositivo móvil no son correctas.&lt;/p&gt;
&lt;p&gt;Para solucionar el problema, abre el reloj de tu dispositivo. Comprueba que la fecha y la hora sean correctas.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Build para desarrolladores</translation>
<translation id="989988560359834682">Editar dirección</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_et.xtb b/chromium/components/strings/components_strings_et.xtb
index e2bdcc4b774..94bf29a5124 100644
--- a/chromium/components/strings/components_strings_et.xtb
+++ b/chromium/components/strings/components_strings_et.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="et">
-<translation id="1005145902654145231">Seansi ümbernimetamine ebaõnnestus.</translation>
<translation id="1008557486741366299">Mitte praegu</translation>
<translation id="1010200102790553230">Laadi leht hiljem</translation>
<translation id="1015730422737071372">Esitage lisateavet</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">tundmatu nimi</translation>
<translation id="1050038467049342496">Sulgege muud rakendused</translation>
<translation id="1055184225775184556">&amp;Võta lisamine tagasi</translation>
+<translation id="1056898198331236512">Hoiatus</translation>
<translation id="1058479211578257048">Kaartide salvestamine …</translation>
<translation id="10614374240317010">Ei ole kunagi salvestatud</translation>
+<translation id="1062160989074299343">Prc10 (ümbrik)</translation>
<translation id="106701514854093668">Töölaua järjehoidjad</translation>
<translation id="1074497978438210769">Pole turvaline</translation>
<translation id="1080116354587839789">Sobita laiusesse</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Kaardil oleva nime lisamine</translation>
<translation id="1089439967362294234">Parooli muutmine</translation>
<translation id="109743633954054152">Hallake paroole Chrome'i seadetes</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Sel ajal kui veebisaidid värskendavad turvafunktsioone, võite sageli hoiatusi näha. See olukord peaks varsti lahenema.</translation>
<translation id="1126551341858583091">Kohaliku salvestusruumi maht on <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Reegli vahemälu töötab probleemideta</translation>
+<translation id="1131264053432022307">Teie kopeeritud pilt</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Muuda nime</translation>
<translation id="1175364870820465910">&amp;Prindi...</translation>
<translation id="1181037720776840403">Eemalda</translation>
<translation id="1197088940767939838">Oranž</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Teie seadme nimi</translation>
<translation id="124116460088058876">Rohkem keeli</translation>
<translation id="1250759482327835220">Kui soovite järgmisel korral kiiremini maksta, salvestage kaart, nimi ja arveldusaadress oma Google'i kontole.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sünkroonitud)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Käsurea variatsioonid</translation>
<translation id="129553762522093515">Viimati suletud</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Kustutage küpsisefailid<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Valitud seanssi ei ole olemas.</translation>
+<translation id="1320233736580025032">Prc1 (ümbrik)</translation>
+<translation id="132301787627749051">Lõikelaua kujutise otsimine</translation>
<translation id="1323433172918577554">Kuva rohkem</translation>
<translation id="132390688737681464">Salvesta ja sisesta aadressid</translation>
<translation id="1333989956347591814">Teie tegevused <ph name="BEGIN_EMPHASIS" />võivad siiski olla nähtavad<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Kättesaamise aadress</translation>
<translation id="1348198688976932919">Sait, mille soovite avada, sisaldab ohtlikke rakendusi</translation>
<translation id="1348779747280417563">Kinnitage nimi</translation>
+<translation id="1357195169723583938">Näitab seadme hiljutisi kasutajaid ja kasutamise aega</translation>
+<translation id="1364822246244961190">See reegel on blokeeritud, selle väärtust eiratakse.</translation>
<translation id="1374468813861204354">soovitused</translation>
+<translation id="1374692235857187091">Index-4x6 (postkaart)</translation>
<translation id="1375198122581997741">Teave versiooni kohta</translation>
<translation id="1376836354785490390">Kuva vähem</translation>
<translation id="1377321085342047638">Kaardinr</translation>
<translation id="138218114945450791">Helesinine</translation>
+<translation id="1382194467192730611">Teie administraator lubas selle USB-seadme</translation>
<translation id="139305205187523129">Host <ph name="HOST_NAME" /> ei saatnud andmeid.</translation>
+<translation id="140316286225361634">Sait <ph name="ORIGIN" /> taotles, et turvalisuse reeglit
+ kohaldatakse igale sisenemistaotlusele, ja see reegel peab seda saiti praegu
+ ebaturvaliseks.</translation>
<translation id="1405567553485452995">Heleroheline</translation>
<translation id="1407135791313364759">Ava kõik</translation>
<translation id="1413809658975081374">Privaatsuse viga</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Jah</translation>
<translation id="1430915738399379752">Printimine</translation>
<translation id="1455413310270022028">Kustutuskumm</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Kuva rohkem</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Valige tarneaadress</translation>
+<translation id="1492194039220927094">Reeglite saatmine:</translation>
<translation id="1501859676467574491">Kuva kaardid minu Google'i kontolt</translation>
-<translation id="1506687042165942984">Lehe salvestatud (s.t teadaolevalt aegunud) koopia kuvamine.</translation>
<translation id="1507202001669085618">&lt;p&gt;Seda viga näete juhul, kui kasutate WiFi-portaali, kuhu tuleb enne võrguühenduse loomist sisse logida.&lt;/p&gt;
&lt;p&gt;Vea parandamiseks klõpsake avataval lehel käsul &lt;strong&gt;Loo ühendus&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefoninumber on nõutav</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Järgu kuupäev</translation>
<translation id="1521655867290435174">Google'i arvutustabelid</translation>
<translation id="1527263332363067270">Ühenduse ootamine …</translation>
+<translation id="1529521330346880926">10x15 (ümbrik)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Leht ütleb</translation>
<translation id="153384715582417236">See on praeguseks kõik</translation>
<translation id="154408704832528245">Valige kohaletoimetamisaadress</translation>
<translation id="1549470594296187301">Selle funktsiooni kasutamiseks peab JavaScript olema lubatud.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Sisestage aegumiskuupäev</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Kopeeritud pilt</translation>
<translation id="1620510694547887537">Kaamera</translation>
<translation id="1623104350909869708">Keela sellel lehel lisadialoogide loomine</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Lõpeta seanss</translation>
<translation id="1639239467298939599">Laadimine</translation>
<translation id="1640180200866533862">Kasutajareeglid</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Serveri sertifikaat sisaldab nõrka krüptograafilist võtit.</translation>
<translation id="1697532407822776718">Kõik on valmis!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument on märkuste lisamiseks liiga suur</translation>
<translation id="1721312023322545264">Vajate saidi külastamiseks halduri <ph name="NAME" /> luba</translation>
<translation id="1721424275792716183">* Kohustuslik väli</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Proovige ühendust võtta süsteemiadministraatoriga.</translation>
<translation id="1740951997222943430">Sisestage kehtiv aegumiskuu</translation>
<translation id="1743520634839655729">Kui soovite järgmisel korral kiiremini maksta, salvestage kaart, nimi ja arveldusaadress oma Google'i kontole ja sellesse seadmesse.</translation>
+<translation id="1745880797583122200">Teie brauserit hallatakse</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Värskendage sünkroonimise parooli.</translation>
<translation id="1787142507584202372">Teie avatud vahelehed kuvatakse siin</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kaardiomaniku nimi</translation>
<translation id="1821930232296380041">Taotlus või selle parameetrid on kehtetud</translation>
+<translation id="1822540298136254167">Teie külastatavad veebisaidid ja nendel veedetav aeg</translation>
<translation id="1826516787628120939">Kontrollimine</translation>
<translation id="1834321415901700177">See sait sisaldab kahjulikke programme</translation>
<translation id="1839551713262164453">Reegli väärtuste valideerimine nurjus ja selle käigus ilmnesid vead</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Kustuta Chrome'i sirvimisajaloo andmed</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ja veel 1}other{ja veel #}}</translation>
<translation id="2003709556000175978">Lähtestage oma parool kohe</translation>
+<translation id="20053308747750172">Server, kuhu sisenete, <ph name="ORIGIN" />, taotleb, et
+ turvalisuse reeglit kohaldatakse igale sisenemistaotlusele. See on aga
+ edastanud sobimatu reegli, mis takistab brauseril
+ täitmast teie sisenemistaotlust saidile <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Puhverserver seadistatakse automaatselt.</translation>
<translation id="2030481566774242610">Kas mõtlesite aadressi <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Kontrollige puhverserverit ja tulemüüri<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Osakond</translation>
<translation id="2102134110707549001">Soovita tugevat parooli …</translation>
<translation id="2108755909498034140">Taaskäivitage oma arvuti</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kaart</translation>
<translation id="2114841414352855701">Seda ignoreeritakse, kuna reegel <ph name="POLICY_NAME" /> alistab selle.</translation>
<translation id="213826338245044447">Mobiili järjehoidjad</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (ümbrik)</translation>
<translation id="2181821976797666341">Reeglid</translation>
<translation id="2183608646556468874">Telefoninumber</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 aadress}other{# aadressi}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefoninumber</translation>
<translation id="2283340219607151381">Salvesta ja sisesta aadressid</translation>
<translation id="2292556288342944218">Teie juurdepääs Internetile on blokeeritud</translation>
+<translation id="2294558542833290837">Link, mille algselt avasite, on ebatavaline</translation>
+<translation id="2297722699537546652">B5 (ümbrik)</translation>
+<translation id="2310021320168182093">Chou2 (ümbrik)</translation>
<translation id="2316887270356262533">Vabastab alla 1 MB. Mõne saidi laadimine võib järgmisel külastusel rohkem aega võtta.</translation>
<translation id="2317259163369394535">Domeen <ph name="DOMAIN" /> nõuab kasutajanime ja parooli.</translation>
<translation id="2317583587496011522">Kaupmees aktsepteerib deebetkaarte.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, aegub <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Seadet juhib administraator</translation>
+<translation id="2346319942568447007">Teie kopeeritud pilt</translation>
<translation id="2349790679044093737">VR-seanss on aktiivne</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> talletatud krahhiaruannet ei laaditud üles</translation>
<translation id="2367567093518048410">Tase</translation>
<translation id="2378238891085281592">Olete privaatses režiimis</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Server, kuhu sisenete, <ph name="ORIGIN" />, taotleb, et
+ turvalisuse reeglit kohaldatakse igale sisenemistaotlusele. Reegli saatmine aga
+ ebaõnnestus, mis takistab brauseril täitmast
+ teie sisenemistaotlust saidile <ph name="SITE" />.</translation>
<translation id="244665789865330679">Teie seadet ja kontot hallatakse domeenilt <ph name="ENROLLMENT_DOMAIN" />. See tähendab, et administraator saab teie seadet ja kontot kaugühenduse teel seadistada.</translation>
<translation id="2463193859425327265">Muuda avalehte</translation>
<translation id="2463739503403862330">Täida</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Valige kohaletoimetamisviis</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Võrgudiagnostika käitamine<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Selle lehe tõlkimine</translation>
<translation id="2479410451996844060">Kehtetu otsingu URL.</translation>
<translation id="2482878487686419369">Märguanded</translation>
<translation id="248348093745724435">Seadme reeglid</translation>
+<translation id="2485387744899240041">Teie seadme ja brauseri kasutajanimed</translation>
<translation id="2491120439723279231">Serveri sertifikaat sisaldab vigu.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Uue kaardi skannimine</translation>
<translation id="2501278716633472235">Mine tagasi</translation>
<translation id="2503184589641749290">Aktsepteeritavad ettemakstud ja deebetkaardid</translation>
<translation id="2515629240566999685">Kontrollige oma piirkonna signaali</translation>
-<translation id="2516852381693169964">Pildi otsimine otsingumootoriga <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Salvestatakse ainult sellesse seadmesse</translation>
<translation id="2524461107774643265">Lisateabe lisamine</translation>
<translation id="2536110899380797252">Lisa aadress</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Kataloogi API ID:</translation>
<translation id="2597378329261239068">Dokument on parooliga kaitstud. Sisestage parool.</translation>
<translation id="2609632851001447353">Variatsioonid</translation>
+<translation id="2618023639789766142">C10 (ümbrik)</translation>
<translation id="2625385379895617796">Teie kell on ees</translation>
<translation id="2634124572758952069">Hosti <ph name="HOST_NAME" /> serveri IP-aadressi ei leitud.</translation>
<translation id="2639739919103226564">Olek:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Sulgege muud vahelehed või rakendused</translation>
<translation id="267371737713284912">tagasivõtmiseks vajutage klahvi <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Olete kindel, et soovite need leheküljed oma ajaloost kustutada?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Lahku</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Aktsepteeritavad kaardid</translation>
<translation id="2702801445560668637">Lugemisloend</translation>
<translation id="2704283930420550640">Väärtus ei vasta vormingule.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Eemalda valitud üksused</translation>
<translation id="277133753123645258">Tarneviis</translation>
<translation id="277499241957683684">Seadme kirje puudub</translation>
-<translation id="2781030394888168909">Ekspordi MacOS-i jaoks</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Ühendus lähtestati.</translation>
<translation id="2788784517760473862">Aktsepteeritavad krediitkaardid</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Ava inkognito aken</translation>
+<translation id="2850739647070081192">Invite (ümbrik)</translation>
<translation id="2851634818064021665">Vajate selle saidi külastamiseks luba</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Kas salvestada kaart?</translation>
<translation id="2903493209154104877">Aadressid</translation>
<translation id="290376772003165898">Kas leht ei ole <ph name="LANGUAGE" /> keeles?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Kohaletoimetamisviis</translation>
<translation id="2928905813689894207">Arveldusaadress</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (ümbrik)</translation>
<translation id="3024663005179499861">Reegli tüüp on vale</translation>
<translation id="3037605927509011580">Ups, ebaõnn!</translation>
<translation id="3041612393474885105">Sertifikaadi andmed</translation>
+<translation id="3060227939791841287">C9 (ümbrik)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Lisage kättesaamisaadress</translation>
<translation id="3105172416063519923">Vara ID:</translation>
<translation id="3109728660330352905">Teil pole volitust selle lehe vaatamiseks.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956">Printer <ph name="PRINTER_NAME" /> serveris <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Tühista makse</translation>
<translation id="3207960819495026254">Järjehoidjatesse lisatud</translation>
-<translation id="3209375525920864198">Sisestage sobiv seansi nimi.</translation>
+<translation id="321912867715453276">Hoiatus. Reeglil on rohkem kui üks allikas, aga väärtused on kõik samad.</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="3229041911291329567">Teie seadme ja brauseri versiooniteave</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Kaardil oleva nime lisamine</translation>
<translation id="3287510313208355388">Laadi alla, kui ühendus on saadaval</translation>
<translation id="3293642807462928945">Lisateave reegli <ph name="POLICY_NAME" /> kohta</translation>
<translation id="3303855915957856445">Otsingutulemusi ei leitud</translation>
-<translation id="3305707030755673451">Teie andmed krüpteeriti <ph name="TIME" /> teie sünkroonimisparooliga. Sisestage see sünkroonimise alustamiseks.</translation>
<translation id="3320021301628644560">Arveldusaadressi lisamine</translation>
<translation id="3324983252691184275">Tulipunane</translation>
<translation id="3338095232262050444">Turvaline</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Muuda uuesti</translation>
<translation id="342781501876943858">Chromium soovitab teil parooli lähtestada, kui kasutasite seda ka muudel saitidel.</translation>
<translation id="3431636764301398940">Salvesta kaart sellesse seadmesse</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Seadme omanik lülitas dinosaurusemängu välja.</translation>
<translation id="3447884698081792621">Kuva sertifikaat (väljastas <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Hankimise intervall:</translation>
+<translation id="3456231139987291353">Number-11 (ümbrik)</translation>
<translation id="3461824795358126837">Esiletõstja</translation>
<translation id="3462200631372590220">Peida täpsemad üksikasjad</translation>
<translation id="3467763166455606212">Kaardiomaniku nimi on kohustuslik</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kaupmees aktsepteerib ettemakstud ja krediitkaarte.</translation>
<translation id="3582930987043644930">Lisage nimi</translation>
<translation id="3583757800736429874">&amp;Teisalda uuesti</translation>
+<translation id="35866233670761917">Administraatorid ei näe teie külastatud veebisaitide sisu.</translation>
<translation id="3586931643579894722">Peida üksikasjad</translation>
+<translation id="3592413004129370115">Italian (ümbrik)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Suurus 2</translation>
<translation id="3615877443314183785">Sisestage kehtiv aegumiskuupäev</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
see loendist eemaldada ja siis uuesti lisada.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Valideerimine õnnestus</translation>
<translation id="3655670868607891010">Kui näete seda sageli, proovige järgmist: <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Redaktsioon</translation>
<translation id="366077651725703012">Värskenda krediitkaarti</translation>
<translation id="3676592649209844519">Seadme ID:</translation>
+<translation id="3677008721441257057">Kas mõtlesite domeeni &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Taotlust ei saanud allkirjastada</translation>
<translation id="3678529606614285348">Avage leht uues inkognito aknas (Ctrl + tõstuklahv + N)</translation>
<translation id="3679803492151881375">Krahhiaruanne jäädvustati ajal <ph name="CRASH_TIME" />, see laaditi üles ajal <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Võrk, mida kasutate, võib nõuda sisselogimislehe külastamist.</translation>
<translation id="3704609568417268905"><ph name="TIME" />, <ph name="BOOKMARKED" />, <ph name="TITLE" />, <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Laadimine...</translation>
+<translation id="3709599264800900598">Teie kopeeritud tekst</translation>
<translation id="3712624925041724820">Litsentsid on ammendunud</translation>
<translation id="3714780639079136834">Lülitage sisse mobiilne andmeside või WiFi</translation>
<translation id="3715597595485130451">Ühenduse loomine WiFi-võrguga</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Kontrollige puhverserveri, tulemüüri ja DNS-i seadistust<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Selle vea võib põhjustada näiteks viirusetõrjetarkvara, tulemüür või veebi filtreerimise või puhverserveritarkvara.</translation>
+<translation id="373042150751172459">B4 (ümbrik)</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="3745099705178523657">Pärast kinnitamist jagatakse teie Google'i kontol olevaid kaardi üksikasju selle saidiga.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Aegub: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Suurus 16</translation>
+<translation id="3797522431967816232">Prc3 (ümbrik)</translation>
<translation id="3807873520724684969">Kahjulik sisu on blokeeritud.</translation>
<translation id="3810973564298564668">Halda</translation>
<translation id="382518646247711829">Kui kasutate puhverserverit ...</translation>
<translation id="3828924085048779000">Tühi parool ei ole lubatud.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> on installinud laiendused, et pakkuda lisafunktsioone. Laiendustel on juurdepääs teie mõningatele andmetele.</translation>
<translation id="385051799172605136">Tagasi</translation>
<translation id="3858027520442213535">Värskenda kuupäeva ja kellaaega</translation>
<translation id="3884278016824448484">Seadme identifikaator on konfliktne</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Küsi sellel saidil alati</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Seansi nimi on juba olemas.</translation>
<translation id="3987940399970879459">Alla 1 MB</translation>
+<translation id="4008849406247176967">Hoiatus. Selle reegli puhul on leitud rohkem kui üks vastuoluliste väärtustega allikas.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Läheduses on 1 veebileht}other{Läheduses on # veebilehte}}</translation>
<translation id="4030383055268325496">&amp;Võta lisamine tagasi</translation>
+<translation id="4032320456957708163">Teie brauserit haldab <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Võti „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (ümbrik)</translation>
<translation id="4067947977115446013">Sobiva aadressi lisamine</translation>
<translation id="4072486802667267160">Teie tellimuse töötlemisel ilmnes viga. Proovige uuesti.</translation>
<translation id="4075732493274867456">Klient ja server ei toeta tavapärast SSL-protokolli versiooni ega šifreerimiskomplekti.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Lilla</translation>
<translation id="4165986682804962316">Saidi seaded</translation>
<translation id="4171400957073367226">Sobimatu kinnitusallkiri</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Veel <ph name="ITEM_COUNT" /> üksus}other{Veel <ph name="ITEM_COUNT" /> üksust}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (ümbrik)</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="4221630205957821124">&lt;h4&gt;1. toiming: logige portaali sisse&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Lähtesta parool</translation>
<translation id="4280429058323657511">, aegub <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{See kaart salvestati teie Google'i kontole}other{Need kaardid salvestati teie Google'i kontole}}</translation>
+<translation id="42981349822642051">Laienda</translation>
+<translation id="4302965934281694568">Chou3 (ümbrik)</translation>
<translation id="4305817255990598646">Lüliti</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokeeri (vaikimisi)</translation>
+<translation id="4318566738941496689">Teie seadme nimi ja võrguaadress</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="4340982228985273705">Tuvastati, et tegemist ei ole ettevõtte hallatava arvutiga, seega saab reegel installida ainult Chrome'i veebipoes hostitavaid laiendusi. Chrome'i veebipoe värskenduse URL on „<ph name="CWS_UPDATE_URL" />”.</translation>
<translation id="4346197816712207223">Aktsepteeritavad krediitkaardid</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Halda makseviise …</translation>
+<translation id="4367563149485757821">Number-12 (ümbrik)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">otsingutulemused</translation>
-<translation id="4406972042435603828">Teie administraatorid on installinud võimekad laiendused.</translation>
<translation id="4408413947728134509">Küpsisefailid: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Kättesaamisaadress</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="443121186588148776">Jadaport</translation>
<translation id="4432688616882109544">Host <ph name="HOST_NAME" /> ei aktsepteerinud teie sisselogimise sertifikaati või te ei esitanud seda.</translation>
<translation id="4434045419905280838">Hüpikaknad ja ümbersuunamised</translation>
+<translation id="4435702339979719576">Postkaart)</translation>
<translation id="443673843213245140">Puhverserveri kasutamine on keelatud, kuid määratud on ka konkreetne puhverserveri konfigureerimine.</translation>
<translation id="445100540951337728">Aktsepteeritavad deebetkaardid</translation>
+<translation id="4466881336512663640">Vormil tehtud muudatused lähevad kaotsi. Kas soovite kindlasti jätkata?</translation>
<translation id="4482953324121162758">Seda saiti ei tõlgita.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Sobimatu URL. Peab olema standardskeemiga URL, nt http://example.com või https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (ümbrik)</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="4517607026994743406">Comm-10 (ümbrik)</translation>
<translation id="4522570452068850558">Üksikasjad</translation>
<translation id="4524805452350978254">Halda kaarte</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Keelake laiendused.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Kohaletoimetamine</translation>
+<translation id="4579056131138995126">Personal (ümbrik)</translation>
<translation id="4582204425268416675">Kaardi eemaldamine</translation>
<translation id="4587425331216688090">Kas eemaldada Chrome'ist aadress?</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="4597348597567598915">Suurus 8</translation>
+<translation id="4600854749408232102">C6/C5 (ümbrik)</translation>
<translation id="4646534391647090355">Vii mind kohe sinna</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Lõpeta kehtetu sertifikaadi kasutamine</translation>
+<translation id="4691835149146451662">Architecture-A (ümbrik)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Teie ühendus katkes</translation>
<translation id="471880041731876836">Teil ei ole selle saidi külastamiseks luba</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windowsi võrgudiagnostika käitamine<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Laadi reeglid uuesti</translation>
<translation id="4728558894243024398">Platvorm</translation>
+<translation id="4731967714531604179">Prc2 (ümbrik)</translation>
<translation id="4736825316280949806">Taaskäivitage Chromium</translation>
<translation id="473775607612524610">Värskenda</translation>
<translation id="4738601419177586157">Otsingusoovitus: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Halda paroole …</translation>
<translation id="4744603770635761495">Täitmistee</translation>
+<translation id="4746351372139058112">Sõnumid</translation>
<translation id="4750917950439032686">Teie teave (nt paroolid või krediitkaardi numbrid) on sellele saidile saates privaatne.</translation>
<translation id="4756388243121344051">&amp;Ajalugu</translation>
<translation id="4758311279753947758">Lisage kontaktteave</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Veebileht aadressil <ph name="URL" /> võib olla ajutiselt maas või jäädavalt uuele veebiaadressile teisaldatud.</translation>
<translation id="4771973620359291008">Tekkis tundmatu viga.</translation>
<translation id="4785689107224900852">Lülitage sellele vahelehele</translation>
-<translation id="4792143361752574037">Seansi failidele juurdepääsemisel ilmnes probleem. Kettale salvestamine on praegu keelatud. Veel kord proovimiseks laadige leht uuesti.</translation>
<translation id="4798078619018708837">Kaardi üksikasjade värskendamiseks sisestage krediitkaardi <ph name="CREDIT_CARD" /> aegumiskuupäev ja CVC. Kui selle kinnitate, jagatakse teie Google'i kontol oleva kaardi üksikasju selle saidiga.</translation>
<translation id="4800132727771399293">Kontrollige aegumiskuupäeva ja CVC-d ning proovige uuesti</translation>
+<translation id="480334179571489655">Algse reegli viga</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Ava</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Tulemusi pole</translation>
<translation id="4950898438188848926">Vahelehe vahetamise nupp, vajutage sisestusklahvi avatud vahelehe aktiveerimiseks, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Toimingud</translation>
-<translation id="495832697253704892">Laienduste aruandlus</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Laienda loendit</translation>
<translation id="4974590756084640048">Luba hoiatused uuesti</translation>
+<translation id="4984339528288761049">Prc5 (ümbrik)</translation>
<translation id="4989163558385430922">Kuva kõik</translation>
<translation id="4989809363548539747">Seda pistikprogrammi ei toetata</translation>
-<translation id="4996230189582812866">Aruandlus</translation>
<translation id="5002932099480077015">Kui see on lubatud, salvestab Chrome teie kaardi koopia vormide kiiremini täitmiseks sellesse seadmesse.</translation>
-<translation id="5014174725590676422">Näidatud on Google'i assistendi esmakordse käivitamise kuva Chrome'is</translation>
<translation id="5015510746216210676">Seadme nimi:</translation>
+<translation id="5017554619425969104">Teie kopeeritud tekst</translation>
<translation id="5018422839182700155">Seda lehte ei saa avada</translation>
<translation id="5019198164206649151">Varusalves esineb probleeme</translation>
<translation id="5023310440958281426">Tutvuge administraatori reeglitega</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Kohalik kontekst (<ph name="CRASH_LOCAL_ID" />)</translation>
<translation id="5039804452771397117">Luba</translation>
<translation id="5040262127954254034">Privaatsus</translation>
+<translation id="5043480802608081735">Teie kopeeritud link</translation>
<translation id="5045550434625856497">Vale salasõna</translation>
<translation id="5056549851600133418">Teile soovitatud artiklid</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kontrollige puhverserveri aadressi<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Serveri sertifikaat pole praegu kehtiv.</translation>
<translation id="5087580092889165836">Lisa kaart</translation>
<translation id="5089810972385038852">Osariik/Maakond</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="5097099694988056070">Seadme statistika, näiteks protsessori/muutmälu kasutus</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Teie seadet hallatakse domeenilt <ph name="ENROLLMENT_DOMAIN" /> ja kontot domeenilt <ph name="ACCOUNT_DOMAIN" />. See tähendab, et administraatorid saavad teie seadet ja kontot kaugühenduse teel seadistada.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bitine)</translation>
-<translation id="5128122789703661928">Selle nimega seanssi ei saa kustutada.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Halda aadresse …</translation>
+<translation id="5138227688689900538">Kuva vähem</translation>
<translation id="5141240743006678641">Krüpteerige sünkroonitud paroolid oma Google'i mandaadiga</translation>
<translation id="5145883236150621069">Reegli vastuses sisaldus veakood</translation>
+<translation id="515292512908731282">C4 (ümbrik)</translation>
<translation id="5159010409087891077">Avage leht uues inkognito aknas (⇧ ⌘ N)</translation>
<translation id="516920405563544094">Sisestage krediitkaardi <ph name="CREDIT_CARD" /> CVC. Pärast kinnitamist jagatakse teie Google'i kontol oleva kaardi üksikasju selle saidiga.</translation>
<translation id="5169827969064885044">Võite kaotada juurdepääsu oma organisatsiooni kontole või teie identiteet võidakse varastada. Chrome soovitab teil kohe oma parooli muuta.</translation>
<translation id="5171045022955879922">Otsige või sisestage URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Masin</translation>
<translation id="5179510805599951267">Tegu ei ole <ph name="ORIGINAL_LANGUAGE" /> keelega? Andke veast teada</translation>
<translation id="5190835502935405962">Järjehoidjariba</translation>
-<translation id="5200263511887412697">Edastab loendi seadme kasutajatest, kes on hiljuti sisse loginud.</translation>
+<translation id="519422657042045905">Märkuste lisamise funktsioon ei ole saadaval</translation>
<translation id="5201306358585911203">Selle lehe manustatud leht ütleb</translation>
<translation id="5205222826937269299">Nimi on nõutav</translation>
<translation id="5215116848420601511">Makseviisid ja aadressid, mis kasutavad teenust Google Pay.</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-posti aadress on nõutav</translation>
<translation id="5230733896359313003">Tarneaadress</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Looge võrguühendus”</translation>
<translation id="5251803541071282808">Pilv</translation>
+<translation id="5252000469029418751">C7 (ümbrik)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Võrguaadressid</translation>
<translation id="5285570108065881030">Kuva kõik salvestatud paroolid</translation>
<translation id="5287240709317226393">Kuva küpsised</translation>
<translation id="5288108484102287882">Reegli väärtuste valideerimisel ilmnesid hoiatused</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" />/<ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Valige kontaktteave</translation>
<translation id="5327248766486351172">Nimi</translation>
+<translation id="5329858041417644019">Teie brauserit ei hallata</translation>
<translation id="5332219387342487447">Tarneviis</translation>
+<translation id="5334013548165032829">Üksikasjalikud süsteemilogid</translation>
<translation id="5344579389779391559">Leht võib üritada teilt tasu võtta</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">„Teie kell on ajast maas” või „Teie kell on ajast ees” või „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">Kõigis seadmetes kaartide kasutamiseks logige sisse ja lülitage sünkroonimine sisse.</translation>
<translation id="5386426401304769735">Selle saidi sertifikaadiahel sisaldab sertifikaati, mis on allkirjastatud SHA-1-ga.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Kehtetu</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Muuda uuesti</translation>
+<translation id="5478437291406423475">B6/C4 (ümbrik)</translation>
<translation id="5481076368049295676">See sisu võib üritada installida teie seadmesse ohtlikku tarkvara, mis varastab või kustutab teie teavet. <ph name="BEGIN_LINK" />Kuva ikkagi<ph name="END_LINK" />.</translation>
<translation id="54817484435770891">Sisestage sobiv aadress</translation>
<translation id="5490432419156082418">Aadressid ja muu</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Võtke ühendust süsteemiadministraatoriga.</translation>
<translation id="549333378215107354">Suurus 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Hallatud järjehoidjad</translation>
<translation id="5510766032865166053">See võidi teisaldada või kustutada.</translation>
<translation id="5523118979700054094">Reegli nimi</translation>
<translation id="552553974213252141">Kas tekst ekstraktiti õigesti?</translation>
+<translation id="553484882784876924">Prc6 (ümbrik)</translation>
<translation id="5540224163453853">Taotletud artiklit ei õnnestunud leida.</translation>
<translation id="5541546772353173584">E-posti aadressi lisamine</translation>
<translation id="5545756402275714221">Teile soovitatud artiklid</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Muuda aadressi</translation>
<translation id="5598944008576757369">Valige makseviis</translation>
<translation id="560412284261940334">Haldust ei toetata</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Host <ph name="HOST_NAME" /> suunas teid liiga mitu korda ümber.</translation>
<translation id="5629630648637658800">Reegli seadete laadimine ebaõnnestus</translation>
<translation id="5631439013527180824">Seadme halduse luba on kehtetu</translation>
+<translation id="5632627355679805402">Teie andmed krüpteeriti viimati teie <ph name="BEGIN_LINK" />Google’i parooliga<ph name="END_LINK" /> kuupäeva <ph name="TIME" /> seisuga. Sisestage see sünkroonimise alustamiseks.</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="563324245173044180">Petlik sisu blokeeriti.</translation>
<translation id="5659593005791499971">Meil</translation>
+<translation id="5663614846592581799">9x11 (ümbrik)</translation>
+<translation id="5663955426505430495">Seadme administraator on installinud laiendused, mis hõlmavad lisafunktsioone. Laiendustel on juurdepääs teie mõningatele andmetele.</translation>
<translation id="5675650730144413517">See leht ei tööta</translation>
+<translation id="5684874026226664614">Vabandust. Lehte ei õnnestunud tõlkida.</translation>
<translation id="5685654322157854305">Lisage tarneaadress</translation>
<translation id="5689199277474810259">Ekspordi JSON-vormingus</translation>
<translation id="5689516760719285838">Asukoht</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Selle veebisaidi identiteeti pole kinnitanud.</translation>
<translation id="5719499550583120431">Kaupmees aktsepteerib ettemakstud kaarte.</translation>
<translation id="5720705177508910913">Praegune kasutaja</translation>
+<translation id="5728056243719941842">C5 (ümbrik)</translation>
<translation id="5730040223043577876">Chrome soovitab teil parooli lähtestada, kui kasutasite seda ka muudel saitidel.</translation>
<translation id="5732392974455271431">Vanemad saavad blokeeringu teie eest tühistada</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Salvestage kaart oma Google'i kontole}other{Salvestage kaardid oma Google'i kontole}}</translation>
<translation id="5763042198335101085">Sisestage kehtiv e-posti aadress</translation>
<translation id="5765072501007116331">Kohaletoimetamisviiside ja nõuete nägemiseks valige aadress</translation>
-<translation id="5770114862687765385">Näib, et fail on rikutud. Seansi lähtestamiseks klõpsake nupul „Lähtesta”.</translation>
<translation id="5778550464785688721">MIDI-seadmete täielik juhtimine</translation>
<translation id="578305955206182703">Merevaigukollane</translation>
<translation id="57838592816432529">Vaigista</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>
+<translation id="5798290721819630480">Kas soovite muudatustest loobuda?</translation>
<translation id="5798683403665926540">Muutke avalehte Chrome'i seadetes</translation>
<translation id="5803412860119678065">Kas soovite sisestada kirje <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Load</translation>
<translation id="5810442152076338065">Teie ühendus domeeniga <ph name="DOMAIN" /> on krüpteeritud aegunud šifreerimiskomplektiga.</translation>
<translation id="5813119285467412249">&amp;Lisa uuesti</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="5860033963881614850">Väljas</translation>
<translation id="5863847714970149516">Järgmisel lehel võidakse teilt üritada tasu võtta</translation>
<translation id="5866257070973731571">Telefoninumbri lisamine</translation>
<translation id="5869405914158311789">Selle saidiga ei saa ühendust</translation>
<translation id="5869522115854928033">Salvestatud paroolid</translation>
<translation id="5887400589839399685">Kaart on salvestatud</translation>
-<translation id="5893718151540690985">Edastab loendi võrguliidestest koos nende tüüpide ja riistvara aadressidega</translation>
<translation id="5893752035575986141">Kaupmees aktsepteerib krediitkaarte.</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="5916664084637901428">Sees</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Kas salvestada kaart Google'i kontole?</translation>
<translation id="5922853866070715753">Peaaegu valmis</translation>
<translation id="5932224571077948991">Sait kuvab sekkuvaid või eksitavaid reklaame</translation>
-<translation id="5939518447894949180">Lähtesta</translation>
<translation id="5946937721014915347">Saidi <ph name="SITE_NAME" /> avamine …</translation>
<translation id="5951495562196540101">Tarbijakontoga ei saa registreeruda (paketipõhine litsents on saadaval).</translation>
<translation id="5967592137238574583">Kontaktteabe muutmine</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Suumib välja</translation>
<translation id="5977489021191000276">Teie seadet ei halda administraator.</translation>
<translation id="5977976211062815271">Selles seadmes</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Makserakendust ei saa avada</translation>
<translation id="5989320800837274978">Määratud ei ole fikseeritud puhverservereid ega pac-skriptiga URL-i.</translation>
<translation id="5990559369517809815">Laiendus blokeeris serverisse saadetavad päringud.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">Edastab riistvara statistikat (nt protsessori/RAM-i kasutus)</translation>
<translation id="6034000775414344507">Helehall</translation>
+<translation id="6034283069659657473">10x14 (ümbrik)</translation>
<translation id="6039846035001940113">Kui probleem jätkub, võtke ühendust saidi omanikuga.</translation>
<translation id="6040143037577758943">Sulge</translation>
<translation id="6044573915096792553">Suurus 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Kas soovite kaarte kasutada kõigis oma seadmetes?</translation>
<translation id="6059925163896151826">USB-seadmed</translation>
-<translation id="6071091556643036997">Reegli tüüp on sobimatu.</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="6094273045989040137">Lisa märkus</translation>
<translation id="610911394827799129">Aadressil <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> võib teie Google'i kontol olla muus vormis sirvimisajalugu</translation>
+<translation id="6132597952260690497">Installitud laienduste ja pistikprogrammide teave</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Vabastab alla <ph name="SIZE" />. Mõne saidi laadimine võib järgmisel külastusel rohkem aega võtta.</translation>
<translation id="6337534724793800597">Reeglite filtreerimine nime järgi</translation>
<translation id="6358450015545214790">Mida need tähendavad?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Jätkamisega võivad kaasneda tasud.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{veel 1 soovitus}other{veel # soovitust}}</translation>
<translation id="6387754724289022810">Kui soovite järgmisel korral kiiremini maksta, salvestage kaart ja arveldusaadress oma Google'i kontole ja sellesse seadmesse.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Muuda järjehoidjat</translation>
+<translation id="6406765186087300643">C0 (ümbrik)</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="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="6434309073475700221">Tühista</translation>
+<translation id="6446163441502663861">Kahu (ümbrik)</translation>
<translation id="6446608382365791566">Lisateabe lisamine</translation>
<translation id="6447842834002726250">Küpsised</translation>
<translation id="6451458296329894277">Kinnita vormi uuestiesitamist</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Taaskäivitage Chrome</translation>
<translation id="6529602333819889595">&amp;Kustuta uuesti</translation>
<translation id="6534179046333460208">Füüsilise veebi soovitused</translation>
+<translation id="6556866813142980365">Tee uuesti</translation>
<translation id="6563469144985748109">Haldur ei ole seda veel kinnitanud</translation>
<translation id="6569060085658103619">Vaatate laienduse lehte</translation>
+<translation id="6578796323535178455">C2 (ümbrik)</translation>
<translation id="6579990219486187401">Heleroosa</translation>
+<translation id="6583674473685352014">B6 (ümbrik)</translation>
+<translation id="6587923378399804057">Teie kopeeritud link</translation>
+<translation id="6591833882275308647">Teie seadet <ph name="DEVICE_TYPE" /> ei hallata</translation>
<translation id="6596325263575161958">Krüpteerimise valikud</translation>
<translation id="6604181099783169992">Liikumis- või valgusandurid</translation>
+<translation id="6609880536175561541">Prc7 (ümbrik)</translation>
<translation id="6624427990725312378">Kontaktteave</translation>
<translation id="6626291197371920147">Kehtiva kaardinumbri lisamine</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />'i otsing</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">See reegel on aegunud.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Mitte ükski}=1{1 saidilt (teid ei logita Google'i kontolt välja)}other{# saidilt (teid ei logita Google'i kontolt välja)}}</translation>
<translation id="6657585470893396449">Parool</translation>
+<translation id="6670613747977017428">Tagasi turvalisusse.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Registreerimismärk:</translation>
<translation id="6711464428925977395">Puhverserveriga on midagi valesti või aadress on vale.</translation>
<translation id="6723740634201835758">Teie Google’i kontol</translation>
+<translation id="6738516213925468394">Teie andmed krüpteeriti teie <ph name="BEGIN_LINK" />sünkroonimisparooliga<ph name="END_LINK" /> kuupäeval <ph name="TIME" />. Sisestage see sünkroonimise alustamiseks.</translation>
<translation id="674375294223700098">Serveri sertifikaadi tundmatu viga.</translation>
<translation id="6744009308914054259">Ühenduse loomise ajal võite avada jaotise Allalaadimised ja lugeda võrguühenduseta artikleid.</translation>
<translation id="6753269504797312559">Reegli väärtus</translation>
<translation id="6757797048963528358">Teie seade lülitus unerežiimile.</translation>
+<translation id="6768213884286397650">Hagaki (postkaart)</translation>
<translation id="6778737459546443941">Vanem ei ole seda veel kinnitanud</translation>
<translation id="67862343314499040">Violetne</translation>
+<translation id="6786747875388722282">Laiendused</translation>
<translation id="679355240208270552">Seda eiratakse, kuna vaikeotsing ei ole reegliga lubatud.</translation>
<translation id="681021252041861472">Kohustuslik väli</translation>
<translation id="6810899417690483278">Kohandamise ID</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Seade</translation>
<translation id="6970216967273061347">Piirkond</translation>
<translation id="6973656660372572881">Määratud on nii fikseeritud puhverserverid kui ka pac-skriptiga URL.</translation>
+<translation id="6973932557599545801">Kahjuks ma ei saa aidata, jätkake iseseisvalt.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Vaigista (vaikeseade)</translation>
<translation id="6984479912851154518">Väljute privaatsest režiimist, et välise rakenduse kaudu maksta. Kas soovite jätkata?</translation>
<translation id="6989763994942163495">Kuva täpsemad seaded ...</translation>
+<translation id="6993898126790112050">6x9 (ümbrik)</translation>
<translation id="6996312675313362352">Tõlgi alati: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">Hiina UnionPay</translation>
<translation id="7016992613359344582">Tasud võivad olla ühekordsed või korduvad ja need ei pruugi olla ilmselged.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Peida</translation>
<translation id="7108819624672055576">Lubas laiendus</translation>
<translation id="7111012039238467737">(Kehtiv)</translation>
+<translation id="7118618213916969306">Lõikelaua URL-i otsimine, <ph name="SHORT_URL" /></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="7135130955892390533">Kuva olek</translation>
<translation id="7138472120740807366">Kohaletoimetamisviis</translation>
<translation id="7139724024395191329">Emiraat</translation>
+<translation id="7152423860607593928">Number-14 (ümbrik)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendlililla</translation>
-<translation id="7158980942472052083">Sobimatu URL. Peab olema standardskeemiga URL.</translation>
<translation id="717330890047184534">Gaia ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Server, kuhu sisenete, <ph name="ORIGIN" />, taotleb, et
+ turvalisuse reeglit kohaldatakse igale sisenemistaotlusele. Reegli
+ saatmise asemel on see aga brauseri ümber suunanud mujale, mis takistab
+ brauseril täitmast teie sisenemistaotlust saidile <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Salvesta ja sisesta makseviisid</translation>
<translation id="7180611975245234373">Värskenda</translation>
<translation id="7182878459783632708">Reegleid pole määratud</translation>
<translation id="7186367841673660872">See leht on tõlgitud keelest<ph name="ORIGINAL_LANGUAGE" />keelde<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Vabastab <ph name="SIZE" />. Mõne saidi laadimine võib järgmisel külastusel rohkem aega võtta.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Teie administraator näeb järgmist.</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Host <ph name="HOST_NAME" /> ei pea turvastandarditest kinni.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /> selle probleemi kohta.</translation>
<translation id="7219179957768738017">Ühendus kasutab protokolli <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Töötlemine</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Avatav veebisait sisaldab pahavara</translation>
+<translation id="724766306220616965">Hoiatused, konflikt</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="7251437084390964440">Võrgu seadistus ei vasta ONC standardile. On võimalik, et seadistuse mõnd osa ei saa importida.
Lisateave:
@@ -982,11 +1120,14 @@ Lisateave:
<translation id="7300012071106347854">Koobaltsinine</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />”</translation>
<translation id="7309308571273880165">Krahhiaruanne jäädvustati ajal <ph name="CRASH_TIME" /> (kasutaja taotles üleslaadimist; pole veel üles laaditud)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Ohutu sirvimise<ph name="END_LINK" /> hoiatused</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ühendamise abi</translation>
<translation id="7334320624316649418">&amp;Korrasta uuesti</translation>
<translation id="733923710415886693">Serveri sertifikaati ei avalikustatud sertifikaadi läbipaistvuse reegli kaudu.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Käsurida</translation>
-<translation id="7365061714576910172">Ekspordi Linuxi vormingus</translation>
<translation id="7372973238305370288">otsingutulemus</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ei</translation>
@@ -994,6 +1135,7 @@ Lisateave:
<translation id="7381288752349550461">Hallatud seansi alistamine</translation>
<translation id="7390545607259442187">Kaardi kinnitamine</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Teie seadet <ph name="DEVICE_NAME" /> hallatakse</translation>
<translation id="7407424307057130981">&lt;p&gt;See viga ilmneb juhul, kui teie Windowsi arvutis on tarkvara Superfish.&lt;/p&gt;
&lt;p&gt;Selleks et veebi pääseda, järgige tarkvara keelamiseks neid toiminguid. Vajate administraatoriõigusi.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Lisateave:
&lt;li&gt;Klõpsake käsul &lt;strong&gt;Apply&lt;/strong&gt; ja seejärel valikul &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Vaadake &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome'i abikeskusest&lt;/a&gt; teavet selle kohta, kuidas tarkvara arvutist jäädavalt eemaldada
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Teenuse <ph name="PRODUCT_NAME" /> haldus</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Halda paroole …</translation>
<translation id="7419106976560586862">Profiili tee</translation>
<translation id="7437289804838430631">Lisa kontaktteave</translation>
@@ -1013,22 +1155,24 @@ Lisateave:
<translation id="7442725080345379071">Heleoranž</translation>
<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="7449109375006139765">Saadab süsteemilogid haldusserverisse</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="7460618730930299168">Filtreerimine erineb valitust. Kas jätkata?</translation>
<translation id="7473891865547856676">Tänan, ei</translation>
-<translation id="7475525192983021547">Edastab perioodid, millal kasutaja on seadmes aktiivne</translation>
<translation id="7481312909269577407">Edasta</translation>
<translation id="7485870689360869515">Andmeid ei leitud.</translation>
+<translation id="7498234416455752244">Jätka muutmist</translation>
<translation id="7508255263130623398">Tagastatud reegli seadme-ID on tühi või ei kattu praeguse seadme-ID-ga</translation>
<translation id="7508870219247277067">Avokaadoroheline</translation>
<translation id="7511955381719512146">WiFi-võrk, mida kasutate, võib nõuda veebilehe <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> külastamist.</translation>
<translation id="7514365320538308">Laadi alla</translation>
<translation id="7518003948725431193">Järgneval veebiaadressil ei olnud ühtegi veebilehte: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (ümbrik)</translation>
<translation id="7521387064766892559">Javascript</translation>
<translation id="7526934274050461096">Teie ühendus selle saidiga pole privaatne</translation>
+<translation id="7535087603100972091">Väärtus</translation>
<translation id="7537536606612762813">Kohustuslik</translation>
+<translation id="7538364083937897561">A2 (ümbrik)</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>
@@ -1037,8 +1181,8 @@ Lisateave:
<translation id="7552846755917812628">Proovige järgmiseid nõuandeid.</translation>
<translation id="7554791636758816595">Uus vaheleht</translation>
<translation id="7564049878696755256">Võite kaotada juurdepääsu oma teenuse <ph name="ORG_NAME" /> kontole või teie identiteet võidakse varastada. Chrome soovitab teil kohe oma parooli muuta.</translation>
-<translation id="7566125604157659769">Tekst, mille kopeerisite</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="7568105740864181217">Seda brauserit haldab ettevõte, kool või muu organisatsioon. Teie administraator saab brauseri seadistust kaugühenduse kaudu muuta. Selle seadme tegevusi võidakse hallata ka väljaspool Chrome'i. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Lisateave:
<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="7633909222644580952">Toimivusandmed ja krahhiaruanded</translation>
<translation id="7637571805876720304">Kas eemaldada Chromiumist krediitkaart?</translation>
<translation id="7639968568612851608">Tumehall</translation>
<translation id="765676359832457558">Peida täpsemad seaded ...</translation>
@@ -1058,9 +1203,11 @@ Lisateave:
<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="7676643023259824263">Lõikelaua teksti otsimine, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Muuda otsingumootorit</translation>
<translation id="7682287625158474539">Kohaletoimetamine</translation>
<translation id="7687186412095877299">Täidab maksevormid teie salvestatud makseviiside andmete alusel</translation>
+<translation id="7697066736081121494">Prc8 (ümbrik)</translation>
<translation id="769721561045429135">Praegu on teil kaarte, mida saab kasutada ainult selles seadmes. Kaartide ülevaatamiseks klõpsake käsul Jätka.</translation>
<translation id="7699293099605015246">Artiklid pole praegu saadaval</translation>
<translation id="7701040980221191251">Mitte ükski</translation>
@@ -1072,11 +1219,13 @@ Lisateave:
<translation id="774634243536837715">Ohtlik sisu blokeeriti.</translation>
<translation id="7752995774971033316">Haldamata</translation>
<translation id="7755287808199759310">Vanem saab blokeeringu teie eest tühistada</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Tulemüür või viirusetõrjetarkvara võis ühenduse blokeerida.</translation>
<translation id="7759163816903619567">Kuvatav domeen:</translation>
<translation id="7761701407923456692">Serveri sertifikaat ei vasta URL-ile.</translation>
<translation id="7763386264682878361">Makse manifesti parser</translation>
<translation id="7764225426217299476">Lisage aadress</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektuur</translation>
<translation id="7791543448312431591">Lisa</translation>
<translation id="7793809570500803535">Veebileht aadressil <ph name="SITE" /> võib olla ajutiselt maas või jäädavalt uuele veebiaadressile teisaldatud.</translation>
@@ -1088,8 +1237,8 @@ Lisateave:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Kas eemaldada Chrome'ist vormi soovitus?</translation>
<translation id="7815407501681723534">Otsingule „<ph name="SEARCH_STRING" />” leiti <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" />.</translation>
-<translation id="7818867226424560206">Eeskirjade haldamine</translation>
<translation id="782886543891417279">WiFi-võrk, mida kasutate (<ph name="WIFI_NAME" />), võib nõuda sisselogimislehe külastamist.</translation>
+<translation id="7836231406687464395">Postfix (ümbrik)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Puudub}=1{1 rakendus (<ph name="EXAMPLE_APP_1" />)}=2{2 rakendust (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# rakendust (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Te pole siiski nähtamatu. Inkognito režiimi kasutamine ei varja teie sirvimist tööandja, Interneti-teenuse pakkuja ega külastatavate veebisaitide eest.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Lisateave:
<translation id="7878562273885520351">Teie parool võib olla ohus</translation>
<translation id="7882421473871500483">Pruun</translation>
<translation id="7887683347370398519">Kontrollige CVC-d ja proovige uuesti</translation>
-<translation id="7893255318348328562">Seansi nimi</translation>
+<translation id="7904208859782148177">C3 (ümbrik)</translation>
<translation id="79338296614623784">Sisestage kehtiv telefoninumber</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Aegub <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Lisateave:
<translation id="7951415247503192394">(32-bitine)</translation>
<translation id="7956713633345437162">Mobiili järjehoidjad</translation>
<translation id="7961015016161918242">Mitte kunagi</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Brauser</translation>
<translation id="8009225694047762179">Halda paroole</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{See kaart ja selle arveldusaadress salvestatakse. Saate seda kasutada, kui olete kontole <ph name="USER_EMAIL" /> sisse logitud.}other{Need kaardid ja nende arveldusaadressid salvestatakse. Saate neid kasutada, kui olete kontole <ph name="USER_EMAIL" /> sisse logitud.}}</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="8034522405403831421">Leht on <ph name="SOURCE_LANGUAGE" /> keeles. Kas tõlkida <ph name="TARGET_LANGUAGE" /> keelde?</translation>
<translation id="8035152190676905274">Sulepea</translation>
+<translation id="8037117624646282037">Näitab, kes on seadet hiljuti kasutanud</translation>
<translation id="8037357227543935929">Küsi (vaikimisi)</translation>
<translation id="803771048473350947">Fail</translation>
<translation id="8041089156583427627">Saada tagasiside</translation>
<translation id="8041940743680923270">Kasuta globaalset vaikeseadet (küsi)</translation>
<translation id="8042918947222776840">Valige kättesaamisviis</translation>
<translation id="8057711352706143257">Tarkvara „<ph name="SOFTWARE_NAME" />” ei ole õigesti seadistatud. Tarkvara „<ph name="SOFTWARE_NAME" />” desinstallimine lahendab tavaliselt probleemi. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Teie seade on seadistatud järgmiseks.</translation>
+<translation id="8066955247577885446">Kahjuks läks midagi valesti</translation>
+<translation id="8074253406171541171">10x13 (ümbrik)</translation>
<translation id="8078141288243656252">Pööramisel ei saa märkusi lisada</translation>
<translation id="8079031581361219619">Kas laadida sait uuesti?</translation>
<translation id="8088680233425245692">Artikli kuvamine ebaõnnestus.</translation>
@@ -1131,11 +1284,12 @@ Lisateave:
<translation id="8091372947890762290">Aktiveerimine on serveris ootel</translation>
<translation id="8092774999298748321">Sügavlilla</translation>
<translation id="8094917007353911263">Võrk, mida kasutate, võib nõuda veebilehe <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> külastamist.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Kehtetud kaardid eemaldati</translation>
<translation id="8103161714697287722">Makseviis</translation>
<translation id="8118489163946903409">Makseviis</translation>
+<translation id="8123836779274890062">Seadet <ph name="DEVICE_TYPE" /> haldab <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Tarkvara „<ph name="SOFTWARE_NAME" />” ei installitud teie arvutisse või võrku korralikult. Paluge IT-administraatoril see probleem lahendada.</translation>
-<translation id="8130693978878176684">Ma ei saa rohkem aidata, jätkake iseseisvalt.</translation>
<translation id="8131740175452115882">Kinnita</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>
@@ -1145,8 +1299,11 @@ Lisateave:
<translation id="8197543752516192074">Tõlgi leht</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (ümbrik)</translation>
<translation id="8211406090763984747">Ühendus on turvaline</translation>
<translation id="8218327578424803826">Määratud asukoht:</translation>
+<translation id="8220146938470311105">C7/C6 (ümbrik)</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="8238581221633243064">Avage leht uuel inkognito vahekaardil</translation>
@@ -1158,14 +1315,16 @@ Lisateave:
<translation id="825929999321470778">Kuva kõik salvestatud paroolid</translation>
<translation id="8261506727792406068">Kustuta</translation>
<translation id="8267698848189296333">Sisselogimine kasutajana <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Seda brauserit haldab <ph name="ENROLLMENT_DOMAIN" />. Teie administraator saab brauseri seadistust kaugühenduse kaudu muuta. Selle seadme tegevusi võidakse hallata ka väljaspool Chrome'i. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Logi sisse</translation>
<translation id="8288807391153049143">Kuva sertifikaat</translation>
<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="8298115750975731693">WiFi-võrk, mida kasutate (<ph name="WIFI_NAME" />), võib nõuda veebilehe <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> külastamist.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Tõlkimine ebaõnnestus võrguühenduse probleemi tõttu.</translation>
-<translation id="8311129316111205805">Laadi seanss</translation>
<translation id="8332188693563227489">Juurdepääs hostile <ph name="HOST_NAME" /> blokeeriti</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Lisateave:
<translation id="8416694386774425977">Võrgu seadistus on sobimatu ja seda ei saa importida.
Lisateave:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Seadet haldab <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Muuda</translation>
<translation id="8428213095426709021">Seaded</translation>
@@ -1210,9 +1368,11 @@ Lisateave:
<translation id="860043288473659153">Kaardiomaniku nimi</translation>
<translation id="861775596732816396">Suurus 4</translation>
<translation id="8620436878122366504">Vanemad ei ole seda veel kinnitanud</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Salvesta kaart sellesse seadmesse</translation>
<translation id="8663226718884576429">Tellimuse kokkuvõte, <ph name="TOTAL_LABEL" />, rohkem üksikasju</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, vastus, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Teie ühendus <ph name="DOMAIN" />'ga pole krüptitud.</translation>
<translation id="8718314106902482036">Makset ei viidud lõpule</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, otsingusoovitus</translation>
@@ -1226,6 +1386,7 @@ Lisateave:
<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="8763927697961133303">USB-seade</translation>
<translation id="8768895707659403558">Kõigis seadmetes kaartide kasutamiseks <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Kustuta uuesti</translation>
<translation id="8792621596287649091">Võite kaotada juurdepääsu oma teenuse <ph name="ORG_NAME" /> kontole või teie identiteet võidakse varastada. Chromium soovitab teil kohe oma parooli muuta.</translation>
<translation id="8800988563907321413">Teie lähedalasuvad soovitused kuvatakse siin</translation>
@@ -1236,10 +1397,12 @@ Lisateave:
<translation id="885730110891505394">Jagamine Google'iga</translation>
<translation id="8858065207712248076">Chromium soovitab teil organisatsiooni <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> parooli lähtestada, kui kasutasite seda ka muudel saitidel.</translation>
<translation id="8866481888320382733">Reegli seadete sõelumisel ilmnes viga</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Viimati suletud</translation>
<translation id="8874824191258364635">Sisestaeg kehtiv kaardinumber</translation>
<translation id="8891727572606052622">Kehtetu puhverserveri režiim.</translation>
<translation id="8903921497873541725">Suurendab</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Kas soovite selle kaardi salvestada oma Google'i kontole?</translation>
<translation id="8932102934695377596">Teie kell on taga</translation>
<translation id="893332455753468063">Nime lisamine</translation>
@@ -1247,13 +1410,13 @@ Lisateave:
<translation id="894185898663964645">Teie administraator on seadistanud kohandatud juursertifikaadid, mille loal võib administraator teie külastatud veebisaitide sisu näha.</translation>
<translation id="8943282376843390568">Laimiroheline</translation>
<translation id="8957210676456822347">Kontrollportaali volitamine</translation>
+<translation id="8966619695390250636">Kas mõtlesite seda?</translation>
<translation id="8968766641738584599">Salvesta kaart</translation>
<translation id="8971063699422889582">Serveri sertifikaat on aegunud.</translation>
<translation id="8975012916872825179">Hõlmab näiteks telefoninumbreid, e-posti ja postiaadresse</translation>
<translation id="8978053250194585037">Google'i ohutu sirvimise funktsioon <ph name="BEGIN_LINK" />tuvastas hiljuti andmepüügi<ph name="END_LINK" /> saidil <ph name="SITE" />. Andmepüügisaidid teesklevad teie petmiseks, et tegemist on teise saidiga.</translation>
<translation id="8983003182662520383">Makseviisid ja aadressid, mis kasutavad teenust Google Pay</translation>
<translation id="8987927404178983737">kuu</translation>
-<translation id="8988408250700415532">Midagi läks valesti. Saate tellimuse lõpule viia veebisaidil.</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>
@@ -1263,6 +1426,7 @@ Lisateave:
<translation id="9011424611726486705">Avage saidi seaded</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Kehtetu)</translation>
<translation id="9035022520814077154">Turvaviga</translation>
<translation id="9038649477754266430">Kasuta lehtede kiiremaks laadimiseks ennustusteenust</translation>
@@ -1274,11 +1438,11 @@ Lisateave:
<translation id="9065745800631924235">Otsing <ph name="TEXT" /> ajaloost</translation>
<translation id="9069693763241529744">Blokeeris laiendus</translation>
<translation id="9076283476770535406">See võib sisaldada täiskasvanutele mõeldud sisu</translation>
+<translation id="9076630408993835509">Seda brauserit ei halda ettevõte ega muu organisatsioon. Selle seadme tegevusi võidakse hallata ka väljaspool Chrome'i. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Vaja on rohkem teavet</translation>
<translation id="9080712759204168376">Tellimuse kokkuvõte</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>
<translation id="9106062320799175032">Arveldusaadressi lisamine</translation>
-<translation id="9110718169272311511">Google'i assistent on Chrome'is saadaval ekraani alaosas</translation>
<translation id="9114524666733003316">Kaardi kinnitamine …</translation>
<translation id="9128870381267983090">Ühendumine Internetiga</translation>
<translation id="9137013805542155359">Kuva originaal</translation>
@@ -1287,6 +1451,7 @@ Lisateave:
<translation id="9148507642005240123">&amp;Võta muudatus tagasi</translation>
<translation id="9154194610265714752">Värskendatud</translation>
<translation id="9157595877708044936">Seadistamine...</translation>
+<translation id="9158625974267017556">C6 (ümbrik)</translation>
<translation id="9168814207360376865">Luba saitidel kontrollida, kas olete makseviisid salvestanud</translation>
<translation id="9169664750068251925">Blokeeri sellel saidil alati</translation>
<translation id="9170848237812810038">&amp;Võta tagasi</translation>
@@ -1301,10 +1466,12 @@ Lisateave:
<translation id="9219103736887031265">Pildid</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">TÜHJENDA VORM</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Võite kaotada juurdepääsu oma Google'i kontole. Chromium soovitab teil kohe oma parooli muuta. Teil palutakse sisse logida.</translation>
<translation id="939736085109172342">Uus kaust</translation>
<translation id="945855313015696284">Vaadake allolevat teavet ja kustutage sobimatud kaardid</translation>
<translation id="951104842009476243">Aktsepteeritavad ettemakstud ja deebetkaardid</translation>
+<translation id="958202389743790697">Blokeeritud saidi <ph name="ORIGIN" /> turvalisuse reegli tõttu</translation>
<translation id="962484866189421427">Sisu võib üritada installida petturlikke rakendusi, mis esinevad millegi muuna või koguvad andmeid, mida saab kasutada teie jälgimiseks. <ph name="BEGIN_LINK" />Kuva siiski<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Ametlik järk</translation>
<translation id="973773823069644502">Lisage kohaletoimetamisaadress</translation>
@@ -1313,6 +1480,7 @@ Lisateave:
<translation id="984275831282074731">Makseviisid</translation>
<translation id="985199708454569384">&lt;p&gt;Seda viga näete juhul, kui teie arvuti või mobiilseadme kuupäev ja kellaaeg pole õiged.&lt;/p&gt;
&lt;p&gt;Vea parandamiseks avage seadme kell ning veenduge, et kellaaeg ja kuupäev oleksid õiged.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Arendaja järk</translation>
<translation id="989988560359834682">Aadressi muutmine</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_fa.xtb b/chromium/components/strings/components_strings_fa.xtb
index ebbf7f8a023..d76f1a8f844 100644
--- a/chromium/components/strings/components_strings_fa.xtb
+++ b/chromium/components/strings/components_strings_fa.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
-<translation id="1005145902654145231">تغییر نام این جلسه انجام نشد.</translation>
<translation id="1008557486741366299">اکنون نه</translation>
<translation id="1010200102790553230">بار کردن صفحه در فرصتی دیگر</translation>
<translation id="1015730422737071372">جزئیات بیشتری ارائه دهید</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">نام ناشناس</translation>
<translation id="1050038467049342496">برنامه‌های دیگر را ببندید</translation>
<translation id="1055184225775184556">&amp;واگرد افزودن</translation>
+<translation id="1056898198331236512">اخطار</translation>
<translation id="1058479211578257048">درحال ذخیره‌سازی کارت‌ها...</translation>
<translation id="10614374240317010">هرگز ذخیره نمی‌شود</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">نشانک‌های دسک‌تاپ</translation>
<translation id="1074497978438210769">امن نیست</translation>
<translation id="1080116354587839789">متناسب با پهنا</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">افزودن نام روی کارت</translation>
<translation id="1089439967362294234">تغییر گذرواژه</translation>
<translation id="109743633954054152">‏گذرواژها را در تنظیمات Chrome مدیریت کنید</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">در مدتی که وب‌سایت‌ها امنیتشان را به‌روزرسانی می‌کنند، ممکن است به‌طور معمول اخطارهایی دریافت کنید. این مورد به‌زودی اصلاح می‌شود.</translation>
<translation id="1126551341858583091">اندازه در فضای ذخیره‌سازی محلی <ph name="CRASH_SIZE" /> است.</translation>
<translation id="112840717907525620">حافظه پنهان خط‌مشی مورد تأیید است</translation>
+<translation id="1131264053432022307">تصویری که کپی کرده‌اید</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> به‌طور غیرمنتظره‌ای اتصال را قطع کرد.</translation>
<translation id="1161325031994447685">‏اتصال مجدد به Wi-Fi</translation>
<translation id="1165039591588034296">خطا</translation>
-<translation id="1173894706177603556">تغییر نام</translation>
<translation id="1175364870820465910">&amp;چاپ...</translation>
<translation id="1181037720776840403">حذف</translation>
<translation id="1197088940767939838">نارنجی</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">نام دستگاهتان</translation>
<translation id="124116460088058876">زبان‌های بیشتر</translation>
<translation id="1250759482327835220">‏برای اینکه دفعه بعد پرداخت سریع‌تری داشته باشید، اطلاعات کارت، نام و نشانی صورت‌حسابتان را در حساب Google خود ذخیره کنید.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />، <ph name="TYPE_2" /> (همگام‌سازی‌شده)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">انواع مختلف خط فرمان</translation>
<translation id="129553762522093515">اخیراً بسته‌شده</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />کوکی‌ها را پاک کنید<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">جلسه انتخاب‌شده موجود نیست.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">جستجوی تصویر بریده‌دان</translation>
<translation id="1323433172918577554">نمایش موارد بیشتر</translation>
<translation id="132390688737681464">ذخیره و تکمیل نشانی</translation>
<translation id="1333989956347591814">فعالیت شما <ph name="BEGIN_EMPHASIS" />ممکن است در موارد زیر قابل‌رؤیت باشد<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">نشانی تحویل گرفتن کالا</translation>
<translation id="1348198688976932919">سایت پیش‌رو حاوی برنامه‌های خطرناک است</translation>
<translation id="1348779747280417563">تأیید نام</translation>
+<translation id="1357195169723583938">افرادی که اخیراً از دستگاه استفاده کرده‌اند و زمان استفاده آن‌ها</translation>
+<translation id="1364822246244961190">این خط‌مشی مسدود شده است، ارزش آن نادیده گرفته خواهد شد.</translation>
<translation id="1374468813861204354">پیشنهادات</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">درباره نسخه</translation>
<translation id="1376836354785490390">نمایش موارد کمتر</translation>
<translation id="1377321085342047638">شماره کارت</translation>
<translation id="138218114945450791">آبی روشن</translation>
+<translation id="1382194467192730611">‏سرپرست دستگاه USB را مجاز کرد</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> داده‌ای ارسال نکرد.</translation>
+<translation id="140316286225361634">سایت <ph name="ORIGIN" /> درخواست کرده است خط‌مشی امنیتی برای همه
+ درخواست‌هایش اعمال شود و این خط‌مشی درحال‌حاضراین سایت را ناامن
+ می‌داند.</translation>
<translation id="1405567553485452995">سبز روشن</translation>
<translation id="1407135791313364759">باز کردن همه</translation>
<translation id="1413809658975081374">خطای حریم خصوصی</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">بله</translation>
<translation id="1430915738399379752">چاپ</translation>
<translation id="1455413310270022028">پاک‌کن</translation>
+<translation id="1463543813647160932">۵x۷</translation>
+<translation id="1472675084647422956">بیشتر ببینید</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">انتخاب نشانی تحویل کالا</translation>
+<translation id="1492194039220927094">اعمال خط‌مشی‌ها:</translation>
<translation id="1501859676467574491">‏کارت‌ها را از حساب Google خود نمایش دهید</translation>
-<translation id="1506687042165942984">یک نسخه ذخیره‌شده (یعنی قدیمی) از این صفحه نشان داده شود.</translation>
<translation id="1507202001669085618">‏&lt;p&gt;اگر از پورتالی از Wi-Fi استفاده می‌کنید که پیش از آنلاین شدن شما را ملزم به ورود به سیستم می‌کند، این خطا را می‌بینید.&lt;/p&gt;
&lt;p&gt;برای برطرف کردن این خطا، در صفحه‌ای که می‌خواهید باز کنید روی &lt;strong&gt;اتصال&lt;/strong&gt; کلیک کنید.&lt;/p&gt;</translation>
<translation id="1517433312004943670">شماره تلفن ضروری است</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">تاریخ ساخت</translation>
<translation id="1521655867290435174">‏کاربرگ‌نگار Google</translation>
<translation id="1527263332363067270">درانتظار برقراری اتصال…‏</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">این صفحه می‌گوید</translation>
<translation id="153384715582417236">درحال‌حاضر مورد دیگری وجود ندارد</translation>
<translation id="154408704832528245">انتخاب نشانی ارسال</translation>
<translation id="1549470594296187301">برای استفاده از این قابلیت، جاوا اسکریپت باید فعال باشد.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">وارد کردن تاریخ انقضا</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">هنگام نمایش این صفحه وب مشکلی پیش آمد.</translation>
<translation id="1592005682883173041">دسترسی داده محلی</translation>
<translation id="1594030484168838125">انتخاب</translation>
<translation id="161042844686301425">فیروزه‌ای</translation>
-<translation id="1618822247301510817">تصویری که کپی کرده‌اید</translation>
<translation id="1620510694547887537">دوربین</translation>
<translation id="1623104350909869708">جلوگیری از ایجاد پنجره‌های اضافی توسط این صفحه</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">پایان جلسه</translation>
<translation id="1639239467298939599">بارگیری</translation>
<translation id="1640180200866533862">خط‌مشی‌های کاربر</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">‏<ph name="SITE" /> معمولاً برای محافظت از اطلاعات شما از رمزگذاری استفاده می‌کند. اما این بار که Chrome تلاش کرد به <ph name="SITE" /> متصل شود، وب‌سایت اعتبارنامه‌ای نامعمول و نادرست را برگرداند. ممکن است مهاجمی در تلاش باشد خود را به‌جای <ph name="SITE" /> معرفی کند یا یک صفحه ورود به سیستم Wi-Fi در ارتباط اختلال ایجاد کرده باشد. اطلاعات شما همچنان ایمن است، زیرا Google Chrome قبل از هرگونه تبادل داده، اتصال را متوقف کرد.</translation>
<translation id="168841957122794586">گواهی‌نامه سرور دارای یک کلید رمزنگاری ضعیف است.</translation>
<translation id="1697532407822776718">آماده‌اید!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">این سند بسیار بزرگ است و نمی‌تواند حاشیه‌نویسی شود</translation>
<translation id="1721312023322545264">برای بازدید این سایت باید از <ph name="NAME" /> اجازه بگیرید</translation>
<translation id="1721424275792716183">* این فیلد اجباری است</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">با سرپرست سیستم تماس بگیرید.</translation>
<translation id="1740951997222943430">ماه انقضای معتبری وارد کنید</translation>
<translation id="1743520634839655729">‏برای اینکه دفعه بعد پرداخت سریع‌تری داشته باشید، اطلاعات کارت، نام و نشانی صورت‌حسابتان را در حساب Google خود و این دستگاه ذخیره کنید.</translation>
+<translation id="1745880797583122200">مرورگرتان تحت مدیریت است</translation>
<translation id="17513872634828108">بازکردن برگه‌ها</translation>
<translation id="1753706481035618306">شماره صفحه</translation>
<translation id="1763864636252898013">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورداعتماد سیستم عامل دستگاه شما نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">لطفاً «رمز عبارتی همگام‌سازی» خود را به‌روزرسانی کنید.</translation>
<translation id="1787142507584202372">برگه‌های بازتان در اینجا نشان داده می‌شوند</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">نام صاحب کارت</translation>
<translation id="1821930232296380041">پارامترهای درخواست یا درخواست نامعتبر</translation>
+<translation id="1822540298136254167">وب‌سایت‌هایی که بازدید می‌کنید و زمانی که در آن‌ها صرف می‌کنید</translation>
<translation id="1826516787628120939">در حال بررسی</translation>
<translation id="1834321415901700177">این سایت محتوی برنامه‌های مضر است</translation>
<translation id="1839551713262164453">اعتبارسنجی مقادیر خط‌مشی با خطا متوقف شد</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">‏داده‌های سابقه مرور Chrome را پاک کنید</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{و ۱ برنامه دیگر}one{و # برنامه دیگر}other{و # برنامه دیگر}}</translation>
<translation id="2003709556000175978">هم‌اکنون گذرواژه‌تان را بازنشانی کنید</translation>
+<translation id="20053308747750172">سروری که به آن می‌روید، <ph name="ORIGIN" />, درخواست کرده است
+ برای همه درخواست‌هایش خط‌مشی ایمنی اعمال شود. اما درحال‌حاضر
+ خط‌مشی نامعتبری ارسال شده است که مانع می‌شود مرورگر
+ درخواستتان را برای <ph name="SITE" /> برآورده کند.</translation>
<translation id="2025186561304664664">پروکسی بر روی پیکربندی خودکار تنظیم شده است.</translation>
<translation id="2030481566774242610">منظورتان <ph name="LINK" /> بود؟</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />بررسی پروکسی و دیوار آتش<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">اداره</translation>
<translation id="2102134110707549001">پیشنهاد گذرواژه قوی…</translation>
<translation id="2108755909498034140">رایانه را راه‌اندازی مجدد کنید</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">کارت</translation>
<translation id="2114841414352855701">نادیده گرفته شد زیرا <ph name="POLICY_NAME" /> آن را لغو می‌کند.</translation>
<translation id="213826338245044447">نشانک‌های تلفن‌ همراه</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">ویرایش کارت</translation>
<translation id="2166049586286450108">دسترسی کامل سرپرست</translation>
<translation id="2166378884831602661">این سایت نمی‌تواند اتصالی ایمن ارائه دهد</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">خط‌ مشی‌ها</translation>
<translation id="2183608646556468874">شماره تلفن</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{۱ نشانی}one{# نشانی}other{# نشانی}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">شماره تلفن</translation>
<translation id="2283340219607151381">ذخیره و تکمیل نشانی</translation>
<translation id="2292556288342944218">دسترسی شما به اینترنت مسدود است</translation>
+<translation id="2294558542833290837">پیوندی که ابتدا باز کرده بودید، نامعمول است</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">کمتر از ۱ مگابایت از فضا را آزاد می‌کند. ممکن است برخی از سایت‌ها در بازدیدهای بعدی کندتر بارگیری شوند.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> به نام کاربری و گذرواژه نیاز دارد.</translation>
<translation id="2317583587496011522">کارت‌های نقدی پذیرفته می‌شوند.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />، در <ph name="EXPIRATION_DATE_ABBR" /> منقضی می‌شود</translation>
<translation id="2337852623177822836">تنظیم توسط سرپرست کنترل می‌شود</translation>
+<translation id="2346319942568447007">تصویری که کپی کرده‌اید</translation>
<translation id="2349790679044093737">‏جلسه VR فعال است</translation>
<translation id="2354001756790975382">نشانک‌های دیگر</translation>
<translation id="2354430244986887761">‏مرور ایمن Google، اخیراً <ph name="BEGIN_LINK" />برنامه‌های خطرناکی<ph name="END_LINK" /> در <ph name="SITE" /> پیدا کرده است.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">گزارش خرابی ثبت‌شده در <ph name="CRASH_TIME" /> بارگذاری نشد</translation>
<translation id="2367567093518048410">سطح</translation>
<translation id="2378238891085281592">به حالت ناشناس رفته‌اید</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">پیش‌فرض شرکتی</translation>
<translation id="2386255080630008482">گواهی سرور باطل شده است.</translation>
<translation id="2392959068659972793">نمایش خط‌مشی‌ها با مقدار تنظیم نشده</translation>
<translation id="239429038616798445">این روش ارسال در دسترس نیست. روش دیگری را امتحان کنید.</translation>
<translation id="2396249848217231973">&amp;واگرد حذف</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن باطل شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
+<translation id="2418081434543109369">سروری که به آن می‌روید، <ph name="ORIGIN" />، درخواست کرده است
+ برای همه درخواست‌هایش خط‌مشی ایمنی اعمال شود. اما اکنون
+ خط‌مشی‌ای را ارسال نکرده است که این امر مانع می‌شود مرورگر درخواستتان را
+ برای سایت <ph name="SITE" /> برآورده کند.</translation>
<translation id="244665789865330679">دستگاه و حسابتان توسط <ph name="ENROLLMENT_DOMAIN" /> مدیریت می‌شود. این یعنی سرپرستتان می‌تواند دستگاه و حسابتان را ازراه‌دور پیکربندی کند.</translation>
<translation id="2463193859425327265">صفحه اصلی را تغییر دهید</translation>
<translation id="2463739503403862330">تکمیل</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">انتخاب روش ارسال</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />در حال اجرای عیب‌یابی شبکه<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ترجمه این صفحه</translation>
<translation id="2479410451996844060">‏URL جستجو نامعتبر است.</translation>
<translation id="2482878487686419369">اعلان‌ها</translation>
<translation id="248348093745724435">خط‌مشی‌های ماشین</translation>
+<translation id="2485387744899240041">نام کاربری دستگاه و مرورگرتان</translation>
<translation id="2491120439723279231">گواهی سرور دارای چندین خطاست.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">‏تجزیه‌کننده JSON</translation>
<translation id="2495093607237746763">‏اگر علامت زده شود، Chromium برای پر کردن سریع‌تر فرم، یک کپی از کارت شما در این دستگاه ذخیره می‌کند.</translation>
<translation id="2498091847651709837">اسکن کارت جدید</translation>
<translation id="2501278716633472235">بازگشت</translation>
<translation id="2503184589641749290">کارت‌های نقدی و پیش‌پرداخت قابل‌قبول</translation>
<translation id="2515629240566999685">بررسی سیگنال در منطقه‌تان</translation>
-<translation id="2516852381693169964">جستجوی <ph name="SEARCH_ENGINE" /> برای تصویر</translation>
<translation id="2523886232349826891">فقط در این دستگاه ذخیره شد</translation>
<translation id="2524461107774643265">افزودن اطلاعات بیشتر</translation>
<translation id="2536110899380797252">افزودن نشانی</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">‏شناسه Directory API:</translation>
<translation id="2597378329261239068">این سند توسط گذرواژه محافظت می‌شود. لطفاً یک گذرواژه وارد کنید.</translation>
<translation id="2609632851001447353">انواع مختلف</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">ساعت شما جلو است</translation>
<translation id="2634124572758952069">‏نشانی IP سرور <ph name="HOST_NAME" /> پیدا نشد.</translation>
<translation id="2639739919103226564">وضعیت:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">برگه‌ها یا برنامه‌های دیگر را ببندید</translation>
<translation id="267371737713284912">برای واگرد، <ph name="MODIFIER_KEY_DESCRIPTION" /> را فشار دهید</translation>
<translation id="2674170444375937751">آیا مطمئن هستید می‌خواهید این صفحات را از سابقه خود حذف کنید؟</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">خروج</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">کارت‌های قابل‌‌قبول</translation>
<translation id="2702801445560668637">فهرست خواندن</translation>
<translation id="2704283930420550640">مقدار با فرمت مطابقت ندارد.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">حذف آیتم های انتخاب شده</translation>
<translation id="277133753123645258">روش ارسال</translation>
<translation id="277499241957683684">ثبت دستگاه موجود نیست</translation>
-<translation id="2781030394888168909">‏صادر کردن سیستم‌عامل Mac</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">اتصال مجدداً برقرار شد.</translation>
<translation id="2788784517760473862">کارت‌های اعتباری قابل‌قبول</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">اتصال با استفاده از <ph name="CIPHER" /> رمزگذاری و راستی‌آزمایی شده است و از <ph name="KX" /> به عنوان مکانیسم تبادل کلید استفاده می‌کند.</translation>
<translation id="2835170189407361413">پاک کردن فرم</translation>
<translation id="2847118875340931228">پنجره ناشناس باز کنید</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">برای بازدید کردن از این سایت، مجوز لازم دارید</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">کارت ذخیره شود؟</translation>
<translation id="2903493209154104877">آدرس‌ها</translation>
<translation id="290376772003165898">صفحه به زبان <ph name="LANGUAGE" /> وجود ندارد؟</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">روش ارسال</translation>
<translation id="2928905813689894207">نشانی صورت‌حساب</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن از <ph name="DOMAIN2" /> است. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
<translation id="2948083400971632585">در صفحه تنظیمات می‌توانید همه پراکسی‌های پیکربندی شده برای هر اتصال را از کار بیاندازید.</translation>
<translation id="2955913368246107853">بستن نوار یافتن</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">نوع خط‌مشی اشتباه است</translation>
<translation id="3037605927509011580">اوه، نه!</translation>
<translation id="3041612393474885105">اطلاعات گواهی</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">درحال خروج از حالت ناشناس، برای پرداخت ازطریق یک برنامه خارجی. ادامه می‌دهید؟</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{هیچ‌کدام}=1{۱ گذرواژه}one{# گذرواژه}other{# گذرواژه}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">افزودن نشانی تحویل گرفتن</translation>
<translation id="3105172416063519923">شناسه دارایی:</translation>
<translation id="3109728660330352905">شما اجازه مشاهده این صفحه را ندارید.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> در <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">لغو پرداخت</translation>
<translation id="3207960819495026254">نشانک‌گذاری شده</translation>
-<translation id="3209375525920864198">لطفاً نام جلسه معتبری وارد کنید.</translation>
+<translation id="321912867715453276">اخطار: برای این خط‌مشی، بیش از یک منبع وجود دارد، اما مقادیر آن‌ها یکسان‌ است.</translation>
<translation id="3225919329040284222">سرور گواهی را نشان می‌دهد که با موارد پیش‌بینی‌شده داخلی مطابقت ندارد. این پیش‌بینی‌ها به‌طور حتم وب‌سایتهای دارای امنیت بالا را جهت محافظت از شما در بر می‌گیرند.</translation>
<translation id="3226128629678568754">دکمه تازه‌سازی را فشار دهید تا داده‌های مورد نیاز برای بارگیری صفحه مجدداً ارسال شود.</translation>
<translation id="3227137524299004712">میکروفن</translation>
<translation id="3228969707346345236">ترجمه انجام نشد زیرا صفحه در حال حاضر به زبان <ph name="LANGUAGE" /> است.</translation>
+<translation id="3229041911291329567">اطلاعات مربوط به نسخه دستگاه و مرورگر</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">افزودن نام روی کارت</translation>
<translation id="3287510313208355388">بارگیری بعد از آنلاین شدن</translation>
<translation id="3293642807462928945">درباره خطمشی <ph name="POLICY_NAME" /> بیشتر بدانید</translation>
<translation id="3303855915957856445">هیچ نتیجه‌ای برای جستجو یافت نشد</translation>
-<translation id="3305707030755673451">داده‌های شما در تاریخ <ph name="TIME" /> با عبارت عبور همگام‌سازی‌تان رمزگذاری شد. برای شروع همگام‌سازی آن را وارد کنید.</translation>
<translation id="3320021301628644560">افزودن نشانی صورتحساب</translation>
<translation id="3324983252691184275">زرشکی</translation>
<translation id="3338095232262050444">ایمن</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;انجام مجدد ویرایش</translation>
<translation id="342781501876943858">‏Chromium توصیه می‌کند اگر از گذرواژه‌تان در سایت‌های دیگری استفاده کردید آن را بازنشانی کنید.</translation>
<translation id="3431636764301398940">این کارت را در این دستگاه ذخیره کنید</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">مالک این دستگاه بازی دایناسور را خاموش کرده است</translation>
<translation id="3447884698081792621">نمایش گواهی (صادرشده توسط <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">فاصله زمانی واکشی:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">ماژیک</translation>
<translation id="3462200631372590220">پنهان کردن پیشرفته</translation>
<translation id="3467763166455606212">نام صاحب حساب الزامی است</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">کارت‌های اعتباری و پیش‌پرداخت پذیرفته می‌شوند.</translation>
<translation id="3582930987043644930">افزودن نام</translation>
<translation id="3583757800736429874">&amp;انجام مجدد انتقال</translation>
+<translation id="35866233670761917">سرپرست‌ها محتوای وب‌سایت‌هایی را که بازدید می‌کنید نمی‌بینند</translation>
<translation id="3586931643579894722">عدم نمایش جزئیات</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />، <ph name="DOMAIN" />، <ph name="TIME" /></translation>
<translation id="3614103345592970299">اندازه ۲</translation>
<translation id="3615877443314183785">تاریخ انقضای معتبری وارد کنید</translation>
<translation id="36224234498066874">پاک کردن داده‌های محصول مرور…</translation>
<translation id="362276910939193118">نمایش کل سابقه</translation>
-<translation id="3623476034248543066">نشان دادن مقدار</translation>
<translation id="3630155396527302611">اگر درحال حاضر به‌عنوان برنامه‌ای برای دسترسی به شبکه در فهرست قرار دارد،
سعی کنید آن را از فهرست حذف کرده و دوباره به فهرست اضافه کنید.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">ارزیابی موفق بود</translation>
<translation id="3655670868607891010">اگر مکرراً با این مشکل مواجه می‌شوید، <ph name="HELP_LINK" /> را امتحان کنید.</translation>
<translation id="3658742229777143148">ویرایش</translation>
<translation id="366077651725703012">کارت اعتباری را به‌روزرسانی کنید</translation>
<translation id="3676592649209844519">شناسه دستگاه:</translation>
+<translation id="3677008721441257057">‏منظورتان &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; است؟</translation>
<translation id="3678029195006412963">درخواست امضا نشد</translation>
<translation id="3678529606614285348">‏صفحه را در پنجره‌ «ناشناس» جدیدی باز کنید (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">گزارش خرابی در <ph name="CRASH_TIME" /> ثبت شد، در <ph name="UPLOAD_TIME" /> بارگذاری شد</translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">شاید شبکه‌ای که استفاده می‌کنید، بازدید از صفحه ورود به سیستم خودش را برای شما ضروری کرده باشد.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> ‏<ph name="BOOKMARKED" /> ‏<ph name="TITLE" /> ‏<ph name="DOMAIN" /></translation>
<translation id="370665806235115550">در حال بارکردن…</translation>
+<translation id="3709599264800900598">نوشتاری که کپی کرده‌اید</translation>
<translation id="3712624925041724820">مجوزها دیگر معتبر نیستند</translation>
<translation id="3714780639079136834">‏روشن کردن داده‌ شبکه تلفن همراه یا Wi-Fi</translation>
<translation id="3715597595485130451">‏اتصال به Wi-Fi</translation>
<translation id="3717027428350673159">‏<ph name="BEGIN_LINK" />بررسی پروکسی، دیوار آتش و پیکربندی DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">برنامه‌هایی که می‌توانند موجب این خطا شوند شامل ضدویروس‌ها، دیوار آتش و نرم‌افزار فیلتر کردن وب یا پراکسی هستند.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">‏بعد از تأیید کردن، جزئیات کارت از حساب Google شما با این سایت هم‌رسانی می‌شود.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">مسترکارت</translation>
<translation id="3787705759683870569">تاریخ انقضا <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">اندازه ۱۶</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">محتوای مضر مسدود شد.</translation>
<translation id="3810973564298564668">مدیریت</translation>
<translation id="382518646247711829">اگر از سرور پراکسی استفاده می‌کنید...</translation>
<translation id="3828924085048779000">عبارت عبور خالی مجاز نیست.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> افزونه‌هایی را برای عملکردهای اضافی نصب کرده است. افزونه‌ها به برخی از داده‌های شما دسترسی دارند.</translation>
<translation id="385051799172605136">بازگشت</translation>
<translation id="3858027520442213535">به‌روزرسانی تاریخ و زمان</translation>
<translation id="3884278016824448484">شناسه دستگاه یکسان نیست</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">درخواست شما برای دسترسی به این سایت برای <ph name="NAME" /> ارسال شده است</translation>
<translation id="3890664840433101773">افزودن ایمیل</translation>
<translation id="3901925938762663762">کارت منقضی شده است</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">در این سایت، همیشه سؤال شود</translation>
<translation id="3949571496842715403">‏این سرور نتوانست ثابت کند که <ph name="DOMAIN" /> است؛ در گواهی امنیتی آن، Subject Alternative Names مشخص نشده است. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط مهاجم ایجاد شده باشد.</translation>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{هیچ‌کدام}=1{از ۱ سایت }one{از # سایت }other{از # سایت }}</translation>
<translation id="397105322502079400">در حال محاسبه…</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> مسدود است</translation>
-<translation id="3984550557525787191">این نام جلسه از قبل وجود دارد.</translation>
<translation id="3987940399970879459">کمتر از ۱ مگابایت</translation>
+<translation id="4008849406247176967">اخطار: برای این خط‌مشی، بیش از یک منبع حاوی مقادیر مغایر موجود است!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ ۱ صفحه وب در این نزدیکی است}one{ # صفحه وب در این نزدیکی است}other{ # صفحه وب در این نزدیکی است}}</translation>
<translation id="4030383055268325496">&amp;واگرد افزودن</translation>
+<translation id="4032320456957708163">مرورگرتان توسط <ph name="ENROLLMENT_DOMAIN" /> مدیریت می‌شود</translation>
<translation id="4058922952496707368">کلید "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">افزودن نشانی معتبر</translation>
<translation id="4072486802667267160">هنگام پردازش سفارش شما خطایی روی داد. لطفاً دوباره امتحان کنید.</translation>
<translation id="4075732493274867456">‏کلاینت و سرور از مجموعه رمزگذاری یا نسخه پروتکل SSL مشترکی استفاده نمی‌کنند.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">بنفش</translation>
<translation id="4165986682804962316">تنظیمات سایت</translation>
<translation id="4171400957073367226">امضای تأیید نامناسب</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> مورد دیگر}one{<ph name="ITEM_COUNT" /> مورد دیگر}other{<ph name="ITEM_COUNT" /> مورد دیگر}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;انجام مجدد انتقال</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />بررسی پیکربندی آنتی‌ویروس و دیوار آتش<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">‏&lt;h4&gt;مرحله ۱: به سیستم پورتال وارد شوید&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">بازنشانی گذرواژه</translation>
<translation id="4280429058323657511">، انقضا <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{‏این کارت در حساب Google ذخیره شده است}one{‏این کارت‌ها در حساب Google ذخیره شده‌اند}other{‏این کارت‌ها در حساب Google ذخیره شده‌اند}}</translation>
+<translation id="42981349822642051">بزرگ کردن</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">جابه‌جایی</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">مسدود کردن (پیش‌فرض)</translation>
+<translation id="4318566738941496689">نام دستگاه و نشانی شبکه شما</translation>
<translation id="4325863107915753736">مقاله یافت نشد.</translation>
<translation id="4326324639298822553">تاریخ انقضا را بررسی و دوباره امتحان کنید</translation>
<translation id="4331708818696583467">امن نیست</translation>
<translation id="4340982228985273705">‏این رایانه به‌صورت سازمانی مدیریت نمی‌شود، بنابراین خط‌مشی تنها می‌تواند به‌صورت خودکار افزونه‌های میزبانی‌شده در «نت‌بازار Chrome» را نصب کند. نشانی وب به‌روزرسانی «نت‌بازار Chrome» «<ph name="CWS_UPDATE_URL" />» است.</translation>
<translation id="4346197816712207223">کارت‌های اعتباری قابل‌‌قبول</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">مهاجم‌ها در این سایت ممکن است تلاش کنند برنامه‌های خطرناکی در رایانه شما نصب کنند که اطلاعات شما (مانند عکس‌ها، گذرواژه‌ها، پیام‌ها و کارت‌های اعتباری) را به سرقت می‌برند یا حذف می‌کنند.</translation>
<translation id="4358461427845829800">مدیریت روش‌های پرداخت…</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">مقدار مورد انتظار <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">شما سعی در دسترسی به <ph name="DOMAIN" /> را داشتید، اما صادر کننده، گواهی ارائه شده از سوی سرور را باطل کرده است. یعنی اصلاً نباید به اطلاعات کاربری که این سرور ارائه می‌کند اطمینان کرد. ممکن است شما با مهاجمی در ارتباط باشید.</translation>
<translation id="4378154925671717803">تلفن</translation>
<translation id="4406896451731180161">نتایج جستجو</translation>
-<translation id="4406972042435603828">سرپرستتان افزونه‌هایی با قابلیت‌های قدرتمندی نصب کرده است.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> کوکی</translation>
<translation id="4415426530740016218">نشانی تحویل گرفتن</translation>
<translation id="4424024547088906515">‏این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن مورداعتماد Chrome نیست. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجی اتصال شما را قطع کرده است.</translation>
+<translation id="443121186588148776">درگاه سریالی</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> گواهی ورود به سیستمتان را نپذیرفت یا ممکن است گواهی‌ای ارائه نشده باشد.</translation>
<translation id="4434045419905280838">پنجره‌های بازشو و هدایت‌ها</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">استفاده از پروکسی غیرفعال است اما یک پیکربندی خاص برای پروکسی تعیین شده است.</translation>
<translation id="445100540951337728">کارت‌های نقدی قابل‌قبول</translation>
+<translation id="4466881336512663640">تغییرات فرم از بین می‌رود. مطمئن هستید می‌خواهید ادامه دهید؟</translation>
<translation id="4482953324121162758">این سایت ترجمه نخواهد شد.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">‏نشانی وب نامعتبر است. باید نشانی وبی با طرحی استاندارد مانند http://example.com یا https://example.com باشد.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">خطای ارزیابی: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">تماس با سرپرست سیستم</translation>
<translation id="450710068430902550">اشتراک‌گذاری با سرپرست سیستم</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">‏کارت‌ها و نشانی‌ها از Chrome و حساب Google شما (<ph name="ACCOUNT_EMAIL" />) هستند. می‌توانید آن‌ها را در <ph name="BEGIN_LINK" />تنظیمات<ph name="END_LINK" /> مدیریت کنید.</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">جزئیات</translation>
<translation id="4524805452350978254">مدیریت کارت‌ها</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">افزونه‌ها را غیرفعال کنید.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">ارسال</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">برداشتن کارت</translation>
<translation id="4587425331216688090">‏آدرس از Chrome پاک شود؟</translation>
<translation id="4592951414987517459">اتصال شما به <ph name="DOMAIN" /> با استفاده از یک مجموعه رمز مدرن، رمزگذاری شده است.</translation>
<translation id="4594403342090139922">&amp;واگرد حذف</translation>
<translation id="4597348597567598915">اندازه ۸</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">اکنون من را به آنجا ببر</translation>
<translation id="4668929960204016307">،</translation>
<translation id="467662567472608290">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ گواهی امنیتی آن خطاهایی دارد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
<translation id="467809019005607715">‏اسلایدنگار Google</translation>
<translation id="4690462567478992370">توقف استفاده از گواهینامه نامعتبر</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">اتصال شما قطع شد</translation>
<translation id="471880041731876836">برای بازدید کردن از این سایت، مجوز لازم ندارید</translation>
<translation id="4722547256916164131">‏<ph name="BEGIN_LINK" />در حال اجرای Windows Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">تازه‌سازی خط مشی‌ها</translation>
<translation id="4728558894243024398">پلت فورم</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">‏Chromium را راه‌اندازی مجدد کنید</translation>
<translation id="473775607612524610">به‌روزرسانی</translation>
<translation id="4738601419177586157">پیشنهاد جستجوی <ph name="TEXT" /></translation>
<translation id="4742407542027196863">مدیریت گذرواژه‌ها…</translation>
<translation id="4744603770635761495">مسیر قابل اجرا</translation>
+<translation id="4746351372139058112">پیام‌ها</translation>
<translation id="4750917950439032686">اطلاعات شما (به‌عنوان مثال، گذرواژه‌ها یا شماره‌ کارت‌های اعتباری) وقتی به این سایت ارسال می‌شوند، خصوصی هستند.</translation>
<translation id="4756388243121344051">&amp;سابقه</translation>
<translation id="4758311279753947758">افزودن اطلاعات تماس</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">ممکن است صفحهٔ وب <ph name="URL" /> موقتاً خراب باشد یا ممکن است برای همیشه به آدرس وب جدید منتقل شده باشد.</translation>
<translation id="4771973620359291008">خطای ناشناخته‌ای رخ داد.</translation>
<translation id="4785689107224900852">جابجا شدن به این برگه</translation>
-<translation id="4792143361752574037">مشکلی در دسترسی به فایل‌های جلسه وجود داشت. درحال‌حاضر ذخیره‌سازی در دیسک غیرفعال است. لطفاً برای امتحان مجدد، صفحه را تازه‌سازی کنید.</translation>
<translation id="4798078619018708837">‏برای به‌روزرسانی جزئیات کارت، تاریخ انقضا و CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید کردن، جزئیات کارت از حساب Google شما با این سایت هم‌رسانی می‌شود.</translation>
<translation id="4800132727771399293">‏تاریخ انقضا و CVC را بررسی کرده و دوباره امتحان کنید</translation>
+<translation id="480334179571489655">خطای خط‌‌مشی اصلی</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">باز کردن</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">نتیجه‌ای پیدا نشد</translation>
<translation id="4950898438188848926">‏دکمه جابه‌جایی برگه، برای جابه‌جایی به برگه باز، کلید Enter را فشار دهید، <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">کنش‌ها</translation>
-<translation id="495832697253704892">گزارش افزونه</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">بزرگ کردن فهرست</translation>
<translation id="4974590756084640048">فعال کردن مجدد اخطارها</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">دیدن همه</translation>
<translation id="4989809363548539747">این افزایه پشتیبانی نمی‌شود</translation>
-<translation id="4996230189582812866">گزارش‌دهی</translation>
<translation id="5002932099480077015">‏اگر فعال شود، Chrome یک کپی از کارت شما را برای پرکردن سریع‌تر فرم در این دستگاه ذخیره می‌کند.</translation>
-<translation id="5014174725590676422">‏صفحه اولین اجرای «دستیار Google» در Chrome نشان داده می‌شود</translation>
<translation id="5015510746216210676">نام ماشین:</translation>
+<translation id="5017554619425969104">نوشتاری که کپی کرده‌اید</translation>
<translation id="5018422839182700155">این صفحه نمی‌تواند باز شود</translation>
<translation id="5019198164206649151">پشتیبان‌گیری ذخیره در وضعیت نادرست است</translation>
<translation id="5023310440958281426">خط‌مشی‌های سرپرست سیستمتان را بررسی کنید</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">بافت محلی <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">اجازه دادن</translation>
<translation id="5040262127954254034">حریم خصوصی</translation>
+<translation id="5043480802608081735">پیوندی که کپی کرده‌اید</translation>
<translation id="5045550434625856497">گذرواژه نادرست</translation>
<translation id="5056549851600133418">مقالاتی برای شما</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />بررسی آدرس پروکسی<ph name="END_LINK" /></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="5097099694988056070">‏آمار دستگاه مانند استفاده از CPU یا RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">دستگاهتان توسط <ph name="ENROLLMENT_DOMAIN" /> مدیریت می‌شود و حسابتان توسط <ph name="ACCOUNT_DOMAIN" /> مدیریت می‌شود. این یعنی سرپرستتان می‌تواند دستگاه و حسابتان را ازراه‌دور پیکربندی کند.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(۶۴ بیت)</translation>
-<translation id="5128122789703661928">جلسه‌ای با این نام، برای حذف معتبر نیست.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">مدیریت نشانی‌ها…</translation>
+<translation id="5138227688689900538">نمایش موارد کمتر</translation>
<translation id="5141240743006678641">‏رمزگذاری گذرواژه‌های همگام‌سازی شده با اطلاعات کاربری Google شما</translation>
<translation id="5145883236150621069">کد خطا در پاسخ خط‌مشی موجود است</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">‏صفحه را در پنجره «ناشناس» جدیدی باز کنید (N⌘⇧)</translation>
<translation id="516920405563544094">‏CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید کردن، جزئیات کارت از حساب Google شما با این سایت هم‌رسانی می‌شود.</translation>
<translation id="5169827969064885044">‏ممکن است دسترسی به حساب سازمانتان را از دست بدهید یا به سرقت هویت دچار شوید. Chrome توصیه می‌کند هم‌اکنون گذرواژه‌تان را تغییر دهید.</translation>
<translation id="5171045022955879922">‏جستجو یا تایپ URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">دستگاه</translation>
<translation id="5179510805599951267">به زبان <ph name="ORIGINAL_LANGUAGE" /> نیست؟ گزارش این خطا</translation>
<translation id="5190835502935405962">نوار نشانک‌ها</translation>
-<translation id="5200263511887412697">فهرست کاربران دستگاه را که اخیراً وارد سیستم شده‌اند گزارش می‌دهد</translation>
+<translation id="519422657042045905">حاشیه‌نویسی دردسترس نیست</translation>
<translation id="5201306358585911203">صفحه جاسازی‌شده‌ای در این صفحه می‌گوید</translation>
<translation id="5205222826937269299">نام ضروری است</translation>
<translation id="5215116848420601511">‏روش‌های پرداخت و نشانی‌های مورداستفاده در Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ایمیل ضروری است</translation>
<translation id="5230733896359313003">نشانی تحویل کالا</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">«به شبکه متصل شوید»</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">نشانی‌های شبکه</translation>
<translation id="5285570108065881030">نمایش همه گذرواژه‌های ذخیره‌شده</translation>
<translation id="5287240709317226393">نمایش کوکی‌ها</translation>
<translation id="5288108484102287882">اعتبارسنجی مقادیر خط‌مشی با چند هشدار به پایان رسید</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> از <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">انتخاب اطلاعات تماس</translation>
<translation id="5327248766486351172">نام</translation>
+<translation id="5329858041417644019">مرورگرتان مدیریت نمی‌شود</translation>
<translation id="5332219387342487447">روش ارسال کالا</translation>
+<translation id="5334013548165032829">گزارش دقیق سیستم</translation>
<translation id="5344579389779391559">این صفحه ممکن است تلاش کند از شما پول دریافت کند</translation>
<translation id="5355557959165512791">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا گواهینامه آن لغو شده است. معمولاً خطاهای شبکه و حمله‌ها موقتی هستند، بنابراین احتمالاً این صفحه بعداً کار خواهد کرد.</translation>
<translation id="536296301121032821">تنظیمات خط‌‌مشی ذخیره نشد</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">‏«ساعتتان عقب است» یا «ساعتتان جلو است» یا «&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;»</translation>
<translation id="5384855140246857529">برای اینکه از کارت‌هایتان در همه دستگاه‌ها استفاده کنید، به سیستم وارد شوید و همگام‌سازی را روشن کنید.</translation>
<translation id="5386426401304769735">‏زنجیره گواهی این سایت حاوی یک گواهی با امضای SHA-1 است.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">این سرور نتوانست ثابت کند که <ph name="DOMAIN" /> است؛ در حال حاضر، گواهی امنیتی آن معتبر نیست. ممکن است این مشکل به دلیل پیکربندی نادرست یا قطع اتصال شما توسط حمله‌کننده ایجاد شده باشد.</translation>
<translation id="5421136146218899937">پاک کردن داده‌های مرور...</translation>
<translation id="5430298929874300616">حذف نشانک</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">نامعتبر</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;انجام مجدد ویرایش</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">شاید این محتوا تلاش کند نرم‌افزار خطرناکی در دستگاهتان نصب کند که اطلاعاتتان را به سرقت برد یا حذف کند. <ph name="BEGIN_LINK" />درهرصورت نمایش داده شود<ph name="END_LINK" /></translation>
<translation id="54817484435770891">نشانی معتبری اضافه کنید</translation>
<translation id="5490432419156082418">نشانی‌ها و سایر موارد</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
با سرپرست سیستم تماس بگیرید.</translation>
<translation id="549333378215107354">اندازه ۳</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">نشانک‌های مدیریت شده</translation>
<translation id="5510766032865166053">ممکن است جابه‌جا یا حذف شده باشد.</translation>
<translation id="5523118979700054094">نام خط‌مشی</translation>
<translation id="552553974213252141">آیا نوشتار به درستی استخراج شده است؟</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">مقاله درخواستی یافت نشد.</translation>
<translation id="5541546772353173584">افزودن ایمیل</translation>
<translation id="5545756402275714221">مقاله‌هایی برای شما</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">ویرایش آدرس</translation>
<translation id="5598944008576757369">انتخاب روش پرداخت</translation>
<translation id="560412284261940334">مدیریت پشتیبانی نمی‌شود</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">بررسی اتصال</translation>
<translation id="5610807607761827392">می‌توانید در <ph name="BEGIN_LINK" />تنظیمات<ph name="END_LINK" />، کارت‌ها و نشانی‌ها را مدیریت کنید.</translation>
<translation id="5617949217645503996">تعداد دفعاتی که <ph name="HOST_NAME" /> شما را به نشانی‌های دیگر هدایت کرده بیش از حد است.</translation>
<translation id="5629630648637658800">تنظیمات خط‌مشی بارگیری نشد</translation>
<translation id="5631439013527180824">نشانه مدیریت دستگاه نامعتبر است</translation>
+<translation id="5632627355679805402">‏داده‌ها با <ph name="BEGIN_LINK" />گذرواژه Google<ph name="END_LINK" /> شما از <ph name="TIME" /> رمز می‌شود. برای شروع همگام‌سازی، آن را وارد کنید.</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="563324245173044180">محتوای فریب‌دهنده مسدود شد.</translation>
<translation id="5659593005791499971">ایمیل</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">سرپرست این دستگاه، افزونه‌هایی را برای عملکردهای اضافی نصب کرده است. افزونه‌ها به برخی از داده‌های شما دسترسی دارند.</translation>
<translation id="5675650730144413517">این صفحه کار نمی‌کند</translation>
+<translation id="5684874026226664614">متأسفیم. این صفحه ترجمه نشد.</translation>
<translation id="5685654322157854305">افزودن نشانی تحویل کالا</translation>
<translation id="5689199277474810259">‏صادر کردن به JSON</translation>
<translation id="5689516760719285838">مکان</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">هویت این وب سایت تأیید نشده است.</translation>
<translation id="5719499550583120431">کارت‌های پیش‌پرداخت پذیرفته می‌شوند.</translation>
<translation id="5720705177508910913">کاربر کنونی</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">‏Chrome توصیه می‌کند اگر از گذرواژه‌تان در سایت‌های دیگری استفاده کردید آن را بازنشانی کنید.</translation>
<translation id="5732392974455271431">والدینتان می‌توانند این سایت را برای شما بگشایند</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{‏ذخیره کردن کارت در حساب Google شما}one{‏ذخیره کردن کارت‌ها در حساب Google}other{‏ذخیره کردن کارت‌ها در حساب Google}}</translation>
<translation id="5763042198335101085">نشانی ایمیل معتبری وارد کنید</translation>
<translation id="5765072501007116331">برای دیدن روش‌های تحویل و شرایط موردنیاز، یک نشانی انتخاب کنید</translation>
-<translation id="5770114862687765385">به نظر می‌رسد فایل خراب شده باشد. برای بازنشانی جلسه، روی دکمه «بازنشانی» کلیک کنید.</translation>
<translation id="5778550464785688721">‏کنترل کامل دستگاه‌های MIDI</translation>
<translation id="578305955206182703">کهربایی</translation>
<translation id="57838592816432529">بی‌صدا کردن</translation>
<translation id="5784606427469807560">هنگام تأیید کارت مشکلی پیش آمد. اتصال اینترنتتان را بررسی و دوباره امتحان کنید.</translation>
<translation id="5785756445106461925">علاوه بر این، این صفحه دارای منابع دیگری است که امن نیستند. دیگران می‌توانند در حین انتقال، این منابع را ببینند و این منابع می‌توانند برای تغییر قفل صفحه، توسط یک مهاجم تغییر داده شوند.</translation>
<translation id="5786044859038896871">می‌خواهید اطلاعات کارتتان را وارد کنید؟</translation>
+<translation id="5798290721819630480">از تغییرات صرف‌‌نظر می‌کنید؟</translation>
<translation id="5798683403665926540">‏صفحه اصلی را در تنظیمات Chrome تغییر دهید</translation>
<translation id="5803412860119678065">می‌خواهید <ph name="CARD_DETAIL" /> خود را وارد کنید؟</translation>
<translation id="5804241973901381774">مجوزها</translation>
<translation id="5810442152076338065">اتصال شما به <ph name="DOMAIN" /> با استفاده از یک مجموعه رمز منسوخ، رمزگذاری شده است.</translation>
<translation id="5813119285467412249">&amp;انجام مجدد افزودن</translation>
<translation id="5838278095973806738">نباید هیچ اطلاعات حساسی (مثل گذرواژه یا کارت اعتباری) را در این سایت وارد کنید، زیرا ممکن است مهاجمین آن‌ها را سرقت کنند.</translation>
+<translation id="5860033963881614850">خاموش</translation>
<translation id="5863847714970149516">صفحه پیش‌رو ممکن است تلاش کند از شما پول دریافت کند</translation>
<translation id="5866257070973731571">افزودن شماره تلفن</translation>
<translation id="5869405914158311789">دسترسی به این سایت امکان‌پذیر نیست</translation>
<translation id="5869522115854928033">گذرواژه‌های ذخیره‌شده</translation>
<translation id="5887400589839399685">کارت ذخیره‌ شد</translation>
-<translation id="5893718151540690985">فهرستی از واسط‌های شبکه را همراه با نوع و نشانی سخت‌افزاری آن‌ها گزارش می‌کند</translation>
<translation id="5893752035575986141">کارت‌های اعتباری پذیرفته می‌شوند.</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="5916664084637901428">روشن</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">‏کارت در حساب Google ذخیره شود؟</translation>
<translation id="5922853866070715753">تقريباً تمام است</translation>
<translation id="5932224571077948991">سایتْ آگهی‌های مزاحم یا گمراه‌کننده نشان می‌دهد</translation>
-<translation id="5939518447894949180">بازنشانی</translation>
<translation id="5946937721014915347">درحال باز کردن <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">نمی‌توان با حساب مصرف‌کننده ثبت‌نام کرد (مجوز بسته‌بندی دردسترس است).</translation>
<translation id="5967592137238574583">ویرایش اطلاعات تماس</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">دورنمایی کردن</translation>
<translation id="5977489021191000276">دستگاهتان توسط سرپرست مدیریت نمی‌شود.</translation>
<translation id="5977976211062815271">در این دستگاه</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">برنامه پرداخت باز نشد</translation>
<translation id="5989320800837274978">‏سرور پروکسی ثابت و URL اسکریپت pac. تعیین نشده‌اند.</translation>
<translation id="5990559369517809815">درخواست‌های ارسالی به سرور توسط یک برنامهٔ افزودنی مسدود شد.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">‏آمار سخت‌افزاری مانند استفاده از CPU یا RAM را گزارش می‌کند</translation>
<translation id="6034000775414344507">خاکستری کم‌رنگ</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">اگر مشکل ادامه دارد، با مالک سایت تماس بگیرید.</translation>
<translation id="6040143037577758943">بستن</translation>
<translation id="6044573915096792553">اندازه ۱۲</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">درحال‌حاضر نمی‌توانید از <ph name="SITE" /> دیدن کنید، زیرا وب‌سایت از پین کردن گواهینامه استفاده می‌کند. خطاهای شبکه و حمله‌ها موقتی هستند، بنابراین احتمالاً این صفحه بعداً کار خواهد کرد.</translation>
<translation id="6058977677006700226">از کارت‌ها در همه دستگاه‌هایتان استفاده شود؟</translation>
<translation id="6059925163896151826">‏دستگاه‌های USB</translation>
-<translation id="6071091556643036997">نوع خط‌مشی نامعتبر است.</translation>
<translation id="6080696365213338172">شما با استفاده از گواهی ارائه شده توسط سرپرست سیستم به محتوا دسترسی پیدا کرده‌اید. داده‌هایی که به <ph name="DOMAIN" /> ارائه می‌کنید ممکن است توسط سرپرست سیستم رهگیری شوند.</translation>
<translation id="6094273045989040137">حاشیه‌نویسی</translation>
<translation id="610911394827799129">‏ممکن است حساب Google شما اشکال دیگری از سابقه مرور در <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> داشته باشد</translation>
+<translation id="6132597952260690497">اطلاعات مربوط به افزونه‌ها و افزایه‌های نصب‌شده</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{هیچ‌کدام}=1{۱ گذرواژه (همگام‌سازی‌شده)}one{# گذرواژه (همگام‌سازی‌شده)}other{# گذرواژه (همگام‌سازی‌شده)}}</translation>
<translation id="6146055958333702838">همه کابل‌ها را بررسی کنید و همه ره‌یاب‌ها، مودم‌ها، یا دیگر دستگاه‌های
 شبکه‌ای را که ممکن است درحال استفاده از آن‌ها باشید مجدداً راه‌اندازی کنید.</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">کمتر از <ph name="SIZE" /> از فضا را آزاد می‌کند. ممکن است برخی از سایت‌ها در بازدیدهای بعدی کندتر بارگیری شوند.</translation>
<translation id="6337534724793800597">فیلتر کردن خط‌مشی‌ها براساس نام</translation>
<translation id="6358450015545214790">معنی این‌ها چیست؟</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">احتمالاً هزینه‌هایی اعمال می‌شود.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{۱ پیشنهاد دیگر}one{# پیشنهاد دیگر}other{# پیشنهاد دیگر}}</translation>
<translation id="6387754724289022810">‏برای اینکه دفعات بعد پرداخت سریع‌تری داشته باشید، اطلاعات کارت و نشانی صورت‌حسابتان را در حساب Google خود و این دستگاه ذخیره کنید.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">ویرایش نشانک</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377">‏CVC‏ و تاریخ انقضای <ph name="CREDIT_CARD" /> را وارد کنید</translation>
<translation id="6414888972213066896">از والدینتان پرسیدید آیا اجازه بازدید از این سایت را دارید</translation>
<translation id="6417515091412812850">امکان بررسی اینکه آیا مجوز باطل شده است یا نه وجود ندارد.</translation>
<translation id="6433490469411711332">ویرایش اطلاعات تماس</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> از اتصال خودداری کرد.</translation>
+<translation id="6434309073475700221">رد کردن</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">افزودن اطلاعات بیشتر</translation>
<translation id="6447842834002726250">کوکی‌ها</translation>
<translation id="6451458296329894277">تأیید ارسال مجدد فرم</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">‏Chrome را راه‌اندازی مجدد کنید</translation>
<translation id="6529602333819889595">&amp;انجام مجدد حذف</translation>
<translation id="6534179046333460208">پیشنهادهای «وب فیزیکی»</translation>
+<translation id="6556866813142980365">انجام مجدد</translation>
<translation id="6563469144985748109">مدیرتان هنوز این سایت را تأیید نکرده است</translation>
<translation id="6569060085658103619">درحال مشاهده یک صفحه افزونه هستید</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">صورتی کم‌رنگ</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">پیوندی که کپی کرده‌اید</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> شما تحت مدیریت نیست</translation>
<translation id="6596325263575161958">گزینه‌های رمزگذاری</translation>
<translation id="6604181099783169992">حسگرهای نوری یا حرکتی</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">اطلاعات تماس</translation>
<translation id="6626291197371920147">افزودن شماره کارت معتبر</translation>
<translation id="6628463337424475685">جستجوی <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">این قانون قدیمی شده است.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{هیچ‌کدام}=1{‏از ۱ سایت (از سیستم حساب Google خود خارج نخواهید شد)}one{‏از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}other{‏از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}}</translation>
<translation id="6657585470893396449">گذرواژه</translation>
+<translation id="6670613747977017428">بازگشت به ایمنی.</translation>
<translation id="6671697161687535275">‏پیشنهاد فرم از Chromium پاک شود؟</translation>
<translation id="6685834062052613830">خروج از سیستم و تکمیل راه‌اندازی</translation>
<translation id="6710213216561001401">قبلی</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">کد ثبت‌نام:</translation>
<translation id="6711464428925977395">مشکلی در سرور پروکسی وجود دارد یا این آدرس درست نیست.</translation>
<translation id="6723740634201835758">‏در حساب Google</translation>
+<translation id="6738516213925468394">داده‌ها با <ph name="BEGIN_LINK" />گذرنویسه همگام‌سازی‌شده<ph name="END_LINK" /> شما در <ph name="TIME" /> رمز می‌شود. برای شروع همگام‌سازی، آن را وارد کنید.</translation>
<translation id="674375294223700098">خطای ناشناس گواهی سرور.</translation>
<translation id="6744009308914054259">وقتی درانتظار اتصال هستید، می‌توانید برای خواندن مقاله‌های آفلاین، «بارگیری‌ها» را مشاهده کنید.</translation>
<translation id="6753269504797312559">مقدار خط‌‌مشی</translation>
<translation id="6757797048963528358">دستگاهتان به خواب رفته است.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">والدینتان هنوز این سایت را تأیید نکرده‌اند</translation>
<translation id="67862343314499040">بنفش</translation>
+<translation id="6786747875388722282">افزونه‌ها</translation>
<translation id="679355240208270552">نادیده گرفته شد، زیرا جستجوی پیش‌فرض توسط خط‌مشی فعال نشده است.</translation>
<translation id="681021252041861472">فیلد ضروری</translation>
<translation id="6810899417690483278">شناسه سفارشی‌سازی</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">دستگاه</translation>
<translation id="6970216967273061347">منطقه</translation>
<translation id="6973656660372572881">‏هم سرورهای پروکسی ثابت و هم آدرس اسکریپت pac. مشخص شده‌اند.</translation>
+<translation id="6973932557599545801">متأسفم، نمی‌توانم کمک کنم، لطفاً خودتان ادامه دهید.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">بی‌صدا (پیش‌فرض)</translation>
<translation id="6984479912851154518">درحال خروج از حالت ناشناس، برای پرداخت ازطریق برنامه‌ای خارجی. ادامه می‌دهید؟</translation>
<translation id="6989763994942163495">نمایش تنظیمات پیشرفته ...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> همیشه ترجمه شود</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">ممکن است این هزینه‌ها یک‌باره یا تکرارشونده باشند و واضح نباشند.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">عدم نمایش</translation>
<translation id="7108819624672055576">توسط افزونه مجاز شده است</translation>
<translation id="7111012039238467737">(معتبر)</translation>
+<translation id="7118618213916969306">جستجوی نشانی وب بریده‌دان، <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">برگه‌ها یا برنامه‌های دیگر را ببندید</translation>
<translation id="7129409597930077180">ارسال به این نشانی ممکن نیست. نشانی دیگری را انتخاب کنید.</translation>
<translation id="7135130955892390533">نمایش وضعیت</translation>
<translation id="7138472120740807366">روش تحویل</translation>
<translation id="7139724024395191329">امارات</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">نیلی کم‌رنگ</translation>
-<translation id="7158980942472052083">نشانی وب نامعتبر است. باید یک نشانی وب با طرح استاندارد باشد.</translation>
<translation id="717330890047184534">‏شناسه Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">سروری که به آن می‌روید، <ph name="ORIGIN" />، درخواست کرده است
+ برای همه درخواست‌هایش خط‌مشی ایمنی اعمال شود. اما به‌جای
+ ارسال خط‌مشی، مرورگر را به جای دیگری هدایت کرده است، که مانع می‌شود
+ مرورگر درخواستتان را از <ph name="SITE" /> برآورده کند.</translation>
<translation id="7179323680825933600">ذخیره و تکمیل روش‌های پرداخت</translation>
<translation id="7180611975245234373">بازخوانی</translation>
<translation id="7182878459783632708">هیچ خط‌مشی‌ای تنظیم نشده است</translation>
<translation id="7186367841673660872">این صفحه از <ph name="ORIGINAL_LANGUAGE" /> به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> از فضا را آزاد می‌کند. ممکن است برخی از سایت‌ها در بازدیدهای بعدی کندتر بارگیری شوند.</translation>
<translation id="719464814642662924">ویزا</translation>
+<translation id="7201591969684833065">سرپرستتان می‌تواند این موارد را ببیند:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> از استانداردهای امنیتی پیروی نمی‌کند.</translation>
<translation id="721197778055552897">دربارهٔ این مشکل <ph name="BEGIN_LINK" />بیشتر بیاموزید<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">اتصال از <ph name="SSL_VERSION" /> استفاده می‌کند.</translation>
<translation id="7220786058474068424">درحال پردازش</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />؛ <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">این وب‌سایت بدافزار دارد</translation>
+<translation id="724766306220616965">هشدارها، تداخل</translation>
<translation id="724975217298816891">‏برای به‌روزرسانی جزئیات کارتتان، تاریخ انقضا و CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید شدن، جزئیات کارتتان با این سایت به اشتراک گذاشته می‌شود.</translation>
<translation id="7251437084390964440">‏پیکربندی شبکه با استاندارد ONC مطابقت ندارد. ممکن است بعضی از قسمت‌های پیکربندی وارد نشود.
توضیحات بیشتر:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">آبی پررنگ</translation>
<translation id="7302712225291570345">«<ph name="TEXT" />»</translation>
<translation id="7309308571273880165">گزارش خرابی ثبت‌شده در <ph name="CRASH_TIME" /> (کاربر درخواست بارگذاری کرده است، هنوز بارگذاری نشده است)</translation>
+<translation id="7313965965371928911">هشدار <ph name="BEGIN_LINK" />مرور ایمن<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">راهنمای اتصال</translation>
<translation id="7334320624316649418">&amp;انجام مجدد ترتیب‌بندی مجدد</translation>
<translation id="733923710415886693">گواهی سرور از طریق شفافیت گواهینامه نشان داده نشده بود.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">خط فرمان</translation>
-<translation id="7365061714576910172">‏صادر کردن Linux</translation>
<translation id="7372973238305370288">نتیجه جستجو</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">نه</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">لغو جلسه مدیریت‌شده</translation>
<translation id="7390545607259442187">تأیید کارت</translation>
<translation id="7400418766976504921">نشانی وب</translation>
+<translation id="7403591733719184120">دستگاه <ph name="DEVICE_NAME" /> تحت مدیریت است</translation>
<translation id="7407424307057130981">‏&lt;p&gt;اگر در رایانه Windows نرم‌افزار Superfish داشته باشید، این خطا را می‌بینید.&lt;/p&gt;
&lt;p&gt;برای غیرفعال کردن موقت این نرم‌افزار و دسترسی به وب، این مراحل را دنبال کنید. لازم است امتیازهای سرپرست را داشته باشید.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;روی &lt;strong&gt;اعمال&lt;/strong&gt; و سپس &lt;strong&gt;تأیید&lt;/strong&gt; کلیک کنید
&lt;li&gt;برای آشنایی با نحوه برداشتن دائم نرم‌افزار از رایانه، از &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;مرکز راهنمای ‏Chrome‏&lt;/a&gt; بازدید کنید
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">مدیریت <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">مدیریت گذرواژه‌ها…</translation>
<translation id="7419106976560586862">مسیر نمایه</translation>
<translation id="7437289804838430631">افرودن اطلاعات تماس</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">نارنجی روشن</translation>
<translation id="7444046173054089907">این سایت مسدود شده است</translation>
<translation id="7445762425076701745">هویت سروری که به آن متصل شده‌اید به‌طور کامل راستی‌آزمایی نمی‌شود. با استفاده از نامی به سرور متصل شده‌اید که فقط در شبکه شما معتبر است و ارائه دهنده مجوز خارجی قادر به راستی‌آزمایی مالکیت آن نیست. به دلیل آنکه برخی از ارائه دهندگان مجوز بدون توجه به هر موردی، مجوزهایی را برای این نام‌ها ارائه می‌کنند، روشی برای اطمینان از این امر وجود ندارد که آیا شما به سایت موردنظر خود متصل شده‌اید یا یک سایت مضر.</translation>
-<translation id="7449109375006139765">گزارش‌های سیستم را به سرور مدیریت ارسال کند</translation>
<translation id="7451311239929941790">درباره این مشکل <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">استفاده از پیش‌فرض جهانی (مسدود)</translation>
<translation id="7460618730930299168">فیلم در حال نمایش با آنچه انتخاب کرده‌اید متفاوت است. ادامه می‌دهید؟</translation>
<translation id="7473891865547856676">نه متشکرم</translation>
-<translation id="7475525192983021547">دوره‌های زمانی را که کاربر در دستگاه فعال بوده است گزارش می‌کند</translation>
<translation id="7481312909269577407">ارسال کردن</translation>
<translation id="7485870689360869515">هیچ داده‌ای یافت نشد.</translation>
+<translation id="7498234416455752244">ادامه ویرایش</translation>
<translation id="7508255263130623398">شناسه دستگاه خط‌مشی برگردانده‌شده خالی است یا با شناسه کنونی دستگاه مطابقت ندارد</translation>
<translation id="7508870219247277067">سبز مایل به زرد</translation>
<translation id="7511955381719512146">‏شبکه Wi-Fi مورد استفاده‌تان احتمالاً نیاز دارد که به صفحه <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> بروید.</translation>
<translation id="7514365320538308">بارگیری</translation>
<translation id="7518003948725431193">صفحه وبی با این آدرس وب یافت نشد: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">جاوا اسکریپت</translation>
<translation id="7526934274050461096">اتصال شما به این سایت خصوصی نیست</translation>
+<translation id="7535087603100972091">مقدار</translation>
<translation id="7537536606612762813">اجباری</translation>
+<translation id="7538364083937897561">A2 (Envelope)</translation>
<translation id="7542403920425041731">بعد از تأیید شما، جزئیات کارتتان با این سایت به اشتراک گذاشته می‌شود.</translation>
<translation id="7542995811387359312">تکمیل خودکار کارت اعتباری غیر فعال است زیرا این فرم از یک اتصال امن استفاده نمی‌کند.</translation>
<translation id="7543525346216957623">از والدینتان بخواهید این کار را انجام دهد</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">نکته‌های زیر را امتحان کنید:</translation>
<translation id="7554791636758816595">برگهٔ جدید</translation>
<translation id="7564049878696755256">‏ممکن است دسترسی به حساب <ph name="ORG_NAME" /> را از دست بدهید یا به سرقت هویت دچار شوید. Chrome توصیه می‌کند هم‌اکنون گذرواژه‌تان را تغییر دهید.</translation>
-<translation id="7566125604157659769">نوشتاری که کپی کرده‌اید</translation>
<translation id="7567204685887185387">این سرور نتوانست اثبات کند که این <ph name="DOMAIN" /> است؛ ممکن است گواهی امنیتی آن به صورت تقلبی صادر شده باشد. ممکن است علت این موضوع پیکربندی اشتباه باشد یا مهاجمی اتصال شما را قطع کرده است.</translation>
+<translation id="7568105740864181217">‏این مرورگر توسط شرکت، مدرسه یا سازمان دیگری مدیریت می‌شود. سرپرستتان می‌تواند تنظیم مرورگرتان را ازراه‌دور تغییر دهد. همچنین ممکن است فعالیت در این دستگاه خارج از Chrome مدیریت شود. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">‏کارت اعتباری از Chrome پاک شود؟</translation>
<translation id="7569983096843329377">سیاه</translation>
<translation id="7578104083680115302">‏با استفاده از کارت‌هایی که با Google ذخیره کرده‌اید به‌سرعت در همه دستگاه‌هایتان پرداخت‌های سایت‌ها و برنامه‌ها را انجام دهید.</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">داده‌های عملکرد و گزارش‌های خرابی</translation>
<translation id="7637571805876720304">‏کارت اعتباری از Chromium پاک شود؟</translation>
<translation id="7639968568612851608">خاکستری تیره</translation>
<translation id="765676359832457558">پنهان کردن تنظیمات پیشرفته…</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">کد خط‌مشی برگردانده‌شده خالی است یا با کد کنونی مطابقت ندارد</translation>
<translation id="7668654391829183341">دستگاه ناشناس</translation>
<translation id="7669271284792375604">مهاجمان در این سایت ممکن است تلاش کنند شما را با نصب برنامه‌هایی که به تجربه مرور شما آسیب می‌رساند، فریب دهند (مثلاً با تغییر دادن صفحه اصلی شما یا با نشان دادن آگهی‌های بیش از حد در سایت‌هایی که بازدید می‌کنید).</translation>
+<translation id="7676643023259824263">جستجوی نوشتار بریده‌دان، <ph name="TEXT" /></translation>
<translation id="7681101578153515023">موتور جستجو را تغییر دهید</translation>
<translation id="7682287625158474539">ارسال</translation>
<translation id="7687186412095877299">فرم‌های پرداخت را با روش‌های پرداخت ذخیره‌شده‌تان پر می‌کند</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">درحال‌حاضر، کارت‌هایی دارید که فقط در این دستگاه قابل استفاده‌اند. برای ادامه مرور کارت‌ها، کلیک کنید.</translation>
<translation id="7699293099605015246">مقاله‌ها درحال‌حاضر دردسترس نیستند</translation>
<translation id="7701040980221191251">هیچ‌کدام</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">محتوای خطرناک مسدود شد.</translation>
<translation id="7752995774971033316">مدیریت نشده</translation>
<translation id="7755287808199759310">والدینتان می‌توانند این سایت را برای شما بگشایند</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">دیوار آتش یا نرم‌افزار ضدویروس ممکن است مانع اتصال شده باشد.</translation>
<translation id="7759163816903619567">نمایش دامنه:</translation>
<translation id="7761701407923456692">گواهی سرور با نشانی وب مطابقت ندارد.</translation>
<translation id="7763386264682878361">تجزیه‌کننده مانیفست پرداخت</translation>
<translation id="7764225426217299476">افزودن آدرس</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">اداره ریاست</translation>
<translation id="7791543448312431591">افزودن</translation>
<translation id="7793809570500803535">ممکن است صفحهٔ وب در <ph name="SITE" /> موقتاً خراب باشد یا ممکن است برای همیشه به یک آدرس وب جدید منتقل شده باشد.</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">‏پیشنهاد فرم از Chrome پاک شود؟</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /><ph name="SEARCH_RESULTS" /> برای «<ph name="SEARCH_STRING" />» پیدا شد</translation>
-<translation id="7818867226424560206">مدیریت خط‌مشی</translation>
<translation id="782886543891417279">‏شبکه Wi-Fi (<ph name="WIFI_NAME" />) مورد استفاده‌تان احتمالاً نیاز دارد که به یک صفحه ورود به سیستم بروید.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{هیچ‌کدام}=1{۱ برنامه (<ph name="EXAMPLE_APP_1" />)}=2{۲ برنامه (<ph name="EXAMPLE_APP_1" />،‏ <ph name="EXAMPLE_APP_2" />)}one{# برنامه (<ph name="EXAMPLE_APP_1" />،‏ <ph name="EXAMPLE_APP_2" />،‏ <ph name="AND_MORE" />)}other{# برنامه (<ph name="EXAMPLE_APP_1" />،‏ <ph name="EXAMPLE_APP_2" />،‏ <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">اما، شما نامرئی نیستید. با استفاده از حالت ناشناس، مرورتان از چشمان کارفرمای شما، ارائه‌دهنده خدمات اینترنت یا وب‌‌سایت‌هایی که بازدید می‌کنید پنهان نمی‌ماند.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">ممکن است گذرواژه‌تان درمعرض خطر باشد</translation>
<translation id="7882421473871500483">قهوه‌ای</translation>
<translation id="7887683347370398519">‏CVC را بررسی کرده و دوباره امتحان کنید</translation>
-<translation id="7893255318348328562">نام جلسه</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">شماره تلفن معتبری وارد کنید</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">در <ph name="EXPIRATION_DATE_ABBR" /> منقضی می‌شود</translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(۳۲ بیت)</translation>
<translation id="7956713633345437162">نشانک‌های تلفن‌ همراه</translation>
<translation id="7961015016161918242">هرگز</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">تعیین نشده</translation>
<translation id="800218591365569300">سعی کنید برگه‌ها یا برنامه‌های دیگر را ببندید تا حافظه آزاد شود.</translation>
+<translation id="8004582292198964060">مرورگر</translation>
<translation id="8009225694047762179">مدیریت گذرواژه</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{این کارت و نشانی صورت‌حساب آن ذخیره می‌شود. وقتی به سیستم <ph name="USER_EMAIL" /> وارد شوید می‌توانید از آن استفاده کنید.}one{این کارت‌ها و نشانی صورت‌حساب آن‌ها ذخیره می‌شود. وقتی به سیستم <ph name="USER_EMAIL" /> وارد شوید می‌توانید از آن‌ها استفاده کنید.}other{این کارت‌ها و نشانی صورت‌حساب آن‌ها ذخیره می‌شود. وقتی به سیستم <ph name="USER_EMAIL" /> وارد شوید می‌توانید از آن‌ها استفاده کنید.}}</translation>
<translation id="8012647001091218357">در حال حاضر نمی‌توانیم با والدینتان ارتباط برقرار کنیم. لطفاً دوباره امتحان کنید.</translation>
<translation id="8025119109950072390">مهاجمان در این سایت ممکن است شما را فریب دهند که کارهای خطرناکی مثل نصب نرم‌افزار یا ارائه اطلاعات شخصی‌تان (مثلاً گذرواژه‌ها، شماره تلفن‌ها یا کارت‌های اعتباری) انجام دهید.</translation>
<translation id="8034522405403831421">این صفحه به زبان <ph name="SOURCE_LANGUAGE" /> است. مایلید آن را به <ph name="TARGET_LANGUAGE" /> ترجمه کنید؟</translation>
<translation id="8035152190676905274">قلم</translation>
+<translation id="8037117624646282037">افرادی که اخیراً از دستگاه استفاده کرده‌اند</translation>
<translation id="8037357227543935929">درخواست (پیش‌فرض)</translation>
<translation id="803771048473350947">فایل</translation>
<translation id="8041089156583427627">ارسال بازخورد</translation>
<translation id="8041940743680923270">استفاده از پیش‌فرض جهانی (سؤال شود)</translation>
<translation id="8042918947222776840">انتخاب روش تحویل گرفتن</translation>
<translation id="8057711352706143257">«<ph name="SOFTWARE_NAME" />» درست پیکربندی نمی‌شود. معمولاً حذف‌ نصب «<ph name="SOFTWARE_NAME" />» مشکل را برطرف می‌کند. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">دستگاهتان برای این موارد پیکربندی شده است:</translation>
+<translation id="8066955247577885446">متأسفیم، مشکلی پیش آمد</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">در حالت چرخش نمی‌توان حاشیه‌نویسی کرد</translation>
<translation id="8079031581361219619">سایت تازه‌سازی شود؟</translation>
<translation id="8088680233425245692">مشاهده مقاله ناموفق بود.</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">فعال‌سازی در سرور در حالت تعلیق است</translation>
<translation id="8092774999298748321">بنفش پررنگ</translation>
<translation id="8094917007353911263">شبکه‌ای که از آن استفاده می‌کنید ممکن است از شما بخواهد که <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> را ببینید.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">کارت‌های نامعتبر برداشته می‌شوند</translation>
<translation id="8103161714697287722">روش پرداخت</translation>
<translation id="8118489163946903409">روش پرداخت</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> تحت مدیریت <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">«<ph name="SOFTWARE_NAME" />» به‌درستی در رایانه یا شبکه‌تان پیکربندی نشد. از سرپرست فناوری اطلاعات خود بخواهید این مشکل را حل کند.</translation>
-<translation id="8130693978878176684">دیگر نمی‌توانم کمک کنم. لطفاً خودتان ادامه دهید.</translation>
<translation id="8131740175452115882">تأیید</translation>
<translation id="8149426793427495338">رایانه‌تان به خواب رفته است.</translation>
<translation id="8150722005171944719">این فایل در <ph name="URL" /> قابل خواندن نیست. ممکن است حذف شده، جابجا شده باشد و یا مجوزهای فایل از دسترسی جلوگیری می‌کنند.</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">ترجمه صفحه</translation>
<translation id="8201077131113104583">نشانی وب به‌روزرسانی نامعتبر برای برنامه افزودنی با شناسه «<ph name="EXTENSION_ID" />».</translation>
<translation id="8202097416529803614">خلاصه سفارش</translation>
+<translation id="8202370299023114387">اختلال</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">اتصال امن است</translation>
<translation id="8218327578424803826">مکان اختصاص یافته:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</translation>
<translation id="8225771182978767009">شخصی که این رایانه را راه‌اندازی کرده این سایت را مسدود کرده است.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />،‏ <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">صفحه را در برگه «ناشناس» جدیدی باز کنید</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">نمایش همه گذرواژه‌های ذخیره‌شده</translation>
<translation id="8261506727792406068">حذف</translation>
<translation id="8267698848189296333">ورود به سیستم به‌عنوان <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">‏این دستگاه توسط <ph name="ENROLLMENT_DOMAIN" /> مدیریت می‌شود. سرپرستتان می‌تواند تنظیم مرورگرتان را ازراه‌دور تغییر دهد. همچنین ممکن است فعالیت در این دستگاه خارج از Chrome مدیریت شود. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">ورود به سیستم</translation>
<translation id="8288807391153049143">نمایش گواهی</translation>
<translation id="8289355894181816810">اگر این موضوع را متوجه نمی‌شوید، با سرپرست شبکه‌تان تماس بگیرید.</translation>
<translation id="8293206222192510085">افزودن نشانک</translation>
<translation id="8294431847097064396">منبع</translation>
<translation id="8298115750975731693">‏شبکه Wi-Fi (<ph name="WIFI_NAME" />) مورد استفاده‌تان احتمالاً نیاز دارد که به صفحه <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> بروید.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">ترجمه انجام نشد چون مشکلی در اتصال به شبکه رخ داد.</translation>
-<translation id="8311129316111205805">بار کردن جلسه</translation>
<translation id="8332188693563227489">دسترسی به <ph name="HOST_NAME" /> رد شد</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">اگر خطرات امنیتی‌ای که متوجه شما هستند را درک می‌کنید، می‌توانید قبل از حذف شدن برنامه‌های خطرناک، <ph name="BEGIN_LINK" />از این سایت بازدید کنید<ph name="END_LINK" />.</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">پیکربندی شبکه نامعتبر است و نمی‌توان آن را وارد کرد.
توضیحات بیشتر:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">دستگاه تحت‌مدیریت <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">تغییر</translation>
<translation id="8428213095426709021">تنظیمات</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">نام صاحب کارت</translation>
<translation id="861775596732816396">اندازه ۴</translation>
<translation id="8620436878122366504">والدینتان هنوز این سایت را تأیید نکرده‌اند</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">ذخیره کردن این کارت در این دستگاه</translation>
<translation id="8663226718884576429">خلاصه سفارش، <ph name="TOTAL_LABEL" />، جزئيات بیشتر</translation>
<translation id="8680536109547170164"><ph name="QUERY" />، پاسخ، <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">اتصال شما به <ph name="DOMAIN" /> رمزگذاری نشده است.</translation>
<translation id="8718314106902482036">پرداخت کامل نشد</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />، <ph name="DESCRIPTION" />، پیشنهاد جستجو</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">‏مرور ایمن Google اخیراً <ph name="BEGIN_LINK" />برنامه‌های خطرناک<ph name="END_LINK" /> را در <ph name="SITE" /> پیدا کرده است.</translation>
<translation id="8763927697961133303">‏دستگاه USB</translation>
<translation id="8768895707659403558">برای اینکه از کارت‌هایتان در همه دستگاه‌هایتان استفاده کنید، <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;انجام مجدد حذف</translation>
<translation id="8792621596287649091">‏ممکن است دسترسی به حساب <ph name="ORG_NAME" /> را از دست بدهید یا به سرقت هویت دچار شوید. Chromium توصیه می‌کند هم‌اکنون گذرواژه‌تان را تغییر دهید.</translation>
<translation id="8800988563907321413">پیشنهادات اطراف شما در اینجا نشان داده می‌شوند</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">‏اشتراک‌گذاری با Google</translation>
<translation id="8858065207712248076">‏Chrome توصیه می‌کند اگر از گذرواژه <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> خود در سایت دیگری استفاده کردید آن را بازنشانی کنید.</translation>
<translation id="8866481888320382733">خطا در تجزیه تنظیمات خط‌مشی</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">اخیراً بسته‌شده</translation>
<translation id="8874824191258364635">شماره کارت معتبری وارد کنید</translation>
<translation id="8891727572606052622">حالت پروکسی نامعتبر است.</translation>
<translation id="8903921497873541725">بزرگ‌نمایی</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">‏می‌خواهید این کارت را در حساب Google خود ذخیره کنید؟</translation>
<translation id="8932102934695377596">ساعت شما عقب است</translation>
<translation id="893332455753468063">افزودن نام</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">سرپرستتان گواهینامه‌های ریشه سفارشی پیکربندی کرده است، که ممکن است به او اجازه دهد محتوای وب‌سایت‌هایی که بازدید می‌کنید را ببیند.</translation>
<translation id="8943282376843390568">لیمویی</translation>
<translation id="8957210676456822347">مجوز پورتال محدود</translation>
+<translation id="8966619695390250636">منظورتان این بود؟</translation>
<translation id="8968766641738584599">ذخیره کارت</translation>
<translation id="8971063699422889582">گواهی سرور منقضی شده است.</translation>
<translation id="8975012916872825179">شامل اطلاعاتی مانند شماره تلفن، نشانی ایمیل و نشانی تحویل کالا می‌شود</translation>
<translation id="8978053250194585037">‏Google Safe Browsing اخیراً در <ph name="SITE" />، <ph name="BEGIN_LINK" />فیشینگ شناسایی کرده است<ph name="END_LINK" />. سایت‌های فیشینگ وانمود می‌کنند وب‌سایت‌های دیگری هستند تا شما را فریب دهند.</translation>
<translation id="8983003182662520383">‏روش‌های پرداخت و نشانی‌های مورداستفاده در Google Pay</translation>
<translation id="8987927404178983737">ماه</translation>
-<translation id="8988408250700415532">مشکلی پیش آمد. می‌توانید سفارشتان را در وب‌سایت تمام کنید.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">سایت در پیش‌رو حاوی برنامه‌های خطرناک است</translation>
<translation id="8997023839087525404">سرور گواهی‌ای را ارائه کرده است که با استفاده از خط‌مشی شفافیت گواهینامه به‌صورت عمومی نشان داده نشده است. برای برخی گواهی‌ها این یک مسئله ضروری است تا از قابل اعتماد بودن آن‌ها و محافظت دربرابر مهاجمین اطمینان حاصل شود.</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">باز کردن تنظیمات سایت</translation>
<translation id="9020200922353704812">نشانی صورت‌حساب کارت لازم است</translation>
<translation id="9020542370529661692">این صفحه به <ph name="TARGET_LANGUAGE" /> ترجمه شده است</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(نامعتبر)</translation>
<translation id="9035022520814077154">خطای امنیتی</translation>
<translation id="9038649477754266430">استفاده از یک سرویس پیش‌بینی برای بار کردن سریع‌تر صفحه‌ها</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">جستجوی <ph name="TEXT" /> از سابقه</translation>
<translation id="9069693763241529744">توسط افزونه مسدود شده است</translation>
<translation id="9076283476770535406">این سایت ممکن است شامل محتوای مخصوص بزرگسالان باشد</translation>
+<translation id="9076630408993835509">‏این مرورگر توسط شرکت یا سازمان دیگری مدیریت نمی‌شود. فعالیت در این دستگاه ممکن است خارج از Chrome مدیریت شود. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">اطلاعات بیشتری نیاز است</translation>
<translation id="9080712759204168376">خلاصه سفارش</translation>
<translation id="9103872766612412690">‏<ph name="SITE" /> معمولاً برای محافظت از اطلاعات شما از رمزگذاری استفاده می‌کند. اما این بار که Chromium تلاش کرد به <ph name="SITE" /> متصل شود، وب‌سایت اعتبارنامه‌ای نامعمول و نادرست را برگرداند. ممکن است مهاجمی در تلاش باشد خود را به‌جای <ph name="SITE" /> معرفی کند یا یک صفحه ورود به سیستم Wi-Fi در ارتباط اختلال ایجاد کرده باشد. اطلاعات شما همچنان ایمن است، زیرا Chromium قبل از هرگونه تبادل داده، اتصال را متوقف کرد.</translation>
<translation id="9106062320799175032">افزودن نشانی صورت‌حساب</translation>
-<translation id="9110718169272311511">‏«دستیار Google» در Chrome در نزدیک پایین صفحه‌نمایش قرار دارد</translation>
<translation id="9114524666733003316">درحال تأیید کردن کارت…</translation>
<translation id="9128870381267983090">اتصال به شبکه</translation>
<translation id="9137013805542155359">نمایش مورد اصلی</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;واگرد ویرایش</translation>
<translation id="9154194610265714752">به‌روزرسانی ‌شد</translation>
<translation id="9157595877708044936">در حال راه‌اندازی...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">سایت‌ها بتوانند بررسی کنند روش پرداخت ذخیره‌شده‌ای دارید یا نه</translation>
<translation id="9169664750068251925">همیشه مسدود در این سایت</translation>
<translation id="9170848237812810038">&amp;واگرد</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">تصاویر</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">پاک کردن فرم</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">‏ممکن است دسترسی به حساب Google را از دست بدهید. Chromium توصیه می‌کند اکنون گذرواژه‌تان را تغییر دهید. از شما خواسته می‌شود به سیستم وارد شوید.</translation>
<translation id="939736085109172342">پوشهٔ جدید</translation>
<translation id="945855313015696284">اطلاعات زیر را بررسی و کارت‌های نامعتبر را حذف کنید</translation>
<translation id="951104842009476243">کارت‌های نقدی و پیش‌پرداخت قابل‌قبول</translation>
+<translation id="958202389743790697">مسدودشده براساس خط‌مشی ایمنی <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">این محتوا ممکن است برنامه‌های فریب‌دهنده‌ای نصب کند که وانمود می‌کنند برنامه دیگری هستند یا اینکه داده‌هایی برای ردیابی شما جمع‌آوری می‌کنند. <ph name="BEGIN_LINK" />درهرصورت نشان داده شود<ph name="END_LINK" /></translation>
<translation id="969892804517981540">ساخت رسمی</translation>
<translation id="973773823069644502">افزودن نشانی ارسال</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">روش‌های پرداخت</translation>
<translation id="985199708454569384">‏&lt;p&gt;اگر تاریخ و زمان رایانه یا دستگاه همراهتان درست نباشد این خطا را می‌بینید.&lt;/p&gt;
&lt;p&gt;برای برطرف کردن این خطا، ساعت دستگاه را باز کنید. مطمئن شوید تاریخ و زمان صحیح است.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">ساخت برنامه‌نویس</translation>
<translation id="989988560359834682">ویرایش آدرس</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_fi.xtb b/chromium/components/strings/components_strings_fi.xtb
index 9cf0ff55b15..f3536e70b40 100644
--- a/chromium/components/strings/components_strings_fi.xtb
+++ b/chromium/components/strings/components_strings_fi.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fi">
-<translation id="1005145902654145231">Käyttökerran uudelleennimeäminen epäonnistui.</translation>
<translation id="1008557486741366299">Ei nyt</translation>
<translation id="1010200102790553230">Lataa sivu myöhemmin</translation>
<translation id="1015730422737071372">Lisätietoja</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">tuntematon nimi</translation>
<translation id="1050038467049342496">Sulje muita sovelluksia.</translation>
<translation id="1055184225775184556">K&amp;umoa lisäys</translation>
+<translation id="1056898198331236512">Varoitus</translation>
<translation id="1058479211578257048">Tallennetaan kortteja…</translation>
<translation id="10614374240317010">Ei tallenneta</translation>
+<translation id="1062160989074299343">Prc10 (kirjekuori)</translation>
<translation id="106701514854093668">Työpöytäkirjanmerkit</translation>
<translation id="1074497978438210769">Ei turvallinen</translation>
<translation id="1080116354587839789">Sovita leveyteen</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Lisää kortissa oleva nimi</translation>
<translation id="1089439967362294234">Vaihda salasana</translation>
<translation id="109743633954054152">Määritä salasanat Chrome-asetuksissa</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Varoituksia voi esiintyä usein, kun verkkosivustot päivittävät suojaustaan. Asian pitäisi korjaantua pian.</translation>
<translation id="1126551341858583091">Paikallisen tallennustilan koko on <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Käytännön välimuisti on OK</translation>
+<translation id="1131264053432022307">Kopioimasi kuva</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Muuta nimeä</translation>
<translation id="1175364870820465910">Tulo&amp;sta...</translation>
<translation id="1181037720776840403">Poista</translation>
<translation id="1197088940767939838">Oranssi</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Laitteesi nimi</translation>
<translation id="124116460088058876">Lisää kieliä</translation>
<translation id="1250759482327835220">Jos haluat maksaa nopeammin ensi kerralla, tallenna kortti, nimi ja laskutusosoite Google-tilillesi.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkronoitu)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Komentorivin muunnelmat</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="1314614906530272393">Valittua käyttökertaa ei ole olemassa.</translation>
+<translation id="1320233736580025032">Prc1 (kirjekuori)</translation>
+<translation id="132301787627749051">Hae leikepöytäkuvaa</translation>
<translation id="1323433172918577554">Näytä lisää</translation>
<translation id="132390688737681464">Tallenna ja täytä osoitteet</translation>
<translation id="1333989956347591814">Toimintasi <ph name="BEGIN_EMPHASIS" />saattaa silti näkyä<ph name="END_EMPHASIS" />
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Nouto-osoite</translation>
<translation id="1348198688976932919">Sivusto sisältää vaarallisia sovelluksia</translation>
<translation id="1348779747280417563">Vahvista nimi</translation>
+<translation id="1357195169723583938">Kuka on äskettäin käyttänyt laitetta ja milloin</translation>
+<translation id="1364822246244961190">Tämä käytäntö on estetty, sen arvo jätetään huomiotta.</translation>
<translation id="1374468813861204354">ehdotuksia</translation>
+<translation id="1374692235857187091">Index-4x6 (postikortti)</translation>
<translation id="1375198122581997741">Tietoja versiosta</translation>
<translation id="1376836354785490390">Näytä vähemmän</translation>
<translation id="1377321085342047638">Kortin numero</translation>
<translation id="138218114945450791">Vaaleansininen</translation>
+<translation id="1382194467192730611">Järjestelmänvalvojan sallima USB-laite</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ei lähettänyt tietoja.</translation>
+<translation id="140316286225361634">Sivusto <ph name="ORIGIN" /> pyytää tietosuojakäytännön
+ soveltamista kaikkiin sen pyyntöihin. Tällä hetkellä käytäntö pitää sivustoa
+ vaarallisena.</translation>
<translation id="1405567553485452995">Vaaleanvihreä</translation>
<translation id="1407135791313364759">Avaa kaikki</translation>
<translation id="1413809658975081374">Tietosuojavirhe</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Kyllä</translation>
<translation id="1430915738399379752">Tulosta</translation>
<translation id="1455413310270022028">Pyyhekumi</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Näytä enemmän</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Valitse toimitusosoite</translation>
+<translation id="1492194039220927094">Käytäntöjen kehotusviestit:</translation>
<translation id="1501859676467574491">Näytä Google-tilin kortit</translation>
-<translation id="1506687042165942984">Näytä tallennettu (eli vanhentuneeksi tiedetty) kopio tästä sivusta.</translation>
<translation id="1507202001669085618">&lt;p&gt;Näet tämän virheen, jos käyttämäsi Wi-Fi-portaali edellyttää kirjautumista ennen verkon käyttöä.&lt;/p&gt;
&lt;p&gt;Korjaa virhe valitsemalla &lt;strong&gt;Yhdistä&lt;/strong&gt; sivulla, jota yrität avata.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Puhelinnumero vaaditaan</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Koontipäivä</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">Odotetaan yhteyttä…</translation>
+<translation id="1529521330346880926">10x15 (kirjekuori)</translation>
+<translation id="1531205177818805254">Johto</translation>
<translation id="1532118530259321453">Viesti tältä sivulta</translation>
<translation id="153384715582417236">Siinä kaikki toistaiseksi</translation>
<translation id="154408704832528245">Valitse jakeluosoite</translation>
<translation id="1549470594296187301">Tämän ominaisuuden käyttö edellyttää JavaScriptiä.</translation>
+<translation id="155039086686388498">Insinööri-D</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="1569487616857761740">Lisää viimeinen voimassaolopäivä</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Kuva kopioitu</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Estä tätä sivua luomasta muita viestejä</translation>
+<translation id="16338877384480380">Arkkitehti-B</translation>
<translation id="1634051627998691300">Lopeta käyttökerta</translation>
<translation id="1639239467298939599">Ladataan</translation>
<translation id="1640180200866533862">Käyttäjäkäytännöt</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Palvelinvarmenne sisältää heikon salausavaimen.</translation>
<translation id="1697532407822776718">Kaikki on valmista.</translation>
+<translation id="1703835215927279855">Kirje</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Tiedosto on liian suuri merkintöihin</translation>
<translation id="1721312023322545264">Tarvitset henkilön <ph name="NAME" /> luvan käydä tällä sivustolla</translation>
<translation id="1721424275792716183">* Kenttä on pakollinen.</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Ota yhteyttä järjestelmänvalvojaan.</translation>
<translation id="1740951997222943430">Anna kelvollinen viimeinen voimassaolokuukausi.</translation>
<translation id="1743520634839655729">Jos haluat maksaa nopeammin ensi kerralla, tallenna kortti, nimi ja laskutusosoite Google-tilillesi ja tälle laitteelle.</translation>
+<translation id="1745880797583122200">Tämä on ylläpidetty selain</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Päivitä synkronoinnin tunnuslause.</translation>
<translation id="1787142507584202372">Avoimet välilehdet näkyvät tässä.</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kortinhaltijan nimi</translation>
<translation id="1821930232296380041">Pyyntö on virheellinen tai pyynnön parametrit ovat virheelliset</translation>
+<translation id="1822540298136254167">Avaamasi verkkosivustot ja niillä vietetty aika</translation>
<translation id="1826516787628120939">Tarkistetaan</translation>
<translation id="1834321415901700177">Tämä sivusto sisältää haitallisia ohjelmia</translation>
<translation id="1839551713262164453">Käytäntöarvojen vahvistus epäonnistui sisältäen virheitä</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Tyhjennä Chromen selaushistoriadata</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ja 1 muu}other{ja # muuta}}</translation>
<translation id="2003709556000175978">Pyydä uusi salasana</translation>
+<translation id="20053308747750172">Kohdepalvelin <ph name="ORIGIN" /> pyytää
+ tietosuojakäytännön soveltamista kaikkiin sen saamiin pyyntöihin. Nyt se on
+ palauttanut virheellisen käytännön, joten selain ei voi
+ toteuttaa <ph name="SITE" />-pyyntöä.</translation>
<translation id="2025186561304664664">Välityspalvelimen asetus: automaattisesti määritetty.</translation>
<translation id="2030481566774242610">Tarkoititko: <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Tarkista välityspalvelimen ja palomuurin määritykset.<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Osasto</translation>
<translation id="2102134110707549001">Ehdota vahvaa salasanaa…</translation>
<translation id="2108755909498034140">Käynnistä tietokone uudelleen.</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kortti</translation>
<translation id="2114841414352855701">Ei käytetä – käytännön <ph name="POLICY_NAME" /> ohittama.</translation>
<translation id="213826338245044447">Mobiilikirjanmerkit</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (kirjekuori)</translation>
<translation id="2181821976797666341">Käytännöt</translation>
<translation id="2183608646556468874">Puhelinnumero</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 osoite}other{# osoitetta}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Puhelinnumero</translation>
<translation id="2283340219607151381">Tallenna ja täytä osoitteet</translation>
<translation id="2292556288342944218">Internetyhteytesi on estetty</translation>
+<translation id="2294558542833290837">Alun perin avaamasi linkki on epätavallinen</translation>
+<translation id="2297722699537546652">B5 (kirjekuori)</translation>
+<translation id="2310021320168182093">Chou2 (kirjekuori)</translation>
<translation id="2316887270356262533">Vapauttaa alle 1 Mt. Jotkin sivustot saattavat latautua hitaammin seuraavalla käynnillä.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> pyytää käyttäjänimeä ja salasanaa.</translation>
<translation id="2317583587496011522">Maksukortit hyväksytään.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, vanhenee <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Järjestelmänvalvojan hallinnoima asetus</translation>
+<translation id="2346319942568447007">Kopioimasi kuva</translation>
<translation id="2349790679044093737">VR-käyttökerta on aktiivinen</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Kaatumisraportti tallennettu <ph name="CRASH_TIME" />, ei vielä lähetetty</translation>
<translation id="2367567093518048410">Taso</translation>
<translation id="2378238891085281592">Olet siirtynyt yksityiseen tilaan</translation>
+<translation id="2380886658946992094">Lakiasiat</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="2410754574180102685">Viranomaiset-lakiasiat</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="2418081434543109369">Kohdepalvelin <ph name="ORIGIN" /> pyytää
+ tietosuojakäytännön soveltamista kaikkiin sen saamiin pyyntöihin. Se ei ole
+ palauttanut käytäntöä, joten selain ei nyt voi
+ toteuttaa <ph name="SITE" />-pyyntöä.</translation>
<translation id="244665789865330679"><ph name="ENROLLMENT_DOMAIN" /> ylläpitää laitettasi ja tiliäsi. Järjestelmänvalvoja voi siis määrittää laitteen ja tilin etäyhteydellä.</translation>
<translation id="2463193859425327265">Vaihda etusivua</translation>
<translation id="2463739503403862330">Täytä</translation>
+<translation id="2465402087343596252">Arkkitehti-E</translation>
<translation id="2465655957518002998">Valitse jakelutapa</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />verkon diagnostiikkaa<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Käännä tämä sivu</translation>
<translation id="2479410451996844060">Virheellinen hakukoneen URL-osoite.</translation>
<translation id="2482878487686419369">Ilmoitukset</translation>
<translation id="248348093745724435">Laitteen käytännöt</translation>
+<translation id="2485387744899240041">Laitteen ja selaimen käyttäjänimet</translation>
<translation id="2491120439723279231">Palvelimen varmenteessa on virheitä.</translation>
+<translation id="2493640343870896922">Kirje-plus</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>
<translation id="2498091847651709837">Skannaa uusi kortti</translation>
<translation id="2501278716633472235">Takaisin</translation>
<translation id="2503184589641749290">Hyväksytyt maksu- ja prepaid-kortit</translation>
<translation id="2515629240566999685">Tarkista alueesi mobiilisignaali.</translation>
-<translation id="2516852381693169964">Hae kuvaa (<ph name="SEARCH_ENGINE" />)</translation>
<translation id="2523886232349826891">Tallennetaan vain tälle laitteelle</translation>
<translation id="2524461107774643265">Lisää tietoja</translation>
<translation id="2536110899380797252">Lisää osoite</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (kirjekuori)</translation>
<translation id="2625385379895617796">Kellosi edistää</translation>
<translation id="2634124572758952069">Sivuston <ph name="HOST_NAME" /> palvelimen IP-osoitetta ei löytynyt.</translation>
<translation id="2639739919103226564">Tila:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Sulje muita välilehtiä tai sovelluksia.</translation>
<translation id="267371737713284912">kumoa painamalla <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Haluatko varmasti poistaa nämä sivut historiastasi?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Poistu</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Hyväksytyt kortit</translation>
<translation id="2702801445560668637">Lukulista</translation>
<translation id="2704283930420550640">Arvo ei vastaa muotoa.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Poista valitut kohteet</translation>
<translation id="277133753123645258">Lähetystapa</translation>
<translation id="277499241957683684">Laitetallenne puuttuu</translation>
-<translation id="2781030394888168909">Vie MacOS-muodossa</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Yhteys katkaistiin.</translation>
<translation id="2788784517760473862">Hyväksytyt luottokortit</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Avaa incognito-ikkuna</translation>
+<translation id="2850739647070081192">Kutsu (kirjekuori)</translation>
<translation id="2851634818064021665">Tarvitset luvan tälle sivustolle siirtymiseen.</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Tallennetaanko kortti?</translation>
<translation id="2903493209154104877">Osoitteet</translation>
<translation id="290376772003165898">Eikö sivu ole kirjoitettu kielellä <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Toimitustapa</translation>
<translation id="2928905813689894207">Laskutusosoite</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" /><ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{ 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="2934466151127459956">Viranomaiskirje</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (kirjekuori)</translation>
<translation id="3024663005179499861">Väärä käytäntötyyppi</translation>
<translation id="3037605927509011580">Voi räkä!</translation>
<translation id="3041612393474885105">Varmenteen tiedot</translation>
+<translation id="3060227939791841287">C9 (kirjekuori)</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="3095940652251934233">Tiliote</translation>
<translation id="3096100844101284527">Lisää noutopaikan osoite</translation>
<translation id="3105172416063519923">Laitteen tunnus:</translation>
<translation id="3109728660330352905">Sinulla ei ole oikeutta tarkastella tätä sivua.</translation>
@@ -365,20 +413,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" />, palvelin: <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Peruuta maksu</translation>
<translation id="3207960819495026254">Kirjanmerkeissä</translation>
-<translation id="3209375525920864198">Anna kelvollinen istunnon nimi.</translation>
+<translation id="321912867715453276">Varoitus: Käytännölle on useita lähteitä, mutta arvot ovat samat.</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="3229041911291329567">Laitteen ja selaimen versiotiedot</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Lisää kortissa oleva nimi</translation>
<translation id="3287510313208355388">Lataa, kun verkkoyhteys on muodostettu</translation>
<translation id="3293642807462928945">Lisätietoja käytännöstä: <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Ei hakutuloksia</translation>
-<translation id="3305707030755673451">Tietosi salattiin synkronoinnin tunnuslauseesi avulla <ph name="TIME" />. Aloita synkronointi antamalla tunnuslause.</translation>
<translation id="3320021301628644560">Lisää laskutusosoite</translation>
<translation id="3324983252691184275">Karmiininpunainen</translation>
<translation id="3338095232262050444">Turvallinen</translation>
@@ -406,9 +455,11 @@
<translation id="3427342743765426898">&amp;Toista muokkaus</translation>
<translation id="342781501876943858">Chromium suosittelee salasanan vaihtamista, jos olet käyttänyt sitä myös muilla sivustoilla.</translation>
<translation id="3431636764301398940">Tallenna kortti tälle laitteelle</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Tämän laitteen omistaja on poistanut dinosauruspelin käytöstä.</translation>
<translation id="3447884698081792621">Näytä varmenne (myöntäjä: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Hakuväli:</translation>
+<translation id="3456231139987291353">Nro 11 (kirjekuori)</translation>
<translation id="3461824795358126837">Korostus</translation>
<translation id="3462200631372590220">Piilota lisäasetukset</translation>
<translation id="3467763166455606212">Kortinhaltijan nimi on pakollinen.</translation>
@@ -431,20 +482,23 @@
<translation id="358285529439630156">Luotto- ja prepaid-kortit hyväksytään.</translation>
<translation id="3582930987043644930">Lisää nimi</translation>
<translation id="3583757800736429874">&amp;Toista siirto</translation>
+<translation id="35866233670761917">Järjestelmänvalvojat eivät näet avaamiesi sivustojen sisältöä</translation>
<translation id="3586931643579894722">Piilota lisätiedot</translation>
+<translation id="3592413004129370115">Italialainen (kirjekuori)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Koko 2</translation>
<translation id="3615877443314183785">Anna kelvollinen viimeinen voimassaolopäivä.</translation>
<translation id="36224234498066874">Poista selaustiedot...</translation>
<translation id="362276910939193118">Näytä koko selaushistoria</translation>
-<translation id="3623476034248543066">Näytä arvo</translation>
<translation id="3630155396527302611">Jos sillä on jo verkon käyttöoikeus, kokeile sen poistamista
sallittujen ohjelmien luettelosta ja lisäämistä sitten uudelleen.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Todennus onnistui</translation>
<translation id="3655670868607891010">Jos näet tämän usein, kokeile näitä <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Päivitetty versio</translation>
<translation id="366077651725703012">Päivitä luottokortti</translation>
<translation id="3676592649209844519">Laitteen tunnus:</translation>
+<translation id="3677008721441257057">Tarkoititko &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Pyynnön allekirjoittaminen epäonnistui.</translation>
<translation id="3678529606614285348">Avaa sivu uudessa incognito-ikkunassa (Ctrl + Vaihto + N).</translation>
<translation id="3679803492151881375">Kaatumisraportti tallennettu <ph name="CRASH_TIME" />, lähetetty <ph name="UPLOAD_TIME" /></translation>
@@ -452,13 +506,14 @@
<translation id="3704162925118123524">Käyttämäsi verkko saattaa edellyttää kirjautumista.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Ladataan...</translation>
+<translation id="3709599264800900598">Kopioimasi teksti</translation>
<translation id="3712624925041724820">Käyttöluvat ovat lopussa</translation>
<translation id="3714780639079136834">Ota mobiilidata tai Wi-Fi käyttöön.</translation>
<translation id="3715597595485130451">Yhteyden muodostaminen Wi-Fi-verkkoon</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Tarkista välityspalvelimen, palomuurin ja nimipalvelun määritykset<ph name="END_LINK" />.</translation>
<translation id="372429172604983730">Tätä virhettä voivat aiheuttaa esimerkiksi virustorjuntaohjelmat, palomuurit ja verkon suodatus- tai välityspalvelinohjelmistot.</translation>
+<translation id="373042150751172459">B4 (kirjekuori)</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="3745099705178523657">Vahvistamisen jälkeen korttitiedot Google-tililtäsi jaetaan tämän sivuston kanssa.</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>
@@ -471,10 +526,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Vanhenee <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Koko 16</translation>
+<translation id="3797522431967816232">Prc3 (kirjekuori)</translation>
<translation id="3807873520724684969">Haitallinen sisältö estetty</translation>
<translation id="3810973564298564668">Hallinnoi</translation>
<translation id="382518646247711829">Jos käytät välityspalvelinta…</translation>
<translation id="3828924085048779000">Tunnuslause ei voi olla tyhjä.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> on asentanut lisätoimintojen laajennuksia. Laajennuksilla on pääsy osaan datastasi.</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>
@@ -482,6 +539,7 @@
<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="3906600011954732550">B5-ekstra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Kysy aina tällä sivustolla</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>
@@ -492,11 +550,13 @@
<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="3984550557525787191">Tämä käyttökerran nimi on jo olemassa.</translation>
<translation id="3987940399970879459">Alle 1 Mt</translation>
+<translation id="4008849406247176967">Varoitus: Käytännölle on useita lähteitä, joiden arvot ovat ristiriidassa.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 verkkosivu lähistöllä}other{# verkkosivua lähistöllä}}</translation>
<translation id="4030383055268325496">K&amp;umoa lisäys</translation>
+<translation id="4032320456957708163">Selaimen ylläpitäjä on <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Avain <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (kirjekuori)</translation>
<translation id="4067947977115446013">Lisää kelvollinen osoite</translation>
<translation id="4072486802667267160">Virhe tilausta käsiteltäessä. Yritä uudelleen.</translation>
<translation id="4075732493274867456">Asiakassovellus ja palvelin eivät tue samaa SSL-protokollaversiota tai salaustekniikkaa.</translation>
@@ -516,10 +576,12 @@
<translation id="4159784952369912983">Violetti</translation>
<translation id="4165986682804962316">Sivustoasetukset</translation>
<translation id="4171400957073367226">Virheellinen vahvistusallekirjoitus.</translation>
+<translation id="4173315687471669144">Foolscap (203 mm x 330 mm)</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> toinen kohde}other{<ph name="ITEM_COUNT" /> muuta kohdetta}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (kirjekuori)</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="4221630205957821124">&lt;h4&gt;Vaihe 1: Kirjaudu portaaliin&lt;/h4&gt;
@@ -551,58 +613,79 @@
<translation id="4277028893293644418">Pyydä uusi salasana</translation>
<translation id="4280429058323657511">, vanhentumispäivä <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Tämä kortti on tallennettu Google-tilillesi}other{Nämä kortit on tallennettu Google-tilillesi}}</translation>
+<translation id="42981349822642051">Laajenna</translation>
+<translation id="4302965934281694568">Chou3 (kirjekuori)</translation>
<translation id="4305817255990598646">Vaihda</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Estä (oletus)</translation>
+<translation id="4318566738941496689">Laitteesi nimi ja verkko-osoite</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="4340982228985273705">Havaintojen mukaan tämä tietokone ei ole yrityksen hallinnoima, joten käytäntö voi asentaa automaattisesti vain Chrome Web Storessa hostattuja laajennuksia. Chrome Web Storen päivitys-URL-osoite on <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Hyväksytyt luottokortit</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Hallinnoi maksutapoja…</translation>
+<translation id="4367563149485757821">Numero-12 (kirjekuori)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Puhelin</translation>
<translation id="4406896451731180161">hakutulokset</translation>
-<translation id="4406972042435603828">Järjestelmänvalvojat ovat asentaneet tehokkaita laajennuksia.</translation>
<translation id="4408413947728134509">Evästeet <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Nouto-osoite</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="443121186588148776">Sarjaportti</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ei hyväksynyt kirjautumisvarmennettasi, tai varmennetta ei annettu.</translation>
<translation id="4434045419905280838">Ponn.ikkunat ja uudelleenohj.</translation>
+<translation id="4435702339979719576">Postikortti</translation>
<translation id="443673843213245140">Välityspalvelinta ei saa käyttää, mutta erilliset välityspalvelimen asetukset on määritetty.</translation>
<translation id="445100540951337728">Hyväksytyt maksukortit</translation>
+<translation id="4466881336512663640">Lomakkeen muutokset menetetään. Haluatko varmasti jatkaa?</translation>
<translation id="4482953324121162758">Tätä sivustoa ei käännetä.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Virheellinen URL-osoite URL-osoitteen on oltava vakiomallien mukainen, esimerkiksi "http://example.com" tai "https://example.com".</translation>
+<translation id="4503882053543859973">Arkkitehti-D</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="4510487217173779431">Chou4 (kirjekuori)</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="4517607026994743406">Comm-10 (kirjekuori)</translation>
<translation id="4522570452068850558">Tiedot</translation>
<translation id="4524805452350978254">Määritä kortit</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Poista laajennukset käytöstä.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Toimitus</translation>
+<translation id="4579056131138995126">Oma (kirjekuori)</translation>
<translation id="4582204425268416675">Poista kortti</translation>
<translation id="4587425331216688090">Poistetaanko osoite Chromen tiedoista?</translation>
<translation id="4592951414987517459">Yhteytesi kohteeseen <ph name="DOMAIN" /> on salattu nykyaikaisella salaustekniikalla.</translation>
<translation id="4594403342090139922">K&amp;umoa poisto</translation>
<translation id="4597348597567598915">Koko 8</translation>
+<translation id="4600854749408232102">C6/C5 (kirjekuori)</translation>
<translation id="4646534391647090355">Siirry nyt</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Lopeta virheellisten varmenteiden käyttö</translation>
+<translation id="4691835149146451662">Arkkitehti-A (kirjekuori)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Yhteys keskeytyi</translation>
<translation id="471880041731876836">Sinulla ei ole lupaa siirtyä tälle sivustolle.</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windowsin verkon diagnostiikkaa<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Päivitä käytännöt</translation>
<translation id="4728558894243024398">Käyttöympäristö</translation>
+<translation id="4731967714531604179">Prc2 (kirjekuori)</translation>
<translation id="4736825316280949806">Käynnistä Chromium uudelleen.</translation>
<translation id="473775607612524610">Päivitä</translation>
<translation id="4738601419177586157">Hakuehdotus <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Ylläpidä salasanoja…</translation>
<translation id="4744603770635761495">Suoritettavan tiedoston polku</translation>
+<translation id="4746351372139058112">Viestit</translation>
<translation id="4750917950439032686">Salasanat, luottokorttinumerot ja muut tietosi pysyvät yksityisinä, kun ne lähetetään tälle sivustolle.</translation>
<translation id="4756388243121344051">&amp;Historia</translation>
<translation id="4758311279753947758">Lisää yhteystiedot</translation>
@@ -610,9 +693,9 @@
<translation id="4764776831041365478">Osoitteessa <ph name="URL" /> oleva sivu saattaa olla väliaikaisesti pois käytöstä tai se on voitu siirtää pysyvästi uuteen osoitteeseen.</translation>
<translation id="4771973620359291008">Tapahtui tuntematon virhe.</translation>
<translation id="4785689107224900852">Siirry tälle välilehdelle</translation>
-<translation id="4792143361752574037">Käyntitiedostoja käytettäessä tapahtui virhe. Tietojen tallentaminen levylle on tällä hetkellä poistettu käytöstä. Päivitä sivu ja yritä uudelleen.</translation>
<translation id="4798078619018708837">Päivitä <ph name="CREDIT_CARD" /> ‑tiedot antamalla sen viimeinen voimassaolopäivä ja CVC. Vahvistamisen jälkeen korttitiedot Google-tililtäsi jaetaan tämän sivuston kanssa.</translation>
<translation id="4800132727771399293">Tarkista vanhenemispäivä ja CVC ja yritä uudelleen.</translation>
+<translation id="480334179571489655">Käytännön alkuperävirhe</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>
@@ -627,7 +710,6 @@
<translation id="4881695831933465202">Avaa</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>
@@ -636,15 +718,15 @@
<translation id="4943872375798546930">Ei tuloksia</translation>
<translation id="4950898438188848926">Välilehden vaihtopainike, siirry avoimelle välilehdelle painamalla Enter, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Toiminnot</translation>
-<translation id="495832697253704892">Laajennusraportointi</translation>
+<translation id="4955242332710481440">A5-ekstra</translation>
<translation id="4958444002117714549">Laajenna luettelo</translation>
<translation id="4974590756084640048">Ota varoitukset uudelleen käyttöön</translation>
+<translation id="4984339528288761049">Prc5 (kirjekuori)</translation>
<translation id="4989163558385430922">Näytä kaikki</translation>
<translation id="4989809363548539747">Tätä laajennusta ei tueta.</translation>
-<translation id="4996230189582812866">Raportointi</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="5014174725590676422">Chromen Google Assistantin ensimmäisen käyttökerran näyttö näkyy</translation>
<translation id="5015510746216210676">Laitteen nimi:</translation>
+<translation id="5017554619425969104">Kopioimasi teksti</translation>
<translation id="5018422839182700155">Sivun avaaminen epäonnistui</translation>
<translation id="5019198164206649151">Tallennustila on virheellisessä tilassa</translation>
<translation id="5023310440958281426">Tarkista järjestelmänvalvojan käytännöt</translation>
@@ -654,35 +736,51 @@
<translation id="5034369478845443529">Paikallinen konteksti: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Salli</translation>
<translation id="5040262127954254034">Tietosuoja</translation>
+<translation id="5043480802608081735">Kopioimasi linkki</translation>
<translation id="5045550434625856497">Väärä salasana</translation>
<translation id="5056549851600133418">Sinulle valitut artikkelit</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Tarkista välityspalvelimen osoite.<ph name="END_LINK" /></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="5097099694988056070">Laitetilastot esim. CPU:n/RAM-muistin käytöstä</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465"><ph name="ENROLLMENT_DOMAIN" /> ylläpitää laitettasi ja <ph name="ACCOUNT_DOMAIN" /> tiliäsi. Järjestelmänvalvojat voivat siis määrittää laitteen ja tilin etäyhteydellä.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">Eurooppalainen-Edp</translation>
<translation id="5115563688576182185">(64-bittinen)</translation>
-<translation id="5128122789703661928">Tämännimistä käyttökertaa ei voi poistaa.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Hallinnoi osoitteita…</translation>
+<translation id="5138227688689900538">Näytä vähemmän</translation>
<translation id="5141240743006678641">Salaa synkronoidut salasanat Google-kirjautumistietojesi avulla</translation>
<translation id="5145883236150621069">Käytäntövastaus sisältää virhekoodin</translation>
+<translation id="515292512908731282">C4 (kirjekuori)</translation>
<translation id="5159010409087891077">Avaa sivu uudessa incognito-ikkunassa (⇧ + ⌘ + N).</translation>
<translation id="516920405563544094">Anna kortin <ph name="CREDIT_CARD" /> CVC. Vahvistamisen jälkeen korttitiedot Google-tililtäsi jaetaan tämän sivuston kanssa.</translation>
<translation id="5169827969064885044">Voit menettää organisaatiosi tilin käyttöoikeuden tai joutua identiteettivarkauden uhriksi. Chrome suosittelee vaihtamaan salasanan välittömästi.</translation>
<translation id="5171045022955879922">Kirjoita hakusanoja tai URL-osoite</translation>
+<translation id="5171689220826475070">European Fanfold</translation>
<translation id="5172758083709347301">Kaikki tietokoneen käyttäjät</translation>
<translation id="5179510805599951267">Eikö kieli ole <ph name="ORIGINAL_LANGUAGE" />? Ilmoita virheestä</translation>
<translation id="5190835502935405962">Kirjanmerkkipalkki</translation>
-<translation id="5200263511887412697">Ilmoittaa luettelon viime aikoina sisäänkirjautuneista laitteen käyttäjistä</translation>
+<translation id="519422657042045905">Merkintää ei saatavilla</translation>
<translation id="5201306358585911203">Viesti tälle sivulle upotetulta sivulta</translation>
<translation id="5205222826937269299">Nimi vaaditaan</translation>
<translation id="5215116848420601511">Maksutavat ja osoitteet Google Paysta</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Sähköposti vaaditaan</translation>
<translation id="5230733896359313003">Toimitusosoite</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">Yhdistä verkkoon</translation>
<translation id="5251803541071282808">Pilvi</translation>
+<translation id="5252000469029418751">C7 (kirjekuori)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Verkko-osoitteet</translation>
<translation id="5285570108065881030">Näytä kaikki tallennetut salasanat</translation>
<translation id="5287240709317226393">Näytä evästeet</translation>
<translation id="5288108484102287882">Käytäntöarvojen vahvistus aiheutti varoituksia</translation>
@@ -694,7 +792,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" />/<ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Valitse yhteystiedot</translation>
<translation id="5327248766486351172">Nimi</translation>
+<translation id="5329858041417644019">Selainta ei ylläpidetä</translation>
<translation id="5332219387342487447">Toimitustapa</translation>
+<translation id="5334013548165032829">Yksityiskohtaiset järjestelmälokit</translation>
<translation id="5344579389779391559">Tämä sivu voi yrittää veloittaa sinua</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>
@@ -702,6 +802,7 @@
<translation id="5377026284221673050">"Kellosi jätättää", "Kellosi edistää" tai "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Jos haluat käyttää kortteja kaikilla laitteillasi, kirjaudu sisään ja ota synkronointi käyttöön.</translation>
<translation id="5386426401304769735">Tämän sivuston varmenneketju sisältää varmenteen, joka on allekirjoitettu SHA-1:llä.</translation>
+<translation id="538659543871111977">A4-välilehti</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>
@@ -712,6 +813,7 @@
<translation id="5457113250005438886">Virheellinen</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Toista muokkaus</translation>
+<translation id="5478437291406423475">B6/C4 (kirjekuori)</translation>
<translation id="5481076368049295676">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="54817484435770891">Lisää kelvollinen osoite</translation>
<translation id="5490432419156082418">Osoitteet ja muita tietoja</translation>
@@ -719,10 +821,12 @@
<ph name="LINE_BREAK" />
Ota yhteyttä järjestelmänvalvojaasi.</translation>
<translation id="549333378215107354">Koko 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Hallinnoidut kirjanmerkit</translation>
<translation id="5510766032865166053">Se on voitu siirtää tai poistaa.</translation>
<translation id="5523118979700054094">Käytännön nimi</translation>
<translation id="552553974213252141">Noudettiinko teksti oikein?</translation>
+<translation id="553484882784876924">Prc6 (kirjekuori)</translation>
<translation id="5540224163453853">Pyydettyä artikkelia ei löydy.</translation>
<translation id="5541546772353173584">Lisää sähköposti</translation>
<translation id="5545756402275714221">Sinulle valitut artikkelit</translation>
@@ -737,15 +841,21 @@
<translation id="5595485650161345191">Osoitteen muokkaus</translation>
<translation id="5598944008576757369">Valitse maksutapa</translation>
<translation id="560412284261940334">Hallintaa ei tueta</translation>
+<translation id="5605670050355397069">Kierrevihko</translation>
+<translation id="5607240918979444548">Arkkitehti-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> uudelleenohjasi sinut liian monta kertaa.</translation>
<translation id="5629630648637658800">Käytännön asetuksien lataaminen epäonnistui</translation>
<translation id="5631439013527180824">Laitteenhallintatunnus on virheellinen</translation>
+<translation id="5632627355679805402">Datasi salattiin <ph name="BEGIN_LINK" />Google-salasanallasi<ph name="END_LINK" /> <ph name="TIME" />. Aloita synkronointi antamalla salasana.</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="563324245173044180">Harhaanjohtava sisältö estetty</translation>
<translation id="5659593005791499971">Sähköposti</translation>
+<translation id="5663614846592581799">9x11 (kirjekuori)</translation>
+<translation id="5663955426505430495">Laitteen järjestelmänvalvoja on asentanut lisätoimintojen laajennuksia. Laajennuksilla on pääsy osaan datastasi.</translation>
<translation id="5675650730144413517">Sivu ei toimi</translation>
+<translation id="5684874026226664614">Hups, tätä sivua ei voi kääntää.</translation>
<translation id="5685654322157854305">Lisää toimitusosoite</translation>
<translation id="5689199277474810259">Vie JSON-tiedostoon</translation>
<translation id="5689516760719285838">Sijainti</translation>
@@ -754,38 +864,39 @@
<translation id="5710435578057952990">Tämän sivuston identiteettiä ei ole vahvistettu.</translation>
<translation id="5719499550583120431">Prepaid-kortit hyväksytään.</translation>
<translation id="5720705177508910913">Nykyinen käyttäjä</translation>
+<translation id="5728056243719941842">C5 (kirjekuori)</translation>
<translation id="5730040223043577876">Chrome suosittelee salasanan vaihtamista, jos olet käyttänyt sitä myös muilla sivustoilla.</translation>
<translation id="5732392974455271431">Vanhempasi voivat kumota eston puolestasi.</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Tallenna kortti Google-tilillesi}other{Tallenna kortit Google-tilillesi}}</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="5770114862687765385">Tiedosto on ilmeisesti vioittunut. Nollaa käyttökerta klikkaamalla Nollaa.</translation>
<translation id="5778550464785688721">MIDI-laitteiden täysi käyttöoikeus</translation>
<translation id="578305955206182703">Kullanruskea</translation>
<translation id="57838592816432529">Mykistä</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>
+<translation id="5798290721819630480">Hylätäänkö muutokset?</translation>
<translation id="5798683403665926540">Vaihda kotisivua Chromen asetuksissa</translation>
<translation id="5803412860119678065">Täytetäänkö kortin <ph name="CARD_DETAIL" /> tiedot?</translation>
<translation id="5804241973901381774">Käyttöoikeudet</translation>
<translation id="5810442152076338065">Yhteytesi kohteeseen <ph name="DOMAIN" /> on salattu vanhentuneella salaustekniikalla.</translation>
<translation id="5813119285467412249">&amp;Toista lisäys</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="5860033963881614850">Pois käytöstä</translation>
<translation id="5863847714970149516">Avaamasi sivu voi yrittää veloittaa sinulta rahaa</translation>
<translation id="5866257070973731571">Lisää puhelinnumero</translation>
<translation id="5869405914158311789">Sivustoon ei saada yhteyttä</translation>
<translation id="5869522115854928033">Tallennetut salasanat</translation>
<translation id="5887400589839399685">Kortti tallennettu</translation>
-<translation id="5893718151540690985">Ilmoittaa luettelon verkon käyttöliittymistä, niiden tyypeistä ja laitteisto-osoitteista</translation>
<translation id="5893752035575986141">Luottokortit hyväksytään.</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="5916664084637901428">Käytössä</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Tallennetaanko kortti Google-tilille?</translation>
<translation id="5922853866070715753">Lähes valmis</translation>
<translation id="5932224571077948991">Sivustolla on häiritseviä tai harhaanjohtavia mainoksia</translation>
-<translation id="5939518447894949180">Tyhjennä</translation>
<translation id="5946937721014915347">Avataan <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Liittyminen kuluttajatilillä ei onnistu (pakettilisenssi saatavilla).</translation>
<translation id="5967592137238574583">Muokkaa yhteystietoja</translation>
@@ -793,6 +904,7 @@
<translation id="5975083100439434680">Loitonna</translation>
<translation id="5977489021191000276">Järjestelmänvalvoja ei ylläpidä laitettasi.</translation>
<translation id="5977976211062815271">Tällä laitteella</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Maksusovelluksen avaaminen ei onnistu.</translation>
<translation id="5989320800837274978">Kiinteitä välityspalvelimia tai .pac-URL-osoitetta ei ole määritetty.</translation>
<translation id="5990559369517809815">Laajennus esti palvelinpyynnöt.</translation>
@@ -803,8 +915,8 @@
<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="6033927989869462158">Ilmoittaa laitetilastoja esimerkiksi CPU:n/RAM-muistin käytöstä</translation>
<translation id="6034000775414344507">Vaaleanharmaa</translation>
+<translation id="6034283069659657473">10x14 (kirjekuori)</translation>
<translation id="6039846035001940113">Jos ongelma jatkuu, ota yhteyttä sivuston omistajaan.</translation>
<translation id="6040143037577758943">Sulje</translation>
<translation id="6044573915096792553">Koko 12</translation>
@@ -813,10 +925,10 @@
<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="6058977677006700226">Haluatko käyttää kortteja kaikilla laitteillasi?</translation>
<translation id="6059925163896151826">USB-laitteet</translation>
-<translation id="6071091556643036997">Käytäntötyyppi on virheellinen.</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="6094273045989040137">Tee merkintä</translation>
<translation id="610911394827799129">Google-tililläsi voi olla muita selaushistoriatietoja osoitteessa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Tietoja asennetuista laajennuksista</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>
@@ -851,15 +963,21 @@
<translation id="6337133576188860026">Vapauttaa alle <ph name="SIZE" />. Jotkin sivustot saattavat latautua hitaammin seuraavalla käynnillä.</translation>
<translation id="6337534724793800597">Suodata käytäntöjä nimen mukaan</translation>
<translation id="6358450015545214790">Mitä nämä tarkoittavat?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Tästä voi seurata kuluja</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 muu ehdotus}other{# muuta ehdotusta}}</translation>
<translation id="6387754724289022810">Jos haluat maksaa nopeammin ensi kerralla, tallenna kortti ja laskutusosoite Google-tilillesi ja tälle laitteelle.</translation>
+<translation id="6390662030813198813">Insinööri-E</translation>
<translation id="6404511346730675251">Muokkaa kirjanmerkkiä</translation>
+<translation id="6406765186087300643">C0 (kirjekuori)</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="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="6434309073475700221">Hylkää</translation>
+<translation id="6446163441502663861">Kahu (kirjekuori)</translation>
<translation id="6446608382365791566">Lisää tietoja</translation>
<translation id="6447842834002726250">Evästeet</translation>
<translation id="6451458296329894277">Vahvista lomakkeen uudelleenlähetys</translation>
@@ -872,11 +990,17 @@
<translation id="6508722015517270189">Käynnistä Chrome uudelleen.</translation>
<translation id="6529602333819889595">&amp;Toista poisto</translation>
<translation id="6534179046333460208">Fyysisen webin ehdotukset</translation>
+<translation id="6556866813142980365">Tee uudelleen</translation>
<translation id="6563469144985748109">Ylläpitäjä ei ole hyväksynyt sitä vielä.</translation>
<translation id="6569060085658103619">Tämä on laajennussivu.</translation>
+<translation id="6578796323535178455">C2 (kirjekuori)</translation>
<translation id="6579990219486187401">Vaaleanpinkki</translation>
+<translation id="6583674473685352014">B6 (kirjekuori)</translation>
+<translation id="6587923378399804057">Kopioimasi linkki</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> ei ole ylläpidetty</translation>
<translation id="6596325263575161958">Salausasetukset</translation>
<translation id="6604181099783169992">Liike- tai valotunnistimet</translation>
+<translation id="6609880536175561541">Prc7 (kirjekuori)</translation>
<translation id="6624427990725312378">Yhteystiedot</translation>
<translation id="6626291197371920147">Lisää kelvollinen kortin numero</translation>
<translation id="6628463337424475685"><ph name="ENGINE" />-haku</translation>
@@ -885,6 +1009,7 @@
<translation id="6644283850729428850">Tämä käytäntö on vanhentunut.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ei mitään}=1{1 sivustolta (sinua ei kirjata ulos Google-tililtäsi)}other{# sivustolta (sinua ei kirjata ulos Google-tililtäsi)}}</translation>
<translation id="6657585470893396449">Salasana</translation>
+<translation id="6670613747977017428">Takaisin turvaan</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>
@@ -892,12 +1017,15 @@
<translation id="671076103358959139">Käyttöönottotunnus:</translation>
<translation id="6711464428925977395">Välityspalvelimessa on jotain vikaa tai osoite on virheellinen.</translation>
<translation id="6723740634201835758">Google-tililläsi</translation>
+<translation id="6738516213925468394">Datasi salattiin <ph name="BEGIN_LINK" />synkronoinnin tunnuslauseella<ph name="END_LINK" /> <ph name="TIME" />. Aloita synkronointi antamalla tunnuslause.</translation>
<translation id="674375294223700098">Tuntematon palvelimen varmennevirhe.</translation>
<translation id="6744009308914054259">Voit lukea artikkeleita offline-tilassa Lataukset-kohdassa, kun odotat yhteyden muodostamista.</translation>
<translation id="6753269504797312559">Käytännön arvo</translation>
<translation id="6757797048963528358">Laitteesi siirtyi virransäästötilaan.</translation>
+<translation id="6768213884286397650">Hagaki (postikortti)</translation>
<translation id="6778737459546443941">Vanhempasi ei ole hyväksynyt sitä vielä.</translation>
<translation id="67862343314499040">Lila</translation>
+<translation id="6786747875388722282">Laajennukset</translation>
<translation id="679355240208270552">Ohitettu, koska oletushaku on poistettu käytöstä käytännön johdosta</translation>
<translation id="681021252041861472">Pakollinen kenttä</translation>
<translation id="6810899417690483278">Muokkaustunnus</translation>
@@ -930,10 +1058,12 @@
<translation id="6965978654500191972">Laite</translation>
<translation id="6970216967273061347">Alue</translation>
<translation id="6973656660372572881">Sekä kiinteät välityspalvelimet että .pac-URL-osoite on määritetty.</translation>
+<translation id="6973932557599545801">En valitettavasti voi auttaa. Voit jatkaa omatoimisesti.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Mykistä (oletus)</translation>
<translation id="6984479912851154518">Yksityinen tila suljetaan, jotta voit tehdä maksun ulkoisella sovelluksella. Haluatko jatkaa?</translation>
<translation id="6989763994942163495">Näytä lisäasetukset...</translation>
+<translation id="6993898126790112050">6x9 (kirjekuori)</translation>
<translation id="6996312675313362352">Käännä aina <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Veloitukset voivat olla kertaluontoisia tai toistuvia, eikä niitä välttämättä esitetä selkeästi.</translation>
@@ -949,28 +1079,36 @@
<translation id="7108338896283013870">Piilota</translation>
<translation id="7108819624672055576">Laajennuksen sallima</translation>
<translation id="7111012039238467737">(Voimassa)</translation>
+<translation id="7118618213916969306">Hae leikepöydän URL-osoitetta, <ph name="SHORT_URL" /></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="7135130955892390533">Näytä tila</translation>
<translation id="7138472120740807366">Toimitustapa</translation>
<translation id="7139724024395191329">Emiirikunta</translation>
+<translation id="7152423860607593928">Nro 14 (kirjekuori)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Laventeli</translation>
-<translation id="7158980942472052083">Virheellinen URL-osoite Täytyy olla vakiomallin sisältävä URL-osoite</translation>
<translation id="717330890047184534">Gaia-tunnus:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Kohdepalvelin <ph name="ORIGIN" /> pyytää
+ tietosuojakäytännön soveltamista kaikkiin sen saamiin pyyntöihin. Käytännön näyttämisen sijaan se ohjaa selaimen muualle,
+ joten selain ei voi
+ toteuttaa <ph name="SITE" />-pyyntöäsi.</translation>
<translation id="7179323680825933600">Tallenna ja täytä maksutavat</translation>
<translation id="7180611975245234373">Päivitä</translation>
<translation id="7182878459783632708">Käytäntöjä ei ole asetettu</translation>
<translation id="7186367841673660872">Tämä sivu on käännetty kielestä<ph name="ORIGINAL_LANGUAGE" />kielelle<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Vapauttaa <ph name="SIZE" />. Jotkin sivustot saattavat latautua hitaammin seuraavalla käynnillä.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Järjestelmänvalvoja näkee seuraavat:</translation>
+<translation id="7202346780273620635">Kirje-ekstra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> ei noudata tietoturvastandardeja.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Lisätietoja<ph name="END_LINK" /> ongelmasta.</translation>
<translation id="7219179957768738017">Yhteys käyttää protokollaa <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Käsitellään.</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />, <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Seuraava verkkosivusto sisältää haittaohjelmia</translation>
+<translation id="724766306220616965">Varoituksia, ristiriita</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="7251437084390964440">Verkkoasetukset eivät noudata ONC-standardia. Kaikkia asetuksia ei välttämättä tuoda.
Lisätietoja:
@@ -983,11 +1121,14 @@ Lisätietoja:
<translation id="7300012071106347854">Koboltinsininen</translation>
<translation id="7302712225291570345"><ph name="TEXT" /></translation>
<translation id="7309308571273880165">Kaatumisraportti tallennettu <ph name="CRASH_TIME" /> (käyttäjä pyysi latausta, ei vielä ladattu)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Selaussuojan<ph name="END_LINK" /> varoitukset</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Yhteysohjeet</translation>
<translation id="7334320624316649418">&amp;Toista uudelleenjärjestely</translation>
<translation id="733923710415886693">Palvelimen varmenteesta ei ole saatu Certificate Transparencyn vaatimia tietoja.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-ekstra</translation>
<translation id="7353601530677266744">Komentorivi</translation>
-<translation id="7365061714576910172">Vie Linux-muodossa</translation>
<translation id="7372973238305370288">hakutulos</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ei</translation>
@@ -995,6 +1136,7 @@ Lisätietoja:
<translation id="7381288752349550461">Hallinnoidun istunnon ohittaminen</translation>
<translation id="7390545607259442187">Vahvista kortti</translation>
<translation id="7400418766976504921">URL-osoite</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> on ylläpidetty</translation>
<translation id="7407424307057130981">&lt;p&gt;Näet tämän virheen, jos Superfish-ohjelmisto on asennettuna Windows-tietokoneellesi.&lt;/p&gt;
&lt;p&gt;Voit poistaa ohjelmiston väliaikaisesti käytöstä ja päästä verkkoon noudattamalla näitä ohjeita. Nämä vaiheet edellyttävät järjestelmänvalvojan oikeuksia.&lt;/p&gt;
&lt;ol&gt;
@@ -1005,7 +1147,7 @@ Lisätietoja:
&lt;li&gt;Valitse &lt;strong&gt;Käytä&lt;/strong&gt; ja sen jälkeen &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Saat ohjeita ohjelmiston pysyvään poistamiseen tietokoneelta &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome-ohjekeskuksesta&lt;/a&gt;.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" />: ylläpito</translation>
+<translation id="741007362987735528">Leveä</translation>
<translation id="7416351320495623771">Ylläpidä salasanoja…</translation>
<translation id="7419106976560586862">Profiilin polku</translation>
<translation id="7437289804838430631">Lisää yhteystieto</translation>
@@ -1014,22 +1156,24 @@ Lisätietoja:
<translation id="7442725080345379071">Vaaleanoranssi</translation>
<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="7449109375006139765">Lähettää järjestelmälokeja hallintapalvelimelle</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="7460618730930299168">Näkymä eroaa valinnoistasi. Haluatko jatkaa?</translation>
<translation id="7473891865547856676">Ei kiitos</translation>
-<translation id="7475525192983021547">Ilmoittaa ajanjaksoista, jolloin käyttäjä on käyttänyt laitetta</translation>
<translation id="7481312909269577407">Seuraava</translation>
<translation id="7485870689360869515">Tietoja ei löydy.</translation>
+<translation id="7498234416455752244">Jatka muokkausta</translation>
<translation id="7508255263130623398">Palautettu käytännön laitetunnus on tyhjä tai ei vastaa nykyistä laitetunnusta.</translation>
<translation id="7508870219247277067">Avokadonvihreä</translation>
<translation id="7511955381719512146">Käyttämäsi Wi-Fi saattaa edellyttää vierailua osoitteessa <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Lataa</translation>
<translation id="7518003948725431193">Verkkosivua ei löytynyt osoitteelle: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (kirjekuori)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Sivustoon muodostamasi yhteys ei ole yksityinen.</translation>
+<translation id="7535087603100972091">Arvo</translation>
<translation id="7537536606612762813">Pakollinen</translation>
+<translation id="7538364083937897561">A2 (kirjekuori)</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>
@@ -1038,8 +1182,8 @@ Lisätietoja:
<translation id="7552846755917812628">Kokeile seuraavia keinoja:</translation>
<translation id="7554791636758816595">Uusi välilehti</translation>
<translation id="7564049878696755256">Saatat menettää <ph name="ORG_NAME" />-tilisi käyttöoikeuden tai joutua identiteettivarkauden uhriksi. Chrome suosittelee salasanan vaihtamista välittömästi.</translation>
-<translation id="7566125604157659769">Kopioimasi teksti</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="7568105740864181217">Yritys, koulu tai muu organisaatio ylläpitää tätä selainta. Järjestelmänvalvoja voi muuttaa selaimen määrityksiä etäyhteydellä. Toimintaa tällä laitteella saatetaan ylläpitää myös Chromen ulkopuolelta. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></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>
@@ -1050,6 +1194,7 @@ Lisätietoja:
<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="7633909222644580952">Tehokkuusdata ja virheraportit</translation>
<translation id="7637571805876720304">Poistetaanko luottokortti Chromiumista?</translation>
<translation id="7639968568612851608">Tummanharmaa</translation>
<translation id="765676359832457558">Piilota lisäasetukset...</translation>
@@ -1059,9 +1204,11 @@ Lisätietoja:
<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="7676643023259824263">Hae leikepöydän tekstiä <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Vaihda hakukonetta</translation>
<translation id="7682287625158474539">Toimitus</translation>
<translation id="7687186412095877299">Täyttää tallennetut maksutapasi maksulomakkeisiin</translation>
+<translation id="7697066736081121494">Prc8 (kirjekuori)</translation>
<translation id="769721561045429135">Joitakin korttejasi voi juuri nyt käyttää vain tällä laitteella. Katso kortit valitsemalla Jatka.</translation>
<translation id="7699293099605015246">Artikkelit eivät juuri nyt ole saatavilla.</translation>
<translation id="7701040980221191251">Ei mitään</translation>
@@ -1073,11 +1220,13 @@ Lisätietoja:
<translation id="774634243536837715">Vaarallinen sisältö estetty</translation>
<translation id="7752995774971033316">Ei hallinnoida</translation>
<translation id="7755287808199759310">Vanhempasi voi kumota eston puolestasi.</translation>
+<translation id="7757555340166475417">Dai Pa Kai (275 mm x 395 mm)</translation>
<translation id="7758069387465995638">Palomuuri tai virustorjuntaohjelmisto on saattanut estää yhteyden.</translation>
<translation id="7759163816903619567">Näytä verkkotunnus:</translation>
<translation id="7761701407923456692">Palvelimen varmenne ei vastaa URL-osoitetta.</translation>
<translation id="7763386264682878361">Maksuluettelon jäsentäjä</translation>
<translation id="7764225426217299476">Lisää osoite</translation>
+<translation id="7770259615151589601">Määritetty-pitkä</translation>
<translation id="777702478322588152">Prefektuuri</translation>
<translation id="7791543448312431591">Lisää</translation>
<translation id="7793809570500803535">Osoitteessa <ph name="SITE" /> oleva sivu saattaa olla väliaikaisesti pois käytöstä, tai se on voitu siirtää pysyvästi uuteen osoitteeseen.</translation>
@@ -1089,8 +1238,8 @@ Lisätietoja:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Poistetaanko lomake-ehdotus Chromen tiedoista?</translation>
<translation id="7815407501681723534">Haku <ph name="SEARCH_STRING" /> tuotti <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" />.</translation>
-<translation id="7818867226424560206">Käytäntöjen hallinta</translation>
<translation id="782886543891417279">Käyttämäsi Wi-Fi (<ph name="WIFI_NAME" />) saattaa edellyttää kirjautumista.</translation>
+<translation id="7836231406687464395">Postfix (kirjekuori)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ei mitään}=1{1 sovellus (<ph name="EXAMPLE_APP_1" />)}=2{2 sovellusta (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# sovellusta (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Et ole kuitenkaan näkymätön. Incognito-tilan käyttäminen ei kätke selaamistasi työnantajaltasi, internetpalveluntarjoajaltasi tai käyttämiltäsi sivustoilta.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1099,7 +1248,7 @@ Lisätietoja:
<translation id="7878562273885520351">Salasanasi on saattanut vaarantua.</translation>
<translation id="7882421473871500483">Ruskea</translation>
<translation id="7887683347370398519">Tarkista CVC ja yritä uudelleen.</translation>
-<translation id="7893255318348328562">Istunnon nimi</translation>
+<translation id="7904208859782148177">C3 (kirjekuori)</translation>
<translation id="79338296614623784">Anna kelvollinen puhelinnumero.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Vanhenee <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1109,21 +1258,25 @@ Lisätietoja:
<translation id="7951415247503192394">(32-bittinen)</translation>
<translation id="7956713633345437162">Mobiilikirjanmerkit</translation>
<translation id="7961015016161918242">Ei koskaan</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Ei määritetty</translation>
<translation id="800218591365569300">Yritä vapauttaa muistia sulkemalla muita välilehtiä tai ohjelmia.</translation>
+<translation id="8004582292198964060">Selain</translation>
<translation id="8009225694047762179">Salasanojen hallinta</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Tämä kortti ja sen laskutusosoite tallennetaan. Voit käyttää sitä sisäänkirjautuneena (<ph name="USER_EMAIL" />).}other{Nämä kortit ja niiden laskutusosoitteet tallennetaan. Voit käyttää niitä sisäänkirjautuneena (<ph name="USER_EMAIL" />).}}</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="8034522405403831421">Sivu on kirjoitettu kielellä <ph name="SOURCE_LANGUAGE" />. Haluatko kääntää sen kielelle <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Kynä</translation>
+<translation id="8037117624646282037">Kuka on käyttänyt laitetta äskettäin</translation>
<translation id="8037357227543935929">Kysy (oletus)</translation>
<translation id="803771048473350947">Tiedosto</translation>
<translation id="8041089156583427627">Lähetä palautetta</translation>
<translation id="8041940743680923270">Käytä yleistä oletusasetusta (kysy)</translation>
<translation id="8042918947222776840">Valitse noutotapa</translation>
<translation id="8057711352706143257"><ph name="SOFTWARE_NAME" /> on määritetty virheellisesti. Ongelma korjaantuu yleensä, jos <ph name="SOFTWARE_NAME" /> poistetaan. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Laitteen määritykset:</translation>
+<translation id="8066955247577885446">Jokin meni pieleen.</translation>
+<translation id="8074253406171541171">10x13 (kirjekuori)</translation>
<translation id="8078141288243656252">Kierrettyyn asiakirjaan ei voi tehdä merkintöjä</translation>
<translation id="8079031581361219619">Ladataanko sivusto uudelleen?</translation>
<translation id="8088680233425245692">Artikkelin näyttäminen epäonnistui.</translation>
@@ -1132,11 +1285,12 @@ Lisätietoja:
<translation id="8091372947890762290">Aktivointi odottaa palvelimella</translation>
<translation id="8092774999298748321">Tummanvioletti</translation>
<translation id="8094917007353911263">Käyttämäsi verkko saattaa edellyttää vierailua osoitteessa <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Virheelliset kortit on poistettu</translation>
<translation id="8103161714697287722">Maksutapa</translation>
<translation id="8118489163946903409">Maksutapa</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" />: ylläpitäjä on <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> on asennettu virheellisesti tietokoneellesi tai verkkoon. Pyydä järjestelmänvalvojaasi ratkaisemaan ongelma.</translation>
-<translation id="8130693978878176684">En voi enää auttaa. Voit jatkaa omatoimisesti.</translation>
<translation id="8131740175452115882">Vahvista</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>
@@ -1146,8 +1300,11 @@ Lisätietoja:
<translation id="8197543752516192074">Käännä sivu</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="8202370299023114387">Ristiriita</translation>
+<translation id="8206978196348664717">Prc4 (kirjekuori)</translation>
<translation id="8211406090763984747">Yhteys on turvallinen</translation>
<translation id="8218327578424803826">Määrätty sijainti:</translation>
+<translation id="8220146938470311105">C7/C6 (kirjekuori)</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="8238581221633243064">Avaa sivu uudessa incognito-välilehdessä.</translation>
@@ -1159,14 +1316,16 @@ Lisätietoja:
<translation id="825929999321470778">Näytä kaikki tallennetut salasanat</translation>
<translation id="8261506727792406068">Poista</translation>
<translation id="8267698848189296333">Kirjaudutaan käyttäjänä <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Tämän selaimen ylläpitäjä on <ph name="ENROLLMENT_DOMAIN" />. Järjestelmänvalvoja voi muuttaa selaimen määrityksiä etäyhteydellä. Toimintaa tällä laitteella saatetaan ylläpitää myös Chromen ulkopuolelta. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Suuri kuva</translation>
<translation id="8286036467436129157">Kirjaudu sisään</translation>
<translation id="8288807391153049143">Näytä varmenne</translation>
<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="8298115750975731693">Käyttämäsi Wi-Fi (<ph name="WIFI_NAME" />) saattaa edellyttää vierailua osoitteessa <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Pieni kuva</translation>
<translation id="8308427013383895095">Käännös epäonnistui, koska verkkoyhteydessä esiintyi ongelmia.</translation>
-<translation id="8311129316111205805">Lataa istunto</translation>
<translation id="8332188693563227489">Sivuston <ph name="HOST_NAME" /> käyttöoikeus evättiin</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1184,7 +1343,6 @@ Lisätietoja:
<translation id="8416694386774425977">Verkkoasetukset ovat virheelliset eikä niitä voi tuoda.
Lisätietoja:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Laitteen ylläpitäjä: <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Vaihda</translation>
<translation id="8428213095426709021">Asetukset</translation>
@@ -1212,9 +1370,11 @@ Lisätietoja:
<translation id="860043288473659153">Kortinhaltijan nimi</translation>
<translation id="861775596732816396">Koko 4</translation>
<translation id="8620436878122366504">Vanhempasi eivät ole hyväksyneet sitä vielä.</translation>
+<translation id="8622948367223941507">Laki-ekstra</translation>
<translation id="8625384913736129811">Tallenna kortti tälle laitteelle</translation>
<translation id="8663226718884576429">Tilauksen yhteenveto, <ph name="TOTAL_LABEL" />, lisätietoja</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, vastaus, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Yhteyttäsi verkkotunnukseen <ph name="DOMAIN" /> ei ole salattu.</translation>
<translation id="8718314106902482036">Maksua ei suoritettu loppuun</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, hakuehdotus</translation>
@@ -1228,6 +1388,7 @@ Lisätietoja:
<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="8763927697961133303">USB-laite</translation>
<translation id="8768895707659403558">Jos haluat käyttää kortteja kaikilla laitteillasi, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Toista poisto</translation>
<translation id="8792621596287649091">Saatat menettää <ph name="ORG_NAME" />-tilisi käyttöoikeuden tai joutua identiteettivarkauden uhriksi. Chromium suosittelee salasanan vaihtamista välittömästi.</translation>
<translation id="8800988563907321413">Nearby-ehdotuksesi näkyvät tässä.</translation>
@@ -1238,10 +1399,12 @@ Lisätietoja:
<translation id="885730110891505394">Googlen kanssa jakaminen</translation>
<translation id="8858065207712248076">Chrome suosittelee organisaation <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> salasanasi vaihtamista, jos olet käyttänyt sitä myös muilla sivustoilla.</translation>
<translation id="8866481888320382733">Virhe jäsennettäessä käytännön asetuksia</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Hiljattain suljetut</translation>
<translation id="8874824191258364635">Anna kelvollinen kortin numero.</translation>
<translation id="8891727572606052622">Virheellinen välityspalvelimen tila.</translation>
<translation id="8903921497873541725">Lähennä</translation>
+<translation id="890485472659500557">Insinööri-C</translation>
<translation id="8931333241327730545">Haluatko tallentaa tämän kortin Google-tilillesi?</translation>
<translation id="8932102934695377596">Kellosi jätättää</translation>
<translation id="893332455753468063">Lisää nimi</translation>
@@ -1249,13 +1412,13 @@ Lisätietoja:
<translation id="894185898663964645">Järjestelmänvalvoja on määrittänyt yksilöidyt juurivarmenteet, joiden avulla hän voi mahdollisesti nähdä avaamiesi verkkosivustojen sisällön.</translation>
<translation id="8943282376843390568">Lime</translation>
<translation id="8957210676456822347">Captive portal -valtuutus</translation>
+<translation id="8966619695390250636">Tarkoititko?</translation>
<translation id="8968766641738584599">Tallenna kortti</translation>
<translation id="8971063699422889582">Palvelimen varmenne on vanhentunut.</translation>
<translation id="8975012916872825179">Tallenna puhelinnumerot, sähköpostiosoitteet, toimitusosoitteet ja muita tietoja</translation>
<translation id="8978053250194585037">Googlen selaussuoja havaitsi äskettäin <ph name="BEGIN_LINK" />tietojenkalasteluyrityksen<ph name="END_LINK" /> sivustolla <ph name="SITE" />. Tietojenkalastelusivustot yrittävät huijata käyttäjiä tekeytymällä toisiksi sivustoiksi.</translation>
<translation id="8983003182662520383">Maksutavat ja osoitteet Google Paysta</translation>
<translation id="8987927404178983737">Kuukausi</translation>
-<translation id="8988408250700415532">Jokin meni vikaan. Voit viimeistellä tilauksesi verkkosivustolla.</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>
@@ -1265,6 +1428,7 @@ Lisätietoja:
<translation id="9011424611726486705">Avaa sivustoasetukset</translation>
<translation id="9020200922353704812">Kortin laskutusosoite pakollinen</translation>
<translation id="9020542370529661692">Sivu on käännetty kielelle <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Virheellinen)</translation>
<translation id="9035022520814077154">Suojausvirhe</translation>
<translation id="9038649477754266430">Ennakointipalvelun avulla voit ladata sivuja nopeammin</translation>
@@ -1276,11 +1440,11 @@ Lisätietoja:
<translation id="9065745800631924235">Historiasta löydetty haku <ph name="TEXT" /></translation>
<translation id="9069693763241529744">Laajennuksen estämä</translation>
<translation id="9076283476770535406">Se saattaa sisältää vain aikuisille tarkoitettua sisältöä.</translation>
+<translation id="9076630408993835509">Yritys tai muu organisaatio ei ylläpidä selainta. Laitteen toimintaa saatetaan ylläpitää muualta kuin Chromesta käsin. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Lisätietoja tarvitaan</translation>
<translation id="9080712759204168376">Tilauksen yhteenveto</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>
<translation id="9106062320799175032">Lisää laskutusosoite</translation>
-<translation id="9110718169272311511">Chromen Google Assistant on käytettävissä näytön alareunassa</translation>
<translation id="9114524666733003316">Vahvistetaan korttia…</translation>
<translation id="9128870381267983090">Yhdistä verkkoon</translation>
<translation id="9137013805542155359">Näytä alkuperäinen</translation>
@@ -1289,6 +1453,7 @@ Lisätietoja:
<translation id="9148507642005240123">K&amp;umoa muokkaus</translation>
<translation id="9154194610265714752">Päivitetty</translation>
<translation id="9157595877708044936">Valmistellaan...</translation>
+<translation id="9158625974267017556">C6 (kirjekuori)</translation>
<translation id="9168814207360376865">Salli sivustojen tarkastaa, oletko tallentanut maksutapoja</translation>
<translation id="9169664750068251925">Estä aina tämä sivusto</translation>
<translation id="9170848237812810038">K&amp;umoa</translation>
@@ -1303,10 +1468,12 @@ Lisätietoja:
<translation id="9219103736887031265">Kuvat</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">TYHJENNÄ LOMAKE</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Saatat menettää Google-tilisi käyttöoikeuden. Chromium suosittelee vaihtamaan salasanan nyt. Sinua pyydetään kirjautumaan sisään.</translation>
<translation id="939736085109172342">Uusi kansio</translation>
<translation id="945855313015696284">Tarkista tiedot alta ja poista virheelliset kortit.</translation>
<translation id="951104842009476243">Hyväksytyt maksu- ja prepaid-kortit</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> estää tämän tietosuojakäytännössään</translation>
<translation id="962484866189421427">Tämä sisältö voi yrittää asentaa petollisia sovelluksia, jotka esiintyvät jonakin muuna tai keräävät tietoja, joilla sinua voidaan seurata. <ph name="BEGIN_LINK" />Näytä silti<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Virallinen koontiversio</translation>
<translation id="973773823069644502">Lisää jakeluosoite</translation>
@@ -1315,6 +1482,7 @@ Lisätietoja:
<translation id="984275831282074731">Maksutavat</translation>
<translation id="985199708454569384">&lt;p&gt;Näet tämän virheen, jos tietokoneen tai mobiililaitteen päivämäärä ja aika ovat virheellisiä.&lt;/p&gt;
&lt;p&gt;Korjaa ongelma avaamalla laitteen kello ja varmistamalla, että päivämäärä ja aika ovat oikein.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Kehittäjän koontiversio</translation>
<translation id="989988560359834682">Osoitteen muokkaus</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_fil.xtb b/chromium/components/strings/components_strings_fil.xtb
index 545d4a710f9..b4400599c92 100644
--- a/chromium/components/strings/components_strings_fil.xtb
+++ b/chromium/components/strings/components_strings_fil.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fil">
-<translation id="1005145902654145231">Hindi napalitan ang pangalan ng session.</translation>
<translation id="1008557486741366299">Hindi Ngayon</translation>
<translation id="1010200102790553230">I-load ang page sa ibang pagkakataon</translation>
<translation id="1015730422737071372">Magbigay ng mga karagdagang detalye</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">Hindi kilalang pangalan</translation>
<translation id="1050038467049342496">Isara ang iba pang app</translation>
<translation id="1055184225775184556">&amp;I-undo ang Pagdagdag</translation>
+<translation id="1056898198331236512">Babala</translation>
<translation id="1058479211578257048">Sine-save ang mga card...</translation>
<translation id="10614374240317010">Hindi kailanman nag-save</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Mga Bookmark sa Desktop</translation>
<translation id="1074497978438210769">Hindi secure</translation>
<translation id="1080116354587839789">Pagkasyahin sa lapad</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Magdagdag ng Pangalan sa Card</translation>
<translation id="1089439967362294234">Palitan ang Password</translation>
<translation id="109743633954054152">Pamahalaan ang mga password sa mga setting ng Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Maaaring karaniwang may mga babala habang nag-a-update para sa seguridad ang mga website. Maaayos din ito sa lalong madaling panahon.</translation>
<translation id="1126551341858583091">Ang laki sa lokal na storage ay <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">OK ang cache ng patakaran</translation>
+<translation id="1131264053432022307">Larawang Kinopya Mo</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Pangalanang muli</translation>
<translation id="1175364870820465910">&amp;I-print...</translation>
<translation id="1181037720776840403">Alisin</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Ang pangalan ng iyong device</translation>
<translation id="124116460088058876">Higit pang wika</translation>
<translation id="1250759482327835220">Para mas mabilis na makapagbayad sa susunod, i-save ang iyong card, pangalan, at billing address sa Google Account mo.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (naka-sync)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Mga variation ng command-line</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="1314614906530272393">Hindi umiiral ang piniling session.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Maghanap ng larawan sa clipboard</translation>
<translation id="1323433172918577554">Magpakita Nang Higit Pa</translation>
<translation id="132390688737681464">I-save at Punan ang Mga Address</translation>
<translation id="1333989956347591814">Ang iyong aktibidad <ph name="BEGIN_EMPHASIS" />ay maaari pa ring makita<ph name="END_EMPHASIS" /> ng:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Address sa pag-pick up</translation>
<translation id="1348198688976932919">May mapapanganib na app ang pupuntahang site</translation>
<translation id="1348779747280417563">Kumpirmahin ang pangalan</translation>
+<translation id="1357195169723583938">Sino ang gumamit sa device kamakailan at kailan</translation>
+<translation id="1364822246244961190">Naka-block ang patakarang ito, babalewalain ang value nito.</translation>
<translation id="1374468813861204354">mga suhestiyon</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Tungkol sa Bersyon</translation>
<translation id="1376836354785490390">Magpakita Nang Mas Kaunti</translation>
<translation id="1377321085342047638">Numero ng Card</translation>
<translation id="138218114945450791">Light Blue</translation>
+<translation id="1382194467192730611">USB device na pinapayagan ng iyong administrator</translation>
<translation id="139305205187523129">Hindi nagpadala ng anumang data ang <ph name="HOST_NAME" />.</translation>
+<translation id="140316286225361634">Hiniling ng site na <ph name="ORIGIN" /> na ilapat ang isang patakaran sa seguridad
+ sa lahat ng kahilingan nito, at kasalukuyang ipinagpapalagay ng patarakang ito na
+ hindi ligtas ang site.</translation>
<translation id="1405567553485452995">Light Green</translation>
<translation id="1407135791313364759">Buksan lahat</translation>
<translation id="1413809658975081374">Error sa privacy</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Oo</translation>
<translation id="1430915738399379752">I-print</translation>
<translation id="1455413310270022028">Pambura</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Magpakita ng higit pa</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Pumili ng Address sa Pagpapadala</translation>
+<translation id="1492194039220927094">Pag-push ng mga patakaran:</translation>
<translation id="1501859676467574491">Ipakita ang mga card mula sa iyong Google Account</translation>
-<translation id="1506687042165942984">Magpakita ng naka-save (ibigsabihin alam na hindi napapanahon) na kopya ng page na ito.</translation>
<translation id="1507202001669085618">&lt;p&gt;Makikita mo ang error na ito kung gumagamit ka ng Wi-Fi portal kung saan kailangan mong mag-sign in bago ka makapag-online.&lt;/p&gt;
&lt;p&gt;Para maayos ang error, i-click ang &lt;strong&gt;Kumonekta&lt;/strong&gt; sa page na sinusubukan mong buksan.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Kinakailangan ang numero ng telepono</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Petsa ng Build</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">Naghihintay ng koneksyon…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Isinasaad ng page na ito na</translation>
<translation id="153384715582417236">'Yan na muna sa ngayon</translation>
<translation id="154408704832528245">Pumili ng Address sa Paghahatid</translation>
<translation id="1549470594296187301">Dapat naka-enable ang JavaScript upang magamit ang feature na ito.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Ilagay ang petsa ng pag-expire</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Nagkaproblema 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="1618822247301510817">Larawang kinopya mo</translation>
<translation id="1620510694547887537">Camera</translation>
<translation id="1623104350909869708">Pigilan ang pahinang ito sa paggawa ng mga karagdagang dialog</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Tapusin ang session</translation>
<translation id="1639239467298939599">Naglo-load</translation>
<translation id="1640180200866533862">Mga patakaran ng user</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Naglalaman ang server certificate ng isang mahinang cryptographic key.</translation>
<translation id="1697532407822776718">Handa ka na!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Masyadong malaki para i-annotate ang dokumento</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Subukang makipag-ugnayan sa admin ng system.</translation>
<translation id="1740951997222943430">Maglagay ng wastong buwan ng pag-expire</translation>
<translation id="1743520634839655729">Para mas mabilis na makapagbayad sa susunod, i-save ang iyong card, pangalan, at billing address sa Google Account mo at sa device na ito.</translation>
+<translation id="1745880797583122200">Pinapamahalaan ang iyong browser</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>
@@ -152,8 +172,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Pangalan ng Cardholder</translation>
<translation id="1821930232296380041">Di-wastong kahilingan o mga parameter ng kahilingan</translation>
+<translation id="1822540298136254167">Mga website na binibisita mo at oras na ginugugol dito</translation>
<translation id="1826516787628120939">Sinusuri</translation>
<translation id="1834321415901700177">Naglalaman ng mga mapanirang program ang site na ito</translation>
<translation id="1839551713262164453">Hindi na-validate ang mga value ng patakaran at may mga error</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">I-clear ang data ng history ng pag-browse sa Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{at 1 pa}one{at # pa}other{at # pa}}</translation>
<translation id="2003709556000175978">I-reset na ang iyong password</translation>
+<translation id="20053308747750172">Hiniling ng server na pupuntahan mo, ang <ph name="ORIGIN" />, na
+ ilapat ang isang patakaran sa seguridad sa lahat ng kahilingan dito. Ngunit naghatid ito ngayon
+ ng invalid na patakaran, na pinipigilan ang browser na
+ tuparin ang iyong kahilingan para sa <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Nakatakda sa awtomatikong naka-configure ang proxy.</translation>
<translation id="2030481566774242610">Ang ibig mo bang sabihin ay <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Suriin ang proxy at ang firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Kagawaran</translation>
<translation id="2102134110707549001">Magmungkahi ng Malakas na Password...</translation>
<translation id="2108755909498034140">I-restart ang iyong computer</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Card</translation>
<translation id="2114841414352855701">Binalewala dahil na-override ito ng <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mga Bookmark sa Mobile</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Mga Patakaran</translation>
<translation id="2183608646556468874">Numero ng Telepono</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 address}one{# address}other{# na address}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Numero ng telepono</translation>
<translation id="2283340219607151381">I-save at punan ang mga address</translation>
<translation id="2292556288342944218">Naka-block ang iyong access sa Internet</translation>
+<translation id="2294558542833290837">Hindi pangkaraniwan ang link na orihinal mong binuksan</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Magbabakante ng wala pang 1 MB. Maaaring mag-load nang mas mabagal ang ilang site sa iyong susunod na pagbisita.</translation>
<translation id="2317259163369394535">Kailangan ng <ph name="DOMAIN" /> ng username at password.</translation>
<translation id="2317583587496011522">Tinatanggap ang mga debit card.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, mag-e-expire sa <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Kinokontrol ng iyong administrator ang setting</translation>
+<translation id="2346319942568447007">Larawang kinopya mo</translation>
<translation id="2349790679044093737">Aktibo ang VR session</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Nakapribado ka</translation>
+<translation id="2380886658946992094">Legal</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 paraan ng pagpapadala na ito. Sumubok ng ibang paraan.</translation>
<translation id="2396249848217231973">&amp;I-undo ang pagtanggal</translation>
+<translation id="2410754574180102685">Government-Legal</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="2418081434543109369">Hiniling ng server na pupuntahan mo, ang <ph name="ORIGIN" />, na
+ ilapat ang isang patakaran sa seguridad sa lahat ng kahilingan dito. Ngunit hindi ito
+ nakapaghatid ng patakaran ngayon, na pinipigilan ang browser na tuparin ang
+ ang iyong kahilingan para sa <ph name="SITE" />.</translation>
<translation id="244665789865330679">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang iyong device at account. Nangangahulugan itong maaaring malayuang i-configure ng iyong administrator ang device at account mo.</translation>
<translation id="2463193859425327265">Baguhin ang Home Page</translation>
<translation id="2463739503403862330">Punan</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Pumili ng Paraan ng Paghahatid</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Magpatakbo ng Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">I-translate ang pahinang ito</translation>
<translation id="2479410451996844060">Di-wastong URL ng paghahanap.</translation>
<translation id="2482878487686419369">Mga Abiso</translation>
<translation id="248348093745724435">Mga patakaran sa machine</translation>
+<translation id="2485387744899240041">Mga username para sa iyong device at browser</translation>
<translation id="2491120439723279231">Naglalaman ng mga error ang certificate ng server.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Mag-scan ng bagong card</translation>
<translation id="2501278716633472235">Bumalik</translation>
<translation id="2503184589641749290">Mga tinatanggap na debit at prepaid card</translation>
<translation id="2515629240566999685">Suriin ang signal sa iyong lugar</translation>
-<translation id="2516852381693169964">Maghanap sa <ph name="SEARCH_ENGINE" /> ng Larawan</translation>
<translation id="2523886232349826891">Ise-save sa device lang na ito</translation>
<translation id="2524461107774643265">Magdagdag ng Higit Pang Impormasyon</translation>
<translation id="2536110899380797252">Magdagdag ng Address</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">Nauuna ang iyong orasan</translation>
<translation id="2634124572758952069">Hindi makita ang IP address ng server ng <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Katayuan:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Isara ang iba pang tab o app</translation>
<translation id="267371737713284912">pindutin ang <ph name="MODIFIER_KEY_DESCRIPTION" /> para i-undo</translation>
<translation id="2674170444375937751">Sigurado ka bang nais mong tanggalin ang mga pahinang ito mula sa iyong history?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Umalis</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Mga Tinatanggap na Card</translation>
<translation id="2702801445560668637">Listahan ng Babasahin</translation>
<translation id="2704283930420550640">Hindi tumutugma ang format sa halaga.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Alisin ang mga napiling item</translation>
<translation id="277133753123645258">Paraan ng pagpapadala</translation>
<translation id="277499241957683684">Nawawalang tala ng device</translation>
-<translation id="2781030394888168909">I-export para sa MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Na-reset ang koneksyon.</translation>
<translation id="2788784517760473862">Mga tinatanggap na credit card</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Magbukas ng Incognito Window</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Kailangan mo ng pahintulot upang mabisita ang site na ito</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">I-save ang card?</translation>
<translation id="2903493209154104877">Mga Address</translation>
<translation id="290376772003165898">Hindi nakasalin ang page sa <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Paraan ng Paghahatid</translation>
<translation id="2928905813689894207">Billing Address</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Maling uri ng patakaran</translation>
<translation id="3037605927509011580">Ay, Naku!</translation>
<translation id="3041612393474885105">Impormasyon sa Certificate</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Magdagdag ng Address sa Pag-pick up</translation>
<translation id="3105172416063519923">Asset ID:</translation>
<translation id="3109728660330352905">Wala kang pahintulot na tingnan ang page na ito.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> sa <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Kanselahin ang Pagbabayad</translation>
<translation id="3207960819495026254">Naka-bookmark</translation>
-<translation id="3209375525920864198">Maglagay ng valid na pangalan ng session.</translation>
+<translation id="321912867715453276">Babala: May umiiral na mahigit sa isang source para sa patakaran, ngunit pareho ang mga value.</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="3229041911291329567">Impormasyon ng bersyon tungkol sa iyong device at browser</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Magdagdag ng pangalan sa card</translation>
<translation id="3287510313208355388">I-download kapag online</translation>
<translation id="3293642807462928945">Matuto pa tungkol sa patakarang <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Walang nakitang resulta ng paghahanap</translation>
-<translation id="3305707030755673451">Na-encrypt ang iyong data gamit ang iyong passphrase sa pag-sync noong <ph name="TIME" />. Ilagay ito upang simulan ang pag-sync.</translation>
<translation id="3320021301628644560">Magdagdag ng billing address</translation>
<translation id="3324983252691184275">Crimson</translation>
<translation id="3338095232262050444">Secure</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Gawing Muli ang Pag-e-edit</translation>
<translation id="342781501876943858">Inirerekomenda ng Chromium na i-reset ang iyong password kung ginamit mo ito sa iba pang site.</translation>
<translation id="3431636764301398940">I-save ang card na ito sa device na ito</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Na-off ng may-ari ng device na ito ang larong dinosaur.</translation>
<translation id="3447884698081792621">Ipakita ang certificate (ibinigay ng <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Kunin ang agwat:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Highlighter</translation>
<translation id="3462200631372590220">Itago ang advanced</translation>
<translation id="3467763166455606212">Kinakailangan ang pangalan ng cardholder</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Tinatanggap ang mga credit at prepaid card.</translation>
<translation id="3582930987043644930">Magdagdag ng pangalan</translation>
<translation id="3583757800736429874">&amp;Gawing Muli ang Paglilipat</translation>
+<translation id="35866233670761917">Hindi nakikita ng iyong mga administrator ang mga content ng mga website na binibisita mo</translation>
<translation id="3586931643579894722">Magtago ng mga detalye</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Laki 2</translation>
<translation id="3615877443314183785">Maglagay ng wastong petsa ng pag-expire</translation>
<translation id="36224234498066874">I-clear ang Data sa Pag-browse...</translation>
<translation id="362276910939193118">Ipakita ang Buong History</translation>
-<translation id="3623476034248543066">Ipakita ang halaga</translation>
<translation id="3630155396527302611">Kung nakalista na ito bilang isang programang pinapahintulutang i-access ang network, subukang
alisin ito mula sa listahan at muli itong idagdag.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Matagumpay ang pagpapatunay</translation>
<translation id="3655670868607891010">Kung madalas mo itong nakikita, subukan ang mga ito <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Rebisyon</translation>
<translation id="366077651725703012">I-update ang Credit Card</translation>
<translation id="3676592649209844519">Device ID:</translation>
+<translation id="3677008721441257057">Ang ibig mo bang sabihin ay &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Hindi malagdaan ang kahilingan</translation>
<translation id="3678529606614285348">Buksan ang page sa bagong Incognito window (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Nakuha ang ulat ng pag-crash noong <ph name="CRASH_TIME" />, na-upload noong <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Ang network na ginagamit mo ay maaaring humiling sa iyo na bisitahin ang page ng pag-login nito.</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="3709599264800900598">Text Na Kinopya Mo</translation>
<translation id="3712624925041724820">Naubos na ang mga lisensya</translation>
<translation id="3714780639079136834">I-on ang mobile data o Wi-Fi</translation>
<translation id="3715597595485130451">Kumonekta sa Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Suriin ang configuration ng proxy, firewall at DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Kabilang ang antivirus, firewall, at pag-filter ng web o proxy na software sa mga application na maaaring magsanhi ng ganitong error.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Account.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Mag-e-expire sa <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Laki 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Na-block ang mapaminsalang content.</translation>
<translation id="3810973564298564668">Mamahala</translation>
<translation id="382518646247711829">Kung gumagamit ka ng proxy server...</translation>
<translation id="3828924085048779000">Hindi pinapayagan ang walang laman na passphrase.</translation>
+<translation id="3831915413245941253">Nag-install ang <ph name="ENROLLMENT_DOMAIN" /> ng mga extension para sa mga karagdagang function. May access ang mga extension sa ilan sa iyong data.</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>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Palaging hilingin sa site na ito</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Mayroon nang ganitong pangalan ng session.</translation>
<translation id="3987940399970879459">Wala pang 1 MB</translation>
+<translation id="4008849406247176967">Babala: May umiiral na mahigit sa isang source na may mga hindi tumutugmang value para sa patakarang ito!</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="4030383055268325496">&amp;I-undo ang pagdagdag</translation>
+<translation id="4032320456957708163">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang iyong browser</translation>
<translation id="4058922952496707368">Key "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Magdagdag ng Wastong Address</translation>
<translation id="4072486802667267160">Nagkaroon ng error sa pagproseso ng iyong order. Pakisubukang muli.</translation>
<translation id="4075732493274867456">Hindi sinusuportahan ng client at server ang isang karaniwang bersyon o cipher suite ng SSL protocol.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Lila</translation>
<translation id="4165986682804962316">Mga setting ng site</translation>
<translation id="4171400957073367226">Hindi wasto ang signature sa pag-verify</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> pang item}one{<ph name="ITEM_COUNT" /> pang item}other{<ph name="ITEM_COUNT" /> pang item}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Hakbang 1: Mag-sign in sa portal&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">I-reset ang password</translation>
<translation id="4280429058323657511">, exp <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Na-save na ang card na ito sa iyong Google Account}one{Na-save na ang mga card na ito sa iyong Google Account}other{Na-save na ang mga card na ito sa iyong Google Account}}</translation>
+<translation id="42981349822642051">Palawakin</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Lumipat</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">I-block (default)</translation>
+<translation id="4318566738941496689">Ang pangalan ng iyong device at address ng network</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="4340982228985273705">Hindi na-detect ang computer na ito bilang pinamamahalaan ng enterprise kaya awtomatiko lang na mai-install ng patakaran ang mga extension na hino-host sa Chrome Webstore. Ang URL ng pag-update ng Chrome Webstore ay "<ph name="CWS_UPDATE_URL" />."</translation>
<translation id="4346197816712207223">Mga Tinatanggap na Credit Card</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Pamahalaan ang mga paraan ng pagbabayad...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telepono</translation>
<translation id="4406896451731180161">mga resulta ng paghahanap</translation>
-<translation id="4406972042435603828">Ang iyong mga administrator ay may mga naka-install na extension na may mahuhusay na kakayahan.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Address sa Pag-pick up</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="443121186588148776">Serial port</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="4434045419905280838">Mga pop-up at pag-redirect</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Hindi pinagana ang paggamit ng isang proxy ngunit tinutukoy ang isang tahasang configuration ng proxy.</translation>
<translation id="445100540951337728">Mga tinatanggap na debit card</translation>
+<translation id="4466881336512663640">Mawawala ang mga pagbabago sa form. Sigurado ka bang gusto mong magpatuloy?</translation>
<translation id="4482953324121162758">Hindi ita-translate ang site na ito.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Di-wastong URL. Dapat ay isang URL na may karaniwang scheme, hal. http://example.com o https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Mga Detalye</translation>
<translation id="4524805452350978254">Pamahalaan ang mga card</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Subukang i-disable ang iyong mga extension.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Paghahatid</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Alisin ang card</translation>
<translation id="4587425331216688090">Alisin ang address sa Chrome?</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="4597348597567598915">Laki 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Dalhin na ako roon</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Ihinto ang paggamit ng di-wastong certificate</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Naputol ang iyong koneksyon</translation>
<translation id="471880041731876836">Wala kang pahintulot na bisitahin ang site na ito</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Magpatakbo ng Windows Network Diagnostics<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">I-reload ang mga patakaran</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">I-restart ang Chromium</translation>
<translation id="473775607612524610">I-update</translation>
<translation id="4738601419177586157">Suhestyon sa paghahanap para sa <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Pamahalaan ang mga password...</translation>
<translation id="4744603770635761495">Naipapatupad na Path</translation>
+<translation id="4746351372139058112">Mga Mensahe</translation>
<translation id="4750917950439032686">Pribado ang iyong impormasyon (halimbawa, mga password o credit card number) kapag ipinadala ito sa site na ito.</translation>
<translation id="4756388243121344051">&amp;History</translation>
<translation id="4758311279753947758">Magdagdag ng impormasyon sa pakikipag-ugnayan</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Ang webpage sa <ph name="URL" /> ay maaaring pansamantalang hindi gumagana o maaaring permanente itong inilipat sa isang bagong web address.</translation>
<translation id="4771973620359291008">Isang hindi alam na error ang nangyari.</translation>
<translation id="4785689107224900852">Lumipat sa tab na ito</translation>
-<translation id="4792143361752574037">Nagkaproblema sa pag-access sa mga session file. Kasalukuyang naka-disable ang pag-save sa disk. Paki-reload ang page upang subukang muli.</translation>
<translation id="4798078619018708837">Ilagay ang petsa ng pag-expire at CVC para sa <ph name="CREDIT_CARD" /> para i-update ang mga detalye ng iyong card. Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Account.</translation>
<translation id="4800132727771399293">Tingnan ang iyong petsa ng pag-expire at CVC at subukang muli</translation>
+<translation id="480334179571489655">Error sa Patakaran ng Pinagmulan</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Buksan</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Walang mga resulta</translation>
<translation id="4950898438188848926">Button sa paglipat ng tab, pindutin ang Enter para lumipat sa nakabukas na tab, na <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Mga Pagkilos</translation>
-<translation id="495832697253704892">Pag-uulat ng extension</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Palawakin ang listahan</translation>
<translation id="4974590756084640048">Muling i-enable ang mga babala</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Tingnan lahat</translation>
<translation id="4989809363548539747">Hindi sinusuportahan ang plugin na ito</translation>
-<translation id="4996230189582812866">Pag-uulat</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="5014174725590676422">Ipinapakita ang screen ng unang pagtakbo ng Google Assistant sa Chrome</translation>
<translation id="5015510746216210676">Pangalan ng Machine:</translation>
+<translation id="5017554619425969104">Text na kinopya mo</translation>
<translation id="5018422839182700155">Hindi mabuksan ang page na ito</translation>
<translation id="5019198164206649151">Hindi maganda ang katayuan ng backing store</translation>
<translation id="5023310440958281426">Suriin ang mga patakaran ng iyong administrator</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Lokal na Konteksto <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Payagan</translation>
<translation id="5040262127954254034">Privacy</translation>
+<translation id="5043480802608081735">Link na Kinopya Mo</translation>
<translation id="5045550434625856497">Hindi wastong password</translation>
<translation id="5056549851600133418">Mga artikulo para sa iyo</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Suriin ang proxy address<ph name="END_LINK" /></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">Lalawigan</translation>
+<translation id="5097099694988056070">Mga istatistika ng device gaya ng paggamit ng CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang iyong device at pinapamahalaan ng <ph name="ACCOUNT_DOMAIN" /> ang account mo. Nangangahulugan itong maaaring malayuang i-configure ng iyong mga administrator ang device at account mo.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">Hindi valid ang session na may ganitong pangalan upang ma-delete.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Pamahalaan ang mga address...</translation>
+<translation id="5138227688689900538">Magpakita ng mas kaunti</translation>
<translation id="5141240743006678641">I-encrypt ang mga naka-sync na password gamit ang iyong mga kredensyal sa Google</translation>
<translation id="5145883236150621069">May code ng error sa tugon sa patakaran</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Buksan ang page sa bagong Incognito window (⇧⌘N)</translation>
<translation id="516920405563544094">Ilagay ang CVC para sa <ph name="CREDIT_CARD" />. Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Account.</translation>
<translation id="5169827969064885044">Maaari kang mawalan ng access sa account ng iyong organisasyon o manakawan ng pagkakakilanlan. Inirerekomenda ng Chrome na palitan ang iyong password ngayon.</translation>
<translation id="5171045022955879922">Hanapin o i-type ang URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Computer</translation>
<translation id="5179510805599951267">Wala sa <ph name="ORIGINAL_LANGUAGE" />? Iulat ang error na ito</translation>
<translation id="5190835502935405962">Bar ng Mga Bookmark</translation>
-<translation id="5200263511887412697">nag-uulat ng listahan ng mga user ng device na kamakailang nag-log in</translation>
+<translation id="519422657042045905">Hindi available ang anotasyon</translation>
<translation id="5201306358585911203">Isinasaad ng naka-embed na page sa page na ito na</translation>
<translation id="5205222826937269299">Kailangan ng pangalan</translation>
<translation id="5215116848420601511">Mga paraan ng pagbabayad at address gamit ang Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Kailangan ng email</translation>
<translation id="5230733896359313003">Address na Padadalhan</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Kumonekta sa network"</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Mga address ng network</translation>
<translation id="5285570108065881030">Ipakita ang lahat ng naka-save na password</translation>
<translation id="5287240709317226393">Ipakita ang cookies</translation>
<translation id="5288108484102287882">Na-validate ang mga value ng patakaran at nagkaroon ng mga babala</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> ng <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Pumili ng Impormasyon sa Pakikipag-ugnayan</translation>
<translation id="5327248766486351172">Pangalan</translation>
+<translation id="5329858041417644019">Hindi pinapamahalaan ang iyong browser</translation>
<translation id="5332219387342487447">Paraan ng Pagpapadala</translation>
+<translation id="5334013548165032829">Mga detalyadong log ng system</translation>
<translation id="5344579389779391559">Maaari kang singilin ng pera ng page na ito</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Nahuhuli ang iyong orasan" o "Nauuna ang iyong orasan" o "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Para magamit ang iyong mga card sa lahat ng device, mag-sign in at i-on ang pag-sync.</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="538659543871111977">A4-Tab</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 pag-browse...</translation>
<translation id="5430298929874300616">Alisin ang bookmark</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Di-wasto</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Gawing muli ang pag-e-edit</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Magdagdag ng wastong address</translation>
<translation id="5490432419156082418">Mga Address at Higit Pa</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Subukang makipag-ugnayan sa iyong system administrator.</translation>
<translation id="549333378215107354">Laki 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Mga pinamamahalaang bookmark</translation>
<translation id="5510766032865166053">Maaaring inilipat o na-delete ito.</translation>
<translation id="5523118979700054094">Pangalan ng patakaran</translation>
<translation id="552553974213252141">Nakuha ba nang tama ang text?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Hindi mahanap ang hiniling na artikulo.</translation>
<translation id="5541546772353173584">Magdagdag ng Email</translation>
<translation id="5545756402275714221">Mga Artikulo para sa Iyo</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Mag-edit ng address</translation>
<translation id="5598944008576757369">Pumili ng Paraan ng Pagbabayad</translation>
<translation id="560412284261940334">Hindi sinusuportahan ang pamamahala</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Masyadong maraming beses kang na-redirect ng <ph name="HOST_NAME" />.</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="5632627355679805402">Na-encrypt ang data mo gamit ang iyong <ph name="BEGIN_LINK" />password sa Google<ph name="END_LINK" /> simula noong <ph name="TIME" />. Ilagay ito para simulan ang pag-sync.</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="563324245173044180">Na-block ang mapanlinlang na content.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">Ang administrator ng device na ito ay nag-install ng mga extension para sa mga karagdagang function. May access ang mga extension sa ilan sa iyong data.</translation>
<translation id="5675650730144413517">Hindi gumagana ang page na ito</translation>
+<translation id="5684874026226664614">Oops. Hindi maisalin ang pahinang ito.</translation>
<translation id="5685654322157854305">Magdagdag ng Address sa Pagpapadala</translation>
<translation id="5689199277474810259">I-export sa JSON</translation>
<translation id="5689516760719285838">Lokasyon</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Ang pagkilala ng website na ito ay hindi natukoy.</translation>
<translation id="5719499550583120431">Tinatanggap ang mga prepaid card.</translation>
<translation id="5720705177508910913">Kasalukuyang user</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Inirerekomenda ng Chrome na i-reset ang iyong password kung ginamit mo ito sa iba pang site.</translation>
<translation id="5732392974455271431">Maaari itong i-unblock ng iyong mga magulang para sa iyo</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{I-save ang card sa iyong Google Account}one{I-save ang mga card sa iyong Google Account}other{I-save ang mga card sa iyong Google Account}}</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="5770114862687765385">Mukhang sira ang file. I-click ang button na 'I-reset' upang i-reset ang session.</translation>
<translation id="5778550464785688721">Ganap na pagkontrol sa mga MIDI device</translation>
<translation id="578305955206182703">Amber</translation>
<translation id="57838592816432529">I-mute</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>
+<translation id="5798290721819630480">I-discard ang mga pagbabago?</translation>
<translation id="5798683403665926540">Baguhin ang home page sa mga setting ng Chrome</translation>
<translation id="5803412860119678065">Gusto mo bang ilagay ang iyong <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Mga Pahintulot</translation>
<translation id="5810442152076338065">Naka-encrypt ang iyong koneksyon sa <ph name="DOMAIN" /> gamit ang isang hindi na ginagamit na cipher suite.</translation>
<translation id="5813119285467412249">&amp;Gawing Muli ang Pagdagdag</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="5860033963881614850">Naka-off</translation>
<translation id="5863847714970149516">Maaari kang singilin sa susunod na page</translation>
<translation id="5866257070973731571">Magdagdag ng Numero ng Telepono</translation>
<translation id="5869405914158311789">Hindi makakonekta sa site na ito</translation>
<translation id="5869522115854928033">Mga naka-save na password</translation>
<translation id="5887400589839399685">Na-save ang card</translation>
-<translation id="5893718151540690985">nag-uulat ng listahan ng mga interface ng network kasama ang mga uri at mga address ng hardware ng mga ito</translation>
<translation id="5893752035575986141">Tinatanggap ang mga credit card.</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="5916664084637901428">Naka-on</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">I-save ang card sa Google Account?</translation>
<translation id="5922853866070715753">Malapit nang matapos</translation>
<translation id="5932224571077948991">Nagpapakita ang site ng mga nakakasagabal o nakakapanlinlang na ad</translation>
-<translation id="5939518447894949180">I-reset</translation>
<translation id="5946937721014915347">Binubuksan ang <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Hindi maka-enroll gamit ang account ng consumer (may available na naka-package na lisensya).</translation>
<translation id="5967592137238574583">I-edit ang Impormasyon ng Contact</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Mag-zoom out</translation>
<translation id="5977489021191000276">Hindi pinapamahalaan ng administrator ang iyong device.</translation>
<translation id="5977976211062815271">Sa device na ito</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Hindi mabuksan ang app sa pagbabayad</translation>
<translation id="5989320800837274978">Hindi tunukoy ang alinman sa mga hindi nababagong proxy server o isang .pac script URL.</translation>
<translation id="5990559369517809815">Na-block ng isang extension ang mga kahilingan sa server.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">nag-uulat ng mga istatistika ng hardware tulad ng paggamit sa CPU/RAM</translation>
<translation id="6034000775414344507">Light Grey</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Kung magpapatuloy ang problema, makipag-ugnayan sa may-ari ng site.</translation>
<translation id="6040143037577758943">Isara</translation>
<translation id="6044573915096792553">Laki 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Gamitin ang iyong mga card sa lahat ng device mo?</translation>
<translation id="6059925163896151826">Mga USB device</translation>
-<translation id="6071091556643036997">Invalid ang uri ng patakaran.</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="6094273045989040137">I-annotate</translation>
<translation id="610911394827799129">Maaaring may iba pang anyo ng history ng pag-browse ang iyong Google Account sa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Impormasyon tungkol sa mga naka-install na extension at plugin</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Magbabakante ng wala pang <ph name="SIZE" />. Maaaring mag-load nang mas mabagal ang ilang site sa iyong susunod na pagbisita.</translation>
<translation id="6337534724793800597">I-filter ang mga patakaran ayon sa pangalan</translation>
<translation id="6358450015545214790">Ano ang ibig sabihin ng mga ito?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Maaaring magkaroon ng singil.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 pang suhestyon}one{# pang suhestyon}other{# pang suhestyon}}</translation>
<translation id="6387754724289022810">Para mas mabilis na makapagbayad sa susunod, i-save ang iyong card at billing address sa Google Account mo at sa device na ito.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">I-edit ang bookmark</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Itapon</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</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>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">I-restart ang Chrome</translation>
<translation id="6529602333819889595">&amp;Gawing Muli ang Pagtanggal</translation>
<translation id="6534179046333460208">Mga suhestyon sa Pisikal na Web</translation>
+<translation id="6556866813142980365">Redo</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="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Light Pink</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link na kinopya mo</translation>
+<translation id="6591833882275308647">Hindi pinapamahalaan ang iyong <ph name="DEVICE_TYPE" /></translation>
<translation id="6596325263575161958">Mga pagpipilian sa pag-encrypt</translation>
<translation id="6604181099783169992">Mga Motion o Light Sensor</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Impormasyon ng Contact</translation>
<translation id="6626291197371920147">Magdagdag ng wastong card number</translation>
<translation id="6628463337424475685">Paghahanap ng <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Hindi na ginagamit ang patakarang ito.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Wala}=1{Mula sa 1 site (hindi ka masa-sign out sa iyong Google Account)}one{Mula sa # site (hindi ka masa-sign out sa iyong Google Account)}other{Mula sa # na site (hindi ka masa-sign out sa iyong Google Account)}}</translation>
<translation id="6657585470893396449">Password</translation>
+<translation id="6670613747977017428">Bumalik sa kaligtasan.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Token sa Pag-enroll</translation>
<translation id="6711464428925977395">May problema sa proxy server, o mali ang address.</translation>
<translation id="6723740634201835758">Sa iyong Google Account</translation>
+<translation id="6738516213925468394">Na-encrypt ang data mo gamit ang iyong <ph name="BEGIN_LINK" />passphrase sa pag-sync<ph name="END_LINK" /> noong <ph name="TIME" />. Ilagay ito para simulan ang pag-sync.</translation>
<translation id="674375294223700098">Hindi alam na error sa certificate ng server</translation>
<translation id="6744009308914054259">Habang naghihintay ng koneksyon, maaari mong bisitahin ang Mga Download para magbasa ng mga offline na artikulo.</translation>
<translation id="6753269504797312559">Halaga ng patakaran</translation>
<translation id="6757797048963528358">Nag-sleep ang iyong device.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Hindi pa ito inaaprubahan ng iyong magulang</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Mga Extension</translation>
<translation id="679355240208270552">Binalewala dahil hindi na-enable ng patakaran ang default na paghahanap.</translation>
<translation id="681021252041861472">Kinakailangang Field</translation>
<translation id="6810899417690483278">Customization ID</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Device</translation>
<translation id="6970216967273061347">Distrito</translation>
<translation id="6973656660372572881">Tinukoy ang parehong mga hindi nababagong proxy server at isang .pac script URL.</translation>
+<translation id="6973932557599545801">Paumanhin, hindi ako makatulong. Magpatuloy nang mag-isa.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">I-mute (default)</translation>
<translation id="6984479912851154518">Aalis sa pribadong mode para magbayad sa pamamagitan ng external na application. Magpatuloy?</translation>
<translation id="6989763994942163495">Ipakita ang mga advanced na setting...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Palaging i-translate ang <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Ang mga singil na ito ay maaaring isang beses lang o umuulit at maaaring hindi mo mapansin.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Itago</translation>
<translation id="7108819624672055576">Pinayagan ng isang extension</translation>
<translation id="7111012039238467737">(Valid)</translation>
+<translation id="7118618213916969306">Hanapin ang URL sa clipboard, na <ph name="SHORT_URL" /></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="7135130955892390533">Ipakita ang status</translation>
<translation id="7138472120740807366">Pamamaraan ng paghahatid</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavender</translation>
-<translation id="7158980942472052083">Invalid na URL. Dapat ay isang URL na may karaniwang scheme.</translation>
<translation id="717330890047184534">Gaia ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Hiniling ng server na pupuntahan mo, ang <ph name="ORIGIN" />, na
+ ilapat ang isang patakaran sa seguridad sa lahat ng kahilingan dito. Ngunit sa halip na
+ maghatid ng patakaran, na-redirect nito ang browser sa ibang lugar, na pinipigilan
+ ang browser na tuparin ang iyong kahilingan para sa <ph name="SITE" />.</translation>
<translation id="7179323680825933600">I-save at Punan ang Mga Paraan ng Pagbabayad</translation>
<translation id="7180611975245234373">I-refresh</translation>
<translation id="7182878459783632708">Walang nakatakdang mga patakaran</translation>
<translation id="7186367841673660872">Naisalin ang pahinang ito mula sa<ph name="ORIGINAL_LANGUAGE" />sa<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Magbabakante ng <ph name="SIZE" />. Maaaring mag-load nang mas mabagal ang ilang site sa iyong susunod na pagbisita.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Makikita ng iyong administrator ang:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Hindi sumusunod ang <ph name="HOST_NAME" /> sa mga pamantayan sa seguridad.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Dagdagan ang nalalaman<ph name="END_LINK" /> tungkol sa problemang ito.</translation>
<translation id="7219179957768738017">Gumagamit ng <ph name="SSL_VERSION" /> ang koneksyon.</translation>
<translation id="7220786058474068424">Pinoproseso</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Naglalaman ng malware ang site</translation>
+<translation id="724766306220616965">Mga Babala, Pagsasalungat</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="7251437084390964440">Hindi sumusunod ang configuration ng network sa pamantayan ng ONC. Hindi maaaring i-import ang mga bahagi ng configuration.
Mga karagdagang detalye:
@@ -982,11 +1120,14 @@ Mga karagdagang detalye:
<translation id="7300012071106347854">Cobalt Blue</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Mga babala sa <ph name="BEGIN_LINK" />Ligtas na Pag-browse<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Tulong sa Koneksyon</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Command Line</translation>
-<translation id="7365061714576910172">I-export sa Linux</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>
@@ -994,6 +1135,7 @@ Mga karagdagang detalye:
<translation id="7381288752349550461">Pag-override ng pinapamahalaang session</translation>
<translation id="7390545607259442187">Kumpirmahin ang Card</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Pinapamahalaan ang iyong <ph name="DEVICE_NAME" /></translation>
<translation id="7407424307057130981">&lt;p&gt;Makikita mo ang error na ito kung mayroon kang Superfish software sa iyong Windows computer.&lt;/p&gt;
&lt;p&gt;Sundin ang mga hakbang na ito para pansamantalang i-disable ang software nang sa gayon ay makapunta ka sa web. Kakailanganin mo ng mga pribilehiyong pang-administrator.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Mga karagdagang detalye:
&lt;li&gt;I-click ang &lt;strong&gt;Apply&lt;/strong&gt;, pagkatapos ay i-click ang &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Bisitahin ang &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;help center ng Chrome&lt;/a&gt; para matutunan kung paano permanenteng alisin ang software sa iyong computer
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Pamamahala ng <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Pamahalaan ang Mga Password...</translation>
<translation id="7419106976560586862">Path ng Profile</translation>
<translation id="7437289804838430631">Magdagdag ng Impormasyon ng Contact</translation>
@@ -1013,22 +1155,24 @@ Mga karagdagang detalye:
<translation id="7442725080345379071">Light Orange</translation>
<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="7449109375006139765">magpadala sa server ng pamamahala ng mga log ng system</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Matuto pa<ph name="END_LINK" /> tungkol sa problemang ito.</translation>
<translation id="7455133967321480974">Gamitin ang pangkalahatang default (I-block)</translation>
<translation id="7460618730930299168">Iba ang screening sa napili mo. Magpatuloy?</translation>
<translation id="7473891865547856676">Hindi, Salamat</translation>
-<translation id="7475525192983021547">nag-uulat ng mga yugto ng panahon kapag aktibo sa device ang isang user</translation>
<translation id="7481312909269577407">Sumulong</translation>
<translation id="7485870689360869515">Walang nahanap na data.</translation>
+<translation id="7498234416455752244">Magpatuloy sa pag-edit</translation>
<translation id="7508255263130623398">Walang laman ang ibinalik na device id ng patakaran o hindi ito tumutugma sa kasalukuyang device id</translation>
<translation id="7508870219247277067">Avocado Green</translation>
<translation id="7511955381719512146">Maaaring hilingin ng Wi-Fi na ginagamit mo na bisitahin mo ang <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">I-download</translation>
<translation id="7518003948725431193">Walang webpage na nahanap para sa web address:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Hindi pribado ang iyong koneksyon sa site na ito</translation>
+<translation id="7535087603100972091">Value</translation>
<translation id="7537536606612762813">Kinakailangan</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1037,8 +1181,8 @@ Mga karagdagang detalye:
<translation id="7552846755917812628">Subukan ang mga sumusunod na tip:</translation>
<translation id="7554791636758816595">Bagong Tab</translation>
<translation id="7564049878696755256">Maaari kang mawalan ng access sa iyong account sa <ph name="ORG_NAME" /> o manakawan ng pagkakakilanlan. Inirerekomenda ng Chrome na palitan ang iyong password ngayon.</translation>
-<translation id="7566125604157659769">Text na kinopya mo</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="7568105740864181217">Pinapamahalaan ng kumpanya, paaralan, o iba pang organisasyon ang browser na ito. Mababago ng iyong administrator ang setup ng browser mo nang malayuan. Maaari ding pamahalaan sa labas ng Chrome ang aktibidad sa device na ito. <ph name="BEGIN_LINK" />Matuto Pa<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Mga karagdagang detalye:
<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="7633909222644580952">Date ng performance at mga ulat ng pag-crash</translation>
<translation id="7637571805876720304">Gusto mo bang alisin ang credit card sa Chromium?</translation>
<translation id="7639968568612851608">Dark Grey</translation>
<translation id="765676359832457558">Itago ang mga advanced na setting...</translation>
@@ -1058,9 +1203,11 @@ Mga karagdagang detalye:
<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="7676643023259824263">Hanapin ang text sa clipboard, na <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Baguhin ang Search Engine</translation>
<translation id="7682287625158474539">Pagpapadala</translation>
<translation id="7687186412095877299">Pinupunan ang mga form sa pagbabayad ng iyong mga naka-save na paraan ng pagbabayad</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">Sa ngayon, may mga card kang magagamit lang sa device na ito. I-click ang Magpatuloy para suriin ang mga card.</translation>
<translation id="7699293099605015246">Hindi available sa ngayon ang mga artikulo</translation>
<translation id="7701040980221191251">Wala</translation>
@@ -1072,11 +1219,13 @@ Mga karagdagang detalye:
<translation id="774634243536837715">Na-block ang mapanganib na content.</translation>
<translation id="7752995774971033316">Hindi pinamamahalaan</translation>
<translation id="7755287808199759310">Maaari itong i-unblock ng iyong magulang para sa iyo</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Maaaring na-block ng firewall o antivirus software ang koneksyon.</translation>
<translation id="7759163816903619567">Display domain:</translation>
<translation id="7761701407923456692">Hindi tumutugma sa URL ang certificate ng server.</translation>
<translation id="7763386264682878361">Pang-parse ng Manifest ng Pagbabayad</translation>
<translation id="7764225426217299476">Magdagdag ng address</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefecture</translation>
<translation id="7791543448312431591">Idagdag</translation>
<translation id="7793809570500803535">Maaaring pansamantalang sira ang webpage sa <ph name="SITE" /> o maaaring permanente itong inilipat sa isang bagong web address.</translation>
@@ -1088,8 +1237,8 @@ Mga karagdagang detalye:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Alisin ang suhestyon sa Chrome?</translation>
<translation id="7815407501681723534">Nakakita ng <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> para sa '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Pamamahala sa patakaran</translation>
<translation id="782886543891417279">Maaaring hilingin ng Wi-Fi na ginagamit mo (<ph name="WIFI_NAME" />) na bisitahin mo ang page nito sa pag-login.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Wala}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# (na) app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# (na) app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Gayunpaman, hindi ka invisible. Kahit mag-incognito ka, hindi matatago ang iyong pagba-browse mula sa iyong employer, sa iyong internet service provider o sa mga website na binibisita mo.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Mga karagdagang detalye:
<translation id="7878562273885520351">Maaaring makompromismo ang iyong password</translation>
<translation id="7882421473871500483">Brown</translation>
<translation id="7887683347370398519">Tingnan ang iyong CVC at subukang muli</translation>
-<translation id="7893255318348328562">Pangalan ng session</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Maglagay ng wastong numero ng telepono</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Mag-e-expire sa <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Mga karagdagang detalye:
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Mga bookmark sa mobile</translation>
<translation id="7961015016161918242">Hindi Kailanman</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Pamahalaan ang Mga Password</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Ise-save ang card na ito at ang billing address nito. Magagamit mo ito kapag nag-sign in ka sa <ph name="USER_EMAIL" />.}one{Ise-save ang mga card na ito at ang mga billing address ng mga ito. Magagamit mo ang mga ito kapag nag-sign in ka sa <ph name="USER_EMAIL" />.}other{Ise-save ang mga card na ito at ang mga billing address ng mga ito. Magagamit mo ang mga ito kapag nag-sign in ka sa <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Nasa <ph name="SOURCE_LANGUAGE" /> ang pahinang ito. Isalin ito sa <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pen</translation>
+<translation id="8037117624646282037">Sino ang gumamit ng device na ito kamakailan</translation>
<translation id="8037357227543935929">Magtanong (default)</translation>
<translation id="803771048473350947">File</translation>
<translation id="8041089156583427627">Magpadala ng Feedback</translation>
<translation id="8041940743680923270">Gamitin ang pangkalahatang default (Tanungin)</translation>
<translation id="8042918947222776840">Pumili ng Paraan ng Pag-pick up</translation>
<translation id="8057711352706143257">Hindi maayos na naka-configure ang "<ph name="SOFTWARE_NAME" />." Kadalasang naaayos ang problema kapag in-uninstall ang "<ph name="SOFTWARE_NAME" />." <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Na-configure ang iyong device na:</translation>
+<translation id="8066955247577885446">Paumanhin, nagkaproblema.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Hindi maaaring i-annotate kapag naka-rotate</translation>
<translation id="8079031581361219619">I-reload ang site?</translation>
<translation id="8088680233425245692">Hindi natingnan ang artikulo.</translation>
@@ -1131,11 +1284,12 @@ Mga karagdagang detalye:
<translation id="8091372947890762290">Nakabinbin sa server ang pag-activate</translation>
<translation id="8092774999298748321">Deep Purple</translation>
<translation id="8094917007353911263">Maaaring hilingin ng network na ginagamit mo na bisitahin mo ang <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Naalis na ang mga invalid na card</translation>
<translation id="8103161714697287722">Paraan ng Pagbabayad</translation>
<translation id="8118489163946903409">Paraan ng pagbabayad</translation>
+<translation id="8123836779274890062">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang <ph name="DEVICE_TYPE" /></translation>
<translation id="8127301229239896662">Hindi na-install nang maayos ang "<ph name="SOFTWARE_NAME" />" sa iyong computer o network. Magtanong sa IT administrator mo upang malutas ang isyung ito.</translation>
-<translation id="8130693978878176684">Hindi na ako makakatulong, magpatuloy nang mag-isa.</translation>
<translation id="8131740175452115882">Kumpirmahin</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>
@@ -1145,8 +1299,11 @@ Mga karagdagang detalye:
<translation id="8197543752516192074">Isalin ang Page</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="8202370299023114387">Hindi pagkakasundo</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">Secure ang koneksyon</translation>
<translation id="8218327578424803826">Itinakdang Lokasyon:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Buksan ang page sa bagong Incognito tab</translation>
@@ -1158,14 +1315,16 @@ Mga karagdagang detalye:
<translation id="825929999321470778">Ipakita ang Lahat ng Naka-save na Password</translation>
<translation id="8261506727792406068">I-delete</translation>
<translation id="8267698848189296333">Nagsa-sign in bilang <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang browser na ito. Maaaring baguhin ng iyong administrator ang setup ng browser mo nang malayuan. Maaari ding pamahalaan sa labas ng Chrome ang aktibidad sa device na ito. <ph name="BEGIN_LINK" />Matuto Pa<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Mag-sign In</translation>
<translation id="8288807391153049143">Ipakita ang certificate</translation>
<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="8298115750975731693">Maaaring hilingin ng Wi-Fi na ginagamit mo (<ph name="WIFI_NAME" />) na bisitahin mo ang <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Nabigo ang translation dahil sa problema sa koneksyon sa network.</translation>
-<translation id="8311129316111205805">I-load ang session</translation>
<translation id="8332188693563227489">Tinanggihan ang access sa <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Mga karagdagang detalye:
<translation id="8416694386774425977">Invalid ang configuration ng network at hindi ito ma-import.
Mga karagdagang detalye:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Pinapamahalaan ng <ph name="ENROLLMENT_DOMAIN" /> ang device</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Baguhin</translation>
<translation id="8428213095426709021">Mga Setting</translation>
@@ -1210,9 +1368,11 @@ Mga karagdagang detalye:
<translation id="860043288473659153">Pangalan ng cardholder</translation>
<translation id="861775596732816396">Laki 4</translation>
<translation id="8620436878122366504">Hindi pa ito inaaprubahan ng iyong mga magulang</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">I-save ang Card na Ito sa Device na Ito</translation>
<translation id="8663226718884576429">Buod ng Order, <ph name="TOTAL_LABEL" />, Higit pang Detalye</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, sagot, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Ang iyong koneksyon sa <ph name="DOMAIN" /> ay hindi naka-encrypt.</translation>
<translation id="8718314106902482036">Hindi nakumpleto ang pagbabayad</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, suhestyon sa paghahanap</translation>
@@ -1226,6 +1386,7 @@ Mga karagdagang detalye:
<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="8763927697961133303">USB device</translation>
<translation id="8768895707659403558">Para magamit ang iyong mga card sa lahat ng device mo, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Gawing muli ang pagtanggal</translation>
<translation id="8792621596287649091">Maaari kang mawalan ng access sa iyong account sa <ph name="ORG_NAME" /> o manakawan ng pagkakakilanlan. Inirerekomenda ng Chromium na palitan ang iyong password ngayon.</translation>
<translation id="8800988563907321413">Lalabas dito ang iyong mga suhestyon na malapit</translation>
@@ -1236,10 +1397,12 @@ Mga karagdagang detalye:
<translation id="885730110891505394">Pagbabahagi sa Google</translation>
<translation id="8858065207712248076">Inirerekomenda ng Chrome na i-reset ang iyong password sa <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> kung ginamit mo ito sa iba pang site.</translation>
<translation id="8866481888320382733">Error sa pag-parse ng mga setting ng patakaran</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Recently Closed</translation>
<translation id="8874824191258364635">Maglagay ng wastong numero ng card</translation>
<translation id="8891727572606052622">Di-wastong mode ng proxy.</translation>
<translation id="8903921497873541725">Mag-zoom in</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Magdagdag ng Pangalan</translation>
@@ -1247,13 +1410,13 @@ Mga karagdagang detalye:
<translation id="894185898663964645">Ang iyong administrator ay may mga naka-configure na custom na root certificate na maaaring payagan ang administrator na makita ang mga content ng mga website na binibisita mo.</translation>
<translation id="8943282376843390568">Lime</translation>
<translation id="8957210676456822347">Pagpapahintulot sa Captive Portal</translation>
+<translation id="8966619695390250636">Ang ibig mo bang sabihin ay?</translation>
<translation id="8968766641738584599">I-save ang card</translation>
<translation id="8971063699422889582">Nag-expire na ang certificate ng server.</translation>
<translation id="8975012916872825179">May kasamang impormasyon tulad ng mga numero ng telepono, email address, at address sa pagpapadala</translation>
<translation id="8978053250194585037">May <ph name="BEGIN_LINK" />na-detect na phishing<ph name="END_LINK" /> sa <ph name="SITE" /> kamakailan ang Ligtas na Pag-browse sa Google. Nagpapanggap ang mga phishing site bilang ibang website upang linlangin ka.</translation>
<translation id="8983003182662520383">Mga Paraan ng Pagbabayad at Address Gamit ang Google Pay</translation>
<translation id="8987927404178983737">Buwan</translation>
-<translation id="8988408250700415532">Nagkaproblema. Maaari mong tapusin ang iyong order sa website.</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>
@@ -1263,6 +1426,7 @@ Mga karagdagang detalye:
<translation id="9011424611726486705">Buksan ang mga setting ng site</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Invalid)</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>
@@ -1274,11 +1438,11 @@ Mga karagdagang detalye:
<translation id="9065745800631924235">Paghahanap para sa <ph name="TEXT" /> mula sa history</translation>
<translation id="9069693763241529744">Na-block ng isang extension</translation>
<translation id="9076283476770535406">Maaaring mayroon itong mature content</translation>
+<translation id="9076630408993835509">Hindi pinapamahalaan ng kumpanya o iba pang organisasyon ang browser na ito. Maaaring pinapamahalaan sa labas ng Chrome ang aktibidad sa device na ito. <ph name="BEGIN_LINK" />Matuto Pa<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Nangangailangan ng higit pang impormasyon</translation>
<translation id="9080712759204168376">Buod ng Order</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>
<translation id="9106062320799175032">Magdagdag ng Billing Address</translation>
-<translation id="9110718169272311511">Available ang Google Assistant sa Chrome malapit sa ibaba ng screen</translation>
<translation id="9114524666733003316">Kinukumpirma ang card...</translation>
<translation id="9128870381267983090">Kumonekta sa network</translation>
<translation id="9137013805542155359">Ipakita ang orihinal</translation>
@@ -1287,6 +1451,7 @@ Mga karagdagang detalye:
<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="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Payagan ang mga site na tingnan kung may mga naka-save kang paraan ng pagbabayad</translation>
<translation id="9169664750068251925">Palaging i-block sa site na ito</translation>
<translation id="9170848237812810038">&amp;I-undo</translation>
@@ -1301,10 +1466,12 @@ Mga karagdagang detalye:
<translation id="9219103736887031265">Mga Larawan</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Maaari kang mawalan ng access sa iyong Google Account. Inirerekomenda ng Chromium na palitan na ang iyong password. Hihilingin sa iyong mag-sign in.</translation>
<translation id="939736085109172342">Bagong folder</translation>
<translation id="945855313015696284">Tingnan ang impormasyon sa ibaba at mag-delete ng anumang invalid na card</translation>
<translation id="951104842009476243">Mga Tinatanggap na Debit at Prepaid Card</translation>
+<translation id="958202389743790697">Na-block alinsunod sa patakaran sa seguridad ng <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Maaaring subukan ng content na itong mag-install ng mga mapanlinlang na app na nagpapanggap na ibang bagay o nangongolekta ng data na maaaring gamitin para subaybayan ka. <ph name="BEGIN_LINK" />Ipakita pa rin<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Official Build</translation>
<translation id="973773823069644502">Magdagdag ng Address sa Paghahatid</translation>
@@ -1313,6 +1480,7 @@ Mga karagdagang detalye:
<translation id="984275831282074731">Mga paraan ng pagbabayad</translation>
<translation id="985199708454569384">&lt;p&gt;Makikita mo ang error na ito kung hindi tumpak ang petsa at oras ng iyong computer o mobile device.&lt;/p&gt;
&lt;p&gt;Para maayos ang error, buksan ang orasan ng iyong device. Tiyaking tama ang oras at petsa.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Bumuo ang Developer</translation>
<translation id="989988560359834682">I-edit ang Address</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_fr.xtb b/chromium/components/strings/components_strings_fr.xtb
index 652a3b507fc..d7677b5cc23 100644
--- a/chromium/components/strings/components_strings_fr.xtb
+++ b/chromium/components/strings/components_strings_fr.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fr">
-<translation id="1005145902654145231">Échec du changement de nom de la session.</translation>
<translation id="1008557486741366299">Pas maintenant</translation>
<translation id="1010200102790553230">Charger la page plus tard</translation>
<translation id="1015730422737071372">Fournir des informations supplémentaires</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">Nom inconnu</translation>
<translation id="1050038467049342496">Fermez les autres applications</translation>
<translation id="1055184225775184556">&amp;Annuler l'ajout</translation>
+<translation id="1056898198331236512">Avertissement</translation>
<translation id="1058479211578257048">Enregistrement des cartes…</translation>
<translation id="10614374240317010">Jamais enregistrés</translation>
+<translation id="1062160989074299343">Prc10 (enveloppe)</translation>
<translation id="106701514854093668">Favoris sur l'ordinateur</translation>
<translation id="1074497978438210769">Non sécurisé</translation>
<translation id="1080116354587839789">Ajuster à la largeur</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Ajouter le nom du titulaire de la carte</translation>
<translation id="1089439967362294234">Modifier le mot de passe</translation>
<translation id="109743633954054152">Gérer les mots de passe dans les paramètres de Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Les avertissements peuvent être fréquents en attendant que les sites Web finissent de mettre à jour leurs systèmes de sécurité. Ce problème devrait être bientôt résolu.</translation>
<translation id="1126551341858583091">La taille sur l'espace de stockage local est de <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache de la règle valide.</translation>
+<translation id="1131264053432022307">Image copiée</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> a mis fin à la connexion de manière inattendue.</translation>
<translation id="1161325031994447685">Reconnectez-vous au réseau Wi-Fi</translation>
<translation id="1165039591588034296">Erreur</translation>
-<translation id="1173894706177603556">Renommer</translation>
<translation id="1175364870820465910">Im&amp;primer...</translation>
<translation id="1181037720776840403">Supprimer</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Nom de votre appareil</translation>
<translation id="124116460088058876">Plus de langues</translation>
<translation id="1250759482327835220">Pour régler vos achats plus rapidement la prochaine fois, enregistrez votre carte, votre nom et votre adresse de facturation dans votre compte Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronisés)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variations de ligne de commande</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="1314614906530272393">La session sélectionnée n'existe pas.</translation>
+<translation id="1320233736580025032">Prc1 (enveloppe)</translation>
+<translation id="132301787627749051">Rechercher l'image du presse-papier</translation>
<translation id="1323433172918577554">Afficher plus</translation>
<translation id="132390688737681464">Enregistrer et renseigner les adresses</translation>
<translation id="1333989956347591814">Votre activité <ph name="BEGIN_EMPHASIS" />peut rester visible<ph name="END_EMPHASIS" /> par :
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Adresse d'enlèvement</translation>
<translation id="1348198688976932919">Ce site contient des applications dangereuses</translation>
<translation id="1348779747280417563">Confirmer le nom</translation>
+<translation id="1357195169723583938">Utilisateurs récents de l'appareil et dates d'utilisation</translation>
+<translation id="1364822246244961190">Cette règle est bloquée. Sa valeur sera ignorée.</translation>
<translation id="1374468813861204354">suggestions</translation>
+<translation id="1374692235857187091">Index-4x6 (carte postale)</translation>
<translation id="1375198122581997741">À propos de la version</translation>
<translation id="1376836354785490390">Afficher moins</translation>
<translation id="1377321085342047638">Numéro de carte</translation>
<translation id="138218114945450791">Bleu clair</translation>
+<translation id="1382194467192730611">Appareil USB autorisé par votre administrateur</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> n'a envoyé aucune donnée.</translation>
+<translation id="140316286225361634">Le site <ph name="ORIGIN" /> a exigé qu'une règle de sécurité soit appliquée à toutes ses demandes, et cette règle considère que le site n'est pas sûr actuellement.</translation>
<translation id="1405567553485452995">Vert clair</translation>
<translation id="1407135791313364759">Tout ouvrir</translation>
<translation id="1413809658975081374">Erreur liée à la confidentialité</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Oui</translation>
<translation id="1430915738399379752">Imprimer</translation>
<translation id="1455413310270022028">Gomme</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Plus</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Sélectionner l'adresse de livraison</translation>
+<translation id="1492194039220927094">Diffusion push des règles :</translation>
<translation id="1501859676467574491">Afficher les cartes de votre compte Google</translation>
-<translation id="1506687042165942984">Afficher une copie enregistrée (non actualisée) de cette page</translation>
<translation id="1507202001669085618">&lt;p&gt;Ce message s'affiche si vous utilisez un portail Wi-Fi auquel vous devez vous connecter pour accéder à Internet.&lt;/p&gt;
&lt;p&gt;Pour corriger cette erreur, cliquez sur &lt;strong&gt;Se connecter&lt;/strong&gt; sur la page que vous essayez d'ouvrir.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Veuillez saisir le numéro de téléphone.</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Date de création</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">En attente de connexion…</translation>
+<translation id="1529521330346880926">10x15 (enveloppe)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Cette page indique</translation>
<translation id="153384715582417236">C'est tout !</translation>
<translation id="154408704832528245">Sélectionner l'adresse d'expédition</translation>
<translation id="1549470594296187301">Vous devez activer JavaScript pour utiliser cette fonctionnalité.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Saisir la date d'expiration</translation>
<translation id="1581080074034554886">Code CVC :</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="1618822247301510817">Image que vous avez copiée</translation>
<translation id="1620510694547887537">Appareil photo</translation>
<translation id="1623104350909869708">Empêcher cette page de générer des boîtes de dialogue supplémentaires</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Fermer la session</translation>
<translation id="1639239467298939599">Chargement en cours</translation>
<translation id="1640180200866533862">Règles relatives aux utilisateurs</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">Le certificat du serveur contient une clé de chiffrement faible.</translation>
<translation id="1697532407822776718">Vous êtes prêt !</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Le document est trop volumineux pour être annoté</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>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Essayez de contacter l'administrateur système.</translation>
<translation id="1740951997222943430">Saisissez un mois d'expiration valide</translation>
<translation id="1743520634839655729">Pour régler plus rapidement vos achats la prochaine fois, enregistrez votre carte, votre nom et votre adresse de facturation dans votre compte Google et sur cet appareil.</translation>
+<translation id="1745880797583122200">Votre navigateur est géré</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Mettre à jour votre phrase secrète de synchronisation</translation>
<translation id="1787142507584202372">Les onglets ouverts s'affichent ici</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nom du titulaire de la carte</translation>
<translation id="1821930232296380041">La demande ou ses paramètres ne sont pas valides.</translation>
+<translation id="1822540298136254167">Sites Web consultés et durée des visites</translation>
<translation id="1826516787628120939">Vérification en cours…</translation>
<translation id="1834321415901700177">Ce site contient des programmes dangereux</translation>
<translation id="1839551713262164453">Échec de la validation des valeurs de règle avec des erreurs</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Effacer les données de l'historique de navigation de Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{et 1 autre}one{et # autre}other{et # autres}}</translation>
<translation id="2003709556000175978">Réinitialiser votre mot de passe maintenant</translation>
+<translation id="20053308747750172">Le serveur auquel vous accédez, <ph name="ORIGIN" />, a exigé qu'une règle de sécurité soit appliquée à toutes les demandes qu'il reçoit. Cependant, une règle non valide vient d'être émise, ce qui empêche le navigateur de répondre à votre demande pour <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Le proxy est défini sur la configuration automatique.</translation>
<translation id="2030481566774242610">Essayez avec <ph name="LINK" /></translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Vérifier le proxy et le pare-feu<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Département</translation>
<translation id="2102134110707549001">Suggérer un mot de passe sécurisé…</translation>
<translation id="2108755909498034140">Redémarrez l'ordinateur</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Carte</translation>
<translation id="2114841414352855701">Ignorée parce que remplacée par <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Favoris sur mobile</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (enveloppe)</translation>
<translation id="2181821976797666341">Règles</translation>
<translation id="2183608646556468874">Numéro de téléphone</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}one{# adresse}other{# adresses}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">N° de téléphone</translation>
<translation id="2283340219607151381">Enregistrer et renseigner les adresses</translation>
<translation id="2292556288342944218">Votre accès à Internet est bloqué</translation>
+<translation id="2294558542833290837">Le lien que vous avez initialement ouvert est inhabituel</translation>
+<translation id="2297722699537546652">B5 (enveloppe)</translation>
+<translation id="2310021320168182093">Chou2 (enveloppe)</translation>
<translation id="2316887270356262533">Libère moins de 1 Mo. Le chargement de certains sites risque d'être plus lent lors de votre prochaine visite.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> nécessite un nom d'utilisateur et un mot de passe.</translation>
<translation id="2317583587496011522">Les cartes de débit sont acceptées.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, arrive à expiration le <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Paramètre contrôlé par votre administrateur</translation>
+<translation id="2346319942568447007">Image copiée</translation>
<translation id="2349790679044093737">Une session RV est active</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>
@@ -239,29 +266,34 @@
<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="2378238891085281592">Vous êtes passé en mode privé</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Le serveur auquel vous accédez, <ph name="ORIGIN" />, a exigé qu'une règle de sécurité soit appliquée à toutes les demandes qu'il reçoit. Cependant, la règle n'a pas pu être émise, ce qui empêche le navigateur de répondre à votre demande pour <ph name="SITE" />.</translation>
<translation id="244665789865330679">Votre appareil et votre compte sont gérés par <ph name="ENROLLMENT_DOMAIN" />. Cela signifie que votre administrateur peut configurer votre appareil et votre compte à distance.</translation>
<translation id="2463193859425327265">Changer de page d'accueil</translation>
<translation id="2463739503403862330">Remplir</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Sélectionner un mode d'expédition</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Exécuter les diagnostics du réseau<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traduire cette page</translation>
<translation id="2479410451996844060">URL de recherche incorrecte</translation>
<translation id="2482878487686419369">Notifications</translation>
<translation id="248348093745724435">Règles associées à la machine</translation>
+<translation id="2485387744899240041">Noms d'utilisateur pour votre appareil et votre navigateur</translation>
<translation id="2491120439723279231">Le certificat du serveur contient des erreurs.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Lire une nouvelle carte</translation>
<translation id="2501278716633472235">Retour</translation>
<translation id="2503184589641749290">Cartes de débit et cartes prépayées acceptées</translation>
<translation id="2515629240566999685">Vérifier le signal dans votre zone</translation>
-<translation id="2516852381693169964">Faire une recherche d'images dans <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Enregistrée sur cet appareil uniquement</translation>
<translation id="2524461107774643265">Ajouter des informations</translation>
<translation id="2536110899380797252">Ajouter une adresse</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (enveloppe)</translation>
<translation id="2625385379895617796">Votre horloge est en avance.</translation>
<translation id="2634124572758952069">Impossible de trouver l'adresse IP du serveur de <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">État :</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Fermez les autres onglets ou applications</translation>
<translation id="267371737713284912">appuyez sur <ph name="MODIFIER_KEY_DESCRIPTION" /> pour annuler</translation>
<translation id="2674170444375937751">Voulez-vous vraiment supprimer ces pages de votre historique ?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Quitter</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Cartes acceptées</translation>
<translation id="2702801445560668637">Liste de lecture</translation>
<translation id="2704283930420550640">La valeur ne respecte pas le format requis.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Supprimer les éléments sélectionnés</translation>
<translation id="277133753123645258">Mode d'expédition</translation>
<translation id="277499241957683684">Enregistrement de l'appareil manquant.</translation>
-<translation id="2781030394888168909">Exporter pour MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">La connexion a été réinitialisée.</translation>
<translation id="2788784517760473862">Cartes de crédit acceptées</translation>
@@ -311,8 +345,10 @@
<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ée est <ph name="KX" />.</translation>
<translation id="2835170189407361413">Effacer le formulaire</translation>
<translation id="2847118875340931228">Ouvrir une fenêtre de navigation privée</translation>
+<translation id="2850739647070081192">Invite (enveloppe)</translation>
<translation id="2851634818064021665">Tu n'es pas autorisé à consulter ce site</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Enregistrer la carte ?</translation>
<translation id="2903493209154104877">Adresses</translation>
<translation id="290376772003165898">La page n'est pas en <ph name="LANGUAGE" /> ?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Mode de livraison</translation>
<translation id="2928905813689894207">Adresse de facturation</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (enveloppe)</translation>
<translation id="3024663005179499861">Type de règle incorrect.</translation>
<translation id="3037605927509011580">Aïe aïe aïe</translation>
<translation id="3041612393474885105">Informations relatives au certificat</translation>
+<translation id="3060227939791841287">C9 (enveloppe)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Ajouter une adresse d'enlèvement</translation>
<translation id="3105172416063519923">ID d'élément :</translation>
<translation id="3109728660330352905">Vous n'êtes pas autorisé à consulter cette page.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> sur <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Annuler le paiement</translation>
<translation id="3207960819495026254">Favori</translation>
-<translation id="3209375525920864198">Veuillez saisir un nom de session valide.</translation>
+<translation id="321912867715453276">Avertissement : Il existe plusieurs sources pour cette règle, mais les valeurs sont identiques.</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="3229041911291329567">Informations sur la version de l'appareil et du navigateur</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Ajouter le nom sur la carte</translation>
<translation id="3287510313208355388">Télécharger une fois en ligne</translation>
<translation id="3293642807462928945">En savoir plus sur les règles <ph name="POLICY_NAME" />.</translation>
<translation id="3303855915957856445">Aucun résultat de recherche n'a été trouvé.</translation>
-<translation id="3305707030755673451">Vos données ont été chiffrées avec votre phrase secrète de synchronisation le <ph name="TIME" />. Saisissez-la pour lancer la synchronisation.</translation>
<translation id="3320021301628644560">Ajouter une adresse de facturation</translation>
<translation id="3324983252691184275">Pourpre</translation>
<translation id="3338095232262050444">Sécurisé</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;Rétablir la modification</translation>
<translation id="342781501876943858">L'équipe Chromium vous recommande de réinitialiser votre mot de passe si vous l'avez réutilisé sur d'autres sites.</translation>
<translation id="3431636764301398940">Enregistrer cette carte sur cet appareil</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Le propriétaire de cet appareil a désactivé le jeu avec le dinosaure.</translation>
<translation id="3447884698081792621">Afficher le certificat (émis par <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Intervalle de récupération :</translation>
+<translation id="3456231139987291353">Number-11 (enveloppe)</translation>
<translation id="3461824795358126837">Surligneur</translation>
<translation id="3462200631372590220">Masquer les paramètres avancés</translation>
<translation id="3467763166455606212">Nom du titulaire de la carte obligatoire</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">Les cartes de crédit et les cartes prépayées sont acceptées.</translation>
<translation id="3582930987043644930">Ajouter un nom</translation>
<translation id="3583757800736429874">&amp;Rétablir le déplacement</translation>
+<translation id="35866233670761917">Les contenus des sites Web que vous visitez ne sont pas visibles par vos administrateurs</translation>
<translation id="3586931643579894722">Masquer les détails</translation>
+<translation id="3592413004129370115">Italian (enveloppe)</translation>
<translation id="3600246354004376029">"<ph name="TITLE" />", <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Taille 2</translation>
<translation id="3615877443314183785">Saisissez une date d'expiration valide</translation>
<translation id="36224234498066874">Effacer les données de navigation...</translation>
<translation id="362276910939193118">Afficher l'historique complet</translation>
-<translation id="3623476034248543066">Afficher la valeur</translation>
<translation id="3630155396527302611">S'il est déjà répertorié en tant que programme autorisé à accéder au réseau,
essayez de le supprimer de la liste, puis de le rajouter.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validation réussie.</translation>
<translation id="3655670868607891010">Si ce message s'affiche régulièrement, essayez ces <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Révision</translation>
<translation id="366077651725703012">Mettre à jour la carte de crédit</translation>
<translation id="3676592649209844519">ID de l'appareil :</translation>
+<translation id="3677008721441257057">Vouliez-vous accéder à &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ?</translation>
<translation id="3678029195006412963">Impossible de signer la demande</translation>
<translation id="3678529606614285348">Ouvrir la page dans une nouvelle fenêtre de navigation privée (Ctrl+Maj+N)</translation>
<translation id="3679803492151881375">Rapport d'erreur enregistré le <ph name="CRASH_TIME" /> et importé le <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +497,14 @@
<translation id="3704162925118123524">Pour utiliser ce réseau, il est possible que vous deviez vous rendre sur la page de connexion correspondante.</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="3709599264800900598">Texte copié</translation>
<translation id="3712624925041724820">Licences épuisées.</translation>
<translation id="3714780639079136834">Activer les données mobiles ou le réseau Wi-Fi</translation>
<translation id="3715597595485130451">Connexion au réseau Wi-Fi</translation>
<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="372429172604983730">Les antivirus, les pare-feu et les logiciels de filtrage Web ou de proxy font partie des applications qui peuvent être à l'origine du problème.</translation>
+<translation id="373042150751172459">B4 (enveloppe)</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="3745099705178523657">Une fois la validation effectuée, les informations relatives à la carte de votre compte Google seront partagées avec ce site.</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, comme installer des logiciels ou divulguer des 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>
@@ -470,10 +517,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expire en <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Taille 16</translation>
+<translation id="3797522431967816232">Prc3 (enveloppe)</translation>
<translation id="3807873520724684969">Contenu malveillant bloqué.</translation>
<translation id="3810973564298564668">Gérer</translation>
<translation id="382518646247711829">Si vous utilisez un serveur proxy…</translation>
<translation id="3828924085048779000">La phrase secrète est obligatoire.</translation>
+<translation id="3831915413245941253">L'administrateur du domaine <ph name="ENROLLMENT_DOMAIN" /> a installé des extensions permettant d'utiliser des fonctions supplémentaires. Ces extensions ont accès à certaines de vos données.</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>
@@ -481,6 +530,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Toujours demander sur ce site</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>
@@ -491,11 +541,13 @@
<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="3984550557525787191">Ce nom de session existe déjà.</translation>
<translation id="3987940399970879459">Moins de 1 Mo</translation>
+<translation id="4008849406247176967">Avertissement : Il existe plusieurs sources avec des valeurs en conflit pour cette règle.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 page Web à proximité}one{# page Web à proximité}other{# pages Web à proximité}}</translation>
<translation id="4030383055268325496">&amp;Annuler l'ajout</translation>
+<translation id="4032320456957708163">Votre navigateur est géré par <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Clé "<ph name="SUBKEY" />" : <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (enveloppe)</translation>
<translation id="4067947977115446013">Ajouter une adresse valide</translation>
<translation id="4072486802667267160">Une erreur s'est produite lors du traitement de votre commande. Veuillez réessayer.</translation>
<translation id="4075732493274867456">Le client et le serveur ne sont pas compatibles avec une version de protocole ou une méthode de chiffrement SSL commune.</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">Violet</translation>
<translation id="4165986682804962316">Paramètres de site</translation>
<translation id="4171400957073367226">Signature de validation non valide.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> élément supplémentaire}one{<ph name="ITEM_COUNT" /> élément supplémentaire}other{<ph name="ITEM_COUNT" /> éléments supplémentaires}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (enveloppe)</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="4221630205957821124">&lt;h4&gt;Étape 1 : Connectez-vous au portail&lt;/h4&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">Réinitialiser le mot de passe</translation>
<translation id="4280429058323657511">, expiration le <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Cette carte a été enregistrée dans votre compte Google}one{Cette carte a été enregistrée dans votre compte Google}other{Ces cartes ont été enregistrées dans votre compte Google}}</translation>
+<translation id="42981349822642051">Développer</translation>
+<translation id="4302965934281694568">Chou3 (enveloppe)</translation>
<translation id="4305817255990598646">Changer</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloquer (par défaut)</translation>
+<translation id="4318566738941496689">Nom et adresse réseau de votre appareil</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="4340982228985273705">Cet ordinateur n'est pas détecté comme étant géré par une entreprise. Selon la règle définie, seules les extensions hébergées par le Chrome Web Store peuvent y être installées. L'URL de mise à jour du Chrome Web Store est "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Cartes de crédit acceptées</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gérer les modes de paiement…</translation>
+<translation id="4367563149485757821">Number-12 (enveloppe)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Téléphone</translation>
<translation id="4406896451731180161">résultats de recherche</translation>
-<translation id="4406972042435603828">Vos administrateurs ont installé des extensions aux capacités puissantes.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Adresse d'enlèvement</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="443121186588148776">Port de série</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="4434045419905280838">Pop-up et redirections</translation>
+<translation id="4435702339979719576">Carte postale)</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="445100540951337728">Cartes de débit acceptées</translation>
+<translation id="4466881336512663640">Les modifications apportées au formulaire seront perdues. Voulez-vous vraiment continuer ?</translation>
<translation id="4482953324121162758">Ce site ne sera pas traduit.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL non valide : vous devez saisir une URL avec un schéma standard, comme http://example.com ou https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (enveloppe)</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="4517607026994743406">Comm-10 (enveloppe)</translation>
<translation id="4522570452068850558">Détails</translation>
<translation id="4524805452350978254">Gérer les cartes</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Essayez de désactiver les extensions.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Livraison</translation>
+<translation id="4579056131138995126">Personal (enveloppe)</translation>
<translation id="4582204425268416675">Supprimer la carte</translation>
<translation id="4587425331216688090">Supprimer l'adresse de Chrome ?</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="4597348597567598915">Taille 8</translation>
+<translation id="4600854749408232102">C6/C5 (enveloppe)</translation>
<translation id="4646534391647090355">Accéder</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Arrêter d'utiliser un certificat non valide</translation>
+<translation id="4691835149146451662">Architecture-A (enveloppe)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Votre connexion a été interrompue</translation>
<translation id="471880041731876836">Vous n'êtes pas autorisé à consulter ce site</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Exécutez les diagnostics réseau de Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Actualiser les règles</translation>
<translation id="4728558894243024398">Plate-forme</translation>
+<translation id="4731967714531604179">Prc2 (enveloppe)</translation>
<translation id="4736825316280949806">Relancez Chromium</translation>
<translation id="473775607612524610">Mettre à jour</translation>
<translation id="4738601419177586157">Suggestion de recherche sur "<ph name="TEXT" />"</translation>
<translation id="4742407542027196863">Gérer les mots de passe…</translation>
<translation id="4744603770635761495">Chemin d'accès exécutable</translation>
+<translation id="4746351372139058112">Messages</translation>
<translation id="4750917950439032686">Vos informations, comme vos mots de passe ou vos numéros de carte de paiement, sont privées lorsqu'elles sont transmises à ce site.</translation>
<translation id="4756388243121344051">&amp;Historique</translation>
<translation id="4758311279753947758">Ajouter des coordonnées</translation>
@@ -609,9 +684,9 @@
<translation id="4764776831041365478">Il se peut que la page Web à l'adresse <ph name="URL" /> soit temporairement inaccessible ou qu'elle ait été déplacée de façon permanente à une autre adresse Web.</translation>
<translation id="4771973620359291008">Une erreur inconnue s'est produite.</translation>
<translation id="4785689107224900852">Passer à cet onglet</translation>
-<translation id="4792143361752574037">Un problème est survenu lors de l'accès aux fichiers de session. L'enregistrement sur disque est actuellement désactivé. Veuillez actualiser la page pour réessayer.</translation>
<translation id="4798078619018708837">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 relatives à la carte de votre compte Google seront partagées avec ce site.</translation>
<translation id="4800132727771399293">Veuillez vérifier la date d'expiration et le code CVC, puis réessayez.</translation>
+<translation id="480334179571489655">Erreur concernant la règle relative à l'origine</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>
@@ -626,7 +701,6 @@
<translation id="4881695831933465202">Ouvrir</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>
@@ -635,15 +709,15 @@
<translation id="4943872375798546930">Aucun résultat</translation>
<translation id="4950898438188848926">Bouton pour changer d'onglet (appuyez sur Entrée pour passer à l'onglet ouvert, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />)</translation>
<translation id="495170559598752135">Actions</translation>
-<translation id="495832697253704892">Création de rapports sur les extensions installées d'office</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Développer la liste</translation>
<translation id="4974590756084640048">Réactiver les avertissements</translation>
+<translation id="4984339528288761049">Prc5 (enveloppe)</translation>
<translation id="4989163558385430922">Tout afficher</translation>
<translation id="4989809363548539747">Ce plug-in n'est pas compatible.</translation>
-<translation id="4996230189582812866">Création de rapports</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="5014174725590676422">L'écran de première utilisation de l'Assistant Google dans Chrome est affiché</translation>
<translation id="5015510746216210676">Nom de la machine :</translation>
+<translation id="5017554619425969104">Texte copié</translation>
<translation id="5018422839182700155">Impossible d'ouvrir cette page</translation>
<translation id="5019198164206649151">L'espace de stockage destiné à la sauvegarde est en mauvais état.</translation>
<translation id="5023310440958281426">Vérifiez les règles définies par votre administrateur</translation>
@@ -653,35 +727,51 @@
<translation id="5034369478845443529">Contexte local : <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Autoriser</translation>
<translation id="5040262127954254034">Confidentialité</translation>
+<translation id="5043480802608081735">Lien copié</translation>
<translation id="5045550434625856497">Mot de passe incorrect</translation>
<translation id="5056549851600133418">Articles pour vous</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Vérifier l'adresse du proxy<ph name="END_LINK" /></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="5097099694988056070">Statistiques concernant l'appareil, telles que l'utilisation du processeur et de la RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Votre appareil est géré par <ph name="ENROLLMENT_DOMAIN" /> et votre compte est géré par <ph name="ACCOUNT_DOMAIN" />. Cela signifie que vos administrateurs peuvent configurer votre appareil et votre compte à distance.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bits)</translation>
-<translation id="5128122789703661928">Impossible de supprimer la session qui porte ce nom.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gérer les adresses…</translation>
+<translation id="5138227688689900538">Afficher moins</translation>
<translation id="5141240743006678641">Chiffrer les mots de passe synchronisés avec vos informations de connexion Google</translation>
<translation id="5145883236150621069">Code d'erreur présent dans la réponse de la règle.</translation>
+<translation id="515292512908731282">C4 (enveloppe)</translation>
<translation id="5159010409087891077">Ouvrir la page dans une nouvelle fenêtre de navigation privée (⇧⌘N)</translation>
<translation id="516920405563544094">Saisissez le code CVC de la carte <ph name="CREDIT_CARD" />. Une fois la validation effectuée, les informations relatives à la carte de votre compte Google seront partagées avec ce site.</translation>
<translation id="5169827969064885044">Vous risquez de perdre l'accès au compte de votre organisation ou d'être victime d'usurpation d'identité. L'équipe Chrome vous recommande de modifier votre mot de passe maintenant.</translation>
<translation id="5171045022955879922">Rechercher ou saisir une URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Ordinateur</translation>
<translation id="5179510805599951267">Cette page n'est pas rédigée en <ph name="ORIGINAL_LANGUAGE" /> ? Signaler l'erreur</translation>
<translation id="5190835502935405962">Barre de favoris</translation>
-<translation id="5200263511887412697">générer une liste des utilisateurs qui se sont récemment connectés à l'appareil</translation>
+<translation id="519422657042045905">Annotation indisponible</translation>
<translation id="5201306358585911203">Une page intégrée à cette page Web indique</translation>
<translation id="5205222826937269299">Veuillez saisir un nom</translation>
<translation id="5215116848420601511">Modes de paiement et adresses utilisés dans Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Veuillez saisir une adresse e-mail</translation>
<translation id="5230733896359313003">Adresse de livraison</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Se connecter au réseau"</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (enveloppe)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Adresses réseau</translation>
<translation id="5285570108065881030">Afficher tous les mots de passe enregistrés</translation>
<translation id="5287240709317226393">Afficher les cookies</translation>
<translation id="5288108484102287882">La validation des valeurs de règle a renvoyé des avertissements</translation>
@@ -693,7 +783,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> sur <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Sélectionner les coordonnées</translation>
<translation id="5327248766486351172">Nom</translation>
+<translation id="5329858041417644019">Votre navigateur n'est pas géré</translation>
<translation id="5332219387342487447">Mode de livraison</translation>
+<translation id="5334013548165032829">Journaux système détaillés</translation>
<translation id="5344579389779391559">L'accès à la page suivante peut engendrer des frais</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>
@@ -701,6 +793,7 @@
<translation id="5377026284221673050">"Votre horloge est en retard.", "Votre horloge est en avance." ou "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Connectez-vous et activez la synchronisation pour utiliser vos cartes sur tous vos appareils.</translation>
<translation id="5386426401304769735">La chaîne de certificats de ce site contient un certificat signé avec SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +804,7 @@
<translation id="5457113250005438886">Non valide</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Rétablir la modification</translation>
+<translation id="5478437291406423475">B6/C4 (enveloppe)</translation>
<translation id="5481076368049295676">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="54817484435770891">Ajouter une adresse valide</translation>
<translation id="5490432419156082418">Adresses et autres</translation>
@@ -718,10 +812,12 @@
<ph name="LINE_BREAK" />
Essayez de contacter votre administrateur système.</translation>
<translation id="549333378215107354">Taille 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Favoris gérés</translation>
<translation id="5510766032865166053">Il a peut-être été déplacé ou supprimé.</translation>
<translation id="5523118979700054094">Nom de la règle</translation>
<translation id="552553974213252141">Le texte a-t-il été extrait correctement ?</translation>
+<translation id="553484882784876924">Prc6 (enveloppe)</translation>
<translation id="5540224163453853">Impossible de trouver l'article demandé.</translation>
<translation id="5541546772353173584">Ajouter une adresse e-mail</translation>
<translation id="5545756402275714221">Articles pour vous</translation>
@@ -736,15 +832,21 @@
<translation id="5595485650161345191">Modifier l'adresse</translation>
<translation id="5598944008576757369">Sélectionner un mode de paiement</translation>
<translation id="560412284261940334">Gestion non acceptée.</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> vous a redirigé à de trop nombreuses reprises.</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="5632627355679805402">Vos données ont été chiffrées avec votre <ph name="BEGIN_LINK" />mot de passe Google<ph name="END_LINK" /> depuis le <ph name="TIME" />. Saisissez-le pour lancer la synchronisation.</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="563324245173044180">Contenu trompeur bloqué.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (enveloppe)</translation>
+<translation id="5663955426505430495">L'administrateur de cet appareil a installé des extensions permettant d'utiliser des fonctions supplémentaires. Ces extensions ont accès à certaines de vos données.</translation>
<translation id="5675650730144413517">Cette page ne fonctionne pas</translation>
+<translation id="5684874026226664614">Petit problème… Impossible de traduire cette page.</translation>
<translation id="5685654322157854305">Ajouter une adresse de livraison</translation>
<translation id="5689199277474810259">Exporter au format JSON</translation>
<translation id="5689516760719285838">Position</translation>
@@ -753,38 +855,39 @@
<translation id="5710435578057952990">L'identité de ce site Web n'a pas été vérifiée.</translation>
<translation id="5719499550583120431">Les cartes prépayées sont acceptées.</translation>
<translation id="5720705177508910913">Utilisateur actuel</translation>
+<translation id="5728056243719941842">C5 (enveloppe)</translation>
<translation id="5730040223043577876">L'équipe Chrome vous recommande de réinitialiser votre mot de passe si vous l'avez réutilisé sur d'autres sites.</translation>
<translation id="5732392974455271431">Tes parents peuvent te le débloquer</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Enregistrer une carte dans votre compte Google}one{Enregistrer une carte dans votre compte Google}other{Enregistrer des cartes dans votre compte Google}}</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="5770114862687765385">Le fichier semble être corrompu. Cliquez sur le bouton "Réinitialiser" pour réinitialiser la session.</translation>
<translation id="5778550464785688721">Contrôle total des appareils MIDI</translation>
<translation id="578305955206182703">Ambre</translation>
<translation id="57838592816432529">Couper le son</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>
+<translation id="5798290721819630480">Supprimer les modifications ?</translation>
<translation id="5798683403665926540">Modifier la page d'accueil dans les paramètres de Chrome</translation>
<translation id="5803412860119678065">Souhaitez-vous indiquer les informations "<ph name="CARD_DETAIL" />" ?</translation>
<translation id="5804241973901381774">Autorisations</translation>
<translation id="5810442152076338065">Votre connexion à <ph name="DOMAIN" /> est chiffrée à l'aide d'une méthode de chiffrement obsolète.</translation>
<translation id="5813119285467412249">&amp;Rétablir l'ajout</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="5860033963881614850">Désactivé</translation>
<translation id="5863847714970149516">Il se peut que l'accès à la page suivante engendre des frais</translation>
<translation id="5866257070973731571">Ajouter un numéro de téléphone</translation>
<translation id="5869405914158311789">Ce site est inaccessible</translation>
<translation id="5869522115854928033">Mots de passe enregistrés</translation>
<translation id="5887400589839399685">Carte enregistrée</translation>
-<translation id="5893718151540690985">générer une liste d'interfaces réseau, avec leur type et leur adresse matérielle sur le serveur</translation>
<translation id="5893752035575986141">Les cartes de crédit sont acceptées.</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="5916664084637901428">Activé</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Enregistrer la carte dans votre compte Google ?</translation>
<translation id="5922853866070715753">Vous avez presque terminé !</translation>
<translation id="5932224571077948991">Le site affiche des annonces intrusives ou trompeuses</translation>
-<translation id="5939518447894949180">Réinitialiser</translation>
<translation id="5946937721014915347">Ouverture du site <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Impossible d'enregistrer votre appareil avec un compte personnel (licence associée disponible).</translation>
<translation id="5967592137238574583">Modifier les coordonnées</translation>
@@ -792,6 +895,7 @@
<translation id="5975083100439434680">Zoom arrière</translation>
<translation id="5977489021191000276">Votre appareil n'est pas géré par un administrateur.</translation>
<translation id="5977976211062815271">Sur cet appareil</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Impossible d'ouvrir l'application de paiement</translation>
<translation id="5989320800837274978">Aucun serveur proxy déterminé ou URL de script .pac n'a été indiqué.</translation>
<translation id="5990559369517809815">Les requêtes vers le serveur ont été bloquées par une extension.</translation>
@@ -802,8 +906,8 @@
<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="6033927989869462158">envoyer des rapports sur les statistiques matérielles tels que l'utilisation du processeur et de la RAM</translation>
<translation id="6034000775414344507">Gris clair</translation>
+<translation id="6034283069659657473">10x14 (enveloppe)</translation>
<translation id="6039846035001940113">Si le problème persiste, contactez le propriétaire du site.</translation>
<translation id="6040143037577758943">Fermer</translation>
<translation id="6044573915096792553">Taille 12</translation>
@@ -812,10 +916,10 @@
<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="6058977677006700226">Vous utilisez vos cartes sur tous vos appareils ?</translation>
<translation id="6059925163896151826">Appareils USB</translation>
-<translation id="6071091556643036997">Ce type de règle n'est pas valide.</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="6094273045989040137">Annoter</translation>
<translation id="610911394827799129">Votre compte Google conserve peut-être d'autres contenus d'historique de navigation sur la page <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informations à propos des extensions et plug-ins installés</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>
@@ -850,15 +954,21 @@
<translation id="6337133576188860026">Libère moins de <ph name="SIZE" />. Le chargement de certains sites risque d'être plus lent lors de votre prochaine visite.</translation>
<translation id="6337534724793800597">Filtrer les règles par nom</translation>
<translation id="6358450015545214790">Qu'est-ce que c'est ?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Des frais peuvent vous être facturés</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 autre suggestion}one{# autre suggestion}other{# autres suggestions}}</translation>
<translation id="6387754724289022810">Pour régler plus rapidement vos achats la prochaine fois, enregistrez votre carte et votre adresse de facturation dans votre compte Google et sur cet appareil.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Modifier le favori</translation>
+<translation id="6406765186087300643">C0 (enveloppe)</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="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="6434309073475700221">Annuler</translation>
+<translation id="6446163441502663861">Kahu (enveloppe)</translation>
<translation id="6446608382365791566">Ajouter d'autres informations</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmer le nouvel envoi du formulaire</translation>
@@ -871,11 +981,17 @@
<translation id="6508722015517270189">Relancez Chrome</translation>
<translation id="6529602333819889595">&amp;Rétablir la suppression</translation>
<translation id="6534179046333460208">Suggestions pour le Web physique</translation>
+<translation id="6556866813142980365">Rétablir</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="6578796323535178455">C2 (enveloppe)</translation>
<translation id="6579990219486187401">Rose clair</translation>
+<translation id="6583674473685352014">B6 (enveloppe)</translation>
+<translation id="6587923378399804057">Lien copié</translation>
+<translation id="6591833882275308647">Votre <ph name="DEVICE_TYPE" /> n'est pas géré</translation>
<translation id="6596325263575161958">Options de chiffrement</translation>
<translation id="6604181099783169992">Capteurs de mouvement ou de lumière</translation>
+<translation id="6609880536175561541">Prc7 (enveloppe)</translation>
<translation id="6624427990725312378">Coordonnées</translation>
<translation id="6626291197371920147">Ajouter un numéro de carte valide</translation>
<translation id="6628463337424475685">Recherche <ph name="ENGINE" /></translation>
@@ -884,6 +1000,7 @@
<translation id="6644283850729428850">Cette règle est obsolète.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Aucun}=1{De 1 site (vous ne serez pas déconnecté de votre compte Google)}one{De # site (vous ne serez pas déconnecté de votre compte Google)}other{De # sites (vous ne serez pas déconnecté de votre compte Google)}}</translation>
<translation id="6657585470893396449">Mot de passe</translation>
+<translation id="6670613747977017428">Retour à la sécurité.</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>
@@ -891,12 +1008,15 @@
<translation id="671076103358959139">Jeton d'inscription :</translation>
<translation id="6711464428925977395">Le serveur proxy présente une erreur, ou l'adresse est incorrecte.</translation>
<translation id="6723740634201835758">Dans votre compte Google</translation>
+<translation id="6738516213925468394">Vos données ont été chiffrées avec votre <ph name="BEGIN_LINK" />phrase secrète de synchronisation<ph name="END_LINK" /> le <ph name="TIME" />. Saisissez-la pour lancer la synchronisation.</translation>
<translation id="674375294223700098">Erreur inconnue liée au certificat du serveur.</translation>
<translation id="6744009308914054259">En attendant d'avoir une connexion, vous pouvez consulter les téléchargements pour lire des articles hors connexion.</translation>
<translation id="6753269504797312559">Valeur de la règle</translation>
<translation id="6757797048963528358">Votre appareil s'est mis en veille.</translation>
+<translation id="6768213884286397650">Hagaki (carte postale)</translation>
<translation id="6778737459546443941">Tes parents ne l'ont pas encore autorisé</translation>
<translation id="67862343314499040">Mauve</translation>
+<translation id="6786747875388722282">Extensions</translation>
<translation id="679355240208270552">Règle ignorée, car le moteur de recherche par défaut n'est pas activé par une règle.</translation>
<translation id="681021252041861472">Champ obligatoire</translation>
<translation id="6810899417690483278">ID de la personnalisation</translation>
@@ -929,10 +1049,12 @@
<translation id="6965978654500191972">Périphérique</translation>
<translation id="6970216967273061347">District</translation>
<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="6973932557599545801">Malheureusement, je ne peux pas vous aider. Veuillez continuer manuellement.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Coupé (par défaut)</translation>
<translation id="6984479912851154518">En payant via une application externe, vous allez quitter le mode privé. Voulez-vous continuer ?</translation>
<translation id="6989763994942163495">Afficher les paramètres avancés…</translation>
+<translation id="6993898126790112050">6x9 (enveloppe)</translation>
<translation id="6996312675313362352">Toujours traduire les pages en <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Il peut s'agir de frais uniques ou récurrents qui ne sont pas toujours clairement signalés.</translation>
@@ -948,28 +1070,33 @@
<translation id="7108338896283013870">Masquer</translation>
<translation id="7108819624672055576">Autorisé par une extension</translation>
<translation id="7111012039238467737">(Valide)</translation>
+<translation id="7118618213916969306">Rechercher l'URL du presse-papier, <ph name="SHORT_URL" /></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="7135130955892390533">Afficher l'état</translation>
<translation id="7138472120740807366">Mode de livraison</translation>
<translation id="7139724024395191329">Émirat</translation>
+<translation id="7152423860607593928">Number-14 (enveloppe)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavande</translation>
-<translation id="7158980942472052083">URL non valide : vous devez saisir une URL avec un schéma standard.</translation>
<translation id="717330890047184534">Identifiant GAIA :</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Le serveur auquel vous accédez, <ph name="ORIGIN" />, a exigé qu'une règle de sécurité soit appliquée à toutes les demandes qu'il reçoit. Cependant, au lieu d'émettre une règle, il a redirigé le navigateur vers une autre destination, ce qui empêche ce dernier de répondre à votre demande pour <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Enregistrer et renseigner les modes de paiement</translation>
<translation id="7180611975245234373">Actualiser</translation>
<translation id="7182878459783632708">Aucune règle n'est définie</translation>
<translation id="7186367841673660872">Cette page en<ph name="ORIGINAL_LANGUAGE" />a été traduite en<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Libère <ph name="SIZE" />. Il se peut que certains sites se chargent moins vite à votre prochaine visite.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Votre administrateur peut consulter les éléments suivants :</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> ne respecte pas les normes de sécurité.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /> sur ce problème.</translation>
<translation id="7219179957768738017">La connexion utilise <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Traitement en cours</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" /> ; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Le site que vous allez ouvrir contient des logiciels malveillants</translation>
+<translation id="724766306220616965">Avertissements, conflit</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="7251437084390964440">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.
Informations supplémentaires :
@@ -982,11 +1109,14 @@ Informations supplémentaires :
<translation id="7300012071106347854">Bleu cobalt</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Avertissements relatifs à la <ph name="BEGIN_LINK" />navigation sécurisée<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Aide à la connexion</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Ligne de commande</translation>
-<translation id="7365061714576910172">Exporter au format Linux</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>
@@ -994,6 +1124,7 @@ Informations supplémentaires :
<translation id="7381288752349550461">Contournement dû à la session gérée</translation>
<translation id="7390545607259442187">Valider la carte</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Votre <ph name="DEVICE_NAME" /> est géré</translation>
<translation id="7407424307057130981">&lt;p&gt;Ce message d'erreur s'affiche si le logiciel Superfish est installé sur votre ordinateur Windows.&lt;/p&gt;
&lt;p&gt;Suivez ces étapes pour désactiver temporairement le logiciel afin d'accéder au Web. Vous devez disposer des droits d'administrateur.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1135,7 @@ Informations supplémentaires :
&lt;li&gt;Cliquez sur &lt;strong&gt;Appliquer&lt;/strong&gt;, puis sur &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Pour savoir comment supprimer définitivement le logiciel de votre ordinateur, consultez le &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centre d'aide Chrome&lt;/a&gt;
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestion de <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Gérer les mots de passe…</translation>
<translation id="7419106976560586862">Chemin d'accès au profil</translation>
<translation id="7437289804838430631">Ajouter des coordonnées</translation>
@@ -1013,22 +1144,24 @@ Informations supplémentaires :
<translation id="7442725080345379071">Orange clair</translation>
<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="7449109375006139765">envoyer des journaux système au serveur de gestion</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="7460618730930299168">Le filtrage est différent de ce que vous avez sélectionné. Continuer ?</translation>
<translation id="7473891865547856676">Non, merci</translation>
-<translation id="7475525192983021547">envoyer des rapports sur les périodes d'activité d'un utilisateur sur un appareil</translation>
<translation id="7481312909269577407">Avancer</translation>
<translation id="7485870689360869515">Aucune donnée n'a été trouvée.</translation>
+<translation id="7498234416455752244">Poursuivre les modifications</translation>
<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="7508870219247277067">Vert avocat</translation>
<translation id="7511955381719512146">Pour utiliser ce réseau Wi-Fi, il est possible que vous deviez vous rendre sur la page <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Télécharger</translation>
<translation id="7518003948725431193">Aucune page Web trouvée à l'adresse :<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (enveloppe)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Votre connexion à ce site n'est pas privée</translation>
+<translation id="7535087603100972091">Valeur</translation>
<translation id="7537536606612762813">Obligatoire</translation>
+<translation id="7538364083937897561">A2 (enveloppe)</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>
@@ -1037,8 +1170,8 @@ Informations supplémentaires :
<translation id="7552846755917812628">Essayez les astuces suivantes :</translation>
<translation id="7554791636758816595">Nouvel onglet</translation>
<translation id="7564049878696755256">Vous risquez de perdre l'accès à votre compte <ph name="ORG_NAME" /> ou d'être victime d'usurpation d'identité. L'équipe Chrome vous recommande de modifier votre mot de passe maintenant.</translation>
-<translation id="7566125604157659769">Texte que vous avez copié</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="7568105740864181217">Ce navigateur est géré par une entreprise, un établissement scolaire ou une autre organisation. Votre administrateur peut modifier sa configuration à distance. Il se peut que l'activité sur cet appareil soit gérée en dehors de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></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>
@@ -1049,6 +1182,7 @@ Informations supplémentaires :
<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="7633909222644580952">Données relatives aux performances et rapports d'erreur</translation>
<translation id="7637571805876720304">Supprimer les données de carte de paiement de Chromium ?</translation>
<translation id="7639968568612851608">Gris foncé</translation>
<translation id="765676359832457558">Masquer les paramètres avancés…</translation>
@@ -1058,9 +1192,11 @@ Informations supplémentaires :
<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="7676643023259824263">Rechercher le texte du presse-papier "<ph name="TEXT" />"</translation>
<translation id="7681101578153515023">Changer de moteur de recherche</translation>
<translation id="7682287625158474539">Adresse de livraison</translation>
<translation id="7687186412095877299">Saisit automatiquement les informations correspondant aux modes de paiement enregistrés</translation>
+<translation id="7697066736081121494">Prc8 (enveloppe)</translation>
<translation id="769721561045429135">Vous disposez actuellement de plusieurs cartes qui ne peuvent être utilisées que sur cet appareil. Cliquez sur "Continuer" pour examiner les cartes.</translation>
<translation id="7699293099605015246">Articles non disponibles pour le moment</translation>
<translation id="7701040980221191251">Aucun</translation>
@@ -1072,11 +1208,13 @@ Informations supplémentaires :
<translation id="774634243536837715">Contenu dangereux bloqué.</translation>
<translation id="7752995774971033316">Non géré</translation>
<translation id="7755287808199759310">Ton parent peut te le débloquer</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Il est possible qu'un pare-feu ou un logiciel antivirus ait bloqué la connexion.</translation>
<translation id="7759163816903619567">Domaine d'affichage :</translation>
<translation id="7761701407923456692">Le certificat du serveur ne correspond pas à l'URL.</translation>
<translation id="7763386264682878361">Analyseur du fichier manifeste du paiement</translation>
<translation id="7764225426217299476">Ajouter une adresse</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Préfecture</translation>
<translation id="7791543448312431591">Ajouter</translation>
<translation id="7793809570500803535">Il est possible que la page Web située à l'adresse <ph name="SITE" /> soit temporairement inaccessible ou qu'elle ait été déplacée de façon permanente à une nouvelle adresse Web.</translation>
@@ -1088,8 +1226,8 @@ Informations supplémentaires :
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Supprimer la suggestion de saisie de formulaire de Chrome ?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> trouvé(s) pour "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Gestion des règles</translation>
<translation id="782886543891417279">Pour utiliser ce réseau Wi-Fi (<ph name="WIFI_NAME" />), il est possible que vous deviez vous rendre sur la page de connexion correspondante.</translation>
+<translation id="7836231406687464395">Postfix (enveloppe)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Aucune}=1{1 application (<ph name="EXAMPLE_APP_1" />)}=2{2 applications (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# application (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# applications (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Cependant, cela ne vous rend pas invisible. Si vous passez en mode navigation privée, votre employeur, votre fournisseur d'accès à Internet ou les sites Web que vous consultez pourront toujours avoir accès à votre historique de navigation.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> : <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1236,7 @@ Informations supplémentaires :
<translation id="7878562273885520351">Votre mot de passe a peut-être été piraté</translation>
<translation id="7882421473871500483">Marron</translation>
<translation id="7887683347370398519">Veuillez vérifier votre code CVC et réessayer.</translation>
-<translation id="7893255318348328562">Nom de la session</translation>
+<translation id="7904208859782148177">C3 (enveloppe)</translation>
<translation id="79338296614623784">Saisissez un numéro de téléphone valide</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Date d'expiration : <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1246,25 @@ Informations supplémentaires :
<translation id="7951415247503192394">(32 bits)</translation>
<translation id="7956713633345437162">Favoris sur mobile</translation>
<translation id="7961015016161918242">Jamais</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Navigateur</translation>
<translation id="8009225694047762179">Gérer les mots de passe</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Cette carte et l'adresse de facturation associée seront enregistrées. Vous pourrez vous en servir lorsque vous serez connecté à <ph name="USER_EMAIL" />.}one{Cette carte et l'adresse de facturation associée seront enregistrées. Vous pourrez vous en servir lorsque vous serez connecté à <ph name="USER_EMAIL" />.}other{Ces cartes et les adresses de facturation associées seront enregistrées. Vous pourrez vous en servir lorsque vous serez connecté à <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Cette page est rédigée en <ph name="SOURCE_LANGUAGE" />. Voulez-vous la traduire en <ph name="TARGET_LANGUAGE" /> ?</translation>
<translation id="8035152190676905274">Stylo</translation>
+<translation id="8037117624646282037">Utilisateurs récents de l'appareil</translation>
<translation id="8037357227543935929">Demander (par défaut)</translation>
<translation id="803771048473350947">Fichier</translation>
<translation id="8041089156583427627">Envoyer</translation>
<translation id="8041940743680923270">Utiliser le paramètre global par défaut ("Demander")</translation>
<translation id="8042918947222776840">Sélectionner un mode d'enlèvement</translation>
<translation id="8057711352706143257">Le logiciel "<ph name="SOFTWARE_NAME" />" n'est pas configuré correctement. En général, la désinstallation de "<ph name="SOFTWARE_NAME" />" permet de remédier à la situation. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Votre appareil a été configuré comme suit :</translation>
+<translation id="8066955247577885446">Désolé, un problème est survenu.</translation>
+<translation id="8074253406171541171">10x13 (enveloppe)</translation>
<translation id="8078141288243656252">Impossible d'ajouter des annotations si le document a pivoté</translation>
<translation id="8079031581361219619">Actualiser le site Web ?</translation>
<translation id="8088680233425245692">Échec de l'affichage de l'article.</translation>
@@ -1131,11 +1273,12 @@ Informations supplémentaires :
<translation id="8091372947890762290">Activation en attente sur le serveur.</translation>
<translation id="8092774999298748321">Violet foncé</translation>
<translation id="8094917007353911263">Pour utiliser ce réseau, il est possible que deviez vous rendre sur la page <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Les cartes non valides ont été supprimées</translation>
<translation id="8103161714697287722">Mode de paiement</translation>
<translation id="8118489163946903409">Mode de paiement</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> géré par <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Le logiciel "<ph name="SOFTWARE_NAME" />" n'a pas été installé correctement sur votre ordinateur ou sur votre réseau. Demandez à l'administrateur informatique de résoudre le problème.</translation>
-<translation id="8130693978878176684">Je ne peux pas vous aider davantage. Veuillez continuer manuellement.</translation>
<translation id="8131740175452115882">Confirmer</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>
@@ -1145,8 +1288,11 @@ Informations supplémentaires :
<translation id="8197543752516192074">Traduire la page</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="8202370299023114387">Conflit</translation>
+<translation id="8206978196348664717">Prc4 (enveloppe)</translation>
<translation id="8211406090763984747">La connexion est sécurisée</translation>
<translation id="8218327578424803826">Position attribuée :</translation>
+<translation id="8220146938470311105">C7/C6 (enveloppe)</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="8238581221633243064">Ouvrir la page dans un nouvel onglet de navigation privée</translation>
@@ -1158,14 +1304,16 @@ Informations supplémentaires :
<translation id="825929999321470778">Afficher tous les mots de passe enregistrés</translation>
<translation id="8261506727792406068">Supprimer</translation>
<translation id="8267698848189296333">Connexion en tant que <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Ce navigateur est géré par <ph name="ENROLLMENT_DOMAIN" />. Votre administrateur peut modifier sa configuration à distance. Il se peut que l'activité sur cet appareil soit gérée en dehors de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Connexion</translation>
<translation id="8288807391153049143">Afficher le certificat</translation>
<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="8298115750975731693">Pour utiliser ce réseau Wi-Fi (<ph name="WIFI_NAME" />), il est possible que vous deviez vous rendre sur la page <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Échec de la traduction en raison d'un problème de connexion réseau</translation>
-<translation id="8311129316111205805">Charger la session</translation>
<translation id="8332188693563227489">L'accès à <ph name="HOST_NAME" /> a été refusé</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1331,6 @@ Informations supplémentaires :
<translation id="8416694386774425977">Impossible d'importer la configuration du réseau : elle n'est pas valide.
Informations supplémentaires :
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Appareil géré par <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Modifier</translation>
<translation id="8428213095426709021">Paramètres</translation>
@@ -1210,9 +1357,11 @@ Informations supplémentaires :
<translation id="860043288473659153">Nom du titulaire de la carte</translation>
<translation id="861775596732816396">Taille 4</translation>
<translation id="8620436878122366504">Tes parents ne l'ont pas encore autorisé</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Enregistrer cette carte sur cet appareil</translation>
<translation id="8663226718884576429">Récapitulatif de la commande, <ph name="TOTAL_LABEL" />, détails supplémentaires</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, réponse, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Votre connexion à <ph name="DOMAIN" /> n'est pas chiffrée.</translation>
<translation id="8718314106902482036">Paiement non finalisé</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, suggestion de recherche</translation>
@@ -1226,6 +1375,7 @@ Informations supplémentaires :
<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="8763927697961133303">Périphérique USB</translation>
<translation id="8768895707659403558">Pour utiliser vos cartes sur tous vos appareils, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Rétablir la suppression</translation>
<translation id="8792621596287649091">Vous risquez de perdre l'accès à votre compte <ph name="ORG_NAME" /> ou d'être victime d'usurpation d'identité. L'équipe Chromium vous recommande de modifier votre mot de passe maintenant.</translation>
<translation id="8800988563907321413">Vos suggestions à proximité s'affichent ici</translation>
@@ -1236,10 +1386,12 @@ Informations supplémentaires :
<translation id="885730110891505394">Partage avec Google</translation>
<translation id="8858065207712248076">L'équipe Chrome vous recommande de réinitialiser votre mot de passe <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> si vous l'avez réutilisé sur d'autres sites.</translation>
<translation id="8866481888320382733">Erreur d'analyse des paramètres de la règle.</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Récemment fermés</translation>
<translation id="8874824191258364635">Saisissez un numéro de carte valide</translation>
<translation id="8891727572606052622">Mode proxy non valide.</translation>
<translation id="8903921497873541725">Zoom avant</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Ajouter un nom</translation>
@@ -1247,13 +1399,13 @@ Informations supplémentaires :
<translation id="894185898663964645">Votre administrateur a configuré des certificats racines personnalisés, qui peuvent permettre à l'administrateur de voir le contenu des sites Web que vous consultez.</translation>
<translation id="8943282376843390568">Citron vert</translation>
<translation id="8957210676456822347">Autorisation du portail captif</translation>
+<translation id="8966619695390250636">Essayez avec :</translation>
<translation id="8968766641738584599">Enregistrer la carte</translation>
<translation id="8971063699422889582">Le certificat du serveur a expiré.</translation>
<translation id="8975012916872825179">Y compris les numéros de téléphone, les adresses e-mail et les adresses de livraison</translation>
<translation id="8978053250194585037">La fonctionnalité de navigation sécurisée Google a récemment permis de <ph name="BEGIN_LINK" />détecter une tentative d'hameçonnage<ph name="END_LINK" /> 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="8983003182662520383">Modes de paiement et adresses utilisés dans Google Pay</translation>
<translation id="8987927404178983737">Mois</translation>
-<translation id="8988408250700415532">Un problème est survenu. Vous pouvez finaliser votre commande sur le site Web.</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>
@@ -1263,6 +1415,7 @@ Informations supplémentaires :
<translation id="9011424611726486705">Ouvrir les paramètres du site</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Non valide)</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>
@@ -1274,11 +1427,11 @@ Informations supplémentaires :
<translation id="9065745800631924235">Recherche sur "<ph name="TEXT" />" dans l'historique</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="9076630408993835509">Ce navigateur n'est géré par aucune entreprise ni aucune autre organisation. Il se peut que l'activité sur cet appareil soit gérée en dehors de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Veuillez fournir d'autres informations</translation>
<translation id="9080712759204168376">Récapitulatif de la commande</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>
<translation id="9106062320799175032">Ajouter une adresse de facturation</translation>
-<translation id="9110718169272311511">L'Assistant Google dans Chrome est disponible au bas de l'écran</translation>
<translation id="9114524666733003316">Validation de la carte…</translation>
<translation id="9128870381267983090">Se connecter au réseau</translation>
<translation id="9137013805542155359">Afficher l'original</translation>
@@ -1287,6 +1440,7 @@ Informations supplémentaires :
<translation id="9148507642005240123">&amp;Annuler la modification</translation>
<translation id="9154194610265714752">Mis à jour</translation>
<translation id="9157595877708044936">Configuration en cours...</translation>
+<translation id="9158625974267017556">C6 (enveloppe)</translation>
<translation id="9168814207360376865">Autorise les sites à vérifier si vous avez enregistré des modes de paiement</translation>
<translation id="9169664750068251925">Toujours bloquer sur ce site</translation>
<translation id="9170848237812810038">Ann&amp;uler</translation>
@@ -1301,10 +1455,12 @@ Informations supplémentaires :
<translation id="9219103736887031265">Images</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">EFFACER LE FORMULAIRE</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Vous pourriez perdre l'accès à votre compte Google. L'équipe Chromium vous recommande de modifier votre mot de passe maintenant. Vous devrez vous connecter.</translation>
<translation id="939736085109172342">Nouveau dossier</translation>
<translation id="945855313015696284">Vérifiez les informations ci-dessous et supprimez les cartes non valides</translation>
<translation id="951104842009476243">Cartes de débit et cartes prépayées acceptées</translation>
+<translation id="958202389743790697">Bloqué selon la règle de sécurité de <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Ce contenu peut essayer d'installer des applications trompeuses se faisant passer pour d'autres, ou de collecter des données afin de vous surveiller. <ph name="BEGIN_LINK" />Je souhaite y accéder malgré tout.<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Build officiel</translation>
<translation id="973773823069644502">Ajouter une adresse d'expédition</translation>
@@ -1313,6 +1469,7 @@ Informations supplémentaires :
<translation id="984275831282074731">Modes de paiement</translation>
<translation id="985199708454569384">&lt;p&gt;Ce message s'affiche si la date et l'heure de votre ordinateur ou de votre appareil mobile sont incorrectes.&lt;/p&gt;
&lt;p&gt;Pour corriger cette erreur, ouvrez l'horloge de votre appareil et assurez-vous que l'heure et la date sont correctes.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Build de développement</translation>
<translation id="989988560359834682">Modifier l'adresse</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_gu.xtb b/chromium/components/strings/components_strings_gu.xtb
index fd2300cbba1..0519f1968b7 100644
--- a/chromium/components/strings/components_strings_gu.xtb
+++ b/chromium/components/strings/components_strings_gu.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="gu">
-<translation id="1005145902654145231">સત્રને નવું નામ આપવામાં નિષ્ફળ થયાં.</translation>
<translation id="1008557486741366299">હમણાં નહીં</translation>
<translation id="1010200102790553230">પેજ પછીથી લોડ કરો</translation>
<translation id="1015730422737071372">અતિરિક્ત વિગતો પ્રદાન કરો</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">અજ્ઞાત નામ</translation>
<translation id="1050038467049342496">અન્ય ઍપ્લિકેશનો બંધ કરો</translation>
<translation id="1055184225775184556">&amp;ઉમેરવું પૂર્વવત્ કરો</translation>
+<translation id="1056898198331236512">ચેતવણી</translation>
<translation id="1058479211578257048">કાર્ડ સાચવી રહ્યાં છીએ…</translation>
<translation id="10614374240317010">ક્યારેય ન સચવાયેલું</translation>
+<translation id="1062160989074299343">Prc10 (એન્વલપ)</translation>
<translation id="106701514854093668">ડેસ્કટૉપ બુકમાર્ક્સ</translation>
<translation id="1074497978438210769">સુરક્ષિત નથી</translation>
<translation id="1080116354587839789">પહોળાઈ પ્રમાણે ફિટ કરો</translation>
+<translation id="1086953900555227778">અનુક્રમણિકા-5x8</translation>
<translation id="1088860948719068836">કાર્ડ પર નામ ઉમેરો</translation>
<translation id="1089439967362294234">પાસવર્ડ બદલો</translation>
<translation id="109743633954054152">Chrome સેટિંગમાં પાસવર્ડ મેનેજ કરો</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">વેબસાઇટ તેમની સુરક્ષા અપડેટ કરી રહ્યાં હોય ત્યારે ચેતવણીઓ દેખાવી સામાન્ય બાબત છે. ટૂંક સમયમાં જ આમાં સુધારો કરવામાં આવશે.</translation>
<translation id="1126551341858583091">સ્થાનિક સ્ટોરેજ પરનું કદ <ph name="CRASH_SIZE" /> છે.</translation>
<translation id="112840717907525620">નીતિ કૅશ મેમરી ઓકે</translation>
+<translation id="1131264053432022307">તમે કૉપિ કરેલી છબી</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> એ અનપેક્ષિત રીતે કનેક્શન બંધ કર્યું.</translation>
<translation id="1161325031994447685">વાઇ-ફાઇ સાથે ફરીથી કનેક્ટ કરીને</translation>
<translation id="1165039591588034296">ભૂલ</translation>
-<translation id="1173894706177603556">નામ બદલો</translation>
<translation id="1175364870820465910">&amp;છાપો...</translation>
<translation id="1181037720776840403">કાઢી નાખો</translation>
<translation id="1197088940767939838">નારંગી</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">તમારા ડિવાઇસનું નામ</translation>
<translation id="124116460088058876">વધુ ભાષાઓ</translation>
<translation id="1250759482327835220">આગલી વખતે વધુ ઝડપથી ચુકવણી કરવા માટે, તમારા કાર્ડ, નામ અને બિલિંગ સરનામાને તમારા Google એકાઉન્ટમાં સાચવો.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (સમન્વયિત)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">આદેશ વાક્યમાં વિવિધતા</translation>
<translation id="129553762522093515">તાજેતરમાં બંધ કરેલા</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />તમારી કૂકીઝને સાફ કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">પસંદ કરેલ સત્ર અસ્તિત્વમાં નથી.</translation>
+<translation id="1320233736580025032">Prc1 (એન્વલપ)</translation>
+<translation id="132301787627749051">ક્લિપબોર્ડ છબી શોધો</translation>
<translation id="1323433172918577554">વધુ બતાવો</translation>
<translation id="132390688737681464">સરનામાં સાચવો અને ભરો</translation>
<translation id="1333989956347591814">તમારી પ્રવૃત્તિ <ph name="BEGIN_EMPHASIS" />હજીપણ દૃશ્યક્ષમ હોય શકે છે<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">પિકઅપ માટેનું સરનામું</translation>
<translation id="1348198688976932919">સાઇટમાં આગળ જોખમકારક ઍપ્લિકેશનો છે</translation>
<translation id="1348779747280417563">નામ કન્ફર્મ કરો</translation>
+<translation id="1357195169723583938">તાજેતરમાં ડિવાઇસનો ઉપયોગ કોણે કર્યો છે અને ક્યારે</translation>
+<translation id="1364822246244961190">આ પૉલિસી બ્લૉક કરેલ છે, તેનું મૂલ્ય અવગણવામાં આવશે.</translation>
<translation id="1374468813861204354">સૂચનો</translation>
+<translation id="1374692235857187091">અનુક્રમણિકા-4x6 (પોસ્ટકાર્ડ)</translation>
<translation id="1375198122581997741">વર્ઝન વિશે</translation>
<translation id="1376836354785490390">ઓછું બતાવો</translation>
<translation id="1377321085342047638">કાર્ડ નંબર</translation>
<translation id="138218114945450791">આછો વાદળી</translation>
+<translation id="1382194467192730611">USB ડિવાઇસને તમારા વ્યવસ્થાપક દ્વારા મંજૂરી આપવામાં આવેલી છે</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> એ કોઈપણ ડેટા મોકલ્યો ન હતો.</translation>
+<translation id="140316286225361634">આ સાઇટ <ph name="ORIGIN" /> દ્વારા વિનંતી કરવામાં આવી છે કે સુરક્ષા પૉલિસી તેની બધી
+ વિનંતી પર લાગુ થશે અને આ પૉલિસી હાલમાં આ સાઇટને અસુરક્ષિત
+ માને છે.</translation>
<translation id="1405567553485452995">આછો લીલો</translation>
<translation id="1407135791313364759">બધું ખોલો</translation>
<translation id="1413809658975081374">ગોપનીયતા ભૂલ</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">હા</translation>
<translation id="1430915738399379752">પ્રિન્ટ</translation>
<translation id="1455413310270022028">ઇરેઝર</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">વધુ બતાવો</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">વિતરણ માટેનું સરનામું પસંદ કરો</translation>
+<translation id="1492194039220927094">પુશ કરેલી પૉલિસી:</translation>
<translation id="1501859676467574491">તમારા Google એકાઉન્ટમાંથી કાર્ડ બતાવો</translation>
-<translation id="1506687042165942984">આ પૃષ્ઠની સાચવેલી (એટલે કે જૂની થઈ ગયેલી તરીકે ઓળખાતી) કૉપિ દર્શાવો.</translation>
<translation id="1507202001669085618">&lt;p&gt;જો તમે ઑનલાઇન થાઓ એ પહેલાં જ્યાં તમારે સાઇન ઇન કરવું જરૂરી હોય તેવા વાઇ-ફાઇ પોર્ટલનો ઉપયોગ કરી રહ્યા હો, તો તમને આ ભૂલ દેખાશે.&lt;/p&gt;
&lt;p&gt;આ સમસ્યા ઉકેલવા માટે, તમે ખોલવાનો પ્રયાસ કરી રહ્યા છો એ પેજ પર &lt;strong&gt;કનેક્ટ કરો&lt;/strong&gt; પર ક્લિક કરો.&lt;/p&gt;</translation>
<translation id="1517433312004943670">ફોન નંબર આવશ્યક</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">નિર્માણ તારીખ</translation>
<translation id="1521655867290435174">Google શીટ</translation>
<translation id="1527263332363067270">કનેક્શનની રાહ જોઈ રહ્યાં છીએ...</translation>
+<translation id="1529521330346880926">10x15 (એન્વલપ)</translation>
+<translation id="1531205177818805254">એક્સેક</translation>
<translation id="1532118530259321453">આ પેજ કહે છે કે</translation>
<translation id="153384715582417236">હમણાં માટે બસ આટલું પૂરતું છે</translation>
<translation id="154408704832528245">વિતરણ માટેનું સરનામું પસંદ કરો</translation>
<translation id="1549470594296187301">આ સુવિધાનો ઉપયોગ કરવા માટે JavaScript સક્ષમ કરેલ હોવી આવશ્યક છે.</translation>
+<translation id="155039086686388498">એન્જિનિયરિંગ-D</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="1569487616857761740">સમાપ્તિ તારીખ દાખલ કરો</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">આ વેબપેજ બતાવતી વખતે કંઈક ખોટું થયું.</translation>
<translation id="1592005682883173041">સ્થાનિક ડેટા ઍક્સેસ</translation>
<translation id="1594030484168838125">પસંદ કરો</translation>
<translation id="161042844686301425">સ્યાન</translation>
-<translation id="1618822247301510817">તમે કૉપિ કરેલ છબી</translation>
<translation id="1620510694547887537">કૅમેરો</translation>
<translation id="1623104350909869708">આ પૃષ્ઠને વધારાના સંવાદો બનાવતા અટકાવો</translation>
+<translation id="16338877384480380">સ્થાપત્ય-B</translation>
<translation id="1634051627998691300">સત્ર સમાપ્ત કરો</translation>
<translation id="1639239467298939599">લોડ કરી રહ્યું છે</translation>
<translation id="1640180200866533862">વપરાશકર્તા નીતિઓ</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> સામાન્ય રીતે તમારી માહિતીને સુરક્ષિત રાખવા માટે એન્ક્રિપ્શનનો ઉપયોગ કરે છે. જ્યારે આ સમયે Google Chrome દ્વારા <ph name="SITE" />થી કનેક્ટ કરવાનો પ્રયાસ થયો, ત્યારે વેબસાઇટે અસામાન્ય અને ખોટા લૉગ ઇન વિગતને પાછા મોકલ્યાં. આવું ત્યારે થઈ શકે જ્યારે કોઈ હુમલાખોર <ph name="SITE" /> હોવાનો ડોળ કરવાનો પ્રયાસ કરી રહ્યો હોય અથવા કોઈ Wi-Fi સાઇન-ઇન સ્ક્રીને કનેક્શનમાં વિક્ષેપ પાડ્યો હોય. તમારી માહિતી હજી પણ સુરક્ષિત છે કારણ કે Google Chrome એ કોઈ પણ ડેટા વિનિમય થાય એ પહેલાં જ કનેક્શન રોકી દીધું.</translation>
<translation id="168841957122794586">સર્વર પ્રમાણપત્ર એક નબળી ક્રિપ્ટોગ્રાફિક કી ધરાવે છે.</translation>
<translation id="1697532407822776718">તમારું બધું સેટ છે!</translation>
+<translation id="1703835215927279855">અક્ષર</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="1715874602234207">F</translation>
<translation id="1718029547804390981">એનોટેટ કરવા માટે દસ્તાવેજ ઘણો મોટો છે</translation>
<translation id="1721312023322545264">આ સાઇટની મુલાકાત લેવા માટે તમને <ph name="NAME" /> ની પરવાનગીની જરૂર છે</translation>
<translation id="1721424275792716183">* ફીલ્ડ આવશ્યક છે</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">સિસ્ટમ વ્યવસ્થાપકનો સંપર્ક કરવાનો પ્રયાસ કરો.</translation>
<translation id="1740951997222943430">એક માન્ય સમાપ્તિ મહિનો દાખલ કરો</translation>
<translation id="1743520634839655729">આગલી વખતે વધુ ઝડપથી ચુકવણી કરવા માટે, તમારા કાર્ડ, નામ અને બિલિંગ સરનામાને તમારા Google એકાઉન્ટ અને આ ઉપકરણ પર સાચવો.</translation>
+<translation id="1745880797583122200">તમારું બ્રાઉઝર મેનેજ કરવામાં આવે છે</translation>
<translation id="17513872634828108">ટેબ્સ ખોલો</translation>
<translation id="1753706481035618306">પૃષ્ઠ નંબર</translation>
<translation id="1763864636252898013">આ સર્વર સાબિત કરી શક્યું નથી કે એ <ph name="DOMAIN" /> છે; એનું સુરક્ષા પ્રમાણપત્ર તમારા ડિવાઇસની ઑપરેટિંગ સિસ્ટમ દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">કૃપા કરી તમારા સમન્વયન પાસફ્રેઝને અપડેટ કરો.</translation>
<translation id="1787142507584202372">તમારા ખુલ્લા ટૅબ્સ અહીં દેખાય છે</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">કાર્ડધારકનું નામ</translation>
<translation id="1821930232296380041">અમાન્ય વિનંતી અથવા વિનંતી પરિમાણો</translation>
+<translation id="1822540298136254167">તમે મુલાકાત લો તે વેબસાઇટ અને તેના પર વિતાવેલો સમય</translation>
<translation id="1826516787628120939">તપાસી રહ્યાં છે</translation>
<translation id="1834321415901700177">આ સાઇટમાં હાનિકારક પ્રોગ્રામ્સ છે</translation>
<translation id="1839551713262164453">ભૂલના લીધે નીતિ મૂલ્યોની માન્યતા નિષ્ફળ થઈ</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Chromeના બ્રાઉઝિંગ ઇતિહાસનો ડેટા સાફ કરો</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{અને 1 વધુ}one{અને # વધુ}other{અને # વધુ}}</translation>
<translation id="2003709556000175978">તમારો પાસવર્ડ હમણાં જ રીસેટ કરો</translation>
+<translation id="20053308747750172">તમે જેના પર જવાનો પ્રયાસ કરી રહ્યાં છો, તે<ph name="ORIGIN" /> સર્વર દ્વારા વિનંતી
+ કરવામાં આવી છે કે સુરક્ષા પૉલિસી તેના પરની બધી વિનંતીઓ પર લાગુ થશે. પણ તેણે હમણાં
+ અમાન્ય પૉલિસી વિતરિત કરી છે, જે બ્રાઉઝરને તમારી
+ <ph name="SITE" /> માટેની વિનંતી પૂરી કરવાથી અટકાવે છે.</translation>
<translation id="2025186561304664664">પ્રૉક્સીને ઑટો ગોઠવણી મોડ પર સેટ કરાઈ છે.</translation>
<translation id="2030481566774242610">શું તમારો અર્થ <ph name="LINK" /> છે?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />પ્રૉક્સી અને ફાયરવૉલ ચેક કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">વિભાગ</translation>
<translation id="2102134110707549001">સશક્ત પાસવર્ડ સૂચવો…</translation>
<translation id="2108755909498034140">તમારું કમ્પ્યુટર પુનઃપ્રારંભ કરો</translation>
+<translation id="2111256659903765347">સુપર-A</translation>
<translation id="2113977810652731515">કાર્ડ</translation>
<translation id="2114841414352855701">અવગણ્યું કારણ કે તે <ph name="POLICY_NAME" /> દ્વારા ઓવરરાઇડ થયું હતું.</translation>
<translation id="213826338245044447">મોબાઇલ બુકમાર્ક્સ</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">કાર્ડમાં ફેરફાર કરો</translation>
<translation id="2166049586286450108">સંપૂર્ણ વ્યવસ્થાપક ઍક્સેસ</translation>
<translation id="2166378884831602661">આ સાઇટ એક સુરક્ષિત કનેક્શન આપી શકતી નથી</translation>
+<translation id="2169984857010174799">Kaku2 (એન્વલપ)</translation>
<translation id="2181821976797666341">નીતિઓ</translation>
<translation id="2183608646556468874">ફોન નંબર</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 સરનામું}one{# સરનામાં}other{# સરનામાં}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">ફોન નંબર</translation>
<translation id="2283340219607151381">સરનામાં સાચવો અને ભરો</translation>
<translation id="2292556288342944218">તમારી ઇન્ટરનેટ ઍક્સેસ અવરોધિત છે</translation>
+<translation id="2294558542833290837">તમે મૂળરૂપે ખોલેલી લિંક અસામાન્ય છે</translation>
+<translation id="2297722699537546652">B5 (એન્વલપ)</translation>
+<translation id="2310021320168182093">Chou2 (એન્વલપ)</translation>
<translation id="2316887270356262533">1 MB કરતાં ઓછું ખાલી કરે છે. તમારી આગલી મુલાકાત સમયે કેટલીક સાઇટો વધુ ધીમે લોડ થઈ શકે છે.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> માટે વપરાશકર્તાનામ અને પાસવર્ડ આવશ્યક છે.</translation>
<translation id="2317583587496011522">ડેબિટ કાર્ડ સ્વીકારવામાં આવે છે.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, <ph name="EXPIRATION_DATE_ABBR" />ના રોજ સમાપ્ત થાય છે</translation>
<translation id="2337852623177822836">તમારા વ્યવસ્થાપકે નિયંત્રિત કરેલ સેટિંગ</translation>
+<translation id="2346319942568447007">તમે કૉપિ કરેલી છબી</translation>
<translation id="2349790679044093737">VR સત્ર સક્રિય છે</translation>
<translation id="2354001756790975382">અન્ય બુકમાર્ક્સ</translation>
<translation id="2354430244986887761">Google સલામત બ્રાઉઝિંગને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />હાનિકારક ઍપ્લિકેશન મળી<ph name="END_LINK" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> એ કૅપ્ચર કરેલ ક્રૅશ રિપોર્ટ અપલોડ કરી ન હતી</translation>
<translation id="2367567093518048410">સ્તર</translation>
<translation id="2378238891085281592">હવે તમારું કાર્ય ખાનગીમાં થશે</translation>
+<translation id="2380886658946992094">કાનૂની</translation>
<translation id="2384307209577226199">એન્ટરપ્રાઇઝ ડિફોલ્ટ</translation>
<translation id="2386255080630008482">સર્વરનું પ્રમાણપત્ર રદ કરવામાં આવ્યું છે.</translation>
<translation id="2392959068659972793">કોઈ કિંમત સેટ નહીં સાથે નીતિઓ બતાવો</translation>
<translation id="239429038616798445">આ વિતરણ પદ્ધતિ ઉપલબ્ધ નથી. કોઈ ભિન્ન પદ્ધતિ અજમાવો.</translation>
<translation id="2396249848217231973">&amp;ડિલીટ રદ કરો</translation>
+<translation id="2410754574180102685">સરકારી-કાનૂની</translation>
<translation id="2413528052993050574">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર રદબાતલ થયું હશે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
+<translation id="2418081434543109369">તમે જેના પર જવાનો પ્રયાસ કરી રહ્યાં છો, તે<ph name="ORIGIN" /> સર્વર દ્વારા વિનંતી
+ કરવામાં આવી છે કે સુરક્ષા પૉલિસી તેના પરની બધી વિનંતીઓ પર લાગુ થશે. પણ તે હમણાં
+ પૉલિસી વિતરિત કરવામાં નિષ્ફળ થયું, જે બ્રાઉઝરને તમારી
+ <ph name="SITE" /> માટેની વિનંતી પૂરી કરવાથી અટકાવે છે.</translation>
<translation id="244665789865330679">તમારું ડિવાઇસ અને એકાઉન્ટ <ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે. આનો અર્થ છે કે તમારા વ્યવસ્થાપક તમારા ડિવાઇસ અને એકાઉન્ટને રિમોટલી ગોઠવી શકે છે.</translation>
<translation id="2463193859425327265">હોમ પેજ બદલો</translation>
<translation id="2463739503403862330">ભરો</translation>
+<translation id="2465402087343596252">સ્થાપત્ય-E</translation>
<translation id="2465655957518002998">વિતરણ પદ્ધતિ પસંદ કરો</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />નેટવર્ક ડાયગ્નોસ્ટિક્સ ચલાવી રહ્યાં છે<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">આ પૃષ્ઠનો અનુવાદ કરો</translation>
<translation id="2479410451996844060">અમાન્ય શોધ URL.</translation>
<translation id="2482878487686419369">સૂચનાઓ</translation>
<translation id="248348093745724435">મશીન નીતિઓ</translation>
+<translation id="2485387744899240041">તમારા ડિવાઇસ અને બ્રાઉઝર માટે વપરાશકર્તાનું નામ</translation>
<translation id="2491120439723279231">સર્વરના પ્રમાણપત્રમાં ભૂલો છે.</translation>
+<translation id="2493640343870896922">લેટર-પ્લસ</translation>
<translation id="2495083838625180221">JSON વિશ્લેષક</translation>
<translation id="2495093607237746763">જો ચેક કરેલું હોય, તો ઝડપથી ફોર્મ ભરવા માટે Chromium આ ઉપકરણ પર તમારા કાર્ડની એક કૉપિ સંગ્રહિત કરશે.</translation>
<translation id="2498091847651709837">નવું કાર્ડ સ્કૅન કરો</translation>
<translation id="2501278716633472235">પાછા જાઓ</translation>
<translation id="2503184589641749290">સ્વીકૃત ડેબિટ અને પ્રીપેઇડ કાર્ડ</translation>
<translation id="2515629240566999685">તમારા વિસ્તારમાં સિગ્નલ તપાસીને</translation>
-<translation id="2516852381693169964">છબી માટે <ph name="SEARCH_ENGINE" /> પર શોધો</translation>
<translation id="2523886232349826891">કાર્ડની માહિતીને માત્ર આ ડિવાઇસ પર સાચવવામાં આવી છે</translation>
<translation id="2524461107774643265">વધુ માહિતી ઉમેરો</translation>
<translation id="2536110899380797252">સરનામું ઉમેરો</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">ડિરેક્ટરી API ID:</translation>
<translation id="2597378329261239068">આ દસ્તાવેજ પાસવર્ડ સુરક્ષિત છે. કૃપા કરીને પાસવર્ડ દાખલ કરો.</translation>
<translation id="2609632851001447353">વૈવિધ્ય</translation>
+<translation id="2618023639789766142">C10 (એન્વલપ)</translation>
<translation id="2625385379895617796">તમારી ઘડિયાળ આગળ છે</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" />નું સર્વર IP ઍડ્રેસ ન મળ્યું.</translation>
<translation id="2639739919103226564">સ્થિતિ:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">અન્ય ટૅબ અથવા ઍપ્લિકેશનો બંધ કરો</translation>
<translation id="267371737713284912">છેલ્લો ફેરફાર રદ કરવા માટે <ph name="MODIFIER_KEY_DESCRIPTION" /> દબાવો</translation>
<translation id="2674170444375937751">શું તમે ખરેખર તમારા ઇતિહાસમાંથી આ પેજને ડિલીટ કરવા માંગો છો?</translation>
+<translation id="2676271551327853224">રૉક-8K</translation>
<translation id="2677748264148917807">છોડો</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">સ્વીકૃત કાર્ડ</translation>
<translation id="2702801445560668637">વાંચન સૂચિ</translation>
<translation id="2704283930420550640">મૂલ્ય ફોર્મેટથી મેળ ખાતું નથી.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">પસંદ કરેલી આઇટમ્સને દૂર કરો</translation>
<translation id="277133753123645258">વિતરણ પદ્ધતિ</translation>
<translation id="277499241957683684">ઉપકરણ રેકોર્ડ ખૂટે છે</translation>
-<translation id="2781030394888168909">MacOSના ફૉર્મેટમાં નિકાસ કરો</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">કનેક્શન ફરીથી સેટ થયું.</translation>
<translation id="2788784517760473862">સ્વીકૃત ક્રેડિટ કાર્ડ</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">કનેક્શન <ph name="CIPHER" />નો ઉપયોગ કરીને એન્ક્રિપ્ટ અને પ્રમાણિત કરેલુંં છે અને મુખ્ય એક્સચેન્જ મેકેનિઝ્મ તરીકે <ph name="KX" />નો ઉપયોગ કરે છે.</translation>
<translation id="2835170189407361413">ફોર્મ સાફ કરો</translation>
<translation id="2847118875340931228">છુપી વિન્ડો ખોલો</translation>
+<translation id="2850739647070081192">આમંત્રણ (એન્વલપ)</translation>
<translation id="2851634818064021665">આ સાઇટની મુલાકાત લેવા માટે તમને પરનાવગીની જરૂર છે</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">કાર્ડ સાચવીએ?</translation>
<translation id="2903493209154104877">સરનામાંઓ</translation>
<translation id="290376772003165898">પેજ <ph name="LANGUAGE" />માં નથી?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">વિતરણ પદ્ધતિ</translation>
<translation id="2928905813689894207">બિલિંગનું સરનામું</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">સરકારી-દસ્તાવેજ</translation>
<translation id="2941952326391522266">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર <ph name="DOMAIN2" /> નું છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="2948083400971632585">તમે સેટિંગ પેજમાંથી કનેક્શન માટે ગોઠવવામાં આવેલ કોઈપણ પ્રોક્સીઓ બંધ કરી શકો છો.</translation>
<translation id="2955913368246107853">શોધ બાર બંધ કરો</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (એન્વલપ)</translation>
<translation id="3024663005179499861">ખોટો નીતિ પ્રકાર</translation>
<translation id="3037605927509011580">અરર કંઇક ભુલ થઇ!</translation>
<translation id="3041612393474885105">પ્રમાણપત્ર માહિતી</translation>
+<translation id="3060227939791841287">C9 (એન્વલપ)</translation>
<translation id="3064966200440839136">બાહ્ય ઍપ્લિકેશન મારફતે ચુકવણી કરવા માટે છુપો મોડ છોડી રહ્યાં છીએ. તો ચાલુ રાખીએ?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{કોઈ નહીં}=1{1 પાસવર્ડ}one{# પાસવર્ડ}other{# પાસવર્ડ}}</translation>
+<translation id="3095940652251934233">સ્ટેટમેંટ</translation>
<translation id="3096100844101284527">પિકઅપ માટેનું સરનામું ઉમેરો</translation>
<translation id="3105172416063519923">સંપત્તિ ID:</translation>
<translation id="3109728660330352905">તમને આ પેજને જોવાનો અધિકાર નથી.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> પર <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">ચુકવણી રદ કરો</translation>
<translation id="3207960819495026254">બુકમાર્ક કરેલ</translation>
-<translation id="3209375525920864198">કૃપા કરીને સત્રનું માન્ય નામ દાખલ કરો.</translation>
+<translation id="321912867715453276">ચેતવણી: આ પૉલિસી માટે એકથી વધુ સૉર્સ ઉપલબ્ધ છે, પણ મૂલ્ય સમાન છે.</translation>
<translation id="3225919329040284222">સર્વર એક પ્રમાણપત્ર પ્રસ્તુત કરે છે જે બિલ્ટ-ઇન અપેક્ષાઓ સાથે મેળ ખાતું નથી. આ અપેક્ષાઓમાં તમને સુરક્ષિત રાખવા માટે અમુક ચોક્કસ, ઉચ્ચ-સુરક્ષા વેબસાઇટ્સનો સમાવેશ થાય છે.</translation>
<translation id="3226128629678568754">પૃષ્ઠને લોડ કરવા માટે જરૂરી ડેટા ફરીથી સબમિટ કરવા માટે ફરીથી લોડ કરો બટન દબાવો.</translation>
<translation id="3227137524299004712">માઇક્રોફોન</translation>
<translation id="3228969707346345236">ભાષાંતર નિષ્ફળ રહ્યું કારણ કે પૃષ્ઠ પહેલાથી જ <ph name="LANGUAGE" /> માં છે.</translation>
+<translation id="3229041911291329567">તમારા ડિવાઇસ અને બ્રાઉઝર વિશે વર્ઝન માહિતી</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">કાર્ડ પર નામ ઉમેરો</translation>
<translation id="3287510313208355388">ઑનલાઇન હોય ત્યારે ડાઉનલોડ કરો</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> નીતિ વિશે વધુ જાણો</translation>
<translation id="3303855915957856445">કોઈ શોધ પરિણામો મળ્યાં નથી</translation>
-<translation id="3305707030755673451">તમારો ડેટા <ph name="TIME" />ના રોજ તમારા સિંક પાસફ્રેઝ સાથે એન્ક્રિપ્ટ કરવામાં આવ્યો હતો. સિંક શરૂ કરવા માટે એ દાખલ કરો.</translation>
<translation id="3320021301628644560">બિલિંગ સરનામું ઉમેરો</translation>
<translation id="3324983252691184275">કિરમજી</translation>
<translation id="3338095232262050444">સુરક્ષિત</translation>
@@ -404,9 +453,11 @@
<translation id="3427342743765426898">&amp;ફરી ફેરફાર કરો</translation>
<translation id="342781501876943858">જો તમે અન્ય સાઇટ પર તમારા પાસવર્ડનો ફરી ઉપયોગ કર્યો હોય, તો Chromium તેને રીસેટ કરવાનો સુઝાવ આપે છે.</translation>
<translation id="3431636764301398940">આ ડિવાઇસ પર આ કાર્ડ સાચવો</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">આ ઉપકરણના માલિકે ડાયનાસોર રમત બંધ કરી છે.</translation>
<translation id="3447884698081792621">(<ph name="ISSUER" /> દ્વારા રજૂ થયેલ) પ્રમાણપત્ર બતાવો</translation>
<translation id="3452404311384756672">આનયન અંતરાલ:</translation>
+<translation id="3456231139987291353">નંબર-11 (એન્વલપ)</translation>
<translation id="3461824795358126837">હાઇલાઇટર</translation>
<translation id="3462200631372590220">વિગતવાર છુપાવો</translation>
<translation id="3467763166455606212">કાર્ડધારકનું નામ આવશ્યક છે</translation>
@@ -429,20 +480,23 @@
<translation id="358285529439630156">ક્રેડિટ અને પ્રીપેઇડ કાર્ડ સ્વીકારવામાં આવે છે.</translation>
<translation id="3582930987043644930">નામ ઉમેરો</translation>
<translation id="3583757800736429874">&amp;ખસેડવું ફરી કરો</translation>
+<translation id="35866233670761917">તમારા વ્યવસ્થાપકો તમે જે વેબસાઇટની મુલાકાત લો તેનું કન્ટેન્ટ જોઈ શકતા નથી</translation>
<translation id="3586931643579894722">વિગતો છુપાવો</translation>
+<translation id="3592413004129370115">ઇટાલિયન (એન્વલપ)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">કદ 2</translation>
<translation id="3615877443314183785">એક માન્ય સમાપ્તિ તારીખ દાખલ કરો</translation>
<translation id="36224234498066874">બ્રાઉઝિંગ ડેટા સાફ કરો...</translation>
<translation id="362276910939193118">પૂર્ણ ઇતિહાસ બતાવો</translation>
-<translation id="3623476034248543066">કિંમત બતાવો</translation>
<translation id="3630155396527302611">જો તે પહેલાંથી જ નેટવર્ક ઍક્સેસ કરવા માટે મંજૂર પ્રોગ્રામ તરીકે સૂચિબદ્ધ હોય, તો
તેને સૂચિમાંથી દૂર કરી અને તેને ફરીથી ઉમેરવાનો પ્રયાસ કરો.</translation>
+<translation id="3640766068866876100">અનુક્રમણિકા-4x6-Ext</translation>
<translation id="3650584904733503804">માન્યતા સફળ</translation>
<translation id="3655670868607891010">જો તમે આ વારંવાર જોઈ રહ્યાં છો, તો આ <ph name="HELP_LINK" /> અજમાવી જુઓ.</translation>
<translation id="3658742229777143148">પુનરાવર્તન</translation>
<translation id="366077651725703012">ક્રેડિટ કાર્ડ અપડેટ કરો</translation>
<translation id="3676592649209844519">ડિવાઇસ ID:</translation>
+<translation id="3677008721441257057">શું તમારો અર્થ &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; હતો?</translation>
<translation id="3678029195006412963">વિનંતી પર સહી કરી શક્યાં નથી</translation>
<translation id="3678529606614285348">એક નવી છુપી વિંડોમાં પેજ ખોલો (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" /> એ ક્રૅશ રિપોર્ટ કૅપ્ચર કરી અને <ph name="UPLOAD_TIME" /> એ અપલોડ કર્યો હતો</translation>
@@ -450,13 +504,14 @@
<translation id="3704162925118123524">તમે ઉપયોગમાં લઈ રહ્યાં છો તે નેટવર્ક માટે, તમારે તેના લોગિન પૃષ્ઠની મુલાકાત લેવાની જરૂર હોઈ શકે છે.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">લોડ કરી રહ્યું છે...</translation>
+<translation id="3709599264800900598">તમે કૉપિ કરેલી ટેક્સ્ટ</translation>
<translation id="3712624925041724820">લાઇસેંસીસ પૂર્ણ</translation>
<translation id="3714780639079136834">મોબાઇલ ડેટા અથવા વાઇ-ફાઇ ચાલુ કરીને</translation>
<translation id="3715597595485130451">વાઇ-ફાઇથી કનેક્ટ કરો</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />પ્રૉક્સી, ફાયરવૉલ અને DNS ગોઠવણી ચેક કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></translation>
<translation id="372429172604983730">જે ઍપ્લિકેશનોને કારણે આ ભૂલ થઈ શકે છે તેમાં ઍન્ટિવાયરસ, ફાયરવૉલ અને વેબ-ફિલ્ટરિંગ અથવા પ્રૉક્સી સૉફ્ટવેરનો સમાવેશ થાય છે.</translation>
+<translation id="373042150751172459">B4 (એન્વલપ)</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="3745099705178523657">તમે કન્ફર્મ કરી લો, પછી આ સાઇટ સાથે તમારા Google એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</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>
@@ -469,10 +524,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> માં સમાપ્ત થાય છે</translation>
<translation id="3789155188480882154">કદ 16</translation>
+<translation id="3797522431967816232">Prc3 (એન્વલપ)</translation>
<translation id="3807873520724684969">નુકસાનકારક કન્ટેન્ટ બ્લૉક કર્યું.</translation>
<translation id="3810973564298564668">મેનેજ કરો</translation>
<translation id="382518646247711829">જો તમે કોઈ પ્રૉક્સી સર્વરનો ઉપયોગ કરો છો...</translation>
<translation id="3828924085048779000">ખાલી પાસફ્રેઝને અનુમતિ નથી. </translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" />એ વધારાના કાર્યો માટે એક્સ્ટેંશન ઇન્સ્ટૉલ કર્યા છે. એક્સ્ટેંશન પાસે તમારા કેટલાક ડેટાનો ઍક્સેસ છે.</translation>
<translation id="385051799172605136">પાછળ</translation>
<translation id="3858027520442213535">તારીખ અને સમય અપડેટ કરો</translation>
<translation id="3884278016824448484">વિરોધાભાસી ઉપકરણ ઓળખકર્તા</translation>
@@ -480,6 +537,7 @@
<translation id="3886446263141354045">આ સાઇટને ઍક્સેસ કરવાની તમારી વિનંતી <ph name="NAME" /> ને મોકલવામાં આવી છે</translation>
<translation id="3890664840433101773">ઇમેઇલ ઉમેરો</translation>
<translation id="3901925938762663762">કાર્ડની સમયસીમા સમાપ્ત થઇ ગઈ છે</translation>
+<translation id="3906600011954732550">B5-અતિરિક્ત</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">આ સાઇટ પર હંમેશાં પૂછો</translation>
<translation id="3949571496842715403">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર વિષય વૈકલ્પિક નામનો ઉલ્લેખ કરતું નથી. આ કોઈ ખોટી ગોઠવણીને કારણે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવતો હોવાને કારણે બન્યું હોઈ શકે.</translation>
@@ -490,11 +548,13 @@
<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="3984550557525787191">આ સત્રનું નામ પહેલેથી અસ્તિત્વમાં છે.</translation>
<translation id="3987940399970879459">1 MB કરતાં ઓછું</translation>
+<translation id="4008849406247176967">ચેતવણી: આ પૉલિસી માટે વિરોધાભાસ મૂલ્ય ધરાવતા એકથી વધુ સૉર્સ ઉપલબ્ધ છે!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{નજીકમાં 1 વેબ પેજ}one{નજીકમાં # વેબ પેજ}other{નજીકમાં # વેબ પેજ}}</translation>
<translation id="4030383055268325496">&amp;ઉમેરવું પૂર્વવત્ કરો</translation>
+<translation id="4032320456957708163">તમારું બ્રાઉઝર <ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે</translation>
<translation id="4058922952496707368">કી "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (એન્વલપ)</translation>
<translation id="4067947977115446013">માન્ય સરનામું ઉમેરો</translation>
<translation id="4072486802667267160">તમારા ઑર્ડરની પ્રક્રિયા કરતી વખતે એક ભૂલ આવી હતી. કૃપા કરીને ફરીથી પ્રયાસ કરો.</translation>
<translation id="4075732493274867456">ક્લાઇન્ટ અને સર્વર સામાન્ય SSL પ્રોટોકોલ વર્ઝન અથવા સાઇફર સ્યૂટની સહાય કરતા નથી.</translation>
@@ -514,10 +574,12 @@
<translation id="4159784952369912983">જાંબલી</translation>
<translation id="4165986682804962316">સાઇટ સેટિંગ્સ</translation>
<translation id="4171400957073367226">ખોટી ચકાસણી સહી</translation>
+<translation id="4173315687471669144">ફૂલ્સ્કૅપ</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{વધુ <ph name="ITEM_COUNT" /> આઇટમ}one{વધુ <ph name="ITEM_COUNT" /> આઇટમ}other{વધુ <ph name="ITEM_COUNT" /> આઇટમ}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ખસેડવું ફરી કરો</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ફાયરવોલ અને એન્ટીવાઇરસ ગોઠવણી તપાસીને<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (એન્વલપ)</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="4221630205957821124">&lt;h4&gt;પગલું 1: પોર્ટલમાં સાઇન ઇન કરો&lt;/h4&gt;
@@ -549,58 +611,79 @@
<translation id="4277028893293644418">પાસવર્ડ રીસેટ કરો</translation>
<translation id="4280429058323657511">, સમાપ્તિ તારીખ <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{આ કાર્ડને તમારા Google એકાઉન્ટમાં સાચવવામાં આવ્યું છે}one{આ કાર્ડને Google એકાઉન્ટમાં સાચવવામાં આવ્યાં છે}other{આ કાર્ડને Google એકાઉન્ટમાં સાચવવામાં આવ્યાં છે}}</translation>
+<translation id="42981349822642051">વિસ્તૃત કરો</translation>
+<translation id="4302965934281694568">Chou3 (એન્વલપ)</translation>
<translation id="4305817255990598646">સ્વિચ</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">અવરોધિત કરો (ડિફૉલ્ટ)</translation>
+<translation id="4318566738941496689">તમારા ડિવાઇસનું નામ અને નેટવર્ક ઍડ્રેસ</translation>
<translation id="4325863107915753736">લેખ શોધવામાં નિષ્ફળ થયાં</translation>
<translation id="4326324639298822553">તમારી સમાપ્તિ તારીખ તપાસો અને ફરી પ્રયાસ કરો</translation>
<translation id="4331708818696583467">સુરક્ષિત નથી</translation>
<translation id="4340982228985273705">આ કમ્પ્યુટર એન્ટરપ્રાઇઝ દ્વારા મેનેજ થતું હોય તેવું જણાયું નથી, તેથી નીતિ માત્ર Chrome Webstore પર હોસ્ટ થયેલા એક્સ્ટેન્શનો આપમેળે ઇન્સ્ટૉલ કરી શકશે. Chrome Webstore અપડેટનું URL "<ph name="CWS_UPDATE_URL" />" છે.</translation>
<translation id="4346197816712207223">સ્વીકૃત ક્રેડિટ કાર્ડ</translation>
+<translation id="4346833872170306413">રૉક-16K</translation>
<translation id="4356973930735388585">આ સાઇટ પરના હુમલાખોરો તમારા કમ્પ્યુટર પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટો, પાસવર્ડ, સંદેશા અને ક્રેડિટ કાર્ડ)ને ચોરી શકે કે કાઢી નાખે એવા જોખમી પ્રોગ્રામને ઇન્સ્ટૉલ કરવાનો પ્રયાસ કરી શકે છે.</translation>
<translation id="4358461427845829800">ચુકવણી પદ્ધતિઓ મેનેજ કરો…</translation>
+<translation id="4367563149485757821">નંબર-12 (એન્વલપ)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">અપેક્ષિત <ph name="VALUE_TYPE" /> મૂલ્ય.</translation>
<translation id="4377125064752653719">તમે <ph name="DOMAIN" /> પર પહોંચવાનો પ્રયાસ કર્યો, પણ સર્વર દ્વારા પ્રસ્તુત કરવામાં આવેલું પ્રમાણપત્ર તેના રજૂકર્તા દ્વારા જ રદ કરવામાં આવ્યું છે. આનો અર્થ છે કે સર્વરે પ્રસ્તુત કરેલા સુરક્ષા પ્રમાણપત્રો પૂર્ણપણે વિશ્વસનીય નથી. તમે કોઈ હુમલાખોર જોડે વાત કરતા હોઈ શકો છો.</translation>
<translation id="4378154925671717803">ફોન</translation>
<translation id="4406896451731180161">શોધ પરિણામો</translation>
-<translation id="4406972042435603828">તમારા વ્યવસ્થાપકોએ શક્તિશાળી ક્ષમતાઓવાળા એક્સ્ટેન્શન ઇન્સ્ટૉલ કર્યા છે.</translation>
<translation id="4408413947728134509">કુકી <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">પિકઅપ માટેનું સરનામું</translation>
<translation id="4424024547088906515">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર Chrome દ્વારા વિશ્વસનીય નથી. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
+<translation id="443121186588148776">સિરીઅલ પોર્ટ</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> એ તમારું લોગિન પ્રમાણપત્ર સ્વીકાર્યું ન હતું અથવા કદાચ કોઈ એક પ્રદાન કરવામાં આવ્યું નથી.</translation>
<translation id="4434045419905280838">પૉપ-અપ અને રીડાયરેક્ટ</translation>
+<translation id="4435702339979719576">પોસ્ટકાર્ડ)</translation>
<translation id="443673843213245140">પ્રૉક્સીનો ઉપયોગ બંધ કરેલો છે પણ એક સ્પષ્ટ પ્રૉક્સી ગોઠવણીનો ઉલ્લેખ કરેલો છે.</translation>
<translation id="445100540951337728">સ્વીકૃત ડેબિટ કાર્ડ</translation>
+<translation id="4466881336512663640">ફોર્મના ફેરફારો ગુમાવશો. શું તમે ખરેખર ચાલુ રાખવા માગો છો?</translation>
<translation id="4482953324121162758">આ સાઇટનો અનુવાદ થશે નહીં.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">અમાન્ય URL. કોઈ માનક સ્કીમ ધરાવતું URL હોવું આવશ્યક છે, દા.ત. http://example.com અથવા https://example.com.</translation>
+<translation id="4503882053543859973">સ્થાપત્ય-D</translation>
<translation id="4506176782989081258">માન્યતા ભૂલ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">સિસ્ટમ વ્યવસ્થાપકનો સંપર્ક કરીને</translation>
<translation id="450710068430902550">વ્યવસ્થાપક સાથે શેર કરવું</translation>
+<translation id="4510487217173779431">Chou4 (એન્વલપ)</translation>
<translation id="4515275063822566619">કાર્ડ અને સરનામા Chrome અને Google એકાઉન્ટ (<ph name="ACCOUNT_EMAIL" />)માંથી છે. તમે તેને <ph name="BEGIN_LINK" />સેટિંગ<ph name="END_LINK" />માં જઈને મેનેજ કરી શકો છો.</translation>
+<translation id="4517607026994743406">Comm-10 (એન્વલપ)</translation>
<translation id="4522570452068850558">વિગતો</translation>
<translation id="4524805452350978254">કાર્ડ મેનેજ કરો</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ફ્લેશ</translation>
<translation id="4558551763791394412">તમારા એક્સ્ટેન્શન્સને અક્ષમ કરવાનો પ્રયાસ કરો.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">વિતરણ</translation>
+<translation id="4579056131138995126">વ્યક્તિગત (એન્વલપ)</translation>
<translation id="4582204425268416675">કાર્ડ કાઢી નાખો</translation>
<translation id="4587425331216688090">Chrome માંથી સરનામું દૂર કરીએ?</translation>
<translation id="4592951414987517459">આધુનિક સાઇફર સ્યૂટનો ઉપયોગ કરીને <ph name="DOMAIN" /> સાથેનું તમારું કનેક્શન એન્ક્રિપ્ટ કરાયું છે.</translation>
<translation id="4594403342090139922">&amp;ડિલીટ રદ કરો</translation>
<translation id="4597348597567598915">કદ 8</translation>
+<translation id="4600854749408232102">C6/C5 (એન્વલપ)</translation>
<translation id="4646534391647090355">મને હવે ડાઉનલોડ હોમ પર લઈ જાઓ</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેના સુરક્ષા પ્રમાણપત્રમાં ભૂલો છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
<translation id="467809019005607715">Google સ્લાઇડ</translation>
<translation id="4690462567478992370">અમાન્ય પ્રમાણપત્રનો ઉપયોગ કરવાનું બંધ કરો</translation>
+<translation id="4691835149146451662">સ્થાપત્ય-A (એન્વલપ)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">તમારું કનેક્શન અવરોધાયું હતું</translation>
<translation id="471880041731876836">તમારી પાસે આ સાઇટની મુલાકાત લેવાની પરવાનગી નથી</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows નેટવર્ક ડાયગ્નોસ્ટિક્સ ચલાવી રહ્યાં છે<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">નીતિઓ ફરીથી લોડ કરો</translation>
<translation id="4728558894243024398">પ્લેટફોર્મ</translation>
+<translation id="4731967714531604179">Prc2 (એન્વલપ)</translation>
<translation id="4736825316280949806">Chromium ને પુનઃપ્રારંભ કરો</translation>
<translation id="473775607612524610">અપડેટ કરો</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> શોધ સૂચન</translation>
<translation id="4742407542027196863">પાસવર્ડ મેનેજ કરો…</translation>
<translation id="4744603770635761495">અમલ કરવાયોગ્ય પાથ</translation>
+<translation id="4746351372139058112">સંદેશા</translation>
<translation id="4750917950439032686">તમારી માહિતી (ઉદાહરણ તરીકે, પાસવર્ડ્સ અથવા ક્રેડિટ કાર્ડ નંબર્સ) ખાનગી હોય છે જ્યારે તે આ સાઇટ પર મોકલવામાં આવે.</translation>
<translation id="4756388243121344051">&amp;ઇતિહાસ</translation>
<translation id="4758311279753947758">સંપર્ક માહિતી ઉમેરો</translation>
@@ -608,9 +691,9 @@
<translation id="4764776831041365478"><ph name="URL" /> પરનાં વેબપેજ અસ્થાયી ધોરણે બંધ હોઈ શકે છે અથવા તે કાયમ માટે નવા વેબ ઍડ્રેસ પર ખસેડવામાં આવ્યા હોઈ શકે છે.</translation>
<translation id="4771973620359291008">કોઈ અજ્ઞાત ભૂલ આવી.</translation>
<translation id="4785689107224900852">આ ટૅબ પર સ્વિચ કરો</translation>
-<translation id="4792143361752574037">સત્ર ફાઇલોને ઍક્સેસ કરવામાં સમસ્યા હતી. ડિસ્કમાં સાચવવાનું અત્યારે બંધ કરેલું છે. ફરીથી પ્રયાસ કરવા માટે, કૃપા કરીને પેજને ફરીથી લોડ કરો.</translation>
<translation id="4798078619018708837">તમારા કાર્ડની વિગતો અપડેટ કરવા <ph name="CREDIT_CARD" />ની સમાપ્તિ તારીખ અને CVC દાખલ કરો. તમે ખાતરી કરી લો, પછી આ સાઇટ સાથે તમારા Google એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</translation>
<translation id="4800132727771399293">તમારી સમાપ્તિ તારીખ અને CVC તપાસો અને ફરીથી પ્રયાસ કરો</translation>
+<translation id="480334179571489655">ઑરિજિન પૉલિસી ભૂલ</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>
@@ -625,7 +708,6 @@
<translation id="4881695831933465202">ખોલો</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>
@@ -634,15 +716,15 @@
<translation id="4943872375798546930">પરિણામો નથી</translation>
<translation id="4950898438188848926">ટૅબ, સ્વિચ બટન, ખુલ્લા ટૅબ, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> પર સ્વિચ કરવા માટે Enter દબાવો</translation>
<translation id="495170559598752135">ક્રિયાઓ</translation>
-<translation id="495832697253704892">એક્સ્ટેન્શનની જાણ કરવી</translation>
+<translation id="4955242332710481440">A5-અતિરિક્ત</translation>
<translation id="4958444002117714549">સૂચિ વિસ્તૃત કરો</translation>
<translation id="4974590756084640048">ચેતવણીઓ ફરીથી ચાલુ કરો</translation>
+<translation id="4984339528288761049">Prc5 (એન્વલપ)</translation>
<translation id="4989163558385430922">બધા જુઓ</translation>
<translation id="4989809363548539747">આ પ્લગ-ઇન સમર્થિત નથી</translation>
-<translation id="4996230189582812866">જાણ કરવી</translation>
<translation id="5002932099480077015">જો સક્ષમ કરેલું હોય, તો ઝડપથી ફોર્મ ભરવા માટે Chrome આ ઉપકરણ પર તમારા કાર્ડની એક કૉપિ સંગ્રહશે.</translation>
-<translation id="5014174725590676422">Chromeમાં Google આસિસ્ટંટની પહેલી સ્ક્રીન બતાવવામાં આવી છે</translation>
<translation id="5015510746216210676">મશીનનું નામ:</translation>
+<translation id="5017554619425969104">તમે કૉપિ કરેલી ટેક્સ્ટ</translation>
<translation id="5018422839182700155">આ પૃષ્ઠ ખોલી શકતાં નથી</translation>
<translation id="5019198164206649151">બેકઅપ સ્ટોર કરવું ખરાબ સ્થિતિમાં છે</translation>
<translation id="5023310440958281426">તમારા વ્યવસ્થાપકની નીતિઓ તપાસો</translation>
@@ -652,35 +734,51 @@
<translation id="5034369478845443529">સ્થાનિક સંદર્ભ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">મંજૂરી આપો</translation>
<translation id="5040262127954254034">ગોપનીયતા</translation>
+<translation id="5043480802608081735">તમે કૉપિ કરેલી લિંક</translation>
<translation id="5045550434625856497">ખોટો પાસવર્ડ</translation>
<translation id="5056549851600133418">તમારા માટે લેખ</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />પ્રૉક્સી ઍડ્રેસ ચેક કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM વપરાશ જેવા ડિવાઇસ આંકડા</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">તમારું ડિવાઇસ <ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે અને તમારું એકાઉન્ટ <ph name="ACCOUNT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે. આનો અર્થ છે કે તમારા વ્યવસ્થાપકો રિમોટલી તમારા ડિવાઇસને અને એકાઉન્ટને ગોઠવી શકે છે.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">યુરોપિયન-Edp</translation>
<translation id="5115563688576182185">(64-બિટ)</translation>
-<translation id="5128122789703661928">આ નામવાળું સત્ર ડિલીટ કરવા માટે માન્ય નથી.</translation>
+<translation id="5125394840236832993">B-પ્લસ</translation>
<translation id="5135404736266831032">સરનામા મેનેજ કરો…</translation>
+<translation id="5138227688689900538">ઓછું બતાવો</translation>
<translation id="5141240743006678641">તમારા Google લૉગ ઇન વિગત સાથે સિંક પાસવર્ડને એન્ક્રિપ્ટ કરો</translation>
<translation id="5145883236150621069">નીતિ પ્રતિક્રિયામાં ભૂલ કોડ હાજર</translation>
+<translation id="515292512908731282">C4 (એન્વલપ)</translation>
<translation id="5159010409087891077">એક નવી છુપી વિંડોમાં પેજ ખોલો (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> માટે CVC દાખલ કરો. તમે ખાતરી કરી લો, પછી આ સાઇટ સાથે તમારા Google એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</translation>
<translation id="5169827969064885044">તમે તમારી સંસ્થાના એકાઉન્ટ માટે ઍક્સેસ ગુમાવી શકો છો અથવા તમને ઓળખ ચોરીનો અનુભવ થઈ શકે છે. Chrome તમને હમણાં જ તમારો પાસવર્ડ બદલવાની ભલામણ કરે છે.</translation>
<translation id="5171045022955879922">URL શોધો અથવા લખો</translation>
+<translation id="5171689220826475070">Fanfold-યુરોપિયન</translation>
<translation id="5172758083709347301">મશીન</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> માં નથી? આ ભૂલની જાણ કરો </translation>
<translation id="5190835502935405962">બુકમાર્ક્સ બાર</translation>
-<translation id="5200263511887412697">તાજેતરમાં લૉગ ઇન કરેલા ડિવાઇસ વપરાશકર્તાઓની રિપોર્ટ સૂચિ</translation>
+<translation id="519422657042045905">ટીકાટિપ્પણી ઉપલબ્ધ નથી</translation>
<translation id="5201306358585911203">આ પેજ પરનું શામેલ કરેલ પેજ કહે છે કે</translation>
<translation id="5205222826937269299">નામ આવશ્યક છે</translation>
<translation id="5215116848420601511">Google Payનો ઉપયોગ કરતી ચુકવણી પદ્ધતિઓ અને ઍડ્રેસ</translation>
+<translation id="5215363486134917902">ફોલિયો-Sp</translation>
<translation id="5222812217790122047">ઇમેઇલ આવશ્યક છે</translation>
<translation id="5230733896359313003">વિતરણ માટેનું સરનામું</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"નેટવર્ક સાથે કનેક્ટ કરો"</translation>
<translation id="5251803541071282808">મેઘ</translation>
+<translation id="5252000469029418751">C7 (એન્વલપ)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">નેટવર્ક ઍડ્રેસ</translation>
<translation id="5285570108065881030">બધા સાચવેલા પાસવર્ડ બતાવો</translation>
<translation id="5287240709317226393">કુકી બતાવો</translation>
<translation id="5288108484102287882">નીતિ મૂલ્યોની માન્યતા ચેતવણીઓનું કારણ બની છે</translation>
@@ -692,7 +790,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> માંથી <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">સંપર્કની માહિતી પસંદ કરો</translation>
<translation id="5327248766486351172">નામ</translation>
+<translation id="5329858041417644019">તમારું બ્રાઉઝર મેનેજ કરેલું નથી</translation>
<translation id="5332219387342487447">શિપિંગ પદ્ધતિ</translation>
+<translation id="5334013548165032829">વિગતવાર સિસ્ટમ લૉગ</translation>
<translation id="5344579389779391559">આ પેજ કદાચ તમારી પાસેથી શુલ્ક વસૂલ કરવાનો પ્રયાસ કરી શકે છે</translation>
<translation id="5355557959165512791">તમે અત્યારે <ph name="SITE" />ની મુલાકાત લઈ શકતાં નથી કારણ કે તેનું પ્રમાણપત્ર રદબાતલ કરવામાં આવ્યું છે. નેટવર્કમાં ભૂલ આવવી અને હુમલા થવા સામાન્ય રીતે અસ્થાયી હોય છે, તેથી આ પેજ સંભવિત રૂપે થોડા સમય પછી કાર્ય કરશે.</translation>
<translation id="536296301121032821">નીતિ સેટિંગ્સ સ્ટોર કરવામાં નિષ્ફળ થયાં</translation>
@@ -700,6 +800,7 @@
<translation id="5377026284221673050">"તમારી ઘડિયાળ પાછળ છે" અથવા "તમારી ઘડિયાળ આગળ છે" અથવા "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">બધા ડિવાઇસ પર તમારા કાર્ડનો ઉપયોગ કરવા માટે, સાઇન ઇન કરો અને સિંક ચાલુ કરો.</translation>
<translation id="5386426401304769735">આ સાઇટ માટેની પ્રમાણપત્ર શ્રૃંખલા SHA-1 નો ઉપયોગ કરીને સહી કરેલ પ્રમાણપત્ર ધરાવે છે.</translation>
+<translation id="538659543871111977">A4-ટૅબ</translation>
<translation id="540969355065856584">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર આ સમયે માન્ય નથી. આ કોઇ ખોટી ગોઠવણીને કારણે થયું હોય અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો હોઇ શકે છે.</translation>
<translation id="5421136146218899937">બ્રાઉઝિંગ ડેટા સાફ કરો...</translation>
<translation id="5430298929874300616">બુકમાર્ક દૂર કરો</translation>
@@ -710,6 +811,7 @@
<translation id="5457113250005438886">અમાન્ય</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;ફરી ફેરફાર કરો</translation>
+<translation id="5478437291406423475">B6/C4 (એન્વલપ)</translation>
<translation id="5481076368049295676">આ કન્ટેન્ટ કદાચ તમારા ડિવાઇસ પર જોખમકારક સૉફ્ટવેર ઇન્સ્ટૉલ કરવાનો પ્રયાસ કરી શકે છે કે જે તમારી માહિતીની ચોરી કરે અથવા કાઢી નાખે છે. <ph name="BEGIN_LINK" />છતાં પણ બતાવો<ph name="END_LINK" /></translation>
<translation id="54817484435770891">માન્ય સરનામું ઉમેરો</translation>
<translation id="5490432419156082418">સરનામા અને વધુ</translation>
@@ -717,10 +819,12 @@
<ph name="LINE_BREAK" />
તમારા સિસ્ટમ વ્યવસ્થાપકનો સંપર્ક કરવાનો પ્રયાસ કરો.</translation>
<translation id="549333378215107354">કદ 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">સંચાલિત બુકમાર્ક્સ</translation>
<translation id="5510766032865166053">તે કદાચ ખસેડવામાં કે કાઢી નાખવામાં આવી છે</translation>
<translation id="5523118979700054094">નીતિનું નામ</translation>
<translation id="552553974213252141">શું ટેક્સ્ટ ઠીકથી કાઢી હતી?</translation>
+<translation id="553484882784876924">Prc6 (એન્વલપ)</translation>
<translation id="5540224163453853">વિનંતી કરેલ લેખ શોધી શકાયો નથી.</translation>
<translation id="5541546772353173584">ઇમેઇલ ઍડ્રેસ ઉમેરો</translation>
<translation id="5545756402275714221">તમારા માટે લેખ</translation>
@@ -735,15 +839,21 @@
<translation id="5595485650161345191">ઍડ્રેસમાં ફેરફાર કરો</translation>
<translation id="5598944008576757369">ચુકવણીની પદ્ધતિ પસંદ કરો</translation>
<translation id="560412284261940334">સંચાલન સમર્થિત નથી</translation>
+<translation id="5605670050355397069">લેજર</translation>
+<translation id="5607240918979444548">સ્થાપત્ય-C</translation>
<translation id="5610142619324316209">કનેક્શન તપાસીને</translation>
<translation id="5610807607761827392">તમે <ph name="BEGIN_LINK" />સેટિંગ્સ<ph name="END_LINK" />માં કાર્ડ્સ અને સરનામાં સંચાલિત કરી શકો છો.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> એ તમને ઘણીબધી વખત રીડાયરેક્ટ કર્યું.</translation>
<translation id="5629630648637658800">નીતિ સેટિંગ્સ લોડ કરવામાં નિષ્ફળ થયાં</translation>
<translation id="5631439013527180824">અમાન્ય ડિવાઇસ સંચાલન ટોકન</translation>
+<translation id="5632627355679805402">તમારો ડેટા <ph name="TIME" />ના રોજ તમારા <ph name="BEGIN_LINK" />Google પાસવર્ડ<ph name="END_LINK" /> સાથે એન્ક્રિપ્ટ કરવામાં આવ્યો હતો. સિંક શરૂ કરવા માટે તે દાખલ કરો.</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="563324245173044180">ભ્રામક કન્ટેન્ટ બ્લૉક કરી</translation>
<translation id="5659593005791499971">ઇમેઇલ</translation>
+<translation id="5663614846592581799">9x11 (એન્વલપ)</translation>
+<translation id="5663955426505430495">આ ડિવાઇસના વ્યવસ્થાપકે વધારાના કાર્યો માટે એક્સ્ટેંશન ઇન્સ્ટૉલ કર્યા છે. એક્સ્ટેંશન પાસે તમારા કેટલાક ડેટાનો ઍક્સેસ છે.</translation>
<translation id="5675650730144413517">આ પૃષ્ઠ કામ કરી રહ્યું નથી</translation>
+<translation id="5684874026226664614">અરેરે. આ પૃષ્ઠનો અનુવાદ કરી શકાયો નથી.</translation>
<translation id="5685654322157854305">વિતરણ માટેનું સરનામું ઉમેરો</translation>
<translation id="5689199277474810259">JSON પર નિકાસ કરો</translation>
<translation id="5689516760719285838">સ્થાન</translation>
@@ -752,38 +862,39 @@
<translation id="5710435578057952990">આ વેબસાઇટની ઓળખ ચકાસવામાં આવી નથી.</translation>
<translation id="5719499550583120431">પ્રીપેઇડ કાર્ડ સ્વીકારવામાં આવે છે.</translation>
<translation id="5720705177508910913">વર્તમાન વપરાશકર્તા</translation>
+<translation id="5728056243719941842">C5 (એન્વલપ)</translation>
<translation id="5730040223043577876">જો તમે અન્ય સાઇટ પર તમારા પાસવર્ડનો ફરી ઉપયોગ કર્યો હોય, તો Chrome તેને રીસેટ કરવાનો સુઝાવ આપે છે.</translation>
<translation id="5732392974455271431">તમારા માટે તમારા માતાપિતા તેને અનાવરોધિત કરી શકે છે</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{તમારા Google એકાઉન્ટમાં કાર્ડ સાચવો}one{તમારા Google એકાઉન્ટમાં કાર્ડ સાચવો}other{તમારા Google એકાઉન્ટમાં કાર્ડ સાચવો}}</translation>
<translation id="5763042198335101085">એક માન્ય ઇમેઇલ ઍડ્રેસ ઉમેરો</translation>
<translation id="5765072501007116331">વિતરણ પદ્ધતિઓ અને આવશ્યકતાઓ જોવા માટે, એક સરનામું પસંદ કરો</translation>
-<translation id="5770114862687765385">ફાઇલ ખામીવાળી લાગે છે. સત્રને રીસેટ કરવા માટે 'રીસેટ કરો' બટન પર ક્લિક કરો.</translation>
<translation id="5778550464785688721">MIDI ઉપકરણોનું પૂર્ણ નિયંત્રણ</translation>
<translation id="578305955206182703">પીળાશ પડતો નારંગી</translation>
<translation id="57838592816432529">અવાજ બંધ કરો</translation>
<translation id="5784606427469807560">તમારા કાર્ડની પુષ્ટિ કરવામાં એક સમસ્યા આવી હતી. તમારું ઇન્ટરનેટ કનેક્શન તપાસો અને ફરીથી પ્રયાસ કરો.</translation>
<translation id="5785756445106461925">વળી, આ પૃષ્ઠમાં અન્ય એવા સાધનો છે જે સુરક્ષિત નથી. ટ્રાંઝિટમાં હોવા પર અન્ય લોકો દ્વારા આ સાધનો જોઈ શકાય છે અને પૃષ્ઠનો દેખાવ બદલવા માટે હુમલાખોર દ્વારા સંશોધિત કરવામાં આવી શકે છે.</translation>
<translation id="5786044859038896871">શું તમે તમારી કાર્ડ માહિતી ભરવા માગો છો?</translation>
+<translation id="5798290721819630480">ફેરફારો કાઢી નાખીએ?</translation>
<translation id="5798683403665926540">Chrome સેટિંગમાં હોમ પેજ બદલો</translation>
<translation id="5803412860119678065">શું તમે તમારી <ph name="CARD_DETAIL" /> માહિતી ભરવા માગો છો?</translation>
<translation id="5804241973901381774">પરવાનગીઓ</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" /> સાથેના તમારા કનેક્શનને ઑબ્સોલિટ સાઇફર સ્યૂટનો ઉપયોગ કરીને એન્ક્રિપ્ટ કરાયું છે.</translation>
<translation id="5813119285467412249">&amp;ઉમેરવું ફરી કરો</translation>
<translation id="5838278095973806738">તમારે આ સાઇટ પર કોઈપણ સંવેદનશીલ માહિતી (ઉદાહરણ તરીકે, પાસવર્ડ્સ અથવા ક્રેડિટ કાર્ડ્સ) દાખલ કરવી જોઈએ નહીં, કારણ કે તે હુમલાખોર દ્વારા ચોરવામાં આવી શકે છે.</translation>
+<translation id="5860033963881614850">બંધ</translation>
<translation id="5863847714970149516">આગળનું પેજ તમને શુલ્ક લાગુ કરી શકે છે</translation>
<translation id="5866257070973731571">ફોન નંબર ઉમેરો</translation>
<translation id="5869405914158311789">આ સાઇટ પર પહોંચી શકાતું નથી</translation>
<translation id="5869522115854928033">સાચવેલા પાસવર્ડ્સ</translation>
<translation id="5887400589839399685">કાર્ડ સાચવ્યું</translation>
-<translation id="5893718151540690985">નેટવર્ક ઇન્ટરફેસની સૂચિની તેમના પ્રકાર અને હાર્ડવેર સરનામાં સાથે જાણ કરો</translation>
<translation id="5893752035575986141">ક્રેડિટ કાર્ડ સ્વીકારવામાં આવે છે.</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="5916664084637901428">ચાલુ</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google એકાઉન્ટમાં કાર્ડ સાચવીએ?</translation>
<translation id="5922853866070715753">લગભગ થઈ ગયું</translation>
<translation id="5932224571077948991">સાઇટ ઘૃણાસ્પદ અથવા ભ્રામક જાહેરાતો બતાવે છે</translation>
-<translation id="5939518447894949180">રીસેટ કરો</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> ખોલી રહ્યાં છે…</translation>
<translation id="5951495562196540101">ઉપભોક્તા એકાઉન્ટ સાથે નોંધણી કરાવી શકાતી નથી (પૅકેજમાં લાઇસન્સ ઉપલબ્ધ છે).</translation>
<translation id="5967592137238574583">સંપર્ક માહિતીમાં ફેરફાર કરો</translation>
@@ -791,6 +902,7 @@
<translation id="5975083100439434680">ઝૂમ ઘટાડો</translation>
<translation id="5977489021191000276">તમારું ડિવાઇસ વ્યવસ્થાપક દ્વારા મેનેજ કરવામાં આવતું નથી.</translation>
<translation id="5977976211062815271">આ ડિવાઇસ પર</translation>
+<translation id="5980920751713728343">અનુક્રમણિકા-3x5</translation>
<translation id="598637245381783098">ચુકવણી ઍપ્લિકેશન ખોલી શકાતી નથી</translation>
<translation id="5989320800837274978">ફિક્સ્ડ પ્રૉક્સી સર્વર કે .pac સ્ક્રિપ્ટ URL, બેમાંથી કોઈનો પણ ઉલ્લેખ કરેલો નથી.</translation>
<translation id="5990559369517809815">સર્વર પરની વિનંતિઓને એક્સ્ટેંશન દ્વારા અવરોધિત કરવામાં આવી છે.</translation>
@@ -801,8 +913,8 @@
<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="6033927989869462158">CPU/RAM વપરાશ જેવા હાર્ડવેર આંકડાની જાણ કરો</translation>
<translation id="6034000775414344507">આછો ગ્રે</translation>
+<translation id="6034283069659657473">10x14 (એન્વલપ)</translation>
<translation id="6039846035001940113">જો સમસ્યા ચાલુ રહે, તો સાઇટના માલિકનો સંપર્ક કરો.</translation>
<translation id="6040143037577758943">બંધ કરો</translation>
<translation id="6044573915096792553">કદ 12</translation>
@@ -811,10 +923,10 @@
<translation id="6051221802930200923">તમે અત્યારે આ <ph name="SITE" />ની મુલાકાત લઈ શકતાં નથી કારણ કે આ વેબસાઇટ પ્રમાણપત્ર પિનિંગનો ઉપયોગ કરે છે. નેટવર્કમાં ભૂલ આવવી અને હુમલા થવા સામાન્ય રીતે અસ્થાયી હોય છે, તેથી આ પેજ સંભવિત રૂપે થોડા સમય પછી કાર્ય કરશે.</translation>
<translation id="6058977677006700226">તમારા બધાં ડિવાઇસ પર તમારાં કાર્ડનો ઉપયોગ કરીએ?</translation>
<translation id="6059925163896151826">USB ઉપકરણો</translation>
-<translation id="6071091556643036997">નીતિ પ્રકાર અમાન્ય છે.</translation>
<translation id="6080696365213338172">તમે વ્યવસ્થાપક-પ્રદત્ત પ્રમાણપત્રનો ઉપયોગ કરીને કન્ટેન્ટ ઍક્સેસ કરી છે. તમે <ph name="DOMAIN" /> ને પ્રદાન કરેલ ડેટા તમારા વ્યવસ્થાપક દ્વારા ઇન્ટરસેપ્ટ થઈ શકે છે.</translation>
<translation id="6094273045989040137">એનોટેટ કરો</translation>
<translation id="610911394827799129">તમારા Google એકાઉન્ટમાં <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> પર બ્રાઉઝિંગ ઇતિહાસના બીજા સ્વરૂપો હોય શકે છે</translation>
+<translation id="6132597952260690497">ઇન્સ્ટૉલ કરેલાં એક્સ્ટેંશન અને પ્લગ-ઇન વિશે માહિતી</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{કોઈ નહીં}=1{1 પાસવર્ડ (સિંક કરેલ)}one{# પાસવર્ડ (સિંક કરેલ)}other{# પાસવર્ડ (સિંક કરેલ)}}</translation>
<translation id="6146055958333702838">કોઈપણ કેબલ્સ તપાસો અને તમે કદાચ ઉપયોગમાં લઇ રહ્યાં હોય તેવા કોઇપણ રાઉટર્સ, મૉડેમ્સ 
અથવા અન્ય નેટવર્ક ઉપકરણોને રીબૂટ કરો.</translation>
@@ -849,15 +961,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> કરતાં ઓછી જગ્યા ખાલી કરે છે. તમારી આગલી મુલાકાત સમયે કેટલીક સાઇટ વધુ ધીમે લોડ થઈ શકે છે.</translation>
<translation id="6337534724793800597">નામ દ્વારા નીતિઓને ફિલ્ટર કરો</translation>
<translation id="6358450015545214790">આનો અર્થ શું છે?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">આગળ ઉપર શુલ્ક લાગવાની શક્યતા.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 અન્ય સૂચન}one{# અન્ય સૂચન}other{# અન્ય સૂચન}}</translation>
<translation id="6387754724289022810">આગલી વખતે વધુ ઝડપથી ચુકવણી કરવા માટે, તમારા કાર્ડ અને બિલિંગ સરનામાંને તમારા Google એકાઉન્ટ અને આ ડિવાઇસ પર સાચવો.</translation>
+<translation id="6390662030813198813">એન્જિનિયરિંગ-E</translation>
<translation id="6404511346730675251">બુકમાર્કમાં ફેરફાર કરો</translation>
+<translation id="6406765186087300643">C0 (એન્વલપ)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> માટે સમાપ્તિ તારીખ અને CVC દાખલ કરો</translation>
<translation id="6414888972213066896">આ પૃષ્ઠની મુલાકાત લો છો તે ઠીક છે કે કેમ તેવું તમે તમારા માતાપિતાને પૂછ્યું</translation>
<translation id="6417515091412812850">પ્રમાણપત્ર રદ કરવામાં આવ્યું છે કે નહીં તે તપાસવામાં અક્ષમ છે.</translation>
<translation id="6433490469411711332">સંપર્ક માહિતીમાં ફેરફાર કરો</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> એ કનેક્ટ કરવાનો ઇનકાર કર્યો.</translation>
+<translation id="6434309073475700221">કાઢી નાખો</translation>
+<translation id="6446163441502663861">Kahu (એન્વલપ)</translation>
<translation id="6446608382365791566">વધુ માહિતી ઉમેરો</translation>
<translation id="6447842834002726250">કૂકીઝ</translation>
<translation id="6451458296329894277">ફોર્મનાં ફરી સબમિશનની પુષ્ટિ કરો</translation>
@@ -870,11 +988,17 @@
<translation id="6508722015517270189">Chrome ને પુનઃપ્રારંભ કરો</translation>
<translation id="6529602333819889595">&amp;ફરી કરો ડિલીટ કરો</translation>
<translation id="6534179046333460208">વાસ્તવિક વેબ સૂચનો</translation>
+<translation id="6556866813142980365">ફરી કરો</translation>
<translation id="6563469144985748109">તમારા સંચાલકે હજી સુધી તેને મંજૂર કરેલ નથી</translation>
<translation id="6569060085658103619">તમે એક્સ્ટેન્શન પૃષ્ઠ જોઈ રહ્યાં છો</translation>
+<translation id="6578796323535178455">C2 (એન્વલપ)</translation>
<translation id="6579990219486187401">આછો ગુલાબી</translation>
+<translation id="6583674473685352014">B6 (એન્વલપ)</translation>
+<translation id="6587923378399804057">તમે કૉપિ કરેલી લિંક</translation>
+<translation id="6591833882275308647">તમારું <ph name="DEVICE_TYPE" /> મેનેજ કરવામાં આવતું નથી</translation>
<translation id="6596325263575161958">એન્ક્રિપ્શન વિકલ્પો</translation>
<translation id="6604181099783169992">મોશન અથવા લાઇટ સેન્સર</translation>
+<translation id="6609880536175561541">Prc7 (એન્વલપ)</translation>
<translation id="6624427990725312378">સંપર્ક માહિતી</translation>
<translation id="6626291197371920147">માન્ય કાર્ડ નંબર ઉમેરો</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> શોધ</translation>
@@ -883,6 +1007,7 @@
<translation id="6644283850729428850">આ નીતિ દૂર કરવામાં આવેલી છે.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{કોઈ નહિ}=1{From 1 site (you won't be signed out of your Google Account)}one{From # sites (you won't be signed out of your Google Account)}other{From # sites (you won't be signed out of your Google Account)}}</translation>
<translation id="6657585470893396449">પાસવર્ડ</translation>
+<translation id="6670613747977017428">સુરક્ષા પર પાછા.</translation>
<translation id="6671697161687535275">Chromium માંથી ફોર્મ સૂચન દૂર કરીએ?</translation>
<translation id="6685834062052613830">સાઇન આઉટ કરો અને સેટઅપ પૂર્ણ કરો</translation>
<translation id="6710213216561001401">પાછલી</translation>
@@ -890,12 +1015,15 @@
<translation id="671076103358959139">નોંધણી ટોકન:</translation>
<translation id="6711464428925977395">પ્રૉક્સી સર્વરમાં કંઈક ખોટું થયું છે અથવા તો ઍડ્રેસ ખોટું છે.</translation>
<translation id="6723740634201835758">તમારા Google એકાઉન્ટમાં</translation>
+<translation id="6738516213925468394">તમારો ડેટા <ph name="TIME" />ના રોજ તમારા <ph name="BEGIN_LINK" />સિંક પાસફ્રેઝ<ph name="END_LINK" /> સાથે એન્ક્રિપ્ટ કરવામાં આવ્યો હતો. સિંક શરૂ કરવા માટે એ દાખલ કરો.</translation>
<translation id="674375294223700098">અજ્ઞાત સર્વર પ્રમાણપત્ર ભૂલ.</translation>
<translation id="6744009308914054259">કનેક્શન માટે રાહ જોતી વખતે, ઑફલાઇન લેખ વાંચવા માટે તમે ડાઉનલોડની મુલાકાત લઈ શકો.</translation>
<translation id="6753269504797312559">નીતિ મૂલ્ય</translation>
<translation id="6757797048963528358">તમારું ઉપકરણ નિષ્ક્રિય થઈ ગયું હતું.</translation>
+<translation id="6768213884286397650">Hagaki (પોસ્ટકાર્ડ)</translation>
<translation id="6778737459546443941">તમારા માતાપિતાએ હજી સુધી તેને મંજૂર કરેલ નથી</translation>
<translation id="67862343314499040">જાંબુડિયો</translation>
+<translation id="6786747875388722282">એક્સ્ટેન્શન્સ</translation>
<translation id="679355240208270552">અવગણના કરી, કારણ કે નીતિએ ડિફૉલ્ટ શોધ બંધ કરેલ છે.</translation>
<translation id="681021252041861472">ફરજિયાત</translation>
<translation id="6810899417690483278">કસ્ટમાઇઝેશન ID</translation>
@@ -928,10 +1056,12 @@
<translation id="6965978654500191972">ઉપકરણ</translation>
<translation id="6970216967273061347">જિલ્લો</translation>
<translation id="6973656660372572881">ફિક્સ્ડ પ્રૉક્સી સર્વર અને .pac script URL બન્નેનો ઉલ્લેખ કરેલો છે.</translation>
+<translation id="6973932557599545801">માફ કરશો, હું હવે વધુ સહાય કરી શકીશ નહીં, કૃપા કરીને તમારી રીતે આગળ વધો.</translation>
<translation id="6979158407327259162">Google ડ્રાઇવ</translation>
<translation id="6979440798594660689">મ્યૂટ કરો (ડિફૉલ્ટ)</translation>
<translation id="6984479912851154518">બાહ્ય ઍપ્લિકેશન મારફતે ચુકવણી કરવા માટે ખાનગી મોડ છોડી રહ્યાં છીએ. ચાલુ રાખવું છે?</translation>
<translation id="6989763994942163495">વિગતવાર સેટિંગ્સ બતાવો...</translation>
+<translation id="6993898126790112050">6x9 (એન્વલપ)</translation>
<translation id="6996312675313362352">હંમેશાં <ph name="ORIGINAL_LANGUAGE" />નો અનુવાદ કરો</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">આ શુલ્ક એક-સમયનું અથવા પુનરાવર્તિત હોઈ શકે છે અને કદાચ દેખીતા શુલ્ક ન પણ હોય.</translation>
@@ -947,28 +1077,36 @@
<translation id="7108338896283013870">છુપાવો</translation>
<translation id="7108819624672055576">એક્સટેન્શન દ્વારા મંજૂર</translation>
<translation id="7111012039238467737">(માન્ય)</translation>
+<translation id="7118618213916969306">ક્લિપબોર્ડ URL શોધો, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">અન્ય ટૅબ અથવા પ્રોગ્રામ બંધ કરો</translation>
<translation id="7129409597930077180">આ સરનામે વિતરણ કરી શકાતું નથી. કોઈ ભિન્ન સરનામું પસંદ કરો.</translation>
<translation id="7135130955892390533">સ્ટેટસ બતાવો</translation>
<translation id="7138472120740807366">વિતરણ પદ્ધતિ</translation>
<translation id="7139724024395191329">એમિરેટ</translation>
+<translation id="7152423860607593928">નંબર-14 (એન્વલપ)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">આછો જાંબલી</translation>
-<translation id="7158980942472052083">અમાન્ય URL. તે માનક સ્કીમ સાથેનું URL હોવું જરૂરી છે.</translation>
<translation id="717330890047184534">Gaia ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">તમે જેના પર જવાનો પ્રયાસ કરી રહ્યાં છો, તે<ph name="ORIGIN" /> સર્વર દ્વારા વિનંતી
+ કરવામાં આવી છે કે સુરક્ષા પૉલિસી તેના પરની બધી વિનંતીઓ પર લાગુ થશે. પણ પૉલિસી વિતરિત
+ કરવાને બદલે તેણે બ્રાઉઝરને અન્ય ક્યાંક રીડાયરેક્ટ કર્યુ, જે બ્રાઉઝરને માટેની
+ <ph name="SITE" /> તમારી વિનંતી પૂરી કરવાથી અટકાવે છે.</translation>
<translation id="7179323680825933600">ચુકવણી પદ્ધતિઓ સાચવો અને ભરો</translation>
<translation id="7180611975245234373">રિફ્રેશ કરો</translation>
<translation id="7182878459783632708">કોઈ નીતિઓ સેટ નથી</translation>
<translation id="7186367841673660872">આ પૃષ્ઠનું<ph name="ORIGINAL_LANGUAGE" />માંથી<ph name="LANGUAGE_LANGUAGE" />માં ભાષાંતર કરવામાં આવ્યું છે.</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> ખાલી કરે છે. તમારી આગલી મુલાકાત સમયે કેટલીક સાઇટો વધુ ધીમે લોડ થઈ શકે છે.</translation>
<translation id="719464814642662924">વિઝા</translation>
+<translation id="7201591969684833065">તમારા વ્યવસ્થાપક જોઈ શકે છે:</translation>
+<translation id="7202346780273620635">અક્ષર-અતિરિક્ત</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" />, સુરક્ષા માનકોનું પાલન કરતું નથી.</translation>
<translation id="721197778055552897">આ સમસ્યા વિશે <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">કનેક્શન <ph name="SSL_VERSION" /> નો ઉપયોગ કરે છે.</translation>
<translation id="7220786058474068424">પ્રક્રિયા કરી રહ્યું છે</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">સાઇટ આગળ મૉલવેર ધરાવે છે</translation>
+<translation id="724766306220616965">ચેતવણીઓ, વિરોધાભાસ</translation>
<translation id="724975217298816891">તમારા કાર્ડની વિગતોને અપડેટ કરવા <ph name="CREDIT_CARD" /> માટે સમાપ્તિ તારીખ અને CVC દાખલ કરો. એકવાર તમે ખાતરી કરી લો, તે પછી આ સાઇટ સાથે તમારા કાર્ડની વિગતો શેર કરવામાં આવશે.</translation>
<translation id="7251437084390964440">નેટવર્ક ગોઠવણી ONC માનકનું પાલન કરતી નથી. કદાચ ગોઠવણીના ભાગોને આયાત કરાશે નહીં.
વધારાની વિગતો:
@@ -981,11 +1119,14 @@
<translation id="7300012071106347854">ઘેરો વાદળી</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">ક્રૅશ રિપોર્ટ <ph name="CRASH_TIME" /> એ કૅપ્ચર કરવામાં આવી (વપરાશકર્તા દ્વારા અપલોડની વિનંતી કરવામાં આવી, હજી સુધી અપલોડ કરેલું નથી)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" />ની ચેતવણીઓ</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">કનેક્શન સહાય</translation>
<translation id="7334320624316649418">&amp;પુનઃક્રમાંકિત કરવું ફરી કરો</translation>
<translation id="733923710415886693">પ્રમાણપત્ર પારદર્શિતા દ્વારા સર્વરનું પ્રમાણપત્ર જાહેર કરવામાં આવ્યું ન હતું.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-અતિરિક્ત</translation>
<translation id="7353601530677266744">આદેશ પંક્તિ</translation>
-<translation id="7365061714576910172">Linuxની નિકાસ કરો</translation>
<translation id="7372973238305370288">શોધ પરિણામ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ના</translation>
@@ -993,6 +1134,7 @@
<translation id="7381288752349550461">મેનેજ કરાયેલ સત્ર ઓવરરાઇડ થયું હોય</translation>
<translation id="7390545607259442187">કાર્ડની પુષ્ટિ કરો</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">તમારું <ph name="DEVICE_NAME" /> મેનેજ કરવામાં આવે છે</translation>
<translation id="7407424307057130981">&lt;p&gt;જો તમે તમારા Windows કમ્પ્યુટર પર Superfish સૉફ્ટવેર ધરાવો છો, તો તમને આ ભૂલ દેખાશે.&lt;/p&gt;
&lt;p&gt;તે સૉફ્ટવેરને થોડા સમય માટે બંધ કરવા માટે, આ પગલાં અનુસરો, જેથી તમે વેબ પર પહોંચી શકો. તમારી પાસે એડમિનના ખાસ અધિકારો હોવા જરૂરી છે.&lt;/p&gt;
 &lt;ol&gt;
@@ -1003,7 +1145,7 @@
&lt;li&gt;&lt;strong&gt;લાગુ કરો&lt;/strong&gt; પર ક્લિક કરો, પછી &lt;strong&gt;ઓકે&lt;/strong&gt; પર ક્લિક કરો
&lt;li&gt;તમારા કમ્પ્યુટર પરથી સૉફ્ટવેરને કાયમી ધોરણે કાઢી નાંખવાની રીત જાણવા માટે, &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome સહાયતા કેન્દ્ર&lt;/a&gt; પર જાઓ
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" />મેનેજમેન્ટ</translation>
+<translation id="741007362987735528">પહોળાઈ-ફૉર્મેટ</translation>
<translation id="7416351320495623771">પાસવર્ડ મેનેજ કરો…</translation>
<translation id="7419106976560586862">પ્રોફાઇલ પાથ</translation>
<translation id="7437289804838430631">સંપર્ક માહિતી ઉમેરો</translation>
@@ -1012,22 +1154,24 @@
<translation id="7442725080345379071">આછો નારંગી</translation>
<translation id="7444046173054089907">આ સાઇટ અવરોધિત છે</translation>
<translation id="7445762425076701745">તમે જે સર્વરથી કનેક્ટ છો તેની ઓળખ સંપૂર્ણ રૂપે માન્ય કરી શકાતી નથી. તમે જે નામનો ઉપયોગ કરીને સર્વરથી કનેક્ટ છો, તે ફક્ત તમારા નેટવર્કની અંતર્ગત જ માન્ય છે, જેના બાહ્ય પ્રમાણપત્ર અધિકારીને માલિકીને માન્ય કરવાની કોઈ રીત નથી. આના પર ધ્યાન આપ્યાં વગર કેટલાક પ્રમાણપત્ર અધિકારીઓ આ નામો માટે પ્રમાણપત્ર બહાર પાડશે, તેથી તમે ઇચ્છિત વેબસાઇટથી કનેક્ટ છો કોઈ હુમલાખોરથી નહીં, તેની ખાતરી કરવાની કોઈ રીત નથી.</translation>
-<translation id="7449109375006139765">મેનેજમેન્ટ સર્વર પર સિસ્ટમ લૉગ મોકલવા</translation>
<translation id="7451311239929941790">આ સમસ્યા વિશે <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">વૈશ્વિક ડિફોલ્ટનો ઉપયોગ કરો (અવરોધિત કરો)</translation>
<translation id="7460618730930299168">તમે પસંદ કર્યું તેનાથી સ્ક્રીનિંગ અલગ છે. ચાલુ રાખીએ?</translation>
<translation id="7473891865547856676">નહીં આભાર</translation>
-<translation id="7475525192983021547">જ્યારે વપરાશકર્તા ડિવાઇસ પર સક્રિય હોય તે સમયગાળાઓની જાણ કરો</translation>
<translation id="7481312909269577407">ફોર્વર્ડ કરો</translation>
<translation id="7485870689360869515">કોઈ ડેટા મળ્યો નથી.</translation>
+<translation id="7498234416455752244">ફેરફાર કરવાનું ચાલુ રાખો</translation>
<translation id="7508255263130623398">પરત થયેલ નીતિ ઉપકરણ id ખાલી છે અથવા વર્તમાન ટોકન સાથે મેળ ખાતું નથી</translation>
<translation id="7508870219247277067">જમરૂખ જેવો લીલો</translation>
<translation id="7511955381719512146">તમે ઉપયોગ કરી રહ્યા છો તે વાઇ-ફાઇને <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ની મુલાકાત લેવાની જરૂર પડી શકે છે.</translation>
<translation id="7514365320538308">ડાઉનલોડ કરો</translation>
<translation id="7518003948725431193">વેબ ઍડ્રેસ માટે કોઈ વેબપેજ મળ્યું નથી: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (એન્વલપ)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">આ સાઇટ પરનું તમારું કનેક્શન ખાનગી નથી</translation>
+<translation id="7535087603100972091">મૂલ્ય</translation>
<translation id="7537536606612762813">ફરજિયાત</translation>
+<translation id="7538364083937897561">A2 (એન્વલપ)</translation>
<translation id="7542403920425041731">એકવાર તમે પુષ્ટિ કરી લો તે પછી, આ સાઇટ સાથે તમારા કાર્ડની વિગતો શેર કરવામાં આવશે.</translation>
<translation id="7542995811387359312">આપમેળે ક્રેડિટ કાર્ડ ભરણ અક્ષમ કર્યું છે કારણ કે આ ફોર્મ સુરક્ષિત કનેક્શનનો ઉપયોગ કરતું નથી.</translation>
<translation id="7543525346216957623">તમારા માતા-પિતાને કહો</translation>
@@ -1036,8 +1180,8 @@
<translation id="7552846755917812628">નીચેની ટિપને અજમાવો:</translation>
<translation id="7554791636758816595">નવું ટૅબ</translation>
<translation id="7564049878696755256">તમે તમારા <ph name="ORG_NAME" /> એકાઉન્ટનો ઍક્સેસ ગુમાવી શકો છો અથવા તમને ઓળખ ચોરીનો અનુભવ થઈ શકે છે. Chrome તમને હમણાં જ તમારો પાસવર્ડ બદલવાની ભલામણ કરે છે.</translation>
-<translation id="7566125604157659769">તમે કૉપિ કરેલ ટેક્સ્ટ</translation>
<translation id="7567204685887185387">આ સર્વર સાબિત કરી શક્યું નથી કે તે <ph name="DOMAIN" /> છે; તેનું સુરક્ષા પ્રમાણપત્ર કપટપૂર્વક રજૂ કરવામાં આવેલ હોઈ શકે છે. આ કોઈ ખોટી ગોઠવણીને કારણે થયું હશે અથવા કોઈ હુમલાખોર તમારા કનેક્શનને અટકાવી રહ્યો છે.</translation>
+<translation id="7568105740864181217">આ બ્રાઉઝર એક કંપની, શાળા અથવા અન્ય સંસ્થા દ્વારા મેનેજ કરવામાં આવે છે. તમારા વ્યવસ્થાપક તમારા બ્રાઉઝર સેટઅપને રિમોટલી બદલી શકે છે. આ ડિવાઇસ પરની પ્રવૃત્તિ Chromeની બહારથી પણ મેનેજ કરી શકાય છે. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome માંથી ક્રેડિટ કાર્ડ દૂર કરીએ?</translation>
<translation id="7569983096843329377">શ્યામ</translation>
<translation id="7578104083680115302">તમે Google સાથે સાચવ્યાં છે તે કાર્ડ્સનો ઉપયોગ કરીને સમગ્ર ઉપકરણોમાં સાઇટ્સ અને ઍપ્લિકેશનો પર ઝડપથી ચુકવણી કરો.</translation>
@@ -1048,6 +1192,7 @@
<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="7633909222644580952">કાર્યપ્રદર્શન ડેટા અને ક્રૅશ રિપોર્ટ</translation>
<translation id="7637571805876720304">Chromium માંથી ક્રેડિટ કાર્ડ દૂર કરીએ?</translation>
<translation id="7639968568612851608">ઘાટો ગ્રે</translation>
<translation id="765676359832457558">વિગતવાર સેટિંગ્સ છુપાવો...</translation>
@@ -1057,9 +1202,11 @@
<translation id="7667346355482952095">પરત કરવાની નીતિનું ટોકન ખાલી છે અથવા વર્તમાન ટોકન સાથે મેળ ખાતું નથી</translation>
<translation id="7668654391829183341">અજ્ઞાત ઉપકરણ</translation>
<translation id="7669271284792375604">આ સાઇટ પરના હુમલાખોરો તમને તમારા બ્રાઉઝિંગ અનુભવને નુકસાન પહોંચાડે એવા પ્રોગ્રામ્સ ઇન્સ્ટૉલ કરવા માટે છેતરવાનો પ્રયાસ કરી શકે છે (ઉદાહરણ તરીકે, તમારું હોમપેજ બદલીને અથવા તમે મુલાકાત લો છો તે સાઇટ્સ પર વધુ પડતી જાહેરાતો બતાવીને).</translation>
+<translation id="7676643023259824263">ક્લિપબોર્ડ ટેક્સ્ટમાંથી શોધો, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">સર્ચ એંજિન બદલો</translation>
<translation id="7682287625158474539">શિપિંગ</translation>
<translation id="7687186412095877299">તમારી સાચવેલી ચુકવણી પદ્ધતિઓ વડે ચુકવણી ફૉર્મ ભરે છે</translation>
+<translation id="7697066736081121494">Prc8 (એન્વલપ)</translation>
<translation id="769721561045429135">હમણાં, તમારી પાસે જે કાર્ડ છે તેનો માત્ર આ ડિવાઇસ પર ઉપયોગ કરી શકાય છે. કાર્ડને રિવ્યૂ કરવા માટે 'ચાલુ રાખો' પર ક્લિક કરો.</translation>
<translation id="7699293099605015246">લેખો અત્યારે ઉપલબ્ધ નથી</translation>
<translation id="7701040980221191251">કોઈ નહીં</translation>
@@ -1071,11 +1218,13 @@
<translation id="774634243536837715">જોખમકારક કન્ટેન્ટ બ્લૉક કર્યું.</translation>
<translation id="7752995774971033316">બિનસંચાલિત</translation>
<translation id="7755287808199759310">તમારા માટે તમારા માતાપિતા તેને અનાવરોધિત કરી શકે છે</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ફાયરવોલ અથવા એન્ટિવાયરસ સોફ્ટવેર એ કનેક્શન અવરોધિત કર્યું હોઈ શકે છે.</translation>
<translation id="7759163816903619567">ડોમેન બતાવો:</translation>
<translation id="7761701407923456692">સર્વરનું પ્રમાણપત્ર URL સાથે મેળ ખાતું નથી.</translation>
<translation id="7763386264682878361">ચુકવણી મેનિફેસ્ટ વિશ્લેષક</translation>
<translation id="7764225426217299476">સરનામું ઉમેરો</translation>
+<translation id="7770259615151589601">નિર્દિષ્ટ-લાંબું</translation>
<translation id="777702478322588152">પ્રીફેચર</translation>
<translation id="7791543448312431591">ઉમેરો</translation>
<translation id="7793809570500803535"><ph name="SITE" /> પરનાં વેબ પેજ થોડા સમય માટે બંધ હોઈ શકે છે અથવા તે કાયમ માટે નવા વેબ ઍડ્રેસ પર ખસેડવામાં આવ્યા હોઈ શકે છે.</translation>
@@ -1087,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome માંથી ફોર્મ સૂચનો દૂર કરીએ?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' માટે <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> મળ્યાં</translation>
-<translation id="7818867226424560206">નીતિનું વ્યવસ્થાપન</translation>
<translation id="782886543891417279">તમે વાપરી રહેલા વાઇ-ફાઇ (<ph name="WIFI_NAME" />)ના લોગિન પેજ પર જવું પડી શકે.</translation>
+<translation id="7836231406687464395">Postfix (એન્વલપ)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{કોઈ નહીં}=1{1 ઍપ (<ph name="EXAMPLE_APP_1" />)}=2{2 ઍપ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# ઍપ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# ઍપ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">જોકે, તમે અદૃશ્ય નથી. છુપામાં જવું તમારા નિયોક્તા, તમારા ઇન્ટરનેટ સેવા પ્રદાતા અથવા તમે મુલાકાત લો છો તે વેબસાઇટથી તમારા બ્રાઉઝિંગને છુપાવતું નથી.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@
<translation id="7878562273885520351">તમારા પાસવર્ડ સાથે ચેડાં થઈ શકે છે</translation>
<translation id="7882421473871500483">ભૂરો</translation>
<translation id="7887683347370398519">તમારું CVC તપાસો અને ફરીથી પ્રયાસ કરો</translation>
-<translation id="7893255318348328562">સત્રનું નામ</translation>
+<translation id="7904208859782148177">C3 (એન્વલપ)</translation>
<translation id="79338296614623784">એક માન્ય ફોન નંબર દાખલ કરો</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" />ના રોજ સમાપ્ત થાય છે</translation>
@@ -1107,21 +1256,25 @@
<translation id="7951415247503192394">(32-બિટ)</translation>
<translation id="7956713633345437162">મોબાઇલ બુકમાર્ક્સ</translation>
<translation id="7961015016161918242">ક્યારેય નહીં</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">નિર્દિષ્ટ કરાયેલ નથી</translation>
<translation id="800218591365569300">મેમરી ખાલી કરવા માટે અન્ય ટૅબ અથવા પ્રોગ્રામને બંધ કરવાનો પ્રયાસ કરો.</translation>
+<translation id="8004582292198964060">બ્રાઉઝર</translation>
<translation id="8009225694047762179">બધા પાસવર્ડ મેનેજ કરો</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{આ કાર્ડ અને તેનું બિલિંગ સરનામું સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેનો ઉપયોગ કરી શકશો.}one{આ કાર્ડ અને તેના બિલિંગ સરનામાં સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેમનો ઉપયોગ કરી શકશો.}other{આ કાર્ડ અને તેના બિલિંગ સરનામાં સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેમનો ઉપયોગ કરી શકશો.}}</translation>
<translation id="8012647001091218357">અમે આ પળે તમારા વાલીઓ સુધી પહોંચી શક્યાં નથી. કૃપા કરીને ફરી પ્રયાસ કરો.</translation>
<translation id="8025119109950072390">આ સાઇટ પરના હુમલાખોરો તમારી વ્યક્તિગત માહિતી (ઉદાહરણ તરીકે, પાસવર્ડ, ફોન નંબર અથવા ક્રેડિટ કાર્ડ)ને દર્શાવવા અથવા સોફ્ટવેર ઇન્સ્ટૉલ કરવા જેવી જોખમી વસ્તુઓને કરવા માટે તમને છેતરવાનો પ્રયાસ કરી શકે છે.</translation>
<translation id="8034522405403831421">આ પૃષ્ઠ <ph name="SOURCE_LANGUAGE" /> માં છે. શું તેનો અનુવાદ <ph name="TARGET_LANGUAGE" /> માં કરીએ?</translation>
<translation id="8035152190676905274">પેન</translation>
+<translation id="8037117624646282037">તાજેતરમાં ડિવાઇસનો ઉપયોગ કરનાર વપરાશકર્તાઓ</translation>
<translation id="8037357227543935929">પૂછો (ડિફૉલ્ટ)</translation>
<translation id="803771048473350947">ફાઇલ</translation>
<translation id="8041089156583427627">પ્રતિસાદ મોકલો</translation>
<translation id="8041940743680923270">વૈશ્વિક ડિફોલ્ટનો ઉપયોગ કરો (કહો)</translation>
<translation id="8042918947222776840">પિકઅપ પદ્ધતિ પસંદ કરો</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />"ની ગોઠવણી યોગ્ય રીતે કરવામાં આવી નથી. સામાન્ય રીતે "<ph name="SOFTWARE_NAME" />"ને અનઇન્સ્ટૉલ કરવાથી સમસ્યા હલ થઈ જાય છે. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">તમારું ડિવાઇસ આવું ગોઠવ્યું છે:</translation>
+<translation id="8066955247577885446">માફ કરશો, કંઈક ખોટું થયું.</translation>
+<translation id="8074253406171541171">10x13 (એન્વલપ)</translation>
<translation id="8078141288243656252">ફેરવેલ હોય ત્યારે એનોટેટ કરી શકતા નથી</translation>
<translation id="8079031581361219619">સાઇટ ફરીથી લોડ કરીએ?</translation>
<translation id="8088680233425245692">લેખ જોવામાં નિષ્ફળ.</translation>
@@ -1130,11 +1283,12 @@
<translation id="8091372947890762290">સક્રિયતા સર્વર પર બાકી છે</translation>
<translation id="8092774999298748321">ઘાટો જાંબલી</translation>
<translation id="8094917007353911263">તમે ઉપયોગ કરી રહ્યાં છો તે નેટવર્કને <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ની મુલાકાત લેવાની જરૂર પડી શકે છે.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">અમાન્ય કાર્ડ કાઢી નાખવામાં આવ્યાં છે</translation>
<translation id="8103161714697287722">ચુકવણીની પદ્ધતિ</translation>
<translation id="8118489163946903409">ચુકવણી પદ્ધતિ</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> <ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે</translation>
<translation id="8127301229239896662">તમારા કમ્પ્યુટરમાં અથવા નેટવર્ક પર "<ph name="SOFTWARE_NAME" />" યોગ્ય રીતે ઇન્સ્ટૉલ થયું નથી. તમારા IT વ્યવસ્થાપકને આ સમસ્યા હલ કરવાનું કહો.</translation>
-<translation id="8130693978878176684">હું હવે વધુ સહાય નહીં કરી શકું, કૃપા કરીને તમારી રીતે ચાલુ રાખો.</translation>
<translation id="8131740175452115882">પુષ્ટિ કરો</translation>
<translation id="8149426793427495338">તમારું કમ્પ્યુટર નિષ્ક્રિય થઈ ગયું હતું.</translation>
<translation id="8150722005171944719"><ph name="URL" /> પરની ફાઇલ વાંચનયોગ્ય નથી. તે દૂર કરવામાં, ખસેડવામાં આવી હોઈ શકે છે અથવા ફાઇલ પરવાનગીઓ ઍક્સેસ કરવાથી અટકાવતી હોઈ શકે છે.</translation>
@@ -1144,8 +1298,11 @@
<translation id="8197543752516192074">પેજનો અનુવાદ કરો</translation>
<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" સાથેના એક્સટેન્શન માટે અમાન્ય અપડેટ URL.</translation>
<translation id="8202097416529803614">ઓર્ડરનો સારાંશ</translation>
+<translation id="8202370299023114387">વિરોધ</translation>
+<translation id="8206978196348664717">Prc4 (એન્વલપ)</translation>
<translation id="8211406090763984747">કનેક્શન સુરક્ષિત છે</translation>
<translation id="8218327578424803826">સોંપાયેલ સ્થાન:</translation>
+<translation id="8220146938470311105">C7/C6 (એન્વલપ)</translation>
<translation id="8225771182978767009">આ કમ્પ્યુટરને સેટ કરનાર વ્યક્તિએ આ સાઇટને અવરોધિત કરવાનું પસંદ કર્યું છે.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">એક નવી છુપી વિંડોમાં પેજ ખોલો</translation>
@@ -1157,14 +1314,16 @@
<translation id="825929999321470778">બધા સાચવેલા પાસવર્ડ બતાવો</translation>
<translation id="8261506727792406068">ડિલીટ કરો</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> તરીકે સાઇન ઇન કરી રહ્યાં છે</translation>
+<translation id="8278457561961988242">આ બ્રાઉઝર <ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરવામાં આવે છે. તમારા વ્યવસ્થાપક તમારા બ્રાઉઝર સેટઅપને રિમોટલી બદલી શકે છે. આ ડિવાઇસ પરની પ્રવૃત્તિ Chromeની બહારથી પણ મેનેજ કરી શકાય છે. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">મોટો-ફોટો</translation>
<translation id="8286036467436129157">સાઇન ઇન કરો</translation>
<translation id="8288807391153049143">પ્રમાણપત્ર બતાવો</translation>
<translation id="8289355894181816810">આ શું છે તે ખાતરીપૂર્વક જાણતા ન હો તો તમારા નેટવર્ક વ્યવસ્થાપકનો સંપર્ક કરો.</translation>
<translation id="8293206222192510085">બુકમાર્ક ઉમેરો</translation>
<translation id="8294431847097064396">સ્રોત</translation>
<translation id="8298115750975731693">તમે વાપરી રહેલા વાઇ-ફાઇ (<ph name="WIFI_NAME" />)ના <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ની જવું પડી શકે.</translation>
+<translation id="8307358339886459768">નાનો-ફોટો</translation>
<translation id="8308427013383895095">નેટવર્ક કનેક્શનમાં સમસ્યાને કારણે ભાષાંતર નિષ્ફળ રહ્યું.</translation>
-<translation id="8311129316111205805">સત્ર લોડ કરો</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ની ઍક્સેસ નકારાઈ હતી</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">જો તમે તમારી સુરક્ષાના જોખમોને સમજો છો, તો તમે જોખમી પ્રોગ્રામ્સ દૂર કરી દેવામાં આવે તે પહેલાં <ph name="BEGIN_LINK" />આ સાઇટની મુલાકાત<ph name="END_LINK" /> લઈ શકો છો.</translation>
@@ -1182,7 +1341,6 @@
<translation id="8416694386774425977">નેટવર્કની ગોઠવણી અમાન્ય છે અને તેને આયાત કરી શકાઈ નથી.
વધારાની વિગતો:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" /> દ્વારા મેનેજ કરાતું ડિવાઇસ</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">બદલો</translation>
<translation id="8428213095426709021">સેટિંગ્સ</translation>
@@ -1209,9 +1367,11 @@
<translation id="860043288473659153">કાર્ડધારકનું નામ</translation>
<translation id="861775596732816396">કદ 4</translation>
<translation id="8620436878122366504">તમારા માતાપિતાએ તેને હજી સુધી મંજૂર કરેલ નથી</translation>
+<translation id="8622948367223941507">કાનૂની-અતિરિક્ત</translation>
<translation id="8625384913736129811">આ કાર્ડને આ ડિવાઇસમાં સાચવો</translation>
<translation id="8663226718884576429">ઑર્ડરનો સારાંશ, <ph name="TOTAL_LABEL" />, વધુ વિગતો</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, જવાબ, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> સાથેનું તમારું કનેક્શન એન્ક્રિપ્ટેડ નથી.</translation>
<translation id="8718314106902482036">ચુકવણી પૂર્ણ થઈ નથી</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, શોધ સૂચન</translation>
@@ -1225,6 +1385,7 @@
<translation id="8761567432415473239">Google Safe Browsing ને તાજેતરમાં <ph name="SITE" /> પર <ph name="BEGIN_LINK" />હાનિકારક પ્રોગ્રામ્સ મળ્યાં<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB ઉપકરણ</translation>
<translation id="8768895707659403558">તમારા બધા ડિવાઇસ પર તમારા કાર્ડનો ઉપયોગ કરવા માટે, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ફરી ડિલીટ કરો</translation>
<translation id="8792621596287649091">તમે તમારા <ph name="ORG_NAME" /> એકાઉન્ટનો ઍક્સેસ ગુમાવી શકો છો અથવા તમને ઓળખ ચોરીનો અનુભવ થઈ શકે છે. Chromium તમને હમણાં જ તમારો પાસવર્ડ બદલવાની ભલામણ કરે છે.</translation>
<translation id="8800988563907321413">તમારા નજીકના સૂચનો અહીં દેખાય છે</translation>
@@ -1235,10 +1396,12 @@
<translation id="885730110891505394">Google સાથે શેર કરવું</translation>
<translation id="8858065207712248076">જો તમે અન્ય સાઇટ પર <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> પાસવર્ડનો ફરી ઉપયોગ કર્યો હોય, તો Chrome તેને રીસેટ કરવાનો સુઝાવ આપે છે.</translation>
<translation id="8866481888320382733">ભૂલ વિશ્લેષણ નીતિ સેટિંગ્સ</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">તાજેતરમાં બંધ કરેલા</translation>
<translation id="8874824191258364635">એક માન્ય કાર્ડ નંબર દાખલ કરો</translation>
<translation id="8891727572606052622">અમાન્ય પ્રૉક્સી મોડ.</translation>
<translation id="8903921497873541725">ઝૂમ વધારો</translation>
+<translation id="890485472659500557">એન્જિનિયરિંગ-C</translation>
<translation id="8931333241327730545">શું તમે આ કાર્ડને તમારા Google એકાઉન્ટમાં સાચવવા માગો છો?</translation>
<translation id="8932102934695377596">તમારી ઘડિયાળ પાછળ છે</translation>
<translation id="893332455753468063">નામ ઉમેરો</translation>
@@ -1246,13 +1409,13 @@
<translation id="894185898663964645">તમારા વ્યવસ્થાપકે કસ્ટમ રૂટ પ્રમાણપત્રો ગોઠવ્યા છે, જે વ્યવસ્થાપકને તમે મુલાકાત લો તે વેબસાઇટના કન્ટેન્ટને જોવાની મંજૂરી આપી શકે છે.</translation>
<translation id="8943282376843390568">લાઇમ</translation>
<translation id="8957210676456822347">કૅપ્ટિવ પોર્ટલ પ્રમાણિત</translation>
+<translation id="8966619695390250636">શું તમારો અર્થ આ હતો?</translation>
<translation id="8968766641738584599">કાર્ડ સાચવો</translation>
<translation id="8971063699422889582">સર્વરના પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ છે.</translation>
<translation id="8975012916872825179">ફોન નંબર, ઇમેઇલ ઍડ્રેસ અને શિપિંગ સરનામા જેવી માહિતીનો સમાવેશ છે</translation>
<translation id="8978053250194585037">Google Safe Browsingને <ph name="SITE" /> પર તાજેતરમાં <ph name="BEGIN_LINK" />ફિશિંગ થયાનું જાણવા મળ્યું છે<ph name="END_LINK" />. ફિશિંગ વેબસાઇટ તમને છેતરવા માટે અન્ય વેબસાઇટ હોવાનો ઢોંગ કરે છે.</translation>
<translation id="8983003182662520383">Google Payનો ઉપયોગ કરતી ચુકવણી પદ્ધતિઓ અને ઍડ્રેસ</translation>
<translation id="8987927404178983737">મહિનો</translation>
-<translation id="8988408250700415532">કંઈક ખોટું થયું. તમે વેબસાઇટ પર તમારો ઑર્ડર પૂર્ણ કરી શકશો.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">સાઇટમાં આગળ હાનિકારક પ્રોગ્રામ્સ છે</translation>
<translation id="8997023839087525404">સર્વરે એવું પ્રમાણપત્ર પ્રસ્તુત કર્યું કે જે પ્રમાણપત્ર પારદર્શિતા નીતિનો ઉપયોગ કરીને સાર્વજનિક રીતે જાહેર કર્યું ન હતું. આ કેટલાક પ્રમાણપત્રો માટે એ ખાતરી કરવા હેતુ આવશ્યક છે કે તેઓ વિશ્વસનીય છે અને હુમલાખારો સામે રક્ષણ કરે છે.</translation>
@@ -1262,6 +1425,7 @@
<translation id="9011424611726486705">સાઇટની સેટિંગ ખોલો</translation>
<translation id="9020200922353704812">કાર્ડનું બિલિંગ સરનામું આવશ્યક છે</translation>
<translation id="9020542370529661692">આ પૃષ્ઠનો <ph name="TARGET_LANGUAGE" /> માં અનુવાદ કરવામાં આવ્યો છે</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(અમાન્ય)</translation>
<translation id="9035022520814077154">સુરક્ષા ભૂલ</translation>
<translation id="9038649477754266430">પૃષ્ઠોને વધુ ઝડપથી લોડ કરવા માટે પૂર્વાનુમાન સેવાનો ઉપયોગ કરો</translation>
@@ -1273,11 +1437,11 @@
<translation id="9065745800631924235">ઇતિહાસમાંથી <ph name="TEXT" /> શોધો</translation>
<translation id="9069693763241529744">એક્સ્ટેન્શન દ્વારા અવરોધિત કરેલ છે</translation>
<translation id="9076283476770535406">તેમાં વયસ્ક કન્ટેન્ટ હોઈ શકે છે</translation>
+<translation id="9076630408993835509">આ બ્રાઉઝર કંપની દ્વારા અથવા અન્ય સંસ્થા દ્વારા મેનેજ કરવામાં આવતું નથી. આ ડિવાઇસ પરની પ્રવૃત્તિ Chromeની બહાર મેનેજ કરી શકાય છે. <ph name="BEGIN_LINK" />વધુ જાણો<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">વધુ માહિતી આવશ્યક</translation>
<translation id="9080712759204168376">ઑર્ડરનો સારાંશ</translation>
<translation id="9103872766612412690"><ph name="SITE" /> સામાન્ય રીતે તમારી માહિતીને સુરક્ષિત રાખવા માટે એન્ક્રિપ્શનનો ઉપયોગ કરે છે. જ્યારે આ સમયે Chromium દ્વારા <ph name="SITE" />થી કનેક્ટ કરવાનો પ્રયાસ થયો, ત્યારે વેબસાઇટે અસામાન્ય અને ખોટા લૉગ ઇન વિગતને પાછા મોકલ્યાં. આવું ત્યારે થઈ શકે જ્યારે કોઈ હુમલાખોર <ph name="SITE" /> હોવાનો ડોળ કરવાનો પ્રયાસ કરી રહ્યો હોવ અથવા કોઈ Wi-Fi સાઇન-ઇન સ્ક્રીને કનેક્શનમાં વિક્ષેપ પાડ્યો હોય. તમારી માહિતી હજી પણ સુરક્ષિત છે કારણ કે Chromium એ કોઈ પણ ડેટા વિનિમય થાય એ પહેલાં જ કનેક્શન રોકી દીધું.</translation>
<translation id="9106062320799175032">બિલિંગ સરનામું ઉમેરો</translation>
-<translation id="9110718169272311511">Chromeમાં Google આસિસ્ટંટ, સ્ક્રીનની નીચેની બાજુએ ઉપલબ્ધ રહે છે</translation>
<translation id="9114524666733003316">કાર્ડ કન્ફર્મ કરી રહ્યાં છીએ...</translation>
<translation id="9128870381267983090">નેટવર્કથી કનેક્ટ કરો</translation>
<translation id="9137013805542155359">મૂળ બતાવો</translation>
@@ -1286,6 +1450,7 @@
<translation id="9148507642005240123">&amp;છેલ્લો ફેરફાર રદ કરો</translation>
<translation id="9154194610265714752">અપડેટેડ</translation>
<translation id="9157595877708044936">સેટિંગ અપ...</translation>
+<translation id="9158625974267017556">C6 (એન્વલપ)</translation>
<translation id="9168814207360376865">તમારી ચુકવણી પદ્ધતિઓ સાચવવામાં આવી છે કે કેમ તે ચેક કરવાની સાઇટને મંજૂરી આપો</translation>
<translation id="9169664750068251925">હંમેશા આ સાઇટ પર અવરોધિત કરો</translation>
<translation id="9170848237812810038">&amp;પૂર્વવત્ કરો</translation>
@@ -1300,10 +1465,12 @@
<translation id="9219103736887031265">છબીઓ</translation>
<translation id="933712198907837967">ડાઇનર્સ ક્લબ</translation>
<translation id="935608979562296692">ફોર્મ સાફ કરો</translation>
+<translation id="936474030629450166">સુપર-B</translation>
<translation id="936602727769022409">તમે તમારા Google એકાઉન્ટનો ઍક્સેસ ગુમાવી શકો છો. Chromium તમને હમણાં જ તમારો પાસવર્ડ બદલવાનો સુઝાવ આપે છે. તમને સાઇન ઇન કરવા માટે કહેવામાં આવશે.</translation>
<translation id="939736085109172342">નવું ફોલ્ડર</translation>
<translation id="945855313015696284">નીચેની માહિતી જુઓ અને કોઈપણ અમાન્ય કાર્ડ ડિલીટ કરો</translation>
<translation id="951104842009476243">સ્વીકૃત ડેબિટ અને પ્રિપેઇડ કાર્ડ</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" />ની સુરક્ષા પૉલિસી અનુસાર બ્લૉક કરેલી છે.</translation>
<translation id="962484866189421427">આ કન્ટેન્ટ કદાચ ભ્રામક ઍપ ઇન્સ્ટૉલ કરવાનો પ્રયાસ કરે છે કે જે પોતાની ખોટી ઓળખ આપે છે અથવા તમને ટ્રૅક કરવા માટે ઉપયોગમાં લઈ શકાય તેવો ડેટા મેળવે છે. <ph name="BEGIN_LINK" />તો પણ બતાવો<ph name="END_LINK" /></translation>
<translation id="969892804517981540">આધિકારિક બિલ્ડ</translation>
<translation id="973773823069644502">વિતરણ માટેનું સરનામું ઉમેરો</translation>
@@ -1312,6 +1479,7 @@
<translation id="984275831282074731">ચુકવણી પદ્ધતિઓ</translation>
<translation id="985199708454569384">&lt;p&gt;જો તમારા કમ્પ્યુટર અથવા મોબાઇલ ઉપકરણની તારીખ અને સમય સચોટ નહીં હોય, તો તમને આ ભૂલ દેખાશે.&lt;/p&gt;
&lt;p&gt;આ ભૂલ સુધારવા માટે, તમારા ઉપકરણની ઘડિયાળ ખોલો. ખાતરી કરો કે સમય અને તારીખ સાચાં છે.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">વિકાસકર્તા બિલ્ડ</translation>
<translation id="989988560359834682">ઍડ્રેસમાં ફેરફાર કરો</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_hi.xtb b/chromium/components/strings/components_strings_hi.xtb
index ce8d0a9334a..e6d7fcc81ae 100644
--- a/chromium/components/strings/components_strings_hi.xtb
+++ b/chromium/components/strings/components_strings_hi.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
-<translation id="1005145902654145231">सत्र का नाम नहीं बदल पाए.</translation>
<translation id="1008557486741366299">अभी नहीं</translation>
<translation id="1010200102790553230">पेज को बाद में लोड करें</translation>
<translation id="1015730422737071372">अतिरिक्त विवरण प्रदान करें</translation>
@@ -11,22 +10,26 @@
<translation id="1038842779957582377">अज्ञात नाम</translation>
<translation id="1050038467049342496">दूूूूसरे ऐप्लिकेशन बंद करें</translation>
<translation id="1055184225775184556">&amp;जोड़ना वापस लाएं</translation>
+<translation id="1056898198331236512">चेतावनी</translation>
<translation id="1058479211578257048">कार्ड सेव किए जा रहे हैं...</translation>
<translation id="10614374240317010">कभी नहीं सेव किया गया</translation>
+<translation id="1062160989074299343">पीआरसी10 (एन्वेलप)</translation>
<translation id="106701514854093668">डेस्कटॉप बुकमार्क</translation>
<translation id="1074497978438210769">सुरक्षित नहीं है</translation>
<translation id="1080116354587839789">चौड़ाई में फ़िट करें</translation>
+<translation id="1086953900555227778">इंडेक्स-5x8</translation>
<translation id="1088860948719068836">कार्ड पर नाम जोड़ें</translation>
<translation id="1089439967362294234">पासवर्ड बदलें</translation>
<translation id="109743633954054152">Chrome सेटिंग में पासवर्ड प्रबंधित करें</translation>
<translation id="1103523840287552314"><ph name="LANGUAGE" /> का हमेशा अनुवाद करें</translation>
-<translation id="1107591249535594099">चेक किए होने पर, अधिक तेज़ फ़ॉर्म भरने के लिए Chrome इस डिवाइस पर आपके कार्ड की कॉपी संग्रहित कर लेगा.</translation>
+<translation id="1107591249535594099">चेक किए होने पर, ज़्यादा तेज़ फ़ॉर्म भरने के लिए Chrome इस डिवाइस पर आपके कार्ड की कॉपी संग्रहित कर लेगा.</translation>
<translation id="1110994991967754504"><ph name="PERMISSION_NAME" /> के लिए अनुमति चुनें</translation>
<translation id="1111153019813902504">हाल के बुकमार्क</translation>
<translation id="1113869188872983271">&amp;पुन: क्रमित करना वापस लाएं</translation>
<translation id="1125573121925420732">जब वेबसाइटें अपनी सुरक्षा अपडेट कर रही होती हैं तब चेतावनियां आम हो सकती हैं. इसमें जल्दी ही सुधार होगा.</translation>
<translation id="1126551341858583091">स्थानीय जगह का आकार <ph name="CRASH_SIZE" /> है.</translation>
<translation id="112840717907525620">नीति संचय ठीक है</translation>
+<translation id="1131264053432022307">आपकी कॉपी की हुई इमेज</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>
@@ -34,21 +37,20 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ने अनपेक्षित रूप से कनेक्शन बंद कर दिया है.</translation>
<translation id="1161325031994447685">वाई-फ़ाई से फिर से कनेक्ट करें</translation>
<translation id="1165039591588034296">गड़बड़ी</translation>
-<translation id="1173894706177603556">नाम बदलें</translation>
<translation id="1175364870820465910">&amp;प्रिंट करें...</translation>
<translation id="1181037720776840403">हटाएं</translation>
<translation id="1197088940767939838">नारंगी</translation>
<translation id="1201402288615127009">आगे बढ़ें</translation>
-<translation id="1201895884277373915">इस साइट की ओर से अधिक</translation>
+<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="124116460088058876">अधिक भाषाएं</translation>
+<translation id="1240347957665416060">आपके डिवाइस का नाम</translation>
+<translation id="124116460088058876">ज़्यादा भाषाएं</translation>
<translation id="1250759482327835220">अगली बार तेज़ी से भुगतान करने के लिए, अपने कार्ड, नाम और बिलिंग पते को अपने 'Google खाते' में सेव करें.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (सिंक किए गए)</translation>
<translation id="1256368399071562588">&lt;p&gt;अगर आप किसी वेबसाइट पर जाने की कोशिश करते हैं और वह नहीं खुलती है तो, कृपया गड़बड़ी ठीक करने संबंधी इन कदमों के ज़रिए समस्या का हल करने की कोशिश करें:&lt;/p&gt;
@@ -66,10 +68,11 @@
<translation id="1294154142200295408">अलग-अलग तरह की कमांड-लाइन</translation>
<translation id="129553762522093515">हाल ही में बंद किए गए</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />अपनी कुकी साफ़ करके देखें<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">चुना गया सत्र मौजूद नहीं है.</translation>
+<translation id="1320233736580025032">पीआरसी1 (एन्वेलप)</translation>
+<translation id="132301787627749051">क्लिपबोर्ड इमेज खोजें</translation>
<translation id="1323433172918577554">और दिखाएं</translation>
<translation id="132390688737681464">पतों की जानकारी सेव करें और फ़ॉर्म में भरें</translation>
-<translation id="1333989956347591814">आपकी गतिविधि इन्हें <ph name="BEGIN_EMPHASIS" />अभी भी दिखाई दे सकती है<ph name="END_EMPHASIS" />:
+<translation id="1333989956347591814">आपकी गतिविधि इन्हें <ph name="BEGIN_EMPHASIS" />अब भी दिखाई दे सकती है<ph name="END_EMPHASIS" />:
<ph name="BEGIN_LIST" />
<ph name="LIST_ITEM" />जिन वेबसाइट पर आप जाते हैं
<ph name="LIST_ITEM" />आपका नियोक्ता या स्कूल
@@ -79,12 +82,18 @@
<translation id="1340482604681802745">पिकअप पता</translation>
<translation id="1348198688976932919">आगे आने वाली साइट में खतरनाक ऐप्लिकेशन हैं</translation>
<translation id="1348779747280417563">नाम की पुष्टि करें</translation>
+<translation id="1357195169723583938">हाल ही में डिवाइस किसने और कब इस्तेमाल किया है</translation>
+<translation id="1364822246244961190">यह नीति ब्लॉक की हुई है. इसका मान नज़रअंदाज कर दिया जाएगा.</translation>
<translation id="1374468813861204354">सुझाव</translation>
+<translation id="1374692235857187091">इंडेक्स-4x6 (पोस्टकार्ड)</translation>
<translation id="1375198122581997741">वर्शन के बारे में</translation>
<translation id="1376836354785490390">कम दिखाएं</translation>
<translation id="1377321085342047638">कार्ड नंबर</translation>
<translation id="138218114945450791">हल्का नीला</translation>
+<translation id="1382194467192730611">आपके व्यवस्थापक ने इस यूएसबी डिवाइस की मंज़ूरी दी है</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ने कोई डेटा नहीं भेजा.</translation>
+<translation id="140316286225361634">साइट <ph name="ORIGIN" /> ने यह अनुरोध किया है कि इसके सभी अनुरोधों पर
+ सुरक्षा नीति लागू होगी, और इस नीति के मुताबिक यह साइट फ़िलहाल असुरक्षित है.</translation>
<translation id="1405567553485452995">हल्का हरा</translation>
<translation id="1407135791313364759">सभी बुकमार्क खोलें</translation>
<translation id="1413809658975081374">निजता गड़बड़ी</translation>
@@ -92,49 +101,58 @@
<translation id="1426410128494586442">हां</translation>
<translation id="1430915738399379752">प्रिंट करें</translation>
<translation id="1455413310270022028">इरेज़र</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">और दिखाएं</translation>
+<translation id="147358896496811705">2ए0</translation>
<translation id="1484290072879560759">शिपिंग पता चुनें</translation>
+<translation id="1492194039220927094">नीतियां भेजें:</translation>
<translation id="1501859676467574491">अपने Google खाते में मौजूद कार्ड दिखाएं</translation>
-<translation id="1506687042165942984">इस पृष्‍ठ की सहेजी गई (अर्थात जिसे पुराना माना जाता है) कॉपी दिखाएं.</translation>
<translation id="1507202001669085618">&lt;p&gt;अगर आप ऐसे वाई-फ़ाई पोर्टल का इस्तेमाल कर रहे हैं जिसमें ऑनलाइन होने से पहले साइन इन ज़रूरी है, तो आपको यह गड़बड़ी दिखाई देगी.&lt;/p&gt;
&lt;p&gt;गड़बड़ी ठीक करने के लिए, उस पेज पर &lt;strong&gt;कनेक्ट करें&lt;/strong&gt; को क्लिक करें जिसे आप खोलने की कोशिश कर रहे हैं.&lt;/p&gt;</translation>
<translation id="1517433312004943670">फ़ोन नंबर आवश्यक है</translation>
<translation id="1517500485252541695">स्वीकृत क्रेडिट और डेबिट कार्ड</translation>
-<translation id="1519264250979466059">बिल्ड दिनांक</translation>
+<translation id="1519264250979466059">बिल्ड तारीख</translation>
<translation id="1521655867290435174">Google पत्रक</translation>
<translation id="1527263332363067270">कनेक्‍शन के इंतज़ार में…</translation>
+<translation id="1529521330346880926">10x15 (एन्वेलप)</translation>
+<translation id="1531205177818805254">एक्ज़ीक्यूटिव</translation>
<translation id="1532118530259321453">इस पेज का कहना है कि</translation>
<translation id="153384715582417236">फिलहाल बस इतना ही</translation>
<translation id="154408704832528245">डिलीवरी पता चुनें</translation>
<translation id="1549470594296187301">इस सुविधा का उपयोग करने के लिए JavaScript को सक्षम किया जाना चाहिए.</translation>
+<translation id="155039086686388498">इंजीनियरिंग-डी</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;
+<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>
+ &lt;p&gt;कृपया तारीख और समय को &lt;strong&gt;सेटिंग&lt;/strong&gt; ऐप के &lt;strong&gt;सामान्‍य&lt;/strong&gt; अनुभाग से एडजस्‍ट करें.&lt;/p&gt;</translation>
+<translation id="1569487616857761740">खत्म होने की तारीख डालें</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">इस वेबपेज को दिखाने के दौरान कुछ गड़बड़ी हुई है.</translation>
<translation id="1592005682883173041">स्थानीय डेटा एक्सेस</translation>
<translation id="1594030484168838125">चुनें</translation>
<translation id="161042844686301425">स्यान</translation>
-<translation id="1618822247301510817">आपकी कॉपी बनाई हुई इमेज</translation>
<translation id="1620510694547887537">कैमरा</translation>
<translation id="1623104350909869708">इस पेज को अतिरिक्त डॉयलॉग बनाने से रोकें</translation>
+<translation id="16338877384480380">आर्किटेक्चर-बी</translation>
<translation id="1634051627998691300">सेशन खत्म करें</translation>
<translation id="1639239467298939599">लोड हो रहा है</translation>
<translation id="1640180200866533862">उपयोगकर्ता नीतियां</translation>
<translation id="1640244768702815859"><ph name="BEGIN_LINK" />साइट के मुखपृष्ठ पर विज़िट करके<ph name="END_LINK" /> देखें.</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="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="1662550410081243962">भुगतान के तरीके सेव करें और जानकारी भरें</translation>
<translation id="1663943134801823270">कार्ड और पते Chrome से मिलते हैं. आप उन्हें <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में प्रबंधित कर सकते हैं.</translation>
<translation id="1671391448414634642">अब से <ph name="SOURCE_LANGUAGE" /> भाषा के पेज का अनुवाद <ph name="TARGET_LANGUAGE" /> भाषा में किया जाएगा.</translation>
-<translation id="1676269943528358898">आपकी जानकारी की सुरक्षा करने के लिए <ph name="SITE" /> आमतौर पर एन्क्रिप्शन का उपयोग करती है. जब Google Chrome ने इस बार <ph name="SITE" /> से कनेक्ट करने का प्रयास किया, तो वेबसाइट ने असामान्य और गलत क्रेडेंशियल वापस भेजे. ऐसा तब हो सकता है जब कोई हमलावर <ph name="SITE" /> होने का दावा करने का प्रयास कर रहा हो या किसी वाई-फ़ाई प्रवेश स्क्रीन ने कनेक्शन को बाधित कर दिया हो. आपकी जानकारी अभी भी सुरक्षित है क्योंकि किसी भी डेटा के आदान-प्रदान से पहले ही Google Chrome ने कनेक्शन को रोक दिया था.</translation>
+<translation id="1676269943528358898">आपकी जानकारी की सुरक्षा करने के लिए <ph name="SITE" /> आमतौर पर एन्क्रिप्शन का उपयोग करती है. जब Google Chrome ने इस बार <ph name="SITE" /> से कनेक्ट करने का प्रयास किया, तो वेबसाइट ने असामान्य और गलत क्रेडेंशियल वापस भेजे. ऐसा तब हो सकता है जब कोई हमलावर <ph name="SITE" /> होने का दावा करने का प्रयास कर रहा हो या किसी वाई-फ़ाई प्रवेश स्क्रीन ने कनेक्शन को बाधित कर दिया हो. आपकी जानकारी अब भी सुरक्षित है क्योंकि किसी भी डेटा के आदान-प्रदान से पहले ही Google Chrome ने कनेक्शन को रोक दिया था.</translation>
<translation id="168841957122794586">सर्वर प्रमाणपत्र में कमज़ोर क्रिप्टोग्राफ़िक कुंजी है.</translation>
<translation id="1697532407822776718">आप बिल्कुल तैयार हैं!</translation>
+<translation id="1703835215927279855">लेटर</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="1715874602234207">एफ़</translation>
<translation id="1718029547804390981">एनोटेट करने के लिए दस्तावेज़ बहुत बड़ा है</translation>
<translation id="1721312023322545264">आपको <ph name="NAME" /> से इस साइट पर जाने की अनुमति लेनी होगी</translation>
<translation id="1721424275792716183">* फ़ील्ड ज़रूरी है</translation>
@@ -145,6 +163,7 @@
<translation id="1734878702283171397">सिस्टम व्यवस्थापक से संपर्क करने का प्रयास करें.</translation>
<translation id="1740951997222943430">खत्म होने का मान्य महीना डालें</translation>
<translation id="1743520634839655729">अगली बार तेज़ी से भुगतान करने के लिए, अपने कार्ड, नाम और बिलिंग पते को अपने 'Google खाते' में और इस डिवाइस में सेव करें.</translation>
+<translation id="1745880797583122200">आपका ब्राउज़र प्रबंधित है</translation>
<translation id="17513872634828108">टैब खोलें</translation>
<translation id="1753706481035618306">पृष्‍ठ संख्‍या</translation>
<translation id="1763864636252898013">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र आपके डिवाइस के ऑपरेटिंग सिस्टम द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
@@ -152,8 +171,10 @@
<translation id="1783075131180517613">कृपया अपना समन्‍वयन पासफ्रेज़ अपडेट करें.</translation>
<translation id="1787142507584202372">आपके द्वारा खोले गए टैब, यहां दिखाई देंगे</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">बी9</translation>
<translation id="1803264062614276815">कार्ड के मालिक का नाम</translation>
<translation id="1821930232296380041">अमान्य अनुरोध या अनुरोध पैरामीटर</translation>
+<translation id="1822540298136254167">आप किन वेबसाइटों पर जाते हैं और उन पर कितना समय देते हैं</translation>
<translation id="1826516787628120939">जाँच की जा रही है</translation>
<translation id="1834321415901700177">इस साइट में हानिकारक प्रोग्राम हैं</translation>
<translation id="1839551713262164453">गड़बड़ियों के चलते नीति मानों की पुष्टि नहीं हो सकी</translation>
@@ -175,11 +196,15 @@
<translation id="1948773908305951926">स्वीकृत प्रीपेड कार्ड</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> बुकमार्क</translation>
<translation id="1973335181906896915">क्रमबद्ध करने में गड़बड़ी</translation>
-<translation id="1974060860693918893">उन्नत</translation>
+<translation id="1974060860693918893">बेहतर</translation>
<translation id="1978555033938440688">फ़र्मवेयर वर्शन</translation>
<translation id="1981206234434200693">Chrome के ब्राउज़िंग इतिहास का डेटा हटाएं</translation>
-<translation id="2001146170449793414">{COUNT,plural, =1{और 1 अधिक}one{और # अधिक}other{और # अधिक}}</translation>
+<translation id="2001146170449793414">{COUNT,plural, =1{और 1 ज़्यादा}one{और # ज़्यादा}other{और # ज़्यादा}}</translation>
<translation id="2003709556000175978">अपना पासवर्ड अभी रीसेट करें</translation>
+<translation id="20053308747750172">आप जिस सर्वर पर जा रहे हैं उसके लिए <ph name="ORIGIN" /> ने यह अनुरोध किया है
+ कि उसके सभी अनुरोधों पर सुरक्षा नीति लागू की जाए. लेकिन अब इसने
+ अमान्य नीति लागू कर दी है, जिस वजह से
+ ब्राउज़र <ph name="SITE" /> के लिए आपका अनुरोध पूरा नहीं कर पा रहा है.</translation>
<translation id="2025186561304664664">प्रॉक्‍सी स्‍वत: कॉन्‍फ़‍िगर पर सेट है.</translation>
<translation id="2030481566774242610">क्या आप मतलब <ph name="LINK" /> से है?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />प्रॉक्सी और फायरवॉल की जाँच करें<ph name="END_LINK" /></translation>
@@ -196,6 +221,7 @@
<translation id="2096368010154057602">विभाग</translation>
<translation id="2102134110707549001">मज़बूत पासवर्ड सुझाएं…</translation>
<translation id="2108755909498034140">अपना कंप्यूटर फिर से चालू करें</translation>
+<translation id="2111256659903765347">सुपर-ए</translation>
<translation id="2113977810652731515">कार्ड</translation>
<translation id="2114841414352855701">ध्यान नहीं दिया गया क्योंकि यह <ph name="POLICY_NAME" /> द्वारा ओवरराइड की गई थी.</translation>
<translation id="213826338245044447">मोबाइल बुकमार्क</translation>
@@ -206,6 +232,7 @@
<translation id="2154484045852737596">कार्ड संपादित करें</translation>
<translation id="2166049586286450108">पूर्ण व्यवस्थापकीय एक्सेस</translation>
<translation id="2166378884831602661">यह साइट सुरक्षित कनेक्शन प्रदान नहीं कर सकती</translation>
+<translation id="2169984857010174799">काकू2 (एन्वेलप)</translation>
<translation id="2181821976797666341">नीतियां</translation>
<translation id="2183608646556468874">फ़ोन नंबर</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 पता}one{# पते}other{# पते}}</translation>
@@ -223,45 +250,57 @@
<translation id="2270484714375784793">फ़ोन नंबर</translation>
<translation id="2283340219607151381">पतों की जानकारी सेव करें और फ़ॉर्म में भरें</translation>
<translation id="2292556288342944218">आपका इंटरनेट कनेक्शन अवरुद्ध है</translation>
+<translation id="2294558542833290837">आपने सबसे पहले जिस लिंक को खोला था, वह सामान्य लिंक नहीं है</translation>
+<translation id="2297722699537546652">बी5 (एन्वेलप)</translation>
+<translation id="2310021320168182093">शू2 (एन्वेलप)</translation>
<translation id="2316887270356262533">1 MB से भी कम जगह खाली करता है. जब आप अगली बार विज़िट करेंगे तो, कुछ साइटें और धीमे लोड हो सकती हैं.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> के लिए उपयोगकर्ता नाम और पासवर्ड आवश्यक है.</translation>
<translation id="2317583587496011522">डेबिट कार्ड स्वीकार किए जाते हैं.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, <ph name="EXPIRATION_DATE_ABBR" /> को खत्म होने वाला है</translation>
<translation id="2337852623177822836">वह सेटिंग जिसे आपका व्यवस्थापक नियंत्रित करता है</translation>
+<translation id="2346319942568447007">आपकी कॉपी की हुई इमेज</translation>
<translation id="2349790679044093737">VR सेशन चालू है</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="2359629602545592467">एक से ज़्यादा</translation>
<translation id="2359808026110333948">जारी रखें</translation>
<translation id="2360873523816792727">सभी डिवाइस पर अपने कार्ड का इस्तेमाल करने के लिए, 'सिंक करें' चालू करें.</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> पर कैप्चर की गई ख़राबी रिपोर्ट अपलोड नहीं की गई</translation>
<translation id="2367567093518048410">स्तर</translation>
<translation id="2378238891085281592">आप ’निजी’ मोड में चले गए हैं</translation>
+<translation id="2380886658946992094">कानूनी</translation>
<translation id="2384307209577226199">एंटरप्राइज़ डिफ़ॉल्ट</translation>
<translation id="2386255080630008482">सर्वर का प्रमाणपत्र निरस्त कर दिया गया है.</translation>
<translation id="2392959068659972793">कोई भी मान सेट नहीं की गई नीतियां दिखाएं</translation>
<translation id="239429038616798445">शिपिंग का यह तरीका उपलब्ध नहीं है. कोई दूसरा तरीका आज़माएं.</translation>
<translation id="2396249848217231973">&amp;हटाना वापस लाएं</translation>
+<translation id="2410754574180102685">सरकारी-कानूनी</translation>
<translation id="2413528052993050574">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" />; इसका सुरक्षा प्रमाणपत्र निरस्त कर दिया गया है. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="2418081434543109369">आप जिस सर्वर पर जा रहे हैं उसके लिए <ph name="ORIGIN" /> ने यह अनुरोध किया है
+ कि उसके सभी अनुरोधों पर सुरक्षा नीति लागू की जाए. लेकिन अब यह
+ नीति के मुताबिक काम नहीं कर रहा है, जिस वजह से
+ ब्राउज़र <ph name="SITE" /> के लिए आपके अनुरोध को पूरा नहीं कर पा रहा है.</translation>
<translation id="244665789865330679">आपके डिवाइस और खाते को <ph name="ENROLLMENT_DOMAIN" /> की ओर से प्रबंधित किया जाता है. इसका मतलब है कि आपका एडमिन दूर रहकर आपके डिवाइस और खाते को कॉन्फ़िगर कर सकता है.</translation>
<translation id="2463193859425327265">होम पेज बदलें</translation>
<translation id="2463739503403862330">भरें</translation>
+<translation id="2465402087343596252">आर्किटेक्चर-ई</translation>
<translation id="2465655957518002998">डिलीवरी का तरीका चुनें</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />नेटवर्क निदान चलाकर देखें<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">इस पेज का अनुवाद करें</translation>
<translation id="2479410451996844060">गलत खोज यूआरएल.</translation>
<translation id="2482878487686419369">सूचनाएं</translation>
<translation id="248348093745724435">मशीन के लिए नीतियां</translation>
+<translation id="2485387744899240041">आपके डिवाइस और ब्राउज़र के लिए उपयोगकर्ता नाम</translation>
<translation id="2491120439723279231">सर्वर के प्रमाणपत्र में त्रुटियां हैं.</translation>
+<translation id="2493640343870896922">लेटर-प्लस</translation>
<translation id="2495083838625180221">JSON पार्सर</translation>
-<translation id="2495093607237746763">यदि चेक किया गया हो, तो अधिक तेज़ी से फ़ॉर्म भरने के लिए क्रोमियम इस डिवाइस पर आपके कार्ड की कॉपी संग्रहित करेगा.</translation>
+<translation id="2495093607237746763">अगर चेक किया गया हो, तो ज़्यादा तेज़ी से फ़ॉर्म भरने के लिए क्रोमियम इस डिवाइस पर आपके कार्ड की कॉपी संग्रहित करेगा.</translation>
<translation id="2498091847651709837">नया कार्ड स्‍कैन करें</translation>
<translation id="2501278716633472235">वापस जाएं</translation>
<translation id="2503184589641749290">स्वीकृत डेबिट और प्रीपेड कार्ड</translation>
<translation id="2515629240566999685">अपने इलाके में सिग्नल की जाँच करें</translation>
-<translation id="2516852381693169964">इमेज <ph name="SEARCH_ENGINE" /> पर खोजें</translation>
<translation id="2523886232349826891">सिर्फ़ इस डिवाइस पर सेव किया गया</translation>
<translation id="2524461107774643265">ज़्यादा जानकारी जोड़ें</translation>
<translation id="2536110899380797252">पता जोड़ें</translation>
@@ -273,6 +312,7 @@
<translation id="2587841377698384444">निर्देशिका API (एपीआई) आईडी:</translation>
<translation id="2597378329261239068">यह दस्तावेज़ पासवर्ड सुरक्षित है. कृपया पासवर्ड डालें.</translation>
<translation id="2609632851001447353">विविधताएं</translation>
+<translation id="2618023639789766142">सी10 (एन्वेलप)</translation>
<translation id="2625385379895617796">आपकी घड़ी आगे है</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> का सर्वर आईपी पता नहीं मिल सका.</translation>
<translation id="2639739919103226564">स्थिति:</translation>
@@ -282,7 +322,9 @@
<translation id="2666117266261740852">दूसरे टैब या ऐप्लिकेशन बंद करें</translation>
<translation id="267371737713284912">पहले जैसा करने के लिए <ph name="MODIFIER_KEY_DESCRIPTION" /> दबाएं</translation>
<translation id="2674170444375937751">क्या आप वाकई अपने इतिहास से इन पृष्ठों को हटाना चाहते हैं?</translation>
+<translation id="2676271551327853224">रॉक-8के</translation>
<translation id="2677748264148917807">छोड़ें</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">स्वीकार किए जाने वाले कार्ड</translation>
<translation id="2702801445560668637">पठन सूची</translation>
<translation id="2704283930420550640">मान का प्रारूप से मिलान नहीं होता.</translation>
@@ -299,20 +341,21 @@
<translation id="2742870351467570537">चयनित आइटम निकालें</translation>
<translation id="277133753123645258">शिपिंग का तरीका</translation>
<translation id="277499241957683684">डिवाइस का रिकॉर्ड लापता है</translation>
-<translation id="2781030394888168909">MacOS निर्यात करें</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">कनेक्‍शन रीसेट किया गया था.</translation>
<translation id="2788784517760473862">स्वीकृत क्रेडिट कार्ड</translation>
<translation id="2794233252405721443">साइट अवरोधित है</translation>
<translation id="2799020568854403057">आगे आने वाली साइट में नुकसान पहुंचाने वाले ऐप्लिकेशन हैं</translation>
-<translation id="2799223571221894425">पुन: लॉन्‍च करें</translation>
+<translation id="2799223571221894425">फिर से लॉन्‍च करें</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="2847118875340931228">गुप्त विंडो खोलें</translation>
+<translation id="2850739647070081192">न्योता (एन्वेलप)</translation>
<translation id="2851634818064021665">आपको इस साइट पर जाने की अनुमति लेनी होगी</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="2878424575911748999">ए1</translation>
<translation id="2881276955470682203">कार्ड सेव करें?</translation>
<translation id="2903493209154104877">पते</translation>
<translation id="290376772003165898">क्या पेज <ph name="LANGUAGE" /> भाषा में नहीं है?</translation>
@@ -322,6 +365,7 @@
<translation id="2925673989565098301">डिलीवरी का तरीका</translation>
<translation id="2928905813689894207">बिलिंग पता</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">सरकारी-पत्र</translation>
<translation id="2941952326391522266">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र <ph name="DOMAIN2" /> की ओर से है. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="2948083400971632585">आप किसी कनेक्शन के लिए कॉन्फ़िगर की गई किसी भी प्रॉक्सी को सेटिंग पेज से बंद कर सकते हैं.</translation>
<translation id="2955913368246107853">खोज बार बंद करें</translation>
@@ -329,7 +373,7 @@
<translation id="2972581237482394796">&amp;फिर से करें</translation>
<translation id="2977665033722899841"><ph name="ROW_NAME" />, इस समय चुना गया है. <ph name="ROW_CONTENT" /></translation>
<translation id="2982481275546140226">डेटा हटाएं</translation>
-<translation id="2985306909656435243">यदि सक्षम किया गया हो, तो अधिक तेज़ी से फ़ॉर्म भरने के लिए क्रोमियम इस डिवाइस पर आपके कार्ड की एक कॉपी संग्रहित करेगा.</translation>
+<translation id="2985306909656435243">अगर सक्षम किया गया हो, तो ज़्यादा तेज़ी से फ़ॉर्म भरने के लिए क्रोमियम इस डिवाइस पर आपके कार्ड की एक कॉपी संग्रहित करेगा.</translation>
<translation id="2985398929374701810">मान्य पता डालें</translation>
<translation id="2986368408720340940">पिकअप का यह तरीका उपलब्ध नहीं है. कोई दूसरा तरीका आज़माएं.</translation>
<translation id="2991174974383378012">वेबसाइटों के साथ साझाकरण</translation>
@@ -338,11 +382,14 @@
<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="3023071826883856138">यू4 (एन्वेलप)</translation>
<translation id="3024663005179499861">गलत नीति प्रकार</translation>
<translation id="3037605927509011580">हे भगवान!</translation>
<translation id="3041612393474885105">प्रमाणपत्र जानकारी</translation>
+<translation id="3060227939791841287">सी9 (एन्वेलप)</translation>
<translation id="3064966200440839136">किसी बाहरी ऐप्लिकेशन के ज़रिए भुगतान करने के लिए गुप्त मोड छोड़ रहे हैं. जारी रखना चाहते हैं?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{कुछ नहीं}=1{1 पासवर्ड}one{# पासवर्ड}other{# पासवर्ड}}</translation>
+<translation id="3095940652251934233">जानकारी</translation>
<translation id="3096100844101284527">पिकअप का पता जोड़ें</translation>
<translation id="3105172416063519923">एसेट आईडी:</translation>
<translation id="3109728660330352905">आपके पास इस पेज को देखने के लिए प्राधिकरण नहीं है.</translation>
@@ -358,26 +405,27 @@
<translation id="3169472444629675720">तलाश करें</translation>
<translation id="3174168572213147020">द्वीप</translation>
<translation id="3176929007561373547">यह सुनिश्चित करने के लिए कि प्रॉक्सी सर्वर काम कर रहा है,
- अपनी प्रॉक्सी सेटिंग जाँचें या अपने नेटवर्क व्यवस्थापक से संपर्क करें. यदि आपको विश्वास नहीं हो
+ अपनी प्रॉक्सी सेटिंग जाँचें या अपने नेटवर्क व्यवस्थापक से संपर्क करें. अगर आपको विश्वास नहीं हो
कि आप किसी प्रॉक्सी सर्वर का उपयोग कर रहे हैं, तो:
<ph name="PLATFORM_TEXT" /></translation>
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> पर <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">भुगतान रद्द करें</translation>
<translation id="3207960819495026254">बुकमार्क किया गया</translation>
-<translation id="3209375525920864198">कृपया सत्र का मान्य नाम डालें.</translation>
+<translation id="321912867715453276">चेतावनीः इस नीति के लिए, एक से ज़्यादा स्रोत मौजूद हैं, लेकिन इनके मान एक जैसे हैं.</translation>
<translation id="3225919329040284222">सर्वर द्वारा कोई प्रमाणपत्र प्रस्‍तुत किया गया, जो बिल्‍ट-इन अपेक्षाओं से मिलान नहीं करता. इन अपेक्षाओं को आपकी सुरक्षा करने के लिए कुछ, उच्‍च-सुरक्षा वेबसाइटों के लिए शामिल किया गया है.</translation>
<translation id="3226128629678568754">पेज को लोड करने के लिए ज़रूरी डेटा फिर सबमिट करने के लिए फिर लोड करें बटन दबाएं.</translation>
<translation id="3227137524299004712">माइक्रोफ़ोन</translation>
<translation id="3228969707346345236">अनुवाद विफल हो गया क्योंकि पेज पहले से ही <ph name="LANGUAGE" /> में है.</translation>
+<translation id="3229041911291329567">आपके डिवाइस और ब्राउज़र के वर्शन के बारे में जानकारी</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="3274521967729236597">पा-काई</translation>
<translation id="3282497668470633863">कार्ड पर नाम जोड़ें</translation>
<translation id="3287510313208355388">ऑनलाइन होने पर डाउनलोड करें</translation>
-<translation id="3293642807462928945"><ph name="POLICY_NAME" /> नीति के बारे में अधिक जानें</translation>
+<translation id="3293642807462928945"><ph name="POLICY_NAME" /> नीति के बारे में ज़्यादा जानें</translation>
<translation id="3303855915957856445">कोई खोज परिणाम नहीं मिला</translation>
-<translation id="3305707030755673451">आपका डेटा आपके समन्वयन पासफ़्रेज़ के साथ <ph name="TIME" /> को एन्क्रिप्ट किया गया था. समन्वयन शुरू करने के लिए इसे डालें.</translation>
<translation id="3320021301628644560">बिलिंग पता जोड़ें</translation>
<translation id="3324983252691184275">गहरा लाल</translation>
<translation id="3338095232262050444">सुरक्षित</translation>
@@ -404,12 +452,14 @@
<translation id="3427092606871434483">अनुमति दें (डिफ़ॉल्ट)</translation>
<translation id="3427342743765426898">&amp;संपादित करना फिर से करें</translation>
<translation id="342781501876943858">अगर आपने अपने पासवर्ड का दूसरी साइटों पर दोबारा इस्तेमाल किया है, तो क्रोमियम आपको उसे रीसेट करने का सुझाव देता है.</translation>
-<translation id="3431636764301398940">इस कार्ड को इस डिवाइस पर सहेजें</translation>
+<translation id="3431636764301398940">इस कार्ड को इस डिवाइस पर सेव करें</translation>
+<translation id="3443726618221119081">जूरो-कु-काई</translation>
<translation id="3447661539832366887">इस डिवाइस के मालिक ने डायनासोर गेम को बंद कर दिया है.</translation>
<translation id="3447884698081792621">प्रमाणपत्र (<ph name="ISSUER" /> की ओर से जारी किया गया) दिखाएं</translation>
<translation id="3452404311384756672">प्राप्ति अंतराल:</translation>
+<translation id="3456231139987291353">संख्या-11 (एन्वेलप)</translation>
<translation id="3461824795358126837">हाइलाइटर</translation>
-<translation id="3462200631372590220">उन्नत को छिपाएं</translation>
+<translation id="3462200631372590220">बेहतर को छिपाएं</translation>
<translation id="3467763166455606212">कार्ड मालिक का नाम ज़रूरी है</translation>
<translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, फ़िलहाल खुला है, 'टैब' दबाएं फिर खुले टैब पर जाने के लिए Enter दबाएं</translation>
<translation id="3479539252931486093">क्या यह अनपेक्षित था? <ph name="BEGIN_LINK" />हमें बताएं<ph name="END_LINK" /></translation>
@@ -417,7 +467,7 @@
<translation id="3484560055331845446">आप अपने Google खाते का एक्सेस खो सकते हैं. Chrome आपको इसी समय अपना पासवर्ड बदलने का सुझाव देता है. आपको साइन इन करने को कहा जाएगा.</translation>
<translation id="3495081129428749620">पेज में ढूंढें
<ph name="PAGE_TITLE" /></translation>
-<translation id="3498215018399854026">हम इस समय आपके अभिभावक तक नहीं पहुंच पा रहे हैं. कृपया पुन: प्रयास करें.</translation>
+<translation id="3498215018399854026">हम इस समय आपके अभिभावक तक नहीं पहुंच पा रहे हैं. कृपया फिर से प्रयास करें.</translation>
<translation id="3528171143076753409">सर्वर का प्रमाणपत्र विश्वसनीय नहीं है.</translation>
<translation id="3528485271872257980">गहरा भूरा</translation>
<translation id="3530944546672790857">{COUNT,plural, =0{सिंक किए हुए डिवाइस पर कम से कम 1 आइटम}=1{1 आइटम (सिंक किए हुए डिवाइस पर और भी बहुत कुछ)}one{# आइटम (सिंक किए हुए डिवाइस पर और भी बहुत कुछ)}other{# आइटम (सिंक किए हुए डिवाइस पर और भी बहुत कुछ)}}</translation>
@@ -430,20 +480,23 @@
<translation id="358285529439630156">क्रेडिट और प्रीपेड कार्ड स्वीकार किए जाते हैं.</translation>
<translation id="3582930987043644930">नाम जोड़ें</translation>
<translation id="3583757800736429874">&amp;ले जाना फिर से करें</translation>
+<translation id="35866233670761917">आपके एडमिन ऐसी वेबसाइटों की सामग्री नहीं देखते जिन पर आप जाते हैं</translation>
<translation id="3586931643579894722">विवरण छुपाएं</translation>
+<translation id="3592413004129370115">इटैलियन (एन्वेलप)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">आकार 2</translation>
<translation id="3615877443314183785">खत्म होने की मान्य तारीख डालें</translation>
<translation id="36224234498066874">ब्राउज़िंग डेटा साफ़ करें...</translation>
<translation id="362276910939193118">पूरा इतिहास दिखाएं</translation>
-<translation id="3623476034248543066">मान दिखाएं</translation>
-<translation id="3630155396527302611">यदि वह नेटवर्क एक्सेस करने की अनुमति प्राप्त प्रोग्राम के रूप में पहले से सूचीबद्ध है, तो
- उसे सूची से निकालें और पुन: जोड़कर देखें.</translation>
+<translation id="3630155396527302611">अगर वह नेटवर्क एक्सेस करने की अनुमति प्राप्त प्रोग्राम के रूप में पहले से सूचीबद्ध है, तो
+ उसे सूची से निकालें और फिर से जोड़कर देखें.</translation>
+<translation id="3640766068866876100">इंडेक्स-4x6-एक्स्ट्रा</translation>
<translation id="3650584904733503804">मान्यकरण सफल</translation>
-<translation id="3655670868607891010">यदि आपको यह बार-बार दिखाई दे रहा हो, तो इन <ph name="HELP_LINK" /> को आज़माएं.</translation>
+<translation id="3655670868607891010">अगर आपको यह बार-बार दिखाई दे रहा हो, तो इन <ph name="HELP_LINK" /> को आज़माएं.</translation>
<translation id="3658742229777143148">पुनरीक्षण</translation>
<translation id="366077651725703012">क्रेडिट कार्ड अपडेट करें</translation>
<translation id="3676592649209844519">डिवाइस आईडी:</translation>
+<translation id="3677008721441257057">क्या आपका मतलब &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; से था?</translation>
<translation id="3678029195006412963">अनुरोध पर हस्ताक्षर नहीं किया जा सका</translation>
<translation id="3678529606614285348">पेज को नई गुप्त विंडो में खोलें (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">ख़राबी रिपोर्ट <ph name="CRASH_TIME" /> पर कैप्चर की गई, <ph name="UPLOAD_TIME" /> पर अपलोड की गई</translation>
@@ -451,16 +504,17 @@
<translation id="3704162925118123524">आप जिस नेटवर्क का उपयोग कर रहे हैं उसके लिए आपको लॉगिन पेज पर जाने की ज़रूरत हो सकती है.</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>
+<translation id="3709599264800900598">आपका कॉपी किया हुआ टेक्स्ट</translation>
+<translation id="3712624925041724820">लाइसेंस खत्म हो गए</translation>
<translation id="3714780639079136834">मोबाइल डेटा या वाई-फ़ाई चालू करें</translation>
<translation id="3715597595485130451">वाई-फ़ाई से कनेक्ट करें</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />प्रॉक्सी, फायरवॉल और DNS कॉन्फ़िगरेशन की जाँच करें<ph name="END_LINK" /></translation>
<translation id="372429172604983730">जिन ऐप्लिकेशन की वजह से यह गड़बड़ी हो सकती है उनमें एंटीवायरस, फ़ायरवॉल और वेब-फ़िल्टरिंग या प्रॉक्सी सॉफ़्टवेयर शामिल हैं.</translation>
+<translation id="373042150751172459">बी4 (एन्वेलप)</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="3745099705178523657">आपके पुष्टि करने के बाद, आपके Google खाते के कार्ड का ब्यौरा इस साइट से शेयर किया जाएगा.</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="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="3761718714832595332">स्थिति छिपाएं</translation>
@@ -470,17 +524,20 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /> में खत्म होगा</translation>
<translation id="3789155188480882154">आकार 16</translation>
+<translation id="3797522431967816232">पीआरसी3 (एन्वेलप)</translation>
<translation id="3807873520724684969">खतरनाक सामग्री ब्लॉक की गई.</translation>
<translation id="3810973564298564668">प्रबंधित करें</translation>
-<translation id="382518646247711829">यदि आप प्रॉक्सी सर्वर का उपयोग करते हैं...</translation>
+<translation id="382518646247711829">अगर आप प्रॉक्सी सर्वर का उपयोग करते हैं...</translation>
<translation id="3828924085048779000">खाली पासफ़्रेज़ की अनुमति नहीं है.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ने और सुविधाओं के लिए एक्सटेंशन इंस्टॉल किया है. एक्सटेंशन आपका कुछ डेटा एक्सेस कर सकते हैं.</translation>
<translation id="385051799172605136">वापस</translation>
-<translation id="3858027520442213535">दिनांक और समय अपडेट करें</translation>
+<translation id="3858027520442213535">तारीख और समय अपडेट करें</translation>
<translation id="3884278016824448484">विरोधाभासी डिवाइस पहचानकर्ता</translation>
<translation id="3885155851504623709">पैरिश</translation>
<translation id="3886446263141354045">यह साइट एक्सेस करने का आपका अनुरोध <ph name="NAME" /> को भेज दिया गया है</translation>
<translation id="3890664840433101773">ईमेल जोड़ें</translation>
<translation id="3901925938762663762">इस कार्ड की समय सीमा समाप्‍त हो गई है</translation>
+<translation id="3906600011954732550">बी5-एक्स्ट्रा</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">इस साइट पर हमेशा पूछें</translation>
<translation id="3949571496842715403">यह सर्वर प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सुरक्षा प्रमाणपत्र में विषय के वैकल्पिक नाम नहीं बताए गए हैं. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता की ओर से आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
@@ -491,18 +548,20 @@
<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="3984550557525787191">यह सत्र नाम पहले से मौजूद है.</translation>
<translation id="3987940399970879459">एक एमबी से कम</translation>
+<translation id="4008849406247176967">चेतावनीः इस नीति के लिए एक-दूसरे से अलग मानों वाले एक से ज़्यादा स्रोत मौजूद हैं!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{आस-पास 1 वेब पेज है}one{आस-पास # वेब पेज हैं}other{आस-पास # वेब पेज हैं}}</translation>
<translation id="4030383055268325496">&amp;जोड़ना वापस लाएं</translation>
+<translation id="4032320456957708163">आपके ब्राउज़र को <ph name="ENROLLMENT_DOMAIN" /> प्रबंधित करता है</translation>
<translation id="4058922952496707368">कुंजी "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">सी1 (एन्वेलप)</translation>
<translation id="4067947977115446013">मान्य पता जोड़ें</translation>
<translation id="4072486802667267160">आपका आदेश संसाधित करते समय गड़बड़ी हुई. कृपया फिर से कोशिश करें.</translation>
<translation id="4075732493274867456">क्लाइंट और सर्वर, सामान्य SSL प्रोटोकॉल वर्शन या सिफ़र सुइट का समर्थन नहीं करते हैं.</translation>
<translation id="4079302484614802869">प्रॉक्‍सी कॉन्‍फ़िगरेशन को .pac स्‍क्रिप्‍ट यूआरएल का उपयोग करने के लिए सेट किया जाता है, फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर के लिए नहीं.</translation>
<translation id="4098354747657067197">आगे भ्रामक साइट है</translation>
<translation id="4103249731201008433">डिवाइस की क्रम संख्या गलत है</translation>
-<translation id="410351446219883937">स्वतः चलाएं</translation>
+<translation id="410351446219883937">अपने आप चलाएं</translation>
<translation id="4103763322291513355">प्रतिबंधित किए गए यूआरएल और आपके सिस्टम ए़़डमिन ने जिन अन्य नीतियों को लागू किया है, उन्हें देखने के लिए &lt;strong&gt;chrome://policy&lt;/strong&gt; पर जाएं.</translation>
<translation id="4110652170750985508">अपना भुगतान देखें</translation>
<translation id="4116663294526079822">इस साइट पर हमेशा अनुमति दें</translation>
@@ -515,10 +574,12 @@
<translation id="4159784952369912983">बैंगनी</translation>
<translation id="4165986682804962316">साइट सेटिंग</translation>
<translation id="4171400957073367226">गलत सत्यापन हस्ताक्षर</translation>
+<translation id="4173315687471669144">फ़ूल्ज़कैप</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> और आइटम}one{<ph name="ITEM_COUNT" /> और आइटम}other{<ph name="ITEM_COUNT" /> और आइटम}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ले जाना फिर से करें</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />फायरवॉल और एंटीवायरस कॉन्फ़िगरेशन की जाँच करें<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (एन्वेलप)</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="4221630205957821124">&lt;h4&gt;कदम 1: पोर्टल में साइन इन करें&lt;/h4&gt;
@@ -537,7 +598,7 @@
&lt;p&gt;समस्या को ठीक करने के लिए, अपना एंटीवायरस सॉफ़्टवेयर बंद करें. अगर सॉफ़्टवेयर बंद करने के बाद पेज काम करता है तो, सुरक्षित साइटों का इस्तेमाल करते समय इस सॉफ़्टवेयर को बंद कर दें.&lt;/p&gt;
&lt;p&gt;जब आपका काम हो जाए तो अपना एंटीवायरस प्रोग्राम वापस चालू करना न भूलें.&lt;/p&gt;
&lt;h4&gt;कदम 5: ज़्यादा मदद पाएं&lt;/h4&gt;
- &lt;p&gt;अगर आपको अभी भी गड़बड़ी दिखाई दे रही है तो, वेबसाइट के मालिक से संपर्क करें.&lt;/p&gt;</translation>
+ &lt;p&gt;अगर आपको अब भी गड़बड़ी दिखाई दे रही है तो, वेबसाइट के मालिक से संपर्क करें.&lt;/p&gt;</translation>
<translation id="4226937834893929579"><ph name="BEGIN_LINK" />नेटवर्क निदान चलाकर देखें<ph name="END_LINK" />.</translation>
<translation id="4235360514405112390">मान्य</translation>
<translation id="4250431568374086873">इस साइट से आपका कनेक्शन पूरी तरह से सुरक्षित नहीं है</translation>
@@ -546,62 +607,83 @@
<translation id="4258748452823770588">खराब हस्ताक्षर</translation>
<translation id="4261046003697461417">सुरक्षित दस्तावेज़ों को एनोटेट नहीं किया जा सकता</translation>
<translation id="4265872034478892965">आपके व्यवस्थापक ने अनुमति दी है</translation>
-<translation id="4275830172053184480">अपना डिवाइस पुन: प्रारंभ करें</translation>
+<translation id="4275830172053184480">अपना डिवाइस फिर से प्रारंभ करें</translation>
<translation id="4277028893293644418">पासवर्ड रीसेट करें</translation>
-<translation id="4280429058323657511">, समाप्ति दिनांक <ph name="EXPIRATION_DATE_ABBR" /></translation>
+<translation id="4280429058323657511">, समाप्ति तारीख <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{यह कार्ड आपके Google खाते में सेव कर लिया गया है}one{ये कार्ड आपके Google खाते में सेव कर लिए गए हैं}other{ये कार्ड आपके Google खाते में सेव कर लिए गए हैं}}</translation>
+<translation id="42981349822642051">विस्तृत करें</translation>
+<translation id="4302965934281694568">शू3 (एन्वेलप)</translation>
<translation id="4305817255990598646">बदलें</translation>
+<translation id="4312613361423056926">बी2</translation>
<translation id="4312866146174492540">अवरुद्ध करें (डिफ़ॉल्ट)</translation>
+<translation id="4318566738941496689">आपके डिवाइस का नाम और नेटवर्क का पता</translation>
<translation id="4325863107915753736">लेख ढूंढ़ने में विफल</translation>
-<translation id="4326324639298822553">अपना समाप्ति दिनांक जाँचें और फिर से कोशिश करें</translation>
+<translation id="4326324639298822553">अपना समाप्ति तारीख जाँचें और फिर से कोशिश करें</translation>
<translation id="4331708818696583467">सुरक्षित नहीं है</translation>
<translation id="4340982228985273705">इस कंप्यूटर की पहचान एंटरप्राइज़ की ओर से प्रबंधित होने के रूप में नहीं की गई है इसलिए नीति सिर्फ़ Chrome वेबस्टोर पर होस्ट किए जाने वाले एक्सटेंशन ही अपने आप इंस्टॉल कर सकती है. Chrome वेबस्टोर अपडेट यूआरएल "<ph name="CWS_UPDATE_URL" />" है.</translation>
<translation id="4346197816712207223">स्वीकार किए जाने वाले क्रेडिट कार्ड</translation>
+<translation id="4346833872170306413">आरओसी-16के</translation>
<translation id="4356973930735388585">इस साइट पर मौजूद हमलावर आपके कंप्यूटर पर ऐसे खतरनाक प्रोग्राम इंस्टॉल करने की कोशिश कर सकते हैं जो आपकी जानकारी (उदाहरण के लिए, फ़ोटो, पासवर्ड, संदेश और क्रेडिट कार्ड) चुरा लेते हैं या उसे हटा देते हैं.</translation>
<translation id="4358461427845829800">भुगतान विधियां प्रबंधित करें...</translation>
+<translation id="4367563149485757821">संख्या-12 (एन्वेलप)</translation>
+<translation id="4372516964750095882">फ़ैनफ़ोल्ड-यूएस</translation>
<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE" /> मान.</translation>
<translation id="4377125064752653719">आपने <ph name="DOMAIN" /> तक पहुंचने का प्रयास किया, लेकिन सर्वर द्वारा प्रस्तुत प्रमाणपत्र को उसके जारीकर्ता द्वारा रद्द कर दिया गया है. इसका अर्थ है कि सर्वर द्वारा प्रस्तुत सुरक्षा प्रमाणिकता पर पूर्णतया विश्वास नहीं करना चाहिए. हो सकता है कि आप किसी हमलावर से बातचीत कर रहे हों.</translation>
<translation id="4378154925671717803">फ़ोन</translation>
<translation id="4406896451731180161">खोज परिणाम</translation>
-<translation id="4406972042435603828">आपके एडमिन ने ज़्याद क्षमताओं वाले एक्सटेंशन इंस्टॉल किए हैं.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> कुकी</translation>
<translation id="4415426530740016218">पिकअप का पता</translation>
<translation id="4424024547088906515">यह सर्वर यह नहीं प्रमाणित कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाणपत्र Chrome द्वारा विश्वसनीय नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="443121186588148776">सीरियल पोर्ट</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ने आपका लॉगिन प्रमाणपत्र स्वीकार नहीं किया है या हो सकता है कि प्रमाणपत्र उपलब्ध नहीं कराया गया हो.</translation>
<translation id="4434045419905280838">पॉप-अप और रीडायरेक्ट</translation>
+<translation id="4435702339979719576">पोस्टकार्ड)</translation>
<translation id="443673843213245140">प्रॉक्‍सी का उपयोग अक्षम है लेकिन कोई स्‍पष्ट प्रॉक्‍सी कॉन्फ़िगरेशन निर्दिष्ट किया गया है.</translation>
<translation id="445100540951337728">स्वीकृत डेबिट कार्ड</translation>
+<translation id="4466881336512663640">फ़ॉर्म में किए गए बदलाव हटा दिए जाएँगे. क्या आप वाकई जारी रखना चाहते हैं?</translation>
<translation id="4482953324121162758">इस साइट का अनुवाद नहीं किया जाएगा.</translation>
+<translation id="4490717597759821841">ए7</translation>
+<translation id="4493480324863638523">यूआरएल गलत है. यूआरएल में सामान्य स्कीम, जैसे कि, http://example.com या https://example.com.ज़रूर होनी चाहिए.</translation>
+<translation id="4503882053543859973">आर्किटेक्चर-डी</translation>
<translation id="4506176782989081258">सत्‍यापन गड़बड़ी: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">सिस्टम व्यवस्थापक से संपर्क करें</translation>
<translation id="450710068430902550">व्यवस्थापक के साथ शेयर करना</translation>
+<translation id="4510487217173779431">शू4 (एन्वेलप)</translation>
<translation id="4515275063822566619">कार्ड और पते की जानकारी Chrome और आपके Google खाते (<ph name="ACCOUNT_EMAIL" />) से ली जाती है. आप उन्हें <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में जाकर प्रबंधित कर सकते हैं.</translation>
+<translation id="4517607026994743406">कॉम-10 (एन्वेलप)</translation>
<translation id="4522570452068850558">विवरण</translation>
<translation id="4524805452350978254">कार्ड प्रबंधित करें</translation>
+<translation id="455113658016510503">ए9</translation>
<translation id="4552089082226364758">फ़्लैश</translation>
<translation id="4558551763791394412">अपने एक्सटेंशन अक्षम करके देखें.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">वितरण</translation>
+<translation id="4579056131138995126">निजी (एन्वेलप)</translation>
<translation id="4582204425268416675">कार्ड हटाएं</translation>
<translation id="4587425331216688090">Chrome से पता निकालें?</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> से आपके कनेक्शन को किसी आधुनिक सिफ़र सुइट का उपयोग करके एन्‍क्रिप्‍ट किया गया है.</translation>
<translation id="4594403342090139922">&amp;हटाना वापस लाएं</translation>
<translation id="4597348597567598915">आकार 8</translation>
+<translation id="4600854749408232102">सी6/सी5 (एन्वेलप)</translation>
<translation id="4646534391647090355">मुझे अभी वहां ले जाएं</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसके सुरक्षा प्रमाणपत्र में त्रुटियां हैं. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="467809019005607715">Google स्लाइड</translation>
<translation id="4690462567478992370">अमान्य प्रमाणपत्र का उपयोग करना बंद करें</translation>
+<translation id="4691835149146451662">आर्किटेक्चर-ए (एन्वेलप)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">आपका कनेक्शन बाधित था</translation>
<translation id="471880041731876836">आपको इस साइट पर जाने की अनुमति नहीं है</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows नेटवर्क निदान चलाकर देखें<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">नीतियां फिर से लोड करें</translation>
<translation id="4728558894243024398">प्लेटफ़ॉर्म</translation>
+<translation id="4731967714531604179">पीआरसी2 (एन्वेलप)</translation>
<translation id="4736825316280949806">क्रोमियम को फिर से शुरू करें</translation>
<translation id="473775607612524610">अपडेट करें</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> खोज सुझाव</translation>
<translation id="4742407542027196863">पासवर्ड प्रबंधित करें…</translation>
<translation id="4744603770635761495">निष्पादन-योग्य पथ</translation>
+<translation id="4746351372139058112">संदेश</translation>
<translation id="4750917950439032686">आपकी जानकारी (जैसे- पासवर्ड या क्रेडिट कार्ड नंबर वगैरह) जब इस साइट पर भेजी जाती है, तब वह निजी होती है.</translation>
<translation id="4756388243121344051">&amp;इतिहास</translation>
<translation id="4758311279753947758">संपर्क जानकारी जोड़ें</translation>
@@ -609,9 +691,9 @@
<translation id="4764776831041365478"><ph name="URL" /> पर मौजूद वेबपेज संभवतः अस्थायी रूप से बंद है या उसे स्थायी रूप से किसी नए वेब पते पर ले जाया गया है.</translation>
<translation id="4771973620359291008">अज्ञात गड़बड़ी आई.</translation>
<translation id="4785689107224900852">इस टैब पर जाएं</translation>
-<translation id="4792143361752574037">सत्र फ़ाइलें एक्सेस करते समय कोई समस्या हुई. फ़िलहाल डिस्क में सेव करने की सुविधा बंद है. दोबारा कोशिश करने के लिए कृपया पेज फिर से लोड करें.</translation>
<translation id="4798078619018708837">अपने कार्ड का ब्यौरा अपडेट करने के लिए <ph name="CREDIT_CARD" /> की खत्म होने की तारीख और कार्ड वेरीफ़िकेशन कोड (सीवीसी) डालें. आपके पुष्टि करने के बाद, आपके Google खाते के कार्ड का ब्यौरा इस साइट के साथ शेयर किया जाएगा.</translation>
-<translation id="4800132727771399293">अपना अवधि समाप्‍ति दिनांक और CVC जाँचें और पुन: प्रयास करें</translation>
+<translation id="4800132727771399293">अपना अवधि समाप्‍ति तारीख और CVC जाँचें और फिर से प्रयास करें</translation>
+<translation id="480334179571489655">शुरुआत की जगह की नीति में गड़बड़ी</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>
@@ -626,7 +708,6 @@
<translation id="4881695831933465202">खोलें</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>
@@ -635,15 +716,15 @@
<translation id="4943872375798546930">कोई परिणाम नहीं</translation>
<translation id="4950898438188848926">'टैब' बदलने का बटन, नए टैब पर जाने के लिए Enter दबाएं, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">क्रियाएं</translation>
-<translation id="495832697253704892">एक्सटेंशन रिपोर्टिंग</translation>
+<translation id="4955242332710481440">ए5-एक्स्ट्रा</translation>
<translation id="4958444002117714549">सूची विस्तृत करें</translation>
<translation id="4974590756084640048">चेतावनियां फिर से सक्षम करें</translation>
+<translation id="4984339528288761049">पीआरसी5 (एन्वेलप)</translation>
<translation id="4989163558385430922">सभी देखें</translation>
<translation id="4989809363548539747">यह प्लग इन समर्थित नहीं है</translation>
-<translation id="4996230189582812866">रिपोर्ट करना</translation>
-<translation id="5002932099480077015">यदि सक्षम किया हुआ हो, तो Chrome फ़ॉर्म को तेज़ी से भरने के लिए इस डिवाइस पर आपके कार्ड की एक प्रति संग्रहित करेगा.</translation>
-<translation id="5014174725590676422">'Chrome में Google Assistant' की सबसे पहली स्क्रीन दिखाई गई है</translation>
+<translation id="5002932099480077015">अगर सक्षम किया हुआ हो, तो Chrome फ़ॉर्म को तेज़ी से भरने के लिए इस डिवाइस पर आपके कार्ड की एक प्रति संग्रहित करेगा.</translation>
<translation id="5015510746216210676">मशीन का नाम:</translation>
+<translation id="5017554619425969104">आपका कॉपी किया हुआ टेक्स्ट</translation>
<translation id="5018422839182700155">यह पेज खुल नहीं पा रहा है</translation>
<translation id="5019198164206649151">बैकिंग संग्रह खराब स्थिति में है</translation>
<translation id="5023310440958281426">अपने व्यवस्थापक की नीतियां देखें</translation>
@@ -653,35 +734,51 @@
<translation id="5034369478845443529">स्थानीय संदर्भ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">अनुमति दें</translation>
<translation id="5040262127954254034">निजता</translation>
+<translation id="5043480802608081735">आपका कॉपी किया हुआ लिंक</translation>
<translation id="5045550434625856497">ग़लत पासवर्ड</translation>
<translation id="5056549851600133418">आपके लिए लेख</translation>
+<translation id="5068524481479508725">ए10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />प्रॉक्सी पते की जाँच करें<ph name="END_LINK" /></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="5097099694988056070">डिवाइस के आंकड़े जैसे कि सीपीयू (CPU)/RAM का इस्तेमाल</translation>
+<translation id="5097501891273180634">ए2</translation>
<translation id="5098222253617183465">आपके डिवाइस को <ph name="ENROLLMENT_DOMAIN" /> की ओर से प्रबंधित किया जाता है और आपके खाते को <ph name="ACCOUNT_DOMAIN" /> की ओर से प्रबंधित किया जाता है. इसका मतलब है कि आपके एडमिन दूर रहकर आपके डिवाइस और खाते को कॉन्फ़िगर कर सकते हैं.</translation>
+<translation id="5112422516732747637">ए5</translation>
+<translation id="5115216390227830982">यूरोपियन-ईडीपी</translation>
<translation id="5115563688576182185">(64-बिट)</translation>
-<translation id="5128122789703661928">इस नाम वाला सीज़न मिटाने के लिए मान्य नहीं है.</translation>
+<translation id="5125394840236832993">बी-प्लस</translation>
<translation id="5135404736266831032">पते प्रबंधित करें...</translation>
+<translation id="5138227688689900538">कम दिखाएं</translation>
<translation id="5141240743006678641">समन्वयित पासवर्ड अपने Google प्रमाणिकता के साथ एन्क्रिप्ट करें</translation>
<translation id="5145883236150621069">नीति प्रतिसाद में गड़बड़ी कोड मौजूद है</translation>
+<translation id="515292512908731282">सी4 (एन्वेलप)</translation>
<translation id="5159010409087891077">पेज को नई गुप्त विंडो में खोलें (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> का कार्ड वेरीफ़िकेशन कोड (सीवीसी) डालें. आपके पुष्टि करने के बाद, आपके Google खाते के कार्ड का ब्यौरा इस साइट के साथ शेयर किया जाएगा.</translation>
<translation id="5169827969064885044">आप अपने संगठन के खाते का एक्सेस खो सकते हैं या आपकी पहचान चोरी हो सकती है. Chrome आपको इसी समय अपना पासवर्ड बदलने का सुझाव देता है.</translation>
<translation id="5171045022955879922">URL खोजें या लिखें</translation>
+<translation id="5171689220826475070">फ़ैनफ़ोल्ड-यूरोपियन</translation>
<translation id="5172758083709347301">मशीन</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> में नहीं है? इस गड़बड़ी की रिपोर्ट करें</translation>
<translation id="5190835502935405962">बुकमार्क बार</translation>
-<translation id="5200263511887412697">हाल ही में लॉग इन करने वाले डिवाइस उपयोगकर्ताओं की रिपोर्ट सूची</translation>
+<translation id="519422657042045905">व्याख्या की सुविधा उपलब्ध नहीं है</translation>
<translation id="5201306358585911203">इस पेज पर एम्बेड किए गए पेज का कहना है कि</translation>
<translation id="5205222826937269299">नाम ज़रूरी है</translation>
<translation id="5215116848420601511">Google Pay का इस्तेमाल करने वाले भुगतान के तरीके और पते</translation>
+<translation id="5215363486134917902">फ़ोलियो-एसपी</translation>
<translation id="5222812217790122047">ईमेल आवश्यक है</translation>
<translation id="5230733896359313003">शिपिंग पता</translation>
+<translation id="5230815978613972521">बी8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"नेटवर्क से कनेक्ट करें"</translation>
<translation id="5251803541071282808">क्लाउड</translation>
+<translation id="5252000469029418751">सी7 (एन्वेलप)</translation>
+<translation id="5254958791078852567">ई1</translation>
+<translation id="5283044957620376778">बी1</translation>
+<translation id="5284909709419567258">नेटवर्क के पते</translation>
<translation id="5285570108065881030">सेव किए गए सभी पासवर्ड दिखाएं</translation>
<translation id="5287240709317226393">कुकी दिखाएं</translation>
<translation id="5288108484102287882">नीति मानों की पुष्टि से चेतावनियां मिली हैं</translation>
@@ -693,14 +790,17 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> में से <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">संपर्क जानकारी चुनें</translation>
<translation id="5327248766486351172">नाम</translation>
+<translation id="5329858041417644019">आपका ब्राउज़र प्रबंधित नहीं है</translation>
<translation id="5332219387342487447">शिपिंग का तरीका</translation>
+<translation id="5334013548165032829">सिस्टम लॉग की ज़्यादा जानकारी</translation>
<translation id="5344579389779391559">यह पेज आपसे शुल्क लेने की कोशिश कर सकता है</translation>
<translation id="5355557959165512791">आप इस समय <ph name="SITE" /> पर नहीं जा सकते हैं क्योंकि उसका प्रमाणपत्र रद्द कर दिया गया है. नेटवर्क की गड़बड़ी और हमले आमतौर पर कुछ देर के लिए होते हैं, इसलिए मुमकिन है कि यह पेज बाद में काम करे.</translation>
<translation id="536296301121032821">नीति सेटिंग संग्रहित करने में विफल</translation>
<translation id="5371425731340848620">कार्ड अपडेट करें</translation>
<translation id="5377026284221673050">"आपकी घड़ी पीछे चल रही है" या "आपकी घड़ी आगे चल रही है" या "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">सभी डिवाइस पर अपने कार्ड का इस्तेमाल करने के लिए, साइन इन करें और 'सिंक करें' चालू करें.</translation>
-<translation id="5386426401304769735">इस साइट की प्रमाणपत्र श्रृंखला में, SHA-1 का उपयोग करके हस्ताक्षर किया गया प्रमाणपत्र शामिल है.</translation>
+<translation id="5386426401304769735">इस साइट की प्रमाणपत्र शृंखला में, SHA-1 का उपयोग करके हस्ताक्षर किया गया प्रमाणपत्र शामिल है.</translation>
+<translation id="538659543871111977">ए4-टैब</translation>
<translation id="540969355065856584">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; इसका सुरक्षा प्रमाण पत्र इस समय मान्य नहीं है. ऐसा गलत कॉन्फ़िगरेशन या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
<translation id="5421136146218899937">ब्राउज़िंग डेटा साफ़ करें...</translation>
<translation id="5430298929874300616">बुकमार्क निकालें</translation>
@@ -711,6 +811,7 @@
<translation id="5457113250005438886">अमान्य</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;संपादित करना फिर से करें</translation>
+<translation id="5478437291406423475">बी6/सी4 (एन्वेलप)</translation>
<translation id="5481076368049295676">यह सामग्री आपके डिवाइस पर ऐसा खतरनाक सॉफ़्टवेयर इंस्टॉल करने की कोशिश कर सकती है जो आपकी जानकारी चुरा सकता है या उसे हटा सकता है. <ph name="BEGIN_LINK" />फिर भी दिखाएं<ph name="END_LINK" /></translation>
<translation id="54817484435770891">मान्य पता जोड़ें</translation>
<translation id="5490432419156082418">पते वगैरह</translation>
@@ -718,15 +819,17 @@
<ph name="LINE_BREAK" />
अपने सिस्टम एडमिन से संपर्क करने की कोशिश करें.</translation>
<translation id="549333378215107354">आकार 3</translation>
+<translation id="5509762909502811065">बी0</translation>
<translation id="5509780412636533143">प्रबंधित बुकमार्क</translation>
<translation id="5510766032865166053">हो सकता है कि उसे ले जाया गया हो या हटा दिया गया हो.</translation>
<translation id="5523118979700054094">नीति का नाम</translation>
<translation id="552553974213252141">क्या लेख सही तरीके से निकाला गया था?</translation>
+<translation id="553484882784876924">पीआरसी6 (एन्वेलप)</translation>
<translation id="5540224163453853">अनुरोध किया गया लेख नहीं ढूंढा जा सका.</translation>
<translation id="5541546772353173584">ईमेल जोड़ें</translation>
<translation id="5545756402275714221">आपके लिए लेख</translation>
<translation id="5556459405103347317">फिर लोड करें</translation>
-<translation id="5560088892362098740">समयसीमा समाप्ति दिनांक</translation>
+<translation id="5560088892362098740">समयसीमा समाप्ति तारीख</translation>
<translation id="5565735124758917034">सक्रिय</translation>
<translation id="5571083550517324815">इस पते से पिक अप नहीं किया जा सकता. कोई दूसरा पता चुनें.</translation>
<translation id="5571347317547569613">({NUM_COOKIES,plural, =1{1 इस्तेमाल में है}one{# इस्तेमाल में हैं}other{# इस्तेमाल में हैं}})</translation>
@@ -736,15 +839,21 @@
<translation id="5595485650161345191">पता संपादित करें</translation>
<translation id="5598944008576757369">भुगतान का तरीका चुनें</translation>
<translation id="560412284261940334">प्रबंधन समर्थित नहीं</translation>
+<translation id="5605670050355397069">लेजर</translation>
+<translation id="5607240918979444548">आर्किटेक्चर-सी</translation>
<translation id="5610142619324316209">कनेक्शन की जाँच करें</translation>
<translation id="5610807607761827392">आप <ph name="BEGIN_LINK" />सेटिंग<ph name="END_LINK" /> में कार्ड और पते प्रबंधित कर सकते हैं.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> ने आपको कई बार रीडायरेक्ट किया है.</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="5632627355679805402">आपका डेटा <ph name="TIME" /> से आपके <ph name="BEGIN_LINK" />Google पासवर्ड<ph name="END_LINK" /> के साथ सुरक्षित किया गया था. सिंक करना शुरू करने के लिए पासवर्ड डालें.</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="563324245173044180">भ्रामक सामग्री ब्लॉक की गई.</translation>
<translation id="5659593005791499971">ईमेल</translation>
+<translation id="5663614846592581799">9x11 (एन्वेलप)</translation>
+<translation id="5663955426505430495">इस डिवाइस के एडमिन ने और फ़ंक्शन के एक्सटेंशन इंस्टॉल किए हैं. एक्सटेंशन आपका कुछ डेटा एक्सेस कर सकते हैं.</translation>
<translation id="5675650730144413517">यह पेज काम नहीं कर रहा है</translation>
+<translation id="5684874026226664614">ओह. इस पेज का अनुवाद नहीं किया जा सका.</translation>
<translation id="5685654322157854305">शिपिंग पता जोड़ें</translation>
<translation id="5689199277474810259">JSON में निर्यात करें</translation>
<translation id="5689516760719285838">स्थान</translation>
@@ -753,38 +862,39 @@
<translation id="5710435578057952990">इस वेबसाइट की पहचान सत्यापित नहीं की गई है.</translation>
<translation id="5719499550583120431">प्रीपेड कार्ड स्वीकार किए जाते हैं.</translation>
<translation id="5720705177508910913">वर्तमान उपयोगकर्ता</translation>
+<translation id="5728056243719941842">सी5 (एन्वेलॉप)</translation>
<translation id="5730040223043577876">अगर आपने अपने पासवर्ड का दूसरी साइटों पर दोबारा इस्तेमाल किया है, तो Chrome आपको उसे रीसेट करने का सुझाव देता है.</translation>
<translation id="5732392974455271431">आपके अभिभावक इसे आपके लिए अनवरोधित कर सकते हैं</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{अपने Google खाते में कार्ड सेव करें}one{अपने Google खाते में कार्ड सेव करें}other{अपने Google खाते में कार्ड सेव करें}}</translation>
<translation id="5763042198335101085">मान्य ईमेल पता डालें</translation>
<translation id="5765072501007116331">वितरण के तरीके और ज़रूरतें देखने के लिए, कोई पता चुनें</translation>
-<translation id="5770114862687765385">लगता है फ़ाइल खराब हो गई है. सत्र रीसेट करने के लिए 'रीसेट करें' बटन क्लिक करें.</translation>
<translation id="5778550464785688721">MIDI डिवाइस पूर्ण नियंत्रण</translation>
<translation id="578305955206182703">ऐंबर</translation>
<translation id="57838592816432529">म्यूट करें</translation>
-<translation id="5784606427469807560">आपके कार्ड की पुष्टि करते समय समस्‍या हुई. अपना इंटरनेट कनेक्‍शन जाँचें और पुन: प्रयास करें.</translation>
+<translation id="5784606427469807560">आपके कार्ड की पुष्टि करते समय समस्‍या हुई. अपना इंटरनेट कनेक्‍शन जाँचें और फिर से प्रयास करें.</translation>
<translation id="5785756445106461925">इसके अतिरिक्त, इस पेज में ऐसे अन्य संसाधन भी शामिल हैं, जो सुरक्षित नहीं हैं. ट्रांज़िट में होने के दौरान ये संसाधन अन्य लोगों द्वारा देखे जा सकते हैं और पेज का स्वरूप बदलने के लिए किसी हमवलावर द्वारा इनमें बदलाव किए जा सकते हैं.</translation>
<translation id="5786044859038896871">क्या अपनी कार्ड जानकारी भरना चाहते हैं?</translation>
+<translation id="5798290721819630480">बदलाव खारिज कर दें?</translation>
<translation id="5798683403665926540">Chrome सेटिंग में जाकर होम पेज बदलें</translation>
<translation id="5803412860119678065">क्या आप अपनी <ph name="CARD_DETAIL" /> भरना चाहते हैं?</translation>
<translation id="5804241973901381774">अनुमतियां</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" /> से आपके कनेक्शन को किसी अप्रचलित सिफ़र सुइट का उपयोग करके एन्‍क्रिप्‍ट किया गया है.</translation>
<translation id="5813119285467412249">&amp;जोड़ना फिर से करें</translation>
<translation id="5838278095973806738">आपको इस साइट पर कोई भी संवेदनशील जानकारी (उदाहरण के लिए, पासवर्ड या क्रेडिट कार्ड) नहीं डालनी चाहिए, क्योंकि उसे हमलावर चुरा सकते हैं.</translation>
+<translation id="5860033963881614850">बंद</translation>
<translation id="5863847714970149516">आगे आने वाला पेज आपसे शुल्क लेने की कोशिश कर सकता है</translation>
<translation id="5866257070973731571">फ़ोन नंबर जोड़ें</translation>
<translation id="5869405914158311789">इस साइट तक नहीं पहुंचा जा सकता</translation>
<translation id="5869522115854928033">सेव किए गए पासवर्ड</translation>
<translation id="5887400589839399685">कार्ड सेव किया गया</translation>
-<translation id="5893718151540690985">नेटवर्क इंटरफ़ेस के प्रकारों और हार्डवेयर पतों सहित उसकी रिपोर्ट सूची</translation>
<translation id="5893752035575986141">क्रेडिट कार्ड स्वीकार किए जाते हैं.</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="5916664084637901428">चालू</translation>
+<translation id="5919090499915321845">बी10</translation>
<translation id="5921639886840618607">कार्ड को Google खाते में सेव करें?</translation>
<translation id="5922853866070715753">करीब-करीब हो गया है</translation>
<translation id="5932224571077948991">साइट में तंग करने वाले या गुमराह करने वाले विज्ञापन दिखाई देते हैं</translation>
-<translation id="5939518447894949180">रीसेट करें</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> को खोला जा रहा है…</translation>
<translation id="5951495562196540101">उपभोक्ता खाते (पैकेज किया गया लाइसेंस मौजूद है) के साथ नामांकन नहीं कर सकते.</translation>
<translation id="5967592137238574583">संपर्क जानकारी में बदलाव करें</translation>
@@ -792,6 +902,7 @@
<translation id="5975083100439434680">ज़ूम आउट</translation>
<translation id="5977489021191000276">आपके डिवाइस को किसी एडमिन की ओर से प्रबंधित नहीं किया जाता.</translation>
<translation id="5977976211062815271">इस डिवाइस पर</translation>
+<translation id="5980920751713728343">इंडेक्स-3x5</translation>
<translation id="598637245381783098">भुगतान ऐप्लिकेशन नहीं खोला जा सकता</translation>
<translation id="5989320800837274978">न तो कोई फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर और न ही कोई .pac स्क्रिप्ट URL साफ़ तौर पर बताया गया है.</translation>
<translation id="5990559369517809815">सर्वर से किए गए अनुरोधों को एक्‍सटेंशन द्वारा अवरुद्ध कर दिया गया है.</translation>
@@ -799,11 +910,11 @@
<translation id="6015796118275082299">वर्ष</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="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="6033927989869462158">हार्डवेयर आंकड़ों जैसे कि सीपीयू (CPU)/RAM इस्तेमाल की रिपोर्ट करें</translation>
<translation id="6034000775414344507">हल्का भूरा</translation>
+<translation id="6034283069659657473">10x14 (एन्वेलप)</translation>
<translation id="6039846035001940113">अगर समस्या बनी रहती है, तो साइट के मालिक से संपर्क करें.</translation>
<translation id="6040143037577758943">बंद करें</translation>
<translation id="6044573915096792553">आकार 12</translation>
@@ -812,10 +923,10 @@
<translation id="6051221802930200923">आप इस समय <ph name="SITE" /> पर नहीं जा सकते क्योंकि वेबसाइट, प्रमाणपत्र पिनिंग का उपयोग करती है. नेटवर्क की गड़बड़ियां और हमले आमतौर पर कुछ समय के लिए होते हैं इसलिए यह पेज शायद बाद में ठीक से काम करेगा.</translation>
<translation id="6058977677006700226">क्या आप अपने कार्ड का इस्तेमाल सभी डिवाइस पर करना चाहते हैं?</translation>
<translation id="6059925163896151826">USB डिवाइस</translation>
-<translation id="6071091556643036997">नीति का प्रकार गलत है.</translation>
<translation id="6080696365213338172">आपने व्यवस्थापक द्वारा प्रदत्त प्रमाणपत्र के उपयोग से सामग्री एक्सेस की है. आपके द्वारा <ph name="DOMAIN" /> को प्रदान किया गया डेटा आपके व्यवस्थापक द्वारा बीच में रोका जा सकता है.</translation>
<translation id="6094273045989040137">एनोटेट करें</translation>
<translation id="610911394827799129">आपके Google खाते में <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> पर दूसरी तरह के ब्राउज़िंग इतिहास हो सकते हैं</translation>
+<translation id="6132597952260690497">इंस्टॉल किए गए एक्सटेंशन और प्लग इन के बारे में जानकारी</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{कुछ नहीं}=1{1 पासवर्ड (सिंक किया हुआ)}one{# पासवर्ड (सिंक किए हुए)}other{# पासवर्ड (सिंक किए हुए)}}</translation>
<translation id="6146055958333702838">सभी केबल जाँचें और आपके द्वारा उपयोग किए जा रहे सभी राउटर, मॉडेम या अन्य नेटवर्क
डिवाइस को रीबूट करें.</translation>
@@ -850,18 +961,24 @@
<translation id="6337133576188860026"><ph name="SIZE" /> से कम जगह खाली करता है. जब आप अगली बार विज़िट करेंगे तो, कुछ साइटें और धीमे लोड हो सकती हैं.</translation>
<translation id="6337534724793800597">नाम के अनुसार नीतियां फ़िल्टर करें</translation>
<translation id="6358450015545214790">इनका क्‍या अर्थ है?</translation>
+<translation id="6361757823711327522">बी7</translation>
+<translation id="6380497234672085559">ए0</translation>
<translation id="6383221683286411806">आगे शुल्क लग सकते हैं.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 अन्‍य सुझाव}one{# अन्‍य सुझाव}other{# अन्‍य सुझाव}}</translation>
<translation id="6387754724289022810">अगली बार तेज़ी से भुगतान करने के लिए, अपने कार्ड और बिलिंग पते को अपने Google खाते में और इस डिवाइस में सेव करें.</translation>
+<translation id="6390662030813198813">इंजीनियरिंग-ई</translation>
<translation id="6404511346730675251">बुकमार्क में बदलाव करें</translation>
-<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> का समाप्ति दिनांक और CVC डालें</translation>
+<translation id="6406765186087300643">सी0 (एन्वेलप)</translation>
+<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> का समाप्ति तारीख और CVC डालें</translation>
<translation id="6414888972213066896">आपने अपने अभिभावक से पूछा है कि इस साइट पर जाना ठीक है या नहीं</translation>
<translation id="6417515091412812850">प्रमाणपत्र को रद्द किया गया है या नहीं यह जाँच करने में असमरर्थ.</translation>
<translation id="6433490469411711332">संपर्क जानकारी संपादित करें</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ने कनेक्ट करने से मना कर दिया है.</translation>
+<translation id="6434309073475700221">खारिज करें</translation>
+<translation id="6446163441502663861">काहू (एन्वेलप)</translation>
<translation id="6446608382365791566">और जानकारी जोड़ें</translation>
<translation id="6447842834002726250">कुकी</translation>
-<translation id="6451458296329894277">फ़ार्म पुन: जमा करने की दुबारा पूछें</translation>
+<translation id="6451458296329894277">फ़ार्म फिर से जमा करने की दुबारा पूछें</translation>
<translation id="6465306955648956876">पासवर्ड प्रबंधित करें...</translation>
<translation id="647261751007945333">डिवाइस नीतियां</translation>
<translation id="6477321094435799029">Chrome को इस पेज पर असामान्य कोड मिला था और उसने आपकी व्यक्तिगत जानकारी (उदाहरण के लिए, पासवर्ड, फ़ोन नंबर और क्रेडिट कार्ड) की सुरक्षा करने के लिए उसे अवरुद्ध कर दिया है.</translation>
@@ -871,19 +988,26 @@
<translation id="6508722015517270189">Chrome को फिर से शुरू करें</translation>
<translation id="6529602333819889595">&amp;हटाना फिर से करें</translation>
<translation id="6534179046333460208">जीता-जागता वेब के सुझाव</translation>
+<translation id="6556866813142980365">फिर से करें</translation>
<translation id="6563469144985748109">आपके प्रबंधक ने अभी तक इसकी स्वीकृति नहीं दी है</translation>
<translation id="6569060085658103619">आप एक एक्सटेंशन पेज देख रहे हैं</translation>
+<translation id="6578796323535178455">सी2 (एन्वेलप)</translation>
<translation id="6579990219486187401">हल्का गुलाबी रंग</translation>
+<translation id="6583674473685352014">बी6 (एन्वेलप)</translation>
+<translation id="6587923378399804057">आपका कॉपी किया हुआ लिंक</translation>
+<translation id="6591833882275308647">आपका <ph name="DEVICE_TYPE" /> प्रबंधित नहीं किया जाता</translation>
<translation id="6596325263575161958">सुरक्षित तरीका विकल्प</translation>
<translation id="6604181099783169992">गति या लाइट सेंसर</translation>
+<translation id="6609880536175561541">पीआरसी7 (एन्वेलप)</translation>
<translation id="6624427990725312378">संपर्क जानकारी</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="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="6643016212128521049">साफ़ करें</translation>
<translation id="6644283850729428850">यह नीति हटा दी गई है.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{कोई नहीं}=1{1 साइट से (आप अपने Google खाते से साइन आउट नहीं होंगे)}one{# साइटों से (आप अपने Google खाते से साइन आउट नहीं होंगे)}other{# साइटों से (आप अपने Google खाते से साइन आउट नहीं होंगे)}}</translation>
<translation id="6657585470893396449">पासवर्ड</translation>
+<translation id="6670613747977017428">सुरक्षित जगह पर लौटें.</translation>
<translation id="6671697161687535275">क्रोमियम से फ़ॉर्म सुझाव निकालें?</translation>
<translation id="6685834062052613830">प्रस्थान करें और सेटअप पूरा करें</translation>
<translation id="6710213216561001401">पिछला</translation>
@@ -891,12 +1015,15 @@
<translation id="671076103358959139">नाम दर्ज करने का टोकन:</translation>
<translation id="6711464428925977395">प्रॉक्सी सर्वर के साथ कुछ गलत है या पता गलत है.</translation>
<translation id="6723740634201835758">अपने Google खाते में</translation>
+<translation id="6738516213925468394">आपका डेटा <ph name="TIME" /> को <ph name="BEGIN_LINK" />सिंक करने के लिए लंबा पासवर्ड बनाकर<ph name="END_LINK" /> सुरक्षित किया गया था. सिंक शुरू करने के लिए पासवर्ड डालें.</translation>
<translation id="674375294223700098">अज्ञात सर्वर प्रमाणपत्र गड़बड़ी.</translation>
<translation id="6744009308914054259">कनेक्शन का इंतज़ार करते समय, ऑफ़लाइन लेख पढ़ने के लिए आप 'डाउनलोड' पर जा सकते हैं.</translation>
<translation id="6753269504797312559">नीति मान</translation>
<translation id="6757797048963528358">आपका डिवाइस निष्क्रिय हो गया है.</translation>
+<translation id="6768213884286397650">हगाकी (पोस्टकार्ड)</translation>
<translation id="6778737459546443941">आपके अभिभावक ने अभी तक इसकी स्वीकृति नहीं दी है</translation>
<translation id="67862343314499040">बैंगनी</translation>
+<translation id="6786747875388722282">एक्‍सटेंशन</translation>
<translation id="679355240208270552">अनदेखा किया गया क्योंकि पॉलिसी ने डिफ़ॉल्ट खोज सक्षम नहीं की है.</translation>
<translation id="681021252041861472">ज़रूरी फ़ील्ड</translation>
<translation id="6810899417690483278">कस्टमाइज़ेशन आईडी</translation>
@@ -929,10 +1056,12 @@
<translation id="6965978654500191972">डिवाइस</translation>
<translation id="6970216967273061347">जिला</translation>
<translation id="6973656660372572881">फ़िक्‍स्‍ड प्रॉक्‍सी सर्वर और .pac स्‍क्रिप्‍ट URL दोनों ही बताए गए हैं.</translation>
+<translation id="6973932557599545801">माफ़ करें, मैं आपकी मदद नहीं कर सकती. कृपया खुद करने की कोशिश करें.</translation>
<translation id="6979158407327259162">Google डिस्क</translation>
<translation id="6979440798594660689">म्यूट करें (डिफ़ॉल्ट)</translation>
<translation id="6984479912851154518">किसी बाहरी ऐप्लिकेशन के ज़रिए भुगतान करने के लिए 'निजी' मोड छोड़ रहे हैं. जारी रखना चाहते हैं?</translation>
<translation id="6989763994942163495">अतिरिक्त सेटिंग दिखाएं...</translation>
+<translation id="6993898126790112050">6x9 (एन्वेलप)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> का हमेशा अनुवाद करें</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">ये शुल्क एक बार लगने वाले या बार-बार लगने वाले हो सकते हैं और हो सकता है कि इनके बारे में स्पष्ट जानकारी न दी जाए.</translation>
@@ -948,33 +1077,41 @@
<translation id="7108338896283013870">छुपाएं</translation>
<translation id="7108819624672055576">किसी एक्सटेंशन ने अनुमति दी है</translation>
<translation id="7111012039238467737">(मान्य)</translation>
+<translation id="7118618213916969306">क्लिपबोर्ड यूआरएल, <ph name="SHORT_URL" /> खोजें</translation>
<translation id="7119414471315195487">दूसरे टैब या प्रोग्राम बंद करें</translation>
<translation id="7129409597930077180">इस पते पर शिप नहीं किया जा सकता. कोई दूसरा पता चुनें.</translation>
<translation id="7135130955892390533">स्थिति दिखाएं</translation>
<translation id="7138472120740807366">वितरण का तरीका</translation>
<translation id="7139724024395191329">अमीरात</translation>
+<translation id="7152423860607593928">संख्या-14 (एन्वेलप)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">हल्का बैंगनी</translation>
-<translation id="7158980942472052083">यूआरएल गलत है. मानक स्कीम वाला यूआरएल होना चाहिए.</translation>
<translation id="717330890047184534">Gaia आईडी:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">आप जिस सर्वर पर जा रहे हैं उसके लिए <ph name="ORIGIN" /> ने यह अनुरोध किया है
+ कि उसके सभी अनुरोधों पर सुरक्षा नीति लागू की जाए. लेकिन नीति
+ के मुताबिक काम करने के बजाय, इसने ब्राउज़र को कहीं और रीडायरेक्ट कर दिया है. इस वजह से
+ ब्राउज़र <ph name="SITE" /> के लिए आपके अनुरोध को पूरा नहीं कर पा रहा है.</translation>
<translation id="7179323680825933600">भुगतान के तरीके सेव करें और भरें</translation>
<translation id="7180611975245234373">रीफ्रेश करें</translation>
<translation id="7182878459783632708">कोई नीति सेट नहीं की गई है</translation>
<translation id="7186367841673660872">इस पेज का <ph name="ORIGINAL_LANGUAGE" />से<ph name="LANGUAGE_LANGUAGE" /> में अनुवाद कर दिया गया है</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> जगह खाली करता है. अगली बार आप जब कुछ साइटों पर जाएंगे, तो उन्हें लोड होने में ज़्यादा समय लग सकता है.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">आपका एडमिन यह देख सकता है:</translation>
+<translation id="7202346780273620635">लेटर-एक्स्ट्रा</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> सुरक्षा मानकों का पालन नहीं करता.</translation>
-<translation id="721197778055552897">इस समस्या के बारे में <ph name="BEGIN_LINK" />अधिक जानें<ph name="END_LINK" />.</translation>
+<translation id="721197778055552897">इस समस्या के बारे में <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">कनेक्‍शन <ph name="SSL_VERSION" /> का उपयोग करता है.</translation>
<translation id="7220786058474068424">संसाधित हो रहा है</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">साइट में आगे मैलवेयर हैं</translation>
-<translation id="724975217298816891">अपने कार्ड विवरण अपडेट करने के लिए <ph name="CREDIT_CARD" /> का समय समाप्ति दिनांक और CVC डालें. आपकी तरफ से पुष्टि हो जाने पर, आपके कार्ड के विवरण इस साइट के साथ शेयर किए जाएंगे.</translation>
+<translation id="724766306220616965">चेतावनियां, विरोध</translation>
+<translation id="724975217298816891">अपने कार्ड विवरण अपडेट करने के लिए <ph name="CREDIT_CARD" /> का समय समाप्ति तारीख और CVC डालें. आपकी तरफ से पुष्टि हो जाने पर, आपके कार्ड के विवरण इस साइट के साथ शेयर किए जाएंगे.</translation>
<translation id="7251437084390964440">नेटवर्क कॉन्फ़िगरेशन ONC मानक के मुताबिक नहीं है. हो सकता है कि कॉन्फ़िगरेशन के कुछ हिस्से नहीं लाए गए हों.
ज़्यादा जानकारी:
<ph name="DEBUG_INFO" /></translation>
-<translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से एक निजी कनेक्‍शन स्‍थापित नहीं किया जा सकता क्‍योंकि आपके कंप्‍यूटर का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</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="7271803869921933038">स्वीकार किए जाने वाले प्रीपेड कार्ड</translation>
<translation id="7275334191706090484">प्रबंधित बुकमार्क</translation>
@@ -982,11 +1119,14 @@
<translation id="7300012071106347854">कोबाल्ट नीला</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">खराबी की रिपोर्ट <ph name="CRASH_TIME" /> बजे दर्ज की गई (उपयोगकर्ता ने अपलोड करने का अनुरोध किया, अभी तक अपलोड नहीं किया गया)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />सुरक्षित ब्राउज़िंग<ph name="END_LINK" /> की चेतावनियां</translation>
+<translation id="7319430975418800333">ए3</translation>
<translation id="7320336641823683070">कनेक्शन संबंधी सहायता</translation>
<translation id="7334320624316649418">&amp;पुन: क्रमित करना फिर से करें</translation>
<translation id="733923710415886693">प्रमाणपत्र पारदर्शिता के माध्यम से सर्वर के प्रमाणपत्र को प्रकट नहीं किया गया.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">ए4-एक्स्ट्रा</translation>
<translation id="7353601530677266744">कमांड लाइन</translation>
-<translation id="7365061714576910172">Linux में निर्यात करें</translation>
<translation id="7372973238305370288">खोज परिणाम</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">नहीं</translation>
@@ -994,6 +1134,7 @@
<translation id="7381288752349550461">प्रबंधित सत्र ओवरराइड</translation>
<translation id="7390545607259442187">कार्ड की पुष्टि करें</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">आपका <ph name="DEVICE_NAME" /> प्रबंधित है</translation>
<translation id="7407424307057130981">&lt;p&gt;अगर आपके Windows कंप्यूटर पर Superfish सॉफ़्टवेयर है तो, आपको यह गड़बड़ी दिखाई देगी.&lt;/p&gt;
&lt;p&gt;आगे बताए गए कदम उठाकर सॉफ़्टवेयर को कुछ देर के लिए बंद कर दें ताकि आप वेब पर जा सकें. आपको एडमिन विशेषाधिकार की ज़रूरत होगी.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1145,7 @@
&lt;li&gt;&lt;strong&gt;लागू करें&lt;/strong&gt; पर क्लिक करें, फिर &lt;strong&gt;ठीक है&lt;/strong&gt; पर क्लिक करें
&lt;li&gt;&lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome सहायता केंद्र&lt;/a&gt; पर जाकर अपने कंप्यूटर से सॉफ़्टवेयर को हमेशा के लिए हटाने का तरीका जानें
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> प्रबंधन</translation>
+<translation id="741007362987735528">चौड़े पेज वाला फ़ॉर्मैट</translation>
<translation id="7416351320495623771">पासवर्ड प्रबंधित करें…</translation>
<translation id="7419106976560586862">प्रोफ़ाइल पथ</translation>
<translation id="7437289804838430631">संपर्क जानकारी जोड़ें</translation>
@@ -1012,33 +1153,35 @@
<translation id="7441627299479586546">गलत नीति विषय</translation>
<translation id="7442725080345379071">हल्का नारंगी</translation>
<translation id="7444046173054089907">यह साइट अवरोधित है</translation>
-<translation id="7445762425076701745">जिस सर्वर से आप कनेक्‍ट हैं उसकी पहचान पूर्णत: सत्‍यापित नहीं की जा सकती. आपने केवल आपके नेटवर्क में ही मान्‍य नाम का उपयोग कर किसी सर्वर से कनेक्‍ट किया है, जिसकी मान्‍यता का सत्‍यापन कोई बाह्य प्रमाणपत्र प्राधिकरण नहीं करता है. जैसा कि कुछ प्रमाणपत्र प्राधिकरण इन नामों के लिए प्रमाणपत्र जारी कर देंगे, और इस पर ध्यान नहीं दिया जाएगा कि यह सुनिश्‍चित करने का कोई तरीका नहीं है कि आप नियत वेबसाइट से कनेक्‍ट हैं, न कि किसी आक्रमणकर्ता से.</translation>
-<translation id="7449109375006139765">प्रबंधन सर्वर को सिस्टम लॉग भेजें</translation>
-<translation id="7451311239929941790">इस समस्या के बारे में <ph name="BEGIN_LINK" />अधिक जानें<ph name="END_LINK" />.</translation>
+<translation id="7445762425076701745">जिस सर्वर से आप कनेक्‍ट हैं उसकी पहचान पूरी तरह सत्‍यापित नहीं की जा सकती. आपने केवल आपके नेटवर्क में ही मान्‍य नाम का उपयोग कर किसी सर्वर से कनेक्‍ट किया है, जिसकी मान्‍यता का सत्‍यापन कोई बाह्य प्रमाणपत्र प्राधिकरण नहीं करता है. जैसा कि कुछ प्रमाणपत्र प्राधिकरण इन नामों के लिए प्रमाणपत्र जारी कर देंगे, और इस पर ध्यान नहीं दिया जाएगा कि यह सुनिश्‍चित करने का कोई तरीका नहीं है कि आप नियत वेबसाइट से कनेक्‍ट हैं, न कि किसी आक्रमणकर्ता से.</translation>
+<translation id="7451311239929941790">इस समस्या के बारे में <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">वैश्विक डिफ़ॉल्ट का उपयोग करें (अवरोधित करें)</translation>
<translation id="7460618730930299168">यह स्क्रीनिंग आपकी चुनी गई स्क्रीनिंग से अलग है. क्या आप जारी रखना चाहते हैं?</translation>
<translation id="7473891865547856676">नहीं, रहने दें</translation>
-<translation id="7475525192983021547">किसी उपयोगकर्ता के डिवाइस पर काम करते रहने पर समय अवधि को रिपोर्ट करें</translation>
<translation id="7481312909269577407">आगे जाएं</translation>
<translation id="7485870689360869515">कोई डेटा नहीं मिला</translation>
+<translation id="7498234416455752244">बदलाव करना जारी रखें</translation>
<translation id="7508255263130623398">वापस लौटाया हुआ नीति डिवाइस आईडी खाली है या उसका मिलान वर्तमान डिवाइस आईडी से नहीं होता है</translation>
<translation id="7508870219247277067">एवोकैडो हरा</translation>
<translation id="7511955381719512146">आप जिस वाई-फ़ाई का उपयोग कर रहे हैं, उसके लिए आपको <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> पर जाने की ज़रूरत पड़ सकती है.</translation>
<translation id="7514365320538308">डाउनलोड करें</translation>
<translation id="7518003948725431193">इस वेब पते के लिए कोई वेब पेज नहीं मिला था: <ph name="URL" /></translation>
+<translation id="7520302887438682816">सी8 (एन्वेलप)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">इस साइट से आपका कनेक्‍शन निजी नहीं है</translation>
+<translation id="7535087603100972091">मान</translation>
<translation id="7537536606612762813">आवश्यक</translation>
+<translation id="7538364083937897561">ए2 (एन्वेलप)</translation>
<translation id="7542403920425041731">आपकी तरफ से पुष्टि हो जाने पर, आपके कार्ड के विवरण इस साइट के साथ शेयर किए जाएंगे.</translation>
-<translation id="7542995811387359312">स्वतः क्रेडिट कार्ड भरना अक्षम किया गया है क्योंकि यह फ़ॉर्म किसी सुरक्षित कनेक्शन का उपयोग नहीं करता है.</translation>
+<translation id="7542995811387359312">अपने आप क्रेडिट कार्ड भरना अक्षम किया गया है क्योंकि यह फ़ॉर्म किसी सुरक्षित कनेक्शन का उपयोग नहीं करता है.</translation>
<translation id="7543525346216957623">अपने अभिभावक से पूछें</translation>
<translation id="7548892272833184391">कनेक्शन गड़बड़ियां ठीक करना</translation>
-<translation id="7549584377607005141">इस वेबपेज को आपके द्वारा पहले दर्ज किए गए डेटा की आवश्यकता है, ताकि इसे सही रूप में प्रदर्शित किया जा सके. आप यह डेटा पुन: भेज सकते हैं, लेकिन ऐसा करके आप इस पेज द्वारा पहले की जा चुकी कोई कार्यवाही दोहराएंगे.</translation>
+<translation id="7549584377607005141">इस वेबपेज को आपके द्वारा पहले दर्ज किए गए डेटा की आवश्यकता है, ताकि इसे सही रूप में प्रदर्शित किया जा सके. आप यह डेटा फिर से भेज सकते हैं, लेकिन ऐसा करके आप इस पेज द्वारा पहले की जा चुकी कोई कार्यवाही दोहराएंगे.</translation>
<translation id="7552846755917812628">ये टिप्स आज़माएं:</translation>
<translation id="7554791636758816595">नया टैब</translation>
<translation id="7564049878696755256">आप अपने <ph name="ORG_NAME" /> खाते का एक्सेस खो सकते हैं या आपकी पहचान चोरी हो सकती है. Chrome आपको इसी समय अपना पासवर्ड बदलने का सुझाव देता है.</translation>
-<translation id="7566125604157659769">आपका कॉपी किया गया टेक्स्ट</translation>
<translation id="7567204685887185387">यह सर्वर यह प्रमाणित नहीं कर सका कि यह <ph name="DOMAIN" /> है; हो सकता है इसका सुरक्षा प्रमाणपत्र धोखे से जारी किया गया हो. ऐसा गलत कॉन्फ़िगरेशन के कारण या किसी आक्रमणकर्ता द्वारा आपके कनेक्शन में अवरोध डालने के कारण हो सकता है.</translation>
+<translation id="7568105740864181217">कंपनी, स्कूल या दूसरा संगठन, इस ब्राउज़र को प्रबंधित करता है. आपका एडमिन किसी दूसरे डिवाइस से आपके ब्राउज़र का सेटअप बदल सकता है. शायद इस डिवाइस की गतिविधि को भी Chrome से बाहर प्रबंधित किया जाए. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome से क्रेडिट कार्ड निकालें?</translation>
<translation id="7569983096843329377">काला</translation>
<translation id="7578104083680115302">Google के साथ सहेजे गए कार्ड का उपयोग करके डिवाइसों में मौजूद साइटों और ऐप्‍स पर तुरंत भुगतान करें.</translation>
@@ -1047,20 +1190,23 @@
<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="7613889955535752492">समय-सीमा खत्म: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="7615602087246926389">आपके पास पहले से ऐसा डेटा है, जिसे आपके Google खाते के पासवर्ड के किसी भिन्‍न वर्शन का उपयोग करके एन्क्रिप्ट किया गया है. कृपया उसे नीचे लिखें.</translation>
+<translation id="7633909222644580952">परफ़ॉर्मेंस डेटा और क्रैश रिपोर्ट</translation>
<translation id="7637571805876720304">क्रोमियम से क्रेडिट कार्ड निकालें?</translation>
<translation id="7639968568612851608">गहरा धूसर</translation>
-<translation id="765676359832457558">उन्नत सेटिंग छिपाएं...</translation>
+<translation id="765676359832457558">बेहतर सेटिंग छिपाएं...</translation>
<translation id="7658239707568436148">अभी नहीं</translation>
<translation id="7662298039739062396">सेटिंग किसी एक्सटेंशन से नियंत्रित है</translation>
<translation id="7663736086183791259">प्रमाणपत्र <ph name="CERTIFICATE_VALIDITY" /></translation>
<translation id="7667346355482952095">वापस लौटा हुआ नीति टोकन खाली है या उसका मिलान वर्तमान टोकन से नहीं होता</translation>
<translation id="7668654391829183341">अज्ञात डिवाइस</translation>
<translation id="7669271284792375604">इस साइट पर मौजूद हमलावर धोखे से आपसे ऐसे प्रोग्राम इंस्टॉल करवाने की कोशिश कर सकते हैं, जिनसे आपके ब्राउज़िंग अनुभव को नुकसान पहुंच सकता है (उदाहरण के लिए, आपका होमपेज बदलकर या आप जिन साइटों पर जाते हैं उन पर ज़्यादा विज्ञापन दिखाकर).</translation>
+<translation id="7676643023259824263">क्लिपबोर्ड टेक्स्ट, <ph name="TEXT" /> खोजें</translation>
<translation id="7681101578153515023">सर्च इंजन बदलें</translation>
<translation id="7682287625158474539">शिपिंग</translation>
<translation id="7687186412095877299">आपके सेव किए गए भुगतान करने के तरीकों के ज़रिए भुगतान फ़ॉर्म भरता है</translation>
+<translation id="7697066736081121494">पीआरसी8 (एन्वेलप)</translation>
<translation id="769721561045429135">फ़िलहाल आपके पास सिर्फ़ इसी डिवाइस पर इस्तेमाल किए जा सकने वाले कार्ड हैं. कार्ड देखने के लिए जारी रखें पर क्लिक करें.</translation>
<translation id="7699293099605015246">फ़िलहाल लेख उपलब्ध नहीं हैं</translation>
<translation id="7701040980221191251">कुछ नहीं</translation>
@@ -1072,11 +1218,13 @@
<translation id="774634243536837715">खतरनाक सामग्री ब्लॉक की गई.</translation>
<translation id="7752995774971033316">अप्रबंधित</translation>
<translation id="7755287808199759310">आपका अभिभावक इसे आपके लिए अनवरोधित कर सकता है</translation>
+<translation id="7757555340166475417">दाई-पा-काई</translation>
<translation id="7758069387465995638">हो सकता है कि फायरवॉल या एंटीवायरस द्वारा कनेक्शन अवरुद्ध हो.</translation>
<translation id="7759163816903619567">डोमेन प्रदर्शित करें:</translation>
<translation id="7761701407923456692">सर्वर का प्रमाणपत्र यूआरएल से मेल नहीं खाता.</translation>
<translation id="7763386264682878361">भुगतान मेनिफ़ेस्ट पार्सर</translation>
<translation id="7764225426217299476">पता जोड़ें</translation>
+<translation id="7770259615151589601">लंबाई वाला फ़ॉर्मैट</translation>
<translation id="777702478322588152">प्रांत</translation>
<translation id="7791543448312431591">जोड़ें</translation>
<translation id="7793809570500803535"><ph name="SITE" /> पर मौजूद वेबपेज संभवत: अस्थायी रूप से कार्य नहीं कर रहा है या उसे स्थायी रूप से नए वेब पते पर स्थानांतरित कर दिया गया है.</translation>
@@ -1088,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome से फ़ॉर्म सुझाव को निकालें?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' के लिए <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> मिले</translation>
-<translation id="7818867226424560206">नीति प्रबंधन</translation>
<translation id="782886543891417279">आप जिस वाई-फ़ाई का उपयोग कर रहे हैं (<ph name="WIFI_NAME" />) आपको उसके लॉगिन पेज पर जाने की ज़रूरत पड़ सकती है.</translation>
+<translation id="7836231406687464395">पोस्टफ़िक्स (एन्वेलप)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{कोई नहीं}=1{एक ऐप्लिकेशन (<ph name="EXAMPLE_APP_1" />)}=2{दो ऐप्लिकेशन (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# ऐप्लिकेशन (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# ऐप्लिकेशन (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">हालांकि, गुप्त मोड का मतलब यह नहीं है कि आपको कोई भी नहीं देख सकता. गुप्त मोड में आप जो भी ब्राउजिंग करते हैं उसे, आपके नियोक्ता, इंटरनेट सेवा देने वाली कंपनी या आप जिन वेबसाइटों को देखते हैं, वे देख सकतीं हैं.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,8 +1245,8 @@
<translation id="7878176543348854470">डेबिट और प्रीपेड कार्ड स्वीकार किए जाते हैं.</translation>
<translation id="7878562273885520351">आपके पासवर्ड से छेड़छाड़ की जा सकती है</translation>
<translation id="7882421473871500483">भूरा</translation>
-<translation id="7887683347370398519">अपना CVC जाँचें और पुन: प्रयास करें</translation>
-<translation id="7893255318348328562">सत्र का नाम</translation>
+<translation id="7887683347370398519">अपना CVC जाँचें और फिर से प्रयास करें</translation>
+<translation id="7904208859782148177">सी3 (एन्वेलप)</translation>
<translation id="79338296614623784">मान्य फ़ोन नंबर डालें</translation>
<translation id="7935318582918952113">DOM डिस्टिलर</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" /> को खत्म होने वाला है</translation>
@@ -1108,21 +1256,25 @@
<translation id="7951415247503192394">(32-बिट)</translation>
<translation id="7956713633345437162">मोबाइल बुकमार्क</translation>
<translation id="7961015016161918242">कभी नहीं</translation>
+<translation id="7977894662897852582">ईडीपी</translation>
<translation id="7995512525968007366">निर्दिष्‍ट नहीं किया गया</translation>
<translation id="800218591365569300">जगह खाली करने के लिए दूसरे टैब या प्रोग्राम बंद करके देखें.</translation>
+<translation id="8004582292198964060">ब्राउज़र</translation>
<translation id="8009225694047762179">पासवर्ड संभालें</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{इस कार्ड और इसके बिलिंग पते को सेव किया जाएगा. <ph name="USER_EMAIL" /> में साइन इन रहने पर आप इसका इस्तेमाल कर पाएंगे.}one{ये कार्ड और इनके बिलिंग पते सेव किए जाएंगे. <ph name="USER_EMAIL" /> में साइन इन रहने पर आप उनका इस्तेमाल कर पाएंगे.}other{ये कार्ड और इनके बिलिंग पते सेव किए जाएंगे. <ph name="USER_EMAIL" /> में साइन इन रहने पर आप उनका इस्तेमाल कर पाएंगे.}}</translation>
-<translation id="8012647001091218357">हम इस समय आपके अभिभावकों तक नहीं पहुंच पा रहे हैं. कृपया पुन: प्रयास करें.</translation>
+<translation id="8012647001091218357">हम इस समय आपके अभिभावकों तक नहीं पहुंच पा रहे हैं. कृपया फिर से प्रयास करें.</translation>
<translation id="8025119109950072390">इस साइट पर मौजूद हमलावर आपको धोखा देकर आपसे कुछ जोखिम वाला काम करा सकते हैं, जैसे सॉफ़्टवेयर इंस्टॉल करना या आपकी व्यक्तिगत जानकारी (उदाहरण के लिए, पासवर्ड, फ़ोन नंबर या क्रेडिट कार्ड) प्रकट करना.</translation>
<translation id="8034522405403831421">यह पेज <ph name="SOURCE_LANGUAGE" /> में है. इसका <ph name="TARGET_LANGUAGE" /> में अनुवाद करें?</translation>
<translation id="8035152190676905274">पेन</translation>
+<translation id="8037117624646282037">हाल ही में डिवाइस किसने इस्तेमाल किया है</translation>
<translation id="8037357227543935929">पूछें (डिफ़ॉल्ट)</translation>
<translation id="803771048473350947">फ़ाइल</translation>
<translation id="8041089156583427627">सुझाव भेजें</translation>
<translation id="8041940743680923270">वैश्विक डिफ़ॉल्ट का उपयोग करें (पूछें)</translation>
<translation id="8042918947222776840">पिकअप का तरीका चुनें</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" सही तरीके से कॉन्फ़िगर नहीं किया गया है. आमतौर पर "<ph name="SOFTWARE_NAME" />" को अनइंस्टॉल करने से समस्या ठीक हो जाती है. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">आपका डिवाइस इसके लिए कॉन्फ़िगर किया गया है:</translation>
+<translation id="8066955247577885446">माफ़ करें, कोई गड़बड़ी हुई.</translation>
+<translation id="8074253406171541171">10x13 (एन्वेलप)</translation>
<translation id="8078141288243656252">घुमाने पर एनोटेट नहीं कर सकते</translation>
<translation id="8079031581361219619">साइट को फिर लोड करें?</translation>
<translation id="8088680233425245692">लेख देखने में विफल रहा.</translation>
@@ -1131,11 +1283,12 @@
<translation id="8091372947890762290">सर्वर पर सक्रियण लंबित है</translation>
<translation id="8092774999298748321">गहरा बैंगनी</translation>
<translation id="8094917007353911263">आप जिस नेटवर्क का उपयोग कर रहे हैं उसके लिए आपको <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> पर जाने की ज़रूरत पड़ सकती है.</translation>
+<translation id="809898108652741896">ए6</translation>
<translation id="8100588592594801589">अमान्य कार्ड हटा दिए गए हैं</translation>
<translation id="8103161714697287722">भुगतान का तरीका</translation>
<translation id="8118489163946903409">भुगतान का तरीका</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> को <ph name="ENROLLMENT_DOMAIN" /> प्रबंधित करता है</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" आपके कंप्यूटर या नेटवर्क पर ठीक से इंस्टॉल नहीं हुआ था. अपने आईटी व्यवस्थापक से इस समस्या को ठीक करने के लिए कहें.</translation>
-<translation id="8130693978878176684">मैं और मदद नहीं कर सकती, कृपया अपने आप करने की कोशिश करें.</translation>
<translation id="8131740175452115882">दुबारा पूछें</translation>
<translation id="8149426793427495338">आपका कंप्यूटर निष्क्रिय हो गया है.</translation>
<translation id="8150722005171944719"><ph name="URL" /> पर मौजूद फ़ाइल पढ़ने योग्य नहीं है. हो सकता है कि इसे निकाल दिया गया हो, कहीं ले जाया गया हो, या फ़ाइल की अनुमतियां पहुंच रोक रही हों.</translation>
@@ -1145,8 +1298,11 @@
<translation id="8197543752516192074">पेज का अनुवाद करें</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" आईडी वाले एक्‍सटेंशन का गलत अपडेट यूआरएल.</translation>
<translation id="8202097416529803614">ऑर्डर की जानकारी</translation>
+<translation id="8202370299023114387">विरोध</translation>
+<translation id="8206978196348664717">पीआरसी4 (एन्वेलप)</translation>
<translation id="8211406090763984747">कनेक्शन सुरक्षित है</translation>
<translation id="8218327578424803826">सौंपा गया स्‍थान:</translation>
+<translation id="8220146938470311105">सी7/सी6 (एन्वेलप)</translation>
<translation id="8225771182978767009">जिस व्यक्ति ने इस कंप्यूटर को सेट किया है, उसने इस साइट को अवरुद्ध करना चुना है.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">पेज को नए गुप्त टैब में खोलें</translation>
@@ -1158,14 +1314,16 @@
<translation id="825929999321470778">सेव किए गए सभी पासवर्ड दिखाएं</translation>
<translation id="8261506727792406068">हटाएं</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> के रूप में प्रवेश करना</translation>
+<translation id="8278457561961988242">इस ब्राउज़र को <ph name="ENROLLMENT_DOMAIN" /> प्रबंधित करता है. आपका एडमिन किसी दूसरे डिवाइस से आपके ब्राउज़र का सेटअप बदल सकता है. शायद इस डिवाइस की गतिविधि को भी Chrome से बाहर प्रबंधित किया जाए. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">बड़े आकार वाली फ़ोटो</translation>
<translation id="8286036467436129157">साइन इन करें</translation>
<translation id="8288807391153049143">प्रमाणपत्र दिखाएं</translation>
-<translation id="8289355894181816810">यदि आप सुनिश्चित नहीं हैं कि इसका क्या मतलब है, तो अपने नेटवर्क व्यवस्थापक से संपर्क करें.</translation>
+<translation id="8289355894181816810">अगर आप सुनिश्चित नहीं हैं कि इसका क्या मतलब है, तो अपने नेटवर्क व्यवस्थापक से संपर्क करें.</translation>
<translation id="8293206222192510085">बुकमार्क जोड़ें</translation>
<translation id="8294431847097064396">स्रोत</translation>
<translation id="8298115750975731693">आप जिस वाई-फ़ाई का उपयोग कर रहे हैं (<ph name="WIFI_NAME" />) उसके लिए आपको <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> पर जाने की ज़रूरत हो सकती है.</translation>
+<translation id="8307358339886459768">छोटे आकार वाली फ़ोटो</translation>
<translation id="8308427013383895095">नेटवर्क कनेक्शन में कोई समस्या होने के कारण अनुवाद विफल हुआ.</translation>
-<translation id="8311129316111205805">सत्र लोड करें</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> का एक्सेस अस्वीकृत किया गया</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">अगर आप अपनी सुरक्षा संबंधी जोखिमों को समझते हैं तो, खतरनाक प्रोग्राम हटाए जाने से पहले आप <ph name="BEGIN_LINK" />इस साइट पर विज़िट<ph name="END_LINK" /> कर सकते हैं.</translation>
@@ -1183,11 +1341,10 @@
<translation id="8416694386774425977">नेटवर्क कॉन्फ़िगरेशन गलत है और उसे लाया नहीं जा सका.
ज़्यादा जानकारी:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" /> की ओर से प्रबंधित डिवाइस</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">बदलें</translation>
<translation id="8428213095426709021">सेटिंग</translation>
-<translation id="8433057134996913067">इससे आप अधिकांश वेबसाइट से प्रस्थान कर जाएंगे.</translation>
+<translation id="8433057134996913067">इससे आप ज़्यादातर वेबसाइट से प्रस्थान कर जाएंगे.</translation>
<translation id="8437238597147034694">&amp;ले जाना वापस लाएं</translation>
<translation id="8461694314515752532">सिंक किए गए डेटा को अपने खुद के सिंक लंबे पासवर्ड से सुरक्षित करें</translation>
<translation id="8466379296835108687">{COUNT,plural, =1{1 क्रेडिट कार्ड}one{# क्रेडिट कार्ड}other{# क्रेडिट कार्ड}}</translation>
@@ -1202,7 +1359,7 @@
<translation id="8543556556237226809">प्रश्न पूछना चाहते हैं? तो उस व्यक्ति से संपर्क करें जो आपकी प्रोफ़ाइल की निगरानी करता है.</translation>
<translation id="8553075262323480129">अनुवाद विफल हो गया क्योंकि पेज की भाषा निर्धारित नहीं की जा सकी.</translation>
<translation id="8557066899867184262">कार्ड वेरीफ़िकेशन कोड (सीवीसी) आपके कार्ड के पीछे मौजूद होता है.</translation>
-<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से एक निजी कनेक्‍शन स्‍थापित नहीं किया जा सकता क्‍योंकि आपके डिवाइस का दिनांक और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
+<translation id="8559762987265718583"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> से एक निजी कनेक्‍शन स्‍थापित नहीं किया जा सकता क्‍योंकि आपके डिवाइस का तारीख और समय (<ph name="DATE_AND_TIME" />) गलत है.</translation>
<translation id="8564985650692024650">अगर आपने अपने <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> पासवर्ड का दूसरी साइटों पर दोबारा इस्तेमाल किया है, तो क्रोमियम आपको उसे रीसेट करने का सुझाव देता है.</translation>
<translation id="8571890674111243710">पेज का अनुवाद <ph name="LANGUAGE" /> में कर रहा है...</translation>
<translation id="858637041960032120">फ़ोन नंबर जोड़ें
@@ -1211,9 +1368,11 @@
<translation id="860043288473659153">कार्डधारक का नाम</translation>
<translation id="861775596732816396">आकार 4</translation>
<translation id="8620436878122366504">आपके अभिभावकों ने अभी तक इसकी स्वीकृति नहीं दी है</translation>
+<translation id="8622948367223941507">लीगल-एक्स्ट्रा</translation>
<translation id="8625384913736129811">यह कार्ड इस डिवाइस पर सेव करें</translation>
<translation id="8663226718884576429">ऑर्डर की खास बातें, <ph name="TOTAL_LABEL" />, ज़्यादा जानकारी</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, उत्तर, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">पीआरसी-16के</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> से आपके कनेक्शन को एन्क्रिप्ट नहीं किया गया है.</translation>
<translation id="8718314106902482036">भुगतान पूरा नहीं हुआ</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, खोज सुझाव</translation>
@@ -1227,6 +1386,7 @@
<translation id="8761567432415473239">Google सुरक्षित ब्राउज़िंग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />हानिकारक प्रोग्राम मिले हैं<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB डिवाइस</translation>
<translation id="8768895707659403558">अपने सभी डिवाइस पर कार्ड का इस्तेमाल करने के लिए, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">ए4</translation>
<translation id="8790007591277257123">&amp;हटाना फिर से करें</translation>
<translation id="8792621596287649091">आप अपने <ph name="ORG_NAME" /> खाते का एक्सेस खो सकते हैं या आपकी पहचान चोरी हो सकती है. क्रोमियम आपको इसी समय अपना पासवर्ड बदलने का सुझाव देता है.</translation>
<translation id="8800988563907321413">आपके आस-पास के सुझाव यहां दिखाई देंगे</translation>
@@ -1237,10 +1397,12 @@
<translation id="885730110891505394">Google के साथ शेयर करना</translation>
<translation id="8858065207712248076">अगर आपने अपने <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> पासवर्ड का दूसरी साइटों पर दोबारा इस्तेमाल किया है, तो Chrome आपको उसे रीसेट करने का सुझाव देता है.</translation>
<translation id="8866481888320382733">नीति सेटिंग पार्स करने में गड़बड़ी</translation>
+<translation id="886872106311861689">बी3</translation>
<translation id="8870413625673593573">हाल ही में बंद किए गए</translation>
<translation id="8874824191258364635">मान्य कार्ड संख्या डालें</translation>
<translation id="8891727572606052622">अमान्य प्रॉक्सी मोड.</translation>
<translation id="8903921497873541725">ज़ूम इन करें</translation>
+<translation id="890485472659500557">इंजीनियरिंग-सी</translation>
<translation id="8931333241327730545">क्या आप इस कार्ड को अपने Google खाते में सहेजना चाहते हैं?</translation>
<translation id="8932102934695377596">आपकी घड़ी पीछे है</translation>
<translation id="893332455753468063">नाम जोड़ें</translation>
@@ -1248,13 +1410,13 @@
<translation id="894185898663964645">आपके एडमिन ने कस्टम रूट सर्टिफ़िकेट कॉन्फ़िगर किए हैं, जो एडमिन को उन वेबसाइट की सामग्री देखने दे सकते हैं जिन पर आप जाते हैं.</translation>
<translation id="8943282376843390568">नींबू पीला</translation>
<translation id="8957210676456822347">कैप्‍टिव पोर्टल प्राधिकरण</translation>
+<translation id="8966619695390250636">क्या आपका मतलब यह था?</translation>
<translation id="8968766641738584599">कार्ड सेव करें</translation>
-<translation id="8971063699422889582">सर्वर के प्रमाणपत्र की समय-सीमा समाप्त हो चुकी है.</translation>
+<translation id="8971063699422889582">सर्वर के प्रमाणपत्र की समय-सीमा खत्म हो चुकी है.</translation>
<translation id="8975012916872825179">इसमें फ़ोन नंबर, ईमेल पते और शिपिंग पते जैसी जानकारी शामिल होती है</translation>
<translation id="8978053250194585037">Google सुरक्षित ब्राउज़िंग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />फ़िशिंग का पता चला है<ph name="END_LINK" />. फ़िशिंग साइटें आपको भ्रमित करने के लिए अन्य वेबसाइटें होने का दिखावा करती हैं.</translation>
<translation id="8983003182662520383">Google Pay का इस्तेमाल करने वाले भुगतान के तरीके और पते</translation>
<translation id="8987927404178983737">माह</translation>
-<translation id="8988408250700415532">कोई गड़बड़ी हुई. आप वेबसाइट पर अपना ऑर्डर पूरा कर सकते हैं.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">साइट में आगे हानिकारक प्रोग्राम हैं</translation>
<translation id="8997023839087525404">सर्वर ने एक प्रमाणपत्र प्रस्तुत किया है, जिसे प्रमाणपत्र पारदर्शिता पॉलिसी का उपयोग करके सार्वजनिक रूप से प्रकट नहीं किया गया था. कुछ प्रमाणपत्रों के लिए यह सुनिश्चित करना आवश्यक है कि वे विश्वसनीय हैं और आक्रमणकर्ताओं से रक्षा करते हैं.</translation>
@@ -1264,9 +1426,10 @@
<translation id="9011424611726486705">साइट सेटिंग खोलें</translation>
<translation id="9020200922353704812">कार्ड बिलिंग पता ज़रूरी है</translation>
<translation id="9020542370529661692">इस पेज का <ph name="TARGET_LANGUAGE" /> में अनुवाद कर दिया गया है</translation>
+<translation id="9020742383383852663">ए8</translation>
<translation id="9025348182339809926">(मान्य नहीं है)</translation>
<translation id="9035022520814077154">सुरक्षा गड़बड़ी</translation>
-<translation id="9038649477754266430">अधिक तेज़ी से पेज लोड करने के लिए किसी पूर्वानुमान सेवा का उपयोग करें</translation>
+<translation id="9038649477754266430">ज़्यादा तेज़ी से पेज लोड करने के लिए किसी पूर्वानुमान सेवा का उपयोग करें</translation>
<translation id="9039213469156557790">इसके अतिरिक्त, इस पेज में ऐसे अन्य संसाधन भी शामिल हैं, जो सुरक्षित नहीं हैं. ट्रांज़िट में होने के दौरान ये संसाधन अन्य लोगों द्वारा देखे जा सकते हैं और पेज का व्यवहार बदलने के लिए किसी हमवलावर द्वारा इनमें बदलाव किए जा सकते हैं.</translation>
<translation id="9045525010788763347"><ph name="RESULT_MODIFIED_DATE" /> - <ph name="RESULT_PRODUCT_SOURCE" /></translation>
<translation id="9049981332609050619">आपने <ph name="DOMAIN" /> पर पहुंचने की कोशिश की लेकिन सर्वर ने एक अमान्‍य प्रमाणपत्र पेश किया.</translation>
@@ -1275,11 +1438,11 @@
<translation id="9065745800631924235"><ph name="TEXT" /> इतिहास में खोजें</translation>
<translation id="9069693763241529744">किसी एक्सटेंशन से अवरोधित है</translation>
<translation id="9076283476770535406">इसमें वयस्क सामग्री हो सकती है</translation>
-<translation id="9078964945751709336">अधिक जानकारी की आवश्यकता है</translation>
+<translation id="9076630408993835509">यह ब्राउज़र कोई कंपनी या दूसरा संगठन प्रबंधित नहीं करता. शायद इस डिवाइस की गतिविधि को Chrome से बाहर प्रबंधित किया जाए. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation>
+<translation id="9078964945751709336">ज़्यादा जानकारी की आवश्यकता है</translation>
<translation id="9080712759204168376">ऑर्डर की जानकारी</translation>
<translation id="9103872766612412690"><ph name="SITE" /> आपकी जानकारी की सुरक्षा करने के लिए आमतौर पर एन्क्रिप्शन का उपयोग करती है. जब क्रोमियम ने इस बार <ph name="SITE" /> से कनेक्ट करने की कोशिश की, तो वेबसाइट ने असामान्य और गलत क्रेडेंशियल वापस भेजे. ऐसा तब हो सकता है जब कोई हमलावर <ph name="SITE" /> होने का दावा करने की कोशिश कर रहा हो या किसी वाई-फ़ाई साइन इन स्क्रीन ने कनेक्शन को रोक दिया हो. आपकी जानकारी अब भी सुरक्षित है क्योंकि किसी भी डेटा के लेन-देन से पहले ही क्रोमियम ने कनेक्शन को रोक दिया था.</translation>
<translation id="9106062320799175032">बिलिंग पता जोड़ें</translation>
-<translation id="9110718169272311511">'Chrome में Google Assistant' स्क्रीन के निचले हिस्से में मौजूद है</translation>
<translation id="9114524666733003316">कार्ड की पुष्टि की जा रही है...</translation>
<translation id="9128870381267983090">नेटवर्क से कनेक्ट करें</translation>
<translation id="9137013805542155359">मूल दिखाएं</translation>
@@ -1288,6 +1451,7 @@
<translation id="9148507642005240123">&amp;संपादन वापस लाएं</translation>
<translation id="9154194610265714752">अपडेट किया गया</translation>
<translation id="9157595877708044936">सेट अप कर रहा है...</translation>
+<translation id="9158625974267017556">सी6 (एन्वेलप)</translation>
<translation id="9168814207360376865">साइट को यह देखने दें कि आपके 'भुगतान के तरीके' सेव किए गए हैं या नहीं</translation>
<translation id="9169664750068251925">इस साइट पर हमेशा अवरोधित करें</translation>
<translation id="9170848237812810038">&amp;पूर्ववत् करें</translation>
@@ -1302,10 +1466,12 @@
<translation id="9219103736887031265">इमेज</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">फ़ॉर्म साफ़ करें</translation>
+<translation id="936474030629450166">सुपर-बी</translation>
<translation id="936602727769022409">आप अपने Google खाते का एक्सेस खो सकते हैं. क्रोमियम आपको इसी समय अपना पासवर्ड बदलने का सुझाव देता है. आपको साइन इन करने को कहा जाएगा.</translation>
<translation id="939736085109172342">नया फ़ोल्डर</translation>
<translation id="945855313015696284">नीचे दी गई जानकारी देखें और सभी गलत कार्ड मिटाएं</translation>
<translation id="951104842009476243">स्वीकार किए जाने वाले डेबिट और प्रीपेड कार्ड</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> की सुरक्षा नीति के मुताबिक रोक लगाई गई.</translation>
<translation id="962484866189421427">यह सामग्री ऐसे धोखा देने वाले ऐप्लिकेशन इंस्टॉल कर सकती है जो कुछ और होने का दावा करते हैं या ऐसा डेटा इकट्ठा करते हैं जिसका इस्तेमाल आप पर नज़र रखने के लिए किया जा सके. <ph name="BEGIN_LINK" />फिर भी दिखाएं<ph name="END_LINK" /></translation>
<translation id="969892804517981540">आधिकारिक बिल्ड</translation>
<translation id="973773823069644502">डिलीवरी का पता जोड़ें</translation>
@@ -1314,6 +1480,7 @@
<translation id="984275831282074731">भुगतान के तरीके</translation>
<translation id="985199708454569384">&lt;p&gt;अगर आपके कंप्यूटर या मोबाइल डिवाइस की तारीख और समय गलत है, तो आपको यह गड़बड़ी दिखाई देगी.&lt;/p&gt;
&lt;p&gt;इस गड़बड़ी को ठीक करने के लिए, अपने डिवाइस की घड़ी खोलें. पक्का करें कि समय और तारीख सही हों.&lt;/p&gt;</translation>
+<translation id="985956168329721395">पीआरसी-32के</translation>
<translation id="988159990683914416">डेवलपर बिल्ड</translation>
<translation id="989988560359834682">पता संपादित करें</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_hr.xtb b/chromium/components/strings/components_strings_hr.xtb
index 427915190f8..9f68d91ba27 100644
--- a/chromium/components/strings/components_strings_hr.xtb
+++ b/chromium/components/strings/components_strings_hr.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hr">
-<translation id="1005145902654145231">Promjena naziva sesije nije uspjela.</translation>
<translation id="1008557486741366299">Ne sada</translation>
<translation id="1010200102790553230">Učitaj stranicu kasnije</translation>
<translation id="1015730422737071372">Navedite dodatne pojedinosti</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nepoznati naziv</translation>
<translation id="1050038467049342496">Zatvorite ostale aplikacije</translation>
<translation id="1055184225775184556">&amp;Poništi dodavanje</translation>
+<translation id="1056898198331236512">Upozorenje</translation>
<translation id="1058479211578257048">Spremanje kartica...</translation>
<translation id="10614374240317010">Zaporke se nikad ne spremaju</translation>
+<translation id="1062160989074299343">Prc10 (omotnica)</translation>
<translation id="106701514854093668">Oznake radne površine</translation>
<translation id="1074497978438210769">Nije sigurno</translation>
<translation id="1080116354587839789">Prilagođavanje širini</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Dodajte ime na kartici</translation>
<translation id="1089439967362294234">Promjena zaporke</translation>
<translation id="109743633954054152">Upravljajte zaporkama u postavkama Chromea</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Upozorenja mogu biti uobičajena dok web-lokacije ažuriraju sigurnost. To bi se uskoro trebalo poboljšati.</translation>
<translation id="1126551341858583091">Veličina na lokalnoj pohrani iznosi <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Predmemorija pravila ispravna je</translation>
+<translation id="1131264053432022307">Slika koju ste kopirali</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Preimenuj</translation>
<translation id="1175364870820465910">&amp;Ispis...</translation>
<translation id="1181037720776840403">Ukloni</translation>
<translation id="1197088940767939838">Narančasta</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Naziv vašeg uređaja</translation>
<translation id="124116460088058876">Više jezika</translation>
<translation id="1250759482327835220">Da biste sljedeći put platili brže, spremite karticu, ime i adresu za naplatu na svoj Google račun.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinkronizirano)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Varijacije naredbenog retka</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="1314614906530272393">Odabrana sesija ne postoji.</translation>
+<translation id="1320233736580025032">Prc1 (omotnica)</translation>
+<translation id="132301787627749051">Traženje slike u međuspremniku</translation>
<translation id="1323433172918577554">Više</translation>
<translation id="132390688737681464">Spremi i popuni adrese</translation>
<translation id="1333989956347591814">Vaše aktivnosti <ph name="BEGIN_EMPHASIS" />i dalje mogu biti vidljive<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Adresa preuzimanja</translation>
<translation id="1348198688976932919">Sljedeća web-lokacija sadrži opasne aplikacije</translation>
<translation id="1348779747280417563">Potvrda imena</translation>
+<translation id="1357195169723583938">Tko je nedavno upotrebljavao uređaj i kada</translation>
+<translation id="1364822246244961190">To je pravilo blokirano i njegova će se vrijednost zanemariti.</translation>
<translation id="1374468813861204354">prijedlozi</translation>
+<translation id="1374692235857187091">Index-4x6 (dopisnica)</translation>
<translation id="1375198122581997741">O verziji</translation>
<translation id="1376836354785490390">Manje</translation>
<translation id="1377321085342047638">Broj kartice</translation>
<translation id="138218114945450791">Svijetloplava</translation>
+<translation id="1382194467192730611">USB uređaj koji je dopustio vaš administrator</translation>
<translation id="139305205187523129">Host <ph name="HOST_NAME" /> nije poslao nikakve podatke.</translation>
+<translation id="140316286225361634">Web-lokacija <ph name="ORIGIN" /> zatražila je da se sigurnosno pravilo
+ primjenjuje na sve njezine zahtjeve i to pravilo web-lokaciju trenutačno smatra
+ nesigurnom.</translation>
<translation id="1405567553485452995">Svijetlozelena</translation>
<translation id="1407135791313364759">Otvori sve</translation>
<translation id="1413809658975081374">Pogreška privatnosti</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Ispis</translation>
<translation id="1455413310270022028">Gumica</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Prikaži više</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Odaberite adresu za dostavu</translation>
+<translation id="1492194039220927094">Push slanje pravila:</translation>
<translation id="1501859676467574491">Prikaži kartice s Google računa</translation>
-<translation id="1506687042165942984">Prikaži spremljenu kopiju te stranice (tj., onu za koju se zna da je zastarjela).</translation>
<translation id="1507202001669085618">&lt;p&gt;Ta će se pogreška prikazati ako upotrebljavate Wi-Fi portal na koji se morate prijaviti da biste se povezali s internetom.&lt;/p&gt;
&lt;p&gt;Da biste ispravili tu pogrešku, kliknite &lt;strong&gt;Poveži se&lt;/strong&gt; na stranici koju pokušavate otvoriti.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonski je broj obavezan</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Datum međuverzije</translation>
<translation id="1521655867290435174">Google tablice</translation>
<translation id="1527263332363067270">Čekanje na uspostavu veze…</translation>
+<translation id="1529521330346880926">10x15 (omotnica)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Na ovoj se stranici navodi sljedeće</translation>
<translation id="153384715582417236">To je zasad sve</translation>
<translation id="154408704832528245">Odaberite adresu za isporuku</translation>
<translation id="1549470594296187301">Za upotrebu te značajke mora biti omogućen JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Unesite datum isteka</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Slika koju ste kopirali</translation>
<translation id="1620510694547887537">Fotoaparat</translation>
<translation id="1623104350909869708">Spriječi da ova stranica stvori dodatne dijaloške okvire</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Završi sesiju</translation>
<translation id="1639239467298939599">Učitavanje</translation>
<translation id="1640180200866533862">Korisnička pravila</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Certifikat poslužitelja sadrži slab kriptografski ključ!</translation>
<translation id="1697532407822776718">Potpuno ste spremni!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument je prevelik za dodavanje bilješki</translation>
<translation id="1721312023322545264"><ph name="NAME" /> mora dopustiti da posjetiš tu web-lokaciju</translation>
<translation id="1721424275792716183">* Polje je obavezno</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Pokušajte kontaktirati administratora sustava.</translation>
<translation id="1740951997222943430">Unesite važeći mjesec isteka</translation>
<translation id="1743520634839655729">Da biste sljedeći put platili brže, spremite karticu, ime i adresu za naplatu na svoj Google račun i ovaj uređaj.</translation>
+<translation id="1745880797583122200">Preglednikom se upravlja</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Ažurirajte zaporku za sinkronizaciju.</translation>
<translation id="1787142507584202372">Ovdje se prikazuju vaše otvorene kartice</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Ime vlasnika kartice</translation>
<translation id="1821930232296380041">Nevažeći zahtjev ili parametri zahtjeva</translation>
+<translation id="1822540298136254167">Web-lokacije koje posjećujete i vrijeme koje na njima provodite</translation>
<translation id="1826516787628120939">Provjera</translation>
<translation id="1834321415901700177">Ova web-lokacija sadrži štetne programe</translation>
<translation id="1839551713262164453">Potvrđivanje vrijednosti pravila nije uspjelo zbog pogrešaka</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Izbrišite Chromeove podatke o povijesti pregledavanja</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{i još 1}one{i još #}few{i još #}other{i još #}}</translation>
<translation id="2003709556000175978">Poništite zaporku odmah</translation>
+<translation id="20053308747750172">Poslužitelj kojem pristupate, <ph name="ORIGIN" />, zatražio je primjenu
+ sigurnosnog pravila na sve zahtjeve upućene prema njemu. No sada je
+ pružio nevažeće pravilo i preglednik zbog toga ne može
+ ispuniti vaš zahtjev za <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy je postavljen na automatsko konfiguriranje.</translation>
<translation id="2030481566774242610">Jeste li mislili <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />provjerite proxy i vatrozid<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departman</translation>
<translation id="2102134110707549001">Predloži snažnu zaporku…</translation>
<translation id="2108755909498034140">Ponovo pokrenite računalo</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kartica</translation>
<translation id="2114841414352855701">Zanemareno jer je nadjačano pravilom <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobilne oznake</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (omotnica)</translation>
<translation id="2181821976797666341">Pravila</translation>
<translation id="2183608646556468874">Telefonski broj</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}one{# adresa}few{# adrese}other{# adresa}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonski broj</translation>
<translation id="2283340219607151381">Spremi i popuni adrese</translation>
<translation id="2292556288342944218">Internetski je pristup blokiran</translation>
+<translation id="2294558542833290837">Veza koju ste prvobitno otvorili nije uobičajena</translation>
+<translation id="2297722699537546652">B5 (omotnica)</translation>
+<translation id="2310021320168182093">Chou2 (omotnica)</translation>
<translation id="2316887270356262533">Oslobodit će se manje od 1 MB. Neke bi se web-lokacije pri sljedećem otvaranju mogle sporije učitavati.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> zahtijeva korisničko ime i zaporku.</translation>
<translation id="2317583587496011522">Prihvaćaju se debitne kartice.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, istječe <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Postavkom upravlja administrator</translation>
+<translation id="2346319942568447007">Slika koju ste kopirali</translation>
<translation id="2349790679044093737">U tijeku je VR sesija</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Sada ste u privatnom načinu</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Poslužitelj kojem pristupate, <ph name="ORIGIN" />, zatražio je primjenu
+ sigurnosnog pravila na sve zahtjeve upućene prema njemu. No sada nije
+ pružio pravilo i preglednik zbog toga ne može
+ ispuniti vaš zahtjev za <ph name="SITE" />.</translation>
<translation id="244665789865330679">Vašim uređajem i računom upravlja <ph name="ENROLLMENT_DOMAIN" />. To znači da administrator može konfigurirati vaš uređaj i račun na daljinu.</translation>
<translation id="2463193859425327265">Promijeni početnu stranicu</translation>
<translation id="2463739503403862330">Ispuni</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Odaberite način isporuke</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />pokrenuti Mrežnu dijagnostiku<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Prevedi ovu stranicu</translation>
<translation id="2479410451996844060">Nevažeći URL pretraživanja.</translation>
<translation id="2482878487686419369">Obavijesti</translation>
<translation id="248348093745724435">Pravila uređaja</translation>
+<translation id="2485387744899240041">Korisnička imena za uređaj i preglednik</translation>
<translation id="2491120439723279231">Certifikat poslužitelja sadrži pogreške.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Skeniraj novu karticu</translation>
<translation id="2501278716633472235">Natrag</translation>
<translation id="2503184589641749290">Prihvaćene debitne i pretplatne kartice</translation>
<translation id="2515629240566999685">provjerite jačinu signala na svom području</translation>
-<translation id="2516852381693169964">Pretraži sliku uz <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Sprema se samo na ovom uređaju</translation>
<translation id="2524461107774643265">Dodajte još podataka</translation>
<translation id="2536110899380797252">Dodaj adresu</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (omotnica)</translation>
<translation id="2625385379895617796">Sat ide unaprijed</translation>
<translation id="2634124572758952069">IP adresa poslužitelja hosta <ph name="HOST_NAME" /> nije pronađena.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Zatvorite ostale kartice ili aplikacije</translation>
<translation id="267371737713284912">pritisnite <ph name="MODIFIER_KEY_DESCRIPTION" /> za poništavanje</translation>
<translation id="2674170444375937751">Jeste li sigurni da te stranice želite izbrisati iz Vaše povijesti?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Napusti</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Prihvaćene kartice</translation>
<translation id="2702801445560668637">Popis za čitanje</translation>
<translation id="2704283930420550640">Vrijednost ne odgovara formatu.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Ukloni odabrane stavke</translation>
<translation id="277133753123645258">Način dostave</translation>
<translation id="277499241957683684">Zapis uređaja nije prisutan</translation>
-<translation id="2781030394888168909">Izvezi za MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Veza je ponovo uspostavljena.</translation>
<translation id="2788784517760473862">Prihvaćene kreditne kartice</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Otvori anonimni prozor</translation>
+<translation id="2850739647070081192">Invite (omotnica)</translation>
<translation id="2851634818064021665">Potrebno ti je dopuštenje za posjet toj web-lokaciji</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Želite li spremiti karticu?</translation>
<translation id="2903493209154104877">Adrese</translation>
<translation id="290376772003165898">Ovo nije <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Način dostave</translation>
<translation id="2928905813689894207">Adresa za naplatu</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (omotnica)</translation>
<translation id="3024663005179499861">Pogrešna vrsta pravila</translation>
<translation id="3037605927509011580">O, ne!</translation>
<translation id="3041612393474885105">Podaci o certifikatu</translation>
+<translation id="3060227939791841287">C9 (omotnica)</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="3095940652251934233">Izjava</translation>
<translation id="3096100844101284527">Dodajte adresu preuzimanja</translation>
<translation id="3105172416063519923">ID uređaja:</translation>
<translation id="3109728660330352905">Nemate ovlaštenje za prikaz te stranice.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na poslužitelju <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Otkaži plaćanje</translation>
<translation id="3207960819495026254">Označeno</translation>
-<translation id="3209375525920864198">Unesite važeći naziv sesije.</translation>
+<translation id="321912867715453276">Upozorenje: za to je pravilo prisutno više izvora, ali vrijednosti su iste.</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="3229041911291329567">Informacije o verziji uređaja i preglednika</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Dodajte ime na kartici</translation>
<translation id="3287510313208355388">Preuzmi online</translation>
<translation id="3293642807462928945">Saznajte više o pravilu <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nisu pronađeni rezultati pretraživanja</translation>
-<translation id="3305707030755673451">Vaši su podaci šifrirani vašom šifrom za sinkronizaciju <ph name="TIME" />. Unesite je da biste pokrenuli sinkronizaciju.</translation>
<translation id="3320021301628644560">Dodajte adresu za naplatu</translation>
<translation id="3324983252691184275">Grimizna</translation>
<translation id="3338095232262050444">Sigurno</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Ponovi uređivanje</translation>
<translation id="342781501876943858">Chromium preporučuje poništavanje zaporke ako ste je upotrebljavali za druge web-lokacije.</translation>
<translation id="3431636764301398940">Spremi tu karticu na ovaj uređaj</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Vlasnik tog uređaja isključio je igru s dinosaurima.</translation>
<translation id="3447884698081792621">Prikaz certifikata (izdavač: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Dohvati interval:</translation>
+<translation id="3456231139987291353">Number-11 (omotnica)</translation>
<translation id="3461824795358126837">Alat za isticanje</translation>
<translation id="3462200631372590220">Sakrij napredno</translation>
<translation id="3467763166455606212">Potrebno je unijeti ime nositelja kartice</translation>
@@ -430,19 +481,22 @@
<translation id="358285529439630156">Prihvaćaju se kreditne i pretplatne kartice.</translation>
<translation id="3582930987043644930">Dodajte ime</translation>
<translation id="3583757800736429874">&amp;Ponovi premještanje</translation>
+<translation id="35866233670761917">Administratori ne mogu vidjeti sadržaj web-lokacija koje posjećujete</translation>
<translation id="3586931643579894722">Sakrij detalje</translation>
+<translation id="3592413004129370115">Italian (omotnica)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Veličina 2</translation>
<translation id="3615877443314183785">Unesite važeći datum isteka</translation>
<translation id="36224234498066874">Obriši podatke o pregledavanju...</translation>
<translation id="362276910939193118">Pokaži cijelu povijest</translation>
-<translation id="3623476034248543066">Prikaži vrijednost</translation>
<translation id="3630155396527302611">Ako je već navedena kao program koji smije pristupiti mreži, pokušajte je ukloniti s popisa pa je ponovo dodati.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Valjanost je uspješna</translation>
<translation id="3655670868607891010">Ako se to često događa, pokušajte <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Izmjena</translation>
<translation id="366077651725703012">Ažuriraj kreditnu karticu</translation>
<translation id="3676592649209844519">ID uređaja:</translation>
+<translation id="3677008721441257057">Jeste li mislili &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Zahtjev nije bilo moguće potpisati</translation>
<translation id="3678529606614285348">Otvorite stranicu u novom anonimnom prozoru (Ctrl – Shift – N)</translation>
<translation id="3679803492151881375">Izvješće o rušenju programa generirano u <ph name="CRASH_TIME" />, preneseno u <ph name="UPLOAD_TIME" /></translation>
@@ -450,13 +504,14 @@
<translation id="3704162925118123524">Mreža koju upotrebljavate može zahtijevati posjet stranici za prijavu.</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="3709599264800900598">Tekst koji ste kopirali</translation>
<translation id="3712624925041724820">Licence su potrošene</translation>
<translation id="3714780639079136834">uključite mobilne podatke ili Wi-Fi</translation>
<translation id="3715597595485130451">Povezivanje s Wi-Fi mrežom</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />provjerite proxy, vatrozid i konfiguraciju DNS-a<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Aplikacije koje mogu prouzročiti tu pogrešku uključuju antivirusni softver, softver vatrozida ili proxyja ili softver za filtriranje weba.</translation>
+<translation id="373042150751172459">B4 (omotnica)</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="3745099705178523657">Nakon što ih potvrdite, podaci o kartici s Google računa podijelit će se s ovom web-lokacijom.</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>
@@ -469,10 +524,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Istječe <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Veličina 16</translation>
+<translation id="3797522431967816232">Prc3 (omotnica)</translation>
<translation id="3807873520724684969">Blokiran je štetni sadržaj.</translation>
<translation id="3810973564298564668">Upravljaj</translation>
<translation id="382518646247711829">Ako upotrebljavate proxy poslužitelj...</translation>
<translation id="3828924085048779000">Prazne zaporke nisu dopuštene.</translation>
+<translation id="3831915413245941253">Domena <ph name="ENROLLMENT_DOMAIN" /> instalirala je proširenja za dodatne funkcije. Proširenja imaju pristup nekim vašim podacima.</translation>
<translation id="385051799172605136">Natrag</translation>
<translation id="3858027520442213535">Ažuriraj datum i vrijeme</translation>
<translation id="3884278016824448484">Identifikator uređaja sukobljen je</translation>
@@ -480,6 +537,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Uvijek pitaj na ovoj web-lokaciji</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>
@@ -490,11 +548,13 @@
<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="3984550557525787191">Naziv sesije već postoji.</translation>
<translation id="3987940399970879459">Manje od 1 MB</translation>
+<translation id="4008849406247176967">Upozorenje: za to je pravilo prisutno više izvora sa sukobljenim vrijednostima!</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="4030383055268325496">&amp;Poništi dodavanje</translation>
+<translation id="4032320456957708163">Vašim preglednikom upravlja <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Stavka "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (omotnica)</translation>
<translation id="4067947977115446013">Dodajte važeću adresu</translation>
<translation id="4072486802667267160">Došlo je do pogreške pri obradi narudžbe. Pokušajte ponovo.</translation>
<translation id="4075732493274867456">Klijent i poslužitelj ne podržavaju uobičajenu verziju SSL protokola ili paket šifri.</translation>
@@ -514,10 +574,12 @@
<translation id="4159784952369912983">Ljubičasto</translation>
<translation id="4165986682804962316">Postavke web-lokacije</translation>
<translation id="4171400957073367226">Potpis za potvrdu nije ispravan.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Još <ph name="ITEM_COUNT" /> stavka}one{Još <ph name="ITEM_COUNT" /> stavka}few{Još <ph name="ITEM_COUNT" /> stavke}other{Još <ph name="ITEM_COUNT" /> stavki}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (omotnica)</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="4221630205957821124">&lt;h4&gt;1. korak: prijavite se na portal&lt;/h4&gt;
@@ -549,58 +611,79 @@
<translation id="4277028893293644418">Poništi zaporku</translation>
<translation id="4280429058323657511">, istek <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Ova je kartica spremljena na vašem Google računu}one{Ove su kartice spremljene na vašem Google računu}few{Ove su kartice spremljene na vašem Google računu}other{Ove su kartice spremljene na vašem Google računu}}</translation>
+<translation id="42981349822642051">Proširi</translation>
+<translation id="4302965934281694568">Chou3 (omotnica)</translation>
<translation id="4305817255990598646">Prebaci</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokiraj (zadano)</translation>
+<translation id="4318566738941496689">Naziv uređaja i mrežna adresa</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="4340982228985273705">Za ovo računalo nije otkriveno da njime upravlja tvrtka, pa pravilo može samo automatski instalirati proširenja hostirana u Chrome web-trgovini. URL za ažuriranje Chrome web-trgovine je "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Prihvaćene kreditne kartice</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Upravljajte načinima plaćanja...</translation>
+<translation id="4367563149485757821">Number-12 (omotnica)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">rezultati pretraživanja</translation>
-<translation id="4406972042435603828">Administratori su instalirali proširenja velikih mogućnosti.</translation>
<translation id="4408413947728134509">Kolačića: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Adresa preuzimanja</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="443121186588148776">Serijski priključak</translation>
<translation id="4432688616882109544">Host <ph name="HOST_NAME" /> nije prihvatio vaš certifikat za prijavu ili certifikat nije poslan.</translation>
<translation id="4434045419905280838">Skočni prozori i preusmjeravanja</translation>
+<translation id="4435702339979719576">Dopisnica)</translation>
<translation id="443673843213245140">Upotreba proxy poslužitelja onemogućena je, ali određena je izričita konfiguracija proxy poslužitelja.</translation>
<translation id="445100540951337728">Prihvaćene debitne kartice</translation>
+<translation id="4466881336512663640">Izgubit će se promjene koje ste unijeli u obrazac. Jeste li sigurni da želite nastaviti?</translation>
<translation id="4482953324121162758">Ova web-lokacija neće biti prevedena.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL nije važeći. URL mora imati standardnu shemu, na primjer http://example.com ili https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (omotnica)</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="4517607026994743406">Comm-10 (omotnica)</translation>
<translation id="4522570452068850558">Detalji</translation>
<translation id="4524805452350978254">Upravljanje karticama</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Pokušajte onemogućiti proširenja.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Dostava</translation>
+<translation id="4579056131138995126">Personal (omotnica)</translation>
<translation id="4582204425268416675">Uklonite karticu</translation>
<translation id="4587425331216688090">Želite li s Chromea ukloniti adresu?</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="4597348597567598915">Veličina 8</translation>
+<translation id="4600854749408232102">C6/C5 (omotnica)</translation>
<translation id="4646534391647090355">Otvori odmah</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="467809019005607715">Google prezentacije</translation>
<translation id="4690462567478992370">Prestani upotrebljavati nevažeći certifikat</translation>
+<translation id="4691835149146451662">Architecture-A (omotnica)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Veza je prekinuta</translation>
<translation id="471880041731876836">Nemaš dopuštenje za posjet toj web-lokaciji</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />pokrenuti Mrežnu dijagnostiku sustava Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Ponovo učitaj pravila</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">Prc2 (omotnica)</translation>
<translation id="4736825316280949806">Ponovo pokrenite Chromium</translation>
<translation id="473775607612524610">Ažuriraj</translation>
<translation id="4738601419177586157">Prijedlog za pretraživanje <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Upravljaj zaporkama…</translation>
<translation id="4744603770635761495">Izvršna putanja</translation>
+<translation id="4746351372139058112">Poruke</translation>
<translation id="4750917950439032686">Vaši podaci (na primjer, zaporke i brojevi kreditnih kartica) privatni su kada se šalju na tu web-lokaciju.</translation>
<translation id="4756388243121344051">&amp;Povijest</translation>
<translation id="4758311279753947758">Dodaj pod. za kontakt</translation>
@@ -608,9 +691,9 @@
<translation id="4764776831041365478">Web-stranica na adresi <ph name="URL" /> možda privremeno nije dostupna ili je trajno preseljena na novu web-adresu.</translation>
<translation id="4771973620359291008">Došlo je do nepoznate pogreške.</translation>
<translation id="4785689107224900852">Prijeđite na ovu karticu</translation>
-<translation id="4792143361752574037">Pojavio se problem prilikom pristupa datotekama sesije. Spremanje na disk trenutačno je onemogućeno. Ponovo učitajte stranicu i pokušajte opet.</translation>
<translation id="4798078619018708837">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 s vašeg Google računa podijelit će se s ovom web-lokacijom.</translation>
<translation id="4800132727771399293">Provjerite datum isteka i CVC pa pokušajte ponovo</translation>
+<translation id="480334179571489655">Pogreška izvornog pravila</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>
@@ -625,7 +708,6 @@
<translation id="4881695831933465202">Otvori</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>
@@ -634,15 +716,15 @@
<translation id="4943872375798546930">Nema rezultata</translation>
<translation id="4950898438188848926">Gumb za promjenu kartice, pritisnite Enter za prebacivanje na otvorenu karticu, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Radnje</translation>
-<translation id="495832697253704892">Izvješćivanje o proširenjima</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Proširi popis</translation>
<translation id="4974590756084640048">Ponovo omogući upozorenja</translation>
+<translation id="4984339528288761049">Prc5 (omotnica)</translation>
<translation id="4989163558385430922">Prikaži sve</translation>
<translation id="4989809363548539747">Taj dodatak nije podržan</translation>
-<translation id="4996230189582812866">Izvješćivanje</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="5014174725590676422">Prikazuje se zaslon prvog pokretanja Google asistenta u Chromeu</translation>
<translation id="5015510746216210676">Naziv uređaja:</translation>
+<translation id="5017554619425969104">Tekst koji ste kopirali</translation>
<translation id="5018422839182700155">Stranica se ne može otvoriti</translation>
<translation id="5019198164206649151">Sigurnosno pohranjivanje u neispravnom je stanju</translation>
<translation id="5023310440958281426">Provjerite pravila svojeg administratora</translation>
@@ -652,35 +734,51 @@
<translation id="5034369478845443529">Lokalni kontekst <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Dopusti</translation>
<translation id="5040262127954254034">Privatnost</translation>
+<translation id="5043480802608081735">Veza koju ste kopirali</translation>
<translation id="5045550434625856497">Pogrešna zaporka</translation>
<translation id="5056549851600133418">Preporučeni članci</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />provjerite proxy adresu<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Certifikat poslužitelja trenutačno nije važeći.</translation>
<translation id="5087580092889165836">Dodaj karticu</translation>
<translation id="5089810972385038852">Savezna 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">Pokrajina</translation>
+<translation id="5097099694988056070">Statistika uređaja kao što je upotreba procesora/RAM-a</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Vašim uređajem upravlja <ph name="ENROLLMENT_DOMAIN" />, a vašim računom upravlja <ph name="ACCOUNT_DOMAIN" />. To znači da administratori mogu konfigurirati vaš uređaj i račun na daljinu.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bitni)</translation>
-<translation id="5128122789703661928">Brisanje sesije nije uspjelo jer naziv sesije nije važeći.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Upravljajte adresama...</translation>
+<translation id="5138227688689900538">Pokaži manje</translation>
<translation id="5141240743006678641">Šifriranje sinkroniziranih zaporki s vjerodajnicama za Google</translation>
<translation id="5145883236150621069">Odgovor na pravilo sadrži kôd pogreške</translation>
+<translation id="515292512908731282">C4 (omotnica)</translation>
<translation id="5159010409087891077">Otvorite stranicu u novom anonimnom prozoru (⇧⌘N)</translation>
<translation id="516920405563544094">Unesite CVC za karticu <ph name="CREDIT_CARD" />. Nakon što ga potvrdite, podaci o kartici s vašeg Google računa podijelit će se s ovom web-lokacijom.</translation>
<translation id="5169827969064885044">Mogli biste izgubiti pristup računu svoje organizacije ili bi netko mogao ukrasti vaš identitet. Chrome preporučuje da odmah promijenite zaporku.</translation>
<translation id="5171045022955879922">Pretražite ili upišite URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Strojno</translation>
<translation id="5179510805599951267">Nije <ph name="ORIGINAL_LANGUAGE" /> jezik? Prijavite tu pogrešku</translation>
<translation id="5190835502935405962">Traka oznaka</translation>
-<translation id="5200263511887412697">generiranje popisa korisnika uređaja koji su se nedavno prijavili</translation>
+<translation id="519422657042045905">Napomena nije dostupna</translation>
<translation id="5201306358585911203">Na ugrađenoj stranici na ovoj stranici navodi se sljedeće</translation>
<translation id="5205222826937269299">Ime je obavezno</translation>
<translation id="5215116848420601511">Načini plaćanja i adrese s Google Paya</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-pošta (obavezno)</translation>
<translation id="5230733896359313003">Adresa za dostavu</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Povezivanje s mrežom"</translation>
<translation id="5251803541071282808">Oblak</translation>
+<translation id="5252000469029418751">C7 (omotnica)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Mrežne adrese</translation>
<translation id="5285570108065881030">Prikaži sve spremljene zaporke</translation>
<translation id="5287240709317226393">Pokaži kolačiće</translation>
<translation id="5288108484102287882">Potvrđivanje vrijednosti pravila rezultiralo je upozorenjima</translation>
@@ -692,7 +790,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> od <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Odaberite podatke za kontakt</translation>
<translation id="5327248766486351172">Naziv</translation>
+<translation id="5329858041417644019">Preglednikom se ne upravlja</translation>
<translation id="5332219387342487447">Način otpreme</translation>
+<translation id="5334013548165032829">Detaljni zapisnici sustava</translation>
<translation id="5344579389779391559">Ta će vam stranica možda pokušati nešto naplatiti</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>
@@ -700,6 +800,7 @@
<translation id="5377026284221673050">"Sat kasni" ili "Sat ide unaprijed" ili "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Da biste svoje kartice upotrebljavali na svim uređajima, prijavite se i uključite sinkronizaciju.</translation>
<translation id="5386426401304769735">Lanac certifikata za ovu web-lokaciju sadrži certifikat s SHA-1 potpisom.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -710,6 +811,7 @@
<translation id="5457113250005438886">Nije važeće</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Ponovi uređivanje</translation>
+<translation id="5478437291406423475">B6/C4 (omotnica)</translation>
<translation id="5481076368049295676">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="54817484435770891">Dodajte važeću adresu</translation>
<translation id="5490432419156082418">Adrese i više</translation>
@@ -717,10 +819,12 @@
<ph name="LINE_BREAK" />
Pokušajte se obratiti administratoru sustava.</translation>
<translation id="549333378215107354">Veličina 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Upravljane oznake</translation>
<translation id="5510766032865166053">Datoteka je možda premještena ili izbrisana.</translation>
<translation id="5523118979700054094">Naziv pravila</translation>
<translation id="552553974213252141">Je li tekst ispravno izdvojen?</translation>
+<translation id="553484882784876924">Prc6 (omotnica)</translation>
<translation id="5540224163453853">Traženi članak nije pronađen.</translation>
<translation id="5541546772353173584">Dodajte e-adresu</translation>
<translation id="5545756402275714221">Preporučeni članci</translation>
@@ -735,15 +839,21 @@
<translation id="5595485650161345191">Uređivanje adrese</translation>
<translation id="5598944008576757369">Odaberite način plaćanja</translation>
<translation id="560412284261940334">Upravljanje nije podržano</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Host <ph name="HOST_NAME" /> preusmjerio vas je previše puta.</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="5632627355679805402">Vaši su podaci kriptirani vašom <ph name="BEGIN_LINK" />Google zaporkom<ph name="END_LINK" /> od <ph name="TIME" />. Unesite je da biste pokrenuli sinkronizaciju.</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="563324245173044180">Blokiran je obmanjujući sadržaj.</translation>
<translation id="5659593005791499971">E-pošta</translation>
+<translation id="5663614846592581799">9x11 (omotnica)</translation>
+<translation id="5663955426505430495">Administrator uređaja instalirao je proširenja za dodatne funkcije. Proširenja imaju pristup nekim vašim podacima.</translation>
<translation id="5675650730144413517">Stranica ne funkcionira</translation>
+<translation id="5684874026226664614">Ups. Stranicu nije bilo moguće prevesti.</translation>
<translation id="5685654322157854305">Dodajte adresu za dostavu</translation>
<translation id="5689199277474810259">Izvezi u JSON</translation>
<translation id="5689516760719285838">Lokacija</translation>
@@ -752,38 +862,39 @@
<translation id="5710435578057952990">Identitet ove web lokacije nije ovjeren.</translation>
<translation id="5719499550583120431">Prihvaćaju se pretplatne kartice.</translation>
<translation id="5720705177508910913">Trenutačni korisnik:</translation>
+<translation id="5728056243719941842">C5 (omotnica)</translation>
<translation id="5730040223043577876">Chrome preporučuje poništavanje zaporke ako ste je upotrebljavali za druge web-lokacije.</translation>
<translation id="5732392974455271431">Tvoji je roditelji mogu deblokirati</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Spremite karticu na svoj Google račun}one{Spremite kartice na svoj Google račun}few{Spremite kartice na svoj Google račun}other{Spremite kartice na svoj Google račun}}</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="5770114862687765385">Čini se da je datoteka oštećena. Kliknite gumb "Poništi" da biste poništili sesiju.</translation>
<translation id="5778550464785688721">Potpuni nadzor nad MIDI uređajima</translation>
<translation id="578305955206182703">Jantarna</translation>
<translation id="57838592816432529">Isključi zvuk</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>
+<translation id="5798290721819630480">Želite li odbaciti izmjene?</translation>
<translation id="5798683403665926540">Promijenite početnu stranicu u postavkama Chromea</translation>
<translation id="5803412860119678065">Želite li ispuniti podatke o kartici <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Dozvoljeno</translation>
<translation id="5810442152076338065">Vaša veza s domenom <ph name="DOMAIN" /> kriptirana je zastarjelim kriptografskim paketom.</translation>
<translation id="5813119285467412249">&amp;Ponovi dodavanje</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="5860033963881614850">Isključeno</translation>
<translation id="5863847714970149516">Stranica koja će se otvoriti može vam pokušati nešto naplatiti</translation>
<translation id="5866257070973731571">Dodajte telefonski broj</translation>
<translation id="5869405914158311789">Web-lokacija ne može se dohvatiti</translation>
<translation id="5869522115854928033">Spremljene zaporke</translation>
<translation id="5887400589839399685">Kartica je spremljena</translation>
-<translation id="5893718151540690985">generiranje popisa mrežnih sučelja s njihovim vrstama i adresama hardvera</translation>
<translation id="5893752035575986141">Prihvaćaju se kreditne kartice.</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="5916664084637901428">Uključi</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Želite li spremiti karticu na Google račun?</translation>
<translation id="5922853866070715753">Skoro gotovo</translation>
<translation id="5932224571077948991">Web-lokacija prikazuje ometajuće ili obmanjujuće oglase</translation>
-<translation id="5939518447894949180">Ponovno postavi</translation>
<translation id="5946937721014915347">Otvaranje web-lokacije <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Prijava s računom potrošača nije moguća (dostupna je paketna licenca).</translation>
<translation id="5967592137238574583">Uredite podatke za kontakt</translation>
@@ -791,6 +902,7 @@
<translation id="5975083100439434680">Smanji</translation>
<translation id="5977489021191000276">Vašim uređajem ne upravlja administrator.</translation>
<translation id="5977976211062815271">Na ovom uređaju</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Aplikacija za plaćanje ne može se otvoriti</translation>
<translation id="5989320800837274978">Nisu određeni fiksni proxy poslužitelji ni URL .pac skripte.</translation>
<translation id="5990559369517809815">Zahtjevi poslužitelju blokirani su proširenjem.</translation>
@@ -801,8 +913,8 @@
<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="6033927989869462158">izvješćivanje o statistici hardvera kao što je upotreba procesora/RAM-a</translation>
<translation id="6034000775414344507">Svijetlosiva</translation>
+<translation id="6034283069659657473">10x14 (omotnica)</translation>
<translation id="6039846035001940113">Ako se problem nastavi, obratite se vlasniku web-lokacije.</translation>
<translation id="6040143037577758943">Zatvori</translation>
<translation id="6044573915096792553">Veličina 12</translation>
@@ -811,10 +923,10 @@
<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="6058977677006700226">Želite li plaćati svojim karticama na svim svojim uređajima?</translation>
<translation id="6059925163896151826">USB uređaji</translation>
-<translation id="6071091556643036997">Vrsta pravila nije važeća.</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="6094273045989040137">Dodaj bilješku</translation>
<translation id="610911394827799129">Na vašem Google računu možda postoje drugi oblici povijesti pregledavanja na stranici <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informacije o instaliranim proširenjima i dodacima</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>
@@ -849,15 +961,21 @@
<translation id="6337133576188860026">Oslobodit će se <ph name="SIZE" />. Neke bi se web-lokacije pri sljedećem otvaranju mogle sporije učitavati.</translation>
<translation id="6337534724793800597">Filtriranje pravila prema nazivu</translation>
<translation id="6358450015545214790">Što to znači?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Ako nastavite, moguća je naplata.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 drugi prijedlog}one{# drugi prijedlog}few{# druga prijedloga}other{# drugih prijedloga}}</translation>
<translation id="6387754724289022810">Da biste sljedeći put platili brže, karticu i adresu za naplatu spremite na svoj Google račun i na ovaj uređaj.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Uredi oznaku</translation>
+<translation id="6406765186087300643">C0 (omotnica)</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="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="6434309073475700221">Odbaci</translation>
+<translation id="6446163441502663861">Kahu (omotnica)</translation>
<translation id="6446608382365791566">Dodajte još podataka</translation>
<translation id="6447842834002726250">Kolačići</translation>
<translation id="6451458296329894277">Potvrdi ponovno slanje obrasca</translation>
@@ -870,11 +988,17 @@
<translation id="6508722015517270189">Ponovo pokrenite Chrome</translation>
<translation id="6529602333819889595">&amp;Ponovi brisanje</translation>
<translation id="6534179046333460208">Prijedlozi Fizičkog weba</translation>
+<translation id="6556866813142980365">Ponovi</translation>
<translation id="6563469144985748109">Voditelj je još nije odobrio</translation>
<translation id="6569060085658103619">Gledate stranicu proširenja</translation>
+<translation id="6578796323535178455">C2 (omotnica)</translation>
<translation id="6579990219486187401">Svijetloružičasta</translation>
+<translation id="6583674473685352014">B6 (omotnica)</translation>
+<translation id="6587923378399804057">Veza koju ste kopirali</translation>
+<translation id="6591833882275308647">Uređaj <ph name="DEVICE_TYPE" /> nije upravljani uređaj</translation>
<translation id="6596325263575161958">Opcije šifriranja</translation>
<translation id="6604181099783169992">Senzori pokreta ili osvjetljenja</translation>
+<translation id="6609880536175561541">Prc7 (omotnica)</translation>
<translation id="6624427990725312378">Podaci za kontakt</translation>
<translation id="6626291197371920147">Dodajte važeći broj kartice</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Pretraživanje</translation>
@@ -883,6 +1007,7 @@
<translation id="6644283850729428850">Ovo je pravilo zastarjelo.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nijedna}=1{S jedne web-lokacije (nećete se odjaviti s Google računa)}one{S # web-lokacije (nećete se odjaviti s Google računa)}few{S # web-lokacije (nećete se odjaviti s Google računa)}other{S # web-lokacija (nećete se odjaviti s Google računa)}}</translation>
<translation id="6657585470893396449">Zaporka</translation>
+<translation id="6670613747977017428">Natrag u sigurnost.</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>
@@ -890,12 +1015,15 @@
<translation id="671076103358959139">Oznaka za prijavu:</translation>
<translation id="6711464428925977395">Nešto nije u redu s proxy poslužiteljem ili adresa nije točna.</translation>
<translation id="6723740634201835758">Na vašem Google računu</translation>
+<translation id="6738516213925468394">Vaši su podaci kriptirani vašom <ph name="BEGIN_LINK" />šifrom za sinkronizaciju<ph name="END_LINK" /> <ph name="TIME" />. Unesite je da biste pokrenuli sinkronizaciju.</translation>
<translation id="674375294223700098">Nepoznata pogreška certifikata poslužitelja</translation>
<translation id="6744009308914054259">Dok čekate vezu, možete otvoriti Preuzimanja i čitati offline članke.</translation>
<translation id="6753269504797312559">Vrijednost pravila</translation>
<translation id="6757797048963528358">Uređaj je u stanju mirovanja.</translation>
+<translation id="6768213884286397650">Hagaki (dopisnica)</translation>
<translation id="6778737459546443941">Roditelj je još nije odobrio</translation>
<translation id="67862343314499040">Ljubičasta</translation>
+<translation id="6786747875388722282">Proširenja</translation>
<translation id="679355240208270552">Zanemareno jer zadano pretraživanje nije omogućeno pravilom.</translation>
<translation id="681021252041861472">Obavezno polje</translation>
<translation id="6810899417690483278">ID prilagođavanja</translation>
@@ -928,10 +1056,12 @@
<translation id="6965978654500191972">Uređaj</translation>
<translation id="6970216967273061347">Distrikt</translation>
<translation id="6973656660372572881">Određeni su fiksni proxy poslužitelji i URL .pac skripte.</translation>
+<translation id="6973932557599545801">Nažalost, ne mogu vam pomoći, nastavite sami.</translation>
<translation id="6979158407327259162">Google disk</translation>
<translation id="6979440798594660689">Bez zvuka (zadano)</translation>
<translation id="6984479912851154518">Napuštate privatni način rada da biste platili putem vanjske aplikacije. Želite li nastaviti?</translation>
<translation id="6989763994942163495">Pokaži napredne postavke...</translation>
+<translation id="6993898126790112050">6x9 (omotnica)</translation>
<translation id="6996312675313362352">Uvijek prevodi <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Ta terećenja mogu biti jednokratna ili ponavljajuća i možda nisu odmah vidljiva.</translation>
@@ -947,28 +1077,36 @@
<translation id="7108338896283013870">Sakrij preglednik</translation>
<translation id="7108819624672055576">Dopustilo proširenje</translation>
<translation id="7111012039238467737">(Važeći)</translation>
+<translation id="7118618213916969306">Traženje URL-a u međuspremniku, <ph name="SHORT_URL" /></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="7135130955892390533">Prikaži status</translation>
<translation id="7138472120740807366">Način isporuke</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (omotnica)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">URL nije važeći. Mora biti URL sa standardnom shemom.</translation>
<translation id="717330890047184534">ID za GAIA-u:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Poslužitelj kojem pristupate, <ph name="ORIGIN" />, zatražio je primjenu
+ sigurnosnog pravila na sve zahtjeve upućene prema njemu. No nije pružio
+ pravilo, već je preusmjerio preglednik drugamo i preglednik zbog toga
+ ne može ispuniti vaš zahtjev za <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Spremi i popuni načine plaćanja</translation>
<translation id="7180611975245234373">Osvježi</translation>
<translation id="7182878459783632708">Nije postavljeno nijedno pravilo</translation>
<translation id="7186367841673660872">Ova je stranica prevedena s jezika<ph name="ORIGINAL_LANGUAGE" />na<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Oslobodit će se <ph name="SIZE" />. Neke bi se web-lokacije pri sljedećem otvaranju mogle sporije učitavati.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Vaš administrator može vidjeti:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Host <ph name="HOST_NAME" /> ne pridržava se sigurnosnih standarda.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /> o ovom problemu.</translation>
<translation id="7219179957768738017">Veza upotrebljava <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Obrada</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Web-lokacija pred vama sadrži zlonamjerni softver</translation>
+<translation id="724766306220616965">Upozorenja, sukob</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="7251437084390964440">Konfiguracija mreže nije u skladu sa standardom ONC. Dijelovi konfiguracije možda se neće uvesti.
Dodatne pojedinosti:
@@ -981,11 +1119,14 @@ Dodatne pojedinosti:
<translation id="7300012071106347854">Kobaltno plava</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Upozorenja <ph name="BEGIN_LINK" />Sigurnog pregledavanja<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Pomoć za povezivanje</translation>
<translation id="7334320624316649418">&amp;Ponovi promjenu rasporeda</translation>
<translation id="733923710415886693">Certifikat poslužitelja nije otkriven putem Transparentnosti certifikata.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Naredbeni redak</translation>
-<translation id="7365061714576910172">Izvezi za Linux</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>
@@ -993,6 +1134,7 @@ Dodatne pojedinosti:
<translation id="7381288752349550461">Nadjačavanje upravljane sesije</translation>
<translation id="7390545607259442187">Potvrda kartice</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Uređaj <ph name="DEVICE_NAME" /> upravljani je uređaj</translation>
<translation id="7407424307057130981">&lt;p&gt;Ta će se pogreška prikazati ako na Windows računalu imate softver Superfish.&lt;/p&gt;
&lt;p&gt;Privremeno onemogućite softver prema ovim uputama da biste se povezali s webom. Potrebne su vam administratorske povlastice.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@ Dodatne pojedinosti:
&lt;li&gt;Kliknite &lt;strong&gt;Primijeni&lt;/strong&gt;, a zatim kliknite &lt;strong&gt;U redu&lt;/strong&gt;
&lt;li&gt;U &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;centru za pomoć za Chrome&lt;/a&gt; možete saznati kako trajno ukloniti softver s računala
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Upravljanje <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Upravljaj zaporkama…</translation>
<translation id="7419106976560586862">Putanja profila</translation>
<translation id="7437289804838430631">Dodajte podatke za kontakt</translation>
@@ -1012,22 +1154,24 @@ Dodatne pojedinosti:
<translation id="7442725080345379071">Svijetlonarančasta</translation>
<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="7449109375006139765">slanje zapisnika sustava poslužitelju za upravljanje</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="7460618730930299168">Projekcija se razlikuje od onog što ste odabrali. Želite li nastaviti?</translation>
<translation id="7473891865547856676">Ne, hvala</translation>
-<translation id="7475525192983021547">izvješćivanje o razdobljima aktivnosti korisnika na uređaju</translation>
<translation id="7481312909269577407">Naprijed</translation>
<translation id="7485870689360869515">Nema pronađenih podataka.</translation>
+<translation id="7498234416455752244">Nastavi uređivati</translation>
<translation id="7508255263130623398">Vraćeni ID uređaja pravila prazan je ili ne odgovara trenutačnom ID-u uređaja</translation>
<translation id="7508870219247277067">Zelenožuta</translation>
<translation id="7511955381719512146">Za Wi-Fi koji upotrebljavate možda ćete morati posjetiti stranicu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Preuzmi</translation>
<translation id="7518003948725431193">Za web-adresu nije pronađena web-stranica:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (omotnica)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Veza s web-lokacijom nije privatna</translation>
+<translation id="7535087603100972091">Vrijednost</translation>
<translation id="7537536606612762813">Obavezno</translation>
+<translation id="7538364083937897561">A2 (omotnica)</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>
@@ -1036,8 +1180,8 @@ Dodatne pojedinosti:
<translation id="7552846755917812628">Pokušajte učiniti sljedeće:</translation>
<translation id="7554791636758816595">Nova kartica</translation>
<translation id="7564049878696755256">Mogli biste izgubiti pristup svojem <ph name="ORG_NAME" /> računu ili bi netko mogao ukrasti vaš identitet. Chrome preporučuje da odmah promijenite zaporku.</translation>
-<translation id="7566125604157659769">Tekst koji ste kopirali</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="7568105740864181217">Preglednikom upravlja vaša tvrtka, škola ili druga organizacija. Vaš administrator može daljinski promijeniti postavke preglednika. Aktivnostima na tom uređaju može se upravljati i izvan Chromea. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></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>
@@ -1048,6 +1192,7 @@ Dodatne pojedinosti:
<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="7633909222644580952">Podaci o uspješnosti i izvješća o padu programa</translation>
<translation id="7637571805876720304">Želite li ukloniti kreditnu karticu iz Chromiuma?</translation>
<translation id="7639968568612851608">Tamnosiva</translation>
<translation id="765676359832457558">Skrivanje naprednih postavki...</translation>
@@ -1057,9 +1202,11 @@ Dodatne pojedinosti:
<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="7676643023259824263">Traženje teksta u međuspremniku, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Promijeni tražilicu</translation>
<translation id="7682287625158474539">Dostava</translation>
<translation id="7687186412095877299">Popunjava obrasce za plaćanje spremljenim načinima plaćanja</translation>
+<translation id="7697066736081121494">Prc8 (omotnica)</translation>
<translation id="769721561045429135">Trenutačno imate kartice kojima se može plaćati samo na ovom uređaju. Kliknite Nastavi da biste pregledali kartice.</translation>
<translation id="7699293099605015246">Članci trenutačno nisu dostupni</translation>
<translation id="7701040980221191251">Nema</translation>
@@ -1071,11 +1218,13 @@ Dodatne pojedinosti:
<translation id="774634243536837715">Blokiran je opasan sadržaj.</translation>
<translation id="7752995774971033316">Nema upravitelja</translation>
<translation id="7755287808199759310">Roditelj je može deblokirati</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Vezu možda blokira vatrozid ili antivirusni softver.</translation>
<translation id="7759163816903619567">Prikaži domenu:</translation>
<translation id="7761701407923456692">Certifikat poslužitelja ne podudara se s URL-om.</translation>
<translation id="7763386264682878361">Raščlanjivač manifesta za plaćanje</translation>
<translation id="7764225426217299476">Dodaj adresu</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7793809570500803535">Web-stranica na web-lokaciji <ph name="SITE" /> možda privremeno nije dostupna ili je trajno preseljena na novu web-adresu.</translation>
@@ -1087,8 +1236,8 @@ Dodatne pojedinosti:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Želite li s Chromea ukloniti prijedlog za obrasce?</translation>
<translation id="7815407501681723534">Pronađeno <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> za "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Upravljanje pravilima</translation>
<translation id="782886543891417279">Za Wi-Fi koji upotrebljavate (<ph name="WIFI_NAME" />) možda ćete morati posjetiti stranicu za prijavu.</translation>
+<translation id="7836231406687464395">Postfix (omotnica)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ništa}=1{1 aplikacija (<ph name="EXAMPLE_APP_1" />)}=2{2 aplikacije (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# aplikacija (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}few{# aplikacije (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# aplikacija (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Niste nevidljivi. Anonimni način ne sakriva vaše pregledavanje od poslodavca, davatelja internetskih usluga ili posjećenih web-lokacija.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@ Dodatne pojedinosti:
<translation id="7878562273885520351">Vaša je zaporka možda ugrožena</translation>
<translation id="7882421473871500483">Smeđa</translation>
<translation id="7887683347370398519">Provjerite CVC i pokušajte ponovo</translation>
-<translation id="7893255318348328562">Naziv sesije</translation>
+<translation id="7904208859782148177">C3 (omotnica)</translation>
<translation id="79338296614623784">Unesite važeći telefonski broj</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Istječe <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@ Dodatne pojedinosti:
<translation id="7951415247503192394">(32-bitni)</translation>
<translation id="7956713633345437162">Mobilne oznake</translation>
<translation id="7961015016161918242">Nikad</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Nije navedeno</translation>
<translation id="800218591365569300">Pokušajte zatvoriti ostale kartice ili programe da biste oslobodili memoriju.</translation>
+<translation id="8004582292198964060">Preglednik</translation>
<translation id="8009225694047762179">Upravljanje zaporkama</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Ova kartica i njezina adresa za naplatu spremit će se. Moći ćete plaćati njome kada ste prijavljeni na račun <ph name="USER_EMAIL" />.}one{Ove kartice i njihove adrese za naplatu spremit će se. Moći ćete plaćati njima kada ste prijavljeni na račun <ph name="USER_EMAIL" />.}few{Ove kartice i njihove adrese za naplatu spremit će se. Moći ćete plaćati njima kada ste prijavljeni na račun <ph name="USER_EMAIL" />.}other{Ove kartice i njihove adrese za naplatu spremit će se. Moći ćete plaćati njima kada ste prijavljeni na račun <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Jezik ove stranice jest <ph name="SOURCE_LANGUAGE" />. Želite li je prevesti na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pero</translation>
+<translation id="8037117624646282037">Tko je nedavno upotrebljavao uređaj</translation>
<translation id="8037357227543935929">Pitaj (zadano)</translation>
<translation id="803771048473350947">Datoteka</translation>
<translation id="8041089156583427627">Slanje povratnih informacija</translation>
<translation id="8041940743680923270">Upotrijebi globalnu zadanu vrijednost (pitaj)</translation>
<translation id="8042918947222776840">Odaberite način preuzimanja</translation>
<translation id="8057711352706143257">Softver "<ph name="SOFTWARE_NAME" />" nije ispravno konfiguriran. Taj se problem obično rješava deinstaliranjem softvera "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Vaš je uređaj konfiguriran za:</translation>
+<translation id="8066955247577885446">Nešto nije u redu.</translation>
+<translation id="8074253406171541171">10x13 (omotnica)</translation>
<translation id="8078141288243656252">Ne može dodati bilješku kada je dokument zakrenut</translation>
<translation id="8079031581361219619">Želite li ponovo učitati web-lokaciju?</translation>
<translation id="8088680233425245692">Prikaz članka nije uspio.</translation>
@@ -1130,11 +1283,12 @@ Dodatne pojedinosti:
<translation id="8091372947890762290">Aktivacija je na čekanju na poslužitelju</translation>
<translation id="8092774999298748321">Tamnoljubičasta</translation>
<translation id="8094917007353911263">Za mrežu koju upotrebljavate možda ćete morati posjetiti stranicu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Nevažeće su kartice uklonjene</translation>
<translation id="8103161714697287722">Način plaćanja</translation>
<translation id="8118489163946903409">Način plaćanja</translation>
+<translation id="8123836779274890062">Uređajem <ph name="DEVICE_TYPE" /> upravlja <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Softver "<ph name="SOFTWARE_NAME" />" nije ispravno instaliran na vašem računalu ili mreži. Obratite se IT administratoru za rješavanje tog problema.</translation>
-<translation id="8130693978878176684">Više vam ne mogu pomagati, nastavite sami.</translation>
<translation id="8131740175452115882">Potvrdi</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>
@@ -1144,8 +1298,11 @@ Dodatne pojedinosti:
<translation id="8197543752516192074">Prevedi stranicu</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="8202370299023114387">Sukob</translation>
+<translation id="8206978196348664717">Prc4 (omotnica)</translation>
<translation id="8211406090763984747">Veza je sigurna</translation>
<translation id="8218327578424803826">Dodijeljena lokacija:</translation>
+<translation id="8220146938470311105">C7/C6 (omotnica)</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="8238581221633243064">Otvorite stranicu u novoj anonimnoj kartici</translation>
@@ -1157,14 +1314,16 @@ Dodatne pojedinosti:
<translation id="825929999321470778">Prikaži sve spremljene zaporke</translation>
<translation id="8261506727792406068">Izbriši</translation>
<translation id="8267698848189296333">Prijavljujete se kao <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Preglednikom upravlja <ph name="ENROLLMENT_DOMAIN" />. Vaš administrator može daljinski promijeniti postavke preglednika. Aktivnostima na tom uređaju može se upravljati i izvan Chromea. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Prijava</translation>
<translation id="8288807391153049143">Prikaz certifikata</translation>
<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="8298115750975731693">Za Wi-Fi koji upotrebljavate (<ph name="WIFI_NAME" />) možda ćete morati posjetiti stranicu <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Prijevod nije uspio zbog problema s mrežnom vezom.</translation>
-<translation id="8311129316111205805">Učitaj sesiju</translation>
<translation id="8332188693563227489">Pristup hostu <ph name="HOST_NAME" /> je odbijen</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1182,7 +1341,6 @@ Dodatne pojedinosti:
<translation id="8416694386774425977">Konfiguracija mreže nije važeća i nije se mogla uvesti.
Dodatne pojedinosti:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Uređajem upravlja <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Promijeni</translation>
<translation id="8428213095426709021">Postavke</translation>
@@ -1210,9 +1368,11 @@ Dodatne pojedinosti:
<translation id="860043288473659153">Ime vlasnika kartice</translation>
<translation id="861775596732816396">Veličina 4</translation>
<translation id="8620436878122366504">Roditelji je još nisu odobrili</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Spremi tu karticu na ovaj uređaj</translation>
<translation id="8663226718884576429">Sažetak narudžbe, <ph name="TOTAL_LABEL" />, više pojedinosti</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, odgovor, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Vaša veza s <ph name="DOMAIN" /> nije šifrirana.</translation>
<translation id="8718314106902482036">Plaćanje nije dovršeno</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, prijedlog za pretraživanje</translation>
@@ -1226,6 +1386,7 @@ Dodatne pojedinosti:
<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="8763927697961133303">USB uređaj</translation>
<translation id="8768895707659403558">Da biste sve svoje kartice upotrebljavali na svim svojim uređajima, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Ponovi brisanje</translation>
<translation id="8792621596287649091">Mogli biste izgubiti pristup svojem <ph name="ORG_NAME" /> računu ili bi netko mogao ukrasti vaš identitet. Chromium preporučuje da odmah promijenite zaporku.</translation>
<translation id="8800988563907321413">Ovdje se prikazuju prijedlozi u blizini za vas</translation>
@@ -1236,10 +1397,12 @@ Dodatne pojedinosti:
<translation id="885730110891505394">Dijeljenje s Googleom</translation>
<translation id="8858065207712248076">Chrome preporučuje poništavanje zaporke za organizaciju <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> ako ste je upotrebljavali za druge web-lokacije.</translation>
<translation id="8866481888320382733">Pogreška pri analizi postavki pravila</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nedavno zatvoreno</translation>
<translation id="8874824191258364635">Unesite važeći broj kreditne kartice</translation>
<translation id="8891727572606052622">Nevažeći način proxy poslužitelja.</translation>
<translation id="8903921497873541725">Povećaj</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Želite li spremiti tu karticu na Google račun?</translation>
<translation id="8932102934695377596">Sat kasni</translation>
<translation id="893332455753468063">Dodajte ime</translation>
@@ -1247,13 +1410,13 @@ Dodatne pojedinosti:
<translation id="894185898663964645">Administrator je konfigurirao prilagođene korijenske certifikate, što mu može omogućiti da vidi sadržaj web-lokacija koje posjećujete.</translation>
<translation id="8943282376843390568">Limeta</translation>
<translation id="8957210676456822347">Autorizacija obaveznog portala za autentifikaciju</translation>
+<translation id="8966619695390250636">Jeste li mislili?</translation>
<translation id="8968766641738584599">Spremanje kartice</translation>
<translation id="8971063699422889582">Istekao je certifikat poslužitelja.</translation>
<translation id="8975012916872825179">Sadrži podatke kao što su telefonski brojevi, e-adrese i adrese za dostavu</translation>
<translation id="8978053250194585037">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo krađu identiteta<ph name="END_LINK" /> 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="8983003182662520383">Načini plaćanja i adrese s Google Paya</translation>
<translation id="8987927404178983737">Mjesec</translation>
-<translation id="8988408250700415532">Došlo je do pogreške. Narudžbu možete dovršiti na web-lokaciji.</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>
@@ -1263,6 +1426,7 @@ Dodatne pojedinosti:
<translation id="9011424611726486705">Otvorite postavke web-lokacije</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Nije važeće)</translation>
<translation id="9035022520814077154">Sigurnosna pogreška</translation>
<translation id="9038649477754266430">Upotreba usluge predviđanja za brže učitavanje stranica</translation>
@@ -1274,12 +1438,12 @@ Dodatne pojedinosti:
<translation id="9065745800631924235">Pretraživanje <ph name="TEXT" /> iz povijesti</translation>
<translation id="9069693763241529744">Blokiralo proširenje</translation>
<translation id="9076283476770535406">Možda ima sadržaj za odrasle</translation>
+<translation id="9076630408993835509">Preglednikom ne upravlja tvrtka ili neka druga organizacija. Aktivnostima na tom uređaju možda se upravlja izvan Chromea. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Potrebno je više podataka</translation>
<translation id="9080712759204168376">Sažetak narudžbe</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
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 Chromium zaustavio povezivanje prije razmjene podataka.</translation>
<translation id="9106062320799175032">Dodajte adresu za naplatu</translation>
-<translation id="9110718169272311511">Google asistent u Chromeu dostupan je pri dnu zaslona</translation>
<translation id="9114524666733003316">Potvrđivanje kartice...</translation>
<translation id="9128870381267983090">Povezivanje s mrežom</translation>
<translation id="9137013805542155359">Prikaži original</translation>
@@ -1288,6 +1452,7 @@ 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="9158625974267017556">C6 (omotnica)</translation>
<translation id="9168814207360376865">Dopusti web-lokacijama da provjere imate li spremljene načine plaćanja</translation>
<translation id="9169664750068251925">Uvijek blokiraj na ovoj web-lokaciji</translation>
<translation id="9170848237812810038">&amp;Poništi</translation>
@@ -1302,10 +1467,12 @@ i netočne vjerodajnice. To može značiti da se neki napadač pokušava predsta
<translation id="9219103736887031265">Slike</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">IZBRIŠI OBRAZAC</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Mogli biste izgubiti pristup svojem Google računu. Chromium preporučuje da odmah promijenite zaporku. Morat ćete se prijaviti.</translation>
<translation id="939736085109172342">Nova mapa</translation>
<translation id="945855313015696284">Pregledajte informacije u nastavku i izbrišite nevažeće kartice</translation>
<translation id="951104842009476243">Prihvaćene debitne i pretplatne kartice</translation>
+<translation id="958202389743790697">Blokirano sigurnosnim pravilom koje određuje <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Ovaj sadržaj može pokušati 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_LINK" />Ipak prikaži<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Službeni sastavak</translation>
<translation id="973773823069644502">Dodajte adresu za isporuku</translation>
@@ -1314,6 +1481,7 @@ i netočne vjerodajnice. To može značiti da se neki napadač pokušava predsta
<translation id="984275831282074731">Načini plaćanja</translation>
<translation id="985199708454569384">&lt;p&gt;Ta će se pogreška prikazati ako datum i vrijeme na računalu ili mobilnom uređaju nisu točni.&lt;/p&gt;
&lt;p&gt;Da biste ispravili tu pogrešku, otvorite sat uređaja. Ako vrijeme i datum nisu točni, ispravite ih.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Sastavak razvojnog programera</translation>
<translation id="989988560359834682">Uređivanje adrese</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_hu.xtb b/chromium/components/strings/components_strings_hu.xtb
index 6167c0f92a7..6c801617b1a 100644
--- a/chromium/components/strings/components_strings_hu.xtb
+++ b/chromium/components/strings/components_strings_hu.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hu">
-<translation id="1005145902654145231">Nem sikerült átnevezni az munkamenetet.</translation>
<translation id="1008557486741366299">Ne most</translation>
<translation id="1010200102790553230">Oldal betöltése később</translation>
<translation id="1015730422737071372">További részletek megadása</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">Ismeretlen név</translation>
<translation id="1050038467049342496">Zárja be a többi alkalmazást</translation>
<translation id="1055184225775184556">&amp;Hozzáadás visszavonása</translation>
+<translation id="1056898198331236512">Figyelmeztetés</translation>
<translation id="1058479211578257048">Kártyák mentése…</translation>
<translation id="10614374240317010">Az alábbi oldalakról soha ne mentsen jelszavakat</translation>
+<translation id="1062160989074299343">Prc10 (boríték)</translation>
<translation id="106701514854093668">Asztali könyvjelzők</translation>
<translation id="1074497978438210769">Nem biztonságos</translation>
<translation id="1080116354587839789">Szélességhez igazítás</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Adja meg a kártyán szereplő nevet</translation>
<translation id="1089439967362294234">Jelszó módosítása</translation>
<translation id="109743633954054152">Jelszavak kezelése a Chrome beállításaiban</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Gyakran előfordulhatnak figyelmeztetések, amikor a webhelyek frissítik biztonsági megoldásaikat. Ez a helyzet hamarosan javulhat.</translation>
<translation id="1126551341858583091">A helyi tárolóban lévő fájl mérete <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Irányelv-gyorsítótár OK</translation>
+<translation id="1131264053432022307">Vágólapra másolt kép</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Átnevezés</translation>
<translation id="1175364870820465910">&amp;Nyomtatás...</translation>
<translation id="1181037720776840403">Eltávolítás</translation>
<translation id="1197088940767939838">Narancssárga</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Az eszköze neve</translation>
<translation id="124116460088058876">További nyelvek…</translation>
<translation id="1250759482327835220">A következő alkalommal gyorsabban fizethet, ha elmenti kártyáját, nevét és számlázási címét a Google-fiókjába.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (szinkronizálva)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Parancssorváltozatok</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="1314614906530272393">A kiválasztott munkamenet nem létezik.</translation>
+<translation id="1320233736580025032">Prc1 (boríték)</translation>
+<translation id="132301787627749051">Vágólapon lévő kép keresése</translation>
<translation id="1323433172918577554">Több</translation>
<translation id="132390688737681464">Címek mentése és betöltése</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:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Átvételi cím</translation>
<translation id="1348198688976932919">A felkeresni kívánt webhely veszélyes alkalmazásokat tartalmaz</translation>
<translation id="1348779747280417563">Név megerősítése</translation>
+<translation id="1357195169723583938">Ki és mikor használta az eszközt a közelmúltban?</translation>
+<translation id="1364822246244961190">Ez a házirend le van tiltva, ezért az értékét figyelmen kívül hagyja a rendszer.</translation>
<translation id="1374468813861204354">javaslatok</translation>
+<translation id="1374692235857187091">Index-4x6 (képeslap)</translation>
<translation id="1375198122581997741">A verzióról</translation>
<translation id="1376836354785490390">Kevesebb</translation>
<translation id="1377321085342047638">Kártyaszám</translation>
<translation id="138218114945450791">Világoskék</translation>
+<translation id="1382194467192730611">A rendszergazda által engedélyezett USB-eszköz</translation>
<translation id="139305205187523129">A(z) <ph name="HOST_NAME" /> nem küldött adatokat.</translation>
+<translation id="140316286225361634">A(z) <ph name="ORIGIN" /> webhely azt kérte, hogy egy adott biztonsági házirend
+ legyen alkalmazva az összes kérésére, és ez a házirend jelenleg
+ nem biztonságosnak ítéli meg a webhelyet.</translation>
<translation id="1405567553485452995">Világoszöld</translation>
<translation id="1407135791313364759">Összes megnyitása</translation>
<translation id="1413809658975081374">Adatvédelmi hiba</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Igen</translation>
<translation id="1430915738399379752">Nyomtatás</translation>
<translation id="1455413310270022028">Radír</translation>
+<translation id="1463543813647160932">5×7</translation>
+<translation id="1472675084647422956">Továbbiak megjelenítése</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Szállítási cím kiválasztása</translation>
+<translation id="1492194039220927094">Irányelvek leküldése:</translation>
<translation id="1501859676467574491">Jelenítsen meg kártyákat az Ön Google-fiókjából</translation>
-<translation id="1506687042165942984">Az oldal mentett (pl. köztudottan régi) változatának megjelenítése.</translation>
<translation id="1507202001669085618">&lt;p&gt;Ez a hiba akkor fordul elő, ha olyan Wi-Fi-portált használ, amely bejelentkezést igényel, mielőtt kapcsolódna az internethez.&lt;/p&gt;
&lt;p&gt;A hiba kijavításához kattintson a &lt;strong&gt;Csatlakozás&lt;/strong&gt; lehetőségre a megnyitni próbált oldalon.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonszám szükséges</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Build dátuma</translation>
<translation id="1521655867290435174">Google Táblázatok</translation>
<translation id="1527263332363067270">Várakozás a kapcsolódásra…</translation>
+<translation id="1529521330346880926">10x15 (boríték)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Az oldal közlendője</translation>
<translation id="153384715582417236">Egyelőre ennyi</translation>
<translation id="154408704832528245">Kézbesítési cím kiválasztása</translation>
<translation id="1549470594296187301">A funkció használatához engedélyezni kell a JavaScriptet.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Adja meg a lejárat dátumát</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Vágólapra másolt kép</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Akadályozza meg, hogy ez az oldal további párbeszédablakokat hozzon létre.</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Munkamenet befejezése</translation>
<translation id="1639239467298939599">Betöltés</translation>
<translation id="1640180200866533862">Felhasználói házirendek</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">A szervertanúsítvány gyenge titkosítási kulcsot tartalmaz.</translation>
<translation id="1697532407822776718">Máris elkészült!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">A dokumentum túl nagy a jegyzeteléshez</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Próbálja felvenni a kapcsolatot a rendszergazdával.</translation>
<translation id="1740951997222943430">Érvényes lejárati hónapot kell megadnia</translation>
<translation id="1743520634839655729">A következő alkalommal gyorsabban fizethet, ha kártyáját, nevét és számlázási címét elmenti Google-fiókjába és az eszközre.</translation>
+<translation id="1745880797583122200">A böngésző felügyelet alatt áll</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>
@@ -152,8 +172,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kártyatulajdonos neve</translation>
<translation id="1821930232296380041">Érvénytelen kérés vagy kérésparaméter</translation>
+<translation id="1822540298136254167">A felkeresett webhelyek és a rajtuk eltöltött idő</translation>
<translation id="1826516787628120939">Ellenőrzés</translation>
<translation id="1834321415901700177">A webhely ártalmas programokat tartalmaz</translation>
<translation id="1839551713262164453">A házirendértékek ellenőrzése hibák miatt sikertelen</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Törölje a Chrome böngészési előzményeit</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{és 1 további}other{és # további}}</translation>
<translation id="2003709556000175978">Jelszó visszaállítása</translation>
+<translation id="20053308747750172">A felkeresni kívánt szerver (<ph name="ORIGIN" />) egy adott biztonsági házirend
+ alkalmazását kérte az összes hozzá irányuló kérés esetében. De most
+ érvénytelen házirendet mutatott be, amely megakadályozza, hogy a böngésző
+ teljesítse a(z) <ph name="SITE" /> webhelyre irányuló kérelmet.</translation>
<translation id="2025186561304664664">Automatikusan konfigurálhatóra beállított proxy.</translation>
<translation id="2030481566774242610">Erre gondolt: <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />A proxy és a tűzfal ellenőrzése<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Megye</translation>
<translation id="2102134110707549001">Erős jelszó ajánlása…</translation>
<translation id="2108755909498034140">Indítsa újra a számítógépet</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kártya</translation>
<translation id="2114841414352855701">A rendszer figyelmen kívül hagyja, mivel a(z) <ph name="POLICY_NAME" /> felülírta.</translation>
<translation id="213826338245044447">Mobilos könyvjelzők</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (boríték)</translation>
<translation id="2181821976797666341">Házirendek</translation>
<translation id="2183608646556468874">Telefonszám</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 cím}other{# cím}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonszám</translation>
<translation id="2283340219607151381">Címek mentése és betöltése</translation>
<translation id="2292556288342944218">Az internethez való hozzáférést a rendszer letiltotta</translation>
+<translation id="2294558542833290837">Az eredetileg megnyitott link szokatlan</translation>
+<translation id="2297722699537546652">B5 (boríték)</translation>
+<translation id="2310021320168182093">Chou2 (boríték)</translation>
<translation id="2316887270356262533">1 MB-nál kevesebb hely szabadul fel. Előfordulhat, hogy egyes webhelyek lassabban töltődnek be, amikor legközelebb felkeresi őket.</translation>
<translation id="2317259163369394535">A(z) <ph name="DOMAIN" /> felhasználónevet és jelszót kér.</translation>
<translation id="2317583587496011522">Elfogadott bankkártyák.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, lejárat dátuma: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">A beállítást a rendszergazda szabályozza</translation>
+<translation id="2346319942568447007">Vágólapra másolt kép</translation>
<translation id="2349790679044093737">A VR-munkamenet aktív</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Ön privát módra váltott.</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">A felkeresni kívánt szerver (<ph name="ORIGIN" />) egy adott biztonsági házirend
+ alkalmazását kérte az összes hozzá irányuló kérés esetében. De most nem sikerült
+ bemutatnia a házirendet, így a böngésző nem tudja teljesíteni
+ a(z) <ph name="SITE" /> webhelyre irányuló kérelmet.</translation>
<translation id="244665789865330679">Eszközét és fiókját a(z) <ph name="ENROLLMENT_DOMAIN" /> kezeli. A rendszergazda távolról módosíthatja az eszköz és a fiók beállításait.</translation>
<translation id="2463193859425327265">Kezdőlap módosítása</translation>
<translation id="2463739503403862330">Kitöltés</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Kézbesítési mód kiválasztása</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Hálózati diagnosztika futtatása<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Oldal lefordítása</translation>
<translation id="2479410451996844060">Érvénytelen keresési URL</translation>
<translation id="2482878487686419369">Értesítések</translation>
<translation id="248348093745724435">A számítógép házirendjei</translation>
+<translation id="2485387744899240041">Az eszköz és a böngésző felhasználónevei</translation>
<translation id="2491120439723279231">A szervezet tanúsítványa hibákat tartalmaz.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Új kártya beolvasása</translation>
<translation id="2501278716633472235">Visszalépés</translation>
<translation id="2503184589641749290">Elfogadott bank- és feltöltőkártyák</translation>
<translation id="2515629240566999685">A térerő ellenőrzése tartózkodási helyén</translation>
-<translation id="2516852381693169964">Képkeresés a következővel: <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Csak erre az eszközre mentve</translation>
<translation id="2524461107774643265">További adatok hozzáadása</translation>
<translation id="2536110899380797252">Cím hozzáadása</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (boríték)</translation>
<translation id="2625385379895617796">Az órája siet</translation>
<translation id="2634124572758952069">A(z) <ph name="HOST_NAME" /> szerver IP-címe nem található.</translation>
<translation id="2639739919103226564">Állapot:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Zárja be a többi lapot vagy alkalmazást</translation>
<translation id="267371737713284912">visszavonás: <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Biztosan törölni szeretné ezeket az oldalakat az előzmények közül?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Lap elhagyása</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Elfogadott kártyák</translation>
<translation id="2702801445560668637">Olvasási lista</translation>
<translation id="2704283930420550640">Az érték nem egyezik a formátummal.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">A kijelölt elemek eltávolítása</translation>
<translation id="277133753123645258">Szállítási mód</translation>
<translation id="277499241957683684">Hiányzó eszközrekord</translation>
-<translation id="2781030394888168909">Exportálás MacOS-formátumban</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">A kapcsolat alaphelyzetbe állt.</translation>
<translation id="2788784517760473862">Elfogadott hitelkártyák</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Inkognitóablak megnyitása</translation>
+<translation id="2850739647070081192">Invite (boríték)</translation>
<translation id="2851634818064021665">A webhely felkereséséhez jogosultságra van szüksége</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Menti a kártyát?</translation>
<translation id="2903493209154104877">Címek</translation>
<translation id="290376772003165898">Az oldal nem <ph name="LANGUAGE" /> nyelvű?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Kézbesítési mód</translation>
<translation id="2928905813689894207">Számlázási cím</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (boríték)</translation>
<translation id="3024663005179499861">Nem megfelelő irányelvtípus</translation>
<translation id="3037605927509011580">A manóba!</translation>
<translation id="3041612393474885105">Tanúsítvány adatai</translation>
+<translation id="3060227939791841287">C9 (boríték)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Átvételi cím hozzáadása</translation>
<translation id="3105172416063519923">Tartalomazonosító:</translation>
<translation id="3109728660330352905">Nincs jogosultsága az oldal megjelenítésére.</translation>
@@ -362,20 +410,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> nyomtató a(z) <ph name="SERVER_NAME" /> nevű szerveren</translation>
<translation id="320323717674993345">Fizetés visszavonása</translation>
<translation id="3207960819495026254">Könyvjelző rögzítve</translation>
-<translation id="3209375525920864198">Érvényes munkamenetnevet adjon meg.</translation>
+<translation id="321912867715453276">Figyelem: Egynél több forrás van megadva a házirendnél, de az értékeik ugyanazok.</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="3229041911291329567">Az eszköz és a böngésző verzióadatai</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Adja meg a kártyán szereplő nevet</translation>
<translation id="3287510313208355388">Letöltés online állapotban</translation>
<translation id="3293642807462928945">További információ a(z) <ph name="POLICY_NAME" /> házirendről</translation>
<translation id="3303855915957856445">Nincs találat</translation>
-<translation id="3305707030755673451">Adatainak titkosítása megtörtént összetett szinkronizálási jelszavával a következő időpontban: <ph name="TIME" />. Adja meg a jelszót a szinkronizálás megkezdéséhez.</translation>
<translation id="3320021301628644560">Számlázási cím hozzáadása</translation>
<translation id="3324983252691184275">Karmazsinvörös</translation>
<translation id="3338095232262050444">Biztonságos</translation>
@@ -403,9 +452,11 @@
<translation id="3427342743765426898">&amp;Szerkesztés újra</translation>
<translation id="342781501876943858">A Chromium azt javasolja, hogy adjon meg új jelszót a régi helyett, ha azt más webhelyeken is használta.</translation>
<translation id="3431636764301398940">Kártya mentése az eszközre</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Az eszköz tulajdonosa kikapcsolta a dinoszauruszos játékot.</translation>
<translation id="3447884698081792621">Tanúsítvány megjelenítése (kibocsátó: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Lekérési intervallum:</translation>
+<translation id="3456231139987291353">Number-11 (boríték)</translation>
<translation id="3461824795358126837">Szövegkiemelő</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>
@@ -428,20 +479,23 @@
<translation id="358285529439630156">Elfogadott hitel- és feltöltőkártyák.</translation>
<translation id="3582930987043644930">Név hozzáadása</translation>
<translation id="3583757800736429874">&amp;Áthelyezés újra</translation>
+<translation id="35866233670761917">Az Ön által felkeresett webhelyek tartalmát a rendszergazdák nem láthatják</translation>
<translation id="3586931643579894722">Részletek elrejtése</translation>
+<translation id="3592413004129370115">Italian (boríték)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Méret: 2</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>
<translation id="362276910939193118">Az összes előzmény</translation>
-<translation id="3623476034248543066">Érték megjelenítése</translation>
<translation id="3630155396527302611">Ha már megjelenik a hálózat elérésére engedélyezett programként, próbálkozzon
az eltávolításával, majd a listára való ismételt felvételével.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Sikeres érvényesítés</translation>
<translation id="3655670868607891010">Ha gyakran látja ezt, próbálja ki a következőt: <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Ellenőrzés</translation>
<translation id="366077651725703012">Hitelkártya frissítése</translation>
<translation id="3676592649209844519">Eszközazonosító:</translation>
+<translation id="3677008721441257057">Erre gondolt: &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">A kérést nem lehetett aláírni</translation>
<translation id="3678529606614285348">Oldal megnyitása új inkognitóablakban (Ctrl+Shift+N)</translation>
<translation id="3679803492151881375">A hibajelentés elkészítésének ideje: <ph name="CRASH_TIME" />; a feltöltés ideje: <ph name="UPLOAD_TIME" /></translation>
@@ -449,13 +503,14 @@
<translation id="3704162925118123524">Előfordulhat, hogy az Ön által használt hálózat megköveteli a bejelentkezési oldalán történő bejelentkezést.</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="3709599264800900598">Vágólapra másolt szöveg</translation>
<translation id="3712624925041724820">Az engedélyek elfogytak</translation>
<translation id="3714780639079136834">A mobiladatok vagy a Wi-Fi bekapcsolása</translation>
<translation id="3715597595485130451">Csatlakozás Wi-Fi-hálózathoz</translation>
<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="372429172604983730">A hibát okozó alkalmazás lehet tűzfal, illetve víruskereső, webszűrő vagy proxyszoftver.</translation>
+<translation id="373042150751172459">B4 (boríték)</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="3745099705178523657">A megerősítést követően a böngésző megosztja az Ön Google-fiókjából származó kártyaadatokat ezzel a webhellyel.</translation>
<translation id="3748148204939282805">A támadók a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen 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, bankkártyaadatokat stb). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
@@ -468,10 +523,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Lejárat dátuma: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Méret: 16</translation>
+<translation id="3797522431967816232">Prc3 (boríték)</translation>
<translation id="3807873520724684969">Kártékony tartalom letiltva.</translation>
<translation id="3810973564298564668">Szerkesztés</translation>
<translation id="382518646247711829">Ha proxyszervert használ...</translation>
<translation id="3828924085048779000">Az üres összetett jelszó nem engedélyezett.</translation>
+<translation id="3831915413245941253">A(z) <ph name="ENROLLMENT_DOMAIN" /> bővítményeket telepített további funkciók használata céljából. A bővítmények hozzáférhetnek az Ön bizonyos adataihoz.</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>
@@ -479,6 +536,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Mindig kérdezze meg ezen a webhelyen</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>
@@ -489,11 +547,13 @@
<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="3984550557525787191">Ez a munkamenetnév már létezik.</translation>
<translation id="3987940399970879459">Kevesebb mint 1 MB</translation>
+<translation id="4008849406247176967">Figyelem: Több, egymással ütköző értékekkel rendelkező forrás található ennél a házirendnél.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 közeli weboldal}other{# közeli weboldal}}</translation>
<translation id="4030383055268325496">&amp;Hozzáadás visszavonása</translation>
+<translation id="4032320456957708163">Böngészőjét a(z) <ph name="ENROLLMENT_DOMAIN" /> felügyeli</translation>
<translation id="4058922952496707368">"<ph name="SUBKEY" />" kulcs: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (boríték)</translation>
<translation id="4067947977115446013">Érvényes címet adjon meg</translation>
<translation id="4072486802667267160">Hiba történt a rendelés feldolgozása közben. Kérjük, próbálja újra.</translation>
<translation id="4075732493274867456">Az ügyfél és a szerver nem támogat ugyanolyan SSL-protokollverziót vagy rejtjelezési csomagot.</translation>
@@ -513,10 +573,12 @@
<translation id="4159784952369912983">Lila</translation>
<translation id="4165986682804962316">Webhelybeállítások</translation>
<translation id="4171400957073367226">Hibás igazoló aláírás.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{ még <ph name="ITEM_COUNT" /> elem}other{ még <ph name="ITEM_COUNT" /> elem}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (boríték)</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="4221630205957821124">&lt;h4&gt;1. lépés: Jelentkezzen be a portálra&lt;/h4&gt;
@@ -548,58 +610,79 @@
<translation id="4277028893293644418">Jelszó visszaállítása</translation>
<translation id="4280429058323657511">, lejár: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{A kártyát mentettük a Google-fiókjába.}other{Ezeket a kártyákat mentettük a Google-fiókjába.}}</translation>
+<translation id="42981349822642051">Kibontás</translation>
+<translation id="4302965934281694568">Chou3 (boríték)</translation>
<translation id="4305817255990598646">Váltás</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Letiltás (alapértelmezett)</translation>
+<translation id="4318566738941496689">Az eszköz neve és hálózati címe</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="4340982228985273705">A rendszer nem vállalat által kezeltként érzékeli ezt a számítógépet, ezért a házirend csak a Chrome Internetes áruházban tárolt bővítményeket tudja automatikusan telepíteni. A Chrome Internetes áruház frissítési URL-je: <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Elfogadott hitelkártyák</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Előfordulhat, hogy a támadók ezen a webhelyen 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 bankkártyájának adatait).</translation>
<translation id="4358461427845829800">Fizetési módok kezelése…</translation>
+<translation id="4367563149485757821">Number-12 (boríték)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">keresési találat</translation>
-<translation id="4406972042435603828">A rendszergazdák nagy befolyást biztosító bővítményeket telepítettek.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> cookie</translation>
<translation id="4415426530740016218">Átvételi cím</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="443121186588148776">Soros port</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="4434045419905280838">Előugró ablakok és átirányítások</translation>
+<translation id="4435702339979719576">képeslap)</translation>
<translation id="443673843213245140">A proxy használata le van tiltva, de kifejezett proxykonfiguráció van megadva.</translation>
<translation id="445100540951337728">Elfogadott bankkártyák</translation>
+<translation id="4466881336512663640">Az űrlapon végzett módosítások elvesznek. Biztosan folytatni szeretné?</translation>
<translation id="4482953324121162758">Nem fordítjuk le ezt a webhelyet.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Érvénytelen URL. Az URL-nek szabványos sémával kell rendelkeznie, például http://example.com vagy https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (boríték)</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="4517607026994743406">Comm-10 (boríték)</translation>
<translation id="4522570452068850558">Részletek</translation>
<translation id="4524805452350978254">Kártyák kezelése</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Próbálkozzon a bővítmények letiltásával.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Szállítás</translation>
+<translation id="4579056131138995126">Personal (boríték)</translation>
<translation id="4582204425268416675">Kártya eltávolítása</translation>
<translation id="4587425331216688090">Eltávolítja a címet a Chrome-ból?</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="4597348597567598915">Méret: 8</translation>
+<translation id="4600854749408232102">C6/C5 (boríték)</translation>
<translation id="4646534391647090355">Megnézem most</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="467809019005607715">Google Diák</translation>
<translation id="4690462567478992370">Érvénytelen tanúsítvány használatának befejezése</translation>
+<translation id="4691835149146451662">Architecture-A (boríték)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Kapcsolata megszakadt</translation>
<translation id="471880041731876836">Nincs jogosultsága a webhely felkereséséhez</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />A Windows Hálózati diagnosztika futtatása<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Házirendek újratöltése</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (boríték)</translation>
<translation id="4736825316280949806">Indítsa újra a Chromiumot</translation>
<translation id="473775607612524610">Frissítés</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> keresési javaslat</translation>
<translation id="4742407542027196863">Jelszavak kezelése…</translation>
<translation id="4744603770635761495">Végrehajtható fájl útvonala</translation>
+<translation id="4746351372139058112">Üzenetek</translation>
<translation id="4750917950439032686">Adatai (például jelszava vagy hitelkártyaszáma) nem láthatók más számára, amikor a rendszer elküldi őket a webhelynek.</translation>
<translation id="4756388243121344051">&amp;Előzmények</translation>
<translation id="4758311279753947758">Névjegyadatok hozzáadása</translation>
@@ -607,9 +690,9 @@
<translation id="4764776831041365478">A <ph name="URL" /> weboldal ideiglenesen nem érhető el, vagy véglegesen új címre költözött.</translation>
<translation id="4771973620359291008">Ismeretlen hiba történt.</translation>
<translation id="4785689107224900852">Váltás erre a lapra</translation>
-<translation id="4792143361752574037">Hiba történt a munkamenetfájlok elérésekor. A lemezre történő mentés jelenleg nem lehetséges. Töltse be újra az oldalt, és próbálja meg ismét.</translation>
<translation id="4798078619018708837">A(z) <ph name="CREDIT_CARD" /> kártyához tartozó CVC-kód és lejárati dátum megadásával frissítheti a kártyaadatokat. A megerősítést követően a böngésző megosztja az Ön Google-fiókjából származó kártyaadatokat ezzel a webhellyel.</translation>
<translation id="4800132727771399293">Ellenőrizze a lejárati dátumot és a CVC-t, majd próbálja újra</translation>
+<translation id="480334179571489655">Eredet házirendhibája</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>
@@ -624,7 +707,6 @@
<translation id="4881695831933465202">Megnyitás</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>
@@ -633,15 +715,15 @@
<translation id="4943872375798546930">Nincs találat</translation>
<translation id="4950898438188848926">Lapváltó gomb. Nyomja meg az Entert a következő megnyitott lapra való váltáshoz: <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Műveletek</translation>
-<translation id="495832697253704892">Jelentés a bővítményekről</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Lista részletes nézete</translation>
<translation id="4974590756084640048">Figyelmeztetések újbóli engedélyezése</translation>
+<translation id="4984339528288761049">Prc5 (boríték)</translation>
<translation id="4989163558385430922">Összes megtekintése</translation>
<translation id="4989809363548539747">Ez a beépülő modul nem támogatott</translation>
-<translation id="4996230189582812866">Jelentés</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="5014174725590676422">A képernyőn a Google Segéd a Chrome-ban szolgáltatás első futtatáskor megjelenő képernyője látható</translation>
<translation id="5015510746216210676">Számítógépnév:</translation>
+<translation id="5017554619425969104">Vágólapra másolt szöveg</translation>
<translation id="5018422839182700155">Nem lehet megnyitni az oldalt</translation>
<translation id="5019198164206649151">A háttértároló állapota nem megfelelő</translation>
<translation id="5023310440958281426">Ellenőrizze rendszergazdai házirendjeit</translation>
@@ -651,35 +733,51 @@
<translation id="5034369478845443529">Helyi kontextus: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Engedélyezés</translation>
<translation id="5040262127954254034">Adatvédelem</translation>
+<translation id="5043480802608081735">Vágólapra másolt link</translation>
<translation id="5045550434625856497">Helytelen jelszó</translation>
<translation id="5056549851600133418">Cikkek Önnek</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />A proxy címének ellenőrzése<ph name="END_LINK" /></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="5097099694988056070">Eszközstatisztikák, például processzor- és memóriahasználat</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Eszközét a(z) <ph name="ENROLLMENT_DOMAIN" />, fiókját pedig a(z) <ph name="ACCOUNT_DOMAIN" /> kezeli. A rendszergazdák távolról módosíthatják eszköze és fiókja beállításait.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bites)</translation>
-<translation id="5128122789703661928">Ez a munkamenetnév nem érvényes, ezért nem törölhető.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Címek kezelése…</translation>
+<translation id="5138227688689900538">Kevesebb megjelenítése</translation>
<translation id="5141240743006678641">A szinkronizált jelszavak titkosítása a Google hitelesítési adataival</translation>
<translation id="5145883236150621069">Az irányelv válasza hibakódot tartalmaz</translation>
+<translation id="515292512908731282">C4 (boríték)</translation>
<translation id="5159010409087891077">Oldal megnyitása új inkognitóablakban (⇧⌘N)</translation>
<translation id="516920405563544094">Adja meg a(z) <ph name="CREDIT_CARD" /> kártya CVC-kódját. A megerősítést követően a böngésző megosztja majd az Ön Google-fiókjából származó kártyaadatokat ezzel a webhellyel.</translation>
<translation id="5169827969064885044">Elveszítheti a hozzáférést szervezete fiókjához, vagy visszaélhetnek személyes adataival. A Chrome azt javasolja, hogy azonnal módosítsa jelszavát.</translation>
<translation id="5171045022955879922">Keressen vagy írjon be egy URL-t</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Számítógép</translation>
<translation id="5179510805599951267">Nem <ph name="ORIGINAL_LANGUAGE" /> nyelven van? Hiba bejelentése</translation>
<translation id="5190835502935405962">Könyvjelzősáv</translation>
-<translation id="5200263511887412697">jelentés a közelmúltban bejelentkezett felhasználók listájáról</translation>
+<translation id="519422657042045905">A jelölési funkció nem áll rendelkezésre</translation>
<translation id="5201306358585911203">Az oldal egyik beágyazott oldalának közlendője</translation>
<translation id="5205222826937269299">A név megadása kötelező</translation>
<translation id="5215116848420601511">A Google Pay szolgáltatásban használt fizetési módok és címek</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Az e-mail-cím megadása kötelező</translation>
<translation id="5230733896359313003">Szállítási cím</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Csatlakozás a hálózathoz”</translation>
<translation id="5251803541071282808">Felhő</translation>
+<translation id="5252000469029418751">C7 (boríték)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Hálózati címek</translation>
<translation id="5285570108065881030">Az összes mentett jelszó megjelenítése</translation>
<translation id="5287240709317226393">Cookie-k megjelenítése</translation>
<translation id="5288108484102287882">A házirendértékek ellenőrzése során figyelmeztetések merültek fel</translation>
@@ -691,7 +789,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> elemből a következő pozícióban: <ph name="MATCH_POSITION" />.</translation>
<translation id="5324080437450482387">Kapcsolatfelvételi adatok kiválasztása</translation>
<translation id="5327248766486351172">Név</translation>
+<translation id="5329858041417644019">A böngésző nem áll felügyelet alatt</translation>
<translation id="5332219387342487447">Szállítási mód</translation>
+<translation id="5334013548165032829">Részletes rendszernaplók</translation>
<translation id="5344579389779391559">Ez az oldal fizetésre próbálhatja meg rávenni</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>
@@ -699,6 +799,7 @@
<translation id="5377026284221673050">„Az óra késik”, „Az óra siet” vagy „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">Ha az összes eszközén szeretné használni kártyáit, jelentkezzen be, és kapcsolja be a szinkronizálást.</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="538659543871111977">A4-Tab</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>
@@ -709,6 +810,7 @@
<translation id="5457113250005438886">Érvénytelen</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Szerkesztés újra</translation>
+<translation id="5478437291406423475">B6/C4 (boríték)</translation>
<translation id="5481076368049295676">Lehet, hogy ez a tartalom megpróbál olyan veszélyes szoftvert telepíteni az eszközre, 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="54817484435770891">Érvényes címet adjon meg</translation>
<translation id="5490432419156082418">Címek és egyebek</translation>
@@ -716,10 +818,12 @@
<ph name="LINE_BREAK" />
Javasoljuk, hogy forduljon a rendszergazdához.</translation>
<translation id="549333378215107354">Méret: 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Kezelt könyvjelzők</translation>
<translation id="5510766032865166053">Előfordulhat, hogy át lett helyezve, vagy törölve lett.</translation>
<translation id="5523118979700054094">Az irányelv neve</translation>
<translation id="552553974213252141">Megfelelően kinyerte a szöveget?</translation>
+<translation id="553484882784876924">Prc6 (boríték)</translation>
<translation id="5540224163453853">A kért cikk nem található.</translation>
<translation id="5541546772353173584">E-mail-cím hozzáadása</translation>
<translation id="5545756402275714221">Cikkek Önnek</translation>
@@ -734,15 +838,21 @@
<translation id="5595485650161345191">Cím szerkesztése</translation>
<translation id="5598944008576757369">Fizetési mód kiválasztása</translation>
<translation id="560412284261940334">A kezelés nem támogatott</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">A(z) <ph name="HOST_NAME" /> túl sokszor irányította át.</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="5632627355679805402">Adatai titkosítva lettek <ph name="BEGIN_LINK" />Google-jelszavával<ph name="END_LINK" /> ekkor: <ph name="TIME" />. Adja meg a jelszót a szinkronizálás megkezdéséhez.</translation>
<translation id="5633066919399395251">Előfordulhat, hogy a támadók a(z) <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> webhelyen 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 bankkártyájának adatait). <ph name="BEGIN_LEARN_MORE_LINK" />További információ<ph name="END_LEARN_MORE_LINK" />.</translation>
<translation id="563324245173044180">Megtévesztő tartalom letiltva.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (boríték)</translation>
+<translation id="5663955426505430495">Az eszköz rendszergazdája bővítményeket telepített további funkciók használata céljából. A bővítmények hozzáférhetnek az Ön bizonyos adataihoz.</translation>
<translation id="5675650730144413517">Az oldal nem működik</translation>
+<translation id="5684874026226664614">Hoppá! Az oldalt nem sikerült lefordítani.</translation>
<translation id="5685654322157854305">Szállítási cím hozzáadása</translation>
<translation id="5689199277474810259">Exportálás JSON formátumba</translation>
<translation id="5689516760719285838">Tartózkodási hely</translation>
@@ -751,38 +861,39 @@
<translation id="5710435578057952990">A webhely valódiságát nem ellenőriztük.</translation>
<translation id="5719499550583120431">Elfogadott feltöltőkártyák.</translation>
<translation id="5720705177508910913">Jelenlegi felhasználó</translation>
+<translation id="5728056243719941842">C5 (boríték)</translation>
<translation id="5730040223043577876">A Chrome azt javasolja, hogy adjon meg új jelszót a régi helyett, ha azt más webhelyeken is használta.</translation>
<translation id="5732392974455271431">A letiltást a szüleid oldhatják fel</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Kártya mentése a Google-fiókba}other{Kártyák mentése a Google-fiókba}}</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="5770114862687765385">Úgy tűnik, a fájl sérült. A munkamenet visszaállításához kattintson a „Visszaállítás” gombra.</translation>
<translation id="5778550464785688721">MIDI eszközök – teljes hozzáférés</translation>
<translation id="578305955206182703">Borostyánsárga</translation>
<translation id="57838592816432529">Némítá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>
+<translation id="5798290721819630480">Elveti a módosításokat?</translation>
<translation id="5798683403665926540">Kezdőlap módosítása a Chrome beállításaiban</translation>
<translation id="5803412860119678065">Ki szeretné tölteni <ph name="CARD_DETAIL" /> kártyájának adataival?</translation>
<translation id="5804241973901381774">Engedélyek</translation>
<translation id="5810442152076338065">A(z) <ph name="DOMAIN" /> domainnel való kapcsolata elavult kriptográfiával van titkosítva.</translation>
<translation id="5813119285467412249">&amp;Hozzáadás újra</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="5860033963881614850">Kikapcsolva</translation>
<translation id="5863847714970149516">Előfordulhat, hogy a következő oldal megpróbál pénzt felszámolni Önnek</translation>
<translation id="5866257070973731571">Telefonszám hozzáadása</translation>
<translation id="5869405914158311789">A webhely nem érhető el</translation>
<translation id="5869522115854928033">Mentett jelszavak</translation>
<translation id="5887400589839399685">Kártya elmentve</translation>
-<translation id="5893718151540690985">jelentés a hálózati interfészekről, típusukról és hardvercímeikről</translation>
<translation id="5893752035575986141">Elfogadott hitelkártyák.</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="5916664084637901428">Be</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Menti a kártyát a Google-fiókjába?</translation>
<translation id="5922853866070715753">Majdnem kész</translation>
<translation id="5932224571077948991">A webhely tolakodó vagy félrevezető hirdetéseket jelenít meg</translation>
-<translation id="5939518447894949180">Visszaállítás</translation>
<translation id="5946937721014915347">A(z) <ph name="SITE_NAME" /> megnyitása…</translation>
<translation id="5951495562196540101">Fogyasztói fiókkal nem lehet regisztrálni (a csomaghoz tartozik licenc is).</translation>
<translation id="5967592137238574583">Kapcsolattartási adatok szerkesztése</translation>
@@ -790,6 +901,7 @@
<translation id="5975083100439434680">Kicsinyítés</translation>
<translation id="5977489021191000276">Eszközét nem kezeli rendszergazda.</translation>
<translation id="5977976211062815271">Ezen az eszközön</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nem sikerült megnyitni a fizetőalkalmazást</translation>
<translation id="5989320800837274978">Sem fix proxyszerver, sem pedig .pac típusú szkript URL-címe nincs megadva.</translation>
<translation id="5990559369517809815">A szerver felé irányuló kéréseket egy bővítmény blokkolja.</translation>
@@ -800,8 +912,8 @@
<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="6033927989869462158">jelentés a hardverstatisztikákról, például a CPU és a RAM kihasználtságáról</translation>
<translation id="6034000775414344507">Világosszürke</translation>
+<translation id="6034283069659657473">10x14 (boríték)</translation>
<translation id="6039846035001940113">Ha a probléma továbbra is fennáll, lépjen kapcsolatba a webhely tulajdonosával.</translation>
<translation id="6040143037577758943">Bezárás</translation>
<translation id="6044573915096792553">Méret: 12</translation>
@@ -810,10 +922,10 @@
<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="6058977677006700226">Minden eszközén szeretné használni a kártyákat?</translation>
<translation id="6059925163896151826">USB-eszközök</translation>
-<translation id="6071091556643036997">A házirend típusa érvénytelen.</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="6094273045989040137">Jegyzetelés</translation>
<translation id="610911394827799129">Előfordulhat, hogy a böngészési előzmények más formái még megtalálhatók Google-fiókjában a <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webhelyen</translation>
+<translation id="6132597952260690497">Információ a telepített bővítményekről és beépülő modulokról</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>
@@ -848,15 +960,21 @@
<translation id="6337133576188860026"><ph name="SIZE" />-nál kevesebb hely szabadul fel. Előfordulhat, hogy egyes webhelyek lassabban töltődnek be, amikor legközelebb felkeresi őket.</translation>
<translation id="6337534724793800597">Házirendek szűrése név szerint</translation>
<translation id="6358450015545214790">Mit jelent ez?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Itt fizetésre próbálhatják rávenni.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 egyéb javaslat}other{# egyéb javaslat}}</translation>
<translation id="6387754724289022810">A következő alkalommal gyorsabban fizethet, ha kártyáját és számlázási címét elmenti Google-fiókjába és az eszközre.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Könyvjelző szerkesztése</translation>
+<translation id="6406765186087300643">C0 (boríték)</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="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="6434309073475700221">Elvetés</translation>
+<translation id="6446163441502663861">Kahu (boríték)</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>
@@ -869,11 +987,17 @@
<translation id="6508722015517270189">Indítsa újra a Chrome-ot</translation>
<translation id="6529602333819889595">&amp;Törlés újra</translation>
<translation id="6534179046333460208">Fizikai web – javaslatok</translation>
+<translation id="6556866813142980365">Újra</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="6578796323535178455">C2 (boríték)</translation>
<translation id="6579990219486187401">Világos rózsaszín</translation>
+<translation id="6583674473685352014">B6 (boríték)</translation>
+<translation id="6587923378399804057">Vágólapra másolt link</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> eszköze nem áll felügyelet alatt</translation>
<translation id="6596325263575161958">Titkosítási lehetőségek</translation>
<translation id="6604181099783169992">Mozgás- és fényérzékelők</translation>
+<translation id="6609880536175561541">Prc7 (boríték)</translation>
<translation id="6624427990725312378">Kapcsolatfelvételi adatok</translation>
<translation id="6626291197371920147">Adjon meg érvényes kártyaszámot</translation>
<translation id="6628463337424475685">Keresés: <ph name="ENGINE" /></translation>
@@ -882,6 +1006,7 @@
<translation id="6644283850729428850">Ez a házirend már elavult.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nincs}=1{1 webhelyről (a böngésző nem jelentkezteti ki Google-fiókjából)}other{# webhelyről (a böngésző nem jelentkezteti ki Google-fiókjából)}}</translation>
<translation id="6657585470893396449">Jelszó</translation>
+<translation id="6670613747977017428">Vissza a biztonsághoz.</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>
@@ -889,12 +1014,15 @@
<translation id="671076103358959139">Regisztrációs token</translation>
<translation id="6711464428925977395">Valami gond van a proxyszerverrel, vagy a cím nem megfelelő.</translation>
<translation id="6723740634201835758">Google-fiókban</translation>
+<translation id="6738516213925468394">Adatai titkosítva lettek <ph name="BEGIN_LINK" />összetett szinkronizálási jelszavával<ph name="END_LINK" /> a következő időpontban: <ph name="TIME" />. Adja meg a jelszót a szinkronizálás megkezdéséhez.</translation>
<translation id="674375294223700098">Ismeretlen szervertanúsítvány-hiba.</translation>
<translation id="6744009308914054259">Miközben kapcsolatra vár, a Letöltések között elolvashatja az offline cikkeket.</translation>
<translation id="6753269504797312559">Házirend értéke</translation>
<translation id="6757797048963528358">Eszköze alvó üzemmódba váltott.</translation>
+<translation id="6768213884286397650">Hagaki (képeslap)</translation>
<translation id="6778737459546443941">A szülő még nem hagyta jóvá</translation>
<translation id="67862343314499040">Ibolyaszín</translation>
+<translation id="6786747875388722282">Bővítmények</translation>
<translation id="679355240208270552">Figyelmen kívül hagyva, mert az alapértelmezett keresőmotort nem engedélyezi a házirend.</translation>
<translation id="681021252041861472">Kötelező mező</translation>
<translation id="6810899417690483278">Testreszabás-azonosító</translation>
@@ -927,10 +1055,12 @@
<translation id="6965978654500191972">Készülék</translation>
<translation id="6970216967273061347">Körzet</translation>
<translation id="6973656660372572881">Mindkét fix proxyszerver és egy .Pac típusú szkript URL-címe meg van adva.</translation>
+<translation id="6973932557599545801">Sajnos nem tudok többet segíteni. Kérjük, folytassa egyedül.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Némítás (alapértelmezett)</translation>
<translation id="6984479912851154518">Elhagyja a privát módot külső alkalmazással történő fizetéshez. Folytatja?</translation>
<translation id="6989763994942163495">Speciális beállítások megjelenítése...</translation>
+<translation id="6993898126790112050">6x9 (boríték)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> – mindig legyen lefordítva</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Ezek egyszeri vagy ismétlődő díjak lehetnek, és nem feltétlenül nyilvánvalóak.</translation>
@@ -946,28 +1076,36 @@
<translation id="7108338896283013870">Elrejtés</translation>
<translation id="7108819624672055576">Bővítmény engedélyezi</translation>
<translation id="7111012039238467737">(Érvényes)</translation>
+<translation id="7118618213916969306">Vágólapon lévő URL, <ph name="SHORT_URL" /> keresése</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="7135130955892390533">Állapot megjelenítése</translation>
<translation id="7138472120740807366">Kézbesítési mód</translation>
<translation id="7139724024395191329">Emírség</translation>
+<translation id="7152423860607593928">Number-14 (boríték)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Levendula</translation>
-<translation id="7158980942472052083">Érvénytelen URL. Az URL-nek szabványos sémával kell rendelkeznie.</translation>
<translation id="717330890047184534">Gaia-azonosító:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">A felkeresni kívánt szerver (<ph name="ORIGIN" />) egy adott biztonsági házirend
+ alkalmazását kérte az összes hozzá irányuló kérés esetében. De ahelyett, hogy
+ átadta volna a házirendet, átirányította máshova a böngészőt, megakadályozva,
+ hogy a böngésző teljesítse a(z) <ph name="SITE" /> webhelyre irányuló kérelmet.</translation>
<translation id="7179323680825933600">Fizetési módok mentése és betöltése</translation>
<translation id="7180611975245234373">Frissítés</translation>
<translation id="7182878459783632708">Nincsenek beállított házirendek</translation>
<translation id="7186367841673660872">Ezt az oldalt<ph name="ORIGINAL_LANGUAGE" />nyelvről fordítottuk<ph name="LANGUAGE_LANGUAGE" />nyelvre.</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> szabadul fel. Előfordulhat, hogy bizonyos oldalak lassabban töltődnek be, amikor legközelebb felkeresi őket.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Rendszergazdája a következőket láthatja:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">A(z) <ph name="HOST_NAME" /> nem felel meg a biztonsági szabványoknak.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />További információ<ph name="END_LINK" /> erről a hibáról.</translation>
<translation id="7219179957768738017">A kapcsolat a következőt használja: <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Feldolgozás alatt</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">A megnyíló oldal rosszindulatú programot tartalmaz</translation>
+<translation id="724766306220616965">Figyelmeztetések, ütközés</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="7251437084390964440">A hálózati konfiguráció nem felel meg az ONC szabványnak. A konfiguráció egyes részeit nem lehet importálni.
További részletek:
@@ -980,11 +1118,14 @@ További részletek:
<translation id="7300012071106347854">Kobaltkék</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />”</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="7313965965371928911">A <ph name="BEGIN_LINK" />Biztonságos böngészés<ph name="END_LINK" /> figyelmeztetései</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Segítség a kapcsolódáshoz</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Parancssor</translation>
-<translation id="7365061714576910172">Exportálás Linux-formátumban</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>
@@ -992,6 +1133,7 @@ További részletek:
<translation id="7381288752349550461">Felügyelt munkameneti felülbírálat</translation>
<translation id="7390545607259442187">Kártya igazolása</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> eszköze felügyelet alatt áll</translation>
<translation id="7407424307057130981">&lt;p&gt;Ez a hibaüzenet akkor jelenik meg, ha Superfish szoftverrel rendelkezik Windows rendszerű számítógépen.&lt;/p&gt;
&lt;p&gt;Kövesse ezeket a lépéseket, ha szeretné átmenetileg letiltani a szoftvert, hogy hozzáférhessen az internethez. Ehhez rendszergazdai jogosultságokra lesz szüksége.&lt;/p&gt;
&lt;ol&gt;
@@ -1002,7 +1144,7 @@ További részletek:
&lt;li&gt;Kattintson az &lt;strong&gt;Alkalmaz&lt;/strong&gt;, majd az &lt;strong&gt;OK&lt;/strong&gt; gombra.
&lt;li&gt;Keresse fel a &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome súgóját&lt;/a&gt;, ahol további információt talál a szoftver számítógépről történő végleges eltávolításáról.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> kezelése</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Jelszavak kezelése…</translation>
<translation id="7419106976560586862">Profil elérési útja</translation>
<translation id="7437289804838430631">Kapcsolatfelvételi adatok hozzáadása</translation>
@@ -1011,22 +1153,24 @@ További részletek:
<translation id="7442725080345379071">Világos narancssárga</translation>
<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="7449109375006139765">rendszernaplók küldése a kezelőszervernek</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="7460618730930299168">Az előzetes vetítés eltér az Ön által kijelölttől. Folytatja?</translation>
<translation id="7473891865547856676">Nem, köszönöm</translation>
-<translation id="7475525192983021547">jelentés az eszköz aktív használatának időszakairól</translation>
<translation id="7481312909269577407">Előre</translation>
<translation id="7485870689360869515">Nem található adat.</translation>
+<translation id="7498234416455752244">Szerkesztés folytatása</translation>
<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="7508870219247277067">Avokádózöld</translation>
<translation id="7511955381719512146">Az Ön által használt Wi-Fi-hálózat megkövetelheti a(z) <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> felkeresését.</translation>
<translation id="7514365320538308">Letöltés</translation>
<translation id="7518003948725431193">Nem található weboldal az internetcímen:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (boríték)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">A webhellyel való kapcsolata nem privát</translation>
+<translation id="7535087603100972091">Érték</translation>
<translation id="7537536606612762813">Kötelező</translation>
+<translation id="7538364083937897561">A2 (boríték)</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>
@@ -1035,8 +1179,8 @@ További részletek:
<translation id="7552846755917812628">Próbálja ki az alábbi tippeket:</translation>
<translation id="7554791636758816595">Új lap</translation>
<translation id="7564049878696755256">Elveszítheti hozzáférést <ph name="ORG_NAME" />-fiókjához, vagy visszaélhetnek személyes adataival. A Chrome azt javasolja, hogy azonnal módosítsa jelszavát.</translation>
-<translation id="7566125604157659769">Vágólapra másolt szöveg</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="7568105740864181217">Ezt a böngészőt egy cég, iskola vagy más szervezet kezeli. A rendszergazda távolról tudja módosítani a böngészőbeállításokat. Az is lehetséges, hogy az eszközön végzett tevékenységeket a Chrome-on kívülről felügyelik. <ph name="BEGIN_LINK" />További információ.<ph name="END_LINK" /></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>
@@ -1047,6 +1191,7 @@ További részletek:
<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="7633909222644580952">Teljesítményre vonatkozó adatok és hibajelentések</translation>
<translation id="7637571805876720304">Eltávolítja a hitelkártyát a Chromiumból?</translation>
<translation id="7639968568612851608">Sötétszürke</translation>
<translation id="765676359832457558">Speciális beállítások elrejtése...</translation>
@@ -1056,9 +1201,11 @@ További részletek:
<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="7676643023259824263">Vágólapon lévő szöveg keresése, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Keresőmotor megváltoztatása</translation>
<translation id="7682287625158474539">Szállítási cím</translation>
<translation id="7687186412095877299">Kitölti a fizetési űrlapokat az Ön mentett fizetési módjaival</translation>
+<translation id="7697066736081121494">Prc8 (boríték)</translation>
<translation id="769721561045429135">Jelenleg vannak olyan kártyái, amelyek csak ezen az eszközön használhatók Kattintson a Folytatás lehetőségre a kártyák áttekintéséhez.</translation>
<translation id="7699293099605015246">A cikkek jelenleg nem állnak rendelkezésre</translation>
<translation id="7701040980221191251">Nincs</translation>
@@ -1070,11 +1217,13 @@ További részletek:
<translation id="774634243536837715">Veszélyes tartalom letiltva.</translation>
<translation id="7752995774971033316">Nem kezelt</translation>
<translation id="7755287808199759310">A letiltást a szülő oldhatja fel</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Előfordulhat, hogy a tűzfal vagy a vírusirtó szoftver tiltotta le a kapcsolatot.</translation>
<translation id="7759163816903619567">Megjelenített domain:</translation>
<translation id="7761701407923456692">A szerver tanúsítványa nem egyezik az URL-lel</translation>
<translation id="7763386264682878361">Fizetésijegyzék-elemző</translation>
<translation id="7764225426217299476">Cím hozzáadása</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektúra</translation>
<translation id="7791543448312431591">Hozzáadás</translation>
<translation id="7793809570500803535">Lehetséges, hogy a(z) <ph name="SITE" /> webhelyen található oldal ideiglenesen nem érhető el, vagy véglegesen új címre költözött.</translation>
@@ -1086,8 +1235,8 @@ További részletek:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Eltávolítja a javaslatot a Chrome-ból?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> található a(z) „<ph name="SEARCH_STRING" />” kifejezésre</translation>
-<translation id="7818867226424560206">Irányelvkezelés</translation>
<translation id="782886543891417279">Az Ön által használt Wi-Fi-hálózat (<ph name="WIFI_NAME" />) megkövetelheti a bejelentkezést a bejelentkezési oldalán.</translation>
+<translation id="7836231406687464395">Postfix (boríték)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nincs}=1{1 alkalmazás (<ph name="EXAMPLE_APP_1" />)}=2{2 alkalmazás (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# alkalmazás (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Azonban Ön nem teljesen láthatatlan. Az inkognitómód használata nem rejti el böngészési műveleteit munkáltatója, az internetszolgáltatója és a felkeresett webhelyek elől.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1096,7 +1245,7 @@ További részletek:
<translation id="7878562273885520351">Előfordultat, hogy jelszava már nem biztonságos</translation>
<translation id="7882421473871500483">Barna</translation>
<translation id="7887683347370398519">Ellenőrizze a CVC-t, majd próbálja újra</translation>
-<translation id="7893255318348328562">Munkamenet neve</translation>
+<translation id="7904208859782148177">C3 (boríték)</translation>
<translation id="79338296614623784">Érvényes telefonszámot adjon meg</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Lejárat dátuma: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1106,21 +1255,25 @@ További részletek:
<translation id="7951415247503192394">(32 bites)</translation>
<translation id="7956713633345437162">Mobilos könyvjelzők</translation>
<translation id="7961015016161918242">Soha</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Böngésző</translation>
<translation id="8009225694047762179">Jelszó kezelése</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{A kártyát és a számlázási címet elmentjük. Az adatok kéznél lesznek, amíg <ph name="USER_EMAIL" /> e-mail-című fiókját használja.}other{A kártyákat és a számlázási címeket elmentjük. Az adatok kéznél lesznek, amíg <ph name="USER_EMAIL" /> e-mail-című fiókját használja.}}</translation>
<translation id="8012647001091218357">Jelenleg nem tudjuk elérni szüleidet. Próbálkozz újra.</translation>
<translation id="8025119109950072390">A támadók ezen a webhelyen 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="8034522405403831421">Ez az oldal <ph name="SOURCE_LANGUAGE" /> nyelven van. Lefordítja <ph name="TARGET_LANGUAGE" /> nyelvre?</translation>
<translation id="8035152190676905274">Toll</translation>
+<translation id="8037117624646282037">Ki használta az eszközt a közelmúltban?</translation>
<translation id="8037357227543935929">Kérdezzen rá (alapértelmezés szerint)</translation>
<translation id="803771048473350947">Fájl</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="8042918947222776840">Átvételi mód kiválasztása</translation>
<translation id="8057711352706143257">A(z) „<ph name="SOFTWARE_NAME" />” nincs megfelelően beállítva. A(z) „<ph name="SOFTWARE_NAME" />” eltávolítása általában megoldja a problémát. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Eszközét a következőkre konfigurálták:</translation>
+<translation id="8066955247577885446">Sajnos hiba történt.</translation>
+<translation id="8074253406171541171">10x13 (boríték)</translation>
<translation id="8078141288243656252">Elforgatott állapotban nem lehetséges a jegyzetelés</translation>
<translation id="8079031581361219619">Újratölti a webhelyet?</translation>
<translation id="8088680233425245692">Nem sikerült megtekinteni a cikket.</translation>
@@ -1129,11 +1282,12 @@ További részletek:
<translation id="8091372947890762290">Az aktiválás függőben van a szerveren</translation>
<translation id="8092774999298748321">Mélylila</translation>
<translation id="8094917007353911263">Az Ön által használt hálózat megkövetelheti a(z) <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> felkeresését.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Az érvénytelen kártyákat eltávolítottuk</translation>
<translation id="8103161714697287722">Fizetési mód</translation>
<translation id="8118489163946903409">Fizetési mód</translation>
+<translation id="8123836779274890062">A(z) <ph name="DEVICE_TYPE" /> kezelője: <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">A(z) „<ph name="SOFTWARE_NAME" />” nem megfelelően lett telepítve a számítógépre vagy a hálózatra. A probléma elhárítása érdekében forduljon rendszergazdájához.</translation>
-<translation id="8130693978878176684">Nem tudok többet segíteni, folytassa önállóan.</translation>
<translation id="8131740175452115882">Megerősítés</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>
@@ -1143,8 +1297,11 @@ További részletek:
<translation id="8197543752516192074">Oldal lefordítá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="8202370299023114387">Ütközés</translation>
+<translation id="8206978196348664717">Prc4 (boríték)</translation>
<translation id="8211406090763984747">A kapcsolat biztonságos</translation>
<translation id="8218327578424803826">Hozzárendelt helyszín:</translation>
+<translation id="8220146938470311105">C7/C6 (boríték)</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="8238581221633243064">Oldal megnyitása új inkognitóablakban</translation>
@@ -1156,14 +1313,16 @@ További részletek:
<translation id="825929999321470778">Az összes mentett jelszó megjelenítése</translation>
<translation id="8261506727792406068">Törlés</translation>
<translation id="8267698848189296333">Bejelentkezés mint <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Ezt a böngészőt a(z) <ph name="ENROLLMENT_DOMAIN" /> kezeli. Rendszergazdája távolról módosíthatja a böngészőbeállításokat. Az is lehetséges, hogy az eszközön végzett tevékenységeket a Chrome-on kívülről felügyelik. <ph name="BEGIN_LINK" />További információ.<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Bejelentkezés</translation>
<translation id="8288807391153049143">Tanúsítvány megjelenítése</translation>
<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="8298115750975731693">Az Ön által használt Wi-Fi-hálózat (<ph name="WIFI_NAME" />) megkövetelheti a(z) <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> felkeresését.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">A fordítás a hálózati kapcsolat problémája miatt nem sikerült.</translation>
-<translation id="8311129316111205805">Munkamenet betöltése</translation>
<translation id="8332188693563227489">A hozzáférés megtagadva a következőhöz: <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1181,7 +1340,6 @@ További részletek:
<translation id="8416694386774425977">A hálózati konfiguráció érvénytelen és nem importálható.
További részletek:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">A(z) <ph name="ENROLLMENT_DOMAIN" /> által kezelt eszköz</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Módosítás</translation>
<translation id="8428213095426709021">Beállítások</translation>
@@ -1209,9 +1367,11 @@ További részletek:
<translation id="860043288473659153">Kártyatulajdonos neve</translation>
<translation id="861775596732816396">Méret: 4</translation>
<translation id="8620436878122366504">A szüleid még nem hagyták jóvá</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Kártya mentése az eszközre</translation>
<translation id="8663226718884576429">Rendelés-összefoglaló, <ph name="TOTAL_LABEL" />, További részletek</translation>
<translation id="8680536109547170164"><ph name="QUERY" />. A válasz: <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">A kapcsolat (<ph name="DOMAIN" />) nem titkosított.</translation>
<translation id="8718314106902482036">A fizetés nem fejeződött be</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, keresési javaslat</translation>
@@ -1225,6 +1385,7 @@ További részletek:
<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="8763927697961133303">USB-eszköz</translation>
<translation id="8768895707659403558">Ha az összes eszközön szeretné használni a kártyákat: <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Törlés újra</translation>
<translation id="8792621596287649091">Elveszítheti a hozzáférést <ph name="ORG_NAME" />-fiókjához, vagy visszaélhetnek személyes adataival. A Chromium azt javasolja, hogy azonnal módosítsa jelszavát.</translation>
<translation id="8800988563907321413">A közeli javaslatok helye</translation>
@@ -1235,10 +1396,12 @@ További részletek:
<translation id="885730110891505394">Megosztás a Google-lal</translation>
<translation id="8858065207712248076">A Chrome azt javasolja, hogy adjon meg új <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />-jelszót a régi helyett, ha azt más webhelyeken is használta.</translation>
<translation id="8866481888320382733">Irányelv-beállítások előfeldolgozási hibája</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Mostanában bezárt</translation>
<translation id="8874824191258364635">Érvényes kártyaszámot adjon meg</translation>
<translation id="8891727572606052622">Érvénytelen proxymód.</translation>
<translation id="8903921497873541725">Nagyítás</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Név hozzáadása</translation>
@@ -1246,13 +1409,13 @@ További részletek:
<translation id="894185898663964645">A rendszergazda egyéni gyökérszintű tanúsítványokat állított be, amelyekkel láthatja az Ön által meglátogatott webhelyek tartalmát.</translation>
<translation id="8943282376843390568">Limezöld</translation>
<translation id="8957210676456822347">Hitelesítés hitelesítési portállal</translation>
+<translation id="8966619695390250636">Erre gondolt?</translation>
<translation id="8968766641738584599">Kártya mentése</translation>
<translation id="8971063699422889582">A szerver tanúsítványa lejárt.</translation>
<translation id="8975012916872825179">Olyan adatokat tartalmaz, mint a telefonszámok, az e-mail-címek és a szállítási címek</translation>
<translation id="8978053250194585037">A Google Biztonságos Böngészés funkciója nemrégiben <ph name="BEGIN_LINK" />adathalászatot észlelt<ph name="END_LINK" /> a következő webhelyen: <ph name="SITE" />. Az adathalász webhelyek más webhelynek adják ki magukat, hogy félrevezessék Önt.</translation>
<translation id="8983003182662520383">A Google Pay szolgáltatásban használt fizetési módok és címek</translation>
<translation id="8987927404178983737">hónap</translation>
-<translation id="8988408250700415532">Hiba történt. A rendelést a webhelyen fejezheti be.</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>
@@ -1262,6 +1425,7 @@ További részletek:
<translation id="9011424611726486705">Webhelybeállítások megnyitása</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Érvénytelen)</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>
@@ -1273,11 +1437,11 @@ További részletek:
<translation id="9065745800631924235"><ph name="TEXT" /> keresése az előzményekben</translation>
<translation id="9069693763241529744">Bővítmény tiltja</translation>
<translation id="9076283476770535406">Lehet, hogy felnőtt tartalommal rendelkezik</translation>
+<translation id="9076630408993835509">Ezt a böngészőt nem kezeli cég vagy más szervezet. Lehetséges, hogy az eszközön végzett tevékenységeket a Chrome-on kívülről felügyelik. <ph name="BEGIN_LINK" />További információ.<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Több információra van szükség</translation>
<translation id="9080712759204168376">Megrendelés összegzése</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>
<translation id="9106062320799175032">Számlázási cím hozzáadása</translation>
-<translation id="9110718169272311511">A Google Segéd a Chrome-ban szolgáltatás a képernyő alsó részén található</translation>
<translation id="9114524666733003316">Kártya ellenőrzése…</translation>
<translation id="9128870381267983090">Csatlakozás hálózathoz</translation>
<translation id="9137013805542155359">Eredeti megjelenítése</translation>
@@ -1286,6 +1450,7 @@ További részletek:
<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="9158625974267017556">C6 (boríték)</translation>
<translation id="9168814207360376865">Engedélyezés a webhelyek számára, hogy ellenőrizzék, van-e elmentett fizetési módja</translation>
<translation id="9169664750068251925">Mindig tiltsa ezen az oldalon</translation>
<translation id="9170848237812810038">&amp;Visszavonás</translation>
@@ -1300,10 +1465,12 @@ További részletek:
<translation id="9219103736887031265">Képek</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ŰRLAP TÖRLÉSE</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Elveszítheti a hozzáférést Google-fiókjához. A Chromium azt javasolja, hogy azonnal módosítsa jelszavát. Be kell majd jelentkeznie.</translation>
<translation id="939736085109172342">Új mappa</translation>
<translation id="945855313015696284">Ellenőrizze az alábbi adatokat, és törölje az érvénytelen kártyákat</translation>
<translation id="951104842009476243">Elfogadott bank- és feltöltőkártyák</translation>
+<translation id="958202389743790697">Letiltva a(z) <ph name="ORIGIN" /> biztonsági házirendje miatt.</translation>
<translation id="962484866189421427">Ez a tartalom megtévesztő alkalmazásokat telepíthet, amelyek más alkalmazásnak tettethetik magukat, illetve az Ön nyomon követésére alkalmas adatokat gyűjthetnek. <ph name="BEGIN_LINK" />Megjelenítés mindenképpen<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Hivatalos verzió</translation>
<translation id="973773823069644502">Kézbesítési cím hozzáadása</translation>
@@ -1312,6 +1479,7 @@ További részletek:
<translation id="984275831282074731">Fizetési módok</translation>
<translation id="985199708454569384">&lt;p&gt;Ez a hiba akkor fordul elő, ha a számítógép vagy mobileszköz dátuma és ideje pontatlan.&lt;/p&gt;
&lt;p&gt;A hiba kijavításához nyissa meg eszköze óráját. Ellenőrizze, hogy helyes-e a dátum és az idő.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Fejlesztői változat</translation>
<translation id="989988560359834682">Cím szerkesztése</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_id.xtb b/chromium/components/strings/components_strings_id.xtb
index 1e635e2cba8..f2148f55ace 100644
--- a/chromium/components/strings/components_strings_id.xtb
+++ b/chromium/components/strings/components_strings_id.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="id">
-<translation id="1005145902654145231">Gagal mengganti nama sesi.</translation>
<translation id="1008557486741366299">Jangan Sekarang</translation>
<translation id="1010200102790553230">Muat halaman nanti</translation>
<translation id="1015730422737071372">Berikan detail tambahan</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nama tidak diketahui</translation>
<translation id="1050038467049342496">Tutup aplikasi lain</translation>
<translation id="1055184225775184556">&amp;Urungkan Penambahan</translation>
+<translation id="1056898198331236512">Peringatan</translation>
<translation id="1058479211578257048">Menyimpan kartu...</translation>
<translation id="10614374240317010">Jangan pernah disimpan</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Bookmark Desktop</translation>
<translation id="1074497978438210769">Tidak aman</translation>
<translation id="1080116354587839789">Paskan dengan lebar</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Tambahkan Nama di Kartu</translation>
<translation id="1089439967362294234">Ubah Sandi</translation>
<translation id="109743633954054152">Kelola sandi di setelan Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Peringatan mungkin akan sering ditampilkan selama situs mengupdate keamanannya. Situasi ini akan segera diperbaiki.</translation>
<translation id="1126551341858583091">Ukuran di penyimpanan lokal adalah <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache kebijakan Oke</translation>
+<translation id="1131264053432022307">Gambar yang Anda Salin</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Ganti nama</translation>
<translation id="1175364870820465910">&amp;Cetak...</translation>
<translation id="1181037720776840403">Hapus</translation>
<translation id="1197088940767939838">Oranye</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Nama perangkat Anda</translation>
<translation id="124116460088058876">Bahasa lainnya</translation>
<translation id="1250759482327835220">Untuk membayar lebih cepat di pembelian berikutnya, simpan kartu, nama, dan alamat penagihan ke Akun Google Anda.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (disinkronkan)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variasi baris perintah</translation>
<translation id="129553762522093515">Baru saja ditutup</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Coba hapus cookie Anda<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Sesi yang dipilih tidak ada.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Telusuri gambar papan klip</translation>
<translation id="1323433172918577554">Tampilkan Lebih Banyak</translation>
<translation id="132390688737681464">Simpan dan Isi Alamat</translation>
<translation id="1333989956347591814">Aktivitas Anda <ph name="BEGIN_EMPHASIS" />mungkin tetap dapat dilihat<ph name="END_EMPHASIS" /> oleh:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Alamat pengambilan</translation>
<translation id="1348198688976932919">Situs yang akan dibuka berisi aplikasi berbahaya</translation>
<translation id="1348779747280417563">Konfirmasi nama</translation>
+<translation id="1357195169723583938">Siapa saja yang baru saja menggunakan perangkat dan kapan itu dilakukan</translation>
+<translation id="1364822246244961190">Kebijakan ini diblokir dan nilainya akan diabaikan.</translation>
<translation id="1374468813861204354">saran</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Tentang Versi</translation>
<translation id="1376836354785490390">Tampilkan Lebih Sedikit</translation>
<translation id="1377321085342047638">Nomor Kartu</translation>
<translation id="138218114945450791">Biru Terang</translation>
+<translation id="1382194467192730611">Perangkat USB diizinkan oleh administrator Anda</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> tidak mengirimkan data apa pun.</translation>
+<translation id="140316286225361634">Situs <ph name="ORIGIN" /> telah meminta agar kebijakan keamanan
+ diterapkan ke semua permintaannya, dan kebijakan ini sekarang menganggap situs tersebut
+ tidak aman.</translation>
<translation id="1405567553485452995">Hijau Muda</translation>
<translation id="1407135791313364759">Buka semua</translation>
<translation id="1413809658975081374">Kesalahan privasi</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ya</translation>
<translation id="1430915738399379752">Cetak</translation>
<translation id="1455413310270022028">Penghapus</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Tampilkan lainnya</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Pilih Alamat Pengiriman</translation>
+<translation id="1492194039220927094">Push kebijakan:</translation>
<translation id="1501859676467574491">Tampilkan kartu dari Akun Google Anda</translation>
-<translation id="1506687042165942984">Tampilkan salinan tersimpan (yang diketahui telah habis masa berlakunya) dari halaman ini.</translation>
<translation id="1507202001669085618">&lt;p&gt;Anda akan melihat error ini jika menggunakan portal Wi-Fi yang mengharuskan Anda login sebelum terhubung online.&lt;/p&gt;
&lt;p&gt;Untuk memperbaiki error, klik &lt;strong&gt;Sambungkan&lt;/strong&gt; di halaman yang ingin Anda buka.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Perlu nomor telepon</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Tanggal Dibuat</translation>
<translation id="1521655867290435174">Google Spreadsheet</translation>
<translation id="1527263332363067270">Menunggu sambungan internet...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Halaman ini menyatakan</translation>
<translation id="153384715582417236">Itu saja untuk sekarang</translation>
<translation id="154408704832528245">Pilih Alamat Pengiriman</translation>
<translation id="1549470594296187301">JavaScript harus diaktifkan untuk menggunakan fitur ini.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Masukkan tanggal habis masa berlaku</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Terjadi masalah sewaktu menampilkan halaman web ini.</translation>
<translation id="1592005682883173041">Akses Data Lokal</translation>
<translation id="1594030484168838125">Pilih</translation>
<translation id="161042844686301425">Sian</translation>
-<translation id="1618822247301510817">Gambar yang Anda salin</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Cegah dialog lain dari halaman ini.</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Akhiri sesi</translation>
<translation id="1639239467298939599">Memuat</translation>
<translation id="1640180200866533862">Kebijakan pengguna</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Sertifikat server berisi kunci kriptografis yang lemah.</translation>
<translation id="1697532407822776718">Anda sudah siap!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokumen terlalu besar untuk dianotasi</translation>
<translation id="1721312023322545264">Anda memerlukan izin dari <ph name="NAME" /> untuk mengunjungi situs ini</translation>
<translation id="1721424275792716183">* Kolom wajib diisi</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Coba hubungi admin sistem.</translation>
<translation id="1740951997222943430">Masukkan bulan habis masa berlaku yang valid</translation>
<translation id="1743520634839655729">Untuk membayar lebih cepat di pembelian berikutnya, simpan kartu, nama, dan alamat penagihan ke Akun Google Anda dan ke perangkat ini.</translation>
+<translation id="1745880797583122200">Browser Anda dikelola</translation>
<translation id="17513872634828108">Buka tab</translation>
<translation id="1753706481035618306">Nomor halaman</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Perbarui frasa sandi sinkronisasi Anda.</translation>
<translation id="1787142507584202372">Tab yang terbuka muncul di sini</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nama Pemegang Kartu</translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak valid</translation>
+<translation id="1822540298136254167">Situs yang Anda kunjungi dan waktu yang dihabiskan untuk mengunjunginya</translation>
<translation id="1826516787628120939">Memeriksa</translation>
<translation id="1834321415901700177">Situs ini berisi program yang berbahaya</translation>
<translation id="1839551713262164453">Validasi nilai kebijakan gagal karena terjadi error</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Hapus data histori browsing Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{dan 1 lainnya}other{dan # lainnya}}</translation>
<translation id="2003709556000175978">Setel ulang sandi Anda sekarang</translation>
+<translation id="20053308747750172">Server yang akan Anda akses, <ph name="ORIGIN" />, telah meminta
+ agar kebijakan keamanan diterapkan ke semua permintaannya. Namun server tersebut sekarang
+ menerapkan kebijakan yang tidak valid, yang mencegah browser agar tidak
+ memenuhi permintaan Anda untuk <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy disetel ke konfigurasi otomatis.</translation>
<translation id="2030481566774242610">Mungkin maksud Anda <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Memeriksa proxy dan firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departemen</translation>
<translation id="2102134110707549001">Sarankan Sandi yang Kuat…</translation>
<translation id="2108755909498034140">Mulai ulang komputer</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kartu</translation>
<translation id="2114841414352855701">Diabaikan karena diganti dengan <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Bookmark Seluler</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Kebijakan</translation>
<translation id="2183608646556468874">Nomor Telepon</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 alamat}other{# alamat}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Nomor telepon</translation>
<translation id="2283340219607151381">Simpan dan isi alamat</translation>
<translation id="2292556288342944218">Akses Internet Anda diblokir</translation>
+<translation id="2294558542833290837">Link yang tadinya Anda buka tidak biasa</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Sediakan ruang kurang dari 1 MB. Beberapa situs mungkin dimuat lebih lambat dibuka lagi.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> memerlukan nama pengguna dan sandi.</translation>
<translation id="2317583587496011522">Kartu debit diterima.</translation>
<translation id="2330137317877982892">Masa berlaku <ph name="CREDIT_CARD" /> habis pada <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Setelan dikontrol oleh administrator Anda</translation>
+<translation id="2346319942568447007">Gambar yang Anda salin</translation>
<translation id="2349790679044093737">Sesi VR aktif</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Laporan kerusakan yang diambil pada pukul <ph name="CRASH_TIME" /> tidak diupload</translation>
<translation id="2367567093518048410">Tingkat</translation>
<translation id="2378238891085281592">Anda telah masuk mode rahasia</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Server yang akan Anda akses, <ph name="ORIGIN" />, telah meminta
+ agar kebijakan keamanan diterapkan ke semua permintaannya. Namun server tersebut sekarang
+ gagal menerapkan kebijakan, yang mencegah browser agar tidak memenuhi
+ permintaan Anda untuk <ph name="SITE" />.</translation>
<translation id="244665789865330679">Perangkat dan akun Anda dikelola oleh <ph name="ENROLLMENT_DOMAIN" />. Ini berarti bahwa administrator dapat mengonfigurasi perangkat dan akun Anda dari jarak jauh.</translation>
<translation id="2463193859425327265">Ubah Halaman Beranda</translation>
<translation id="2463739503403862330">Isi</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Pilih Metode Pengiriman</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Jalankan Diagnostik Jaringan<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Terjemahkan halaman ini</translation>
<translation id="2479410451996844060">URL penelusuran tidak valid.</translation>
<translation id="2482878487686419369">Notifikasi</translation>
<translation id="248348093745724435">Kebijakan mesin</translation>
+<translation id="2485387744899240041">Nama pengguna untuk perangkat dan browser Anda</translation>
<translation id="2491120439723279231">Sertifikat server mengandung kesalahan.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Pindai kartu baru</translation>
<translation id="2501278716633472235">Kembali</translation>
<translation id="2503184589641749290">Kartu prabayar dan debit yang diterima</translation>
<translation id="2515629240566999685">Periksa sinyal di area Anda</translation>
-<translation id="2516852381693169964">Telusuri Gambar di <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Hanya disimpan di perangkat ini</translation>
<translation id="2524461107774643265">Tambahkan Informasi Lainnya</translation>
<translation id="2536110899380797252">Tambahkan Alamat</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">ID API Direktori:</translation>
<translation id="2597378329261239068">Dokumen ini dilindungi sandi. Masukkan sandi.</translation>
<translation id="2609632851001447353">Variasi</translation>
+<translation id="2618023639789766142">C10 (Amplop)</translation>
<translation id="2625385379895617796">Setelan jam terlalu cepat</translation>
<translation id="2634124572758952069">Alamat IP server <ph name="HOST_NAME" /> tidak dapat ditemukan.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Tutup tab atau aplikasi lain</translation>
<translation id="267371737713284912">tekan <ph name="MODIFIER_KEY_DESCRIPTION" /> untuk mengurungkan</translation>
<translation id="2674170444375937751">Yakin ingin menghapus halaman ini dari histori?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Keluar</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Kartu yang Diterima</translation>
<translation id="2702801445560668637">Daftar Bacaan</translation>
<translation id="2704283930420550640">Nilai tidak sesuai format.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Hapus item yang dipilih</translation>
<translation id="277133753123645258">Metode pengiriman</translation>
<translation id="277499241957683684">Catatan perangkat hilang</translation>
-<translation id="2781030394888168909">Ekspor MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Sambungan disetel ulang.</translation>
<translation id="2788784517760473862">Kartu kredit yang diterima</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Buka Jendela Samaran</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Anda memerlukan izin untuk membuka situs ini</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Simpan kartu?</translation>
<translation id="2903493209154104877">Alamat</translation>
<translation id="290376772003165898">Halaman tidak dalam bahasa <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Metode Pengiriman</translation>
<translation id="2928905813689894207">Alamat Penagihan</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> lainnya}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> lainnya}}</translation>
+<translation id="2934466151127459956">Government-Letter</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 halaman setelan.</translation>
<translation id="2955913368246107853">Tutup bilah cari</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Jenis kebijakan salah</translation>
<translation id="3037605927509011580">Yah!</translation>
<translation id="3041612393474885105">Informasi Sertifikat</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Tambahkan Alamat Pengambilan</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3109728660330352905">Anda tidak memiliki otorisasi untuk melihat halaman ini.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> di <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Batalkan Pembayaran</translation>
<translation id="3207960819495026254">Diberi bookmark</translation>
-<translation id="3209375525920864198">Harap masukkan nama sesi yang valid.</translation>
+<translation id="321912867715453276">Peringatan: Ada beberapa sumber yang nilainya sama untuk kebijakan ini.</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 halaman ini.</translation>
<translation id="3227137524299004712">Mikrofon</translation>
<translation id="3228969707346345236">Terjemahan gagal karena halaman sudah dalam bahasa <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Informasi versi tentang perangkat dan browser Anda</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 halaman ini</translation>
<translation id="3270847123878663523">&amp;Urungkan Pengaturan Ulang</translation>
+<translation id="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Tambahkan nama di kartu</translation>
<translation id="3287510313208355388">Download saat online</translation>
<translation id="3293642807462928945">Pelajari lebih lanjut tentang kebijakan <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Hasil penelusuran tidak ditemukan</translation>
-<translation id="3305707030755673451">Data Anda dienkripsi dengan frasa sandi sinkronisasi pada tanggal <ph name="TIME" />. Masukkan frasa sandi untuk memulai sinkronisasi.</translation>
<translation id="3320021301628644560">Tambahkan alamat penagihan</translation>
<translation id="3324983252691184275">Merah Lembayung</translation>
<translation id="3338095232262050444">Aman</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Ulangi Pengeditan</translation>
<translation id="342781501876943858">Chromium menyarankan untuk menyetel ulang sandi jika Anda juga menggunakannya di situs lain.</translation>
<translation id="3431636764301398940">Simpan kartu ini ke perangkat ini</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Pemilik perangkat ini menonaktifkan game dinosaurus.</translation>
<translation id="3447884698081792621">Tampilkan sertifikat (diterbitkan oleh <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Interval pengambilan:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Stabilo</translation>
<translation id="3462200631372590220">Sembunyikan lanjutan</translation>
<translation id="3467763166455606212">Diperlukan nama pemegang kartu</translation>
@@ -429,20 +480,23 @@
<translation id="358285529439630156">Kartu kredit dan prabayar diterima.</translation>
<translation id="3582930987043644930">Tambahkan nama</translation>
<translation id="3583757800736429874">&amp;Ulangi Pemindahan</translation>
+<translation id="35866233670761917">Konten situs yang Anda buka tidak dilihat oleh administrator</translation>
<translation id="3586931643579894722">Sembunyikan detail</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Ukuran 2</translation>
<translation id="3615877443314183785">Masukkan tanggal masa berlaku yang valid</translation>
<translation id="36224234498066874">Hapus Data Penjelajahan...</translation>
<translation id="362276910939193118">Tampilkan Histori Lengkap</translation>
-<translation id="3623476034248543066">Tampilkan nilai</translation>
<translation id="3630155396527302611">Jika sudah tercantum sebagai program yang diizinkan untuk mengakses jaringan,
coba hapus dari daftar dan tambahkan lagi.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validasi berhasil</translation>
<translation id="3655670868607891010">Jika Anda sering melihatnya, coba <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisi</translation>
<translation id="366077651725703012">Perbarui Kartu Kredit</translation>
<translation id="3676592649209844519">ID Perangkat:</translation>
+<translation id="3677008721441257057">Maksud Anda &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Permintaan tidak dapat ditandatangani</translation>
<translation id="3678529606614285348">Buka halaman dalam Jendela samaran baru (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Laporan kerusakan direkam pada <ph name="CRASH_TIME" />, diupload pada <ph name="UPLOAD_TIME" /></translation>
@@ -450,13 +504,14 @@
<translation id="3704162925118123524">Jaringan yang digunakan mungkin mewajibkan Anda mengunjungi halaman masuk jaringan.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Memuat...</translation>
+<translation id="3709599264800900598">Teks yang Anda Salin</translation>
<translation id="3712624925041724820">Lisensi habis</translation>
<translation id="3714780639079136834">Aktifkan data seluler atau Wi-Fi</translation>
<translation id="3715597595485130451">Menyambung ke jaringan Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Periksa proxy, firewall, dan konfigurasi DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Aplikasi yang dapat menyebabkan error ini mencakup antivirus, firewall, dan software proxy atau pemfilteran web.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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 halaman ini mungkin akan bekerja nanti.</translation>
<translation id="3745099705178523657">Setelah mengonfirmasi, detail kartu dari Akun Google Anda akan dibagikan dengan situs ini.</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>
@@ -469,10 +524,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Masa berlaku <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Ukuran 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Konten yang berbahaya diblokir.</translation>
<translation id="3810973564298564668">Kelola</translation>
<translation id="382518646247711829">Jika Anda menggunakan server proxy...</translation>
<translation id="3828924085048779000">Frasa sandi kosong tidak dibolehkan.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> telah menginstal ekstensi untuk fungsi tambahan. Ekstensi memiliki akses ke sebagian data Anda.</translation>
<translation id="385051799172605136">Mundur</translation>
<translation id="3858027520442213535">Perbarui tanggal dan waktu</translation>
<translation id="3884278016824448484">Pengenal perangkat bertentangan</translation>
@@ -480,6 +537,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Selalu tanyakan pada situs ini</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>
@@ -490,11 +548,13 @@
<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="3984550557525787191">Nama sesi ini sudah ada.</translation>
<translation id="3987940399970879459">Kurang dari 1 MB</translation>
+<translation id="4008849406247176967">Peringatan: Ada beberapa sumber dengan nilai yang bertentangan untuk kebijakan ini!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 halaman web di sekitar}other{# halaman web di sekitar}}</translation>
<translation id="4030383055268325496">&amp;Urungkan penambahan</translation>
+<translation id="4032320456957708163">Browser Anda dikelola oleh <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Kunci "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Tambahkan Alamat yang Valid</translation>
<translation id="4072486802667267160">Terjadi error saat memproses pesanan Anda. Harap coba lagi.</translation>
<translation id="4075732493274867456">Klien dan server tidak mendukung versi protokol SSL umum atau cipher suite.</translation>
@@ -514,10 +574,12 @@
<translation id="4159784952369912983">Ungu</translation>
<translation id="4165986682804962316">Setelan situs</translation>
<translation id="4171400957073367226">Tanda tangan verifikasi tidak valid</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> item lainnya}other{<ph name="ITEM_COUNT" /> item lainnya}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Langkah 1: Login ke portal&lt;/h4&gt;
@@ -549,58 +611,79 @@
<translation id="4277028893293644418">Setel ulang sandi</translation>
<translation id="4280429058323657511">, kedaluwarsa <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Kartu ini telah disimpan di Akun Google Anda}other{Kartu-kartu ini telah disimpan di Akun Google Anda}}</translation>
+<translation id="42981349822642051">Luaskan</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Alihkan</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokir (default)</translation>
+<translation id="4318566738941496689">Nama dan alamat jaringan perangkat Anda</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="4340982228985273705">Komputer ini tidak terdeteksi sebagai dikelola perusahaan sehingga kebijakan hanya dapat secara otomatis menginstal ekstensi yang dihosting di Chrome Webstore. URL update Chrome Webstore-nya adalah "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Kartu Kredit yang Diterima</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Kelola metode pembayaran...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Ponsel</translation>
<translation id="4406896451731180161">hasil penelusuran</translation>
-<translation id="4406972042435603828">Administrator telah menginstal ekstensi dengan kemampuan canggih.</translation>
<translation id="4408413947728134509">Cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Alamat Pengambilan</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="443121186588148776">Port serial</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> tidak menerima sertifikat masuk Anda, atau sertifikat masuk mungkin tidak diberikan.</translation>
<translation id="4434045419905280838">Pop-up dan pengalihan</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Penggunaan proxy dinonaktifkan tetapi konfigurasi proxy yang eksplisit ditentukan.</translation>
<translation id="445100540951337728">Kartu kredit yang diterima</translation>
+<translation id="4466881336512663640">Perubahan pada formulir akan hilang. Yakin ingin melanjutkan?</translation>
<translation id="4482953324121162758">Situs ini tidak akan diterjemahkan.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL tidak valid. Harus berupa URL dengan skema standar, misalnya http://example.com atau https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Detail</translation>
<translation id="4524805452350978254">Kelola kartu</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Coba nonaktifkan ekstensi.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Pengiriman</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Hapus kartu</translation>
<translation id="4587425331216688090">Hapus alamat dari Chrome?</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="4597348597567598915">Ukuran 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Buka Download sekarang</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="467809019005607715">Google Slide</translation>
<translation id="4690462567478992370">Berhenti menggunakan sertifikat yang tidak valid</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Sambungan Anda terganggu</translation>
<translation id="471880041731876836">Anda tidak memiliki izin untuk membuka situs ini</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Jalankan Diagnostik Jaringan Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Muat ulang kebijakan</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Buka Ulang Chromium</translation>
<translation id="473775607612524610">Perbarui</translation>
<translation id="4738601419177586157">Saran penelusuran <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Kelola sandi...</translation>
<translation id="4744603770635761495">Jalur Yang Dapat Dijalankan</translation>
+<translation id="4746351372139058112">Pesan</translation>
<translation id="4750917950439032686">Informasi Anda (misalnya, sandi atau nomor kartu kredit) bersifat pribadi saat dikirimkan ke situs ini.</translation>
<translation id="4756388243121344051">&amp;Riwayat</translation>
<translation id="4758311279753947758">Tambahkan info kontak</translation>
@@ -608,9 +691,9 @@
<translation id="4764776831041365478">Halaman web di <ph name="URL" /> mungkin sedang tidak aktif untuk sementara atau dipindahkan secara permanen ke alamat web baru.</translation>
<translation id="4771973620359291008">Terjadi kesalahan yang tidak diketahui.</translation>
<translation id="4785689107224900852">Alihkan ke tab ini</translation>
-<translation id="4792143361752574037">Terjadi masalah saat mengakses file sesi. Fitur menyimpan ke disk saat ini dinonaktifkan. Harap muat ulang halaman untuk mencoba lagi.</translation>
<translation id="4798078619018708837">Masukkan tanggal habis masa berlaku dan CVC untuk <ph name="CREDIT_CARD" /> guna memperbarui detail kartu. Setelah mengonfirmasi, detail kartu dari Akun Google Anda akan dibagikan dengan situs ini.</translation>
<translation id="4800132727771399293">Periksa tanggal masa berlaku habis dan CVC, lalu coba lagi</translation>
+<translation id="480334179571489655">Error Kebijakan Asal</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 halaman ini mungkin akan bekerja nanti.</translation>
<translation id="4813512666221746211">Kesalahan jaringan</translation>
@@ -625,7 +708,6 @@
<translation id="4881695831933465202">Buka</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 halaman web lainnya}other{dan # halaman web lainnya}}</translation>
-<translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation>
<translation id="4923417429809017348">Halaman 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>
@@ -634,15 +716,15 @@
<translation id="4943872375798546930">Tidak ada hasil</translation>
<translation id="4950898438188848926">Tombol beralih tab, tekan Enter untuk beralih ke tab yang terbuka, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Tindakan</translation>
-<translation id="495832697253704892">Pelaporan ekstensi</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Luaskan daftar</translation>
<translation id="4974590756084640048">Aktifkan kembali peringatan</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Lihat semua</translation>
<translation id="4989809363548539747">Plugin ini tidak didukung</translation>
-<translation id="4996230189582812866">Pelaporan</translation>
<translation id="5002932099480077015">Jika diaktifkan, Chrome akan menyimpan salinan kartu Anda di perangkat ini untuk pengisian formulir yang lebih cepat.</translation>
-<translation id="5014174725590676422">Layar penggunaan pertama Asisten Google di Chrome ditampilkan</translation>
<translation id="5015510746216210676">Nama Mesin:</translation>
+<translation id="5017554619425969104">Teks yang Anda salin</translation>
<translation id="5018422839182700155">Tidak dapat membuka halaman ini</translation>
<translation id="5019198164206649151">Penyimpanan cadangan dalam kondisi buruk</translation>
<translation id="5023310440958281426">Periksa kebijakan administrator Anda</translation>
@@ -652,35 +734,51 @@
<translation id="5034369478845443529">Konteks Lokal <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Izinkan</translation>
<translation id="5040262127954254034">Privasi</translation>
+<translation id="5043480802608081735">Link yang Anda Salin</translation>
<translation id="5045550434625856497">Sandi salah</translation>
<translation id="5056549851600133418">Artikel untuk Anda</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Periksa alamat proxy<ph name="END_LINK" /></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="5097099694988056070">Statistik perangkat seperti penggunaan CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Perangkat dikelola oleh <ph name="ENROLLMENT_DOMAIN" /> dan akun dikelola oleh <ph name="ACCOUNT_DOMAIN" />. Ini berarti bahwa administrator dapat mengonfigurasi perangkat dan akun Anda dari jarak jauh.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bit)</translation>
-<translation id="5128122789703661928">Sesi dengan nama ini tidak valid untuk dihapus.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Kelola alamat...</translation>
+<translation id="5138227688689900538">Tampilkan lebih sedikit</translation>
<translation id="5141240743006678641">Enkripsikan sandi yang disinkronkan dengan kredensial Google Anda</translation>
<translation id="5145883236150621069">Ada kode kesalahan dalam tanggapan kebijakan</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Buka halaman dalam Jendela samaran baru (⇧⌘N)</translation>
<translation id="516920405563544094">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah mengonfirmasi, detail kartu dari Akun Google Anda akan dibagikan dengan situs ini.</translation>
<translation id="5169827969064885044">Anda dapat kehilangan akses ke akun organisasi atau mengalami pencurian identitas. Chrome menyarankan Anda untuk mengubah sandi sekarang.</translation>
<translation id="5171045022955879922">Telusuri atau ketik URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Mesin</translation>
<translation id="5179510805599951267">Bukan <ph name="ORIGINAL_LANGUAGE" />? Laporkan kesalahan deteksi ini</translation>
<translation id="5190835502935405962">Bilah Bookmark</translation>
-<translation id="5200263511887412697">melaporkan daftar perangkat yang baru-baru ini digunakan oleh pengguna untuk login</translation>
+<translation id="519422657042045905">Anotasi tidak tersedia</translation>
<translation id="5201306358585911203">Halaman tersemat di halaman ini menyatakan</translation>
<translation id="5205222826937269299">Nama wajib diisi</translation>
<translation id="5215116848420601511">Metode pembayaran dan alamat yang menggunakan Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Email wajib diisi</translation>
<translation id="5230733896359313003">Alamat Pengiriman</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Sambungkan ke jaringan"</translation>
<translation id="5251803541071282808">Awan</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Alamat jaringan</translation>
<translation id="5285570108065881030">Tampilkan semua sandi tersimpan</translation>
<translation id="5287240709317226393">Tampilkan cookie</translation>
<translation id="5288108484102287882">Validasi nilai kebijakan telah memunculkan peringatan</translation>
@@ -692,7 +790,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> dari <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Pilih Info Kontak</translation>
<translation id="5327248766486351172">Nama</translation>
+<translation id="5329858041417644019">Browser Anda tidak dikelola</translation>
<translation id="5332219387342487447">Metode Pengiriman</translation>
+<translation id="5334013548165032829">Log sistem mendetail</translation>
<translation id="5344579389779391559">Halaman ini mungkin mencoba menagih Anda</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>
@@ -700,6 +800,7 @@
<translation id="5377026284221673050">"Jam Anda terlalu lambat" atau "Jam Anda terlalu cepat" atau "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Untuk menggunakan kartu di semua perangkat, harap login dan aktifkan sinkronisasi.</translation>
<translation id="5386426401304769735">Rantai sertifikat untuk situs ini berisi sertifikat yang ditandatangani menggunakan SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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 penjelajahan...</translation>
<translation id="5430298929874300616">Buang bookmark</translation>
@@ -710,6 +811,7 @@
<translation id="5457113250005438886">Tidak valid</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> lainnya}other{<ph name="CONTACT_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> lainnya}}</translation>
<translation id="5470861586879999274">&amp;Ulangi pengeditan</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">Konten ini mungkin mencoba menginstal software berbahaya yang mencuri atau menghapus informasi Anda di perangkat. <ph name="BEGIN_LINK" />Tetap tampilkan<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Tambahkan alamat yang valid</translation>
<translation id="5490432419156082418">Alamat dan Lain-Lain</translation>
@@ -717,10 +819,12 @@
<ph name="LINE_BREAK" />
Coba hubungi administrator sistem Anda.</translation>
<translation id="549333378215107354">Ukuran 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Mengelola bookmark</translation>
<translation id="5510766032865166053">File mungkin telah dipindahkan atau dihapus.</translation>
<translation id="5523118979700054094">Nama kebijakan</translation>
<translation id="552553974213252141">Apakah teks diekstrak dengan benar?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Tidak dapat menemukan artikel yang diminta.</translation>
<translation id="5541546772353173584">Tambahkan Email</translation>
<translation id="5545756402275714221">Artikel untuk Anda</translation>
@@ -735,15 +839,21 @@
<translation id="5595485650161345191">Edit alamat</translation>
<translation id="5598944008576757369">Pilih Metode Pembayaran</translation>
<translation id="560412284261940334">Pengelolaan tidak didukung</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> terlalu sering mengalihkan Anda.</translation>
<translation id="5629630648637658800">Gagal memuat setelan kebijakan</translation>
<translation id="5631439013527180824">Token pengelolaan perangkat tidak valid</translation>
+<translation id="5632627355679805402">Data Anda dienkripsi dengan <ph name="BEGIN_LINK" />sandi Google<ph name="END_LINK" /> mulai <ph name="TIME" />. Masukkan frasa sandi untuk memulai sinkronisasi.</translation>
<translation id="5633066919399395251">Penyerang yang saat ini berada di <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> mungkin berusaha menginstal program berbahaya di komputer Anda untuk 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="563324245173044180">Konten penipuan diblokir.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">Administrator perangkat ini telah menginstal ekstensi untuk fungsi tambahan. Ekstensi memiliki akses ke sebagian data Anda.</translation>
<translation id="5675650730144413517">Halaman ini tidak berfungsi</translation>
+<translation id="5684874026226664614">Ups. Halaman ini tidak dapat diterjemahkan.</translation>
<translation id="5685654322157854305">Tambahkan Alamat Pengiriman</translation>
<translation id="5689199277474810259">Ekspor ke JSON</translation>
<translation id="5689516760719285838">Lokasi</translation>
@@ -752,38 +862,39 @@
<translation id="5710435578057952990">Identitas situs Web ini belum diverifikasi.</translation>
<translation id="5719499550583120431">Kartu prabayar diterima.</translation>
<translation id="5720705177508910913">Pengguna saat ini</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome menyarankan untuk menyetel ulang sandi jika Anda juga menggunakannya di situs lain.</translation>
<translation id="5732392974455271431">Orang tua dapat membuka blokirnya untukmu</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Simpan kartu di Akun Google Anda}other{Simpan kartu di Akun Google Anda}}</translation>
<translation id="5763042198335101085">Masukkan alamat email yang valid</translation>
<translation id="5765072501007116331">Untuk melihat persyaratan dan metode pengiriman, pilih alamat</translation>
-<translation id="5770114862687765385">File tersebut sepertinya rusak. Harap klik tombol 'Setel Ulang' untuk menyetel ulang sesi.</translation>
<translation id="5778550464785688721">Kontrol penuh perangkat MIDI</translation>
<translation id="578305955206182703">Oranye kekuningan</translation>
<translation id="57838592816432529">Bisukan</translation>
<translation id="5784606427469807560">Terjadi masalah saat mengonfirmasi kartu. Periksa sambungan internet Anda dan coba lagi.</translation>
<translation id="5785756445106461925">Selain itu, halaman 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>
+<translation id="5798290721819630480">Hapus perubahan?</translation>
<translation id="5798683403665926540">Ubah halaman beranda di setelan Chrome</translation>
<translation id="5803412860119678065">Ingin mengisi <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Izin</translation>
<translation id="5810442152076338065">Sambungan Anda ke <ph name="DOMAIN" /> dienkripsi menggunakan cipher suite yang sudah usang.</translation>
<translation id="5813119285467412249">&amp;Ulangi Penambahan</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="5860033963881614850">Nonaktif</translation>
<translation id="5863847714970149516">Halaman berikutnya mungkin mencoba menagih Anda.</translation>
<translation id="5866257070973731571">Tambahkan Nomor Telepon</translation>
<translation id="5869405914158311789">Situs ini tidak dapat dijangkau</translation>
<translation id="5869522115854928033">Sandi tersimpan</translation>
<translation id="5887400589839399685">Kartu disimpan</translation>
-<translation id="5893718151540690985">melaporkan daftar antarmuka jaringan dengan jenis dan alamat hardware</translation>
<translation id="5893752035575986141">Kartu kredit diterima.</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="5916664084637901428">Aktif</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Simpan kartu ke Akun Google?</translation>
<translation id="5922853866070715753">Hampir selesai</translation>
<translation id="5932224571077948991">Situs menampilkan iklan yang mengganggu atau menyesatkan</translation>
-<translation id="5939518447894949180">Setel ulang</translation>
<translation id="5946937721014915347">Membuka <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Tidak dapat mendaftar dengan akun konsumen (tersedia paket lisensi).</translation>
<translation id="5967592137238574583">Edit Info Kontak</translation>
@@ -791,6 +902,7 @@
<translation id="5975083100439434680">Perkecil</translation>
<translation id="5977489021191000276">Perangkat Anda tidak dikelola oleh administrator.</translation>
<translation id="5977976211062815271">Di perangkat ini</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Tidak dapat membuka aplikasi pembayaran</translation>
<translation id="5989320800837274978">Baik proxy server tetap ataupun URL skrip .pac tidak ditentukan.</translation>
<translation id="5990559369517809815">Permintaan ke server telah dicekal oleh ekstensi.</translation>
@@ -801,8 +913,8 @@
<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="6033927989869462158">melaporkan statistik hardware seperti penggunaan CPU/RAM</translation>
<translation id="6034000775414344507">Abu-abu Muda</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Jika masalah berlanjut, hubungi pemilik situs.</translation>
<translation id="6040143037577758943">Tutup</translation>
<translation id="6044573915096792553">Ukuran 12</translation>
@@ -811,10 +923,10 @@
<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="6058977677006700226">Gunakan kartu Anda di semua perangkat?</translation>
<translation id="6059925163896151826">Perangkat USB</translation>
-<translation id="6071091556643036997">Jenis kebijakan tidak valid.</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="6094273045989040137">Anotasi</translation>
<translation id="610911394827799129">Akun Google Anda mungkin memiliki bentuk histori penjelajahan lainnya di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informasi tentang ekstensi dan plugin yang diinstal</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>
@@ -849,15 +961,21 @@
<translation id="6337133576188860026">Sediakan ruang kurang dari <ph name="SIZE" />. Beberapa situs mungkin dimuat lebih lambat saat dibuka lagi.</translation>
<translation id="6337534724793800597">Filter kebijakan menurut nama</translation>
<translation id="6358450015545214790">Apakah maksud ini?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Kemungkinan mengenakan tagihan di awal.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 saran lain}other{# saran lain}}</translation>
<translation id="6387754724289022810">Untuk membayar lebih cepat di pembelian berikutnya, simpan kartu dan alamat penagihan ke akun Google Anda.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Edit bookmark</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Tutup</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Tambahkan informasi lainnya</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Konfirmasikan Pengiriman Ulang Formulir</translation>
@@ -870,11 +988,17 @@
<translation id="6508722015517270189">Buka Ulang Chrome</translation>
<translation id="6529602333819889595">&amp;Ulangi Penghapusan</translation>
<translation id="6534179046333460208">Saran Web Fisik</translation>
+<translation id="6556866813142980365">Urungkan</translation>
<translation id="6563469144985748109">Pengelola Anda belum menyetujuinya</translation>
<translation id="6569060085658103619">Anda melihat halaman ekstensi</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Merah Muda Terang</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link yang Anda salin</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> Anda tidak dikelola</translation>
<translation id="6596325263575161958">Opsi enkripsi</translation>
<translation id="6604181099783169992">Sensor Gerakan atau Cahaya</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Info Kontak</translation>
<translation id="6626291197371920147">Tambahkan kartu yang valid</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Penelusuran</translation>
@@ -883,6 +1007,7 @@
<translation id="6644283850729428850">Kebijakan ini telah usang.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Tidak ada}=1{Dari 1 situs (Anda tidak akan logout dari Akun Google)}other{Dari # situs (Anda tidak akan logout dari Akun Google)}}</translation>
<translation id="6657585470893396449">Sandi</translation>
+<translation id="6670613747977017428">Kembali agar aman.</translation>
<translation id="6671697161687535275">Hapus saran formulir dari Chromium?</translation>
<translation id="6685834062052613830">Keluar dan selesaikan penyiapan</translation>
<translation id="6710213216561001401">Sebelumnya</translation>
@@ -890,12 +1015,15 @@
<translation id="671076103358959139">Token Pendaftaran:</translation>
<translation id="6711464428925977395">Ada yang salah dengan server proxy, atau alamat tidak benar.</translation>
<translation id="6723740634201835758">Di Akun Google Anda</translation>
+<translation id="6738516213925468394">Data Anda dienkripsi dengan <ph name="BEGIN_LINK" />frasa sandi sinkronisasi<ph name="END_LINK" /> pada tanggal <ph name="TIME" />. Masukkan frasa sandi untuk memulai sinkronisasi.</translation>
<translation id="674375294223700098">Kesalahan sertifikat server tidak dikenal.</translation>
<translation id="6744009308914054259">Sambil menunggu koneksi, Anda dapat mengunjungi Hasil Download untuk membaca artikel secara offline.</translation>
<translation id="6753269504797312559">Nilai kebijakan</translation>
<translation id="6757797048963528358">Perangkat Anda sedang dalam mode tidur.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Orang tuamu belum menyetujuinya</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Ekstensi</translation>
<translation id="679355240208270552">Diabaikan karena penelusuran default tidak diaktifkan menurut kebijakan.</translation>
<translation id="681021252041861472">Kolom Wajib Diisi</translation>
<translation id="6810899417690483278">ID Penyesuaian</translation>
@@ -928,10 +1056,12 @@
<translation id="6965978654500191972">Perangkat</translation>
<translation id="6970216967273061347">Distrik</translation>
<translation id="6973656660372572881">Server proxy tetap dan URL skrip .pac telah ditentukan.</translation>
+<translation id="6973932557599545801">Maaf, saya tidak bisa membantu lagi. Silakan lanjutkan sendiri.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Matikan (default)</translation>
<translation id="6984479912851154518">Keluar dari mode rahasia untuk membayar melalui aplikasi eksternal. Lanjutkan?</translation>
<translation id="6989763994942163495">Tampilkan setelan lanjutan...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Selalu terjemahkan bahasa <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Tagihan ini bisa hanya satu kali atau berulang, dan mungkin tidak pasti.</translation>
@@ -947,28 +1077,36 @@
<translation id="7108338896283013870">Sembunyikan</translation>
<translation id="7108819624672055576">Diizinkan oleh ekstensi</translation>
<translation id="7111012039238467737">(Valid)</translation>
+<translation id="7118618213916969306">Telusuri URL papan klip, <ph name="SHORT_URL" /></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="7135130955892390533">Tampilkan status</translation>
<translation id="7138472120740807366">Metode pengiriman</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> lainnya}other{<ph name="PAYMENT_METHOD_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> lainnya}}</translation>
<translation id="7153618581592392745">Lembayung Muda</translation>
-<translation id="7158980942472052083">URL tidak valid. Harus berupa URL dengan skema standar.</translation>
<translation id="717330890047184534">ID GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> lainnya}other{<ph name="SHIPPING_OPTION_PREVIEW" /> dan <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> lainnya}}</translation>
+<translation id="7177397715882417099">Server yang akan Anda akses, <ph name="ORIGIN" />, telah meminta
+ agar kebijakan keamanan diterapkan ke semua permintaannya. Namun bukannya
+ menerapkan kebijakan, server tersebut telah mengalihkan browser ke tempat lain, yang mencegah
+ browser agar tidak memenuhi permintaan Anda untuk <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Simpan dan Isi Metode Pembayaran</translation>
<translation id="7180611975245234373">Perbarui</translation>
<translation id="7182878459783632708">Tidak ada kebijakan yang disetel</translation>
<translation id="7186367841673660872">Halaman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Sediakan ruang sebesar <ph name="SIZE" />. Sebagian situs mungkin dimuat lebih lambat pada kunjungan Anda berikutnya.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administrator dapat melihat:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> tidak mematuhi standar keamanan.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Selengkapnya<ph name="END_LINK" /> tentang masalah ini.</translation>
<translation id="7219179957768738017">Koneksi menggunakan <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Dalam proses</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Situs yang akan dibuka berisi software perusak</translation>
+<translation id="724766306220616965">Peringatan, Bentrok</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="7251437084390964440">Konfigurasi jaringan tidak mematuhi standar ONC. Sebagian konfigurasi mungkin tidak diimpor. Detail tambahan: <ph name="DEBUG_INFO" /></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>
@@ -979,11 +1117,14 @@
<translation id="7300012071106347854">Biru Kobalt</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Laporan kerusakan diambil pada <ph name="CRASH_TIME" /> (upload yang diminta pengguna, belum diupload)</translation>
+<translation id="7313965965371928911">Peringatan <ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Bantuan Koneksi</translation>
<translation id="7334320624316649418">&amp;Ulangi pengaturan ulang</translation>
<translation id="733923710415886693">Sertifikat server tidak diungkapkan melalui Transparansi Sertifikat.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Baris Perintah</translation>
-<translation id="7365061714576910172">Ekspor Linux</translation>
<translation id="7372973238305370288">hasil penelusuran</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Tidak</translation>
@@ -991,6 +1132,7 @@
<translation id="7381288752349550461">Penggantian sesi terkelola</translation>
<translation id="7390545607259442187">Konfirmasi Kartu</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> Anda dikelola</translation>
<translation id="7407424307057130981">&lt;p&gt;Anda akan melihat error ini jika memiliki software Superfish di komputer Windows.&lt;/p&gt;
&lt;p&gt;Ikuti langkah-langkah ini untuk menonaktifkan software tersebut sementara waktu agar Anda dapat mengakses web. Anda memerlukan hak istimewa administrator.&lt;/p&gt;
&lt;ol&gt;
@@ -1001,7 +1143,7 @@
&lt;li&gt;Klik &lt;strong&gt;Apply&lt;/strong&gt;, lalu klik &lt;strong&gt;Ok&lt;/strong&gt;
&lt;li&gt;Buka &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Pusat bantuan Chrome&lt;/a&gt; untuk mempelajari cara menghapus software tersebut secara permanen dari komputer
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Pengelolaan <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Kelola Sandi...</translation>
<translation id="7419106976560586862">Jalur Profil</translation>
<translation id="7437289804838430631">Tambahkan Info Kontak</translation>
@@ -1010,22 +1152,24 @@
<translation id="7442725080345379071">Oranye Muda</translation>
<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="7449109375006139765">mengirimkan log sistem ke server pengelolaan</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="7460618730930299168">Penyaringan ini berbeda dengan yang telah Anda pilih. Lanjutkan?</translation>
<translation id="7473891865547856676">Lain Kali</translation>
-<translation id="7475525192983021547">melaporkan periode waktu saat pengguna aktif menggunakan perangkat</translation>
<translation id="7481312909269577407">Maju</translation>
<translation id="7485870689360869515">Tidak ada data yang ditemukan.</translation>
+<translation id="7498234416455752244">Lanjut mengedit</translation>
<translation id="7508255263130623398">ID perangkat kebijakan yang dikembalikan kosong atau tidak cocok dengan ID perangkat saat ini</translation>
<translation id="7508870219247277067">Hijau Avokad</translation>
<translation id="7511955381719512146">Wi-Fi yang digunakan mungkin mewajibkan Anda mengunjungi <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Download</translation>
<translation id="7518003948725431193">Tidak ada halaman web yang ditemukan untuk alamat web:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Koneksi Anda ke situs ini tidak bersifat pribadi</translation>
+<translation id="7535087603100972091">Nilai</translation>
<translation id="7537536606612762813">Wajib</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1034,8 +1178,8 @@
<translation id="7552846755917812628">Coba tips berikut:</translation>
<translation id="7554791636758816595">Tab Baru</translation>
<translation id="7564049878696755256">Anda dapat kehilangan akses ke akun <ph name="ORG_NAME" /> atau mengalami pencurian identitas. Chrome menyarankan Anda untuk mengubah sandi sekarang.</translation>
-<translation id="7566125604157659769">Teks yang Anda salin</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="7568105740864181217">Browser ini dikelola oleh sebuah perusahaan, sekolah, atau organisasi lain. Administrator dapat mengubah penyiapan browser Anda dari jarak jauh. Aktivitas di perangkat ini juga dapat dikelola di luar Chrome. <ph name="BEGIN_LINK" />Pelajari Lebih Lanjut<ph name="END_LINK" /></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>
@@ -1046,6 +1190,7 @@
<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="7633909222644580952">Data performa dan laporan kerusakan</translation>
<translation id="7637571805876720304">Hapus kartu kredit dari Chromium?</translation>
<translation id="7639968568612851608">Abu-Abu Tua</translation>
<translation id="765676359832457558">Sembunyikan setelan lanjutan...</translation>
@@ -1055,9 +1200,11 @@
<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="7676643023259824263">Telusuri teks papan klip, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Ubah Mesin Telusur</translation>
<translation id="7682287625158474539">Pengiriman</translation>
<translation id="7687186412095877299">Mengisi formulir pembayaran dengan metode pembayaran yang Anda simpan</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">Sekarang, Anda memiliki beberapa kartu yang hanya dapat digunakan di perangkat ini. Klik Lanjutkan untuk meninjau kartu.</translation>
<translation id="7699293099605015246">Artikel tidak tersedia untuk saat ini</translation>
<translation id="7701040980221191251">Tidak ada</translation>
@@ -1069,11 +1216,13 @@
<translation id="774634243536837715">Konten berbahaya diblokir.</translation>
<translation id="7752995774971033316">Tidak terkelola</translation>
<translation id="7755287808199759310">Orang tua dapat membuka blokirnya untukmu</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Software antivirus atau firewall mungkin memblokir sambungan.</translation>
<translation id="7759163816903619567">Tampilkan domain:</translation>
<translation id="7761701407923456692">Sertifikat server tidak cocok dengan URL.</translation>
<translation id="7763386264682878361">Parser Manifes Pembayaran</translation>
<translation id="7764225426217299476">Tambahkan alamat</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Tambahkan</translation>
<translation id="7793809570500803535">Halaman web di <ph name="SITE" /> mungkin sedang tidak aktif untuk sementara atau telah dipindahkan secara permanen ke alamat web baru.</translation>
@@ -1085,8 +1234,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Hapus sebagai saran dari Chrome?</translation>
<translation id="7815407501681723534">Ditemukan <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> hasil untuk '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Manajemen kebijakan</translation>
<translation id="782886543891417279">Wi-Fi yang digunakan (<ph name="WIFI_NAME" />) mungkin mewajibkan Anda mengunjungi halaman masuknya.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Tidak ada}=1{1 aplikasi (<ph name="EXAMPLE_APP_1" />)}=2{2 aplikasi (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# aplikasi (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Namun, Anda masih dapat terlihat. Login ke mode penyamaran tidak menyembunyikan penjelajahan Anda dari atasan, penyedia layanan internet, atau situs web yang Anda kunjungi.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1095,7 +1244,7 @@
<translation id="7878562273885520351">Sandi Anda mungkin disusupi</translation>
<translation id="7882421473871500483">Cokelat</translation>
<translation id="7887683347370398519">Periksa CVC dan coba lagi</translation>
-<translation id="7893255318348328562">Nama sesi</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Masukkan nomor telepon yang valid</translation>
<translation id="7935318582918952113">Penyaring DOM</translation>
<translation id="7937554595067888181">Masa berlaku habis pada <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1105,21 +1254,25 @@
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Bookmark seluler</translation>
<translation id="7961015016161918242">Jangan pernah</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
<translation id="800218591365569300">Coba tutup tab atau program lain untuk mengosongkan memori.</translation>
+<translation id="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Kelola Kata sandi</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Kartu ini dan alamat penagihannya akan disimpan. Anda dapat menggunakannya saat login ke <ph name="USER_EMAIL" />.}other{Semua kartu ini dan alamat penagihannya akan disimpan. Anda dapat menggunakannya saat login ke <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Halaman ini berbahasa <ph name="SOURCE_LANGUAGE" />. Terjemahkan ke <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pena</translation>
+<translation id="8037117624646282037">Siapa yang baru saja menggunakan perangkat</translation>
<translation id="8037357227543935929">Tanyakan (default)</translation>
<translation id="803771048473350947">File</translation>
<translation id="8041089156583427627">Kirim Masukan</translation>
<translation id="8041940743680923270">Gunakan default global (Tanyakan)</translation>
<translation id="8042918947222776840">Pilih Metode Pengambilan</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" tidak dikonfigurasi dengan benar. Biasanya masalah akan terselesaikan dengan meng-uninstal "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Perangkat telah dikonfigurasi untuk:</translation>
+<translation id="8066955247577885446">Maaf, terjadi error.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Tidak dapat menambahkan anotasi saat diputar</translation>
<translation id="8079031581361219619">Muat ulang situs?</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
@@ -1128,11 +1281,12 @@
<translation id="8091372947890762290">Aktivasi ditunda di server</translation>
<translation id="8092774999298748321">Ungu Tua</translation>
<translation id="8094917007353911263">Jaringan yang Anda gunakan mungkin mewajibkan Anda mengunjungi <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Kartu yang tidak valid telah dihapus</translation>
<translation id="8103161714697287722">Metode Pembayaran</translation>
<translation id="8118489163946903409">Metode pembayaran</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> dikelola menurut <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" tidak diinstal dengan benar di komputer atau jaringan Anda. Mintalah administrator IT untuk menyelesaikan masalah ini.</translation>
-<translation id="8130693978878176684">Maaf, kami tidak bisa membantu lagi. Silakan lanjutkan sendiri.</translation>
<translation id="8131740175452115882">Konfirmasi</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>
@@ -1142,8 +1296,11 @@
<translation id="8197543752516192074">Terjemahkan Halaman</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="8202370299023114387">Konflik</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">Koneksi aman</translation>
<translation id="8218327578424803826">Lokasi yang Ditetapkan:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Buka halaman dalam tab Penyamaran baru</translation>
@@ -1155,14 +1312,16 @@
<translation id="825929999321470778">Tampilkan Semua Sandi Tersimpan</translation>
<translation id="8261506727792406068">Hapus</translation>
<translation id="8267698848189296333">Login sebagai <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Browser ini dikelola oleh <ph name="ENROLLMENT_DOMAIN" />. Administrator dapat mengubah penyiapan browser Anda dari jarak jauh. Aktivitas di perangkat ini juga dapat dikelola di luar Chrome. <ph name="BEGIN_LINK" />Pelajari Lebih Lanjut<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Login</translation>
<translation id="8288807391153049143">Tampilkan sertifikat</translation>
<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="8298115750975731693">Wi-Fi yang digunakan (<ph name="WIFI_NAME" />) mungkin mewajibkan Anda mengunjungi <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Terjemahan gagal karena ada masalah dengan koneksi jaringan.</translation>
-<translation id="8311129316111205805">Muat sesi</translation>
<translation id="8332188693563227489">Akses ke <ph name="HOST_NAME" /> ditolak</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1178,7 +1337,6 @@
<translation id="8412145213513410671">Ngadat (<ph name="CRASH_COUNT" />)</translation>
<translation id="8412392972487953978">Anda harus memasukkan frasa sandi yang sama dua kali.</translation>
<translation id="8416694386774425977">Konfigurasi jaringan tidak valid dan tidak dapat diimpor. Detail tambahan: <ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Perangkat dikelola oleh <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Ubah</translation>
<translation id="8428213095426709021">Setelan</translation>
@@ -1205,9 +1363,11 @@
<translation id="860043288473659153">Nama pemegang kartu</translation>
<translation id="861775596732816396">Ukuran 4</translation>
<translation id="8620436878122366504">Orang tuamu belum menyetujuinya</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Simpan Kartu Ini ke Perangkat Ini</translation>
<translation id="8663226718884576429">Ringkasan Pesanan, <ph name="TOTAL_LABEL" />, Detail Selengkapnya</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, dengan jawaban, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Sambungan ke <ph name="DOMAIN" /> tidak dienkripsi.</translation>
<translation id="8718314106902482036">Pembayaran belum selesai</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, saran penelusuran</translation>
@@ -1221,6 +1381,7 @@
<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="8763927697961133303">Perangkat USB</translation>
<translation id="8768895707659403558">Untuk menggunakan kartu Anda di semua perangkat, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Ulangi penghapusan</translation>
<translation id="8792621596287649091">Anda dapat kehilangan akses ke akun <ph name="ORG_NAME" /> atau mengalami pencurian identitas. Chromium menyarankan Anda untuk mengubah sandi sekarang.</translation>
<translation id="8800988563907321413">Saran terdekat muncul di sini</translation>
@@ -1231,10 +1392,12 @@
<translation id="885730110891505394">Berbagi dengan Google</translation>
<translation id="8858065207712248076">Chrome menyarankan untuk menyetel ulang sandi <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> jika Anda juga menggunakannya di situs lain.</translation>
<translation id="8866481888320382733">Kesalahan saat menguraikan setelan kebijakan</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Baru Saja Ditutup</translation>
<translation id="8874824191258364635">Masukkan nomor kartu yang valid</translation>
<translation id="8891727572606052622">Mode proxy tidak valid.</translation>
<translation id="8903921497873541725">Perbesar</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Ingin menyimpan kartu ini ke Akun Google Anda?</translation>
<translation id="8932102934695377596">Setelan waktu Anda terlalu lambat</translation>
<translation id="893332455753468063">Tambahkan Nama</translation>
@@ -1242,13 +1405,13 @@
<translation id="894185898663964645">Administrator telah mengonfigurasi root certificate kustom, yang dapat mengizinkan administrator melihat konten situs yang Anda buka.</translation>
<translation id="8943282376843390568">Hijau limau</translation>
<translation id="8957210676456822347">Otorisasi Portal Tawanan</translation>
+<translation id="8966619695390250636">Apakah yang Anda maksud?</translation>
<translation id="8968766641738584599">Simpan kartu</translation>
<translation id="8971063699422889582">Sertifikat server telah kedaluwarsa.</translation>
<translation id="8975012916872825179">Termasuk informasi seperti nomor telepon, alamat email, dan alamat pengiriman</translation>
<translation id="8978053250194585037">Google Safe Browsing baru-baru ini <ph name="BEGIN_LINK" />mendeteksi phishing<ph name="END_LINK" /> di <ph name="SITE" />. Situs phishing berpura-pura menjadi situs lain untuk mengelabui Anda.</translation>
<translation id="8983003182662520383">Metode Pembayaran dan Alamat yang Menggunakan Google Pay</translation>
<translation id="8987927404178983737">Bulan</translation>
-<translation id="8988408250700415532">Terjadi masalah. Anda dapat menyelesaikan pesanan di situs.</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>
@@ -1258,6 +1421,7 @@
<translation id="9011424611726486705">Buka setelan situs</translation>
<translation id="9020200922353704812">Perlu alamat penagihan kartu</translation>
<translation id="9020542370529661692">Halaman ini telah diterjemahkan ke <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Tidak valid)</translation>
<translation id="9035022520814077154">Kesalahan keamanan</translation>
<translation id="9038649477754266430">Gunakan layanan prediksi agar halaman dimuat dengan lebih cepat</translation>
@@ -1269,11 +1433,11 @@
<translation id="9065745800631924235">penelusuran <ph name="TEXT" /> dari histori</translation>
<translation id="9069693763241529744">Diblokir oleh ekstensi</translation>
<translation id="9076283476770535406">Situs mungkin berisi konten dewasa</translation>
+<translation id="9076630408993835509">Browser ini tidak dikelola oleh sebuah perusahaan atau organisasi lain. Aktivitas di perangkat ini mungkin dikelola di luar Chrome. <ph name="BEGIN_LINK" />Pelajari Lebih Lanjut<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Dibutuhkan informasi lebih lanjut</translation>
<translation id="9080712759204168376">Ringkasan Pesanan</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>
<translation id="9106062320799175032">Tambahkan Alamat Penagihan</translation>
-<translation id="9110718169272311511">Asisten Google di Chrome tersedia di dekat bagian bawah layar</translation>
<translation id="9114524666733003316">Mengonfirmasi kartu...</translation>
<translation id="9128870381267983090">Sambungkan ke jaringan</translation>
<translation id="9137013805542155359">Perlihatkan halaman asli</translation>
@@ -1282,6 +1446,7 @@
<translation id="9148507642005240123">&amp;Urungkan pengeditan</translation>
<translation id="9154194610265714752">Diperbarui</translation>
<translation id="9157595877708044936">Menyiapkan...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Izinkan situs memeriksa apakah Anda telah menyimpan metode pembayaran atau belum</translation>
<translation id="9169664750068251925">Selalu cekal di situs ini</translation>
<translation id="9170848237812810038">&amp;Urung</translation>
@@ -1296,10 +1461,12 @@
<translation id="9219103736887031265">Gambar</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">HAPUS FORMULIR</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Anda dapat kehilangan akses ke Akun Google Anda. Chromium merekomendasikan untuk mengubah sandi Anda sekarang. Anda akan diminta untuk login.</translation>
<translation id="939736085109172342">Folder baru</translation>
<translation id="945855313015696284">Periksa info di bawah dan hapus kartu apa pun yang tidak valid</translation>
<translation id="951104842009476243">Kartu Debit dan Prabayar yang Diterima</translation>
+<translation id="958202389743790697">Diblokir sesuai dengan kebijakan keamanan <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Konten ini mungkin mencoba menginstal aplikasi penipuan dengan berpura-pura menjadi sesuatu yang lain atau mengumpulkan data yang dapat digunakan untuk melacak Anda. <ph name="BEGIN_LINK" />Tampilkan saja<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Pembuatan Resmi</translation>
<translation id="973773823069644502">Tambahkan Alamat Pengiriman</translation>
@@ -1308,6 +1475,7 @@
<translation id="984275831282074731">Metode pembayaran</translation>
<translation id="985199708454569384">&lt;p&gt;Anda akan melihat error ini jika tanggal dan waktu di komputer atau perangkat seluler Anda tidak akurat.&lt;/p&gt;
&lt;p&gt;Untuk memperbaiki error, buka jam perangkat. Pastikan waktu dan tanggal sudah tepat.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Buatan Pengembang</translation>
<translation id="989988560359834682">Edit Alamat</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_it.xtb b/chromium/components/strings/components_strings_it.xtb
index 8f0ef46e2ec..c31ec1e0a78 100644
--- a/chromium/components/strings/components_strings_it.xtb
+++ b/chromium/components/strings/components_strings_it.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="it">
-<translation id="1005145902654145231">Impossibile rinominare la sessione.</translation>
<translation id="1008557486741366299">Non adesso</translation>
<translation id="1010200102790553230">Carica la pagina più tardi</translation>
<translation id="1015730422737071372">Fornisci ulteriori dettagli</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nome sconosciuto</translation>
<translation id="1050038467049342496">Chiudi altre app</translation>
<translation id="1055184225775184556">&amp;Annulla aggiunta</translation>
+<translation id="1056898198331236512">Avviso</translation>
<translation id="1058479211578257048">Salvataggio delle carte...</translation>
<translation id="10614374240317010">Mai salvate</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Preferiti desktop</translation>
<translation id="1074497978438210769">Non sicuro</translation>
<translation id="1080116354587839789">Adatta in larghezza</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Aggiungi il nome indicato sulla carta</translation>
<translation id="1089439967362294234">Cambia password</translation>
<translation id="109743633954054152">Gestisci le password nelle impostazioni di Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Gli avvisi potrebbero essere frequenti durante l'aggiornamento della sicurezza dei siti web. La situazione dovrebbe migliorare a breve.</translation>
<translation id="1126551341858583091">Le dimensioni nello spazio di archiviazione locale sono pari a <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache dei criteri integra</translation>
+<translation id="1131264053432022307">Immagine copiata</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Rinomina</translation>
<translation id="1175364870820465910">&amp;Stampa...</translation>
<translation id="1181037720776840403">Rimuovi</translation>
<translation id="1197088940767939838">Arancione</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Il nome del tuo dispositivo</translation>
<translation id="124116460088058876">Altre lingue</translation>
<translation id="1250759482327835220">Per pagare più velocemente la prossima volta, salva la carta, il nome e l'indirizzo di fatturazione sul tuo Account Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizzati)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variazioni nella riga di comando</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="1314614906530272393">La sessione selezionata non esiste.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Cerca immagine negli appunti</translation>
<translation id="1323433172918577554">Espandi</translation>
<translation id="132390688737681464">Salva e compila gli indirizzi</translation>
<translation id="1333989956347591814">La tua attività <ph name="BEGIN_EMPHASIS" />potrebbe comunque essere visibile<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Indirizzo di ritiro</translation>
<translation id="1348198688976932919">Il sito che stai per visitare contiene app pericolose</translation>
<translation id="1348779747280417563">Confermare il nome</translation>
+<translation id="1357195169723583938">Utenti che hanno usato il dispositivo di recente e quando</translation>
+<translation id="1364822246244961190">Questa norma è bloccata e quindi verrà ignorata.</translation>
<translation id="1374468813861204354">suggerimenti</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Informazioni sulla versione</translation>
<translation id="1376836354785490390">Comprimi</translation>
<translation id="1377321085342047638">Numero carta</translation>
<translation id="138218114945450791">Azzurro</translation>
+<translation id="1382194467192730611">Dispositivo USB consentito dall'amministratore</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> non ha inviato dati.</translation>
+<translation id="140316286225361634">Il sito <ph name="ORIGIN" /> ha richiesto l'applicazione di una norma di sicurezza
+ a tutte le richieste e questa norma attualmente reputa il sito
+ pericoloso.</translation>
<translation id="1405567553485452995">Verde chiaro</translation>
<translation id="1407135791313364759">Apri tutte</translation>
<translation id="1413809658975081374">Errore di privacy</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Sì</translation>
<translation id="1430915738399379752">Stampa</translation>
<translation id="1455413310270022028">Gomma</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Mostra altro</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Scegli l'indirizzo di spedizione</translation>
+<translation id="1492194039220927094">Push delle norme:</translation>
<translation id="1501859676467574491">Mostra le carte dall'Account Google</translation>
-<translation id="1506687042165942984">Mostra una copia salvata (cioè che è noto sia obsoleta) di questa pagina.</translation>
<translation id="1507202001669085618">&lt;p&gt;Vedrai questo errore se stai utilizzando un portale Wi-Fi che richiede l'accesso per poterti connettere a Internet.&lt;/p&gt;
&lt;p&gt;Per risolvere il problema, fai clic su &lt;strong&gt;Connetti&lt;/strong&gt; nella pagina che stai cercando di aprire.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Numero di telefono obbligatorio</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Data build</translation>
<translation id="1521655867290435174">Fogli Google</translation>
<translation id="1527263332363067270">In attesa di connessione…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Questa pagina dice</translation>
<translation id="153384715582417236">Per il momento è tutto</translation>
<translation id="154408704832528245">Scegli l'indirizzo di consegna</translation>
<translation id="1549470594296187301">JavaScript deve essere attivato per utilizzare questa funzione.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Inserisci data di scadenza</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Immagine copiata</translation>
<translation id="1620510694547887537">Videocamera</translation>
<translation id="1623104350909869708">Impedisci la creazione di altre finestre di dialogo in questa pagina</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Termina sessione</translation>
<translation id="1639239467298939599">Caricamento</translation>
<translation id="1640180200866533862">Criteri utente</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Il certificato del server contiene una chiave crittografica debole.</translation>
<translation id="1697532407822776718">Ecco fatto!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Il documento è troppo voluminoso per potervi inserire annotazioni</translation>
<translation id="1721312023322545264">Ti occorre l'autorizzazione di <ph name="NAME" /> per poter visitare il sito</translation>
<translation id="1721424275792716183">* Campo obbligatorio</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Prova a contattare l'amministratore di sistema.</translation>
<translation id="1740951997222943430">Inserisci un mese di scadenza valido</translation>
<translation id="1743520634839655729">Per pagare più velocemente la prossima volta, salva la carta e l'indirizzo di fatturazione sul tuo Account Google e su questo dispositivo.</translation>
+<translation id="1745880797583122200">Il browser in uso è gestito</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Aggiorna la tua passphrase di sincronizzazione.</translation>
<translation id="1787142507584202372">Le tue schede aperte vengono visualizzate qui</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nome del titolare della carta</translation>
<translation id="1821930232296380041">Richiesta o parametri della richiesta non validi</translation>
+<translation id="1822540298136254167">Siti web visitati e tempo trascorso sui siti</translation>
<translation id="1826516787628120939">Verifica in corso...</translation>
<translation id="1834321415901700177">Il sito contiene programmi dannosi.</translation>
<translation id="1839551713262164453">Convalida dei valori della norma non riuscita con errori</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Cancella i dati della cronologia di navigazione di Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{e un'altra}other{e altre #}}</translation>
<translation id="2003709556000175978">Reimposta ora la password</translation>
+<translation id="20053308747750172">Il server a cui ti stai collegando, <ph name="ORIGIN" />, ha richiesto
+ l'applicazione di una norma di sicurezza per tutte le richieste. Ma adesso ha
+ pubblicato una norma non valida che impedisce al browser
+ di soddisfare la tua richiesta per il sito <ph name="SITE" />.</translation>
<translation id="2025186561304664664">È stata impostata la configurazione automatica del proxy.</translation>
<translation id="2030481566774242610">Forse cercavi <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Controllare il proxy e firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Dipartimento</translation>
<translation id="2102134110707549001">Suggerisci password efficace…</translation>
<translation id="2108755909498034140">Riavvia il computer</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Carta</translation>
<translation id="2114841414352855701">Ignorata perché è stata sostituita da <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Preferiti su disp. mobili</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Criteri</translation>
<translation id="2183608646556468874">Numero di telefono</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 indirizzo}other{# indirizzi}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Numero di telefono</translation>
<translation id="2283340219607151381">Salva e compila gli indirizzi</translation>
<translation id="2292556288342944218">L'accesso a Internet è bloccato</translation>
+<translation id="2294558542833290837">Il link che hai aperto in partenza è insolito</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Consente di liberare meno di 1 MB. Alcuni siti potrebbero caricarsi più lentamente alla prossima visita.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> richiede un nome utente e una password.</translation>
<translation id="2317583587496011522">Le carte di debito sono accettate.</translation>
<translation id="2330137317877982892">Scadenza della carta <ph name="CREDIT_CARD" />: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Impostazione controllata dall'amministratore</translation>
+<translation id="2346319942568447007">Immagine copiata</translation>
<translation id="2349790679044093737">Sessione VR attiva</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Navigazione privata attiva</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Valore predefinito aziendale</translation>
<translation id="2386255080630008482">Il certificato del server è stato revocato.</translation>
<translation id="2392959068659972793">Mostra criteri 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="2410754574180102685">Government-Legal</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="2418081434543109369">Il server a cui ti stai collegando, <ph name="ORIGIN" />, ha richiesto
+ l'applicazione di una norma di sicurezza per tutte le richieste. Ma adesso non
+ è riuscito a pubblicare una norma e ciò impedisce al browser
+ di soddisfare la tua richiesta per il sito <ph name="SITE" />.</translation>
<translation id="244665789865330679">Il tuo dispositivo e il tuo account sono gestiti da <ph name="ENROLLMENT_DOMAIN" />. L'amministratore può configurare da remoto il dispositivo e l'account.</translation>
<translation id="2463193859425327265">Cambia la pagina iniziale</translation>
<translation id="2463739503403862330">Compila</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Scegli il metodo di consegna</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Eseguire lo strumento Diagnostica di rete<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traduci questa pagina</translation>
<translation id="2479410451996844060">URL ricerca non valido.</translation>
<translation id="2482878487686419369">Notifiche</translation>
<translation id="248348093745724435">Norme macchina</translation>
+<translation id="2485387744899240041">Nomi utente del dispositivo e del browser</translation>
<translation id="2491120439723279231">Il certificato del server contiene degli errori.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Esegui scansione nuova carta</translation>
<translation id="2501278716633472235">Indietro</translation>
<translation id="2503184589641749290">Carte di debito e prepagate accettate</translation>
<translation id="2515629240566999685">Controllare il segnale nella tua area</translation>
-<translation id="2516852381693169964">Cerca l'immagine su <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Salvataggio effettuato solo su questo dispositivo</translation>
<translation id="2524461107774643265">Aggiungi altre informazioni</translation>
<translation id="2536110899380797252">Aggiungi indirizzo</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">L'orologio è avanti</translation>
<translation id="2634124572758952069">Impossibile trovare l'indirizzo IP del server di <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Stato:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Chiudi altre schede o app</translation>
<translation id="267371737713284912">Premi <ph name="MODIFIER_KEY_DESCRIPTION" /> per annullare</translation>
<translation id="2674170444375937751">Eliminare le pagine dalla cronologia?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Esci</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Carte accettate</translation>
<translation id="2702801445560668637">Elenco di lettura</translation>
<translation id="2704283930420550640">Il valore non corrisponde al formato.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Rimuovi gli elementi selezionati</translation>
<translation id="277133753123645258">Metodo di spedizione</translation>
<translation id="277499241957683684">Record del dispositivo mancante</translation>
-<translation id="2781030394888168909">Esporta Mac OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">La connessione è stata reimpostata.</translation>
<translation id="2788784517760473862">Carte di credito accettate</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Apri finestra di navigazione in incognito</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Ti occorre l'autorizzazione per poter visitare questo sito</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Salvare la carta?</translation>
<translation id="2903493209154104877">Indirizzi</translation>
<translation id="290376772003165898">La pagina non è in <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Metodo di consegna</translation>
<translation id="2928905813689894207">Indirizzo di fatturazione</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Tipo di criterio errato</translation>
<translation id="3037605927509011580">Uffa!</translation>
<translation id="3041612393474885105">Informazioni certificato</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Aggiungi l'indirizzo di ritiro</translation>
<translation id="3105172416063519923">ID asset:</translation>
<translation id="3109728660330352905">Non sei autorizzato a visualizzare questa pagina.</translation>
@@ -361,20 +409,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> su <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Annulla pagamento</translation>
<translation id="3207960819495026254">Aggiunto ai preferiti</translation>
-<translation id="3209375525920864198">Inserisci un nome sessione valido</translation>
+<translation id="321912867715453276">Avviso: è presente più di una fonte per questa norma, ma i valori sono gli stessi.</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="3229041911291329567">Informazioni sulla versione del dispositivo e del browser</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Aggiungi il nome indicato sulla carta</translation>
<translation id="3287510313208355388">Scarica quando è online</translation>
<translation id="3293642807462928945">Scopri di più sulla norma <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nessun risultato di ricerca trovato</translation>
-<translation id="3305707030755673451">I tuoi dati sono stati criptati con la tua passphrase di sincronizzazione in data <ph name="TIME" />. Inseriscila per avviare la sincronizzazione.</translation>
<translation id="3320021301628644560">Aggiungi l'indirizzo di fatturazione</translation>
<translation id="3324983252691184275">Cremisi</translation>
<translation id="3338095232262050444">Sicuro</translation>
@@ -402,9 +451,11 @@
<translation id="3427342743765426898">&amp;Ripeti modifica</translation>
<translation id="342781501876943858">Chromium ti consiglia di reimpostare la password, se l'hai utilizzata su altri siti.</translation>
<translation id="3431636764301398940">Salva la carta per questo dispositivo</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Il proprietario del dispositivo ha disattivato il gioco dei dinosauri.</translation>
<translation id="3447884698081792621">Mostra certificato (rilasciato da <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Intervallo recupero:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Evidenziatore</translation>
<translation id="3462200631372590220">Nascondi avanzate</translation>
<translation id="3467763166455606212">Nome titolare carta obbligatorio</translation>
@@ -427,20 +478,23 @@
<translation id="358285529439630156">Le carte di credito e prepagate sono accettate.</translation>
<translation id="3582930987043644930">Aggiungi nome</translation>
<translation id="3583757800736429874">&amp;Ripeti spostamento</translation>
+<translation id="35866233670761917">I contenuti dei siti web visitati non sono visti dagli amministratori</translation>
<translation id="3586931643579894722">Nascondi dettagli</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Dimensione 2</translation>
<translation id="3615877443314183785">Inserisci una data di scadenza valida</translation>
<translation id="36224234498066874">Cancella dati di navigazione...</translation>
<translation id="362276910939193118">Mostra cronologia completa</translation>
-<translation id="3623476034248543066">Mostra valore</translation>
<translation id="3630155396527302611">Se è già elencato come programma autorizzato ad accedere alla rete, prova a
rimuoverlo dall'elenco e ad aggiungerlo di nuovo.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Convalida riuscita</translation>
<translation id="3655670868607891010">Se questo problema si verifica spesso, prova questi <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisione</translation>
<translation id="366077651725703012">Aggiorna carta di credito</translation>
<translation id="3676592649209844519">ID dispositivo:</translation>
+<translation id="3677008721441257057">Forse intendevi &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Impossibile firmare la richiesta</translation>
<translation id="3678529606614285348">Apri la pagina in un'altra finestra di navigazione in incognito (CTRL-MAIUSC-N)</translation>
<translation id="3679803492151881375">Rapporto sugli arresti anomali generato in data <ph name="CRASH_TIME" />, caricato in data <ph name="UPLOAD_TIME" /></translation>
@@ -448,13 +502,14 @@
<translation id="3704162925118123524">La rete che stai utilizzando può richiedere di visitare la relativa pagina di accesso.</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="3709599264800900598">Testo copiato</translation>
<translation id="3712624925041724820">Licenze esaurite</translation>
<translation id="3714780639079136834">Attivare la rete dati mobile o Wi-Fi</translation>
<translation id="3715597595485130451">Collegati alla rete Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Controllare la configurazione del proxy, firewall e DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Le applicazioni che possono causare questo errore includono software antivirus, firewall e proxy o di filtraggio web.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Dopo essere stati confermati, i dati della carta del tuo Account Google saranno condivisi con questo sito.</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, come installare software o 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>
@@ -467,10 +522,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Data di scadenza: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Dimensione 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Contenuti dannosi bloccati.</translation>
<translation id="3810973564298564668">Gestisci</translation>
<translation id="382518646247711829">Se utilizzi un server proxy...</translation>
<translation id="3828924085048779000">Non è consentita una passphrase vuota.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ha installato estensioni relative a funzioni aggiuntive. Le estensioni hanno accesso ad alcuni tuoi dati.</translation>
<translation id="385051799172605136">Indietro</translation>
<translation id="3858027520442213535">Aggiorna data e ora</translation>
<translation id="3884278016824448484">Identificativo del dispositivo in conflitto</translation>
@@ -478,6 +535,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Chiedi sempre su questo sito</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>
@@ -488,11 +546,13 @@
<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="3984550557525787191">Esiste già una sessione con questo nome.</translation>
<translation id="3987940399970879459">Meno di 1 MB</translation>
+<translation id="4008849406247176967">Avviso: è presente più di una fonte con valori in conflitto per questa norma.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Una pagina web nelle vicinanze}other{# pagine web nelle vicinanze}}</translation>
<translation id="4030383055268325496">&amp;Annulla aggiunta</translation>
+<translation id="4032320456957708163">Il browser in uso è gestito da <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Chiave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Aggiungi un indirizzo valido</translation>
<translation id="4072486802667267160">Si è verificato un errore durante l'elaborazione dell'ordine. Riprova.</translation>
<translation id="4075732493274867456">Il client e il server non supportano un pacchetto di crittografia o una versione del protocollo SSL comuni.</translation>
@@ -512,10 +572,12 @@
<translation id="4159784952369912983">Viola</translation>
<translation id="4165986682804962316">Impostazioni sito</translation>
<translation id="4171400957073367226">Firma di verifica non valida</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> altro elemento}other{Altri <ph name="ITEM_COUNT" /> elementi}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Passaggio 1: accedi al portale&lt;/h4&gt;
@@ -547,58 +609,79 @@
<translation id="4277028893293644418">Reimposta password</translation>
<translation id="4280429058323657511">, scad.: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Questa carta è stata salvata nel tuo Account Google}other{Queste carte sono state salvate nel tuo Account Google}}</translation>
+<translation id="42981349822642051">Espandi</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Cambia</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blocca (predefinita)</translation>
+<translation id="4318566738941496689">Il nome e l'indirizzo di rete del dispositivo</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="4340982228985273705">Questo computer sembra non essere gestito dall'azienda, pertanto la norma consente di installare automaticamente soltanto le estensioni ospitate sul Chrome Web Store. L'URL di aggiornamento del Chrome Web Store è "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Carte di credito accettate</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gestisci metodi di pagamento…</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefono</translation>
<translation id="4406896451731180161">risultati di ricerca</translation>
-<translation id="4406972042435603828">Gli amministratori hanno installato estensioni con funzionalità efficaci.</translation>
<translation id="4408413947728134509">Cookie: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Indirizzo di ritiro</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="443121186588148776">Porta seriale</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> non ha accettato il certificato di accesso oppure non ne è stato fornito uno.</translation>
<translation id="4434045419905280838">Popup e reindirizzamenti</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">L'utilizzo di un proxy è stato disattivato ma è stata specificata una configurazione proxy esplicita.</translation>
<translation id="445100540951337728">Carte di debito accettate</translation>
+<translation id="4466881336512663640">Le modifiche apportate al modulo andranno perse. Vuoi continuare?</translation>
<translation id="4482953324121162758">Questo sito non verrà tradotto.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL non valido. Deve essere un URL con schema standard, ad esempio http://example.com o https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Dettagli</translation>
<translation id="4524805452350978254">Gestisci le carte</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prova a disattivare le estensioni.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Consegna</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Carta rimossa</translation>
<translation id="4587425331216688090">Rimuovere l'indirizzo da Chrome?</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="4597348597567598915">Dimensione 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Vai subito</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="467809019005607715">Presentazioni Google</translation>
<translation id="4690462567478992370">Interrompi l'utilizzo di un certificato non valido</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">La connessione è stata interrotta</translation>
<translation id="471880041731876836">Non sei autorizzato a visitare questo sito</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Eseguire lo strumento Diagnostica di rete Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Ricarica criteri</translation>
<translation id="4728558894243024398">Piattaforma</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Riavvia Chromium</translation>
<translation id="473775607612524610">Aggiorna</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> suggerimento di ricerca</translation>
<translation id="4742407542027196863">Gestisci password…</translation>
<translation id="4744603770635761495">Percorso eseguibile</translation>
+<translation id="4746351372139058112">Messaggi</translation>
<translation id="4750917950439032686">Le tue informazioni (ad esempio password o numeri di carte di credito) restano private quando vengono inviate a questo sito.</translation>
<translation id="4756388243121344051">&amp;Cronologia</translation>
<translation id="4758311279753947758">Aggiungi informazioni di contatto</translation>
@@ -606,9 +689,9 @@
<translation id="4764776831041365478">La pagina web all'indirizzo <ph name="URL" /> potrebbe essere temporaneamente non disponibile oppure è stata permanentemente spostata a un nuovo indirizzo web.</translation>
<translation id="4771973620359291008">Si è verificato un errore sconosciuto.</translation>
<translation id="4785689107224900852">Passa a questa scheda</translation>
-<translation id="4792143361752574037">Si è verificato un problema durante l'accesso ai file di sessione. Il salvataggio su disco è attualmente disattivato. Ricarica la pagina e riprova.</translation>
<translation id="4798078619018708837">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 dati della carta del tuo Account Google saranno condivisi con questo sito.</translation>
<translation id="4800132727771399293">Controlla la data di scadenza e il codice CVC, poi riprova</translation>
+<translation id="480334179571489655">Errore norma di partenza</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>
@@ -623,7 +706,6 @@
<translation id="4881695831933465202">Apri</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>
@@ -632,15 +714,15 @@
<translation id="4943872375798546930">Nessun risultato</translation>
<translation id="4950898438188848926">Pulsante per cambiare scheda, premi INVIO per passare alla scheda aperta, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Azioni</translation>
-<translation id="495832697253704892">Rapporto sulle estensioni</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Espandi elenco</translation>
<translation id="4974590756084640048">Riattiva avvisi</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Mostra tutto</translation>
<translation id="4989809363548539747">Questo plug-in non è supportato</translation>
-<translation id="4996230189582812866">Rapporti</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="5014174725590676422">È mostrata la schermata della prima esecuzione dell'Assistente Google in Chrome</translation>
<translation id="5015510746216210676">Nome macchina:</translation>
+<translation id="5017554619425969104">Testo copiato</translation>
<translation id="5018422839182700155">Impossibile aprire questa pagina</translation>
<translation id="5019198164206649151">Archivio di backup in stato non valido</translation>
<translation id="5023310440958281426">Consulta le norme dell'amministratore</translation>
@@ -650,35 +732,51 @@
<translation id="5034369478845443529">Contesto locale <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Consenti</translation>
<translation id="5040262127954254034">Privacy</translation>
+<translation id="5043480802608081735">Link copiato</translation>
<translation id="5045550434625856497">Password non corretta</translation>
<translation id="5056549851600133418">Articoli per te</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Controllare l'indirizzo proxy<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Il certificato del server non è valido in questa fase.</translation>
<translation id="5087580092889165836">Aggiungi carta</translation>
<translation id="5089810972385038852">Stato</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="5097099694988056070">Statistiche del dispositivo quali l'utilizzo di CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Il tuo dispositivo è gestito da <ph name="ENROLLMENT_DOMAIN" />, il tuo account da <ph name="ACCOUNT_DOMAIN" />. Gli amministratori possono configurare da remoto il dispositivo e l'account.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(a 64 bit)</translation>
-<translation id="5128122789703661928">Impossibile eliminare la sessione perché il nome specificato non è valido.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gestisci indirizzi…</translation>
+<translation id="5138227688689900538">Mostra meno</translation>
<translation id="5141240743006678641">Cripta le password sincronizzate con le tue credenziali Google</translation>
<translation id="5145883236150621069">Codice di errore presente nella risposta del criterio</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Apri la pagina in un'altra finestra di navigazione in incognito (⇧⌘N)</translation>
<translation id="516920405563544094">Inserisci il codice CVC della carta <ph name="CREDIT_CARD" />. Dopo essere stati confermati, i dati della carta del tuo Account Google saranno condivisi con questo sito.</translation>
<translation id="5169827969064885044">Potresti perdere l'accesso all'account della tua organizzazione o subire un furto d'identità. Chrome ti consiglia di cambiare subito la password.</translation>
<translation id="5171045022955879922">Cerca o digita un URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Computer</translation>
<translation id="5179510805599951267">Non in <ph name="ORIGINAL_LANGUAGE" />? Segnala questo errore</translation>
<translation id="5190835502935405962">Barra dei Preferiti</translation>
-<translation id="5200263511887412697">Segnala l'elenco di utenti del dispositivo che hanno eseguito l'accesso di recente</translation>
+<translation id="519422657042045905">Annotazione non disponibile</translation>
<translation id="5201306358585911203">Una pagina incorporata in questa pagina dice</translation>
<translation id="5205222826937269299">Nome obbligatorio</translation>
<translation id="5215116848420601511">Metodi di pagamento e indirizzi che utilizzano Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Email obbligatoria</translation>
<translation id="5230733896359313003">Indirizzo di spedizione</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Collegati alla rete"</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Indirizzi di rete</translation>
<translation id="5285570108065881030">Mostra tutte le password salvate</translation>
<translation id="5287240709317226393">Mostra cookie</translation>
<translation id="5288108484102287882">La convalida dei valori della norma ha generato degli avvisi</translation>
@@ -690,7 +788,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> di <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Scegli le informazioni di contatto</translation>
<translation id="5327248766486351172">Nome</translation>
+<translation id="5329858041417644019">Il browser in uso non è gestito</translation>
<translation id="5332219387342487447">Modalità di spedizione</translation>
+<translation id="5334013548165032829">Log di sistema dettagliati</translation>
<translation id="5344579389779391559">Questa pagina potrebbe tentare di addebitarti dei costi</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>
@@ -698,6 +798,7 @@
<translation id="5377026284221673050">"L'orologio è indietro", "L'orologio è avanti" oppure "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Accedi e attiva la sincronizzazione per utilizzare le tue carte su tutti i dispositivi.</translation>
<translation id="5386426401304769735">Il certificato di questo sito contiene un certificato che è stato firmato utilizzando SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -708,6 +809,7 @@
<translation id="5457113250005438886">Non validi</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Ripeti modifica</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Aggiungi un indirizzo valido</translation>
<translation id="5490432419156082418">Indirizzi e altro</translation>
@@ -715,10 +817,12 @@
<ph name="LINE_BREAK" />
Prova a contattare l'amministratore di sistema.</translation>
<translation id="549333378215107354">Dimensione 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Preferiti gestiti</translation>
<translation id="5510766032865166053">Potrebbe essere stato spostato o eliminato.</translation>
<translation id="5523118979700054094">Nome norma</translation>
<translation id="552553974213252141">Il testo è stato estratto correttamente?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Impossibile trovare l'articolo richiesto.</translation>
<translation id="5541546772353173584">Aggiungi email</translation>
<translation id="5545756402275714221">Articoli per te</translation>
@@ -733,15 +837,21 @@
<translation id="5595485650161345191">Modifica indirizzo</translation>
<translation id="5598944008576757369">Scegli il metodo di pagamento</translation>
<translation id="560412284261940334">Gestione non supportata</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> ti ha reindirizzato troppe volte.</translation>
<translation id="5629630648637658800">Caricamento delle impostazioni criterio non riuscito</translation>
<translation id="5631439013527180824">Token di gestione del dispositivo non valido</translation>
+<translation id="5632627355679805402">I tuoi dati sono stati criptati con la tua <ph name="BEGIN_LINK" />password Google<ph name="END_LINK" /> in data <ph name="TIME" />. Inserisci la password per avviare la sincronizzazione.</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="563324245173044180">Contenuti ingannevoli bloccati.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">L'amministratore di questo dispositivo ha installato estensioni relative a funzioni aggiuntive. Le estensioni hanno accesso ad alcuni tuoi dati.</translation>
<translation id="5675650730144413517">La pagina non funziona</translation>
+<translation id="5684874026226664614">Spiacenti. Impossibile tradurre questa pagina.</translation>
<translation id="5685654322157854305">Aggiungi l'indirizzo di spedizione</translation>
<translation id="5689199277474810259">Esporta in JSON</translation>
<translation id="5689516760719285838">Posizione</translation>
@@ -750,38 +860,39 @@
<translation id="5710435578057952990">L'identità di questo sito web non è stata verificata.</translation>
<translation id="5719499550583120431">Le carte prepagate sono accettate.</translation>
<translation id="5720705177508910913">Utente corrente</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome ti consiglia di reimpostare la password, se l'hai utilizzata su altri siti.</translation>
<translation id="5732392974455271431">I tuoi genitori possono sbloccarlo per te</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Salva la carta nel tuo Account Google}other{Salva carte nel tuo Account Google}}</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="5770114862687765385">Sembra che il file sia danneggiato. Fai clic sul pulsante "Ripristina" per ripristinare la sessione.</translation>
<translation id="5778550464785688721">Controllo completo di dispositivi MIDI</translation>
<translation id="578305955206182703">Ambra</translation>
<translation id="57838592816432529">Disattiva audio</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>
+<translation id="5798290721819630480">Vuoi annullare le modifiche?</translation>
<translation id="5798683403665926540">Cambia la pagina iniziale nelle impostazioni di Chrome</translation>
<translation id="5803412860119678065">Vuoi inserire automaticamente <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Autorizzazioni</translation>
<translation id="5810442152076338065">La connessione a <ph name="DOMAIN" /> è criptata tramite un pacchetto di crittografia obsoleto.</translation>
<translation id="5813119285467412249">&amp;Ripeti aggiunta</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="5860033963881614850">Off</translation>
<translation id="5863847714970149516">La pagina che segue potrebbe tentare di addebitarti dei costi</translation>
<translation id="5866257070973731571">Aggiungi numero di telefono</translation>
<translation id="5869405914158311789">Impossibile raggiungere il sito</translation>
<translation id="5869522115854928033">Password salvate</translation>
<translation id="5887400589839399685">Carta salvata</translation>
-<translation id="5893718151540690985">Comunica l'elenco di interfacce di rete con i relativi tipi e indirizzi hardware</translation>
<translation id="5893752035575986141">Le carte di credito sono accettate.</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="5916664084637901428">On</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vuoi salvare la carta nell'Account Google?</translation>
<translation id="5922853866070715753">Hai quasi finito.</translation>
<translation id="5932224571077948991">Il sito mostra annunci invasivi o fuorvianti</translation>
-<translation id="5939518447894949180">Reimposta</translation>
<translation id="5946937721014915347">Apertura di <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Impossibile effettuare la registrazione con l'account consumer (è disponibile la licenza inclusa).</translation>
<translation id="5967592137238574583">Modifica informazioni di contatto</translation>
@@ -789,6 +900,7 @@
<translation id="5975083100439434680">Diminuisci lo zoom</translation>
<translation id="5977489021191000276">Il tuo dispositivo non è gestito da un amministratore.</translation>
<translation id="5977976211062815271">Su questo dispositivo</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Impossibile aprire l'app per i pagamenti</translation>
<translation id="5989320800837274978">Non sono stati specificati né server proxy fissi né un URL script .pac.</translation>
<translation id="5990559369517809815">Le richieste al server sono state bloccate da un'estensione.</translation>
@@ -799,8 +911,8 @@
<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="6033927989869462158">Segnala statistiche hardware quali l'utilizzo di CPU/RAM</translation>
<translation id="6034000775414344507">Grigio chiaro</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Se il problema persiste, contatta il proprietario del sito.</translation>
<translation id="6040143037577758943">Chiudi</translation>
<translation id="6044573915096792553">Dimensione 12</translation>
@@ -809,10 +921,10 @@
<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="6058977677006700226">Utilizzare le carte su tutti i tuoi dispositivi?</translation>
<translation id="6059925163896151826">Dispositivi USB</translation>
-<translation id="6071091556643036997">Il tipo di norma non è valido.</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="6094273045989040137">Consente di inserire l'annotazione</translation>
<translation id="610911394827799129">Il tuo Account Google potrebbe avere altre forme di cronologia di navigazione all'indirizzo <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informazioni su estensioni e plug-in installati</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>
@@ -846,15 +958,21 @@
<translation id="6337133576188860026">Consente di liberare meno di <ph name="SIZE" />. Alcuni siti potrebbero caricarsi più lentamente alla prossima visita.</translation>
<translation id="6337534724793800597">Filtra i criteri per nome</translation>
<translation id="6358450015545214790">Che cosa significano?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Potrebbe essere applicato un addebito.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 altro suggerimento}other{# altri suggerimenti}}</translation>
<translation id="6387754724289022810">Per pagare più velocemente la prossima volta, salva la carta e l'indirizzo di fatturazione sul tuo Account Google e su questo dispositivo.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Modifica preferito</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Annulla</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Aggiungi altre informazioni</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">Conferma reinvio modulo</translation>
@@ -867,11 +985,17 @@
<translation id="6508722015517270189">Riavvia Chrome</translation>
<translation id="6529602333819889595">&amp;Ripeti eliminazione</translation>
<translation id="6534179046333460208">Suggerimenti relativi al Physical Web</translation>
+<translation id="6556866813142980365">Ripeti</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="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Rosa chiaro</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link copiato</translation>
+<translation id="6591833882275308647">Il tuo dispositivo <ph name="DEVICE_TYPE" /> non è gestito</translation>
<translation id="6596325263575161958">Opzioni di crittografia</translation>
<translation id="6604181099783169992">Sensori di movimento o della luce</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Informazioni di contatto</translation>
<translation id="6626291197371920147">Aggiungi un numero di carta valido</translation>
<translation id="6628463337424475685">Ricerca <ph name="ENGINE" /></translation>
@@ -880,6 +1004,7 @@
<translation id="6644283850729428850">Questa norma è obsoleta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nessuno}=1{Da 1 sito (non verrai disconnesso dal tuo Account Google)}other{Da # siti (non verrai disconnesso dal tuo Account Google)}}</translation>
<translation id="6657585470893396449">Password</translation>
+<translation id="6670613747977017428">Torna nell'area protetta.</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>
@@ -887,12 +1012,15 @@
<translation id="671076103358959139">Token di registrazione:</translation>
<translation id="6711464428925977395">Si è verificato un problema con il server proxy oppure l'indirizzo non è corretto.</translation>
<translation id="6723740634201835758">Nell'Account Google</translation>
+<translation id="6738516213925468394">I tuoi dati sono stati criptati con la tua <ph name="BEGIN_LINK" />passphrase di sincronizzazione<ph name="END_LINK" /> in data <ph name="TIME" />. Inseriscila per avviare la sincronizzazione.</translation>
<translation id="674375294223700098">Errore sconosciuto del certificato del server.</translation>
<translation id="6744009308914054259">In attesa di una connessione, puoi visitare la pagina Download per leggere gli articoli offline.</translation>
<translation id="6753269504797312559">Valore norma</translation>
<translation id="6757797048963528358">Il dispositivo è entrato in modalità sospensione.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Il tuo genitore non ha ancora approvato la richiesta</translation>
<translation id="67862343314499040">Lilla</translation>
+<translation id="6786747875388722282">Estensioni</translation>
<translation id="679355240208270552">Ignorato perché la ricerca predefinita non è attiva secondo la norma.</translation>
<translation id="681021252041861472">Campo obbligatorio</translation>
<translation id="6810899417690483278">ID personalizzazione</translation>
@@ -925,10 +1053,12 @@
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">District</translation>
<translation id="6973656660372572881">Sono stati specificati sia i server proxy fissi che un URL script .pac.</translation>
+<translation id="6973932557599545801">Mi spiace, non posso aiutarti. Continua autonomamente.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Disattivazione audio (impostazione predefinita)</translation>
<translation id="6984479912851154518">Per procedere al pagamento tramite un'applicazione esterna, uscirai dalla modalità di navigazione privata. Vuoi continuare?</translation>
<translation id="6989763994942163495">Mostra impostazioni avanzate...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Traduci sempre questa lingua: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">L'addebito potrebbe essere singolo oppure ricorrente e potrebbe non essere evidente.</translation>
@@ -944,28 +1074,36 @@
<translation id="7108338896283013870">Nascondi</translation>
<translation id="7108819624672055576">Consentita da un'estensione</translation>
<translation id="7111012039238467737">(Valido)</translation>
+<translation id="7118618213916969306">Cerca URL dagli appunti, <ph name="SHORT_URL" /></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="7135130955892390533">Mostra stato</translation>
<translation id="7138472120740807366">Metodo di consegna</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">URL non valido. Deve essere un URL con schema standard.</translation>
<translation id="717330890047184534">ID GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Il server a cui ti stai collegando, <ph name="ORIGIN" />, ha richiesto
+ l'applicazione di una norma di sicurezza per tutte le richieste. Ma anziché
+ pubblicare una norma ha reindirizzato il browser altrove, impedendo
+ così al browser di soddisfare la tua richiesta per il sito <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Salva e compila i metodi di pagamento</translation>
<translation id="7180611975245234373">Aggiorna</translation>
<translation id="7182878459783632708">Nessuna norma impostata</translation>
<translation id="7186367841673660872">Questa pagina è stata tradotta da<ph name="ORIGINAL_LANGUAGE" />a<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Consente di liberare <ph name="SIZE" />. Alcuni siti potrebbero caricarsi più lentamente alla prossima visita.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">L'amministratore è in grado di vedere:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> non è conforme agli standard di sicurezza.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /> su questo problema.</translation>
<translation id="7219179957768738017">La connessione utilizza <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Elaborazione in corso</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Il sito che stai per visitare contiene malware</translation>
+<translation id="724766306220616965">Avvisi, conflitto</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="7251437084390964440">La configurazione di rete non è conforme allo standard ONC. Parti della configurazione potrebbero non essere importate.
Ulteriori dettagli:
@@ -978,11 +1116,14 @@ Ulteriori dettagli:
<translation id="7300012071106347854">Blu cobalto</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Rapporto sugli arresti anomali generato <ph name="CRASH_TIME" /> (caricamento richiesto dall'utente, ma non ancora eseguito)</translation>
+<translation id="7313965965371928911">Avvisi di <ph name="BEGIN_LINK" />Navigazione sicura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Guida alla connessione</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Riga di comando</translation>
-<translation id="7365061714576910172">Esporta Linux</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>
@@ -990,6 +1131,7 @@ Ulteriori dettagli:
<translation id="7381288752349550461">Eseguire l'override della sessione gestita</translation>
<translation id="7390545607259442187">Conferma della carta</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Il tuo dispositivo <ph name="DEVICE_NAME" /> è gestito</translation>
<translation id="7407424307057130981">&lt;p&gt;Vedrai questo errore se sul tuo computer Windows è installato il software Superfish.&lt;/p&gt;
&lt;p&gt;Segui questi passaggi per disattivare temporaneamente il software in modo da riuscire a connetterti a Internet. Devi disporre dei privilegi di amministratore.&lt;/p&gt;
&lt;ol&gt;
@@ -1000,7 +1142,7 @@ Ulteriori dettagli:
&lt;li&gt;Fai clic su &lt;strong&gt;Applica&lt;/strong&gt;, quindi su &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Visita il &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centro assistenza Chrome&lt;/a&gt; per avere informazioni su come rimuovere definitivamente il software dal computer.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestione di <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Gestisci password…</translation>
<translation id="7419106976560586862">Percorso profilo</translation>
<translation id="7437289804838430631">Aggiungi informazioni di contatto</translation>
@@ -1009,22 +1151,24 @@ Ulteriori dettagli:
<translation id="7442725080345379071">Arancione chiaro</translation>
<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="7449109375006139765">Invia log di sistema al server di gestione</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="7460618730930299168">I contenuti mostrati sono diversi da quelli che hai selezionato. Continuare?</translation>
<translation id="7473891865547856676">No grazie</translation>
-<translation id="7475525192983021547">Segnala i periodi di attività di un utente sul dispositivo</translation>
<translation id="7481312909269577407">Avanti</translation>
<translation id="7485870689360869515">Nessun dato trovato.</translation>
+<translation id="7498234416455752244">Continua modifica</translation>
<translation id="7508255263130623398">L'ID dispositivo della norma restituito è vuoto o non corrisponde all'ID dispositivo corrente</translation>
<translation id="7508870219247277067">Verde pisello</translation>
<translation id="7511955381719512146">La rete Wi-Fi in uso potrebbe richiedere la visita della pagina <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Scarica</translation>
<translation id="7518003948725431193">Nessuna pagina web trovata per l'indirizzo web: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">La connessione a questo sito non è privata</translation>
+<translation id="7535087603100972091">Valore</translation>
<translation id="7537536606612762813">Obbligatoria</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1033,8 +1177,8 @@ Ulteriori dettagli:
<translation id="7552846755917812628">Prova i seguenti suggerimenti:</translation>
<translation id="7554791636758816595">Nuova scheda</translation>
<translation id="7564049878696755256">Potresti non riuscire più ad accedere al tuo account <ph name="ORG_NAME" /> o subire un furto d'identità. Chrome ti consiglia di cambiare subito la password.</translation>
-<translation id="7566125604157659769">Testo copiato</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="7568105740864181217">Il browser in uso è gestito da un'azienda, una scuola o un'altra organizzazione. L'amministratore può modificare da remoto la configurazione del browser. L'attività svolta su questo dispositivo potrebbe essere gestita anche al di fuori di Chrome. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></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>
@@ -1045,6 +1189,7 @@ Ulteriori dettagli:
<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="7633909222644580952">Dati sulle prestazioni e rapporti sugli arresti anomali</translation>
<translation id="7637571805876720304">Rimuovere la carta di credito da Chromium?</translation>
<translation id="7639968568612851608">Grigio scuro</translation>
<translation id="765676359832457558">Nascondi impostazioni avanzate...</translation>
@@ -1054,9 +1199,11 @@ Ulteriori dettagli:
<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="7676643023259824263">Cerca testo negli appunti, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Cambia motore di ricerca</translation>
<translation id="7682287625158474539">Spedizione</translation>
<translation id="7687186412095877299">Compila i moduli di pagamento con i metodi di pagamento salvati</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">Al momento hai carte che possono essere utilizzate solo su questo dispositivo. Fai clic su Continua per controllare le carte.</translation>
<translation id="7699293099605015246">Gli articoli non sono al momento disponibili</translation>
<translation id="7701040980221191251">Nessuno</translation>
@@ -1068,11 +1215,13 @@ Ulteriori dettagli:
<translation id="774634243536837715">Contenuti pericolosi bloccati.</translation>
<translation id="7752995774971033316">Non gestito</translation>
<translation id="7755287808199759310">Il tuo genitore può sbloccarlo per te</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Il software antivirus o il firewall potrebbe avere bloccato la connessione.</translation>
<translation id="7759163816903619567">Visualizza dominio:</translation>
<translation id="7761701407923456692">Il certificato del server non corrisponde all'URL.</translation>
<translation id="7763386264682878361">Analizzatore sintattico dei file manifest dei pagamenti</translation>
<translation id="7764225426217299476">Aggiungi indirizzo</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefettura</translation>
<translation id="7791543448312431591">Aggiungi</translation>
<translation id="7793809570500803535">La pagina web all'indirizzo <ph name="SITE" /> potrebbe non essere momentaneamente disponibile o potrebbe essere stata spostata definitivamente su un nuovo indirizzo web.</translation>
@@ -1084,8 +1233,8 @@ Ulteriori dettagli:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Rimuovere il suggerimento per i moduli da Chrome?</translation>
<translation id="7815407501681723534"><ph name="SEARCH_RESULTS" /> per "<ph name="SEARCH_STRING" />": <ph name="NUMBER_OF_RESULTS" /></translation>
-<translation id="7818867226424560206">Gestione norme</translation>
<translation id="782886543891417279">La rete Wi-Fi in uso (<ph name="WIFI_NAME" />) potrebbe richiedere la visita della relativa pagina di accesso.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nessuna}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Non sei completamente invisibile: se navighi in incognito, la tua navigazione non viene nascosta al tuo datore di lavoro, al provider di servizi Internet o ai siti web che visiti.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1094,7 +1243,7 @@ Ulteriori dettagli:
<translation id="7878562273885520351">La tua password potrebbe essere stata compromessa</translation>
<translation id="7882421473871500483">Marrone</translation>
<translation id="7887683347370398519">Controlla il tuo codice CVC e riprova</translation>
-<translation id="7893255318348328562">Nome sessione</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Inserisci un numero di telefono valido</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Scadenza: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1104,21 +1253,25 @@ Ulteriori dettagli:
<translation id="7951415247503192394">(a 32 bit)</translation>
<translation id="7956713633345437162">Preferiti su disp. mobili</translation>
<translation id="7961015016161918242">Mai</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Gestisci password</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Questa carta e il relativo indirizzo di fatturazione verranno salvati. Potrai usarla dopo aver eseguito l'accesso all'account <ph name="USER_EMAIL" />.}other{Queste carte e i relativi indirizzi di fatturazione verranno salvati. Potrai usarle dopo aver eseguito l'accesso all'account <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Questa pagina è in <ph name="SOURCE_LANGUAGE" />. Tradurla in <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Penna</translation>
+<translation id="8037117624646282037">Utenti che hanno usato il dispositivo di recente</translation>
<translation id="8037357227543935929">Chiedi (predefinita)</translation>
<translation id="803771048473350947">Archivio</translation>
<translation id="8041089156583427627">Invia feedback</translation>
<translation id="8041940743680923270">Usa predefinita globale (Chiedi)</translation>
<translation id="8042918947222776840">Scegli il metodo di ritiro</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" non è configurato correttamente. La disinstallazione di "<ph name="SOFTWARE_NAME" />" solitamente risolve il problema. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Sul tuo dispositivo sono state configurate le seguenti norme:</translation>
+<translation id="8066955247577885446">Si è verificato un problema.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Non è possibile inserire annotazioni se il documento è ruotato</translation>
<translation id="8079031581361219619">Vuoi ricaricare il sito?</translation>
<translation id="8088680233425245692">Impossibile visualizzare l'articolo.</translation>
@@ -1127,11 +1280,12 @@ Ulteriori dettagli:
<translation id="8091372947890762290">Attivazione in attesa sul server</translation>
<translation id="8092774999298748321">Viola scuro</translation>
<translation id="8094917007353911263">La rete in uso potrebbe richiedere la visita della pagina <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Le carte non valide sono state rimosse</translation>
<translation id="8103161714697287722">Metodo di pagamento</translation>
<translation id="8118489163946903409">Metodo di pagamento</translation>
+<translation id="8123836779274890062">Dispositivo <ph name="DEVICE_TYPE" /> gestito da <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" non è stato installato correttamente sul computer o sulla rete. Chiedi all'amministratore IT di risolvere il problema.</translation>
-<translation id="8130693978878176684">Non posso più aiutarti. Continua autonomamente.</translation>
<translation id="8131740175452115882">Conferma</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>
@@ -1141,8 +1295,11 @@ Ulteriori dettagli:
<translation id="8197543752516192074">Traduci la pagina</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="8202370299023114387">Conflitto</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">La connessione è protetta</translation>
<translation id="8218327578424803826">Posizione assegnata:</translation>
+<translation id="8220146938470311105">C7/C6 (Busta)</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="8238581221633243064">Apri la pagina in una nuova scheda di navigazione in incognito</translation>
@@ -1154,14 +1311,16 @@ Ulteriori dettagli:
<translation id="825929999321470778">Mostra tutte le password salvate</translation>
<translation id="8261506727792406068">Elimina</translation>
<translation id="8267698848189296333">Accesso come <ph name="USERNAME" /> in corso</translation>
+<translation id="8278457561961988242">Il browser in uso è gestito da <ph name="ENROLLMENT_DOMAIN" />. L'amministratore può modificare da remoto la configurazione del browser. L'attività svolta su questo dispositivo potrebbe essere gestita anche al di fuori di Chrome. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Accedi</translation>
<translation id="8288807391153049143">Mostra certificato</translation>
<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="8298115750975731693">La rete Wi-Fi in uso (<ph name="WIFI_NAME" />) potrebbe richiedere la visita della pagina <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">La traduzione non è riuscita a causa di un problema con la connessione di rete.</translation>
-<translation id="8311129316111205805">Carica sessione</translation>
<translation id="8332188693563227489">Accesso a <ph name="HOST_NAME" /> negato</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1179,7 +1338,6 @@ Ulteriori dettagli:
<translation id="8416694386774425977">La configurazione di rete non è valida e non può essere importata.
Ulteriori dettagli:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositivo gestito da <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Cambia</translation>
<translation id="8428213095426709021">Impostazioni</translation>
@@ -1206,9 +1364,11 @@ Ulteriori dettagli:
<translation id="860043288473659153">Nome del titolare della carta</translation>
<translation id="861775596732816396">Dimensione 4</translation>
<translation id="8620436878122366504">I tuoi genitori non hanno ancora approvato la richiesta</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Salva la carta su questo dispositivo</translation>
<translation id="8663226718884576429">Riepilogo ordine, <ph name="TOTAL_LABEL" />, altri dettagli</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, risposta, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">La connessione a <ph name="DOMAIN" /> non è criptata.</translation>
<translation id="8718314106902482036">Pagamento non completato</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, suggerimento di ricerca</translation>
@@ -1222,6 +1382,7 @@ Ulteriori dettagli:
<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="8763927697961133303">Dispositivo USB</translation>
<translation id="8768895707659403558">Per utilizzare le tue carte su tutti i tuoi dispositivi, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Ripeti eliminazione</translation>
<translation id="8792621596287649091">Potresti non riuscire più ad accedere al tuo account <ph name="ORG_NAME" /> o subire un furto d'identità. Chromium ti consiglia di cambiare subito la password.</translation>
<translation id="8800988563907321413">I suggerimenti Qui vicino vengono visualizzati qui</translation>
@@ -1232,10 +1393,12 @@ Ulteriori dettagli:
<translation id="885730110891505394">Condivisione con Google</translation>
<translation id="8858065207712248076">Chrome ti consiglia di reimpostare la password di <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, se l'hai utilizzata su altri siti.</translation>
<translation id="8866481888320382733">Errore durante l'analisi delle impostazioni criterio</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Chiusi di recente</translation>
<translation id="8874824191258364635">Inserisci un numero di carta di credito valido</translation>
<translation id="8891727572606052622">Modalità proxy non valida.</translation>
<translation id="8903921497873541725">Aumenta lo zoom</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Vuoi salvare la scheda nel tuo Account Google?</translation>
<translation id="8932102934695377596">L'orologio è indietro</translation>
<translation id="893332455753468063">Aggiungi nome</translation>
@@ -1243,13 +1406,13 @@ Ulteriori dettagli:
<translation id="894185898663964645">L'amministratore ha configurato certificati radice personalizzati, che potrebbero consentirgli di vedere i contenuti dei siti web che visiti.</translation>
<translation id="8943282376843390568">Giallo-verde</translation>
<translation id="8957210676456822347">Autorizzazione Captive Portal</translation>
+<translation id="8966619695390250636">Forse cercavi:</translation>
<translation id="8968766641738584599">Salva carta</translation>
<translation id="8971063699422889582">Il certificato del server è scaduto.</translation>
<translation id="8975012916872825179">Include informazioni come numeri di telefono, indirizzi email e indirizzi di spedizione</translation>
<translation id="8978053250194585037">La funzione Google Navigazione sicura <ph name="BEGIN_LINK" />ha rilevato di recente attività di phishing<ph name="END_LINK" /> sul sito <ph name="SITE" />. I siti di phishing si spacciano per altri siti web per ingannarti.</translation>
<translation id="8983003182662520383">Metodi di pagamento e indirizzi che utilizzano Google Pay</translation>
<translation id="8987927404178983737">Mese</translation>
-<translation id="8988408250700415532">Si è verificato un problema. Puoi completare l'ordine sul sito web.</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>
@@ -1259,6 +1422,7 @@ Ulteriori dettagli:
<translation id="9011424611726486705">Apri le impostazioni del sito</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Non valido)</translation>
<translation id="9035022520814077154">Errore di sicurezza</translation>
<translation id="9038649477754266430">Utilizza un servizio di previsione per velocizzare il caricamento delle pagine</translation>
@@ -1270,11 +1434,11 @@ Ulteriori dettagli:
<translation id="9065745800631924235">Ricerca di <ph name="TEXT" /> nella cronologia</translation>
<translation id="9069693763241529744">Bloccata da un'estensione</translation>
<translation id="9076283476770535406">Può includere contenuti per adulti</translation>
+<translation id="9076630408993835509">Questo browser non è gestito da un'azienda o da un'altra organizzazione. L'attività svolta su questo dispositivo potrebbe essere gestita al di fuori di Chrome. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Sono necessarie maggiori informazioni</translation>
<translation id="9080712759204168376">Riepilogo dell'ordine</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>
<translation id="9106062320799175032">Aggiungi indirizzo di fatturazione</translation>
-<translation id="9110718169272311511">L'Assistente Google in Chrome è disponibile nella parte inferiore dello schermo</translation>
<translation id="9114524666733003316">Conferma della carta...</translation>
<translation id="9128870381267983090">Collegati alla rete</translation>
<translation id="9137013805542155359">Mostra originale</translation>
@@ -1283,6 +1447,7 @@ Ulteriori dettagli:
<translation id="9148507642005240123">&amp;Annulla modifica</translation>
<translation id="9154194610265714752">Aggiornato</translation>
<translation id="9157595877708044936">Configurazione in corso...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Consenti ai siti di controllare se hai metodi di pagamento salvati</translation>
<translation id="9169664750068251925">Blocca sempre su questo sito</translation>
<translation id="9170848237812810038">&amp;Annulla</translation>
@@ -1297,10 +1462,12 @@ Ulteriori dettagli:
<translation id="9219103736887031265">Immagini</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CANCELLA MODULO</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Potresti non riuscire più ad accedere al tuo Account Google. Chromium consiglia di cambiare subito la password. Ti verrà chiesto di eseguire l'accesso.</translation>
<translation id="939736085109172342">Nuova cartella</translation>
<translation id="945855313015696284">Controlla le informazioni riportate di seguito ed elimina le schede non valide</translation>
<translation id="951104842009476243">Carte di debito e prepagate accettate</translation>
+<translation id="958202389743790697">Bloccato secondo la norma sulla sicurezza di <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Questi contenuti 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_LINK" />Mostra comunque<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Build ufficiale</translation>
<translation id="973773823069644502">Aggiungi l'indirizzo di consegna</translation>
@@ -1309,6 +1476,7 @@ Ulteriori dettagli:
<translation id="984275831282074731">Metodi di pagamento</translation>
<translation id="985199708454569384">&lt;p&gt;Vedrai questo errore se la data e l'ora del dispositivo mobile o del computer non sono esatte.&lt;/p&gt;
&lt;p&gt;Per risolvere il problema, apri l'orologio del dispositivo e assicurati che la data e l'ora siano corrette.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Build</translation>
<translation id="989988560359834682">Modifica indirizzo</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_iw.xtb b/chromium/components/strings/components_strings_iw.xtb
index f2f4fad703a..3af3d200ce2 100644
--- a/chromium/components/strings/components_strings_iw.xtb
+++ b/chromium/components/strings/components_strings_iw.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="iw">
-<translation id="1005145902654145231">שינוי השם של הסשן נכשל.</translation>
<translation id="1008557486741366299">לא עכשיו</translation>
<translation id="1010200102790553230">לטעינת הדף מאוחר יותר</translation>
<translation id="1015730422737071372">ספק פרטים נוספים</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">שם לא ידוע</translation>
<translation id="1050038467049342496">סגירת יישומים אחרים</translation>
<translation id="1055184225775184556">&amp;ביטול הוספה</translation>
+<translation id="1056898198331236512">אזהרה</translation>
<translation id="1058479211578257048">הכרטיסים נשמרים...</translation>
<translation id="10614374240317010">פריטים שאף פעם לא נשמרו</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)‎</translation>
<translation id="106701514854093668">סימניות שולחן עבודה</translation>
<translation id="1074497978438210769">לא מאובטח</translation>
<translation id="1080116354587839789">התאם לרוחב</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">הוספת השם שמופיע בכרטיס</translation>
<translation id="1089439967362294234">שינוי סיסמה</translation>
<translation id="109743633954054152">‏ניהול סיסמאות בהגדרות Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">לפעמים מופיעות אזהרות בזמן שאתרים מעדכנים את האבטחה שלהם. זה אמור להיפסק בקרוב.</translation>
<translation id="1126551341858583091">גודל האחסון המקומי הוא <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">המטמון של המדיניות תקין</translation>
+<translation id="1131264053432022307">תמונה שהעתקת</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> סגר את החיבור באופן בלתי צפוי.</translation>
<translation id="1161325031994447685">‏להתחבר מחדש אל ה-Wi-Fi</translation>
<translation id="1165039591588034296">שגיאה</translation>
-<translation id="1173894706177603556">שנה שם</translation>
<translation id="1175364870820465910">הדפסה…</translation>
<translation id="1181037720776840403">הסרה</translation>
<translation id="1197088940767939838">כתום</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">שם המכשיר שלך</translation>
<translation id="124116460088058876">שפות נוספות</translation>
<translation id="1250759482327835220">‏כדי לשלם מהר יותר בפעם הבאה, אפשר לשמור בחשבון Google את פרטי הכרטיס, השם והכתובת לחיוב.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (מסונכרנים)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">וריאציות של שורת פקודה</translation>
<translation id="129553762522093515">נסגרו לאחרונה</translation>
<translation id="129863573139666797">‏<ph name="BEGIN_LINK" />נסה לנקות את קובצי ה-Cookie<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">הסשן שנבחר לא קיים.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)‎</translation>
+<translation id="132301787627749051">חיפוש תמונה בלוח</translation>
<translation id="1323433172918577554">הצגת פריטים נוספים</translation>
<translation id="132390688737681464">שמירה ומילוי של כתובות</translation>
<translation id="1333989956347591814">הפעילות שלך <ph name="BEGIN_EMPHASIS" />עדיין עשויה להיות מוצגת<ph name="END_EMPHASIS" /> בפני:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">כתובת איסוף</translation>
<translation id="1348198688976932919">האתר הבא מכיל יישומים מסוכנים</translation>
<translation id="1348779747280417563">אישור השם</translation>
+<translation id="1357195169723583938">מי השתמש במכשיר לאחרונה ומתי</translation>
+<translation id="1364822246244961190">המדיניות הזו חסומה והמערכת תתעלם מהערך שלה.</translation>
<translation id="1374468813861204354">הצעות</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)‎</translation>
<translation id="1375198122581997741">מידע על הגרסה</translation>
<translation id="1376836354785490390">הצגת פחות פריטים</translation>
<translation id="1377321085342047638">מספר כרטיס</translation>
<translation id="138218114945450791">כחול בהיר</translation>
+<translation id="1382194467192730611">‏מנהל המערכת שלך אישר את התקן ה-USB</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> לא שלח נתונים.</translation>
+<translation id="140316286225361634">האתר <ph name="ORIGIN" /> ביקש שמדיניות אבטחה תחול על כל הבקשות שלו, והמדיניות הזו קובעת עכשיו שהאתר לא בטוח.</translation>
<translation id="1405567553485452995">ירוק בהיר</translation>
<translation id="1407135791313364759">פתח הכל</translation>
<translation id="1413809658975081374">שגיאת פרטיות</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">כן</translation>
<translation id="1430915738399379752">הדפסה</translation>
<translation id="1455413310270022028">כלי מחיקה</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">הצג יותר</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">בחירת כתובת למשלוח</translation>
+<translation id="1492194039220927094">דחיפת מדיניות:</translation>
<translation id="1501859676467574491">‏הצגת כרטיסים מחשבון Google שלך</translation>
-<translation id="1506687042165942984">הצג עותק שמור (כלומר, ידוע שהוא עדכני) של הדף הזה.</translation>
<translation id="1507202001669085618">‏&lt;p&gt;השגיאה הזו תוצג אם אתם משתמשים בפורטל Wi-Fi שבו צריך להיכנס לחשבון לפני התחברות לרשת.&lt;/p&gt;
&lt;p&gt;כדי לפתור את השגיאה, צריך ללחוץ על &lt;strong&gt;התחברות&lt;/strong&gt; בדף שמנסים לפתוח.&lt;/p&gt;</translation>
<translation id="1517433312004943670">יש צורך במספר טלפון</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">‏תאריך ה-Build</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">ממתין לחיבור...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)‎</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">הדף הזה אומר</translation>
<translation id="153384715582417236">זה הכול בינתיים</translation>
<translation id="154408704832528245">בחירת כתובת למסירה</translation>
<translation id="1549470594296187301">‏JavaScript צריך להיות מופעל כדי להשתמש בתכונה זו.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">יש להזין תאריך תפוגה</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">משהו השתבש בעת הצגת דף אינטרנט זה.</translation>
<translation id="1592005682883173041">גישה לנתונים מקומיים</translation>
<translation id="1594030484168838125">בחירה</translation>
<translation id="161042844686301425">ציאן</translation>
-<translation id="1618822247301510817">תמונה שהעתקת</translation>
<translation id="1620510694547887537">מצלמה</translation>
<translation id="1623104350909869708">מנע מהדף זה ליצור תיבות דו-שיח נוספות</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">סיום הסשן</translation>
<translation id="1639239467298939599">טוען</translation>
<translation id="1640180200866533862">מדיניות משתמשים</translation>
@@ -133,8 +148,10 @@
<translation id="1676269943528358898">‏האתר <ph name="SITE" /> משתמש בדרך כלל בהצפנה כדי להגן על המידע שלך. כאשר Google Chrome ניסה הפעם להתחבר ל-<ph name="SITE" />, האתר שלח חזרה אישורים חריגים ושגויים. ייתכן שתוקף מנסה להתחזות לאתר <ph name="SITE" />, או שמסך כניסה ל-Wi-Fi הפריע לחיבור. המידע שלך עדיין מאובטח מכיוון ש-Google Chrome הפסיק את החיבור לפני חילופי הנתונים.</translation>
<translation id="168841957122794586">אישור השרת מכיל מפתח הצפנה חלש.</translation>
<translation id="1697532407822776718">הכל מוכן!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">המסמך גדול מדי ולא ניתן להוסיף לו הערות</translation>
<translation id="1721312023322545264">עליך לפנות אל <ph name="NAME" /> לקבלת הרשאה לביקור באתר הזה</translation>
<translation id="1721424275792716183">* זהו שדה חובה</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">נסה לפנות אל מנהל המערכת.</translation>
<translation id="1740951997222943430">עליך להזין חודש תפוגה חוקי</translation>
<translation id="1743520634839655729">‏כדי לשלם מהר יותר בפעם הבאה, אפשר לשמור בחשבון Google ובמכשיר הזה את פרטי הכרטיס, השם והכתובת לחיוב.</translation>
+<translation id="1745880797583122200">הדפדפן שלך מנוהל</translation>
<translation id="17513872634828108">כרטיסיות פתוחות</translation>
<translation id="1753706481035618306">מספר דף</translation>
<translation id="1763864636252898013">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי מערכת ההפעלה של המכשיר. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">עדכן את משפט-הסיסמה של הסינכרון.</translation>
<translation id="1787142507584202372">כאן מופיעות הכרטיסיות שאתה פותח</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">שם בעל הכרטיס</translation>
<translation id="1821930232296380041">הבקשה או הפרמטרים של הבקשה אינם חוקיים</translation>
+<translation id="1822540298136254167">אתרים שנכנסת אליהם וזמני השהייה באתרים האלה</translation>
<translation id="1826516787628120939">מתבצעת בדיקה</translation>
<translation id="1834321415901700177">האתר הזה מכיל תוכניות מזיקות</translation>
<translation id="1839551713262164453">אימות ערכי המדיניות נכשל והתרחשו שגיאות</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">‏ניקוי נתוני היסטוריית הגלישה של Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ואפליקציה אחת נוספת}two{ושתי אפליקציות נוספות}many{ו-# אפליקציות נוספות}other{ו-# אפליקציות נוספות}}</translation>
<translation id="2003709556000175978">צריך לאפס את הסיסמה עכשיו</translation>
+<translation id="20053308747750172">השרת שאליו ביקשת לעבור, <ph name="ORIGIN" />, ביקש להחיל מדיניות אבטחה על כל הבקשות הנשלחות אליו. הוא סיפק עכשיו מדיניות לא חוקית, ולכן הדפדפן לא יכול למלא את הבקשה לעבור אל <ph name="SITE" />.</translation>
<translation id="2025186561304664664">‏שרת Proxy נקבע למוגדר אוטומטית.</translation>
<translation id="2030481566774242610">האם התכוונת ל-<ph name="LINK" />?</translation>
<translation id="2032962459168915086">‏<ph name="BEGIN_LINK" />לבדוק את שרת ה-Proxy ואת חומת האש<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">מחלקה</translation>
<translation id="2102134110707549001">הצעת סיסמה חזקה…</translation>
<translation id="2108755909498034140">אתחול המחשב</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">כרטיס</translation>
<translation id="2114841414352855701">המערכת התעלמה משום שהמדיניות בוטלה על ידי <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">סימניות לנייד</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">עריכת כרטיס</translation>
<translation id="2166049586286450108">גישה מלאה של מנהל המערכת</translation>
<translation id="2166378884831602661">אתר זה לא יכול לספק חיבור מאובטח</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)‎</translation>
<translation id="2181821976797666341">מדיניות</translation>
<translation id="2183608646556468874">מספר טלפון</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{כתובת אחת}two{שתי כתובות}many{# כתובות}other{# כתובות}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">מספר טלפון</translation>
<translation id="2283340219607151381">שמירה ומילוי של כתובות</translation>
<translation id="2292556288342944218">הגישה לאינטרנט חסומה</translation>
+<translation id="2294558542833290837">הקישור המקורי שפתחת חריג</translation>
+<translation id="2297722699537546652">B5 (Envelope)‎</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)‎</translation>
<translation id="2316887270356262533">‏פינוי של פחות מ-‎1 MB‎ מהשטח. ייתכן שחלק מהאתרים ייטענו לאט יותר בביקור הבא שלך.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> דורש שם משתמש וסיסמה.</translation>
<translation id="2317583587496011522">אפשר לשלם בכרטיסי חיוב.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, בתוקף עד <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">ההגדרה נשלטת על-ידי מנהל המערכת</translation>
+<translation id="2346319942568447007">תמונה שהעתקת</translation>
<translation id="2349790679044093737">‏יש עכשיו סשן VR פעיל</translation>
<translation id="2354001756790975382">סימניות אחרות</translation>
<translation id="2354430244986887761">‏התכונה 'גלישה בטוחה' של Google <ph name="BEGIN_LINK" />מצאה לאחרונה יישומים מזיקים<ph name="END_LINK" /> באתר <ph name="SITE" />.</translation>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">דוח הקריסה שתועד ב-<ph name="CRASH_TIME" /> לא הועלה</translation>
<translation id="2367567093518048410">רמה</translation>
<translation id="2378238891085281592">עברת למצב פרטי</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">ברירת מחדל של ארגון</translation>
<translation id="2386255080630008482">אישור השרת נשלל.</translation>
<translation id="2392959068659972793">הצגת מדיניות ללא ערך מוגדר</translation>
<translation id="239429038616798445">שיטת המשלוח הזו לא זמינה. עליך לבחור שיטה אחרת.</translation>
<translation id="2396249848217231973">&amp;ביטול מחיקה</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. ייתכן שאישור האבטחה שלו בוטל. הסיבה לכך עשויה להיות הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
+<translation id="2418081434543109369">השרת שאליו ביקשת לעבור, <ph name="ORIGIN" />, ביקש להחיל מדיניות אבטחה על כל הבקשות הנשלחות אליו. עם זאת, עכשיו הוא לא הצליח לספק מדיניות, ומצב זה מונע מהדפדפן למלא את הבקשה לעבור אל <ph name="SITE" />.</translation>
<translation id="244665789865330679">המכשיר והחשבון מנוהלים על-ידי <ph name="ENROLLMENT_DOMAIN" />. המשמעות היא שמנהל המערכת יכול להגדיר מרחוק את תצורת המכשיר והחשבון.</translation>
<translation id="2463193859425327265">שינוי דף הבית</translation>
<translation id="2463739503403862330">מלא</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">בחירת שיטת מסירה</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />מפעיל את אבחון הרשת<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">תרגם את הדף הזה</translation>
<translation id="2479410451996844060">כתובת אתר לא חוקית של חיפוש</translation>
<translation id="2482878487686419369">התראות</translation>
<translation id="248348093745724435">מדיניות המחשב</translation>
+<translation id="2485387744899240041">שמות משתמש למכשיר ולדפדפן שלך</translation>
<translation id="2491120439723279231">אישור השרת מכיל שגיאות.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">‏מנתח JSON</translation>
<translation id="2495093607237746763">‏אם האפשרות תסומן, Chromium ישמור עותק של הכרטיס במכשיר הזה כדי למלא טפסים במהירות רבה יותר.</translation>
<translation id="2498091847651709837">סריקת כרטיס חדש</translation>
<translation id="2501278716633472235">חזרה</translation>
<translation id="2503184589641749290">כרטיסי חיוב וכרטיסים משולמים מראש שהסוחר מקבל</translation>
<translation id="2515629240566999685">לבדוק את האות באזור שלך</translation>
-<translation id="2516852381693169964">חיפוש תמונה ב-<ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">הכרטיס יישמר רק במכשיר הזה</translation>
<translation id="2524461107774643265">הוספת עוד מידע</translation>
<translation id="2536110899380797252">הוספת כתובת</translation>
@@ -273,6 +305,7 @@
<translation id="2587841377698384444">‏מזהה ממשק API של ספרייה:</translation>
<translation id="2597378329261239068">מסמך זה מוגן באמצעות סיסמה. הזן סיסמה.</translation>
<translation id="2609632851001447353">וריאציות</translation>
+<translation id="2618023639789766142">C10 (Envelope)‎</translation>
<translation id="2625385379895617796">השעון שלך מקדים</translation>
<translation id="2634124572758952069">‏לא ניתן היה למצוא את כתובת ה-IP של השרת של <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">סטטוס:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">סגירת כרטיסיות או יישומים אחרים</translation>
<translation id="267371737713284912">הקשה על <ph name="MODIFIER_KEY_DESCRIPTION" /> מבטלת את הפעולה</translation>
<translation id="2674170444375937751">האם אתה בטוח שברצונך להסיר דפים אלו מההיסטוריה שלך?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">יציאה</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">כרטיסים שהסוחר מקבל</translation>
<translation id="2702801445560668637">רשימת קריאה</translation>
<translation id="2704283930420550640">הערך לא תואם לפורמט.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">הסר פריטים שנבחרו</translation>
<translation id="277133753123645258">שיטת משלוח</translation>
<translation id="277499241957683684">חסרה רשומת מכשיר</translation>
-<translation id="2781030394888168909">‏ייצוא בפורמט ל-MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">החיבור עבר איפוס.</translation>
<translation id="2788784517760473862">כרטיסי אשראי שהסוחר מקבל</translation>
@@ -311,8 +345,10 @@
<translation id="2826760142808435982">החיבור מוצפן ומאומת באמצעות <ph name="CIPHER" /> ומשתמש ב-<ph name="KX" /> כמנגנון להחלפת מפתחות.</translation>
<translation id="2835170189407361413">ניקוי הטופס</translation>
<translation id="2847118875340931228">פתיחת חלון גלישה בסתר</translation>
+<translation id="2850739647070081192">Invite (Envelope)‎</translation>
<translation id="2851634818064021665">יש צורך בהרשאה כדי להיכנס אל האתר הזה</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">לשמור את הכרטיס?</translation>
<translation id="2903493209154104877">כתובות</translation>
<translation id="290376772003165898">הדף לא ב<ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">שיטת משלוח</translation>
<translation id="2928905813689894207">כתובת לחיוב</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו הוא מ-<ph name="DOMAIN2" />. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="2948083400971632585">‏ניתן להשבית כל שרת proxy המוגדר לחיבור מדף ההגדרות.</translation>
<translation id="2955913368246107853">סגור את חלונית החיפוש</translation>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (Envelope)‎</translation>
<translation id="3024663005179499861">סוג המדיניות שגוי</translation>
<translation id="3037605927509011580">אוי, לא!</translation>
<translation id="3041612393474885105">פרטי אישור</translation>
+<translation id="3060227939791841287">C9 (Envelope)‎</translation>
<translation id="3064966200440839136">בחרת לצאת ממצב גלישה בסתר כדי לשלם באמצעות יישום חיצוני. להמשיך?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ללא}=1{סיסמה אחת}two{שתי סיסמאות}many{# סיסמאות}other{# סיסמאות}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">הוספת כתובת לאיסוף</translation>
<translation id="3105172416063519923">מזהה נכס:</translation>
<translation id="3109728660330352905">אין לך הרשאה לצפות בדף הזה.</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> בשרת <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">בטל תשלום</translation>
<translation id="3207960819495026254">מסומן בסימניה</translation>
-<translation id="3209375525920864198">יש להזין שם הפעלה חוקי.</translation>
+<translation id="321912867715453276">אזהרה: במדיניות הזו קיים יותר ממקור אחד, אבל הערכים זהים.</translation>
<translation id="3225919329040284222">השרת הציג אישור שאינו תואם את הציפיות המובנות. ציפיות אלה נכללות עבור אתרי אינטרנט מסוימים בעלי אבטחה גבוהה כדי להגן עליך.</translation>
<translation id="3226128629678568754">לחץ על לחצן הטעינה מחדש כדי לשלוח מחדש את הנתונים הדרושים לטעינת הדף.</translation>
<translation id="3227137524299004712">מיקרופון</translation>
<translation id="3228969707346345236">התרגום נכשל כיוון שהדף כבר ב<ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">פרטי גרסה של המכשיר והדפדפן</translation>
<translation id="323107829343500871">הזן את קוד האימות של הכרטיס <ph name="CREDIT_CARD" /></translation>
<translation id="3234666976984236645">זהה תמיד תוכן חשוב באתר זה</translation>
<translation id="3254409185687681395">הוסף את הדף לסימניות</translation>
<translation id="3270847123878663523">&amp;ביטול של שינוי סדר</translation>
+<translation id="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">הוספה של השם המופיע בכרטיס</translation>
<translation id="3287510313208355388">להורדה אחרי התחברות לרשת</translation>
<translation id="3293642807462928945">מידע נוסף על המדיניות <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">לא נמצאו תוצאות חיפוש</translation>
-<translation id="3305707030755673451">הנתונים שלך הוצפנו ב-<ph name="TIME" /> באמצעות ביטוי הסיסמה לסינכרון. הזן אותו כדי להתחיל בסינכרון.</translation>
<translation id="3320021301628644560">הוספה של כתובת לחיוב</translation>
<translation id="3324983252691184275">ארגמן</translation>
<translation id="3338095232262050444">מאובטח</translation>
@@ -405,9 +446,11 @@
<translation id="3427342743765426898">&amp;ביצוע מחדש של עריכה</translation>
<translation id="342781501876943858">‏אם הזנת את הסיסמה שלך באתרים אחרים, ההמלצה של Chromium היא לאפס אותה.</translation>
<translation id="3431636764301398940">שמור כרטיס זה במכשיר הנוכחי</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">הבעלים של המכשיר הזה כיבה את משחק הדינוזאורים.</translation>
<translation id="3447884698081792621">הצגת אישור (נופק על-ידי <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">מרווח אחזור:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)‎</translation>
<translation id="3461824795358126837">כלי הדגשה</translation>
<translation id="3462200631372590220">הסתר פרטים מתקדמים</translation>
<translation id="3467763166455606212">עליך לציין את שם בעל הכרטיס</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">אפשר לשלם באמצעות כרטיסי אשראי וכרטיסים משולמים מראש.</translation>
<translation id="3582930987043644930">הוסף שם</translation>
<translation id="3583757800736429874">&amp;ביצוע מחדש של העברה</translation>
+<translation id="35866233670761917">התוכן של אתרים שביקרת בהם לא גלוי למנהלי המערכת שלך</translation>
<translation id="3586931643579894722">הסתר פרטים</translation>
+<translation id="3592413004129370115">Italian (Envelope)‎</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">גודל 2</translation>
<translation id="3615877443314183785">עליך להזין תאריך תפוגה חוקי</translation>
<translation id="36224234498066874">ניקוי נתוני גלישה…</translation>
<translation id="362276910939193118">כל ההיסטוריה</translation>
-<translation id="3623476034248543066">הצג ערך</translation>
<translation id="3630155396527302611">אם היא כבר רשומה כתוכנית המורשית לגשת לרשת, נסה
להסיר אותה מהרשימה ולהוסיף אותה שוב.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">האימות בוצע בהצלחה</translation>
<translation id="3655670868607891010">אם נתקלת בזה לעתים קרובות, כדאי לנסות את ה<ph name="HELP_LINK" /> האלה.</translation>
<translation id="3658742229777143148">גרסה קודמת</translation>
<translation id="366077651725703012">עדכון כרטיס אשראי</translation>
<translation id="3676592649209844519">מזהה מכשיר:</translation>
+<translation id="3677008721441257057">‏התכוונת לכתובת &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">לא ניתן היה לחתום על הבקשה</translation>
<translation id="3678529606614285348">‏פתח את הדף בחלון חדש של גלישה בסתר (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">דוח קריסה תועד ב-<ph name="CRASH_TIME" />, הועלה ב-<ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +497,14 @@
<translation id="3704162925118123524">ייתכן שתוצג דרישה להיכנס לדף ההתחברות של הרשת שבה אתה משתמש.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">טוען...</translation>
+<translation id="3709599264800900598">טקסט שהעתקת</translation>
<translation id="3712624925041724820">אין מספיק רישיונות</translation>
<translation id="3714780639079136834">‏להפעיל נתונים לנייד או את ה-Wi-Fi</translation>
<translation id="3715597595485130451">‏התחברות ל-Wi-Fi</translation>
<translation id="3717027428350673159">‏<ph name="BEGIN_LINK" />לבדוק את תצורת ה-DNS, חומת האש ושרת ה-Proxy<ph name="END_LINK" /></translation>
<translation id="372429172604983730">‏יישומים שיכולים לגרום לשגיאה הזו כוללים תוכנות אנטי-וירוס, חומות אש ותוכנות proxy או סינון אינטרנט.</translation>
+<translation id="373042150751172459">B4 (Envelope)‎</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="3745099705178523657">‏אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון Google.</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>
@@ -470,10 +517,12 @@
<translation id="3783418713923659662">מאסטרקארד</translation>
<translation id="3787705759683870569">תאריך תפוגה: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">גודל 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)‎</translation>
<translation id="3807873520724684969">תוכן מזיק נחסם.</translation>
<translation id="3810973564298564668">נהל</translation>
<translation id="382518646247711829">‏אם אתה משתמש בשרת Proxy...</translation>
<translation id="3828924085048779000">אין אפשרות להשתמש במשפט-סיסמה ריק.</translation>
+<translation id="3831915413245941253">הותקנו תוספים מהדומיין <ph name="ENROLLMENT_DOMAIN" /> כדי להשתמש בפונקציות נוספות. לתוספים יש גישה לחלק מהנתונים שלך.</translation>
<translation id="385051799172605136">חזרה</translation>
<translation id="3858027520442213535">עדכן את התאריך והשעה</translation>
<translation id="3884278016824448484">מזהה מכשיר מתנגש</translation>
@@ -481,6 +530,7 @@
<translation id="3886446263141354045">הבקשה שלך לגשת לאתר הזה נשלחה אל <ph name="NAME" /></translation>
<translation id="3890664840433101773">הוספת כתובת אימייל</translation>
<translation id="3901925938762663762">תוקף הכרטיס פג</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">שאל תמיד באתר הזה</translation>
<translation id="3949571496842715403">‏השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו לא מציין ערכי Subject Alternative Name. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
@@ -491,11 +541,13 @@
<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="3984550557525787191">שם הסשן כבר קיים.</translation>
<translation id="3987940399970879459">‏פחות מ-‎1 MB</translation>
+<translation id="4008849406247176967">אזהרה: קיים יותר ממקור אחד עם ערכים סותרים עבור המדיניות הזו!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{דף אינטרנט קרוב אחד}two{# דפי אינטרנט קרובים}many{# דפי אינטרנט קרובים}other{# דפי אינטרנט קרובים}}</translation>
<translation id="4030383055268325496">&amp;ביטול הוספה</translation>
+<translation id="4032320456957708163">הדפדפן שלך מנוהל על ידי <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">מפתח "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)‎</translation>
<translation id="4067947977115446013">הוספה של כתובת חוקית</translation>
<translation id="4072486802667267160">התרחשה שגיאה במהלך עיבוד התשלום שלך. נסה שוב.</translation>
<translation id="4075732493274867456">‏הלקוח והשרת אינם תומכים בגרסה נפוצה של פרוטוקול SSL או בחבילת צפנים.</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">סגול</translation>
<translation id="4165986682804962316">הגדרות אתרים</translation>
<translation id="4171400957073367226">חתימת אימות לא חוקית</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{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="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ביצוע מחדש של העברה</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />לבדוק את תצורת האנטי-וירוס וחומת האש<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)‎</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="4221630205957821124">‏&lt;h4&gt;שלב ראשון: כניסה לפורטל&lt;/h4&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">איפוס סיסמה</translation>
<translation id="4280429058323657511">, בתוקף עד <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{‏הכרטיס הזה נשמר בחשבון Google שלך}two{‏הכרטיסים האלה נשמרו בחשבון Google שלך}many{‏הכרטיסים האלה נשמרו בחשבון Google שלך}other{‏הכרטיסים האלה נשמרו בחשבון Google שלך}}</translation>
+<translation id="42981349822642051">הרחבה</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)‎</translation>
<translation id="4305817255990598646">מעבר</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">חסום (ברירת מחדל)</translation>
+<translation id="4318566738941496689">שם המכשיר וכתובת הרשת שלך</translation>
<translation id="4325863107915753736">לא ניתן היה למצוא את הפריט</translation>
<translation id="4326324639298822553">בדוק את תאריך התפוגה ונסה שוב</translation>
<translation id="4331708818696583467">לא מאובטח</translation>
<translation id="4340982228985273705">‏המחשב לא זוהה כמכשיר המנוהל על ידי הארגון, כך שלפי המדיניות מותר להתקין אוטומטית רק תוספים מחנות האינטרנט של Chrome. כתובת האתר לעדכונים מחנות האינטרנט של Chrome היא "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">כרטיסי אשראי שהסוחר מקבל</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">תוקפים באתר הזה עשויים לנסות להתקין במחשב שלך תוכניות מסוכנות שגונבות או מוחקות מידע שלך (לדוגמה: תמונות, סיסמאות, הודעות ופרטי כרטיסי אשראי).</translation>
<translation id="4358461427845829800">ניהול אמצעי תשלום...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)‎</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">צפוי ערך מסוג <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">ניסית להשיג את <ph name="DOMAIN" />, אך האישור שהשרת הציג בוטל על ידי המנפיק שלו. פירוש הדבר שאין כל אפשרות לתת אמון באישורי האבטחה שהשרת הציג. ייתכן שאתה מתקשר עם תוקף.</translation>
<translation id="4378154925671717803">טלפון</translation>
<translation id="4406896451731180161">תוצאות חיפוש</translation>
-<translation id="4406972042435603828">מנהלי המערכת התקינו אפליקציות עם יכולות נרחבות.</translation>
<translation id="4408413947728134509">‏קובצי Cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">כתובת איסוף</translation>
<translation id="4424024547088906515">‏השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. אישור האבטחה שלו לא נחשב כמהימן על ידי Chrome. ייתכן שהסיבה לכך היא תצורה שגויה או תוקף המיירט את החיבור שלך.</translation>
+<translation id="443121186588148776">יציאה טורית</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> לא אישר את אישור ההתחברות שלך, או שלא סופק אישור התחברות.</translation>
<translation id="4434045419905280838">חלונות קופצים והפניות אוטומטיות</translation>
+<translation id="4435702339979719576">Postcard)‎</translation>
<translation id="443673843213245140">‏השימוש בשרת Proxy הושבת, אך צויינה תצורת שרת Proxy מפורשת.</translation>
<translation id="445100540951337728">כרטיסי חיוב שהסוחר מקבל</translation>
+<translation id="4466881336512663640">השינויים בטופס יתבטלו. להמשיך?</translation>
<translation id="4482953324121162758">האתר הזה לא יתורגם.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">‏כתובת URL לא חוקית. הסכימה של כתובת ה-URL צריכה להיות רגילה, כלומר: http://example.com או https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">שגיאת אימות: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">לפנות אל מנהל המערכת</translation>
<translation id="450710068430902550">שיתוף עם מנהל מערכת</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)‎</translation>
<translation id="4515275063822566619">‏הכרטיסים והכתובות לקוחים מ-Chrome ומחשבון Google שלך (<ph name="ACCOUNT_EMAIL" />). אפשר לנהל אותם ב<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)‎</translation>
<translation id="4522570452068850558">פרטים</translation>
<translation id="4524805452350978254">ניהול כרטיסים</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">נסה להשבית את התוספים.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">משלוח</translation>
+<translation id="4579056131138995126">Personal (Envelope)‎</translation>
<translation id="4582204425268416675">הסרת הכרטיס</translation>
<translation id="4587425331216688090">‏האם להסיר את הכתובת מ-Chrome?</translation>
<translation id="4592951414987517459">החיבור שלך אל <ph name="DOMAIN" /> מוצפן באמצעות חבילת צופן מתקדמת.</translation>
<translation id="4594403342090139922">&amp;ביטול מחיקה</translation>
<translation id="4597348597567598915">גודל 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)‎</translation>
<translation id="4646534391647090355">אני רוצה לעבור לשם עכשיו</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו מכיל שגיאות. ייתכן שהסיבה לכך היא הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
<translation id="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">הפסק להשתמש באישור לא חוקי</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)‎</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">החיבור נקטע</translation>
<translation id="471880041731876836">אין לך הרשאה להיכנס אל האתר הזה</translation>
<translation id="4722547256916164131">‏<ph name="BEGIN_LINK" />מפעיל את אבחון הרשת של Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">טען מדיניות מחדש</translation>
<translation id="4728558894243024398">פלטפורמה</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)‎</translation>
<translation id="4736825316280949806">‏אתחול ה-Chromium</translation>
<translation id="473775607612524610">עדכן</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> – הצעת חיפוש</translation>
<translation id="4742407542027196863">ניהול סיסמאות…</translation>
<translation id="4744603770635761495">נתיב להפעלה</translation>
+<translation id="4746351372139058112">הודעות</translation>
<translation id="4750917950439032686">הפרטים שלך (כמו סיסמאות או מספרי כרטיסי אשראי) נשלחים לאתר הזה במצב פרטי.</translation>
<translation id="4756388243121344051">&amp;היסטוריה</translation>
<translation id="4758311279753947758">הוסף פרטים ליצירת קשר</translation>
@@ -613,9 +688,9 @@
1240185477879256427אתר
Del</translation>
<translation id="4785689107224900852">החלפה לכרטיסייה זו</translation>
-<translation id="4792143361752574037">הייתה בעיה בגישה אל קובצי ההפעלה. שמירה בדיסק מושבתת עכשיו. יש לטעון מחדש את הדף כדי לנסות שוב.</translation>
<translation id="4798078619018708837">‏כדי לעדכן את פרטי הכרטיס, יש להזין את תאריך התפוגה וקוד האימות של <ph name="CREDIT_CARD" />. אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון Google.</translation>
<translation id="4800132727771399293">‏בדוק את תאריך התפוגה ואת ה-CVC ונסה שוב</translation>
+<translation id="480334179571489655">שגיאת מדיניות מקור</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>
@@ -630,7 +705,6 @@ Del</translation>
<translation id="4881695831933465202">פתיחה</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>
@@ -639,15 +713,15 @@ Del</translation>
<translation id="4943872375798546930">אין תוצאות</translation>
<translation id="4950898438188848926">‏לחצן החלפת כרטיסיות, יש להקיש על Enter כדי לעבור לכרטיסייה הפתוחה, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">פעולות</translation>
-<translation id="495832697253704892">דיווח תוספים</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">הרחב רשימה</translation>
<translation id="4974590756084640048">הפעל מחדש אזהרות</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)‎</translation>
<translation id="4989163558385430922">אני רוצה לראות הכול</translation>
<translation id="4989809363548539747">הפלאגין הזה אינו נתמך</translation>
-<translation id="4996230189582812866">דיווח</translation>
<translation id="5002932099480077015">‏אם האפשרות הזו תופעל, Chrome יאחסן עותק של הכרטיס שלך במכשיר הזה למילוי מהיר יותר של טפסים.</translation>
-<translation id="5014174725590676422">‏מוצג מסך ההפעלה הראשונה של Google Assistant ב-Chrome</translation>
<translation id="5015510746216210676">שם המחשב:</translation>
+<translation id="5017554619425969104">טקסט שהעתקת</translation>
<translation id="5018422839182700155">לא ניתן לפתוח את הדף</translation>
<translation id="5019198164206649151">האחסון המשמש כגיבוי אינו תקין</translation>
<translation id="5023310440958281426">בדוק את תקנון מנהל המערכת שלך</translation>
@@ -657,35 +731,51 @@ Del</translation>
<translation id="5034369478845443529">הקשר מקומי <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">זה בסדר</translation>
<translation id="5040262127954254034">פרטיות</translation>
+<translation id="5043480802608081735">קישור שהעתקת</translation>
<translation id="5045550434625856497">סיסמה שגויה</translation>
<translation id="5056549851600133418">מאמרים שעשויים לעניין אותך</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645">‏<ph name="BEGIN_LINK" />לבדוק את כתובת שרת ה-Proxy<ph name="END_LINK" /></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="5097099694988056070">‏נתונים סטטיסטיים של המכשיר, כמו ניצול יחידת העיבוד המרכזית (CPU)/זיכרון RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">המכשיר מנוהל על-ידי <ph name="ENROLLMENT_DOMAIN" /> והחשבון מנוהל על-ידי <ph name="ACCOUNT_DOMAIN" />. המשמעות היא שמנהלי המערכות יכולים להגדיר מרחוק את תצורת המכשיר והחשבון.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 סיביות)</translation>
-<translation id="5128122789703661928">שם ההפעלה למחיקה אינו חוקי.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">ניהול כתובות...</translation>
+<translation id="5138227688689900538">פחות אפליקציות</translation>
<translation id="5141240743006678641">‏הצפנת סיסמאות מסונכרנות באמצעות פרטי הכניסה שלך ל-Google</translation>
<translation id="5145883236150621069">קיים קוד שגיאה בתגובת המדיניות</translation>
+<translation id="515292512908731282">C4 (Envelope)‎</translation>
<translation id="5159010409087891077">‏פתח את הדף בחלון חדש של גלישה בסתר (‎⇧⌘N)</translation>
<translation id="516920405563544094">‏יש להזין את קוד האימות של <ph name="CREDIT_CARD" />. אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון Google.</translation>
<translation id="5169827969064885044">‏ייתכן שלא יתאפשר לך לגשת לחשבון הארגוני, והזהות שלך עלולה להיגנב. לגלישה בטוחה ב-Chrome, מומלץ לשנות את הסיסמה עכשיו.</translation>
<translation id="5171045022955879922">טקסט או כתובת אתר לחיפוש</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">מכונה</translation>
<translation id="5179510805599951267">לא ב<ph name="ORIGINAL_LANGUAGE" />? דיווח על שגיאה זו</translation>
<translation id="5190835502935405962">סרגל הסימניות</translation>
-<translation id="5200263511887412697">הצגת רשימה של משתמשי המכשיר שהתחברו לאחרונה</translation>
+<translation id="519422657042045905">ההערה לא זמינה</translation>
<translation id="5201306358585911203">דף מוטמע בדף הזה אומר</translation>
<translation id="5205222826937269299">שם (חובה)</translation>
<translation id="5215116848420601511">‏אמצעי תשלום וכתובות שנשמרו ב-Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">אימייל (חובה)</translation>
<translation id="5230733896359313003">כתובת למשלוח</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"יש להתחבר לרשת"</translation>
<translation id="5251803541071282808">ענן</translation>
+<translation id="5252000469029418751">C7 (Envelope)‎</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">כתובות רשת</translation>
<translation id="5285570108065881030">הצגת כל הסיסמאות השמורות</translation>
<translation id="5287240709317226393">‏הצגת קובצי Cookie</translation>
<translation id="5288108484102287882">בעקבות אימות ערכי המדיניות הופיעו אזהרות</translation>
@@ -697,7 +787,9 @@ Del</translation>
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> מתוך <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">בחירת פרטי איש קשר</translation>
<translation id="5327248766486351172">שם</translation>
+<translation id="5329858041417644019">הדפדפן שלך לא מנוהל</translation>
<translation id="5332219387342487447">שיטת משלוח</translation>
+<translation id="5334013548165032829">יומני מערכת מפורטים</translation>
<translation id="5344579389779391559">ייתכן שהדף הזה ינסה לדרוש ממך תשלום</translation>
<translation id="5355557959165512791">נכון לעכשיו אי אפשר לבקר באתר <ph name="SITE" /> מאחר שהאישור שלו בוטל. שגיאות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף הזה יחזור כנראה לפעול מאוחר יותר.</translation>
<translation id="536296301121032821">אחסון הגדרות המדיניות נכשל</translation>
@@ -705,6 +797,7 @@ Del</translation>
<translation id="5377026284221673050">‏"השעון מאחר", "השעון מקדים" או "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">כדי להשתמש בכרטיסים שלך בכל המכשירים, יש להיכנס לחשבון ולהפעיל את הסנכרון</translation>
<translation id="5386426401304769735">‏שרשרת האישורים של האתר הזה כוללת אישור שנחתם באמצעות SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">שרת זה לא הצליח להוכיח שהוא <ph name="DOMAIN" />; אישור האבטחה שלו אינו תקף כעת. הסיבה לכך עשויה להיות תצורה שגויה או שתוקף מיירט את החיבור שלך.</translation>
<translation id="5421136146218899937">ניקוי נתוני גלישה...</translation>
<translation id="5430298929874300616">הסר סימניה</translation>
@@ -715,6 +808,7 @@ Del</translation>
<translation id="5457113250005438886">לא חוקי</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;ביצוע מחדש של עריכה</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)‎</translation>
<translation id="5481076368049295676">ייתכן שהתוכן הזה מכיל אמצעים שינסו להתקין תוכנה מסוכנת, שגונבת או מוחקת את המידע שלך. <ph name="BEGIN_LINK" />הצג בכל זאת<ph name="END_LINK" /></translation>
<translation id="54817484435770891">הוספה של כתובת חוקית</translation>
<translation id="5490432419156082418">כתובות ועוד</translation>
@@ -723,10 +817,12 @@ Del</translation>
<ph name="LINE_BREAK" />
נסה ליצור קשר עם מנהל המערכת.</translation>
<translation id="549333378215107354">גודל 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">סימניות מנוהלות</translation>
<translation id="5510766032865166053">ייתכן שהוא הועבר או נמחק.</translation>
<translation id="5523118979700054094">שם מדיניות</translation>
<translation id="552553974213252141">האם הטקסט נשלף כראוי?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)‎</translation>
<translation id="5540224163453853">לא ניתן היה למצוא את הפריט המבוקש.</translation>
<translation id="5541546772353173584">הוספת כתובת אימייל</translation>
<translation id="5545756402275714221">מאמרים שעשויים לעניין אותך</translation>
@@ -741,15 +837,21 @@ Del</translation>
<translation id="5595485650161345191">עריכת כתובת</translation>
<translation id="5598944008576757369">בחירת אמצעי תשלום</translation>
<translation id="560412284261940334">ניהול אינו נתמך</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">לבדוק את החיבור</translation>
<translation id="5610807607761827392">ב<ph name="BEGIN_LINK" />הגדרות<ph name="END_LINK" /> תוכל לנהל את האפשרויות של כרטיסים וכתובות.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> הפנה אותך מחדש פעמים רבות מדי.</translation>
<translation id="5629630648637658800">טעינת הגדרות המדיניות נכשלה</translation>
<translation id="5631439013527180824">אסימון ניהול המכשיר אינו חוקי</translation>
+<translation id="5632627355679805402">‏החל מ-<ph name="TIME" /> הנתונים שלך מוצפנים בעזרת <ph name="BEGIN_LINK" />הסיסמה שלך ל-Google<ph name="END_LINK" />. יש להזין את הסיסמה כדי להתחיל את הסנכרון.</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="563324245173044180">תוכן מטעה נחסם</translation>
<translation id="5659593005791499971">אימייל</translation>
+<translation id="5663614846592581799">9x11 (Envelope)‎</translation>
+<translation id="5663955426505430495">מנהל המערכת של המכשיר הזה התקין תוספים שמאפשרים להשתמש בפונקציות נוספות. לתוספים יש גישה לחלק מהנתונים שלך.</translation>
<translation id="5675650730144413517">הדף הזה לא עובד</translation>
+<translation id="5684874026226664614">אופס. לא ניתן היה לתרגם את הדף הזה.</translation>
<translation id="5685654322157854305">הוספת כתובת למשלוח</translation>
<translation id="5689199277474810259">‏ייצוא אל JSON</translation>
<translation id="5689516760719285838">מיקום</translation>
@@ -758,38 +860,39 @@ Del</translation>
<translation id="5710435578057952990">הזהות של אתר זה לא אומתה.</translation>
<translation id="5719499550583120431">אפשר לשלם באמצעות כרטיסים משולמים מראש.</translation>
<translation id="5720705177508910913">משתמש נוכחי:</translation>
+<translation id="5728056243719941842">C5 (Envelope)‎</translation>
<translation id="5730040223043577876">‏אם הזנת את הסיסמה שלך באתרים אחרים, ההמלצה של Chrome היא לאפס אותה.</translation>
<translation id="5732392974455271431">ההורים שלך יכולים לבטל בשבילך את החסימה</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{‏שמירת הכרטיס בחשבון Google}two{‏שמירת הכרטיסים בחשבון Google}many{‏שמירת הכרטיסים בחשבון Google}other{‏שמירת הכרטיסים בחשבון Google}}</translation>
<translation id="5763042198335101085">עליך להזין כתובת אימייל חוקית</translation>
<translation id="5765072501007116331">עליך לבחור כתובת כדי לראות שיטות מסירה ודרישות</translation>
-<translation id="5770114862687765385">נראה שהקובץ פגום. יש ללחוץ על הלחצן 'איפוס' כדי לאפס את ההפעלה.</translation>
<translation id="5778550464785688721">‏שליטה מלאה במכשירי MIDI</translation>
<translation id="578305955206182703">ענבר</translation>
<translation id="57838592816432529">השתקה</translation>
<translation id="5784606427469807560">הייתה בעיה באישור הכרטיס. בדוק את החיבור לאינטרנט ונסה שוב.</translation>
<translation id="5785756445106461925">כמו כן, דף זה כולל משאבים נוספים שאינם מאובטחים. גורמים אחרים עלולים לראות את המשאבים האלה במהלך העברתם, ותוקף עלול לשנות אותם באופן שישנה את מראה הדף.</translation>
<translation id="5786044859038896871">האם ברצונך למלא את פרטי הכרטיס שלך?</translation>
+<translation id="5798290721819630480">לבטל את השינויים?</translation>
<translation id="5798683403665926540">‏שינוי דף הבית בהגדרות Chrome</translation>
<translation id="5803412860119678065">האם ברצונך למלא את פרטי הכרטיס <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">הרשאות</translation>
<translation id="5810442152076338065">החיבור שלך אל <ph name="DOMAIN" /> מוצפן באמצעות חבילת צופן מיושנת.</translation>
<translation id="5813119285467412249">&amp;ביצוע מחדש של הוספה</translation>
<translation id="5838278095973806738">אין להזין מידע רגיש באתר הזה (כמו סיסמאות או מספרי כרטיסי אשראי), מאחר שתוקפים עלולים לקבל אליו גישה.</translation>
+<translation id="5860033963881614850">כבוי</translation>
<translation id="5863847714970149516">בדף הבא עשויה להיות דרישה לתשלום</translation>
<translation id="5866257070973731571">הוספת מספר טלפון</translation>
<translation id="5869405914158311789">לא ניתן לגשת לאתר הזה</translation>
<translation id="5869522115854928033">סיסמאות שמורות</translation>
<translation id="5887400589839399685">הכרטיס נשמר</translation>
-<translation id="5893718151540690985">דיווח רשימה של ממשקי רשתות יחד עם הסוגים וכתובות החומרה שלהם</translation>
<translation id="5893752035575986141">אפשר לשלם באמצעות כרטיסי אשראי.</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="5916664084637901428">פועל</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">‏לשמור את הכרטיס בחשבון Google?</translation>
<translation id="5922853866070715753">עוד רגע מסיימים</translation>
<translation id="5932224571077948991">באתר מוצגות מודעות מפריעות או מטעות</translation>
-<translation id="5939518447894949180">אפס</translation>
<translation id="5946937721014915347">פתיחה של <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">אי אפשר להירשם באמצעות חשבון פרטי (יש רישיון משויך זמין).</translation>
<translation id="5967592137238574583">עריכת הפרטים ליצירת קשר</translation>
@@ -797,6 +900,7 @@ Del</translation>
<translation id="5975083100439434680">התרחק</translation>
<translation id="5977489021191000276">המכשיר לא מנוהל על-ידי מנהל מערכת.</translation>
<translation id="5977976211062815271">במכשיר הזה</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">לא ניתן לפתוח את אפליקציית התשלומים</translation>
<translation id="5989320800837274978">‏לא צוינו שרתי Proxy קבועים ולא כתובת אתר של סקריפט ‎.pac</translation>
<translation id="5990559369517809815">בקשות שנשלחו לשרת נחסמו על ידי תוסף.</translation>
@@ -807,8 +911,8 @@ Del</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="6033927989869462158">‏דיווח נתונים סטטיסטיים לגבי חומרה, כמו שימוש ביחידת עיבוד מרכזית (CPU) או בזיכרון RAM</translation>
<translation id="6034000775414344507">אפור בהיר</translation>
+<translation id="6034283069659657473">10x14 (Envelope)‎</translation>
<translation id="6039846035001940113">אם הבעיה ממשיכה, יש לפנות אל בעל האתר.</translation>
<translation id="6040143037577758943">סגור</translation>
<translation id="6044573915096792553">גודל 12</translation>
@@ -817,10 +921,10 @@ Del</translation>
<translation id="6051221802930200923">נכון לעכשיו אי אפשר לבקר באתר <ph name="SITE" />, מאחר שבאתר הזה נעשה שימוש בנעיצת אישורים. שגיאות רשת ומתקפות הן בדרך כלל זמניות, כך שהדף הזה יחזור כנראה לפעול מאוחר יותר.</translation>
<translation id="6058977677006700226">רוצה להשתמש בכרטיסים בכל המכשירים שברשותך?</translation>
<translation id="6059925163896151826">‏מכשירי USB</translation>
-<translation id="6071091556643036997">סוג המדיניות אינו חוקי.</translation>
<translation id="6080696365213338172">ניגשת לתוכן באמצעות אישור שהוענק על ידי מנהל מערכת. מנהל המערכת שלך עשוי ליירט נתונים שתספק ל-<ph name="DOMAIN" />.</translation>
<translation id="6094273045989040137">הוספת הערה</translation>
<translation id="610911394827799129">‏ייתכן שלחשבון Google שלך משויכים סוגים אחרים של היסטוריית גלישה בכתובת <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">מידע על תוספים ויישומי פלאגין מותקנים</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ללא}=1{סיסמה אחת (מסונכרנת)}two{שתי סיסמאות (מסונכרנות)}many{# סיסמאות (מסונכרנות)}other{# סיסמאות (מסונכרנות)}}</translation>
<translation id="6146055958333702838">בדוק את הכבלים והפעל מחדש את הנתבים, המודמים ושאר התקני הרשת
שאתה משתמש בהם.</translation>
@@ -855,15 +959,21 @@ Del</translation>
<translation id="6337133576188860026">פינוי של פחות מ-<ph name="SIZE" /> מהשטח. ייתכן שחלק מהאתרים ייטענו לאט יותר בביקור הבא שלך.</translation>
<translation id="6337534724793800597">סנן מדיניות לפי שם</translation>
<translation id="6358450015545214790">מה זה אומר?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">ייתכנו חיובים באתר.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{הצעה אחת נוספת}two{שתי הצעות נוספות}many{# הצעות נוספות}other{# הצעות נוספות}}</translation>
<translation id="6387754724289022810">‏כדי לשלם מהר יותר בפעם הבאה, אפשר לשמור בחשבון Google ובמכשיר הזה את פרטי הכרטיס ואת הכתובת לחיוב.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">ערוך סימניה</translation>
+<translation id="6406765186087300643">C0 (Envelope)‎</translation>
<translation id="6410264514553301377">הזן את תאריך התפוגה ואת קוד האימות של <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">שאלת אחד מהוריך אם אתה יכול לבקר באתר הזה</translation>
<translation id="6417515091412812850">לא ניתן לבדוק אם האישור נשלל.</translation>
<translation id="6433490469411711332">עריכת הפרטים ליצירת קשר</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> סירב להתחבר.</translation>
+<translation id="6434309073475700221">התעלם</translation>
+<translation id="6446163441502663861">Kahu (Envelope)‎</translation>
<translation id="6446608382365791566">הוסף מידע</translation>
<translation id="6447842834002726250">‏קובצי Cookie</translation>
<translation id="6451458296329894277">אשר שליחה-מחדש של הטופס</translation>
@@ -876,11 +986,17 @@ Del</translation>
<translation id="6508722015517270189">‏הפעלה מחדש של Chrome</translation>
<translation id="6529602333819889595">&amp;ביצוע מחדש של מחיקה</translation>
<translation id="6534179046333460208">הצעות לאינטרנט הפיזי</translation>
+<translation id="6556866813142980365">בצע מחדש</translation>
<translation id="6563469144985748109">המנהל שלך עדיין לא אישר זאת</translation>
<translation id="6569060085658103619">אתה מציג דף של תוסף</translation>
+<translation id="6578796323535178455">C2 (Envelope)‎</translation>
<translation id="6579990219486187401">ורוד בהיר</translation>
+<translation id="6583674473685352014">B6 (Envelope)‎</translation>
+<translation id="6587923378399804057">קישור שהעתקת</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> זה אינו מנוהל</translation>
<translation id="6596325263575161958">אפשרויות הצפנה</translation>
<translation id="6604181099783169992">חיישני תנועה או אור</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)‎</translation>
<translation id="6624427990725312378">פרטי איש קשר</translation>
<translation id="6626291197371920147">הוסף מספר כרטיס חוקי</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> חיפוש</translation>
@@ -889,6 +1005,7 @@ Del</translation>
<translation id="6644283850729428850">מדיניות זו אינה בתוקף.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ללא}=1{‏מאתר אחד (לא תבוצע יציאה מחשבון Google שלך.)}two{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}many{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}other{‏מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}}</translation>
<translation id="6657585470893396449">סיסמה</translation>
+<translation id="6670613747977017428">חזרה לדף הבטוח.</translation>
<translation id="6671697161687535275">‏האם להסיר מ-Chromium הצעות לטפסים?</translation>
<translation id="6685834062052613830">צא והשלם את ההגדרה</translation>
<translation id="6710213216561001401">הקודם</translation>
@@ -896,12 +1013,15 @@ Del</translation>
<translation id="671076103358959139">אסימון הרשמה:</translation>
<translation id="6711464428925977395">‏משהו אינו תקין בשרת ה-proxy, או שהכתובת שגויה.</translation>
<translation id="6723740634201835758">‏בחשבון Google שלך</translation>
+<translation id="6738516213925468394">הנתונים שלך הוצפנו באמצעות<ph name="BEGIN_LINK" />ביטוי סיסמה לסנכרון<ph name="END_LINK" /> בתאריך <ph name="TIME" />. צריך להזין אותו כדי להתחיל את הסנכרון.</translation>
<translation id="674375294223700098">שגיאת אישור שרת לא ידוע.</translation>
<translation id="6744009308914054259">בזמן ההמתנה לחיבור אפשר לעבור אל 'הורדות' כדי לקרוא מאמרים לא מקוונים.</translation>
<translation id="6753269504797312559">ערך מדיניות</translation>
<translation id="6757797048963528358">המכשיר עבר למצב שינה.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)‎</translation>
<translation id="6778737459546443941">ההורה ששאלת עדיין לא אישר זאת</translation>
<translation id="67862343314499040">סגול סיגלית</translation>
+<translation id="6786747875388722282">תוספים</translation>
<translation id="679355240208270552">המערכת התעלמה מערך מדיניות זה, משום שלפי המדיניות חיפוש ברירת המחדל מושבת.</translation>
<translation id="681021252041861472">שדה חובה</translation>
<translation id="6810899417690483278">מזהה של התאמה אישית</translation>
@@ -934,10 +1054,12 @@ Del</translation>
<translation id="6965978654500191972">התקן</translation>
<translation id="6970216967273061347">מחוז</translation>
<translation id="6973656660372572881">‏צוינו שרתי Proxy קבועים וכתובת אתר של הסקריפט מסוג ‎.Pac</translation>
+<translation id="6973932557599545801">לצערי אין לי אפשרות לעזור. עליך להמשיך בעצמך.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">השתקה (ברירת מחדל)</translation>
<translation id="6984479912851154518">בחרת לצאת ממצב פרטי כדי לשלם באמצעות אפליקציה חיצונית. להמשיך?</translation>
<translation id="6989763994942163495">הצג הגדרות מתקדמות...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)‎</translation>
<translation id="6996312675313362352">תמיד לתרגם מ<ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">התשלום עשוי להיות חד-פעמי או לכלול חיובים חוזרים וייתכן שהדרישה לתשלום לא תוצג בצורה ברורה וחד-משמעית.</translation>
@@ -953,28 +1075,33 @@ Del</translation>
<translation id="7108338896283013870">הסתרה</translation>
<translation id="7108819624672055576">אושרה על-ידי תוסף</translation>
<translation id="7111012039238467737">(חוקי)</translation>
+<translation id="7118618213916969306">‏חיפוש כתובת ה-URL שהועתקה ללוח, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">סגירת כרטיסיות או תוכניות אחרות</translation>
<translation id="7129409597930077180">לא ניתן לבצע משלוח לכתובת הזו. עליך לבחור כתובת אחרת.</translation>
<translation id="7135130955892390533">הצגת סטטוס</translation>
<translation id="7138472120740807366">שיטת מסירה</translation>
<translation id="7139724024395191329">האמירויות הערביות</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)‎</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">לבנדר</translation>
-<translation id="7158980942472052083">כתובת אתר לא חוקית. כתובת האתר חייבת להיות בתבנית רגילה.</translation>
<translation id="717330890047184534">‏מזהה GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">השרת שאליו ביקשת לעבור, <ph name="ORIGIN" />, ביקש להחיל מדיניות אבטחה על כל הבקשות הנשלחות אליו. עם זאת, במקום לספק מדיניות הוא הפנה את הדפדפן לכתובת אתר אחרת. מצב זה מונע מהדפדפן למלא את הבקשה לעבור אל <ph name="SITE" />.</translation>
<translation id="7179323680825933600">שמירה ומילוי של אמצעי תשלום</translation>
<translation id="7180611975245234373">רענון</translation>
<translation id="7182878459783632708">לא הוגדרה מדיניות</translation>
<translation id="7186367841673660872">דף זה תורגם מ<ph name="ORIGINAL_LANGUAGE" />ל<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">פינוי של <ph name="SIZE" /> מהשטח. תיתכן טעינה איטית יותר של אתרים מסוימים בביקור הבא שלך.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">מנהל המערכת יכול לראות:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> לא פועל בהתאם לתקני האבטחה.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /> בנושא זה.</translation>
<translation id="7219179957768738017">החיבור משתמש ב-<ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">מעבד</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">האתר שלפניך מכיל תוכנה זדונית</translation>
+<translation id="724766306220616965">אזהרות, סתירה</translation>
<translation id="724975217298816891">הזן את תאריך התפוגה ואת קוד האימות של <ph name="CREDIT_CARD" /> כדי לעדכן את פרטי הכרטיס. ברגע שתאשר, פרטי הכרטיס שלך ישותפו עם האתר הזה.</translation>
<translation id="7251437084390964440">‏תצורת הרשת אינה תואמת לתקן ONC. ייתכן שחלקים מהתצורה לא ייכללו בייבוא.
פרטים נוספים:
@@ -987,11 +1114,14 @@ Del</translation>
<translation id="7300012071106347854">כחול קובלט</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">דוח הקריסה תועד ב<ph name="CRASH_TIME" /> (המשתמש ביקש העלאה, הדוח עדיין לא הועלה)</translation>
+<translation id="7313965965371928911">אזהרות <ph name="BEGIN_LINK" />גלישה בטוחה<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">עזרה בחיבור</translation>
<translation id="7334320624316649418">&amp;ביצוע מחדש של שינוי סדר</translation>
<translation id="733923710415886693">אישור השרת לא נחשף דרך 'שקיפות אישורים'.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">שורת פקודה </translation>
-<translation id="7365061714576910172">‏ייצוא בפורמט ל-Linux</translation>
<translation id="7372973238305370288">תוצאת חיפוש</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">לא</translation>
@@ -999,6 +1129,7 @@ Del</translation>
<translation id="7381288752349550461">שינוי כתוצאה מסשן מנוהל</translation>
<translation id="7390545607259442187">אשר את הכרטיס</translation>
<translation id="7400418766976504921">כתובת אתר</translation>
+<translation id="7403591733719184120">מכשיר <ph name="DEVICE_NAME" /> זה מנוהל</translation>
<translation id="7407424307057130981">‏&lt;p&gt;השגיאה הזו תופיע אם תוכנת Superfish מותקנת במחשב Windows שלך.&lt;/p&gt;
&lt;p&gt;כדי להשבית את התוכנה באופן זמני ולקבל גישה לאינטרנט, צריך לבצע את השלבים הבאים. צריכות להיות לך הרשאות מנהל.&lt;/p&gt;
&lt;ol&gt;
@@ -1009,7 +1140,7 @@ Del</translation>
&lt;li&gt;לוחצים על &lt;strong&gt;הפעלה&lt;/strong&gt; ולאחר מכן לוחצים על &lt;strong&gt;אישור&lt;/strong&gt;
&lt;li&gt;עוברים אל &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;מרכז העזרה של Chrome&lt;/a&gt; כדי ללמוד כיצד להסיר את התוכנה מהמחשב
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">ניהול <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">ניהול סיסמאות…</translation>
<translation id="7419106976560586862">נתיב פרופיל</translation>
<translation id="7437289804838430631">הוספת פרטים ליצירת קשר</translation>
@@ -1018,22 +1149,24 @@ Del</translation>
<translation id="7442725080345379071">כתום בהיר</translation>
<translation id="7444046173054089907">האתר הזה חסום</translation>
<translation id="7445762425076701745">לא ניתן לאמת לגמרי את הזהות של השרת שאליו אתה מחובר. אתה מחובר לשרת באמצעות שם שקיים רק ברשת שלך, ושלרשות אישורים חיצונית אין דרך לאמת את בעלותך עליו. מכיוון שחלק מרשויות האישורים ינפיקו אישורים לשמות אלה ללא קשר, אין דרך להבטיח שאתה מחובר לאתר המיועד ואינך גורם תוקף.</translation>
-<translation id="7449109375006139765">שליחה של יומני מערכת לשרת הניהול</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />למידע נוסף<ph name="END_LINK" /> על בעיה זו.</translation>
<translation id="7455133967321480974">השתמש בברירת המחדל הכללית (חסום)</translation>
<translation id="7460618730930299168">הסינון שונה ממה שבחרת. להמשיך?</translation>
<translation id="7473891865547856676">לא, תודה</translation>
-<translation id="7475525192983021547">דיווח תקופות זמן שבהן המשתמש פעיל במכשיר</translation>
<translation id="7481312909269577407">קדימה</translation>
<translation id="7485870689360869515">לא נמצאו נתונים.</translation>
+<translation id="7498234416455752244">המשך העריכה</translation>
<translation id="7508255263130623398">מזהה המכשיר במדיניות שהוחזר ריק או שאינו תואם את מזהה המכשיר הנוכחי</translation>
<translation id="7508870219247277067">ירוק אבוקדו</translation>
<translation id="7511955381719512146">‏ייתכן שתידרש להיכנס ל-<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> עבור רשת ה-Wi-Fi שבה אתה משתמש.</translation>
<translation id="7514365320538308">הורדה</translation>
<translation id="7518003948725431193">לא נמצא דף אינטרנט עבור כתובת האינטרנט: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)‎</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">החיבור שלך לאתר זה אינו פרטי</translation>
+<translation id="7535087603100972091">ערך</translation>
<translation id="7537536606612762813">הכרחי</translation>
+<translation id="7538364083937897561">A2 (Envelope)‎</translation>
<translation id="7542403920425041731">ברגע שתאשר, פרטי הכרטיס שלך ישותפו עם האתר הזה.</translation>
<translation id="7542995811387359312">מילוי אוטומטי של פרטי כרטיס אשראי מושבת כיוון שטופס זה אינו משתמש בחיבור מאובטח.</translation>
<translation id="7543525346216957623">יש לבקש רשות מההורים</translation>
@@ -1042,8 +1175,8 @@ Del</translation>
<translation id="7552846755917812628">אולי הטיפים האלו יעזרו לך:</translation>
<translation id="7554791636758816595">כרטיסייה חדשה</translation>
<translation id="7564049878696755256">‏הגישה שלך לחשבון <ph name="ORG_NAME" /> עשויה להישלל והזהות שלך עשויה להיגנב. ההמלצה של Chrome היא לשנות את הסיסמה עכשיו.</translation>
-<translation id="7566125604157659769">הטקסט שהעתקת</translation>
<translation id="7567204685887185387">השרת הזה לא הצליח להוכיח שהוא <ph name="DOMAIN" />. ייתכן שאישור האבטחה שלו נופק כהונאה. הסיבה לכך עשויה להיות הגדרה שגויה או תוקף המיירט את החיבור שלך.</translation>
+<translation id="7568105740864181217">‏הדפדפן הזה מנוהל על ידי חברה, בית ספר או ארגון אחר. מנהל המערכת יכול לשנות את הגדרת הדפדפן שלך מרחוק. בנוסף, ניתן לנהל את הפעילות במכשיר הזה מחוץ ל-Chrome. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">‏האם להסיר את כרטיס האשראי מ-Chrome?</translation>
<translation id="7569983096843329377">שחור</translation>
<translation id="7578104083680115302">‏ניתן לשלם במהירות באתרים ובאפליקציות בכל המכשירים באמצעות כרטיסים ששמרת ב-Google.</translation>
@@ -1054,6 +1187,7 @@ Del</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="7633909222644580952">נתוני ביצועים ודוחות קריסה</translation>
<translation id="7637571805876720304">‏האם להסיר מ-Chromium את כרטיס האשראי?</translation>
<translation id="7639968568612851608">אפור כהה</translation>
<translation id="765676359832457558">הסתר הגדרות מתקדמות...</translation>
@@ -1063,9 +1197,11 @@ Del</translation>
<translation id="7667346355482952095">אסימון המדיניות שהוחזר הוא ריק או שאינו תואם לאסימון הנוכחי</translation>
<translation id="7668654391829183341">מכשיר לא ידוע</translation>
<translation id="7669271284792375604">תוקפים באתר הזה עשויים לגרום לך, בדרכי מרמה, להתקין תוכניות שיפגעו בחוויית הגלישה שלך (לדוגמה, על ידי שינוי דף הבית או הצגת מודעות נוספות באתרים שבהם אתה מבקר).</translation>
+<translation id="7676643023259824263">חיפוש טקסט בלוח, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">שינוי מנוע החיפוש</translation>
<translation id="7682287625158474539">משלוח</translation>
<translation id="7687186412095877299">ממלא בטופסי תשלום את אמצעי התשלום ששמרת</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)‎</translation>
<translation id="769721561045429135">יש לך כרגע כרטיסים שאפשר להשתמש בהם רק במכשיר הזה. כדי לעיין בכרטיסים יש ללחוץ על 'המשך".</translation>
<translation id="7699293099605015246">לא ניתן להציג כרגע מאמרים</translation>
<translation id="7701040980221191251">ללא</translation>
@@ -1077,11 +1213,13 @@ Del</translation>
<translation id="774634243536837715">תוכן מסוכן נחסם.</translation>
<translation id="7752995774971033316">ללא ניהול</translation>
<translation id="7755287808199759310">אחד מההורים שלך יכול לבטל בשבילך את החסימה</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ייתכן שחומת אש או תוכנת אנטי-וירוס חסמו את החיבור.</translation>
<translation id="7759163816903619567">דומיין תצוגה:</translation>
<translation id="7761701407923456692">אישור השרת אינו תואם לכתובת האתר.</translation>
<translation id="7763386264682878361">מנתח מניפסט התשלום</translation>
<translation id="7764225426217299476">הוסף כתובת</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">תחום שיפוט</translation>
<translation id="7791543448312431591">הוספה</translation>
<translation id="7793809570500803535">ייתכן שדף האינטרנט בכתובת <ph name="SITE" /> אינו פעיל זמנית, או שהועבר לכתובת אינטרנט חדשה לצמיתות.</translation>
@@ -1093,8 +1231,8 @@ Del</translation>
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">‏האם להסיר מ-Chrome הצעות בשביל טפסים?</translation>
<translation id="7815407501681723534">נמצאו <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> בנושא '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">ניהול מדיניות</translation>
<translation id="782886543891417279">‏ייתכן שתידרש להיכנס לדף ההתחברות של רשת ה-Wi-Fi שבה אתה משתמש (<ph name="WIFI_NAME" />).</translation>
+<translation id="7836231406687464395">Postfix (Envelope)‎</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ללא}=1{אפליקציה אחת (<ph name="EXAMPLE_APP_1" />)}=2{2 אפליקציות (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}many{# אפליקציות (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# אפליקציות (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">עם זאת, אינך בלתי נראה. המעבר למצב גלישה בסתר לא מסתיר את הגלישה שלך מהמעסיק, מספק האינטרנט או מהאתרים שאליהם אתה נכנס.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1103,7 +1241,7 @@ Del</translation>
<translation id="7878562273885520351">ייתכן שאבטחת הסיסמה שלך נפגעה</translation>
<translation id="7882421473871500483">חום</translation>
<translation id="7887683347370398519">‏בדוק את ה-CVC ונסה שוב</translation>
-<translation id="7893255318348328562">שם הפעלה</translation>
+<translation id="7904208859782148177">C3 (Envelope)‎</translation>
<translation id="79338296614623784">עליך להזין מספר טלפון חוקי</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">בתוקף עד <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1113,21 +1251,25 @@ Del</translation>
<translation id="7951415247503192394">(32 סיביות)</translation>
<translation id="7956713633345437162">סימניות לנייד</translation>
<translation id="7961015016161918242">אף פעם</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">לא צוין</translation>
<translation id="800218591365569300">מומלץ לסגור כרטיסיות או תוכניות אחרות וכך לפנות מקום בזיכרון.</translation>
+<translation id="8004582292198964060">דפדפן</translation>
<translation id="8009225694047762179">ניהול סיסמאות</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{הכרטיס הזה יישמר יחד עם הכתובת שלו לחיוב. יתאפשר לך להשתמש בו לאחר התחברות אל <ph name="USER_EMAIL" />.}two{הכרטיסים האלה יישמרו יחד עם הכתובות שלהם לחיוב. יתאפשר לך להשתמש בהם לאחר התחברות אל <ph name="USER_EMAIL" />.}many{הכרטיסים האלה יישמרו יחד עם הכתובות שלהם לחיוב. יתאפשר לך להשתמש בהם לאחר התחברות אל <ph name="USER_EMAIL" />.}other{הכרטיסים האלה יישמרו יחד עם הכתובות שלהם לחיוב. יתאפשר לך להשתמש בהם לאחר התחברות אל <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">לא הצלחנו ליצור קשר עם ההורים שלך. נסה שוב מאוחר יותר.</translation>
<translation id="8025119109950072390">תוקפים באתר הזה עשויים לגרום לך, בדרכי מרמה, לבצע פעולות מסוכנות כמו התקנת תוכנה או חשיפה של מידע אישי (לדוגמה: סיסמאות, מספרי טלפון או פרטי כרטיסי אשראי).</translation>
<translation id="8034522405403831421">דף זה מוצג ב<ph name="SOURCE_LANGUAGE" />. האם לתרגם אותו ל<ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">עט</translation>
+<translation id="8037117624646282037">מי השתמש במכשיר לאחרונה</translation>
<translation id="8037357227543935929">שאל (ברירת מחדל)</translation>
<translation id="803771048473350947">קובץ</translation>
<translation id="8041089156583427627"> שליחת משוב</translation>
<translation id="8041940743680923270">השתמש בברירת המחדל הכללית (שאל)</translation>
<translation id="8042918947222776840">בחירת שיטת איסוף</translation>
<translation id="8057711352706143257">יש בעיה בהגדרה של "<ph name="SOFTWARE_NAME" />". בדרך כלל, הסרת ההתקנה של "<ph name="SOFTWARE_NAME" />" פותרת את הבעיה. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">במכשיר הוגדרו קביעות המדיניות הבאות:</translation>
+<translation id="8066955247577885446">מצטערים, משהו השתבש.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)‎</translation>
<translation id="8078141288243656252">לא ניתן להוסיף הערה במצב מסובב</translation>
<translation id="8079031581361219619">לטעון את האתר מחדש?</translation>
<translation id="8088680233425245692">הצגת הפריט נכשלה.</translation>
@@ -1136,11 +1278,12 @@ Del</translation>
<translation id="8091372947890762290">ההפעלה ממתינה בשרת</translation>
<translation id="8092774999298748321">סגול כהה</translation>
<translation id="8094917007353911263">ייתכן שתידרש להיכנס ל-<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> עבור הרשת שבה אתה משתמש.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">הכרטיסים שאינם בתוקף הוסרו</translation>
<translation id="8103161714697287722">אמצעי תשלום</translation>
<translation id="8118489163946903409">אמצעי תשלום</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> מנוהל על ידי <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">‏הייתה בעיה בהתקנה של "<ph name="SOFTWARE_NAME" />" במחשב שלך או ברשת. יש לבקש ממנהל ה-IT לפתור את הבעיה.</translation>
-<translation id="8130693978878176684">אני כבר לא יכול לעזור. עליך להמשיך בעצמך.</translation>
<translation id="8131740175452115882">אישור</translation>
<translation id="8149426793427495338">המחשב עבר למצב שינה.</translation>
<translation id="8150722005171944719">הקובץ הנמצא ב-<ph name="URL" /> לא ניתן לקריאה. ייתכן שהקובץ הוסר או הועבר, או שהרשאות הקובץ מונעות גישה אליו.</translation>
@@ -1150,8 +1293,11 @@ Del</translation>
<translation id="8197543752516192074">תרגום הדף</translation>
<translation id="8201077131113104583">כתובת אתר לא חוקית לעדכון עבור תוסף עם המזהה "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">סיכום הזמנה</translation>
+<translation id="8202370299023114387">התנגשות</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)‎</translation>
<translation id="8211406090763984747">החיבור מאובטח</translation>
<translation id="8218327578424803826">מיקום מוקצה:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)‎</translation>
<translation id="8225771182978767009">המשתמש שהגדיר את המחשב הזה בחר לחסום את האתר הזה.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">פתיחת הדף בכרטיסייה חדשה של גלישה בסתר</translation>
@@ -1163,14 +1309,16 @@ Del</translation>
<translation id="825929999321470778">הצגת כל הסיסמאות השמורות</translation>
<translation id="8261506727792406068">מחיקה</translation>
<translation id="8267698848189296333">נכנס כ-<ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">‏דפדפן זה מנוהל על ידי <ph name="ENROLLMENT_DOMAIN" />. מנהל המערכת יכול לשנות את הגדרת הדפדפן מרחוק. בנוסף, ניתן לנהל את הפעילות במכשיר הזה מחוץ ל-Chrome. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">כניסה</translation>
<translation id="8288807391153049143">הצגת אישור</translation>
<translation id="8289355894181816810">פנה אל מנהל הרשת אם אינך יודע מה זה אומר.</translation>
<translation id="8293206222192510085">הוסף סימניה</translation>
<translation id="8294431847097064396">מקור</translation>
<translation id="8298115750975731693">‏ייתכן שתידרש להיכנס ל-<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> עבור רשת ה-Wi-Fi שבה אתה משתמש (<ph name="WIFI_NAME" />).</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">התרגום נכשל עקב בעיה בחיבור הרשת.</translation>
-<translation id="8311129316111205805">טעינת הפעלה</translation>
<translation id="8332188693563227489">אין גישה אל <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">אם אתה מבין את סיכוני האבטחה, תוכל <ph name="BEGIN_LINK" />להיכנס לאתר לא בטוח זה<ph name="END_LINK" /> לפני הסרת התכניות המסוכנות.</translation>
@@ -1188,7 +1336,6 @@ Del</translation>
<translation id="8416694386774425977">תצורת הרשת אינה חוקית ולא ניתן לייבא אותה.
פרטים נוספים:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">המכשיר מנוהל על-ידי <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">שנה</translation>
<translation id="8428213095426709021">הגדרות</translation>
@@ -1216,9 +1363,11 @@ Del</translation>
<translation id="860043288473659153">שם בעל הכרטיס</translation>
<translation id="861775596732816396">גודל 4</translation>
<translation id="8620436878122366504">ההורים שלך עדיין לא אישרו זאת</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">שמירת כרטיס זה במכשיר הנוכחי</translation>
<translation id="8663226718884576429">סיכום הזמנה, <ph name="TOTAL_LABEL" />, פרטים נוספים</translation>
<translation id="8680536109547170164"><ph name="QUERY" /> , תשובה, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">ההתחברות שלך אל <ph name="DOMAIN" /> אינה מוצפנת.</translation>
<translation id="8718314106902482036">התשלום לא הושלם</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, הצעת חיפוש</translation>
@@ -1232,6 +1381,7 @@ Del</translation>
<translation id="8761567432415473239">‏גלישה בטוחה של Google <ph name="BEGIN_LINK" />איתרה לאחרונה תוכניות מזיקות<ph name="END_LINK" /> באתר <ph name="SITE" />.</translation>
<translation id="8763927697961133303">‏התקן USB</translation>
<translation id="8768895707659403558">כדי להשתמש בכרטיסים שלך בכל המכשירים שברשותך, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ביצוע מחדש של מחיקה</translation>
<translation id="8792621596287649091">‏הגישה שלך לחשבון <ph name="ORG_NAME" /> עשויה להישלל והזהות שלך עשויה להיגנב. ההמלצה של Chromium היא לשנות את הסיסמה עכשיו.</translation>
<translation id="8800988563907321413">כאן מופיעות הצעות עבורך למקומות קרובים</translation>
@@ -1242,10 +1392,12 @@ Del</translation>
<translation id="885730110891505394">‏שיתוף עם Google</translation>
<translation id="8858065207712248076">‏אם הזנת את הסיסמה של <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> באתרים אחרים, ההמלצה של Chrome היא לאפס אותה.</translation>
<translation id="8866481888320382733">שגיאה בניתוח הגדרות המדיניות</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">נסגרו לאחרונה</translation>
<translation id="8874824191258364635">עליך להזין מספר כרטיס חוקי</translation>
<translation id="8891727572606052622">‏מצב שרת Proxy לא חוקי.</translation>
<translation id="8903921497873541725">התקרב</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">‏האם ברצונך לשמור את הכרטיס הזה בחשבון Google שלך?</translation>
<translation id="8932102934695377596">השעון שלך מאחר</translation>
<translation id="893332455753468063">הוספת שם</translation>
@@ -1253,13 +1405,13 @@ Del</translation>
<translation id="894185898663964645">מנהל המערכת הגדיר אישורי בסיס מותאמים אישית, וייתכן שיש לו אפשרות לראות את תוכן האתרים שנכנסת אליהם.</translation>
<translation id="8943282376843390568">ליים</translation>
<translation id="8957210676456822347">הרשאת פורטל חובה</translation>
+<translation id="8966619695390250636">האם התכוונת?</translation>
<translation id="8968766641738584599">שמירת הכרטיס</translation>
<translation id="8971063699422889582">פג תוקפו של אישור השרת.</translation>
<translation id="8975012916872825179">כולל מידע כמו מספרי טלפון, כתובות אימייל וכתובות למשלוח</translation>
<translation id="8978053250194585037">‏לאחרונה <ph name="BEGIN_LINK" />זוהה דיוג<ph name="END_LINK" /> באתר <ph name="SITE" /> על-ידי הגלישה הבטוחה של Google. אתרי דיוג מתחזים לאתרים אחרים כדי להונות אותך.</translation>
<translation id="8983003182662520383">‏אמצעי תשלום וכתובות שנשמרו ב-Google Pay</translation>
<translation id="8987927404178983737">חודש</translation>
-<translation id="8988408250700415532">משהו השתבש. אפשר לסיים את ההזמנה באתר.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">האתר הבא מכיל תוכניות מזיקות</translation>
<translation id="8997023839087525404">השרת הציג אישור שלא נחשף באופן ציבורי בעזרת מדיניות 'שקיפות אישורים'. זוהי דרישה עבור חלק מהאישורים, ומטרתה לוודא שהם מהימנים וכדי להגן מפני תוקפים.</translation>
@@ -1269,6 +1421,7 @@ Del</translation>
<translation id="9011424611726486705">פתיחת הגדרות האתר</translation>
<translation id="9020200922353704812">יש להזין את הכתובת לחיוב של הכרטיס</translation>
<translation id="9020542370529661692">הדף הזה תורגם ל<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(לא חוקי)</translation>
<translation id="9035022520814077154">שגיאת אבטחה</translation>
<translation id="9038649477754266430">השתמש בשירות חיזוי כדי לטעון דפים מהר יותר</translation>
@@ -1280,11 +1433,11 @@ Del</translation>
<translation id="9065745800631924235"><ph name="TEXT" /> – חיפוש מההיסטוריה</translation>
<translation id="9069693763241529744">נחסמה על-ידי תוסף</translation>
<translation id="9076283476770535406">ייתכן שהאתר מכיל תוכן למבוגרים בלבד</translation>
+<translation id="9076630408993835509">‏הדפדפן הזה לא מנוהל על ידי חברה או ארגון אחר. ייתכן שהפעילות במכשיר הזה מנוהלת מחוץ ל-Chrome. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">נדרש מידע נוסף</translation>
<translation id="9080712759204168376">סיכום הזמנה</translation>
<translation id="9103872766612412690">‏האתר <ph name="SITE" /> משתמש בדרך כלל בהצפנה כדי להגן על המידע שלך. כאשר Chromium ניסה הפעם להתחבר ל-<ph name="SITE" />, האתר שלח חזרה אישורים חריגים ושגויים. ייתכן שתוקף מנסה להתחזות לאתר <ph name="SITE" />, או שמסך כניסה ל-Wi-Fi הפריע לחיבור. המידע שלך עדיין מאובטח מכיוון ש-Chromium הפסיק את החיבור לפני חילופי הנתונים.</translation>
<translation id="9106062320799175032">הוספה של כתובת לחיוב</translation>
-<translation id="9110718169272311511">‏Google Assistant זמין ב-Chrome בחלק התחתון של המסך</translation>
<translation id="9114524666733003316">אישור הכרטיס מתבצע...</translation>
<translation id="9128870381267983090">התחבר לרשת</translation>
<translation id="9137013805542155359">הצג מקור</translation>
@@ -1293,6 +1446,7 @@ Del</translation>
<translation id="9148507642005240123">&amp;ביטול עריכה</translation>
<translation id="9154194610265714752">עודכן</translation>
<translation id="9157595877708044936">מגדיר...</translation>
+<translation id="9158625974267017556">C6 (Envelope)‎</translation>
<translation id="9168814207360376865">מתן הרשאה לאתרים לבדוק אם שמרת אמצעי תשלום</translation>
<translation id="9169664750068251925">חסום תמיד באתר זה</translation>
<translation id="9170848237812810038">&amp;ביטול</translation>
@@ -1307,10 +1461,12 @@ Del</translation>
<translation id="9219103736887031265">תמונות</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ניקוי הטופס</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">‏ייתכן שמישהו אחר ישלול את הגישה שלך לחשבון Google. לגלישה בטוחה ב-Chromium, מומלץ לשנות את הסיסמה עכשיו.</translation>
<translation id="939736085109172342">תיקייה חדשה</translation>
<translation id="945855313015696284">יש לבדוק את המידע שבהמשך ולמחוק כרטיסים עם שגיאות</translation>
<translation id="951104842009476243">כרטיסי חיוב וכרטיסים משולמים מראש שהסוחר מקבל</translation>
+<translation id="958202389743790697">נחסם בהתאם למדיניות האבטחה של <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">ייתכן שבתוכן הזה יש קוד להתקנת אפליקציות מטעות שמתחזות למשהו אחר או שאוספות נתונים המאפשרים לעקוב אחריך. <ph name="BEGIN_LINK" />אני רוצה לראות בכל זאת<ph name="END_LINK" /></translation>
<translation id="969892804517981540">גירסה רשמית</translation>
<translation id="973773823069644502">הוספת כתובת למסירה</translation>
@@ -1319,6 +1475,7 @@ Del</translation>
<translation id="984275831282074731">אמצעי תשלום</translation>
<translation id="985199708454569384">‏&lt;p&gt;השגיאה הזו תוצג אם התאריך והשעה במחשב או בנייד אינם מדויקים.&lt;/p&gt;
&lt;p&gt;כדי לפתור את השגיאה, פותחים את השעון של המכשיר. מוודאים שהשעה והתאריך נכונים&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">גירסת מפתחים</translation>
<translation id="989988560359834682">ערוך כתובת</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ja.xtb b/chromium/components/strings/components_strings_ja.xtb
index 1130d82f768..87e8acbb32b 100644
--- a/chromium/components/strings/components_strings_ja.xtb
+++ b/chromium/components/strings/components_strings_ja.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
-<translation id="1005145902654145231">セッションの名前を変更できませんでした。</translation>
<translation id="1008557486741366299">後で</translation>
<translation id="1010200102790553230">後でページを読み込む</translation>
<translation id="1015730422737071372">詳細を報告する</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">不明な名前</translation>
<translation id="1050038467049342496">他のアプリを終了する</translation>
<translation id="1055184225775184556">追加の取り消し(&amp;U)</translation>
+<translation id="1056898198331236512">警告</translation>
<translation id="1058479211578257048">カードを保存しています...</translation>
<translation id="10614374240317010">常に保存しない</translation>
+<translation id="1062160989074299343">Prc10(封筒)</translation>
<translation id="106701514854093668">パソコンのブックマーク</translation>
<translation id="1074497978438210769">保護されていない通信</translation>
<translation id="1080116354587839789">ウィンドウ幅に合わせる</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">名義人名の追加</translation>
<translation id="1089439967362294234">パスワードを変更</translation>
<translation id="109743633954054152">Chrome の設定でパスワードを管理します</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">ウェブサイトのセキュリティ更新中は警告メッセージが表示されることがあります。これはまもなく改善される予定です。</translation>
<translation id="1126551341858583091">ローカル ストレージ上のサイズは <ph name="CRASH_SIZE" /> です。</translation>
<translation id="112840717907525620">ポリシー キャッシュは正常です</translation>
+<translation id="1131264053432022307">コピーした画像</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> により途中で接続が切断されました。</translation>
<translation id="1161325031994447685">Wi-Fi に再度接続する</translation>
<translation id="1165039591588034296">エラー</translation>
-<translation id="1173894706177603556">名前を変更</translation>
<translation id="1175364870820465910">印刷(&amp;P)...</translation>
<translation id="1181037720776840403">削除</translation>
<translation id="1197088940767939838">オレンジ</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">デバイス名</translation>
<translation id="124116460088058876">その他の言語</translation>
<translation id="1250759482327835220">カード、お名前、請求先住所を Google アカウントに保存すると、次回のお支払いが簡単になります。</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />、<ph name="TYPE_2" />(同期済み)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">コマンドラインのバリエーション</translation>
<translation id="129553762522093515">最近閉じたタブ</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Cookie を消去してみてください<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">選択されたセッションが存在しません。</translation>
+<translation id="1320233736580025032">Prc1(封筒)</translation>
+<translation id="132301787627749051">クリップボードにある画像を検索します</translation>
<translation id="1323433172918577554">もっと見る</translation>
<translation id="132390688737681464">住所の保存と入力</translation>
<translation id="1333989956347591814">ただし、次の相手に<ph name="BEGIN_EMPHASIS" />あなたのアクティビティが知られる<ph name="END_EMPHASIS" />可能性はあります。
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">引取先住所</translation>
<translation id="1348198688976932919">アクセス先のサイトには危険なアプリがあります</translation>
<translation id="1348779747280417563">名前を確認</translation>
+<translation id="1357195169723583938">最近デバイスを使用したユーザーとその日時</translation>
+<translation id="1364822246244961190">このポリシーはブロックされているため、値は無視されます。</translation>
<translation id="1374468813861204354">ヒント</translation>
+<translation id="1374692235857187091">Index-4x6(ポストカード)</translation>
<translation id="1375198122581997741">バージョン情報</translation>
<translation id="1376836354785490390">折りたたむ</translation>
<translation id="1377321085342047638">カード番号</translation>
<translation id="138218114945450791">ライトブルー</translation>
+<translation id="1382194467192730611">管理者によって許可された USB デバイス</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> からデータが送信されませんでした。</translation>
+<translation id="140316286225361634">サイト <ph name="ORIGIN" /> は、すべてのリクエストにセキュリティ ポリシーの適用を求めており、このセキュリティ ポリシーにより、現在このサイトは安全ではないとみなされています。</translation>
<translation id="1405567553485452995">ライトグリーン</translation>
<translation id="1407135791313364759">すべて開く</translation>
<translation id="1413809658975081374">プライバシー エラー</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">はい</translation>
<translation id="1430915738399379752">印刷</translation>
<translation id="1455413310270022028">消しゴム</translation>
+<translation id="1463543813647160932">5×7</translation>
+<translation id="1472675084647422956">表示項目を増やす</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">配送先住所を選択</translation>
+<translation id="1492194039220927094">ポリシーのプッシュ:</translation>
<translation id="1501859676467574491">Google アカウントに保存したカードを表示</translation>
-<translation id="1506687042165942984">このページの保存されているコピー(古いバージョン)を表示します。</translation>
<translation id="1507202001669085618">&lt;p&gt;インターネットに接続するために Wi-Fi ポータルへのログインが必要な場合は、このエラーが表示されます。&lt;/p&gt;
&lt;p&gt;エラーを解決するには、開こうとしているページで [&lt;strong&gt;接続&lt;/strong&gt;] をクリックします。&lt;/p&gt;</translation>
<translation id="1517433312004943670">電話番号が必要です</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">ビルド日</translation>
<translation id="1521655867290435174">Google スプレッドシート</translation>
<translation id="1527263332363067270">接続を待機しています…</translation>
+<translation id="1529521330346880926">10x15(封筒)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">このページの内容</translation>
<translation id="153384715582417236">現在、コンテンツはありません</translation>
<translation id="154408704832528245">配達先住所を選択</translation>
<translation id="1549470594296187301">この機能を使用するには JavaScript を有効にする必要があります。</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">有効期限の入力</translation>
<translation id="1581080074034554886">CVC</translation>
-<translation id="1583429793053364125">このウェブページを表示中に問題が発生しました。</translation>
+<translation id="1583429793053364125">このウェブページの表示中に問題が発生しました。</translation>
<translation id="1592005682883173041">ローカルデータへのアクセス</translation>
<translation id="1594030484168838125">選択</translation>
<translation id="161042844686301425">シアン</translation>
-<translation id="1618822247301510817">コピーした画像</translation>
<translation id="1620510694547887537">カメラ</translation>
<translation id="1623104350909869708">このページで追加のダイアログが作成されないようにする</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">セッションを終了</translation>
<translation id="1639239467298939599">読み込み中</translation>
<translation id="1640180200866533862">ユーザー ポリシー</translation>
@@ -133,8 +148,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> では通常、暗号化して情報を保護しています。今回、Google Chrome から <ph name="SITE" /> への接続試行時に、このウェブサイトからいつもとは異なる誤った認証情報が返されました。悪意のあるユーザーが <ph name="SITE" /> になりすまそうとしているか、Wi-Fi ログイン画面で接続が中断された可能性があります。データのやり取りが行われる前に Google Chrome によって接続が停止されたため、情報は引き続き保護されています。</translation>
<translation id="168841957122794586">サーバー証明書に脆弱な暗号鍵が含まれています。</translation>
<translation id="1697532407822776718">設定が完了しました。</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書はおそらく明日以降に利用できるようになります。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。}other{このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。セキュリティ証明書はおそらく # 日後から利用できるようになります。原因として、設定が不適切であるか、悪意のあるユーザーが接続を妨害していることが考えられます。}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">ドキュメントのサイズが大きすぎるため注釈を追加できません</translation>
<translation id="1721312023322545264">このサイトにアクセスするには <ph name="NAME" /> さんの許可が必要です</translation>
<translation id="1721424275792716183">* 必須欄です</translation>
@@ -144,7 +161,8 @@
<translation id="1734864079702812349">AMEX</translation>
<translation id="1734878702283171397">システム管理者にお問い合わせください。</translation>
<translation id="1740951997222943430">有効期限(月)を正しい形式で入力してください</translation>
-<translation id="1743520634839655729">カード、お名前、請求先住所を Google アカウントとこの端末に保存すると、次回のお支払いが簡単になります。</translation>
+<translation id="1743520634839655729">カード、お名前、請求先住所を Google アカウントとこのデバイスに保存すると、次回のお支払いが簡単になります。</translation>
+<translation id="1745880797583122200">ご使用のブラウザは管理されています</translation>
<translation id="17513872634828108">開いているタブ</translation>
<translation id="1753706481035618306">ページ番号</translation>
<translation id="1763864636252898013">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は、ご使用のデバイスのオペレーティング システムによって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">同期パスフレーズを更新してください。</translation>
<translation id="1787142507584202372">最近開いたタブがここに表示されます</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">カード名義人</translation>
<translation id="1821930232296380041">無効なリクエストまたはリクエスト パラメータです</translation>
+<translation id="1822540298136254167">アクセスしたウェブサイトと閲覧時間</translation>
<translation id="1826516787628120939">確認中</translation>
<translation id="1834321415901700177">このサイトには有害なプログラムが含まれています</translation>
<translation id="1839551713262164453">ポリシーの値を検証できませんでした(エラーが発生しました)</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Chrome の閲覧履歴データを削除する</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{他 1 個}other{他 # 個}}</translation>
<translation id="2003709556000175978">今すぐパスワードを再設定してください</translation>
+<translation id="20053308747750172">アクセスしているサーバー <ph name="ORIGIN" /> では、サーバーへのすべてのリクエストにセキュリティ ポリシーを適用することが求められていますが、送信されたポリシーが無効であるため、ブラウザは <ph name="SITE" /> のリクエストを満たすことができません。</translation>
<translation id="2025186561304664664">プロキシは自動設定になっています。</translation>
<translation id="2030481566774242610">もしかして: <ph name="LINK" /></translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />プロキシとファイアウォールを確認する<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">県</translation>
<translation id="2102134110707549001">安全なパスワードを自動生成…</translation>
<translation id="2108755909498034140">パソコンを再起動する</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">カード</translation>
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> によって上書きされるため無視されます。</translation>
<translation id="213826338245044447">モバイルのブックマーク</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">カードを編集</translation>
<translation id="2166049586286450108">すべてのデータへの管理者アクセス</translation>
<translation id="2166378884831602661">このサイトは安全に接続できません</translation>
+<translation id="2169984857010174799">角2(封筒)</translation>
<translation id="2181821976797666341">ポリシー</translation>
<translation id="2183608646556468874">電話番号</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 件のアドレス}other{# 件のアドレス}}</translation>
@@ -213,7 +236,7 @@
<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="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="2224337661447660594">インターネットに接続されていません</translation>
<translation id="2230458221926704099"><ph name="BEGIN_LINK" />診断アプリ<ph name="END_LINK" />を使用して接続を修正してください</translation>
<translation id="2239100178324503013">送信</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">電話番号</translation>
<translation id="2283340219607151381">住所の保存と入力</translation>
<translation id="2292556288342944218">インターネット アクセスがブロックされています</translation>
+<translation id="2294558542833290837">最初に開いたリンクは通常とは異なります</translation>
+<translation id="2297722699537546652">B5(封筒)</translation>
+<translation id="2310021320168182093">長2(封筒)</translation>
<translation id="2316887270356262533">最大で 1 MB を解放します。サイトによっては、次回アクセスする際に読み込みに時間がかかる可能性があります。</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> にはユーザー名とパスワードが必要です。</translation>
<translation id="2317583587496011522">デビットカードをご利用いただけます。</translation>
<translation id="2330137317877982892">「<ph name="CREDIT_CARD" />」の有効期限は <ph name="EXPIRATION_DATE_ABBR" /> です</translation>
<translation id="2337852623177822836">管理者が指定する設定</translation>
+<translation id="2346319942568447007">コピーした画像</translation>
<translation id="2349790679044093737">VR セッションはアクティブです</translation>
<translation id="2354001756790975382">その他のブックマーク</translation>
<translation id="2354430244986887761"><ph name="SITE" /> では最近、Google セーフ ブラウジングにより<ph name="BEGIN_LINK" />有害なアプリが検出<ph name="END_LINK" />されました。</translation>
@@ -235,33 +262,38 @@
<translation id="2356070529366658676">確認する</translation>
<translation id="2359629602545592467">複数</translation>
<translation id="2359808026110333948">続行</translation>
-<translation id="2360873523816792727">お使いのどの端末でも同じカードを使用するには、同期を有効にします。</translation>
+<translation id="2360873523816792727">お使いのどのデバイスでも同じカードを使用するには、同期を有効にします。</translation>
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> に作成されたクラッシュ レポートはアップロードされませんでした</translation>
<translation id="2367567093518048410">レベル</translation>
<translation id="2378238891085281592">プライベート モードです</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は取り消されている可能性があります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
+<translation id="2418081434543109369">アクセスしているサーバー <ph name="ORIGIN" /> では、サーバーへのすべてのリクエストにセキュリティ ポリシーを適用することが求められていますが、ポリシーを送信できなかったため、ブラウザは <ph name="SITE" /> のリクエストを満たすことができません。</translation>
<translation id="244665789865330679">ご使用のデバイスとアカウントは <ph name="ENROLLMENT_DOMAIN" /> で管理されています。管理者はデバイスとアカウントをリモートで設定できます。</translation>
<translation id="2463193859425327265">ホームページを変更する</translation>
<translation id="2463739503403862330">入力する</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">配達方法を選択</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />ネットワーク診断ツールを実行する<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">このページを翻訳</translation>
<translation id="2479410451996844060">検索 URL が無効です。</translation>
<translation id="2482878487686419369">通知</translation>
<translation id="248348093745724435">マシンポリシー</translation>
+<translation id="2485387744899240041">デバイスとブラウザのユーザー名</translation>
<translation id="2491120439723279231">サーバーの証明書にエラーがあります。</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON パーサー</translation>
-<translation id="2495093607237746763">チェックボックスをオンにすると、Chromium がカード情報をこの端末に保存するためフォームにすばやく入力できるようになります。</translation>
+<translation id="2495093607237746763">チェックボックスをオンにすると、Chromium がカード情報をこのデバイスに保存するためフォームにすばやく入力できるようになります。</translation>
<translation id="2498091847651709837">新しいカードをスキャン</translation>
<translation id="2501278716633472235">戻る</translation>
<translation id="2503184589641749290">利用可能なデビットカードとプリペイド カード</translation>
<translation id="2515629240566999685">電波状況を確認する</translation>
-<translation id="2516852381693169964"><ph name="SEARCH_ENGINE" /> で画像を検索</translation>
<translation id="2523886232349826891">カードはこのデバイスのみに保存されます</translation>
<translation id="2524461107774643265">その他の情報の追加</translation>
<translation id="2536110899380797252">住所を追加</translation>
@@ -273,6 +305,7 @@
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">このドキュメントはパスワードで保護されています。パスワードを入力してください。</translation>
<translation id="2609632851001447353">バリエーション</translation>
+<translation id="2618023639789766142">C10(封筒)</translation>
<translation id="2625385379895617796">時計が進んでいます</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> のサーバーの IP アドレスが見つかりませんでした。</translation>
<translation id="2639739919103226564">ステータス:</translation>
@@ -282,13 +315,15 @@
<translation id="2666117266261740852">他のタブやアプリを閉じる</translation>
<translation id="267371737713284912">元に戻すには <ph name="MODIFIER_KEY_DESCRIPTION" /> を押します</translation>
<translation id="2674170444375937751">履歴からこれらのページを削除してもよろしいですか?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">このページを離れる</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">利用可能なカード</translation>
<translation id="2702801445560668637">リーディング リスト</translation>
<translation id="2704283930420550640">値が有効な形式ではありません。</translation>
<translation id="2705137772291741111">このサイトの保存(キャッシュ)されたコピーを読み取れませんでした。</translation>
<translation id="2709516037105925701">自動入力</translation>
-<translation id="2712173769900027643">権限をリクエスト</translation>
+<translation id="2712173769900027643">許可をリクエスト</translation>
<translation id="2713444072780614174">白</translation>
<translation id="2720342946869265578">周辺</translation>
<translation id="2721148159707890343">リクエストを正常に送信しました</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">選択したアイテムを削除</translation>
<translation id="277133753123645258">配送方法</translation>
<translation id="277499241957683684">デバイス レコードがありません</translation>
-<translation id="2781030394888168909">Mac OS 形式でエクスポート</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">接続がリセットされました。</translation>
<translation id="2788784517760473862">利用可能なクレジット カード</translation>
@@ -311,8 +345,10 @@
<translation id="2826760142808435982">接続は <ph name="CIPHER" /> を使用して暗号化および認証されており、<ph name="KX" /> が鍵交換メカニズムとして使用されています。</translation>
<translation id="2835170189407361413">フォームをクリア</translation>
<translation id="2847118875340931228">シークレット ウィンドウを開く</translation>
+<translation id="2850739647070081192">Invite(封筒)</translation>
<translation id="2851634818064021665">このサイトにアクセスするには許可が必要です</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">カードを保存しますか?</translation>
<translation id="2903493209154104877">住所</translation>
<translation id="290376772003165898"><ph name="LANGUAGE" />のページではない場合:</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">配達方法</translation>
<translation id="2928905813689894207">請求先住所</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は <ph name="DOMAIN2" /> から発行されています。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="2948083400971632585">接続用に設定されたプロキシは、設定ページで無効にできます。</translation>
<translation id="2955913368246107853">検索バーを閉じる</translation>
@@ -329,7 +366,7 @@
<translation id="2972581237482394796">やり直し(&amp;R)</translation>
<translation id="2977665033722899841"><ph name="ROW_NAME" />が現在選択されています。<ph name="ROW_CONTENT" /></translation>
<translation id="2982481275546140226">データを削除</translation>
-<translation id="2985306909656435243">有効にすると、Chromium がカード情報をこの端末に保存するためフォームにすばやく入力できるようになります。</translation>
+<translation id="2985306909656435243">有効にすると、Chromium がカード情報をこのデバイスに保存するためフォームにすばやく入力できるようになります。</translation>
<translation id="2985398929374701810">有効な住所を入力してください</translation>
<translation id="2986368408720340940">この受け取り方法はご利用いただけません。別の方法を選択してください。</translation>
<translation id="2991174974383378012">ウェブサイトとの共有</translation>
@@ -338,11 +375,14 @@
<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="3023071826883856138">洋4(封筒)</translation>
<translation id="3024663005179499861">ポリシー タイプが間違っています</translation>
<translation id="3037605927509011580">エラー</translation>
<translation id="3041612393474885105">証明書情報</translation>
+<translation id="3060227939791841287">C9(封筒)</translation>
<translation id="3064966200440839136">外部アプリケーションを経由したお支払いの処理に進むため、シークレット モードを解除します。続行しますか?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{なし}=1{1 個のパスワード}other{# 個のパスワード}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">集荷先住所を追加</translation>
<translation id="3105172416063519923">アセット ID:</translation>
<translation id="3109728660330352905">このページを表示する権限がありません。</translation>
@@ -364,20 +404,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" />(<ph name="SERVER_NAME" /> 上)</translation>
<translation id="320323717674993345">支払いをキャンセル</translation>
<translation id="3207960819495026254">ブックマークしました</translation>
-<translation id="3209375525920864198">有効なセッション名を入力してください。</translation>
+<translation id="321912867715453276">警告: ポリシーに複数のソースがありますが、値は同一です。</translation>
<translation id="3225919329040284222">サーバーの提示した証明書が、組み込まれている想定の証明書と一致しません。これらの想定の証明書は、ユーザー保護のため、特定の安全性の高いウェブサイトについて用意されています。</translation>
<translation id="3226128629678568754">ページの読み込みに必要なデータを再送信するには、再読み込みボタンを押してください。</translation>
<translation id="3227137524299004712">マイク</translation>
<translation id="3228969707346345236">このページは既に<ph name="LANGUAGE" />なので、翻訳できません。</translation>
+<translation id="3229041911291329567">デバイスとブラウザに関するバージョン情報</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">名義人名を追加</translation>
<translation id="3287510313208355388">オンライン時にダウンロード</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> ポリシーの詳細</translation>
<translation id="3303855915957856445">一致する結果は見つかりませんでした</translation>
-<translation id="3305707030755673451">データは <ph name="TIME" /> に同期パスフレーズで暗号化されました。同期を開始するには、同期パスフレーズを入力してください。</translation>
<translation id="3320021301628644560">請求先住所を追加</translation>
<translation id="3324983252691184275">クリムゾン</translation>
<translation id="3338095232262050444">保護された通信</translation>
@@ -404,10 +445,12 @@
<translation id="3427092606871434483">許可(デフォルト)</translation>
<translation id="3427342743765426898">編集のやり直し(&amp;R)</translation>
<translation id="342781501876943858">パスワードを他のサイトで再使用した場合、Chromium ではパスワードの再設定を促すメッセージが表示されます。</translation>
-<translation id="3431636764301398940">このカード情報をこの端末に保存する</translation>
+<translation id="3431636764301398940">このカード情報をこのデバイスに保存する</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">このデバイスの所有者が恐竜ゲームを無効にしています。</translation>
<translation id="3447884698081792621">証明書(発行元: <ph name="ISSUER" />)を表示</translation>
<translation id="3452404311384756672">取得間隔:</translation>
+<translation id="3456231139987291353">Number-11(封筒)</translation>
<translation id="3461824795358126837">蛍光ペン</translation>
<translation id="3462200631372590220">詳細情報を表示しない</translation>
<translation id="3467763166455606212">カード名義人は必須です</translation>
@@ -430,20 +473,23 @@
<translation id="358285529439630156">クレジット カードとプリペイド カードをご利用いただけます。</translation>
<translation id="3582930987043644930">名前を追加</translation>
<translation id="3583757800736429874">移動のやり直し(&amp;R)</translation>
+<translation id="35866233670761917">管理者はユーザーがアクセスするウェブサイトのコンテンツを監視していません</translation>
<translation id="3586931643579894722">詳細を非表示</translation>
+<translation id="3592413004129370115">Italian(封筒)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />、<ph name="DOMAIN" />、<ph name="TIME" /></translation>
<translation id="3614103345592970299">サイズ 2</translation>
<translation id="3615877443314183785">有効期限(日)を入力してください</translation>
-<translation id="36224234498066874">閲覧履歴を消去...</translation>
+<translation id="36224234498066874">閲覧履歴データを削除...</translation>
<translation id="362276910939193118">全履歴を表示</translation>
-<translation id="3623476034248543066">値を表示</translation>
<translation id="3630155396527302611">ネットワークへのアクセスを許可されたプログラムとして既に表示されている場合は、
いったんリストから削除し、もう一度追加してみてください。</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">検証が正常に完了しました</translation>
<translation id="3655670868607891010">このエラーが頻繁に表示される場合は、こちらの<ph name="HELP_LINK" />をお試しください。</translation>
<translation id="3658742229777143148">変更履歴</translation>
<translation id="366077651725703012">クレジット カードを更新する</translation>
-<translation id="3676592649209844519">端末 ID:</translation>
+<translation id="3676592649209844519">デバイス ID:</translation>
+<translation id="3677008721441257057">もしかして: &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;</translation>
<translation id="3678029195006412963">リクエストに署名できませんでした</translation>
<translation id="3678529606614285348">ページを新しいシークレット ウィンドウで開く(Ctrl-Shift-N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" /> にクラッシュ レポートが作成され、<ph name="UPLOAD_TIME" /> にアップロードされました</translation>
@@ -451,13 +497,14 @@
<translation id="3704162925118123524">ご利用のネットワークでは、ログインページへのアクセスが必要な可能性があります。</translation>
<translation id="3704609568417268905"><ph name="TIME" />、<ph name="TITLE" />(<ph name="DOMAIN" />)を<ph name="BOOKMARKED" /></translation>
<translation id="370665806235115550">読み込んでいます...</translation>
+<translation id="3709599264800900598">コピーしたテキスト</translation>
<translation id="3712624925041724820">ライセンスを使い切りました</translation>
<translation id="3714780639079136834">モバイルデータまたは Wi-Fi を有効にする</translation>
<translation id="3715597595485130451">Wi-Fi 接続</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />プロキシ、ファイアウォール、DNS の設定を確認する<ph name="END_LINK" /></translation>
<translation id="372429172604983730">このエラーの原因としては、ウィルス対策ソフトウェア、ファイアウォール ソフトウェア、ウェブ フィルタリング ソフトウェア、プロキシ ソフトウェアなどが考えられます。</translation>
+<translation id="373042150751172459">B4(封筒)</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="3745099705178523657">確認後、Google アカウントのカード情報がこのサイトと共有されます。</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>
@@ -465,15 +512,17 @@
<translation id="3759461132968374835">最近発生した障害はありません。障害レポートが無効になっているときに発生した障害は、ここには表示されません。</translation>
<translation id="3761718714832595332">ステータスを表示しない</translation>
<translation id="3765032636089507299">セーフ ブラウジング ページは準備中です。</translation>
-<translation id="3778403066972421603">このカードを Google アカウントとこの端末に保存しますか?</translation>
+<translation id="3778403066972421603">このカードを Google アカウントとこのデバイスに保存しますか?</translation>
<translation id="3781428340399460090">ホットピンク</translation>
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">有効期限: <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">サイズ 16</translation>
+<translation id="3797522431967816232">Prc3(封筒)</translation>
<translation id="3807873520724684969">有害なコンテンツがブロックされました。</translation>
<translation id="3810973564298564668">管理</translation>
<translation id="382518646247711829">プロキシ サーバーを使用している場合...</translation>
<translation id="3828924085048779000">パスフレーズは必ず指定してください。</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> によって、機能を追加する拡張機能がインストールされました。この拡張機能では、ユーザーデータの一部にアクセスする場合があります。</translation>
<translation id="385051799172605136">戻る</translation>
<translation id="3858027520442213535">日時を更新</translation>
<translation id="3884278016824448484">競合するデバイス識別子です</translation>
@@ -481,6 +530,7 @@
<translation id="3886446263141354045">このサイトへのアクセス リクエストを <ph name="NAME" /> さんに送信しました</translation>
<translation id="3890664840433101773">メールを追加</translation>
<translation id="3901925938762663762">カードの有効期限が切れています</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">このサイトでは常に確認</translation>
<translation id="3949571496842715403">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書で SAN(サブジェクトの別名)が指定されていません。設定が不適切であるか、悪意のあるユーザーによって接続が妨害されている可能性があります。</translation>
@@ -491,11 +541,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{なし}=1{1 件のサイトから}other{# 件のサイトから}}</translation>
<translation id="397105322502079400">計算しています...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> はブロックされています</translation>
-<translation id="3984550557525787191">そのセッション名はすでに存在しています。</translation>
<translation id="3987940399970879459">1 MB 未満</translation>
+<translation id="4008849406247176967">警告: このポリシーには、値が競合する複数のソースがあります。</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 件の近くのウェブページ}other{# 件の近くのウェブページ}}</translation>
<translation id="4030383055268325496">追加の取り消し(&amp;U)</translation>
+<translation id="4032320456957708163">ご使用のブラウザは <ph name="ENROLLMENT_DOMAIN" /> によって管理されています</translation>
<translation id="4058922952496707368">キー「<ph name="SUBKEY" />」: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1(封筒)</translation>
<translation id="4067947977115446013">有効なアドレスの追加</translation>
<translation id="4072486802667267160">ご注文の処理中にエラーが発生しました。もう一度お試しください。</translation>
<translation id="4075732493274867456">クライアントとサーバーで、共通の SSL プロトコル バージョンまたは暗号スイートがサポートされていません。</translation>
@@ -515,10 +567,12 @@
<translation id="4159784952369912983">パープル</translation>
<translation id="4165986682804962316">サイトの設定</translation>
<translation id="4171400957073367226">確認用の署名に問題があります</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{他 <ph name="ITEM_COUNT" /> 件のアイテム}other{他 <ph name="ITEM_COUNT" /> 件のアイテム}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">移動のやり直し(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ファイアウォールとウイルス対策の設定を確認する<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9(封筒)</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="4221630205957821124">&lt;h4&gt;ステップ 1: ポータルにログインする&lt;/h4&gt;
@@ -531,7 +585,7 @@
&lt;p&gt;アクセスしたページをシークレット ウィンドウで開きます。&lt;/p&gt;
&lt;p&gt;この方法でページが表示された場合は、Chrome の拡張機能に問題があります。エラーを解決するには、問題のある拡張機能を無効にしてください。&lt;/p&gt;
&lt;h4&gt;ステップ 3: オペレーティング システムを更新する&lt;/h4&gt;
- &lt;p&gt;端末が最新の状態であることを確認します。&lt;/p&gt;
+ &lt;p&gt;デバイスが最新の状態であることを確認します。&lt;/p&gt;
&lt;h4&gt;ステップ 4: ウィルス対策ソフトウェアを一時的に無効にする&lt;/h4&gt;
&lt;p&gt;このエラーは、「HTTPS 保護」や「HTTPS スキャン」などの機能を備えたウィルス対策ソフトウェアを使用している場合に表示されます。こうしたウィルス対策ソフトウェアにより、Chrome のセキュリティが適用されなくなっています。&lt;/p&gt;
&lt;p&gt;問題を解決するには、ウィルス対策ソフトウェアを無効にします。無効にするとページを利用できるようになる場合は、セキュリティで保護されたサイトにアクセスするときにこのソフトウェアを無効にしてください。&lt;/p&gt;
@@ -550,58 +604,79 @@
<translation id="4277028893293644418">パスワードを再設定</translation>
<translation id="4280429058323657511">、有効期限: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{このカードを Google アカウントに保存しました}other{これらのカードを Google アカウントに保存しました}}</translation>
+<translation id="42981349822642051">展開</translation>
+<translation id="4302965934281694568">長3(封筒)</translation>
<translation id="4305817255990598646">切り替え</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">ブロック(デフォルト)</translation>
+<translation id="4318566738941496689">デバイスの名前とネットワーク アドレス</translation>
<translation id="4325863107915753736">記事が見つかりませんでした</translation>
<translation id="4326324639298822553">有効期限の「日」を確認してもう一度お試しください</translation>
<translation id="4331708818696583467">保護されていない通信</translation>
<translation id="4340982228985273705">このパソコンは企業の管理対象として検出されていないため、ポリシーで自動的にインストールできるのは Chrome ウェブストアでホストされている拡張機能のみとなります。Chrome ウェブストアの更新 URL は「<ph name="CWS_UPDATE_URL" />」です。</translation>
<translation id="4346197816712207223">利用可能なクレジット カード</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">このサイトを利用すると、悪意のあるユーザーによって、危険なプログラム(写真、パスワード、メッセージ、クレジット カード番号などの情報を盗み取るか削除するプログラム)がお使いのパソコンにインストールされる可能性があります。</translation>
<translation id="4358461427845829800">お支払い方法を管理...</translation>
+<translation id="4367563149485757821">Number-12(封筒)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948"><ph name="VALUE_TYPE" /> 値が想定されます。</translation>
<translation id="4377125064752653719"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから提示された証明書は発行元により取り消されています。これは、サーバーから提示されたセキュリティ認証情報が信頼できないことを示しており、悪意のあるユーザーと通信しようとしている可能性があります。</translation>
<translation id="4378154925671717803">電話</translation>
<translation id="4406896451731180161">検索結果</translation>
-<translation id="4406972042435603828">管理者が強力な機能を持つ拡張機能をインストールしました。</translation>
<translation id="4408413947728134509">Cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">集荷先住所</translation>
<translation id="4424024547088906515">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は Chrome によって信頼されているものではありません。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
+<translation id="443121186588148776">シリアルポート</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> でログイン証明書が承認されなかったか、ログイン証明書が提示されていない可能性があります。</translation>
<translation id="4434045419905280838">ポップアップとリダイレクト</translation>
+<translation id="4435702339979719576">ポストカード</translation>
<translation id="443673843213245140">プロキシの使用は無効ですが、プロキシの設定が明示的に指定されています。</translation>
<translation id="445100540951337728">利用可能なデビットカード</translation>
+<translation id="4466881336512663640">フォームの変更内容は破棄されます。続行してもよろしいですか?</translation>
<translation id="4482953324121162758">このサイトは翻訳されません。</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL が無効です。標準のスキームを使用した URL を指定してください(例: http://example.com、https://example.com)。</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">検証エラー: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">システム管理者に問い合わせる</translation>
<translation id="450710068430902550">管理者との共有</translation>
+<translation id="4510487217173779431">長4(封筒)</translation>
<translation id="4515275063822566619">Chrome と Google アカウント(<ph name="ACCOUNT_EMAIL" />)に保存されているクレジット カードと住所です。[<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] で管理できます。</translation>
+<translation id="4517607026994743406">Comm-10(封筒)</translation>
<translation id="4522570452068850558">詳細</translation>
<translation id="4524805452350978254">カードを管理</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">拡張機能を無効にしてみてください。</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">配送</translation>
+<translation id="4579056131138995126">Personal(封筒)</translation>
<translation id="4582204425268416675">カードを削除</translation>
<translation id="4587425331216688090">Chrome からアドレスを削除してもよろしいですか?</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> への接続は新しい暗号スイートにより暗号化されています。</translation>
<translation id="4594403342090139922">削除の取り消し(&amp;U)</translation>
<translation id="4597348597567598915">サイズ 8</translation>
+<translation id="4600854749408232102">C6 / C5(封筒)</translation>
<translation id="4646534391647090355">今すぐ表示</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書にはエラーがあります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
<translation id="467809019005607715">Google スライド</translation>
<translation id="4690462567478992370">無効な証明書の使用をやめる</translation>
+<translation id="4691835149146451662">Architecture-A(封筒)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">接続が中断されました</translation>
<translation id="471880041731876836">このサイトへのアクセスが許可されていません</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows ネットワーク診断ツールを実行する<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">ポリシーを再読み込み</translation>
<translation id="4728558894243024398">プラットフォーム</translation>
+<translation id="4731967714531604179">Prc2(封筒)</translation>
<translation id="4736825316280949806">Chromium を再起動する</translation>
<translation id="473775607612524610">更新</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> の検索候補</translation>
<translation id="4742407542027196863">パスワードを管理…</translation>
<translation id="4744603770635761495">実行ファイルのパス</translation>
+<translation id="4746351372139058112">メッセージ</translation>
<translation id="4750917950439032686">お客様がこのサイトに送信した情報(パスワード、クレジット カード番号など)が第三者に見られることはありません。</translation>
<translation id="4756388243121344051">履歴(&amp;H)</translation>
<translation id="4758311279753947758">連絡先情報を追加</translation>
@@ -609,9 +684,9 @@
<translation id="4764776831041365478"><ph name="URL" /> のウェブページは一時的に停止しているか、新しいウェブアドレスに移動した可能性があります。</translation>
<translation id="4771973620359291008">不明なエラーが発生しました。</translation>
<translation id="4785689107224900852">このタブに切り替え</translation>
-<translation id="4792143361752574037">セッション ファイルにアクセスする際に問題が発生しました。現在、ディスクに保存することはできません。ページを再読み込みしてもう一度お試しください。</translation>
<translation id="4798078619018708837">カード情報を更新するには <ph name="CREDIT_CARD" /> の有効期限と CVC を入力します。確認後、Google アカウントのカード情報がこのサイトと共有されます。</translation>
<translation id="4800132727771399293">有効期限と CVC を確認してからもう一度お試しください</translation>
+<translation id="480334179571489655">元のポリシーエラー</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>
@@ -626,7 +701,6 @@
<translation id="4881695831933465202">開く</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>
@@ -635,15 +709,15 @@
<translation id="4943872375798546930">結果はありません</translation>
<translation id="4950898438188848926">タブの切り替えボタンです。Enter キーを押すと開いているタブ「<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />」に切り替わります</translation>
<translation id="495170559598752135">操作</translation>
-<translation id="495832697253704892">拡張機能に関するレポート</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">リストを展開する</translation>
<translation id="4974590756084640048">警告を再度有効にする</translation>
+<translation id="4984339528288761049">Prc5(封筒)</translation>
<translation id="4989163558385430922">すべて表示</translation>
<translation id="4989809363548539747">このプラグインはサポートされていません</translation>
-<translation id="4996230189582812866">レポート</translation>
-<translation id="5002932099480077015">有効にすると、Chrome ではこの端末にカードのコピーが保存されます。これにより、フォームにすばやく入力できるようになります。</translation>
-<translation id="5014174725590676422">Chrome の Google アシスタントの初回実行画面が表示されました</translation>
+<translation id="5002932099480077015">有効にすると、Chrome ではこのデバイスにカードのコピーが保存されます。これにより、フォームにすばやく入力できるようになります。</translation>
<translation id="5015510746216210676">マシン名:</translation>
+<translation id="5017554619425969104">コピーしたテキスト</translation>
<translation id="5018422839182700155">このページを開けません</translation>
<translation id="5019198164206649151">代替ストアの状態が不適切です</translation>
<translation id="5023310440958281426">管理者のポリシーを確認してください</translation>
@@ -653,35 +727,51 @@
<translation id="5034369478845443529">ローカル コンテキスト <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">許可</translation>
<translation id="5040262127954254034">プライバシー</translation>
+<translation id="5043480802608081735">コピーしたリンク</translation>
<translation id="5045550434625856497">パスワードが正しくありません</translation>
<translation id="5056549851600133418">おすすめの記事</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />プロキシ アドレスを確認する<ph name="END_LINK" /></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="5097099694988056070">CPU や RAM の使用率などのデバイスの統計情報</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">ご使用のデバイスは <ph name="ENROLLMENT_DOMAIN" /> で管理され、アカウントは <ph name="ACCOUNT_DOMAIN" /> で管理されています。それぞれの管理者はデバイスやアカウントをリモートで設定できます。</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 ビット)</translation>
-<translation id="5128122789703661928">セッションの名前が有効でないため、削除できません。</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">住所を管理...</translation>
+<translation id="5138227688689900538">一部を表示</translation>
<translation id="5141240743006678641">Google の認証情報で同期パスワードを暗号化する</translation>
<translation id="5145883236150621069">ポリシー応答内にエラー コードがあります</translation>
+<translation id="515292512908731282">C4(封筒)</translation>
<translation id="5159010409087891077">ページを新しいシークレット ウィンドウで開く(⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> の CVC を入力します。確認後、Google アカウントのカード情報がこのサイトと共有されます。</translation>
<translation id="5169827969064885044">組織のアカウントにアクセスできなくなったり、個人情報が盗まれたりする可能性があります。今すぐパスワードを変更することをおすすめします。</translation>
<translation id="5171045022955879922">検索または URL を入力</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">マシン</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />でない場合はこのエラーを報告する</translation>
<translation id="5190835502935405962">ブックマーク バー</translation>
-<translation id="5200263511887412697">最近ログインしたデバイス ユーザーのリストを報告します</translation>
+<translation id="519422657042045905">注釈は使用できません</translation>
<translation id="5201306358585911203">このページに埋め込まれているページの内容</translation>
<translation id="5205222826937269299">名前は必須です</translation>
<translation id="5215116848420601511">Google Pay のお支払い方法と住所</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">メールアドレスは必須です</translation>
<translation id="5230733896359313003">配送先住所</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">「ネットワークに接続してください」</translation>
<translation id="5251803541071282808">クラウド</translation>
+<translation id="5252000469029418751">C7(封筒)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">ネットワーク アドレス</translation>
<translation id="5285570108065881030">保存したパスワードをすべて表示</translation>
<translation id="5287240709317226393">Cookie を表示</translation>
<translation id="5288108484102287882">ポリシー値の検証で警告が返されました</translation>
@@ -693,16 +783,19 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />、<ph name="MATCH_POSITION" />/<ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">連絡作情報を選択</translation>
<translation id="5327248766486351172">名前</translation>
+<translation id="5329858041417644019">ご使用のブラウザは管理されていません</translation>
<translation id="5332219387342487447">配送方法</translation>
+<translation id="5334013548165032829">詳細なシステムログ</translation>
<translation id="5344579389779391559">このページでは課金される恐れがあります</translation>
<translation id="5355557959165512791"><ph name="SITE" /> は証明書が失効しているため、現在アクセスできません。通常、ネットワーク エラーやネットワークへの攻撃は一時的なものです。しばらくするとページにアクセスできるようになります。</translation>
<translation id="536296301121032821">ポリシー設定を保存できませんでした</translation>
<translation id="5371425731340848620">カードを更新</translation>
<translation id="5377026284221673050">「時計が遅れています」、「時計が進んでいます」、「&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;」</translation>
-<translation id="5384855140246857529">お使いのどの端末でも同じカードを使用するには、ログインして同期を有効にします。</translation>
+<translation id="5384855140246857529">お使いのどのデバイスでも同じカードを使用するには、ログインして同期を有効にします。</translation>
<translation id="5386426401304769735">このサイトの証明書チェーンには SHA-1 を使って署名された証明書が含まれています。</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は現在有効ではありません。設定が不適切か、悪意のあるユーザーによって接続が妨害されている可能性があります。</translation>
-<translation id="5421136146218899937">閲覧履歴データの消去...</translation>
+<translation id="5421136146218899937">閲覧履歴データを削除...</translation>
<translation id="5430298929874300616">ブックマークを削除</translation>
<translation id="5431657950005405462">ファイルが見つかりませんでした</translation>
<translation id="5439770059721715174">「<ph name="ERROR_PATH" />」でスキーマ確認エラー: <ph name="ERROR" /></translation>
@@ -711,6 +804,7 @@
<translation id="5457113250005438886">無効</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">編集のやり直し(&amp;R)</translation>
+<translation id="5478437291406423475">B6 / C4(封筒)</translation>
<translation id="5481076368049295676">アクセス先のコンテンツによって、個人情報を入手したり削除したりする危険なソフトウェアがインストールされる可能性があります。<ph name="BEGIN_LINK" />危険性を理解したうえで表示する<ph name="END_LINK" /></translation>
<translation id="54817484435770891">有効なアドレスを追加</translation>
<translation id="5490432419156082418">住所やその他の情報</translation>
@@ -718,10 +812,12 @@
<ph name="LINE_BREAK" />
システム管理者にお問い合わせください。</translation>
<translation id="549333378215107354">サイズ 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">管理対象のブックマーク</translation>
<translation id="5510766032865166053">移動または削除された可能性があります。</translation>
<translation id="5523118979700054094">ポリシー名</translation>
<translation id="552553974213252141">テキストは正しく抽出されましたか?</translation>
+<translation id="553484882784876924">Prc6(封筒)</translation>
<translation id="5540224163453853">リクエストされた記事が見つかりませんでした。</translation>
<translation id="5541546772353173584">メールの追加</translation>
<translation id="5545756402275714221">おすすめの記事</translation>
@@ -736,55 +832,62 @@
<translation id="5595485650161345191">住所の編集</translation>
<translation id="5598944008576757369">お支払い方法を選択</translation>
<translation id="560412284261940334">管理はサポートされていません</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">接続を確認する</translation>
<translation id="5610807607761827392">カードと住所は [<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] で管理できます。</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> でリダイレクトが繰り返し行われました。</translation>
<translation id="5629630648637658800">ポリシー設定を読み込めませんでした</translation>
<translation id="5631439013527180824">無効なデバイス管理トークンです</translation>
+<translation id="5632627355679805402">データは <ph name="TIME" />に <ph name="BEGIN_LINK" />Google パスワード<ph name="END_LINK" />で暗号化されました。同期を開始するにはパスフレーズを入力してください。</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="563324245173044180">不正の可能性があるコンテンツがブロックされました。</translation>
<translation id="5659593005791499971">メール</translation>
+<translation id="5663614846592581799">9x11(封筒)</translation>
+<translation id="5663955426505430495">このデバイスの管理者によって、機能を追加する拡張機能がインストールされました。この拡張機能では、ユーザーデータの一部にアクセスする場合があります。</translation>
<translation id="5675650730144413517">このページは動作していません</translation>
+<translation id="5684874026226664614">このページを翻訳できませんでした。</translation>
<translation id="5685654322157854305">配送先住所を追加</translation>
<translation id="5689199277474810259">JSON にエクスポート</translation>
-<translation id="5689516760719285838">現在地</translation>
+<translation id="5689516760719285838">位置情報</translation>
<translation id="570530837424789914">管理...</translation>
<translation id="57094364128775171">安全なパスワードを自動生成…</translation>
<translation id="5710435578057952990">このウェブサイトの ID は確認されていません。</translation>
<translation id="5719499550583120431">プリペイド カードをご利用いただけます。</translation>
<translation id="5720705177508910913">現在のユーザー</translation>
+<translation id="5728056243719941842">C5(封筒)</translation>
<translation id="5730040223043577876">パスワードを他のサイトで再使用した場合、Chrome ではパスワードの再設定を促すメッセージが表示されます。</translation>
<translation id="5732392974455271431">ブロックの解除は保護者が行うことができます</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Google アカウントにカードを保存}other{Google アカウントにカードを保存}}</translation>
<translation id="5763042198335101085">有効なメールアドレスを入力してください</translation>
<translation id="5765072501007116331">配達方法と要件を確認するには、住所を選択してください</translation>
-<translation id="5770114862687765385">ファイルが壊れているようです。[リセット] ボタンをクリックしてセッションをリセットしてください。</translation>
<translation id="5778550464785688721">MIDI デバイスのフル コントロール</translation>
<translation id="578305955206182703">アンバー</translation>
<translation id="57838592816432529">ミュート</translation>
<translation id="5784606427469807560">カードの確認中に問題が発生しました。インターネット接続を確認してもう一度お試しください。</translation>
<translation id="5785756445106461925">加えて、このページには安全でない他のリソースが含まれています。このリソースは送信中に他のユーザーから見られる可能性があります。また、悪意のあるユーザーによって改変されページの見た目が変わる可能性もあります。</translation>
<translation id="5786044859038896871">カード情報を入力しますか?</translation>
+<translation id="5798290721819630480">変更を破棄しますか?</translation>
<translation id="5798683403665926540">Chrome の設定でホームページを変更します</translation>
<translation id="5803412860119678065"><ph name="CARD_DETAIL" /> を入力しますか?</translation>
<translation id="5804241973901381774">権限</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" /> への接続は古い暗号スイートにより暗号化されています。</translation>
<translation id="5813119285467412249">追加のやり直し(&amp;R)</translation>
<translation id="5838278095973806738">このサイトでは機密情報(パスワード、クレジット カードなど)を入力しないでください。悪意のあるユーザーに情報が盗まれる恐れがあります。</translation>
+<translation id="5860033963881614850">オフ</translation>
<translation id="5863847714970149516">表示しようとしているページでは課金される恐れがあります</translation>
<translation id="5866257070973731571">電話番号の追加</translation>
<translation id="5869405914158311789">このサイトにアクセスできません</translation>
<translation id="5869522115854928033">保存したパスワード</translation>
<translation id="5887400589839399685">カードが保存されました</translation>
-<translation id="5893718151540690985">ネットワーク インターフェースの種類とハードウェア アドレスのリストを報告します</translation>
<translation id="5893752035575986141">クレジット カードをご利用いただけます。</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="5916664084637901428">オン</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">カードを Google アカウントに保存しますか?</translation>
<translation id="5922853866070715753">ほぼ完了です</translation>
<translation id="5932224571077948991">このサイトでは煩わしい広告や誤解を招く広告が表示されます</translation>
-<translation id="5939518447894949180">リセット</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> を開いています…</translation>
<translation id="5951495562196540101">一般ユーザー向けアカウントでは登録できません(ライセンス パッケージが利用可能です)。</translation>
<translation id="5967592137238574583">連絡先情報の編集</translation>
@@ -792,6 +895,7 @@
<translation id="5975083100439434680">縮小する</translation>
<translation id="5977489021191000276">お使いのデバイスは管理者によって管理されていません。</translation>
<translation id="5977976211062815271">このデバイス</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">お支払いアプリを開けません</translation>
<translation id="5989320800837274978">固定プロキシ サーバーと .pac スクリプト URL のどちらも指定されていません。</translation>
<translation id="5990559369517809815">サーバーへのリクエストは拡張機能によってブロックされています。</translation>
@@ -802,8 +906,8 @@
<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="6033927989869462158">CPU や RAM の使用率などのハードウェア統計情報を報告します</translation>
<translation id="6034000775414344507">ライトグレー</translation>
+<translation id="6034283069659657473">10x14(封筒)</translation>
<translation id="6039846035001940113">この問題が何度も発生する場合は、サイト所有者にお問い合わせください。</translation>
<translation id="6040143037577758943">閉じる</translation>
<translation id="6044573915096792553">サイズ 12</translation>
@@ -812,18 +916,18 @@
<translation id="6051221802930200923"><ph name="SITE" /> では証明書ピンニングが使用されているため、現在アクセスできません。通常、ネットワーク エラーやネットワークへの攻撃は一時的なものです。しばらくするとページにアクセスできるようになります。</translation>
<translation id="6058977677006700226">お使いのどのデバイスでも同じカードを使用できるようにしかすか?</translation>
<translation id="6059925163896151826">USB デバイス</translation>
-<translation id="6071091556643036997">ポリシーのタイプが無効です。</translation>
<translation id="6080696365213338172">管理者が提供する証明書を使用してコンテンツにアクセスしています。<ph name="DOMAIN" /> に提供するデータは管理者によって傍受される可能性があります。</translation>
<translation id="6094273045989040137">注釈を追加</translation>
<translation id="610911394827799129">お使いの Google アカウントの <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> に、他の形式の閲覧履歴が記録されている場合があります</translation>
+<translation id="6132597952260690497">インストールされている拡張機能とプラグインに関する情報</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{なし}=1{1 個のパスワード(同期済み)}other{# 個のパスワード(同期済み)}}</translation>
<translation id="6146055958333702838">ケーブルを確認し、使用しているネットワーク デバイス(ルーター、モデムなど)を
再起動してください。</translation>
-<translation id="614940544461990577">次をお試しください:</translation>
+<translation id="614940544461990577">次をお試しください</translation>
<translation id="6151417162996330722">サーバー証明書の有効期限が長すぎます。</translation>
<translation id="6157877588268064908">配送方法と要件を確認するには、住所を選択してください</translation>
-<translation id="6165508094623778733">詳しく見る</translation>
-<translation id="6169916984152623906">現在、シークレット モードで閲覧しています。あなたのアクティビティは、この端末を利用する他のユーザーには表示されません。ただし、ダウンロードしたファイルとブックマークは通常どおり保存されます。</translation>
+<translation id="6165508094623778733">詳細</translation>
+<translation id="6169916984152623906">現在、シークレット モードで閲覧しています。あなたのアクティビティは、このデバイスを利用する他のユーザーには表示されません。ただし、ダウンロードしたファイルとブックマークは通常どおり保存されます。</translation>
<translation id="6177128806592000436">このサイトへの接続は保護されていません</translation>
<translation id="6203231073485539293">インターネット接続を確認してください</translation>
<translation id="6218753634732582820">Chromium からアドレスを削除してもよろしいですか?</translation>
@@ -850,15 +954,21 @@
<translation id="6337133576188860026">最大で <ph name="SIZE" /> を解放します。サイトによっては、次回アクセスする際に読み込みに時間がかかる可能性があります。</translation>
<translation id="6337534724793800597">ポリシーを名前でフィルタ</translation>
<translation id="6358450015545214790">ヘルプ</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">続行すると料金が請求される可能性があります。</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{他 1 件の候補}other{他 # 件の候補}}</translation>
-<translation id="6387754724289022810">カードと請求先住所を Google アカウントとこの端末に保存すると、次回のお支払いが簡単になります。</translation>
+<translation id="6387754724289022810">カードと請求先住所を Google アカウントとこのデバイスに保存すると、次回のお支払いが簡単になります。</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">ブックマークを編集</translation>
+<translation id="6406765186087300643">C0(封筒)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> の有効期限と CVC を入力</translation>
<translation id="6414888972213066896">このサイトを開いてもよいかの問い合わせを保護者に送信しました</translation>
<translation id="6417515091412812850">証明書が取り消されたかどうかを確認できません。</translation>
<translation id="6433490469411711332">連絡先情報の編集</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> で接続が拒否されました。</translation>
+<translation id="6434309073475700221">破棄</translation>
+<translation id="6446163441502663861">Kahu(封筒)</translation>
<translation id="6446608382365791566">他の情報を追加</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">フォーム再送信の確認</translation>
@@ -871,11 +981,17 @@
<translation id="6508722015517270189">Chrome を再起動する</translation>
<translation id="6529602333819889595">削除のやり直し(&amp;R)</translation>
<translation id="6534179046333460208">フィジカル ウェブからの URL</translation>
+<translation id="6556866813142980365">やり直す</translation>
<translation id="6563469144985748109">管理者がまだサイトを開くことを許可していません</translation>
<translation id="6569060085658103619">拡張機能のページを表示しています</translation>
+<translation id="6578796323535178455">C2(封筒)</translation>
<translation id="6579990219486187401">ライトピンク</translation>
+<translation id="6583674473685352014">B6(封筒)</translation>
+<translation id="6587923378399804057">コピーしたリンク</translation>
+<translation id="6591833882275308647">ご使用の <ph name="DEVICE_TYPE" /> は管理されていません</translation>
<translation id="6596325263575161958">暗号化オプション</translation>
<translation id="6604181099783169992">モーション センサーまたは光センサー</translation>
+<translation id="6609880536175561541">Prc7(封筒)</translation>
<translation id="6624427990725312378">連絡先情報</translation>
<translation id="6626291197371920147">有効なカード番号を追加</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 検索</translation>
@@ -884,6 +1000,7 @@
<translation id="6644283850729428850">このポリシーは廃止されました。</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{なし}=1{1 件のサイト(Google アカウントへのログイン状態は維持されます)}other{# 件のサイト(Google アカウントへのログイン状態は維持されます)}}</translation>
<translation id="6657585470893396449">パスワード</translation>
+<translation id="6670613747977017428">セキュリティで保護されたページに戻ります。</translation>
<translation id="6671697161687535275">Chromium から候補を削除してもよろしいですか?</translation>
<translation id="6685834062052613830">ログアウトして設定を完了してください</translation>
<translation id="6710213216561001401">前へ</translation>
@@ -891,12 +1008,15 @@
<translation id="671076103358959139">登録トークン:</translation>
<translation id="6711464428925977395">プロキシ サーバーに問題がある、またはアドレスが正しくありません。</translation>
<translation id="6723740634201835758">Google アカウント</translation>
+<translation id="6738516213925468394">データは <ph name="TIME" />に<ph name="BEGIN_LINK" />同期パスフレーズ<ph name="END_LINK" />で暗号化されました。同期を開始するには、同期パスフレーズを入力してください。</translation>
<translation id="674375294223700098">不明なサーバー証明書エラー</translation>
<translation id="6744009308914054259">接続するまでの間、[ダウンロード] に移動してオフラインで記事を読むことができます。</translation>
<translation id="6753269504797312559">ポリシーの値</translation>
<translation id="6757797048963528358">デバイスがスリープ状態です。</translation>
+<translation id="6768213884286397650">はがき</translation>
<translation id="6778737459546443941">保護者がまだサイトを開くことを許可していません</translation>
<translation id="67862343314499040">バイオレット</translation>
+<translation id="6786747875388722282">拡張機能</translation>
<translation id="679355240208270552">ポリシーによって既定の検索エンジンが有効になっていないため、無視されました。</translation>
<translation id="681021252041861472">必須項目</translation>
<translation id="6810899417690483278">カスタム ID</translation>
@@ -929,13 +1049,15 @@
<translation id="6965978654500191972">デバイス</translation>
<translation id="6970216967273061347">地区</translation>
<translation id="6973656660372572881">固定プロキシ サーバーと .pac スクリプト URL の両方が指定されています。</translation>
+<translation id="6973932557599545801">自動入力できません。残りの入力はご自身で行ってください。</translation>
<translation id="6979158407327259162">Google ドライブ</translation>
<translation id="6979440798594660689">ミュート(デフォルト)</translation>
<translation id="6984479912851154518">外部アプリケーションでのお支払い処理に進むため、プライベート モードを解除します。続行しますか?</translation>
<translation id="6989763994942163495">詳細設定を表示...</translation>
+<translation id="6993898126790112050">6x9(封筒)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" />を常に翻訳</translation>
<translation id="7012363358306927923">中国銀聯</translation>
-<translation id="7016992613359344582">料金の請求は 1 回限りの場合も毎月行われる場合もあり、課金されたかどうかわからないこともあります。</translation>
+<translation id="7016992613359344582">料金の請求は 1 回限りの場合も繰り返し行われる場合もあり、課金されたかどうかわからないこともあります。</translation>
<translation id="7029809446516969842">パスワード</translation>
<translation id="7050187094878475250"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーに提示された証明書の有効期限が長すぎて信頼性を確認できませんでした。</translation>
<translation id="705310974202322020">{NUM_CARDS,plural, =1{現在、このカードは保存できません}other{現在、これらのカードは保存できません}}</translation>
@@ -948,28 +1070,33 @@
<translation id="7108338896283013870">非表示</translation>
<translation id="7108819624672055576">拡張機能によって許可</translation>
<translation id="7111012039238467737">(有効)</translation>
+<translation id="7118618213916969306">クリップボードにある URL(<ph name="SHORT_URL" />)を検索します</translation>
<translation id="7119414471315195487">他のタブやプログラムを閉じる</translation>
<translation id="7129409597930077180">この住所には配送できません。別の住所を選択してください。</translation>
<translation id="7135130955892390533">ステータスを表示</translation>
<translation id="7138472120740807366">配達方法</translation>
<translation id="7139724024395191329">管轄区域</translation>
+<translation id="7152423860607593928">Number-14(封筒)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ラベンダー</translation>
-<translation id="7158980942472052083">URL が無効です。標準スキームの URL を指定してください。</translation>
<translation id="717330890047184534">GAIA ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">アクセスしているサーバー <ph name="ORIGIN" /> では、サーバーへのすべてのリクエストにセキュリティ ポリシーを適用することが求められていますが、ポリシーは送信されず、ブラウザは他の場所にリダイレクトされたため、ブラウザは <ph name="SITE" /> のリクエストを満たすことができません。</translation>
<translation id="7179323680825933600">お支払い方法の保存と入力</translation>
<translation id="7180611975245234373">更新</translation>
<translation id="7182878459783632708">ポリシーが設定されていません</translation>
<translation id="7186367841673660872">このページは<ph name="ORIGINAL_LANGUAGE" />から<ph name="LANGUAGE_LANGUAGE" />に翻訳されました</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> を解放します。サイトによっては、次回アクセスする際に読み込みがこれまでより遅くなる可能性があります。</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">管理者は、以下の情報を確認できます。</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> ではセキュリティ規格が遵守されていません。</translation>
<translation id="721197778055552897">この問題の詳細については、<ph name="BEGIN_LINK" />こちら<ph name="END_LINK" />をご覧ください。</translation>
<translation id="7219179957768738017">この接続には <ph name="SSL_VERSION" /> を使用しています。</translation>
<translation id="7220786058474068424">処理しています</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />、<ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">アクセス先のサイトで不正なソフトウェアを検出しました</translation>
+<translation id="724766306220616965">警告、競合</translation>
<translation id="724975217298816891">カードの詳細を更新するには <ph name="CREDIT_CARD" /> の有効期限と CVC を入力します。確認を行うと、カードの詳細がこのサイトと共有されます。</translation>
<translation id="7251437084390964440">ネットワーク設定が ONC 標準に準拠していません。設定の一部がインポートされない可能性があります。
詳細:
@@ -982,11 +1109,14 @@
<translation id="7300012071106347854">コバルトブルー</translation>
<translation id="7302712225291570345">「<ph name="TEXT" />」</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> にクラッシュ レポートが作成されました(ユーザーからアップロードがリクエストされましたが、まだアップロードされていません)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />セーフ ブラウジング<ph name="END_LINK" />の警告</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">接続に関するヘルプ</translation>
<translation id="7334320624316649418">順序変更のやり直し(&amp;R)</translation>
<translation id="733923710415886693">サーバーの証明書は、証明書の透明性ポリシーを介して公開されていません。</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">コマンドライン</translation>
-<translation id="7365061714576910172">Linux 形式でエクスポート</translation>
<translation id="7372973238305370288">検索結果</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">いいえ</translation>
@@ -994,6 +1124,7 @@
<translation id="7381288752349550461">管理対象セッションのオーバーライド</translation>
<translation id="7390545607259442187">カードの確認</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">ご使用の <ph name="DEVICE_NAME" /> は管理されています</translation>
<translation id="7407424307057130981">&lt;p&gt;このエラーは、Windows パソコンで Superfish ソフトウェアを使用している場合に表示されます。&lt;/p&gt;
&lt;p&gt;次の手順でソフトウェアを一時的に無効にすると、インターネットに接続できるようになります。なお、この操作には管理者権限が必要です。&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1135,7 @@
&lt;li&gt;[&lt;strong&gt;適用&lt;/strong&gt;] をクリックし、[&lt;strong&gt;OK&lt;/strong&gt;] をクリックします。
&lt;li&gt;このソフトウェアをパソコンから完全に削除する方法については、&lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome ヘルプセンター&lt;/a&gt;をご覧ください。
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> の管理</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">パスワードを管理…</translation>
<translation id="7419106976560586862">プロフィール パス</translation>
<translation id="7437289804838430631">連絡先情報を追加</translation>
@@ -1013,22 +1144,24 @@
<translation id="7442725080345379071">ライトオレンジ</translation>
<translation id="7444046173054089907">このサイトはブロックされています</translation>
<translation id="7445762425076701745">接続してるサーバーの身元について、十分な検証ができません。接続しているサーバーは、そのネットワーク内でのみ有効な名前を使用しており、外部認証局がその所有権を検証する方法はありません。こうした名前で証明書を発行する認証局もあるので、接続先が意図したウェブサイトか、悪意のあるユーザーのサイトかは確認できません。</translation>
-<translation id="7449109375006139765">システムログを管理サーバーに送信します</translation>
<translation id="7451311239929941790">この問題について<ph name="BEGIN_LINK" />詳細を確認<ph name="END_LINK" />する</translation>
<translation id="7455133967321480974">グローバルのデフォルト値([ブロック])を使用</translation>
<translation id="7460618730930299168">スクリーニングが選択内容と異なっています。続行しますか?</translation>
<translation id="7473891865547856676">スキップ</translation>
-<translation id="7475525192983021547">ユーザーがデバイスを操作した時間を報告します</translation>
<translation id="7481312909269577407">進む</translation>
<translation id="7485870689360869515">データが見つかりません。</translation>
-<translation id="7508255263130623398">返されたポリシーの端末 ID が空であるか、現在の端末 ID と一致しません</translation>
+<translation id="7498234416455752244">編集を続ける</translation>
+<translation id="7508255263130623398">返されたポリシーのデバイス ID が空であるか、現在のデバイス ID と一致しません</translation>
<translation id="7508870219247277067">アボカド グリーン</translation>
<translation id="7511955381719512146">ご利用の Wi-Fi では、<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> へのアクセスが必要な可能性があります。</translation>
<translation id="7514365320538308">ダウンロード</translation>
<translation id="7518003948725431193">次の URL のウェブページは見つかりませんでした:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8(封筒)</translation>
<translation id="7521387064766892559">Javascript</translation>
<translation id="7526934274050461096">このサイトへの接続ではプライバシーが保護されません</translation>
+<translation id="7535087603100972091">値</translation>
<translation id="7537536606612762813">必須</translation>
+<translation id="7538364083937897561">A2(封筒)</translation>
<translation id="7542403920425041731">確認すると、カードの情報がこのサイトに共有されます。</translation>
<translation id="7542995811387359312">このフォームは安全な接続を使用していないため、クレジットカードの自動入力が無効になっています。</translation>
<translation id="7543525346216957623">保護者に頼んでください</translation>
@@ -1037,11 +1170,11 @@
<translation id="7552846755917812628">次のことをお試しください。</translation>
<translation id="7554791636758816595">新しいタブ</translation>
<translation id="7564049878696755256"><ph name="ORG_NAME" /> アカウントにアクセスできなくなったり、個人情報が盗まれたりする可能性があります。今すぐパスワードを変更することをおすすめします。</translation>
-<translation id="7566125604157659769">コピーしたテキスト</translation>
<translation id="7567204685887185387">このサーバーが <ph name="DOMAIN" /> であることを確認できませんでした。このサーバーのセキュリティ証明書は不正に発行されたものである可能性があります。原因としては、不適切な設定や、悪意のあるユーザーによる接続妨害が考えられます。</translation>
+<translation id="7568105740864181217">このブラウザは、会社、学校、その他の組織によって管理されています。管理者はブラウザの設定をリモートで変更できます。このデバイスでのアクティビティは、Chrome 以外でも管理されている可能性があります。<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome からクレジット カードを削除してもよろしいですか?</translation>
<translation id="7569983096843329377">黒</translation>
-<translation id="7578104083680115302">どの端末でも、Google に保存したカードを使ってサイトやアプリの支払いをすばやく行うことができます。</translation>
+<translation id="7578104083680115302">どのデバイスでも、Google に保存したカードを使ってサイトやアプリの支払いをすばやく行うことができます。</translation>
<translation id="7592362899630581445">サーバーの証明書が名前の制約に違反しています。</translation>
<translation id="7598391785903975535"><ph name="UPPER_ESTIMATE" /> 未満</translation>
<translation id="759889825892636187"><ph name="HOST_NAME" /> では現在このリクエストを処理できません。</translation>
@@ -1049,6 +1182,7 @@
<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="7633909222644580952">パフォーマンス データと障害レポート</translation>
<translation id="7637571805876720304">Chromium からクレジット カードを削除してもよろしいですか?</translation>
<translation id="7639968568612851608">ダークグレー</translation>
<translation id="765676359832457558">詳細設定を表示しない...</translation>
@@ -1058,9 +1192,11 @@
<translation id="7667346355482952095">返されたポリシーのトークンが空であるか、現在のトークンと一致しません</translation>
<translation id="7668654391829183341">不明なデバイス</translation>
<translation id="7669271284792375604">このサイトを利用すると、悪意のあるユーザーによって、閲覧時のエクスペリエンスを損なうプログラム(ホームページを改ざんする、アクセス先のサイトに追加の広告を表示するなどのプログラム)をインストールするよう誘導される可能性があります。</translation>
+<translation id="7676643023259824263">クリップボードにあるテキスト<ph name="TEXT" />を検索します</translation>
<translation id="7681101578153515023">検索エンジンを変更する</translation>
<translation id="7682287625158474539">発送先</translation>
<translation id="7687186412095877299">保存したお支払い方法を使ってお支払いフォームに入力する</translation>
+<translation id="7697066736081121494">Prc8(封筒)</translation>
<translation id="769721561045429135">現在、このデバイスでのみ使用できるカードがあります。カードを確認するには [続行] をクリックしてください。</translation>
<translation id="7699293099605015246">記事は現在利用できません</translation>
<translation id="7701040980221191251">なし</translation>
@@ -1072,11 +1208,13 @@
<translation id="774634243536837715">危険なコンテンツがブロックされました。</translation>
<translation id="7752995774971033316">管理されていません</translation>
<translation id="7755287808199759310">ブロックの解除は保護者が行うことができます</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ファイアウォールまたはウイルス対策ソフトウェアによって接続がブロックされた可能性があります。</translation>
<translation id="7759163816903619567">表示ドメイン:</translation>
<translation id="7761701407923456692">サーバーの証明書が URL と一致しません。</translation>
<translation id="7763386264682878361">Payment Manifest Parser</translation>
<translation id="7764225426217299476">住所を追加</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">都道府県</translation>
<translation id="7791543448312431591">追加</translation>
<translation id="7793809570500803535"><ph name="SITE" /> のウェブページは一時的に停止しているか、新しいウェブアドレスに移動した可能性があります。</translation>
@@ -1088,8 +1226,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome から候補を削除してもよろしいですか?</translation>
<translation id="7815407501681723534">「<ph name="SEARCH_STRING" />」に対し <ph name="NUMBER_OF_RESULTS" /> 件の <ph name="SEARCH_RESULTS" />が見つかりました</translation>
-<translation id="7818867226424560206">ポリシー管理</translation>
<translation id="782886543891417279">ご利用の Wi-Fi(<ph name="WIFI_NAME" />)では、ログインページへのアクセスが必要な可能性があります。</translation>
+<translation id="7836231406687464395">Postfix(封筒)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{なし}=1{1 個のアプリ(<ph name="EXAMPLE_APP_1" />)}=2{2 個のアプリ(<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />)}other{# 個のアプリ(<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />、<ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">あらゆる場所に記録が一切残らないわけではありません。シークレット モードを使っても、雇用主、インターネット サービス プロバイダ、訪問先のウェブサイトに閲覧内容が知られる可能性はあります。</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1236,7 @@
<translation id="7878562273885520351">パスワードが不正使用される可能性があります</translation>
<translation id="7882421473871500483">茶</translation>
<translation id="7887683347370398519">CVC を確認してからもう一度お試しください</translation>
-<translation id="7893255318348328562">セッション名</translation>
+<translation id="7904208859782148177">C3(封筒)</translation>
<translation id="79338296614623784">有効な電話番号を入力してください</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">有効期限は <ph name="EXPIRATION_DATE_ABBR" /> です</translation>
@@ -1108,21 +1246,25 @@
<translation id="7951415247503192394">(32 ビット)</translation>
<translation id="7956713633345437162">モバイルのブックマーク</translation>
<translation id="7961015016161918242">使用しない</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">指定なし</translation>
<translation id="800218591365569300">メモリを解放するために、他のタブやプログラムを閉じてみてください。</translation>
+<translation id="8004582292198964060">ブラウザ</translation>
<translation id="8009225694047762179">パスワードを管理</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{このカードと請求先住所は保存され、<ph name="USER_EMAIL" /> にログインすると使用できます。}other{これらのカードと請求先住所は保存され、<ph name="USER_EMAIL" /> にログインすると使用できます。}}</translation>
<translation id="8012647001091218357">現在、保護者にたずねることができません。もう一度お試しください。</translation>
<translation id="8025119109950072390">このサイトを利用すると、悪意のあるユーザーによって、ソフトウェアのインストールや個人情報(例: パスワード、電話番号、クレジット カード番号)の入力などの危険な操作を行うよう誘導される可能性があります。</translation>
<translation id="8034522405403831421">このページの言語は<ph name="SOURCE_LANGUAGE" />です。<ph name="TARGET_LANGUAGE" />に翻訳しますか?</translation>
<translation id="8035152190676905274">ペン</translation>
+<translation id="8037117624646282037">最近デバイスを使用したユーザー</translation>
<translation id="8037357227543935929">確認(デフォルト)</translation>
<translation id="803771048473350947">ファイル</translation>
<translation id="8041089156583427627">フィードバックを送信</translation>
<translation id="8041940743680923270">グローバルのデフォルト値([確認])を使用</translation>
<translation id="8042918947222776840">集荷方法を選択</translation>
<translation id="8057711352706143257">「<ph name="SOFTWARE_NAME" />」が正しく設定されていません。通常、この問題は「<ph name="SOFTWARE_NAME" />」をアンインストールすることで解決します。<ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">お使いのデバイスは次のように設定されています:</translation>
+<translation id="8066955247577885446">エラーが発生しました。</translation>
+<translation id="8074253406171541171">10x13(封筒)</translation>
<translation id="8078141288243656252">回転時に注釈を追加することはできません</translation>
<translation id="8079031581361219619">このサイトを再読み込みしますか?</translation>
<translation id="8088680233425245692">記事を表示できませんでした。</translation>
@@ -1131,11 +1273,12 @@
<translation id="8091372947890762290">サーバーで有効化が保留になっています</translation>
<translation id="8092774999298748321">ディープ パープル</translation>
<translation id="8094917007353911263">ご利用のネットワークでは、<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> へのアクセスが必要な可能性があります。</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">無効なカードを削除しました</translation>
<translation id="8103161714697287722">お支払い方法</translation>
<translation id="8118489163946903409">お支払い方法</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> は <ph name="ENROLLMENT_DOMAIN" /> によって管理されています</translation>
<translation id="8127301229239896662">「<ph name="SOFTWARE_NAME" />」がパソコンまたはネットワークに正しくインストールされていません。管理者にこの問題を解決するよう依頼してください。</translation>
-<translation id="8130693978878176684">自動入力できません。残りの入力はご自身で行ってください。</translation>
<translation id="8131740175452115882">確認</translation>
<translation id="8149426793427495338">パソコンがスリープ状態です。</translation>
<translation id="8150722005171944719"><ph name="URL" /> のファイルを読むことができません。削除されたか移動された可能性があります。ファイルに対するアクセス権がない場合もあります。</translation>
@@ -1145,8 +1288,11 @@
<translation id="8197543752516192074">ページを翻訳する</translation>
<translation id="8201077131113104583">ID「<ph name="EXTENSION_ID" />」の拡張機能に対する無効な更新 URL です。</translation>
<translation id="8202097416529803614">ご注文概要</translation>
+<translation id="8202370299023114387">競合</translation>
+<translation id="8206978196348664717">Prc4(封筒)</translation>
<translation id="8211406090763984747">この接続は保護されています</translation>
<translation id="8218327578424803826">割り当てられた場所:</translation>
+<translation id="8220146938470311105">C7 / C6(封筒)</translation>
<translation id="8225771182978767009">このサイトは、このパソコンを設定したユーザーによってブロックされています。</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />、<ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">ページを新しいシークレット タブで開く</translation>
@@ -1158,14 +1304,16 @@
<translation id="825929999321470778">保存したパスワードをすべて表示</translation>
<translation id="8261506727792406068">削除</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> としてログイン</translation>
+<translation id="8278457561961988242">このブラウザは <ph name="ENROLLMENT_DOMAIN" /> によって管理されています。管理者はブラウザの設定をリモートで変更できます。このデバイスでのアクティビティは、Chrome 以外でも管理されている可能性があります。<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">ログイン</translation>
<translation id="8288807391153049143">証明書を表示</translation>
<translation id="8289355894181816810">確認方法がわからない場合は、ネットワーク管理者までお問い合わせください。</translation>
<translation id="8293206222192510085">ブックマークの追加</translation>
<translation id="8294431847097064396">ソース</translation>
<translation id="8298115750975731693">ご利用の Wi-Fi(<ph name="WIFI_NAME" />)では、<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> へのアクセスが必要な可能性があります。</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">ネットワーク接続に問題があったため翻訳できませんでした。</translation>
-<translation id="8311129316111205805">セッションを読み込む</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> へのアクセスが拒否されました</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">有害なプログラムが削除されるより前に<ph name="BEGIN_LINK" />このサイトにアクセスする<ph name="END_LINK" />場合は、セキュリティ上のリスクについてご承知おきください。</translation>
@@ -1175,7 +1323,7 @@
<translation id="8368476060205742148">Google Play 開発者サービス</translation>
<translation id="8371889962595521444">カスタムルート証明書</translation>
<translation id="8380941800586852976">危険</translation>
-<translation id="8381674639488873545">料金の請求は 1 回限りの場合も毎月行われる場合もあり、課金されたかどうかわからないこともあります。<ph name="BEGIN_LINK" />理解したうえで表示する<ph name="END_LINK" /></translation>
+<translation id="8381674639488873545">料金の請求は 1 回限りの場合も繰り返し行われる場合もあり、課金されたかどうかわからないこともあります。<ph name="BEGIN_LINK" />理解したうえで表示する<ph name="END_LINK" /></translation>
<translation id="8382348898565613901">最近アクセスしたブックマークがここに表示されます</translation>
<translation id="8398259832188219207">クラッシュ レポートが <ph name="UPLOAD_TIME" /> にアップロードされました</translation>
<translation id="8412145213513410671">障害数(<ph name="CRASH_COUNT" />)</translation>
@@ -1183,7 +1331,6 @@
<translation id="8416694386774425977">ネットワーク設定が無効なためインポートできませんでした。
詳細:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" /> で管理されているデバイス</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">変更</translation>
<translation id="8428213095426709021">設定</translation>
@@ -1211,9 +1358,11 @@
<translation id="860043288473659153">カード名義人</translation>
<translation id="861775596732816396">サイズ 4</translation>
<translation id="8620436878122366504">保護者がまだサイトを開くことを許可していません</translation>
-<translation id="8625384913736129811">このカード情報をこの端末に保存する</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
+<translation id="8625384913736129811">このカード情報をこのデバイスに保存する</translation>
<translation id="8663226718884576429">ご注文の概要、<ph name="TOTAL_LABEL" />、その他の詳細</translation>
<translation id="8680536109547170164">「<ph name="QUERY" />」に対する答え: 「<ph name="ANSWER" />」</translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> への接続は暗号化されていません。</translation>
<translation id="8718314106902482036">支払い処理を完了できませんでした</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />、<ph name="DESCRIPTION" />、検索候補</translation>
@@ -1226,7 +1375,8 @@
<translation id="8759274551635299824">このカードは有効期限が切れています</translation>
<translation id="8761567432415473239"><ph name="SITE" /> では最近、Google セーフ ブラウジングにより<ph name="BEGIN_LINK" />有害なプログラムが検出<ph name="END_LINK" />されました。</translation>
<translation id="8763927697961133303">USB デバイス</translation>
-<translation id="8768895707659403558">お使いのどの端末でも同じカードを使用するには、<ph name="SIGN_IN_LINK" />します。</translation>
+<translation id="8768895707659403558">お使いのどのデバイスでも同じカードを使用するには、<ph name="SIGN_IN_LINK" />します。</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">削除のやり直し(&amp;R)</translation>
<translation id="8792621596287649091"><ph name="ORG_NAME" /> アカウントにアクセスできなくなったり、個人情報が盗まれたりする可能性があります。今すぐパスワードを変更することをおすすめします。</translation>
<translation id="8800988563907321413">周辺のおすすめの場所がここに表示されます</translation>
@@ -1237,10 +1387,12 @@
<translation id="885730110891505394">Google との共有</translation>
<translation id="8858065207712248076"><ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> パスワードを他のサイトで再使用した場合、Chrome ではパスワードの再設定を促すメッセージが表示されます。</translation>
<translation id="8866481888320382733">ポリシー設定の解析中にエラーが発生しました</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">最近閉じたタブ</translation>
<translation id="8874824191258364635">有効なクレジット カード番号を入力してください</translation>
<translation id="8891727572606052622">プロキシ モードが無効です。</translation>
<translation id="8903921497873541725">拡大する</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">このカードを Google アカウントに保存しますか?</translation>
<translation id="8932102934695377596">時計が遅れています</translation>
<translation id="893332455753468063">名前の追加</translation>
@@ -1248,13 +1400,13 @@
<translation id="894185898663964645">管理者がカスタムルート証明書を設定しています。管理者は、ユーザーがアクセスしたウェブサイトのコンテンツを表示できます。</translation>
<translation id="8943282376843390568">ライム</translation>
<translation id="8957210676456822347">キャプティブ ポータル認証</translation>
+<translation id="8966619695390250636">もしかして:</translation>
<translation id="8968766641738584599">カードを保存</translation>
<translation id="8971063699422889582">サーバーの証明書の有効期限が切れています。</translation>
<translation id="8975012916872825179">電話番号、メールアドレス、配送先住所などの情報が含まれます</translation>
<translation id="8978053250194585037"><ph name="SITE" /> では最近、Google セーフ ブラウジングにより、<ph name="BEGIN_LINK" />フィッシング行為が検出されました<ph name="END_LINK" />。フィッシング サイトは、他のウェブサイトになりすましてユーザーを欺こうとするサイトです。</translation>
<translation id="8983003182662520383">Google Pay のお支払い方法と住所</translation>
<translation id="8987927404178983737">月</translation>
-<translation id="8988408250700415532">エラーが発生しました。注文はウェブサイトで完了できます。</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">この先のサイトには有害なプログラムがあります</translation>
<translation id="8997023839087525404">サーバーから提示された証明書は、証明書の透明性ポリシーを介して公開されていません。一部の証明書は、信頼性の確保と攻撃者からの保護のため、証明書の透明性ポリシーを介して公開されることが要件となっています。</translation>
@@ -1264,6 +1416,7 @@
<translation id="9011424611726486705">サイトの設定を開きます</translation>
<translation id="9020200922353704812">カードの請求先住所を入力する必要があります</translation>
<translation id="9020542370529661692">このページは<ph name="TARGET_LANGUAGE" />に翻訳されています</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(無効)</translation>
<translation id="9035022520814077154">セキュリティ エラー</translation>
<translation id="9038649477754266430">予測サービスを使用してページをより迅速に読み込む</translation>
@@ -1275,11 +1428,11 @@
<translation id="9065745800631924235"><ph name="TEXT" /> を履歴から検索</translation>
<translation id="9069693763241529744">拡張機能によってブロック</translation>
<translation id="9076283476770535406">成人向けコンテンツが含まれている可能性があります</translation>
+<translation id="9076630408993835509">このブラウザは、会社またはその他の組織によって管理されていません。このデバイスでのアクティビティは、Chrome 以外で管理されている可能性があります。<ph name="BEGIN_LINK" />詳細<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">その他の情報が必要です</translation>
<translation id="9080712759204168376">ご注文の概要</translation>
<translation id="9103872766612412690"><ph name="SITE" /> では通常、暗号化して情報を保護しています。今回、Chromium から <ph name="SITE" /> への接続試行時に、このウェブサイトからいつもとは異なる誤った認証情報が返されました。悪意のあるユーザーが <ph name="SITE" /> になりすまそうとしているか、Wi-Fi ログイン画面で接続が中断された可能性があります。データのやり取りが行われる前に Chromium によって接続が停止されたため、情報は引き続き保護されています。</translation>
<translation id="9106062320799175032">請求先住所の追加</translation>
-<translation id="9110718169272311511">画面下部にある Chrome の Google アシスタントを使用できます</translation>
<translation id="9114524666733003316">カードを確認しています…</translation>
<translation id="9128870381267983090">ネットワークに接続する</translation>
<translation id="9137013805542155359">原文のページを表示</translation>
@@ -1288,7 +1441,8 @@
<translation id="9148507642005240123">編集の取り消し(&amp;U)</translation>
<translation id="9154194610265714752">更新完了</translation>
<translation id="9157595877708044936">セットアップ中...</translation>
-<translation id="9168814207360376865">お支払い方法を保存しているかどうかの確認をサイトに許可する</translation>
+<translation id="9158625974267017556">C6(封筒)</translation>
+<translation id="9168814207360376865">お支払い方法を保存しているかどうかの確認をサイトに許可します</translation>
<translation id="9169664750068251925">このサイトでは常にブロック</translation>
<translation id="9170848237812810038">取消(&amp;U)</translation>
<translation id="9171296965991013597">アプリを終了しますか?</translation>
@@ -1302,18 +1456,21 @@
<translation id="9219103736887031265">画像</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">フォームをクリア</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Google アカウントにアクセスできなくなる可能性があります。Chromium で今すぐパスワードを変更することをおすすめします。変更の際には、ログインするよう求められます。</translation>
<translation id="939736085109172342">新しいフォルダ</translation>
<translation id="945855313015696284">下記の情報を確認し、無効なカードがあれば削除してください</translation>
<translation id="951104842009476243">利用可能なデビットカードとプリペイド カード</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> のセキュリティ ポリシーに沿ってブロックしました。</translation>
<translation id="962484866189421427">このコンテンツを表示すると、詐欺的なアプリ(他のものに成りすましたり、ユーザーの追跡などに使用可能なデータを収集したりするアプリ)のインストールが試行される可能性があります。<ph name="BEGIN_LINK" />危険性を理解したうえで表示する<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Official Build</translation>
<translation id="973773823069644502">配達先住所を追加</translation>
<translation id="975560348586398090">{COUNT,plural, =0{なし}=1{1 件のアイテム}other{# 件のアイテム}}</translation>
<translation id="981121421437150478">オフライン</translation>
<translation id="984275831282074731">お支払い方法</translation>
-<translation id="985199708454569384">&lt;p&gt;このエラーは、パソコンまたはモバイル端末の日付と時刻が正確でない場合に表示されます。&lt;/p&gt;
- &lt;p&gt;エラーを解決するには、端末の時計を開き、日付と時刻が正しいことを確認します。&lt;/p&gt;</translation>
+<translation id="985199708454569384">&lt;p&gt;このエラーは、パソコンまたはモバイル デバイスの日付と時刻が正確でない場合に表示されます。&lt;/p&gt;
+ &lt;p&gt;エラーを解決するには、デバイスの時計を開き、日付と時刻が正しいことを確認します。&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Developer Build</translation>
<translation id="989988560359834682">住所の編集</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_kn.xtb b/chromium/components/strings/components_strings_kn.xtb
index 358b11de992..85cb275fee7 100644
--- a/chromium/components/strings/components_strings_kn.xtb
+++ b/chromium/components/strings/components_strings_kn.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="kn">
-<translation id="1005145902654145231">ಸೆಶನ್ ಅನ್ನು ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ.</translation>
<translation id="1008557486741366299">ಈಗಲೇ ಅಲ್ಲ</translation>
<translation id="1010200102790553230">ಪುಟವನ್ನು ನಂತರ ಲೋಡ್ ಮಾಡಿ</translation>
<translation id="1015730422737071372">ಹೆಚ್ಚುವರಿ ವಿವರಗಳನ್ನು ಒದಗಿಸಿ</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">ಆಜ್ಞಾತ ಹೆಸರು</translation>
<translation id="1050038467049342496">ಇತರ ಅಪ್ಲಿಕೇಶನ್‍ಗಳನ್ನು ಮುಚ್ಚಿ</translation>
<translation id="1055184225775184556">&amp;ಸೇರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
+<translation id="1056898198331236512">ಎಚ್ಚರಿಕೆ</translation>
<translation id="1058479211578257048">ಕಾರ್ಡ್‌ಗಳನ್ನು ಉಳಿಸಲಾಗುತ್ತಿದೆ...</translation>
<translation id="10614374240317010">ಉಳಿಸಿಯೇ ಇಲ್ಲ</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">ಡೆಸ್ಕ್‌ಟಾಪ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="1074497978438210769">ಸುರಕ್ಷಿತವಾಗಿಲ್ಲ</translation>
<translation id="1080116354587839789">ಅಗಲಕ್ಕೆ ಹೊಂದಿಸಿ</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">ಕಾರ್ಡ್‌ನಲ್ಲಿರುವ ಹೆಸರನ್ನು ಸೇರಿಸಿ</translation>
<translation id="1089439967362294234">ಪಾಸ್‌ವರ್ಡ್ ಬದಲಾಯಿಸಿ</translation>
<translation id="109743633954054152">ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು Chrome ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ನಿರ್ವಹಿಸಿ</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">ವೆಬ್‌ಸೈಟ್‌ಗಳು ತಮ್ಮ ಸುರಕ್ಷತೆಯನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡುವಾಗ, ಸಾಮಾನ್ಯವಾಗಿ ಎಚ್ಚರಿಕೆಗಳು ಕಾಣಿಸಿಕೊಳ್ಳಬಹುದು. ಇದನ್ನು ಶೀಘ್ರದಲ್ಲೇ ಸುಧಾರಿಸಲಾಗುವುದು.</translation>
<translation id="1126551341858583091">ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆಯಲ್ಲಿರುವ ಗಾತ್ರ <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">ನೀತಿಯ ಸಂಗ್ರಹ ಸರಿಯಾಗಿದೆ</translation>
+<translation id="1131264053432022307">ನೀವು ನಕಲಿಸಿದ ಚಿತ್ರ</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ಅನಿರೀಕ್ಷಿತವಾಗಿ ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚಿದೆ.</translation>
<translation id="1161325031994447685">ವೈ-ಫೈಗೆ ಮರುಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="1165039591588034296">ದೋಷ</translation>
-<translation id="1173894706177603556">ಮರುಹೆಸರಿಸು</translation>
<translation id="1175364870820465910">&amp;ಮುದ್ರಿಸಿ...</translation>
<translation id="1181037720776840403">ತೆಗೆದುಹಾಕು</translation>
<translation id="1197088940767939838">ಕಿತ್ತಳೆ</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">ನಿಮ್ಮ ಸಾಧನದ ಹೆಸರು</translation>
<translation id="124116460088058876">ಹೆಚ್ಚಿನ ಭಾಷೆಗಳು</translation>
<translation id="1250759482327835220">ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಪಾವತಿಸಲು, ನಿಮ್ಮ ಕಾರ್ಡ್, ಹೆಸರು ಮತ್ತು ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಉಳಿಸಿ.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">ಕಮಾಂಡ್-ಲೈನ್ ವ್ಯತ್ಯಾಸಗಳು</translation>
<translation id="129553762522093515">ಇತ್ತೀಚೆಗೆ ಮುಚ್ಚಲಾಗಿರುವುದು</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ನಿಮ್ಮ ಕುಕೀಗಳನ್ನು ತೆರವುಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಿ<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">ಆಯ್ಕೆ ಮಾಡಿದ ಸೆಷನ್ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್ ಚಿತ್ರಕ್ಕಾಗಿ ಹುಡುಕಿ</translation>
<translation id="1323433172918577554">ಇನ್ನಷ್ಟು ತೋರಿಸಿ</translation>
<translation id="132390688737681464">ವಿಳಾಸಗಳನ್ನು ಉಳಿಸಿ ಮತ್ತು ಭರ್ತಿ ಮಾಡಿ</translation>
<translation id="1333989956347591814">ನಿಮ್ಮ ಚಟುವಟಿಕೆಗಳು <ph name="BEGIN_EMPHASIS" />ಇನ್ನೂ ಇವರಿಗೆ ಕಾಣಿಸಿಕೊಳ್ಳಬಹುದು<ph name="END_EMPHASIS" /> :
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">ಪಿಕಪ್ ವಿಳಾಸ</translation>
<translation id="1348198688976932919">ಮುಂದಿರುವ ಸೈಟ್‌ನಲ್ಲಿ ಅಪಾಯಕಾರಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿವೆ</translation>
<translation id="1348779747280417563">ಹೆಸರನ್ನು ಖಚಿತಪಡಿಸಿ</translation>
+<translation id="1357195169723583938">ಸಾಧನವನ್ನು ಇತ್ತೀಚೆಗೆ ಯಾರೆಲ್ಲಾ ಮತ್ತು ಯಾವಾಗ ಬಳಸಿದ್ದಾರೆ</translation>
+<translation id="1364822246244961190">ಈ ಕಾರ್ಯನೀತಿಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದ್ದು, ಅದರ ಮೌಲ್ಯವನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗುತ್ತದೆ.</translation>
<translation id="1374468813861204354">ಸಲಹೆಗಳು</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">ಆವೃತ್ತಿಯ ಕುರಿತು</translation>
<translation id="1376836354785490390">ಕಡಿಮೆ ತೋರಿಸಿ</translation>
<translation id="1377321085342047638">ಕಾರ್ಡ್ ಸಂಖ್ಯೆ</translation>
<translation id="138218114945450791">ತಿಳಿ ನೀಲಿ</translation>
+<translation id="1382194467192730611">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು USB ಸಾಧನವನ್ನು ಅನುಮತಿಸಿದ್ದಾರೆ</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ಯಾವುದೇ ಡೇಟಾ ಕಳುಹಿಸಲಾಗಿಲ್ಲ.</translation>
+<translation id="140316286225361634">ಸುರಕ್ಷತೆ ನೀತಿಯು ತನ್ನ ಎಲ್ಲಾ ವಿನಂತಿಗೆ ಅನ್ವಯವಾಗುತ್ತದೆ ಎಂಬುದಾಗಿ
+ ಸೈಟ್ <ph name="ORIGIN" /> ವಿನಂತಿಸಿಕೊಂಡಿದೆ ಮತ್ತು ಈ ಕಾರ್ಯನೀತಿಯು ಪ್ರಸ್ತುತವಾಗಿ ಸೈಟ್ ಅನ್ನು ಅಸುರಕ್ಷಿತ ಎಂಬುದಾಗಿ
+ ಪರಿಗಣಿಸಿದೆ.</translation>
<translation id="1405567553485452995">ತಿಳಿ ಹಸಿರು</translation>
<translation id="1407135791313364759">ಎಲ್ಲವನ್ನೂ ತೆರೆಯಿರಿ</translation>
<translation id="1413809658975081374">ಗೌಪ್ಯತೆ ದೋಷ</translation>
@@ -92,32 +102,39 @@
<translation id="1426410128494586442">ಹೌದು</translation>
<translation id="1430915738399379752">ಮುದ್ರಿಸು</translation>
<translation id="1455413310270022028">ಎರೇಸರ್</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">ಇನ್ನಷ್ಟು ತೋರಿಸಿ</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸವನ್ನು ಆರಿಸಿ</translation>
+<translation id="1492194039220927094">ಕಾರ್ಯನೀತಿಗಳನ್ನು ಪುಶ್ ಮಾಡುವ ಕ್ರಿಯೆ:</translation>
<translation id="1501859676467574491">ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿರುವ ಕಾರ್ಡ್‌ಗಳನ್ನು ತೋರಿಸಿ</translation>
-<translation id="1506687042165942984">ಈ ಪುಟದ ಉಳಿಸಲಾದ (ಉದಾ. ಹಳೆಯದು ಎಂದು ಕರೆಯಲಾಗುವ) ನಕಲನ್ನು ತೋರಿಸಿ.</translation>
<translation id="1507202001669085618">&lt;p&gt;ನೀವು ಆನ್‌ಲೈನ್ ಪ್ರವೇಶಿಸುವ ಮೊದಲು ಸೈನ್‌ ಇನ್‌ ಮಾಡಬೇಕಾದ ವೈ-ಫೈ ಪೋರ್ಟಲ್ ಅನ್ನು ಬಳಸುತ್ತಿದ್ದರೆ ಈ ದೋಷವನ್ನು ಕಾಣುತ್ತೀರಿ.&lt;/p&gt; &lt;p&gt;ನೀವು ತೆರೆಯಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವ ಪುಟದಲ್ಲಿ ದೋಷವನ್ನು ಸರಿಪಡಿಸಲು &lt;strong&gt;ಸಂಪರ್ಕಿಸಿ&lt;/strong&gt; ಅನ್ನು ಕ್ಲಿಕ್‌ ಮಾಡಿ.&lt;/p&gt;</translation>
<translation id="1517433312004943670">ಫೋನ್ ಸಂಖ್ಯೆ ಅಗತ್ಯವಿದೆ</translation>
<translation id="1517500485252541695">ಸಮ್ಮತಿಸಲಾದ ಕ್ರೆಡಿಟ್ ಮತ್ತು ಡೆಬಿಟ್ ಕಾರ್ಡ್‌ಗಳು</translation>
<translation id="1519264250979466059">ಬಿಲ್ಡ್ ಡೇಟಾ</translation>
<translation id="1521655867290435174">Google ಶೀಟ್‌ಗಳು</translation>
<translation id="1527263332363067270">ಸಂಪರ್ಕಕ್ಕೆ ಕಾಯಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">ಈ ಪುಟವು ಹೀಗೆ ಹೇಳುತ್ತದೆ</translation>
<translation id="153384715582417236">ಇದುವರೆಗೂ ಇಷ್ಟೇ</translation>
<translation id="154408704832528245">ವಿತರಣೆಯ ವಿಳಾಸಗಳನ್ನು ಆರಿಸಿ</translation>
<translation id="1549470594296187301">ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು JavaScript ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">ಅವಧಿ ಮುಗಿಯುವ ದಿನಾಂಕವನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">ಈ ವೆಬ್‌ಪುಟವನ್ನು ಪ್ರದರ್ಶಿಸುವಾಗ ಯಾವುದೋ ತಪ್ಪು ಸಂಭವಿಸಿದೆ.</translation>
<translation id="1592005682883173041">ಸ್ಥಳೀಯ ಡೇಟಾ ಪ್ರವೇಶ</translation>
<translation id="1594030484168838125">ಆರಿಸಿ</translation>
<translation id="161042844686301425">ಹಸಿರುನೀಲಿ</translation>
-<translation id="1618822247301510817">ನೀವು ನಕಲಿಸಿದ ಚಿತ್ರ</translation>
<translation id="1620510694547887537">ಕ್ಯಾಮರಾ</translation>
<translation id="1623104350909869708">ಹೆಚ್ಚುವರಿ ಸಂವಾದಗಳನ್ನು ರಚಿಸದಂತೆ ಈ ಪುಟವನ್ನು ತಡೆಯಿರಿ</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">ಸೆಶನ್ ಅಂತ್ಯಗೊಳಿಸಿ</translation>
<translation id="1639239467298939599">ಲೋಡ್ ಆಗುತ್ತಿದೆ</translation>
<translation id="1640180200866533862">ಬಳಕೆದಾರನ ನೀತಿಗಳು</translation>
@@ -132,8 +149,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> ಸಾಮಾನ್ಯವಾಗಿ ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಸಂರಕ್ಷಿಸಲು ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಪ್ರಯೋಜನವನ್ನು ಬಳಸಿಕೊಳ್ಳುತ್ತದೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ Google Chrome <ph name="SITE" /> ವೆಬ್‌ಸೈಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಿದಾಗ, ಆ ವೆಬ್‌ಸೈಟ್‌‌ ಅಸಹಜ ಮತ್ತು ತಪ್ಪು ರುಜುವಾತುಗಳನ್ನು ಹಿಂತಿರುಗಿಸಿದೆ. ದಾಳಿಕೋರರು <ph name="SITE" /> ರೂಪದಲ್ಲಿ ಸೋಗು ಹಾಕಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವಾಗ ಅಥವಾ ವೈ-ಫೈ ಸೈನ್-ಇನ್ ಪರದೆಯು ಸಂಪರ್ಕಕ್ಕೆ ಅಡ್ಡಿಯುಂಟು ಮಾಡಿದಾಗ ಇದು ಕಂಡುಬರಬಹುದು. ಯಾವುದೇ ಡೇಟಾವನ್ನು ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳುವ ಮೊದಲೇ Google Chrome ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿರುವ ಕಾರಣ, ನಿಮ್ಮ ಮಾಹಿತಿ ಈಗಲೂ ಸುರಕ್ಷಿತವಾಗಿದೆ.</translation>
<translation id="168841957122794586">ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವು ದುರ್ಬಲ ಕ್ರಿಪ್ಟೋಗ್ರಾಫಿಕ್ ಕೀಯನ್ನು ಹೊಂದಿದೆ.</translation>
<translation id="1697532407822776718">ನೀವು ಎಲ್ಲ ರೀತಿಯಲ್ಲಿಯೂ ಸಿದ್ಧರಾಗಿರುವಿರಿ!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">ಟಿಪ್ಪಣಿ ಮಾಡಲು ಡಾಕ್ಯುಮೆಂಟ್‌ ತುಂಬಾ ದೊಡ್ಡದಾಗಿದೆ</translation>
<translation id="1721312023322545264">ಈ ಸೈಟ್‌ಗೆ ಭೇಟಿ ನೀಡಲು ನಿಮಗೆ <ph name="NAME" /> ಅವರ ಅನುಮತಿಯ ಅಗತ್ಯವಿರುತ್ತದೆ</translation>
<translation id="1721424275792716183">* ಈ ಫೀಲ್ಡ್ ಅಗತ್ಯವಿದೆ</translation>
@@ -144,6 +163,7 @@
<translation id="1734878702283171397">ಸಿಸ್ಟಂ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="1740951997222943430">ಮಾನ್ಯವಾದ ಅವಧಿ-ಮುಕ್ತಾಯ ತಿಂಗಳನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="1743520634839655729">ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಪಾವತಿಸಲು, ನಿಮ್ಮ ಕಾರ್ಡ್‌, ಹೆಸರು ಮತ್ತು ನಿಮ್ಮ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು Google ಖಾತೆಯಲ್ಲಿ ಮತ್ತು ಈ ಸಾಧನದಲ್ಲಿ ಉಳಿಸಿ.</translation>
+<translation id="1745880797583122200">ನಿಮ್ಮ ಬ್ರೌಸರ್ ಅನ್ನು ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation>
<translation id="17513872634828108">ತೆರೆದ ಟ್ಯಾಬ್‌ಗಳು</translation>
<translation id="1753706481035618306">ಪುಟ ಸಂಖ್ಯೆ</translation>
<translation id="1763864636252898013">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು ನಿಮ್ಮ ಸಾಧನದ ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಂ‌ ಪ್ರಕಾರ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
@@ -151,8 +171,10 @@
<translation id="1783075131180517613">ದಯವಿಟ್ಟು ನಿಮ್ಮ ಸಿಂಕ್ ಪಾಸ್‌ಫ್ರೇಸ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ.</translation>
<translation id="1787142507584202372">ನಿಮ್ಮ ತೆರೆಯಲಾದ ಟ್ಯಾಬ್‌ಗಳು ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತದೆ</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">ಕಾರ್ಡ್‌ಹೋಲ್ಡರ್ ಹೆಸರು</translation>
<translation id="1821930232296380041">ಅಮಾನ್ಯವಾದ ವಿನಂತಿ ಅಥವಾ ವಿನಂತಿ ಪ್ಯಾರಾಮೀಟರ್‌ಗಳು</translation>
+<translation id="1822540298136254167">ನೀವು ಭೇಟಿ ನೀಡಿರುವ ವೆಬ್‌ಸೈಟ್‌ಗಳು ಮತ್ತು ಅವುಗಳಲ್ಲಿ ನೀವು ಕಳೆದಿರುವ ಸಮಯ</translation>
<translation id="1826516787628120939">ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="1834321415901700177">ಈ ಸೈಟ್ ಹಾನಿಕಾರಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಹೊಂದಿದೆ</translation>
<translation id="1839551713262164453">ದೋಷಗಳಿರುವ ಕಾರಣ ಕಾರ್ಯನೀತಿಯ ಮೌಲ್ಯಗಳ ಮೌಲ್ಯೀಕರಣವು ವಿಫಲವಾಗಿದೆ</translation>
@@ -179,6 +201,10 @@
<translation id="1981206234434200693">Chrome ನ ಬ್ರೌಸಿಂಗ್ ಇತಿಹಾಸದ ಡೇಟಾವನ್ನು ತೆರವುಗೊಳಿಸಿ</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ಮತ್ತು 1 ಇನ್ನಷ್ಟು}one{ಮತ್ತು # ಇನ್ನಷ್ಟು}other{ಮತ್ತು # ಇನ್ನಷ್ಟು}}</translation>
<translation id="2003709556000175978">ಇದೀಗ ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಮರುಹೊಂದಿಸಿ</translation>
+<translation id="20053308747750172">ನೀವು ಪ್ರವೇಶಿಸುತ್ತಿರುವ ಸರ್ವರ್, <ph name="ORIGIN" />, ತನ್ನ ಎಲ್ಲಾ ವಿನಂತಿಗಳಿಗೆ
+ ಅನ್ವಯವಾಗುವ ಸುರಕ್ಷತೆ ನೀತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಂಡಿದೆ. ಆದರೆ, ಇದು ಈಗ
+ ಅಮಾನ್ಯ ಕಾರ್ಯನೀತಿಯನ್ನು ಒದಗಿಸಿದ್ದು, ಇದು
+ <ph name="SITE" /> ಗಾಗಿ ನಿಮ್ಮ ವಿನಂತಿಯನ್ನು ಈಡೇರಿಸುವುದರಿಂದ ಬ್ರೌಸರ್ ಅನ್ನು ತಡೆಯುತ್ತದೆ.</translation>
<translation id="2025186561304664664">ಪ್ರಾಕ್ಸಿಯನ್ನು ಸ್ವಯಂ ಕಾನ್ಫಿಗರ್ ಆಗಿ ಹೊಂದಿಸಲಾಗಿದೆ.</translation>
<translation id="2030481566774242610">ನಿಮ್ಮ ಮಾತಿನ ಅರ್ಥ <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />ಪ್ರಾಕ್ಸಿ ಮತ್ತು ಫೈರ್‌ವಾಲ್ ಅನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ<ph name="END_LINK" /></translation>
@@ -195,6 +221,7 @@
<translation id="2096368010154057602">ವಿಭಾಗ</translation>
<translation id="2102134110707549001">ಸದೃಢವಾದ ಪಾಸ್‌ವರ್ಡ್ ಸೂಚಿಸಿ…</translation>
<translation id="2108755909498034140">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">ಕಾರ್ಡ್</translation>
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ರಿಂದ ಅತಿಕ್ರಮಿಸಲಾಗಿರುವ ಕಾರಣ ಇದನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
<translation id="213826338245044447">ಮೊಬೈಲ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
@@ -205,6 +232,7 @@
<translation id="2154484045852737596">ಕಾರ್ಡ್ ಎಡಿಟ್ ಮಾಡಿ</translation>
<translation id="2166049586286450108">ಪೂರ್ಣ ನಿರ್ವಾಹಕ ಪ್ರವೇಶ</translation>
<translation id="2166378884831602661">ಈ ಸೈಟ್‌ಗೆ ಸುರಕ್ಷಿತ ಸಂಪರ್ಕವನ್ನು ಒದಗಿಸಲಾಗುವುದಿಲ್ಲ</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">ನಿಯಮಗಳು</translation>
<translation id="2183608646556468874">ಫೋನ್ ಸಂಖ್ಯೆ</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 ವಿಳಾಸ}one{# ವಿಳಾಸಗಳು}other{# ವಿಳಾಸಗಳು}}</translation>
@@ -222,11 +250,15 @@
<translation id="2270484714375784793">ಫೋನ್ ಸಂಖ್ಯೆ</translation>
<translation id="2283340219607151381">ವಿಳಾಸಗಳನ್ನು ಉಳಿಸಿ ಮತ್ತು ಭರ್ತಿ ಮಾಡಿ</translation>
<translation id="2292556288342944218">ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation>
+<translation id="2294558542833290837">ನೀವು ಮೂಲತಃ ತೆರೆದಿರುವ ಲಿಂಕ್ ಅಸಹಜವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿದೆ</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">1 MB ಕ್ಕಿಂತ ಕಡಿಮೆ ಇರುವುದನ್ನು ತೆಗೆದುಹಾಕಿ. ನಿಮ್ಮ ನಂತರದ ಭೇಟಿಯ ಸಮಯದಲ್ಲಿ ಕೆಲವು ಸೈಟ್‌ಗಳು ನಿಧಾನವಾಗಿ ಲೋಡ್ ಆಗಬಹುದು.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ಗೆ ಬಳಕೆದಾರಹೆಸರು ಮತ್ತು ಪಾಸ್‌ವರ್ಡ್ ಅಗತ್ಯವಿದೆ.</translation>
<translation id="2317583587496011522">ಡೆಬಿಟ್ ಕಾರ್ಡ್‌ಗಳನ್ನು ಸಮ್ಮತಿಸಲಾಗಿದೆ.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, <ph name="EXPIRATION_DATE_ABBR" /> ದಿನಾಂಕದಂದು ಅವಧಿ ಮೀರುತ್ತದೆ</translation>
<translation id="2337852623177822836">ನಿಮ್ಮ ನಿರ್ವಾಹಕದಿಂದ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ನಿಯಂತ್ರಿಸಲಾಗಿದೆ</translation>
+<translation id="2346319942568447007">ನೀವು ನಕಲಿಸಿದ ಚಿತ್ರ</translation>
<translation id="2349790679044093737">VR ಸೆಶನ್ ಸಕ್ರಿಯವಾಗಿದೆ</translation>
<translation id="2354001756790975382">ಇತರ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="2354430244986887761">Google ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್‌ ಇತ್ತೀಚಿಗೆ <ph name="SITE" /> ನಲ್ಲಿ <ph name="BEGIN_LINK" />ಹಾನಿಕಾರಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಕಂಡುಹಿಡಿದಿದೆ<ph name="END_LINK" />.</translation>
@@ -238,29 +270,36 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> ನಲ್ಲಿ ಸೆರೆಹಿಡಿಯಲಾದ ಕ್ರ್ಯಾಶ್ ವರದಿಯನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿಲ್ಲ</translation>
<translation id="2367567093518048410">ಹಂತ</translation>
<translation id="2378238891085281592">ನೀವು ಖಾಸಗಿ ಮೋಡ್‍ಗೆ ಹೋಗಿದ್ದೀರಿ.</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">ಎಂಟರ್‌ಪ್ರೈಸ್ ಡಿಫಾಲ್ಟ್</translation>
<translation id="2386255080630008482">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂಪಡೆಯಲಾಗಿದೆ.</translation>
<translation id="2392959068659972793">ಯಾವುದೇ ಮೌಲ್ಯ ಹೊಂದಿಸಿಲ್ಲದ ನೀತಿಗಳನ್ನು ತೋರಿಸಿ</translation>
<translation id="239429038616798445">ಈ ಶಿಪ್ಪಿಂಗ್ ವಿಧಾನ ಲಭ್ಯವಿಲ್ಲ. ಬೇರೊಂದು ವಿಧಾನವನ್ನು ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="2396249848217231973">&amp;ಅಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸು</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಲಾಗಿರಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="2418081434543109369">ನೀವು ಪ್ರವೇಶಿಸುತ್ತಿರುವ ಸರ್ವರ್, <ph name="ORIGIN" />, ತನ್ನ ಎಲ್ಲಾ ವಿನಂತಿಗಳಿಗೆ
+ ಅನ್ವಯವಾಗುವ ಸುರಕ್ಷತೆ ನೀತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಂಡಿದೆ. ಅದರೆ ಇದು ಈಗ
+ ಕಾರ್ಯನೀತಿಯನ್ನು ಒದಗಿಸಲು ವಿಫಲವಾಗಿದೆ, ಇದರಿಂದಾಗಿ <ph name="SITE" /> ಗೆ ನಿಮ್ಮ ವಿನಂತಿಯನ್ನು ಈಡೇರಿಸದ ಹಾಗೆ ಬ್ರೌಸರ್ ಅನ್ನು ತಡೆಯುತ್ತದೆ.</translation>
<translation id="244665789865330679">ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಖಾತೆಯನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ. ಅಂದರೆ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಖಾತೆಯನ್ನು ದೂರದಿಂದಲೇ ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದು ಎಂದರ್ಥ.</translation>
<translation id="2463193859425327265">ಮುಖಪುಟವನ್ನು ಬದಲಾಯಿಸಿ</translation>
<translation id="2463739503403862330">ಭರ್ತಿ ಮಾಡು</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">ವಿತರಣೆ ವಿಧಾನವನ್ನು ಆರಿಸಿ</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />ನೆಟ್‌ವರ್ಕ್ ಡಯಾಗ್ನಾಸ್ಟಿಕ್ಸ್‌ ರನ್ ಆಗುತ್ತಿದೆ<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ಈ ಪುಟವನ್ನು ಅನುವಾದಿಸಿ</translation>
<translation id="2479410451996844060">ಅಮಾನ್ಯವಾದ ಹುಡುಕಾಟ URL.</translation>
<translation id="2482878487686419369">ಸೂಚನೆಗಳು</translation>
<translation id="248348093745724435">ಯಂತ್ರದ ಕಾರ್ಯನೀತಿಗಳು</translation>
+<translation id="2485387744899240041">ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಬ್ರೌಸರ್‌ಗಾಗಿ ಬಳಕೆದಾರ ಹೆಸರುಗಳು</translation>
<translation id="2491120439723279231">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವು ದೋಷಗಳನ್ನು ಹೊಂದಿದೆ.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON ವಿಶ್ಲೇಷಕ</translation>
<translation id="2495093607237746763">ಪರಿಶೀಲಿಸಿದರೆ, ವೇಗವಾಗಿ ಫಾರ್ಮ್ ಭರ್ತಿ ಮಾಡಲು Chromium ಈ ಸಾಧನದಲ್ಲಿ ನಿಮ್ಮ ಕಾರ್ಡ್‌ನ ಪ್ರತಿಯನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ.</translation>
<translation id="2498091847651709837">ಹೊಸ ಕಾರ್ಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</translation>
<translation id="2501278716633472235">ಹಿಂದಿರುಗಿ</translation>
<translation id="2503184589641749290">ಸಮ್ಮತಿಸಲಾದ ಡೆಬಿಟ್ ಮತ್ತು ಪ್ರೀಪೇಯ್ಡ್ ಕಾರ್ಡ್‌ಗಳು</translation>
<translation id="2515629240566999685">ನಿಮ್ಮ ಪ್ರದೇಶದಲ್ಲಿನ ಸಿಗ್ನಲ್ ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</translation>
-<translation id="2516852381693169964">ಚಿತ್ರಕ್ಕಾಗಿ <ph name="SEARCH_ENGINE" /> ನಲ್ಲಿ ಹುಡುಕಿ</translation>
<translation id="2523886232349826891">ಈ ಸಾಧನದಲ್ಲಿ ಮಾತ್ರ ಉಳಿಸಲಾಗಿದೆ</translation>
<translation id="2524461107774643265">ಇನ್ನಷ್ಟು ಮಾಹಿತಿಯನ್ನು ಸೇರಿಸಿ</translation>
<translation id="2536110899380797252">ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
@@ -272,6 +311,7 @@
<translation id="2587841377698384444">ಡೈರೆಕ್ಟರಿ API ID:</translation>
<translation id="2597378329261239068">ಈ ಡಾಕ್ಯುಮೆಂಟ್‌ ಅನ್ನು ಪಾಸ್‌ವರ್ಡ್‌ನಿಂದ ರಕ್ಷಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನಮೂದಿಸಿ.</translation>
<translation id="2609632851001447353">ಪರಿವರ್ತನೆಗಳು</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">ನಿಮ್ಮ ಗಡಿಯಾರವು ಮುಂದೆ ಇದೆ</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> ನ ಸರ್ವರ್ IP ವಿಳಾಸ ಕಂಡುಬರಲಿಲ್ಲ.</translation>
<translation id="2639739919103226564">ಸ್ಥಿತಿ: </translation>
@@ -281,7 +321,9 @@
<translation id="2666117266261740852">ಇತರ ಟ್ಯಾಬ್‌ಗಳು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್‍ಗಳನ್ನು ಮುಚ್ಚಿ</translation>
<translation id="267371737713284912">ರದ್ದುಗೊಳಿಸಲು <ph name="MODIFIER_KEY_DESCRIPTION" /> ಒತ್ತಿರಿ</translation>
<translation id="2674170444375937751">ನಿಮ್ಮ ಇತಿಹಾಸದಿಂದ ನೀವು ಈ ಪುಟಗಳನ್ನು ಖಚಿತವಾಗಿ ಅಳಿಸಲು ಬಯಸುತ್ತಿದ್ದೀರಾ?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">ತೊರೆಯಿರಿ</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">ಸ್ವೀಕೃತ ಕಾರ್ಡ್‌ಗಳು</translation>
<translation id="2702801445560668637">ಓದುವ ಪಟ್ಟಿ</translation>
<translation id="2704283930420550640">ಮೌಲ್ಯವು ಸ್ವರೂಪಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ.</translation>
@@ -298,7 +340,6 @@
<translation id="2742870351467570537">ಆಯ್ಕೆಮಾಡಿದ ಐಟಂಗಳನ್ನು ತೆಗೆದುಹಾಕಿ</translation>
<translation id="277133753123645258">ಶಿಪ್ಪಿಂಗ್ ವಿಧಾನ</translation>
<translation id="277499241957683684">ಸಾಧನದ ರೆಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ</translation>
-<translation id="2781030394888168909">MacOS ಅನ್ನು ರಫ್ತು ಮಾಡಿ</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">ಸಂಪರ್ಕವನ್ನು ರೀಸೆಟ್ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="2788784517760473862">ಸ್ವೀಕೃತ ಕ್ರೆಡಿಟ್‌ ಕಾರ್ಡ್‌ಗಳು</translation>
@@ -310,8 +351,10 @@
<translation id="2826760142808435982"><ph name="CIPHER" /> ಬಳಸಿಕೊಂಡು ಸಂಪರ್ಕವನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ದೃಢೀಕರಿಸಲಾಗಿದೆ ಮತ್ತು <ph name="KX" /> ಅನ್ನು ಕೀ ವಿನಿಮಯ ಯಾಂತ್ರಿಕತೆಯಂತೆ ಬಳಸುತ್ತದೆ.</translation>
<translation id="2835170189407361413">ಫಾರ್ಮ್ ತೆರವುಗೊಳಿಸು</translation>
<translation id="2847118875340931228">ಅದೃಶ್ಯ ವಿಂಡೋವನ್ನು ತೆರೆಯಿರಿ</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">ಈ ಸೈಟ್‌ ಗೆ ಭೇಟಿ ನೀಡಲು ನಿಮ್ಮಗೆ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">ಕಾರ್ಡ್‌ ಉಳಿಸುವುದೇ?</translation>
<translation id="2903493209154104877">ವಿಳಾಸಗಳು</translation>
<translation id="290376772003165898"><ph name="LANGUAGE" /> ನಲ್ಲಿನ ಪುಟ ಇಲ್ಲವೇ?</translation>
@@ -321,6 +364,7 @@
<translation id="2925673989565098301">ವಿತರಣೆ ವಿಧಾನ</translation>
<translation id="2928905813689894207">ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸ</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು <ph name="DOMAIN2" /> ದಿಂದ ಆಗಿದೆ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="2948083400971632585">ಸಂಪರ್ಕಕ್ಕಾಗಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿರುವ ಯಾವುದೇ ಪ್ರಾಕ್ಸಿಗಳನ್ನು ನೀವು ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಪುಟದಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಬಹುದು.</translation>
<translation id="2955913368246107853">ಹುಡುಕಿ ಬಾರ್ ಅನ್ನು ಮುಚ್ಚಿ</translation>
@@ -337,11 +381,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">ತಪ್ಪಾದ ನೀತಿಯ ಪ್ರಕಾರ</translation>
<translation id="3037605927509011580">ಓಹ್, ಹೋಯ್ತು!</translation>
<translation id="3041612393474885105">ಪ್ರಮಾಣಪತ್ರ ಮಾಹಿತಿ</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">ಬಾಹ್ಯ ಅಪ್ಲಿಕೇಶನ್‌‌ ಮೂಲಕರ ಪಾವತಿಸಲು ಅದೃಶ್ಯ ಮೋಡ್‌‌ ತೊರೆಯಲಾಗುತ್ತಿದೆ. ಮುಂದುವರಿಸುವುದೇ?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ಯಾವುದೂ ಇಲ್ಲ}=1{1 ಪಾಸ್‌ವರ್ಡ್‌}one{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು}other{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">ಪಿಕಪ್ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
<translation id="3105172416063519923">ಸ್ವತ್ತು ID:</translation>
<translation id="3109728660330352905">ಈ ಪುಟ ವೀಕ್ಷಿಸುವ ಅಧಿಕಾರ ನಿಮಗಿಲ್ಲ</translation>
@@ -361,20 +408,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> ನಲ್ಲಿ <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">ಪಾವತಿಯನ್ನು ರದ್ದುಮಾಡಿ</translation>
<translation id="3207960819495026254">ಬುಕ್‌ಮಾರ್ಕ್‌ ಮಾಡಲಾಗಿದೆ</translation>
-<translation id="3209375525920864198">ಮಾನ್ಯವಾದ ಸೆಶನ್ ಹೆಸರನ್ನು ನಮೂದಿಸಿ.</translation>
+<translation id="321912867715453276">ಎಚ್ಚರಿಕೆ: ಕಾರ್ಯನೀತಿಗಾಗಿ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಮೂಲಗಳು ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ, ಆದರೆ ಮೌಲ್ಯಗಳು ಒಂದೇ ಆಗಿವೆ.</translation>
<translation id="3225919329040284222">ಆಂತರಿಕ ಮಾನದಂಡಗಳಿಗೆ ಹೊಂದಿಕೆಯಾಗದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸರ್ವರ್ ಹಾಜರಿಪಡಿಸಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ಸಲುವಾಗಿ ಕೆಲವು ಹೆಚ್ಚು ಸುರಕ್ಷಿತ ವೆಬ್ ಸೈಟ್‌ಗಳಲ್ಲಿ ಈ ಮಾನದಂಡಗಳನ್ನು ಸೇರ್ಪಡೆಗೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="3226128629678568754">ಪುಟವನ್ನು ಲೋಡ್ ಮಾಡುವುದಕ್ಕೆ ಅಗತ್ಯವಿರುವ ಡೇಟಾವನ್ನು ಮರುಸಲ್ಲಿಸಲು ಮರುಲೋಡ್ ಬಟನ್ ಒತ್ತಿರಿ.</translation>
<translation id="3227137524299004712">ಮೈಕ್ರೋಫೋನ್</translation>
<translation id="3228969707346345236">ಪುಟವು ಈಗಾಗಲೇ <ph name="LANGUAGE" /> ರಲ್ಲಿ ಇರುವುದರ ಕಾರಣ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
+<translation id="3229041911291329567">ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಬ್ರೌಸರ್ ಕುರಿತು ಆವೃತ್ತಿಯ ಮಾಹಿತಿ</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">ಕಾರ್ಡ್‌ನಲ್ಲಿರುವ ಹೆಸರನ್ನು ಸೇರಿಸಿ</translation>
<translation id="3287510313208355388">ಆನ್‌ಲೈನ್‌ನಲ್ಲಿರುವಾಗ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> ಕಾರ್ಯನೀತಿಯ ಕುರಿತು ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಿ</translation>
<translation id="3303855915957856445">ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳು ಕಂಡುಬಂದಿಲ್ಲ</translation>
-<translation id="3305707030755673451">ನಿಮ್ಮ ಡೇಟಾವನ್ನು <ph name="TIME" /> ರಂದು ನಿಮ್ಮ ಸಿಂಕ್ ಪಾಸ್‌ಫ್ರೇಸ್‌ನೊಂದಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಸಿಂಕ್ ಪ್ರಾರಂಭಿಸಲು ಅದನ್ನು ನಮೂದಿಸಿ.</translation>
<translation id="3320021301628644560">ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
<translation id="3324983252691184275">ಕಡುಗೆಂಪು</translation>
<translation id="3338095232262050444">ಸುರಕ್ಷಿತ</translation>
@@ -402,9 +450,11 @@
<translation id="3427342743765426898">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="342781501876943858">ನೀವು ಇತರ ಸೈಟ್‌ಗಳಲ್ಲಿ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಮರುಬಳಕೆ ಮಾಡಿದ್ದಲ್ಲಿ Chromium ನಿಮ್ಮ ಪಾಸವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲು ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
<translation id="3431636764301398940">ಈ ಸಾಧನಕ್ಕೆ ಈ ಕಾರ್ಡ್ ಉಳಿಸಿ</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">ಈ ಸಾಧನದ ಮಾಲೀಕರು ಡೈನೊಸಾರ್ ಆಟವನ್ನು ಆಫ್ ಮಾಡಿದ್ದಾರೆ.</translation>
<translation id="3447884698081792621">ಪ್ರಮಾಣಪತ್ರವನ್ನು ತೋರಿಸಿ (<ph name="ISSUER" /> ಇವರಿಂದ ನೀಡಲಾಗಿದೆ)</translation>
<translation id="3452404311384756672">ವಿರಾಮವನ್ನು ಪಡೆಯಿರಿ:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">ಹೈಲೈಟರ್</translation>
<translation id="3462200631372590220">ಸುಧಾರಿತ ಆಯ್ಕೆಮಾಡಿ</translation>
<translation id="3467763166455606212">ಕಾರ್ಡ್‌ಹೋಲ್ಡರ್ ಹೆಸರು ಅಗತ್ಯವಿದೆ</translation>
@@ -427,19 +477,22 @@
<translation id="358285529439630156">ಡೆಬಿಟ್‌ ಮತ್ತು ಪ್ರೀಪೇಯ್ಡ್‌ ಕಾರ್ಡ್‌ಗಳನ್ನು ಸಮ್ಮತಿಸಲಾಗಿದೆ.</translation>
<translation id="3582930987043644930">ಹೆಸರು ಸೇರಿಸಿ</translation>
<translation id="3583757800736429874">&amp;ಸರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
+<translation id="35866233670761917">ನೀವು ಭೇಟಿ ನೀಡುವ ವೆಬ್‌ಸೈಟ್‌ಗಳ ವಿಷಯಗಳನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನೋಡುವುದಿಲ್ಲ</translation>
<translation id="3586931643579894722">ವಿವರಗಳನ್ನು ಮರೆಮಾಡಿ</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">ಗಾತ್ರ 2</translation>
<translation id="3615877443314183785">ಮಾನ್ಯವಾದ ಅವಧಿ-ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="36224234498066874">ಬ್ರೌಸ್ ಆಗುತ್ತಿರುವ ಡೇಟಾವನ್ನು ತೆರವುಗೊಳಿಸಿ...</translation>
<translation id="362276910939193118">ಪೂರ್ಣ ಇತಿಹಾಸ ತೋರಿಸಿ</translation>
-<translation id="3623476034248543066">ಮೌಲ್ಯವನ್ನು ತೋರಿಸಿ</translation>
<translation id="3630155396527302611">ಒಂದು ವೇಳೆ ನೆಟ್‌ವರ್ಕ್ ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಸುವ ಒಂದು ಪ್ರೊಗ್ರಾಂನಂತೆ ಇದನ್ನು ಈಗಾಗಲೇ ಪಟ್ಟಿ ಮಾಡಲಾಗಿದ್ದರೆ, ಅದನ್ನು ಪಟ್ಟಿಯಿಂದ ತೆಗೆಯಲು ಮತ್ತು ಪುನಃ ಅದನ್ನು ಸೇರಿಸಲು ಪ್ರಯತ್ನಿಸಿ.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">ಊರ್ಜಿತಗೊಳಿಸುವಿಕೆಯು ಯಶಸ್ವಿಯಾಗಿದೆ</translation>
<translation id="3655670868607891010">ಇದು ನಿಮಗೆ ಪದೇ ಪದೇ ಎದುರಾಗುತ್ತಿದ್ದರೆ, <ph name="HELP_LINK" /> ಇವುಗಳನ್ನು ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="3658742229777143148">ಪರಿಷ್ಕರಣೆ</translation>
<translation id="366077651725703012">ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಮಾಹಿತಿಯನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ</translation>
<translation id="3676592649209844519">ಸಾಧನದ ಐಡಿ:</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ಎಂಬುದು ನಿಮ್ಮ ಮಾತಿನ ಅರ್ಥವೇ?</translation>
<translation id="3678029195006412963">ವಿನಂತಿಗೆ ಸಹಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ</translation>
<translation id="3678529606614285348">ಪುಟವನ್ನು ಹೊಸ ಅದೃಶ್ಯ ವಿಂಡೋದಲ್ಲಿ ತೆರೆಯಿರಿ (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" /> ನಲ್ಲಿ ಕ್ರ್ಯಾಶ್ ವರದಿಯನ್ನು ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ, <ph name="UPLOAD_TIME" /> ಸಮಯಕ್ಕೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</translation>
@@ -447,13 +500,14 @@
<translation id="3704162925118123524">ನೀವು ಬಳಸುತ್ತಿರುವ ನೆಟ್‌ವರ್ಕ್‌ನ ಲಾಗಿನ್ ಪುಟಕ್ಕೆ ಭೇಟಿ ನೀಡಬೇಕಾದ ಅಗತ್ಯವಿದೆ.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ಲೋಡ್ ಆಗುತ್ತಿದೆ...</translation>
+<translation id="3709599264800900598">ನೀವು ನಕಲಿಸಿದ ಪಠ್ಯ</translation>
<translation id="3712624925041724820">ಪರವಾನಗಿಗಳು ಬರಿದಾಗಿವೆ</translation>
<translation id="3714780639079136834">ಮೊಬೈಲ್ ಡೇಟಾ ಅಥವಾ ವೈ-ಫೈ ಆನ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation>
<translation id="3715597595485130451">ವೈ-ಫೈಗೆ ಸಂಪರ್ಕಿಸಿ</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ಪ್ರಾಕ್ಸಿ, ಫೈರ್‌ವಾಲ್ ಮತ್ತು DNS ಕಾನ್ಫಿಗರೇಶನ್‌‌ ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ<ph name="END_LINK" /></translation>
<translation id="372429172604983730">ಈ ದೋಷವನ್ನು ಉಂಟುಮಾಡಬಹುದಾದ ಅಪ್ಲಿಕೇಶನ್‌‌ಗಳು ಆಂಟಿವೈರಸ್, ಫೈರ್‌ವಾಲ್‌ ಮತ್ತು ವೆಬ್‌-ಫಿಲ್ಟರಿಂಗ್ ಅಥವಾ ಪ್ರಾಕ್ಸಿ ಸಾಫ್ಟ್‌ವೇರ್ ಅನ್ನು ಒಳಗೊಂಡಿವೆ.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿನ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</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>
@@ -466,10 +520,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">ಅವಧಿ-ಮುಕ್ತಾಯ <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">ಗಾತ್ರ 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">ಹಾನಿಕಾರಕ ವಿಷಯವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.</translation>
<translation id="3810973564298564668">ನಿರ್ವಹಿಸು</translation>
<translation id="382518646247711829">ನೀವು ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್ ಬಳಸಿದರೆ...</translation>
<translation id="3828924085048779000">ಖಾಲಿ ಪಾಸ್‌ಫ್ರೇಸ್ ಅನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ.</translation>
+<translation id="3831915413245941253">ಹೆಚ್ಚುವರಿ ಕಾರ್ಯವಿಧಾನಗಳಿಗಾಗಿ <ph name="ENROLLMENT_DOMAIN" /> ವಿಸ್ತರಣೆಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದೆ. ವಿಸ್ತರಣೆಗಳು ನಿಮ್ಮ ಕೆಲವು ಡೇಟಾಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ.</translation>
<translation id="385051799172605136">ಹಿಂದೆ</translation>
<translation id="3858027520442213535">ದಿನಾಂಕ ಮತ್ತು ಸಮಯವನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಿ</translation>
<translation id="3884278016824448484">ಸಂಘರ್ಷಗೊಳ್ಳುತ್ತಿರುವ ಸಾಧನ ಗುರುತಿಸುವಿಕೆ</translation>
@@ -477,6 +533,7 @@
<translation id="3886446263141354045">ಈ ಸೈಟ್‌ಗೆ ಪ್ರವೇಶಿಸುವ ನಿಮ್ಮ ವಿನಂತಿಯನ್ನು <ph name="NAME" /> ಅವರಿಗೆ ಕಳುಹಿಸಲಾಗಿದೆ</translation>
<translation id="3890664840433101773">ಇಮೇಲ್ ಸೇರಿಸಿ</translation>
<translation id="3901925938762663762">ಕಾರ್ಡ್ ಅವಧಿಯು ಮುಗಿದಿದೆ</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">ಯಾವಾಗಲೂ ಈ ಸೈಟ್‌ನಲ್ಲಿ ಕೇಳಿ</translation>
<translation id="3949571496842715403">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣ ಪತ್ರವು ವಿಷಯವಸ್ತು ಪರ್ಯಾಯ ಹೆಸರುಗಳನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
@@ -487,11 +544,13 @@
<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="3984550557525787191">ಈ ಸೆಶನ್‌ನ ಹೆಸರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ.</translation>
<translation id="3987940399970879459">1 MB ಗಿಂತ ಕಡಿಮೆ</translation>
+<translation id="4008849406247176967">ಎಚ್ಚರಿಕೆ: ಸಂಘರ್ಷವನ್ನು ಉಂಟುಮಾಡುವ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿರುವ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ಮೂಲಗಳು ಈ ಕಾರ್ಯನೀತಿಗಾಗಿ ಅಸ್ತಿತ್ವದಲ್ಲಿವೆ!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ಹತ್ತಿರದ 1 ವೆಬ್ ಪುಟ}one{ಹತ್ತಿರದ # ವೆಬ್ ಪುಟಗಳು}other{ಹತ್ತಿರದ # ವೆಬ್ ಪುಟಗಳು}}</translation>
<translation id="4030383055268325496">&amp;ಸೇರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
+<translation id="4032320456957708163">ನಿಮ್ಮ ಬ್ರೌಸರ್ ಅನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ನಿರ್ವಹಿಸುತ್ತಿದೆ</translation>
<translation id="4058922952496707368">ಕೀ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">ಮಾನ್ಯವಾದ ವಿಳಾಸ ಸೇರಿಸಿ</translation>
<translation id="4072486802667267160">ನಿಮ್ಮ ಆರ್ಡ‌ರ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವಲ್ಲಿ ದೋಷ ಕಂಡುಬಂದಿದೆ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="4075732493274867456">ಸಾಮಾನ್ಯ SSL ಪ್ರೊಟೋಕಾಲ್ ಆವೃತ್ತಿ ಅಥವಾ ಸೈಫರ್ ಸ್ಯೂಟ್ ಅನ್ನು ಕ್ಲೈಂಟ್ ಮತ್ತು ಸರ್ವರ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ.</translation>
@@ -511,10 +570,12 @@
<translation id="4159784952369912983">ನೇರಳೆ</translation>
<translation id="4165986682804962316">ಸೈಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
<translation id="4171400957073367226">ತಪ್ಪು ಪರಿಶೀಲನೆ ಸಹಿ</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ಹೆಚ್ಚಿನ ಐಟಂ}one{<ph name="ITEM_COUNT" /> ಹೆಚ್ಚಿನ ಐಟಂಗಳು}other{<ph name="ITEM_COUNT" /> ಹೆಚ್ಚಿನ ಐಟಂಗಳು}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ಸರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ಫೈರ್‌ವಾಲ್ ಮತ್ತು ಆಂಟಿವೈರಸ್ ಕಾನ್ಫಿಗರೇಶನ್‌‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;ಹಂತ 1: ಪೋರ್ಟಲ್‌ಗೆ ಸೈನ್‌ ಇನ್‌ ಮಾಡಿ&lt;/h4&gt;
@@ -546,58 +607,79 @@
<translation id="4277028893293644418">ಪಾಸ್‌ವರ್ಡ್ ಮರುಹೊಂದಿಸಿ</translation>
<translation id="4280429058323657511">, ಅವಧಿ ಮುಕ್ತಾಯ <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{ಈ ಕಾರ್ಡ್ ಅನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ}one{ಈ ಕಾರ್ಡ್‌ಗಳನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ}other{ಈ ಕಾರ್ಡ್‌ಗಳನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ}}</translation>
+<translation id="42981349822642051">ವಿಸ್ತರಿಸಿ</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">ಬದಲಿಸಿ</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">ನಿರ್ಬಂಧಿಸು (ಡಿಫಾಲ್ಟ್)</translation>
+<translation id="4318566738941496689">ನಿಮ್ಮ ಸಾಧನದ ಹೆಸರು ಮತ್ತು ನೆಟ್‌ವರ್ಕ್ ವಿಳಾಸ</translation>
<translation id="4325863107915753736">ಲೇಖನ ಕಂಡುಬರಲಿಲ್ಲ</translation>
<translation id="4326324639298822553">ನಿಮ್ಮ ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
<translation id="4331708818696583467">ಸುರಕ್ಷಿತವಲ್ಲ</translation>
<translation id="4340982228985273705">ಈ ಕಂಪ್ಯೂಟರ್‌ ಅನ್ನು ಎಂಟರ್‌ಪ್ರೈಸ್ ನಿರ್ವಹಣೆ ಮಾಡುತ್ತಿದೆ ಎಂದು ಪತ್ತೆಹಚ್ಚಲಾಗಿಲ್ಲ, ಆದ್ದರಿಂದ ಕಾರ್ಯನೀತಿಯು Chrome ವೆಬ್‌ ಸ್ಟೋರ್‌ನಲ್ಲಿ ಹೋಸ್ಟ್ ಮಾಡಲಾದ ವಿಸ್ತರಣೆಗಳನ್ನು ಮಾತ್ರ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಬಹುದು. Chrome ವೆಬ್‌ ಸ್ಟೋರ್‌ ಅಪ್‌ಡೇಟ್‌ URL "<ph name="CWS_UPDATE_URL" />" ಆಗಿರುತ್ತದೆ.</translation>
<translation id="4346197816712207223">ಸ್ವೀಕೃತ ಕ್ರೆಡಿಟ್‌ ಕಾರ್ಡ್‌ಗಳು</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">ಈ ಸೈಟ್‌ನಲ್ಲಿರುವ ದಾಳಿಕೋರರು ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನಲ್ಲಿರುವ ಮಾಹಿತಿ (ಉದಾಹರಣೆಗೆ, ಫೋಟೋಗಳು, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಮಾಹಿತಿಗಳು) ಕದಿಯಲು ಇಲ್ಲವೇ ಅಳಿಸಲು ಅಪಾಯಕಾರಿ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರಬಹುದು.</translation>
<translation id="4358461427845829800">ಪಾವತಿ ವಿಧಾನಗಳನ್ನು ನಿರ್ವಹಿಸಿ...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">ನಿರೀಕ್ಷಿತ <ph name="VALUE_TYPE" /> ಮೌಲ್ಯ.</translation>
<translation id="4377125064752653719">ನೀವು <ph name="DOMAIN" /> ಅನ್ನು ತಲುಪಲು ಪ್ರಯತ್ನಿಸಿದಿರಿ, ಆದರೆ ಸರ್ವರ್ ನೀಡಿದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಅದರ ನೀಡುವವರು ಹಿಂತೆಗೆದುಕೊಂಡಿದ್ದಾರೆ. ಇದರರ್ಥ ಸರ್ವರ್ ನೀಡಿದ ಸುರಕ್ಷತೆ ರುಜುವಾತುಗಳನ್ನು ಖಂಡಿತವಾಗಿ ನಂಬಲಾಗುವುದಿಲ್ಲ. ನೀವು ಆಕ್ರಮಣಕಾರರೊಂದಿಗೆ ಸಂವಹಿಸುತ್ತಿರಬಹುದು.</translation>
<translation id="4378154925671717803">ಫೋನ್</translation>
<translation id="4406896451731180161">ಹುಡುಕಾಟದ ಫಲಿತಾಂಶಗಳು</translation>
-<translation id="4406972042435603828">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಪ್ರಬಲ ಸಾಮರ್ಥ್ಯಗಳನ್ನು ಹೊಂದಿರುವ ವಿಸ್ತರಣೆಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ್ದಾರೆ.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> ಕುಕೀಗಳು</translation>
<translation id="4415426530740016218">ಪಿಕಪ್ ವಿಳಾಸ</translation>
<translation id="4424024547088906515">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು Chrome ಪಾಲಿಗೆ ವಿಶ್ವಾಸಾರ್ಹವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="443121186588148776">ಸೀರಿಯಲ್ ಪೋರ್ಟ್</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ನಿಮ್ಮ ಲಾಗಿನ್ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸ್ವೀಕರಿಸಲಿಲ್ಲ ಅಥವಾ ಅದನ್ನು ಒದಗಿಸದೆ ಇರಬಹುದು.</translation>
<translation id="4434045419905280838">ಪಾಪ್-ಅಪ್‌ಗಳು ಹಾಗೂ ಮರುನಿರ್ದೇಶನಗಳು</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">ಪ್ರಾಕ್ಸಿಯ ಬಳಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಆದರೆ ಬಹಿರಂಗ ಪ್ರಾಕ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ.</translation>
<translation id="445100540951337728">ಸಮ್ಮತಿಸಲಾದ ಡೆಬಿಟ್ ಕಾರ್ಡ್‌ಗಳು</translation>
+<translation id="4466881336512663640">ಫಾರ್ಮ್‌ನಲ್ಲಿ ಮಾಡಿರುವ ಬದಲಾವಣೆಗಳು ಕಳೆದು ಹೋಗುತ್ತವೆ. ನೀವು ಖಂಡಿತವಾಗಿಯೂ ಮುಂದುವರಿಯಲು ಬಯಸುತ್ತೀರಾ?</translation>
<translation id="4482953324121162758">ಈ ಸೈಟ್ ಅನುವಾದಕ್ಕೆ ಒಳಪಡುವುದಿಲ್ಲ.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">ಅಮಾನ್ಯ URL. ಪ್ರಮಾಣಿತ ವ್ಯವಸ್ಥೆಯೊಂದಿಗಿನ URL ಆಗಿರಬೇಕು, ಉದಾ. http://example.com or https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">ಮೌಲ್ಯೀಕರಿಸುವಿಕೆಯ ದೋಷ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">ಸಿಸ್ಟಂ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="450710068430902550">ನಿರ್ವಾಹಕರೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳುವುದು</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">ಕಾರ್ಡ್‌ಗಳು ಮತ್ತು ವಿಳಾಸಗಳನ್ನು ನಿಮ್ಮ Chrome ಮತ್ತು ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ (<ph name="ACCOUNT_EMAIL" />) ಪಡೆಯಲಾಗಿದೆ. ನೀವು ಅವುಗಳನ್ನು <ph name="BEGIN_LINK" />ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ<ph name="END_LINK" /> ನಿರ್ವಹಿಸಬಹುದು.</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">ವಿವರಗಳು</translation>
<translation id="4524805452350978254">ಕಾರ್ಡ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ಫ್ಲ್ಯಾಶ್‌</translation>
<translation id="4558551763791394412">ನಿಮ್ಮ ವಿಸ್ತರಣೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಿ.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">ವಿತರಣೆ</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕಿ</translation>
<translation id="4587425331216688090">Chrome ನಿಂದ ವಿಳಾಸವನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="4592951414987517459">ಆಧುನಿಕ ಸೈಫರ್ ಸೂಟ್ ಬಳಸುವ ಮೂಲಕ <ph name="DOMAIN" /> ಗೆ ನಿಮ್ಮ ಸಂಪರ್ಕವನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="4594403342090139922">&amp;ಅಳಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="4597348597567598915">ಗಾತ್ರ 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">ನನ್ನನ್ನು ಈಗ ಅಲ್ಲಿಗೆ ಕರೆದೊಯ್ಯಿರಿ</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರದಲ್ಲಿ ಸಾಕಷ್ಟು ದೋಷಗಳಿವೆ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="467809019005607715">Google ಸ್ಲೈಡ್‌ಗಳು</translation>
<translation id="4690462567478992370">ಅಮಾನ್ಯ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಬಳಸಿಕೊಂಡು ನಿಲ್ಲಿಸಿ</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">ನಿಮ್ಮ ಸಂಪರ್ಕಕ್ಕೆ ಅಡ್ಡಿಯಾಗಿದೆ</translation>
<translation id="471880041731876836">ಈ ಸೈಟ್‌ ಗೆ ಭೇಟಿ ನೀಡಲು ನೀವು ಅನುಮತಿ ಹೊಂದಿಲ್ಲ</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows ನೆಟ್‌ವರ್ಕ್ ಡಯಾಗ್ನಾಸ್ಟಿಕ್ಸ್ ರನ್ ಮಾಡಲಾಗುತ್ತಿದೆ<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">ನೀತಿಗಳನ್ನು ಮರುಲೋಡ್ ಮಾಡಿ</translation>
<translation id="4728558894243024398">ಪ್ಲಾಟ್‌ಫಾರ್ಮ್</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Chromium ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="473775607612524610">ಅಪ್‌ಡೇಟ್‌‌</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> ಹುಡುಕಾಟ ಸಲಹೆ</translation>
<translation id="4742407542027196863">ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ…</translation>
<translation id="4744603770635761495">ಪ್ರದರ್ಶನಗೊಳ್ಳುವಂತಹ ಹಾದಿ</translation>
+<translation id="4746351372139058112">ಸಂದೇಶಗಳು</translation>
<translation id="4750917950439032686">ಈ ಸೈಟ್‌ಗೆ ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಕಳುಹಿಸಿದಾಗ ಅದು (ಉದಾಹರಣೆಗೆ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಅಥವಾ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಗಳು) ಖಾಸಗಿಯಾಗಿರುತ್ತದೆ.</translation>
<translation id="4756388243121344051">&amp;ಇತಿಹಾಸ</translation>
<translation id="4758311279753947758">ಸಂಪರ್ಕ ಮಾಹಿತಿಯನ್ನು ಸೇರಿಸಿ</translation>
@@ -605,9 +687,9 @@
<translation id="4764776831041365478"><ph name="URL" /> ನಲ್ಲಿರುವ ವೆಬ್‌ಪುಟವು ತಾತ್ಕಾಲಿಕವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೇ ಇರಬಹುದು ಅಥವಾ ಅದನ್ನು ಶಾಶ್ವತವಾಗಿ ಹೊಸ ವೆಬ್ ವಿಳಾಸಕ್ಕೆ ಸರಿಸಲಾಗಿರಬಹುದು.</translation>
<translation id="4771973620359291008">ಅಪರಿಚಿತ ದೋಷವೊಂದು ಎದುರಾಗಿದೆ.</translation>
<translation id="4785689107224900852">ಈ ಟ್ಯಾಬ್‌ಗೆ ಬದಲಾಯಿಸಿ</translation>
-<translation id="4792143361752574037">ಸೆಶನ್ ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸುವಲ್ಲಿ ಸಮಸ್ಯೆ ಇದೆ. ಡಿಸ್ಕ್‌ಗೆ ಉಳಿಸುವುದು ಪ್ರಸ್ತುತ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಪುಟವನ್ನು ಮರುಲೋಡ್ ಮಾಡಿ.</translation>
<translation id="4798078619018708837">ನಿಮ್ಮ ಕಾರ್ಡ್‌ ವಿವರಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು <ph name="CREDIT_CARD" /> ಗೆ ಸಂಬಂಧಿಸಿದ ಅವಧಿ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು CVC ಅನ್ನು ನಮೂದಿಸಿ. ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿನ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation>
<translation id="4800132727771399293">ನಿಮ್ಮ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು CVC ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
+<translation id="480334179571489655">ಮೂಲ ಕಾರ್ಯನೀತಿಯ ದೋಷ</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>
@@ -622,7 +704,6 @@
<translation id="4881695831933465202">ತೆರೆ</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>
@@ -631,15 +712,15 @@
<translation id="4943872375798546930">ಯಾವುದೇ ಫಲಿತಾಂಶಗಳಿಲ್ಲ</translation>
<translation id="4950898438188848926">ಟ್ಯಾಬ್ ಬದಲಿಸುವ ಬಟನ್, ತೆರೆದಿರುವ ಟ್ಯಾಬ್, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> ಗೆ ಬದಲಾಯಿಸಲು Enter ಒತ್ತಿರಿ</translation>
<translation id="495170559598752135">ಕ್ರಿಯೆಗಳು</translation>
-<translation id="495832697253704892">ವಿಸ್ತರಣೆ ವರದಿ ಮಾಡುವಿಕೆ</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">ಪಟ್ಟಿಯನ್ನು ವಿಸ್ತರಿಸಿ</translation>
<translation id="4974590756084640048">ಎಚ್ಚರಿಕೆಗಳನ್ನು ಮರುಸಕ್ರಿಯಗೊಳಿಸಿ</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">ಎಲ್ಲವನ್ನೂ ನೋಡಿ</translation>
<translation id="4989809363548539747">ಈ ಪ್ಲಗಿನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ</translation>
-<translation id="4996230189582812866">ವರದಿ ಮಾಡುವಿಕೆ</translation>
<translation id="5002932099480077015">ಸಕ್ರಿಯವಾಗಿದ್ದರೆ, ವೇಗವಾಗಿ ಫಾರ್ಮ್ ಭರ್ತಿ ಮಾಡಲು Chrome ಈ ಸಾಧನದಲ್ಲಿ ನಿಮ್ಮ ಕಾರ್ಡ್‌ನ ಪ್ರತಿಯನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ.</translation>
-<translation id="5014174725590676422">Chrome ನಲ್ಲಿನ Google ಅಸಿಸ್ಟೆಂಟ್‌ನ ಮೊದಲ ಬಾರಿ ರನ್ ಮಾಡಿದ ಸ್ಕ್ರೀನ್ ಅನ್ನು ತೋರಿಸಲಾಗಿದೆ</translation>
<translation id="5015510746216210676">ಯಂತ್ರದ ಹೆಸರು:</translation>
+<translation id="5017554619425969104">ನೀವು ನಕಲಿಸಿದ ಪಠ್ಯ</translation>
<translation id="5018422839182700155">ಈ ಪುಟವನ್ನು ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ</translation>
<translation id="5019198164206649151">ಕಳಪೆ ಸ್ಥಿತಿಯಲ್ಲಿ ಸಂಗ್ರಹಣೆಯನ್ನು ಹಿಂತಿರುಗಿಸಲಾಗಿದೆ</translation>
<translation id="5023310440958281426">ನಿಮ್ಮ ನಿರ್ವಾಹಕ ನೀತಿಗಳನ್ನು ಪರಿಶೀಲಿಸಿ</translation>
@@ -649,35 +730,51 @@
<translation id="5034369478845443529">ಸ್ಥಳೀಯ ಸಂದರ್ಭ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">ಅನುಮತಿಸಿ</translation>
<translation id="5040262127954254034">ಗೌಪ್ಯತೆ</translation>
+<translation id="5043480802608081735">ನೀವು ನಕಲಿಸಿದ ಲಿಂಕ್</translation>
<translation id="5045550434625856497">ತಪ್ಪು ಪಾಸ್‌ವರ್ಡ್</translation>
<translation id="5056549851600133418">ನಿಮಗಾಗಿ ಲೇಖನಗಳು</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ಪ್ರಾಕ್ಸಿ ವಿಳಾಸವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM ಬಳಕೆ ರೀತಿಯ ಸಾಧನದ ಅಂಕಿಅಂಶಗಳು</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">ನಿಮ್ಮ ಸಾಧನವನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ ಮತ್ತು ನಿಮ್ಮ ಖಾತೆಯನ್ನು <ph name="ACCOUNT_DOMAIN" /> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ. ಅಂದರೆ, ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಖಾತೆಯನ್ನು ದೂರದಿಂದಲೇ ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದು ಎಂದರ್ಥ.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-ಬಿಟ್)</translation>
-<translation id="5128122789703661928">ಈ ಹೆಸರಿನ ಸೆಶನ್ ಅಳಿಸಲು ಮಾನ್ಯವಾಗಿಲ್ಲ.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">ವಿಳಾಸಗಳನ್ನು ನಿರ್ವಹಿಸಿ...</translation>
+<translation id="5138227688689900538">ಕಡಿಮೆ ತೋರಿಸಿ</translation>
<translation id="5141240743006678641">ನಿಮ್ಮ Google ರುಜುವಾತುಗಳ ಜೊತೆಗೆ ಸಿಂಕ್ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಎನ್‌ಕ್ರಿಫ್ಟ್ ಮಾಡಿ</translation>
<translation id="5145883236150621069">ನೀತಿ ಪ್ರತಿಕ್ರಿಯೆಯಲ್ಲಿ ದೋಷದ ಕೋಡ್ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">ಪುಟವನ್ನು ಹೊಸ ಅದೃಶ್ಯ ವಿಂಡೋದಲ್ಲಿ ತೆರೆಯಿರಿ (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> ಗೆ ಸಂಬಂಧಿಸಿದ CVC ಅನ್ನು ನಮೂದಿಸಿ. ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿನ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation>
<translation id="5169827969064885044">ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಖಾತೆಗೆ ನೀವು ಪ್ರವೇಶವನ್ನು ಕಳೆದುಕೊಳ್ಳಬಹುದು ಅಥವಾ ಗುರುತು ಕಳ್ಳತನಕ್ಕೆ ಒಳಗಾಗಬಹುದು. ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಇದೀಗ ಬದಲಾಯಿಸುವಂತೆ Chrome ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
<translation id="5171045022955879922">ಹುಡುಕಾಟ ನಡೆಸಿ ಅಥವಾ URL ಅನ್ನು ಟೈಪ್‌ ಮಾಡಿ</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">ಯಂತ್ರ</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> ರಲ್ಲಿ ಇಲ್ಲವೆ? ಈ ದೋಷವನ್ನು ವರದಿ ಮಾಡಿ</translation>
<translation id="5190835502935405962">ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳ ಬಾರ್</translation>
-<translation id="5200263511887412697">ಸಾಧನವನ್ನು ಇತ್ತೀಚೆಗೆ ಬಳಸಿರುವ ಬಳಕೆದಾರರ ಪಟ್ಟಿಯನ್ನು ವರದಿ ಮಾಡಿ</translation>
+<translation id="519422657042045905">ವಿವರಣೆ ಲಭ್ಯವಿಲ್ಲ</translation>
<translation id="5201306358585911203">ಈ ಪುಟದಲ್ಲಿ ಎಂಬೆಡ್ ಮಾಡಲಾದ ಪುಟವು ಹೀಗೆ ಹೇಳುತ್ತದೆ</translation>
<translation id="5205222826937269299">ಹೆಸರು ಅವಶ್ಯವಾಗಿದೆ</translation>
<translation id="5215116848420601511">Google Pay ಅನ್ನು ಬಳಸುವ ಪಾವತಿ ವಿಧಾನಗಳು ಮತ್ತು ವಿಳಾಸಗಳು</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ಇಮೇಲ್ ಅಗತ್ಯವಿದೆ</translation>
<translation id="5230733896359313003">ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸ</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಿ"</translation>
<translation id="5251803541071282808">ಮೇಘ</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">ನೆಟ್‌ವರ್ಕ್ ವಿಳಾಸಗಳು</translation>
<translation id="5285570108065881030">ಉಳಿಸಿದ ಎಲ್ಲ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ತೋರಿಸಿ</translation>
<translation id="5287240709317226393">ಕುಕೀಸ್ ಅನ್ನು ತೋರಿಸಿ</translation>
<translation id="5288108484102287882">ಕಾರ್ಯನೀತಿ ಮೌಲ್ಯಗಳ ಮೌಲ್ಯೀಕರಣ ಪ್ರಕ್ರಿಯೆಯು ಎಚ್ಚರಿಕೆಯ ಸಂದೇಶಗಳನ್ನು ತೋರಿಸುತ್ತಿದೆ</translation>
@@ -689,7 +786,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> ಗಳ <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">ಸಂಪರ್ಕ ಮಾಹಿತಿ ಆಯ್ಕೆಮಾಡಿ</translation>
<translation id="5327248766486351172">ಹೆಸರು</translation>
+<translation id="5329858041417644019">ನಿಮ್ಮ ಬ್ರೌಸರ್ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿಲ್ಲ</translation>
<translation id="5332219387342487447">ಶಿಪ್ಪಿಂಗ್ ವಿಧಾನ</translation>
+<translation id="5334013548165032829">ವಿವರವಾದ ಸಿಸ್ಟಂ ಲಾಗ್‌ಗಳು</translation>
<translation id="5344579389779391559">ಈ ಪುಟವು ನಿಮಗೆ ಶುಲ್ಕ ವಿಧಿಸಲು ಪ್ರಯತ್ನಿಸಬಹುದು</translation>
<translation id="5355557959165512791">ಸದ್ಯಕ್ಕೆ ನೀವು <ph name="SITE" /> ಗೆ ಭೇಟಿ ನೀಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಏಕೆಂದರೆ ಇದರ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳಲಾಗಿದೆ. ನೆಟ್‌ವರ್ಕ್ ದೋಷಗಳು ಮತ್ತು ಆಕ್ರಮಣಗಳು ತಾತ್ಕಾಲಿಕವಾಗಿರುತ್ತವೆ, ಹೀಗಾಗಿ ಈ ಪುಟವು ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಕಾರ್ಯನಿರ್ವಹಿಸಬಹುದು.</translation>
<translation id="536296301121032821">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಸಂಗ್ರಹಿಸುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ</translation>
@@ -697,6 +796,7 @@
<translation id="5377026284221673050">"ನಿಮ್ಮ ಗಡಿಯಾರ ಹಿಂದಿದೆ" ಅಥವಾ "ನಿಮ್ಮ ಗಡಿಯಾರ ಮುಂದಿದೆ" ಅಥವಾ "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">ನಿಮ್ಮ ಕಾರ್ಡ್‌ಗಳನ್ನು ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿ ಬಳಸಲು, ಸೈನ್ ಇನ್ ಮಾಡಿ ಮತ್ತು ಸಿಂಕ್ ಆನ್ ಮಾಡಿ.</translation>
<translation id="5386426401304769735">ಈ ಸೈಟ್‌ಗೆ ಪ್ರಮಾಣಪತ್ರ ಸರಣಿಯು SHA-1 ಬಳಸಿಕೊಂಡು ಸಹಿ ಮಾಡಲಾದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಈ ಸಮಯದಲ್ಲಿ ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವು ಮಾನ್ಯವಾಗಿಲ್ಲ. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
<translation id="5421136146218899937">ಬ್ರೌಸಿಂಗ್ ಡೇಟಾವನ್ನು ತೆರವುಗೊಳಿಸಿ...</translation>
<translation id="5430298929874300616">ಬುಕ್‌ಮಾರ್ಕ್‌ ತೆಗೆದುಹಾಕಿ</translation>
@@ -707,6 +807,7 @@
<translation id="5457113250005438886">ಅಮಾನ್ಯ</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">ಈ ಕಂಟೆಂಟ್‌ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿರುವ ಮಾಹಿತಿಯನ್ನು ಕದಿಯುವ ಅಥವಾ ಅಳಿಸುವ ಅಪಾಯಕಾರಿ ಸಾಫ್ಟ್‌ವೇರ್ ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರಬಹುದು. <ph name="BEGIN_LINK" />ಹೇಗಿದ್ದರೂ ತೋರಿಸಿ<ph name="END_LINK" />.</translation>
<translation id="54817484435770891">ಮಾನ್ಯವಾದ ವಿಳಾಸ ಸೇರಿಸಿ</translation>
<translation id="5490432419156082418">ವಿಳಾಸಗಳು ಮತ್ತು ಇನ್ನಷ್ಟು</translation>
@@ -714,10 +815,12 @@
<ph name="LINE_BREAK" />
ನಿಮ್ಮ ಸಿಸ್ಟಂ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="549333378215107354">ಗಾತ್ರ 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">ನಿರ್ವಹಿಸಿದ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="5510766032865166053">ಈ ಫೈಲನ್ನು ಬೇರೆಡೆಗೆ ಸರಿಸಿರಬಹುದು ಇಲ್ಲವೇ ಅಳಿಸಿರಬಹುದು.</translation>
<translation id="5523118979700054094">ನೀತಿ ಹೆಸರು</translation>
<translation id="552553974213252141">ಪಠ್ಯವನ್ನು ಸರಿಯಾಗಿ ಪ್ರತ್ಯೇಕಿಸಲಾಗಿದೆಯೇ?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">ವಿನಂತಿಸಿದ ಲೇಖನವನ್ನು ಹುಡುಕಲು ಸಾಧವಾಗಲಿಲ್ಲ.</translation>
<translation id="5541546772353173584">ಇಮೇಲ್ ಸೇರಿಸಿ</translation>
<translation id="5545756402275714221">ನಿಮಗಾಗಿ ಲೇಖನಗಳು</translation>
@@ -732,15 +835,21 @@
<translation id="5595485650161345191">ವಿಳಾಸ ಎಡಿಟ್ ಮಾಡಿ</translation>
<translation id="5598944008576757369">ಪಾವತಿ ವಿಧಾನವನ್ನು ಆರಿಸಿ</translation>
<translation id="560412284261940334">ನಿರ್ವಾಹಕ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="5610807607761827392">ನೀವು ಕಾರ್ಡ್‌ಗಳು ಮತ್ತು ವಿಳಾಸಗಳನ್ನು <ph name="BEGIN_LINK" />ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ<ph name="END_LINK" /> ನಿರ್ವಹಿಸಬಹುದು.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> ನಿಮ್ಮನ್ನು ತೀರಾ ಹೆಚ್ಚು ಬಾರಿ ಮರುನಿರ್ದೇಶಿಸಿದೆ.</translation>
<translation id="5629630648637658800">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ</translation>
<translation id="5631439013527180824">ಅಮಾನ್ಯವಾದ ಸಾಧನ ನಿರ್ವಹಣೆ ಟೋಕನ್</translation>
+<translation id="5632627355679805402">ನಿಮ್ಮ ಡೇಟಾವನ್ನು <ph name="TIME" /> ಸಮಯಕ್ಕೆ ನಿಮ್ಮ <ph name="BEGIN_LINK" />Google ಪಾಸ್‌ವರ್ಡ್<ph name="END_LINK" /> ನೊಂದಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಸಿಂಕ್ ಪ್ರಾರಂಭಿಸಲು ಅದನ್ನು ನಮೂದಿಸಿ.</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="563324245173044180">ವಂಚನೀಯ ವಿಷಯವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.</translation>
<translation id="5659593005791499971">ಇಮೇಲ್</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">ಈ ಸಾಧನದ ನಿರ್ವಾಹಕರು ಹೆಚ್ಚುವರಿ ಕಾರ್ಯವಿಧಾನಗಳಿಗಾಗಿ ವಿಸ್ತರಣೆಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ್ದಾರೆ. ವಿಸ್ತರಣೆಗಳು ನಿಮ್ಮ ಕೆಲವು ಡೇಟಾಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತವೆ.</translation>
<translation id="5675650730144413517">ಈ ಪುಟ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ</translation>
+<translation id="5684874026226664614">ಓಹ್. ಈ ಪುಟವನ್ನು ಅನುವಾದಿಸಲಾಗುವುದಿಲ್ಲ.</translation>
<translation id="5685654322157854305">ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
<translation id="5689199277474810259">JSON ಗೆ ರಫ್ತು ಮಾಡಿ</translation>
<translation id="5689516760719285838">ಸ್ಥಳ</translation>
@@ -749,38 +858,39 @@
<translation id="5710435578057952990">ಈ ವೆಬ್‌ಸೈಟ್‌ನ ಗುರುತಿಸುವಿಕೆಯನ್ನು ಇನ್ನೂ ಪರಿಶೀಲಿಸಲಾಗಿಲ್ಲ.</translation>
<translation id="5719499550583120431">ಪ್ರೀಪೇಯ್ಡ್ ಕಾರ್ಡ್‌ಗಳನ್ನು ಸಮ್ಮತಿಸಲಾಗಿದೆ.</translation>
<translation id="5720705177508910913">ಪ್ರಸ್ತುತ ಬಳಕೆದಾರ</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">ನೀವು ಇತರ ಸೈಟ್‌ಗಳಲ್ಲಿ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಮರುಬಳಕೆ ಮಾಡಿದ್ದಲ್ಲಿ Chrome ನಿಮ್ಮ ಪಾಸವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲು ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
<translation id="5732392974455271431">ನಿಮ್ಮ ಪೋಷಕರು ನಿಮಗಾಗಿ ಅದನ್ನು ಅನಿರ್ಬಂಧಿಸಬಹುದಾಗಿದೆ</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಕಾರ್ಡ್‌ ಉಳಿಸಿ}one{ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಕಾರ್ಡ್‌ಗಳನ್ನು ಉಳಿಸಿ}other{ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿ ಕಾರ್ಡ್‌ಗಳನ್ನು ಉಳಿಸಿ}}</translation>
<translation id="5763042198335101085">ಮಾನ್ಯವಾದ ಇಮೇಲ್ ವಿಳಾಸವನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="5765072501007116331">ವಿತರಣೆಯ ವಿಧಾನಗಳು ಹಾಗೂ ಆವಶ್ಯಕತೆಗಳನ್ನು ನೋಡಲು, ಒಂದು ವಿಳಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</translation>
-<translation id="5770114862687765385">ಫೈಲ್ ದೋಷಪೂರಿತವಾಗಿದೆ ಎಂದು ತೋರುತ್ತದೆ. ಸೆಶನ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲು 'ಮರುಹೊಂದಿಸು' ಬಟನ್ ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ</translation>
<translation id="5778550464785688721">MIDI ಸಾಧನಗಳು ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣ</translation>
<translation id="578305955206182703">ಕಿತ್ತಳೆ ಹಳದಿ</translation>
<translation id="57838592816432529">ಮ್ಯೂಟ್</translation>
<translation id="5784606427469807560">ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ದೃಢೀಕರಿಸುವಲ್ಲಿ ಸಮಸ್ಯೆ ಇದೆ. ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="5785756445106461925">ಅಲ್ಲದೇ, ಸುರಕ್ಷಿತವಲ್ಲದ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಈ ಪುಟ ಒಳಗೊಂಡಿದೆ. ಪ್ರಯಾಣದ ಸಂದರ್ಭದಲ್ಲಿ ಈ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಇತರರೂ ವೀಕ್ಷಿಸಬಹುದಾಗಿದೆ ಮತ್ತು ಪುಟದ ನೋಟವೇ ಬದಲಾಗುವಂತೆ ಆಕ್ರಮಣಕಾರರು ಅದನ್ನು ತಿದ್ದಬಹುದಾಗಿದೆ.</translation>
<translation id="5786044859038896871">ನಿಮ್ಮ ಕಾರ್ಡ್ ಮಾಹಿತಿ ಭರ್ತಿ ಮಾಡಲು ನೀವು ಬಯಸುವಿರಾ?</translation>
+<translation id="5798290721819630480">ಬದಲಾವಣೆಗಳನ್ನು ತ್ಯಜಿಸುವುದೇ?</translation>
<translation id="5798683403665926540">ಮುಖಪುಟವನ್ನು Chrome ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಿ</translation>
<translation id="5803412860119678065">ನಿಮ್ಮ <ph name="CARD_DETAIL" /> ಭರ್ತಿ ಮಾಡಲು ನೀವು ಬಯಸುವಿರಾ?</translation>
<translation id="5804241973901381774">ಅನುಮತಿಗಳು</translation>
<translation id="5810442152076338065">ಬಳಕೆಯಲ್ಲಿಲ್ಲದ ಸೈಫರ್ ಸೂಟ್ ಬಳಸುವ ಮೂಲಕ <ph name="DOMAIN" /> ಗೆ ನಿಮ್ಮ ಸಂಪರ್ಕವನ್ನು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ.</translation>
<translation id="5813119285467412249">&amp;ಸೇರಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="5838278095973806738">ಈ ಸೈಟ್‌ನಲ್ಲಿ ನೀವು ಯಾವುದೇ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು (ಉದಾಹರಣೆಗೆ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಅಥವಾ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್‌ಗಳು) ನಮೂದಿಸಬಾರದು, ಏಕೆಂದರೆ ಅದು ದಾಳಿಕೋರರ ಮೂಲಕ ಕಳುವಾಗಬಹುದು.</translation>
+<translation id="5860033963881614850">ಆಫ್</translation>
<translation id="5863847714970149516">ಮುಂದಿನ ಪುಟವು ನಿಮಗೆ ಶುಲ್ಕ ವಿಧಿಸಲು ಪ್ರಯತ್ನಿಸಬಹುದು</translation>
<translation id="5866257070973731571">ಫೋನ್ ಸಂಖ್ಯೆಯನ್ನು ಸೇರಿಸಿ</translation>
<translation id="5869405914158311789">ಈ ಸೈಟ್ ತಲುಪಲಾಗುವುದಿಲ್ಲ</translation>
<translation id="5869522115854928033">ಉಳಿಸಲಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು</translation>
<translation id="5887400589839399685">ಕಾರ್ಡ್ ಉಳಿಸಲಾಗಿದೆ</translation>
-<translation id="5893718151540690985">ನೆಟ್‌ವರ್ಕ್ ಇಂಟರ್ಫೇಸ್‌ಗಳ ಪಟ್ಟಿಯನ್ನು ಅದರ ಪ್ರಕಾರಗಳು ಮತ್ತು ಹಾರ್ಡ್‌ವೇರ್ ವಿಳಾಸಗಳ ಸಮೇತವಾಗಿ ವರದಿ ಮಾಡಿ</translation>
<translation id="5893752035575986141">ಕ್ರೆಡಿಟ್‌ ಕಾರ್ಡ್‌ಗಳನ್ನು ಸಮ್ಮತಿಸಲಾಗಿದೆ.</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="5916664084637901428">ಆನ್‌</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google ಖಾತೆಯಲ್ಲಿ ಕಾರ್ಡ್ ಅನ್ನು ಉಳಿಸಬೇಕೇ?</translation>
<translation id="5922853866070715753">ಬಹುತೇಕ ಮುಗಿದಿದೆ</translation>
<translation id="5932224571077948991">ಅತಿಕ್ರಮಣಕಾರಿಯಾಗಿರುವ ಅಥವಾ ತಪ್ಪುದಾರಿಗೆಳೆಯುವ ಜಾಹೀರಾತುಗಳನ್ನು ಸೈಟ್ ತೋರಿಸುತ್ತದೆ</translation>
-<translation id="5939518447894949180">ಮರುಹೊಂದಿಸು</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> ತೆರೆಯಲಾಗುತ್ತಿದೆ…</translation>
<translation id="5951495562196540101">ಗ್ರಾಹಕರ ಖಾತೆಯ ಮೂಲಕ ನೋಂದಣಿ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ (ಪ್ಯಾಕೇಜ್ ಮಾಡಲಾದ ಪರವಾನಗಿ ಲಭ್ಯವಿದೆ).</translation>
<translation id="5967592137238574583">ಸಂಪರ್ಕ ಮಾಹಿತಿಯನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation>
@@ -788,6 +898,7 @@
<translation id="5975083100439434680">ಝೂಮ್ ಔಟ್</translation>
<translation id="5977489021191000276">ನಿಮ್ಮ ಸಾಧನವನ್ನು ಓರ್ವ ನಿರ್ವಾಹಕರು ನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ.</translation>
<translation id="5977976211062815271">ಈ ಸಾಧನದಲ್ಲಿರುವವು</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">ಪಾವತಿ ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ</translation>
<translation id="5989320800837274978">ಹೊಂದಿಸಿದ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳು ಆಗಲಿ ಅಥವಾ .pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಿಲ್ಲ.</translation>
<translation id="5990559369517809815">ಸರ್ವರ್‌ಗಳ ವಿನಂತಿಗಳನ್ನು ವಿಸ್ತರಣೆಯಿಂದ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.</translation>
@@ -798,8 +909,8 @@
<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="6033927989869462158">CPU/RAM ಬಳಕೆ ರೀತಿಯ ಹಾರ್ಡ್‌ವೇರ್ ಅಂಕಿಅಂಶಗಳನ್ನು ವರದಿ ಮಾಡಿ</translation>
<translation id="6034000775414344507">ತಿಳಿ ಬೂದು</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">ಸಮಸ್ಯೆ ಮುಂದುವರಿದರೆ, ಸೈಟ್ ಮಾಲೀಕರನ್ನು ಸಂಪರ್ಕಿಸಿ.</translation>
<translation id="6040143037577758943">ಮುಚ್ಚಿರಿ</translation>
<translation id="6044573915096792553">ಗಾತ್ರ 12</translation>
@@ -808,10 +919,10 @@
<translation id="6051221802930200923">ನೀವು ಸದ್ಯಕ್ಕೆ <ph name="SITE" /> ಗೆ ಭೇಟಿ ನೀಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಏಕೆಂದರೆ, ವೆಬ್‌ಸೈಟ್ ಪ್ರಮಾಣಪತ್ರ ಪಿನ್ ಮಾಡುವಿಕೆಯನ್ನು ಬಳಸುತ್ತದೆ. ನೆಟ್‌ವರ್ಕ್ ದೋಷಗಳು ಮತ್ತು ಆಕ್ರಮಣಗಳು ತಾತ್ಕಾಲಿಕವಾಗಿರುತ್ತವೆ, ಹೀಗಾಗಿ ಈ ಪುಟವು ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಕಾರ್ಯ ನಿರ್ವಹಿಸಬಹುದು.</translation>
<translation id="6058977677006700226">ನಿಮ್ಮ ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿಯೂ ನಿಮ್ಮ ಕಾರ್ಡ್‌ಗಳನ್ನು ಬಳಸಬೇಕೇ?</translation>
<translation id="6059925163896151826">USB ಸಾಧನಗಳು</translation>
-<translation id="6071091556643036997">ಕಾರ್ಯನೀತಿಯ ವಿಧ ಅಮಾನ್ಯವಾಗಿದೆ.</translation>
<translation id="6080696365213338172">ನಿರ್ವಾಹಕರು-ಒದಗಿಸಿದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಬಳಸಿಕೊಂಡು ನೀವು ವಿಷಯವನ್ನು ಪ್ರವೇಶಿಸಿರುವಿರಿ. <ph name="DOMAIN" /> ಗೆ ನೀವು ಒದಗಿಸುವ ಡೇಟಾವನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ತಡೆಹಿಡಿಯಬಹುದಾಗಿದೆ.</translation>
<translation id="6094273045989040137">ಟಿಪ್ಪಣಿ</translation>
<translation id="610911394827799129">ನಿಮ್ಮ Google ಖಾತೆಯು <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ನಲ್ಲಿ ಇತರ ವಿಧಗಳ ಬ್ರೌಸಿಂಗ್ ಇತಿಹಾಸವನ್ನು ಹೊಂದಿರಬಹುದು</translation>
+<translation id="6132597952260690497">ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿರುವ ವಿಸ್ತರಣೆಗಳು ಮತ್ತು ಪ್ಲಗ್ಇನ್‌ಗಳ ಕುರಿತು ಮಾಹಿತಿ</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ಯಾವುದೂ ಇಲ್ಲ}=1{1 ಪಾಸ್‌ವರ್ಡ್ (ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ)}one{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು (ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ)}other{# ಪಾಸ್‌ವರ್ಡ್‌ಗಳು (ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ)}}</translation>
<translation id="6146055958333702838">ಯಾವುದೇ ಕೇಬಲ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ. ನೀವು ಬಳಸುತ್ತಿರಬಹುದಾದ ಯಾವುದೇ ರೂಟರ್‌ಗಳು, ಮೋಡೆಮ್‌ಗಳು ಅಥವಾ ಇತರ ನೆಟ್‌ವರ್ಕ್ ಸಾಧನಗಳನ್ನು ರೀಬೂಟ್ ಮಾಡಿ.</translation>
<translation id="614940544461990577">ಪ್ರಯತ್ನಿಸಿ:</translation>
@@ -845,15 +956,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> ಕ್ಕಿಂತ ಕಡಿಮೆ ಇರುವುದನ್ನು ತೆಗೆದುಹಾಕಿ. ನಿಮ್ಮ ನಂತರದ ಭೇಟಿಯ ಸಮಯದಲ್ಲಿ ಕೆಲವು ಸೈಟ್‌ಗಳು ನಿಧಾನವಾಗಿ ಲೋಡ್ ಆಗಬಹುದು.</translation>
<translation id="6337534724793800597">ಹೆಸರಿನ ಪ್ರಕಾರವಾಗಿ ನೀತಿಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ</translation>
<translation id="6358450015545214790">ಇವುಗಳ ಅರ್ಥವೇನು?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">ಮುಂದಕ್ಕೆ ಶುಲ್ಕವಿರುವ ಸಾಧ್ಯತೆಗಳಿವೆ</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 ಇತರ ಸಲಹೆ}one{# ಇತರ ಸಲಹೆಗಳು}other{# ಇತರ ಸಲಹೆಗಳು}}</translation>
<translation id="6387754724289022810">ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಪಾವತಿಸಲು, ನಿಮ್ಮ ಕಾರ್ಡ್‌ ಮತ್ತು ನಿಮ್ಮ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು Google ಖಾತೆಯಲ್ಲಿ ಮತ್ತು ಈ ಸಾಧನದಲ್ಲಿ ಉಳಿಸಿ.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> ಗೆ ಮುಕ್ತಾಯ ದಿನಾಂಕ ಮತ್ತು ಸಿವಿಸಿ ಅನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="6414888972213066896">ಈ ಸೈಟ್‌ಗೆ ಭೇಟಿ ನೀಡುವುದು ಸರಿಯೇ ಎಂದು ನೀವು ನಿಮ್ಮ ಪೋಷಕರನ್ನು ಕೇಳಿರುವಿರಿ</translation>
<translation id="6417515091412812850">ಪ್ರಮಾಣಪತ್ರವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆಯೆ ಎಂಬುದನ್ನು ಪರಿಶೀಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ.</translation>
<translation id="6433490469411711332">ಸಂಪರ್ಕ ಮಾಹಿತಿ ಎಡಿಟ್ ಮಾಡಿ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ಸಂಪರ್ಕಗೊಳ್ಳಲು ನಿರಾಕರಿಸಿದೆ.</translation>
+<translation id="6434309073475700221">ತಿರಸ್ಕರಿಸಿ</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">ಇನ್ನಷ್ಟು ಮಾಹಿತಿಯನ್ನು ಸೇರಿಸಿ</translation>
<translation id="6447842834002726250">ಕುಕೀಸ್</translation>
<translation id="6451458296329894277">ಮರುಸಲ್ಲಿಕೆ ಫಾರ್ಮ್ ಅನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ</translation>
@@ -866,11 +983,17 @@
<translation id="6508722015517270189">Chrome ಮರುಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="6529602333819889595">&amp;ಅಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="6534179046333460208">ಭೌತಿಕ ವೆಬ್ ಸಲಹೆಗಳು</translation>
+<translation id="6556866813142980365">ಮತ್ತೆಮಾಡು</translation>
<translation id="6563469144985748109">ನಿಮ್ಮ ಮ್ಯಾನೇಜರ್ ಇನ್ನೂ ಇದನ್ನು ಅಂಗೀಕರಿಸಿಲ್ಲ</translation>
<translation id="6569060085658103619">ನೀವು ವಿಸ್ತರಣೆ ಪುಟವನ್ನು ವೀಕ್ಷಿಸುತ್ತಿರುವಿರಿ</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">ತಿಳಿ ಗುಲಾಬಿ</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">ನೀವು ನಕಲಿಸಿದ ಲಿಂಕ್</translation>
+<translation id="6591833882275308647">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿಲ್ಲ</translation>
<translation id="6596325263575161958">ಎನ್‌ಕ್ರಿಫ್ಶನ್ ಆಯ್ಕೆಗಳು</translation>
<translation id="6604181099783169992">ಚಲನೆ ಅಥವಾ ಬೆಳಕಿನ ಸೆನ್ಸರ್‌ಗಳು</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">ಸಂಪರ್ಕ ಮಾಹಿತಿ</translation>
<translation id="6626291197371920147">ಮಾನ್ಯವಾದ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಸೇರಿಸಿ</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> ಹುಡುಕಾಟ</translation>
@@ -879,6 +1002,7 @@
<translation id="6644283850729428850">ಈ ನೀತಿಯನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ಯಾವುದೂ ಇಲ್ಲ}=1{1 ಸೈಟ್‌‍ನಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}one{# ಸೈಟ್‌ಗಳಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}other{# ಸೈಟ್‌ಗಳಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}}</translation>
<translation id="6657585470893396449">ಪಾಸ್‌ವರ್ಡ್</translation>
+<translation id="6670613747977017428">ಸುರಕ್ಷತೆಗೆ ಹಿಂತಿರುಗಿ.</translation>
<translation id="6671697161687535275">Chromium ನಿಂದ ಫಾರ್ಮ್ ಸಲಹೆಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="6685834062052613830">ಸೈನ್‌ ಔಟ್‌ ಮಾಡಿ ಹಾಗೂ ಸೆಟಪ್ ಪೂರ್ಣಗೊಳಿಸಿ</translation>
<translation id="6710213216561001401">ಹಿಂದೆ</translation>
@@ -886,12 +1010,15 @@
<translation id="671076103358959139">ನೋಂದಣಿಯ ಟೋಕನ್:</translation>
<translation id="6711464428925977395">ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌‌ನಲ್ಲಿ ಏನೋ ದೋಷವಿದೆ ಅಥವಾ ವಿಳಾಸವು ತಪ್ಪಾಗಿದೆ.</translation>
<translation id="6723740634201835758">ನಿಮ್ಮ Google ಖಾತೆಯಲ್ಲಿರುವವು</translation>
+<translation id="6738516213925468394">ನಿಮ್ಮ ಡೇಟಾವನ್ನು <ph name="TIME" /> ಸಮಯಕ್ಕೆ ನಿಮ್ಮ <ph name="BEGIN_LINK" />ಸಿಂಕ್ ಪಾಸ್‌ಫ್ರೇಸ್<ph name="END_LINK" /> ನೊಂದಿಗೆ ಎನ್‌ಕ್ರಿಪ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಸಿಂಕ್ ಪ್ರಾರಂಭಿಸಲು ಅದನ್ನು ನಮೂದಿಸಿ.</translation>
<translation id="674375294223700098">ಅಪರಿಚಿತ ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರ ದೋಷ.</translation>
<translation id="6744009308914054259">ಸಂಪರ್ಕಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸುತ್ತಿರುವಾಗ, ಆಫ್‌ಲೈನ್ ​​ಲೇಖನಗಳನ್ನು ಓದಲು ನೀವು ಡೌನ್‌ಲೋಡ್‌ಗಳಿಗೆ ಭೇಟಿ ನೀಡಬಹುದು.</translation>
<translation id="6753269504797312559">ನೀತಿ ಮೌಲ್ಯ</translation>
<translation id="6757797048963528358">ನಿಮ್ಮ ಸಾಧನವು ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗಿದೆ.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">ನಿಮ್ಮ ಪೋಷಕರು ಇನ್ನೂ ಇದನ್ನು ಅಂಗೀಕರಿಸಿಲ್ಲ</translation>
<translation id="67862343314499040">ನೇರಳೆ</translation>
+<translation id="6786747875388722282">ವಿಸ್ತರಣೆಗಳು</translation>
<translation id="679355240208270552">ಡೀಫಾಲ್ಟ್ ಹುಡುಕಾಟವನ್ನು ನೀತಿಯ ಮೂಲಕ ಸಕ್ರಿಯಗೊಳಿಸದ ಕಾರಣ ನಿರ್ಲಕ್ಷಿಸಲಾಗಿದೆ.</translation>
<translation id="681021252041861472">ಅಗತ್ಯವಿರುವ ಕ್ಷೇತ್ರ</translation>
<translation id="6810899417690483278">ಕಸ್ಟಮೈಸೇಶನ್ ಐಡಿ</translation>
@@ -924,10 +1051,12 @@
<translation id="6965978654500191972">ಸಾಧನ</translation>
<translation id="6970216967273061347">ಜಿಲ್ಲೆ</translation>
<translation id="6973656660372572881">ಹೊಂದಿಸಿದ ಪ್ರಾಕ್ಸಿ ಸರ್ವರ್‌ಗಳು ಮತ್ತು .pac ಸ್ಕ್ರಿಪ್ಟ್ URL ಎರಡನ್ನೂ ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿದೆ.</translation>
+<translation id="6973932557599545801">ಕ್ಷಮಿಸಿ, ನನ್ನಿಂದ ಸಹಾಯ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ, ನಿಮ್ಮ ವಿವೇಚನೆಗೆ ತಕ್ಕಂತೆ ಮುಂದುವರಿಸಿ.</translation>
<translation id="6979158407327259162">Google ಡ್ರೈವ್‌‌</translation>
<translation id="6979440798594660689">ಮ್ಯೂಟ್ (ಡಿಫಾಲ್ಟ್)</translation>
<translation id="6984479912851154518">ಬಾಹ್ಯ ಆ್ಯಪ್ ಮೂಲಕ ಪಾವತಿಸಲು ಖಾಸಗಿ ಮೋಡ್‌‌ ತೊರೆಯಲಾಗುತ್ತಿದೆ. ಮುಂದುವರಿಸುವುದೇ?</translation>
<translation id="6989763994942163495">ಸುಧಾರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೋರಿಸು...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" />ಭಾಷೆಯನ್ನು ಯಾವಾಗಲೂ ಅನುವಾದಿಸಿ</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">ಇವುಗಳು ಒಂದು ಬಾರಿ ಪಾವತಿಸುವಂತಹ ಶುಲ್ಕಗಳಾಗಿರಬಹುದು, ಮರುಕಳಿಸುವ ಶುಲ್ಕಗಳಾಗಿರಬಹುದು ಅಥವಾ ಸ್ಪಷ್ಟವಾಗಿಲ್ಲದೇ ಇರಬಹುದು.</translation>
@@ -943,28 +1072,36 @@
<translation id="7108338896283013870">ಮರೆಮಾಡಿ</translation>
<translation id="7108819624672055576">ವಿಸ್ತರಣೆಯ ಮೂಲಕ ಅನುಮತಿಸಲಾಗಿದೆ</translation>
<translation id="7111012039238467737">(ಮಾನ್ಯವಾಗಿದೆ)</translation>
+<translation id="7118618213916969306">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್ URL ಗಾಗಿ ಹುಡುಕಿ, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">ಇತರ ಟ್ಯಾಬ್‌ಗಳನ್ನು ಅಥವಾ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಮುಚ್ಚಿ</translation>
<translation id="7129409597930077180">ಈ ವಿಳಾಸಕ್ಕೆ ರವಾನಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಬೇರೊಂದು ವಿಳಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ.</translation>
<translation id="7135130955892390533">ಕಾರ್ಯನೀತಿ ಸ್ಥಿತಿಯನ್ನು ತೋರಿಸಿ</translation>
<translation id="7138472120740807366">ವಿತರಣೆ ವಿಧಾನ</translation>
<translation id="7139724024395191329">ಎಮಿರೇಟ್</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ನಸು ಕೆನ್ನೀಲಿ</translation>
-<translation id="7158980942472052083">ಅಮಾನ್ಯ URL. ಪ್ರಮಾಣಿತ ವ್ಯವಸ್ಥೆಯೊಂದಿಗಿನ URL ಆಗಿರಬೇಕು.</translation>
<translation id="717330890047184534">Gaia ಐಡಿ:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">ನೀವು ಪ್ರವೇಶಿಸುತ್ತಿರುವ ಸರ್ವರ್, <ph name="ORIGIN" />, ತನ್ನ ಎಲ್ಲಾ ವಿನಂತಿಗಳಿಗೆ
+ ಅನ್ವಯವಾಗುವ ಸುರಕ್ಷತೆ ನೀತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಂಡಿದೆ. ಆದರೆ ಕಾರ್ಯನೀತಿಯನ್ನು
+ ಒದಗಿಸುವ ಬದಲಿಗೆ, ಅದು ಬ್ರೌಸರ್ ಅನ್ನು ಬೇರೆಲ್ಲಿಗೋ ಮರುನಿರ್ದೇಶಿಸಿದೆ, ಇದು <ph name="SITE" /> ಗಾಗಿ
+ ನಿಮ್ಮ ವಿನಂತಿಯನ್ನು ಈಡೇರಿಸದ ಹಾಗೆ ಬ್ರೌಸರ್ ಅನ್ನು ತಡೆಯುತ್ತದೆ.</translation>
<translation id="7179323680825933600">ಪಾವತಿ ವಿಧಾನಗಳನ್ನು ಉಳಿಸಿ ಮತ್ತು ಭರ್ತಿ ಮಾಡಿ</translation>
<translation id="7180611975245234373">ರಿಫ್ರೆಶ್ ಮಾಡಿ</translation>
<translation id="7182878459783632708">ಯಾವುದೇ ನೀತಿಗಳನ್ನು ಹೊಂದಿಸಿಲ್ಲ</translation>
<translation id="7186367841673660872">ಈ ಪುಟವನ್ನು<ph name="ORIGINAL_LANGUAGE" />ನಿಂದ<ph name="LANGUAGE_LANGUAGE" />ಗೆ ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> ತೆಗೆದುಹಾಕಿ. ನಿಮ್ಮ ನಂತರದ ಭೇಟಿಯ ಸಮಯದಲ್ಲಿ ಕೆಲವು ಸೈಟ್‌ಗಳು ನಿಧಾನವಾಗಿ ಲೋಡ್ ಆಗಬಹುದು.</translation>
<translation id="719464814642662924">ವೀಸಾ</translation>
+<translation id="7201591969684833065">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಇವುಗಳನ್ನು ನೋಡಬಹುದು:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> ಭದ್ರತೆ ಮಾನದಂಡಗಳನ್ನು ಅನುಸರಿಸುತ್ತಿಲ್ಲ.</translation>
<translation id="721197778055552897">ಈ ತೊಂದರೆಯ ಬಗ್ಗೆ <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">ಸಂಪರ್ಕವು <ph name="SSL_VERSION" /> ಅನ್ನು ಬಳಸುತ್ತದೆ.</translation>
<translation id="7220786058474068424">ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">ಮುಂದಿರುವ ಸೈಟ್‌ನಲ್ಲಿ ಮಾಲ್‌ವೇರ್ ಇದೆ</translation>
+<translation id="724766306220616965">ಎಚ್ಚರಿಕೆಗಳು, ಸಂಘರ್ಷ</translation>
<translation id="724975217298816891">ನಿಮ್ಮ ಕಾರ್ಡ್‌ ವಿವರಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು <ph name="CREDIT_CARD" /> ಗೆ ಮುಕ್ತಾಯ ದಿನಾಂಕ ಮತ್ತು CVC ಅನ್ನು ನಮೂದಿಸಿ. ನೀವು ಒಮ್ಮೆ ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮ್ಮ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation>
<translation id="7251437084390964440">ನೆಟ್‌ವರ್ಕ್ ಕಾನ್ಫಿಗರೇಶನ್, ONC ಮಾನದಂಡಕ್ಕೆ ಅನುಗುಣವಾಗಿಲ್ಲ. ಕಾನ್ಫಿಗರೇಶನ್‌ನಲ್ಲಿನ ಕೆಲವು ಭಾಗಗಳನ್ನು ಆಮದು ಮಾಡಲು ಸಾಧ್ಯವಾಗದಿರಬಹುದು.
ಹೆಚ್ಚುವರಿ ವಿವರಗಳು:
@@ -977,11 +1114,14 @@
<translation id="7300012071106347854">ಕೋಬಾಲ್ಟ್ ನೀಲಿ</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">ಕ್ರ್ಯಾಶ್ ವರದಿಯನ್ನು <ph name="CRASH_TIME" /> ರಲ್ಲಿ ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ (ಬಳಕೆದಾರರ ಮೂಲಕ ವಿನಂತಿಸಲಾದ ಅಪ್‌ಲೋಡ್ ಅನ್ನು, ಇನ್ನೂ ಅಪ್‌ಲೋಡ್ ಮಾಡಿಲಾಗಿಲ್ಲ)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್<ph name="END_LINK" /> ಎಚ್ಚರಿಕೆಗಳು</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">ಸಂಪರ್ಕ ಸಹಾಯ</translation>
<translation id="7334320624316649418">&amp;ಮರುಕ್ರಮಗೊಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="733923710415886693">ಪ್ರಮಾಣಪತ್ರ ಪಾರದರ್ಶಕತೆಯ ಮೂಲಕ ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಬಹಿರಂಗಪಡಿಸಲಾಗಿಲ್ಲ.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">ಕಮಾಂಡ್ ಸಾಲು</translation>
-<translation id="7365061714576910172">Linux ಅನ್ನು ರಫ್ತು ಮಾಡಿ</translation>
<translation id="7372973238305370288">ಹುಡುಕಾಟ ಫಲಿತಾಂಶ</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ಬೇಡ</translation>
@@ -989,6 +1129,7 @@
<translation id="7381288752349550461">ನಿರ್ವಹಿಸಲಾದ ಸೆಶನ್‌ ಅತಿಕ್ರಮಣ</translation>
<translation id="7390545607259442187">ಕಾರ್ಡ್ ಅನ್ನು ದೃಢೀಕರಿಸಿ</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">ನಿಮ್ಮ <ph name="DEVICE_NAME" /> ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation>
<translation id="7407424307057130981">&lt;p&gt;ನಿಮ್ಮ ವಿಂಡೋಸ್ ಕಂಪ್ಯೂಟರ್‌ನಲ್ಲಿ ಸೂಪರ್‌ಫಿಶ್ ಸಾಫ್ಟ್‌ವೇರ್ ಇದ್ದರೆ, ನಿಮಗೆ ಈ ದೋಷ ಕಾಣಿಸುತ್ತದೆ.&lt;/p&gt;
&lt;p&gt;ಈ ಹಂತಗಳನ್ನು ಅನುಸರಿಸಿ ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಾಫ್ಟ್‌ವೇರ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದರೆ ನೀವು ವೆಬ್‌‍ಗೆ ಪ್ರವೇಶಿಸಬಹುದಾಗಿದೆ. ನಿಮಗೆ ನಿರ್ವಾಹಕರ ಸವಲತ್ತುಗಳ ಅಗತ್ಯವಿದೆ.&lt;/p&gt;
&lt;ol&gt;
@@ -998,7 +1139,7 @@
&lt;li&gt;&lt;strong&gt;ಸೇವೆಯ ಸ್ಥಿತಿಯ&lt;/strong&gt; ಅಡಿಯಲ್ಲಿ, &lt;strong&gt;ನಿಲ್ಲಿಸಿ&lt;/strong&gt; ಕ್ಲಿಕ್ ಮಾಡಿ
&lt;li&gt; &lt;strong&gt;ಅನ್ವಯಿಸಿ&lt;/strong&gt; ಕ್ಲಿಕ್ ಮಾಡಿ, ನಂತರ &lt;strong&gt;ಸರಿ&lt;/strong&gt; ಕ್ಲಿಕ್ ಮಾಡಿ
&lt;li&gt;ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನಿಂದ ಸಾಫ್ಟ್‌ವೇರ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ತೆಗೆದುಹಾಕುವುದು ಹೇಗೆ ಎಂದು ತಿಳಿದುಕೊಳ್ಳಲು &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome ಸಹಾಯ ಕೇಂದ್ರಕ್ಕೆ&lt;/a&gt; ಭೇಟಿ ನೀಡಿ &lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> ನಿರ್ವಹಣೆ</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ…</translation>
<translation id="7419106976560586862">ಪ್ರೊಫೈಲ್ ಹಾದಿ</translation>
<translation id="7437289804838430631">ಸಂಪರ್ಕ ಮಾಹಿತಿಯನ್ನು ಸೇರಿಸು</translation>
@@ -1007,22 +1148,24 @@
<translation id="7442725080345379071">ತಿಳಿ ಕಿತ್ತಳೆ</translation>
<translation id="7444046173054089907">ಈ ಸೈಟ್ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation>
<translation id="7445762425076701745">ನೀವು ಸಂಪರ್ಕ ಮಾಡಿರುವ ಸರ್ವರ್‌ನ ಗುರುತನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಮೌಲ್ಯೀಕರಿಸಲಾಗುವುದಿಲ್ಲ. ನೀವು ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿಯೇ ಮಾನ್ಯವಿರುವ ಹೆಸರನ್ನು ಮಾತ್ರ ಬಳಸಿಕೊಂಡು ಸಂಪರ್ಕ ಹೊಂದಿರುವಿರಿ, ಇದರ ಮಾಲಿಕತ್ವವನ್ನು ಮೌಲ್ಯೀಕರಿಸುವ ಯಾವ ಅವಕಾಶವನ್ನೂ ಬಾಹ್ಯ ಪ್ರಮಾಣಪತ್ರ ಪ್ರಾಧಿಕಾರವು ಹೊಂದಿಲ್ಲ. ಕೆಲವು ಪ್ರಮಾಣಪತ್ರ ಪ್ರಾಧಿಕಾರಗಳು, ಯಾವುದೇ ಹೆಸರನ್ನು ಪರಿಗಣಿಸದೇ, ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡುವ ಕಾರಣದಿಂದಾಗಿ, ನೀವು ಉದ್ದೇಶಿತ ವೆಬ್‌ಸೈಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಿರುವಿರೇ ಹೊರತು ದಾಳಿ ಮಾಡಲು ಅಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವ ಯಾವ ಅವಕಾಶವೂ ಇಲ್ಲ.</translation>
-<translation id="7449109375006139765">ನಿರ್ವಹಣೆ ಸರ್ವರ್‌ಗೆ ಸಿಸ್ಟಂ ಲಾಗ್‌ಗಳನ್ನು ಕಳುಹಿಸಿ</translation>
<translation id="7451311239929941790">ಈ ಸಮಸ್ಯೆಯ ಕುರಿತು <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯುವಿಕೆ<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">ಜಾಗತಿಕ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ (ನಿರ್ಬಂಧಿಸಿ)</translation>
<translation id="7460618730930299168">ವೀಕ್ಷಣೆ ಅವಧಿಯು ನೀವು ಆಯ್ಕೆ ಮಾಡಿರುವುದಕ್ಕಿಂತಲೂ ಭಿನ್ನವಾಗಿದೆ. ಮುಂದುವರಿಯುವುದೇ?</translation>
<translation id="7473891865547856676">ಇಲ್ಲ, ಧನ್ಯವಾದಗಳು</translation>
-<translation id="7475525192983021547">ಓರ್ವ ಬಳಕೆದಾರರು ಸಾಧನದಲ್ಲಿ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅವರ ಚಟುವಟಿಕೆ ಕಾಲಾವಧಿಗಳನ್ನು ವರದಿ ಮಾಡಿ</translation>
<translation id="7481312909269577407">ಫಾರ್ವರ್ಡ್</translation>
<translation id="7485870689360869515">ಯಾವುದೇ ಡೇಟಾ ಕಂಡುಬಂದಿಲ್ಲ.</translation>
+<translation id="7498234416455752244">ಎಡಿಟ್‌ ಮಾಡುತ್ತಿರಿ</translation>
<translation id="7508255263130623398">ಹಿಂತಿರುಗಿಸಲಾದ ನೀತಿಯ ಸಾಧನ ಐಡಿ ಖಾಲಿ ಇದೆ ಅಥವಾ ಪ್ರಸ್ತುತ ಸಾಧನ ಐಡಿಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ</translation>
<translation id="7508870219247277067">ಅವಕಾಡೊ ಹಸಿರು</translation>
<translation id="7511955381719512146">ನೀವು ಬಳಸುತ್ತಿರುವ ವೈ-ಫೈಗೆ ನೀವು <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ಅನ್ನು ಭೇಟಿ ನೀಡುವ ಅಗತ್ಯವಿದೆ.</translation>
<translation id="7514365320538308">ಡೌನ್‌ಲೋಡ್</translation>
<translation id="7518003948725431193">ಈ ವೆಬ್ ವಿಳಾಸಕ್ಕಾಗಿ ಯಾವುದೇ ವೆಬ್ ಪುಟವು ಕಂಡುಬರಲಿಲ್ಲ: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">ಈ ಸೈಟ್‌ಗೆ ನಿಮ್ಮ ಸಂಪರ್ಕವು ಖಾಸಗಿಯಾಗಿಲ್ಲ.</translation>
+<translation id="7535087603100972091">ಮೌಲ್ಯ</translation>
<translation id="7537536606612762813">ಕಡ್ಡಾಯ</translation>
+<translation id="7538364083937897561">A2 (Envelope)</translation>
<translation id="7542403920425041731">ನೀವು ಒಮ್ಮೆ ಖಚಿತಪಡಿಸಿದರೆ, ನಿಮ್ಮ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation>
<translation id="7542995811387359312">ಈ ಫಾರ್ಮ್ ಸುರಕ್ಷಿತವಾದ ಸಂಪರ್ಕವನ್ನು ಬಳಸುತ್ತಿಲ್ಲವಾದ ಕಾರಣ ಸ್ವಯಂಚಾಲಿತ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಭರ್ತಿ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.</translation>
<translation id="7543525346216957623">ನಿಮ್ಮ ಪೋಷಕರಿಗೆ ಕೇಳಿ</translation>
@@ -1031,8 +1174,8 @@
<translation id="7552846755917812628">ಕೆಳಗಿನ ಸಲಹೆಗಳನ್ನು ಪ್ರಯತ್ನಿಸಿ:</translation>
<translation id="7554791636758816595">ಹೊಸ ಟ್ಯಾಬ್</translation>
<translation id="7564049878696755256">ನಿಮ್ಮ <ph name="ORG_NAME" /> ಖಾತೆಗೆ ನೀವು ಪ್ರವೇಶವನ್ನು ಕಳೆದುಕೊಳ್ಳಬಹುದು ಅಥವಾ ಗುರುತು ಕಳ್ಳತನಕ್ಕೆ ಒಳಗಾಗಬಹುದು. ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಇದೀಗ ಬದಲಾಯಿಸುವಂತೆ Chrome ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
-<translation id="7566125604157659769">ನೀವು ನಕಲಿಸಿದ ಪಠ್ಯ</translation>
<translation id="7567204685887185387">ಈ ಸರ್ವರ್ <ph name="DOMAIN" /> ಆಗಿದೆ ಎಂಬುದನ್ನು ಸಾಬೀತುಪಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ; ಅದರ ಸುರಕ್ಷತಾ ಪ್ರಮಾಣಪತ್ರವನ್ನು ವಂಚನೆಯಿಂದ ನೀಡಿರಬಹುದು. ಇದು ತಪ್ಪು ಕಾನ್ಫಿಗರೇಶನ್‌ನಿಂದ ಅಥವಾ ಆಕ್ರಮಣಕಾರರು ನಿಮ್ಮ ಸಂಪರ್ಕದಲ್ಲಿ ಒಳನುಸುಳಿರುವುದರಿಂದ ಆಗಿರಬಹುದು.</translation>
+<translation id="7568105740864181217">ಈ ಬ್ರೌಸರ್ ಅನ್ನು ಕಂಪನಿ, ಶಾಲೆ ಅಥವಾ ಇತರ ಸಂಸ್ಥೆಯು ನಿರ್ವಹಿಸುತ್ತಿದೆ. ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ದೂರದಿಂದಲೇ ನಿಮ್ಮ ಬ್ರೌಸರ್ ಸೆಟಪ್ ಅನ್ನು ಬದಲಾಯಿಸಬಹುದು. ಈ ಸಾಧನದಲ್ಲಿನ ಚಟುವಟಿಕೆಯನ್ನು Chrome ನಿಂದ ಹೊರಗೂ ನಿರ್ವಹಿಸಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome ನಿಂದ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="7569983096843329377">ಕಪ್ಪು</translation>
<translation id="7578104083680115302">Google ನೊಂದಿಗೆ ನೀವು ಉಳಿಸಲಾದ ಕಾರ್ಡ್‌ಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸಾಧನಗಳಾದ್ಯಂತ ಸೈಟ್‌ಗಳು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ತ್ವರಿತವಾಗಿ ಪಾವತಿಸಿ.</translation>
@@ -1043,6 +1186,7 @@
<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="7633909222644580952">ಕಾರ್ಯಕ್ಷಮತೆಯ ಡೇಟಾ ಮತ್ತು ಕ್ರ್ಯಾಶ್ ವರದಿಗಳು</translation>
<translation id="7637571805876720304">Chromium ನಿಂದ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="7639968568612851608">ಕಡು ಬೂದು</translation>
<translation id="765676359832457558">ಸುಧಾರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮರೆಮಾಡು...</translation>
@@ -1052,9 +1196,11 @@
<translation id="7667346355482952095">ಹಿಂತಿರುಗಿಸಲಾದ ನೀತಿಯ ಟೋಕನ್‌ ಖಾಲಿ ಇದೆ ಅಥವಾ ಪ್ರಸ್ತುತ ಟೋಕನ್‌ಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ</translation>
<translation id="7668654391829183341">ಅಪರಿಚಿತ ಸಾಧನ</translation>
<translation id="7669271284792375604">ನಿಮ್ಮ ಬ್ರೌಸಿಂಗ್‌ ಅನುಭವವನ್ನು ಹಾನಿಮಾಡಲು ಸ್ಥಾಪಿಸಲಾಗುವ ಪ್ರೋಗ್ರಾಂಗಳಲ್ಲಿ ನಿಮ್ಮನ್ನು ವಂಚಿಸಲು ಆಕ್ರಮಣಕಾರರು ಈ ಸೈಟ್‌ ಮೇಲೆ ದಾಳಿ ಮಾಡಬಹುದು (ಉದಾಹರಣೆಗೆ, ನಿಮ್ಮ ಮುಖಪುಟವನ್ನು ಬದಲಾಯಿಸಲಾಗುತ್ತದೆ ಅಥವಾ ನೀವು ಭೇಟಿ ನೀಡುವ ಸೈಟ್‌ಗಳಲ್ಲಿ ಹೆಚ್ಚಿನ ಜಾಹೀರಾತುಗಳನ್ನು ತೋರಿಸಲಾಗುತ್ತದೆ).</translation>
+<translation id="7676643023259824263">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್ ಪಠ್ಯಕ್ಕಾಗಿ ಹುಡುಕಿ, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">ಹುಡುಕಾಟ ಎಂಜಿನ್ ಅನ್ನು ಬದಲಿಸಿ</translation>
<translation id="7682287625158474539">ಶಿಪ್ಪಿಂಗ್</translation>
<translation id="7687186412095877299">ಉಳಿಸಲಾದ ನಿಮ್ಮ ಪಾವತಿ ವಿಧಾನಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಪಾವತಿ ಫಾರ್ಮ್‌ಗಳನ್ನು ಭರ್ತಿ ಮಾಡುತ್ತದೆ</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">ಸದ್ಯಕ್ಕೆ, ಈ ಸಾಧನದಲ್ಲಿ ಬಳಸಬಹುದಾದ ಕಾರ್ಡ್‌ಗಳನ್ನು ಮಾತ್ರವೇ ನೀವು ಹೊಂದಿದ್ದೀರಿ. ಕಾರ್ಡ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಮುಂದುವರಿಸಿ ಕ್ಲಿಕ್ ಮಾಡಿ.</translation>
<translation id="7699293099605015246">ಲೇಖನಗಳು ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ</translation>
<translation id="7701040980221191251">ಯಾವುದೂ ಇಲ್ಲ</translation>
@@ -1066,11 +1212,13 @@
<translation id="774634243536837715">ಅಪಾಯಕಾರಿ ವಿಷಯವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.</translation>
<translation id="7752995774971033316">ನಿರ್ವಹಣೆಯಲ್ಲಿಲ್ಲ</translation>
<translation id="7755287808199759310">ನಿಮ್ಮ ಪೋಷಕರು ನಿಮಗಾಗಿ ಅದನ್ನು ಅನಿರ್ಬಂಧಿಸಬಹುದಾಗಿದೆ</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ಸಂಪರ್ಕವನ್ನು ಫೈರ್‌ವಾಲ್ ಅಥವಾ ಆಂಟಿವೈರಸ್ ಸಾಫ್ಟ್‌ವೇರ್ ನಿರ್ಬಂಧಿಸಿರಬಹುದು.</translation>
<translation id="7759163816903619567">ಪ್ರದರ್ಶನ ಡೊಮೇನ್:</translation>
<translation id="7761701407923456692">ಸರ್ವರ್‌ನ ಪ್ರಮಾಣಪತ್ರವು URL ಗೆ ಸರಿ ಹೊಂದುವುದಿಲ್ಲ.</translation>
<translation id="7763386264682878361">ಪಾವತಿ ಮ್ಯಾನಿಫೆಸ್ಟ್ ವಿಶ್ಲೇಷಕರು</translation>
<translation id="7764225426217299476">ವಿಳಾಸ ಸೇರಿಸಿ</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">ಪ್ರಿಫೆಕ್ಚರ್‌‌</translation>
<translation id="7791543448312431591">ಸೇರಿಸು</translation>
<translation id="7793809570500803535"><ph name="SITE" /> ನಲ್ಲಿರುವ ವೆಬ್‌ಪುಟವು ತಾತ್ಕಾಲಿಕವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರಬಹುದು ಅಥವಾ ಅದನ್ನು ಶಾಶ್ವತವಾಗಿ ಹೊಸ ವೆಬ್ ವಿಳಾಸಕ್ಕೆ ಸರಿಸಿರಬಹುದು.</translation>
@@ -1082,8 +1230,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome ನಿಂದ ಫಾರ್ಮ್ ಸಲಹೆಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> ಗೆ '<ph name="SEARCH_STRING" />' ಕಂಡುಬಂದಿದೆ</translation>
-<translation id="7818867226424560206">ನೀತಿ ನಿರ್ವಹಣೆ</translation>
<translation id="782886543891417279">ನೀವು ಬಳಸುತ್ತಿರುವ ವೈ-ಫೈ (<ph name="WIFI_NAME" />) ಅದರ ಲಾಗಿನ್ ಪುಟಕ್ಕೆ ನೀವು ಭೇಟಿ ನೀಡುವ ಅಗತ್ಯವಿದೆ.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ಒಂದೂ ಇಲ್ಲ}=1{1 ಆ್ಯಪ್ (<ph name="EXAMPLE_APP_1" />)}=2{2 ಆ್ಯಪ್‌ಗಳು (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# ಆ್ಯಪ್‌ಗಳು (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# ಆ್ಯಪ್‌ಗಳು (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">ಆದರೆ, ನೀವು ಅದೃಶ್ಯರಾಗಿರುವುದಿಲ್ಲ. ಅಜ್ಞಾತವಾಗಿ ಹೋಗುವುದರಿಂದ ನಿಮ್ಮ ಉದ್ಯೋಗದಾತರು, ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಸೇವಾ ಪೂರೈಕೆದಾರರು ಇಲ್ಲವೇ ನೀವು ಭೇಟಿ ನೀಡುವ ವೆಬ್‌ಸೈಟ್‌ಗಳಿಂದ ನಿಮ್ಮ ಬ್ರೌಸಿಂಗ್ ಮರೆ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1092,7 +1240,7 @@
<translation id="7878562273885520351">ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಸುಲಭವಾಗಿ ಪತ್ತೆ ಮಾಡಬಹುದು</translation>
<translation id="7882421473871500483">ಕಂದು</translation>
<translation id="7887683347370398519">ನಿಮ್ಮ CVC ಅನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ</translation>
-<translation id="7893255318348328562">ಸೆಶನ್ ಹೆಸರು</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">ಮಾನ್ಯವಾದ ಫೋನ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="7935318582918952113">DOM ಡಿಸ್ಟಿಲರ್</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" /> ದಿನಾಂಕದಂದು ಅವಧಿ ಮೀರುತ್ತದೆ</translation>
@@ -1102,21 +1250,25 @@
<translation id="7951415247503192394">(32-ಬಿಟ್)</translation>
<translation id="7956713633345437162">ಮೊಬೈಲ್ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು</translation>
<translation id="7961015016161918242">ಎಂದಿಗೂ ಇಲ್ಲ</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">ನಿರ್ದಿಷ್ಟಪಡಿಸಲಾಗಿಲ್ಲ</translation>
<translation id="800218591365569300">ಮೆಮೊರಿ ಮುಕ್ತಗೊಳಿಸಲು ಇತರ ಟ್ಯಾಬ್‌ಗಳನ್ನು ಅಥವಾ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಮುಚ್ಚಲು ಪ್ರಯತ್ನಿಸಿ.</translation>
+<translation id="8004582292198964060">ಬ್ರೌಸರ್</translation>
<translation id="8009225694047762179">ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{ಈ ಕಾರ್ಡ್ ಮತ್ತು ಅದರ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ. ನೀವು <ph name="USER_EMAIL" /> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿದಾಗ ಅದನ್ನು ಬಳಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ.}one{ಈ ಕಾರ್ಡ್‌ಗಳು ಮತ್ತು ಅವುಗಳ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸಗಳನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ. ನೀವು <ph name="USER_EMAIL" /> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿದಾಗ ಅವುಗಳನ್ನು ಬಳಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ.}other{ಈ ಕಾರ್ಡ್‌ಗಳು ಮತ್ತು ಅವುಗಳ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸಗಳನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ. ನೀವು <ph name="USER_EMAIL" /> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿದಾಗ ಅವುಗಳನ್ನು ಬಳಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ.}}</translation>
<translation id="8012647001091218357">ಈ ಕ್ಷಣದಲ್ಲಿ ನಿಮ್ಮ ಪೋಷಕರನ್ನು ತಲುಪಲು ನಮಗೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation>
<translation id="8025119109950072390">ಈ ಸೈಟ್‌ನಲ್ಲಿನ ಆಕ್ರಮಣಕಾರರು ಸಾಫ್ಟ್‌ವೇರ್ ಸ್ಥಾಪಿಸುವಿಕೆ ಅಥವಾ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಬಹಿರಂಗ ಪಡಿಸುವಂತಹ ಅಪಾಯಕಾರಿಯಾಗಿ ಏನಾದರೂ ಮಾಡುವಂತಹ ಮೋಸವನ್ನು ಮಾಡಬಹುದು (ಉದಾಹರಣೆಗೆ, ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಫೋನ್‌ ಸಂಖ್ಯೆಗಳು ಅಥವಾ ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್‌ಗಳು).</translation>
<translation id="8034522405403831421">ಈ ಪುಟವು <ph name="SOURCE_LANGUAGE" /> ನಲ್ಲಿ ಇದೆ. ಇದನ್ನು <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸುವುದೇ?</translation>
<translation id="8035152190676905274">ಪೆನ್</translation>
+<translation id="8037117624646282037">ಸಾಧನವನ್ನು ಇತ್ತೀಚೆಗೆ ಯಾರೆಲ್ಲಾ ಬಳಸಿದ್ದಾರೆ</translation>
<translation id="8037357227543935929">ಕೇಳು (ಡಿಫಾಲ್ಟ್)</translation>
<translation id="803771048473350947">ಫೈಲ್</translation>
<translation id="8041089156583427627">ಪ್ರತಿಕ್ರಿಯೆ ಕಳುಹಿಸಿ</translation>
<translation id="8041940743680923270">ಜಾಗತಿಕ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ (ಕೇಳಿ)</translation>
<translation id="8042918947222776840">ಪಿಕಪ್ ವಿಧಾನವನ್ನು ಆರಿಸಿ</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" ಅನ್ನು ಸರಿಯಾಗಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿಲ್ಲ. ಸಾಮಾನ್ಯವಾಗಿ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು "<ph name="SOFTWARE_NAME" />" ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">ನಿಮ್ಮ ಸಾಧನವನ್ನು ಇದಕ್ಕೆ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ:</translation>
+<translation id="8066955247577885446">ಕ್ಷಮಿಸಿ, ಏನೋ ತಪ್ಪಾಗಿದೆ.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">ಡಾಕ್ಯುಮೆಂಟ್‌ ಅನ್ನು ತಿರುಗಿಸಿದಾಗ ಟಿಪ್ಪಣಿ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ</translation>
<translation id="8079031581361219619">ಸೈಟ್ ಅನ್ನು ಪುನಃ ಲೋಡ್ ಮಾಡಬೇಕೇ?</translation>
<translation id="8088680233425245692">ಲೇಖನವನ್ನು ವೀಕ್ಷಿಸಲು ವಿಫಲವಾಗಿದೆ.</translation>
@@ -1125,11 +1277,12 @@
<translation id="8091372947890762290">ಸರ್ವರ್‌ನಲ್ಲಿ ಸಕ್ರಿಯತೆ ಬಾಕಿ ಉಳಿದಿದೆ</translation>
<translation id="8092774999298748321">ಗಾಢ ನೇರಳೆ</translation>
<translation id="8094917007353911263">ನೀವು ಬಳಸುತ್ತಿರುವ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ನೀವು <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ಅನ್ನು ಭೇಟಿ ನೀಡುವ ಅಗತ್ಯವಿದೆ.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">ಅಮಾನ್ಯ ಕಾರ್ಡ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ</translation>
<translation id="8103161714697287722">ಪಾವತಿ ವಿಧಾನ</translation>
<translation id="8118489163946903409">ಪಾವತಿ ವಿಧಾನ</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> ಸಾಧನವನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ನಿರ್ವಹಿಸುತ್ತಿದೆ</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಅಥವಾ ನೆಟ್‌ವರ್ಕ್ ನಲ್ಲಿ ಸರಿಯಾಗಿ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿಲ್ಲ: ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ತಿಳಿಸಿ.</translation>
-<translation id="8130693978878176684">ನಾನು ಇನ್ನು ಮುಂದೆ ಸಹಾಯ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ, ನಿಮ್ಮ ವಿವೇಚನೆಗೆ ತಕ್ಕಂತೆ ಮುಂದುವರಿಸಿ.</translation>
<translation id="8131740175452115882">ದೃಢೀಕರಿಸು</translation>
<translation id="8149426793427495338">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗಿದೆ.</translation>
<translation id="8150722005171944719"><ph name="URL" /> ನಲ್ಲಿನ ಫೈಲ್ ಓದುವಂತಿರುವುದಿಲ್ಲ. ಇದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು, ಚಲಿಸಬಹುದು, ಅಥವಾ ಫೈಲ್ ಅನುಮತಿಗಳು ಪ್ರವೇಶವನ್ನು ತಡೆಗಟ್ಟುತ್ತಿರಬಹುದು.</translation>
@@ -1139,8 +1292,11 @@
<translation id="8197543752516192074">ಪುಟವನ್ನು ಅನುವಾದಿಸಿ</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ಜೊತೆಗಿನ ವಿಸ್ತರಣೆಗೆ ಅಮಾನ್ಯವಾದ ಅಪ್‌ಡೇಟ್‌‌ URL.</translation>
<translation id="8202097416529803614">ಆರ್ಡರ್ ಸಾರಾಂಶ</translation>
+<translation id="8202370299023114387">ಸಂಘರ್ಷ</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">ಸಂಪರ್ಕ ಸುರಕ್ಷಿತವಾಗಿದೆ</translation>
<translation id="8218327578424803826">ನಿಯೋಜಿಸಲಾದ ಸ್ಥಳ:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</translation>
<translation id="8225771182978767009">ಈ ಕಂಪ್ಯೂಟರ್ ಹೊಂದಿಸಿರುವ ವ್ಯಕ್ತಿಯು ಈ ಸೈಟ್ ನಿರ್ಬಂಧಿಸಲು ಆಯ್ಕೆಮಾಡಿದ್ದಾರೆ.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">ಪುಟವನ್ನು ಹೊಸ ಅದೃಶ್ಯ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ</translation>
@@ -1152,14 +1308,16 @@
<translation id="825929999321470778">ಉಳಿಸಿದ ಎಲ್ಲ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ತೋರಿಸಿ</translation>
<translation id="8261506727792406068">ಅಳಿಸಿ</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> ನಂತೆ ಸೈನ್ ಇನ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation>
+<translation id="8278457561961988242">ನಿಮ್ಮ ಬ್ರೌಸರ್ ಅನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ನಿರ್ವಹಿಸುತ್ತಿದೆ. ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ದೂರದಿಂದಲೇ ನಿಮ್ಮ ಬ್ರೌಸರ್ ಸೆಟಪ್ ಅನ್ನು ಬದಲಾಯಿಸಬಹುದು. ಈ ಸಾಧನದಲ್ಲಿನ ಚಟುವಟಿಕೆಯನ್ನು Chrome ನಿಂದ ಹೊರಗೂ ನಿರ್ವಹಿಸಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">ಸೈನ್ ಇನ್</translation>
<translation id="8288807391153049143">ಪ್ರಮಾಣಪತ್ರವನ್ನು ತೋರಿಸಿ</translation>
<translation id="8289355894181816810">ಇದರ ಅರ್ಥವೇನೆಂದು ನಿಮಗೆ ಖಚಿತವಾಗದಿದ್ದರೆ ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ.</translation>
<translation id="8293206222192510085">ಬುಕ್‌ಮಾರ್ಕ್ ಸೇರಿಸು</translation>
<translation id="8294431847097064396">ಮೂಲ</translation>
<translation id="8298115750975731693">ನೀವು ಬಳಸುತ್ತಿರುವ ವೈ-ಫೈ (<ph name="WIFI_NAME" />) ಗೆ ನೀವು <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ಅನ್ನು ಭೇಟಿ ನೀಡುವ ಅಗತ್ಯವಿದೆ.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದಲ್ಲಿನ ಸಮಸ್ಯೆಯಿಂದಾಗಿ ಭಾಷಾಂತರವು ವಿಫಲವಾಗಿದೆ.</translation>
-<translation id="8311129316111205805">ಸೆಶನ್ ಲೋಡ್ ಮಾಡಿ</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ಗೆ ಪ್ರವೇಶವನ್ನು ನಿರಾಕರಿಸಲಾಗಿದೆ</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">ನಿಮ್ಮ ಸುರಕ್ಷತೆ ಅಪಾಯಗಳು ನಿಮಗೆ ಅರ್ಥವಾಗಿದ್ದರೆ, ಅಪಾಯಕಾರಿ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ತೆಗೆದುಹಾಕುವುದಕ್ಕೂ ಮೊದಲು ನೀವು <ph name="BEGIN_LINK" />ಈ ಸೈಟ್‌ಗೆ ಭೇಟಿ<ph name="END_LINK" /> ನೀಡಬಹುದು.</translation>
@@ -1177,7 +1335,6 @@
<translation id="8416694386774425977">ನೆಟ್‌ವರ್ಕ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅಮಾನ್ಯವಾಗಿದೆ ಮತ್ತು ಅದನ್ನು ಆಮದು ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ.
ಹೆಚ್ಚುವರಿ ವಿವರಗಳು:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">ಸಾಧನವನ್ನು <ph name="ENROLLMENT_DOMAIN" /> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">ಬದಲಿಸಿ</translation>
<translation id="8428213095426709021">ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
@@ -1205,9 +1362,11 @@
<translation id="860043288473659153">ಕಾರ್ಡ್‌ಹೋಲ್ಡರ್ ಹೆಸರು</translation>
<translation id="861775596732816396">ಗಾತ್ರ 4</translation>
<translation id="8620436878122366504">ನಿಮ್ಮ ಪೋಷಕರು ಇನ್ನೂ ಇದನ್ನು ಅಂಗೀಕರಿಸಿಲ್ಲ</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">ಈ ಕಾರ್ಡ್ ಅನ್ನು ಈ ಸಾಧನದಲ್ಲಿ ಉಳಿಸಿ</translation>
<translation id="8663226718884576429">ಆರ್ಡರ್ ಸಾರಾಂಶ, <ph name="TOTAL_LABEL" />, ಹೆಚ್ಚಿನ ವಿವರಗಳು</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, ಉತ್ತರ, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> ಗೆ ನಿಮ್ಮ ಸಂಪರ್ಕವು ಎನ್‌ಕ್ರಿಪ್ಟ್ ಆಗಿಲ್ಲ.</translation>
<translation id="8718314106902482036">ಪಾವತಿ ಪೂರ್ಣಗೊಂಡಿಲ್ಲ</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, ಹುಡುಕಾಟ ಸಲಹೆ</translation>
@@ -1221,6 +1380,7 @@
<translation id="8761567432415473239">Google ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್‌ ಇತ್ತೀಚಿಗೆ <ph name="SITE" /> ನಲ್ಲಿ <ph name="BEGIN_LINK" />ಹಾನಿಕಾರಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಕಂಡುಹಿಡಿದಿದೆ<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB ಸಾಧನ</translation>
<translation id="8768895707659403558">ನಿಮ್ಮ ಕಾರ್ಡ್‌ಗಳನ್ನು ನಿಮ್ಮ ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿ ಬಳಸಲು, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ಅಳಿಸುವುದನ್ನು ಮತ್ತೆಮಾಡು</translation>
<translation id="8792621596287649091">ನಿಮ್ಮ <ph name="ORG_NAME" /> ಖಾತೆಗೆ ನೀವು ಪ್ರವೇಶವನ್ನು ಕಳೆದುಕೊಳ್ಳಬಹುದು ಅಥವಾ ಗುರುತು ಕಳ್ಳತನಕ್ಕೆ ಒಳಗಾಗಬಹುದು. ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಇದೀಗ ಬದಲಾಯಿಸುವಂತೆ Chromium ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
<translation id="8800988563907321413">ನಿಮ್ಮ ಸಮೀಪದ ವೆಬ್ ಪುಟದ ಸಲಹೆಗಳು ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ</translation>
@@ -1231,10 +1391,12 @@
<translation id="885730110891505394">Google ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳುವುದು</translation>
<translation id="8858065207712248076">ನೀವು ಇತರ ಸೈಟ್‌ಗಳಲ್ಲಿ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಮರುಬಳಕೆ ಮಾಡಿದ್ದಲ್ಲಿ Chrome ನಿಮ್ಮ <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> ಪಾಸವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಲು ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ.</translation>
<translation id="8866481888320382733">ನೀತಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪಾಸ್ ಮಾಡುವಲ್ಲಿ ದೋಷ</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">ಇತ್ತೀಚೆಗೆ ಮುಚ್ಚಿರುವುದು</translation>
<translation id="8874824191258364635">ಮಾನ್ಯವಾದ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</translation>
<translation id="8891727572606052622">ಅಮಾನ್ಯವಾದ ಪ್ರಾಕ್ಸಿ ಮೋಡ್.</translation>
<translation id="8903921497873541725">ಝೂಮ್ ಇನ್</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">ಈ ಕಾರ್ಡನ್ನು ನಿಮ್ಮ Google ಖಾತೆನಲ್ಲಿ ಉಳಿಸಲು ಬಯಸುವಿರಾ?</translation>
<translation id="8932102934695377596">ನಿಮ್ಮ ಗಡಿಯಾರ ಹಿಂದೆ ಇದೆ</translation>
<translation id="893332455753468063">ಹೆಸರು ಸೇರಿಸಿ</translation>
@@ -1242,13 +1404,13 @@
<translation id="894185898663964645">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಕಸ್ಟಮ್ ರೂಟ್ ಪ್ರಮಾಣಪತ್ರಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿದ್ದಾರೆ, ಇದರಿಂದಾಗಿ ನೀವು ಭೇಟಿ ನೀಡುವ ವೆಬ್‌ಸೈಟ್‌ಗಳಲ್ಲಿನ ವಿಷಯಗಳನ್ನು ನಿರ್ವಾಹಕರು ನೋಡಬಹುದು.</translation>
<translation id="8943282376843390568">ನಿಂಬೆ ಹಳದಿ</translation>
<translation id="8957210676456822347">ಕ್ಯಾಪ್ಟಿವ್ ಪೋರ್ಟಲ್ ದೃಢೀಕರಣ</translation>
+<translation id="8966619695390250636">ನೀವು ಹುಡುಕಿದ್ದು ಇದನ್ನೇ?</translation>
<translation id="8968766641738584599">ಕಾರ್ಡ್‌ ಉಳಿಸಿ</translation>
<translation id="8971063699422889582">ಸರ್ವರ್‌ನ ಪ್ರಕಮಾಣಪತ್ರದ ಅವಧಿ ಮುಕ್ತಾಯಗೊಂಡಿದೆ.</translation>
<translation id="8975012916872825179">ಫೋನ್ ಸಂಖ್ಯೆಗಳು, ಇಮೇಲ್ ವಿಳಾಸಗಳು ಮತ್ತು ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ</translation>
<translation id="8978053250194585037">Google ಸುರಕ್ಷಿತ ಬ್ರೌಸಿಂಗ್ ಇತ್ತೀಚೆಗೆ <ph name="SITE" /> ನಲ್ಲಿ <ph name="BEGIN_LINK" />ಫಿಶಿಂಗ್ ಪತ್ತೆಹಚ್ಚಿದೆ<ph name="END_LINK" />. ಫಿಶಿಂಗ್ ಸೈಟ್‌ಗಳು ನಿಮ್ಮನ್ನು ಮೋಸಗೊಳಿಸಲು ಇತರ ಸೈಟ್‌ಗಳಂತೆ ನಟಿಸುತ್ತವೆ.</translation>
<translation id="8983003182662520383">Google Pay ಅನ್ನು ಬಳಸುವ ಪಾವತಿ ವಿಧಾನಗಳು ಮತ್ತು ವಿಳಾಸಗಳು</translation>
<translation id="8987927404178983737">ತಿಂಗಳು</translation>
-<translation id="8988408250700415532">ಏನೋ ತಪ್ಪಾಗಿದೆ. ನೀವು ವೆಬ್‌ಸೈಟ್‌ನಲ್ಲಿ ನಿಮ್ಮ ಆರ್ಡರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಬಹುದು.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ಈ ಮುಂದಕ್ಕೆ ಸೈಟ್ ಹಾನಿಕಾರಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ಹೊಂದಿದೆ</translation>
<translation id="8997023839087525404">ಪ್ರಮಾಣಪತ್ರ ಪಾರದರ್ಶಕತೆ ನೀತಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಸಾರ್ವಜನಿಕವಾಗಿ ಬಹಿರಂಗಗೊಳಿಸದ ಪ್ರಮಾಣಪತ್ರವನ್ನು ಸರ್ವರ್ ಪ್ರಸ್ತುತಪಡಿಸಿದೆ. ಇದು ಅವುಗಳು ವಿಶ್ವಾಸಾರ್ಹವಾಗಿವೆ ಮತ್ತು ಆಕ್ರಮಣಗಾರರ ವಿರುದ್ಧ ರಕ್ಷಣೆಯನ್ನು ನೀಡುತ್ತವೆ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಕೆಲವು ಪ್ರಮಾಣಪತ್ರಗಳಿಗೆ ಅಗತ್ಯವಾಗಿದೆ.</translation>
@@ -1258,6 +1420,7 @@
<translation id="9011424611726486705">ಸೈಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ</translation>
<translation id="9020200922353704812">ಕಾರ್ಡ್‌ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸದ ಅಗತ್ಯವಿದೆ</translation>
<translation id="9020542370529661692">ಈ ಪುಟವನ್ನು <ph name="TARGET_LANGUAGE" /> ಗೆ ಅನುವಾದಿಸಲಾಗಿದೆ</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(ಅಮಾನ್ಯ)</translation>
<translation id="9035022520814077154">ಭದ್ರತಾ ದೋಷ</translation>
<translation id="9038649477754266430">ಪುಟಗಳನ್ನು ಹೆಚ್ಚು ವೇಗವಾಗಿ ಲೋಡ್ ಮಾಡಲು ಮುನ್ನೋಟಗಳನ್ನು ಬಳಸಿ</translation>
@@ -1269,11 +1432,11 @@
<translation id="9065745800631924235">ಇತಿಹಾಸದಿಂದ <ph name="TEXT" /> ಹುಡುಕಾಟ</translation>
<translation id="9069693763241529744">ವಿಸ್ತರಣೆಯ ಮೂಲಕ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation>
<translation id="9076283476770535406">ಇದು ಪ್ರಬುದ್ಧ ವಿಷಯವನ್ನು ಹೊಂದಿರಬಹುದು</translation>
+<translation id="9076630408993835509">ಈ ಬ್ರೌಸರ್ ಅನ್ನು ಕಂಪನಿ ಅಥವಾ ಇತರ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ. ಈ ಸಾಧನದಲ್ಲಿನ ಚಟುವಟಿಕೆಯನ್ನು Chrome ನಿಂದ ಹೊರಗೆ ನಿರ್ವಹಿಸಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">ಇನ್ನಷ್ಟು ಮಾಹಿತಿಯ ಅಗತ್ಯವಿದೆ</translation>
<translation id="9080712759204168376">ಆರ್ಡರ್ ಸಾರಾಂಶ</translation>
<translation id="9103872766612412690"><ph name="SITE" /> ಸಾಮಾನ್ಯವಾಗಿ ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಸಂರಕ್ಷಿಸಲು ಎನ್‌ಕ್ರಿಪ್ಶನ್ ಪ್ರಯೋಜನವನ್ನು ಬಳಸಿಕೊಳ್ಳುತ್ತದೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ Chromium <ph name="SITE" /> ವೆಬ್‌ಸೈಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಪ್ರಯತ್ನಿಸಿದಾಗ, ಆ ವೆಬ್‌ಸೈಟ್‌‌ ಅಸಹಜ ಮತ್ತು ತಪ್ಪು ರುಜುವಾತುಗಳನ್ನು ಹಿಂತಿರುಗಿಸಿದೆ. ದಾಳಿಕೋರರು <ph name="SITE" /> ರೂಪದಲ್ಲಿ ಸೋಗು ಹಾಕಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವಾಗ ಅಥವಾ ವೈ-ಫೈ ಸೈನ್-ಇನ್ ಪರದೆಯು ಸಂಪರ್ಕಕ್ಕೆ ಅಡ್ಡಿಯುಂಟು ಮಾಡಿದಾಗ ಇದು ಕಂಡುಬರಬಹುದು. ಯಾವುದೇ ಡೇಟಾವನ್ನು ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳುವ ಮೊದಲೇ Chromium ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿರುವ ಕಾರಣ, ನಿಮ್ಮ ಮಾಹಿತಿ ಈಗಲೂ ಸುರಕ್ಷಿತವಾಗಿದೆ.</translation>
<translation id="9106062320799175032">ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
-<translation id="9110718169272311511">Chrome ನಲ್ಲಿನ Google ಅಸಿಸ್ಟೆಂಟ್‌ ಸ್ಕ್ರೀನ್‌ ಕೆಳಭಾಗದಲ್ಲಿ ಲಭ್ಯವಿದೆ</translation>
<translation id="9114524666733003316">ಕಾರ್ಡ್‌ ದೃಢೀಕರಿಸಲಾಗುತ್ತಿದೆ...</translation>
<translation id="9128870381267983090">ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸು</translation>
<translation id="9137013805542155359">ಮೂಲವನ್ನು ತೋರಿಸಿ</translation>
@@ -1282,6 +1445,7 @@
<translation id="9148507642005240123">&amp;ಸಂಪಾದಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
<translation id="9154194610265714752">ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲಾಗಿದೆ</translation>
<translation id="9157595877708044936">ಹೊಂದಿಸಲಾಗುತ್ತಿದೆ...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">ನೀವು ಪಾವತಿ ವಿಧಾನಗಳನ್ನು ಉಳಿಸಿದಲ್ಲಿ ಪರಿಶೀಲಿಸಲು ಸೈಟ್‌ಗಳನ್ನು ಅನುಮತಿಸಿ</translation>
<translation id="9169664750068251925">ಈ ಸೈಟ್ ಅನ್ನು ಯಾವಾಗಲೂ ನಿರ್ಬಂಧಿಸು</translation>
<translation id="9170848237812810038">&amp;ರದ್ದುಮಾಡು</translation>
@@ -1296,10 +1460,12 @@
<translation id="9219103736887031265">ಚಿತ್ರಗಳು</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ಫಾರ್ಮ್ ತೆರವುಗೊಳಿಸಿ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">ನಿಮ್ಮ Google ಖಾತೆಗೆ ನೀವು ಪ್ರವೇಶವನ್ನು ಕಳೆದುಕೊಳ್ಳಬಹುದು. ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಅನ್ನು ಈಗಲೇ ಬದಲಾಯಿಸುವಂತೆ Chromium ಶಿಫಾರಸು ಮಾಡುತ್ತದೆ. ಸೈನ್ ಇನ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.</translation>
<translation id="939736085109172342">ಹೊಸ ಫೋಲ್ಡರ್</translation>
<translation id="945855313015696284">ಕೆಳಗಿನ ಮಾಹಿತಿಯನ್ನು ಪರಿಶೀಲಿಸಿ ಮತ್ತು ಯಾವುದೇ ಅಮಾನ್ಯ ಕಾರ್ಡ್‌ಗಳನ್ನು ಅಳಿಸಿ</translation>
<translation id="951104842009476243">ಸ್ವೀಕೃತ ಡೆಬಿಟ್ ಮತ್ತು ಪ್ರೀಪೇಯ್ಡ್ ಕಾರ್ಡ್‌ಗಳು</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> ನ ಸುರಕ್ಷತೆ ಕಾರ್ಯನೀತಿಗೆ ಅನುಗುಣವಾಗಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ.</translation>
<translation id="962484866189421427">ಈ ವಿಷಯವು ವಂಚಕ ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಬಹುದು. ಈ ಆ್ಯಪ್‌ಗಳು ಬೇರೆ ಯಾವುದರಂತೆಯೋ ಸೋಗು ಹಾಕುವ ಅಥವಾ ನಿಮ್ಮನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಬಳಸಬಹುದಾದ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುವ ಸಾಧ್ಯತೆಯಿದೆ. <ph name="BEGIN_LINK" />ಹೇಗಿದ್ದರೂ ತೋರಿಸಿ<ph name="END_LINK" /></translation>
<translation id="969892804517981540">ಅಧಿಕೃತವಾಗಿ ನಿರ್ಮಿಸಿ</translation>
<translation id="973773823069644502">ವಿತರಣೆ ವಿಳಾಸವನ್ನು ಸೇರಿಸಿ</translation>
@@ -1307,6 +1473,7 @@
<translation id="981121421437150478">ಆಫ್‌ಲೈನ್</translation>
<translation id="984275831282074731">ಪಾವತಿ ವಿಧಾನಗಳು</translation>
<translation id="985199708454569384">&lt;p&gt;ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಅಥವಾ ಮೊಬೈಲ್ ಸಾಧನದ ದಿನಾಂಕ ಮತ್ತು ಸಮಯ ನಿಖರವಾಗಿರದಿದ್ದರೆ, ನೀವು ಈ ದೋಷವನ್ನು ನೋಡುವಿರಿ&lt;/p&gt; &lt;p&gt;ದೋಷವನ್ನು ಪರಿಹರಿಸಲು, ನಿಮ್ಮ ಸಾಧನದ ಗಡಿಯಾರವನ್ನು ತೆರೆಯಿರಿ. ದಿನಾಂಕ ಮತ್ತು ಸಮಯ ಸರಿಯಾಗಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">ಡೆವಲಪರ್ ಬಿಲ್ಡ್</translation>
<translation id="989988560359834682">ವಿಳಾಸವನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ko.xtb b/chromium/components/strings/components_strings_ko.xtb
index 2cb1b4a104f..1e0c6afd144 100644
--- a/chromium/components/strings/components_strings_ko.xtb
+++ b/chromium/components/strings/components_strings_ko.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ko">
-<translation id="1005145902654145231">세션 이름을 바꾸지 못했습니다.</translation>
<translation id="1008557486741366299">나중에 하기</translation>
<translation id="1010200102790553230">페이지 나중에 로드하기</translation>
<translation id="1015730422737071372">추가 세부정보 제공</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">알 수 없는 이름</translation>
<translation id="1050038467049342496">다른 앱 닫기</translation>
<translation id="1055184225775184556">추가 실행 취소(&amp;U)</translation>
+<translation id="1056898198331236512">경고</translation>
<translation id="1058479211578257048">카드 저장 중...</translation>
<translation id="10614374240317010">저장되지 않음</translation>
+<translation id="1062160989074299343">Prc10(봉투)</translation>
<translation id="106701514854093668">데스크톱 북마크</translation>
<translation id="1074497978438210769">주의 요함</translation>
<translation id="1080116354587839789">너비에 맞춤</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">카드 명의 추가</translation>
<translation id="1089439967362294234">비밀번호 변경</translation>
<translation id="109743633954054152">Chrome 설정에서 비밀번호를 관리하세요.</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">웹사이트에서 보안을 업데이트하는 동안에는 경고가 자주 발생할 수 있습니다. 곧 개선될 것입니다.</translation>
<translation id="1126551341858583091">로컬 저장소는 <ph name="CRASH_SIZE" />입니다.</translation>
<translation id="112840717907525620">정책 캐시 확인</translation>
+<translation id="1131264053432022307">복사한 이미지</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" />와(과)의 연결이 예기치 않게 종료되었습니다.</translation>
<translation id="1161325031994447685">Wi-Fi에 다시 연결</translation>
<translation id="1165039591588034296">오류</translation>
-<translation id="1173894706177603556">이름 바꾸기</translation>
<translation id="1175364870820465910">인쇄(&amp;P)</translation>
<translation id="1181037720776840403">삭제</translation>
<translation id="1197088940767939838">오렌지색</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">기기 이름</translation>
<translation id="124116460088058876">다른 언어</translation>
<translation id="1250759482327835220">다음번에 더 빠르게 결제할 수 있도록 Google 계정에 카드, 이름, 청구서 수신 주소를 저장하세요.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" />(동기화됨)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">명령줄 변형</translation>
<translation id="129553762522093515">최근에 닫은 탭</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />쿠키 삭제해 보기<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">선택한 세션이 존재하지 않습니다.</translation>
+<translation id="1320233736580025032">Prc1(봉투)</translation>
+<translation id="132301787627749051">클립보드 이미지 검색</translation>
<translation id="1323433172918577554">더보기</translation>
<translation id="132390688737681464">주소 저장 및 자동 입력</translation>
<translation id="1333989956347591814">다음의 관계자는 내 활동 내역을 <ph name="BEGIN_EMPHASIS" />확인할 수도 있습니다<ph name="END_EMPHASIS" />.
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">수령 주소</translation>
<translation id="1348198688976932919">방문하려는 사이트에 위험한 앱이 있습니다.</translation>
<translation id="1348779747280417563">이름 확인</translation>
+<translation id="1357195169723583938">최근에 기기를 사용한 사용자와 사용 시간</translation>
+<translation id="1364822246244961190">차단된 정책이므로 값이 무시됩니다.</translation>
<translation id="1374468813861204354">제안사항</translation>
+<translation id="1374692235857187091">Index-4x6(엽서)</translation>
<translation id="1375198122581997741">버전 정보</translation>
<translation id="1376836354785490390">간략히 보기</translation>
<translation id="1377321085342047638">카드 번호</translation>
<translation id="138218114945450791">하늘색</translation>
+<translation id="1382194467192730611">관리자가 허용한 USB 기기</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" />에서 전송한 데이터가 없습니다.</translation>
+<translation id="140316286225361634">사이트 <ph name="ORIGIN" />이(가) 모든 요청에 보안 정책을
+ 적용하도록 요청했으며 현재 이 정책에 따르면 이 사이트는
+ 안전하지 않습니다.</translation>
<translation id="1405567553485452995">연한 녹색</translation>
<translation id="1407135791313364759">모두 열기</translation>
<translation id="1413809658975081374">개인정보 보호 오류</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">예</translation>
<translation id="1430915738399379752">인쇄</translation>
<translation id="1455413310270022028">지우개</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">자세히 보기</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">배송지 주소 선택</translation>
+<translation id="1492194039220927094">정책 푸시:</translation>
<translation id="1501859676467574491">Google 계정에 저장된 카드 표시</translation>
-<translation id="1506687042165942984">오래된 것으로 알려진 이 페이지의 저장된 사본을 표시합니다.</translation>
<translation id="1507202001669085618">&lt;p&gt;온라인에 접속하기 위해 로그인해야 하는 Wi-Fi 포털을 사용하면 이 오류가 표시됩니다.&lt;/p&gt;
&lt;p&gt;오류를 수정하려면 열려는 페이지에서 &lt;strong&gt;연결&lt;/strong&gt;을 클릭하세요.&lt;/p&gt;</translation>
<translation id="1517433312004943670">전화번호 필요</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">생성 날짜</translation>
<translation id="1521655867290435174">Google 스프레드시트</translation>
<translation id="1527263332363067270">연결 대기 중...</translation>
+<translation id="1529521330346880926">10x15(봉투)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">이 페이지 내용:</translation>
<translation id="153384715582417236">새 콘텐츠 없음</translation>
<translation id="154408704832528245">배달 주소 선택</translation>
<translation id="1549470594296187301">이 기능을 이용하려면 자바스크립트를 사용하도록 설정해야 합니다.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">만료일 입력</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">이 웹페이지를 표시하는 도중 문제가 발생했습니다.</translation>
<translation id="1592005682883173041">로컬 데이터 액세스</translation>
<translation id="1594030484168838125">선택</translation>
<translation id="161042844686301425">청록색</translation>
-<translation id="1618822247301510817">복사한 이미지</translation>
<translation id="1620510694547887537">카메라</translation>
<translation id="1623104350909869708">이 페이지가 추가적인 대화를 생성하지 않도록 차단</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">세션 종료</translation>
<translation id="1639239467298939599">로드 중</translation>
<translation id="1640180200866533862">사용자 정책</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" />에서는 사용자 정보를 보호하기 위해 일반적으로 암호화를 사용합니다. 이번에 Chrome에서 <ph name="SITE" />에 연결을 시도했을 때 웹사이트에서 비정상적이고 잘못된 사용자 인증 정보를 반환했습니다. 이는 공격자가 <ph name="SITE" />인 것처럼 가장하려고 하거나 Wi-Fi 로그인 화면이 연결을 방해했기 때문일 수 있습니다. 데이터 교환이 발생하기 전에 Chrome에서 연결을 중단했기 때문에 사용자 정보는 안전합니다.</translation>
<translation id="168841957122794586">서버 인증서에 안전성이 낮은 암호화 키가 포함되어 있습니다.</translation>
<translation id="1697532407822776718">설정 완료</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{서버의 보안 인증서가 내일 발효될 예정이며 이에 따라 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.}other{서버의 보안 인증서가 #일 후 발효될 예정이며 이에 따라 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">문서가 너무 커서 주석을 달 수 없습니다.</translation>
<translation id="1721312023322545264">이 사이트를 방문하려면 <ph name="NAME" />님으로부터 권한을 받아야 합니다.</translation>
<translation id="1721424275792716183">* 필수 입력란</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">시스템 관리자에게 문의하세요.</translation>
<translation id="1740951997222943430">올바른 만료 월을 입력하세요.</translation>
<translation id="1743520634839655729">다음번에 더 빠르게 결제할 수 있도록 Google 계정과 기기에 카드, 이름, 청구서 수신 주소를 저장하세요.</translation>
+<translation id="1745880797583122200">관리 대상 브라우저입니다</translation>
<translation id="17513872634828108">열린 탭</translation>
<translation id="1753706481035618306">페이지 번호</translation>
<translation id="1763864636252898013">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 기기의 운영체제에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">동기화 암호를 업데이트하세요.</translation>
<translation id="1787142507584202372">열린 탭이 여기에 표시됩니다.</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">카드 소유자 이름</translation>
<translation id="1821930232296380041">잘못된 요청 또는 요청 매개변수</translation>
+<translation id="1822540298136254167">방문 웹사이트 및 접속 시간</translation>
<translation id="1826516787628120939">확인 중</translation>
<translation id="1834321415901700177">이 사이트에 유해한 프로그램이 있습니다.</translation>
<translation id="1839551713262164453">오류가 발생하여 정책 값의 유효성을 검사하지 못했습니다.</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Chrome 인터넷 사용 기록 삭제</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{외 1개}other{외 #개}}</translation>
<translation id="2003709556000175978">지금 비밀번호 재설정</translation>
+<translation id="20053308747750172">대상 서버인 <ph name="ORIGIN" />에서 모든 요청에
+ 보안 정책 적용을 요청했습니다. 하지만 현재
+ 잘못된 정책이 제공되어 브라우저가 <ph name="SITE" />에 대한 요청을
+ 처리할 수 없습니다.</translation>
<translation id="2025186561304664664">프록시가 자동 설정되도록 지정됩니다.</translation>
<translation id="2030481566774242610"><ph name="LINK" />을(를) 찾으셨나요?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />프록시 및 방화벽 확인<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">부서</translation>
<translation id="2102134110707549001">강력한 비밀번호 추천...</translation>
<translation id="2108755909498034140">컴퓨터 다시 시작</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">카드</translation>
<translation id="2114841414352855701"><ph name="POLICY_NAME" />이(가) 우선 적용되었기 때문에 무시됩니다.</translation>
<translation id="213826338245044447">모바일 북마크</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">카드 수정</translation>
<translation id="2166049586286450108">전체 관리자 액세스</translation>
<translation id="2166378884831602661">사이트에 보안 연결할 수 없음</translation>
+<translation id="2169984857010174799">Kaku2(봉투)</translation>
<translation id="2181821976797666341">정책</translation>
<translation id="2183608646556468874">전화번호</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{주소 1개}other{주소 #개}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">전화번호</translation>
<translation id="2283340219607151381">주소 저장 및 자동 입력</translation>
<translation id="2292556288342944218">인터넷 액세스가 차단됨</translation>
+<translation id="2294558542833290837">처음에 열어본 링크가 비정상적입니다.</translation>
+<translation id="2297722699537546652">B5(봉투)</translation>
+<translation id="2310021320168182093">Chou2(봉투)</translation>
<translation id="2316887270356262533">1MB 미만의 저장용량을 확보합니다. 일부 사이트는 다음 방문 시 로드 속도가 느려질 수 있습니다.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />에 사용자 이름과 비밀번호를 입력해야 합니다.</translation>
<translation id="2317583587496011522">직불카드를 사용할 수 있습니다.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, 만료일: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">관리자가 제어하는 설정</translation>
+<translation id="2346319942568447007">복사한 이미지</translation>
<translation id="2349790679044093737">VR 세션 사용 중</translation>
<translation id="2354001756790975382">기타 북마크</translation>
<translation id="2354430244986887761">Google 세이프 브라우징이 최근 <ph name="SITE" />에서 <ph name="BEGIN_LINK" />유해한 앱을 발견<ph name="END_LINK" />했습니다.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" />에 캡처된 비정상 종료 보고서가 업로드되지 않았습니다.</translation>
<translation id="2367567093518048410">수준</translation>
<translation id="2378238891085281592">시크릿 모드로 전환됨</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 취소될 수 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="2418081434543109369">대상 서버인 <ph name="ORIGIN" />에서 모든 요청에
+ 보안 정책 적용을 요청했습니다. 하지만 현재
+ 정책 전달에 실패하여 브라우저가 <ph name="SITE" />에 대한 요청을
+ 처리할 수 없습니다.</translation>
<translation id="244665789865330679"><ph name="ENROLLMENT_DOMAIN" />에서 내 기기 및 계정을 관리합니다. 이는 관리자가 내 기기와 계정을 원격으로 구성할 수 있음을 의미합니다.</translation>
<translation id="2463193859425327265">홈페이지 변경</translation>
<translation id="2463739503403862330">입력</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">배달 방법 선택</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />네트워크 진단 프로그램 실행<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">이 페이지 번역하기</translation>
<translation id="2479410451996844060">검색 URL이 잘못됨</translation>
<translation id="2482878487686419369">알림</translation>
<translation id="248348093745724435">컴퓨터 정책</translation>
+<translation id="2485387744899240041">기기 및 브라우저에서 사용 중인 사용자 이름</translation>
<translation id="2491120439723279231">서버 인증서에 오류가 있습니다.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON 파서</translation>
<translation id="2495093607237746763">선택하면 이 기기에 카드 사본이 저장되어 Chromium에서 양식을 더 빠르게 입력할 수 있습니다.</translation>
<translation id="2498091847651709837">새 카드 스캔</translation>
<translation id="2501278716633472235">뒤로 이동</translation>
<translation id="2503184589641749290">사용 가능한 직불카드 및 선불카드</translation>
<translation id="2515629240566999685">현재 지역의 신호 확인</translation>
-<translation id="2516852381693169964"><ph name="SEARCH_ENGINE" />에서 이미지 검색</translation>
<translation id="2523886232349826891">이 기기에만 저장됨</translation>
<translation id="2524461107774643265">자세한 정보 추가</translation>
<translation id="2536110899380797252">주소 추가</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">문서가 비밀번호로 보호되고 있습니다. 비밀번호를 입력하세요.</translation>
<translation id="2609632851001447353">유사 버전</translation>
+<translation id="2618023639789766142">C10(봉투)</translation>
<translation id="2625385379895617796">시간이 너무 먼 미래로 설정되어 있습니다.</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" />의 서버 IP 주소를 찾을 수 없습니다.</translation>
<translation id="2639739919103226564">상태:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">다른 탭 또는 앱 닫기</translation>
<translation id="267371737713284912"><ph name="MODIFIER_KEY_DESCRIPTION" />을(를) 눌러 실행취소합니다.</translation>
<translation id="2674170444375937751">방문 기록에서 이 페이지를 삭제하시겠습니까?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">나가기</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">사용할 수 있는 카드</translation>
<translation id="2702801445560668637">읽기 목록</translation>
<translation id="2704283930420550640">값이 형식과 일치하지 않습니다.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">선택한 항목 삭제</translation>
<translation id="277133753123645258">배송 방법</translation>
<translation id="277499241957683684">기기 기록 없음</translation>
-<translation id="2781030394888168909">MacOS 내보내기</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">연결이 재설정되었습니다.</translation>
<translation id="2788784517760473862">사용 가능한 신용카드</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">이 연결은 <ph name="CIPHER" />을(를) 사용하여 암호화되고 인증되며 <ph name="KX" />을(를) 키 교환 매커니즘으로 사용합니다.</translation>
<translation id="2835170189407361413">서식 지우기</translation>
<translation id="2847118875340931228">시크릿 창 열기</translation>
+<translation id="2850739647070081192">Invite(봉투)</translation>
<translation id="2851634818064021665">이 사이트에 방문하려면 권한이 필요합니다.</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">카드를 저장하시겠습니까?</translation>
<translation id="2903493209154104877">주소</translation>
<translation id="290376772003165898">페이지가 <ph name="LANGUAGE" />로 되어 있지 않습니까?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">배달 방법</translation>
<translation id="2928905813689894207">청구서 수신 주소</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 <ph name="DOMAIN2" />에서 제공한 것입니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="2948083400971632585">설정 페이지의 연결을 구성하는 프록시를 사용 중지할 수 있습니다.</translation>
<translation id="2955913368246107853">검색 바 닫기</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4(봉투)</translation>
<translation id="3024663005179499861">잘못된 정책 유형</translation>
<translation id="3037605927509011580">앗, 이런!</translation>
<translation id="3041612393474885105">인증서 정보</translation>
+<translation id="3060227939791841287">C9(봉투)</translation>
<translation id="3064966200440839136">시크릿 모드를 종료하고 외부 애플리케이션에서 결제합니다. 계속하시겠습니까?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{없음}=1{비밀번호 1개}other{비밀번호 #개}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">수령 주소 추가</translation>
<translation id="3105172416063519923">애셋 ID:</translation>
<translation id="3109728660330352905">이 페이지를 볼 수 있는 권한이 없습니다.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" />의 <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">결제 취소</translation>
<translation id="3207960819495026254">북마크에 추가됨</translation>
-<translation id="3209375525920864198">올바른 세션 이름을 입력하세요.</translation>
+<translation id="321912867715453276">경고: 정책에 대한 소스가 두 개 이상 있으나 값이 동일합니다.</translation>
<translation id="3225919329040284222">서버가 내장된 기대치와 일치하지 않는 인증서를 전달했습니다. 이러한 기대치는 사용자를 보호하기 위해 보안이 엄격한 특정 웹사이트에 포함됩니다.</translation>
<translation id="3226128629678568754">페이지 로드에 필요한 데이터를 다시 제출하려면 새로고침 버튼을 누릅니다.</translation>
<translation id="3227137524299004712">마이크</translation>
<translation id="3228969707346345236">페이지가 <ph name="LANGUAGE" />(으)로 되어 있으므로 번역하지 못했습니다.</translation>
+<translation id="3229041911291329567">기기와 브라우저에 관한 버전 정보</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">카드 명의 추가</translation>
<translation id="3287510313208355388">온라인 상태일 때 다운로드</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> 정책에 관해 자세히 알아보기</translation>
<translation id="3303855915957856445">검색결과 없음</translation>
-<translation id="3305707030755673451"><ph name="TIME" />에 동기화 암호로 데이터가 암호화되었습니다. 동기화를 시작하려면 입력하세요.</translation>
<translation id="3320021301628644560">청구지 주소 추가</translation>
<translation id="3324983252691184275">진홍색</translation>
<translation id="3338095232262050444">보안 연결</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">수정 다시 실행(&amp;R)</translation>
<translation id="342781501876943858">다른 사이트에서 비밀번호를 재사용했다면 비밀번호를 재설정하는 것이 좋습니다.</translation>
<translation id="3431636764301398940">기기에 카드 저장</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">이 기기의 소유자가 공룡 게임을 사용 중지했습니다.</translation>
<translation id="3447884698081792621">인증서 표시(발급 기관: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">가져오기 간격:</translation>
+<translation id="3456231139987291353">Number-11(봉투)</translation>
<translation id="3461824795358126837">형광펜</translation>
<translation id="3462200631372590220">세부정보 숨기기</translation>
<translation id="3467763166455606212">카드 소유자 이름을 입력해야 합니다.</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">신용카드 및 선불카드를 사용할 수 있습니다.</translation>
<translation id="3582930987043644930">이름 추가</translation>
<translation id="3583757800736429874">이동 다시 실행(&amp;R)</translation>
+<translation id="35866233670761917">내가 방문한 웹사이트 콘텐츠는 관리자가 볼 수 없습니다.</translation>
<translation id="3586931643579894722">세부정보 숨기기</translation>
+<translation id="3592413004129370115">Italian(봉투)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">크기 2</translation>
<translation id="3615877443314183785">올바른 만료일을 입력하세요.</translation>
<translation id="36224234498066874">인터넷 사용 기록 삭제...</translation>
<translation id="362276910939193118">방문 기록 전체 보기</translation>
-<translation id="3623476034248543066">값 표시</translation>
<translation id="3630155396527302611">이미 네트워크 액세스가 허용된 프로그램으로 되어 있는 경우
목록에서 삭제한 뒤 다시 추가합니다.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">유효성 검사 성공</translation>
<translation id="3655670868607891010">이 메시지가 자주 표시된다면 다음을 시도해 보세요. <ph name="HELP_LINK" /></translation>
<translation id="3658742229777143148">개정</translation>
<translation id="366077651725703012">신용카드 정보 업데이트</translation>
<translation id="3676592649209844519">기기 ID:</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;을(를) 찾으셨나요?</translation>
<translation id="3678029195006412963">요청을 서명할 수 없음</translation>
<translation id="3678529606614285348">새 시크릿 창에서 페이지 열기(Ctrl-Shift-N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" />에 캡처된 비정상 종료 보고서가 <ph name="UPLOAD_TIME" />에 업로드됨</translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">사용 중인 네트워크에서 로그인 페이지 방문을 요청할 수 있습니다.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">로드 중...</translation>
+<translation id="3709599264800900598">복사한 텍스트</translation>
<translation id="3712624925041724820">라이선스 만료됨</translation>
<translation id="3714780639079136834">모바일 데이터 또는 Wi-Fi 사용 설정</translation>
<translation id="3715597595485130451">Wi-Fi 연결</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />프록시, 방화벽, DNS 설정 확인<ph name="END_LINK" /></translation>
<translation id="372429172604983730">이 오류를 일으키는 애플리케이션에는 바이러스 백신, 방화벽, 웹 필터링 또는 프록시 소프트웨어 등이 있습니다.</translation>
+<translation id="373042150751172459">B4(봉투)</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="3745099705178523657">카드를 확인하면 Google 계정의 카드 세부정보가 이 사이트와 공유됩니다.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">만료: <ph name="EXPIRATION_YEAR" />년 <ph name="EXPIRATION_MONTH" />월</translation>
<translation id="3789155188480882154">크기 16</translation>
+<translation id="3797522431967816232">Prc3(봉투)</translation>
<translation id="3807873520724684969">유해한 콘텐츠 차단됨</translation>
<translation id="3810973564298564668">관리</translation>
<translation id="382518646247711829">프록시 서버를 사용하는 경우</translation>
<translation id="3828924085048779000">암호를 빈 칸으로 두어서는 안 됩니다.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" />에서 추가 기능을 위한 확장 프로그램을 설치했습니다. 확장 프로그램에는 내 데이터 중 일부에 액세스할 권한이 있습니다.</translation>
<translation id="385051799172605136">뒤로</translation>
<translation id="3858027520442213535">시간과 날짜 업데이트</translation>
<translation id="3884278016824448484">기기 식별자 충돌</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">사용자의 사이트 액세스 요청이 <ph name="NAME" />님에게 전송되었습니다.</translation>
<translation id="3890664840433101773">이메일 추가</translation>
<translation id="3901925938762663762">만료된 카드입니다.</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">이 사이트에서 항상 물어보기</translation>
<translation id="3949571496842715403">보안 인증서에 주체 대체 이름(SAN)이 지정되어 있지 않아 이 서버가 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버를 잘못 설정했거나 공격자가 연결을 가로채고 있기 때문일 수도 있습니다.</translation>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{없음}=1{사이트 1개 }other{사이트 #개 }}</translation>
<translation id="397105322502079400">계산 중...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" />이(가) 차단됨</translation>
-<translation id="3984550557525787191">이미 존재하는 세션 이름입니다.</translation>
<translation id="3987940399970879459">1MB 미만</translation>
+<translation id="4008849406247176967">경고: 이 정책에 충돌하는 값을 가진 소스가 두 개 이상 있습니다.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{주변 웹페이지 1개}other{주변 웹페이지 #개}}</translation>
<translation id="4030383055268325496">추가 실행 취소(&amp;U)</translation>
+<translation id="4032320456957708163"><ph name="ENROLLMENT_DOMAIN" />에서 관리하는 브라우저입니다</translation>
<translation id="4058922952496707368">'<ph name="SUBKEY" />' 키: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1(봉투)</translation>
<translation id="4067947977115446013">유효한 주소 추가</translation>
<translation id="4072486802667267160">주문을 처리하는 중에 오류가 발생했습니다. 다시 시도하세요.</translation>
<translation id="4075732493274867456">클라이언트와 서버가 일반적인 SSL 프로토콜 버전 또는 암호화 제품군을 지원하지 않습니다.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">보라색</translation>
<translation id="4165986682804962316">사이트 설정</translation>
<translation id="4171400957073367226">잘못된 인증 서명입니다.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{그 외 <ph name="ITEM_COUNT" />개 항목}other{그 외 <ph name="ITEM_COUNT" />개 항목}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">이동 다시 실행(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />방화벽 및 바이러스 백신 소프트웨어 설정 확인<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9(봉투)</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="4221630205957821124">&lt;h4&gt;1단계: 포털에 로그인하기&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">비밀번호 재설정</translation>
<translation id="4280429058323657511">, 만료일 <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{다음 카드가 Google 계정에 저장되었습니다.}other{다음 카드가 Google 계정에 저장되었습니다.}}</translation>
+<translation id="42981349822642051">펼치기</translation>
+<translation id="4302965934281694568">Chou3(봉투)</translation>
<translation id="4305817255990598646">전환</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">차단(기본값)</translation>
+<translation id="4318566738941496689">기기 이름 및 네트워크 주소</translation>
<translation id="4325863107915753736">도움말을 찾지 못했습니다.</translation>
<translation id="4326324639298822553">만료일을 확인한 후 다시 시도해 주세요.</translation>
<translation id="4331708818696583467">주의 요함</translation>
<translation id="4340982228985273705">이 컴퓨터는 기업에서 관리하는 기기가 아닌 것으로 파악되므로, Chrome 웹 스토어에 호스팅된 확장 프로그램만 정책을 통해 자동으로 설치할 수 있습니다. Chrome 웹 스토어의 업데이트 URL은 '<ph name="CWS_UPDATE_URL" />'입니다.</translation>
<translation id="4346197816712207223">사용 가능한 신용카드</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">이 사이트의 공격자가 사용자 정보(예: 사진, 비밀번호, 메시지, 신용카드)를 도용하거나 삭제하는 위험한 프로그램을 컴퓨터에 설치하려고 시도할 수 있습니다.</translation>
<translation id="4358461427845829800">결제 수단 관리...</translation>
+<translation id="4367563149485757821">Number-12(봉투)</translation>
+<translation id="4372516964750095882">Fanfold-미국</translation>
<translation id="4372948949327679948">예상 <ph name="VALUE_TYPE" /> 값입니다.</translation>
<translation id="4377125064752653719"><ph name="DOMAIN" />에 접속하려 했으나 발행기관에서 서버가 전달한 인증서를 폐기했습니다. 이는 서버가 제시한 보안 자격증명 정보를 신뢰할 수 없음을 의미합니다. 사용자는 현재 공격자와 통신 중일 수도 있습니다.</translation>
<translation id="4378154925671717803">전화기</translation>
<translation id="4406896451731180161">검색결과</translation>
-<translation id="4406972042435603828">관리자가 강력한 기능이 포함된 확장 프로그램을 설치했습니다.</translation>
<translation id="4408413947728134509">쿠키 <ph name="NUM_COOKIES" />개</translation>
<translation id="4415426530740016218">픽업 주소</translation>
<translation id="4424024547088906515">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 Chrome에서 신뢰하는 보안 인증서가 아닙니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="443121186588148776">직렬 포트</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" />에서 로그인 인증서를 승인하지 않았거나 로그인 인증서가 제공되지 않았을 수 있습니다.</translation>
<translation id="4434045419905280838">팝업 및 리디렉션</translation>
+<translation id="4435702339979719576">엽서)</translation>
<translation id="443673843213245140">프록시 사용은 중지되었지만 명시적 프록시 설정이 지정되어 있습니다.</translation>
<translation id="445100540951337728">사용 가능한 직불카드</translation>
+<translation id="4466881336512663640">양식에서 변경한 사항이 삭제됩니다. 계속하시겠습니까?</translation>
<translation id="4482953324121162758">이 사이트는 번역되지 않습니다.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">잘못된 URL입니다. URL에는 표준 스키마가 있어야 합니다(예: http://example.com 또는 https://example.com).</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">유효성 검사 오류 <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">시스템 관리자에게 문의</translation>
<translation id="450710068430902550">관리자와 공유</translation>
+<translation id="4510487217173779431">Chou4(봉투)</translation>
<translation id="4515275063822566619">카드와 주소는 Chrome 및 Google 계정(<ph name="ACCOUNT_EMAIL" />)에서 가져왔습니다. 이 정보는 <ph name="BEGIN_LINK" />설정<ph name="END_LINK" />에서 관리할 수 있습니다.</translation>
+<translation id="4517607026994743406">Comm-10(봉투)</translation>
<translation id="4522570452068850558">세부정보</translation>
<translation id="4524805452350978254">카드 관리</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">확장 프로그램 사용 중지해 보기</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">배송</translation>
+<translation id="4579056131138995126">Personal(봉투)</translation>
<translation id="4582204425268416675">카드 삭제</translation>
<translation id="4587425331216688090">Chrome에서 주소를 삭제하시겠습니까?</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" />에 대한 연결은 최신 암호화 기술을 사용하여 암호화됩니다.</translation>
<translation id="4594403342090139922">삭제 실행 취소(&amp;U)</translation>
<translation id="4597348597567598915">크기 8</translation>
+<translation id="4600854749408232102">C6/C5(봉투)</translation>
<translation id="4646534391647090355">지금 이동</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서에 오류가 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="467809019005607715">Google 프레젠테이션</translation>
<translation id="4690462567478992370">유효하지 않은 인증서 사용 중단</translation>
+<translation id="4691835149146451662">Architecture-A(봉투)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">연결이 끊김</translation>
<translation id="471880041731876836">이 사이트에 방문할 수 있는 권한이 없습니다.</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows 네트워크 진단 프로그램 실행<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">정책 새로고침</translation>
<translation id="4728558894243024398">플랫폼</translation>
+<translation id="4731967714531604179">Prc2(봉투)</translation>
<translation id="4736825316280949806">Chromium 다시 시작</translation>
<translation id="473775607612524610">업데이트</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> 추천 검색어</translation>
<translation id="4742407542027196863">비밀번호 관리...</translation>
<translation id="4744603770635761495">실행 가능 경로</translation>
+<translation id="4746351372139058112">메시지</translation>
<translation id="4750917950439032686">비밀번호나 신용카드 번호 등의 정보는 비공개 상태로 이 사이트에 전송됩니다.</translation>
<translation id="4756388243121344051">방문 기록(&amp;H)</translation>
<translation id="4758311279753947758">연락처 정보 추가</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478"><ph name="URL" />의 웹페이지가 일시적으로 다운되었거나 새 웹 주소로 완전히 이동했을 수 있습니다.</translation>
<translation id="4771973620359291008">알 수 없는 오류가 발생했습니다.</translation>
<translation id="4785689107224900852">이 탭으로 전환</translation>
-<translation id="4792143361752574037">세션 파일에 액세스하는 중에 문제가 발생했습니다. 현재 디스크에 저장할 수 없습니다. 페이지를 새로고침하여 다시 시도하세요.</translation>
<translation id="4798078619018708837">카드 세부정보를 업데이트하려면 <ph name="CREDIT_CARD" /> 카드의 만료일과 CVC를 입력하세요. 카드를 확인하면 Google 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation>
<translation id="4800132727771399293">유효기간과 CVC를 확인한 후 다시 시도해 주세요.</translation>
+<translation id="480334179571489655">기존 정책 오류</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">열기</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">검색결과가 없습니다.</translation>
<translation id="4950898438188848926">탭 전환 버튼, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> 열린 탭으로 전환하려면 Enter를 누르세요</translation>
<translation id="495170559598752135">작업</translation>
-<translation id="495832697253704892">확장 프로그램 보고</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">펼치기 목록</translation>
<translation id="4974590756084640048">경고 다시 사용</translation>
+<translation id="4984339528288761049">Prc5(봉투)</translation>
<translation id="4989163558385430922">모두 보기</translation>
<translation id="4989809363548539747">이 플러그인은 지원되지 않습니다.</translation>
-<translation id="4996230189582812866">보고</translation>
<translation id="5002932099480077015">선택하면 Chrome에서 양식을 더 빠르게 작성할 수 있도록 이 기기에 카드 사본을 저장합니다.</translation>
-<translation id="5014174725590676422">Chrome의 Google 어시스턴트 첫 실행 화면이 표시됩니다.</translation>
<translation id="5015510746216210676">컴퓨터 이름:</translation>
+<translation id="5017554619425969104">복사한 텍스트</translation>
<translation id="5018422839182700155">이 페이지를 열 수 없음</translation>
<translation id="5019198164206649151">보조 기억 장치 상태가 잘못됨</translation>
<translation id="5023310440958281426">관리자 정책을 확인하세요.</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">로컬 컨텍스트 <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">허용</translation>
<translation id="5040262127954254034">개인정보 보호</translation>
+<translation id="5043480802608081735">복사한 링크</translation>
<translation id="5045550434625856497">비밀번호가 잘못되었습니다.</translation>
<translation id="5056549851600133418">추천 기사</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />프록시 주소 확인<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM 사용 등의 기기 통계</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465"><ph name="ENROLLMENT_DOMAIN" />에서 내 기기를 관리하고 <ph name="ACCOUNT_DOMAIN" />에서 내 계정을 관리합니다. 이는 관리자가 내 기기와 계정을 원격으로 구성할 수 있음을 의미합니다.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64비트)</translation>
-<translation id="5128122789703661928">세션 이름이 잘못되어 삭제할 수 없습니다.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">주소 관리...</translation>
+<translation id="5138227688689900538">간략히</translation>
<translation id="5141240743006678641">동기화 비밀번호를 Google 자격증명으로 암호화</translation>
<translation id="5145883236150621069">정책 응답에 오류 코드가 포함되어 있음</translation>
+<translation id="515292512908731282">C4(봉투)</translation>
<translation id="5159010409087891077">새 시크릿 창에서 페이지 열기(⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> 카드의 CVC를 입력하세요. 카드를 확인하면 Google 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation>
<translation id="5169827969064885044">조직의 계정에 액세스할 수 없게 되거나 신원 도용이 발생할 수도 있습니다. 지금 비밀번호를 변경하는 것이 좋습니다.</translation>
<translation id="5171045022955879922">검색 또는 URL 입력</translation>
+<translation id="5171689220826475070">Fanfold-유럽</translation>
<translation id="5172758083709347301">컴퓨터</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />가 아닙니까? 오류 신고</translation>
<translation id="5190835502935405962">북마크바</translation>
-<translation id="5200263511887412697">최근 로그인한 기기 사용자 목록을 보고합니다.</translation>
+<translation id="519422657042045905">주석을 사용할 수 없음</translation>
<translation id="5201306358585911203">이 페이지에 삽입된 페이지 내용:</translation>
<translation id="5205222826937269299">이름은 필수입니다.</translation>
<translation id="5215116848420601511">Google Pay에 사용되는 결제 수단 및 주소</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">이메일은 필수입니다.</translation>
<translation id="5230733896359313003">배송지 주소</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">'네트워크에 연결'</translation>
<translation id="5251803541071282808">클라우드</translation>
+<translation id="5252000469029418751">C7(봉투)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">네트워크 주소</translation>
<translation id="5285570108065881030">저장된 비밀번호 모두 표시</translation>
<translation id="5287240709317226393">쿠키 표시</translation>
<translation id="5288108484102287882">정책 값 유효성 검사 결과 경고가 발생했습니다.</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" />/<ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">연락처 정보 선택</translation>
<translation id="5327248766486351172">이름</translation>
+<translation id="5329858041417644019">관리 대상 브라우저가 아닙니다</translation>
<translation id="5332219387342487447">배송 방법</translation>
+<translation id="5334013548165032829">세부 시스템 로그</translation>
<translation id="5344579389779391559">이 페이지에서 금액을 청구할 수 있습니다.</translation>
<translation id="5355557959165512791">인증서가 취소되었기 때문에 현재 <ph name="SITE" />에 방문할 수 없습니다. 네트워크 오류와 공격은 대부분 일시적이므로 나중에 이 페이지가 정상적으로 작동할 수 있습니다.</translation>
<translation id="536296301121032821">정책 설정 저장 실패</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">'시간이 너무 먼 과거로 설정되어 있습니다.', '시간이 너무 먼 미래로 설정되어 있습니다.', 또는 '&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;'</translation>
<translation id="5384855140246857529">어느 기기에서나 카드를 사용하려면 로그인하고 동기화를 사용 설정하세요.</translation>
<translation id="5386426401304769735">이 사이트의 인증서 체인은 SHA-1을 사용하여 서명된 인증서를 포함합니다.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없습니다. 서버의 보안 인증서가 현재 유효하지 않습니다. 서버를 잘못 설정했거나 공격자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
<translation id="5421136146218899937">인터넷 사용 기록 삭제...</translation>
<translation id="5430298929874300616">북마크 삭제</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">잘못된 데이터</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">수정 다시 실행(&amp;R)</translation>
+<translation id="5478437291406423475">B6/C4(봉투)</translation>
<translation id="5481076368049295676">이 콘텐츠는 사용자의 정보를 도용하거나 삭제하는 위험한 소프트웨어를 기기에 설치하려 할 수도 있습니다. <ph name="BEGIN_LINK" />표시하기<ph name="END_LINK" /></translation>
<translation id="54817484435770891">유효한 주소 추가</translation>
<translation id="5490432419156082418">주소 및 기타</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
시스템 관리자에게 문의하세요.</translation>
<translation id="549333378215107354">크기 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">관리 북마크</translation>
<translation id="5510766032865166053">이동되었거나 삭제되었을 수 있습니다.</translation>
<translation id="5523118979700054094">정책 이름</translation>
<translation id="552553974213252141">텍스트가 올바로 추출되었습니까?</translation>
+<translation id="553484882784876924">Prc6(봉투)</translation>
<translation id="5540224163453853">요청한 글을 찾지 못했습니다.</translation>
<translation id="5541546772353173584">이메일 추가</translation>
<translation id="5545756402275714221">추천 기사</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">주소 수정</translation>
<translation id="5598944008576757369">결제 수단 선택</translation>
<translation id="560412284261940334">관리가 지원되지 않음</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">연결 확인</translation>
<translation id="5610807607761827392"><ph name="BEGIN_LINK" />설정<ph name="END_LINK" />에서 카드와 주소를 관리할 수 있습니다.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" />에서 리디렉션한 횟수가 너무 많습니다.</translation>
<translation id="5629630648637658800">정책 설정 로드 실패</translation>
<translation id="5631439013527180824">잘못된 기기 관리 토큰</translation>
+<translation id="5632627355679805402"><ph name="TIME" />자로 데이터가 <ph name="BEGIN_LINK" />Google 비밀번호<ph name="END_LINK" />를 통해 암호화되었습니다. 동기화를 시작하려면 비밀번호를 입력하세요.</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="563324245173044180">사기성 콘텐츠 차단됨</translation>
<translation id="5659593005791499971">이메일</translation>
+<translation id="5663614846592581799">9x11(봉투)</translation>
+<translation id="5663955426505430495">이 기기의 관리자가 추가 기능을 위한 확장 프로그램을 설치했습니다. 확장 프로그램에는 내 데이터 중 일부에 액세스할 권한이 있습니다.</translation>
<translation id="5675650730144413517">페이지가 작동하지 않습니다.</translation>
+<translation id="5684874026226664614">죄송합니다. 이 페이지를 번역할 수 없습니다.</translation>
<translation id="5685654322157854305">배송지 주소 추가</translation>
<translation id="5689199277474810259">JSON 형식으로 내보내기</translation>
<translation id="5689516760719285838">위치</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">이 웹사이트의 주소가 확인되지 않았습니다.</translation>
<translation id="5719499550583120431">선불카드를 사용할 수 있습니다.</translation>
<translation id="5720705177508910913">현재 사용자</translation>
+<translation id="5728056243719941842">C5(봉투)</translation>
<translation id="5730040223043577876">다른 사이트에서 비밀번호를 재사용했다면 비밀번호를 재설정하는 것이 좋습니다.</translation>
<translation id="5732392974455271431">부모님이 차단 해제할 수 있습니다.</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Google 계정에 카드 저장}other{Google 계정에 카드 저장}}</translation>
<translation id="5763042198335101085">올바른 이메일 주소를 입력하세요.</translation>
<translation id="5765072501007116331">배달 방법과 요구사항을 확인하려면 주소를 선택하세요.</translation>
-<translation id="5770114862687765385">파일이 손상된 것 같습니다. 세션을 다시 설정하려면 '재설정' 버튼을 클릭하세요.</translation>
<translation id="5778550464785688721">MIDI 기기 전체 제어</translation>
<translation id="578305955206182703">황색</translation>
<translation id="57838592816432529">음소거</translation>
<translation id="5784606427469807560">카드 확인 중에 문제가 발생했습니다. 인터넷 연결을 확인하고 다시 시도하세요.</translation>
<translation id="5785756445106461925">또한 이 페이지에는 안전하지 않은 다른 리소스가 포함되어 있습니다. 이러한 리소스는 전송 중에 다른 사람이 볼 수 있으며 페이지의 모양을 변경하기 위해 공격자가 수정할 수 있습니다.</translation>
<translation id="5786044859038896871">카드 정보를 입력하시겠습니까?</translation>
+<translation id="5798290721819630480">변경사항을 삭제하시겠습니까?</translation>
<translation id="5798683403665926540">Chrome 설정에서 홈페이지를 변경하세요.</translation>
<translation id="5803412860119678065"><ph name="CARD_DETAIL" />을(를) 입력하시겠습니까?</translation>
<translation id="5804241973901381774">권한</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" />에 대한 연결이 더 이상 사용되지 않는 암호화 기술을 사용하여 암호화됩니다.</translation>
<translation id="5813119285467412249">추가 다시 실행(&amp;R)</translation>
<translation id="5838278095973806738">이 사이트에 입력하는 비밀번호나 신용카드 번호 등의 정보가 공격자에 의해 도용될 수 있습니다.</translation>
+<translation id="5860033963881614850">사용 안함</translation>
<translation id="5863847714970149516">방문하려는 페이지에서 금액을 청구할 수 있습니다.</translation>
<translation id="5866257070973731571">전화번호 추가</translation>
<translation id="5869405914158311789">사이트에 연결할 수 없음</translation>
<translation id="5869522115854928033">저장된 비밀번호</translation>
<translation id="5887400589839399685">저장된 카드</translation>
-<translation id="5893718151540690985">네트워크 유형과 하드웨어 주소를 포함한 네트워크 인터페이스 목록을 보고합니다.</translation>
<translation id="5893752035575986141">신용카드를 사용할 수 있습니다.</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="5916664084637901428">사용</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">카드를 Google 계정에 저장하시겠습니까?</translation>
<translation id="5922853866070715753">거의 완료되었습니다</translation>
<translation id="5932224571077948991">사이트에서 방해가 되거나 사용자를 현혹하는 광고를 표시함</translation>
-<translation id="5939518447894949180">초기화</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> 여는 중…</translation>
<translation id="5951495562196540101">일반 계정으로 등록할 수 없습니다(패키지 라이선스 사용 가능).</translation>
<translation id="5967592137238574583">연락처 정보 수정</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">축소</translation>
<translation id="5977489021191000276">내 기기는 관리자에 의해 관리되지 않습니다.</translation>
<translation id="5977976211062815271">이 기기에서</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">결제 앱을 열 수 없습니다.</translation>
<translation id="5989320800837274978">고정 프록시 서버와 .pac 스크립트 URL이 모두 지정되지 않았습니다.</translation>
<translation id="5990559369517809815">서버에 대한 요청이 확장 프로그램에 의해 차단되었습니다.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">CPU/RAM 사용 등의 하드웨어 통계를 보고합니다.</translation>
<translation id="6034000775414344507">연한 회색</translation>
+<translation id="6034283069659657473">10x14(봉투)</translation>
<translation id="6039846035001940113">문제가 계속되면 사이트 소유자에게 문의하세요.</translation>
<translation id="6040143037577758943">닫기</translation>
<translation id="6044573915096792553">크기 12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">현재 <ph name="SITE" />에서 인증서 고정을 사용하기 때문에 방문할 수 없습니다. 네트워크 오류와 공격은 대부분 일시적이므로 나중에 이 페이지가 정상적으로 작동할 수 있습니다.</translation>
<translation id="6058977677006700226">모든 기기에서 카드를 사용하고 싶으신가요?</translation>
<translation id="6059925163896151826">USB 기기</translation>
-<translation id="6071091556643036997">잘못된 정책 유형입니다.</translation>
<translation id="6080696365213338172">관리자 제공 인증서를 사용하여 콘텐츠에 액세스했습니다. 사용자가 <ph name="DOMAIN" />에 제공한 데이터가 관리자에 의해 차단될 수 있습니다.</translation>
<translation id="6094273045989040137">주석 추가</translation>
<translation id="610911394827799129">Google 계정의 내 활동(<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />)에는 인터넷 방문 기록이 다른 형식으로 남아 있을 수도 있습니다</translation>
+<translation id="6132597952260690497">설치된 확장 프로그램 및 플러그인에 관한 정보</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{없음}=1{비밀번호 1개(동기화됨)}other{비밀번호 #개(동기화됨)}}</translation>
<translation id="6146055958333702838">케이블을 확인하고 사용 중인 라우터, 모뎀 또는 기타 네트워크 기기를
재부팅하시기 바랍니다.</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> 미만의 저장용량을 확보합니다. 일부 사이트는 다음 방문 시 로드 속도가 느려질 수 있습니다.</translation>
<translation id="6337534724793800597">이름별로 정책 필터링</translation>
<translation id="6358450015545214790">자세히 알아보기</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">해당 사이트에서 비용이 청구될 수 있음</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{그 외 제안 1건}other{그 외 제안 #건}}</translation>
<translation id="6387754724289022810">다음번에 더 빠르게 결제할 수 있도록 Google 계정과 기기에 카드와 청구서 수신 주소를 저장하세요.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">북마크 수정</translation>
+<translation id="6406765186087300643">C0(봉투)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />의 만료일과 CVC를 입력하세요.</translation>
<translation id="6414888972213066896">이 사이트를 방문해도 괜찮은지 부모님께 문의했습니다.</translation>
<translation id="6417515091412812850">인증서가 취소되었는지 확인할 수 없습니다.</translation>
<translation id="6433490469411711332">연락처 정보 수정</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" />에서 연결을 거부했습니다.</translation>
+<translation id="6434309073475700221">중지</translation>
+<translation id="6446163441502663861">Kahu(봉투)</translation>
<translation id="6446608382365791566">자세한 정보 추가</translation>
<translation id="6447842834002726250">쿠키</translation>
<translation id="6451458296329894277">양식 다시 제출 확인</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Chrome 다시 시작하기</translation>
<translation id="6529602333819889595">삭제 다시 실행(&amp;R)</translation>
<translation id="6534179046333460208">피지컬 웹 제안</translation>
+<translation id="6556866813142980365">다시실행</translation>
<translation id="6563469144985748109">관리자가 아직 승인하지 않았습니다.</translation>
<translation id="6569060085658103619">확장 프로그램 페이지를 보는 중</translation>
+<translation id="6578796323535178455">C2(봉투)</translation>
<translation id="6579990219486187401">연한 분홍색</translation>
+<translation id="6583674473685352014">B6(봉투)</translation>
+<translation id="6587923378399804057">복사한 링크</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> 기기는 관리 대상 기기가 아닙니다.</translation>
<translation id="6596325263575161958">암호화 옵션</translation>
<translation id="6604181099783169992">모션 또는 조도 센서</translation>
+<translation id="6609880536175561541">Prc7(봉투)</translation>
<translation id="6624427990725312378">연락처 정보</translation>
<translation id="6626291197371920147">유효한 카드 번호 추가</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 검색</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">이 정책은 사용되지 않습니다.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{없음}=1{사이트 1개(Google 계정에서 로그아웃되지 않음)}other{사이트 #개(Google 계정에서 로그아웃되지 않음)}}</translation>
<translation id="6657585470893396449">비밀번호</translation>
+<translation id="6670613747977017428">안전한 페이지로 돌아갑니다.</translation>
<translation id="6671697161687535275">Chromium에서 자동완성 항목 추천을 삭제하시겠습니까?</translation>
<translation id="6685834062052613830">로그아웃 후 설정 완료</translation>
<translation id="6710213216561001401">이전</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">등록 토큰:</translation>
<translation id="6711464428925977395">프록시 서버에 문제가 발생했거나 주소가 잘못되었습니다.</translation>
<translation id="6723740634201835758">내 Google 계정에서</translation>
+<translation id="6738516213925468394"><ph name="TIME" />자로 <ph name="BEGIN_LINK" />동기화 암호<ph name="END_LINK" />를 통해 데이터가 암호화되었습니다. 동기화를 시작하려면 암호를 입력하세요.</translation>
<translation id="674375294223700098">알 수 없는 서버 인증서 오류입니다.</translation>
<translation id="6744009308914054259">연결을 기다리는 동안 다운로드에서 오프라인 기사를 읽을 수 있습니다.</translation>
<translation id="6753269504797312559">정책 값</translation>
<translation id="6757797048963528358">기기가 절전 모드 상태입니다.</translation>
+<translation id="6768213884286397650">Hagaki(엽서)</translation>
<translation id="6778737459546443941">부모님이 아직 승인하지 않았습니다.</translation>
<translation id="67862343314499040">보라색</translation>
+<translation id="6786747875388722282">확장 프로그램</translation>
<translation id="679355240208270552">정책에 의해 기본 검색이 사용 설정되지 않았기 때문에 무시되었습니다.</translation>
<translation id="681021252041861472">필수 입력란</translation>
<translation id="6810899417690483278">맞춤설정 ID</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">기기</translation>
<translation id="6970216967273061347">주소</translation>
<translation id="6973656660372572881">고정 프록시 서버와 .pac 스크립트 URL이 모두 지정되어 있습니다.</translation>
+<translation id="6973932557599545801">죄송합니다. 더 이상 도와드릴 수 없습니다. 직접 계속해 주세요.</translation>
<translation id="6979158407327259162">Google 드라이브</translation>
<translation id="6979440798594660689">음소거(기본값)</translation>
<translation id="6984479912851154518">시크릿 모드를 종료하고 외부 애플리케이션에서 결제합니다. 계속하시겠습니까?</translation>
<translation id="6989763994942163495">고급 설정 표시</translation>
+<translation id="6993898126790112050">6x9(봉투)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> 항상 번역</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">이러한 금액 청구는 일회성이거나 반복적일 수 있으며 불분명한 방식으로 이루어질 수도 있습니다.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">숨기기</translation>
<translation id="7108819624672055576">확장 프로그램에서 허용</translation>
<translation id="7111012039238467737">(유효)</translation>
+<translation id="7118618213916969306">클립보드 URL <ph name="SHORT_URL" /> 검색</translation>
<translation id="7119414471315195487">다른 탭 또는 프로그램 닫기</translation>
<translation id="7129409597930077180">이 주소로 배송할 수 없습니다. 다른 주소를 선택하세요.</translation>
<translation id="7135130955892390533">상태 보기</translation>
<translation id="7138472120740807366">배달 방법</translation>
<translation id="7139724024395191329">에미레이트</translation>
+<translation id="7152423860607593928">Number-14(봉투)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">라벤더색</translation>
-<translation id="7158980942472052083">잘못된 URL입니다. URL이 표준 스키마를 사용해야 합니다.</translation>
<translation id="717330890047184534">GAIA ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">대상 서버인 <ph name="ORIGIN" />에서 모든 요청에
+ 보안 정책 적용을 요청했습니다. 하지만
+ 정책을 전달하는 대신 브라우저를 다른 곳으로 리디렉션하여
+ 브라우저가 <ph name="SITE" />에 대한 요청을 처리할 수 없습니다.</translation>
<translation id="7179323680825933600">결제 수단 저장 및 자동 입력</translation>
<translation id="7180611975245234373">새로고침</translation>
<translation id="7182878459783632708">설정된 정책 없음</translation>
<translation id="7186367841673660872">이 페이지는<ph name="ORIGINAL_LANGUAGE" />에서<ph name="LANGUAGE_LANGUAGE" />로 번역되었습니다.</translation>
<translation id="7192203810768312527"><ph name="SIZE" />의 저장용량을 확보합니다. 일부 사이트는 다음에 방문할 때 로드 속도가 느려질 수도 있습니다.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">관리자가 볼 수 있는 항목은 다음과 같습니다.</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" />에서 보안 기준을 준수하지 않습니다.</translation>
<translation id="721197778055552897">이 문제에 대해 <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation>
<translation id="7219179957768738017"><ph name="SSL_VERSION" /> 연결입니다.</translation>
<translation id="7220786058474068424">처리 중</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">다음 사이트에 멀웨어가 있습니다.</translation>
+<translation id="724766306220616965">경고, 충돌</translation>
<translation id="724975217298816891">카드 세부정보를 업데이트하려면 <ph name="CREDIT_CARD" /> 카드의 만료일과 CVC를 입력하세요. 카드를 확인하면 카드 세부정보가 이 사이트와 공유됩니다.</translation>
<translation id="7251437084390964440">네트워크 설정이 ONC 표준을 준수하지 않습니다. 일부 설정을 가져오지 못했을 수도 있습니다.
추가 세부정보:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">코발트 녹색</translation>
<translation id="7302712225291570345">‘<ph name="TEXT" />’</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />에 캡처된 비정상 종료 보고서(사용자가 업로드를 요청했으나 아직 업로드되지 않음)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />세이프 브라우징<ph name="END_LINK" /> 경고</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">연결 도움말</translation>
<translation id="7334320624316649418">재정렬 다시 실행(&amp;R)</translation>
<translation id="733923710415886693">서버 인증서가 인증서 투명성 정책을 사용하여 공개되지 않았습니다.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">명령줄</translation>
-<translation id="7365061714576910172">Linux 내보내기</translation>
<translation id="7372973238305370288">검색결과</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">안함</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">관리 세션 재정의</translation>
<translation id="7390545607259442187">카드 확인</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> 기기는 관리 대상 기기입니다</translation>
<translation id="7407424307057130981">&lt;p&gt;Windows 컴퓨터에 Superfish 소프트웨어가 있으면 이 오류가 표시됩니다.&lt;/p&gt;
&lt;p&gt;소프트웨어를 일시적으로 사용 중지하여 웹에 접속하려면 다음 단계를 따르세요. 관리자 권한이 필요합니다.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@
&lt;li&gt;&lt;strong&gt;서비스 상태&lt;/strong&gt;에서 &lt;strong&gt;중지&lt;/strong&gt;를 클릭합니다.
&lt;li&gt;&lt;strong&gt;적용&lt;/strong&gt;을 클릭한 다음 &lt;strong&gt;확인&lt;/strong&gt;을 클릭합니다.
&lt;li&gt;&lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome 고객센터&lt;/a&gt;를 방문하여 컴퓨터에서 소프트웨어를 영구적으로 삭제하는 방법을 알아보세요. &lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> 관리</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">비밀번호 관리...</translation>
<translation id="7419106976560586862">프로필 경로</translation>
<translation id="7437289804838430631">연락처 정보 추가</translation>
@@ -1012,22 +1154,24 @@
<translation id="7442725080345379071">연한 주황색</translation>
<translation id="7444046173054089907">차단된 사이트</translation>
<translation id="7445762425076701745">연결하려는 서버 ID를 확인할 수 없습니다. 외부 인증 기관에서 소유권을 확인할 수 없으므로 네트워크에서 유효한 이름을 사용하여 서버에 연결됩니다. 일부 인증 기관에서는 이러한 이름에 대해 관계없이 인증서를 발급하기 때문에 공격자가 아니라 의도한 웹사이트에 연결되어 있는지 확인할 수 없습니다.</translation>
-<translation id="7449109375006139765">시스템 로그를 관리 서버로 전송합니다.</translation>
<translation id="7451311239929941790">이 문제를 <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation>
<translation id="7455133967321480974">전체 기본값 사용(차단)</translation>
<translation id="7460618730930299168">선택한 영화와 상영 영화가 다릅니다. 계속하시겠습니까?</translation>
<translation id="7473891865547856676">건너뛰기</translation>
-<translation id="7475525192983021547">사용자가 기기를 사용한 시간을 보고합니다.</translation>
<translation id="7481312909269577407">앞으로</translation>
<translation id="7485870689360869515">데이터 없음</translation>
+<translation id="7498234416455752244">계속 수정</translation>
<translation id="7508255263130623398">반환된 정책 기기 ID가 비었거나 현재 기기 ID와 일치하지 않음</translation>
<translation id="7508870219247277067">아보카도 녹색</translation>
<translation id="7511955381719512146">사용 중인 Wi-Fi에서 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> 방문을 요청할 수 있습니다.</translation>
<translation id="7514365320538308">다운로드</translation>
<translation id="7518003948725431193">다음 웹 주소(<ph name="URL" />)에 대해 발견된 웹페이지가 없습니다.</translation>
+<translation id="7520302887438682816">C8(봉투)</translation>
<translation id="7521387064766892559">자바스크립트</translation>
<translation id="7526934274050461096">이 사이트로의 연결은 비공개가 아닙니다.</translation>
+<translation id="7535087603100972091">값</translation>
<translation id="7537536606612762813">필수</translation>
+<translation id="7538364083937897561">A2(봉투)</translation>
<translation id="7542403920425041731">확인하면 카드 세부정보가 이 사이트와 공유됩니다.</translation>
<translation id="7542995811387359312">양식에 보안 연결이 사용되지 않아 신용카드 자동 채우기가 사용 중지되었습니다.</translation>
<translation id="7543525346216957623">부모님께 물어보세요.</translation>
@@ -1036,8 +1180,8 @@
<translation id="7552846755917812628">다음 도움말을 확인해 보세요.</translation>
<translation id="7554791636758816595">새 탭</translation>
<translation id="7564049878696755256"><ph name="ORG_NAME" /> 계정에 액세스할 수 없게 되거나 신원 도용이 발생할 수도 있습니다. 따라서 지금 비밀번호를 변경하는 것이 좋습니다.</translation>
-<translation id="7566125604157659769">복사한 텍스트</translation>
<translation id="7567204685887185387">이 서버가 <ph name="DOMAIN" />임을 입증할 수 없으며 서버의 보안 인증서가 부정한 방식으로 발행되었을 수 있습니다. 서버를 잘못 설정했거나 불법 사용자가 연결을 가로채고 있기 때문일 수 있습니다.</translation>
+<translation id="7568105740864181217">이 브라우저는 회사, 학교 또는 기타 조직에서 관리합니다. 관리자가 원격으로 브라우저 설정을 변경할 수 있습니다. 이 기기의 활동은 Chrome 외부에서 관리될 수도 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome에서 신용카드를 삭제하시겠습니까?</translation>
<translation id="7569983096843329377">검정색</translation>
<translation id="7578104083680115302">Google에 저장한 카드를 사용하여 어떤 기기에서든지 사이트 및 앱에서 빠르게 지불할 수 있습니다.</translation>
@@ -1048,6 +1192,7 @@
<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="7633909222644580952">성능 데이터 및 비정상 종료 보고서</translation>
<translation id="7637571805876720304">Chromium에서 신용카드를 삭제하시겠습니까?</translation>
<translation id="7639968568612851608">짙은 회색</translation>
<translation id="765676359832457558">고급 설정 숨기기</translation>
@@ -1057,9 +1202,11 @@
<translation id="7667346355482952095">반환된 정책 토큰이 비었거나 현재 토큰과 일치하지 않음</translation>
<translation id="7668654391829183341">알 수 없는 기기</translation>
<translation id="7669271284792375604">이 사이트의 공격자가 인터넷 사용 환경에 악영향을 미치는 프로그램을 설치하도록 속임수(예를 들어, 방문하는 사이트의 홈페이지를 변경하거나 추가로 광고를 표시)를 시도할 수 있습니다.</translation>
+<translation id="7676643023259824263">클립보드 텍스트 <ph name="TEXT" /> 검색</translation>
<translation id="7681101578153515023">검색엔진 변경</translation>
<translation id="7682287625158474539">배송</translation>
<translation id="7687186412095877299">저장된 결제 수단이 결제 양식에 자동으로 입력됩니다.</translation>
+<translation id="7697066736081121494">Prc8(봉투)</translation>
<translation id="769721561045429135">현재 이 기기에서만 사용할 수 있는 카드가 있습니다. 카드를 검토하려면 계속을 클릭하세요.</translation>
<translation id="7699293099605015246">지금은 기사를 가져올 수 없음</translation>
<translation id="7701040980221191251">없음</translation>
@@ -1071,11 +1218,13 @@
<translation id="774634243536837715">위험한 콘텐츠 차단됨</translation>
<translation id="7752995774971033316">관리되지 않음</translation>
<translation id="7755287808199759310">부모님이 차단 해제할 수 있습니다.</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">방화벽이나 바이러스 백신 소프트웨어가 연결을 차단했을 수 있습니다.</translation>
<translation id="7759163816903619567">표시 도메인:</translation>
<translation id="7761701407923456692">서버의 인증서가 URL과 일치하지 않습니다.</translation>
<translation id="7763386264682878361">결제 매니페스트 파서</translation>
<translation id="7764225426217299476">주소 추가</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">현</translation>
<translation id="7791543448312431591">추가</translation>
<translation id="7793809570500803535"><ph name="SITE" />의 웹페이지가 일시적으로 다운되었거나 새 웹 주소로 완전히 이동했을 수 있습니다.</translation>
@@ -1087,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome에서 추천검색어를 삭제하시겠습니까?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />'에 대해 <ph name="SEARCH_RESULTS" /> <ph name="NUMBER_OF_RESULTS" />개의 검색 결과를 찾았습니다.</translation>
-<translation id="7818867226424560206">정책 관리</translation>
<translation id="782886543891417279">사용 중인 Wi-Fi(<ph name="WIFI_NAME" />)에서 로그인 페이지 방문을 요청할 수 있습니다.</translation>
+<translation id="7836231406687464395">Postfix(봉투)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{없음}=1{앱 1개(<ph name="EXAMPLE_APP_1" />)}=2{앱 2개(<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{앱 #개(<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">하지만 흔적이 아예 남지 않는 것은 아닙니다. 시크릿 모드로 탐색해도 회사, 인터넷 서비스 제공업체 또는 방문한 웹사이트에 저장된 흔적까지 없앨 수는 없습니다.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@
<translation id="7878562273885520351">비밀번호가 도용될 수도 있음</translation>
<translation id="7882421473871500483">갈색</translation>
<translation id="7887683347370398519">CVC를 확인한 후 다시 시도하세요.</translation>
-<translation id="7893255318348328562">세션 이름</translation>
+<translation id="7904208859782148177">C3(봉투)</translation>
<translation id="79338296614623784">올바른 전화번호를 입력하세요.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">만료일: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@
<translation id="7951415247503192394">(32비트)</translation>
<translation id="7956713633345437162">모바일 북마크</translation>
<translation id="7961015016161918242">사용하지 않음</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">지정되지 않음</translation>
<translation id="800218591365569300">다른 탭이나 프로그램을 종료하여 메모리를 확보하세요.</translation>
+<translation id="8004582292198964060">브라우저</translation>
<translation id="8009225694047762179">비밀번호 관리</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{이 카드와 청구서 수신 주소가 저장됩니다. <ph name="USER_EMAIL" /> 계정으로 로그인하면 카드를 사용할 수 있습니다.}other{이 카드와 청구서 수신 주소가 저장됩니다. <ph name="USER_EMAIL" /> 계정으로 로그인하면 카드를 사용할 수 있습니다.}}</translation>
<translation id="8012647001091218357">현재 부모님께 연락할 수 없습니다. 나중에 다시 시도해 주세요.</translation>
<translation id="8025119109950072390">이 사이트의 공격자가 소프트웨어를 설치하거나 개인정보(예: 비밀번호, 전화번호, 신용카드)를 공개하는 등의 위험한 행동을 하도록 사용자를 속일 수 있습니다.</translation>
<translation id="8034522405403831421">이 페이지는 <ph name="SOURCE_LANGUAGE" />로 되어 있습니다. <ph name="TARGET_LANGUAGE" />로 번역하시겠습니까?</translation>
<translation id="8035152190676905274">펜</translation>
+<translation id="8037117624646282037">최근에 기기를 사용한 사용자</translation>
<translation id="8037357227543935929">요청(기본값)</translation>
<translation id="803771048473350947">파일</translation>
<translation id="8041089156583427627">의견 보내기</translation>
<translation id="8041940743680923270">전체 기본값 사용(요청)</translation>
<translation id="8042918947222776840">수령 방법 선택</translation>
<translation id="8057711352706143257">'<ph name="SOFTWARE_NAME" />이(가) 올바르게 설정되지 않았습니다. 일반적으로 '<ph name="SOFTWARE_NAME" />'을(를) 제거하면 문제가 해결됩니다. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">기기가 다음과 같이 구성되었습니다.</translation>
+<translation id="8066955247577885446">문제 발생</translation>
+<translation id="8074253406171541171">10x13(봉투)</translation>
<translation id="8078141288243656252">회전 시 주석을 달 수 없습니다.</translation>
<translation id="8079031581361219619">사이트를 새로고침하시겠습니까?</translation>
<translation id="8088680233425245692">글을 조회하지 못했습니다.</translation>
@@ -1130,11 +1283,12 @@
<translation id="8091372947890762290">활성화 요청이 서버에서 대기 중</translation>
<translation id="8092774999298748321">짙은 보라색</translation>
<translation id="8094917007353911263">사용 중인 네트워크에서 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> 방문을 요청할 수 있습니다.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">유효하지 않은 카드가 삭제되었습니다.</translation>
<translation id="8103161714697287722">결제 수단</translation>
<translation id="8118489163946903409">결제 수단</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> 기기는 <ph name="ENROLLMENT_DOMAIN" />에서 관리하는 기기입니다</translation>
<translation id="8127301229239896662">'<ph name="SOFTWARE_NAME" />'이(가) 컴퓨터 또는 네트워크에 제대로 설치되지 않았습니다. IT 관리자에게 문제 해결을 요청해 보세요.</translation>
-<translation id="8130693978878176684">더 이상 도와드릴 수 없습니다. 직접 계속해 주세요.</translation>
<translation id="8131740175452115882">확인</translation>
<translation id="8149426793427495338">컴퓨터가 절전 모드 상태입니다.</translation>
<translation id="8150722005171944719"><ph name="URL" />의 파일을 읽을 수 없습니다. 삭제 또는 이동되었거나 파일 사용 권한이 액세스를 차단할 수도 있습니다.</translation>
@@ -1144,8 +1298,11 @@
<translation id="8197543752516192074">페이지 번역</translation>
<translation id="8201077131113104583">ID가 '<ph name="EXTENSION_ID" />'인 확장 프로그램에 대한 잘못된 업데이트 URL</translation>
<translation id="8202097416529803614">주문 요약</translation>
+<translation id="8202370299023114387">충돌</translation>
+<translation id="8206978196348664717">Prc4(봉투)</translation>
<translation id="8211406090763984747">이 사이트는 보안 연결(HTTPS)이 사용되었습니다.</translation>
<translation id="8218327578424803826">지정된 위치:</translation>
+<translation id="8220146938470311105">C7/C6(봉투)</translation>
<translation id="8225771182978767009">컴퓨터를 설정한 사용자가 이 사이트를 차단했습니다.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">새 시크릿 창에서 페이지 열기</translation>
@@ -1157,14 +1314,16 @@
<translation id="825929999321470778">저장된 비밀번호 모두 표시</translation>
<translation id="8261506727792406068">삭제</translation>
<translation id="8267698848189296333"><ph name="USERNAME" />(으)로 로그인</translation>
+<translation id="8278457561961988242">이 브라우저는 <ph name="ENROLLMENT_DOMAIN" />에서 관리합니다. 관리자가 브라우저 설정을 원격으로 변경할 수 있습니다. 이 기기의 활동은 Chrome 외부에서 관리될 수도 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">로그인</translation>
<translation id="8288807391153049143">인증서 표시</translation>
<translation id="8289355894181816810">잘 모르는 경우 네트워크 관리자에게 문의하시기 바랍니다.</translation>
<translation id="8293206222192510085">북마크 추가</translation>
<translation id="8294431847097064396">출처</translation>
<translation id="8298115750975731693">사용 중인 Wi-Fi(<ph name="WIFI_NAME" />)에서 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> 방문을 요청할 수 있습니다.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">네트워크 연결 문제로 인해 번역에 실패했습니다.</translation>
-<translation id="8311129316111205805">세션 로드</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" />에 대한 액세스가 거부됨</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_YEAR" />/<ph name="EXPIRATION_MONTH" /></translation>
<translation id="834457929814110454">보안 관련 위험을 이해한다면 악성 프로그램이 삭제되기 전에 <ph name="BEGIN_LINK" />이 사이트를 방문<ph name="END_LINK" />해도 됩니다.</translation>
@@ -1182,7 +1341,6 @@
<translation id="8416694386774425977">네트워크 설정이 잘못되어 가져올 수 없습니다.
추가 세부정보:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" />에서 관리하는 기기</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">변경</translation>
<translation id="8428213095426709021">설정</translation>
@@ -1209,9 +1367,11 @@
<translation id="860043288473659153">카드 명의자 이름</translation>
<translation id="861775596732816396">크기 4</translation>
<translation id="8620436878122366504">부모님이 아직 승인하지 않았습니다.</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">이 기기에 카드 저장</translation>
<translation id="8663226718884576429">주문 요약, <ph name="TOTAL_LABEL" />, 세부정보 더보기</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, 답변, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" />로의 연결은 암호화되지 않습니다.</translation>
<translation id="8718314106902482036">결제가 완료되지 않음</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, 추천 검색어</translation>
@@ -1225,6 +1385,7 @@
<translation id="8761567432415473239">Google 세이프 브라우징 결과 <ph name="SITE" />에서 최근 <ph name="BEGIN_LINK" />악성 프로그램이 발견<ph name="END_LINK" />되었습니다.</translation>
<translation id="8763927697961133303">USB 기기</translation>
<translation id="8768895707659403558">어느 기기에서나 카드를 사용하려면 <ph name="SIGN_IN_LINK" />하세요.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">삭제 다시 실행(&amp;R)</translation>
<translation id="8792621596287649091"><ph name="ORG_NAME" /> 계정에 액세스할 수 없게 되거나 신원 도용이 발생할 수도 있습니다. 따라서 지금 비밀번호를 변경하는 것이 좋습니다.</translation>
<translation id="8800988563907321413">근처 추천 항목이 여기에 표시됩니다.</translation>
@@ -1235,10 +1396,12 @@
<translation id="885730110891505394">Google과 공유</translation>
<translation id="8858065207712248076">다른 사이트에서 비밀번호를 재사용했다면 <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> 비밀번호를 재설정하는 것이 좋습니다.</translation>
<translation id="8866481888320382733">정책 설정을 파싱하는 중 오류 발생</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">최근에 닫은 탭</translation>
<translation id="8874824191258364635">올바른 카드 번호를 입력하세요.</translation>
<translation id="8891727572606052622">프록시 모드가 잘못되었습니다.</translation>
<translation id="8903921497873541725">확대</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">이 카드를 Google 계정에 저장하시겠습니까?</translation>
<translation id="8932102934695377596">시간이 너무 먼 과거로 설정되어 있습니다.</translation>
<translation id="893332455753468063">이름 추가</translation>
@@ -1246,13 +1409,13 @@
<translation id="894185898663964645">관리자가 맞춤 루트 인증서를 구성했으며, 이로 인해 관리자가 내가 방문하는 웹사이트의 콘텐츠를 볼 수 있습니다.</translation>
<translation id="8943282376843390568">라임색</translation>
<translation id="8957210676456822347">캡티브 포털 승인</translation>
+<translation id="8966619695390250636">이 URL을 찾으셨나요?</translation>
<translation id="8968766641738584599">카드 저장</translation>
<translation id="8971063699422889582">서버 인증서가 만료되었습니다.</translation>
<translation id="8975012916872825179">전화번호, 이메일 주소, 배송지 주소 등의 정보를 포함합니다.</translation>
<translation id="8978053250194585037">Google 세이프 브라우징이 최근 <ph name="SITE" />에서 <ph name="BEGIN_LINK" />피싱을 감지<ph name="END_LINK" />했습니다. 피싱 사이트는 사용자를 속이기 위해 다른 웹사이트인 것처럼 가장합니다.</translation>
<translation id="8983003182662520383">Google Pay에 사용되는 결제 수단 및 주소</translation>
<translation id="8987927404178983737">월</translation>
-<translation id="8988408250700415532">문제가 발생했습니다. 웹사이트에서 주문을 완료할 수 있습니다.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">방문하려는 사이트에 유해한 프로그램이 있습니다.</translation>
<translation id="8997023839087525404">서버에서 인증서 투명성 정책을 사용하여 공개되지 않은 인증서를 제시했습니다. 인증서 투명성 정책은 인증서가 신뢰할 수 있으며 공격자로부터 사용자를 보호하고 있음을 보장하기 위한 것으로 일부 인증서의 경우 필수사항입니다.</translation>
@@ -1262,6 +1425,7 @@
<translation id="9011424611726486705">사이트 설정 열기</translation>
<translation id="9020200922353704812">카드 청구서 수신 주소가 필요함</translation>
<translation id="9020542370529661692">이 페이지는 <ph name="TARGET_LANGUAGE" />로 번역되었습니다.</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(유효하지 않음)</translation>
<translation id="9035022520814077154">보안 오류</translation>
<translation id="9038649477754266430">빠른 페이지 로드를 위해 예상 검색어 서비스 사용</translation>
@@ -1273,11 +1437,11 @@
<translation id="9065745800631924235">검색기록에서 <ph name="TEXT" /> 검색</translation>
<translation id="9069693763241529744">확장 프로그램에서 차단함</translation>
<translation id="9076283476770535406">성인용 콘텐츠가 포함되어 있을 수 있습니다.</translation>
+<translation id="9076630408993835509">이 브라우저는 회사 또는 다른 조직에서 관리하지 않습니다. 이 기기의 활동은 Chrome 외부에서 관리될 수 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">자세한 정보 필요</translation>
<translation id="9080712759204168376">주문 요약</translation>
<translation id="9103872766612412690"><ph name="SITE" />에서는 사용자 정보를 보호하기 위해 일반적으로 암호화를 사용합니다. 이번에 Chromium에서 <ph name="SITE" />에 연결을 시도했을 때 웹사이트에서 비정상적이고 잘못된 사용자 인증 정보를 반환했습니다. 이는 공격자가 <ph name="SITE" />인 것처럼 가장하려고 하거나 Wi-Fi 로그인 화면이 연결을 방해했기 때문일 수 있습니다. 데이터 교환이 발생하기 전에 Chromium에서 연결을 중단했으므로 사용자 정보는 안전합니다.</translation>
<translation id="9106062320799175032">청구서 주소 추가</translation>
-<translation id="9110718169272311511">화면 하단에서 Chrome의 Google 어시스턴트를 사용할 수 있습니다.</translation>
<translation id="9114524666733003316">카드 확인 중...</translation>
<translation id="9128870381267983090">네트워크에 연결</translation>
<translation id="9137013805542155359">원본 보기</translation>
@@ -1286,6 +1450,7 @@
<translation id="9148507642005240123">수정 실행 취소(&amp;U)</translation>
<translation id="9154194610265714752">업데이트됨</translation>
<translation id="9157595877708044936">설정 중...</translation>
+<translation id="9158625974267017556">C6(봉투)</translation>
<translation id="9168814207360376865">사이트에서 저장된 결제 수단이 있는지 확인하도록 허용</translation>
<translation id="9169664750068251925">이 사이트에서 항상 차단</translation>
<translation id="9170848237812810038">실행 취소(&amp;U)</translation>
@@ -1300,10 +1465,12 @@
<translation id="9219103736887031265">이미지</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">양식 지우기</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Google 계정에 액세스하지 못할 수 있습니다. 따라서 지금 비밀번호를 변경하는 것이 좋습니다. 로그인하라는 메시지가 표시됩니다.</translation>
<translation id="939736085109172342">새 폴더</translation>
<translation id="945855313015696284">아래 정보를 확인하고 잘못된 카드를 삭제하세요.</translation>
<translation id="951104842009476243">사용 가능한 직불카드 및 선불카드</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" />의 보안 정책에 따라 차단되었습니다</translation>
<translation id="962484866189421427">이 콘텐츠에서 다른 앱인 것처럼 가장하거나 사용자를 추적하는 데 사용될 수 있는 데이터를 수집하는 사기성 앱을 설치할 수도 있습니다. <ph name="BEGIN_LINK" />그래도 표시하기<ph name="END_LINK" /></translation>
<translation id="969892804517981540">공식 빌드</translation>
<translation id="973773823069644502">배달 주소 추가</translation>
@@ -1312,6 +1479,7 @@
<translation id="984275831282074731">결제 수단</translation>
<translation id="985199708454569384">&lt;p&gt;컴퓨터나 휴대기기의 날짜 및 시간이 잘못 설정되어 있는 경우 이 오류가 표시됩니다.&lt;/p&gt;
&lt;p&gt;오류를 수정하려면 기기의 시계를 열고 날짜 및 시간이 올바른지 확인하세요.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">개발자 빌드</translation>
<translation id="989988560359834682">주소 수정</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_lt.xtb b/chromium/components/strings/components_strings_lt.xtb
index 061fe7b86b6..6d92c3161ee 100644
--- a/chromium/components/strings/components_strings_lt.xtb
+++ b/chromium/components/strings/components_strings_lt.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lt">
-<translation id="1005145902654145231">Nepavyko pervardyti sesijos.</translation>
<translation id="1008557486741366299">Ne dabar</translation>
<translation id="1010200102790553230">Įkelti puslapį vėliau</translation>
<translation id="1015730422737071372">Pateikti papildomos išsamios informacijos</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nežinomas pavadinimas</translation>
<translation id="1050038467049342496">Uždarykite kitas programas</translation>
<translation id="1055184225775184556">&amp;Anuliuoti pridėjimą</translation>
+<translation id="1056898198331236512">Įspėjimas</translation>
<translation id="1058479211578257048">Išsaugomos kortelės...</translation>
<translation id="10614374240317010">Niekada neišsaugota</translation>
+<translation id="1062160989074299343">„Prc10“ (vokas)</translation>
<translation id="106701514854093668">Žymės staliniame kompiuteryje</translation>
<translation id="1074497978438210769">Nesaugi</translation>
<translation id="1080116354587839789">Pritaikyti pagal plotį</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Kortelėje nurodytų vardo ir pavardės pridėjimas</translation>
<translation id="1089439967362294234">Slaptažodžio keitimas</translation>
<translation id="109743633954054152">Tvarkyti slaptažodžius „Chrome“ nustatymuose</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Kol atnaujinami svetainių saugos nustatymai, gali būti dažnai rodomi įspėjimai. Netrukus tai turėtų būti išspręsta.</translation>
<translation id="1126551341858583091">Dydis vietinėje saugykloje yra <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Gera politikos talpykla</translation>
+<translation id="1131264053432022307">Nukopijuotas vaizdas</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Pervadinti</translation>
<translation id="1175364870820465910">&amp;Spausdinti...</translation>
<translation id="1181037720776840403">Pašalinti</translation>
<translation id="1197088940767939838">Oranžinė</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Įrenginio pavadinimas</translation>
<translation id="124116460088058876">Daugiau kalbų</translation>
<translation id="1250759482327835220">Kad kitą kartą galėtumėte greičiau atlikti mokėjimą, išsaugokite kortelę, vardą bei pavardę ir atsiskaitymo adresą „Google“ paskyroje.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinchronizuota)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Komandos eilutės kintamieji</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="1314614906530272393">Pasirinktos sesijos nėra.</translation>
+<translation id="1320233736580025032">„Prc1“ (vokas)</translation>
+<translation id="132301787627749051">Ieškoti iškarpinės vaizdo</translation>
<translation id="1323433172918577554">Rodyti daugiau</translation>
<translation id="132390688737681464">Išsaugoti ir užpildyti adresus</translation>
<translation id="1333989956347591814">Veiklą <ph name="BEGIN_EMPHASIS" />vis tiek gali peržiūrėti<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Paėmimo adresas</translation>
<translation id="1348198688976932919">Pateiktoje svetainėje yra pavojingų programų</translation>
<translation id="1348779747280417563">Pavadinimo patvirtinimas</translation>
+<translation id="1357195169723583938">Kas ir kada neseniai naudojo įrenginį</translation>
+<translation id="1364822246244961190">Ši politika blokuojama, jos vertės bus nepaisoma.</translation>
<translation id="1374468813861204354">pasiūlymai</translation>
+<translation id="1374692235857187091">„Index-4x6“ (atvirukas)</translation>
<translation id="1375198122581997741">Apie versiją</translation>
<translation id="1376836354785490390">Rodyti mažiau</translation>
<translation id="1377321085342047638">Kort. Nr.</translation>
<translation id="138218114945450791">Šviesiai mėlyna</translation>
+<translation id="1382194467192730611">USB įrenginį leidžia administratorius</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> neišsiuntė jokių duomenų.</translation>
+<translation id="140316286225361634">Svetainė <ph name="ORIGIN" /> pateikė užklausą saugos politiką
+ taikyti visai jos užklausai, o pagal šią politiką šiuo metu manoma, kad svetainė
+ nesaugi.</translation>
<translation id="1405567553485452995">Šviesiai žalia</translation>
<translation id="1407135791313364759">Atidaryti viską</translation>
<translation id="1413809658975081374">Privatumo klaida</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Taip</translation>
<translation id="1430915738399379752">Spausdinti</translation>
<translation id="1455413310270022028">Trintukas</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Rodyti daugiau</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Pasirinkti pristatymo adresą</translation>
+<translation id="1492194039220927094">Politikos gavimas:</translation>
<translation id="1501859676467574491">Rodyti korteles iš „Google“ paskyros</translation>
-<translation id="1506687042165942984">Rodyti išsaugotą šio puslapio kopiją (kuri yra pasenusi).</translation>
<translation id="1507202001669085618">&lt;p&gt;Ši klaida rodoma, jei naudojate „Wi-Fi“ portalą, prie kurio reikia prisijungti, kad galėtumėte naudotis internetu.&lt;/p&gt;
&lt;p&gt;Kad ištaisytumėte šią klaidą, puslapyje, kurį bandote atidaryti, spustelėkite &lt;strong&gt;Prisijungti&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Būtinas telefono numeris</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Sukūrimo data</translation>
<translation id="1521655867290435174">„Google“ skaičiuoklės</translation>
<translation id="1527263332363067270">Laukiama ryšio…</translation>
+<translation id="1529521330346880926">10 x 15 (vokas)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Šiame puslapyje nurodyta:</translation>
<translation id="153384715582417236">Kol kas tiek</translation>
<translation id="154408704832528245">Pasirinkti pristatymo adresą</translation>
<translation id="1549470594296187301">Norint naudoti šią funkciją, reikia įgalinti „JavaScript“.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Įveskite galiojimo laiko pabaigos datą</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Nukopijuotas vaizdas</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Neleisti šiam puslapiui kurti papildomų dialogo langų</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Baigti sesiją</translation>
<translation id="1639239467298939599">Įkeliama</translation>
<translation id="1640180200866533862">Naudotojo politika</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Serverio sertifikate yra nesudėtingas kriptografinis raktas.</translation>
<translation id="1697532407822776718">Viskas nustatyta!</translation>
+<translation id="1703835215927279855">Laiškas</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokumentas per didelis, kad būtų galima komentuoti</translation>
<translation id="1721312023322545264">Turite gauti <ph name="NAME" /> leidimą apsilankyti šioje svetainėje</translation>
<translation id="1721424275792716183">* Būtina užpildyti lauką</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Pabandykite susisiekti su sistemos administratoriumi.</translation>
<translation id="1740951997222943430">Įveskite tinkamą galiojimo laiko pabaigos mėnesį</translation>
<translation id="1743520634839655729">Kad kitą kartą galėtumėte greičiau atlikti mokėjimą, išsaugokite kortelę, vardą bei pavardę ir atsiskaitymo adresą „Google“ paskyroje ir šiame įrenginyje.</translation>
+<translation id="1745880797583122200">Jūsų naršyklė tvarkoma</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Atnaujinkite sinchronizavimo slaptafrazę.</translation>
<translation id="1787142507584202372">Atidaryti skirtukai bus rodomi čia</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kortelės savininko vardas</translation>
<translation id="1821930232296380041">Netinkama užklausa arba jos parametrai</translation>
+<translation id="1822540298136254167">Svetainės, kuriose lankotės, ir jose praleidžiamas laikas</translation>
<translation id="1826516787628120939">Tikrinama</translation>
<translation id="1834321415901700177">Šioje svetainėje yra kenkėjiškų programų</translation>
<translation id="1839551713262164453">Nepavyko patvirtinti politikos verčių (rasta klaidų)</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Išvalyti „Chrome“ naršymo istorijos duomenis</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ir dar 1}one{ir dar #}few{ir dar #}many{ir dar #}other{ir dar #}}</translation>
<translation id="2003709556000175978">Nustatykite slaptažodį iš naujo dabar</translation>
+<translation id="20053308747750172">Serveris, į kurį esate nukreipiami (<ph name="ORIGIN" />), pateikė užklausą
+ taikyti saugos politiką visoms jam teikiamoms užklausoms. Bet dabar
+ pateikta netinkama politika, dėl kurios naršyklei neleidžiama
+ vykdyti svetainės <ph name="SITE" /> užklausos.</translation>
<translation id="2025186561304664664">Nustatytas automatinis įgaliotojo serverio konfigūravimas.</translation>
<translation id="2030481566774242610">Ar turėjote omenyje <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Patikrinti tarpinį serverį ir užkardą<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departamentas</translation>
<translation id="2102134110707549001">Siūlyti sudėtingą slaptažodį…</translation>
<translation id="2108755909498034140">Iš naujo paleiskite kompiuterį</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kortelė</translation>
<translation id="2114841414352855701">Nepaisoma, nes buvo pakeista taikant „<ph name="POLICY_NAME" />“.</translation>
<translation id="213826338245044447">Žymės mobiliesiems</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">„Kaku2“ (vokas)</translation>
<translation id="2181821976797666341">Politika</translation>
<translation id="2183608646556468874">Telefono numeris</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresas}one{# adresas}few{# adresai}many{# adreso}other{# adresų}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefono numeris</translation>
<translation id="2283340219607151381">Išsaugoti ir užpildyti adresus</translation>
<translation id="2292556288342944218">Interneto prieiga užblokuota</translation>
+<translation id="2294558542833290837">Pradinė atidaryta nuoroda neįprasta</translation>
+<translation id="2297722699537546652">B5 (vokas)</translation>
+<translation id="2310021320168182093">„Chou2“ (vokas)</translation>
<translation id="2316887270356262533">Atlaisvina mažiau nei 1 MB. Per kitą jūsų apsilankymą kai kurios svetainės gali būti įkeliamos lėčiau.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> būtina įvesti naudotojo vardą ir slaptažodį.</translation>
<translation id="2317583587496011522">Debeto kortelės tinkamos.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, baigia galioti <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Nustatymą valdo administratorius</translation>
+<translation id="2346319942568447007">Nukopijuotas vaizdas</translation>
<translation id="2349790679044093737">VR sesija aktyvi</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> užfiksuota strigčių ataskaita nebuvo įkelta</translation>
<translation id="2367567093518048410">Lygis</translation>
<translation id="2378238891085281592">Įjungėte privatų režimą</translation>
+<translation id="2380886658946992094">Teisinis</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="2410754574180102685">Government-Legal</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="2418081434543109369">Serveris, į kurį esate nukreipiami (<ph name="ORIGIN" />), pateikė užklausą
+ taikyti saugos politiką visoms jam teikiamoms užklausoms. Bet dabar jam
+ nepavyko pateikti politikos, neleidžiančios naršyklei vykdyti
+ svetainės <ph name="SITE" /> užklausos.</translation>
<translation id="244665789865330679">Jūsų įrenginį ir paskyrą tvarko <ph name="ENROLLMENT_DOMAIN" />. Tai reiškia, kad administratorius gali nuotoliniu būdu juos konfigūruoti.</translation>
<translation id="2463193859425327265">Keisti pagrindinį puslapį</translation>
<translation id="2463739503403862330">Užpildyti</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Pasirinkti pristatymo metodą</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Paleistas įrankis „Windows Network Diagnostics“<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Išversti šį puslapį</translation>
<translation id="2479410451996844060">Netinkamas paieškos URL.</translation>
<translation id="2482878487686419369">Pranešimai</translation>
<translation id="248348093745724435">Įrenginio politikos</translation>
+<translation id="2485387744899240041">Jūsų įrenginio ir naršyklės naudotojo vardai</translation>
<translation id="2491120439723279231">Serverio sertifikate yra klaidų.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Nuskaityti naują kortelę</translation>
<translation id="2501278716633472235">Grįžti</translation>
<translation id="2503184589641749290">Tinkamos debeto ir išankstinio mokėjimo kortelės</translation>
<translation id="2515629240566999685">Patikrinti signalo stiprumą savo srityje</translation>
-<translation id="2516852381693169964">Ieškoti vaizdo sistemoje „<ph name="SEARCH_ENGINE" />“</translation>
<translation id="2523886232349826891">Išsaugota tik šiame įrenginyje</translation>
<translation id="2524461107774643265">Daugiau informacijos pridėjimas</translation>
<translation id="2536110899380797252">Pridėti adresą</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (vokas)</translation>
<translation id="2625385379895617796">Jūsų laikrodis skuba</translation>
<translation id="2634124572758952069">Nepavyko rasti <ph name="HOST_NAME" /> serverio IP adreso.</translation>
<translation id="2639739919103226564">Būsena:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Uždarykite kitus skirtukus arba programas</translation>
<translation id="267371737713284912">paspauskite <ph name="MODIFIER_KEY_DESCRIPTION" />, kad anuliuotumėte</translation>
<translation id="2674170444375937751">Ar tikrai norite pašalinti šiuos puslapius iš savo istorijos?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Išeiti</translation>
+<translation id="2684561033061424857">11 x 12</translation>
<translation id="2699302886720511147">Tinkamos kortelės</translation>
<translation id="2702801445560668637">Skait. sąraš.</translation>
<translation id="2704283930420550640">Vertė neatitinka formato.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Pašalinti pasirinktus elementus</translation>
<translation id="277133753123645258">Pristatymo metodas</translation>
<translation id="277499241957683684">Trūksta įrenginio įrašo</translation>
-<translation id="2781030394888168909">Eksportuoti „Mac“ OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Ryšys atkurtas.</translation>
<translation id="2788784517760473862">Tinkamos kredito kortelės</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Atidaryti inkognito langą</translation>
+<translation id="2850739647070081192">„Invite“ (vokas)</translation>
<translation id="2851634818064021665">Jums reikalingas leidimas, kad galėtumėte apsilankykite šioje svetainėje</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Išsaugoti kortelę?</translation>
<translation id="2903493209154104877">Adresai</translation>
<translation id="290376772003165898">Puslapis parašytas ne <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Pristatymo metodas</translation>
<translation id="2928905813689894207">Atsiskaitymo adresas</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Oficialus laiškas</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">„You4“ (vokas)</translation>
<translation id="3024663005179499861">Netinkamas politikos tipas</translation>
<translation id="3037605927509011580">Oi!</translation>
<translation id="3041612393474885105">Sertifikato informacija</translation>
+<translation id="3060227939791841287">C9 (vokas)</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="3095940652251934233">Ataskaita</translation>
<translation id="3096100844101284527">Pridėti paėmimo adresą</translation>
<translation id="3105172416063519923">Ištekliaus ID:</translation>
<translation id="3109728660330352905">Neturite prieigos teisės žiūrėti šį puslapį.</translation>
@@ -365,20 +413,21 @@
<translation id="3195213714973468956">„<ph name="PRINTER_NAME" />“ serveryje „<ph name="SERVER_NAME" />“</translation>
<translation id="320323717674993345">Atšaukti mokėjimą</translation>
<translation id="3207960819495026254">Pažymėta</translation>
-<translation id="3209375525920864198">Įveskite tinkamą sesijos pavadinimą.</translation>
+<translation id="321912867715453276">Įspėjimas: pateiktas daugiau nei vienas politikos šaltinis, bet vertės vienodos.</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="3229041911291329567">Įrenginio ir naršyklės versijos informacija</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Ant kortelės pateikto vardo pridėjimas</translation>
<translation id="3287510313208355388">Atsisiųsti prisijungus</translation>
<translation id="3293642807462928945">Sužinokite daugiau apie „<ph name="POLICY_NAME" />“ politiką</translation>
<translation id="3303855915957856445">Nerasta jokių paieškos rezultatų</translation>
-<translation id="3305707030755673451"><ph name="TIME" /> duomenys buvo užšifruoti naudojant sinchronizavimo slaptafrazę. Įveskite ją, kad pradėtumėte sinchronizuoti.</translation>
<translation id="3320021301628644560">Atsiskaitymo adreso pridėjimas</translation>
<translation id="3324983252691184275">Tamsiai raudona</translation>
<translation id="3338095232262050444">Saugi</translation>
@@ -406,9 +455,11 @@
<translation id="3427342743765426898">&amp;Redaguoti dar kartą</translation>
<translation id="342781501876943858">„Chromium“ rekomenduoja iš naujo nustatyti slaptažodį, jei naudojate jį kitose svetainėse.</translation>
<translation id="3431636764301398940">Išsaugoti šią kortelę šiame įrenginyje</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Įrenginio savininkas išjungė dinozauro žaidimą.</translation>
<translation id="3447884698081792621">Rodyti sertifikatą (išdavė „<ph name="ISSUER" />“)</translation>
<translation id="3452404311384756672">Gauti intervalą:</translation>
+<translation id="3456231139987291353">„Number-11“ (vokas)</translation>
<translation id="3461824795358126837">Paryškinimo žymeklis</translation>
<translation id="3462200631372590220">Slėpti išsamią informaciją</translation>
<translation id="3467763166455606212">Būtina nurodyti kortelės savininko vardą ir pavardę</translation>
@@ -431,20 +482,23 @@
<translation id="358285529439630156">Kredito ir išankstinio mokėjimo kortelės tinkamos.</translation>
<translation id="3582930987043644930">Pridėti vardą</translation>
<translation id="3583757800736429874">&amp;Perkelti dar kartą</translation>
+<translation id="35866233670761917">Administratoriai nemato svetainių, kuriose lankotės, turinio</translation>
<translation id="3586931643579894722">Slėpti išsamią informaciją</translation>
+<translation id="3592413004129370115">„Italian“ (vokas)</translation>
<translation id="3600246354004376029">„<ph name="TITLE" />“, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Dydis: 2</translation>
<translation id="3615877443314183785">Įveskite tinkamą galiojimo laiko pabaigos datą</translation>
<translation id="36224234498066874">Išvalyti naršymo duomenis...</translation>
<translation id="362276910939193118">Rodyti visą istoriją</translation>
-<translation id="3623476034248543066">Rodyti vertę</translation>
<translation id="3630155396527302611">Jei ji nurodyta kaip programa, kuriai leidžiama pasiekti tinklą, pabandykite
ją pašalinti iš sąrašo ir vėl pridėti.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Tikrinimas sėkmingas</translation>
<translation id="3655670868607891010">Jei tai rodoma dažnai, išbandykite <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Peržiūrėtas ir pataisytas leidimas</translation>
<translation id="366077651725703012">Atnaujinti kredito kortelę</translation>
<translation id="3676592649209844519">Įrenginio ID:</translation>
+<translation id="3677008721441257057">Ar norėjote apsilankyti &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Nepavyko pasirašyti užklausos</translation>
<translation id="3678529606614285348">Atidarykite puslapį naujame inkognito lange („Ctrl“ – „Shift“ – N)</translation>
<translation id="3679803492151881375">Strigčių ataskaita užfiksuota <ph name="CRASH_TIME" />, įkelta <ph name="UPLOAD_TIME" /></translation>
@@ -452,13 +506,14 @@
<translation id="3704162925118123524">Naudojant šį tinklą gali būti prašoma apsilankyti prisijungimo puslapyje.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Įkeliama...</translation>
+<translation id="3709599264800900598">Nukopijuotas tekstas</translation>
<translation id="3712624925041724820">Licencijos baigėsi</translation>
<translation id="3714780639079136834">Įjungti mobiliojo ryšio duomenis arba „Wi-Fi“</translation>
<translation id="3715597595485130451">Prisijungimas prie „Wi-Fi“</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Patikrinti tarpinio serverio, užkardos ir DNS konfigūraciją<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Ši klaida galėjo įvykti dėl antivirusinės, užkardos ar žiniatinklio filtravimo programos arba tarpinio serverio programinės įrangos.</translation>
+<translation id="373042150751172459">B4 (vokas)</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="3745099705178523657">Kai patvirtinsite, „Google“ paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</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>
@@ -471,10 +526,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Galiojimo laikas baigiasi <ph name="EXPIRATION_MONTH" /> / <ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Dydis: 16</translation>
+<translation id="3797522431967816232">„Prc3“ (vokas)</translation>
<translation id="3807873520724684969">Žalingas turinys užblokuotas.</translation>
<translation id="3810973564298564668">Valdyti</translation>
<translation id="382518646247711829">Jei naudojate tarpinį serverį…</translation>
<translation id="3828924085048779000">Neleidžiama naudoti tuščios slaptafrazės.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> įdiegta papildomų funkcijų plėtinių. Naudojant plėtinius galima pasiekti kai kuriuos jūsų duomenis.</translation>
<translation id="385051799172605136">Atgal</translation>
<translation id="3858027520442213535">Atnaujinti datą ir laiką</translation>
<translation id="3884278016824448484">Nesuderinamas įrenginio identifikatorius</translation>
@@ -482,6 +539,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Visada klausti šioje svetainėje</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>
@@ -492,11 +550,13 @@
<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="3984550557525787191">Šis sesijos pavadinimas jau yra.</translation>
<translation id="3987940399970879459">Mažiau nei 1 MB</translation>
+<translation id="4008849406247176967">Įspėjimas: pateiktas daugiau nei vienas šios politikos šaltinis su nesuderinamomis vertėmis!</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="4030383055268325496">&amp;Anuliuoti pridėjimą</translation>
+<translation id="4032320456957708163">Jūsų naršyklę tvarko <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Raktas „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (vokas)</translation>
<translation id="4067947977115446013">Tinkamo adreso pridėjimas</translation>
<translation id="4072486802667267160">Apdorojant jūsų užsakymą įvyko klaida. Bandykite dar kartą.</translation>
<translation id="4075732493274867456">Kliento programa ir serveris nepalaiko įprasto SSL protokolo versijos ar šifruotojo programų komplekto.</translation>
@@ -516,10 +576,12 @@
<translation id="4159784952369912983">Violetinė</translation>
<translation id="4165986682804962316">Svetainės nustatymai</translation>
<translation id="4171400957073367226">Netinkamas patvirtinimo parašas</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Dar <ph name="ITEM_COUNT" /> elementas}one{Dar <ph name="ITEM_COUNT" /> elementas}few{Dar <ph name="ITEM_COUNT" /> elementai}many{Dar <ph name="ITEM_COUNT" /> elemento}other{Dar <ph name="ITEM_COUNT" /> elementų}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7 x 9 (vokas)</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="4221630205957821124">&lt;h4&gt;1 veiksmas: prisijunkite prie portalo&lt;/h4&gt;
@@ -551,58 +613,79 @@
<translation id="4277028893293644418">Iš naujo nustatyti slaptažodį</translation>
<translation id="4280429058323657511">, gal. pab. <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Ši kortelė išsaugota jūsų „Google“ paskyroje}one{Šios kortelės išsaugotos jūsų „Google“ paskyroje}few{Šios kortelės išsaugotos jūsų „Google“ paskyroje}many{Šios kortelės išsaugotos jūsų „Google“ paskyroje}other{Šios kortelės išsaugotos jūsų „Google“ paskyroje}}</translation>
+<translation id="42981349822642051">Išskleisti</translation>
+<translation id="4302965934281694568">„Chou3“ (vokas)</translation>
<translation id="4305817255990598646">Perjungti</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Užblokuoti (numatytoji parinktis)</translation>
+<translation id="4318566738941496689">Įrenginio pavadinimas ir tinklo adresas</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="4340982228985273705">Šis kompiuteris neaptinkamas kaip valdomas įmonės, todėl taikant politiką galima automatiškai įdiegti tik „Chrome“ internetinėje parduotuvėje priglobiamus plėtinius. „Chrome“ internetinės parduotuvės atnaujinimo URL yra „<ph name="CWS_UPDATE_URL" />“.</translation>
<translation id="4346197816712207223">Tinkamos kredito kortelės</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Tvarkyti mokėjimo metodus...</translation>
+<translation id="4367563149485757821">„Number-12“ (vokas)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefonas</translation>
<translation id="4406896451731180161">paieškos rezultatai</translation>
-<translation id="4406972042435603828">Administratorius įdiegė veiksmingų funkcijų plėtinių.</translation>
<translation id="4408413947728134509">Slapukai <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Paėmimo adresas</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="443121186588148776">Nuoseklusis prievadas</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> nepriėmė jūsų prisijungimo sertifikato arba prisijungimo sertifikatas nebuvo pateiktas.</translation>
<translation id="4434045419905280838">Iššok. langai ir peradresavimai</translation>
+<translation id="4435702339979719576">Atvirukas</translation>
<translation id="443673843213245140">Įgaliotojo serverio naudojimas neleidžiamas, bet nurodyta aiški įgaliotojo serverio konfigūracija.</translation>
<translation id="445100540951337728">Tinkamos debeto kortelės</translation>
+<translation id="4466881336512663640">Formos pakeitimai bus prarasti. Ar tikrai norite tęsti?</translation>
<translation id="4482953324121162758">Ši svetainė nebus verčiama.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Netinkamas URL. Tai turi būti įprastos schemos URL, pvz., http://example.com arba https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">„Chou4“ (vokas)</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="4517607026994743406">„Comm-10“ (vokas)</translation>
<translation id="4522570452068850558">Išsami informacija</translation>
<translation id="4524805452350978254">Tvarkyti korteles</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Pabandykite išjungti plėtinius.</translation>
+<translation id="4559332380232738994">10 x 11</translation>
<translation id="457875822857220463">Pristatymas</translation>
+<translation id="4579056131138995126">Asmeninis (vokas)</translation>
<translation id="4582204425268416675">Pašalinti kortelę</translation>
<translation id="4587425331216688090">Pašalinti adresą iš „Chrome“?</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="4597348597567598915">Dydis: 8</translation>
+<translation id="4600854749408232102">C6 / C5 (vokas)</translation>
<translation id="4646534391647090355">Eiti dabar</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="467809019005607715">„Google“ skaidrės</translation>
<translation id="4690462567478992370">Nebenaudoti negaliojančio sertifikato</translation>
+<translation id="4691835149146451662">„Architecture-A“ (vokas)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Ryšys nutrauktas</translation>
<translation id="471880041731876836">Neturite leidimo, kad galėtumėte apsilankykite šioje svetainėje</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Paleistas įrankis „Windows Network Diagnostics“<ph name="END_LINK" />.</translation>
<translation id="4726672564094551039">Iš naujo įkelti politiką</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">„Prc2“ (vokas)</translation>
<translation id="4736825316280949806">Iš naujo paleiskite „Chromium“</translation>
<translation id="473775607612524610">Atnaujinti</translation>
<translation id="4738601419177586157">„<ph name="TEXT" />“ paieškos pasiūlymas</translation>
<translation id="4742407542027196863">Tvarkyti slaptažodžius…</translation>
<translation id="4744603770635761495">Vykdomasis kelias</translation>
+<translation id="4746351372139058112">Pranešimai</translation>
<translation id="4750917950439032686">Į šią svetainę siunčiama informacija (pvz., slaptažodžiai arba kredito kortelių numeriai) yra privati.</translation>
<translation id="4756388243121344051">&amp;Istorija</translation>
<translation id="4758311279753947758">Pridėti kontaktinę informaciją</translation>
@@ -610,9 +693,9 @@
<translation id="4764776831041365478">Tinklalapis šiuo adresu <ph name="URL" /> gali laikinai neveikti arba visam laikui būti perkeltas kitu žiniatinklio adresu.</translation>
<translation id="4771973620359291008">Įvyko nežinoma klaida.</translation>
<translation id="4785689107224900852">Perjungti į šį skirtuką</translation>
-<translation id="4792143361752574037">Pasiekiant sesijos failus kilo problema. Išsaugojimo diske funkcija šiuo metu išjungta. Iš naujo įkelkite puslapį ir bandykite dar kartą.</translation>
<translation id="4798078619018708837">Jei norite atnaujinti išsamią kortelės informaciją, įveskite „<ph name="CREDIT_CARD" />“ galiojimo laiko pabaigos datą ir kortelės saugos kodą (CVC). Kai patvirtinsite, „Google“ paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
<translation id="4800132727771399293">Patikrinkite kortelės galiojimo pabaigos datą bei saugos kodą (CVC) ir bandykite dar kart</translation>
+<translation id="480334179571489655">Pradinės politikos klaida</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>
@@ -627,7 +710,6 @@
<translation id="4881695831933465202">Atidaryti</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>
@@ -636,15 +718,15 @@
<translation id="4943872375798546930">Rezultatų nėra</translation>
<translation id="4950898438188848926">Skirtuko perjungimo mygtukas. Paspauskite „Enter“, kad perjungtumėte į atidarytą skirtuką „<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />“</translation>
<translation id="495170559598752135">Veiksmai</translation>
-<translation id="495832697253704892">Plėtinių ataskaitų teikimas</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Išskleisti sąrašą</translation>
<translation id="4974590756084640048">Iš naujo įgalinti įspėjimus</translation>
+<translation id="4984339528288761049">„Prc5“ (vokas)</translation>
<translation id="4989163558385430922">Žr. viską</translation>
<translation id="4989809363548539747">Šis papildinys nepalaikomas</translation>
-<translation id="4996230189582812866">Ataskaitų teikimas</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="5014174725590676422">Rodomas „Google“ padėjėjo sistemoje „Chrome“ pirmosios paleisties ekranas</translation>
<translation id="5015510746216210676">Įrenginio pavadinimas:</translation>
+<translation id="5017554619425969104">Nukopijuotas tekstas</translation>
<translation id="5018422839182700155">Negalima atidaryti šio puslapio</translation>
<translation id="5019198164206649151">Bloga atsarginio atminties įrenginio būsena</translation>
<translation id="5023310440958281426">Patikrinkite savo administratoriaus politiką</translation>
@@ -654,35 +736,51 @@
<translation id="5034369478845443529">Vietinis kontekstas <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Leisti</translation>
<translation id="5040262127954254034">Privatumas</translation>
+<translation id="5043480802608081735">Nukopijuota nuoroda</translation>
<translation id="5045550434625856497">Neteisingas slaptažodis</translation>
<translation id="5056549851600133418">Jums skirti straipsniai</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Patikrinti tarpinio serverio adresą<ph name="END_LINK" /></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="5097099694988056070">Įrenginio statistika, pvz., centrinio procesoriaus / laisvosios prieigos atminties naudojimas</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Jūsų įrenginį tvarko <ph name="ENROLLMENT_DOMAIN" />, o jūsų paskyrą tvarko <ph name="ACCOUNT_DOMAIN" />. Tai reiškia, kad administratoriai gali nuotoliniu būdu sukonfigūruoti įrenginį ir paskyrą.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bitų)</translation>
-<translation id="5128122789703661928">Sesijos šiuo pavadinimu negalima ištrinti.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Tvarkyti adresus...</translation>
+<translation id="5138227688689900538">Rodyti mažiau</translation>
<translation id="5141240743006678641">Šifruoti sinchronizuotus slaptažodžius naudojant „Google“ prisijungimo duomenis</translation>
<translation id="5145883236150621069">Politikos atsakyme yra klaidos kodas</translation>
+<translation id="515292512908731282">C4 (vokas)</translation>
<translation id="5159010409087891077">Atidarykite puslapį naujame inkognito lange (⇧⌘N)</translation>
<translation id="516920405563544094">Įveskite „<ph name="CREDIT_CARD" />“ kortelės saugos kodą (CVC). Kai patvirtinsite, „Google“ paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation>
<translation id="5169827969064885044">Galite prarasti prieigą prie organizacijos paskyros arba gali būti pavogta tapatybė. „Chrome“ rekomenduoja pakeisti slaptažodį dabar.</translation>
<translation id="5171045022955879922">Ieškokite ar įveskite URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Įrenginys</translation>
<translation id="5179510805599951267">Ne <ph name="ORIGINAL_LANGUAGE" /> k.? Pranešti apie šią klaidą</translation>
<translation id="5190835502935405962">Žymių juosta</translation>
-<translation id="5200263511887412697">pateikti neseniai prisijungusių įrenginio naudotojų sąrašą</translation>
+<translation id="519422657042045905">Komentaras nepasiekiamas</translation>
<translation id="5201306358585911203">Šiame puslapyje įterptame puslapyje nurodyta:</translation>
<translation id="5205222826937269299">Būtina nurodyti pavadinimą</translation>
<translation id="5215116848420601511">„Google Pay“ naudojami mokėjimo metodai ir adresai</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Būtina nurodyti el. paštą</translation>
<translation id="5230733896359313003">Pristatymo adresas</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12 x 19</translation>
<translation id="5250209940322997802">„Prisijungimas prie tinklo“</translation>
<translation id="5251803541071282808">Debesis</translation>
+<translation id="5252000469029418751">C7 (vokas)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Tinklų adresai</translation>
<translation id="5285570108065881030">Rodyti visus išsaugotus slaptažodžius</translation>
<translation id="5287240709317226393">Rodyti slapukus</translation>
<translation id="5288108484102287882">Patvirtinant politikos vertes pateikta įspėjimų</translation>
@@ -694,7 +792,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> iš <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Pasirinkti kontaktinę informaciją</translation>
<translation id="5327248766486351172">Pavadinimas</translation>
+<translation id="5329858041417644019">Jūsų naršyklė nėra tvarkoma</translation>
<translation id="5332219387342487447">Pristatymo metodas</translation>
+<translation id="5334013548165032829">Išsamūs sistemos žurnalai</translation>
<translation id="5344579389779391559">Šiame puslapyje gali būti bandoma jus apmokestinti</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>
@@ -702,6 +802,7 @@
<translation id="5377026284221673050">„Laikrodis atsilieka“, „Laikrodis skuba“ arba „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;“</translation>
<translation id="5384855140246857529">Norėdami naudoti korteles visuose įrenginiuose, prisijunkite ir įjunkite sinchronizavimą.</translation>
<translation id="5386426401304769735">Šios svetainės sertifikatų grandinėje yra sertifikatas, pasirašytas naudojant SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -712,6 +813,7 @@
<translation id="5457113250005438886">Netinkama</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Redaguoti dar kartą</translation>
+<translation id="5478437291406423475">B6 / C4 (vokas)</translation>
<translation id="5481076368049295676">Š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="54817484435770891">Tinkamo adreso pridėjimas</translation>
<translation id="5490432419156082418">Adresai ir dar daugiau</translation>
@@ -719,10 +821,12 @@
<ph name="LINE_BREAK" />
Pabandykite susisiekti su sistemos administratoriumi.</translation>
<translation id="549333378215107354">Dydis: 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Tvarkomos žymės</translation>
<translation id="5510766032865166053">Galbūt jis perkeltas arba ištrintas.</translation>
<translation id="5523118979700054094">Politikos pavadinimas</translation>
<translation id="552553974213252141">Ar tekstas tinkamai ištrauktas?</translation>
+<translation id="553484882784876924">„Prc6“ (vokas)</translation>
<translation id="5540224163453853">Nepavyko rasti straipsnio, dėl kurio pateikta užklausa.</translation>
<translation id="5541546772353173584">El. pašto adreso pridėjimas</translation>
<translation id="5545756402275714221">Jums skirti straipsniai</translation>
@@ -737,15 +841,21 @@
<translation id="5595485650161345191">Adreso redagavimas</translation>
<translation id="5598944008576757369">Pasirinkti mokėjimo metodą</translation>
<translation id="560412284261940334">Tvarkymas nepalaikomas</translation>
+<translation id="5605670050355397069">Buhalterinis</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> buvote per daug kartų peradresuoti.</translation>
<translation id="5629630648637658800">Įkeliant politikos nustatymus įvyko klaida</translation>
<translation id="5631439013527180824">Netinkamas įrenginio tvarkymo prieigos raktas</translation>
+<translation id="5632627355679805402">Nuo <ph name="TIME" /> duomenys užšifruoti naudojant <ph name="BEGIN_LINK" />„Google“ slaptažodį<ph name="END_LINK" />. Įveskite jį, kad pradėtumėte sinchronizuoti.</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="563324245173044180">Klaidinantis turinys užblokuotas.</translation>
<translation id="5659593005791499971">El. paštas</translation>
+<translation id="5663614846592581799">9 x 11 (vokas)</translation>
+<translation id="5663955426505430495">Šio įrenginio administratorius įdiegė papildomų funkcijų plėtinių. Naudojant plėtinius galima pasiekti kai kuriuos jūsų duomenis.</translation>
<translation id="5675650730144413517">Šis puslapis neveikia</translation>
+<translation id="5684874026226664614">Oi, nepavyko išversti šio puslapio.</translation>
<translation id="5685654322157854305">Pridėti pristatymo adresą</translation>
<translation id="5689199277474810259">Eksportuoti kaip JSON</translation>
<translation id="5689516760719285838">Vieta</translation>
@@ -754,38 +864,39 @@
<translation id="5710435578057952990">Šio tinklalapio tapatybė nenustatyta.</translation>
<translation id="5719499550583120431">Išankstinio mokėjimo kortelės tinkamos.</translation>
<translation id="5720705177508910913">Dabartinis naudotojas</translation>
+<translation id="5728056243719941842">C5 (vokas)</translation>
<translation id="5730040223043577876">„Chrome“ rekomenduoja iš naujo nustatyti slaptažodį, jei naudojate jį kitose svetainėse.</translation>
<translation id="5732392974455271431">Jūsų tėvai gali atblokuoti ją už jus</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Išsaugokite kortelę „Google“ paskyroje}one{Išsaugokite korteles „Google“ paskyroje}few{Išsaugokite korteles „Google“ paskyroje}many{Išsaugokite korteles „Google“ paskyroje}other{Išsaugokite korteles „Google“ paskyroje}}</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="5770114862687765385">Panašu, kad failas sugadintas. Spustelėkite nustatymo iš naujo mygtuką ir nustatykite sesiją iš naujo.</translation>
<translation id="5778550464785688721">MIDI įrenginių visateisis valdymas</translation>
<translation id="578305955206182703">Gintaro spalva</translation>
<translation id="57838592816432529">Nutildyti</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>
+<translation id="5798290721819630480">Atmesti pakeitimus?</translation>
<translation id="5798683403665926540">Keisti pagrindinį puslapį „Chrome“ nustatymuose</translation>
<translation id="5803412860119678065">Ar norite, kad būtų įvesta <ph name="CARD_DETAIL" /> informacija?</translation>
<translation id="5804241973901381774">Leidimai</translation>
<translation id="5810442152076338065">Ryšys su <ph name="DOMAIN" /> užšifruotas naudojant pasenusį šifravimo paketą.</translation>
<translation id="5813119285467412249">&amp;Pridėti dar kartą</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="5860033963881614850">Išjungta</translation>
<translation id="5863847714970149516">Toliau pateiktame puslapyje gali būti bandoma jus apmokestinti</translation>
<translation id="5866257070973731571">Telefono numerio pridėjimas</translation>
<translation id="5869405914158311789">Nepavyksta pasiekti šios svetainės</translation>
<translation id="5869522115854928033">Išsaugoti slaptažodžiai</translation>
<translation id="5887400589839399685">Kortelė išsaugota</translation>
-<translation id="5893718151540690985">pateikti tinklo sąsajų su jų tipais ir aparatinės įrangos adresais, sąrašą</translation>
<translation id="5893752035575986141">Kredito kortelės tinkamos.</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="5916664084637901428">Įjungta</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Išsaugoti kortelę „Google“ paskyroje?</translation>
<translation id="5922853866070715753">Beveik atlikta</translation>
<translation id="5932224571077948991">Svetainėje rodomi nepageidaujami arba klaidinantys skelbimai</translation>
-<translation id="5939518447894949180">Nustatyti iš naujo</translation>
<translation id="5946937721014915347">Atidaroma „<ph name="SITE_NAME" />“…</translation>
<translation id="5951495562196540101">Nepavyko prisiregistruoti su kliento paskyra (galima įsigyti licencijos paketą).</translation>
<translation id="5967592137238574583">Kontaktinės informacijos redagavimas</translation>
@@ -793,6 +904,7 @@
<translation id="5975083100439434680">Tolinti</translation>
<translation id="5977489021191000276">Jūsų įrenginio netvarko administratorius.</translation>
<translation id="5977976211062815271">Šiame įrenginyje</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nepavyksta atidaryti mokėjimo programos</translation>
<translation id="5989320800837274978">Nenurodyti nei fiksuoti įgaliotieji serveriai, nei .pac scenarijaus URL.</translation>
<translation id="5990559369517809815">Plėtinys užblokavo serveriui teikiamas užklausas.</translation>
@@ -803,8 +915,8 @@
<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="6033927989869462158">pranešti aparatinės įrangos statistikos duomenis, pvz., centrinio procesoriaus / laisvosios prieigos atminties naudojimo duomenis</translation>
<translation id="6034000775414344507">Šviesiai pilka</translation>
+<translation id="6034283069659657473">10 x 14 (vokas)</translation>
<translation id="6039846035001940113">Jei problema išlieka, susisiekite su svetainės savininku.</translation>
<translation id="6040143037577758943">Uždaryti</translation>
<translation id="6044573915096792553">Dydis: 12</translation>
@@ -813,10 +925,10 @@
<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="6058977677006700226">Naudojate korteles visuose įrenginiuose?</translation>
<translation id="6059925163896151826">USB įrenginiai</translation>
-<translation id="6071091556643036997">Politikos tipas netinkamas.</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="6094273045989040137">Komentuoti</translation>
<translation id="610911394827799129">„Google“ paskyroje gali būti kito tipo naršymo istorijos, kuri pasiekiama adresu <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Informacija apie įdiegtus plėtinius ir papildinius</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>
@@ -851,15 +963,21 @@
<translation id="6337133576188860026">Atlaisvina mažiau nei <ph name="SIZE" />. Per kitą jūsų apsilankymą kai kurios svetainės gali būti įkeliamos lėčiau.</translation>
<translation id="6337534724793800597">Filtruoti politiką pagal pavadinimą</translation>
<translation id="6358450015545214790">Ką tai reiškia?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Galimi apmokestinimai.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{Dar 1 pasiūlymas}one{Dar # pasiūlymas}few{Dar # pasiūlymai}many{Dar # pasiūlymo}other{Dar # pasiūlymų}}</translation>
<translation id="6387754724289022810">Kad kitą kartą galėtumėte greičiau atlikti mokėjimą, išsaugokite kortelę ir atsiskaitymo adresą „Google“ paskyroje ir šiame įrenginyje.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Redaguoti žymę</translation>
+<translation id="6406765186087300643">C0 (vokas)</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="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="6434309073475700221">Atmesti</translation>
+<translation id="6446163441502663861">„Kahu“ (vokas)</translation>
<translation id="6446608382365791566">Daugiau informacijos pridėjimas</translation>
<translation id="6447842834002726250">Slapukai</translation>
<translation id="6451458296329894277">Patvirtinkite pakartotiną formos pateikimą</translation>
@@ -872,11 +990,17 @@
<translation id="6508722015517270189">Iš naujo paleiskite „Chrome“</translation>
<translation id="6529602333819889595">&amp;Ištrinti dar kartą</translation>
<translation id="6534179046333460208">Fizinio žiniatinklio pasiūlymai</translation>
+<translation id="6556866813142980365">Grąžinti</translation>
<translation id="6563469144985748109">Jūsų valdytojas dar jos nepatvirtino</translation>
<translation id="6569060085658103619">Peržiūrite plėtinio puslapį</translation>
+<translation id="6578796323535178455">C2 (vokas)</translation>
<translation id="6579990219486187401">Šviesiai rausva spalva</translation>
+<translation id="6583674473685352014">B6 (vokas)</translation>
+<translation id="6587923378399804057">Nukopijuota nuoroda</translation>
+<translation id="6591833882275308647">Jūsų „<ph name="DEVICE_TYPE" />“ netvarkomas</translation>
<translation id="6596325263575161958">Šifravimo parinktys</translation>
<translation id="6604181099783169992">Judesio arba šviesos jutikliai</translation>
+<translation id="6609880536175561541">„Prc7“ (vokas)</translation>
<translation id="6624427990725312378">Kontaktinė informacija</translation>
<translation id="6626291197371920147">Galiojančios kortelės numerio pridėjimas</translation>
<translation id="6628463337424475685">„<ph name="ENGINE" />“ paieška</translation>
@@ -885,6 +1009,7 @@
<translation id="6644283850729428850">Ši politika nepatvirtinta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nėra}=1{Iš 1 svetainės (nebūsite atjungti nuo „Google“ paskyros)}one{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}few{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}many{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}other{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}}</translation>
<translation id="6657585470893396449">Slaptažodis</translation>
+<translation id="6670613747977017428">Grįžti prie saugumo.</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>
@@ -892,12 +1017,15 @@
<translation id="671076103358959139">Registracijos prieigos raktas:</translation>
<translation id="6711464428925977395">Kažkas negerai su tarpiniu serveriu arba adresas netinkamas.</translation>
<translation id="6723740634201835758">„Google“ paskyroje</translation>
+<translation id="6738516213925468394"><ph name="TIME" /> duomenys buvo užšifruoti naudojant <ph name="BEGIN_LINK" />sinchronizavimo slaptafrazę<ph name="END_LINK" />. Įveskite ją, kad pradėtumėte sinchronizuoti.</translation>
<translation id="674375294223700098">Nežinoma serverio sertifikato klaida.</translation>
<translation id="6744009308914054259">Laukdami ryšio galite apsilankyti skiltyje „Atsisiuntimai“ ir perskaityti neprisijungus pasiekiamus straipsnius.</translation>
<translation id="6753269504797312559">Politikos vertė</translation>
<translation id="6757797048963528358">Įjungta įrenginio miego būsena.</translation>
+<translation id="6768213884286397650">„Hagaki“ (atvirukas)</translation>
<translation id="6778737459546443941">Jūsų tėtis ar mama dar jos nepatvirtino</translation>
<translation id="67862343314499040">Violetinė</translation>
+<translation id="6786747875388722282">Plėtiniai</translation>
<translation id="679355240208270552">Nepaisoma, nes numatytoji paieška neįgalinta pagal politiką.</translation>
<translation id="681021252041861472">Būtinas laukas</translation>
<translation id="6810899417690483278">Tinkinimo ID</translation>
@@ -930,10 +1058,12 @@
<translation id="6965978654500191972">Įrenginys</translation>
<translation id="6970216967273061347">Rajonas</translation>
<translation id="6973656660372572881">Nurodyti fiksuoti įgaliotieji serveriai ir .pac scenarijaus URL.</translation>
+<translation id="6973932557599545801">Deja, negaliu padėti, tolesnius veiksmus atlikite patys.</translation>
<translation id="6979158407327259162">„Google“ diskas</translation>
<translation id="6979440798594660689">Nutildyti (numatytasis)</translation>
<translation id="6984479912851154518">Išjungiate privatų režimą, kad galėtumėte sumokėti naudodami išorinę programą. Tęsti?</translation>
<translation id="6989763994942163495">Rodyti išplėstinius nustatymus...</translation>
+<translation id="6993898126790112050">6 x 9 (vokas)</translation>
<translation id="6996312675313362352">Visada versti <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Šie mokesčiai gali būti vienkartiniai arba pasikartojantys ir gali būti neaiškūs.</translation>
@@ -949,28 +1079,36 @@
<translation id="7108338896283013870">Slėpti</translation>
<translation id="7108819624672055576">Leidžiama pagal plėtinį</translation>
<translation id="7111012039238467737">(tinkamas)</translation>
+<translation id="7118618213916969306">Ieškoti iškarpinės URL, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">Uždarykite kitus skirtukus ir programas</translation>
<translation id="7129409597930077180">Negalima pristatyti šiuo adresu. Pasirinkite kitą adresą.</translation>
<translation id="7135130955892390533">Rodyti būseną</translation>
<translation id="7138472120740807366">Pristatymo metodas</translation>
<translation id="7139724024395191329">Emyratas</translation>
+<translation id="7152423860607593928">„Number-14“ (vokas)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Levandų spalva</translation>
-<translation id="7158980942472052083">Netinkamas URL. Tai turi būti įprastos schemos URL.</translation>
<translation id="717330890047184534">„Gaia“ ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Serveris, į kurį esate nukreipiami (<ph name="ORIGIN" />), pateikė užklausą
+ taikyti saugos politiką visoms jam teikiamoms užklausoms. Bet užuot
+ pateikęs politiką jis apribojo naršyklę kitoje vietoje, todėl
+ naršyklei neleidžiama vykdyti svetainės <ph name="SITE" /> užklausos.</translation>
<translation id="7179323680825933600">Išsaugoti ir užpildyti mokėjimo metodų informaciją</translation>
<translation id="7180611975245234373">Atnaujinti</translation>
<translation id="7182878459783632708">Nenustatyta jokia politika</translation>
<translation id="7186367841673660872">Šis puslapis išverstas iš<ph name="ORIGINAL_LANGUAGE" />į<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Atlaisvina <ph name="SIZE" />. Per kitą jūsų apsilankymą kai kurios svetainės gali būti įkeliamos lėčiau.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administratorius gali peržiūrėti:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> nesilaikoma saugos standartų.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /> apie šią problemą.</translation>
<translation id="7219179957768738017">Ryšiui naudojama <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Apdorojama</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Svetainėje, kurioje ketinate apsilankyti, yra kenkėjiškų programų</translation>
+<translation id="724766306220616965">Įspėjimai, prieštaravimas</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="7251437084390964440">Tinklo konfigūracija neatitinka ONC standarto. Kai kurių konfigūracijos dalių negalima importuoti.
Papildoma išsami informacija:
@@ -983,11 +1121,14 @@ Papildoma išsami informacija:
<translation id="7300012071106347854">Kobalto mėlyna</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />“</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="7313965965371928911"><ph name="BEGIN_LINK" />Saugaus naršymo<ph name="END_LINK" /> įspėjimai</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Su ryšiu susijusi pagalba</translation>
<translation id="7334320624316649418">&amp;Pertvarkyti dar kartą</translation>
<translation id="733923710415886693">Serverio sertifikatas nebuvo atskleistas taikant sertifikato skaidrumą.</translation>
+<translation id="734600844861828519">11 x 15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Komandos eilutė</translation>
-<translation id="7365061714576910172">Eksportuoti „Linux“ formatu</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>
@@ -995,6 +1136,7 @@ Papildoma išsami informacija:
<translation id="7381288752349550461">Valdomos sesijos nepaisymas</translation>
<translation id="7390545607259442187">Kortelės patvirtinimas</translation>
<translation id="7400418766976504921">URL adresas</translation>
+<translation id="7403591733719184120">Jūsų „<ph name="DEVICE_NAME" />“ tvarkomas</translation>
<translation id="7407424307057130981">&lt;p&gt;Ši klaida rodoma, jei „Windows“ kompiuteryje naudojate „Superfish“ programinę įrangą.&lt;/p&gt;
&lt;p&gt;Vadovaudamiesi toliau nurodytais veiksmais laikinai išjunkite programinę įrangą, kad galėtumėte naršyti žiniatinklyje. Reikės administratoriaus teisių.&lt;/p&gt;
&lt;ol&gt;
@@ -1005,7 +1147,7 @@ Papildoma išsami informacija:
&lt;li&gt;Spustelėkite &lt;strong&gt;Taikyti&lt;/strong&gt;, tada – &lt;strong&gt;Gerai&lt;/strong&gt;.
&lt;li&gt;Apsilankykite &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;„Chrome“ pagalbos centre&lt;/a&gt;, kad sužinotumėte, kaip visam laikui pašalinti programinę įrangą iš kompiuterio.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">„<ph name="PRODUCT_NAME" />“ tvarkymas</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Tvarkyti slaptažodžius…</translation>
<translation id="7419106976560586862">Profilio kelias</translation>
<translation id="7437289804838430631">Pridėti kontaktinę informaciją</translation>
@@ -1014,22 +1156,24 @@ Papildoma išsami informacija:
<translation id="7442725080345379071">Šviesiai oranžinė</translation>
<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="7449109375006139765">sistemos žurnalų siuntimas valdymo serveriui</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="7460618730930299168">Vaizdas ekrane skiriasi nuo to, ką pasirinkote. Tęsti?</translation>
<translation id="7473891865547856676">Ne, ačiū</translation>
-<translation id="7475525192983021547">pranešti apie laikotarpius, kai naudotojas naudoja įrenginį</translation>
<translation id="7481312909269577407">Persiųsti</translation>
<translation id="7485870689360869515">Nerasta jokių duomenų.</translation>
+<translation id="7498234416455752244">Toliau redaguoti</translation>
<translation id="7508255263130623398">Sugrąžinto politikos įrenginio ID nenurodytas arba neatitinka dabartinio įrenginio ID</translation>
<translation id="7508870219247277067">Avokado žalia</translation>
<translation id="7511955381719512146">Naudojant šį „Wi-Fi“ tinklą gali būti prašoma apsilankyti <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Atsisiųsti</translation>
<translation id="7518003948725431193">Nerasta nė vieno tinklalapio šiuo žiniatinklio adresu: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (vokas)</translation>
<translation id="7521387064766892559">„JavaScript“</translation>
<translation id="7526934274050461096">Jūsų ryšys su šia svetaine nėra privatus</translation>
+<translation id="7535087603100972091">Reikšmė</translation>
<translation id="7537536606612762813">Privaloma</translation>
+<translation id="7538364083937897561">A2 (vokas)</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>
@@ -1038,8 +1182,8 @@ Papildoma išsami informacija:
<translation id="7552846755917812628">Išbandykite toliau pateiktus patarimus.</translation>
<translation id="7554791636758816595">Naujas skirtukas</translation>
<translation id="7564049878696755256">Galite prarasti galimybę pasiekti „<ph name="ORG_NAME" />“ paskyrą arba gali būti pavogta tapatybė. „Chrome“ rekomenduoja pakeisti slaptažodį dabar.</translation>
-<translation id="7566125604157659769">Tekstas, kurį nukopijavote</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="7568105740864181217">Šią naršyklę tvarko įmonė, mokykla arba kita organizacija. Administratorius gali nuotoliniu būdu keisti naršyklės nustatymą. Veiklą šiame įrenginyje taip pat galima tvarkyti ne naršyklėje „Chrome“. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></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>
@@ -1050,6 +1194,7 @@ Papildoma išsami informacija:
<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="7633909222644580952">Našumo duomenys ir strigčių ataskaitos</translation>
<translation id="7637571805876720304">Pašalinti kredito kortelės informaciją iš „Chromium“?</translation>
<translation id="7639968568612851608">Tamsiai pilka</translation>
<translation id="765676359832457558">Slėpti išplėstinius nustatymus...</translation>
@@ -1059,9 +1204,11 @@ Papildoma išsami informacija:
<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="7676643023259824263">Ieškoti iškarpinės teksto „<ph name="TEXT" />“</translation>
<translation id="7681101578153515023">Keisti paieškos variklį</translation>
<translation id="7682287625158474539">Pristatymas</translation>
<translation id="7687186412095877299">Užpildomos mokėjimo formos naudojant išsaugotus mokėjimo metodus</translation>
+<translation id="7697066736081121494">„Prc8“ (vokas)</translation>
<translation id="769721561045429135">Šiuo metu turite kortelių, kurias galima naudoti tik šiuo įrenginiu. Jei norite peržiūrėti korteles, spustelėkite „Tęsti“.</translation>
<translation id="7699293099605015246">Straipsniai šiuo metu negalimi</translation>
<translation id="7701040980221191251">Nieko</translation>
@@ -1073,11 +1220,13 @@ Papildoma išsami informacija:
<translation id="774634243536837715">Pavojingas turinys užblokuotas.</translation>
<translation id="7752995774971033316">Netvarkoma</translation>
<translation id="7755287808199759310">Jūsų tėtis ar mama gali ją atblokuoti už jus</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Gali būti, kad užkarda arba antivirusinė programinė įranga užblokavo ryšį.</translation>
<translation id="7759163816903619567">Pateikties domenas:</translation>
<translation id="7761701407923456692">Serverio sertifikatas neatitinka URL.</translation>
<translation id="7763386264682878361">Mokėjimo aprašo analizavimo įrankis</translation>
<translation id="7764225426217299476">Pridėti adresą</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektūra</translation>
<translation id="7791543448312431591">Pridėti</translation>
<translation id="7793809570500803535"><ph name="SITE" /> tinklalapis gali laikinai neveikti arba visam laikui būti perkeltas nauju žiniatinklio adresu.</translation>
@@ -1089,8 +1238,8 @@ Papildoma išsami informacija:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Pašalinti formos pasiūlymą iš „Chrome“?</translation>
<translation id="7815407501681723534">Pagal terminą „<ph name="SEARCH_STRING" />“ surasta tiek <ph name="SEARCH_RESULTS" />: <ph name="NUMBER_OF_RESULTS" /></translation>
-<translation id="7818867226424560206">Politikos valdymas</translation>
<translation id="782886543891417279">Naudojant šį „Wi-Fi“ tinklą („<ph name="WIFI_NAME" />“) gali būti prašoma apsilankyti prisijungimo puslapyje.</translation>
+<translation id="7836231406687464395">„Postfix“ (vokas)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nėra}=1{1 programa („<ph name="EXAMPLE_APP_1" />“)}=2{2 programos („<ph name="EXAMPLE_APP_1" />“, „<ph name="EXAMPLE_APP_2" />“)}one{# programa („<ph name="EXAMPLE_APP_1" />“, „<ph name="EXAMPLE_APP_2" />“ <ph name="AND_MORE" />)}few{# programos („<ph name="EXAMPLE_APP_1" />“, „<ph name="EXAMPLE_APP_2" />“ <ph name="AND_MORE" />)}many{# programos („<ph name="EXAMPLE_APP_1" />“, „<ph name="EXAMPLE_APP_2" />“ <ph name="AND_MORE" />)}other{# programų („<ph name="EXAMPLE_APP_1" />“, „<ph name="EXAMPLE_APP_2" />“ <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Tačiau nesate nematomi. Įjungus inkognito režimą, naršymo veiksmai vis tiek matomi darbdaviui, interneto paslaugų teikėjui ar svetainėms, kuriose lankotės.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1099,7 +1248,7 @@ Papildoma išsami informacija:
<translation id="7878562273885520351">Jūsų slaptažodis gali būti pažeistas</translation>
<translation id="7882421473871500483">Ruda</translation>
<translation id="7887683347370398519">Patikrinkite kortelės saugos kodą (CVC) ir bandykite dar kartą</translation>
-<translation id="7893255318348328562">Sesijos pavadinimas</translation>
+<translation id="7904208859782148177">C3 (vokas)</translation>
<translation id="79338296614623784">Įveskite tinkamą telefono numerį</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Baigia galioti <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1109,21 +1258,25 @@ Papildoma išsami informacija:
<translation id="7951415247503192394">(32 bitų)</translation>
<translation id="7956713633345437162">Žymės mobiliesiems</translation>
<translation id="7961015016161918242">Niekada</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Nenurodytas</translation>
<translation id="800218591365569300">Pabandykite uždaryti skirtukus arba kitas programas, kad atlaisvintumėte atminties.</translation>
+<translation id="8004582292198964060">Naršyklė</translation>
<translation id="8009225694047762179">Tvarkyti slaptažodžius</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Ši kortelė ir jos atsiskaitymo adresas bus išsaugoti. Ją galėsite naudoti prisijungę prie <ph name="USER_EMAIL" />.}one{Šios kortelės ir jų atsiskaitymo adresai bus išsaugoti. Jas galėsite naudoti prisijungę prie <ph name="USER_EMAIL" />.}few{Šios kortelės ir jų atsiskaitymo adresai bus išsaugoti. Jas galėsite naudoti prisijungę prie <ph name="USER_EMAIL" />.}many{Šios kortelės ir jų atsiskaitymo adresai bus išsaugoti. Jas galėsite naudoti prisijungę prie <ph name="USER_EMAIL" />.}other{Šios kortelės ir jų atsiskaitymo adresai bus išsaugoti. Jas galėsite naudoti prisijungę prie <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Šis puslapis yra <ph name="SOURCE_LANGUAGE" /> k. Išversti į <ph name="TARGET_LANGUAGE" /> k.?</translation>
<translation id="8035152190676905274">Rašiklis</translation>
+<translation id="8037117624646282037">Kas neseniai naudojo įrenginį</translation>
<translation id="8037357227543935929">Klausti (numatytoji parinktis)</translation>
<translation id="803771048473350947">Failas</translation>
<translation id="8041089156583427627">Siųsti atsiliepimą</translation>
<translation id="8041940743680923270">Naudoti visuotinį numatytąjį nustatymą (klausti)</translation>
<translation id="8042918947222776840">Pasirinkti paėmimo metodą</translation>
<translation id="8057711352706143257">„<ph name="SOFTWARE_NAME" />“ netinkamai sukonfigūruota. Pašalinus „<ph name="SOFTWARE_NAME" />“ paprastai pavyksta išspręsti šią problemą. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Įrenginys sukonfigūruotas:</translation>
+<translation id="8066955247577885446">Deja, kažkas nepavyko.</translation>
+<translation id="8074253406171541171">10 x 13 (vokas)</translation>
<translation id="8078141288243656252">Negalima rašyti komentarų, kai pasukta</translation>
<translation id="8079031581361219619">Iš naujo įkelti svetainę?</translation>
<translation id="8088680233425245692">Nepavyko peržiūrėti straipsnio.</translation>
@@ -1132,11 +1285,12 @@ Papildoma išsami informacija:
<translation id="8091372947890762290">Laukiama aktyvinimo serveryje</translation>
<translation id="8092774999298748321">Sodri violetinė</translation>
<translation id="8094917007353911263">Naudojant šį tinklą gali būti prašoma apsilankyti <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Netinkamos kortelės pašalintos</translation>
<translation id="8103161714697287722">Mokėjimo metodas</translation>
<translation id="8118489163946903409">Mokėjimo metodas</translation>
+<translation id="8123836779274890062">„<ph name="DEVICE_TYPE" />“ tvarko <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">„<ph name="SOFTWARE_NAME" />“ nebuvo tinkamai įdiegta kompiuteryje ar tinkle. Kreipkitės į IT administratorių, kad ši problema būtų išspręsta.</translation>
-<translation id="8130693978878176684">Nebegaliu padėti, tolesnius veiksmus atlikite patys.</translation>
<translation id="8131740175452115882">Patvirtinti</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>
@@ -1146,8 +1300,11 @@ Papildoma išsami informacija:
<translation id="8197543752516192074">Versti puslapį</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="8202370299023114387">Konfliktas</translation>
+<translation id="8206978196348664717">„Prc4“ (vokas)</translation>
<translation id="8211406090763984747">Ryšys saugus</translation>
<translation id="8218327578424803826">Priskirta vieta:</translation>
+<translation id="8220146938470311105">C7 / C6 (vokas)</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="8238581221633243064">Atidarykite puslapį naujame inkognito skirtuke</translation>
@@ -1159,14 +1316,16 @@ Papildoma išsami informacija:
<translation id="825929999321470778">Rodyti visus išsaugotus slaptažodžius</translation>
<translation id="8261506727792406068">Ištrinti</translation>
<translation id="8267698848189296333">Prisijungiama kaip <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Ši naršyklė tvarkoma <ph name="ENROLLMENT_DOMAIN" />. Administratorius gali nuotoliniu būdu keisti naršyklės nustatymą. Veiklą šiame įrenginyje taip pat galima tvarkyti ne naršyklėje „Chrome“. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Prisijungti</translation>
<translation id="8288807391153049143">Rodyti sertifikatą</translation>
<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="8298115750975731693">Naudojant šį „Wi-Fi“ tinklą („<ph name="WIFI_NAME" />“) gali būti prašoma apsilankyti <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Vertimas nepavyko dėl tinklo ryšio problemos.</translation>
-<translation id="8311129316111205805">Įkelti sesiją</translation>
<translation id="8332188693563227489">Prieiga prie <ph name="HOST_NAME" /> atmesta</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_YEAR" />/<ph name="EXPIRATION_MONTH" /></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>
@@ -1184,7 +1343,6 @@ Papildoma išsami informacija:
<translation id="8416694386774425977">Tinklo konfigūracija netinkama ir jos nepavyko importuoti.
Papildoma išsami informacija:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Įrenginį tvarko <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Keisti</translation>
<translation id="8428213095426709021">Nustatymai</translation>
@@ -1212,9 +1370,11 @@ Papildoma išsami informacija:
<translation id="860043288473659153">Kortelės savininko vardas</translation>
<translation id="861775596732816396">Dydis: 4</translation>
<translation id="8620436878122366504">Jūsų tėvai dar jos nepatvirtino</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Išsaugoti šią kortelę šiame įrenginyje</translation>
<translation id="8663226718884576429">Užsakymo suvestinė, <ph name="TOTAL_LABEL" />, daugiau informacijos</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, atsakymas, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Jūsų ryšys su <ph name="DOMAIN" /> nekoduotas.</translation>
<translation id="8718314106902482036">Mokėjimas neužbaigtas</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, paieškos pasiūlymas</translation>
@@ -1228,6 +1388,7 @@ Papildoma išsami informacija:
<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="8763927697961133303">USB įrenginys</translation>
<translation id="8768895707659403558">Norėdami naudoti korteles visuose įrenginiuose, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Ištrinti dar kartą</translation>
<translation id="8792621596287649091">Galite prarasti galimybę pasiekti „<ph name="ORG_NAME" />“ paskyrą arba gali būti pavogta tapatybė. „Chromium“ rekomenduoja pakeisti slaptažodį dabar.</translation>
<translation id="8800988563907321413">Netoliese esantys pasiūlymai jums rodomi čia</translation>
@@ -1238,10 +1399,12 @@ Papildoma išsami informacija:
<translation id="885730110891505394">Bendrinimas su „Google“</translation>
<translation id="8858065207712248076">„Chrome“ rekomenduoja iš naujo nustatyti <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> slaptažodį, jei naudojate jį kitose svetainėse.</translation>
<translation id="8866481888320382733">Analizuojant politikos nustatymus įvyko klaida</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Neseniai uždaryta</translation>
<translation id="8874824191258364635">Įveskite tinkamą kortelės numerį</translation>
<translation id="8891727572606052622">Netinkamas įgaliotojo serverio režimas.</translation>
<translation id="8903921497873541725">Artinti</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Vardo ir pavardės pridėjimas</translation>
@@ -1249,13 +1412,13 @@ Papildoma išsami informacija:
<translation id="894185898663964645">Administratorius sukonfigūravo tinkintus šakninius sertifikatus, kurie gali leisti jam peržiūrėti svetainių, kuriose lankotės, turinį.</translation>
<translation id="8943282376843390568">Žaliųjų citrinų spalva</translation>
<translation id="8957210676456822347">Fiksuotojo portalo autorizavimas</translation>
+<translation id="8966619695390250636">Turėjote omenyje?</translation>
<translation id="8968766641738584599">Išsaugoti kortelę</translation>
<translation id="8971063699422889582">Baigėsi serverio sertifikato galiojimo laikas.</translation>
<translation id="8975012916872825179">Įtraukiama tokia informacija kaip telefono numeriai, el. pašto adresai ir pristatymo adresai</translation>
<translation id="8978053250194585037">„Google“ saugaus naršymo sistema neseniai <ph name="BEGIN_LINK" />aptiko, kad svetainėje <ph name="SITE" /> sukčiaujama<ph name="END_LINK" />. Sukčiavimo svetainės apsimeta kitomis svetainėmis, kad jus apgautų.</translation>
<translation id="8983003182662520383">„Google Pay“ naudojami mokėjimo metodai ir adresai</translation>
<translation id="8987927404178983737">Mėnuo</translation>
-<translation id="8988408250700415532">Kilo problema. Užsakymą galite užbaigti svetainėje.</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>
@@ -1265,6 +1428,7 @@ Papildoma išsami informacija:
<translation id="9011424611726486705">Atidaryti svetainės nustatymus</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(netinkamas)</translation>
<translation id="9035022520814077154">Saugos klaida</translation>
<translation id="9038649477754266430">Naudokite numatymo paslaugą, kad puslapiai būtų įkeliami greičiau</translation>
@@ -1276,11 +1440,11 @@ Papildoma išsami informacija:
<translation id="9065745800631924235">„<ph name="TEXT" />“ paieška istorijoje</translation>
<translation id="9069693763241529744">Užblokuota pagal plėtinį</translation>
<translation id="9076283476770535406">Joje gali būti suaugusiesiems skirto turinio</translation>
+<translation id="9076630408993835509">Šios naršyklės netvarko įmonė ar kita organizacija. Veiklą šiame įrenginyje galima tvarkyti ne naršyklėje „Chrome“. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Būtina pateikti daugiau informacijos</translation>
<translation id="9080712759204168376">Užsakymų suvestinė</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>
<translation id="9106062320799175032">Atsiskaitymo adreso pridėjimas</translation>
-<translation id="9110718169272311511">„Google“ padėjėjas sistemoje „Chrome“ rodomas netoli ekrano apačios</translation>
<translation id="9114524666733003316">Kortelė patvirtinama...</translation>
<translation id="9128870381267983090">Prisijungti prie tinklo</translation>
<translation id="9137013805542155359">Rodyti originalą</translation>
@@ -1289,6 +1453,7 @@ Papildoma išsami informacija:
<translation id="9148507642005240123">&amp;Anuliuoti redagavimą</translation>
<translation id="9154194610265714752">Atnaujinta</translation>
<translation id="9157595877708044936">Nustatoma...</translation>
+<translation id="9158625974267017556">C6 (vokas)</translation>
<translation id="9168814207360376865">Leisti svetainėms tikrinti, ar esate išsaugoję mokėjimo metodus</translation>
<translation id="9169664750068251925">Visada blokuoti šioje svetainėje</translation>
<translation id="9170848237812810038">&amp;Atšaukti</translation>
@@ -1303,10 +1468,12 @@ Papildoma išsami informacija:
<translation id="9219103736887031265">Vaizdai</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">CLEAR FORM</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Galite prarasti prieigą prie „Google“ paskyros. „Chromium“ rekomenduoja pakeisti slaptažodį dabar. Bus prašoma prisijungti.</translation>
<translation id="939736085109172342">Naujas aplankas</translation>
<translation id="945855313015696284">Patikrinkite toliau pateiktą informaciją ir ištrinkite visas netinkamas korteles</translation>
<translation id="951104842009476243">Tinkamos debeto ir išankstinio mokėjimo kortelės</translation>
+<translation id="958202389743790697">Užblokuota vadovaujantis <ph name="ORIGIN" /> saugos politika.</translation>
<translation id="962484866189421427">Šis turinys gali bandyti įdiegti klaidinančių programų, kurios apsimeta kitomis programomis, arba rinkti duomenis, naudojamus jums stebėti. <ph name="BEGIN_LINK" />Rodyti vis tiek<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Oficialiai pagaminta</translation>
<translation id="973773823069644502">Pridėti pristatymo adresą</translation>
@@ -1315,6 +1482,7 @@ Papildoma išsami informacija:
<translation id="984275831282074731">Mokėjimo metodai</translation>
<translation id="985199708454569384">&lt;p&gt;Ši klaida rodoma, jei kompiuterio ar mobiliojo įrenginio data ir laikas netikslūs.&lt;/p&gt;
&lt;p&gt;Kad ištaisytumėte klaidą, atidarykite įrenginio laikrodį. Įsitikinkite, kad rodomas tikslus laikas ir data.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Vykdymo programa sukurta</translation>
<translation id="989988560359834682">Adreso redagavimas</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_lv.xtb b/chromium/components/strings/components_strings_lv.xtb
index 2ad6d9601b0..ded851dc9ae 100644
--- a/chromium/components/strings/components_strings_lv.xtb
+++ b/chromium/components/strings/components_strings_lv.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
-<translation id="1005145902654145231">Neizdevās pārdēvēt sesiju.</translation>
<translation id="1008557486741366299">Vēlāk</translation>
<translation id="1010200102790553230">Ielādēt lapu vēlāk</translation>
<translation id="1015730422737071372">Sniegt papildu informāciju</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nezināms nosaukums</translation>
<translation id="1050038467049342496">Aizveriet citas lietotnes</translation>
<translation id="1055184225775184556">&amp;Pievienošanas atsaukšana</translation>
+<translation id="1056898198331236512">Brīdinājums</translation>
<translation id="1058479211578257048">Notiek karšu datu saglabāšana...</translation>
<translation id="10614374240317010">Netiek saglabātas</translation>
+<translation id="1062160989074299343">Prc10 (aploksne)</translation>
<translation id="106701514854093668">Datora grāmatzīmes</translation>
<translation id="1074497978438210769">Nav droša</translation>
<translation id="1080116354587839789">Ietilpināt pēc platuma</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Uz kartes norādītā vārda pievienošana</translation>
<translation id="1089439967362294234">Nomainīt paroli</translation>
<translation id="109743633954054152">Pārvaldīt paroles Chrome iestatījumos</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Tīmekļa vietņu drošības atjauninājumu laikā bieži var tikt rādīti brīdinājumi. Drīzumā tas tiks labots.</translation>
<translation id="1126551341858583091">Lielums vietējā krātuvē ir <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Politikas kešatmiņa ir labā stāvoklī.</translation>
+<translation id="1131264053432022307">Kopētais attēls</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Pārdēvēt</translation>
<translation id="1175364870820465910">Drukāt...</translation>
<translation id="1181037720776840403">Noņemt</translation>
<translation id="1197088940767939838">Oranža</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Jūsu ierīces nosaukums</translation>
<translation id="124116460088058876">Citas valodas…</translation>
<translation id="1250759482327835220">Lai nākamreiz veiktu maksājumu ātrāk, saglabājiet kartes datus, vārdu un norēķinu adresi savā Google kontā.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (veikta sinhronizācija)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Komandrindu varianti</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="1314614906530272393">Atlasītā sesija nepastāv.</translation>
+<translation id="1320233736580025032">Prc1 (aploksne)</translation>
+<translation id="132301787627749051">Meklēt starpliktuves attēlu</translation>
<translation id="1323433172918577554">Rādīt vairāk</translation>
<translation id="132390688737681464">Saglabāt un aizpildīt adreses</translation>
<translation id="1333989956347591814">Iespējams, jūsu darbības <ph name="BEGIN_EMPHASIS" />joprojām būs redzamas<ph name="END_EMPHASIS" />:
@@ -79,12 +82,18 @@
<translation id="1340482604681802745">Saņemšanas adrese</translation>
<translation id="1348198688976932919">Vietnē, kas tiks atvērta, ir bīstamas lietotnes</translation>
<translation id="1348779747280417563">Apstipriniet vārdu</translation>
+<translation id="1357195169723583938">Kas un kad nesen lietoja ierīci</translation>
+<translation id="1364822246244961190">Šī politika ir bloķēta, tās vērtība tiks ignorēta.</translation>
<translation id="1374468813861204354">ieteikumus</translation>
+<translation id="1374692235857187091">Index-4x6 (pastkarte)</translation>
<translation id="1375198122581997741">Par versiju</translation>
<translation id="1376836354785490390">Rādīt mazāk</translation>
<translation id="1377321085342047638">Kartes numurs</translation>
<translation id="138218114945450791">Gaiši zila</translation>
+<translation id="1382194467192730611">USB ierīce, ko atļauj jūsu administrators</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> nenosūtīja nekādus datus.</translation>
+<translation id="140316286225361634">Vietne <ph name="ORIGIN" /> ir pieprasījusi, lai drošības politika
+     attiektos uz visu tās pieprasījumu, un saskaņā ar šo politiku šobrīd vietne tiek uzskatīta par nedrošu.</translation>
<translation id="1405567553485452995">Gaiši zaļa</translation>
<translation id="1407135791313364759">Atvērt visas</translation>
<translation id="1413809658975081374">Konfidencialitātes kļūda</translation>
@@ -92,9 +101,12 @@
<translation id="1426410128494586442">Jā</translation>
<translation id="1430915738399379752">Drukāt</translation>
<translation id="1455413310270022028">Dzēšgumija</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Rādīt vairāk</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Izvēlēties nosūtīšanas adresi</translation>
+<translation id="1492194039220927094">Politiku informatīvie ziņojumi:</translation>
<translation id="1501859676467574491">Rādī kartes no mana Google konta</translation>
-<translation id="1506687042165942984">Rādīt saglabātu (t.i., novecojušu) šīs lapas versiju.</translation>
<translation id="1507202001669085618">&lt;p&gt;Šis kļūdas ziņojums tiek rādīts, ja izmantojat Wi-Fi portālu, kurā ir jāpierakstās, lai varētu pāriet tiešsaistē.&lt;/p&gt;
&lt;p&gt;Lai novērstu šo kļūdu, lapā, kuru mēģināt atvērt, noklikšķiniet uz &lt;strong&gt;Izveidot savienojumu&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Jānorāda tālruņa numurs</translation>
@@ -102,23 +114,27 @@
<translation id="1519264250979466059">Būvējuma datums</translation>
<translation id="1521655867290435174">Google izklājlapas</translation>
<translation id="1527263332363067270">Tiek gaidīta savienojuma izveide...</translation>
+<translation id="1529521330346880926">10x15 (aploksne)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Šajā lapā ir rakstīts</translation>
<translation id="153384715582417236">Pagaidām tas arī viss!</translation>
<translation id="154408704832528245">Izvēlēties piegādes adresi</translation>
<translation id="1549470594296187301">Lai izmantotu šo funkciju, ir jābūt iespējotai valodai JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Ievadīt derīguma termiņu</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Jūsu nokopētais attēls</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Neļaut šai lapai veidot papildu dialoglodziņus</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Beigt sesiju</translation>
<translation id="1639239467298939599">Notiek ielāde</translation>
<translation id="1640180200866533862">Lietotāja politikas</translation>
@@ -133,8 +149,10 @@
<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="168841957122794586">Servera sertifikāts ietver vāju kriptogrāfisko atslēgu.</translation>
<translation id="1697532407822776718">Gatavs!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokuments ir pārāk liels, tādēļ tam nevar pievienot piezīmes</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>
@@ -145,6 +163,7 @@
<translation id="1734878702283171397">Sazinieties ar sistēmas administratoru.</translation>
<translation id="1740951997222943430">Ievadiet derīgu mēnesi</translation>
<translation id="1743520634839655729">Lai nākamreiz veiktu maksājumu ātrāk, saglabājiet kartes datus, vārdu un norēķinu adresi savā Google kontā un šajā ierīcē.</translation>
+<translation id="1745880797583122200">Jūsu pārlūks tiek pārvaldīts</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>
@@ -152,8 +171,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kartes īpašnieka vārds, uzvārds</translation>
<translation id="1821930232296380041">Pieprasījums vai tā parametri nebija derīgi.</translation>
+<translation id="1822540298136254167">Tīmekļa vietnes, kuras apmeklējat, un cik daudz laika tajās pavadāt</translation>
<translation id="1826516787628120939">Pārbaude</translation>
<translation id="1834321415901700177">Šī vietne satur kaitnieciskas programmas</translation>
<translation id="1839551713262164453">Politikas vērtību validēšana neizdevās, tika konstatētas kļūdas</translation>
@@ -180,6 +201,7 @@
<translation id="1981206234434200693">Notīrīt Chrome pārlūkošanas vēstures datus</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{un vēl 1}zero{un vēl #}one{un vēl #}other{un vēl #}}</translation>
<translation id="2003709556000175978">Nekavējoties atiestatiet paroli</translation>
+<translation id="20053308747750172">Visiem pieprasījumiem uz serveri <ph name="ORIGIN" /> tiek piemērota drošības politika. Taču tagad serveris ir iesniedzis nederīgu politiku, kas neļauj pārlūkam izpildīt jūsu pieprasījumu vietnei <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Starpniekserverim ir iestatīta autokonfigurācija.</translation>
<translation id="2030481566774242610">Vai domājāt <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Pārbaudiet starpniekserveri un ugunsmūri<ph name="END_LINK" />.</translation>
@@ -196,6 +218,7 @@
<translation id="2096368010154057602">Departaments</translation>
<translation id="2102134110707549001">Ieteikt drošu paroli…</translation>
<translation id="2108755909498034140">Restartējiet datoru</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Karte</translation>
<translation id="2114841414352855701">Ignorēta, jo to atcēla politika <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobilās grāmatzīmes</translation>
@@ -206,6 +229,7 @@
<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="2169984857010174799">Kaku2 (aploksne)</translation>
<translation id="2181821976797666341">Politikas</translation>
<translation id="2183608646556468874">Tālruņa numurs</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adrese}zero{# adreses}one{# adrese}other{# adreses}}</translation>
@@ -223,11 +247,15 @@
<translation id="2270484714375784793">Tālruņa numurs</translation>
<translation id="2283340219607151381">Saglabāt un aizpildīt adreses</translation>
<translation id="2292556288342944218">Piekļuve internetam ir bloķēta</translation>
+<translation id="2294558542833290837">Saite, ko sākotnēji atvērāt, ir neparasta</translation>
+<translation id="2297722699537546652">B5 (aploksne)</translation>
+<translation id="2310021320168182093">Chou2 (aploksne)</translation>
<translation id="2316887270356262533">Tiks atbrīvots mazāk nekā 1 MB. Dažas vietnes nākamajā apmeklējumā var ielādēt lēnāk.</translation>
<translation id="2317259163369394535">Vietnē <ph name="DOMAIN" /> ir jāievada lietotājvārds un parole.</translation>
<translation id="2317583587496011522">Tiek pieņemtas debetkartes.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, derīguma termiņš: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Iestatījumu kontrolē jūsu administrators</translation>
+<translation id="2346319942568447007">Kopētais attēls</translation>
<translation id="2349790679044093737">VR sesija ir aktīva.</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>
@@ -239,29 +267,34 @@
<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="2378238891085281592">Jūs esat atvēris privāto režīmu</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Visiem pieprasījumiem uz serveri <ph name="ORIGIN" /> tiek piemērota drošības politika. Bet tagad serveris nevar iesniegt politiku, kas neļauj pārlūkam izpildīt jūsu pieprasījumu vietnei <ph name="SITE" />.</translation>
<translation id="244665789865330679">Jūsu ierīci un kontu pārvalda <ph name="ENROLLMENT_DOMAIN" />. Tas nozīmē, ka administrators var attāli konfigurēt jūsu ierīci un kontu.</translation>
<translation id="2463193859425327265">Mainīt sākumlapu</translation>
<translation id="2463739503403862330">Aizpildīt</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Izvēlēties piegādes veidu</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Palaist tīkla diagnostiku<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Tulkot šo lapu</translation>
<translation id="2479410451996844060">Nederīgs meklēšanas URL.</translation>
<translation id="2482878487686419369">Paziņojumi</translation>
<translation id="248348093745724435">Ierīces politikas</translation>
+<translation id="2485387744899240041">Lietotājvārdi jūsu ierīcei un pārlūkam</translation>
<translation id="2491120439723279231">Servera sertifikātā ir kļūdas.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Skenēt jaunu karti</translation>
<translation id="2501278716633472235">Doties atpakaļ</translation>
<translation id="2503184589641749290">Atbalstītās debetkartes un priekšapmaksas kartes</translation>
<translation id="2515629240566999685">Pārbaudiet signālu savā apkaimē.</translation>
-<translation id="2516852381693169964">Meklēt attēlu <ph name="SEARCH_ENGINE" /> tīklā</translation>
<translation id="2523886232349826891">Tiks saglabāta tikai šajā ierīcē</translation>
<translation id="2524461107774643265">Papildu informācijas pievienošana</translation>
<translation id="2536110899380797252">Pievienot adresi</translation>
@@ -273,6 +306,7 @@
<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="2618023639789766142">C10 (aploksne)</translation>
<translation id="2625385379895617796">Norādītais laiks ir pārāk tālu nākotnē</translation>
<translation id="2634124572758952069">Nevarēja atrast vietnes <ph name="HOST_NAME" /> servera IP adresi.</translation>
<translation id="2639739919103226564">Statuss:</translation>
@@ -282,7 +316,9 @@
<translation id="2666117266261740852">Aizveriet citas cilnes vai lietotnes</translation>
<translation id="267371737713284912">nospiediet taustiņu <ph name="MODIFIER_KEY_DESCRIPTION" />, lai atsauktu</translation>
<translation id="2674170444375937751">Vai tiešām vēlaties dzēst šīs lapas no savas vēstures?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Iziet</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Atbalstītās kartes</translation>
<translation id="2702801445560668637">Atvērt sarakstu</translation>
<translation id="2704283930420550640">Vērtība neatbilst formātam.</translation>
@@ -299,7 +335,6 @@
<translation id="2742870351467570537">Noņemt atlasītos vienumus</translation>
<translation id="277133753123645258">Nosūtīšanas veids</translation>
<translation id="277499241957683684">Trūkst ierīces ieraksta.</translation>
-<translation id="2781030394888168909">Eksportēt MacOS formātā</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Savienojums tika atiestatīts.</translation>
<translation id="2788784517760473862">Atbalstītās kredītkartes</translation>
@@ -311,8 +346,10 @@
<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="2847118875340931228">Atvērt inkognito režīma logu</translation>
+<translation id="2850739647070081192">Invite (aploksne)</translation>
<translation id="2851634818064021665">Jums nepieciešama atļauja, lai apmeklētu šo vietni</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Vai saglabāt karti?</translation>
<translation id="2903493209154104877">Adreses</translation>
<translation id="290376772003165898">Vai lapa nav šajā valodā: <ph name="LANGUAGE" />?</translation>
@@ -322,6 +359,7 @@
<translation id="2925673989565098301">Piegādes veids</translation>
<translation id="2928905813689894207">Norēķinu adrese</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +376,14 @@
<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="3023071826883856138">You4 (aploksne)</translation>
<translation id="3024663005179499861">Politikas tips nav pareizs.</translation>
<translation id="3037605927509011580">Cilnes avārija.</translation>
<translation id="3041612393474885105">Sertifikāta informācija</translation>
+<translation id="3060227939791841287">C9 (aploksne)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Pievienot saņemšanas adresi</translation>
<translation id="3105172416063519923">Līdzekļa ID:</translation>
<translation id="3109728660330352905">Jums nav pilnvaru, lai skatītu šo lapu.</translation>
@@ -364,20 +405,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> serverī <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Atcelt maksājumu</translation>
<translation id="3207960819495026254">Atzīmēts kā grāmatzīme</translation>
-<translation id="3209375525920864198">Lūdzu, ievadiet derīgu sesijas nosaukumu.</translation>
+<translation id="321912867715453276">Brīdinājums! Šai politikai ir vairāk nekā viens avots, bet vērtības ir vienādas.</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="3229041911291329567">Versijas informācija par ierīci un pārlūku</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Pievienot vārdu un uzvārdu uz kartes</translation>
<translation id="3287510313208355388">Lejupielādēt, kad pieejama tiešsaiste</translation>
<translation id="3293642807462928945">Uzzināt vairāk par politiku <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Netika atrasts neviens meklēšanas rezultāts.</translation>
-<translation id="3305707030755673451">Jūsu dati tika šifrēti, izmantojot jūsu sinhronizācijas ieejas frāzi šādā datumā: <ph name="TIME" />. Lai sāktu sinhronizāciju, ievadiet ieejas frāzi.</translation>
<translation id="3320021301628644560">Norēķinu adreses pievienošana</translation>
<translation id="3324983252691184275">Tumši sarkana</translation>
<translation id="3338095232262050444">Droši</translation>
@@ -405,9 +447,11 @@
<translation id="3427342743765426898">&amp;Labojuma atsaukuma atcelšana</translation>
<translation id="342781501876943858">Chromium iesaka atiestatīt jūsu paroli, ja izmantojāt to citās vietnēs.</translation>
<translation id="3431636764301398940">Saglabāt šo karti šajā ierīcē</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Šīs ierīces īpašnieks ir izslēdzis dinozauru spēli.</translation>
<translation id="3447884698081792621">Parādīt sertifikātu (izsniedza <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Pirmsielādes intervāls:</translation>
+<translation id="3456231139987291353">Number-11 (aploksne)</translation>
<translation id="3461824795358126837">Marķieris</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>
@@ -430,19 +474,22 @@
<translation id="358285529439630156">Tiek pieņemtas kredītkartes un priekšapmaksas kartes.</translation>
<translation id="3582930987043644930">Pievienojiet vārdu.</translation>
<translation id="3583757800736429874">&amp;Pārvietošanas atsaukuma atcelšana</translation>
+<translation id="35866233670761917">Jūsu apmeklēto vietņu saturs nav redzams administratoriem</translation>
<translation id="3586931643579894722">Slēpt detaļas</translation>
+<translation id="3592413004129370115">Italian (aploksne)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">2. izmērs</translation>
<translation id="3615877443314183785">Ievadiet derīgu datumu</translation>
<translation id="36224234498066874">Dzēst pārlūkošanas datus...</translation>
<translation id="362276910939193118">Rādīt pilnu vēsturi</translation>
-<translation id="3623476034248543066">Rādīt vērtību</translation>
<translation id="3630155396527302611">Ja tā jau ir norādīta kā programma, kurai ir atļauts piekļūt tīklam, noņemiet to no saraksta un pievienojiet vēlreiz.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validācija bija veiksmīga.</translation>
<translation id="3655670868607891010">Ja šo redzat bieži, izmēģiniet šos <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Pārskatīšana</translation>
<translation id="366077651725703012">Kredītkartes informācijas atjaunināšana</translation>
<translation id="3676592649209844519">Ierīces ID:</translation>
+<translation id="3677008721441257057">Vai jūs domājāt &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Pieprasījumu nevarēja parakstīt.</translation>
<translation id="3678529606614285348">Atvērt lapu jaunā inkognito režīma logā (Ctrl+Shift+N)</translation>
<translation id="3679803492151881375">Avāriju pārskats tverts: <ph name="CRASH_TIME" />; augšupielādēts: <ph name="UPLOAD_TIME" /></translation>
@@ -450,13 +497,14 @@
<translation id="3704162925118123524">Iespējams, izmantotajā tīklā tiks pieprasīts apmeklēt pieteikšanās lapu.</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="3709599264800900598">Kopētais teksts</translation>
<translation id="3712624925041724820">Nav pietiekami daudz licenču.</translation>
<translation id="3714780639079136834">Ieslēdziet mobilo datu savienojumu vai Wi-Fi.</translation>
<translation id="3715597595485130451">Savienojuma izveide ar Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Pārbaudiet starpniekserveri, ugunsmūri un DNS konfigurāciju<ph name="END_LINK" />.</translation>
<translation id="372429172604983730">Šo kļūdu var izraisīt tādas lietojumprogrammas kā pretvīrusu, ugunsmūra, tīmekļa filtrēšanas vai starpniekservera programmatūra.</translation>
+<translation id="373042150751172459">B4 (aploksne)</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="3745099705178523657">Pēc apstiprināšanas kartes informācija no Google konta tiks kopīgota ar šo vietni.</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>
@@ -469,10 +517,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Derīguma termiņš: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">16. izmērs</translation>
+<translation id="3797522431967816232">Prc3 (aploksne)</translation>
<translation id="3807873520724684969">Tika bloķēts kaitīgs saturs.</translation>
<translation id="3810973564298564668">Pārvaldīt</translation>
<translation id="382518646247711829">Ja izmantojat starpniekserveri...</translation>
<translation id="3828924085048779000">Tukša ieejas frāze nav atļauta.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> instalēja paplašinājumus papildu funkcijām. Paplašinājumiem ir piekļuve dažiem jūsu datiem.</translation>
<translation id="385051799172605136">Atpakaļ</translation>
<translation id="3858027520442213535">Atjaunināt datumu un laiku</translation>
<translation id="3884278016824448484">Ierīces identifikators rada konfliktu.</translation>
@@ -480,6 +530,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Vienmēr jautāt šajā vietnē</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>
@@ -490,11 +541,13 @@
<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="3984550557525787191">Šāds sesijas nosaukums jau pastāv.</translation>
<translation id="3987940399970879459">Mazāk nekā 1 MB</translation>
+<translation id="4008849406247176967">Brīdinājums! Šai politikai pastāv vairāk nekā viens avots ar pretrunīgām vērtībām!</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="4030383055268325496">&amp;Atsaukt pievienošanu</translation>
+<translation id="4032320456957708163">Jūsu pārlūku pārvalda <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Atslēga <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (aploksne)</translation>
<translation id="4067947977115446013">Derīgas adreses pievienošana</translation>
<translation id="4072486802667267160">Apstrādājot pasūtījumu, radās kļūda. Lūdzu, mēģiniet vēlreiz.</translation>
<translation id="4075732493274867456">Klients un serveris neatbalsta bieži lietoto SSL protokola versiju vai šifra komplektu.</translation>
@@ -514,10 +567,12 @@
<translation id="4159784952369912983">Violets</translation>
<translation id="4165986682804962316">Vietnes iestatījumi</translation>
<translation id="4171400957073367226">Verifikācijas paraksts nav derīgs.</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Vēl <ph name="ITEM_COUNT" /> vienums}zero{Vēl <ph name="ITEM_COUNT" /> vienumi}one{Vēl <ph name="ITEM_COUNT" /> vienums}other{Vēl <ph name="ITEM_COUNT" /> vienumi}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (aploksne)</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="4221630205957821124">&lt;h4&gt;1. darbība. Pierakstīšanās portālā&lt;/h4&gt;
@@ -549,58 +604,79 @@
<translation id="4277028893293644418">Atiestatīt paroli</translation>
<translation id="4280429058323657511">, derīga līdz <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Šī karte tika saglabāta jūsu Google kontā}zero{Šīs kartes tika saglabātas jūsu Google kontā}one{Šīs kartes tika saglabātas jūsu Google kontā}other{Šīs kartes tika saglabātas jūsu Google kontā}}</translation>
+<translation id="42981349822642051">Izvērst</translation>
+<translation id="4302965934281694568">Chou3 (aploksne)</translation>
<translation id="4305817255990598646">Pāriet</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloķēt (pēc noklusējuma)</translation>
+<translation id="4318566738941496689">Jūsu ierīces nosaukums un tīkla adrese</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="4340982228985273705">Šo datoru nepārvalda uzņēmums, tāpēc politika var automātiski instalēt tikai tos paplašinājumus, kas tiek mitināti Chrome interneta veikalā. Chrome interneta veikala atjauninājumu URL: <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Pieņemtās kredītkartes</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Pārvaldīt maksājumu veidus...</translation>
+<translation id="4367563149485757821">Number-12 (aploksne)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Tālrunis</translation>
<translation id="4406896451731180161">meklēšanas rezultāti</translation>
-<translation id="4406972042435603828">Administratori ir instalējuši paplašinājumus ar jaudīgām iespējām.</translation>
<translation id="4408413947728134509">Sīkfaili <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Saņemšanas adrese</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="443121186588148776">Seriālais ports</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="4434045419905280838">Uznirstošie elem. un novirzīšana</translation>
+<translation id="4435702339979719576">Pastkarte)</translation>
<translation id="443673843213245140">Starpniekservera lietošana ir atspējota, bet ir norādīta atklāta starpniekservera konfigurācija.</translation>
<translation id="445100540951337728">Atbalstītās debetkartes</translation>
+<translation id="4466881336512663640">Veidlapas izmaiņas tiks zaudētas. Vai tiešām vēlaties turpināt?</translation>
<translation id="4482953324121162758">Šī vietne netiks tulkota.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Nederīgs URL. Vietrādim URL ir jābūt ar standarta shēmu, piemēram, “http://example.com” vai “https://example.com”.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (aploksne)</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="4517607026994743406">Comm-10 (aploksne)</translation>
<translation id="4522570452068850558">Informācija</translation>
<translation id="4524805452350978254">Pārvaldīt kartītes</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Atspējojiet paplašinājumus.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Piegāde</translation>
+<translation id="4579056131138995126">Personisks (aploksne)</translation>
<translation id="4582204425268416675">Noņemt karti</translation>
<translation id="4587425331216688090">Vai noņemt adresi no pārlūka Chrome?</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="4597348597567598915">8. izmērs</translation>
+<translation id="4600854749408232102">C6/C5 (aploksne)</translation>
<translation id="4646534391647090355">Doties uz turieni tagad</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="467809019005607715">Google prezentācijas</translation>
<translation id="4690462567478992370">Pārtraukt nederīga sertifikāta izmantošanu</translation>
+<translation id="4691835149146451662">Architecture-A (aploksne)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Savienojums tika pārtraukts</translation>
<translation id="471880041731876836">Jums nav atļaujas apmeklēt šo vietni</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Palaist Windows tīkla diagnostiku<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Atkārtoti ielādēt politikas</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">Prc2 (aploksne)</translation>
<translation id="4736825316280949806">Restartējiet pārlūku Chromium</translation>
<translation id="473775607612524610">Atjaunināt</translation>
<translation id="4738601419177586157">Meklēšanas ieteikums vaicājumam “<ph name="TEXT" />”</translation>
<translation id="4742407542027196863">Pārvaldīt paroles…</translation>
<translation id="4744603770635761495">Izpildāms ceļš</translation>
+<translation id="4746351372139058112">Messages</translation>
<translation id="4750917950439032686">Jūsu informācija (piemēram, paroles vai kredītkaršu numuri) ir privāta, kad tā tiek nosūtīta uz šo vietni.</translation>
<translation id="4756388243121344051">Vēsture</translation>
<translation id="4758311279753947758">Pievienot kontaktinformāciju</translation>
@@ -608,9 +684,9 @@
<translation id="4764776831041365478">Tīmekļa lapa vietnē <ph name="URL" /> var īslaicīgi nebūt pieejama, vai tā var būt pārvietota uz jaunu tīmekļa adresi.</translation>
<translation id="4771973620359291008">Radās nezināma kļūda.</translation>
<translation id="4785689107224900852">Pāriet uz šo cilni</translation>
-<translation id="4792143361752574037">Piekļūstot sesijas failiem, radās problēma. Saglabāšana diskā šobrīd ir atspējota. Lai mēģinātu vēlreiz, atkārtoti ielādējiet lapu.</translation>
<translation id="4798078619018708837">Lai atjauninātu kartes informāciju, ievadiet kredītkartes <ph name="CREDIT_CARD" /> derīguma termiņu un CVC kodu. Pēc apstiprināšanas kartes informācija no Google konta tiks kopīgota ar šo vietni.</translation>
<translation id="4800132727771399293">Pārbaudiet derīguma termiņu un CVC kodu un mēģiniet vēlreiz.</translation>
+<translation id="480334179571489655">Izcelsmes politikas kļūda</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>
@@ -625,7 +701,6 @@
<translation id="4881695831933465202">Atvērt</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>
@@ -634,15 +709,15 @@
<translation id="4943872375798546930">Nav rezultātu</translation>
<translation id="4950898438188848926">Ciļņu pārslēgšanas poga. Nospiediet ievadīšanas taustiņu, lai pārslēgtos uz atvērto cilni, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />.</translation>
<translation id="495170559598752135">Darbības</translation>
-<translation id="495832697253704892">Ziņošana par paplašinājumiem</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Izvērst sarakstu</translation>
<translation id="4974590756084640048">Atkārtoti iespējot brīdinājumus</translation>
+<translation id="4984339528288761049">Prc5 (aploksne)</translation>
<translation id="4989163558385430922">Skatīt visu</translation>
<translation id="4989809363548539747">Šis spraudnis netiek atbalstīts</translation>
-<translation id="4996230189582812866">Ziņošana</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="5014174725590676422">Tiek rādīts Google asistenta pirmās palaišanas ekrāns pārlūkprogrammā Chrome.</translation>
<translation id="5015510746216210676">Ierīces nosaukums:</translation>
+<translation id="5017554619425969104">Kopētais teksts</translation>
<translation id="5018422839182700155">Nevar atvērt šo lapu</translation>
<translation id="5019198164206649151">Dublējumu krātuve nav labā stāvoklī.</translation>
<translation id="5023310440958281426">Administratora politiku pārbaude</translation>
@@ -652,35 +727,51 @@
<translation id="5034369478845443529">Lokālais konteksts: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Atļaut</translation>
<translation id="5040262127954254034">Konfidencialitāte</translation>
+<translation id="5043480802608081735">Jūsu kopētā saite</translation>
<translation id="5045550434625856497">Nepareiza parole</translation>
<translation id="5056549851600133418">Jums piemeklēti raksti</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Pārbaudiet starpniekservera adresi<ph name="END_LINK" />.</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="5097099694988056070">Ierīces statistika, piemēram, CPU/RAM lietojums</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Jūsu ierīci pārvalda <ph name="ENROLLMENT_DOMAIN" />, un jūsu kontu pārvalda <ph name="ACCOUNT_DOMAIN" />. Tas nozīmē, ka administratori var attāli konfigurēt jūsu ierīci un kontu.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bitu)</translation>
-<translation id="5128122789703661928">Sesija ar šādu nosaukumu nav dzēšama.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Pārvaldīt adreses...</translation>
+<translation id="5138227688689900538">Rādīt mazāk</translation>
<translation id="5141240743006678641">Šifrēt sinhronizētās paroles, izmantojot Google akreditācijas datus</translation>
<translation id="5145883236150621069">Politikas atbildē ir kļūdas kods.</translation>
+<translation id="515292512908731282">C4 (aploksne)</translation>
<translation id="5159010409087891077">Atvērt lapu jaunā inkognito režīma logā (⇧⌘N)</translation>
<translation id="516920405563544094">Ievadiet kredītkartes <ph name="CREDIT_CARD" /> CVC kodu. Pēc apstiprināšanas kartes informācija no Google konta tiks kopīgota ar šo vietni.</translation>
<translation id="5169827969064885044">Varat zaudēt piekļuvi savam organizācijas kontam, vai jūsu identitāte var tikt nozagta. Chrome iesaka nekavējoties nomainīt paroli.</translation>
<translation id="5171045022955879922">Meklējiet vai ievadiet URL.</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Ierīce</translation>
<translation id="5179510805599951267">Vai nav valodā: <ph name="ORIGINAL_LANGUAGE" />? Ziņot par šo kļūdu</translation>
<translation id="5190835502935405962">Grāmatzīmju josla</translation>
-<translation id="5200263511887412697">parāda sarakstu ar ierīces lietotājiem, kuri nesen ir pieteikušies</translation>
+<translation id="519422657042045905">Anotācija nav pieejama</translation>
<translation id="5201306358585911203">Šajā lapā iegultā lapā ir rakstīts</translation>
<translation id="5205222826937269299">Jānorāda vārds vai nosaukums.</translation>
<translation id="5215116848420601511">Adreses un maksājumu veidi, kuros tiek izmantots pakalpojums Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Jānorāda e-pasta adrese.</translation>
<translation id="5230733896359313003">Piegādes adrese</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">“Izveidojiet savienojumu ar tīklu”</translation>
<translation id="5251803541071282808">Mākonis</translation>
+<translation id="5252000469029418751">C7 (aploksne)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Tīkla adreses</translation>
<translation id="5285570108065881030">Rādīt visas saglabātās paroles</translation>
<translation id="5287240709317226393">Rādīt sīkfailus</translation>
<translation id="5288108484102287882">Validējot politikas vērtības, tika konstatētas kļūdas</translation>
@@ -692,7 +783,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" />. no <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Izvēlēties kontaktinformāciju</translation>
<translation id="5327248766486351172">Nosaukums</translation>
+<translation id="5329858041417644019">Jūsu pārlūks netiek pārvaldīts</translation>
<translation id="5332219387342487447">Piegādes veids</translation>
+<translation id="5334013548165032829">Sistēmas žurnāli ar detalizētu informāciju</translation>
<translation id="5344579389779391559">Šajā lapā var tikt mēģināts pieprasīt naudu</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>
@@ -700,6 +793,7 @@
<translation id="5377026284221673050">“Pulkstenis atpaliek”, “Pulkstenis steidzas” vai “&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">Lai kartes varētu izmantot visās ierīcēs, pierakstieties un ieslēdziet sinhronizāciju.</translation>
<translation id="5386426401304769735">Šīs vietnes sertifikātu ķēdē ir iekļauts sertifikāts, kas ir parakstīts, izmantojot SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -710,6 +804,7 @@
<translation id="5457113250005438886">Nav derīgi</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Atcelt labojuma atsaukšanu</translation>
+<translation id="5478437291406423475">B6/C4 (aploksne)</translation>
<translation id="5481076368049295676">Šis saturs jūsu ierīcē var mēģināt instalēt bīstamu programmatūru, kas var nozagt vai izdzēst jūsu informāciju. <ph name="BEGIN_LINK" />Tāpat rādīt<ph name="END_LINK" />.</translation>
<translation id="54817484435770891">Derīgas adreses pievienošana</translation>
<translation id="5490432419156082418">Adreses un citus datus</translation>
@@ -717,10 +812,12 @@
<ph name="LINE_BREAK" />
Sazinieties ar sistēmas administratoru.</translation>
<translation id="549333378215107354">3. izmērs</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Pārvaldītās grāmatzīmes</translation>
<translation id="5510766032865166053">Iespējams, tas ir pārvietots vai izdzēsts.</translation>
<translation id="5523118979700054094">Politikas nosaukums</translation>
<translation id="552553974213252141">Vai iegūtais teksts bija pareizs?</translation>
+<translation id="553484882784876924">Prc6 (aploksne)</translation>
<translation id="5540224163453853">Pieprasīto rakstu nevarēja atrast.</translation>
<translation id="5541546772353173584">E-pasta adreses pievienošana</translation>
<translation id="5545756402275714221">Ieteiktie raksti</translation>
@@ -735,15 +832,21 @@
<translation id="5595485650161345191">Rediģēt adresi</translation>
<translation id="5598944008576757369">Izvēlēties maksājuma veidu</translation>
<translation id="560412284261940334">Pārvaldīšana netiek atbalstīta.</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> novirzīja pārāk daudz reižu.</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="5632627355679805402">Jūsu dati tika šifrēti, izmantojot jūsu <ph name="BEGIN_LINK" />Google paroli<ph name="END_LINK" />, no šāda datuma: <ph name="TIME" />. Ievadiet paroli, lai sāktu sinhronizāciju.</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="563324245173044180">Bloķēts maldinošs saturs</translation>
<translation id="5659593005791499971">E-pasts</translation>
+<translation id="5663614846592581799">9x11 (aploksne)</translation>
+<translation id="5663955426505430495">Šīs ierīces administrators ir instalējis paplašinājumus papildu funkcijām. Paplašinājumiem ir piekļuve dažiem jūsu datiem.</translation>
<translation id="5675650730144413517">Šī lapa nedarbojas</translation>
+<translation id="5684874026226664614">Hmm... Šo lapu nevarēja iztulkot.</translation>
<translation id="5685654322157854305">Pievienot nosūtīšanas adresi</translation>
<translation id="5689199277474810259">Eksportēt JSON formātā</translation>
<translation id="5689516760719285838">Atrašanās vieta</translation>
@@ -752,38 +855,39 @@
<translation id="5710435578057952990">Tīmekļa vietnes identitāte nav apstiprināta.</translation>
<translation id="5719499550583120431">Tiek pieņemtas priekšapmaksas kartes.</translation>
<translation id="5720705177508910913">Pašreizējais lietotājs</translation>
+<translation id="5728056243719941842">C5 (aploksne)</translation>
<translation id="5730040223043577876">Chrome iesaka atiestatīt jūsu paroli, ja izmantojāt to citās vietnēs.</translation>
<translation id="5732392974455271431">Lai atbloķētu, vērsieties pie vecākiem</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Kartes datu saglabāšana Google kontā}zero{Karšu datu saglabāšana Google kontā}one{Karšu datu saglabāšana Google kontā}other{Karšu datu saglabāšana Google kontā}}</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="5770114862687765385">Šķiet, ka fails ir bojāts. Lai atiestatītu sesiju, noklikšķiniet uz pogas “Atiestatīt”.</translation>
<translation id="5778550464785688721">Pilnīga MIDI ierīču pārvaldība</translation>
<translation id="578305955206182703">Dzintarkrāsa</translation>
<translation id="57838592816432529">Izslēgt skaņu</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>
+<translation id="5798290721819630480">Vai atmest izmaiņas?</translation>
<translation id="5798683403665926540">Mainīt sākumlapu Chrome iestatījumos</translation>
<translation id="5803412860119678065">Vai vēlaties aizpildīt lauku ar informāciju “<ph name="CARD_DETAIL" />”?</translation>
<translation id="5804241973901381774">Atļaujas</translation>
<translation id="5810442152076338065">Savienojums ar domēnu <ph name="DOMAIN" /> ir šifrēts, izmantojot novecojušu šifra komplektu.</translation>
<translation id="5813119285467412249">&amp;Pievienošanas atsaukuma atcelšana</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="5860033963881614850">Izsl.</translation>
<translation id="5863847714970149516">Nākamajā lapā var tikt mēģināts pieprasīt naudu</translation>
<translation id="5866257070973731571">Tālruņa numura pievienošana</translation>
<translation id="5869405914158311789">Šī vietne nav sasniedzama</translation>
<translation id="5869522115854928033">Saglabātās paroles</translation>
<translation id="5887400589839399685">Kartīte ir saglabāta</translation>
-<translation id="5893718151540690985">nosūtīt tīmekļa saskarņu sarakstu ar to veidiem un aparatūras adresēm</translation>
<translation id="5893752035575986141">Tiek pieņemtas kredītkartes.</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="5916664084637901428">Iesl.</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vai saglabāt kartes datus Google kontā?</translation>
<translation id="5922853866070715753">Gandrīz pabeigts</translation>
<translation id="5932224571077948991">Vietnē tiek rādītas traucējošas vai maldinošas reklāmas</translation>
-<translation id="5939518447894949180">Atiestatīt</translation>
<translation id="5946937721014915347">Notiek vietnes <ph name="SITE_NAME" /> atvēršana...</translation>
<translation id="5951495562196540101">Neizdevās reģistrēt, izmantojot patērētāja kontu (pieejama komplektā iekļauta licence).</translation>
<translation id="5967592137238574583">Kontaktinformācijas rediģēšana</translation>
@@ -791,6 +895,7 @@
<translation id="5975083100439434680">Tālināt</translation>
<translation id="5977489021191000276">Jūsu ierīci nepārvalda administrators.</translation>
<translation id="5977976211062815271">Šajā ierīcē</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nevar atvērt maksājumu lietotni</translation>
<translation id="5989320800837274978">Nav norādīti nedz fiksēti starpniekserveri, nedz .pac skripta URL.</translation>
<translation id="5990559369517809815">Paplašinājums ir bloķējis pieprasījumus serverim.</translation>
@@ -801,8 +906,8 @@
<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="6033927989869462158">nosūtīt aparatūras statistiku, piemēram, par centrālā procesora/RAM lietojumu</translation>
<translation id="6034000775414344507">Gaiši pelēka</translation>
+<translation id="6034283069659657473">10x14 (aploksne)</translation>
<translation id="6039846035001940113">Ja problēma joprojām pastāv, sazinieties ar vietnes īpašnieku.</translation>
<translation id="6040143037577758943">Aizvērt</translation>
<translation id="6044573915096792553">12. izmērs</translation>
@@ -811,10 +916,10 @@
<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="6058977677006700226">Vai vēlaties izmantot kartes visās savās ierīcēs?</translation>
<translation id="6059925163896151826">USB ierīces</translation>
-<translation id="6071091556643036997">Politikas veids nav derīgs.</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="6094273045989040137">Pievienot piezīmi</translation>
<translation id="610911394827799129">Jūsu Google kontam var būt citu veidu pārlūkošanas vēstures dati vietnē <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Informācija par instalētajiem paplašinājumiem un spraudņiem</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>
@@ -849,15 +954,21 @@
<translation id="6337133576188860026">Tiks atbrīvots mazāk nekā <ph name="SIZE" />. Dažas vietnes nākamajā apmeklējumā var ielādēt lēnāk.</translation>
<translation id="6337534724793800597">Filtrēt politikas pēc nosaukuma</translation>
<translation id="6358450015545214790">Ko tas nozīmē?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Iespējams, tiks pieprasīta maksa.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{vēl 1 ieteikums}zero{vēl # ieteikumi}one{vēl # ieteikums}other{vēl # ieteikumi}}</translation>
<translation id="6387754724289022810">Lai nākamreiz veiktu maksājumu ātrāk, saglabājiet kartes datus un norēķinu adresi savā Google kontā un šajā ierīcē.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Rediģēt grāmatzīmi</translation>
+<translation id="6406765186087300643">C0 (aploksne)</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="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="6434309073475700221">Atmest</translation>
+<translation id="6446163441502663861">Kahu (aploksne)</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>
@@ -870,11 +981,17 @@
<translation id="6508722015517270189">Restartējiet pārlūku Chrome</translation>
<translation id="6529602333819889595">&amp;Dzēšanas atsaukuma atcelšana</translation>
<translation id="6534179046333460208">Fiziskā tīmekļa ieteikumi</translation>
+<translation id="6556866813142980365">Atcelt atsaukšanu</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="6578796323535178455">C2 (aploksne)</translation>
<translation id="6579990219486187401">Gaiši rozā</translation>
+<translation id="6583674473685352014">B6 (aploksne)</translation>
+<translation id="6587923378399804057">Jūsu kopētā saite</translation>
+<translation id="6591833882275308647">Jūsu <ph name="DEVICE_TYPE" /> ierīce netiek pārvaldīta</translation>
<translation id="6596325263575161958">Šifrēšanas opcijas</translation>
<translation id="6604181099783169992">Kustību un gaismas sensori</translation>
+<translation id="6609880536175561541">Prc7 (aploksne)</translation>
<translation id="6624427990725312378">Kontaktinformācija</translation>
<translation id="6626291197371920147">Derīga kartes numura pievienošana</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> meklēšana</translation>
@@ -883,6 +1000,7 @@
<translation id="6644283850729428850">Šī politika ir izbeigta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nav}=1{No 1 vietnes (jūs netiksiet izrakstīts no sava Google konta)}zero{No # vietnēm (jūs netiksiet izrakstīts no sava Google konta)}one{No # vietnes (jūs netiksiet izrakstīts no sava Google konta)}other{No # vietnēm (jūs netiksiet izrakstīts no sava Google konta)}}</translation>
<translation id="6657585470893396449">Parole</translation>
+<translation id="6670613747977017428">Atpakaļ drošībā.</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>
@@ -890,12 +1008,15 @@
<translation id="671076103358959139">Reģistrācijas pilnvara:</translation>
<translation id="6711464428925977395">Starpniekserverī radās kļūda, vai arī adrese nav pareiza.</translation>
<translation id="6723740634201835758">Google kontā</translation>
+<translation id="6738516213925468394">Jūsu dati tika šifrēti, izmantojot jūsu <ph name="BEGIN_LINK" />sinhronizācijas ieejas frāzi<ph name="END_LINK" />šādā datumā: <ph name="TIME" />. Lai sāktu sinhronizāciju, ievadiet ieejas frāzi.</translation>
<translation id="674375294223700098">Nezināma servera sertifikāta kļūda.</translation>
<translation id="6744009308914054259">Kamēr tiek gaidīts savienojums, varat apmeklēt Lejupielādes, lai lasītu rakstu bezsaistē.</translation>
<translation id="6753269504797312559">Politikas vērtība</translation>
<translation id="6757797048963528358">Ierīce tika pārslēgta miega režīmā.</translation>
+<translation id="6768213884286397650">Hagaki (pastkarte)</translation>
<translation id="6778737459546443941">Neviens no jūsu vecākiem vēl nav to apstiprinājis</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Paplašinājumi</translation>
<translation id="679355240208270552">Politika ignorēta, jo noklusējuma meklēšana nav iespējota politikā.</translation>
<translation id="681021252041861472">Obligātais lauks</translation>
<translation id="6810899417690483278">Pielāgošanas ID</translation>
@@ -928,10 +1049,12 @@
<translation id="6965978654500191972">Ierīce</translation>
<translation id="6970216967273061347">Rajons</translation>
<translation id="6973656660372572881">Ir norādīti gan fiksēti starpniekserveri, gan .pac skripta URL.</translation>
+<translation id="6973932557599545801">Diemžēl nevaru palīdzēt. Lūdzu, turpiniet patstāvīgi.</translation>
<translation id="6979158407327259162">Google disks</translation>
<translation id="6979440798594660689">Izslēgt skaņu (noklusējums)</translation>
<translation id="6984479912851154518">Ja maksāšanai tiks izmantota ārējā lietojumprogramma, tiks aizvērts privātais režīms. Vai turpināt?</translation>
<translation id="6989763994942163495">Rādīt papildu iestatījumus...</translation>
+<translation id="6993898126790112050">6x9 (aploksne)</translation>
<translation id="6996312675313362352">Vienmēr tulkot šo valodu: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Šie naudas pieprasījumi var būt vienreizēji vai atkārtoti, un tie var nebūt uzreiz pamanāmi.</translation>
@@ -947,28 +1070,33 @@
<translation id="7108338896283013870">Slēpt</translation>
<translation id="7108819624672055576">Atļāva paplašinājums</translation>
<translation id="7111012039238467737">(derīgs)</translation>
+<translation id="7118618213916969306">Meklēt starpliktuves URL, <ph name="SHORT_URL" /></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="7135130955892390533">Rādīt statusu</translation>
<translation id="7138472120740807366">Piegādes veids</translation>
<translation id="7139724024395191329">Emirāti</translation>
+<translation id="7152423860607593928">Number-14 (aploksne)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavandas krāsa</translation>
-<translation id="7158980942472052083">Nederīgs URL. Vietrādim URL ir jābūt ar standarta shēmu.</translation>
<translation id="717330890047184534">GAIA ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Visiem pieprasījumiem uz serveri <ph name="ORIGIN" />tiek piemērota drošības politika. Taču tā vietā, lai iesniegtu politiku, serveris ir novirzījis pārlūku citur, un tas neļauj pārlūkam izpildīt jūsu pieprasījumu vietnei <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Saglabāt un aizpildīt maksājumu veidus</translation>
<translation id="7180611975245234373">Atsvaidzināt</translation>
<translation id="7182878459783632708">Nav iestatīta neviena politika</translation>
<translation id="7186367841673660872">Šī lapa ir tulkota no<ph name="ORIGINAL_LANGUAGE" />valodas<ph name="LANGUAGE_LANGUAGE" />valodā</translation>
<translation id="7192203810768312527">Tiks atbrīvota vieta: <ph name="SIZE" />. Iespējams, nākamajā apmeklējuma reizē dažas vietnes tiks ielādētas lēnāk.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administrators var redzēt:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> neatbilst drošības standartiem.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Uzziniet vairāk<ph name="END_LINK" /> par šo problēmu.</translation>
<translation id="7219179957768738017">Savienojums izmanto <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Notiek apstrāde</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Vietnē ir ļaunprātīga programmatūra</translation>
+<translation id="724766306220616965">Brīdinājumi, sarežģījumi</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="7251437084390964440">Tīkla konfigurācija neatbilst standartam ONC. Iespējams, konfigurācijas daļas netiks importētas.
Papildu informācija:
@@ -981,11 +1109,14 @@ Papildu informācija:
<translation id="7300012071106347854">Kobalta zila</translation>
<translation id="7302712225291570345">“<ph name="TEXT" />”</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="7313965965371928911"><ph name="BEGIN_LINK" />Drošas pārlūkošanas<ph name="END_LINK" /> brīdinājumi</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Savienojuma palīdzība</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Komandrinda</translation>
-<translation id="7365061714576910172">Eksportēt Linux formātā</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>
@@ -993,6 +1124,7 @@ Papildu informācija:
<translation id="7381288752349550461">Pārvaldītas sesijas ignorēšana</translation>
<translation id="7390545607259442187">Kartes apstiprināšana</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Jūsu <ph name="DEVICE_NAME" /> ierīce tiek pārvaldīta</translation>
<translation id="7407424307057130981">&lt;p&gt;Šī kļūda tiek rādīta, ja Windows datorā ir instalēta Superfish programmatūra.&lt;/p&gt;
&lt;p&gt;Lai īslaicīgi atspējotu šo programmatūru un piekļūtu tīmeklim, veiciet tālāk minētās darbības. Jums būs nepieciešamas administratora privilēģijas.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1135,7 @@ Papildu informācija:
&lt;li&gt;Noklikšķiniet uz &lt;strong&gt;Lietot&lt;/strong&gt;, pēc tam noklikšķiniet uz &lt;strong&gt;Labi&lt;/strong&gt;.
&lt;li&gt;Apmeklējiet &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome palīdzības centru&lt;/a&gt;, lai uzzinātu, kā neatgriezeniski noņemt programmatūru no datora.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> pārvaldība</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Pārvaldīt paroles…</translation>
<translation id="7419106976560586862">Profila ceļš</translation>
<translation id="7437289804838430631">Pievienot kontaktinformāciju</translation>
@@ -1012,22 +1144,24 @@ Papildu informācija:
<translation id="7442725080345379071">Gaiši oranža</translation>
<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="7449109375006139765">sūtīt sistēmas žurnālus pārvaldības serverim</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="7460618730930299168">Pārmeklēšana atšķiras no jūsu atlasītās. Vai vēlaties turpināt?</translation>
<translation id="7473891865547856676">Nē, paldies!</translation>
-<translation id="7475525192983021547">nosūtīt laika periodus, kuros lietotājs aktīvi izmanto ierīci</translation>
<translation id="7481312909269577407">Pārsūtīt</translation>
<translation id="7485870689360869515">Dati netika atrasti.</translation>
+<translation id="7498234416455752244">Turpināt rediģēšanu</translation>
<translation id="7508255263130623398">Atgrieztais politikas ierīces ID ir tukšs vai neatbilst pašreizējam ierīces ID.</translation>
<translation id="7508870219247277067">Avokado zaļa</translation>
<translation id="7511955381719512146">Iespējams, izmantotajā Wi-Fi tīklā tiks pieprasīts apmeklēt vietni <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (aploksne)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Jūsu savienojums ar šo vietni nav privāts.</translation>
+<translation id="7535087603100972091">Vērtība</translation>
<translation id="7537536606612762813">Obligāti</translation>
+<translation id="7538364083937897561">A2 (aploksne)</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>
@@ -1036,8 +1170,8 @@ Papildu informācija:
<translation id="7552846755917812628">Izmantojiet tālāk sniegtos padomus.</translation>
<translation id="7554791636758816595">Jauna cilne</translation>
<translation id="7564049878696755256">Varat zaudēt piekļuvi savam <ph name="ORG_NAME" /> kontam, vai jūsu identitāte var tikt nozagta. Chrome iesaka nekavējoties nomainīt paroli.</translation>
-<translation id="7566125604157659769">Jūsu nokopētais teksts</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="7568105740864181217">Šo pārlūku pārvalda uzņēmums, skola vai cita organizācija. Jūsu administrators var attālināti mainīt jūsu pārlūka iestatījumus. Darbību šajā ierīcē var pārvaldīt arī ārpus Chrome. <ph name="BEGIN_LINK" />Uzzināt vairāk<ph name="END_LINK" /></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>
@@ -1048,6 +1182,7 @@ Papildu informācija:
<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="7633909222644580952">Veiktspējas dati un avāriju pārskati</translation>
<translation id="7637571805876720304">Vai noņemt kredītkarti no pārlūka Chromium?</translation>
<translation id="7639968568612851608">Tumši pelēka</translation>
<translation id="765676359832457558">Slēpt papildu iestatījumus...</translation>
@@ -1057,9 +1192,11 @@ Papildu informācija:
<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="7676643023259824263">Meklēt starpliktuves tekstu <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Mainīt meklētājprogrammu</translation>
<translation id="7682287625158474539">Piegāde</translation>
<translation id="7687186412095877299">Aizpilda maksājumu veidlapas, izmantojot saglabātos maksājuma veidus</translation>
+<translation id="7697066736081121494">Prc8 (aploksne)</translation>
<translation id="769721561045429135">Pašlaik dažas kartes varat izmantot tikai šajā ierīcē. Lai pārskatītu kartes, noklikšķiniet uz Turpināt.</translation>
<translation id="7699293099605015246">Raksti pašlaik nav pieejami</translation>
<translation id="7701040980221191251">Neviens</translation>
@@ -1071,11 +1208,13 @@ Papildu informācija:
<translation id="774634243536837715">Bloķēts bīstams saturs</translation>
<translation id="7752995774971033316">Netiek pārvaldīts</translation>
<translation id="7755287808199759310">Lai atbloķētu, vēsieties pie vecāka</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Iespējams, savienojumu ir bloķējis ugunsmūris vai pretvīrusu programmatūra.</translation>
<translation id="7759163816903619567">Parādāmais domēns:</translation>
<translation id="7761701407923456692">Servera sertifikāts neatbilst URL.</translation>
<translation id="7763386264682878361">Maksājumu manifestu parsētājs</translation>
<translation id="7764225426217299476">Pievienot adresi</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektūra</translation>
<translation id="7791543448312431591">Pievienot</translation>
<translation id="7793809570500803535">Tīmekļa lapa vietnē <ph name="SITE" /> var īslaicīgi nebūt pieejama, vai tā var būt pārvietota uz jaunu tīmekļa adresi.</translation>
@@ -1087,8 +1226,8 @@ Papildu informācija:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Vai noņemt veidlapas ieteikumu no pārlūka Chrome?</translation>
<translation id="7815407501681723534">Meklējot pēc virknes “<ph name="SEARCH_STRING" />”, tika atrasti <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /></translation>
-<translation id="7818867226424560206">Politiku pārvaldība</translation>
<translation id="782886543891417279">Iespējams, izmantotajā Wi-Fi tīklā (<ph name="WIFI_NAME" />) tiks pieprasīts apmeklēt pieteikšanās lapu.</translation>
+<translation id="7836231406687464395">Postfix (aploksne)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nav}=1{1 lietotne (<ph name="EXAMPLE_APP_1" />)}=2{2 lietotnes (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}zero{# lietotnes (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}one{# lietotne (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# lietotnes (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Tomēr jūs neesat neredzams. Pārlūkojot inkognito režīmā, jūsu pārlūkošanas darbības netiek slēptas no jūsu darba devēja, interneta pakalpojumu sniedzēja vai apmeklētajām vietnēm.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1236,7 @@ Papildu informācija:
<translation id="7878562273885520351">Iespējams, jūsu parole ir apdraudēta</translation>
<translation id="7882421473871500483">Brūna</translation>
<translation id="7887683347370398519">Pārbaudiet CVC kodu un mēģiniet vēlreiz.</translation>
-<translation id="7893255318348328562">Sesijas nosaukums</translation>
+<translation id="7904208859782148177">C3 (aploksne)</translation>
<translation id="79338296614623784">Ievadiet derīgu tālruņa numuru</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Derīguma termiņš: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1246,25 @@ Papildu informācija:
<translation id="7951415247503192394">(32 bitu)</translation>
<translation id="7956713633345437162">Mobilās grāmatzīmes</translation>
<translation id="7961015016161918242">Nekad</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Pārlūkprogramma</translation>
<translation id="8009225694047762179">Pārvaldīt paroles</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Šī karte un tās norēķinu adrese tiks saglabāta. Jūs varēsiet to izmantot, kad būsiet pierakstījies kontā <ph name="USER_EMAIL" />.}zero{Šīs kartes un to norēķinu adreses tiks saglabātas. Jūs varēsiet tās izmantot, kad būsiet pierakstījies kontā <ph name="USER_EMAIL" />.}one{Šīs kartes un to norēķinu adreses tiks saglabātas. Jūs varēsiet tās izmantot, kad būsiet pierakstījies kontā <ph name="USER_EMAIL" />.}other{Šīs kartes un to norēķinu adreses tiks saglabātas. Jūs varēsiet tās izmantot, kad būsiet pierakstījies kontā <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Šī lapas saturs ir šādā valodā: <ph name="SOURCE_LANGUAGE" />. Vai tulkot šādā valodā: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pildspalva</translation>
+<translation id="8037117624646282037">Kas nesen lietoja ierīci</translation>
<translation id="8037357227543935929">Vaicāt (pēc noklusējuma)</translation>
<translation id="803771048473350947">Fails</translation>
<translation id="8041089156583427627">Sūtīt atsauksmes</translation>
<translation id="8041940743680923270">Izmantot globālo noklusējumu (Vaicāt)</translation>
<translation id="8042918947222776840">Izvēlēties saņemšanas veidu</translation>
<translation id="8057711352706143257">Programmatūra <ph name="SOFTWARE_NAME" /> nav pareizi konfigurēta. Atinstalējot programmatūru <ph name="SOFTWARE_NAME" />, parasti problēma tiek novērsta. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Jūsu ierīcē ir veikta šāda konfigurācija:</translation>
+<translation id="8066955247577885446">Diemžēl radās problēma.</translation>
+<translation id="8074253406171541171">10x13 (aploksne)</translation>
<translation id="8078141288243656252">Pagrieztiem dokumentiem nevar pievienot piezīmes</translation>
<translation id="8079031581361219619">Vai atkārtoti ielādēt vietni?</translation>
<translation id="8088680233425245692">Rakstu neizdevās skatīt.</translation>
@@ -1130,11 +1273,12 @@ Papildu informācija:
<translation id="8091372947890762290">Aktivizācija vēl nav apstiprināta serverī.</translation>
<translation id="8092774999298748321">Tumši violets</translation>
<translation id="8094917007353911263">Iespējams, izmantotajā tīklā tiks pieprasīts apmeklēt vietni <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Nederīgās kartes tika noņemtas</translation>
<translation id="8103161714697287722">Maksājuma veids</translation>
<translation id="8118489163946903409">Maksājuma veids</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> pārvalda domēns <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Programmatūra <ph name="SOFTWARE_NAME" /> netika pareizi instalēta datorā vai tīklā. Lūdziet IT administratoram atrisināt šo problēmu.</translation>
-<translation id="8130693978878176684">Es vairs nevaru palīdzēt. Lūdzu, turpiniet patstāvīgi.</translation>
<translation id="8131740175452115882">Apstiprināt</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>
@@ -1144,8 +1288,11 @@ Papildu informācija:
<translation id="8197543752516192074">Tulkot lapu</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="8202370299023114387">Konflikts</translation>
+<translation id="8206978196348664717">Prc4 (aploksne)</translation>
<translation id="8211406090763984747">Savienojums ir drošs</translation>
<translation id="8218327578424803826">Piešķirtā atrašanās vieta:</translation>
+<translation id="8220146938470311105">C7/C6 (aploksne)</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="8238581221633243064">Atvērt lapu jaunā inkognito režīma cilnē</translation>
@@ -1157,14 +1304,16 @@ Papildu informācija:
<translation id="825929999321470778">Rādīt visas saglabātās paroles</translation>
<translation id="8261506727792406068">Dzēst</translation>
<translation id="8267698848189296333">Notiek pierakstīšanās lietotāja <ph name="USERNAME" /> kontā</translation>
+<translation id="8278457561961988242">Šo pārlūku pārvalda domēns <ph name="ENROLLMENT_DOMAIN" />. Jūsu administrators var attālināti mainīt pārlūka iestatījumus. Darbību šajā ierīcē var pārvaldīt arī ārpus Chrome. <ph name="BEGIN_LINK" />Uzzināt vairāk<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Pierakstīties</translation>
<translation id="8288807391153049143">Rādīt sertifikātu</translation>
<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="8298115750975731693">Iespējams, izmantotajā Wi-Fi tīklā (<ph name="WIFI_NAME" />) tiks pieprasīts apmeklēt vietni <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Tulkošana neizdevās, jo radās problēma ar tīkla savienojumu.</translation>
-<translation id="8311129316111205805">Ielādēt sesiju</translation>
<translation id="8332188693563227489">Piekļuve vietnei <ph name="HOST_NAME" /> tika noraidīta</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1182,7 +1331,6 @@ Papildu informācija:
<translation id="8416694386774425977">Tīkla konfigurācija nav derīga, un to nevarēja importēt.
Papildu informācija:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Ierīci pārvalda <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" />, <ph name="SECOND_LABEL" />, <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Mainīt</translation>
<translation id="8428213095426709021">Iestatījumi</translation>
@@ -1210,9 +1358,11 @@ Papildu informācija:
<translation id="860043288473659153">Bankas kartes īpašnieka vārds</translation>
<translation id="861775596732816396">4. izmērs</translation>
<translation id="8620436878122366504">Jūsu vecāki vēl nav to apstiprinājuši</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Saglabāt šo karti šajā ierīcē</translation>
<translation id="8663226718884576429">Pasūtījuma kopsavilkums, <ph name="TOTAL_LABEL" />, citi dati</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, atbilde, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Jūsu savienojums ar <ph name="DOMAIN" /> nav kodēts.</translation>
<translation id="8718314106902482036">Maksājums nav pabeigts</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, meklēšanas ieteikums</translation>
@@ -1226,6 +1376,7 @@ Papildu informācija:
<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="8763927697961133303">USB ierīce</translation>
<translation id="8768895707659403558">Lai kartes varētu izmantot visās ierīcēs, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Atcelt dzēšanas atsaukšanu</translation>
<translation id="8792621596287649091">Varat zaudēt piekļuvi savam <ph name="ORG_NAME" /> kontam, vai jūsu identitāte var tikt nozagta. Chromium iesaka nekavējoties nomainīt paroli.</translation>
<translation id="8800988563907321413">Šeit tiks parādīti funkcijas Tuvumā ieteikumi</translation>
@@ -1236,10 +1387,12 @@ Papildu informācija:
<translation id="885730110891505394">Kopīgošana ar Google</translation>
<translation id="8858065207712248076">Chrome iesaka atiestatīt jūsu <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> paroli, ja izmantojāt to citās vietnēs.</translation>
<translation id="8866481888320382733">Parsējot politikas iestatījumus, radās kļūda.</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nesen aizvērtas</translation>
<translation id="8874824191258364635">Ievadiet derīgu kartes numuru</translation>
<translation id="8891727572606052622">Nederīgs starpniekservera režīms.</translation>
<translation id="8903921497873541725">Tuvināt</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Vārda pievienošana</translation>
@@ -1247,13 +1400,13 @@ Papildu informācija:
<translation id="894185898663964645">Administrators ir konfigurējis pielāgotus saknes sertifikātus, kas, iespējams, ļauj administratoram skatīt apmeklēto vietņu saturu.</translation>
<translation id="8943282376843390568">Laima zaļa</translation>
<translation id="8957210676456822347">Caurlaides lapas autorizācija</translation>
+<translation id="8966619695390250636">Vai bija domāts?</translation>
<translation id="8968766641738584599">Saglabāt karti</translation>
<translation id="8971063699422889582">Servera sertifikātam ir beidzies derīguma termiņš.</translation>
<translation id="8975012916872825179">Iekļauta tāda informācija kā tālruņa numuri, e-pasta un piegādes adreses</translation>
<translation id="8978053250194585037">Google drošā pārlūkošana nesen <ph name="BEGIN_LINK" />konstatēja pikšķerēšanu<ph name="END_LINK" /> vietnē <ph name="SITE" />. Pikšķerēšanas vietnes uzdodas par citām vietnēm, lai jūs maldinātu.</translation>
<translation id="8983003182662520383">Adreses un maksājumu veidi, kuros tiek izmantots pakalpojums Google Pay</translation>
<translation id="8987927404178983737">Mēnesis</translation>
-<translation id="8988408250700415532">Diemžēl radās problēma. Savu pasūtījumu varat pabeigt vietnē.</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>
@@ -1263,6 +1416,7 @@ Papildu informācija:
<translation id="9011424611726486705">Atveriet vietnes iestatījumus</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(nederīgs)</translation>
<translation id="9035022520814077154">Drošības kļūda</translation>
<translation id="9038649477754266430">Ieteikumu pakalpojuma izmantošana ātrākai lapu ielādei</translation>
@@ -1274,11 +1428,11 @@ Papildu informācija:
<translation id="9065745800631924235">Teksta “<ph name="TEXT" />” meklēšana no vēstures</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="9076630408993835509">Šo pārlūku nepārvalda uzņēmums vai cita organizācija. Darbību šajā ierīcē var pārvaldīt ārpus pārlūka Chrome. <ph name="BEGIN_LINK" />Uzzināt vairāk<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Nepieciešama plašāka informācija.</translation>
<translation id="9080712759204168376">Pasūtījuma kopsavilkums</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>
<translation id="9106062320799175032">Norēķinu adreses pievienošana</translation>
-<translation id="9110718169272311511">Google asistents pārlūkprogrammā Chrome ir pieejams ekrāna apakšdaļā.</translation>
<translation id="9114524666733003316">Notiek kartes apstiprināšana...</translation>
<translation id="9128870381267983090">Izveidot savienojumu ar tīklu</translation>
<translation id="9137013805542155359">Rādīt oriģinālo</translation>
@@ -1287,6 +1441,7 @@ Papildu informācija:
<translation id="9148507642005240123">&amp;Atsaukt labojumu</translation>
<translation id="9154194610265714752">Atjaunināts</translation>
<translation id="9157595877708044936">Notiek uzstādīšana...</translation>
+<translation id="9158625974267017556">C6 (aploksne)</translation>
<translation id="9168814207360376865">Atļaut vietnēm pārbaudīt, vai jums ir saglabāti maksājumu veidi</translation>
<translation id="9169664750068251925">Vienmēr bloķēt šajā vietnē</translation>
<translation id="9170848237812810038">&amp;Atsaukt</translation>
@@ -1301,10 +1456,12 @@ Papildu informācija:
<translation id="9219103736887031265">Attēli</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">NOTĪRĪT VEIDLAPU</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Varat zaudēt piekļuvi savam Google kontam. Chromium iesaka nekavējoties nomainīt paroli. Jums tiks lūgts pierakstīties.</translation>
<translation id="939736085109172342">Jauna mape</translation>
<translation id="945855313015696284">Pārbaudiet tālāk sniegto informāciju un dzēsiet visas nederīgās kartītes.</translation>
<translation id="951104842009476243">Atbalstītās debetkartes un priekšapmaksas kartes</translation>
+<translation id="958202389743790697">Bloķēts, pamatojoties uz <ph name="ORIGIN" /> drošības politiku.</translation>
<translation id="962484866189421427">Šis saturs jūsu ierīcē var mēģināt instalēt maldinošas lietotnes, kas tiek uzdodas par cita veida saturu, vai vākt datus, kas var tikt izmantoti jūsu izsekošanai. <ph name="BEGIN_LINK" />Tāpat rādīt<ph name="END_LINK" />.</translation>
<translation id="969892804517981540">Oficiālā Uzbūve</translation>
<translation id="973773823069644502">Pievienot piegādes adresi</translation>
@@ -1313,6 +1470,7 @@ Papildu informācija:
<translation id="984275831282074731">Maksājumu veidi</translation>
<translation id="985199708454569384">&lt;p&gt;Šis kļūdas ziņojums tiek rādīts, ja datora vai mobilās ierīces datums un laiks nav precīzs.&lt;/p&gt;
&lt;p&gt;Lai novērstu šo kļūdu, atveriet ierīces pulksteni. Iestatiet pareizu datumu un laiku.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Attīstītāja konstrukcija</translation>
<translation id="989988560359834682">Rediģēt adresi</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ml.xtb b/chromium/components/strings/components_strings_ml.xtb
index 6f5d7a05d2e..80dc02880b2 100644
--- a/chromium/components/strings/components_strings_ml.xtb
+++ b/chromium/components/strings/components_strings_ml.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ml">
-<translation id="1005145902654145231">സെഷന്റെ പേരുമാറ്റുന്നതിൽ പരാജയപ്പെട്ടു.</translation>
<translation id="1008557486741366299">ഇപ്പോഴല്ല</translation>
<translation id="1010200102790553230">പേജ് പിന്നീട് ലോഡ് ചെയ്യുക</translation>
<translation id="1015730422737071372">കൂടുതൽ വിശദാംശങ്ങൾ നൽകുക</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">അജ്ഞാത നാമം</translation>
<translation id="1050038467049342496">മറ്റ് ആപ്പുകൾ അടയ്‌ക്കുക</translation>
<translation id="1055184225775184556">&amp;ചേർത്തത് പഴയപടിയാക്കുക</translation>
+<translation id="1056898198331236512">മുന്നറിയിപ്പ്</translation>
<translation id="1058479211578257048">കാർഡുകൾ സംരക്ഷിക്കുന്നു...</translation>
<translation id="10614374240317010">ഒരിക്കലും സംരക്ഷിച്ചില്ല</translation>
+<translation id="1062160989074299343">Prc10 (എൻവലപ്പ്)</translation>
<translation id="106701514854093668">ഡെസ്‌ക്‌ടോപ്പ് ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="1074497978438210769">സുരക്ഷിതമല്ല</translation>
<translation id="1080116354587839789">അനുയോജ്യമായ വീതിയിലാക്കുക</translation>
+<translation id="1086953900555227778">സൂചിക-5x8</translation>
<translation id="1088860948719068836">കാർഡിൽ പേര് ചേർക്കുക</translation>
<translation id="1089439967362294234">പാസ്‌വേഡ് മാറ്റുക</translation>
<translation id="109743633954054152">Chrome ക്രമീകരണത്തിൽ പാസ്‌വേഡ് മാനേജ് ചെയ്യുക</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">വെബ്‌സൈറ്റുകൾ അവയുടെ സുരക്ഷ അപ്‌ഡേറ്റ് ചെയ്യുന്ന സമയത്ത് പൊതുവെ മുന്നറിയിപ്പുകൾ കാണിച്ചേക്കാം. ഇത് താമസിയാതെ മെച്ചപ്പെടും.</translation>
<translation id="1126551341858583091">ലോക്കൽ സ്‌‌റ്റോറേജിന്റെ വലുപ്പം <ph name="CRASH_SIZE" /> ആണ്.</translation>
<translation id="112840717907525620">നയ കാഷെ ശരി</translation>
+<translation id="1131264053432022307">നിങ്ങൾ പകർത്തിയ ചിത്രം</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> അപ്രതീക്ഷിതമായി കണക്ഷൻ അടച്ചു.</translation>
<translation id="1161325031994447685">Wi-Fi-ലേക്ക് വീണ്ടും കണക്റ്റുചെയ്യുന്നു</translation>
<translation id="1165039591588034296">പിശക്</translation>
-<translation id="1173894706177603556">പേരുമാറ്റുക</translation>
<translation id="1175364870820465910">&amp;അച്ചടിക്കൂ...</translation>
<translation id="1181037720776840403">നീക്കംചെയ്യൂ</translation>
<translation id="1197088940767939838">ഓറഞ്ച്</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">നിങ്ങളുടെ ഉപകരണത്തിൻ്റെ പേര്</translation>
<translation id="124116460088058876">കൂടുതൽ ഭാഷകൾ</translation>
<translation id="1250759482327835220">അടുത്ത പ്രാവശ്യം കൂടുതൽ വേഗത്തിൽ പണമടയ്ക്കാൻ, നിങ്ങളുടെ Google അക്കൗണ്ടിൽ കാർഡ്, പേര്, ബില്ലിംഗ് വിലാസം എന്നിവ സംരക്ഷിക്കുക.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (സമന്വയിപ്പിച്ചു)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">കമാൻഡ്-ലൈൻ വ്യതിയാനങ്ങൾ</translation>
<translation id="129553762522093515">സമീപകാലത്ത് അടച്ചവ</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />നിങ്ങളുടെ കുക്കികൾ മായ്‌ക്കുന്നത് പരീക്ഷിക്കുക<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">തിരഞ്ഞെടുത്ത സെഷൻ നിലവിലില്ല.</translation>
+<translation id="1320233736580025032">Prc1 (എൻവലപ്പ്)</translation>
+<translation id="132301787627749051">ക്ലിപ്പ്ബോർഡ് ചിത്രത്തിനായി തിരയുക</translation>
<translation id="1323433172918577554">കൂടുതൽ കാണിക്കുക</translation>
<translation id="132390688737681464">വിലാസങ്ങൾ സംരക്ഷിച്ച് സ്വമേധയാ പൂരിപ്പിക്കുക</translation>
<translation id="1333989956347591814">നിങ്ങളുടെ ആക്‌റ്റിവിറ്റി ഇനിപ്പറയുന്നവയ്‌ക്ക് <ph name="BEGIN_EMPHASIS" />തുടർന്നും ദൃശ്യമായേക്കും<ph name="END_EMPHASIS" />:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">പിക്കപ്പ് വിലാസം</translation>
<translation id="1348198688976932919">നിങ്ങൾ പോകുന്ന സൈറ്റിൽ അപകടകരമായ ആപ്പുകൾ ഉണ്ട്</translation>
<translation id="1348779747280417563">പേര് സ്ഥിരീകരിക്കുക</translation>
+<translation id="1357195169723583938">അടുത്തിടെ ഉപകരണം ഉപയോഗിച്ചവരും ഉപയോഗിച്ച സമയവും</translation>
+<translation id="1364822246244961190">ഈ നയം ബ്ലോക്ക് ചെയ്‌തിരിക്കുന്നു, ഇതിൻ്റെ മൂല്യം അവഗണിക്കപ്പെടും.</translation>
<translation id="1374468813861204354">നിർദ്ദേശങ്ങൾ</translation>
+<translation id="1374692235857187091">സൂചിക-4x6 (പോസ്‌റ്റ് കാർഡ്)</translation>
<translation id="1375198122581997741">പതിപ്പിനെ കുറിച്ച്</translation>
<translation id="1376836354785490390">കുറച്ച് കാണിക്കുക</translation>
<translation id="1377321085342047638">കാർഡ് നമ്പർ</translation>
<translation id="138218114945450791">ഇളം നീല</translation>
+<translation id="1382194467192730611">നിങ്ങളുടെ അഡ്‌‌മിനിസ്‌ട്രേറ്റർ USB ഉപകരണം അനുവദിച്ചു</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ഡാറ്റയൊന്നും അയച്ചിട്ടില്ല.</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> സൈറ്റിൻ്റെ എല്ലാ അഭ്യർത്ഥനകളിലേക്കും ഒരു സുരക്ഷാ നയം ബാധകമാക്കുമെന്ന് ഇത് അഭ്യർത്ഥിച്ചിരിക്കുന്നു, ഈ നയം നിലവിൽ സൈറ്റ് സുരക്ഷിതമല്ലാതാക്കുകയും ചെയ്യുന്നു.</translation>
<translation id="1405567553485452995">ഇളം പച്ച</translation>
<translation id="1407135791313364759">എല്ലാം തുറക്കുക</translation>
<translation id="1413809658975081374">സ്വകാര്യ പിശക്</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">അതെ</translation>
<translation id="1430915738399379752">അച്ചടിക്കുക</translation>
<translation id="1455413310270022028">ഇറേസർ</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">കൂടുതൽ‍ കാണിക്കുക</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">ഷിപ്പിംഗ് വിലാസം തിരഞ്ഞെടുക്കുക</translation>
+<translation id="1492194039220927094">നയങ്ങൾ പുഷ് ചെയ്യൽ:</translation>
<translation id="1501859676467574491">നിങ്ങളുടെ Google അക്കൗണ്ടിൽ നിന്ന് കാർഡുകൾ കാണിക്കുക</translation>
-<translation id="1506687042165942984">ഈ പേജിന്റെ സംരക്ഷിച്ച (അതായത്. അത് കാലഹരണപ്പെട്ടതായി അറിയിക്കുന്നു) പകർപ്പ് കാണിക്കുക</translation>
<translation id="1507202001669085618">&lt;p&gt;ഓൺലൈൻ ആകുന്നതിന് സൈൻ ഇൻ ചെയ്യേണ്ടി വരുന്ന ഒരു വൈഫൈ പോർട്ടലാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, നിങ്ങൾ ഈ പിശക് കാണും.&lt;/p&gt;
&lt;p&gt;പിശക് പരിഹരിക്കാൻ, നിങ്ങൾ തുറക്കാൻ ശ്രമിക്കുന്ന പേജിൽ &lt;strong&gt;കണക്‌റ്റ് ചെയ്യുക&lt;/strong&gt; ക്ലിക്ക് ചെയ്യുക.&lt;/p&gt;</translation>
<translation id="1517433312004943670">ഫോൺ നമ്പർ ആവശ്യമാണ്</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">ബിൽഡ് തീയതി</translation>
<translation id="1521655867290435174">Google ഷീറ്റ്</translation>
<translation id="1527263332363067270">കണക്ഷനുവേണ്ടി കാക്കുന്നു…</translation>
+<translation id="1529521330346880926">10x15 (എൻവലപ്പ്)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">ഈ പേജ് പറയുന്നത്:</translation>
<translation id="153384715582417236">ഇപ്പോൾ ഇത്രമാത്രം ലഭ്യം</translation>
<translation id="154408704832528245">ഡെലിവറി നൽകേണ്ട വിലാസം തിരഞ്ഞെടുക്കുക</translation>
<translation id="1549470594296187301">ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ JavaScript പ്രവർത്തനക്ഷമമാക്കിയിരിക്കണം.</translation>
+<translation id="155039086686388498">എഞ്ചിനീയറിംഗ്-D</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="1569487616857761740">കാലഹരണപ്പെടുന്ന തീയതി നൽകുക</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">ഈ വെബ്‌പേജ് പ്രദർശിപ്പിക്കുമ്പോൾ എന്തോ കുഴപ്പം സംഭവിച്ചു.</translation>
<translation id="1592005682883173041">പ്രാദേശിക ഡാറ്റ ആക്‌സസ്സ്</translation>
<translation id="1594030484168838125">തിരഞ്ഞെടുക്കുക</translation>
<translation id="161042844686301425">സിയാൻ</translation>
-<translation id="1618822247301510817">നിങ്ങൾ പകർത്തിയ ചിത്രം</translation>
<translation id="1620510694547887537">ക്യാമറ</translation>
<translation id="1623104350909869708">കൂടുതൽ ഡയലോഗുകൾ സൃഷ്‌ടിക്കുന്നതിൽ നിന്നും ഈ പേജിനെ തടയുക</translation>
+<translation id="16338877384480380">ആര്‍ക്കിടെക്ച്ചര്‍-B</translation>
<translation id="1634051627998691300">സെഷൻ അവസാനിപ്പിക്കുക</translation>
<translation id="1639239467298939599">ലോഡുചെയ്യുന്നു</translation>
<translation id="1640180200866533862">ഉപയോക്തൃ നയങ്ങൾ</translation>
@@ -133,8 +148,10 @@
<translation id="1676269943528358898">നിങ്ങളുടെ വിവരങ്ങൾ പരിരക്ഷിക്കാൻ സാധാരണയായി <ph name="SITE" />, എൻക്രിപ്‌ഷൻ ഉപയോഗിക്കുന്നു. ഇപ്പോൾ <ph name="SITE" /> സൈറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്യാൻ Google Chrome ശ്രമിച്ചപ്പോൾ, അസാധാരണമായതും തെറ്റായതുമായ ക്രെഡൻഷ്യലുകൾ വെബ്‌സൈറ്റ് തിരികെ അയച്ചു. ഒരു ആക്രമണകാരി, <ph name="SITE" /> എന്നതായി ഭാവിക്കാൻ ശ്രമിക്കുമ്പോഴോ Wi-Fi സൈൻ ഇൻ സ്‌ക്രീൻ, കണക്ഷനെ തടസ്സപ്പെടുത്തുമ്പോഴോ ആണ് ഇങ്ങനെ സംഭവിക്കാനിടയുള്ളത്. ഏതെങ്കിലും ഡാറ്റ കൈമാറുന്നതിനുമുമ്പ് Google Chrome കണക്ഷൻ അവസാനിപ്പിച്ചതിനാൽ, നിങ്ങളുടെ വിവരങ്ങൾ തുടർന്നും സുരക്ഷിതമായിരിക്കും.</translation>
<translation id="168841957122794586">സെർവർ സർട്ടിഫിക്കറ്റിൽ ഒരു ദുർബലമായ ഗൂഢഭാഷ കീ ഉൾപ്പെടുന്നു.</translation>
<translation id="1697532407822776718">എല്ലാം സജ്ജമായിക്കഴിഞ്ഞു!</translation>
+<translation id="1703835215927279855">ലെറ്റർ</translation>
<translation id="1706954506755087368">{1,plural, =1{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് ഇന്നലെ മുതൽ സാധുവല്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.}other{ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് # ദിവസം മുതൽ സാധുവായിരിക്കില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">അനോട്ടേറ്റ് ചെയ്യാനാവുന്നതിലും വളരെ വലുതാണ് ഈ ഡോക്യുമെൻ്റ്</translation>
<translation id="1721312023322545264">ഈ സൈറ്റ് സന്ദർശിക്കാൻ നിങ്ങൾക്ക് <ph name="NAME" /> എന്നയാളിൽ നിന്നുള്ള അനുമതി ആവശ്യമാണ്</translation>
<translation id="1721424275792716183">* ഫീൽഡ് ആവശ്യമാണ്</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">സിസ്റ്റം അഡ്‌മിനെ ബന്ധപ്പെടാൻ ശ്രമിക്കുക.</translation>
<translation id="1740951997222943430">കാലഹരണപ്പെടുന്ന ശരിയായ മാസം നല്‍കുക</translation>
<translation id="1743520634839655729">അടുത്ത പ്രാവശ്യം കൂടുതൽ വേഗത്തിൽ പണമടയ്ക്കാൻ, നിങ്ങളുടെ Google അക്കൗണ്ടിലും ഈ ഉപകരണത്തിലും ഈ കാർഡ്, പേര്, ബില്ലിംഗ് വിലാസം എന്നിവ സംരക്ഷിക്കുക.</translation>
+<translation id="1745880797583122200">നിങ്ങളുടെ ബ്രൗസർ മാനേജ് ചെയ്യപ്പെട്ടിരിക്കുന്നു</translation>
<translation id="17513872634828108">ഓപ്പൺ ടാബുകൾ</translation>
<translation id="1753706481035618306">പേജ് നമ്പർ</translation>
<translation id="1763864636252898013">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിനെ നിങ്ങളുടെ ഉപകരണത്തിന്റെ ഓപ്പറേറ്റിംഗ് സിസ്‌റ്റത്തിന് പരിചയമില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">നിങ്ങളുടെ സമന്വയ പാസ്‌ഫ്രേസ് ദയവായി അപ്‌ഡേറ്റ് ചെയ്യുക.</translation>
<translation id="1787142507584202372">നിങ്ങൾ നിലവിൽ തുറന്നിട്ടുള്ള ടാബുകൾ ഇവിടെ ദൃശ്യമാകും</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">കാർഡ് ഉടമയുടെ പേര്</translation>
<translation id="1821930232296380041">അസാധുവായ അഭ്യർത്ഥന അല്ലെങ്കിൽ അഭ്യർത്ഥനാ പാരാമീറ്ററുകൾ</translation>
+<translation id="1822540298136254167">നിങ്ങൾ സന്ദർശിക്കുന്ന വെബ്‌സൈറ്റുകളും അവയിൽ ചെലവഴിക്കുന്ന സമയവും</translation>
<translation id="1826516787628120939">പരിശോധിക്കുന്നു</translation>
<translation id="1834321415901700177">ഈ സൈറ്റിൽ ദോഷകരമായ പ്രോഗ്രാമുകൾ അടങ്ങിയിരിക്കുന്നു</translation>
<translation id="1839551713262164453">നയ മൂല്യങ്ങളുടെ സാധൂകരണം പിശകുകളോടെ പരാജയപ്പെട്ടു</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Chrome-ന്‍റെ ബ്രൗസിംഗ് ചരിത്ര ഡാറ്റ മായ്‌ക്കുക</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{കൂടാതെ 1 കൂടി}other{എന്നിവയും # എണ്ണവും കൂടി}}</translation>
<translation id="2003709556000175978">നിങ്ങളുടെ പാസ്‌വേഡ് ഇപ്പോൾ തന്നെ റീസെറ്റ് ചെയ്യുക</translation>
+<translation id="20053308747750172">സെർവർ ഉപയോഗിച്ച് നിങ്ങൾ പോകുന്ന <ph name="ORIGIN" /> സൈറ്റ്, അതിൻ്റെ എല്ലാ അഭ്യർത്ഥനകളിലേക്കും ഒരു സുരക്ഷാ നയം ബാധകമാക്കുമെന്ന് ഇത് അഭ്യർത്ഥിച്ചിരിക്കുന്നു. എന്നാൽ ഇപ്പോൾ ഇത് അസാധുവായ ഒരു നയം നിർവഹിച്ചിരിക്കുന്നതിനാൽ <ph name="SITE" /> എന്നതിനുള്ള നിങ്ങളുടെ അഭ്യർത്ഥന പൂർത്തീകരിക്കാൻ ബ്രൗസറിന് കഴിയുന്നില്ല.</translation>
<translation id="2025186561304664664">പ്രോക്സി സ്വയമേവ കോൺഫിഗർ ചെയ്യാൻ സജ്ജമാക്കി.</translation>
<translation id="2030481566774242610">നിങ്ങൾ ഉദ്ദേശിച്ചത് <ph name="LINK" /> ആണോ?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />പ്രോക്‌സിയും ഫയർവാളും പരിശോധിക്കുന്നു<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">വകുപ്പ്</translation>
<translation id="2102134110707549001">ശക്തമായ പാസ്‌വേഡ് നിർദ്ദേശിക്കുക…</translation>
<translation id="2108755909498034140">നിങ്ങളുടെ കമ്പ്യൂട്ടർ റീസ്‌റ്റാർട്ടുചെയ്യുക</translation>
+<translation id="2111256659903765347">സൂപ്പർ-A</translation>
<translation id="2113977810652731515">കാർഡ്</translation>
<translation id="2114841414352855701"> <ph name="POLICY_NAME" /> എന്നതിനാൽ മറികടന്നതിനാൽ ഇത് അവഗണിച്ചു.</translation>
<translation id="213826338245044447">മൊബൈൽ ബുക്ക്‌മാർക്കുകൾ</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">കാർഡ് എഡിറ്റുചെയ്യുക</translation>
<translation id="2166049586286450108">പൂർണ്ണമായ അഡ്‌മിൻ ആക്‌സസ്സ്</translation>
<translation id="2166378884831602661">ഈ സൈറ്റിന് സുരക്ഷിതമായ കണക്ഷൻ നൽകാനാകില്ല</translation>
+<translation id="2169984857010174799">കാകു2 (എൻവലപ്പ്)</translation>
<translation id="2181821976797666341">നയങ്ങൾ</translation>
<translation id="2183608646556468874">ഫോണ്‍ നമ്പര്‍</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{ഒരു വിലാസം}other{# വിലാസങ്ങൾ}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">ഫോൺ നമ്പർ</translation>
<translation id="2283340219607151381">വിലാസങ്ങൾ സംരക്ഷിച്ച് സ്വമേധയാ പൂരിപ്പിക്കുക</translation>
<translation id="2292556288342944218">നിങ്ങളുടെ ഇന്റർനെറ്റ് ആക്‌സസ്സ് ബ്ലോക്കുചെയ്‌തു</translation>
+<translation id="2294558542833290837">നിങ്ങൾ യഥാർത്ഥത്തിൽ തുറന്ന ലിങ്ക് അസാധാരണമായതാണ്</translation>
+<translation id="2297722699537546652">B5 (എൻവലപ്പ്)</translation>
+<translation id="2310021320168182093">Chou2 (എൻവലപ്പ്)</translation>
<translation id="2316887270356262533">1 MB-യിൽ കുറഞ്ഞ ഡാറ്റ ലാഭിക്കുന്നു. അടുത്തതവണ നിങ്ങൾ സന്ദർശിക്കുമ്പോൾ ചില സൈറ്റുകൾ ഇതിനേക്കാൾ പതുക്കെ ലോഡാകാം.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ഡൊമെയ്‌ന് ഒരു ഉപയോക്തൃനാമവും പാസ്‌വേഡും വേണം.</translation>
<translation id="2317583587496011522">ഡെബിറ്റ് കാർഡുകൾ സ്വീകരിക്കുന്നു.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, <ph name="EXPIRATION_DATE_ABBR" />-ന് കാലഹരണപ്പെടുന്നു</translation>
<translation id="2337852623177822836">ക്രമീകരണം നിയന്ത്രിക്കുന്നത് നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്ററാണ്</translation>
+<translation id="2346319942568447007">നിങ്ങൾ പകർത്തിയ ചിത്രം</translation>
<translation id="2349790679044093737">VR സെഷൻ സജീവമാണ്</translation>
<translation id="2354001756790975382">മറ്റ് ബുക്‌മാര്‍ക്കുകള്‍</translation>
<translation id="2354430244986887761">Google സുരക്ഷിത ബ്രൗസിംഗ് ഈയിടെ <ph name="SITE" /> എന്നതിൽ <ph name="BEGIN_LINK" />ദോഷകരമായ ആപ്പുകൾ കണ്ടെത്തി<ph name="END_LINK" />.</translation>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" />-ന് ക്യാപ്‌ച്ചർ ചെയ്‌ത ക്രാഷ് റിപ്പോർട്ട് അപ്‌ലോഡുചെയ്‌തിട്ടില്ല</translation>
<translation id="2367567093518048410">നില</translation>
<translation id="2378238891085281592">നിങ്ങൾ സ്വകാര്യ മോഡിലേക്ക് മാറിയിരിക്കുന്നു</translation>
+<translation id="2380886658946992094">നിയമപരം</translation>
<translation id="2384307209577226199">എന്റര്‍പ്രൈസ് ഡിഫോൾട്ട്</translation>
<translation id="2386255080630008482">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് അസാധുവാക്കി.</translation>
<translation id="2392959068659972793">മൂല്യമൊന്നും സജ്ജമാക്കാത്ത നയങ്ങൾ കാണിക്കുക</translation>
<translation id="239429038616798445">ഈ ഷിപ്പിംഗ് രീതി ലഭ്യമല്ല. മറ്റൊരു രീതി പരീക്ഷിക്കുക.</translation>
<translation id="2396249848217231973">&amp;ഇല്ലാതാക്കൽ പഴയപടിയാക്കുക</translation>
+<translation id="2410754574180102685">സർക്കാർ-നിയമപരം</translation>
<translation id="2413528052993050574">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; സെർവറിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് റദ്ദാക്കിയിരിക്കാം. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="2418081434543109369">സെർവർ ഉപയോഗിച്ച് നിങ്ങൾ പോകുന്ന <ph name="ORIGIN" /> സൈറ്റ്, അതിൻ്റെ എല്ലാ അഭ്യർത്ഥനകളിലേക്കും ഒരു സുരക്ഷാ നയം ബാധകമാക്കുമെന്ന് ഇത് അഭ്യർത്ഥിച്ചിരിക്കുന്നു. ഒരു നയം നിർവഹിക്കാൻ ഇപ്പോൾ ഇതിന് കഴിയാത്തതിനാൽ <ph name="SITE" /> എന്നതിനുള്ള നിങ്ങളുടെ അഭ്യർത്ഥന പൂർത്തീകരിക്കാൻ ബ്രൗസറിന് കഴിയുന്നില്ല.</translation>
<translation id="244665789865330679">നിങ്ങളുടെ ഉപകരണവും അക്കൗണ്ടും മാനേജ് ചെയ്യുന്നത് <ph name="ENROLLMENT_DOMAIN" /> ആണ്. നിങ്ങളുടെ അക്കൗണ്ടും ഉപകരണവും വിദൂരമായി അഡ്‌മിനിസ്‌ട്രേറ്റർ കോൺഫിഗർ ചെയ്യാമെന്നാണ് ഇതിനർത്ഥം.</translation>
<translation id="2463193859425327265">ഹോം പേജ് മാറ്റുക</translation>
<translation id="2463739503403862330">പൂരിപ്പിക്കുക</translation>
+<translation id="2465402087343596252">ആര്‍ക്കിടെക്ച്ചര്‍-E</translation>
<translation id="2465655957518002998">ഡെലിവറി രീതി തിരഞ്ഞെടുക്കുക</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />നെറ്റ്‌വർക്ക് ഡയഗണോസ്‌റ്റിക്‌സ് റൺ ചെയ്യുന്നു<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ഈ പേജ് വിവർത്തനം ചെയ്യുക</translation>
<translation id="2479410451996844060">അസാധുവായ തിരയൽ URL.</translation>
<translation id="2482878487686419369">വിജ്ഞാപനങ്ങള്‍‌</translation>
<translation id="248348093745724435">മെഷീന്‍ നയങ്ങള്‍</translation>
+<translation id="2485387744899240041">നിങ്ങളുടെ ഉപകരണത്തിനും ബ്രൗസറിനുമുള്ള ഉപയോക്തൃനാമങ്ങൾ</translation>
<translation id="2491120439723279231">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റില്‍ പിശകുകള്‍ അടങ്ങിയിരിക്കുന്നു.</translation>
+<translation id="2493640343870896922">ലെറ്റർ-പ്ലസ്</translation>
<translation id="2495083838625180221">JSON പാഴ്‌സർ</translation>
<translation id="2495093607237746763">പരിശോധിച്ചെങ്കിൽ, വേഗത്തിൽ ഫോം പൂരിപ്പിക്കാൻ Chromium ഈ ഉപകരണത്തിൽ നിങ്ങളുടെ കാർഡിന്റെ ഒരു പകർപ്പ് സൂക്ഷിക്കും.</translation>
<translation id="2498091847651709837">പുതിയ കാർഡ് സ്‌കാൻ ചെയ്യുക</translation>
<translation id="2501278716633472235">പിന്നോട്ട് പോകുക</translation>
<translation id="2503184589641749290">ഡെബിറ്റ് കാർഡുകളും പ്രീപെയ്ഡ് കാർഡുകളും സ്വീകരിക്കുന്നു</translation>
<translation id="2515629240566999685">നിങ്ങളുടെ ഏരിയയിലെ സിഗ്‌നൽ പരിശോധിക്കുന്നു</translation>
-<translation id="2516852381693169964">ചിത്രത്തിനായി <ph name="SEARCH_ENGINE" /> എന്നതിൽ തിരയുക</translation>
<translation id="2523886232349826891">ഈ ഉപകരണത്തിൽ മാത്രം സംരക്ഷിക്കപ്പെടും</translation>
<translation id="2524461107774643265">കൂടുതൽ വിവരങ്ങൾ ചേർക്കുക</translation>
<translation id="2536110899380797252">വിലാസം ചേർക്കുക</translation>
@@ -273,6 +305,7 @@
<translation id="2587841377698384444">ഡയറക്‌ടറി API ഐഡി:</translation>
<translation id="2597378329261239068">ഈ പ്രമാണം പാസ്‌വേഡ് പരിരക്ഷിതമാണ്. ദയവായി ഒരു പാസ്‌വേഡ് നല്‍‌കുക.</translation>
<translation id="2609632851001447353">വേരിയേഷനുകൾ</translation>
+<translation id="2618023639789766142">C10 (എൻവലപ്പ്)</translation>
<translation id="2625385379895617796">നിങ്ങളുടെ ക്ലോക്ക് വളരെ മുമ്പിലാണ്</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" />-ന്‍റെ സെർവർ IP വിലാസം കണ്ടെത്താനായില്ല.</translation>
<translation id="2639739919103226564">നില:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">മറ്റ് ടാബുകളോ ആപ്‌സുകളോ അടയ്‌ക്കുക</translation>
<translation id="267371737713284912">പഴയപടിയാക്കാൻ <ph name="MODIFIER_KEY_DESCRIPTION" /> അമർത്തുക</translation>
<translation id="2674170444375937751">നിങ്ങളുടെ ചരിത്രത്തില്‍ നിന്നും ഈ പേജുകള്‍ മായ്ക്കുന്നതിന് നിങ്ങള്‍ താല്പര്യമുണ്ടോ?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">ഉപേക്ഷിക്കുക</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">സ്വീകരിക്കുന്ന കാർഡുകൾ</translation>
<translation id="2702801445560668637">വായനാ ലിസ്റ്റ്</translation>
<translation id="2704283930420550640">മൂല്യം ഫോർമാറ്റുമായി പൊരുത്തപ്പെടുന്നില്ല.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">തിരഞ്ഞെടുത്ത ഇനങ്ങള്‍‌ നീക്കംചെയ്യുക </translation>
<translation id="277133753123645258">ഷിപ്പിംഗ് രീതി</translation>
<translation id="277499241957683684">ഉപകരണ റെക്കോർഡ് കാണുന്നില്ല</translation>
-<translation id="2781030394888168909">MacOS എക്‌സ്‌പോർട്ട് ചെയ്യുക</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">കണക്ഷന്‍ പുനഃസജ്ജമാക്കിയതാണ്.</translation>
<translation id="2788784517760473862">ക്രെഡിറ്റ് കാർഡുകൾ സ്വീകരിക്കുന്നു</translation>
@@ -311,8 +345,10 @@
<translation id="2826760142808435982"><ph name="CIPHER" /> ഉപയോഗിച്ച് കണക്ഷൻ എൻക്രിപ്‌റ്റുചെയ്‌ത് പ്രാമാണീകരിക്കുന്നു, ഒപ്പം പ്രധാന എക്‌സേഞ്ച് മെക്കാനിസമായി <ph name="KX" /> ഉപയോഗിക്കുന്നു.</translation>
<translation id="2835170189407361413">ഫോം മായ്‌ക്കുക</translation>
<translation id="2847118875340931228">അദൃശ്യ വിൻഡോ തുറക്കുക</translation>
+<translation id="2850739647070081192">ക്ഷണം (എൻവലപ്പ്)</translation>
<translation id="2851634818064021665">ഈ സൈറ്റ് സന്ദർശിക്കാൻ നിങ്ങൾക്ക് അനുമതി ആവശ്യമാണ്</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">കാർഡ് സംരക്ഷിക്കണോ?</translation>
<translation id="2903493209154104877">വിലാസങ്ങള്‍‌</translation>
<translation id="290376772003165898">പേജ് <ph name="LANGUAGE" /> ഭാഷയിലല്ലേ?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">ഡെലിവറി രീതി</translation>
<translation id="2928905813689894207">ബില്ലിംഗ് വിലാസം</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">ഗവൺമെൻ്റ്-ലെറ്റർ</translation>
<translation id="2941952326391522266">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; <ph name="DOMAIN2" /> എന്നതിൽ നിന്നുള്ളതാണ് അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ്. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="2948083400971632585">കണക്ഷനായി കോൺഫിഗർ ചെയ്‌ത ഏതൊരു പ്രോക്‌സികളും ക്രമീകരണങ്ങൾ പേജിൽ നിന്ന് നിങ്ങൾക്ക് പ്രവർത്തനരഹിതമാക്കാനാകും.</translation>
<translation id="2955913368246107853">ഫൈന്‍ഡ് ബാര്‍ അടയ്ക്കുക</translation>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (എൻവലപ്പ്)</translation>
<translation id="3024663005179499861">തെറ്റായ നയ തരം</translation>
<translation id="3037605927509011580">കഷ്ടം!</translation>
<translation id="3041612393474885105">സര്‍‌ട്ടിഫിക്കറ്റ് വിവരങ്ങള്‍‌</translation>
+<translation id="3060227939791841287">C9 (എൻവലപ്പ്)</translation>
<translation id="3064966200440839136">ഒരു എക്‌സ്‌റ്റേണൽ അപ്ലിക്കേഷൻ വഴി പണമടയ്‌ക്കാൻ അദൃശ്യതാ സംവിധാനം ഒഴിവാക്കുന്നു. തുടരണോ?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു പാസ്‌വേഡ്}other{# പാസ്‌വേഡുകൾ}}</translation>
+<translation id="3095940652251934233">പ്രസ്‌താവന</translation>
<translation id="3096100844101284527">പിക്കപ്പ് വിലാസം ചേർക്കുക</translation>
<translation id="3105172416063519923">അസറ്റ് ഐഡി:</translation>
<translation id="3109728660330352905">നിങ്ങൾക്ക് ഈ പേജ് കാണാനുള്ള അംഗീകാരമില്ല.</translation>
@@ -363,20 +403,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> എന്നതിലെ <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">പേയ്‌മെന്റ് റദ്ദാക്കുക</translation>
<translation id="3207960819495026254">ബുക്ക്‌മാർക്കുചെയ്‌തു</translation>
-<translation id="3209375525920864198">സാധുതയുള്ളൊരു സെഷൻ പേര് നൽകുക.</translation>
+<translation id="321912867715453276">മുന്നറിയിപ്പ്: ഈ നയത്തിന് ഒന്നിലധികം ഉറവിടങ്ങളുണ്ടെങ്കിലും മൂല്യങ്ങൾ സമാനമാണ്.</translation>
<translation id="3225919329040284222">ബിൽട്ട്-ഇൻ പ്രതീക്ഷകള്‍ക്ക് പൊരുത്തപ്പെടാത്ത സര്‍ട്ടിഫിക്കറ്റാണ് സെര്‍വര്‍ അവതരിപ്പിച്ചത്. നിങ്ങളെ സംരക്ഷിക്കുന്നതിലേക്കായുള്ള നിശ്ചിത, ഉന്നത-സുരക്ഷാ വെബ്‌സൈറ്റുകൾക്കായാണ് ഈ പ്രതീക്ഷകൾ ഉൾപ്പെടുത്തിയിരിക്കുന്നത്.</translation>
<translation id="3226128629678568754">പേജ് ലോഡുചെയ്യുന്നതിനാവശ്യമായ ഡാറ്റ വീണ്ടും സമർപ്പിക്കാൻ വീണ്ടും ലോഡുചെയ്യുക ബട്ടൺ അമർത്തുക.</translation>
<translation id="3227137524299004712">മൈക്രോഫോൺ</translation>
<translation id="3228969707346345236"><ph name="LANGUAGE" /> ല്‍‌ ഈ പേജ് ഇതിനകം ഉള്ളതിനാല്‍‌ വിവര്‍‌ത്തനം പരാജയപ്പെട്ടു.</translation>
+<translation id="3229041911291329567">നിങ്ങളുടെ ഉപകരണത്തെയും ബ്രൗസറിനെയും കുറിച്ചുള്ള പതിപ്പ് വിവരങ്ങൾ</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="3274521967729236597">പാ-കായ്</translation>
<translation id="3282497668470633863">കാർഡിൽ പേര് ചേർക്കുക</translation>
<translation id="3287510313208355388">ഓൺലൈൻ ആയിരിക്കുന്ന സമയത്ത് ഡൗൺലോഡുചെയ്യുക</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> നയത്തെ കുറിച്ച് കൂടുതലറിയുക</translation>
<translation id="3303855915957856445">തിരയൽ ഫലങ്ങളൊന്നും കണ്ടെത്തിയില്ല</translation>
-<translation id="3305707030755673451"><ph name="TIME" />-ന് നിങ്ങളുടെ സമന്വയ പാസ്‌ഫ്രെയ്‌സ് ഉപയോഗിച്ച് ഡാറ്റ എൻക്രിപ്‌റ്റുചെയ്‌തു. സമന്വയം ആരംഭിക്കുന്നതിന് ഇത് നൽകുക.</translation>
<translation id="3320021301628644560">ബില്ലിംഗ് വിലാസം ചേർക്കുക</translation>
<translation id="3324983252691184275">ക്രിംസൺ</translation>
<translation id="3338095232262050444">സുരക്ഷിതം</translation>
@@ -404,9 +445,11 @@
<translation id="3427342743765426898">&amp;എഡിറ്റുചെയ്യുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="342781501876943858">മറ്റ് സൈറ്റുകളിൽ നിങ്ങളുടെ പാസ്‌വേഡ് പുനരുപയോഗിച്ചിട്ടുണ്ടെങ്കിൽ, അത് റീസെറ്റ് ചെയ്യാൻ Chromium ശുപാർശ ചെയ്യുന്നു.</translation>
<translation id="3431636764301398940">ഈ ഉപകരണത്തിൽ ഈ കാർഡ് സംരക്ഷിക്കുക</translation>
+<translation id="3443726618221119081">ജുറോ-കു-കായ്</translation>
<translation id="3447661539832366887">ഈ ഉപകരണത്തിന്റെ ഉടമ ദിനോസർ ഗെയിം ഓഫാക്കി.</translation>
<translation id="3447884698081792621">സർട്ടിഫിക്കറ്റ് (<ph name="ISSUER" /> ഇഷ്യൂ ചെയ്‌തത്) കാണിക്കുക</translation>
<translation id="3452404311384756672">ഇടവേള ലഭ്യമാക്കുക:</translation>
+<translation id="3456231139987291353">നമ്പർ-11 (എന്‍‌വലപ്പ്)</translation>
<translation id="3461824795358126837">ഹൈലൈറ്റർ</translation>
<translation id="3462200631372590220">വിപുലമായവ മറയ്ക്കുക</translation>
<translation id="3467763166455606212">കാർഡ് ഉടമയുടെ പേര് ആവശ്യമാണ്</translation>
@@ -429,20 +472,23 @@
<translation id="358285529439630156">ക്രെഡിറ്റ് കാർഡുകളും പ്രീപെയ്ഡ് കാർഡുകളും സ്വീകരിക്കുന്നു.</translation>
<translation id="3582930987043644930">പേര് ചേർക്കുക</translation>
<translation id="3583757800736429874">&amp;നീക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
+<translation id="35866233670761917">നിങ്ങൾ സന്ദർശിക്കുന്ന വെബ്‌സൈറ്റുകളുടെ ഉള്ളടക്കം കാണാൻ അഡ്‌മിൻമാർക്ക് കഴിയില്ല</translation>
<translation id="3586931643579894722">വിശദാംശങ്ങൾ മറയ്‌ക്കുക‍‌</translation>
+<translation id="3592413004129370115">ഇറ്റാലിയൻ (എൻവലപ്പ്)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">വലുപ്പം 2</translation>
<translation id="3615877443314183785">കാലഹരണപ്പെടുന്ന ശരിയായ തീയതി നല്‍കുക</translation>
<translation id="36224234498066874">ബ്രൌസിംഗ് ഡാറ്റ മായ്‌ക്കുക...</translation>
<translation id="362276910939193118">മുഴുവന്‍ ചരിത്രവും കാണിക്കുക</translation>
-<translation id="3623476034248543066">മൂല്യം കാണിക്കുക</translation>
<translation id="3630155396527302611">ഇതിനെ നെറ്റ്‌വർക്ക് ആക്‌സസ്സുചെയ്യാൻ അനുമതിയുള്ള ഒരു പ്രോഗ്രാമായി നിലവിൽ ലിസ്റ്റുചെയ്‌തിട്ടുണ്ടെങ്കിൽ,
അതിനെ ലിസ്റ്റിൽ നിന്ന് നീക്കംചെയ്‌ത്, വീണ്ടും ചേർക്കാൻ ശ്രമിക്കുക.</translation>
+<translation id="3640766068866876100">സൂചിക-4x6-Ext</translation>
<translation id="3650584904733503804">മൂല്യനിർണ്ണയം വിജയകരം</translation>
<translation id="3655670868607891010">നിങ്ങൾ ഇത് പതിവായി കാണുന്നുണ്ടെങ്കിൽ, ഈ <ph name="HELP_LINK" /> പരീക്ഷിക്കൂ.</translation>
<translation id="3658742229777143148">പുനരവലോകനം</translation>
<translation id="366077651725703012">ക്രെഡിറ്റ് കാർഡ് അപ്‌ഡേറ്റ് ചെയ്യുക</translation>
<translation id="3676592649209844519">ഉപകരണ ഐഡി:</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; എന്നാണോ ഉദ്ദേശിച്ചത്?</translation>
<translation id="3678029195006412963">അഭ്യർത്ഥന സൈൻ ചെയ്യാനായില്ല</translation>
<translation id="3678529606614285348">പുതിയ അദൃശ്യ വിൻഡോയിൽ പേജ് തുറക്കുക (കൺട്രോൾ-ഷിഫ്റ്റ്-N)</translation>
<translation id="3679803492151881375">ക്രാഷ് റിപ്പോർട്ട് <ph name="CRASH_TIME" />-ന് ക്യാപ്‌ചർ ചെയ്‌ത്, <ph name="UPLOAD_TIME" />-ന് അപ്‌ലോഡുചെയ്‌തു</translation>
@@ -450,13 +496,14 @@
<translation id="3704162925118123524">നിങ്ങൾ ഉപയോഗിക്കുന്ന നെറ്റ്‌വർക്കിനായി, ഇതിന്റെ ലോഗിൻ പേജ് സന്ദർശിക്കേണ്ടിവരാം.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ലോഡ്ചെയ്യുന്നു...</translation>
+<translation id="3709599264800900598">നിങ്ങൾ പകർത്തിയ ടെക്‌സ്‌റ്റ്</translation>
<translation id="3712624925041724820">ലൈസൻസുകൾ കാലഹരണപ്പെട്ടു</translation>
<translation id="3714780639079136834">മൊബൈൽ ഡാറ്റ അല്ലെങ്കിൽ Wi-Fi ഓണാക്കുന്നു</translation>
<translation id="3715597595485130451">Wi-Fi-യിലേക്ക് കണക്റ്റുചെയ്യുക</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />പ്രോക്‌സിയും ഫയർവാളും DNS കോൺഫിഗറേഷനും പരിശോധിക്കുന്നു<ph name="END_LINK" /></translation>
<translation id="372429172604983730">ആന്‍റിവൈറസ്, ഫയർവാൾ, വെബ് ഫിൽട്ടറിംഗ് അല്ലെങ്കിൽ പ്രോക്‌സി സോഫ്റ്റ്‌വെയർ എന്നിവ ഉൾപ്പെടെയുള്ള അപ്ലിക്കേഷനുകൾ ഈ പിശകിന് കാരണമാകുന്നു.</translation>
+<translation id="373042150751172459">B4 (എൻവലപ്പ്)</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="3745099705178523657">സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ പങ്കിടും.</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>
@@ -469,10 +516,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" />-ൽ അവസാനിക്കുന്നു</translation>
<translation id="3789155188480882154">വലുപ്പം 16</translation>
+<translation id="3797522431967816232">Prc3 (എൻവലപ്പ്)</translation>
<translation id="3807873520724684969">ദോഷകരമായ ഉള്ളടക്കം ബ്ലോക്ക് ചെയ്‌തു.</translation>
<translation id="3810973564298564668">മാനേജ് ചെയ്യുക</translation>
<translation id="382518646247711829">നിങ്ങൾ ഒരു പ്രോക്‌സി സെർവർ ഉപയോഗിക്കുന്നെങ്കിൽ...</translation>
<translation id="3828924085048779000">ശൂന്യ പാസ്ഫ്രെയ്സ് അനുവദനീയമല്ല.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" />അധിക ഫംഗ്ഷനുകൾക്കുള്ള വിപുലീകരണങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്‌തിരിക്കുന്നു. വിപുലീകരണങ്ങൾക്ക് നിങ്ങളുടെ ചില ഡാറ്റയിലേക്ക് ആക്‌സസ് ഉണ്ട്.</translation>
<translation id="385051799172605136">പിന്നോട്ട്</translation>
<translation id="3858027520442213535">തീയതിയും സമയവും അപ്‌ഡേറ്റുചെയ്യുക</translation>
<translation id="3884278016824448484">വിരുദ്ധ ഉപകരണ ഐഡന്റിഫയർ</translation>
@@ -480,6 +529,7 @@
<translation id="3886446263141354045"><ph name="NAME" /> എന്നയാൾക്ക് ഈ സൈറ്റ് ആക്‌സസ് ചെയ്യാനുള്ള നിങ്ങളുടെ അഭ്യർത്ഥന അയച്ചു</translation>
<translation id="3890664840433101773">ഇമെയില്‍‌ ചേര്‍‌ക്കുക</translation>
<translation id="3901925938762663762">കാർഡ് കാലഹരണപ്പെട്ടു</translation>
+<translation id="3906600011954732550">B5-അധികം</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">ഈ സൈറ്റിൽ എല്ലായ്‌പ്പോഴും ചോദിക്കുക</translation>
<translation id="3949571496842715403">ഈ സെർവറിന് ഇത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് വിഷയേതര നാമങ്ങൾ വ്യക്തമാക്കുന്നില്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
@@ -490,11 +540,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു സൈറ്റിൽ നിന്ന് }other{# സൈറ്റുകളിൽ നിന്ന് }}</translation>
<translation id="397105322502079400">കണക്കാക്കുന്നു...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ബ്ലോക്കുചെയ്‌തിരിക്കുന്നു</translation>
-<translation id="3984550557525787191">ഈ സെഷൻ പേര് മുമ്പേ നിലവിലുണ്ട്.</translation>
<translation id="3987940399970879459">ഒരു MB-യിൽ കുറവാണ്</translation>
+<translation id="4008849406247176967">മുന്നറിയിപ്പ്: ഈ നയത്തിന് വിരുദ്ധ മൂല്യങ്ങളുള്ള ഒന്നിലധികം ഉറവിടങ്ങളുണ്ട്!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{സമീപത്ത് ഒരു വെബ്‌പേജുണ്ട്}other{സമീപത്ത് # വെബ്‌പേജുകളുണ്ട്}}</translation>
<translation id="4030383055268325496">&amp;ചേർത്തത് പഴയപടിയാക്കുക</translation>
+<translation id="4032320456957708163">നിങ്ങളുടെ ബ്രൗസർ മാനേജ് ചെയ്യുന്നത് <ph name="ENROLLMENT_DOMAIN" /> ആണ്</translation>
<translation id="4058922952496707368">കീ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (എൻവലപ്പ്)</translation>
<translation id="4067947977115446013">ശരിയായ വിലാസം ചേർക്കുക</translation>
<translation id="4072486802667267160">നിങ്ങളുടെ ഓർഡർ പ്രോസസ്സ് ചെയ്യുന്നതിൽ ഒരു പിശകുണ്ടായി. വീണ്ടും ശ്രമിച്ചുനോക്കൂ.</translation>
<translation id="4075732493274867456">ഒരു സാധാരണ SSL പ്രോട്ടോക്കോൾ പതിപ്പിനെയോ സൈഫർ സ്യൂട്ടിനെയോ ക്ലയന്റും സെർവറും പിന്തുണയ്‌ക്കില്ല.</translation>
@@ -514,10 +566,12 @@
<translation id="4159784952369912983">പര്‍പ്പിള്‍</translation>
<translation id="4165986682804962316">സൈറ്റ് ക്രമീകരണങ്ങൾ</translation>
<translation id="4171400957073367226">മോശം പരിശോധിച്ചുറപ്പിക്കൽ സിഗ്‌നേച്ചർ</translation>
+<translation id="4173315687471669144">ഫൂൾസ്‌‌കേപ്പ്</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ഇനം കൂടി}other{<ph name="ITEM_COUNT" /> ഇനങ്ങൾ കൂടി}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;നീക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ഫയർവാളും ആന്റിവൈറസ് കോൺഫിഗറേഷനുകളും പരിശോധിക്കുന്നു<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (എൻവലപ്പ്)</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="4221630205957821124">&lt;h4&gt;ഘട്ടം 1: പോർട്ടലിലേക്ക് സൈൻ ഇൻ ചെയ്യുക&lt;/h4&gt;
@@ -549,58 +603,79 @@
<translation id="4277028893293644418">പാസ്‌വേഡ് റീസെറ്റ് ചെയ്യുക</translation>
<translation id="4280429058323657511">, <ph name="EXPIRATION_DATE_ABBR" />-ന് കാലാവധി തീരുന്നു</translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{ഈ കാർഡ് നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിച്ചു}other{ഈ കാർഡുകൾ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിച്ചു}}</translation>
+<translation id="42981349822642051">വികസിപ്പിക്കുക</translation>
+<translation id="4302965934281694568">Chou3 (എൻവലപ്പ്)</translation>
<translation id="4305817255990598646">സ്വിച്ച് ചെയ്യുക</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">ബ്ലോക്കുചെയ്യുക (ഡിഫോൾട്ട്)</translation>
+<translation id="4318566738941496689">നിങ്ങളുടെ ഉപകരണത്തിൻ്റെ പേരും നെറ്റ്‌വർക്ക് വിലാസവും</translation>
<translation id="4325863107915753736">ലേഖനം കണ്ടെത്തുന്നത് പരാജയപ്പെട്ടു</translation>
<translation id="4326324639298822553">കാലാവധി തീരുന്ന തീയതി പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക</translation>
<translation id="4331708818696583467">സുരക്ഷിതമല്ല</translation>
<translation id="4340982228985273705">എന്റർപ്രൈസ് നിയന്ത്രിക്കുന്ന തരത്തിൽ ഈ കമ്പ്യൂട്ടർ തിരിച്ചറിയപ്പെടുന്നില്ല, അതുകൊണ്ട് Chrome വെബ്‌സ്റ്റോറിൽ ഹോസ്റ്റ് ചെയ്‌തിട്ടുള്ള വിപുലീകരണങ്ങൾ മാത്രമാണ് നയത്തിന് സ്വമേധയാ ഇൻസ്റ്റാൾ ചെയ്യാനാവുക. Chrome വെബ്‌സ്റ്റോർ അപ്‌ഡേറ്റ് URL "<ph name="CWS_UPDATE_URL" />" ആണ്.</translation>
<translation id="4346197816712207223">സ്വീകരിക്കുന്ന ക്രെഡിറ്റ് കാർഡുകൾ</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">ഈ സൈറ്റിലെ ആക്രമണകാരികൾ നിങ്ങളുടെ വിവരങ്ങൾ മോഷ്‌ടിക്കാനോ ഇല്ലാതാക്കാനോ ഇടയുള്ള (ഉദാഹരണത്തിന്, ഫോട്ടോകൾ, പാസ്‌വേഡുകൾ, സന്ദേശങ്ങൾ, ക്രെഡിറ്റ് കാർഡുകൾ എന്നിവ) അപകടകരമായ പ്രോഗ്രാമുകൾ കമ്പ്യൂട്ടറിൽ ഇൻസ്‌റ്റാൾ ചെയ്യാൻ ശ്രമിച്ചേക്കാം.</translation>
<translation id="4358461427845829800">പേയ്മെന്റ് രീതികൾ മാനേജ് ചെയ്യുക...</translation>
+<translation id="4367563149485757821">നമ്പർ-12 (എൻവലപ്പ്)</translation>
+<translation id="4372516964750095882">ഫാൻഫോൾഡ്-Us</translation>
<translation id="4372948949327679948">പ്രതീക്ഷിച്ച <ph name="VALUE_TYPE" /> മൂല്യം.</translation>
<translation id="4377125064752653719">നിങ്ങള്‍‌ <ph name="DOMAIN" /> എന്നതില്‍‌ എത്താന്‍‌ ശ്രമിച്ചു, പക്ഷേ സെര്‍‌വര്‍‌ നൽകിയ സര്‍‌ട്ടിഫിക്കറ്റ് അത് നല്‍‌കിയ ആള്‍‌ അസാധുവാക്കി. സെര്‍‌വര്‍‌ നല്‍‌കിയ സുരക്ഷാ ക്രെഡന്‍‌ഷ്യലുകള്‍‌ തികച്ചും വിശ്വാ‍സയോഗ്യമല്ല എന്നാണ് ഇതിനര്‍‌ത്ഥം. നിങ്ങള്‍‌ ഒരു ആക്രമണകാരിയുമായിട്ടാകാം ആശയവിനിമയം നടത്തുന്നത്.</translation>
<translation id="4378154925671717803">ഫോൺ</translation>
<translation id="4406896451731180161">തിരയൽ ഫലങ്ങൾ</translation>
-<translation id="4406972042435603828">നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർമാർ ശക്തമായ ശേഷികളുള്ള വിപുലീകരണങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്‌തിട്ടുണ്ട്.</translation>
<translation id="4408413947728134509">കുക്കികൾ <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">പിക്കപ്പ് വിലാസം</translation>
<translation id="4424024547088906515">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റ് Chrome-ന് പരിചയമില്ലാത്തതാണ്. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="443121186588148776">സീരിയൽ പോർട്ട്</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" />, നിങ്ങളുടെ ലോഗിൻ സർട്ടിഫിക്കറ്റിന് അംഗീകരിച്ചിട്ടില്ല, അല്ലെങ്കിൽ അങ്ങനെയൊരെണ്ണം നൽകിയിട്ടില്ലായിരിക്കാം.</translation>
<translation id="4434045419905280838">പോപ്-അപ്പുകളും റീഡയറക്‌റ്റുകളും</translation>
+<translation id="4435702339979719576">പോസ്‌റ്റ്‌ കാർഡ്)</translation>
<translation id="443673843213245140">പ്രോക്‌സി ഉപയോഗം അപ്രാപ്‌തമാക്കി പക്ഷെ ഒരു വ്യക്തമായ പ്രോക്‌സി കോൺഫിഗറേഷൻ നിർദ്ദേശിച്ചു.</translation>
<translation id="445100540951337728">ഡെബിറ്റ് കാർഡുകൾ സ്വീകരിക്കുന്നു</translation>
+<translation id="4466881336512663640">ഫോം മാറ്റങ്ങൾ നഷ്‌ടമാകും. തുടരണമെന്ന് നിങ്ങൾക്ക് തീർച്ചയാണോ?</translation>
<translation id="4482953324121162758">ഈ സൈറ്റ് വിവർത്തനം ചെയ്യപ്പെടില്ല.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL അസാധുവാണ്. സ്‌റ്റാൻഡേർഡ് സ്‌കീം ഉള്ള URL ആയിരിക്കണം, ഉദാ. http://example.com അല്ലെങ്കിൽ https://example.com.</translation>
+<translation id="4503882053543859973">ആര്‍ക്കിടെക്ച്ചര്‍-D</translation>
<translation id="4506176782989081258">മൂല്യനിർണ്ണയ പിശക്: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">സിസ്റ്റം അഡ്‌മിനെ ബന്ധപ്പെടുന്നു</translation>
<translation id="450710068430902550">അഡ്‌മിനിസ്‌ട്രേറ്ററുമായി പങ്കിടുന്നു</translation>
+<translation id="4510487217173779431">Chou4 (എൻവലപ്പ്)</translation>
<translation id="4515275063822566619">കാർഡുകളും വിലാസങ്ങളും Chrome-ൽ നിന്നും നിങ്ങളുടെ അ‌ക്കൗണ്ടിൽ (<ph name="ACCOUNT_EMAIL" />) നിന്നുമുള്ളതുമാണ്. നിങ്ങൾക്ക് ഇവ <ph name="BEGIN_LINK" />ക്രമീകരണത്തിൽ<ph name="END_LINK" /> മാനേജുചെയ്യാം.</translation>
+<translation id="4517607026994743406">Comm-10 (എൻവലപ്പ്)</translation>
<translation id="4522570452068850558">വിശദാംശങ്ങൾ‌</translation>
<translation id="4524805452350978254">കാർഡുകൾ മാനേജ് ചെയ്യുക</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ഫ്ലാഷ്</translation>
<translation id="4558551763791394412">നിങ്ങളുടെ വിപുലീകരണങ്ങൾ പ്രവർത്തനരഹിതമാക്കുന്നത് പരീക്ഷിക്കുക.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">ഡെലിവറി വിവരങ്ങൾ</translation>
+<translation id="4579056131138995126">വ്യക്തിപരം (എൻവലപ്പ്)</translation>
<translation id="4582204425268416675">കാർഡ് നീക്കം ചെയ്യുക</translation>
<translation id="4587425331216688090">Chrome-ൽ നിന്ന് വിലാസം നീക്കംചെയ്യണോ?</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" /> എന്നതിലേക്കുള്ള നിങ്ങളുടെ കണക്ഷനെ ആധുനിക സൈഫർ സ്യൂട്ട് ഉപയോഗിച്ച് എൻക്രിപ്റ്റുചെയ്‌തിരിക്കുന്നു.</translation>
<translation id="4594403342090139922">&amp;ഇല്ലാതാക്കുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="4597348597567598915">വലുപ്പം 8</translation>
+<translation id="4600854749408232102">C6/C5 (എൻവലപ്പ്)</translation>
<translation id="4646534391647090355">എന്നെ ഇപ്പോൾ അവിടെയെത്തിക്കൂ</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷാ സർട്ടിഫിക്കറ്റിൽ പിശകുകൾ അടങ്ങിയിരിക്കുന്നു. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="467809019005607715">Google സ്ലൈഡ്</translation>
<translation id="4690462567478992370">അസാധുവായ ഒരു സർട്ടിഫിക്കറ്റ് ഉപയോഗിക്കുന്നത് നിർത്തുക</translation>
+<translation id="4691835149146451662">ആര്‍ക്കിടെക്ച്ചര്‍-A (എൻവലപ്പ്)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">നിങ്ങളുടെ കണക്ഷൻ തടസ്സപ്പെട്ടു</translation>
<translation id="471880041731876836">ഈ സൈറ്റ് സന്ദർശിക്കാൻ നിങ്ങൾക്ക് അനുമതി ആവശ്യമില്ല</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows നെറ്റ്‌വർക്ക് ഡയഗണോസ്‌റ്റിക്‌സ് റൺ ചെയ്യുന്നു<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">നയങ്ങൾ വീണ്ടും ലോഡുചെയ്യുക</translation>
<translation id="4728558894243024398">പ്ലാറ്റ്ഫോം</translation>
+<translation id="4731967714531604179">Prc2 (എൻവലപ്പ്)</translation>
<translation id="4736825316280949806">Chromium റീസ്‌റ്റാർട്ടുചെയ്യുക</translation>
<translation id="473775607612524610">അപ്‌ഡേറ്റുചെയ്യുക</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> തിരയൽ നിർദ്ദേശം</translation>
<translation id="4742407542027196863">പാസ്‌വേഡുകൾ മാനേജ് ചെയ്യുക…</translation>
<translation id="4744603770635761495">നിര്‍വ്വഹിക്കാവുന്ന പാത</translation>
+<translation id="4746351372139058112">സന്ദേശങ്ങൾ</translation>
<translation id="4750917950439032686">നിങ്ങളുടെ വിവരങ്ങൾ (ഉദാഹരണത്തിന്, പാസ്‌വേഡുകളോ ക്രെഡിറ്റ് കാർഡ് നമ്പറുകളോ) ഈ സൈറ്റിലേക്ക് അയച്ച് കഴിഞ്ഞാൽ പിന്നെയത് സ്വകാര്യമായിരിക്കും.</translation>
<translation id="4756388243121344051">&amp;ചരിത്രം</translation>
<translation id="4758311279753947758">കോൺടാക്റ്റ് വിവരങ്ങൾ ചേർക്കുക</translation>
@@ -608,9 +683,9 @@
<translation id="4764776831041365478"><ph name="URL" /> ലെ വെബ്‌പേജ് താല്‍‌ക്കാലികമായി പ്രവര്‍‌ത്തനരഹിതമായിരിക്കാം, അല്ലെങ്കില്‍‌ ഒരു പുതിയ വെബ് വിലാസത്തിലേക്ക് ശാശ്വതമായി നീക്കംചെയ്യപ്പെട്ടിരിക്കാം.</translation>
<translation id="4771973620359291008">ഒരു അജ്ഞാത പിശക് സംഭവിച്ചു.</translation>
<translation id="4785689107224900852">ഈ ടാബിലേക്ക് സ്വിച്ച് ചെയ്യുക</translation>
-<translation id="4792143361752574037">സെഷൻ ഫയലുകൾ ആക്‌സസ്സ് ചെയ്യുന്നതിൽ ഒരു പ്രശ്നം ഉണ്ടായിരുന്നു. ഡിസ്‌ക്കിലേക്ക് സംരക്ഷിക്കുന്നത് നിലവിൽ പ്രവർത്തനരഹിതമാക്കി. വീണ്ടും ശ്രമിക്കാൻ പേജ് റീലോഡ് ചെയ്യുക.</translation>
<translation id="4798078619018708837">നിങ്ങളുടെ കാർഡ് വിശദാംശങ്ങൾ അപ്‌ഡേറ്റ് ചെയ്യാൻ <ph name="CREDIT_CARD" />-ന്‍റെ കാലാവധി തീരുന്ന തീയതിയും CVC-യും നൽകുക. സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation>
<translation id="4800132727771399293">നിങ്ങളുടെ കാലഹരണ തീയതിയും CVC യും പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക</translation>
+<translation id="480334179571489655">ഒറിജിൻ നയത്തിൽ പിശക്</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>
@@ -625,7 +700,6 @@
<translation id="4881695831933465202">തുറക്കുക</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>
@@ -634,15 +708,15 @@
<translation id="4943872375798546930">ഫലങ്ങളൊന്നുമില്ല</translation>
<translation id="4950898438188848926">ടാബ് മാറാനുള്ള ബട്ടൺ, തുറന്നിരിക്കുന്ന ടാബായ <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> എന്നതിലേക്ക് മാറാൻ എൻ്റർ അമർത്തുക</translation>
<translation id="495170559598752135">പ്രവര്‍ത്തനങ്ങള്‍</translation>
-<translation id="495832697253704892">വിപുലീകരണം റിപ്പോർട്ട് ചെയ്യൽ</translation>
+<translation id="4955242332710481440">A5-അധികം</translation>
<translation id="4958444002117714549">ലിസ്റ്റ് വിപുലീകരിക്കുക</translation>
<translation id="4974590756084640048">മുന്നറിയിപ്പുകൾ വീണ്ടും പ്രവർത്തനക്ഷമമാക്കുക</translation>
+<translation id="4984339528288761049">Prc5 (എൻവലപ്പ്)</translation>
<translation id="4989163558385430922">എല്ലാം കാണുക</translation>
<translation id="4989809363548539747">ഈ പ്ലഗിൻ പിന്തുണയ്‌ക്കുന്നില്ല</translation>
-<translation id="4996230189582812866">റിപ്പോർട്ട് ചെയ്യൽ</translation>
<translation id="5002932099480077015">പ്രവർത്തനക്ഷമമാക്കിയെങ്കിൽ, വേഗത്തിൽ ഫോം പൂരിപ്പിക്കാൻ Chrome ഈ ഉപകരണത്തിൽ നിങ്ങളുടെ കാർഡിന്റെ ഒരു പകർപ്പ് സൂക്ഷിക്കും.</translation>
-<translation id="5014174725590676422">Chrome-ലെ Google അസിസ്‌റ്റന്‍റ്, ആദ്യ റൺ സ്‌ക്രീൻ കാണിക്കുന്നു</translation>
<translation id="5015510746216210676">മെഷീനിന്‍റെ പേര്‌:</translation>
+<translation id="5017554619425969104">നിങ്ങൾ പകർത്തിയ ടെക്‌സ്‌റ്റ്</translation>
<translation id="5018422839182700155">ഈ പേജ് തുറക്കാനായില്ല</translation>
<translation id="5019198164206649151">ബാക്കിംഗ് സംഭരണം മോശം അവസ്ഥയിലാണ്</translation>
<translation id="5023310440958281426">നിങ്ങളുടെ അഡ്‌മിനിസ്ട്രേറ്ററുടെ നയങ്ങൾ പരിശോധിക്കുക.</translation>
@@ -652,35 +726,51 @@
<translation id="5034369478845443529">പ്രാദേശിക സന്ദർഭം <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">അനുവദിക്കൂ</translation>
<translation id="5040262127954254034">സ്വകാര്യത</translation>
+<translation id="5043480802608081735">നിങ്ങൾ പകർത്തിയ ലിങ്ക്</translation>
<translation id="5045550434625856497">ശരിയല്ലാത്ത രഹസ്യവാക്ക്</translation>
<translation id="5056549851600133418">നിങ്ങൾക്കുള്ള ലേഖനങ്ങൾ</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />പ്രോക്‌സി വിലാസം പരിശോധിക്കുന്നു<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM ഉപയോഗം പോലുള്ള ഉപകരണ സ്ഥിതിവിവരക്കണക്കുകൾ</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">നിങ്ങളുടെ ഉപകരണം മാനേജ് ചെയ്യുന്നത് <ph name="ENROLLMENT_DOMAIN" />-ഉം അക്കൗണ്ട് മാനേജ് ചെയ്യുന്നത് <ph name="ACCOUNT_DOMAIN" />-ഉം ആണ്. നിങ്ങളുടെ ഉപകരണവും അക്കൗണ്ടും അഡ്‌മിനിസ്‌ട്രേറ്റർമാർ വിദൂരമായി കോൺഫിഗർ ചെയ്യാമെന്നാണ് ഇതിനർത്ഥം.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">യൂറോപ്യൻ-Edp</translation>
<translation id="5115563688576182185">(64-ബിറ്റ്)</translation>
-<translation id="5128122789703661928">സെഷന്‍റെ പേര് തെറ്റായതിനാൽ ഇല്ലാതാക്കാനായില്ല.</translation>
+<translation id="5125394840236832993">B-പ്ലസ്</translation>
<translation id="5135404736266831032">വിലാസങ്ങൾ മാനേജ് ചെയ്യുക...</translation>
+<translation id="5138227688689900538">കുറച്ച് കാണിക്കുക</translation>
<translation id="5141240743006678641">Google ക്രെഡൻഷ്യലുകൾ ഉപയോഗിച്ച് സമന്വിത പാസ്‌വേഡുകൾ എൻക്രിപ്റ്റുചെയ്യുക</translation>
<translation id="5145883236150621069">നയ പ്രതികരണത്തിൽ പിശക് കോഡ് ഉണ്ട്</translation>
+<translation id="515292512908731282">C4 (എൻവലപ്പ്)</translation>
<translation id="5159010409087891077">പുതിയൊരു അദൃശ്യ വിൻഡോയിൽ പേജ് തുറക്കുക (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" />-ന്‍റെ CVC നൽകുക. സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation>
<translation id="5169827969064885044">നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ അക്കൗണ്ടിലേക്കുള്ള ആക്‌സസ് നഷ്‌ടമാകാനോ നിങ്ങളുടെ ഐഡന്‍റിറ്റി മോഷ്ടിക്കപ്പെടാനോ സാധ്യതയുണ്ട്. ഇപ്പോൾ തന്നെ പാസ്‍വേഡ് മാറ്റാൻ Chrome ശുപാർശ ചെയ്യുന്നു.</translation>
<translation id="5171045022955879922">തിരയുക അല്ലെങ്കിൽ URL ടൈപ്പുചെയ്യുക</translation>
+<translation id="5171689220826475070">ഫാൻഫോൾഡ്-യൂറോപ്യന്‍‌</translation>
<translation id="5172758083709347301">മെഷീൻ</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> എന്നതില്‍‌ ഇല്ലേ? ഈ പിശക് റിപ്പോര്‍‌ട്ടുചെയ്യുക</translation>
<translation id="5190835502935405962">ബുക്ക്‌മാര്‍‌ക്കുകള്‍‌ ബാര്‍‌</translation>
-<translation id="5200263511887412697">അടുത്തിടെ ലോഗിൻ ചെയ്‌ത ഉപകരണ ഉപയോക്താക്കളുടെ ലിസ്‌റ്റ് റിപ്പോർട്ട് ചെയ്യുക</translation>
+<translation id="519422657042045905">കുറിപ്പ് ലഭ്യമല്ല</translation>
<translation id="5201306358585911203">ഈ പേജിലെ ഉൾച്ചേർത്ത പേജ് പറയുന്നത്:</translation>
<translation id="5205222826937269299">പേര് ആവശ്യമാണ്</translation>
<translation id="5215116848420601511">Google Pay ഉപയോഗിക്കുന്ന വിലാസങ്ങളും പേയ്മെന്റ് രീതികളും</translation>
+<translation id="5215363486134917902">ഫോളിയോ-Sp</translation>
<translation id="5222812217790122047">ഇമെയിൽ ആവശ്യമാണ്</translation>
<translation id="5230733896359313003">ഷിപ്പിംഗ് വിലാസം</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"നെറ്റ്‌വർക്കിലേക്ക് കണക്‌റ്റ് ചെയ്യുക"</translation>
<translation id="5251803541071282808">ക്ലൗഡ്</translation>
+<translation id="5252000469029418751">C7 (എൻവലപ്പ്)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">നെറ്റ്‌വർക്ക് വിലാസങ്ങൾ</translation>
<translation id="5285570108065881030">സംരക്ഷിച്ച എല്ലാ പാസ്‌വേഡുകളും കാണിക്കുക</translation>
<translation id="5287240709317226393">കുക്കികള്‍ കാണിക്കുക</translation>
<translation id="5288108484102287882">നയ മൂല്യങ്ങളുടെ സാധൂകരണം മുന്നറിയിപ്പുകൾ സൃഷ്‌ടിച്ചിട്ടുണ്ട്</translation>
@@ -692,7 +782,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> / <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">കോണ്‍ടാക്റ്റ് വിവരം തിരഞ്ഞെടുക്കുക</translation>
<translation id="5327248766486351172">പേര്</translation>
+<translation id="5329858041417644019">നിങ്ങളുടെ ബ്രൗസർ മാനേജ് ചെയ്‌തിട്ടില്ല</translation>
<translation id="5332219387342487447">ഷിപ്പിംഗ് രീതി</translation>
+<translation id="5334013548165032829">വിശദമായ സിസ്‌റ്റം ലോഗുകൾ</translation>
<translation id="5344579389779391559">ഈ പേജ് നിങ്ങളില്‍ നിന്ന് പണം ഈടാക്കാനിടയുണ്ട്</translation>
<translation id="5355557959165512791">സർട്ടിഫിക്കറ്റ് റദ്ദാക്കിയതിനാൽ നിങ്ങൾക്കിപ്പോൾ <ph name="SITE" /> സന്ദർശിക്കാനാകില്ല. നെറ്റ്‌വർക്ക് പിശകുകളും ആക്രമണങ്ങളും സാധാരണ താൽക്കാലികമായിരിക്കും, അതിനാൽ ഈ പേജ് മിക്കവാറും പിന്നീട് പ്രവർത്തിക്കും.</translation>
<translation id="536296301121032821">നയ ക്രമീകരണങ്ങൾ സംഭരിക്കുന്നതിൽ പരാജയപ്പെട്ടു</translation>
@@ -700,6 +792,7 @@
<translation id="5377026284221673050">"നിങ്ങളുടെ സമയം പിന്നിലാണ്" അല്ലെങ്കിൽ "നിങ്ങളുടെ സമയം മുന്നിലാണ്" അല്ലെങ്കിൽ "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">എല്ലാ ഉപകരണങ്ങളിലും നിങ്ങളുടെ കാർഡുകൾ ഉപയോഗിക്കുന്നതിന്, സൈൻ ഇൻ ചെയ്‌ത് സമന്വയിപ്പിക്കൽ ഓണാക്കുക.</translation>
<translation id="5386426401304769735">ഈ സൈറ്റിന്റെ സർട്ടിഫിക്കറ്റ് ചെയിനിൽ SHA-1 ഉപയോഗിച്ച് സൈൻ ചെയ്‌ത ഒരു സർട്ടിഫിക്കറ്റ് അടങ്ങിയിരിക്കുന്നു.</translation>
+<translation id="538659543871111977">A4-ടാബ്</translation>
<translation id="540969355065856584">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; അതിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റിന് ഇപ്പോൾ സാധുതയുള്ളതല്ല. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു ആക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
<translation id="5421136146218899937">ബ്രൗസിംഗ് ഡാറ്റ മായ്‌ക്കുക...</translation>
<translation id="5430298929874300616">ബുക്ക്‌മാർക്ക് നീക്കം ചെയ്യുക</translation>
@@ -710,6 +803,7 @@
<translation id="5457113250005438886">അസാധുവാണ്</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;എഡിറ്റുചെയ്യുന്നത് വീണ്ടും ചെയ്യുക</translation>
+<translation id="5478437291406423475">B6/C4 (എൻവലപ്പ്)</translation>
<translation id="5481076368049295676">ഈ ഉള്ളടക്കം, നിങ്ങളുടെ ഉപകരണത്തിൽ വിവരങ്ങൾ മോഷ്‌ടിക്കുകയോ ഇല്ലാതാക്കുയോ ചെയ്യുന്ന തരത്തിലുള്ള സോഫ്‌റ്റ്‌വെയർ ഇൻസ്‌റ്റാൾ ചെയ്യാൻ ശ്രമിച്ചേക്കാം. <ph name="BEGIN_LINK" />എന്തായാലും കാണിക്കുക<ph name="END_LINK" /></translation>
<translation id="54817484435770891">ശരിയായ വിലാസം ചേർക്കുക</translation>
<translation id="5490432419156082418">വിലാസങ്ങളും മറ്റും</translation>
@@ -717,10 +811,12 @@
<ph name="LINE_BREAK" />
നിങ്ങളുടെ സിസ്‌റ്റം അഡ്‌മിനിസ്‌ട്രേറ്ററുമായി ബന്ധപ്പെടാൻ ശ്രമിക്കുക.</translation>
<translation id="549333378215107354">വലുപ്പം 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">നിയന്ത്രിത ബുക്കുമാർക്കുകൾ</translation>
<translation id="5510766032865166053">ഇത് നീക്കുകയോ ഇല്ലാതാക്കുകയോ ചെയ്‌തിരിക്കാം.</translation>
<translation id="5523118979700054094">നയത്തിന്റെ പേര്</translation>
<translation id="552553974213252141">വാചകം ശരിയായി എക്‌സ്‌ട്രാക്റ്റുചെയ്‌തോ?</translation>
+<translation id="553484882784876924">Prc6 (എൻവലപ്പ്)</translation>
<translation id="5540224163453853">അഭ്യർത്ഥിച്ച ലേഖനം കണ്ടെത്താനായില്ല.</translation>
<translation id="5541546772353173584">ഇമെയില്‍‌ ചേര്‍‌ക്കുക</translation>
<translation id="5545756402275714221">നിങ്ങൾക്കുള്ള ലേഖനങ്ങൾ</translation>
@@ -735,15 +831,21 @@
<translation id="5595485650161345191">വിലാസം എഡിറ്റുചെയ്യുക</translation>
<translation id="5598944008576757369">പേയ്‌മെന്‍റ് രീതി തിരഞ്ഞെടുക്കുക</translation>
<translation id="560412284261940334">മാനേജുമെന്റ് പിന്തുണയ്‌ക്കുന്നില്ല</translation>
+<translation id="5605670050355397069">ലെഡ്‌ജർ</translation>
+<translation id="5607240918979444548">ആര്‍ക്കിടെക്ച്ചര്‍-C</translation>
<translation id="5610142619324316209">കണക്ഷൻ പരിശോധിക്കുന്നു</translation>
<translation id="5610807607761827392">നിങ്ങൾക്ക് <ph name="BEGIN_LINK" />ക്രമീകരണത്തിൽ<ph name="END_LINK" /> കാർഡുകളും വിലാസങ്ങളും മാനേജുചെയ്യാം.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" />, നിരവധി തവണ നിങ്ങളെ റീഡയറക്‌ടുചെയ്‌തു.</translation>
<translation id="5629630648637658800">നയ ക്രമീകരണങ്ങൾ ലോഡുചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു</translation>
<translation id="5631439013527180824">അസാധുവായ ഉപകരണ മാനേജ്മെന്റ് ടോക്കൺ</translation>
+<translation id="5632627355679805402"><ph name="TIME" />-ന് <ph name="BEGIN_LINK" />Google പാസ്‌വേഡ്‌<ph name="END_LINK" /> ഉപയോഗിച്ച്‌ നിങ്ങളുടെ ഡാറ്റ എൻക്രിപ്‌റ്റ് ചെയ്‌തു. സമന്വയിപ്പിക്കൽ തുടങ്ങുന്നതിന് ഇത് നൽകുക.</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="563324245173044180">തെറ്റിദ്ധരിപ്പിക്കുന്ന ഉള്ളടക്കം ബ്ലോക്കുചെയ്‌തു.</translation>
<translation id="5659593005791499971">ഇമെയില്‍</translation>
+<translation id="5663614846592581799">9x11 (എൻവലപ്പ്)</translation>
+<translation id="5663955426505430495">ഈ ഉപകരണത്തിൻ്റെ അഡ്‌മിനിസ്‌ട്രേറ്റർ അധിക ഫംഗ്ഷനുകൾക്കുള്ള വിപുലീകരണങ്ങൾ ഇൻസ്‌റ്റാൾ ചെയ്‌തിരിക്കുന്നു. വിപുലീകരണങ്ങൾക്ക് നിങ്ങളുടെ ചില ഡാറ്റയിലേക്ക് ആക്‌സസ് ഉണ്ട്.</translation>
<translation id="5675650730144413517">ഈ പേജ് പ്രവർത്തിക്കുന്നില്ല</translation>
+<translation id="5684874026226664614">ക്ഷമിക്കണം. ഈ പേജ് വിവർത്തനം ചെയ്യാനായില്ല.</translation>
<translation id="5685654322157854305">ഷിപ്പിംഗ് വിലാസം ചേർക്കുക</translation>
<translation id="5689199277474810259">JSON-ലേക്ക് ‌എക്‌സ്‌പോർട്ട് ചെയ്യുക</translation>
<translation id="5689516760719285838">ലൊക്കേഷൻ</translation>
@@ -752,38 +854,39 @@
<translation id="5710435578057952990">ഈ വെബ്സൈറ്റിന്റെ വ്യക്തിത്വം പരിശോധിച്ചിട്ടില്ല.</translation>
<translation id="5719499550583120431">പ്രീപെയ്ഡ് കാർഡുകൾ സ്വീകരിക്കുന്നു.</translation>
<translation id="5720705177508910913">നിലവിലെ ഉപയോക്താവ്</translation>
+<translation id="5728056243719941842">C5 (എൻവലപ്പ്)</translation>
<translation id="5730040223043577876">മറ്റ് സൈറ്റുകളിൽ നിങ്ങളുടെ പാസ്‌വേഡ് പുനരുപയോഗിച്ചിട്ടുണ്ടെങ്കിൽ, അത് പുനഃസജ്ജീകരിക്കാൻ Chrome ശുപാർശ ചെയ്യുന്നു.</translation>
<translation id="5732392974455271431">നിങ്ങൾക്ക് വേണ്ടി ഇത് അൺബ്ലോക്കുചെയ്യാൻ രക്ഷിതാക്കൾക്ക് കഴിയും</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{നിങ്ങളുടെ Google അക്കൗണ്ടിൽ കാർഡ് സംരക്ഷിക്കുക}other{നിങ്ങളുടെ Google അക്കൗണ്ടിൽ കാർഡുകൾ സംരക്ഷിക്കുക}}</translation>
<translation id="5763042198335101085">ശരിയായ ഇമെയിൽ വിലാസം നൽകുക</translation>
<translation id="5765072501007116331">ഡെലിവറി രീതികളും ആവശ്യകതകളും കാണാൻ ഒരു വിലാസം തിരഞ്ഞെടുക്കുക</translation>
-<translation id="5770114862687765385">ഫയൽ കേടായതായി തോന്നുന്നു. സെഷന്‍ പുനഃസജ്ജീകരിക്കാൻ 'പുനഃസജ്ജീകരിക്കുക' ബട്ടൺ ക്ലിക്ക് ചെയ്യുക.</translation>
<translation id="5778550464785688721">MIDI ഉപകരണങ്ങളുടെ പൂർണ നിയന്ത്രണം</translation>
<translation id="578305955206182703">ആംബർ</translation>
<translation id="57838592816432529">മ്യൂട്ടുചെയ്യുക</translation>
<translation id="5784606427469807560">നിങ്ങളുടെ കാർഡ് സ്ഥിരീകരിക്കുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഇന്റർനെറ്റ് കണക്ഷൻ പരിശോധിച്ച്, വീണ്ടും ശ്രമിക്കുക.</translation>
<translation id="5785756445106461925">കൂടാതെ, ഈ പേജിൽ സുരക്ഷിതമല്ലാത്ത മറ്റ് ഉറവിടങ്ങൾ ഉൾപ്പെടുന്നു. ഈ ഉറവിടങ്ങൾ കൈമാറുന്നതിനിടെ മറ്റുള്ളവർക്ക് കാണാനും പേജിന്റെ രൂപം മാറ്റുന്ന തരത്തിൽ ഒരു ആക്രമണകാരിയ്‌ക്ക് പരിഷ്‌ക്കരിക്കാനുമായേക്കും.</translation>
<translation id="5786044859038896871">നിങ്ങളുടെ കാർഡ് വിവരം പൂരിപ്പിക്കണോ?</translation>
+<translation id="5798290721819630480">മാറ്റങ്ങൾ നിരസിക്കണോ?</translation>
<translation id="5798683403665926540">Chrome ക്രമീകരണത്തിൽ ഹോം പേജ് മാറ്റുക</translation>
<translation id="5803412860119678065">നിങ്ങളുടെ <ph name="CARD_DETAIL" /> പൂരിപ്പിക്കണോ?</translation>
<translation id="5804241973901381774">അനുമതികൾ</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" /> എന്നതിലേക്കുള്ള നിങ്ങളുടെ കണക്ഷൻ കാലഹരണപ്പെട്ട സൈഫർ സ്യൂട്ട് ഉപയോഗിച്ച് എൻക്രിപ്റ്റുചെയ്‌തിരിക്കുന്നു.</translation>
<translation id="5813119285467412249">&amp;ചേർത്തത് വീണ്ടും ചെയ്യുക</translation>
<translation id="5838278095973806738">അക്രമകാരികൾ മോഷ്‌ടിക്കാൻ സാധ്യതയുള്ളതിനാൽ ഈ സൈറ്റിൽ നിങ്ങളുടെ രഹസ്യ വിവരങ്ങളൊന്നും (ഉദാഹരണത്തിന്, പാസ്‌വേഡുകളോ ക്രെഡിറ്റ് കാർഡുകളോ പോലുള്ളവ) നൽകരുത്.</translation>
+<translation id="5860033963881614850">ഓഫാക്കുക</translation>
<translation id="5863847714970149516">മുമ്പോട്ടുള്ള പേജ് നിങ്ങളിൽ നിന്ന് പണമീടാക്കാൻ ശ്രമിച്ചേക്കാം</translation>
<translation id="5866257070973731571">ഫോണ്‍ നമ്പര്‍ ചേര്‍ക്കുക</translation>
<translation id="5869405914158311789">ഈ സൈറ്റ് ലഭ്യമാക്കാനാകുന്നില്ല</translation>
<translation id="5869522115854928033">സംരക്ഷിച്ച പാസ്‌വേഡുകള്‍</translation>
<translation id="5887400589839399685">കാർഡ് സംരക്ഷിച്ചു</translation>
-<translation id="5893718151540690985">നെറ്റ്‌വർക്ക് ഇന്റർഫേസുകളുടെ ലിസ്റ്റും അതിൻ്റെ തരങ്ങളും ഹാർഡ്‌വെയർ വിലാസങ്ങളും റിപ്പോർട്ട് ചെയ്യുക</translation>
<translation id="5893752035575986141">ക്രെഡിറ്റ് കാർഡുകൾ സ്വീകരിക്കുന്നു.</translation>
<translation id="5901630391730855834">മഞ്ഞ</translation>
<translation id="5908541034548427511"><ph name="TYPE_1" /> (സമന്വയിപ്പിച്ചത്)</translation>
-<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ഒരെണ്ണം ഉപയോഗത്തിലുണ്ട്}other{# എണ്ണം ഉപയോഗത്തിലുണ്ട്}}</translation>
+<translation id="5916664084637901428">ഓൺ ചെയ്യുക</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google അക്കൗണ്ടിൽ കാർഡ് സംരക്ഷിക്കണോ?</translation>
<translation id="5922853866070715753">ഏതാണ്ട് പൂർത്തിയായി</translation>
<translation id="5932224571077948991">അനാവശ്യമോ തെറ്റിദ്ധരിപ്പിക്കുന്നതോ ആയ പരസ്യങ്ങള്‍ കാണിക്കുന്ന സൈറ്റ്</translation>
-<translation id="5939518447894949180">വീണ്ടും സജ്ജീകരിക്കുക</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> തുറക്കുന്നു…</translation>
<translation id="5951495562196540101">ഉപയോക്തൃ അക്കൗണ്ട് ഉപയോഗിച്ച് എൻറോൾ ചെയ്യാനാവില്ല (പാക്കേജ് ചെയ്‌ത ലൈസൻസ് ലഭ്യമാണ്).</translation>
<translation id="5967592137238574583">കോൺടാക്‌റ്റ് വിവരം എഡിറ്റുചെയ്യുക</translation>
@@ -791,6 +894,7 @@
<translation id="5975083100439434680">സൂം ഔട്ട്</translation>
<translation id="5977489021191000276">നിങ്ങളുടെ ഉപകരണം അഡ്‌മിനിസ്ട്രേറ്റർ മാനേജ് ചെയ്യുന്നില്ല.</translation>
<translation id="5977976211062815271">ഈ ഉപകരണത്തിലേത്</translation>
+<translation id="5980920751713728343">സൂചിക-3x5</translation>
<translation id="598637245381783098">പേയ്‌മെന്റ് ആപ്പ് തുറക്കാനായില്ല</translation>
<translation id="5989320800837274978">ഒരു സ്ഥിരമായ പ്രോക്സി സെർവർ അല്ലെങ്കിൽ ഒരു .pac സ്‌ക്രിപ്റ്റ് URL വ്യക്തമാക്കിയിട്ടില്ല.</translation>
<translation id="5990559369517809815">സെർവറിലേക്കുള്ള അഭ്യർത്ഥനകൾ ഒരു വിപുലീകരണം തടഞ്ഞു.</translation>
@@ -801,8 +905,8 @@
<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="6033927989869462158">CPU/RAM ഉപയോഗം പോലുള്ള ഹാർഡ്‌വെയർ സ്ഥിതിവിവരക്കണക്കുകൾ റിപ്പോർട്ട് ചെയ്യുക</translation>
<translation id="6034000775414344507">ഇളം ചാരനിറം</translation>
+<translation id="6034283069659657473">10x14 (എൻവലപ്പ്)</translation>
<translation id="6039846035001940113">പ്രശ്‌നം പരിഹരിക്കപ്പെടുന്നില്ലെങ്കിൽ, സൈറ്റ് ഉടമയെ ബന്ധപ്പെടുക.</translation>
<translation id="6040143037577758943">അടയ്ക്കുക</translation>
<translation id="6044573915096792553">വലുപ്പം 12</translation>
@@ -811,10 +915,10 @@
<translation id="6051221802930200923"><ph name="SITE" /> എന്ന വെബ്‌സൈറ്റ് സർട്ടിഫിക്കറ്റ് പിന്നിംഗ് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങൾക്കിപ്പോൾ അത് സന്ദർശിക്കാനാകില്ല. നെറ്റ്‌വർക്ക് പിശകുകളും ആക്രമണങ്ങളും സാധാരണയായി താൽക്കാലികമായിരിക്കും, അതിനാൽ ഈ പേജ് മിക്കവാറും പിന്നീട് പ്രവർത്തിക്കും.</translation>
<translation id="6058977677006700226">നിങ്ങളുടെ എല്ലാ ഉപകരണങ്ങളിലും നിങ്ങളുടെ കാർഡുകൾ ഉപയോഗിക്കണോ?</translation>
<translation id="6059925163896151826">USB ഉപകരണങ്ങൾ</translation>
-<translation id="6071091556643036997">സാധുതയില്ലാത്ത നയ തരം.</translation>
<translation id="6080696365213338172">അഡ്‌മിനിസ്‌ട്രേറ്റർ നൽകിയ സർട്ടിഫിക്കറ്റ് ഉപയോഗിച്ച് നിങ്ങൾ ഉള്ളടക്കം ആക്‌സസ്സുചെയ്‌തു. നിങ്ങൾ <ph name="DOMAIN" /> എന്നതിലേക്ക് നൽകുന്ന ഡാറ്റ അഡ്‌മിനിസ്‌ട്രേറ്റർക്ക് തടയാനാവും.</translation>
<translation id="6094273045989040137">അനോട്ടേറ്റ് ചെയ്യുക</translation>
<translation id="610911394827799129">നിങ്ങളുടെ Google അക്കൗണ്ടിന് <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> എന്നതിൽ മറ്റ് തരത്തിലുള്ള ബ്രൗസിംഗ് ചരിത്രമുണ്ടായിരിക്കാം.</translation>
+<translation id="6132597952260690497">ഇൻസ്‌റ്റാൾ ചെയ്‌ത വിപുലീകരണങ്ങളെയും പ്ലഗിന്നുകളെയും കുറിച്ചുള്ള വിവരങ്ങൾ</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു പാസ്‌വേഡ് (സമന്വയിപ്പിച്ചത്)}other{# പാസ്‌വേഡുകൾ (സമന്വയിപ്പിച്ചത്)}}</translation>
<translation id="6146055958333702838">എല്ലാ കേബിളുകളും പരിശോധിക്കുക ഒപ്പം ഏതെങ്കിലും റൂട്ടറുകൾ, മോഡങ്ങൾ നിങ്ങൾ ഉപയോഗിക്കാനിടയുള്ള മറ്റ് നെറ്റ്‌വർക്ക് ഉപകരണങ്ങൾ എന്നിവ റീബൂട്ട് ചെയ്യുക.</translation>
<translation id="614940544461990577">പരീക്ഷിച്ചുനോക്കൂ:</translation>
@@ -848,15 +952,21 @@
<translation id="6337133576188860026"><ph name="SIZE" />-യിൽ കുറഞ്ഞ ഡാറ്റ ലാഭിക്കുന്നു.അടുത്തതവണ നിങ്ങൾ സന്ദർശിക്കുമ്പോൾ ചില സൈറ്റുകൾ ഇതിനേക്കാൾ പതുക്കെ ലോഡാകാം.</translation>
<translation id="6337534724793800597">പേരിന്റെ ക്രമത്തിൽ നയങ്ങൾ ഫിൽട്ടർ ചെയ്യുക</translation>
<translation id="6358450015545214790">ഇത് അര്‍ത്ഥമാക്കുന്നതെന്താണ്?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">ഭാവിയില്‍ നിരക്കുകള്‍ ഈടാക്കാനിടയുണ്ട്.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{മറ്റൊരു നിർദ്ദേശം}other{മറ്റ് # നിർദ്ദേശങ്ങൾ}}</translation>
<translation id="6387754724289022810">അടുത്ത പ്രാവശ്യം വേഗത്തിൽ പണമടയ്ക്കാൻ, നിങ്ങളുടെ Google അക്കൗണ്ടിലും ഈ ഉപകരണത്തിലും ഈ കാർഡും ബില്ലിംഗ് വിലാസവും സംരക്ഷിക്കുക.</translation>
+<translation id="6390662030813198813">എഞ്ചിനീയറിംഗ്-E</translation>
<translation id="6404511346730675251">ബുക്ക്‌മാർക്ക് എഡിറ്റ് ചെയ്യുക</translation>
+<translation id="6406765186087300643">C0 (എൻവലപ്പ്)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />-ന്റെ കാലാവധി തീരുന്ന തീയതിയും CVC-യും നൽകുക</translation>
<translation id="6414888972213066896">ഈ സൈറ്റ് സന്ദർശിക്കുന്നതിന് നിങ്ങൾ രക്ഷിതാവിനോട് അനുമതി ആവശ്യപ്പെട്ടു</translation>
<translation id="6417515091412812850">സര്‍ട്ടിഫിക്കറ്റ് അസാധുവാക്കിയോ എന്ന് പരിശോധിക്കാനാവുന്നില്ല.</translation>
<translation id="6433490469411711332">കോൺടാക്‌റ്റ് വിവരം എഡിറ്റുചെയ്യുക</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> കണക്‌റ്റുചെയ്യൽ നിരസിച്ചു.</translation>
+<translation id="6434309073475700221">നിരാകരിക്കുക</translation>
+<translation id="6446163441502663861">കഹു (എൻവലപ്പ്)</translation>
<translation id="6446608382365791566">കൂടുതൽ വിവരങ്ങൾ ചേർക്കുക</translation>
<translation id="6447842834002726250">കുക്കികള്‍</translation>
<translation id="6451458296329894277">വീണ്ടും സമര്‍പ്പിക്കല്‍ അപേക്ഷ ഉറപ്പാക്കുക</translation>
@@ -869,11 +979,17 @@
<translation id="6508722015517270189">Chrome റീസ്‌റ്റാർട്ടുചെയ്യുക</translation>
<translation id="6529602333819889595">&amp;ഇല്ലാതാക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="6534179046333460208">ഫിസിക്കൽ വെബ് നിർദ്ദേശങ്ങൾ</translation>
+<translation id="6556866813142980365">വീണ്ടുംചെയ്യുക</translation>
<translation id="6563469144985748109">നിങ്ങളുടെ മാനേജർ ഇതുവരെ അംഗീകാരം നൽകിയിട്ടില്ല</translation>
<translation id="6569060085658103619">നിങ്ങൾ ഒരു വിപുലീകരണ പേജാണ് കാണുന്നത്</translation>
+<translation id="6578796323535178455">C2 (എൻവലപ്പ്)</translation>
<translation id="6579990219486187401">ഇളം പിങ്ക്</translation>
+<translation id="6583674473685352014">B6 (എൻവലപ്പ്)</translation>
+<translation id="6587923378399804057">നിങ്ങൾ പകർത്തിയ ലിങ്ക്</translation>
+<translation id="6591833882275308647">നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> മാനേജ് ചെയ്യപ്പെടുന്നില്ല</translation>
<translation id="6596325263575161958">എൻക്രിപ്‌ഷൻ ഓപ്‌ഷനുകൾ</translation>
<translation id="6604181099783169992">ചലന അല്ലെങ്കിൽ വെളിച്ച സെൻസറുകൾ</translation>
+<translation id="6609880536175561541">Prc7 (എൻവലപ്പ്)</translation>
<translation id="6624427990725312378">കോണ്‍ടാക്റ്റ് വിവരം</translation>
<translation id="6626291197371920147">ശരിയായ കാർഡ് നമ്പർ ചേർക്കുക</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> തിരയൽ</translation>
@@ -882,6 +998,7 @@
<translation id="6644283850729428850">ഈ നയം ഒഴിവാക്കി.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു സൈറ്റിൽ നിന്ന് (നിങ്ങൾ Google അക്കൗണ്ടിൽ നിന്ന് സൈൻ ഔട്ട് ചെയ്യപ്പെടില്ല)}other{# സൈറ്റുകളിൽ നിന്ന് (നിങ്ങൾ Google അക്കൗണ്ടിൽ നിന്ന് സൈൻ ഔട്ട് ചെയ്യപ്പെടില്ല)}}</translation>
<translation id="6657585470893396449">പാസ്‌വേഡ്</translation>
+<translation id="6670613747977017428">സുരക്ഷയിലേക്ക് മടങ്ങുക.</translation>
<translation id="6671697161687535275">Chromium-ത്തിൽ നിന്ന് ഫോം നിർദ്ദേശം നീക്കംചെയ്യണോ?</translation>
<translation id="6685834062052613830">സൈൻ ഔട്ട് ചെയ്‌ത്, സജ്ജമാക്കൽ പൂർത്തിയാക്കുക</translation>
<translation id="6710213216561001401">കഴിഞ്ഞ</translation>
@@ -889,12 +1006,15 @@
<translation id="671076103358959139">എന്‍‌റോള്‍‌മെന്‍റ് ടോക്കണ്‍:</translation>
<translation id="6711464428925977395">പ്രോക്‌സി സെർവറിൽ എന്തോ പ്രശ്‌നമുണ്ട്, അല്ലെങ്കിൽ വിലാസം തെറ്റാണ്.</translation>
<translation id="6723740634201835758">നിങ്ങളുടെ Google അക്കൗണ്ടിലേത്</translation>
+<translation id="6738516213925468394"><ph name="TIME" />-ന് നിങ്ങളുടെ <ph name="BEGIN_LINK" />സമന്വയ പാസ്‌ഫ്രെയ്‌സ്<ph name="END_LINK" /> ഉപയോഗിച്ച് ഡാറ്റ എൻക്രിപ്‌റ്റ് ചെയ്‌തു. സമന്വയം ആരംഭിക്കുന്നതിന് ഇത് നൽകുക.</translation>
<translation id="674375294223700098">അറിയപ്പെടാത്ത സെര്‍വര്‍ സര്‍ട്ടിഫിക്കറ്റ് പിശക്.</translation>
<translation id="6744009308914054259">കണക്‌ഷനായി കാത്തിരിക്കുമ്പോൾ, ഓഫ്‌ലൈൻ ലേഖനങ്ങൾ വായിക്കാനായി നിങ്ങൾക്ക് ഡൗൺലോഡുകൾ സന്ദർശിക്കാം.</translation>
<translation id="6753269504797312559">നയ മൂല്യം</translation>
<translation id="6757797048963528358">നിങ്ങളുടെ ഉപകരണം സുഷുപ്‌തിയിലായി.</translation>
+<translation id="6768213884286397650">ഹഗാക്കി (പോസ്‌റ്റ്‌കാർഡ്)</translation>
<translation id="6778737459546443941">നിങ്ങളുടെ രക്ഷിതാവ് ഇതുവരെ അംഗീകാരം നൽകിയിട്ടില്ല</translation>
<translation id="67862343314499040">വയലറ്റ്</translation>
+<translation id="6786747875388722282">വിപുലീകരണങ്ങള്‍</translation>
<translation id="679355240208270552">നയ പ്രകാരം, ഡിഫോൾട്ട് തിരയൽ പ്രവർത്തനക്ഷമമാക്കാത്തതിനാൽ അവഗണിച്ചു.</translation>
<translation id="681021252041861472">ഇത് പൂരിപ്പിക്കേണ്ടതുണ്ട്</translation>
<translation id="6810899417690483278">ഇഷ്‌ടാനുസൃതമാക്കൽ ഐഡി</translation>
@@ -927,10 +1047,12 @@
<translation id="6965978654500191972">ഉപാധി</translation>
<translation id="6970216967273061347">ജില്ല</translation>
<translation id="6973656660372572881">സ്ഥിരമായ പ്രോക്‌സി സെർവറുകളും ഒരു സ്‌ക്രിപ്റ്റ് URL-ഉം വ്യക്തമാക്കിയിരിക്കുന്നു.</translation>
+<translation id="6973932557599545801">ക്ഷമിക്കണം, എനിക്ക് സഹായിക്കാൻ കഴിയില്ല, സ്വയം പൂരിപ്പിക്കുക.</translation>
<translation id="6979158407327259162">Google ഡ്രൈവ്</translation>
<translation id="6979440798594660689">മ്യൂട്ട് ചെയ്യുക (ഡിഫോൾട്ട്)</translation>
<translation id="6984479912851154518">ഒരു എക്‌സ്‌റ്റേണൽ അപ്ലിക്കേഷൻ വഴി പണമടയ്‌ക്കുന്നതിന് വേണ്ടി സ്വകാര്യ മോഡ് വിടുന്നു. തുടരണോ?</translation>
<translation id="6989763994942163495">വിപുലമായ ക്രമീകരണങ്ങൾ കാണിക്കുക...</translation>
+<translation id="6993898126790112050">6x9 (എൻവലപ്പ്)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> എല്ലായ്‌പ്പോഴും വിവർത്തനം ചെയ്യുക</translation>
<translation id="7012363358306927923">ചൈന UnionPay</translation>
<translation id="7016992613359344582">ഈ നിരക്കുകൾ ഒറ്റത്തവണ അടയ്ക്കുന്നതോ അല്ലെങ്കിൽ ആവർത്തിക്കുന്നവയോ ആവാം, ഒപ്പം വ്യക്തമല്ലായിരിക്കാം.</translation>
@@ -946,28 +1068,33 @@
<translation id="7108338896283013870">മറയ്ക്കുക</translation>
<translation id="7108819624672055576">ഒരു വിപുലീകരണം മുഖേന അവദിച്ചിരിക്കുന്നു</translation>
<translation id="7111012039238467737">(സാധുതയുള്ളത്)</translation>
+<translation id="7118618213916969306">ക്ലിപ്പ്ബോർഡ് URL-നുള്ള തിരയൽ, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">മറ്റ് ടാബുകളോ പ്രോഗ്രാമുകളോ അടയ്‌ക്കുക</translation>
<translation id="7129409597930077180">ഈ വിലാസത്തിലേക്ക് ഷിപ്പ് ചെയ്യാൻ കഴിയില്ല. മറ്റൊരു വിലാസം തിരഞ്ഞെടുക്കുക.</translation>
<translation id="7135130955892390533">സ്‌റ്റാറ്റസ് കാണിക്കുക</translation>
<translation id="7138472120740807366">ഡെലിവറി രീതി</translation>
<translation id="7139724024395191329">എമിറേറ്റ്</translation>
+<translation id="7152423860607593928">നമ്പർ-14 (എൻവലപ്പ്)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ലാവെൻഡർ</translation>
-<translation id="7158980942472052083">URL അസാധുവാണ്. സ്‌റ്റാൻഡേർഡ് സ്‌കീമുള്ള URL ആയിരിക്കണം.</translation>
<translation id="717330890047184534">Gaia ഐഡി:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">സെർവർ ഉപയോഗിച്ച് നിങ്ങൾ പോകുന്ന <ph name="ORIGIN" /> സൈറ്റ്, അതിൻ്റെ എല്ലാ അഭ്യർത്ഥനകളിലേക്കും ഒരു സുരക്ഷാ നയം ബാധകമാക്കുമെന്ന് ഇത് അഭ്യർത്ഥിച്ചിരിക്കുന്നു. എന്നാൽ ഒരു നയം നിർവഹിക്കുന്നതിന് പകരം ഇത് ബ്രൗസറിനെ മറ്റിടത്തേയ്ക്ക് റീഡയറക്‌ട് ചെയ്‌തതിനാൽ, <ph name="SITE" />എന്നതിനുള്ള നിങ്ങളുടെ അഭ്യർത്ഥന പൂർത്തീകരിക്കാൻ ബ്രൗസറിന് കഴിയുന്നില്ല.</translation>
<translation id="7179323680825933600">പേയ്‌മെന്റ് രീതികൾ സംരക്ഷിച്ച് പൂരിപ്പിക്കുക</translation>
<translation id="7180611975245234373">പുതുക്കുക</translation>
<translation id="7182878459783632708">നയങ്ങളൊന്നും സജ്ജമാക്കിയിട്ടില്ല</translation>
<translation id="7186367841673660872">ഈ പേജ്<ph name="ORIGINAL_LANGUAGE" />ല്‍‌ നിന്നും<ph name="LANGUAGE_LANGUAGE" />ലേക്ക് വിവര്‍‌ത്തനം ചെയ്‌തു</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> ലാഭിക്കുക. നിങ്ങളുടെ അടുത്ത സന്ദർശനത്തിൽ ചില സൈറ്റുകൾ സാവധാനത്തിൽ ലോഡുചെയ്‌തേക്കാം.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർക്ക് ഇവ കാണാനാകും:</translation>
+<translation id="7202346780273620635">ലെറ്റർ-അധികം</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" />, സുരക്ഷാ മാനദണ്ഡങ്ങൾ പാലിക്കുന്നില്ല.</translation>
<translation id="721197778055552897">ഈ പ്രശ്‌നത്തെക്കുറിച്ച് <ph name="BEGIN_LINK" />കൂടുതൽ‍ മനസിലാക്കുക<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">കണക്ഷന്‍ <ph name="SSL_VERSION" /> ഉപയോഗിക്കുന്നു.</translation>
<translation id="7220786058474068424">പ്രോസസ്സുചെയ്യുന്നു</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">സൈറ്റിൽ മാൽവെയർ അടങ്ങിയിരിക്കുന്നു</translation>
+<translation id="724766306220616965">മുന്നറിയിപ്പുകൾ, പൊരുത്തക്കേട്</translation>
<translation id="724975217298816891">നിങ്ങളുടെ കാർഡ് വിശദാംശങ്ങൾ അപ്‌ഡേറ്റുചെയ്യാൻ <ph name="CREDIT_CARD" />-ന്റെ കാലാവധി തീരുന്ന തീയതിയും CVC-യും നൽകുക. സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, ഈ സൈറ്റുമായി കാർഡ് വിശദാംശങ്ങൾ പങ്കിടും.</translation>
<translation id="7251437084390964440">നെറ്റ്‌വർക്ക് കോൺഫിഗറേഷൻ, ONC നിലവാരത്തിന് അനുസരിച്ചുള്ളതല്ല. കോൺഫിഗറേഷൻ ഭാഗങ്ങൾ ഇമ്പോർട്ട് ചെയ്‌തേക്കില്ല.
കൂടുതൽ വിശദാംശങ്ങൾ:
@@ -980,11 +1107,14 @@
<translation id="7300012071106347854">കൊബാൾട്ട് നീല</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />-ന് ക്യാപ്‌ചർ ചെയ്‌ത ക്രാഷ് റിപ്പോർട്ടുകൾ (ഉപയോക്താവ് അഭ്യർത്ഥിച്ച അപ്‌ലോഡ്, ഇതുവരെ അപ്‌ലോഡുചെയ്‌തിട്ടില്ല)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />സുരക്ഷിത ബ്രൗസിംഗ്<ph name="END_LINK" /> മുന്നറിയിപ്പുകൾ</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">കണക്ഷൻ സഹായം</translation>
<translation id="7334320624316649418">&amp;പുനഃക്രമീകരിക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="733923710415886693">സർട്ടിഫിക്കറ്റ് സുതാര്യതയിലൂടെ സെർവറുടെ സർട്ടിഫിക്കറ്റ് വെളിപ്പെടുത്തിയിട്ടില്ല.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-അധികം</translation>
<translation id="7353601530677266744">കമാന്‍റ് ലൈന്‍‌</translation>
-<translation id="7365061714576910172">ലിനക്സ് എക്സ്പോർട്ട് ചെയ്യുക</translation>
<translation id="7372973238305370288">തിരയൽ ഫലം</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">വേണ്ട</translation>
@@ -992,6 +1122,7 @@
<translation id="7381288752349550461">മാനേജ് ചെയ്യപ്പെടുന്ന സെഷന്‍ അസാധുവാക്കി</translation>
<translation id="7390545607259442187">കാർഡ് സ്ഥിരീകരിക്കുക</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">നിങ്ങളുടെ <ph name="DEVICE_NAME" /> മാനേജ് ചെയ്യപ്പെട്ടിരിക്കുന്നു</translation>
<translation id="7407424307057130981">&lt;p&gt;നിങ്ങളുടെ Windows കമ്പ്യൂട്ടറിൽ Superfish സോഫ്റ്റ്‌വെയർ ഉണ്ടെങ്കിൽ, നിങ്ങൾ ഈ പിശക് കാണും.&lt;/p&gt;
&lt;p&gt;നിങ്ങൾക്ക് വെബിലേക്ക് കണക്‌റ്റ് ചെയ്യാൻ, സോഫ്‌റ്റ്‌വെയർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കാൻ ഈ ഘട്ടങ്ങൾ പിന്തുടരുക. നിങ്ങൾക്ക് അഡ്‌മിനിസ്ട്രേറ്ററുടെ സവിശേഷാധികാരങ്ങൾ ആവശ്യമായിവരും.&lt;/p&gt;
&lt;ol&gt;
@@ -1000,7 +1131,7 @@
&lt;strong&gt;സ്റ്റാർട്ടപ്പ് തരം/strong&gt; എന്നതിന് താഴെ, &lt;strong&gt;പ്രവർത്തനരഹിതമാക്കി&lt;/strong&gt; തിരഞ്ഞെടുക്കുക &lt;li&gt;&lt;strong&gt;സേവന നില&lt;/strong&gt; എന്നതിന് താഴെ, &lt;strong&gt;നിർത്തുക&lt;/strong&gt; ക്ലിക്ക് ചെയ്യുക &lt;li&gt;&lt;strong&gt;പ്രയോഗിക്കുക&lt;/strong&gt; ക്ലിക്ക് ചെയ്യുക, തുടർന്ന് &lt;strong&gt;ശരി&lt;/strong&gt; ക്ലിക്ക് ചെയ്യുക &lt;li&gt;
നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ നിന്ന് എങ്ങനെയാണ് സോഫ്റ്റ്‌വെയർ ശാശ്വതമായി നീക്കംചെയ്യുന്നത് എന്നറിയാൻ &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome സഹായ കേന്ദ്രം&lt;/a&gt; സന്ദർശിക്കുക &lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> മാനേജ്‌മെൻ്റ്</translation>
+<translation id="741007362987735528">വിസ്‌തൃത-ഫോർമാറ്റ്</translation>
<translation id="7416351320495623771">പാസ്‌വേഡുകൾ മാനേജ് ചെയ്യുക…</translation>
<translation id="7419106976560586862">പ്രൊഫൈൽ പാത</translation>
<translation id="7437289804838430631">ബന്ധപ്പെടാനുള്ള വിവരങ്ങൾ ചേർക്കുക</translation>
@@ -1009,22 +1140,24 @@
<translation id="7442725080345379071">ഇളം ഓറഞ്ച് നിറം</translation>
<translation id="7444046173054089907">ഈ സൈറ്റ് ബ്ലോക്കുചെയ്‌തു</translation>
<translation id="7445762425076701745">നിങ്ങള്‍ ബന്ധിപ്പിച്ച സെര്‍വറിന്‍റെ ഐഡന്‍റിറ്റി പൂര്‍ണ്ണമായി സാധൂകരിക്കാന്‍ കഴിയില്ല. നിങ്ങളുടെ നെറ്റ്‍വര്‍ക്കില്‍ മാത്രം സാധുവായ ഒരു നാമം ഉപയോഗിക്കുന്ന സെര്‍വറിലേക്ക് നിങ്ങള്‍ ബന്ധിപ്പിച്ചിരിക്കുന്നു, അതിന്‍റെ ഉടമസ്ഥാവകാശം ഒരു ബാഹ്യ അതോറിറ്റിയ്ക്ക് ഒരിക്കലും സാധൂകരിക്കാന്‍ കഴിയില്ല. ചില സാക്‍ഷ്യപത്ര അതോറിറ്റികള്‍ ഈ നാമങ്ങളെ കണക്കാക്കാതെ സാക്‍ഷ്യപത്രങ്ങള്‍ നല്‍കുന്നതിനാല്‍, ഉദ്ദേശിച്ച വെബ്സൈറ്റിലേക്കാണ് നിങ്ങള്‍ ബന്ധിപ്പിച്ചിരിക്കുന്നതെന്നും ഒരു ആക്രമണകാരിയല്ലെന്നും ഉറപ്പാക്കാന്‍ ഒരു മാര്‍ഗ്ഗവുമില്ല.</translation>
-<translation id="7449109375006139765">മാനേജ്‌മെൻ്റ് സെർവറിലേക്ക് സിസ്‌റ്റം ലോഗുകൾ അയയ്‌ക്കുക</translation>
<translation id="7451311239929941790">ഈ പ്രശ്‌നത്തെക്കുറിച്ച് <ph name="BEGIN_LINK" />കൂടുതലറിയുന്നു<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">ഗ്ലോബൽ ഡിഫോൾട്ട് ഉപയോഗിക്കുക (തടയുക)</translation>
<translation id="7460618730930299168">നിങ്ങൾ തിരഞ്ഞെടുത്തതിൽ നിന്ന് വ്യത്യസ്‌തമാണ് ഈ സ്ക്രീനിംഗ്. തുടരണോ?</translation>
<translation id="7473891865547856676">വേണ്ട, നന്ദി</translation>
-<translation id="7475525192983021547">ഉപയോക്താവ് ഉപകരണത്തിൽ സജീവമായിരിക്കുമ്പോൾ സമയ കാലയളവ് റിപ്പോർട്ട് ചെയ്യുക</translation>
<translation id="7481312909269577407">മുന്നോട്ട്</translation>
<translation id="7485870689360869515">ഡാറ്റകളൊന്നും കണ്ടെത്തിയില്ല.</translation>
+<translation id="7498234416455752244">എഡിറ്റ് ചെയ്യുന്നത് തുടരുക</translation>
<translation id="7508255263130623398">നൽകിയ നയ ഉപകരണ ഐഡി ശൂന്യമാണ് അല്ലെങ്കിൽ നിലവിലെ ഉപകരണ ഐഡിയുമായി യോജിക്കുന്നില്ല</translation>
<translation id="7508870219247277067">അവക്കാഡോ പച്ച</translation>
<translation id="7511955381719512146">നിങ്ങൾ ഉപയോഗിക്കുന്ന Wi-Fi <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> സന്ദർശിക്കാൻ നിങ്ങളോട് ആവശ്യപ്പെടാം.</translation>
<translation id="7514365320538308">ഡൗൺലോഡുചെയ്യുക</translation>
<translation id="7518003948725431193">വെബ് വിലാസത്തിനായി വെബ്‌പേജൊന്നും കണ്ടെത്തിയില്ല: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (എൻവലപ്പ്)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">ഈ സൈറ്റിലേക്കുള്ള നിങ്ങളുടെ കണക്ഷൻ സ്വകാര്യമല്ല</translation>
+<translation id="7535087603100972091">മൂല്യം</translation>
<translation id="7537536606612762813">നിർബന്ധിതം</translation>
+<translation id="7538364083937897561">A2 (എൻവലപ്പ്)</translation>
<translation id="7542403920425041731">സ്ഥിരീകരിച്ചുകഴിഞ്ഞാൽ, നിങ്ങളുടെ കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation>
<translation id="7542995811387359312">ഈ ഫോം ഒരു സുരക്ഷിത കണക്ഷന്‍ ഉപയോഗിക്കാത്തതിനാല്‍ സ്വപ്രേരിത ക്രെഡിറ്റ് കാര്‍ഡ് പൂരിപ്പിക്കല്‍ അപ്രാപ്തമാക്കി.</translation>
<translation id="7543525346216957623">നിങ്ങളുടെ രക്ഷിതാവിനോട്‌ ആവശ്യപ്പെടുക</translation>
@@ -1033,8 +1166,8 @@
<translation id="7552846755917812628">ഇനിപ്പറയുന്ന നുറുങ്ങുകൾ പരീക്ഷിക്കൂ:</translation>
<translation id="7554791636758816595">പുതിയ ടാബ്</translation>
<translation id="7564049878696755256">നിങ്ങളുടെ <ph name="ORG_NAME" /> അക്കൗണ്ടിലേക്കുള്ള ആക്‌സസ് നഷ്‌ടമാകാനോ നിങ്ങളുടെ ഐഡന്‍റിറ്റി മോഷ്ടിക്കപ്പെടാനോ സാധ്യതയുണ്ട്. ഇപ്പോൾ തന്നെ പാസ്‍വേഡ് മാറ്റാൻ Chrome ശുപാർശ ചെയ്യുന്നു.</translation>
-<translation id="7566125604157659769">നിങ്ങൾ പകർത്തിയ ടെക്‌സ്‌റ്റ്</translation>
<translation id="7567204685887185387">ഈ സെർവറിന് അത് <ph name="DOMAIN" /> ആണെന്ന് തെളിയിക്കാനായില്ല; സെർവറിന്റെ സുരക്ഷ സർട്ടിഫിക്കറ്റ് വഞ്ചനാപരമായി ഇഷ്യൂ ചെയ്‌തിരിക്കാം. തെറ്റായ കോൺഫിഗറേഷൻ കാരണമോ ഒരു അക്രമണകാരി നിങ്ങളുടെ കണക്ഷനെ തടസ്സപ്പെടുത്തുന്നത് കൊണ്ടോ ആയിരിക്കാം ഇത് സംഭവിച്ചത്.</translation>
+<translation id="7568105740864181217">ഈ ബ്രൗസർ മാനേജ് ചെയ്യുന്നത് ഒരു കമ്പനിയോ സ്‌കൂളോ മറ്റേതെങ്കിലും സ്ഥാപനമോ ആണ്. നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർക്ക് വിദൂരമായി ബ്രൗസർ സജ്ജീകരണം മാറ്റാം. ഈ ഉപകരണത്തിലെ ആക്‌റ്റിവിറ്റി Chrome-ന് പുറത്തും മാനേജ് ചെയ്യുന്നുണ്ടാകാം. <ph name="BEGIN_LINK" />കൂടുതലറിയുക<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome-ൽ നിന്ന് ക്രെഡിറ്റ് കാർഡ് നീക്കംചെയ്യണോ?</translation>
<translation id="7569983096843329377">കറുപ്പ്</translation>
<translation id="7578104083680115302">നിങ്ങൾ Google-ൽ സംരക്ഷിച്ച കാർഡുകൾ ഉപയോഗിച്ച് ഉപകരണങ്ങളിലുടനീളമുള്ള സൈറ്റുകളിലും ആപ്‌സിലും പെട്ടെന്ന് പണമടയ്‌ക്കുക.</translation>
@@ -1045,6 +1178,7 @@
<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="7633909222644580952">പ്രകടന ഡാറ്റയും ക്രാഷ് റിപ്പോർട്ടുകളും</translation>
<translation id="7637571805876720304">Chromium-ത്തിൽ നിന്ന് ക്രെഡിറ്റ് കാർഡ് നീക്കംചെയ്യണോ?</translation>
<translation id="7639968568612851608">കടും ചാരനിറം</translation>
<translation id="765676359832457558">വിപുലമായ ക്രമീകരണങ്ങൾ മറയ്‌ക്കുക...</translation>
@@ -1054,9 +1188,11 @@
<translation id="7667346355482952095">നൽകിയ നയ ടോക്കൺ ശൂന്യമാണ് അല്ലെങ്കിൽ നിലവിലെ ടോക്കണുമായി യോജിക്കുന്നില്ല</translation>
<translation id="7668654391829183341">അജ്ഞാതമായ ഉപകരണം</translation>
<translation id="7669271284792375604">ഈ സൈറ്റിലെ ആക്രമണകാരികൾ, ബ്രൗസർ അനുഭവത്തെ ദോഷകരമായി ബാധിക്കുന്ന പ്രോഗ്രാമുകൾ ഇൻസ്‌റ്റാൾ ചെയ്യിക്കുന്ന വിധത്തിൽ നിങ്ങളെ കബളിപ്പിക്കാൻ ശ്രമിച്ചേക്കും (ഉദാഹരണത്തിന്, നിങ്ങളുടെ ഹോംപേജ് മാറ്റുന്നതിലൂടെയോ അല്ലെങ്കിൽ സന്ദർശിക്കുന്ന സൈറ്റുകളിൽ കൂടുതൽ പരസ്യങ്ങൾ കാണിക്കുന്നതിലൂടെയോ).</translation>
+<translation id="7676643023259824263">ക്ലിപ്പ്‌ബോർഡ് ടെക്‌സ്‌റ്റിനായി തിരയുക, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">തിരയല്‍ യന്ത്രം മാറ്റുക</translation>
<translation id="7682287625158474539">ഷിപ്പിംഗ്</translation>
<translation id="7687186412095877299">നിങ്ങളുടെ സംരക്ഷിച്ച പേയ്‌മെന്‍റ് രീതികൾ ഉപയോഗിച്ച് പേയ്‌മെന്‍റ് ഫോമുകളിൽ പൂരിപ്പിക്കുന്നു</translation>
+<translation id="7697066736081121494">Prc8 (എൻവലപ്പ്)</translation>
<translation id="769721561045429135">ഇപ്പോൾ, ഈ ഉപകരണത്തിൽ മാത്രം ഉപയോഗിക്കാനാവുന്ന കാർഡുകൾ നിങ്ങൾക്കുണ്ട്. കാർഡുകൾ അവലോകനം ചെയ്യാൻ, 'തുടരുക' ക്ലിക്ക് ചെയ്യുക.</translation>
<translation id="7699293099605015246">ഇപ്പോൾ ലേഖനങ്ങൾ ലഭ്യമല്ല</translation>
<translation id="7701040980221191251">ഒന്നുമില്ല</translation>
@@ -1068,11 +1204,13 @@
<translation id="774634243536837715">അപകടകരമായ ഉള്ളടക്കം ബ്ലോക്കുചെയ്‌തു.</translation>
<translation id="7752995774971033316">നിയന്ത്രിക്കാനാകാത്തത്</translation>
<translation id="7755287808199759310">നിങ്ങൾക്ക് വേണ്ടി ഇത് അൺബ്ലോക്കുചെയ്യാൻ രക്ഷിതാവിന് കഴിയും</translation>
+<translation id="7757555340166475417">ഡായ്-പാ-കായ്</translation>
<translation id="7758069387465995638">ഫയർവാളോ ആന്റി വൈറസ് സോഫ്‌റ്റ്‌വെയറോ കണക്ഷൻ ബ്ലോക്കുചെയ്‌തിട്ടുണ്ടാകാം.</translation>
<translation id="7759163816903619567">പ്രദർശിപ്പിച്ച ഡൊമെയ്ന്‍:</translation>
<translation id="7761701407923456692">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് URL മായി പൊരുത്തപ്പെടുന്നില്ല.</translation>
<translation id="7763386264682878361">പേയ്‌മെന്റ് മാനിഫെസ്‌റ്റ് പാർസർ</translation>
<translation id="7764225426217299476">വിലാസം ചേർക്കുക</translation>
+<translation id="7770259615151589601">ഡെസിഗ്‌നേറ്റ് ചെയ്‌തത്-വലുത്</translation>
<translation id="777702478322588152">പ്രിഫെക്ച്വര്‍</translation>
<translation id="7791543448312431591">ചേര്‍ക്കൂ</translation>
<translation id="7793809570500803535"><ph name="SITE" /> എന്നതിലെ വെബ്‌പേജ് താല്‍‌ക്കാലികമായി പ്രവര്‍‌ത്തനരഹിതമായിരിക്കാം, അല്ലെങ്കില്‍‌ ഒരു പുതിയ വെബ് വിലാസത്തിലേക്ക് ശാശ്വതമായി നീക്കിയിരിക്കാം.</translation>
@@ -1084,8 +1222,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome-ൽ നിന്നുള്ള നിർദ്ദേശം നീക്കംചെയ്യണോ?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' എന്നതിന്റെ <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> കണ്ടു</translation>
-<translation id="7818867226424560206">പോളിസി മാനേജ്‌മെന്‍റ്</translation>
<translation id="782886543891417279">നിങ്ങൾ ഉപയോഗിക്കുന്ന Wi-Fi (<ph name="WIFI_NAME" />) അതിന്റെ ലോഗിൻ പേജ് സന്ദർശിക്കാൻ ആവശ്യപ്പെടാം..</translation>
+<translation id="7836231406687464395">പോസ്‌റ്റ്ഫിക്‌സ് (എൻവലപ്പ്)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ഒന്നുമില്ല}=1{ഒരു ആപ്പ് (<ph name="EXAMPLE_APP_1" />)}=2{2 ആപ്പുകൾ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# ആപ്പുകൾ (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">എന്നിരുന്നാലും നിങ്ങൾ അദൃശ്യനല്ല. ആൾമാറാട്ടത്തിലേയ്‌ക്ക് പോകുന്നത്, നിങ്ങളുടെ തൊഴിൽ ദാതാവിൽ നിന്നോ ഇന്റർനെറ്റ് സേവന ദാതാവിൽ നിന്നോ നിങ്ങൾ സന്ദർശിക്കുന്ന വെബ്‌സൈറ്റുകളിൽ നിന്നോ ഉള്ള ബ്രൗസിംഗിനെ മറയ്‌ക്കില്ല.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1094,7 +1232,7 @@
<translation id="7878562273885520351">നിങ്ങളുടെ പാസ്‍വേഡ് അപഹരിക്കപ്പെട്ടേക്കാം</translation>
<translation id="7882421473871500483">തവിട്ട് നിറം</translation>
<translation id="7887683347370398519">നിങ്ങളുടെ CVC പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക</translation>
-<translation id="7893255318348328562">സെഷൻ പേര്</translation>
+<translation id="7904208859782148177">C3 (എൻവലപ്പ്)</translation>
<translation id="79338296614623784">ശരിയായ ഒരു ഫോൺ നമ്പർ നൽകുക</translation>
<translation id="7935318582918952113">DOM ഡിസ്‌റ്റിലർ</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" />-ന് കാലഹരണപ്പെടുന്നു</translation>
@@ -1104,21 +1242,25 @@
<translation id="7951415247503192394">(32-ബിറ്റ്)</translation>
<translation id="7956713633345437162">മൊബൈൽ ബുക്ക്‌മാർക്കുകൾ</translation>
<translation id="7961015016161918242">ഒരിക്കലും</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">വ്യക്തമാക്കിയിട്ടില്ല</translation>
<translation id="800218591365569300">ഇടം സൃഷ്‌ടിക്കാൻ മറ്റ് ടാബുകളോ പ്രോഗ്രാമുകളോ അടയ്‌ക്കുന്നത് പരീക്ഷിക്കൂ.</translation>
+<translation id="8004582292198964060">ബ്രൗസര്‍</translation>
<translation id="8009225694047762179">പാസ്‌വേഡുകൾ മാനേജ് ചെയ്യുക</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{ഈ കാർഡും അവയുടെ ബില്ലിംഗ് വിലാസവും സംരക്ഷിക്കപ്പെടും. നിങ്ങൾ <ph name="USER_EMAIL" /> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്‌തിരിക്കുമ്പോൾ അത് ഉപയോഗിക്കാനാകും.}other{ഈ കാർഡുകളും അവയുടെ ബില്ലിംഗ് വിലാസങ്ങളും സംരക്ഷിക്കപ്പെടും. നിങ്ങൾ <ph name="USER_EMAIL" /> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്‌തിരിക്കുമ്പോൾ അവ ഉപയോഗിക്കാനാകും.}}</translation>
<translation id="8012647001091218357">ഇപ്പോൾ ഞങ്ങൾക്ക് നിങ്ങളുടെ രക്ഷകർത്താക്കളെ ബന്ധപ്പെടാനായില്ല. വീണ്ടും ശ്രമിക്കുക.</translation>
<translation id="8025119109950072390">ഈ സൈറ്റിലെ ആക്രമണകാരികൾ സോഫ്‌റ്റ്‌വെയർ ഇൻസ്റ്റാൾ ചെയ്യുന്നതോ വ്യക്തിപരമായ വിവരങ്ങൾ വെളിപ്പെടുത്തുന്നതോ (ഉദാഹരണത്തിന്, പാസ്‌വേഡുകൾ, ഫോൺ നമ്പറുകൾ, ക്രെഡിറ്റ് കാർഡുകൾ എന്നീ വിവരങ്ങൾ) പോലുള്ള അപകടകരമായ കാര്യങ്ങൾ ചെയ്യിപ്പിക്കുന്ന തരത്തിൽ നിങ്ങളെ കബളിപ്പിച്ചേക്കാം.</translation>
<translation id="8034522405403831421">ഈ പേജ് <ph name="SOURCE_LANGUAGE" />-ലാണ്. <ph name="TARGET_LANGUAGE" />-ലേക്ക് വിവർത്തനം ചെയ്യണോ?</translation>
<translation id="8035152190676905274">പേന</translation>
+<translation id="8037117624646282037">അടുത്തിടെ ഉപകരണം ഉപയോഗിച്ചവർ</translation>
<translation id="8037357227543935929">ചോദിക്കുക (ഡിഫോൾട്ട്)</translation>
<translation id="803771048473350947">ഫയല്‍</translation>
<translation id="8041089156583427627">ഫീഡ്ബാക്ക് അയയ്ക്കുക</translation>
<translation id="8041940743680923270">ഗ്ലോബൽ ഡിഫോൾട്ട് ഉപയോഗിക്കുക (ചോദിക്കുക)</translation>
<translation id="8042918947222776840">പിക്കപ്പ് രീതി തിരഞ്ഞെടുക്കുക</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" ശരിയായി കോൺഫിഗർ ചെയ്‌‌തിട്ടില്ല. സാധാരണഗതിയിൽ "<ph name="SOFTWARE_NAME" />" അൺഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ ഈ പ്രശ്‌നം പരിഹരിക്കാം. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">നിങ്ങളുടെ ഉപകരണം ഇതിലേക്ക് കോൺഫിഗർ ചെയ്‌തു:</translation>
+<translation id="8066955247577885446">ക്ഷമിക്കണം, എന്തോ കുഴപ്പമുണ്ടായി.</translation>
+<translation id="8074253406171541171">10x13 (എൻവലപ്പ്)</translation>
<translation id="8078141288243656252">തിരിക്കുമ്പോൾ അനോട്ടേറ്റ് ചെയ്യാനാവില്ല</translation>
<translation id="8079031581361219619">സൈറ്റ് റീലോഡ് ചെയ്യണോ?</translation>
<translation id="8088680233425245692">ലേഖനം കാണുന്നത് പരാജയപ്പെട്ടു.</translation>
@@ -1127,11 +1269,12 @@
<translation id="8091372947890762290">സെർവറിൽ സജീവമാക്കൽ തീർപ്പാക്കിയിട്ടില്ല</translation>
<translation id="8092774999298748321">ഇരുണ്ട പർപ്പിൾ</translation>
<translation id="8094917007353911263">നിങ്ങൾക്ക് ഉപയോഗിക്കുന്ന നെറ്റ്‌വർക്ക് <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> സന്ദർശിക്കാൻ നിങ്ങളോട് ആവശ്യപ്പെടാം.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">അസാധുവായ കാർഡുകൾ നീക്കം ചെയ്‌തു</translation>
<translation id="8103161714697287722">പേയ്‌മെന്റ് രീതി</translation>
<translation id="8118489163946903409">പേയ്‌മെന്റ് രീതി</translation>
+<translation id="8123836779274890062"><ph name="ENROLLMENT_DOMAIN" /> മാനേജ് ചെയ്യുന്നത് <ph name="DEVICE_TYPE" /> ആണ്</translation>
<translation id="8127301229239896662">നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ അല്ലെങ്കിൽ നെറ്റ്‍വര്‍ക്കിൽ "<ph name="SOFTWARE_NAME" />" ശരിയായി ഇൻസ്‌റ്റാൾ ചെയ്‌തിട്ടില്ല. ഈ പ്രശ്‌നം പരിഹരിക്കാൻ നിങ്ങളുടെ ഐടി അഡ്‌മിനിസ്‌ട്രേറ്ററോട് ആവശ്യപ്പെടുക.</translation>
-<translation id="8130693978878176684">എനിക്ക് ഇനി സഹായിക്കാനാവില്ല, സ്വയം പൂരിപ്പിക്കുക.</translation>
<translation id="8131740175452115882">സ്ഥിരീകരിക്കുക</translation>
<translation id="8149426793427495338">നിങ്ങളുടെ കമ്പ്യൂട്ടർ സുഷുപ്‌തിയിലായി.</translation>
<translation id="8150722005171944719"><ph name="URL" /> എന്നതിലെ ഫയൽ റീഡുചെയ്യാനാവുന്നില്ല. അത് നീക്കംചെയ്‌തിരിക്കുകയോ, നീക്കിയിരിക്കുകയോ ഫയൽ അനുമതികൾ ആക്‌സസ്സ് തടയുകയോ ചെയ്യുന്നുണ്ടാകാം.</translation>
@@ -1141,8 +1284,11 @@
<translation id="8197543752516192074">പേജ് വിവർത്തനം ചെയ്യുക</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" എന്ന ഐഡിയുള്ള വിപുലീകരണത്തിന്റെ അസാധുവായ അപ്‌ഡേറ്റ് URL.</translation>
<translation id="8202097416529803614">ഓർഡർ സംഗ്രഹം</translation>
+<translation id="8202370299023114387">പൊരുത്തക്കേട്</translation>
+<translation id="8206978196348664717">Prc4 (എൻവലപ്പ്)</translation>
<translation id="8211406090763984747">കണക്ഷൻ സുരക്ഷിതമാണ്</translation>
<translation id="8218327578424803826">നൽകിയിരിക്കുന്ന ലൊക്കേഷൻ:</translation>
+<translation id="8220146938470311105">C7/C6 (എൻവലപ്പ്)</translation>
<translation id="8225771182978767009">ഈ കമ്പ്യൂട്ടർ സജ്ജമാക്കിയ വ്യക്തി, ഈ സൈറ്റ് ബ്ലോക്കുചെയ്യാൻ തീരുമാനിച്ചിരുന്നു.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">പുതിയൊരു അദൃശ്യ ടാബിൽ പേജ് തുറക്കുക</translation>
@@ -1154,14 +1300,16 @@
<translation id="825929999321470778">സംരക്ഷിച്ച എല്ലാ പാസ്‌വേഡുകളും കാണിക്കുക</translation>
<translation id="8261506727792406068">ഇല്ലാതാക്കുക</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> എന്നയാളായി സൈൻ ഇൻ ചെയ്യുന്നു</translation>
+<translation id="8278457561961988242">ഈ ബ്രൗസർ മാനേജ് ചെയ്യുന്നത് <ph name="ENROLLMENT_DOMAIN" /> ആണ്. നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർക്ക് വിദൂരമായി ബ്രൗസർ സജ്ജീകരണം മാറ്റാം. ഈ ഉപകരണത്തിലെ ആക്‌റ്റിവിറ്റി Chrome-ന് പുറത്തും മാനേജ് ചെയ്യുന്നുണ്ടാകാം. <ph name="BEGIN_LINK" />കൂടുതലറിയുക<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">വലിയ-ഫോട്ടോ</translation>
<translation id="8286036467436129157">സൈൻ ഇൻ ചെയ്യുക</translation>
<translation id="8288807391153049143">സർട്ടിഫിക്കറ്റ് കാണിക്കുക</translation>
<translation id="8289355894181816810">ഇത് അർത്ഥമാക്കുന്നത് എന്താണെന്ന് നിങ്ങൾക്ക് ഉറപ്പില്ലെങ്കിൽ നെറ്റ്‌വർക്ക് അഡ്‌മിനിസ്‌ട്രേറ്ററെ ബന്ധപ്പെടുക.</translation>
<translation id="8293206222192510085">ബുക്ക്‌മാര്‍‌ക്ക് ചേര്‍‌ക്കുക</translation>
<translation id="8294431847097064396">ഉറവിടം</translation>
<translation id="8298115750975731693">നിങ്ങൾ ഉപയോഗിക്കുന്ന Wi-Fi (<ph name="WIFI_NAME" />), <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> സന്ദർശിക്കാൻ നിങ്ങളോട് ആവശ്യപ്പെടാം.</translation>
+<translation id="8307358339886459768">ചെറിയ-ഫോട്ടോ</translation>
<translation id="8308427013383895095">നെറ്റ്വര്‍ക്ക് കണക്ഷനിലെ ഒരു പിശക് കാരണം വിവര്‍ത്തനം പരാജയപ്പെട്ടു.</translation>
-<translation id="8311129316111205805">സെഷൻ ലോഡ് ചെയ്യുക</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ഹോസ്‌റ്റിലേക്കുള്ള ആക്‌സസ്സ് നിരസിച്ചു</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">നിങ്ങളുടെ സുരക്ഷയെ ബാധിക്കാനിടയുണ്ടെന്ന് മനസ്സിലാക്കുകയാണെങ്കിൽ, ദോഷകരമായ പ്രോഗ്രാമുകൾ നീക്കംചെയ്യുന്നതിനു മുമ്പ് <ph name="BEGIN_LINK" />ഈ സൈറ്റ് നിങ്ങൾക്ക് സന്ദർശിക്കാം<ph name="END_LINK" />.</translation>
@@ -1179,7 +1327,6 @@
<translation id="8416694386774425977">നെറ്റ്‌വർക്ക് കോൺഫിഗറേഷൻ അസാധുവായതിനാൽ ഇമ്പോർട്ട് ചെയ്യാൻ കഴിഞ്ഞില്ല.
കൂടുതൽ വിശദാംശങ്ങൾ:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">ഉപകരണം മാനേജ് ചെയ്യുന്നത്<ph name="ENROLLMENT_DOMAIN" /> ആണ്</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">മാറ്റുക</translation>
<translation id="8428213095426709021">ക്രമീകരണങ്ങള്‍</translation>
@@ -1206,9 +1353,11 @@
<translation id="860043288473659153">കാർഡിന്റെ ഉടമയുടെ പേര്</translation>
<translation id="861775596732816396">വലുപ്പം 4</translation>
<translation id="8620436878122366504">നിങ്ങളുടെ രക്ഷിതാക്കൾ ഇതുവരെ അംഗീകാരം നൽകിയിട്ടില്ല</translation>
+<translation id="8622948367223941507">നിയമപരം-അധികം</translation>
<translation id="8625384913736129811">ഈ ഉപകരണത്തിലേക്ക് ഈ കാർഡ് സംരക്ഷിക്കുക</translation>
<translation id="8663226718884576429">ഓർഡർ സംഗ്രഹം, <ph name="TOTAL_LABEL" />, കൂടുതൽ വിശദാംശങ്ങൾ</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, ഉത്തരം, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> ലേക്കുള്ള നിങ്ങളുടെ കണക്ഷന്‍ എന്‍‌ക്രിപ്റ്റ് ചെയ്തിട്ടില്ല.</translation>
<translation id="8718314106902482036">പേയ്‌മെന്റ് പൂർത്തിയായിട്ടില്ല</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, തിരയൽ നിർദ്ദേശം</translation>
@@ -1222,6 +1371,7 @@
<translation id="8761567432415473239">Google സുരക്ഷിത ബ്രൗസിംഗ് <ph name="SITE" /> എന്നതിൽ ഈയിടെ <ph name="BEGIN_LINK" />ദോഷകരമായ പ്രോഗ്രാമുകൾ കണ്ടെത്തി<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB ഉപകരണം</translation>
<translation id="8768895707659403558">എല്ലാ ഉപകരണങ്ങളിലും നിങ്ങളുടെ കാർഡുകൾ ഉപയോഗിക്കുന്നതിന്, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ഇല്ലാതാക്കുന്നത് വീണ്ടും ചെയ്യുക</translation>
<translation id="8792621596287649091">നിങ്ങളുടെ <ph name="ORG_NAME" /> അക്കൗണ്ടിലേക്കുള്ള ആക്‌സസ് നഷ്‌ടമാകാനോ നിങ്ങളുടെ ഐഡന്‍റിറ്റി മോഷ്ടിക്കപ്പെടാനോ സാധ്യതയുണ്ട്. ഇപ്പോൾ തന്നെ പാസ്‍വേഡ് മാറ്റാൻ Chromium ശുപാർശ ചെയ്യുന്നു.</translation>
<translation id="8800988563907321413">നിങ്ങളുടെ സമീപത്തുള്ള നിർദ്ദേശങ്ങൾ ഇവിടെ ദൃശ്യമാകും</translation>
@@ -1232,10 +1382,12 @@
<translation id="885730110891505394">Google-മായി പങ്കിടുന്നു</translation>
<translation id="8858065207712248076">മറ്റ് സൈറ്റുകളിൽ നിങ്ങൾ <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> പാസ്‌വേഡ് പുനരുപയോഗിച്ചിട്ടുണ്ടെങ്കിൽ, അത് പുനഃസജ്ജീകരിക്കാൻ Chrome ശുപാർ‌ശ ചെയ്യുന്നു.</translation>
<translation id="8866481888320382733">നയ ക്രമീകരണങ്ങൾ പാഴ്‌സുചെയ്യുന്നതിൽ പിശക്</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">സമീപകാലത്ത് അടച്ചവ</translation>
<translation id="8874824191258364635">ശരിയായ കാർഡ് നമ്പർ നൽകുക</translation>
<translation id="8891727572606052622">അസാധുവായ പ്രോക്സി മോഡ്</translation>
<translation id="8903921497873541725">സൂം ഇന്‍</translation>
+<translation id="890485472659500557">എഞ്ചിനീയറിംഗ്-C</translation>
<translation id="8931333241327730545">ഈ കാർഡ് നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കണോ?</translation>
<translation id="8932102934695377596">നിങ്ങളുടെ ക്ലോക്ക് വളരെ പിന്നിലാണ്</translation>
<translation id="893332455753468063">പേര് ചേർക്കുക</translation>
@@ -1243,13 +1395,13 @@
<translation id="894185898663964645">നിങ്ങളുടെ അഡ്‌മിനിസ്ട്രേറ്റർ ഇഷ്‌ടാനുസൃത റൂട്ട് സർട്ടിഫിക്കറ്റുകൾ കോൺഫിഗർ ചെയ്‌തിട്ടുണ്ട്, അത് വെബ്‌സൈറ്റുകളുടെ ഉള്ളടക്കം കാണാൻ അഡ്‌മിനിസ്ട്രേറ്ററെ അനുവദിച്ചേക്കാം.</translation>
<translation id="8943282376843390568">ചെറുനാരങ്ങയുടെ നിറം</translation>
<translation id="8957210676456822347">ക്യാപ്‌റ്റീവ് പോർട്ടൽ അംഗീകരിക്കൽ</translation>
+<translation id="8966619695390250636">ഇതാണോ നിങ്ങള്‍ ഉദ്ദേശിച്ചത്?</translation>
<translation id="8968766641738584599">കാർഡ് സംരക്ഷിക്കുക</translation>
<translation id="8971063699422889582">സെര്‍വറിന്‍റെ സര്‍ട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു.</translation>
<translation id="8975012916872825179">ഫോൺ നമ്പറുകൾ, ഇമെയിൽ വിലാസങ്ങൾ, ഷിപ്പിംഗ് വിലാസങ്ങൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഉൾപ്പെടുന്നു</translation>
<translation id="8978053250194585037">Google സുരക്ഷിത ബ്രൗസിംഗ് ഈയിടെ <ph name="SITE" />-ൽ <ph name="BEGIN_LINK" />ഫിഷിംഗ് കണ്ടെത്തി<ph name="END_LINK" />. നിങ്ങളെ കബളിപ്പിക്കാൻ ഫിഷിംഗ് സൈറ്റുകൾ മറ്റു വെബ്‌സൈറ്റുകളെന്ന നിലയിൽ ഭാവിക്കും.</translation>
<translation id="8983003182662520383">Google Pay ഉപയോഗിക്കുന്ന വിലാസങ്ങളും പേയ്മെന്റ് രീതികളും</translation>
<translation id="8987927404178983737">മാസം</translation>
-<translation id="8988408250700415532">എന്തോ കുഴപ്പം സംഭവിച്ചു. നിങ്ങൾക്ക് വെബ്‌സൈറ്റിൽ ഓർഡർ പൂർത്തിയാക്കാം.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">നിങ്ങൾ പോകാനിരിക്കുന്ന സൈറ്റിൽ ദോഷകരമായ പ്രോഗ്രാമുകളുണ്ട്</translation>
<translation id="8997023839087525404">സർട്ടിഫിക്കറ്റ് സുതാര്യതാ നയം ഉപയോഗിച്ച് സെർവർ, എല്ലാവർക്കുമായി വെളുപ്പെടുത്തിയിട്ടില്ലാത്ത ഒരു സർട്ടിഫിക്കറ്റ് ലഭ്യമാക്കി. ചില സർട്ടിഫിക്കറ്റുകൾ വിശ്വാസയോഗ്യമാണെന്നും അക്രമകാരികളിൽ നിന്നും പരിരക്ഷിക്കുന്നതാണെന്നും ഉറപ്പാക്കാൻ അവയ്‌ക്ക് ഇത് ആവശ്യമാണ്.</translation>
@@ -1259,6 +1411,7 @@
<translation id="9011424611726486705">സൈറ്റ് ക്രമീകരണം തുറക്കുക</translation>
<translation id="9020200922353704812">കാർഡ് ബില്ലിംഗ് വിലാസം ആവശ്യമാണ്</translation>
<translation id="9020542370529661692">ഈ പേജ് <ph name="TARGET_LANGUAGE" />-ലേക്ക് വിവർത്തനം ചെയ്‌തു</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(അസാധുവാണ്)</translation>
<translation id="9035022520814077154">സുരക്ഷ പിശക്</translation>
<translation id="9038649477754266430">പേജുകൾ കൂടുതൽ വേഗത്തിൽ ലോഡുചെയ്യാൻ ഒരു പ്രവചന സേവനം ഉപയോഗിക്കുക</translation>
@@ -1270,11 +1423,11 @@
<translation id="9065745800631924235">ചരിത്രത്തിൽ നിന്നുള്ള <ph name="TEXT" /> തിരയൽ</translation>
<translation id="9069693763241529744">ഒരു വിപുലീകരണം മുഖേന ബ്ലോക്കുചെയ്‌തു</translation>
<translation id="9076283476770535406">ഇതിൽ മുതിർന്നവർക്കുള്ള ഉള്ളടക്കം ഉണ്ടായിരിക്കാം</translation>
+<translation id="9076630408993835509">ഈ ബ്രൗസർ ഒരു കമ്പനിയോ മറ്റേതെങ്കിലും സ്ഥാപനമോ മാനേജ് ചെയ്യുന്നില്ല. ഈ ഉപകരണത്തിലെ ആക്‌റ്റിവിറ്റി Chrome-ന് പുറത്ത് മാനേജ് ചെയ്യുന്നുണ്ടാകാം. <ph name="BEGIN_LINK" />കൂടുതലറിയുക<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">കൂടുതൽ വിവരങ്ങൾ ആവശ്യമാണ്</translation>
<translation id="9080712759204168376">ഓർഡർ സംഗ്രഹം</translation>
<translation id="9103872766612412690">നിങ്ങളുടെ വിവരങ്ങൾ പരിരക്ഷിക്കാൻ സാധാരണയായി <ph name="SITE" />, എൻക്രിപ്‌ഷൻ ഉപയോഗിക്കുന്നു. ഇത്തവണ <ph name="SITE" />, സൈറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്യാൻ Chromium ശ്രമിച്ചപ്പോൾ, അസാധാരണമായതും തെറ്റായതുമായ ക്രെഡൻഷ്യലുകൾ വെബ്‌സൈറ്റ് തിരികെ അയച്ചു. ഒരു ആക്രമണകാരി <ph name="SITE" /> എന്നതായി ഭാവിക്കാൻ ശ്രമിക്കുമ്പോഴോ Wi-Fi സൈൻ ഇൻ സ്‌ക്രീൻ, കണക്ഷനെ തടസ്സപ്പെടുത്തുമ്പോഴോ ആണ് ഇങ്ങനെ സംഭവിക്കാനിടയുള്ളത്. ഏതെങ്കിലും ഡാറ്റ കൈമാറുന്നതിനുമുമ്പ് Chromium കണക്ഷൻ അവസാനിപ്പിച്ചതിനാൽ, നിങ്ങളുടെ വിവരങ്ങൾ തുടർന്നും സുരക്ഷിതമായിരിക്കും.</translation>
<translation id="9106062320799175032">ബില്ലിംഗ് വിലാസം ചേർക്കുക</translation>
-<translation id="9110718169272311511">Chrome-ലെ Google അസിസ്‌റ്റന്‍റ്, സ്‌ക്രീനിന്‍റെ ചുവടെ ലഭ്യമാണ്</translation>
<translation id="9114524666733003316">കാർഡ് സ്ഥിരീകരിക്കുന്നു...</translation>
<translation id="9128870381267983090">നെറ്റ്വര്‍ക്കിലേക്ക് ബന്ധിപ്പിക്കുക</translation>
<translation id="9137013805542155359">യഥാര്‍ത്ഥമായത് കാണിക്കുക</translation>
@@ -1283,6 +1436,7 @@
<translation id="9148507642005240123">&amp;എഡിറ്റുചെയ്യുന്നത് പഴയപടിയാക്കുക</translation>
<translation id="9154194610265714752">അപ്‌ഡേറ്റുചെയ്‌തു</translation>
<translation id="9157595877708044936">സജ്ജീകരിക്കുന്നു...</translation>
+<translation id="9158625974267017556">C6 (എൻവലപ്പ്)</translation>
<translation id="9168814207360376865">നിങ്ങൾ പേയ്‌മെന്റ് രീതികൾ സംരക്ഷിച്ചിട്ടുണ്ടോ എന്ന് പരിശോധിക്കാൻ സൈറ്റുകളെ അനുവദിക്കുക</translation>
<translation id="9169664750068251925">ഈ സൈറ്റിൽ എല്ലായ്‌പ്പോഴും തടയുക</translation>
<translation id="9170848237812810038">‍&amp;പൂര്‍വാവസ്ഥയിലാക്കുക</translation>
@@ -1297,10 +1451,12 @@
<translation id="9219103736887031265">ചിത്രങ്ങൾ‌</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ഫോം മായ്‌ക്കുക</translation>
+<translation id="936474030629450166">സൂപ്പർ-B</translation>
<translation id="936602727769022409">നിങ്ങളുടെ Google അക്കൗണ്ടിലേക്കുള്ള ആക്‌സസ് നഷ്‌ടപ്പെടാനിടയുണ്ട്. ഇപ്പോൾ തന്നെ പാസ്‌വേഡ് മാറ്റാൻ Chromium ശുപാർശ ചെയ്യുന്നു. സൈൻ ഇൻ ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.</translation>
<translation id="939736085109172342">പുതിയ ഫോള്‍ഡര്‍</translation>
<translation id="945855313015696284">ചുവടെയുള്ള വിവരം പരിശോധിച്ച്, അസാധുവായ കാര്‍ഡുകളുണ്ടെങ്കിൽ അവ ഇല്ലാതാക്കുക</translation>
<translation id="951104842009476243">സ്വീകരിക്കുന്ന ഡെബിറ്റ് കാർഡുകളും പ്രീപെയ്ഡ് കാർഡുകളും</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> എന്നതിൻ്റെ സുരക്ഷാ നയത്തിന് അനുസൃതമായി ബ്ലോക്ക് ചെയ്‌തു.</translation>
<translation id="962484866189421427">മറ്റെന്തെങ്കിലും ആണെന്ന് അവകാശപ്പെടുന്ന അല്ലെങ്കിൽ നിങ്ങളെ ട്രാക്ക് ചെയ്യാൻ ഉപയോഗിച്ചേക്കാവുന്ന ഡാറ്റ ശേഖരിക്കുന്ന, തെറ്റിദ്ധരിപ്പിക്കുന്ന ആപ്പുകൾ ഇൻസ്‌റ്റാൾ ചെയ്യാൻ ഈ ഉള്ളടക്കം ശ്രമിച്ചേക്കാം. <ph name="BEGIN_LINK" />എന്തായാലും കാണിക്കുക<ph name="END_LINK" /></translation>
<translation id="969892804517981540">ഔദ്യോഗിക ബില്‍ഡ്</translation>
<translation id="973773823069644502">ഡെലിവറി നൽകേണ്ട വിലാസം ചേർക്കുക</translation>
@@ -1309,6 +1465,7 @@
<translation id="984275831282074731">പേയ്‌മെന്റ് രീതികൾ</translation>
<translation id="985199708454569384">&lt;p&gt;നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെയോ മൊബൈൽ ഉപകരണത്തിന്റെയോ തീയതിയും സമയവും കൃത്യമല്ലെങ്കിൽ ഈ പിശക് കാണും.&lt;/p&gt;
&lt;p&gt;പിശക് പരിഹരിക്കാൻ, ഉപകരണത്തിന്റെ ക്ലോക്ക് തുറക്കുക. സമയവും തീയതിയും കൃത്യമാണെന്ന് ഉറപ്പാക്കുക.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">വികാസക പതിപ്പ്</translation>
<translation id="989988560359834682">വിലാസം എഡിറ്റുചെയ്യുക</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_mr.xtb b/chromium/components/strings/components_strings_mr.xtb
index 75cc48852e4..2318344e6db 100644
--- a/chromium/components/strings/components_strings_mr.xtb
+++ b/chromium/components/strings/components_strings_mr.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mr">
-<translation id="1005145902654145231">सेशनचे नाव बदलू शकलो नाही.</translation>
<translation id="1008557486741366299">सध्या नाही</translation>
<translation id="1010200102790553230">पेज नंतर लोड करा</translation>
<translation id="1015730422737071372">अतिरिक्त तपशील प्रदान करा</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">अज्ञात नाव</translation>
<translation id="1050038467049342496">अन्य अॅप्स बंद करा</translation>
<translation id="1055184225775184556">&amp;जोडा पूर्ववत करा</translation>
+<translation id="1056898198331236512">चेतावणी</translation>
<translation id="1058479211578257048">कार्डे सेव्ह करत आहे...</translation>
<translation id="10614374240317010">कधीही सेव्ह न केलेले</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)Prc10 (Envelope)</translation>
<translation id="106701514854093668">डेस्‍कटॉप बुकमार्क</translation>
<translation id="1074497978438210769">सुरक्षित नाही</translation>
<translation id="1080116354587839789">रूंदीत फिट करा</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">कार्डवर नाव जोडा</translation>
<translation id="1089439967362294234">पासवर्ड बदला</translation>
<translation id="109743633954054152">Chrome सेटिंग्जमध्ये पासवर्ड व्यवस्थापित करा</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">वेबसाइट त्यांची सीक्युरिटी अपडेट करत असताना चेतावण्या सामान्य असू शकतात. यात लवकरच सुधारणा व्हावी.</translation>
<translation id="1126551341858583091">स्थानिक संचयावरील आकार <ph name="CRASH_SIZE" /> आहे.</translation>
<translation id="112840717907525620">धोरण कॅशे ठीक</translation>
+<translation id="1131264053432022307">तुम्ही कॉपी केलेली इमेज</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> नी कनेक्शन अनपेक्षितरित्या बंद केले.</translation>
<translation id="1161325031994447685">वाय-फाय शी पुन्हा कनेक्ट करत आहे</translation>
<translation id="1165039591588034296">एरर</translation>
-<translation id="1173894706177603556">नाव बदला</translation>
<translation id="1175364870820465910">&amp;मुद्रण...</translation>
<translation id="1181037720776840403">काढून टाका</translation>
<translation id="1197088940767939838">नारिंगी</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">तुमच्या डिव्हाइसचे नाव</translation>
<translation id="124116460088058876">आणखी भाषा...</translation>
<translation id="1250759482327835220">पुढील वेळेस जलद पेमेंट करण्यासाठी, तुमच्या Google खात्यावर तुमचे कार्ड आणि बिलिंग पत्ता सेव्ह करा.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (सिंक केलेले)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">विविध कमांड लाइन</translation>
<translation id="129553762522093515">अलीकडे बंद केलेले</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />आपल्या कुकीज साफ करून पहा<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">निवडलेले सेशन अस्तित्वात नाही.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">क्लिपबोर्ड इमेज शोधा</translation>
<translation id="1323433172918577554">अधिक दाखवा</translation>
<translation id="132390688737681464">पत्ते भरा आणि सेव्ह करा</translation>
<translation id="1333989956347591814">तुम्हाला पुढील अॅक्टिव्हिटी <ph name="BEGIN_EMPHASIS" />अद्याप दिसतील<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">घेण्याचा पत्ता</translation>
<translation id="1348198688976932919">पुढील साइटमध्ये धोकादायक ॲप आहे</translation>
<translation id="1348779747280417563">नावाची खात्री करा</translation>
+<translation id="1357195169723583938">डिव्हाइस अलीकडे कोणी आणि केव्हा वापरले</translation>
+<translation id="1364822246244961190">हे धोरण ब्लॉक केले आहे, त्याचे मूल्य दुर्लक्षित केले जाईल.</translation>
<translation id="1374468813861204354">सूचना</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">आवृत्तीबद्दल</translation>
<translation id="1376836354785490390">कमी दर्शवा</translation>
<translation id="1377321085342047638">कार्ड नंबर</translation>
<translation id="138218114945450791">फिकट न‍िळा</translation>
+<translation id="1382194467192730611">तुमच्या अ‍ॅडमिनिस्ट्रेटरने अनुमती दिलेले USB डिव्हाइस</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> नी कोणताही डेटा पाठविला नाही.</translation>
+<translation id="140316286225361634">साइट <ph name="ORIGIN" /> ने विनंती केली आहे की सुरक्षितता धोरण
+ तिच्या सर्व विनंत्यांना लागू होईल आणि हे धोरण सध्या ही साइट असुरक्षित आहे
+ असे मानते.</translation>
<translation id="1405567553485452995">फिकट हिरवा</translation>
<translation id="1407135791313364759">सर्व उघडा</translation>
<translation id="1413809658975081374">गोपनीयता एरर</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">होय</translation>
<translation id="1430915738399379752">प्रिंट</translation>
<translation id="1455413310270022028">खोडरबर</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">अधिक दर्शवा</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">पाठवण्याचा पत्ता निवडा</translation>
+<translation id="1492194039220927094">धोरणे पुढे ढकला:</translation>
<translation id="1501859676467574491">तुमच्या Google खात्यावरील कार्डे दाखवा</translation>
-<translation id="1506687042165942984">या पृष्ठाची सेव्ह केलेली (उदा. कालबाह्य होणारे ज्ञात) प्रत दर्शवा.</translation>
<translation id="1507202001669085618">&lt;p&gt;ऑनलाइन येण्यापूर्वी तुम्हाला साइन इन करावे लागेल अशी व्यवस्था असलेले वाय-फाय पोर्टल वापरत असल्यास तुम्हाला ही एरर दिसून येईल.&lt;/p&gt;
&lt;p&gt;एरर निघून जाण्यासाठी, तुम्ही उघडण्याचा प्रयत्न करत असलेल्या पेजवर &lt;strong&gt;कनेक्ट&lt;/strong&gt; वर क्लिक करा.&lt;/p&gt;</translation>
<translation id="1517433312004943670">फोन नंबर आवश्यक आहे</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">बिल्ड तारीख</translation>
<translation id="1521655867290435174">Google पत्रक</translation>
<translation id="1527263332363067270">कनेक्शनची वाट पाहत आहे...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">या पेजचे म्हणणे हे आहे की</translation>
<translation id="153384715582417236">सध्या इतकेच</translation>
<translation id="154408704832528245">वितरणाचा पत्ता निवडा</translation>
<translation id="1549470594296187301">हे वैशिष्‍ट्य वापरण्‍यासाठी JavaScript सक्षम करणे आवश्‍यक आहे.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">एक्स्पायरीची तारीख एंटर करा</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">हे वेबपेज दाखवताना काहीतरी चूक झाली.</translation>
<translation id="1592005682883173041">स्थानिक डेटा प्रवेश</translation>
<translation id="1594030484168838125">निवडा</translation>
<translation id="161042844686301425">निळसर</translation>
-<translation id="1618822247301510817">तुम्ही कॉपी केलेली इमेज</translation>
<translation id="1620510694547887537">कॅमेरा</translation>
<translation id="1623104350909869708">या पृष्ठास अतिरिक्त संवाद तयार करण्यापासून प्रतिबंधित करा</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">सेशन समाप्त करा</translation>
<translation id="1639239467298939599">लोड करीत आहे</translation>
<translation id="1640180200866533862">वापरकर्ता धोरणे</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> तुमची माहिती संरक्षित करण्यासाठी सामान्यतः एंक्रिप्शन वापरते. Google Chrome ने यावेळी <ph name="SITE" /> शी कनेक्‍ट करण्‍याचा प्रयत्न केला तेव्‍हा, वेबसाइटने असामान्य आणि अयोग्य क्रेडेंशियल परत पाठवले. एकतर आक्रमणकर्ता <ph name="SITE" /> असल्याची बतावणी करण्याचा प्रयत्न करतो तेव्‍हा किंवा वाय-फाय साइन इन स्क्रीनने कनेक्शनमध्ये व्यत्यय आणले तेव्‍हा हे घडू शकते. कोणत्याही डेटाची अदलाबदल करण्यापूर्वी Google Chrome ने कनेक्शन थांबवल्यामुळे तुमची माहिती अद्याप सुरक्षित आहे.</translation>
<translation id="168841957122794586">सर्व्हर सर्टिफिकेटमध्ये एक कमकुवत क्रिप्टोग्राफिक की आहे.</translation>
<translation id="1697532407822776718">तुम्ही पूर्णपणे तयार आहात!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">भाष्य करण्यासाठी दस्तऐवज खूपच मोठे आहे</translation>
<translation id="1721312023322545264">या साइटला भेट देण्यासाठी तुम्हाला <ph name="NAME" /> कडील परवानगी आवश्यक आहे</translation>
<translation id="1721424275792716183">* फील्ड आवश्यक आहे</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">सिस्टम प्रशासकाशी संपर्क साधण्याचा प्रयत्न करा.</translation>
<translation id="1740951997222943430">वैध समाप्ती महिना एंटर करा</translation>
<translation id="1743520634839655729">पुढील वेळेस जलद पेमेंट करण्यासाठी, तुमच्या Google खात्यावर आणि या डिव्हाइसवर तुमचे कार्ड आणि बिलिंग पत्ता सेव्ह करा.</translation>
+<translation id="1745880797583122200">तुमचा ब्राउझर व्यवस्थापित केला आहे</translation>
<translation id="17513872634828108">खुले टॅब</translation>
<translation id="1753706481035618306">पृष्ठ क्रमांक</translation>
<translation id="1763864636252898013">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट तुम्हाला डिव्हाइसच्या ऑपरेटिंग सिस्टमद्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉन्फिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">कृपया तुमचे सिंक सांकेतिक पासफ्रेझ अपडेट करा.</translation>
<translation id="1787142507584202372">तुमचे खुले टॅब येथे दिसतात</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">कार्डधारकाचे नाव</translation>
<translation id="1821930232296380041">चुकीची विनंती किंवा विनंती मापदंड</translation>
+<translation id="1822540298136254167">तुम्ही भेट देत असलेल्या वेबसाइट आणि त्यावर व्यतीत केलेला वेळ</translation>
<translation id="1826516787628120939">तपासत आहे</translation>
<translation id="1834321415901700177">या साइटमध्ये धोकादायक प्रोग्राम आहेत</translation>
<translation id="1839551713262164453">धोरण मूल्यांची वैधता एररसह अयशस्वी झाली आहे</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Chrome चा ब्राउझिंग इतिहास डेटा साफ करा</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{आणि 1 अधिक}one{आणि # अधिक}other{आणि # अधिक}}</translation>
<translation id="2003709556000175978">आता तुमचा पासवर्ड रीसेट करा</translation>
+<translation id="20053308747750172">तुम्ही जात आहात तो सर्व्हर, <ph name="ORIGIN" />, ने विनंती केली आहे की
+ सुरक्षितता धोरण त्याच्या सर्व विनंत्यांना लागू होईल. परंतु त्याने आता
+ अवैध धोरण डिलिव्हर केले आहे, जे ब्राउझरला तुमच्या
+ <ph name="SITE" /> साठीच्या विनंतीची पूर्तता करण्यापासून रोखते.</translation>
<translation id="2025186561304664664">प्रॉक्सी स्वयंचलित ‍कॉन्फिगरेशनवर सेट करण्‍यात आली.</translation>
<translation id="2030481566774242610">तुम्हाला असे म्हणायचे होते <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />प्रॉक्सी आणि फायरवॉल तपासणे<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">विभाग</translation>
<translation id="2102134110707549001">क्लिष्ट पासवर्ड सुचवा…</translation>
<translation id="2108755909498034140">तुमचा कॉंप्युटर रीस्टार्ट करा</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">कार्ड</translation>
<translation id="2114841414352855701">दुर्लक्ष केले कारण ते <ph name="POLICY_NAME" /> कडून अधिलिखित झाले होते.</translation>
<translation id="213826338245044447">Mobile बुकमार्क</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">कार्ड संपादित करा</translation>
<translation id="2166049586286450108">पूर्ण प्रशासन प्रवेश</translation>
<translation id="2166378884831602661">ही साइट सुरक्षित कनेक्शन प्रदान करू शकत नाही</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">धोरणे</translation>
<translation id="2183608646556468874">फोन नंबर</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 पत्ता}one{# पत्ता}other{# पत्ते}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">फोन नंबर</translation>
<translation id="2283340219607151381">पत्ते भरा आणि सेव्ह करा</translation>
<translation id="2292556288342944218">तुमचा इंटरनेट प्रवेश अवरोधित केला आहे</translation>
+<translation id="2294558542833290837">तुम्ही मुळात उघडलेली लिंक असाधारण आहे</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">1 MB पेक्षा कमी जागा मोकळी करते. काही साइट तुमच्या पुढील भेटीच्या वेळी आणखी धीम्या गतीने लोड होऊ शकतात.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> साठी वापरकर्तानाव आणि पासवर्ड आवश्यक आहेत.</translation>
<translation id="2317583587496011522">डेबिट कार्डे स्वीकारली जातात.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, <ph name="EXPIRATION_DATE_ABBR" /> रोजी एक्स्पायर होईल</translation>
<translation id="2337852623177822836">सेटिंग तुमच्या प्रशासकाने नियंत्रित केलेली आहे</translation>
+<translation id="2346319942568447007">तुम्ही कॉपी केलेली इमेज</translation>
<translation id="2349790679044093737">VR सेशन अ‍ॅक्टिव्ह आहे</translation>
<translation id="2354001756790975382">इतर बुकमार्क</translation>
<translation id="2354430244986887761">Google सुरक्षित ब्राउझिंगला अलीकडे <ph name="SITE" />मध्ये <ph name="BEGIN_LINK" />हानिकारक अॅप्स सापडले<ph name="END_LINK" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> वाजता कॅप्चर केलेला क्रॅश अहवाल अपलोड केला नाही</translation>
<translation id="2367567093518048410">दर्जा</translation>
<translation id="2378238891085281592">तुम्ही खाजगी मोडमध्ये गेला आहात</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">एंटरप्राइझ डीफॉल्ट</translation>
<translation id="2386255080630008482">सर्व्हरचे सर्टिफिकेट रिव्होक केले गेले.</translation>
<translation id="2392959068659972793">कोणतेही मूल्य सेट केल्याशिवाय धोरणे दर्शवा</translation>
<translation id="239429038616798445">ही शिपिंग पद्धत उपलब्ध नाही. वेगळी पद्धत वापरून पहा.</translation>
<translation id="2396249848217231973">&amp;हटवा पूर्ववत करा</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट कदाचित रद्द केले असू शकते. हे कदाचित एका चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
+<translation id="2418081434543109369">तुम्ही जात आहात तो सर्व्हर, <ph name="ORIGIN" />, ने विनंती केली आहे की
+ सुरक्षितता धोरण त्याच्या सर्व विनंत्यांना लागू होईल. परंतु त्याला आता
+ धोरण डिलिव्हर करण्यात अपयश आले आहे, जे ब्राउझरला तुमच्या <ph name="SITE" /> साठीच्या विनंतीची
+ पूर्तता करण्यापासून रोखते.</translation>
<translation id="244665789865330679">तुमचे डिव्हाइस आणि खाते <ph name="ENROLLMENT_DOMAIN" /> कडून व्यवस्थापित केले जाते. याचा अर्थ तुमचा अ‍ॅडमिनिस्ट्रेटर तुमचे डिव्हाइस आणि खाते रिमोट पद्धतीने कॉन्फिगर करू शकतो.</translation>
<translation id="2463193859425327265">होम पेज बदला</translation>
<translation id="2463739503403862330">भरून टाका</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">वितरणाची पद्धत निवडा</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />नेटवर्क निदान चालविणे<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">या पृष्ठाचे भाषांतर करा</translation>
<translation id="2479410451996844060">चुकीचे शोध URL.</translation>
<translation id="2482878487686419369">सूचना</translation>
<translation id="248348093745724435">मशीन धोरणे</translation>
+<translation id="2485387744899240041">तुमच्या डिव्हाइस आणि ब्राउझरसाठी वापरकर्तानावे</translation>
<translation id="2491120439723279231">सर्व्हरच्या सर्टिफिकेटमध्ये एरर आहेत.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON विश्लेषक</translation>
<translation id="2495093607237746763">चेक केल्यास, अधिक जलद फॉर्म भरण्यासाठी या डिव्हाइसवर Chromium आपल्या कार्डची एक प्रत संचयित करेल.</translation>
<translation id="2498091847651709837">नवीन कार्ड स्कॅन करा</translation>
<translation id="2501278716633472235">परत जा</translation>
<translation id="2503184589641749290">स्वीकारली जाणारी डेबिट आणि प्रीपेड कार्डे</translation>
<translation id="2515629240566999685">आपल्या क्षेत्रातील सिग्नल तपासणे</translation>
-<translation id="2516852381693169964">इमेजसाठी <ph name="SEARCH_ENGINE" /> शोधा</translation>
<translation id="2523886232349826891">फक्त या डिव्हाइसवर सेव्ह केले जाईल</translation>
<translation id="2524461107774643265">अधिक माहिती जोडा</translation>
<translation id="2536110899380797252">पत्ता जोडा</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">शब्दकोश API आयडी:</translation>
<translation id="2597378329261239068">हा दस्तऐवज पासवर्ड संरक्षित आहे. कृपया पासवर्ड एंटर करा.</translation>
<translation id="2609632851001447353">तफावत</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">तुमचे घड्याळ पुढे आहे</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> चा सर्व्हर आयपी अॅड्रेस सापडला नाही.</translation>
<translation id="2639739919103226564">स्थिती:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">इतर टॅब किंवा अॅप्स बंद करा</translation>
<translation id="267371737713284912">पहिल्यासारखे करण्यासाठी <ph name="MODIFIER_KEY_DESCRIPTION" /> दाबा</translation>
<translation id="2674170444375937751">तुमची खात्री आहे की तुम्ही ही पेज आपल्‍या इतिहासातून हटवू इच्छिता?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">सोडा</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">स्वीकारली जाणारी कार्डे</translation>
<translation id="2702801445560668637">वाचन सूची</translation>
<translation id="2704283930420550640">मूल्य स्वरुपनाशी जुळत नाही.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">निवडलेले आयटम काढून टाका</translation>
<translation id="277133753123645258">शिपिंग पद्धत</translation>
<translation id="277499241957683684">डिव्हाइस रेकॉर्ड गहाळ</translation>
-<translation id="2781030394888168909">MacOS एक्सपोर्ट करा</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">कनेक्शन रीसेट केले.</translation>
<translation id="2788784517760473862">क्रेडिट कार्डे स्वीकारली जातात</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">कनेक्शन <ph name="CIPHER" /> वापरून आणि महत्त्वाचे एक्स्चेंज तंत्र म्हणून <ph name="KX" /> वापर एंक्रिप्ट आणि अॉथेंटिकेट केले आहे.</translation>
<translation id="2835170189407361413">फॉर्म क्लिअर करा</translation>
<translation id="2847118875340931228">गुप्त विंडो उघडा</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">या साइटला भेट देण्यासाठी तुम्हाला परवानगीची गरज आहे</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">कार्ड सेव्ह करायचे?</translation>
<translation id="2903493209154104877">पत्ते</translation>
<translation id="290376772003165898">पेज <ph name="LANGUAGE" />मध्ये नाही?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">वितरण पद्धत</translation>
<translation id="2928905813689894207">बिलिंग पत्ता</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट <ph name="DOMAIN2" /> वरील आहे. हे कदाचित एका चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
<translation id="2948083400971632585">तुम्हे सेटिंग्ज पेजवरून एका कनेक्शनसाठी कॉन्फिगर केलेले कोणत्याही प्रॉक्सी अक्षम करू शकता.</translation>
<translation id="2955913368246107853">शोध बार बंद करा</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">चुकीचा धोरण प्रकार</translation>
<translation id="3037605927509011580">च्चक!</translation>
<translation id="3041612393474885105">सर्टिफिकेट माहिती</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">बाह्य अॅप्लिकेशन द्वारे पेमेंट देण्यासाठी गुप्त मोड सोडत आहे. सुरु ठेवायचे?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{काहीही नाही}=1{1 पासवर्ड}one{# पासवर्ड}other{# पासवर्ड}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">पिकअप पत्ता जोडा</translation>
<translation id="3105172416063519923">मालमत्ता आयडी:</translation>
<translation id="3109728660330352905">हे पृष्ठ पाहण्यासाठी तुम्ही प्राधिकृत नाही.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> वर <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">पेमेंट रद्द करा</translation>
<translation id="3207960819495026254">बुकमार्क केलेली</translation>
-<translation id="3209375525920864198">कृपया एक वैध सेशन नाव टाका.</translation>
+<translation id="321912867715453276">चेतावणी: धोरणासाठी एकापेक्षा जास्त स्रोत आहेत, परंतु मूल्ये सारखी आहेत.</translation>
<translation id="3225919329040284222">सर्व्हरने असे सर्टिफिकेट सादर केले आहे जे अंगभूत अपेक्षांशी जुळत नाही. या अपेक्षा तुम्हाला संरक्षित करण्यासाठी विशिष्ट, उच्च सुरक्षिततेच्या वेबसाइटसाठी समाविष्ट केल्या आहेत.</translation>
<translation id="3226128629678568754">पृष्ठ लोड करण्यास आवश्यक असलेला डेटा पुन्हा सबमिट करण्यासाठी रीलोड बटण दाबा.</translation>
<translation id="3227137524299004712">मायक्रोफोन</translation>
<translation id="3228969707346345236">व्यवहार अयशस्वी झाला कारण पृष्ठ पूर्वीपासून <ph name="LANGUAGE" /> मध्ये आहे.</translation>
+<translation id="3229041911291329567">तुमच्या डिव्हाइस आणि ब्राउझरविषयी आवृत्ती माहिती</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">कार्डवर नाव जोडा</translation>
<translation id="3287510313208355388">ऑनलाइन असताना डाउनलोड करा</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> धोरणांबद्दल अधिक जाणून घ्या</translation>
<translation id="3303855915957856445">कोणतेही शोध परिणाम आढळले नाहीत</translation>
-<translation id="3305707030755673451">तुमचा डेटा तुमच्या सिंक पासफ्रेजसह <ph name="TIME" /> वाजता एंक्रिप्ट केला होता. सिंक सुरु करण्यासाठी तो एंटर करा.</translation>
<translation id="3320021301628644560">बिलिंग पत्ता जोडा</translation>
<translation id="3324983252691184275">किरमिजी</translation>
<translation id="3338095232262050444">सुरक्षित</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;संपादित करा पुन्हा करा</translation>
<translation id="342781501876943858">जर तुम्ही तुमच्या पासवर्डचा इतर साइटवर पुन्हा वापर केला असेल तर Chromium तुम्हाला तो रीसेट करण्याची शिफारस करतो.</translation>
<translation id="3431636764301398940">या डिव्हाइसवर हे कार्ड सेव्ह करा</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">या डिव्हाइसच्या मालकाने डायनासोर गेम बंद केला आहे.</translation>
<translation id="3447884698081792621">सर्टिफिकेट दाखवा (<ph name="ISSUER" /> ने जारी केलेले)</translation>
<translation id="3452404311384756672">मध्यंतर प्राप्त करा:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">हायलाइटर</translation>
<translation id="3462200631372590220">प्रगत लपवा</translation>
<translation id="3467763166455606212">कार्डधारकाचे नाव आवश्यक</translation>
@@ -429,20 +480,23 @@
<translation id="358285529439630156">क्रेडिट आणि प्रीपेड कार्डे स्वीकारली जातात.</translation>
<translation id="3582930987043644930">नाव जोडा</translation>
<translation id="3583757800736429874">&amp;हलवा पुन्हा करा</translation>
+<translation id="35866233670761917">तुम्ही भेट देत असलेल्या वेबसाइटचे आशय तुमच्या अ‍ॅडमिनिस्ट्रेटरने पाहिलेले नाहीत</translation>
<translation id="3586931643579894722">तपशील लपवा</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">आकार २</translation>
<translation id="3615877443314183785">वैध समाप्ती दिनांक एंटर करा</translation>
<translation id="36224234498066874">ब्राउझिंग डेटा साफ करा...</translation>
<translation id="362276910939193118">पूर्ण इतिहास दर्शवा</translation>
-<translation id="3623476034248543066">मूल्य दर्शवा</translation>
<translation id="3630155396527302611">नेटवर्कवर प्रवेश करण्यासाठी अनुमती दिलेला प्रोग्राम म्हणून तो आधीपासून सूचीबद्ध केला असल्यास
तो सूचीमधून काढा आणि पुन्हा जोडून पहा.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">प्रमाणीकरण यशस्वी</translation>
<translation id="3655670868607891010">तुम्ही हे वारंवार पहात असल्यास, हे वापरून पहा <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">पुनरावृत्ती</translation>
<translation id="366077651725703012">क्रेडिट कार्ड अपडेट करा</translation>
<translation id="3676592649209844519">डिव्हाइस आयडी:</translation>
+<translation id="3677008721441257057">तुम्हाला &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; म्हणायचे आहे का?</translation>
<translation id="3678029195006412963">विनंती स्वाक्षरीकृत करणे शक्य झाले नाही</translation>
<translation id="3678529606614285348">पेज एका नवीन गुप्त विंडोमध्ये उघडा (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">क्रॅश अहवाल <ph name="CRASH_TIME" /> वाजता कॅप्चर केला, <ph name="UPLOAD_TIME" /> वाजता अपलोड केला</translation>
@@ -450,13 +504,14 @@
<translation id="3704162925118123524">तुम्ही वापरत असलेल्या नेटवर्कला तुम्ही त्याच्या लॉग इन पृष्ठास भेट देण्याची आवश्यकता असू शकते.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">लोड करीत आहे...</translation>
+<translation id="3709599264800900598">तुम्ही कॉपी केलेला मजकूर</translation>
<translation id="3712624925041724820">परवाने संपुष्टात</translation>
<translation id="3714780639079136834">मोबाइल डेटा किंवा वाय-फाय सुरू करणे</translation>
<translation id="3715597595485130451">वाय-फाय वर कनेक्ट करा</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />प्रॉक्सी, फायरवॉल आणि DNS कॉन्फिगरेशन तपासणे<ph name="END_LINK" /></translation>
<translation id="372429172604983730">या एररला कारणीभूत असू शकणार्‍या अॅप्लिकेशनमध्ये अँटिव्हायरस, फायरवॉल आणि वेब-फिल्टरिंग किंवा प्रॉक्सी सॉफ्टवेअरचा समावेश होतो.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">तुम्ही निश्चित केल्यानंतर, तुमच्या Google खात्यामधील कार्ड तपशील या साइटसोबत शेअर केला जाईल.</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>
@@ -469,10 +524,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">समाप्त होते: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">आकार १६</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">हानिकारक आशय ब्लॉक केला गेला.</translation>
<translation id="3810973564298564668">व्यवस्थापित करा</translation>
<translation id="382518646247711829">तुम्ही प्रॉक्सी सर्व्हर वापरत असल्यास...</translation>
<translation id="3828924085048779000">रिक्त सांकेतिक वाक्यांशाची परवानगी नाही.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ने अतिरिक्त फंक्शनसाठी एक्स्टेंशन इंस्टॉल केले आहे. एक्स्टेंशनकडे तुमच्या काही डेटाचा अ‍ॅक्सेस आहे.</translation>
<translation id="385051799172605136">मागील</translation>
<translation id="3858027520442213535">तारीख आणि वेळ अपडेट करा</translation>
<translation id="3884278016824448484">संघर्ष करणारा डिव्हाइस अभिज्ञापक</translation>
@@ -480,6 +537,7 @@
<translation id="3886446263141354045">या साइटवर प्रवेश करण्याची तुमची विनंती <ph name="NAME" /> कडे पाठविली गेली आहे</translation>
<translation id="3890664840433101773">ईमेल जोडा</translation>
<translation id="3901925938762663762">कार्ड कालबाह्य झाले आहे</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">नेहमी या साइटवर विचारा</translation>
<translation id="3949571496842715403">हा सर्व्हर <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षा सर्टिफिकेट विषय पर्यायी नावांचा उल्लेख करत नाही. हे कदाचित चुकीच्या कॉंफिगरेशनमुळे होत आहे किंवा हल्लेखोर तुमच्या कनेक्शनमध्ये अडथळा आणत आहे.</translation>
@@ -490,11 +548,13 @@
<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="3984550557525787191">या सेशनचे नाव आधीपासून अस्तित्वात आहे.</translation>
<translation id="3987940399970879459">1 MB पेक्षा कमी</translation>
+<translation id="4008849406247176967">चेतावणी: या धोरणासाठी परस्परविरोधी मूल्ये असलेले एकापेक्षा जास्त स्रोत आहेत!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{जवळपास 1 वेब पृष्‍ठ}one{जवळपास # वेब पृष्‍ठ}other{जवळपास # वेब पेज}}</translation>
<translation id="4030383055268325496">&amp;जोडा पूर्ववत करा</translation>
+<translation id="4032320456957708163">तुमचा ब्राउझर <ph name="ENROLLMENT_DOMAIN" /> द्वारे व्यवस्थापित केला आहे</translation>
<translation id="4058922952496707368">की "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">वैध पत्ता जोडा</translation>
<translation id="4072486802667267160">आपल्या मागणीवर प्रक्रिया करताना एरर आली, कृपया पुन्हा प्रयत्न करा.</translation>
<translation id="4075732493274867456">क्लायंट आणि सर्व्हर एक सामान्य SSL प्रोटोकॉल आवृत्ती किंवा सायफर सूटला सपोर्ट करत नाही.</translation>
@@ -514,10 +574,12 @@
<translation id="4159784952369912983">जांभळा</translation>
<translation id="4165986682804962316">साइट सेटिंग्ज</translation>
<translation id="4171400957073367226">खराब पडताळणी स्वाक्षरी</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{आणखी <ph name="ITEM_COUNT" /> आयटम}one{आणखी <ph name="ITEM_COUNT" /> आयटम}other{आणखी <ph name="ITEM_COUNT" /> आयटम}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;हलवा पुन्हा करा</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />फायरवॉल आणि अँटीव्हायरस कॉन्फिगरेशन तपासणे<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;पायरी १: पोर्टलमध्ये साइन इन करा&lt;/h4&gt;
@@ -549,58 +611,79 @@
<translation id="4277028893293644418">पासवर्ड रीसेट करा</translation>
<translation id="4280429058323657511">, कालबाह्यता <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{हे कार्ड तुमच्या Google खात्यात सेव्ह केले गेले}one{हे कार्ड तुमच्या Google खात्यात सेव्ह केले गेले}other{ही कार्डे तुमच्या Google खात्यात सेव्ह केली गेली}}</translation>
+<translation id="42981349822642051">विस्तृत करा</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">स्विच</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">अवरोधित करा (डीफॉल्ट)</translation>
+<translation id="4318566738941496689">तुमच्या डिव्हाइसचे नाव आणि नेटवर्कचा पत्ता</translation>
<translation id="4325863107915753736">लेख शोधण्यात अयशस्वी</translation>
<translation id="4326324639298822553">तुमची कालबाह्यता तारीख तपासा आणि पुन्हा प्रयत्न करा</translation>
<translation id="4331708818696583467">सुरक्षित नाही</translation>
<translation id="4340982228985273705">हा कॉंम्पुटर एंटरप्राइझ व्यवस्थापित म्हणून आढळला नाही म्हणून धोरण फक्त Chrome वेबस्टोअरवर होस्ट केलेले एक्सटेंशन आपोआप इंस्टॉल करू शकते. Chrome वेबस्टोअर अपडेट URL <ph name="CWS_UPDATE_URL" /> ही आहे.</translation>
<translation id="4346197816712207223">स्वीकारली जाणारी क्रेडिट कार्डे</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">या साइट वरील आक्रमणकर्ते तुमची माहिती (उदाहरणार्थ, फोटो, पासवर्ड, संदेश आणि क्रेडिट कार्ड) चोरणारे किंवा हटविणारे धोकादायक प्रोग्राम आपल्या संगणकावर इंस्टॉल करण्‍याचा प्रयत्न करू शकतात.</translation>
<translation id="4358461427845829800">पेमेंट पद्धती व्यवस्थापित करा</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">अपेक्षित <ph name="VALUE_TYPE" /> मूल्य.</translation>
<translation id="4377125064752653719">तुम्ही <ph name="DOMAIN" /> वर पोहोचण्याचा प्रयत्न केला, परंतु सर्व्हरने सादर केलेले प्रमाणपत्र त्याच्या जारीकर्त्याद्वारे मागे घेतले गेले आहे. याचा अर्थ सर्व्हरने सादर केलेल्या सुरक्षा क्रेडेंशियलवर अजिबात विश्वास ठेवला जाऊ नये. तुम्ही कदाचित आक्रमणकर्त्याशी संवाद प्रइंस्टॉल करत आहात.</translation>
<translation id="4378154925671717803">फोन</translation>
<translation id="4406896451731180161">शोध परिणाम</translation>
-<translation id="4406972042435603828">तुमच्या अ‍ॅडमिनिस्ट्रेटरनी शक्तिशाली क्षमता असलेली एक्स्टेंशन इंस्टॉल केली आहेत.</translation>
<translation id="4408413947728134509">कुकीज <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">घेण्याचा पत्ता</translation>
<translation id="4424024547088906515">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट Chrome द्वारे विश्वसनीय नाही. हे कदाचित एका चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
+<translation id="443121186588148776">सिरीअल पोर्ट</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ने तुमचे लॉग इन सर्टिफिकेट स्वीकारले नाही किंवा कदाचित दिले गेले नसावे.</translation>
<translation id="4434045419905280838">पॉप-अप आणि रीडिरेक्ट</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">प्रॉक्सीचा वापर अक्षम करण्‍यात आला आहे पण एक सुस्पष्‍ट प्रॉक्सी कॉन्‍फिगरेशन निर्दिष्‍ट करण्‍यात आले आहे.</translation>
<translation id="445100540951337728">डेबिट कार्डे स्वीकारली जातात</translation>
+<translation id="4466881336512663640">फॉर्म बदल गमावतील. तुम्हाला नक्की पुढे सुरू ठेवायचे आहे?</translation>
<translation id="4482953324121162758">या साइटचे भाषांतर केले जाणार नाही.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">चुकीची URL. URL चा एक ठरावीक फॉरमॅट असणे आवश्यक आहे, उदा. http://example.com or https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">प्रमाणीकरण एरर: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">सिस्टम प्रशासकाशी संपर्क साधणे</translation>
<translation id="450710068430902550">प्रशासकासह शेअर करीत आहे</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">कार्ड आणि पत्ते Chrome आणि आपल्या Google खात्याकडील (<ph name="ACCOUNT_EMAIL" />) आहेत. तुम्ही त्यांना <ph name="BEGIN_LINK" />सेटिंग्‍ज<ph name="END_LINK" /> मधून व्यवस्थापित करू शकता.</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">तपशील</translation>
<translation id="4524805452350978254">कार्डे व्यवस्थापित करा</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">फ्लॅश</translation>
<translation id="4558551763791394412">तुमचे विस्तार अक्षम करून पहा.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">वितरण</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">कार्ड काढून टाका</translation>
<translation id="4587425331216688090">Chrome मधून पत्ता काढून टाकायचा?</translation>
<translation id="4592951414987517459">तुमचे <ph name="DOMAIN" /> वरील कनेक्शन आधुनिक सायफर सूट वापरून एंक्रिप्ट केलेले आहे.</translation>
<translation id="4594403342090139922">&amp;हटवा पूर्ववत करा</translation>
<translation id="4597348597567598915">आकार ८</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">आता मला तेथे घेऊन जा</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याच्या सुरक्षितता सर्टिफिकेटमध्ये एरर आहेत. हे कदाचित एका चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
<translation id="467809019005607715">Google स्लाइड</translation>
<translation id="4690462567478992370">चुकीचे सर्टिफिकेट वापरणे थांबवा</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">आपल्या कनेक्शनमध्ये व्यत्यय आला</translation>
<translation id="471880041731876836">या साइटला भेट देण्याची तुम्हाला परवानगी नाही</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows नेटवर्क निदान चालविणे<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">धोरणे रीलोड करा</translation>
<translation id="4728558894243024398">प्लॅटफॉर्म</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Chromium रीस्टार्ट करा</translation>
<translation id="473775607612524610">अपडेट करा</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> शोध सूचना</translation>
<translation id="4742407542027196863">पासवर्ड व्यवस्थापित करा…</translation>
<translation id="4744603770635761495">कार्यवाहीयोग्य पथ</translation>
+<translation id="4746351372139058112">संदेश</translation>
<translation id="4750917950439032686">तुमची माहिती (उदाहरणार्थ, पासवर्ड किंवा क्रेडिट कार्ड क्रमांक) या साइटवर पाठविली जाते तेव्हा ती खाजगी राहते.</translation>
<translation id="4756388243121344051">&amp;इतिहास</translation>
<translation id="4758311279753947758">संपर्क माहिती जोडा</translation>
@@ -608,9 +691,9 @@
<translation id="4764776831041365478"><ph name="URL" /> येथील वेबपृष्ठ कदाचित तात्पुरते बंद आहे किंवा ते कदाचित कायमचे नवीन वेब पत्त्यावर हलवले आहे.</translation>
<translation id="4771973620359291008">एक अज्ञात एरर आली आहे.</translation>
<translation id="4785689107224900852">या टॅबवर स्विच करा</translation>
-<translation id="4792143361752574037">सेशन फायली अ‍ॅक्सेस करताना अडचण आली. डिस्कवर सेव्ह करणे सध्या बंद केलेले आहे. पुन्हा प्रयत्न करण्यासाठी कृपया पेज रीलोड करा.</translation>
<translation id="4798078619018708837">तुमच्या कार्डाचा तपशील अपडेट करण्यासाठी <ph name="CREDIT_CARD" /> साठी कार्डची एक्स्पायरेशन तारीख आणि CVC टाका. तुम्ही निश्चित केल्यानंतर, तुमच्या Google खात्यामधील कार्डाचा तपशील या साइटसोबत शेअर केला जाईल.</translation>
<translation id="4800132727771399293">तुमची कालबाह्यता तारीख आणि CVC तपासा आणि पुन्हा प्रयत्न करा</translation>
+<translation id="480334179571489655">मूळ धोरण एरर</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>
@@ -625,7 +708,6 @@
<translation id="4881695831933465202">उघडा</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>
@@ -634,15 +716,15 @@
<translation id="4943872375798546930">परिणाम नाहीत</translation>
<translation id="4950898438188848926">टॅब स्विच बटण, उघड्या टॅबवर स्विच करण्यासाठी एंटर दाबा, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">क्रिया</translation>
-<translation id="495832697253704892">एक्स्टेंशनचा अहवाल देणे</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">सूची विस्तृत करा</translation>
<translation id="4974590756084640048">चेतावण्या पुन्हा सक्षम करा</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">सर्व पाहा</translation>
<translation id="4989809363548539747">हे प्लगिन समर्थित नाही</translation>
-<translation id="4996230189582812866">अहवाल देणे</translation>
<translation id="5002932099480077015">सक्षम केल्‍यास, Chrome जलदपणे फॉर्म भरण्‍यासाठी आपल्‍या कार्डची एक प्रत या डिव्‍हाइसवर संग्रहित करेल.</translation>
-<translation id="5014174725590676422">Chrome मध्ये Google असिस्टंट पहिल्यांदा रन केलेली स्क्रीन दाखवली आहे</translation>
<translation id="5015510746216210676">मशीन नाव:</translation>
+<translation id="5017554619425969104">तुम्ही कॉपी केलेला मजकूर</translation>
<translation id="5018422839182700155">हे पृष्‍ठ उघडू शकत नाही</translation>
<translation id="5019198164206649151">समर्थन संचयन खराब स्थितीत</translation>
<translation id="5023310440958281426">आपल्या प्रशासकाची धोरणे तपासा</translation>
@@ -652,35 +734,51 @@
<translation id="5034369478845443529">स्थानिक संदर्भ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">परवानगी द्या</translation>
<translation id="5040262127954254034">गोपनीयता</translation>
+<translation id="5043480802608081735">तुम्ही कॉपी केलेली लिंक</translation>
<translation id="5045550434625856497">अयोग्य पासवर्ड</translation>
<translation id="5056549851600133418">तुमच्यासाठी लेख</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />प्रॉक्सी पत्ता तपासणे<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM वापर यासारखी डिव्हाइस आकडेवारी</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">तुमचे डिव्हाइस <ph name="ENROLLMENT_DOMAIN" /> कडून व्यवस्थापित केले जाते आणि तुमचे खाते <ph name="ACCOUNT_DOMAIN" /> कडून व्यवस्थापित केले जाते. याचा अर्थ तुमचे अ‍ॅडमिनिस्ट्रेटर तुमचे डिव्हाइस आणि खाते रिमोट पद्धतीने कॉन्फिगर करू शकतात.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-बिट)</translation>
-<translation id="5128122789703661928">हे नाव असलेले सेशन हटवण्यासाठी वैध नाही.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">पत्ते व्यवस्थापित करा...</translation>
+<translation id="5138227688689900538">कमी दाखवा</translation>
<translation id="5141240743006678641">तुमच्या Google क्रेडेंशियलसह सिंक केलेले पासवर्ड एंक्रिप्ट करा</translation>
<translation id="5145883236150621069">धोरण प्रतिसादामध्ये एरर कोड अस्तित्वात आहे</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">नवीन गुप्त विंडोमध्ये पेज उघडा (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> चा CVC टाका. तुम्ही निश्चित केल्यानंतर तुमच्या Google खात्यामधील कार्डाचा तपशील या साइटसोबत शेअर केला जाईल.</translation>
<translation id="5169827969064885044">तुम्ही तुमच्या संस्थेच्या खात्याचा अॅक्सेस गमावू शकता किंवा तुमची संवेदनशील माहिती चोरीला जाऊ शकते. Chrome लगेच तुमचा पासवर्ड बदलण्याची शिफारस करत आहे.</translation>
<translation id="5171045022955879922">URL शोधा किंवा टाइप करा</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">मशीन</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> मध्ये नाही? या एररचा अहवाल नोंदवा</translation>
<translation id="5190835502935405962">बुकमार्क बार</translation>
-<translation id="5200263511887412697">नुकतेच लॉग इन केलेल्या डिव्हाइस वापरकर्त्यांची अहवाल सूची</translation>
+<translation id="519422657042045905">भाष्य उपलब्ध नाही</translation>
<translation id="5201306358585911203">या पेजवरील एंबेड केलेल्‍या पेजचे म्हणणे हे आहे की</translation>
<translation id="5205222826937269299">नाव आवश्यक आहे</translation>
<translation id="5215116848420601511">Google Pay वापरून पेमेंट पद्धती आणि पत्ते</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ईमेल आवश्यक आहे</translation>
<translation id="5230733896359313003">पाठविण्याचा पत्ता</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"नेटवर्कशी कनेक्ट करा"</translation>
<translation id="5251803541071282808">क्लाउड</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">नेटवर्क पत्ते</translation>
<translation id="5285570108065881030">सर्व सेव्ह केलेले पासवर्ड दाखवा</translation>
<translation id="5287240709317226393">कुकीज दाखवा</translation>
<translation id="5288108484102287882">धोरण मूल्यांच्या वैधतेमुळे चेतावण्या वाढल्या आहेत</translation>
@@ -692,7 +790,9 @@
<translation id="5323105697514565458"><ph name="NUM_MATCHES" /> पैकी <ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">संपर्क माहिती निवडा</translation>
<translation id="5327248766486351172">नाव</translation>
+<translation id="5329858041417644019">तुमचे ब्राउझर व्यवस्थापित केलेले नाही</translation>
<translation id="5332219387342487447">पाठविण्‍याची पद्धत</translation>
+<translation id="5334013548165032829">तपशीलवार सिस्टम लॉग</translation>
<translation id="5344579389779391559">या पेजवर कदाचित तुमच्याकडून शुल्क आकारले जाऊ शकते</translation>
<translation id="5355557959165512791">तुम्ही आत्ता <ph name="SITE" /> ला भेट देऊ शकत नाही कारण तिचे सर्टिफिकेट रिव्होक केले गेले आहे. नेटवर्क एरर आणि आक्रमणे शक्यतो तात्पुरती असतात, त्यामुळे हे पेज नंतर पाहता येईल.</translation>
<translation id="536296301121032821">धोरण सेटिंग्ज संचयित करण्यात अयशस्वी</translation>
@@ -700,6 +800,7 @@
<translation id="5377026284221673050">"तुमचे क्लॉक मागे पडले आहे" किंवा "तुमचे क्लॉक वेळेपेक्षा पुढे आहे" किंवा "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">तुमच्या सर्व डिव्हाइसवर तुमची कार्डे वापरण्यासाठी साइन इन करा आणि सिंक सुरू करा.</translation>
<translation id="5386426401304769735">या साइटसाठी असलेल्या सर्टिफिकेट श्रृंखलेत SHA-1 वापरून स्वाक्षरी केलेले सर्टिफिकेट असते.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">हा सर्व्हर <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट यावेळी वैध नाही. हे कदाचित चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोर तुमचे कनेक्शन इंटरसेप्ट करत असल्‍यामुळे होऊ शकते.</translation>
<translation id="5421136146218899937">ब्राउझिंग डेटा साफ करा...</translation>
<translation id="5430298929874300616">बुकमार्क काढून टाका</translation>
@@ -710,6 +811,7 @@
<translation id="5457113250005438886">चुकीचा</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;संपादित करा पुन्हा करा</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">हा आशय तुमच्या डिव्हाइसवर तुमची माहिती चोरू किंवा मिटवू शकणारे धोकादायक सॉफ्टवेअर इंस्टॉल करण्याचा कदाचित प्रयत्न करेल. <ph name="BEGIN_LINK" />तरीही दाखवा<ph name="END_LINK" /></translation>
<translation id="54817484435770891">वैध पत्ता जोडा</translation>
<translation id="5490432419156082418">पत्ते आणि बरेच काही</translation>
@@ -717,10 +819,12 @@
<ph name="LINE_BREAK" />
सिस्टम अॅडमिनिस्ट्रेटराशी संपर्क साधण्याचा प्रयत्न करा.</translation>
<translation id="549333378215107354">आकार ३</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">व्यवस्थापित केलेले बुकमार्क</translation>
<translation id="5510766032865166053">ती कदाचित हलविली किंवा हटविली गेली आहे.</translation>
<translation id="5523118979700054094">धोरणाचे नाव</translation>
<translation id="552553974213252141">मजकूर योग्यरितीने काढला होता?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">विनंती केलेला लेख शोधू शकलो नाही.</translation>
<translation id="5541546772353173584">ईमेल जोडा</translation>
<translation id="5545756402275714221">तुमच्यासाठी लेख</translation>
@@ -735,15 +839,21 @@
<translation id="5595485650161345191">पत्ता संपादित करा</translation>
<translation id="5598944008576757369">पेमेंट पद्धत निवडा</translation>
<translation id="560412284261940334">व्यवस्थापन समर्थित नाही</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">कनेक्शन तपासणे</translation>
<translation id="5610807607761827392">तुम्ही कार्ड आणि पत्ते <ph name="BEGIN_LINK" />सेटिंग्ज<ph name="END_LINK" /> मध्ये व्यवस्थापित करू शकता.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> नी आपल्‍याला अनेक वेळा पुनर्निर्देशित केले.</translation>
<translation id="5629630648637658800">धोरण सेटिंग्ज लोड करण्यात अयशस्वी</translation>
<translation id="5631439013527180824">चुकीचे डिव्हाइस व्यवस्थापन टोकन</translation>
+<translation id="5632627355679805402">तुमचा डेटा तुमच्या <ph name="BEGIN_LINK" />Google पासवर्ड <ph name="END_LINK" /> ने <ph name="TIME" /> वाजता एंक्रिप्ट केला गेला होता. सिंक सुरू करण्यासाठी तो एंटर करा.</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="563324245173044180">फसवणारा आशय ब्लॉक केला.</translation>
<translation id="5659593005791499971">ईमेल</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">या डिव्हाइसच्या अ‍ॅडमिनिस्ट्रेटरने अतिरिक्त फंक्शनसाठी एक्स्टेंशन इंस्टॉल केले आहे. एक्स्टेंशनकडे तुमच्या काही डेटाचा अ‍ॅक्सेस आहे.</translation>
<translation id="5675650730144413517">हे पृष्ठ कार्य करीत नाही</translation>
+<translation id="5684874026226664614">अरेरे. हे पृष्‍ठ भाषांतरित केले जाऊ शकले नाही.</translation>
<translation id="5685654322157854305">पाठवण्याचा पत्ता जोडा</translation>
<translation id="5689199277474810259">JSON वर एक्सपोर्ट करा</translation>
<translation id="5689516760719285838">स्थान</translation>
@@ -752,38 +862,39 @@
<translation id="5710435578057952990">या वेबसाइटची ओळख सत्यापित केली गेली नाही.</translation>
<translation id="5719499550583120431">प्रीपेड कार्डे स्वीकारली जातात.</translation>
<translation id="5720705177508910913">वर्तमान वापरकर्ता</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">जर तुम्ही तुमच्या पासवर्डचा इतर साइटवर पुन्हा वापर केला असेल तर Chrome तुम्हाला तो रीसेट करण्याची शिफारस करतो.</translation>
<translation id="5732392974455271431">तुमचे पालक तुमच्यासाठी ती अनावरोधित करू शकतात</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{तुमच्या Google खात्यामध्ये कार्ड सेव्ह करा}one{तुमच्या Google खात्यामध्ये कार्डे सेव्ह करा}other{तुमच्या Google खात्यामध्ये कार्डे सेव्ह करा}}</translation>
<translation id="5763042198335101085">वैध ईमेल अॅड्रेस एंटर करा</translation>
<translation id="5765072501007116331">वितरण पद्धती आणि आवश्यकता पाहण्यासाठी, एक पत्ता निवडा</translation>
-<translation id="5770114862687765385">फाइल करप्ट आहे असे दिसते. सेशन रीसेट करण्यासाठी 'रीसेट करा' बटणावर क्लिक करा.</translation>
<translation id="5778550464785688721">MIDI डिव्हाइसेस पूर्ण नियंत्रण</translation>
<translation id="578305955206182703">अंबर</translation>
<translation id="57838592816432529">निःशब्द करा</translation>
<translation id="5784606427469807560">आपल्या कार्डची पुष्टी करताना समस्या आली. तुमचे इंटरनेट कनेक्शन तपासा आणि पुन्हा प्रयत्न करा.</translation>
<translation id="5785756445106461925">पुढे, या पृष्ठात सुरक्षित नसलेली इतर संसाधने समाविष्ट आहेत. ही संसाधने संक्रमणात असताना इतरांद्वारे पाहिली जाऊ शकतात आणि पृष्ठाचे स्वरूप बदलण्यासाठी आक्रमणकर्त्याद्वारे सुधारित केली जाऊ शकतात.</translation>
<translation id="5786044859038896871">तुम्ही तुमची कार्ड माहिती भरू इच्छित आहात?</translation>
+<translation id="5798290721819630480">बदल टाकून द्यायचे?</translation>
<translation id="5798683403665926540">Chrome सेटिंग्जमध्ये होम पेज बदला</translation>
<translation id="5803412860119678065">तुम्ही तुमचे <ph name="CARD_DETAIL" /> भरू इच्छित आहात?</translation>
<translation id="5804241973901381774">परवानग्या</translation>
<translation id="5810442152076338065">तुमचे <ph name="DOMAIN" /> वरील कनेक्शन अॉब्सोलीट सायफर सूट वापरून एंक्रिप्ट केलेले आहे.</translation>
<translation id="5813119285467412249">&amp;जोडा पुन्हा करा</translation>
<translation id="5838278095973806738">या साइटवर कोणतीही संवेदनशील माहिती (उदाहरणार्थ, पासवर्ड किंवा क्रेडिट कार्ड) एंटर करू नका, कारण आक्रमणकर्ते ती चोरू शकतात.</translation>
+<translation id="5860033963881614850">बंद</translation>
<translation id="5863847714970149516">पुढील पेजवर तुमच्याकडून शुल्क आकारले जाऊ शकते</translation>
<translation id="5866257070973731571">फोन नंबर जोडा</translation>
<translation id="5869405914158311789">या साइटवर पोहचणे शक्य नाही</translation>
<translation id="5869522115854928033">सेव्ह केलेले पासवर्ड</translation>
<translation id="5887400589839399685">कार्ड सेव्ह केले</translation>
-<translation id="5893718151540690985">नेटवर्क इंटरफेसच्या सूचीचा त्यांचे प्रकार आणि हार्डवेअर अ‍ॅड्रेससह अहवाल द्या</translation>
<translation id="5893752035575986141">क्रेडिट कार्डे स्वीकारली जातात.</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="5916664084637901428">चालू</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google खात्यात कार्ड सेव्ह करायचे?</translation>
<translation id="5922853866070715753">जवळजवळ पूर्ण झाले</translation>
<translation id="5932224571077948991">साइट अनाहूत किंवा दिशाभूल करणाऱ्या जाहिराती दाखवते</translation>
-<translation id="5939518447894949180">रीसेट करा</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> उघडत आहे…</translation>
<translation id="5951495562196540101">उपभोक्ता खात्याने नोंदणी करू शकत नाही (पॅकेज केलेला परवाना उपलब्ध).</translation>
<translation id="5967592137238574583">संपर्क माहिती संपादित करा</translation>
@@ -791,6 +902,7 @@
<translation id="5975083100439434680">झूम कमी करा</translation>
<translation id="5977489021191000276">तुमचे डिव्हाइस अ‍ॅडमिनिस्ट्रेटरकडून व्यवस्थापित केले जात नाही.</translation>
<translation id="5977976211062815271">या डिव्हाइसवरील</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">पेमेंट ॲप उघडू शकत नाही</translation>
<translation id="5989320800837274978">निश्चित प्रॉक्‍सी सर्व्हर किंवा .pac स्क्रिप्ट URL देखील निर्दिष्‍ट केलेली नाही.</translation>
<translation id="5990559369517809815">सर्व्हरला केल्या जाणार्‍या विनंत्या एका विस्ताराने अवरोधित केल्या गेल्या आहेत.</translation>
@@ -801,8 +913,8 @@
<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="6033927989869462158">CPU/RAM वापरासारख्या हार्डवेअर आकडेवारीचा अहवाल द्या</translation>
<translation id="6034000775414344507">फिकट राखाडी</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">समस्या कायम राहिल्यास साइटच्या मालकाशी संपर्क साधा.</translation>
<translation id="6040143037577758943">बंद करा</translation>
<translation id="6044573915096792553">आकार १२</translation>
@@ -811,10 +923,10 @@
<translation id="6051221802930200923">ही वेबसाइट सर्टिफिकेट पिनिंग वापरत असल्यामुळे तुम्ही आत्ता <ph name="SITE" /> पाहू शकणार नाही. नेटवर्क एरर आणि आक्रमणे शक्यतो तात्पुरती असतात, त्यामुळे हे पेज नंतर पाहता येईल.</translation>
<translation id="6058977677006700226">तुमच्या सर्व डिव्हाइसवर तुमची कार्डे वापरायची का?</translation>
<translation id="6059925163896151826">USB डिव्हाइसेस</translation>
-<translation id="6071091556643036997">धोरणाचा प्रकार चुकीचा आहे.</translation>
<translation id="6080696365213338172">तुम्ही अॅडमिनिस्ट्रेटरने दिलेले सर्टिफिकेट वापरून आशय अॅक्सेस केला. तुम्ही <ph name="DOMAIN" /> वर प्रदान करता तो डेटा तुमच्या अॅडमिनिस्ट्रेटरद्वारे इंटरसेप्ट केला जाऊ शकतो.</translation>
<translation id="6094273045989040137">भाष्य करा</translation>
<translation id="610911394827799129">तुमच्या Google खात्यामध्ये <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> वर ब्राउझिंग इतिहासाची अन्य स्वरूपे असू शकतात.</translation>
+<translation id="6132597952260690497">इंस्टॉल केलेल्या एक्स्टेंशन आणि प्लग-इनविषयी माहिती</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{काहीही नाही}=1{1 पासवर्ड (सिंक केलेला)}one{# पासवर्ड (सिंक केलेला)}other{# पासवर्ड (सिंक केलेले)}}</translation>
<translation id="6146055958333702838">कोणत्याही केबल तपासा आणि कोणतेही राउटर, मोडेम किंवा तुम्ही
वापरत असलेले
@@ -850,15 +962,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> पेक्षा कमी जागा मोकळी करते. काही साइट तुमच्या पुढील भेटीच्या वेळी आणखी धीम्या गतीने लोड होऊ शकतात.</translation>
<translation id="6337534724793800597">धोरणे नावानुसार फिल्टर करा</translation>
<translation id="6358450015545214790">याचा अर्थ काय आहे?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">पुढे संभाव्य शुल्क आहे.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 अन्य सूचना}one{# अन्य सूचना}other{# अन्य सूचना}}</translation>
<translation id="6387754724289022810">पुढील वेळी जलद पेमेंट देण्यासाठी, तुमच्या Google खात्यावर आणि या डिव्हाइसवर तुमचे कार्ड आणि बिलिंग पत्ता सेव्ह करा.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">बुकमार्क संपादित करा</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> साठी कालबाह्यता तारीख आणि CVC प्रविष्‍ट करा</translation>
<translation id="6414888972213066896">या साइटला भेट देणे ठीक आहे का ते तुम्ही आपल्‍या पालकास विचारले</translation>
<translation id="6417515091412812850">सर्टिफिकेट मागे घेतले की नाही हे तपासता आले नाही.</translation>
<translation id="6433490469411711332">संपर्क माहिती संपादित करा</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> नी कनेक्ट करण्यास नकार दिला.</translation>
+<translation id="6434309073475700221">नाकारा</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">अधिक माहिती जोडा</translation>
<translation id="6447842834002726250">कुकीज</translation>
<translation id="6451458296329894277">फॉर्म रीसबमिशनची पुष्टी करा</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Chrome रीस्टार्ट करा</translation>
<translation id="6529602333819889595">&amp;पुन्हा करा हटवा</translation>
<translation id="6534179046333460208">वास्तविक वेब सूचना</translation>
+<translation id="6556866813142980365">पुन्हा करा</translation>
<translation id="6563469144985748109">आपल्या व्यवस्थापकाने अद्याप ती मंजूर केली नाही</translation>
<translation id="6569060085658103619">तुम्ही एक विस्तार पृष्ठ पाहत आहात</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">फिकट गुलाबी</translation>
+<translation id="6583674473685352014">B6 (Envelope)B6 (Envelope)</translation>
+<translation id="6587923378399804057">तुम्ही कॉपी केलेली लिंक</translation>
+<translation id="6591833882275308647">तुमचे <ph name="DEVICE_TYPE" /> व्यवस्थापित केलेले नाही</translation>
<translation id="6596325263575161958">एंक्रिप्शन पर्याय</translation>
<translation id="6604181099783169992">गती किंवा प्रकाश सेन्सर</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)Prc7 (Envelope)</translation>
<translation id="6624427990725312378">संपर्क माहिती</translation>
<translation id="6626291197371920147">वैध कार्ड नंबर जोडा</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> शोध</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">हे धोरण नापसंत आहे.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{काहीही नाही}=1{एका साइटवरून (तुम्हाला तुमच्या Google खात्यातून साइन आउट केले जाणार नाही)}one{# साइटवरून (तुम्हाला तुमच्या Google खात्यातून साइन आउट केले जाणार नाही)}other{# साइटवरून (तुम्हाला तुमच्या Google खात्यातून साइन आउट केले जाणार नाही)}}</translation>
<translation id="6657585470893396449">पासवर्ड</translation>
+<translation id="6670613747977017428">सुरक्षिततेकडे परत जा.</translation>
<translation id="6671697161687535275">Chromium वरून फॉर्म सूचना काढून टाकायच्या?</translation>
<translation id="6685834062052613830">साइन आउट करा आणि सेटअप पूर्ण करा</translation>
<translation id="6710213216561001401">मागील</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">नोंदणी टोकन:</translation>
<translation id="6711464428925977395">प्रॉक्सी सर्व्हरमध्ये काहीतरी चुकीचे आहे किंवा पत्ता चुकीचा आहे.</translation>
<translation id="6723740634201835758">तुमच्या Google खात्यामध्ये</translation>
+<translation id="6738516213925468394">तुमचा डेटा तुमच्या <ph name="BEGIN_LINK" />सिंक पासफ्रेज<ph name="END_LINK" /> ने <ph name="TIME" /> वाजता एंक्रिप्ट केला गेला होता. सिंक सुरू करण्यासाठी तो एंटर करा.</translation>
<translation id="674375294223700098">अज्ञात सर्व्हर सर्टिफिकेट एरर.</translation>
<translation id="6744009308914054259">कनेक्शनची वाट पाहत असताना, तुम्ही ऑफलाइन लेख वाचण्यासाठी डाउनलोडवर जाऊ शकता.</translation>
<translation id="6753269504797312559">धोरण मूल्य</translation>
<translation id="6757797048963528358">तुमचे डिव्हाइस निष्क्रीय झाले.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">आपल्या पालकाने अद्याप ती मंजूर केली नाही</translation>
<translation id="67862343314499040">जांभळा</translation>
+<translation id="6786747875388722282">विस्तार</translation>
<translation id="679355240208270552">दुर्लक्ष केले कारण डीफॉल्ट शोध धोरणाने सुरू केलेले नाही</translation>
<translation id="681021252041861472">आवश्यक भाग</translation>
<translation id="6810899417690483278">सानुकूलीकरण आयडी</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">डिव्हाइस</translation>
<translation id="6970216967273061347">जिल्हा</translation>
<translation id="6973656660372572881">निश्चित प्रॉक्सी सर्व्हर आणि .pac स्क्रिप्ट URL निर्दिष्‍ट करण्‍यात आले आहेत.</translation>
+<translation id="6973932557599545801">सॉरी मला मदत करता आली नाही कृपया तुम्ही स्वतःच सुरू ठेवा.</translation>
<translation id="6979158407327259162">Google ड्राइव्ह</translation>
<translation id="6979440798594660689">निःशब्द करा (डीफॉल्ट)</translation>
<translation id="6984479912851154518">बाह्य अॅप्लिकेशनने पैसे भरण्यासाठी खाजगी मोड सोडत आहे. सुरू ठेवायचे का?</translation>
<translation id="6989763994942163495">प्रगत सेटिंग्ज दर्शवा...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)6x9 (Envelope)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" />चे नेहमी भाषांतर करा</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">हे शुल्क एकाच वेळी द्यायचे किंवा आवर्ती असू शकतात आणि स्पष्ट नसू शकतात.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">लपवा</translation>
<translation id="7108819624672055576">एका विस्ताराने परवानगी दिलेले</translation>
<translation id="7111012039238467737">(वैध)</translation>
+<translation id="7118618213916969306">क्लिपबोर्ड URL, <ph name="SHORT_URL" /> शोधा</translation>
<translation id="7119414471315195487">अन्य टॅब आणि प्रोग्राम बंद करा</translation>
<translation id="7129409597930077180">या पत्त्यावर पाठवू शकत नाही. वेगळा पत्ता निवडा.</translation>
<translation id="7135130955892390533">स्थिती दाखवा</translation>
<translation id="7138472120740807366">वितरण पद्धत</translation>
<translation id="7139724024395191329">अमिरात</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">फिकट जांभळा</translation>
-<translation id="7158980942472052083">चुकीची URL. साधारण स्कीम असलेली URL असणे आवश्यक आहे.</translation>
<translation id="717330890047184534">Gaia आयडी:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">तुम्ही जात आहात तो सर्व्हर, <ph name="ORIGIN" />, ने विनंती केली आहे की
+ सुरक्षितता धोरण त्याच्या सर्व विनंत्यांना लागू होईल. परंतु धोरण डिलिव्हर
+ करण्याऐवजी त्याने ब्राउझर अन्यत्र रीडिरेक्ट केले जे ब्राउझरला तुमच्या <ph name="SITE" /> साठीच्या
+ विनंतीची पूर्तता करण्यापासून रोखते.</translation>
<translation id="7179323680825933600">पेमेंट पद्धती सेव्ह करा आणि भरा</translation>
<translation id="7180611975245234373">रिफ्रेश करा</translation>
<translation id="7182878459783632708">कोणतीही धोरणे सेट नाहीत</translation>
<translation id="7186367841673660872">हे पृष्ठ<ph name="ORIGINAL_LANGUAGE" />मधून<ph name="LANGUAGE_LANGUAGE" />मध्ये अनुवादित केले गेले आहे</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> जागा मोकळी करते. काही साइट तुमच्या पुढील भेटीच्या वेळी आणखी धीम्या गतीने लोड होऊ शकतात.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">तुमचा अ‍ॅडमिनिस्ट्रेटर हे पाहू शकतो:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> नी सुरक्षितता मानकांचे पालन केले नाही.</translation>
<translation id="721197778055552897">या समस्येबद्दल <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">कनेक्शन <ph name="SSL_VERSION" /> वापरते.</translation>
<translation id="7220786058474068424">प्रक्रिया करत आहे</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">साइटमध्ये पुढे मालवेअर आहे</translation>
+<translation id="724766306220616965">चेतावण्या, विरोध</translation>
<translation id="724975217298816891">तुमचे कार्ड तपशील अपडेट करण्‍यासाठी <ph name="CREDIT_CARD" /> करिता कालबाह्यता तारीख आणि CVC प्रविष्‍ट करा. तुम्ही पुष्टी केल्यावर, तुमचे कार्ड तपशील या साइटसह शेअर केले जातील.</translation>
<translation id="7251437084390964440">नेटवर्क कॉन्फिगरेशन ONC स्टँडर्डचे पालन करत नाही. कॉन्फिगरेशनचे भाग कदाचित इंपोर्ट करता येणार नाहीत.
अतिरिक्त तपशील:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">गडद निळा</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> वाजता क्रॅश अहवाल कॅप्चर केला (वापरकर्त्याने विनंती केलेले अपलोड, अद्याप अपलोड केलेले नाही)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />सुरक्षित ब्राउझिंग<ph name="END_LINK" /> चेतावणी</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">कनेक्शन मदत</translation>
<translation id="7334320624316649418">&amp;पुनर्क्रमित करा पुन्हा करा</translation>
<translation id="733923710415886693">सर्टिफिकेट पारदर्शकतेअंतर्गत सर्व्हरचे सर्टिफिकेट उघड केले नाही.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">कमांड लाइन</translation>
-<translation id="7365061714576910172">Linux एक्सपोर्ट करा</translation>
<translation id="7372973238305370288">शोध परिणाम</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">नाही</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">व्यवस्थापित केलेले सेशन ओव्हरराइड</translation>
<translation id="7390545607259442187">कार्डची पुष्टी करा</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">तुमचे <ph name="DEVICE_NAME" /> व्यवस्थापित केले आहे</translation>
<translation id="7407424307057130981">&lt;p&gt;जर तुम्हाला Windows कॉंप्युटरवर Superfish सॉफ्टवेअर असेल, तर तुम्हाला हा एरर दिसेल.&lt;/p&gt;
&lt;p&gt;सॉफ्टवेअरला तात्पुरत्या स्वरुपात बंद करण्यासाठी या पायऱ्यांनुसार कृती करा, जेणेकरून तुम्‍ही ते वेबवर मिळवू शकाल. तुमच्याकडे अॅडमिनिस्ट्रेटरचे अधिकार असणे आवश्यक आहे.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;&lt;strong&gt;लागू करा&lt;/strong&gt; वर क्लिक करा, मग &lt;strong&gt;ओके&lt;/strong&gt; वर क्लिक करा
&lt;li&gt;तुमच्या कॉंप्युटरवरून सॉफ्टवेअर कायमस्वरूपी कसे काढून टाकावे याबाबत शिकण्यासाठी&lt;a href="https://support.google.com/chrome/answer/6०९886९"&gt;Chrome मदत केंद्र&lt;/a&gt; ला भेट द्या.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> व्यवस्थापन</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">पासवर्ड व्यवस्थापित करा…</translation>
<translation id="7419106976560586862">प्रोफाइल पथ</translation>
<translation id="7437289804838430631">संपर्क माहिती जोडा</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">फिकट नारिंगी</translation>
<translation id="7444046173054089907">ही साइट अवरोधित केली आहे</translation>
<translation id="7445762425076701745">तुम्ही कनेक्ट केलेल्या सर्व्हरची ओळख पूर्णपणे पडताळणे शक्य नाही. तुम्ही सर्व्हरशी फक्त आपल्‍या डोमेनमध्ये वैध असलेले नाव वापरून कनेक्ट केलेले आहे, ज्याची मालकी सत्यापित करण्यासाठी बाह्य सर्टिफिकेट अधिकृततेला परवानगी नाही. काही सर्टिफिकेट अधिकारी तरीही या नावांसाठी सर्टिफिकेट जारी करतील, याची खात्री करण्याचा काहीही मार्ग नाही की तुम्ही इच्छित वेबसाइटशी कनेक्ट केले आहे आणि हल्लेखोराशी नाही.</translation>
-<translation id="7449109375006139765">सिस्टम लॉग व्यवस्थापन सर्व्हरला पाठवा</translation>
<translation id="7451311239929941790">या समस्येविषयी <ph name="BEGIN_LINK" />अधिक जाणून घेणे<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">सार्वत्रिक डीफॉल्‍ट वापरा (अवरोधित करा)</translation>
<translation id="7460618730930299168">तुम्ही जे निवडले, त्यापेक्षा स्क्रीनिंग वेगळे आहे. सुरू ठेवायचे का?</translation>
<translation id="7473891865547856676">नाही, नको</translation>
-<translation id="7475525192983021547">वापरकर्ता डिव्हाइसवर अ‍ॅक्टिव्ह असतानाच्या कालावधींचा अहवाल द्या</translation>
<translation id="7481312909269577407">पुढील</translation>
<translation id="7485870689360869515">डेटा आढळला नाही.</translation>
+<translation id="7498234416455752244">संपादन सुरू ठेवा</translation>
<translation id="7508255263130623398">परत केलेला धोरण डिव्हाइस आयडी रिक्त आहे किंवा वर्तमान डिव्हाइस आयडी शी जुळत नाही</translation>
<translation id="7508870219247277067">हिरवे पिवळे</translation>
<translation id="7511955381719512146">तुम्ही वापरत असलेल्या वाय-फाय ला तुम्ही <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ला भेट देण्याची आवश्यकता असू शकते.</translation>
<translation id="7514365320538308">डाउनलोड करा</translation>
<translation id="7518003948725431193">या वेबपत्त्यासाठी वेबपृष्ठ आढळले नाही: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">या साइटवर तुमचे कनेक्शन खाजगी नाही</translation>
+<translation id="7535087603100972091">मूल्य</translation>
<translation id="7537536606612762813">अनिवार्य</translation>
+<translation id="7538364083937897561">A2 (Envelope)</translation>
<translation id="7542403920425041731">तुम्ही निश्चित केल्यावर, तुमचे कार्ड तपशील या साइटसह शेअर केले जातील.</translation>
<translation id="7542995811387359312">स्वयंचलित क्रेडिट कार्ड भरणे अक्षम झाले आहे कारण हा फॉर्म सुरक्षित कनेक्शन वापरत नाही.</translation>
<translation id="7543525346216957623">आपल्या पालकास विचारा</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">खालील टिपा वापरून पहा:</translation>
<translation id="7554791636758816595">नवीन टॅब</translation>
<translation id="7564049878696755256">तुम्ही तुमच्या Google <ph name="ORG_NAME" /> चा अॅक्सेस गमावू शकता किंवा तुमची संवेदनशील माहिती चोरीला जाऊ शकते. Chrome लगेच तुमचा पासवर्ड बदलण्याची शिफारस करत आहे.</translation>
-<translation id="7566125604157659769">तुम्ही कॉपी केलेला मजकूर</translation>
<translation id="7567204685887185387">हा सर्व्हर हे <ph name="DOMAIN" /> असल्याचे सिद्ध करू शकला नाही; त्याचे सुरक्षितता सर्टिफिकेट कदाचित लबाडीने जारी केले असावे. हे कदाचित एका चुकीच्या कॉंफिगरेशनमुळे किंवा हल्लेखोराने तुमचे कनेक्शन इंटरसेप्ट केल्यामुळे झाले असू शकते.</translation>
+<translation id="7568105740864181217">हा ब्राउझर कंपनी, शाळा किंवा अन्य संस्थेद्वारे व्यवस्थापित केला आहे. तुमचा अ‍ॅडमिनिस्ट्रेटर तुमच्या ब्राउझरचे सेटअप रिमोट पद्धतीने बदलू शकतो. या डिव्हाइसवरील अ‍ॅक्टिव्हिटी कदाचित Chrome च्या बाहेर व्यवस्थापित केलेली असू शकते. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome मधून क्रेडिट कार्ड काढून टाकायचे?</translation>
<translation id="7569983096843329377">काळा</translation>
<translation id="7578104083680115302">तुम्ही Google सह सेव्ह केलेल्या कार्डचा वापर करून डिव्‍हाइसेसवरून द्रुतपणे साइट आणि अॅप्सवर पेमेंट करा.</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">परफॉर्मंस डेटा आणि क्रॅश अहवाल</translation>
<translation id="7637571805876720304">Chromium वरून क्रेडिट कार्ड काढून टाकायचे?</translation>
<translation id="7639968568612851608">गडद राखाडी</translation>
<translation id="765676359832457558">प्रगत सेटिंग्ज लपवा...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">परत केलेले धोरण टोकन रिक्त आहे किंवा वर्तमान टोकनशी जुळत नाही</translation>
<translation id="7668654391829183341">अज्ञात डिव्हाइस</translation>
<translation id="7669271284792375604">या साइट वरील आक्रमणकर्ते कदाचित आपल्या ब्राउझिंग अनुभवास हानी पोहोचविणारे प्रोग्राम (उदाहरणार्थ, तुमचे मुख्यपृष्ठ बदलून किंवा तुम्ही भेट देता त्या साइटवर अतिरिक्त जाहिराती दर्शवून) इंस्टॉल करून तुमची फसवणूक करण्‍याचा प्रयत्न करू शकतात.</translation>
+<translation id="7676643023259824263">क्लिपबोर्ड मजकूर, <ph name="TEXT" /> शोधा</translation>
<translation id="7681101578153515023">शोध इंजिन बदला</translation>
<translation id="7682287625158474539">शिपिंग</translation>
<translation id="7687186412095877299">तुमच्या सेव्ह केलेल्या पेमेंट पद्धतींसह पेमेंट फॉर्म भरते</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">सध्या, तुमच्याकडे अशी कार्डे आहेत जी फक्त या डिव्हाइसवर वापरली जाऊ शकतात. कार्डांचे पुनरावलोकन करण्यासाठी सुरू ठेवा क्लिक करा.</translation>
<translation id="7699293099605015246">लेख आत्ता उपलब्ध नाहीत</translation>
<translation id="7701040980221191251">काहीही नाही</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">धोकादायक आशय ब्लॉक केला.</translation>
<translation id="7752995774971033316">व्यवस्थापित न केलेले</translation>
<translation id="7755287808199759310">तुमचे पालक तुमच्यासाठी ती अनावरोधित करू शकतात</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">फायरवॉल किंवा अँटीव्हायरस सॉफ्टवेअरने कदाचित कनेक्शन अवरोधित केले असावे.</translation>
<translation id="7759163816903619567">डोमेन दाखवा:</translation>
<translation id="7761701407923456692">सर्व्हरचे सर्टिफिकेट URL शी जुळत नाही.</translation>
<translation id="7763386264682878361">पेमेंट मॅनिफेस्ट विश्लेषक</translation>
<translation id="7764225426217299476">पत्ता जोडा</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">परफेक्चुअर</translation>
<translation id="7791543448312431591">जोडा</translation>
<translation id="7793809570500803535"><ph name="SITE" />येथील वेबपृष्ठ कदाचित तात्पुरते बंद आहे किंवा ते कदाचित नवीन वेब पत्त्यावर कायमचे हलवले आहे.</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome मधून सूचना फॉर्म काढून टाकायचा?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' साठी <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> सापडले</translation>
-<translation id="7818867226424560206">धोरण व्‍यवस्‍थापन</translation>
<translation id="782886543891417279">तुम्ही वापरत असलेल्या (<ph name="WIFI_NAME" />) वाय-फाय च्या लॉग इन पेजला तुम्हाला भेट देण्याची आवश्यकता असू शकते.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{काहीही नाही}=1{एक अ‍ॅप <ph name="EXAMPLE_APP_1" />}=2{२ अ‍ॅप्स <ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />}one{# अ‍ॅप्स <ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />}other{# अ‍ॅप्स <ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />}}</translation>
<translation id="785549533363645510">तरीही, तुम्ही अदृश्य नाही. गुप्त झाल्याने तुमचे ब्राउझिंग तुमचा एम्पलॉयर, तुमचा इंटरनेट सेवा पुरवठादार, किंवा तुम्ही भेट देता त्या वेबसाइटपासून लपत नाही.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">तुमच्या पासवर्डशी तडजोड होत असल्याची शक्यता आहे</translation>
<translation id="7882421473871500483">तपकिरी</translation>
<translation id="7887683347370398519">तुमचे CVC तपासा आणि पुन्हा प्रयत्न करा</translation>
-<translation id="7893255318348328562">सेशन नाव</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">वैध फोन नंबर एंटर करा</translation>
<translation id="7935318582918952113">DOM डिस्टिलर</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" /> रोजी एक्स्पायर होईल</translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(32-बिट)</translation>
<translation id="7956713633345437162">Mobile बुकमार्क</translation>
<translation id="7961015016161918242">कधीही नाही</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">नमूद केलेले नाही</translation>
<translation id="800218591365569300">मेमरी मोकळी करण्‍यासाठी अन्य टॅब किंवा प्रोग्राम बंद करून पहा.</translation>
+<translation id="8004582292198964060">ब्राउझर</translation>
<translation id="8009225694047762179">पासवर्ड व्यवस्थापित करा</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{हे कार्ड आणि त्याचा बिलिंग पत्ता सेव्ह केला जाईल. <ph name="USER_EMAIL" /> मध्ये साइन इन केलेले असताना तुम्ही ते वापरू शकाल.}one{हे कार्ड आणि त्याचा बिलिंग पत्ता सेव्ह केला जाईल. <ph name="USER_EMAIL" /> मध्ये साइन इन केलेले असताना तुम्ही ते वापरू शकाल.}other{ही कार्डे आणि त्यांचे बिलिंग पत्ते सेव्ह केले जातील. <ph name="USER_EMAIL" /> मध्ये साइन इन केलेले असताना तुम्ही ती वापरू शकाल.}}</translation>
<translation id="8012647001091218357">आम्ही याक्षणी आपल्या पालकांपर्यंत पोहोचू शकलो नाही. कृपया पुन्हा प्रयत्न करा.</translation>
<translation id="8025119109950072390">या साइट वरील आक्रमणकर्ते सॉफ्‍टवेअर इंस्टॉल करणे किंवा तुमची वैयक्तिक माहिती (उदाहरणार्थ, पासवर्ड, फोन नंबर किंवा क्रेडिट कार्ड) उघड करणे यासारखे काहीतरी धोकादायक करण्‍यामध्‍ये आपल्‍याला युक्तीने गुंतवू शकतात.</translation>
<translation id="8034522405403831421">हे पृष्‍ठ <ph name="SOURCE_LANGUAGE" /> मध्ये आहे. त्यास <ph name="TARGET_LANGUAGE" /> मध्ये भाषांतरीत करायचे?</translation>
<translation id="8035152190676905274">पेन</translation>
+<translation id="8037117624646282037">डिव्हाइस अलीकडे कोणी वापरले</translation>
<translation id="8037357227543935929">विचारा (डीफॉल्ट)</translation>
<translation id="803771048473350947">फाइल</translation>
<translation id="8041089156583427627">अभिप्राय पाठवा</translation>
<translation id="8041940743680923270">सार्वत्रिक डीफॉल्‍ट वापरा (विचारा)</translation>
<translation id="8042918947222776840">पिकअप पद्धत निवडा</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" योग्य रीतीने कॉन्फिगर केलेले नाही. "<ph name="SOFTWARE_NAME" />" अनइंस्टॉल केल्याने सहसा समस्या सुटते. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">तुमचे डिव्हाइस यावर कॉन्फिगर केले गेले आहे:</translation>
+<translation id="8066955247577885446">सॉरी, काहीतरी चूक झाली.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">फिरवल्यावर भाष्य करू शकत नाही</translation>
<translation id="8079031581361219619">साइट रीलोड करायची?</translation>
<translation id="8088680233425245692">लेख पाहण्यात अयशस्वी.</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">सक्रियकरण सर्व्हरवर प्रलंबित आहे</translation>
<translation id="8092774999298748321">गडद जांभळा</translation>
<translation id="8094917007353911263">तुम्ही वापरत असलेल्या नेटवर्कला तुम्ही <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ला भेट देण्याची आवश्यकता आहे.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">चुकीची कार्डे काढून टाकण्यात आली आहेत</translation>
<translation id="8103161714697287722">पेमेंट पद्धत</translation>
<translation id="8118489163946903409">पेमेंट पद्धत</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> हे <ph name="ENROLLMENT_DOMAIN" /> द्वारे व्यवस्थापित केले आहे</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" तुमच्या काँप्युटरवर किंवा नेटवर्कवर योग्य रीतीने इंस्टॉल केले नव्हते. तुमच्या अ‍ॅडमिनिस्ट्रेटरला ही समस्या सोडवण्यास सांगा.</translation>
-<translation id="8130693978878176684">मी यापुढे मदत करू शकत नाही, कृपया तुम्ही स्वतःच सुरू ठेवा.</translation>
<translation id="8131740175452115882">पुष्टी करा</translation>
<translation id="8149426793427495338">तुमचा कॉंप्युटर निष्क्रीय झाला.</translation>
<translation id="8150722005171944719"><ph name="URL" /> येथील फाइल वाचनीय नाही. ती काढून टाकलेली, हलविलेली असू शकते किंवा फाइल परवानग्या प्रवेश प्रतिबंधित करत असू शकतात.</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">पेजचे भाषांतर करा</translation>
<translation id="8201077131113104583"><ph name="EXTENSION_ID" /> ID असलेल्या एक्स्टेंशनासाठी चुकीची अपडेट URL.</translation>
<translation id="8202097416529803614">ऑर्डर सारांश</translation>
+<translation id="8202370299023114387">विरोध</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">कनेक्शन सुरक्षित आहे</translation>
<translation id="8218327578424803826">नियुक्त केलेले स्थान:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</translation>
<translation id="8225771182978767009">ज्या व्यक्तीने हा कॉंप्युटर सेट केला त्या व्यक्तीने ही साइट अवरोधित करण्याचे निवडले आहे.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">पेज नवीन गुप्त टॅबमध्ये उघडा</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">सेव्ह केलेले सर्व पासवर्ड दाखवा</translation>
<translation id="8261506727792406068">हटवा</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> म्हणून साइन इन करीत आहे</translation>
+<translation id="8278457561961988242">हा ब्राउझर <ph name="ENROLLMENT_DOMAIN" /> द्वारे व्यवस्थापित केला आहे. तुमचा अ‍ॅडमिनिस्ट्रेटर तुमच्या ब्राउझरचे सेटअप रिमोट पद्धतीने बदलू शकतो. या डिव्हाइसवरील अ‍ॅक्टिव्हिटी कदाचित Chrome च्या बाहेर व्यवस्थापित केलेली असू शकते. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">साइन इन</translation>
<translation id="8288807391153049143">सर्टिफिकेट दाखवा</translation>
<translation id="8289355894181816810">याचा निश्चित अर्थ तुम्हाला माहिती नसल्यास आपल्या नेटवर्क प्रशासकाशी संपर्क साधा.</translation>
<translation id="8293206222192510085">बुकमार्क जोडा</translation>
<translation id="8294431847097064396">स्रोत</translation>
<translation id="8298115750975731693">तुम्ही वापरत असलेल्या (<ph name="WIFI_NAME" />) वाय-फाय ला तुम्ही <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ला भेट देण्याची आवश्यकता असू शकते.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">नेटवर्क कनेक्शनसह समस्या असल्यामुळे भाषांतर अयशस्वी झाला.</translation>
-<translation id="8311129316111205805">सेशन लोड करा</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> मधील प्रवेश नाकारला</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">तुम्हाला आपल्या सुरक्षिततेच्या जोखमी समजत असल्यास, धोकादायक प्रोग्राम काढले जाण्यापूर्वी तुम्ही <ph name="BEGIN_LINK" />या असुरक्षित साइटला भेट देऊ शकता<ph name="END_LINK" />.</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">नेटवर्क कॉन्फिगरेशन चुकीचे आहे आणि इंपोर्ट केले जाऊ शकत नाही.
अतिरिक्त तपशील:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">डिव्हाइस <ph name="ENROLLMENT_DOMAIN" /> ने व्‍यवस्‍थापित केले आहे</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">बदल करा</translation>
<translation id="8428213095426709021">सेटिंग्ज</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">कार्डधारकाचे नाव</translation>
<translation id="861775596732816396">आकार ४</translation>
<translation id="8620436878122366504">आपल्या पालकांनी अद्याप ती मंजूर केली नाही</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">या डिव्हाइसवर हे कार्ड सेव्‍ह करा</translation>
<translation id="8663226718884576429">ऑर्डर सारांश, <ph name="TOTAL_LABEL" />, आणखी तपशील</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, उत्तर, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">तुमचे <ph name="DOMAIN" /> चे कनेक्शन एंक्रिप्ट केलेले नाही.</translation>
<translation id="8718314106902482036">पेमेंट पूर्ण झाले नाही</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, शोध सूचना</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google सुरक्षित ब्राउझिंग ला <ph name="SITE" /> वर अलीकडे <ph name="BEGIN_LINK" />हानिकारक प्रोग्राम आढळले आहेत<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB डिव्हाइस</translation>
<translation id="8768895707659403558">तुमच्या सर्व डिव्हाइसवर तुमची कार्डे वापरण्यासाठी, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;पुन्हा करा हटवा</translation>
<translation id="8792621596287649091">तुम्ही तुमच्या Google <ph name="ORG_NAME" /> चा अॅक्सेस गमावू शकता किंवा तुमची संवेदनशील माहिती चोरीला जाऊ शकते. Chromium लगेच तुमचा पासवर्ड बदलण्याची शिफारस करत आहे.</translation>
<translation id="8800988563907321413">आपल्या जवळपासच्या सूचना येथे दिसतात</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">Google सह सामायिकरण</translation>
<translation id="8858065207712248076">जर तुम्ही तुमच्या <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> पासवर्डचा इतर साइटवर पुन्हा वापर केला असेल तर Chrome तुम्हाला तो रीसेट करण्याची शिफारस करतो.</translation>
<translation id="8866481888320382733">धोरण सेटिंग्ज विश्लेषित करताना एरर</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">अलीकडे बंद</translation>
<translation id="8874824191258364635">वैध कार्ड नंबर एंटर करा</translation>
<translation id="8891727572606052622">चुकीचे प्रॉक्सी मोड.</translation>
<translation id="8903921497873541725">झूम इन करा</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">तुम्ही तुमच्या Google खात्यात हे कार्ड सेव्ह करू इच्छिता?</translation>
<translation id="8932102934695377596">तुमचे घड्याळ मागे आहे</translation>
<translation id="893332455753468063">नाव जोडा</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">तुमच्या अ‍ॅडमिनिस्ट्रेटरने कस्टम रूट सर्टिफिकेट कॉन्फिगर केली आहेत, ज्यामुळे अ‍ॅडमिनिस्ट्रेटरला तुम्ही भेट देत असलेल्या वेबसाइटचे आशय पाहण्यास अनुमती मिळू शकते.</translation>
<translation id="8943282376843390568">लिंबू</translation>
<translation id="8957210676456822347">बंद पोर्टल प्राधिकृतता</translation>
+<translation id="8966619695390250636">तुम्हाला असे म्हणायचे होते काय?</translation>
<translation id="8968766641738584599">कार्ड सेव्ह करा</translation>
<translation id="8971063699422889582">सर्व्हरचे सर्टिफिकेट एक्स्पायर झाले आहे.</translation>
<translation id="8975012916872825179">फोन नंबर, ईमेल अॅड्रेस आणि शिपिंग पत्ते यांसारखी माहिती समाविष्ट आहे</translation>
<translation id="8978053250194585037">Google सुरक्षित ब्राउझिंगला <ph name="SITE" /> वर अलीकडे <ph name="BEGIN_LINK" />फिशिंग आढळले<ph name="END_LINK" />. तुम्हाला फसवण्यासाठी फिशिंग साइट दुसर्‍याच कुठल्यातरी वेबसाइट असल्याचे भासवतात.</translation>
<translation id="8983003182662520383">Google Pay वापरून पेमेंट पद्धती आणि पत्ते</translation>
<translation id="8987927404178983737">महिना</translation>
-<translation id="8988408250700415532">काहीतरी चूक झाली. तुम्ही वेबसाइटवर तुमची ऑर्डर पूर्ण करू शकता.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">पुढे असणार्‍या साइटमध्ये हानिकारक प्रोग्राम आहेत</translation>
<translation id="8997023839087525404">सर्व्हरने सर्टिफिकेट पारदर्शकता धोरणाचा वापर करून सार्वजनिकरत्या उघड न केलेले एक सर्टिफिकेट सादर केले. काही सर्टिफिकेट विश्वसनीय आहेत आणि हल्लेखोरांविरूद्ध संरक्षण करतात याची खात्री करण्‍यासाठी त्यांच्यासाठी ही एक आवश्यकता आहे.</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">साइटच्या सेटिंग्ज उघडा</translation>
<translation id="9020200922353704812">कार्ड बिलिंग पत्ता आवश्यक आहे</translation>
<translation id="9020542370529661692">हे पृष्ठ <ph name="TARGET_LANGUAGE" /> मध्ये भाषांतरित केले गेले आहे.</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(चुकीचे)</translation>
<translation id="9035022520814077154">सुरक्षितता एरर</translation>
<translation id="9038649477754266430">पेज अधिक जलदपणे लोड करण्यासाठी पूर्वानुमान सेवेचा वापर करा</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">इतिहासामधून <ph name="TEXT" /> शोध</translation>
<translation id="9069693763241529744">एक विस्ताराने ब्लॉक केलेले</translation>
<translation id="9076283476770535406">कदाचित तिच्यामध्ये प्रौढ सामग्री असू शकते</translation>
+<translation id="9076630408993835509">हा ब्राउझर कंपनी किंवा अन्य संस्थेद्वारे व्यवस्थापित केलेला नाही. या डिव्हाइसवरील अ‍ॅक्टिव्हिटी कदाचित Chrome च्या बाहेर व्यवस्थापित केलेली असू शकते. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">अधिक माहिती आवश्यक आहे</translation>
<translation id="9080712759204168376">मागणी सारांश</translation>
<translation id="9103872766612412690">तुमची माहिती संरक्षित करण्यासाठी <ph name="SITE" /> सामान्यतः एंक्रिप्शन वापरते. Chromium ने यावेळी <ph name="SITE" /> शी कनेक्‍ट करण्‍याचा प्रयत्न केला तेव्‍हा, वेबसाइटने असामान्य आणि अयोग्य क्रेडेंशियल परत पाठवले. एकतर आक्रमणकर्ता <ph name="SITE" /> असल्याची बतावणी करण्याचा प्रयत्न करतो तेव्‍हा किंवा वाय-फाय साइन इन स्क्रीनने कनेक्शनमध्ये व्यत्यय आणले तेव्‍हा हे घडू शकते. कोणत्याही डेटाची अदलाबदल करण्यापूर्वी Chromium ने कनेक्शन थांबवल्यामुळे तुमची माहिती अद्याप सुरक्षित आहे.</translation>
<translation id="9106062320799175032">बिलिंग पत्ता जोडा</translation>
-<translation id="9110718169272311511">Chrome मधील Google असिस्टंट स्क्रीनच्या तळाजवळ उपलब्ध आहे</translation>
<translation id="9114524666733003316">कार्डची निश्चिती करत आहे...</translation>
<translation id="9128870381267983090">नेटवर्कशी कनेक्ट करा</translation>
<translation id="9137013805542155359">मूळ दर्शवा</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;संपादित करा पूर्ववत करा</translation>
<translation id="9154194610265714752">अपडेट केलेले</translation>
<translation id="9157595877708044936">सेट अप करीत आहे...</translation>
+<translation id="9158625974267017556">C6 (Envelope)C6 (Envelope)</translation>
<translation id="9168814207360376865">तुम्ही पेमेंट पद्धती सेव्ह केल्या आहेत का हे तपासण्याची साइटला परवानगी द्या</translation>
<translation id="9169664750068251925">या साइटवर नेहमी अवरोधित करा</translation>
<translation id="9170848237812810038">&amp;पूर्ववत करा</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">इमेज</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">फॉर्म साफ करा</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">तुम्ही तुमच्या Google खात्याचा अॅक्सेस कदाचित गमवाल. Chromium आता तुमचा पासवर्ड बदलण्याची शिफारस करते. तुम्हाला साइन इन करण्यासाठी सांगितले जाऊ शकते.</translation>
<translation id="939736085109172342">नवीन फोल्‍डर</translation>
<translation id="945855313015696284">खालील माहिती तपासा आणि कोणतीही चुकीची कार्डे हटवा</translation>
<translation id="951104842009476243">स्वीकारली जाणारी डेबिट आणि प्रीपेड कार्डे</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> च्या सुरक्षितता धोरणानुसार ब्लॉक केले.</translation>
<translation id="962484866189421427">हा आशय काहीतरी दुसरे असण्याची बतावणी करणारी फसवी अॅप्स इंस्टॉल करण्याचा किंवा तुमचा माग ठेवण्यासाठी वापरला जाऊ शकणारा डेटा गोळा करण्याचा प्रयत्न करू शकतो. <ph name="BEGIN_LINK" />तरीही दाखवा<ph name="END_LINK" /></translation>
<translation id="969892804517981540">अधिकृत बिल्ड</translation>
<translation id="973773823069644502">वितरणाचा पत्ता जोडा</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">पेमेंट पद्धती</translation>
<translation id="985199708454569384">&lt;p&gt;जर तुमच्या कॉंप्युटर किंवा मोबाइल डिव्हाइसची तारीख आणि वेळ चुकीची असेल, तर तुम्हाला ही एरर दिसेल.&lt;/p&gt;
&lt;p&gt;या एररला घालवण्यासाठी, तुमच्या डिव्हाइसचे क्लॉक उघडा. वेळ आणि तारीख अचूक असल्याची खात्री करा.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">विकसक बिल्ड</translation>
<translation id="989988560359834682">पत्ता संपादित करा</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ms.xtb b/chromium/components/strings/components_strings_ms.xtb
index ada6cc9015f..ff4e0dc5818 100644
--- a/chromium/components/strings/components_strings_ms.xtb
+++ b/chromium/components/strings/components_strings_ms.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ms">
-<translation id="1005145902654145231">Gagal menamakan semula sesi itu.</translation>
<translation id="1008557486741366299">Bukan Sekarang</translation>
<translation id="1010200102790553230">Muatkan halaman kemudian</translation>
<translation id="1015730422737071372">Berikan butiran tambahan</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nama tidak diketahui</translation>
<translation id="1050038467049342496">Tutup apl lain</translation>
<translation id="1055184225775184556">&amp;Buat Asal Tambahkan</translation>
+<translation id="1056898198331236512">Amaran</translation>
<translation id="1058479211578257048">Menyimpan kad...</translation>
<translation id="10614374240317010">Tidak pernah disimpan</translation>
+<translation id="1062160989074299343">Prc10 (Sampul Surat)</translation>
<translation id="106701514854093668">Penanda Halaman Desktop</translation>
<translation id="1074497978438210769">Tidak selamat</translation>
<translation id="1080116354587839789">Muat ikut lebar</translation>
+<translation id="1086953900555227778">Indeks-5x8</translation>
<translation id="1088860948719068836">Tambahkan Nama pada Kad</translation>
<translation id="1089439967362294234">Tukar Kata Laluan</translation>
<translation id="109743633954054152">Urus kata laluan dalam tetapan Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Amaran mungkin biasa dipaparkan semasa tapak web mengemas kini keselamatannya. Ini akan diperbaik tidak lama lagi.</translation>
<translation id="1126551341858583091">Saiz pada storan setempat ialah <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache dasar OK</translation>
+<translation id="1131264053432022307">Imej yang Anda Salin</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Namakan semula</translation>
<translation id="1175364870820465910">&amp;Cetak...</translation>
<translation id="1181037720776840403">Alih keluar</translation>
<translation id="1197088940767939838">Oren</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Nama peranti anda</translation>
<translation id="124116460088058876">Lagi bahasa</translation>
<translation id="1250759482327835220">Untuk membayar dengan lebih cepat selepas ini, simpan kad, nama dan alamat pengebilan anda ke Akaun Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (disegerakkan)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variasi baris perintah</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="1314614906530272393">Sesi yang dipilih tidak wujud.</translation>
+<translation id="1320233736580025032">Prc1 (Sampul Surat)</translation>
+<translation id="132301787627749051">Cari imej papan keratan</translation>
<translation id="1323433172918577554">Tunjukkan Lagi</translation>
<translation id="132390688737681464">Simpan dan Lengkapkan Alamat</translation>
<translation id="1333989956347591814">Aktiviti anda <ph name="BEGIN_EMPHASIS" />mungkin masih boleh dilihat<ph name="END_EMPHASIS" /> oleh:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Alamat pengambilan</translation>
<translation id="1348198688976932919">Tapak yang akan disemak imbas mengandungi apl berbahaya</translation>
<translation id="1348779747280417563">Sahkan nama</translation>
+<translation id="1357195169723583938">Orang yang menggunakan peranti ini baru-baru ini dan masa penggunaan</translation>
+<translation id="1364822246244961190">Dasar ini disekat, nilainya akan diabaikan.</translation>
<translation id="1374468813861204354">cadangan</translation>
+<translation id="1374692235857187091">Indeks-4x6 (Poskad)</translation>
<translation id="1375198122581997741">Mengenai Versi</translation>
<translation id="1376836354785490390">Tunjukkan Kurang</translation>
<translation id="1377321085342047638">Nombor Kad</translation>
<translation id="138218114945450791">Biru Cerah</translation>
+<translation id="1382194467192730611">Peranti USB yang dibenarkan oleh pentadbir anda</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> tidak menghantar sebarang data.</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> tapak ini telah meminta agar dasar keselamatan dikenakan pada semua permintaannya, dan pada masa ini dasar ini menganggap tapak ini sebagai tidak selamat.</translation>
<translation id="1405567553485452995">Hijau Cerah</translation>
<translation id="1407135791313364759">Buka semua</translation>
<translation id="1413809658975081374">Ralat privasi</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Ya</translation>
<translation id="1430915738399379752">Cetak</translation>
<translation id="1455413310270022028">Pemadam</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Tunjukkan lagi</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Pilih Alamat Pengiriman</translation>
+<translation id="1492194039220927094">Penolakan dasar:</translation>
<translation id="1501859676467574491">Tunjukkan kad daripada Akaun Google anda</translation>
-<translation id="1506687042165942984">Tunjukkan salinan yang disimpan (iaitu diketahui telah lapuk) bagi halaman ini.</translation>
<translation id="1507202001669085618">&lt;p&gt;Anda akan melihat ralat ini jika menggunakan portal Wi-Fi yang menghendaki anda untuk log masuk sebelum boleh masuk dalam talian.&lt;/p&gt;
&lt;p&gt;Untuk membetulkan ralat itu, klik &lt;strong&gt;Sambung&lt;/strong&gt; pada halaman yang cuba dibuka.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Nombor telefon diperlukan</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Tarikh Bina</translation>
<translation id="1521655867290435174">Helaian Google</translation>
<translation id="1527263332363067270">Menunggu sambungan...</translation>
+<translation id="1529521330346880926">10x15 (Sampul Surat)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Halaman ini menyatakan</translation>
<translation id="153384715582417236">Itu sahaja buat masa ini</translation>
<translation id="154408704832528245">Pilih Alamat Penghantaran</translation>
<translation id="1549470594296187301">Javascript mesti didayakan untuk menggunakan ciri ini.</translation>
+<translation id="155039086686388498">Kejuruteraan-D</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="1569487616857761740">Masukkan tarikh tamat tempoh</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imej yang anda salin</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Halang halaman ini daripada mencipta dialog tambahan</translation>
+<translation id="16338877384480380">Seni Bina-B</translation>
<translation id="1634051627998691300">Tamatkan sesi</translation>
<translation id="1639239467298939599">Memuatkan</translation>
<translation id="1640180200866533862">Dasar pengguna</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">Sijil pelayan mengandungi kunci kriptografi yang lemah.</translation>
<translation id="1697532407822776718">Anda telah bersedia!</translation>
+<translation id="1703835215927279855">Surat</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokumen terlalu besar untuk dianotasikan</translation>
<translation id="1721312023322545264">Anda memerlukan kebenaran daripada <ph name="NAME" /> untuk melawat tapak ini</translation>
<translation id="1721424275792716183">* Medan perlu diisi</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Cuba hubungi pentadbir sistem.</translation>
<translation id="1740951997222943430">Masukkan bulan tamat tempoh yang sah</translation>
<translation id="1743520634839655729">Untuk membayar dengan lebih cepat selepas ini, simpan kad, nama dan alamat pengebilan anda ke Akaun Google dan ke peranti ini.</translation>
+<translation id="1745880797583122200">Penyemak imbas anda diurus</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Sila kemas kini frasa laluan segerak anda.</translation>
<translation id="1787142507584202372">Tab yang dibuka dipaparkan di sini</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nama Pemegang Kad</translation>
<translation id="1821930232296380041">Permintaan atau parameter permintaan tidak sah</translation>
+<translation id="1822540298136254167">Tapak web yang anda lawati dan tempoh anda melayarinya</translation>
<translation id="1826516787628120939">Menyemak</translation>
<translation id="1834321415901700177">Tapak ini mengandungi atur cara berbahaya</translation>
<translation id="1839551713262164453">Pengesahan nilai dasar gagal dengan ralat</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Kosongkan data sejarah penyemakan imbas Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{dan 1 lagi}other{dan # lagi}}</translation>
<translation id="2003709556000175978">Tetapkan semula kata laluan anda sekarang</translation>
+<translation id="20053308747750172">Pelayan destinasi anda, <ph name="ORIGIN" />, telah meminta agar dasar keselamatan dikenakan pada semua permintaan yang diterimanya. Akan tetapi kini pelayan tersebut telah menyampaikan dasar yang tidak sah, yang menghalang penyemak imbas daripada memenuhi permintaan anda untuk <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proksi ditetapkan kepada auto konfigurasi.</translation>
<translation id="2030481566774242610">Adakah anda maksudkan <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Menyemak proksi dan tembok api<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Jabatan</translation>
<translation id="2102134110707549001">Cadangkan Kata Laluan Yang Kukuh…</translation>
<translation id="2108755909498034140">Mulakan semula komputer anda</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kad</translation>
<translation id="2114841414352855701">Diabaikan kerana ia telah diatasi oleh <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Penanda Halaman Mudah Alih</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (Sampul Surat)</translation>
<translation id="2181821976797666341">Dasar</translation>
<translation id="2183608646556468874">Nombor Telefon</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 alamat}other{# alamat}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Nombor telefon</translation>
<translation id="2283340219607151381">Simpan dan lengkapkan alamat</translation>
<translation id="2292556288342944218">Akses Internet anda disekat</translation>
+<translation id="2294558542833290837">Pautan yang anda buka pada asalnya luar daripada kebiasaan</translation>
+<translation id="2297722699537546652">B5 (Sampul Surat)</translation>
+<translation id="2310021320168182093">Chou2 (Sampul Surat)</translation>
<translation id="2316887270356262533">Mengosongkan kurang daripada 1 MB. Sesetengah tapak mungkin dimuatkan dengan lebih perlahan pada lawatan anda yang seterusnya.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> memerlukan nama pengguna dan kata laluan.</translation>
<translation id="2317583587496011522">Kad debit diterima.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, tamat tempoh pada <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Tetapan dikawal oleh pentadbir anda</translation>
+<translation id="2346319942568447007">Imej yang anda salin</translation>
<translation id="2349790679044093737">Sesi VR aktif</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>
@@ -239,29 +266,35 @@
<translation id="2365563543831475020">Laporan ranap sistem yang dirakam pada <ph name="CRASH_TIME" /> tidak dimuat naik</translation>
<translation id="2367567093518048410">Tahap</translation>
<translation id="2378238891085281592">Anda menggunakan mod peribadi</translation>
+<translation id="2380886658946992094">Perundangan</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="2410754574180102685">Kerajaan-Perundangan</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="2418081434543109369">Pelayan destinasi anda, <ph name="ORIGIN" />, telah meminta agar
+ dasar keselamatan dikenakan pada semua permintaan yang diterimanya. Akan tetapi kini pelayan itu gagal menyampaikan dasar, yang menghalang penyemak imbas daripada memenuhi permintaan anda untuk <ph name="SITE" />.</translation>
<translation id="244665789865330679">Peranti dan akaun anda diurus oleh <ph name="ENROLLMENT_DOMAIN" />. Ini bermakna pentadbir anda boleh mengkonfigurasikan peranti dan akaun anda dari jauh.</translation>
<translation id="2463193859425327265">Tukar Halaman Utama</translation>
<translation id="2463739503403862330">Isi</translation>
+<translation id="2465402087343596252">Seni Bina-E</translation>
<translation id="2465655957518002998">Pilih Kaedah Penghantaran</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Jalankan Diagnostik Rangkaian<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Terjemahkan halaman ini</translation>
<translation id="2479410451996844060">URL carian tidak sah.</translation>
<translation id="2482878487686419369">Pemberitahuan</translation>
<translation id="248348093745724435">Dasar mesin</translation>
+<translation id="2485387744899240041">Nama pengguna bagi peranti dan penyemak imbas anda</translation>
<translation id="2491120439723279231">Sijil pelayan mengandungi ralat.</translation>
+<translation id="2493640343870896922">Surat-Plus</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>
<translation id="2498091847651709837">Imbas kad baharu</translation>
<translation id="2501278716633472235">Kembali</translation>
<translation id="2503184589641749290">Kad debit dan prabayar yang diterima</translation>
<translation id="2515629240566999685">Semak isyarat di kawasan anda</translation>
-<translation id="2516852381693169964">Cari Imej di <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Disimpan pada peranti ini sahaja</translation>
<translation id="2524461107774643265">Tambahkan Maklumat Lanjut</translation>
<translation id="2536110899380797252">Tambahkan Alamat</translation>
@@ -273,6 +306,7 @@
<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="2618023639789766142">C10 (Sampul Surat)</translation>
<translation id="2625385379895617796">Jam anda lebih awal</translation>
<translation id="2634124572758952069">Alamat IP pelayan <ph name="HOST_NAME" /> tidak ditemui.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +316,9 @@
<translation id="2666117266261740852">Tutup tab atau apl lain</translation>
<translation id="267371737713284912">tekan <ph name="MODIFIER_KEY_DESCRIPTION" /> untuk buat asal</translation>
<translation id="2674170444375937751">Adakah anda pasti anda mahu memadamkan halaman ini daripada sejarah anda?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Tinggalkan</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Kad yang Diterima</translation>
<translation id="2702801445560668637">Senarai Bacaan</translation>
<translation id="2704283930420550640">Nilai tidak sepadan dengan format.</translation>
@@ -299,7 +335,6 @@
<translation id="2742870351467570537">Buang item yang dipilih</translation>
<translation id="277133753123645258">Kaedah penghantaran</translation>
<translation id="277499241957683684">Tiada rekod peranti</translation>
-<translation id="2781030394888168909">Eksport MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Sambungan ditetapkan semula.</translation>
<translation id="2788784517760473862">Kad kredit yang diterima</translation>
@@ -311,8 +346,10 @@
<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="2847118875340931228">Buka Tetingkap Inkognito</translation>
+<translation id="2850739647070081192">Jemputan (Sampul Surat)</translation>
<translation id="2851634818064021665">Anda memerlukan kebenaran untuk melawat tapak ini</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Simpan kad?</translation>
<translation id="2903493209154104877">Alamat</translation>
<translation id="290376772003165898">Halaman bukan dalam <ph name="LANGUAGE" />?</translation>
@@ -322,6 +359,7 @@
<translation id="2925673989565098301">Kaedah Penghantaran</translation>
<translation id="2928905813689894207">Alamat Pengebilan</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Surat-Kerajaan</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>
@@ -338,11 +376,14 @@
<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="3023071826883856138">You4 (Sampul Surat)</translation>
<translation id="3024663005179499861">Jenis dasar salah</translation>
<translation id="3037605927509011580">Oh, Tidak!</translation>
<translation id="3041612393474885105">Maklumat Sijil</translation>
+<translation id="3060227939791841287">C9 (Sampul Surat)</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="3095940652251934233">Kenyataan</translation>
<translation id="3096100844101284527">Tambahkan Alamat Pengambilan</translation>
<translation id="3105172416063519923">ID Aset:</translation>
<translation id="3109728660330352905">Anda tidak mempunyai kebenaran untuk melihat halaman ini.</translation>
@@ -364,20 +405,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> pada <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Batal Pembayaran</translation>
<translation id="3207960819495026254">Ditandai halaman</translation>
-<translation id="3209375525920864198">Sila masukkan nama sesi yang sah.</translation>
+<translation id="321912867715453276">Amaran: Lebih daripada satu sumber terdapat dalam dasar ini, tetapi nilainya sama.</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="3229041911291329567">Maklumat versi tentang peranti dan penyemak imbas anda</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Tambahkan nama pada kad</translation>
<translation id="3287510313208355388">Muat turun semasa dalam talian</translation>
<translation id="3293642807462928945">Ketahui lebih lanjut tentang dasar <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Tiada hasil carian ditemui</translation>
-<translation id="3305707030755673451">Data anda disulitkan dengan ungkapan laluan segerak anda pada <ph name="TIME" />. Masukkannya untuk memulakan penyegerakan.</translation>
<translation id="3320021301628644560">Tambahkan alamat pengebilan</translation>
<translation id="3324983252691184275">Merah lembayung</translation>
<translation id="3338095232262050444">Selamat</translation>
@@ -405,9 +447,11 @@
<translation id="3427342743765426898">&amp;Buat Semula Edit</translation>
<translation id="342781501876943858">Chromium mengesyorkan penetapan semula kata laluan jika anda menggunakan semula kata laluan itu di tapak lain.</translation>
<translation id="3431636764301398940">Simpan kad ini pada peranti ini</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Pemilik peranti ini telah mematikan permainan dinosaur.</translation>
<translation id="3447884698081792621">Tunjukkan sijil (yang dikeluarkan oleh <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Selang masa ambil:</translation>
+<translation id="3456231139987291353">Number-11 (Sampul Surat)</translation>
<translation id="3461824795358126837">Penyerlah</translation>
<translation id="3462200631372590220">Menyembunyikan butiran</translation>
<translation id="3467763166455606212">Nama pemegang kad diperlukan</translation>
@@ -430,21 +474,24 @@
<translation id="358285529439630156">Kad kredit dan prabayar diterima.</translation>
<translation id="3582930987043644930">Tambah nama</translation>
<translation id="3583757800736429874">&amp;Buat Semula Pindahkan</translation>
+<translation id="35866233670761917">Kandungan tapak web yang anda lawati tidak dilihat oleh pentadbir anda</translation>
<translation id="3586931643579894722">Sembunyikan butiran</translation>
+<translation id="3592413004129370115">Itali (Sampul Surat)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Saiz 2</translation>
<translation id="3615877443314183785">Masukkan tarikh tamat tempoh yang sah</translation>
<translation id="36224234498066874">Kosongkan Data Semakan Imbas...</translation>
<translation id="362276910939193118">Paparkan Sejarah Penuh</translation>
-<translation id="3623476034248543066">Tunjukkan nilai</translation>
<translation id="3630155396527302611">Jika apl telah disenaraikan sebagai atur cara yang dibenarkan untuk mengakses
rangkaian, cuba alihkannya keluar daripada senarai dan tambahkannya  
semula.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Pengesahan berjaya</translation>
<translation id="3655670868607891010">Jika anda kerap melihatnya, cuba <ph name="HELP_LINK" /> ini.</translation>
<translation id="3658742229777143148">Semakan</translation>
<translation id="366077651725703012">Kemas Kini Kad Kredit</translation>
<translation id="3676592649209844519">ID peranti:</translation>
+<translation id="3677008721441257057">Adakah anda maksudkan &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Permintaan tidak dapat ditandatangani</translation>
<translation id="3678529606614285348">Buka halaman dalam tetingkap Inkognito baharu (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Laporan ranap sistem dirakam pada <ph name="CRASH_TIME" />, dimuat naik pada <ph name="UPLOAD_TIME" /></translation>
@@ -452,13 +499,14 @@
<translation id="3704162925118123524">Rangkaian yang anda gunakan mungkin memerlukan anda untuk melawat halaman log masuknya.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Memuatkan...</translation>
+<translation id="3709599264800900598">Teks yang Anda Salin</translation>
<translation id="3712624925041724820">Kehabisan lesen</translation>
<translation id="3714780639079136834">Menghidupkan data mudah alih atau Wi-Fi</translation>
<translation id="3715597595485130451">Sambung ke Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Menyemak proksi, tembok api dan konfigurasi DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Aplikasi yang boleh menyebabkan ralat ini termasuk antivirus, tembok api dan perisian penapisan web atau proksi.</translation>
+<translation id="373042150751172459">B4 (Sampul Surat)</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="3745099705178523657">Setelah anda membuat pengesahan, butiran kad daripada Akaun Google anda akan dikongsi dengan tapak ini.</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>
@@ -471,10 +519,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Tamat tempoh pada <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Saiz 16</translation>
+<translation id="3797522431967816232">Prc3 (Sampul Surat)</translation>
<translation id="3807873520724684969">Kandungan berbahaya disekat.</translation>
<translation id="3810973564298564668">Urus</translation>
<translation id="382518646247711829">Jika anda menggunakan pelayan proksi...</translation>
<translation id="3828924085048779000">Kosongkan frasa laluan adalah tidak dibenarkan.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> telah memasang sambungan bagi fungsi tambahan. Sambungan mempunyai akses kepada sesetengah data anda.</translation>
<translation id="385051799172605136">Kembali</translation>
<translation id="3858027520442213535">Kemas kini tarikh dan masa</translation>
<translation id="3884278016824448484">Pengecam peranti bercanggah</translation>
@@ -482,6 +532,7 @@
<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="3906600011954732550">B5-Ekstra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Sentiasa tanya pada tapak ini</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>
@@ -492,11 +543,13 @@
<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="3984550557525787191">Nama sesi ini sudah wujud.</translation>
<translation id="3987940399970879459">Kurang daripada 1 MB</translation>
+<translation id="4008849406247176967">Amaran: Lebih daripada satu sumber yang mempunyai nilai yang bercanggah terdapat dalam dasar ini!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 halaman web berdekatan}other{# halaman web berdekatan}}</translation>
<translation id="4030383055268325496">&amp;Buat asal tambahkan</translation>
+<translation id="4032320456957708163">Penyemak imbas anda diurus oleh <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Kekunci "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Sampul Surat)</translation>
<translation id="4067947977115446013">Tambahkan Alamat yang Sah</translation>
<translation id="4072486802667267160">Ralat berlaku semasa memproses pesanan anda. Sila cuba lagi.</translation>
<translation id="4075732493274867456">Pelanggan dan pelayan tidak menyokong versi protokol SSL atau set sifer biasa.</translation>
@@ -516,10 +569,12 @@
<translation id="4159784952369912983">Ungu</translation>
<translation id="4165986682804962316">Tetapan tapak</translation>
<translation id="4171400957073367226">Tandatangan pengesahan tidak sah</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> lagi item}other{<ph name="ITEM_COUNT" /> lagi item}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Sampul Surat)</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="4221630205957821124">&lt;h4&gt;Langkah 1: Log masuk ke portal&lt;/h4&gt;
@@ -551,58 +606,79 @@
<translation id="4277028893293644418">Tetapkan semula kata laluan</translation>
<translation id="4280429058323657511">, tamat tempoh <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Kad ini telah disimpan ke Akaun Google anda}other{Kad ini telah disimpan ke Akaun Google anda}}</translation>
+<translation id="42981349822642051">Kembangkan</translation>
+<translation id="4302965934281694568">Chou3 (Sampul Surat)</translation>
<translation id="4305817255990598646">Tukar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Sekat (lalai)</translation>
+<translation id="4318566738941496689">Nama dan alamat rangkaian peranti anda</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="4340982228985273705">Komputer ini tidak dikesan sebagai diurus perusahaan, jadi dasar hanya boleh memasang secara automatik sambungan yang dihoskan di Gedung Web Chrome. URL kemas kini Gedung Web Chrome ialah "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Kad Kredit yang Diterima</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Urus kaedah pembayaran...</translation>
+<translation id="4367563149485757821">Number-12 (Sampul Surat)</translation>
+<translation id="4372516964750095882">Fanfold-AS</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">hasil carian</translation>
-<translation id="4406972042435603828">Pentadbir anda telah memasang sambungan yang mempunyai keupayaan yang kuat.</translation>
<translation id="4408413947728134509">Kuki <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Alamat Pengambilan</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="443121186588148776">Port siri</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> tidak menerima sijil log masuk anda atau sijil log masuk mungkin tidak diberikan.</translation>
<translation id="4434045419905280838">Tetingkap timbul dan ubah hala</translation>
+<translation id="4435702339979719576">Poskad)</translation>
<translation id="443673843213245140">Penggunaan proksi dilumpuhkan tetapi konfigurasi proksi yang jelas dinyatakan.</translation>
<translation id="445100540951337728">Kad debit yang diterima</translation>
+<translation id="4466881336512663640">Perubahan borang akan hilang. Adakah anda pasti mahu meneruskan?</translation>
<translation id="4482953324121162758">Tapak ini tidak akan diterjemah.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL tidak sah. Mestilah URL dengan skema standard, mis http://example.com atau https://example.com.</translation>
+<translation id="4503882053543859973">Seni Bina-D</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="4510487217173779431">Chou4 (Sampul Surat)</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="4517607026994743406">Comm-10 (Sampul Surat)</translation>
<translation id="4522570452068850558">Butiran</translation>
<translation id="4524805452350978254">Urus kad</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Cuba lumpuhkan sambungan anda.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Penghantaran</translation>
+<translation id="4579056131138995126">Peribadi (Sampul Surat)</translation>
<translation id="4582204425268416675">Alih keluar kad</translation>
<translation id="4587425331216688090">Alih keluar alamat daripada Chrome?</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="4597348597567598915">Saiz 8</translation>
+<translation id="4600854749408232102">C6/C5 (Sampul Surat)</translation>
<translation id="4646534391647090355">Bawa saya ke sana sekarang</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="467809019005607715">Slaid Google</translation>
<translation id="4690462567478992370">Berhenti menggunakan sijil tidak sah</translation>
+<translation id="4691835149146451662">Seni Bina-A (Sampul Surat)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Sambungan anda tergendala</translation>
<translation id="471880041731876836">Anda tiada kebenaran untuk melawat tapak ini</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Jalankan Diagnostik Rangkaian Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Muat semula dasar</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Sampul Surat)</translation>
<translation id="4736825316280949806">Mulakan semula Chromium</translation>
<translation id="473775607612524610">Kemas kini</translation>
<translation id="4738601419177586157">Cadangan carian <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Urus kata laluan…</translation>
<translation id="4744603770635761495">Laluan Boleh Laku</translation>
+<translation id="4746351372139058112">Mesej</translation>
<translation id="4750917950439032686">Maklumat anda (contohnya, kata laluan atau nombor kad kredit) adalah berciri peribadi apabila dihantar ke tapak ini.</translation>
<translation id="4756388243121344051">&amp;Sejarah</translation>
<translation id="4758311279753947758">Tambahkan maklumat hubungan</translation>
@@ -610,9 +686,9 @@
<translation id="4764776831041365478">Laman web di <ph name="URL" /> mungkin tergendala buat sementara waktu atau ia mungkin dpindahkan secara kekal ke alamat web baharu.</translation>
<translation id="4771973620359291008">Ralat tidak diketahui telah berlaku.</translation>
<translation id="4785689107224900852">Beralih ke tab ini</translation>
-<translation id="4792143361752574037">Terdapat masalah untuk mengakses fail sesi. Penyimpanan pada cakera dilumpuhkan pada masa ini. Sila muat semula halaman untuk mencuba lagi.</translation>
<translation id="4798078619018708837">Masukkan tarikh tamat tempoh dan CVC <ph name="CREDIT_CARD" /> untuk mengemas kini butiran kad anda. Setelah anda mengesahkan maklumat, butiran kad daripada Akaun Google anda akan dikongsi dengan tapak ini.</translation>
<translation id="4800132727771399293">Semak tarikh tamat tempoh serta CVC anda dan cuba lagi</translation>
+<translation id="480334179571489655">Ralat Dasar Asal</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>
@@ -627,7 +703,6 @@
<translation id="4881695831933465202">Buka</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>
@@ -636,15 +711,15 @@
<translation id="4943872375798546930">Tiada hasil carian</translation>
<translation id="4950898438188848926">Butang peralihan tab, tekan Enter untuk beralih ke tab yang terbuka, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Tindakan</translation>
-<translation id="495832697253704892">Pelaporan sambungan</translation>
+<translation id="4955242332710481440">A5-Ekstra</translation>
<translation id="4958444002117714549">Kembangkan senarai</translation>
<translation id="4974590756084640048">Dayakan semula amaran</translation>
+<translation id="4984339528288761049">Prc5 (Sampul Surat)</translation>
<translation id="4989163558385430922">Lihat semua</translation>
<translation id="4989809363548539747">Pemalam ini tidak disokong</translation>
-<translation id="4996230189582812866">Pelaporan</translation>
<translation id="5002932099480077015">Jika didayakan, Chrome akan menyimpan salinan kad anda pada peranti ini untuk pengisian borang yang lebih cepat.</translation>
-<translation id="5014174725590676422">Google Assistant dalam skrin pelaksanaan pertama Chrome dipaparkan</translation>
<translation id="5015510746216210676">Nama Mesin:</translation>
+<translation id="5017554619425969104">Teks yang anda salin</translation>
<translation id="5018422839182700155">Tidak dapat membuka halaman ini</translation>
<translation id="5019198164206649151">Simpanan penyandaran dalam keadaan buruk</translation>
<translation id="5023310440958281426">Semak dasar pentadbir anda</translation>
@@ -654,35 +729,51 @@
<translation id="5034369478845443529">Konteks Setempat <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Benarkan</translation>
<translation id="5040262127954254034">Privasi</translation>
+<translation id="5043480802608081735">Pautan yang Anda Salin</translation>
<translation id="5045550434625856497">Kata laluan tidak sah</translation>
<translation id="5056549851600133418">Artikel untuk anda</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Menyemak alamat proksi<ph name="END_LINK" /></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="5097099694988056070">Statistik peranti seperti penggunaan CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Peranti anda diurus oleh <ph name="ENROLLMENT_DOMAIN" /> dan akaun anda diurus oleh <ph name="ACCOUNT_DOMAIN" />. Ini bermakna pentadbir anda boleh mengkonfigurasikan peranti dan akaun anda dari jauh.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">Edp-Eropah</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">Sesi dengan nama ini tidak sah untuk pemadaman.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Urus alamat...</translation>
+<translation id="5138227688689900538">Tunjukkan kurang</translation>
<translation id="5141240743006678641">Sulitkan kata laluan yang disegerakkan dengan bukti kelayakan Google anda</translation>
<translation id="5145883236150621069">Terdapat kod ralat dalam balasan dasar</translation>
+<translation id="515292512908731282">C4 (Sampul Surat)</translation>
<translation id="5159010409087891077">Buka halaman dalam tetingkap Inkognito baharu (⇧⌘N)</translation>
<translation id="516920405563544094">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah anda mengesahkan maklumat, butiran kad daripada Akaun Google anda akan dikongsi dengan tapak ini.</translation>
<translation id="5169827969064885044">Anda boleh kehilangan akses kepada akaun organisasi anda atau mengalami kecurian identiti. Chrome mengesyorkan supaya kata laluan anda ditukar sekarang.</translation>
<translation id="5171045022955879922">Buat carian atau taipkan URL</translation>
+<translation id="5171689220826475070">Fanfold-Eropah</translation>
<translation id="5172758083709347301">Mesin</translation>
<translation id="5179510805599951267">Bukan dalam <ph name="ORIGINAL_LANGUAGE" />? Laporkan ralat ini</translation>
<translation id="5190835502935405962">Bar Penanda Halaman</translation>
-<translation id="5200263511887412697">laporkan senarai pengguna peranti yang telah log masuk baru-baru ini</translation>
+<translation id="519422657042045905">Anotasi tidak tersedia</translation>
<translation id="5201306358585911203">Halaman terbenam pada halaman ini menyatakan</translation>
<translation id="5205222826937269299">Nama diperlukan</translation>
<translation id="5215116848420601511">Kaedah pembayaran dan alamat yang menggunakan Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-mel diperlukan</translation>
<translation id="5230733896359313003">Alamat Penghantaran</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Sambung kepada rangkaian"</translation>
<translation id="5251803541071282808">Awan</translation>
+<translation id="5252000469029418751">C7 (Sampul Surat)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Alamat rangkaian</translation>
<translation id="5285570108065881030">Tunjukkan semua kata laluan yang disimpan</translation>
<translation id="5287240709317226393">Tunjukkan kuki</translation>
<translation id="5288108484102287882">Pengesahan nilai dasar telah menimbulkan amaran</translation>
@@ -694,7 +785,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> daripada <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Pilih Maklumat Hubungan</translation>
<translation id="5327248766486351172">Nama</translation>
+<translation id="5329858041417644019">Penyemak imbas anda tidak diurus</translation>
<translation id="5332219387342487447">Kaedah Penghantaran</translation>
+<translation id="5334013548165032829">Log sistem terperinci</translation>
<translation id="5344579389779391559">Halaman ini mungkin cuba mengenakan bayaran kepada anda</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>
@@ -702,6 +795,7 @@
<translation id="5377026284221673050">"Jam anda lambat" atau "Jam anda cepat" atau "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Untuk menggunakan kad anda pada semua peranti, log masuk dan hidupkan penyegerakan.</translation>
<translation id="5386426401304769735">Rantaian sijil untuk tapak ini mengandungi sijil yang ditandatangani menggunakan SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -712,6 +806,7 @@
<translation id="5457113250005438886">Tidak sah</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Buat semula edit</translation>
+<translation id="5478437291406423475">B6/C4 (Sampul Surat)</translation>
<translation id="5481076368049295676">Kandungan ini mungkin cuba memasang perisian berbahaya pada peranti anda yang mencuri atau memadamkan maklumat anda. <ph name="BEGIN_LINK" />Tunjukkan juga<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Tambahkan alamat yang sah</translation>
<translation id="5490432419156082418">Alamat dan Pelbagai Lagi</translation>
@@ -719,10 +814,12 @@
<ph name="LINE_BREAK" />
Cuba hubungi pentadbir sistem anda.</translation>
<translation id="549333378215107354">Saiz 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Penanda halaman terurus</translation>
<translation id="5510766032865166053">Fail mungkin telah dipindahkan atau dipadamkan.</translation>
<translation id="5523118979700054094">Nama dasar</translation>
<translation id="552553974213252141">Adakah teks diekstrak dengan betul?</translation>
+<translation id="553484882784876924">Prc6 (Sampul Surat)</translation>
<translation id="5540224163453853">Tidak menemui artikel yang diminta.</translation>
<translation id="5541546772353173584">Tambahkan E-mel</translation>
<translation id="5545756402275714221">Artikel untuk Anda</translation>
@@ -737,15 +834,21 @@
<translation id="5595485650161345191">Edit alamat</translation>
<translation id="5598944008576757369">Pilih Kaedah Pembayaran</translation>
<translation id="560412284261940334">Pengurusan tidak disokong</translation>
+<translation id="5605670050355397069">Lejar</translation>
+<translation id="5607240918979444548">Seni Bina-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> telah terlalu kerap mengubah hala anda.</translation>
<translation id="5629630648637658800">Gagal memuatkan tetapan dasar</translation>
<translation id="5631439013527180824">Token pengurusan peranti tidak sah</translation>
+<translation id="5632627355679805402">Data anda disulitkan dengan <ph name="BEGIN_LINK" />kata laluan Google<ph name="END_LINK" /> anda pada <ph name="TIME" />. Masukkan kata laluan itu untuk memulakan penyegerakan.</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="563324245173044180">Kandungan mengelirukan disekat.</translation>
<translation id="5659593005791499971">E-mel</translation>
+<translation id="5663614846592581799">9x11 (Sampul Surat)</translation>
+<translation id="5663955426505430495">Pentadbir peranti ini telah memasang sambungan bagi fungsi tambahan. Sambungan mempunyai akses kepada sesetengah data anda.</translation>
<translation id="5675650730144413517">Halaman ini tidak berfungsi</translation>
+<translation id="5684874026226664614">Op. Halaman ini tidak dapat diterjemahkan.</translation>
<translation id="5685654322157854305">Tambahkan Alamat Penghantaran</translation>
<translation id="5689199277474810259">Eksport ke JSON</translation>
<translation id="5689516760719285838">Lokasi</translation>
@@ -754,38 +857,39 @@
<translation id="5710435578057952990">Identiti tapak web ini belum disahkan.</translation>
<translation id="5719499550583120431">Kad prabayar diterima.</translation>
<translation id="5720705177508910913">Pengguna semasa</translation>
+<translation id="5728056243719941842">C5 (Sampul Surat)</translation>
<translation id="5730040223043577876">Chrome mengesyorkan penetapan semula kata laluan jika anda menggunakan semula kata laluan itu di tapak lain.</translation>
<translation id="5732392974455271431">Ibu bapa anda boleh menyahsekatnya untuk anda</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Simpan kad ke Akaun Google anda}other{Simpan kad ke Akaun Google 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="5770114862687765385">Fail tersebut kelihatan rosak. Klik butang 'Tetapkan semula' untuk menetapkan semula sesi.</translation>
<translation id="5778550464785688721">Kawalan penuh peranti MIDI</translation>
<translation id="578305955206182703">Kuning jingga</translation>
<translation id="57838592816432529">Redam</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>
+<translation id="5798290721819630480">Buang perubahan?</translation>
<translation id="5798683403665926540">Tukar halaman utama dalam tetapan Chrome</translation>
<translation id="5803412860119678065">Adakah anda ingin mengisi <ph name="CARD_DETAIL" /> anda?</translation>
<translation id="5804241973901381774">Kebenaran</translation>
<translation id="5810442152076338065">Sambungan anda ke <ph name="DOMAIN" /> disulitkan menggunakan suit sifer yang sudah usang.</translation>
<translation id="5813119285467412249">&amp;Buat Semula Tambahkan</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="5860033963881614850">Dimatikan</translation>
<translation id="5863847714970149516">Halaman yang seterusnya mungkin cuba mengenakan bayaran kepada anda</translation>
<translation id="5866257070973731571">Tambahkan Nombor Telefon</translation>
<translation id="5869405914158311789">Tapak ini tidak dapat dicapai</translation>
<translation id="5869522115854928033">Kata laluan disimpan</translation>
<translation id="5887400589839399685">Kad disimpan</translation>
-<translation id="5893718151540690985">laporkan senarai antara muka rangkaian bersama jenis dan alamat perkakasannya</translation>
<translation id="5893752035575986141">Kad kredit diterima.</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="5916664084637901428">Hidupkan</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Simpan kad ke Akaun Google?</translation>
<translation id="5922853866070715753">Hampir selesai</translation>
<translation id="5932224571077948991">Tapak menyiarkan iklan yang mengganggu atau mengelirukan</translation>
-<translation id="5939518447894949180">Tetapkan semula</translation>
<translation id="5946937721014915347">Membuka <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Tidak dapat mendaftar dengan akaun pengguna (lesen berpakej tersedia).</translation>
<translation id="5967592137238574583">Edit Maklumat Hubungan</translation>
@@ -793,6 +897,7 @@
<translation id="5975083100439434680">Zum keluar</translation>
<translation id="5977489021191000276">Peranti anda tidak diurus oleh pentadbir.</translation>
<translation id="5977976211062815271">Pada peranti ini</translation>
+<translation id="5980920751713728343">Indeks-3x5</translation>
<translation id="598637245381783098">Tidak dapat membuka apl pembayaran</translation>
<translation id="5989320800837274978">Pelayan proksi tetap begitu juga URL skrip .pac, kedua-duanya tidak ditetapkan.</translation>
<translation id="5990559369517809815">Permintaan pada pelayan telah disekat oleh sambungan.</translation>
@@ -803,8 +908,8 @@
<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="6033927989869462158">laporkan statistik perkakasan seperti penggunaan CPU/RAM</translation>
<translation id="6034000775414344507">Kelabu Cerah</translation>
+<translation id="6034283069659657473">10x14 (Sampul Surat)</translation>
<translation id="6039846035001940113">Jika masalah berterusan, hubungi pemilik tapak.</translation>
<translation id="6040143037577758943">Tutup</translation>
<translation id="6044573915096792553">Saiz 12</translation>
@@ -813,10 +918,10 @@
<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="6058977677006700226">Gunakan kad anda pada semua peranti anda?</translation>
<translation id="6059925163896151826">Peranti USB</translation>
-<translation id="6071091556643036997">Jenis dasar tidak sah.</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="6094273045989040137">Anotasi</translation>
<translation id="610911394827799129">Akaun Google anda mungkin mempunyai bentuk sejarah penyemakan imbas yang lain di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Maklumat tentang sambungan dan pemalam yang dipasang</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>
@@ -851,15 +956,21 @@
<translation id="6337133576188860026">Mengosongkan kurang daripada <ph name="SIZE" />. Sesetengah tapak mungkin dimuatkan dengan lebih perlahan pada lawatan anda yang seterusnya.</translation>
<translation id="6337534724793800597">Tapis dasar mengikut nama</translation>
<translation id="6358450015545214790">Apakah maksudnya?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Caj mungkin dikenakan nanti.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 cadangan lain}other{# cadangan lain}}</translation>
<translation id="6387754724289022810">Untuk membayar dengan lebih cepat selepas ini, simpan kad dan alamat pengebilan anda ke Akaun Google dan ke peranti ini.</translation>
+<translation id="6390662030813198813">Kejuruteraan-E</translation>
<translation id="6404511346730675251">Edit penanda halaman</translation>
+<translation id="6406765186087300643">C0 (Sampul Surat)</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="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="6434309073475700221">Buang</translation>
+<translation id="6446163441502663861">Kahu (Sampul Surat)</translation>
<translation id="6446608382365791566">Tambahkan maklumat lanjut</translation>
<translation id="6447842834002726250">Kuki</translation>
<translation id="6451458296329894277">Sahkan Penyerahan Semula Borang</translation>
@@ -872,11 +983,17 @@
<translation id="6508722015517270189">Mulakan semula Chrome</translation>
<translation id="6529602333819889595">&amp;Buat Semula Pemadaman</translation>
<translation id="6534179046333460208">Cadangan Web Fizikal</translation>
+<translation id="6556866813142980365">Buat semula</translation>
<translation id="6563469144985748109">Pengurus anda belum meluluskannya</translation>
<translation id="6569060085658103619">Anda sedang melihat halaman sambungan</translation>
+<translation id="6578796323535178455">C2 (Sampul Surat)</translation>
<translation id="6579990219486187401">Merah Jambu Cerah</translation>
+<translation id="6583674473685352014">B6 (Sampul Surat)</translation>
+<translation id="6587923378399804057">Pautan yang anda salin</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> anda tidak diurus</translation>
<translation id="6596325263575161958">Pilihan penyulitan</translation>
<translation id="6604181099783169992">Penderia Gerakan atau Cahaya</translation>
+<translation id="6609880536175561541">Prc7 (Sampul Surat)</translation>
<translation id="6624427990725312378">Maklumat Hubungan</translation>
<translation id="6626291197371920147">Tambahkan nombor kad yang sah</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Carian</translation>
@@ -885,6 +1002,7 @@
<translation id="6644283850729428850">Dasar ini telah dikecam.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Tiada}=1{Daripada 1 tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}other{Daripada # tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}}</translation>
<translation id="6657585470893396449">Kata laluan</translation>
+<translation id="6670613747977017428">Kembali ke keselamatan.</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>
@@ -892,12 +1010,15 @@
<translation id="671076103358959139">Token Pendaftaran:</translation>
<translation id="6711464428925977395">Ada sesuatu yang tidak kena dengan pelayan proksi atau alamat tidak betul.</translation>
<translation id="6723740634201835758">Dalam Akaun Google anda</translation>
+<translation id="6738516213925468394">Data anda disulitkan dengan <ph name="BEGIN_LINK" />ungkapan laluan segerak<ph name="END_LINK" /> anda pada <ph name="TIME" />. Masukkannya untuk memulakan penyegerakan.</translation>
<translation id="674375294223700098">Ralat sijil pelayan tidak diketahui.</translation>
<translation id="6744009308914054259">Sementara menunggu sambungan, anda boleh melawati Muat turun untuk membaca artikel luar talian.</translation>
<translation id="6753269504797312559">Nilai dasar</translation>
<translation id="6757797048963528358">Peranti anda tidak aktif.</translation>
+<translation id="6768213884286397650">Hagaki (Poskad)</translation>
<translation id="6778737459546443941">Ibu bapa anda belum meluluskannya</translation>
<translation id="67862343314499040">Ungu Lembayung</translation>
+<translation id="6786747875388722282">Pelanjutan</translation>
<translation id="679355240208270552">Diabaikan kerana carian lalai tidak didayakan oleh dasar.</translation>
<translation id="681021252041861472">Medan Diperlukan</translation>
<translation id="6810899417690483278">ID Penyesuaian</translation>
@@ -930,10 +1051,12 @@
<translation id="6965978654500191972">Peranti</translation>
<translation id="6970216967273061347">Daerah</translation>
<translation id="6973656660372572881">Pelayan proksi tetap dan juga URL skrip .pac tidak ditetapkan.</translation>
+<translation id="6973932557599545801">Maaf, saya tidak dapat membantu. Sila teruskan sendiri.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Redam (lalai)</translation>
<translation id="6984479912851154518">Meninggalkan mod peribadi untuk membayar melalui aplikasi luar. Teruskan?</translation>
<translation id="6989763994942163495">Paparkan tetapan lanjutan...</translation>
+<translation id="6993898126790112050">6x9 (Sampul Surat)</translation>
<translation id="6996312675313362352">Sentiasa terjemahkan <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Caj ini mungkin caj sekali atau caj berulang dan mungkin tidak ketara.</translation>
@@ -949,28 +1072,33 @@
<translation id="7108338896283013870">Sembunyikan</translation>
<translation id="7108819624672055576">Dibenarkan oleh sambungan</translation>
<translation id="7111012039238467737">(Sah)</translation>
+<translation id="7118618213916969306">Cari URL papan keratan, <ph name="SHORT_URL" /></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="7135130955892390533">Tunjukkan status</translation>
<translation id="7138472120740807366">Kaedah penghantaran</translation>
<translation id="7139724024395191329">Amiriah</translation>
+<translation id="7152423860607593928">Number-14 (Sampul Surat)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Gandaria</translation>
-<translation id="7158980942472052083">URL tidak sah. Mestilah URL dengan skema standard.</translation>
<translation id="717330890047184534">ID Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Pelayan destinasi anda, <ph name="ORIGIN" />, telah meminta agar dasar keselamatan dikenakan pada semua permintaan yang diterimanya. Pelayan itu sepatutnya menyampaikan dasar tersebut, tetapi sebaliknya telah mengubah hala penyemak imbas ke tempat lain, yang menghalang penyemak imbas daripada memenuhi permintaan anda untuk <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Simpan dan Lengkapkan Kaedah Pembayaran</translation>
<translation id="7180611975245234373">Muat semula</translation>
<translation id="7182878459783632708">Tiada dasar ditetapkan</translation>
<translation id="7186367841673660872">Halaman ini telah diterjemahkan dari<ph name="ORIGINAL_LANGUAGE" />ke<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Mengosongkan <ph name="SIZE" />. Sesetengah tapak mungkin dimuatkan dengan perlahan pada lawatan anda yang seterusnya.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Pentadbir anda dapat melihat:</translation>
+<translation id="7202346780273620635">Surat-Ekstra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> tidak mematuhi piawaian keselamatan.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /> mengenai masalah ini.</translation>
<translation id="7219179957768738017">Sambungan menggunakan <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Memproses</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Tapak di hadapan mengandungi perisian hasad</translation>
+<translation id="724766306220616965">Amaran, Konflik</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="7251437084390964440">Konfigurasi rangkaian tidak mematuhi standard ONC. Sebahagian konfigurasi tidak boleh diimport.
Butiran tambahan:
@@ -983,11 +1111,14 @@ Butiran tambahan:
<translation id="7300012071106347854">Biru Kobalt</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Amaran <ph name="BEGIN_LINK" />Penyemakan Imbas Selamat<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Bantuan Sambungan</translation>
<translation id="7334320624316649418">&amp;Buat semula susun semula</translation>
<translation id="733923710415886693">Sijil pelayan tidak didedahkan melalui Ketelusan Sijil.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Ekstra</translation>
<translation id="7353601530677266744">Baris Perintah</translation>
-<translation id="7365061714576910172">Eksport Linux</translation>
<translation id="7372973238305370288">hasil carian</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Tidak</translation>
@@ -995,6 +1126,7 @@ Butiran tambahan:
<translation id="7381288752349550461">Pembatalan sesi terurus</translation>
<translation id="7390545607259442187">Sahkan Kad</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> anda diurus</translation>
<translation id="7407424307057130981">&lt;p&gt;Anda akan melihat ralat ini jika anda memasang perisian Superfish pada komputer Windows anda.&lt;/p&gt;
&lt;p&gt;Ikut langkah berikut untuk melumpuhkan perisian itu buat sementara waktu supaya anda dapat mengakses web. Anda memerlukan hak keistimewaan pentadbir.&lt;/p&gt;
&lt;ol&gt;
@@ -1005,7 +1137,7 @@ Butiran tambahan:
&lt;li&gt;Klik &lt;strong&gt;Apply&lt;/strong&gt;, kemudian klik &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Lawati &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Pusat bantuan Chrome&lt;/a&gt; untuk mengetahui cara mengalih keluar perisian itu daripada komputer anda secara kekal
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Pengurusan <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Format-Lebar</translation>
<translation id="7416351320495623771">Urus Kata Laluan…</translation>
<translation id="7419106976560586862">Laluan Profil</translation>
<translation id="7437289804838430631">Tambahkan Maklumat Hubungan</translation>
@@ -1014,22 +1146,24 @@ Butiran tambahan:
<translation id="7442725080345379071">Jingga Cerah</translation>
<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="7449109375006139765">hantar log sistem ke pelayan pengurusan</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="7460618730930299168">Tayangan ini berbeza daripada pilihan anda. Teruskan?</translation>
<translation id="7473891865547856676">Tidak, Terima Kasih</translation>
-<translation id="7475525192983021547">laporkan tempoh masa apabila pengguna aktif pada peranti</translation>
<translation id="7481312909269577407">Majukan</translation>
<translation id="7485870689360869515">Tiada data dijumpai.</translation>
+<translation id="7498234416455752244">Teruskan mengedit</translation>
<translation id="7508255263130623398">Id peranti yang dikembalikan kosong atau tidak sepadan dengan id peranti semasa</translation>
<translation id="7508870219247277067">Hijau Avokado</translation>
<translation id="7511955381719512146">Wi-Fi yang anda gunakan mungkin memerlukan anda untuk melawat <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Muat Turun</translation>
<translation id="7518003948725431193">Tiada halaman web dijumpai untuk alamat web: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Sampul Surat)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Sambungan anda ke tapak ini tidak berciri peribadi</translation>
+<translation id="7535087603100972091">Nilai</translation>
<translation id="7537536606612762813">Wajib</translation>
+<translation id="7538364083937897561">A2 (Sampul Surat)</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>
@@ -1038,8 +1172,8 @@ Butiran tambahan:
<translation id="7552846755917812628">Cuba petua berikut:</translation>
<translation id="7554791636758816595">Tab Baharu</translation>
<translation id="7564049878696755256">Anda boleh kehilangan akses kepada akaun <ph name="ORG_NAME" /> anda atau mengalami kecurian identiti. Chrome mengesyorkan supaya kata laluan anda ditukar sekarang.</translation>
-<translation id="7566125604157659769">Teks yang anda salin</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="7568105740864181217">Penyemak imbas ini diurus oleh syarikat, sekolah atau organisasi lain. Pentadbir anda boleh menukar persediaan penyemak imbas anda dari jauh. Aktiviti pada peranti ini mungkin turut diurus di luar Chrome. <ph name="BEGIN_LINK" />Ketahui Lebih Lanjut<ph name="END_LINK" /></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>
@@ -1050,6 +1184,7 @@ Butiran tambahan:
<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="7633909222644580952">Data prestasi dan laporan ranap sistem</translation>
<translation id="7637571805876720304">Alih keluar kad kredit daripada Chromium?</translation>
<translation id="7639968568612851608">Kelabu Gelap</translation>
<translation id="765676359832457558">Sembunyikan tetapan lanjutan...</translation>
@@ -1059,9 +1194,11 @@ Butiran tambahan:
<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="7676643023259824263">Cari teks papan keratan, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Tukar Enjin Carian</translation>
<translation id="7682287625158474539">Penghantaran</translation>
<translation id="7687186412095877299">Mengisi borang pembayaran dengan kaedah pembayaran yang disimpan</translation>
+<translation id="7697066736081121494">Prc8 (Sampul Surat)</translation>
<translation id="769721561045429135">Sekarang, anda mempunyai kad yang boleh digunakan pada peranti ini sahaja. Klik Teruskan untuk menyemak kad.</translation>
<translation id="7699293099605015246">Artikel tidak tersedia sekarang</translation>
<translation id="7701040980221191251">Tiada</translation>
@@ -1073,11 +1210,13 @@ Butiran tambahan:
<translation id="774634243536837715">Kandungan berbahaya disekat.</translation>
<translation id="7752995774971033316">Tidak Diurus</translation>
<translation id="7755287808199759310">Ibu bapa anda boleh menyahsekatnya untuk anda</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Tembok api atau perisian antivirus mungkin telah menyekat sambungan.</translation>
<translation id="7759163816903619567">Domain paparan:</translation>
<translation id="7761701407923456692">Sijil pelayan tidak sepadan dengan URL.</translation>
<translation id="7763386264682878361">Penghurai Manifes Bayaran</translation>
<translation id="7764225426217299476">Tambahkan alamat</translation>
+<translation id="7770259615151589601">Panjang-Ditetapkan</translation>
<translation id="777702478322588152">Wilayah</translation>
<translation id="7791543448312431591">Tambah</translation>
<translation id="7793809570500803535">Halaman web di <ph name="SITE" /> mungkin tergendala buat sementara waktu atau ia mungkin dpindahkan secara kekal ke alamat web baharu.</translation>
@@ -1089,8 +1228,8 @@ Butiran tambahan:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Alih keluar cadangan borang daripada Chrome?</translation>
<translation id="7815407501681723534">Menemui <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> untuk '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Pengurusan dasar</translation>
<translation id="782886543891417279">Wi-Fi yang anda gunakan (<ph name="WIFI_NAME" />) mungkin memerlukan anda melawat halaman log masuknya.</translation>
+<translation id="7836231406687464395">Postfix (Sampul Surat)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Tiada}=1{1 apl (<ph name="EXAMPLE_APP_1" />)}=2{2 apl (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# apl (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Walau bagaimanapun, anda tidak halimunan. Apabila anda menggunakan mod inkognito, penyemakan imbas anda tidak akan disembunyikan daripada majikan anda, penyedia perkhidmatan Internet anda atau tapak web yang anda lawati.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1099,7 +1238,7 @@ Butiran tambahan:
<translation id="7878562273885520351">Kata laluan anda mungkin terjejas</translation>
<translation id="7882421473871500483">Coklat</translation>
<translation id="7887683347370398519">Semak CVC anda dan cuba lagi</translation>
-<translation id="7893255318348328562">Nama sesi</translation>
+<translation id="7904208859782148177">C3 (Sampul Surat)</translation>
<translation id="79338296614623784">Masukkan nombor telefon yang sah</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Tamat tempoh pada <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1109,21 +1248,25 @@ Butiran tambahan:
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Penanda halaman mudah alih</translation>
<translation id="7961015016161918242">Tidak sama sekali</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Tidak Ditentukan</translation>
<translation id="800218591365569300">Cuba tutup tab atau atur cara lain untuk mengosongkan memori.</translation>
+<translation id="8004582292198964060">Penyemak Imbas</translation>
<translation id="8009225694047762179">Urus Kata Laluan</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Kad ini dan alamat pengebilannya akan disimpan. Anda akan dapat menggunakan kad ini apabila anda log masuk ke <ph name="USER_EMAIL" />.}other{Kad ini dan alamat pengebilannya akan disimpan. Anda akan dapat menggunakan kad ini apabila anda log masuk ke <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Halaman ini dalam <ph name="SOURCE_LANGUAGE" />. Terjemahkannya kepada <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pen</translation>
+<translation id="8037117624646282037">Orang yang menggunakan peranti ini baru-baru ini</translation>
<translation id="8037357227543935929">Tanya (lalai)</translation>
<translation id="803771048473350947">Fail</translation>
<translation id="8041089156583427627">Hantar Maklum Balas</translation>
<translation id="8041940743680923270">Gunakan lalai global (Tanya)</translation>
<translation id="8042918947222776840">Pilih Kaedah Pengambilan</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" tidak dikonfigurasi dengan betul. Tindakan menyahpasang "<ph name="SOFTWARE_NAME" />" biasanya dapat menyelesaikan masalah ini. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Peranti anda telah dikonfigurasikan kepada:</translation>
+<translation id="8066955247577885446">Maaf, kesilapan telah berlaku.</translation>
+<translation id="8074253406171541171">10x13 (Sampul Surat)</translation>
<translation id="8078141288243656252">Tidak boleh melakukan anotasi apabila diputarkan</translation>
<translation id="8079031581361219619">Muatkan semula tapak?</translation>
<translation id="8088680233425245692">Gagal melihat artikel.</translation>
@@ -1132,11 +1275,12 @@ Butiran tambahan:
<translation id="8091372947890762290">Pengaktifan belum selesai pada pelayan</translation>
<translation id="8092774999298748321">Ungu Tua</translation>
<translation id="8094917007353911263">Rangkaian yang anda gunakan mungkin memerlukan anda melawat <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Kad tidak sah telah dialih keluar</translation>
<translation id="8103161714697287722">Kaedah Pembayaran</translation>
<translation id="8118489163946903409">Kaedah pembayaran</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> diurus oleh <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" tidak dipasang dengan betul pada komputer atau rangkaian anda. Minta pentadbir IT anda menyelesaikan isu ini.</translation>
-<translation id="8130693978878176684">Saya tidak dapat membantu lagi, sila teruskan sendiri.</translation>
<translation id="8131740175452115882">Sahkan</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>
@@ -1146,8 +1290,11 @@ Butiran tambahan:
<translation id="8197543752516192074">Terjemah Halaman</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="8202370299023114387">Konflik</translation>
+<translation id="8206978196348664717">Prc4 (Sampul Surat)</translation>
<translation id="8211406090763984747">Sambungan selamat</translation>
<translation id="8218327578424803826">Lokasi yang Ditentukan:</translation>
+<translation id="8220146938470311105">C7/C6 (Sampul Surat)</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="8238581221633243064">Buka halaman dalam tab Inkognito baharu</translation>
@@ -1159,14 +1306,16 @@ Butiran tambahan:
<translation id="825929999321470778">Tunjukkan Semua Kata Laluan yang Disimpan</translation>
<translation id="8261506727792406068">Padam</translation>
<translation id="8267698848189296333">Log masuk sebagai <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Penyemak imbas ini diurus oleh <ph name="ENROLLMENT_DOMAIN" />. Pentadbir anda boleh menukar persediaan penyemak imbas anda dari jauh. Aktiviti pada peranti ini mungkin turut diurus di luar Chrome. <ph name="BEGIN_LINK" />Ketahui Lebih Lanjut<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Foto-Besar</translation>
<translation id="8286036467436129157">Log Masuk</translation>
<translation id="8288807391153049143">Tunjukkan sijil</translation>
<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="8298115750975731693">Wi-Fi yang anda gunakan (<ph name="WIFI_NAME" />) mungkin memerlukan anda untuk melawat <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Foto-Kecil</translation>
<translation id="8308427013383895095">Gagal terjemahan kerana masalah dengan sambungan rangkaian.</translation>
-<translation id="8311129316111205805">Muatkan sesi</translation>
<translation id="8332188693563227489">Akses ke <ph name="HOST_NAME" /> dinafikan</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1184,7 +1333,6 @@ Butiran tambahan:
<translation id="8416694386774425977">Konfigurasi rangkaian tidak sah dan tidak boleh diimport.
Butiran tambahan:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Peranti diurus oleh <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Tukar</translation>
<translation id="8428213095426709021">Tetapan</translation>
@@ -1212,9 +1360,11 @@ Butiran tambahan:
<translation id="860043288473659153">Nama pemegang kad</translation>
<translation id="861775596732816396">Saiz 4</translation>
<translation id="8620436878122366504">Ibu bapa anda belum meluluskannya</translation>
+<translation id="8622948367223941507">Perundangan-Ekstra</translation>
<translation id="8625384913736129811">Simpan Kad Ini pada Peranti Ini</translation>
<translation id="8663226718884576429">Ringkasan Pesanan, <ph name="TOTAL_LABEL" />, Butiran Lanjut</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, jawapan, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Sambungan anda ke <ph name="DOMAIN" /> tidak disulitkan.</translation>
<translation id="8718314106902482036">Pembayaran belum selesai</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, cadangan carian</translation>
@@ -1228,6 +1378,7 @@ Butiran tambahan:
<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="8763927697961133303">Peranti USB</translation>
<translation id="8768895707659403558">Untuk menggunakan kad pada semua peranti anda, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Buat semula pemadaman</translation>
<translation id="8792621596287649091">Anda boleh kehilangan akses kepada akaun <ph name="ORG_NAME" /> anda atau mengalami kecurian identiti. Chromium mengesyorkan supaya kata laluan anda ditukar sekarang.</translation>
<translation id="8800988563907321413">Cadangan berdekatan anda dipaparkan di sini</translation>
@@ -1238,10 +1389,12 @@ Butiran tambahan:
<translation id="885730110891505394">Berkongsi dengan Google</translation>
<translation id="8858065207712248076">Chrome mengesyorkan penetapan semula kata laluan <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> jika anda menggunakan semula kata laluan itu di tapak lain.</translation>
<translation id="8866481888320382733">Ralat semasa menghuraikan tetapan dasar</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Ditutup Baru-baru Ini</translation>
<translation id="8874824191258364635">Masukkan nombor kad yang sah</translation>
<translation id="8891727572606052622">Mod proksi tidak sah.</translation>
<translation id="8903921497873541725">Zum masuk</translation>
+<translation id="890485472659500557">Kejuruteraan-C</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="893332455753468063">Tambahkan Nama</translation>
@@ -1249,13 +1402,13 @@ Butiran tambahan:
<translation id="894185898663964645">Pentadbir anda telah mengkonfigurasikan sijil akar tersuai, yang mungkin membolehkan pentadbir anda melihat kandungan tapak web yang anda lawati.</translation>
<translation id="8943282376843390568">Hijau pucuk pisang</translation>
<translation id="8957210676456822347">Keizinan Portal Tawanan</translation>
+<translation id="8966619695390250636">Adakah anda maksudkan?</translation>
<translation id="8968766641738584599">Simpan kad</translation>
<translation id="8971063699422889582">Sijil pelayan telah tamat tempoh.</translation>
<translation id="8975012916872825179">Merangkumi maklumat seperti nombor telefon, alamat e-mel dan alamat penghantaran</translation>
<translation id="8978053250194585037">Penyemakan Imbas Selamat Google <ph name="BEGIN_LINK" />mengesan pancingan data<ph name="END_LINK" /> di <ph name="SITE" /> baru-baru ini. Tapak pancingan data menyamar sebagai tapak web lain untuk menipu anda.</translation>
<translation id="8983003182662520383">Kaedah Pembayaran dan Alamat yang Menggunakan Google Pay</translation>
<translation id="8987927404178983737">Bulan</translation>
-<translation id="8988408250700415532">Kesilapan telah berlaku, Anda boleh menyelesaikan pesanan anda di tapak web.</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>
@@ -1265,6 +1418,7 @@ Butiran tambahan:
<translation id="9011424611726486705">Buka tetapan tapak</translation>
<translation id="9020200922353704812">Alamat pengebilan kad diperlukan</translation>
<translation id="9020542370529661692">Halaman ini telah diterjemahkan kepada <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Tidak sah)</translation>
<translation id="9035022520814077154">Ralat keselamatan</translation>
<translation id="9038649477754266430">Gunakan perkhidmatan ramalan untuk memuatkan halaman lebih cepat</translation>
@@ -1276,11 +1430,11 @@ Butiran tambahan:
<translation id="9065745800631924235">Carian <ph name="TEXT" /> daripada sejarah</translation>
<translation id="9069693763241529744">Disekat oleh sambungan</translation>
<translation id="9076283476770535406">Tapak mungkin mengandungi kandungan dewasa</translation>
+<translation id="9076630408993835509">Penyemak imbas ini tidak diurus oleh syarikat atau organisasi lain. Aktiviti pada peranti ini mungkin diurus di luar Chrome. <ph name="BEGIN_LINK" />Ketahui Lebih Lanjut<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Maklumat lanjut diperlukan</translation>
<translation id="9080712759204168376">Ringkasan Pesanan</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>
<translation id="9106062320799175032">Tambahkan Alamat Pengebilan</translation>
-<translation id="9110718169272311511">Google Assistant dalam Chrome tersedia berhampiran bahagian bawah skrin</translation>
<translation id="9114524666733003316">Mengesahkan kad...</translation>
<translation id="9128870381267983090">Sambung ke rangkaian</translation>
<translation id="9137013805542155359">Paparkan asal</translation>
@@ -1289,6 +1443,7 @@ Butiran tambahan:
<translation id="9148507642005240123">&amp;Buat asal edit</translation>
<translation id="9154194610265714752">Dikemas kini</translation>
<translation id="9157595877708044936">Menyediakan...</translation>
+<translation id="9158625974267017556">C6 (Sampul Surat)</translation>
<translation id="9168814207360376865">Benarkan tapak menyemak sama ada anda mempunyai kaedah pembayaran yang disimpan</translation>
<translation id="9169664750068251925">Sentiasa sekat di tapak ini</translation>
<translation id="9170848237812810038">&amp;Buat asal</translation>
@@ -1303,10 +1458,12 @@ Butiran tambahan:
<translation id="9219103736887031265">Imej</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">KOSONGKAN BORANG</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Anda mungkin akan kehilangan akses kepada Akaun Google anda. Chromium mengesyorkan supaya anda menukar kata laluan sekarang. Anda akan diminta untuk log masuk.</translation>
<translation id="939736085109172342">Folder baharu</translation>
<translation id="945855313015696284">Semak maklumat di bawah dan padamkan sebarang kad yang tidak sah</translation>
<translation id="951104842009476243">Kad Debit dan Prabayar yang Diterima</translation>
+<translation id="958202389743790697">Disekat menurut dasar keselamatan <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Kandungan ini mungkin cuba memasang apl mengelirukan yang berpura-pura menjadi sesuatu yang lain atau mengumpulkan data yang mungkin digunakan untuk menjejak anda. <ph name="BEGIN_LINK" />Tunjukkan juga <ph name="END_LINK" /></translation>
<translation id="969892804517981540">Binaan Rasmi</translation>
<translation id="973773823069644502">Tambahkan Alamat Penghantaran</translation>
@@ -1315,6 +1472,7 @@ Butiran tambahan:
<translation id="984275831282074731">Kaedah pembayaran</translation>
<translation id="985199708454569384">&lt;p&gt;Anda akan melihat ralat ini jika tarikh dan masa komputer atau peranti mudah alih anda tidak tepat.&lt;/p&gt;
&lt;p&gt;Untuk membetulkan ralat ini, buka jam peranti anda. Pastikan masa dan tarikh adalah betul.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Binaan Pemaju</translation>
<translation id="989988560359834682">Edit Alamat</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_nl.xtb b/chromium/components/strings/components_strings_nl.xtb
index fa352da3e78..ff28b45c050 100644
--- a/chromium/components/strings/components_strings_nl.xtb
+++ b/chromium/components/strings/components_strings_nl.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="nl">
-<translation id="1005145902654145231">De naam van de sessie wijzigen is mislukt.</translation>
<translation id="1008557486741366299">Niet nu</translation>
<translation id="1010200102790553230">Pagina later laden</translation>
<translation id="1015730422737071372">Aanvullende gegevens verzenden</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">onbekende naam</translation>
<translation id="1050038467049342496">Andere apps sluiten</translation>
<translation id="1055184225775184556">&amp;Toevoegen ongedaan maken</translation>
+<translation id="1056898198331236512">Waarschuwing</translation>
<translation id="1058479211578257048">Passen opslaan...</translation>
<translation id="10614374240317010">Nooit opgeslagen</translation>
+<translation id="1062160989074299343">Prc10 (envelop)</translation>
<translation id="106701514854093668">Desktopbladwijzers</translation>
<translation id="1074497978438210769">Niet beveiligd</translation>
<translation id="1080116354587839789">Aanpassen aan breedte</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Naam op pas toevoegen</translation>
<translation id="1089439967362294234">Wachtwoord wijzigen</translation>
<translation id="109743633954054152">Wachtwoorden beheren in de Chrome-instellingen</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Wanneer de beveiliging van websites wordt geüpdatet, worden vaak waarschuwingen weergegeven. Dit wordt binnenkort verbeterd.</translation>
<translation id="1126551341858583091">De grootte in de lokale opslag is <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cachegeheugen van beleid is OK</translation>
+<translation id="1131264053432022307">Afbeelding die je hebt gekopieerd</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Naam wijzigen</translation>
<translation id="1175364870820465910">&amp;Afdrukken...</translation>
<translation id="1181037720776840403">Verwijderen</translation>
<translation id="1197088940767939838">Oranje</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">De naam van je apparaat</translation>
<translation id="124116460088058876">Meer talen</translation>
<translation id="1250759482327835220">Sla je pas, naam en factuuradres op in je Google-account zodat je de volgende keer sneller kunt betalen.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (gesynchroniseerd)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Opdrachtregelvarianten</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="1314614906530272393">De geselecteerde sessie bestaat niet.</translation>
+<translation id="1320233736580025032">Prc1 (envelop)</translation>
+<translation id="132301787627749051">Zoeken naar klembordafbeelding</translation>
<translation id="1323433172918577554">Meer weergeven</translation>
<translation id="132390688737681464">Adressen opslaan en invullen</translation>
<translation id="1333989956347591814">Je activiteit is mogelijk <ph name="BEGIN_EMPHASIS" />nog wel zichtbaar<ph name="END_EMPHASIS" /> voor:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Ophaaladres</translation>
<translation id="1348198688976932919">De volgende site bevat gevaarlijke apps</translation>
<translation id="1348779747280417563">Naam bevestigen</translation>
+<translation id="1357195169723583938">Wie het apparaat recent heeft gebruikt en wanneer</translation>
+<translation id="1364822246244961190">Dit beleid is geblokkeerd. De waarde ervan wordt genegeerd.</translation>
<translation id="1374468813861204354">suggesties</translation>
+<translation id="1374692235857187091">Index-4x6 (briefkaart)</translation>
<translation id="1375198122581997741">Over deze versie</translation>
<translation id="1376836354785490390">Minder weergeven</translation>
<translation id="1377321085342047638">Kaartnummer</translation>
<translation id="138218114945450791">Lichtblauw</translation>
+<translation id="1382194467192730611">USB-apparaat toegestaan door je beheerder</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> heeft geen gegevens verzonden.</translation>
+<translation id="140316286225361634">De site <ph name="ORIGIN" /> heeft gevraagd een beveiligingsbeleid toe te passen op alle verzoeken van de site en dit beleid beschouwt de site momenteel als onveilig.</translation>
<translation id="1405567553485452995">Lichtgroen</translation>
<translation id="1407135791313364759">Alles openen</translation>
<translation id="1413809658975081374">Privacyfout</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Afdrukken</translation>
<translation id="1455413310270022028">Gum</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Meer weergeven</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Verzendadres kiezen</translation>
+<translation id="1492194039220927094">Pushen van beleid:</translation>
<translation id="1501859676467574491">Passen uit je Google-account weergeven</translation>
-<translation id="1506687042165942984">Een opgeslagen (verouderde) kopie van deze pagina weergeven.</translation>
<translation id="1507202001669085618">&lt;p&gt;J​e ​zi​et​ d​ez​e ​fo​ut​ a​ls​ j​e ​ee​n ​wi​fi​-p​or​ta​l ​ge​br​ui​kt​ w​aa​ro​p ​je​ m​oe​t ​in​lo​gg​en​ v​oo​rd​at​ j​e ​on​li​ne​ k​un​t ​ga​an​.&lt;/p&gt;
&lt;p&gt;​K​li​k ​op​ &lt;​st​ro​ng​&gt;V​er​bi​nd​in​g ​ma​ke​n&lt;​/s​tr​on​g&gt;​ o​p ​de​ p​ag​in​a ​di​e ​je​ p​ro​be​er​t ​te​ o​pe​ne​n ​om​ d​ez​e ​fo​ut​ o​p ​te​ l​os​se​n.​&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefoonnummer vereist</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Datum van build</translation>
<translation id="1521655867290435174">Google Spreadsheets</translation>
<translation id="1527263332363067270">Wachten op verbinding...</translation>
+<translation id="1529521330346880926">10x15 (envelop)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Deze pagina meldt het volgende</translation>
<translation id="153384715582417236">Dat is voorlopig alles</translation>
<translation id="154408704832528245">Afleveradres kiezen</translation>
<translation id="1549470594296187301">JavaScript moet zijn ingeschakeld om deze functie te kunnen gebruiken.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Vervaldatum invoeren</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Afbeelding die je hebt gekopieerd</translation>
<translation id="1620510694547887537">Camera</translation>
<translation id="1623104350909869708">Voorkomen dat deze pagina extra dialoogvensters weergeeft</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Sessie beëindigen</translation>
<translation id="1639239467298939599">Laden</translation>
<translation id="1640180200866533862">Gebruikersbeleid</translation>
@@ -133,8 +148,10 @@
<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 beveiligd omdat Google Chrome de verbinding heeft beëindigd voordat er gegevens konden worden uitgewisseld.</translation>
<translation id="168841957122794586">Het servercertificaat bevat een zwakke cryptografische sleutel.</translation>
<translation id="1697532407822776718">Je bent nu klaar!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Document is te groot om aantekeningen te maken</translation>
<translation id="1721312023322545264">Je hebt toestemming van <ph name="NAME" /> nodig om deze site te bezoeken</translation>
<translation id="1721424275792716183">* Verplicht veld</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Probeer contact op te nemen met de systeembeheerder.</translation>
<translation id="1740951997222943430">Geef een geldige vervalmaand op</translation>
<translation id="1743520634839655729">Sla je pas, naam en factuuradres op in je Google-account en op dit apparaat zodat je de volgende keer sneller kunt betalen.</translation>
+<translation id="1745880797583122200">Je browser wordt beheerd</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Update je wachtwoordzin voor synchronisatie.</translation>
<translation id="1787142507584202372">Je geopende tabbladen worden hier weergegeven</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Naam kaarthouder</translation>
<translation id="1821930232296380041">Ongeldige aanvraag of aanvraagparameters</translation>
+<translation id="1822540298136254167">Websites die je bezoekt en waarop je tijd doorbrengt</translation>
<translation id="1826516787628120939">Controleren</translation>
<translation id="1834321415901700177">Deze site bevat schadelijke programma's</translation>
<translation id="1839551713262164453">De validatie van de beleidswaarden is mislukt doordat er fouten zijn opgetreden</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">De gegevens van de Chrome-browsegeschiedenis wissen</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{en 1 andere}other{en # andere}}</translation>
<translation id="2003709556000175978">Stel je wachtwoord nu opnieuw in</translation>
+<translation id="20053308747750172">De server waar je naartoe gaat (<ph name="ORIGIN" />), heeft gevraagd om een beveiligingsbeleid toe te passen op alle verzoeken aan de server. De server heeft nu echter een ongeldig beleid geleverd, waardoor de browser je verzoek voor <ph name="SITE" /> niet kan uitvoeren.</translation>
<translation id="2025186561304664664">Proxy is ingesteld op automatische configuratie.</translation>
<translation id="2030481566774242610">Bedoelde je <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Controleer de proxy en firewall<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Departement</translation>
<translation id="2102134110707549001">Sterk wachtwoord voorstellen…</translation>
<translation id="2108755909498034140">Je computer opnieuw opstarten</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Pas</translation>
<translation id="2114841414352855701">Genegeerd omdat het werd overschreven door <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobiele bladwijzers</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">Pas bewerken</translation>
<translation id="2166049586286450108">Volledige beheerderstoegang</translation>
<translation id="2166378884831602661">Deze site kan geen beveiligde verbinding leveren</translation>
+<translation id="2169984857010174799">Kaku2 (envelop)</translation>
<translation id="2181821976797666341">Beleid</translation>
<translation id="2183608646556468874">Telefoonnummer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}other{# adressen}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Telefoonnummer</translation>
<translation id="2283340219607151381">Adressen opslaan en invullen</translation>
<translation id="2292556288342944218">Je toegang tot internet wordt geblokkeerd</translation>
+<translation id="2294558542833290837">De link die je oorspronkelijk hebt geopend, is ongebruikelijk</translation>
+<translation id="2297722699537546652">B5 (envelop)</translation>
+<translation id="2310021320168182093">Chou2 (envelop)</translation>
<translation id="2316887270356262533">Hiermee wordt minder dan 1 MB vrijgemaakt. Sommige sites kunnen langzamer worden geladen wanneer je ze weer bezoekt.</translation>
<translation id="2317259163369394535">Voor <ph name="DOMAIN" /> zijn een gebruikersnaam en een wachtwoord vereist.</translation>
<translation id="2317583587496011522">Betaalpassen worden geaccepteerd.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, verloopt op <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Instelling beheerd door je beheerder</translation>
+<translation id="2346319942568447007">Afbeelding die je hebt gekopieerd</translation>
<translation id="2349790679044093737">VR-sessie is actief</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>
@@ -239,29 +266,34 @@
<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="2378238891085281592">Je gebruikt de privémodus</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Zakelijk standaard</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="2410754574180102685">Government-Legal</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="2418081434543109369">De server waar je naartoe gaat (<ph name="ORIGIN" />), heeft gevraagd om een beveiligingsbeleid toe te passen op alle verzoeken aan de server. De server heeft nu echter geen beleid geleverd, waardoor de browser je verzoek voor <ph name="SITE" /> niet kan uitvoeren.</translation>
<translation id="244665789865330679">Je apparaat en account worden beheerd door <ph name="ENROLLMENT_DOMAIN" />. Dat betekent dat je beheerder je apparaat en account op afstand kan configureren.</translation>
<translation id="2463193859425327265">Homepage wijzigen</translation>
<translation id="2463739503403862330">Invullen</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Bezorgingsmethode kiezen</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Netwerkcontrole uitvoeren<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Deze pagina vertalen</translation>
<translation id="2479410451996844060">Ongeldige zoek-URL.</translation>
<translation id="2482878487686419369">Meldingen</translation>
<translation id="248348093745724435">Apparaatbeleid</translation>
+<translation id="2485387744899240041">Gebruikersnamen voor je apparaat en browser</translation>
<translation id="2491120439723279231">Het servercertificaat bevat fouten.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON Parser</translation>
<translation id="2495093607237746763">Als deze optie is aangevinkt, bewaart Chromium een exemplaar van je pas op dit apparaat om formulieren sneller te kunnen invullen.</translation>
<translation id="2498091847651709837">Nieuwe pas scannen</translation>
<translation id="2501278716633472235">Terug</translation>
<translation id="2503184589641749290">Geaccepteerde betaalpassen en prepaidkaarten</translation>
<translation id="2515629240566999685">Check of je bereik hebt in je omgeving</translation>
-<translation id="2516852381693169964">Afbeelding zoeken in <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Alleen opgeslagen op dit apparaat</translation>
<translation id="2524461107774643265">Meer informatie toevoegen</translation>
<translation id="2536110899380797252">Adres toevoegen</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (envelop)</translation>
<translation id="2625385379895617796">Je klok loopt voor</translation>
<translation id="2634124572758952069">Het IP-adres van de server van <ph name="HOST_NAME" /> kan niet worden gevonden.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Andere tabbladen of apps sluiten</translation>
<translation id="267371737713284912">druk op <ph name="MODIFIER_KEY_DESCRIPTION" /> om dit ongedaan maken</translation>
<translation id="2674170444375937751">Weet je zeker dat je deze pagina's uit je geschiedenis wilt verwijderen?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Verlaten</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Geaccepteerde passen</translation>
<translation id="2702801445560668637">Leeslijst</translation>
<translation id="2704283930420550640">Waarde komt niet overeen met notatie.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Geselecteerde items verwijderen</translation>
<translation id="277133753123645258">Verzendmethode</translation>
<translation id="277499241957683684">Apparaatrecord ontbreekt</translation>
-<translation id="2781030394888168909">Exporteren naar Mac OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">De verbinding is opnieuw ingesteld.</translation>
<translation id="2788784517760473862">Geaccepteerde creditcards</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Incognitovenster openen</translation>
+<translation id="2850739647070081192">Invite (envelop)</translation>
<translation id="2851634818064021665">Je hebt toestemming nodig om deze site te bezoeken</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Pas opslaan?</translation>
<translation id="2903493209154104877">Adressen</translation>
<translation id="290376772003165898">Pagina is niet in het <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Bezorgingsmethode</translation>
<translation id="2928905813689894207">Factuuradres</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (envelop)</translation>
<translation id="3024663005179499861">Onjuist beleidstype</translation>
<translation id="3037605927509011580">Helaas.</translation>
<translation id="3041612393474885105">Certificaatgegevens</translation>
+<translation id="3060227939791841287">C9 (envelop)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Ophaaladres toevoegen</translation>
<translation id="3105172416063519923">Item-ID:</translation>
<translation id="3109728660330352905">Je hebt geen toestemming om deze pagina te bekijken.</translation>
@@ -361,20 +401,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> op <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Betaling annuleren</translation>
<translation id="3207960819495026254">Toegevoegd aan 'Bladwijzers'</translation>
-<translation id="3209375525920864198">Geef een geldige sessienaam op.</translation>
+<translation id="321912867715453276">Waarschuwing: Er zijn meerdere bronnen aanwezig voor het beleid, maar de waarden zijn gelijk.</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="3229041911291329567">Versie-informatie over je apparaat en browser</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Naam op pas toevoegen</translation>
<translation id="3287510313208355388">Downloaden wanneer online</translation>
<translation id="3293642807462928945">Meer informatie over het beleid <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Geen zoekresultaten gevonden</translation>
-<translation id="3305707030755673451">Je gegevens zijn op <ph name="TIME" /> versleuteld met je wachtwoordzin voor synchronisatie. Geef deze op om de synchronisatie te starten.</translation>
<translation id="3320021301628644560">Factuuradres toevoegen</translation>
<translation id="3324983252691184275">Karmozijnrood</translation>
<translation id="3338095232262050444">Beveiligd</translation>
@@ -402,9 +443,11 @@
<translation id="3427342743765426898">&amp;Opnieuw bewerken</translation>
<translation id="342781501876943858">Chromium raadt je aan je wachtwoord te resetten als je het voor andere sites hebt hergebruikt.</translation>
<translation id="3431636764301398940">Deze creditcard opslaan op dit apparaat</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">De eigenaar van dit apparaat heeft de dinosaurusgame uitgeschakeld.</translation>
<translation id="3447884698081792621">Certificaat weergeven (uitgegeven door <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Ophaalinterval:</translation>
+<translation id="3456231139987291353">Number-11 (envelop)</translation>
<translation id="3461824795358126837">Markeren</translation>
<translation id="3462200631372590220">Gedetailleerde informatie verbergen</translation>
<translation id="3467763166455606212">Naam kaarthouder vereist</translation>
@@ -426,19 +469,22 @@
<translation id="358285529439630156">Creditcards en prepaidkaarten worden geaccepteerd.</translation>
<translation id="3582930987043644930">Voeg naam toe</translation>
<translation id="3583757800736429874">&amp;Opnieuw verplaatsen</translation>
+<translation id="35866233670761917">De content van websites die je bezoekt, is niet zichtbaar voor je beheerders</translation>
<translation id="3586931643579894722">Details verbergen</translation>
+<translation id="3592413004129370115">Italian (envelop)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Grootte 2</translation>
<translation id="3615877443314183785">Geef een geldige vervaldatum op</translation>
<translation id="36224234498066874">Browsegegevens wissen</translation>
<translation id="362276910939193118">Volledige geschiedenis weergeven</translation>
-<translation id="3623476034248543066">Waarde weergeven</translation>
<translation id="3630155396527302611">Als dit programma al wordt vermeld als een programma dat toegang heeft tot het netwerk, kun je proberen het uit de lijst te verwijderen en het opnieuw toe te voegen.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validatie geslaagd</translation>
<translation id="3655670868607891010">Als je deze melding vaker ziet, probeer je deze <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisie</translation>
<translation id="366077651725703012">Creditcard updaten</translation>
<translation id="3676592649209844519">Apparaat-ID:</translation>
+<translation id="3677008721441257057">Bedoelde je &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Verzoek kan niet worden ondertekend</translation>
<translation id="3678529606614285348">Pagina openen in een nieuw incognitovenster (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Crashrapport vastgelegd op <ph name="CRASH_TIME" />, geüpload op <ph name="UPLOAD_TIME" /></translation>
@@ -446,13 +492,14 @@
<translation id="3704162925118123524">Het is mogelijk dat je de inlogpagina moet bezoeken van het netwerk dat je gebruikt.</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="3709599264800900598">Tekst die je hebt gekopieerd</translation>
<translation id="3712624925041724820">Licenties zijn verbruikt</translation>
<translation id="3714780639079136834">Zet je mobiele data of wifi aan</translation>
<translation id="3715597595485130451">Verbinding maken met wifi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Controleer de proxy, firewall en DNS-configuratie<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Apps die deze fout kunnen veroorzaken, omvatten antivirussoftware, firewalls en webfilter- of proxysoftware.</translation>
+<translation id="373042150751172459">B4 (envelop)</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="3745099705178523657">Nadat je hebt bevestigd, worden de kaartgegevens uit je Google-account gedeeld met deze site.</translation>
<translation id="3748148204939282805">Cybercriminelen op <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> kunnen proberen om je te misleiden zodat je iets gevaarlijks doet, bijvoorbeeld software installeren of je persoonsgegevens bekendmaken (zoals wachtwoorden, telefoonnummers of creditcardgegevens). <ph name="BEGIN_LEARN_MORE_LINK" />Meer informatie<ph name="END_LEARN_MORE_LINK" /></translation>
@@ -465,10 +512,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Verloopt: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Grootte 16</translation>
+<translation id="3797522431967816232">Prc3 (envelop)</translation>
<translation id="3807873520724684969">Schadelijke content geblokkeerd.</translation>
<translation id="3810973564298564668">Beheren</translation>
<translation id="382518646247711829">Als je een proxyserver gebruikt...</translation>
<translation id="3828924085048779000">Een lege wachtwoordzin is niet toegestaan.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> heeft extensies voor aanvullende functies geïnstalleerd. Extensies hebben toegang tot sommige van je gegevens.</translation>
<translation id="385051799172605136">Vorige</translation>
<translation id="3858027520442213535">Datum en tijd updaten</translation>
<translation id="3884278016824448484">Conflicterende apparaat-ID's</translation>
@@ -476,6 +525,7 @@
<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 pas is verlopen</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Altijd vragen op deze site</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>
@@ -486,11 +536,13 @@
<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="3984550557525787191">Deze sessienaam bestaat al.</translation>
<translation id="3987940399970879459">Minder dan 1 MB</translation>
+<translation id="4008849406247176967">Waarschuwing: Er zijn meerdere bronnen met conflicterende waarden aanwezig voor dit beleid.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webpagina in de buurt}other{# webpagina's in de buurt}}</translation>
<translation id="4030383055268325496">&amp;Toevoegen ongedaan maken</translation>
+<translation id="4032320456957708163">Je browser wordt beheerd door <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Sleutel '<ph name="SUBKEY" />': <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (envelop)</translation>
<translation id="4067947977115446013">Geldig adres toevoegen</translation>
<translation id="4072486802667267160">Er is een fout opgetreden bij het verwerken van je bestelling. Probeer het opnieuw.</translation>
<translation id="4075732493274867456">De client en server ondersteunen geen algemene SSL-protocolversie of coderingssuite.</translation>
@@ -510,10 +562,12 @@
<translation id="4159784952369912983">Paars</translation>
<translation id="4165986682804962316">Site-instellingen</translation>
<translation id="4171400957073367226">Onjuiste verificatiehandtekening</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Nog <ph name="ITEM_COUNT" /> item}other{Nog <ph name="ITEM_COUNT" /> items}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (envelop)</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="4221630205957821124">&lt;h4&gt;Stap 1: Log in bij de portal&lt;/h4&gt;
@@ -545,58 +599,79 @@
<translation id="4277028893293644418">Wachtwoord opnieuw instellen</translation>
<translation id="4280429058323657511">, vervalt <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Deze pas is opgeslagen in je Google-account}other{Deze passen zijn opgeslagen in je Google-account}}</translation>
+<translation id="42981349822642051">Uitvouwen</translation>
+<translation id="4302965934281694568">Chou3 (envelop)</translation>
<translation id="4305817255990598646">Overschakelen</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokkeren (standaard)</translation>
+<translation id="4318566738941496689">De naam en het netwerkadres van je apparaat</translation>
<translation id="4325863107915753736">Kan artikel niet vinden</translation>
<translation id="4326324639298822553">Controleer de vervaldatum en probeer het opnieuw</translation>
<translation id="4331708818696583467">Niet beveiligd</translation>
<translation id="4340982228985273705">Deze computer is niet gedetecteerd als een zakelijk beheerde computer. Overeenkomstig het beleid kunnen alleen automatisch extensies worden geïnstalleerd die worden gehost in de Chrome Web Store. De update-URL van de Chrome Web Store is <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Geaccepteerde creditcards</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Betaalmethoden beheren...</translation>
+<translation id="4367563149485757821">Number-12 (envelop)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefoon</translation>
<translation id="4406896451731180161">zoekresultaten</translation>
-<translation id="4406972042435603828">Je beheerders hebben extensies met krachtige functionaliteit geïnstalleerd.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> cookies</translation>
<translation id="4415426530740016218">Ophaaladres</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="443121186588148776">Seriële poort</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> heeft je inlogcertificaat niet geaccepteerd of er is geen inlogcertificaat geleverd.</translation>
<translation id="4434045419905280838">Pop-ups en omleidingen</translation>
+<translation id="4435702339979719576">Briefkaart</translation>
<translation id="443673843213245140">Het gebruik van een proxy is uitgeschakeld, maar er is wel een expliciete proxyconfiguratie opgegeven.</translation>
<translation id="445100540951337728">Geaccepteerde betaalpassen</translation>
+<translation id="4466881336512663640">Hiermee gaan formulierwijzigingen verloren. Weet je zeker dat je wilt doorgaan?</translation>
<translation id="4482953324121162758">Deze site wordt niet vertaald.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Ongeldige URL. Dit moet een URL met een standaardschema zijn, zoals http://example.com of https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (envelop)</translation>
<translation id="4515275063822566619">Passen 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="4517607026994743406">Comm-10 (envelop)</translation>
<translation id="4522570452068850558">Details</translation>
<translation id="4524805452350978254">Passen beheren</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Probeer je extensies uit te schakelen.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Bezorging</translation>
+<translation id="4579056131138995126">Personal (envelop)</translation>
<translation id="4582204425268416675">Pas verwijderen</translation>
<translation id="4587425331216688090">Adres verwijderen uit Chrome?</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="4597348597567598915">Grootte 8</translation>
+<translation id="4600854749408232102">C6/C5 (envelop)</translation>
<translation id="4646534391647090355">Breng me daar nu naartoe</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="467809019005607715">Google Presentaties</translation>
<translation id="4690462567478992370">Stoppen met het gebruik van een ongeldig certificaat</translation>
+<translation id="4691835149146451662">Architecture-A (envelop)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Je verbinding is onderbroken</translation>
<translation id="471880041731876836">Je hebt geen toestemming om deze site te bezoeken</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows Netwerkcontrole uitvoeren<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Beleid opnieuw laden</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (envelop)</translation>
<translation id="4736825316280949806">Chromium opnieuw starten</translation>
<translation id="473775607612524610">Updaten</translation>
<translation id="4738601419177586157">Zoeksuggestie: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Wachtwoorden beheren…</translation>
<translation id="4744603770635761495">Uitvoerbaar pad</translation>
+<translation id="4746351372139058112">Berichten</translation>
<translation id="4750917950439032686">Je gegevens (zoals wachtwoorden of creditcardnummers) zijn privé wanneer ze worden verzonden naar deze site.</translation>
<translation id="4756388243121344051">Gesc&amp;hiedenis</translation>
<translation id="4758311279753947758">Contactgegevens toevoegen</translation>
@@ -604,9 +679,9 @@
<translation id="4764776831041365478"><ph name="URL" /> werkt even niet, of de pagina kan verhuisd zijn naar een nieuw webadres.</translation>
<translation id="4771973620359291008">Er is een onbekende fout opgetreden.</translation>
<translation id="4785689107224900852">Overschakelen naar dit tabblad</translation>
-<translation id="4792143361752574037">Er is een probleem opgetreden bij het openen van de sessiebestanden. Opslaan op schijf is momenteel uitgeschakeld. Laad pagina opnieuw om het nogmaals te proberen.</translation>
<translation id="4798078619018708837">Geef de vervaldatum en CVC-code voor <ph name="CREDIT_CARD" /> op om je creditcardgegevens te updaten. Nadat je hebt bevestigd, worden de creditcardgegevens uit je Google-account gedeeld met deze site.</translation>
<translation id="4800132727771399293">Controleer je vervaldatum en CVC-code en probeer het opnieuw</translation>
+<translation id="480334179571489655">Fout met beleid van oorsprong</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>
@@ -621,7 +696,6 @@
<translation id="4881695831933465202">Openen</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>
@@ -630,15 +704,15 @@
<translation id="4943872375798546930">Geen resultaten</translation>
<translation id="4950898438188848926">Schakelknop voor tabbladen, druk op Enter om naar het geopende tabblad, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, te schakelen</translation>
<translation id="495170559598752135">Acties</translation>
-<translation id="495832697253704892">Extensierapportage</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Lijst uitvouwen</translation>
<translation id="4974590756084640048">Waarschuwingen opnieuw inschakelen</translation>
+<translation id="4984339528288761049">Prc5 (envelop)</translation>
<translation id="4989163558385430922">Alles weergeven</translation>
<translation id="4989809363548539747">Deze plug-in wordt niet ondersteund</translation>
-<translation id="4996230189582812866">Rapportage</translation>
<translation id="5002932099480077015">Indien ingeschakeld, slaat Chrome een kopie van je pas op dit apparaat op zodat formulieren sneller kunnen worden ingevuld.</translation>
-<translation id="5014174725590676422">Het eerste uitvoeringsscherm van de Google Assistent in Chrome wordt weergegeven</translation>
<translation id="5015510746216210676">Naam apparaat:</translation>
+<translation id="5017554619425969104">Tekst die je hebt gekopieerd</translation>
<translation id="5018422839182700155">Kan deze pagina niet openen</translation>
<translation id="5019198164206649151">Backend-opslag in slechte staat</translation>
<translation id="5023310440958281426">Neem het beleid van je beheerder door</translation>
@@ -648,35 +722,51 @@
<translation id="5034369478845443529">Lokale context <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Toestaan</translation>
<translation id="5040262127954254034">Privacy</translation>
+<translation id="5043480802608081735">Link die je hebt gekopieerd</translation>
<translation id="5045550434625856497">Onjuist wachtwoord</translation>
<translation id="5056549851600133418">Artikelen voor jou</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Het proxy-adres controleren<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Het servercertificaat is momenteel niet geldig.</translation>
<translation id="5087580092889165836">Pas 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="5097099694988056070">Apparaatstatistieken zoals CPU-/RAM-gebruik rapporteren</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Je apparaat wordt beheerd door <ph name="ENROLLMENT_DOMAIN" /> en je account wordt beheerd door <ph name="ACCOUNT_DOMAIN" />. Dit betekent dat je beheerders je apparaat en account op afstand kunnen configureren.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bits)</translation>
-<translation id="5128122789703661928">De naam van deze sessie die je wilt verwijderen, is ongeldig.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Adressen beheren...</translation>
+<translation id="5138227688689900538">Minder weergeven</translation>
<translation id="5141240743006678641">Gesynchroniseerde wachtwoorden versleutelen met je Google-aanmeldingsgegevens</translation>
<translation id="5145883236150621069">Foutcode aanwezig in de beleidsreactie</translation>
+<translation id="515292512908731282">C4 (envelop)</translation>
<translation id="5159010409087891077">Pagina openen in een nieuw incognitovenster (⇧⌘N)</translation>
<translation id="516920405563544094">Geef de CVC-code voor <ph name="CREDIT_CARD" /> op. Nadat je hebt bevestigd, worden de creditcardgegevens uit je Google-account gedeeld met deze site.</translation>
<translation id="5169827969064885044">Je kunt de toegang tot het account van je organisatie kwijtraken of slachtoffer worden van identiteitsdiefstal. Chrome raadt je aan je wachtwoord nu te wijzigen.</translation>
<translation id="5171045022955879922">Zoek of typ een URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Computer</translation>
<translation id="5179510805599951267">Niet in het <ph name="ORIGINAL_LANGUAGE" />? Deze fout melden</translation>
<translation id="5190835502935405962">Bladwijzerbalk</translation>
-<translation id="5200263511887412697">lijst melden met apparaatgebruikers die onlangs zijn ingelogd</translation>
+<translation id="519422657042045905">Annotatie niet beschikbaar</translation>
<translation id="5201306358585911203">Een ingesloten pagina op deze pagina meldt het volgende</translation>
<translation id="5205222826937269299">Naam vereist</translation>
<translation id="5215116848420601511">Betaalmethoden en adressen die Google Pay gebruiken</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-mailadres vereist</translation>
<translation id="5230733896359313003">Verzendadres</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">'Verbinding maken met netwerk'</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (envelop)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Netwerkadressen</translation>
<translation id="5285570108065881030">Alle opgeslagen wachtwoorden weergeven</translation>
<translation id="5287240709317226393">Cookies weergeven</translation>
<translation id="5288108484102287882">Tijdens de validatie van de beleidswaarden zijn er waarschuwingen geconstateerd</translation>
@@ -688,7 +778,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> van <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Contactgegevens kiezen</translation>
<translation id="5327248766486351172">Naam</translation>
+<translation id="5329858041417644019">Je browser wordt niet beheerd.</translation>
<translation id="5332219387342487447">Verzendmethode</translation>
+<translation id="5334013548165032829">Gedetailleerde systeemlogboeken</translation>
<translation id="5344579389779391559">Deze pagina brengt je mogelijk kosten in rekening</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>
@@ -696,6 +788,7 @@
<translation id="5377026284221673050">'Je klok loopt achter', 'Je klok loopt voor' of '&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;'</translation>
<translation id="5384855140246857529">Als je je passen op alle apparaten wilt gebruiken, moet je inloggen en synchronisatie inschakelen.</translation>
<translation id="5386426401304769735">De certificaatketen voor deze site bevat een certificaat dat is ondertekend met SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -706,6 +799,7 @@
<translation id="5457113250005438886">Ongeldig</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Opnieuw bewerken</translation>
+<translation id="5478437291406423475">B6/C4 (envelop)</translation>
<translation id="5481076368049295676">Deze content probeert mogelijk 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="54817484435770891">Voeg een geldig adres toe</translation>
<translation id="5490432419156082418">Adressen en meer</translation>
@@ -713,10 +807,12 @@
<ph name="LINE_BREAK" />
Neem contact op met je systeembeheerder.</translation>
<translation id="549333378215107354">Grootte 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Beheerde bladwijzers</translation>
<translation id="5510766032865166053">Het bestand is mogelijk verplaatst of verwijderd.</translation>
<translation id="5523118979700054094">Beleidsnaam</translation>
<translation id="552553974213252141">Is de tekst correct geëxtraheerd?</translation>
+<translation id="553484882784876924">Prc6 (envelop)</translation>
<translation id="5540224163453853">Kan het gevraagde artikel niet vinden.</translation>
<translation id="5541546772353173584">E-mailadres toevoegen</translation>
<translation id="5545756402275714221">Artikelen voor jou</translation>
@@ -731,15 +827,21 @@
<translation id="5595485650161345191">Adres bewerken</translation>
<translation id="5598944008576757369">Betaalmethode kiezen</translation>
<translation id="560412284261940334">Beheer wordt niet ondersteund</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">Controleer de verbinding</translation>
<translation id="5610807607761827392">Je kunt passen en adressen beheren in <ph name="BEGIN_LINK" />Instellingen<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> heeft je te vaak omgeleid.</translation>
<translation id="5629630648637658800">Laden van beleidsinstellingen is mislukt</translation>
<translation id="5631439013527180824">Ongeldige token voor apparaatbeheer</translation>
+<translation id="5632627355679805402">Je gegevens zijn vanaf <ph name="TIME" /> versleuteld met je <ph name="BEGIN_LINK" />Google-wachtwoord<ph name="END_LINK" />. Geef het wachtwoord op om de synchronisatie te starten.</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="563324245173044180">Misleidende content geblokkeerd.</translation>
<translation id="5659593005791499971">E-mailadres</translation>
+<translation id="5663614846592581799">9x11 (envelop)</translation>
+<translation id="5663955426505430495">De beheerder van dit apparaat heeft extensies voor aanvullende functies geïnstalleerd. Extensies hebben toegang tot sommige van je gegevens.</translation>
<translation id="5675650730144413517">Deze pagina werkt niet</translation>
+<translation id="5684874026226664614">Deze pagina kan niet worden vertaald.</translation>
<translation id="5685654322157854305">Verzendadres toevoegen</translation>
<translation id="5689199277474810259">Exporteren naar JSON</translation>
<translation id="5689516760719285838">Locatie</translation>
@@ -748,38 +850,39 @@
<translation id="5710435578057952990">De identiteit van deze website is niet geverifieerd.</translation>
<translation id="5719499550583120431">Prepaidkaarten worden geaccepteerd.</translation>
<translation id="5720705177508910913">Huidige gebruiker</translation>
+<translation id="5728056243719941842">C5 (envelop)</translation>
<translation id="5730040223043577876">Chrome raadt je aan je wachtwoord opnieuw in te stellen als je het voor andere sites hebt hergebruikt.</translation>
<translation id="5732392974455271431">Je ouders kunnen de blokkering van deze site opheffen</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Pas opslaan in je Google-account}other{Passen opslaan in je Google-account}}</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="5770114862687765385">Het bestand lijkt beschadigd. Klik op de knop Resetten om de sessie te resetten.</translation>
<translation id="5778550464785688721">Volledige controle voor MIDI-apparaten</translation>
<translation id="578305955206182703">Geelbruin</translation>
<translation id="57838592816432529">Dempen</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>
+<translation id="5798290721819630480">Wijzigingen niet opslaan?</translation>
<translation id="5798683403665926540">De homepage wijzigen in de Chrome-instellingen</translation>
<translation id="5803412860119678065">Wil je de gegevens van je <ph name="CARD_DETAIL" /> laten invullen?</translation>
<translation id="5804241973901381774">Rechten</translation>
<translation id="5810442152076338065">Je verbinding met <ph name="DOMAIN" /> is versleuteld via een verouderde Cipher Suite.</translation>
<translation id="5813119285467412249">&amp;Opnieuw toevoegen</translation>
<translation id="5838278095973806738">Geef geen gevoelige gegevens op op deze site (zoals wachtwoorden of creditcards), want deze kunnen worden gestolen door cybercriminelen.</translation>
+<translation id="5860033963881614850">Uit</translation>
<translation id="5863847714970149516">De komende pagina probeert misschien kosten in rekening te brengen</translation>
<translation id="5866257070973731571">Telefoonnummer toevoegen</translation>
<translation id="5869405914158311789">Deze site is niet bereikbaar</translation>
<translation id="5869522115854928033">Opgeslagen wachtwoorden</translation>
<translation id="5887400589839399685">Pas opgeslagen</translation>
-<translation id="5893718151540690985">lijst van netwerkinterfaces rapporteren met de bijbehorende typen en hardware-adressen</translation>
<translation id="5893752035575986141">Creditcards worden geaccepteerd.</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="5916664084637901428">Aan</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Pas opslaan in Google-account?</translation>
<translation id="5922853866070715753">Bijna klaar</translation>
<translation id="5932224571077948991">Site geeft opdringerige of misleidende advertenties weer</translation>
-<translation id="5939518447894949180">Resetten</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> openen…</translation>
<translation id="5951495562196540101">Kan consumentenaccount niet inschrijven (verpakte licentie beschikbaar).</translation>
<translation id="5967592137238574583">Contactgegevens bewerken</translation>
@@ -787,6 +890,7 @@
<translation id="5975083100439434680">Uitzoomen</translation>
<translation id="5977489021191000276">Je apparaat wordt niet beheerd door een beheerder.</translation>
<translation id="5977976211062815271">Op dit apparaat</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Kan betaal-app niet openen</translation>
<translation id="5989320800837274978">Er worden geen vaste proxyservers en geen pac-script-URL gespecificeerd.</translation>
<translation id="5990559369517809815">Verzoeken aan de server zijn door een extensie geblokkeerd.</translation>
@@ -797,8 +901,8 @@
<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="6033927989869462158">hardwarestatistieken rapporteren zoals CPU-/RAM-gebruik</translation>
<translation id="6034000775414344507">Lichtgrijs</translation>
+<translation id="6034283069659657473">10x14 (envelop)</translation>
<translation id="6039846035001940113">Als het probleem blijft optreden, neem je contact op met de site-eigenaar.</translation>
<translation id="6040143037577758943">Sluiten</translation>
<translation id="6044573915096792553">Grootte 12</translation>
@@ -807,10 +911,10 @@
<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="6058977677006700226">Je passen gebruiken op al je apparaten?</translation>
<translation id="6059925163896151826">USB-apparaten</translation>
-<translation id="6071091556643036997">Het type beleid is ongeldig.</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="6094273045989040137">Aantekeningen maken</translation>
<translation id="610911394827799129">Er kunnen andere vormen van browsegeschiedenis zijn opgeslagen voor je Google-account op <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Informatie over geïnstalleerde extensies en plug-ins</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 dit eens:</translation>
@@ -844,15 +948,21 @@
<translation id="6337133576188860026">Hiermee wordt minder dan <ph name="SIZE" /> vrijgemaakt. Sommige sites kunnen langzamer worden geladen wanneer je ze weer bezoekt.</translation>
<translation id="6337534724793800597">Beleid filteren op naam</translation>
<translation id="6358450015545214790">Wat betekent dit?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Er worden later mogelijk kosten in rekening gebracht.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 andere suggestie}other{# andere suggesties}}</translation>
<translation id="6387754724289022810">Sla je pas en factuuradres op in je Google-account en op dit apparaat zodat je de volgende keer sneller kunt betalen.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Bladwijzer bewerken</translation>
+<translation id="6406765186087300643">C0 (envelop)</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="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="6434309073475700221">Annuleren</translation>
+<translation id="6446163441502663861">Kahu (envelop)</translation>
<translation id="6446608382365791566">Meer informatie toevoegen</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Opnieuw indienen bevestigen</translation>
@@ -865,11 +975,17 @@
<translation id="6508722015517270189">Chrome opnieuw starten</translation>
<translation id="6529602333819889595">&amp;Opnieuw verwijderen</translation>
<translation id="6534179046333460208">Fysieke web-suggesties</translation>
+<translation id="6556866813142980365">Opnieuw</translation>
<translation id="6563469144985748109">Je beheerder heeft dit nog niet goedgekeurd</translation>
<translation id="6569060085658103619">Je bekijkt een extensiepagina</translation>
+<translation id="6578796323535178455">C2 (envelop)</translation>
<translation id="6579990219486187401">Lichtroze</translation>
+<translation id="6583674473685352014">B6 (envelop)</translation>
+<translation id="6587923378399804057">Link die je hebt gekopieerd</translation>
+<translation id="6591833882275308647">Je <ph name="DEVICE_TYPE" /> wordt niet beheerd</translation>
<translation id="6596325263575161958">Opties voor encryptie</translation>
<translation id="6604181099783169992">Bewegings- of lichtsensoren</translation>
+<translation id="6609880536175561541">Prc7 (envelop)</translation>
<translation id="6624427990725312378">Contactgegevens</translation>
<translation id="6626291197371920147">Een geldig kaartnummer toevoegen</translation>
<translation id="6628463337424475685">Zoeken via <ph name="ENGINE" /></translation>
@@ -878,6 +994,7 @@
<translation id="6644283850729428850">Dit beleid is verouderd.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Geen}=1{Van 1 site (je wordt niet uitgelogd bij je Google-account)}other{Van # sites (je wordt niet uitgelogd bij je Google-account)}}</translation>
<translation id="6657585470893396449">Wachtwoord</translation>
+<translation id="6670613747977017428">Terug naar veilige pagina.</translation>
<translation id="6671697161687535275">Formuliersuggestie verwijderen uit Chromium?</translation>
<translation id="6685834062052613830">Uitloggen en configuratie voltooien</translation>
<translation id="6710213216561001401">Vorige</translation>
@@ -885,12 +1002,15 @@
<translation id="671076103358959139">Inschrijftoken:</translation>
<translation id="6711464428925977395">Er is iets mis met de proxyserver of het adres is onjuist.</translation>
<translation id="6723740634201835758">In je Google-account</translation>
+<translation id="6738516213925468394">Je gegevens zijn op <ph name="TIME" /> versleuteld met je <ph name="BEGIN_LINK" />wachtwoordzin voor synchronisatie<ph name="END_LINK" />. Geef deze op om de synchronisatie te starten.</translation>
<translation id="674375294223700098">Onbekende fout met servercertificaat.</translation>
<translation id="6744009308914054259">Terwijl je op een verbinding wacht, kun je naar Downloads gaan om offline artikelen te lezen.</translation>
<translation id="6753269504797312559">Beleidswaarde</translation>
<translation id="6757797048963528358">De slaapstand van je apparaat is geactiveerd.</translation>
+<translation id="6768213884286397650">Hagaki (briefkaart)</translation>
<translation id="6778737459546443941">Je ouder of voogd heeft dit nog niet goedgekeurd</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Extensies</translation>
<translation id="679355240208270552">Genegeerd omdat de standaard zoekoptie door het beleid is uitgeschakeld.</translation>
<translation id="681021252041861472">Verplicht veld</translation>
<translation id="6810899417690483278">Aanpassings-ID</translation>
@@ -923,10 +1043,12 @@
<translation id="6965978654500191972">Apparaat</translation>
<translation id="6970216967273061347">District</translation>
<translation id="6973656660372572881">Zowel vaste proxyservers als een pac-script-URL worden gespecificeerd.</translation>
+<translation id="6973932557599545801">Ik kan je helaas niet helpen. Ga zelf verder.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Dempen (standaard)</translation>
<translation id="6984479912851154518">Je verlaat de privémodus om te betalen via een externe app. Doorgaan?</translation>
<translation id="6989763994942163495">Geavanceerde instellingen weergeven...</translation>
+<translation id="6993898126790112050">6x9 (envelop)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> altijd vertalen</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Dit kunnen eenmalige of terugkerende kosten zijn die misschien niet duidelijk worden aangegeven.</translation>
@@ -942,28 +1064,33 @@
<translation id="7108338896283013870">Verbergen</translation>
<translation id="7108819624672055576">Toegestaan door een extensie</translation>
<translation id="7111012039238467737">(Geldig)</translation>
+<translation id="7118618213916969306">Zoeken naar klembord-URL, <ph name="SHORT_URL" /></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="7135130955892390533">Status weergeven</translation>
<translation id="7138472120740807366">Bezorgingsmethode</translation>
<translation id="7139724024395191329">Emiraat</translation>
+<translation id="7152423860607593928">Number-14 (envelop)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendel</translation>
-<translation id="7158980942472052083">Ongeldige URL. Dit moet een URL met een standaardschema zijn.</translation>
<translation id="717330890047184534">Gaia-ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">De server waar je naartoe gaat (<ph name="ORIGIN" />), heeft gevraagd om een beveiligingsbeleid toe te passen op alle verzoeken aan de server. De server heeft echter geen beleid geleverd, maar heeft de browser omgeleid naar een andere locatie. Hierdoor kan de browser je verzoek voor <ph name="SITE" /> niet uitvoeren.</translation>
<translation id="7179323680825933600">Betaalmethoden toevoegen en invullen</translation>
<translation id="7180611975245234373">Vernieuwen</translation>
<translation id="7182878459783632708">Geen beleid ingesteld</translation>
<translation id="7186367841673660872">Deze pagina is vertaald van het<ph name="ORIGINAL_LANGUAGE" />in het<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Hiermee wordt <ph name="SIZE" /> vrijgemaakt. Sommige sites kunnen langzamer worden geladen wanneer je ze weer bezoekt.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">De beheerder kan het volgende zien:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> voldoet niet aan de beveiligingsnormen.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /> over dit probleem.</translation>
<translation id="7219179957768738017">De verbinding maakt gebruik van <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Verwerken</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">De volgende website bevat malware</translation>
+<translation id="724766306220616965">Waarschuwingen, conflict</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="7251437084390964440">De netwerkconfiguratie voldoet niet aan de ONC-standaard. Delen van de configuratie worden mogelijk niet geïmporteerd.
Aanvullende informatie:
@@ -976,11 +1103,14 @@ Aanvullende informatie:
<translation id="7300012071106347854">Kobaltblauw</translation>
<translation id="7302712225291570345">'<ph name="TEXT" />'</translation>
<translation id="7309308571273880165">Crashrapport vastgelegd op <ph name="CRASH_TIME" /> (upload aangevraagd door gebruiker, nog niet geüpload)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" />-waarschuwingen</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Hulp bij verbinding maken</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Opdrachtregel</translation>
-<translation id="7365061714576910172">Exporteren naar Linux</translation>
<translation id="7372973238305370288">zoekresultaat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nee</translation>
@@ -988,6 +1118,7 @@ Aanvullende informatie:
<translation id="7381288752349550461">Overschrijving voor beheerde sessie</translation>
<translation id="7390545607259442187">Creditcard bevestigen</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Je <ph name="DEVICE_NAME" /> wordt beheerd</translation>
<translation id="7407424307057130981">&lt;p&gt;Deze foutmelding wordt weergegeven als je Superfish-software op je Windows-computer hebt geïnstalleerd.&lt;/p&gt;
&lt;p&gt;Volg deze stappen om de software tijdelijk uit te schakelen zodat je verbinding met internet kunt maken. Je hebt beheerdersrechten nodig.&lt;/p&gt;
&lt;ol&gt;
@@ -998,7 +1129,7 @@ Aanvullende informatie:
&lt;li&gt;Klik op &lt;strong&gt;Toepassen&lt;/strong&gt; en vervolgens op &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Ga naar het &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Helpcentrum van Chrome&lt;/a&gt; voor meer informatie over hoe je de software definitief van je computer kunt verwijderen
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Beheer van <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Wachtwoorden beheren…</translation>
<translation id="7419106976560586862">Profielpad</translation>
<translation id="7437289804838430631">Contactgegevens toevoegen</translation>
@@ -1007,22 +1138,24 @@ Aanvullende informatie:
<translation id="7442725080345379071">Lichtoranje</translation>
<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="7449109375006139765">systeemlogboeken naar de beheerserver verzenden</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="7460618730930299168">De screening verschilt van wat je hebt geselecteerd. Doorgaan?</translation>
<translation id="7473891865547856676">Nee, bedankt</translation>
-<translation id="7475525192983021547">perioden rapporteren waarin een gebruiker actief is op het apparaat</translation>
<translation id="7481312909269577407">Vooruit</translation>
<translation id="7485870689360869515">Geen gegevens gevonden.</translation>
+<translation id="7498234416455752244">Doorgaan met bewerken</translation>
<translation id="7508255263130623398">Geretourneerde apparaat-ID voor beleid is leeg of komt niet overeen met de huidige apparaat-ID</translation>
<translation id="7508870219247277067">Avocadogroen</translation>
<translation id="7511955381719512146">Het is mogelijk dat je <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> moet bezoeken van het wifi-netwerk dat je gebruikt.</translation>
<translation id="7514365320538308">Downloaden</translation>
<translation id="7518003948725431193">Er is geen webpagina gevonden voor het webadres: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (envelop)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Je verbinding met deze site is niet privé</translation>
+<translation id="7535087603100972091">Waarde</translation>
<translation id="7537536606612762813">Verplicht</translation>
+<translation id="7538364083937897561">A2 (envelop)</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>
@@ -1031,8 +1164,8 @@ Aanvullende informatie:
<translation id="7552846755917812628">Probeer de volgende tips:</translation>
<translation id="7554791636758816595">Nieuw tabblad</translation>
<translation id="7564049878696755256">Je kunt de toegang tot je account van <ph name="ORG_NAME" /> kwijtraken of slachtoffer worden van identiteitsdiefstal. Chrome raadt je aan je wachtwoord nu te wijzigen.</translation>
-<translation id="7566125604157659769">Tekst die je hebt gekopieerd</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="7568105740864181217">Deze browser wordt beheerd door een bedrijf, school of andere organisatie. Je beheerder kan je browserinstellingen op afstand wijzigen. Activiteit op dit apparaat kan ook buiten Chrome worden beheerd. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></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 passen die je hebt opgeslagen via Google.</translation>
@@ -1043,6 +1176,7 @@ Aanvullende informatie:
<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="7633909222644580952">Prestatiegegevens en crashrapporten</translation>
<translation id="7637571805876720304">Creditcard verwijderen uit Chromium?</translation>
<translation id="7639968568612851608">Donkergrijs</translation>
<translation id="765676359832457558">Geavanceerde instellingen verbergen...</translation>
@@ -1052,9 +1186,11 @@ Aanvullende informatie:
<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="7676643023259824263">Zoeken naar klembordtekst, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Zoekmachine wijzigen</translation>
<translation id="7682287625158474539">Verzendadres</translation>
<translation id="7687186412095877299">Hiermee worden betalingsformulieren ingevuld met je opgeslagen betaalmethoden</translation>
+<translation id="7697066736081121494">Prc8 (envelop)</translation>
<translation id="769721561045429135">Je hebt momenteel passen die alleen op dit apparaat kunnen worden gebruikt. Klik op Doorgaan om de passen te bekijken.</translation>
<translation id="7699293099605015246">Er zijn op dit moment geen artikelen beschikbaar</translation>
<translation id="7701040980221191251">Geen</translation>
@@ -1066,11 +1202,13 @@ Aanvullende informatie:
<translation id="774634243536837715">Gevaarlijke content geblokkeerd.</translation>
<translation id="7752995774971033316">Niet-beheerd</translation>
<translation id="7755287808199759310">Je ouder of voogd kan de blokkering van deze site opheffen</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">De verbinding is mogelijk geblokkeerd door de firewall of antivirussoftware.</translation>
<translation id="7759163816903619567">Weergegeven domein:</translation>
<translation id="7761701407923456692">Het servercertificaat komt niet overeen met de URL.</translation>
<translation id="7763386264682878361">Payment Manifest Parser</translation>
<translation id="7764225426217299476">Adres toevoegen</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefectuur</translation>
<translation id="7791543448312431591">Toevoegen</translation>
<translation id="7793809570500803535">De webpagina op <ph name="SITE" /> is mogelijk tijdelijk uitgeschakeld of permanent verplaatst naar een nieuw webadres.</translation>
@@ -1082,8 +1220,8 @@ Aanvullende informatie:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Formuliersuggestie verwijderen uit Chrome?</translation>
<translation id="7815407501681723534"><ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> gevonden voor '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Beleidsbeheer</translation>
<translation id="782886543891417279">Het is mogelijk dat je de inlogpagina moet bezoeken van het wifi-netwerk (<ph name="WIFI_NAME" />) dat je gebruikt.</translation>
+<translation id="7836231406687464395">Postfix (envelop)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Geen}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Je bent echter niet onzichtbaar. Als je incognito bent, wordt je browsegeschiedenis niet verborgen voor je werkgever, je internetprovider of de websites die je bezoekt.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1092,7 +1230,7 @@ Aanvullende informatie:
<translation id="7878562273885520351">Je wachtwoord is mogelijk gehackt</translation>
<translation id="7882421473871500483">Bruin</translation>
<translation id="7887683347370398519">Controleer je CVC-code en probeer het opnieuw</translation>
-<translation id="7893255318348328562">Sessienaam</translation>
+<translation id="7904208859782148177">C3 (envelop)</translation>
<translation id="79338296614623784">Geef een geldig telefoonnummer op</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Verloopt op <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1102,21 +1240,25 @@ Aanvullende informatie:
<translation id="7951415247503192394">(32-bits)</translation>
<translation id="7956713633345437162">Mobiele bladwijzers</translation>
<translation id="7961015016161918242">Nooit</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Wachtwoorden beheren</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Deze pas en het bijbehorende factuuradres worden opgeslagen. Je kunt deze gegevens gebruiken wanneer je bent ingelogd op <ph name="USER_EMAIL" />.}other{Deze passen en de bijbehorende factuuradressen worden opgeslagen. Je kunt deze gegevens gebruiken wanneer je bent ingelogd op <ph name="USER_EMAIL" />.}}</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 persoonsgegevens bekendmaken (bijvoorbeeld wachtwoorden, telefoonnummers of creditcards).</translation>
<translation id="8034522405403831421">Deze pagina is in het <ph name="SOURCE_LANGUAGE" />. Vertalen naar het <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pen</translation>
+<translation id="8037117624646282037">Wie het apparaat recent heeft gebruikt</translation>
<translation id="8037357227543935929">Vragen (standaard)</translation>
<translation id="803771048473350947">Archief</translation>
<translation id="8041089156583427627">Feedback verzenden</translation>
<translation id="8041940743680923270">Algemene standaardinstelling gebruiken (Vragen)</translation>
<translation id="8042918947222776840">Ophaalmethode kiezen</translation>
<translation id="8057711352706143257">'<ph name="SOFTWARE_NAME" />' is niet correct geconfigureerd. Als je '<ph name="SOFTWARE_NAME" />' verwijdert, wordt het probleem meestal opgelost. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Je apparaat is geconfigureerd naar:</translation>
+<translation id="8066955247577885446">Er is iets misgegaan.</translation>
+<translation id="8074253406171541171">10x13 (envelop)</translation>
<translation id="8078141288243656252">Kan geen aantekeningen maken als het document is gedraaid</translation>
<translation id="8079031581361219619">Site opnieuw laden?</translation>
<translation id="8088680233425245692">Kan artikel niet bekijken.</translation>
@@ -1125,11 +1267,12 @@ Aanvullende informatie:
<translation id="8091372947890762290">Activering is in behandeling op de server</translation>
<translation id="8092774999298748321">Dieppaars</translation>
<translation id="8094917007353911263">Het is mogelijk dat je <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> moet bezoeken van het netwerk dat je gebruikt.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">De ongeldige passen zijn verwijderd</translation>
<translation id="8103161714697287722">Betaalmethode</translation>
<translation id="8118489163946903409">Betaalmethode</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> beheerd door <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">'<ph name="SOFTWARE_NAME" />' is niet correct geïnstalleerd op je computer of netwerk. Neem contact op met je IT-beheerder om dit probleem op te lossen.</translation>
-<translation id="8130693978878176684">Ik kan je niet verder helpen. Ga zelf verder.</translation>
<translation id="8131740175452115882">Bevestigen</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>
@@ -1139,8 +1282,11 @@ Aanvullende informatie:
<translation id="8197543752516192074">Pagina vertalen</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="8202370299023114387">Conflict</translation>
+<translation id="8206978196348664717">Prc4 (envelop)</translation>
<translation id="8211406090763984747">Verbinding is beveiligd</translation>
<translation id="8218327578424803826">Toegewezen locatie:</translation>
+<translation id="8220146938470311105">C7/C6 (envelop)</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="8238581221633243064">Pagina openen op een nieuw incognitotabblad</translation>
@@ -1152,14 +1298,16 @@ Aanvullende informatie:
<translation id="825929999321470778">Alle opgeslagen wachtwoorden weergeven</translation>
<translation id="8261506727792406068">Verwijderen</translation>
<translation id="8267698848189296333">Inloggen als <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Deze browser wordt beheerd door <ph name="ENROLLMENT_DOMAIN" />. Je beheerder kan je browserinstellingen op afstand wijzigen. Activiteit op dit apparaat kan ook buiten Chrome worden beheerd. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Grote foto</translation>
<translation id="8286036467436129157">Inloggen</translation>
<translation id="8288807391153049143">Certificaat weergeven</translation>
<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="8298115750975731693">Het is mogelijk dat je <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> moet bezoeken van het wifi-netwerk (<ph name="WIFI_NAME" />) dat je gebruikt.</translation>
+<translation id="8307358339886459768">Kleine foto</translation>
<translation id="8308427013383895095">De vertaling is mislukt omdat er een probleem is opgetreden met de netwerkverbinding.</translation>
-<translation id="8311129316111205805">Sessie laden</translation>
<translation id="8332188693563227489">Toegang tot <ph name="HOST_NAME" /> is geweigerd</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1177,7 +1325,6 @@ Aanvullende informatie:
<translation id="8416694386774425977">De netwerkconfiguratie is ongeldig en kan niet worden geïmporteerd.
Aanvullende informatie:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Apparaat beheerd door <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Wijzigen</translation>
<translation id="8428213095426709021">Instellingen</translation>
@@ -1204,9 +1351,11 @@ Aanvullende informatie:
<translation id="860043288473659153">Naam kaarthouder</translation>
<translation id="861775596732816396">Grootte 4</translation>
<translation id="8620436878122366504">Je ouders hebben dit nog niet goedgekeurd</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Deze pas opslaan op dit apparaat</translation>
<translation id="8663226718884576429">Besteloverzicht, <ph name="TOTAL_LABEL" />, meer informatie</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, antwoord, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Je verbinding met <ph name="DOMAIN" /> is niet gecodeerd.</translation>
<translation id="8718314106902482036">Betaling niet voltooid</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, zoeksuggestie</translation>
@@ -1220,6 +1369,7 @@ Aanvullende informatie:
<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="8763927697961133303">USB-apparaat</translation>
<translation id="8768895707659403558">Als je je passen op alle apparaten wilt gebruiken, moet je <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Opnieuw verwijderen</translation>
<translation id="8792621596287649091">Je kunt de toegang tot je account van <ph name="ORG_NAME" /> kwijtraken of slachtoffer worden van identiteitsdiefstal. Chromium raadt je aan je wachtwoord nu te wijzigen.</translation>
<translation id="8800988563907321413">Je suggesties voor in de buurt worden hier weergegeven</translation>
@@ -1230,10 +1380,12 @@ Aanvullende informatie:
<translation id="885730110891505394">Delen met Google</translation>
<translation id="8858065207712248076">Chrome raadt je aan het wachtwoord voor <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> opnieuw in te stellen als je het voor andere sites hebt hergebruikt.</translation>
<translation id="8866481888320382733">Fout bij het parseren van beleidsinstellingen</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Recent gesloten</translation>
<translation id="8874824191258364635">Geef een geldig kaartnummer op</translation>
<translation id="8891727572606052622">Ongeldige proxymodus.</translation>
<translation id="8903921497873541725">Inzoomen</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Wil je deze pas opslaan in je Google-account?</translation>
<translation id="8932102934695377596">Je klok loopt achter</translation>
<translation id="893332455753468063">Naam toevoegen</translation>
@@ -1241,13 +1393,13 @@ Aanvullende informatie:
<translation id="894185898663964645">Je beheerder heeft custom rootcertificaten geconfigureerd, waardoor de beheerder mogelijk de content kan bekijken van websites die je bezoekt.</translation>
<translation id="8943282376843390568">Limoengroen</translation>
<translation id="8957210676456822347">Autorisatie van captive portal</translation>
+<translation id="8966619695390250636">Bedoelde je?</translation>
<translation id="8968766641738584599">Pas opslaan</translation>
<translation id="8971063699422889582">Het servercertificaat is verlopen.</translation>
<translation id="8975012916872825179">Inclusief informatie als telefoonnummers, e-mailadressen en verzendadressen</translation>
<translation id="8978053250194585037">Google Safe Browsing heeft onlangs <ph name="BEGIN_LINK" />phishing gedetecteerd<ph name="END_LINK" /> op <ph name="SITE" />. Phishingsites doen zich voor als een andere website om je te misleiden.</translation>
<translation id="8983003182662520383">Betaalmethoden en adressen die Google Pay gebruiken</translation>
<translation id="8987927404178983737">Maand</translation>
-<translation id="8988408250700415532">Er is een fout opgetreden. Je kunt je bestelling afronden op de website.</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>
@@ -1257,6 +1409,7 @@ Aanvullende informatie:
<translation id="9011424611726486705">Site-instellingen openen</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Ongeldig)</translation>
<translation id="9035022520814077154">Beveiligingsfout</translation>
<translation id="9038649477754266430">Een voorspellingsservice gebruiken om pagina's sneller te laden</translation>
@@ -1268,11 +1421,11 @@ Aanvullende informatie:
<translation id="9065745800631924235">Zoekopdracht <ph name="TEXT" /> in de geschiedenis</translation>
<translation id="9069693763241529744">Geblokkeerd door een extensie</translation>
<translation id="9076283476770535406">De site kan content voor volwassenen bevatten</translation>
+<translation id="9076630408993835509">Deze browser wordt niet beheerd door een bedrijf of andere organisatie. Activiteit op dit apparaat kan buiten Chrome worden beheerd. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Meer informatie vereist</translation>
<translation id="9080712759204168376">Besteloverzicht</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 beveiligd omdat Chromium de verbinding heeft beëindigd voordat er gegevens konden worden uitgewisseld.</translation>
<translation id="9106062320799175032">Factuuradres toevoegen</translation>
-<translation id="9110718169272311511">De Google Assistent in Chrome is onderaan het scherm beschikbaar</translation>
<translation id="9114524666733003316">Creditcard bevestigen...</translation>
<translation id="9128870381267983090">Verbinding maken met netwerk</translation>
<translation id="9137013805542155359">Origineel weergeven</translation>
@@ -1281,6 +1434,7 @@ Aanvullende informatie:
<translation id="9148507642005240123">&amp;Bewerken ongedaan maken</translation>
<translation id="9154194610265714752">Bijgewerkt</translation>
<translation id="9157595877708044936">Bezig met instellen...</translation>
+<translation id="9158625974267017556">C6 (envelop)</translation>
<translation id="9168814207360376865">Toestaan dat sites controleren of je betaalmethoden hebt opgeslagen</translation>
<translation id="9169664750068251925">Altijd blokkeren op deze site</translation>
<translation id="9170848237812810038">&amp;Ongedaan maken</translation>
@@ -1295,10 +1449,12 @@ Aanvullende informatie:
<translation id="9219103736887031265">Afbeeldingen</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FORMULIER LEEGMAKEN</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Je kunt de toegang tot je Google-account kwijtraken. Chromium raadt je aan je wachtwoord nu te wijzigen. Je wordt gevraagd in te loggen op je account.</translation>
<translation id="939736085109172342">Nieuwe map</translation>
<translation id="945855313015696284">Controleer de informatie hieronder en verwijder alle ongeldige passen</translation>
<translation id="951104842009476243">Geaccepteerde betaalpassen en prepaidkaarten</translation>
+<translation id="958202389743790697">Geblokkeerd op basis van het beveiligingsbeleid van <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Deze content kan mogelijk proberen misleidende apps te installeren die zich voordoen als iets anders of gegevens verzamelen die kunnen worden gebruikt om je te volgen. <ph name="BEGIN_LINK" />Toch weergeven<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Officiële build</translation>
<translation id="973773823069644502">Afleveradres toevoegen</translation>
@@ -1307,6 +1463,7 @@ Aanvullende informatie:
<translation id="984275831282074731">Betaalmethoden</translation>
<translation id="985199708454569384">&lt;p&gt;Je ziet deze fout als de datum en tijd van je computer of mobiele apparaat niet goed zijn ingesteld.&lt;/p&gt;
&lt;p&gt;Open de klok van het apparaat om deze fout op te lossen. Zorg dat de tijd en datum juist zijn.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Ontwikkelaarsbuild</translation>
<translation id="989988560359834682">Adres bewerken</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_no.xtb b/chromium/components/strings/components_strings_no.xtb
index 23406e96a24..de4a070675a 100644
--- a/chromium/components/strings/components_strings_no.xtb
+++ b/chromium/components/strings/components_strings_no.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="no">
-<translation id="1005145902654145231">Kunne ikke gi økten nytt navn.</translation>
<translation id="1008557486741366299">Ikke nå</translation>
<translation id="1010200102790553230">Last inn siden senere</translation>
<translation id="1015730422737071372">Oppgi flere detaljer</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">ukjent navn</translation>
<translation id="1050038467049342496">Lukk andre apper</translation>
<translation id="1055184225775184556">&amp;Angre tilleggingen</translation>
+<translation id="1056898198331236512">Advarsel</translation>
<translation id="1058479211578257048">Lagrer kort …</translation>
<translation id="10614374240317010">Aldri lagret</translation>
+<translation id="1062160989074299343">Prc10 (konvolutt)</translation>
<translation id="106701514854093668">Bokmerker på datamaskinen</translation>
<translation id="1074497978438210769">Ikke sikker</translation>
<translation id="1080116354587839789">Tilpass til vindusbredden</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Legg til navnet på kortet</translation>
<translation id="1089439967362294234">Endre passord</translation>
<translation id="109743633954054152">Administrer passord i Chrome-innstillingene</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Det kan hende du ser mange advarsler mens nettstedene oppdaterer sikkerheten sin. Dette forbedres snart.</translation>
<translation id="1126551341858583091">Størrelsen på den lokale lagringsplassen er <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Bufferen for enhetsinnstillinger er OK</translation>
+<translation id="1131264053432022307">Bildet du kopierte</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Gi nytt navn</translation>
<translation id="1175364870820465910">&amp;Skriv ut...</translation>
<translation id="1181037720776840403">Fjern</translation>
<translation id="1197088940767939838">Oransje</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Navnet på enheten din</translation>
<translation id="124116460088058876">Flere språk</translation>
<translation id="1250759482327835220">For å betale raskere neste gang, lagre kortet og faktureringsadressen i Google-kontoen din.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" /> og <ph name="TYPE_2" /> (synkronisert)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variasjoner i kommandolinjen</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="1314614906530272393">Den valgte økten finnes ikke.</translation>
+<translation id="1320233736580025032">Prc1 (konvolutt)</translation>
+<translation id="132301787627749051">Søk etter bilde på utklippstavlen</translation>
<translation id="1323433172918577554">Vis mer</translation>
<translation id="132390688737681464">Lagre og fyll inn adresser</translation>
<translation id="1333989956347591814">Aktiviteten din <ph name="BEGIN_EMPHASIS" />kan fortsatt være synlig<ph name="END_EMPHASIS" /> for
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Henteadresse</translation>
<translation id="1348198688976932919">Nettstedet du er på vei til, inneholder farlige apper</translation>
<translation id="1348779747280417563">Bekreft navnet</translation>
+<translation id="1357195169723583938">Personer som har brukt enheten i det siste, og når de har gjort det</translation>
+<translation id="1364822246244961190">Denne regelen er blokkert. Regelens verdi ignoreres.</translation>
<translation id="1374468813861204354">forslagene</translation>
+<translation id="1374692235857187091">Index-4x6 (postkort)</translation>
<translation id="1375198122581997741">Om versjon</translation>
<translation id="1376836354785490390">Vis mindre</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="138218114945450791">Lyseblå</translation>
+<translation id="1382194467192730611">USB-enheten er tillatt av administratoren din</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> sendte ingen data.</translation>
+<translation id="140316286225361634">Nettstedet <ph name="ORIGIN" /> har bedt om at en sikkerhetsregel
+ skal gjelde hele forespørselen, og denne regelen anser nettstedet
+ som utrygt akkurat nå.</translation>
<translation id="1405567553485452995">Lysegrønn</translation>
<translation id="1407135791313364759">Åpne alle</translation>
<translation id="1413809658975081374">Personvernfeil</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Skriv ut</translation>
<translation id="1455413310270022028">Viskelær</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Vis mer</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Velg leveringsadresse</translation>
+<translation id="1492194039220927094">Push-levering av regler:</translation>
<translation id="1501859676467574491">Vis kredittkort fra Google-kontoen din</translation>
-<translation id="1506687042165942984">Vis en lagret kopi av denne siden (dvs. en kopi du vet at er utdatert).</translation>
<translation id="1507202001669085618">&lt;p&gt;Du ser denne feilmeldingen hvis du bruker en Wi-Fi-portal hvor du må logge på før du kommer deg på nettet.&lt;/p&gt;
&lt;p&gt;For å fikse feilen, klikk på &lt;strong&gt;Koble til&lt;/strong&gt; på siden du prøver å åpne.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Det kreves et telefonnummer</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Versjonsdato</translation>
<translation id="1521655867290435174">Google Regneark</translation>
<translation id="1527263332363067270">Venter på tilkobling …</translation>
+<translation id="1529521330346880926">10x15 (konvolutt)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">På denne siden står det</translation>
<translation id="153384715582417236">Det var alt for denne gangen</translation>
<translation id="154408704832528245">Velg leveringsadresse</translation>
<translation id="1549470594296187301">Denne funksjonen kan ikke brukes når JavaScript er slått av.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Oppgi utløpsdato</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Bildet du kopierte</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Hindre denne siden i å opprette flere dialogruter</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Avslutt økten</translation>
<translation id="1639239467298939599">Laster inn</translation>
<translation id="1640180200866533862">Brukerretningslinjer</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Tjenersertifikatet inneholder en svak kryptografisk nøkkel.</translation>
<translation id="1697532407822776718">Da er alt klart!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokumentet er for stort til å annoteres</translation>
<translation id="1721312023322545264">Du trenger tillatelse fra <ph name="NAME" /> for å besøke dette nettstedet</translation>
<translation id="1721424275792716183">* Feltet er obligatorisk</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Prøv å kontakte systemadministratoren.</translation>
<translation id="1740951997222943430">Angi en gyldig utløpsmåned</translation>
<translation id="1743520634839655729">For å betale raskere neste gang, lagre kortet og faktureringsadressen i Google-kontoen din og på denne enheten.</translation>
+<translation id="1745880797583122200">Nettleseren din administreres</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Oppdater passordfrasen for synkronisering.</translation>
<translation id="1787142507584202372">De åpne fanene dine vises her</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kortinnehaverens navn</translation>
<translation id="1821930232296380041">Ugyldig forespørsel eller forespørselsparametere</translation>
+<translation id="1822540298136254167">Nettsteder du besøker, og hvor mye tid du bruker på dem</translation>
<translation id="1826516787628120939">Kontrollerer</translation>
<translation id="1834321415901700177">Dette nettstedet inneholder skadelige programmer</translation>
<translation id="1839551713262164453">Validering av regelverdier mislyktes med feil</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Tøm nettlesingsloggen i Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{og 1 til}other{og # til}}</translation>
<translation id="2003709556000175978">Tilbakestill passordet ditt nå</translation>
+<translation id="20053308747750172">Tjeneren du er på vei til (<ph name="ORIGIN" />), har bedt om at
+ en sikkerhetsregel brukes for alle forespørsler som sendes til den. Men nå har tjeneren
+ sendt en ugyldig regel, som forhindrer nettleseren fra
+ å utføre forespørselen din til <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Mellomtjeneren er innstilt på automatisk konfigurasjon.</translation>
<translation id="2030481566774242610">Mener du <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Sjekk proxy-tjeneren og brannmuren<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departement</translation>
<translation id="2102134110707549001">Foreslå et sterkt passord…</translation>
<translation id="2108755909498034140">Start datamaskinen på nytt.</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kort</translation>
<translation id="2114841414352855701">Ignorert fordi det ble overstyrt av <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Bokmerker for mobil</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Endre kortet</translation>
<translation id="2166049586286450108">Full administratortilgang</translation>
<translation id="2166378884831602661">Dette nettstedet tilbyr ikke sikre tilkoblinger</translation>
+<translation id="2169984857010174799">Kaku2 (konvolutt)</translation>
<translation id="2181821976797666341">Retningslinjer</translation>
<translation id="2183608646556468874">Telefonnummer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresse}other{# adresser}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2283340219607151381">Lagre og fyll inn adresser</translation>
<translation id="2292556288342944218">Internett-tilgangen din er blokkert</translation>
+<translation id="2294558542833290837">Linken du opprinnelig åpnet, er uvanlig</translation>
+<translation id="2297722699537546652">B5 (konvolutt)</translation>
+<translation id="2310021320168182093">Chou2 (konvolutt)</translation>
<translation id="2316887270356262533">Frigjør mindre enn 1 MB. Det kan hende enkelte nettsteder lastes inn tregere neste gang du besøker dem.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> krever brukernavn og passord.</translation>
<translation id="2317583587496011522">Debetkort godtas.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" /> – utløper <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Innstillingen kontrolleres av administratoren din</translation>
+<translation id="2346319942568447007">Bildet du kopierte</translation>
<translation id="2349790679044093737">En VR-økt pågår</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Programstopprapporten fra <ph name="CRASH_TIME" /> ble ikke lastet opp</translation>
<translation id="2367567093518048410">Nivå</translation>
<translation id="2378238891085281592">Nå er du i privatmodus</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Tjeneren du er på vei til (<ph name="ORIGIN" />), har bedt om at
+ en sikkerhetsregel brukes for alle forespørsler som sendes til den. Men nå har tjeneren
+ ikke klart å sende en regel, og dette forhindrer nettleseren fra å utføre
+ forespørselen din til <ph name="SITE" />.</translation>
<translation id="244665789865330679">Enheten og kontoen din administreres av <ph name="ENROLLMENT_DOMAIN" />. Det betyr at administratoren kan konfigurere enheten og kontoen din eksternt.</translation>
<translation id="2463193859425327265">Endre startsiden</translation>
<translation id="2463739503403862330">Fyll ut</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Velg leveringsmåte</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Kjør Nettverksdiagnose<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Oversett denne siden</translation>
<translation id="2479410451996844060">Ugyldig nettadresse for søk.</translation>
<translation id="2482878487686419369">Varsler</translation>
<translation id="248348093745724435">Maskininnstillinger</translation>
+<translation id="2485387744899240041">Brukernavn for enheten og nettleseren din</translation>
<translation id="2491120439723279231">Tjenerens sertifikat inneholder feil.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Skann nytt kort</translation>
<translation id="2501278716633472235">Gå tilbake</translation>
<translation id="2503184589641749290">Godkjente debetkort og forhåndsbetalte kort</translation>
<translation id="2515629240566999685">Sjekk signalet i området ditt</translation>
-<translation id="2516852381693169964">Søk etter bildet på <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Kun lagret på denne enheten</translation>
<translation id="2524461107774643265">Legg til mer informasjon</translation>
<translation id="2536110899380797252">Legg til adresse</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (konvolutt)</translation>
<translation id="2625385379895617796">Klokken går for fort</translation>
<translation id="2634124572758952069">Fant ikke IP-adressen til tjeneren for <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Lukk andre faner eller apper</translation>
<translation id="267371737713284912">trykk på <ph name="MODIFIER_KEY_DESCRIPTION" /> for å angre</translation>
<translation id="2674170444375937751">Er du sikker på at du vil slette disse sidene fra loggen?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Gå ut</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Godkjente kort</translation>
<translation id="2702801445560668637">Leseliste</translation>
<translation id="2704283930420550640">Verdien samsvarer ikke med formatet.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Fjern valgte elementer</translation>
<translation id="277133753123645258">Leveringsmetode</translation>
<translation id="277499241957683684">Manglende enhetsoppføring</translation>
-<translation id="2781030394888168909">Eksportér til MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Tilkoblingen ble tilbakestilt.</translation>
<translation id="2788784517760473862">Godkjente kredittkort</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Åpne et inkognitovindu</translation>
+<translation id="2850739647070081192">Invite (konvolutt)</translation>
<translation id="2851634818064021665">Du trenger tillatelse for å besøke dette nettstedet</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Vil du lagre kortet?</translation>
<translation id="2903493209154104877">Adresser</translation>
<translation id="290376772003165898">Er ikke siden på <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Leveringsmåte</translation>
<translation id="2928905813689894207">Faktureringsadresse</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (konvolutt)</translation>
<translation id="3024663005179499861">Feil type enhetsinnstillinger</translation>
<translation id="3037605927509011580">Æsj!</translation>
<translation id="3041612393474885105">Sertifikatinformasjon</translation>
+<translation id="3060227939791841287">C9 (konvolutt)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Legg til henteadresse</translation>
<translation id="3105172416063519923">Ressurs-ID:</translation>
<translation id="3109728660330352905">Du har ikke autorisasjon til å se denne siden.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> på <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Avbryt betalingen</translation>
<translation id="3207960819495026254">Bokmerket</translation>
-<translation id="3209375525920864198">Skriv inn et gyldig øktnavn.</translation>
+<translation id="321912867715453276">Advarsel: Regelen har mer enn én kilde, men verdiene er like.</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="3229041911291329567">Versjonsinformasjon om enheten og nettleseren din</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Legg til navnet på kortet</translation>
<translation id="3287510313208355388">Last ned når du er koblet til Internett</translation>
<translation id="3293642807462928945">Finn ut mer om regelen <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Søket ga ingen treff</translation>
-<translation id="3305707030755673451">Dataene dine er kryptert med passordfrasen din for synkronisering <ph name="TIME" />. Skriv den inn for å starte synkroniseringen.</translation>
<translation id="3320021301628644560">Legg til faktureringsadresse</translation>
<translation id="3324983252691184275">Karmosinrød</translation>
<translation id="3338095232262050444">Sikker</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Endre likevel</translation>
<translation id="342781501876943858">Chromium anbefaler at du tilbakestiller passordet ditt hvis du også har brukt det på andre nettsteder.</translation>
<translation id="3431636764301398940">Lagre dette kortet på denne enheten</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Eieren av denne enheten har slått av dinosaurspillet.</translation>
<translation id="3447884698081792621">Vis sertifikat (utstedt av <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Hentingsintervall:</translation>
+<translation id="3456231139987291353">Number-11 (konvolutt)</translation>
<translation id="3461824795358126837">Markering</translation>
<translation id="3462200631372590220">Skjul detaljer</translation>
<translation id="3467763166455606212">Kortinnhaverens navn er obligatorisk</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kredittkort og forhåndsbetalte kort godtas.</translation>
<translation id="3582930987043644930">Legg til navn</translation>
<translation id="3583757800736429874">&amp;Flytt likevel</translation>
+<translation id="35866233670761917">Administratorene kan ikke se innholdet på nettsteder du besøker</translation>
<translation id="3586931643579894722">Skjul detaljer</translation>
+<translation id="3592413004129370115">Italian (konvolutt)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Størrelse 2</translation>
<translation id="3615877443314183785">Angi en gyldig utløpsdato</translation>
<translation id="36224234498066874">Slett nettleserdata</translation>
<translation id="362276910939193118">Vis fullstendig logg</translation>
-<translation id="3623476034248543066">Vis verdien</translation>
<translation id="3630155396527302611">Hvis programmet allerede har fått tillatelse til å bruke nettverket, kan du prøve
å fjerne det fra listen og så legge det til på nytt.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Valideringen var vellykket</translation>
<translation id="3655670868607891010">Hvis du ser denne meldingen ofte, kan du prøve disse <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Versjon</translation>
<translation id="366077651725703012">Oppdater kredittkortet</translation>
<translation id="3676592649209844519">Enhets-ID:</translation>
+<translation id="3677008721441257057">Mente du &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Forespørselen kunne ikke undertegnes</translation>
<translation id="3678529606614285348">Åpne siden i et nytt inkognitovindu (Ctrl + Shift + N)</translation>
<translation id="3679803492151881375">Programstopprapport generert <ph name="CRASH_TIME" /> og lastet opp <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Det kan hende at det er et krav for nettverket du bruker, at du besøker påloggingssiden for nettverket.</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="3709599264800900598">Teksten du kopierte</translation>
<translation id="3712624925041724820">Lisensene er oppbrukt</translation>
<translation id="3714780639079136834">Slå på mobildata eller Wi-Fi</translation>
<translation id="3715597595485130451">Tilkobling til Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Sjekk proxy-tjener-, brannmur- og DNS-konfigurasjonen<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Apper som kan forårsake denne feilen, omfatter programvare for antivirus, brannmur og nettfiltrering eller proxy-tjenester.</translation>
+<translation id="373042150751172459">B4 (konvolutt)</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="3745099705178523657">Etter at du har bekreftet, deles kortopplysningene fra Google-kontoen din med dette nettstedet.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Utløper <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Størrelse 16</translation>
+<translation id="3797522431967816232">Prc3 (konvolutt)</translation>
<translation id="3807873520724684969">Skadelig innhold er blokkert.</translation>
<translation id="3810973564298564668">Administrer</translation>
<translation id="382518646247711829">Hvis du bruker en mellomtjener...</translation>
<translation id="3828924085048779000">Tom passordfrase er ikke tillatt.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> har installert utvidelser for tilleggsfunksjoner. Utvidelsene har tilgang til noen av dataene dine.</translation>
<translation id="385051799172605136">Tilbake</translation>
<translation id="3858027520442213535">Oppdater dato og klokkeslett</translation>
<translation id="3884278016824448484">Motstridende enhetsidentifikator</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Spør alltid på dette nettstedet</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Dette øktnavnet finnes allerede.</translation>
<translation id="3987940399970879459">Under 1 MB</translation>
+<translation id="4008849406247176967">Advarsel: Denne regelen har mer enn én kilde med motstridende verdier.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 Like ved-nettside}other{# Like ved-nettsider}}</translation>
<translation id="4030383055268325496">&amp;Angre tilleggingen</translation>
+<translation id="4032320456957708163">Nettleseren din administreres av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Nøkkel – «<ph name="SUBKEY" />»: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (konvolutt)</translation>
<translation id="4067947977115446013">Du må angi en gyldig adresse</translation>
<translation id="4072486802667267160">Det oppsto en feil under behandlingen av bestillingen din. Prøv på nytt.</translation>
<translation id="4075732493274867456">Klienten og tjeneren støtter ingen felles SSL-protokollversjon eller -chifferserie.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Fiolett</translation>
<translation id="4165986682804962316">Nettstedsinnstillinger</translation>
<translation id="4171400957073367226">Ugyldig bekreftelsessignatur</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> element til}other{<ph name="ITEM_COUNT" /> elementer til}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (konvolutt)</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="4221630205957821124">&lt;h4&gt;Trinn 1: Logg på portalen&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Tilbakestill passordet</translation>
<translation id="4280429058323657511">, utløper <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Dette kortet er lagret i Google-kontoen din}other{Disse kortene er lagret i Google-kontoen din}}</translation>
+<translation id="42981349822642051">Vis</translation>
+<translation id="4302965934281694568">Chou3 (konvolutt)</translation>
<translation id="4305817255990598646">Bytt</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokkér (standard)</translation>
+<translation id="4318566738941496689">Navnet og nettverksadressen til enheten din</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="4340982228985273705">Denne datamaskinen er ikke registrert som administrert av en bedrift, så regelen kan bare automatisk installere utvidelser som finnes på Chrome Nettmarked. Nettadressen for Chrome Nettmarked-oppdateringen er «<ph name="CWS_UPDATE_URL" />».</translation>
<translation id="4346197816712207223">Godkjente kredittkort</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Administrer betalingsmåter…</translation>
+<translation id="4367563149485757821">Number-12 (konvolutt)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">søkeresultater</translation>
-<translation id="4406972042435603828">Administratorene dine har installert utvidelser med kraftig funksjonalitet.</translation>
<translation id="4408413947728134509">Informasjonskapsler <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Henteadresse</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="443121186588148776">Seriell port</translation>
<translation id="4432688616882109544">Enten godtok ikke <ph name="HOST_NAME" /> påloggingssertifikatet ditt, eller så ble det ikke oppgitt.</translation>
<translation id="4434045419905280838">Forgrunnsvinduer/viderekoblinger</translation>
+<translation id="4435702339979719576">postkort)</translation>
<translation id="443673843213245140">Bruk av mellomtjener er deaktivert, men det er angitt en uttrykkelig mellomtjenerkonfigurasjon.</translation>
<translation id="445100540951337728">Godkjente debetkort</translation>
+<translation id="4466881336512663640">Endringer i skjemaet går tapt. Er du sikker på at du vil fortsette?</translation>
<translation id="4482953324121162758">Dette nettstedet oversettes ikke.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Ugyldig nettadresse. Dette må være en nettadresse på standardformat, f.eks. http://example.com eller https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (konvolutt)</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="4517607026994743406">Comm-10 (konvolutt)</translation>
<translation id="4522570452068850558">Detaljer</translation>
<translation id="4524805452350978254">Administrer kort</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Prøv å slå av utvidelsene dine.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Levering</translation>
+<translation id="4579056131138995126">Personlig (konvolutt)</translation>
<translation id="4582204425268416675">Fjern kortet</translation>
<translation id="4587425331216688090">Vil du fjerne adressen fra Chrome?</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="4597348597567598915">Størrelse 8</translation>
+<translation id="4600854749408232102">C6/C5 (konvolutt)</translation>
<translation id="4646534391647090355">Gå dit nå</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="467809019005607715">Google Presentasjoner</translation>
<translation id="4690462567478992370">Slutt å bruke et ugyldig sertifikat</translation>
+<translation id="4691835149146451662">Architecture-A (konvolutt)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Tilkoblingen ble avbrutt</translation>
<translation id="471880041731876836">Du har ikke tillatelse til å besøke dette nettstedet</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Kjør Windows Nettverksdiagnose<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Last inn retningslinjer på nytt</translation>
<translation id="4728558894243024398">Plattform</translation>
+<translation id="4731967714531604179">Prc2 (konvolutt)</translation>
<translation id="4736825316280949806">Start Chromium på nytt</translation>
<translation id="473775607612524610">Oppdater</translation>
<translation id="4738601419177586157">Søkeforslag for <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Administrer passord…</translation>
<translation id="4744603770635761495">Kjørbar sti</translation>
+<translation id="4746351372139058112">Meldinger</translation>
<translation id="4750917950439032686">Informasjonen din (for eksempel passord eller kredittkortnumre) er privat når den sendes til dette nettstedet.</translation>
<translation id="4756388243121344051">&amp;Logg</translation>
<translation id="4758311279753947758">Legg til kontaktinformasjon</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Det kan hende at nettsiden på <ph name="URL" /> er midlertidig nede eller flyttet permanent til en ny nettadresse.</translation>
<translation id="4771973620359291008">Det har oppstått en ukjent feil.</translation>
<translation id="4785689107224900852">Bytt til denne fanen</translation>
-<translation id="4792143361752574037">Fikk ikke tilgang til øktfilene. Lagring til disk er for øyeblikket deaktivert. Last inn siden på nytt for å prøve igjen.</translation>
<translation id="4798078619018708837">Skriv inn utløpsdatoen og verifiseringskoden for <ph name="CREDIT_CARD" /> for å oppdatere kortopplysningene dine. Etter at du har bekreftet, deles kortopplysningene fra Google-kontoen din med dette nettstedet.</translation>
<translation id="4800132727771399293">Kontrollér utløpsdatoen og CVC-koden, og prøv igjen.</translation>
+<translation id="480334179571489655">Feil i opprinnelsesregel</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Åpne</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Ingen resultater</translation>
<translation id="4950898438188848926">Knappen for å bytte fane – trykk på Enter for å bytte til den åpne fanen, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Handlinger</translation>
-<translation id="495832697253704892">Rapportering for utvidelser</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Utvid liste</translation>
<translation id="4974590756084640048">Slå på advarsler på nytt</translation>
+<translation id="4984339528288761049">Prc5 (konvolutt)</translation>
<translation id="4989163558385430922">Se alle</translation>
<translation id="4989809363548539747">Dette programtillegget støttes ikke</translation>
-<translation id="4996230189582812866">Rapportering</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="5014174725590676422">Skjermen for første kjøring av Google-assistenten i Chrome vises</translation>
<translation id="5015510746216210676">Maskinnavn:</translation>
+<translation id="5017554619425969104">Teksten du kopierte</translation>
<translation id="5018422839182700155">Kan ikke åpne denne siden</translation>
<translation id="5019198164206649151">Ugyldig funksjonalitet for sikkerhetskopiering</translation>
<translation id="5023310440958281426">Kontrollér retningslinjene til administratoren din</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Lokal kontekst <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Tillat</translation>
<translation id="5040262127954254034">Personvern</translation>
+<translation id="5043480802608081735">Linken du kopierte</translation>
<translation id="5045550434625856497">Feil passord</translation>
<translation id="5056549851600133418">Artikler for deg</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Sjekk proxy-tjeneradressen<ph name="END_LINK" /></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="5097099694988056070">Enhetsstatistikk, som prosessor- og minnebruk</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Enheten administreres av <ph name="ENROLLMENT_DOMAIN" />, og kontoen din administreres av <ph name="ACCOUNT_DOMAIN" />. Det betyr at administratorene kan konfigurere enheten og kontoen din eksternt.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bit)</translation>
-<translation id="5128122789703661928">Økten med dette navnet er ikke gyldig for sletting.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Adminstrer adresser…</translation>
+<translation id="5138227688689900538">Vis færre</translation>
<translation id="5141240743006678641">Kryptér synkroniserte passord med Google-legitimasjonen din</translation>
<translation id="5145883236150621069">Feilkode i responsen for enhetsinnstillinger</translation>
+<translation id="515292512908731282">C4 (konvolutt)</translation>
<translation id="5159010409087891077">Åpne siden i et nytt inkognitovindu (⇧ + ⌘ + N)</translation>
<translation id="516920405563544094">Skriv inn verifiseringskoden for <ph name="CREDIT_CARD" />. Etter at du har bekreftet, deles kortopplysningene fra Google-kontoen din med dette nettstedet.</translation>
<translation id="5169827969064885044">Du kan miste tilgangen til organisasjonskontoen din eller bli utsatt for identitetstyveri. Chrome anbefaler at du endrer passordet ditt nå.</translation>
<translation id="5171045022955879922">Søk, eller skriv inn en nettadresse</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Datamaskin</translation>
<translation id="5179510805599951267">Er ikke dette <ph name="ORIGINAL_LANGUAGE" />? Rapportér denne feilen</translation>
<translation id="5190835502935405962">Bokmerkerad</translation>
-<translation id="5200263511887412697">rapportere en liste over enhetsbrukere som har logget på i det siste</translation>
+<translation id="519422657042045905">Annotering er ikke tilgjengelig</translation>
<translation id="5201306358585911203">På en innebygd side på denne siden står det</translation>
<translation id="5205222826937269299">Navn er obligatorisk</translation>
<translation id="5215116848420601511">Betalingsmåter og adresser som bruker Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-post er obligatorisk</translation>
<translation id="5230733896359313003">Leveringsadresse</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">«Koble til nettverk»</translation>
<translation id="5251803541071282808">Nettsky</translation>
+<translation id="5252000469029418751">C7 (konvolutt)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Nettverksadresser</translation>
<translation id="5285570108065881030">Vis alle lagrede passord</translation>
<translation id="5287240709317226393">Vis informasjonskapsler</translation>
<translation id="5288108484102287882">Det har oppstått advarsler under validering av regelverdier</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> av <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Velg kontaktinformasjon</translation>
<translation id="5327248766486351172">Navn</translation>
+<translation id="5329858041417644019">Nettleseren din administreres ikke</translation>
<translation id="5332219387342487447">Leveringsmetode</translation>
+<translation id="5334013548165032829">Detaljerte systemlogger</translation>
<translation id="5344579389779391559">Denne siden kan prøve å belaste deg for penger</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">«Klokken går for sent», «Klokken går for fort» eller «&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;»</translation>
<translation id="5384855140246857529">For å bruke kortene dine på alle enheter, logg på og slå på synkronisering.</translation>
<translation id="5386426401304769735">Sertifikatkjeden for dette nettstedet inneholder et sertifikat som er signert med SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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 nettleserdata</translation>
<translation id="5430298929874300616">Fjern bokmerke</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Ugyldig</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Endre likevel</translation>
+<translation id="5478437291406423475">B6/C4 (konvolutt)</translation>
<translation id="5481076368049295676">Dette innholdet kan prøve å installere farlig programvare som stjeler eller sletter informasjon, på enheten din. <ph name="BEGIN_LINK" />Vis det likevel<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Du må angi en gyldig adresse</translation>
<translation id="5490432419156082418">Adresser med mer</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Prøv å kontakte systemadministratoren din.</translation>
<translation id="549333378215107354">Størrelse 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Administrerte bokmerker</translation>
<translation id="5510766032865166053">Den kan ha blitt flyttet eller slettet.</translation>
<translation id="5523118979700054094">Navn på retningslinje</translation>
<translation id="552553974213252141">Ble tekstutdraget riktig?</translation>
+<translation id="553484882784876924">Prc6 (konvolutt)</translation>
<translation id="5540224163453853">Den forespurte artikkelen ble ikke funnet.</translation>
<translation id="5541546772353173584">Legg til e-post</translation>
<translation id="5545756402275714221">Artikler for deg</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Rediger adresse</translation>
<translation id="5598944008576757369">Velg betalingsmåte</translation>
<translation id="560412284261940334">Administrering støttes ikke</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> viderekoblet deg for mange ganger.</translation>
<translation id="5629630648637658800">Kunne ikke laste in angivelsen for enhetsinnstillinger</translation>
<translation id="5631439013527180824">Ugyldig token for enhetsadministrering</translation>
+<translation id="5632627355679805402">Dataene dine har blitt kryptert med <ph name="BEGIN_LINK" />Google-passordet<ph name="END_LINK" /> ditt siden <ph name="TIME" />. Skriv det inn for å starte synkroniseringen.</translation>
<translation id="5633066919399395251">Angripere som 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="563324245173044180">Villedende innhold er blokkert.</translation>
<translation id="5659593005791499971">E-post</translation>
+<translation id="5663614846592581799">9x11 (konvolutt)</translation>
+<translation id="5663955426505430495">Enhetsadministratoren har installert utvidelser for tilleggsfunksjoner. Utvidelsene har tilgang til noen av dataene dine.</translation>
<translation id="5675650730144413517">Denne siden fungerer ikke</translation>
+<translation id="5684874026226664614">Beklager. Denne siden kunne ikke oversettes.</translation>
<translation id="5685654322157854305">Legg til leveringsadresse</translation>
<translation id="5689199277474810259">Eksportér til JSON</translation>
<translation id="5689516760719285838">Sted</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Identiteten til dette nettstedet er ikke verifisert.</translation>
<translation id="5719499550583120431">Forhåndsbetalte kort godtas.</translation>
<translation id="5720705177508910913">Gjeldende bruker</translation>
+<translation id="5728056243719941842">C5 (konvolutt)</translation>
<translation id="5730040223043577876">Chrome anbefaler at du tilbakestiller passordet ditt hvis du også har brukt det på andre nettsteder.</translation>
<translation id="5732392974455271431">Foreldrene dine kan oppheve blokkeringen for deg</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Lagre kort i Google-kontoen din}other{Lagre kort i Google-kontoen din}}</translation>
<translation id="5763042198335101085">Angi en gyldig e-postadresse</translation>
<translation id="5765072501007116331">For å se leveringsmetoder og -krav, velg en adresse</translation>
-<translation id="5770114862687765385">Filen ser ut til å være skadet. Klikk på «Tilbakestill»-knappen for å tilbakestille økten.</translation>
<translation id="5778550464785688721">Full kontroll av MIDI-enheter</translation>
<translation id="578305955206182703">Ravgul</translation>
<translation id="57838592816432529">Kutt lyden</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>
+<translation id="5798290721819630480">Vil du forkaste endringene?</translation>
<translation id="5798683403665926540">Endre startsiden i Chrome-innstillingene</translation>
<translation id="5803412860119678065">Vil du fylle ut informasjonen knyttet til <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Tillatelser</translation>
<translation id="5810442152076338065">Tilkoblingen til <ph name="DOMAIN" /> er kryptert med en foreldet chifferserie.</translation>
<translation id="5813119285467412249">&amp;Legg til likevel</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="5860033963881614850">Av</translation>
<translation id="5863847714970149516">Den neste siden kan prøve å belaste deg for penger</translation>
<translation id="5866257070973731571">Legg til telefonnummer</translation>
<translation id="5869405914158311789">Dette nettstedet er ikke tilgjengelig</translation>
<translation id="5869522115854928033">Lagrede passord</translation>
<translation id="5887400589839399685">Kortet er lagret</translation>
-<translation id="5893718151540690985">rapportere en liste over nettverksgrensesnitt (inkludert typer og maskinvareadresser)</translation>
<translation id="5893752035575986141">Kredittkort godtas.</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="5916664084637901428">På</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vil du lagre kortet i Google-kontoen?</translation>
<translation id="5922853866070715753">Nesten ferdig</translation>
<translation id="5932224571077948991">Nettstedet viser forstyrrende eller villedende annonser</translation>
-<translation id="5939518447894949180">Tilbakestill</translation>
<translation id="5946937721014915347">Åpner <ph name="SITE_NAME" /> …</translation>
<translation id="5951495562196540101">Kan ikke registrere med en forbrukerkonto (medfølgende lisens er tilgjengelig).</translation>
<translation id="5967592137238574583">Endre kontaktinformasjonen</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Zoom ut</translation>
<translation id="5977489021191000276">Enheten administreres ikke av en administrator.</translation>
<translation id="5977976211062815271">På denne enheten</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Kan ikke åpne betalingsappen</translation>
<translation id="5989320800837274978">Verken statiske proxytjenere eller en nettadresse med .pac-skript er angitt.</translation>
<translation id="5990559369517809815">Forespørsler til tjeneren har blitt blokkert av en utvidelse.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">rapportere maskinvarestatistikk, som prosessor- og minnebruk</translation>
<translation id="6034000775414344507">Lysegrå</translation>
+<translation id="6034283069659657473">10x14 (konvolutt)</translation>
<translation id="6039846035001940113">Hvis problemet fortsetter, kan du kontakte nettstedseieren.</translation>
<translation id="6040143037577758943">Lukk</translation>
<translation id="6044573915096792553">Størrelse 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Vil du bruke kortene på alle enhetene dine?</translation>
<translation id="6059925163896151826">USB-enheter</translation>
-<translation id="6071091556643036997">Regeltypen er ugyldig.</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="6094273045989040137">Annoter</translation>
<translation id="610911394827799129">Det kan hende Google-kontoen din har andre typer nettleserlogger på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Informasjon om installerte utvidelser og programtillegg</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Frigjør mindre enn <ph name="SIZE" />. Det kan hende enkelte nettsteder lastes inn tregere neste gang du besøker dem.</translation>
<translation id="6337534724793800597">Filtrér retningslinjer etter navn</translation>
<translation id="6358450015545214790">Hva innebærer dette?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Potensielle gebyrer i sikte.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 annet forslag}other{# andre forslag}}</translation>
<translation id="6387754724289022810">For å betale raskere neste gang, lagre kortet ditt og faktureringsadressen i Google-kontoen din og på denne enheten.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Rediger bokmerket</translation>
+<translation id="6406765186087300643">C0 (konvolutt)</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="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="6434309073475700221">Forkast</translation>
+<translation id="6446163441502663861">Kahu (konvolutt)</translation>
<translation id="6446608382365791566">Legg til mer informasjon</translation>
<translation id="6447842834002726250">Informasjonskapsler</translation>
<translation id="6451458296329894277">Bekreft ny innsending av skjema</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Start Chrome på nytt</translation>
<translation id="6529602333819889595">&amp;Slett likevel</translation>
<translation id="6534179046333460208">Fysisk nett-forslag</translation>
+<translation id="6556866813142980365">Gjør om</translation>
<translation id="6563469144985748109">Administratoren din har ikke godkjent det ennå</translation>
<translation id="6569060085658103619">Du ser på en utvidelsesside</translation>
+<translation id="6578796323535178455">C2 (konvolutt)</translation>
<translation id="6579990219486187401">Lys rosa</translation>
+<translation id="6583674473685352014">B6 (konvolutt)</translation>
+<translation id="6587923378399804057">Linken du kopierte</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> administreres ikke</translation>
<translation id="6596325263575161958">Krypteringsalternativer</translation>
<translation id="6604181099783169992">Bevegelses- eller lyssensorer</translation>
+<translation id="6609880536175561541">Prc7 (konvolutt)</translation>
<translation id="6624427990725312378">Kontaktinformasjon</translation>
<translation id="6626291197371920147">Legg til et gyldig kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Søk</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Denne retningslinjen er foreldet.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Fra 1 nettsted (du blir ikke logget av Google-kontoen din)}other{Fra # nettsteder (du blir ikke logget av Google-kontoen din)}}</translation>
<translation id="6657585470893396449">Passord</translation>
+<translation id="6670613747977017428">Tilbake til trygg grunn.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Registreringstoken:</translation>
<translation id="6711464428925977395">Det er noe galt med proxy-tjeneren, eller adressen er feil.</translation>
<translation id="6723740634201835758">I Google-kontoen din</translation>
+<translation id="6738516213925468394">Dataene dine ble kryptert med <ph name="BEGIN_LINK" />passordfrasen for synkronisering<ph name="END_LINK" /> <ph name="TIME" />. Skriv den inn for å starte synkroniseringen.</translation>
<translation id="674375294223700098">Ukjent feil med tjenersertifikat.</translation>
<translation id="6744009308914054259">Mens du venter på å koble til, kan du gå til Nedlastinger for å lese artikler uten nett.</translation>
<translation id="6753269504797312559">Retningslinjeverdi</translation>
<translation id="6757797048963528358">Enheten din gikk inn i hvilemodus.</translation>
+<translation id="6768213884286397650">Hagaki (postkort)</translation>
<translation id="6778737459546443941">Forelderen din har ikke godkjent det ennå</translation>
<translation id="67862343314499040">Fiolett</translation>
+<translation id="6786747875388722282">Utvidelser</translation>
<translation id="679355240208270552">Ignorert fordi standardsøk ikke er aktivert av regel.</translation>
<translation id="681021252041861472">Obligatorisk felt</translation>
<translation id="6810899417690483278">Tilpasnings-ID</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Enhet</translation>
<translation id="6970216967273061347">Område</translation>
<translation id="6973656660372572881">Både statiske proxytjenere og en .pac-skriptnettadresse er angitt.</translation>
+<translation id="6973932557599545801">Beklager, jeg kan ikke hjelpe deg. Fortsett på egen hånd.</translation>
<translation id="6979158407327259162">Google Disk</translation>
<translation id="6979440798594660689">Kutt lyden (standard)</translation>
<translation id="6984479912851154518">Går ut av privatmodus for å betale via en ekstern app. Vil du fortsette?</translation>
<translation id="6989763994942163495">Vis avanserte innstillinger</translation>
+<translation id="6993898126790112050">6x9 (konvolutt)</translation>
<translation id="6996312675313362352">Oversett alltid <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Disse belastningene kan skje én gang eller være gjentakende, og det er ikke sikkert de er åpenbare.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Skjul</translation>
<translation id="7108819624672055576">Tillatt av en utvidelse</translation>
<translation id="7111012039238467737">(Gyldig)</translation>
+<translation id="7118618213916969306">Søk etter nettadressen <ph name="SHORT_URL" /> på utklippstavlen</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="7135130955892390533">Vis statusen</translation>
<translation id="7138472120740807366">Leveringsmetode</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (konvolutt)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendel</translation>
-<translation id="7158980942472052083">Ugyldig nettadresse. Dette må være en nettadresse på standardformat.</translation>
<translation id="717330890047184534">Gaia-ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Tjeneren du er på vei til (<ph name="ORIGIN" />), har bedt om at
+ en sikkerhetsregel brukes for alle forespørsler som sendes til den. Men i stedet for
+ å sende en regel har tjeneren viderekoblet nettleseren, og dette forhindrer
+ nettleseren fra å utføre forespørselen din til <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Lagre, og fyll ut betalingsmåter</translation>
<translation id="7180611975245234373">Last inn på nytt</translation>
<translation id="7182878459783632708">Ingen retningslinjer er angitt</translation>
<translation id="7186367841673660872">Denne siden har blitt oversatt fra<ph name="ORIGINAL_LANGUAGE" />til<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Frigjør <ph name="SIZE" />. Det kan hende noen nettsteder lastes inn tregere neste gang du besøker dem.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administratoren kan se dette:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> retter seg ikke etter sikkerhetsstandardene.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Mer informasjon<ph name="END_LINK" /> om dette problemet.</translation>
<translation id="7219179957768738017">Tilkoblingen bruker <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Behandler</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Nettstedet du er på vei til, inneholder skadelig programvare</translation>
+<translation id="724766306220616965">Advarsler, konflikt</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="7251437084390964440">Nettverkskonfigurasjonen overholder ikke ONC-standarden. Deler av konfigurasjonen kan muligens ikke importeres. Mer informasjon:
<ph name="DEBUG_INFO" /></translation>
@@ -981,11 +1119,14 @@
<translation id="7300012071106347854">Koboltblå</translation>
<translation id="7302712225291570345">«<ph name="TEXT" />»</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="7313965965371928911"><ph name="BEGIN_LINK" />Safe Browsing<ph name="END_LINK" />-advarsler</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Tilkoblingshjelp</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Kommandolinje </translation>
-<translation id="7365061714576910172">Eksportér til Linux</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>
@@ -993,6 +1134,7 @@
<translation id="7381288752349550461">Overstyring av administrert økt</translation>
<translation id="7390545607259442187">Bekreft kortet</translation>
<translation id="7400418766976504921">Nettadresse</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> administreres</translation>
<translation id="7407424307057130981">&lt;p&gt;Du ser denne feilen hvis du har Superfish-programvare på Windows-datamaskinen din.&lt;/p&gt;
&lt;p&gt;Følg disse trinnene for å deaktivere programvaren midlertidig, sånn at du kan komme deg på nettet. Du må ha administratorrettigheter.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@
&lt;li&gt;Klikk på &lt;strong&gt;Bruk&lt;/strong&gt; og deretter på &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Gå til &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;brukerstøtten for Chrome&lt;/a&gt; for å finne ut hvordan du fjerner programvaren fra datamaskinen permanent.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" />-administrering</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Administrer passord…</translation>
<translation id="7419106976560586862">Profilbane</translation>
<translation id="7437289804838430631">Legg til kontaktinformasjon</translation>
@@ -1012,22 +1154,24 @@
<translation id="7442725080345379071">Lys oransje</translation>
<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="7449109375006139765">sende systemlogger til administrasjonstjeneren</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="7460618730930299168">Fremvisningen er forskjellig fra den du har valgt. Vil du fortsette?</translation>
<translation id="7473891865547856676">Nei takk</translation>
-<translation id="7475525192983021547">rapportere tidsperioder med brukeraktivitet på enheten</translation>
<translation id="7481312909269577407">Frem</translation>
<translation id="7485870689360869515">Ingen data ble funnet.</translation>
+<translation id="7498234416455752244">Fortsett å endre</translation>
<translation id="7508255263130623398">Den returnerte enhets-ID-en for regelen er tom eller samsvarer ikke med den faktiske enhets-ID-en</translation>
<translation id="7508870219247277067">Avokadogrønn</translation>
<translation id="7511955381719512146">Det kan hende at Wi-Fi-nettverket du bruker, krever at du besøker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Last ned</translation>
<translation id="7518003948725431193">Finner ingen nettside for denne nettadressen: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (konvolutt)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Tilkoblingen til dette nettstedet er ikke privat</translation>
+<translation id="7535087603100972091">Verdi</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7538364083937897561">A2 (konvolutt)</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>
@@ -1036,8 +1180,8 @@
<translation id="7552846755917812628">Prøv følgende tips:</translation>
<translation id="7554791636758816595">Ny fane</translation>
<translation id="7564049878696755256">Du kan miste tilgangen til <ph name="ORG_NAME" />-kontoen din eller bli utsatt for identitetstyveri. Chrome anbefaler at du endrer passordet ditt nå.</translation>
-<translation id="7566125604157659769">Tekst du har kopiert</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="7568105740864181217">Denne nettleseren administreres av et selskap, en skole eller en annen organisasjon. Administratoren kan endre nettleseroppsettet eksternt. Aktiviteten på denne enheten kan også administreres utenfor Chrome. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></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>
@@ -1048,6 +1192,7 @@
<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="7633909222644580952">Ytelsesdata og programstopprapporter</translation>
<translation id="7637571805876720304">Vil du fjerne kredittkortet fra Chromium?</translation>
<translation id="7639968568612851608">Mørk grå</translation>
<translation id="765676359832457558">Skjul avanserte innstillinger</translation>
@@ -1057,9 +1202,11 @@
<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="7676643023259824263">Søk etter teksten <ph name="TEXT" /> på utklippstavlen</translation>
<translation id="7681101578153515023">Endre søkemotoren</translation>
<translation id="7682287625158474539">Forsendelse</translation>
<translation id="7687186412095877299">Fyll ut betalingsskjemaer med de lagrede betalingsmåtene dine</translation>
+<translation id="7697066736081121494">Prc8 (konvolutt)</translation>
<translation id="769721561045429135">Akkurat nå har du kort som bare kan brukes på denne enheten. Klikk på Fortsett for å gå gjennom kortene.</translation>
<translation id="7699293099605015246">Artikler er ikke tilgjengelige for øyeblikket</translation>
<translation id="7701040980221191251">Ingen</translation>
@@ -1071,11 +1218,13 @@
<translation id="774634243536837715">Farlig innhold er blokkert.</translation>
<translation id="7752995774971033316">Administreres ikke</translation>
<translation id="7755287808199759310">Forelderen din kan oppheve blokkeringen for deg</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Brannmur- eller antivirusprogramvare kan ha blokkert tilkoblingen.</translation>
<translation id="7759163816903619567">Visningsdomene:</translation>
<translation id="7761701407923456692">Tjenerens sertifikat samsvarer ikke med nettadressen.</translation>
<translation id="7763386264682878361">Parser for betalingsmanifest</translation>
<translation id="7764225426217299476">Legg til adresse</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Legg til</translation>
<translation id="7793809570500803535">Det kan hende at nettsiden på <ph name="SITE" /> er midlertidig nede eller flyttet permanent til en ny nettadresse.</translation>
@@ -1087,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Vil du fjerne skjemaforslaget fra Chrome?</translation>
<translation id="7815407501681723534">Fant <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> for «<ph name="SEARCH_STRING" />»</translation>
-<translation id="7818867226424560206">Administrasjon av retningslinjer</translation>
<translation id="782886543891417279">Det kan hende at Wi-Fi-nettverket du bruker (<ph name="WIFI_NAME" />), krever at du besøker en påloggingsside.</translation>
+<translation id="7836231406687464395">Postfix (konvolutt)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ingen}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apper (<ph name="EXAMPLE_APP_1" /> og <ph name="EXAMPLE_APP_2" />)}other{# apper (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Du er imidlertid ikke usynlig. Inkognitomodus skjuler ikke surfingen din for arbeidsgiveren din, Internett-leverandøren eller nettstedene du besøker.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@
<translation id="7878562273885520351">Passordet ditt kan være kompromittert</translation>
<translation id="7882421473871500483">Brun</translation>
<translation id="7887683347370398519">Kontrollér CVC-koden din, og prøv igjen.</translation>
-<translation id="7893255318348328562">Øktnavn</translation>
+<translation id="7904208859782148177">C3 (konvolutt)</translation>
<translation id="79338296614623784">Angi et gyldig telefonnummer</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Utløper <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@
<translation id="7951415247503192394">(32-bit)</translation>
<translation id="7956713633345437162">Bokmerker for mobil</translation>
<translation id="7961015016161918242">Aldri</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Ikke spesifisert</translation>
<translation id="800218591365569300">Prøv å lukke andre faner eller programmer for å frigjøre minne.</translation>
+<translation id="8004582292198964060">Nettleser</translation>
<translation id="8009225694047762179">Administrer passord</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Dette kortet og den tilknyttede faktureringsadressen lagres. Du kan bruke det når du er logget på <ph name="USER_EMAIL" />.}other{Disse kortene og de tilknyttede faktureringsadressene lagres. Du kan bruke dem når du er logget på <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Denne siden er på <ph name="SOURCE_LANGUAGE" />. Vil du oversette den til <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Penn</translation>
+<translation id="8037117624646282037">Personer som har brukt enheten i det siste</translation>
<translation id="8037357227543935929">Spør (standard)</translation>
<translation id="803771048473350947">Fil</translation>
<translation id="8041089156583427627">Send tilbakemelding</translation>
<translation id="8041940743680923270">Bruk global standardinnstilling (Spør)</translation>
<translation id="8042918947222776840">Velg hentemåte</translation>
<translation id="8057711352706143257">«<ph name="SOFTWARE_NAME" />» er ikke riktig konfigurert. Avinstallering av «<ph name="SOFTWARE_NAME" />» løser vanligvis problemet. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Enheten din er konfigurert til å</translation>
+<translation id="8066955247577885446">Beklager, noe gikk galt.</translation>
+<translation id="8074253406171541171">10x13 (konvolutt)</translation>
<translation id="8078141288243656252">Kan ikke legge til annoteringer når dokumentet er rotert</translation>
<translation id="8079031581361219619">Vil du laste inn nettstedet på nytt?</translation>
<translation id="8088680233425245692">Kunne ikke åpne artikkelen.</translation>
@@ -1130,11 +1283,12 @@
<translation id="8091372947890762290">Aktivering venter på tjeneren</translation>
<translation id="8092774999298748321">Mørk fiolett</translation>
<translation id="8094917007353911263">Det kan hende at nettverket du bruker, krever at du besøker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">De ugyldige kortene er fjernet</translation>
<translation id="8103161714697287722">Betalingsmåte</translation>
<translation id="8118489163946903409">Betalingsmåte</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> administreres av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">«<ph name="SOFTWARE_NAME" />» er ikke riktig installert på datamaskinen eller på nettverket. Be IT-administratoren din om å løse problemet.</translation>
-<translation id="8130693978878176684">Jeg kan ikke hjelpe deg lenger. Fortsett på egen hånd.</translation>
<translation id="8131740175452115882">Bekreft</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>
@@ -1144,8 +1298,11 @@
<translation id="8197543752516192074">Oversett siden</translation>
<translation id="8201077131113104583">Ugyldig oppdaterings-URL for utvidelse med ID «<ph name="EXTENSION_ID" />».</translation>
<translation id="8202097416529803614">Bestillingssammendrag</translation>
+<translation id="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (konvolutt)</translation>
<translation id="8211406090763984747">Tilkoblingen er sikker</translation>
<translation id="8218327578424803826">Tilordnet posisjon:</translation>
+<translation id="8220146938470311105">C7/C6 (konvolutt)</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="8238581221633243064">Åpne siden i et nytt inkognitovindu</translation>
@@ -1157,21 +1314,23 @@
<translation id="825929999321470778">Vis alle lagrede passord</translation>
<translation id="8261506727792406068">Slett</translation>
<translation id="8267698848189296333">Logger på som <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Denne nettleseren administreres av <ph name="ENROLLMENT_DOMAIN" />. Administratoren kan endre nettleseroppsettet eksternt. Aktiviteten på denne enheten kan også administreres utenfor Chrome. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Logg på</translation>
<translation id="8288807391153049143">Vis sertifikat</translation>
<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="8298115750975731693">Det kan hende at Wi-Fi-nettverket du bruker (<ph name="WIFI_NAME" />), krever at du besøker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Oversettelsen mislyktes på grunn av et problem med nettverksforbindelsen.</translation>
-<translation id="8311129316111205805">Last inn økten</translation>
<translation id="8332188693563227489">Forsøket på å koble til <ph name="HOST_NAME" /> ble avvist</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
<translation id="8349305172487531364">Bokmerkerad</translation>
<translation id="8363502534493474904">Slå av flymodus</translation>
<translation id="8364627913115013041">Ikke angitt.</translation>
-<translation id="8368476060205742148">Google Play Tjenester</translation>
+<translation id="8368476060205742148">Google Play-tjenester</translation>
<translation id="8371889962595521444">Tilpassede rotsertifikater</translation>
<translation id="8380941800586852976">Farlig</translation>
<translation id="8381674639488873545">Disse belastningene kan skje én gang eller være gjentakende, og det er ikke sikkert de er åpenbare. <ph name="BEGIN_LINK" />Vis likevel<ph name="END_LINK" /></translation>
@@ -1182,7 +1341,6 @@
<translation id="8416694386774425977">Nettverkskonfigurasjonen er ugyldig og kan ikke importeres.
Mer informasjon:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Enheten administreres av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Endre</translation>
<translation id="8428213095426709021">Innstillinger</translation>
@@ -1209,9 +1367,11 @@ Mer informasjon:
<translation id="860043288473659153">Kortinnehavers navn</translation>
<translation id="861775596732816396">Størrelse 4</translation>
<translation id="8620436878122366504">Foreldrene dine har ikke godkjent det ennå</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Lagre dette kortet på denne enheten</translation>
<translation id="8663226718884576429">Bestillingssammendrag, <ph name="TOTAL_LABEL" />, mer informasjon</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, svar, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Tilkoblingen til <ph name="DOMAIN" /> er ikke kryptert.</translation>
<translation id="8718314106902482036">Betalingen er ikke fullført</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, søkeforslag</translation>
@@ -1225,6 +1385,7 @@ Mer informasjon:
<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="8763927697961133303">USB-enhet</translation>
<translation id="8768895707659403558">For å bruke kortene dine på alle enhetene dine, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Slett likevel</translation>
<translation id="8792621596287649091">Du kan miste tilgangen til <ph name="ORG_NAME" />-kontoen din eller bli utsatt for identitetstyveri. Chromium anbefaler at du endrer passordet ditt nå.</translation>
<translation id="8800988563907321413">Forslagene dine om ting like ved vises her</translation>
@@ -1235,10 +1396,12 @@ Mer informasjon:
<translation id="885730110891505394">Deling med Google</translation>
<translation id="8858065207712248076">Chrome anbefaler at du tilbakestiller passordet ditt for <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> hvis du også har brukt det på andre nettsteder.</translation>
<translation id="8866481888320382733">Analysefeil i angivelsen av enhetrsinnstillinger</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nylig lukket</translation>
<translation id="8874824191258364635">Angi et gyldig kortnummer</translation>
<translation id="8891727572606052622">Ugyldig modus for mellomtjener.</translation>
<translation id="8903921497873541725">Zoom inn</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Legg til navn</translation>
@@ -1246,13 +1409,13 @@ Mer informasjon:
<translation id="894185898663964645">Administratoren din har konfigurert tilpassede rotsertifikater, noe som betyr at vedkommende kanskje kan se innholdet på nettsteder du besøker.</translation>
<translation id="8943282376843390568">Limegrønn</translation>
<translation id="8957210676456822347">Captive Portal-autorisasjon</translation>
+<translation id="8966619695390250636">Mente du dette?</translation>
<translation id="8968766641738584599">Lagre kortet</translation>
<translation id="8971063699422889582">Tjenerens sertifikat er utløpt.</translation>
<translation id="8975012916872825179">Inkluderer informasjon som telefonnumre, e-postadresser og leveringsadresser</translation>
<translation id="8978053250194585037">Google Safe Browsing <ph name="BEGIN_LINK" />oppdaget nylig nettfisking<ph name="END_LINK" /> på <ph name="SITE" />. Nettsteder for nettfisking er laget for å ligne på andre nettsteder, for å prøve å lure deg.</translation>
<translation id="8983003182662520383">Betalingsmåter og adresser som bruker Google Pay</translation>
<translation id="8987927404178983737">Måned</translation>
-<translation id="8988408250700415532">Noe gikk galt. Du kan fullføre bestillingen din på nettstedet.</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>
@@ -1262,6 +1425,7 @@ Mer informasjon:
<translation id="9011424611726486705">Åpne nettstedsinnstillinger</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Ugyldig)</translation>
<translation id="9035022520814077154">Sikkerhetsfeil</translation>
<translation id="9038649477754266430">Bruk en prediksjonstjeneste for å laste inn sider raskere</translation>
@@ -1273,11 +1437,11 @@ Mer informasjon:
<translation id="9065745800631924235"><ph name="TEXT" />-søk fra loggen</translation>
<translation id="9069693763241529744">Blokkert av en utvidelse</translation>
<translation id="9076283476770535406">Det kan ha voksent innhold</translation>
+<translation id="9076630408993835509">Denne nettleseren administreres ikke av et selskap eller en annen organisasjon. Aktiviteten på denne enheten kan administreres utenfor Chrome. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Mer informasjon er nødvendig</translation>
<translation id="9080712759204168376">Bestillingssammendrag</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>
<translation id="9106062320799175032">Legg til faktureringsadresse</translation>
-<translation id="9110718169272311511">Du finner Google-assistenten i Chrome på nedre del av skjermen.</translation>
<translation id="9114524666733003316">Bekrefter kortet …</translation>
<translation id="9128870381267983090">Koble til nettverk</translation>
<translation id="9137013805542155359">Vis original</translation>
@@ -1286,6 +1450,7 @@ Mer informasjon:
<translation id="9148507642005240123">&amp;Angre endringen</translation>
<translation id="9154194610265714752">Oppdatert</translation>
<translation id="9157595877708044936">Konfigurerer ...</translation>
+<translation id="9158625974267017556">C6 (konvolutt)</translation>
<translation id="9168814207360376865">Tillatt nettsteder å sjekke om du har noen lagrede betalingsmåter</translation>
<translation id="9169664750068251925">Blokkér alltid på dette nettstedet</translation>
<translation id="9170848237812810038">&amp;Angre</translation>
@@ -1300,10 +1465,12 @@ Mer informasjon:
<translation id="9219103736887031265">Bilder</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">SLETT INNHOLDET I SKJEMAET</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Du kan miste tilgangen til Google-kontoen din. Chromium anbefaler at du endrer passordet ditt nå. Du blir bedt om å logge på.</translation>
<translation id="939736085109172342">Ny mappe</translation>
<translation id="945855313015696284">Gå gjennom informasjonen nedenfor, og slett eventuelle ugyldige kort</translation>
<translation id="951104842009476243">Godkjente debetkort og forhåndsbetalte kort</translation>
+<translation id="958202389743790697">Blokkert i samsvar med sikkerhetsregelen for <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Dette innholdet kan prøve å installere villedende apper som gir seg ut for å være noe annet, eller samle inn data som kan brukes til å spore deg. <ph name="BEGIN_LINK" />Vis det likevel<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Offisiell delversjon</translation>
<translation id="973773823069644502">Legg til leveringsadresse</translation>
@@ -1312,6 +1479,7 @@ Mer informasjon:
<translation id="984275831282074731">Betalingsmåter</translation>
<translation id="985199708454569384">&lt;p&gt;Du ser denne feilen hvis du har feil dato eller klokkeslett på datamaskinen eller mobilenheten din.&lt;/p&gt;
&lt;p&gt;For å fikse feilen, åpne klokken på enheten, og sørg for at klokkeslettet og datoen er riktig.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Utviklerversjon</translation>
<translation id="989988560359834682">Rediger adresse</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_pl.xtb b/chromium/components/strings/components_strings_pl.xtb
index 0d453531c18..78a1417061e 100644
--- a/chromium/components/strings/components_strings_pl.xtb
+++ b/chromium/components/strings/components_strings_pl.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pl">
-<translation id="1005145902654145231">Nie udało się zmienić nazwy sesji.</translation>
<translation id="1008557486741366299">Nie teraz</translation>
<translation id="1010200102790553230">Wczytaj stronę później</translation>
<translation id="1015730422737071372">Podaj dodatkowe informacje</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nieznana nazwa</translation>
<translation id="1050038467049342496">Zamknij inne aplikacje</translation>
<translation id="1055184225775184556">&amp;Cofnij dodanie</translation>
+<translation id="1056898198331236512">Ostrzeżenie</translation>
<translation id="1058479211578257048">Zapisuję karty…</translation>
<translation id="10614374240317010">Nigdy nie zapisane</translation>
+<translation id="1062160989074299343">Prc10 (koperta)</translation>
<translation id="106701514854093668">Zakładki na komputerze</translation>
<translation id="1074497978438210769">Niezabezpieczona</translation>
<translation id="1080116354587839789">Dopasuj do szerokości</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Dodaj imię i nazwisko z karty</translation>
<translation id="1089439967362294234">Zmień hasło</translation>
<translation id="109743633954054152">Hasłami możesz zarządzać w ustawieniach Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Ostrzeżenia mogą pojawiać się często, dopóki strony internetowe nie zaktualizują swoich zabezpieczeń. Wkrótce powinno się to poprawić.</translation>
<translation id="1126551341858583091">Rozmiar w pamięci lokalnej: <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Pamięć podręczna zasad: OK</translation>
+<translation id="1131264053432022307">Skopiowany obraz</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Zmień nazwę</translation>
<translation id="1175364870820465910">&amp;Drukuj...</translation>
<translation id="1181037720776840403">Usuń</translation>
<translation id="1197088940767939838">Pomarańczowy</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Nazwa urządzenia</translation>
<translation id="124116460088058876">Więcej języków</translation>
<translation id="1250759482327835220">Aby następnym razem zapłacić szybciej, zapisz kartę oraz imię, nazwisko i adres rozliczeniowy na swoim koncie Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (zsynchronizowane)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Odmiany w wierszu poleceń</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="1314614906530272393">Wybrana sesja nie istnieje.</translation>
+<translation id="1320233736580025032">Prc1 (koperta)</translation>
+<translation id="132301787627749051">Wyszukaj obraz ze schowka</translation>
<translation id="1323433172918577554">Pokaż więcej</translation>
<translation id="132390688737681464">Zapisuj i automatycznie uzupełniaj adresy</translation>
<translation id="1333989956347591814">Twoja aktywność <ph name="BEGIN_EMPHASIS" />może być nadal widoczna<ph name="END_EMPHASIS" /> dla:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Adres odbioru</translation>
<translation id="1348198688976932919">Strona, którą chcesz otworzyć, zawiera niebezpieczne aplikacje</translation>
<translation id="1348779747280417563">Potwierdź nazwę</translation>
+<translation id="1357195169723583938">Kto i kiedy ostatnio używał urządzenia</translation>
+<translation id="1364822246244961190">Ta zasada jest zablokowana. Jej wartość będzie ignorowana.</translation>
<translation id="1374468813861204354">sugestie</translation>
+<translation id="1374692235857187091">Index-4x6 (pocztówka)</translation>
<translation id="1375198122581997741">Informacje o wersji</translation>
<translation id="1376836354785490390">Pokaż mniej</translation>
<translation id="1377321085342047638">Numer karty</translation>
<translation id="138218114945450791">Jasnoniebieski</translation>
+<translation id="1382194467192730611">Urządzenie USB dozwolone przez administratora</translation>
<translation id="139305205187523129">Serwer <ph name="HOST_NAME" /> nie wysłał żadnych danych.</translation>
+<translation id="140316286225361634">Strona <ph name="ORIGIN" /> zażądała stosowania zasady bezpieczeństwa
+ do wszystkich jej żądań, a obecnie według tej zasady
+ strona jest uznawana za niebezpieczną.</translation>
<translation id="1405567553485452995">Jasnozielony</translation>
<translation id="1407135791313364759">Otwórz wszystkie</translation>
<translation id="1413809658975081374">Błąd dotyczący prywatności</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Tak</translation>
<translation id="1430915738399379752">Drukuj</translation>
<translation id="1455413310270022028">Gumka</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Pokaż więcej</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Wybierz adres wysyłki</translation>
+<translation id="1492194039220927094">Przekazywanie zasad w trybie push:</translation>
<translation id="1501859676467574491">Pokaż karty z konta Google</translation>
-<translation id="1506687042165942984">Pokaż zapisaną (tzn. nieaktualną) kopię tej strony.</translation>
<translation id="1507202001669085618">&lt;p&gt;Ten komunikat pojawia się, jeśli do połączenia z internetem wymagane jest zalogowanie się w portalu Wi-Fi.&lt;/p&gt;
&lt;p&gt;Aby naprawić błąd, kliknij &lt;strong&gt;Połącz&lt;/strong&gt; na stronie, którą chcesz otworzyć.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Numer telefonu jest wymagany</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Data kompilacji</translation>
<translation id="1521655867290435174">Arkusze Google</translation>
<translation id="1527263332363067270">Czekam na połączenie…</translation>
+<translation id="1529521330346880926">10x15 (koperta)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Komunikat z bieżącej strony</translation>
<translation id="153384715582417236">Na razie to wszystko</translation>
<translation id="154408704832528245">Wybierz adres dostawy</translation>
<translation id="1549470594296187301">Aby można było korzystać z tej funkcji, musi być włączony JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Wpisz datę ważności</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Skopiowany obraz</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Zapobiegaj wyświetlaniu dodatkowych okien dialogowych na tej stronie</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Zakończ sesję</translation>
<translation id="1639239467298939599">Wczytuję</translation>
<translation id="1640180200866533862">Zasady dotyczące użytkowników</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Certyfikat serwera ma słaby klucz kryptograficzny.</translation>
<translation id="1697532407822776718">Wszystko gotowe.</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument jest za duży i nie można dodawać do niego adnotacji</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Skontaktuj się z administratorem systemu.</translation>
<translation id="1740951997222943430">Wpisz miesiąc w prawidłowym formacie</translation>
<translation id="1743520634839655729">Aby następnym razem zapłacić szybciej, zapisz kartę oraz imię, nazwisko i adres rozliczeniowy na swoim koncie Google i na tym urządzeniu.</translation>
+<translation id="1745880797583122200">Twoja przeglądarka jest zarządzana</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Zaktualizuj swoje hasło synchronizacji.</translation>
<translation id="1787142507584202372">Tutaj pojawiają się otwarte karty</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Imię i nazwisko posiadacza karty</translation>
<translation id="1821930232296380041">Nieprawidłowe żądanie lub jego parametry</translation>
+<translation id="1822540298136254167">Odwiedzone strony internetowe i spędzony na nich czas</translation>
<translation id="1826516787628120939">Sprawdzam</translation>
<translation id="1834321415901700177">Ta strona zawiera szkodliwe programy</translation>
<translation id="1839551713262164453">Weryfikacja wartości zasad nie udała się z powodu błędów</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Wyczyść dane historii przeglądania Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{i jeszcze 1}few{i jeszcze #}many{i jeszcze #}other{i jeszcze #}}</translation>
<translation id="2003709556000175978">Zresetuj teraz swoje hasło</translation>
+<translation id="20053308747750172">Serwer <ph name="ORIGIN" />, z którym chcesz się połączyć, zażądał stosowania
+ zasady bezpieczeństwa do wszystkich swoich żądań. Teraz dostarczył jednak
+ nieprawidłową zasadę, która uniemożliwia przeglądarce
+ zrealizowanie Twojego żądania dotyczącego strony <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Ustawiono automatyczne konfigurowanie proxy.</translation>
<translation id="2030481566774242610">Czy chodziło Ci o <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Sprawdź serwer proxy i zaporę sieciową<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departament</translation>
<translation id="2102134110707549001">Zaproponuj silne hasło…</translation>
<translation id="2108755909498034140">Uruchom ponownie komputer</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Karta</translation>
<translation id="2114841414352855701">Ignorowana, ponieważ jest zastąpiona przez <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Zakładki na komórce</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (koperta)</translation>
<translation id="2181821976797666341">Zasady</translation>
<translation id="2183608646556468874">Numer telefonu</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}few{# adresy}many{# adresów}other{# adresu}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Numer telefonu</translation>
<translation id="2283340219607151381">Zapisuj i automatycznie uzupełniaj adresy</translation>
<translation id="2292556288342944218">Masz zablokowany dostęp do internetu</translation>
+<translation id="2294558542833290837">Link, który chcesz otworzyć, wygląda nietypowo</translation>
+<translation id="2297722699537546652">B5 (koperta)</translation>
+<translation id="2310021320168182093">Chou2 (koperta)</translation>
<translation id="2316887270356262533">Zwolni się mniej niż 1 MB. Podczas następnej wizyty niektóre strony mogą ładować się wolniej.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> wymaga nazwy użytkownika i hasła.</translation>
<translation id="2317583587496011522">Karty debetowe są akceptowane.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, ważna do <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Ustawienie kontrolowane przez administratora</translation>
+<translation id="2346319942568447007">Skopiowany obraz</translation>
<translation id="2349790679044093737">Włączona jest sesja VR</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Jesteś w trybie prywatnym</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Serwer <ph name="ORIGIN" />, z którym chcesz się połączyć, zażądał stosowania
+ zasady bezpieczeństwa do wszystkich swoich żądań. Jednak nie dostarczył zasad,
+ co uniemożliwia przeglądarce zrealizowanie
+ Twojego żądania dotyczącego strony <ph name="SITE" />.</translation>
<translation id="244665789865330679">Twoim urządzeniem i kontem zarządza <ph name="ENROLLMENT_DOMAIN" />. Oznacza to, że administrator może zdalnie konfigurować Twoje urządzenie i konto.</translation>
<translation id="2463193859425327265">Zmień stronę główną</translation>
<translation id="2463739503403862330">Wpisz</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Wybierz metodę dostawy</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Uruchom diagnostykę sieci<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Przetłumacz tę stronę</translation>
<translation id="2479410451996844060">Nieprawidłowy URL wyszukiwania</translation>
<translation id="2482878487686419369">Powiadomienia</translation>
<translation id="248348093745724435">Zasady dotyczące komputera</translation>
+<translation id="2485387744899240041">Nazwy użytkownika z urządzenia i przeglądarki</translation>
<translation id="2491120439723279231">Certyfikat serwera zawiera błędy.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Zeskanuj nową kartę</translation>
<translation id="2501278716633472235">Wróć</translation>
<translation id="2503184589641749290">Akceptowane karty debetowe i przedpłacone</translation>
<translation id="2515629240566999685">Sprawdź sygnał w swojej okolicy</translation>
-<translation id="2516852381693169964">Wyszukaj obraz w: <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Zapisana tylko na tym urządzeniu</translation>
<translation id="2524461107774643265">Dodaj więcej informacji</translation>
<translation id="2536110899380797252">Dodaj adres</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (koperta)</translation>
<translation id="2625385379895617796">Twój zegar się śpieszy</translation>
<translation id="2634124572758952069">Nie udało się znaleźć adresu IP serwera ze stroną <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Stan:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Zamknij inne karty lub aplikacje</translation>
<translation id="267371737713284912">naciśnij <ph name="MODIFIER_KEY_DESCRIPTION" />, by cofnąć</translation>
<translation id="2674170444375937751">Czy na pewno chcesz usunąć te strony z historii?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Wyjdź</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Akceptowane karty</translation>
<translation id="2702801445560668637">Do przeczytania</translation>
<translation id="2704283930420550640">Wartość nie pasuje do formatu.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Usuń wybrane elementy</translation>
<translation id="277133753123645258">Metoda wysyłki</translation>
<translation id="277499241957683684">Brak rekordu urządzenia</translation>
-<translation id="2781030394888168909">Eksportuj (MacOS)</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Połączenie zostało zresetowane.</translation>
<translation id="2788784517760473862">Akceptowane karty kredytowe</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Otwórz okno incognito</translation>
+<translation id="2850739647070081192">Invite (koperta)</translation>
<translation id="2851634818064021665">Musisz mieć pozwolenie, by wejść na tę stronę</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Czy zapisać kartę?</translation>
<translation id="2903493209154104877">Adresy</translation>
<translation id="290376772003165898">Język tej strony to nie <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Metoda dostawy</translation>
<translation id="2928905813689894207">Adres rozliczeniowy</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}few{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}many{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" />}}</translation>
+<translation id="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (koperta)</translation>
<translation id="3024663005179499861">Nieprawidłowy typ zasady</translation>
<translation id="3037605927509011580">Kurza twarz!</translation>
<translation id="3041612393474885105">Informacje o certyfikacie</translation>
+<translation id="3060227939791841287">C9 (koperta)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Dodaj adres odbioru</translation>
<translation id="3105172416063519923">Identyfikator zasobu:</translation>
<translation id="3109728660330352905">Nie masz uprawnień do wyświetlania tej strony.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na serwerze <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Anuluj płatność</translation>
<translation id="3207960819495026254">Dodano do zakładek</translation>
-<translation id="3209375525920864198">Wpisz prawidłową nazwę sesji.</translation>
+<translation id="321912867715453276">Ostrzeżenie: dla tej zasady określono więcej niż jedno źródło, ale wartości tych źródeł są jednakowe.</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="3229041911291329567">Informacje o wersji urządzenia i przeglądarki</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Dodaj imię i nazwisko na karcie</translation>
<translation id="3287510313208355388">Pobierz, gdy będę online</translation>
<translation id="3293642807462928945">Więcej informacji o zasadzie <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Brak wyników wyszukiwania</translation>
-<translation id="3305707030755673451">Twoje dane zostały zaszyfrowane z użyciem hasła synchronizacji w dniu <ph name="TIME" />. Wpisz je, by rozpocząć synchronizację.</translation>
<translation id="3320021301628644560">Dodaj adres rozliczeniowy</translation>
<translation id="3324983252691184275">Karmazynowy</translation>
<translation id="3338095232262050444">Bezpieczna</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Ponów edycję</translation>
<translation id="342781501876943858">Chromium zaleca zresetowanie hasła, jeśli zostało użyte na innej stronie.</translation>
<translation id="3431636764301398940">Zapisz tę kartę na tym urządzeniu</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Właściciel tego urządzenia wyłączył grę z dinozaurem.</translation>
<translation id="3447884698081792621">Pokaż certyfikat (wydany przez: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Okres pobierania:</translation>
+<translation id="3456231139987291353">Number-11 (koperta)</translation>
<translation id="3461824795358126837">Zakreślacz</translation>
<translation id="3462200631372590220">Ukryj zaawansowane</translation>
<translation id="3467763166455606212">Wymagane jest imię i nazwisko posiadacza karty</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Karty kredytowe i przedpłacone są akceptowane.</translation>
<translation id="3582930987043644930">Dodaj nazwę</translation>
<translation id="3583757800736429874">&amp;Ponów przeniesienie</translation>
+<translation id="35866233670761917">Treść otwieranych stron internetowych nie jest widoczna dla administratorów</translation>
<translation id="3586931643579894722">Ukryj szczegóły</translation>
+<translation id="3592413004129370115">Italian (koperta)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Rozmiar 2</translation>
<translation id="3615877443314183785">Wpisz prawidłową datę ważności</translation>
<translation id="36224234498066874">Wyczyść dane przeglądania...</translation>
<translation id="362276910939193118">Wyświetl całą historię</translation>
-<translation id="3623476034248543066">Pokaż wartość</translation>
<translation id="3630155396527302611">Jeśli ten program jest już na liście programów mogących korzystać z sieci,
spróbuj go z niej usunąć i dodać ponownie.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Weryfikacja powiodła się</translation>
<translation id="3655670868607891010">Jeśli często widzisz ten komunikat, przeczytaj <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Wersja</translation>
<translation id="366077651725703012">Zaktualizuj kartę kredytową</translation>
<translation id="3676592649209844519">Identyfikator urządzenia:</translation>
+<translation id="3677008721441257057">Czy chodziło Ci o &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Nie udało się podpisać żądania</translation>
<translation id="3678529606614285348">Otwórz stronę w nowym oknie incognito (Ctrl+Shift+N)</translation>
<translation id="3679803492151881375">Raport o awarii zarejestrowano: <ph name="CRASH_TIME" />, przesłano: <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Sieć, której używasz, może wymagać otwarcia strony logowania.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Ładuję...</translation>
+<translation id="3709599264800900598">Skopiowany tekst</translation>
<translation id="3712624925041724820">Brak wolnych licencji</translation>
<translation id="3714780639079136834">Włącz komórkową transmisję danych lub Wi-Fi</translation>
<translation id="3715597595485130451">Połączenie z siecią Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Sprawdź serwer proxy, zaporę sieciową i konfigurację DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Aplikacje, które mogą wywoływać ten błąd, to na przykład programy antywirusowe, zapory sieciowe oraz oprogramowanie do filtrowania ruchu w sieci lub obsługi serwera proxy.</translation>
+<translation id="373042150751172459">B4 (koperta)</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="3745099705178523657">Po potwierdzeniu dane karty z Twojego konta Google zostaną udostępnione tej stronie.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Wygasa: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Rozmiar 16</translation>
+<translation id="3797522431967816232">Prc3 (koperta)</translation>
<translation id="3807873520724684969">Zablokowano szkodliwe treści.</translation>
<translation id="3810973564298564668">Zarządzaj</translation>
<translation id="382518646247711829">Jeśli używasz serwera proxy...</translation>
<translation id="3828924085048779000">Puste hasło jest niedozwolone.</translation>
+<translation id="3831915413245941253">Administrator <ph name="ENROLLMENT_DOMAIN" /> zainstalował rozszerzenia obsługujące dodatkowe funkcje. Rozszerzenia mają dostęp do niektórych Twoich danych.</translation>
<translation id="385051799172605136">Wstecz</translation>
<translation id="3858027520442213535">Zaktualizuj datę i godzinę</translation>
<translation id="3884278016824448484">Konflikt identyfikatorów urządzeń</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Zawsze pytaj na tej stronie</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Taka nazwa sesji już istnieje.</translation>
<translation id="3987940399970879459">Mniej niż 1 MB</translation>
+<translation id="4008849406247176967">Ostrzeżenie: dla tej zasady określono więcej niż jedno źródło, a wartości tych źródeł są sprzeczne.</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="4030383055268325496">&amp;Cofnij dodanie</translation>
+<translation id="4032320456957708163">Twoją przeglądarką zarządza <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Klucz „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (koperta)</translation>
<translation id="4067947977115446013">Dodaj poprawny adres</translation>
<translation id="4072486802667267160">Podczas przetwarzania zamówienia wystąpił błąd. Spróbuj ponownie.</translation>
<translation id="4075732493274867456">Klient i serwer nie obsługują wspólnej wersji protokołu SSL lub mechanizmu szyfrowania.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Purpurowy</translation>
<translation id="4165986682804962316">Ustawienia witryny</translation>
<translation id="4171400957073367226">Nieprawidłowy podpis weryfikujący</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Jeszcze <ph name="ITEM_COUNT" /> element}few{Jeszcze <ph name="ITEM_COUNT" /> elementy}many{Jeszcze <ph name="ITEM_COUNT" /> elementów}other{Jeszcze <ph name="ITEM_COUNT" /> elementu}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (koperta)</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="4221630205957821124">&lt;h4&gt;Krok 1. Zaloguj się w portalu&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Resetuj hasło</translation>
<translation id="4280429058323657511">, ważna do: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Ta karta została zapisana na Twoim koncie Google}few{Te karty zostały zapisane na Twoim koncie Google}many{Te karty zostały zapisane na Twoim koncie Google}other{Te karty zostały zapisane na Twoim koncie Google}}</translation>
+<translation id="42981349822642051">Rozwiń</translation>
+<translation id="4302965934281694568">Chou3 (koperta)</translation>
<translation id="4305817255990598646">Przełącz</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokuj (domyślnie)</translation>
+<translation id="4318566738941496689">Nazwa i adres sieciowy urządzenia</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="4340982228985273705">Ten komputer nie został wykryty jako zarządzany przez firmę, przez co zasada może instalować automatycznie tylko rozszerzenia hostowane w Chrome Web Store. URL sklepu Chrome Web Store służący do aktualizacji to „<ph name="CWS_UPDATE_URL" />”.</translation>
<translation id="4346197816712207223">Akceptowane karty kredytowe</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Zarządzaj formami płatności…</translation>
+<translation id="4367563149485757821">Number-12 (koperta)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">wyniki wyszukiwania</translation>
-<translation id="4406972042435603828">Administratorzy zainstalowali rozszerzenia o dużych możliwościach.</translation>
<translation id="4408413947728134509">Pliki cookie (<ph name="NUM_COOKIES" />)</translation>
<translation id="4415426530740016218">Adres odbioru</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="443121186588148776">Port szeregowy</translation>
<translation id="4432688616882109544">Serwer <ph name="HOST_NAME" /> nie zaakceptował lub nie otrzymał Twojego certyfikatu logowania.</translation>
<translation id="4434045419905280838">Pop-upy i przekierowania</translation>
+<translation id="4435702339979719576">pocztówka)</translation>
<translation id="443673843213245140">Korzystanie z serwera proxy jest wyłączone, ale podano konfigurację proxy.</translation>
<translation id="445100540951337728">Akceptowane karty debetowe</translation>
+<translation id="4466881336512663640">Zmiany w formularzu zostaną utracone. Na pewno chcesz kontynuować?</translation>
<translation id="4482953324121162758">Ta strona nie będzie tłumaczona.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Nieprawidłowy URL. URL musi być zgodny ze schematem standardowym, np. http://example.com lub https://example.com</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (koperta)</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="4517607026994743406">Comm-10 (koperta)</translation>
<translation id="4522570452068850558">Szczegóły</translation>
<translation id="4524805452350978254">Zarządzaj kartami</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Spróbuj wyłączyć rozszerzenia.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Dostawa</translation>
+<translation id="4579056131138995126">Personal (koperta)</translation>
<translation id="4582204425268416675">Usuń kartę</translation>
<translation id="4587425331216688090">Usunąć ten adres z Chrome?</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="4597348597567598915">Rozmiar 8</translation>
+<translation id="4600854749408232102">C6/C5 (koperta)</translation>
<translation id="4646534391647090355">Przejdź tam teraz</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="467809019005607715">Prezentacje Google</translation>
<translation id="4690462567478992370">Przestań używać nieprawidłowego certyfikatu</translation>
+<translation id="4691835149146451662">Architecture-A (koperta)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Połączenie zostało przerwane</translation>
<translation id="471880041731876836">Nie masz pozwolenia, by wejść na tę stronę</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Uruchom Diagnostykę sieci systemu Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Odśwież zasady</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">Prc2 (koperta)</translation>
<translation id="4736825316280949806">Uruchom ponownie Chromium</translation>
<translation id="473775607612524610">Aktualizuj</translation>
<translation id="4738601419177586157">Propozycja wyszukiwania: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Zarządzaj hasłami…</translation>
<translation id="4744603770635761495">Ścieżka pliku wykonywalnego</translation>
+<translation id="4746351372139058112">Wiadomość tekstowa</translation>
<translation id="4750917950439032686">Informacje, które wysyłasz tej witrynie (na przykład hasła lub numery kart kredytowych), pozostają prywatne.</translation>
<translation id="4756388243121344051">&amp;Historia</translation>
<translation id="4758311279753947758">Dodaj dane kontaktowe</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Strona internetowa pod adresem <ph name="URL" /> może być tymczasowo niedostępna lub została na stałe przeniesiona pod nowy adres internetowy.</translation>
<translation id="4771973620359291008">Wystąpił nieznany błąd.</translation>
<translation id="4785689107224900852">Przełącz na tę kartę</translation>
-<translation id="4792143361752574037">Podczas uzyskiwania dostępu do plików sesji wystąpił problem. Zapisywanie na dysku jest obecnie wyłączone. Załaduj stronę jeszcze i raz i spróbuj ponownie.</translation>
<translation id="4798078619018708837">Wpisz datę ważności i kod CVC karty <ph name="CREDIT_CARD" />, by zaktualizować jej dane. Po potwierdzeniu dane karty z Twojego konta Google zostaną udostępnione tej stronie.</translation>
<translation id="4800132727771399293">Sprawdź datę ważności i kod CVC, a potem spróbuj ponownie</translation>
+<translation id="480334179571489655">Błąd zasady dotyczącej źródła</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Otwórz</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Brak wyników</translation>
<translation id="4950898438188848926">Przycisk przełączania kart. Naciśnij Enter, by przełączyć się na otwartą kartę, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Czynności</translation>
-<translation id="495832697253704892">Zgłaszanie rozszerzenia</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Rozwiń listę</translation>
<translation id="4974590756084640048">Ponownie włącz ostrzeżenia</translation>
+<translation id="4984339528288761049">Prc5 (koperta)</translation>
<translation id="4989163558385430922">Pokaż wszystko</translation>
<translation id="4989809363548539747">Ta wtyczka nie jest obsługiwana</translation>
-<translation id="4996230189582812866">Raportowanie</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="5014174725590676422">Wyświetlany jest ekran pierwszego uruchomienia Asystenta Google w Chrome</translation>
<translation id="5015510746216210676">Nazwa komputera:</translation>
+<translation id="5017554619425969104">Skopiowany tekst</translation>
<translation id="5018422839182700155">Nie można otworzyć tej strony</translation>
<translation id="5019198164206649151">Nieprawidłowy stan magazynu wspomagającego</translation>
<translation id="5023310440958281426">Sprawdź zasady administratora</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Kontekst lokalny: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Zezwalaj</translation>
<translation id="5040262127954254034">Prywatność</translation>
+<translation id="5043480802608081735">Skopiowany link</translation>
<translation id="5045550434625856497">Nieprawidłowe hasło</translation>
<translation id="5056549851600133418">Artykuły dla Ciebie</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Sprawdź adres serwera proxy<ph name="END_LINK" /></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="5097099694988056070">Statystyki na temat sprzętu, np. użycie procesora czy pamięci RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Twoim urządzeniem zarządza <ph name="ENROLLMENT_DOMAIN" />, a Twoim kontem – <ph name="ACCOUNT_DOMAIN" />. Oznacza to, że administrator może zdalnie konfigurować Twoje urządzenie i konto.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bitowa)</translation>
-<translation id="5128122789703661928">Nie możesz usunąć tej sesji, bo jej nazwa jest nieprawidłowa.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Zarządzaj adresami…</translation>
+<translation id="5138227688689900538">Pokaż mniej</translation>
<translation id="5141240743006678641">Szyfruj synchronizowane hasła za pomocą danych logowania Google</translation>
<translation id="5145883236150621069">W odebranej polityce znajduje się kod błędu</translation>
+<translation id="515292512908731282">C4 (koperta)</translation>
<translation id="5159010409087891077">Otwórz stronę w nowym oknie incognito (⇧⌘N)</translation>
<translation id="516920405563544094">Wpisz kod CVC karty <ph name="CREDIT_CARD" />. Po potwierdzeniu dane karty z Twojego konta Google zostaną udostępnione tej stronie.</translation>
<translation id="5169827969064885044">Możesz stracić dostęp do swojego konta organizacji lub paść ofiarą kradzieży tożsamości. Chrome zaleca natychmiastową zmianę hasła.</translation>
<translation id="5171045022955879922">Wyszukaj lub wpisz URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Komputer</translation>
<translation id="5179510805599951267">Jeśli to nie jest język <ph name="ORIGINAL_LANGUAGE" />, zgłoś błąd</translation>
<translation id="5190835502935405962">Pasek zakładek</translation>
-<translation id="5200263511887412697">generować raporty z listą użytkowników urządzenia, którzy niedawno się zalogowali.</translation>
+<translation id="519422657042045905">Adnotacja niedostępna</translation>
<translation id="5201306358585911203">Komunikat z elementu umieszczonego na bieżącej stronie</translation>
<translation id="5205222826937269299">Nazwa jest wymagana</translation>
<translation id="5215116848420601511">Formy płatności i adresy z Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-mail jest wymagany</translation>
<translation id="5230733896359313003">Adres wysyłki</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Połącz z siecią”</translation>
<translation id="5251803541071282808">Chmura</translation>
+<translation id="5252000469029418751">C7 (koperta)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Adresy sieciowe</translation>
<translation id="5285570108065881030">Pokaż wszystkie zapisane hasła</translation>
<translation id="5287240709317226393">Pokaż pliki cookie</translation>
<translation id="5288108484102287882">Weryfikacja wartości zasad zakończyła się z ostrzeżeniami</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> z <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Wybierz dane kontaktowe</translation>
<translation id="5327248766486351172">Nazwa</translation>
+<translation id="5329858041417644019">Twoja przeglądarka nie jest zarządzana</translation>
<translation id="5332219387342487447">Metoda wysyłki</translation>
+<translation id="5334013548165032829">Szczegółowe dzienniki systemowe</translation>
<translation id="5344579389779391559">Ta strona może próbować obciążyć Cię płatnością</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">„Twój zegar się spóźnia” lub „Twój zegar się śpieszy” lub „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">Aby używać swoich kart na wszystkich urządzeniach, zaloguj się i włącz synchronizację.</translation>
<translation id="5386426401304769735">Łańcuch certyfikatów tej witryny zawiera certyfikat podpisany za pomocą SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Nieprawidłowe</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<ph name="CONTACT_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}few{<ph name="CONTACT_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}many{<ph name="CONTACT_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="5470861586879999274">&amp;Ponów edycję</translation>
+<translation id="5478437291406423475">B6/C4 (koperta)</translation>
<translation id="5481076368049295676">Te treści mogą próbować instalować na Twoim urządzeniu niebezpieczne oprogramowanie, które wykrada lub usuwa dane. <ph name="BEGIN_LINK" />Wyświetl mimo to<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Dodaj poprawny adres</translation>
<translation id="5490432419156082418">Adresy i ustawienia</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Skontaktuj się z administratorem systemu.</translation>
<translation id="549333378215107354">Rozmiar 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Zakładki zarządzane</translation>
<translation id="5510766032865166053">Mógł zostać przeniesiony lub usunięty.</translation>
<translation id="5523118979700054094">Nazwa zasady</translation>
<translation id="552553974213252141">Czy tekst został prawidłowo wyodrębniony?</translation>
+<translation id="553484882784876924">Prc6 (koperta)</translation>
<translation id="5540224163453853">Nie udało się znaleźć tego artykułu.</translation>
<translation id="5541546772353173584">Dodaj adres e-mail</translation>
<translation id="5545756402275714221">Artykuły dla Ciebie</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Edytuj adres</translation>
<translation id="5598944008576757369">Wybierz formę płatności</translation>
<translation id="560412284261940334">Zarządzanie jest nieobsługiwane</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Strona <ph name="HOST_NAME" /> spowodowała zbyt wiele przekierowań.</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="5632627355679805402">Twoje dane zostały zaszyfrowane <ph name="BEGIN_LINK" />hasłem Google<ph name="END_LINK" /> w dniu <ph name="TIME" />. Wpisz to hasło, by rozpocząć synchronizację.</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="563324245173044180">Zablokowano treści wprowadzające w błąd.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (koperta)</translation>
+<translation id="5663955426505430495">Administrator urządzenia zainstalował rozszerzenia obsługujące dodatkowe funkcje. Rozszerzenia mają dostęp do niektórych Twoich danych.</translation>
<translation id="5675650730144413517">Ta strona nie działa</translation>
+<translation id="5684874026226664614">Nie można przetłumaczyć tej strony.</translation>
<translation id="5685654322157854305">Dodaj adres wysyłki</translation>
<translation id="5689199277474810259">Eksportuj w formacie JSON</translation>
<translation id="5689516760719285838">Lokalizacja</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Tożsamość witryny nie została zweryfikowana.</translation>
<translation id="5719499550583120431">Karty przedpłacone są akceptowane.</translation>
<translation id="5720705177508910913">Bieżący użytkownik</translation>
+<translation id="5728056243719941842">C5 (koperta)</translation>
<translation id="5730040223043577876">Chrome zaleca zresetowanie hasła, jeśli zostało użyte na innej stronie.</translation>
<translation id="5732392974455271431">Mogą ją dla Ciebie odblokować Twoi rodzice</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Zapisywanie karty na koncie Google}few{Zapisywanie kart na koncie Google}many{Zapisywanie kart na koncie Google}other{Zapisywanie kart na koncie Google}}</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="5770114862687765385">Plik wygląda na uszkodzony. Kliknij przycisk „Zresetuj”, by zresetować sesję.</translation>
<translation id="5778550464785688721">Pełne sterowanie urządzeniami MIDI</translation>
<translation id="578305955206182703">Bursztynowy</translation>
<translation id="57838592816432529">Wycisz</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>
+<translation id="5798290721819630480">Odrzucić zmiany?</translation>
<translation id="5798683403665926540">Stronę główną możesz zmienić w ustawieniach Chrome</translation>
<translation id="5803412860119678065">Chcesz wpisać dane swojej karty (<ph name="CARD_DETAIL" />)?</translation>
<translation id="5804241973901381774">Uprawnienia</translation>
<translation id="5810442152076338065">Połączenie z <ph name="DOMAIN" /> jest szyfrowane przy użyciu przestarzałego zestawu szyfrów.</translation>
<translation id="5813119285467412249">&amp;Ponów dodanie</translation>
<translation id="5838278095973806738">Nie podawaj żadnych informacji poufnych (takich jak hasła czy dane kart kredytowych) w tej witrynie, bo osoby atakujące będą mogły je wykraść.</translation>
+<translation id="5860033963881614850">Wyłączone</translation>
<translation id="5863847714970149516">Otwierana strona może próbować obciążyć Cię płatnością</translation>
<translation id="5866257070973731571">Dodaj numer telefonu</translation>
<translation id="5869405914158311789">Ta witryna jest nieosiągalna</translation>
<translation id="5869522115854928033">Zapisane hasła</translation>
<translation id="5887400589839399685">Zapisano kartę</translation>
-<translation id="5893718151540690985">generować raporty z listą interfejsów sieciowych wraz z ich typami i adresami sprzętowymi</translation>
<translation id="5893752035575986141">Karty kredytowe są akceptowane.</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="5916664084637901428">Włączone</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Zapisać kartę na koncie Google?</translation>
<translation id="5922853866070715753">Prawie gotowe</translation>
<translation id="5932224571077948991">Na tej stronie wyświetlają się uciążliwe lub wprowadzające w błąd reklamy</translation>
-<translation id="5939518447894949180">Resetuj</translation>
<translation id="5946937721014915347">Otwieram <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Nie można zarejestrować się przy użyciu konta klienta (w pakiecie dostępna jest licencja).</translation>
<translation id="5967592137238574583">Edytuj dane kontaktowe</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Pomniejsz</translation>
<translation id="5977489021191000276">Twoim urządzeniem nie zarządza administrator.</translation>
<translation id="5977976211062815271">Na tym urządzeniu</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nie można otworzyć aplikacji do płatności</translation>
<translation id="5989320800837274978">Nie określono ani stałych serwerów proxy, ani adresu URL skryptu PAC.</translation>
<translation id="5990559369517809815">Żądania do serwera zostały zablokowane przez rozszerzenie.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">generować raporty ze statystykami na temat sprzętu, np. użyciem procesora czy pamięci RAM.</translation>
<translation id="6034000775414344507">Jasnoszary</translation>
+<translation id="6034283069659657473">10x14 (koperta)</translation>
<translation id="6039846035001940113">Jeśli problem nie ustąpi, skontaktuj się z właścicielem strony.</translation>
<translation id="6040143037577758943">Zamknij</translation>
<translation id="6044573915096792553">Rozmiar 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Chcesz używać swoich kart na wszystkich urządzeniach?</translation>
<translation id="6059925163896151826">Urządzenia USB</translation>
-<translation id="6071091556643036997">Typ zasady jest nieprawidłowy.</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="6094273045989040137">Dodaj adnotacje</translation>
<translation id="610911394827799129">Inne rodzaje historii przeglądania mogą być nadal dostępne na Twoim koncie Google na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informacje o zainstalowanych rozszerzeniach i wtyczkach</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Zwolni się mniej niż <ph name="SIZE" />. Podczas następnej wizyty niektóre strony mogą ładować się wolniej.</translation>
<translation id="6337534724793800597">Filtruj zasady według nazwy</translation>
<translation id="6358450015545214790">Co to oznacza?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Uważaj na możliwe opłaty.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 inna podpowiedź}few{# inne podpowiedzi}many{# innych podpowiedzi}other{# innej podpowiedzi}}</translation>
<translation id="6387754724289022810">Aby następnym razem zapłacić szybciej, zapisz kartę i adres rozliczeniowy na swoim koncie Google i na tym urządzeniu.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Edytuj zakładkę</translation>
+<translation id="6406765186087300643">C0 (koperta)</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="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="6434309073475700221">Przerwij</translation>
+<translation id="6446163441502663861">Kahu (koperta)</translation>
<translation id="6446608382365791566">Dodaj więcej informacji</translation>
<translation id="6447842834002726250">Pliki cookie</translation>
<translation id="6451458296329894277">Potwierdź ponowne przesłanie formularza</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Uruchom ponownie Chrome</translation>
<translation id="6529602333819889595">&amp;Ponów usunięcie</translation>
<translation id="6534179046333460208">Sugestie dotyczące internetu rzeczy</translation>
+<translation id="6556866813142980365">Ponów</translation>
<translation id="6563469144985748109">Twój menedżer jeszcze na to nie zezwolił</translation>
<translation id="6569060085658103619">Przeglądasz stronę rozszerzenia</translation>
+<translation id="6578796323535178455">C2 (koperta)</translation>
<translation id="6579990219486187401">Jasnoróżowy</translation>
+<translation id="6583674473685352014">B6 (koperta)</translation>
+<translation id="6587923378399804057">Skopiowany link</translation>
+<translation id="6591833882275308647">Twoje urządzenie <ph name="DEVICE_TYPE" /> nie jest zarządzane</translation>
<translation id="6596325263575161958">Opcje szyfrowania</translation>
<translation id="6604181099783169992">Czujniki ruchu lub światła</translation>
+<translation id="6609880536175561541">Prc7 (koperta)</translation>
<translation id="6624427990725312378">Dane kontaktowe</translation>
<translation id="6626291197371920147">Dodaj prawidłowy numer karty</translation>
<translation id="6628463337424475685">Wyszukiwarka <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Zasada jest wycofana</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Brak}=1{Z 1 witryny (nie spowoduje to wylogowania z konta Google)}few{Z # witryn (nie spowoduje to wylogowania z konta Google)}many{Z # witryn (nie spowoduje to wylogowania z konta Google)}other{Z # witryny (nie spowoduje to wylogowania z konta Google)}}</translation>
<translation id="6657585470893396449">Hasło</translation>
+<translation id="6670613747977017428">Wróć do bezpiecznej strony.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Token rejestracji:</translation>
<translation id="6711464428925977395">Serwer proxy działa nieprawidłowo albo adres jest błędny.</translation>
<translation id="6723740634201835758">Na Twoim koncie Google</translation>
+<translation id="6738516213925468394">Twoje dane zostały zaszyfrowane <ph name="BEGIN_LINK" />hasłem synchronizacji<ph name="END_LINK" /> w dniu <ph name="TIME" />. Wpisz to hasło, by rozpocząć synchronizację.</translation>
<translation id="674375294223700098">Nieznany błąd certyfikatu serwera.</translation>
<translation id="6744009308914054259">Dopóki nie masz połączenia, możesz poczytać artykuły offline z Pobranych plików.</translation>
<translation id="6753269504797312559">Wartość zasady</translation>
<translation id="6757797048963528358">Twoje urządzenie przeszło w tryb uśpienia.</translation>
+<translation id="6768213884286397650">Hagaki (pocztówka)</translation>
<translation id="6778737459546443941">Twój rodzic jeszcze na to nie zezwolił</translation>
<translation id="67862343314499040">Fioletowy</translation>
+<translation id="6786747875388722282">Rozszerzenia</translation>
<translation id="679355240208270552">Ignorowana, ponieważ wyszukiwarka domyślna nie jest dozwolona przez zasadę.</translation>
<translation id="681021252041861472">Pole wymagane</translation>
<translation id="6810899417690483278">Identyfikator dostosowania</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Urządzenie</translation>
<translation id="6970216967273061347">Okręg</translation>
<translation id="6973656660372572881">Określono zarówno stałe serwery proxy, jak i URL skryptu PAC.</translation>
+<translation id="6973932557599545801">Nie jestem w stanie Ci pomóc. Kontynuuj samodzielnie.</translation>
<translation id="6979158407327259162">Dysk Google</translation>
<translation id="6979440798594660689">Wycisz (domyślnie)</translation>
<translation id="6984479912851154518">Opuszczasz tryb prywatny, by zapłacić w zewnętrznej aplikacji. Kontynuować?</translation>
<translation id="6989763994942163495">Pokaż ustawienia zaawansowane...</translation>
+<translation id="6993898126790112050">6x9 (koperta)</translation>
<translation id="6996312675313362352">Zawsze tłumacz z tego języka: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Może to być opłata jednorazowa lub cykliczna, a informacje o niej mogą nie być wyraźnie podane.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ukryj</translation>
<translation id="7108819624672055576">Dozwolone przez rozszerzenie</translation>
<translation id="7111012039238467737">(Ważny)</translation>
+<translation id="7118618213916969306">Wyszukaj URL ze schowka, <ph name="SHORT_URL" /></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="7135130955892390533">Pokaż stan</translation>
<translation id="7138472120740807366">Metoda dostawy</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (koperta)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}few{<ph name="PAYMENT_METHOD_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}many{<ph name="PAYMENT_METHOD_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation>
<translation id="7153618581592392745">Lawendowy</translation>
-<translation id="7158980942472052083">Nieprawidłowy URL. Wymagany jest URL zgodny ze schematem standardowym.</translation>
<translation id="717330890047184534">Identyfikator GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}few{<ph name="SHIPPING_OPTION_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}many{<ph name="SHIPPING_OPTION_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> i jeszcze <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation>
+<translation id="7177397715882417099">Serwer <ph name="ORIGIN" />, z którym chcesz się połączyć, zażądał stosowania
+ zasady bezpieczeństwa do wszystkich swoich żądań. Jednak zamiast
+ dostarczyć zasadę, przekierował przeglądarkę gdzie indziej, uniemożliwiając jej
+ zrealizowanie Twojego żądania dotyczącego strony <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Zapisuj i automatycznie uzupełniaj informacje o formach płatności</translation>
<translation id="7180611975245234373">Odśwież</translation>
<translation id="7182878459783632708">Brak ustawionych zasad</translation>
<translation id="7186367841673660872">Ta strona została przetłumaczona z języka<ph name="ORIGINAL_LANGUAGE" />na język<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Zwolni się <ph name="SIZE" />. Podczas następnej wizyty niektóre strony mogą ładować się wolniej.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administrator może zobaczyć:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Serwer <ph name="HOST_NAME" /> nie spełnia norm bezpieczeństwa.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /> na temat tego problemu.</translation>
<translation id="7219179957768738017">Połączenie z szyfrowaniem <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Przetwarzanie</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Strona, którą chcesz otworzyć, zawiera złośliwe oprogramowanie</translation>
+<translation id="724766306220616965">Ostrzeżenia, konflikt</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="7251437084390964440">Konfiguracja sieci jest niezgodna ze standardem ONC. Jej część mogła nie zostać zaimportowana.
Dodatkowe informacje:
@@ -982,11 +1120,14 @@ Dodatkowe informacje:
<translation id="7300012071106347854">Niebieski kobalt</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />”</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="7313965965371928911">Ostrzeżenia <ph name="BEGIN_LINK" />Bezpiecznego przeglądania<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Pomoc dotycząca połączeń</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Wiersz poleceń</translation>
-<translation id="7365061714576910172">Eksportuj (Linux)</translation>
<translation id="7372973238305370288">wynik wyszukiwania</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nie</translation>
@@ -994,6 +1135,7 @@ Dodatkowe informacje:
<translation id="7381288752349550461">Zastąpienie sesji zarządzanej</translation>
<translation id="7390545607259442187">Potwierdź kartę</translation>
<translation id="7400418766976504921">Adres URL</translation>
+<translation id="7403591733719184120">Twoje urządzenie <ph name="DEVICE_NAME" /> jest zarządzane</translation>
<translation id="7407424307057130981">&lt;p&gt;Ten błąd występuje, jeśli na komputerze z systemem Windows masz zainstalowane oprogramowanie Superfish.&lt;/p&gt;
&lt;p&gt;Wykonaj te czynności, by tymczasowo wyłączyć to oprogramowanie i połączyć się z internetem. Będziesz potrzebować uprawnień administratora.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Dodatkowe informacje:
&lt;li&gt;Kliknij &lt;strong&gt;Zastosuj&lt;/strong&gt;, a potem kliknij &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;W &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centrum pomocy Chrome&lt;/a&gt; dowiesz się, jak trwale usunąć to oprogramowanie z komputera.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> – zarządzanie</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Zarządzaj hasłami…</translation>
<translation id="7419106976560586862">Ścieżka profilu</translation>
<translation id="7437289804838430631">Dodaj dane kontaktowe</translation>
@@ -1013,22 +1155,24 @@ Dodatkowe informacje:
<translation id="7442725080345379071">Jasnopomarańczowy</translation>
<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="7449109375006139765">wysyłać dzienniki systemowe na serwer zarządzania</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="7460618730930299168">Godziny seansów są inne niż wybrane przez Ciebie. Czy chcesz kontynuować?</translation>
<translation id="7473891865547856676">Nie, dziękuję</translation>
-<translation id="7475525192983021547">generować raporty z okresami aktywności użytkownika na urządzeniu</translation>
<translation id="7481312909269577407">Dalej</translation>
<translation id="7485870689360869515">Nie znaleziono danych.</translation>
+<translation id="7498234416455752244">Edytuj dalej</translation>
<translation id="7508255263130623398">Zwrócony identyfikator urządzenia dla zasad jest pusty lub nie pasuje do bieżącego identyfikatora urządzenia</translation>
<translation id="7508870219247277067">Zielony awokado</translation>
<translation id="7511955381719512146">Sieć Wi-Fi, której używasz, może wymagać otwarcia strony <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Pobierz</translation>
<translation id="7518003948725431193">Nie znaleziono strony internetowej pod adresem <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (koperta)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Twoje połączenie z tą stroną nie jest prywatne</translation>
+<translation id="7535087603100972091">Wartość</translation>
<translation id="7537536606612762813">Obowiązkowe</translation>
+<translation id="7538364083937897561">A2 (koperta)</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>
@@ -1037,8 +1181,8 @@ Dodatkowe informacje:
<translation id="7552846755917812628">Skorzystaj z tych wskazówek:</translation>
<translation id="7554791636758816595">Nowa karta</translation>
<translation id="7564049878696755256">Możesz stracić dostęp do swojego konta <ph name="ORG_NAME" /> lub paść ofiarą kradzieży tożsamości. Chrome zaleca natychmiastową zmianę hasła.</translation>
-<translation id="7566125604157659769">Skopiowany tekst</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="7568105740864181217">Ta przeglądarka jest zarządzana przez firmę, szkołę lub inną organizację. Administrator może zdalnie zmienić konfigurację przeglądarki. Aktywność na tym urządzeniu może być zarządzana również poza Chrome. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Dodatkowe informacje:
<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="7633909222644580952">Dane o wydajności i raporty o awariach</translation>
<translation id="7637571805876720304">Usunąć tę kartę kredytową z Chromium?</translation>
<translation id="7639968568612851608">Ciemnoszary</translation>
<translation id="765676359832457558">Ukryj ustawienia zaawansowane...</translation>
@@ -1058,9 +1203,11 @@ Dodatkowe informacje:
<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="7676643023259824263">Wyszukaj tekst ze schowka, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Zmień wyszukiwarkę</translation>
<translation id="7682287625158474539">Adres wysyłkowy</translation>
<translation id="7687186412095877299">Wypełniaj formularze płatności, używając zapisanych form płatności</translation>
+<translation id="7697066736081121494">Prc8 (koperta)</translation>
<translation id="769721561045429135">Obecnie niektórych z Twoich kart można używać tylko na tym urządzeniu. Kliknij Dalej, by wyświetlić karty.</translation>
<translation id="7699293099605015246">Artykuły nie są obecnie dostępne</translation>
<translation id="7701040980221191251">Brak</translation>
@@ -1072,11 +1219,13 @@ Dodatkowe informacje:
<translation id="774634243536837715">Zablokowano niebezpieczne treści.</translation>
<translation id="7752995774971033316">Niezarządzany</translation>
<translation id="7755287808199759310">Może ją dla Ciebie odblokować Twój rodzic</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Połączenie mogło zostać zablokowane przez zaporę sieciową lub program antywirusowy.</translation>
<translation id="7759163816903619567">Wyświetlana domena:</translation>
<translation id="7761701407923456692">Certyfikat serwera jest niezgodny z adresem URL.</translation>
<translation id="7763386264682878361">Parser pliku manifestu dla płatności</translation>
<translation id="7764225426217299476">Dodaj adres</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7793809570500803535">Strona <ph name="SITE" /> może być tymczasowo niedostępna lub została na stałe przeniesiona pod nowy adres internetowy.</translation>
@@ -1088,8 +1237,8 @@ Dodatkowe informacje:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Usunąć tę podpowiedź do formularza z Chrome?</translation>
<translation id="7815407501681723534">Znalezione <ph name="SEARCH_RESULTS" /> dla zapytania „<ph name="SEARCH_STRING" />”: <ph name="NUMBER_OF_RESULTS" /></translation>
-<translation id="7818867226424560206">Zarządzanie zasadami</translation>
<translation id="782886543891417279">Sieć Wi-Fi (<ph name="WIFI_NAME" />), której używasz, może wymagać otwarcia strony logowania.</translation>
+<translation id="7836231406687464395">Postfix (koperta)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Brak}=1{Jedna aplikacja (<ph name="EXAMPLE_APP_1" />)}=2{Dwie aplikacje (<ph name="EXAMPLE_APP_1" /> i <ph name="EXAMPLE_APP_2" />)}few{# aplikacje (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}many{# aplikacji (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# aplikacji (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">To jednak nie znaczy, że Cię nie widać. Nawet gdy przejdziesz w tryb incognito, Twój pracodawca, dostawca usług internetowych czy webmasterzy stron, na które wchodzisz, mogą dowiedzieć się, co przeglądasz.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@ Dodatkowe informacje:
<translation id="7878562273885520351">Ktoś mógł poznać Twoje hasło</translation>
<translation id="7882421473871500483">Brązowy</translation>
<translation id="7887683347370398519">Sprawdź kod CVC i spróbuj ponownie</translation>
-<translation id="7893255318348328562">Nazwa sesji</translation>
+<translation id="7904208859782148177">C3 (koperta)</translation>
<translation id="79338296614623784">Wpisz prawidłowy numer telefonu</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Ważna do <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Dodatkowe informacje:
<translation id="7951415247503192394">(32-bitowa)</translation>
<translation id="7956713633345437162">Zakładki na komórce</translation>
<translation id="7961015016161918242">Nigdy</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Nie określono</translation>
<translation id="800218591365569300">Zamknij inne karty lub programy, by zwolnić pamięć.</translation>
+<translation id="8004582292198964060">Przeglądarka</translation>
<translation id="8009225694047762179">Zarządzaj hasłami</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Ta karta i jej adres rozliczeniowy zostaną zapisane. Możesz ich używać po zalogowaniu się na konto <ph name="USER_EMAIL" />.}few{Te karty i ich adresy rozliczeniowe zostaną zapisane. Możesz ich używać po zalogowaniu się na konto <ph name="USER_EMAIL" />.}many{Te karty i ich adresy rozliczeniowe zostaną zapisane. Możesz ich używać po zalogowaniu się na konto <ph name="USER_EMAIL" />.}other{Te karty i ich adresy rozliczeniowe zostaną zapisane. Możesz ich używać po zalogowaniu się na konto <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Język tej strony to <ph name="SOURCE_LANGUAGE" />. Przetłumaczyć ją na <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pióro</translation>
+<translation id="8037117624646282037">Kto ostatnio używał urządzenia</translation>
<translation id="8037357227543935929">Pytaj (domyślnie)</translation>
<translation id="803771048473350947">Plik</translation>
<translation id="8041089156583427627">Prześlij opinię</translation>
<translation id="8041940743680923270">Użyj globalnej wartości domyślnej (Pytaj)</translation>
<translation id="8042918947222776840">Wybierz metodę odbioru</translation>
<translation id="8057711352706143257">Oprogramowanie „<ph name="SOFTWARE_NAME" />” nie jest prawidłowo skonfigurowane. Odinstalowanie oprogramowania „<ph name="SOFTWARE_NAME" />” zwykle rozwiązuje problem. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Twoje urządzenie zostało skonfigurowane tak, by:</translation>
+<translation id="8066955247577885446">Coś poszło nie tak.</translation>
+<translation id="8074253406171541171">10x13 (koperta)</translation>
<translation id="8078141288243656252">Nie można dodawać adnotacji, gdy dokument jest obrócony</translation>
<translation id="8079031581361219619">Załadować ponownie stronę?</translation>
<translation id="8088680233425245692">Nie udało się wyświetlić artykułu.</translation>
@@ -1131,11 +1284,12 @@ Dodatkowe informacje:
<translation id="8091372947890762290">Aktywacja oczekuje na serwerze</translation>
<translation id="8092774999298748321">Mocno fioletowy</translation>
<translation id="8094917007353911263">Sieć, której używasz, może wymagać otwarcia strony <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Nieprawidłowe karty zostały usunięte</translation>
<translation id="8103161714697287722">Forma płatności</translation>
<translation id="8118489163946903409">Forma płatności</translation>
+<translation id="8123836779274890062">Urządzenie <ph name="DEVICE_TYPE" /> zarządzane przez <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Oprogramowanie „<ph name="SOFTWARE_NAME" />” nie zostało prawidłowo zainstalowane na komputerze lub w sieci. Poproś administratora o rozwiązanie tego problemu.</translation>
-<translation id="8130693978878176684">Nie mogę Ci tutaj pomóc. Kontynuuj samodzielnie.</translation>
<translation id="8131740175452115882">Potwierdź</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>
@@ -1145,8 +1299,11 @@ Dodatkowe informacje:
<translation id="8197543752516192074">Przetłumacz stronę</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (koperta)</translation>
<translation id="8211406090763984747">Połączenie jest bezpieczne</translation>
<translation id="8218327578424803826">Przypisana lokalizacja:</translation>
+<translation id="8220146938470311105">C7/C6 (koperta)</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="8238581221633243064">Otwórz stronę w nowej karcie incognito</translation>
@@ -1158,14 +1315,16 @@ Dodatkowe informacje:
<translation id="825929999321470778">Pokaż wszystkie zapisane hasła</translation>
<translation id="8261506727792406068">Usuń</translation>
<translation id="8267698848189296333">Logujesz się jako <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Ta przeglądarka jest zarządzana przez <ph name="ENROLLMENT_DOMAIN" />. Administrator może zdalnie zmienić konfigurację przeglądarki. Aktywność na tym urządzeniu może być zarządzana również poza Chrome. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Zaloguj się</translation>
<translation id="8288807391153049143">Pokaż certyfikat</translation>
<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="8298115750975731693">Sieć Wi-Fi (<ph name="WIFI_NAME" />), której używasz, może wymagać otwarcia strony <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Tłumaczenie nie powiodło się z powodu problemu z połączeniem sieciowym.</translation>
-<translation id="8311129316111205805">Wczytaj sesję</translation>
<translation id="8332188693563227489">Odmowa dostępu do <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Dodatkowe informacje:
<translation id="8416694386774425977">Konfiguracja sieci jest nieprawidłowa i nie można jej zaimportować.
Dodatkowe informacje:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Urządzeniem zarządza <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Zmień</translation>
<translation id="8428213095426709021">Ustawienia</translation>
@@ -1210,9 +1368,11 @@ Dodatkowe informacje:
<translation id="860043288473659153">Imię i nazwisko posiadacza karty</translation>
<translation id="861775596732816396">Rozmiar 4</translation>
<translation id="8620436878122366504">Twoi rodzice jeszcze na to nie zezwolili</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Zapisz tę kartę na tym urządzeniu</translation>
<translation id="8663226718884576429">Podsumowanie zamówienia, <ph name="TOTAL_LABEL" />, Szczegółowe informacje</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, odpowiedź, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Połączenie z witryną <ph name="DOMAIN" /> nie jest szyfrowane.</translation>
<translation id="8718314106902482036">Płatność nie została zrealizowana</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sugestia wyszukiwania</translation>
@@ -1226,6 +1386,7 @@ Dodatkowe informacje:
<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="8763927697961133303">Urządzenie USB</translation>
<translation id="8768895707659403558">Aby używać swoich kart na wszystkich urządzeniach, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Ponów usunięcie</translation>
<translation id="8792621596287649091">Możesz stracić dostęp do swojego konta <ph name="ORG_NAME" /> lub paść ofiarą kradzieży tożsamości. Chromium zaleca natychmiastową zmianę hasła.</translation>
<translation id="8800988563907321413">Tutaj wyświetlają się sugestie witryn w pobliżu</translation>
@@ -1236,10 +1397,12 @@ Dodatkowe informacje:
<translation id="885730110891505394">Udostępnianie Google</translation>
<translation id="8858065207712248076">Chrome zaleca zresetowanie hasła, którego używasz w: <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, jeśli zostało użyte na innej stronie.</translation>
<translation id="8866481888320382733">Podczas przetwarzania ustawień zasady wystąpił błąd</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Ostatnio zamknięte</translation>
<translation id="8874824191258364635">Wpisz prawidłowy numer karty</translation>
<translation id="8891727572606052622">Nieprawidłowy tryb proxy</translation>
<translation id="8903921497873541725">Powiększ</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Dodaj imię i nazwisko lub nazwę firmy</translation>
@@ -1247,13 +1410,13 @@ Dodatkowe informacje:
<translation id="894185898663964645">Administrator skonfigurował niestandardowe certyfikaty główne, które mogą umożliwiać mu wgląd w treści stron, które otwierasz.</translation>
<translation id="8943282376843390568">Limonkowy</translation>
<translation id="8957210676456822347">Autoryzacja portalu przechwytującego</translation>
+<translation id="8966619695390250636">Czy chodziło Ci o to?</translation>
<translation id="8968766641738584599">Zapisz kartę</translation>
<translation id="8971063699422889582">Ważność certyfikatu serwera wygasła.</translation>
<translation id="8975012916872825179">Obejmuje numery telefonów, adresy e-mail i adresy dostawy</translation>
<translation id="8978053250194585037">Bezpieczne przeglądanie Google <ph name="BEGIN_LINK" />wykryło ostatnio próbę wyłudzenia informacji<ph name="END_LINK" /> na stronie <ph name="SITE" />. Strony wyłudzające informacje udają inne strony, by Cię oszukać.</translation>
<translation id="8983003182662520383">Formy płatności i adresy z Google Pay</translation>
<translation id="8987927404178983737">Miesiąc</translation>
-<translation id="8988408250700415532">Coś poszło nie tak. Możesz dokończyć składanie zamówienia na stronie internetowej.</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>
@@ -1263,6 +1426,7 @@ Dodatkowe informacje:
<translation id="9011424611726486705">Otwórz ustawienia witryny</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Nieważny)</translation>
<translation id="9035022520814077154">Błąd zabezpieczeń</translation>
<translation id="9038649477754266430">Używaj podpowiedzi, by strony ładowały się szybciej</translation>
@@ -1274,11 +1438,11 @@ Dodatkowe informacje:
<translation id="9065745800631924235">Wyszukiwanie ciągu <ph name="TEXT" /> w historii</translation>
<translation id="9069693763241529744">Zablokowane przez rozszerzenie</translation>
<translation id="9076283476770535406">Może zawierać treści dla dorosłych</translation>
+<translation id="9076630408993835509">Ta przeglądarka nie jest zarządzana przez firmę ani inną organizację. Aktywność na tym urządzeniu może być zarządzana poza Chrome. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Potrzebujemy więcej informacji</translation>
<translation id="9080712759204168376">Podsumowanie zamówienia</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>
<translation id="9106062320799175032">Dodaj adres rozliczeniowy</translation>
-<translation id="9110718169272311511">Asystent Google w Chrome jest dostępny u dołu ekranu</translation>
<translation id="9114524666733003316">Sprawdzam kartę…</translation>
<translation id="9128870381267983090">Połącz z siecią</translation>
<translation id="9137013805542155359">Pokaż tekst oryginalny</translation>
@@ -1287,6 +1451,7 @@ Dodatkowe informacje:
<translation id="9148507642005240123">&amp;Cofnij edycję</translation>
<translation id="9154194610265714752">Zaktualizowano</translation>
<translation id="9157595877708044936">Konfigurowanie...</translation>
+<translation id="9158625974267017556">C6 (koperta)</translation>
<translation id="9168814207360376865">Zezwalaj stronom na sprawdzanie, czy masz zapisane formy płatności</translation>
<translation id="9169664750068251925">Zawsze blokuj w tej witrynie</translation>
<translation id="9170848237812810038">&amp;Cofnij</translation>
@@ -1301,10 +1466,12 @@ Dodatkowe informacje:
<translation id="9219103736887031265">Grafika</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">WYCZYŚĆ FORMULARZ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Możesz stracić dostęp do swojego konta Google. Chromium zaleca natychmiastową zmianę hasła. Zobaczysz prośbę, by się zalogować.</translation>
<translation id="939736085109172342">Nowy folder</translation>
<translation id="945855313015696284">Sprawdź poniższe informacje i usuń karty z błędami</translation>
<translation id="951104842009476243">Akceptowane karty debetowe i przedpłacone</translation>
+<translation id="958202389743790697">Zablokowano zgodnie z zasadami bezpieczeństwa strony <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Te treści mogą próbować zainstalować 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_LINK" />Pokaż mimo to<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Oficjalna wersja</translation>
<translation id="973773823069644502">Dodaj adres dostawy</translation>
@@ -1313,6 +1480,7 @@ Dodatkowe informacje:
<translation id="984275831282074731">Formy płatności</translation>
<translation id="985199708454569384">&lt;p&gt;Ten błąd występuje, jeśli data i godzina na komputerze lub urządzeniu mobilnym są niedokładne.&lt;/p&gt;
&lt;p&gt;Aby naprawić błąd, otwórz ustawienia zegara na urządzeniu i zmień datę oraz godzinę na prawidłowe.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Build</translation>
<translation id="989988560359834682">Edytuj adres</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_pt-BR.xtb b/chromium/components/strings/components_strings_pt-BR.xtb
index d02ae8abc56..5929382dc04 100644
--- a/chromium/components/strings/components_strings_pt-BR.xtb
+++ b/chromium/components/strings/components_strings_pt-BR.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pt-BR">
-<translation id="1005145902654145231">Falha ao renomear a sessão.</translation>
<translation id="1008557486741366299">Não agora</translation>
<translation id="1010200102790553230">Carregar página mais tarde</translation>
<translation id="1015730422737071372">Forneça detalhes adicionais</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nome desconhecido</translation>
<translation id="1050038467049342496">Fechar outros apps</translation>
<translation id="1055184225775184556">&amp;Desfazer adicionar</translation>
+<translation id="1056898198331236512">Aviso</translation>
<translation id="1058479211578257048">Salvando cartões…</translation>
<translation id="10614374240317010">Nunca salvas</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Favoritos em computador</translation>
<translation id="1074497978438210769">Não seguro</translation>
<translation id="1080116354587839789">Ajustar à largura</translation>
+<translation id="1086953900555227778">Ficha</translation>
<translation id="1088860948719068836">Adicionar Nome como consta no Cartão</translation>
<translation id="1089439967362294234">Alterar senha</translation>
<translation id="109743633954054152">Gerencie senhas nas configurações do Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Avisos podem ser comuns enquanto os sites atualizam a segurança. Isso deve melhorar em breve.</translation>
<translation id="1126551341858583091">O tamanho no armazenamento local é de <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache da política OK</translation>
+<translation id="1131264053432022307">Imagem que você copiou</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Renomear</translation>
<translation id="1175364870820465910">&amp;Imprimir...</translation>
<translation id="1181037720776840403">Remover</translation>
<translation id="1197088940767939838">Laranja</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">O nome do seu dispositivo</translation>
<translation id="124116460088058876">Mais idiomas</translation>
<translation id="1250759482327835220">Para agilizar o pagamento na próxima vez, salve o cartão, seu nome e o endereço de faturamento na sua Conta do Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variações de linha de comando</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="1314614906530272393">A sessão selecionada não existe.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Pesquisar uma imagem na área de transferência</translation>
<translation id="1323433172918577554">Mostrar mais</translation>
<translation id="132390688737681464">Salvar e preencher endereços</translation>
<translation id="1333989956347591814">É possível que sua atividade <ph name="BEGIN_EMPHASIS" />ainda esteja visível<ph name="END_EMPHASIS" /> para:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Endereço de retirada</translation>
<translation id="1348198688976932919">O site a seguir contém apps perigosos</translation>
<translation id="1348779747280417563">Confirmar nome</translation>
+<translation id="1357195169723583938">Quem usou o dispositivo recentemente e quando</translation>
+<translation id="1364822246244961190">Esta política está bloqueada. O valor dela será ignorado.</translation>
<translation id="1374468813861204354">sugestões</translation>
+<translation id="1374692235857187091">10 mm x 15 mm (Postal)</translation>
<translation id="1375198122581997741">Sobre a versão</translation>
<translation id="1376836354785490390">Mostrar menos</translation>
<translation id="1377321085342047638">Número do cartão</translation>
<translation id="138218114945450791">Azul-claro</translation>
+<translation id="1382194467192730611">Dispositivo USB permitido pelo administrador</translation>
<translation id="139305205187523129">Nenhum dado foi enviado por <ph name="HOST_NAME" /></translation>
+<translation id="140316286225361634">O site <ph name="ORIGIN" /> solicitou que uma política de segurança
+ seja aplicada a todas as solicitações, e essa política atualmente considera o site
+ inseguro.</translation>
<translation id="1405567553485452995">Verde-claro</translation>
<translation id="1407135791313364759">Abrir todas</translation>
<translation id="1413809658975081374">Erro de privacidade</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Sim</translation>
<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455413310270022028">Borracha</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Mostrar mais</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Escolher endereço de entrega</translation>
+<translation id="1492194039220927094">Push de políticas:</translation>
<translation id="1501859676467574491">Mostre os cartões salvos na Conta do Google</translation>
-<translation id="1506687042165942984">Mostrar uma cópia salva (ou seja, reconhecidamente desatualizada) desta página.</translation>
<translation id="1507202001669085618">&lt;p&gt;Você verá esse erro se estiver usando um portal Wi-Fi em que precise fazer login para poder se conectar.&lt;/p&gt;
&lt;p&gt;Para corrigir o erro, clique em &lt;strong&gt;Conectar&lt;/strong&gt; na página que você está tentando abrir.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Número de telefone necessário</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Data da versão</translation>
<translation id="1521655867290435174">Planilhas Google</translation>
<translation id="1527263332363067270">Aguardando conexão...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Executivo</translation>
<translation id="1532118530259321453">Essa página diz</translation>
<translation id="153384715582417236">Isso é tudo por enquanto</translation>
<translation id="154408704832528245">Escolher endereço de entrega</translation>
<translation id="1549470594296187301">O JavaScript deve ser ativado para usar este recurso.</translation>
+<translation id="155039086686388498">Engineering D</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="1569487616857761740">Informar data de validade</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imagem que você copiou</translation>
<translation id="1620510694547887537">Câmera</translation>
<translation id="1623104350909869708">Impedir que esta página crie caixas de diálogo adicionais</translation>
+<translation id="16338877384480380">Arch B</translation>
<translation id="1634051627998691300">Finalizar sessão</translation>
<translation id="1639239467298939599">Carregando</translation>
<translation id="1640180200866533862">Políticas de usuário</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">O certificado do servidor contém uma chave de criptografia fraca.</translation>
<translation id="1697532407822776718">Pronto.</translation>
+<translation id="1703835215927279855">Carta</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="1715874602234207">F</translation>
<translation id="1718029547804390981">O documento é grande demais para receber anotações</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Tente entrar em contato com o administrador do sistema.</translation>
<translation id="1740951997222943430">Informe um mês de validade válido</translation>
<translation id="1743520634839655729">Para agilizar o pagamento na próxima vez, salve o cartão, seu nome e o endereço de faturamento na sua Conta do Google e neste dispositivo.</translation>
+<translation id="1745880797583122200">Seu navegador é gerenciado</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Favor atualizar sua senha de sincronização.</translation>
<translation id="1787142507584202372">Suas guias abertas são exibidas aqui</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nome do titular do cartão</translation>
<translation id="1821930232296380041">Solicitação ou parâmetros de solicitação inválidos</translation>
+<translation id="1822540298136254167">Os sites que você visita e o tempo gasto neles</translation>
<translation id="1826516787628120939">Em verificação</translation>
<translation id="1834321415901700177">Este site contém programas perigosos</translation>
<translation id="1839551713262164453">Falha com erros na validação dos valores da política</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Limpe os dados do histórico de navegação do Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{e mais um}one{e mais #}other{e mais #}}</translation>
<translation id="2003709556000175978">Redefinir sua senha agora</translation>
+<translation id="20053308747750172">O servidor que você acessará, <ph name="ORIGIN" />, solicitou que
+ uma política de segurança seja aplicada a todas as solicitações. Porém, agora ele
+ apresentou uma política inválida, que impede o navegador de
+ executar sua solicitação para <ph name="SITE" />.</translation>
<translation id="2025186561304664664">O proxy está configurado em configuração automática.</translation>
<translation id="2030481566774242610">Você quis dizer <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Verificar o proxy e o firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departamento</translation>
<translation id="2102134110707549001">Sugerir senha forte…</translation>
<translation id="2108755909498034140">Reiniciar seu computador</translation>
+<translation id="2111256659903765347">Super A</translation>
<translation id="2113977810652731515">Cartão</translation>
<translation id="2114841414352855701">Ignorado porque foi substituído por <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Favoritos nos dispositivos móveis</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2183608646556468874">Número de telefone</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 endereço}one{# endereço}other{# endereços}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Número do telefone</translation>
<translation id="2283340219607151381">Salvar e preencher endereços</translation>
<translation id="2292556288342944218">O seu acesso à Internet está bloqueado</translation>
+<translation id="2294558542833290837">O link que você abriu originalmente é incomum</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Libera menos de 1 MB. O carregamento de alguns sites pode ficar mais lento no seu próximo acesso.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> exige um nome de usuário e uma senha.</translation>
<translation id="2317583587496011522">Cartões de débito são aceitos.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, expira em <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Configuração controlada pelo administrador</translation>
+<translation id="2346319942568447007">Imagem que você copiou</translation>
<translation id="2349790679044093737">A sessão de RV está ativa</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Você está em modo privado</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Ofício 2</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="2418081434543109369">O servidor que você acessará, <ph name="ORIGIN" />, solicitou que
+ uma política de segurança seja aplicada a todas as solicitações. Porém, agora ele
+ deixou de carregar uma política, o que impede que o navegador execute
+ sua solicitação para <ph name="SITE" />.</translation>
<translation id="244665789865330679">Seu dispositivo e sua conta são gerenciados por <ph name="ENROLLMENT_DOMAIN" />. Isso significa que seu administrador pode configurá-los remotamente.</translation>
<translation id="2463193859425327265">Alterar a página inicial</translation>
<translation id="2463739503403862330">Preencher</translation>
+<translation id="2465402087343596252">Arch E</translation>
<translation id="2465655957518002998">Escolher método de entrega</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar o Diagnóstico de Rede<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traduzir esta página</translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
<translation id="2482878487686419369">Notificações</translation>
<translation id="248348093745724435">Políticas do computador</translation>
+<translation id="2485387744899240041">Nomes de usuário para seu dispositivo e navegador</translation>
<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
+<translation id="2493640343870896922">Letter Plus</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>
<translation id="2498091847651709837">Digitalizar novo cartão</translation>
<translation id="2501278716633472235">Voltar</translation>
<translation id="2503184589641749290">Cartões de débito e pré-pagos aceitos</translation>
<translation id="2515629240566999685">Verificar o sinal na sua área</translation>
-<translation id="2516852381693169964">Procurar imagem no <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Salvo apenas neste dispositivo</translation>
<translation id="2524461107774643265">Adicione Mais Informações</translation>
<translation id="2536110899380797252">Adicionar Endereço</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">Seu relógio está adiantado</translation>
<translation id="2634124572758952069">Não foi possível encontrar o endereço IP do servidor de <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Fechar outras guias ou apps</translation>
<translation id="267371737713284912">pressione <ph name="MODIFIER_KEY_DESCRIPTION" /> para desfazer</translation>
<translation id="2674170444375937751">Tem certeza que quer excluir essas páginas do seu histórico?</translation>
+<translation id="2676271551327853224">8K 273 mm x 394 mm</translation>
<translation id="2677748264148917807">Sair</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Cartões aceitos</translation>
<translation id="2702801445560668637">Lista de leitura</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Remover itens selecionados</translation>
<translation id="277133753123645258">Método de envio</translation>
<translation id="277499241957683684">Registro de dispositivo não encontrado</translation>
-<translation id="2781030394888168909">Exportar para MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">A conexão foi redefinida.</translation>
<translation id="2788784517760473862">Cartões de crédito aceitos</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Abrir janela anônima</translation>
+<translation id="2850739647070081192">Convite (Envelope)</translation>
<translation id="2851634818064021665">Você precisa de permissão para visitar este site</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Salvar cartão?</translation>
<translation id="2903493209154104877">Endereços</translation>
<translation id="290376772003165898">A página não está em <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Método de envio</translation>
<translation id="2928905813689894207">Endereço de cobrança</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3037605927509011580">Ah, não!</translation>
<translation id="3041612393474885105">Informações do certificado</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">Saindo do modo de navegação anônima 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="3095940652251934233">Meia carta</translation>
<translation id="3096100844101284527">Adicionar endereço de retirada</translation>
<translation id="3105172416063519923">Código do recurso:</translation>
<translation id="3109728660330352905">Você não tem autorização para ver esta página.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> em <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancelar pagamento</translation>
<translation id="3207960819495026254">Adicionado aos favoritos</translation>
-<translation id="3209375525920864198">Digite um nome de sessão válido.</translation>
+<translation id="321912867715453276">Aviso: há mais de uma fonte para esta política, mas os valores são os mesmos.</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="3229041911291329567">Informações sobre a versão do seu dispositivo e navegador</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Adicionar nome (como consta no cartão)</translation>
<translation id="3287510313208355388">Download quando estiver on-line</translation>
<translation id="3293642807462928945">Saiba mais sobre a política <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nenhum resultado de pesquisa encontrado</translation>
-<translation id="3305707030755673451">Seus dados foram criptografados com sua senha longa de sincronização no dia <ph name="TIME" />. Informe-a para começar a sincronização.</translation>
<translation id="3320021301628644560">Adicionar endereço de faturamento</translation>
<translation id="3324983252691184275">Carmim</translation>
<translation id="3338095232262050444">Seguro</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Refazer editar</translation>
<translation id="342781501876943858">O Chromium recomenda redefinir sua senha se você a reutilizou em outros sites.</translation>
<translation id="3431636764301398940">Salvar este cartão neste dispositivo</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">O proprietário deste dispositivo desativou o jogo do dinossauro.</translation>
<translation id="3447884698081792621">Mostrar certificado (emitido por <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Buscar intervalo:</translation>
+<translation id="3456231139987291353">Nº 11 (Envelope)</translation>
<translation id="3461824795358126837">Marcador</translation>
<translation id="3462200631372590220">Ocultar detalhes</translation>
<translation id="3467763166455606212">O nome do titular do cartão é obrigatório</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Cartões de crédito e pré-pagos são aceitos.</translation>
<translation id="3582930987043644930">Adicionar nome</translation>
<translation id="3583757800736429874">&amp;Refazer mover</translation>
+<translation id="35866233670761917">O conteúdo dos sites que você visita não é visto pelos administradores</translation>
<translation id="3586931643579894722">Ocultar detalhes</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Tamanho 2</translation>
<translation id="3615877443314183785">Informe uma data de validade válida</translation>
<translation id="36224234498066874">Limpar dados de navegação...</translation>
<translation id="362276910939193118">Mostrar histórico completo</translation>
-<translation id="3623476034248543066">Mostrar valor</translation>
<translation id="3630155396527302611">Se ele já estiver listado como um programa que tem permissão para acessar a rede, tente
removê-lo da lista e adicioná-lo novamente.</translation>
+<translation id="3640766068866876100">102 mm × 152 mm</translation>
<translation id="3650584904733503804">Validação bem-sucedida</translation>
<translation id="3655670868607891010">Caso veja esta página com frequência, tente <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisão</translation>
<translation id="366077651725703012">Atualizar cartão de crédito</translation>
<translation id="3676592649209844519">Código do dispositivo:</translation>
+<translation id="3677008721441257057">Você quis dizer &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Não foi possível assinar a solicitação</translation>
<translation id="3678529606614285348">Abrir página em uma nova janela anônima (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Relatório de erros registrado em <ph name="CRASH_TIME" />, enviado em <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">A rede que você está usando pode exigir que você visite a página de login.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Carregando...</translation>
+<translation id="3709599264800900598">Texto que você copiou</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
<translation id="3714780639079136834">Ativar os dados da rede celular ou o Wi-Fi</translation>
<translation id="3715597595485130451">Conectar-se ao Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Verificar a configuração de DNS, proxy e firewall<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Entre os apps que podem causar esse erro estão antivírus, firewall e softwares de filtros ou proxy da Web.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Depois da confirmação, os detalhes do cartão da sua Conta do Google serão compartilhados com este site.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Validade: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Tamanho 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Conteúdo nocivo bloqueado.</translation>
<translation id="3810973564298564668">Gerenciar</translation>
<translation id="382518646247711829">Se você usa um servidor proxy...</translation>
<translation id="3828924085048779000">Uma senha vazia não é permitida.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> instalou extensões para funções adicionais. As extensões têm acesso a alguns dos seus dados.</translation>
<translation id="385051799172605136">Voltar</translation>
<translation id="3858027520442213535">Atualizar data e hora</translation>
<translation id="3884278016824448484">Identificador de dispositivo em conflito</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5 Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Sempre perguntar neste site</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Esse nome de sessão já existe.</translation>
<translation id="3987940399970879459">Menos de 1 MB</translation>
+<translation id="4008849406247176967">Aviso: há mais de uma fonte com valores conflitantes para esta política.</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="4030383055268325496">&amp;Desfazer adicionar</translation>
+<translation id="4032320456957708163">Seu navegador é gerenciado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Chave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Adicione um Endereço Válido</translation>
<translation id="4072486802667267160">Ocorreu um erro ao processar seu pedido. Tente novamente.</translation>
<translation id="4075732493274867456">O cliente e o servidor não são compatíveis com uma versão do protocolo SSL comum ou com o pacote de criptografia.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Roxo</translation>
<translation id="4165986682804962316">Configurações do site</translation>
<translation id="4171400957073367226">Assinatura de verificação inválida</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Mais <ph name="ITEM_COUNT" /> item}one{Mais <ph name="ITEM_COUNT" /> item}other{Mais <ph name="ITEM_COUNT" /> itens}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Etapa 1: fazer login no portal&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Redefinir senha</translation>
<translation id="4280429058323657511">, validade <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Esse cartão foi adicionado à sua Conta do Google}one{Esse cartão foi adicionado à sua Conta do Google}other{Esses cartões foram adicionados à sua Conta do Google}}</translation>
+<translation id="42981349822642051">Expandir</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Alternar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloquear (padrão)</translation>
+<translation id="4318566738941496689">O nome do seu dispositivo e o endereço da rede</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="4340982228985273705">Este computador não foi detectado como gerenciado por empresa, portanto, a política só pode instalar automaticamente as extensões hospedadas na Chrome Web Store. O URL de atualização da Chrome Web Store é o seguinte: <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Cartões de crédito aceitos</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gerenciar formas de pagamento…</translation>
+<translation id="4367563149485757821">Nº 12 (Envelope)</translation>
+<translation id="4372516964750095882">216 mm x 304 mm</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="4378154925671717803">Telefone</translation>
<translation id="4406896451731180161">resultados da pesquisa</translation>
-<translation id="4406972042435603828">Seus administradores instalaram extensões com recursos avançados.</translation>
<translation id="4408413947728134509">Cookies: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Endereço de Retirada</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="443121186588148776">Porta serial</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="4434045419905280838">Pop-ups e redirecionamentos</translation>
+<translation id="4435702339979719576">Postal</translation>
<translation id="443673843213245140">O uso de um proxy está desativado, mas uma configuração explícita de proxy é especificada.</translation>
<translation id="445100540951337728">Cartões de débito aceitos</translation>
+<translation id="4466881336512663640">As alterações no formulário serão perdidas. Tem certeza de que quer continuar?</translation>
<translation id="4482953324121162758">Este site não será traduzido.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL inválido. É necessário um URL com um esquema padrão, como http://example.com ou https://example.com.</translation>
+<translation id="4503882053543859973">Arch D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm 10 (Envelope)</translation>
<translation id="4522570452068850558">Saiba mais</translation>
<translation id="4524805452350978254">Gerenciar cartões</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Tente desativar suas extensões.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Entrega</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Remover cartão</translation>
<translation id="4587425331216688090">Remover endereço do Chrome?</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="4597348597567598915">Tamanho 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Acessar agora</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="467809019005607715">Apresentações Google</translation>
<translation id="4690462567478992370">Suspender o uso de um certificado inválido</translation>
+<translation id="4691835149146451662">Arch A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">A conexão foi interrompida</translation>
<translation id="471880041731876836">Você não tem permissão para visitar este site</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executar o Diagnóstico de Rede do Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Atualizar políticas</translation>
<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Reiniciar o Chromium</translation>
<translation id="473775607612524610">Atualizar</translation>
<translation id="4738601419177586157">Sugestão de pesquisa: <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Gerenciar senhas…</translation>
<translation id="4744603770635761495">Caminho do executável</translation>
+<translation id="4746351372139058112">Mensagens</translation>
<translation id="4750917950439032686">Suas informações (por exemplo, senhas ou números de cartão de crédito) permanecem privadas quando são enviadas para esse site.</translation>
<translation id="4756388243121344051">&amp;Histórico</translation>
<translation id="4758311279753947758">Adicionar dados de contato</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">A página <ph name="URL" /> pode estar temporariamente indisponível ou pode ter sido movida permanentemente para um novo endereço da Web.</translation>
<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4785689107224900852">Alternar para esta guia</translation>
-<translation id="4792143361752574037">Ocorreu um problema ao acessar os arquivos de sessão. O salvamento em disco está desativado no momento. Atualize a página e tente novamente.</translation>
<translation id="4798078619018708837">Informe 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 da sua Conta do Google serão compartilhados com este site.</translation>
<translation id="4800132727771399293">Verifique sua data de validade e seu CVC e tente novamente</translation>
+<translation id="480334179571489655">Erro de política de origem</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Abrir</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Nenhum resultado</translation>
<translation id="4950898438188848926">Botão de alternância de guia. Pressione Enter para alternar para a guia aberta, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Ações</translation>
-<translation id="495832697253704892">Relatório de extensões</translation>
+<translation id="4955242332710481440">A5 Extra</translation>
<translation id="4958444002117714549">Expandir lista</translation>
<translation id="4974590756084640048">Reativar avisos</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Ver tudo</translation>
<translation id="4989809363548539747">Este plug-in não é compatível</translation>
-<translation id="4996230189582812866">Relatórios</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="5014174725590676422">Exibição da tela de primeiro acesso do Google Assistente no Chrome</translation>
<translation id="5015510746216210676">Nome do computador:</translation>
+<translation id="5017554619425969104">Texto que você copiou</translation>
<translation id="5018422839182700155">Não é possível abrir essa página</translation>
<translation id="5019198164206649151">Armazenamento de backup em estado inválido</translation>
<translation id="5023310440958281426">Verifique as políticas do administrador</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Contexto local: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidade</translation>
+<translation id="5043480802608081735">Link que você copiou</translation>
<translation id="5045550434625856497">Senha incorreta</translation>
<translation id="5056549851600133418">Artigos para você</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Verificar o endereço do proxy<ph name="END_LINK" /></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="5097099694988056070">Estatísticas do dispositivo, como uso de CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Seu dispositivo é gerenciado por <ph name="ENROLLMENT_DOMAIN" />, e sua conta é gerenciada por <ph name="ACCOUNT_DOMAIN" />. Isso significa que seus administradores podem configurá-los remotamente.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">64 bits</translation>
-<translation id="5128122789703661928">A sessão com este nome não é válida para exclusão.</translation>
+<translation id="5125394840236832993">B Plus</translation>
<translation id="5135404736266831032">Gerenciar endereços…</translation>
+<translation id="5138227688689900538">Mostrar menos</translation>
<translation id="5141240743006678641">Criptografar senhas sincronizadas com suas credenciais do Google</translation>
<translation id="5145883236150621069">Código de erro presente na resposta da política</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Abrir página em uma nova janela anônima (⇧⌘N)</translation>
<translation id="516920405563544094">Informe o CVC do <ph name="CREDIT_CARD" />. Depois da confirmação, os detalhes do cartão da sua Conta do Google serão compartilhados com este site.</translation>
<translation id="5169827969064885044">Você pode perder o acesso à conta da sua organização ou sofrer roubo de identidade. O Chrome recomenda que você altere sua senha agora.</translation>
<translation id="5171045022955879922">Pesquisar ou digitar URL</translation>
+<translation id="5171689220826475070">Fanfold European</translation>
<translation id="5172758083709347301">Máquina</translation>
<translation id="5179510805599951267">Não está em <ph name="ORIGINAL_LANGUAGE" />? Informe este erro</translation>
<translation id="5190835502935405962">Barra de favoritos</translation>
-<translation id="5200263511887412697">informar a lista de usuários do dispositivo que fizeram login recentemente</translation>
+<translation id="519422657042045905">Anotação indisponível</translation>
<translation id="5201306358585911203">Uma página incorporada nesta página diz</translation>
<translation id="5205222826937269299">Nome obrigatório</translation>
<translation id="5215116848420601511">Formas de pagamento e endereços que usam o Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-mail obrigatório</translation>
<translation id="5230733896359313003">Endereço de entrega</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Conectar-se à rede"</translation>
<translation id="5251803541071282808">Nuvem</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Endereços de rede</translation>
<translation id="5285570108065881030">Mostrar todas as senhas salvas</translation>
<translation id="5287240709317226393">Mostrar cookies</translation>
<translation id="5288108484102287882">A validação dos valores da política gerou alguns avisos</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> de <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Escolher informações de contato</translation>
<translation id="5327248766486351172">Nome</translation>
+<translation id="5329858041417644019">Seu navegador não é gerenciado</translation>
<translation id="5332219387342487447">Forma de envio</translation>
+<translation id="5334013548165032829">Registros detalhados do sistema</translation>
<translation id="5344579389779391559">Esta página pode tentar cobrar pagamento em dinheiro</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Seu relógio está atrasado", "Seu relógio está adiantado" ou "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Para usar seus cartões em todos os dispositivos, faça login e ative a sincronização.</translation>
<translation id="5386426401304769735">A cadeia de certificados desse site contém um certificado assinado usando SHA-1.</translation>
+<translation id="538659543871111977">A4 Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Inválidos</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Refazer editar</translation>
+<translation id="5478437291406423475">Envelope 125 mm x 324 mm</translation>
<translation id="5481076368049295676">Este 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="54817484435770891">Adicionar endereço válido</translation>
<translation id="5490432419156082418">Endereços e mais</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Tente entrar em contato com o administrador do sistema.</translation>
<translation id="549333378215107354">Tamanho 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Favoritos gerenciados</translation>
<translation id="5510766032865166053">Talvez tenha sido movido ou excluído.</translation>
<translation id="5523118979700054094">Nome da política</translation>
<translation id="552553974213252141">O texto foi extraído corretamente?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Não foi possível encontrar o artigo solicitado.</translation>
<translation id="5541546772353173584">Adicione um E-mail</translation>
<translation id="5545756402275714221">Artigos para você</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Editar endereço</translation>
<translation id="5598944008576757369">Escolher forma de pagamento</translation>
<translation id="560412284261940334">Gerenciamento não suportado</translation>
+<translation id="5605670050355397069">Tabloide</translation>
+<translation id="5607240918979444548">Arch C</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>
<translation id="5617949217645503996">Redirecionamento em excesso por <ph name="HOST_NAME" /></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="5632627355679805402">Seus dados foram criptografados com sua <ph name="BEGIN_LINK" />senha do Google<ph name="END_LINK" /> a partir de <ph name="TIME" />. Digite-a para iniciar a sincronização.</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="563324245173044180">Conteúdo enganoso bloqueado.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">O administrador do dispositivo instalou extensões para funções adicionais. As extensões têm acesso a alguns dos seus dados.</translation>
<translation id="5675650730144413517">Esta página não está funcionando</translation>
+<translation id="5684874026226664614">Não foi possível traduzir esta página.</translation>
<translation id="5685654322157854305">Adicionar endereço de entrega</translation>
<translation id="5689199277474810259">Exportar para JSON</translation>
<translation id="5689516760719285838">Local</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">A identidade deste site não foi confirmada.</translation>
<translation id="5719499550583120431">Cartões pré-pagos são aceitos.</translation>
<translation id="5720705177508910913">Usuário atual</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">O Chrome recomenda redefinir sua senha se você a reutilizou em outros sites.</translation>
<translation id="5732392974455271431">Seus responsáveis podem desbloqueá-lo para você</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Salvar cartão na Conta do Google}one{Salvar cartão na Conta do Google}other{Salvar cartões na Conta do Google}}</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="5770114862687765385">O arquivo parece estar corrompido. Clique no botão "Redefinir" para reiniciar a sessão.</translation>
<translation id="5778550464785688721">Controle total de dispositivos MIDI</translation>
<translation id="578305955206182703">Âmbar</translation>
<translation id="57838592816432529">Desativar som</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">Quer preencher as informações do cartão?</translation>
+<translation id="5798290721819630480">Descartar alterações?</translation>
<translation id="5798683403665926540">Altere a página inicial nas configurações do Chrome</translation>
<translation id="5803412860119678065">Quer preencher as informações do seu cartão <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permissões</translation>
<translation id="5810442152076338065">Sua conexão com <ph name="DOMAIN" /> está criptografada com um pacote de criptografia obsoleto.</translation>
<translation id="5813119285467412249">&amp;Refazer adicionar</translation>
<translation id="5838278095973806738">É recomendado não fornecer informações confidencial a esse site (por exemplo, senhas ou cartões de crédito), porque elas podem ser roubadas por invasores.</translation>
+<translation id="5860033963881614850">Desativado</translation>
<translation id="5863847714970149516">A página que você está prestes a acessar pode tentar cobrar pagamentos</translation>
<translation id="5866257070973731571">Adicione um Número de Telefone</translation>
<translation id="5869405914158311789">Não é possível acessar esse site</translation>
<translation id="5869522115854928033">Senhas salvas</translation>
<translation id="5887400589839399685">Cartão salvo</translation>
-<translation id="5893718151540690985">informar uma lista de interfaces de rede com os tipos e endereços de hardware delas</translation>
<translation id="5893752035575986141">Cartões de crédito são aceitos.</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="5916664084637901428">Ativado</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Salvar cartão na Conta do Google?</translation>
<translation id="5922853866070715753">Quase pronto</translation>
<translation id="5932224571077948991">No site, há exibição de anúncios invasivos ou enganosos</translation>
-<translation id="5939518447894949180">Redefinir</translation>
<translation id="5946937721014915347">Abrindo <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Não é possível fazer a inscrição com a conta pessoal (pacote de licença disponível).</translation>
<translation id="5967592137238574583">Edite as Informações de Contato</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Diminuir zoom</translation>
<translation id="5977489021191000276">Seu dispositivo não é gerenciado por um administrador.</translation>
<translation id="5977976211062815271">Neste dispositivo</translation>
+<translation id="5980920751713728343">76 mm x 127 mm</translation>
<translation id="598637245381783098">Não foi possível abrir app de pagamento</translation>
<translation id="5989320800837274978">Nem os servidores proxy fixos nem o URL de script .pac foram especificados.</translation>
<translation id="5990559369517809815">Solicitações ao servidor foram bloqueadas por uma extensão.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">informar estatísticas de hardware, como uso de CPU/RAM</translation>
<translation id="6034000775414344507">Cinza-claro</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Se o problema continuar, entre em contato com o proprietário do site.</translation>
<translation id="6040143037577758943">Fechar</translation>
<translation id="6044573915096792553">Tamanho 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Usar seus cartões em todos os dispositivos?</translation>
<translation id="6059925163896151826">Dispositivos USB</translation>
-<translation id="6071091556643036997">O tipo de política é inválido.</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="6094273045989040137">Anotar</translation>
<translation id="610911394827799129">Sua Conta do Google pode ter outras formas de histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informações sobre extensões e plug-ins instalados</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Libera menos de <ph name="SIZE" />. O carregamento de alguns sites pode ficar mais lento no seu próximo acesso.</translation>
<translation id="6337534724793800597">Filtrar políticas por nome</translation>
<translation id="6358450015545214790">O que são essas informações?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Acesso sujeito a cobranças.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 outra sugestão}one{# outra sugestão}other{# outras sugestões}}</translation>
<translation id="6387754724289022810">Para agilizar o pagamento na próxima vez, salve o cartão e o endereço de faturamento na sua Conta do Google e neste dispositivo.</translation>
+<translation id="6390662030813198813">Engineering E</translation>
<translation id="6404511346730675251">Editar favorito</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Descartar</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Adicionar mais informações</translation>
<translation id="6447842834002726250">Cookies</translation>
<translation id="6451458296329894277">Confirmar reenvio do formulário</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Reiniciar o Chrome</translation>
<translation id="6529602333819889595">&amp;Refazer excluir</translation>
<translation id="6534179046333460208">Sugestões da Web física</translation>
+<translation id="6556866813142980365">Refazer</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="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Rosa-claro</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link que você copiou</translation>
+<translation id="6591833882275308647">Seu <ph name="DEVICE_TYPE" /> não é gerenciado</translation>
<translation id="6596325263575161958">Opções de criptografia</translation>
<translation id="6604181099783169992">Sensores de luz ou movimento</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Informações de Contato</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>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Esta política foi encerrada.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nenhum}=1{De 1 site (você não será desconectado da sua Conta do Google)}one{De # site (você não será desconectado da sua Conta do Google)}other{De # sites (você não será desconectado da sua Conta do Google)}}</translation>
<translation id="6657585470893396449">Senha</translation>
+<translation id="6670613747977017428">Voltar à segurança.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Token de inscrição:</translation>
<translation id="6711464428925977395">Há algo errado com o servidor proxy, ou o endereço está incorreto.</translation>
<translation id="6723740634201835758">Na Conta do Google</translation>
+<translation id="6738516213925468394">Seus dados foram criptografados com sua <ph name="BEGIN_LINK" />senha longa de sincronização<ph name="END_LINK" /> em <ph name="TIME" />. Digite-a para iniciar a sincronização.</translation>
<translation id="674375294223700098">Erro, certificado de servidor desconhecido.</translation>
<translation id="6744009308914054259">Enquanto espera por uma conexão, acesse "Downloads" para ler artigos off-line.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6757797048963528358">O dispositivo entrou em modo de suspensão.</translation>
+<translation id="6768213884286397650">Hagaki (Postal)</translation>
<translation id="6778737459546443941">Seu responsável ainda não o aprovou</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Extensões</translation>
<translation id="679355240208270552">Ignorado porque a pesquisa padrão não foi ativada pela política.</translation>
<translation id="681021252041861472">Campo obrigatório</translation>
<translation id="6810899417690483278">Código de personalização</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">Distrito</translation>
<translation id="6973656660372572881">Ambos os servidores proxy fixo e um URL de script .pac foram especificados.</translation>
+<translation id="6973932557599545801">Não posso ajudar. Você está por conta própria.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Desativar som (padrão)</translation>
<translation id="6984479912851154518">Saindo do modo privado para fazer um pagamento com um aplicativo externo. Continuar?</translation>
<translation id="6989763994942163495">Mostrar configurações avançadas...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Sempre traduzir <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Essas cobranças podem ser únicas ou recorrentes e talvez não sejam óbvias.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ocultar</translation>
<translation id="7108819624672055576">Permitida por uma extensão</translation>
<translation id="7111012039238467737">(válido)</translation>
+<translation id="7118618213916969306">Pesquisa o URL da área de transferência, <ph name="SHORT_URL" /></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="7135130955892390533">Mostrar status</translation>
<translation id="7138472120740807366">Método de entrega</translation>
<translation id="7139724024395191329">Emirado</translation>
+<translation id="7152423860607593928">Nº 14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavanda</translation>
-<translation id="7158980942472052083">URL inválido. É necessário um URL com um esquema padrão.</translation>
<translation id="717330890047184534">Código Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">O servidor que você acessará, <ph name="ORIGIN" />, solicitou que
+ uma política de segurança seja aplicada a todas as solicitações. Porém, em vez de
+ exibir uma política, ele redirecionou o navegador para outro lugar, o que impede
+ a execução da sua solicitação de <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Salvar e preencher as formas de pagamento</translation>
<translation id="7180611975245234373">Atualizar</translation>
<translation id="7182878459783632708">Não há políticas definidas</translation>
<translation id="7186367841673660872">Esta página foi traduzida de<ph name="ORIGINAL_LANGUAGE" />para<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Libera <ph name="SIZE" />. O carregamento de alguns sites pode ficar mais lento no seu próximo acesso.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">O administrador pode ver:</translation>
+<translation id="7202346780273620635">Letter Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> não adere aos padrões de segurança.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /> sobre este problema.</translation>
<translation id="7219179957768738017">A conexão usa a <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Processando</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />, <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">O site a seguir contém malware</translation>
+<translation id="724766306220616965">Avisos, conflito</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="7251437084390964440">A configuração de rede não está de acordo com o padrão ONC. É possível que partes da configuração não sejam importadas.
Mais detalhes:
@@ -982,11 +1120,14 @@ Mais detalhes:
<translation id="7300012071106347854">Azul-cobalto</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Avisos do <ph name="BEGIN_LINK" />Navegação segura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ajuda de conexão</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4 Extra</translation>
<translation id="7353601530677266744">Linha de comando</translation>
-<translation id="7365061714576910172">Exportar para Linux</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>
@@ -994,6 +1135,7 @@ Mais detalhes:
<translation id="7381288752349550461">Modificação de sessão gerenciada</translation>
<translation id="7390545607259442187">Confirmar cartão</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Seu <ph name="DEVICE_NAME" /> é gerenciado</translation>
<translation id="7407424307057130981">&lt;p&gt;Você verá esse erro se tiver o software Superfish no seu computador Windows.&lt;/p&gt;
&lt;p&gt;Siga estas etapas para desativar temporariamente o software. Assim, você poderá se conectar à Web. Será necessário ter de privilégios de administrador.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Mais detalhes:
&lt;li&gt;Clique em &lt;strong&gt;Aplicar&lt;/strong&gt; e depois em &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Visite a &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Central de Ajuda do Chrome&lt;/a&gt; para saber como remover permanentemente o software do seu computador
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gerenciamento do <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Formato largo</translation>
<translation id="7416351320495623771">Gerenciar senhas…</translation>
<translation id="7419106976560586862">Caminho de perfil</translation>
<translation id="7437289804838430631">Adicionar Informações de Contato</translation>
@@ -1013,22 +1155,24 @@ Mais detalhes:
<translation id="7442725080345379071">Laranja-claro</translation>
<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="7449109375006139765">enviar registros do sistema para o servidor de gerenciamento</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="7460618730930299168">A exibição na tela está diferente da que você selecionou. Continuar?</translation>
<translation id="7473891865547856676">Não, obrigado</translation>
-<translation id="7475525192983021547">informar os períodos de atividade do usuário no dispositivo</translation>
<translation id="7481312909269577407">Avançar</translation>
<translation id="7485870689360869515">Nenhum dado encontrado</translation>
+<translation id="7498234416455752244">Continuar editando</translation>
<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="7508870219247277067">Verde-abacate</translation>
<translation id="7511955381719512146">O Wi-Fi que você está usando pode exigir a visita a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Sua conexão a este site não é particular</translation>
+<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obrigatória</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1037,8 +1181,8 @@ Mais detalhes:
<translation id="7552846755917812628">Tente seguir estas dicas:</translation>
<translation id="7554791636758816595">Nova guia</translation>
<translation id="7564049878696755256">Você pode perder o acesso à sua conta de <ph name="ORG_NAME" /> ou ter sua identidade roubada. O Chrome recomenda que sua senha seja alterada agora.</translation>
-<translation id="7566125604157659769">Texto que você copiou</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="7568105740864181217">Este navegador é gerenciado por uma empresa, escola ou outra organização. O administrador pode alterar as configurações do navegador remotamente. A atividade deste dispositivo também pode ser gerenciada fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Mais detalhes:
<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="7633909222644580952">Dados de desempenho e relatórios de erros</translation>
<translation id="7637571805876720304">Remover cartão de crédito do Chromium?</translation>
<translation id="7639968568612851608">Cinza-escuro</translation>
<translation id="765676359832457558">Ocultar configurações avançadas...</translation>
@@ -1058,9 +1203,11 @@ Mais detalhes:
<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="7676643023259824263">Pesquisar um texto na área de transferência, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Alterar mecanismo de pesquisa</translation>
<translation id="7682287625158474539">Entrega</translation>
<translation id="7687186412095877299">Preencher formulários com suas formas de pagamento salvas</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">No momento, você tem cartões que só podem ser usados neste dispositivo. Clique em "Continuar" para analisá-los.</translation>
<translation id="7699293099605015246">Os artigos não estão disponíveis no momento</translation>
<translation id="7701040980221191251">Nenhum</translation>
@@ -1072,11 +1219,13 @@ Mais detalhes:
<translation id="774634243536837715">Conteúdo perigoso bloqueado.</translation>
<translation id="7752995774971033316">Não gerenciado</translation>
<translation id="7755287808199759310">Seu responsável pode desbloqueá-lo para você</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">É possível que o software antivírus ou o firewall tenha bloqueado a conexão.</translation>
<translation id="7759163816903619567">Domínio de exibição:</translation>
<translation id="7761701407923456692">O certificado do servidor não é compatível com o URL.</translation>
<translation id="7763386264682878361">Analisador de manifesto de pagamento</translation>
<translation id="7764225426217299476">Adicionar endereço</translation>
+<translation id="7770259615151589601">Envelope DL</translation>
<translation id="777702478322588152">Município</translation>
<translation id="7791543448312431591">Adicionar</translation>
<translation id="7793809570500803535">A página da web em <ph name="SITE" /> pode estar temporariamente indisponível ou pode ter sido movida permanentemente para um novo endereço da Web.</translation>
@@ -1088,8 +1237,8 @@ Mais detalhes:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Remover sugestão de formulário do Chrome?</translation>
<translation id="7815407501681723534">Localizados <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> para "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Gerenciamento de políticas</translation>
<translation id="782886543891417279">O Wi-Fi que você está usando (<ph name="WIFI_NAME" />) pode exigir a visita a uma página de login.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nenhum}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# app (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">O modo invisível NÃO oculta seus dados de navegação. Seu empregador, seu provedor de Internet e os websites visitados continuam tendo acesso a essas informações.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Mais detalhes:
<translation id="7878562273885520351">Sua senha pode estar comprometida</translation>
<translation id="7882421473871500483">Marrom</translation>
<translation id="7887683347370398519">Verifique seu CVC e tente novamente</translation>
-<translation id="7893255318348328562">Nome da sessão</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Informe um número de telefone válido</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Expira em <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Mais detalhes:
<translation id="7951415247503192394">32 bits</translation>
<translation id="7956713633345437162">Favoritos de dispositivos móveis</translation>
<translation id="7961015016161918242">Nunca</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Não especificado</translation>
<translation id="800218591365569300">Tente fechar outras guias ou programas para liberar memória.</translation>
+<translation id="8004582292198964060">Navegador</translation>
<translation id="8009225694047762179">Gerenciar senha</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Este cartão e o endereço de faturamento dele serão salvos. Você poderá usá-lo quando a conta <ph name="USER_EMAIL" /> estiver conectada.}one{Este cartão e o endereço de faturamento dele serão salvos. Você poderá usá-lo quando a conta <ph name="USER_EMAIL" /> estiver conectada.}other{Estes cartões e os endereços de faturamento deles serão salvos. Você poderá usá-los quando a conta <ph name="USER_EMAIL" /> estiver conectada.}}</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="8034522405403831421">Esta página está escrita em <ph name="SOURCE_LANGUAGE" />. Traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Caneta</translation>
+<translation id="8037117624646282037">Quem usou o dispositivo recentemente</translation>
<translation id="8037357227543935929">Perguntar (padrão)</translation>
<translation id="803771048473350947">Arquivo</translation>
<translation id="8041089156583427627">Enviar comentários</translation>
<translation id="8041940743680923270">Usar padrão global (Perguntar)</translation>
<translation id="8042918947222776840">Escolher método de retirada</translation>
<translation id="8057711352706143257">O software "<ph name="SOFTWARE_NAME" />" não foi configurado corretamente. A desinstalação do "<ph name="SOFTWARE_NAME" />" costuma resolver o problema. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Seu dispositivo foi configurado para:</translation>
+<translation id="8066955247577885446">Algo deu errado.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Não é possível fazer anotações em documentos girados</translation>
<translation id="8079031581361219619">Atualizar o site?</translation>
<translation id="8088680233425245692">Falha ao exibir artigo.</translation>
@@ -1131,11 +1284,12 @@ Mais detalhes:
<translation id="8091372947890762290">A ativação está pendente no servidor</translation>
<translation id="8092774999298748321">Roxo intenso</translation>
<translation id="8094917007353911263">A rede que você está usando pode exigir uma visita a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Os cartões inválidos foram removidos</translation>
<translation id="8103161714697287722">Forma de Pagamento</translation>
<translation id="8118489163946903409">Método de pagamento</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> gerenciado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">O software "<ph name="SOFTWARE_NAME" />" não foi instalado corretamente no computador ou na rede. Peça ao administrador de TI para resolver o problema.</translation>
-<translation id="8130693978878176684">Não posso mais ajudar. Você está por conta própria.</translation>
<translation id="8131740175452115882">Confirmar</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>
@@ -1145,8 +1299,11 @@ Mais detalhes:
<translation id="8197543752516192074">Traduzir página</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="8202370299023114387">Conflito</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">A conexão é segura</translation>
<translation id="8218327578424803826">Local designado:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Abrir página em uma nova guia anônima</translation>
@@ -1158,14 +1315,16 @@ Mais detalhes:
<translation id="825929999321470778">Mostrar todas as senhas salvas</translation>
<translation id="8261506727792406068">Excluir</translation>
<translation id="8267698848189296333">Fazendo login como <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Este navegador é gerenciado por <ph name="ENROLLMENT_DOMAIN" />. Seu administrador pode alterar a configuração do navegador remotamente. A atividade deste dispositivo também pode ser gerenciada fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large photo</translation>
<translation id="8286036467436129157">Fazer login</translation>
<translation id="8288807391153049143">Mostrar certificado</translation>
<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="8298115750975731693">O Wi-Fi que você está usando (<ph name="WIFI_NAME" />) pode exigir a visita a <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small photo</translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a conexão de rede.</translation>
-<translation id="8311129316111205805">Carregar sessão</translation>
<translation id="8332188693563227489">O acesso a <ph name="HOST_NAME" /> foi negado</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Mais detalhes:
<translation id="8416694386774425977">A configuração de rede é inválida e não pôde ser importada.
Mais detalhes:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositivo gerenciado por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Alterar</translation>
<translation id="8428213095426709021">Configurações</translation>
@@ -1211,9 +1369,11 @@ Mais detalhes:
<translation id="860043288473659153">Nome do titular do cartão</translation>
<translation id="861775596732816396">Tamanho 4</translation>
<translation id="8620436878122366504">Seus responsáveis ainda não o aprovaram</translation>
+<translation id="8622948367223941507">Legal extra</translation>
<translation id="8625384913736129811">Salvar este cartão neste dispositivo</translation>
<translation id="8663226718884576429">Resumo do pedido, <ph name="TOTAL_LABEL" />, Mais detalhes</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, resposta, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Sua conexão com <ph name="DOMAIN" /> não está criptografada.</translation>
<translation id="8718314106902482036">Pagamento não concluído</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sugestão de pesquisa</translation>
@@ -1227,6 +1387,7 @@ Mais detalhes:
<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="8763927697961133303">Dispositivo USB</translation>
<translation id="8768895707659403558">Para usar seus cartões em todos os dispositivos, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Refazer excluir</translation>
<translation id="8792621596287649091">Você pode perder o acesso à sua conta de <ph name="ORG_NAME" /> ou ter sua identidade roubada. O Chromium recomenda que sua senha seja alterada agora.</translation>
<translation id="8800988563907321413">As sugestões de itens nas proximidades são exibidas aqui</translation>
@@ -1237,10 +1398,12 @@ Mais detalhes:
<translation id="885730110891505394">Compartilhar com o Google</translation>
<translation id="8858065207712248076">O Chrome recomenda redefinir sua senha de <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> se você a reutilizou em outros sites.</translation>
<translation id="8866481888320382733">Configurações da política de análise de erros</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Recentemente fechadas</translation>
<translation id="8874824191258364635">Informe um número de cartão válido</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
<translation id="8903921497873541725">Aumentar zoom</translation>
+<translation id="890485472659500557">Engineering C</translation>
<translation id="8931333241327730545">Quer salvar este cartão na sua Conta do Google?</translation>
<translation id="8932102934695377596">Seu relógio está atrasado</translation>
<translation id="893332455753468063">Adicione um Nome</translation>
@@ -1248,13 +1411,13 @@ Mais detalhes:
<translation id="894185898663964645">Seu administrador configurou certificados raiz personalizados, o que pode permitir que ele veja o conteúdo dos sites que você visita.</translation>
<translation id="8943282376843390568">Verde-limão</translation>
<translation id="8957210676456822347">Autorização de portal cativo</translation>
+<translation id="8966619695390250636">Você quis dizer?</translation>
<translation id="8968766641738584599">Salvar cartão</translation>
<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8975012916872825179">Inclui informações como números de telefone, endereços de e-mail e endereços de entrega</translation>
<translation id="8978053250194585037">Recentemente, o recurso "Navegação segura" do Google <ph name="BEGIN_LINK" />detectou phishing<ph name="END_LINK" /> em <ph name="SITE" />. Os sites de phishing fingem ser outros sites para enganar você.</translation>
<translation id="8983003182662520383">Formas de pagamento e endereços que usam o Google Pay</translation>
<translation id="8987927404178983737">Mês</translation>
-<translation id="8988408250700415532">Algo deu errado. Você pode terminar o pedido no site.</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>
@@ -1264,6 +1427,7 @@ Mais detalhes:
<translation id="9011424611726486705">Abra as configurações do site</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(inválido)</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>
@@ -1275,12 +1439,12 @@ Mais detalhes:
<translation id="9065745800631924235">Pesquisa sobre <ph name="TEXT" /> no histórico</translation>
<translation id="9069693763241529744">Bloqueada por uma extensão</translation>
<translation id="9076283476770535406">Pode apresentar conteúdo adulto</translation>
+<translation id="9076630408993835509">Este navegador não é gerenciado por uma empresa ou outra organização. A atividade deste dispositivo pode ser gerenciada fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">São necessárias mais informações</translation>
<translation id="9080712759204168376">Resumo do pedido</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
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 Chromium interrompeu a conexão antes que os dados fossem trocados.</translation>
<translation id="9106062320799175032">Adicione um Endereço de Faturamento</translation>
-<translation id="9110718169272311511">O Google Assistente no Chrome está disponível perto da parte inferior da tela</translation>
<translation id="9114524666733003316">Confirmando cartão…</translation>
<translation id="9128870381267983090">Conectar-se à rede</translation>
<translation id="9137013805542155359">Mostrar original</translation>
@@ -1289,6 +1453,7 @@ 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="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Permite que os sites verifiquem se você tem formas de pagamento salvas</translation>
<translation id="9169664750068251925">Sempre bloquear neste site</translation>
<translation id="9170848237812810038">&amp;Desfazer</translation>
@@ -1303,10 +1468,12 @@ incomuns e incorretas. Isso pode acontecer quando um invasor está fingindo ser
<translation id="9219103736887031265">Imagens</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">LIMPAR FORMULÁRIO</translation>
+<translation id="936474030629450166">Super B</translation>
<translation id="936602727769022409">Você pode perder o acesso à sua Conta do Google. O Chromium recomenda que sua senha seja alterada agora. Solicitaremos que você faça login.</translation>
<translation id="939736085109172342">Nova pasta</translation>
<translation id="945855313015696284">Verifique as informações abaixo e exclua todos os cartões inválidos</translation>
<translation id="951104842009476243">Cartões de débito e pré-pagos aceitos</translation>
+<translation id="958202389743790697">Bloqueado de acordo com política de segurança de <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Este conteúdo pode tentar instalar apps enganosos que fingem ser outra coisa ou coletam dados que podem ser usados para rastrear você. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Versão oficial</translation>
<translation id="973773823069644502">Adicionar endereço de entrega</translation>
@@ -1315,6 +1482,7 @@ incomuns e incorretas. Isso pode acontecer quando um invasor está fingindo ser
<translation id="984275831282074731">Formas de pagamento</translation>
<translation id="985199708454569384">&lt;p&gt;Esse erro será exibido se a data e a hora do computador ou dispositivo móvel estiverem incorretas.&lt;/p&gt;
&lt;p&gt;Para corrigir o erro, abra o relógio do dispositivo e verifique se a hora e a data estão corretas.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Versão do desenvolvedor</translation>
<translation id="989988560359834682">Editar endereço</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_pt-PT.xtb b/chromium/components/strings/components_strings_pt-PT.xtb
index 66fba6b1192..2313fb25083 100644
--- a/chromium/components/strings/components_strings_pt-PT.xtb
+++ b/chromium/components/strings/components_strings_pt-PT.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pt-PT">
-<translation id="1005145902654145231">Falha ao mudar o nome da sessão.</translation>
<translation id="1008557486741366299">Agora não</translation>
<translation id="1010200102790553230">Carregar a página mais tarde</translation>
<translation id="1015730422737071372">Forneça mais detalhes</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nome desconhecido</translation>
<translation id="1050038467049342496">Fechar outras aplicações</translation>
<translation id="1055184225775184556">&amp;Anular adição</translation>
+<translation id="1056898198331236512">Aviso</translation>
<translation id="1058479211578257048">A guardar os cartões…</translation>
<translation id="10614374240317010">Nunca guardadas</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Marcadores do Ambiente de Trabalho</translation>
<translation id="1074497978438210769">Inseguro</translation>
<translation id="1080116354587839789">Ajustar à largura</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Adicionar nome no cartão</translation>
<translation id="1089439967362294234">Alterar palavra-passe</translation>
<translation id="109743633954054152">Gerir palavras-passe nas definições do Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Pode ser frequente a apresentação de avisos enquanto os Websites atualizam a respetiva segurança. Esta situação deve melhorar brevemente.</translation>
<translation id="1126551341858583091">O tamanho no armazenamento local é de <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cache da política OK</translation>
+<translation id="1131264053432022307">Imagem que copiou</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Mudar nome</translation>
<translation id="1175364870820465910">Im&amp;primir...</translation>
<translation id="1181037720776840403">Remover</translation>
<translation id="1197088940767939838">Laranja</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">O nome do dispositivo</translation>
<translation id="124116460088058876">Mais idiomas</translation>
<translation id="1250759482327835220">Para pagar mais rapidamente da próxima vez, guarde o cartão, o nome e o endereço de faturação na sua Conta Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizados)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variações da linha de comandos</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="1314614906530272393">A sessão selecionada não existe.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Pesquisar imagem da área de transferência</translation>
<translation id="1323433172918577554">Mostrar mais</translation>
<translation id="132390688737681464">Guardar e preencher endereços</translation>
<translation id="1333989956347591814">A sua atividade <ph name="BEGIN_EMPHASIS" />poderá continuar visível<ph name="END_EMPHASIS" /> para:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Endereço de recolha</translation>
<translation id="1348198688976932919">O site que pretende visitar contém aplicações perigosas</translation>
<translation id="1348779747280417563">Confirmar nome</translation>
+<translation id="1357195169723583938">Quem utilizou o dispositivo recentemente e quando</translation>
+<translation id="1364822246244961190">Esta política está bloqueada e o valor será ignorado.</translation>
<translation id="1374468813861204354">sugestões</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">Acerca da versão</translation>
<translation id="1376836354785490390">Mostrar menos</translation>
<translation id="1377321085342047638">N.º cartão</translation>
<translation id="138218114945450791">Azul-claro</translation>
+<translation id="1382194467192730611">Dispositivo USB permitido pelo administrador</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> não enviou quaisquer dados.</translation>
+<translation id="140316286225361634">O site <ph name="ORIGIN" /> solicitou que seja aplicada uma política de segurança
+ a todos os pedidos e esta política considera atualmente o site
+ inseguro.</translation>
<translation id="1405567553485452995">Verde-claro</translation>
<translation id="1407135791313364759">Abrir tudo</translation>
<translation id="1413809658975081374">Erro de privacidade</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Sim</translation>
<translation id="1430915738399379752">Imprimir</translation>
<translation id="1455413310270022028">Borracha</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Mostrar mais</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Escolher morada para envio</translation>
+<translation id="1492194039220927094">Push das políticas:</translation>
<translation id="1501859676467574491">Mostrar cartões da sua Conta Google</translation>
-<translation id="1506687042165942984">Mostrar uma cópia guardada desta página (isto é, uma cópia desatualizada).</translation>
<translation id="1507202001669085618">&lt;p&gt;Este erro é apresentado se estiver a utilizar um portal Wi-Fi que requer que inicie sessão para poder aceder à Internet.&lt;/p&gt;
&lt;p&gt;Para corrigir o erro, clique em &lt;strong&gt;Ligar&lt;/strong&gt; na página que está a tentar abrir.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Número de telefone obrigatório</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Data da Compilação</translation>
<translation id="1521655867290435174">Google Sheets</translation>
<translation id="1527263332363067270">A aguardar ligação…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Esta página diz</translation>
<translation id="153384715582417236">É tudo por agora</translation>
<translation id="154408704832528245">Escolher endereço de entrega</translation>
<translation id="1549470594296187301">É necessário ativar o JavaScript para utilizar esta funcionalidade.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Introduza a data de validade</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imagem que copiou</translation>
<translation id="1620510694547887537">Câmara</translation>
<translation id="1623104350909869708">Evitar que esta página crie caixas de diálogo adicionais</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Terminar sessão</translation>
<translation id="1639239467298939599">A carregar</translation>
<translation id="1640180200866533862">Políticas do utilizador</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">O certificado do servidor contém uma chave criptográfica fraca.</translation>
<translation id="1697532407822776718">O processo está concluído!</translation>
+<translation id="1703835215927279855">Letter</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.}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="1715874602234207">F</translation>
<translation id="1718029547804390981">O documento é demasiado grande para ser anotado.</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Experimente contactar o gestor do sistema.</translation>
<translation id="1740951997222943430">Introduza um mês de expiração válido</translation>
<translation id="1743520634839655729">Para pagar mais rapidamente da próxima vez, guarde o cartão, o nome e o endereço de faturação na sua Conta Google e neste dispositivo.</translation>
+<translation id="1745880797583122200">O seu navegador é gerido</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Atualize a frase de acesso de sincronização.</translation>
<translation id="1787142507584202372">Os separadores abertos aparecem aqui</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Nome do titular do cartão</translation>
<translation id="1821930232296380041">Pedido ou parâmetros do pedido inválidos</translation>
+<translation id="1822540298136254167">Os Websites que visita e o tempo despendido nos mesmos.</translation>
<translation id="1826516787628120939">A verificar</translation>
<translation id="1834321415901700177">Este site contém programas prejudiciais</translation>
<translation id="1839551713262164453">A validação dos valores da política falhou devido a erros.</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Limpar os dados do histórico de navegação do Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{e mais 1}other{e mais #}}</translation>
<translation id="2003709556000175978">Repor a palavra-passe agora</translation>
+<translation id="20053308747750172">O servidor ao qual irá aceder, <ph name="ORIGIN" />, solicitou que seja aplicada uma
+ política de segurança a todos os pedidos. Contudo, devolveu agora
+ uma política inválida, o que impede o navegador de
+ satisfazer o seu pedido para <ph name="SITE" />.</translation>
<translation id="2025186561304664664">O proxy está definido para configuração automática.</translation>
<translation id="2030481566774242610">Será que quis dizer <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Verificar o proxy e a firewall<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departamento</translation>
<translation id="2102134110707549001">Sugerir palavra-passe forte…</translation>
<translation id="2108755909498034140">Reiniciar o computador</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Cartão</translation>
<translation id="2114841414352855701">Ignorada porque foi substituída por <ph name="POLICY_NAME" /> .</translation>
<translation id="213826338245044447">Marcadores de Telemóvel</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Editar cartão</translation>
<translation id="2166049586286450108">Acesso de gestor total</translation>
<translation id="2166378884831602661">Este site não consegue fornecer uma ligação segura</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Políticas</translation>
<translation id="2183608646556468874">Número de telefone</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 endereço}other{# endereços}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Número de telefone</translation>
<translation id="2283340219607151381">Guardar e preencher endereços</translation>
<translation id="2292556288342944218">O acesso à Internet está bloqueado</translation>
+<translation id="2294558542833290837">O link que abriu inicialmente é pouco habitual.</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Liberta menos de 1 MB. É possível que alguns sites sejam carregados mais lentamente na sua próxima visita.</translation>
<translation id="2317259163369394535">O domínio <ph name="DOMAIN" /> requer um nome de utilizador e uma palavra-passe.</translation>
<translation id="2317583587496011522">Os cartões de débito são admitidos.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, expira a <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Definição controlada pelo gestor</translation>
+<translation id="2346319942568447007">Imagem que copiou</translation>
<translation id="2349790679044093737">A sessão de RV está ativa</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Entrou no modo privado</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">O servidor ao qual irá aceder, <ph name="ORIGIN" />, solicitou que seja aplicada uma
+ política de segurança a todos os pedidos. Contudo, não
+ conseguiu devolver uma política, o que impede o navegador de satisfazer
+ o seu pedido para <ph name="SITE" />.</translation>
<translation id="244665789865330679">O seu dispositivo e a sua conta são geridos por <ph name="ENROLLMENT_DOMAIN" />. Isto significa que o seu administrador pode configurar remotamente o seu dispositivo e a sua conta.</translation>
<translation id="2463193859425327265">Alterar página inicial</translation>
<translation id="2463739503403862330">Preencher</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Escolher método de fornecimento</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Executar o Diagnóstico de rede<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Traduzir esta página</translation>
<translation id="2479410451996844060">URL de pesquisa inválido.</translation>
<translation id="2482878487686419369">Notificações</translation>
<translation id="248348093745724435">Políticas do computador</translation>
+<translation id="2485387744899240041">Os nomes de utilizador para o dispositivo e o navegador.</translation>
<translation id="2491120439723279231">O certificado do servidor contém erros.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Digitalizar novo cartão</translation>
<translation id="2501278716633472235">Voltar</translation>
<translation id="2503184589641749290">Cartões de débito e pré-pagos admitidos</translation>
<translation id="2515629240566999685">Verificar o sinal na área</translation>
-<translation id="2516852381693169964">Pesquisar Imagem no <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Guardado apenas neste dispositivo.</translation>
<translation id="2524461107774643265">Adicionar mais informações</translation>
<translation id="2536110899380797252">Adicionar endereço</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">O seu relógio está adiantado</translation>
<translation id="2634124572758952069">Não foi possível encontrar o endereço IP do servidor de <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Estado:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Fechar outros separadores ou aplicações</translation>
<translation id="267371737713284912">prima <ph name="MODIFIER_KEY_DESCRIPTION" /> para anular</translation>
<translation id="2674170444375937751">Tem a certeza de que pretende eliminar estas páginas do seu histórico?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Sair</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Cartões aceites</translation>
<translation id="2702801445560668637">Lista de leitura</translation>
<translation id="2704283930420550640">O valor não corresponde ao formato.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Remover itens seleccionados</translation>
<translation id="277133753123645258">Método de envio</translation>
<translation id="277499241957683684">Registo do dispositivo em falta</translation>
-<translation id="2781030394888168909">Exportar para MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">A ligação foi reposta.</translation>
<translation id="2788784517760473862">Cartões de crédito admitidos</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Abrir janela de navegação anónima</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Necessita de autorização para aceder a este site</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Pretende guardar o cartão?</translation>
<translation id="2903493209154104877">Endereços</translation>
<translation id="290376772003165898">A página não está em <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Método de fornecimento</translation>
<translation id="2928905813689894207">Endereço de faturação</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{<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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Tipo de política incorreto</translation>
<translation id="3037605927509011580">Ah, bolas!!</translation>
<translation id="3041612393474885105">Informações do certificado</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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}other{# palavras-passe}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Adicionar endereço de levantamento</translation>
<translation id="3105172416063519923">ID de recurso:</translation>
<translation id="3109728660330352905">Não tem autorização para ver esta página.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> no servidor <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Cancelar pagamento</translation>
<translation id="3207960819495026254">Adicionado aos marcadores</translation>
-<translation id="3209375525920864198">Introduza um nome de sessão válido.</translation>
+<translation id="321912867715453276">Aviso: existe mais de uma origem para a política, mas os valores são iguais.</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="3229041911291329567">Informações da versão do dispositivo e do navegador.</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Adicionar nome no cartão</translation>
<translation id="3287510313208355388">Transferir quando estiver online</translation>
<translation id="3293642807462928945">Saiba mais acerca da política <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Não foram encontrados resultados da pesquisa</translation>
-<translation id="3305707030755673451">Os dados foram encriptados com a sua frase de acesso de sincronização em <ph name="TIME" />. Introduza-a para iniciar a sincronização.</translation>
<translation id="3320021301628644560">Adicionar endereço de faturação</translation>
<translation id="3324983252691184275">Carmesim</translation>
<translation id="3338095232262050444">Seguro</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Refazer edição</translation>
<translation id="342781501876943858">O Chromium recomenda a reposição da palavra-passe se a tiver reutilizado noutros sites.</translation>
<translation id="3431636764301398940">Guardar este cartão neste dispositivo</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">O proprietário deste dispositivo desativou o jogo do dinossauro.</translation>
<translation id="3447884698081792621">Mostrar certificado (emitido por <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Intervalo de obtenção:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Marcador</translation>
<translation id="3462200631372590220">Ocultar avançadas</translation>
<translation id="3467763166455606212">Nome do titular do cartão obrigatório</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Os cartões de crédito e pré-pagos são admitidos.</translation>
<translation id="3582930987043644930">Adicionar nome</translation>
<translation id="3583757800736429874">&amp;Refazer movimentação</translation>
+<translation id="35866233670761917">O conteúdo dos Websites que visita não são visualizados pelos seus administradores.</translation>
<translation id="3586931643579894722">Ocultar detalhes</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Tamanho 2</translation>
<translation id="3615877443314183785">Introduza uma data de expiração válida</translation>
<translation id="36224234498066874">Limpar dados de navegação...</translation>
<translation id="362276910939193118">Mostrar histórico completo</translation>
-<translation id="3623476034248543066">Apresentar o valor</translation>
<translation id="3630155396527302611">Se já estiver indicado na lista como sendo um programa com permissão para aceder à rede, experimente
removê-lo da lista e adicioná-lo novamente.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validação com êxito</translation>
<translation id="3655670868607891010">Se vê isto com frequência, experimente <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Revisão</translation>
<translation id="366077651725703012">Atualizar cartão de crédito</translation>
<translation id="3676592649209844519">ID do dispositivo:</translation>
+<translation id="3677008721441257057">Será que quis dizer &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Não foi possível assinar o pedido</translation>
<translation id="3678529606614285348">Abrir a página numa nova janela de navegação anónima (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Relatório de falhas capturado no(a) <ph name="CRASH_TIME" /> e carregado no(a) <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">A rede que está a utilizar pode exigir que visite a respetivapágina de início de sessão.</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="3709599264800900598">Texto que copiou</translation>
<translation id="3712624925041724820">Licenças esgotadas</translation>
<translation id="3714780639079136834">Ativar os dados móveis ou o Wi-Fi</translation>
<translation id="3715597595485130451">Estabelecer ligação a redes Wi-Fi</translation>
<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="372429172604983730">As aplicações que podem causar este erro incluem antivírus, firewalls e software de filtragem Web ou proxy.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Depois de confirmar, os detalhes do cartão da sua Conta Google são partilhados com este site.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expira a <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Tamanho 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Conteúdo prejudicial bloqueado.</translation>
<translation id="3810973564298564668">Gerir</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="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> instalou extensões para funções adicionais. As extensões têm acesso a alguns dos seus dados.</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>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Perguntar sempre neste site</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>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{Nenhum}=1{De 1 site }other{De # sites }}</translation>
<translation id="397105322502079400">A calcular...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> está bloqueado</translation>
-<translation id="3984550557525787191">Este nome de sessão já existe.</translation>
<translation id="3987940399970879459">Menos de 1 MB</translation>
+<translation id="4008849406247176967">Aviso: existe mais de uma origem com valores em conflito para esta política!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 página Web próxima}other{# páginas Web próximas}}</translation>
<translation id="4030383055268325496">&amp;Anular adição</translation>
+<translation id="4032320456957708163">O navegador é gerido por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Chave "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Adicionar endereço válido</translation>
<translation id="4072486802667267160">Ocorreu um erro ao processar a sua encomenda. Tente novamente.</translation>
<translation id="4075732493274867456">O cliente e o servidor não suportam uma versão do protocolo SSL ou um conjunto de cifras comum.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Roxo</translation>
<translation id="4165986682804962316">Definições de sites</translation>
<translation id="4171400957073367226">Assinatura de verificação incorreta</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Mais <ph name="ITEM_COUNT" /> item}other{Mais <ph name="ITEM_COUNT" /> itens}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;Passo 1: inicie sessão no portal&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Repor palavra-passe</translation>
<translation id="4280429058323657511">, exp. <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Este cartão foi guardado na sua Conta Google.}other{Estes cartões foram guardados na sua Conta Google.}}</translation>
+<translation id="42981349822642051">Expandir</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Mudar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Bloquear (predefinição)</translation>
+<translation id="4318566738941496689">O nome do dispositivo e o endereço de rede.</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="4340982228985273705">Este computador não é detetado como sendo gerido pela empresa, por isso, a política apenas pode instalar automaticamente extensões alojadas na Web Store do Chrome. O URL de atualização da Web Store do Chrome é "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Cartões de crédito aceites</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gerir métodos de pagamento…</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telemóvel</translation>
<translation id="4406896451731180161">resultados da pesquisa</translation>
-<translation id="4406972042435603828">Os seus administradores instalaram extensões com capacidades poderosas.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Endereço de recolha</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="443121186588148776">Porta de série</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="4434045419905280838">Pop-ups e redirecionamentos</translation>
+<translation id="4435702339979719576">Postcard)</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="445100540951337728">Cartões de débito admitidos</translation>
+<translation id="4466881336512663640">As alterações ao formulário serão perdidas. Tem a certeza de que pretende continuar?</translation>
<translation id="4482953324121162758">Este site não será traduzido.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL inválido. Tem de ser um URL com um esquema padrão, por exemplo, http://example.com ou https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Erro de validação: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Contactar o gestor do sistema</translation>
<translation id="450710068430902550">Partilha com o gestor</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Detalhes</translation>
<translation id="4524805452350978254">Gerir cartões</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Experimente desativar as extensões.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Entrega</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Remover cartão</translation>
<translation id="4587425331216688090">Pretende remover o endereço do Chrome?</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="4597348597567598915">Tamanho 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Aceder agora</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="467809019005607715">Google Slides</translation>
<translation id="4690462567478992370">Parar de utilizar um certificado inválido</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">A ligação foi interrompida</translation>
<translation id="471880041731876836">Não tem autorização para aceder a este site</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Executar o Diagnóstico de rede do Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Recarregar políticas</translation>
<translation id="4728558894243024398">Plataforma</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Reiniciar o Chromium</translation>
<translation id="473775607612524610">Atualizar</translation>
<translation id="4738601419177586157">Sugestão de pesquisa de <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Gerir palavras-passe…</translation>
<translation id="4744603770635761495">Caminho do Executável</translation>
+<translation id="4746351372139058112">Mensagens</translation>
<translation id="4750917950439032686">As suas informações (por exemplo, palavras-passe ou números de cartões de crédito) são privadas quando são enviadas para este site.</translation>
<translation id="4756388243121344051">&amp;Histórico</translation>
<translation id="4758311279753947758">Adicionar informações de contacto</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">A página Web em <ph name="URL" /> poderá estar temporariamente inactiva ou poderá ter sido movida permanentemente para um novo endereço Web.</translation>
<translation id="4771973620359291008">Ocorreu um erro desconhecido.</translation>
<translation id="4785689107224900852">Mudar para este separador</translation>
-<translation id="4792143361752574037">Ocorreu um problema ao aceder aos ficheiros da sessão. A opção de guardar no disco está atualmente desativada. Recarregue a página para tentar novamente.</translation>
<translation id="4798078619018708837">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. Depois de confirmar, os detalhes do cartão da sua Conta Google são partilhados com este site.</translation>
<translation id="4800132727771399293">Verifique a data de validade e o Código de Segurança/CVC e tente novamente</translation>
+<translation id="480334179571489655">Erro de política de origem</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Abrir</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}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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Nenhum resultado</translation>
<translation id="4950898438188848926">Botão de mudança de separador: prima Enter para mudar para o separador aberto, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Ações</translation>
-<translation id="495832697253704892">Comunicação de extensões</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Expandir lista</translation>
<translation id="4974590756084640048">Reativar avisos</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Ver tudo</translation>
<translation id="4989809363548539747">Este plug-in não é compatível</translation>
-<translation id="4996230189582812866">Relatórios</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="5014174725590676422">É apresentado o primeiro ecrã de execução do Assistente Google no Chrome.</translation>
<translation id="5015510746216210676">Nome do computador:</translation>
+<translation id="5017554619425969104">Texto que copiou</translation>
<translation id="5018422839182700155">Não é possível abrir esta página</translation>
<translation id="5019198164206649151">Armazenamento de segurança em mau estado</translation>
<translation id="5023310440958281426">Verificar as políticas do gestor</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Contexto local <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permitir</translation>
<translation id="5040262127954254034">Privacidade</translation>
+<translation id="5043480802608081735">Link que copiou</translation>
<translation id="5045550434625856497">Palavra-passe incorrecta</translation>
<translation id="5056549851600133418">Artigos para si</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Verificar o endereço proxy<ph name="END_LINK" /></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="5097099694988056070">Estatísticas do dispositivo, como utilização da CPU/RAM.</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">O seu dispositivo é gerido por <ph name="ENROLLMENT_DOMAIN" /> e a sua conta é gerida por <ph name="ACCOUNT_DOMAIN" />. Isto significa que os seus administradores podem configurar remotamente o seu dispositivo e a sua conta.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bits)</translation>
-<translation id="5128122789703661928">A sessão com este nome não é válida para eliminação.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gerir endereços…</translation>
+<translation id="5138227688689900538">Mostrar menos</translation>
<translation id="5141240743006678641">Encriptar palavras-passe sincronizadas com as credenciais Google</translation>
<translation id="5145883236150621069">Código de erro presente na resposta da política</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Abrir a página numa nova janela de navegação anónima (⇧⌘N)</translation>
<translation id="516920405563544094">Introduza o Código de Segurança/CVC de <ph name="CREDIT_CARD" />. Depois de confirmar, os detalhes do cartão da sua Conta Google são partilhados com este site.</translation>
<translation id="5169827969064885044">Pode perder o acesso à conta da sua entidade ou ser vítima de roubo de identidade. O Chrome recomenda a alteração da palavra-passe agora.</translation>
<translation id="5171045022955879922">Pesquise ou escreva URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Equipamento</translation>
<translation id="5179510805599951267">Não está em <ph name="ORIGINAL_LANGUAGE" />? Comunicar este erro</translation>
<translation id="5190835502935405962">Barra de marcadores</translation>
-<translation id="5200263511887412697">comunicar lista de utilizadores do dispositivo que iniciaram sessão recentemente</translation>
+<translation id="519422657042045905">As notas não estão disponíveis.</translation>
<translation id="5201306358585911203">Uma página incorporada nesta página diz</translation>
<translation id="5205222826937269299">Nome obrigatório</translation>
<translation id="5215116848420601511">Métodos de pagamento e endereços com o Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Email obrigatório</translation>
<translation id="5230733896359313003">Endereço de envio</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Ligar à rede"</translation>
<translation id="5251803541071282808">Nuvem</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Endereços de rede</translation>
<translation id="5285570108065881030">Mostrar todas as palavras-passe guardadas</translation>
<translation id="5287240709317226393">Mostrar cookies</translation>
<translation id="5288108484102287882">A validação dos valores da política gerou avisos.</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> de <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Escolher informações de contacto</translation>
<translation id="5327248766486351172">Nome</translation>
+<translation id="5329858041417644019">O seu navegador não é gerido</translation>
<translation id="5332219387342487447">Método de envio</translation>
+<translation id="5334013548165032829">Registos de sistema detalhados</translation>
<translation id="5344579389779391559">Esta página pode tentar cobrar-lhe dinheiro</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"O seu relógio está atrasado" ou "O seu relógio está adiantado" ou "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Para utilizar os seus cartões em todos os dispositivos, inicie sessão e ative a sincronização.</translation>
<translation id="5386426401304769735">A cadeia de certificados inclui um certificado assinado através de SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Inválido</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<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="5470861586879999274">&amp;Refazer edição</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Adicionar endereço válido</translation>
<translation id="5490432419156082418">Endereços e Mais</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Experimente contactar o gestor do sistema.</translation>
<translation id="549333378215107354">Tamanho 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Marcadores geridos</translation>
<translation id="5510766032865166053">Pode ter sido movido ou eliminado.</translation>
<translation id="5523118979700054094">Nome da política</translation>
<translation id="552553974213252141">O texto foi extraído corretamente?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Não foi possível encontrar o artigo solicitado.</translation>
<translation id="5541546772353173584">Adicionar email</translation>
<translation id="5545756402275714221">Artigos para si</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Editar morada</translation>
<translation id="5598944008576757369">Escolher método de pagamento</translation>
<translation id="560412284261940334">Gestão não suportada</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> redirecionou-o demasiadas vezes.</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="5632627355679805402">Os dados foram encriptados com a sua <ph name="BEGIN_LINK" />palavra-passe do Google<ph name="END_LINK" /> à(s) <ph name="TIME" />. Introduza a mesma para iniciar a sincronização.</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="563324245173044180">Conteúdo fraudulento bloqueado.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">O administrador deste dispositivo instalou extensões para funções adicionais. As extensões têm acesso a alguns dos seus dados.</translation>
<translation id="5675650730144413517">Esta página não está a funcionar</translation>
+<translation id="5684874026226664614">Ups! Não foi possível traduzir esta página.</translation>
<translation id="5685654322157854305">Adicionar morada para envio</translation>
<translation id="5689199277474810259">Exportar para JSON</translation>
<translation id="5689516760719285838">Local</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">A identidade deste Website não foi verificada.</translation>
<translation id="5719499550583120431">Os cartões pré-pagos são admitidos.</translation>
<translation id="5720705177508910913">Utilizador atual</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">O Chrome recomenda a reposição da palavra-passe se a tiver reutilizado noutros sites.</translation>
<translation id="5732392974455271431">Os teus pais podem desbloquear-te</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Guardar o cartão na sua Conta Google}other{Guardar os cartões na sua Conta Google}}</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="5770114862687765385">O ficheiro parece estar danificado. Clique no botão "Repor" para repor a sessão.</translation>
<translation id="5778550464785688721">Controlo total de dispositivos MIDI</translation>
<translation id="578305955206182703">Âmbar</translation>
<translation id="57838592816432529">Desativar som</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>
+<translation id="5798290721819630480">Pretende rejeitar as alterações?</translation>
<translation id="5798683403665926540">Alterar página inicial nas definições do Chrome</translation>
<translation id="5803412860119678065">Pretende preencher o seu cartão <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permissões</translation>
<translation id="5810442152076338065">A sua ligação a <ph name="DOMAIN" /> está encriptada através de um conjunto de cifras obsoleto.</translation>
<translation id="5813119285467412249">&amp;Refazer adição</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="5860033963881614850">Desativado</translation>
<translation id="5863847714970149516">A próxima página pode tentar cobrar-lhe dinheiro</translation>
<translation id="5866257070973731571">Adicionar número de telefone</translation>
<translation id="5869405914158311789">Não é possível aceder a este site</translation>
<translation id="5869522115854928033">Palavras-passe guardadas</translation>
<translation id="5887400589839399685">Cartão guardado</translation>
-<translation id="5893718151540690985">comunicar a lista de interfaces de rede com os respetivos tipos e endereços de hardware</translation>
<translation id="5893752035575986141">Os cartões de crédito são admitidos.</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}other{# em utilização}}</translation>
+<translation id="5916664084637901428">Ativado</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Pretende guardar o cartão na Conta Google?</translation>
<translation id="5922853866070715753">Estamos quase a terminar</translation>
<translation id="5932224571077948991">O site apresenta anúncios intrusivos ou enganadores.</translation>
-<translation id="5939518447894949180">Repor</translation>
<translation id="5946937721014915347">A abrir <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Não é possível inscrever-se com conta de consumidor (licença incluída disponível).</translation>
<translation id="5967592137238574583">Editar informações de contacto</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Reduzir</translation>
<translation id="5977489021191000276">O seu dispositivo não é gerido por um administrador.</translation>
<translation id="5977976211062815271">Neste dispositivo</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Não é possível abrir a aplicação de pagamento</translation>
<translation id="5989320800837274978">Não foram especificados servidores proxy fixos nem um URL de script .pac.</translation>
<translation id="5990559369517809815">Os pedidos para o servidor foram bloqueados por uma extensão.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">comunicar estatísticas de hardware, como a utilização da CPU/RAM</translation>
<translation id="6034000775414344507">Cinzento-claro</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Se o problema persistir, contacte o proprietário do site.</translation>
<translation id="6040143037577758943">Fechar</translation>
<translation id="6044573915096792553">Tamanho 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Pretende utilizar os seus cartões em todos os seus dispositivos?</translation>
<translation id="6059925163896151826">Dispositivos USB</translation>
-<translation id="6071091556643036997">O tipo de política é inválido.</translation>
<translation id="6080696365213338172">Acedeu a conteúdos utilizando um certificado fornecido por um gestor. Os dados que fornecer a <ph name="DOMAIN" /> podem ser intercetados pelo seu gestor.</translation>
<translation id="6094273045989040137">Anotar</translation>
<translation id="610911394827799129">A sua Conta Google pode ter outras formas do histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Informações acerca das extensões e dos plug-ins instalados</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{Nenhuma}=1{1 palavra-passe (sincronizada)}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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Liberta menos de <ph name="SIZE" />. É possível que alguns sites sejam carregados mais lentamente na sua próxima visita.</translation>
<translation id="6337534724793800597">Filtrar políticas pelo nome</translation>
<translation id="6358450015545214790">O que significam?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Possíveis cobranças se prosseguir.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 outra sugestão}other{# outras sugestões}}</translation>
<translation id="6387754724289022810">Para pagar mais rapidamente da próxima vez, guarde o cartão e o endereço de faturação na sua Conta Google e neste dispositivo.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Editar marcador</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Rejeitar</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</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>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Reiniciar o Chrome</translation>
<translation id="6529602333819889595">&amp;Refazer eliminação</translation>
<translation id="6534179046333460208">Sugestões da Web física</translation>
+<translation id="6556866813142980365">Refazer</translation>
<translation id="6563469144985748109">O seu gestor ainda não o aprovou</translation>
<translation id="6569060085658103619">Está a ver a página de uma extensão</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Rosa claro</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Link copiado por si</translation>
+<translation id="6591833882275308647">O seu <ph name="DEVICE_TYPE" /> não é gerido.</translation>
<translation id="6596325263575161958">Opções de encriptação</translation>
<translation id="6604181099783169992">Sensores de movimento ou de luz</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Informações de contacto</translation>
<translation id="6626291197371920147">Adicionar número de cartão válido</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Pesquisar</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Esta política está obsoleta.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nenhum}=1{De 1 site (a sessão na sua Conta Google não é terminada).}other{De # sites (a sessão na sua Conta Google não é terminada).}}</translation>
<translation id="6657585470893396449">Palavra-passe</translation>
+<translation id="6670613747977017428">Voltar para segurança.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Símbolo de inscrição:</translation>
<translation id="6711464428925977395">Existe um problema com o servidor proxy ou o endereço está incorreto.</translation>
<translation id="6723740634201835758">Na sua Conta Google</translation>
+<translation id="6738516213925468394">Os seus dados foram encriptados com a sua <ph name="BEGIN_LINK" />frase de acesso de sincronização<ph name="END_LINK" /> à(s) <ph name="TIME" />. Introduza a mesma para iniciar a sincronização.</translation>
<translation id="674375294223700098">Erro de certificado de servidor desconhecido.</translation>
<translation id="6744009308914054259">Enquanto aguarda uma ligação, pode visitar a secção Transferências para ler artigos offline.</translation>
<translation id="6753269504797312559">Valor da política</translation>
<translation id="6757797048963528358">O dispositivo entrou em suspensão.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">O teu pai/a tua mãe ainda não o aprovou</translation>
<translation id="67862343314499040">Violeta</translation>
+<translation id="6786747875388722282">Extensões</translation>
<translation id="679355240208270552">Ignorado porque a pesquisa predefinida não está ativada pela política.</translation>
<translation id="681021252041861472">Campo obrigatório</translation>
<translation id="6810899417690483278">ID de personalização</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Dispositivo</translation>
<translation id="6970216967273061347">Distrito</translation>
<translation id="6973656660372572881">Foram especificados servidores proxy fixos e um URL de script .pac.</translation>
+<translation id="6973932557599545801">Lamento, mas não posso ajudar. Continue por sua conta.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Desativar som (predefinição)</translation>
<translation id="6984479912851154518">Está a sair do modo privado para pagar através de uma aplicação externa. Pretende continuar?</translation>
<translation id="6989763994942163495">Mostrar definições avançadas...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Traduzir sempre do <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Estas cobranças podem ser únicas ou recorrentes e podem não ser óbvias.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ocultar</translation>
<translation id="7108819624672055576">Permitida por uma extensão</translation>
<translation id="7111012039238467737">(Válido)</translation>
+<translation id="7118618213916969306">Pesquisar URL da área de transferência, <ph name="SHORT_URL" /></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="7135130955892390533">Mostrar estado</translation>
<translation id="7138472120740807366">Método de fornecimento</translation>
<translation id="7139724024395191329">Emirato</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<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="7153618581592392745">Lilás</translation>
-<translation id="7158980942472052083">URL inválido. Tem de ser um URL com um esquema padrão.</translation>
<translation id="717330890047184534">ID Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<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="7177397715882417099">O servidor ao qual irá aceder, <ph name="ORIGIN" />, solicitou que seja aplicada uma
+ política de segurança a todos os pedidos. Contudo, em vez de
+ devolver uma política, redirecionou o navegador para outro sítio, o que impede
+ que o mesmo satisfaça o seu pedido para <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Guardar e preencher métodos de pagamento</translation>
<translation id="7180611975245234373">Atualizar</translation>
<translation id="7182878459783632708">Não estão definidas políticas</translation>
<translation id="7186367841673660872">Esta página foi traduzida de<ph name="ORIGINAL_LANGUAGE" />para<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Liberta <ph name="SIZE" />. É possível que alguns sites sejam carregados mais lentamente na sua próxima visita.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">O administrador pode ver:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> não respeita os padrões de segurança.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /> sobre este problema.</translation>
<translation id="7219179957768738017">A ligação utiliza <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">A processar</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">O site que pretende visitar contém software malicioso</translation>
+<translation id="724766306220616965">Avisos, conflito</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="7251437084390964440">A configuração de rede não cumpre a norma ONC. Partes da configuração podem não ser importadas.
Detalhes adicionais:
@@ -982,11 +1120,14 @@ Detalhes adicionais:
<translation id="7300012071106347854">Azul cobalto</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Avisos da <ph name="BEGIN_LINK" />Navegação segura<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ajuda para estabelecer ligação</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Linha de comandos</translation>
-<translation id="7365061714576910172">Exportar Linux</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>
@@ -994,6 +1135,7 @@ Detalhes adicionais:
<translation id="7381288752349550461">Substituição de sessão gerida</translation>
<translation id="7390545607259442187">Confirmar cartão</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">O seu <ph name="DEVICE_NAME" /> é gerido</translation>
<translation id="7407424307057130981">&lt;p&gt;Este erro é apresentado se tiver software Superfish no seu computador com Windows.&lt;/p&gt;
&lt;p&gt;Siga estes passos para desativar temporariamente o software para que possa aceder à Web. Vai precisar de privilégios de administrador.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@ Detalhes adicionais:
&lt;li&gt;Em &lt;strong&gt;Estado do serviço&lt;/strong&gt;, clique em &lt;strong&gt;Parar&lt;/strong&gt;.
&lt;li&gt;Clique em &lt;strong&gt;Aplicar&lt;/strong&gt; e, de seguida, em &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Visite o &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centro de Ajuda do Chrome&lt;/a&gt; para saber como remover permanentemente o software do computador. &lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestão do <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Gerir palavras-passe…</translation>
<translation id="7419106976560586862">Caminho do Perfil</translation>
<translation id="7437289804838430631">Adicionar informações de contacto</translation>
@@ -1012,22 +1154,24 @@ Detalhes adicionais:
<translation id="7442725080345379071">Laranja-claro</translation>
<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 Website que pretende e não a um site pirata.</translation>
-<translation id="7449109375006139765">enviar registos do sistema para o servidor de gestão</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="7460618730930299168">A apresentação é diferente daquilo que selecionou. Pretende continuar?</translation>
<translation id="7473891865547856676">Não, obrigado</translation>
-<translation id="7475525192983021547">comunicar períodos de tempo quando um utilizador está ativo no dispositivo</translation>
<translation id="7481312909269577407">Avançar</translation>
<translation id="7485870689360869515">Não foram encontrados dados.</translation>
+<translation id="7498234416455752244">Continuar a editar</translation>
<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="7508870219247277067">Verde abacate</translation>
<translation id="7511955381719512146">A rede Wi-Fi que está a utilizar pode exigir que visite <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">A sua ligação a este site não é privada.</translation>
+<translation id="7535087603100972091">Valor</translation>
<translation id="7537536606612762813">Obrigatório</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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á desativado, porque este formulário não utiliza uma ligação segura.</translation>
<translation id="7543525346216957623">Pede aos teus pais</translation>
@@ -1036,8 +1180,8 @@ Detalhes adicionais:
<translation id="7552846755917812628">Experimente as sugestões seguintes:</translation>
<translation id="7554791636758816595">Novo separador</translation>
<translation id="7564049878696755256">Pode perder o acesso à sua conta do serviço <ph name="ORG_NAME" /> ou ser vítima de roubo de identidade. O Chrome recomenda a alteração da palavra-passe agora.</translation>
-<translation id="7566125604157659769">Texto que copiou</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="7568105740864181217">Este navegador é gerido por uma empresa, escola ou outra entidade. O administrador pode alterar a configuração do navegador remotamente. A atividade neste dispositivo também pode ser gerida fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></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>
@@ -1048,6 +1192,7 @@ Detalhes adicionais:
<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="7633909222644580952">Dados de desempenho e relatórios de falhas</translation>
<translation id="7637571805876720304">Pretende remover o cartão de crédito do Chromium?</translation>
<translation id="7639968568612851608">Cinzento-escuro</translation>
<translation id="765676359832457558">Ocultar definições avançadas...</translation>
@@ -1057,9 +1202,11 @@ Detalhes adicionais:
<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="7676643023259824263">Pesquisar texto da área de transferência, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Alterar motor de pesquisa</translation>
<translation id="7682287625158474539">Envio</translation>
<translation id="7687186412095877299">Preenche os formulários de pagamento com os seus métodos de pagamento guardados</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">De momento, tem cartões que apenas podem ser utilizados neste dispositivo. Clique em Continuar para rever os cartões.</translation>
<translation id="7699293099605015246">De momento, não estão disponíveis artigos</translation>
<translation id="7701040980221191251">Nenhum</translation>
@@ -1071,11 +1218,13 @@ Detalhes adicionais:
<translation id="774634243536837715">Conteúdo perigoso bloqueado.</translation>
<translation id="7752995774971033316">Não gerido</translation>
<translation id="7755287808199759310">O teu pai/a tua mãe pode desbloquear-te</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">O software de firewall ou antivírus pode ter bloqueado a ligação.</translation>
<translation id="7759163816903619567">Domínio de apresentação:</translation>
<translation id="7761701407923456692">O certificado do servidor não corresponde ao URL.</translation>
<translation id="7763386264682878361">Analisador de manifestos de pagamento</translation>
<translation id="7764225426217299476">Adicionar endereço</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Município</translation>
<translation id="7791543448312431591">Adicionar</translation>
<translation id="7793809570500803535">A página Web de <ph name="SITE" /> poderá estar temporariamente inativa ou poderá ter sido movida permanentemente para um novo endereço Web.</translation>
@@ -1087,8 +1236,8 @@ Detalhes adicionais:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Pretende remover a sugestão do formulário do Chrome?</translation>
<translation id="7815407501681723534">Encontrados <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> para "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">Gestão de políticas</translation>
<translation id="782886543891417279">A rede Wi-Fi que está a utilizar (<ph name="WIFI_NAME" />) pode exigir que visite a respetiva página de início de sessão.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Nenhuma}=1{1 aplicação (<ph name="EXAMPLE_APP_1" />)}=2{2 aplicações (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# aplicações (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">No entanto, a navegação não é invisível. Passar para o modo de navegação anónima não oculta a navegação do empregador ou do fornecedor de serviços de Internet, nem dos Sites que visitar.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@ Detalhes adicionais:
<translation id="7878562273885520351">A palavra-passe pode estar comprometida</translation>
<translation id="7882421473871500483">Castanho</translation>
<translation id="7887683347370398519">Verifique o Código de Segurança/CVC e tente novamente</translation>
-<translation id="7893255318348328562">Nome de sessão</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Introduza um número de telefone válido</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Expira a <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@ Detalhes adicionais:
<translation id="7951415247503192394">32 bits</translation>
<translation id="7956713633345437162">Marcadores telemóvel</translation>
<translation id="7961015016161918242">Nunca</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Não especificado</translation>
<translation id="800218591365569300">Experimente fechar outros separadores ou programas para libertar memória.</translation>
+<translation id="8004582292198964060">Navegador</translation>
<translation id="8009225694047762179">Gerir palavras-passe</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Este cartão e o respetivo endereço de faturação serão guardados. Pode utilizá-lo quando tiver sessão iniciada em <ph name="USER_EMAIL" />.}other{Estes cartões e os respetivos endereços de faturação serão guardados. Pode utilizá-los quando tiver sessão iniciada em <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Esta página está em <ph name="SOURCE_LANGUAGE" />. Pretende traduzi-la para <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Caneta</translation>
+<translation id="8037117624646282037">Quem utilizou o dispositivo recentemente</translation>
<translation id="8037357227543935929">Pedir (predefinição)</translation>
<translation id="803771048473350947">Ficheiro</translation>
<translation id="8041089156583427627">Enviar comentários</translation>
<translation id="8041940743680923270">Utilizar predefinição global (Perguntar)</translation>
<translation id="8042918947222776840">Escolher método de levantamento</translation>
<translation id="8057711352706143257">O "<ph name="SOFTWARE_NAME" />" não está configurado corretamente. Normalmente, a desinstalação do "<ph name="SOFTWARE_NAME" />" resolve o problema. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">O seu dispositivo foi configurado para:</translation>
+<translation id="8066955247577885446">Lamentamos, mas ocorreu um erro.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Não é possível criar anotação se tiver sido aplicada uma rotação ao documento</translation>
<translation id="8079031581361219619">Pretende atualizar o site?</translation>
<translation id="8088680233425245692">Falha ao ver o artigo.</translation>
@@ -1130,11 +1283,12 @@ Detalhes adicionais:
<translation id="8091372947890762290">Ativação pendente no servidor</translation>
<translation id="8092774999298748321">Roxo escuro</translation>
<translation id="8094917007353911263">A rede que está a utilizar pode exigir que visite <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Os cartões inválidos foram removidos.</translation>
<translation id="8103161714697287722">Método de pagamento</translation>
<translation id="8118489163946903409">Método de pagamento</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> gerido por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">O "<ph name="SOFTWARE_NAME" />" não foi instalado corretamente no computador ou na rede. Peça ao gestor de TI que resolva este problema.</translation>
-<translation id="8130693978878176684">Não é possível ajudar mais, continue por sua conta.</translation>
<translation id="8131740175452115882">Confirmar</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>
@@ -1144,8 +1298,11 @@ Detalhes adicionais:
<translation id="8197543752516192074">Traduzir página</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="8202370299023114387">Conflito</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">A ligação é segura</translation>
<translation id="8218327578424803826">Localização atribuída:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Abrir página num novo separador anónimo</translation>
@@ -1157,14 +1314,16 @@ Detalhes adicionais:
<translation id="825929999321470778">Mostrar todas as palavras-passe guardadas</translation>
<translation id="8261506727792406068">Eliminar</translation>
<translation id="8267698848189296333">A iniciar sessão como <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Este navegador é gerido por <ph name="ENROLLMENT_DOMAIN" />. O administrador pode alterar a configuração do navegador remotamente. A atividade neste dispositivo também pode ser gerida fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Iniciar Sessão</translation>
<translation id="8288807391153049143">Mostrar certificado</translation>
<translation id="8289355894181816810">Se não tiver a certeza do que isto significa, contacte o gestor de rede.</translation>
<translation id="8293206222192510085">Adicionar marcador</translation>
<translation id="8294431847097064396">Origem</translation>
<translation id="8298115750975731693">A rede Wi-Fi que está a utilizar (<ph name="WIFI_NAME" />) pode exigir que visite <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">A tradução falhou devido a um problema com a ligação de rede.</translation>
-<translation id="8311129316111205805">Carregar sessão</translation>
<translation id="8332188693563227489">O acesso a <ph name="HOST_NAME" /> foi recusado</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1182,7 +1341,6 @@ Detalhes adicionais:
<translation id="8416694386774425977">A configuração de rede é inválida e não foi possível importá-la.
Detalhes adicionais:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispositivo gerido por <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Alterar</translation>
<translation id="8428213095426709021">Definições</translation>
@@ -1210,9 +1368,11 @@ Detalhes adicionais:
<translation id="860043288473659153">Nome do titular do cartão</translation>
<translation id="861775596732816396">Tamanho 4</translation>
<translation id="8620436878122366504">Os teus pais ainda não o aprovaram</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Guardar este cartão neste dispositivo</translation>
<translation id="8663226718884576429">Resumo da encomenda, <ph name="TOTAL_LABEL" />, mais detalhes</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, resposta, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">A sua ligação a <ph name="DOMAIN" /> não está encriptada.</translation>
<translation id="8718314106902482036">Pagamento não concluído</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sugestão de pesquisa.</translation>
@@ -1226,6 +1386,7 @@ Detalhes adicionais:
<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="8763927697961133303">Dispositivo USB</translation>
<translation id="8768895707659403558">Para utilizar os seus cartões em todos os dispositivos, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Refazer eliminação</translation>
<translation id="8792621596287649091">Pode perder o acesso à sua conta do serviço <ph name="ORG_NAME" /> ou ser vítima de roubo de identidade. O Chromium recomenda a alteração da palavra-passe agora.</translation>
<translation id="8800988563907321413">As sugestões próximas aparecem aqui</translation>
@@ -1236,10 +1397,12 @@ Detalhes adicionais:
<translation id="885730110891505394">Partilha com a Google</translation>
<translation id="8858065207712248076">O Chrome recomenda a reposição da palavra-passe da <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> se a tiver reutilizado noutros sites.</translation>
<translation id="8866481888320382733">Erro ao analisar as definições da política</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Fechadas recentemente</translation>
<translation id="8874824191258364635">Introduza um número de cartão válido</translation>
<translation id="8891727572606052622">Modo de proxy inválido.</translation>
<translation id="8903921497873541725">Ampliar</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Adicionar nome</translation>
@@ -1247,13 +1410,13 @@ Detalhes adicionais:
<translation id="894185898663964645">O seu administrador configurou certificados de raiz personalizados, os quais podem permitir ao administrador ver os conteúdos dos Websites que visita.</translation>
<translation id="8943282376843390568">Lima</translation>
<translation id="8957210676456822347">Autorização de portal cativo</translation>
+<translation id="8966619695390250636">Será que quis dizer...?</translation>
<translation id="8968766641738584599">Guardar cartão</translation>
<translation id="8971063699422889582">O certificado do servidor expirou.</translation>
<translation id="8975012916872825179">Inclui informações como números de telefone, endereços de email e moradas para envio</translation>
<translation id="8978053250194585037">A Navegação segura do Google <ph name="BEGIN_LINK" />detetou phishing<ph name="END_LINK" /> recentemente em <ph name="SITE" />. Os sites de phishing simulam ser outros Websites para o enganar.</translation>
<translation id="8983003182662520383">Métodos de pagamento e endereços com o Google Pay</translation>
<translation id="8987927404178983737">Mês</translation>
-<translation id="8988408250700415532">Ocorreu um erro. Pode concluir a sua encomenda no Website.</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>
@@ -1263,6 +1426,7 @@ Detalhes adicionais:
<translation id="9011424611726486705">Abrir definições do site</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Inválido)</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>
@@ -1274,11 +1438,11 @@ Detalhes adicionais:
<translation id="9065745800631924235">Pesquisa de <ph name="TEXT" /> no histórico</translation>
<translation id="9069693763241529744">Bloqueada por uma extensão</translation>
<translation id="9076283476770535406">Pode ter conteúdo para adultos</translation>
+<translation id="9076630408993835509">Este navegador não é gerido por uma empresa ou outra entidade. A atividade neste dispositivo pode ser gerida fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">São necessárias mais informações</translation>
<translation id="9080712759204168376">Resumo da encomenda</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>
<translation id="9106062320799175032">Adicionar endereço de faturação</translation>
-<translation id="9110718169272311511">O Assistente Google no Chrome está disponível junto à parte inferior do ecrã.</translation>
<translation id="9114524666733003316">A confirmar o cartão…</translation>
<translation id="9128870381267983090">Ligar à rede</translation>
<translation id="9137013805542155359">Mostrar original</translation>
@@ -1287,6 +1451,7 @@ Detalhes adicionais:
<translation id="9148507642005240123">&amp;Anular edição</translation>
<translation id="9154194610265714752">Atualizado</translation>
<translation id="9157595877708044936">A configurar...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Permitir que os sites verifiquem se tem métodos de pagamento guardados</translation>
<translation id="9169664750068251925">Bloquear sempre neste Website</translation>
<translation id="9170848237812810038">An&amp;ular</translation>
@@ -1301,10 +1466,12 @@ Detalhes adicionais:
<translation id="9219103736887031265">Imagens</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">LIMPAR FORMULÁRIO</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Pode perder o acesso à sua Conta Google. O Chromium recomenda que altere a palavra-passe agora. Ser-lhe-á pedido para iniciar sessão.</translation>
<translation id="939736085109172342">Nova pasta</translation>
<translation id="945855313015696284">Verifique as informações abaixo e elimine os cartões inválidos</translation>
<translation id="951104842009476243">Cartões de débito e pré-pagos aceites</translation>
+<translation id="958202389743790697">Bloqueado de acordo com a política de segurança de <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Este conteúdo poderá tentar instalar aplicações fraudulentas que se fazem passar por algo diferente ou que recolhem dados que podem ser utilizados para o monitorizar. <ph name="BEGIN_LINK" />Mostrar, mesmo assim<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Compilação oficial</translation>
<translation id="973773823069644502">Adicionar endereço de entrega</translation>
@@ -1313,6 +1480,7 @@ Detalhes adicionais:
<translation id="984275831282074731">Métodos de pagamento</translation>
<translation id="985199708454569384">&lt;p&gt;Este erro é apresentado se a data e a hora do computador ou do dispositivo móvel estiverem erradas.&lt;/p&gt;
&lt;p&gt;Para corrigir o erro, aceda ao relógio do dispositivo. Certifique-se de que a data e a hora estão corretas.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Compilação de programador</translation>
<translation id="989988560359834682">Editar endereço</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ro.xtb b/chromium/components/strings/components_strings_ro.xtb
index c2071da6d66..f75c4f8b92a 100644
--- a/chromium/components/strings/components_strings_ro.xtb
+++ b/chromium/components/strings/components_strings_ro.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ro">
-<translation id="1005145902654145231">Sesiunea nu a fost redenumită.</translation>
<translation id="1008557486741366299">Nu acum</translation>
<translation id="1010200102790553230">Încarcă pagina mai târziu</translation>
<translation id="1015730422737071372">Specifică detalii suplimentare</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">nume necunoscut</translation>
<translation id="1050038467049342496">închide celelalte aplicații;</translation>
<translation id="1055184225775184556">&amp;Anulați adăugarea</translation>
+<translation id="1056898198331236512">Avertisment</translation>
<translation id="1058479211578257048">Se salvează cardurile…</translation>
<translation id="10614374240317010">Nu se salvează niciodată</translation>
+<translation id="1062160989074299343">Prc10 (Plic)</translation>
<translation id="106701514854093668">Marcaje desktop</translation>
<translation id="1074497978438210769">Nesecurizat</translation>
<translation id="1080116354587839789">Încadrează pe lățime</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Adaugă numele de pe card</translation>
<translation id="1089439967362294234">Schimbă parola</translation>
<translation id="109743633954054152">Gestionează parolele în setările Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Este posibil să apară frecvent avertismente pe durata actualizării setărilor de securitate ale site-urilor. Acest aspect va fi îmbunătățit în curând.</translation>
<translation id="1126551341858583091">Dimensiunea spațiului de stocare local este <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Memoria cache pentru politică este OK</translation>
+<translation id="1131264053432022307">Imaginea copiată de tine</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Redenumește</translation>
<translation id="1175364870820465910">&amp;Printează...</translation>
<translation id="1181037720776840403">Elimină</translation>
<translation id="1197088940767939838">Portocaliu</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Numele dispozitivului tău</translation>
<translation id="124116460088058876">Mai multe limbi</translation>
<translation id="1250759482327835220">Pentru a plăti mai rapid data viitoare, salvează cardul, numele și adresa de facturare în Contul Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sincronizate)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variații ale liniilor de comandă</translation>
<translation id="129553762522093515">Închise recent</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Șterge cookie-urile<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Sesiunea selectată nu există.</translation>
+<translation id="1320233736580025032">Prc1 (Plic)</translation>
+<translation id="132301787627749051">Caută imaginea din clipboard</translation>
<translation id="1323433172918577554">Afișează mai multe</translation>
<translation id="132390688737681464">Salvează și completează adresele</translation>
<translation id="1333989956347591814">Este posibil ca activitatea ta <ph name="BEGIN_EMPHASIS" />să fie în continuare vizibilă<ph name="END_EMPHASIS" /> pentru:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Adresa de preluare</translation>
<translation id="1348198688976932919">Site-ul pe care urmează să îl accesezi conține aplicații periculoase</translation>
<translation id="1348779747280417563">Confirmă numele</translation>
+<translation id="1357195169723583938">Cine a folosit dispozitivul recent și când</translation>
+<translation id="1364822246244961190">Politica este blocată, iar valoarea sa va fi ignorată.</translation>
<translation id="1374468813861204354">sugestii</translation>
+<translation id="1374692235857187091">Index-4x6 (Carte poștală)</translation>
<translation id="1375198122581997741">Despre versiune</translation>
<translation id="1376836354785490390">Afișează mai puține</translation>
<translation id="1377321085342047638">Număr card</translation>
<translation id="138218114945450791">Albastru deschis</translation>
+<translation id="1382194467192730611">Dispozitiv USB permis de administrator</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> nu a trimis date.</translation>
+<translation id="140316286225361634">Site-ul <ph name="ORIGIN" /> a solicitat ca o politică de securitate
+ să se aplice tuturor solicitărilor, iar această politică apreciază site-ul
+ ca fiind nesigur.</translation>
<translation id="1405567553485452995">Verde deschis</translation>
<translation id="1407135791313364759">Deschideți-le pe toate</translation>
<translation id="1413809658975081374">Eroare legată de confidențialitate</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Printează</translation>
<translation id="1455413310270022028">Radieră</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Afișați mai multe</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Alege adresa de expediere</translation>
+<translation id="1492194039220927094">Notificări pentru politici:</translation>
<translation id="1501859676467574491">Arată cardurile din Contul Google</translation>
-<translation id="1506687042165942984">Afișează o copie salvată (adică despre care se știe că este învechită) a acestei pagini.</translation>
<translation id="1507202001669085618">&lt;p&gt;Această eroare se va afișa dacă folosești un portal Wi-Fi la care trebuie să te conectezi înainte de a putea fi online.&lt;/p&gt;
&lt;p&gt;Pentru a remedia eroarea, dă clic pe &lt;strong&gt;Conectează-te&lt;/strong&gt;, în pagina pe care încerci să o deschizi.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Numărul de telefon este obligatoriu</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Dată versiune:</translation>
<translation id="1521655867290435174">Foi de calcul Google</translation>
<translation id="1527263332363067270">Se așteaptă conectarea…</translation>
+<translation id="1529521330346880926">10x15 (Plic)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Această pagină afișează mesajul</translation>
<translation id="153384715582417236">Asta este tot</translation>
<translation id="154408704832528245">Alege adresa de livrare</translation>
<translation id="1549470594296187301">Trebuie să activezi JavaScript pentru a folosi această funcție.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Introdu data expirării</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Imaginea copiată de tine</translation>
<translation id="1620510694547887537">Camera</translation>
<translation id="1623104350909869708">Restricționați capacitatea acestei pagini de a crea casete de dialog suplimentare</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Încheie sesiunea</translation>
<translation id="1639239467298939599">Se încarcă</translation>
<translation id="1640180200866533862">Politici privind utilizatorii</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Certificatul de server conține o cheie criptografică slabă.</translation>
<translation id="1697532407822776718">Ești gata!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Documentul este prea mare pentru a face adnotări</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Încearcă să contactezi administratorul sistemului.</translation>
<translation id="1740951997222943430">Introdu o lună de expirare validă</translation>
<translation id="1743520634839655729">Pentru a plăti mai rapid data viitoare, salvează cardul, numele și adresa de facturare în Contul Google și pe acest dispozitiv.</translation>
+<translation id="1745880797583122200">Browserul tău este gestionat</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Actualizează expresia de acces pentru sincronizare.</translation>
<translation id="1787142507584202372">Filele deschise sunt afișate aici</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Numele titularului cardului</translation>
<translation id="1821930232296380041">Solicitarea sau parametrii săi sunt greșiți</translation>
+<translation id="1822540298136254167">Site-urile pe care le-ai accesat și timpul petrecut pe ele</translation>
<translation id="1826516787628120939">Se verifică</translation>
<translation id="1834321415901700177">Acest site conține programe dăunătoare</translation>
<translation id="1839551713262164453">Validarea valorilor de politică a returnat erori</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Șterge datele istoricului de navigare ale Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{și încă una}few{și încă #}other{și încă #}}</translation>
<translation id="2003709556000175978">Resetează parola acum</translation>
+<translation id="20053308747750172">Serverul pe care dorești să îl accesezi, <ph name="ORIGIN" />, a solicitat
+ ca o politică de securitate să fie aplicată tuturor solicitărilor către el. Dar acum
+ a livrat o politică nevalidă, care împiedică browserul
+ să îți îndeplinească solicitarea pentru <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy-ul este setat la Configurat automat.</translation>
<translation id="2030481566774242610">Ați dorit să scrieți <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />să verifici proxy-ul și firewallul;<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departament</translation>
<translation id="2102134110707549001">Sugerează o parolă puternică…</translation>
<translation id="2108755909498034140">repornește computerul;</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Card</translation>
<translation id="2114841414352855701">Politica este ignorată, deoarece a fost înlocuită de <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Marcaje mobile</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Plic)</translation>
<translation id="2181821976797666341">Politici</translation>
<translation id="2183608646556468874">Număr de telefon</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresă}few{# adrese}other{# de adrese}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Număr telefon</translation>
<translation id="2283340219607151381">Salvează și completează adresele</translation>
<translation id="2292556288342944218">Accesul la internet este blocat</translation>
+<translation id="2294558542833290837">Linkul pe care l-ai deschis inițial este neobișnuit</translation>
+<translation id="2297722699537546652">B5 (Plic)</translation>
+<translation id="2310021320168182093">Chou2 (Plic)</translation>
<translation id="2316887270356262533">Eliberează mai puțin de 1 MB. Este posibil ca unele site-uri să se încarce mai lent la următoarea accesare.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> necesită un nume de utilizator și o parolă.</translation>
<translation id="2317583587496011522">Se acceptă carduri de debit.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, expiră pe <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Setare controlată de administrator</translation>
+<translation id="2346319942568447007">Imaginea copiată de tine</translation>
<translation id="2349790679044093737">Sesiunea RV este activă</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Raportul de blocare creat <ph name="CRASH_TIME" /> nu a fost încărcat</translation>
<translation id="2367567093518048410">Nivel</translation>
<translation id="2378238891085281592">Ai trecut în modul privat</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Serverul pe care dorești să îl accesezi, <ph name="ORIGIN" />, a solicitat
+ ca o politică de securitate să fie aplicată tuturor solicitărilor către el. Dar acum
+ nu a reușit să livreze o politică, ceea ce împiedică browserul să îți îndeplinească
+ solicitarea pentru <ph name="SITE" />.</translation>
<translation id="244665789865330679">Dispozitivul și contul tău sunt administrate de <ph name="ENROLLMENT_DOMAIN" />. Administratorul poate să-ți configureze dispozitivul și contul de la distanță.</translation>
<translation id="2463193859425327265">Schimbă Pagina principală</translation>
<translation id="2463739503403862330">Completează</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Alege metoda de livrare</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />să rulezi Diagnostice rețea<ph name="END_LINK" />;</translation>
<translation id="2473195200299095979">Traduceți această pagină</translation>
<translation id="2479410451996844060">Adresă URL de căutare nevalidă.</translation>
<translation id="2482878487686419369">Notificări</translation>
<translation id="248348093745724435">Politicile dispozitivului</translation>
+<translation id="2485387744899240041">Nume de utilizator pentru dispozitivul și browserul tău</translation>
<translation id="2491120439723279231">Certificatul serverului conține erori.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Scanează un card nou</translation>
<translation id="2501278716633472235">Înapoi</translation>
<translation id="2503184589641749290">Carduri de debit și preplătite acceptate</translation>
<translation id="2515629240566999685">să verifici semnalul din zona ta.</translation>
-<translation id="2516852381693169964">Caută imaginea pe <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Salvat numai pe acest dispozitiv</translation>
<translation id="2524461107774643265">Adaugă mai multe informații</translation>
<translation id="2536110899380797252">Adaugă o adresă</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Plic)</translation>
<translation id="2625385379895617796">Ora este setată în viitor</translation>
<translation id="2634124572758952069">Nu s-a găsit adresa IP pentru serverul <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Stare:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">închide celelalte file sau aplicații;</translation>
<translation id="267371737713284912">apasă <ph name="MODIFIER_KEY_DESCRIPTION" /> pentru a anula</translation>
<translation id="2674170444375937751">Sigur doriți să ștergeți aceste pagini din istoric?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Ieși</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Carduri acceptate</translation>
<translation id="2702801445560668637">Listă de lectură</translation>
<translation id="2704283930420550640">Valoarea nu se potrivește cu formatul.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Elimină elementele selectate</translation>
<translation id="277133753123645258">Metodă de expediere</translation>
<translation id="277499241957683684">Lipsește o înregistrare pentru gadget</translation>
-<translation id="2781030394888168909">Exportă în format MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Conexiunea a fost resetată.</translation>
<translation id="2788784517760473862">Carduri de credit acceptate</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Deschide o fereastră incognito</translation>
+<translation id="2850739647070081192">Invite (Plic)</translation>
<translation id="2851634818064021665">Ai nevoie de permisiune ca să accesezi acest site</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Salvezi cardul?</translation>
<translation id="2903493209154104877">Adrese</translation>
<translation id="290376772003165898">Pagina nu este în <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Metodă de livrare</translation>
<translation id="2928905813689894207">Adresă de facturare</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Plic)</translation>
<translation id="3024663005179499861">Tip de politică greșit</translation>
<translation id="3037605927509011580">Of, nu mai merge!</translation>
<translation id="3041612393474885105">Informații despre certificat</translation>
+<translation id="3060227939791841287">C9 (Plic)</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="3095940652251934233">Extras</translation>
<translation id="3096100844101284527">Adaugă o adresă de preluare</translation>
<translation id="3105172416063519923">ID articol:</translation>
<translation id="3109728660330352905">Nu ești autorizat(ă) să vezi această pagină.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> pe <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Anulează plata</translation>
<translation id="3207960819495026254">Marcată</translation>
-<translation id="3209375525920864198">Introdu un nume de sesiune valid.</translation>
+<translation id="321912867715453276">Avertisment: Este prezentă mai mult de o sursă pentru politică, dar valorile sunt identice.</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="3229041911291329567">Informații despre versiunea dispozitivului și browserului</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Adaugă numele de pe card</translation>
<translation id="3287510313208355388">Descarcă când ești online</translation>
<translation id="3293642807462928945">Află mai multe despre politica <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nu s-au găsit rezultate de căutare</translation>
-<translation id="3305707030755673451">Datele au fost criptate cu expresia de acces pentru sincronizare la <ph name="TIME" />. Introdu-o pentru a începe sincronizarea.</translation>
<translation id="3320021301628644560">Adaugă o adresă de facturare</translation>
<translation id="3324983252691184275">Roșu aprins</translation>
<translation id="3338095232262050444">Securizat</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Repetați editarea</translation>
<translation id="342781501876943858">Chromium îți recomandă să resetezi parola dacă ai folosit-o și pe alte site-uri.</translation>
<translation id="3431636764301398940">Salvează cardul pe acest dispozitiv</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Proprietarul acestui dispozitiv a dezactivat jocul cu dinozaurul.</translation>
<translation id="3447884698081792621">Afișează certificatul (emis de <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Interval de preluare:</translation>
+<translation id="3456231139987291353">Number-11 (Plic)</translation>
<translation id="3461824795358126837">Evidențiator</translation>
<translation id="3462200631372590220">Ascundeți detaliile avansate</translation>
<translation id="3467763166455606212">Este necesar numele titularului cardului</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Se acceptă carduri de credit și preplătite.</translation>
<translation id="3582930987043644930">Adăugați un nume</translation>
<translation id="3583757800736429874">&amp;Repetați mutarea</translation>
+<translation id="35866233670761917">Conținutul site-urilor pe care le accesezi nu este vizibil administratorilor.</translation>
<translation id="3586931643579894722">Ascunde detaliile</translation>
+<translation id="3592413004129370115">Italian (Plic)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Mărimea 2</translation>
<translation id="3615877443314183785">Introdu o dată de expirare validă</translation>
<translation id="36224234498066874">Șterge datele de navigare...</translation>
<translation id="362276910939193118">Afișează întregul istoric</translation>
-<translation id="3623476034248543066">Afișați valoarea</translation>
<translation id="3630155396527302611">Dacă este deja inclus ca program căruia i se permite să acceseze rețeaua, încearcă
să îl elimini din listă și să îl adaugi din nou.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Validarea a reușit</translation>
<translation id="3655670868607891010">Dacă această pagină se afișează în mod frecvent, încercați <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Versiune</translation>
<translation id="366077651725703012">Actualizează cardul de credit</translation>
<translation id="3676592649209844519">ID dispozitiv:</translation>
+<translation id="3677008721441257057">Ai vrut să accesezi &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Solicitarea nu a putut fi semnată</translation>
<translation id="3678529606614285348">Deschide pagina într-o fereastră incognito nouă (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Raport de blocare creat <ph name="CRASH_TIME" /> și încărcat <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Rețeaua pe care o folosești poate solicita accesarea paginii de conectare.</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="3709599264800900598">Textul copiat de tine</translation>
<translation id="3712624925041724820">Licențe epuizate</translation>
<translation id="3714780639079136834">să activezi datele mobile sau conexiunea Wi-Fi;</translation>
<translation id="3715597595485130451">Conectează-te la o rețea Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />să verifici configurarea pentru proxy, firewall și DNS;<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Aplicațiile care pot genera această eroare includ software-ul antivirus, firewall, de filtrare web sau proxy.</translation>
+<translation id="373042150751172459">B4 (Plic)</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="3745099705178523657">După ce confirmi, acest site va avea acces la detaliile cardului tău din Contul Google.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Expiră în <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Mărimea 16</translation>
+<translation id="3797522431967816232">Prc3 (Plic)</translation>
<translation id="3807873520724684969">Conținutul dăunător a fost blocat.</translation>
<translation id="3810973564298564668">Gestionează</translation>
<translation id="382518646247711829">Dacă utilizați un server proxy...</translation>
<translation id="3828924085048779000">Trebuie să fie introdusă expresia de acces.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> a instalat extensii pentru funcții suplimentare. Extensiile au acces la unele dintre datele tale.</translation>
<translation id="385051799172605136">Înapoi</translation>
<translation id="3858027520442213535">Actualizează data și ora</translation>
<translation id="3884278016824448484">Identificator de gadget în conflict</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Întreabă întotdeauna pe acest site</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Acest nume de sesiune există deja.</translation>
<translation id="3987940399970879459">Mai puțin de 1 MB</translation>
+<translation id="4008849406247176967">Avertisment: Pentru această politică este prezentă mai mult de o sursă cu valori în conflict!</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="4030383055268325496">&amp;Anulați adăugarea</translation>
+<translation id="4032320456957708163">Browserul este gestionat de <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Cheie „<ph name="SUBKEY" />”: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Plic)</translation>
<translation id="4067947977115446013">Adaugă o adresă validă</translation>
<translation id="4072486802667267160">A apărut o eroare la procesarea comenzii. Încearcă din nou.</translation>
<translation id="4075732493274867456">Clientul și serverul nu acceptă o versiune a protocolului SSL sau o suită de codificare obișnuită.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Mov</translation>
<translation id="4165986682804962316">Setări pentru site-uri</translation>
<translation id="4171400957073367226">Semnătură de verificare nevalidă</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Încă <ph name="ITEM_COUNT" /> articol}few{Încă <ph name="ITEM_COUNT" /> articole}other{Încă <ph name="ITEM_COUNT" /> de articole}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Plic)</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="4221630205957821124">&lt;h4&gt;Pasul 1: conectează-te la portal&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Resetează parola</translation>
<translation id="4280429058323657511">data expirării: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Acest card a fost salvat în Contul tău Google}few{Aceste carduri au fost salvate în Contul tău Google}other{Aceste carduri au fost salvate în Contul tău Google}}</translation>
+<translation id="42981349822642051">Extinde</translation>
+<translation id="4302965934281694568">Chou3 (Plic)</translation>
<translation id="4305817255990598646">Comută</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blochează (în mod prestabilit)</translation>
+<translation id="4318566738941496689">Numele și adresa de rețea ale dispozitivului tău</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="4340982228985273705">Acest computer nu este detectat ca fiind gestionat de companie, deci politica poate instala automat doar extensiile găzduite în Magazinul web Chrome. Adresa URL pentru actualizare din Magazinul web Chrome este „<ph name="CWS_UPDATE_URL" />”.</translation>
<translation id="4346197816712207223">Carduri de credit acceptate</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Gestionează metodele de plată...</translation>
+<translation id="4367563149485757821">Number-12 (Plic)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">rezultate ale căutării</translation>
-<translation id="4406972042435603828">Administratorii au instalat extensii care au capacități puternice.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> cookie-uri</translation>
<translation id="4415426530740016218">Adresă de preluare</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="443121186588148776">Port serial</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="4434045419905280838">Ferestre pop-up și redirecționări</translation>
+<translation id="4435702339979719576">Carte poștală)</translation>
<translation id="443673843213245140">Utilizarea unui proxy este dezactivată, dar o configurare proxy este specificată în mod explicit.</translation>
<translation id="445100540951337728">Carduri de debit acceptate</translation>
+<translation id="4466881336512663640">Modificările aduse formularului se vor pierde. Sigur dorești să continui?</translation>
<translation id="4482953324121162758">Acest site nu va fi tradus.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Adresă URL nevalidă. Trebuie să fie o adresă URL cu schemă standard, de exemplu: http://example.com sau https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Plic)</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="4517607026994743406">Comm-10 (Plic)</translation>
<translation id="4522570452068850558">Detalii</translation>
<translation id="4524805452350978254">Gestionează cardurile</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Dezactivează extensiile.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Livrare</translation>
+<translation id="4579056131138995126">Personal (Plic)</translation>
<translation id="4582204425268416675">Elimină cardul</translation>
<translation id="4587425331216688090">Elimini adresa din Chrome?</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="4597348597567598915">Mărimea 8</translation>
+<translation id="4600854749408232102">C6/C5 (Plic)</translation>
<translation id="4646534391647090355">Accesez acum</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="467809019005607715">Prezentări Google</translation>
<translation id="4690462567478992370">Nu mai folosi un certificat nevalid</translation>
+<translation id="4691835149146451662">Architecture-A (Plic)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Conexiunea a fost întreruptă</translation>
<translation id="471880041731876836">Nu ai permisiunea să accesezi acest site</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />să rulezi Diagnostice rețea Windows<ph name="END_LINK" />;</translation>
<translation id="4726672564094551039">Reîncărcați politicile</translation>
<translation id="4728558894243024398">Platformă</translation>
+<translation id="4731967714531604179">Prc2 (Plic)</translation>
<translation id="4736825316280949806">repornește Chromium;</translation>
<translation id="473775607612524610">Actualizează</translation>
<translation id="4738601419177586157">Sugestie de căutare <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Gestionează parolele…</translation>
<translation id="4744603770635761495">Cale executabilă</translation>
+<translation id="4746351372139058112">Mesaje</translation>
<translation id="4750917950439032686">Informațiile tale (de exemplu, parolele și numerele cardurilor de credit) sunt private când sunt trimise la acest site.</translation>
<translation id="4756388243121344051">&amp;Istoric</translation>
<translation id="4758311279753947758">Adaugă informații de contact</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Pagina web de la <ph name="URL" /> poate fi temporar nefuncțională sau a fost mutată definitiv la o nouă adresă web.</translation>
<translation id="4771973620359291008">A apărut o eroare necunoscută.</translation>
<translation id="4785689107224900852">Comută la această filă</translation>
-<translation id="4792143361752574037">A apărut o problemă la accesarea fișierelor de sesiune. Salvarea pe disc este dezactivată momentan. Reîncarcă pagina pentru a încerca din nou.</translation>
<translation id="4798078619018708837">Introdu data de expirare și codul CVC pentru <ph name="CREDIT_CARD" /> ca să actualizezi detaliile cardului. După ce confirmi, acest site va avea acces la detaliile cardului tău din Contul Google.</translation>
<translation id="4800132727771399293">Verifică data de expirare și codul CVC și încearcă din nou</translation>
+<translation id="480334179571489655">Eroare de politică de origine</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Deschide</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Nu există rezultate</translation>
<translation id="4950898438188848926">Butonul Comută între file, apasă pe Enter pentru a comuta la fila deschisă, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Acțiuni</translation>
-<translation id="495832697253704892">Raportarea extensiilor</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Extindeți lista</translation>
<translation id="4974590756084640048">Reactivează avertismentele</translation>
+<translation id="4984339528288761049">Prc5 (Plic)</translation>
<translation id="4989163558385430922">Afișează-le pe toate</translation>
<translation id="4989809363548539747">Acest plugin nu este acceptat</translation>
-<translation id="4996230189582812866">Raportare</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="5014174725590676422">Se afișează ecranul pentru prima rulare a Asistentului Google în Chrome</translation>
<translation id="5015510746216210676">Numele dispozitivului:</translation>
+<translation id="5017554619425969104">Textul copiat de tine</translation>
<translation id="5018422839182700155">Pagina nu poate fi deschisă</translation>
<translation id="5019198164206649151">Depozit de fundal în stare nevalidă</translation>
<translation id="5023310440958281426">Consultați politicile administratorului</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Context local <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Permite</translation>
<translation id="5040262127954254034">Confidențialitate</translation>
+<translation id="5043480802608081735">Linkul copiat de tine</translation>
<translation id="5045550434625856497">Parolă incorectă</translation>
<translation id="5056549851600133418">Articole pentru tine</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />să verifici adresa proxy-ului;<ph name="END_LINK" /></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="5097099694988056070">Statistici privind dispozitivul, cum ar fi utilizarea CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Dispozitivul tău este gestionat de <ph name="ENROLLMENT_DOMAIN" /> și contul tău este gestionat de <ph name="ACCOUNT_DOMAIN" />. Administratorii pot configura de la distanță dispozitivul și contul tău.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 de biți)</translation>
-<translation id="5128122789703661928">Sesiunea cu acest nume nu este validă pentru ștergere.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Gestionează adresele...</translation>
+<translation id="5138227688689900538">Afișează mai puțin</translation>
<translation id="5141240743006678641">Criptează parolele sincronizate cu datele de conectare Google</translation>
<translation id="5145883236150621069">Răspunsul pentru politică include un cod de eroare</translation>
+<translation id="515292512908731282">C4 (Plic)</translation>
<translation id="5159010409087891077">Deschide pagina într-o fereastră incognito nouă (⇧⌘N)</translation>
<translation id="516920405563544094">Introdu codul CVC pentru <ph name="CREDIT_CARD" />. După ce confirmi, acest site va avea acces la detaliile cardului tău din Contul Google.</translation>
<translation id="5169827969064885044">Este posibil să pierzi accesul la contul organizației sau să fii victima unui furt de identitate. Chrome îți recomandă să îți schimbi acum parola.</translation>
<translation id="5171045022955879922">Caută sau introdu adresa URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Computer</translation>
<translation id="5179510805599951267">Nu este în <ph name="ORIGINAL_LANGUAGE" />? Semnalează această eroare.</translation>
<translation id="5190835502935405962">Bară de marcaje</translation>
-<translation id="5200263511887412697">raportează lista cu utilizatorii dispozitivului care s-au conectat recent</translation>
+<translation id="519422657042045905">Adnotarea nu este disponibilă</translation>
<translation id="5201306358585911203">O pagină încorporată de pe această pagină afișează mesajul</translation>
<translation id="5205222826937269299">Numele este obligatoriu</translation>
<translation id="5215116848420601511">Metodele de plată și adresele care folosesc Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Adresa de e-mail este obligatorie</translation>
<translation id="5230733896359313003">Adresă de expediere</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Conectează-te la rețea”</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (Plic)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Adrese de rețea</translation>
<translation id="5285570108065881030">Afișează toate parolele salvate</translation>
<translation id="5287240709317226393">Afișați cookie-urile</translation>
<translation id="5288108484102287882">Validarea valorilor de politică a returnat avertismente</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> din <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Alege informațiile de contact</translation>
<translation id="5327248766486351172">Nume</translation>
+<translation id="5329858041417644019">Browserul tău nu este gestionat</translation>
<translation id="5332219387342487447">Metoda de expediere</translation>
+<translation id="5334013548165032829">Jurnale de sistem detaliate</translation>
<translation id="5344579389779391559">Această pagină poate să genereze costuri</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">„Ora este setată în trecut”, „Ora este setată în viitor” sau „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">Pentru a-ți folosi cardurile pe toate dispozitivele, conectează-te și activează sincronizarea.</translation>
<translation id="5386426401304769735">Lanțul de certificate pentru acest site conține un certificat semnat folosind SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Nevalide</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Repetați editarea</translation>
+<translation id="5478437291406423475">B6/C4 (Plic)</translation>
<translation id="5481076368049295676">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="54817484435770891">Adaugă o adresă validă</translation>
<translation id="5490432419156082418">Adrese și altele</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Contactează administratorul sistemului.</translation>
<translation id="549333378215107354">Mărimea 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Marcaje gestionate</translation>
<translation id="5510766032865166053">Este posibil să fi fost mutat sau șters.</translation>
<translation id="5523118979700054094">Numele politicii</translation>
<translation id="552553974213252141">Textul a fost extras corect?</translation>
+<translation id="553484882784876924">Prc6 (Plic)</translation>
<translation id="5540224163453853">Articolul solicitat nu poate fi găsit.</translation>
<translation id="5541546772353173584">Adaugă o adresă de e-mail</translation>
<translation id="5545756402275714221">Articole pentru tine</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Editează adresa</translation>
<translation id="5598944008576757369">Alege metoda de plată</translation>
<translation id="560412284261940334">Gestionarea nu este acceptată</translation>
+<translation id="5605670050355397069">Registru</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> te-a redirecționat de prea multe ori.</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="5632627355679805402">Datele au fost criptate cu <ph name="BEGIN_LINK" />parola Google<ph name="END_LINK" /> începând cu <ph name="TIME" />. Introdu parola pentru a începe sincronizarea.</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="563324245173044180">Conținutul înșelător a fost blocat.</translation>
<translation id="5659593005791499971">Adresă de e-mail</translation>
+<translation id="5663614846592581799">9x11 (Plic)</translation>
+<translation id="5663955426505430495">Administratorul acestui dispozitiv a instalat extensii pentru funcții suplimentare. Extensiile au acces la unele dintre datele tale.</translation>
<translation id="5675650730144413517">Pagina nu funcționează</translation>
+<translation id="5684874026226664614">Hopa. Această pagină nu a putut fi tradusă.</translation>
<translation id="5685654322157854305">Adaugă adresa de expediere</translation>
<translation id="5689199277474810259">Exportă în format JSON</translation>
<translation id="5689516760719285838">Locație</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Identitatea acestui site nu a fost confirmată.</translation>
<translation id="5719499550583120431">Se acceptă carduri preplătite.</translation>
<translation id="5720705177508910913">Utilizator curent</translation>
+<translation id="5728056243719941842">C5 (Plic)</translation>
<translation id="5730040223043577876">Chrome îți recomandă să resetezi parola dacă ai folosit-o și pe alte site-uri.</translation>
<translation id="5732392974455271431">Părinții tăi îl pot debloca pentru tine</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Salvează cardul în Contul Google}few{Salvează cardurile în Contul Google}other{Salvează cardurile în Contul Google}}</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="5770114862687765385">Fișierul pare deteriorat. Pentru a reseta sesiunea, dă clic pe butonul „Resetează”.</translation>
<translation id="5778550464785688721">Control complet asupra dispozitivelor MIDI</translation>
<translation id="578305955206182703">Chihlimbar</translation>
<translation id="57838592816432529">Dezactivează sunetul</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>
+<translation id="5798290721819630480">Renunți la modificări?</translation>
<translation id="5798683403665926540">Schimbă Pagina principală în setările Chrome</translation>
<translation id="5803412860119678065">Dorești să completezi datele <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Permisiuni</translation>
<translation id="5810442152076338065">Conexiunea la <ph name="DOMAIN" /> este criptată folosind o suită de codificare învechită.</translation>
<translation id="5813119285467412249">&amp;Repetați adăugarea</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="5860033963881614850">Dezactivat</translation>
<translation id="5863847714970149516">Următoarea pagină poate să genereze costuri</translation>
<translation id="5866257070973731571">Adaugă un număr de telefon</translation>
<translation id="5869405914158311789">Acest site nu poate fi accesat</translation>
<translation id="5869522115854928033">Parole salvate</translation>
<translation id="5887400589839399685">Cardul a fost salvat</translation>
-<translation id="5893718151540690985">raportează lista cu interfețele de rețea, care cuprinde tipurile acestora și adresele hardware</translation>
<translation id="5893752035575986141">Se acceptă carduri de credit.</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="5916664084637901428">Activat</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Salvezi cardul în Contul Google?</translation>
<translation id="5922853866070715753">Aproape finalizat</translation>
<translation id="5932224571077948991">Site-ul afișează anunțuri deranjante sau înșelătoare</translation>
-<translation id="5939518447894949180">Resetează</translation>
<translation id="5946937721014915347">Se deschide <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Nu te poți înscrie cu contul de consumator (este disponibilă o licență din pachet).</translation>
<translation id="5967592137238574583">Editează informațiile de contact</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Micșorează</translation>
<translation id="5977489021191000276">Dispozitivul tău nu este gestionat de un administrator.</translation>
<translation id="5977976211062815271">Pe acest dispozitiv</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nu se poate deschide aplicația de plată</translation>
<translation id="5989320800837274978">Nu sunt specificate nici servere proxy fixe și nici o adresă URL pentru scripturi .pac.</translation>
<translation id="5990559369517809815">Solicitările trimise la server au fost blocate de o extensie.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">raportează statisticile privind hardware-ul cum ar fi utilizarea CPU/RAM</translation>
<translation id="6034000775414344507">Gri deschis</translation>
+<translation id="6034283069659657473">10x14 (Plic)</translation>
<translation id="6039846035001940113">Dacă problema persistă, contactează proprietarul site-ului.</translation>
<translation id="6040143037577758943">Închide</translation>
<translation id="6044573915096792553">Mărimea 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Folosești cardurile pe toate dispozitivele?</translation>
<translation id="6059925163896151826">Dispozitive USB</translation>
-<translation id="6071091556643036997">Tipul de politică nu este valid.</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="6094273045989040137">Adnotează</translation>
<translation id="610911394827799129">Contul Google poate să ofere alte forme ale istoricului de navigare la <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informații despre extensiile și pluginurile instalate</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Eliberează mai puțin de <ph name="SIZE" />. Este posibil ca unele site-uri să se încarce mai lent la următoarea accesare.</translation>
<translation id="6337534724793800597">Filtrați politicile după nume</translation>
<translation id="6358450015545214790">Ce înseamnă acestea?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Urmează costuri potențiale.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{o altă sugestie}few{alte # sugestii}other{alte # de sugestii}}</translation>
<translation id="6387754724289022810">Pentru a plăti mai rapid data viitoare, salvează cardul și adresa de facturare în Contul Google și pe acest dispozitiv.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Modifică marcajul</translation>
+<translation id="6406765186087300643">C0 (Plic)</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="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="6434309073475700221">Renunță</translation>
+<translation id="6446163441502663861">Kahu (Plic)</translation>
<translation id="6446608382365791566">Adaugă mai multe informații</translation>
<translation id="6447842834002726250">Cookie-uri</translation>
<translation id="6451458296329894277">Confirmă retrimiterea formularului</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">repornește Chrome;</translation>
<translation id="6529602333819889595">&amp;Repetați ștergerea</translation>
<translation id="6534179046333460208">Sugestii pentru Webul material</translation>
+<translation id="6556866813142980365">Repetă</translation>
<translation id="6563469144985748109">Administratorul nu l-a aprobat încă</translation>
<translation id="6569060085658103619">Se afișează pagina unei extensii</translation>
+<translation id="6578796323535178455">C2 (Plic)</translation>
<translation id="6579990219486187401">Roz deschis</translation>
+<translation id="6583674473685352014">B6 (Plic)</translation>
+<translation id="6587923378399804057">Linkul copiat de tine</translation>
+<translation id="6591833882275308647">Dispozitivul <ph name="DEVICE_TYPE" /> nu este gestionat</translation>
<translation id="6596325263575161958">Opțiuni de criptare</translation>
<translation id="6604181099783169992">Senzori de mișcare sau de lumină</translation>
+<translation id="6609880536175561541">Prc7 (Plic)</translation>
<translation id="6624427990725312378">Informații de contact</translation>
<translation id="6626291197371920147">Adaugă un număr de card valid</translation>
<translation id="6628463337424475685">Căutare <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Această politică este învechită.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Niciunul}=1{De pe un site (nu te va deconecta de la Contul Google)}few{De pe # site-uri (nu te va deconecta de la Contul Google)}other{De pe # de site-uri (nu te va deconecta de la Contul Google)}}</translation>
<translation id="6657585470893396449">Parolă</translation>
+<translation id="6670613747977017428">Înapoi la zona sigură.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Indicativ de înregistrare:</translation>
<translation id="6711464428925977395">A apărut o problemă la serverul proxy sau adresa nu este corectă.</translation>
<translation id="6723740634201835758">În Contul Google</translation>
+<translation id="6738516213925468394">Datele au fost criptate cu <ph name="BEGIN_LINK" />expresia de acces pentru sincronizare<ph name="END_LINK" /> la <ph name="TIME" />. Introdu expresia de acces pentru a începe sincronizarea.</translation>
<translation id="674375294223700098">Eroare de certificat de server necunoscută.</translation>
<translation id="6744009308914054259">În timp ce aștepți o conexiune, poți accesa Descărcările pentru a citi articole offline.</translation>
<translation id="6753269504797312559">Valoarea politicii</translation>
<translation id="6757797048963528358">Dispozitivul este inactiv.</translation>
+<translation id="6768213884286397650">Hagaki (Carte poștală)</translation>
<translation id="6778737459546443941">Părintele tău nu l-a aprobat încă</translation>
<translation id="67862343314499040">Violet</translation>
+<translation id="6786747875388722282">Extensii</translation>
<translation id="679355240208270552">Valoare ignorată, deoarece politica nu a activat căutarea prestabilită.</translation>
<translation id="681021252041861472">Câmp obligatoriu</translation>
<translation id="6810899417690483278">ID-ul de personalizare</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Dispozitiv</translation>
<translation id="6970216967273061347">Județ</translation>
<translation id="6973656660372572881">Sunt specificate atât servere proxy fixe, cât și o adresă URL pentru scripturi .pac.</translation>
+<translation id="6973932557599545801">Nu te mai pot ajuta. Continuă personal.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Dezactivează sunetul (prestabilit)</translation>
<translation id="6984479912851154518">Vei părăsi modul privat pentru a plăti folosind o aplicație externă. Continui?</translation>
<translation id="6989763994942163495">Afișează setările avansate...</translation>
+<translation id="6993898126790112050">6x9 (Plic)</translation>
<translation id="6996312675313362352">Tradu întotdeauna din <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Aceste costuri pot fi unice sau recurente și ascunse.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ascunde</translation>
<translation id="7108819624672055576">Permisă de o extensie</translation>
<translation id="7111012039238467737">(Valid)</translation>
+<translation id="7118618213916969306">Caută URL-ul din clipboard, <ph name="SHORT_URL" /></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="7135130955892390533">Arată starea</translation>
<translation id="7138472120740807366">Metodă de livrare</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (Plic)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavandă</translation>
-<translation id="7158980942472052083">Adresă URL nevalidă. Trebuie să fie un URL cu o schemă standard.</translation>
<translation id="717330890047184534">Cod Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Serverul pe care dorești să îl accesezi, <ph name="ORIGIN" />, a solicitat
+ ca o politică de securitate să fie aplicată tuturor solicitărilor către el. Însă, în loc să
+ livreze o politică, a redirecționat browserul în altă parte, ceea ce împiedică
+ browserul să îți îndeplinească solicitarea pentru <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Salvează și completează metodele de plată</translation>
<translation id="7180611975245234373">Actualizați</translation>
<translation id="7182878459783632708">Nu au fost setate politici</translation>
<translation id="7186367841673660872">Această pagină a fost tradusă din <ph name="ORIGINAL_LANGUAGE" /> în <ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Eliberează <ph name="SIZE" />. Este posibil ca unele site-uri să se încarce mai lent la următoarea accesare.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administratorul tău poate să vadă:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> nu respectă standardele de securitate.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /> despre această problemă.</translation>
<translation id="7219179957768738017">Conexiunea utilizează <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Se procesează</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Site-ul pe care urmează să îl accesezi conține programe malware</translation>
+<translation id="724766306220616965">Avertismente, Conflict</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="7251437084390964440">Configurația rețelei nu respectă standardul ONC. Este posibil ca anumite părți ale configurației să nu fie importate.
Detalii suplimentare:
@@ -982,11 +1120,14 @@ Detalii suplimentare:
<translation id="7300012071106347854">Albastru cobalt</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />”</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="7313965965371928911">Avertizări privind <ph name="BEGIN_LINK" />Navigarea sigură<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Ajutor pentru conectare</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Linie de comandă</translation>
-<translation id="7365061714576910172">Exportă în format Linux</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>
@@ -994,6 +1135,7 @@ Detalii suplimentare:
<translation id="7381288752349550461">Modificarea sesiunii gestionate</translation>
<translation id="7390545607259442187">Confirmă cardul</translation>
<translation id="7400418766976504921">Adresă URL</translation>
+<translation id="7403591733719184120">Dispozitivul <ph name="DEVICE_NAME" /> este gestionat</translation>
<translation id="7407424307057130981">&lt;p&gt;Această eroare se va afișa dacă ai un software Superfish pe computerul Windows.&lt;/p&gt;
&lt;p&gt;Urmează acești pași ca să dezactivezi temporar software-ul, astfel încât să poți accesa internetul. Vei avea nevoie de privilegii de administrator.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Detalii suplimentare:
&lt;&lt;li&gt;Dă clic pe &lt;strong&gt;Apply&lt;/strong&gt; (Aplică), apoi dă clic pe &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Accesează &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Centrul de ajutor Chrome&lt;/a&gt; pentru a afla cum poți să elimini definitiv software-ul de pe computer
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Gestionare <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Format-Larg</translation>
<translation id="7416351320495623771">Gestionează parolele…</translation>
<translation id="7419106976560586862">Calea profilului</translation>
<translation id="7437289804838430631">Adaugă informații de contact</translation>
@@ -1013,22 +1155,24 @@ Detalii suplimentare:
<translation id="7442725080345379071">Portocaliu deschis</translation>
<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="7449109375006139765">trimite jurnalele de sistem la serverul de gestionare</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="7460618730930299168">Proiecția este diferită de ce ai selectat. Continui?</translation>
<translation id="7473891865547856676">Nu, mulțumesc</translation>
-<translation id="7475525192983021547">raportează intervalele de timp în care utilizatorul este activ pe dispozitiv</translation>
<translation id="7481312909269577407">Înainte</translation>
<translation id="7485870689360869515">Nu s-au găsit date.</translation>
+<translation id="7498234416455752244">Continuați editarea</translation>
<translation id="7508255263130623398">ID-ul de dispozitiv returnat pentru politică este gol sau nu corespunde cu ID-ul de dispozitiv actual</translation>
<translation id="7508870219247277067">Verde avocado</translation>
<translation id="7511955381719512146">Rețeaua Wi-Fi pe care o folosești poate solicita accesarea adresei <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Plic)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Conexiunea la acest site nu este privată</translation>
+<translation id="7535087603100972091">Valoare</translation>
<translation id="7537536606612762813">Obligatorie</translation>
+<translation id="7538364083937897561">A2 (Plic)</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>
@@ -1037,8 +1181,8 @@ Detalii suplimentare:
<translation id="7552846755917812628">Încearcă următoarele sfaturi:</translation>
<translation id="7554791636758816595">Filă nouă</translation>
<translation id="7564049878696755256">Este posibil să pierzi accesul la contul <ph name="ORG_NAME" /> sau să fii victima unui furt de identitate. Chrome îți recomandă să îți schimbi acum parola.</translation>
-<translation id="7566125604157659769">Textul copiat</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="7568105740864181217">Browserul este gestionat de o companie, școală sau altă organizație. Administratorul poate schimba configurația browserului de la distanță. Este posibil ca activitatea de pe acest dispozitiv să fie gestionată și din afara Chrome. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Detalii suplimentare:
<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="7633909222644580952">Date privind performanța și rapoarte de blocare</translation>
<translation id="7637571805876720304">Elimini cardul de credit din Chromium?</translation>
<translation id="7639968568612851608">Gri închis</translation>
<translation id="765676359832457558">Ascundeți setările avansate...</translation>
@@ -1058,9 +1203,11 @@ Detalii suplimentare:
<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="7676643023259824263">Caută text din clipboard, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Schimbă motorul de căutare</translation>
<translation id="7682287625158474539">Expediere</translation>
<translation id="7687186412095877299">Completează formularele de plată cu metodele de plată salvate</translation>
+<translation id="7697066736081121494">Prc8 (Plic)</translation>
<translation id="769721561045429135">În acest moment ai carduri care pot fi folosite doar pe acest dispozitiv. Dă clic pe Continuă pentru a vedea cardurile.</translation>
<translation id="7699293099605015246">Articolele nu sunt disponibile în acest moment</translation>
<translation id="7701040980221191251">Niciuna</translation>
@@ -1072,11 +1219,13 @@ Detalii suplimentare:
<translation id="774634243536837715">Conținutul periculos a fost blocat.</translation>
<translation id="7752995774971033316">Negestionat</translation>
<translation id="7755287808199759310">Părintele tău îl poate debloca pentru tine</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Este posibil ca firewallul sau software-ul antivirus să fi blocat conexiunea.</translation>
<translation id="7759163816903619567">Domeniu afișat:</translation>
<translation id="7761701407923456692">Certificatul serverului nu se potrivește cu adresa URL.</translation>
<translation id="7763386264682878361">Parser pentru manifestul plății</translation>
<translation id="7764225426217299476">Adaugă o adresă</translation>
+<translation id="7770259615151589601">Designated-Lung</translation>
<translation id="777702478322588152">Prefectură</translation>
<translation id="7791543448312431591">Adaugă</translation>
<translation id="7793809570500803535">Pagina web de la <ph name="SITE" /> poate fi temporar nefuncțională sau a fost mutată definitiv la o nouă adresă web.</translation>
@@ -1088,8 +1237,8 @@ Detalii suplimentare:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Elimini sugestia pentru formular din Chrome?</translation>
<translation id="7815407501681723534">S-au găsit <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> pentru „<ph name="SEARCH_STRING" />”</translation>
-<translation id="7818867226424560206">Gestionarea politicilor</translation>
<translation id="782886543891417279">Rețeaua Wi-Fi pe care o folosești (<ph name="WIFI_NAME" />) poate solicita accesarea paginii de conectare.</translation>
+<translation id="7836231406687464395">Postfix (Plic)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Niciuna}=1{O aplicație (<ph name="EXAMPLE_APP_1" />)}=2{Două aplicații (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}few{# aplicații (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# de aplicații (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Cu toate acestea, nu ești invizibil(ă). Trecerea în modul incognito nu ascunde activitatea de navigare față de angajator, față de furnizorul de servicii de internet sau față de site-urile pe care le accesezi.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@ Detalii suplimentare:
<translation id="7878562273885520351">Este posibil ca parola să fie compromisă</translation>
<translation id="7882421473871500483">Maro</translation>
<translation id="7887683347370398519">Verifică codul CVC și încearcă din nou</translation>
-<translation id="7893255318348328562">Numele sesiunii</translation>
+<translation id="7904208859782148177">C3 (Plic)</translation>
<translation id="79338296614623784">Introdu un număr de telefon valid</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Expiră pe <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Detalii suplimentare:
<translation id="7951415247503192394">(32 de biți)</translation>
<translation id="7956713633345437162">Marcaje mobile</translation>
<translation id="7961015016161918242">Niciodată</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Nespecificată</translation>
<translation id="800218591365569300">Încearcă să închizi celelalte file sau programe pentru a elibera memoria.</translation>
+<translation id="8004582292198964060">Browser</translation>
<translation id="8009225694047762179">Gestionează parolele</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Acest card și adresa de facturare vor fi salvate. Le vei putea folosi după ce te-ai conectat la <ph name="USER_EMAIL" />.}few{Aceste carduri și adresele de facturare vor fi salvate. Le vei putea folosi după ce te-ai conectat la <ph name="USER_EMAIL" />.}other{Aceste carduri și adresele de facturare vor fi salvate. Le vei putea folosi după ce te-ai conectat la <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Această pagină este în <ph name="SOURCE_LANGUAGE" />. Doriți traducere în <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Stilou</translation>
+<translation id="8037117624646282037">Cine a folosit recent dispozitivul</translation>
<translation id="8037357227543935929">Solicită (în mod prestabilit)</translation>
<translation id="803771048473350947">Fișier</translation>
<translation id="8041089156583427627">Trimiteți feedback</translation>
<translation id="8041940743680923270">Utilizați setarea prestabilită la nivel global (Întrebați)</translation>
<translation id="8042918947222776840">Alege metoda de preluare</translation>
<translation id="8057711352706143257">„<ph name="SOFTWARE_NAME" />” nu este configurat corect. De obicei, problema se remediază dezinstalând „<ph name="SOFTWARE_NAME" />” <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Dispozitivul a fost configurat pentru:</translation>
+<translation id="8066955247577885446">A apărut o eroare.</translation>
+<translation id="8074253406171541171">10x13 (Plic)</translation>
<translation id="8078141288243656252">Nu se poate adnota când este rotit</translation>
<translation id="8079031581361219619">Reîncarci site-ul?</translation>
<translation id="8088680233425245692">Articolul nu a fost vizualizat.</translation>
@@ -1131,11 +1284,12 @@ Detalii suplimentare:
<translation id="8091372947890762290">Se așteaptă activarea pe server</translation>
<translation id="8092774999298748321">Mov intens</translation>
<translation id="8094917007353911263">Rețeaua pe care o folosești poate solicita accesarea adresei <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Cardurile nevalide au fost eliminate</translation>
<translation id="8103161714697287722">Metodă de plată</translation>
<translation id="8118489163946903409">Metodă de plată</translation>
+<translation id="8123836779274890062">Dispozitivul <ph name="DEVICE_TYPE" /> gestionat de <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">„<ph name="SOFTWARE_NAME" />” nu a fost instalat corect pe computer sau în rețea. Contactează administratorul IT pentru a remedia această problemă.</translation>
-<translation id="8130693978878176684">Nu te mai pot ajuta. Continuă personal.</translation>
<translation id="8131740175452115882">Confirmați</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>
@@ -1145,8 +1299,11 @@ Detalii suplimentare:
<translation id="8197543752516192074">Tradu pagina</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="8202370299023114387">Conflict</translation>
+<translation id="8206978196348664717">Prc4 (Plic)</translation>
<translation id="8211406090763984747">Conexiunea este securizată</translation>
<translation id="8218327578424803826">Locație atribuită:</translation>
+<translation id="8220146938470311105">C7/C6 (Plic)</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="8238581221633243064">Deschide pagina într-o filă incognito nouă</translation>
@@ -1158,14 +1315,16 @@ Detalii suplimentare:
<translation id="825929999321470778">Afișează toate parolele salvate</translation>
<translation id="8261506727792406068">Șterge</translation>
<translation id="8267698848189296333">Te conectezi ca <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Browserul este gestionat de <ph name="ENROLLMENT_DOMAIN" />. Administratorul tău poate schimba configurarea browserului de la distanță. Este posibil ca activitatea de pe acest dispozitiv să fie gestionată și din afara Chrome. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Fotografie-Mare</translation>
<translation id="8286036467436129157">Conectați-vă</translation>
<translation id="8288807391153049143">Afișează certificatul</translation>
<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="8298115750975731693">Rețeaua Wi-Fi pe care o folosești (<ph name="WIFI_NAME" />) poate solicita accesarea adresei <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Fotografie-Mic</translation>
<translation id="8308427013383895095">Traducerea nu a reușit din cauza unei probleme cu conexiunea la rețea.</translation>
-<translation id="8311129316111205805">Încarcă sesiunea</translation>
<translation id="8332188693563227489">Accesul la <ph name="HOST_NAME" /> nu este permis</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Detalii suplimentare:
<translation id="8416694386774425977">Configurația rețelei este nevalidă și nu a putut fi importată.
Detalii suplimentare:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Dispozitiv gestionat de <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Modificați</translation>
<translation id="8428213095426709021">Setări</translation>
@@ -1211,9 +1369,11 @@ Detalii suplimentare:
<translation id="860043288473659153">Nume titular de card</translation>
<translation id="861775596732816396">Mărimea 4</translation>
<translation id="8620436878122366504">Părinții tăi nu l-au aprobat încă</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Salvează cardul pe acest dispozitiv</translation>
<translation id="8663226718884576429">Rezumatul comenzii, <ph name="TOTAL_LABEL" />, Mai multe detalii</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, răspuns, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Conexiunea la <ph name="DOMAIN" /> nu este criptată.</translation>
<translation id="8718314106902482036">Plata nu a fost finalizată</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sugestie de căutare</translation>
@@ -1227,6 +1387,7 @@ Detalii suplimentare:
<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="8763927697961133303">Dispozitiv USB</translation>
<translation id="8768895707659403558">Pentru a-ți folosi cardurile pe toate dispozitivele, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Repetați ștergerea</translation>
<translation id="8792621596287649091">Este posibil să pierzi accesul la contul <ph name="ORG_NAME" /> sau să fii victima unui furt de identitate. Chromium îți recomandă să îți schimbi acum parola.</translation>
<translation id="8800988563907321413">Sugestiile pentru În apropiere sunt afișate aici</translation>
@@ -1237,10 +1398,12 @@ Detalii suplimentare:
<translation id="885730110891505394">Permiterea accesului pentru Google</translation>
<translation id="8858065207712248076">Chrome îți recomandă să resetezi parola pentru <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> dacă ai folosit-o și pe alte site-uri.</translation>
<translation id="8866481888320382733">Eroare la analizarea setărilor pentru politică</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Închise recent</translation>
<translation id="8874824191258364635">Introdu un număr de card valid</translation>
<translation id="8891727572606052622">Mod proxy nevalid.</translation>
<translation id="8903921497873541725">Mărește</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Adaugă un nume</translation>
@@ -1248,13 +1411,13 @@ Detalii suplimentare:
<translation id="894185898663964645">Administratorul a configurat certificate rădăcină personalizate, care îi pot permite să vadă conținutul site-urilor pe care le accesezi.</translation>
<translation id="8943282376843390568">Verde-gălbui</translation>
<translation id="8957210676456822347">Autorizarea prin portalul captiv</translation>
+<translation id="8966619695390250636">Rezultate aproximative</translation>
<translation id="8968766641738584599">Salvează cardul</translation>
<translation id="8971063699422889582">Certificatul serverului a expirat.</translation>
<translation id="8975012916872825179">Include informații precum numerele de telefon, adresele de e-mail și adresele de expediere</translation>
<translation id="8978053250194585037">Recent, Navigarea sigură Google <ph name="BEGIN_LINK" />a detectat phishing<ph name="END_LINK" /> pe <ph name="SITE" />. Site-urile de phishing falsifică alte site-uri, pentru a te înșela.</translation>
<translation id="8983003182662520383">Metodele de plată și adresele care folosesc Google Pay</translation>
<translation id="8987927404178983737">Lună</translation>
-<translation id="8988408250700415532">A apărut o eroare. Poți termina comanda pe site.</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>
@@ -1264,6 +1427,7 @@ Detalii suplimentare:
<translation id="9011424611726486705">Deschide setările pentru site</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Nevalid)</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>
@@ -1275,11 +1439,11 @@ Detalii suplimentare:
<translation id="9065745800631924235">Căutare <ph name="TEXT" /> în istoric</translation>
<translation id="9069693763241529744">Blocată de o extensie</translation>
<translation id="9076283476770535406">Poate include conținut destinat adulților</translation>
+<translation id="9076630408993835509">Browserul nu este gestionat de o companie sau o altă organizație. Este posibil ca activitatea de pe acest dispozitiv să fie gestionată în afara Chrome. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Sunt necesare mai multe informații</translation>
<translation id="9080712759204168376">Rezumatul comenzii</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>
<translation id="9106062320799175032">Adaugă o adresă de facturare</translation>
-<translation id="9110718169272311511">Asistentul Google în Chrome este disponibil în partea de jos a ecranului</translation>
<translation id="9114524666733003316">Se confirmă cardul…</translation>
<translation id="9128870381267983090">Conectați-vă la rețea</translation>
<translation id="9137013805542155359">Afișează originalul</translation>
@@ -1288,6 +1452,7 @@ Detalii suplimentare:
<translation id="9148507642005240123">&amp;Anulați editarea</translation>
<translation id="9154194610265714752">Actualizat</translation>
<translation id="9157595877708044936">Se configurează...</translation>
+<translation id="9158625974267017556">C6 (Plic)</translation>
<translation id="9168814207360376865">Permite site-urilor să verifice dacă ai salvat metode de plată</translation>
<translation id="9169664750068251925">Blocați întotdeauna pe acest site</translation>
<translation id="9170848237812810038">&amp;Anulează</translation>
@@ -1302,10 +1467,12 @@ Detalii suplimentare:
<translation id="9219103736887031265">Imagini</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">GOLEȘTE FORMULARUL</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Este posibil să pierzi accesul la Contul Google. Chromium îți recomandă să îți schimbi parola acum. Ți se va cere să te conectezi.</translation>
<translation id="939736085109172342">Dosar nou</translation>
<translation id="945855313015696284">Verifică informațiile de mai jos și șterge cardurile nevalide</translation>
<translation id="951104842009476243">Carduri de debit și preplătite acceptate</translation>
+<translation id="958202389743790697">Blocat conform politicii de securitate de la <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Acest conținut poate încerca să instaleze aplicații înșelătoare care pretind a fi altceva sau colectează date care pot fi folosite pentru a te urmări. <ph name="BEGIN_LINK" />Afișează oricum<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Versiune oficială</translation>
<translation id="973773823069644502">Adaugă o adresă de livrare</translation>
@@ -1314,6 +1481,7 @@ Detalii suplimentare:
<translation id="984275831282074731">Metode de plată</translation>
<translation id="985199708454569384">&lt;p&gt;Această eroare se va afișa dacă data și ora de pe computer sau de pe dispozitivul mobil sunt inexacte.&lt;/p&gt;
&lt;p&gt;Pentru a remedia eroarea, deschide ceasul dispozitivului. Asigură-te că data și ora sunt corecte.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Versiune de programare</translation>
<translation id="989988560359834682">Editați adresa</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ru.xtb b/chromium/components/strings/components_strings_ru.xtb
index a4ac287e82f..a47dba61ad9 100644
--- a/chromium/components/strings/components_strings_ru.xtb
+++ b/chromium/components/strings/components_strings_ru.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ru">
-<translation id="1005145902654145231">Не удалось переименовать сеанс.</translation>
<translation id="1008557486741366299">Не сейчас</translation>
<translation id="1010200102790553230">Загрузить страницу позже</translation>
<translation id="1015730422737071372">Сообщить дополнительную информацию</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">неизвестное имя</translation>
<translation id="1050038467049342496">Закройте другие приложения.</translation>
<translation id="1055184225775184556">&amp;Отменить добавление</translation>
+<translation id="1056898198331236512">Внимание</translation>
<translation id="1058479211578257048">Сохранение карт…</translation>
<translation id="10614374240317010">Сайты, пароли для которых не сохраняются</translation>
+<translation id="1062160989074299343">Prc10 (конверт)</translation>
<translation id="106701514854093668">Закладки на компьютере</translation>
<translation id="1074497978438210769">Не защищено</translation>
<translation id="1080116354587839789">Выровнять по ширине окна</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Укажите имя владельца карты</translation>
<translation id="1089439967362294234">Сменить пароль</translation>
<translation id="109743633954054152">Открыть настройки паролей в Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Пока на сайтах обновляются сертификаты безопасности, предупреждения временно могут появляться чаще обычного.</translation>
<translation id="1126551341858583091">Место на карте памяти: <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">В кеше политики ошибок не найдено</translation>
+<translation id="1131264053432022307">Скопированное изображение</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885">Сайт <ph name="HOST_NAME" /> неожиданно разорвал соединение.</translation>
<translation id="1161325031994447685">Подключитесь к сети Wi-Fi ещё раз.</translation>
<translation id="1165039591588034296">Ошибка</translation>
-<translation id="1173894706177603556">Переименовать</translation>
<translation id="1175364870820465910">&amp;Печать...</translation>
<translation id="1181037720776840403">Удалить</translation>
<translation id="1197088940767939838">Оранжевый</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Название вашего устройства</translation>
<translation id="124116460088058876">Другие языки</translation>
<translation id="1250759482327835220">Чтобы ускорить процесс оплаты в будущем, сохраните карту, свое имя и платежный адрес в аккаунте Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (данные синхронизируются)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Модификации для командной строки</translation>
<translation id="129553762522093515">Недавно закрытые</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Удалите файлы cookie<ph name="END_LINK" />.</translation>
-<translation id="1314614906530272393">Выбранный сеанс не существует.</translation>
+<translation id="1320233736580025032">Prc1 (конверт)</translation>
+<translation id="132301787627749051">Поиск по изображению из буфера обмена</translation>
<translation id="1323433172918577554">Развернуть</translation>
<translation id="132390688737681464">Сохранять и автоматически подставлять адреса</translation>
<translation id="1333989956347591814">Ваши действия <ph name="BEGIN_EMPHASIS" />будут видны<ph name="END_EMPHASIS" />:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Адрес выдачи</translation>
<translation id="1348198688976932919">Сайт содержит опасные приложения</translation>
<translation id="1348779747280417563">Подтверждение</translation>
+<translation id="1357195169723583938">Кто и когда использовал устройство.</translation>
+<translation id="1364822246244961190">Правило заблокировано. Его значение не будет учтено.</translation>
<translation id="1374468813861204354">подсказки</translation>
+<translation id="1374692235857187091">Index-4x6 (открытка)</translation>
<translation id="1375198122581997741">Сведения о версии</translation>
<translation id="1376836354785490390">Свернуть</translation>
<translation id="1377321085342047638">Номер карты</translation>
<translation id="138218114945450791">Голубой</translation>
+<translation id="1382194467192730611">Это устройство USB входит в список разрешенных</translation>
<translation id="139305205187523129">Сайт <ph name="HOST_NAME" /> не отправил данных.</translation>
+<translation id="140316286225361634">Ко всем запросам сайта <ph name="ORIGIN" /> применяется политика безопасности, согласно которой сайт в данный момент считается небезопасным.</translation>
<translation id="1405567553485452995">Светло-зеленый</translation>
<translation id="1407135791313364759">Открыть все</translation>
<translation id="1413809658975081374">Ошибка нарушения конфиденциальности</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Печать</translation>
<translation id="1455413310270022028">Ластик</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Показать больше...</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Выбрать адрес доставки посылок</translation>
+<translation id="1492194039220927094">Обновление правил:</translation>
<translation id="1501859676467574491">Показывать банковские карты, сохраненные в аккаунте Google</translation>
-<translation id="1506687042165942984">Показывает предыдущую сохраненную копию этой страницы.</translation>
<translation id="1507202001669085618">&lt;p&gt;Эта ошибка может возникать при использовании портала Wi-Fi, для работы с которым требуется выполнить вход.&lt;/p&gt;
&lt;p&gt;Чтобы устранить проблему, нажмите &lt;strong&gt;Подключиться&lt;/strong&gt; на нужной веб-странице.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Укажите номер телефона</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Дата сборки</translation>
<translation id="1521655867290435174">Google Таблицы</translation>
<translation id="1527263332363067270">Ожидание подключения…</translation>
+<translation id="1529521330346880926">10x15 (конверт)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Подтвердите действие</translation>
<translation id="153384715582417236">Пока это всё</translation>
<translation id="154408704832528245">Выбрать адрес доставки</translation>
<translation id="1549470594296187301">Для использования этой функции необходимо включить JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Укажите дату окончания срока действия</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">При загрузке этой страницы возникли неполадки.</translation>
<translation id="1592005682883173041">Доступ к данным на устройстве</translation>
<translation id="1594030484168838125">Выбрать</translation>
<translation id="161042844686301425">Голубой</translation>
-<translation id="1618822247301510817">Скопированное изображение</translation>
<translation id="1620510694547887537">Камера</translation>
<translation id="1623104350909869708">Запретить создание дополнительных диалоговых окон на этой странице</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Закончить сеанс</translation>
<translation id="1639239467298939599">Загрузка</translation>
<translation id="1640180200866533862">Пользовательские правила</translation>
@@ -133,8 +148,10 @@
<translation id="1676269943528358898">На сайте <ph name="SITE" /> для защиты ваших данных обычно используется шифрование. Однако учетные данные, которые мы получили от сайта <ph name="SITE" /> сейчас, отличаются от тех, которые он отправляет обычно. Вероятно, вредоносный сайт пытается выдать себя за <ph name="SITE" />, либо страница подключения к сети Wi-Fi прервала соединение. Ваша информация по-прежнему в безопасности, так как браузер Google Chrome разорвал соединение до того, как произошел обмен данными.</translation>
<translation id="168841957122794586">Сертификат сервера содержит ненадежный криптографический ключ.</translation>
<translation id="1697532407822776718">Готово!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Недоступно, так как документ слишком большой</translation>
<translation id="1721312023322545264">Для доступа к этой странице требуется разрешение пользователя <ph name="NAME" /></translation>
<translation id="1721424275792716183">*Обязательное поле</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Обратитесь за помощью к системному администратору.</translation>
<translation id="1740951997222943430">Недопустимый формат месяца.</translation>
<translation id="1743520634839655729">Чтобы ускорить процесс оплаты в будущем, сохраните карту, свое имя, а также платежный адрес в аккаунте Google и на этом устройстве.</translation>
+<translation id="1745880797583122200">Этот браузер управляется администратором</translation>
<translation id="17513872634828108">Открытые вкладки</translation>
<translation id="1753706481035618306">Номер страницы</translation>
<translation id="1763864636252898013">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Операционная система устройства не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Обновите кодовую фразу для синхронизации.</translation>
<translation id="1787142507584202372">Здесь появятся открытые вкладки.</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Владелец карты</translation>
<translation id="1821930232296380041">Недопустимый запрос или неверные параметры запроса</translation>
+<translation id="1822540298136254167">Сайты, которые вы посещали, и время пребывания на них</translation>
<translation id="1826516787628120939">Проверка</translation>
<translation id="1834321415901700177">Сайт содержит вредоносное ПО</translation>
<translation id="1839551713262164453">При проверке значений политик обнаружены ошибки</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Удалить данные о работе в браузере Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{и ещё 1}one{и ещё #}few{и ещё #}many{и ещё #}other{и ещё #}}</translation>
<translation id="2003709556000175978">Сброс пароля</translation>
+<translation id="20053308747750172">Ко всем запросам, отправляемым на сервер <ph name="ORIGIN" />, применяются правила безопасности. Однако сервер отправил недействительные правила, поэтому браузер не может выполнить ваш запрос для сайта <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Прокси-сервер настраивается автоматически.</translation>
<translation id="2030481566774242610">Возможно, вы имели в виду <ph name="LINK" />.</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Проверьте настройки прокси-сервера и брандмауэра<ph name="END_LINK" />.</translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Департамент</translation>
<translation id="2102134110707549001">Сгенерировать надежный пароль</translation>
<translation id="2108755909498034140">Перезагрузите компьютер.</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Карта</translation>
<translation id="2114841414352855701">Игнорируется, так как правило <ph name="POLICY_NAME" /> имеет приоритет.</translation>
<translation id="213826338245044447">Закладки на мобильном</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">Изменение данных карты</translation>
<translation id="2166049586286450108">Доступ администратора ко всем данным</translation>
<translation id="2166378884831602661">Этот сайт не может обеспечить безопасное соединение</translation>
+<translation id="2169984857010174799">Kaku2 (конверт)</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2183608646556468874">Номер телефона</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адрес}one{# адрес}few{# адреса}many{# адресов}other{# адреса}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Номер телефона</translation>
<translation id="2283340219607151381">Сохранять и автоматически подставлять адреса</translation>
<translation id="2292556288342944218">Доступ в Интернет закрыт</translation>
+<translation id="2294558542833290837">Первоначально открытая вами ссылка выглядит необычно</translation>
+<translation id="2297722699537546652">B5 (конверт)</translation>
+<translation id="2310021320168182093">Chou2 (конверт)</translation>
<translation id="2316887270356262533">Освободится менее 1 МБ пространства. После этого некоторые веб-страницы могут загружаться дольше обычного.</translation>
<translation id="2317259163369394535">Для доступа к домену <ph name="DOMAIN" /> необходимо указать имя пользователя и пароль.</translation>
<translation id="2317583587496011522">Принимаются дебетовые карты.</translation>
<translation id="2330137317877982892">Карта <ph name="CREDIT_CARD" />, действует до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Эта настройка управляется администратором</translation>
+<translation id="2346319942568447007">Скопированное изображение</translation>
<translation id="2349790679044093737">Активный сеанс VR</translation>
<translation id="2354001756790975382">Другие закладки</translation>
<translation id="2354430244986887761">Система Безопасного просмотра Google недавно <ph name="BEGIN_LINK" />обнаружила вредоносные приложения<ph name="END_LINK" /> на сайте <ph name="SITE" />.</translation>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" />: получен отчет о сбое (не загружен)</translation>
<translation id="2367567093518048410">Уровень</translation>
<translation id="2378238891085281592">Вы работаете в режиме инкогнито</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Для предприятий (по умолчанию)</translation>
<translation id="2386255080630008482">Сертификат сервера отозван.</translation>
<translation id="2392959068659972793">Показывать правила, значения которых не заданы</translation>
<translation id="239429038616798445">Этот способ доставки недоступен. Выберите другой.</translation>
<translation id="2396249848217231973">&amp;Отменить удаление</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности может быть отозван. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="2418081434543109369">Ко всем запросам, отправляемым на сервер <ph name="ORIGIN" />, применяются . Однако серверу не удалось отправить правила, поэтому браузер не может выполнить ваш запрос для сайта <ph name="SITE" />.</translation>
<translation id="244665789865330679">Ваше устройство и аккаунт находятся под управлением домена <ph name="ENROLLMENT_DOMAIN" />. Администратор этого домена может удаленно изменять настройки вашего устройства и аккаунта.</translation>
<translation id="2463193859425327265">Изменить главную страницу</translation>
<translation id="2463739503403862330">Заполнить</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Выбрать способ доставки</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Выполните диагностику сети<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Перевести эту страницу</translation>
<translation id="2479410451996844060">Недействительный URL поисковой системы.</translation>
<translation id="2482878487686419369">Уведомления</translation>
<translation id="248348093745724435">Правила для компьютера</translation>
+<translation id="2485387744899240041">Имена пользователей для вашего устройства и браузера</translation>
<translation id="2491120439723279231">Сертификат сервера содержит ошибки.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">Синтаксический анализатор JSON</translation>
<translation id="2495093607237746763">Если флажок установлен, Chromium будет хранить на этом устройстве данные карты для быстрого заполнения форм.</translation>
<translation id="2498091847651709837">Сканировать новую карту</translation>
<translation id="2501278716633472235">Назад</translation>
<translation id="2503184589641749290">Дебетовые карты и карты предоплаты, которые принимаются к оплате</translation>
<translation id="2515629240566999685">Проверьте уровень сигнала сети.</translation>
-<translation id="2516852381693169964">Найти картинку (<ph name="SEARCH_ENGINE" />)</translation>
<translation id="2523886232349826891">Карта будет сохранена только на этом устройстве</translation>
<translation id="2524461107774643265">Укажите дополнительную информацию</translation>
<translation id="2536110899380797252">Добавить адрес</translation>
@@ -273,6 +305,7 @@
<translation id="2587841377698384444">Идентификатор Directory API:</translation>
<translation id="2597378329261239068">Документ защищен паролем. Введите пароль.</translation>
<translation id="2609632851001447353">Варианты</translation>
+<translation id="2618023639789766142">C10 (конверт)</translation>
<translation id="2625385379895617796">Часы спешат</translation>
<translation id="2634124572758952069">Не удалось найти IP-адрес сервера <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Состояние:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Закройте другие вкладки, расширения и приложения.</translation>
<translation id="267371737713284912">для отмены нажмите <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Удалить эти страницы из истории посещений?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Закрыть</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Карты, которые принимаются к оплате</translation>
<translation id="2702801445560668637">Список для чтения</translation>
<translation id="2704283930420550640">Значение не соответствует формату.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Удалить выбранные элементы</translation>
<translation id="277133753123645258">Способ доставки</translation>
<translation id="277499241957683684">Устройство не зарегистрировано</translation>
-<translation id="2781030394888168909">Экспортировать для macOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Соединение сброшено.</translation>
<translation id="2788784517760473862">Кредитные карты, которые принимаются к оплате</translation>
@@ -311,8 +345,10 @@
<translation id="2826760142808435982">Соединение зашифровано и проверено с помощью <ph name="CIPHER" />. В качестве механизма обмена ключами используется <ph name="KX" />.</translation>
<translation id="2835170189407361413">Очистить форму</translation>
<translation id="2847118875340931228">Открыть окно в режиме инкогнито</translation>
+<translation id="2850739647070081192">Invite (конверт)</translation>
<translation id="2851634818064021665">Для доступа к этой странице требуется разрешение.</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Сохранить карту?</translation>
<translation id="2903493209154104877">Адреса</translation>
<translation id="290376772003165898">Язык страницы не <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Способ доставки</translation>
<translation id="2928905813689894207">Платежный адрес</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности относится к <ph name="DOMAIN2" />. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="2948083400971632585">Прокси-серверы, используемые для соединения, можно отключить на странице настроек.</translation>
<translation id="2955913368246107853">Закрыть панель поиска</translation>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (конверт)</translation>
<translation id="3024663005179499861">Неверный тип политики</translation>
<translation id="3037605927509011580">Опаньки...</translation>
<translation id="3041612393474885105">Данные сертификата</translation>
+<translation id="3060227939791841287">C9 (конверт)</translation>
<translation id="3064966200440839136">Вы выйдете из режима инкогнито, чтобы произвести оплату во внешнем приложении. Продолжить?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{Нет}=1{1 пароль}one{# пароль}few{# пароля}many{# паролей}other{# пароля}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Добавить адрес получения</translation>
<translation id="3105172416063519923">Идентификатор объекта:</translation>
<translation id="3109728660330352905">У вас нет прав для просмотра этой страницы.</translation>
@@ -363,20 +403,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> на <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Отменить оплату</translation>
<translation id="3207960819495026254">Добавлено в закладки.</translation>
-<translation id="3209375525920864198">Недопустимое название сеанса.</translation>
+<translation id="321912867715453276">Внимание! Для этого правила существует более одного источника с одинаковыми значениями.</translation>
<translation id="3225919329040284222">Сертификат не соответствует встроенным параметрам определенных сайтов с высоким уровнем безопасности.</translation>
<translation id="3226128629678568754">Чтобы повторно ввести данные, необходимые для загрузки страницы, нажмите "Обновить".</translation>
<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Перевод не удался, так как страница уже написана на следующем языке: <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Версия вашего устройства и браузера</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Укажите имя владельца карты</translation>
<translation id="3287510313208355388">Скачать при подключении к Интернету</translation>
<translation id="3293642807462928945">Подробнее о политике <ph name="POLICY_NAME" />…</translation>
<translation id="3303855915957856445">Ничего не найдено</translation>
-<translation id="3305707030755673451">Данные были зашифрованы с помощью кодовой фразы <ph name="TIME" />. Введите ее, чтобы начать синхронизацию.</translation>
<translation id="3320021301628644560">Добавьте платежный адрес</translation>
<translation id="3324983252691184275">Малиновый</translation>
<translation id="3338095232262050444">Защищено</translation>
@@ -404,9 +445,11 @@
<translation id="3427342743765426898">&amp;Повторить изменения</translation>
<translation id="342781501876943858">Chromium рекомендует сбросить пароль, если вы использовали его на других сайтах.</translation>
<translation id="3431636764301398940">Сохранить карту на этом устройстве</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Владелец этого устройства отключил игру с динозавром.</translation>
<translation id="3447884698081792621">Показать сертификат (издатель: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Выберите интервал:</translation>
+<translation id="3456231139987291353">Number-11 (конверт)</translation>
<translation id="3461824795358126837">Маркер</translation>
<translation id="3462200631372590220">Скрыть подробности</translation>
<translation id="3467763166455606212">Укажите имя владельца карты.</translation>
@@ -429,20 +472,23 @@
<translation id="358285529439630156">Принимаются кредитные карты и карты предоплаты.</translation>
<translation id="3582930987043644930">Добавьте имя</translation>
<translation id="3583757800736429874">&amp;Повторить перемещение</translation>
+<translation id="35866233670761917">Администраторы не видят содержимое сайтов, которые вы посещаете.</translation>
<translation id="3586931643579894722">Скрыть подробности</translation>
+<translation id="3592413004129370115">Italian (конверт)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Размер: 2</translation>
<translation id="3615877443314183785">Укажите правильный срок действия.</translation>
<translation id="36224234498066874">Очистить историю...</translation>
<translation id="362276910939193118">Показать всю историю</translation>
-<translation id="3623476034248543066">Показать значение</translation>
<translation id="3630155396527302611">Если программа входит в список тех, которым разрешен доступ к сети,
удалите ее из списка и добавьте туда снова.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Проверка выполнена успешно</translation>
<translation id="3655670868607891010">Если эта проблема возникает часто, изучите <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Версия</translation>
<translation id="366077651725703012">Изменить данные кредитной карты</translation>
<translation id="3676592649209844519">Идентификатор устройства:</translation>
+<translation id="3677008721441257057">Возможно, вы хотели открыть сайт &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Не удалось подписать запрос</translation>
<translation id="3678529606614285348">Открыть страницу в новом окне в режиме инкогнито (Ctrl + Shift + N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" />: отчет о сбоях сохранен. <ph name="UPLOAD_TIME" />: отчет о сбоях загружен.</translation>
@@ -450,13 +496,14 @@
<translation id="3704162925118123524">Возможно, вам нужно перейти на страницу входа используемой сети.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Загрузка...</translation>
+<translation id="3709599264800900598">Скопированный текст</translation>
<translation id="3712624925041724820">Недостаточно лицензий</translation>
<translation id="3714780639079136834">Включите Wi-Fi или передачу данных по мобильной сети.</translation>
<translation id="3715597595485130451">Подключение к Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Проверьте настройки прокси-сервера, брандмауэра и DNS<ph name="END_LINK" />.</translation>
<translation id="372429172604983730">Эта ошибка может возникать из-за антивирусных приложений, брандмауэра, программ для веб-фильтрации или прокси-сервера.</translation>
+<translation id="373042150751172459">B4 (конверт)</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="3745099705178523657">После подтверждения реквизиты карты из аккаунта Google будут переданы этому сайту.</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>
@@ -469,10 +516,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Срок действия: до <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Размер: 16</translation>
+<translation id="3797522431967816232">Prc3 (конверт)</translation>
<translation id="3807873520724684969">Заблокирован опасный контент</translation>
<translation id="3810973564298564668">Настроить</translation>
<translation id="382518646247711829">Если вы используете прокси-сервер...</translation>
<translation id="3828924085048779000">Пустые кодовые фразы запрещены.</translation>
+<translation id="3831915413245941253">Администратор <ph name="ENROLLMENT_DOMAIN" /> установил расширения с дополнительными функциями для браузера. У расширений есть доступ к некоторым вашим данным.</translation>
<translation id="385051799172605136">Назад</translation>
<translation id="3858027520442213535">Обновить дату и время</translation>
<translation id="3884278016824448484">Конфликт идентификаторов устройств</translation>
@@ -480,6 +529,7 @@
<translation id="3886446263141354045">Ваш запрос на доступ к сайту отправлен пользователю <ph name="NAME" /></translation>
<translation id="3890664840433101773">Добавление адреса электронной почты</translation>
<translation id="3901925938762663762">Срок действия карты истек</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" />. <ph name="ERROR" />.</translation>
<translation id="3946209740501886391">Всегда спрашивать на этом сайте</translation>
<translation id="3949571496842715403">Сервер не может подтвердить связь с доменом <ph name="DOMAIN" />. В его сертификате безопасности не указаны альтернативные варианты имен. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
@@ -490,11 +540,13 @@
<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="3984550557525787191">Такое название уже существует.</translation>
<translation id="3987940399970879459">Менее 1 МБ</translation>
+<translation id="4008849406247176967">Внимание! Для этого правила существует более одного источника с конфликтующими значениями.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-страница поблизости}one{# веб-страница поблизости}few{# веб-страницы поблизости}many{# веб-страниц поблизости}other{# веб-страницы поблизости}}</translation>
<translation id="4030383055268325496">&amp;Отменить добавление</translation>
+<translation id="4032320456957708163">Этим браузером управляет администратор <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Ключ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (конверт)</translation>
<translation id="4067947977115446013">Введите действительный адрес</translation>
<translation id="4072486802667267160">При обработке заказа произошла ошибка. Повторите попытку.</translation>
<translation id="4075732493274867456">Клиент и сервер поддерживают разные версии протокола SSL или набора шифров.</translation>
@@ -514,10 +566,12 @@
<translation id="4159784952369912983">Фиолетовый</translation>
<translation id="4165986682804962316">Настройки сайтов</translation>
<translation id="4171400957073367226">Подтверждающая подпись недействительна</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{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="4179515394835346607"><ph name="ROW_NAME" />: <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;Повторить перемещение</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Проверьте настройки брандмауэра и антивирусного ПО<ph name="END_LINK" />.</translation>
+<translation id="4215751373031079683">7x9 (конверт)</translation>
<translation id="4220128509585149162">Сбои в работе Chrome</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="4221630205957821124">&lt;h4&gt;Шаг 1. Войдите на портал&lt;/h4&gt;
@@ -549,58 +603,79 @@
<translation id="4277028893293644418">Сбросить пароль</translation>
<translation id="4280429058323657511">, действует до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Карта сохранена в аккаунте Google.}one{Карты сохранены в аккаунте Google.}few{Карты сохранены в аккаунте Google.}many{Карты сохранены в аккаунте Google.}other{Карты сохранены в аккаунте Google.}}</translation>
+<translation id="42981349822642051">Развернуть</translation>
+<translation id="4302965934281694568">Chou3 (конверт)</translation>
<translation id="4305817255990598646">Переключиться</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Блокировать (по умолчанию)</translation>
+<translation id="4318566738941496689">Название вашего устройства и сетевой адрес</translation>
<translation id="4325863107915753736">Не удалось найти статью</translation>
<translation id="4326324639298822553">Проверьте срок действия и повторите попытку</translation>
<translation id="4331708818696583467">Ненадежный</translation>
<translation id="4340982228985273705">По нашим данным, этот компьютер не является корпоративным, поэтому в соответствии с правилом на него можно автоматически устанавливать только расширения из Интернет-магазина Chrome. URL для обновления: <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Кредитные карты, которые принимаются к оплате</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Злоумышленники могут использовать этот сайт, чтобы установить на ваш компьютер вредоносное ПО, которое крадет или удаляет личную информацию (например, фотографии, пароли, сообщения и реквизиты банковских карт).</translation>
<translation id="4358461427845829800">Управление способами оплаты…</translation>
+<translation id="4367563149485757821">Number-12 (конверт)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">Ожидаемое значение: <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">Вы попытались перейти на сайт <ph name="DOMAIN" />, однако сертификат, предоставленный сервером, был отозван издателем. Это означает, что учетные данные безопасности, предоставленные сервером, не заслуживают доверия. Возможно, вы имеете дело со злоумышленниками.</translation>
<translation id="4378154925671717803">Телефон</translation>
<translation id="4406896451731180161">Результаты поиска</translation>
-<translation id="4406972042435603828">Администратор установил полезные расширения для вашего браузера.</translation>
<translation id="4408413947728134509">Настройки файлов cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Адрес получения</translation>
<translation id="4424024547088906515">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Chrome не доверяет его сертификату безопасности. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="443121186588148776">Последовательный порт</translation>
<translation id="4432688616882109544">Ваш сертификат отклонен сайтом <ph name="HOST_NAME" /> или не был выдан.</translation>
<translation id="4434045419905280838">Всплывающие окна и переадресация</translation>
+<translation id="4435702339979719576">Открытка</translation>
<translation id="443673843213245140">Прокси-сервер отключен, но при этом его конфигурация задана явным образом.</translation>
<translation id="445100540951337728">Дебетовые карты, которые принимаются к оплате</translation>
+<translation id="4466881336512663640">Внесенные в форму изменения не сохранятся. Продолжить?</translation>
<translation id="4482953324121162758">Этот сайт не будет переводиться автоматически.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Недопустимый URL. Укажите URL в стандартном виде, например http://example.com или https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Ошибка проверки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">Обратитесь за помощью к системному администратору.</translation>
<translation id="450710068430902550">Доступ администратора</translation>
+<translation id="4510487217173779431">Chou4 (конверт)</translation>
<translation id="4515275063822566619">Это карты и адреса, указанные в Chrome и вашем аккаунте Google (<ph name="ACCOUNT_EMAIL" />). Вы можете изменить их на странице <ph name="BEGIN_LINK" />Настройки<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (конверт)</translation>
<translation id="4522570452068850558">Подробнее</translation>
<translation id="4524805452350978254">Изменить</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Отключите расширения.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Доставка</translation>
+<translation id="4579056131138995126">Персональный (конверт)</translation>
<translation id="4582204425268416675">Удалить карту</translation>
<translation id="4587425331216688090">Удалить адрес из Chrome?</translation>
<translation id="4592951414987517459">Соединение с <ph name="DOMAIN" /> зашифровано с помощью современных наборов шифров.</translation>
<translation id="4594403342090139922">&amp;Отменить удаление</translation>
<translation id="4597348597567598915">Размер: 8</translation>
+<translation id="4600854749408232102">C6/C5 (конверт)</translation>
<translation id="4646534391647090355">Перейти сейчас</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности содержит ошибки. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="467809019005607715">Google Презентации</translation>
<translation id="4690462567478992370">Прекратить использование недействительного сертификата</translation>
+<translation id="4691835149146451662">Architecture-A (конверт)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Соединение прервано</translation>
<translation id="471880041731876836">Доступ запрещен</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Выполните диагностику сети в Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Повторно загрузить политики</translation>
<translation id="4728558894243024398">Платформа</translation>
+<translation id="4731967714531604179">Prc2 (конверт)</translation>
<translation id="4736825316280949806">Перезапустите Chromium.</translation>
<translation id="473775607612524610">Обновить</translation>
<translation id="4738601419177586157">Подсказка при поиске "<ph name="TEXT" />"</translation>
<translation id="4742407542027196863">Управление паролями</translation>
<translation id="4744603770635761495">Путь к исполняемому файлу</translation>
+<translation id="4746351372139058112">Сообщения</translation>
<translation id="4750917950439032686">Информация, которую вы сообщаете этому сайту (например, пароли и номера банковских карт), защищена.</translation>
<translation id="4756388243121344051">&amp;История</translation>
<translation id="4758311279753947758">Добавить контактные данные</translation>
@@ -608,9 +683,9 @@
<translation id="4764776831041365478">Веб-страница по адресу <ph name="URL" />, возможно, временно недоступна или постоянно перемещена по новому адресу.</translation>
<translation id="4771973620359291008">Произошла неизвестная ошибка.</translation>
<translation id="4785689107224900852">Переключиться на эту вкладку</translation>
-<translation id="4792143361752574037">Не удалось получить доступ к файлам сеанса. Сохранение на диск пока недоступно. Обновите страницу и повторите попытку.</translation>
<translation id="4798078619018708837">Введите срок действия и CVC-код карты <ph name="CREDIT_CARD" />. После этого ее реквизиты из аккаунта Google будут переданы сайту.</translation>
<translation id="4800132727771399293">Проверьте срок действия и CVC-код, а затем повторите попытку</translation>
+<translation id="480334179571489655">Ошибка политики источника</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>
@@ -625,7 +700,6 @@
<translation id="4881695831933465202">Открыть</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>
@@ -634,15 +708,15 @@
<translation id="4943872375798546930">Нет результатов</translation>
<translation id="4950898438188848926">Кнопка переключения между вкладками. Чтобы переключиться на открытую вкладку (<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />), нажмите клавишу "Ввод".</translation>
<translation id="495170559598752135">Действия</translation>
-<translation id="495832697253704892">Отчеты о расширениях</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Развернуть список</translation>
<translation id="4974590756084640048">Снова включить предупреждения</translation>
+<translation id="4984339528288761049">Prc5 (конверт)</translation>
<translation id="4989163558385430922">Показать все</translation>
<translation id="4989809363548539747">Плагин не поддерживается</translation>
-<translation id="4996230189582812866">Отчеты</translation>
<translation id="5002932099480077015">Chrome будет хранить на этом устройстве данные карты для быстрого заполнения форм.</translation>
-<translation id="5014174725590676422">Показан экран первого запуска Google Ассистента в Chrome</translation>
<translation id="5015510746216210676">Имя компьютера:</translation>
+<translation id="5017554619425969104">Скопированный текст</translation>
<translation id="5018422839182700155">Не удалось открыть страницу</translation>
<translation id="5019198164206649151">Данные в хранилище повреждены</translation>
<translation id="5023310440958281426">Проверьте правила, установленные администратором</translation>
@@ -652,35 +726,51 @@
<translation id="5034369478845443529">Локальный идентификатор сбоя: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Разрешить</translation>
<translation id="5040262127954254034">Личные данные</translation>
+<translation id="5043480802608081735">Скопированная ссылка</translation>
<translation id="5045550434625856497">Неправильный пароль</translation>
<translation id="5056549851600133418">Статьи для вас</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Проверьте адрес прокси-сервера<ph name="END_LINK" />.</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="5097099694988056070">Статистические данные устройства, например об использовании процессора или оперативной памяти.</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Ваше устройство находится под управлением домена <ph name="ENROLLMENT_DOMAIN" />, а аккаунт – <ph name="ACCOUNT_DOMAIN" />. Администраторы этих доменов могут удаленно изменять настройки вашего устройства и аккаунта.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 бит)</translation>
-<translation id="5128122789703661928">Невозможно удалить сеанс с таким названием.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Управление адресами…</translation>
+<translation id="5138227688689900538">Свернуть</translation>
<translation id="5141240743006678641">Шифровать синхронизированные пароли с помощью учетных данных Google</translation>
<translation id="5145883236150621069">При проверке политики возвращен код ошибки</translation>
+<translation id="515292512908731282">C4 (конверт)</translation>
<translation id="5159010409087891077">Открыть страницу в новом окне в режиме инкогнито (⇧ + ⌘ + N)</translation>
<translation id="516920405563544094">Введите CVC-код карты <ph name="CREDIT_CARD" />. После этого ее реквизиты из аккаунта Google будут переданы сайту.</translation>
<translation id="5169827969064885044">Возможно, кто-то пытается получить доступ к вашим личным данным или корпоративному аккаунту. Рекомендуем немедленно сменить пароль.</translation>
<translation id="5171045022955879922">Введите запрос или URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Локальный компьютер</translation>
<translation id="5179510805599951267">Это не <ph name="ORIGINAL_LANGUAGE" />? Сообщите об ошибке</translation>
<translation id="5190835502935405962">Панель закладок</translation>
-<translation id="5200263511887412697">Отправлять данные о пользователях, недавно выполнявших вход на устройстве.</translation>
+<translation id="519422657042045905">В этот PDF-файл нельзя добавлять заметки</translation>
<translation id="5201306358585911203">Подтвердите действие</translation>
<translation id="5205222826937269299">Введите имя или название</translation>
<translation id="5215116848420601511">Способы оплаты и адреса из Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Введите адрес электронной почты</translation>
<translation id="5230733896359313003">Адрес доставки</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Подключитесь к сети"</translation>
<translation id="5251803541071282808">Облако</translation>
+<translation id="5252000469029418751">C7 (конверт)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Сетевые адреса.</translation>
<translation id="5285570108065881030">Показать все сохраненные пароли</translation>
<translation id="5287240709317226393">Показать файлы сookie</translation>
<translation id="5288108484102287882">При проверке значений политик обнаружены некритичные ошибки</translation>
@@ -692,7 +782,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> из <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Выбрать контактные данные</translation>
<translation id="5327248766486351172">Название</translation>
+<translation id="5329858041417644019">Этот браузер не управляется администратором</translation>
<translation id="5332219387342487447">Способ доставки</translation>
+<translation id="5334013548165032829">Подробные системные журналы.</translation>
<translation id="5344579389779391559">Если вы откроете эту страницу, с вашего счета могут быть списаны средства</translation>
<translation id="5355557959165512791">Сертификат веб-сайта <ph name="SITE" /> отозван. Открыть сайт в настоящее время нельзя. Сбой мог быть вызван сетевой ошибкой или действиями злоумышленников. Скорее всего, сайт заработает через некоторое время.</translation>
<translation id="536296301121032821">Не удалось сохранить настройки политики</translation>
@@ -700,6 +792,7 @@
<translation id="5377026284221673050">"Часы отстают", "Часы спешат" или &lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;</translation>
<translation id="5384855140246857529">Чтобы пользоваться картами на всех своих устройствах, войдите в аккаунт и включите синхронизацию.</translation>
<translation id="5386426401304769735">В цепочке сертификатов этого сайта есть сертификат, подписанный с помощью алгоритма SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности может быть недействителен в настоящее время. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
<translation id="5421136146218899937">Очистить историю...</translation>
<translation id="5430298929874300616">Удалить закладку</translation>
@@ -710,6 +803,7 @@
<translation id="5457113250005438886">Недопустимые данные</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Повторить изменения</translation>
+<translation id="5478437291406423475">B6/C4 (конверт)</translation>
<translation id="5481076368049295676">Посещение этой страницы может привести к установке вредоносной программы, которая похищает или удаляет данные. <ph name="BEGIN_LINK" />Все равно продолжить<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Введите действительный адрес</translation>
<translation id="5490432419156082418">Адреса и другие данные</translation>
@@ -717,10 +811,12 @@
<ph name="LINE_BREAK" />
Обратитесь к системному администратору.</translation>
<translation id="549333378215107354">Размер: 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Управляемые закладки</translation>
<translation id="5510766032865166053">Возможно, он был перемещен или удален.</translation>
<translation id="5523118979700054094">Название правила</translation>
<translation id="552553974213252141">Правильно ли извлечен текст?</translation>
+<translation id="553484882784876924">Prc6 (конверт)</translation>
<translation id="5540224163453853">Не удалось найти указанную статью</translation>
<translation id="5541546772353173584">Добавьте адрес электронной почты</translation>
<translation id="5545756402275714221">Новости для вас</translation>
@@ -735,15 +831,21 @@
<translation id="5595485650161345191">Изменить адрес</translation>
<translation id="5598944008576757369">Выбрать способ оплаты</translation>
<translation id="560412284261940334">Управление устройствами не поддерживается</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">Проверьте подключение к Интернету.</translation>
<translation id="5610807607761827392">Сведения о картах и адресах можно изменить в <ph name="BEGIN_LINK" />настройках<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996">Сайт <ph name="HOST_NAME" /> выполнил переадресацию слишком много раз.</translation>
<translation id="5629630648637658800">Не удалось применить настройки политики</translation>
<translation id="5631439013527180824">Токен устройства недействителен</translation>
+<translation id="5632627355679805402">Ваши данные были зашифрованы <ph name="TIME" /> с помощью <ph name="BEGIN_LINK" />пароля Google<ph name="END_LINK" />. Введите его, чтобы начать синхронизацию.</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="563324245173044180">Мошеннический контент заблокирован</translation>
<translation id="5659593005791499971">Электронная почта</translation>
+<translation id="5663614846592581799">9x11 (конверт)</translation>
+<translation id="5663955426505430495">Администратор устройства установил расширения с дополнительными функциями для браузера. У расширений есть доступ к некоторым вашим данным.</translation>
<translation id="5675650730144413517">Страница недоступна</translation>
+<translation id="5684874026226664614">Не удалось перевести страницу</translation>
<translation id="5685654322157854305">Добавить адрес доставки посылок</translation>
<translation id="5689199277474810259">Экспортировать как JSON</translation>
<translation id="5689516760719285838">Геоданные</translation>
@@ -752,38 +854,39 @@
<translation id="5710435578057952990">Идентификационные данные этого сайта не проверены.</translation>
<translation id="5719499550583120431">Принимаются карты предоплаты.</translation>
<translation id="5720705177508910913">Текущий пользователь</translation>
+<translation id="5728056243719941842">C5 (конверт)</translation>
<translation id="5730040223043577876">Chrome рекомендует сбросить пароль, если вы использовали его на других сайтах.</translation>
<translation id="5732392974455271431">Для разблокировки обратитесь к родителям.</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Сохраните карту в аккаунте Google}one{Сохраните карты в аккаунте Google}few{Сохраните карты в аккаунте Google}many{Сохраните карты в аккаунте Google}other{Сохраните карты в аккаунте Google}}</translation>
<translation id="5763042198335101085">Укажите действительный адрес электронной почты.</translation>
<translation id="5765072501007116331">Выберите адрес, чтобы посмотреть способы и условия доставки.</translation>
-<translation id="5770114862687765385">Файл поврежден. Чтобы восстановить сеанс, нажмите кнопку "Сбросить".</translation>
<translation id="5778550464785688721">Полный контроль над MIDI-устройствами</translation>
<translation id="578305955206182703">Янтарный</translation>
<translation id="57838592816432529">Отключить звук</translation>
<translation id="5784606427469807560">Не удалось подтвердить данные карты. Проверьте подключение к Интернету и повторите попытку.</translation>
<translation id="5785756445106461925">Обратите внимание, что на странице обнаружен небезопасный контент. Возможно, при передаче ресурсы просматриваются третьими лицами, а злоумышленники могут получить доступ к странице и изменить ее поведение или внешний вид.</translation>
<translation id="5786044859038896871">Заполнить данные банковской карты?</translation>
+<translation id="5798290721819630480">Отменить изменения?</translation>
<translation id="5798683403665926540">Изменить главную страницу в настройках Chrome</translation>
<translation id="5803412860119678065">Заполнить данные банковской карты <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Разрешения</translation>
<translation id="5810442152076338065">Соединение с <ph name="DOMAIN" /> зашифровано с помощью устаревшего набора шифров.</translation>
<translation id="5813119285467412249">&amp;Повторить добавление</translation>
<translation id="5838278095973806738">Не сообщайте этому сайту конфиденциальную информацию (например, пароли и номера банковских карт). К ней могут получить доступ злоумышленники.</translation>
+<translation id="5860033963881614850">ВЫКЛ</translation>
<translation id="5863847714970149516">При открытии этой страницы с вашего счета могут быть списаны средства</translation>
<translation id="5866257070973731571">Добавьте номер телефона</translation>
<translation id="5869405914158311789">Не удается получить доступ к сайту</translation>
<translation id="5869522115854928033">Сайты с сохраненными паролями</translation>
<translation id="5887400589839399685">Карта сохранена</translation>
-<translation id="5893718151540690985">Отправлять список сетевых интерфейсов с указанием их типов и адресов оборудования.</translation>
<translation id="5893752035575986141">Принимаются кредитные карты.</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="5916664084637901428">ВКЛ</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Сохранить карту в аккаунте Google?</translation>
<translation id="5922853866070715753">Почти готово…</translation>
<translation id="5932224571077948991">Сайт показывает навязчивую или вводящую в заблуждение рекламу</translation>
-<translation id="5939518447894949180">Сбросить</translation>
<translation id="5946937721014915347">Загрузка <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Регистрация невозможна, так как тип аккаунта не соответствует лицензии на устройстве.</translation>
<translation id="5967592137238574583">Измените контактную информацию</translation>
@@ -791,6 +894,7 @@
<translation id="5975083100439434680">Уменьшить</translation>
<translation id="5977489021191000276">Ваше устройство не управляется администратором.</translation>
<translation id="5977976211062815271">На этом устройстве</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Не удалось открыть Payments</translation>
<translation id="5989320800837274978">Ни фиксированные прокси-серверы, ни URL PAC-скриптов не указаны.</translation>
<translation id="5990559369517809815">Расширение заблокировало отправку запроса на сервер.</translation>
@@ -801,8 +905,8 @@
<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="6033927989869462158">Отправлять статистические данные о работе аппаратного оборудования, например об использовании процессора или оперативной памяти.</translation>
<translation id="6034000775414344507">Светло-серый</translation>
+<translation id="6034283069659657473">10x14 (конверт)</translation>
<translation id="6039846035001940113">Если проблема не исчезнет, свяжитесь с владельцем сайта.</translation>
<translation id="6040143037577758943">Закрыть</translation>
<translation id="6044573915096792553">Размер: 12</translation>
@@ -811,10 +915,10 @@
<translation id="6051221802930200923">Веб-сайт <ph name="SITE" /> использует механизм Certificate Pinning, поэтому на нем могла произойти подмена сертификата. Открыть сайт в настоящее время нельзя. Сбой мог быть вызван сетевой ошибкой или действиями злоумышленников. Скорее всего, сайт заработает через некоторое время.</translation>
<translation id="6058977677006700226">Хотите использовать карты на всех устройствах?</translation>
<translation id="6059925163896151826">USB-устройства</translation>
-<translation id="6071091556643036997">Указан неверный тип правил.</translation>
<translation id="6080696365213338172">Вы используете сертификат, предоставленный администратором, поэтому он может заблокировать передачу данных на сайт <ph name="DOMAIN" />.</translation>
<translation id="6094273045989040137">Аннотировать</translation>
<translation id="610911394827799129">Информация о других ваших действиях в Интернете может также храниться на странице <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Информация об установленных расширениях и плагинах</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{Нет}=1{1 синхронизированный пароль}one{# синхронизированный пароль}few{# синхронизированных пароля}many{# синхронизированных паролей}other{# синхронизированного пароля}}</translation>
<translation id="6146055958333702838">Проверьте соединение кабелей, перезагрузите маршрутизаторы, модемы и другие
сетевые устройства.</translation>
@@ -849,15 +953,21 @@
<translation id="6337133576188860026">Освободится менее <ph name="SIZE" /> пространства. После этого некоторые веб-страницы могут загружаться дольше обычного.</translation>
<translation id="6337534724793800597">Фильтровать политики по названию</translation>
<translation id="6358450015545214790">Что это значит?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Возможное списание средств</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{ещё 1 вариант}one{ещё # вариант}few{ещё # варианта}many{ещё # вариантов}other{ещё # варианта}}</translation>
<translation id="6387754724289022810">Чтобы ускорить процесс оплаты в будущем, сохраните карту и платежный адрес в аккаунте Google и на этом устройстве.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Изменить закладку</translation>
+<translation id="6406765186087300643">C0 (конверт)</translation>
<translation id="6410264514553301377">Введите срок действия и CVC-код карты <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Запрос на просмотр сайта отправлен вашему родителю</translation>
<translation id="6417515091412812850">Не удается проверить, был ли отозван сертификат.</translation>
<translation id="6433490469411711332">Изменить контактную информацию</translation>
<translation id="6433595998831338502">Сайт <ph name="HOST_NAME" /> не позволяет установить соединение.</translation>
+<translation id="6434309073475700221">Отменить передачу</translation>
+<translation id="6446163441502663861">Kahu (конверт)</translation>
<translation id="6446608382365791566">Укажите дополнительную информацию</translation>
<translation id="6447842834002726250">Файлы сookie</translation>
<translation id="6451458296329894277">Подтвердите повторную отправку формы</translation>
@@ -870,11 +980,17 @@
<translation id="6508722015517270189">Перезапустите Google Chrome.</translation>
<translation id="6529602333819889595">&amp;Повторить удаление</translation>
<translation id="6534179046333460208">Интернет вокруг нас: рекомендации</translation>
+<translation id="6556866813142980365">Повторить</translation>
<translation id="6563469144985748109">Ещё не одобрено администратором</translation>
<translation id="6569060085658103619">Вы просматриваете страницу расширения</translation>
+<translation id="6578796323535178455">C2 (конверт)</translation>
<translation id="6579990219486187401">Светло-розовый</translation>
+<translation id="6583674473685352014">B6 (конверт)</translation>
+<translation id="6587923378399804057">Скопированная ссылка</translation>
+<translation id="6591833882275308647">Это устройство <ph name="DEVICE_TYPE" /> не управляется администратором.</translation>
<translation id="6596325263575161958">Параметры шифрования</translation>
<translation id="6604181099783169992">Датчики движения и освещенности</translation>
+<translation id="6609880536175561541">Prc7 (конверт)</translation>
<translation id="6624427990725312378">Контактная информация</translation>
<translation id="6626291197371920147">Введите номер действующей карты</translation>
<translation id="6628463337424475685">Поиск <ph name="ENGINE" /></translation>
@@ -883,6 +999,7 @@
<translation id="6644283850729428850">Правило устарело.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Нет}=1{С 1 сайта (вы останетесь в аккаунте Google)}one{С # сайта (вы останетесь в аккаунте Google)}few{С # сайтов (вы останетесь в аккаунте Google)}many{С # сайтов (вы останетесь в аккаунте Google)}other{С # сайта (вы останетесь в аккаунте Google)}}</translation>
<translation id="6657585470893396449">Пароль</translation>
+<translation id="6670613747977017428">К настройкам безопасности</translation>
<translation id="6671697161687535275">Удалить подсказку из Chromium?</translation>
<translation id="6685834062052613830">Выйдите из аккаунта и завершите настройку</translation>
<translation id="6710213216561001401">Назад</translation>
@@ -890,12 +1007,15 @@
<translation id="671076103358959139">Токен регистрации:</translation>
<translation id="6711464428925977395">На прокси-сервере возникла проблема или адрес указан неверно.</translation>
<translation id="6723740634201835758">В аккаунте Google</translation>
+<translation id="6738516213925468394">Данные были зашифрованы <ph name="TIME" /> с помощью <ph name="BEGIN_LINK" />кодовой фразы<ph name="END_LINK" />. Введите ее, чтобы начать синхронизацию.</translation>
<translation id="674375294223700098">Неизвестная ошибка сертификата сервера.</translation>
<translation id="6744009308914054259">В ожидании подключения вы можете открыть скачанные файлы и почитать статьи офлайн.</translation>
<translation id="6753269504797312559">Значение правила</translation>
<translation id="6757797048963528358">Устройство находится в спящем режиме.</translation>
+<translation id="6768213884286397650">Hagaki (открытка)</translation>
<translation id="6778737459546443941">Ещё не одобрено родителем</translation>
<translation id="67862343314499040">Фиолетовый</translation>
+<translation id="6786747875388722282">Расширения</translation>
<translation id="679355240208270552">Игнорируется, так как в правиле не задан поиск по умолчанию.</translation>
<translation id="681021252041861472">Обязательное поле</translation>
<translation id="6810899417690483278">Идентификатор персонализации</translation>
@@ -928,10 +1048,12 @@
<translation id="6965978654500191972">Устройство</translation>
<translation id="6970216967273061347">Округ</translation>
<translation id="6973656660372572881">Указаны как фиксированные прокси-серверы, так и URL PAC-скриптов.</translation>
+<translation id="6973932557599545801">Извините, я ничем не могу помочь. Продолжите самостоятельно.</translation>
<translation id="6979158407327259162">Google Диск</translation>
<translation id="6979440798594660689">Без звука (по умолчанию)</translation>
<translation id="6984479912851154518">Вы выйдете из режима инкогнито, чтобы произвести оплату во внешнем приложении. Продолжить?</translation>
<translation id="6989763994942163495">Показать дополнительные настройки</translation>
+<translation id="6993898126790112050">6x9 (конверт)</translation>
<translation id="6996312675313362352">Всегда переводить <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Списание может быть разовым или повторяющимся без каких-либо уведомлений.</translation>
@@ -947,28 +1069,33 @@
<translation id="7108338896283013870">Скрыть</translation>
<translation id="7108819624672055576">Разрешено расширением</translation>
<translation id="7111012039238467737">(действительный)</translation>
+<translation id="7118618213916969306">Поиск по адресу <ph name="SHORT_URL" /> из буфера обмена</translation>
<translation id="7119414471315195487">Закройте другие вкладки и программы.</translation>
<translation id="7129409597930077180">Невозможно отправить заказ по этому адресу. Выберите другой вариант.</translation>
<translation id="7135130955892390533">Показать статус</translation>
<translation id="7138472120740807366">Способ доставки</translation>
<translation id="7139724024395191329">Эмират</translation>
+<translation id="7152423860607593928">Number-14 (конверт)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Бледно-лиловый</translation>
-<translation id="7158980942472052083">Недопустимый URL. Используйте стандартную схему.</translation>
<translation id="717330890047184534">Идентификатор GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Ко всем запросам, отправляемым на сервер <ph name="ORIGIN" />, применяются правила безопасности. Однако вместо того, чтобы передать правила, сервер перенаправил браузер по другому адресу, поэтому браузер не может выполнить ваш запрос для сайта <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Сохранять и автоматически подставлять платежные данные</translation>
<translation id="7180611975245234373">Обновить</translation>
<translation id="7182878459783632708">Правила не заданы</translation>
<translation id="7186367841673660872">Эта страница была переведена автоматически<ph name="ORIGINAL_LANGUAGE" />&gt;<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Освободится <ph name="SIZE" /> пространства. После этого некоторые веб-страницы могут загружаться дольше обычного.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Администратор может отслеживать:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Сайт <ph name="HOST_NAME" /> не соответствует стандартам безопасности.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Подробнее <ph name="END_LINK" /> об этой неполадке.</translation>
<translation id="7219179957768738017">В этом подключении используется протокол <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Подождите…</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Осторожно, вредоносное ПО!</translation>
+<translation id="724766306220616965">Предупреждения, конфликт</translation>
<translation id="724975217298816891">Введите срок действия и CVC-код карты <ph name="CREDIT_CARD" />. После этого ее данные будут переданы сайту.</translation>
<translation id="7251437084390964440">Некоторые элементы сетевой конфигурации невозможно импортировать, поскольку она не соответствует стандарту ONC.
Подробнее:
@@ -981,11 +1108,14 @@
<translation id="7300012071106347854">Синий (кобальт)</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" />: отчет о сбое сохранен, но ещё не загружен (пользователь запросил загрузку)</translation>
+<translation id="7313965965371928911">Предупреждения <ph name="BEGIN_LINK" />Безопасного просмотра<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Устранение ошибок при подключении к Интернету</translation>
<translation id="7334320624316649418">&amp;Повторить изменение порядка</translation>
<translation id="733923710415886693">Сертификат сервера не проходил проверку.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Командная строка</translation>
-<translation id="7365061714576910172">Экспортировать для Linux</translation>
<translation id="7372973238305370288">результат поиска</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Нет</translation>
@@ -993,6 +1123,7 @@
<translation id="7381288752349550461">Управляемый сеанс (переопределено)</translation>
<translation id="7390545607259442187">Подтвердите карту</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Это устройство <ph name="DEVICE_NAME" /> управляется администратором</translation>
<translation id="7407424307057130981">&lt;p&gt;Эта проблема возникает, когда на компьютере с Windows установлено ПО Superfish.&lt;/p&gt;
&lt;p&gt;Чтобы временно отключить ПО и установить соединение с Интернетом, следуйте инструкциям ниже. Вам потребуются права администратора.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1134,7 @@
&lt;li&gt;Нажмите &lt;strong&gt;Применить&lt;/strong&gt;, а затем – &lt;strong&gt;ОК&lt;/strong&gt;.
&lt;li&gt;О том, как удалить ПО с компьютера, читайте в &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Справочном центре Chrome&lt;/a&gt;.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Управление <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Управление паролями</translation>
<translation id="7419106976560586862">Путь к профилю</translation>
<translation id="7437289804838430631">Добавить контактные данные</translation>
@@ -1012,22 +1143,24 @@
<translation id="7442725080345379071">Светло-оранжевый</translation>
<translation id="7444046173054089907">Сайт заблокирован</translation>
<translation id="7445762425076701745">Идентификация сервера, к которому вы подключились, не может быть полностью подтверждена. Вы подключились к серверу, используя название, которое действительно только в вашей сети; владелец этого сервера не может быть проверен или подтвержден внешним центром сертификации. Так как некоторые центры сертификации могут выдавать сертификаты для подобных названий, отсутствуют гарантии в том, что это действительно нужный вам сайт, а не сайт злоумышленника.</translation>
-<translation id="7449109375006139765">Отправлять системные журналы на сервер для проверки.</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Узнайте больше<ph name="END_LINK" /> об этой проблеме.</translation>
<translation id="7455133967321480974">Использовать глобальный параметр по умолчанию (блокировать)</translation>
<translation id="7460618730930299168">Настройки этого сеанса отличаются от тех, которые выбрали вы. Продолжить?</translation>
<translation id="7473891865547856676">Пропустить</translation>
-<translation id="7475525192983021547">Отправлять данные о длительности работы пользователей с устройством.</translation>
<translation id="7481312909269577407">Вперед</translation>
<translation id="7485870689360869515">Данные не найдены.</translation>
+<translation id="7498234416455752244">Продолжить редактирование</translation>
<translation id="7508255263130623398">Возвращенный идентификатор устройства пуст или не соответствует имеющемуся</translation>
<translation id="7508870219247277067">Зеленый (авокадо)</translation>
<translation id="7511955381719512146">Возможно, вам нужно перейти на страницу <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> сети Wi-Fi.</translation>
<translation id="7514365320538308">Скачать</translation>
<translation id="7518003948725431193">Не найдена страница для веб-адреса <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (конверт)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Подключение к сайту не защищено</translation>
+<translation id="7535087603100972091">Значение</translation>
<translation id="7537536606612762813">Обязательная</translation>
+<translation id="7538364083937897561">A2 (конверт)</translation>
<translation id="7542403920425041731">После этого данные вашей карты будут переданы сайту.</translation>
<translation id="7542995811387359312">Автозаполнение отключено – незащищенное подключение.</translation>
<translation id="7543525346216957623">Обратитесь за помощью к родителю</translation>
@@ -1036,8 +1169,8 @@
<translation id="7552846755917812628">Попробуйте сделать следующее:</translation>
<translation id="7554791636758816595">Новая вкладка</translation>
<translation id="7564049878696755256">Кто-то посторонний мог получить доступ к вашим личным данным или аккаунту в домене <ph name="ORG_NAME" />. Рекомендуем немедленно сменить пароль.</translation>
-<translation id="7566125604157659769">Скопированный текст</translation>
<translation id="7567204685887185387">Не удалось подтвердить, что это сервер <ph name="DOMAIN" />. Его сертификат безопасности мог быть выдан обманным путем. Возможно, сервер настроен неправильно или кто-то пытается перехватить ваши данные.</translation>
+<translation id="7568105740864181217">Этим браузером управляет компания, учебное заведение или другая организация. Администратор может удаленно менять настройки браузера и выполнять другие действия вне браузера Chrome на этом устройстве. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Удалить кредитную карту из Chrome?</translation>
<translation id="7569983096843329377">Черный</translation>
<translation id="7578104083680115302">Быстро оплачивайте покупки на сайтах и в приложениях с помощью карт, сохраненных в Google Payments. Настройка будет действовать на всех ваших устройствах.</translation>
@@ -1048,6 +1181,7 @@
<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="7633909222644580952">Данные о производительности и отчеты о сбоях</translation>
<translation id="7637571805876720304">Удалить кредитную карту из Chromium?</translation>
<translation id="7639968568612851608">Темно-серый</translation>
<translation id="765676359832457558">Скрыть дополнительные настройки</translation>
@@ -1057,9 +1191,11 @@
<translation id="7667346355482952095">Возвращенный токен пуст или не соответствует имеющемуся</translation>
<translation id="7668654391829183341">Неизвестное устройство</translation>
<translation id="7669271284792375604">Посещение этого сайта может привести к установке вредоносного ПО, которое будет мешать работе браузера (например, меняя стартовую страницу или показывая дополнительную рекламу на сайтах).</translation>
+<translation id="7676643023259824263">Поиск по тексту "<ph name="TEXT" />" из буфера обмена</translation>
<translation id="7681101578153515023">Изменить поисковую систему</translation>
<translation id="7682287625158474539">Адрес доставки</translation>
<translation id="7687186412095877299">Сохранять и автоматически заполнять платежные данные</translation>
+<translation id="7697066736081121494">Prc8 (конверт)</translation>
<translation id="769721561045429135">Сейчас ваши карты можно использовать только на этом устройстве. Чтобы посмотреть информацию о них, нажмите "Продолжить".</translation>
<translation id="7699293099605015246">Статьи пока недоступны</translation>
<translation id="7701040980221191251">Нет</translation>
@@ -1071,11 +1207,13 @@
<translation id="774634243536837715">Опасный контент заблокирован</translation>
<translation id="7752995774971033316">Не управляется</translation>
<translation id="7755287808199759310">Для разблокировки обратитесь к родителю.</translation>
+<translation id="7757555340166475417">Dai Pa Kai</translation>
<translation id="7758069387465995638">Возможно, подключение заблокировано брандмауэром или антивирусным ПО.</translation>
<translation id="7759163816903619567">Показывать домен:</translation>
<translation id="7761701407923456692">Сертификат сервера не соответствует URL.</translation>
<translation id="7763386264682878361">Синтаксический анализатор манифестов</translation>
<translation id="7764225426217299476">Добавить адрес</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Добавить</translation>
<translation id="7793809570500803535">Веб-страница по адресу <ph name="SITE" />, возможно, временно недоступна или перемещена на новый адрес.</translation>
@@ -1087,8 +1225,8 @@
<translation id="7812922009395017822">Мир</translation>
<translation id="7813600968533626083">Удалить подсказку из Chrome?</translation>
<translation id="7815407501681723534"><ph name="SEARCH_RESULTS" /> по запросу "<ph name="SEARCH_STRING" />" (<ph name="NUMBER_OF_RESULTS" />)</translation>
-<translation id="7818867226424560206">Управление правилами</translation>
<translation id="782886543891417279">Возможно, вам нужно перейти на страницу входа сети Wi-Fi (<ph name="WIFI_NAME" />).</translation>
+<translation id="7836231406687464395">Postfix (конверт)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Нет}=1{1 приложение (<ph name="EXAMPLE_APP_1" />)}=2{2 приложения (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# приложение (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}few{# приложения (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}many{# приложений (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# приложения (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Тем не менее ваши действия будут видны системному администратору и интернет-провайдеру, а также доступны веб-сайтам, которые вы посещаете.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1097,7 +1235,7 @@
<translation id="7878562273885520351">Злоумышленники могли узнать ваш пароль</translation>
<translation id="7882421473871500483">Коричневый</translation>
<translation id="7887683347370398519">Проверьте CVC-код и повторите попытку</translation>
-<translation id="7893255318348328562">Название сеанса</translation>
+<translation id="7904208859782148177">C3 (конверт)</translation>
<translation id="79338296614623784">Укажите действительный номер телефона.</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Действует до <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1245,25 @@
<translation id="7951415247503192394">(32 бит)</translation>
<translation id="7956713633345437162">Моб. закладки</translation>
<translation id="7961015016161918242">Нет</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Не указано</translation>
<translation id="800218591365569300">Закройте другие вкладки и программы, чтобы освободить память.</translation>
+<translation id="8004582292198964060">Браузер</translation>
<translation id="8009225694047762179">Управление паролями</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Данные этой карты и ее платежный адрес будут сохранены. Вы сможете пользоваться ею после входа в аккаунт <ph name="USER_EMAIL" />.}one{Данные этих карт и их платежные адреса будут сохранены. Вы сможете пользоваться ими после входа в аккаунт <ph name="USER_EMAIL" />.}few{Данные этих карт и их платежные адреса будут сохранены. Вы сможете пользоваться ими после входа в аккаунт <ph name="USER_EMAIL" />.}many{Данные этих карт и их платежные адреса будут сохранены. Вы сможете пользоваться ими после входа в аккаунт <ph name="USER_EMAIL" />.}other{Данные этих карт и их платежные адреса будут сохранены. Вы сможете пользоваться ими после входа в аккаунт <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">Не удалось связаться с вашими родителями. Повторите попытку.</translation>
<translation id="8025119109950072390">Посещение этого сайта может привести к установке вредоносного ПО или хищению личной информации (например, паролей, телефонных номеров и данных банковских карт).</translation>
<translation id="8034522405403831421">Язык этой страницы: <ph name="SOURCE_LANGUAGE" />. Перевести ее на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Ручка</translation>
+<translation id="8037117624646282037">Кто недавно работал с устройством.</translation>
<translation id="8037357227543935929">Спрашивать (по умолчанию)</translation>
<translation id="803771048473350947">Файл</translation>
<translation id="8041089156583427627">Отправить отзыв</translation>
<translation id="8041940743680923270">Использовать глобальный параметр по умолчанию (спрашивать)</translation>
<translation id="8042918947222776840">Выбрать способ получения</translation>
<translation id="8057711352706143257">Программа "<ph name="SOFTWARE_NAME" />" настроена неправильно. Чтобы устранить проблему, удалите программу "<ph name="SOFTWARE_NAME" />". <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Для вашего устройства установлены следующие настройки:</translation>
+<translation id="8066955247577885446">Произошла ошибка.</translation>
+<translation id="8074253406171541171">10x13 (конверт)</translation>
<translation id="8078141288243656252">Недоступно, когда документ повернут</translation>
<translation id="8079031581361219619">Перезагрузить сайт?</translation>
<translation id="8088680233425245692">Не удалось показать статью</translation>
@@ -1130,11 +1272,12 @@
<translation id="8091372947890762290">Активация управления устройствами не завершена</translation>
<translation id="8092774999298748321">Насыщенный фиолетовый</translation>
<translation id="8094917007353911263">Возможно, вам нужно перейти на страницу <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> используемой сети.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Недействительные карты удалены.</translation>
<translation id="8103161714697287722">Способ оплаты</translation>
<translation id="8118489163946903409">Способ оплаты</translation>
+<translation id="8123836779274890062">Устройство <ph name="DEVICE_TYPE" /> управляется <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Программа "<ph name="SOFTWARE_NAME" />" была установлена неправильно. Обратитесь за помощью к системному администратору.</translation>
-<translation id="8130693978878176684">Больше я ничем не могу вам помочь. Продолжите ввод самостоятельно.</translation>
<translation id="8131740175452115882">Подтвердить</translation>
<translation id="8149426793427495338">Ваш компьютер перешел в спящий режим.</translation>
<translation id="8150722005171944719">Файл по адресу <ph name="URL" /> недоступен. Возможно, он был удален или перемещен либо права доступа к нему ограничены.</translation>
@@ -1144,8 +1287,11 @@
<translation id="8197543752516192074">Перевести страницу</translation>
<translation id="8201077131113104583">Недействительный URL для обновления расширения с идентификатором <ph name="EXTENSION_ID" />.</translation>
<translation id="8202097416529803614">Информация о заказе</translation>
+<translation id="8202370299023114387">Конфликт</translation>
+<translation id="8206978196348664717">Prc4 (конверт)</translation>
<translation id="8211406090763984747">Безопасное подключение</translation>
<translation id="8218327578424803826">Назначенное местоположение:</translation>
+<translation id="8220146938470311105">C7/C6 (конверт)</translation>
<translation id="8225771182978767009">Тот, кто настраивал компьютер, заблокировал этот сайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" /> и <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">Открыть страницу в новой вкладке инкогнито</translation>
@@ -1157,14 +1303,16 @@
<translation id="825929999321470778">Показать все сохраненные пароли</translation>
<translation id="8261506727792406068">Удалить</translation>
<translation id="8267698848189296333">Вход в аккаунт <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">У администратора <ph name="ENROLLMENT_DOMAIN" /> есть право удаленно менять настройки этого браузера и выполнять другие действия вне браузера Chrome на этом устройстве. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Вход</translation>
<translation id="8288807391153049143">Показать сертификат</translation>
<translation id="8289355894181816810">Уточните информацию у администратора сети.</translation>
<translation id="8293206222192510085">Добавление закладки</translation>
<translation id="8294431847097064396">Источник</translation>
<translation id="8298115750975731693">Возможно, вам нужно перейти на страницу <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> сети Wi-Fi (<ph name="WIFI_NAME" />).</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Перевод не завершен из-за проблем с сетевым подключением.</translation>
-<translation id="8311129316111205805">Загрузить сеанс</translation>
<translation id="8332188693563227489">Доступ к <ph name="HOST_NAME" /> запрещен</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">Если вы готовы подвергнуть риску ваши личные данные, вы можете <ph name="BEGIN_LINK" />перейти на зараженный сайт<ph name="END_LINK" />, не дожидаясь удаления вредоносного ПО.</translation>
@@ -1182,7 +1330,6 @@
<translation id="8416694386774425977">Импорт невозможен: недопустимая конфигурация сети.
Подробнее:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Устройство под управлением домена <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Изменить</translation>
<translation id="8428213095426709021">Настройки</translation>
@@ -1209,9 +1356,11 @@
<translation id="860043288473659153">Имя владельца карты</translation>
<translation id="861775596732816396">Размер: 4</translation>
<translation id="8620436878122366504">Ещё не одобрено родителями</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Сохранить карту на этом устройстве</translation>
<translation id="8663226718884576429">Информация о заказе, <ph name="TOTAL_LABEL" />, дополнительные сведения</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, ответ, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Соединение с <ph name="DOMAIN" /> не зашифровано.</translation>
<translation id="8718314106902482036">Не удалось обработать платеж</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, подсказка</translation>
@@ -1225,6 +1374,7 @@
<translation id="8761567432415473239">Система Google по проверке безопасности сайтов недавно обнаружила на <ph name="SITE" /> <ph name="BEGIN_LINK" />вредоносное ПО<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB-устройство</translation>
<translation id="8768895707659403558">Чтобы использовать карты на всех своих устройствах, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Повторить удаление</translation>
<translation id="8792621596287649091">Кто-то посторонний мог получить доступ к вашим личным данным или аккаунту в домене <ph name="ORG_NAME" />. Рекомендуем немедленно сменить пароль.</translation>
<translation id="8800988563907321413">Здесь появятся рекомендации.</translation>
@@ -1235,10 +1385,12 @@
<translation id="885730110891505394">Доступ Google</translation>
<translation id="8858065207712248076">Chrome рекомендует сбросить пароль, используемый в подразделении <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, если вы указывали его на других сайтах.</translation>
<translation id="8866481888320382733">Не удалось выполнить анализ настроек политики</translation>
+<translation id="886872106311861689">В3</translation>
<translation id="8870413625673593573">Недавно закрытые</translation>
<translation id="8874824191258364635">Введите действительный номер карты.</translation>
<translation id="8891727572606052622">Недопустимый режим работы прокси-сервера.</translation>
<translation id="8903921497873541725">Увеличить</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Сохранить эту карту в аккаунте Google?</translation>
<translation id="8932102934695377596">Часы отстают</translation>
<translation id="893332455753468063">Добавьте имя</translation>
@@ -1246,13 +1398,13 @@
<translation id="894185898663964645">Ваш администратор настроил корневые сертификаты, позволяющие ему просматривать контент посещенных вами сайтов.</translation>
<translation id="8943282376843390568">Лаймовый</translation>
<translation id="8957210676456822347">Авторизация через адаптивный портал</translation>
+<translation id="8966619695390250636">Вы не ошиблись?</translation>
<translation id="8968766641738584599">Сохранить карту</translation>
<translation id="8971063699422889582">Сертификат сервера устарел.</translation>
<translation id="8975012916872825179">В том числе телефонные номера, адреса электронной почты и адреса доставки.</translation>
<translation id="8978053250194585037">Функция "Google Безопасный просмотр" недавно <ph name="BEGIN_LINK" />обнаружила попытку фишинга<ph name="END_LINK" /> на сайте <ph name="SITE" />. Будьте внимательны! Мошенники часто создают веб-страницы, похожие на знакомые вам сайты.</translation>
<translation id="8983003182662520383">Способы оплаты и адреса из Google Pay</translation>
<translation id="8987927404178983737">Месяц</translation>
-<translation id="8988408250700415532">Произошла ошибка. Завершите оформление заказа на сайте.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сайт содержит нежелательное ПО</translation>
<translation id="8997023839087525404">Предоставленный сервером сертификат не проходил проверку безопасности. Она необходима в некоторых случаях, чтобы доказать, что сертификат надежен и защищает от злоумышленников.</translation>
@@ -1262,6 +1414,7 @@
<translation id="9011424611726486705">Открыть настройки сайта</translation>
<translation id="9020200922353704812">Необходимо указать платежный адрес карты</translation>
<translation id="9020542370529661692">Эта страница переведена на <ph name="TARGET_LANGUAGE" />.</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(недействительный)</translation>
<translation id="9035022520814077154">Ошибка безопасности</translation>
<translation id="9038649477754266430">Использовать подсказки для ускорения загрузки страниц</translation>
@@ -1273,11 +1426,11 @@
<translation id="9065745800631924235">Поисковый запрос "<ph name="TEXT" />" из истории</translation>
<translation id="9069693763241529744">Заблокировано расширением</translation>
<translation id="9076283476770535406">Может содержать контент для взрослых</translation>
+<translation id="9076630408993835509">Компания или организация не управляет этим браузером. Действиями на этом устройстве можно управлять вне браузера Chrome. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Информации недостаточно</translation>
<translation id="9080712759204168376">Информация о заказе</translation>
<translation id="9103872766612412690">На сайте <ph name="SITE" /> для защиты ваших данных обычно используется шифрование. Однако учетные данные, которые мы получили от сайта <ph name="SITE" /> сейчас, отличаются от тех, которые он отправляет обычно. Вероятно, вредоносный сайт пытается выдать себя за <ph name="SITE" />, либо страница подключения к сети Wi-Fi прервала соединение. Ваша информация по-прежнему в безопасности, так как браузер Chromium разорвал соединение до того, как произошел обмен данными.</translation>
<translation id="9106062320799175032">Добавьте платежный адрес</translation>
-<translation id="9110718169272311511">Google Ассистент находится в нижней части экрана Chrome</translation>
<translation id="9114524666733003316">Подтверждение карты...</translation>
<translation id="9128870381267983090">Подключитесь к сети</translation>
<translation id="9137013805542155359">Показать оригинал</translation>
@@ -1286,6 +1439,7 @@
<translation id="9148507642005240123">&amp;Отменить изменения</translation>
<translation id="9154194610265714752">Обновлено</translation>
<translation id="9157595877708044936">Настройка...</translation>
+<translation id="9158625974267017556">C6 (конверт)</translation>
<translation id="9168814207360376865">Разрешить сайтам проверять наличие сохраненных способов оплаты</translation>
<translation id="9169664750068251925">Всегда блокировать на этом сайте</translation>
<translation id="9170848237812810038">&amp;Отменить</translation>
@@ -1300,10 +1454,12 @@
<translation id="9219103736887031265">Картинки</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОЧИСТИТЬ ФОРМУ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Вы можете потерять доступ к аккаунту Google. Рекомендуем немедленно сменить пароль. После этого потребуется снова войти в аккаунт.</translation>
<translation id="939736085109172342">Новая папка</translation>
<translation id="945855313015696284">Проверьте данные и удалите недействительные карты.</translation>
<translation id="951104842009476243">Дебетовые карты и карты предоплаты, которые принимаются к оплате</translation>
+<translation id="958202389743790697">Заблокировано в соответствии с политикой безопасности сайта <ph name="ORIGIN" /></translation>
<translation id="962484866189421427">Переход на эту страницу может привести к установке вредоносных приложений, маскирующихся под безопасные программы или собирающих данные, по которым вас можно отследить. <ph name="BEGIN_LINK" />Все равно продолжить<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Официальная сборка</translation>
<translation id="973773823069644502">Добавить адрес доставки</translation>
@@ -1312,6 +1468,7 @@
<translation id="984275831282074731">Способы оплаты</translation>
<translation id="985199708454569384">&lt;p&gt;Эта ошибка возникает, если дата и время на компьютере или мобильном устройстве установлены неправильно.&lt;/p&gt;
&lt;p&gt;Чтобы устранить проблему, откройте настройки системных часов и установите правильные параметры.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Сборка для разработчиков</translation>
<translation id="989988560359834682">Изменение адреса</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_sk.xtb b/chromium/components/strings/components_strings_sk.xtb
index 3dc03201fa3..e4405114e82 100644
--- a/chromium/components/strings/components_strings_sk.xtb
+++ b/chromium/components/strings/components_strings_sk.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sk">
-<translation id="1005145902654145231">Reláciu sa nepodarilo premenovať.</translation>
<translation id="1008557486741366299">Teraz nie</translation>
<translation id="1010200102790553230">Načítať stránku neskôr</translation>
<translation id="1015730422737071372">Poskytnite ďalšie podrobnosti</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">neznámy názov</translation>
<translation id="1050038467049342496">Zavrite ostatné aplikácie</translation>
<translation id="1055184225775184556">&amp;Vrátiť späť pridanie</translation>
+<translation id="1056898198331236512">Upozornenie</translation>
<translation id="1058479211578257048">Ukladajú sa karty…</translation>
<translation id="10614374240317010">Nikdy neukladať</translation>
+<translation id="1062160989074299343">Prc10 (obálka)</translation>
<translation id="106701514854093668">Záložky v počítači</translation>
<translation id="1074497978438210769">Nezabezpečené</translation>
<translation id="1080116354587839789">Prispôsobiť šírke</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Pridanie mena na karte</translation>
<translation id="1089439967362294234">Zmeniť heslo</translation>
<translation id="109743633954054152">Spravujte heslá v nastaveniach Chromu</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Kým weby aktualizujú svoje zabezpečenie, môžu sa často zobrazovať upozornenia. Čoskoro by sa to malo zlepšiť.</translation>
<translation id="1126551341858583091">Veľkosť súboru v lokálnom úložisku je <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Vyrovnávacia pamäť pravidla je v poriadku</translation>
+<translation id="1131264053432022307">Skopírovaný obrázok</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Premenovať</translation>
<translation id="1175364870820465910">&amp;Tlačiť...</translation>
<translation id="1181037720776840403">Odstrániť</translation>
<translation id="1197088940767939838">Oranžová</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Názov vášho zariadenia</translation>
<translation id="124116460088058876">Ďalšie jazyky</translation>
<translation id="1250759482327835220">Ak chcete nabudúce zaplatiť rýchlejšie, uložte si kartu, meno a fakturačnú adresu do účtu Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synchronizované)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Variácie v príkazovom riadku</translation>
<translation id="129553762522093515">Nedávno zatvorené</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Skúste vymazať súbory cookie<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Vybraná relácia neexistuje.</translation>
+<translation id="1320233736580025032">Prc1 (obálka)</translation>
+<translation id="132301787627749051">Hľadať obrázok v schránke</translation>
<translation id="1323433172918577554">Zobraziť viac</translation>
<translation id="132390688737681464">Ukladať a dopĺňať adresy</translation>
<translation id="1333989956347591814">Vašu aktivitu <ph name="BEGIN_EMPHASIS" />stále môžu vidieť<ph name="END_EMPHASIS" />:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">Adresa vyzdvihnutia</translation>
<translation id="1348198688976932919">Web s nebezpečnými aplikáciami</translation>
<translation id="1348779747280417563">Potvrdenie mena</translation>
+<translation id="1357195169723583938">Kto nedávno použil toto zariadenie a kedy</translation>
+<translation id="1364822246244961190">Toto pravidlo je blokované. Jeho hodnota sa bude ignorovať.</translation>
<translation id="1374468813861204354">návrhy</translation>
+<translation id="1374692235857187091">Index-4x6 (pohľadnica)</translation>
<translation id="1375198122581997741">Informácie o verzii</translation>
<translation id="1376836354785490390">Zobraziť menej</translation>
<translation id="1377321085342047638">Číslo karty</translation>
<translation id="138218114945450791">Svetlomodrá</translation>
+<translation id="1382194467192730611">Zariadenie USB je povolené správcom</translation>
<translation id="139305205187523129">Web <ph name="HOST_NAME" /> neodoslal žiadne údaje.</translation>
+<translation id="140316286225361634">Web <ph name="ORIGIN" /> požiadal, aby sa na všetky jeho žiadosti vzťahovalo pravidlo zabezpečenia, podľa ktorého je tento web momentálne nebezpečný.</translation>
<translation id="1405567553485452995">Svetlozelená</translation>
<translation id="1407135791313364759">Otvoriť všetko</translation>
<translation id="1413809658975081374">Chyba v ochrane osobných údajov</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">Áno</translation>
<translation id="1430915738399379752">Tlačiť</translation>
<translation id="1455413310270022028">Guma</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Zobraziť viac</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Zvoliť dodaciu adresu</translation>
+<translation id="1492194039220927094">Odosielanie pravidiel:</translation>
<translation id="1501859676467574491">Zobraziť karty z vášho účtu Google</translation>
-<translation id="1506687042165942984">Zobrazí sa uložená (t. j. neaktuálna) kópia tejto stránky.</translation>
<translation id="1507202001669085618">&lt;p&gt;Táto chyba sa zobrazí, keď používate portál Wi-Fi, ktorý podmieňuje prístup k internetu prihlásením.&lt;/p&gt;
&lt;p&gt;Ak ju chcete odstrániť, kliknite na možnosť &lt;strong&gt;Pripojiť&lt;/strong&gt; na stránke, ktorú sa pokúšate otvoriť.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Vyžaduje sa telefónne číslo</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">Dátum zostavenia</translation>
<translation id="1521655867290435174">Tabuľky Google</translation>
<translation id="1527263332363067270">Čaká sa na pripojenie...</translation>
+<translation id="1529521330346880926">10x15 (obálka)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Táto stránka hovorí</translation>
<translation id="153384715582417236">To je zatiaľ všetko</translation>
<translation id="154408704832528245">Zvoliť adresu doručenia</translation>
<translation id="1549470594296187301">Ak chcete použiť túto funkciu, musíte povoliť JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Zadajte dátum vypršania platnosti</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Pri zobrazovaní webovej stránky sa niečo pokazilo.</translation>
<translation id="1592005682883173041">Prístup k miestnym údajom</translation>
<translation id="1594030484168838125">Zvoliť</translation>
<translation id="161042844686301425">Azúrová</translation>
-<translation id="1618822247301510817">Skopírovaný obrázok</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Zakázať tejto stránke otvárať ďalšie dialógové okná</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Ukončiť reláciu</translation>
<translation id="1639239467298939599">Prebieha načítavanie</translation>
<translation id="1640180200866533862">Pravidlá pre používateľa</translation>
@@ -133,8 +148,10 @@
<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="168841957122794586">Certifikát servera obsahuje slabý kryptografický kľúč.</translation>
<translation id="1697532407822776718">Všetko je nastavené!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument nie je možné anotovať, pretože je príliš veľký</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>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">Skúste kontaktovať správcu systému.</translation>
<translation id="1740951997222943430">Zadajte platný mesiac vypršania platnosti</translation>
<translation id="1743520634839655729">Ak chcete nabudúce zaplatiť rýchlejšie, uložte si kartu, meno a fakturačnú adresu do účtu Google a tohto zariadenia.</translation>
+<translation id="1745880797583122200">Váš prehliadač je spravovaný</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>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">Aktualizujte prístupovú frázu na synchronizáciu.</translation>
<translation id="1787142507584202372">Tu sa zobrazia otvorené karty</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Meno majiteľa karty</translation>
<translation id="1821930232296380041">Neplatná žiadosť alebo parametre žiadosti</translation>
+<translation id="1822540298136254167">Weby, ktoré navštívite, a čas, ktorý na nich strávite</translation>
<translation id="1826516787628120939">Kontroluje sa</translation>
<translation id="1834321415901700177">Tento web obsahuje škodlivé programy</translation>
<translation id="1839551713262164453">Overenie hodnôt pravidiel zlyhalo a obsahuje chyby</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">Vymažte údaje histórie prehliadania Chromu</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{a 1 ďalšia}few{a # ďalšie}many{a # ďalšej}other{a # ďalších}}</translation>
<translation id="2003709556000175978">Obnovte heslo</translation>
+<translation id="20053308747750172">Server <ph name="ORIGIN" />, na ktorý prechádzate, požiadal, aby sa na všetky naň odoslané žiadosti vzťahovalo pravidlo zabezpečenia. Poskytol však neplatné pravidlo, ktoré bráni prehliadaču splniť vašu žiadosť týkajúcu sa webu <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proxy je nastavené na automatickú konfiguráciu.</translation>
<translation id="2030481566774242610">Mysleli ste stránku <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Skontrolovať proxy server a bránu firewall<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">Department</translation>
<translation id="2102134110707549001">Navrhnúť silné heslo…</translation>
<translation id="2108755909498034140">Reštartujte počítač</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Karta</translation>
<translation id="2114841414352855701">Ignorované, pretože bolo prepísané pravidlom <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobilné záložky</translation>
@@ -206,6 +228,7 @@
<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="2169984857010174799">Kaku2 (obálka)</translation>
<translation id="2181821976797666341">Pravidlá</translation>
<translation id="2183608646556468874">Telefónne číslo</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adresa}few{# adresy}many{# adresy}other{# adries}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">Telefónne číslo</translation>
<translation id="2283340219607151381">Ukladať a dopĺňať adresy</translation>
<translation id="2292556288342944218">Váš prístup k internetu je blokovaný</translation>
+<translation id="2294558542833290837">Pôvodne otvorený odkaz je nezvyčajný</translation>
+<translation id="2297722699537546652">B5 (obálka)</translation>
+<translation id="2310021320168182093">Chou2 (obálka)</translation>
<translation id="2316887270356262533">Uvoľní menej ako 1 MB. Niektoré weby sa môžu pri ďalšej návšteve načítať pomalšie.</translation>
<translation id="2317259163369394535">Doména <ph name="DOMAIN" /> vyžaduje používateľské meno a heslo.</translation>
<translation id="2317583587496011522">Debetné karty sú akceptované.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, platí do <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Nastavenie ovládané správcom</translation>
+<translation id="2346319942568447007">Skopírovaný obrázok</translation>
<translation id="2349790679044093737">Relácia VR je aktívna</translation>
<translation id="2354001756790975382">Ostatné</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>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">Správa o zlyhaní zaznamenaná v čase <ph name="CRASH_TIME" /> nebola nahraná</translation>
<translation id="2367567093518048410">Úroveň</translation>
<translation id="2378238891085281592">Ste v súkromnom režime</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Vládny právny dokument</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="2418081434543109369">Server <ph name="ORIGIN" />, na ktorý prechádzate, požiadal, aby sa na všetky naň odoslané žiadosti vzťahovalo pravidlo zabezpečenia. Neposkytol však pravidlo, ktoré bráni prehliadaču splniť vašu žiadosť týkajúcu sa webu <ph name="SITE" />.</translation>
<translation id="244665789865330679">Zariadenie spravuje doména <ph name="ENROLLMENT_DOMAIN" />. Znamená to, že správca môže vzdialene nakonfigurovať vaše zariadenie aj účet.</translation>
<translation id="2463193859425327265">Zmeniť domovskú stránku</translation>
<translation id="2463739503403862330">Vyplniť</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Zvoliť spôsob doručenia</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Spustiť nástroj Diagnostika siete<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Preložiť túto stránku</translation>
<translation id="2479410451996844060">Neplatná webová adresa vyhľadávania.</translation>
<translation id="2482878487686419369">Upozornenia</translation>
<translation id="248348093745724435">Pravidlá počítača</translation>
+<translation id="2485387744899240041">Používateľské mená pre vaše zariadenie a prehliadač</translation>
<translation id="2491120439723279231">Certifikát servera obsahuje chyby.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Naskenovať novú kartu</translation>
<translation id="2501278716633472235">Prejsť späť</translation>
<translation id="2503184589641749290">Akceptované debetné a predplatené karty</translation>
<translation id="2515629240566999685">Skontrolovať signál vo vašej oblasti</translation>
-<translation id="2516852381693169964">Hľadať obrázok v službe <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Uložené iba na tomto zariadení</translation>
<translation id="2524461107774643265">Pridanie ďalších informácií</translation>
<translation id="2536110899380797252">Pridať adresu</translation>
@@ -273,6 +305,7 @@
<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="2618023639789766142">C10 (obálka)</translation>
<translation id="2625385379895617796">Vaše hodiny idú dopredu</translation>
<translation id="2634124572758952069">Adresu IP servera <ph name="HOST_NAME" /> sa nepodarilo nájsť.</translation>
<translation id="2639739919103226564">Stav:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">Zavrite ostatné karty alebo aplikácie</translation>
<translation id="267371737713284912">vráťte späť stlačením klávesa <ph name="MODIFIER_KEY_DESCRIPTION" /></translation>
<translation id="2674170444375937751">Naozaj chcete odstrániť tieto stránky zo svojej histórie?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Odísť</translation>
+<translation id="2684561033061424857">11 x 12</translation>
<translation id="2699302886720511147">Akceptované karty</translation>
<translation id="2702801445560668637">Čitateľský zoznam</translation>
<translation id="2704283930420550640">Hodnota nezodpovedá formátu.</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">Odstrániť vybraté položky</translation>
<translation id="277133753123645258">Spôsob dodania</translation>
<translation id="277499241957683684">Chýbajúci záznam zariadenia</translation>
-<translation id="2781030394888168909">Exportovať pre MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Spojenie bolo resetované.</translation>
<translation id="2788784517760473862">Akceptované kreditné karty</translation>
@@ -311,8 +345,10 @@
<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="2847118875340931228">Otvoriť okno inkognito</translation>
+<translation id="2850739647070081192">Invite (obálka)</translation>
<translation id="2851634818064021665">Na návštevu tohto webu potrebujete povolenie</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Uložiť kartu?</translation>
<translation id="2903493209154104877">Adresy</translation>
<translation id="290376772003165898">Stránka nie je v jazyku <ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">Spôsob doručenia</translation>
<translation id="2928905813689894207">Fakturačná adresa</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (obálka)</translation>
<translation id="3024663005179499861">Chybný typ pravidla</translation>
<translation id="3037605927509011580">Aj, chyba!</translation>
<translation id="3041612393474885105">Informácie o certifikáte</translation>
+<translation id="3060227939791841287">C9 (obálka)</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="3095940652251934233">Výpis</translation>
<translation id="3096100844101284527">Pridať adresu vyzdvihnutia</translation>
<translation id="3105172416063519923">Identifikátor obsahu:</translation>
<translation id="3109728660330352905">Nemáte povolenie na zobrazenie tejto stránky.</translation>
@@ -361,20 +401,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> na serveri <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Zrušiť platbu</translation>
<translation id="3207960819495026254">Pridané medzi záložky</translation>
-<translation id="3209375525920864198">Zadajte platný názov relácie.</translation>
+<translation id="321912867715453276">Upozornenie: V rámci tohto pravidla je k dispozícii viacero zdrojov, ale ich hodnoty sú rovnaké.</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="3229041911291329567">Informácie o verzii vášho zariadenia a prehliadača</translation>
<translation id="323107829343500871">Zadajte kód CVC karty <ph name="CREDIT_CARD" /></translation>
<translation id="3234666976984236645">Vždy na tomto webe 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="3274521967729236597">Pa‑Kai</translation>
<translation id="3282497668470633863">Pridanie mena na karte</translation>
<translation id="3287510313208355388">Stiahnuť po obnovení pripojenia</translation>
<translation id="3293642807462928945">Ďalšie informácie o pravidle <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Nič sa nenašlo</translation>
-<translation id="3305707030755673451">Vaše údaje boli <ph name="TIME" /> zašifrované pomocou vlastnej prístupovej frázy synchronizácie. Keď ju zadáte, synchronizácia sa spustí.</translation>
<translation id="3320021301628644560">Pridanie fakturačnej adresy</translation>
<translation id="3324983252691184275">Karmínová</translation>
<translation id="3338095232262050444">Zabezpečené</translation>
@@ -402,9 +443,11 @@
<translation id="3427342743765426898">&amp;Znova upraviť</translation>
<translation id="342781501876943858">Ak ste heslo použili aj na iných weboch, Chromium ho odporúča obnoviť.</translation>
<translation id="3431636764301398940">Uložiť túto kartu na zariadení</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Vlastník tohto zariadenia vypol hru Dinosaur.</translation>
<translation id="3447884698081792621">Zobraziť certifikát (od vydavateľa <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Interval načítania:</translation>
+<translation id="3456231139987291353">Number-11 (obálka)</translation>
<translation id="3461824795358126837">Zvýrazňovač</translation>
<translation id="3462200631372590220">Skryť rozšírené podrobnosti</translation>
<translation id="3467763166455606212">Meno majiteľa karty je povinný údaj</translation>
@@ -427,19 +470,22 @@
<translation id="358285529439630156">Kreditné a predplatené karty sú akceptované.</translation>
<translation id="3582930987043644930">Pridajte meno</translation>
<translation id="3583757800736429874">&amp;Znova presunúť</translation>
+<translation id="35866233670761917">Vaši správcovia neuvidia obsah webov, ktoré navštívite</translation>
<translation id="3586931643579894722">Skryť podrobnosti</translation>
+<translation id="3592413004129370115">Italian (obálka)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Veľkosť 2</translation>
<translation id="3615877443314183785">Zadajte správny dátum vypršania platnosti</translation>
<translation id="36224234498066874">Vymazať dáta prehliadania...</translation>
<translation id="362276910939193118">Zobraziť celú históriu</translation>
-<translation id="3623476034248543066">Zobraziť hodnotu</translation>
<translation id="3630155396527302611">Ak je už uvedený ako program s prístupom k sieti, skúste ho odstrániť zo zoznamu a znova ho pridať.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Overenie bolo úspešné</translation>
<translation id="3655670868607891010">Ak sa vám táto stránka zobrazuje často, skúste použiť tieto stránky <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Verzia</translation>
<translation id="366077651725703012">Aktualizovať kreditnú kartu</translation>
<translation id="3676592649209844519">ID zariadenia:</translation>
+<translation id="3677008721441257057">Mysleli ste doménu &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Požiadavku sa nepodarilo podpísať</translation>
<translation id="3678529606614285348">Otvorte stránku v novom okne inkognito (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Správa o zlyhaní zaznamenaná v čase <ph name="CRASH_TIME" /> bola nahraná o <ph name="UPLOAD_TIME" /></translation>
@@ -447,13 +493,14 @@
<translation id="3704162925118123524">Sieť, ktorú používate, môže vyžadovať, aby ste navštívili jej prihlasovaciu stránku.</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="3709599264800900598">Skopírovaný text</translation>
<translation id="3712624925041724820">Vyčerpané licencie</translation>
<translation id="3714780639079136834">Zapnúť mobilné dáta alebo Wi‑Fi</translation>
<translation id="3715597595485130451">Pripojenie k sieti Wi‑Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Skontrolovať proxy server, bránu firewall a konfiguráciu DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Medzi aplikácie, ktoré môžu túto chybu spôsobiť, patria okrem iných antivírusové programy, brány firewall, softvér na filtrovanie webu alebo proxy softvér.</translation>
+<translation id="373042150751172459">B4 (obálka)</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="3745099705178523657">Po potvrdení sa budú údaje o karte z vášho účtu Google zdieľať s týmto webom.</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>
@@ -466,10 +513,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Platnosť vyprší <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Veľkosť 16</translation>
+<translation id="3797522431967816232">Prc3 (obálka)</translation>
<translation id="3807873520724684969">Škodlivý obsah bol zablokovaný.</translation>
<translation id="3810973564298564668">Spravovať</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="3831915413245941253">Doména <ph name="ENROLLMENT_DOMAIN" /> nainštalovala rozšírenia pre ďalšie funkcie. Rozšírenia majú prístup k niektorým vašim údajom.</translation>
<translation id="385051799172605136">Naspäť</translation>
<translation id="3858027520442213535">Aktualizovať dátum a čas</translation>
<translation id="3884278016824448484">Kolidujúci identifikátor zariadenia</translation>
@@ -477,6 +526,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Vždy sa opýtať na tomto webe</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>
@@ -487,11 +537,13 @@
<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="3984550557525787191">Tento názov relácie už existuje.</translation>
<translation id="3987940399970879459">Menej ako 1 MB</translation>
+<translation id="4008849406247176967">Upozornenie: V rámci tohto pravidla je k dispozícii viacero zdrojov s konfliktnými hodnotami!</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="4030383055268325496">&amp;Vrátiť späť pridanie</translation>
+<translation id="4032320456957708163">Váš prehliadač spravuje doména <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Kľúč <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (obálka)</translation>
<translation id="4067947977115446013">Pridanie platnej adresy</translation>
<translation id="4072486802667267160">Pri spracovaní vašej objednávky sa vyskytla chyba. Skúste to znova.</translation>
<translation id="4075732493274867456">Klient a server nepodporujú spoločnú verziu protokolu SSL ani šifrovaciu súpravu.</translation>
@@ -511,10 +563,12 @@
<translation id="4159784952369912983">Purpurová</translation>
<translation id="4165986682804962316">Nastavenia webu</translation>
<translation id="4171400957073367226">Nesprávny overovací podpis</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> ďalšia položka}few{<ph name="ITEM_COUNT" /> ďalšie položky}many{<ph name="ITEM_COUNT" /> ďalšej položky}other{<ph name="ITEM_COUNT" /> ďalších položiek}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (obálka)</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="4221630205957821124">&lt;h4&gt;1. krok: Prihláste sa do portálu.&lt;/h4&gt;
@@ -546,58 +600,79 @@
<translation id="4277028893293644418">Obnoviť heslo</translation>
<translation id="4280429058323657511">, dátum vypršania platnosti: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Táto karta sa uložila do vášho účtu Google}few{Tieto karty sa uložili do vášho účtu Google}many{Tieto karty sa uložili do vášho účtu Google}other{Tieto karty sa uložili do vášho účtu Google}}</translation>
+<translation id="42981349822642051">Rozbaliť</translation>
+<translation id="4302965934281694568">Chou3 (obálka)</translation>
<translation id="4305817255990598646">Prepnúť</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokovať (predvolené)</translation>
+<translation id="4318566738941496689">Názov a sieťová adresa vášho zariadenia</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="4340982228985273705">Tento počítač nebol rozpoznaný ako spravovaný podnikom, takže pravidlá môžu automaticky inštalovať iba rozšírenia hostené v Internetovom obchode Chrome. Webová adresa aktualizácie z Internetového obchodu Chrome je <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Akceptované kreditné karty</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Spravovať spôsoby platby…</translation>
+<translation id="4367563149485757821">Number-12 (obálka)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefón</translation>
<translation id="4406896451731180161">výsledky vyhľadávania</translation>
-<translation id="4406972042435603828">Vaši správcovia nainštalovali rozšírenia s rozsiahlymi funkciami.</translation>
<translation id="4408413947728134509">Súbory cookie: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Adresa vyzdvihnutia</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="443121186588148776">Sériový port</translation>
<translation id="4432688616882109544">Web <ph name="HOST_NAME" /> neakceptoval váš prihlasovací certifikát alebo nebol žiadny poskytnutý.</translation>
<translation id="4434045419905280838">Vyskakovacie okná a presmerovania</translation>
+<translation id="4435702339979719576">pohľadnica)</translation>
<translation id="443673843213245140">Použitie servera proxy je zakázané, ale je určená explicitná konfigurácia servera proxy.</translation>
<translation id="445100540951337728">Akceptované debetné karty</translation>
+<translation id="4466881336512663640">Zmeny formulára sa odstránia. Naozaj chcete pokračovať?</translation>
<translation id="4482953324121162758">Tento web nebude preložený.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Neplatná webová adresa. Je nutné použiť webovú adresu so štandardnou schémou, napr. http://example.com alebo https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (obálka)</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="4517607026994743406">Comm-10 (obálka)</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
<translation id="4524805452350978254">Spravovať karty</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Skúste deaktivovať rozšírenia.</translation>
+<translation id="4559332380232738994">10 x 11</translation>
<translation id="457875822857220463">Doručenie</translation>
+<translation id="4579056131138995126">Personal (obálka)</translation>
<translation id="4582204425268416675">Odstrániť kartu</translation>
<translation id="4587425331216688090">Chcete adresu odstrániť z prehliadača Chrome?</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="4597348597567598915">Veľkosť 8</translation>
+<translation id="4600854749408232102">C6/C5 (obálka)</translation>
<translation id="4646534391647090355">Prejsť do daného umiestnenia</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="467809019005607715">Prezentácie Google</translation>
<translation id="4690462567478992370">Nepoužívať neplatné certifikáty</translation>
+<translation id="4691835149146451662">Architecture-A (obálka)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Pripojenie bolo prerušené</translation>
<translation id="471880041731876836">Nemáte povolenie na návštevu tohto webu</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Spustiť nástroj Diagnostika siete systému Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Znova načítať pravidlá</translation>
<translation id="4728558894243024398">Platforma</translation>
+<translation id="4731967714531604179">Prc2 (obálka)</translation>
<translation id="4736825316280949806">Reštartujte Chromium</translation>
<translation id="473775607612524610">Aktualizovať</translation>
<translation id="4738601419177586157">Návrh vyhľadávania <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Spravovať heslá…</translation>
<translation id="4744603770635761495">Spustiteľná cesta</translation>
+<translation id="4746351372139058112">Správy</translation>
<translation id="4750917950439032686">Vaše údaje, napríklad heslá alebo čísla kreditných kariet, sú pri odosielaní na tento web utajené.</translation>
<translation id="4756388243121344051">&amp;História</translation>
<translation id="4758311279753947758">Pridať kontaktné údaje</translation>
@@ -605,9 +680,9 @@
<translation id="4764776831041365478">Stránka <ph name="URL" /> je možno dočasne nedostupná, možno bola natrvalo presunutá na novú webovú adresu.</translation>
<translation id="4771973620359291008">Vyskytla sa neznáma chyba.</translation>
<translation id="4785689107224900852">Prepnite na túto kartu</translation>
-<translation id="4792143361752574037">Pri pokuse o prístup k súborom relácie sa vyskytol problém. Ukladanie na disk je momentálne zakázané. Opakujte načítanie stránky a skúste to znova.</translation>
<translation id="4798078619018708837">Ak chcete aktualizovať údaje o karte <ph name="CREDIT_CARD" />, zadajte dátum vypršania platnosti a kód CVC. Po potvrdení sa budú údaje o karte z vášho účtu Google zdieľať s týmto webom.</translation>
<translation id="4800132727771399293">Skontrolujte dátum vypršania platnosti aj kód CVC a skúste to znova</translation>
+<translation id="480334179571489655">Chyba pravidla pôvodu</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>
@@ -622,7 +697,6 @@
<translation id="4881695831933465202">Otvoriť</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>
@@ -631,15 +705,15 @@
<translation id="4943872375798546930">Žiadne výsledky</translation>
<translation id="4950898438188848926">Tlačidlo na prepnutie karty, stlačením klávesa Enter prepnete na otvorenú kartu, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Akcie</translation>
-<translation id="495832697253704892">Prehľady rozšírenia</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Rozbaliť zoznam</translation>
<translation id="4974590756084640048">Opätovne aktivovať upozornenia</translation>
+<translation id="4984339528288761049">Prc5 (obálka)</translation>
<translation id="4989163558385430922">Zobraziť všetko</translation>
<translation id="4989809363548539747">Tento doplnok nie je podporovaný</translation>
-<translation id="4996230189582812866">Prehľady</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="5014174725590676422">Zobrazuje sa obrazovka pri prvom spustení Asistenta Google v Chrome</translation>
<translation id="5015510746216210676">Názov počítača:</translation>
+<translation id="5017554619425969104">Skopírovaný text</translation>
<translation id="5018422839182700155">Táto stránka sa nedá otvoriť</translation>
<translation id="5019198164206649151">Zlý stav záložného ukladacieho priestoru</translation>
<translation id="5023310440958281426">Skontrolujte pravidlá správcu</translation>
@@ -649,35 +723,51 @@
<translation id="5034369478845443529">Miestny kontext <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Povoliť</translation>
<translation id="5040262127954254034">Ochrana súkromia</translation>
+<translation id="5043480802608081735">Skopírovaný odkaz</translation>
<translation id="5045550434625856497">Nesprávne heslo</translation>
<translation id="5056549851600133418">Články pre vás</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Skontrolovať adresu proxy servera<ph name="END_LINK" /></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="5097099694988056070">Štatistiky zariadenia, ako napríklad využitie procesora alebo pamäte RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Zariadenie spravuje doména <ph name="ENROLLMENT_DOMAIN" /> a váš účet spravuje <ph name="ACCOUNT_DOMAIN" />. Znamená to, že správcovia môžu vzdialene nakonfigurovať vaše zariadenie aj účet.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bitová verzia)</translation>
-<translation id="5128122789703661928">Relácia s týmto názvom je neplatná a nedá sa odstrániť.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Spravovať adresy…</translation>
+<translation id="5138227688689900538">Zobraziť menej</translation>
<translation id="5141240743006678641">Šifrovať synchronizované heslá pomocou poverení Google</translation>
<translation id="5145883236150621069">V odpovedi na pravidlo sa nachádza kód chyby</translation>
+<translation id="515292512908731282">C4 (obálka)</translation>
<translation id="5159010409087891077">Otvorte stránku v novom okne inkognito (⇧⌘N)</translation>
<translation id="516920405563544094">Zadajte kód CVC karty <ph name="CREDIT_CARD" />. Po potvrdení sa budú údaje o karte z vášho účtu Google zdieľať s týmto webom.</translation>
<translation id="5169827969064885044">Môžete stratiť prístup do účtu svojej organizácie alebo vám niekto môže ukradnúť totožnosť. Chrome odporúča, aby ste si ihneď zmenili heslo.</translation>
<translation id="5171045022955879922">Vyhľadajte alebo zadajte webovú adresu</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Počítač</translation>
<translation id="5179510805599951267">Text sa nezobrazil v jazyku <ph name="ORIGINAL_LANGUAGE" />? Nahláste túto chybu</translation>
<translation id="5190835502935405962">Panel so záložkami</translation>
-<translation id="5200263511887412697">nahlasovanie zoznamu používateľov zariadenia, ktorí sa nedávno prihlásili</translation>
+<translation id="519422657042045905">Anotácia nie je k dispozícii</translation>
<translation id="5201306358585911203">Vložená stránka na tejto stránke hovorí</translation>
<translation id="5205222826937269299">Meno je povinný údaj</translation>
<translation id="5215116848420601511">Spôsoby platby a adresy pomocou Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-mailová adresa je povinný údaj</translation>
<translation id="5230733896359313003">Dodacia adresa</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Pripojte sa k sieti“</translation>
<translation id="5251803541071282808">Cloud</translation>
+<translation id="5252000469029418751">C7 (obálka)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Sieťové adresy</translation>
<translation id="5285570108065881030">Zobraziť všetky uložené heslá</translation>
<translation id="5287240709317226393">Zobraziť súbory cookie</translation>
<translation id="5288108484102287882">Overenie hodnôt pravidiel vygenerovalo upozornenia</translation>
@@ -689,7 +779,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> z <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Vybrať kontaktné informácie</translation>
<translation id="5327248766486351172">Názov</translation>
+<translation id="5329858041417644019">Váš prehliadač nie je spravovaný</translation>
<translation id="5332219387342487447">Spôsob dodania</translation>
+<translation id="5334013548165032829">Podrobné denníky systému</translation>
<translation id="5344579389779391559">Táto stránka sa vám môže pokúsiť účtovať poplatky</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>
@@ -697,6 +789,7 @@
<translation id="5377026284221673050">„Vaše hodiny meškajú“, „Vaše hodiny idú dopredu“ alebo „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;“</translation>
<translation id="5384855140246857529">Ak chcete používať karty vo všetkých zariadeniach, prihláste sa a zapnite synchronizáciu.</translation>
<translation id="5386426401304769735">Reťazec certifikátu pre tento web obsahuje certifikát podpísaný pomocou funkcie SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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">Vymazať dáta prehliadania…</translation>
<translation id="5430298929874300616">Odstrániť záložku</translation>
@@ -707,6 +800,7 @@
<translation id="5457113250005438886">Neplatné</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Znova upraviť</translation>
+<translation id="5478437291406423475">B6/C4 (obálka)</translation>
<translation id="5481076368049295676">Tento obsah sa môže pokúsiť nainštalovať v zariadení nebezpečný softvér, ktorý ukradne alebo odstráni vaše informácie. <ph name="BEGIN_LINK" />Napriek tomu zobraziť<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Pridanie platnej adresy</translation>
<translation id="5490432419156082418">Adresy a ďalšie údaje</translation>
@@ -714,10 +808,12 @@
<ph name="LINE_BREAK" />
Skúste kontaktovať správcu systému.</translation>
<translation id="549333378215107354">Veľkosť 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Spravované záložky</translation>
<translation id="5510766032865166053">Mohol byť prenesený alebo odstránený.</translation>
<translation id="5523118979700054094">Názov pravidla</translation>
<translation id="552553974213252141">Bol text vyňatý správne?</translation>
+<translation id="553484882784876924">Prc6 (obálka)</translation>
<translation id="5540224163453853">Požadovaný článok sa nepodarilo nájsť.</translation>
<translation id="5541546772353173584">Pridanie e-mailu</translation>
<translation id="5545756402275714221">Články pre vás</translation>
@@ -732,15 +828,21 @@
<translation id="5595485650161345191">Upraviť adresu</translation>
<translation id="5598944008576757369">Zvoliť spôsob platby</translation>
<translation id="560412284261940334">Správa nie je podporovaná</translation>
+<translation id="5605670050355397069">Účtovná kniha</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Web <ph name="HOST_NAME" /> vás presmeroval príliš veľakrát.</translation>
<translation id="5629630648637658800">Nastavenia pravidla sa nepodarilo načítať</translation>
<translation id="5631439013527180824">Neplatný token správy zariadenia</translation>
+<translation id="5632627355679805402">Údaje boli <ph name="TIME" /> zašifrované vaším <ph name="BEGIN_LINK" />heslom Google<ph name="END_LINK" />. Synchronizácia sa spustí po jeho zadaní.</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="563324245173044180">Klamlivý obsah bol zablokovaný.</translation>
<translation id="5659593005791499971">E-mail</translation>
+<translation id="5663614846592581799">9x11 (obálka)</translation>
+<translation id="5663955426505430495">Správca tohto zariadenia nainštaloval rozšírenia pre ďalšie funkcie. Rozšírenia majú prístup k niektorým vašim údajom.</translation>
<translation id="5675650730144413517">Táto stránka nefunguje</translation>
+<translation id="5684874026226664614">Hops. Túto stránku nebolo možné preložiť.</translation>
<translation id="5685654322157854305">Pridať dodaciu adresu</translation>
<translation id="5689199277474810259">Exportovať vo formáte JSON</translation>
<translation id="5689516760719285838">Poloha</translation>
@@ -749,38 +851,39 @@
<translation id="5710435578057952990">Identita tejto webovej stránky nebola overená.</translation>
<translation id="5719499550583120431">Predplatené karty sú akceptované.</translation>
<translation id="5720705177508910913">Aktuálny používateľ</translation>
+<translation id="5728056243719941842">C5 (obálka)</translation>
<translation id="5730040223043577876">Ak ste heslo použili aj na iných weboch, Chrome ho odporúča obnoviť.</translation>
<translation id="5732392974455271431">Vaši rodičia ho môžu pre vás odblokovať</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Uloženie karty do účtu Google}few{Uloženie kariet do účtu Google}many{Save cards in your Google Account}other{Uloženie kariet do účtu Google}}</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="5770114862687765385">Súbor je zrejme poškodený. Obnovte reláciu kliknutím na tlačidlo Obnoviť.</translation>
<translation id="5778550464785688721">Úplné ovládanie zariadení MIDI</translation>
<translation id="578305955206182703">Žltohnedá</translation>
<translation id="57838592816432529">Vypnúť zvuk</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>
+<translation id="5798290721819630480">Chcete zahodiť zmeny?</translation>
<translation id="5798683403665926540">Zmeniť domovskú stránku v nastaveniach Chromu</translation>
<translation id="5803412860119678065">Chcete vyplniť informácie o karte <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Povolenia</translation>
<translation id="5810442152076338065">Vaše pripojenie k doméne <ph name="DOMAIN" /> je šifrované pomocou zastaranej šifrovacej súpravy.</translation>
<translation id="5813119285467412249">&amp;Znova pridať</translation>
<translation id="5838278095973806738">Na tomto webe by ste nemali zadávať citlivé údaje, napríklad heslá alebo kreditné karty, pretože by ich mohli ukradnúť útočníci.</translation>
+<translation id="5860033963881614850">Vypnuté</translation>
<translation id="5863847714970149516">Stránka, na ktorú sa chystáte prejsť, vám môže účtovať poplatky</translation>
<translation id="5866257070973731571">Pridanie telefónneho čísla</translation>
<translation id="5869405914158311789">Tento web je nedostupný</translation>
<translation id="5869522115854928033">Uložené heslá</translation>
<translation id="5887400589839399685">Karta bola uložená</translation>
-<translation id="5893718151540690985">nahlasovanie zoznamu sieťových rozhraní s typmi a adresami hardvéru</translation>
<translation id="5893752035575986141">Kreditné karty sú akceptované.</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="5916664084637901428">Zapnuté</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Chcete uložiť kartu do účtu Google?</translation>
<translation id="5922853866070715753">Takmer dokončené</translation>
<translation id="5932224571077948991">Web zobrazuje obťažujúce alebo zavádzajúce reklamy</translation>
-<translation id="5939518447894949180">Resetovať</translation>
<translation id="5946937721014915347">Otvára sa web <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Nemôžete sa zaregistrovať spotrebiteľským účtom (k dispozícii je licencia v balíčku).</translation>
<translation id="5967592137238574583">Úprava kontaktných informácií</translation>
@@ -788,6 +891,7 @@
<translation id="5975083100439434680">Oddialiť</translation>
<translation id="5977489021191000276">Vaše zariadenie neovláda žiadny správca.</translation>
<translation id="5977976211062815271">V tomto zariadení</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Nie je možné otvoriť platobnú aplikáciu</translation>
<translation id="5989320800837274978">Nie sú určené pevne dané servery proxy ani skript PAC webovej adresy.</translation>
<translation id="5990559369517809815">Žiadosti odoslané serveru boli zablokované rozšírením.</translation>
@@ -798,8 +902,8 @@
<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="6033927989869462158">nahlasovanie štatistík hardvéru, napríklad využitie procesora alebo pamäte RAM</translation>
<translation id="6034000775414344507">Svetlosivá</translation>
+<translation id="6034283069659657473">10x14 (obálka)</translation>
<translation id="6039846035001940113">Ak problém naďalej pretrváva, kontaktujte vlastníka webu.</translation>
<translation id="6040143037577758943">Zavrieť</translation>
<translation id="6044573915096792553">Veľkosť 12</translation>
@@ -808,10 +912,10 @@
<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="6058977677006700226">Chcete použiť svoje karty vo všetkých zariadeniach?</translation>
<translation id="6059925163896151826">Zariadenia USB</translation>
-<translation id="6071091556643036997">Tento typ pravidiel je neplatný.</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="6094273045989040137">Pridať anotáciu</translation>
<translation id="610911394827799129">Váš účet Google môže mať ďalšie formy histórie prehliadania na adrese <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Informácie o nainštalovaných rozšíreniach a doplnkoch</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>
@@ -845,15 +949,21 @@
<translation id="6337133576188860026">Uvoľní menej ako <ph name="SIZE" />. Niektoré weby sa môžu pri ďalšej návšteve načítať pomalšie.</translation>
<translation id="6337534724793800597">Filtrovať pravidlá podľa mena</translation>
<translation id="6358450015545214790">Čo znamenajú tieto položky?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Ak prejdete ďalej, môžu vám byť účtované poplatky.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 ďalší návrh}few{# ďalšie návrhy}many{# ďalšieho návrhu}other{# ďalších návrhov}}</translation>
<translation id="6387754724289022810">Ak chcete nabudúce zaplatiť rýchlejšie, uložte si kartu a fakturačnú adresu do účtu Google a tohto zariadenia.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Upraviť záložku</translation>
+<translation id="6406765186087300643">C0 (obálka)</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="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="6434309073475700221">Odstrániť</translation>
+<translation id="6446163441502663861">Kahu (obálka)</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>
@@ -866,11 +976,17 @@
<translation id="6508722015517270189">Reštartujte Chrome</translation>
<translation id="6529602333819889595">&amp;Znova odstrániť</translation>
<translation id="6534179046333460208">Návrhy Fyzického webu</translation>
+<translation id="6556866813142980365">Znova</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="6578796323535178455">C2 (obálka)</translation>
<translation id="6579990219486187401">Svetloružová</translation>
+<translation id="6583674473685352014">B6 (obálka)</translation>
+<translation id="6587923378399804057">Skopírovaný odkaz</translation>
+<translation id="6591833882275308647">Zariadenie <ph name="DEVICE_TYPE" /> nie je spravované</translation>
<translation id="6596325263575161958">Možnosti šifrovania</translation>
<translation id="6604181099783169992">Senzory pohybu alebo svetla</translation>
+<translation id="6609880536175561541">Prc7 (obálka)</translation>
<translation id="6624427990725312378">Kontaktné informácie</translation>
<translation id="6626291197371920147">Pridanie platného čísla karty</translation>
<translation id="6628463337424475685">Vyhľadávanie <ph name="ENGINE" /></translation>
@@ -879,6 +995,7 @@
<translation id="6644283850729428850">Toto pravidlo bolo označené ako zastarané.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Žiadne}=1{Z 1 webu (neodhlásime vás z účtu Google)}few{Z # webov (neodhlásime vás z účtu Google)}many{From # sites (you won't be signed out of your Google Account)}other{Z # webov (neodhlásime vás z účtu Google)}}</translation>
<translation id="6657585470893396449">Heslo</translation>
+<translation id="6670613747977017428">Späť do bezpečia</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>
@@ -886,12 +1003,15 @@
<translation id="671076103358959139">Registračný token:</translation>
<translation id="6711464428925977395">Vyskytol sa problém s proxy serverom alebo je adresa nesprávna.</translation>
<translation id="6723740634201835758">V účte Google</translation>
+<translation id="6738516213925468394">Vaše údaje boli <ph name="TIME" /> zašifrované pomocou <ph name="BEGIN_LINK" />prístupovej frázy synchronizácie<ph name="END_LINK" />. Synchronizácia sa spustí po jej zadaní.</translation>
<translation id="674375294223700098">Neznáma chyba spôsobená certifikátom servera.</translation>
<translation id="6744009308914054259">Zatiaľ čo čakáte na pripojenie, môžete prejsť do priečinka stiahnutých súborov a prečítať si články v režime offline.</translation>
<translation id="6753269504797312559">Hodnota pravidla</translation>
<translation id="6757797048963528358">Vaše zariadenie prešlo do režimu spánku.</translation>
+<translation id="6768213884286397650">Hagaki (pohľadnica)</translation>
<translation id="6778737459546443941">Váš rodič to zatiaľ neschválil</translation>
<translation id="67862343314499040">Fialová</translation>
+<translation id="6786747875388722282">Rozšírenia</translation>
<translation id="679355240208270552">Ignorované, pretože predvolené vyhľadávanie je zakázané pravidlom.</translation>
<translation id="681021252041861472">Povinné pole</translation>
<translation id="6810899417690483278">Identifikátor prispôsobenia</translation>
@@ -924,10 +1044,12 @@
<translation id="6965978654500191972">Zariadenie</translation>
<translation id="6970216967273061347">Okres</translation>
<translation id="6973656660372572881">Určené sú pevne dané servery proxy aj skript PAC webovej adresy.</translation>
+<translation id="6973932557599545801">Ľutujem, neviem pomôcť. Pokračujte samostatne.</translation>
<translation id="6979158407327259162">Disk Google</translation>
<translation id="6979440798594660689">Ignorovať (predvolené)</translation>
<translation id="6984479912851154518">Ak zaplatíte pomocou externej aplikácie, opustíte režim inkognito. Chcete pokračovať?</translation>
<translation id="6989763994942163495">Zobraziť rozšírené nastavenia...</translation>
+<translation id="6993898126790112050">6x9 (obálka)</translation>
<translation id="6996312675313362352">Vždy prekladať jazyk <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Tieto poplatky môžu byť jednorazové alebo opakované a nemusia byť predvídateľné.</translation>
@@ -943,28 +1065,33 @@
<translation id="7108338896283013870">Skryť</translation>
<translation id="7108819624672055576">Povolené rozšírením</translation>
<translation id="7111012039238467737">(Platný)</translation>
+<translation id="7118618213916969306">Vyhľadať webovú adresu v schránke <ph name="SHORT_URL" /></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="7135130955892390533">Zobraziť stav</translation>
<translation id="7138472120740807366">Spôsob doručenia</translation>
<translation id="7139724024395191329">Emirát</translation>
+<translation id="7152423860607593928">Number-14 (obálka)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Levanduľová</translation>
-<translation id="7158980942472052083">Neplatná webová adresa. Musí to byť webová adresa so štandardnou schémou.</translation>
<translation id="717330890047184534">ID služby Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Server <ph name="ORIGIN" />, na ktorý prechádzate, požiadal, aby sa na všetky naň odoslané žiadosti vzťahovalo pravidlo zabezpečenia. Namiesto poskytnutia pravidla presmeroval prehliadač inam, čo bráni prehliadaču splniť vašu žiadosť týkajúcu sa webu <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Ukladať a dopĺňať spôsoby platby</translation>
<translation id="7180611975245234373">Obnoviť</translation>
<translation id="7182878459783632708">Nie sú nastavené žiadne pravidlá</translation>
<translation id="7186367841673660872">Táto stránka bola preložená z jazyka<ph name="ORIGINAL_LANGUAGE" />do jazyka<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Uvoľní <ph name="SIZE" />. Niektoré weby sa môžu pri ďalšej návšteve načítať pomalšie.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Váš správca uvidí:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Web <ph name="HOST_NAME" /> nespĺňa bezpečnostné štandardy.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /> o tomto probléme.</translation>
<translation id="7219179957768738017">Spojenie používa protokol <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Spracováva sa</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Webové stránky, ktoré chcete otvoriť, obsahujú malvér</translation>
+<translation id="724766306220616965">Upozornenia, konflikt</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="7251437084390964440">Konfigurácia siete nie je v súlade so štandardom ONC. Niektoré časti konfigurácie sa nemusia importovať.
Ďalšie podrobnosti:
@@ -977,11 +1104,14 @@
<translation id="7300012071106347854">Kobaltová modrá</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />“</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="7313965965371928911">Upozornenia <ph name="BEGIN_LINK" />Bezpečného prehliadania<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Pomocník s pripojením</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Príkazový riadok</translation>
-<translation id="7365061714576910172">Exportovať Linux</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>
@@ -989,6 +1119,7 @@
<translation id="7381288752349550461">Prepísanie spravovanej relácie</translation>
<translation id="7390545607259442187">Overenie karty</translation>
<translation id="7400418766976504921">Webová adresa</translation>
+<translation id="7403591733719184120">Zariadenie <ph name="DEVICE_NAME" /> je spravované</translation>
<translation id="7407424307057130981">&lt;p&gt;Táto chyba sa zobrazí, keď máte v počítači so systémom Windows softvér Superfish.&lt;/p&gt;
&lt;p&gt;Postupujte podľa týchto krokov a softvér dočasne zakážte, aby ste mohli prejsť na daný web. Budete potrebovať oprávnenia správcu.&lt;/p&gt;
&lt;ol&gt;
@@ -999,7 +1130,7 @@
&lt;li&gt;Kliknite na možnosť &lt;strong&gt;Použiť&lt;/strong&gt;, potom na &lt;strong&gt;OK&lt;/strong&gt;.
&lt;li&gt;Ďalšie informácie o tom, ako natrvalo odstrániť softvér z počítača, nájdete v &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;centre pomoci Chromu&lt;/a&gt;.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Správa prehliadača <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Široký formát</translation>
<translation id="7416351320495623771">Spravovať heslá…</translation>
<translation id="7419106976560586862">Cesta profilu</translation>
<translation id="7437289804838430631">Pridať kontaktné informácie</translation>
@@ -1008,22 +1139,24 @@
<translation id="7442725080345379071">Svetlooranžová</translation>
<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="7449109375006139765">odosielanie denníkov systému na správcovský server</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="7460618730930299168">Zobrazené informácie sa líšia od vášho výberu. Pokračovať?</translation>
<translation id="7473891865547856676">Nie, ďakujem</translation>
-<translation id="7475525192983021547">nahlasovanie časových období, kedy používateľ aktívne využíval zariadenie</translation>
<translation id="7481312909269577407">Dopredu</translation>
<translation id="7485870689360869515">Nenašli sa žiadne údaje.</translation>
+<translation id="7498234416455752244">Pokračovať v úprave</translation>
<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="7508870219247277067">Žltozelená</translation>
<translation id="7511955381719512146">Sieť Wi‑Fi, ktorú používate, môže vyžadovať, aby ste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
<translation id="7514365320538308">Stiahnuť</translation>
<translation id="7518003948725431193">Na <ph name="URL" /> sa nenašla žiadna webová stránka</translation>
+<translation id="7520302887438682816">C8 (obálka)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Spojenie s týmto webom nie je súkromné</translation>
+<translation id="7535087603100972091">Hodnota</translation>
<translation id="7537536606612762813">Povinné</translation>
+<translation id="7538364083937897561">A2 (obálka)</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>
@@ -1032,8 +1165,8 @@
<translation id="7552846755917812628">Vyskúšajte nasledujúce tipy:</translation>
<translation id="7554791636758816595">Nová karta</translation>
<translation id="7564049878696755256">Môžete stratiť prístup do účtu <ph name="ORG_NAME" /> alebo vám niekto môže ukradnúť identitu. Chrome odporúča, aby ste si ihneď zmenili heslo.</translation>
-<translation id="7566125604157659769">Skopírovaný text</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="7568105740864181217">Tento prehliadač spravuje spoločnosť, škola alebo iná organizácia. Nastavenia prehliadača môže vzdialene zmeniť správca. Aktivita v tomto zariadení môže byť tiež spravovaná mimo Chromu. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></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>
@@ -1044,6 +1177,7 @@
<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="7633909222644580952">Údaje o výkonnosti a správy o zlyhaní</translation>
<translation id="7637571805876720304">Chcete kreditnú kartu odstrániť z prehliadača Chromium?</translation>
<translation id="7639968568612851608">Tmavosivá</translation>
<translation id="765676359832457558">Skryť rozšírené nastavenia...</translation>
@@ -1053,9 +1187,11 @@
<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="7676643023259824263">Vyhľadať v schránke text <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Zmeniť vyhľadávač</translation>
<translation id="7682287625158474539">Dodacia</translation>
<translation id="7687186412095877299">Doplní do platobných formulárov vaše uložené spôsoby platby</translation>
+<translation id="7697066736081121494">Prc8 (obálka)</translation>
<translation id="769721561045429135">Momentálne máte karty, ktoré je možné použiť iba v tomto zariadení Ak chcete skontrolovať karty, kliknite na Pokračovať.</translation>
<translation id="7699293099605015246">Články nie sú momentálne k dispozícii</translation>
<translation id="7701040980221191251">Žiadne</translation>
@@ -1067,11 +1203,13 @@
<translation id="774634243536837715">Nebezpečný obsah bol zablokovaný.</translation>
<translation id="7752995774971033316">Nespravované</translation>
<translation id="7755287808199759310">Váš rodič ho môže pre vás odblokovať</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Pripojenie mohla zablokovať brána firewall alebo antivírusový softvér.</translation>
<translation id="7759163816903619567">Zobrazená doména:</translation>
<translation id="7761701407923456692">Certifikát servera sa nezhoduje s webovou adresou.</translation>
<translation id="7763386264682878361">Analyzátor manifestov platieb</translation>
<translation id="7764225426217299476">Pridať adresu</translation>
+<translation id="7770259615151589601">Určené – dlhé</translation>
<translation id="777702478322588152">Prefektúra</translation>
<translation id="7791543448312431591">Pridať</translation>
<translation id="7793809570500803535">Stránka <ph name="SITE" /> je možno dočasne nedostupná, možno bola natrvalo presunutá na novú webovú adresu.</translation>
@@ -1083,8 +1221,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chcete návrh odstrániť z prehliadača Chrome?</translation>
<translation id="7815407501681723534">Nájdené výsledky (počet: <ph name="NUMBER_OF_RESULTS" />) pre dopyt „<ph name="SEARCH_STRING" />“: <ph name="SEARCH_RESULTS" /></translation>
-<translation id="7818867226424560206">Správa pravidiel</translation>
<translation id="782886543891417279">Sieť Wi‑Fi (<ph name="WIFI_NAME" />), ktorú používate, môže vyžadovať, aby ste navštívili jej prihlasovaciu stránku</translation>
+<translation id="7836231406687464395">Postfix (obálka)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Žiadne}=1{1 aplikácia (<ph name="EXAMPLE_APP_1" />)}=2{2 aplikácie (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}few{# aplikácie (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}many{# apps (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# aplikácií (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Nie ste však neviditeľný/-á. Prejdením do režimu inkognito neskryjete svoje prehliadanie pred zamestnávateľom, poskytovateľom internetových služieb ani pred navštívenými webmi.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1093,7 +1231,7 @@
<translation id="7878562273885520351">Vaše heslo mohlo byť napadnuté</translation>
<translation id="7882421473871500483">Hnedá</translation>
<translation id="7887683347370398519">Skontrolujte svoj kód CVC a skúste to znova</translation>
-<translation id="7893255318348328562">Názov relácie</translation>
+<translation id="7904208859782148177">C3 (obálka)</translation>
<translation id="79338296614623784">Zadajte platné telefónne číslo</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Platí do <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1103,21 +1241,25 @@
<translation id="7951415247503192394">(32-bitová verzia)</translation>
<translation id="7956713633345437162">Mobilné záložky</translation>
<translation id="7961015016161918242">Nikdy</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Prehliadač</translation>
<translation id="8009225694047762179">Spravovať heslá</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Táto karta a jej fakturačná adresa budú uložené. Budete ju môcť použiť po prihlásení do účtu <ph name="USER_EMAIL" />.}few{Tieto karty a ich fakturačné adresy budú uložené. Budete ich môcť použiť po prihlásení do účtu <ph name="USER_EMAIL" />.}many{Tieto karty a ich fakturačné adresy budú uložené. Budete ich môcť použiť po prihlásení do účtu <ph name="USER_EMAIL" />.}other{Tieto karty a ich fakturačné adresy budú uložené. Budete ich môcť použiť po prihlásení do účtu <ph name="USER_EMAIL" />.}}</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="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="8035152190676905274">Pero</translation>
+<translation id="8037117624646282037">Kto nedávno použil toto zariadenie</translation>
<translation id="8037357227543935929">Opýtať sa (predvolené)</translation>
<translation id="803771048473350947">Súbor</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="8042918947222776840">Zvoliť spôsob vyzdvihnutia</translation>
<translation id="8057711352706143257">Softvér <ph name="SOFTWARE_NAME" /> nie je správne nakonfigurovaný. Tento problém sa zvyčajne odstráni odinštalovaním softvéru <ph name="SOFTWARE_NAME" />. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">V zariadení boli nakonfigurované nasledujúce pravidlá:</translation>
+<translation id="8066955247577885446">Je nám to ľúto, ale vyskytol sa problém.</translation>
+<translation id="8074253406171541171">10x13 (obálka)</translation>
<translation id="8078141288243656252">Po otočení dokumentu nie je anotácia možná</translation>
<translation id="8079031581361219619">Znova načítať web?</translation>
<translation id="8088680233425245692">Článok sa nepodarilo zobraziť.</translation>
@@ -1126,11 +1268,12 @@
<translation id="8091372947890762290">Aktivácia čaká na server</translation>
<translation id="8092774999298748321">Tmavopurpurová</translation>
<translation id="8094917007353911263">Sieť, ktorú používate, môže vyžadovať, aby ste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Neplatné karty boli odstránené</translation>
<translation id="8103161714697287722">Spôsob platby</translation>
<translation id="8118489163946903409">Spôsob platby</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> spravuje <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Softvér <ph name="SOFTWARE_NAME" /> nebol v počítači alebo sieti riadne nainštalovaný. Požiadajte správcu IT, aby tento problém vyriešil.</translation>
-<translation id="8130693978878176684">Už vám nemôžem pomôcť. Pokračujte ručným zadávaním.</translation>
<translation id="8131740175452115882">Potvrdiť</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>
@@ -1140,8 +1283,11 @@
<translation id="8197543752516192074">Preložiť stránku</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (obálka)</translation>
<translation id="8211406090763984747">Spojenie je zabezpečené</translation>
<translation id="8218327578424803826">Pridelená poloha:</translation>
+<translation id="8220146938470311105">C7/C6 (obálka)</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="8238581221633243064">Otvorte stránku na novej karte inkognito</translation>
@@ -1153,14 +1299,16 @@
<translation id="825929999321470778">Zobraziť všetky uložené heslá</translation>
<translation id="8261506727792406068">Odstrániť</translation>
<translation id="8267698848189296333">Prihlasovanie pomocou účtu <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Tento prehliadač spravuje <ph name="ENROLLMENT_DOMAIN" />. Jeho nastavenie môže vzdialene zmeniť váš správca. Aktivita v tomto zariadení môže byť tiež spravovaná mimo Chromu. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Veľká fotka</translation>
<translation id="8286036467436129157">Prihlásenie</translation>
<translation id="8288807391153049143">Zobraziť certifikát</translation>
<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="8298115750975731693">Sieť Wi‑Fi (<ph name="WIFI_NAME" />), ktorú používate, môže vyžadovať, aby ste navštívili stránku <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
+<translation id="8307358339886459768">Malá fotka</translation>
<translation id="8308427013383895095">Preklad zlyhal v dôsledku problému so sieťovým pripojením.</translation>
-<translation id="8311129316111205805">Načítať reláciu</translation>
<translation id="8332188693563227489">Prístup k webu <ph name="HOST_NAME" /> bol zamietnutý</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1178,7 +1326,6 @@
<translation id="8416694386774425977">Konfigurácia siete je neplatná a nepodarilo sa ju importovať.
Ďalšie podrobnosti:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Zariadenie spravuje doména <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Zmeniť</translation>
<translation id="8428213095426709021">Nastavenia</translation>
@@ -1206,9 +1353,11 @@
<translation id="860043288473659153">Meno držiteľa karty</translation>
<translation id="861775596732816396">Veľkosť 4</translation>
<translation id="8620436878122366504">Vaši rodičia to zatiaľ neschválili</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Uložiť túto kartu do tohto zariadenia</translation>
<translation id="8663226718884576429">Súhrn objednávky, <ph name="TOTAL_LABEL" />, ďalšie podrobnosti</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, odpoveď, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Vaše pripojenie k doméne <ph name="DOMAIN" /> sa nešifruje.</translation>
<translation id="8718314106902482036">Platba nebola dokončená</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, návrh vyhľadávania</translation>
@@ -1222,6 +1371,7 @@
<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="8763927697961133303">Zariadenie USB</translation>
<translation id="8768895707659403558">Ak chcete používať karty vo všetkých zariadeniach, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Znova vymazať</translation>
<translation id="8792621596287649091">Môžete stratiť prístup do účtu <ph name="ORG_NAME" /> alebo vám niekto môže ukradnúť identitu. Chromium odporúča, aby ste si ihneď zmenili heslo.</translation>
<translation id="8800988563907321413">Tu sa zobrazia návrhy funkcie Nablízku</translation>
@@ -1232,10 +1382,12 @@
<translation id="885730110891505394">Zdieľanie s Googlom</translation>
<translation id="8858065207712248076">Ak ste heslo organizácie <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> použili aj na iných weboch, Chrome ho odporúča obnoviť.</translation>
<translation id="8866481888320382733">Pri analýze nastavení pravidla sa vyskytla chyba</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nedávno zatvorené</translation>
<translation id="8874824191258364635">Zadajte platné číslo karty</translation>
<translation id="8891727572606052622">Neplatný režim proxy.</translation>
<translation id="8903921497873541725">Priblížiť</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Pridanie mena</translation>
@@ -1243,13 +1395,13 @@
<translation id="894185898663964645">Váš správca nakonfiguroval vlastné koreňové certifikáty, ktoré mu môžu umožniť zobrazovať obsah vami navštevovaných webov.</translation>
<translation id="8943282376843390568">Limetková</translation>
<translation id="8957210676456822347">Autorizácia portálu na prihlásenie do siete</translation>
+<translation id="8966619695390250636">Mysleli ste?</translation>
<translation id="8968766641738584599">Uložiť kartu</translation>
<translation id="8971063699422889582">Platnosť certifikátu servera vypršala.</translation>
<translation id="8975012916872825179">Zahŕňa telefónne čísla, e‑mailové adresy a dodacie adresy</translation>
<translation id="8978053250194585037">Funkcia Bezpečné prehliadanie Google nedávno <ph name="BEGIN_LINK" />zistila phishing<ph name="END_LINK" /> na webe <ph name="SITE" />. Phishingové stránky sa vydávajú za iné weby, aby vás oklamali.</translation>
<translation id="8983003182662520383">Spôsoby platby a adresy pomocou Google Pay</translation>
<translation id="8987927404178983737">Mesiac</translation>
-<translation id="8988408250700415532">Vyskytol sa problém. Objednávku môžete dokončiť na webe.</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>
@@ -1259,6 +1411,7 @@
<translation id="9011424611726486705">Otvoriť nastavenia webu</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Neplatný)</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>
@@ -1270,11 +1423,11 @@
<translation id="9065745800631924235">Vyhľadávanie <ph name="TEXT" /> z histórie</translation>
<translation id="9069693763241529744">Blokované rozšírením</translation>
<translation id="9076283476770535406">Môže zahŕňať obsah pre dospelých</translation>
+<translation id="9076630408993835509">Tento prehliadač nespravuje firma ani iná organizácia. Aktivita v tomto zariadení môže byť spravovaná mimo Chromu. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Treba zadať ďalšie informácie</translation>
<translation id="9080712759204168376">Súhrn objednávky</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>
<translation id="9106062320799175032">Pridanie fakturačnej adresy</translation>
-<translation id="9110718169272311511">Asistent Google sa v Chrome nachádza v dolnej časti obrazovky</translation>
<translation id="9114524666733003316">Overuje sa karta…</translation>
<translation id="9128870381267983090">Pripojiť k sieti</translation>
<translation id="9137013805542155359">Zobraziť originál</translation>
@@ -1283,6 +1436,7 @@
<translation id="9148507642005240123">&amp;Vrátiť späť úpravu</translation>
<translation id="9154194610265714752">Aktualizované</translation>
<translation id="9157595877708044936">Prebieha nastavenie...</translation>
+<translation id="9158625974267017556">C6 (obálka)</translation>
<translation id="9168814207360376865">Povoliť webom zisťovať, či máte uložené spôsoby platby</translation>
<translation id="9169664750068251925">Vždy blokovať na tomto webe</translation>
<translation id="9170848237812810038">&amp;Naspäť</translation>
@@ -1297,10 +1451,12 @@
<translation id="9219103736887031265">Obrázky</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">VYMAZAŤ FORMULÁR</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Môžete stratiť prístup do účtu Google. Chromium odporúča, aby ste si ihneď zmenili heslo. Zobrazí sa výzva na prihlásenie.</translation>
<translation id="939736085109172342">Nový priečinok</translation>
<translation id="945855313015696284">Skontrolujte informácie nižšie a odstráňte neplatné karty</translation>
<translation id="951104842009476243">Akceptované debetné a predplatené karty</translation>
+<translation id="958202389743790697">Blokované pravidlom zabezpečenia zo zdroja <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Tento obsah sa môže pokúsiť nainštalovať klamlivé aplikácie vydávajúce sa za iné aplikácie alebo zhromažďovať údaje, ktoré sa dajú použiť na sledovanie vašej osoby. <ph name="BEGIN_LINK" />Napriek tomu zobraziť<ph name="END_LINK" /></translation>
<translation id="969892804517981540">oficiálna zostava</translation>
<translation id="973773823069644502">Pridať adresu doručenia</translation>
@@ -1309,6 +1465,7 @@
<translation id="984275831282074731">Spôsoby platby</translation>
<translation id="985199708454569384">&lt;p&gt;Táto chyba sa zobrazí, keď máte v počítači alebo mobilnom zariadení nesprávny dátum a čas.&lt;/p&gt;
&lt;p&gt;Ak chcete túto chybu odstrániť, otvorte v zariadení hodiny a nastavte správny dátum a čas.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Zostavenie pre vývojárov</translation>
<translation id="989988560359834682">Úprava adresy</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_sl.xtb b/chromium/components/strings/components_strings_sl.xtb
index 7ca6856be66..6a61d320ad0 100644
--- a/chromium/components/strings/components_strings_sl.xtb
+++ b/chromium/components/strings/components_strings_sl.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sl">
-<translation id="1005145902654145231">Seje ni bilo mogoče preimenovati.</translation>
<translation id="1008557486741366299">Ne zdaj</translation>
<translation id="1010200102790553230">Naloži stran pozneje</translation>
<translation id="1015730422737071372">Navedite dodatne podrobnosti</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">neznano ime</translation>
<translation id="1050038467049342496">Zaprite druge aplikacije</translation>
<translation id="1055184225775184556">&amp;Razveljavi dodajanje</translation>
+<translation id="1056898198331236512">Opozorilo</translation>
<translation id="1058479211578257048">Shranjevanje kartic …</translation>
<translation id="10614374240317010">Nikoli shranjeno</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">Zaznamki namizja</translation>
<translation id="1074497978438210769">Ni varno</translation>
<translation id="1080116354587839789">Prilagoditev prikaza širini</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Dodajanje imena na kartico</translation>
<translation id="1089439967362294234">Spremeni geslo</translation>
<translation id="109743633954054152">Upravljajte gesla v Chromovih nastavitvah</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Medtem ko spletne strani posodabljajo varnost, se lahko opozorila pogosto prikažejo. To se bo kmalu izboljšalo.</translation>
<translation id="1126551341858583091">Velikosti v lokalni shrambi je <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Predpomnilnik pravilnika ustrezen</translation>
+<translation id="1131264053432022307">Slika, ki ste jo kopirali</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Preimenuj</translation>
<translation id="1175364870820465910">&amp;Natisni ...</translation>
<translation id="1181037720776840403">Odstrani</translation>
<translation id="1197088940767939838">Oranžna</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Ime vaše naprave</translation>
<translation id="124116460088058876">Več jezikov</translation>
<translation id="1250759482327835220">Če želite naslednjič hitreje plačati, shranite kartico, ime in naslov za izstavitev računa v Google Računu.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinhronizirano)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Različice ukazne vrstice</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="1314614906530272393">Izbrana seja ne obstaja.</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">Iskanje slike v odložišču</translation>
<translation id="1323433172918577554">Pokaži več</translation>
<translation id="132390688737681464">Shranjevanje in izpolnjevanje naslovov</translation>
<translation id="1333989956347591814">Vaša dejavnost <ph name="BEGIN_EMPHASIS" />je morda še vedno vidna<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Naslov za prevzem</translation>
<translation id="1348198688976932919">Spletno mesto vsebuje nevarne aplikacije</translation>
<translation id="1348779747280417563">Potrditev imena</translation>
+<translation id="1357195169723583938">Kdo je nedavno uporabljal napravo in kdaj</translation>
+<translation id="1364822246244961190">Ta pravilnik je blokiran in njegova vrednost bo prezrta.</translation>
<translation id="1374468813861204354">predlogi</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">O različici</translation>
<translation id="1376836354785490390">Pokaži manj</translation>
<translation id="1377321085342047638">Card Number</translation>
<translation id="138218114945450791">Svetlo modra</translation>
+<translation id="1382194467192730611">Naprava USB, ki jo je dovolil skrbnik</translation>
<translation id="139305205187523129">Spletno mesto <ph name="HOST_NAME" /> ni poslalo nobenih podatkov.</translation>
+<translation id="140316286225361634">Spletno mesto <ph name="ORIGIN" /> je zahtevalo, da za vse njegove
+ zahteve velja varnostni pravilnik, in ta pravilnik spletno mesto trenutno obravnava, kot da
+ ni varno.</translation>
<translation id="1405567553485452995">Svetlo zelena</translation>
<translation id="1407135791313364759">Odpri vse</translation>
<translation id="1413809658975081374">Napaka zasebnosti</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Da</translation>
<translation id="1430915738399379752">Natisni</translation>
<translation id="1455413310270022028">Radirka</translation>
+<translation id="1463543813647160932">5 x 7</translation>
+<translation id="1472675084647422956">Pokaži več</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Izbira naslova za pošiljanje</translation>
+<translation id="1492194039220927094">Potiskanje pravilnikov:</translation>
<translation id="1501859676467574491">Prikaz kartic iz Google Računa</translation>
-<translation id="1506687042165942984">Prikaži shranjeno (zastarelo) kopijo te strani.</translation>
<translation id="1507202001669085618">&lt;p&gt;Ta napaka se prikaže, če uporabljate portal Wi-Fi, ki pred uporabo spleta zahteva prijavo.&lt;/p&gt;
&lt;p&gt;Napravo odpravite tako, da na strani, ki jo poskušate odpreti, kliknete &lt;strong&gt;Poveži&lt;/strong&gt;.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonska številka je obvezna</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Datum gradnje</translation>
<translation id="1521655867290435174">Google Preglednice</translation>
<translation id="1527263332363067270">Čakanje na povezavo ...</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Ta stran sporoča:</translation>
<translation id="153384715582417236">To je vse za zdaj</translation>
<translation id="154408704832528245">Izbira naslova za dostavo</translation>
<translation id="1549470594296187301">Če želite uporabljati to funkcijo, mora biti omogočen JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Vnesite datum poteka</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Slika, ki ste jo kopirali</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Tej strani prepreči, da bi ustvarila dodatna pogovorna okna</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Končaj sejo</translation>
<translation id="1639239467298939599">Nalaganje</translation>
<translation id="1640180200866533862">Uporabniški pravilniki</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Potrdilo strežnika vsebuje šibek šifrirni ključ.</translation>
<translation id="1697532407822776718">Pripravljeni ste.</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Dokument je prevelik, da bi mu dodali pripise</translation>
<translation id="1721312023322545264"><ph name="NAME" /> vam mora odobriti obisk tega spletnega mesta</translation>
<translation id="1721424275792716183">*Polje je obvezno</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Poskusite se obrniti na skrbnika sistema.</translation>
<translation id="1740951997222943430">Vnesite veljaven mesec poteka veljavnosti</translation>
<translation id="1743520634839655729">Če želite naslednjič hitreje plačati, shranite kartico, ime in naslov za izstavitev računa v Google Računu in v tej napravi.</translation>
+<translation id="1745880797583122200">Vaš brskalnik je upravljan</translation>
<translation id="17513872634828108">Odprti zavihki</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Posodobite geslo za sinhronizacijo.</translation>
<translation id="1787142507584202372">Tu so prikazani odprti zavihki</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Ime imetnika kartice</translation>
<translation id="1821930232296380041">Neveljavna zahteva ali parametri zahteve</translation>
+<translation id="1822540298136254167">Spletna mesta, ki jih obiščete, in čas, ki ga porabite zanje</translation>
<translation id="1826516787628120939">Preverjanje</translation>
<translation id="1834321415901700177">Na tem spletnem mestu so škodljivi programi</translation>
<translation id="1839551713262164453">Preverjanje vrednosti pravilnika je bilo neuspešno z napakami</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Počistite podatke zgodovine brskanja v Chromu</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{in še 1}one{in še #}two{in še #}few{in še #}other{in še #}}</translation>
<translation id="2003709556000175978">Ponastavite geslo</translation>
+<translation id="20053308747750172">Strežnik, na katerega greste (<ph name="ORIGIN" />), je zahteval, da se
+ za vse zahteve, ki so mu poslane, uporabi varnostni pravilnik. Vendar pa je zdaj
+ zagotovil neveljaven pravilnik, ki brskalniku preprečuje,
+ da bi izpolnil vašo zahtevo za <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Strežnik proxy je nastavljen na samodejno konfiguriranje.</translation>
<translation id="2030481566774242610">Ali ste mislili <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />preveriti strežnik proxy in požarni zid<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Področje</translation>
<translation id="2102134110707549001">Predlagaj zapleteno geslo …</translation>
<translation id="2108755909498034140">Znova zaženite računalnik</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kartica</translation>
<translation id="2114841414352855701">Prezrto, ker je to preglasil pravilnik <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Mobilni zaznamki</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">Pravilniki</translation>
<translation id="2183608646556468874">Telefonska številka</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 naslov}one{# naslov}two{# naslova}few{# naslovi}other{# naslovov}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonska številka</translation>
<translation id="2283340219607151381">Shranjevanje in izpolnjevanje naslovov</translation>
<translation id="2292556288342944218">Internetni dostop je blokiran</translation>
+<translation id="2294558542833290837">Povezava, ki ste jo prvotno odprli, je nenavadna</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">Sprosti manj kot 1 MB. Nekatera spletna mesta se bodo ob naslednjem obisku morda počasneje naložila.</translation>
<translation id="2317259163369394535">Domena <ph name="DOMAIN" /> zahteva uporabniško ime in geslo.</translation>
<translation id="2317583587496011522">Sprejema debetne kartice.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, poteče <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Nastavitev nadzira vaš skrbnik</translation>
+<translation id="2346319942568447007">Slika, ki ste jo kopirali</translation>
<translation id="2349790679044093737">Seja VR je aktivna</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Uporabljate zasebni način</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Strežnik, na katerega greste (<ph name="ORIGIN" />), je zahteval, da se
+ za vse zahteve, ki so mu poslane, uporabi varnostni pravilnik. Vendar pa zdaj
+ ni zagotovil pravilnika, kar brskalniku preprečuje,
+ da bi izpolnil vašo zahtevo za <ph name="SITE" />.</translation>
<translation id="244665789865330679">Vašo napravo in račun upravlja domena <ph name="ENROLLMENT_DOMAIN" />. To pomeni, da lahko skrbnik na daljavo konfigurira vašo napravo in račun.</translation>
<translation id="2463193859425327265">Spremeni domačo stran</translation>
<translation id="2463739503403862330">Izpolni</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Izbira načina dostave</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Izvajanje orodja za omrežno diagnostiko<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Prevede to stran</translation>
<translation id="2479410451996844060">Neveljaven URL iskanja.</translation>
<translation id="2482878487686419369">Obvestila</translation>
<translation id="248348093745724435">Pravilniki naprave</translation>
+<translation id="2485387744899240041">Uporabniška imena za napravo in brskalnik</translation>
<translation id="2491120439723279231">V potrdilu strežnika so napake.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Optično branje nove kartice</translation>
<translation id="2501278716633472235">Nazaj</translation>
<translation id="2503184589641749290">Sprejete debetne in predplačniške kartice</translation>
<translation id="2515629240566999685">preveriti signal na svojem območju</translation>
-<translation id="2516852381693169964">Iskanje slike v iskalniku <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Shranjena samo v tej napravi</translation>
<translation id="2524461107774643265">Dodajanje več podatkov</translation>
<translation id="2536110899380797252">Dodaj naslov</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">Ura prehiteva</translation>
<translation id="2634124572758952069">Naslova IP strežnika <ph name="HOST_NAME" /> ni bilo mogoče najti.</translation>
<translation id="2639739919103226564">Stanje:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Zaprite druge zavihke ali aplikacije</translation>
<translation id="267371737713284912">pritisk tipke <ph name="MODIFIER_KEY_DESCRIPTION" /> za razveljavitev</translation>
<translation id="2674170444375937751">Ali ste prepričani, da želite te strani izbrisati iz svoje zgodovine?</translation>
+<translation id="2676271551327853224">ROC 16K</translation>
<translation id="2677748264148917807">Zapusti</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Sprejete kartice</translation>
<translation id="2702801445560668637">Reading List</translation>
<translation id="2704283930420550640">Vrednost se ne ujema z obliko.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Odstrani izbrane elemente</translation>
<translation id="277133753123645258">Način pošiljanja</translation>
<translation id="277499241957683684">Manjka zapis o napravi</translation>
-<translation id="2781030394888168909">Izvozi za macOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Povezava je bila obnovljena.</translation>
<translation id="2788784517760473862">Sprejete kreditne kartice</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Odpri novo okno brez beleženja zgodovine</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">Za obisk tega spletnega mesta potrebujete dovoljenje</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Želite shraniti kartico?</translation>
<translation id="2903493209154104877">Naslovi</translation>
<translation id="290376772003165898">Stran ni v jeziku <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Način dostave</translation>
<translation id="2928905813689894207">Naslov za izstavitev računa</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">Napačna vrsta pravilnika</translation>
<translation id="3037605927509011580">Ti šment!</translation>
<translation id="3041612393474885105">Informacije o potrdilu</translation>
+<translation id="3060227939791841287">C9 (Envelope)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Dodajanje naslova za prevzem</translation>
<translation id="3105172416063519923">ID sredstva:</translation>
<translation id="3109728660330352905">Nimate dovoljenja za ogled te strani.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> v strežniku <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Prekliči plačilo</translation>
<translation id="3207960819495026254">Dodano med zaznamke</translation>
-<translation id="3209375525920864198">Vnesite veljavno ime seje.</translation>
+<translation id="321912867715453276">Opozorilo: Za pravilnik je več virov, vendar so vrednosti enake.</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="3229041911291329567">Podatki o različici za napravo in brskalnik</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="3274521967729236597">Pa Kai</translation>
<translation id="3282497668470633863">Dodajanje imena na kartico</translation>
<translation id="3287510313208355388">Prenesi, ko je povezava</translation>
<translation id="3293642807462928945">Preberite več o pravilniku <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Ni rezultatov iskanja</translation>
-<translation id="3305707030755673451">Podatki so bili šifrirani z vašim geslom za sinhronizacijo <ph name="TIME" />. Vnesite ga, če želite začeti sinhronizacijo.</translation>
<translation id="3320021301628644560">Dodajanje naslova za izstavitev računa</translation>
<translation id="3324983252691184275">Škrlatna</translation>
<translation id="3338095232262050444">Varno</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Uveljavi urejanje</translation>
<translation id="342781501876943858">Chromium priporoča, da ponastavite geslo, če ste ga uporabljali tudi na drugih spletnih mestih.</translation>
<translation id="3431636764301398940">Shrani to kartico v tej napravi</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Lastnik te naprave je izklopil igro z dinozavri</translation>
<translation id="3447884698081792621">Prikaz potrdila (izdal: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Interval prejemanja:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">Označevalnik</translation>
<translation id="3462200631372590220">Skrij podrobnosti</translation>
<translation id="3467763166455606212">Ime imetnika kartice je obvezno</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Sprejema kreditne in predplačniške kartice.</translation>
<translation id="3582930987043644930">Dodajte ime</translation>
<translation id="3583757800736429874">&amp;Uveljavi premik</translation>
+<translation id="35866233670761917">Vsebina spletnih mest, ki jih obiščete, vašim skrbnikom ni vidna</translation>
<translation id="3586931643579894722">Skrij podrobnosti</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Velikost 2</translation>
<translation id="3615877443314183785">Vnesite veljaven datum poteka veljavnosti</translation>
<translation id="36224234498066874">Izbriši podatke brskanja ...</translation>
<translation id="362276910939193118">Prikaži celotno zgodovino</translation>
-<translation id="3623476034248543066">Pokaži vrednost</translation>
<translation id="3630155396527302611">Če je že na seznamu programov, ki jim je dovoljen dostop do omrežja, ga poskusite
odstraniti s seznama in znova dodati.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Preverjanje veljavnosti uspešno</translation>
<translation id="3655670868607891010">Če se to pogosto zgodi, poskusite <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Različica</translation>
<translation id="366077651725703012">Posodobi kreditno kartico</translation>
<translation id="3676592649209844519">ID naprave:</translation>
+<translation id="3677008721441257057">Ali ste mislili &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Zahteve ni bilo mogoče podpisati</translation>
<translation id="3678529606614285348">Odpiranje strani v novem oknu brez beleženja zgodovine (Ctrl + Shift + N)</translation>
<translation id="3679803492151881375">Poročilo o zrušitvi je bilo zajeto takrat: <ph name="CRASH_TIME" />, naloženo takrat: <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Omrežje, ki ga uporabljate, morda zahteva, da obiščete stran za prijavo.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Nalaganje ...</translation>
+<translation id="3709599264800900598">Besedilo, ki ste ga kopirali</translation>
<translation id="3712624925041724820">Ni dovolj licenc</translation>
<translation id="3714780639079136834">vklopiti prenos podatkov v mobilnih omrežjih ali Wi-Fi</translation>
<translation id="3715597595485130451">Vzpostavljanje povezave z omrežjem Wi-Fi</translation>
<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="372429172604983730">Aplikacije, ki lahko povzročijo to napako, so med drugim protivirusni program, požarni zid, programska oprema za spletno filtriranje ali strežnik proxy.</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kartici iz Google Računa.</translation>
<translation id="3748148204939282805">Napadalci na <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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Poteče: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Velikost 16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">Škodljiva vsebina je bila blokirana.</translation>
<translation id="3810973564298564668">Upravljanje</translation>
<translation id="382518646247711829">Če uporabite namestniški strežnik ...</translation>
<translation id="3828924085048779000">Prazno geslo ni dovoljeno.</translation>
+<translation id="3831915413245941253">Domena <ph name="ENROLLMENT_DOMAIN" /> je namestila razširitve zaradi dodatnih funkcij. Razširitve imajo dostop do nekaterih vaših podatkov.</translation>
<translation id="385051799172605136">Nazaj</translation>
<translation id="3858027520442213535">Posodobi datum in uro</translation>
<translation id="3884278016824448484">Identifikator naprave je v sporu</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> – <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Vedno vprašaj na tem spletnem mestu</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">To ime seje že obstaja.</translation>
<translation id="3987940399970879459">Manj kot 1 MB</translation>
+<translation id="4008849406247176967">Opozorilo: Za ta pravilnik je več virov z navzkrižnimi vrednostmi.</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="4030383055268325496">&amp;Razveljavi dodajanje</translation>
+<translation id="4032320456957708163">Brskalnik upravlja domena <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Ključ »<ph name="SUBKEY" />«: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">Dodajanje veljavnega naslova</translation>
<translation id="4072486802667267160">Pri obdelavi naročila je prišlo do napake. Poskusite znova.</translation>
<translation id="4075732493274867456">Odjemalec in strežnik ne podpirata skupne različice protokola SSL ali šifrirne zbirke.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Vijolična</translation>
<translation id="4165986682804962316">Nastavitve spletnega mesta</translation>
<translation id="4171400957073367226">Neveljavni podpis za preverjanje</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Še <ph name="ITEM_COUNT" /> element}one{Še <ph name="ITEM_COUNT" /> element}two{Še <ph name="ITEM_COUNT" /> elementa}few{Še <ph name="ITEM_COUNT" /> elementi}other{Še <ph name="ITEM_COUNT" /> elementov}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;1. korak: prijavite se v portal&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Ponastavi geslo</translation>
<translation id="4280429058323657511">, datum poteka veljavnosti: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Ta kartica je shranjena v Google Računu}one{Te kartice so shranjene v Google Računu}two{Te kartice so shranjene v Google Računu}few{Te kartice so shranjene v Google Računu}other{Te kartice so shranjene v Google Računu}}</translation>
+<translation id="42981349822642051">Razširi</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">Preklopi</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blokira (privzeto)</translation>
+<translation id="4318566738941496689">Ime naprave in omrežni naslov</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="4340982228985273705">Ta računalnik ni zaznan kot računalnik, ki ga upravlja podjetje, zato lahko pravilnik samodejno namesti samo razširitve, ki gostujejo v Spletni trgovini Chrome. URL za posodobitve v Spletni trgovini Chrome je »<ph name="CWS_UPDATE_URL" />«.</translation>
<translation id="4346197816712207223">Sprejete kreditne kartice</translation>
+<translation id="4346833872170306413">ROC 16K</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="4358461427845829800">Upravljanje plačilnih sredstev ...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">rezultati iskanja</translation>
-<translation id="4406972042435603828">Skrbniki so namestili zmogljive razširitve.</translation>
<translation id="4408413947728134509">Piškotki <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Naslov za prevzem</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="443121186588148776">Serijska vrata</translation>
<translation id="4432688616882109544">Spletno mesto <ph name="HOST_NAME" /> ni sprejelo potrdila za prijavo ali pa to ni bilo posredovano.</translation>
<translation id="4434045419905280838">Pojavna okna in preusmeritve</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">Uporaba strežnika proxy je onemogočena, vendar je njegova konfiguracija izrecno določena.</translation>
<translation id="445100540951337728">Sprejete debetne kartice</translation>
+<translation id="4466881336512663640">Spremembe obrazca bodo izgubljene. Ali ste prepričani, da želite nadaljevati?</translation>
<translation id="4482953324121162758">To spletno mesto ne bo prevedeno.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Neveljaven URL. Mora biti URL s standardno shemo, kot je http://primer.com ali https://primer.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Envelope)</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="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">Podrobnosti</translation>
<translation id="4524805452350978254">Upravljanje kartic</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Poskusite onemogočiti razširitve.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Dostava</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">Odstranitev kartice</translation>
<translation id="4587425331216688090">Želite odstraniti naslov iz Chroma?</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="4597348597567598915">Velikost 8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">Odpri zdaj</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="467809019005607715">Google Predstavitve</translation>
<translation id="4690462567478992370">Prenehaj uporabljati neveljavno potrdilo</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Povezava je bila prekinjena</translation>
<translation id="471880041731876836">Nimate dovoljenja za obisk tega spletnega mesta</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Izvajanje orodja Omrežna diagnostika Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Znova naloži pravilnike</translation>
<translation id="4728558894243024398">Okolje</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">Znova zaženite Chromium</translation>
<translation id="473775607612524610">Posodobi</translation>
<translation id="4738601419177586157">Predlog za iskanje poizvedbe <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Upravljaj gesla …</translation>
<translation id="4744603770635761495">Pot do izvedljive datoteke</translation>
+<translation id="4746351372139058112">Sporočila</translation>
<translation id="4750917950439032686">Vaši podatki (npr. gesla ali številke kreditnih kartic) so zasebni, kadar so poslani temu spletnemu mestu.</translation>
<translation id="4756388243121344051">&amp;Zgodovina</translation>
<translation id="4758311279753947758">Dodaj podatke za stik</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Spletna stran na naslovu <ph name="URL" /> morda začasno ne deluje ali pa je trajno premaknjena na novi spletni naslov.</translation>
<translation id="4771973620359291008">Prišlo je do neznane napake.</translation>
<translation id="4785689107224900852">Preklop na ta zavihek</translation>
-<translation id="4792143361752574037">Pri dostopanju do datotek seje je prišlo do težave. Shranjevanje na disk je trenutno onemogočeno. Znova naložite stran, če želite poskusiti znova.</translation>
<translation id="4798078619018708837">Vnesite datum poteka in CVC za kreditno kartico <ph name="CREDIT_CARD" />, da posodobite podatke o kartici. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kreditni kartici iz Google Računa.</translation>
<translation id="4800132727771399293">Preverite datum poteka in številko CVC ter poskusite znova</translation>
+<translation id="480334179571489655">Napaka pravilnika o izvoru</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Odpri</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Ni rezultatov</translation>
<translation id="4950898438188848926">Gumb za preklop zavihkov, pritisnite Enter, če želite preklopiti na odprti zavihek, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Dejanja</translation>
-<translation id="495832697253704892">Poročanje o razširitvah</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Razširi seznam</translation>
<translation id="4974590756084640048">Vnovično omogočanje opozoril</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">Pokaži vse</translation>
<translation id="4989809363548539747">Ta vtičnik ni podprt</translation>
-<translation id="4996230189582812866">Poročanje</translation>
<translation id="5002932099480077015">Če je to omogočeno, Chrome shrani kopijo kartice v tej napravi zaradi hitrejšega izpolnjevanja obrazcev.</translation>
-<translation id="5014174725590676422">Prikazan je zaslon za prvi zagon Pomočnika Google v Chromu</translation>
<translation id="5015510746216210676">Ime naprave:</translation>
+<translation id="5017554619425969104">Besedilo, ki ste ga kopirali</translation>
<translation id="5018422839182700155">Te strani ni mogoče odpreti</translation>
<translation id="5019198164206649151">Neprimerno stanje rezervne shrambe</translation>
<translation id="5023310440958281426">Preverite skrbnikove pravilnike</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Lokalni kontekst <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Dovoli</translation>
<translation id="5040262127954254034">Zasebnost</translation>
+<translation id="5043480802608081735">Povezava, ki ste jo kopirali</translation>
<translation id="5045550434625856497">Nepravilno geslo</translation>
<translation id="5056549851600133418">Članki za vas</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />preveriti naslov strežnika proxy<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Potrdilo strežnika trenutno ni veljavno.</translation>
<translation id="5087580092889165836">Dodaj kartico</translation>
<translation id="5089810972385038852">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="5097099694988056070">Statistični podatki naprave, kot je uporaba CPE-ja/RAM-a</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Vašo napravo upravlja <ph name="ENROLLMENT_DOMAIN" /> in vaš račun upravlja <ph name="ACCOUNT_DOMAIN" />. To pomeni, da lahko skrbnika na daljavo konfigurirata napravo in račun.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-bitno)</translation>
-<translation id="5128122789703661928">Seja s tem imenom ni veljavna za izbris.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Upravljanje naslovov ...</translation>
+<translation id="5138227688689900538">Pokaži manj</translation>
<translation id="5141240743006678641">Šifrirajte sinhronizirana gesla s poverilnicami za Google</translation>
<translation id="5145883236150621069">Koda napake v odzivu pravilnika</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">Odpiranje strani v novem oknu brez beleženja zgodovine (⇧⌘N)</translation>
<translation id="516920405563544094">Vnesite CVC za kreditno kartico <ph name="CREDIT_CARD" />. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kreditni kartici iz Google Računa.</translation>
<translation id="5169827969064885044">Izgubite lahko dostop do računa za organizacijo ali postanete žrtev kraje identitete. Chrome priporoča, da spremenite geslo.</translation>
<translation id="5171045022955879922">Poiščite ali vnesite URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Računalnik</translation>
<translation id="5179510805599951267">Ni v <ph name="ORIGINAL_LANGUAGE" />? Obvestite nas o tej napaki</translation>
<translation id="5190835502935405962">Vrstica z zaznamki</translation>
-<translation id="5200263511887412697">poročanje o seznamu nedavno prijavljenih uporabnikov naprave</translation>
+<translation id="519422657042045905">Pripisi niso na voljo</translation>
<translation id="5201306358585911203">Vdelana stran na tej spletni strani sporoča:</translation>
<translation id="5205222826937269299">Ime je obvezno</translation>
<translation id="5215116848420601511">Plačilna sredstva in naslovi z Googlom Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-poštni naslov je obvezen</translation>
<translation id="5230733896359313003">Naslov za pošiljanje</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">»Vzpostavite povezavo z omrežjem«</translation>
<translation id="5251803541071282808">Oblak</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Omrežni naslovi</translation>
<translation id="5285570108065881030">Prikaži vsa shranjena gesla</translation>
<translation id="5287240709317226393">Pokaži piškotke</translation>
<translation id="5288108484102287882">Preverjanje vrednosti pravilnika je aktiviralo opozorila</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> od <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Izbira podatkov za stik</translation>
<translation id="5327248766486351172">Ime</translation>
+<translation id="5329858041417644019">Vaš brskalnik ni upravljan</translation>
<translation id="5332219387342487447">Način pošiljanja</translation>
+<translation id="5334013548165032829">Podrobni sistemski dnevniki</translation>
<translation id="5344579389779391559">Ta stran vam bo morda poskusila kaj zaračunati</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">Ura zaostaja« ali »Ura prehiteva« ali »&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;«</translation>
<translation id="5384855140246857529">Če želite uporabljati kartice v vseh napravah, se prijavite in vklopite sinhronizacijo.</translation>
<translation id="5386426401304769735">Veriga potrdil za to spletno mesto vsebuje potrdilo, podpisano z algoritmom SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Neveljavno</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Uveljavi urejanje</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">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="54817484435770891">Dodajanje veljavnega naslova</translation>
<translation id="5490432419156082418">Naslovi in drugo</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Poskusite se obrniti na skrbnika sistema.</translation>
<translation id="549333378215107354">Velikost 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Upravljani zaznamki</translation>
<translation id="5510766032865166053">Morda je premaknjena ali izbrisana.</translation>
<translation id="5523118979700054094">Ime pravilnika</translation>
<translation id="552553974213252141">Ali je bilo besedilo pravilno izvlečeno?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">Zahtevanega članka ni bilo mogoče najti.</translation>
<translation id="5541546772353173584">Dodajanje e-poštnega naslova</translation>
<translation id="5545756402275714221">Članki za vas</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Uredi naslov</translation>
<translation id="5598944008576757369">Izbira plačilnega sredstva</translation>
<translation id="560412284261940334">Upravljanje ni podprto</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996">Spletno mesto <ph name="HOST_NAME" /> vas je prevečkrat preusmerilo.</translation>
<translation id="5629630648637658800">Nastavitev pravilnika ni bilo mogoče naložiti</translation>
<translation id="5631439013527180824">Neveljaven žeton za upravljanje naprave</translation>
+<translation id="5632627355679805402">Vaši podatki so bili ob <ph name="TIME" /> šifrirani z vašim <ph name="BEGIN_LINK" />geslom za Google<ph name="END_LINK" />. Če želite začeti sinhronizacijo, ga vnesite.</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="563324245173044180">Zavajajoča vsebina blokirana.</translation>
<translation id="5659593005791499971">E-pošta</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">Skrbnik te naprave je namestil razširitve zaradi dodatnih funkcij. Razširitve imajo dostop do nekaterih vaših podatkov.</translation>
<translation id="5675650730144413517">Ta stran ne deluje</translation>
+<translation id="5684874026226664614">Ojoj, te strani bi bilo mogoče prevesti.</translation>
<translation id="5685654322157854305">Dodajanje naslova za pošiljanje</translation>
<translation id="5689199277474810259">Izvozi v JSON</translation>
<translation id="5689516760719285838">Lokacija</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Identiteta tega spletnega mesta ni bila potrjena.</translation>
<translation id="5719499550583120431">Sprejema predplačniške kartice.</translation>
<translation id="5720705177508910913">Trenutni uporabnik</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">Chrome priporoča, da ponastavite geslo, če ste ga uporabljali na drugih spletnih mestih.</translation>
<translation id="5732392974455271431">Starši ga lahko odblokirajo</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Shranjevanje kartice v Google Računu}one{Shranjevanje kartic v Google Računu}two{Shranjevanje kartic v Google Računu}few{Shranjevanje kartic v Google Računu}other{Shranjevanje kartic v Google Računu}}</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="5770114862687765385">Videti je, da je datoteka poškodovana. Kliknite gumb »Ponastavi«, da ponastavite sejo.</translation>
<translation id="5778550464785688721">Popolni nadzor naprav MIDI</translation>
<translation id="578305955206182703">Jantarna</translation>
<translation id="57838592816432529">Izklopi zvok</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>
+<translation id="5798290721819630480">Želite zavreči spremembe?</translation>
<translation id="5798683403665926540">Spremenite domačo stran v Chromovih nastavitvah</translation>
<translation id="5803412860119678065">Ali želite izpolniti podatke za kartico <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Dovoljenja</translation>
<translation id="5810442152076338065">Povezava z domeno <ph name="DOMAIN" /> je šifrirana z zastarelo šifrirno zbirko.</translation>
<translation id="5813119285467412249">&amp;Uveljavi dodajanje</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="5860033963881614850">Izklopljeno</translation>
<translation id="5863847714970149516">Stran, ki se bo odprla, vam bo morda poskusila kaj zaračunati</translation>
<translation id="5866257070973731571">Dodajanje telefonske številke</translation>
<translation id="5869405914158311789">Tega spletnega mesta ni mogoče doseči</translation>
<translation id="5869522115854928033">Shranjena gesla</translation>
<translation id="5887400589839399685">Kartica je shranjena</translation>
-<translation id="5893718151540690985">poročanje seznama omrežnih vmesnikov z vrstami in naslovi strojne opreme.</translation>
<translation id="5893752035575986141">Sprejema kreditne kartice.</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="5916664084637901428">Vklopljeno</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Ali želite kartico shraniti v Google Račun?</translation>
<translation id="5922853866070715753">Skoraj končano</translation>
<translation id="5932224571077948991">Spletno mesto prikazuje vsiljive ali zavajajoče oglase</translation>
-<translation id="5939518447894949180">Ponastavi</translation>
<translation id="5946937721014915347">Odpiranje spletnega mesta <ph name="SITE_NAME" /> …</translation>
<translation id="5951495562196540101">S potrošniškim računom se ni mogoče včlaniti (na voljo je pridružena licenca).</translation>
<translation id="5967592137238574583">Urejanje podatkov o stiku</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Pomanjšaj</translation>
<translation id="5977489021191000276">Vaše naprave ne upravlja skrbnik.</translation>
<translation id="5977976211062815271">V tej napravi</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Plačilne aplikacije ni mogoče odpreti</translation>
<translation id="5989320800837274978">Določeni niso ne stalni strežniki proxy ne URL skripta .pac.</translation>
<translation id="5990559369517809815">Zahteve za strežnik je blokirala razširitev.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">poročanje statističnih podatkov o strojni opremi, kot je uporaba CPE-ja/RAM-a</translation>
<translation id="6034000775414344507">Svetlo siva</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">Če težave ne odpravite, se obrnite na lastnika spletnega mesta.</translation>
<translation id="6040143037577758943">Zapri</translation>
<translation id="6044573915096792553">Velikost 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Želite kartice uporabljati v vseh svojih napravah?</translation>
<translation id="6059925163896151826">Naprave USB</translation>
-<translation id="6071091556643036997">Vrsta pravilnika je neveljavna.</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="6094273045989040137">Pripisovanje</translation>
<translation id="610911394827799129">V Google Računu so morda druge vrste zgodovine brskanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Podatki o nameščenih razširitvah in vtičnikih</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Sprosti manj kot <ph name="SIZE" />. Nekatera spletna mesta se bodo ob naslednjem obisku morda počasneje naložila.</translation>
<translation id="6337534724793800597">Filtriraj pravilnike po imenu</translation>
<translation id="6358450015545214790">Več o teh nastavitvah</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Morda bo prišlo do bremenitev.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{in še 1 predlog}one{in še # predlog}two{in še # predloga}few{in še # predlogi}other{in še # predlogov}}</translation>
<translation id="6387754724289022810">Če želite naslednjič hitreje plačati, shranite kartico in naslov za izstavitev računa v Google Računu in v tej napravi.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Uredi zaznamek</translation>
+<translation id="6406765186087300643">C0 (Envelope)</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="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="6434309073475700221">Zavrzi</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">Dodajanje več podatkov</translation>
<translation id="6447842834002726250">Piškotki</translation>
<translation id="6451458296329894277">Potrdite ponovno pošiljanje obrazca</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Znova zaženite Chrome</translation>
<translation id="6529602333819889595">&amp;Uveljavi izbris</translation>
<translation id="6534179046333460208">Predlogi za Fizični splet</translation>
+<translation id="6556866813142980365">Uveljavi</translation>
<translation id="6563469144985748109">Skrbnik še ni odobril</translation>
<translation id="6569060085658103619">Ogledujete si stran razširitve</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">Svetlo rožnata</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">Povezava, ki ste jo kopirali</translation>
+<translation id="6591833882275308647">Naprava <ph name="DEVICE_TYPE" /> ni upravljana</translation>
<translation id="6596325263575161958">Možnosti šifriranja</translation>
<translation id="6604181099783169992">Tipala za gibanje in svetlobe</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">Podatki o stiku</translation>
<translation id="6626291197371920147">Dodajanje veljavne številke kartice</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Iskanje</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Ta pravilnik je zastarel.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Nič}=1{Na 1 spletnem mestu (iz Google Računa ne boste odjavljeni)}one{Na # spletnem mestu (iz Google Računa ne boste odjavljeni)}two{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}few{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}other{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}}</translation>
<translation id="6657585470893396449">Geslo</translation>
+<translation id="6670613747977017428">Nazaj na varno.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Žeton za včlanitev:</translation>
<translation id="6711464428925977395">Nekaj je narobe s strežnikom proxy ali pa naslov ni pravilen.</translation>
<translation id="6723740634201835758">V računu za Google</translation>
+<translation id="6738516213925468394">Podatki so bili šifrirani (<ph name="TIME" />) z vašim <ph name="BEGIN_LINK" />geslom za sinhronizacijo<ph name="END_LINK" />. Vnesite ga, če želite začeti sinhronizacijo.</translation>
<translation id="674375294223700098">Neznana napaka potrdila strežnika.</translation>
<translation id="6744009308914054259">Med čakanjem na povezavo lahko berete članke za branje brez povezave med prenosi.</translation>
<translation id="6753269504797312559">Vrednost pravilnika</translation>
<translation id="6757797048963528358">Naprava je preklopila v stanje pripravljenosti.</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">Starši še niso odobrili</translation>
<translation id="67862343314499040">Vijoličnomodra</translation>
+<translation id="6786747875388722282">Razširitve</translation>
<translation id="679355240208270552">Prezrto, ker pravilnik ne omogoča privzetega iskanja.</translation>
<translation id="681021252041861472">Obvezno polje</translation>
<translation id="6810899417690483278">ID za prilagajanje</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Naprava</translation>
<translation id="6970216967273061347">Okrožje</translation>
<translation id="6973656660372572881">Določeni so stalni strežniki proxy in URL skripta .pac.</translation>
+<translation id="6973932557599545801">Ne morem vam pomagati. Nadaljujte sami.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Izklop zvoka (privzeto)</translation>
<translation id="6984479912851154518">Zaradi plačila v zunanji aplikaciji boste zapustili zasebni način. Želite nadaljevati?</translation>
<translation id="6989763994942163495">Prikaži dodatne nastavitve ...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">Vedno prevedi ta jezik: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Te bremenitve so lahko enkratne ali ponavljajoče se in morda niso očitne.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Skrij</translation>
<translation id="7108819624672055576">Omogoča razširitev</translation>
<translation id="7111012039238467737">(veljavno)</translation>
+<translation id="7118618213916969306">Iskanje URL-ja v odložišču, <ph name="SHORT_URL" /></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="7135130955892390533">Prikaz stanja</translation>
<translation id="7138472120740807366">Način dostave</translation>
<translation id="7139724024395191329">Emirat:</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Svetlo vijolična</translation>
-<translation id="7158980942472052083">Neveljaven URL. URL mora imeti standardno shemo.</translation>
<translation id="717330890047184534">ID za Gaio:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Strežnik, na katerega greste (<ph name="ORIGIN" />), je zahteval, da se
+ za vse zahteve, ki so mu poslane, uporabi varnostni pravilnik. Vendar pa ni
+ zagotovil pravilnika, temveč je brskalnik preusmeril drugam, kar brskalniku preprečuje,
+ da bi izpolnil vašo zahtevo za <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Shranjevanje in izpolnjevanje podatkov o plačilnih sredstvih</translation>
<translation id="7180611975245234373">Osveži</translation>
<translation id="7182878459783632708">Ni nastavljenih pravilnikov</translation>
<translation id="7186367841673660872">Ta stran je bila prevedena iz jezika<ph name="ORIGINAL_LANGUAGE" />v jezik<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Sprosti <ph name="SIZE" />. Nekatera spletna mesta se bodo ob naslednjem obisku morda počasneje naložila.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Skrbniku je prikazano to:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Spletno mesto <ph name="HOST_NAME" /> ne upošteva varnostnih standardov.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Več o<ph name="END_LINK" /> tej težavi.</translation>
<translation id="7219179957768738017">Povezava uporablja <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Obdelovanje</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Spletno mesto z zlonamerno programsko opremo</translation>
+<translation id="724766306220616965">Opozorila, navzkrižje</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="7251437084390964440">Omrežna konfiguracija ne ustreza standardu ONC. Deli konfiguracije morda niso bili uvoženi.
Dodatne podrobnosti:
@@ -982,11 +1120,14 @@ Dodatne podrobnosti:
<translation id="7300012071106347854">Kobaltovo modra</translation>
<translation id="7302712225291570345">»<ph name="TEXT" />«</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="7313965965371928911">Opozorila za <ph name="BEGIN_LINK" />varno brskanje<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Pomoč pri povezavi</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Ukazna vrstica</translation>
-<translation id="7365061714576910172">Izvozi za Linux</translation>
<translation id="7372973238305370288">rezultat iskanja</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> – <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ne</translation>
@@ -994,6 +1135,7 @@ Dodatne podrobnosti:
<translation id="7381288752349550461">Preglasitev upravljane seje</translation>
<translation id="7390545607259442187">Potrditev kartice</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Naprava <ph name="DEVICE_NAME" /> je upravljana</translation>
<translation id="7407424307057130981">&lt;p&gt;To napako boste videli, če imate v računalniku s sistemom Windows programsko opremo Superfish.&lt;/p&gt;
&lt;p&gt;Upoštevajte ta navodila, če želite začasno onemogočiti programsko opremo, da se boste lahko povezali v splet. Potrebujete skrbniške pravice.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Dodatne podrobnosti:
&lt;li&gt;Kliknite &lt;strong&gt;Uporabi&lt;/strong&gt; in nato &lt;strong&gt;V redu&lt;/strong&gt;.
&lt;li&gt;Obiščite &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;center za pomoč za Chrome&lt;/a&gt; če želite izvedeti, kako programsko opremo trajno odstranite iz računalnika.
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Upravljanje storitve <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Upravljaj gesla …</translation>
<translation id="7419106976560586862">Pot profila</translation>
<translation id="7437289804838430631">Dodaj podatke o stiku</translation>
@@ -1013,22 +1155,24 @@ Dodatne podrobnosti:
<translation id="7442725080345379071">Svetlo oranžna</translation>
<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="7449109375006139765">pošiljanje sistemskih dnevnikov v strežnik za upravljanje</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="7460618730930299168">Predvajanje se razlikuje od tega, kar ste izbrali. Želite nadaljevati?</translation>
<translation id="7473891865547856676">Ne, hvala</translation>
-<translation id="7475525192983021547">poročanje časovnih obdobij, ko je uporabnik aktiven v napravi</translation>
<translation id="7481312909269577407">Naprej</translation>
<translation id="7485870689360869515">Ni podatkov.</translation>
+<translation id="7498234416455752244">Nadaljuj urejanje</translation>
<translation id="7508255263130623398">Vrnjen ID naprave pravilnika je prazen ali se ne ujema s trenutnim ID-jem naprave</translation>
<translation id="7508870219247277067">Avokadovo zelena</translation>
<translation id="7511955381719512146">Omrežje Wi-Fi, ki ga uporabljate, morda zahteva, da obiščete <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Povezava s tem mestom ni zasebna</translation>
+<translation id="7535087603100972091">Vrednost</translation>
<translation id="7537536606612762813">Obvezen</translation>
+<translation id="7538364083937897561">A2 (Envelope)</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>
@@ -1037,8 +1181,8 @@ Dodatne podrobnosti:
<translation id="7552846755917812628">Poskusite te nasvete:</translation>
<translation id="7554791636758816595">Nov zavihek</translation>
<translation id="7564049878696755256">Izgubite lahko dostop do računa za <ph name="ORG_NAME" /> ali postanete žrtev kraje identitete. Chrome priporoča, da spremenite geslo.</translation>
-<translation id="7566125604157659769">Besedilo, ki ste ga kopirali</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="7568105740864181217">Ta brskalnik upravlja podjetje, šola ali druga organizacija. Skrbnik lahko spremeni nastavitev brskalnika na daljavo. Dejavnost v tej napravi morda tudi upravljajo zunaj Chroma. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Dodatne podrobnosti:
<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="7633909222644580952">Podatki o delovanju in poročila o zrušitvah</translation>
<translation id="7637571805876720304">Želite kreditno kartico odstraniti iz Chromiuma?</translation>
<translation id="7639968568612851608">Temno siva</translation>
<translation id="765676359832457558">Skrij dodatne nastavitve ...</translation>
@@ -1058,9 +1203,11 @@ Dodatne podrobnosti:
<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="7676643023259824263">Iskanje besedila v odložišču, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Zamenjaj iskalnik</translation>
<translation id="7682287625158474539">Pošiljanje</translation>
<translation id="7687186412095877299">Izpolni obrazce za plačilo s shranjenimi podatki o plačilnih sredstvih</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">Trenutno je mogoče nekatere vaše kartice uporabljati samo v tej napravi. Kliknite »Naprej«, če si želite ogledati kartice.</translation>
<translation id="7699293099605015246">Članki trenutno niso na voljo</translation>
<translation id="7701040980221191251">Brez</translation>
@@ -1072,11 +1219,13 @@ Dodatne podrobnosti:
<translation id="774634243536837715">Nevarna vsebina blokirana.</translation>
<translation id="7752995774971033316">Odstranjen iz uporabe</translation>
<translation id="7755287808199759310">Starš ga lahko odblokira</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Povezavo je morda blokiral požarni zid ali protivirusni program.</translation>
<translation id="7759163816903619567">Prikaz domene:</translation>
<translation id="7761701407923456692">Potrdilo strežnika se ne ujema z URL-jem.</translation>
<translation id="7763386264682878361">Razčlenjevalnik manifesta plačil</translation>
<translation id="7764225426217299476">Dodaj naslov</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektura</translation>
<translation id="7791543448312431591">Dodaj</translation>
<translation id="7793809570500803535">Spletna stran na <ph name="SITE" /> morda začasno ne deluje ali pa je trajno premaknjena na nov spletni naslov.</translation>
@@ -1088,8 +1237,8 @@ Dodatne podrobnosti:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Želite odstraniti predlog obrazca iz Chroma?</translation>
<translation id="7815407501681723534">Za »<ph name="SEARCH_STRING" />« je bilo najdenih toliko <ph name="SEARCH_RESULTS" />: <ph name="NUMBER_OF_RESULTS" />.</translation>
-<translation id="7818867226424560206">Upravljanje pravilnikov</translation>
<translation id="782886543891417279">Omrežje Wi-Fi, ki ga uporabljate (<ph name="WIFI_NAME" />), morda zahteva, da obiščete stran za prijavo.</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Brez}=1{1 aplikacija (<ph name="EXAMPLE_APP_1" />)}=2{2 aplikaciji (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# aplikacija (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}two{# aplikaciji (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}few{# aplikacije (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# aplikacij (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Kljub temu pa niste nevidni. Z uporabo načina brez beleženja zgodovine brskanja ne skrijete pred delodajalcem, ponudnikom internetnih storitev ali spletnimi mesti, ki jih obiščete.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@ Dodatne podrobnosti:
<translation id="7878562273885520351">Geslo je morda ogroženo</translation>
<translation id="7882421473871500483">Rjava</translation>
<translation id="7887683347370398519">Preverite CVC in poskusite znova</translation>
-<translation id="7893255318348328562">Ime seje</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">Vnesite veljavno telefonsko številko</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Poteče <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Dodatne podrobnosti:
<translation id="7951415247503192394">(32-bitno)</translation>
<translation id="7956713633345437162">Mobilni zaznamki</translation>
<translation id="7961015016161918242">Nikoli</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Ni navedeno</translation>
<translation id="800218591365569300">Poskusite zapreti druge zavihke ali programe, da boste tako sprostili pomnilnik.</translation>
+<translation id="8004582292198964060">Brskalnik</translation>
<translation id="8009225694047762179">Upravljanje gesel</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Shranjena bosta ta kartica in njen naslov za izstavitev računa. Uporabljali jo boste lahko, ko boste prijavljeni v račun <ph name="USER_EMAIL" />.}one{Shranjene bodo te kartice in njihovi naslovi za izstavitev računa. Uporabljali jih boste lahko, ko boste prijavljeni v račun <ph name="USER_EMAIL" />.}two{Shranjene bodo te kartice in njihovi naslovi za izstavitev računa. Uporabljali jih boste lahko, ko boste prijavljeni v račun <ph name="USER_EMAIL" />.}few{Shranjene bodo te kartice in njihovi naslovi za izstavitev računa. Uporabljali jih boste lahko, ko boste prijavljeni v račun <ph name="USER_EMAIL" />.}other{Shranjene bodo te kartice in njihovi naslovi za izstavitev računa. Uporabljali jih boste lahko, ko boste prijavljeni v račun <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Ta stran je v jeziku <ph name="SOURCE_LANGUAGE" />. Jo želite prevesti v jezik <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Pisalo</translation>
+<translation id="8037117624646282037">Kdo je nedavno uporabljal napravo</translation>
<translation id="8037357227543935929">Zahteva (privzeto)</translation>
<translation id="803771048473350947">Datoteka</translation>
<translation id="8041089156583427627">Pošlji povratne informacije</translation>
<translation id="8041940743680923270">Uporabi globalno privzeto (Vprašaj)</translation>
<translation id="8042918947222776840">Izbira načina prevzema</translation>
<translation id="8057711352706143257">Programska oprema »<ph name="SOFTWARE_NAME" />« ni pravilno konfigurirana. Običajno težavo odpravite tako, da odstranite programsko opremo »<ph name="SOFTWARE_NAME" />«. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Vaša naprava je konfigurirana za to:</translation>
+<translation id="8066955247577885446">Prišlo je do napake.</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">Ko je dokument zasukan, pripisovanje ni mogoče</translation>
<translation id="8079031581361219619">Želite znova naložiti spletno mesto?</translation>
<translation id="8088680233425245692">Članka si ni bilo mogoče ogledati.</translation>
@@ -1131,11 +1284,12 @@ Dodatne podrobnosti:
<translation id="8091372947890762290">Čakanje na aktivacijo v strežniku</translation>
<translation id="8092774999298748321">Močna vijolična</translation>
<translation id="8094917007353911263">Omrežje, ki ga uporabljate, morda zahteva, da obiščete <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Neveljavne kartice so odstranjene</translation>
<translation id="8103161714697287722">Plačilno sredstvo</translation>
<translation id="8118489163946903409">Plačilno sredstvo</translation>
+<translation id="8123836779274890062">Napravo <ph name="DEVICE_TYPE" /> upravlja domena <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Programska oprema »<ph name="SOFTWARE_NAME" />« ni bila pravilno nameščena v računalniku ali omrežju. Obrnite se na skrbnika za IT glede odpravljanja te težave.</translation>
-<translation id="8130693978878176684">Ne morem več pomagati. Nadaljujte sami.</translation>
<translation id="8131740175452115882">Potrdi</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>
@@ -1145,8 +1299,11 @@ Dodatne podrobnosti:
<translation id="8197543752516192074">Prevedi stran</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="8202370299023114387">Spor</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">Povezava je varna</translation>
<translation id="8218327578424803826">Dodeljena lokacija:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</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="8238581221633243064">Odpiranje strani v novem zavihku brez beleženja zgodovine.</translation>
@@ -1158,14 +1315,16 @@ Dodatne podrobnosti:
<translation id="825929999321470778">Prikaz vseh shranjenih gesel</translation>
<translation id="8261506727792406068">Izbriši</translation>
<translation id="8267698848189296333">Prijava kot: <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Ta brskalnik upravlja domena <ph name="ENROLLMENT_DOMAIN" />. Skrbnik lahko spremeni nastavitev brskalnika na daljavo. Dejavnost v tej napravi morda tudi upravljajo zunaj Chroma. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Prijava</translation>
<translation id="8288807391153049143">Prikaz potrdila</translation>
<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="8298115750975731693">Omrežje Wi-Fi, ki ga uporabljate (<ph name="WIFI_NAME" />), morda zahteva, da obiščete <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Prevod ni uspel zaradi težave s povezavo omrežja.</translation>
-<translation id="8311129316111205805">Naloži sejo</translation>
<translation id="8332188693563227489">Dostop do spletnega mesta <ph name="HOST_NAME" /> je bil zavrnjen</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Dodatne podrobnosti:
<translation id="8416694386774425977">Omrežna konfiguracija je neveljavna in je ni mogoče uvoziti.
Dodatne podrobnosti:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Napravo upravlja <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" />, <ph name="SECOND_LABEL" />, <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Spremeni</translation>
<translation id="8428213095426709021">Nastavitve</translation>
@@ -1210,9 +1368,11 @@ Dodatne podrobnosti:
<translation id="860043288473659153">Ime imetnika kartice</translation>
<translation id="861775596732816396">Velikost 4</translation>
<translation id="8620436878122366504">Starši še niso odobrili</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Shrani to kartico v tej napravi</translation>
<translation id="8663226718884576429">Povzetek naročila, <ph name="TOTAL_LABEL" />, več podrobnosti</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, odgovor, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Vaša povezava z <ph name="DOMAIN" /> ni kodirana.</translation>
<translation id="8718314106902482036">Plačilo ni končano</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, predlog iskanja</translation>
@@ -1226,6 +1386,7 @@ Dodatne podrobnosti:
<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="8763927697961133303">Naprava USB</translation>
<translation id="8768895707659403558">Če želite uporabljati kartice v vseh napravah, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Uveljavi izbris</translation>
<translation id="8792621596287649091">Izgubite lahko dostop do računa za <ph name="ORG_NAME" /> ali postanete žrtev kraje identitete. Chromium priporoča, da spremenite geslo.</translation>
<translation id="8800988563907321413">Tu so prikazani predlogi v bližini</translation>
@@ -1236,10 +1397,12 @@ Dodatne podrobnosti:
<translation id="885730110891505394">Deljenje z Googlom</translation>
<translation id="8858065207712248076">Chrome priporoča, da ponastavite geslo za <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, če ste ga uporabljali na drugih spletnih mestih.</translation>
<translation id="8866481888320382733">Napaka pri razčlenjevanju nastavitev pravilnika</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nedavno zaprto</translation>
<translation id="8874824191258364635">Vnesite veljavno številko kartice</translation>
<translation id="8891727572606052622">Neveljaven način strežnika proxy.</translation>
<translation id="8903921497873541725">Povečaj</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Ali želite to kartico shraniti v Google Račun?</translation>
<translation id="8932102934695377596">Ura zaostaja</translation>
<translation id="893332455753468063">Dodajanje imena</translation>
@@ -1247,13 +1410,13 @@ Dodatne podrobnosti:
<translation id="894185898663964645">Skrbnik je konfiguriral korenska potrdila po meri, ki skrbniku morda omogočajo ogled vsebine spletnih mest, ki jih obiščete.</translation>
<translation id="8943282376843390568">Rumenozelena</translation>
<translation id="8957210676456822347">Odobritev prestreznega portala</translation>
+<translation id="8966619695390250636">Ali ste morda mislili?</translation>
<translation id="8968766641738584599">Shrani kartico</translation>
<translation id="8971063699422889582">Potrdilo strežnika je poteklo.</translation>
<translation id="8975012916872825179">Vključuje podatke, kot so telefonske številke, e-poštni naslovi in naslovi za pošiljanje</translation>
<translation id="8978053250194585037">Google Varno brskanje je nedavno <ph name="BEGIN_LINK" />zaznalo lažno predstavljanje<ph name="END_LINK" /> 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="8983003182662520383">Plačilna sredstva in naslovi z Googlom Pay</translation>
<translation id="8987927404178983737">Mesec</translation>
-<translation id="8988408250700415532">Prišlo je do napake. Naročilo lahko dokončate na spletnem mestu.</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>
@@ -1263,6 +1426,7 @@ Dodatne podrobnosti:
<translation id="9011424611726486705">Odpiranje nastavitev spletnega mesta</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(neveljavno)</translation>
<translation id="9035022520814077154">Varnostna napaka</translation>
<translation id="9038649477754266430">Uporaba storitve predvidevanja za hitrejše nalaganje strani</translation>
@@ -1274,11 +1438,11 @@ Dodatne podrobnosti:
<translation id="9065745800631924235">Iskanje poizvedbe <ph name="TEXT" /> iz zgodovine</translation>
<translation id="9069693763241529744">Blokirala razširitev</translation>
<translation id="9076283476770535406">Morda vsebuje vsebino za odrasle</translation>
+<translation id="9076630408993835509">Tega brskalnika ne upravlja podjetje ali druga organizacija. Dejavnost v tej napravi morda upravljajo zunaj Chroma. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Vnesti morate več podatkov</translation>
<translation id="9080712759204168376">Povzetek naročila</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>
<translation id="9106062320799175032">Dodajanje naslova za izstavitev računa</translation>
-<translation id="9110718169272311511">Pomočnik Google v Chromu je na voljo pri dnu zaslona</translation>
<translation id="9114524666733003316">Potrjevanje kartice …</translation>
<translation id="9128870381267983090">Vzpostavi povezavo z omrežjem</translation>
<translation id="9137013805542155359">Pokaži izvirno besedilo</translation>
@@ -1287,6 +1451,7 @@ Dodatne podrobnosti:
<translation id="9148507642005240123">&amp;Razveljavi urejanje</translation>
<translation id="9154194610265714752">Posodobljeno</translation>
<translation id="9157595877708044936">Nastavljanje ...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">Dovolite spletnim mestom, da preverijo, ali imate shranjena plačilna sredstva</translation>
<translation id="9169664750068251925">Vedno blokiraj na tem spletnem mestu</translation>
<translation id="9170848237812810038">&amp;Razveljavi</translation>
@@ -1301,10 +1466,12 @@ Dodatne podrobnosti:
<translation id="9219103736887031265">Slike</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">POČISTI OBRAZEC</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Izgubite lahko dostop do Google Računa. Chromium priporoča, da spremenite geslo. Pozvani boste, da se prijavite.</translation>
<translation id="939736085109172342">Nova mapa</translation>
<translation id="945855313015696284">Preverite spodnje podatke in izbrišite neveljavne kartice</translation>
<translation id="951104842009476243">Sprejete debetne in predplačniške kartice</translation>
+<translation id="958202389743790697">Blokirano v skladu s pravilnikom za <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Ta vsebina lahko poskusi namestiti zavajajoče aplikacije, ki se izdajajo za kaj drugega ali zbirajo podatke, s katerimi vas je mogoče spremljati. <ph name="BEGIN_LINK" />Vseeno pokaži<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Uradna različica</translation>
<translation id="973773823069644502">Dodajanje naslova za dostavo</translation>
@@ -1313,6 +1480,7 @@ Dodatne podrobnosti:
<translation id="984275831282074731">Plačilna sredstva</translation>
<translation id="985199708454569384">&lt;p&gt;Ta napaka se prikaže, če datum in ura v računalniku ali mobilni napravi nista točna.&lt;/p&gt;
&lt;p&gt;Napako odpravite tako, da v napravi odprete uro ter se prepričate, da sta ura in datum pravilna.&lt;/p&gt;</translation>
+<translation id="985956168329721395">PRC 16K</translation>
<translation id="988159990683914416">Različica za razvijalce</translation>
<translation id="989988560359834682">Uredi naslov</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_sr.xtb b/chromium/components/strings/components_strings_sr.xtb
index 35e58c9b9d8..09d6b9c2706 100644
--- a/chromium/components/strings/components_strings_sr.xtb
+++ b/chromium/components/strings/components_strings_sr.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sr">
-<translation id="1005145902654145231">Преименовање сесије није успело.</translation>
<translation id="1008557486741366299">Не сада</translation>
<translation id="1010200102790553230">Касније учитај страницу</translation>
<translation id="1015730422737071372">Наведите додатне детаље</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">непознато име</translation>
<translation id="1050038467049342496">Затворите друге апликације</translation>
<translation id="1055184225775184556">&amp;Опозови додавање</translation>
+<translation id="1056898198331236512">Упозорење</translation>
<translation id="1058479211578257048">Картице се чувају...</translation>
<translation id="10614374240317010">Никада се не чува</translation>
+<translation id="1062160989074299343">Prc10 (коверат)</translation>
<translation id="106701514854093668">Обележивачи на рачунару</translation>
<translation id="1074497978438210769">Није безбедно</translation>
<translation id="1080116354587839789">Уклопите по ширини</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Додајте име са картице</translation>
<translation id="1089439967362294234">Промена лозинке</translation>
<translation id="109743633954054152">Управљајте лозинкама у подешавањима Chrome-а</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Упозорења могу често да се приказују док веб-сајтови ажурирају безбедност. То би ускоро требало да се побољша.</translation>
<translation id="1126551341858583091">Величина у локалном меморијском простору је <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Кеш смерница је у реду</translation>
+<translation id="1131264053432022307">Копирана слика</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885">Хост <ph name="HOST_NAME" /> је неочекивано прекинуо везу.</translation>
<translation id="1161325031994447685">поново да се повежете са Wi-Fi мрежом</translation>
<translation id="1165039591588034296">Грешка</translation>
-<translation id="1173894706177603556">Преименуј</translation>
<translation id="1175364870820465910">&amp;Одштампај...</translation>
<translation id="1181037720776840403">Уклони</translation>
<translation id="1197088940767939838">Наранџаста</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Назив уређаја</translation>
<translation id="124116460088058876">Још језика</translation>
<translation id="1250759482327835220">Да бисте следећи пут платили брже, сачувајте картицу, име и адресу за обрачун на Google налогу.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (синхронизовано)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Варијације командне линије</translation>
<translation id="129553762522093515">Недавно затворено</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Покушајте да обришете колачиће<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Изабрана сесија не постоји.</translation>
+<translation id="1320233736580025032">Prc1 (коверат)</translation>
+<translation id="132301787627749051">Потражите слику у привременој меморији</translation>
<translation id="1323433172918577554">Прикажи више</translation>
<translation id="132390688737681464">Чувај и уноси адресе</translation>
<translation id="1333989956347591814">Активности ће <ph name="BEGIN_EMPHASIS" />можда ипак бити видљиве<ph name="END_EMPHASIS" /> за:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Адреса преузимања</translation>
<translation id="1348198688976932919">Сајт који ћете посетити садржи опасне апликације</translation>
<translation id="1348779747280417563">Потврдите име</translation>
+<translation id="1357195169723583938">Ко је недавно користио уређај и када</translation>
+<translation id="1364822246244961190">Ове смернице су блокиране. Њихова вредност ће бити занемарена.</translation>
<translation id="1374468813861204354">предлози</translation>
+<translation id="1374692235857187091">Index-4x6 (разгледница)</translation>
<translation id="1375198122581997741">О верзији</translation>
<translation id="1376836354785490390">Прикажи мање</translation>
<translation id="1377321085342047638">Број картице</translation>
<translation id="138218114945450791">Светлоплава</translation>
+<translation id="1382194467192730611">USB уређај који дозвољава администратор</translation>
<translation id="139305205187523129">Хост <ph name="HOST_NAME" /> није послао никакве податке.</translation>
+<translation id="140316286225361634">Сајт <ph name="ORIGIN" /> је затражио да се безбедносне смернице
+ примене на све захтеве, а ове смернице тренутно процењују да сајт
+ није безбедан.</translation>
<translation id="1405567553485452995">Светлозелена</translation>
<translation id="1407135791313364759">Отвори све</translation>
<translation id="1413809658975081374">Грешка у вези са приватношћу</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Да</translation>
<translation id="1430915738399379752">Штампај</translation>
<translation id="1455413310270022028">Брисач</translation>
+<translation id="1463543813647160932">5×7</translation>
+<translation id="1472675084647422956">Прикажи више</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Одаберите адресу за испоруку</translation>
+<translation id="1492194039220927094">Слање смерница:</translation>
<translation id="1501859676467574491">Приказуј картице са мог Google налога</translation>
-<translation id="1506687042165942984">Прикажите сачувану копију ове странице (тј. копију за коју се зна да је застарела).</translation>
<translation id="1507202001669085618">&lt;p&gt;Ова грешка се приказује ако користите Wi-Fi портал на коме морате да се пријавите да бисте се повезали на интернет.&lt;/p&gt;
&lt;p&gt;Да бисте отклонили ту грешку, кликните на &lt;strong&gt;Повежи се&lt;/strong&gt; на страници коју покушавате да отворите.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Број телефона је обавезан</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Датум верзије</translation>
<translation id="1521655867290435174">Google табеле</translation>
<translation id="1527263332363067270">Чека се веза…</translation>
+<translation id="1529521330346880926">10x15 (коверат)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Ова страница наводи:</translation>
<translation id="153384715582417236">То је све за сада</translation>
<translation id="154408704832528245">Одаберите адресу за доставу</translation>
<translation id="1549470594296187301">JavaScript мора да буде омогућен да бисте користили ову функцију.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Унесите датум истека</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Дошло је до грешке при приказивању ове веб-странице.</translation>
<translation id="1592005682883173041">Приступ локалним подацима</translation>
<translation id="1594030484168838125">Одабери</translation>
<translation id="161042844686301425">Плавозелена</translation>
-<translation id="1618822247301510817">Копирана слика</translation>
<translation id="1620510694547887537">Камера</translation>
<translation id="1623104350909869708">Спречи ову страницу да прави додатне дијалоге</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Заврши сесију</translation>
<translation id="1639239467298939599">Учитавање</translation>
<translation id="1640180200866533862">Смернице за кориснике</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> обично користи шифровање да би заштитио информације. Када је Google Chrome овог пута покушао да се повеже са <ph name="SITE" />, веб-сајт је вратио необичне и нетачне акредитиве. Или нападач покушава да се представи као <ph name="SITE" /> или је екран за Wi-Fi пријављивање прекинуо везу. Информације су и даље безбедне зато што је Google Chrome прекинуо везу пре него што су размењени било какви подаци.</translation>
<translation id="168841957122794586">Сертификат сервера садржи слаб криптографски кључ.</translation>
<translation id="1697532407822776718">Спремни сте!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Документ је исувише велики да бисте му додали напомене</translation>
<translation id="1721312023322545264">Потребна вам је дозвола корисника <ph name="NAME" /> да бисте посетили овај сајт</translation>
<translation id="1721424275792716183">* Поље је обавезно</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Покушајте да контактирате администратора система.</translation>
<translation id="1740951997222943430">Унесите важећи месец истека</translation>
<translation id="1743520634839655729">Да бисте следећи пут платили брже, сачувајте картицу, име и адресу за обрачун на Google налогу и овом уређају.</translation>
+<translation id="1745880797583122200">Прегледачем се управља</translation>
<translation id="17513872634828108">Отворене картице</translation>
<translation id="1753706481035618306">Број странице</translation>
<translation id="1763864636252898013">Овај сервер не може да докаже да је <ph name="DOMAIN" />; оперативни систем уређаја нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Ажурирај приступну фразу за синхронизацију</translation>
<translation id="1787142507584202372">Отворене картице се појављују овде</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Име власника картице</translation>
<translation id="1821930232296380041">Неважећи захтев или параметри захтева</translation>
+<translation id="1822540298136254167">Веб-сајтови које посећујете и време проведено на њима</translation>
<translation id="1826516787628120939">Провера</translation>
<translation id="1834321415901700177">Овај сајт садржи штетне програме</translation>
<translation id="1839551713262164453">Валидација вредности смерница није успела уз грешке</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Обришите податке из историје прегледања у Chrome-у</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ и још 1}one{и још #}few{и још #}other{и још #}}</translation>
<translation id="2003709556000175978">Ресетујте лозинку</translation>
+<translation id="20053308747750172">Сервер на који идете, <ph name="ORIGIN" />, затражио је
+ да се безбедносне смернице примене на све захтеве ка њему. Међутим, сада је
+ послао неважеће смернице, па прегледач не може
+ испуни захтев за <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Прокси је подешен да буде аутоматски конфигурисан.</translation>
<translation id="2030481566774242610">Да ли сте мислили <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />да проверите прокси и заштитни зид<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Одсек</translation>
<translation id="2102134110707549001">Предложи јаку лозинку…</translation>
<translation id="2108755909498034140">Поново покрените рачунар</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Картица</translation>
<translation id="2114841414352855701">Занемарују се јер су замењене смерницама <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Мобилни обележивачи</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Измените картицу</translation>
<translation id="2166049586286450108">Потпуни администраторски приступ</translation>
<translation id="2166378884831602661">Овај сајт не може да пружи безбедну везу</translation>
+<translation id="2169984857010174799">Kaku2 (коверат)</translation>
<translation id="2181821976797666341">Смернице</translation>
<translation id="2183608646556468874">Број телефона</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреса}one{# адреса}few{# адресе}other{# адреса}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Број телефона</translation>
<translation id="2283340219607151381">Чувај и уноси адресе</translation>
<translation id="2292556288342944218">Приступ интернету је блокиран</translation>
+<translation id="2294558542833290837">Линк који сте првобитно отворили је неуобичајен</translation>
+<translation id="2297722699537546652">B5 (коверат)</translation>
+<translation id="2310021320168182093">Chou2 (коверат)</translation>
<translation id="2316887270356262533">Ослобађа мање од 1 MB. Неки сајтови ће се можда спорије учитавати кад их следећи пут посетите.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> захтева корисничко име и лозинку.</translation>
<translation id="2317583587496011522">Прихватају се дебитне картице.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, истиче <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Подешавање контролише администратор</translation>
+<translation id="2346319942568447007">Копирана слика</translation>
<translation id="2349790679044093737">ВР сесија је у току</translation>
<translation id="2354001756790975382">Остали обележивачи</translation>
<translation id="2354430244986887761">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило штетне апликације<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Извештај о отказивању снимљен у <ph name="CRASH_TIME" /> није отпремљен</translation>
<translation id="2367567093518048410">Ниво</translation>
<translation id="2378238891085281592">Прешли сте на режим приватног прегледања</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Подразумеване смернице за предузеће</translation>
<translation id="2386255080630008482">Сертификат сервера је опозван.</translation>
<translation id="2392959068659972793">Прикажи смернице без подешених вредности</translation>
<translation id="239429038616798445">Овај начин слања није доступан. Испробајте неки други начин.</translation>
<translation id="2396249848217231973">&amp;Опозови брисање</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат ће можда бити опозван. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="2418081434543109369">Сервер на који идете, <ph name="ORIGIN" />, затражио је
+ да се безбедносне смернице примене на све захтеве ка њему. Међутим, слање
+ смерница није успело, па прегледач не може да испуни
+ ваш захтев за <ph name="SITE" />.</translation>
<translation id="244665789865330679">Уређајем и налогом управља <ph name="ENROLLMENT_DOMAIN" />. То значи да администратор може даљински да конфигурише уређај и налог.</translation>
<translation id="2463193859425327265">Промените почетну страницу</translation>
<translation id="2463739503403862330">Попуни</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Одаберите начин доставе</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />да покренете дијагностику мреже<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Преведите ову страницу</translation>
<translation id="2479410451996844060">Неважећа URL адреса претраге.</translation>
<translation id="2482878487686419369">Обавештења</translation>
<translation id="248348093745724435">Смернице за уређаје</translation>
+<translation id="2485387744899240041">Корисничка имена за уређај и прегледач</translation>
<translation id="2491120439723279231">Сертификат сервера садржи грешке.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">Рашчлањивач JSON датотека</translation>
<translation id="2495093607237746763">Ако означите ову опцију, Chromium ће складиштити копију картице на овом уређају ради бржег попуњавања образаца.</translation>
<translation id="2498091847651709837">Скенирајте нову картицу</translation>
<translation id="2501278716633472235">Назад</translation>
<translation id="2503184589641749290">Дебитне и припејд картице које се прихватају</translation>
<translation id="2515629240566999685">да проверите сигнал у својој области</translation>
-<translation id="2516852381693169964">Потражи слику помоћу претраживача <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Сачувано је само на овом уређају</translation>
<translation id="2524461107774643265">Додајте још информација</translation>
<translation id="2536110899380797252">Додај адресу</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">ИД API-ја за директоријуме:</translation>
<translation id="2597378329261239068">Овај документ је заштићен лозинком. Унесите лозинку.</translation>
<translation id="2609632851001447353">Варијације</translation>
+<translation id="2618023639789766142">C10 (коверат)</translation>
<translation id="2625385379895617796">Сат вам жури</translation>
<translation id="2634124572758952069">Нисмо успели да пронађемо IP адресу сервера хоста <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Статус:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Затворите друге картице или апликације</translation>
<translation id="267371737713284912">притисните <ph name="MODIFIER_KEY_DESCRIPTION" /> да бисте опозвали</translation>
<translation id="2674170444375937751">Желите ли стварно да избришете ове странице из историје?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Затвори</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Картице које се прихватају</translation>
<translation id="2702801445560668637">Листа за читање</translation>
<translation id="2704283930420550640">Вредност се не подудара са форматом.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Уклони изабране ставке</translation>
<translation id="277133753123645258">Начин слања</translation>
<translation id="277499241957683684">Недостаје евиденција уређаја</translation>
-<translation id="2781030394888168909">Извези за Mac OS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Веза је враћена на почетне вредности.</translation>
<translation id="2788784517760473862">Кредитне картице које се прихватају</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">Веза је шифрована и њена аутентичност је потврђена помоћу <ph name="CIPHER" /> и користи <ph name="KX" /> као механизам за размену шифара.</translation>
<translation id="2835170189407361413">Обриши образац</translation>
<translation id="2847118875340931228">Отвори прозор без архивирања</translation>
+<translation id="2850739647070081192">Invite (коверат)</translation>
<translation id="2851634818064021665">Треба вам дозвола да бисте посетили овај сајт</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Желите ли да сачувате картицу?</translation>
<translation id="2903493209154104877">Адресе</translation>
<translation id="290376772003165898">Ова страница није на језику <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Начин испоруке</translation>
<translation id="2928905813689894207">Адреса за обрачун</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је са домена <ph name="DOMAIN2" />. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="2948083400971632585">На страници Подешавања можете да онемогућите све проксије конфигурисане за везу.</translation>
<translation id="2955913368246107853">Затворите траку за проналажење</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (коверат)</translation>
<translation id="3024663005179499861">Погрешан тип смерница</translation>
<translation id="3037605927509011580">О, не!</translation>
<translation id="3041612393474885105">Информације о сертификату</translation>
+<translation id="3060227939791841287">C9 (коверат)</translation>
<translation id="3064966200440839136">Напустићете режим без архивирања да бисте платили у спољној апликацији. Желите ли да наставите?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{None}=1{1 лозинка}one{# лозинка}few{# лозинке}other{# лозинки}}</translation>
+<translation id="3095940652251934233">Изјава</translation>
<translation id="3096100844101284527">Додај адресу преузимања</translation>
<translation id="3105172416063519923">ИД елемента:</translation>
<translation id="3109728660330352905">Немате овлашћење да прегледате ову страницу.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> на: <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Откажи плаћање</translation>
<translation id="3207960819495026254">Обележено</translation>
-<translation id="3209375525920864198">Унесите важећи назив сесије.</translation>
+<translation id="321912867715453276">Упозорење: Присутно је више извора са истим вредностима за ове смернице.</translation>
<translation id="3225919329040284222">Сервер је приказао сертификат који се не подудара са уграђеним очекивањима. Та очекивања су обухваћена за одређене веб-сајтове са јаким безбедносним мерама како би вас заштитила.</translation>
<translation id="3226128629678568754">Притисните дугме Поново учитај да бисте поново послали податке потребне за учитавање странице.</translation>
<translation id="3227137524299004712">Микрофон</translation>
<translation id="3228969707346345236">Превод није успео јер је страница већ на језику <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Информације о верзији за уређај и прегледач</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Додајте име на картици</translation>
<translation id="3287510313208355388">Преузми када сам онлајн</translation>
<translation id="3293642807462928945">Сазнајте више о смерницама <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Нису пронађени резултати претраге</translation>
-<translation id="3305707030755673451">Подаци су шифровани помоћу приступне фразе за синхронизацију <ph name="TIME" />. Унесите је да бисте започели синхронизацију.</translation>
<translation id="3320021301628644560">Додајте адресу за обрачун</translation>
<translation id="3324983252691184275">Јаркоцрвена</translation>
<translation id="3338095232262050444">Безбедан</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Понови измену</translation>
<translation id="342781501876943858">Chromium вам препоручује да ресетујете лозинку ако сте је користили на другим сајтовима.</translation>
<translation id="3431636764301398940">Сачувај ову картицу на овом уређају</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Власник овог уређаја је искључио ову застарелу игру.</translation>
<translation id="3447884698081792621">Прикажи сертификат (издаје <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Интервал учитавања:</translation>
+<translation id="3456231139987291353">Број-11 (коверат)</translation>
<translation id="3461824795358126837">Алатка за истицање</translation>
<translation id="3462200631372590220">Сакриј напредно</translation>
<translation id="3467763166455606212">Име власника картице је обавезно</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Прихватају се кредитне и припејд картице.</translation>
<translation id="3582930987043644930">Додајте име</translation>
<translation id="3583757800736429874">&amp;Понови премештање</translation>
+<translation id="35866233670761917">Администратори не могу да виде садржај веб-сајтова које посећујете</translation>
<translation id="3586931643579894722">Сакриј детаље</translation>
+<translation id="3592413004129370115">Italian (коверат)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Величина 2</translation>
<translation id="3615877443314183785">Унесите важећи датум истека</translation>
<translation id="36224234498066874">Обриши податке прегледања...</translation>
<translation id="362276910939193118">Прикажи комплетну историју</translation>
-<translation id="3623476034248543066">Прикажи вредност</translation>
<translation id="3630155396527302611">Ако је већ наведен као програм коме је дозвољен приступ мрежи, покушајте да га
уклоните са листе и да га поново додате.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Потврда ваљаности је успела</translation>
<translation id="3655670868607891010">Ако вам се ово често приказује, можда вам помогну следећи <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Ревизија</translation>
<translation id="366077651725703012">Ажурирајте кредитну картицу</translation>
<translation id="3676592649209844519">ИД уређаја:</translation>
+<translation id="3677008721441257057">Да ли сте мислили &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Потписивање захтева није успело</translation>
<translation id="3678529606614285348">Отворите страницу у ноцом прозору без архивирања (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Извештај о отказивању је снимљен <ph name="CRASH_TIME" />, а отпремљен <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Мрежа коју користите ће можда захтевати да посетите страницу за пријављивање.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Учитава се...</translation>
+<translation id="3709599264800900598">Текст који сте копирали</translation>
<translation id="3712624925041724820">Нема више лиценци</translation>
<translation id="3714780639079136834">да укључите податке за мобилне уређаје или Wi-Fi</translation>
<translation id="3715597595485130451">Повезивање са Wi-Fi мрежом</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />да проверите конфигурацију проксија, заштитног зида и DNS-а<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Апликације које могу да доведу до ове грешке обухватају антивирусни софтвер, заштитни зид и веб-филтрирање или прокси софтвер.</translation>
+<translation id="373042150751172459">B4 (коверат)</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="3745099705178523657">Када будете потврдили, подаци о картици са Google налога ће се делити са овим сајтом.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Истиче <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Величина 16</translation>
+<translation id="3797522431967816232">Prc3 (коверат)</translation>
<translation id="3807873520724684969">Блокиран је штетан садржај.</translation>
<translation id="3810973564298564668">Промени</translation>
<translation id="382518646247711829">Ако користите прокси сервер...</translation>
<translation id="3828924085048779000">Није дозвољено да поље за приступну фразу буде празно.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> је инсталирао додатке за додатне функције. Додаци имају приступ некима од података.</translation>
<translation id="385051799172605136">Назад</translation>
<translation id="3858027520442213535">Ажурирајте датум и време</translation>
<translation id="3884278016824448484">Неусаглашени идентификатор уређаја</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">Захтев за приступ овом сајту је послат кориснику <ph name="NAME" /></translation>
<translation id="3890664840433101773">Додајте имејл</translation>
<translation id="3901925938762663762">Картица је истекла</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Увек питај на овом сајту</translation>
<translation id="3949571496842715403">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат не наводи Алтернативне називе субјекта. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Овај назив сесије већ постоји.</translation>
<translation id="3987940399970879459">Мање од 1 MB</translation>
+<translation id="4008849406247176967">Упозорење: Присутно је више извора са неусаглашеним вредностима за ове смернице!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-страница у околини}one{# веб-страница у околини}few{# веб-странице у околини}other{# веб-страница у околини}}</translation>
<translation id="4030383055268325496">&amp;Опозови додавање</translation>
+<translation id="4032320456957708163">Прегледачем управља <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Кључ „<ph name="SUBKEY" />“: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (коверат)</translation>
<translation id="4067947977115446013">Додајте важећу адресу</translation>
<translation id="4072486802667267160">Дошло је до грешке при обради поруџбине. Пробајте поново.</translation>
<translation id="4075732493274867456">Клијент и сервер не подржавају исту верзију SSL протокола или пакет за шифровање.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Љубичаста</translation>
<translation id="4165986682804962316">Подешавања сајта</translation>
<translation id="4171400957073367226">Неисправан потпис за верификацију</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{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="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;Понови премештање</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />да проверите конфигурацију заштитног зида и антивируса<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (коверат)</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="4221630205957821124">&lt;h4&gt;1. корак: Пријавите се на портал&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Ресетујте лозинку</translation>
<translation id="4280429058323657511">, истиче <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Ова картица је сачувана на Google налогу}one{Ове картице су сачуване на Google налогу}few{Ове картице су сачуване на Google налогу}other{Ове картице су сачуване на Google налогу}}</translation>
+<translation id="42981349822642051">Проширите</translation>
+<translation id="4302965934281694568">Chou3 (коверат)</translation>
<translation id="4305817255990598646">Пређи</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Блокирај (подразумевано)</translation>
+<translation id="4318566738941496689">Назив и мрежна адреса уређаја</translation>
<translation id="4325863107915753736">Нисмо успели да пронађемо чланак</translation>
<translation id="4326324639298822553">Проверите датум истека и пробајте поново</translation>
<translation id="4331708818696583467">Није безбедан</translation>
<translation id="4340982228985273705">Откривено је да овим рачунаром не управља предузеће, па смернице могу аутоматски да инсталирају само додатке који се хостују у Chrome веб-продавници. URL ажурирања у Chrome веб-продавници је „<ph name="CWS_UPDATE_URL" />“.</translation>
<translation id="4346197816712207223">Кредитне картице које се прихватају</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Нападачи на овом сајту ће можда покушати да инсталирају опасне програме на рачунару који краду или бришу информације (на пример, слике, лозинке, поруке и бројеве кредитних картица).</translation>
<translation id="4358461427845829800">Управљајте начинима плаћања...</translation>
+<translation id="4367563149485757821">Број-12 (коверат)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">Очекивана вредност je <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">Покушали сте да контактирате <ph name="DOMAIN" />, али је издавач опозвао сертификат који је сервер навео. То значи да никако не треба имати поверења у безбедносне акредитиве које је сервер навео. Могуће је да комуницирате са нападачем.</translation>
<translation id="4378154925671717803">Телефон</translation>
<translation id="4406896451731180161">резултати претраге</translation>
-<translation id="4406972042435603828">Администратори су инсталирали додатке са великим могућностима.</translation>
<translation id="4408413947728134509">Колачићи (<ph name="NUM_COOKIES" />)</translation>
<translation id="4415426530740016218">Адреса преузимања</translation>
<translation id="4424024547088906515">Овај сервер не може да докаже да је <ph name="DOMAIN" />; Chrome нема поверења у његов безбедносни сертификат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="443121186588148776">Серијски порт</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> није прихватио сертификат за пријављивање или сертификат за пријављивање није приложен.</translation>
<translation id="4434045419905280838">Искачући прозори и преусмеравања</translation>
+<translation id="4435702339979719576">разгледница)</translation>
<translation id="443673843213245140">Коришћење проксија је онемогућено, али је наведена експлицитна конфигурација проксија.</translation>
<translation id="445100540951337728">Дебитне картице које се прихватају</translation>
+<translation id="4466881336512663640">Промене обрасца се неће сачувати. Желите ли стварно да наставите?</translation>
<translation id="4482953324121162758">Овај сајт неће бити преведен.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL је неважећи. URL мора да има стандардну шему, нпр. http://example.com или https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Грешка при потврди ваљаности: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">да контактирате администратора система</translation>
<translation id="450710068430902550">Дељење са администратором</translation>
+<translation id="4510487217173779431">Chou4 (коверат)</translation>
<translation id="4515275063822566619">Картице и адресе су из Chrome-а и са вашег Google налога (<ph name="ACCOUNT_EMAIL" />). Њима можете да управљате у <ph name="BEGIN_LINK" />подешавњима<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (коверат)</translation>
<translation id="4522570452068850558">Детаљи</translation>
<translation id="4524805452350978254">Управљајте картицама</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Покушајте да онемогућите додатке.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Испорука</translation>
+<translation id="4579056131138995126">Personal (коверат)</translation>
<translation id="4582204425268416675">Уклони картицу</translation>
<translation id="4587425331216688090">Желите ли да уклоните адресу из Chrome-а?</translation>
<translation id="4592951414987517459">Веза са доменом <ph name="DOMAIN" /> је шифрована помоћу модерног пакета за шифровање.</translation>
<translation id="4594403342090139922">&amp;Опозови брисање</translation>
<translation id="4597348597567598915">Величина 8</translation>
+<translation id="4600854749408232102">C6/C5 (коверат)</translation>
<translation id="4646534391647090355">Одведи ме тамо</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат садржи грешке. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="467809019005607715">Google презентације</translation>
<translation id="4690462567478992370">Обустави коришћење неважећег сертификата</translation>
+<translation id="4691835149146451662">Architecture-A (коверат)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Веза је прекинута</translation>
<translation id="471880041731876836">Немате дозволу да посетите овај сајт</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />да покренете Windows дијагностику мреже<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Поново учитај смернице</translation>
<translation id="4728558894243024398">Платформа</translation>
+<translation id="4731967714531604179">Prc2 (коверат)</translation>
<translation id="4736825316280949806">Поново покрените Chromium</translation>
<translation id="473775607612524610">Ажурирај</translation>
<translation id="4738601419177586157">Предлог за претрагу <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Управљај лозинкама...</translation>
<translation id="4744603770635761495">Путања извршне датотеке</translation>
+<translation id="4746351372139058112">Поруке</translation>
<translation id="4750917950439032686">Информације (на пример, лозинке или бројеви кредитних картица) су приватне када се шаљу овом сајту.</translation>
<translation id="4756388243121344051">&amp;Историја</translation>
<translation id="4758311279753947758">Додај контакт информације</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Могуће је да веб-страница на адреси <ph name="URL" /> привремено не функционише или да је трајно премештена на нову веб адресу.</translation>
<translation id="4771973620359291008">Дошло је до непознате грешке.</translation>
<translation id="4785689107224900852">Пређите на ову картицу</translation>
-<translation id="4792143361752574037">Дошло је до проблема при приступању датотекама сесије. Чување на диску је тренутно онемогућено. Учитајте поново страницу да бисте пробали поново.</translation>
<translation id="4798078619018708837">Унесите рок трајања и CVC за картицу <ph name="CREDIT_CARD" /> да бисте ажурирали податке о картици. Када будете потврдили, подаци о картици са Google налога ће се делити са овим сајтом.</translation>
<translation id="4800132727771399293">Проверите датум истека и CVC и покушајте поново</translation>
+<translation id="480334179571489655">Грешка са пореклом смерница</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Отвори</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Нема резултата</translation>
<translation id="4950898438188848926">Дугме за промену картице, притисните Enter да бисте прешли на отворену картицу, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Радње</translation>
-<translation id="495832697253704892">Пријављивање додатка</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Прошири листу</translation>
<translation id="4974590756084640048">Поново омогући упозорења</translation>
+<translation id="4984339528288761049">Prc5 (коверат)</translation>
<translation id="4989163558385430922">Прикажи све</translation>
<translation id="4989809363548539747">Ова додатна компонента није подржана</translation>
-<translation id="4996230189582812866">Пријављивање</translation>
<translation id="5002932099480077015">Ако је ова опција омогућена, Chrome ће складиштити копију картице на овом уређају ради бржег попуњавања образаца.</translation>
-<translation id="5014174725590676422">Приказује се екран за прво покретање Google помоћника у Chrome-у</translation>
<translation id="5015510746216210676">Назив уређаја:</translation>
+<translation id="5017554619425969104">Текст који сте копирали</translation>
<translation id="5018422839182700155">Не можемо да отворимо ову страницу</translation>
<translation id="5019198164206649151">Складиште тока података је у лошем стању</translation>
<translation id="5023310440958281426">Проверите смернице администратора</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Локални контекст <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Дозволи</translation>
<translation id="5040262127954254034">Приватност</translation>
+<translation id="5043480802608081735">Линк који сте копирали</translation>
<translation id="5045550434625856497">Неисправна лозинка</translation>
<translation id="5056549851600133418">Чланци за вас</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />да проверите адресу проксија<ph name="END_LINK" /></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="5097099694988056070">Статистички подаци о уређају, попут искоришћености процесора/RAM меморије</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Уређајем управља <ph name="ENROLLMENT_DOMAIN" />, а налогом <ph name="ACCOUNT_DOMAIN" />. То значи да администратори могу да даљински конфигуришу уређај и налог.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-битни)</translation>
-<translation id="5128122789703661928">Сесија са овим називом није доступна за брисање.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Управљајте адресама...</translation>
+<translation id="5138227688689900538">Прикажи мање</translation>
<translation id="5141240743006678641">Шифруј синхронизоване лозинке помоћу Google акредитива</translation>
<translation id="5145883236150621069">Кôд грешке је присутан у одговору на смернице</translation>
+<translation id="515292512908731282">C4 (коверат)</translation>
<translation id="5159010409087891077">Отворите страницу у новом прозору без архивирања (⇧⌘N)</translation>
<translation id="516920405563544094">Унесите CVC за картицу <ph name="CREDIT_CARD" />. Када будете потврдили, подаци о картици са Google налога ће се делити са овим сајтом.</translation>
<translation id="5169827969064885044">Могли бисте да изгубите приступ налогу за организацију или би могло да дође до крађе идентитета. Chrome вам препоручује да одмах промените лозинку.</translation>
<translation id="5171045022955879922">Претражите или унесите URL адресу</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Рачунар</translation>
<translation id="5179510805599951267">Није <ph name="ORIGINAL_LANGUAGE" />? Пријавите ову грешку</translation>
<translation id="5190835502935405962">Трака са обележивачима</translation>
-<translation id="5200263511887412697">извештај листе корисника уређаја који су се недавно пријавили</translation>
+<translation id="519422657042045905">Напомена није доступна</translation>
<translation id="5201306358585911203">Уграђена страница на овој веб-страници наводи:</translation>
<translation id="5205222826937269299">Име је обавезно</translation>
<translation id="5215116848420601511">Начини плаћања и адресе из Google Pay-а</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Имејл је обавезан</translation>
<translation id="5230733896359313003">Адреса за испоруку</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">„Повежите се на мрежу“</translation>
<translation id="5251803541071282808">Клауд</translation>
+<translation id="5252000469029418751">C7 (коверат)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Мрежне адресе</translation>
<translation id="5285570108065881030">Прикажи све сачуване лозинке</translation>
<translation id="5287240709317226393">Прикажи колачиће</translation>
<translation id="5288108484102287882">Валидација вредности смерница је активирала упозорења</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" />. од <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Одаберите контакт информације</translation>
<translation id="5327248766486351172">Назив</translation>
+<translation id="5329858041417644019">Прегледачем нико не управља</translation>
<translation id="5332219387342487447">Начин испоруке</translation>
+<translation id="5334013548165032829">Детаљне евиденције система</translation>
<translation id="5344579389779391559">Ова страница може да покуша да вам нешто наплати</translation>
<translation id="5355557959165512791">Тренутно не можете да посетите <ph name="SITE" /> јер је његов сертификат опозван. Грешке и напади на мрежи су обично привремени, па ће ова страница вероватно функционисати касније.</translation>
<translation id="536296301121032821">Складиштење подешавања смерница није успело</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">„Сат касни“ или „Сат жури“ или „&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;“</translation>
<translation id="5384855140246857529">Да бисте користили картице на свим уређајима, пријавите се и укључите синхронизацију.</translation>
<translation id="5386426401304769735">Ланац сертификата за овај сајт садржи сертификат потписан помоћу алгоритма SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат тренутно није важећи. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
<translation id="5421136146218899937">Обриши податке прегледања...</translation>
<translation id="5430298929874300616">Уклоните обележивач</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Неважеће</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Понови измену</translation>
+<translation id="5478437291406423475">B6/C4 (коверат)</translation>
<translation id="5481076368049295676">Овај садржај ће покушати да инсталира опасан софтвер на уређај који ће украсти или обрисати ваше податке. <ph name="BEGIN_LINK" />Ипак прикажи<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Додајте важећу адресу</translation>
<translation id="5490432419156082418">Адресе и друго</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Покушајте да се обратите администратору система.</translation>
<translation id="549333378215107354">Величина 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Обележивачи којим се управља</translation>
<translation id="5510766032865166053">Можда је премештен или избрисан.</translation>
<translation id="5523118979700054094">Назив смерница</translation>
<translation id="552553974213252141">Да ли је текст правилно издвојен?</translation>
+<translation id="553484882784876924">Prc6 (коверат)</translation>
<translation id="5540224163453853">Нисмо пронашли захтевани чланак.</translation>
<translation id="5541546772353173584">Додајте имејл</translation>
<translation id="5545756402275714221">Чланци за вас</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Измена адресе</translation>
<translation id="5598944008576757369">Одаберите начин плаћања</translation>
<translation id="560412284261940334">Управљање није подржано</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">да проверите везу</translation>
<translation id="5610807607761827392">Картицама и адресама можете да управљате у <ph name="BEGIN_LINK" />Подешавањима<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996">Хост <ph name="HOST_NAME" /> вас је преусмерио превелики број пута.</translation>
<translation id="5629630648637658800">Учитавање подешавања смерница није успело</translation>
<translation id="5631439013527180824">Неважећи токен за управљање уређајима</translation>
+<translation id="5632627355679805402">Подаци су шифровани помоћу <ph name="BEGIN_LINK" />Google лозинке<ph name="END_LINK" /> (<ph name="TIME" />). Унесите је да бисте започели синхронизацију.</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="563324245173044180">Обмањујући садржај је блокиран.</translation>
<translation id="5659593005791499971">Имејл</translation>
+<translation id="5663614846592581799">9x11 (коверат)</translation>
+<translation id="5663955426505430495">Администратор овог уређаја је инсталирао додатке за додатне функције. Додаци имају приступ некима од података.</translation>
<translation id="5675650730144413517">Ова страница не функционише</translation>
+<translation id="5684874026226664614">Упс, превођење ове странице није успело.</translation>
<translation id="5685654322157854305">Додај адресу за испоруку</translation>
<translation id="5689199277474810259">Извези у JSON</translation>
<translation id="5689516760719285838">Локација</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Идентитет овог веб-сајта није верификован.</translation>
<translation id="5719499550583120431">Прихватају се припејд картице.</translation>
<translation id="5720705177508910913">Тренутни корисник</translation>
+<translation id="5728056243719941842">C5 (коверат)</translation>
<translation id="5730040223043577876">Chrome вам препоручује да ресетујете лозинку ако сте је користили на другим сајтовима.</translation>
<translation id="5732392974455271431">Родитељи могу да га деблокирају за тебе</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Сачувајте картицу на Google налогу}one{Сачувајте картице на Google налогу}few{Сачувајте картице на Google налогу}other{Сачувајте картице на Google налогу}}</translation>
<translation id="5763042198335101085">Унесите важећу имејл адресу</translation>
<translation id="5765072501007116331">Да бисте видели начине и захтеве за испоруку, изаберите адресу</translation>
-<translation id="5770114862687765385">Изгледа да је датотека оштећена. Кликните на дугме „Ресетуј“ да бисте ресетовали сесију.</translation>
<translation id="5778550464785688721">Потпуна контрола над MIDI уређајима</translation>
<translation id="578305955206182703">Окер</translation>
<translation id="57838592816432529">Искључи звук</translation>
<translation id="5784606427469807560">Дошло је до проблема при потврди картице. Проверите интернет везу и покушајте поново.</translation>
<translation id="5785756445106461925">Поред тога, ова страница садржи и друге ресурсе који нису безбедни. Ове ресурсе могу да виде и други док су у пролазу и нападач може да их измени како би променио изглед странице.</translation>
<translation id="5786044859038896871">Желите ли да попуните информације о картици?</translation>
+<translation id="5798290721819630480">Желите ли да одбаците промене?</translation>
<translation id="5798683403665926540">Промените почетну страницу у подешавањима Chrome-а</translation>
<translation id="5803412860119678065">Желите ли да попуните подацима <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Дозволе</translation>
<translation id="5810442152076338065">Веза са доменом <ph name="DOMAIN" /> је шифрована помоћу застарелог пакета за шифровање.</translation>
<translation id="5813119285467412249">&amp;Понови додавање</translation>
<translation id="5838278095973806738">Немојте да уносите осетљиве информације на овом сајту (на пример, лозинке или кредитне картице) јер нападачи могу да их украду.</translation>
+<translation id="5860033963881614850">Искључено</translation>
<translation id="5863847714970149516">Следећа страница може да покуша да вам нешто наплати</translation>
<translation id="5866257070973731571">Додајте број телефона</translation>
<translation id="5869405914158311789">Овај сајт није доступан</translation>
<translation id="5869522115854928033">Сачуване лозинке</translation>
<translation id="5887400589839399685">Картица је сачувана</translation>
-<translation id="5893718151540690985">да пријављује листу мрежних интерфејса са њиховим типовима и адресе хардвера</translation>
<translation id="5893752035575986141">Прихватају се кредитне картице.</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="5916664084637901428">Укључено</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Желите ли да сачувате картицу на Google налогу?</translation>
<translation id="5922853866070715753">Скоро је готово</translation>
<translation id="5932224571077948991">Сајт приказује огласе који ометају активности или обмањујуће огласе</translation>
-<translation id="5939518447894949180">Ресетуј</translation>
<translation id="5946937721014915347">Отвара се <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Регистрација корисничког налога није успела (доступна је лиценца пакета).</translation>
<translation id="5967592137238574583">Измените контакт информације</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Умањивање</translation>
<translation id="5977489021191000276">Уређајем не управља администратор.</translation>
<translation id="5977976211062815271">На овом уређају</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Отварање апликације за плаћање није успело</translation>
<translation id="5989320800837274978">Нису наведени ни фиксни прокси сервери нити URL адреса .pac скрипте.</translation>
<translation id="5990559369517809815">Додатак је блокирао захтеве упућене серверу.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">да пријављује статистику о хардверу, на пример, искоришћеност процесора/RAM меморије.</translation>
<translation id="6034000775414344507">Светлосива</translation>
+<translation id="6034283069659657473">10x14 (коверат)</translation>
<translation id="6039846035001940113">Ако се проблем и даље јавља, контактирајте власника сајта.</translation>
<translation id="6040143037577758943">Затвори</translation>
<translation id="6044573915096792553">Величина 12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">Тренутно не можете да посетите <ph name="SITE" /> јер веб-сајт користи проверу сертификата. Грешке и напади на мрежи су обично привремени, па ће ова страница вероватно функционисати касније.</translation>
<translation id="6058977677006700226">Желите ли да користите картице на свим уређајима?</translation>
<translation id="6059925163896151826">USB уређаји</translation>
-<translation id="6071091556643036997">Овај тип смерница је неважећи.</translation>
<translation id="6080696365213338172">Приступали сте садржају помоћу сертификата који је обезбедио администратор. Администратор може да пресретне податке које обезбедите домену <ph name="DOMAIN" />.</translation>
<translation id="6094273045989040137">Додајте напомене</translation>
<translation id="610911394827799129">Google налог може да има друге облике историје прегледања на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Информације о инсталираним додацима и додатним компонентама</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{None}=1{1 лозинка (синхронизована)}one{# лозинка (синхронизована)}few{# лозинке (синхронизоване)}other{# лозинки (синхронизованих)}}</translation>
<translation id="6146055958333702838">Проверите све каблове и рестартујте све рутере, модеме или друге мрежне уређаје које можда користите.</translation>
<translation id="614940544461990577">Покушајте:</translation>
@@ -849,15 +961,21 @@
<translation id="6337133576188860026">Ослобађа мање од <ph name="SIZE" />. Неки сајтови ће се можда спорије учитавати кад их следећи пут посетите.</translation>
<translation id="6337534724793800597">Филтрирај смернице према називу</translation>
<translation id="6358450015545214790">Шта ово значи?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Очекују вас потенцијални трошкови.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{још 1 предлог}one{још # предлог}few{још # предлога}other{још # предлога}}</translation>
<translation id="6387754724289022810">Да бисте следећи пут платили брже, сачувајте картицу и адресу за обрачун на Google налогу и овом уређају.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Измена обележивача</translation>
+<translation id="6406765186087300643">C0 (коверат)</translation>
<translation id="6410264514553301377">Унесите датум истека и CVC за картицу <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Питао/ла си родитеља да ли смеш да посетиш овај сајт</translation>
<translation id="6417515091412812850">Није могуће проверити да ли је сертификат опозван.</translation>
<translation id="6433490469411711332">Измените контакт информације</translation>
<translation id="6433595998831338502">Хост <ph name="HOST_NAME" /> је одбио повезивање.</translation>
+<translation id="6434309073475700221">Одбаци</translation>
+<translation id="6446163441502663861">Kahu (коверат)</translation>
<translation id="6446608382365791566">Додајте још информација</translation>
<translation id="6447842834002726250">Колачићи</translation>
<translation id="6451458296329894277">Потврђивање поновног слања обрасца</translation>
@@ -870,11 +988,17 @@
<translation id="6508722015517270189">Поново покрените Chrome</translation>
<translation id="6529602333819889595">&amp;Понови брисање</translation>
<translation id="6534179046333460208">Предлози Интернета око нас</translation>
+<translation id="6556866813142980365">Понови</translation>
<translation id="6563469144985748109">Менаџер га још увек није одобрио</translation>
<translation id="6569060085658103619">Прегледате страницу додатка.</translation>
+<translation id="6578796323535178455">C2 (коверат)</translation>
<translation id="6579990219486187401">Светлорозе</translation>
+<translation id="6583674473685352014">B6 (коверат)</translation>
+<translation id="6587923378399804057">Линк који сте копирали</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" />-ом се не управља</translation>
<translation id="6596325263575161958">Опције шифровања</translation>
<translation id="6604181099783169992">Сензори за покрет или светло</translation>
+<translation id="6609880536175561541">Prc7 (коверат)</translation>
<translation id="6624427990725312378">Контакт информације</translation>
<translation id="6626291197371920147">Додајте важећи број картице</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> претрага</translation>
@@ -883,6 +1007,7 @@
<translation id="6644283850729428850">Ове смернице су застареле.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{None}=1{Са 1 сајта (нећемо вас одјавити са Google налога)}one{Са # сајта (нећемо вас одјавити са Google налога)}few{Са # сајта (нећемо вас одјавити са Google налога)}other{Са # сајтова (нећемо вас одјавити са Google налога)}}</translation>
<translation id="6657585470893396449">Лозинка</translation>
+<translation id="6670613747977017428">Назад на безбедно.</translation>
<translation id="6671697161687535275">Желите ли да уклоните предлог из Chromium-а?</translation>
<translation id="6685834062052613830">Одјавите се и довршите подешавање</translation>
<translation id="6710213216561001401">Претходно</translation>
@@ -890,12 +1015,15 @@
<translation id="671076103358959139">Токен за регистрацију:</translation>
<translation id="6711464428925977395">Нешто није у реду са прокси сервером или је адреса нетачна.</translation>
<translation id="6723740634201835758">На Google налогу</translation>
+<translation id="6738516213925468394">Подаци су шифровани помоћу <ph name="BEGIN_LINK" />приступне фразе<ph name="END_LINK" /> (<ph name="TIME" />). Унесите је да бисте започели синхронизацију.</translation>
<translation id="674375294223700098">Непозната грешка сертификата сервера.</translation>
<translation id="6744009308914054259">Док чекате на везу, посетите Преузимања и читајте офлајн чланке.</translation>
<translation id="6753269504797312559">Вредност смерница</translation>
<translation id="6757797048963528358">Уређај је прешао у режим спавања.</translation>
+<translation id="6768213884286397650">Hagaki (разгледница)</translation>
<translation id="6778737459546443941">Родитељ га још увек није одобрио</translation>
<translation id="67862343314499040">Љубичаста</translation>
+<translation id="6786747875388722282">Додаци</translation>
<translation id="679355240208270552">Занемарује се зато што смернице нису омогућиле подразумевани претраживач.</translation>
<translation id="681021252041861472">Обавезно поље</translation>
<translation id="6810899417690483278">ИД за прилагођавање</translation>
@@ -928,10 +1056,12 @@
<translation id="6965978654500191972">Уређај</translation>
<translation id="6970216967273061347">Округ</translation>
<translation id="6973656660372572881">Наведени су и фиксни прокси сервери и URL адреса .pac скрипте.</translation>
+<translation id="6973932557599545801">Жао ми је, не могу да вам помогнем. Наставите сами.</translation>
<translation id="6979158407327259162">Google диск</translation>
<translation id="6979440798594660689">Искључен (подразумевано)</translation>
<translation id="6984479912851154518">Напустићете режим приватног прегледања да бисте платили у спољној апликацији. Желите ли да наставите?</translation>
<translation id="6989763994942163495">Прикажи напредна подешавања...</translation>
+<translation id="6993898126790112050">6x9 (коверат)</translation>
<translation id="6996312675313362352">Увек преводи <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Те наплате могу да буду једнократне или периодичне и можда нису одмах видљиве.</translation>
@@ -947,28 +1077,36 @@
<translation id="7108338896283013870">Сакриј</translation>
<translation id="7108819624672055576">Дозвољава додатак</translation>
<translation id="7111012039238467737">(Важећи)</translation>
+<translation id="7118618213916969306">Потражите URL у привременој меморији, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">Затворите друге картице или програме</translation>
<translation id="7129409597930077180">Слање на ову адресу није могуће. Изаберите другу адресу.</translation>
<translation id="7135130955892390533">Прикажи статус</translation>
<translation id="7138472120740807366">Начин испоруке</translation>
<translation id="7139724024395191329">Емират</translation>
+<translation id="7152423860607593928">Број-14 (коверат)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Светлољубичаста</translation>
-<translation id="7158980942472052083">URL је неважећи. Мора да буде URL са стандардном шемом.</translation>
<translation id="717330890047184534">Gaia ИД:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Сервер на који идете, <ph name="ORIGIN" />, затражио је
+ да се безбедносне смернице примене на све захтеве ка њему. Међутим, уместо
+ слања смерница, преусмерио је прегледач ка другој локацији, што спречава
+ прегледач да испуни захтев за <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Чувај и уноси начине плаћања</translation>
<translation id="7180611975245234373">Освежи</translation>
<translation id="7182878459783632708">Нису подешене никакве смернице</translation>
<translation id="7186367841673660872">Ова страница је преведена са језика:<ph name="ORIGINAL_LANGUAGE" />на<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Ослободиће се <ph name="SIZE" />. Неки сајтови ће се спорије учитавати при следећој посети.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Администратор може да види:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Хост <ph name="HOST_NAME" /> не поштује безбедносне стандарде.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /> о овом проблему.</translation>
<translation id="7219179957768738017">Веза користи <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Обрада</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Сајт који ћете посетити садржи малвер</translation>
+<translation id="724766306220616965">Упозорења, неусаглашеност</translation>
<translation id="724975217298816891">Унесите рок трајања и CVC за картицу <ph name="CREDIT_CARD" /> да бисте ажурирали податке о картици. Када будете потврдили, подаци о картици ће бити послати овом сајту.</translation>
<translation id="7251437084390964440">Конфигурација мреже није у складу са ONC стандардом. Делови конфигурације можда нису увезени.
Додатни детаљи:
@@ -981,11 +1119,14 @@
<translation id="7300012071106347854">Кобалтноплава</translation>
<translation id="7302712225291570345">„<ph name="TEXT" />“</translation>
<translation id="7309308571273880165">Извештај о отказивању је снимљен <ph name="CRASH_TIME" /> (корисник треба да га отпреми, још увек није отпремљен)</translation>
+<translation id="7313965965371928911">Упозорења у вези са <ph name="BEGIN_LINK" />Безбедним прегледањем<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Помоћ при повезивању</translation>
<translation id="7334320624316649418">&amp;Понови промену редоследа</translation>
<translation id="733923710415886693">Сертификат сервера није откривен помоћу Транспарентности сертификата.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Командна линија</translation>
-<translation id="7365061714576910172">Извези за Linux</translation>
<translation id="7372973238305370288">резултат претраге</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Не</translation>
@@ -993,6 +1134,7 @@
<translation id="7381288752349550461">Замена сесије којом се управља</translation>
<translation id="7390545607259442187">Потврдите картицу</translation>
<translation id="7400418766976504921">URL адреса</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" />-ом се управља</translation>
<translation id="7407424307057130981">&lt;p&gt;Ова грешка ће вам се приказати ако имате Superfish софтвер на Windows рачунару.&lt;/p&gt;
&lt;p&gt;Пратите ове кораке да бисте привремено онемогућили софтвер и приступили вебу. Требаће вам привилегије администратора.&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@
&lt;li&gt;Прво кликните на &lt;strong&gt;Apply&lt;/strong&gt; (Примени), па на &lt;strong&gt;OK&lt;/strong&gt; (У реду)
&lt;li&gt;Посетите &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome центар за помоћ&lt;/a&gt; да бисте сазнали како да трајно уклоните софтвер са рачунара
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Управљајте производом <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Управљај лозинкама...</translation>
<translation id="7419106976560586862">Путања профила</translation>
<translation id="7437289804838430631">Додај контакт информације</translation>
@@ -1012,22 +1154,24 @@
<translation id="7442725080345379071">Светлонаранџаста</translation>
<translation id="7444046173054089907">Овај сајт је блокиран</translation>
<translation id="7445762425076701745">Није могуће у потпуности потврдити идентитет сервера са којим сте повезани. Повезани сте са сервером који користи назив који је важећи само у вашој мрежи, а којем спољни ауторитет за издавање сертификата не може да провери власништво. Будући да неки ауторитети за издавање сертификата упркос томе издају сертификате за ове називе, ни на који начин не можете да будете сигурни да сте повезани са жељеним веб-сајтом, а не са нападачем.</translation>
-<translation id="7449109375006139765">да шаље системске евиденције на сервер за управљање</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />да сазнате више<ph name="END_LINK" /> о овом проблему.</translation>
<translation id="7455133967321480974">Користи глобалну подразумевану вредност (Блокирај)</translation>
<translation id="7460618730930299168">Приказ се разликује од онога што сте изабрали. Желите ли да наставите?</translation>
<translation id="7473891865547856676">Не, хвала</translation>
-<translation id="7475525192983021547">да пријављује временске периоде када је корисник активан на уређају</translation>
<translation id="7481312909269577407">Проследи</translation>
<translation id="7485870689360869515">Нису пронађени подаци.</translation>
+<translation id="7498234416455752244">Наставите са изменама</translation>
<translation id="7508255263130623398">Враћени ИД уређаја за смернице је празан или се не подудара са актуелним ИД-ом уређаја</translation>
<translation id="7508870219247277067">Зеленожута</translation>
<translation id="7511955381719512146">Wi-Fi мрежа коју користите ће можда захтевати да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Преузми</translation>
<translation id="7518003948725431193">Ниједна веб-страница није пронађена за веб адресу: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (коверат)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Веза са овим сајтом није приватна</translation>
+<translation id="7535087603100972091">Вредност</translation>
<translation id="7537536606612762813">Обавезно</translation>
+<translation id="7538364083937897561">A2 (коверат)</translation>
<translation id="7542403920425041731">Када будете потврдили, подаци о картици ће бити послати овом сајту.</translation>
<translation id="7542995811387359312">Онемогућено је аутоматско попуњавање кредитне картице зато што овај образац не користи безбедну везу.</translation>
<translation id="7543525346216957623">Питај родитеља</translation>
@@ -1036,8 +1180,8 @@
<translation id="7552846755917812628">Испробајте следеће савете:</translation>
<translation id="7554791636758816595">Нова картица</translation>
<translation id="7564049878696755256">Можете да изгубите приступ налогу за <ph name="ORG_NAME" /> или би могло да дође до крађе идентитета. Chrome вам препоручује да одмах промените лозинку.</translation>
-<translation id="7566125604157659769">Текст који сте копирали</translation>
<translation id="7567204685887185387">Овај сервер не може да докаже да је <ph name="DOMAIN" />; његов безбедносни сертификат је можда лажно издат. Узрок томе је можда погрешна конфигурација или нападач који је прекинуо везу.</translation>
+<translation id="7568105740864181217">Овим прегледачем управља компанија, школа или нека друга организација. Администратор може даљински да промени подешавање прегледача. Активностима на овом уређају се можда управља и ван Chrome-а. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Желите ли да уклоните кредитну картицу из Chrome-а?</translation>
<translation id="7569983096843329377">Црна</translation>
<translation id="7578104083680115302">Плаћајте брзо на сајтовима и у апликацијама на свим уређајима помоћу картица које сте сачували на Google-у.</translation>
@@ -1048,6 +1192,7 @@
<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="7633909222644580952">Подаци о учинку и извештаји о отказивању</translation>
<translation id="7637571805876720304">Желите ли да уклоните кредитну картицу из Chromium-а?</translation>
<translation id="7639968568612851608">Тамносива</translation>
<translation id="765676359832457558">Сакриј напредна подешавања...</translation>
@@ -1057,9 +1202,11 @@
<translation id="7667346355482952095">Враћени токен смерница је празан или се не подудара са актуелним токеном</translation>
<translation id="7668654391829183341">Непознат уређај</translation>
<translation id="7669271284792375604">Нападачи на овом сајту могу да покушају да вас преваре да бисте инсталирали програме који штете доживљају прегледања (на пример, тако што мењају почетну страницу или приказују додатне огласе на сајтовима које посећујете).</translation>
+<translation id="7676643023259824263">Потражите текст у привременој меморији, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Промените претраживач</translation>
<translation id="7682287625158474539">Испорука</translation>
<translation id="7687186412095877299">Попуњава обрасце за плаћање информацијама о сачуваним начинима плаћања</translation>
+<translation id="7697066736081121494">Prc8 (коверат)</translation>
<translation id="769721561045429135">Тренутно имате картице које могу да се користе само на овом уређају. Кликните на Настави да бисте прегледали картице.</translation>
<translation id="7699293099605015246">Чланци тренутно нису доступни</translation>
<translation id="7701040980221191251">Ниједна</translation>
@@ -1071,11 +1218,13 @@
<translation id="774634243536837715">Опасан садржај је блокиран.</translation>
<translation id="7752995774971033316">Не управља</translation>
<translation id="7755287808199759310">Родитељ може да га деблокира за тебе</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Можда је заштитни зид или антивирусни софтвер блокирао везу.</translation>
<translation id="7759163816903619567">Домен за приказ:</translation>
<translation id="7761701407923456692">Сертификат сервера се не подудара са URL адресом.</translation>
<translation id="7763386264682878361">Рашчлањивач манифеста за плаћање</translation>
<translation id="7764225426217299476">Додајте адресу</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Додај</translation>
<translation id="7793809570500803535">Могуће је да веб-страница на сајту <ph name="SITE" /> привремено не функционише или да је трајно премештена на нову веб адресу.</translation>
@@ -1087,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Желите ли да уклоните предлог из Chrome-а?</translation>
<translation id="7815407501681723534">Пронашли смо <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> за „<ph name="SEARCH_STRING" />“</translation>
-<translation id="7818867226424560206">Управљање смерницама</translation>
<translation id="782886543891417279">Wi-Fi мрежа коју користите (<ph name="WIFI_NAME" />) ће можда захтевати да посетите страницу за пријављивање.</translation>
+<translation id="7836231406687464395">Postfix (коверат)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Ниједна}=1{1 апликација (<ph name="EXAMPLE_APP_1" />)}=2{2 апликације (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# апликација (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}few{# апликације (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}other{# апликација (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Али, нисте невидљиви. Преласком у режим без архивирања нећете сакрити прегледање од послодавца, интернет провајдера или веб-сајтова које посећујете.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1097,7 +1246,7 @@
<translation id="7878562273885520351">Лозинка је можда компромитована</translation>
<translation id="7882421473871500483">Браон</translation>
<translation id="7887683347370398519">Проверите CVC и покушајте поново</translation>
-<translation id="7893255318348328562">Назив сесије</translation>
+<translation id="7904208859782148177">C3 (коверат)</translation>
<translation id="79338296614623784">Унесите важећи број телефона</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Истиче <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@
<translation id="7951415247503192394">(32-битни)</translation>
<translation id="7956713633345437162">Мобилни обележивачи</translation>
<translation id="7961015016161918242">Никад</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Није наведено</translation>
<translation id="800218591365569300">Пробајте да затворите друге картице или програме да бисте ослободили меморију.</translation>
+<translation id="8004582292198964060">Прегледач</translation>
<translation id="8009225694047762179">Управљај лозинкама</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Та картица и њена адреса за обрачун ће бити сачуване. Моћи ћете да је користите када сте пријављени на <ph name="USER_EMAIL" />.}one{Те картице и њихове адресе за обрачун ће бити сачуване. Моћи ћете да их користите када сте пријављени на <ph name="USER_EMAIL" />.}few{Те картице и њихове адресе за обрачун ће бити сачуване. Моћи ћете да их користите када сте пријављени на <ph name="USER_EMAIL" />.}other{Те картице и њихове адресе за обрачун ће бити сачуване. Моћи ћете да их користите када сте пријављени на <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">Тренутно не можемо да контактирамо родитеље. Пробај поново.</translation>
<translation id="8025119109950072390">Нападачи на овом сајту могу да вас преваре да бисте урадили нешто опасно, на пример, да инсталирате софтвер или откријете личне податке (попут лозинки, бројева телефона или бројева кредитних картица).</translation>
<translation id="8034522405403831421">Језик ове странице је <ph name="SOURCE_LANGUAGE" />. Желите ли да је преведете на <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Перо</translation>
+<translation id="8037117624646282037">Ко је недавно користио уређај</translation>
<translation id="8037357227543935929">Питај (подразумевано)</translation>
<translation id="803771048473350947">Датотека</translation>
<translation id="8041089156583427627">Пошаљи повратне информације</translation>
<translation id="8041940743680923270">Користи глобалну подразумевану вредност (Питај)</translation>
<translation id="8042918947222776840">Одаберите начин преузимања</translation>
<translation id="8057711352706143257">Софтвер „<ph name="SOFTWARE_NAME" />“ није правилно конфигурисан. Деинсталирање софтвера „<ph name="SOFTWARE_NAME" />“ обично решава проблем. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Уређај је конфигурисан:</translation>
+<translation id="8066955247577885446">Жао нам је, дошло је до грешке.</translation>
+<translation id="8074253406171541171">10x13 (коверат)</translation>
<translation id="8078141288243656252">Додавање напомене није могуће када је ротиран</translation>
<translation id="8079031581361219619">Желите ли поново да учитате сајт?</translation>
<translation id="8088680233425245692">Прегледање чланка није успело.</translation>
@@ -1130,11 +1283,12 @@
<translation id="8091372947890762290">Активација је на чекању на серверу</translation>
<translation id="8092774999298748321">Тамнољубичаста</translation>
<translation id="8094917007353911263">Мрежа коју користите ће можда захтевати да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Неважеће картице су уклоњене</translation>
<translation id="8103161714697287722">Начин плаћања</translation>
<translation id="8118489163946903409">Начин плаћања</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" />-ом управља <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Софтвер „<ph name="SOFTWARE_NAME" />“ није правилно инсталиран на рачунару или мрежи. Затражите од ИТ администратора да реши овај проблем.</translation>
-<translation id="8130693978878176684">Више не могу да вам помажем, наставите сами.</translation>
<translation id="8131740175452115882">Потврди</translation>
<translation id="8149426793427495338">Рачунар је прешао у режим спавања.</translation>
<translation id="8150722005171944719">Датотека на адреси <ph name="URL" /> не може да се чита. Можда је уклоњена или премештена или дозволе за датотеке спречавају приступ.</translation>
@@ -1144,8 +1298,11 @@
<translation id="8197543752516192074">Преведи страницу</translation>
<translation id="8201077131113104583">Неважећи URL за ажурирање за додатак са ИД-ом „<ph name="EXTENSION_ID" />“.</translation>
<translation id="8202097416529803614">Резиме поруџбине</translation>
+<translation id="8202370299023114387">Неусаглашеност</translation>
+<translation id="8206978196348664717">Prc4 (коверат)</translation>
<translation id="8211406090763984747">Веза је безбедна</translation>
<translation id="8218327578424803826">Додељена локација:</translation>
+<translation id="8220146938470311105">C7/C6 (коверат)</translation>
<translation id="8225771182978767009">Особа која је подесила овај рачунар је одлучила да блокира овај сајт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">Отворите страницу на новој картици без архивирања</translation>
@@ -1157,14 +1314,16 @@
<translation id="825929999321470778">Прикажи све сачуване лозинке</translation>
<translation id="8261506727792406068">Избриши</translation>
<translation id="8267698848189296333">Пријављујете се као <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Овим прегледачем управља <ph name="ENROLLMENT_DOMAIN" />. Администратор може даљински да промени подешавање прегледача. Активностима на овом уређају се можда управља и ван Chrome-а. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Пријави ме</translation>
<translation id="8288807391153049143">Прикажи сертификат</translation>
<translation id="8289355894181816810">Контактирајте администратора мреже ако нисте сигурни шта то значи.</translation>
<translation id="8293206222192510085">Додавање обележивача</translation>
<translation id="8294431847097064396">Извор</translation>
<translation id="8298115750975731693">Wi-Fi мрежа коју користите (<ph name="WIFI_NAME" />) ће можда захтевати да посетите <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Превођење није успело због проблема са мрежном везом.</translation>
-<translation id="8311129316111205805">Учитај сесију</translation>
<translation id="8332188693563227489">Приступ хосту <ph name="HOST_NAME" /> је одбијен</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">Ако разумете безбедносне ризике, можете да <ph name="BEGIN_LINK" />посетите овај сајт<ph name="END_LINK" /> пре него што уклонимо штетне програме.</translation>
@@ -1182,7 +1341,6 @@
<translation id="8416694386774425977">Конфигурација мреже је неважећа и не може да се увезе.
Додатни детаљи:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Уређајем управља <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Промени</translation>
<translation id="8428213095426709021">Подешавања</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">Име власника картице</translation>
<translation id="861775596732816396">Величина 4</translation>
<translation id="8620436878122366504">Родитељи га још увек нису одобрили</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Сачувај ову картицу на овом уређају</translation>
<translation id="8663226718884576429">Резиме поруџбине, <ph name="TOTAL_LABEL" />, још детаља</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, одговор, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Ваша веза са доменом <ph name="DOMAIN" /> није шифрована.</translation>
<translation id="8718314106902482036">Плаћање није довршено</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, предлог за претрагу</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило штетне програме<ph name="END_LINK" /> на <ph name="SITE" />.</translation>
<translation id="8763927697961133303">USB уређај</translation>
<translation id="8768895707659403558">Да бисте користили картице на свим уређајима, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Понови брисање</translation>
<translation id="8792621596287649091">Можете да изгубите приступ налогу за <ph name="ORG_NAME" /> или би могло да дође до крађе идентитета. Chromium вам препоручује да одмах промените лозинку.</translation>
<translation id="8800988563907321413">Предлози у близини ће се приказивати овде</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">Дељење са Google-ом</translation>
<translation id="8858065207712248076">Chrome вам препоручује да ресетујете лозинку за <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> ако сте је користили на другим сајтовима.</translation>
<translation id="8866481888320382733">Грешка при рашчлањивању подешавања смерница</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Недавно затворено</translation>
<translation id="8874824191258364635">Унесите важећи број картице</translation>
<translation id="8891727572606052622">Неважећи режим проксија.</translation>
<translation id="8903921497873541725">Увећавање</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Да ли желите да сачувате ову картицу на Google налог?</translation>
<translation id="8932102934695377596">Сат вам касни</translation>
<translation id="893332455753468063">Додајте име</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">Администратор је конфигурисао прилагођене сертификате основног нивоа што може да омогући администратору да види садржај веб-сајтова које посећујете.</translation>
<translation id="8943282376843390568">Јаркозелена</translation>
<translation id="8957210676456822347">Овлашћење на улазном порталу</translation>
+<translation id="8966619695390250636">Да ли сте мислили?</translation>
<translation id="8968766641738584599">Сачувај картицу</translation>
<translation id="8971063699422889582">Сертификат сервера је истекао.</translation>
<translation id="8975012916872825179">Обухвата информације попут бројева телефона, имејл адреса и адреса за испоруку</translation>
<translation id="8978053250194585037">Google безбедно прегледање је недавно <ph name="BEGIN_LINK" />открило „пецање“<ph name="END_LINK" /> на <ph name="SITE" />. Сајтови са „пецањем“ се представљају као неки други веб-сајтови да би вас преварили.</translation>
<translation id="8983003182662520383">Начини плаћања и адресе из Google Pay-а</translation>
<translation id="8987927404178983737">Месец</translation>
-<translation id="8988408250700415532">Дошло је до грешке. Поруџбину можете да довршите на веб-сајту.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сајт који ћете посетити садржи штетне програме</translation>
<translation id="8997023839087525404">Сервер је приказао сертификат који није јавно откривен помоћу смерница Транспарентност сертификата. То је обавезно за неке сертификате да бисмо се уверили да су поуздани и да штите од нападача.</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">Отворите подешавања сајта</translation>
<translation id="9020200922353704812">Адреса за обрачун за картицу је обавезна</translation>
<translation id="9020542370529661692">Ова страница је преведена на <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Неважеће)</translation>
<translation id="9035022520814077154">Безбедносна грешка</translation>
<translation id="9038649477754266430">Користите услугу предвиђања да бисте брже учитавали странице</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">Претрага <ph name="TEXT" /> из историје</translation>
<translation id="9069693763241529744">Блокира додатак</translation>
<translation id="9076283476770535406">Можда обухвата садржај за одрасле</translation>
+<translation id="9076630408993835509">Овим прегледачем не управља компанија или нека друга организација. Активностима на овом уређају се можда управља ван Chrome-а. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Потребно је више информација</translation>
<translation id="9080712759204168376">Резиме поруџбине</translation>
<translation id="9103872766612412690"><ph name="SITE" /> обично користи шифровање да би заштитио информације. Када је Chromium овог пута покушао да се повеже са <ph name="SITE" />, веб-сајт је вратио необичне и нетачне акредитиве. Или нападач покушава да се представи као <ph name="SITE" /> или је екран за Wi-Fi пријављивање прекинуо везу. Информације су и даље безбедне зато што је Chromium прекинуо везу пре него што су размењени било какви подаци.</translation>
<translation id="9106062320799175032">Додајте адресу за обрачун</translation>
-<translation id="9110718169272311511">Google помоћник у Chrome-у је доступан у дну екрана</translation>
<translation id="9114524666733003316">Картица се потврђује...</translation>
<translation id="9128870381267983090">Повезивање са мрежом</translation>
<translation id="9137013805542155359">Прикажи оригинал</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;Опозови измену</translation>
<translation id="9154194610265714752">Ажурирано</translation>
<translation id="9157595877708044936">Подешавање...</translation>
+<translation id="9158625974267017556">C6 (коверат)</translation>
<translation id="9168814207360376865">Дозволите сајтовима да проверавају да ли имате сачуване начине плаћања</translation>
<translation id="9169664750068251925">Увек блокирај на овом сајту</translation>
<translation id="9170848237812810038">&amp;Опозови</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">Слике</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОБРИШИ ОБРАЗАЦ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Могли бисте да изгубите приступ Google налогу. Chromium препоручује да одмах промените лозинку. Мораћете да се пријавите.</translation>
<translation id="939736085109172342">Нови директоријум</translation>
<translation id="945855313015696284">Проверите информације у наставку и избришите све неважеће картице</translation>
<translation id="951104842009476243">Дебитне и припејд картице које се прихватају</translation>
+<translation id="958202389743790697">Блокирано је у складу са безбедносним смерницама (<ph name="ORIGIN" />).</translation>
<translation id="962484866189421427">Овај садржај можда покушава да инсталира обмањујуће апликације које се претварају да су нешто друго или да прикупљају податке који могу да се користе за праћење. <ph name="BEGIN_LINK" />Прикажи<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Званична верзија</translation>
<translation id="973773823069644502">Додај адресу за доставу</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">Начини плаћања</translation>
<translation id="985199708454569384">&lt;p&gt;Ова грешка се приказује ако датум и време на рачунару или мобилном уређају нису тачни.&lt;/p&gt;
&lt;p&gt;Да бисте отклонили грешку, отворите сат на уређају. Уверите се да су време и датум тачни.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Верзија за програмере</translation>
<translation id="989988560359834682">Измена адресе</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_sv.xtb b/chromium/components/strings/components_strings_sv.xtb
index f0bfce678a9..ff5c433d5f7 100644
--- a/chromium/components/strings/components_strings_sv.xtb
+++ b/chromium/components/strings/components_strings_sv.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sv">
-<translation id="1005145902654145231">Det gick inte att byta namn på sessionen.</translation>
<translation id="1008557486741366299">Inte nu</translation>
<translation id="1010200102790553230">Läs in sidan senare</translation>
<translation id="1015730422737071372">Ange ytterligare information</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">okänt namn</translation>
<translation id="1050038467049342496">Stäng andra appar</translation>
<translation id="1055184225775184556">&amp;Ångra Lägg till</translation>
+<translation id="1056898198331236512">Varning</translation>
<translation id="1058479211578257048">Sparar kort …</translation>
<translation id="10614374240317010">Aldrig sparad</translation>
+<translation id="1062160989074299343">Prc10 (kuvert)</translation>
<translation id="106701514854093668">Bokmärken på skrivbordet</translation>
<translation id="1074497978438210769">Inte säker</translation>
<translation id="1080116354587839789">Anpassa till fönstrets bredd</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Lägg till namnet på kortet</translation>
<translation id="1089439967362294234">Ändra lösenordet</translation>
<translation id="109743633954054152">Hantera lösenord i Chrome-inställningarna</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Varningar kan förekomma medan en webbplats uppdaterar säkerheten. Detta förbättras inom kort.</translation>
<translation id="1126551341858583091">Storleken på det lokala lagringsutrymmet är <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Cacheminnet för policyn är OK</translation>
+<translation id="1131264053432022307">Bilden som du kopierade</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Ändra namn</translation>
<translation id="1175364870820465910">Skriv &amp;ut...</translation>
<translation id="1181037720776840403">Ta bort</translation>
<translation id="1197088940767939838">Orange</translation>
@@ -45,9 +47,9 @@
<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 princip.</translation>
-<translation id="1227633850867390598">Dölj värde</translation>
<translation id="1228893227497259893">Fel enhetsidentifierare</translation>
<translation id="1232569758102978740">Namnlös</translation>
+<translation id="1240347957665416060">Ditt enhetsnamn</translation>
<translation id="124116460088058876">Fler språk</translation>
<translation id="1250759482327835220">Spara kortet, faktureringsadressen och ditt namn i Google-kontot så går det snabbare att betala nästa gång.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkroniserade)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Varianter på kommandoraden</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="1314614906530272393">Den valda sessionen finns inte.</translation>
+<translation id="1320233736580025032">Prc1 (kuvert)</translation>
+<translation id="132301787627749051">Sök efter bilden i Urklipp</translation>
<translation id="1323433172918577554">Visa fler</translation>
<translation id="132390688737681464">Spara och fyll i adresser</translation>
<translation id="1333989956347591814">Din aktivitet <ph name="BEGIN_EMPHASIS" />kanske fortfarande är synlig<ph name="END_EMPHASIS" /> för:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Hämtningsadress</translation>
<translation id="1348198688976932919">Det finns farliga appar på webbplatsen du är på väg till</translation>
<translation id="1348779747280417563">Bekräfta namn</translation>
+<translation id="1357195169723583938">Vem har använt enheten nyligen och när</translation>
+<translation id="1364822246244961190">Den här principen är blockerad. Dess värde ignoreras.</translation>
<translation id="1374468813861204354">förslag</translation>
+<translation id="1374692235857187091">Index-4x6 (vykort)</translation>
<translation id="1375198122581997741">Om version</translation>
<translation id="1376836354785490390">Visa färre</translation>
<translation id="1377321085342047638">Kortnummer</translation>
<translation id="138218114945450791">Ljusblå</translation>
+<translation id="1382194467192730611">USB-enhet som tillåtits av administratören</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> skickade ingen data.</translation>
+<translation id="140316286225361634">Webbplatsen <ph name="ORIGIN" /> har begärt att en säkerhetsprincip ska gälla för
+ varje begäran som ställs till den, och för närvarande ses webbplatsen
+ som osäker enligt principen.</translation>
<translation id="1405567553485452995">Ljusgrön</translation>
<translation id="1407135791313364759">Öppna alla</translation>
<translation id="1413809658975081374">Sekretessfel</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ja</translation>
<translation id="1430915738399379752">Skriv ut</translation>
<translation id="1455413310270022028">Suddgummi</translation>
+<translation id="1463543813647160932">5:7</translation>
+<translation id="1472675084647422956">Visa fler</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Välj leveransadress</translation>
+<translation id="1492194039220927094">Skicka principer:</translation>
<translation id="1501859676467574491">Visa kort från ditt Google-konto</translation>
-<translation id="1506687042165942984">Visa en sparad kopia av sidan (en som vi vet är inaktuell).</translation>
<translation id="1507202001669085618">&lt;p&gt;Felmeddelandet visas om du använder en Wi-Fi-portal där du måste logga in innan du kommer ut på internet.&lt;/p&gt;
&lt;p&gt;Åtgärda problemet genom att klicka på &lt;strong&gt;Anslut&lt;/strong&gt; på sidan du försöker öppna.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefonnummer är obligatoriskt</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Programversionsdatum</translation>
<translation id="1521655867290435174">Google Kalkylark</translation>
<translation id="1527263332363067270">Väntar på anslutning …</translation>
+<translation id="1529521330346880926">10x15 (kuvert)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">På den här sidan står det</translation>
<translation id="153384715582417236">Det var allt för den här gången</translation>
<translation id="154408704832528245">Välj leveransadress</translation>
<translation id="1549470594296187301">JavaScript måste aktiveras för att du ska kunna använda den här funktionen.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Ange sista giltighetsdatum</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Bilden som du kopierade</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Hindra sidan från att skapa fler dialogrutor</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Avsluta session</translation>
<translation id="1639239467298939599">Läser in</translation>
<translation id="1640180200866533862">Användarpolicyer</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Servercertifikatet innehåller en svag kryptografisk nyckel.</translation>
<translation id="1697532407822776718">Färdigt!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Det går inte att annotera det här dokumentet eftersom det är för stort</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Kontakta systemadministratören.</translation>
<translation id="1740951997222943430">Ange en giltig utgångsmånad</translation>
<translation id="1743520634839655729">Spara kortet, faktureringsadressen och namnet i Google-kontot och på enheten så går det snabbare att betala nästa gång.</translation>
+<translation id="1745880797583122200">Din webbläsare hanteras</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Uppdatera lösenfrasen för synkroniseringen.</translation>
<translation id="1787142507584202372">Öppna flikar visas här</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Namn på kortinnehavare</translation>
<translation id="1821930232296380041">Begäran eller parametrar i begäran var ogiltiga</translation>
+<translation id="1822540298136254167">De webbplatser du besöker och hur länge du är där</translation>
<translation id="1826516787628120939">Kontrollerar</translation>
<translation id="1834321415901700177">Den här webbplatsen innehåller skadliga program</translation>
<translation id="1839551713262164453">Valideringen av principvärdena har misslyckats med fel</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Rensa webbhistoriken i Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{och 1 till}other{och # till}}</translation>
<translation id="2003709556000175978">Återställ lösenordet nu</translation>
+<translation id="20053308747750172">Servern som du är på väg till, <ph name="ORIGIN" />, har begärt att en
+ säkerhetsprincip ska gälla varje gång den svarar på en begäran. Men den har nu
+ skickat en ogiltig princip, vilket gör att det inte
+ går att slutföra begäran om <ph name="SITE" /> i webbläsaren.</translation>
<translation id="2025186561304664664">Proxyn är inställd på automatisk konfiguration.</translation>
<translation id="2030481566774242610">Menade du <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />kontrollera proxyn och brandväggen<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Departement</translation>
<translation id="2102134110707549001">Föreslå ett starkt lösenord …</translation>
<translation id="2108755909498034140">Starta om datorn</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kort</translation>
<translation id="2114841414352855701">Ignoreras eftersom den åsidosätts av <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Bokmärken i mobilen</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (kuvert)</translation>
<translation id="2181821976797666341">Policyer</translation>
<translation id="2183608646556468874">Telefonnummer</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adress}other{# adresser}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefonnummer</translation>
<translation id="2283340219607151381">Spara och fyll i adresser</translation>
<translation id="2292556288342944218">Internetanslutningen har blockerats</translation>
+<translation id="2294558542833290837">Länken som du öppnade först är ovanlig</translation>
+<translation id="2297722699537546652">B5 (kuvert)</translation>
+<translation id="2310021320168182093">Chou2 (kuvert)</translation>
<translation id="2316887270356262533">Frigör mindre än 1 MB. Vissa webbplatser kan läsas in långsammare nästa gång du besöker dem.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> kräver användarnamn och lösenord.</translation>
<translation id="2317583587496011522">Betalkort kan användas.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" /> upphör att gälla den <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Inställningen styrs av administratören</translation>
+<translation id="2346319942568447007">Bilden som du kopierade</translation>
<translation id="2349790679044093737">En VR-session pågår</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Felrapport som skapades <ph name="CRASH_TIME" /> laddades inte upp</translation>
<translation id="2367567093518048410">Nivå</translation>
<translation id="2378238891085281592">Du surfar privat</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Servern som du är på väg till, <ph name="ORIGIN" />, har begärt att en
+ säkerhetsprincip ska gälla varje gång den svarar på en begäran. Men den skickade
+ ingen princip, och därför går det inte att slutföra begäran
+ om <ph name="SITE" /> i webbläsaren.</translation>
<translation id="244665789865330679">Enheten och kontot hanteras av <ph name="ENROLLMENT_DOMAIN" />. Detta innebär att administratören kan fjärrkonfigurera enheten och kontot.</translation>
<translation id="2463193859425327265">Ändra startsida</translation>
<translation id="2463739503403862330">Fyll i</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Välj leveranssätt</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />att köra nätverksdiagnostik<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Översätt den här sidan</translation>
<translation id="2479410451996844060">Ogiltig sökadress.</translation>
<translation id="2482878487686419369">Aviseringar</translation>
<translation id="248348093745724435">Datorprinciper</translation>
+<translation id="2485387744899240041">Användarnamn för din enhet och webbläsare</translation>
<translation id="2491120439723279231">Servercertifikatet innehåller fel.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Läs in ett nytt kort</translation>
<translation id="2501278716633472235">Föregående</translation>
<translation id="2503184589641749290">Godkända betalkort och förbetalda kort</translation>
<translation id="2515629240566999685">kontrollera mottagningen i området</translation>
-<translation id="2516852381693169964">Sök på <ph name="SEARCH_ENGINE" /> efter bild</translation>
<translation id="2523886232349826891">Endast sparat på den här enheten</translation>
<translation id="2524461107774643265">Lägg till mer information</translation>
<translation id="2536110899380797252">Lägg till adress</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (kuvert)</translation>
<translation id="2625385379895617796">Klockan går före</translation>
<translation id="2634124572758952069">Det gick inte att hitta IP-adressen till servern på <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Status:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Stäng andra flikar eller appar</translation>
<translation id="267371737713284912">tryck på <ph name="MODIFIER_KEY_DESCRIPTION" /> för att ångra</translation>
<translation id="2674170444375937751">Vill du ta bort de här sidorna från historiken?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Lämna</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Godkända kort</translation>
<translation id="2702801445560668637">Läslista</translation>
<translation id="2704283930420550640">Värdet matchar inte formatet.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Ta bort valda objekt</translation>
<translation id="277133753123645258">Fraktalternativ</translation>
<translation id="277499241957683684">Enhetsregister saknas</translation>
-<translation id="2781030394888168909">Exportera för MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Anslutningen återställdes.</translation>
<translation id="2788784517760473862">Godkända kreditkort</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Öppna ett inkognitofönster</translation>
+<translation id="2850739647070081192">Invite (kuvert)</translation>
<translation id="2851634818064021665">Du behöver tillstånd att besöka den här webbplatsen</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Vill du spara kortet?</translation>
<translation id="2903493209154104877">Adresser</translation>
<translation id="290376772003165898">Är sidan inte på <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Leveranssätt</translation>
<translation id="2928905813689894207">Faktureringsadress</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (kuvert)</translation>
<translation id="3024663005179499861">Felaktig policytyp</translation>
<translation id="3037605927509011580">Oj, ett fel har uppstått!</translation>
<translation id="3041612393474885105">Certifikatinformation</translation>
+<translation id="3060227939791841287">C9 (kuvert)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Lägg till hämtningsadress</translation>
<translation id="3105172416063519923">Tillgångs-id:</translation>
<translation id="3109728660330352905">Du är inte behörig att se den här sidan.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> på <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Avbryt betalningen</translation>
<translation id="3207960819495026254">Bokmärkt</translation>
-<translation id="3209375525920864198">Ange ett giltigt sessionsnamn.</translation>
+<translation id="321912867715453276">Varning! Principen har fler än en källa, men med samma värden.</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="3229041911291329567">Versionsinformation om enhet och webbläsare</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Lägg till namnet på kortet</translation>
<translation id="3287510313208355388">Ladda ned när du är online</translation>
<translation id="3293642807462928945">Läs mer om principen <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Inga sökresultat hittades</translation>
-<translation id="3305707030755673451">Din data krypterades med din lösenfras för synkronisering den <ph name="TIME" />. Ange den om du vill starta synkroniseringen.</translation>
<translation id="3320021301628644560">Lägg till faktureringsadress</translation>
<translation id="3324983252691184275">Karmosinröd</translation>
<translation id="3338095232262050444">Säker</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Gör om Redigera</translation>
<translation id="342781501876943858">Du rekommenderas att återställa lösenordet om du har återanvänt det på andra webbplatser.</translation>
<translation id="3431636764301398940">Spara kortet på enheten</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Enhetens ägare har stängt av dinosauriespelet.</translation>
<translation id="3447884698081792621">Visa certifikat (utfärdat av <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Hämta intervall:</translation>
+<translation id="3456231139987291353">Number-11 (kuvert)</translation>
<translation id="3461824795358126837">Överstrykningspenna</translation>
<translation id="3462200631372590220">Dölja avancerade uppgifter</translation>
<translation id="3467763166455606212">Kortinnehavarens namn måste anges</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kreditkort och förbetalda kort kan användas.</translation>
<translation id="3582930987043644930">Lägg till namn</translation>
<translation id="3583757800736429874">&amp;Gör om Flytta</translation>
+<translation id="35866233670761917">Administratören kan inte se innehållet på webbplatser du besöker</translation>
<translation id="3586931643579894722">Dölj detaljerad information</translation>
+<translation id="3592413004129370115">Italian (kuvert)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Storlek 2</translation>
<translation id="3615877443314183785">Ange ett giltigt utgångsdatum</translation>
<translation id="36224234498066874">Rensa webbinformation ...</translation>
<translation id="362276910939193118">Visa fullständig historik</translation>
-<translation id="3623476034248543066">Visa värde</translation>
<translation id="3630155396527302611">Om den redan finns med på listan över program som har tillgång till nätverket
kan du prova att ta bort den från listan och sedan lägga till den igen.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Valideringen har genomförts</translation>
<translation id="3655670868607891010">Om du ser detta ofta provar du <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Version</translation>
<translation id="366077651725703012">Uppdatera kreditkortet</translation>
<translation id="3676592649209844519">Enhets-id:</translation>
+<translation id="3677008721441257057">Menade du &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Begäran kunde inte signeras</translation>
<translation id="3678529606614285348">Öppna sidan i ett nytt inkognitofönster (Ctrl-Skift-N)</translation>
<translation id="3679803492151881375">Kraschrapporten skapades den <ph name="CRASH_TIME" /> och laddades upp den <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Nätverket du använder kanske kräver att du besöker dess inloggningssida.</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="3709599264800900598">Texten som du kopierade</translation>
<translation id="3712624925041724820">Licenserna har tagit slut</translation>
<translation id="3714780639079136834">aktivera mobildata eller Wi-Fi</translation>
<translation id="3715597595485130451">Anslut till Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />kontrollera proxyn, brandväggen och DNS-konfigureringen<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Det här problemet kan orsakas av bland annat antivirusprogram, brandväggar, webbfiltrerings- och proxyprogram.</translation>
+<translation id="373042150751172459">B4 (kuvert)</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="3745099705178523657">När du bekräftar delas kortuppgifter från ditt Google-konto med webbplatsen.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Utgångsdatum: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Storlek 16</translation>
+<translation id="3797522431967816232">Prc3 (kuvert)</translation>
<translation id="3807873520724684969">Skadligt innehåll har blockerats.</translation>
<translation id="3810973564298564668">Hantera</translation>
<translation id="382518646247711829">Om du använder en proxyserver ...</translation>
<translation id="3828924085048779000">Lösenfrasen får inte vara tom.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> har installerat tillägg för fler funktioner. Tilläggen har åtkomst till en del av din data.</translation>
<translation id="385051799172605136">Bakåt</translation>
<translation id="3858027520442213535">Uppdatera datum och tid</translation>
<translation id="3884278016824448484">Motstridiga enhetsidentifierare</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Fråga alltid på den här webbplatsen</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Detta sessionsnamn finns redan.</translation>
<translation id="3987940399970879459">Mindre än 1 MB</translation>
+<translation id="4008849406247176967">Varning! Den här principen har flera källor med olika värden.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 webbsida i närheten}other{# webbsidor i närheten}}</translation>
<translation id="4030383055268325496">&amp;Ångra Lägg till</translation>
+<translation id="4032320456957708163">Din webbläsare hanteras av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Nyckel <ph name="SUBKEY" />: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (kuvert)</translation>
<translation id="4067947977115446013">Lägg till giltig adress</translation>
<translation id="4072486802667267160">Det gick inte att behandla beställningen. Försök igen.</translation>
<translation id="4075732493274867456">Klienten och servern har inte stöd för en gemensam SSL-protokollversion eller chiffersvit.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Lila</translation>
<translation id="4165986682804962316">Platsinställningar</translation>
<translation id="4171400957073367226">Felaktig verifieringssignatur</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> objekt till}other{<ph name="ITEM_COUNT" /> objekt till}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (kuvert)</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="4221630205957821124">&lt;h4&gt;Steg 1: Logga in på portalen&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Återställ lösenord</translation>
<translation id="4280429058323657511">, utgångsdatum <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Det här kortet har sparats i ditt Google-konto}other{De här korten har sparats i ditt Google-konto}}</translation>
+<translation id="42981349822642051">Expandera</translation>
+<translation id="4302965934281694568">Chou3 (kuvert)</translation>
<translation id="4305817255990598646">Byt</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Blockera (standard)</translation>
+<translation id="4318566738941496689">Enhetens namn och nätverksadress</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äker</translation>
<translation id="4340982228985273705">Den här datorn har inte identifierats som företagshanterad, så bara tillägg på Chrome Web Store kan installeras automatiskt med principen. Uppdateringsadressen på Chrome Web Store är <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Godkända kreditkort</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Hantera betalningsmetoder …</translation>
+<translation id="4367563149485757821">Number-12 (kuvert)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Mobil</translation>
<translation id="4406896451731180161">sökresultat</translation>
-<translation id="4406972042435603828">Administratören har installerat tillägg med funktioner som har vidsträckt påverkan.</translation>
<translation id="4408413947728134509">Cookies <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Hämtningsadress</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="443121186588148776">Serieport</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> godkände inte inloggningscertifikatet eller så har inget inloggningscertifikat angetts.</translation>
<translation id="4434045419905280838">Popup och omdirigeringar</translation>
+<translation id="4435702339979719576">vykort)</translation>
<translation id="443673843213245140">Användning av proxy är inaktiverad men en explicit proxykonfiguration har angetts.</translation>
<translation id="445100540951337728">Godkända betalkort</translation>
+<translation id="4466881336512663640">Ändringar i formuläret ändras inte. Vill du fortsätta?</translation>
<translation id="4482953324121162758">Den här webbplatsen översätts inte.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Ogiltig webbadress. Måste vara en webbadress med ett standardprotokoll, t.ex. http://example.com eller https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (kuvert)</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="4517607026994743406">Comm-10 (kuvert)</translation>
<translation id="4522570452068850558">Info</translation>
<translation id="4524805452350978254">Hantera kort</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Testa att inaktivera tilläggen.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Leverans</translation>
+<translation id="4579056131138995126">Personal (kuvert)</translation>
<translation id="4582204425268416675">Ta bort kort</translation>
<translation id="4587425331216688090">Vill du ta bort adressen från Chrome?</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="4597348597567598915">Storlek 8</translation>
+<translation id="4600854749408232102">C6/C5 (kuvert)</translation>
<translation id="4646534391647090355">Gå dit nu</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="467809019005607715">Google Presentationer</translation>
<translation id="4690462567478992370">Sluta använda ett ogiltigt certifikat</translation>
+<translation id="4691835149146451662">Architecture-A (kuvert)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Anslutningen avbröts</translation>
<translation id="471880041731876836">Du har inte behörighet att besöka den här webbplatsen.</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" /> köra nätverksdiagnostik för Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Läs in policyer på nytt</translation>
<translation id="4728558894243024398">Plattform</translation>
+<translation id="4731967714531604179">Prc2 (kuvert)</translation>
<translation id="4736825316280949806">Starta om Chromium</translation>
<translation id="473775607612524610">Uppdatera</translation>
<translation id="4738601419177586157">Sökförslag för <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Hantera lösenord …</translation>
<translation id="4744603770635761495">Sökväg till körbar fil</translation>
+<translation id="4746351372139058112">Meddelanden</translation>
<translation id="4750917950439032686">Dina uppgifter (till exempel lösenord eller kreditkortsnummer) är privata när de skickas till den här webbplatsen.</translation>
<translation id="4756388243121344051">&amp;Historik</translation>
<translation id="4758311279753947758">Lägg till kontaktuppgifter</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Webbsidan på <ph name="URL" /> kan ligga nere för tillfället eller kan ha flyttats permanent till en ny webbadress.</translation>
<translation id="4771973620359291008">Ett okänt fel uppstod.</translation>
<translation id="4785689107224900852">Byt till den här fliken</translation>
-<translation id="4792143361752574037">Det gick inte att få åtkomst till sessionsfilerna. Det går för närvarande inte att spara till enheten. Läs in sidan igen och gör ett nytt försök.</translation>
<translation id="4798078619018708837">Uppdatera kortinformationen genom att ange sista giltighetsdatum och CVC-kod för <ph name="CREDIT_CARD" />. När du bekräftar delas kortuppgifter från ditt Google-konto med webbplatsen.</translation>
<translation id="4800132727771399293">Kontrollera utgångsdatum och CVC-kod och försök igen</translation>
+<translation id="480334179571489655">Fel vid tillämpning av ursprungsprincip</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Öppna</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Inga resultat</translation>
<translation id="4950898438188848926">Knapp för flikbyte. Tryck på retur för att byta till den öppna fliken <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Åtgärder</translation>
-<translation id="495832697253704892">Tilläggsrapportering</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Expandera lista</translation>
<translation id="4974590756084640048">Aktivera varningar igen</translation>
+<translation id="4984339528288761049">Prc5 (kuvert)</translation>
<translation id="4989163558385430922">Visa alla</translation>
<translation id="4989809363548539747">Det här pluginprogrammet stöds inte</translation>
-<translation id="4996230189582812866">Rapportering</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="5014174725590676422">Skärmen vid första användningen av Googe-assistenten i Chrome visas</translation>
<translation id="5015510746216210676">Datornamn:</translation>
+<translation id="5017554619425969104">Texten som du kopierade</translation>
<translation id="5018422839182700155">Det går inte att öppna den här sidan</translation>
<translation id="5019198164206649151">Säkerhetskopian har dålig status</translation>
<translation id="5023310440958281426">Kontrollera administratörsprinciperna</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Lokala <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Tillåt</translation>
<translation id="5040262127954254034">Sekretess</translation>
+<translation id="5043480802608081735">Länk som du har kopierat</translation>
<translation id="5045550434625856497">Felaktigt lösenord</translation>
<translation id="5056549851600133418">Artiklar för dig</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />kontrollera proxyadressen<ph name="END_LINK" /></translation>
<translation id="5087286274860437796">Servercertifikatet är inte giltigt för närvarande.</translation>
<translation id="5087580092889165836">Lägg till kort</translation>
<translation id="5089810972385038852">Stat</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="5097099694988056070">Enhetsstatistik, till exempel processor- och RAM-användning</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Enheten hanteras av <ph name="ENROLLMENT_DOMAIN" /> och kontot hanteras av <ph name="ACCOUNT_DOMAIN" />. Detta innebär att administratörerna kan fjärrkonfigurera enheten och kontot.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bitar)</translation>
-<translation id="5128122789703661928">Sessionen med det här namnet går inte att radera.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Hantera adresser …</translation>
+<translation id="5138227688689900538">Visa färre</translation>
<translation id="5141240743006678641">Kryptera synkroniserade lösenord med dina inloggningsuppgifter för Google</translation>
<translation id="5145883236150621069">Felkoden ingår i policysvaret</translation>
+<translation id="515292512908731282">C4 (kuvert)</translation>
<translation id="5159010409087891077">Öppna sidan i ett nytt inkognitofönster (⇧⌘N)</translation>
<translation id="516920405563544094">Ange CVC-koden för <ph name="CREDIT_CARD" />. När du bekräftar delas kortuppgifter från ditt Google-konto med webbplatsen.</translation>
<translation id="5169827969064885044">Du kan förlora åtkomsten till organisationens konto eller bli utsatt för identitetsstöld. Du rekommenderas att ändra lösenordet nu.</translation>
<translation id="5171045022955879922">Sök eller ange webbadress</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Dator</translation>
<translation id="5179510805599951267">Inte på <ph name="ORIGINAL_LANGUAGE" />? Rapportera felet</translation>
<translation id="5190835502935405962">Bokmärkesfältet</translation>
-<translation id="5200263511887412697">rapportera en lista över enhetsanvändare som har loggat in nyligen</translation>
+<translation id="519422657042045905">Kommentering är inte tillgängligt</translation>
<translation id="5201306358585911203">På en inbäddad sida på den här sidan står det</translation>
<translation id="5205222826937269299">Namn måste anges</translation>
<translation id="5215116848420601511">Betalningsmetoder och adresser som används med Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-postadress måste anges</translation>
<translation id="5230733896359313003">Leveransadress</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">Anslut till ett nätverk</translation>
<translation id="5251803541071282808">Moln</translation>
+<translation id="5252000469029418751">C7 (kuvert)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Nätverksadresser</translation>
<translation id="5285570108065881030">Visa alla sparade lösenord</translation>
<translation id="5287240709317226393">Visa cookies</translation>
<translation id="5288108484102287882">Valideringen av principvärdena har utlöst varningar</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> av <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Välj kontaktuppgifter</translation>
<translation id="5327248766486351172">Namn</translation>
+<translation id="5329858041417644019">Din webbläsare är inte hanterad</translation>
<translation id="5332219387342487447">Fraktmetod</translation>
+<translation id="5334013548165032829">Detaljerade systemloggar</translation>
<translation id="5344579389779391559">Den här sidan kan försöka debitera dig</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">Klockan går efter, Klockan går före eller &lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;</translation>
<translation id="5384855140246857529">Logga in och aktivera synkronisering så kan du använda korten på alla enheter.</translation>
<translation id="5386426401304769735">Certifikatkedjan för den här webbplatsen innehåller ett certifikat som signerades med SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Ogiltigt</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Gör om Redigera</translation>
+<translation id="5478437291406423475">B6/C4 (kuvert)</translation>
<translation id="5481076368049295676">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="54817484435770891">Lägg till giltig adress</translation>
<translation id="5490432419156082418">Adresser och annat</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Testa med att kontakta systemadministratören.</translation>
<translation id="549333378215107354">Storlek 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Hanterade bokmärken</translation>
<translation id="5510766032865166053">Den kan ha flyttats eller tagits bort.</translation>
<translation id="5523118979700054094">Policynamn</translation>
<translation id="552553974213252141">Extraherades texten korrekt?</translation>
+<translation id="553484882784876924">Prc6 (kuvert)</translation>
<translation id="5540224163453853">Det gick inte att hitta den önskade artikeln.</translation>
<translation id="5541546772353173584">Lägg till e-postadress</translation>
<translation id="5545756402275714221">Artiklar för dig</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Redigera adress</translation>
<translation id="5598944008576757369">Välj betalningsmetod</translation>
<translation id="560412284261940334">Hantering stöds inte</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> omdirigerade dig för många gånger.</translation>
<translation id="5629630648637658800">Det gick inte att läsa in policyinställningarna</translation>
<translation id="5631439013527180824">Ogiltig enhetshanteringstoken</translation>
+<translation id="5632627355679805402">Din data krypterades med det <ph name="BEGIN_LINK" />Google-lösenord<ph name="END_LINK" /> du hade den <ph name="TIME" />. Ange det om du vill starta synkroniseringen.</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="563324245173044180">Bedrägligt innehåll har blockerats.</translation>
<translation id="5659593005791499971">E-post</translation>
+<translation id="5663614846592581799">9x11 (kuvert)</translation>
+<translation id="5663955426505430495">Administratören för enheten har installerat tillägg för ytterligare funktioner. Tilläggen har åtkomst till en del av din data.</translation>
<translation id="5675650730144413517">Sidan fungerar inte</translation>
+<translation id="5684874026226664614">Det gick inte att översätta sidan.</translation>
<translation id="5685654322157854305">Lägg till leveransadress</translation>
<translation id="5689199277474810259">Exportera som JSON</translation>
<translation id="5689516760719285838">Plats</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Webbplatsens identitet har inte verifierats.</translation>
<translation id="5719499550583120431">Förbetalda kort kan användas.</translation>
<translation id="5720705177508910913">Aktuell användare</translation>
+<translation id="5728056243719941842">C5 (kuvert)</translation>
<translation id="5730040223043577876">Du rekommenderas att återställa lösenordet om du har återanvänt det på andra webbplatser.</translation>
<translation id="5732392974455271431">Dina föräldrar kan ta bort blockeringen</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Spara kortet i Google-kontot}other{Spara korten i Google-kontot}}</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="5770114862687765385">Den här filen verkar vara skadad. Återställ sessionen genom att klicka på återställningsknappen.</translation>
<translation id="5778550464785688721">MIDI-enheter – fullständig kontroll</translation>
<translation id="578305955206182703">Bärnstensfärgad</translation>
<translation id="57838592816432529">Stäng av ljudet</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>
+<translation id="5798290721819630480">Vill du ignorera ändringarna?</translation>
<translation id="5798683403665926540">Ändra startsida i Chrome-inställningarna</translation>
<translation id="5803412860119678065">Vill du att uppgifterna om <ph name="CARD_DETAIL" /> ska fyllas i?</translation>
<translation id="5804241973901381774">Behörigheter</translation>
<translation id="5810442152076338065">Anslutningen till <ph name="DOMAIN" /> är krypterad med en gammal krypteringssvit.</translation>
<translation id="5813119285467412249">&amp;Gör om Lägg till</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="5860033963881614850">Av</translation>
<translation id="5863847714970149516">Sidan du är på väg till kan försöka debitera dig</translation>
<translation id="5866257070973731571">Ange telefonnummer</translation>
<translation id="5869405914158311789">Webbplatsen kan inte nås</translation>
<translation id="5869522115854928033">Sparade lösenord</translation>
<translation id="5887400589839399685">Kortet har sparats</translation>
-<translation id="5893718151540690985">rapportera en lista över nätverksgränssnitt med typ och maskinvaruadress</translation>
<translation id="5893752035575986141">Kreditkort får användas.</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="5916664084637901428">På</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Vill du spara kortet i Google-kontot?</translation>
<translation id="5922853866070715753">Nästan klart</translation>
<translation id="5932224571077948991">Påträngande eller vilseledande annonser visas på webbplatsen</translation>
-<translation id="5939518447894949180">Återställ</translation>
<translation id="5946937721014915347">Öppnar <ph name="SITE_NAME" /> …</translation>
<translation id="5951495562196540101">Det går inte att registrera enheten med ett konsumentkonto (paketerad licens är tillgänglig).</translation>
<translation id="5967592137238574583">Redigera kontaktuppgifter</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Zooma ut</translation>
<translation id="5977489021191000276">Din enhet hanteras inte av någon administratör.</translation>
<translation id="5977976211062815271">På den här enheten</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Det gick inte att öppna betalningsappen</translation>
<translation id="5989320800837274978">Varken fasta proxyservrar eller en webbadress med PAC-skript har angetts.</translation>
<translation id="5990559369517809815">Förfrågningar till servern har blockerats av ett tillägg.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">rapportera maskinvarustatistik, till exempel CPU- och RAM-användning</translation>
<translation id="6034000775414344507">Ljusgrå</translation>
+<translation id="6034283069659657473">10x14 (kuvert)</translation>
<translation id="6039846035001940113">Kontakta webbplatsens ägare om problemet kvarstår.</translation>
<translation id="6040143037577758943">Stäng</translation>
<translation id="6044573915096792553">Storlek 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Vill du använda dina kort på alla enheter?</translation>
<translation id="6059925163896151826">USB-enheter</translation>
-<translation id="6071091556643036997">Ogiltig policytyp.</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="6094273045989040137">Annotera</translation>
<translation id="610911394827799129">Det kan finnas andra former av webbhistorik i Google-kontot på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Information om installerade tillägg och pluginprogram</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Frigör mindre än <ph name="SIZE" />. Vissa webbplatser kan läsas in långsammare nästa gång du besöker dem.</translation>
<translation id="6337534724793800597">Filtrera princip efter namn</translation>
<translation id="6358450015545214790">Vad innebär dessa?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Du kan komma att debiteras.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 annat förslag}other{# andra förslag}}</translation>
<translation id="6387754724289022810">Spara kortet och faktureringsadressen i Google-kontot och på enheten så går det snabbare att betala nästa gång.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Redigera bokmärke</translation>
+<translation id="6406765186087300643">C0 (kuvert)</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="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="6434309073475700221">Kasta</translation>
+<translation id="6446163441502663861">Kahu (kuvert)</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>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Starta om Chrome</translation>
<translation id="6529602333819889595">&amp;Gör om Ta bort</translation>
<translation id="6534179046333460208">Förslag från Physical Web</translation>
+<translation id="6556866813142980365">Upprepa</translation>
<translation id="6563469144985748109">Den ansvarige har inte godkänt den ännu</translation>
<translation id="6569060085658103619">Du visar en tilläggssida</translation>
+<translation id="6578796323535178455">C2 (kuvert)</translation>
<translation id="6579990219486187401">Ljusrosa</translation>
+<translation id="6583674473685352014">B6 (kuvert)</translation>
+<translation id="6587923378399804057">Länk som du har kopierat</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> hanteras inte</translation>
<translation id="6596325263575161958">Krypteringsalternativ</translation>
<translation id="6604181099783169992">Rörelse- eller ljussensorer</translation>
+<translation id="6609880536175561541">Prc7 (kuvert)</translation>
<translation id="6624427990725312378">Kontaktuppgifter</translation>
<translation id="6626291197371920147">Lägg till ett giltigt kortnummer</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Sök</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Policyn är föråldrad.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Från 1 webbplats (du loggas inte ut från Google-kontot)}other{Från # webbplatser (du loggas inte ut från Google-kontot)}}</translation>
<translation id="6657585470893396449">Lösenord</translation>
+<translation id="6670613747977017428">Tillbaka till säker webbplats.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Registreringstoken:</translation>
<translation id="6711464428925977395">Något är fel med proxyservern eller så är adressen felaktig.</translation>
<translation id="6723740634201835758">I Google-kontot</translation>
+<translation id="6738516213925468394">Din data krypterades med din <ph name="BEGIN_LINK" />lösenfras för synkronisering<ph name="END_LINK" /> den <ph name="TIME" />. Ange den om du vill starta synkroniseringen.</translation>
<translation id="674375294223700098">Fel - okänt servercertifikat.</translation>
<translation id="6744009308914054259">Du kan öppna Nedladdningar och läsa artiklar offline medan du väntar på anslutningen.</translation>
<translation id="6753269504797312559">Policyvärde</translation>
<translation id="6757797048963528358">Enheten gick i viloläge.</translation>
+<translation id="6768213884286397650">Hagaki (vykort)</translation>
<translation id="6778737459546443941">Din förälder har inte godkänt den ännu</translation>
<translation id="67862343314499040">Violett</translation>
+<translation id="6786747875388722282">Tillägg</translation>
<translation id="679355240208270552">Ignoreras eftersom standardsökmotorn inte har aktiverats av principen.</translation>
<translation id="681021252041861472">Obligatoriskt fält</translation>
<translation id="6810899417690483278">Anpassnings-id</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Enhet</translation>
<translation id="6970216967273061347">Distrikt</translation>
<translation id="6973656660372572881">Både fasta proxyservrar och en webbadress för PAC-skript anges.</translation>
+<translation id="6973932557599545801">Jag kan tyvärr inte hjälpa till. Fortsätt på egen hand.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Ljud av (standard)</translation>
<translation id="6984479912851154518">Om du betalar i en extern app sker inte det i privat läge. Vill du fortsätta?</translation>
<translation id="6989763994942163495">Visa avancerade inställningar ...</translation>
+<translation id="6993898126790112050">6x9 (kuvert)</translation>
<translation id="6996312675313362352">Översätt alltid <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Debiteringen kan göras en gång eller återkommande och det behöver inte framgå tydligt att detta händer.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Dölj</translation>
<translation id="7108819624672055576">Beviljades av ett tillägg</translation>
<translation id="7111012039238467737">(Giltigt)</translation>
+<translation id="7118618213916969306">Sök efter webbadressen i Urklipp, <ph name="SHORT_URL" /></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="7135130955892390533">Visa status</translation>
<translation id="7138472120740807366">Leveranssätt</translation>
<translation id="7139724024395191329">Emirat</translation>
+<translation id="7152423860607593928">Number-14 (kuvert)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Lavendelfärgad</translation>
-<translation id="7158980942472052083">Ogiltig webbadress. Måste vara en webbadress med ett standardprotokoll.</translation>
<translation id="717330890047184534">Gaia-id:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Servern som du är på väg till, <ph name="ORIGIN" />, har begärt att en
+ säkerhetsprincip ska gälla varje gång den svarar på en begäran. Men i stället för att
+ skicka en princip har den omdirigerat webbläsaren. Det gör att
+ det inte går att slutföra begäran om <ph name="SITE" /> i webbläsaren.</translation>
<translation id="7179323680825933600">Spara och fyll i betalningsmetoder</translation>
<translation id="7180611975245234373">Uppdatera</translation>
<translation id="7182878459783632708">Inga policyer har ställts in</translation>
<translation id="7186367841673660872">Sidan har översatts från<ph name="ORIGINAL_LANGUAGE" />till<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Frigör <ph name="SIZE" />. Vissa webbplatser kan läsas in långsammare nästa gång du besöker dem.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Administratören kan se</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> följer inte säkerhetsstandarderna.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /> om problemet.</translation>
<translation id="7219179957768738017">För anslutningen används <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Bearbetning pågår</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Det förekommer skadlig programvara på följande sida</translation>
+<translation id="724766306220616965">Varningar, konflikt</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="7251437084390964440">Nätverkskonfigurationen uppfyller inte ONC-standarden. Det kan hända att delar av konfigurationen inte kan importeras.
Mer information.
@@ -982,11 +1120,14 @@ Mer information.
<translation id="7300012071106347854">Koboltblå</translation>
<translation id="7302712225291570345"><ph name="TEXT" /></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="7313965965371928911">Varningar från <ph name="BEGIN_LINK" />Säker webbsökning<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Anslutningshjälp</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Kommandorad</translation>
-<translation id="7365061714576910172">Exportera för Linux</translation>
<translation id="7372973238305370288">sökresultat</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Nej</translation>
@@ -994,6 +1135,7 @@ Mer information.
<translation id="7381288752349550461">Åsidosätt hanterad session</translation>
<translation id="7390545607259442187">Bekräfta kort</translation>
<translation id="7400418766976504921">Webbadress</translation>
+<translation id="7403591733719184120">Din <ph name="DEVICE_NAME" /> hanteras</translation>
<translation id="7407424307057130981">&lt;p&gt;Det här felmeddelandet visas om du har programvaran Superfish på Windows-datorn.&lt;/p&gt;
&lt;p&gt;Inaktivera programvaran tillfälligt enligt anvisningarna nedan så att du kan komma ut på internet. Du måste ha administratörsbehörighet.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Mer information.
&lt;li&gt;Klicka på &lt;strong&gt;Verkställ&lt;/strong&gt; och sedan på &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Besök &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;hjälpcentret för Chrome&lt;/a&gt; om du vill veta mer om hur du tar bort programvaran från datorn permanent
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Hantering av <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Hantera lösenord …</translation>
<translation id="7419106976560586862">Profilsökväg</translation>
<translation id="7437289804838430631">Lägg till kontaktuppgifter</translation>
@@ -1013,22 +1155,24 @@ Mer information.
<translation id="7442725080345379071">Ljusorange</translation>
<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="7449109375006139765">skicka systemloggar till hanteringsservern</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="7460618730930299168">Visningen skiljer sig från den du valde. Vill du fortsätta?</translation>
<translation id="7473891865547856676">Nej tack</translation>
-<translation id="7475525192983021547">rapportera tidsperioder när en användare är aktiv på enheten</translation>
<translation id="7481312909269577407">Framåt</translation>
<translation id="7485870689360869515">Ingen data hittades.</translation>
+<translation id="7498234416455752244">Fortsätt redigera</translation>
<translation id="7508255263130623398">Enhets-id för returnerad princip är tomt eller matchar inte nuvarande enhets-id</translation>
<translation id="7508870219247277067">Avokadogrön</translation>
<translation id="7511955381719512146">Wi-Fi-nätverket du använder kanske kräver att du besöker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Ladda ned</translation>
<translation id="7518003948725431193">Det fanns ingen webbsida på webbadressen: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (kuvert)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Din anslutning till webbplatsen är inte privat</translation>
+<translation id="7535087603100972091">Värde</translation>
<translation id="7537536606612762813">Obligatorisk</translation>
+<translation id="7538364083937897561">A2 (kuvert)</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>
@@ -1037,8 +1181,8 @@ Mer information.
<translation id="7552846755917812628">Testa följande tips:</translation>
<translation id="7554791636758816595">Ny flik</translation>
<translation id="7564049878696755256">Du kan förlora åtkomsten till kontot på <ph name="ORG_NAME" /> eller bli utsatt för identitetsstöld. Du rekommenderas att ändra lösenordet nu.</translation>
-<translation id="7566125604157659769">Texten du kopierade</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="7568105740864181217">Den här webbläsaren hanteras av ett företag, en skola eller någon annan organisation. Administratören kan ändra webbläsarinställningarna på distans. Aktiviteter på den här enheten kan också hanteras utanför Chrome. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Mer information.
<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="7633909222644580952">Prestandainformation och kraschrapporter</translation>
<translation id="7637571805876720304">Vill du ta bort kreditkortet från Chromium?</translation>
<translation id="7639968568612851608">Mörkgrå</translation>
<translation id="765676359832457558">Dölj avancerade inställningar ...</translation>
@@ -1058,9 +1203,11 @@ Mer information.
<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="7676643023259824263">Sök efter texten i Urklipp, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Ändra sökmotor</translation>
<translation id="7682287625158474539">Frakt</translation>
<translation id="7687186412095877299">Fyller i sparade betalningsmetoder i betalningsformulär</translation>
+<translation id="7697066736081121494">Prc8 (kuvert)</translation>
<translation id="769721561045429135">Du har för närvarande kort som bara kan användas på den här enheten. Klicka på Fortsätt om du vill granska korten.</translation>
<translation id="7699293099605015246">Inga artiklar är tillgängliga just nu</translation>
<translation id="7701040980221191251">Inget</translation>
@@ -1072,11 +1219,13 @@ Mer information.
<translation id="774634243536837715">Farligt innehåll har blockerats.</translation>
<translation id="7752995774971033316">Hanteras inte</translation>
<translation id="7755287808199759310">En förälder kan ta bort blockeringen</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Anslutningen kan ha blockerats av en brandvägg eller antivirusprogram.</translation>
<translation id="7759163816903619567">Visningsdomän:</translation>
<translation id="7761701407923456692">Servercertifikatet överensstämmer inte med webbadressen.</translation>
<translation id="7763386264682878361">Textanalysator för manifest för betalning</translation>
<translation id="7764225426217299476">Lägg till adress</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Prefektur</translation>
<translation id="7791543448312431591">Lägg till</translation>
<translation id="7793809570500803535">Webbsidan på <ph name="SITE" /> kan ligga nere för tillfället eller så kan den ha flyttats permanent till en ny webbadress.</translation>
@@ -1088,8 +1237,8 @@ Mer information.
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Vill du ta bort formulärförslaget från Chrome?</translation>
<translation id="7815407501681723534">Hittade <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> för <ph name="SEARCH_STRING" /></translation>
-<translation id="7818867226424560206">Hantera principer</translation>
<translation id="782886543891417279">Wi-Fi-nätverket du använder (<ph name="WIFI_NAME" />) kanske kräver att du besöker dess inloggningssida.</translation>
+<translation id="7836231406687464395">Postfix (kuvert)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Inga}=1{1 app (<ph name="EXAMPLE_APP_1" />)}=2{2 appar (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# appar (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Men du är inte osynlig. Inkognitoläget döljer inte webbhistoriken för din arbetsgivare, internetleverantören eller webbplatserna du besöker.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@ Mer information.
<translation id="7878562273885520351">Lösenordet kan vara utsatt för risk</translation>
<translation id="7882421473871500483">Brun</translation>
<translation id="7887683347370398519">Kontrollera CVC-koden och försök igen</translation>
-<translation id="7893255318348328562">Sessionsnamn</translation>
+<translation id="7904208859782148177">C3 (kuvert)</translation>
<translation id="79338296614623784">Ange ett giltigt telefonnummer</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Upphör att gälla den <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Mer information.
<translation id="7951415247503192394">(32 bitar)</translation>
<translation id="7956713633345437162">Bokmärken i mobilen</translation>
<translation id="7961015016161918242">Aldrig</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Webbläsare</translation>
<translation id="8009225694047762179">Hantera Lösenord</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Det här kortet och dess faktureringsadress sparas. Du kan använda det när du är inloggad som <ph name="USER_EMAIL" />.}other{De här korten och deras faktureringsadresser sparas. Du kan använda dem när du är inloggad som <ph name="USER_EMAIL" />.}}</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="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="8035152190676905274">Penna</translation>
+<translation id="8037117624646282037">Vem har använt enheten nyligen</translation>
<translation id="8037357227543935929">Fråga (standard)</translation>
<translation id="803771048473350947">Arkiv</translation>
<translation id="8041089156583427627">Skicka feedback</translation>
<translation id="8041940743680923270">Använd global standardinställning (Fråga)</translation>
<translation id="8042918947222776840">Välj hämtningsalternativ</translation>
<translation id="8057711352706143257"><ph name="SOFTWARE_NAME" /> har inte konfigurerats korrekt. Ofta hjälper det att avinstallera <ph name="SOFTWARE_NAME" />. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Enheten har konfigurerats att</translation>
+<translation id="8066955247577885446">Något gick tyvärr fel.</translation>
+<translation id="8074253406171541171">10x13 (kuvert)</translation>
<translation id="8078141288243656252">Det går inte att annotera när dokumentet har roterats</translation>
<translation id="8079031581361219619">Vill du läsa in webbplatsen igen?</translation>
<translation id="8088680233425245692">Det gick inte att visa artikeln.</translation>
@@ -1131,11 +1284,12 @@ Mer information.
<translation id="8091372947890762290">Aktiveringen väntar på servern</translation>
<translation id="8092774999298748321">Mörklila</translation>
<translation id="8094917007353911263">Nätverket du använder kanske kräver att du besöker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">De ogiltiga korten har tagits bort</translation>
<translation id="8103161714697287722">Betalningsmetod</translation>
<translation id="8118489163946903409">Betalningsmetod</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> hanteras av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> har inte installerats korrekt på datorn eller nätverket. Be IT-administratören om hjälp med problemet.</translation>
-<translation id="8130693978878176684">Jag kan inte hjälpa till mer. Fortsätt på egen hand.</translation>
<translation id="8131740175452115882">Bekräfta</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>
@@ -1145,8 +1299,11 @@ Mer information.
<translation id="8197543752516192074">Översätt sidan</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="8202370299023114387">Konflikt</translation>
+<translation id="8206978196348664717">Prc4 (kuvert)</translation>
<translation id="8211406090763984747">Anslutningen är säker</translation>
<translation id="8218327578424803826">Tilldelad plats:</translation>
+<translation id="8220146938470311105">C7/C6 (kuvert)</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="8238581221633243064">Öppna sidan på en ny inkognitoflik</translation>
@@ -1158,14 +1315,16 @@ Mer information.
<translation id="825929999321470778">Visa alla sparade lösenord</translation>
<translation id="8261506727792406068">Radera</translation>
<translation id="8267698848189296333">Loggar in som <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Den här webbläsaren hanteras av <ph name="ENROLLMENT_DOMAIN" />. Din administratör kan ändra dina webbläsarinställningar på distans. Aktiviteter på den här enheten kan också hanteras utanför Chrome. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Logga in</translation>
<translation id="8288807391153049143">Visa certifikat</translation>
<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="8298115750975731693">Wi-Fi-nätverket du använder (<ph name="WIFI_NAME" />) kanske kräver att du besöker <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Det gick inte att översätta på grund av ett nätverksfel.</translation>
-<translation id="8311129316111205805">Läs in session</translation>
<translation id="8332188693563227489">Åtkomst nekades till <ph name="HOST_NAME" />.</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Mer information.
<translation id="8416694386774425977">Nätverkskonfigurationen är ogiltig och kunde inte importeras.
Mer information:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Enheten hanteras av <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Ändra</translation>
<translation id="8428213095426709021">Inställningar</translation>
@@ -1211,9 +1369,11 @@ Mer information:
<translation id="860043288473659153">Namn på kortinnehavare</translation>
<translation id="861775596732816396">Storlek 4</translation>
<translation id="8620436878122366504">Dina föräldrar har inte godkänt den ännu</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Spara kortet på enheten</translation>
<translation id="8663226718884576429">Beställningsöversikt, <ph name="TOTAL_LABEL" />, mer information</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, svar, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Din anslutning till <ph name="DOMAIN" /> är inte krypterad.</translation>
<translation id="8718314106902482036">Betalningen slutfördes inte</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, sökförslag</translation>
@@ -1227,6 +1387,7 @@ Mer information:
<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="8763927697961133303">USB-enhet</translation>
<translation id="8768895707659403558"><ph name="SIGN_IN_LINK" /> om du vill använda dina kort på alla enheter.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Gör om Ta bort</translation>
<translation id="8792621596287649091">Du kan förlora åtkomsten till kontot på <ph name="ORG_NAME" /> eller bli utsatt för identitetsstöld. Du rekommenderas att ändra lösenordet nu.</translation>
<translation id="8800988563907321413">Förslag på webbsidor i närheten visas här</translation>
@@ -1237,10 +1398,12 @@ Mer information:
<translation id="885730110891505394">Delar med Google</translation>
<translation id="8858065207712248076">Du rekommenderas att återställa lösenordet för <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> om du har återanvänt det på andra webbplatser.</translation>
<translation id="8866481888320382733">Det uppstod ett fel när policyinställningarna analyserades</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Nyligen stängda</translation>
<translation id="8874824191258364635">Ange ett giltigt kortnummer</translation>
<translation id="8891727572606052622">Ogiltigt proxyläge.</translation>
<translation id="8903921497873541725">Zooma in</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Lägg till namn</translation>
@@ -1248,13 +1411,13 @@ Mer information:
<translation id="894185898663964645">Administratören har konfigurerat anpassade rotcertifikat. Det kan innebära att administratören ser innehållet på de webbplatser du besöker.</translation>
<translation id="8943282376843390568">Limegrön</translation>
<translation id="8957210676456822347">Auktorisering av infångstportal</translation>
+<translation id="8966619695390250636">Menade du?</translation>
<translation id="8968766641738584599">Spara kortet</translation>
<translation id="8971063699422889582">Servercertifikatet har gått ut.</translation>
<translation id="8975012916872825179">Gäller uppgifter som telefonnummer, e-postadresser och leveransadresser</translation>
<translation id="8978053250194585037"><ph name="BEGIN_LINK" />Nätfiske<ph name="END_LINK" /> upptäcktes nyligen av Google Säker webbsökning på <ph name="SITE" />. Webbplatser som används för nätfiske imiterar andra webbplatser i syfte att lura dig.</translation>
<translation id="8983003182662520383">Betalningsmetoder och adresser som används med Google Pay</translation>
<translation id="8987927404178983737">Månad</translation>
-<translation id="8988408250700415532">Något gick fel. Du kan slutföra beställningen på webbplatsen.</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>
@@ -1264,6 +1427,7 @@ Mer information:
<translation id="9011424611726486705">Öppna webbplatsinställningarna</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Ogiltigt)</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>
@@ -1275,11 +1439,11 @@ Mer information:
<translation id="9065745800631924235">Sök efter <ph name="TEXT" /> i historiken</translation>
<translation id="9069693763241529744">Blockerades av ett tillägg</translation>
<translation id="9076283476770535406">Den kan innehålla barnförbjudet innehåll</translation>
+<translation id="9076630408993835509">Den här webbläsaren hanteras inte av ett företag eller en organisation. Aktiviteter på den här enheten kan hanteras utanför Chrome. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Mer information krävs</translation>
<translation id="9080712759204168376">Sammanfattning av beställningen</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>
<translation id="9106062320799175032">Lägg till faktureringsadress</translation>
-<translation id="9110718169272311511">Du hittar Google-assistenten i Chrome nära skärmens nederkant</translation>
<translation id="9114524666733003316">Kortet kontrolleras …</translation>
<translation id="9128870381267983090">Anslut till ett nätverk</translation>
<translation id="9137013805542155359">Visa original</translation>
@@ -1288,6 +1452,7 @@ Mer information:
<translation id="9148507642005240123">&amp;Ångra Redigera</translation>
<translation id="9154194610265714752">Uppdaterat</translation>
<translation id="9157595877708044936">Konfigurerar...</translation>
+<translation id="9158625974267017556">C6 (kuvert)</translation>
<translation id="9168814207360376865">Tillåt att webbplatser kontrollerar om du har sparade betalningsmetoder</translation>
<translation id="9169664750068251925">Blockera alltid den här webbplatsen</translation>
<translation id="9170848237812810038">&amp;Ångra</translation>
@@ -1302,10 +1467,12 @@ Mer information:
<translation id="9219103736887031265">Bilder</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">RENSA FORMULÄRET</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Du kan förlora tillgången till Google-kontot. Du rekommenderas att ändra lösenordet nu. Du blir uppmanad att logga in.</translation>
<translation id="939736085109172342">Ny mapp</translation>
<translation id="945855313015696284">Kontrollera informationen nedan och radera alla ogiltiga kort</translation>
<translation id="951104842009476243">Godkända bankkort och förbetalda kort</translation>
+<translation id="958202389743790697">Blockerad i enlighet med säkerhetsprincipen på <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Bedrägliga appar som inte gör vad de påstås göra eller insamling av data som används för att spåra dig skulle kunna installeras via innehållet. <ph name="BEGIN_LINK" />Visa ändå<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Officiell version</translation>
<translation id="973773823069644502">Lägg till leveransadress</translation>
@@ -1314,6 +1481,7 @@ Mer information:
<translation id="984275831282074731">Betalningsmetoder</translation>
<translation id="985199708454569384">&lt;p&gt;Felet visas om klockan går fel eller fel datum är inställt på datorn eller den mobila enheten.&lt;/p&gt;
&lt;p&gt;Åtgärda felet genom att öppna klockan på enheten. Ställ in rätt tid och datum.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Utvecklarversion</translation>
<translation id="989988560359834682">Redigera adress</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_sw.xtb b/chromium/components/strings/components_strings_sw.xtb
index 8054d11c065..d98c1a94932 100644
--- a/chromium/components/strings/components_strings_sw.xtb
+++ b/chromium/components/strings/components_strings_sw.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sw">
-<translation id="1005145902654145231">Imeshindwa kubadilisha jina la kipindi</translation>
<translation id="1008557486741366299">Sio Sasa</translation>
<translation id="1010200102790553230">Pakia ukurasa baadaye</translation>
<translation id="1015730422737071372">Toa maelezo ya ziada</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">jina lisilojulikana</translation>
<translation id="1050038467049342496">Funga programu nyingine</translation>
<translation id="1055184225775184556">Tendua Kuongeza</translation>
+<translation id="1056898198331236512">Ilani</translation>
<translation id="1058479211578257048">Inahifadhi kadi...</translation>
<translation id="10614374240317010">Haijahifadhiwa kamwe</translation>
+<translation id="1062160989074299343">Prc10 (Bahasha)</translation>
<translation id="106701514854093668">Alamisho za Eneokazi</translation>
<translation id="1074497978438210769">Si salama</translation>
<translation id="1080116354587839789">Fanya itoshe kwenye upana</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Ongeza Jina kwenye Kadi</translation>
<translation id="1089439967362294234">Badilisha Nenosiri</translation>
<translation id="109743633954054152">Dhibiti manenosiri katika mipangilio ya Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Huenda onyo zikawa nyingi wakati tovuti zinasasisha usalama. Hali hii itaboreshwa hivi karibuni.</translation>
<translation id="1126551341858583091">Ukubwa kwenye nafasi ya hifadhi ya ndani ya kifaa ni <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Akiba ya sera ni SAWA</translation>
+<translation id="1131264053432022307">Picha Uliyonakili</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> imefunga muunganisho bila kutarajiwa.</translation>
<translation id="1161325031994447685">Kuunganisha tena kwenye Wi-Fi</translation>
<translation id="1165039591588034296">Hitilafu</translation>
-<translation id="1173894706177603556">Ipe jina jipya</translation>
<translation id="1175364870820465910">&amp;Chapisha...</translation>
<translation id="1181037720776840403">Ondoa</translation>
<translation id="1197088940767939838">Rangi ya machungwa</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Jina la kifaa chako</translation>
<translation id="124116460088058876">Lugha zaidi</translation>
<translation id="1250759482327835220">Ili ulipe kwa haraka wakati ujao, hifadhi anwani ya kutuma bili, jina na maelezo ya kadi yako kwenye Akaunti yako ya Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (zimesawazishwa)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Tofauti za miundo ya amri</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="1314614906530272393">Kipindi ulichochagua hakipo.</translation>
+<translation id="1320233736580025032">Prc1 (Bahasha)</translation>
+<translation id="132301787627749051">Tafuta picha kwenye ubao wa kunakili</translation>
<translation id="1323433172918577554">Onyesha Zaidi</translation>
<translation id="132390688737681464">Hifadhi na Ujaze Anwani</translation>
<translation id="1333989956347591814">Huenda bado shughuli zako <ph name="BEGIN_EMPHASIS" />Zitaonwa<ph name="END_EMPHASIS" /> na:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Anwani ya eneo la kuchukulia</translation>
<translation id="1348198688976932919">Kuna programu hasidi kwenye tovuti unayotaka kuifungua</translation>
<translation id="1348779747280417563">Thibitisha jina</translation>
+<translation id="1357195169723583938">Waliotumia kifaa hivi majuzi na wakati walikitumia</translation>
+<translation id="1364822246244961190">Sera hii imezuiwa, thamani yake haitazingatiwa.</translation>
<translation id="1374468813861204354">mapendekezo</translation>
+<translation id="1374692235857187091">Index-4x6 (Kadi ya Posta)</translation>
<translation id="1375198122581997741">Kuhusu Toleo</translation>
<translation id="1376836354785490390">Onyesha Chache</translation>
<translation id="1377321085342047638">Nambari ya Kadi</translation>
<translation id="138218114945450791">Samawati Isiyokolea</translation>
+<translation id="1382194467192730611">Kifaa cha USB kinachoruhusiwa na msimamizi wako</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> haikutuma data yoyote.</translation>
+<translation id="140316286225361634">Tovuti ya <ph name="ORIGIN" /> imeomba kwamba sera ya usalama
+ itatumika kwenye ombi lake lote na sera hii kwa sasa inabaini kuwa tovuti
+ si salama.</translation>
<translation id="1405567553485452995">Kijani Isiyokolea</translation>
<translation id="1407135791313364759">Fungua zote</translation>
<translation id="1413809658975081374">Hitilafu ya faragha</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Ndio</translation>
<translation id="1430915738399379752">Chapisha</translation>
<translation id="1455413310270022028">Kifutio</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Onyesha zaidi</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Chagua Anwani ya Mahali Bidhaa Zitakapopelekwa</translation>
+<translation id="1492194039220927094">Sera zinaweza kutumwa:</translation>
<translation id="1501859676467574491">Onyesha kadi kutoka Akaunti yako ya Google</translation>
-<translation id="1506687042165942984">Onyesha nakala iliyohifadhiwa (yaani inayojulikana kwisha muda) ya ukurasa huu.</translation>
<translation id="1507202001669085618">&lt;p&gt;Utaona hitilafu hii kama unatumia mtandao wa Wi-Fi ambapo unatakiwa kuingia katika akaunti kabla ya kwenda mtandaoni.&lt;/p&gt;
&lt;p&gt;Ili urekebishe hitilafu, bofya &lt;strong&gt;Unganisha&lt;/strong&gt; kwenye ukurasa unaojaribu kufungua.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Nambari ya simu inahitajika</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Unda Tarehe</translation>
<translation id="1521655867290435174">Majedwali ya Google</translation>
<translation id="1527263332363067270">Inasubiri muunganisho...</translation>
+<translation id="1529521330346880926">10x15 (Bahasha)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Ukurasa huu unasema</translation>
<translation id="153384715582417236">Hakuna maudhui mengine kwa sasa</translation>
<translation id="154408704832528245">Chagua Mahali Bidhaa Itakapopelekwa</translation>
<translation id="1549470594296187301">Lazima JavaScript iwashwe ili utumie kipengele hiki.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Weka tarehe ya mwisho wa matumizi</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Picha uliyonakili</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Zuia ukurasa huu usiunde vidadisi zaidi</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Maliza kipindi</translation>
<translation id="1639239467298939599">Inapakia</translation>
<translation id="1640180200866533862">Sera za mtumiaji</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Cheti cha seva kina kitufe dhaifu cha kifichua msimbo.</translation>
<translation id="1697532407822776718">Mko tayari nyote!</translation>
+<translation id="1703835215927279855">Barua</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Huwezi kuweka vidokezo kwenye hati kwa kuwa ni kubwa mno</translation>
<translation id="1721312023322545264">Unahitaji ruhusa kutoka kwa <ph name="NAME" /> ili utembelee tovuti hii</translation>
<translation id="1721424275792716183">* Unahitaji kujaza sehemu hii</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Kuwasiliana na msimamizi wa mfumo.</translation>
<translation id="1740951997222943430">Andika mwezi sahihi wa kuisha kwa muda wa matumizi</translation>
<translation id="1743520634839655729">Ili ulipe kwa haraka wakati ujao, hifadhi anwani ya kutuma bili, jina na maelezo ya kadi yako kwenye Akaunti yako ya Google na kwenye kifaa hiki.</translation>
+<translation id="1745880797583122200">Kivinjari chako kinadhibitiwa</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>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Tafadhali sasisha kaulisiri yako iliyolandanishwa.</translation>
<translation id="1787142507584202372">Vichupo vyako vilivyo wazi huonekana hapa</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Jina la mwenye kadi</translation>
<translation id="1821930232296380041">Ombi au vigezo vya ombi batili</translation>
+<translation id="1822540298136254167">Tovuti ulizotembelea na muda uliotumia kwenye tovuti hizo</translation>
<translation id="1826516787628120939">Inakagua</translation>
<translation id="1834321415901700177">Tovuti hii ina programu hatari</translation>
<translation id="1839551713262164453">Imeshindwa kuthibitisha thamani za sera kutokana na hitilafu</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Futa data ya historia ya kuvinjari katika Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{na nyingine 1}other{na nyingine #}}</translation>
<translation id="2003709556000175978">Badilisha nenosiri lako sasa</translation>
+<translation id="20053308747750172">Seva ambako unaenda, <ph name="ORIGIN" />, imeomba kwamba
+ sera ya usalama itatumika katika maombi yake yote. Lakini kwa sasa
+ imewasilisha sera isiyo sahihi, inayozuia kivinjari
+ kisitimize ombi lako la <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Proksi imewekwa katika usanidi otomatiki.</translation>
<translation id="2030481566774242610">Je, ulimaanisha <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Kuangalia seva mbadala na kinga mtandao<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Idara</translation>
<translation id="2102134110707549001">Pendekeza Nenosiri Thabiti…</translation>
<translation id="2108755909498034140">Zima na uwashe kompyuta yako</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kadi</translation>
<translation id="2114841414352855701">Imepuuzwa kwa sababu ilifutwa na <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Alamisho kwenye Simu</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Bahasha)</translation>
<translation id="2181821976797666341">Sera</translation>
<translation id="2183608646556468874">Nambari ya Simu</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{Anwani 1}other{Anwani #}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Nambari ya simu</translation>
<translation id="2283340219607151381">Hifadhi na ujaze anwani</translation>
<translation id="2292556288342944218">Ufikiaji wako wa intaneti umezuiwa</translation>
+<translation id="2294558542833290837">Kiungo ulichofungua mwanzoni si cha kawaida</translation>
+<translation id="2297722699537546652">B5 (Bahasha)</translation>
+<translation id="2310021320168182093">Chou2 (Bahasha)</translation>
<translation id="2316887270356262533">Huongeza nafasi isiyozidi MB 1. Baadhi ya tovuti huenda zikapakia polepole zaidi utakapozivinjari tena.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> inahitaji jina la mtumiaji na nenosiri.</translation>
<translation id="2317583587496011522">Kadi za malipo zinakubaliwa.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, muda wa matumizi utakwisha <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Mipangilio inadhibitiwa na msimamizi wako</translation>
+<translation id="2346319942568447007">Picha uliyonakili</translation>
<translation id="2349790679044093737">Kipindi cha VR kinaendelea</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Ripoti ya kuacha kufanya kazi iliyochukuliwa <ph name="CRASH_TIME" /> haikupakiwa</translation>
<translation id="2367567093518048410">Kiwango</translation>
<translation id="2378238891085281592">Unatumia hali ya faragha</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Biashara chaguomsingi</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="2410754574180102685">Government-Legal</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="2418081434543109369">Seva ambako unaenda, <ph name="ORIGIN" />, imeomba kwamba
+ sera ya usalama itatumika katika maombi yake yote. Lakini kwa sasa
+ imeshindwa kuwasilisha sera inayozuia kivinjari kutimiza
+ ombi lako la <ph name="SITE" />.</translation>
<translation id="244665789865330679">Akaunti na kifaa chako kinadhibitiwa na<ph name="ENROLLMENT_DOMAIN" />. Hii inamaanisha kwamba msimamizi wako anaweza kuweka mipangilio ya akaunti na kifaa chako kwa mbali.</translation>
<translation id="2463193859425327265">Badilisha Ukurasa wa Kwanza</translation>
<translation id="2463739503403862330">Jaza</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Chagua Njia ya Kusafirisha</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Inaendesha Zana ya Kuchunguza Mtandao<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Tafsiri ukurasa huu</translation>
<translation id="2479410451996844060">URL batili ya utafutaji.</translation>
<translation id="2482878487686419369">Arifa</translation>
<translation id="248348093745724435">Sera za mashine</translation>
+<translation id="2485387744899240041">Majina ya watumiaji kwenye kivinjari na kifaa chako</translation>
<translation id="2491120439723279231">Cheti cha seva kina hitilafu.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Changanua kadi mpya</translation>
<translation id="2501278716633472235">Rudi nyuma</translation>
<translation id="2503184589641749290">Kadi za malipo na za kulipia awali zinazokubaliwa</translation>
<translation id="2515629240566999685">Kuangalia uthabiti wa mawimbi katika eneo lako</translation>
-<translation id="2516852381693169964">Tafuta Picha kwenye <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Imehifadhiwa kwenye kifaa hiki pekee</translation>
<translation id="2524461107774643265">Ongeza Maelezo Zaidi</translation>
<translation id="2536110899380797252">Ongeza Anwani</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Bahasha)</translation>
<translation id="2625385379895617796">Saa yako iko mbele</translation>
<translation id="2634124572758952069">Haikupata anwani ya IP ya seva ya <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Hali:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Funga vichupo au programu nyingine</translation>
<translation id="267371737713284912">bonyeza <ph name="MODIFIER_KEY_DESCRIPTION" /> ili utendue</translation>
<translation id="2674170444375937751">Je, una hakika kuwa ungependa kufuta kurasa hizi kutoka historia yako?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Ondoka</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Kadi Zinazokubaliwa</translation>
<translation id="2702801445560668637">Orodha ya Kusoma</translation>
<translation id="2704283930420550640">Thamani haioani na umbizo.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Ondoa vipengee vilivyochaguliwa</translation>
<translation id="277133753123645258">Mbinu ya usafirishaji</translation>
<translation id="277499241957683684">Rekodi ya kifaa inayokosekana</translation>
-<translation id="2781030394888168909">Hamisha katika muundo wa MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Muunganisho uliwekwa upya.</translation>
<translation id="2788784517760473862">Kadi za malipo zinazokubaliwa</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Fungua Dirisha Fiche</translation>
+<translation id="2850739647070081192">Invite (Bahasha)</translation>
<translation id="2851634818064021665">Unahitaji ruhusa ili utembelee tovuti hii</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Ungependa kuhifadhi kadi?</translation>
<translation id="2903493209154104877">Anwani</translation>
<translation id="290376772003165898">Je, ukurasa huu haupo katika <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Njia ya Kusafirisha</translation>
<translation id="2928905813689894207">Anwani ya kutuma Bili</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Bahasha)</translation>
<translation id="3024663005179499861">Aina mbaya ya sera</translation>
<translation id="3037605927509011580">Lo!</translation>
<translation id="3041612393474885105">Maelezo ya Cheti</translation>
+<translation id="3060227939791841287">C9 (Bahasha)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Ongeza Anwani ya Mahali pa Kuchukulia Bidhaa</translation>
<translation id="3105172416063519923">Kitambulisho cha Kipengee:</translation>
<translation id="3109728660330352905">Huna idhini ya kuona ukurasa huu.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> kwenye <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Ghairi Malipo</translation>
<translation id="3207960819495026254">Imealamishwa</translation>
-<translation id="3209375525920864198">Tafadhali andika jina sahihi la kipindi.</translation>
+<translation id="321912867715453276">Onyo: Sera hii ina zaidi ya chanzo kimoja, lakini thamani zinafanana.</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="3229041911291329567">Maelezo ya toleo kuhusu kivinjari na kifaa chako</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Ongeza jina kwenye kadi</translation>
<translation id="3287510313208355388">Pakua ukiwa mtandaoni</translation>
<translation id="3293642807462928945">Pata maelezo zaidi kuhusu sera ya <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Hakuna matokeo ya utafutaji yaliyopatikana</translation>
-<translation id="3305707030755673451">Data yako ilisimbwa kwa njia fiche kwa kauli yako ya siri ya kusawazisha mnamo <ph name="TIME" />. Iweke ili uanze kusawazisha.</translation>
<translation id="3320021301628644560">Ongeza anwani ya kutuma bili</translation>
<translation id="3324983252691184275">Nyekundu Iliyoiva</translation>
<translation id="3338095232262050444">Salama</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">Rudia Kuhariri</translation>
<translation id="342781501876943858">Chromium inapendekeza ubadilishe nenosiri lako ikiwa ulilitumia tena kwenye tovuti zingine.</translation>
<translation id="3431636764301398940">Hifadhi kadi hii kwenye kifaa hiki</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Mmiliki wa kifaa hiki amezima mchezo wa dinosau.</translation>
<translation id="3447884698081792621">Onyesha cheti (kilitolewa na <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Muda unaotumika kuleta:</translation>
+<translation id="3456231139987291353">Number-11 (Bahasha)</translation>
<translation id="3461824795358126837">Zana ya Kuangazia</translation>
<translation id="3462200631372590220">Ficha mahiri</translation>
<translation id="3467763166455606212">Jina la mwenye kadi linahitajika</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kadi za mikopo na za kulipia awali zinazokubaliwa.</translation>
<translation id="3582930987043644930">Ongeza jina</translation>
<translation id="3583757800736429874">Rudia Hatua</translation>
+<translation id="35866233670761917">Wasimamizi wako hawaoni maudhui ya tovuti ambazo unatembelea.</translation>
<translation id="3586931643579894722">Ficha maelezo</translation>
+<translation id="3592413004129370115">Italian (Bahasha)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Ukubwa wa 2</translation>
<translation id="3615877443314183785">Andika tarehe sahihi ya kuisha kwa muda wa matumizi</translation>
<translation id="36224234498066874">Futa Data ya Kuvinjari...</translation>
<translation id="362276910939193118">Onyesha Historia Kamili</translation>
-<translation id="3623476034248543066">Onyesha thamani</translation>
<translation id="3630155396527302611">Ikiwa tayari imeorodheshwa kuwa programu inayoruhusiwa kufikia mtandao, jaribu
kuiondoa kwenye orodha kisha uiongeze tena.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Uhalalishaji umefanikiwa</translation>
<translation id="3655670868607891010">Ikiwa unaliona tatizo hili mara kwa mara, jaribu <ph name="HELP_LINK" /> haya.</translation>
<translation id="3658742229777143148">Marekebisho</translation>
<translation id="366077651725703012">Sasisha Kadi ya Mikopo</translation>
<translation id="3676592649209844519">Kitambulisho cha Kifaa:</translation>
+<translation id="3677008721441257057">Unamaanisha &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Ombi halikutiwa sahihi</translation>
<translation id="3678529606614285348">Fungua ukurasa kwenye dirisha fiche jipya (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Ripoti ya kuacha kufanya kazi ilitolewa <ph name="CRASH_TIME" /> na kupakiwa <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Mtandao unaotumia unaweza kukuhitaji kuutembelea ukurasa wake wa kuingia katika akaunti.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Inapakia...</translation>
+<translation id="3709599264800900598">Maandishi Uliyonakili</translation>
<translation id="3712624925041724820">Leseni zimekwisha</translation>
<translation id="3714780639079136834">Kuwasha data ya simu au Wi-Fi</translation>
<translation id="3715597595485130451">Unganisha kwenye Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />Kuangalia seva mbadala, kingamtandao na mipangilio ya DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">Programu zinazoweza kusababisha hitilafu hii ni pamoja na kingavirusi, kinga mtandao, kichujio cha wavuti au programu ya seva mbadala.</translation>
+<translation id="373042150751172459">B4 (Bahasha)</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="3745099705178523657">Baada ya kuthibitisha, maelezo ya kadi kutoka Akaunti yako ya Google yatashirikiwa na tovuti hii.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Muda wa matumizi utakwisha <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Ukubwa wa 16</translation>
+<translation id="3797522431967816232">Prc3 (Bahasha)</translation>
<translation id="3807873520724684969">Imezuia maudhui hatari.</translation>
<translation id="3810973564298564668">Dhibiti</translation>
<translation id="382518646247711829">Ukitumia seva mbadala...</translation>
<translation id="3828924085048779000">Kaulisiri tupu hairuhusiwi.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> imesakinisha viendelezi kwa ajili ya majukumu ya ziada. Viendelezi vina idhini ya kufikia baadhi ya data yako.</translation>
<translation id="385051799172605136">Rudi nyuma</translation>
<translation id="3858027520442213535">Sasisha tarehe na saa</translation>
<translation id="3884278016824448484">Kitambulisho cha kifaa kinachokinzana</translation>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Uliza kwenye tovuti hii kila wakati</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Tayari jina la kipindi hiki lipo.</translation>
<translation id="3987940399970879459">Chini ya MB 1</translation>
+<translation id="4008849406247176967">Onyo: Sera hii ina zaidi ya chanzo kimoja chenye thamani zinazokinzana!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{ukurasa 1 wa wavuti ulio karibu}other{kurasa # za wavuti zilizo karibu}}</translation>
<translation id="4030383055268325496">Tendua kuongeza</translation>
+<translation id="4032320456957708163">Kivinjari chako kinadhibitiwa na <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Kitufe "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Bahasha)</translation>
<translation id="4067947977115446013">Ongeza Anwani Sahihi ya Mahali Bidhaa Itapelekwa</translation>
<translation id="4072486802667267160">Hitilafu imetokea wakati wa kushughulikia agizo lako. Tafadhali jaribu tena.</translation>
<translation id="4075732493274867456">Mteja na seva hazitumii toleo la kawaida la itifaki ya SSL au mipangilio ya kriptografia.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Zambarau</translation>
<translation id="4165986682804962316">Mipangilio ya tovuti</translation>
<translation id="4171400957073367226">Sahihi mbaya ya uthibitishaji</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{Kipengee kingine <ph name="ITEM_COUNT" />}other{Vipengee vingine <ph name="ITEM_COUNT" />}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">Rudia hatua</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />Kuangalia mipangilio ya kinga mtandao na kingavirusi<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Bahasha)</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="4221630205957821124">&lt;h4&gt;Hatua ya 1: Ingia katika akaunti ya tovuti&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Badilisha nenosiri</translation>
<translation id="4280429058323657511">, muda wa kutumika utakwisha <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Kadi hii imehifadhiwa kwenye Akaunti yako ya Google}other{Kadi hizi zimehifadhiwa kwenye Akaunti yako ya Google}}</translation>
+<translation id="42981349822642051">Panua</translation>
+<translation id="4302965934281694568">Chou3 (Bahasha)</translation>
<translation id="4305817255990598646">Badilisha</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Zuia (chaguomsingi)</translation>
+<translation id="4318566738941496689">Jina la kifaa chako na anwani ya mtandao</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="4340982228985273705">Kompyuta hii haitambuliwi kama inayodhibitiwa na biashara. Kwa hivyo, sera inaweza tu kusakinisha viendelezi vinavyopangishwa kwenye Duka la Chrome kwenye Wavuti. URL ya kusasisha Duka la Chrome kwenye Wavuti ni "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Kadi za Mikopo Zinazokubaliwa</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Dhibiti njia za kulipa...</translation>
+<translation id="4367563149485757821">Number-12 (Bahasha)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Simu</translation>
<translation id="4406896451731180161">matokeo ya utafutaji</translation>
-<translation id="4406972042435603828">Wasimamizi wako wamesakinisha viendelezi thabiti.</translation>
<translation id="4408413947728134509">Vidakuzi <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Anwani ya Mahali pa Kuchukulia Bidhaa</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="443121186588148776">Mlango wa nambari ya ufuatiliaji</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> haikukubali cheti chako cha kuingia katika akaunti, au huenda hukutoa cheti.</translation>
<translation id="4434045419905280838">Madirisha ibukizi/kuelekeza kwingine</translation>
+<translation id="4435702339979719576">Kad ya Posta)</translation>
<translation id="443673843213245140">Matumizi ya proksi yamelemazwa lakini usanidi wa proksi wazi umebainishwa.</translation>
<translation id="445100540951337728">Kadi za malipo zinazokubaliwa</translation>
+<translation id="4466881336512663640">Haitahifadhi mabadiliko uliyofanya kwenye fomu. Je, una uhakika unataka kuendelea?</translation>
<translation id="4482953324121162758">Haitatafsiri tovuti hii.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL si sahihi. Lazima iwe URL yenye mfumo wa kawaida, k.m. http://example.com or https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Bahasha)</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="4517607026994743406">Comm-10 (Bahasha)</translation>
<translation id="4522570452068850558">Maelezo</translation>
<translation id="4524805452350978254">Dhibiti kadi</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Mmweko</translation>
<translation id="4558551763791394412">Jaribu kuzima viendelezi vyako.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Usafirishaji</translation>
+<translation id="4579056131138995126">Personal (Bahasha)</translation>
<translation id="4582204425268416675">Ondoa kadi</translation>
<translation id="4587425331216688090">Ungependa kuondoa anwani kutoka kwenye Chrome?</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="4597348597567598915">Ukubwa wa 8</translation>
+<translation id="4600854749408232102">C6/C5 (Bahasha)</translation>
<translation id="4646534391647090355">Nipeleke kwenye sehemu hiyo sasa</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="467809019005607715">Slaidi za Google</translation>
<translation id="4690462567478992370">Acha kutumia cheti kisicho sahihi</translation>
+<translation id="4691835149146451662">Architecture-A (Bahasha)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Muunganisho wako umekatizwa</translation>
<translation id="471880041731876836">Huna ruhusa ya kutembelea tovuti hii</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Kuendesha Zana ya Windows ya Kuchunguza Mtandao<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Pakia sera upya</translation>
<translation id="4728558894243024398">Mfumo wa uendeshaji</translation>
+<translation id="4731967714531604179">Prc2 (Bahasha)</translation>
<translation id="4736825316280949806">Zima na uwashe Chromium</translation>
<translation id="473775607612524610">Sasisha</translation>
<translation id="4738601419177586157">Pendekezo la utafutajI la <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Dhibiti manenosiri…</translation>
<translation id="4744603770635761495">Njia Tekelezi</translation>
+<translation id="4746351372139058112">Ujumbe</translation>
<translation id="4750917950439032686">Maelezo yako (kwa mfano, manenosiri, au nambari za kadi za mikopo) ni ya faragha yanapotumwa kwenye tovuti hii.</translation>
<translation id="4756388243121344051">&amp;Historia</translation>
<translation id="4758311279753947758">Ongeza maelezo ya mawasiliano</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Ukurasa wa wavuti ulio <ph name="URL" /> unaweza kuwa haupatikani kwa muda au unaweza kuwa umehamishwa kabisa hadi anwani mpya ya wavuti.</translation>
<translation id="4771973620359291008">Hitilafu isiyojulikana imetokea.</translation>
<translation id="4785689107224900852">Badili utumie kichupo hiki</translation>
-<translation id="4792143361752574037">Hitilafu imetokea wakati wa kufikia faili za kipindi. Kuhifadhia kwenye diski kwa sasa kumezimwa. Tafadhali pakia ukurasa upya na ujaribu tena.</translation>
<translation id="4798078619018708837">Ili usasishe maelezo ya kadi yako, weka tarehe ya mwisho wa matumizi na CVC ya <ph name="CREDIT_CARD" />. Baada ya kuthibitisha, maelezo ya kadi kutoka Akaunti yako ya Google yatashirikiwa na tovuti hii.</translation>
<translation id="4800132727771399293">Angalia tarehe yako ya kuisha muda na CVC na ujaribu tena</translation>
+<translation id="480334179571489655">Hitilafu ya Sera Asili</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Fungua</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Hakuna matokeo yoyote yaliyopatikana</translation>
<translation id="4950898438188848926">Kitufe cha kubadilisha kichupo, bonyeza Enter ili uende kwenye kichupo cha kufungua, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Vitendo</translation>
-<translation id="495832697253704892">Kuripoti viendelezi</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Panua orodha</translation>
<translation id="4974590756084640048">Onyesha maonyo tena</translation>
+<translation id="4984339528288761049">Prc5 (Bahasha)</translation>
<translation id="4989163558385430922">Angalia vyote</translation>
<translation id="4989809363548539747">Programu jalizi hii haitumiki</translation>
-<translation id="4996230189582812866">Kuripoti</translation>
<translation id="5002932099480077015">Ikiwashwa, Chrome itahifadhi nakala ya kadi yako kwenye kifaa hiki kwa ajili ya kujaza fomu haraka zaidi.</translation>
-<translation id="5014174725590676422">Inaonyesha skrini ya haraka ya programu ya Mratibu wa Google katika Chrome</translation>
<translation id="5015510746216210676">Jina la Mashine:</translation>
+<translation id="5017554619425969104">Maandishi uliyonakili</translation>
<translation id="5018422839182700155">Ukurasa huu haufunguki</translation>
<translation id="5019198164206649151">Hifadhi la kucheleza liko katika hali mbaya</translation>
<translation id="5023310440958281426">Angalia sera za msimamizi wako</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Maudhui ya Ndani <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Ruhusu</translation>
<translation id="5040262127954254034">Faragha</translation>
+<translation id="5043480802608081735">Kiungo Ulichonakili</translation>
<translation id="5045550434625856497">Nenosiri lisilo sahihi</translation>
<translation id="5056549851600133418">Makala kwa ajili yako</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kuangalia anwani mbadala<ph name="END_LINK" /></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="5097099694988056070">Takwimu za kifaa kama vile matumizi ya CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Kifaa chako kinadhibitiwa na <ph name="ENROLLMENT_DOMAIN" /> na akaunti yako inadhibitiwa na <ph name="ACCOUNT_DOMAIN" />. Hii inamaanisha kwamba wasimamizi wako wanaweza kuweka mipangilio kwenye kifaa na akaunti yako kwa mbali.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(biti 64)</translation>
-<translation id="5128122789703661928">Huruhusiwi kufuta kipindi kilicho na jina hili.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Dhibiti anwani...</translation>
+<translation id="5138227688689900538">Onyesha chache</translation>
<translation id="5141240743006678641">Simba kwa njia fiche manenosiri yaliyosawazishwa ukitumia stakabadhi zako za Google</translation>
<translation id="5145883236150621069">Msimbo wa hitilafu uko katika jibu la sera</translation>
+<translation id="515292512908731282">C4 (Bahasha)</translation>
<translation id="5159010409087891077">Fungua ukurasa kwenye dirisha fiche jipya (⇧⌘N)</translation>
<translation id="516920405563544094">Weka CVC ya <ph name="CREDIT_CARD" />. Baada ya kuthibitisha, maelezo ya kadi kutoka Akaunti yako ya Google yatashirikiwa na tovuti hii.</translation>
<translation id="5169827969064885044">Unaweza kupoteza uwezo wa kufikia akaunti ya shirika lako au kuibiwa utambulisho. Chrome inapendekeza ubadilishe nenosiri lako sasa.</translation>
<translation id="5171045022955879922">Tafuta au charaza URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Mashine</translation>
<translation id="5179510805599951267">Haiko katika <ph name="ORIGINAL_LANGUAGE" />? Ripoti hitilafu hii</translation>
<translation id="5190835502935405962">Sehemu ya Alamisho</translation>
-<translation id="5200263511887412697">ripoti orodha ya watumiaji wa kifaa walioingia katika akaunti hivi majuzi</translation>
+<translation id="519422657042045905">Vidokezi havipatikani</translation>
<translation id="5201306358585911203">Ukurasa uliopachikwa kwenye ukurasa huu unasema</translation>
<translation id="5205222826937269299">Jina linahitajika</translation>
<translation id="5215116848420601511">Njia za kulipa na anwani zinazotumia Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Anwani ya barua pepe inahitajika</translation>
<translation id="5230733896359313003">Anwani ya Mahali Bidhaa Zitakapopelekwa</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Unganisha kwenye mtandao"</translation>
<translation id="5251803541071282808">Wingu</translation>
+<translation id="5252000469029418751">C7 (Bahasha)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Anwani za mtandao</translation>
<translation id="5285570108065881030">Onyesha manenosiri yote yaliyohifadhiwa</translation>
<translation id="5287240709317226393">Onyesha vidakuzi</translation>
<translation id="5288108484102287882">Imethibitisha thamani za sera na kutoa maonyo</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> kati ya <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Chagua Maelezo ya Mawasiliano</translation>
<translation id="5327248766486351172">Jina</translation>
+<translation id="5329858041417644019">Kivinjari chako hakidhibitiwi</translation>
<translation id="5332219387342487447">Mbinu ya Usafirishaji</translation>
+<translation id="5334013548165032829">Kumbukumbu za mfumo za kina</translation>
<translation id="5344579389779391559">Ukurasa huu huenda ukajaribu kukutoza pesa</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Saa yako iko nyuma" au "Saa yako iko mbele" au "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Ingia katika akaunti na uwashe kipengele cha kusawazisha ili utumie kadi zako kwenye vifaa vyako vyote.</translation>
<translation id="5386426401304769735">Msururu wa cheti wa tovuti hii una cheti kilichotiwa sahihi kwa kutumia SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Haiwezi kutumika</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<ph name="CONTACT_PREVIEW" /> na mwingine <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}other{<ph name="CONTACT_PREVIEW" /> na wengine <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" />}}</translation>
<translation id="5470861586879999274">Rudia kuhariri</translation>
+<translation id="5478437291406423475">B6/C4 (Bahasha)</translation>
<translation id="5481076368049295676">Huenda maudhui haya yakajaribu kusakinisha programu hatari inayoiba au kufuta maelezo yaliyo kwenye kifaa chako. <ph name="BEGIN_LINK" />Onyesha tu<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Ongeza anwani sahihi ya barua pepe</translation>
<translation id="5490432419156082418">Anwani na Zaidi</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Jaribu kuwasiliana na msimamizi wa mfumo wako.</translation>
<translation id="549333378215107354">Ukubwa wa 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Alamisho zinazosimamiwa</translation>
<translation id="5510766032865166053">Huenda imehamishwa au imefutwa.</translation>
<translation id="5523118979700054094">Jina la sera</translation>
<translation id="552553974213252141">Je, maandishi yalitolewa kwa njia sahihi?</translation>
+<translation id="553484882784876924">Prc6 (Bahasha)</translation>
<translation id="5540224163453853">Haikuweza kupata makala yaliyoitishwa.</translation>
<translation id="5541546772353173584">Ongeza Anwani ya Barua Pepe</translation>
<translation id="5545756402275714221">Makala Tunayokupendekezea</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Badilisha anwani</translation>
<translation id="5598944008576757369">Chagua Njia ya Kulipa</translation>
<translation id="560412284261940334">Usimamizi hautumiki</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> imekuelekeza upya mara nyingi mno.</translation>
<translation id="5629630648637658800">Imeshindwa kupakia mipangilio ya sera</translation>
<translation id="5631439013527180824">Ishara ya usimamizi wa kifaa batili</translation>
+<translation id="5632627355679805402">Data yako imesimbwa kwa kutumia <ph name="BEGIN_LINK" />Nenosiri la Google<ph name="END_LINK" /> kufikia <ph name="TIME" />. Liweke ili uanze kusawazisha.</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="563324245173044180">Maudhui ya udanganyifu yamezuiwa.</translation>
<translation id="5659593005791499971">Barua pepe</translation>
+<translation id="5663614846592581799">9x11 (Bahasha)</translation>
+<translation id="5663955426505430495">Msimamizi wa kifaa hiki amesakinisha viendelezi kwa ajili ya majukumu ya ziada. Viendelezi vina idhini ya kufikia baadhi ya data yako.</translation>
<translation id="5675650730144413517">Ukurasa huu haufanyi kazi</translation>
+<translation id="5684874026226664614">Lo! Ukurasa huu haukuweza kutafsiriwa.</translation>
<translation id="5685654322157854305">Ongeza mahali zitakapopelekwa</translation>
<translation id="5689199277474810259">Tuma katika mfumo wa JSON</translation>
<translation id="5689516760719285838">Mahali</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Utambulisho wa tovuti hii haujathibitishwa.</translation>
<translation id="5719499550583120431">Kadi za kulipia awali zinakubaliwa.</translation>
<translation id="5720705177508910913">Mtumiaji wa sasa</translation>
+<translation id="5728056243719941842">C5 (Bahasha)</translation>
<translation id="5730040223043577876">Chrome inapendekeza ubadilishe nenosiri lako ikiwa ulilitumia tena kwenye tovuti zingine.</translation>
<translation id="5732392974455271431">Wazazi wako wanaweza kukuondolea kizuizi</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Hifadhi kadi katika Akaunti yako ya Google}other{Hifadhi kadi katika Akaunti yako ya Google}}</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="5770114862687765385">Inaonekana faili imeharibika. Bofya kitufe cha 'Pakia upya' ili uanzishe upya kipindi.</translation>
<translation id="5778550464785688721">Udhibiti kamili wa vifaa vya MIDI</translation>
<translation id="578305955206182703">Rangi ya chungwa</translation>
<translation id="57838592816432529">Zima sauti</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>
+<translation id="5798290721819630480">Ungependa kufuta mabadiliko uliyoyafanya?</translation>
<translation id="5798683403665926540">Badilisha ukurasa wa kwanza katika mipangilio ya Chrome</translation>
<translation id="5803412860119678065">Ungependa kujaza maelezo ya <ph name="CARD_DETAIL" /> yako?</translation>
<translation id="5804241973901381774">Idhini</translation>
<translation id="5810442152076338065">Muunganisho wako kwenye <ph name="DOMAIN" /> umesimbwa kwa njia fiche kwa kutumia mipangilio ya kriptografia ya zamani.</translation>
<translation id="5813119285467412249">Rudia Kuongeza</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="5860033963881614850">Kimezimwa</translation>
<translation id="5863847714970149516">Huenda ukurasa unaofuata ukajaribu kukutoza pesa</translation>
<translation id="5866257070973731571">Ongeza Nambari ya Simu</translation>
<translation id="5869405914158311789">Imeshindwa kufungua tovuti hii</translation>
<translation id="5869522115854928033">Manenosiri yaliyohifadhiwa</translation>
<translation id="5887400589839399685">Kadi imehifadhiwa</translation>
-<translation id="5893718151540690985">ripoti orodha ya violesura vya mitandao pamoja na aina na anwani za maunzi husika.</translation>
<translation id="5893752035575986141">Kadi za mikopo zinakubaliwa.</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="5916664084637901428">Imewashwa</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Ungependa kuhifadhi kadi kwenye Akaunti ya Google?</translation>
<translation id="5922853866070715753">Unakaribia kumaliza</translation>
<translation id="5932224571077948991">Tovuti inaonyesha matangazo yanayopotosha au yanayokatiza huduma</translation>
-<translation id="5939518447894949180">Weka upya</translation>
<translation id="5946937721014915347">Inafungua <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Huwezi kujiandikisha ukitumia akaunti ya mteja (ina leseni ya kifurushi).</translation>
<translation id="5967592137238574583">Badilisha Maelezo ya Mawasiliano</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Fifiza</translation>
<translation id="5977489021191000276">Kifaa chako hakidhibiwi na msimamizi.</translation>
<translation id="5977976211062815271">Kwenye kifaa hiki</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Imeshindwa kufungua programu ya kulipa</translation>
<translation id="5989320800837274978">Siyo seva proksi za kudumu wala URL ya hati ya .pac zimebainishwa.</translation>
<translation id="5990559369517809815">Maombi katika seva yamezuiwa kwa kiendelezi.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">ripoti takwimu za maunzi kama vile matumizi ya CPU au RAM</translation>
<translation id="6034000775414344507">Kijivu Isiyokolea</translation>
+<translation id="6034283069659657473">10x14 (Bahasha)</translation>
<translation id="6039846035001940113">Ikiwa tatizo litaendelea, wasiliana na mmiliki wa tovuti.</translation>
<translation id="6040143037577758943">Funga</translation>
<translation id="6044573915096792553">Ukubwa wa 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Ungependa kutumia kadi zako kwenye vifaa vyako vyote?</translation>
<translation id="6059925163896151826">Vifaa vya USB</translation>
-<translation id="6071091556643036997">Aina ya sera si sahihi.</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="6094273045989040137">Weka vidokezo</translation>
<translation id="610911394827799129">Huenda Akaunti yako ya Google ina aina nyingine za historia ya kuvinjari katika <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="6132597952260690497">Maelezo kuhusu viendelezi na programu jalizi zilizosakinishwa</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Huongeza nafasi isiyozidi <ph name="SIZE" />. Baadhi ya tovuti huenda zikapakia polepole zaidi utakapozivinjari tena.</translation>
<translation id="6337534724793800597">Chuja sera kwa jina</translation>
<translation id="6358450015545214790">Je, hii inamaanisha nini?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Huenda ukatozwa gharama.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{Pendekezo jingine 1}other{Mapendekezo mengine #}}</translation>
<translation id="6387754724289022810">Ili ulipe kwa haraka wakati ujao, hifadhi anwani ya kutuma bili na maelezo ya kadi yako kwenye Akaunti yako ya Google na kwenye kifaa hiki.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Badilisha alamisho</translation>
+<translation id="6406765186087300643">C0 (Bahasha)</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="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="6434309073475700221">Tupa</translation>
+<translation id="6446163441502663861">Kahu (Bahasha)</translation>
<translation id="6446608382365791566">Ongeza maelezo zaidi</translation>
<translation id="6447842834002726250">Vidakuzi</translation>
<translation id="6451458296329894277">Thibitisha kuwa Fomu Iwasilishwe Tena</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Zima na uwashe Chrome</translation>
<translation id="6529602333819889595">Rudia Kufuta</translation>
<translation id="6534179046333460208">Mapendekezo ya Wavuti kila Mahali</translation>
+<translation id="6556866813142980365">Rudia</translation>
<translation id="6563469144985748109">Msimamizi wako bado hajaiidhinisha</translation>
<translation id="6569060085658103619">Unaangalia ukurasa wa kiendelezi</translation>
+<translation id="6578796323535178455">C2 (Bahasha)</translation>
<translation id="6579990219486187401">Waridi Isiyokolea</translation>
+<translation id="6583674473685352014">B6 (Bahasha)</translation>
+<translation id="6587923378399804057">Kiungo ulichonakili</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> yako haidhibitiwi</translation>
<translation id="6596325263575161958">Chaguo za usimbaji fiche</translation>
<translation id="6604181099783169992">Vitambuzi vya Mwendo au Mwangaza</translation>
+<translation id="6609880536175561541">Prc7 (Bahasha)</translation>
<translation id="6624427990725312378">Maelezo ya Mawasiliano</translation>
<translation id="6626291197371920147">Ongeza nambari sahihi ya kadi</translation>
<translation id="6628463337424475685">Utafutaji wa <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Sera hii imepingwa.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Hamna}=1{Kutoka tovuti 1 (hutaondolewa kwenye Akaunti ya Google)}other{Kutoka tovuti # (hutaondolewa kwenye Akaunti ya Google)}}</translation>
<translation id="6657585470893396449">Nenosiri</translation>
+<translation id="6670613747977017428">Rudi kwenye ukurasa salama.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Tokeni ya Kujiandikisha:</translation>
<translation id="6711464428925977395">Kuna hitilafu katika seva mbadala, au anwani siyo sahihi.</translation>
<translation id="6723740634201835758">Katika Akaunti yako ya Google</translation>
+<translation id="6738516213925468394">Data yako ilisimbwa kwa kutumia <ph name="BEGIN_LINK" />kauli ya siri ya usawazishaji<ph name="END_LINK" /> mnamo <ph name="TIME" />. Iweke ili uanze kusawazisha.</translation>
<translation id="674375294223700098">Hitilafu isiyojulikana ya cheti cha seva.</translation>
<translation id="6744009308914054259">Wakati unasubiri muunganisho, unaweza kutembelea Vipakuliwa ili usome makala yaliyo nje ya mtandao.</translation>
<translation id="6753269504797312559">Thamani ya sera</translation>
<translation id="6757797048963528358">Kifaa chako kiko katika hali tuli.</translation>
+<translation id="6768213884286397650">Hagaki (Kadi ya Posta)</translation>
<translation id="6778737459546443941">Mzazi wako bado hajaiidhinisha</translation>
<translation id="67862343314499040">Zambarau iliyokolea</translation>
+<translation id="6786747875388722282">Viendelezi</translation>
<translation id="679355240208270552">Imepuuzwa kwa sababu utafutaji chaguomsingi umezimwa na sera.</translation>
<translation id="681021252041861472">Sehemu Hii Sharti Ijazwe</translation>
<translation id="6810899417690483278">Kitambulisho cha kubadilisha ili kukufaa</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Kifaa</translation>
<translation id="6970216967273061347">Wilaya</translation>
<translation id="6973656660372572881">Seva zote za proksi thabiti na URL ya hati ya .pac zimebainishwa.</translation>
+<translation id="6973932557599545801">Samahani, nimeshindwa kukusaidia, tafadhali endelea mwenyewe.</translation>
<translation id="6979158407327259162">Hifadhi ya Google</translation>
<translation id="6979440798594660689">Zima (chaguomsingi)</translation>
<translation id="6984479912851154518">Unafunga hali ya faragha ili ulipe kupitia programu ya nje. Ungependa kuendelea?</translation>
<translation id="6989763994942163495">Onyesha mipangilio ya kina...</translation>
+<translation id="6993898126790112050">6x9 (Bahasha)</translation>
<translation id="6996312675313362352">Tafsiri <ph name="ORIGINAL_LANGUAGE" /> kila wakati</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Gharama hizi zinaweza kuwa za mara moja au za kujirudia na huenda zisiwe za moja kwa moja.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ficha</translation>
<translation id="7108819624672055576">Imeruhusiwa na kiendelezi</translation>
<translation id="7111012039238467737">(Sahihi)</translation>
+<translation id="7118618213916969306">Tafuta URL ya ubao wa kunakili, <ph name="SHORT_URL" /></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="7135130955892390533">Onyesha hali</translation>
<translation id="7138472120740807366">Njia ya kusafirisha</translation>
<translation id="7139724024395191329">Emirate</translation>
+<translation id="7152423860607593928">Number-14 (Bahasha)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Urujuani</translation>
-<translation id="7158980942472052083">URL si sahihi. Lazima iwe URL yenye mfumo wa kawaida.</translation>
<translation id="717330890047184534">Kitambulisho cha Gaia</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Seva ambako unaenda, <ph name="ORIGIN" />, imeomba kwamba
+ sera ya usalama itatumika katika maombi yake yote. Lakini badala ya
+ kuwasilisha sera, imeelekeza kivinjari kwingine; hali
+ inayozuia kivinjari kisitekeleze ombi lako la <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Hifadhi na Ujaze Njia za Kulipa</translation>
<translation id="7180611975245234373">Onyesha upya</translation>
<translation id="7182878459783632708">Hakuna sera zilizowekwa</translation>
<translation id="7186367841673660872">Ukurasa huu umetafsiriwa kutoka<ph name="ORIGINAL_LANGUAGE" />hadi<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Huongeza nafasi ya <ph name="SIZE" />. Huenda baadhi ya tovuti zikapakia polepole katika tembeleo lako lijalo.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Msimamizi wako anaweza kuona:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> haizingatii viwango vya usalama.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /> kuhusu tatizo hili.</translation>
<translation id="7219179957768738017">Muunganisho unatumia <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Malipo yanashughulikiwa</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Tovuti unayoelekea kufungua ina programu hasidi</translation>
+<translation id="724766306220616965">Maonyo, Mgogoro</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="7251437084390964440">Mipangilio ya mtandao haitii kiwango cha ONC. Huenda baadhi ya mipangilio haitapakiwa. Maelezo ya ziada: <ph name="DEBUG_INFO" /></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>
@@ -980,11 +1118,14 @@
<translation id="7300012071106347854">Nili Iliyoiva</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Ripoti ya kuacha kufanya kazi iliyochukuliwa <ph name="CRASH_TIME" /> (kipakiwa kilichoombwa na mtumiaji bado hakijapakiwa)</translation>
+<translation id="7313965965371928911">Maonyo ya <ph name="BEGIN_LINK" />Kuvinjari Salama<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Usaidizi kuhusu Muunganisho</translation>
<translation id="7334320624316649418">Rudia Kupanga Upya</translation>
<translation id="733923710415886693">Cheti cha seva hakikufichuliwa kupitia Uwazi wa Cheti.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Mbinu ya Amri</translation>
-<translation id="7365061714576910172">Hamisha katika muundo wa Linux</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>
@@ -992,6 +1133,7 @@
<translation id="7381288752349550461">Kipindi kinachodhibitiwa kimebatilishwa</translation>
<translation id="7390545607259442187">Thibitisha Kadi</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">Kifaa chako cha <ph name="DEVICE_NAME" /> kinadhibitiwa</translation>
<translation id="7407424307057130981">&lt;p&gt;Utaona ujumbe huu wa hitilafu ikiwa una programu ya Superfish kwenye kompyuta yako ya Windows.&lt;/p&gt;
&lt;p&gt;Fuata hatua hizi ili uzime progamu kwa muda na uweze kufikia wavuti. Utahitaji haki za msimamizi.&lt;/p&gt;
&lt;ol&gt;
@@ -1002,7 +1144,7 @@
&lt;li&gt;Bofya &lt;strong&gt;Tumia&lt;/strong&gt;, kisha ubofye &lt;strong&gt;SAWA&lt;/strong&gt;
&lt;li&gt;Tembelea &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Kituo cha usaidizi wa Chrome&lt;/a&gt; ili upate maelezo zaidi kuhusu jinsi ya kuondoa kabisa programu kwenye kompyuta yako
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Usimamizi wa <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Dhibiti Manenosiri…</translation>
<translation id="7419106976560586862">Kijia cha Maelezo mafupi</translation>
<translation id="7437289804838430631">Ongeza Maelezo ya Mawasiliano</translation>
@@ -1011,22 +1153,24 @@
<translation id="7442725080345379071">Chungwa Isiyokolea</translation>
<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="7449109375006139765">tuma kumbukumbu za mfumo kwenye seva ya kudhibiti</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /> kuhusu hitilafu hii.</translation>
<translation id="7455133967321480974">Tumia chaguomsingi la duniani (Zuia)</translation>
<translation id="7460618730930299168">Onyesho kwenye skrini ni tofauti na ile uliyochagua. Ungependa kuendelea?</translation>
<translation id="7473891865547856676">La Asante</translation>
-<translation id="7475525192983021547">ripoti vipindi ambavyo mtumiaji anatumia kifaa</translation>
<translation id="7481312909269577407">Mbele</translation>
<translation id="7485870689360869515">Hakuna data iliyopatikana.</translation>
+<translation id="7498234416455752244">Endelea kubadilisha</translation>
<translation id="7508255263130623398">Kitambulisho cha sera ya kifaa kilichorejeshwa hakina kitu au hakilingani na kitambulisho cha kifaa kilichopo</translation>
<translation id="7508870219247277067">Kijani cha Parachichi</translation>
<translation id="7511955381719512146">Wi-Fi unayotumia inaweza kukuhitaji kutembelea <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Bahasha)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Muunganisho wako kwenye tovuti hii si wa faragha</translation>
+<translation id="7535087603100972091">Thamani</translation>
<translation id="7537536606612762813">Lazima</translation>
+<translation id="7538364083937897561">A2 (Bahasha)</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>
@@ -1035,8 +1179,8 @@
<translation id="7552846755917812628">Jaribu vidokezo vinavyofuata:</translation>
<translation id="7554791636758816595">Kichupo Kipya</translation>
<translation id="7564049878696755256">Unaweza kupoteza uwezo wa kufikia Akaunti yako ya <ph name="ORG_NAME" /> au kuibiwa utambulisho. Chrome inapendekeza ubadilishe nenosiri lako sasa.</translation>
-<translation id="7566125604157659769">Maandishi uliyonakili</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="7568105740864181217">Kivinjari hiki kinadhibitiwa na kampuni, shule au shirika lingine. Msimamizi wako anaweza kubadilisha mipangilio ya kuweka kivinjari kwa mbali. Shughuli kwenye kifaa hiki huenda zikadhibitiwa nje ya Chrome. <ph name="BEGIN_LINK" />Pata Maelezo Zaidi<ph name="END_LINK" /></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>
@@ -1047,6 +1191,7 @@
<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="7633909222644580952">Ripoti za utendaji na programu kuacha kufanya kazi</translation>
<translation id="7637571805876720304">Je, ungependa kuondoa kadi ya mikopo kwenye Chromium?</translation>
<translation id="7639968568612851608">Kijivu Iliyokolea</translation>
<translation id="765676359832457558">Ficha mipangilio ya kina...</translation>
@@ -1056,9 +1201,11 @@
<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="7676643023259824263">Tafuta maandishi ya ubao wa kunakili, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Badilisha Mtambo wa Kutafuta</translation>
<translation id="7682287625158474539">Anwani ya Kufikishia</translation>
<translation id="7687186412095877299">Hujaza fomu za malipo kwa kutumia njia za kulipa ulizohifadhi</translation>
+<translation id="7697066736081121494">Prc8 (Bahasha)</translation>
<translation id="769721561045429135">Sasa hivi, kadi zako zinaweza kutumika kwenye kifaa hiki pekee. Bofya ili uendelee kukagua kadi.</translation>
<translation id="7699293099605015246">Makala hayapatikani kwa sasa</translation>
<translation id="7701040980221191251">Hamna</translation>
@@ -1070,11 +1217,13 @@
<translation id="774634243536837715">Maudhui hatari yamezuiwa.</translation>
<translation id="7752995774971033316">Haidhibitiwi</translation>
<translation id="7755287808199759310">Mzazi wako anaweza kukuondolea kizuizi</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Huenda muunganisho huu umezuiwa na kinga mtandao au kingavirusi.</translation>
<translation id="7759163816903619567">Onyesha kikoa:</translation>
<translation id="7761701407923456692">Cheti cha seva hakilingani na URL.</translation>
<translation id="7763386264682878361">Kichanganuzi cha Faili za Maelezo ya Malipo</translation>
<translation id="7764225426217299476">Ongeza anwani</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Mkoa</translation>
<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>
@@ -1086,8 +1235,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Ungependa kuondoa pendekezo la fomu kutoka kwenye Chrome?</translation>
<translation id="7815407501681723534">Imepata matokeo <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> ya '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Usimamiaji wa sera</translation>
<translation id="782886543891417279">Wi-Fi unayotumia (<ph name="WIFI_NAME" />) inaweza kukuhitaji kutembelea ukurasa wake wa kuingia katika akaunti.</translation>
+<translation id="7836231406687464395">Postfix (Bahasha)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Hamna}=1{Programu 1 (<ph name="EXAMPLE_APP_1" />)}=2{Programu 2 (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{Programu # (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Hata hivyo, huonekani. Kuvinjari katika hali fiche hakufichi kuvinjari kwako kusionekane na mwajiri, mtoaji huduma wako wa intaneti, au tovuti unazotembelea.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1096,7 +1245,7 @@
<translation id="7878562273885520351">Huenda nenosiri lako limetambulika</translation>
<translation id="7882421473871500483">Kahawia</translation>
<translation id="7887683347370398519">Angalia CVC yako na ujaribu tena</translation>
-<translation id="7893255318348328562">Jina la kipindi</translation>
+<translation id="7904208859782148177">C3 (Bahasha)</translation>
<translation id="79338296614623784">Andika nambari sahihi ya simu</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Muda wa matumizi utakwisha <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1106,21 +1255,25 @@
<translation id="7951415247503192394">(biti 32)</translation>
<translation id="7956713633345437162">Alamisho kwenye simu</translation>
<translation id="7961015016161918242">Katu</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Hakijabainishwa</translation>
<translation id="800218591365569300">Jaribu kufunga vichupo au programu nyingine upate nafasi zaidi.</translation>
+<translation id="8004582292198964060">Kivinjari</translation>
<translation id="8009225694047762179">Dhibiti Manenosiri</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Tutahifadhi maelezo ya kadi hii pamoja na anwani yake ya kutuma bili. Utaweza kuitumia utakapoingia katika akaunti ya <ph name="USER_EMAIL" />.}other{Tutahifadhi maelezo ya kadi hizi pamoja na anwani za kutuma bili. Utaweza kuzitumia utakapoingia katika akaunti ya <ph name="USER_EMAIL" />.}}</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="8034522405403831421">Ukurasa huu ni wa lugha ya <ph name="SOURCE_LANGUAGE" />. Je, ungependa kuutasfiri kuwa <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Kalamu</translation>
+<translation id="8037117624646282037">Waliotumia kifaa hivi majuzi</translation>
<translation id="8037357227543935929">Uliza (chaguomsingi)</translation>
<translation id="803771048473350947">Faili</translation>
<translation id="8041089156583427627">Tuma Maoni</translation>
<translation id="8041940743680923270">Tumia chaguomsingi la duniani (Uliza)</translation>
<translation id="8042918947222776840">Chagua Mbinu ya Kuchukua Bidhaa</translation>
<translation id="8057711352706143257">Haikuweka mipangilio ya "<ph name="SOFTWARE_NAME" />" kwa njia sahihi. Kwa kawaida, kuondoa "<ph name="SOFTWARE_NAME" />" hurekebisha tatizo hili. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Kifaa chako kimewekewa mipangilio ya:</translation>
+<translation id="8066955247577885446">Samahani, hitilafu fulani imetokea.</translation>
+<translation id="8074253406171541171">10x13 (Bahasha)</translation>
<translation id="8078141288243656252">Huwezi kuweka vidokezo ikiwa imezungushwa</translation>
<translation id="8079031581361219619">Ungependa kupakia upya tovuti?</translation>
<translation id="8088680233425245692">Haikufaulu kuangalia makala.</translation>
@@ -1129,11 +1282,12 @@
<translation id="8091372947890762290">Uwashaji unasubiri kwenye seva</translation>
<translation id="8092774999298748321">Zambarau Iliyokolea</translation>
<translation id="8094917007353911263">Mtandao unaotumia unaweza kukuhitaji kutembelea <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Tumeondoa kadi zisizo sahihi</translation>
<translation id="8103161714697287722">Njia ya Kulipa</translation>
<translation id="8118489163946903409">Njia ya kulipa</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> inadhibitiwa na <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">Haikusakinisha "<ph name="SOFTWARE_NAME" />" kwa njia sahihi kwenye mtandao au kompyuta yako. Mweleze msimamizi wako wa TEHAMA asuluhishe tatizo hili.</translation>
-<translation id="8130693978878176684">Nimeshindwa kukusaidia, tafadhali endelea mwenyewe.</translation>
<translation id="8131740175452115882">Thibitisha</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>
@@ -1143,8 +1297,11 @@
<translation id="8197543752516192074">Tafsiri Ukurasa</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="8202370299023114387">Mgogoro</translation>
+<translation id="8206978196348664717">Prc4 (Bahasha)</translation>
<translation id="8211406090763984747">Muunganisho ni salama</translation>
<translation id="8218327578424803826">Mahali Palipohawilishwa:</translation>
+<translation id="8220146938470311105">C7/C6 (Bahasha)</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="8238581221633243064">Fungua ukurasa kwenye kichupo fiche kipya</translation>
@@ -1156,14 +1313,16 @@
<translation id="825929999321470778">Onyesha Manenosiri Yote Yaliyohifadhiwa</translation>
<translation id="8261506727792406068">Futa</translation>
<translation id="8267698848189296333">Ingia katika akaunti ukitumia <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Kivinjari hiki kinadhibitiwa na <ph name="ENROLLMENT_DOMAIN" />. Msimamizi wako anaweza kubadilisha mipangilio ya kuweka kivinjari chako kwa mbali. Shughuli kwenye kifaa hiki huenda zikadhibitiwa nje ya Chrome. <ph name="BEGIN_LINK" />Pata Maelezo Zaidi<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Ingia</translation>
<translation id="8288807391153049143">Onyesha cheti</translation>
<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="8298115750975731693">Wi-Fi unayotumia (<ph name="WIFI_NAME" />) inaweza kukuhitaji kutembelea <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Utafsiri haukufanikiwa kwa sababu ya hitilafu ya seva.</translation>
-<translation id="8311129316111205805">Pakia kipindi</translation>
<translation id="8332188693563227489">Ufikiaji wa <ph name="HOST_NAME" /> umekataliwa</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1179,7 +1338,6 @@
<translation id="8412145213513410671">Mivurugo ( <ph name="CRASH_COUNT" /> )</translation>
<translation id="8412392972487953978">Lazima uingize kaulisiri ile ile mara mbili.</translation>
<translation id="8416694386774425977">Mipangilio ya mtandao si sahihi na haikuweza kupakiwa. Maelezo ya ziada: <ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Kifaa kinadhibitiwa na <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Badilisha</translation>
<translation id="8428213095426709021">Mipangilio</translation>
@@ -1207,9 +1365,11 @@
<translation id="860043288473659153">Jina la mmiliki wa kadi</translation>
<translation id="861775596732816396">Ukubwa wa 4</translation>
<translation id="8620436878122366504">Wazazi wako bado hawajaiidhinisha</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Hifadhi Maelezo ya Kadi Hii kwenye Kifaa Hiki</translation>
<translation id="8663226718884576429">Muhtasari wa Agizo, <ph name="TOTAL_LABEL" />, Maelezo Zaidi</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, jibu, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Muunganisho wako kwa <ph name="DOMAIN" /> haujasimbwa.</translation>
<translation id="8718314106902482036">Malipo hayajakamilishwa</translation>
<translation id="8719263113926255150"><ph name="ENTITY" /> , <ph name="DESCRIPTION" /> , pendekezo la utafutaji</translation>
@@ -1223,6 +1383,7 @@
<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="8763927697961133303">Kifaa cha USB</translation>
<translation id="8768895707659403558">Ili utumie kadi zako kwenye vifaa vyako vyote, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">Rudia kufuta</translation>
<translation id="8792621596287649091">Unaweza kupoteza uwezo wa kufikia Akaunti yako ya <ph name="ORG_NAME" /> au kuibiwa utambulisho. Chromium inapendekeza ubadilishe nenosiri lako la sasa.</translation>
<translation id="8800988563907321413">Mapendekezo ya maudhui ya uhamishaji wa karibu yataonekana hapa</translation>
@@ -1233,10 +1394,12 @@
<translation id="885730110891505394">Kushiriki kwenye Google</translation>
<translation id="8858065207712248076">Chrome inapendekeza ubadilishe nenosiri lako la <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> ikiwa ulilitumia tena kwenye tovuti zingine.</translation>
<translation id="8866481888320382733">Hitilafu wakati wa kuchanganua mipangilio ya sera</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Zilizofungwa Hivi Karibuni</translation>
<translation id="8874824191258364635">Andika nambari sahihi ya kadi</translation>
<translation id="8891727572606052622">Modi batili ya proksi.</translation>
<translation id="8903921497873541725">Kuza karibu</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Ongeza Jina</translation>
@@ -1244,13 +1407,13 @@
<translation id="894185898663964645">Msimamizi wako ameweka mipangilio ya vyeti maalum vya msingi, hatua ambayo inaweza kumruhusu msimamizi aone maudhui ya tovuti unazotembelea.</translation>
<translation id="8943282376843390568">Chokaa</translation>
<translation id="8957210676456822347">Uidhinishaji wa Ukurasa wa Wavuti</translation>
+<translation id="8966619695390250636">Ulimaanisha?</translation>
<translation id="8968766641738584599">Hifadhi kadi</translation>
<translation id="8971063699422889582">Cheti cha seva kimechina.</translation>
<translation id="8975012916872825179">Hujumuisha maelezo kama nambari za simu, anwani za barua pepe na anwani za mahali bidhaa zitakapopelekwa</translation>
<translation id="8978053250194585037">Mfumo wa Kuvinjari Salama kwenye Google umegundua <ph name="BEGIN_LINK" />jaribio la kuiba data ya binafsi<ph name="END_LINK" /> kwenye <ph name="SITE" /> hivi majuzi. Tovuti zanazoiba data ya binafsi huiga tovuti nyingine ili kukuhadaa.</translation>
<translation id="8983003182662520383">Njia za Kulipa na Anwani Zinazotumia Google Pay</translation>
<translation id="8987927404178983737">Mwezi</translation>
-<translation id="8988408250700415532">Hitilafu fulani imetokea. Unaweza kumaliza agizo lako kwenye tovuti.</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>
@@ -1260,6 +1423,7 @@
<translation id="9011424611726486705">Fungua mipangilio ya tovuti</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Si sahihi)</translation>
<translation id="9035022520814077154">Hitilafu ya usalama</translation>
<translation id="9038649477754266430">Tumia huduma ya kutabiri ili upakie kurasa kwa haraka zaidi</translation>
@@ -1271,11 +1435,11 @@
<translation id="9065745800631924235"><ph name="TEXT" /> tafuta kwenye historia</translation>
<translation id="9069693763241529744">Imezuiwa na kiendelezi</translation>
<translation id="9076283476770535406">Huenda ina maudhui ya ngono</translation>
+<translation id="9076630408993835509">Kivinjari hiki hakidhibitiwi na kampuni au shirika lingine. Huenda shughuli kwenye kifaa hiki zinadhibitiwa nje ya Chrome. <ph name="BEGIN_LINK" />Pata Maelezo Zaidi<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Maelezo zaidi yanahitajika</translation>
<translation id="9080712759204168376">Muhtasari wa Agizo</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>
<translation id="9106062320799175032">Ongeza Anwani ya Kutuma Bili</translation>
-<translation id="9110718169272311511">Programu ya Mratibu wa Google katika Chrome inapatikana karibu na sehemu ya chini ya skrini</translation>
<translation id="9114524666733003316">Inathibitisha kadi…</translation>
<translation id="9128870381267983090">Unganisha kwenye mtandao</translation>
<translation id="9137013805542155359">Onyesha asili</translation>
@@ -1284,6 +1448,7 @@
<translation id="9148507642005240123">Tendua kuhariri</translation>
<translation id="9154194610265714752">Imesasishwa</translation>
<translation id="9157595877708044936">Inasanidi...</translation>
+<translation id="9158625974267017556">C6 (Bahasha)</translation>
<translation id="9168814207360376865">Ruhusu tovuti zikague ikiwa umehifadhi njia ya kulipa</translation>
<translation id="9169664750068251925">Zuia kila wakati kwenye tovuti hii</translation>
<translation id="9170848237812810038">&amp;Tendua</translation>
@@ -1298,10 +1463,12 @@
<translation id="9219103736887031265">Picha</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FUTA FOMU</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Unaweza kupoteza uwezo wa kufikia Akaunti yako ya Google. Chromium inapendekeza ubadilishe nenosiri lako sasa. Utaombwa uingie katika akaunti.</translation>
<translation id="939736085109172342">Folda mpya</translation>
<translation id="945855313015696284">Angalia maelezo yaliyo hapa chini na ufute kadi zozote ambazo si sahihi</translation>
<translation id="951104842009476243">Kadi za Malipo na za Kulipia Awali Zinazokubaliwa</translation>
+<translation id="958202389743790697">Imezuiwa kulingana na sera ya usalama ya <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Huenda maudhui haya yakajaribu kusakinisha programu za udanganyifu zinazojifanya kuwa kitu kingine au kukusanya data inayoweza kutumika kukufuatilia. <ph name="BEGIN_LINK" />Onyesha tu<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Muundo Rasmi</translation>
<translation id="973773823069644502">Chagua Mahali Bidhaa Itakapopelekwa</translation>
@@ -1310,6 +1477,7 @@
<translation id="984275831282074731">Njia za kulipa</translation>
<translation id="985199708454569384">&lt;p&gt;Utaona hitilafu hii kwenye kompyuta au simu yako kwa sababu tarehe na wakati wa kifaa chako si sahihi.&lt;/p&gt;
&lt;p&gt;Ili urekebishe hitilafu, fungua saa ya kifaa chako. Hakikisha kuwa tarehe na wakati ni sahihi.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Muundo wa Wasanidi Programu</translation>
<translation id="989988560359834682">Badilisha Anwani</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_ta.xtb b/chromium/components/strings/components_strings_ta.xtb
index cc850441ab4..7088bcace5d 100644
--- a/chromium/components/strings/components_strings_ta.xtb
+++ b/chromium/components/strings/components_strings_ta.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ta">
-<translation id="1005145902654145231">அமர்வின் பெயரை மாற்ற முடியவில்லை.</translation>
<translation id="1008557486741366299">இப்போது இல்லை </translation>
<translation id="1010200102790553230">பக்கத்தைப் பின்னர் ஏற்று</translation>
<translation id="1015730422737071372">கூடுதல் விவரங்களை வழங்கவும்</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">அறியப்படாத பெயர்</translation>
<translation id="1050038467049342496">பிற பயன்பாடுகளை மூடவும்</translation>
<translation id="1055184225775184556">&amp;சேர்த்தலைச் செயல்தவிர்</translation>
+<translation id="1056898198331236512">எச்சரிக்கை</translation>
<translation id="1058479211578257048">கார்டுகளைச் சேமிக்கிறது...</translation>
<translation id="10614374240317010">எப்போதும் சேமிக்காதவை</translation>
+<translation id="1062160989074299343">Prc10 (என்வலப்)</translation>
<translation id="106701514854093668">டெஸ்க்டாப் புக்மார்க்குகள்</translation>
<translation id="1074497978438210769">பாதுகாப்பற்றது</translation>
<translation id="1080116354587839789">அகலத்திற்குப் பொருத்து</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">கார்டிலுள்ள பெயரைச் சேர்க்கவும்</translation>
<translation id="1089439967362294234">கடவுச்சொல்லை மாற்று</translation>
<translation id="109743633954054152">Chrome அமைப்புகளில் கடவுச்சொற்களை நிர்வகிக்கவும்</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">இணையதளங்கள் தங்கள் பாதுகாப்பைப் புதுப்பிக்கும் போது, எச்சரிக்கைகளைக் காண்பிப்பது வழக்கம் தான். இந்த நிலை விரைவில் மேம்படும்.</translation>
<translation id="1126551341858583091">அகச் சேமிப்பகத்தில் <ph name="CRASH_SIZE" /> அளவு உள்ளது.</translation>
<translation id="112840717907525620">கொள்கை தற்காலிக சேமிப்பு சரியாக உள்ளது</translation>
+<translation id="1131264053432022307">நீங்கள் நகலெடுத்த படம்</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> எதிர்பாராத விதமாக இணைப்பை நிறுத்தியது.</translation>
<translation id="1161325031994447685">வைஃபையுடன் மீண்டும் இணைத்தல்</translation>
<translation id="1165039591588034296">பிழை</translation>
-<translation id="1173894706177603556">மறுபெயரிடு</translation>
<translation id="1175364870820465910">&amp;அச்சிடு...</translation>
<translation id="1181037720776840403">அகற்று</translation>
<translation id="1197088940767939838">ஆரஞ்சு</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">உங்கள் சாதனப் பெயர்</translation>
<translation id="124116460088058876">மேலும் மொழிகள்</translation>
<translation id="1250759482327835220">அடுத்த முறை விரைவாகப் பணம் செலுத்த, உங்கள் கார்டின் பெயரையும் பில்லிங் முகவரியையும் உங்கள் Google கணக்கில் சேமிக்கவும்.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (ஒத்திசைக்கப்பட்டன)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">கட்டளை வரி மாற்று வடிவங்கள்</translation>
<translation id="129553762522093515">சமீபத்தில் மூடியவை</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />குக்கீகளை அழிக்கவும்<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">தேர்ந்தெடுத்த அமர்வு இல்லை.</translation>
+<translation id="1320233736580025032">Prc1 (என்வலப்)</translation>
+<translation id="132301787627749051">கிளிப்-போர்டு படத்தைத் தேடும்</translation>
<translation id="1323433172918577554">மேலும் காட்டு</translation>
<translation id="132390688737681464">முகவரிகளைச் சேமித்துத் தானாக நிரப்பு</translation>
<translation id="1333989956347591814">இருப்பினும், பின்வரும் தரப்பினர் உங்கள் செயல்பாட்டைப் <ph name="BEGIN_EMPHASIS" />பார்க்க முடியும்<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">பிக்கப் முகவரி</translation>
<translation id="1348198688976932919">தளத்தில் ஆபத்தான பயன்பாடுகள் உள்ளன</translation>
<translation id="1348779747280417563">பெயரை உறுதிப்படுத்தவும்</translation>
+<translation id="1357195169723583938">சமீபத்தில் சாதனத்தை யார், எப்போது பயன்படுத்தியது</translation>
+<translation id="1364822246244961190">இந்தக் கொள்கை தடைசெய்யப்பட்டுள்ளது, இதன் மதிப்பு புறக்கணிக்கப்படும்.</translation>
<translation id="1374468813861204354">பரிந்துரைகள்</translation>
+<translation id="1374692235857187091">Index-4x6 (போஸ்ட்கார்டு)</translation>
<translation id="1375198122581997741">பதிப்பைப் பற்றி</translation>
<translation id="1376836354785490390">குறைவாகக் காட்டு</translation>
<translation id="1377321085342047638">கார்டு எண்</translation>
<translation id="138218114945450791">வெளிர் நீலம்</translation>
+<translation id="1382194467192730611">உங்கள் நிர்வாகி அனுமதிக்கும் USB சாதனம்</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> எந்தத் தரவையும் அனுப்பவில்லை.</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> தளம் அதன் கோரிக்கைகள் அனைத்திற்கும் பாதுகாப்புக் கொள்கை
+ பொருந்த வேண்டும் எனக் கோரிக்கை விடுத்துள்ளது, மேலும் இந்தக் கொள்கையானது தற்போது தளத்தைப்
+ பாதுகாப்பற்றது எனக் கருதுகிறது.</translation>
<translation id="1405567553485452995">வெளிர் பச்சை</translation>
<translation id="1407135791313364759">எல்லாவற்றையும் திற</translation>
<translation id="1413809658975081374">தனியுரிமைப் பிழை</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">ஆம்</translation>
<translation id="1430915738399379752">அச்சிடுக</translation>
<translation id="1455413310270022028">எரேஸர்</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">மேலும் காண்பி</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">ஷிப்பிங் முகவரியைத் தேர்வு செய்</translation>
+<translation id="1492194039220927094">கொள்கைகள் புஷ்:</translation>
<translation id="1501859676467574491">எனது Google கணக்கிலிருந்து கார்டுகளைக் காண்பி</translation>
-<translation id="1506687042165942984">இந்தப் பக்கத்தின் சேமித்த நகலைக் காட்டு (அதாவது, காலாவதியானது என அறியப்பட்டது).</translation>
<translation id="1507202001669085618">&lt;p&gt;சில வைஃபை போர்ட்டல்களில், இணையத்தைப் பயன்படுத்தும் முன்பு நீங்கள் உள்நுழைய வேண்டியிருக்கும். அதுபோன்ற போர்ட்டல்களைப் பயன்படுத்தினால், இந்தப் பிழையைப் பார்ப்பீர்கள்.&lt;/p&gt;
&lt;p&gt;பிழையைச் சரிசெய்ய, நீங்கள் திறக்க முயலும் பக்கத்தில் உள்ள &lt;strong&gt;இணை&lt;/strong&gt; என்பதைக் கிளிக் செய்யவும்.&lt;/p&gt;</translation>
<translation id="1517433312004943670">ஃபோன் எண் தேவை</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">உருவாக்கிய தேதி</translation>
<translation id="1521655867290435174">Google விரிதாள்</translation>
<translation id="1527263332363067270">இணைப்பிற்காகக் காத்திருக்கிறது…</translation>
+<translation id="1529521330346880926">10x15 (என்வலப்)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">இந்தப் பக்கம் தெரிவிப்பது:</translation>
<translation id="153384715582417236">அவ்வளவு தான்!</translation>
<translation id="154408704832528245">டெலிவரி முகவரியைத் தேர்வு செய்</translation>
<translation id="1549470594296187301">இந்த அம்சத்தைப் பயன்படுத்த JavaScript இயக்கப்பட வேண்டும்.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">காலாவதித் தேதியை உள்ளிடவும்</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">இந்த இணையப்பக்கத்தைக் காட்டும்போது ஏதோ தவறு ஏற்பட்டது.</translation>
<translation id="1592005682883173041">அகத் தரவு அணுகல்</translation>
<translation id="1594030484168838125">தேர்வுசெய்</translation>
<translation id="161042844686301425">சியான்</translation>
-<translation id="1618822247301510817">நீங்கள் நகலெடுத்த படம்</translation>
<translation id="1620510694547887537">கேமரா</translation>
<translation id="1623104350909869708">கூடுதல் உரையாடல்களை உருவாக்குவதிலிருந்து இந்தப் பக்கத்தைத் தடு</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">அமர்வை முடி</translation>
<translation id="1639239467298939599">ஏற்றுகிறது</translation>
<translation id="1640180200866533862">பயனர் கொள்கைகள்</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">வழக்கமாக, <ph name="SITE" /> உங்கள் தகவலைப் பாதுகாப்பதற்காக முறைமையாக்கத்தைப் பயன்படுத்துகிறது. இந்த முறை <ph name="SITE" /> உடன் இணைவதற்கு Google Chrome முயற்சித்தபோது வழக்கத்திற்கு மாறான மற்றும் தவறான நற்சான்றிதழ்களை இணையதளம் வழங்கியது. தாக்குபவர் தன்னை <ph name="SITE" /> ஆகக் காட்ட முயற்சிக்கும் போது அல்லது இணைப்பை வைஃபை உள்நுழைவுத் திரை குறுக்கிடும் போது இது ஏற்படலாம். இருப்பினும், தரவு எதுவும் பரிமாற்றப்படுவதற்கு முன் Google Chrome இணைப்பை நிறுத்தியதால் உங்கள் தகவல் பாதுகாப்பாகவே இருக்கிறது.</translation>
<translation id="168841957122794586">சேவையக சான்றிதழில் வலுவற்ற குறியீட்டாக்க விசை இருக்கிறது.</translation>
<translation id="1697532407822776718">எல்லாவற்றையும் அமைத்துவிட்டீர்கள்!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் நாளை முதலே செல்லுபடியாகும். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.}other{இந்தச் சேவையகம் தான் <ph name="DOMAIN" /> என்பதை நிரூபிக்க முடியவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் எதிர்காலத்தில் # நாட்களில் ஏற்றுக்கொள்ளப்படும். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">ஆவணம் மிகப் பெரிதாக இருப்பதால் அதில் விரிவுரையைச் சேர்க்க முடியாது</translation>
<translation id="1721312023322545264">இந்தத் தளத்திற்குச் செல்ல, <ph name="NAME" /> இன் அனுமதி வேண்டும்</translation>
<translation id="1721424275792716183">* அவசியமான புலம்</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">கணினி நிர்வாகியைத் தொடர்புகொள்ளவும்</translation>
<translation id="1740951997222943430">சரியான காலாவதி மாதத்தை உள்ளிடவும்</translation>
<translation id="1743520634839655729">அடுத்த முறை விரைவாகப் பணம் செலுத்த, உங்கள் கார்டின் பெயரையும் பில்லிங் முகவரியையும் உங்கள் Google கணக்கிலும் இந்தச் சாதனத்திலும் சேமிக்கவும்.</translation>
+<translation id="1745880797583122200">உங்கள் உலாவி நிர்வகிக்கப்படுகிறது</translation>
<translation id="17513872634828108">தாவல்களைத் திற</translation>
<translation id="1753706481035618306">பக்க எண்</translation>
<translation id="1763864636252898013">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை உங்கள் சாதனத்தின் இயக்க முறைமை நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">உங்களின் ஒத்திசை சொற்றொடரைப் புதுப்பிக்கவும்.</translation>
<translation id="1787142507584202372">உங்கள் தாவல்கள் இங்கே தோன்றும்</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">கார்டு உரிமையாளரின் பெயர்</translation>
<translation id="1821930232296380041">தவறான கோரிக்கை அல்லது கோரிக்கை அளவுருக்கள்</translation>
+<translation id="1822540298136254167">நீங்கள் பார்வையிட்ட இணையதளங்களும் அவற்றில் செலவழித்த நேரமும்</translation>
<translation id="1826516787628120939">சரிபார்க்கிறது</translation>
<translation id="1834321415901700177">இந்தத் தளத்தில் தீங்கிழைக்கும் நிரல்கள் உள்ளன</translation>
<translation id="1839551713262164453">கொள்கை மதிப்புகளின் சரிபார்ப்பு பிழைகளுடன் தோல்வியில் முடிந்தது.</translation>
@@ -180,6 +202,9 @@
<translation id="1981206234434200693">Chromeமின் உலாவல் வரலாற்றுத் தரவை அழி</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{மேலும் 1}other{மேலும் #}}</translation>
<translation id="2003709556000175978">உங்கள் கடவுச்சொல்லை இப்போதே மீட்டமைக்கவும்</translation>
+<translation id="20053308747750172">நீங்கள் செல்லும் <ph name="ORIGIN" /> சேவையகம், அதனுடன் தொடர்புடைய எல்லாக் கோரிக்கைகளுக்கும்
+ பாதுகாப்புக் கொள்கை பொருந்த வேண்டுமெனக் கோரிக்கை விடுத்துள்ளது. ஆனால் தற்போது அது
+ தவறான கொள்கையை வழங்கியுள்ளது. இதன் மூலம், <ph name="SITE" />க்கான உங்கள் கோரிக்கையை நிறைவுசெய்ய முடியாத வகையில் உலாவி தடுக்கப்பட்டுள்ளது.</translation>
<translation id="2025186561304664664">ப்ராக்ஸி, தானியங்கி உள்ளமைவுக்கு அமைக்கப்பட்டுள்ளது</translation>
<translation id="2030481566774242610"><ph name="LINK" /> ஐக் குறிப்பிடுகிறீர்களா?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />ப்ராக்ஸி மற்றும் ஃபயர்வாலைச் சரிபார்த்தல்<ph name="END_LINK" /></translation>
@@ -196,6 +221,7 @@
<translation id="2096368010154057602">துறை</translation>
<translation id="2102134110707549001">வலுவான கடவுச்சொல்லைப் பரிந்துரைசெய்…</translation>
<translation id="2108755909498034140">கணினியை மீண்டும் தொடங்கவும்</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">கார்டு</translation>
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> ஆல் கொள்கை மேலெழுதப்பட்டுள்ளதால் புறக்கணிக்கப்பட்டது.</translation>
<translation id="213826338245044447">மொபைல் புக்மார்க்குகள்</translation>
@@ -206,6 +232,7 @@
<translation id="2154484045852737596">கார்டைத் திருத்தவும்</translation>
<translation id="2166049586286450108">முழு நிர்வாகி அணுகல்</translation>
<translation id="2166378884831602661">இந்தத் தளத்தால் பாதுகாப்பான இணைப்பை வழங்க முடியவில்லை</translation>
+<translation id="2169984857010174799">Kaku2 (என்வலப்)</translation>
<translation id="2181821976797666341">கொள்கைகள்</translation>
<translation id="2183608646556468874">ஃபோன் எண்</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 முகவரி}other{# முகவரிகள்}}</translation>
@@ -223,11 +250,15 @@
<translation id="2270484714375784793">தொலைபேசி எண்</translation>
<translation id="2283340219607151381">முகவரிகளைச் சேமித்துத் தானாக நிரப்பு</translation>
<translation id="2292556288342944218">உங்கள் இணைய அணுகல் தடுக்கப்பட்டது</translation>
+<translation id="2294558542833290837">நீங்கள் திறந்துள்ள இணைப்பு வழக்கத்திற்கு மாறானது</translation>
+<translation id="2297722699537546652">B5 (என்வலப்)</translation>
+<translation id="2310021320168182093">Chou2 (என்வலப்)</translation>
<translation id="2316887270356262533">1 மெ.பை. அளவிற்கும் குறைவான இடத்தைக் காலியாக்கும். நீங்கள் அடுத்த முறை பார்வையிடும் போது, சில தளங்கள் மிகவும் மெதுவாக ஏற்றப்படலாம்.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />க்குப் பயனர்பெயரும் கடவுச்சொல்லும் தேவை.</translation>
<translation id="2317583587496011522">டெபிட் கார்டுகள் ஏற்கப்படுகின்றன.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, காலாவதித் தேதி - <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">அமைப்பை உங்கள் நிர்வாகி கட்டுப்படுத்துகிறார்</translation>
+<translation id="2346319942568447007">நீங்கள் நகலெடுத்தப் படம்</translation>
<translation id="2349790679044093737">VR அமர்வு இயக்கத்திலுள்ளது</translation>
<translation id="2354001756790975382">பிற புக்மார்க்ஸ்</translation>
<translation id="2354430244986887761">சமீபத்தில் Google பாதுகாப்பான தேடலானது <ph name="SITE" /> இல் <ph name="BEGIN_LINK" />தீங்கிழைக்கும் பயன்பாடுகளைக் கண்டறிந்தது<ph name="END_LINK" />.</translation>
@@ -239,29 +270,39 @@
<translation id="2365563543831475020"><ph name="CRASH_TIME" /> அன்று பெற்ற சிதைவு அறிக்கை பதிவேற்றப்படவில்லை</translation>
<translation id="2367567093518048410">நிலை</translation>
<translation id="2378238891085281592">மறைநிலையில் இருக்கிறீர்கள்</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">நிறுவன இயல்புநிலை</translation>
<translation id="2386255080630008482">சேவையகச் சான்றிதழ் திரும்பப் பெறப்பட்டது.</translation>
<translation id="2392959068659972793">மதிப்பும் எதுவும் அமைக்கப்படாத கொள்கைகளைக் காட்டு</translation>
<translation id="239429038616798445">இந்த ஷிப்பிங் முறை இல்லை. வேறு முறையைப் பயன்படுத்திப் பார்க்கவும்.</translation>
<translation id="2396249848217231973">&amp;நீக்குதலைச் செயல்தவிர்</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் திரும்பப்பெறப்பட்டிருக்கலாம். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="2418081434543109369">நீங்கள் செல்லும் <ph name="ORIGIN" /> சேவையகம், அதனுடன் தொடர்புடைய எல்லாக் கோரிக்கைகளுக்கும்
+ பாதுகாப்புக் கொள்கை பொருந்த வேண்டுமெனக் கோரிக்கை விடுத்துள்ளது. ஆனால், இப்போது
+ இது கொள்கையை வழங்கவில்லை. இதனால்
+ <ph name="SITE" />க்கான உங்கள் கோரிக்கையை நிறைவுசெய்ய
+ முடியாத வகையில்
+ உலாவி தடுக்கப்பட்டுள்ளது.</translation>
<translation id="244665789865330679">உங்கள் சாதனத்தையும் கணக்கையும் <ph name="ENROLLMENT_DOMAIN" /> நிர்வகிக்கிறது. அதாவது உங்கள் நிர்வாகி இவற்றைத் தொலைநிலையிலிருந்து உள்ளமைக்க முடியும்.</translation>
<translation id="2463193859425327265">முகப்புப் பக்கத்தை மாற்று</translation>
<translation id="2463739503403862330">நிரப்பு</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">டெலிவரி முறையைத் தேர்வு செய்</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />நெட்வொர்க் டயக்னாஸ்டிக்ஸ் கருவியை இயக்கவும்<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">இந்தப் பக்கத்தை மொழிபெயர்</translation>
<translation id="2479410451996844060">தவறான தேடல் URL.</translation>
<translation id="2482878487686419369">அறிவிப்புகள்</translation>
<translation id="248348093745724435">சாதனக் கொள்கைகள்</translation>
+<translation id="2485387744899240041">உங்கள் சாதனம் மற்றும் உலாவியின் பயனர்பெயர்கள்</translation>
<translation id="2491120439723279231">சேவையகச் சான்றிதழில் பிழைகள் உள்ளன.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON பார்சர்</translation>
<translation id="2495093607237746763">இது தேர்ந்தெடுக்கப்பட்டால், விரைவாகப் படிவத்தை நிரப்ப, உங்கள் கார்டின் நகலை Chromium இந்தச் சாதனத்தில் சேமிக்கும்.</translation>
<translation id="2498091847651709837">புதிய கார்டை ஸ்கேன்செய்</translation>
<translation id="2501278716633472235">திரும்பிச் செல்</translation>
<translation id="2503184589641749290">ஏற்கப்படும் டெபிட் மற்றும் ப்ரீபெய்டு கார்டுகள்</translation>
<translation id="2515629240566999685">உங்கள் பகுதியில் உள்ள சிக்னலைச் சரிபார்த்தல்</translation>
-<translation id="2516852381693169964">படத்தை <ph name="SEARCH_ENGINE" /> இல் தேடும்</translation>
<translation id="2523886232349826891">இந்தச் சாதனத்தில் மட்டும் சேமிக்கப்படும்</translation>
<translation id="2524461107774643265">மேலும் தகவலைச் சேர்க்கவும்</translation>
<translation id="2536110899380797252">முகவரியைச் சேர்</translation>
@@ -273,6 +314,7 @@
<translation id="2587841377698384444">கோப்பக API ஐடி:</translation>
<translation id="2597378329261239068">இந்த ஆவணம் கடவுச்சொல் பாதுகாக்கப்பட்ட ஒன்று. தயவுசெய்து ஒரு கடவுச்சொல்லை உள்ளிடுக.</translation>
<translation id="2609632851001447353">வேறுபாடுகள்</translation>
+<translation id="2618023639789766142">C10 (என்வலப்)</translation>
<translation id="2625385379895617796">உங்கள் கடிகாரம் மிகவும் முன்னோக்கி இருக்கிறது</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> இன் சேவையக IP முகவரியைக் கண்டறிய முடியவில்லை.</translation>
<translation id="2639739919103226564">நிலை:</translation>
@@ -282,7 +324,9 @@
<translation id="2666117266261740852">பிற தாவல்கள் அல்லது பயன்பாடுகளை மூடவும்</translation>
<translation id="267371737713284912">செயல்தவிர்க்க, <ph name="MODIFIER_KEY_DESCRIPTION" />ஐ அழுத்தவும்</translation>
<translation id="2674170444375937751">உங்கள் வரலாற்றிலிருக்கும் பக்கங்களை நிச்சயமாக நீக்க விரும்புகிறீர்களா?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">வெளியேறு</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">ஏற்கப்படும் கார்டுகள்</translation>
<translation id="2702801445560668637">வாசிப்புப் பட்டியல்</translation>
<translation id="2704283930420550640">மதிப்பானது வடிவமைப்பிற்குப் பொருந்தவில்லை.</translation>
@@ -299,7 +343,6 @@
<translation id="2742870351467570537">தேர்ந்தெடுத்த உருப்படிகளை அகற்றுக</translation>
<translation id="277133753123645258">ஷிப்பிங் முறை</translation>
<translation id="277499241957683684">சாதனப் பதிவு இல்லை</translation>
-<translation id="2781030394888168909">MacOS வடிவமைப்பில் பதிவிறக்கு</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">இணைப்பு மீட்டமைக்கப்பட்டது.</translation>
<translation id="2788784517760473862">ஏற்கப்படும் கிரெடிட் கார்டுகள்</translation>
@@ -311,8 +354,10 @@
<translation id="2826760142808435982">இந்த இணைப்பு <ph name="CIPHER" /> ஐப் பயன்படுத்தி குறியாக்கப்பட்டது, அங்கீகரிக்கப்பட்டது, ஒரு முக்கிய பரிமாற்ற செயல்முறையாக <ph name="KX" /> ஐப் பயன்படுத்துகிறது.</translation>
<translation id="2835170189407361413">படிவத்தை அழி</translation>
<translation id="2847118875340931228">மறைநிலை சாளரத்தைத் திற</translation>
+<translation id="2850739647070081192">Invite (என்வலப்)</translation>
<translation id="2851634818064021665">இந்தத் தளத்தைப் பார்ப்பதற்கு அனுமதி தேவை</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">கார்டைச் சேமிக்கவா?</translation>
<translation id="2903493209154104877">முகவரிகள்</translation>
<translation id="290376772003165898"><ph name="LANGUAGE" /> மொழியில் பக்கம் இல்லையா?</translation>
@@ -322,6 +367,7 @@
<translation id="2925673989565098301">டெலிவரி முறை</translation>
<translation id="2928905813689894207">பில்லிங் முகவரி</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழ் <ph name="DOMAIN2" /> இலிருந்து பெறப்பட்டது. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="2948083400971632585">இணைப்பிற்காக உள்ளமைத்த எந்த பிராக்சிகளையும் நீங்கள் அமைப்புகள் பக்கத்திலிருந்து முடக்கலாம்.</translation>
<translation id="2955913368246107853">தேடல் பெட்டியை மூடுக</translation>
@@ -338,11 +384,14 @@
<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="3023071826883856138">You4 (என்வலப்)</translation>
<translation id="3024663005179499861">தவறான கொள்கை வகை</translation>
<translation id="3037605927509011580">அச்சச்சோ!</translation>
<translation id="3041612393474885105">சான்றிதழ் தகவல்</translation>
+<translation id="3060227939791841287">C9 (என்வலப்)</translation>
<translation id="3064966200440839136">வெளிப்புறப் பயன்பாட்டின் மூலம் பணத்தை செலுத்த, மறைநிலையிலிருந்து வெளியேறுகிறீர்கள். தொடரவா?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ஏதுமில்லை}=1{1 கடவுச்சொல்}other{# கடவுச்சொற்கள்}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">பிக்அப் முகவரியைச் சேர்</translation>
<translation id="3105172416063519923">பண்பு ஐடி:</translation>
<translation id="3109728660330352905">இந்தப் பக்கத்தைக் காண உங்களுக்கு அங்கீகாரம் அளிக்கப்படவில்லை.</translation>
@@ -361,20 +410,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> இல் <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">கட்டணம் செலுத்துவதை ரத்துசெய்</translation>
<translation id="3207960819495026254">புக்மார்க் செய்யப்பட்டது</translation>
-<translation id="3209375525920864198">சரியான அமர்வுப் பெயரை உள்ளிடவும்.</translation>
+<translation id="321912867715453276">எச்சரிக்கை: ஒன்றுக்கும் மேற்பட்ட மூலங்கள் கொள்கையில் உள்ளன. ஆனால், மதிப்புகளில் மாற்றம் இல்லை.</translation>
<translation id="3225919329040284222">உள்ளமைந்த எதிர்பார்ப்புகளுடன் பொருந்தாத சான்றிதழை சேவையகம் வழங்கியது. சில உயர்-பாதுகாப்பு வலைத்தளங்களில் உங்களைப் பாதுகாக்கவே இந்த எதிர்பார்ப்புகள் சேர்க்கப்படுகின்றன.</translation>
-<translation id="3226128629678568754">பக்கத்தை ஏற்ற தேவைப்படும் தரவை மறுமுறைச் சமர்ப்பிப்பதற்கு மீண்டும் ஏற்று என்ற பொத்தானை அழுத்துக.</translation>
+<translation id="3226128629678568754">பக்கத்தை ஏற்ற தேவைப்படும் தரவை மறுமுறைச் சமர்ப்பிப்பதற்கு மீண்டும் ஏற்று என்ற பட்டனை அழுத்துக.</translation>
<translation id="3227137524299004712">மைக்ரோஃபோன்</translation>
<translation id="3228969707346345236">பக்கம் முன்பே <ph name="LANGUAGE" /> இல் இருப்பதால் மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
+<translation id="3229041911291329567">உங்கள் சாதனம் மற்றும் உலாவியின் பதிப்புத் தகவல்</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">கார்டிலுள்ள பெயரைச் சேர்க்கவும்</translation>
<translation id="3287510313208355388">ஆன்லைனில் இருக்கும் போது பதிவிறக்கு</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> கொள்கை குறித்து மேலும் அறிக</translation>
<translation id="3303855915957856445">தேடல் முடிவுகள் எதுவுமில்லை</translation>
-<translation id="3305707030755673451"><ph name="TIME" /> அன்று உங்கள் தரவு உங்கள் ஒத்திசைவு கடவுச்சொற்றொடரைக் கொண்டு முறைமையாக்கப்பட்டது. ஒத்திசைவைத் தொடங்க, அதை உள்ளிடவும்.</translation>
<translation id="3320021301628644560">பில்லிங் முகவரியைச் சேர்க்கவும்</translation>
<translation id="3324983252691184275">அடர்சிவப்பு</translation>
<translation id="3338095232262050444">பாதுகாப்பானது</translation>
@@ -402,9 +452,11 @@
<translation id="3427342743765426898">&amp;திருத்தலை மீண்டும் செய்</translation>
<translation id="342781501876943858">பிற தளங்களில் உங்கள் கடவுச்சொல்லை மீண்டும் பயன்படுத்தினால், அதை மீட்டமைக்கும்படி Chromium பரிந்துரைக்கிறது.</translation>
<translation id="3431636764301398940">இந்தச் சாதனத்தில் கார்டைச் சேமி</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">சாதனத்தின் உரிமையாளர் டைனோசர் கேமை முடக்கியுள்ளார்.</translation>
<translation id="3447884698081792621">சான்றிதழைக் காட்டு (வழங்கியது: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">எடுப்பதற்கான இடைவேளை:</translation>
+<translation id="3456231139987291353">Number-11 (என்வலப்)</translation>
<translation id="3461824795358126837">ஹைலைட்டர்</translation>
<translation id="3462200631372590220">மேம்பட்டவையை மறை</translation>
<translation id="3467763166455606212">கார்டு உரிமையாளரின் பெயர் தேவை</translation>
@@ -426,20 +478,23 @@
<translation id="358285529439630156">கிரெடிட் மற்றும் ப்ரீபெய்டு கார்டுகள் ஏற்கப்படுகின்றன.</translation>
<translation id="3582930987043644930">பெயரைச் சேர்</translation>
<translation id="3583757800736429874">&amp;நகர்த்தலை மீண்டும் செய்</translation>
+<translation id="35866233670761917">நீங்கள் செல்லும் இணையதளங்களின் உள்ளடக்கங்களை நிர்வாகிகள் பார்ப்பதில்லை</translation>
<translation id="3586931643579894722">விவரங்களை மறை</translation>
+<translation id="3592413004129370115">Italian (என்வலப்)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">அளவு: 2</translation>
<translation id="3615877443314183785">சரியான காலாவதித் தேதியை உள்ளிடவும்</translation>
<translation id="36224234498066874">உலாவல் தரவை அழி...</translation>
<translation id="362276910939193118">முழு வரலாற்றையும் காண்பி</translation>
-<translation id="3623476034248543066">மதிப்பைக் காட்டு</translation>
<translation id="3630155396527302611">இது நெட்வொர்க்கை அணுகுவதற்கு அனுமதிக்கப்பட்ட நிரலாக ஏற்கனவே பட்டியலிடப்பட்டிருந்தால்,
இதைப் பட்டியலில் இருந்து அகற்றிவிட்டு மீண்டும் சேர்த்துப் பார்க்கவும்.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">சரிபார்ப்பு வெற்றி</translation>
<translation id="3655670868607891010">இதை அடிக்கடி காண்கிறீர்கள் எனில், <ph name="HELP_LINK" /> ஐ முயற்சிக்கவும்.</translation>
<translation id="3658742229777143148">மீள்திருத்தங்கள்</translation>
<translation id="366077651725703012">கிரெடிட் கார்டைப் புதுப்பி</translation>
<translation id="3676592649209844519">சாதன ஐடி:</translation>
+<translation id="3677008721441257057">இதைக் குறிப்பிட்டீர்களா: &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">கோரிக்கையில் கையொப்பமிட முடியவில்லை</translation>
<translation id="3678529606614285348">புதிய மறைநிலைச் சாளரத்தில் பக்கத்தைத் திறக்கவும் (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375"><ph name="CRASH_TIME" /> அன்று சிதைவு அறிக்கை பதிவுசெய்யப்பட்டு, <ph name="UPLOAD_TIME" /> அன்று பதிவேற்றப்பட்டது</translation>
@@ -447,13 +502,14 @@
<translation id="3704162925118123524">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் நெட்வொர்க், அதன் உள்நுழைவுப் பக்கத்தை நீங்கள் பார்க்கக் கோரலாம்.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">ஏற்றுகிறது…</translation>
+<translation id="3709599264800900598">நீங்கள் நகலெடுத்த உரை</translation>
<translation id="3712624925041724820">உரிமம் முடிந்தது</translation>
<translation id="3714780639079136834">மொபைல் டேட்டா அல்லது வைஃபையை இயக்குதல்</translation>
<translation id="3715597595485130451">வைஃபையுடன் இணைத்தல்</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ப்ராக்ஸி, ஃபயர்வால் மற்றும் DNS உள்ளமைவைச் சரிபார்த்தல்<ph name="END_LINK" /></translation>
<translation id="372429172604983730">வைரஸ்தடுப்பு, ஃபயர்வால், இணைய வடிப்பான் அல்லது ப்ராக்ஸி மென்பொருள் உள்ளிட்ட ஆப்ஸ்கள் இந்தப் பிழையை ஏற்படுத்தக்கூடும்.</translation>
+<translation id="373042150751172459">B4 (என்வலப்)</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="3745099705178523657">நீங்கள் உறுதிப்படுத்திய பின்னர், உங்கள் Google கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</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>
@@ -466,10 +522,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">காலாவதி: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">அளவு: 16</translation>
+<translation id="3797522431967816232">Prc3 (என்வலப்)</translation>
<translation id="3807873520724684969">தீங்கிழைக்கும் உள்ளடக்கம் தடுக்கப்பட்டது.</translation>
<translation id="3810973564298564668">நிர்வகி</translation>
<translation id="382518646247711829">நீங்கள் பிராக்சி சர்வரைப் பயன்படுத்தினால்....</translation>
<translation id="3828924085048779000">வெற்று கடவுச்சொற்றொடருக்கு அனுமதியில்லை.</translation>
+<translation id="3831915413245941253">கூடுதல் செயல்பாடுகளுக்காக <ph name="ENROLLMENT_DOMAIN" /> நீட்டிப்புகளை நிறுவியுள்ளது. உங்கள் தரவில் சிலவற்றை இந்த நீட்டிப்புகள் அணுகும்.</translation>
<translation id="385051799172605136">முந்தைய பக்கம்</translation>
<translation id="3858027520442213535">தேதியையும் நேரத்தையும் புதுப்பி</translation>
<translation id="3884278016824448484">முரண்பாடான சாதன அடையாளங்காட்டி</translation>
@@ -477,6 +535,7 @@
<translation id="3886446263141354045">இந்தத் தளத்தை அணுகுவதற்கான உங்கள் கோரிக்கை <ph name="NAME" />க்கு அனுப்பப்பட்டது</translation>
<translation id="3890664840433101773">மின்னஞ்சலைச் சேர்</translation>
<translation id="3901925938762663762">கார்டு காலாவதியானது</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">இந்தத் தளத்தில் எப்போதும் கேள்</translation>
<translation id="3949571496842715403">இது <ph name="DOMAIN" /> தான் என்பதை, இந்தச் சேவையகத்தால் உறுதிப்படுத்த முடியவில்லை; பொருள் மாற்றுப் பெயர்களை அதன் பாதுகாப்புச் சான்றிதழ் குறிப்பிடவில்லை. இது தவறான உள்ளமைவினால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
@@ -487,11 +546,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{ஏதுமில்லை}=1{1 தளத்திலிருந்து }other{# தளங்களிலிருந்து }}</translation>
<translation id="397105322502079400">கணக்கிடுகிறது...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> தடுக்கப்பட்டுள்ளது</translation>
-<translation id="3984550557525787191">இந்த அமர்வுப் பெயர் ஏற்கனவே உள்ளது.</translation>
<translation id="3987940399970879459">1 மெ.பை. அளவை விடக் குறைவாக உள்ளது</translation>
+<translation id="4008849406247176967">எச்சரிக்கை: பொருந்தாத மதிப்புகளைக் கொண்ட ஒன்றுக்கும் மேற்பட்ட மூலங்கள் இந்தக் கொள்கையில் உள்ளன!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{அருகில் ஒரு இணையப் பக்கம் உள்ளது}other{அருகில் # இணையப் பக்கங்கள் உள்ளன}}</translation>
<translation id="4030383055268325496">&amp;சேர்த்தலைச் செயல்தவிர்</translation>
+<translation id="4032320456957708163">உங்கள் உலாவியை <ph name="ENROLLMENT_DOMAIN" /> நிர்வகிக்கிறது</translation>
<translation id="4058922952496707368">விசை "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (என்வலப்)</translation>
<translation id="4067947977115446013">சரியான முகவரியைச் சேர்க்கவும்</translation>
<translation id="4072486802667267160">ஆர்டரைச் செயல்படுத்துவதில் பிழை ஏற்பட்டது. பிறகு முயலவும்.</translation>
<translation id="4075732493274867456">க்ளையன்ட்டும் சேவையகமும் பொதுவான SSL நெறிமுறைப் பதிப்பையோ சைஃபர் பொதியையோ ஆதரிக்கவில்லை.</translation>
@@ -511,10 +572,12 @@
<translation id="4159784952369912983">பர்பிள்</translation>
<translation id="4165986682804962316">தள அமைப்புகள்</translation>
<translation id="4171400957073367226">தவறான சரிபார்ப்பு கையொப்பம்</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{மேலும் <ph name="ITEM_COUNT" /> உருப்படி}other{மேலும் <ph name="ITEM_COUNT" /> உருப்படிகள்}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;நகர்த்தலை மீண்டும் செய்</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ஃபயர்வால் மற்றும் வைரஸ் எதிர்ப்பு உள்ளமைவைச் சரிபார்த்தல்<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (என்வலப்)</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="4221630205957821124">&lt;h4&gt;படி 1: போர்ட்டலில் உள்நுழையவும்&lt;/h4&gt;
@@ -546,58 +609,79 @@
<translation id="4277028893293644418">கடவுச்சொல்லை மீட்டமை</translation>
<translation id="4280429058323657511">, காலாவதித் தேதி: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{இந்தக் கார்டு உங்கள் Google கணக்கில் சேமிக்கப்பட்டது}other{இந்தக் கார்டுகள் உங்கள் Google கணக்கில் சேமிக்கப்பட்டன}}</translation>
+<translation id="42981349822642051">விரி</translation>
+<translation id="4302965934281694568">Chou3 (என்வலப்)</translation>
<translation id="4305817255990598646">மாறு</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">தடு (இயல்பு)</translation>
+<translation id="4318566738941496689">உங்கள் சாதனப் பெயர் மற்றும் நெட்வொர்க் முகவரி</translation>
<translation id="4325863107915753736">கட்டுரையைக் கண்டறிய முடியவில்லை</translation>
<translation id="4326324639298822553">காலாவதித் தேதியைச் சரிபார்த்து, மீண்டும் முயலவும்</translation>
<translation id="4331708818696583467">பாதுகாப்பற்றது</translation>
<translation id="4340982228985273705">இந்தக் கணினியானது நிறுவனத்தால் நிர்வகிக்கப்படுவதாகக் கண்டறியப்படவில்லை. எனவே, கொள்கையால் Chrome இணைய அங்காடியில் ஹோஸ்ட் செய்யப்படும் நீட்டிப்புகளை மட்டும் தானாக நிறுவ முடியும். "<ph name="CWS_UPDATE_URL" />" என்பது Chrome இணைய அங்காடிப் புதுப்பிப்பு URL ஆகும்.</translation>
<translation id="4346197816712207223">ஏற்கப்படும் கிரெடிட் கார்டுகள்</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">இந்தத் தளத்தில் உள்ள தீங்கிழைப்பவர்கள், உங்கள் தகவலைத் (எடுத்துக்காட்டு: படங்கள், கடவுச்சொற்கள், செய்திகள் மற்றும் கிரெடிட் கார்டுகள்) திருடக்கூடிய அல்லது நீக்கக்கூடிய தீங்கிழைக்கும் நிரல்களை உங்கள் கணினியில் நிறுவ முயலலாம்.</translation>
<translation id="4358461427845829800">கட்டண முறைகளை நிர்வகி...</translation>
+<translation id="4367563149485757821">Number-12 (என்வலப்)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">எதிர்பார்த்த <ph name="VALUE_TYPE" /> மதிப்பு.</translation>
<translation id="4377125064752653719"><ph name="DOMAIN" /> ஐ அடைய முயற்சி செய்தீர்கள். ஆனால் சேவையகம் வழங்கிய சான்றிதழானது அதன் வழங்குநரால் நிராகரிக்கப்பட்டது. அதாவது, சேவையகம் வழங்கிய பாதுகாப்பு நம்பிக்கைச்சான்றுகளை நிச்சயமாக எக்காரணத்தைக்கொண்டும் நம்பக்கூடாது. போலியான ஒன்றுடன் நீங்கள் தகவல் பரிமாற்றம் செய்துகொண்டிருக்கக்கூடும்.</translation>
<translation id="4378154925671717803">மொபைல்</translation>
<translation id="4406896451731180161">தேடல் முடிவுகள்</translation>
-<translation id="4406972042435603828">சக்திவாய்ந்த திறன்களுள்ள நீட்டிப்புகளை உங்கள் நிர்வாகிகள் நிறுவியுள்ளனர்.</translation>
<translation id="4408413947728134509">குக்கீகள் (<ph name="NUM_COOKIES" />)</translation>
<translation id="4415426530740016218">பிக்அப் முகவரி</translation>
<translation id="4424024547088906515">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழை Chrome நம்பவில்லை. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="443121186588148776">சீரியல் போர்ட்</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> உங்கள் உள்நுழைவுச் சான்றிதழை ஏற்கவில்லை அல்லது சான்றிதழ் வழங்கப்படாமல் இருக்கக்கூடும்.</translation>
<translation id="4434045419905280838">பாப் அப்கள் &amp; திசைதிருப்புதல்கள்</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">ப்ராக்ஸி பயன்பாடு முடக்கப்பட்டுள்ளது. ஆனால் வெளிப்படையான ப்ராக்ஸி உள்ளமைவு குறிப்பிடப்பட்டுள்ளது.</translation>
<translation id="445100540951337728">ஏற்கப்படும் டெபிட் கார்டுகள்</translation>
+<translation id="4466881336512663640">படிவத்தில் செய்த மாற்றங்கள் சேமிக்கப்படாது. நிச்சயமாகத் தொடர விரும்புகிறீர்களா?</translation>
<translation id="4482953324121162758">இந்தத் தளம் மொழிபெயர்க்கப்படாது.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">தவறான URL. URL ஒரு நிலையான வகையில் இருக்க வேண்டும், எ.கா http://example.com or https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">சரிபார்ப்புப் பிழை: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">கணினி நிர்வாகியைத் தொடர்புகொள்ளுதல்</translation>
<translation id="450710068430902550">நிர்வாகியுடன் பகிர்பவை</translation>
+<translation id="4510487217173779431">Chou4 (என்வலப்)</translation>
<translation id="4515275063822566619">கார்டுகளும் முகவரிகளும் Chrome இலிருந்தும் <ph name="ACCOUNT_EMAIL" /> எனும் உங்கள் Google கணக்கிலிருந்தும் பெறப்பட்டவையாகும். <ph name="BEGIN_LINK" />அமைப்புகளில்<ph name="END_LINK" /> அவற்றை நிர்வகிக்கலாம்.</translation>
+<translation id="4517607026994743406">Comm-10 (என்வலப்)</translation>
<translation id="4522570452068850558">விவரங்கள்</translation>
<translation id="4524805452350978254">கார்டுகளை நிர்வகி</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ஃப்ளாஷ்</translation>
<translation id="4558551763791394412">நீட்டிப்புகளை முடக்கவும்.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">டெலிவரி</translation>
+<translation id="4579056131138995126">Personal (என்வலப்)</translation>
<translation id="4582204425268416675">கார்டை அகற்றும்</translation>
<translation id="4587425331216688090">Chrome இலிருந்து முகவரியை அகற்றவா?</translation>
<translation id="4592951414987517459">நவீன சைபர் சூட்டைப் பயன்படுத்தி <ph name="DOMAIN" /> உடனான உங்கள் இணைப்பு என்க்ரிப்ட் செய்யப்பட்டது.</translation>
<translation id="4594403342090139922">&amp;நீக்குதலைச் செயல்தவிர்</translation>
<translation id="4597348597567598915">அளவு: 8</translation>
+<translation id="4600854749408232102">C6/C5 (என்வலப்)</translation>
<translation id="4646534391647090355">அங்கே செல்</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழில் பிழைகள் உள்ளன. இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="467809019005607715">Google ஸ்லைடு</translation>
<translation id="4690462567478992370">தவறான சான்றிதழைப் பயன்படுத்துவதை நிறுத்து</translation>
+<translation id="4691835149146451662">Architecture-A (என்வலப்)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">உங்கள் இணைப்பில் தடங்கல் ஏற்பட்டது</translation>
<translation id="471880041731876836">இந்தத் தளத்தைப் பார்ப்பதற்கான அனுமதி உங்களிடம் இல்லை</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows நெட்வொர்க் டயக்னாஸ்டிக்ஸ் கருவியை இயக்கவும்<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">கொள்கைகளை மீண்டும் ஏற்று</translation>
<translation id="4728558894243024398">ப்ளாட்ஃபார்ம்</translation>
+<translation id="4731967714531604179">Prc2 (என்வலப்)</translation>
<translation id="4736825316280949806">Chromiumஐ மீண்டும் தொடங்கவும்</translation>
<translation id="473775607612524610">புதுப்பி</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> தேடல் பரிந்துரை</translation>
<translation id="4742407542027196863">கடவுச்சொற்களை நிர்வகி…</translation>
<translation id="4744603770635761495">இயக்கநிரல் பாதை</translation>
+<translation id="4746351372139058112">செய்திகள்</translation>
<translation id="4750917950439032686">உங்கள் தகவலை (எடுத்துக்காட்டு: கடவுச்சொற்கள் அல்லது கிரெடிட் கார்டு எண்கள்) இந்தத் தளத்திற்கு அனுப்பும் போது, தனிப்பட்டதாக இருக்கும்.</translation>
<translation id="4756388243121344051">&amp;வரலாறு</translation>
<translation id="4758311279753947758">தொடர்புத் தகவலைச் சேர்</translation>
@@ -605,9 +689,9 @@
<translation id="4764776831041365478"><ph name="URL" /> இல் உள்ள வலைப்பக்கமானது தற்காலிகமாக இயங்காமல் இருக்கலாம் அல்லது அது ஒரு புதிய வலை முகவரிக்கு நிரந்தரமாக நகர்த்தப்பட்டிருக்கலாம்.</translation>
<translation id="4771973620359291008">அறியப்படாத பிழை ஏற்பட்டுள்ளது.</translation>
<translation id="4785689107224900852">இந்தத் தாவலுக்கு மாற்றும்</translation>
-<translation id="4792143361752574037">அமர்வுக் கோப்புகளை அணுகும் போது சிக்கல் ஏற்பட்டது. வட்டில் சேமிப்பது தற்போது முடக்கப்பட்டுள்ளது. மீண்டும் முயல, பக்கத்தை மீண்டும் ஏற்றவும்.</translation>
<translation id="4798078619018708837">கார்டு விவரங்களைப் புதுப்பிக்க, <ph name="CREDIT_CARD" /> இன் காலாவதித் தேதியையும் CVC எண்ணையும் உள்ளிடவும். நீங்கள் உறுதிப்படுத்திய பின்னர், உங்கள் Google கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation>
<translation id="4800132727771399293">காலாவதியாகும் நேரத்தையும், CVCஐயும் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்</translation>
+<translation id="480334179571489655">அசல் கொள்கை பிழை</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>
@@ -622,7 +706,6 @@
<translation id="4881695831933465202">திற</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>
@@ -631,15 +714,15 @@
<translation id="4943872375798546930">முடிவுகள் இல்லை</translation>
<translation id="4950898438188848926"><ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> தாவலைத் திறக்க, ‘தாவல்’ மாற்ற பட்டனைத் தட்டி, ‘எண்டர்’ பட்டனை அழுத்தவும்</translation>
<translation id="495170559598752135">செயல்கள்</translation>
-<translation id="495832697253704892">நீட்டிப்பு குறித்து அறிக்கையளித்தல்</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">பட்டியலை விரி</translation>
<translation id="4974590756084640048">எச்சரிக்கைகளை மீண்டும் இயக்கு</translation>
+<translation id="4984339528288761049">Prc5 (என்வலப்)</translation>
<translation id="4989163558385430922">எல்லாம் காட்டு</translation>
<translation id="4989809363548539747">இந்தச் செருகுநிரல் ஆதரிக்கப்படவில்லை</translation>
-<translation id="4996230189582812866">அறிக்கையளித்தல்</translation>
<translation id="5002932099480077015">இயக்கப்பட்டால், விரைவாகப் படிவத்தை நிரப்ப உங்கள் கார்டின் நகலை இச்சாதனத்தில் Chrome சேமித்து வைக்கும்.</translation>
-<translation id="5014174725590676422">’Chromeமில் Google அசிஸ்டண்ட்’ முதன்மைத் திரை காண்பிக்கப்படுகிறது</translation>
<translation id="5015510746216210676">சாதனப் பெயர்:</translation>
+<translation id="5017554619425969104">நீங்கள் நகலெடுத்த உரை</translation>
<translation id="5018422839182700155">பக்கத்தைத் திறக்க முடியவில்லை</translation>
<translation id="5019198164206649151">தவறான நிலையில் மீட்பு சேமிப்பு உள்ளது</translation>
<translation id="5023310440958281426">உங்கள் நிர்வாகியின் கொள்கைகளைச் சரிபார்க்கவும்</translation>
@@ -649,35 +732,51 @@
<translation id="5034369478845443529">அகச் சூழல் <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">அனுமதி</translation>
<translation id="5040262127954254034">தனியுரிமை</translation>
+<translation id="5043480802608081735">நீங்கள் நகலெடுத்த இணைப்பு</translation>
<translation id="5045550434625856497">தவறான கடவுச்சொல்</translation>
<translation id="5056549851600133418">உங்களுக்கான செய்திக் கட்டுரைகள்</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ப்ராக்ஸி முகவரியைச் சரிபார்த்தல்<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM உபயோகம் போன்ற சாதனப் புள்ளிவிவரங்கள்</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">உங்கள் சாதனத்தை <ph name="ENROLLMENT_DOMAIN" /> நிர்வகிக்கிறது, உங்கள் கணக்கை <ph name="ACCOUNT_DOMAIN" /> நிர்வகிக்கிறது. உங்கள் சாதனத்தையும் கணக்கையும் உங்கள் நிர்வாகிகள் தொலைநிலையிலிருந்து உள்ளமைக்க முடியும்.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-பிட்)</translation>
-<translation id="5128122789703661928">இந்தப் பெயரைக் கொண்ட அமர்வானது நீக்குவதற்குத் தகுதியானதல்ல.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">முகவரிகளை நிர்வகி...</translation>
+<translation id="5138227688689900538">குறைவாகக் காட்டு</translation>
<translation id="5141240743006678641">ஒத்திசைக்கப்பட்ட கடவுச்சொற்களை உங்கள் Google அனுமதிச் சான்றுகள் மூலம் என்க்ரிப்ட் செய்யும்</translation>
<translation id="5145883236150621069">கொள்கைப் பதிலில் பிழைக் குறியீடு உள்ளது</translation>
+<translation id="515292512908731282">C4 (என்வலப்)</translation>
<translation id="5159010409087891077">புதிய மறைநிலைச் சாளரத்தில் பக்கத்தைத் திறக்கவும் (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> இன் CVC எண்ணை உள்ளிடவும். நீங்கள் உறுதிப்படுத்திய பின்னர், உங்கள் Google கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation>
<translation id="5169827969064885044">உங்கள் நிறுவனத்தின் கணக்கிற்கான அணுகலை நீங்கள் இழக்கக்கூடும் அல்லது அடையாளத் திருட்டை எதிர்கொள்ளக்கூடும். இப்போதே உங்கள் கடவுச்சொல்லை மாற்றும்படி Chrome பரிந்துரைக்கிறது.</translation>
<translation id="5171045022955879922">தேடுக அல்லது URLலை உள்ளிடுக</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">இயந்திரம்</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> இல் இல்லையா? இந்தப் பிழையை தெரிவிக்கவும்</translation>
<translation id="5190835502935405962">புக்மார்க் பட்டி</translation>
-<translation id="5200263511887412697">பயனர்கள் சமீபத்தில் உள்நுழைந்த சாதனங்களின் அறிக்கைப் பட்டியல்</translation>
+<translation id="519422657042045905">விரிவுரை இல்லை</translation>
<translation id="5201306358585911203">இந்தப் பக்கத்திலுள்ள உட்பொதிக்கப்பட்ட பக்கம் தெரிவிப்பது:</translation>
<translation id="5205222826937269299">பெயர் தேவை</translation>
<translation id="5215116848420601511">Google Payவைப் பயன்படுத்தும் கட்டண முறைகளும் முகவரிகளும்</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">மின்னஞ்சல் தேவை</translation>
<translation id="5230733896359313003">ஷிப்பிங் முகவரி</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"நெட்வொர்க்குடன் இணைக்கவும்"</translation>
<translation id="5251803541071282808">கிளவுடு</translation>
+<translation id="5252000469029418751">C7 (என்வலப்)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">நெட்வொர்க் முகவரிகள்</translation>
<translation id="5285570108065881030">சேமித்த எல்லாக் கடவுச்சொற்களையும் காட்டு</translation>
<translation id="5287240709317226393">குக்கீகளைக் காட்டும்</translation>
<translation id="5288108484102287882">கொள்கை மதிப்புகளின் சரிபார்ப்பு எச்சரிக்கைகளை எழுப்பியுள்ளது</translation>
@@ -689,7 +788,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> இல் <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">தொடர்புத் தகவலைத் தேர்வு செய்</translation>
<translation id="5327248766486351172">பெயர்</translation>
+<translation id="5329858041417644019">உங்கள் உலாவி நிர்வகிக்கப்படவில்லை</translation>
<translation id="5332219387342487447">ஷிப்பிங் முறை</translation>
+<translation id="5334013548165032829">விரிவான சிஸ்டம் பதிவுகள்</translation>
<translation id="5344579389779391559">இந்தப் பக்கம் உங்களிடமிருந்து கட்டணம் வசூலிக்கலாம்</translation>
<translation id="5355557959165512791"><ph name="SITE" /> தளத்தின் சான்றிதழ் ரத்துசெய்யப்பட்டதால், தற்போது அதைப் பார்க்க முடியாது. பொதுவாக நெட்வொர்க் பிழைகளும் பாதிப்புகளும் தற்காலிகமானவை என்பதால், இந்தப் பக்கம் பின்னர் சரியாகச் செயல்படக்கூடும்.</translation>
<translation id="536296301121032821">கொள்கை அமைப்புகளைச் சேமிப்பதில் தோல்வி</translation>
@@ -697,6 +798,7 @@
<translation id="5377026284221673050">"நேரம் பின்தங்கியுள்ளது" அல்லது "நேரம் கூடுதலாக அமைக்கப்பட்டுள்ளது" அல்லது "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">உங்கள் சாதனங்கள் அனைத்திலும் உங்கள் கார்டுகளைப் பயன்படுத்த, உள்நுழைந்து, ஒத்திசைவை இயக்கவும்.</translation>
<translation id="5386426401304769735">இந்தச் சான்றிதழ் சங்கிலியில், SHA-1ஐப் பயன்படுத்தி கையொப்பமிடப்பட்ட சான்றிதழ் உள்ளது.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584"><ph name="DOMAIN" /> டொமைனை, சேவையகம் உறுதிப்படுத்தவில்லை; அதற்கான காரணங்கள்: இதன் பாதுகாப்புச் சான்றிதழ் தற்போது செல்லுபடியானதல்ல. இது தவறான உள்ளமைவினால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
<translation id="5421136146218899937">உலாவல் தரவை அழி...</translation>
<translation id="5430298929874300616">புத்தகக்குறியை அகற்று</translation>
@@ -707,6 +809,7 @@
<translation id="5457113250005438886">தவறானது</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;மீண்டும் திருத்து</translation>
+<translation id="5478437291406423475">B6/C4 (என்வலப்)</translation>
<translation id="5481076368049295676">உங்கள் தகவலைத் திருடும் அல்லது நீக்கும் ஆபத்தான மென்பொருளை உங்கள் சாதனத்தில் இந்த உள்ளடக்கம் நிறுவ முயலலாம். <ph name="BEGIN_LINK" />பரவாயில்லை, காட்டு<ph name="END_LINK" /></translation>
<translation id="54817484435770891">சரியான முகவரியைச் சேர்க்கவும்</translation>
<translation id="5490432419156082418">முகவரிகள் மற்றும் பல</translation>
@@ -714,10 +817,12 @@
<ph name="LINE_BREAK" />
உங்கள் முறைமை நிர்வாகியைத் தொடர்புகொள்ள முயலவும்.</translation>
<translation id="549333378215107354">அளவு: 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">நிர்வகிக்கப்படும் புக்மார்க்குகள்</translation>
<translation id="5510766032865166053">அது நகர்த்தப்பட்டிருக்கலாம் அல்லது நீக்கப்பட்டிருக்கலாம்.</translation>
<translation id="5523118979700054094">கொள்கைப் பெயர்</translation>
<translation id="552553974213252141">உரையானது சரியான முறையில் பிரித்தெடுக்கப்பட்டதா?</translation>
+<translation id="553484882784876924">Prc6 (என்வலப்)</translation>
<translation id="5540224163453853">கோரப்பட்ட கட்டுரையைக் கண்டுபிடிக்க முடியவில்லை.</translation>
<translation id="5541546772353173584">மின்னஞ்சலைச் சேர்க்கவும்</translation>
<translation id="5545756402275714221">உங்களுக்கான செய்திக் கட்டுரைகள்</translation>
@@ -732,15 +837,21 @@
<translation id="5595485650161345191">முகவரியைத் திருத்து</translation>
<translation id="5598944008576757369">கட்டண முறையைத் தேர்வு செய்</translation>
<translation id="560412284261940334">நிர்வாகம் ஆதரிக்கவில்லை</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">இணைப்பைச் சரிபார்த்தல்</translation>
<translation id="5610807607761827392"><ph name="BEGIN_LINK" />அமைப்புகளில்<ph name="END_LINK" /> கார்டுகளையும் முகவரிகளையும் நிர்வகிக்கலாம்.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> உங்களைப் பலமுறை திசைதிருப்பம் செய்தது.</translation>
<translation id="5629630648637658800">கொள்கை அமைப்புகளை ஏற்றுவதில் தோல்வி</translation>
<translation id="5631439013527180824">தவறான சாதன நிர்வாக டோக்கன்</translation>
+<translation id="5632627355679805402"><ph name="TIME" /> வரை உங்கள் <ph name="BEGIN_LINK" />Google கடவுச்சொல்<ph name="END_LINK" /> மூலம் உங்கள் தரவு என்கிரிப்ட் செய்யப்பட்டது. ஒத்திசைவைத் தொடங்க, அதை உள்ளிடவும்.</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="563324245173044180">ஏமாற்றத்தக்க உள்ளடக்கம் தடுக்கப்பட்டது.</translation>
<translation id="5659593005791499971">மின்னஞ்சல்</translation>
+<translation id="5663614846592581799">9x11 (என்வலப்)</translation>
+<translation id="5663955426505430495">கூடுதல் செயல்பாடுகளுக்காக இந்தச் சாதனத்தின் நிர்வாகி சில நீட்டிப்புகளை நிறுவியுள்ளார். உங்கள் தரவில் சிலவற்றை இந்த நீட்டிப்புகள் அணுகும்.</translation>
<translation id="5675650730144413517">இந்தப் பக்கம் செயல்படவில்லை</translation>
+<translation id="5684874026226664614">அச்சச்சோ. இந்தப் பக்கத்தை மொழிபெயர்க்க முடியாது.</translation>
<translation id="5685654322157854305">ஷிப்பிங் முகவரியைச் சேர்</translation>
<translation id="5689199277474810259">JSONக்கு ஏற்று</translation>
<translation id="5689516760719285838">இருப்பிடம்</translation>
@@ -749,38 +860,39 @@
<translation id="5710435578057952990">இந்த தளத்தின் அடையாளம் சரிபார்க்கப்படவில்லை.</translation>
<translation id="5719499550583120431">ப்ரீபெய்டு கார்டுகள் ஏற்கப்படுகின்றன.</translation>
<translation id="5720705177508910913">நடப்புப் பயனர்</translation>
+<translation id="5728056243719941842">C5 (என்வலப்)</translation>
<translation id="5730040223043577876">பிற தளங்களில் உங்கள் கடவுச்சொல்லை மீண்டும் பயன்படுத்தினால், அதை மீட்டமைக்கும்படி Chrome பரிந்துரைக்கிறது.</translation>
<translation id="5732392974455271431">உங்களுக்காக, தளத்தின் தடுப்பை உங்கள் பெற்றோர் நீக்க முடியும்</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{உங்கள் Google கணக்கில் கார்டைச் சேமியுங்கள்}other{உங்கள் Google கணக்கில் கார்டுகளைச் சேமியுங்கள்}}</translation>
<translation id="5763042198335101085">சரியான மின்னஞ்சல் முகவரியை உள்ளிடவும்</translation>
<translation id="5765072501007116331">டெலிவரி முறைகளையும் தேவைகளையும் பார்க்க, முகவரியைத் தேர்ந்தெடுக்கவும்</translation>
-<translation id="5770114862687765385">கோப்பு சிதைந்துள்ளது போல் தெரிகிறது. அமர்வை மீட்டமைக்க, 'மீட்டமை' பொத்தானைக் கிளிக் செய்யவும்.</translation>
<translation id="5778550464785688721">MIDI சாதனங்கள் முழுக்கட்டுப்பாடு</translation>
<translation id="578305955206182703">ஆம்பர்</translation>
<translation id="57838592816432529">ஒலியடக்கு</translation>
<translation id="5784606427469807560">கார்டை உறுதிசெய்வதில் சிக்கல் ஏற்பட்டது. இணைய இணைப்பைச் சரிபார்த்து, மீண்டும் முயலவும்.</translation>
<translation id="5785756445106461925">மேலும், பாதுகாப்பற்ற பிற ஆதாரங்கள் இந்தப் பக்கத்தில் உள்ளன. இந்த ஆதாரங்களை ட்ரான்ஸிட்டில் இருக்கும்போதும் பிறர் பார்வையிடலாம், மேலும் பக்கத்தின் தோற்றத்தை மாற்ற, தீங்கிழைப்பவர் அதை மாற்றியமைக்கலாம்.</translation>
<translation id="5786044859038896871">கார்டு தகவலை நிரப்ப விரும்புகிறீர்களா?</translation>
+<translation id="5798290721819630480">மாற்றங்களை நிராகரிக்கவா?</translation>
<translation id="5798683403665926540">Chrome அமைப்புகளில் முகப்புப் பக்கத்தை மாற்றவும்</translation>
<translation id="5803412860119678065"><ph name="CARD_DETAIL" />ஐ நிரப்ப விரும்புகிறீர்களா?</translation>
<translation id="5804241973901381774">அனுமதிகள்</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" />க்கான உங்கள் இணைப்பு, நடைமுறையில் இல்லாத சைபர் சூட்டைப் பயன்படுத்தி என்க்ரிப்ட் செய்யப்பட்டது.</translation>
<translation id="5813119285467412249">&amp;சேர்த்தலை மீண்டும் செய்</translation>
<translation id="5838278095973806738">தீங்கிழைப்பவர்கள் திருடிவிடலாம் என்பதால், இந்தத் தளத்தில் முக்கியத் தகவலை (எடுத்துக்காட்டு: கடவுச்சொற்கள் அல்லது கிரெடிட் கார்டுகள்) உள்ளிட வேண்டாம்.</translation>
+<translation id="5860033963881614850">ஆஃப்</translation>
<translation id="5863847714970149516">அடுத்த பக்கத்தில் உங்களிடமிருந்து கட்டணம் வசூலிக்கப்படலாம்</translation>
<translation id="5866257070973731571">மொபைல் எண்ணைச் சேர்க்கவும்</translation>
<translation id="5869405914158311789">இந்தத் தளத்தை அணுக முடியவில்லை</translation>
<translation id="5869522115854928033">சேமிக்கப்பட்ட கடவுச்சொற்கள்</translation>
<translation id="5887400589839399685">கார்டு சேமிக்கப்பட்டது</translation>
-<translation id="5893718151540690985">வகைகள் மற்றும் வன்பொருள் முகவரிகளுடன் கூடிய நெட்வொர்க் இடைமுகங்களின் பட்டியலை அறிக்கையளிக்கும்</translation>
<translation id="5893752035575986141">கிரெடிட் கார்டுகள் ஏற்கப்படுகின்றன.</translation>
<translation id="5901630391730855834">மஞ்சள்</translation>
<translation id="5908541034548427511"><ph name="TYPE_1" /> (ஒத்திசைக்கப்பட்டது)</translation>
-<translation id="5920262536204764679">{NUM_COOKIES,plural, =1{ஒரு குக்கீ பயன்படுத்தப்படுகிறது}other{# குக்கீகள் பயன்படுத்தப்படுகின்றன}}</translation>
+<translation id="5916664084637901428">இயக்கு</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google கணக்கில் கார்டைச் சேமிக்கவா?</translation>
<translation id="5922853866070715753">கிட்டத்தட்ட முடிந்துவிட்டது</translation>
<translation id="5932224571077948991">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களை தளம் காண்பிக்கிறது</translation>
-<translation id="5939518447894949180">மீட்டமை</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" />ஐத் திறக்கிறது…</translation>
<translation id="5951495562196540101">நுகர்வோர் கணக்கில் பதிவுசெய்ய முடியவில்லை (தொகுக்கப்பட்ட உரிமம் உள்ளது).</translation>
<translation id="5967592137238574583">தொடர்புத் தகவலைத் திருத்தவும்</translation>
@@ -788,6 +900,7 @@
<translation id="5975083100439434680">சிறிதாக்கு</translation>
<translation id="5977489021191000276">உங்கள் சாதனம் நிர்வாகியால் நிர்வகிக்கப்படவில்லை.</translation>
<translation id="5977976211062815271">இந்தச் சாதனத்தில்</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">பேமெண்ட் பயன்பாட்டைத் திறக்க முடியவில்லை</translation>
<translation id="5989320800837274978">ப்ராக்ஸி சேவையகம் சரிசெய்யப்படவும் இல்லை .pac ஸ்கிரிப்ட் URL குறிப்பிடப்படவுமில்லை.</translation>
<translation id="5990559369517809815">சேவையகத்திற்கான கோரிக்கைகள் நீட்டிப்பினால் தடுக்கப்பட்டது.</translation>
@@ -798,8 +911,8 @@
<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="6033927989869462158">CPU/RAM உபயோகம் போன்ற வன்பொருள் புள்ளிவிவரங்களை அறிக்கையளிக்கும்</translation>
<translation id="6034000775414344507">வெளிர் சாம்பல்</translation>
+<translation id="6034283069659657473">10x14 (என்வலப்)</translation>
<translation id="6039846035001940113">சிக்கல் தொடர்ந்தால், தள உரிமையாளரைத் தொடர்புகொள்ளவும்.</translation>
<translation id="6040143037577758943">மூடு</translation>
<translation id="6044573915096792553">அளவு: 12</translation>
@@ -808,10 +921,10 @@
<translation id="6051221802930200923"><ph name="SITE" /> தளமானது சர்டிஃபிகேட் பின்னிங்கைப் பயன்படுத்துவதால், தற்போது அதைப் பார்க்க முடியாது. பொதுவாக நெட்வொர்க் பிழைகளும் பாதிப்புகளும் தற்காலிகமானவை என்பதால், இந்தப் பக்கம் பின்னர் சரியாகச் செயல்படக்கூடும்.</translation>
<translation id="6058977677006700226">உங்கள் சாதனங்கள் அனைத்திலும் உங்கள் கார்டுகளைப் பயன்படுத்தவா?</translation>
<translation id="6059925163896151826">USB சாதனங்கள்</translation>
-<translation id="6071091556643036997">கொள்கை வகை செல்லுபடியாகவில்லை.</translation>
<translation id="6080696365213338172">நிர்வாகி வழங்கிய சான்றிதழைப் பயன்படுத்தி உள்ளடக்கத்தை அணுகியுள்ளீர்கள். <ph name="DOMAIN" /> க்கு நீங்கள் வழங்கிய தரவானது உங்கள் நிர்வாகியால் இடைமறிக்கப்படலாம்.</translation>
<translation id="6094273045989040137">விரிவுரைப் பயன்முறை</translation>
<translation id="610911394827799129"><ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> என்ற முகவரியில், உங்கள் Google கணக்கிற்கான பிற வகை உலாவல் வரலாறும் இருக்கக்கூடும்</translation>
+<translation id="6132597952260690497">நிறுவப்பட்டுள்ள நீட்டிப்புகளையும் செருகுநிரல்களையும் குறித்த தகவல்கள்</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ஏதுமில்லை}=1{1 கடவுச்சொல் (ஒத்திசைத்தது)}other{# கடவுச்சொற்கள் (ஒத்திசைத்தவை)}}</translation>
<translation id="6146055958333702838">கேபிள்களைச் சரிபார்த்து, நீங்கள் பயன்படுத்தக்கூடிய ரூட்டர்கள், மோடம்கள் அல்லது பிற நெட்வொர்க் சாதனங்களை மறுபடி தொடங்கவும்.</translation>
<translation id="614940544461990577">இவற்றைச் செய்து பார்க்கவும்:</translation>
@@ -845,15 +958,21 @@
<translation id="6337133576188860026"><ph name="SIZE" />க்கும் குறைவான அளவைக் காலியாக்கும். நீங்கள் அடுத்த முறை பார்வையிடும் போது, சில தளங்கள் மிகவும் மெதுவாக ஏற்றப்படலாம்.</translation>
<translation id="6337534724793800597">பெயரின்படி கொள்கைகளை வடி</translation>
<translation id="6358450015545214790">இவற்றின் பொருள் என்ன?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">கட்டணங்கள் விதிக்கப்படச் சாத்தியமுள்ளது.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{மேலும் 1 பரிந்துரை}other{மேலும் # பரிந்துரைகள்}}</translation>
<translation id="6387754724289022810">அடுத்த முறை விரைவாகப் பணம் அனுப்ப, உங்கள் கார்டையும் பில்லிங் முகவரியையும் Google கணக்கிலும் இந்தச் சாதனத்திலும் சேமிக்கவும்.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">புக்மார்க்களைத் திருத்து</translation>
+<translation id="6406765186087300643">C0 (என்வலப்)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" />க்கான காலாவதித் தேதியையும் CVC எண்ணையும் உள்ளிடவும்</translation>
<translation id="6414888972213066896">இந்தத் தளத்தைப் பார்வையிடலாமா என, நீங்கள் பெற்றோரிடம் கேட்டுள்ளீர்கள்</translation>
<translation id="6417515091412812850">சான்றிதழ் திரும்பப்பெறப்பட்டதா என்று சோதிக்க முடியவில்லை.</translation>
<translation id="6433490469411711332">தொடர்புத் தகவலை மாற்று</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> இணைக்க மறுத்தது.</translation>
+<translation id="6434309073475700221">நிராகரி</translation>
+<translation id="6446163441502663861">Kahu (என்வலப்)</translation>
<translation id="6446608382365791566">மேலும் தகவலைச் சேர்க்கவும்</translation>
<translation id="6447842834002726250">குக்கீகள்</translation>
<translation id="6451458296329894277">படிவ மறுசமர்ப்பிப்பை உறுதிசெய்க</translation>
@@ -866,11 +985,17 @@
<translation id="6508722015517270189">Chromeஐ மீண்டும் தொடங்கவும்</translation>
<translation id="6529602333819889595">&amp;நீக்குதலை மீண்டும் செய்</translation>
<translation id="6534179046333460208">இயல்நிலை இணையப் பரிந்துரைகள்</translation>
+<translation id="6556866813142980365">மீண்டும் செய்</translation>
<translation id="6563469144985748109">இன்னும் உங்கள் நிர்வாகி அனுமதிக்கவில்லை</translation>
<translation id="6569060085658103619">நீட்டிப்புப் பக்கத்தைப் பார்க்கிறீர்கள்</translation>
+<translation id="6578796323535178455">C2 (என்வலப்)</translation>
<translation id="6579990219486187401">வெளிர் பிங்க் நிறம்</translation>
+<translation id="6583674473685352014">B6 (என்வலப்)</translation>
+<translation id="6587923378399804057">நீங்கள் நகலெடுத்த இணைப்பு</translation>
+<translation id="6591833882275308647">உங்கள் <ph name="DEVICE_TYPE" /> சாதனம் நிர்வகிக்கப்படவில்லை</translation>
<translation id="6596325263575161958">என்கோடர் விருப்பங்கள்</translation>
<translation id="6604181099783169992">நகர்வு அல்லது ஒளி உணர்விகள்</translation>
+<translation id="6609880536175561541">Prc7 (என்வலப்)</translation>
<translation id="6624427990725312378">தொடர்புத் தகவல்</translation>
<translation id="6626291197371920147">சரியான கார்டு எண்ணைச் சேர்க்கவும்</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> தேடல்</translation>
@@ -879,6 +1004,7 @@
<translation id="6644283850729428850">இந்தக் கொள்கை தவிர்க்கப்பட்டது.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{எதுவுமில்லை}=1{1 தளத்திலிருந்து (உங்கள் Google கணக்கிலிருந்து வெளியேறமாட்டீர்கள்)}other{# தளங்களிலிருந்து (உங்கள் Google கணக்கிலிருந்து வெளியேறமாட்டீர்கள்)}}</translation>
<translation id="6657585470893396449">கடவுச்சொல்</translation>
+<translation id="6670613747977017428">பாதுகாப்பான நிலைக்குத் திரும்பு.</translation>
<translation id="6671697161687535275">Chromium இலிருந்து படிவப் பரிந்துரையை அகற்றவா?</translation>
<translation id="6685834062052613830">வெளியேறி, அமைப்பை முடிக்கவும்</translation>
<translation id="6710213216561001401">முந்தையது</translation>
@@ -886,12 +1012,15 @@
<translation id="671076103358959139">பதிவு டோக்கன்:</translation>
<translation id="6711464428925977395">ப்ராக்ஸி சர்வரில் ஏதோ தவறு உள்ளது அல்லது முகவரி தவறாக உள்ளது.</translation>
<translation id="6723740634201835758">உங்கள் Google கணக்கில்</translation>
+<translation id="6738516213925468394"><ph name="TIME" />க்கு உங்கள் தரவு உங்கள் <ph name="BEGIN_LINK" />ஒத்திசைவுக் கடவுச்சொற்றொடரைக்<ph name="END_LINK" /> கொண்டு என்க்ரிப்ட் செய்யப்பட்டது. ஒத்திசைவைத் தொடங்க, அதை உள்ளிடவும்.</translation>
<translation id="674375294223700098">தெரியாத சேவையகச் சான்றிதழ் பிழை.</translation>
<translation id="6744009308914054259">இணைப்புக்காகக் காத்திருக்கும்போது ​​ஆஃப்லைன் கட்டுரைகளைப் படிக்க, ‘பதிவிறக்கங்கள்’ என்பதைப் பார்க்கவும்.</translation>
<translation id="6753269504797312559">கொள்கை மதிப்பு</translation>
<translation id="6757797048963528358">உங்கள் சாதனம் உறக்கநிலைக்குச் சென்றது.</translation>
+<translation id="6768213884286397650">Hagaki (போஸ்ட்கார்டு)</translation>
<translation id="6778737459546443941">இன்னும் உங்கள் பெற்றோர் அனுமதிக்கவில்லை</translation>
<translation id="67862343314499040">ஊதா</translation>
+<translation id="6786747875388722282">நீட்டிப்புகள்</translation>
<translation id="679355240208270552">கொள்கையின்படி இயல்புநிலைத் தேடல் முடக்கப்பட்டுள்ளதால் புறக்கணிக்கப்பட்டது.</translation>
<translation id="681021252041861472">அவசியம்</translation>
<translation id="6810899417690483278">தனிப்பயனாக்கல் ஐடி</translation>
@@ -924,10 +1053,12 @@
<translation id="6965978654500191972">சாதனம்</translation>
<translation id="6970216967273061347">மாவட்டம்</translation>
<translation id="6973656660372572881">நிலையான ப்ராக்ஸி சேவையகங்களும் .pac ஸ்கிரிப்ட் URL ஆகிய இரண்டும் குறிப்பிடப்பட்டுள்ளது.</translation>
+<translation id="6973932557599545801">மன்னிக்கவும், என்னால் உதவ இயலவில்லை. நீங்களே செய்யுங்கள்.</translation>
<translation id="6979158407327259162">Google இயக்ககம்</translation>
<translation id="6979440798594660689">முடக்கு (இயல்பு)</translation>
<translation id="6984479912851154518">மூன்றாம் தரப்பு ஆப்ஸின் மூலம் பணத்தைச் செலுத்த, மறைநிலையிலிருந்து வெளியேறுகிறது. தொடரவா?</translation>
<translation id="6989763994942163495">மேம்பட்ட அமைப்புகளைக் காண்பி...</translation>
+<translation id="6993898126790112050">6x9 (என்வலப்)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> மொழியிலிருந்து எப்போதும் மொழிபெயர்</translation>
<translation id="7012363358306927923">சீனா UnionPay</translation>
<translation id="7016992613359344582">இந்தக் கட்டணங்கள் ஒருமுறை அல்லது தொடர்ந்து வசூலிக்கப்படலாம், அவை வெளிப்படையாகத் தெரிவிக்கப்படாமல் இருக்கலாம்.</translation>
@@ -943,28 +1074,36 @@
<translation id="7108338896283013870">மறை</translation>
<translation id="7108819624672055576">நீட்டிப்பு அனுமதித்தது</translation>
<translation id="7111012039238467737">(சரியானது)</translation>
+<translation id="7118618213916969306"><ph name="SHORT_URL" /> எனும் கிளிப்-போர்டு URLலைத் தேடும்</translation>
<translation id="7119414471315195487">பிற தாவல்கள் அல்லது நிரல்களை மூடவும்</translation>
<translation id="7129409597930077180">இந்த முகவரிக்கு அனுப்ப முடியாது. வேறு முகவரியைத் தேர்ந்தெடுக்கவும்.</translation>
<translation id="7135130955892390533">நிலையைக் காட்டு</translation>
<translation id="7138472120740807366">டெலிவரி முறை</translation>
<translation id="7139724024395191329">எமிரேட்</translation>
+<translation id="7152423860607593928">Number-14 (என்வலப்)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">லாவெண்டர் நிறம்</translation>
-<translation id="7158980942472052083">தவறான URL நிலையான திட்டமுள்ள ஒரு URL ஆக இருக்க வேண்டும்.</translation>
<translation id="717330890047184534">Gaia ஐடி:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">நீங்கள் செல்லும் <ph name="ORIGIN" /> சேவையகம், அதனுடன் தொடர்புடைய எல்லாக் கோரிக்கைகளுக்கும்
+ பாதுகாப்புக் கொள்கை பொருந்த வேண்டுமெனக் கோரிக்கை விடுத்துள்ளது. ஆனால், கொள்கையை
+ வழங்குவதற்குப் பதிலாக இது உலாவியை வேறு இடத்திற்குத் திசைதிருப்பியுள்ளது. இதனால் <ph name="SITE" /> க்கான உங்கள் கோரிக்கையை நிறைவுசெய்ய முடியாத வகையில்
+ உலாவி தடுக்கப்பட்டுள்ளது.</translation>
<translation id="7179323680825933600">கட்டண முறைகளைச் சேமித்துத் தானாக நிரப்பு</translation>
<translation id="7180611975245234373">புதுப்பி</translation>
<translation id="7182878459783632708">கொள்கைகள் அமைக்கப்படவில்லை</translation>
<translation id="7186367841673660872">இந்தப் பக்கமானது<ph name="ORIGINAL_LANGUAGE" />இலிருந்து<ph name="LANGUAGE_LANGUAGE" />க்கு மொழிபெயர்க்கப்பட்டது</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> அளவைக் காலியாக்கும். நீங்கள் அடுத்த முறை பார்வையிடும் போது, சில தளங்கள் மிகவும் மெதுவாக ஏற்றப்படலாம்.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">உங்கள் நிர்வாகி இவற்றைப் பார்க்க முடியும்:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> பாதுகாப்புத் தரநிலைகளுக்கு இணங்கவில்லை.</translation>
<translation id="721197778055552897">இந்த சிக்கல் குறித்து <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">இணைப்பு <ph name="SSL_VERSION" /> ஐப் பயன்படுத்துகிறது.</translation>
<translation id="7220786058474068424">செயல்படுத்துகிறது</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">தளத்தில் தீம்பொருள் உள்ளது</translation>
+<translation id="724766306220616965">எச்சரிக்கைகள், முரண்பாடு</translation>
<translation id="724975217298816891">கார்டு விவரங்களைப் புதுப்பிக்க, <ph name="CREDIT_CARD" /> இன் காலாவதி தேதியையும் CVC எண்ணையும் உள்ளிடவும். உறுதிசெய்த பின்னர், உங்கள் கார்டு விவரங்கள் இந்தத் தளத்திற்குப் பகிரப்படும்.</translation>
<translation id="7251437084390964440">நெட்வொர்க் உள்ளமைவானது ONC தரத்துடன் இணங்கவில்லை. உள்ளமைவின் பகுதிகள் இறக்குமதியாகாமல் போகக்கூடும்.
கூடுதல் விவரங்கள்:
@@ -977,11 +1116,14 @@
<translation id="7300012071106347854">அடர் நீலம்</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165"><ph name="CRASH_TIME" /> அன்று சிதைவு அறிக்கை பெறப்பட்டது (பயனர் பதிவேற்றக் கோரியுள்ளார், இன்னும் பதிவேற்றப்படவில்லை)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />பாதுகாப்பு உலாவல்<ph name="END_LINK" /> எச்சரிக்கைகள்</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">இணைப்பிற்கான உதவி</translation>
<translation id="7334320624316649418">&amp;மறுவரிசைப்படுத்தலை மீண்டும் செய்</translation>
<translation id="733923710415886693">சான்றிதழ் வெளிப்படைத்தன்மை மூலம் சேவையகத்தின் சான்றிதழ் வெளியிடப்படவில்லை.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">கட்டளை வரி</translation>
-<translation id="7365061714576910172">Linuxஐப் பதிவிறக்கு</translation>
<translation id="7372973238305370288">தேடல் முடிவு</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">வேண்டாம்</translation>
@@ -989,6 +1131,7 @@
<translation id="7381288752349550461">நிர்வகிக்கப்பட்ட அமர்வு மேலெழுதப்பட்டது</translation>
<translation id="7390545607259442187">கார்டை உறுதிசெய்</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">உங்கள் <ph name="DEVICE_NAME" /> சாதனம் நிர்வகிக்கப்படுகிறது</translation>
<translation id="7407424307057130981">&lt;p&gt;உங்கள் Windows கம்ப்யூட்டரில் Superfish மென்பொருள் இருந்தால் இந்தப் பிழையைப் பார்ப்பீர்கள்.&lt;/p&gt;
&lt;p&gt;மென்பொருளைத் தற்காலிகமாக முடக்கி இணையத்துடன் இணைவதற்கு, பின்வரும் படிகளைப் பின்பற்றவும். உங்களுக்கு நிர்வாகி முன்னுரிமைகள் தேவைப்படும்.&lt;/p&gt;
&lt;ol&gt;
@@ -999,7 +1142,7 @@
&lt;li&gt;&lt;strong&gt;பயன்படுத்து&lt;/strong&gt; என்பதைக் கிளிக் செய்து, &lt;strong&gt;சரி&lt;/strong&gt; என்பதைக் கிளிக் செய்யவும்
&lt;li&gt;உங்கள் கம்ப்யூட்டரிலிருந்து மென்பொருளை நிரந்தரமாக அகற்றுவது எப்படி என்பதை அறிய, &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome உதவி மையம்&lt;/a&gt; என்பதற்குச் செல்லவும்
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> நிர்வாகம்</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">கடவுச்சொற்களை நிர்வகி…</translation>
<translation id="7419106976560586862">சுயவிவரப் பாதை</translation>
<translation id="7437289804838430631">தொடர்புத் தகவலைச் சேர்</translation>
@@ -1008,22 +1151,24 @@
<translation id="7442725080345379071">வெளிர் ஆரஞ்சு</translation>
<translation id="7444046173054089907">இந்தத் தளம் தடுக்கப்பட்டது</translation>
<translation id="7445762425076701745">நீங்கள் இணைந்துள்ள சேவையகத்தின் அடையாளத்தை முழுமையாகச் சரிபார்க்க முடியவில்லை. உங்கள் நெட்வொர்க்கில் மட்டுமே செல்லுபடியாகும் பெயரைப் பயன்படுத்தி சேவையகத்துடன் இணைந்துள்ளீர்கள். இதன் உரிமையை ஒரு வெளிப்புற சான்றிதழ் மையம் உறுதிப்படுத்த முடியாது. சில சான்றிதழ் மையங்கள், இந்தப் பெயர்களுக்கும் சான்றிதழ்களை வழங்கும் என்பதால், நீங்கள் நினைத்த வலைப்பக்கத்துடனே இணைந்துள்ளீர்கள் என்பதையும் ஏதேனும் மோசடி தளத்துடன் இணையவில்லை என்பதையும் உறுதிப்படுத்த எந்த வழியும் இல்லை.</translation>
-<translation id="7449109375006139765">நிர்வகிப்புச் சேவையகத்திற்கு சிஸ்டம் பதிவுகளை அனுப்பும்</translation>
<translation id="7451311239929941790">இந்தச் சிக்கல் குறித்து <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">முழுமையான இயல்புநிலையைப் பயன்படுத்து (தடு)</translation>
<translation id="7460618730930299168">திரையிலுள்ள உள்ளடக்கமும் நீங்கள் தேர்ந்தெடுத்த உள்ளடக்கமும் மாறுபடுகின்றன. தொடரவா?</translation>
<translation id="7473891865547856676">வேண்டாம் நன்றி</translation>
-<translation id="7475525192983021547">சாதனத்தை ஒரு பயனர் பயன்படுத்தும் காலஅளவுகளைப் பற்றி அறிக்கையளிக்கும்</translation>
<translation id="7481312909269577407">அடுத்த பக்கம்</translation>
<translation id="7485870689360869515">தரவு எதுவும் இல்லை.</translation>
+<translation id="7498234416455752244">திருத்துவதைத் தொடர்க</translation>
<translation id="7508255263130623398">கிடைத்த பாலிசி சாதன ஐடி காலியாக உள்ளது அல்லது தற்போதைய சாதன ஐடியுடன் பொருந்தவில்லை</translation>
<translation id="7508870219247277067">அவகாடோ பச்சை</translation>
<translation id="7511955381719512146">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் வைஃபை, அதன் <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ஐ நீங்கள் பார்க்கக் கோரலாம்.</translation>
<translation id="7514365320538308">பதிவிறக்கு</translation>
<translation id="7518003948725431193">வலை முகவரிக்கான வலைப்பக்கங்கள் ஏதும் காணப்படவில்லை: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (என்வலப்)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">இந்தத் தளத்திற்கான உங்கள் இணைப்பு தனிப்பட்டதல்ல</translation>
+<translation id="7535087603100972091">மதிப்பு</translation>
<translation id="7537536606612762813">கட்டாயம்</translation>
+<translation id="7538364083937897561">A2 (என்வலப்)</translation>
<translation id="7542403920425041731">நீங்கள் உறுதிசெய்ததும், உங்கள் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation>
<translation id="7542995811387359312">இந்தப் படிவம் பாதுகாப்பான இணைப்பைப் பயன்படுத்தாத காரணத்தால், தானியங்கு கடன் அட்டை நிரப்புதல் முடக்கப்பட்டிருக்கிறது.</translation>
<translation id="7543525346216957623">உங்கள் பெற்றோரிடம் கேட்கவும்</translation>
@@ -1032,8 +1177,8 @@
<translation id="7552846755917812628">பின்வரும் உதவிக் குறிப்புகளைச் செய்து பார்க்கவும்:</translation>
<translation id="7554791636758816595">புதிய தாவல்</translation>
<translation id="7564049878696755256"><ph name="ORG_NAME" /> கணக்கிற்கான அணுகலை நீங்கள் இழக்கக்கூடும் அல்லது அடையாளத் திருட்டை எதிர்கொள்ளக்கூடும். இப்போதே உங்கள் கடவுச்சொல்லை மாற்றும்படி Chrome பரிந்துரைக்கிறது.</translation>
-<translation id="7566125604157659769">நீங்கள் நகலெடுத்த உரை</translation>
<translation id="7567204685887185387">இது <ph name="DOMAIN" /> தான் என்பதை இந்தச் சேவையகம் உறுதிப்படுத்தவில்லை; இதன் பாதுகாப்புச் சான்றிதழில் மோசடி செய்யப்பட்டிருக்கலாம். இது தவறான உள்ளமைவால் ஏற்பட்டிருக்கலாம் அல்லது தீங்கிழைப்பவர் உங்கள் இணைப்பில் குறுக்கிட்டிருக்கலாம்.</translation>
+<translation id="7568105740864181217">இந்த உலாவி ஒரு நிறுவனம், பள்ளி அல்லது பிற அமைப்பால் நிர்வகிக்கப்படுகிறது. உங்கள் உலாவியின் அமைவை உங்கள் நிர்வாகியால் தொலைநிலையிலிருந்து மாற்ற முடியும். இந்தச் சாதனத்தின் செயல்பாடுகளை Chromeமுக்கு வெளியிலிருந்தும் நிர்வகிக்கலாம். <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome இலிருந்து கிரெடிட் கார்டை அகற்றவா?</translation>
<translation id="7569983096843329377">கருப்பு</translation>
<translation id="7578104083680115302">Google இல் நீங்கள் சேமித்துள்ள கார்டுகளைப் பயன்படுத்தி பல தளங்களிலும் பயன்பாடுகளிலும் உங்களுடைய சாதனங்களில் அனைத்திலும் விரைவாகப் பணம் செலுத்தலாம்.</translation>
@@ -1044,6 +1189,7 @@
<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="7633909222644580952">செயல்திறன் தரவுகள் &amp; சிதைவு அறிக்கைகள்</translation>
<translation id="7637571805876720304">Chromium இலிருந்து கிரெடிட் கார்டை அகற்றவா?</translation>
<translation id="7639968568612851608">அடர்ந்த சாம்பல்</translation>
<translation id="765676359832457558">மேம்பட்ட அமைப்புகளை மறை...</translation>
@@ -1053,9 +1199,11 @@
<translation id="7667346355482952095">கிடைத்த பாலிசி டோக்கன் காலியாக உள்ளது அல்லது தற்போதைய டோக்கனுடன் பொருந்தவில்லை</translation>
<translation id="7668654391829183341">அறியப்படாத சாதனம்</translation>
<translation id="7669271284792375604">இந்தத் தளத்தில் உள்ள ஹேக்கர்கள், உங்களை ஏமாற்றி (எடுத்துக்காட்டாக, உங்கள் முகப்புப் பக்கத்தை மாற்றுவது அல்லது நீங்கள் பார்வையிடும் தளங்களில் கூடுதல் விளம்பரங்களைக் காட்டுவது), உங்கள் உலாவல் அனுபவத்தைப் பாதிக்கக்கூடிய நிரல்களை நிறுவ வைக்கலாம்.</translation>
+<translation id="7676643023259824263"><ph name="TEXT" /> கிளிப்-போர்டு உரையைத் தேடும்</translation>
<translation id="7681101578153515023">தேடல் இன்ஜினை மாற்று</translation>
<translation id="7682287625158474539">ஷிப்பிங்</translation>
<translation id="7687186412095877299">கட்டணப் படிவங்களில் உங்கள் சேமிக்கப்பட்ட கட்டண முறைகளை நிரப்பும்</translation>
+<translation id="7697066736081121494">Prc8 (என்வலப்)</translation>
<translation id="769721561045429135">தற்போது, இந்தச் சாதனத்தில் மட்டுமே பயன்படுத்தக்கூடிய கார்டுகள் உள்ளன கார்டுகளைப் பார்க்க, ‘தொடர்க’ என்பதைக் கிளிக் செய்யவும்.</translation>
<translation id="7699293099605015246">தற்போது கட்டுரைகள் இல்லை</translation>
<translation id="7701040980221191251">எதுவுமில்லை</translation>
@@ -1067,11 +1215,13 @@
<translation id="774634243536837715">ஆபத்தான உள்ளடக்கம் தடுக்கப்பட்டது.</translation>
<translation id="7752995774971033316">நிர்வகிக்கப்படாதது</translation>
<translation id="7755287808199759310">உங்களுக்காக, தளத்தின் தடுப்பை உங்கள் பெற்றோர் நீக்க முடியும்</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ஃபயர்வால் அல்லது வைரஸ்தடுப்பு மென்பொருள் உங்கள் இணைப்பைத் தடுத்திருக்கலாம்.</translation>
<translation id="7759163816903619567">காட்சி டொமைன்:</translation>
<translation id="7761701407923456692">சேவையகச் சான்றிதழ் URL உடன் பொருந்தவில்லை.</translation>
<translation id="7763386264682878361">பேமெண்ட் மெனிஃபெஸ்ட் பாகுபடுத்தி</translation>
<translation id="7764225426217299476">முகவரியைச் சேர்</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">ப்ரீஃபெக்சர்</translation>
<translation id="7791543448312431591">சேர்</translation>
<translation id="7793809570500803535"><ph name="SITE" /> இல் உள்ள வலைப்பக்கமானது தற்காலிகமாக இயங்காமல் இருக்கலாம் அல்லது அது ஒரு புதிய வலை முகவரிக்கு நிரந்தரமாக நகர்த்தப்பட்டிருக்கலாம்.</translation>
@@ -1083,8 +1233,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome இலிருந்து படிவப் பரிந்துரையை அகற்றவா?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />'க்கு <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> உள்ளன</translation>
-<translation id="7818867226424560206">கொள்கை மேலாண்மை</translation>
<translation id="782886543891417279">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் (<ph name="WIFI_NAME" />) வைஃபை, அதன் உள்நுழைவுப் பக்கத்தை நீங்கள் பார்க்கக் கோரலாம்.</translation>
+<translation id="7836231406687464395">Postfix (என்வலப்)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{எதுவுமில்லை}=1{1 ஆப்ஸ் (<ph name="EXAMPLE_APP_1" />)}=2{2 ஆப்ஸ் (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# ஆப்ஸ் (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">இருப்பினும், நீங்கள் மறைந்திருக்கமாட்டீர்கள். மறைநிலைக்குச் செல்வது பணிக்கமர்த்தும் நிறுவனம், இணையச் சேவை வழங்குநர் அல்லது நீங்கள் செல்லும் இணையதளங்களிடம் உங்கள் உலாவலை மறைக்காது.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1093,7 +1243,7 @@
<translation id="7878562273885520351">உங்கள் கடவுச்சொல் திருடப்பட்டிருக்கலாம்</translation>
<translation id="7882421473871500483">பழுப்பு</translation>
<translation id="7887683347370398519">CVCஐச் சோதித்து, மீண்டும் முயற்சிக்கவும்</translation>
-<translation id="7893255318348328562">அமர்வின் பெயர்</translation>
+<translation id="7904208859782148177">C3 (என்வலப்)</translation>
<translation id="79338296614623784">சரியான ஃபோன் எண்ணை உள்ளிடவும்</translation>
<translation id="7935318582918952113">DOM டிஸ்டில்லர்</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" /> அன்று காலாவதியாகும்</translation>
@@ -1103,21 +1253,25 @@
<translation id="7951415247503192394">(32-பிட்)</translation>
<translation id="7956713633345437162">மொபைல் புக்மார்க்குகள்</translation>
<translation id="7961015016161918242">எப்போதும் இல்லை</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">குறிப்பிடப்படவில்லை</translation>
<translation id="800218591365569300">பிற தாவல்கள் அல்லது நிரல்களை மூடி, நினைவகத்தைக் காலியாக்கவும்.</translation>
+<translation id="8004582292198964060">உலாவி</translation>
<translation id="8009225694047762179">கடவுச்சொற்களை நிர்வகி</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{இந்தக் கார்டும் அதன் பில்லிங் முகவரியும் சேமிக்கப்படும். <ph name="USER_EMAIL" /> இல் உள்நுழைந்திருக்கும்போது இதைப் பயன்படுத்தலாம்.}other{இந்தக் கார்டுகளும் அவற்றின் பில்லிங் முகவரிகளும் சேமிக்கப்படும். <ph name="USER_EMAIL" /> இல் உள்நுழைந்திருக்கும்போது இவற்றைப் பயன்படுத்தலாம்.}}</translation>
<translation id="8012647001091218357">தற்போது எங்களால் உங்கள் பெற்றோர்களைத் தொடர்புகொள்ள முடியவில்லை. மீண்டும் முயற்சிக்கவும்.</translation>
<translation id="8025119109950072390">இந்தத் தளத்தில் உள்ள ஹேக்கர்கள், உங்களை ஏமாற்றி, மென்பொருளை நிறுவுவது அல்லது தனிப்பட்ட தகவலை (எடுத்துக்காட்டாக, கடவுச்சொற்கள், ஃபோன் எண்கள் அல்லது கிரெடிட் கார்டுகள்) வெளிப்படுத்துவது போன்ற உங்களுக்கு ஆபத்தை விளைவிக்கும் செயல்களைச் செய்ய வைக்கலாம்.</translation>
<translation id="8034522405403831421">இந்தப் பக்கம் <ph name="SOURCE_LANGUAGE" /> மொழியில் உள்ளது. இதை <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கவா?</translation>
<translation id="8035152190676905274">பேனா</translation>
+<translation id="8037117624646282037">சமீபத்தில் சாதனத்தைப் பயன்படுத்தியவர்கள்</translation>
<translation id="8037357227543935929">கேள் (இயல்பு)</translation>
<translation id="803771048473350947">கோப்பு</translation>
<translation id="8041089156583427627">கருத்துத் தெரிவிக்கவும்</translation>
<translation id="8041940743680923270">முழுமையான இயல்புநிலையைப் பயன்படுத்து (கேள்)</translation>
<translation id="8042918947222776840">பிக்அப் முறையைத் தேர்வு செய்</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" மென்பொருள் சரியாக உள்ளமைக்கப்படவில்லை. வழக்கமாக, "<ph name="SOFTWARE_NAME" />"ஐ நிறுவல் நீக்கினால் சிக்கல் சரியாகிவிடும். <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">உங்கள் சாதனம் இவற்றுக்கு உள்ளமைக்கப்பட்டுள்ளது:</translation>
+<translation id="8066955247577885446">ஏதோ தவறாகிவிட்டது.</translation>
+<translation id="8074253406171541171">10x13 (என்வலப்)</translation>
<translation id="8078141288243656252">சுழற்றப்பட்டுள்ளபோது ஆவணத்தில் விரிவுரையைச் சேர்க்க முடியாது</translation>
<translation id="8079031581361219619">தளத்தை மீண்டும் ஏற்றவா?</translation>
<translation id="8088680233425245692">கட்டுரையைக் காட்டுவதில் தோல்வி.</translation>
@@ -1126,11 +1280,12 @@
<translation id="8091372947890762290">சேவையகத்தில் செயலாக்கம் நிலுவையிலுள்ளது</translation>
<translation id="8092774999298748321">அடர் பர்பிள்</translation>
<translation id="8094917007353911263">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் நெட்வொர்க், <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> ஐ நீங்கள் பார்க்கக் கோரலாம்.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">செல்லாத கார்டுகள் அகற்றப்பட்டன</translation>
<translation id="8103161714697287722">கட்டண முறை</translation>
<translation id="8118489163946903409">கட்டண முறை</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> சாதனத்தை <ph name="ENROLLMENT_DOMAIN" /> நிர்வகிக்கிறது</translation>
<translation id="8127301229239896662">உங்கள் கம்ப்யூட்டர் அல்லது நெட்வொர்க்கில் "<ph name="SOFTWARE_NAME" />" மென்பொருள் சரியாக நிறுவப்படவில்லை. இந்தச் சிக்கலைச் சரிசெய்யும்படி உங்கள் ஐடி நிர்வாகியிடம் கேட்கவும்.</translation>
-<translation id="8130693978878176684">தொடர்ந்து என்னால் உதவ முடியாது, நீங்களே செய்யுங்கள்.</translation>
<translation id="8131740175452115882">உறுதிப்படுத்து</translation>
<translation id="8149426793427495338">உங்கள் கணினி உறக்கநிலைக்குச் சென்றது.</translation>
<translation id="8150722005171944719"><ph name="URL" /> இல் உள்ள கோப்பு படிக்கக் கூடியதாக இல்லை. அது அகற்றப்பட்டிருக்கலாம், நகர்த்தப்பட்டிருக்கலாம் அல்லது கோப்பு அனுமதிகள் அணுகலைத் தடுத்திருக்கலாம்.</translation>
@@ -1140,8 +1295,11 @@
<translation id="8197543752516192074">பக்கத்தை மொழிபெயர்</translation>
<translation id="8201077131113104583">"<ph name="EXTENSION_ID" />" ஐடியுடன் கூடிய நீட்டிப்பிற்கான தவறான புதுப்பிப்பு URL.</translation>
<translation id="8202097416529803614">ஆர்டர் பற்றிய சுருக்கவிவரம்</translation>
+<translation id="8202370299023114387">முரண்பாடு</translation>
+<translation id="8206978196348664717">Prc4 (என்வலப்)</translation>
<translation id="8211406090763984747">இணைப்பு பாதுகாப்பானது</translation>
<translation id="8218327578424803826">ஒதுக்கிய இருப்பிடம்:</translation>
+<translation id="8220146938470311105">C7/C6 (என்வலப்)</translation>
<translation id="8225771182978767009">இந்தக் கணினியை அமைத்த நபர் இந்தத் தளத்தைத் தடுக்கும்படி தேர்வுசெய்துள்ளார்.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">புதிய மறைநிலைத் தாவலில் பக்கத்தைத் திறக்கவும்</translation>
@@ -1153,14 +1311,16 @@
<translation id="825929999321470778">சேமித்த எல்லாக் கடவுச்சொற்களையும் காட்டு</translation>
<translation id="8261506727792406068">நீக்கு</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> ஆக உள்நுழைகிறீர்கள்</translation>
+<translation id="8278457561961988242">இந்த உலாவியை <ph name="ENROLLMENT_DOMAIN" /> நிர்வகிக்கிறது. உங்கள் உலாவியின் அமைவை உங்கள் நிர்வாகியால் தொலைநிலையிலிருந்து மாற்ற முடியும். இந்தச் சாதனத்தின் செயல்பாடுகளை Chromeமுக்கு வெளியிலிருந்தும் நிர்வகிக்கலாம். <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">உள்நுழை</translation>
<translation id="8288807391153049143">சான்றிதழைக் காட்டும்</translation>
<translation id="8289355894181816810">இதன் பொருள் உங்களுக்குத் தெரியவில்லையெனில் உங்கள் நெட்வொர்க் நிர்வாகியைத் தொடர்புகொள்ளவும்.</translation>
<translation id="8293206222192510085">புக்மார்க்கைச் சேர்</translation>
<translation id="8294431847097064396">மூலம்</translation>
<translation id="8298115750975731693">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் (<ph name="WIFI_NAME" />) வைஃபை, அதன் <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ஐ நீங்கள் பார்க்கக் கோரலாம்.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">நெட்வொர்க் இணைப்பில் ஒரு சிக்கல் இருப்பதால் மொழிபெயர்ப்பு தோல்வியடைந்தது.</translation>
-<translation id="8311129316111205805">அமர்வை ஏற்று</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> க்கான அணுகல் மறுக்கப்பட்டது</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">உங்கள் பாதுகாப்பிற்கான ஆபத்தைப் புரிந்துகொண்டால், தீங்கான நிரல்களை அகற்றும் முன் <ph name="BEGIN_LINK" />இந்தத் தளத்தைப் பார்வையிடலாம்<ph name="END_LINK" />.</translation>
@@ -1178,7 +1338,6 @@
<translation id="8416694386774425977">நெட்வொர்க் உள்ளமைவு தவறானது மேலும் அதை இறக்குமதி செய்ய முடியவில்லை.
கூடுதல் விவரங்கள்:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">சாதன நிர்வாகி: <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">மாற்று</translation>
<translation id="8428213095426709021">அமைப்புகள்</translation>
@@ -1205,9 +1364,11 @@
<translation id="860043288473659153">கார்டு உரிமையாளரின் பெயர்</translation>
<translation id="861775596732816396">அளவு: 4</translation>
<translation id="8620436878122366504">இன்னும் உங்கள் பெற்றோர் அனுமதிக்கவில்லை</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">இந்தச் சாதனத்தில் கார்டைச் சேமி</translation>
<translation id="8663226718884576429">ஆர்டர் சுருக்கம், <ph name="TOTAL_LABEL" />, மேலும் விவரங்கள்</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, பதில், <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> க்கான உங்கள் இணைப்பு குறியாக்கம் செய்யப்படவில்லை.</translation>
<translation id="8718314106902482036">பேமெண்ட் முடியவில்லை</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, தேடல் பரிந்துரை</translation>
@@ -1221,6 +1382,7 @@
<translation id="8761567432415473239">Google பாதுகாப்பான தேடல், <ph name="SITE" /> இல் சமீபத்தில் <ph name="BEGIN_LINK" />தீங்கான நிரல்களைக் கண்டறிந்தது<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB சாதனம்</translation>
<translation id="8768895707659403558">உங்கள் சாதனங்கள் அனைத்திலும் உங்கள் கார்டுகளைப் பயன்படுத்த, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;நீக்குதலை மீண்டும் செய்</translation>
<translation id="8792621596287649091"><ph name="ORG_NAME" /> கணக்கிற்கான அணுகலை நீங்கள் இழக்கக்கூடும் அல்லது அடையாளத் திருட்டை எதிர்கொள்ளக்கூடும். இப்போதே உங்கள் கடவுச்சொல்லை மாற்றும்படி Chromium பரிந்துரைக்கிறது.</translation>
<translation id="8800988563907321413">உங்கள் அருகிலுள்ளவற்றுக்கான பரிந்துரைகள் இங்கே தோன்றும்</translation>
@@ -1231,10 +1393,12 @@
<translation id="885730110891505394">Google உடன் பகிர்பவை</translation>
<translation id="8858065207712248076">பிற தளங்களில் உங்கள் <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> கடவுச்சொல்லை மீண்டும் பயன்படுத்தினால், அதை மீட்டமைக்கும்படி Chrome பரிந்துரைக்கிறது.</translation>
<translation id="8866481888320382733">கொள்கை அமைப்புகளை அலசுவதில் பிழை</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">சமீபத்தில் மூடியவை</translation>
<translation id="8874824191258364635">சரியான கார்டு எண்ணை உள்ளிடவும்</translation>
<translation id="8891727572606052622">தவறான ப்ராக்ஸி முறை.</translation>
<translation id="8903921497873541725">பெரிதாக்கு</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">இந்தக் கார்டை உங்கள் Google கணக்கில் சேமிக்க வேண்டுமா?</translation>
<translation id="8932102934695377596">உங்கள் கடிகாரம் மிகவும் பின்தங்கி இருக்கிறது</translation>
<translation id="893332455753468063">பெயரைச் சேர்க்கவும்</translation>
@@ -1242,13 +1406,13 @@
<translation id="894185898663964645">பிரத்தியேகமான முதன்மை சான்றிதழ்களை உங்கள் நிர்வாகி உள்ளமைத்துள்ளார், இதன் மூலம் நீங்கள் பார்வையிடும் இணையதளங்களின் உள்ளடக்கங்களை நிர்வாகியால் பார்க்க முடியும்.</translation>
<translation id="8943282376843390568">சுண்ணாம்பு நிறம்</translation>
<translation id="8957210676456822347">கேப்டிவ் போர்டல் அங்கீகாரம்</translation>
+<translation id="8966619695390250636">இதைக் குறிப்பிடுகிறீர்களா?</translation>
<translation id="8968766641738584599">கார்டைச் சேமி</translation>
<translation id="8971063699422889582">சேவையகச் சான்றிதழ் காலாவதியானது.</translation>
<translation id="8975012916872825179">இதில் ஃபோன் எண்கள், மின்னஞ்சல் முகவரிகள், ஷிப்பிங் முகவரிகள் போன்ற தகவல்கள் உள்ளடங்கும்</translation>
<translation id="8978053250194585037">சமீபத்தில் Google பாதுகாப்பான உலாவலானது <ph name="SITE" /> தளத்தில் <ph name="BEGIN_LINK" />ஃபிஷிங்கைக் கண்டறிந்தது<ph name="END_LINK" />. ஃபிஷிங் தளங்கள் பிற இணையதளங்களைப் போல் காண்பித்து, உங்களை ஏமாற்ற முயற்சிக்கக்கூடும்.</translation>
<translation id="8983003182662520383">Google Payவைப் பயன்படுத்தும் கட்டண முறைகளும் முகவரிகளும்</translation>
<translation id="8987927404178983737">மாதம்</translation>
-<translation id="8988408250700415532">ஏதோ தவறாகிவிட்டது. உங்கள் ஆர்டரை இணையதளத்தில் முடிக்கலாம்.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">தளத்தில் தீங்கிழைக்கும் நிரல்கள் அதிகளவில் உள்ளன</translation>
<translation id="8997023839087525404">சான்றிதழ் வெளிப்படைத்தன்மை கொள்கையின்படி பொதுவில் வெளியிடப்படாத சான்றிதழைச் சேவையகம் வழங்கியுள்ளது. நம்பகத்தன்மை மற்றும் தாக்குதல்களுக்கு எதிரான பாதுகாப்பை உறுதிசெய்ய, சில சான்றிதழ்களுக்கு இது தேவையான ஒன்றாகும்.</translation>
@@ -1258,6 +1422,7 @@
<translation id="9011424611726486705">தள அமைப்புகளைத் திறக்கும்</translation>
<translation id="9020200922353704812">கார்டு பில்லிங் முகவரி தேவை</translation>
<translation id="9020542370529661692">இந்தப் பக்கம் <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கப்பட்டது</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(தவறானது)</translation>
<translation id="9035022520814077154">பாதுகாப்புப் பிழை</translation>
<translation id="9038649477754266430">பக்கங்களை இன்னும் விரைவாக ஏற்ற, யூக சேவையைப் பயன்படுத்தவும்</translation>
@@ -1269,12 +1434,12 @@
<translation id="9065745800631924235">வரலாற்றிலிருந்து <ph name="TEXT" /> பற்றிய தேடல்கள்</translation>
<translation id="9069693763241529744">நீட்டிப்பு தடுத்துள்ளது</translation>
<translation id="9076283476770535406">இதில் பெரியவர்களுக்கான உள்ளடக்கம் இருக்கக்கூடும்</translation>
+<translation id="9076630408993835509">இந்த உலாவியை ஒரு நிறுவனமோ பிற அமைப்போ நிர்வகிக்கவில்லை. இந்தச் சாதனத்தின் செயல்பாடுகளை Chromeமுக்கு வெளியிலிருந்து நிர்வகிக்கலாம். <ph name="BEGIN_LINK" />மேலும் அறிக<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">கூடுதல் தகவல் தேவை</translation>
<translation id="9080712759204168376">ஆர்டர் பற்றிய சுருக்கவிவரம்</translation>
<translation id="9103872766612412690">வழக்கமாக, <ph name="SITE" /> உங்கள் தகவலைப் பாதுகாப்பதற்காக முறைமையாக்கத்தைப் பயன்படுத்துகிறது.
இந்த முறை <ph name="SITE" /> உடன் இணைவதற்கு Chromium முயற்சித்தபோது வழக்கத்திற்கு மாறான, தவறான நற்சான்றிதழ்களை இணையதளம் வழங்கியது. தாக்குபவர் தன்னை <ph name="SITE" /> ஆகக் காட்ட முயற்சிக்கும் போது அல்லது இணைப்பை வைஃபை உள்நுழைவுத் திரை குறுக்கிடும் போது இது ஏற்படலாம். இருப்பினும், தரவு எதுவும் பரிமாற்றப்படுவதற்கு முன் Chromium இணைப்பை நிறுத்தியதால் உங்கள் தகவல் பாதுகாப்பாகவே இருக்கிறது.</translation>
<translation id="9106062320799175032">பில்லிங் முகவரியைச் சேர்க்கவும்</translation>
-<translation id="9110718169272311511">திரையின் அடிப்பகுதிக்கு அருகே ’Chromeமில் Google அசிஸ்டண்ட்’ உள்ளது</translation>
<translation id="9114524666733003316">கார்டை உறுதிசெய்கிறது...</translation>
<translation id="9128870381267983090">நெட்வொர்க்குடன் இணையவும்</translation>
<translation id="9137013805542155359">அசலைக் காண்பி</translation>
@@ -1283,6 +1448,7 @@
<translation id="9148507642005240123">&amp;திருத்தலைச் செயல்தவிர்</translation>
<translation id="9154194610265714752">புதுப்பிக்கப்பட்டது</translation>
<translation id="9157595877708044936">அமைக்கிறது...</translation>
+<translation id="9158625974267017556">C6 (என்வலப்)</translation>
<translation id="9168814207360376865">சேமித்துள்ள உங்கள் கட்டண முறைகளைப் பார்க்க தளங்களை அனுமதிக்கவும்</translation>
<translation id="9169664750068251925">இந்தத் தளத்தில் எப்போதும் தடு</translation>
<translation id="9170848237812810038">&amp;செயல்தவிர்</translation>
@@ -1297,10 +1463,12 @@
<translation id="9219103736887031265">படங்கள்</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">படிவத்தை அழி</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">உங்கள் Google கணக்கிற்கான அணுகலை நீங்கள் இழக்கக்கூடும். இப்போதே உங்கள் கடவுச்சொல்லை மாற்றுமாறு Chromium பரிந்துரைக்கிறது. அதற்கு நீங்கள் உள்நுழைய வேண்டும்.</translation>
<translation id="939736085109172342">புதிய கோப்புறை</translation>
<translation id="945855313015696284">கீழுள்ள தகவல்களைச் சரிபார்த்து, செல்லுபடியாகாத கார்டுகள் ஏதேனும் இருந்தால் அவற்றை நீக்கவும்.</translation>
<translation id="951104842009476243">ஏற்கப்படும் டெபிட் மற்றும் ப்ரீபெய்டு கார்டுகள்</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" />ன் பாதுகாப்புக் கொள்கையின் காரணமாகத் தடுக்கப்பட்டுள்ளது.</translation>
<translation id="962484866189421427">இந்த உள்ளடக்கம், வேறொரு பிரபல ஆப்ஸ் போலத் தோற்றமளிக்கக்கூடிய அல்லது உங்களைக் கண்காணிக்கப் பயன்படுத்தக்கூடிய தரவைச் சேகரிக்கும் போலியான ஆப்ஸை நிறுவ முயலலாம். <ph name="BEGIN_LINK" />பரவாயில்லை, பக்கத்தைக் காட்டு<ph name="END_LINK" /></translation>
<translation id="969892804517981540">அதிகாரப்பூர்வ கட்டமைப்பு</translation>
<translation id="973773823069644502">டெலிவரி முகவரியைச் சேர்</translation>
@@ -1309,6 +1477,7 @@
<translation id="984275831282074731">பேமெண்ட் முறைகள்</translation>
<translation id="985199708454569384">&lt;p&gt;உங்கள் கணினி அல்லது மொபைல் சாதனத்தின் தேதி மற்றும் நேரம் தவறாக இருந்தால், இந்தப் பிழையைப் பார்ப்பீர்கள்.&lt;/p&gt;
&lt;p&gt;இந்தப் பிழையைச் சரிசெய்ய, உங்கள் சாதனத்தின் கடிகாரத்தைத் திறக்கவும். நேரமும் தேதியும் சரியாக இருப்பதை உறுதிப்படுத்தவும்.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">டெவலப்பர் கட்டமைப்பு</translation>
<translation id="989988560359834682">முகவரியைத் திருத்து</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_te.xtb b/chromium/components/strings/components_strings_te.xtb
index ca2bb71d461..d0e74e2b336 100644
--- a/chromium/components/strings/components_strings_te.xtb
+++ b/chromium/components/strings/components_strings_te.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="te">
-<translation id="1005145902654145231">సెషన్ పేరును మార్చడం విఫలమైంది.</translation>
<translation id="1008557486741366299">ఇప్పుడు కాదు</translation>
<translation id="1010200102790553230">పేజీని తర్వాత లోడ్ చేయి</translation>
<translation id="1015730422737071372">అదనపు వివరాలను అందించండి</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">తెలియని పేరు</translation>
<translation id="1050038467049342496">ఇతర అనువర్తనాలను మూసివేయండి</translation>
<translation id="1055184225775184556">&amp;జోడించడాన్ని రద్దు చేయి</translation>
+<translation id="1056898198331236512">హెచ్చరిక</translation>
<translation id="1058479211578257048">కార్డ్‌లు సేవ్ చేయబడుతున్నాయి...</translation>
<translation id="10614374240317010">ఎప్పటికి సేవ్ చెయ్యబడవు</translation>
+<translation id="1062160989074299343">Prc10 (ఎన్వలప్)</translation>
<translation id="106701514854093668">డెస్క్‌టాప్‌ బుక్‌మార్క్‌లు</translation>
<translation id="1074497978438210769">సురక్షితం కాదు</translation>
<translation id="1080116354587839789">వెడల్పు సరిపోయేలా అమర్చు</translation>
+<translation id="1086953900555227778">సూచిక-5x8</translation>
<translation id="1088860948719068836">కార్డ్‌లో పేరుని జోడించండి</translation>
<translation id="1089439967362294234">పాస్‌వర్డ్‌ని మార్చు</translation>
<translation id="109743633954054152">Chrome సెట్టింగ్‌లలో పాస్‌వర్డ్‌లను నిర్వహించండి</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">వెబ్‌సైట్‌ల యొక్క భద్రతను అప్‌డేట్ చేస్తున్నప్పుడు హెచ్చరికలు కనిపించడం సాధారణమే. ఇది త్వరలోనే మెరుగుపరచబడుతుంది.</translation>
<translation id="1126551341858583091">స్థానిక నిల్వలో పరిమాణం <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">విధాన కాష్ సరిపోయింది</translation>
+<translation id="1131264053432022307">మీరు కాపీ చేసిన చిత్రం</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ఊహించని విధంగా కనెక్షన్‌ను మూసివేసింది.</translation>
<translation id="1161325031994447685">Wi-Fiకి మళ్లీ కనెక్ట్ చేయడం</translation>
<translation id="1165039591588034296">ఎర్రర్</translation>
-<translation id="1173894706177603556">పేరుమార్చు</translation>
<translation id="1175364870820465910">&amp;ముద్రించు...</translation>
<translation id="1181037720776840403">తీసివేయి</translation>
<translation id="1197088940767939838">నారింజ రంగు</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">మీ పరికరం పేరు</translation>
<translation id="124116460088058876">మరిన్ని భాషలు</translation>
<translation id="1250759482327835220">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్, పేరు మరియు బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు సేవ్ చేయండి.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (సమకాలీకరించబడ్డాయి)</translation>
@@ -59,14 +61,15 @@
&lt;/ol&gt;</translation>
<translation id="1257286744552378071">మీ సంస్థ నిర్వహించని ఒక సైట్‌లో మీరు మీ పాస్‌వర్డ్‌ను నమోదు చేసారు. మీ ఖాతాను రక్షించడం కోసం, ఇతర యాప్‌లు మరియు సైట్‌లలో మీ పాస్‌వర్డ్‌ను తిరిగి ఉపయోగించవద్దు.</translation>
<translation id="1263231323834454256">పఠన జాబితా</translation>
-<translation id="1264126396475825575">క్రాష్ నివేదిక <ph name="CRASH_TIME" />కి క్యాప్చర్ చేయబడింది (ఇంకా అప్‌లోడ్ చేయలేదు లేదా విస్మరించబడింది)</translation>
+<translation id="1264126396475825575">క్రాష్ నివేదిక <ph name="CRASH_TIME" />కు క్యాప్చ‌ర్ చేయ‌బ‌డింది (ఇంకా అప్‌లోడ్ చేయలేదు లేదా విస్మరించబడింది)</translation>
<translation id="1270502636509132238">పికప్ పద్ధతి</translation>
<translation id="1285320974508926690">ఈ సైట్‌ను ఎప్పటికీ అనువదించవద్దు</translation>
<translation id="1292701964462482250">"మీ కంప్యూటర్‌లో ఉన్న సాఫ్ట్‌వేర్ కారణంగా Chrome సురక్షితంగా వెబ్‌కి కనెక్ట్ కాలేకపోతోంది" (Windows కంప్యూటర్‌లకు మాత్రమే)</translation>
<translation id="1294154142200295408">ఆదేశ-పంక్తి వ్యత్యాసాలు</translation>
<translation id="129553762522093515">ఇటీవల మూసివెయ్యబడినవి</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />మీ కుక్కీలను తీసివేయడానికి ప్రయత్నించండి<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">ఎంచుకోబడిన సెషన్ ఉనికిలో లేదు.</translation>
+<translation id="1320233736580025032">Prc1 (ఎన్వలప్)</translation>
+<translation id="132301787627749051">క్లిప్‌బోర్డ్ చిత్రం కోసం వెతకండి</translation>
<translation id="1323433172918577554">మరింత చూపు</translation>
<translation id="132390688737681464">చిరునామాలను సేవ్ చేసి, పూరించండి</translation>
<translation id="1333989956347591814">మీ కార్యాచరణ వీరికి <ph name="BEGIN_EMPHASIS" />ఇప్పటికీ కనిపించవచ్చు<ph name="END_EMPHASIS" />:
@@ -81,12 +84,17 @@
<translation id="1340482604681802745">పికప్ చిరునామా</translation>
<translation id="1348198688976932919">రాబోయే సైట్‌లో హానికరమైన యాప్‌లు ఉన్నాయి</translation>
<translation id="1348779747280417563">పేరును నిర్ధారించండి</translation>
+<translation id="1357195169723583938">పరికరాన్ని ఇటీవల ఎవరెవరు, ఏయే సమయాలలో ఉపయోగించారు</translation>
+<translation id="1364822246244961190">ఈ విధానాన్ని బ్లాక్ చేస్తే, దీని విలువ విస్మరించబడుతుంది.</translation>
<translation id="1374468813861204354">సూచనలు</translation>
+<translation id="1374692235857187091">సూచిక-4x6 (పోస్ట్‌కార్డ్)</translation>
<translation id="1375198122581997741">వెర్షన్ గురించి</translation>
<translation id="1376836354785490390">తక్కువ చూపు</translation>
<translation id="1377321085342047638">కార్డ్ సంఖ్య</translation>
<translation id="138218114945450791">లేత నీలి రంగు</translation>
+<translation id="1382194467192730611">మీ నిర్వాహకుడు అనుమతించే USB పరికరం</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> డేటా ఏదీ పంపలేదు.</translation>
+<translation id="140316286225361634">సైట్ <ph name="ORIGIN" /> యొక్క అన్ని అభ్యర్థనలకు భద్రతా విధానం వర్తిస్తుందని సైట్ తెలియజేసింది మరియు ప్రస్తుతం ఈ విధానం ప్రకారం సైట్‌ సురక్షితం కాదు.</translation>
<translation id="1405567553485452995">లేత ఆకుపచ్చ రంగు</translation>
<translation id="1407135791313364759">అన్నీ తెరువు</translation>
<translation id="1413809658975081374">గోప్యతా ఎర్రర్</translation>
@@ -94,33 +102,40 @@
<translation id="1426410128494586442">అవును</translation>
<translation id="1430915738399379752">ముద్రించు</translation>
<translation id="1455413310270022028">ఎరేజర్</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">మరిన్ని చూపించు</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">షిప్పింగ్ చిరునామాను ఎంచుకోండి</translation>
+<translation id="1492194039220927094">విధానాలను పుష్ చేయి:</translation>
<translation id="1501859676467574491">మీ Google ఖాతా నుండి కార్డ్‌లను చూపండి</translation>
-<translation id="1506687042165942984">ఈ పేజీ యొక్క సేవ్ చేసిన (అంటే పాతది) కాపీని చూపుతుంది.</translation>
-<translation id="1507202001669085618">&lt;p&gt;ఆన్‌లైన్‌కు వెళ్లగలిగే ముందు సైన్ ఇన్ చేయాల్సిన అవసరం ఉన్న Wi-Fi పోర్టల్‌ను మీరు ఉపయోగిస్తున్నట్లయితే మీకు ఈ ఎర్రర్ కనిపిస్తుంది.&lt;/p&gt;
+<translation id="1507202001669085618">&lt;p&gt;ఆన్‌లైన్‌కు వెళ్లడం కంటే ముందు సైన్ ఇన్ చేయాల్సిన అవసరం ఉన్న Wi-Fi పోర్టల్‌ను మీరు ఉపయోగిస్తున్నట్లయితే మీకు ఈ ఎర్రర్ కనిపిస్తుంది.&lt;/p&gt;
&lt;p&gt;ఎర్రర్‌ను పరిష్కరించడానికి, మీరు తెరవాలనుకుంటున్న పేజీలో &lt;strong&gt;కనెక్ట్ చేయి&lt;/strong&gt;ని నొక్కండి.&lt;/p&gt;</translation>
<translation id="1517433312004943670">ఫోన్ నంబర్ అవసరం</translation>
<translation id="1517500485252541695">ఆమోదించబడిన క్రెడిట్ మరియు డెబిట్ కార్డ్‌లు</translation>
<translation id="1519264250979466059">బిల్డ్ తేదీ</translation>
<translation id="1521655867290435174">Google షీట్‌లు</translation>
<translation id="1527263332363067270">కనెక్షన్ కోసం వేచి ఉన్నాము...</translation>
+<translation id="1529521330346880926">10x15 (ఎన్వలప్)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">ఈ పేజీ ఇలా చెబుతోంది</translation>
<translation id="153384715582417236">ఇప్పటికి ఇంతే</translation>
<translation id="154408704832528245">బట్వాడా చిరునామాను ఎంచుకోండి</translation>
<translation id="1549470594296187301">ఈ ఫీచర్‌ను ఉపయోగించడానికి జావాస్క్రిప్ట్ తప్పనిసరిగా ప్రారంభించాలి.</translation>
+<translation id="155039086686388498">ఇంజనీరింగ్-D</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="1569487616857761740">గడువు ముగింపు తేదీని నమోదు చేయండి</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">ఈ వెబ్ పేజీని ప్రదర్శిస్తున్నప్పుడు ఏదో తప్పు జరిగింది.</translation>
<translation id="1592005682883173041">స్థానిక డేటా యాక్సెస్</translation>
<translation id="1594030484168838125">ఎంచుకోండి</translation>
<translation id="161042844686301425">నీలి ఆకుపచ్చ</translation>
-<translation id="1618822247301510817">మీరు కాపీ చేసిన చిత్రం</translation>
<translation id="1620510694547887537">కెమెరా</translation>
<translation id="1623104350909869708">ఈ పేజీని అదనపు డైలాగ్‌లు సృష్టించనీయకుండా నిరోధించు</translation>
+<translation id="16338877384480380">ఆర్కిటెక్చర్-B</translation>
<translation id="1634051627998691300">సెషన్‌ను ముగించు</translation>
<translation id="1639239467298939599">లోడ్ అవుతోంది</translation>
<translation id="1640180200866533862">వినియోగదారు విధానాలు</translation>
@@ -135,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> సాధారణంగా మీ సమాచారాన్ని రక్షించడానికి ఎన్‌క్రిప్ష‌న్‌ను ఉపయోగిస్తుంది. Google Chrome ఈసారి <ph name="SITE" />కు కనెక్ట్ చేయడానికి ప్రయత్నించినప్పుడు, వెబ్‌సైట్ అసాధారణ మరియు తప్పు ఆధారాలు అని ప్రతిస్పందించింది. దాడి చేసే వ్యక్తి <ph name="SITE" />గా వ్యవహరించి మోసగించడానికి ప్రయత్నిస్తున్నప్పుడు లేదా Wi-Fi సైన్-ఇన్ స్క్రీన్ కనెక్షన్‌కు అంతరాయం కలిగించినప్పుడు ఇలా జరగవచ్చు. Google Chrome డేటా వినిమయం జ‌ర‌గ‌క ముందే కనెక్షన్‌ను ఆపివేసినందున మీ సమాచారం ఇప్పటికీ సురక్షితంగానే ఉంది.</translation>
<translation id="168841957122794586">సర్వర్ ప్రమాణపత్రం బలహీన క్రిప్టోగ్రాఫిక్ కీని కలిగి ఉంది.</translation>
<translation id="1697532407822776718">మీరు సిద్ధంగా ఉన్నారు!</translation>
+<translation id="1703835215927279855">లెటర్</translation>
<translation id="1706954506755087368">{1,plural, =1{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం రేపటిది కావచ్చు. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు.}other{ఈ సర్వర్ ఇది <ph name="DOMAIN" /> అని నిరూపించలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం భవిష్యత్తులో # రోజుల తదుపరిది కావచ్చు. తప్పుగా కాన్ఫిగర్ చేసినందున లేదా దాడిచేసేవారు మీ కనెక్షన్‌కు అంతరాయం కలిగించినందున ఇలా జరిగి ఉండవచ్చు.}}</translation>
<translation id="1710259589646384581">OS</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">పత్రం అదనపు గమనికలను జోడించడానికి వీలు లేకుండా చాలా అధిక పరిమాణంలో ఉంది</translation>
<translation id="1721312023322545264">ఈ సైట్‌ని సందర్శించడానికి మీకు <ph name="NAME" /> నుండి అనుమతి అవసరం</translation>
<translation id="1721424275792716183">* అవసరమైన ఫీల్డ్</translation>
@@ -147,6 +164,7 @@
<translation id="1734878702283171397">సిస్టమ్ నిర్వాహకుడిని సంప్రదించి ప్రయత్నించండి.</translation>
<translation id="1740951997222943430">చెల్లుబాటు అయ్యే గడువు ముగింపు నెలను నమోదు చేయండి</translation>
<translation id="1743520634839655729">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్, పేరు మరియు బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు మరియు ఈ పరికరానికి సేవ్ చేయండి.</translation>
+<translation id="1745880797583122200">మీ బ్రౌజర్ నిర్వహించబడుతోంది</translation>
<translation id="17513872634828108">తెరిచిన ట్యాబ్‍లు</translation>
<translation id="1753706481035618306">పేజీ సంఖ్య</translation>
<translation id="1763864636252898013">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని మీ పరికర ఆపరేటింగ్ సిస్టమ్ విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
@@ -154,8 +172,10 @@
<translation id="1783075131180517613">దయచేసి మీ సింక్‌ ర‌హ‌స్య ప‌ద‌బంధాన్ని అప్‌డేట్ చేయండి.</translation>
<translation id="1787142507584202372">మీ తెరవబడిన ట్యాబ్‌లు ఇక్కడ కనిపిస్తాయి</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">కార్డుదారుని పేరు</translation>
<translation id="1821930232296380041">చెల్లని అభ్యర్థన లేదా అభ్యర్థన పారామీట‌ర్‌లు</translation>
+<translation id="1822540298136254167">మీరు సందర్శించిన వెబ్‌సైట్‌లు, వాటిపై వెచ్చించిన సమయం</translation>
<translation id="1826516787628120939">తనిఖీ చేస్తోంది</translation>
<translation id="1834321415901700177">ఈ సైట్‌లో హానికరమైన ప్రోగ్రామ్‌లు ఉన్నాయి</translation>
<translation id="1839551713262164453">విధాన విలువల క్రమబద్ధీకరణ ఎర్రర్‌లతో విఫలమైంది</translation>
@@ -173,7 +193,7 @@
<translation id="192020519938775529">{COUNT,plural, =0{ఏమీ లేవు}=1{1 సైట్}other{# సైట్‌లు}}</translation>
<translation id="1927235823738766038">ఆమోదించే క్రెడిట్ మరియు డెబిట్ కార్డ్‌లు</translation>
<translation id="194030505837763158"><ph name="LINK" />కి వెళ్లండి</translation>
-<translation id="1945968466830820669">మీరు మీ సంస్థ యొక్క ఖాతాకు యాక్సెస్‌ని కోల్పోవచ్చు లేదా గుర్తింపు చౌర్యానికి గురికావచ్చు. Chromium మీరు ఇప్పుడే మీ పాస్‌వర్డ్‌ని మార్చాల్సిందిగా సిఫార్సు చేస్తోంది.</translation>
+<translation id="1945968466830820669">మీరు మీ సంస్థ ఖాతాకు యాక్సెస్‌ను కోల్పోవచ్చు. లేదా గుర్తింపు స‌మాచారం చౌర్యానికి గురికావచ్చు. Chromium మీరు ఇప్పుడే మీ పాస్‌వర్డ్‌ను మార్చాల్సిందిగా సిఫార్సు చేస్తోంది.</translation>
<translation id="1948773908305951926">ఆమోదించబడిన ప్రీపెయిడ్ కార్డ్‌లు</translation>
<translation id="1962204205936693436"><ph name="DOMAIN" /> బుక్‌మార్క్‌లు</translation>
<translation id="1973335181906896915">శ్రేణిగా రూపొందించడంలో ఎర్రర్</translation>
@@ -182,6 +202,7 @@
<translation id="1981206234434200693">Chrome బ్రౌజింగ్ చరిత్ర డేటాని తీసివేయి</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{మరియు మరొకటి}other{మరియు మరో #}}</translation>
<translation id="2003709556000175978">ఇప్పుడే మీ పాస్‌వర్డ్‌ని రీసెట్ చేయండి</translation>
+<translation id="20053308747750172">మీరు వెళ్లాలనుకుంటున్న సర్వర్ <ph name="ORIGIN" /> దానికి చేసే అన్ని అభ్యర్థనలకు భద్రతా విధానం వర్తిస్తుందని తెలియజేసింది. కానీ అది ఇప్పుడు చెల్లుబాటు కాని విధానాన్ని డెలివరీ చేసింది, ఇది <ph name="SITE" />కోసం మీరు అభ్యర్థనను అనుమతించడంలో బ్రౌజర్‌ను నివారిస్తుంది.</translation>
<translation id="2025186561304664664">ప్రాక్సీ ఆటోమేటిక్‌గా కాన్ఫిగర్ చేయబడేలా సెట్ చేయబడింది.</translation>
<translation id="2030481566774242610">మీ ఉద్దేశ్యం <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />ప్రాక్సీ మరియు ఫైర్‌వాల్‌ను తనిఖీ చేయడం<ph name="END_LINK" /></translation>
@@ -198,6 +219,7 @@
<translation id="2096368010154057602">శాఖ</translation>
<translation id="2102134110707549001">బలమైన పాస్‌వర్డ్‌ను సూచించు…</translation>
<translation id="2108755909498034140">మీ కంప్యూటర్‌ను పునఃప్రారంభించండి</translation>
+<translation id="2111256659903765347">సూపర్-A</translation>
<translation id="2113977810652731515">కార్డ్</translation>
<translation id="2114841414352855701">ఇది <ph name="POLICY_NAME" /> ద్వారా భర్తీ చేయబడినందున విస్మరించబడింది.</translation>
<translation id="213826338245044447">మొబైల్ బుక్‌మార్క్‌లు</translation>
@@ -208,6 +230,7 @@
<translation id="2154484045852737596">కార్డ్‌ను సవరించండి</translation>
<translation id="2166049586286450108">పూర్తి నిర్వాహక యాక్సెస్</translation>
<translation id="2166378884831602661">ఈ సైట్ సురక్షితమైన కనెక్షన్‌ను అందించలేకపోయింది</translation>
+<translation id="2169984857010174799">Kaku2 (ఎన్వలప్)</translation>
<translation id="2181821976797666341">విధానాలు</translation>
<translation id="2183608646556468874">ఫోన్ నంబర్</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 చిరునామా}other{# చిరునామాలు}}</translation>
@@ -225,11 +248,15 @@
<translation id="2270484714375784793">ఫోన్ నంబర్</translation>
<translation id="2283340219607151381">చిరునామాలను సేవ్ చేసి, పూరించండి</translation>
<translation id="2292556288342944218">మీ ఇంటర్నెట్ యాక్సెస్ బ్లాక్ చేయబడింది</translation>
+<translation id="2294558542833290837">వాస్తవానికి మీరు తెరిచిన లింక్ అసాధారణంగా ఉంది</translation>
+<translation id="2297722699537546652">B5 (ఎన్వలప్)</translation>
+<translation id="2310021320168182093">Chou2 (ఎన్వలప్)</translation>
<translation id="2316887270356262533">1 MB కంటే తక్కువ స్థలాన్ని ఖాళీ చేస్తుంది. మీ తదుపరి సందర్శనలో కొన్ని సైట్‌లు మరింత నెమ్మదిగా లోడ్ కావచ్చు.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" />కు వినియోగదారు పేరు మరియు పాస్‌వర్డ్ అవసరం.</translation>
<translation id="2317583587496011522">డెబిట్ కార్డ్‌లు ఆమోదించబడతాయి.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, గడువు <ph name="EXPIRATION_DATE_ABBR" />న ముగుస్తుంది</translation>
<translation id="2337852623177822836">సెట్టింగ్‌ను మీ నిర్వాహకులు నియంత్రిస్తున్నారు</translation>
+<translation id="2346319942568447007">మీరు కాపీ చేసిన చిత్రం</translation>
<translation id="2349790679044093737">VR సెషన్ యాక్టివ్‌లో ఉంది</translation>
<translation id="2354001756790975382">ఇతర బుక్‌మార్క్‌లు</translation>
<translation id="2354430244986887761">Google సురక్షిత బ్రౌజింగ్ ఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />హానికర యాప్‌లను కనుగొంది<ph name="END_LINK" />.</translation>
@@ -238,32 +265,37 @@
<translation id="2359629602545592467">అనేకం</translation>
<translation id="2359808026110333948">కొనసాగించు</translation>
<translation id="2360873523816792727">మీ కార్డ్‌ల‌ను అన్ని పరికరాలలో ఉపయోగించాలంటే, సమకాలీకరణను ఆన్ చేయండి.</translation>
-<translation id="2365563543831475020"><ph name="CRASH_TIME" />కి క్యాప్చర్ చేసిన క్రాష్ నివేదిక అప్‌లోడ్ కాలేదు</translation>
+<translation id="2365563543831475020"><ph name="CRASH_TIME" />కు క్యాప్చ‌ర్ చేయ‌బ‌డిన‌ క్రాష్ నివేదిక అప్‌లోడ్ కాలేదు</translation>
<translation id="2367567093518048410">స్థాయి</translation>
<translation id="2378238891085281592">మీరు ప్రైవేట్ మోడ్‌లోకి వెళ్లారు</translation>
+<translation id="2380886658946992094">చట్టపరం</translation>
<translation id="2384307209577226199">ఎంటర్‌ప్రైజ్ డిఫాల్ట్</translation>
<translation id="2386255080630008482">సర్వర్ ప్రమాణపత్రం రద్దు చెయ్యబడింది.</translation>
<translation id="2392959068659972793">విలువ సెట్ చేయని విధానాలను చూపు</translation>
<translation id="239429038616798445">ఈ రవాణా పద్ధతి అందుబాటులో లేదు. వేరే పద్ధతిని ప్రయత్నించండి.</translation>
<translation id="2396249848217231973">&amp;తొలగించడాన్ని రద్దు చేయి</translation>
+<translation id="2410754574180102685">ప్రభుత్వం-న్యాయ సంబంధిత</translation>
<translation id="2413528052993050574">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం ఉపసంహరించబడి ఉండవచ్చు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="2418081434543109369">మీరు వెళ్లాలనుకుంటున్న సర్వర్ <ph name="ORIGIN" /> దానికి చేసే అన్ని అభ్యర్థనలకు భద్రతా విధానం వర్తిస్తుందని తెలియజేసింది. కానీ అది ఇప్పుడు విధానాన్ని డెలివరీ చేయడంలో విఫలమైంది, దీని వలన <ph name="SITE" /> కోసం మీ అభ్యర్థనను ఆమోదించడంలో బ్రౌజర్‌ను నివారిస్తుంది.</translation>
<translation id="244665789865330679">మీ పరికరం, ఖాతా <ph name="ENROLLMENT_DOMAIN" /> ద్వారా నిర్వహించబడతాయి. దీని ప్రకారం, మీ నిర్వాహకుడు రిమోట్ పద్ధతిలో మీ పరికరాన్ని, ఖాతాను కాన్ఫిగర్ చేయవచ్చు.</translation>
<translation id="2463193859425327265">హోమ్ పేజీని మార్చు</translation>
<translation id="2463739503403862330">పూరించు</translation>
+<translation id="2465402087343596252">ఆర్కిటెక్చర్-E</translation>
<translation id="2465655957518002998">బట్వాడా పద్ధతిని ఎంచుకోండి</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />నెట్‌వర్క్ సమస్య విశ్లేషణలను అమలు చేయడం<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">ఈ పేజీని అనువదించండి</translation>
<translation id="2479410451996844060">శోధన URL చెల్లదు.</translation>
<translation id="2482878487686419369">ప్రకటనలు</translation>
<translation id="248348093745724435">మెషీన్ విధానాలు</translation>
+<translation id="2485387744899240041">మీ పరికరం, బ్రౌజర్‌ల వినియోగదారు పేర్లు</translation>
<translation id="2491120439723279231">సర్వర్ యొక్క ప్రమాణపత్రంలో లోపాలు ఉన్నాయి.</translation>
+<translation id="2493640343870896922">లెటర్-ప్లస్</translation>
<translation id="2495083838625180221">JSON పార్సర్</translation>
<translation id="2495093607237746763">ఎంచుకుంటే, Chromium వేగవంతమైన ఫారమ్ పూరింపు కోసం ఈ పరికరంలో మీ కార్డ్ కాపీని నిల్వ చేస్తుంది.</translation>
<translation id="2498091847651709837">కొత్త కార్డ్‌ను స్కాన్ చేయండి</translation>
<translation id="2501278716633472235">వెనుకకు వెళ్ళు</translation>
<translation id="2503184589641749290">ఆమోదించబడిన డెబిట్ మరియు ప్రీపెయిడ్ కార్డ్‌లు</translation>
<translation id="2515629240566999685">మీ ప్రాంతంలో సిగ్నల్‌ను తనిఖీ చేయడం</translation>
-<translation id="2516852381693169964">చిత్రం కోసం <ph name="SEARCH_ENGINE" />లో వెతకండి</translation>
<translation id="2523886232349826891">ఈ పరికరంలో మాత్రమే సేవ్ చేయబడి ఉంటుంది</translation>
<translation id="2524461107774643265">మరింత సమాచారాన్ని జోడించండి</translation>
<translation id="2536110899380797252">చిరునామాను జోడించు</translation>
@@ -275,6 +307,7 @@
<translation id="2587841377698384444">డైరెక్టరీ API ID:</translation>
<translation id="2597378329261239068">ఈ పత్రం అనుమతి పదంచే రక్షించబడింది. దయచేసి అనుమతి పదాన్ని నమోదు చేయండి.</translation>
<translation id="2609632851001447353">వ్యత్యాసాలు</translation>
+<translation id="2618023639789766142">C10 (ఎన్వలప్)</translation>
<translation id="2625385379895617796">మీ గడియారం సమయం భవిష్యత్తులో ఉంది</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> యొక్క సర్వర్ IP చిరునామా కనుగొనబడలేదు.</translation>
<translation id="2639739919103226564">స్థితి: </translation>
@@ -284,7 +317,9 @@
<translation id="2666117266261740852">ఇతర ట్యాబ్‌లు లేదా అనువర్తనాలను మూసివేయండి</translation>
<translation id="267371737713284912">చర్యరద్దు చేయడం కోసం <ph name="MODIFIER_KEY_DESCRIPTION" /> నొక్కండి</translation>
<translation id="2674170444375937751">మీ చరిత్ర నుండి ఈ పేజీలను తొలగించదలిచారా?</translation>
+<translation id="2676271551327853224">ROC 8K</translation>
<translation id="2677748264148917807">నిష్క్రమించు</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">ఆమోదించే కార్డ్‌లు</translation>
<translation id="2702801445560668637">పఠనా జాబితా</translation>
<translation id="2704283930420550640">విలువ ఆకృతికి సరిపోలలేదు.</translation>
@@ -301,7 +336,6 @@
<translation id="2742870351467570537">ఎంచుకున్న అంశాలను తీసివేయండి</translation>
<translation id="277133753123645258">రవాణా పద్ధతి</translation>
<translation id="277499241957683684">పరికరం రికార్డ్ లేదు</translation>
-<translation id="2781030394888168909">MacOS ఫార్మాట్‌లో ఎగుమతి చేయి</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">కనెక్షన్ మళ్ళీ సెట్ చేయబడింది.</translation>
<translation id="2788784517760473862">ఆమోదించబడిన క్రెడిట్ కార్డ్‌లు</translation>
@@ -313,8 +347,10 @@
<translation id="2826760142808435982"><ph name="CIPHER" />ను ఉపయోగించి కనెక్షన్ ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది, ప్రామాణీకరించబడింది మరియు <ph name="KX" />ను కీలకమైన పరివర్తన విధానంగా ఉపయోగిస్తుంది.</translation>
<translation id="2835170189407361413">ఫారమ్‌ను క్లియర్ చేయి</translation>
<translation id="2847118875340931228">అజ్ఞాత విండోని తెరువు</translation>
+<translation id="2850739647070081192">ఆహ్వానం (ఎన్వలప్)</translation>
<translation id="2851634818064021665">ఈ సైట్‌ను సందర్శించడానికి మీకు అనుమతి అవసరం</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">కార్డ్‌ను సేవ్ చేయాలా?</translation>
<translation id="2903493209154104877">చిరునామాలు</translation>
<translation id="290376772003165898">పేజీ <ph name="LANGUAGE" />లో లేదా?</translation>
@@ -324,6 +360,7 @@
<translation id="2925673989565098301">బట్వాడా పద్ధతి</translation>
<translation id="2928905813689894207">బిల్లింగ్ చిరునామా</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">ప్రభుత్వ-లెటర్</translation>
<translation id="2941952326391522266">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం <ph name="DOMAIN2" /> నుండి జారీ చేయబడింది. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="2948083400971632585">మీరు సెట్టింగ్‌ల పేజీ నుండి కనెక్షన్ కోసం కాన్ఫిగర్ చేయబడిన ఏ ప్రాక్సీలను అయినా నిలిపివేయవచ్చు.</translation>
<translation id="2955913368246107853">కనుగొను పట్టీని మూసివేయి</translation>
@@ -340,11 +377,14 @@
<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="3023071826883856138">You4 (ఎన్వలప్)</translation>
<translation id="3024663005179499861">చెల్లని విధాన రకం</translation>
<translation id="3037605927509011580">ఆవ్, స్నాప్!</translation>
<translation id="3041612393474885105">సర్టిఫికెట్ సమాచారం</translation>
+<translation id="3060227939791841287">C9 (ఎన్వలప్)</translation>
<translation id="3064966200440839136">బాహ్య అప్లికేషన్‌ ద్వారా చెల్లించడానికి అజ్ఞాత మోడ్ నుండి నిష్క్రమిస్తోంది. కొనసాగించాలా?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ఏమీ లేవు}=1{1 పాస్‌వర్డ్}other{# పాస్‌వర్డ్‌లు}}</translation>
+<translation id="3095940652251934233">స్టేట్‌మెంట్</translation>
<translation id="3096100844101284527">పికప్ చిరునామాను జోడించండి</translation>
<translation id="3105172416063519923">అసెట్ ID:</translation>
<translation id="3109728660330352905">మీకు ఈ పేజీని వీక్షించడానికి అధికారం లేదు.</translation>
@@ -366,20 +406,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" />లో <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">చెల్లింపును రద్దు చేయండి</translation>
<translation id="3207960819495026254">బుక్‌మార్క్ చేయబడింది</translation>
-<translation id="3209375525920864198">దయచేసి చెల్లుబాటు అయ్యే సెషన్ పేరును నమోదు చేయండి.</translation>
+<translation id="321912867715453276">హెచ్చరిక: ఈ విధానంలో ఒకటి కంటే ఎక్కువ మూలాలు ఉన్నాయి, కానీ విలువలు సమానంగా ఉన్నాయి.</translation>
<translation id="3225919329040284222">అంతర్గత అంచనాలకు సరిపోలని ఒక ధృవీకరణ పత్రాన్ని సర్వర్ సమర్పించింది. మిమ్మల్ని సంరక్షించే దిశగా నిర్దిష్ట, ఉన్నత స్ధాయి భద్రతా వెబ్‌సైట్‌ల కోసం ఈ అంచనాలు చేర్చబడ్డాయి.</translation>
<translation id="3226128629678568754">పేజీని లోడ్ చేయడానికి అవసరమైన డేటాను మళ్లీ సమర్పించడం కోసం 'మళ్లీ లోడ్ చేయి' బటన్ క్లిక్ చేయండి.</translation>
<translation id="3227137524299004712">మైక్రోఫోన్</translation>
<translation id="3228969707346345236">పేజీ ఇప్పటికే <ph name="LANGUAGE" />లో ఉన్నందున అనువాదం విఫలమైంది.</translation>
+<translation id="3229041911291329567">మీ పరికరం, బ్రౌజర్‌ల వెర్షన్ సమాచారం</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="3274521967729236597">పా-కాయ్</translation>
<translation id="3282497668470633863">కార్డ్‌లో పేరుని జోడించండి</translation>
<translation id="3287510313208355388">ఆన్‌లైన్‌లో ఉన్నప్పుడు డౌన్‌లోడ్ చేయి</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> విధానం గురించి మరింత తెలుసుకోండి</translation>
<translation id="3303855915957856445">శోధన ఫలితాలు ఏవీ కనుగొనబడలేదు</translation>
-<translation id="3305707030755673451"><ph name="TIME" />న మీ సింక్‌ రహస్య పదబంధంతో మీ డేటా ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది. సింక్‌ను ప్రారంభించడానికి దీన్ని నమోదు చేయండి.</translation>
<translation id="3320021301628644560">బిల్లింగ్ చిరునామాను జోడించండి</translation>
<translation id="3324983252691184275">ముదురు ఎరుపు రంగు</translation>
<translation id="3338095232262050444">సురక్షితం</translation>
@@ -407,9 +448,11 @@
<translation id="3427342743765426898">&amp;సవరించడాన్ని పునరావృతం చేయి</translation>
<translation id="342781501876943858">మీరు మీ పాస్‌వర్డ్‌ని ఇతర సైట్‌లలో తిరిగి ఉపయోగించినట్లయితే దీనిని రీసెట్ చేయాల్సిందిగా Chromium సిఫార్సు చేస్తోంది.</translation>
<translation id="3431636764301398940">ఈ కార్డ్‌ను ఈ పరికరానికి సేవ్ చేయి</translation>
+<translation id="3443726618221119081">జుర్రో-కు-కాయ్</translation>
<translation id="3447661539832366887">ఈ పరికర యజమాని డైనోసార్ గేమ్‌ను ఆఫ్ చేసారు.</translation>
<translation id="3447884698081792621">సర్టిఫికేట్‌ను చూపు (<ph name="ISSUER" /> ద్వారా జారీ చేయబడింది)</translation>
<translation id="3452404311384756672">విరామాన్ని పొందండి:</translation>
+<translation id="3456231139987291353">నంబర్-11 (ఎన్వలప్)</translation>
<translation id="3461824795358126837">హైలైటర్</translation>
<translation id="3462200631372590220">అధునాతనం దాచు</translation>
<translation id="3467763166455606212">కార్డుదారుని పేరు అవసరం</translation>
@@ -432,34 +475,38 @@
<translation id="358285529439630156">క్రెడిట్ మరియు ప్రీపెయిడ్ కార్డ్‌లు ఆమోదించబడతాయి.</translation>
<translation id="3582930987043644930">పేరు జోడించండి</translation>
<translation id="3583757800736429874">&amp;తరలించడాన్ని పునరావృతం చేయి</translation>
+<translation id="35866233670761917">మీరు సందర్శించే వెబ్‌సైట్‌లలోని కంటెంట్‌లను మీ నిర్వాహకులు చూడలేరు</translation>
<translation id="3586931643579894722">వివరాలను దాచిపెట్టు</translation>
+<translation id="3592413004129370115">ఇటాలియన్ (ఎన్వలప్)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">పరిమాణం 2</translation>
<translation id="3615877443314183785">చెల్లుబాటు అయ్యే గడువు ముగింపు తేదీని నమోదు చేయండి</translation>
<translation id="36224234498066874">బ్రౌజింగ్ డేటాను క్లియర్ చేయి...</translation>
<translation id="362276910939193118">పూర్తి చరిత్రను చూపించు</translation>
-<translation id="3623476034248543066">విలువను చూపండి</translation>
<translation id="3630155396527302611">ఇప్పటికే ఇది నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి అనుమతించబడిన ప్రోగ్రామ్ లాగా జాబితా చేయబడి ఉంటే,
దీన్ని జాబితా నుండి తీసివేసి, ఆపై మళ్లీ జోడించి ప్రయత్నించండి.</translation>
+<translation id="3640766068866876100">సూచిక-4x6-Ext</translation>
<translation id="3650584904733503804">ప్రామాణీకరణ విజయవంతం అయింది</translation>
<translation id="3655670868607891010">మీరు దీన్ని తరచుగా చూస్తుంటే, ఈ <ph name="HELP_LINK" />ని ప్రయత్నించండి.</translation>
<translation id="3658742229777143148">పునర్విమర్శ</translation>
<translation id="366077651725703012">క్రెడిట్ కార్డ్‌ని అప్‌డేట్ చేయి</translation>
<translation id="3676592649209844519">పరికర ID:</translation>
+<translation id="3677008721441257057">మీరు &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; గురించి అభ్యర్థిస్తున్నారా?</translation>
<translation id="3678029195006412963">అభ్యర్థనకు సంతకం అందించడం సాధ్యపడలేదు</translation>
<translation id="3678529606614285348">కొత్త అజ్ఞాత విండోలో పేజీని తెరవండి (Ctrl-Shift-N)</translation>
-<translation id="3679803492151881375">క్రాష్ నివేదిక <ph name="CRASH_TIME" />కి క్యాప్చర్ చేయబడింది, <ph name="UPLOAD_TIME" />కి అప్‌లోడ్ చేయబడింది</translation>
+<translation id="3679803492151881375">క్రాష్ నివేదిక <ph name="CRASH_TIME" />కు క్యాప్చ‌ర్ చేయ‌బ‌డింది, <ph name="UPLOAD_TIME" />కు అప్‌లోడ్ చేయబడింది</translation>
<translation id="3681007416295224113">సర్టిఫికెట్ సమాచారం</translation>
<translation id="3704162925118123524">మీరు ఉపయోగించే నెట్‌వర్క్‌కు మీరు దాని లాగిన్ పేజీని సందర్శించడం అవసరం కావచ్చు.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">లోడ్ అవుతోంది...</translation>
+<translation id="3709599264800900598">మీరు కాపీ చేసిన వచనం</translation>
<translation id="3712624925041724820">లైసెన్స్‌లు అయిపోయాయి</translation>
<translation id="3714780639079136834">మొబైల్ డేటా లేదా Wi-Fiని ఆన్ చేయడం</translation>
<translation id="3715597595485130451">Wi-Fiకి కనెక్ట్ చేయండి</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ప్రాక్సీ, ఫైర్‌వాల్ మరియు DNS కాన్ఫిగరేషన్‌ను తనిఖీ చేయడం<ph name="END_LINK" /></translation>
<translation id="372429172604983730">ఈ ఎర్రర్‌కు దారితీసే అప్లికేషన్‌లలో యాంటీవైరస్, ఫైర్‌వాల్ మరియు వెబ్ ఫిల్టరింగ్ లేదా ప్రాక్సీ సాఫ్ట్‌వేర్ ఉండవచ్చు.</translation>
+<translation id="373042150751172459">B4 (ఎన్వలప్)</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="3745099705178523657">మీరు నిర్ధారించిన తర్వాత, మీ Google ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్‌తో షేర్ చేయబడతాయి.</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>
@@ -472,10 +519,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">గడువు ముగింపు <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">పరిమాణం 16</translation>
+<translation id="3797522431967816232">Prc3 (ఎన్వలప్)</translation>
<translation id="3807873520724684969">హానికర కంటెంట్ బ్లాక్ చేయబడింది.</translation>
<translation id="3810973564298564668">నిర్వహించు</translation>
<translation id="382518646247711829">మీరు ప్రాక్సీ సర్వర్‌ను ఉపయోగిస్తే...</translation>
<translation id="3828924085048779000">ఖాళీ రహస్య పదబంధం అనుమతించబడదు.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> అదనపు ఫంక్షన్‌ల కోసం ఎక్స్‌టెన్షన్‌లను ఇన్‌స్టాల్ చేసారు. మీ డేటాలో కొంత భాగానికి ఎక్స్‌టెన్షన్‌లు యాక్సెస్ కలిగి ఉంటాయి.</translation>
<translation id="385051799172605136">వెనుకకు</translation>
<translation id="3858027520442213535">తేదీని, సమయాన్ని అప్‌డేట్ చేయి</translation>
<translation id="3884278016824448484">వైరుధ్యమైన పరికరం ఐడెంటిఫైయర్</translation>
@@ -483,6 +532,7 @@
<translation id="3886446263141354045">మీరు ఈ సైట్‌ను యాక్సెస్ చేయడానికి చేసిన అభ్యర్థన <ph name="NAME" />కు పంపబడింది</translation>
<translation id="3890664840433101773">ఇమెయిల్‌ను జోడించండి</translation>
<translation id="3901925938762663762">కార్డ్ గడువు సమయం ముగిసింది</translation>
+<translation id="3906600011954732550">B5-అదనం</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">ఈ సైట్‌లో ఎల్లప్పుడూ అడగాలి</translation>
<translation id="3949571496842715403">ఈ సర్వర్ తను <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రంలో విషయ ప్రత్యామ్నాయ పేర్లు పేర్కొనబడలేదు. తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా హ్యాకర్ మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన ఇలా జరిగి ఉండవచ్చు.</translation>
@@ -493,17 +543,19 @@
<translation id="3964661563329879394">{COUNT,plural, =0{ఏవీ కాదు}=1{1 సైట్ నుండి }other{# సైట్‌ల నుండి }}</translation>
<translation id="397105322502079400">గణిస్తోంది...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> బ్లాక్ చేయబడింది</translation>
-<translation id="3984550557525787191">ఈ సెషన్ పేరు ఇప్పటికే ఉనికిలో ఉంది.</translation>
<translation id="3987940399970879459">1 MB కంటే తక్కువ</translation>
+<translation id="4008849406247176967">హెచ్చరిక: ఈ విధానంలో వైరుధ్య విలువలతో కూడిన ఒకటి కంటే ఎక్కువ మూలాలు ఉన్నాయి!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 వెబ్ పేజీ సమీపంలో ఉంది}other{# వెబ్ పేజీలు సమీపంలో ఉన్నాయి}}</translation>
<translation id="4030383055268325496">&amp;జోడించడాన్ని రద్దు చేయి</translation>
+<translation id="4032320456957708163">మీ బ్రౌజర్ <ph name="ENROLLMENT_DOMAIN" /> ద్వారా నిర్వహించబడుతోంది</translation>
<translation id="4058922952496707368">కీ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (ఎన్వలప్)</translation>
<translation id="4067947977115446013">చెల్లుబాటు అయ్యే చిరునామాను జోడించండి</translation>
<translation id="4072486802667267160">మీ ఆర్డర్‌ను ప్రాసెస్ చేస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది. దయచేసి మళ్లీ ప్రయత్నించండి.</translation>
-<translation id="4075732493274867456">క్లయింట్ మరియు సర్వర్ ఒకే SSL ప్రోటోకాల్ వెర్షన్‌ లేదా సైఫర్ సూట్‌కు మద్దతివ్వవు.</translation>
+<translation id="4075732493274867456">క్లయింట్, సర్వర్- ఒకే SSL ప్రోటోకాల్ సంస్కరణ లేదా సైఫర్ సూట్‌కు మద్దతు ఇవ్వవు.</translation>
<translation id="4079302484614802869">స్థిరమైన ప్రాక్సీ సర్వర్‌లను కాకుండా, ఒక .pac స్క్రిప్ట్ URLను ఉపయోగించేలా ప్రాక్సీ కాన్ఫిగరేషన్ సెట్ చేయబడింది.</translation>
<translation id="4098354747657067197">ముందున్న సైట్ మోసపూరితమైనది</translation>
-<translation id="4103249731201008433">పరికర క్రమ సంఖ్య చెల్లదు</translation>
+<translation id="4103249731201008433">పరికరం క్రమ సంఖ్య చెల్లదు</translation>
<translation id="410351446219883937">స్వీయ ప్లే</translation>
<translation id="4103763322291513355">బ్లాక్‌లిస్ట్‌లో ఉన్న URLల జాబితాను మరియు మీ సిస్టమ్ నిర్వాహకుని ద్వారా అమలు చేయబడిన ఇతర విధానాలను చూడటానికి &lt;strong&gt;chrome://policy&lt;/strong&gt;ని సందర్శించండి.</translation>
<translation id="4110652170750985508">మీ చెల్లింపును సమీక్షించండి</translation>
@@ -517,10 +569,12 @@
<translation id="4159784952369912983">వంగపండు రంగు</translation>
<translation id="4165986682804962316">సైట్ సెట్టింగ్‌లు</translation>
<translation id="4171400957073367226">ధృవీకరణ సంతకం చెల్లదు</translation>
+<translation id="4173315687471669144">ఫుల్‌స్కేప్</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{మరో <ph name="ITEM_COUNT" /> అంశం}other{మరో <ph name="ITEM_COUNT" /> అంశాలు}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;తరలించడాన్ని పునరావృతం చేయి</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ఫైర్‌వాల్ మరియు యాంటీవైరస్ కాన్ఫిగరేషన్‌లను తనిఖీ చేయడం<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (ఎన్వలప్)</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="4221630205957821124">&lt;h4&gt;1వ దశ: పోర్టల్‌కు సైన్ ఇన్ చేయండి&lt;/h4&gt;
@@ -552,58 +606,79 @@
<translation id="4277028893293644418">పాస్‌వర్డ్‌ను రీసెట్ చేయి</translation>
<translation id="4280429058323657511">, గడువు ముగింపు <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{ఈ కార్డ్ మీ Google ఖాతాలో సేవ్ చేయబడింది}other{ఈ కార్డ్‌లు మీ Google ఖాతాలో సేవ్ చేయబడ్డాయి}}</translation>
+<translation id="42981349822642051">విస్తరించు</translation>
+<translation id="4302965934281694568">Chou3 (ఎన్వలప్)</translation>
<translation id="4305817255990598646">స్విచ్</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">బ్లాక్ చేయి (డిఫాల్ట్)</translation>
+<translation id="4318566738941496689">మీ పరికరం పేరు, నెట్‌వర్క్ చిరునామా</translation>
<translation id="4325863107915753736">కథనాన్ని కనుగొనడం విఫలమైంది</translation>
<translation id="4326324639298822553">మీ గడువు ముగింపు తేదీని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</translation>
<translation id="4331708818696583467">సురక్షితం కాదు</translation>
<translation id="4340982228985273705">ఈ కంప్యూటర్‌ను ఎంటర్‌ప్రైజ్ నిర్వహిస్తున్నట్లు గుర్తించబడలేదు, కనుక Chrome వెబ్‌స్టోర్‌లో హోస్ట్ చేసిన ఎక్స్‌టెన్షన్‌లను మాత్రమే విధానం ఆటోమేటిక్‌గా ఇన్‌స్టాల్ చేస్తుంది. Chrome వెబ్‌స్టోర్ అప్‌డేట్ URL "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">ఆమోదించే క్రెడిట్ కార్డ్‌లు</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">ఈ సైట్‌లోని దాడి చేసేవారు మీ సమాచారాన్ని (ఉదాహరణకు, ఫోటోలు, పాస్‌వర్డ్‌లు, సందేశాలు మరియు క్రెడిట్ కార్డ్‌లు) దొంగిలించడం కోసం లేదా తొలగించడం కోసం మీ కంప్యూటర్‌లో ప్రమాదకరమైన ప్రోగ్రామ్‌లను ఇన్‌స్టాల్ చేయడానికి ప్రయత్నించవచ్చు.</translation>
<translation id="4358461427845829800">చెల్లింపు పద్ధతులను నిర్వహించండి...</translation>
+<translation id="4367563149485757821">నంబర్-12 (ఎన్వలప్)</translation>
+<translation id="4372516964750095882">ఫ్యాన్‌ఫోల్డ్-Us</translation>
<translation id="4372948949327679948">ఆశిస్తున్న <ph name="VALUE_TYPE" /> విలువ.</translation>
<translation id="4377125064752653719"><ph name="DOMAIN" />ను చేరుకోవడానికి మీరు ప్రయత్నించారు, కానీ సర్వర్ అందించిన ప్రమాణపత్రాన్ని దాన్ని జారీ చేసినవారు రద్దు చేసారు. సర్వర్ అందించిన భద్రత ఆధారాలు ఖచ్చితంగా విశ్వసించబడలేదని దీని అర్థం. మీరు దాడి చేసే వారితో కమ్యూనికేట్ చేస్తూ ఉండవచ్చు.</translation>
<translation id="4378154925671717803">ఫోన్</translation>
<translation id="4406896451731180161">శోధన ఫలితాలు</translation>
-<translation id="4406972042435603828">మీ నిర్వాహకులు శక్తివంతమైన సామర్థ్యాలతో ఎక్స్‌టెన్షన్‌లను ఇన్‌స్టాల్ చేశారు.</translation>
<translation id="4408413947728134509">కుక్కీలు <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">పికప్ చిరునామా</translation>
<translation id="4424024547088906515">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రాన్ని Chrome విశ్వసించలేదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="443121186588148776">శ్రేణీకృత పోర్ట్</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> మీ లాగిన్ ప్రమాణపత్రాన్ని ఆమోదించలేదు లేదా ఏదీ అందించి ఉండకపోవచ్చు.</translation>
<translation id="4434045419905280838">పాప్-అప్‌లు మరియు మళ్లింపులు</translation>
+<translation id="4435702339979719576">పోస్ట్‌కార్డ్)</translation>
<translation id="443673843213245140">ప్రాక్సీని ఉపయోగించడం ఆపివేయబడింది కానీ స్పష్టమైన ప్రాక్సీ కాన్ఫిగరేషన్ పేర్కొనబడింది.</translation>
<translation id="445100540951337728">ఆమోదించబడిన డెబిట్ కార్డ్‌లు</translation>
+<translation id="4466881336512663640">ఫారమ్‌లో చేసిన మార్పులను కోల్పోతారు. మీరు ఖచ్చితంగా కొనసాగాలనుకుంటున్నారా?</translation>
<translation id="4482953324121162758">ఈ సైట్ అనువదించబడదు.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">చెల్లని URL. URL తప్పనిసరిగా ఒక ప్రామాణిక స్కీమ్‌ను కలిగి ఉండాలి, ఉదా http://example.com లేదా https://example.com.</translation>
+<translation id="4503882053543859973">ఆర్కిటెక్చర్-D</translation>
<translation id="4506176782989081258">ధృవీకరణ ఎర్రర్: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">సిస్టమ్ నిర్వాహకుడిని సంప్రదించడం</translation>
<translation id="450710068430902550">నిర్వాహకుడితో షేర్‌</translation>
+<translation id="4510487217173779431">Chou4 (ఎన్వలప్)</translation>
<translation id="4515275063822566619">కార్డ్‌లు, చిరునామాలు- Chrome నుండి, మీ Google ఖాతా (<ph name="ACCOUNT_EMAIL" />) నుండి పొందినవి. మీరు <ph name="BEGIN_LINK" />సెట్టింగ్‌లు<ph name="END_LINK" />లో వాటిని నిర్వహించవచ్చు.</translation>
+<translation id="4517607026994743406">Comm-10 (ఎన్వలప్)</translation>
<translation id="4522570452068850558">వివరాలు</translation>
<translation id="4524805452350978254">కార్డ్‌లను నిర్వహించండి</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">ఫ్లాష్</translation>
<translation id="4558551763791394412">మీ పొడిగింపులను నిలిపివేయడం ప్రయత్నించండి.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">బట్వాడా</translation>
+<translation id="4579056131138995126">వ్యక్తిగతం (ఎన్వలప్)</translation>
<translation id="4582204425268416675">కార్డ్‌ని తీసివేయండి</translation>
<translation id="4587425331216688090">Chrome నుండి చిరునామాను తీసివేయాలా?</translation>
<translation id="4592951414987517459"><ph name="DOMAIN" />కు గల మీ కనెక్షన్ ఆధునిక సైఫర్ సూట్ ఉపయోగించి ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది.</translation>
<translation id="4594403342090139922">&amp;తొలగించడాన్ని రద్దు చేయి</translation>
<translation id="4597348597567598915">పరిమాణం 8</translation>
+<translation id="4600854749408232102">C6/C5 (ఎన్వలప్)</translation>
<translation id="4646534391647090355">ఇప్పుడు నన్ను అక్కడకు తీసుకు వెళ్లు</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రంలో లోపాలు ఉన్నాయి. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="467809019005607715">Google స్లయిడ్‌లు</translation>
<translation id="4690462567478992370">చెల్లని ప్రమాణపత్రాన్ని ఉపయోగించడాన్ని ఆపివేయి</translation>
+<translation id="4691835149146451662">ఆర్కిటెక్చర్-A (ఎన్వలప్)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">మీ కనెక్షన్‌కు అంతరాయం ఏర్పడింది</translation>
<translation id="471880041731876836">ఈ సైట్‌ను సందర్శించడానికి మీకు అనుమతి లేదు</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows నెట్‌వర్క్ సమస్య విశ్లేషణలను అమలు చేయడం<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">విధానాలను మళ్లీ లోడ్ చేయి</translation>
<translation id="4728558894243024398">ప్లాట్‌ఫారమ్</translation>
+<translation id="4731967714531604179">Prc2 (ఎన్వలప్)</translation>
<translation id="4736825316280949806">Chromiumని పునఃప్రారంభించండి</translation>
<translation id="473775607612524610">అప్‌డేట్‌</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> శోధన సూచన</translation>
<translation id="4742407542027196863">పాస్‌వర్డ్‌లను నిర్వహించు…</translation>
<translation id="4744603770635761495">అమలు చేయగల పాథ్‌</translation>
+<translation id="4746351372139058112">సందేశాలు</translation>
<translation id="4750917950439032686">మీ సమాచారాన్ని (ఉదాహరణకు, పాస్‌వర్డ్‌లు లేదా క్రెడిట్ కార్డ్ నంబర్‌లు) ఈ సైట్‌కు పంపినప్పుడు అది ప్రైవేట్‌గా ఉంచబడుతుంది.</translation>
<translation id="4756388243121344051">&amp;చరిత్ర</translation>
<translation id="4758311279753947758">సంప్రదింపు సమాచారాన్ని జోడించు</translation>
@@ -611,9 +686,9 @@
<translation id="4764776831041365478"><ph name="URL" /> వద్ద వెబ్‌పేజీ తాత్కాలికంగా తెరుచుకోవటం లేదు లేదా అది క్రొత్త వెబ్ చిరునామాకు శాశ్వతంగా తరలించబడి ఉండవచ్చు.</translation>
<translation id="4771973620359291008">తెలియని ఎర్రర్ ఒకటి ఏర్పడింది.</translation>
<translation id="4785689107224900852">ఈ టాబ్‌కు మారండి</translation>
-<translation id="4792143361752574037">సెషన్ ఫైల్‌లను యాక్సెస్ చేస్తున్నప్పుడు సమస్య ఏర్పడింది. ప్రస్తుతానికి డిస్క్‌లో సేవ్ చేయడం నిలిపివేయబడింది. దయచేసి మళ్లీ ప్రయత్నించడం కోసం పేజీని తిరిగి లోడ్ చేయండి.</translation>
<translation id="4798078619018708837">మీ కార్డ్ వివరాలను అప్‌డేట్ చేయడానికి <ph name="CREDIT_CARD" /> కార్డ్ గడువు ముగింపు తేదీ, CVCని నమోదు చేయండి. మీరు నిర్ధారించిన తర్వాత, మీ Google ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్‌తో షేర్ చేయబడతాయి.</translation>
<translation id="4800132727771399293">మీ గడువు ముగింపు తేదీ మరియు CVCని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</translation>
+<translation id="480334179571489655">అసలు విధానం ఎర్రర్</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>
@@ -628,7 +703,6 @@
<translation id="4881695831933465202">తెరువు</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>
@@ -637,15 +711,15 @@
<translation id="4943872375798546930">ఫలితాలు ఏవీ లేవు</translation>
<translation id="4950898438188848926">ట్యాబ్ మార్పు బటన్, తెరిచియున్న ట్యాబ్ <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" />కు మారడానికి ఎంటర్ నొక్కండి</translation>
<translation id="495170559598752135">చర్యలు</translation>
-<translation id="495832697253704892">ఎక్స్‌టెన్ష‌న్‌ నివేదన</translation>
+<translation id="4955242332710481440">A5-అదనం</translation>
<translation id="4958444002117714549">జాబితాను విస్తరించు</translation>
<translation id="4974590756084640048">హెచ్చరికలను మళ్లీ ప్రారంభించు</translation>
+<translation id="4984339528288761049">Prc5 (ఎన్వలప్)</translation>
<translation id="4989163558385430922">అన్నీ చూడండి</translation>
<translation id="4989809363548539747">ఈ ప్లగ్ఇన్‌‌కు మద్దతు లేదు</translation>
-<translation id="4996230189582812866">నివేదన</translation>
<translation id="5002932099480077015">ప్రారంభిస్తే, వేగవంతమైన ఫారమ్ పూరింపు కోసం ఈ పరికరంలో మీ కార్డ్ కాపీని నిల్వ చేస్తుంది.</translation>
-<translation id="5014174725590676422">Chromeలో Google అసిస్టెంట్ మొదటి అమలు స్క్రీన్ చూపబడింది</translation>
<translation id="5015510746216210676">మెషీన్ పేరు:</translation>
+<translation id="5017554619425969104">మీరు కాపీ చేసిన వచనం</translation>
<translation id="5018422839182700155">ఈ పేజీని తెరవడం సాధ్యపడదు</translation>
<translation id="5019198164206649151">బ్యాకింగ్ నిల్వ చెల్లని స్థితిలో ఉంది</translation>
<translation id="5023310440958281426">మీ నిర్వాహకుని విధానాలను చూడండి</translation>
@@ -655,35 +729,51 @@
<translation id="5034369478845443529">స్థానిక సందర్భం <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">అనుమతించు</translation>
<translation id="5040262127954254034">గోప్యత</translation>
+<translation id="5043480802608081735">మీరు కాపీ చేసిన లింక్</translation>
<translation id="5045550434625856497">సరికాని పాస్‌వర్డ్</translation>
<translation id="5056549851600133418">మీ కోసం కథనాలు</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ప్రాక్సీ చిరునామాను తనిఖీ చేయడం<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM వినియోగం లాంటి పరికర గణాంకాలు</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">మీ పరికరం <ph name="ENROLLMENT_DOMAIN" /> ద్వారా నిర్వహించబడుతుంది, అలాగే <ph name="ACCOUNT_DOMAIN" /> ద్వారా మీ ఖాతా నిర్వహించబడుతుంది. దీని ప్రకారం, మీ నిర్వాహకులు రిమోట్ విధానం ద్వారా మీ పరికరం, ఖాతాను కాన్ఫిగర్ చేయవచ్చు .</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">యూరోపియన్-Edp</translation>
<translation id="5115563688576182185">(64-బిట్)</translation>
-<translation id="5128122789703661928">ఈ పేరు కలిగిన సెషన్‌ను తొలగించలేరు.</translation>
+<translation id="5125394840236832993">B-ప్లస్</translation>
<translation id="5135404736266831032">చిరునామాలను నిర్వహించండి...</translation>
+<translation id="5138227688689900538">తక్కువ చూపు</translation>
<translation id="5141240743006678641">మీ Google ఆధారాలతో సింక్ చేయ‌బ‌డిన పాస్‌వర్డ్‌లను ఎన్‌క్రిప్ట్ చేయండి</translation>
<translation id="5145883236150621069">విధాన ప్రతిస్పందనలో ఎర్రర్ కోడ్ ఉంది</translation>
+<translation id="515292512908731282">C4 (ఎన్వలప్)</translation>
<translation id="5159010409087891077">కొత్త అజ్ఞాత విండోలో పేజీని తెరవండి (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> కార్డ్ CVCని నమోదు చేయండి. మీరు నిర్ధారించిన తర్వాత, మీ Google ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్‌తో షేర్ చేయబడతాయి.</translation>
-<translation id="5169827969064885044">మీరు మీ సంస్థ యొక్క ఖాతాకు యాక్సెస్‌ని కోల్పోవచ్చు లేదా గుర్తింపు చౌర్యానికి గురికావచ్చు. Chrome మీరు ఇప్పుడే మీ పాస్‌వర్డ్‌ని మార్చాల్సిందిగా సిఫార్సు చేస్తోంది.</translation>
+<translation id="5169827969064885044">మీరు మీ సంస్థ ఖాతాకు యాక్సెస్‌ను కోల్పోవచ్చు. లేదా గుర్తింపు స‌మాచారం చౌర్యానికి గురికావచ్చు. మీరు ఇప్పుడే మీ పాస్‌వర్డ్‌ను మార్చాల్సిందిగా Chrome సిఫార్సు చేస్తోంది.</translation>
<translation id="5171045022955879922">URLను వెతకండి లేదా టైప్ చేయండి</translation>
+<translation id="5171689220826475070">ఫ్యాన్‌ఫోల్డ్-యూరోపియన్</translation>
<translation id="5172758083709347301">మెషీన్</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" />లో లేదా? ఈ ఎర్రర్‌ను నివేదించండి</translation>
<translation id="5190835502935405962">బుక్‌మార్క్‌ల బార్</translation>
-<translation id="5200263511887412697">ఇటీవల లాగిన్ చేసిన పరికర వినియోగదారుల జాబితాను నివేదించండి</translation>
+<translation id="519422657042045905">అదనపు గమనిక అందుబాటులో లేదు</translation>
<translation id="5201306358585911203">ఈ పేజీలోని పొందుపరిచిన పేజీ ఇలా చెబుతోంది</translation>
<translation id="5205222826937269299">పేరు ఆవశ్యకం</translation>
<translation id="5215116848420601511">Google Payని ఉపయోగిస్తున్న చెల్లింపు పద్ధతులు మరియు చిరునామాలు</translation>
+<translation id="5215363486134917902">ఫోలియో-Sp</translation>
<translation id="5222812217790122047">ఇమెయిల్ అవ‌స‌రం</translation>
<translation id="5230733896359313003">బట్వాడా చిరునామా</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"నెట్‌వర్క్‌కు కనెక్ట్ చేయండి"</translation>
<translation id="5251803541071282808">క్లౌడ్</translation>
+<translation id="5252000469029418751">C7 (ఎన్వలప్)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">నెట్‌వర్క్ చిరునామాలు</translation>
<translation id="5285570108065881030">సేవ్ చేసిన అన్ని పాస్‌వర్డ్‌లను చూపు</translation>
<translation id="5287240709317226393">కుక్కీలను చూపించు</translation>
<translation id="5288108484102287882">విధాన విలువల క్రమబద్ధీకరణ హెచ్చరికలను జారీ చేసింది</translation>
@@ -695,7 +785,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" />లో <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">సంప్రదింపు సమాచారాన్ని ఎంచుకోండి</translation>
<translation id="5327248766486351172">పేరు</translation>
+<translation id="5329858041417644019">మీ బ్రౌజర్ నిర్వహించబడటం లేదు</translation>
<translation id="5332219387342487447">షిప్పింగ్ పద్ధతి</translation>
+<translation id="5334013548165032829">వివరణాత్మక సిస్టమ్ లాగ్‌లు</translation>
<translation id="5344579389779391559">ఈ పేజీ మీకు డబ్బు ఛార్జీ చేయడానికి ప్రయత్నించవచ్చు</translation>
<translation id="5355557959165512791"><ph name="SITE" /> యొక్క ప్రమాణపత్రం రద్దు చేయబడినందున మీరు ప్రస్తుతం దీన్ని సందర్శించలేరు. నెట్‌వర్క్ లోపాలు మరియు దాడులు సాధారణంగా తాత్కాలికమే, కనుక ఈ పేజీ తర్వాత పని చేయవచ్చు.</translation>
<translation id="536296301121032821">విధాన సెట్టింగ్‌లను నిల్వ చేయడంలో విఫలమైంది</translation>
@@ -703,6 +795,7 @@
<translation id="5377026284221673050">"మీ గడియారం ఆలస్యంగా నడుస్తోంది" లేదా "మీ గడియారం ముందుగా ఉంది" లేదా "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">మీ కార్డ్‌ల‌ను అన్ని పరికరాలలో ఉపయోగించాలంటే, సైన్ ఇన్ చేసి, సమకాలీకరణను ఆన్ చేయండి.</translation>
<translation id="5386426401304769735">ఈ సైట్ సర్టిఫికెట్ గొలుసులో SHA-1 ఉపయోగించి సంతకం చేసిన సర్టిఫికెట్ ఉంది.</translation>
+<translation id="538659543871111977">A4-ట్యాబ్</translation>
<translation id="540969355065856584">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం ప్రస్తుతం చెల్లదు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడి చేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
<translation id="5421136146218899937">బ్రౌజింగ్ డేటాను క్లియర్ చేయి...</translation>
<translation id="5430298929874300616">బుక్‌మార్క్‌ను తీసివేయండి</translation>
@@ -713,6 +806,7 @@
<translation id="5457113250005438886">చెల్లదు</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;సవరించడాన్ని పునరావృతం చేయి</translation>
+<translation id="5478437291406423475">B6/C4 (ఎన్వలప్)</translation>
<translation id="5481076368049295676">ఈ కంటెంట్ మీ సమాచారాన్ని దొంగిలించగల లేదా తొలగించగల హానికరమైన సాఫ్ట్‌వేర్‌ను మీ పరికరంలో ఇన్‌స్టాల్ చేయడానికి ప్రయత్నించవచ్చు. <ph name="BEGIN_LINK" />ఏదేమైనా చూపు<ph name="END_LINK" /></translation>
<translation id="54817484435770891">చెల్లుబాటు అయ్యే చిరునామాను జోడించండి</translation>
<translation id="5490432419156082418">చిరునామాలు మరియు మరిన్ని</translation>
@@ -720,10 +814,12 @@
<ph name="LINE_BREAK" />
మీ సిస్టమ్ నిర్వాహకుడిని సంప్రదించడానికి ప్రయత్నించండి.</translation>
<translation id="549333378215107354">పరిమాణం 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">నిర్వహించబడిన బుక్‌మార్క్‌లు</translation>
<translation id="5510766032865166053">ఇది తరలించబడి ఉండవచ్చు లేదా తొలగించబడి ఉండవచ్చు.</translation>
<translation id="5523118979700054094">విధానం పేరు</translation>
<translation id="552553974213252141">వచనం సరిగ్గా సంగ్రహించబడిందా?</translation>
+<translation id="553484882784876924">Prc6 (ఎన్వలప్)</translation>
<translation id="5540224163453853">అభ్యర్థించిన కథనాన్ని కనుగొనడం సాధ్యపడలేదు.</translation>
<translation id="5541546772353173584">ఇమెయిల్‌ను జోడించండి</translation>
<translation id="5545756402275714221">మీ కోసం కథనాలు</translation>
@@ -738,15 +834,21 @@
<translation id="5595485650161345191">చిరునామాను సవరించు</translation>
<translation id="5598944008576757369">చెల్లింపు పద్ధతిని ఎంచుకోండి</translation>
<translation id="560412284261940334">నిర్వహణకు మద్దతు లేదు</translation>
+<translation id="5605670050355397069">లెడ్జర్</translation>
+<translation id="5607240918979444548">ఆర్కిటెక్చర్-C</translation>
<translation id="5610142619324316209">కనెక్షన్‌ను తనిఖీ చేయడం</translation>
<translation id="5610807607761827392">మీరు కార్డ్‌లు మరియు చిరునామాలను <ph name="BEGIN_LINK" />సెట్టింగ్‌ల<ph name="END_LINK" />లో నిర్వహించగలరు.</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> మిమ్మల్ని అనేక సార్లు దారి మళ్లించింది.</translation>
<translation id="5629630648637658800">విధాన సెట్టింగ్‌లను లోడ్ చేయడంలో విఫలమైంది</translation>
<translation id="5631439013527180824">చెల్లని పరికర నిర్వహణ టోకెన్</translation>
+<translation id="5632627355679805402">మీ డేటా <ph name="TIME" />తేదీన మీ <ph name="BEGIN_LINK" />Google పాస్‌వర్డ్‌<ph name="END_LINK" />తో ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది. సింక్‌ చేయడం ప్రారంభించడానికి దానిని నమోదు చేయండి.</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="563324245173044180">మోసపూరిత కంటెంట్ బ్లాక్ చేయబడింది.</translation>
<translation id="5659593005791499971">ఇమెయిల్</translation>
+<translation id="5663614846592581799">9x11 (ఎన్వలప్)</translation>
+<translation id="5663955426505430495">ఈ పరికరం నిర్వాహకుడు అదనపు ఫంక్షన్‌ల కోసం ఎక్స్‌టెన్షన్‌లను ఇన్‌స్టాల్ చేసారు. మీ డేటాలో కొంత భాగానికి ఎక్స్‌టెన్షన్‌లు యాక్సెస్ కలిగి ఉంటాయి.</translation>
<translation id="5675650730144413517">ఈ పేజీ పని చేయడం లేదు</translation>
+<translation id="5684874026226664614">అయ్యో. ఈ పేజీని అనువదించడం సాధ్యపడలేదు.</translation>
<translation id="5685654322157854305">షిప్పింగ్ చిరునామాను జోడించండి</translation>
<translation id="5689199277474810259">JSONకు ఎగుమతి చేయి</translation>
<translation id="5689516760719285838">స్థానం</translation>
@@ -755,38 +857,39 @@
<translation id="5710435578057952990">ఈ వెబ్‍‌సైట్ యొక్క గుర్తింపు నిర్థారించబడలేదు.</translation>
<translation id="5719499550583120431">ప్రీపెయిడ్ కార్డ్‌లు ఆమోదించబడతాయి.</translation>
<translation id="5720705177508910913">ప్రస్తుత వినియోగదారు</translation>
+<translation id="5728056243719941842">C5 (ఎన్వలప్)</translation>
<translation id="5730040223043577876">మీరు మీ పాస్‌వర్డ్‌ని ఇతర సైట్‌లలో తిరిగి ఉపయోగించినట్లయితే దీనిని రీసెట్ చేయాల్సిందిగా Chrome సిఫార్సు చేస్తోంది.</translation>
<translation id="5732392974455271431">మీ తల్లిదండ్రులు దీన్ని మీ కోసం అన్‌బ్లాక్ చేయగలరు</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{కార్డ్‌ను మీ Google ఖాతాలో సేవ్ చేయండి}other{కార్డ్‌లను మీ Google ఖాతాలో సేవ్ చేయండి}}</translation>
<translation id="5763042198335101085">చెల్లుబాటు అయ్యే ఇమెయిల్ చిరునామాను నమోదు చేయండి</translation>
<translation id="5765072501007116331">బట్వాడా పద్ధతులు మరియు అవసరాలను చూడాలంటే, చిరునామాని ఎంచుకోండి</translation>
-<translation id="5770114862687765385">ఫైల్ పాడై ఉండవచ్చు. సెషన్‌ను రీసెట్ చేయడం కోసం 'రీసెట్ చేయి' బటన్‌ను క్లిక్ చేయండి</translation>
<translation id="5778550464785688721">MIDI పరికరాల పూర్తి నియంత్రణ</translation>
<translation id="578305955206182703">కాషాయ రంగు</translation>
<translation id="57838592816432529">మ్యూట్ చేయి</translation>
<translation id="5784606427469807560">మీ కార్డ్‌ను నిర్ధారించడంలో సమస్య ఏర్పడింది. మీ ఇంటర్నెట్ కనెక్షన్‌ని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి.</translation>
<translation id="5785756445106461925">అలాగే, ఈ పేజీలో సురక్షితం కాని ఇతర వనరులు ఉన్నాయి. ఈ వనరులను బదిలీ చేస్తున్నప్పుడు ఇతరులు చూడగలరు మరియు దాడికి పాల్పడేవారు పేజీ రూపాన్ని మార్చేలా వీటిని సవరించగలరు.</translation>
<translation id="5786044859038896871">మీరు మీ కార్డ్ సమాచారం పూరించాలనుకుంటున్నారా?</translation>
+<translation id="5798290721819630480">మార్పులను విస్మరించాలా?</translation>
<translation id="5798683403665926540">Chrome సెట్టింగ్‌లలో హోమ్ పేజీని మార్చండి</translation>
<translation id="5803412860119678065">మీరు మీ <ph name="CARD_DETAIL" /> కార్డ్ సమాచారం పూరించాలనుకుంటున్నారా?</translation>
<translation id="5804241973901381774">అనుమతులు</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" />కు గల మీ కనెక్షన్ వాడుకలో లేని సైఫర్ సూట్ ఉపయోగించి ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది.</translation>
<translation id="5813119285467412249">&amp;జోడించడాన్ని పునరావృతం చేయి</translation>
<translation id="5838278095973806738">మీరు ఈ సైట్‌లో ఎలాంటి గోప్యమైన సమాచారాన్ని నమోదు చేయకూడదు (ఉదాహరణకు, పాస్‌వర్డ్‌లు లేదా క్రెడిట్ కార్డ్‌లు), దాడికి పాల్పడేవారు ఆ సమాచారం దొంగిలించే అవకాశం ఉంటుంది.</translation>
+<translation id="5860033963881614850">ఆఫ్ అయ్యింది</translation>
<translation id="5863847714970149516">మీరు చూడబోతున్న పేజీ మీకు డబ్బు ఛార్జ్ చేయడానికి ప్రయత్నించవచ్చు</translation>
<translation id="5866257070973731571">ఫోన్ నంబర్‌ను జోడించండి</translation>
<translation id="5869405914158311789">ఈ సైట్‌ను చేరుకోలేకపోయాము</translation>
<translation id="5869522115854928033">సేవ్ చేసిన పాస్‌వర్డ్‌లు</translation>
<translation id="5887400589839399685">కార్డ్ సేవ్ చేయబడింది</translation>
-<translation id="5893718151540690985">నెట్‌వర్క్ ఇంటర్‌ఫేస్‌ల జాబితాను వాటి రకాలు, హార్డ్‌వేర్ చిరునామాలతో నివేదిస్తుంది</translation>
<translation id="5893752035575986141">క్రెడిట్ కార్డ్‌లు ఆమోదించబడతాయి.</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="5916664084637901428">ఆన్ చేయి</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Google ఖాతాకు కార్డ్‌ను సేవ్ చేయాలా?</translation>
<translation id="5922853866070715753">దాదాపు పూర్తయింది</translation>
<translation id="5932224571077948991">సైట్ అనుచితమైన లేదా తప్పుదారి పట్టించే ప్రకటనలను చూపుతుంది</translation>
-<translation id="5939518447894949180">రీసెట్ చేయి</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> తెరవబడుతోంది…</translation>
<translation id="5951495562196540101">వినియోగదారు ఖాతాతో నమోదు చేయడం సాధ్యపడదు (ప్యాకేజ్డ్ లైసెన్స్ అందుబాటులో ఉంది).</translation>
<translation id="5967592137238574583">సంప్రదింపు సమాచారాన్ని సవరించండి</translation>
@@ -794,6 +897,7 @@
<translation id="5975083100439434680">దూరంగా జూమ్ చెయ్యి</translation>
<translation id="5977489021191000276">మీ పరికరం నిర్వాహకుడితో నిర్వహించబడదు.</translation>
<translation id="5977976211062815271">ఈ పరికరంలో</translation>
+<translation id="5980920751713728343">సూచిక-3x5</translation>
<translation id="598637245381783098">చెల్లింపు యాప్‌ను తెరవడం సాధ్యం కాదు</translation>
<translation id="5989320800837274978">స్థిర ప్రాక్సీ సర్వర్‌లు లేదా ఒక .pac స్క్రిప్ట్ URL పేర్కొనబడలేదు.</translation>
<translation id="5990559369517809815">సర్వర్‌కు అభ్యర్థనలను ఒక ఎక్సటెన్షన్ బ్లాక్ చేయబడ్డాయి.</translation>
@@ -804,8 +908,8 @@
<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="6033927989869462158">CPU/RAM వినియోగం లాంటి హార్డ్‌వేర్ గణాంకాలను నివేదిస్తుంది</translation>
<translation id="6034000775414344507">లేత బూడిద రంగు</translation>
+<translation id="6034283069659657473">10x14 (ఎన్వలప్)</translation>
<translation id="6039846035001940113">సమస్య కొనసాగుతుంటే, సైట్ యజమానిని సంప్రదించండి.</translation>
<translation id="6040143037577758943">మూసివేయి</translation>
<translation id="6044573915096792553">పరిమాణం 12</translation>
@@ -814,10 +918,10 @@
<translation id="6051221802930200923">ప్రమాణపత్రాన్ని పిన్ చేసే పద్ధతిని వెబ్‌సైట్ ఉపయోగిస్తుంది కనుక మీరు ప్రస్తుతానికి <ph name="SITE" /> ను సందర్శించలేరు. నెట్‌వర్క్ లోపాలు మరియు దాడులు సాధారణంగా తాత్కాలికమే, కనుక ఈ పేజీ తర్వాత పని చేయవచ్చు.</translation>
<translation id="6058977677006700226">మీ కార్డ్‌లను మీ అన్ని పరికరాలలో ఉపయోగించాలా?</translation>
<translation id="6059925163896151826">USB పరికరాలు</translation>
-<translation id="6071091556643036997">విధాన రకం చెల్లదు.</translation>
<translation id="6080696365213338172">మీరు నిర్వాహకుని ద్వారా అందించబడిన ప్రమాణపత్రాన్ని ఉపయోగించి కంటెంట్‌ను యాక్సెస్ చేసారు. మీరు <ph name="DOMAIN" />కు అందించే డేటాకు మీ నిర్వాహకుని ద్వారా అంతరాయం ఏర్పడవచ్చు.</translation>
<translation id="6094273045989040137">అదనపు గమనికను జోడించండి</translation>
<translation id="610911394827799129">మీ Google ఖాతా <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />లో ఇతర రూపాల్లో ఉన్న బ్రౌజింగ్ చరిత్రను కలిగి ఉండవచ్చు</translation>
+<translation id="6132597952260690497">ఇన్‌స్టాల్ చేసిన ఎక్స్‌టెన్షన్‌లు, ప్లగ్ఇన్‌ల గురించిన సమాచారం</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ఏమీ లేవు}=1{1 పాస్‌వర్డ్ (సమకాలీకరించబడింది)}other{# పాస్‌వర్డ్‌లు (సమకాలీకరించబడ్డాయి)}}</translation>
<translation id="6146055958333702838">ఏవైనా కేబుల్‌లను తనిఖీ చేయండి మరియు మీరు ఉపయోగించే ఏవైనా రూటర్‌లు, మోడెమ్‌లు
లేదా ఇతర నెట్‌వర్క్ పరికరాలను రీబూట్ చేయండి.</translation>
@@ -839,7 +943,7 @@
<translation id="6264485186158353794">భద్రతకు తిరిగి వెళ్ళు</translation>
<translation id="6266934640124581640">లేత నీలి ఆకుపచ్చ రంగు</translation>
<translation id="6276112860590028508">మీ పఠన జాబితాలో ఉన్న పేజీలు ఇక్కడ కనిపిస్తాయి</translation>
-<translation id="627746635834430766">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్ మరియు బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు సేవ్ చేయండి.</translation>
+<translation id="627746635834430766">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్, బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు సేవ్ చేయండి.</translation>
<translation id="6280223929691119688">ఈ చిరునామాకు బట్వాడా చేయడం సాధ్యం కాదు. వేరే చిరునామాని ఎంచుకోండి.</translation>
<translation id="6282194474023008486">పోస్టల్ కోడ్</translation>
<translation id="6290238015253830360">మీకు సూచించిన కథనాలు ఇక్కడ కనిపిస్తాయి</translation>
@@ -852,15 +956,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> కంటే తక్కువ స్థలాన్ని ఖాళీ చేస్తుంది. మీ తదుపరి సందర్శనలో కొన్ని సైట్‌లు మరింత నెమ్మదిగా లోడ్ కావచ్చు.</translation>
<translation id="6337534724793800597">పేరు ద్వారా విధానాలను ఫిల్టర్ చేయి</translation>
<translation id="6358450015545214790">దీని అర్ధం ఏమిటి?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">కొనసాగించడం వల్ల ఛార్జ్‌లు చెల్లించాల్సి రావచ్చు.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 ఇతర సూచన}other{# ఇతర సూచనలు}}</translation>
-<translation id="6387754724289022810">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్ మరియు బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు మరియు ఈ పరికరానికి సేవ్ చేయండి.</translation>
+<translation id="6387754724289022810">తర్వాతిసారి మరింత వేగంగా చెల్లించడానికి, మీ కార్డ్, బిల్లింగ్ చిరునామాను మీ Google ఖాతాకు, ఈ పరికరానికి సేవ్ చేయండి.</translation>
+<translation id="6390662030813198813">ఇంజనీరింగ్-E</translation>
<translation id="6404511346730675251">బుక్‌మార్క్‌ను సవరించు</translation>
+<translation id="6406765186087300643">C0 (ఎన్వలప్)</translation>
<translation id="6410264514553301377"><ph name="CREDIT_CARD" /> గడువు ముగింపు తేదీ మరియు CVCని నమోదు చేయండి</translation>
<translation id="6414888972213066896">మీరు ఈ సైట్‌ను సందర్శించడానికి అనుమతించమని కోరుతూ మీ తల్లి/తండ్రికి అభ్యర్థన పంపారు</translation>
<translation id="6417515091412812850">ప్రమాణపత్రం రద్దు చెయ్యబడిందా అని తనిఖీ చెయ్యడం సాధ్యం కాలేదు.</translation>
<translation id="6433490469411711332">సంప్రదింపు సమాచారాన్ని సవరించండి</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> కనెక్ట్ కావడానికి నిరాకరించింది.</translation>
+<translation id="6434309073475700221">తొలగించు</translation>
+<translation id="6446163441502663861">Kahu (ఎన్వలప్)</translation>
<translation id="6446608382365791566">మరింత సమాచారాన్ని జోడించండి</translation>
<translation id="6447842834002726250">కుక్కీలు</translation>
<translation id="6451458296329894277">ఫారమ్ పునఃసమర్పణను నిర్థారించండి</translation>
@@ -873,11 +983,17 @@
<translation id="6508722015517270189">Chromeను పునఃప్రారంభించండి</translation>
<translation id="6529602333819889595">&amp;తొలగించడాన్ని పునరావృతం చేయి</translation>
<translation id="6534179046333460208">ప్రత్యక్ష వెబ్ సూచనలు</translation>
+<translation id="6556866813142980365">మళ్లీ చేయి</translation>
<translation id="6563469144985748109">మీ నిర్వాహకుడు దీన్ని ఇంకా ఆమోదించలేదు</translation>
<translation id="6569060085658103619">మీరు పొడిగింపు పేజీని వీక్షిస్తున్నారు</translation>
+<translation id="6578796323535178455">C2 (ఎన్వలప్)</translation>
<translation id="6579990219486187401">లేత గులాబీ రంగు</translation>
+<translation id="6583674473685352014">B6 (ఎన్వలప్)</translation>
+<translation id="6587923378399804057">మీరు కాపీ చేసిన లింక్</translation>
+<translation id="6591833882275308647">మీ <ph name="DEVICE_TYPE" /> నిర్వహించబడటం లేదు</translation>
<translation id="6596325263575161958">ఎన్‌క్రిప్షన్ ఎంపికలు</translation>
<translation id="6604181099783169992">చలనం లేదా కాంతి సర్దుబాటు సెన్సార్‌లు</translation>
+<translation id="6609880536175561541">Prc7 (ఎన్వలప్)</translation>
<translation id="6624427990725312378">సంప్రదింపు సమాచారం</translation>
<translation id="6626291197371920147">చెల్లుబాటయ్యే కార్డ్ నంబర్‌ను జోడించండి</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> శోధన</translation>
@@ -886,6 +1002,7 @@
<translation id="6644283850729428850">ఈ విధానం విస్మరించబడింది.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ఏవీ లేవు}=1{1 సైట్ నుండి (మీరు మీ Google ఖాతా నుండి సైన్ అవుట్ చేయబడరు)}other{# సైట్‌ల నుండి (మీరు మీ Google ఖాతా నుండి సైన్ అవుట్ చేయబడరు)}}</translation>
<translation id="6657585470893396449">పాస్‌వర్డ్</translation>
+<translation id="6670613747977017428">భద్రతకు తిరిగి వెళ్ళు.</translation>
<translation id="6671697161687535275">Chromium నుండి ఫారమ్ సూచనను తీసివేయాలా?</translation>
<translation id="6685834062052613830">సైన్ అవుట్ చేసి, సెటప్‌ను పూర్తి చేయండి</translation>
<translation id="6710213216561001401">మునుపటి</translation>
@@ -893,12 +1010,15 @@
<translation id="671076103358959139">నమోదు టోకెన్:</translation>
<translation id="6711464428925977395">ప్రాక్సీ సర్వర్‌లో ఏదో తప్పు ఉంది లేదా చిరునామా సరైనది కాదు.</translation>
<translation id="6723740634201835758">మీ Google ఖాతాలో</translation>
+<translation id="6738516213925468394"><ph name="TIME" /> తేదీన మీ <ph name="BEGIN_LINK" />సింక్‌ రహస్య పదబంధం <ph name="END_LINK" />తో మీ డేటా ఎన్‌క్రిప్ట్ చేయ‌బ‌డింది. సింక్‌ను ప్రారంభించడానికి దీన్ని నమోదు చేయండి.</translation>
<translation id="674375294223700098">తెలియని సర్వర్ ప్రమాణపత్రం లోపం.</translation>
<translation id="6744009308914054259">కనెక్షన్ కోసం వేచి ఉన్నప్పుడు, మీరు ఆఫ్‌లైన్ కథనాలను చదవడానికి డౌన్‌లోడ్‌లను సందర్శించవచ్చు.</translation>
<translation id="6753269504797312559">విధానం విలువ</translation>
<translation id="6757797048963528358">మీ పరికరం నిద్రావస్థకు వెళ్లింది.</translation>
+<translation id="6768213884286397650">హగకి (పోస్ట్‌కార్డ్)</translation>
<translation id="6778737459546443941">మీ తల్లి/తండ్రి దీన్ని ఇంకా ఆమోదించలేదు</translation>
<translation id="67862343314499040">నీలి ఊదా రంగు</translation>
+<translation id="6786747875388722282">ఎక్స్‌టెన్షన్‌లు</translation>
<translation id="679355240208270552">విధానం ప్రకారం డిఫాల్ట్ శోధన ప్రారంభించబడలేదు కాబట్టి, ఇది విస్మరించబడింది.</translation>
<translation id="681021252041861472">అవసరమైన ఫీల్డ్</translation>
<translation id="6810899417690483278">అనుకూలీకరణ ID</translation>
@@ -931,10 +1051,12 @@
<translation id="6965978654500191972">పరికరం</translation>
<translation id="6970216967273061347">జిల్లా</translation>
<translation id="6973656660372572881">రెండు స్థిర ప్రాక్సీ సర్వర్లు మరియు ఒక .pac స్క్రిప్ట్ URL పేర్కొనబడ్డాయి.</translation>
+<translation id="6973932557599545801">క్షమించండి నేను సహాయం చేయలేకపోయాను, దయచేసి మీరే స్వంతంగా కొనసాగండి.</translation>
<translation id="6979158407327259162">Google డిస్క్</translation>
<translation id="6979440798594660689">మ్యూట్ (డిఫాల్ట్)</translation>
<translation id="6984479912851154518">బాహ్య అప్లికేషన్ ద్వారా చెల్లించడానికి ప్రైవేట్ మోడ్ నుండి నిష్క్రమిస్తోంది. కొనసాగించాలా?</translation>
<translation id="6989763994942163495">అధునాతన సెట్టింగ్‌లను చూపించు...</translation>
+<translation id="6993898126790112050">6x9 (ఎన్వలప్)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" />భాషలోని కంటెంట్‌ను ఎల్లప్పుడూ అనువదించు</translation>
<translation id="7012363358306927923">చైనా యూనియన్ పే</translation>
<translation id="7016992613359344582">ఈ ఛార్జ్‌లు ఒకే సారి చెల్లించేవి లేదా పునరావృతంగా చెల్లించాల్సినవి కావచ్చు మరియు స్పష్టంగా పేర్కొనబడకపోవచ్చు.</translation>
@@ -950,28 +1072,33 @@
<translation id="7108338896283013870">దాచిపెట్టు</translation>
<translation id="7108819624672055576">పొడిగింపు ద్వారా అనుమతించబడింది</translation>
<translation id="7111012039238467737">(చెల్లుతుంది)</translation>
+<translation id="7118618213916969306">క్లిప్‌బోర్డ్ URL, <ph name="SHORT_URL" /> కోసం వెతకండి</translation>
<translation id="7119414471315195487">ఇతర ట్యాబ్‌లు లేదా ప్రోగ్రామ్‌లను మూసివేయండి</translation>
<translation id="7129409597930077180">ఈ చిరునామాకు రవాణా చేయడం సాధ్యం కాదు. వేరే చిరునామాని ఎంచుకోండి.</translation>
<translation id="7135130955892390533">స్థితిని చూపు</translation>
<translation id="7138472120740807366">బట్వాడా పద్ధతి</translation>
<translation id="7139724024395191329">ఎమిరేట్</translation>
+<translation id="7152423860607593928">నంబర్-14 (ఎన్వలప్)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">లావెండర్ రంగు</translation>
-<translation id="7158980942472052083">చెల్లని URL. తప్పక ప్రామాణిక స్కీమ్‌ని కలిగిన URL అయి ఉండాలి.</translation>
<translation id="717330890047184534">Gaia ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">మీరు వెళ్లాలనుకుంటున్న సర్వర్ <ph name="ORIGIN" /> దానికి చేసే అన్ని అభ్యర్థనలకు భద్రతా విధానం వర్తిస్తుందని తెలియజేసింది. కానీ విధానాన్ని డెలివరీ చేయడానికి బదులు అది బ్రౌజర్‌ను మరెక్కడికో మళ్లించింది, దీని వలన <ph name="SITE" /> కోసం మీ అభ్యర్థనను పూర్తి చేయకుండా బ్రౌజర్‌ను నివారిస్తుంది.</translation>
<translation id="7179323680825933600">చెల్లింపు పద్ధతులను సేవ్ చేసి, పూరించు</translation>
<translation id="7180611975245234373">రిఫ్రెష్ చేయి</translation>
<translation id="7182878459783632708">విధానాలను సెట్ చేయలేదు</translation>
<translation id="7186367841673660872">ఈ పేజీ<ph name="ORIGINAL_LANGUAGE" />నుండి<ph name="LANGUAGE_LANGUAGE" />కు అనువదించబడింది</translation>
<translation id="7192203810768312527"><ph name="SIZE" />ను ఖాళీ చేస్తుంది. మీ తదుపరి సందర్శనలో కొన్ని సైట్‌లు మరింత నెమ్మదిగా లోడ్ కావచ్చు.</translation>
<translation id="719464814642662924">వీసా</translation>
+<translation id="7201591969684833065">మీ నిర్వాహకుడు వీటిని చూడగలరు:</translation>
+<translation id="7202346780273620635">లెటర్-అదనం</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> భద్రతా ప్రమాణాలకు కట్టుబడి లేదు.</translation>
<translation id="721197778055552897">ఈ సమస్య గురించి <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి <ph name="END_LINK" />.</translation>
<translation id="7219179957768738017">కనెక్షన్ <ph name="SSL_VERSION" />ని ఉపయోగిస్తుంది.</translation>
<translation id="7220786058474068424">ప్రాసెస్ చేస్తోంది</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">ముందున్న సైట్‌లో మాల్వేర్ ఉంది</translation>
+<translation id="724766306220616965">హెచ్చరికలు, వైరుధ్యం</translation>
<translation id="724975217298816891">మీ కార్డ్ వివరాలను అప్‌డేట్ చేయడానికి <ph name="CREDIT_CARD" /> కార్డ్ గడువు ముగింపు తేదీ మరియు CVCని నమోదు చేయండి. మీరు నిర్ధారించిన తర్వాత, మీ కార్డ్ వివరాలు ఈ సైట్‌తో షేర్ చేయబడతాయి.</translation>
<translation id="7251437084390964440">నెట్‌వర్క్ కాన్ఫిగరేషన్ ONC ప్రమాణానికి అనుకూలంగా లేదు. కాన్ఫిగరేషన్‌లోని భాగాలు దిగుమతి కాకపోయి ఉండకపోవచ్చు.
అదనపు వివరాలు:
@@ -983,12 +1110,15 @@
<translation id="7298195798382681320">సిఫార్సు చేయబడినవి</translation>
<translation id="7300012071106347854">నల్ల కావిరాయి నీలం</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
-<translation id="7309308571273880165"><ph name="CRASH_TIME" /> తేదీన క్యాప్చర్ చేసిన క్రాష్ నివేదిక (అప్‌లోడ్ చేయాల్సిందిగా వినియోగదారుకు అభ్యర్థన, ఇంకా అప్‌లోడ్ చేయలేదు)</translation>
+<translation id="7309308571273880165"><ph name="CRASH_TIME" /> తేదీన క్యాప్చ‌ర్ చేయ‌బ‌డిన‌ క్రాష్ నివేదిక (అప్‌లోడ్ చేయాల్సిందిగా వినియోగదారుకు అభ్యర్థన, ఇంకా అప్‌లోడ్ చేయలేదు)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />సురక్షిత బ్రౌజింగ్<ph name="END_LINK" /> హెచ్చరికలు</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">కనెక్షన్ సహాయం</translation>
<translation id="7334320624316649418">&amp;మళ్లీ క్రమం చేయడాన్ని పునరావృతం చేయి</translation>
<translation id="733923710415886693">సర్వర్ ప్రమాణపత్రాన్ని ప్రమాణపత్రం పారదర్శకత ద్వారా బహిరంగపరచలేదు.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-అదనం</translation>
<translation id="7353601530677266744">ఆదేశ పంక్తి</translation>
-<translation id="7365061714576910172">Linux ఫార్మాట్‌లో ఎగుమతి చేయి</translation>
<translation id="7372973238305370288">శోధన ఫలితం</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">వద్దు</translation>
@@ -996,17 +1126,18 @@
<translation id="7381288752349550461">నిర్వహిత సెషన్ భర్తీ</translation>
<translation id="7390545607259442187">కార్డ్‌ని నిర్ధారించండి</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120">మీ <ph name="DEVICE_NAME" /> నిర్వహించబడుతోంది</translation>
<translation id="7407424307057130981">&lt;p&gt;మీ Windows కంప్యూటర్‌లో Superfish సాఫ్ట్‌వేర్ ఉన్నట్లయితే మీకు ఈ ఎర్రర్ కనిపిస్తుంది.&lt;/p&gt;
- &lt;p&gt;మీరు వెబ్‌లోకి వెళ్లడం కోసం, సాఫ్ట్‌వేర్‌ని తాత్కాలికంగా నిలిపివేయడానికి ఈ దశలను అనుసరించండి. మీ వద్ద నిర్వాహకుడి స్థాయి అధికారాలు ఉండాలి.&lt;/p&gt;
+ &lt;p&gt;మీరు వెబ్‌లోకి వెళ్లడం కోసం, సాఫ్ట్‌వేర్‌ను తాత్కాలికంగా నిలిపివేయడానికి ఈ దశలను అనుసరించండి. మీ వద్ద నిర్వాహకుడి స్థాయి అధికారాలు ఉండాలి.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ప్రారంభించు&lt;/strong&gt;ను క్లిక్ చేసి, ఆపై &lt;strong&gt;"స్థానిక సేవలను వీక్షించండి"&lt;/strong&gt; కోసం వెతికి, దానిని ఎంచుకోండి
&lt;li&gt;&lt;strong&gt;VisualDiscovery&lt;/strong&gt;ని ఎంచుకోండి
&lt;li&gt;&lt;strong&gt;ప్రారంభ రకం&lt;/strong&gt;లో, &lt;strong&gt;నిలిపివేయబడింది&lt;/strong&gt; ఎంచుకోండి
&lt;li&gt;&lt;strong&gt;సేవా స్థితి&lt;/strong&gt;లో, &lt;strong&gt;ఆపివేయి&lt;/strong&gt;ని క్లిక్ చేయండి
&lt;li&gt;&lt;strong&gt;వర్తింపజేయి&lt;/strong&gt;ని క్లిక్ చేసి, ఆపై &lt;strong&gt;సరే&lt;/strong&gt; క్లిక్ చేయండి
- &lt;li&gt;మీ కంప్యూటర్ నుండి శాశ్వతంగా సాఫ్ట్‌వేర్‌ను ఎలా తొలగించాలో తెలుసుకోవడానికి &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome సహాయ కేంద్రం&lt;/a&gt;ను సందర్శించండి
+ &lt;li&gt;మీ కంప్యూటర్ నుండి శాశ్వతంగా సాఫ్ట్‌వేర్‌ను ఎలా తొలగించాలో తెలుసుకోవడానికి &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome సహాయ కేంద్రం&lt;/a&gt;ని సందర్శించండి
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> నిర్వహణ</translation>
+<translation id="741007362987735528">వెడల్పైన-ఫార్మాట్</translation>
<translation id="7416351320495623771">పాస్‌వర్డ్‌లను నిర్వహించండి…</translation>
<translation id="7419106976560586862">ప్రొఫైల్ మార్గం</translation>
<translation id="7437289804838430631">సంప్రదింపు సమాచారాన్ని జోడించు</translation>
@@ -1015,22 +1146,24 @@
<translation id="7442725080345379071">లేత నారింజ రంగు</translation>
<translation id="7444046173054089907">ఈ సైట్ బ్లాక్ చేయబడింది</translation>
<translation id="7445762425076701745">మీరు కనెక్ట్ చేసిన సర్వర్ యొక్క గుర్తింపు పూర్తిగా ధృవీకరించబడలేదు. మీరు దీని యొక్క యాజమాన్యాన్ని ధృవీకరించడానికి అంతర్గత ప్రమాణపత్రం అధికారికి మరొక దాని లేని మీ నెట్‌వర్క్‌లో మాత్రమే చెల్లుబాటు అయ్యే పేరును ఉపయోగించి సర్వర్‌కి కనెక్ట్ చేసారు. కొన్ని ప్రమాణపత్రం అధికారులు సంబంధంలేని ఈ పేర్లకు ప్రమాణపత్రాన్ని జారీ చేస్తారు, మీరు సరైన వెబ్‌సైట్‌కు మరియు అటాకర్‌కి కనెక్ట్ చేసారా అని నిర్ధారించడానికి వేరే మార్గం లేదు.</translation>
-<translation id="7449109375006139765">సిస్టమ్ లాగ్‌లను నిర్వహణ సర్వర్‌కు పంపుతుంది</translation>
<translation id="7451311239929941790">ఈ సమస్య గురించి <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" />.</translation>
<translation id="7455133967321480974">సార్వజనీన డిఫాల్ట్‌ను ఉపయోగించు (బ్లాక్ చేయి)</translation>
<translation id="7460618730930299168">మీరు ఎంచుకున్నది మరియు స్క్రీనింగ్ చేస్తున్నది వేరుగా ఉన్నాయి. కొనసాగించాలా?</translation>
<translation id="7473891865547856676">వద్దు, ధన్యవాదాలు</translation>
-<translation id="7475525192983021547">పరికరంలో వినియోగదారు యాక్టివ్‌గా ఉన్నప్పుడు కాల వ్యవధులను నివేదిస్తుంది</translation>
<translation id="7481312909269577407">ఫార్వర్డ్</translation>
<translation id="7485870689360869515">డేటా కనుగొనబడలేదు.</translation>
+<translation id="7498234416455752244">సవరణను కొనసాగించు</translation>
<translation id="7508255263130623398">అందించబడిన విధాన పరికర id ఖాళీగా ఉంది లేదా ప్రస్తుత పరికర idకి సరిపోలలేదు</translation>
<translation id="7508870219247277067">వెన్నపండు ఆకుపచ్చ</translation>
<translation id="7511955381719512146">మీరు ఉపయోగిస్తున్న Wi-Fiకు మీరు<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ను సందర్శించడం అవసరం.</translation>
<translation id="7514365320538308">డౌన్‌లోడ్ చేయి</translation>
<translation id="7518003948725431193">వెబ్ చిరునామాకు వెబ్‌పేజీ కనుగొనబడలేదు: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (ఎన్వలప్)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">ఈ సైట్‌తో మీకున్న కనెక్షన్ ప్రైవేట్‌గా లేదు</translation>
+<translation id="7535087603100972091">విలువ</translation>
<translation id="7537536606612762813">తప్పనిసరి</translation>
+<translation id="7538364083937897561">A2 (ఎన్వలప్)</translation>
<translation id="7542403920425041731">మీరు నిర్ధారించిన తర్వాత, మీ కార్డ్ వివరాలు ఈ సైట్‌తో షేర్ చేయబడతాయి.</translation>
<translation id="7542995811387359312">ఈ ఫారమ్ సురక్షిత కనెక్షన్‌ను ఉపయోగించనందున క్రెడిట్ కార్డ్ వివరాలను ఆటోమేటిక్‌గా పూర్తి చేయడం ఆపివేయబడింది.</translation>
<translation id="7543525346216957623">మీ తల్లి/తండ్రిని అడగండి</translation>
@@ -1039,8 +1172,8 @@
<translation id="7552846755917812628">క్రింది చిట్కాలను ప్రయత్నించండి:</translation>
<translation id="7554791636758816595">కొత్త ట్యాబ్</translation>
<translation id="7564049878696755256">మీరు మీ <ph name="ORG_NAME" /> ఖాతాకు యాక్సెస్‌ని కోల్పోవచ్చు లేదా గుర్తింపు చోరీకి గురి కావచ్చు. మీ పాస్‌వర్డ్‌ని ఇప్పుడే రీసెట్ చేయాల్సిందిగా Chrome సిఫార్సు చేస్తోంది.</translation>
-<translation id="7566125604157659769">మీరు కాపీ చేసిన వచనం</translation>
<translation id="7567204685887185387">ఈ సర్వర్ <ph name="DOMAIN" /> అని నిరూపించుకోలేకపోయింది; దీని భద్రతా ప్రమాణపత్రం మోసపూరితంగా జారీ అయ్యి ఉండవచ్చు. ఇది తప్పుగా కాన్ఫిగర్ చేయడం వలన లేదా దాడిచేసే వ్యక్తి మీ కనెక్షన్‌కు అంతరాయం కలిగించడం వలన జరిగి ఉండవచ్చు.</translation>
+<translation id="7568105740864181217">ఈ బ్రౌజర్ కంపెనీ, పాఠశాల లేదా ఇతర సంస్థ ద్వారా నిర్వహించబడుతోంది. మీ నిర్వాహకుడు మీ బ్రౌజర్ సెటప్‌ను రిమోట్ విధానంలో మార్చవచ్చు. ఈ పరికరంలోని కార్యకలాపం Chrome వెలుపల కూడా నిర్వహిస్తుండవచ్చు. <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Chrome నుండి క్రెడిట్ కార్డ్‌ను తీసివేయాలా?</translation>
<translation id="7569983096843329377">నలుపు</translation>
<translation id="7578104083680115302">మీరు Googleతో సేవ్ చేసిన కార్డ్‌లను ఉపయోగించి పరికరాల్లోని సైట్‌లు మరియు అనువర్తనాల్లో శీఘ్రంగా చెల్లించండి.</translation>
@@ -1050,7 +1183,8 @@
<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="7615602087246926389">మీకు ఇప్పటికే మీ Google ఖాతా పాస్‌వర్డ్ యొక్క మరొక వెర్ష‌న్‌ను ఉపయోగించి ఎన్‌క్రిప్ట్ అయిన డేటా ఉంది. దయచేసి దాన్ని దిగువ నమోదు చేయండి.</translation>
+<translation id="7633909222644580952">పనితీరు డేటా, క్రాష్ నివేదికలు</translation>
<translation id="7637571805876720304">Chromium నుండి క్రెడిట్ కార్డ్‌ను తీసివేయాలా?</translation>
<translation id="7639968568612851608">ముదురు బూడిద రంగు</translation>
<translation id="765676359832457558">అధునాతన సెట్టింగ్‌లను దాచు...</translation>
@@ -1060,9 +1194,11 @@
<translation id="7667346355482952095">అందించిన విధాన టోకెన్ ఖాళీగా ఉంది లేదా ప్రస్తుత టోకెన్‌తో సరిపోలలేదు</translation>
<translation id="7668654391829183341">తెలియని పరికరం</translation>
<translation id="7669271284792375604">ఈ సైట్‌లోని దాడి చేసేవారు మీ బ్రౌజింగ్ అనుభవానికి (ఉదాహరణకు, మీ హోమ్ పేజీని మార్చడం లేదా మీరు సందర్శించే సైట్‌ల్లో అదనపు ప్రకటనలను చూపడం ద్వారా) హాని కలిగించే ప్రోగ్రామ్‌లను ఇన్‌స్టాల్ చేసే విధంగా మిమ్మల్ని మోసగించడానికి ప్రయత్నించవచ్చు.</translation>
+<translation id="7676643023259824263">క్లిప్‌బోర్డ్ వచనం, <ph name="TEXT" /> కోసం వెతకండి</translation>
<translation id="7681101578153515023">శోధన ఇంజిన్‌ను మార్చు</translation>
<translation id="7682287625158474539">ఓడ రవాణా</translation>
<translation id="7687186412095877299">సేవ్ చేయబడిన మీ చెల్లింపు పద్ధతులతో చెల్లింపు ఫారమ్‌లను పూరిస్తుంది</translation>
+<translation id="7697066736081121494">Prc8 (ఎన్వలప్)</translation>
<translation id="769721561045429135">ఇప్పుడు, కేవలం ఈ పరికరంలో మాత్రమే ఉపయోగించగల కార్డ్‌లు మీ వద్ద ఉన్నాయి. కార్డ్‌లను సమీక్షించడం కోసం కొనసాగించుని క్లిక్ చేయండి.</translation>
<translation id="7699293099605015246">ప్రస్తుతం కథనాలు అందుబాటులో లేవు</translation>
<translation id="7701040980221191251">ఏదీ కాదు</translation>
@@ -1074,11 +1210,13 @@
<translation id="774634243536837715">హానికరమైన కంటెంట్ బ్లాక్ చేయబడింది.</translation>
<translation id="7752995774971033316">నిర్వహించడం లేదు</translation>
<translation id="7755287808199759310">మీ తల్లి/తండ్రి దీన్ని మీ కోసం అన్‌బ్లాక్ చేయగలరు</translation>
+<translation id="7757555340166475417">డాయ్-పా-కాయ్</translation>
<translation id="7758069387465995638">ఫైర్‌వాల్ లేదా యాంటీవైరస్ సాఫ్ట్‌వేర్ కనెక్షన్‌ను బ్లాక్ చేసి ఉండవచ్చు.</translation>
<translation id="7759163816903619567">ప్రదర్శన డొమైన్:</translation>
<translation id="7761701407923456692">సర్వర్ ప్రమాణపత్రం URLతో సరిపోలలేదు.</translation>
<translation id="7763386264682878361">చెల్లింపు మానిఫెస్ట్ అన్వయ ప్రక్రియ</translation>
<translation id="7764225426217299476">చిరునామాను జోడించు</translation>
+<translation id="7770259615151589601">పొడవుగా నిర్దేశించబడింది</translation>
<translation id="777702478322588152">అధికారిక నివాసం</translation>
<translation id="7791543448312431591">జోడించు</translation>
<translation id="7793809570500803535"><ph name="SITE" />లోని వెబ్‌పేజీ తాత్కాలికంగా పని చేయకపోవచ్చు లేదా ఇది క్రొత్త వెబ్ చిరునామాకు శాశ్వతంగా తరలించబడి ఉండవచ్చు.</translation>
@@ -1090,8 +1228,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Chrome నుండి ఫారమ్ సూచనను తీసివేయాలా?</translation>
<translation id="7815407501681723534">'<ph name="SEARCH_STRING" />' కోసం <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> కనుగొనబడ్డాయి</translation>
-<translation id="7818867226424560206">విధాన నిర్వహణ</translation>
<translation id="782886543891417279">మీరు ఉపయోగిస్తున్న Wi-Fi (<ph name="WIFI_NAME" />)కు మీరు దాని లాగిన్ పేజీని సందర్శించడం అవసరం.</translation>
+<translation id="7836231406687464395">Postfix (ఎన్వలప్)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ఏదీ వద్దు}=1{1 యాప్ (<ph name="EXAMPLE_APP_1" />)}=2{2 యాప్‌లు (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# యాప్‌లు (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">అయితే, మీరు అదృశ్యంగా ఉండరు. అజ్ఞాతంలోకి వెళ్లడం వలన మీ బ్రౌజింగ్ మీ యజమానికి, మీ ఇంటర్నెట్ సేవా ప్రదాతకు లేదా మీరు సందర్శించే వెబ్‌సైట్‌లకు కనిపించకుండా దాచబడదు.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1100,7 +1238,7 @@
<translation id="7878562273885520351">మీ పాస్‌వర్డ్ ఎవరికైనా తెలిసిపోయి ఉండవచ్చు</translation>
<translation id="7882421473871500483">గోధుమ రంగు</translation>
<translation id="7887683347370398519">మీ CVCని తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి</translation>
-<translation id="7893255318348328562">సెషన్ పేరు</translation>
+<translation id="7904208859782148177">C3 (ఎన్వలప్)</translation>
<translation id="79338296614623784">చెల్లుబాటు అయ్యే ఫోన్ నంబర్‌ను నమోదు చేయండి</translation>
<translation id="7935318582918952113">DOM డిస్టిల్లర్</translation>
<translation id="7937554595067888181"><ph name="EXPIRATION_DATE_ABBR" />న గడువు ముగుస్తుంది</translation>
@@ -1110,21 +1248,25 @@
<translation id="7951415247503192394">(32-బిట్)</translation>
<translation id="7956713633345437162">మొబైల్ బుక్‌మార్క్‌లు</translation>
<translation id="7961015016161918242">ఎప్పుడూ లేదు</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">పేర్కొనబడలేదు</translation>
<translation id="800218591365569300">మెమరీని ఖాళీ చేయడానికి ఇతర ట్యాబ్‌లు లేదా ప్రోగ్రామ్‌లను మూసివేయడాన్ని ప్రయత్నించండి.</translation>
+<translation id="8004582292198964060">బ్రౌజర్</translation>
<translation id="8009225694047762179">పాస్‌వర్డ్‌లను నిర్వహించండి</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{ఈ కార్డ్, దీని బిల్లింగ్ చిరునామా సేవ్ చేయబడతాయి. <ph name="USER_EMAIL" />కు సైన్ ఇన్ చేసినప్పుడు మీరు దీనిని ఉపయోగించగలరు.}other{ఈ కార్డ్‌లు, వీటి బిల్లింగ్ చిరునామాలు సేవ్ చేయబడతాయి. <ph name="USER_EMAIL" />కు సైన్ ఇన్ చేసినప్పడు, మీరు వీటిని ఉపయోగించగలరు.}}</translation>
<translation id="8012647001091218357">మేము ప్రస్తుతం మీ తల్లిదండ్రులను సంప్రదించలేకపోయాము. దయచేసి మళ్లీ ప్రయత్నించండి.</translation>
<translation id="8025119109950072390">ఈ సైట్‌లోని దాడి చేసేవారు సాఫ్ట్‌వేర్‌ను ఇన్‌స్టాల్ చేయడం లేదా మీ వ్యక్తిగత సమాచారాన్ని (ఉదాహరణకు, పాస్‌వర్డ్‌లు, ఫోన్ నంబర్‌లు లేదా క్రెడిట్ కార్డ్‌లు) వెల్లడించడం వంటి ప్రమాదకరమైన పనులు చేసేలా మిమ్మల్ని మాయ చేయవచ్చు.</translation>
<translation id="8034522405403831421">ఈ పేజీ <ph name="SOURCE_LANGUAGE" />లో ఉంది. దీన్ని <ph name="TARGET_LANGUAGE" />లోకి అనువదించాలా?</translation>
<translation id="8035152190676905274">పెన్</translation>
+<translation id="8037117624646282037">పరికరాన్ని ఇటీవల ఎవరెవరు ఉపయోగించారు</translation>
<translation id="8037357227543935929">అడగాలి (డిఫాల్ట్)</translation>
<translation id="803771048473350947">ఫైల్</translation>
<translation id="8041089156583427627">ప్రతిస్పందనను పంపండి</translation>
<translation id="8041940743680923270">సార్వజనీన డిఫాల్ట్‌ను ఉపయోగించు (అడుగు)</translation>
<translation id="8042918947222776840">పికప్ పద్ధతిని ఎంచుకోండి</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />"ని సరిగ్గా కాన్ఫిగర్ చేయలేదు. సాధారణంగా "<ph name="SOFTWARE_NAME" />"ని అన్ఇన్‌స్టాల్ చేయడం ద్వారా సమస్య పరిష్కారం కావచ్చు. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">మీ పరికరం దీనికి కాన్ఫిగర్ చేయబడింది:</translation>
+<translation id="8066955247577885446">క్షమించండి, ఏదో తప్పు జరిగింది.</translation>
+<translation id="8074253406171541171">10x13 (ఎన్వలప్)</translation>
<translation id="8078141288243656252">తిప్పినప్పుడు అదనపు గమనికలను అందించడం సాధ్యపడదు</translation>
<translation id="8079031581361219619">సైట్‌ను తిరిగి లోడ్ చేయాలా?</translation>
<translation id="8088680233425245692">కథనాన్ని వీక్షించడంలో విఫలమైంది.</translation>
@@ -1133,11 +1275,12 @@
<translation id="8091372947890762290">సర్వర్‌లో యాక్టివేషన్ పెండింగ్‌లో ఉంది</translation>
<translation id="8092774999298748321">ముదురు ఊదా రంగు</translation>
<translation id="8094917007353911263">మీరు ఉపయోగిస్తున్న నెట్‌వర్క్‌కు మీరు <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ను సందర్శించడం అవసరం.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">చెల్లని కార్డ్‌లు తీసివేయబడ్డాయి</translation>
<translation id="8103161714697287722">చెల్లింపు పద్ధతి</translation>
<translation id="8118489163946903409">చెల్లింపు పద్ధతి</translation>
+<translation id="8123836779274890062"><ph name="ENROLLMENT_DOMAIN" /> ద్వారా <ph name="DEVICE_TYPE" /> నిర్వహించబడుతోంది</translation>
<translation id="8127301229239896662">మీ కంప్యూటర్ లేదా నెట్‌వర్క్‌లో "<ph name="SOFTWARE_NAME" />" సరిగ్గా ఇన్‌స్టాల్ కాలేదు. ఈ సమస్యను పరిష్కరించమని మీ IT నిర్వాహకులను కోరండి.</translation>
-<translation id="8130693978878176684">నేను ఇక సహాయం చేయలేను, మీ స్వంతంగా కొనసాగించండి.</translation>
<translation id="8131740175452115882">నిర్ధారించు</translation>
<translation id="8149426793427495338">మీ కంప్యూటర్ నిద్రావస్థకి వెళ్లింది.</translation>
<translation id="8150722005171944719"><ph name="URL" />లో ఫైల్ చదవగలిగేది కాదు. దీన్ని తీసివేసి ఉండవచ్చు, తరలించి ఉండవచ్చు లేదా ఫైల్ అనుమతులు యాక్సెస్‌ను నిరోధిస్తుండవచ్చు.</translation>
@@ -1147,8 +1290,11 @@
<translation id="8197543752516192074">పేజీని అనువదించు</translation>
<translation id="8201077131113104583">ID "<ph name="EXTENSION_ID" />" ఉన్న ఎక్స్‌టెన్ష‌న్‌ కోసం అప్‌డేట్‌ URL చెల్లదు.</translation>
<translation id="8202097416529803614">ఆర్డర్ సారాంశం</translation>
+<translation id="8202370299023114387">వైరుధ్యం</translation>
+<translation id="8206978196348664717">Prc4 (ఎన్వలప్)</translation>
<translation id="8211406090763984747">కనెక్షన్ సురక్షితంగా ఉంది</translation>
<translation id="8218327578424803826">కేటాయించిన స్థానం:</translation>
+<translation id="8220146938470311105">C7/C6 (ఎన్వలప్)</translation>
<translation id="8225771182978767009">ఈ కంప్యూటర్‌ను సెటప్ చేసిన వ్యక్తి ఈ సైట్‌ను బ్లాక్ చేయడం ఎంచుకున్నారు.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">కొత్త అజ్ఞాత ట్యాబ్‌లో పేజీని తెరవండి</translation>
@@ -1160,14 +1306,16 @@
<translation id="825929999321470778">సేవ్ చేసిన అన్ని పాస్‌వర్డ్‌లను చూపండి</translation>
<translation id="8261506727792406068">తొలగించు</translation>
<translation id="8267698848189296333"><ph name="USERNAME" />గా సైన్ ఇన్ చేస్తోంది</translation>
+<translation id="8278457561961988242">ఈ బ్రౌజర్ <ph name="ENROLLMENT_DOMAIN" /> ద్వారా నిర్వహించబడుతోంది. మీ నిర్వాహకుడు మీ బ్రౌజర్ సెటప్‌ను రిమోట్ విధానంలో మార్చవచ్చు. ఈ పరికరంలోని కార్యకలాపం Chrome వెలుపల కూడా నిర్వహిస్తుండవచ్చు. <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">పెద్ద-ఫోటో</translation>
<translation id="8286036467436129157">సైన్ ఇన్ చేయండి</translation>
<translation id="8288807391153049143">సర్టిఫికేట్‌ను చూపు</translation>
<translation id="8289355894181816810">మీకు దీని గురించి ఖచ్చితంగా తెలియకుంటే మీ నెట్‌వర్క్ నిర్వాహకుని సంప్రదించండి.</translation>
<translation id="8293206222192510085">బుక్‌మార్క్‌లను జోడించు</translation>
<translation id="8294431847097064396">మూలం</translation>
<translation id="8298115750975731693">మీరు ఉపయోగిస్తున్న Wi-Fi (<ph name="WIFI_NAME" />)కు మీరు<ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ను సందర్శించడం అవసరం.</translation>
+<translation id="8307358339886459768">చిన్న-ఫోటో</translation>
<translation id="8308427013383895095">నెట్‌వర్క్ కనెక్షన్‌తో సమస్య ఉన్నందున అనువాదం విఫలమైంది.</translation>
-<translation id="8311129316111205805">సెషన్‌ను లోడ్ చేయి</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" />కి యాక్సెస్ నిరాకరించబడింది</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">మీ భద్రతకు వాటిల్లే ఆపదల గురించి మీకు అర్థం అయ్యి ఉంటే, హానికర ప్రోగ్రామ్‌లు తీసివేయబడటానికి ముందే మీరు <ph name="BEGIN_LINK" />ఈ సైట్‌ను సందర్శించవచ్చు<ph name="END_LINK" />.</translation>
@@ -1185,7 +1333,6 @@
<translation id="8416694386774425977">నెట్‌వర్క్ కాన్ఫిగరేషన్ చెల్లదు, కాబట్టి దిగుమతి చేయడం సాధ్యం కాదు.
అదనపు వివరాలు:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">పరికరం <ph name="ENROLLMENT_DOMAIN" /> ద్వారా నిర్వహించబడుతుంది</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">మార్చు</translation>
<translation id="8428213095426709021">సెట్టింగ్‌లు</translation>
@@ -1212,9 +1359,11 @@
<translation id="860043288473659153">కార్డుదారుని పేరు</translation>
<translation id="861775596732816396">పరిమాణం 4</translation>
<translation id="8620436878122366504">మీ తల్లిదండ్రులు దీన్ని ఇంకా ఆమోదించలేదు</translation>
+<translation id="8622948367223941507">చట్ట సంబంధితం-అదనం</translation>
<translation id="8625384913736129811">ఈ కార్డ్‌ను ఈ పరికరానికి సేవ్ చేయి</translation>
<translation id="8663226718884576429">ఆర్డర్ సారాంశం, <ph name="TOTAL_LABEL" />, మరిన్ని వివరాలు</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, సమాధానం, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" />కు మీ కనెక్షన్ ఎన్‌క్రిప్ట్ చేయ‌బ‌డ‌లేదు.</translation>
<translation id="8718314106902482036">చెల్లింపు పూర్తి కాలేదు</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, శోధన సూచన</translation>
@@ -1228,8 +1377,9 @@
<translation id="8761567432415473239">Google సురక్షిత బ్రౌజింగ్ ఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />హానికర ప్రోగ్రామ్‍లను కనుగొనింది<ph name="END_LINK" />.</translation>
<translation id="8763927697961133303">USB పరికరం</translation>
<translation id="8768895707659403558">మీ కార్డ్‌లను మీ అన్ని పరికరాలలో ఉపయోగించాలంటే, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;తొలగించడాన్ని పునరావృతం చేయి</translation>
-<translation id="8792621596287649091">మీరు మీ <ph name="ORG_NAME" /> ఖాతాకు యాక్సెస్‌ని కోల్పోవచ్చు లేదా గుర్తింపు చోరీకి గురి కావచ్చు. మీ పాస్‌వర్డ్‌ని ఇప్పుడే రీసెట్ చేయాల్సిందిగా Chromium సిఫార్సు చేస్తోంది.</translation>
+<translation id="8792621596287649091">మీరు మీ <ph name="ORG_NAME" /> ఖాతాకు యాక్సెస్‌ను కోల్పోవచ్చు. లేదా గుర్తింపు స‌మాచారం చోరీకి గురి కావచ్చు. మీ పాస్‌వర్డ్‌ను ఇప్పుడే రీసెట్ చేయాల్సిందిగా Chromium సిఫార్సు చేస్తోంది.</translation>
<translation id="8800988563907321413">మీ సమీపంలోని సూచనలు ఇక్కడ కనిపిస్తాయి</translation>
<translation id="8820817407110198400">బుక్‌మార్క్‌లు</translation>
<translation id="883848425547221593">ఇతర బుక్‌మార్క్‌లు:</translation>
@@ -1238,10 +1388,12 @@
<translation id="885730110891505394">Googleతో భాగస్వామ్యం</translation>
<translation id="8858065207712248076">మీరు మీ <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> పాస్‌వర్డ్‌ని ఇతర సైట్‌లలో తిరిగి ఉపయోగించినట్లయితే దీనిని రీసెట్ చేయాల్సిందిగా Chrome సిఫార్సు చేస్తోంది.</translation>
<translation id="8866481888320382733">విధాన సెట్టింగ్‌లను అన్వయించడంలో ఎర్రర్</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">ఇటీవల మూసివేసినవి</translation>
<translation id="8874824191258364635">చెల్లుబాటు అయ్యే కార్డ్ నంబర్‌ను నమోదు చేయండి</translation>
<translation id="8891727572606052622">చెల్లని ప్రాక్సీ మోడ్.</translation>
<translation id="8903921497873541725">దగ్గరికి జూమ్ చెయ్యి</translation>
+<translation id="890485472659500557">ఇంజినీరింగ్-C</translation>
<translation id="8931333241327730545">మీరు ఈ కార్డ్‌ను మీ Google ఖాతాకు సేవ్ చేయాలనుకుంటున్నారా?</translation>
<translation id="8932102934695377596">మీ గడియారం సమయం గతంలో ఉంది</translation>
<translation id="893332455753468063">పేరుని జోడించండి</translation>
@@ -1249,13 +1401,13 @@
<translation id="894185898663964645">మీ నిర్వాహకుడు అనుకూల రూట్ సర్టిఫికెట్‌లను కాన్ఫిగర్ చేసారు, ఇవి మీరు సందర్శించే వెబ్‌సైట్‌ల కంటెంట్‌ను చూసేందుకు నిర్వాహకుడిని అనుమతించవచ్చు.</translation>
<translation id="8943282376843390568">నిమ్మపండు రంగు</translation>
<translation id="8957210676456822347">క్యాప్టివ్ పోర్టల్ ప్రామాణీకరణ</translation>
+<translation id="8966619695390250636">మీరు దీనిని అడిగారా?</translation>
<translation id="8968766641738584599">కార్డ్‌ని సేవ్ చేయండి</translation>
<translation id="8971063699422889582">సర్వర్ ప్రమాణపత్రం గడువు ముగిసింది.</translation>
<translation id="8975012916872825179">ఫోన్ నంబర్‌లు, ఇమెయిల్ చిరునామాలు మరియు బట్వాడా చిరునామాలు లాంటి సమాచారం ఉంటుంది</translation>
<translation id="8978053250194585037">Google సురక్షిత బ్రౌజింగ్ ఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />ఫిషింగ్‌ని గుర్తించింది<ph name="END_LINK" />. ఫిషింగ్ సైట్‌లు వేరే వెబ్‌సైట్‌ల వలె ప్రవర్తించడం ద్వారా మిమ్మల్ని మాయ చేయవచ్చు.</translation>
<translation id="8983003182662520383">Google Payని ఉపయోగిస్తున్న చెల్లింపు పద్ధతులు మరియు చిరునామాలు</translation>
<translation id="8987927404178983737">నెల</translation>
-<translation id="8988408250700415532">ఏదో తప్పు జరిగింది. మీరు వెబ్‌సైట్‌లో మీ ఆర్డర్‌ని పూర్తి చేయవచ్చు.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ఈ సైట్‌లో హానికర ప్రోగ్రామ్‌లు ఉన్నాయి</translation>
<translation id="8997023839087525404">సర్టిఫికెట్ పారదర్శకత విధానాన్ని ఉపయోగించి పబ్లిక్‌గా బహిరంగపరచబడని సర్టిఫికెట్‌ను ఈ సర్వర్ అందించింది. కొన్ని సర్టిఫికెట్‌లకు, అవి విశ్వసనీయమైనవని మరియు దాడి చేసేవారి నుండి రక్షణ కల్పించగలవని నిర్ధారించడానికి, ఇది ఆవశ్యకం.</translation>
@@ -1265,6 +1417,7 @@
<translation id="9011424611726486705">సైట్ సెట్టింగ్‌లను తెరవండి</translation>
<translation id="9020200922353704812">కార్డ్ బిల్లింగ్ చిరునామా అవసరం</translation>
<translation id="9020542370529661692">ఈ పేజీ <ph name="TARGET_LANGUAGE" />కి అనువదించబడింది</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(చెల్లదు)</translation>
<translation id="9035022520814077154">భద్రతా ఎర్రర్</translation>
<translation id="9038649477754266430">పేజీలను మరింత త్వరగా లోడ్ చేయడానికి సూచన సేవను ఉపయోగించండి</translation>
@@ -1276,11 +1429,11 @@
<translation id="9065745800631924235">చరిత్ర నుండి <ph name="TEXT" /> శోధన</translation>
<translation id="9069693763241529744">పొడిగింపు ద్వారా బ్లాక్ చేయబడింది</translation>
<translation id="9076283476770535406">ఇందులో పెద్దలకు మాత్రమే తగిన కంటెంట్ ఉండవచ్చు</translation>
+<translation id="9076630408993835509">ఈ బ్రౌజర్‌ను కంపెనీ లేదా సంస్థ నిర్వహించట్లేదు. ఈ పరికరంలోని కార్యకలాపం Chrome వెలుపల నిర్వహిస్తుండవచ్చు. <ph name="BEGIN_LINK" />మరింత తెలుసుకోండి<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">మరింత సమాచారం ఆవశ్యకం</translation>
<translation id="9080712759204168376">ఆర్డర్ సారాంశం</translation>
<translation id="9103872766612412690"><ph name="SITE" /> సాధారణంగా మీ సమాచారాన్ని రక్షించడానికి ఎన్‌క్రిప్ష‌న్‌ను ఉపయోగిస్తుంది. Chromium ఈసారి <ph name="SITE" />కు కనెక్ట్ చేయడానికి ప్రయత్నించినప్పుడు, వెబ్‌సైట్ అసాధారణ మరియు తప్పు ఆధారాలు అని ప్రతిస్పందించింది. దాడి చేసే వ్యక్తి <ph name="SITE" />గా వ్యవహరించి మోసగించడానికి ప్రయత్నిస్తున్నప్పుడు లేదా Wi-Fi సైన్-ఇన్ స్క్రీన్ కనెక్షన్‌కు అంతరాయం కలిగించినప్పుడు ఇలా జరగవచ్చు. Chromium ఎలాంటి డేటా వినిమయం జ‌ర‌గ‌క ముందే కనెక్షన్‌ను ఆపివేసినందున మీ సమాచారం ఇప్పటికీ సురక్షితంగానే ఉంది.</translation>
<translation id="9106062320799175032">బిల్లింగ్ చిరునామాను జోడించండి</translation>
-<translation id="9110718169272311511">Chromeలో Google అసిస్టెంట్ స్క్రీన్ దిగువ భాగానికి దగ్గరలో అందుబాటులో ఉంది</translation>
<translation id="9114524666733003316">కార్డ్‌ నిర్ధారించబడుతోంది...</translation>
<translation id="9128870381267983090">నెట్‌వర్క్‌కి కనెక్ట్ చేయి</translation>
<translation id="9137013805542155359">అసలును చూపించు</translation>
@@ -1289,6 +1442,7 @@
<translation id="9148507642005240123">&amp;సవరించడాన్ని రద్దు చేయి</translation>
<translation id="9154194610265714752">నవీకరించబడింది</translation>
<translation id="9157595877708044936">అమర్చుతోంది...</translation>
+<translation id="9158625974267017556">C6 (ఎన్వలప్)</translation>
<translation id="9168814207360376865">మీ వద్ద సేవ్ చేయబడిన చెల్లింపు పద్ధతులు ఉన్నాయో లేదో తనిఖీ చేయడానికి సైట్‌లను అనుమతించండి</translation>
<translation id="9169664750068251925">ఈ సైట్‌లో ఎప్పుడూ బ్లాక్ చేయి</translation>
<translation id="9170848237812810038">&amp;అన్డు</translation>
@@ -1303,10 +1457,12 @@
<translation id="9219103736887031265">చిత్రాలు</translation>
<translation id="933712198907837967">డైనర్స్ క్లబ్</translation>
<translation id="935608979562296692">ఫారమ్‌ను తీసివేయండి</translation>
+<translation id="936474030629450166">సూపర్-B</translation>
<translation id="936602727769022409">మీరు మీ Google ఖాతాకు యాక్సెస్‌ని కోల్పోవచ్చు. మీరు ఇప్పుడే మీ పాస్‌వర్డ్‌ని మార్చాల్సిందిగా Chromium సిఫార్సు చేస్తోంది. మీరు సైన్ ఇన్ చేయాల్సి ఉంటుంది.</translation>
<translation id="939736085109172342">క్రొత్త ఫోల్డర్</translation>
<translation id="945855313015696284">ఈ కింది వివరాలను ఒక్కసారి పరిశీలించి చెల్లని కార్డ్‌లు ఏమైనా ఉంటే తొలగించండి</translation>
<translation id="951104842009476243">ఆమోదించే డెబిట్ మరియు ప్రీపెయిడ్ కార్డ్‌లు</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> యొక్క భద్రతా విధానం ప్రకారం బ్లాక్ చేయబడింది.</translation>
<translation id="962484866189421427">ఈ కంటెంట్ వేరేవాటిలా కనిపించే మోసపూరిత యాప్‌లను ఇన్‌స్టాల్ చేయడానికి ప్రయత్నించవచ్చు లేదా మిమ్మల్ని ట్రాక్ చేయడానికి ఉపయోగించే డేటాని సేకరించవచ్చు. <ph name="BEGIN_LINK" />అయినప్పటికీ, చూపించు<ph name="END_LINK" /></translation>
<translation id="969892804517981540">అధికారిక బిల్డ్</translation>
<translation id="973773823069644502">డెలివరీ చిరునామాను జోడించండి</translation>
@@ -1315,6 +1471,7 @@
<translation id="984275831282074731">చెల్లింపు పద్ధతులు</translation>
<translation id="985199708454569384">&lt;p&gt;మీ కంప్యూటర్ లేదా మొబైల్ పరికరంలో తేదీ మరియు సమయం తప్పుగా ఉన్నట్లయితే మీకు ఈ ఎర్రర్ కనిపిస్తుంది.&lt;/p&gt;
&lt;p&gt;ఎర్రర్‌ను పరిష్కరించడానికి, మీ పరికర గడియారాన్ని తెరవండి. సమయం మరియు తేదీ సరిగ్గా ఉన్నాయని నిర్ధారించుకోండి.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">డెవలపర్ బిల్డ్</translation>
<translation id="989988560359834682">చిరునామాను సవరించు</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_th.xtb b/chromium/components/strings/components_strings_th.xtb
index 172e92ce6f0..8bbcff5d481 100644
--- a/chromium/components/strings/components_strings_th.xtb
+++ b/chromium/components/strings/components_strings_th.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="th">
-<translation id="1005145902654145231">เปลี่ยนชื่อเซสชันไม่ได้</translation>
<translation id="1008557486741366299">ไม่ใช่ตอนนี้</translation>
<translation id="1010200102790553230">โหลดหน้าภายหลัง</translation>
<translation id="1015730422737071372">ให้รายละเอียดเพิ่มเติม</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">ไม่ทราบชื่อ</translation>
<translation id="1050038467049342496">ปิดแอปอื่นๆ</translation>
<translation id="1055184225775184556">&amp;เลิกทำการเพิ่ม</translation>
+<translation id="1056898198331236512">คำเตือน</translation>
<translation id="1058479211578257048">กำลังบันทึกบัตร...</translation>
<translation id="10614374240317010">ไม่เคยบันทึก</translation>
+<translation id="1062160989074299343">Prc10 (ซองจดหมาย)</translation>
<translation id="106701514854093668">บุ๊กมาร์กบนเดสก์ท็อป</translation>
<translation id="1074497978438210769">ไม่ปลอดภัย</translation>
<translation id="1080116354587839789">พอดีกับความกว้าง</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">เพิ่มชื่อบนบัตร</translation>
<translation id="1089439967362294234">เปลี่ยนรหัสผ่าน</translation>
<translation id="109743633954054152">จัดการรหัสผ่านในการตั้งค่า Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">คุณอาจเห็นคำเตือนอยู่บ่อยๆ ระหว่างที่เว็บไซต์อัปเดตความปลอดภัย เราจะปรับปรุงเร็วๆ นี้</translation>
<translation id="1126551341858583091">ขนาดบนพื้นที่เก็บข้อมูลในเครื่องคือ <ph name="CRASH_SIZE" /></translation>
<translation id="112840717907525620">แคชนโยบายใช้ได้</translation>
+<translation id="1131264053432022307">รูปภาพที่คุณคัดลอก</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> ปิดการเชื่อมต่อโดยไม่คาดคิด</translation>
<translation id="1161325031994447685">เชื่อมต่อ Wi-Fi ใหม่</translation>
<translation id="1165039591588034296">ข้อผิดพลาด</translation>
-<translation id="1173894706177603556">เปลี่ยนชื่อ</translation>
<translation id="1175364870820465910">&amp;พิมพ์...</translation>
<translation id="1181037720776840403">นำออก</translation>
<translation id="1197088940767939838">สีส้ม</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">ชื่ออุปกรณ์ของคุณ</translation>
<translation id="124116460088058876">ภาษาเพิ่มเติม</translation>
<translation id="1250759482327835220">เพื่อความรวดเร็วในการชำระเงินครั้งถัดไป โปรดบันทึกบัตร ชื่อ และที่อยู่สำหรับการเรียกเก็บเงินไว้ในบัญชี Google</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" /> <ph name="TYPE_2" /> (ซิงค์แล้ว)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">บรรทัดคำสั่งรูปแบบต่างๆ</translation>
<translation id="129553762522093515">เพิ่งปิด</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />ลองล้างคุกกี้<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">ไม่มีเซสชันที่เลือก</translation>
+<translation id="1320233736580025032">Prc1 (ซองจดหมาย)</translation>
+<translation id="132301787627749051">ค้นหารูปภาพในคลิปบอร์ด</translation>
<translation id="1323433172918577554">แสดงเพิ่มเติม</translation>
<translation id="132390688737681464">บันทึกและกรอกที่อยู่</translation>
<translation id="1333989956347591814">ผู้อื่น<ph name="BEGIN_EMPHASIS" />อาจยังมองเห็น<ph name="END_EMPHASIS" />กิจกรรมของคุณ:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">ที่อยู่ในการรับ</translation>
<translation id="1348198688976932919">เว็บไซต์ที่จะเปิดมีแอปอันตราย</translation>
<translation id="1348779747280417563">ยืนยันชื่อ</translation>
+<translation id="1357195169723583938">ผู้ใดใช้อุปกรณ์เมื่อเร็วๆ นี้และใช้เมื่อใด</translation>
+<translation id="1364822246244961190">นโยบายนี้ถูกล็อกอยู่ ระบบจะไม่สนใจค่าของนโยบายนี้</translation>
<translation id="1374468813861204354">คำแนะนำ</translation>
+<translation id="1374692235857187091">Index-4x6 (โปสการ์ด)</translation>
<translation id="1375198122581997741">เกี่ยวกับรุ่น</translation>
<translation id="1376836354785490390">แสดงน้อยลง</translation>
<translation id="1377321085342047638">หมายเลขบัตร</translation>
<translation id="138218114945450791">ฟ้าอ่อน</translation>
+<translation id="1382194467192730611">อุปกรณ์ USB ที่ผู้ดูแลระบบอนุญาต</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> ไม่ส่งข้อมูลใดๆ</translation>
+<translation id="140316286225361634">เว็บไซต์ <ph name="ORIGIN" /> ขอให้บังคับใช้นโยบายความปลอดภัย
+ กับคำขอทั้งหมดของเว็บไซต์ และนโยบายนี้เห็นว่าขณะนี้เว็บไซต์ดังกล่าว
+ ไม่ปลอดภัย</translation>
<translation id="1405567553485452995">เขียวอ่อน</translation>
<translation id="1407135791313364759">เปิดทั้งหมด</translation>
<translation id="1413809658975081374">ข้อผิดพลาดเกี่ยวกับความเป็นส่วนตัว</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">ยอมรับ</translation>
<translation id="1430915738399379752">พิมพ์</translation>
<translation id="1455413310270022028">ยางลบ</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">แสดงเพิ่มเติม</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">เลือกที่อยู่สำหรับจัดส่ง</translation>
+<translation id="1492194039220927094">การพุชนโยบาย:</translation>
<translation id="1501859676467574491">แสดงบัตรจากบัญชี Google ของคุณ</translation>
-<translation id="1506687042165942984">แสดงสำเนาที่บันทึกไว้ (หรือที่ล้าสมัย) ของหน้านี้</translation>
<translation id="1507202001669085618">&lt;p&gt;คุณจะเห็นข้อผิดพลาดนี้ หากใช้พอร์ทัล Wi-Fi ที่คุณต้องลงชื่อเข้าใช้ก่อนจึงจะสามารถออนไลน์ได้&lt;/p&gt;
&lt;p&gt;ในการแก้ไขข้อผิดพลาด ให้คลิก&lt;strong&gt;เชื่อมต่อ&lt;/strong&gt;บนหน้าเว็บที่คุณพยายามจะเปิด&lt;/p&gt;</translation>
<translation id="1517433312004943670">ต้องระบุหมายเลขโทรศัพท์</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">วันที่สร้าง</translation>
<translation id="1521655867290435174">Google ชีต</translation>
<translation id="1527263332363067270">กำลังรอการเชื่อมต่อ…</translation>
+<translation id="1529521330346880926">10x15 (ซองจดหมาย)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">หน้านี้บอกว่า</translation>
<translation id="153384715582417236">เสร็จเรียบร้อย</translation>
<translation id="154408704832528245">เลือกที่อยู่สำหรับนำส่งสินค้า</translation>
<translation id="1549470594296187301">ต้องเปิดใช้ JavaScript เพื่อใช้ฟีเจอร์นี้</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">ป้อนวันที่หมดอายุ</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">มีสิ่งผิดปกติเกิดขึ้นในขณะที่แสดงหน้าเว็บนี้</translation>
<translation id="1592005682883173041">การเข้าถึงข้อมูลในเครื่อง</translation>
<translation id="1594030484168838125">เลือก</translation>
<translation id="161042844686301425">สีฟ้า</translation>
-<translation id="1618822247301510817">รูปภาพที่คุณคัดลอกมา</translation>
<translation id="1620510694547887537">กล้องถ่ายรูป</translation>
<translation id="1623104350909869708">ป้องกันหน้าเว็บนี้จากการสร้างการโต้ตอบเพิ่มเติม</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">จบเซสชัน</translation>
<translation id="1639239467298939599">กำลังโหลด</translation>
<translation id="1640180200866533862">นโยบายผู้ใช้</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">โดยทั่วไป <ph name="SITE" /> จะใช้การเข้ารหัสเพื่อปกป้องข้อมูลของคุณ เมื่อ Google Chrome พยายามเชื่อมต่อกับ <ph name="SITE" /> ในครั้งนี้ เว็บไซต์ดังกล่าวส่งข้อมูลรับรองที่ผิดปกติและไม่ถูกต้องกลับมา เหตุการณ์นี้อาจเกิดขึ้นเมื่อผู้บุกรุกพยายามปลอมเป็น <ph name="SITE" /> หรือหน้าจอการลงชื่อเข้าใช้ Wi-Fi รบกวนการเชื่อมต่อ ข้อมูลของคุณยังปลอดภัยอยู่เนื่องจาก Google Chrome หยุดการเชื่อมต่อก่อนมีการแลกเปลี่ยนข้อมูล</translation>
<translation id="168841957122794586">ใบรับรองของเซิร์ฟเวอร์มีคีย์การเข้ารหัสที่ไม่รัดกุม</translation>
<translation id="1697532407822776718">คุณพร้อมแล้ว!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ตั้งแต่วันพรุ่งนี้ โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ}other{เซิร์ฟเวอร์นี้พิสูจน์ไม่ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยควรจะเริ่มใช้งานได้ในอีก # วันข้างหน้า โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ}}</translation>
<translation id="1710259589646384581">ระบบปฏิบัติการ</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">เอกสารมีขนาดใหญ่เกินกว่าจะใส่หมายเหตุได้</translation>
<translation id="1721312023322545264">คุณต้องได้รับสิทธิ์จาก <ph name="NAME" /> เพื่อเข้าชมเว็บไซต์นี้</translation>
<translation id="1721424275792716183">* ช่องที่ต้องกรอก</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">ลองติดต่อผู้ดูแลระบบ</translation>
<translation id="1740951997222943430">ป้อนเดือนที่หมดอายุที่ถูกต้อง</translation>
<translation id="1743520634839655729">เพื่อความรวดเร็วในการชำระเงินครั้งถัดไป โปรดบันทึกบัตร ชื่อ และที่อยู่สำหรับการเรียกเก็บเงินไว้ในบัญชี Google และในอุปกรณ์นี้</translation>
+<translation id="1745880797583122200">เบราว์เซอร์ของคุณมีการจัดการ</translation>
<translation id="17513872634828108">แท็บที่เปิดอยู่</translation>
<translation id="1753706481035618306">เลขหน้า</translation>
<translation id="1763864636252898013">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะระบบปฏิบัติการของอุปกรณ์ของคุณไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">โปรดอัปเดตข้อความรหัสผ่านที่ซิงค์ของคุณ</translation>
<translation id="1787142507584202372">แท็บที่คุณเปิดไว้จะปรากฏที่นี่</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">ชื่อผู้ถือบัตร</translation>
<translation id="1821930232296380041">คำขอหรือพารามิเตอร์คำขอไม่ถูกต้อง</translation>
+<translation id="1822540298136254167">เว็บไซต์ที่คุณเข้าชมและเวลาที่ใช้ไป</translation>
<translation id="1826516787628120939">กำลังตรวจสอบ</translation>
<translation id="1834321415901700177">เว็บไซต์นี้มีโปรแกรมอันตราย</translation>
<translation id="1839551713262164453">การตรวจสอบความถูกต้องของค่านโยบายมีข้อผิดพลาดและล้มเหลว</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">ล้างข้อมูลประวัติการเข้าชมของ Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{และอีก 1 แอป}other{และอีก # แอป}}</translation>
<translation id="2003709556000175978">รีเซ็ตรหัสผ่านเลย</translation>
+<translation id="20053308747750172">เซิร์ฟเวอร์ที่คุณกำลังจะเข้าถึง <ph name="ORIGIN" /> ขอให้บังคับใช้
+ นโยบายความปลอดภัยกับคำขอทั้งหมดที่จะส่งถึงเซิร์ฟเวอร์ แต่ขณะนี้
+ เซิร์ฟเวอร์แสดงนโยบายที่ไม่ถูกต้อง
+ ซึ่งทำให้เบราว์เซอร์ดำเนินการตามคำขอของคุณสำหรับ <ph name="SITE" /> ไม่ได้</translation>
<translation id="2025186561304664664">พร็อกซีถูกตั้งค่าให้ทำการกำหนดค่าโดยอัตโนมัติ</translation>
<translation id="2030481566774242610">หรือคุณหมายถึง <ph name="LINK" /></translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />ตรวจสอบพร็อกซีและไฟร์วอลล์<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">แผนก</translation>
<translation id="2102134110707549001">แนะนำรหัสผ่านที่รัดกุม…</translation>
<translation id="2108755909498034140">รีสตาร์ทคอมพิวเตอร์</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">บัตร</translation>
<translation id="2114841414352855701">ไม่สนใจเพราะถูกแทนที่โดย <ph name="POLICY_NAME" /></translation>
<translation id="213826338245044447">บุ๊กมาร์กบนอุปกรณ์เคลื่อนที่</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">แก้ไขบัตร</translation>
<translation id="2166049586286450108">การเข้าถึงระดับผู้ดูแลระบบโดยสมบูรณ์</translation>
<translation id="2166378884831602661">เว็บไซต์นี้ไม่สามารถให้การเชื่อมต่อที่ปลอดภัย</translation>
+<translation id="2169984857010174799">Kaku2 (ซองจดหมาย)</translation>
<translation id="2181821976797666341">นโยบาย</translation>
<translation id="2183608646556468874">หมายเลขโทรศัพท์</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{ที่อยู่ 1 รายการ}other{ที่อยู่ # รายการ}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">หมายเลขโทรศัพท์</translation>
<translation id="2283340219607151381">บันทึกและกรอกที่อยู่</translation>
<translation id="2292556288342944218">การเข้าถึงอินเทอร์เน็ตของคุณถูกบล็อก</translation>
+<translation id="2294558542833290837">ลิงก์ที่คุณเปิดครั้งแรกมีความผิดปกติ</translation>
+<translation id="2297722699537546652">B5 (ซองจดหมาย)</translation>
+<translation id="2310021320168182093">Chou2 (ซองจดหมาย)</translation>
<translation id="2316887270356262533">หากเพิ่มพื้นที่ว่างไม่ถึง 1 MB ไซต์บางแห่งอาจโหลดช้าลงเมื่อคุณเข้าชมครั้งถัดไป</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> ต้องใช้ชื่อผู้ใช้และรหัสผ่าน</translation>
<translation id="2317583587496011522">รับบัตรเดบิต</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" /> หมดอายุ <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">ผู้ดูแลระบบเป็นผู้ควบคุมการตั้งค่า</translation>
+<translation id="2346319942568447007">รูปภาพที่คุณคัดลอก</translation>
<translation id="2349790679044093737">เซสชัน VR ทำงานอยู่</translation>
<translation id="2354001756790975382">บุ๊กมาร์กอื่นๆ</translation>
<translation id="2354430244986887761">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />พบแอปอันตราย<ph name="END_LINK" />ใน <ph name="SITE" /></translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> ยังไม่ได้อัปโหลด</translation>
<translation id="2367567093518048410">ระดับ</translation>
<translation id="2378238891085281592">คุณเข้าสู่โหมดส่วนตัวแล้ว</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">ค่าเริ่มต้นขององค์กร</translation>
<translation id="2386255080630008482">ใบรับรองของเซิร์ฟเวอร์ถูกเพิกถอนแล้ว</translation>
<translation id="2392959068659972793">แสดงนโยบายโดยที่ไม่ได้ตั้งค่า</translation>
<translation id="239429038616798445">วิธีการจัดส่งสินค้านี้ไม่พร้อมให้บริการ โปรดลองใช้วิธีการอื่น</translation>
<translation id="2396249848217231973">&amp;เลิกทำการนำออก</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีการเพิกถอนใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="2418081434543109369">เซิร์ฟเวอร์ที่คุณกำลังจะเข้าถึง <ph name="ORIGIN" /> ขอให้บังคับใช้
+ นโยบายความปลอดภัยกับคำขอทั้งหมดที่จะส่งถึงเซิร์ฟเวอร์ แต่ขณะนี้
+ เซิร์ฟเวอร์แสดงนโยบายไม่ได้ ซึ่งทำให้เบราว์เซอร์
+ ดำเนินการตามคำขอของคุณสำหรับ <ph name="SITE" /> ไม่ได้</translation>
<translation id="244665789865330679">อุปกรณ์และบัญชีของคุณจัดการโดย <ph name="ENROLLMENT_DOMAIN" /> ซึ่งหมายความว่าผู้ดูแลระบบอาจกำหนดค่าอุปกรณ์และบัญชีดังกล่าวจากระยะไกล</translation>
<translation id="2463193859425327265">เปลี่ยนหน้าแรก</translation>
<translation id="2463739503403862330">กรอกข้อมูล</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">เลือกวิธีนำส่งสินค้า</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />เรียกใช้การวินิจฉัยเครือข่าย<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">แปลหน้านี้</translation>
<translation id="2479410451996844060">URL ค้นหาไม่ถูกต้อง</translation>
<translation id="2482878487686419369">การแจ้งเตือน</translation>
<translation id="248348093745724435">นโยบายเครื่อง</translation>
+<translation id="2485387744899240041">ชื่อผู้ใช้สำหรับอุปกรณ์และเบราว์เซอร์ของคุณ</translation>
<translation id="2491120439723279231">ใบรับรองของเซิร์ฟเวอร์มีข้อผิดพลาด</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">โปรแกรมแยกวิเคราะห์ JSON</translation>
<translation id="2495093607237746763">หากเลือกไว้ Chromium จะจัดเก็บสำเนาบัตรของคุณบนอุปกรณ์นี้เพื่อการกรอกแบบฟอร์มที่รวดเร็วขึ้น</translation>
<translation id="2498091847651709837">สแกนบัตรใหม่</translation>
<translation id="2501278716633472235">ย้อนกลับ</translation>
<translation id="2503184589641749290">บัตรเดบิตและบัตรเติมเงินที่ยอมรับ</translation>
<translation id="2515629240566999685">ตรวจสอบสัญญาณในพื้นที่ของคุณ</translation>
-<translation id="2516852381693169964">ค้นหารูปภาพจาก <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">บันทึกไว้เฉพาะในอุปกรณ์นี้</translation>
<translation id="2524461107774643265">เพิ่มข้อมูลอื่นๆ</translation>
<translation id="2536110899380797252">เพิ่มที่อยู่</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">รหัส API ไดเรกทอรี:</translation>
<translation id="2597378329261239068">เอกสารนี้ได้รับการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่าน</translation>
<translation id="2609632851001447353">รูปแบบต่างๆ</translation>
+<translation id="2618023639789766142">C10 (ซองจดหมาย)</translation>
<translation id="2625385379895617796">นาฬิกาเร็วเกินไป</translation>
<translation id="2634124572758952069">ไม่พบที่อยู่ IP ของเซิร์ฟเวอร์ <ph name="HOST_NAME" /></translation>
<translation id="2639739919103226564">สถานะ:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">ปิดแท็บหรือแอปอื่นๆ</translation>
<translation id="267371737713284912">กด <ph name="MODIFIER_KEY_DESCRIPTION" /> เพื่อเลิกทำ</translation>
<translation id="2674170444375937751">คุณแน่ใจหรือไม่ว่าต้องการนำออกหน้าเหล่านี้ออกจากประวัติการเข้าชมของคุณ</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">ออก</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">บัตรที่ยอมรับ</translation>
<translation id="2702801445560668637">รายการที่จะอ่าน</translation>
<translation id="2704283930420550640">ค่าไม่ตรงกับรูปแบบ</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">นำรายการที่เลือกออก </translation>
<translation id="277133753123645258">วิธีการจัดส่งสินค้า</translation>
<translation id="277499241957683684">ไม่มีอุปกรณ์บันทึก</translation>
-<translation id="2781030394888168909">ส่งออก MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">การเชื่อมต่อได้รับการรีเซ็ตแล้ว</translation>
<translation id="2788784517760473862">บัตรเครดิตที่ยอมรับ</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">การเชื่อมต่อถูกเข้ารหัสและรับรองความถูกต้องโดยใช้ <ph name="CIPHER" /> และใช้ <ph name="KX" /> เป็นกลไกการแลกเปลี่ยนคีย์</translation>
<translation id="2835170189407361413">ล้างฟอร์ม</translation>
<translation id="2847118875340931228">เปิดหน้าต่างที่ไม่ระบุตัวตน</translation>
+<translation id="2850739647070081192">Invite (ซองจดหมาย)</translation>
<translation id="2851634818064021665">คุณต้องได้รับสิทธิ์เพื่อเข้าชมไซต์นี้</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">บันทึกบัตรไหม</translation>
<translation id="2903493209154104877">ที่อยู่</translation>
<translation id="290376772003165898">หน้านี้ไม่ใช่ภาษา<ph name="LANGUAGE" />ใช่ไหม</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">วิธีการนำส่งสินค้า</translation>
<translation id="2928905813689894207">ที่อยู่สำหรับการเรียกเก็บเงิน</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมาจาก <ph name="DOMAIN2" /> โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="2948083400971632585">คุณสามารถปิดใช้งานพร็อกซีที่กำหนดค่าสำหรับการเชื่อมต่อจากหน้าการตั้งค่าได้</translation>
<translation id="2955913368246107853">ปิดแถบค้นหา</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (ซองจดหมาย)</translation>
<translation id="3024663005179499861">ประเภทนโยบายไม่ถูกต้อง</translation>
<translation id="3037605927509011580">แย่จัง!</translation>
<translation id="3041612393474885105">ข้อมูลในใบรับรอง</translation>
+<translation id="3060227939791841287">C9 (ซองจดหมาย)</translation>
<translation id="3064966200440839136">ออกจากโหมดไม่ระบุตัวตนเพื่อชำระเงินผ่านแอปพลิเคชันภายนอก ดำเนินการต่อไหม</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{ไม่มี}=1{รหัสผ่าน 1 รายการ}other{รหัสผ่าน # รายการ}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">เพิ่มที่อยู่สำหรับรับสินค้า</translation>
<translation id="3105172416063519923">รหัสสินทรัพย์:</translation>
<translation id="3109728660330352905">คุณไม่มีสิทธิ์ดูหน้านี้</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> ใน <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">ยกเลิกการชำระเงิน</translation>
<translation id="3207960819495026254">บุ๊กมาร์กแล้ว</translation>
-<translation id="3209375525920864198">โปรดป้อนชื่อเซสชันที่ถูกต้อง</translation>
+<translation id="321912867715453276">คำเตือน: นโยบายนี้มีแหล่งที่มามากกว่า 1 แห่งแต่มีค่าต่างๆ เหมือนกัน</translation>
<translation id="3225919329040284222">เซิร์ฟเวอร์แสดงใบรับรองที่ไม่ตรงกับการคาดการณ์ที่มีอยู่ การคาดการณ์เหล่านี้มีอยู่ในบางเว็บไซต์ที่มีการรักษาความปลอดภัยสูงเพื่อปกป้องคุณ</translation>
<translation id="3226128629678568754">กดปุ่มโหลดซ้ำเพื่อส่งซ้ำข้อมูลที่จำเป็นในการโหลดหน้าเว็บ</translation>
<translation id="3227137524299004712">ไมโครโฟน</translation>
<translation id="3228969707346345236">การแปลล้มเหลวเนื่องจากหน้าเว็บนี้เป็นภาษา<ph name="LANGUAGE" />อยู่แล้ว</translation>
+<translation id="3229041911291329567">ข้อมูลเวอร์ชันเกี่ยวกับอุปกรณ์และเบราว์เซอร์</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">เพิ่มชื่อบนบัตร</translation>
<translation id="3287510313208355388">ดาวน์โหลดเมื่อออนไลน์</translation>
<translation id="3293642807462928945">ดูข้อมูลเพิ่มเติมเกี่ยวกับนโยบาย <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">ไม่พบผลการค้นหา</translation>
-<translation id="3305707030755673451">ข้อมูลของคุณได้รับการเข้ารหัสด้วยรหัสผ่านการซิงค์เมื่อวันที่ <ph name="TIME" /> โปรดป้อนรหัสผ่านเพื่อเริ่มซิงค์</translation>
<translation id="3320021301628644560">เพิ่มที่อยู่สำหรับการเรียกเก็บเงิน</translation>
<translation id="3324983252691184275">แดงเข้ม</translation>
<translation id="3338095232262050444">ปลอดภัย</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;ทำซ้ำการแก้ไข</translation>
<translation id="342781501876943858">Chromium ขอแนะนำให้รีเซ็ตรหัสผ่านหากคุณใช้รหัสผ่านนี้ซ้ำในเว็บไซต์อื่น</translation>
<translation id="3431636764301398940">บันทึกบัตรนี้ลงในอุปกรณ์นี้</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">เจ้าของอุปกรณ์นี้ปิดเกมไดโนเสาร์</translation>
<translation id="3447884698081792621">แสดงใบรับรอง (ออกโดย <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">ช่วงการดึงข้อมูล:</translation>
+<translation id="3456231139987291353">Number-11 (ซองจดหมาย)</translation>
<translation id="3461824795358126837">ไฮไลต์</translation>
<translation id="3462200631372590220">ซ่อนข้อมูลขั้นสูง</translation>
<translation id="3467763166455606212">ต้องระบุชื่อผู้ถือบัตร</translation>
@@ -429,20 +480,23 @@
<translation id="358285529439630156">รับบัตรเครดิตและบัตรเติมเงิน</translation>
<translation id="3582930987043644930">เพิ่มชื่อ</translation>
<translation id="3583757800736429874">&amp;ทำซ้ำการย้าย</translation>
+<translation id="35866233670761917">ผู้ดูแลระบบจะมองไม่เห็นเนื้อหาของเว็บไซต์ที่คุณเข้าชม</translation>
<translation id="3586931643579894722">ซ่อนรายละเอียด</translation>
+<translation id="3592413004129370115">Italian (ซองจดหมาย)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">ขนาด 2</translation>
<translation id="3615877443314183785">ป้อนวันที่หมดอายุที่ถูกต้อง</translation>
<translation id="36224234498066874">ล้างข้อมูลการท่องเว็บ</translation>
<translation id="362276910939193118">แสดงประวัติการเข้าชมทั้งหมด</translation>
-<translation id="3623476034248543066">แสดงค่า</translation>
<translation id="3630155396527302611">หากโปรแกรมอยู่ในรายการที่ได้รับอนุญาตให้เข้าถึงเครือข่ายอยู่แล้ว
ลองนำโปรแกรมออกจากรายการและเพิ่มกลับเข้าไปใหม่</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">การตรวจสอบสำเร็จ</translation>
<translation id="3655670868607891010">หากคุณเห็นข้อความนี้บ่อยๆ ให้ลองไปที่ <ph name="HELP_LINK" /></translation>
<translation id="3658742229777143148">การแก้ไข</translation>
<translation id="366077651725703012">อัปเดตบัตรเครดิต</translation>
<translation id="3676592649209844519">รหัสอุปกรณ์:</translation>
+<translation id="3677008721441257057">คุณหมายถึง &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ใช่ไหม</translation>
<translation id="3678029195006412963">ไม่สามารถลงนามคำขอ</translation>
<translation id="3678529606614285348">เปิดหน้าเว็บในหน้าต่างที่ไม่ระบุตัวตนใหม่ (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> อัปโหลดเมื่อ <ph name="UPLOAD_TIME" /></translation>
@@ -450,13 +504,14 @@
<translation id="3704162925118123524">เครือข่ายที่คุณใช้อาจต้องการให้คุณไปที่หน้าการเข้าสู่ระบบ</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">กำลังโหลด ...</translation>
+<translation id="3709599264800900598">ข้อความที่คุณคัดลอก</translation>
<translation id="3712624925041724820">ใบอนุญาตหมด</translation>
<translation id="3714780639079136834">เปิดอินเทอร์เน็ตมือถือหรือ Wi-Fi</translation>
<translation id="3715597595485130451">เชื่อมต่อ Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />ตรวจสอบพร็อกซี ไฟร์วอลล์ และการกำหนดค่า DNS<ph name="END_LINK" /></translation>
<translation id="372429172604983730">แอปพลิเคชันที่อาจทำให้เกิดข้อผิดพลาดนี้ ได้แก่ ซอฟต์แวร์ป้องกันไวรัส ซอฟต์แวร์ไฟร์วอลล์ รวมถึงซอฟต์แวร์การกรองเว็บหรือซอฟต์แวร์พร็อกซี</translation>
+<translation id="373042150751172459">B4 (ซองจดหมาย)</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="3745099705178523657">เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google กับเว็บไซต์นี้</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>
@@ -469,10 +524,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">หมดอายุ <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">ขนาด 16</translation>
+<translation id="3797522431967816232">Prc3 (ซองจดหมาย)</translation>
<translation id="3807873520724684969">บล็อกเนื้อหาอันตรายแล้ว</translation>
<translation id="3810973564298564668">จัดการ</translation>
<translation id="382518646247711829">หากคุณใช้พร็อกซีเซิร์ฟเวอร์...</translation>
<translation id="3828924085048779000">ข้อความรหัสผ่านต้องไม่เว้นว่างไว้</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> ได้ติดตั้งส่วนขยายสำหรับฟังก์ชันเพิ่มเติม ส่วนขยายเข้าถึงข้อมูลบางส่วนของคุณได้</translation>
<translation id="385051799172605136">กลับ</translation>
<translation id="3858027520442213535">อัปเดตวันที่และเวลา</translation>
<translation id="3884278016824448484">ตัวชี้อุปกรณ์ขัดแย้งกัน</translation>
@@ -480,6 +537,7 @@
<translation id="3886446263141354045">ระบบส่งคำขอเข้าถึงเว็บไซต์นี้ของคุณให้ <ph name="NAME" /> แล้ว</translation>
<translation id="3890664840433101773">เพิ่มอีเมล</translation>
<translation id="3901925938762663762">บัตรหมดอายุ</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">ถามทุกครั้งบนเว็บไซต์นี้</translation>
<translation id="3949571496842715403">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยไม่ได้ระบุชื่อสำรองของหัวเรื่อง โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้โจมตีที่ขัดขวางการเชื่อมต่อของคุณ</translation>
@@ -490,11 +548,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{ไม่มี}=1{จากเว็บไซต์ 1 แห่ง }other{จากเว็บไซต์ # แห่ง }}</translation>
<translation id="397105322502079400">กำลังคำนวณ...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> ถูกบล็อก</translation>
-<translation id="3984550557525787191">มีชื่อเซสชันนี้อยู่แล้ว</translation>
<translation id="3987940399970879459">ไม่ถึง 1 MB</translation>
+<translation id="4008849406247176967">คำเตือน: นโยบายนี้มีแหล่งที่มามากกว่า 1 แห่งที่มีค่าขัดแย้งกัน</translation>
<translation id="40103911065039147">{URL_count,plural, =1{มีหน้าเว็บ 1 หน้าใกล้ๆ}other{มีหน้าเว็บ # หน้าใกล้ๆ}}</translation>
<translation id="4030383055268325496">&amp;เลิกทำการเพิ่ม</translation>
+<translation id="4032320456957708163">เบราว์เซอร์ของคุณจัดการโดย <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">คีย์ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (ซองจดหมาย)</translation>
<translation id="4067947977115446013">เพิ่มที่อยู่ที่ถูกต้อง</translation>
<translation id="4072486802667267160">เกิดข้อผิดพลาดในการประมวลผลคำสั่งซื้อของคุณ โปรดลองอีกครั้ง</translation>
<translation id="4075732493274867456">ไคลเอ็นต์และเซิร์ฟเวอร์ไม่รองรับโปรโตคอล SSL เวอร์ชันทั่วไปหรือชุดการเข้ารหัส</translation>
@@ -514,10 +574,12 @@
<translation id="4159784952369912983">ม่วง</translation>
<translation id="4165986682804962316">การตั้งค่าเว็บไซต์</translation>
<translation id="4171400957073367226">ลายเซ็นยืนยันไม่ถูกต้อง</translation>
+<translation id="4173315687471669144">กระดาษฟุลสแก๊ป</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{อีก <ph name="ITEM_COUNT" /> รายการ}other{อีก <ph name="ITEM_COUNT" /> รายการ}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;ทำซ้ำการย้าย</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />ตรวจสอบไฟร์วอลล์และการกำหนดค่าการป้องกันไวรัส<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (ซองจดหมาย)</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="4221630205957821124">&lt;h4&gt;ขั้นตอนที่ 1: ลงชื่อเข้าใช้พอร์ทัล&lt;/h4&gt;
@@ -549,58 +611,79 @@
<translation id="4277028893293644418">รีเซ็ตรหัสผ่าน</translation>
<translation id="4280429058323657511">หมดอายุ <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{บันทึกบัตรนี้ลงในบัญชี Google ของคุณแล้ว}other{บันทึกบัตรเหล่านี้ลงในบัญชี Google ของคุณแล้ว}}</translation>
+<translation id="42981349822642051">ขยาย</translation>
+<translation id="4302965934281694568">Chou3 (ซองจดหมาย)</translation>
<translation id="4305817255990598646">สลับ</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">บล็อก (ค่าเริ่มต้น)</translation>
+<translation id="4318566738941496689">ชื่ออุปกรณ์และที่อยู่เครือข่ายของคุณ</translation>
<translation id="4325863107915753736">การค้นหาบทความล้มเหลว</translation>
<translation id="4326324639298822553">ตรวจสอบวันหมดอายุแล้วลองอีกครั้ง</translation>
<translation id="4331708818696583467">ไม่ปลอดภัย</translation>
<translation id="4340982228985273705">ไม่มีการตรวจพบว่าคอมพิวเตอร์เครื่องนี้ได้รับการจัดการโดยองค์กร ดังนั้นนโยบายจะติดตั้งเฉพาะส่วนขยายที่โฮสต์ใน Chrome เว็บสโตร์โดยอัตโนมัติ URL การอัปเดตของ Chrome เว็บสโตร์คือ "<ph name="CWS_UPDATE_URL" />"</translation>
<translation id="4346197816712207223">บัตรเครดิตที่ยอมรับ</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">ผู้โจมตีในเว็บไซต์นี้อาจพยายามติดตั้งโปรแกรมอันตรายซึ่งจะขโมยหรือลบข้อมูล (ตัวอย่างเช่น รูปภาพ รหัสผ่าน ข้อความ และบัตรเครดิต) ลงในคอมพิวเตอร์ของคุณ</translation>
<translation id="4358461427845829800">จัดการวิธีการชำระเงิน...</translation>
+<translation id="4367563149485757821">Number-12 (ซองจดหมาย)</translation>
+<translation id="4372516964750095882">กระดาษต่อเนื่องแบบสหรัฐฯ</translation>
<translation id="4372948949327679948">ค่า <ph name="VALUE_TYPE" /> ที่คาดไว้</translation>
<translation id="4377125064752653719">คุณพยายามเข้าถึง <ph name="DOMAIN" /> แต่ใบรับรองที่เซิร์ฟเวอร์แจ้งมาถูกเพิกถอนโดยผู้ออกใบรับรอง ซึ่งหมายความว่าข้อมูลรับรองด้านความปลอดภัยที่เซิร์ฟเวอร์แจ้งมานั้นไม่สามารถเชื่อถือได้ คุณอาจกำลังติดต่อกับคนที่คิดจะโจมตีคุณ</translation>
<translation id="4378154925671717803">โทรศัพท์</translation>
<translation id="4406896451731180161">ผลการค้นหา</translation>
-<translation id="4406972042435603828">ผู้ดูแลระบบได้ติดตั้งส่วนขยายซึ่งมาพร้อมกับความสามารถที่มีประสิทธิภาพ</translation>
<translation id="4408413947728134509">คุกกี้ <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">ที่อยู่ในการรับ</translation>
<translation id="4424024547088906515">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะ Chrome ไม่เชื่อถือใบรับรองความปลอดภัย โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="443121186588148776">พอร์ตอนุกรม</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> ไม่ยอมรับใบรับรองการเข้าสู่ระบบหรือไม่ได้ให้ใบรับรองไว้</translation>
<translation id="4434045419905280838">ป๊อปอัปและการเปลี่ยนเส้นทาง</translation>
+<translation id="4435702339979719576">โปสการ์ด)</translation>
<translation id="443673843213245140">การใช้พร็อกซีถูกปิดใช้งาน แต่มีการระบุการกำหนดค่าพร็อกซีอย่างชัดเจน</translation>
<translation id="445100540951337728">บัตรเดบิตที่ยอมรับ</translation>
+<translation id="4466881336512663640">การเปลี่ยนแปลงในฟอร์มจะหายไป คุณแน่ใจไหมว่าต้องการดำเนินการต่อ</translation>
<translation id="4482953324121162758">ระบบจะไม่แปลเว็บไซต์นี้</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL ไม่ถูกต้อง ต้องเป็น URL ที่มีรูปแบบมาตรฐาน เช่น http://example.com หรือ https://example.com</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">ข้อผิดพลาดในการตรวจสอบ: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">ติดต่อผู้ดูแลระบบ</translation>
<translation id="450710068430902550">การแชร์กับผู้ดูแลระบบ</translation>
+<translation id="4510487217173779431">Chou4 (ซองจดหมาย)</translation>
<translation id="4515275063822566619">ข้อมูลบัตรและที่อยู่มาจาก Chrome และบัญชี Google (<ph name="ACCOUNT_EMAIL" />) คุณสามารถจัดการข้อมูลเหล่านี้ใน<ph name="BEGIN_LINK" />การตั้งค่า<ph name="END_LINK" /></translation>
+<translation id="4517607026994743406">Comm-10 (ซองจดหมาย)</translation>
<translation id="4522570452068850558">รายละเอียด</translation>
<translation id="4524805452350978254">จัดการการ์ด</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">ลองปิดใช้ส่วนขยาย</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">การจัดส่ง</translation>
+<translation id="4579056131138995126">Personal (ซองจดหมาย)</translation>
<translation id="4582204425268416675">นำบัตรออก</translation>
<translation id="4587425331216688090">นำที่อยู่ออกจาก Chrome ไหม</translation>
<translation id="4592951414987517459">มีการเข้ารหัสการเชื่อมต่อของคุณกับ <ph name="DOMAIN" /> ด้วยชุดการเข้ารหัสที่ทันสมัย</translation>
<translation id="4594403342090139922">&amp;เลิกทำการนำออก</translation>
<translation id="4597348597567598915">ขนาด 8</translation>
+<translation id="4600854749408232102">C6/C5 (ซองจดหมาย)</translation>
<translation id="4646534391647090355">พาฉันไปที่นั่นเลย</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะใบรับรองความปลอดภัยมีข้อผิดพลาด โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="467809019005607715">Google สไลด์</translation>
<translation id="4690462567478992370">หยุดใช้ใบรับรองที่ไม่ถูกต้อง</translation>
+<translation id="4691835149146451662">Architecture-A (ซองจดหมาย)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">การเชื่อมต่อของคุณขัดข้อง</translation>
<translation id="471880041731876836">คุณไม่มีสิทธิ์เข้าชมไซต์นี้</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />เรียกใช้การวินิจฉัยเครือข่ายของ Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">โหลดนโยบายซ้ำ</translation>
<translation id="4728558894243024398">แพลตฟอร์ม</translation>
+<translation id="4731967714531604179">Prc2 (ซองจดหมาย)</translation>
<translation id="4736825316280949806">รีสตาร์ท Chromium</translation>
<translation id="473775607612524610">อัปเดต</translation>
<translation id="4738601419177586157">การแนะนำการค้นหา <ph name="TEXT" /></translation>
<translation id="4742407542027196863">จัดการรหัสผ่าน…</translation>
<translation id="4744603770635761495">เส้นทางปฏิบัติการ</translation>
+<translation id="4746351372139058112">ข้อความ</translation>
<translation id="4750917950439032686">ข้อมูลของคุณ (ตัวอย่างเช่น รหัสผ่านหรือหมายเลขบัตรเครดิต) จะเป็นส่วนตัวเมื่อส่งมายังเว็บไซต์นี้</translation>
<translation id="4756388243121344051">&amp;ประวัติการเข้าชม</translation>
<translation id="4758311279753947758">เพิ่มข้อมูลติดต่อ</translation>
@@ -608,9 +691,9 @@
<translation id="4764776831041365478">หน้าเว็บใน <ph name="URL" /> อาจหยุดให้บริการชั่วคราวหรืออาจถูกย้ายไปยังที่อยู่เว็บใหม่อย่างถาวร</translation>
<translation id="4771973620359291008">มีข้อผิดพลาดที่ไม่ทราบเกิดขึ้น</translation>
<translation id="4785689107224900852">เปลี่ยนเป็นแท็บนี้</translation>
-<translation id="4792143361752574037">เกิดปัญหาในการเข้าถึงไฟล์เซสชัน ขณะนี้ระบบปิดใช้การบันทึกลงในดิสก์ โปรดโหลดหน้าใหม่เพื่อลองอีกครั้ง</translation>
<translation id="4798078619018708837">ป้อนวันที่หมดอายุและ CVC ของ <ph name="CREDIT_CARD" /> เพื่ออัปเดตรายละเอียดของบัตร เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google กับเว็บไซต์นี้</translation>
<translation id="4800132727771399293">ตรวจสอบวันหมดอายุและ CVC แล้วลองอีกครั้ง</translation>
+<translation id="480334179571489655">ข้อผิดพลาดเกี่ยวกับนโยบายต้นทาง</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>
@@ -625,7 +708,6 @@
<translation id="4881695831933465202">เปิด</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>
@@ -634,15 +716,15 @@
<translation id="4943872375798546930">ไม่มีผลการค้นหา</translation>
<translation id="4950898438188848926">ปุ่มเปลี่ยนแท็บ โปรดกด Enter เพื่อเปลี่ยนไปยังแท็บที่เปิดอยู่ <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">การทำงาน</translation>
-<translation id="495832697253704892">การรายงานส่วนขยาย</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">ขยายรายการ</translation>
<translation id="4974590756084640048">เปิดใช้คำเตือนอีกครั้ง</translation>
+<translation id="4984339528288761049">Prc5 (ซองจดหมาย)</translation>
<translation id="4989163558385430922">ดูทั้งหมด</translation>
<translation id="4989809363548539747">ไม่รองรับปลั๊กอินนี้</translation>
-<translation id="4996230189582812866">การรายงาน</translation>
<translation id="5002932099480077015">หากเปิดใช้ Chrome จะเก็บสำเนาการ์ดของคุณในอุปกรณ์นี้เพื่อให้การกรอกฟอร์มทำได้เร็วขึ้น</translation>
-<translation id="5014174725590676422">กำลังแสดงหน้าจอเรียกใช้ Google Assistant ครั้งแรกใน Chrome</translation>
<translation id="5015510746216210676">ชื่อเครื่อง:</translation>
+<translation id="5017554619425969104">ข้อความที่คุณคัดลอก</translation>
<translation id="5018422839182700155">ไม่สามารถเปิดหน้านี้</translation>
<translation id="5019198164206649151">ไม่สามารถจัดเก็บเนื่องจากระบบแบ็คเอนด์อยู่ในสถานะไม่ดี</translation>
<translation id="5023310440958281426">ตรวจสอบนโยบายของผู้ดูแลระบบของคุณ</translation>
@@ -652,35 +734,51 @@
<translation id="5034369478845443529">บริบทเฉพาะรายการ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">อนุญาต</translation>
<translation id="5040262127954254034">ความเป็นส่วนตัว</translation>
+<translation id="5043480802608081735">ลิงก์ที่คุณคัดลอก</translation>
<translation id="5045550434625856497">รหัสผ่านไม่ถูกต้อง</translation>
<translation id="5056549851600133418">บทความสำหรับคุณ</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />ตรวจสอบที่อยู่พร็อกซี<ph name="END_LINK" /></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="5097099694988056070">สถิติของอุปกรณ์ เช่น การใช้ CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">อุปกรณ์ของคุณจัดการโดย <ph name="ENROLLMENT_DOMAIN" /> และบัญชีของคุณจัดการโดย <ph name="ACCOUNT_DOMAIN" /> ซึ่งหมายความว่าผู้ดูแลระบบอาจกำหนดค่าอุปกรณ์และบัญชีดังกล่าวจากระยะไกล</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">Edp แบบยุโรป</translation>
<translation id="5115563688576182185">(64 บิต)</translation>
-<translation id="5128122789703661928">ลบเซสชันที่ใช้ชื่อนี้ไม่ได้</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">จัดการที่อยู่...</translation>
+<translation id="5138227688689900538">แสดงน้อยลง</translation>
<translation id="5141240743006678641">เข้ารหัสผ่านที่ซิงค์ด้วยข้อมูลรับรอง Google ของคุณ</translation>
<translation id="5145883236150621069">มีรหัสข้อผิดพลาดในการตอบกลับนโยบาย</translation>
+<translation id="515292512908731282">C4 (ซองจดหมาย)</translation>
<translation id="5159010409087891077">เปิดหน้าเว็บในหน้าต่างที่ไม่ระบุตัวตนใหม่ (⇧⌘N)</translation>
<translation id="516920405563544094">ป้อน CVC ของ <ph name="CREDIT_CARD" /> เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google กับเว็บไซต์นี้</translation>
<translation id="5169827969064885044">คุณอาจเข้าถึงบัญชีขององค์กรไม่ได้หรือถูกโจรกรรมข้อมูลประจำตัว Chrome ขอแนะนำให้เปลี่ยนรหัสผ่านตอนนี้เลย</translation>
<translation id="5171045022955879922">ค้นหาหรือพิมพ์ URL</translation>
+<translation id="5171689220826475070">กระดาษต่อเนื่องแบบยุโรป</translation>
<translation id="5172758083709347301">ผู้ใช้คอมพิวเตอร์นี้</translation>
<translation id="5179510805599951267">หากไม่มีในภาษา <ph name="ORIGINAL_LANGUAGE" /> ให้รายงานข้อผิดพลาดนี้</translation>
<translation id="5190835502935405962">แถบบุ๊กมาร์ก</translation>
-<translation id="5200263511887412697">รายงานรายชื่อผู้ใช้อุปกรณ์ที่ลงชื่อเข้าสู่ระบบเมื่อเร็วๆ นี้</translation>
+<translation id="519422657042045905">โหมดคำอธิบายประกอบไม่พร้อมใช้งาน</translation>
<translation id="5201306358585911203">หน้าที่ฝังไว้ในหน้าเว็บนี้บอกว่า</translation>
<translation id="5205222826937269299">ต้องระบุชื่อ</translation>
<translation id="5215116848420601511">วิธีการชำระเงินและที่อยู่จาก Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">ต้องระบุอีเมล</translation>
<translation id="5230733896359313003">ที่อยู่ในการจัดส่ง</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"เชื่อมต่อกับเครือข่าย"</translation>
<translation id="5251803541071282808">ระบบคลาวด์</translation>
+<translation id="5252000469029418751">C7 (ซองจดหมาย)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">ที่อยู่เครือข่าย</translation>
<translation id="5285570108065881030">แสดงรหัสผ่านที่บันทึกไว้ทั้งหมด</translation>
<translation id="5287240709317226393">แสดงคุกกี้</translation>
<translation id="5288108484102287882">มีคำเตือนจากการตรวจสอบความถูกต้องของค่านโยบาย</translation>
@@ -692,7 +790,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" /> <ph name="MATCH_POSITION" /> จาก <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">เลือกข้อมูลติดต่อ</translation>
<translation id="5327248766486351172">ชื่อ</translation>
+<translation id="5329858041417644019">เบราว์เซอร์ของคุณไม่มีการจัดการ</translation>
<translation id="5332219387342487447">วิธีการจัดส่ง</translation>
+<translation id="5334013548165032829">บันทึกของระบบโดยละเอียด</translation>
<translation id="5344579389779391559">อาจมีการพยายามเรียกเก็บเงินจากคุณในหน้านี้</translation>
<translation id="5355557959165512791">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจากใบรับรองถูกเพิกถอนแล้ว โดยปกติข้อผิดพลาดของเครือข่ายและการโจมตีจะเกิดขึ้นเพียงชั่วคราว หน้านี้จึงอาจจะใช้งานได้ในภายหลัง</translation>
<translation id="536296301121032821">ไม่สามารถจัดเก็บการตั้งค่านโยบาย</translation>
@@ -700,6 +800,7 @@
<translation id="5377026284221673050">"นาฬิกาของคุณช้ากว่าปัจจุบัน" หรือ "นาฬิกาของคุณเร็วกว่าปัจจุบัน" หรือ "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">ลงชื่อเข้าใช้และเปิดการซิงค์เพื่อใช้บัตรในอุปกรณ์ทุกเครื่อง</translation>
<translation id="5386426401304769735">กลุ่มใบรับรองสำหรับเว็บไซต์นี้มีใบรับรองที่ลงนามโดยใช้ SHA-1</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เนื่องจากใบรับรองความปลอดภัยไม่สามารถใช้ได้ในขณะนี้ ซึ่งอาจเป็นเพราะการกำหนดค่าที่ไม่ถูกต้องหรือมีผู้โจมตีที่ขัดขวางการเชื่อมต่อของคุณ</translation>
<translation id="5421136146218899937">ล้างข้อมูลการท่องเว็บ...</translation>
<translation id="5430298929874300616">นำบุ๊กมาร์กออก</translation>
@@ -710,6 +811,7 @@
<translation id="5457113250005438886">ไม่ถูกต้อง</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;ทำซ้ำการแก้ไข</translation>
+<translation id="5478437291406423475">B6/C4 (ซองจดหมาย)</translation>
<translation id="5481076368049295676">เนื้อหานี้อาจพยายามติดตั้งซอฟต์แวร์อันตรายที่จะขโมยหรือลบข้อมูลในอุปกรณ์ของคุณ <ph name="BEGIN_LINK" />แสดงเนื้อหา<ph name="END_LINK" /></translation>
<translation id="54817484435770891">เพิ่มที่อยู่ที่ถูกต้อง</translation>
<translation id="5490432419156082418">ที่อยู่และอื่นๆ</translation>
@@ -717,10 +819,12 @@
<ph name="LINE_BREAK" />
โปรดลองติดต่อผู้ดูแลระบบของคุณ</translation>
<translation id="549333378215107354">ขนาด 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">บุ๊กมาร์กที่มีการจัดการ</translation>
<translation id="5510766032865166053">ไฟล์อาจถูกย้ายหรือลบไปแล้ว</translation>
<translation id="5523118979700054094">ชื่อนโยบาย</translation>
<translation id="552553974213252141">ดึงข้อความออกมาถูกต้องไหม</translation>
+<translation id="553484882784876924">Prc6 (ซองจดหมาย)</translation>
<translation id="5540224163453853">ไม่พบบทความที่ขอ</translation>
<translation id="5541546772353173584">เพิ่มอีเมล</translation>
<translation id="5545756402275714221">บทความสำหรับคุณ</translation>
@@ -735,15 +839,21 @@
<translation id="5595485650161345191">แก้ไขที่อยู่</translation>
<translation id="5598944008576757369">เลือกวิธีการชำระเงิน</translation>
<translation id="560412284261940334">ไม่สนับสนุนการจัดการ</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">ตรวจสอบการเชื่อมต่อ</translation>
<translation id="5610807607761827392">คุณสามารถจัดการบัตรและที่อยู่ใน<ph name="BEGIN_LINK" />การตั้งค่า<ph name="END_LINK" /></translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> เปลี่ยนเส้นทางของคุณบ่อยเกินไป</translation>
<translation id="5629630648637658800">ไม่สามารถโหลดการตั้งค่านโยบาย</translation>
<translation id="5631439013527180824">โทเค็นการจัดการอุปกรณ์ไม่ถูกต้อง</translation>
+<translation id="5632627355679805402">ข้อมูลของคุณเข้ารหัสลับไว้ด้วย<ph name="BEGIN_LINK" />รหัสผ่าน Google<ph name="END_LINK" /> เมื่อ <ph name="TIME" /> ป้อนรหัสผ่านเพื่อเริ่มซิงค์</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="563324245173044180">บล็อกเนื้อหาที่หลอกลวงแล้ว</translation>
<translation id="5659593005791499971">อีเมล</translation>
+<translation id="5663614846592581799">9x11 (ซองจดหมาย)</translation>
+<translation id="5663955426505430495">ผู้ดูแลระบบของอุปกรณ์นี้ได้ติดตั้งส่วนขยายสำหรับฟังก์ชันเพิ่มเติม ส่วนขยายเข้าถึงข้อมูลบางส่วนของคุณได้</translation>
<translation id="5675650730144413517">หน้านี้ใช้ไม่ได้</translation>
+<translation id="5684874026226664614">อ๊ะ หน้านี้ไม่สามารถแปลได้</translation>
<translation id="5685654322157854305">เพิ่มที่อยู่สำหรับจัดส่ง</translation>
<translation id="5689199277474810259">ส่งออกไปยัง JSON</translation>
<translation id="5689516760719285838">ตำแหน่ง</translation>
@@ -752,38 +862,39 @@
<translation id="5710435578057952990">ข้อมูลประจำตัวของเว็บไซต์นี้ยังไม่ได้รับการยืนยัน</translation>
<translation id="5719499550583120431">รับบัตรเติมเงิน</translation>
<translation id="5720705177508910913">ผู้ใช้ปัจจุบัน</translation>
+<translation id="5728056243719941842">C5 (ซองจดหมาย)</translation>
<translation id="5730040223043577876">Chrome ขอแนะนำให้รีเซ็ตรหัสผ่านหากคุณใช้รหัสผ่านนี้ซ้ำในเว็บไซต์อื่น</translation>
<translation id="5732392974455271431">ผู้ปกครองสามารถเลิกบล็อกเว็บไซต์ให้คุณ</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{บันทึกบัตรลงในบัญชี Google ของคุณ}other{บันทึกบัตรลงในบัญชี Google ของคุณ}}</translation>
<translation id="5763042198335101085">ป้อนที่อยู่อีเมลที่ถูกต้อง</translation>
<translation id="5765072501007116331">หากต้องการดูวิธีการนำส่งสินค้าและข้อกำหนด โปรดเลือกที่อยู่</translation>
-<translation id="5770114862687765385">ดูเหมือนไฟล์จะเสียหาย คลิกปุ่ม "รีเซ็ต" เพื่อรีเซ็ตเซสชัน</translation>
<translation id="5778550464785688721">การควบคุมอุปกรณ์ MIDI เต็มรูปแบบ</translation>
<translation id="578305955206182703">เหลืองอำพัน</translation>
<translation id="57838592816432529">ปิดเสียง</translation>
<translation id="5784606427469807560">เกิดปัญหาในการยืนยันบัตรของคุณ โปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตและลองอีกครั้ง</translation>
<translation id="5785756445106461925">นอกจากนี้ หน้านี้ประกอบด้วยทรัพยากรอื่นๆ ซึ่งไม่ปลอดภัย ผู้อื่นสามารถดูทรัพยากรเหล่านี้ขณะถ่ายโอน และผู้บุกรุกสามารถแก้ไขเพื่อเปลี่ยนรูปลักษณ์ของหน้าได้</translation>
<translation id="5786044859038896871">คุณต้องการกรอกข้อมูลบัตรไหม</translation>
+<translation id="5798290721819630480">ทิ้งการเปลี่ยนแปลงไหม</translation>
<translation id="5798683403665926540">เปลี่ยนหน้าแรกในการตั้งค่า Chrome</translation>
<translation id="5803412860119678065">คุณต้องการกรอกข้อมูล <ph name="CARD_DETAIL" /> ไหม</translation>
<translation id="5804241973901381774">การอนุญาต</translation>
<translation id="5810442152076338065">มีการเข้ารหัสการเชื่อมต่อของคุณกับ <ph name="DOMAIN" /> ด้วยชุดการเข้ารหัสที่ล้าสมัยแล้ว</translation>
<translation id="5813119285467412249">&amp;ทำซ้ำการเพิ่ม</translation>
<translation id="5838278095973806738">คุณไม่ควรป้อนข้อมูลที่ละเอียดอ่อนบนเว็บไซต์นี้ (ตัวอย่างเช่น รหัสผ่านหรือบัตรเครดิต) เนื่องจากผู้โจมตีอาจขโมยข้อมูลดังกล่าวไปได้</translation>
+<translation id="5860033963881614850">ปิด</translation>
<translation id="5863847714970149516">ระบบอาจพยายามเรียกเก็บเงินจากคุณในหน้าถัดไป</translation>
<translation id="5866257070973731571">เพิ่มหมายเลขโทรศัพท์</translation>
<translation id="5869405914158311789">ไม่สามารถเข้าถึงเว็บไซต์นี้</translation>
<translation id="5869522115854928033">รหัสผ่านที่บันทึกไว้</translation>
<translation id="5887400589839399685">บันทึกการ์ดแล้ว</translation>
-<translation id="5893718151540690985">รายงานรายการอินเทอร์เฟซเครือข่ายพร้อมด้วยประเภทและที่อยู่ฮาร์ดแวร์</translation>
<translation id="5893752035575986141">รับบัตรเครดิต</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="5916664084637901428">เปิด</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">บันทึกบัตรลงในบัญชี Google ไหม</translation>
<translation id="5922853866070715753">เกือบเสร็จแล้ว</translation>
<translation id="5932224571077948991">เว็บไซต์แสดงโฆษณาที่แทรกหรือทำให้เข้าใจผิด</translation>
-<translation id="5939518447894949180">รีเซ็ต</translation>
<translation id="5946937721014915347">กำลังเปิด <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">ลงทะเบียนด้วยบัญชีผู้ใช้ทั่วไปไม่ได้ (มีใบอนุญาตแบบแพ็กเกจ)</translation>
<translation id="5967592137238574583">แก้ไขข้อมูลติดต่อ</translation>
@@ -791,6 +902,7 @@
<translation id="5975083100439434680">ย่อ</translation>
<translation id="5977489021191000276">อุปกรณ์ไม่ได้จัดการโดยผู้ดูแลระบบ</translation>
<translation id="5977976211062815271">ในอุปกรณ์นี้</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">ไม่สามารถเปิดแอปการชำระเงิน</translation>
<translation id="5989320800837274978">ไม่มีการระบุทั้งพร็อกซีเซิร์ฟเวอร์แบบคงที่หรือ URL สคริปต์ .pac</translation>
<translation id="5990559369517809815">คำขอไปยังเซิร์ฟเวอร์ถูกบล็อกโดยส่วนขยาย</translation>
@@ -801,8 +913,8 @@
<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="6033927989869462158">รายงานสถิติฮาร์ดแวร์ เช่น การใช้งาน CPU/RAM</translation>
<translation id="6034000775414344507">เทาอ่อน</translation>
+<translation id="6034283069659657473">10x14 (ซองจดหมาย)</translation>
<translation id="6039846035001940113">หากยังคงพบปัญหา ให้ติดต่อเจ้าของเว็บไซต์</translation>
<translation id="6040143037577758943">ปิด</translation>
<translation id="6044573915096792553">ขนาด 12</translation>
@@ -811,10 +923,10 @@
<translation id="6051221802930200923">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้เนื่องจากเว็บไซต์ใช้การตรึงใบรับรอง โดยปกติข้อผิดพลาดของเครือข่ายและการโจมตีจะเกิดขึ้นเพียงชั่วคราว หน้านี้จึงอาจใช้งานได้ในภายหลัง</translation>
<translation id="6058977677006700226">ต้องการใช้บัตรในอุปกรณ์ทุกเครื่องไหม</translation>
<translation id="6059925163896151826">อุปกรณ์ USB</translation>
-<translation id="6071091556643036997">ประเภทนโยบายไม่ถูกต้อง</translation>
<translation id="6080696365213338172">คุณเข้าถึงเนื้อหาโดยใช้ใบรับรองที่ผู้ดูแลระบบออกให้ ข้อมูลที่คุณให้กับ <ph name="DOMAIN" /> อาจถูกสกัดกั้นโดยผู้ดูแลระบบ</translation>
<translation id="6094273045989040137">ใส่หมายเหตุ</translation>
<translation id="610911394827799129">บัญชี Google อาจมีประวัติการท่องเว็บรูปแบบอื่นๆ ที่ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">ข้อมูลเกี่ยวกับส่วนขยายและปลั๊กอินที่ติดตั้งไว้</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{ไม่มี}=1{รหัสผ่าน (ที่ซิงค์) 1 รายการ}other{รหัสผ่าน (ที่ซิงค์) # รายการ}}</translation>
<translation id="6146055958333702838">ตรวจสายเคเบิลและรีบูตเราเตอร์ โมเด็ม หรืออุปกรณ์เครือข่ายอื่น
ที่คุณอาจใช้งานอยู่</translation>
@@ -849,15 +961,21 @@
<translation id="6337133576188860026">หากเพิ่มพื้นที่ว่างไม่ถึง <ph name="SIZE" /> ไซต์บางแห่งอาจโหลดช้าลงเมื่อคุณเข้าชมครั้งถัดไป</translation>
<translation id="6337534724793800597">กรองนโยบายตามชื่อ</translation>
<translation id="6358450015545214790">นี่หมายถึงอะไร</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">อาจมีการเรียกเก็บเงิน</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{อีก 1 คำแนะนำ}other{อีก # คำแนะนำ}}</translation>
<translation id="6387754724289022810">เพื่อความสะดวกในการชำระเงินในครั้งถัดไป โปรดบันทึกบัตรและที่อยู่สำหรับการเรียกเก็บเงินไว้ในบัญชี Google สำหรับอุปกรณฺ์นี้</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">แก้ไขบุ๊กมาร์ก</translation>
+<translation id="6406765186087300643">C0 (ซองจดหมาย)</translation>
<translation id="6410264514553301377">ป้อนวันหมดอายุและ CVC ของ <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">คุณถามผู้ปกครองแล้วว่าสามารถเข้าชมเว็บไซต์นี้ได้ไหม</translation>
<translation id="6417515091412812850">ไม่สามารถตรวจสอบว่าใบรับรองถูกเพิกถอนหรือไม่</translation>
<translation id="6433490469411711332">แก้ไขข้อมูลติดต่อ</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> ปฏิเสธการเชื่อมต่อ</translation>
+<translation id="6434309073475700221">ทิ้ง</translation>
+<translation id="6446163441502663861">Kahu (ซองจดหมาย)</translation>
<translation id="6446608382365791566">เพิ่มข้อมูลเพิ่มเติม</translation>
<translation id="6447842834002726250">คุกกี้</translation>
<translation id="6451458296329894277">ยืนยันการส่งแบบฟอร์มอีกครั้ง</translation>
@@ -870,11 +988,17 @@
<translation id="6508722015517270189">รีสตาร์ท Chrome</translation>
<translation id="6529602333819889595">&amp;ทำซ้ำการนำออก</translation>
<translation id="6534179046333460208">คำแนะนำ Physical Web</translation>
+<translation id="6556866813142980365">ทำซ้ำ</translation>
<translation id="6563469144985748109">ผู้จัดการยังไม่ได้อนุมัติเว็บไซต์นี้</translation>
<translation id="6569060085658103619">คุณกำลังดูหน้าส่วนขยาย</translation>
+<translation id="6578796323535178455">C2 (ซองจดหมาย)</translation>
<translation id="6579990219486187401">ชมพูอ่อน</translation>
+<translation id="6583674473685352014">B6 (ซองจดหมาย)</translation>
+<translation id="6587923378399804057">ลิงก์ที่คุณคัดลอก</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> ของคุณไม่มีการจัดการ</translation>
<translation id="6596325263575161958">ตัวเลือกการเข้ารหัส</translation>
<translation id="6604181099783169992">เซ็นเซอร์จับความเคลื่อนไหวหรือเซ็นเซอร์แสง</translation>
+<translation id="6609880536175561541">Prc7 (ซองจดหมาย)</translation>
<translation id="6624427990725312378">ข้อมูลติดต่อ</translation>
<translation id="6626291197371920147">เพิ่มหมายเลขบัตรที่ถูกต้อง</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> ค้นหา</translation>
@@ -883,6 +1007,7 @@
<translation id="6644283850729428850">นโยบายนี้ถูกยกเลิกแล้ว</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{ไม่มี}=1{จาก 1 เว็บไซต์ (คุณจะไม่ออกจากระบบบัญชี Google)}other{จาก # เว็บไซต์ (คุณจะไม่ออกจากระบบบัญชี Google)}}</translation>
<translation id="6657585470893396449">รหัสผ่าน</translation>
+<translation id="6670613747977017428">กลับสู่ความปลอดภัย</translation>
<translation id="6671697161687535275">ต้องการนำคำแนะนำสำหรับแบบฟอร์มออกจาก Chromium ใช่ไหม</translation>
<translation id="6685834062052613830">ออกจากระบบและตั้งค่าให้เสร็จสมบูรณ์</translation>
<translation id="6710213216561001401">ก่อนหน้า</translation>
@@ -890,12 +1015,15 @@
<translation id="671076103358959139">โทเค็นการลงทะเบียน:</translation>
<translation id="6711464428925977395">พร็อกซีเซิร์ฟเวอร์ผิดปกติหรือที่อยู่ไม่ถูกต้อง</translation>
<translation id="6723740634201835758">ในบัญชี Google</translation>
+<translation id="6738516213925468394">ข้อมูลของคุณเข้ารหัสลับไว้ด้วย<ph name="BEGIN_LINK" />รหัสผ่านการซิงค์<ph name="END_LINK" />เมื่อ <ph name="TIME" /> ป้อนรหัสผ่านเพื่อเริ่มซิงค์</translation>
<translation id="674375294223700098">ข้อผิดพลาดใบรับรองของเซิร์ฟเวอร์ที่ไม่รู้จัก</translation>
<translation id="6744009308914054259">ระหว่างที่รอการเชื่อมต่อ คุณไปที่หน้า "ดาวน์โหลด" เพื่ออ่านบทความออฟไลน์ได้</translation>
<translation id="6753269504797312559">ค่านโยบาย</translation>
<translation id="6757797048963528358">อุปกรณ์ของคุณเข้าสู่โหมดสลีปแล้ว</translation>
+<translation id="6768213884286397650">Hagaki (โปสการ์ด)</translation>
<translation id="6778737459546443941">ผู้ปกครองยังไม่ได้อนุมัติเว็บไซต์นี้</translation>
<translation id="67862343314499040">ม่วงอมน้ำเงิน</translation>
+<translation id="6786747875388722282">ส่วนขยาย</translation>
<translation id="679355240208270552">ไม่ใช้งานเนื่องจากมีการเปิดใช้การค้นหาเริ่มต้นตามนโยบาย</translation>
<translation id="681021252041861472">ช่องที่ต้องกรอก</translation>
<translation id="6810899417690483278">รหัสการปรับแต่ง</translation>
@@ -928,10 +1056,12 @@
<translation id="6965978654500191972">อุปกรณ์</translation>
<translation id="6970216967273061347">อำเภอ</translation>
<translation id="6973656660372572881">มีการระบุทั้งพร็อกซีเซิร์ฟเวอร์แบบคงที่และ URL สคริปต์ .pac ไว้</translation>
+<translation id="6973932557599545801">ขออภัย ฉันช่วยคุณไม่ได้ โปรดดำเนินการต่อด้วยตนเอง</translation>
<translation id="6979158407327259162">Google ไดรฟ์</translation>
<translation id="6979440798594660689">ปิดเสียง (ค่าเริ่มต้น)</translation>
<translation id="6984479912851154518">ออกจากโหมดส่วนตัวเพื่อชำระเงินผ่านแอปพลิเคชันภายนอก ดำเนินการต่อไหม</translation>
<translation id="6989763994942163495">แสดงการตั้งค่าขั้นสูง...</translation>
+<translation id="6993898126790112050">6x9 (ซองจดหมาย)</translation>
<translation id="6996312675313362352">แปลภาษา<ph name="ORIGINAL_LANGUAGE" />เสมอ</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">การเรียกเก็บเงินเหล่านี้อาจเกิดขึ้นครั้งเดียวหรือเป็นเกิดขึ้นซ้ำๆ และอาจไม่แสดงอย่างชัดแจ้ง</translation>
@@ -947,28 +1077,36 @@
<translation id="7108338896283013870">ซ่อน</translation>
<translation id="7108819624672055576">อนุญาตโดยส่วนขยาย</translation>
<translation id="7111012039238467737">(ถูกต้อง)</translation>
+<translation id="7118618213916969306">ค้นหา URL ในคลิปบอร์ด <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">ปิดแท็บหรือโปรแกรมอื่นๆ</translation>
<translation id="7129409597930077180">ไม่สามารถจัดส่งสินค้าไปยังที่อยู่นี้ โปรดเลือกที่อยู่อื่น</translation>
<translation id="7135130955892390533">แสดงสถานะ</translation>
<translation id="7138472120740807366">วิธีการนำส่งสินค้า</translation>
<translation id="7139724024395191329">เอมิเรต</translation>
+<translation id="7152423860607593928">Number-14 (ซองจดหมาย)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">ลาเวนเดอร์</translation>
-<translation id="7158980942472052083">URL ไม่ถูกต้อง ต้องเป็น URL ที่มีรูปแบบมาตรฐาน</translation>
<translation id="717330890047184534">รหัส GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">เซิร์ฟเวอร์ที่คุณกำลังจะเข้าถึง <ph name="ORIGIN" /> ขอให้บังคับใช้
+ นโยบายความปลอดภัยกับคำขอทั้งหมดที่จะส่งถึงเซิร์ฟเวอร์ แต่แทนที่จะแสดงนโยบาย
+ เซิร์ฟเวอร์กลับเปลี่ยนเส้นทางเบราว์เซอร์ไปที่อื่น
+ ซึ่งทำให้เบราว์เซอร์ดำเนินการตามคำขอของคุณสำหรับ <ph name="SITE" /> ไม่ได้</translation>
<translation id="7179323680825933600">บันทึกและกรอกวิธีการชำระเงิน</translation>
<translation id="7180611975245234373">รีเฟรช</translation>
<translation id="7182878459783632708">ไม่ได้กำหนดนโยบายไว้</translation>
<translation id="7186367841673660872">แปลหน้าเว็บนี้จาก<ph name="ORIGINAL_LANGUAGE" />เป็น<ph name="LANGUAGE_LANGUAGE" />แล้ว</translation>
<translation id="7192203810768312527">เพิ่มพื้นที่ว่าง <ph name="SIZE" /> เว็บไซต์บางแห่งอาจโหลดช้าลงเมื่อคุณเข้าชมครั้งถัดไป</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">ผู้ดูแลระบบจะเห็นสิ่งต่อไปนี้</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> ไม่เป็นไปตามมาตรฐานความปลอดภัย</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /> เกี่ยวกับปัญหานี้</translation>
<translation id="7219179957768738017">การเชื่อมต่อใช้ <ph name="SSL_VERSION" /></translation>
<translation id="7220786058474068424">กำลังดำเนินการ</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" /> <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">ไซต์ที่จะเปิดมีมัลแวร์</translation>
+<translation id="724766306220616965">คำเตือนและความขัดแย้ง</translation>
<translation id="724975217298816891">ป้อนวันหมดอายุและ CVC สำหรับ <ph name="CREDIT_CARD" /> เพื่ออัปเดตรายละเอียดของบัตร เมื่อคุณยืนยันแล้ว รายละเอียดบัตรของคุณจะแชร์กับเว็บไซต์นี้</translation>
<translation id="7251437084390964440">การกำหนดค่าเครือข่ายไม่เป็นไปตามมาตรฐาน ONC ระบบอาจไม่นำเข้าการกำหนดค่าบางส่วน
รายละเอียดเพิ่มเติม:
@@ -981,11 +1119,14 @@
<translation id="7300012071106347854">น้ำเงินเข้ม</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">รายงานข้อขัดข้องเมื่อ <ph name="CRASH_TIME" /> (ผู้ใช้ขอการอัปโหลด ยังไม่ได้อัปโหลด)</translation>
+<translation id="7313965965371928911">คำเตือน <ph name="BEGIN_LINK" />Google Safe Browsing<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">ความช่วยเหลือเกี่ยวกับการเชื่อมต่อ</translation>
<translation id="7334320624316649418">&amp;ทำซ้ำการจัดลำดับใหม่</translation>
<translation id="733923710415886693">ไม่มีการเปิดเผยใบรับรองของเซิร์ฟเวอร์ผ่านความโปร่งใสของใบรับรอง</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">บรรทัดคำสั่ง </translation>
-<translation id="7365061714576910172">ส่งออกรูปแบบ Linux</translation>
<translation id="7372973238305370288">ผลการค้นหา</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">ไม่</translation>
@@ -993,6 +1134,7 @@
<translation id="7381288752349550461">ลบล้างเซสชันที่มีการจัดการ</translation>
<translation id="7390545607259442187">ยืนยันบัตร</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> ของคุณมีการจัดการ</translation>
<translation id="7407424307057130981">&lt;p&gt;คุณจะเห็นข้อผิดพลาดนี้หากมีซอฟต์แวร์ Superfish ในคอมพิวเตอร์ที่ใช้ระบบปฏิบัติการ Windows&lt;/p&gt;
&lt;p&gt;ทำตามขั้นตอนการปิดใช้ซอฟต์แวร์ชั่วคราวต่อไปนี้เพื่อให้เข้าสู่เว็บได้ ทั้งนี้คุณจะต้องมีสิทธิ์ของผู้ดูแลระบบ&lt;/p&gt;
&lt;ol&gt;
@@ -1003,7 +1145,7 @@
&lt;li&gt;คลิก&lt;strong&gt;ใช้&lt;/strong&gt; แล้วคลิก&lt;strong&gt;ตกลง&lt;/strong&gt;
&lt;li&gt;ไปที่&lt;a href="https://support.google.com/chrome/answer/6098869"&gt;ศูนย์ช่วยเหลือของ Chrome&lt;/a&gt; เพื่อดูวิธีนำซอฟต์แวร์ดังกล่าวออกจากคอมพิวเตอร์อย่างถาวร
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">การจัดการ <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">จัดการรหัสผ่าน…</translation>
<translation id="7419106976560586862">เส้นทางโปรไฟล์</translation>
<translation id="7437289804838430631">เพิ่มข้อมูลติดต่อ</translation>
@@ -1012,22 +1154,24 @@
<translation id="7442725080345379071">ส้มอ่อน</translation>
<translation id="7444046173054089907">เว็บไซต์นี้ถูกบล็อก</translation>
<translation id="7445762425076701745">ไม่สามารถตรวจสอบความถูกต้องของข้อมูลประจำตัวของเซิร์ฟเวอร์ที่คุณเชื่อมต่ออยู่ได้ทั้งหมด คุณกำลังเชื่อมต่อกับเซิร์ฟเวอร์ที่ใช้ชื่อที่ใช้ได้เฉพาะในเครือข่ายของคุณ ซึ่งผู้ออกใบรับรองภายนอกไม่สามารถตรวจสอบการเป็นเจ้าของได้ เนื่องจากผู้ออกใบรับรองบางรายจะยังคงออกใบรับรองให้กับชื่อเหล่านี้อยู่ คุณจึงไม่มีทางมั่นใจได้ว่ากำลังเชื่อมต่อกับเว็บไซต์ที่คุณต้องการดูโดยไม่ใช่ผู้โจมตี</translation>
-<translation id="7449109375006139765">ส่งบันทึกของระบบไปยังเซิร์ฟเวอร์การจัดการ</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" />เกี่ยวกับปัญหานี้</translation>
<translation id="7455133967321480974">ใช้ค่าเริ่มต้นสากล (บล็อก)</translation>
<translation id="7460618730930299168">การแสดงบนหน้าจอแตกต่างจากที่คุณเลือก ต้องการดำเนินการต่อไหม</translation>
<translation id="7473891865547856676">ไม่ ขอบคุณ</translation>
-<translation id="7475525192983021547">รายงานระยะเวลาที่ผู้ใช้ดำเนินการในอุปกรณ์</translation>
<translation id="7481312909269577407">ส่งต่อ</translation>
<translation id="7485870689360869515">ไม่พบข้อมูล</translation>
+<translation id="7498234416455752244">แก้ไขต่อ</translation>
<translation id="7508255263130623398">รหัสอุปกรณ์นโยบายที่ส่งกลับว่างเปล่าหรือไม่ตรงกับรหัสอุปกรณ์ปัจจุบัน</translation>
<translation id="7508870219247277067">เขียวอะโวคาโด</translation>
<translation id="7511955381719512146">Wi-Fi ที่คุณใช้อาจต้องการให้คุณไปที่ <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
<translation id="7514365320538308">ดาวน์โหลด</translation>
<translation id="7518003948725431193">ไม่พบหน้าเว็บสำหรับที่อยู่เว็บ: <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (ซองจดหมาย)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">การเชื่อมต่อกับไซต์นี้ไม่เป็นส่วนตัว</translation>
+<translation id="7535087603100972091">ราคา</translation>
<translation id="7537536606612762813">จำเป็น</translation>
+<translation id="7538364083937897561">A2 (ซองจดหมาย)</translation>
<translation id="7542403920425041731">เมื่อคุณยืนยันแล้ว จะมีการแชร์รายละเอียดบัตรของคุณกับไซต์นี้</translation>
<translation id="7542995811387359312">การป้อนหมายเลขบัตรเครดิตอัตโนมัติถูกปิดใช้งานเนื่องจากฟอร์มนี้ไม่ได้ใช้การเชื่อมต่อที่ปลอดภัย</translation>
<translation id="7543525346216957623">ถามผู้ปกครอง</translation>
@@ -1036,8 +1180,8 @@
<translation id="7552846755917812628">ลองทำตามเคล็ดลับต่อไปนี้:</translation>
<translation id="7554791636758816595">แท็บใหม่</translation>
<translation id="7564049878696755256">คุณอาจเข้าถึงบัญชี <ph name="ORG_NAME" /> ไม่ได้หรือถูกโจรกรรมข้อมูลประจำตัว Chrome ขอแนะนำให้เปลี่ยนรหัสผ่านตอนนี้เลย</translation>
-<translation id="7566125604157659769">ข้อความที่คุณคัดลอกมา</translation>
<translation id="7567204685887185387">เซิร์ฟเวอร์นี้ไม่สามารถพิสูจน์ได้ว่าเป็น <ph name="DOMAIN" /> เพราะอาจมีการออกใบรับรองความปลอดภัยปลอม โดยอาจเกิดจากการกำหนดค่าผิดหรือผู้บุกรุกที่ขัดขวางการเชื่อมต่อของคุณ</translation>
+<translation id="7568105740864181217">เบราว์เซอร์นี้จัดการโดยบริษัท โรงเรียน หรือองค์กรอื่นๆ ผู้ดูแลระบบจะเปลี่ยนการตั้งค่าเบราว์เซอร์จากระยะไกลได้ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chrome ได้ด้วย <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">นำบัตรเครดิตออกจาก Chrome ไหม</translation>
<translation id="7569983096843329377">สีดำ</translation>
<translation id="7578104083680115302">ชำระเงินบนเว็บไซต์และแอปในอุปกรณ์ต่างๆ ได้อย่างรวดเร็วด้วยบัตรที่คุณได้บันทึกไว้กับ Google</translation>
@@ -1048,6 +1192,7 @@
<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="7633909222644580952">ข้อมูลประสิทธิภาพและรายงานข้อขัดข้อง</translation>
<translation id="7637571805876720304">ต้องการนำบัตรเครดิตออกจาก Chromium ใช่ไหม</translation>
<translation id="7639968568612851608">เทาเข้ม</translation>
<translation id="765676359832457558">ซ่อนการตั้งค่าขั้นสูง...</translation>
@@ -1057,9 +1202,11 @@
<translation id="7667346355482952095">โทเค็นนโยบายที่ส่งกลับว่างเปล่าหรือไม่ตรงกับโทเค็นปัจจุบัน</translation>
<translation id="7668654391829183341">อุปกรณ์ที่ไม่รู้จัก</translation>
<translation id="7669271284792375604">ผู้โจมตีเว็บไซต์นี้อาจพยายามหลอกล่อให้คุณติดตั้งโปรแกรมที่เป็นอันตรายต่อประสบการณ์การท่องเว็บของคุณ (ตัวอย่างเช่น โดยการเปลี่ยนแปลงหน้าแรกหรือแสดงโฆษณาเพิ่มเติมในเว็บไซต์ที่คุณเข้าชม)</translation>
+<translation id="7676643023259824263">ค้นหาข้อความในคลิปบอร์ด <ph name="TEXT" /></translation>
<translation id="7681101578153515023">เปลี่ยนเครื่องมือค้นหา</translation>
<translation id="7682287625158474539">จัดส่ง</translation>
<translation id="7687186412095877299">กรอกฟอร์มการชำระเงินด้วยวิธีการชำระเงินที่คุณบันทึกไว้</translation>
+<translation id="7697066736081121494">Prc8 (ซองจดหมาย)</translation>
<translation id="769721561045429135">ขณะนี้คุณมีบัตรต่างๆ ที่ใช้ได้ในอุปกรณ์นี้เท่านั้น คลิก "ทำต่อ" เพื่อดูบัตร</translation>
<translation id="7699293099605015246">บทความไม่พร้อมใช้งานในขณะนี้</translation>
<translation id="7701040980221191251">ไม่มี</translation>
@@ -1071,11 +1218,13 @@
<translation id="774634243536837715">บล็อกเนื้อหาอันตรายแล้ว</translation>
<translation id="7752995774971033316">ไม่ได้จัดการ</translation>
<translation id="7755287808199759310">ผู้ปกครองสามารถเลิกบล็อกเว็บไซต์ให้คุณ</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">ไฟร์วอลล์หรือซอฟต์แวร์ป้องกันไวรัสอาจบล็อกการเชื่อมต่อนี้</translation>
<translation id="7759163816903619567">โดเมนที่แสดง:</translation>
<translation id="7761701407923456692">ใบรับรองของเซิร์ฟเวอร์ไม่ตรงกับ URL</translation>
<translation id="7763386264682878361">โปรแกรมแยกวิเคราะห์ไฟล์ Manifest ของการชำระเงิน</translation>
<translation id="7764225426217299476">เพิ่มที่อยู่</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">เขตปกครอง</translation>
<translation id="7791543448312431591">เพิ่ม</translation>
<translation id="7793809570500803535">หน้าเว็บที่ <ph name="SITE" /> อาจหยุดให้บริการชั่วคราวหรืออาจถูกย้ายไปยังที่อยู่เว็บใหม่อย่างถาวร</translation>
@@ -1087,8 +1236,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">นำคำแนะนำสำหรับแบบฟอร์มออกจาก Chrome ไหม</translation>
<translation id="7815407501681723534">พบ<ph name="SEARCH_RESULTS" /> <ph name="NUMBER_OF_RESULTS" /> รายการสำหรับ "<ph name="SEARCH_STRING" />"</translation>
-<translation id="7818867226424560206">การจัดการนโยบาย</translation>
<translation id="782886543891417279">Wi-Fi ที่คุณใช้ (<ph name="WIFI_NAME" />) อาจต้องการให้คุณไปที่หน้าการเข้าสู่ระบบ</translation>
+<translation id="7836231406687464395">Postfix (ซองจดหมาย)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{ไม่มี}=1{1 แอป (<ph name="EXAMPLE_APP_1" />)}=2{2 แอป (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# แอป (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">อย่างไรก็ตาม ระบบยังมองเห็นคุณ การเข้าสู่โหมดไม่ระบุตัวตนไม่ได้เป็นการซ่อนการท่องเว็บจากนายจ้างของคุณ ผู้ให้บริการอินเทอร์เน็ต หรือเว็บไซต์ที่คุณเข้าชม</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1097,7 +1246,7 @@
<translation id="7878562273885520351">รหัสผ่านของคุณอาจถูกขโมยได้</translation>
<translation id="7882421473871500483">น้ำตาล</translation>
<translation id="7887683347370398519">ตรวจสอบ CVC และลองอีกครั้ง</translation>
-<translation id="7893255318348328562">ชื่อเซสชัน</translation>
+<translation id="7904208859782148177">C3 (ซองจดหมาย)</translation>
<translation id="79338296614623784">ป้อนหมายเลขโทรศัพท์ที่ถูกต้อง</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">หมดอายุ <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1107,21 +1256,25 @@
<translation id="7951415247503192394">(32 บิต)</translation>
<translation id="7956713633345437162">บุ๊กมาร์กบนอุปกรณ์เคลื่อนที่</translation>
<translation id="7961015016161918242">ไม่ต้องเลย</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">ไม่ได้ระบุ</translation>
<translation id="800218591365569300">ลองปิดแท็บหรือโปรแกรมอื่นๆ เพื่อเพิ่มหน่วยความจำ</translation>
+<translation id="8004582292198964060">เบราว์เซอร์</translation>
<translation id="8009225694047762179">จัดการรหัสผ่าน</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{ระบบจะบันทึกบัตรนี้และที่อยู่สำหรับการเรียกเก็บเงินของบัตร คุณจะใช้บัตรนี้ได้เมื่อลงชื่อเข้าใช้ <ph name="USER_EMAIL" />}other{ระบบจะบันทึกบัตรเหล่านี้และที่อยู่สำหรับการเรียกเก็บเงินของบัตร คุณจะใช้บัตรเหล่านี้ได้เมื่อลงชื่อเข้าใช้ <ph name="USER_EMAIL" />}}</translation>
<translation id="8012647001091218357">เราไม่สามารถติดต่อผู้ปกครองของคุณได้ในขณะนี้ โปรดลองอีกครั้ง</translation>
<translation id="8025119109950072390">ผู้โจมตีในเว็บไซต์นี้อาจหลอกล่อให้คุณทำบางสิ่งที่อันตราย เช่น การติดตั้งซอฟต์แวร์หรือเปิดเผยข้อมูลส่วนบุคคล (ตัวอย่างเช่น รหัสผ่าน หมายเลขโทรศัพท์ หรือบัตรเครดิต)</translation>
<translation id="8034522405403831421">หน้าเว็บนี้อยู่ในภาษา<ph name="SOURCE_LANGUAGE" /> ต้องการแปลเป็นภาษา<ph name="TARGET_LANGUAGE" />ไหม</translation>
<translation id="8035152190676905274">ปากกา</translation>
+<translation id="8037117624646282037">ผู้ที่ใช้อุปกรณ์เมื่อเร็วๆ นี้</translation>
<translation id="8037357227543935929">ขอ (ค่าเริ่มต้น)</translation>
<translation id="803771048473350947">ไฟล์</translation>
<translation id="8041089156583427627">ส่งความคิดเห็น</translation>
<translation id="8041940743680923270">ใช้ค่าเริ่มต้นสากล (ถาม)</translation>
<translation id="8042918947222776840">เลือกวิธีรับสินค้า</translation>
<translation id="8057711352706143257">กำหนดค่า "<ph name="SOFTWARE_NAME" />" ไม่ถูกต้อง การถอนการติดตั้ง "<ph name="SOFTWARE_NAME" />" มักแก้ไขปัญหานี้ได้ <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">อุปกรณ์ได้รับการกำหนดค่าเป็น</translation>
+<translation id="8066955247577885446">ขออภัย มีบางอย่างผิดพลาด</translation>
+<translation id="8074253406171541171">10x13 (ซองจดหมาย)</translation>
<translation id="8078141288243656252">เมื่อหมุนแล้วจะใส่หมายเหตุไม่ได้</translation>
<translation id="8079031581361219619">โหลดเว็บไซต์ซ้ำไหม</translation>
<translation id="8088680233425245692">การดูบทความล้มเหลว</translation>
@@ -1130,11 +1283,12 @@
<translation id="8091372947890762290">กำลังรอการเปิดใช้งานบนเซิร์ฟเวอร์</translation>
<translation id="8092774999298748321">ม่วงเข้ม</translation>
<translation id="8094917007353911263">เครือข่ายที่คุณใช้อาจต้องการให้คุณไปที่ <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">นำบัตรที่ใช้ไม่ได้ออกแล้ว</translation>
<translation id="8103161714697287722">วิธีการชำระเงิน</translation>
<translation id="8118489163946903409">วิธีการชำระเงิน</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> จัดการโดย <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" ไม่ได้ติดตั้งในคอมพิวเตอร์หรือเครือข่ายอย่างถูกต้อง โปรดขอให้ผู้ดูแลระบบ IT แก้ไขปัญหานี้</translation>
-<translation id="8130693978878176684">ช่วยต่อไม่ได้แล้ว ลองดำเนินการต่อเองนะ</translation>
<translation id="8131740175452115882">ยืนยัน</translation>
<translation id="8149426793427495338">คอมพิวเตอร์ของคุณเข้าสู่โหมดสลีปแล้ว</translation>
<translation id="8150722005171944719">ไฟล์ที่ <ph name="URL" /> ไม่สามารถอ่านได้ เนื่องจากอาจถูกลบ ย้ายไปแล้ว หรือการอนุญาตของไฟล์อาจป้องกันการเข้าถึง</translation>
@@ -1144,8 +1298,11 @@
<translation id="8197543752516192074">แปลหน้าเว็บ</translation>
<translation id="8201077131113104583">การอัปเดต URL ไม่ถูกต้องสำหรับส่วนขยายรหัส "<ph name="EXTENSION_ID" />"</translation>
<translation id="8202097416529803614">ข้อมูลสรุปคำสั่งซื้อ</translation>
+<translation id="8202370299023114387">ความขัดแย้ง</translation>
+<translation id="8206978196348664717">Prc4 (ซองจดหมาย)</translation>
<translation id="8211406090763984747">การเชื่อมต่อปลอดภัย</translation>
<translation id="8218327578424803826">ตำแหน่งที่มอบหมาย:</translation>
+<translation id="8220146938470311105">C7/C6 (ซองจดหมาย)</translation>
<translation id="8225771182978767009">ผู้ที่ตั้งค่าคอมพิวเตอร์เครื่องนี้เลือกบล็อกเว็บไซต์นี้</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">เปิดหน้าเว็บในแท็บไม่ระบุตัวตนใหม่</translation>
@@ -1157,14 +1314,16 @@
<translation id="825929999321470778">แสดงรหัสผ่านที่บันทึกไว้ทั้งหมด</translation>
<translation id="8261506727792406068">ลบ</translation>
<translation id="8267698848189296333">ลงชื่อเข้าใช้ด้วย <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">เบราว์เซอร์นี้จัดการโดย <ph name="ENROLLMENT_DOMAIN" /> ผู้ดูแลระบบจะเปลี่ยนการตั้งค่าเบราว์เซอร์จากระยะไกลได้ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chrome ได้ด้วย <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">รูปภาพขนาดใหญ่</translation>
<translation id="8286036467436129157">ลงชื่อเข้าใช้</translation>
<translation id="8288807391153049143">แสดงใบรับรอง</translation>
<translation id="8289355894181816810">ติดต่อผู้ดูแลระบบเครือข่ายของคุณหากไม่แน่ใจว่าข้อความนี้หมายถึงอะไร</translation>
<translation id="8293206222192510085">เพิ่มบุ๊กมาร์ก</translation>
<translation id="8294431847097064396">แหล่งที่มา</translation>
<translation id="8298115750975731693">Wi-Fi ที่คุณใช้ (<ph name="WIFI_NAME" />) อาจต้องการให้คุณไปที่ <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /></translation>
+<translation id="8307358339886459768">รูปภาพขนาดเล็ก</translation>
<translation id="8308427013383895095">การแปลล้มเหลวเนื่องจากเกิดปัญหาการเชื่อมต่อกับเครือข่าย </translation>
-<translation id="8311129316111205805">โหลดเซสชัน</translation>
<translation id="8332188693563227489">การเข้าถึง <ph name="HOST_NAME" /> ถูกปฏิเสธ</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">หากคุณเข้าใจความเสี่ยงต่อความปลอดภัย คุณสามารถ<ph name="BEGIN_LINK" />ไปยังไซต์นี้<ph name="END_LINK" />ก่อนที่จะมีการนำโปรแกรมอันตรายออก</translation>
@@ -1182,7 +1341,6 @@
<translation id="8416694386774425977">การกำหนดค่าเครือข่ายไม่ถูกต้องและนำเข้าไม่ได้
รายละเอียดเพิ่มเติม:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">อุปกรณ์จัดการโดย <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">เปลี่ยน</translation>
<translation id="8428213095426709021">การตั้งค่า</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">ชื่อผู้ถือบัตร</translation>
<translation id="861775596732816396">ขนาด 4</translation>
<translation id="8620436878122366504">ผู้ปกครองยังไม่ได้อนุมัติเว็บไซต์นี้</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">บันทึกบัตรนี้ลงในอุปกรณ์นี้</translation>
<translation id="8663226718884576429">สรุปคำสั่งซื้อ <ph name="TOTAL_LABEL" /> รายละเอียดเพิ่มเติม</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, คำตอบ, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">การเชื่อมต่อของคุณไปยัง <ph name="DOMAIN" /> ไม่ได้รับการเข้ารหัส</translation>
<translation id="8718314106902482036">การชำระเงินไม่เสร็จสมบูรณ์</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, คำแนะนำการค้นหา</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google Safe Browsing <ph name="BEGIN_LINK" />พบโปรแกรมที่เป็นอันตราย<ph name="END_LINK" />บน <ph name="SITE" /> เมื่อเร็วๆ นี้</translation>
<translation id="8763927697961133303">อุปกรณ์ USB</translation>
<translation id="8768895707659403558"><ph name="SIGN_IN_LINK" />เพื่อใช้บัตรในอุปกรณ์ทุกเครื่อง</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;ทำซ้ำการนำออก</translation>
<translation id="8792621596287649091">คุณอาจเข้าถึงบัญชี <ph name="ORG_NAME" /> ไม่ได้หรือถูกโจรกรรมข้อมูลประจำตัว Chromium ขอแนะนำให้เปลี่ยนรหัสผ่านตอนนี้เลย</translation>
<translation id="8800988563907321413">คำแนะนำในบริเวณใกล้เคียงจะปรากฏที่นี่</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">การแชร์กับ Google</translation>
<translation id="8858065207712248076">Chrome ขอแนะนำให้รีเซ็ตรหัสผ่าน <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> หากคุณใช้รหัสผ่านนี้ซ้ำในเว็บไซต์อื่น</translation>
<translation id="8866481888320382733">ข้อผิดพลาดในการแยกวิเคราะห์การตั้งค่านโยบาย</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">เพิ่งปิด</translation>
<translation id="8874824191258364635">ป้อนหมายเลขบัตรที่ถูกต้อง</translation>
<translation id="8891727572606052622">โหมดพร็อกซีไม่ถูกต้อง</translation>
<translation id="8903921497873541725">ขยาย</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">คุณต้องการบันทึกบัตรนี้ในบัญชี Google ไหม</translation>
<translation id="8932102934695377596">นาฬิกาช้าเกินไป</translation>
<translation id="893332455753468063">เพิ่มชื่อ</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">ผู้ดูแลระบบได้กำหนดค่าใบรับรองรูทที่กำหนดเอง ซึ่งอาจทำให้ผู้ดูแลระบบดูเนื้อหาของเว็บไซต์ที่คุณเข้าชมได้</translation>
<translation id="8943282376843390568">เหลืองมะนาว</translation>
<translation id="8957210676456822347">การให้สิทธิ์แคปทีฟพอร์ทัล</translation>
+<translation id="8966619695390250636">หรือคุณหมายถึง</translation>
<translation id="8968766641738584599">บันทึกบัตร</translation>
<translation id="8971063699422889582">ใบรับรองของเซิร์ฟเวอร์หมดอายุแล้ว</translation>
<translation id="8975012916872825179">รวมข้อมูล เช่น หมายเลขโทรศัพท์ อีเมล และที่อยู่สำหรับจัดส่ง</translation>
<translation id="8978053250194585037">เมื่อเร็วๆ นี้ Google Safe Browsing <ph name="BEGIN_LINK" />ตรวจพบฟิชชิง<ph name="END_LINK" />ใน <ph name="SITE" /> เว็บไซต์ฟิชชิงปลอมเป็นเว็บไซต์อื่นๆ เพื่อหลอกคุณ</translation>
<translation id="8983003182662520383">วิธีการชำระเงินและที่อยู่จาก Google Pay</translation>
<translation id="8987927404178983737">เดือน</translation>
-<translation id="8988408250700415532">มีบางอย่างผิดพลาด คุณสั่งซื้อให้เสร็จในเว็บไซต์ได้นะ</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">ไซต์ที่จะเปิดมีโปรแกรมที่เป็นอันตราย</translation>
<translation id="8997023839087525404">เซิร์ฟเวอร์แสดงใบรับรองที่ไม่มีการเปิดเผยต่อสาธารณะโดยใช้นโยบายความโปร่งใสของใบรับรอง ซึ่งเป็นข้อกำหนดสำหรับใบรับรองบางรายการ เพื่อยืนยันว่าเชื่อถือได้และป้องกันการจู่โจม</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">เปิดการตั้งค่าเว็บไซต์</translation>
<translation id="9020200922353704812">ต้องใส่ที่อยู่สำหรับการเรียกเก็บเงินของบัตร</translation>
<translation id="9020542370529661692">หน้านี้ได้รับการแปลเป็น <ph name="TARGET_LANGUAGE" /> แล้ว</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(ไม่ถูกต้อง)</translation>
<translation id="9035022520814077154">ข้อผิดพลาดของการรักษาความปลอดภัย</translation>
<translation id="9038649477754266430">ใช้บริการการคาดคะเนเพื่อโหลดหน้าได้เร็วขึ้น</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">การค้นหา <ph name="TEXT" /> จากประวัติ</translation>
<translation id="9069693763241529744">ถูกบล็อกโดยส่วนขยาย</translation>
<translation id="9076283476770535406">เว็บไซต์นี้อาจมีเนื้อหาสำหรับผู้ใหญ่</translation>
+<translation id="9076630408993835509">เบราว์เซอร์นี้ไม่ได้จัดการโดยบริษัทหรือองค์กรอื่นๆ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chrome <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">ต้องระบุข้อมูลเพิ่มเติม</translation>
<translation id="9080712759204168376">สรุปการสั่งซื้อ</translation>
<translation id="9103872766612412690">โดยทั่วไป <ph name="SITE" /> จะใช้การเข้ารหัสเพื่อปกป้องข้อมูลของคุณ เมื่อ Chromium พยายามเชื่อมต่อกับ <ph name="SITE" /> ในครั้งนี้ เว็บไซต์ดังกล่าวส่งข้อมูลรับรองที่ผิดปกติและไม่ถูกต้องกลับมา เหตุการณ์นี้อาจเกิดขึ้นเมื่อผู้บุกรุกพยายามปลอมเป็น <ph name="SITE" /> หรือหน้าจอการลงชื่อเข้าใช้ Wi-Fi รบกวนการเชื่อมต่อ ข้อมูลของคุณยังปลอดภัยอยู่เนื่องจาก Chromium หยุดการเชื่อมต่อก่อนมีการแลกเปลี่ยนข้อมูล</translation>
<translation id="9106062320799175032">เพิ่มที่อยู่สำหรับการเรียกเก็บเงิน</translation>
-<translation id="9110718169272311511">Google Assistant ใน Chrome พร้อมใช้งานที่บริเวณด้านล่างของหน้าจอ</translation>
<translation id="9114524666733003316">กำลังยืนยันบัตร…</translation>
<translation id="9128870381267983090">เชื่อมต่อกับเครือข่าย</translation>
<translation id="9137013805542155359">แสดงหน้าเว็บเดิม</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">&amp;เลิกทำการแก้ไข</translation>
<translation id="9154194610265714752">อัปเดตแล้ว</translation>
<translation id="9157595877708044936">กำลังตั้งค่า...</translation>
+<translation id="9158625974267017556">C6 (ซองจดหมาย)</translation>
<translation id="9168814207360376865">อนุญาตให้เว็บไซต์ตรวจสอบว่าคุณได้บันทึกวิธีการชำระเงินไว้ไหม</translation>
<translation id="9169664750068251925">บล็อกบนไซต์นี้เสมอ</translation>
<translation id="9170848237812810038">เ&amp;ลิกทำ</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">ภาพ</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ล้างฟอร์ม</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">คุณอาจสูญเสียสิทธิ์เข้าถึงบัญชี Google ของคุณ Chromium ขอแนะนำให้เปลี่ยนรหัสผ่านทันที ระบบจะขอให้คุณลงชื่อเข้าใช้</translation>
<translation id="939736085109172342">โฟลเดอร์ใหม่</translation>
<translation id="945855313015696284">ตรวจสอบข้อมูลด้านล่างและลบบัตรที่ไม่ถูกต้อง</translation>
<translation id="951104842009476243">บัตรเดบิตและบัตรเติมเงินที่ยอมรับ</translation>
+<translation id="958202389743790697">ถูกบล็อกตามนโยบายความปลอดภัยของ <ph name="ORIGIN" /></translation>
<translation id="962484866189421427">เนื้อหานี้อาจพยายามติดตั้งแอปที่หลอกลวงซึ่งปลอมเป็นเนื้อหาอย่างอื่นหรือรวบรวมข้อมูลที่อาจนำไปใช้ติดตามคุณ <ph name="BEGIN_LINK" />แสดงเนื้อหา<ph name="END_LINK" /></translation>
<translation id="969892804517981540">รุ่นที่เป็นทางการ</translation>
<translation id="973773823069644502">เพิ่มที่อยู่สำหรับนำส่งสินค้า</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">วิธีการชำระเงิน</translation>
<translation id="985199708454569384">&lt;p&gt;คุณจะเห็นข้อผิดพลาดนี้หากวันที่และเวลาของคอมพิวเตอร์หรืออุปกรณ์เคลื่อนที่ไม่ถูกต้อง&lt;/p&gt;
&lt;p&gt;ในการแก้ไขข้อผิดพลาด ให้เปิดนาฬิกาของอุปกรณ์ ตรวจสอบให้แน่ใจว่าเวลาและวันที่ถูกต้องแล้ว&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">รุ่นนักพัฒนา</translation>
<translation id="989988560359834682">แก้ไขที่อยู่</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_tr.xtb b/chromium/components/strings/components_strings_tr.xtb
index 89bc8273392..2c16626cffe 100644
--- a/chromium/components/strings/components_strings_tr.xtb
+++ b/chromium/components/strings/components_strings_tr.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="tr">
-<translation id="1005145902654145231">Oturum yeniden adlandırılamadı.</translation>
<translation id="1008557486741366299">Şimdi Değil</translation>
<translation id="1010200102790553230">Sayfayı daha sonra yükle</translation>
<translation id="1015730422737071372">Diğer ayrıntıları sağlayın</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">bilinmeyen ad</translation>
<translation id="1050038467049342496">Diğer uygulamaları kapatın</translation>
<translation id="1055184225775184556">Eklemeyi &amp;Geri Al</translation>
+<translation id="1056898198331236512">Uyarı</translation>
<translation id="1058479211578257048">Kartlar kaydediliyor...</translation>
<translation id="10614374240317010">Hiç kaydedilmeyecekler</translation>
+<translation id="1062160989074299343">Prc10 (Zarf)</translation>
<translation id="106701514854093668">Masaüstü Yer İşaretleri</translation>
<translation id="1074497978438210769">Güvenli değil</translation>
<translation id="1080116354587839789">Genişliğe sığdır</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Kart Üzerindeki Adı Ekleyin</translation>
<translation id="1089439967362294234">Şifreyi Değiştir</translation>
<translation id="109743633954054152">Şifreleri Chrome ayarlarından yönetin</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Web siteleri güvenliklerini güncellerken uyarılar yaygın olarak görülebilir. Yakında bu işlev iyileştirilecektir.</translation>
<translation id="1126551341858583091">Yerel depolama alanındaki boyut <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Politika önbelleği uygun</translation>
+<translation id="1131264053432022307">Kopyalanan Resim</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>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Yeniden adlandır</translation>
<translation id="1175364870820465910">Ya&amp;zdır...</translation>
<translation id="1181037720776840403">Kaldır</translation>
<translation id="1197088940767939838">Turuncu</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Cihazınızın adı</translation>
<translation id="124116460088058876">Diğer diller</translation>
<translation id="1250759482327835220">Bir dahaki sefere daha hızlı ödeme yapmak için kartınızı ve fatura adresinizi Google Hesabınıza kaydedin.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (senkronize edildi)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Komut satırı varyasyonları</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="1314614906530272393">Seçilen oturum mevcut değil.</translation>
+<translation id="1320233736580025032">Prc1 (Zarf)</translation>
+<translation id="132301787627749051">Panoda resmi ara</translation>
<translation id="1323433172918577554">Daha Fazla Göster</translation>
<translation id="132390688737681464">Adresleri Kaydet ve Doldur</translation>
<translation id="1333989956347591814">Etkinliğiniz şunlar tarafından <ph name="BEGIN_EMPHASIS" />yine de görülebilir<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Alınacağı adres</translation>
<translation id="1348198688976932919">Girmekte olduğunuz site tehlikeli uygulamalar içeriyor</translation>
<translation id="1348779747280417563">Adı onaylayın</translation>
+<translation id="1357195169723583938">Cihazı son zamanlarda kimin ne zaman kullandığı</translation>
+<translation id="1364822246244961190">Bu politika engellendiği için politikanın değeri yoksayılacak.</translation>
<translation id="1374468813861204354">öneriler</translation>
+<translation id="1374692235857187091">Index-4x6 (Kartpostal)</translation>
<translation id="1375198122581997741">Sürüm Hakkında</translation>
<translation id="1376836354785490390">Daha Az Göster</translation>
<translation id="1377321085342047638">Kart Numarası</translation>
<translation id="138218114945450791">Açık Mavi</translation>
+<translation id="1382194467192730611">Yöneticiniz USB cihaza izin veriyor</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> hiç veri göndermedi.</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> sitesi tüm istekleri için bir güvenlik politikasının
+ geçerli olmasını talep etti ve bu politika şu anda sitenin güvenli olmadığını
+ belirtiyor.</translation>
<translation id="1405567553485452995">Açık Yeşil</translation>
<translation id="1407135791313364759">Tümünü aç</translation>
<translation id="1413809658975081374">Gizlilik hatası</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Evet</translation>
<translation id="1430915738399379752">Yazdır</translation>
<translation id="1455413310270022028">Silgi</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Daha fazla göster</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Gönderim Adresi Seç</translation>
+<translation id="1492194039220927094">Politikalar aktarılabilir:</translation>
<translation id="1501859676467574491">Google Hesabımdaki kartları göster</translation>
-<translation id="1506687042165942984">Bu sayfanın kaydedilmiş (eski olduğu bilinen) bir kopyasını gösterin.</translation>
<translation id="1507202001669085618">&lt;p&gt;İnternete girmek için oturum açmanızı gerektiren bir kablosuz portal kullanıyorsanız bu hatayı görürsünüz.&lt;/p&gt;
&lt;p&gt;Hatayı gidermek için, açmaya çalıştığınız sayfada &lt;strong&gt;Bağlan&lt;/strong&gt;'ı tıklayın.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Telefon numarası gerekli</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Oluşturma Tarihi</translation>
<translation id="1521655867290435174">Google E-Tablolar</translation>
<translation id="1527263332363067270">Bağlantı bekleniyor…</translation>
+<translation id="1529521330346880926">10x15 (Zarf)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Bu sayfanın mesajı</translation>
<translation id="153384715582417236">Şimdilik hepsi bu</translation>
<translation id="154408704832528245">Teslimat Adresi Seç</translation>
<translation id="1549470594296187301">Bu özelliğin kullanılabilmesi için JavaScript etkinleştirilmelidir.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Son kullanma tarihi girin</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Kopyaladığınız resim</translation>
<translation id="1620510694547887537">Kamera</translation>
<translation id="1623104350909869708">Bu sayfanın daha fazla iletişim kutusu oluşturmasını önle</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Oturumu sonlandır</translation>
<translation id="1639239467298939599">Yükleniyor</translation>
<translation id="1640180200866533862">Kullanıcı politikaları</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Sunucu sertifikasında zayıf bir şifreleme anahtarı var.</translation>
<translation id="1697532407822776718">Artık hazırsınız!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Doküman, ek açıklama ilave edilemeyecek kadar büyük</translation>
<translation id="1721312023322545264">Bu siteyi ziyaret etmek için <ph name="NAME" /> size izin vermelidir</translation>
<translation id="1721424275792716183">* Zorunlu alan</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Sistem yöneticisiyle iletişime geçmeyi deneyin.</translation>
<translation id="1740951997222943430">Geçerli bir son kullanma ayı girin</translation>
<translation id="1743520634839655729">Gelecek sefer daha hızlı ödeme yapabilmek için kartınızı, adınızı ve fatura adresinizi Google hesabınıza kaydedin.</translation>
+<translation id="1745880797583122200">Tarayıcınız yönetilmektedir</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>
@@ -152,8 +172,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Kart Sahibinin Adı</translation>
<translation id="1821930232296380041">Geçersiz istek veya istek parametreleri</translation>
+<translation id="1822540298136254167">Ziyaret ettiğiniz web siteleri ve bu sitelerde geçirdiğiniz zaman</translation>
<translation id="1826516787628120939">Kontrol ediliyor</translation>
<translation id="1834321415901700177">Bu site zararlı programlar içeriyor</translation>
<translation id="1839551713262164453">Politika değerlerini doğrulama işlemi hatalarla başarısız oldu</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Chrome'un tarama geçmişi verilerini temizleyin</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{ve 1 uygulama daha}other{ve # uygulama daha}}</translation>
<translation id="2003709556000175978">Şifrenizi şimdi sıfırlayın</translation>
+<translation id="20053308747750172">Gittiğiniz sunucu (<ph name="ORIGIN" />) kendisine gelen tüm isteklere
+ bir güvenlik politikasının uygulanmasını talep etmişti. Ancak şimdi
+ geçersiz bir politika sunduğu için tarayıcı, <ph name="SITE" /> sitesiyle ilgili
+ isteğinizi yerine getiremiyor.</translation>
<translation id="2025186561304664664">Proxy, otomatik yapılandırıldı değerine ayarlandı.</translation>
<translation id="2030481566774242610">Şunu mu demek istediniz?: <ph name="LINK" /></translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Proxy'yi ve güvenlik duvarını kontrol etme<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Bölüm</translation>
<translation id="2102134110707549001">Güçlü Şifre Öner…</translation>
<translation id="2108755909498034140">Bilgisayarınızı yeniden başlatın</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Kart</translation>
<translation id="2114841414352855701"><ph name="POLICY_NAME" /> tarafından geçersiz kılındığı için yoksayıldı.</translation>
<translation id="213826338245044447">Mobil Yer İşaretleri</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Zarf)</translation>
<translation id="2181821976797666341">Politikalar</translation>
<translation id="2183608646556468874">Telefon Numarası</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 adres}other{# adres}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Telefon numarası</translation>
<translation id="2283340219607151381">Adresleri kaydet ve doldur</translation>
<translation id="2292556288342944218">İnternet erişiminiz engellendi</translation>
+<translation id="2294558542833290837">Başta açtığınız bağlantı normal değil</translation>
+<translation id="2297722699537546652">B5 (Zarf)</translation>
+<translation id="2310021320168182093">Chou2 (Zarf)</translation>
<translation id="2316887270356262533">1 MB'tan az yer açar. Bir sonraki ziyaretinizde bazı siteler daha yavaş yüklenebilir.</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> için kullanıcı adı ve şifre gerekiyor.</translation>
<translation id="2317583587496011522">Banka kartları kabul edilir.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" /> için kullanım süresi sonu: <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Ayar yöneticinizin kontrolü altındadır</translation>
+<translation id="2346319942568447007">Kopyalanan resim</translation>
<translation id="2349790679044093737">VR oturumu etkin</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>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Yakalanan kilitlenme raporu (<ph name="CRASH_TIME" />) yüklenmedi</translation>
<translation id="2367567093518048410">Düzey</translation>
<translation id="2378238891085281592">Gizli moda geçtiniz</translation>
+<translation id="2380886658946992094">Hukuk</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="2410754574180102685">Government-Legal</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="2418081434543109369">Gittiğiniz sunucu (<ph name="ORIGIN" />) kendisine gelen tüm isteklere
+ bir güvenlik politikasının uygulanmasını talep etmişti. Ancak şimdi
+ politika sunamadığı için tarayıcı, <ph name="SITE" /> sitesiyle ilgili isteğinizi
+ yerine getiremiyor.</translation>
<translation id="244665789865330679">Cihazınız ve hesabınız <ph name="ENROLLMENT_DOMAIN" /> tarafından yönetiliyor. Bu durumda yöneticiniz cihazınızı ve hesabınızı uzaktan yapılandırabilir.</translation>
<translation id="2463193859425327265">Ana Sayfayı değiştir</translation>
<translation id="2463739503403862330">Doldur</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Teslimat Yöntemi Seç</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Ağ Teşhislerini Çalıştırma<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Bu sayfayı çevir</translation>
<translation id="2479410451996844060">Geçersiz arama URL'si.</translation>
<translation id="2482878487686419369">Bildirimler</translation>
<translation id="248348093745724435">Makine politikaları</translation>
+<translation id="2485387744899240041">Cihazınız ve tarayıcınız için kullanıcı adları</translation>
<translation id="2491120439723279231">Sunucu sertifikası hatalar içeriyor.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Yeni kart tara</translation>
<translation id="2501278716633472235">Geri dön</translation>
<translation id="2503184589641749290">Kabul edilen banka ve ön ödemeli kartlar</translation>
<translation id="2515629240566999685">Bulunduğunuz bölgedeki sinyali kontrol etme</translation>
-<translation id="2516852381693169964"><ph name="SEARCH_ENGINE" /> içinde Resim ara</translation>
<translation id="2523886232349826891">Yalnızca bu cihazda kaydedildi</translation>
<translation id="2524461107774643265">Daha Fazla Bilgi Ekleyin</translation>
<translation id="2536110899380797252">Adres Ekle</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Zarf)</translation>
<translation id="2625385379895617796">Saatiniz ileri</translation>
<translation id="2634124572758952069"><ph name="HOST_NAME" /> ana makinesinin sunucu IP adresi bulunamadı.</translation>
<translation id="2639739919103226564">Durum:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Diğer sekmeleri veya uygulamaları kapatın</translation>
<translation id="267371737713284912">işlemi geri almak için <ph name="MODIFIER_KEY_DESCRIPTION" /> tuşuna basın</translation>
<translation id="2674170444375937751">Bu sayfaları geçmişinizden silmek istediğinizden emin misiniz?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Çık</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Kabul Edilen Kartlar</translation>
<translation id="2702801445560668637">Okuma Listesi</translation>
<translation id="2704283930420550640">Değer, biçimle eşleşmiyor.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Seçilen öğeleri kaldır</translation>
<translation id="277133753123645258">Gönderim yöntemi</translation>
<translation id="277499241957683684">Eksik cihaz kaydı</translation>
-<translation id="2781030394888168909">MacOS Biçiminde Dışa Aktar</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Bağlantı sıfırlandı.</translation>
<translation id="2788784517760473862">Kabul edilen kredi kartları</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Gizli Pencereyi Aç</translation>
+<translation id="2850739647070081192">Invite (Zarf)</translation>
<translation id="2851634818064021665">Bu siteyi ziyaret etmek için izninizin olması gerekir</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Kart kaydedilsin mi?</translation>
<translation id="2903493209154104877">Adresler</translation>
<translation id="290376772003165898">Sayfa <ph name="LANGUAGE" /> dilinde değil mi?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Teslimat Yöntemi</translation>
<translation id="2928905813689894207">Fatura Adresi</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=1{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> adres daha}other{<ph name="SHIPPING_ADDRESS_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> adres daha}}</translation>
+<translation id="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Zarf)</translation>
<translation id="3024663005179499861">Yanlış politika türü</translation>
<translation id="3037605927509011580">Hay aksi!</translation>
<translation id="3041612393474885105">Sertifika Bilgileri</translation>
+<translation id="3060227939791841287">C9 (Zarf)</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="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Alınacağı Adres Ekle</translation>
<translation id="3105172416063519923">Öğe Kimliği:</translation>
<translation id="3109728660330352905">Bu sayfayı görüntüleme yetkiniz yok.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> üzerinde <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">Ödemeyi iptal et</translation>
<translation id="3207960819495026254">Yer işareti koyuldu</translation>
-<translation id="3209375525920864198">Lütfen geçerli bir oturum adı girin.</translation>
+<translation id="321912867715453276">Uyarı: Bu politikada birden fazla kaynak var, ancak değerler aynı.</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="3229041911291329567">Cihazınız ve tarayıcınızla ilgili sürüm bilgileri</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Kart üzerindeki ismi ekle</translation>
<translation id="3287510313208355388">Çevrimiçi olduğunda indir</translation>
<translation id="3293642807462928945"><ph name="POLICY_NAME" /> politikası ile ilgili daha fazla bilgi edinin</translation>
<translation id="3303855915957856445">Arama sonucu bulunamadı</translation>
-<translation id="3305707030755673451">Verileriniz <ph name="TIME" /> tarihinde senkronizasyon parolanızla şifrelendi. Senkronizasyonu başlatmak için senkronizasyon parolanızı girin.</translation>
<translation id="3320021301628644560">Fatura adresi ekle</translation>
<translation id="3324983252691184275">Kızıl</translation>
<translation id="3338095232262050444">Güvenli</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Düzenlemeyi Yeniden Yap</translation>
<translation id="342781501876943858">Chromium, şifrenizi başka sitelerde kullandıysanız sıfırlamanızı önerir.</translation>
<translation id="3431636764301398940">Bu kartı bu cihaza kaydet</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Bu cihazın sahibi dinozor oyununu kapattı.</translation>
<translation id="3447884698081792621">Sertifikayı göster (yayınlayan: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Getirme aralığı:</translation>
+<translation id="3456231139987291353">Number-11 (Zarf)</translation>
<translation id="3461824795358126837">Vurgulayıcı</translation>
<translation id="3462200631372590220">Gelişmiş bilgileri gizle</translation>
<translation id="3467763166455606212">Kart sahibinin adı zorunludur</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Kredi ve ön ödemeli kartlar kabul edilir.</translation>
<translation id="3582930987043644930">Ad ekleyin</translation>
<translation id="3583757800736429874">Taşımayı &amp;Yeniden Yap</translation>
+<translation id="35866233670761917">Yöneticileriniz, ziyaret ettiğiniz web sitelerinin içeriğini göremezler</translation>
<translation id="3586931643579894722">Ayrıntıları gizle</translation>
+<translation id="3592413004129370115">Italian (Zarf)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Boyut 2</translation>
<translation id="3615877443314183785">Geçerli bir son kullanma tarihi girin</translation>
<translation id="36224234498066874">Göz Atma Verilerini Temizle...</translation>
<translation id="362276910939193118">Tam Geçmişi Göster</translation>
-<translation id="3623476034248543066">Değeri göster</translation>
<translation id="3630155396527302611">Ağa erişmesine izin verilmiş bir program olarak zaten listeleniyorsa,
listeden kaldırıp tekrar eklemeyi deneyin.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Doğrulama başarılı</translation>
<translation id="3655670868607891010">Bunu çok sık görüyorsanız, şunları deneyin: <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Düzeltme</translation>
<translation id="366077651725703012">Kredi Kartını Güncelle</translation>
<translation id="3676592649209844519">Cihaz kimliği:</translation>
+<translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; adresine gitmek mi istemiştiniz?</translation>
<translation id="3678029195006412963">İstek imzalanamadı</translation>
<translation id="3678529606614285348">Sayfayı yeni Gizli pencerede açın (Ctrl-Üst Karakter-N)</translation>
<translation id="3679803492151881375">Kilitlenme raporunun oluşturulma zamanı: <ph name="CRASH_TIME" />, raporun yüklenme zamanı: <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Kullandığınız ağ bir giriş sayfasını ziyaret etmenizi gerektiriyor olabilir.</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="3709599264800900598">Kopyalanan Metin</translation>
<translation id="3712624925041724820">Lisanslar bitti</translation>
<translation id="3714780639079136834">Mobil veriyi veya kablosuz bağlantıyı açma</translation>
<translation id="3715597595485130451">Kablosuz Ağa Bağlanma</translation>
<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="372429172604983730">Bu hataya neden olabilecek uygulamalar arasında virüsten korunma programları, güvenlik duvarları ve web filtreleme veya proxy yazılımları sayılabilir.</translation>
+<translation id="373042150751172459">B4 (Zarf)</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="3745099705178523657">Onayladığınızda Google Hesabınızdaki kart bilgileriniz bu siteyle paylaşılı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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Son kullanma tarihi: <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Boyut 16</translation>
+<translation id="3797522431967816232">Prc3 (Zarf)</translation>
<translation id="3807873520724684969">Zararlı içerik engellendi.</translation>
<translation id="3810973564298564668">Yönet</translation>
<translation id="382518646247711829">Proxy sunucu kullanıyorsanız...</translation>
<translation id="3828924085048779000">Boş parolaya izin verilmez.</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> diğer işlevler için uzantılar yüklemiş. Söz konusu uzantıların bazı verilerinize erişimi bulunuyor.</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>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Bu sitede her zaman sor</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Bu oturum adı zaten var.</translation>
<translation id="3987940399970879459">1 MB'tan az</translation>
+<translation id="4008849406247176967">Uyarı: Bu politikada, birbiriyle çelişen değerler içeren birden fazla kaynak bulunuyor.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{Yakındaki 1 web sayfası}other{Yakındaki # web sayfası}}</translation>
<translation id="4030383055268325496">Eklemeyi &amp;geri al</translation>
+<translation id="4032320456957708163">Tarayıcınız <ph name="ENROLLMENT_DOMAIN" /> tarafından yönetilmektedir</translation>
<translation id="4058922952496707368">"<ph name="SUBKEY" />" anahtarı: <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Zarf)</translation>
<translation id="4067947977115446013">Geçerli Adres Ekleyin</translation>
<translation id="4072486802667267160">Ödemeniz işlenirken bir hata oluştu. Lütfen tekrar deneyin.</translation>
<translation id="4075732493274867456">İstemci ve sunucu, ortak bir SSL protokolü sürümünü veya şifre setini desteklemiyor.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Mor</translation>
<translation id="4165986682804962316">Site ayarları</translation>
<translation id="4171400957073367226">Geçersiz doğrulama imzası</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> öğe daha}other{<ph name="ITEM_COUNT" /> öğe daha}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Zarf)</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="4221630205957821124">&lt;h4&gt;1. Adım: Portalda oturum açın&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Şifreyi sıfırla</translation>
<translation id="4280429058323657511">, son kullanma tarihi <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Bu kart Google Hesabınıza kaydedildi}other{Bu kartlar Google Hesabınıza kaydedildi}}</translation>
+<translation id="42981349822642051">Genişlet</translation>
+<translation id="4302965934281694568">Chou3 (Zarf)</translation>
<translation id="4305817255990598646">Anahtar</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Engelle (varsayılan)</translation>
+<translation id="4318566738941496689">Cihazınızın adı ve ağ adresi</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="4340982228985273705">Bu bilgisayarın kurumsal olarak yönetilmediği algılandığı için politika yalnızca Chrome Web Mağazası'nda barındırılan uzantıları otomatik olarak yükleyebilir. Chrome Web Mağazası'nın güncelleme URL'si "<ph name="CWS_UPDATE_URL" />" şeklindedir.</translation>
<translation id="4346197816712207223">Kabul Edilen Kredi Kartları</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Ödeme yöntemlerini yönet...</translation>
+<translation id="4367563149485757821">Number-12 (Zarf)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Telefon</translation>
<translation id="4406896451731180161">arama sonuçları</translation>
-<translation id="4406972042435603828">Yöneticileriniz etkili özelliklere sahip uzantılar yüklemiş.</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> çerez</translation>
<translation id="4415426530740016218">Alınacağı Adres</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="443121186588148776">Seri bağlantı noktası</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> giriş sertifikanızı kabul etmedi veya giriş sertifikası sağlanmamış olabilir.</translation>
<translation id="4434045419905280838">Pop-up'lar ve yönlendirmeler</translation>
+<translation id="4435702339979719576">Kartpostal)</translation>
<translation id="443673843213245140">Proxy kullanımı devre dışı, ancak açık bir proxy yapılandırması belirtildi.</translation>
<translation id="445100540951337728">Kabul edilen banka kartları</translation>
+<translation id="4466881336512663640">Formda yaptığınız değişiklikler kaybolacak. Devam etmek istediğinizden emin misiniz?</translation>
<translation id="4482953324121162758">Bu site çevrilmeyecek.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Geçersiz URL. Standart şemaya sahip bir URL olmalıdır. Ör. http://example.com veya https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Zarf)</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="4517607026994743406">Comm-10 (Zarf)</translation>
<translation id="4522570452068850558">Ayrıntılar</translation>
<translation id="4524805452350978254">Kartları yönet</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Uzantılarınızı devre dışı bırakmayı deneyin</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Teslimat</translation>
+<translation id="4579056131138995126">Personal (Zarf)</translation>
<translation id="4582204425268416675">Kartı kaldır</translation>
<translation id="4587425331216688090">Adres Chrome'dan kaldırılsın mı?</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="4597348597567598915">Boyut 8</translation>
+<translation id="4600854749408232102">C6/C5 (Zarf)</translation>
<translation id="4646534391647090355">İndirilenlere git</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="467809019005607715">Google Slaytlar</translation>
<translation id="4690462567478992370">Geçersiz sertifika kullanımını durdur</translation>
+<translation id="4691835149146451662">Architecture-A (Zarf)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">Bağlantınız kesildi</translation>
<translation id="471880041731876836">Bu siteyi ziyaret etmek için izniniz yok</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Windows Ağ Teşhislerini Çalıştırma<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Politikaları yeniden yükle</translation>
<translation id="4728558894243024398">Platform</translation>
+<translation id="4731967714531604179">Prc2 (Zarf)</translation>
<translation id="4736825316280949806">Chromium'u yeniden başlatın</translation>
<translation id="473775607612524610">Güncelle</translation>
<translation id="4738601419177586157"><ph name="TEXT" /> arama önerisi</translation>
<translation id="4742407542027196863">Şifreleri yönet…</translation>
<translation id="4744603770635761495">Çalıştırılabilir Yol</translation>
+<translation id="4746351372139058112">Mesajlar</translation>
<translation id="4750917950439032686">Bilgileriniz (örneğin şifreler veya kredi kartı numaraları), bu siteye gönderilirken gizli olur.</translation>
<translation id="4756388243121344051">&amp;Geçmiş</translation>
<translation id="4758311279753947758">İletişim bilgilerinizi ekleyin</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478"><ph name="URL" /> adresindeki web sayfası, geçici olarak kullanılamıyor veya kalıcı olarak yeni bir web adresine taşınmış olabilir.</translation>
<translation id="4771973620359291008">Bilinmeyen bir hata oluştu.</translation>
<translation id="4785689107224900852">Bu sekmeye geç</translation>
-<translation id="4792143361752574037">Oturum dosyalarına erişimle ilgili bir sorun oluştu. Diske kaydetme şu anda devre dışı bırakıldı. Tekrar denemek için lütfen sayfayı yeniden yükleyin.</translation>
<translation id="4798078619018708837">Kart bilgilerinizi güncellemek için <ph name="CREDIT_CARD" /> numaralı karta ait son kullanma tarihini ve CVC kodunu girin. Onayladığınızda Googe Hesabınızdaki kart bilgileriniz bu siteyle paylaşılır.</translation>
<translation id="4800132727771399293">Son kullanma tarihinizi ve CVC'nizi kontrol edip tekrar deneyin</translation>
+<translation id="480334179571489655">Kaynak Politikası Hatası</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Aç</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Sonuç yok</translation>
<translation id="4950898438188848926">Sekme değiştirme düğmesi, açık sekmeye geçmek için enter tuşuna basın, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">İşlemler</translation>
-<translation id="495832697253704892">Uzantı raporlama</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Listeyi genişlet</translation>
<translation id="4974590756084640048">Uyarıları yeniden etkinleştir</translation>
+<translation id="4984339528288761049">Prc5 (Zarf)</translation>
<translation id="4989163558385430922">Tümünü göster</translation>
<translation id="4989809363548539747">Bu eklenti desteklenmiyor</translation>
-<translation id="4996230189582812866">Raporlama</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="5014174725590676422">Chrome'da Google Asistan'ın ilk kez çalışma ekranı aşağıda gösterilmiştir</translation>
<translation id="5015510746216210676">Makine Adı:</translation>
+<translation id="5017554619425969104">Kopyalanan metin</translation>
<translation id="5018422839182700155">Bu sayfa açılamıyor</translation>
<translation id="5019198164206649151">Yedekleme deposu kötü durumda</translation>
<translation id="5023310440958281426">Yöneticinizin politikalarını inceleyin.</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Yerel Bağlam <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">İzin ver</translation>
<translation id="5040262127954254034">Gizlilik</translation>
+<translation id="5043480802608081735">Kopyalanan Bağlantı</translation>
<translation id="5045550434625856497">Hatalı parola</translation>
<translation id="5056549851600133418">Size uygun makaleler</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Proxy adresini kontrol etme<ph name="END_LINK" /></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">Eyalet</translation>
+<translation id="5097099694988056070">CPU/RAM kullanımı gibi cihaz istatistikleri</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">Cihazınız <ph name="ENROLLMENT_DOMAIN" /> tarafından, hesabınız ise <ph name="ACCOUNT_DOMAIN" /> tarafından yönetiliyor. Bu durumda yöneticileriniz cihazınızı ve hesabınızı uzaktan yapılandırabilir.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bit)</translation>
-<translation id="5128122789703661928">Silmek üzere gönderilen bu oturum adı geçerli değil.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Adresleri yönet...</translation>
+<translation id="5138227688689900538">Daha az göster</translation>
<translation id="5141240743006678641">Senkronize edilen şifreleri Google kimlik bilgileriyle şifrele</translation>
<translation id="5145883236150621069">Politika yanıtında hata kodu var</translation>
+<translation id="515292512908731282">C4 (Zarf)</translation>
<translation id="5159010409087891077">Sayfayı yeni Gizli pencerede açın (⇧⌘N)</translation>
<translation id="516920405563544094"><ph name="CREDIT_CARD" /> numaralı kartın CVC kodunu girin. Onayladığınızda Google Hesabınızdaki kart bilgileriniz bu siteyle paylaşılır.</translation>
<translation id="5169827969064885044">Kuruluşunuzun hesabına erişimi kaybedebilir veya kimlik hırsızlığına maruz kalabilirsiniz. Chrome, şifrenizi hemen değiştirmenizi önerir.</translation>
<translation id="5171045022955879922">Arayın veya URL'yi yazın</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Makine</translation>
<translation id="5179510805599951267"><ph name="ORIGINAL_LANGUAGE" /> dilinde değil mi? Bu hatayı bildirin</translation>
<translation id="5190835502935405962">Yer İşareti Çubuğu</translation>
-<translation id="5200263511887412697">son zamanlarda giriş yapmış cihaz kullanıcılarının listesini rapor et</translation>
+<translation id="519422657042045905">Ek açıklama kullanılamıyor</translation>
<translation id="5201306358585911203">Bu sayfadaki yerleşik bir sayfanın mesajı</translation>
<translation id="5205222826937269299">Ad gerekli</translation>
<translation id="5215116848420601511">Google Pay'i kullanan ödeme yöntemleri ve adresler</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">E-posta gerekli</translation>
<translation id="5230733896359313003">Gönderim Adresi</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Ağa bağlanın"</translation>
<translation id="5251803541071282808">Bulut</translation>
+<translation id="5252000469029418751">C7 (Zarf)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Ağ adresleri</translation>
<translation id="5285570108065881030">Tüm kayıtlı şifreleri göster</translation>
<translation id="5287240709317226393">Çerezleri göster</translation>
<translation id="5288108484102287882">Politika değerlerini doğrulama işlemi uyarılarla sonuçlandı</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="NUM_MATCHES" /> eşleşme arasında <ph name="MATCH_POSITION" />. sırada</translation>
<translation id="5324080437450482387">İletişim Bilgisi Seç</translation>
<translation id="5327248766486351172">Ad</translation>
+<translation id="5329858041417644019">Tarayıcınız yönetilmemektedir</translation>
<translation id="5332219387342487447">Gönderim Yöntemi</translation>
+<translation id="5334013548165032829">Ayrıntılı sistem günlükleri</translation>
<translation id="5344579389779391559">Bu sayfa sizden para almaya çalışabilir</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Saatiniz geri", "Saatiniz ileri" veya "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Kartlarınızı tüm cihazlarınızda kullanmak için oturum açın ve senkronizasyonu etkinleştirin.</translation>
<translation id="5386426401304769735">Bu sitenin sertifika zinciri, SHA-1 kullanılarak imzalanmış bir sertifika içeriyor.</translation>
+<translation id="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Geçersiz</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=1{<ph name="CONTACT_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> kişi daha}other{<ph name="CONTACT_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> kişi daha}}</translation>
<translation id="5470861586879999274">Düzenlemeyi &amp;yeniden yap</translation>
+<translation id="5478437291406423475">B6/C4 (Zarf)</translation>
<translation id="5481076368049295676">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="54817484435770891">Geçerli adres ekleyin</translation>
<translation id="5490432419156082418">Adresler ve Daha Fazlası</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Sistem yöneticinize başvurmayı deneyin.</translation>
<translation id="549333378215107354">Boyut 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Yönetilen yer işaretleri</translation>
<translation id="5510766032865166053">Taşınmış veya silinmiş olabilir.</translation>
<translation id="5523118979700054094">Politika adı</translation>
<translation id="552553974213252141">Metin doğru bir şekilde çıkarıldı mı?</translation>
+<translation id="553484882784876924">Prc6 (Zarf)</translation>
<translation id="5540224163453853">İstenen makale bulunamadı.</translation>
<translation id="5541546772353173584">E-posta Adresi Ekleyin</translation>
<translation id="5545756402275714221">Sizin için Seçilmiş Makaleler</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Adresi düzenle</translation>
<translation id="5598944008576757369">Ödeme Yöntemi Seç</translation>
<translation id="560412284261940334">Yönetim desteklenmiyor</translation>
+<translation id="5605670050355397069">Ana Defter</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> sizi çok fazla kez yönlendirdi.</translation>
<translation id="5629630648637658800">Politika ayarları yüklenemedi</translation>
<translation id="5631439013527180824">Geçersiz cihaz yönetimi jetonu</translation>
+<translation id="5632627355679805402"><ph name="TIME" /> itibarıyla verileriniz <ph name="BEGIN_LINK" />Google şifrenizle<ph name="END_LINK" /> şifrelendi. Senkronizasyonu başlatmak için şifreyi girin.</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="563324245173044180">Yanıltıcı içerik engellendi.</translation>
<translation id="5659593005791499971">E-posta</translation>
+<translation id="5663614846592581799">9x11 (Zarf)</translation>
+<translation id="5663955426505430495">Bu cihazın yöneticisi diğer işlevler için uzantılar yüklemiş. Söz konusu uzantıların bazı verilerinize erişimi bulunuyor.</translation>
<translation id="5675650730144413517">Bu sayfa çalışmıyor</translation>
+<translation id="5684874026226664614">Hata! Bu sayfa çevrilemedi.</translation>
<translation id="5685654322157854305">Gönderim Adresi Ekle</translation>
<translation id="5689199277474810259">JSON'a aktar</translation>
<translation id="5689516760719285838">Konum</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Bu web sitesinin kimliği doğrulanmadı.</translation>
<translation id="5719499550583120431">Ön ödemeli kartlar kabul edilir.</translation>
<translation id="5720705177508910913">Geçerli kullanıcı</translation>
+<translation id="5728056243719941842">C5 (Zarf)</translation>
<translation id="5730040223043577876">Chrome, şifrenizi başka sitelerde kullandıysanız sıfırlamanızı önerir.</translation>
<translation id="5732392974455271431">Ebeveynleriniz engellemeyi kaldırabilir</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Kartı Google Hesabınıza kaydedin}other{Kartları Google Hesabınıza kaydedin}}</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="5770114862687765385">Dosya bozuk gibi görünüyor. Oturumu sıfırlamak için "Sıfırla" düğmesini tıklayın.</translation>
<translation id="5778550464785688721">MIDI cihazları tam denetimi</translation>
<translation id="578305955206182703">Kehribar rengi</translation>
<translation id="57838592816432529">Sesi kapat</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>
+<translation id="5798290721819630480">Değişiklikler silinsin mi?</translation>
<translation id="5798683403665926540">Ana sayfayı Chrome ayarlarından değiştirin</translation>
<translation id="5803412860119678065"><ph name="CARD_DETAIL" /> kartınıza ait bilgilerin doldurulmasını istiyor musunuz?</translation>
<translation id="5804241973901381774">İzinler</translation>
<translation id="5810442152076338065"><ph name="DOMAIN" /> ile olan bağlantınız eski bir şifre seti kullanılarak şifrelendi.</translation>
<translation id="5813119285467412249">Eklemeyi &amp;Yeniden Yap</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="5860033963881614850">Kapalı</translation>
<translation id="5863847714970149516">Gireceğiniz sayfa sizden para almaya çalışabilir</translation>
<translation id="5866257070973731571">Telefon Numarası Ekleyin</translation>
<translation id="5869405914158311789">Bu siteye ulaşılamıyor</translation>
<translation id="5869522115854928033">Kayıtlı şifreler</translation>
<translation id="5887400589839399685">Kart kaydedildi</translation>
-<translation id="5893718151540690985">türleri ve donanım adresleriyle birlikte ağ arayüzleri listesini rapor et</translation>
<translation id="5893752035575986141">Kredi kartları kabul edilir.</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="5916664084637901428">Açık</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Kart Google Hesabı'na kaydedilsin mi?</translation>
<translation id="5922853866070715753">Tamamlanmak üzere</translation>
<translation id="5932224571077948991">Site, araya giren veya yanıltıcı reklamlar gösteriyor</translation>
-<translation id="5939518447894949180">Sıfırla</translation>
<translation id="5946937721014915347"><ph name="SITE_NAME" /> açılıyor…</translation>
<translation id="5951495562196540101">Tüketici hesabına kaydedilemiyor (paket lisans mevcut).</translation>
<translation id="5967592137238574583">İletişim Bilgilerini Düzenleyin</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Uzaklaştır</translation>
<translation id="5977489021191000276">Cihazınız bir yönetici tarafından yönetilmiyor.</translation>
<translation id="5977976211062815271">Bu cihazda</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Ödeme uygulaması açılamıyor</translation>
<translation id="5989320800837274978">Sabit proxy sunucular veya bir .pac komut dosyası URL'si belirtilmedi.</translation>
<translation id="5990559369517809815">Sunucuya gönderilen istekler bir uzantı tarafından engellendi.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">CPU/RAM kullanımı gibi donanım istatistiklerini rapor et</translation>
<translation id="6034000775414344507">Açık Gri</translation>
+<translation id="6034283069659657473">10x14 (Zarf)</translation>
<translation id="6039846035001940113">Sorun devam ederse site sahibiyle iletişime geçin.</translation>
<translation id="6040143037577758943">Kapat</translation>
<translation id="6044573915096792553">Boyut 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Kartlarınızı tüm cihazlarınızda kullanmak istiyor musunuz?</translation>
<translation id="6059925163896151826">USB cihazları</translation>
-<translation id="6071091556643036997">Politika türü geçersiz.</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="6094273045989040137">Ek açıklama ekle</translation>
<translation id="610911394827799129">Google Hesabınızın <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> adresinde başka biçimlerde tarama geçmişi olabilir</translation>
+<translation id="6132597952260690497">Yüklü uzantılar ve eklentiler hakkında bilgi</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026"><ph name="SIZE" /> boyutundan daha az yer açar. Bir sonraki ziyaretinizde bazı siteler daha yavaş yüklenebilir.</translation>
<translation id="6337534724793800597">Politikalara ada göre filtre uygula</translation>
<translation id="6358450015545214790">Bunlar ne anlama geliyor?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Devam etmeniz halinde ödeme yapmanız gerekebilir.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 öneri daha}other{# öneri daha}}</translation>
<translation id="6387754724289022810">Gelecek sefer daha hızlı ödeme yapabilmek için kartınızı ve fatura adresinizi Google hesabınıza kaydedin.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Yer işaretini düzenle</translation>
+<translation id="6406765186087300643">C0 (Zarf)</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="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="6434309073475700221">Sil</translation>
+<translation id="6446163441502663861">Kahu (Zarf)</translation>
<translation id="6446608382365791566">Daha fazla bilgi ekleyin</translation>
<translation id="6447842834002726250">Çerezler</translation>
<translation id="6451458296329894277">Yeniden Form Gönderme İşlemini Onayla</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Chrome'u yeniden başlatın</translation>
<translation id="6529602333819889595">Silmeyi &amp;Yeniden Yap</translation>
<translation id="6534179046333460208">Fiziksel Web önerileri</translation>
+<translation id="6556866813142980365">Yeniden Yap</translation>
<translation id="6563469144985748109">Yöneticiniz henüz onaylamadı</translation>
<translation id="6569060085658103619">Bir uzantı sayfası görüntülüyorsunuz</translation>
+<translation id="6578796323535178455">C2 (Zarf)</translation>
<translation id="6579990219486187401">Açık Pembe</translation>
+<translation id="6583674473685352014">B6 (Zarf)</translation>
+<translation id="6587923378399804057">Kopyalanan bağlantı</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> cihazınız yönetilmemektedir</translation>
<translation id="6596325263575161958">Şifreleme seçenekleri</translation>
<translation id="6604181099783169992">Hareket veya Işık Sensörleri</translation>
+<translation id="6609880536175561541">Prc7 (Zarf)</translation>
<translation id="6624427990725312378">İletişim Bilgileri</translation>
<translation id="6626291197371920147">Geçerli kart numarası ekle</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> Arama</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Bu politika uygun bulunmadı.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Yok}=1{1 siteden (Google Hesabınızdan çıkış yapılmaz)}other{# siteden (Google Hesabınızdan çıkış yapılmaz)}}</translation>
<translation id="6657585470893396449">Şifre</translation>
+<translation id="6670613747977017428">Güvenliğe dön.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Kayıt Jetonu:</translation>
<translation id="6711464428925977395">Proxy sunucusunda bir sorun var veya adres yanlış.</translation>
<translation id="6723740634201835758">Google Hesabınızda</translation>
+<translation id="6738516213925468394">Verileriniz <ph name="TIME" /> tarihinde <ph name="BEGIN_LINK" />senkronizasyon parolanızla<ph name="END_LINK" /> şifrelendi. Senkronizasyonu başlatmak için senkronizasyon parolanızı girin.</translation>
<translation id="674375294223700098">Bilinmeyen sunucu sertifikası hatası.</translation>
<translation id="6744009308914054259">Bağlantı kurulmasını beklerken çevrimdışı makaleleri okumak için İndirilenler bölümünü ziyaret edebilirsiniz.</translation>
<translation id="6753269504797312559">Politika değeri</translation>
<translation id="6757797048963528358">Cihazınız uyku moduna geçti.</translation>
+<translation id="6768213884286397650">Hagaki (Kartpostal)</translation>
<translation id="6778737459546443941">Ebeveyniniz henüz onaylamadı</translation>
<translation id="67862343314499040">Mor</translation>
+<translation id="6786747875388722282">Uzantılar</translation>
<translation id="679355240208270552">Varsayılan arama motoru politika tarafından etkinleştirilmediği için yoksayıldı.</translation>
<translation id="681021252041861472">Gerekli Alan</translation>
<translation id="6810899417690483278">Özelleştirme Kimliği</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Cihaz</translation>
<translation id="6970216967273061347">Bölge</translation>
<translation id="6973656660372572881">Hem sabit proxy sunucular hem de bir .pac komut dosyası URL'si belirtildi.</translation>
+<translation id="6973932557599545801">Maalesef daha fazla yardımcı olamıyorum, lütfen kendiniz devam edin.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Sesi kapat (varsayılan)</translation>
<translation id="6984479912851154518">Harici bir uygulama üzerinden ödeme gerçekleştirmek için gizli moddan çıkılacak. Devam edilsin mi?</translation>
<translation id="6989763994942163495">Gelişmiş ayarları göster...</translation>
+<translation id="6993898126790112050">6x9 (Zarf)</translation>
<translation id="6996312675313362352"><ph name="ORIGINAL_LANGUAGE" /> dilini daima çevir</translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Bu ödemeler bir defalık alınabileceği gibi yinelenen ödemeler de olabilir ve bu durum açıkça belli olmayabilir.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Gizle</translation>
<translation id="7108819624672055576">Bir uzantı tarafından izin verildi</translation>
<translation id="7111012039238467737">(Geçerli)</translation>
+<translation id="7118618213916969306">Panoda URL'yi (<ph name="SHORT_URL" />) ara</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="7135130955892390533">Durumu göster</translation>
<translation id="7138472120740807366">Teslimat yöntemi</translation>
<translation id="7139724024395191329">Emirlik</translation>
+<translation id="7152423860607593928">Number-14 (Zarf)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> yöntem daha}other{<ph name="PAYMENT_METHOD_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> yöntem daha}}</translation>
<translation id="7153618581592392745">Lavanta</translation>
-<translation id="7158980942472052083">Geçersiz URL. URL'nin standart düzende olması gerekir.</translation>
<translation id="717330890047184534">Gaia Kimliği:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> seçenek daha}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ve <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> seçenek daha}}</translation>
+<translation id="7177397715882417099">Gittiğiniz sunucu (<ph name="ORIGIN" />) kendisine gelen tüm isteklere
+ bir güvenlik politikasının uygulanmasını talep etmişti. Ancak bir politika
+ sunmak yerine tarayıcıyı başka bir yere yönlendirdiği için tarayıcı, <ph name="SITE" />
+ sitesiyle ilgili isteğinizi yerine getiremiyor.</translation>
<translation id="7179323680825933600">Ödeme Yöntemlerini Kaydet ve Doldur</translation>
<translation id="7180611975245234373">Yenile</translation>
<translation id="7182878459783632708">Hiçbir politika ayarlanmamış</translation>
<translation id="7186367841673660872">Bu sayfa,<ph name="ORIGINAL_LANGUAGE" />dilinden<ph name="LANGUAGE_LANGUAGE" />diline çevrilmiştir</translation>
<translation id="7192203810768312527"><ph name="SIZE" /> yer açar. Bir sonraki ziyaretinizde bazı siteler daha yavaş yüklenebilir.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Yöneticiniz şunları görebilir:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> güvenlik standartlarına uymuyor.</translation>
<translation id="721197778055552897">Bu sorun hakkında <ph name="BEGIN_LINK" />daha fazla<ph name="END_LINK" /> bilgi edinin.</translation>
<translation id="7219179957768738017">Bağlantı <ph name="SSL_VERSION" /> kullanıyor.</translation>
<translation id="7220786058474068424">İşleme koyuluyor</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Gideceğiniz site kötü amaçlı yazılım içeriyor</translation>
+<translation id="724766306220616965">Uyarılar, Çakışma</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="7251437084390964440">Ağ yapılandırması ONC standardına uymuyor. Yapılandırmanın bazı bölümleri içe aktarılamaz.
Ek ayrıntılar:
@@ -982,11 +1120,14 @@ Ek ayrıntılar:
<translation id="7300012071106347854">Çini Mavisi</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911"><ph name="BEGIN_LINK" />Güvenli Tarama<ph name="END_LINK" /> uyarıları</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Bağlantı Yardımı</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Komut Satırı</translation>
-<translation id="7365061714576910172">Linux Biçiminde Dışa Aktar</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>
@@ -994,6 +1135,7 @@ Ek ayrıntılar:
<translation id="7381288752349550461">Yönetilen oturum tarafından geçersiz kılındı</translation>
<translation id="7390545607259442187">Kartı Onayla</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> adlı cihazınız yönetilmektedir</translation>
<translation id="7407424307057130981">&lt;p&gt;Windows bilgisayarınızda Superfish yazılımı varsa bu hatayı görürsünüz.&lt;/p&gt;
&lt;p&gt;Web'e ulaşabilmeniz amacıyla yazılımı geçici olarak devre dışı bırakmak için bu adımları uygulayın. Bu adımları gerçekleştirmek için yönetici ayrıcalıklarınızın olması gerekir.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Ek ayrıntılar:
&lt;li&gt;&lt;strong&gt;Uygula&lt;/strong&gt;'yı, ardından &lt;strong&gt;Tamam&lt;/strong&gt;'ı tıklayın
&lt;li&gt;Yazılımı bilgisayarınızdan kalıcı olarak nasıl kaldıracağınızı öğrenmek için &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome yardım merkezini&lt;/a&gt; ziyaret edin
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" /> yönetimi</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Şifreleri Yönet…</translation>
<translation id="7419106976560586862">Profil Yolu</translation>
<translation id="7437289804838430631">İletişim Bilgisi Ekle</translation>
@@ -1013,22 +1155,24 @@ Ek ayrıntılar:
<translation id="7442725080345379071">Açık Turuncu</translation>
<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="7449109375006139765">yönetim sunucusuna sistem günlükleri gönder</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="7460618730930299168">Filtreleme sizin seçiminizden farklı. Devam etmek istiyor musunuz?</translation>
<translation id="7473891865547856676">Hayır, Teşekkürler</translation>
-<translation id="7475525192983021547">bir kullanıcının cihazı aktif olarak kullandığı dönemleri rapor et</translation>
<translation id="7481312909269577407">İleri</translation>
<translation id="7485870689360869515">Hiçbir veri bulunamadı.</translation>
+<translation id="7498234416455752244">Düzenlemeye devam et</translation>
<translation id="7508255263130623398">Döndürülen politika cihaz kimliği boş veya mevcut cihaz kimliğiyle eşleşmiyor</translation>
<translation id="7508870219247277067">Avokado Yeşili</translation>
<translation id="7511955381719512146">Kullandığınız kablosuz bağlantı ağı, <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> adresini ziyaret etmenizi gerektiriyor olabilir.</translation>
<translation id="7514365320538308">İndir</translation>
<translation id="7518003948725431193">Şu web adresi için web sayfası bulunamadı:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Zarf)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Bu siteye bağlantınız gizli değil</translation>
+<translation id="7535087603100972091">Değer</translation>
<translation id="7537536606612762813">Zorunlu</translation>
+<translation id="7538364083937897561">A2 (Zarf)</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>
@@ -1037,8 +1181,8 @@ Ek ayrıntılar:
<translation id="7552846755917812628">Aşağıdaki ipuçlarını deneyin:</translation>
<translation id="7554791636758816595">Yeni Sekme</translation>
<translation id="7564049878696755256"><ph name="ORG_NAME" /> hesabınıza erişimi kaybedebilir veya kimlik hırsızlığına maruz kalabilirsiniz. Chrome, şifrenizi hemen değiştirmenizi önerir.</translation>
-<translation id="7566125604157659769">Kopyaladığınız metin</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="7568105740864181217">Bu tarayıcı bir şirket, okul veya başka bir kuruluş tarafından yönetilmektedir. Yöneticiniz, tarayıcınızın kurulumunu uzaktan değiştirebilir. Bu cihazdaki etkinlikler Chrome dışında da yönetilebilir. <ph name="BEGIN_LINK" />Daha Fazla Bilgi<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Ek ayrıntılar:
<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="7633909222644580952">Performans verileri ve kilitlenme raporları</translation>
<translation id="7637571805876720304">Kredi kartı Chromium'dan kaldırılsın mı?</translation>
<translation id="7639968568612851608">Koyu Gri</translation>
<translation id="765676359832457558">Gelişmiş ayarları gizle...</translation>
@@ -1058,9 +1203,11 @@ Ek ayrıntılar:
<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="7676643023259824263">Panoda metni (<ph name="TEXT" />) ara</translation>
<translation id="7681101578153515023">Arama Motorunu değiştir</translation>
<translation id="7682287625158474539">Sevkiyat</translation>
<translation id="7687186412095877299">Ödeme formlarını kayıtlı ödeme yöntemlerinizle doldurur</translation>
+<translation id="7697066736081121494">Prc8 (Zarf)</translation>
<translation id="769721561045429135">Şu anda, yalnızca bu cihazda kullanılabilen kartlarınız var. Kartları incelemek için Devam'ı tıklayın.</translation>
<translation id="7699293099605015246">Makaleler şu anda kullanılamıyor</translation>
<translation id="7701040980221191251">Yok</translation>
@@ -1072,11 +1219,13 @@ Ek ayrıntılar:
<translation id="774634243536837715">Tehlikeli içerik engellendi.</translation>
<translation id="7752995774971033316">Yönetimden kaldırıldı</translation>
<translation id="7755287808199759310">Ebeveyniniz engellemeyi sizin için kaldırabilir</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Bağlantıyı güvenlik duvarı veya virüsten korunma yazılımı engellemiş olabilir.</translation>
<translation id="7759163816903619567">Görünen alan:</translation>
<translation id="7761701407923456692">Sunucu sertifikası URL ile eşleşmiyor.</translation>
<translation id="7763386264682878361">Ödeme Bildirimi Ayrıştırıcısı</translation>
<translation id="7764225426217299476">Adres ekle</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Bölge</translation>
<translation id="7791543448312431591">Ekle</translation>
<translation id="7793809570500803535"><ph name="SITE" /> adresindeki Web sayfası geçici olarak kullanılamıyor veya kalıcı olarak yeni bir Web adresine taşınmış olabilir.</translation>
@@ -1088,8 +1237,8 @@ Ek ayrıntılar:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Form önerisi Chrome'dan kaldırılsın mı?</translation>
<translation id="7815407501681723534">"<ph name="SEARCH_STRING" />" için <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> bulundu.</translation>
-<translation id="7818867226424560206">Politika yönetimi</translation>
<translation id="782886543891417279">Kullandığınız kablosuz bağlantı ağı (<ph name="WIFI_NAME" />) giriş sayfasını ziyaret etmenizi gerektiriyor olabilir.</translation>
+<translation id="7836231406687464395">Postfix (Zarf)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Yok}=1{1 uygulama (<ph name="EXAMPLE_APP_1" />)}=2{2 uygulama (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# uygulama (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Ancak görünmez olmazsınız. Gizli moda geçmek göz atma etkinliğinizi işvereninizden, İnternet servis sağlayıcınızdan veya ziyaret ettiğiniz web sitelerinden gizlemez.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Ek ayrıntılar:
<translation id="7878562273885520351">Şifrenizin güvenliği ihlal edilmiş olabilir</translation>
<translation id="7882421473871500483">Kahverengi</translation>
<translation id="7887683347370398519">CVC'nizi kontrol edin ve tekrar deneyin</translation>
-<translation id="7893255318348328562">Oturum adı</translation>
+<translation id="7904208859782148177">C3 (Zarf)</translation>
<translation id="79338296614623784">Geçerli bir telefon numarası girin</translation>
<translation id="7935318582918952113">DOM Ayrıştırıcı</translation>
<translation id="7937554595067888181">Süre sonu: <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Ek ayrıntılar:
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Mobil yer işaretleri</translation>
<translation id="7961015016161918242">Hiçbir Zaman</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Tarayıcı</translation>
<translation id="8009225694047762179">Şifreleri Yönet</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Aşağıdaki kart ve ona ait fatura adresi kaydedilecektir. Kaydettiğiniz kartı <ph name="USER_EMAIL" /> hesabında oturumunuz açıkken kullanabilirsiniz.}other{Aşağıdaki kartlar ve onlara ait fatura adresleri kaydedilecektir. Kaydettiğiniz kartları <ph name="USER_EMAIL" /> hesabında oturumunuz açıkken kullanabilirsiniz.}}</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="8034522405403831421">Bu sayfa <ph name="SOURCE_LANGUAGE" /> dilinde. <ph name="TARGET_LANGUAGE" /> diline çevrilsin mi?</translation>
<translation id="8035152190676905274">Kalem</translation>
+<translation id="8037117624646282037">Cihazı son zamanlarda kullananlar</translation>
<translation id="8037357227543935929">Sor (varsayılan)</translation>
<translation id="803771048473350947">Dosya</translation>
<translation id="8041089156583427627">Görüş bildirin</translation>
<translation id="8041940743680923270">Genel varsayılanı kullan (Sor)</translation>
<translation id="8042918947222776840">Alma Yöntemi Seç</translation>
<translation id="8057711352706143257">"<ph name="SOFTWARE_NAME" />" doğru şekilde yapılandırılmamış. Genellikle "<ph name="SOFTWARE_NAME" />" kaldırıldığında sorun çözülür. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Cihazınız şu şekilde yapılandırıldı:</translation>
+<translation id="8066955247577885446">Maalesef bir hata oluştu.</translation>
+<translation id="8074253406171541171">10x13 (Zarf)</translation>
<translation id="8078141288243656252">Doküman döndürüldüğünde ek açıklama özelliği kullanılamaz</translation>
<translation id="8079031581361219619">Site yeniden yüklensin mi?</translation>
<translation id="8088680233425245692">Makale görüntülenemedi.</translation>
@@ -1131,11 +1284,12 @@ Ek ayrıntılar:
<translation id="8091372947890762290">Etkinleştirme sunucuda bekliyor</translation>
<translation id="8092774999298748321">Koyu Mor</translation>
<translation id="8094917007353911263">Kullandığınız ağ <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> adresini ziyaret etmenizi gerektiriyor olabilir.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Geçersiz kartlar kaldırıldı</translation>
<translation id="8103161714697287722">Ödeme Yöntemi</translation>
<translation id="8118489163946903409">Ödeme yöntemi</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" />, <ph name="ENROLLMENT_DOMAIN" /> tarafından yönetilmektedir</translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" yazılımı bilgisayarınıza veya ağa düzgün şekilde yüklenmemiş. BT yöneticinizden sorunu çözmesini isteyin.</translation>
-<translation id="8130693978878176684">Daha fazla yardımcı olamıyorum, lütfen kendiniz devam edin.</translation>
<translation id="8131740175452115882">Onayla</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>
@@ -1145,8 +1299,11 @@ Ek ayrıntılar:
<translation id="8197543752516192074">Sayfayı Çevir</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="8202370299023114387">Çakışma</translation>
+<translation id="8206978196348664717">Prc4 (Zarf)</translation>
<translation id="8211406090763984747">Bağlantı güvenli</translation>
<translation id="8218327578424803826">Atanan Konum:</translation>
+<translation id="8220146938470311105">C7/C6 (Zarf)</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="8238581221633243064">Sayfayı yeni bir Gizli sekmede aç</translation>
@@ -1158,14 +1315,16 @@ Ek ayrıntılar:
<translation id="825929999321470778">Tüm Kayıtlı Şifreleri Göster</translation>
<translation id="8261506727792406068">Sil</translation>
<translation id="8267698848189296333"><ph name="USERNAME" /> olarak oturum açılıyor</translation>
+<translation id="8278457561961988242">Bu tarayıcı, <ph name="ENROLLMENT_DOMAIN" /> tarafından yönetilmektedir. Yöneticiniz, tarayıcınızın kurulumunu uzaktan değiştirebilir. Bu cihazdaki etkinlikler Chrome dışında da yönetilebilir. <ph name="BEGIN_LINK" />Daha Fazla Bilgi<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Oturum Aç</translation>
<translation id="8288807391153049143">Sertifikayı göster</translation>
<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="8298115750975731693">Kullandığınız kablosuz bağlantı ağı (<ph name="WIFI_NAME" />) <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" /> adresini ziyaret etmenizi gerektiriyor olabilir.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Ağ bağlantısıyla ilgili bir sorun nedeniyle çeviri başarısız oldu.</translation>
-<translation id="8311129316111205805">Oturum yükle</translation>
<translation id="8332188693563227489"><ph name="HOST_NAME" /> ana makinesine erişim reddedildi</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Ek ayrıntılar:
<translation id="8416694386774425977">Ağ yapılandırması geçersiz ve içe aktarılamadı.
Ek ayrıntılar:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Cihaz <ph name="ENROLLMENT_DOMAIN" /> tarafından yönetiliyor</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Değiştir</translation>
<translation id="8428213095426709021">Ayarlar</translation>
@@ -1211,9 +1369,11 @@ Ek ayrıntılar:
<translation id="860043288473659153">Kart sahibinin adı</translation>
<translation id="861775596732816396">Boyut 4</translation>
<translation id="8620436878122366504">Ebeveynleriniz henüz onaylamadı</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Bu Kartı Bu Cihaza Kaydet</translation>
<translation id="8663226718884576429">Sipariş Özeti, <ph name="TOTAL_LABEL" />, Daha Fazla Ayrıntı</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, yanıt, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206"><ph name="DOMAIN" /> bağlantınız şifrelenmedi.</translation>
<translation id="8718314106902482036">Ödeme işlemi tamamlanmadı</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, arama önerisi</translation>
@@ -1227,6 +1387,7 @@ Ek ayrıntılar:
<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="8763927697961133303">USB cihaz</translation>
<translation id="8768895707659403558">Kartlarınızı tüm cihazlarınızda kullanmak için <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">Silmeyi &amp;yeniden yap</translation>
<translation id="8792621596287649091"><ph name="ORG_NAME" /> hesabınıza erişimi kaybedebilir veya kimlik hırsızlığına maruz kalabilirsiniz. Chromium, şifrenizi hemen değiştirmenizi önerir.</translation>
<translation id="8800988563907321413">Yakın çevrenizle ilgili öneriler burada görünür</translation>
@@ -1237,10 +1398,12 @@ Ek ayrıntılar:
<translation id="885730110891505394">Google ile Paylaşma</translation>
<translation id="8858065207712248076">Chrome, <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> şifrenizi başka sitelerde kullandıysanız sıfırlamanızı önerir.</translation>
<translation id="8866481888320382733">Politika ayarlarını ayrıştırma hatası</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Son Kapatılan</translation>
<translation id="8874824191258364635">Geçerli bir kart numarası girin</translation>
<translation id="8891727572606052622">Geçersiz proxy modu.</translation>
<translation id="8903921497873541725">Yakınlaştır</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Bu kartı Google Hesabınıza kaydetmek istiyor musunuz?</translation>
<translation id="8932102934695377596">Saatiniz geri</translation>
<translation id="893332455753468063">Ad Ekleyin</translation>
@@ -1248,13 +1411,13 @@ Ek ayrıntılar:
<translation id="894185898663964645">Yöneticiniz, ziyaret ettiğiniz web sitelerinin içeriğinin yönetici tarafından görülmesini sağlayabilen özel kök sertifikalar yapılandırmış.</translation>
<translation id="8943282376843390568">Küf yeşili</translation>
<translation id="8957210676456822347">Giriş Portalı Yetkilendirmesi</translation>
+<translation id="8966619695390250636">Bunu mu arıyordunuz?</translation>
<translation id="8968766641738584599">Kartı kaydet</translation>
<translation id="8971063699422889582">Sunucu sertifikasının süresi doldu.</translation>
<translation id="8975012916872825179">Telefon numaraları, e-posta adresleri ve gönderim adresleri gibi bilgileri içerir</translation>
<translation id="8978053250194585037">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />kimlik avı yapıldığını tespit etti<ph name="END_LINK" />. Kimlik avı siteleri sizi aldatmak için başka web siteleri gibi görünür.</translation>
<translation id="8983003182662520383">Google Pay'i Kullanan Ödeme Yöntemleri ve Adresler</translation>
<translation id="8987927404178983737">Ay</translation>
-<translation id="8988408250700415532">Bir sorun oluştu. Siparişinizi web sitesinde tamamlayabilirsiniz.</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>
@@ -1264,6 +1427,7 @@ Ek ayrıntılar:
<translation id="9011424611726486705">Site ayarlarını aç</translation>
<translation id="9020200922353704812">Kartın fatura adresi gerekli</translation>
<translation id="9020542370529661692">Bu sayfa <ph name="TARGET_LANGUAGE" /> diline çevrildi</translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Geçersiz)</translation>
<translation id="9035022520814077154">Güvenlik hatası</translation>
<translation id="9038649477754266430">Sayfaları daha hızlı yüklemek için bir tahmin hizmeti kullan</translation>
@@ -1275,11 +1439,11 @@ Ek ayrıntılar:
<translation id="9065745800631924235">geçmişteki <ph name="TEXT" /> araması</translation>
<translation id="9069693763241529744">Bir uzantı tarafından engellendi</translation>
<translation id="9076283476770535406">Yetişkin içeriği bulunabilir</translation>
+<translation id="9076630408993835509">Bu tarayıcı bir şirket veya başka bir kuruluş tarafından yönetilmemektedir. Bu cihazdaki etkinlikler Chrome dışında yönetilebilir. <ph name="BEGIN_LINK" />Daha Fazla Bilgi<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Daha fazla bilgi gerekli</translation>
<translation id="9080712759204168376">Sipariş Özeti</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>
<translation id="9106062320799175032">Fatura Adresi Ekleyin</translation>
-<translation id="9110718169272311511">Chrome'da Google Asistan ekranın altına yakın bir bölümde bulunur</translation>
<translation id="9114524666733003316">Kart onaylanıyor...</translation>
<translation id="9128870381267983090">Ağa bağlan</translation>
<translation id="9137013805542155359">Orijinali göster</translation>
@@ -1288,6 +1452,7 @@ Ek ayrıntılar:
<translation id="9148507642005240123">Düzenlemeyi &amp;geri al</translation>
<translation id="9154194610265714752">Güncellendi</translation>
<translation id="9157595877708044936">Ayarlanıyor...</translation>
+<translation id="9158625974267017556">C6 (Zarf)</translation>
<translation id="9168814207360376865">Sitelerin, kayıtlı ödeme yöntemleriniz olup olmadığını kontrol etmesine izin verin</translation>
<translation id="9169664750068251925">Bu sitede her zaman engelle</translation>
<translation id="9170848237812810038">&amp;Geri al</translation>
@@ -1302,10 +1467,12 @@ Ek ayrıntılar:
<translation id="9219103736887031265">Resimler</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">FORMU TEMİZLE</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Google Hesabınıza erişimi kaybedebilirsiniz. Chromium, şifrenizi hemen değiştirmenizi önerir. Oturum açmanız istenecektir.</translation>
<translation id="939736085109172342">Yeni klasör</translation>
<translation id="945855313015696284">Aşağıdaki bilgileri kontrol edin ve geçersiz kartları silin</translation>
<translation id="951104842009476243">Kabul Edilen Banka ve Ön Ödemeli Kartlar</translation>
+<translation id="958202389743790697"><ph name="ORIGIN" /> sitesinin güvenlik politikası uyarınca engellendi.</translation>
<translation id="962484866189421427">Bu içerik başka bir şeyi taklit eden aldatıcı uygulamalar yükleyebilir veya sizi izlemek için kullanılabilecek veriler toplayabilir. <ph name="BEGIN_LINK" />Yine de göster<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Resmi Derleme</translation>
<translation id="973773823069644502">Teslimat Adresi Ekle</translation>
@@ -1314,6 +1481,7 @@ Ek ayrıntılar:
<translation id="984275831282074731">Ödeme yöntemleri</translation>
<translation id="985199708454569384">&lt;p&gt;Bilgisayarınızın veya mobil cihazınızın tarihi ve saati doğru değilse bu hatayı görürsünüz.&lt;/p&gt;
&lt;p&gt;Hatayı gidermek için cihazınızın saatini açın. Saat ve tarih ayarının doğru olduğundan emin olun.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Geliştirici Derlemesi</translation>
<translation id="989988560359834682">Adresi Düzenle</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_uk.xtb b/chromium/components/strings/components_strings_uk.xtb
index 955258f1044..00457a0367e 100644
--- a/chromium/components/strings/components_strings_uk.xtb
+++ b/chromium/components/strings/components_strings_uk.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="uk">
-<translation id="1005145902654145231">Не вдалося перейменувати сеанс.</translation>
<translation id="1008557486741366299">Не зараз</translation>
<translation id="1010200102790553230">Завантажити сторінку пізніше</translation>
<translation id="1015730422737071372">Надати додаткову інформацію</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">Невідоме ім’я</translation>
<translation id="1050038467049342496">Закрийте інші додатки</translation>
<translation id="1055184225775184556">&amp;Відмінити додавання</translation>
+<translation id="1056898198331236512">Застереження</translation>
<translation id="1058479211578257048">Зберігання карток…</translation>
<translation id="10614374240317010">Ніколи не зберігалося</translation>
+<translation id="1062160989074299343">Prc10 (конверт)</translation>
<translation id="106701514854093668">Закладки на комп’ютері</translation>
<translation id="1074497978438210769">Не конфіденційний</translation>
<translation id="1080116354587839789">За шириною сторінки</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Додайте ім’я на картці</translation>
<translation id="1089439967362294234">Змінити пароль</translation>
<translation id="109743633954054152">Керуйте паролями в налаштуваннях Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Можуть з’являтися застереження під час оновлення системи безпеки сайтів. Цю проблему буде незабаром виправлено.</translation>
<translation id="1126551341858583091">Обсяг локальної пам’яті – <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Кеш-пам’ять правила не пошкоджено</translation>
+<translation id="1131264053432022307">Скопійоване зображення</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885">Хост <ph name="HOST_NAME" /> неочікувано розірвав з’єднання.</translation>
<translation id="1161325031994447685">знову під’єднати пристрій до мережі Wi-Fi</translation>
<translation id="1165039591588034296">Помилка</translation>
-<translation id="1173894706177603556">Перейменувати</translation>
<translation id="1175364870820465910">&amp;Друк...</translation>
<translation id="1181037720776840403">Видалити</translation>
<translation id="1197088940767939838">Оранжевий</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Назва пристрою</translation>
<translation id="124116460088058876">Інші мови</translation>
<translation id="1250759482327835220">Щоб наступного разу платити швидше, збережіть дані картки, ім’я та платіжну адресу в обліковому записі Google.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (синхронізовано)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Варіанти командного рядка</translation>
<translation id="129553762522093515">Нещодавно закриті</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />Спробуйте видалити файли cookie<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">Вибраний сеанс не існує.</translation>
+<translation id="1320233736580025032">Prc1 (конверт)</translation>
+<translation id="132301787627749051">Пошук зображення з буфера обміну</translation>
<translation id="1323433172918577554">Показати більше</translation>
<translation id="132390688737681464">Зберігати й заповнювати адреси</translation>
<translation id="1333989956347591814">Дані про вашу активність <ph name="BEGIN_EMPHASIS" />усе ще можуть бачити<ph name="END_EMPHASIS" />:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Адреса отримання</translation>
<translation id="1348198688976932919">Сайт містить небезпечні додатки</translation>
<translation id="1348779747280417563">Підтвердити назву</translation>
+<translation id="1357195169723583938">Хто й коли нещодавно користувався пристроєм</translation>
+<translation id="1364822246244961190">Це правило заблоковано. Його значення ігноруватиметься.</translation>
<translation id="1374468813861204354">пропозиції</translation>
+<translation id="1374692235857187091">Index-4x6 (листівка)</translation>
<translation id="1375198122581997741">Про версію</translation>
<translation id="1376836354785490390">Показати менше</translation>
<translation id="1377321085342047638">Номер картки</translation>
<translation id="138218114945450791">Світло-синій</translation>
+<translation id="1382194467192730611">Пристрій USB дозволив адміністратор</translation>
<translation id="139305205187523129">Хост <ph name="HOST_NAME" /> не надіслав дані.</translation>
+<translation id="140316286225361634">Сайт <ph name="ORIGIN" /> попросив, щоб правило безпеки
+ застосовувалося до всіх його запитів. Наразі це правило вважає цей сайт
+ ненадійним.</translation>
<translation id="1405567553485452995">Світло-зелений</translation>
<translation id="1407135791313364759">Відкрити все</translation>
<translation id="1413809658975081374">Помилка через порушення конфіденційності</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Так</translation>
<translation id="1430915738399379752">Друк</translation>
<translation id="1455413310270022028">Гумка</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Показати більше</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Вибрати адресу доставки</translation>
+<translation id="1492194039220927094">Сповіщення про правила:</translation>
<translation id="1501859676467574491">Показує картки з облікового запису Google</translation>
-<translation id="1506687042165942984">Показати стару збережену копію цієї сторінки.</translation>
<translation id="1507202001669085618">&lt;p&gt;Це повідомлення про помилку з’являється, якщо ви користуєтеся порталом Wi-Fi, на який потрібно ввійти, перш ніж підключитися до мережі.&lt;/p&gt;
&lt;p&gt;Щоб виправити цю помилку, натисніть &lt;strong&gt;Підключитися&lt;/strong&gt; на сторінці, яку ви намагаєтеся відкрити.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Введіть номер телефону</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Дата створення версії</translation>
<translation id="1521655867290435174">Google Таблиці</translation>
<translation id="1527263332363067270">Очікується з’єднання…</translation>
+<translation id="1529521330346880926">10x15 (конверт)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Повідомлення з цієї сторінки</translation>
<translation id="153384715582417236">Більше нічого немає</translation>
<translation id="154408704832528245">Вибрати адресу доставки</translation>
<translation id="1549470594296187301">Щоб користуватися цією функцією, потрібно ввімкнути JavaScript.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Введіть дату закінчення терміну дії</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">Під час завантаженння цієї сторінки сталася помилка.</translation>
<translation id="1592005682883173041">Доступ до локальних даних</translation>
<translation id="1594030484168838125">Вибрати</translation>
<translation id="161042844686301425">Бірюзовий</translation>
-<translation id="1618822247301510817">Скопійоване зображення</translation>
<translation id="1620510694547887537">Камера</translation>
<translation id="1623104350909869708">Заборонити цій сторінці створювати додаткові діалогові вікна</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Завершити сеанс</translation>
<translation id="1639239467298939599">Завантаження</translation>
<translation id="1640180200866533862">Правила користувача</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898">Веб-сайт <ph name="SITE" /> зазвичай використовує шифрування для захисту вашої інформації. Під час цієї спроби Chrome під’єднатися до сторінки <ph name="SITE" /> з неї отримано незвичні й неправильні облікові дані. Це може статися, коли зловмисник намагається видавати себе за веб-сайт <ph name="SITE" /> або з’єднання перервано екраном входу Wi-Fi. Ваша інформація залишається захищеною, оскільки Chrome припинив з’єднання до того, як почався обмін будь-якими даними.</translation>
<translation id="168841957122794586">Сертифікат сервера містить слабкий криптографічний ключ.</translation>
<translation id="1697532407822776718">Готово!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Документ завеликий для створення приміток</translation>
<translation id="1721312023322545264">Вам потрібен дозвіл адміністратора <ph name="NAME" />, щоб перейти на цей сайт</translation>
<translation id="1721424275792716183">* Обов’язкове поле</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Зв’яжіться із системним адміністратором.</translation>
<translation id="1740951997222943430">Введіть дійсний місяць закінчення терміну дії</translation>
<translation id="1743520634839655729">Щоб наступного разу платити швидше, збережіть дані картки, ім’я та платіжну адресу в обліковому записі Google і на цьому пристрої.</translation>
+<translation id="1745880797583122200">Вашим веб-переглядачем керує адміністратор</translation>
<translation id="17513872634828108">Відкриті вкладки</translation>
<translation id="1753706481035618306">Номер сторінки</translation>
<translation id="1763864636252898013">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Операційна система вашого пристрою не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">Оновіть парольну фразу для синхронізації.</translation>
<translation id="1787142507584202372">Тут відображатимуться ваші відкриті вкладки</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Ім’я та прізвище власника картки</translation>
<translation id="1821930232296380041">Недійсний запит або параметри запиту</translation>
+<translation id="1822540298136254167">Відвідані веб-сайти й час перебування на них</translation>
<translation id="1826516787628120939">Перевірка</translation>
<translation id="1834321415901700177">Цей сайт містить шкідливі програми</translation>
<translation id="1839551713262164453">Не вдалося перевірити значення правила. Знайдено помилки</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Очистити дані історії веб-перегляду Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{і ще 1}one{і ще #}few{і ще #}many{і ще #}other{і ще #}}</translation>
<translation id="2003709556000175978">Скиньте пароль</translation>
+<translation id="20053308747750172">Сервер, на який ви переходите (<ph name="ORIGIN" />), попросив, щоб
+ до всіх його запитів застосовувалося правило безпеки. Однак зараз він
+ повернув недійсне правило, яке не дозволяє веб-переглядачу
+ виконати вам запит для сайту <ph name="SITE" />.</translation>
<translation id="2025186561304664664">Проксі-сервер установлено на автоматичне налаштування.</translation>
<translation id="2030481566774242610">Можливо, ви мали на увазі <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />перевірити проксі-сервер і брандмауер<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Департамент</translation>
<translation id="2102134110707549001">Запропонувати надійний пароль…</translation>
<translation id="2108755909498034140">Перезавантажте комп’ютер</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Картка</translation>
<translation id="2114841414352855701">Правило ігнорується, оскільки його замінено правилом <ph name="POLICY_NAME" />.</translation>
<translation id="213826338245044447">Закладки на мобільному</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">Редагувати картку</translation>
<translation id="2166049586286450108">Повний адміністративний доступ</translation>
<translation id="2166378884831602661">Цей сайт не може забезпечити захищене з’єднання</translation>
+<translation id="2169984857010174799">Kaku2 (конверт)</translation>
<translation id="2181821976797666341">Правила</translation>
<translation id="2183608646556468874">Номер телефону</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 адреса}one{# адреса}few{# адреси}many{# адрес}other{# адреси}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Номер телефону</translation>
<translation id="2283340219607151381">Зберігати й заповнювати адреси</translation>
<translation id="2292556288342944218">Ваш доступ до Інтернету заблоковано</translation>
+<translation id="2294558542833290837">Посилання, яке ви початково відкрили, незвичне</translation>
+<translation id="2297722699537546652">B5 (конверт)</translation>
+<translation id="2310021320168182093">Chou2 (конверт)</translation>
<translation id="2316887270356262533">Звільняє менше 1 Мб. Деякі сайти можуть завантажуватися повільніше під час наступного відвідування.</translation>
<translation id="2317259163369394535">Для сайту <ph name="DOMAIN" /> потрібно ввести ім’я користувача та пароль.</translation>
<translation id="2317583587496011522">Дебетові картки, які приймаються.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, діє до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Налаштуванням керує ваш адміністратор</translation>
+<translation id="2346319942568447007">Скопійоване зображення</translation>
<translation id="2349790679044093737">VR-сеанс активний</translation>
<translation id="2354001756790975382">Інші закладки</translation>
<translation id="2354430244986887761">Функція безпечного перегляду від Google нещодавно <ph name="BEGIN_LINK" />виявила шкідливі додатки<ph name="END_LINK" /> на сайті <ph name="SITE" />.</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">Звіт про аварійне завершення роботи о <ph name="CRASH_TIME" /> не завантажено</translation>
<translation id="2367567093518048410">Рівень</translation>
<translation id="2378238891085281592">Ви перейшли в приватний режим</translation>
+<translation id="2380886658946992094">Legal</translation>
<translation id="2384307209577226199">Стандартне корпоративне правило</translation>
<translation id="2386255080630008482">Сертифікат сервера відкликано.</translation>
<translation id="2392959068659972793">Показувати правила, для яких не встановлено значення</translation>
<translation id="239429038616798445">Цей спосіб відправлення недоступний. Виберіть інший спосіб.</translation>
<translation id="2396249848217231973">&amp;Відмінити видалення</translation>
+<translation id="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Можливо, його сертифікат безпеки відкликано. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
+<translation id="2418081434543109369">Сервер, на який ви переходите (<ph name="ORIGIN" />), попросив, щоб
+ до всіх його запитів застосовувалося правило безпеки. Однак зараз він
+ не повертає правило, що не дозволяє веб-переглядачу виконати
+ ваш запит для сайту <ph name="SITE" />.</translation>
<translation id="244665789865330679"><ph name="ENROLLMENT_DOMAIN" /> керує вашим пристроєм і обліковим записом. Це означає, що адміністратор може віддалено налаштовувати їх.</translation>
<translation id="2463193859425327265">Змінити домашню сторінку</translation>
<translation id="2463739503403862330">Заповнити</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Вибрати спосіб доставки</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />провести діагностику мережі<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Перекласти цю сторінку</translation>
<translation id="2479410451996844060">Недійсна URL-адреса для пошуку.</translation>
<translation id="2482878487686419369">Сповіщення</translation>
<translation id="248348093745724435">Правила пристрою</translation>
+<translation id="2485387744899240041">Імена користувачів пристрою та веб-переглядача</translation>
<translation id="2491120439723279231">Сертифікат сервера містить помилки.</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">Синтаксичний аналізатор файлів JSON</translation>
<translation id="2495093607237746763">Якщо вибрати цю опцію, Chromium зберігатиме копію даних вашої картки на цьому пристрої, щоб ви могли швидше заповнювати форми.</translation>
<translation id="2498091847651709837">Сканувати нову картку</translation>
<translation id="2501278716633472235">Назад</translation>
<translation id="2503184589641749290">Прийнятні дебетові та передплачені картки</translation>
<translation id="2515629240566999685">перевірити сигнал у своїй місцевості</translation>
-<translation id="2516852381693169964">Шукати зображення в <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Збережено лише на цьому пристрої</translation>
<translation id="2524461107774643265">Додайте більше інформації</translation>
<translation id="2536110899380797252">Додати адресу</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Ідентифікатор API каталогу:</translation>
<translation id="2597378329261239068">Цей документ захищено паролем. Введіть пароль.</translation>
<translation id="2609632851001447353">Різновиди</translation>
+<translation id="2618023639789766142">C10 (конверт)</translation>
<translation id="2625385379895617796">Ваш годинник спішить</translation>
<translation id="2634124572758952069">IP-адресу сервера <ph name="HOST_NAME" /> не знайдено.</translation>
<translation id="2639739919103226564">Статус:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Закрийте інші вкладки та додатки</translation>
<translation id="267371737713284912">натисніть <ph name="MODIFIER_KEY_DESCRIPTION" />, щоб відмінити</translation>
<translation id="2674170444375937751">Ви дійсно бажаєте видалити ці сторінки зі своєї історії?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Вийти</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Картки, які приймаються до оплати</translation>
<translation id="2702801445560668637">Список читання</translation>
<translation id="2704283930420550640">Значення не відповідає формату.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Видалити вибрані елементи</translation>
<translation id="277133753123645258">Спосіб відправлення</translation>
<translation id="277499241957683684">Відсутній запис пристрою</translation>
-<translation id="2781030394888168909">Експортувати для ОС Mac</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">З’єднання було скинуто.</translation>
<translation id="2788784517760473862">Прийнятні кредитні картки</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">З’єднання зашифровано й автентифіковано з використанням шифру <ph name="CIPHER" /> і використовує механізм обміну ключами <ph name="KX" />.</translation>
<translation id="2835170189407361413">Очистити форму</translation>
<translation id="2847118875340931228">Відкрити вікно в режимі анонімного перегляду</translation>
+<translation id="2850739647070081192">Invite (конверт)</translation>
<translation id="2851634818064021665">Щоб відвідувати цей сайт, потрібен дозвіл</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Зберегти картку?</translation>
<translation id="2903493209154104877">Адреси</translation>
<translation id="290376772003165898">Ця сторінка відображається не такою мовою: <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Спосіб доставки</translation>
<translation id="2928905813689894207">Платіжна адреса</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Його сертифікат безпеки походить із домену <ph name="DOMAIN2" />. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="2948083400971632585">Усі проксі-сервери, налаштовані для з’єднання, можна вимкнути на сторінці налаштувань.</translation>
<translation id="2955913368246107853">Закрити панель пошуку</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (конверт)</translation>
<translation id="3024663005179499861">Неправильний тип правила</translation>
<translation id="3037605927509011580">От халепа!</translation>
<translation id="3041612393474885105">Інформація про сертифікат</translation>
+<translation id="3060227939791841287">C9 (конверт)</translation>
<translation id="3064966200440839136">Щоб оплатити в зовнішньому додатку, ви вийдете з режиму анонімного перегляду. Продовжити?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{Немає}=1{1 пароль}one{# пароль}few{# паролі}many{# паролів}other{# пароля}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">Додати адресу отримання</translation>
<translation id="3105172416063519923">Ідентифікатор об’єкта:</translation>
<translation id="3109728660330352905">У вас немає дозволу переглядати цю сторінку.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> на сервері <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Скасувати оплату</translation>
<translation id="3207960819495026254">Створено закладку</translation>
-<translation id="3209375525920864198">Введіть дійсну назву сеансу.</translation>
+<translation id="321912867715453276">Застереження. У правилі є кілька джерел з однаковими значеннями.</translation>
<translation id="3225919329040284222">Сервер надав сертифікат, який не відповідає очікуваним вбудованим параметрам. Ці очікувані параметри встановлено для певних веб-сайтів із високим рівнем безпеки, щоб захистити вас.</translation>
<translation id="3226128629678568754">Натисніть кнопку перезавантаження, щоб повторно надіслати дані, потрібні для завантаження сторінки.</translation>
<translation id="3227137524299004712">Мікрофон</translation>
<translation id="3228969707346345236">Помилка перекладу. Сторінку вже перекладено такою мовою: <ph name="LANGUAGE" />.</translation>
+<translation id="3229041911291329567">Інформація про версії пристрою та веб-переглядача</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Додати ім’я на кредитній картці</translation>
<translation id="3287510313208355388">Завантажити після відновлення інтернет-з’єднання</translation>
<translation id="3293642807462928945">Докладніше про правило <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Немає результатів</translation>
-<translation id="3305707030755673451">Ваші дані було зашифровано <ph name="TIME" /> за допомогою парольної фрази для синхронізації. Введіть її, щоб почати синхронізацію.</translation>
<translation id="3320021301628644560">Додати платіжну адресу</translation>
<translation id="3324983252691184275">Малиновий</translation>
<translation id="3338095232262050444">Надійне</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Повторити редагування</translation>
<translation id="342781501876943858">Chromium радить скинути пароль, якщо ви застосовували його на інших сайтах.</translation>
<translation id="3431636764301398940">Зберегти цю картку на пристрої</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">Власник цього пристрою вимкнув гру з динозавром.</translation>
<translation id="3447884698081792621">Показати сертифікат (видавець: <ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">Інтервал отримання:</translation>
+<translation id="3456231139987291353">Number-11 (конверт)</translation>
<translation id="3461824795358126837">Фломастер</translation>
<translation id="3462200631372590220">Сховати додаткову інформацію</translation>
<translation id="3467763166455606212">Потрібно вказати ім’я власника картки</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Кредитні та передплачені картки, які приймаються.</translation>
<translation id="3582930987043644930">Додати ім’я</translation>
<translation id="3583757800736429874">&amp;Повторити переміщення</translation>
+<translation id="35866233670761917">Адміністратори не можу бачити вміст відвіданих вами веб-сайтів</translation>
<translation id="3586931643579894722">Сховати докладні дані</translation>
+<translation id="3592413004129370115">Italian (конверт)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Розмір 2</translation>
<translation id="3615877443314183785">Введіть дійсний термін дії</translation>
<translation id="36224234498066874">Очистити історію…</translation>
<translation id="362276910939193118">Показати повну історію</translation>
-<translation id="3623476034248543066">Показати значення</translation>
<translation id="3630155396527302611">Якщо цій програмі вже надано доступ до мережі, спробуйте
вилучити її зі списку та додати знову.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Перевірку закінчено</translation>
<translation id="3655670868607891010">Якщо ви бачите це часто, спробуйте <ph name="HELP_LINK" />.</translation>
<translation id="3658742229777143148">Редакція</translation>
<translation id="366077651725703012">Оновити кредитну картку</translation>
<translation id="3676592649209844519">Ідентифікатор пристрою:</translation>
+<translation id="3677008721441257057">Ви мали на увазі &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Не вдалося підписати запит</translation>
<translation id="3678529606614285348">Відкрийте сторінку в анонімному вікні (Ctrl+Shift+N)</translation>
<translation id="3679803492151881375">Звіт про аварійне завершення роботи створено: <ph name="CRASH_TIME" />, завантажено: <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Можливо, щоб з’єднатися з цією мережею, потрібно відвідати її сторінку входу.</translation>
<translation id="3704609568417268905"><ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">Завантаження...</translation>
+<translation id="3709599264800900598">Скопійований текст</translation>
<translation id="3712624925041724820">Ліцензії вичерпано</translation>
<translation id="3714780639079136834">увімкнути мобільний Інтернет або Wi-Fi</translation>
<translation id="3715597595485130451">Під’єднання до мережі Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />перевірити конфігурацію проксі-сервера, брандмауера та DNS-сервера<ph name="END_LINK" /></translation>
<translation id="372429172604983730">До додатків, що можуть спричиняти цю помилку, належать антивіруси, брандмауери та програми для веб-фільтрування доступу через проксі.</translation>
+<translation id="373042150751172459">B4 (конверт)</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="3745099705178523657">Щойно ви підтвердите дані картки з облікового запису Google, цей сайт отримає доступ до них.</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">Діє до <ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">Розмір 16</translation>
+<translation id="3797522431967816232">Prc3 (конверт)</translation>
<translation id="3807873520724684969">Заблоковано шкідливий вміст.</translation>
<translation id="3810973564298564668">Змінити</translation>
<translation id="382518646247711829">Якщо ви використовуєте проксі-сервер…</translation>
<translation id="3828924085048779000">Порожня парольна фраза заборонена.</translation>
+<translation id="3831915413245941253">Адміністратор домену <ph name="ENROLLMENT_DOMAIN" /> установив розширення для додаткових функцій. Розширення мають доступ до деяких ваших даних.</translation>
<translation id="385051799172605136">Назад</translation>
<translation id="3858027520442213535">Оновити дату й час</translation>
<translation id="3884278016824448484">Конфліктуючий ідентифікатор пристрою</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">Запит на доступ до цього сайту надіслано користувачу <ph name="NAME" /></translation>
<translation id="3890664840433101773">Додати електронну адресу</translation>
<translation id="3901925938762663762">Термін дії картки минув</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" />: <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Завжди запитувати на цьому сайті</translation>
<translation id="3949571496842715403">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. У його сертифікаті безпеки не вказано альтернативні імена. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Сеанс із такою назвою вже існує.</translation>
<translation id="3987940399970879459">Менше 1 МБ</translation>
+<translation id="4008849406247176967">Застереження. У цьому правилі є кілька джерел із конфліктними значеннями.</translation>
<translation id="40103911065039147">{URL_count,plural, =1{1 веб-сторінка поруч}one{# веб-сторінка поруч}few{# веб-сторінки поруч}many{# веб-сторінок поруч}other{# веб-сторінки поруч}}</translation>
<translation id="4030383055268325496">&amp;Відмінити додавання</translation>
+<translation id="4032320456957708163">Вашим веб-переглядачем керує домен <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="4058922952496707368">Ключ "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (конверт)</translation>
<translation id="4067947977115446013">Додайте дійсну адресу</translation>
<translation id="4072486802667267160">Не вдалось обробити ваше замовлення. Повторіть спробу.</translation>
<translation id="4075732493274867456">Клієнт і сервер підтримують різні версії протоколу SSL або набору шифрів.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Пурпуровий</translation>
<translation id="4165986682804962316">Налаштування сайту</translation>
<translation id="4171400957073367226">Недійсний підпис для підтвердження</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{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="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">&amp;Повторити переміщення</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />перевірити конфігурацію брандмауера й антивірусної програми<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (конверт)</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="4221630205957821124">&lt;h4&gt;Крок 1. Увійдіть на портал&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Скинути пароль</translation>
<translation id="4280429058323657511">, дійсна до <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Цю картку збережено у вашому обліковому записі Google}one{Ці картки збережено у вашому обліковому записі Google}few{Ці картки збережено у вашому обліковому записі Google}many{Ці картки збережено у вашому обліковому записі Google}other{Ці картки збережено у вашому обліковому записі Google}}</translation>
+<translation id="42981349822642051">Розгорнути</translation>
+<translation id="4302965934281694568">Chou3 (конверт)</translation>
<translation id="4305817255990598646">Перейти</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Блокувати (за умовчанням)</translation>
+<translation id="4318566738941496689">Назва пристрою й адреса мережі</translation>
<translation id="4325863107915753736">Статтю не знайдено</translation>
<translation id="4326324639298822553">Перевірте дату закінчення терміну дії та повторіть спробу</translation>
<translation id="4331708818696583467">Ненадійне</translation>
<translation id="4340982228985273705">Цим комп’ютером не керує адміністратор підприємства, тому правило може лише автоматично встановити розширення, розміщені у Веб-магазині Chrome. URL-адреса для оновлення Веб-магазину Chrome: <ph name="CWS_UPDATE_URL" />.</translation>
<translation id="4346197816712207223">Кредитні картки, які приймаються до оплати</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">Зловмисники на цьому сайті можуть намагатися встановити на ваш комп’ютер небезпечні програми, що викрадають або видаляють інформацію (наприклад, фотографії, паролі, повідомлення й дані кредитних карток).</translation>
<translation id="4358461427845829800">Керувати способами оплати…</translation>
+<translation id="4367563149485757821">Number-12 (конверт)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">Очікуване значення: <ph name="VALUE_TYPE" />.</translation>
<translation id="4377125064752653719">Ви пробували зв’язатися з доменом <ph name="DOMAIN" />, проте сервер надав сертифікат, відкликаний його видавцем. Це означає, що не варто довіряти обліковим даним системи захисту, наданим сервером. Можливо, ви обмінюєтеся даними зі зловмисником.</translation>
<translation id="4378154925671717803">Телефон</translation>
<translation id="4406896451731180161">результати пошуку</translation>
-<translation id="4406972042435603828">Ваші адміністратори встановили потужні розширення.</translation>
<translation id="4408413947728134509">Файли cookie: <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Адреса отримання</translation>
<translation id="4424024547088906515">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Chrome не вважає його сертифікат безпеки надійним. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
+<translation id="443121186588148776">Послідовний порт</translation>
<translation id="4432688616882109544">Хост <ph name="HOST_NAME" /> не прийняв ваш сертифікат входу або ви не надали цей сертифікат.</translation>
<translation id="4434045419905280838">Спливаючі вікна й переадресація</translation>
+<translation id="4435702339979719576">Листівка)</translation>
<translation id="443673843213245140">Використання проксі-сервера вимкнено, але чітко вказано налаштування проксі-сервера.</translation>
<translation id="445100540951337728">Прийнятні дебетові картки</translation>
+<translation id="4466881336512663640">Зміни форми не буде збережено. Продовжити?</translation>
<translation id="4482953324121162758">Цей сайт не перекладатиметься.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">Недійсна URL-адреса. Потрібно вказати URL-адресу зі стандартною схемою, як-от http://example.com або https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">Помилка перевірки: <ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">зв’язатися із системним адміністратором</translation>
<translation id="450710068430902550">Надання інформації адміністратору</translation>
+<translation id="4510487217173779431">Chou4 (конверт)</translation>
<translation id="4515275063822566619">Дані картки та список адрес містяться в Chrome і вашому обліковому записі Google (<ph name="ACCOUNT_EMAIL" />). Ними можна керувати в <ph name="BEGIN_LINK" />Налаштуваннях<ph name="END_LINK" />.</translation>
+<translation id="4517607026994743406">Comm-10 (конверт)</translation>
<translation id="4522570452068850558">Деталі</translation>
<translation id="4524805452350978254">Керувати картками</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Спробуйте вимкнути розширення.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Доставка</translation>
+<translation id="4579056131138995126">Особистий (конверт)</translation>
<translation id="4582204425268416675">Видалити картку</translation>
<translation id="4587425331216688090">Видалити адресу з Chrome?</translation>
<translation id="4592951414987517459">З’єднання з доменом <ph name="DOMAIN" /> шифрується за допомогою сучасного набору шифрів.</translation>
<translation id="4594403342090139922">&amp;Відмінити видалення</translation>
<translation id="4597348597567598915">Розмір 8</translation>
+<translation id="4600854749408232102">C6/C5 (конверт)</translation>
<translation id="4646534391647090355">Перейти зараз</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Його сертифікат безпеки містить помилки. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
<translation id="467809019005607715">Google Презентації</translation>
<translation id="4690462567478992370">Припинити використання недійсного сертифіката</translation>
+<translation id="4691835149146451662">Architecture-A (конверт)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">З’єднання розірвано</translation>
<translation id="471880041731876836">У вас немає дозволу відвідувати цей сайт</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />провести діагностику мережі Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Перезавантажити правила</translation>
<translation id="4728558894243024398">Платформа</translation>
+<translation id="4731967714531604179">Prc2 (конверт)</translation>
<translation id="4736825316280949806">Перезапустіть Chromium</translation>
<translation id="473775607612524610">Оновити</translation>
<translation id="4738601419177586157">Пропозиція пошуку за запитом "<ph name="TEXT" />"</translation>
<translation id="4742407542027196863">Керувати паролями…</translation>
<translation id="4744603770635761495">Виконуваний шлях</translation>
+<translation id="4746351372139058112">Повідомлення</translation>
<translation id="4750917950439032686">Ваша інформація (як-от паролі та номери кредитних карток) залишається конфіденційною, коли надсилається на цей сайт.</translation>
<translation id="4756388243121344051">&amp;Історія</translation>
<translation id="4758311279753947758">Додати контактну інформацію</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Веб-сторінка за адресою <ph name="URL" /> може бути тимчасово недоступною або її назавжди переміщено на нову веб-адресу.</translation>
<translation id="4771973620359291008">Виникла невідома помилка.</translation>
<translation id="4785689107224900852">Перейти на цю вкладку</translation>
-<translation id="4792143361752574037">Не вдалось отримати доступ до файлів сеансу. Наразі не можна зберегти сеанс на диску. Оновіть сторінку та повторіть спробу.</translation>
<translation id="4798078619018708837">Введіть дату закінчення терміну дії та код CVC картки <ph name="CREDIT_CARD" />, щоб оновити її дані. Щойно ви підтвердите дані картки в обліковому записі Google, цей сайт отримає доступ до них.</translation>
<translation id="4800132727771399293">Перевірте дату закінчення терміну дії та код CVC та повторіть спробу</translation>
+<translation id="480334179571489655">Помилка правила джерела</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">Відкрити</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Не знайдено жодного результату</translation>
<translation id="4950898438188848926">Кнопка перемикання вкладки: натисніть Enter, щоб перейти на відкриту вкладку, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Дії</translation>
-<translation id="495832697253704892">Звіти про розширення</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Розгорнути список</translation>
<translation id="4974590756084640048">Показувати застереження</translation>
+<translation id="4984339528288761049">Prc5 (конверт)</translation>
<translation id="4989163558385430922">Показати все</translation>
<translation id="4989809363548539747">Цей плагін не підтримується</translation>
-<translation id="4996230189582812866">Звітування</translation>
<translation id="5002932099480077015">Коли цю функцію ввімкнено, Chrome зберігає копію даних вашої картки на пристрої, щоб ви могли швидше заповнювати форми.</translation>
-<translation id="5014174725590676422">Показано екран першого запуску Google Асистента в Chrome</translation>
<translation id="5015510746216210676">Назва пристрою:</translation>
+<translation id="5017554619425969104">Скопійований текст</translation>
<translation id="5018422839182700155">Не вдається відкрити цю сторінку</translation>
<translation id="5019198164206649151">Резервний носій пошкоджено</translation>
<translation id="5023310440958281426">Перегляньте правила свого адміністратора</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Локальний контекст: <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Дозволити</translation>
<translation id="5040262127954254034">Конфіденційність</translation>
+<translation id="5043480802608081735">Скопійоване посилання</translation>
<translation id="5045550434625856497">Неправильний пароль</translation>
<translation id="5056549851600133418">Статті для вас</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />перевірити адресу проксі-сервера<ph name="END_LINK" /></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="5097099694988056070">Статистика пристрою, як-от використання ЦП чи оперативної пам’яті</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465"><ph name="ENROLLMENT_DOMAIN" /> керує вашим пристроєм, а <ph name="ACCOUNT_DOMAIN" /> – обліковим записом. Це означає, що адміністратори можуть віддалено налаштовувати їх.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64-розрядна версія)</translation>
-<translation id="5128122789703661928">Сеанс із цією назвою не можна видалити.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Керувати адресами…</translation>
+<translation id="5138227688689900538">Показати менше</translation>
<translation id="5141240743006678641">Шифрувати синхронізовані паролі за допомогою облікових даних Google</translation>
<translation id="5145883236150621069">Відповідь правила містить код помилки</translation>
+<translation id="515292512908731282">C4 (конверт)</translation>
<translation id="5159010409087891077">Відкрийте сторінку в анонімному вікні (⇧⌘N)</translation>
<translation id="516920405563544094">Введіть код CVC картки <ph name="CREDIT_CARD" />. Щойно ви підтвердите дані картки в обліковому записі Google, цей сайт отримає доступ до них.</translation>
<translation id="5169827969064885044">Ви можете втратити доступ до облікового запису організації, або хтось може викрасти вашу особисту інформацію. Chrome радить змінити пароль.</translation>
<translation id="5171045022955879922">Знайдіть або введіть URL-адресу</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Комп’ютер</translation>
<translation id="5179510805599951267">Це не <ph name="ORIGINAL_LANGUAGE" />? Повідомте про помилку</translation>
<translation id="5190835502935405962">Панель закладок</translation>
-<translation id="5200263511887412697">надавати список користувачів, які нещодавно входили на пристрій</translation>
+<translation id="519422657042045905">Анотація недоступна</translation>
<translation id="5201306358585911203">Повідомлення з вбудованої сторінки на цій сторінці</translation>
<translation id="5205222826937269299">Укажіть ім’я</translation>
<translation id="5215116848420601511">Способи оплати й адреси, пов’язані з Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Укажіть електронну адресу</translation>
<translation id="5230733896359313003">Адреса доставки</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Під’єднайте пристрій до мережі"</translation>
<translation id="5251803541071282808">Хмара</translation>
+<translation id="5252000469029418751">C7 (конверт)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Адреси мережі</translation>
<translation id="5285570108065881030">Показати всі збережені паролі</translation>
<translation id="5287240709317226393">Показати cookie-файли</translation>
<translation id="5288108484102287882">Під час перевірки значень правила виявлено застереження</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> з <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Вибрати контактну інформацію</translation>
<translation id="5327248766486351172">Назва</translation>
+<translation id="5329858041417644019">Веб-переглядачем не керує адміністратор</translation>
<translation id="5332219387342487447">Спосіб доставки</translation>
+<translation id="5334013548165032829">Докладні журнали системи</translation>
<translation id="5344579389779391559">Ця сторінка може спробувати стягнути плату</translation>
<translation id="5355557959165512791">Зараз не можна перейти на сторінку <ph name="SITE" />, оскільки цей сертифікат відкликано. Помилки мережі й атаки зазвичай тимчасові, тому ця сторінка, скоріш за все, запрацює пізніше.</translation>
<translation id="536296301121032821">Помилка збереження налаштувань правила</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Ваш годинник відстає", "Ваш годинник спішить" або "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Щоб використовувати картки на всіх своїх пристроях, увійдіть в обліковий запис і ввімкніть синхронізацію.</translation>
<translation id="5386426401304769735">Ланцюжок сертифіката цього сайту містить сертифікат, підписаний за допомогою SHA-1.</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">Серверу не вдалося підтвердити, що це <ph name="DOMAIN" />. Його сертифікат безпеки зараз недійсний. Можливі причини: неправильна конфігурація або хтось перехопив ваше з’єднання.</translation>
<translation id="5421136146218899937">Очистити історію…</translation>
<translation id="5430298929874300616">Видалити закладку</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Недійсні дані</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Повторити редагування</translation>
+<translation id="5478437291406423475">B6/C4 (конверт)</translation>
<translation id="5481076368049295676">Цей вміст може намагатися встановити на ваш пристрій небезпечну програму, яка викрадає або видаляє інформацію. <ph name="BEGIN_LINK" />Усе одно показати<ph name="END_LINK" /></translation>
<translation id="54817484435770891">Додати дійсну адресу</translation>
<translation id="5490432419156082418">Адреси й інше</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Зв’яжіться зі своїм системним адміністратором.</translation>
<translation id="549333378215107354">Розмір 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Закладки, якими керує адміністратор</translation>
<translation id="5510766032865166053">Можливо, його переміщено або видалено.</translation>
<translation id="5523118979700054094">Назва правила</translation>
<translation id="552553974213252141">Текст отримано правильно?</translation>
+<translation id="553484882784876924">Prc6 (конверт)</translation>
<translation id="5540224163453853">Не вдалося знайти потрібну статтю.</translation>
<translation id="5541546772353173584">Додайте електронну адресу</translation>
<translation id="5545756402275714221">Статті для вас</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Редагувати адресу</translation>
<translation id="5598944008576757369">Вибрати спосіб оплати</translation>
<translation id="560412284261940334">Керування не підтримується</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">перевірити наявність з’єднання</translation>
<translation id="5610807607761827392">Ви можете керувати картками й адресами в <ph name="BEGIN_LINK" />Налаштуваннях<ph name="END_LINK" />.</translation>
<translation id="5617949217645503996">Хост <ph name="HOST_NAME" /> переспрямував вас забагато разів.</translation>
<translation id="5629630648637658800">Помилка завантаження налаштувань правила</translation>
<translation id="5631439013527180824">Недійсний маркер керування пристрою</translation>
+<translation id="5632627355679805402">Дані зашифровано <ph name="BEGIN_LINK" />паролем Google<ph name="END_LINK" /> від <ph name="TIME" />. Введіть пароль, щоб почати синхронізацію.</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="563324245173044180">Заблоковано оманливий вміст.</translation>
<translation id="5659593005791499971">Електронна пошта</translation>
+<translation id="5663614846592581799">9x11 (конверт)</translation>
+<translation id="5663955426505430495">Адміністратор пристрою встановив розширення для додаткових функцій. Розширення мають доступ до деяких ваших даних.</translation>
<translation id="5675650730144413517">Сторінка не працює</translation>
+<translation id="5684874026226664614">На жаль, цю сторінку неможливо перекласти.</translation>
<translation id="5685654322157854305">Додати адресу доставки</translation>
<translation id="5689199277474810259">Експортувати у формат JSON</translation>
<translation id="5689516760719285838">Місцезнаходження</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Ідентифікаційну інформацію цього веб-сайта не було перевірено.</translation>
<translation id="5719499550583120431">Передплачені картки, які приймаються.</translation>
<translation id="5720705177508910913">Поточний користувач</translation>
+<translation id="5728056243719941842">C5 (конверт)</translation>
<translation id="5730040223043577876">Chrome радить скинути пароль, якщо ви застосовували його на інших сайтах.</translation>
<translation id="5732392974455271431">Батьки можуть розблокувати його</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Збережіть картку в обліковому записі Google}one{Збережіть картки в обліковому записі Google}few{Збережіть картки в обліковому записі Google}many{Збережіть картки в обліковому записі Google}other{Збережіть картки в обліковому записі Google}}</translation>
<translation id="5763042198335101085">Введіть дійсну електронну адресу</translation>
<translation id="5765072501007116331">Укажіть адресу, щоб переглянути способи доставки та вимоги.</translation>
-<translation id="5770114862687765385">Схоже, файл пошкоджено. Натисніть кнопку "Скинути", щоб завершити сеанс.</translation>
<translation id="5778550464785688721">Повний контроль пристроїв MIDI</translation>
<translation id="578305955206182703">Бурштиновий</translation>
<translation id="57838592816432529">Вимкнути звук</translation>
<translation id="5784606427469807560">Не вдалося підтвердити дані картки. Перевірте з’єднання з Інтернетом і повторіть спробу.</translation>
<translation id="5785756445106461925">Окрім цього, сторінка містить незахищені ресурси. Інші особи можуть переглядати їх під час передавання даних, а зловмисники можуть змінювати вигляд сторінки.</translation>
<translation id="5786044859038896871">Ввести дані кредитної картки?</translation>
+<translation id="5798290721819630480">Відхилити зміни?</translation>
<translation id="5798683403665926540">Змініть домашню сторінку в налаштуваннях Chrome</translation>
<translation id="5803412860119678065">Ввести дані кредитної картки <ph name="CARD_DETAIL" />?</translation>
<translation id="5804241973901381774">Дозволи</translation>
<translation id="5810442152076338065">З’єднання з доменом <ph name="DOMAIN" /> шифрується за допомогою застарілого набору шифрів.</translation>
<translation id="5813119285467412249">&amp;Повторити додавання</translation>
<translation id="5838278095973806738">Не вводьте конфіденційну інформацію на цьому сайті (як-от паролі й дані кредитних карток). Зловмисники можуть викрасти її.</translation>
+<translation id="5860033963881614850">Вимк.</translation>
<translation id="5863847714970149516">Наступна сторінка може спробувати стягнути плату</translation>
<translation id="5866257070973731571">Додайте номер телефону</translation>
<translation id="5869405914158311789">Немає зв’язку із сайтом</translation>
<translation id="5869522115854928033">Збережені паролі</translation>
<translation id="5887400589839399685">Картку збережено</translation>
-<translation id="5893718151540690985">повідомляти список мережевих інтерфейсів, указуючи їх типи й адреси апаратного забезпечення</translation>
<translation id="5893752035575986141">Кредитні картки, які приймаються.</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="5916664084637901428">Увімкнути</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Зберегти картку в обліковому записі Google?</translation>
<translation id="5922853866070715753">Майже готово</translation>
<translation id="5932224571077948991">Сайт показує нав’язливі чи оманливі оголошення</translation>
-<translation id="5939518447894949180">Скинути</translation>
<translation id="5946937721014915347">Відкривається <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Не вдається зареєструватися за допомогою особистого облікового запису користувача (ліцензію отримано в комплекті з пристроєм).</translation>
<translation id="5967592137238574583">Змініть контактну інформацію</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Зменшити масштаб</translation>
<translation id="5977489021191000276">Адміністратор не керує вашим пристроєм.</translation>
<translation id="5977976211062815271">На цьому пристрої</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Неможливо відкрити додаток для платежів</translation>
<translation id="5989320800837274978">Не вказано ні фіксованих проксі-серверів, ні URL-адрес сценарію .pac.</translation>
<translation id="5990559369517809815">Надсилання запитів на сервер заблоковано розширенням.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">повідомляти статистику апаратного забезпечення, як-от використання ЦП або оперативної пам’яті</translation>
<translation id="6034000775414344507">Світло-сірий</translation>
+<translation id="6034283069659657473">10x14 (конверт)</translation>
<translation id="6039846035001940113">Якщо проблема не зникла, зв’яжіться з власником сайту.</translation>
<translation id="6040143037577758943">Закрити</translation>
<translation id="6044573915096792553">Розмір 12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">Зараз не можна перейти на сторінку <ph name="SITE" />, оскільки цей веб-сайт використовує закріплення сертифікатів. Помилки мережі й атаки зазвичай тимчасові, тому ця сторінка, скоріш за все, запрацює пізніше.</translation>
<translation id="6058977677006700226">Використовувати картки на всіх ваших пристроях?</translation>
<translation id="6059925163896151826">Пристрої USB</translation>
-<translation id="6071091556643036997">Це правило недійсне.</translation>
<translation id="6080696365213338172">Ви отримали доступ до вмісту, використовуючи наданий адміністратором сертифікат. Адміністратор може перехоплювати дані, які ви надасте домену <ph name="DOMAIN" />.</translation>
<translation id="6094273045989040137">Додати примітку</translation>
<translation id="610911394827799129">Історія веб-перегляду може також зберігатися у вашому обліковому записі Google на сторінці <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Інформація про встановлені розширення та плагіни</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{Немає}=1{1 пароль (синхронізовано)}one{# пароль (синхронізовано)}few{# паролі (синхронізовано)}many{# паролів (синхронізовано)}other{# пароля (синхронізовано)}}</translation>
<translation id="6146055958333702838">Перевірте всі кабелі та перезавантажте всі маршрутизатори, модеми чи інші мережеві
пристрої, які ви використовуєте.</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Звільняє менше <ph name="SIZE" />. Деякі сайти можуть завантажуватися повільніше під час наступного відвідування.</translation>
<translation id="6337534724793800597">Фільтрувати правила за назвою</translation>
<translation id="6358450015545214790">Що це означає?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Можливе стягнення плати.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{і ще 1 пропозиція}one{і ще # пропозиція}few{і ще # пропозиції}many{і ще # пропозицій}other{і ще # пропозиції}}</translation>
<translation id="6387754724289022810">Щоб наступного разу платити швидше, збережіть дані картки та платіжну адресу в обліковому записі Google і на цьому пристрої.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Редагувати закладку</translation>
+<translation id="6406765186087300643">C0 (конверт)</translation>
<translation id="6410264514553301377">Введіть дату закінчення терміну дії та код CVC картки <ph name="CREDIT_CARD" /></translation>
<translation id="6414888972213066896">Ви надіслали одному з батьків запит на перегляд цього сайту</translation>
<translation id="6417515091412812850">Неможливо перевірити, чи цей сертифікат було відкликано.</translation>
<translation id="6433490469411711332">Змінити контактні дані</translation>
<translation id="6433595998831338502">Хост <ph name="HOST_NAME" /> відхилив запит на з’єднання.</translation>
+<translation id="6434309073475700221">Скасувати</translation>
+<translation id="6446163441502663861">Kahu (конверт)</translation>
<translation id="6446608382365791566">Додати більше інформації</translation>
<translation id="6447842834002726250">Cookie-файли</translation>
<translation id="6451458296329894277">Підтвердити повторне надсилання форми</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Перезапустіть Chrome</translation>
<translation id="6529602333819889595">&amp;Повторити видалення</translation>
<translation id="6534179046333460208">Пропозиції сервісу "Інтернет навколо нас"</translation>
+<translation id="6556866813142980365">Повторити</translation>
<translation id="6563469144985748109">Адміністратор ще не схвалив його</translation>
<translation id="6569060085658103619">Ви переглядаєте сторінку розширень</translation>
+<translation id="6578796323535178455">C2 (конверт)</translation>
<translation id="6579990219486187401">Світло-рожевий</translation>
+<translation id="6583674473685352014">B6 (конверт)</translation>
+<translation id="6587923378399804057">Скопійоване посилання</translation>
+<translation id="6591833882275308647">Пристроєм <ph name="DEVICE_TYPE" /> не керує адміністратор</translation>
<translation id="6596325263575161958">Параметри шифрування</translation>
<translation id="6604181099783169992">Датчики руху чи світла</translation>
+<translation id="6609880536175561541">Prc7 (конверт)</translation>
<translation id="6624427990725312378">Контактна інформація</translation>
<translation id="6626291197371920147">Додати дійсний номер картки</translation>
<translation id="6628463337424475685">Пошук <ph name="ENGINE" /></translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Це правило більше не використовується.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Немає}=1{З 1 сайту (ви не вийдете з облікового запису Google)}one{З # сайту (ви не вийдете з облікового запису Google)}few{З # сайтів (ви не вийдете з облікового запису Google)}many{З # сайтів (ви не вийдете з облікового запису Google)}other{З # сайту (ви не вийдете з облікового запису Google)}}</translation>
<translation id="6657585470893396449">Пароль</translation>
+<translation id="6670613747977017428">Повернутися до безпечного режиму.</translation>
<translation id="6671697161687535275">Видалити пропозицію автозаповнення форм із Chromium?</translation>
<translation id="6685834062052613830">Вийдіть з облікового запису та завершіть процедуру налаштування</translation>
<translation id="6710213216561001401">Попереднє</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Маркер реєстрації:</translation>
<translation id="6711464428925977395">Помилка проксі-сервера або неправильна адреса.</translation>
<translation id="6723740634201835758">В обліковому записі Google</translation>
+<translation id="6738516213925468394">Ваші дані було зашифровано за допомогою <ph name="BEGIN_LINK" />парольної фрази для синхронізації<ph name="END_LINK" /> від <ph name="TIME" />. Введіть її, щоб почати синхронізацію.</translation>
<translation id="674375294223700098">Помилка "Невідомий сертифікат сервера".</translation>
<translation id="6744009308914054259">Очікуючи на з’єднання, можете перейти в папку "Завантаження" й переглянути статті, доступні в режимі офлайн.</translation>
<translation id="6753269504797312559">Значення правила</translation>
<translation id="6757797048963528358">Ваш пристрій перейшов у режим сну.</translation>
+<translation id="6768213884286397650">Hagaki (листівка)</translation>
<translation id="6778737459546443941">Батьки ще не схвалили його</translation>
<translation id="67862343314499040">Фіолетовий</translation>
+<translation id="6786747875388722282">Розширення</translation>
<translation id="679355240208270552">Ігнорується, оскільки пошукову систему за умовчанням вимкнено правилом.</translation>
<translation id="681021252041861472">Обов’язкове поле</translation>
<translation id="6810899417690483278">Ідентифікатор налаштування</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Пристрій</translation>
<translation id="6970216967273061347">Округ</translation>
<translation id="6973656660372572881">Указано фіксовані проксі-сервери та URL-адреса сценарію .pac.</translation>
+<translation id="6973932557599545801">На жаль, я не можу допомогти. Продовжуйте самостійно.</translation>
<translation id="6979158407327259162">Диск Google</translation>
<translation id="6979440798594660689">Без звуку (за умовчанням)</translation>
<translation id="6984479912851154518">Щоб оплатити в зовнішньому додатку, ви вийдете з приватного режиму. Продовжити?</translation>
<translation id="6989763994942163495">Показати розширені налаштування...</translation>
+<translation id="6993898126790112050">6x9 (конверт)</translation>
<translation id="6996312675313362352">Завжди перекладати з такої мови: <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Такі стягнення можуть бути одноразовими чи регулярними й неочевидними.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Сховати</translation>
<translation id="7108819624672055576">Дозволено розширенням</translation>
<translation id="7111012039238467737">(Дійсний)</translation>
+<translation id="7118618213916969306">Пошук URL-адреси з буфера обміну, <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">Закрийте інші вкладки та програми</translation>
<translation id="7129409597930077180">Неможливо відправити замовлення на цю адресу. Укажіть іншу адресу.</translation>
<translation id="7135130955892390533">Показати статус</translation>
<translation id="7138472120740807366">Спосіб доставки</translation>
<translation id="7139724024395191329">Емірат</translation>
+<translation id="7152423860607593928">Number-14 (конверт)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Лавандовий</translation>
-<translation id="7158980942472052083">Недійсна URL-адреса. Потрібно вказати URL-адресу зі стандартною схемою.</translation>
<translation id="717330890047184534">Ідентифікатор GAIA:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Сервер, на який ви переходите (<ph name="ORIGIN" />), попросив, щоб
+ до всіх його запитів застосовувалося правило безпеки. Однак замість
+ повернення правила він переспрямовує веб-переглядач, що не дозволяє
+ йому виконати ваш запит для сайту <ph name="SITE" />.</translation>
<translation id="7179323680825933600">Зберігати й заповнювати способи оплати</translation>
<translation id="7180611975245234373">Оновити</translation>
<translation id="7182878459783632708">Правила не встановлено</translation>
<translation id="7186367841673660872">Цю сторінку перекладено. Мова оригіналу:<ph name="ORIGINAL_LANGUAGE" />мова перекладу:<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Звільниться до <ph name="SIZE" /> простору. Після цього деякі сайти можуть завантажуватися довше.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Адміністратор може бачити:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423">Хост <ph name="HOST_NAME" /> не відповідає стандартам безпеки.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /> про цю проблему.</translation>
<translation id="7219179957768738017">З'єднання використовує версію <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Обробка</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">Сайт містить зловмисне програмне забезпечення</translation>
+<translation id="724766306220616965">Застереження, конфлікт</translation>
<translation id="724975217298816891">Введіть термін дії та код CVC картки <ph name="CREDIT_CARD" />, щоб оновити її дані. Щойно ви підтвердите дані картки, цей сайт отримає доступ до них.</translation>
<translation id="7251437084390964440">Конфігурація мережі не відповідає стандарту ONC. Вона може імпортуватися частково.
Додаткові відомості:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">Кобальтовий</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</translation>
<translation id="7309308571273880165">Звіт про аварійне завершення роботи створено <ph name="CRASH_TIME" /> (ще не завантажено)</translation>
+<translation id="7313965965371928911">Застереження <ph name="BEGIN_LINK" />Безпечного перегляду<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Довідка щодо з’єднання</translation>
<translation id="7334320624316649418">&amp;Повторити перевпорядкування</translation>
<translation id="733923710415886693">Сертифікат сервера не надав інформацію про перевірку.</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Командний рядок</translation>
-<translation id="7365061714576910172">Експортувати Linux</translation>
<translation id="7372973238305370288">результат пошуку</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">Ні</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">Заміна керованого сеансу</translation>
<translation id="7390545607259442187">Підтвердити дані картки</translation>
<translation id="7400418766976504921">URL-адреса</translation>
+<translation id="7403591733719184120">Пристроєм <ph name="DEVICE_NAME" /> керує адміністратор</translation>
<translation id="7407424307057130981">&lt;p&gt;Це повідомлення про помилку з’являється, якщо на комп’ютері Windows установлено програму Superfish.&lt;/p&gt;
&lt;p&gt;Виконайте ці дії, щоб тимчасово вимкнути програмне забезпечення й отримати доступ до Інтернету. Для цього потрібні права адміністратора.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;Натисніть &lt;strong&gt;Застосувати&lt;/strong&gt;, а потім – кнопку &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Відвідайте &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Довідковий центр Chrome&lt;/a&gt;, щоб дізнатися, як повністю видалити програмне забезпечення з комп’ютера
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Керування <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Широкий формат</translation>
<translation id="7416351320495623771">Керувати паролями…</translation>
<translation id="7419106976560586862">Шлях до профілю</translation>
<translation id="7437289804838430631">Додати контактну інформацію</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">Світло-оранжевий</translation>
<translation id="7444046173054089907">Цей сайт заблоковано</translation>
<translation id="7445762425076701745">Ідентифікацію сервера, з яким ви з'єднані, не можна повністю підтвердити. Ви з'єднані із сервером за допомогою імені, дійсного лише у вашій мережі, і зовнішній центр сертифікації не має способів підтвердити право власності на це ім'я. Хоча деякі центри сертифікації, попри все, видають сертифікати на такі імена, неможливо цілком упевнитися, що ви з'єднані з безпечним сайтом, а не зі зловмисником.</translation>
-<translation id="7449109375006139765">надсилати системні журнали на сервер керування</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />дізнатися більше<ph name="END_LINK" /> про цю проблему.</translation>
<translation id="7455133967321480974">Використовувати глобальне налаштування за умовчанням (Блокувати)</translation>
<translation id="7460618730930299168">Дані відрізняються від вибраних. Продовжити?</translation>
<translation id="7473891865547856676">Ні, дякую</translation>
-<translation id="7475525192983021547">повідомляти періоди активності пристрою</translation>
<translation id="7481312909269577407">Переслати</translation>
<translation id="7485870689360869515">Даних не знайдено.</translation>
+<translation id="7498234416455752244">Продовжити редагування</translation>
<translation id="7508255263130623398">Отриманий ідентифікатор правил пристрою порожній або не збігається з поточним ідентифікатором пристрою</translation>
<translation id="7508870219247277067">Світло-зелений</translation>
<translation id="7511955381719512146">Можливо, щоб під’єднатися до цієї мережі Wi-Fi, потрібно відвідати сторінку <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
<translation id="7514365320538308">Завантажити</translation>
<translation id="7518003948725431193">Не знайдено веб-сторінок для веб-адреси <ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (конверт)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Ваше з’єднання з цим сайтом не конфіденційне</translation>
+<translation id="7535087603100972091">Яскравість</translation>
<translation id="7537536606612762813">Обов’язкове</translation>
+<translation id="7538364083937897561">A2 (конверт)</translation>
<translation id="7542403920425041731">Щойно ви підтвердите, цей сайт отримає доступ до даних вашої картки.</translation>
<translation id="7542995811387359312">Автоматичне заповнення кредитної картки вимкнено, оскільки ця форма не використовує безпечне з'єднання.</translation>
<translation id="7543525346216957623">Попросіть когось із батьків</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">Виконайте вказівки нижче.</translation>
<translation id="7554791636758816595">Нова вкладка</translation>
<translation id="7564049878696755256">Ви можете втратити доступ до облікового запису, який вам надає <ph name="ORG_NAME" />, або хтось може викрасти вашу особисту інформацію. Chrome радить змінити пароль.</translation>
-<translation id="7566125604157659769">Скопійований текст</translation>
<translation id="7567204685887185387">Цей сервер не зміг довести, що він – домен <ph name="DOMAIN" />. Можливо, його сертифікат безпеки видали шахраї. Імовірні причини: неправильна конфігурація або хтось намагається перехопити ваше з’єднання.</translation>
+<translation id="7568105740864181217">Цим веб-переглядачем керує адміністратор компанії, навчального закладу чи іншої організації. Адміністратор може змінити налаштування веб-переглядача віддалено. Діями на цьому пристрої можна керувати за межами Chrome. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">Видалити дані кредитної картки з Chrome?</translation>
<translation id="7569983096843329377">Чорний</translation>
<translation id="7578104083680115302">Зберігайте картки в Google, щоб швидко платити на сайтах і в додатках на всіх своїх пристроях.</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">Дані про ефективність і звіти про збої</translation>
<translation id="7637571805876720304">Видалити дані кредитної картки з Chromium?</translation>
<translation id="7639968568612851608">Темно-сірий</translation>
<translation id="765676359832457558">Сховати розширені налаштування...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">Отриманий маркер правила порожній або не збігається з поточним маркером</translation>
<translation id="7668654391829183341">Невідомий пристрій</translation>
<translation id="7669271284792375604">Зловмисники на цьому сайті можуть обманом змусити вас установити програми, які погіршують роботу в Інтернеті (наприклад, змінюють вашу домашню сторінку або показують додаткову рекламу на сайтах, які ви відвідуєте).</translation>
+<translation id="7676643023259824263">Пошук тексту з буфера обміну: <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Змінити пошукову систему</translation>
<translation id="7682287625158474539">Адреса для надсилання</translation>
<translation id="7687186412095877299">Заповнює платіжні форми, використовуючи збережені способи оплати</translation>
+<translation id="7697066736081121494">Prc8 (конверт)</translation>
<translation id="769721561045429135">Зараз у вас є картки, які можна використовувати лише на цьому пристрої. Натисніть "Продовжити", щоб переглянути їх.</translation>
<translation id="7699293099605015246">Зараз статті недоступні</translation>
<translation id="7701040980221191251">Немає</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">Заблоковано небезпечний вміст.</translation>
<translation id="7752995774971033316">Некерований клієнт</translation>
<translation id="7755287808199759310">Хтось із батьків може розблокувати його</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">Можливо, брандмауер або антивірусна програма заблокували з’єднання.</translation>
<translation id="7759163816903619567">Видимий домен:</translation>
<translation id="7761701407923456692">Сертифікат сервера не відповідає URL-адресі.</translation>
<translation id="7763386264682878361">Синтаксичний аналізатор маніфесту платежу</translation>
<translation id="7764225426217299476">Додати адресу</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Префектура</translation>
<translation id="7791543448312431591">Додати</translation>
<translation id="7793809570500803535">Веб-сторінка на сайті <ph name="SITE" /> може бути тимчасово недоступна або її назавжди переміщено за новою веб-адресою.</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Видалити дані для автозаповнення форм із Chrome?</translation>
<translation id="7815407501681723534">Знайдено результатів за запитом "<ph name="SEARCH_STRING" />": <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /></translation>
-<translation id="7818867226424560206">Правила</translation>
<translation id="782886543891417279">Можливо, щоб під’єднатися до цієї мережі Wi-Fi (<ph name="WIFI_NAME" />), потрібно відвідати її сторінку входу.</translation>
+<translation id="7836231406687464395">Postfix (конверт)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Немає}=1{1 додаток (<ph name="EXAMPLE_APP_1" />)}=2{2 додатки (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}one{# додаток (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}few{# додатки (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}many{# додатків (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}other{# додатка (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" /> <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Навіть у режимі анонімного перегляду ваш роботодавець, постачальник послуг Інтернету чи веб-сайти, які ви відвідуєте, можуть бачити, що ви переглядаєте.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" />: <ph name="FORMATTED_TOTAL_AMOUNT" /> <ph name="CURRENCY_CODE" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">Ваш пароль можуть зламати</translation>
<translation id="7882421473871500483">Коричневий</translation>
<translation id="7887683347370398519">Перевірте код CVC й повторіть спробу</translation>
-<translation id="7893255318348328562">Назва сеансу</translation>
+<translation id="7904208859782148177">C3 (конверт)</translation>
<translation id="79338296614623784">Введіть дійсний номер телефону</translation>
<translation id="7935318582918952113">Дистилятор DOM</translation>
<translation id="7937554595067888181">Діє до <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(32-розрядна версія)</translation>
<translation id="7956713633345437162">Закладки на мобільному</translation>
<translation id="7961015016161918242">Ніколи</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">Не вказано</translation>
<translation id="800218591365569300">Щоб звільнити пам’ять, закрийте інші вкладки та програми.</translation>
+<translation id="8004582292198964060">Переглядач</translation>
<translation id="8009225694047762179">Керувати паролями</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Цю картку та її платіжну адресу буде збережено. Ви зможете скористатися нею, коли ввійдете в обліковий запис <ph name="USER_EMAIL" />.}one{Ці картки та їх платіжні адреси буде збережено. Ви зможете скористатися ними, коли ввійдете в обліковий запис <ph name="USER_EMAIL" />.}few{Ці картки та їх платіжні адреси буде збережено. Ви зможете скористатися ними, коли ввійдете в обліковий запис <ph name="USER_EMAIL" />.}many{Ці картки та їх платіжні адреси буде збережено. Ви зможете скористатися ними, коли ввійдете в обліковий запис <ph name="USER_EMAIL" />.}other{Ці картки та їх платіжні адреси буде збережено. Ви зможете скористатися ними, коли ввійдете в обліковий запис <ph name="USER_EMAIL" />.}}</translation>
<translation id="8012647001091218357">Не вдалося зв’язатися з вашими батьками. Повторіть спробу.</translation>
<translation id="8025119109950072390">Зловмисники на цьому сайті можуть обманом змусити вас виконати небезпечну дію, як-от установити програмне забезпечення або повідомити особисту інформацію (наприклад, паролі, номери телефонів або кредитних карток).</translation>
<translation id="8034522405403831421">Мова цієї сторінки: <ph name="SOURCE_LANGUAGE" />. Перекласти її такою мовою: <ph name="TARGET_LANGUAGE" />?</translation>
<translation id="8035152190676905274">Перо</translation>
+<translation id="8037117624646282037">Хто нещодавно користувався пристроєм</translation>
<translation id="8037357227543935929">Запитувати (за умовчанням)</translation>
<translation id="803771048473350947">Файл</translation>
<translation id="8041089156583427627">Надіслати відгук</translation>
<translation id="8041940743680923270">Використовувати глобальне налаштування за умовчанням (Запитувати)</translation>
<translation id="8042918947222776840">Вибрати спосіб отримання</translation>
<translation id="8057711352706143257"><ph name="SOFTWARE_NAME" /> налаштовано неправильно. Якщо видалити програмне забезпечення <ph name="SOFTWARE_NAME" />, проблема зазвичай зникає. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Ваш пристрій налаштовано, щоб:</translation>
+<translation id="8066955247577885446">Сталася помилка.</translation>
+<translation id="8074253406171541171">10x13 (конверт)</translation>
<translation id="8078141288243656252">Коли документ обернено, створення приміток недоступне</translation>
<translation id="8079031581361219619">Оновити сайт?</translation>
<translation id="8088680233425245692">Не вдалося переглянути статтю.</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">Активація очікує на сервері</translation>
<translation id="8092774999298748321">Насичений пурпуровий</translation>
<translation id="8094917007353911263">Можливо, щоб під’єднатися до цієї мережі, потрібно відвідати сторінку <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Недійсні картки видалено</translation>
<translation id="8103161714697287722">Спосіб оплати</translation>
<translation id="8118489163946903409">Спосіб оплати</translation>
+<translation id="8123836779274890062">Пристроєм <ph name="DEVICE_TYPE" /> керує домен <ph name="ENROLLMENT_DOMAIN" /></translation>
<translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> неправильно встановлено на вашому комп’ютері або в мережі. Попросіть IT-адміністратора вирішити цю проблему.</translation>
-<translation id="8130693978878176684">Я більше не можу допомогти, продовжуйте самостійно.</translation>
<translation id="8131740175452115882">Підтвердити</translation>
<translation id="8149426793427495338">Ваш комп’ютер перейшов у режим сну.</translation>
<translation id="8150722005171944719">Файл за адресою <ph name="URL" /> не читається. Можливо, його видалено, переміщено або доступ заборонено дозволами файлу.</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">Перекласти сторінку</translation>
<translation id="8201077131113104583">Недійсна URL-адреса для оновлення розширення з ідентифікатором "<ph name="EXTENSION_ID" />".</translation>
<translation id="8202097416529803614">Підсумок замовлення</translation>
+<translation id="8202370299023114387">Конфлікт</translation>
+<translation id="8206978196348664717">Prc4 (конверт)</translation>
<translation id="8211406090763984747">З’єднання безпечне</translation>
<translation id="8218327578424803826">Указане місцезнаходження:</translation>
+<translation id="8220146938470311105">C7/C6 (конверт)</translation>
<translation id="8225771182978767009">Користувач, який налаштував комп’ютер, заблокував цей сайт.</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">Відкрити сторінку в новій анонімній вкладці</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">Показати всі збережені паролі</translation>
<translation id="8261506727792406068">Видалити</translation>
<translation id="8267698848189296333">Ви входите як <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">Цим веб-переглядачем керує домен <ph name="ENROLLMENT_DOMAIN" />. Адміністратор може змінити налаштування веб-переглядача віддалено. Діями на цьому пристрої можна керувати за межами Chrome. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Вхід</translation>
<translation id="8288807391153049143">Показати сертифікат</translation>
<translation id="8289355894181816810">Зверніться до адміністратора своєї мережі, якщо ви не знаєте, що це означає.</translation>
<translation id="8293206222192510085">Додати закладку</translation>
<translation id="8294431847097064396">Джерело</translation>
<translation id="8298115750975731693">Можливо, щоб під’єднатися до цієї мережі Wi-Fi (<ph name="WIFI_NAME" />), потрібно відвідати сторінку <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Переклад не виконано через проблему підключення до мережі.</translation>
-<translation id="8311129316111205805">Завантажити сеанс</translation>
<translation id="8332188693563227489">Відмовлено в доступі до хосту <ph name="HOST_NAME" /></translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">Якщо ви розумієте ризики, пов’язані з безпекою, можете <ph name="BEGIN_LINK" />перейти на цей сайт<ph name="END_LINK" /> до того, як небезпечні програми буде видалено.</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">Конфігурація мережі недійсна та не може імпортуватися.
Додаткові відомості:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533"><ph name="ENROLLMENT_DOMAIN" /> керує пристроєм</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Змінити</translation>
<translation id="8428213095426709021">Налаштування</translation>
@@ -1211,9 +1369,11 @@
<translation id="860043288473659153">Ім’я та прізвище власника картки</translation>
<translation id="861775596732816396">Розмір 4</translation>
<translation id="8620436878122366504">Батьки ще не схвалили його</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Зберегти цю картку на пристрої</translation>
<translation id="8663226718884576429">Підсумок замовлення, <ph name="TOTAL_LABEL" />, докладніше</translation>
<translation id="8680536109547170164">"<ph name="QUERY" />", відповідь: "<ph name="ANSWER" />"</translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Ваше з’єднання з <ph name="DOMAIN" /> не зашифровано.</translation>
<translation id="8718314106902482036">Оплату не завершено</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, пропозиція пошуку</translation>
@@ -1227,6 +1387,7 @@
<translation id="8761567432415473239">Функція безпечного перегляду від Google нещодавно <ph name="BEGIN_LINK" />виявила шкідливі програми<ph name="END_LINK" /> на сайті <ph name="SITE" />.</translation>
<translation id="8763927697961133303">Пристрій USB</translation>
<translation id="8768895707659403558">Щоб використовувати картки на всіх своїх пристроях, <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Повторити видалення</translation>
<translation id="8792621596287649091">Ви можете втратити доступ до облікового запису, який вам надає <ph name="ORG_NAME" />, або хтось може викрасти вашу особисту інформацію. Chromium радить змінити пароль.</translation>
<translation id="8800988563907321413">Тут відображатимуться пропозиції</translation>
@@ -1237,10 +1398,12 @@
<translation id="885730110891505394">Надання інформації службам Google</translation>
<translation id="8858065207712248076">Chrome радить скинути пароль <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" />, якщо ви застосовували його на інших сайтах.</translation>
<translation id="8866481888320382733">Помилка аналізу налаштувань правила</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Нещодавно закриті</translation>
<translation id="8874824191258364635">Введіть дійсний номер картки</translation>
<translation id="8891727572606052622">Недійсний режим проксі-сервера.</translation>
<translation id="8903921497873541725">Збільшити масштаб</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">Зберегти цю картку у вашому обліковому записі Google?</translation>
<translation id="8932102934695377596">Ваш годинник запізнюється</translation>
<translation id="893332455753468063">Додайте ім’я</translation>
@@ -1248,13 +1411,13 @@
<translation id="894185898663964645">Адміністратор налаштував власні кореневі сертифікати, які дозволяють йому переглядати вміст відвіданих вами веб-сайтів.</translation>
<translation id="8943282376843390568">Лаймовий</translation>
<translation id="8957210676456822347">Авторизація приєднаного порталу</translation>
+<translation id="8966619695390250636">Ви мали на увазі?</translation>
<translation id="8968766641738584599">Зберегти картку</translation>
<translation id="8971063699422889582">Термін дії сертифіката сервера завершився.</translation>
<translation id="8975012916872825179">Номери телефонів, електронні адреси, адреси доставки тощо</translation>
<translation id="8978053250194585037">Функція безпечного перегляду від Google нещодавно <ph name="BEGIN_LINK" />виявила фішинг<ph name="END_LINK" /> на сайті <ph name="SITE" />. Фішингові сайти видають себе за інші сайти, щоб ошукати вас.</translation>
<translation id="8983003182662520383">Способи оплати й адреси, пов’язані з Google Pay</translation>
<translation id="8987927404178983737">Місяць</translation>
-<translation id="8988408250700415532">Сталася помилка. Ви можете завершити замовлення на веб-сайті.</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">Сайт містить шкідливі програми</translation>
<translation id="8997023839087525404">Сервер надав сертифікат без інформації про перевірку. Це обов’язкові дані для деяких сертифікатів. Вони підтверджують надійність сертифіката й захищають від атак зловмисників.</translation>
@@ -1264,6 +1427,7 @@
<translation id="9011424611726486705">Відкрити налаштування сайту</translation>
<translation id="9020200922353704812">Потрібно вказати платіжну адресу картки</translation>
<translation id="9020542370529661692">Цю сторінку перекладено такою мовою: <ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Недійсний)</translation>
<translation id="9035022520814077154">Помилка системи безпеки</translation>
<translation id="9038649477754266430">Користуйтеся службою передбачення, щоб сторінки завантажувалися швидше</translation>
@@ -1275,11 +1439,11 @@
<translation id="9065745800631924235">Пошук в історії за запитом "<ph name="TEXT" />"</translation>
<translation id="9069693763241529744">Заблоковано розширенням</translation>
<translation id="9076283476770535406">На ньому може бути вміст для дорослих</translation>
+<translation id="9076630408993835509">Цим веб-переглядачем не керує адміністратор компанії чи іншої організації. Діями на цьому пристрої можна керувати за межами Chrome. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Потрібно більше інформації</translation>
<translation id="9080712759204168376">Підсумок замовлення</translation>
<translation id="9103872766612412690">Веб-сайт <ph name="SITE" /> зазвичай використовує шифрування для захисту вашої інформації. Під час цієї спроби Chromium під’єднатися до сторінки <ph name="SITE" /> з неї отримано незвичні й неправильні облікові дані. Це може статися, коли зловмисник намагається видавати себе за веб-сайт <ph name="SITE" /> або з’єднання перервано екраном входу Wi-Fi. Ваша інформація залишається захищеною, оскільки Chromium припинив з’єднання до того, як почався обмін будь-якими даними.</translation>
<translation id="9106062320799175032">Додайте платіжну адресу</translation>
-<translation id="9110718169272311511">Google Асистент розташований унизу екрана Chrome</translation>
<translation id="9114524666733003316">Підтверджуються дані картки…</translation>
<translation id="9128870381267983090">З'єднатися з мережею</translation>
<translation id="9137013805542155359">Показати оригінал</translation>
@@ -1288,6 +1452,7 @@
<translation id="9148507642005240123">&amp;Відмінити редагування</translation>
<translation id="9154194610265714752">Оновлено</translation>
<translation id="9157595877708044936">Налаштування...</translation>
+<translation id="9158625974267017556">C6 (конверт)</translation>
<translation id="9168814207360376865">Дозволити сайтам перевіряти, чи у вас є збережені способи оплати</translation>
<translation id="9169664750068251925">Завжди блокувати на цьому сайті</translation>
<translation id="9170848237812810038">&amp;Скасувати</translation>
@@ -1302,10 +1467,12 @@
<translation id="9219103736887031265">Зображення</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">ОЧИСТИТИ ФОРМУ</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Ви можете втратити доступ до облікового запису Google. Chromium радить змінити пароль. Вам буде запропоновано ввійти в обліковий запис.</translation>
<translation id="939736085109172342">Нова папка</translation>
<translation id="945855313015696284">Перевірте дані нижче й видаліть недійсні картки.</translation>
<translation id="951104842009476243">Дебетові та передплачені картки, які приймаються до оплати</translation>
+<translation id="958202389743790697">Заблоковано відповідно до правила безпеки <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Ця сторінка може намагатися встановлювати оманливі додатки, які видають себе за інший вміст, або збирати дані для відстеження ваших дій. <ph name="BEGIN_LINK" />Усе одно показати<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Розробка</translation>
<translation id="973773823069644502">Додати адресу доставки</translation>
@@ -1314,6 +1481,7 @@
<translation id="984275831282074731">Способи оплати</translation>
<translation id="985199708454569384">&lt;p&gt;Це повідомлення про помилку з’являється, якщо дата й час на комп’ютері або мобільному пристрої неправильні.&lt;/p&gt;
&lt;p&gt;Щоб виправити цю помилку, відкрийте годинник на пристрої та переконайтеся, що дата й час правильні.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Конструкція розробника</translation>
<translation id="989988560359834682">Редагувати адресу</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_vi.xtb b/chromium/components/strings/components_strings_vi.xtb
index 4933eedaf39..6e92c10afa3 100644
--- a/chromium/components/strings/components_strings_vi.xtb
+++ b/chromium/components/strings/components_strings_vi.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="vi">
-<translation id="1005145902654145231">Không đổi được tên phiên.</translation>
<translation id="1008557486741366299">Không phải Bây giờ</translation>
<translation id="1010200102790553230">Tải trang vào lúc khác</translation>
<translation id="1015730422737071372">Cung cấp chi tiết bổ sung</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">tên không biết</translation>
<translation id="1050038467049342496">Đóng các ứng dụng khác</translation>
<translation id="1055184225775184556">&amp;Hoàn tác thêm</translation>
+<translation id="1056898198331236512">Cảnh báo</translation>
<translation id="1058479211578257048">Đang lưu thẻ...</translation>
<translation id="10614374240317010">Không bao giờ lưu</translation>
+<translation id="1062160989074299343">Prc10 (Phong bì)</translation>
<translation id="106701514854093668">Dấu trang máy tính</translation>
<translation id="1074497978438210769">Không bảo mật</translation>
<translation id="1080116354587839789">Vừa với chiều rộng</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">Thêm tên trên thẻ</translation>
<translation id="1089439967362294234">Thay đổi mật khẩu</translation>
<translation id="109743633954054152">Quản lý mật khẩu trong mục cài đặt của Chrome</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">Cảnh báo hiển thị khi trang web cập nhật bảo mật là điều bình thường. Việc này sẽ sớm được cải tiến.</translation>
<translation id="1126551341858583091">Kích thước trên bộ nhớ cục bộ là <ph name="CRASH_SIZE" />.</translation>
<translation id="112840717907525620">Bộ nhớ đệm chính sách OK</translation>
+<translation id="1131264053432022307">Hình ảnh bạn đã sao chép</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ớ đệm<ph name="END_LINK" /> của <ph name="URL" /></translation>
@@ -34,7 +37,6 @@
<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="1173894706177603556">Đổi tên</translation>
<translation id="1175364870820465910">&amp;In...</translation>
<translation id="1181037720776840403">Xóa</translation>
<translation id="1197088940767939838">Màu cam</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">Tên thiết bị của bạn</translation>
<translation id="124116460088058876">Ngôn ngữ khác</translation>
<translation id="1250759482327835220">Để thanh toán nhanh hơn vào lần tới, hãy lưu địa chỉ thanh toán, tên và thẻ vào Tài khoản Google của bạn.</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (được đồng bộ hóa)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">Các biến thể của dòng lệnh</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="1314614906530272393">Phiên đã chọn không tồn tại.</translation>
+<translation id="1320233736580025032">Prc1 (Phong bì)</translation>
+<translation id="132301787627749051">Tìm kiếm hình ảnh trong khay nhớ tạm</translation>
<translation id="1323433172918577554">Xem thêm</translation>
<translation id="132390688737681464">Lưu và điền địa chỉ</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:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">Địa chỉ nhận hàng</translation>
<translation id="1348198688976932919">Trang web bạn sắp truy cập chứa ứng dụng nguy hiểm</translation>
<translation id="1348779747280417563">Xác nhận tên</translation>
+<translation id="1357195169723583938">Người đã sử dụng thiết bị này gần đây và thời điểm sử dụng</translation>
+<translation id="1364822246244961190">Chính sách này đã bị chặn nên giá trị của chính sách sẽ bị bỏ qua.</translation>
<translation id="1374468813861204354">đề xuất</translation>
+<translation id="1374692235857187091">Index-4x6 (Bưu thiếp)</translation>
<translation id="1375198122581997741">Giới thiệu Phiên bản</translation>
<translation id="1376836354785490390">Ẩn bớt</translation>
<translation id="1377321085342047638">Số thẻ</translation>
<translation id="138218114945450791">Xanh lam nhạt</translation>
+<translation id="1382194467192730611">Thiết bị USB được quản trị viên của bạn cho phép</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> không gửi bất kỳ dữ liệu nào.</translation>
+<translation id="140316286225361634">Trang web <ph name="ORIGIN" /> đã yêu cầu phải áp dụng một
+ chính sách bảo mật cho tất cả các yêu cầu của trang đó, và chính sách này hiện cho rằng trang web đó
+ không an toàn.</translation>
<translation id="1405567553485452995">Xanh lục nhạt</translation>
<translation id="1407135791313364759">Mở tất cả</translation>
<translation id="1413809658975081374">Lỗi bảo mật</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">Có</translation>
<translation id="1430915738399379752">In</translation>
<translation id="1455413310270022028">Tẩy</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">Hiển thị thêm</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">Chọn địa chỉ giao hàng</translation>
+<translation id="1492194039220927094">Gửi thông báo đẩy khi có chính sách:</translation>
<translation id="1501859676467574491">Hiển thị các thẻ trong Tài khoản Google của bạn</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="1507202001669085618">&lt;p&gt;Bạn sẽ gặp lỗi này nếu đang sử dụng cổng Wi-Fi yêu cầu bạn đăng nhập để có thể vào mạng.&lt;/p&gt;
&lt;p&gt;Để khắc phục lỗi này, hãy nhấp vào &lt;strong&gt;Kết nối&lt;/strong&gt; trên trang mà bạn đang cố mở.&lt;/p&gt;</translation>
<translation id="1517433312004943670">Phải có số điện thoại</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">Ngày tạo</translation>
<translation id="1521655867290435174">Google Trang tính</translation>
<translation id="1527263332363067270">Đang chờ kết nối…</translation>
+<translation id="1529521330346880926">10x15 (Phong bì)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">Trang này cho biết</translation>
<translation id="153384715582417236">Hiện chưa có nội dung</translation>
<translation id="154408704832528245">Chọn địa chỉ giao hàng</translation>
<translation id="1549470594296187301">Bạn phải bật JavaScript để sử dụng tính năng này.</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">Nhập ngày hết hạn</translation>
<translation id="1581080074034554886">CVC</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="1618822247301510817">Hình ảnh bạn đã sao chép</translation>
<translation id="1620510694547887537">Máy ảnh</translation>
<translation id="1623104350909869708">Ngăn trang này tạo hộp thoại bổ sung</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">Kết thúc phiên</translation>
<translation id="1639239467298939599">Đang tải</translation>
<translation id="1640180200866533862">Chính sách người dùng</translation>
@@ -133,8 +150,10 @@
<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="168841957122794586">Chứng chỉ máy chủ chứa khóa mật mã yếu.</translation>
<translation id="1697532407822776718">Bạn đã hoàn tất!</translation>
+<translation id="1703835215927279855">Letter</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="1715874602234207">F</translation>
<translation id="1718029547804390981">Tài liệu quá lớn nên không thể chú thích được</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>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">Thử liên hệ với quản trị viên hệ thống.</translation>
<translation id="1740951997222943430">Nhập tháng hết hạn hợp lệ</translation>
<translation id="1743520634839655729">Để thanh toán nhanh hơn vào lần tới, hãy lưu địa chỉ thanh toán, tên và thẻ vào thiết bị này và Tài khoản Google của bạn.</translation>
+<translation id="1745880797583122200">Trình duyệt của bạn được quản lý</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>
@@ -152,8 +172,10 @@
<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="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">Tên chủ thẻ</translation>
<translation id="1821930232296380041">Yêu cầu hoặc tham số yêu cầu không hợp lệ</translation>
+<translation id="1822540298136254167">Các trang web bạn đã truy cập và thời lượng truy cập các trang web đó</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="1839551713262164453">Không xác thực được các giá trị của chính sách do xảy ra lỗi</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">Xóa dữ liệu lịch sử duyệt web của Chrome</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{và 1 ứng dụng khác}other{và # ứng dụng khác}}</translation>
<translation id="2003709556000175978">Đặt lại mật khẩu của bạn ngay bây giờ</translation>
+<translation id="20053308747750172">Máy chủ bạn định truy cập vào, <ph name="ORIGIN" />, đã yêu cầu phải áp dụng
+ một chính sách bảo mật cho tất cả các yêu cầu được gửi tới máy chủ đó. Tuy nhiên, máy chủ đó hiện đã
+ cung cấp một chính sách không hợp lệ, khiến cho trình duyệt
+ không hoàn tất được yêu cầu truy cập vào <ph name="SITE" /> của bạn.</translation>
<translation id="2025186561304664664">Proxy được đặt thành định cấu hình tự động.</translation>
<translation id="2030481566774242610">Ý của bạn là <ph name="LINK" />?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />Kiểm tra proxy và tường lửa<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">Khu vực hành chính</translation>
<translation id="2102134110707549001">Đề xuất mật khẩu mạnh…</translation>
<translation id="2108755909498034140">Khởi động lại máy tính của bạn</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">Thẻ</translation>
<translation id="2114841414352855701">Bỏ qua vì đã bị <ph name="POLICY_NAME" /> ghi đè.</translation>
<translation id="213826338245044447">Dấu trang di động</translation>
@@ -206,6 +233,7 @@
<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="2169984857010174799">Kaku2 (Phong bì)</translation>
<translation id="2181821976797666341">Chính sách</translation>
<translation id="2183608646556468874">Số điện thoại</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 địa chỉ}other{# địa chỉ}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">Số điện thoại</translation>
<translation id="2283340219607151381">Lưu và điền địa chỉ</translation>
<translation id="2292556288342944218">Quyền truy cập Internet của bạn bị chặn</translation>
+<translation id="2294558542833290837">Đường dẫn liên kết bạn mở ban đầu là không bình thường</translation>
+<translation id="2297722699537546652">B5 (Phong bì)</translation>
+<translation id="2310021320168182093">Chou2 (Phong bì)</translation>
<translation id="2316887270356262533">Bộ nhớ đệm còn chưa đầy 1 MB. Một số trang web có thể tải chậm hơn vào lần tới bạn truy cập.</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="2317583587496011522">Thẻ ghi nợ được chấp nhận.</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />, hết hạn vào <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">Cài đặt do quản trị viên kiểm soát</translation>
+<translation id="2346319942568447007">Hình ảnh bạn đã sao chép</translation>
<translation id="2349790679044093737">Phiên thực tế ảo đang hoạt động</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>
@@ -239,29 +271,37 @@
<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="2378238891085281592">Bạn đã chuyển sang chế độ riêng tư</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</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="2418081434543109369">Máy chủ bạn định truy cập vào, <ph name="ORIGIN" />, đã yêu cầu phải áp dụng
+ một chính sách bảo mật cho tất cả các yêu cầu được gửi tới máy chủ đó. Tuy nhiên, hiện máy chủ đó
+ không cung cấp được chính sách, điều này khiến cho trình duyệt không hoàn tất được
+ yêu cầu truy cập vào <ph name="SITE" /> của bạn.</translation>
<translation id="244665789865330679"><ph name="ENROLLMENT_DOMAIN" /> quản lý thiết bị và tài khoản của bạn. Điều này có nghĩa là quản trị viên có thể định cấu hình thiết bị và tài khoản của bạn từ xa.</translation>
<translation id="2463193859425327265">Thay đổi trang chủ</translation>
<translation id="2463739503403862330">Điền</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">Chọn cách giao hàng</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />Chạy Chẩn đoán mạng<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">Dịch trang này</translation>
<translation id="2479410451996844060">URL tìm kiếm hợp lệ.</translation>
<translation id="2482878487686419369">Thông báo</translation>
<translation id="248348093745724435">Chính sách về máy</translation>
+<translation id="2485387744899240041">Tên người dùng dành cho thiết bị và trình duyệt của bạn</translation>
<translation id="2491120439723279231">Chứng chỉ của máy chủ có lỗi.</translation>
+<translation id="2493640343870896922">Letter-Plus</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>
<translation id="2498091847651709837">Quét thẻ mới</translation>
<translation id="2501278716633472235">Quay lại</translation>
<translation id="2503184589641749290">Thẻ ghi nợ và thẻ trả trước được chấp nhận</translation>
<translation id="2515629240566999685">Kiểm tra tín hiệu trong khu vực của bạn</translation>
-<translation id="2516852381693169964">Tìm kiếm hình ảnh trên <ph name="SEARCH_ENGINE" /></translation>
<translation id="2523886232349826891">Chỉ lưu trên thiết bị này</translation>
<translation id="2524461107774643265">Thêm thông tin khác</translation>
<translation id="2536110899380797252">Thêm địa chỉ</translation>
@@ -273,6 +313,7 @@
<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="2618023639789766142">C10 (Phong bì)</translation>
<translation id="2625385379895617796">Đồng hồ của bạn chạy nhanh</translation>
<translation id="2634124572758952069">Không thể tìm thấy địa chỉ IP của máy chủ <ph name="HOST_NAME" />.</translation>
<translation id="2639739919103226564">Trạng thái:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">Đóng các tab hoặc ứng dụng khác</translation>
<translation id="267371737713284912">nhấn <ph name="MODIFIER_KEY_DESCRIPTION" /> để hoàn tác</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="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">Rời khỏi</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">Thẻ được chấp nhận</translation>
<translation id="2702801445560668637">Danh sách đọc</translation>
<translation id="2704283930420550640">Giá trị không khớp với định dạng.</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">Xóa các mục đã chọn</translation>
<translation id="277133753123645258">Phương thức giao hàng</translation>
<translation id="277499241957683684">Thiếu hồ sơ thiết bị</translation>
-<translation id="2781030394888168909">Xuất ở định dạng MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">Kết nối đã được đặt lại.</translation>
<translation id="2788784517760473862">Thẻ tín dụng được chấp nhận</translation>
@@ -311,8 +353,10 @@
<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="2847118875340931228">Mở cửa sổ ẩn danh</translation>
+<translation id="2850739647070081192">Invite (Phong bì)</translation>
<translation id="2851634818064021665">Bạn cần quyền để truy cập trang web này</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">Lưu thẻ?</translation>
<translation id="2903493209154104877">Địa chỉ</translation>
<translation id="290376772003165898">Trang này không được viết bằng <ph name="LANGUAGE" />?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">Phương thức giao hàng</translation>
<translation id="2928905813689894207">Ðịa chỉ thanh toán</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</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>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (Phong bì)</translation>
<translation id="3024663005179499861">Loại chính sách sai</translation>
<translation id="3037605927509011580">Ôi, hỏng! </translation>
<translation id="3041612393474885105">Thông tin Chứng chỉ</translation>
+<translation id="3060227939791841287">C9 (Phong bì)</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="3095940652251934233">Tuyên bố</translation>
<translation id="3096100844101284527">Thêm địa chỉ nhận hàng</translation>
<translation id="3105172416063519923">ID phần tử:</translation>
<translation id="3109728660330352905">Bạn không có quyền xem trang này.</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="PRINTER_NAME" /> trên <ph name="SERVER_NAME" /></translation>
<translation id="320323717674993345">Hủy thanh toán</translation>
<translation id="3207960819495026254">Đã đánh dấu trang</translation>
-<translation id="3209375525920864198">Vui lòng nhập tên phiên hợp lệ.</translation>
+<translation id="321912867715453276">Cảnh báo: Chính sách này hiện có nhiều nguồn nhưng các giá trị giống nhau.</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="3229041911291329567">Thông tin phiên bản về thiết bị và trình duyệt của bạn</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">Thêm tên trên thẻ</translation>
<translation id="3287510313208355388">Tải xuống khi trực tuyến</translation>
<translation id="3293642807462928945">Hãy tìm hiểu thêm về chính sách <ph name="POLICY_NAME" /></translation>
<translation id="3303855915957856445">Không tìm thấy kết quả tìm kiếm nào</translation>
-<translation id="3305707030755673451">Dữ liệu của bạn đã được mã hóa bằng cụm mật khẩu đồng bộ hóa của bạn vào <ph name="TIME" />. Nhập cụm mật khẩu đó để bắt đầu đồng bộ hóa.</translation>
<translation id="3320021301628644560">Thêm địa chỉ thanh toán</translation>
<translation id="3324983252691184275">Đỏ thẫm</translation>
<translation id="3338095232262050444">Bảo mật</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">&amp;Làm lại chỉnh sửa</translation>
<translation id="342781501876943858">Chromium khuyên bạn nên đặt lại mật khẩu của mình nếu đã sử dụng lại mật khẩu này trên các trang web khác.</translation>
<translation id="3431636764301398940">Lưu thẻ này vào thiết bị này</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</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="3447884698081792621">Hiển thị chứng chỉ (do <ph name="ISSUER" /> cấp)</translation>
<translation id="3452404311384756672">Khoảng thời gian tìm nạp:</translation>
+<translation id="3456231139987291353">Number-11 (Phong bì)</translation>
<translation id="3461824795358126837">Bút đánh dấu</translation>
<translation id="3462200631372590220">Ẩn chi tiết</translation>
<translation id="3467763166455606212">Yêu cầu tên chủ thẻ</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">Thẻ tín dụng và thẻ trả trước được chấp nhận.</translation>
<translation id="3582930987043644930">Thêm tên</translation>
<translation id="3583757800736429874">&amp;Làm lại di chuyển</translation>
+<translation id="35866233670761917">Nội dung của trang web mà bạn truy cập sẽ không hiển thị với quản trị viên của bạn</translation>
<translation id="3586931643579894722">Ẩn chi tiết</translation>
+<translation id="3592413004129370115">Italian (Phong bì)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />, <ph name="DOMAIN" />, <ph name="TIME" /></translation>
<translation id="3614103345592970299">Kích thước 2</translation>
<translation id="3615877443314183785">Nhập ngày hết hạn hợp lệ</translation>
<translation id="36224234498066874">Xóa DL duyệt web</translation>
<translation id="362276910939193118">Hiển thị Toàn bộ Lịch sử</translation>
-<translation id="3623476034248543066">Hiển thị giá trị</translation>
<translation id="3630155396527302611">Nếu chương trình đã được liệt kê là chương trình được phép truy cập mạng, hãy thử
xóa chương trình này khỏi danh sách rồi thêm lại.</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">Xác thực thành công</translation>
<translation id="3655670868607891010">Nếu bạn thường xuyên thấy thông báo này, hãy thử các <ph name="HELP_LINK" /> sau.</translation>
<translation id="3658742229777143148">Bản sửa đổi</translation>
<translation id="366077651725703012">Cập nhật thẻ tín dụng</translation>
<translation id="3676592649209844519">ID thiết bị:</translation>
+<translation id="3677008721441257057">Ý bạn là &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">Không thể ký yêu cầu</translation>
<translation id="3678529606614285348">Mở trang trong cửa sổ Ẩn danh mới (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">Báo cáo sự cố được ghi lại vào <ph name="CRASH_TIME" />, được tải lên vào <ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">Mạng mà bạn đang sử dụng có thể yêu cầu bạn phải truy cập trang đăng nhập của mạng đó.</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="3709599264800900598">Văn bản bạn đã sao chép</translation>
<translation id="3712624925041724820">Giấy phép không đủ</translation>
<translation id="3714780639079136834">Bật dữ liệu di dộng hoặc Wi-Fi</translation>
<translation id="3715597595485130451">Kết nối Wi-Fi</translation>
<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="372429172604983730">Các ứng dụng có thể gây ra lỗi này gồm có phần mềm diệt vi-rút, tường lửa và lọc web hoặc phần mềm proxy.</translation>
+<translation id="373042150751172459">B4 (Phong bì)</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="3745099705178523657">Sau khi bạn xác nhận, thông tin chi tiết thẻ trong Tài khoản Google của bạn sẽ được chia sẻ với trang web này.</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>
@@ -470,10 +525,12 @@
<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="3789155188480882154">Kích thước 16</translation>
+<translation id="3797522431967816232">Prc3 (Phong bì)</translation>
<translation id="3807873520724684969">Đã chặn nội dung độc hại.</translation>
<translation id="3810973564298564668">Quản lý</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="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> đã cài đặt các tiện ích để bổ sung thêm chức năng. Các tiện ích có quyền truy cập vào một số dữ liệu của bạn.</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>
@@ -481,6 +538,7 @@
<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="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">Luôn hỏi trên trang web này</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>
@@ -491,11 +549,13 @@
<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="3984550557525787191">Tên phiên này đã tồn tại.</translation>
<translation id="3987940399970879459">Dưới 1 MB</translation>
+<translation id="4008849406247176967">Cảnh báo: Chính sách này hiện có nhiều nguồn và các giá trị nguồn xung đột với nhau!</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="4030383055268325496">&amp;Hoàn tác thêm</translation>
+<translation id="4032320456957708163"><ph name="ENROLLMENT_DOMAIN" /> quản lý trình duyệt của bạn</translation>
<translation id="4058922952496707368">Khóa "<ph name="SUBKEY" />": <ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Phong bì)</translation>
<translation id="4067947977115446013">Thêm địa chỉ hợp lệ</translation>
<translation id="4072486802667267160">Đã xảy ra lỗi khi xử lý đơn đặt hàng của bạn. Vui lòng thử lại.</translation>
<translation id="4075732493274867456">Ứng dụng và máy chủ không hỗ trợ bộ mã hóa hoặc phiên bản giao thức SSL thông thường.</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">Tím</translation>
<translation id="4165986682804962316">Cài đặt trang web</translation>
<translation id="4171400957073367226">Chữ ký xác minh không hợp lệ</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{<ph name="ITEM_COUNT" /> mục khác}other{<ph name="ITEM_COUNT" /> mục khác}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></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="4215751373031079683">7x9 (Phong bì)</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="4221630205957821124">&lt;h4&gt;Bước 1: Đăng nhập vào cổng&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">Đặt lại mật khẩu</translation>
<translation id="4280429058323657511">, hết hạn <ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{Đã lưu thẻ này vào Tài khoản Google của bạn}other{Đã lưu các thẻ này vào Tài khoản Google của bạn}}</translation>
+<translation id="42981349822642051">Mở rộng</translation>
+<translation id="4302965934281694568">Chou3 (Phong bì)</translation>
<translation id="4305817255990598646">Chuyển</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">Chặn (mặc định)</translation>
+<translation id="4318566738941496689">Tên thiết bị và địa chỉ mạng của bạn</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="4340982228985273705">Máy tính này không được coi là máy tính do doanh nghiệp quản lý, vì vậy, chính sách này chỉ có thể tự động cài đặt các tiện ích được lưu trữ trên Cửa hàng Chrome trực tuyến. URL cập nhật Cửa hàng Chrome trực tuyến là "<ph name="CWS_UPDATE_URL" />".</translation>
<translation id="4346197816712207223">Thẻ tín dụng được chấp nhận</translation>
+<translation id="4346833872170306413">Roc-16K</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="4358461427845829800">Quản lý phương thức thanh toán...</translation>
+<translation id="4367563149485757821">Number-12 (Phong bì)</translation>
+<translation id="4372516964750095882">Fanfold-Us</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="4378154925671717803">Điện thoại</translation>
<translation id="4406896451731180161">kết quả tìm kiếm</translation>
-<translation id="4406972042435603828">Quản trị viên của bạn đã cài đặt các tiện ích có nhiều tính năng nâng cao.</translation>
<translation id="4408413947728134509">Cookie <ph name="NUM_COOKIES" /></translation>
<translation id="4415426530740016218">Địa chỉ nhận hàng</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="443121186588148776">Cổng nối tiếp</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="4434045419905280838">Cửa sổ bật lên và liên kết chuyển hướng</translation>
+<translation id="4435702339979719576">Bưu thiế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="445100540951337728">Thẻ ghi nợ được chấp nhận</translation>
+<translation id="4466881336512663640">Các thay đổi đối với biểu mẫu sẽ bị mất. Bạn có chắc chắn muốn tiếp tục không?</translation>
<translation id="4482953324121162758">Trang web này sẽ không được dịch.</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">URL không hợp lệ. Phải là URL chứa tên giao thức chuẩn, chẳng hạn như: http://example.com hoặc https://example.com.</translation>
+<translation id="4503882053543859973">Architecture-D</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="4510487217173779431">Chou4 (Phong bì)</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="4517607026994743406">Comm-10 (Phong bì)</translation>
<translation id="4522570452068850558">Chi tiết</translation>
<translation id="4524805452350978254">Quản lý thẻ</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">Thử tắt tiện ích.</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">Giao hàng</translation>
+<translation id="4579056131138995126">Personal (Phong bì)</translation>
<translation id="4582204425268416675">Xóa thẻ</translation>
<translation id="4587425331216688090">Xóa địa chỉ khỏi Chrome?</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="4597348597567598915">Kích thước 8</translation>
+<translation id="4600854749408232102">C6/C5 (Phong bì)</translation>
<translation id="4646534391647090355">Chuyển đến đó ngay</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="467809019005607715">Google Trang trình bày</translation>
<translation id="4690462567478992370">Dừng sử dụng chứng chỉ không hợp lệ</translation>
+<translation id="4691835149146451662">Architecture-A (Phong bì)</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="471880041731876836">Bạn không có quyền để truy cập trang web này</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />Chạy Chẩn đoán mạng của Windows<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">Tải lại chính sách</translation>
<translation id="4728558894243024398">Nền tảng</translation>
+<translation id="4731967714531604179">Prc2 (Phong bì)</translation>
<translation id="4736825316280949806">Khởi động lại Chromium</translation>
<translation id="473775607612524610">Cập nhật</translation>
<translation id="4738601419177586157">Đề xuất tìm kiếm <ph name="TEXT" /></translation>
<translation id="4742407542027196863">Quản lý mật khẩu…</translation>
<translation id="4744603770635761495">Đường dẫn thực thi</translation>
+<translation id="4746351372139058112">Tin nhắn</translation>
<translation id="4750917950439032686">Thông tin của bạn (ví dụ: mật khẩu hoặc số thẻ tín dụng) sẽ được bảo mật khi được gửi tới trang web này.</translation>
<translation id="4756388243121344051">&amp;Lịch sử</translation>
<translation id="4758311279753947758">Thêm thông tin liên hệ</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478">Trang web tại <ph name="URL" /> có thể tạm thời không hoạt động hay được chuyển vĩnh viễn sang địa chỉ web mới.</translation>
<translation id="4771973620359291008">Xảy ra lỗi chưa biết.</translation>
<translation id="4785689107224900852">Chuyển sang tab này</translation>
-<translation id="4792143361752574037">Đã xảy ra sự cố khi truy cập vào các tệp phiên. Tính năng lưu vào ổ đĩa hiện bị vô hiệu hóa. Vui lòng tải lại trang để thử lại.</translation>
<translation id="4798078619018708837">Hãy nhập ngày hết hạn và số CVC của <ph name="CREDIT_CARD" /> để cập nhật thông tin chi tiết thẻ của bạn. Sau khi bạn xác nhận, thông tin chi tiết thẻ trong Tài khoản Google của bạn sẽ được chia sẻ với trang web này.</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="480334179571489655">Lỗi chính sách nguồn gốc</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 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.</translation>
<translation id="4813512666221746211">Lỗi mạng</translation>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">Không tìm thấy kết quả nào</translation>
<translation id="4950898438188848926">Nút chuyển đổi tab, nhấn phím Enter để chuyển sang tab đang mở, <ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">Tác vụ</translation>
-<translation id="495832697253704892">Báo cáo tiện ích</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">Mở rộng danh sách</translation>
<translation id="4974590756084640048">Bật lại cảnh báo</translation>
+<translation id="4984339528288761049">Prc5 (Phong bì)</translation>
<translation id="4989163558385430922">Xem tất cả</translation>
<translation id="4989809363548539747">Plugin này không được hỗ trợ</translation>
-<translation id="4996230189582812866">Báo cáo</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="5014174725590676422">Màn hình chạy đầu tiên của Trợ lý Google trong Chrome đã được hiển thị</translation>
<translation id="5015510746216210676">Tên máy:</translation>
+<translation id="5017554619425969104">Văn bản bạn đã sao chép</translation>
<translation id="5018422839182700155">Không thể mở trang này</translation>
<translation id="5019198164206649151">Không thể lưu trữ do chương trình phụ trợ ở trạng thái xấu</translation>
<translation id="5023310440958281426">Kiểm tra chính sách của quản trị viên của bạn</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">Ngữ cảnh cục bộ <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">Cho phép</translation>
<translation id="5040262127954254034">Bảo mật</translation>
+<translation id="5043480802608081735">Liên kết bạn đã sao chép</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="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />Kiểm tra địa chỉ proxy<ph name="END_LINK" /></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">Tỉnh</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</translation>
+<translation id="5097099694988056070">Số liệu thống kê về thiết bị, chẳng hạn như mức sử dụng CPU/RAM</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465"><ph name="ENROLLMENT_DOMAIN" /> quản lý thiết bị của bạn và <ph name="ACCOUNT_DOMAIN" /> quản lý tài khoản của bạn. Điều này có nghĩa là quản trị viên có thể định cấu hình thiết bị và tài khoản của bạn từ xa.</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 bit)</translation>
-<translation id="5128122789703661928">Không thể xóa phiên do tên phiên không hợp lệ.</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">Quản lý địa chỉ...</translation>
+<translation id="5138227688689900538">Ẩn bớt</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>
<translation id="5145883236150621069">Mã lỗi có trong phản hồi chính sách</translation>
+<translation id="515292512908731282">C4 (Phong bì)</translation>
<translation id="5159010409087891077">Mở trang trong cửa sổ Ẩn danh mới (⇧⌘N)</translation>
<translation id="516920405563544094">Hãy nhập số CVC của <ph name="CREDIT_CARD" />. Sau khi bạn xác nhận, thông tin chi tiết thẻ trong Tài khoản Google của bạn sẽ được chia sẻ với trang web này.</translation>
<translation id="5169827969064885044">Bạn có thể mất quyền truy cập vào tài khoản của tổ chức mình hoặc bị đánh cắp danh tính. Chrome khuyên bạn nên thay đổi mật khẩu ngay bây giờ.</translation>
<translation id="5171045022955879922">Tìm kiếm hoặc nhập URL</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">Máy</translation>
<translation id="5179510805599951267">Không ở <ph name="ORIGINAL_LANGUAGE" />? Báo cáo lỗi này</translation>
<translation id="5190835502935405962">Thanh Dấu trang</translation>
-<translation id="5200263511887412697">báo cáo danh sách những người dùng thiết bị đã đăng nhập gần đây</translation>
+<translation id="519422657042045905">Không có chú thích</translation>
<translation id="5201306358585911203">Một trang được nhúng trên trang này cho biết</translation>
<translation id="5205222826937269299">Cần có tên</translation>
<translation id="5215116848420601511">Địa chỉ và phương thức thanh toán lưu trong Google Pay</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">Cần có email</translation>
<translation id="5230733896359313003">Địa chỉ giao hàng</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">"Kết nối với mạng"</translation>
<translation id="5251803541071282808">Đám mây</translation>
+<translation id="5252000469029418751">C7 (Phong bì)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">Địa chỉ mạng</translation>
<translation id="5285570108065881030">Hiển thị tất cả mật khẩu đã lưu</translation>
<translation id="5287240709317226393">Hiển thị cookie</translation>
<translation id="5288108484102287882">Xuất hiện cảnh báo khi xác thực các giá trị của chính sách</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />, <ph name="MATCH_POSITION" /> / <ph name="NUM_MATCHES" /></translation>
<translation id="5324080437450482387">Chọn thông tin liên hệ</translation>
<translation id="5327248766486351172">Tên</translation>
+<translation id="5329858041417644019">Trình duyệt của bạn không được quản lý</translation>
<translation id="5332219387342487447">Phương thức giao hàng</translation>
+<translation id="5334013548165032829">Nhật ký hệ thống chi tiết</translation>
<translation id="5344579389779391559">Trang này có thể tìm cách tính phí bạn</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>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">"Đồng hồ của bạn chạy chậm" hoặc "Đồng hồ của bạn chạy nhanh" hay "&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;"</translation>
<translation id="5384855140246857529">Để sử dụng thẻ trên tất cả thiết bị, hãy đăng nhập và bật tính năng đồng bộ hóa.</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="538659543871111977">A4-Tab</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>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">Không hợp lệ</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">&amp;Làm lại chỉnh sửa</translation>
+<translation id="5478437291406423475">B6/C4 (Phong bì)</translation>
<translation id="5481076368049295676">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="54817484435770891">Thêm địa chỉ hợp lệ</translation>
<translation id="5490432419156082418">Địa chỉ và các tùy chọn khác</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
Hãy thử liên hệ với quản trị viên hệ thống của bạn.</translation>
<translation id="549333378215107354">Kích thước 3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">Dấu trang được quản lý</translation>
<translation id="5510766032865166053">Tệp này có thể đã bị di chuyển hoặc xóa.</translation>
<translation id="5523118979700054094">Tên chính sách</translation>
<translation id="552553974213252141">Văn bản đã được trích xuất chính xác chưa?</translation>
+<translation id="553484882784876924">Prc6 (Phong bì)</translation>
<translation id="5540224163453853">Không thể tìm thấy bài viết đã yêu cầu.</translation>
<translation id="5541546772353173584">Thêm email</translation>
<translation id="5545756402275714221">Tin bài dành cho bạn</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">Chỉnh sửa địa chỉ</translation>
<translation id="5598944008576757369">Chọn phương thức thanh toán</translation>
<translation id="560412284261940334">Không hỗ trợ quản lý</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</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>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> đã chuyển hướng bạn quá nhiều lần.</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="5632627355679805402">Dữ liệu của bạn đã được mã hóa bằng <ph name="BEGIN_LINK" />mật khẩu Google<ph name="END_LINK" /> kể từ <ph name="TIME" />. Hãy nhập mật khẩu đó để bắt đầu đồng bộ hóa.</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="563324245173044180">Đã chặn nội dung lừa đảo.</translation>
<translation id="5659593005791499971">Email</translation>
+<translation id="5663614846592581799">9x11 (Phong bì)</translation>
+<translation id="5663955426505430495">Quản trị viên của thiết bị này đã cài đặt các tiện ích để bổ sung thêm chức năng. Các tiện ích có quyền truy cập vào một số dữ liệu của bạn.</translation>
<translation id="5675650730144413517">Trang này hiện không hoạt động</translation>
+<translation id="5684874026226664614">Rất tiếc. Không thể dịch trang này.</translation>
<translation id="5685654322157854305">Thêm địa chỉ giao hàng</translation>
<translation id="5689199277474810259">Xuất sang định dạng JSON</translation>
<translation id="5689516760719285838">Vị trí</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">Nhận dạng trang web này chưa được xác minh.</translation>
<translation id="5719499550583120431">Thẻ trả trước được chấp nhận.</translation>
<translation id="5720705177508910913">Người dùng hiện tại</translation>
+<translation id="5728056243719941842">C5 (Phong bì)</translation>
<translation id="5730040223043577876">Chrome khuyên bạn nên đặt lại mật khẩu của mình nếu đã sử dụng lại mật khẩu này trên các trang web khác.</translation>
<translation id="5732392974455271431">Cha mẹ của bạn có thể bỏ chặn trang web cho bạn</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{Lưu thẻ vào Tài khoản Google}other{Lưu các thẻ vào Tài khoản Google}}</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="5770114862687765385">Tệp dường như bị lỗi. Hãy nhấp vào nút 'Đặt lại' để đặt lại phiên làm việc này.</translation>
<translation id="5778550464785688721">Điều khiển toàn bộ thiết bị MIDI</translation>
<translation id="578305955206182703">Hổ phách</translation>
<translation id="57838592816432529">Tắt tiếng</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>
+<translation id="5798290721819630480">Hủy thay đổi?</translation>
<translation id="5798683403665926540">Thay đổi trang chủ trong mục cài đặt của Chrome</translation>
<translation id="5803412860119678065">Bạn có muốn điền <ph name="CARD_DETAIL" /> của mình không?</translation>
<translation id="5804241973901381774">Quyền</translation>
<translation id="5810442152076338065">Kết nối của bạn tới <ph name="DOMAIN" /> được mã hóa bằng bộ số 0 đã lỗi thời.</translation>
<translation id="5813119285467412249">&amp;Làm lại thêm</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="5860033963881614850">Tắt</translation>
<translation id="5863847714970149516">Trang phía trước có thể tìm cách tính phí bạn</translation>
<translation id="5866257070973731571">Thêm số điện thoại</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="5887400589839399685">Đã lưu thẻ</translation>
-<translation id="5893718151540690985">báo cáo danh sách các giao diện mạng kèm thông tin về loại giao diện và địa chỉ phần cứng</translation>
<translation id="5893752035575986141">Thẻ tín dụng được chấp nhận.</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="5916664084637901428">Bật</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">Bạn có muốn lưu thẻ vào Tài khoản Google không?</translation>
<translation id="5922853866070715753">Sắp hoàn tất</translation>
<translation id="5932224571077948991">Trang web hiển thị quảng cáo xâm nhập hoặc quảng cáo gây hiểu nhầm</translation>
-<translation id="5939518447894949180">Đặt lại</translation>
<translation id="5946937721014915347">Đang mở <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">Không thể đăng ký bằng tài khoản người dùng thông thường (có sẵn giấy phép theo gói).</translation>
<translation id="5967592137238574583">Chỉnh sửa thông tin liên hệ</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">Thu nhỏ</translation>
<translation id="5977489021191000276">Thiết bị của bạn không do quản trị viên quản lý.</translation>
<translation id="5977976211062815271">Trên thiết bị này</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">Không thể mở ứng dụng thanh toán</translation>
<translation id="5989320800837274978">Cả máy chủ proxy cố định và URL tập lệnh .pac đều chưa được chỉ định.</translation>
<translation id="5990559369517809815">Tiện ích đã chặn yêu cầu tới máy chủ.</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">báo cáo thống kê phần cứng chẳng hạn như mức sử dụng CPU/RAM</translation>
<translation id="6034000775414344507">Xám nhạt</translation>
+<translation id="6034283069659657473">10x14 (Phong bì)</translation>
<translation id="6039846035001940113">Nếu sự cố vẫn tiếp diễn, hãy liên hệ với chủ sở hữu trang web.</translation>
<translation id="6040143037577758943">Đóng</translation>
<translation id="6044573915096792553">Kích thước 12</translation>
@@ -812,10 +924,10 @@
<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="6058977677006700226">Bạn muốn sử dụng thẻ trên tất cả thiết bị?</translation>
<translation id="6059925163896151826">Thiết bị USB</translation>
-<translation id="6071091556643036997">Loại chính sách là không hợp lệ.</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="6094273045989040137">Chú thích</translation>
<translation id="610911394827799129">Tài khoản Google của bạn có thể có các dạng lịch sử duyệt web khác tại <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="6132597952260690497">Thông tin về các tiện ích và plugin đã cài đặt</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>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">Bộ nhớ đệm còn chưa đầy <ph name="SIZE" />. Một số trang web có thể tải chậm hơn vào lần tới bạn truy cập.</translation>
<translation id="6337534724793800597">Lọc chính sách theo tên</translation>
<translation id="6358450015545214790">Những phần này có ý nghĩa gì?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">Nếu tiếp tục, bạn có thể bị tính phí.</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 đề xuất khác}other{# đề xuất khác}}</translation>
<translation id="6387754724289022810">Để thanh toán nhanh hơn vào lần tiếp theo, hãy lưu địa chỉ thanh toán và thẻ vào Tài khoản Google của bạn và thiết bị này.</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">Chỉnh sửa dấu trang</translation>
+<translation id="6406765186087300643">C0 (Phong bì)</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="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="6434309073475700221">Hủy</translation>
+<translation id="6446163441502663861">Kahu (Phong bì)</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>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">Khởi động lại Chrome</translation>
<translation id="6529602333819889595">&amp;Làm lại xóa</translation>
<translation id="6534179046333460208">Đề xuất Web trong cuộc sống</translation>
+<translation id="6556866813142980365">Làm lại</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="6578796323535178455">C2 (Phong bì)</translation>
<translation id="6579990219486187401">Hồng nhạt</translation>
+<translation id="6583674473685352014">B6 (Phong bì)</translation>
+<translation id="6587923378399804057">Liên kết bạn đã sao chép</translation>
+<translation id="6591833882275308647"><ph name="DEVICE_TYPE" /> của bạn không được quản lý</translation>
<translation id="6596325263575161958">Tùy chọn mã hóa</translation>
<translation id="6604181099783169992">Cảm biến chuyển động hoặc ánh sáng</translation>
+<translation id="6609880536175561541">Prc7 (Phong bì)</translation>
<translation id="6624427990725312378">Thông tin liên hệ</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>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">Chính sách này không được chấp thuận.</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{Không có trang web nào}=1{Từ 1 trang web (bạn sẽ không bị đăng xuất khỏi Tài khoản Google của mình)}other{Từ # trang web (bạn sẽ không bị đăng xuất khỏi Tài khoản Google của mình)}}</translation>
<translation id="6657585470893396449">Mật khẩu</translation>
+<translation id="6670613747977017428">Quay lại trang an toàn.</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>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">Mã đăng ký:</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="6723740634201835758">Trong Tài khoản Google của bạn</translation>
+<translation id="6738516213925468394">Dữ liệu của bạn đã được mã hóa bằng <ph name="BEGIN_LINK" />cụm mật khẩu đồng bộ hóa<ph name="END_LINK" /> vào <ph name="TIME" />. Hãy nhập cụm mật khẩu đó để bắt đầu đồng bộ hóa.</translation>
<translation id="674375294223700098">Lỗi chứng chỉ máy chủ không xác định.</translation>
<translation id="6744009308914054259">Trong khi chờ kết nối, bạn có thể chuyển đến phần Tài nguyên đã tải xuống để đọc các bài viết ngoại tuyến.</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>
+<translation id="6768213884286397650">Hagaki (Bưu thiếp)</translation>
<translation id="6778737459546443941">Cha mẹ của bạn chưa phê duyệt trang web</translation>
<translation id="67862343314499040">Tím vi-ô-lét</translation>
+<translation id="6786747875388722282">Tiện ích</translation>
<translation id="679355240208270552">Đã bỏ qua vì chính sách đã tắt tìm kiếm mặc định.</translation>
<translation id="681021252041861472">Trường bắt buộc</translation>
<translation id="6810899417690483278">ID tùy chỉnh</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">Thiết bị</translation>
<translation id="6970216967273061347">Quận</translation>
<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="6973932557599545801">Rất tiếc, tôi không thể trợ giúp được nữa. Bạn vui lòng tự thực hiện việc này.</translation>
<translation id="6979158407327259162">Google Drive</translation>
<translation id="6979440798594660689">Tắt tiếng (mặc định)</translation>
<translation id="6984479912851154518">Đang rời khỏi chế độ riêng tư để thanh toán qua một ứng dụng bên ngoài. Bạn có muốn tiếp tục không?</translation>
<translation id="6989763994942163495">Hiển thị cài đặt nâng cao...</translation>
+<translation id="6993898126790112050">6x9 (Phong bì)</translation>
<translation id="6996312675313362352">Luôn dịch <ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">China UnionPay</translation>
<translation id="7016992613359344582">Các khoản phí này có thể là khoản thu một lần hoặc định kỳ và có thể không rõ ràng.</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">Ẩn</translation>
<translation id="7108819624672055576">Được một tiện ích cho phép</translation>
<translation id="7111012039238467737">(Hợp lệ)</translation>
+<translation id="7118618213916969306">Tìm kiếm URL trong khay nhớ tạm, <ph name="SHORT_URL" /></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="7135130955892390533">Hiển thị trạng thái</translation>
<translation id="7138472120740807366">Phương thức phân phối</translation>
<translation id="7139724024395191329">Tiểu vương quốc Ả rập</translation>
+<translation id="7152423860607593928">Number-14 (Phong bì)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">Tím oải hương</translation>
-<translation id="7158980942472052083">URL không hợp lệ. Phải là một URL có lược đồ chuẩn.</translation>
<translation id="717330890047184534">ID Gaia:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">Máy chủ bạn định truy cập vào, <ph name="ORIGIN" />, đã yêu cầu phải áp dụng
+ một chính sách bảo mật cho tất cả các yêu cầu được gửi tới máy chủ đó. Tuy nhiên, thay vì
+ cung cấp một chính sách thì máy chủ đó đã chuyển hướng trình duyệt tới một nơi khác, điều này khiến cho
+ trình duyệt không hoàn tất được yêu cầu truy cập vào <ph name="SITE" /> của bạn.</translation>
<translation id="7179323680825933600">Lưu và điền phương thức thanh toán</translation>
<translation id="7180611975245234373">Làm mới</translation>
<translation id="7182878459783632708">Không có chính sách nào được đặt</translation>
<translation id="7186367841673660872">Trang này đã được dịch từ<ph name="ORIGINAL_LANGUAGE" />sang<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">Giải phóng <ph name="SIZE" />. Một số trang web có thể tải chậm hơn trong lần tiếp theo bạn truy cập.</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">Quản trị viên của bạn có thể xem:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> không tuân thủ các tiêu chuẩn bảo mật.</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /> về sự cố này.</translation>
<translation id="7219179957768738017">Kết nối sử dụng <ph name="SSL_VERSION" />.</translation>
<translation id="7220786058474068424">Đang xử lý</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></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="724766306220616965">Cảnh báo, xung đột</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="7251437084390964440">Cấu hình mạng này không tuân thủ tiêu chuẩn ONC. Một số phần của cấu hình có thể không nhập được.
Thông tin chi tiết bổ sung:
@@ -982,11 +1120,14 @@ Thông tin chi tiết bổ sung:
<translation id="7300012071106347854">Xanh thẩm</translation>
<translation id="7302712225291570345">"<ph name="TEXT" />"</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="7313965965371928911">Cảnh báo <ph name="BEGIN_LINK" />Duyệt web an toàn<ph name="END_LINK" /></translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">Trợ giúp kết nối</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="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">Dòng Lệnh</translation>
-<translation id="7365061714576910172">Xuất ở định dạng Linux</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>
@@ -994,6 +1135,7 @@ Thông tin chi tiết bổ sung:
<translation id="7381288752349550461">Ghi đè phiên được quản lý</translation>
<translation id="7390545607259442187">Xác nhận thẻ</translation>
<translation id="7400418766976504921">URL</translation>
+<translation id="7403591733719184120"><ph name="DEVICE_NAME" /> của bạn được quản lý</translation>
<translation id="7407424307057130981">&lt;p&gt;Bạn sẽ thấy lỗi này nếu bạn có phần mềm Superfish trên máy tính chạy Windows.&lt;/p&gt;
&lt;p&gt;Hãy làm theo các bước sau để tạm thời tắt phần mềm này nhằm giúp bạn có thể truy cập vào web. Bạn cần phải có đặc quyền của quản trị viên.&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@ Thông tin chi tiết bổ sung:
&lt;li&gt;Nhấp vào &lt;strong&gt;Apply&lt;/strong&gt; (Áp dụng), sau đó nhấp vào &lt;strong&gt;OK&lt;/strong&gt;
&lt;li&gt;Truy cập vào &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Trung tâm trợ giúp Chrome&lt;/a&gt; để tìm hiểu cách xóa vĩnh viễn phần mềm này khỏi máy tính của bạn
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">Quản lý <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">Quản lý mật khẩu…</translation>
<translation id="7419106976560586862">Đường dẫn cấu hình</translation>
<translation id="7437289804838430631">Thêm thông tin liên hệ</translation>
@@ -1013,22 +1155,24 @@ Thông tin chi tiết bổ sung:
<translation id="7442725080345379071">Cam nhạt</translation>
<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="7449109375006139765">gửi nhật ký hệ thống đến máy chủ quản lý</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="7460618730930299168">Màn hình khác với nội dung bạn đã chọn. Bạn có muốn tiếp tục không?</translation>
<translation id="7473891865547856676">Không, cảm ơn</translation>
-<translation id="7475525192983021547">báo cáo khoảng thời gian khi người dùng sử dụng thiết bị</translation>
<translation id="7481312909269577407">Chuyển tiếp</translation>
<translation id="7485870689360869515">Không tìm thấy dữ liệu.</translation>
+<translation id="7498234416455752244">Tiếp tục chỉnh sửa</translation>
<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="7508870219247277067">Xanh quả bơ</translation>
<translation id="7511955381719512146">Wi-Fi mà bạn đang sử dụng có thể yêu cầu bạn phải truy cập <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</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="7520302887438682816">C8 (Phong bì)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">Kết nối của bạn tới trang web này không ở chế độ riêng tư</translation>
+<translation id="7535087603100972091">Giá trị</translation>
<translation id="7537536606612762813">Bắt buộc</translation>
+<translation id="7538364083937897561">A2 (Phong bì)</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>
@@ -1037,8 +1181,8 @@ Thông tin chi tiết bổ sung:
<translation id="7552846755917812628">Thử các mẹo sau:</translation>
<translation id="7554791636758816595">Tab mới</translation>
<translation id="7564049878696755256">Bạn có thể mất quyền truy cập vào tài khoản <ph name="ORG_NAME" /> của mình hoặc bị đánh cắp danh tính. Chrome khuyên bạn nên thay đổi mật khẩu ngay bây giờ.</translation>
-<translation id="7566125604157659769">Văn bản bạn đã sao chép</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="7568105740864181217">Một công ty, trường học hoặc tổ chức khác quản lý trình duyệt này. Quản trị viên có thể thay đổi quy trình thiết lập trình duyệt của bạn từ xa. Hoạt động trên thiết bị này cũng có thể được quản lý bên ngoài Chrome. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></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>
@@ -1049,6 +1193,7 @@ Thông tin chi tiết bổ sung:
<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="7633909222644580952">Báo cáo sự cố và dữ liệu hiệu suất</translation>
<translation id="7637571805876720304">Bạn muốn xóa thẻ tín dụng khỏi Chromium?</translation>
<translation id="7639968568612851608">Xám đen</translation>
<translation id="765676359832457558">Ẩn cài đặt nâng cao...</translation>
@@ -1058,9 +1203,11 @@ Thông tin chi tiết bổ sung:
<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="7676643023259824263">Tìm kiếm văn bản trong khay nhớ tạm, <ph name="TEXT" /></translation>
<translation id="7681101578153515023">Thay đổi công cụ tìm kiếm</translation>
<translation id="7682287625158474539">Địa chỉ gửi hàng</translation>
<translation id="7687186412095877299">Điền vào biểu mẫu thanh toán bằng phương thức thanh toán đã lưu</translation>
+<translation id="7697066736081121494">Prc8 (Phong bì)</translation>
<translation id="769721561045429135">Bạn hiện có các thẻ chỉ dùng được trên thiết bị này. Nhấp vào Tiếp tục để xem lại các thẻ.</translation>
<translation id="7699293099605015246">Không có bài viết nào ngay lúc này</translation>
<translation id="7701040980221191251">Không có</translation>
@@ -1072,11 +1219,13 @@ Thông tin chi tiết bổ sung:
<translation id="774634243536837715">Đã chặn nội dung nguy hiểm.</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="7757555340166475417">Dai-Pa-Kai</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>
<translation id="7759163816903619567">Miền hiển thị:</translation>
<translation id="7761701407923456692">Chứng chỉ của máy chủ không phù hợp với URL.</translation>
<translation id="7763386264682878361">Trình phân tích cú pháp tệp kê khai thanh toán</translation>
<translation id="7764225426217299476">Thêm địa chỉ</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">Quận</translation>
<translation id="7791543448312431591">Thêm</translation>
<translation id="7793809570500803535">Trang web tại <ph name="SITE" /> có thể tạm thời không hoạt động hay được chuyển vĩnh viễn sang địa chỉ web mới.</translation>
@@ -1088,8 +1237,8 @@ Thông tin chi tiết bổ sung:
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">Xóa đề xuất biểu mẫu khỏi Chrome?</translation>
<translation id="7815407501681723534">Đã tìm thấy <ph name="NUMBER_OF_RESULTS" /> <ph name="SEARCH_RESULTS" /> cho '<ph name="SEARCH_STRING" />'</translation>
-<translation id="7818867226424560206">Quản lý chính sách</translation>
<translation id="782886543891417279">Wi-Fi mà bạn đang sử dụng (<ph name="WIFI_NAME" />) có thể yêu cầu bạn phải truy cập trang đăng nhập của mạng đó.</translation>
+<translation id="7836231406687464395">Postfix (Phong bì)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{Không có}=1{1 ứng dụng (<ph name="EXAMPLE_APP_1" />)}=2{2 ứng dụng (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />)}other{# ứng dụng (<ph name="EXAMPLE_APP_1" />, <ph name="EXAMPLE_APP_2" />, <ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">Tuy nhiên, bạn không ẩn. Việc chuyển sang chế độ ẩn danh sẽ không ẩn thao tác duyệt của bạn với chủ lao động, nhà cung cấp dịch vụ internet hoặc các trang web bạn truy cập.</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@ Thông tin chi tiết bổ sung:
<translation id="7878562273885520351">Mật khẩu của bạn có thể bị xâm phạm</translation>
<translation id="7882421473871500483">Nâu</translation>
<translation id="7887683347370398519">Kiểm tra CVC của bạn và thử lại</translation>
-<translation id="7893255318348328562">Tên phiên</translation>
+<translation id="7904208859782148177">C3 (Phong bì)</translation>
<translation id="79338296614623784">Nhập số điện thoại hợp lệ</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">Hết hạn vào <ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@ Thông tin chi tiết bổ sung:
<translation id="7951415247503192394">(32 bit)</translation>
<translation id="7956713633345437162">Dấu trang di động</translation>
<translation id="7961015016161918242">Không bao giờ</translation>
+<translation id="7977894662897852582">Edp</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="8004582292198964060">Trình duyệt</translation>
<translation id="8009225694047762179">Quản lý mật khẩu</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{Thẻ này và địa chỉ thanh toán của thẻ sẽ được lưu. Bạn có thể sử dụng thẻ khi đăng nhập vào <ph name="USER_EMAIL" />.}other{Các thẻ này và địa chỉ thanh toán của thẻ sẽ được lưu. Bạn có thể sử dụng các thẻ này khi đăng nhập vào <ph name="USER_EMAIL" />.}}</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="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="8035152190676905274">Bút</translation>
+<translation id="8037117624646282037">Người đã sử dụng thiết bị này gần đây</translation>
<translation id="8037357227543935929">Yêu cầu (mặc định)</translation>
<translation id="803771048473350947">Tệp</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="8042918947222776840">Chọn phương thức nhận hàng</translation>
<translation id="8057711352706143257">Cấu hình của "<ph name="SOFTWARE_NAME" />" không chính xác. Việc gỡ cài đặt "<ph name="SOFTWARE_NAME" />" thường sẽ khắc phục được sự cố này. <ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">Thiết bị của bạn đã được định cấu hình thành:</translation>
+<translation id="8066955247577885446">Rất tiếc, đã xảy ra lỗi.</translation>
+<translation id="8074253406171541171">10x13 (Phong bì)</translation>
<translation id="8078141288243656252">Không thể chú thích khi xoay</translation>
<translation id="8079031581361219619">Tải lại trang web?</translation>
<translation id="8088680233425245692">Không xem được bài viết.</translation>
@@ -1131,11 +1284,12 @@ Thông tin chi tiết bổ sung:
<translation id="8091372947890762290">Kích hoạt đang chờ xử lý trên máy chủ</translation>
<translation id="8092774999298748321">Tím đậm</translation>
<translation id="8094917007353911263">Mạng mà bạn đang sử dụng có thể yêu cầu bạn phải truy cập <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">Đã xóa các thẻ không hợp lệ</translation>
<translation id="8103161714697287722">Phương thức thanh toán</translation>
<translation id="8118489163946903409">Phương thức thanh toán</translation>
+<translation id="8123836779274890062"><ph name="ENROLLMENT_DOMAIN" /> quản lý <ph name="DEVICE_TYPE" /></translation>
<translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" đã được cài đặt không đúng trên máy tính hoặc mạng của bạn. Hãy yêu cầu quản trị viên CNTT của bạn giải quyết vấn đề này.</translation>
-<translation id="8130693978878176684">Tôi không thể trợ giúp được nữa. Bạn vui lòng tự thực hiện hành động này.</translation>
<translation id="8131740175452115882">Xác nhận</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>
@@ -1145,8 +1299,11 @@ Thông tin chi tiết bổ sung:
<translation id="8197543752516192074">Dịch trang</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="8202370299023114387">Xung đột</translation>
+<translation id="8206978196348664717">Prc4 (Phong bì)</translation>
<translation id="8211406090763984747">Kết nối an toàn</translation>
<translation id="8218327578424803826">Vị trí được gán:</translation>
+<translation id="8220146938470311105">C7/C6 (Phong bì)</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="8238581221633243064">Mở trang trong tab Ẩn danh mới</translation>
@@ -1158,14 +1315,16 @@ Thông tin chi tiết bổ sung:
<translation id="825929999321470778">Hiển thị tất cả các mật khẩu đã lưu</translation>
<translation id="8261506727792406068">Xóa</translation>
<translation id="8267698848189296333">Đăng nhập với tên <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242"><ph name="ENROLLMENT_DOMAIN" /> quản lý trình duyệt này. Quản trị viên có thể thay đổi quy trình thiết lập trình duyệt của bạn từ xa. Hoạt động trên thiết bị này cũng có thể được quản lý bên ngoài Chrome. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">Đăng nhập</translation>
<translation id="8288807391153049143">Hiển thị chứng chỉ</translation>
<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="8298115750975731693">Wi-Fi mà bạn đang sử dụng (<ph name="WIFI_NAME" />) có thể yêu cầu bạn phải truy cập <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />.</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">Không thể dịch do kết nối mạng có sự cố.</translation>
-<translation id="8311129316111205805">Tải phiên</translation>
<translation id="8332188693563227489">Quyền truy cập <ph name="HOST_NAME" /> bị từ chối</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></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>
@@ -1183,7 +1342,6 @@ Thông tin chi tiết bổ sung:
<translation id="8416694386774425977">Cấu hình mạng này là không hợp lệ và không thể nhập được.
Thông tin chi tiết bổ sung:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">Thiết bị do <ph name="ENROLLMENT_DOMAIN" /> quản lý</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">Thay đổi</translation>
<translation id="8428213095426709021">Cài đặt</translation>
@@ -1211,9 +1369,11 @@ Thông tin chi tiết bổ sung:
<translation id="860043288473659153">Tên chủ thẻ</translation>
<translation id="861775596732816396">Kích thước 4</translation>
<translation id="8620436878122366504">Cha mẹ của bạn chưa phê duyệt trang web</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">Lưu thẻ này vào thiết bị này</translation>
<translation id="8663226718884576429">Tóm tắt đơn hàng, <ph name="TOTAL_LABEL" />, chi tiết khác</translation>
<translation id="8680536109547170164"><ph name="QUERY" />, câu trả lời, <ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">Kết nối của bạn đến <ph name="DOMAIN" /> không được mã hóa.</translation>
<translation id="8718314106902482036">Thanh toán chưa hoàn tất</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />, <ph name="DESCRIPTION" />, đề xuất tìm kiếm</translation>
@@ -1227,6 +1387,7 @@ Thông tin chi tiết bổ sung:
<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="8763927697961133303">Thiết bị USB</translation>
<translation id="8768895707659403558">Để sử dụng thẻ trên tất cả thiết bị, hãy <ph name="SIGN_IN_LINK" />.</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">&amp;Làm lại xóa</translation>
<translation id="8792621596287649091">Bạn có thể mất quyền truy cập vào tài khoản <ph name="ORG_NAME" /> của mình hoặc bị đánh cắp danh tính. Chromium khuyên bạn nên thay đổi mật khẩu ngay bây giờ.</translation>
<translation id="8800988563907321413">Đề xuất ở gần bạn xuất hiện ở đây</translation>
@@ -1237,10 +1398,12 @@ Thông tin chi tiết bổ sung:
<translation id="885730110891505394">Chia sẻ với Google</translation>
<translation id="8858065207712248076">Chrome khuyên bạn nên đặt lại mật khẩu <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> của mình nếu đã sử dụng lại mật khẩu này trên các trang web khác.</translation>
<translation id="8866481888320382733">Lỗi phân tích cú pháp cài đặt chính sách</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">Các tab đã Đóng gần đây</translation>
<translation id="8874824191258364635">Nhập số thẻ hợp lệ</translation>
<translation id="8891727572606052622">Chế độ proxy không hợp lệ.</translation>
<translation id="8903921497873541725">Phóng to</translation>
+<translation id="890485472659500557">Engineering-C</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="893332455753468063">Thêm tên</translation>
@@ -1248,13 +1411,13 @@ Thông tin chi tiết bổ sung:
<translation id="894185898663964645">Quản trị viên của bạn đã định cấu hình chứng chỉ gốc tùy chỉnh. Điều này có thể cho phép quản trị viên xem nội dung của các trang web mà bạn truy cập.</translation>
<translation id="8943282376843390568">Vàng chanh</translation>
<translation id="8957210676456822347">Ủy quyền cổng bị khóa</translation>
+<translation id="8966619695390250636">Ý bạn là?</translation>
<translation id="8968766641738584599">Lưu thẻ</translation>
<translation id="8971063699422889582">Chứng chỉ của máy chủ đã hết hạn.</translation>
<translation id="8975012916872825179">Bao gồm các thông tin như số điện thoại, địa chỉ email và địa chỉ giao hàng</translation>
<translation id="8978053250194585037">Tính năng Duyệt web an toàn của Google gần đây đã <ph name="BEGIN_LINK" />phát hiện dấu hiệu lừa đảo<ph name="END_LINK" /> trên <ph name="SITE" />. Các trang web lừa đảo sẽ giả mạo các trang web khác để đánh lừa bạn.</translation>
<translation id="8983003182662520383">Địa chỉ và phương thức thanh toán lưu trong Google Pay</translation>
<translation id="8987927404178983737">Tháng</translation>
-<translation id="8988408250700415532">Đã xảy ra lỗi. Bạn có thể hoàn tất đơn đặt hàng trên trang web.</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>
@@ -1264,6 +1427,7 @@ Thông tin chi tiết bổ sung:
<translation id="9011424611726486705">Mở cài đặt trang web</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="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(Không hợp lệ)</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>
@@ -1275,11 +1439,11 @@ Thông tin chi tiết bổ sung:
<translation id="9065745800631924235">Cụm từ tìm kiếm <ph name="TEXT" /> từ lịch sử</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="9076630408993835509">Không có công ty hay tổ chức nào quản lý trình duyệt này. Hoạt động trên thiết bị này có thể được quản lý ở bên ngoài Chrome. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">Yêu cầu thêm thông tin</translation>
<translation id="9080712759204168376">Tóm tắt đơn hàng</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>
<translation id="9106062320799175032">Thêm địa chỉ thanh toán</translation>
-<translation id="9110718169272311511">Chức năng Trợ lý Google trong Chrome có ở gần cuối màn hình</translation>
<translation id="9114524666733003316">Đang xác nhận thẻ...</translation>
<translation id="9128870381267983090">Kết nối đến mạng</translation>
<translation id="9137013805542155359">Hiển thị văn bản gốc</translation>
@@ -1288,6 +1452,7 @@ Thông tin chi tiết bổ sung:
<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="9158625974267017556">C6 (Phong bì)</translation>
<translation id="9168814207360376865">Cho phép các trang web kiểm tra xem bạn đã lưu phương thức thanh toán hay chưa</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>
@@ -1302,10 +1467,12 @@ Thông tin chi tiết bổ sung:
<translation id="9219103736887031265">Hình ảnh</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">XÓA BIỂU MẪU</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">Bạn có thể mất quyền truy cập vào Tài khoản Google của mình. Chromium khuyên bạn nên đổi mật khẩu ngay bây giờ. Bạn sẽ được yêu cầu đăng nhập.</translation>
<translation id="939736085109172342">Thư mục mới</translation>
<translation id="945855313015696284">Kiểm tra thông tin bên dưới và xóa mọi thẻ không hợp lệ</translation>
<translation id="951104842009476243">Thẻ ghi nợ và thẻ trả trước được chấp nhận</translation>
+<translation id="958202389743790697">Bị chặn theo chính sách bảo mật của <ph name="ORIGIN" />.</translation>
<translation id="962484866189421427">Nội dung này có thể tìm cách cài đặt ứng dụng lừa đảo giả mạo nội dung khác hoặc thu thập dữ liệu có thể được dùng để theo dõi bạn. <ph name="BEGIN_LINK" />Vẫn hiển thị<ph name="END_LINK" /></translation>
<translation id="969892804517981540">Phiên bản Chính thức</translation>
<translation id="973773823069644502">Thêm địa chỉ giao hàng</translation>
@@ -1314,6 +1481,7 @@ Thông tin chi tiết bổ sung:
<translation id="984275831282074731">Phương thức thanh toán</translation>
<translation id="985199708454569384">&lt;p&gt;Bạn sẽ gặp lỗi này nếu ngày và giờ trên máy tính hoặc thiết bị di động không chính xác.&lt;/p&gt;
&lt;p&gt;Để khắc phục lỗi này, hãy mở đồng hồ trên thiết bị. Đảm bảo ngày và giờ chính xác.&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">Phiên bản dành cho Nhà phát triển</translation>
<translation id="989988560359834682">Chỉnh sửa địa chỉ</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_zh-CN.xtb b/chromium/components/strings/components_strings_zh-CN.xtb
index ae7df7a13c5..c6599ef6492 100644
--- a/chromium/components/strings/components_strings_zh-CN.xtb
+++ b/chromium/components/strings/components_strings_zh-CN.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
-<translation id="1005145902654145231">无法重命名会话。</translation>
<translation id="1008557486741366299">以后再说</translation>
<translation id="1010200102790553230">保存网页以供日后加载</translation>
<translation id="1015730422737071372">提供其他详细信息</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">未知名称</translation>
<translation id="1050038467049342496">关闭其他应用</translation>
<translation id="1055184225775184556">撤消添加(&amp;U)</translation>
+<translation id="1056898198331236512">警告</translation>
<translation id="1058479211578257048">正在保存银行卡…</translation>
<translation id="10614374240317010">一律不保存</translation>
+<translation id="1062160989074299343">Prc10 (Envelope)</translation>
<translation id="106701514854093668">桌面书签</translation>
<translation id="1074497978438210769">不安全</translation>
<translation id="1080116354587839789">适合窗口宽度</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">添加持卡人姓名</translation>
<translation id="1089439967362294234">更改密码</translation>
<translation id="109743633954054152">在 Chrome 设置中管理密码</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">网站在更新其安全设置期间可能会经常显示警告。此问题应该很快就会得到改进。</translation>
<translation id="1126551341858583091">占用的本地存储空间为 <ph name="CRASH_SIZE" />。</translation>
<translation id="112840717907525620">策略缓存良好</translation>
+<translation id="1131264053432022307">您复制的图片</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> 意外终止了连接。</translation>
<translation id="1161325031994447685">重新连接到 Wi-Fi 网络</translation>
<translation id="1165039591588034296">错误</translation>
-<translation id="1173894706177603556">重命名</translation>
<translation id="1175364870820465910">打印(&amp;P)...</translation>
<translation id="1181037720776840403">删除</translation>
<translation id="1197088940767939838">橙色</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">您的设备名称</translation>
<translation id="124116460088058876">更多语言</translation>
<translation id="1250759482327835220">若想在下次购物时更快捷地付款,请将您的付款卡信息、姓名和帐单邮寄地址保存到您的 Google 帐号名下。</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />、<ph name="TYPE_2" />(已同步)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">命令行变体</translation>
<translation id="129553762522093515">最近关闭的标签页</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />尝试清除 Cookie<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">所选会话不存在。</translation>
+<translation id="1320233736580025032">Prc1 (Envelope)</translation>
+<translation id="132301787627749051">搜索剪贴板上的图片</translation>
<translation id="1323433172918577554">展开</translation>
<translation id="132390688737681464">保存并填写地址</translation>
<translation id="1333989956347591814">以下各方<ph name="BEGIN_EMPHASIS" />可能仍会看到<ph name="END_EMPHASIS" />您的活动:
@@ -79,12 +82,17 @@
<translation id="1340482604681802745">取货地址</translation>
<translation id="1348198688976932919">您要访问的网站包含危险应用</translation>
<translation id="1348779747280417563">确认姓名</translation>
+<translation id="1357195169723583938">最近使用过这部设备的用户和使用时间</translation>
+<translation id="1364822246244961190">此政策已被禁用,其值也会被忽略。</translation>
<translation id="1374468813861204354">建议</translation>
+<translation id="1374692235857187091">Index-4x6 (Postcard)</translation>
<translation id="1375198122581997741">关于版本</translation>
<translation id="1376836354785490390">收起</translation>
<translation id="1377321085342047638">卡号</translation>
<translation id="138218114945450791">浅蓝色</translation>
+<translation id="1382194467192730611">您的管理员允许使用的 USB 设备</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> 未发送任何数据。</translation>
+<translation id="140316286225361634">网站 <ph name="ORIGIN" /> 已请求将一项安全政策应用于它的所有请求,但此政策目前认为该网站不安全。</translation>
<translation id="1405567553485452995">浅绿色</translation>
<translation id="1407135791313364759">全部打开</translation>
<translation id="1413809658975081374">隐私设置错误</translation>
@@ -92,9 +100,12 @@
<translation id="1426410128494586442">是</translation>
<translation id="1430915738399379752">打印</translation>
<translation id="1455413310270022028">橡皮擦</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">显示更多</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">选择送货地址</translation>
+<translation id="1492194039220927094">政策推送:</translation>
<translation id="1501859676467574491">显示您的 Google 帐号中保存的支付卡</translation>
-<translation id="1506687042165942984">显示为此页面保存的已知过时副本。</translation>
<translation id="1507202001669085618">&lt;p&gt;如果您使用的 Wi-Fi 门户网站必须登录才能连接网络,您就会看到这条错误消息。&lt;/p&gt;
&lt;p&gt;要修正该错误,请在您尝试打开的网页上点击&lt;strong&gt;连接&lt;/strong&gt;。&lt;/p&gt;</translation>
<translation id="1517433312004943670">必须提供电话号码</translation>
@@ -102,23 +113,27 @@
<translation id="1519264250979466059">构建日期</translation>
<translation id="1521655867290435174">Google 表格</translation>
<translation id="1527263332363067270">正在等待建立连接…</translation>
+<translation id="1529521330346880926">10x15 (Envelope)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">此网页显示</translation>
<translation id="153384715582417236">暂无新内容</translation>
<translation id="154408704832528245">选择速递地址</translation>
<translation id="1549470594296187301">必须启用 JavaScript 才能使用此功能。</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">输入失效日期</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">显示此网页时出了点问题。</translation>
<translation id="1592005682883173041">本地数据访问权限</translation>
<translation id="1594030484168838125">选择</translation>
<translation id="161042844686301425">青色</translation>
-<translation id="1618822247301510817">您复制的图片</translation>
<translation id="1620510694547887537">摄像头</translation>
<translation id="1623104350909869708">阻止此页创建其他对话框</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">结束会话</translation>
<translation id="1639239467298939599">正在加载</translation>
<translation id="1640180200866533862">用户政策</translation>
@@ -133,8 +148,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> 通常会使用加密技术来保护您的信息。Google Chrome 此次尝试连接到 <ph name="SITE" /> 时,此网站发回了异常的错误凭据。这可能是因为有攻击者在试图冒充 <ph name="SITE" />,或 Wi-Fi 登录屏幕中断了此次连接。请放心,您的信息仍然是安全的,因为 Google Chrome 尚未进行任何数据交换便停止了连接。</translation>
<translation id="168841957122794586">服务器证书包含弱加密密钥。</translation>
<translation id="1697532407822776718">搞定了!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书明天才会生效。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。}other{此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书 # 天后才会生效。出现此问题的原因可能是配置有误,或有攻击者拦截了您的连接。}}</translation>
<translation id="1710259589646384581">操作系统</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">无法为该文档添加注释,因为它太大</translation>
<translation id="1721312023322545264">您需要获得<ph name="NAME" />的许可,然后才能访问此网站</translation>
<translation id="1721424275792716183">标有“*”的字段均是必填字段</translation>
@@ -145,6 +162,7 @@
<translation id="1734878702283171397">请尝试联系系统管理员。</translation>
<translation id="1740951997222943430">请输入有效的失效月份</translation>
<translation id="1743520634839655729">若想在下次购物时更快捷地付款,请将您的付款卡信息、姓名和帐单邮寄地址保存到您的 Google 帐号名下以及这台设备中。</translation>
+<translation id="1745880797583122200">您的浏览器受管理</translation>
<translation id="17513872634828108">目前打开的标签页</translation>
<translation id="1753706481035618306">页码</translation>
<translation id="1763864636252898013">此服务器无法证明它是<ph name="DOMAIN" />;您设备的操作系统不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
@@ -152,8 +170,10 @@
<translation id="1783075131180517613">请更新您的同步密码。</translation>
<translation id="1787142507584202372">您打开的标签页会显示在此处</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">持卡人姓名</translation>
<translation id="1821930232296380041">请求或请求参数无效</translation>
+<translation id="1822540298136254167">您访问过的网站和您在这些网站上花费的时间</translation>
<translation id="1826516787628120939">正在检查</translation>
<translation id="1834321415901700177">此网站包含有害程序</translation>
<translation id="1839551713262164453">由于出现错误,未能成功验证政策值</translation>
@@ -180,6 +200,7 @@
<translation id="1981206234434200693">清除 Chrome 的浏览记录数据</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{以及另外 1 个应用}other{以及另外 # 个应用}}</translation>
<translation id="2003709556000175978">立即重置您的密码</translation>
+<translation id="20053308747750172">您要访问的服务器 <ph name="ORIGIN" /> 已请求将一项安全政策应用于向其发出的所有请求。但该服务器现在提供了一项无效的政策,此政策会阻止浏览器满足您对 <ph name="SITE" /> 的访问请求。</translation>
<translation id="2025186561304664664">代理已设为自动配置。</translation>
<translation id="2030481566774242610">您是想访问<ph name="LINK" />吗?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />检查代理服务器和防火墙<ph name="END_LINK" /></translation>
@@ -196,6 +217,7 @@
<translation id="2096368010154057602">省</translation>
<translation id="2102134110707549001">建议安全系数高的密码…</translation>
<translation id="2108755909498034140">重新启动计算机</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">信用卡</translation>
<translation id="2114841414352855701">由于已被 <ph name="POLICY_NAME" /> 替换,该政策已忽略。</translation>
<translation id="213826338245044447">移动设备书签</translation>
@@ -206,6 +228,7 @@
<translation id="2154484045852737596">修改支付卡</translation>
<translation id="2166049586286450108">完全的管理员访问权限</translation>
<translation id="2166378884831602661">此网站无法提供安全连接</translation>
+<translation id="2169984857010174799">Kaku2 (Envelope)</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2183608646556468874">电话号码</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 个地址}other{# 个地址}}</translation>
@@ -223,11 +246,15 @@
<translation id="2270484714375784793">电话号码</translation>
<translation id="2283340219607151381">保存并填写地址</translation>
<translation id="2292556288342944218">您被禁止访问互联网</translation>
+<translation id="2294558542833290837">您最初打开的链接存在异常</translation>
+<translation id="2297722699537546652">B5 (Envelope)</translation>
+<translation id="2310021320168182093">Chou2 (Envelope)</translation>
<translation id="2316887270356262533">释放了不到 1 MB。当您下次访问时,某些网站的加载速度可能会更慢。</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> 要求提供用户名和密码。</translation>
<translation id="2317583587496011522">接受借记卡。</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />,到期时间:<ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">设置由管理员控制</translation>
+<translation id="2346319942568447007">您复制的图片</translation>
<translation id="2349790679044093737">VR 会话正在进行中</translation>
<translation id="2354001756790975382">其他书签</translation>
<translation id="2354430244986887761">Google 安全浏览功能最近在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />发现了有害应用<ph name="END_LINK" />。</translation>
@@ -239,29 +266,34 @@
<translation id="2365563543831475020">于 <ph name="CRASH_TIME" /> 获取的崩溃报告未上传</translation>
<translation id="2367567093518048410">级别</translation>
<translation id="2378238891085281592">您已启用无痕模式</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书可能已被撤消。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="2418081434543109369">您要访问的服务器 <ph name="ORIGIN" /> 已请求将一项安全政策应用于向其发出的所有请求。但该服务器现在未能提供任何政策,这会阻止浏览器满足您对 <ph name="SITE" /> 的访问请求。</translation>
<translation id="244665789865330679">您的设备和帐号由 <ph name="ENROLLMENT_DOMAIN" /> 管理。这意味着,您的管理员可能会远程配置您的设备和帐号。</translation>
<translation id="2463193859425327265">更改主页</translation>
<translation id="2463739503403862330">填充</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">选择速递方式</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />运行网络诊断<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">翻译此页</translation>
<translation id="2479410451996844060">搜索网址无效。</translation>
<translation id="2482878487686419369">通知</translation>
<translation id="248348093745724435">设备政策</translation>
+<translation id="2485387744899240041">您的设备和浏览器的用户名</translation>
<translation id="2491120439723279231">服务器证书中包含错误。</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON 解析器</translation>
<translation id="2495093607237746763">选中后,Chromium 会将您的信用卡副本存储在此设备上,以加快表单填写速度。</translation>
<translation id="2498091847651709837">扫描新的信用卡</translation>
<translation id="2501278716633472235">返回</translation>
<translation id="2503184589641749290">接受的借记卡和预付卡</translation>
<translation id="2515629240566999685">检查您所在区域的网络信号</translation>
-<translation id="2516852381693169964">通过<ph name="SEARCH_ENGINE" />搜索图片</translation>
<translation id="2523886232349826891">仅会保存在此设备上</translation>
<translation id="2524461107774643265">添加更多信息</translation>
<translation id="2536110899380797252">添加地址</translation>
@@ -273,6 +305,7 @@
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">本文档设置了密码保护,请输入密码。</translation>
<translation id="2609632851001447353">其他变体</translation>
+<translation id="2618023639789766142">C10 (Envelope)</translation>
<translation id="2625385379895617796">您的时钟快了</translation>
<translation id="2634124572758952069">找不到 <ph name="HOST_NAME" /> 的服务器 IP 地址。</translation>
<translation id="2639739919103226564">状态:</translation>
@@ -282,7 +315,9 @@
<translation id="2666117266261740852">关闭其他标签页或应用</translation>
<translation id="267371737713284912">按 <ph name="MODIFIER_KEY_DESCRIPTION" /> 即可撤消</translation>
<translation id="2674170444375937751">确定要从历史记录中删除这些页吗?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">离开</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">接受的银行卡</translation>
<translation id="2702801445560668637">读取列表</translation>
<translation id="2704283930420550640">值不符合格式要求。</translation>
@@ -299,7 +334,6 @@
<translation id="2742870351467570537">移除所选项</translation>
<translation id="277133753123645258">送货方式</translation>
<translation id="277499241957683684">缺少设备记录</translation>
-<translation id="2781030394888168909">以 MacOS 格式导出</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">连接已重置。</translation>
<translation id="2788784517760473862">接受的信用卡</translation>
@@ -311,8 +345,10 @@
<translation id="2826760142808435982">该连接使用 <ph name="CIPHER" /> 进行加密和身份验证,并使用 <ph name="KX" /> 作为密钥交换机制。</translation>
<translation id="2835170189407361413">清除表单</translation>
<translation id="2847118875340931228">打开无痕式窗口</translation>
+<translation id="2850739647070081192">Invite (Envelope)</translation>
<translation id="2851634818064021665">您需获得许可,才能访问此网站</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">保存卡片?</translation>
<translation id="2903493209154104877">地址</translation>
<translation id="290376772003165898">网页的源语言不是<ph name="LANGUAGE" />?</translation>
@@ -322,6 +358,7 @@
<translation id="2925673989565098301">递送方式</translation>
<translation id="2928905813689894207">帐单邮寄地址</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书来自<ph name="DOMAIN2" />。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="2948083400971632585">您可以在设置页面中停用任何针对某个连接配置的代理。</translation>
<translation id="2955913368246107853">关闭查找栏</translation>
@@ -338,11 +375,14 @@
<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="3023071826883856138">You4 (Envelope)</translation>
<translation id="3024663005179499861">策略类型有误</translation>
<translation id="3037605927509011580">喔唷,崩溃啦!</translation>
<translation id="3041612393474885105">证书信息</translation>
+<translation id="3060227939791841287">C9 (Envelope)</translation>
<translation id="3064966200440839136">将要退出隐身模式,以便通过外部应用付款。是否继续?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{无}=1{1 个密码}other{# 个密码}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">添加取货地址</translation>
<translation id="3105172416063519923">资产 ID:</translation>
<translation id="3109728660330352905">您未获授权,无法查看此网页。</translation>
@@ -362,20 +402,21 @@
<translation id="3195213714973468956">“<ph name="SERVER_NAME" />”上的“<ph name="PRINTER_NAME" />”</translation>
<translation id="320323717674993345">取消付款</translation>
<translation id="3207960819495026254">已加书签</translation>
-<translation id="3209375525920864198">请输入一个有效的会话名称。</translation>
+<translation id="321912867715453276">警告:此政策存在多个来源,但它们具有相同的值。</translation>
<translation id="3225919329040284222">服务器提供的证书与内置预期证书不匹配。这些预期证书是针对某些高安全性网站提供的,以便为您提供保护。</translation>
<translation id="3226128629678568754">按“重新加载”按钮,重新提交加载该网页所需的数据。</translation>
<translation id="3227137524299004712">麦克风</translation>
<translation id="3228969707346345236">此网页已经是<ph name="LANGUAGE" />网页,因此无法翻译。</translation>
+<translation id="3229041911291329567">与您的设备和浏览器相关的版本信息</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">添加持卡人姓名</translation>
<translation id="3287510313208355388">联网时下载</translation>
<translation id="3293642807462928945">详细了解“<ph name="POLICY_NAME" />”政策</translation>
<translation id="3303855915957856445">未找到任何搜索结果</translation>
-<translation id="3305707030755673451">您的数据已于 <ph name="TIME" />使用您的同步密码加密。输入该密码即可开始同步。</translation>
<translation id="3320021301628644560">添加账单邮寄地址</translation>
<translation id="3324983252691184275">深红色</translation>
<translation id="3338095232262050444">安全</translation>
@@ -403,9 +444,11 @@
<translation id="3427342743765426898">恢复修改(&amp;R)</translation>
<translation id="342781501876943858">如果您在其他网站上重复使用了您的密码,Chromium 建议您重置该密码。</translation>
<translation id="3431636764301398940">将此卡的信息保存到该设备</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">此设备的所有者已关闭恐龙游戏。</translation>
<translation id="3447884698081792621">显示证书(由<ph name="ISSUER" />签发)</translation>
<translation id="3452404311384756672">抓取时间间隔:</translation>
+<translation id="3456231139987291353">Number-11 (Envelope)</translation>
<translation id="3461824795358126837">荧光笔</translation>
<translation id="3462200631372590220">隐藏详情</translation>
<translation id="3467763166455606212">必须输入持卡人姓名</translation>
@@ -427,19 +470,22 @@
<translation id="358285529439630156">接受信用卡和预付卡。</translation>
<translation id="3582930987043644930">添加名称</translation>
<translation id="3583757800736429874">恢复移动(&amp;R)</translation>
+<translation id="35866233670761917">您的管理员看不到您访问的网站的内容</translation>
<translation id="3586931643579894722">隐藏详细信息</translation>
+<translation id="3592413004129370115">Italian (Envelope)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />,<ph name="DOMAIN" />,<ph name="TIME" /></translation>
<translation id="3614103345592970299">大小:2</translation>
<translation id="3615877443314183785">请输入有效的失效日期</translation>
<translation id="36224234498066874">清除浏览数据...</translation>
<translation id="362276910939193118">显示所有历史记录</translation>
-<translation id="3623476034248543066">显示值</translation>
<translation id="3630155396527302611">如果它已在可访问网络的程序列表中,请尝试将它从该列表中移除,然后重新添加到其中。</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">验证成功</translation>
<translation id="3655670868607891010">如果您频繁遇到此问题,请尝试这些<ph name="HELP_LINK" />。</translation>
<translation id="3658742229777143148">修订版本</translation>
<translation id="366077651725703012">更新信用卡</translation>
<translation id="3676592649209844519">设备 ID:</translation>
+<translation id="3677008721441257057">您是想访问 &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; 吧?</translation>
<translation id="3678029195006412963">无法签署该请求</translation>
<translation id="3678529606614285348">在新的无痕式窗口中打开网页 (Ctrl-Shift-N)</translation>
<translation id="3679803492151881375">崩溃报告的获取时间:<ph name="CRASH_TIME" />;上传时间:<ph name="UPLOAD_TIME" /></translation>
@@ -447,13 +493,14 @@
<translation id="3704162925118123524">您正在使用的网络可能会要求您访问其登录页面。</translation>
<translation id="3704609568417268905"><ph name="TIME" /> - <ph name="BOOKMARKED" /> - <ph name="TITLE" /> - <ph name="DOMAIN" /></translation>
<translation id="370665806235115550">正在加载...</translation>
+<translation id="3709599264800900598">您复制的文字</translation>
<translation id="3712624925041724820">许可已用尽</translation>
<translation id="3714780639079136834">开启移动数据网络或 WLAN</translation>
<translation id="3715597595485130451">连接到 Wi-Fi 网络</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />检查代理服务器、防火墙和 DNS 配置<ph name="END_LINK" /></translation>
<translation id="372429172604983730">可能导致此错误的应用包括防病毒软件、防火墙软件和网络过滤/代理软件。</translation>
+<translation id="373042150751172459">B4 (Envelope)</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="3745099705178523657">待您确认后,系统便会将您 Google 帐号中的信用卡详细信息共享给该网站。</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>
@@ -466,10 +513,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">失效日期:<ph name="EXPIRATION_YEAR" /> 年 <ph name="EXPIRATION_MONTH" /> 月</translation>
<translation id="3789155188480882154">大小:16</translation>
+<translation id="3797522431967816232">Prc3 (Envelope)</translation>
<translation id="3807873520724684969">有害内容已被拦截。</translation>
<translation id="3810973564298564668">管理</translation>
<translation id="382518646247711829">如果您使用代理服务器…</translation>
<translation id="3828924085048779000">密码输入字段不能留空。</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> 已安装了一些扩展程序来提供更多功能。这些扩展程序有权访问您的部分数据。</translation>
<translation id="385051799172605136">后退</translation>
<translation id="3858027520442213535">更新日期和时间</translation>
<translation id="3884278016824448484">设备标识符存在冲突</translation>
@@ -477,6 +526,7 @@
<translation id="3886446263141354045">系统已将您想访问此网站的请求发送给<ph name="NAME" /></translation>
<translation id="3890664840433101773">添加电子邮件地址</translation>
<translation id="3901925938762663762">此信用卡已过期</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" /> <ph name="ERROR" /></translation>
<translation id="3946209740501886391">在该网站上一律询问</translation>
<translation id="3949571496842715403">此服务器无法证实它就是 <ph name="DOMAIN" /> - 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。</translation>
@@ -487,11 +537,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{无}=1{来自 1 个网站}other{来自 # 个网站}}</translation>
<translation id="397105322502079400">正在计算...</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> 已被屏蔽</translation>
-<translation id="3984550557525787191">此会话名称已存在。</translation>
<translation id="3987940399970879459">小于 1 MB</translation>
+<translation id="4008849406247176967">警告:此政策存在多个具有冲突值的来源!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{附近有 1 个网页}other{附近有 # 个网页}}</translation>
<translation id="4030383055268325496">撤消添加(&amp;U)</translation>
+<translation id="4032320456957708163">您的浏览器由 <ph name="ENROLLMENT_DOMAIN" /> 管理</translation>
<translation id="4058922952496707368">“<ph name="SUBKEY" />”键:<ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (Envelope)</translation>
<translation id="4067947977115446013">添加有效地址</translation>
<translation id="4072486802667267160">处理您的订单时出错。请重试。</translation>
<translation id="4075732493274867456">客户端和服务器不支持一般 SSL 协议版本或加密套件。</translation>
@@ -511,10 +563,12 @@
<translation id="4159784952369912983">紫色</translation>
<translation id="4165986682804962316">网站设置</translation>
<translation id="4171400957073367226">验证签名无效</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{另外 <ph name="ITEM_COUNT" /> 项}other{另外 <ph name="ITEM_COUNT" /> 项}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> - <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">恢复移动(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />检查防火墙和防病毒配置<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (Envelope)</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="4221630205957821124">&lt;h4&gt;第 1 步:登录门户网站&lt;/h4&gt;
@@ -546,58 +600,79 @@
<translation id="4277028893293644418">重置密码</translation>
<translation id="4280429058323657511">,到期日期:<ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{这张卡已保存到您的 Google 帐号中}other{这些卡已保存到您的 Google 帐号中}}</translation>
+<translation id="42981349822642051">展开</translation>
+<translation id="4302965934281694568">Chou3 (Envelope)</translation>
<translation id="4305817255990598646">切换</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">屏蔽(默认)</translation>
+<translation id="4318566738941496689">您的设备名称和网络地址</translation>
<translation id="4325863107915753736">找不到文章</translation>
<translation id="4326324639298822553">请检查您的信用卡到期日期,然后重试</translation>
<translation id="4331708818696583467">不安全</translation>
<translation id="4340982228985273705">系统检测到,此计算机不是由企业管理,因此政策只能自动安装 Chrome 网上应用店中托管的扩展程序。对应的 Chrome 网上应用店更新网址为“<ph name="CWS_UPDATE_URL" />”。</translation>
<translation id="4346197816712207223">接受的信用卡</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">此网站上的攻击者可能会试图在您的计算机上安装危险程序,以窃取或删除您的信息(例如:照片、密码、通讯内容和信用卡信息)。</translation>
<translation id="4358461427845829800">管理付款方式…</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">应使用<ph name="VALUE_TYPE" />值。</translation>
<translation id="4377125064752653719">您尝试访问的是 <ph name="DOMAIN" />,但服务器出示的证书已被其颁发者吊销。这表明绝对不应该信任此服务器出示的安全凭据。您可能正在与攻击者进行通信。</translation>
<translation id="4378154925671717803">电话机</translation>
<translation id="4406896451731180161">搜索结果</translation>
-<translation id="4406972042435603828">您的管理员安装了一些具有强大功能的扩展程序。</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" />Cookie</translation>
<translation id="4415426530740016218">取货地址</translation>
<translation id="4424024547088906515">此服务器无法证明它是<ph name="DOMAIN" />;Chrome不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="443121186588148776">串行端口</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> 不接受您的登录证书,或者您可能没有提供登录证书。</translation>
<translation id="4434045419905280838">弹出式窗口和重定向</translation>
+<translation id="4435702339979719576">Postcard)</translation>
<translation id="443673843213245140">已停用代理,但是指定了明确的代理配置。</translation>
<translation id="445100540951337728">接受的借记卡</translation>
+<translation id="4466881336512663640">对表单所做的更改将会丢失。确定要继续吗?</translation>
<translation id="4482953324121162758">系统不会翻译此网站。</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">网址无效。必须是采用标准架构的网址,例如“http://example.com”或“https://example.com”。</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">验证错误:<ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">联系系统管理员</translation>
<translation id="450710068430902550">与管理员分享</translation>
+<translation id="4510487217173779431">Chou4 (Envelope)</translation>
<translation id="4515275063822566619">信用卡选项和地址选项均来自 Chrome 和您的 Google 帐号 (<ph name="ACCOUNT_EMAIL" />)。您可在<ph name="BEGIN_LINK" />设置<ph name="END_LINK" />中管理这些选项。</translation>
+<translation id="4517607026994743406">Comm-10 (Envelope)</translation>
<translation id="4522570452068850558">详细信息</translation>
<translation id="4524805452350978254">管理卡片</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">尝试停用扩展程序。</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">递送</translation>
+<translation id="4579056131138995126">Personal (Envelope)</translation>
<translation id="4582204425268416675">移除卡</translation>
<translation id="4587425331216688090">从 Chrome 中移除地址?</translation>
<translation id="4592951414987517459">您与 <ph name="DOMAIN" /> 之间的连接采用新型加密套件进行了加密。</translation>
<translation id="4594403342090139922">撤消删除(&amp;U)</translation>
<translation id="4597348597567598915">大小:8</translation>
+<translation id="4600854749408232102">C6/C5 (Envelope)</translation>
<translation id="4646534391647090355">立即前往</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书有误。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="467809019005607715">Google 幻灯片</translation>
<translation id="4690462567478992370">停止使用无效的证书</translation>
+<translation id="4691835149146451662">Architecture-A (Envelope)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /><ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">您的连接已中断</translation>
<translation id="471880041731876836">您无权访问此网站</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />运行 Windows 网络诊断<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">重新加载政策</translation>
<translation id="4728558894243024398">平台</translation>
+<translation id="4731967714531604179">Prc2 (Envelope)</translation>
<translation id="4736825316280949806">重新启动 Chromium</translation>
<translation id="473775607612524610">更新</translation>
<translation id="4738601419177586157"><ph name="TEXT" />搜索建议</translation>
<translation id="4742407542027196863">管理密码…</translation>
<translation id="4744603770635761495">可执行文件路径</translation>
+<translation id="4746351372139058112">信息</translation>
<translation id="4750917950439032686">您发送给这个网站的信息(例如密码或信用卡号)不会外泄。</translation>
<translation id="4756388243121344051">历史记录(&amp;H)</translation>
<translation id="4758311279753947758">添加联系信息</translation>
@@ -605,9 +680,9 @@
<translation id="4764776831041365478">网址为 <ph name="URL" /> 的网页可能暂时无法连接,或者它已永久性地移动到了新网址。</translation>
<translation id="4771973620359291008">发生未知错误。</translation>
<translation id="4785689107224900852">切换到这个标签页</translation>
-<translation id="4792143361752574037">访问会话文件时出问题了。“保存到磁盘”功能已被停用。请重新加载此页以重试。</translation>
<translation id="4798078619018708837">请输入 <ph name="CREDIT_CARD" /> 的失效日期和银行卡验证码 (CVC),以更新您的信用卡详细信息。待您确认后,系统便会将您 Google 帐号中的信用卡详细信息共享给该网站。</translation>
<translation id="4800132727771399293">请检查您的到期日期和银行卡验证码 (CVC),然后重试</translation>
+<translation id="480334179571489655">来源政策错误</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>
@@ -622,7 +697,6 @@
<translation id="4881695831933465202">打开</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>
@@ -631,15 +705,15 @@
<translation id="4943872375798546930">找不到结果</translation>
<translation id="4950898438188848926">标签页切换按钮,按 Enter 键可切换到打开的标签页,<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">操作</translation>
-<translation id="495832697253704892">扩展程序报告</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">展开列表</translation>
<translation id="4974590756084640048">重新启用警告功能</translation>
+<translation id="4984339528288761049">Prc5 (Envelope)</translation>
<translation id="4989163558385430922">查看全部</translation>
<translation id="4989809363548539747">该插件不受支持</translation>
-<translation id="4996230189582812866">报告</translation>
<translation id="5002932099480077015">如果您选中此项,Chrome 会将您的卡的副本存储在此设备上,以加快表单填写速度。</translation>
-<translation id="5014174725590676422">显示 Chrome 中的 Google 助理的首次运行屏幕</translation>
<translation id="5015510746216210676">设备名称:</translation>
+<translation id="5017554619425969104">您复制的文字</translation>
<translation id="5018422839182700155">无法打开此网页</translation>
<translation id="5019198164206649151">后备存储状态不佳</translation>
<translation id="5023310440958281426">请查看管理员制定的政策</translation>
@@ -649,35 +723,51 @@
<translation id="5034369478845443529">本地上下文:<ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">允许</translation>
<translation id="5040262127954254034">隐私设置</translation>
+<translation id="5043480802608081735">您复制的链接</translation>
<translation id="5045550434625856497">密码不正确</translation>
<translation id="5056549851600133418">为您推荐的文章</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />检查代理服务器地址<ph name="END_LINK" /></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="5097099694988056070">设备统计信息(例如 CPU/RAM 使用情况)</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">您的设备由 <ph name="ENROLLMENT_DOMAIN" /> 管理,而您的帐号由 <ph name="ACCOUNT_DOMAIN" /> 管理。这意味着,您的管理员可能会远程配置您的设备和帐号。</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 位)</translation>
-<translation id="5128122789703661928">无法删除此会话,因为它的名称无效。</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">管理地址…</translation>
+<translation id="5138227688689900538">收起</translation>
<translation id="5141240743006678641">使用您的 Google 凭据加密已同步的密码</translation>
<translation id="5145883236150621069">策略响应中存在错误代码</translation>
+<translation id="515292512908731282">C4 (Envelope)</translation>
<translation id="5159010409087891077">在新的无痕式窗口中打开网页 (⇧⌘N)</translation>
<translation id="516920405563544094">请输入 <ph name="CREDIT_CARD" /> 的银行卡验证码 (CVC)。待您确认后,系统便会将您 Google 帐号中的信用卡详细信息共享给该网站。</translation>
<translation id="5169827969064885044">您可能会无法再访问所属组织的帐号,或被他人盗用身份信息。Chrome 建议您立即更改密码。</translation>
<translation id="5171045022955879922">搜索或输入网址</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">本机</translation>
<translation id="5179510805599951267">不是<ph name="ORIGINAL_LANGUAGE" />?报告此错误</translation>
<translation id="5190835502935405962">书签栏</translation>
-<translation id="5200263511887412697">以列表的形式报告最近登录过的设备用户</translation>
+<translation id="519422657042045905">注释不可用</translation>
<translation id="5201306358585911203">此网页上的嵌入式页面显示</translation>
<translation id="5205222826937269299">需要提供名称</translation>
<translation id="5215116848420601511">Google Pay 中存储的付款方式和地址信息</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">需要提供电子邮件地址</translation>
<translation id="5230733896359313003">送货地址</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">“连接到网络”</translation>
<translation id="5251803541071282808">云端</translation>
+<translation id="5252000469029418751">C7 (Envelope)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">网络地址</translation>
<translation id="5285570108065881030">显示所有已保存的密码</translation>
<translation id="5287240709317226393">显示 Cookie</translation>
<translation id="5288108484102287882">政策值验证引发了警告</translation>
@@ -689,7 +779,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />,第 <ph name="MATCH_POSITION" /> 个(共 <ph name="NUM_MATCHES" /> 个)</translation>
<translation id="5324080437450482387">选择联系信息</translation>
<translation id="5327248766486351172">名称</translation>
+<translation id="5329858041417644019">您的浏览器不受管理</translation>
<translation id="5332219387342487447">送货方式</translation>
+<translation id="5334013548165032829">详细的系统日志</translation>
<translation id="5344579389779391559">此页面可能会向您收取费用</translation>
<translation id="5355557959165512791">您目前无法访问 <ph name="SITE" />,因为此证书已被撤消。网络错误和攻击行为通常是暂时的,因此,此网页稍后可能会恢复正常。</translation>
<translation id="536296301121032821">无法存储策略设置</translation>
@@ -697,6 +789,7 @@
<translation id="5377026284221673050">“您的时钟慢了”、“您的时钟快了”或“&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;”</translation>
<translation id="5384855140246857529">要在所有设备上使用您的卡,请登录您的帐号并开启同步功能。</translation>
<translation id="5386426401304769735">此网站的证书链包含使用 SHA-1 签署的证书。</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">此服务器无法证明它是 <ph name="DOMAIN" />;其安全证书目前无效。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
<translation id="5421136146218899937">清除浏览数据...</translation>
<translation id="5430298929874300616">移除书签</translation>
@@ -707,6 +800,7 @@
<translation id="5457113250005438886">无效</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">恢复修改(&amp;R)</translation>
+<translation id="5478437291406423475">B6/C4 (Envelope)</translation>
<translation id="5481076368049295676">此内容可能会试图在您的设备上安装危险的软件来窃取或删除您的信息。<ph name="BEGIN_LINK" />仍然显示<ph name="END_LINK" /></translation>
<translation id="54817484435770891">添加有效地址</translation>
<translation id="5490432419156082418">地址和其他信息</translation>
@@ -714,10 +808,12 @@
<ph name="LINE_BREAK" />
请尝试与您的系统管理员联系。</translation>
<translation id="549333378215107354">大小:3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">受管理的书签</translation>
<translation id="5510766032865166053">该文件可能已被移至别处或遭到删除。</translation>
<translation id="5523118979700054094">政策名</translation>
<translation id="552553974213252141">提取的内容是否正确?</translation>
+<translation id="553484882784876924">Prc6 (Envelope)</translation>
<translation id="5540224163453853">找不到请求的文章。</translation>
<translation id="5541546772353173584">添加电子邮件地址</translation>
<translation id="5545756402275714221">为您推荐的文章</translation>
@@ -732,15 +828,21 @@
<translation id="5595485650161345191">修改地址</translation>
<translation id="5598944008576757369">选择付款方式</translation>
<translation id="560412284261940334">不支持管理</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">检查网络连接</translation>
<translation id="5610807607761827392">您可以在<ph name="BEGIN_LINK" />设置<ph name="END_LINK" />中管理信用卡和地址信息。</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> 将您重定向的次数过多。</translation>
<translation id="5629630648637658800">无法加载策略设置</translation>
<translation id="5631439013527180824">设备管理令牌无效</translation>
+<translation id="5632627355679805402">您的数据已于 <ph name="TIME" />使用您的 <ph name="BEGIN_LINK" />Google 密码<ph name="END_LINK" />加密。输入该密码即可开始同步。</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="563324245173044180">欺骗性内容已被拦截。</translation>
<translation id="5659593005791499971">电子邮件</translation>
+<translation id="5663614846592581799">9x11 (Envelope)</translation>
+<translation id="5663955426505430495">此设备的管理员已安装了一些扩展程序来提供更多功能。这些扩展程序有权访问您的部分数据。</translation>
<translation id="5675650730144413517">该网页无法正常运作</translation>
+<translation id="5684874026226664614">糟糕,此网页内容无法翻译。</translation>
<translation id="5685654322157854305">添加送货地址</translation>
<translation id="5689199277474810259">导出为 JSON 格式</translation>
<translation id="5689516760719285838">位置信息</translation>
@@ -749,38 +851,39 @@
<translation id="5710435578057952990">此网站尚未经过身份验证。</translation>
<translation id="5719499550583120431">接受预付卡。</translation>
<translation id="5720705177508910913">当前用户</translation>
+<translation id="5728056243719941842">C5 (Envelope)</translation>
<translation id="5730040223043577876">如果您在其他网站上重复使用了您的密码,Chrome 建议您重置该密码。</translation>
<translation id="5732392974455271431">您的父母可为您取消屏蔽此网站</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{将这张卡保存在您的 Google 帐号中}other{将这些卡保存在您的 Google 帐号中}}</translation>
<translation id="5763042198335101085">请输入有效的电子邮件地址</translation>
<translation id="5765072501007116331">要查看递送方式和要求,请选择相应地址</translation>
-<translation id="5770114862687765385">该文件似乎已受损。请点击“重置”按钮以重置此会话。</translation>
<translation id="5778550464785688721">完全控制 MIDI 设备</translation>
<translation id="578305955206182703">琥珀色</translation>
<translation id="57838592816432529">静音</translation>
<translation id="5784606427469807560">确认您的信用卡时出现问题。请检查您的互联网连接,然后重试。</translation>
<translation id="5785756445106461925">而且,此页中包含其他不安全的资源。他人能在这些资源传输过程中进行查看,攻击者也可以修改这些资源,从而改变此页的外观。</translation>
<translation id="5786044859038896871">要填充您的信用卡信息吗?</translation>
+<translation id="5798290721819630480">舍弃更改?</translation>
<translation id="5798683403665926540">在 Chrome 设置中更改主页</translation>
<translation id="5803412860119678065">要填充您的“<ph name="CARD_DETAIL" />”吗?</translation>
<translation id="5804241973901381774">权限</translation>
<translation id="5810442152076338065">您与 <ph name="DOMAIN" /> 之间的连接采用过时的加密套件进行了加密。</translation>
<translation id="5813119285467412249">恢复添加(&amp;R)</translation>
<translation id="5838278095973806738">请勿在此网站上输入任何敏感信息(例如密码或信用卡信息),因为攻击者可能会盗取这些信息。</translation>
+<translation id="5860033963881614850">关闭</translation>
<translation id="5863847714970149516">即将进入的页面可能会向您收取费用</translation>
<translation id="5866257070973731571">添加电话号码</translation>
<translation id="5869405914158311789">无法访问此网站</translation>
<translation id="5869522115854928033">已保存的密码</translation>
<translation id="5887400589839399685">已保存卡片</translation>
-<translation id="5893718151540690985">以列表的形式报告网络接口及其类型和硬件地址</translation>
<translation id="5893752035575986141">接受信用卡。</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="5916664084637901428">启用</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">将银行卡信息保存到 Google 帐号中?</translation>
<translation id="5922853866070715753">即将完成</translation>
<translation id="5932224571077948991">网站展示过侵扰性或误导性广告</translation>
-<translation id="5939518447894949180">重置</translation>
<translation id="5946937721014915347">正在打开 <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">无法通过消费者帐号注册(有封装的许可)。</translation>
<translation id="5967592137238574583">修改联系信息</translation>
@@ -788,6 +891,7 @@
<translation id="5975083100439434680">缩小</translation>
<translation id="5977489021191000276">您的设备不受管理员管理。</translation>
<translation id="5977976211062815271">在这部设备上</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">无法打开付款应用</translation>
<translation id="5989320800837274978">固定代理服务器和 .pac 脚本网址均未指定。</translation>
<translation id="5990559369517809815">对服务器的请求已遭到某个扩展程序的阻止。</translation>
@@ -798,8 +902,8 @@
<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="6033927989869462158">报告硬件统计信息(例如 CPU/RAM 使用情况)</translation>
<translation id="6034000775414344507">浅灰色</translation>
+<translation id="6034283069659657473">10x14 (Envelope)</translation>
<translation id="6039846035001940113">如果问题仍然存在,请与网站所有者联系。</translation>
<translation id="6040143037577758943">关闭</translation>
<translation id="6044573915096792553">大小:12</translation>
@@ -808,10 +912,10 @@
<translation id="6051221802930200923">您目前无法访问 <ph name="SITE" />,因为此网站使用了证书锁定。网络错误和攻击通常是暂时的,因此,此网页稍后可能会恢复正常。</translation>
<translation id="6058977677006700226">在您的所有设备上使用您的卡?</translation>
<translation id="6059925163896151826">USB 设备</translation>
-<translation id="6071091556643036997">政策类型无效。</translation>
<translation id="6080696365213338172">您已使用管理员提供的证书访问了内容,因此管理员可以拦截您提供给 <ph name="DOMAIN" /> 的数据。</translation>
<translation id="6094273045989040137">注释</translation>
<translation id="610911394827799129">您的 Google 帐号在 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 上可能有其他形式的浏览记录</translation>
+<translation id="6132597952260690497">与已安装的扩展程序和插件相关的信息</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{无}=1{1 个密码(已同步)}other{# 个密码(已同步)}}</translation>
<translation id="6146055958333702838">请检查所有网线是否都已连好,然后重新启动您可能正在使用的任何路由器、调制解调器或其他网络设备。</translation>
<translation id="614940544461990577">请试试以下办法:</translation>
@@ -845,15 +949,21 @@
<translation id="6337133576188860026">释放了不到 <ph name="SIZE" />。当您下次访问时,某些网站的加载速度可能会更慢。</translation>
<translation id="6337534724793800597">按名称过滤政策</translation>
<translation id="6358450015545214790">这分别意味着什么?</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">可能产生费用。</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{1 条其他建议}other{# 条其他建议}}</translation>
<translation id="6387754724289022810">只要将您的付款卡信息和帐单邮寄地址保存到您的 Google 帐号和此设备,下次即可更便捷地完成付款。</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">修改书签</translation>
+<translation id="6406765186087300643">C0 (Envelope)</translation>
<translation id="6410264514553301377">请输入“<ph name="CREDIT_CARD" />”的到期日期和银行卡验证码 (CVC)</translation>
<translation id="6414888972213066896">您已向父亲/母亲发送请求,询问其是否允许您访问此网站</translation>
<translation id="6417515091412812850">无法检查证书是否已吊销。</translation>
<translation id="6433490469411711332">修改联系信息</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> 拒绝了我们的连接请求。</translation>
+<translation id="6434309073475700221">放弃</translation>
+<translation id="6446163441502663861">Kahu (Envelope)</translation>
<translation id="6446608382365791566">添加更多信息</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">确认重新提交表单</translation>
@@ -866,11 +976,17 @@
<translation id="6508722015517270189">重新启动 Chrome</translation>
<translation id="6529602333819889595">恢复删除(&amp;R)</translation>
<translation id="6534179046333460208">实物网建议</translation>
+<translation id="6556866813142980365">重做</translation>
<translation id="6563469144985748109">您的管理员尚未批准此网站</translation>
<translation id="6569060085658103619">您正在查看扩展程序页面</translation>
+<translation id="6578796323535178455">C2 (Envelope)</translation>
<translation id="6579990219486187401">浅粉色</translation>
+<translation id="6583674473685352014">B6 (Envelope)</translation>
+<translation id="6587923378399804057">您复制的链接</translation>
+<translation id="6591833882275308647">您的 <ph name="DEVICE_TYPE" /> 不受管理</translation>
<translation id="6596325263575161958">加密选项</translation>
<translation id="6604181099783169992">动态传感器或光传感器</translation>
+<translation id="6609880536175561541">Prc7 (Envelope)</translation>
<translation id="6624427990725312378">联系信息</translation>
<translation id="6626291197371920147">添加有效的卡号</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 搜索</translation>
@@ -879,6 +995,7 @@
<translation id="6644283850729428850">此政策已弃用。</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{无}=1{来自 1 个网站(这不会致使您退出自己的 Google 帐号)}other{来自 # 个网站(这不会致使您退出自己的 Google 帐号)}}</translation>
<translation id="6657585470893396449">密码</translation>
+<translation id="6670613747977017428">返回到安全网页。</translation>
<translation id="6671697161687535275">要从 Chromium 中移除表单填写建议吗?</translation>
<translation id="6685834062052613830">请退出并完成设置</translation>
<translation id="6710213216561001401">上一个</translation>
@@ -886,12 +1003,15 @@
<translation id="671076103358959139">注册令牌:</translation>
<translation id="6711464428925977395">代理服务器出现问题,或者地址有误。</translation>
<translation id="6723740634201835758">在您的 Google 帐号中</translation>
+<translation id="6738516213925468394">您的数据已于 <ph name="TIME" />使用您的<ph name="BEGIN_LINK" />同步密码<ph name="END_LINK" />加密。输入该密码即可开始同步。</translation>
<translation id="674375294223700098">未知的服务器证书错误。</translation>
<translation id="6744009308914054259">在等待连接时,您可以前往“下载内容”页面阅读离线文章。</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6757797048963528358">您的设备已进入休眠模式。</translation>
+<translation id="6768213884286397650">Hagaki (Postcard)</translation>
<translation id="6778737459546443941">您的父亲/母亲尚未批准此网站</translation>
<translation id="67862343314499040">紫罗兰色</translation>
+<translation id="6786747875388722282">扩展程序</translation>
<translation id="679355240208270552">由于政策未启用默认搜索引擎,因此政策值已被忽略。</translation>
<translation id="681021252041861472">必填字段</translation>
<translation id="6810899417690483278">自定义 ID</translation>
@@ -924,10 +1044,12 @@
<translation id="6965978654500191972">设备</translation>
<translation id="6970216967273061347">区</translation>
<translation id="6973656660372572881">固定代理服务器和 .pac 脚本网址均已指定。</translation>
+<translation id="6973932557599545801">抱歉,我已是爱莫能助,请您自行继续操作。</translation>
<translation id="6979158407327259162">Google 云端硬盘</translation>
<translation id="6979440798594660689">静音(默认)</translation>
<translation id="6984479912851154518">即将退出无痕模式,以便通过外部应用付款。要继续吗?</translation>
<translation id="6989763994942163495">显示高级设置...</translation>
+<translation id="6993898126790112050">6x9 (Envelope)</translation>
<translation id="6996312675313362352">始终翻译<ph name="ORIGINAL_LANGUAGE" />内容</translation>
<translation id="7012363358306927923">中国银联</translation>
<translation id="7016992613359344582">这些费用可能只收取一次,也可能会周期性收取,而且可能不易察觉。</translation>
@@ -943,28 +1065,33 @@
<translation id="7108338896283013870">隐藏</translation>
<translation id="7108819624672055576">某款扩展程序允许</translation>
<translation id="7111012039238467737">(有效)</translation>
+<translation id="7118618213916969306">搜索剪贴板上的网址:<ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">关闭其他标签页或程序</translation>
<translation id="7129409597930077180">无法向此地址送货。请另选一个地址。</translation>
<translation id="7135130955892390533">显示状态</translation>
<translation id="7138472120740807366">递送方式</translation>
<translation id="7139724024395191329">酋长国</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">薰衣草色</translation>
-<translation id="7158980942472052083">网址无效。必须是采用标准架构的网址。</translation>
<translation id="717330890047184534">GAIA ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">您要访问的服务器 <ph name="ORIGIN" /> 已请求将一项安全政策应用于向其发出的所有请求。但该服务器并未提供任何政策,而是将浏览器重定向到了别处,这会阻止浏览器满足您对 <ph name="SITE" /> 的访问请求。</translation>
<translation id="7179323680825933600">保存并填写付款方式</translation>
<translation id="7180611975245234373">刷新</translation>
<translation id="7182878459783632708">未设置任何政策</translation>
<translation id="7186367841673660872">已将此网页从<ph name="ORIGINAL_LANGUAGE" />翻译成<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">释放了 <ph name="SIZE" />。当您下次访问时,某些网站的加载速度可能会更慢。</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">您的管理员可以查看:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> 不符合相关安全标准。</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />详细了解<ph name="END_LINK" />此问题。</translation>
<translation id="7219179957768738017">该连接使用 <ph name="SSL_VERSION" />。</translation>
<translation id="7220786058474068424">正在处理</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />;<ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">您要访问的网站包含恶意软件</translation>
+<translation id="724766306220616965">警告、冲突</translation>
<translation id="724975217298816891">输入“<ph name="CREDIT_CARD" />”的过期日期和银行卡验证码 (CVC) 以更新您的信用卡详情。在您确认后,您的信用卡详情将与此网站共享。</translation>
<translation id="7251437084390964440">网络配置不符合 ONC 标准,因此它的某些部分可能会无法导入。
更多详情:
@@ -977,11 +1104,14 @@
<translation id="7300012071106347854">钴蓝色</translation>
<translation id="7302712225291570345">“<ph name="TEXT" />”</translation>
<translation id="7309308571273880165">崩溃报告获取时间:<ph name="CRASH_TIME" />(用户已请求上传,但尚未上传)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />安全浏览<ph name="END_LINK" />警告</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">与连接相关的帮助</translation>
<translation id="7334320624316649418">恢复顺序调整(&amp;R)</translation>
<translation id="733923710415886693">该服务器的证书未通过证书透明度政策进行披露。</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">命令行</translation>
-<translation id="7365061714576910172">以 Linux 格式导出</translation>
<translation id="7372973238305370288">搜索结果</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">否</translation>
@@ -989,6 +1119,7 @@
<translation id="7381288752349550461">受管理自助服务终端替换</translation>
<translation id="7390545607259442187">确认信用卡</translation>
<translation id="7400418766976504921">网址</translation>
+<translation id="7403591733719184120">您的 <ph name="DEVICE_NAME" /> 受管理</translation>
<translation id="7407424307057130981">&lt;p&gt;如果您的 Windows 计算机上装有 SuperFish 软件,您将会看到这条错误消息。&lt;/p&gt;
&lt;p&gt;您可以按照下述步骤暂时停用该软件,以便连接到网络。您需要拥有管理员权限才能执行下列操作。&lt;/p&gt;
&lt;ol&gt;
@@ -999,7 +1130,7 @@
&lt;li&gt;依次点击&lt;strong&gt;应用&lt;/strong&gt;和&lt;strong&gt;确定&lt;/strong&gt;
&lt;li&gt;访问 &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome 帮助中心&lt;/a&gt;,了解如何从您的计算机中永久移除该软件
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399"><ph name="PRODUCT_NAME" />管理</translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">管理密码…</translation>
<translation id="7419106976560586862">个人资料路径</translation>
<translation id="7437289804838430631">添加联系信息</translation>
@@ -1008,22 +1139,24 @@
<translation id="7442725080345379071">浅橙色</translation>
<translation id="7444046173054089907">此网站已被屏蔽</translation>
<translation id="7445762425076701745">无法完全验证您所连接到的服务器的身份。您在连接服务器时使用的服务器名称仅在您的网络中有效,而外部证书授权中心无法验证该名称的所有权。由于一些证书授权中心仍然会为这些名称颁发证书,因此无法确保您连接到想要访问的网站而不是攻击网站。</translation>
-<translation id="7449109375006139765">将系统日志发送到管理服务器</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />详细了解<ph name="END_LINK" />此问题。</translation>
<translation id="7455133967321480974">使用全局默认设置(阻止)</translation>
<translation id="7460618730930299168">此处显示的放映时间不同于您的选择。继续?</translation>
<translation id="7473891865547856676">不,谢谢</translation>
-<translation id="7475525192983021547">报告用户在设备上处于活跃状态的时间段</translation>
<translation id="7481312909269577407">前进</translation>
<translation id="7485870689360869515">找不到数据。</translation>
+<translation id="7498234416455752244">继续修改</translation>
<translation id="7508255263130623398">返回的政策设备 ID 为空,或与当前的设备 ID 不一致</translation>
<translation id="7508870219247277067">黄绿色</translation>
<translation id="7511955381719512146">您要使用的 Wi-Fi 网络可能需要您访问 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
<translation id="7514365320538308">下载</translation>
<translation id="7518003948725431193">找不到与以下网址对应的网页:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (Envelope)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">您与此网站的连接不是私密连接</translation>
+<translation id="7535087603100972091">值</translation>
<translation id="7537536606612762813">强制</translation>
+<translation id="7538364083937897561">A2 (Envelope)</translation>
<translation id="7542403920425041731">一旦您予以确认,系统便会将您的信用卡详情共享给此网站。</translation>
<translation id="7542995811387359312">由于该表单不使用安全连接,因此自动填写信用卡信息的功能已停用。</translation>
<translation id="7543525346216957623">请先征得您父亲/母亲的许可</translation>
@@ -1032,8 +1165,8 @@
<translation id="7552846755917812628">请尝试按以下提示操作:</translation>
<translation id="7554791636758816595">新标签页</translation>
<translation id="7564049878696755256">您可能会无法再访问自己的 <ph name="ORG_NAME" /> 帐号,或者身份信息遭到盗用。Chrome 建议您立即更改密码。</translation>
-<translation id="7566125604157659769">您复制的文字</translation>
<translation id="7567204685887185387">此服务器无法证明它是<ph name="DOMAIN" />;其安全证书可能是由骗子发出的。出现此问题的原因可能是配置有误或您的连接被拦截了。</translation>
+<translation id="7568105740864181217">此浏览器由某个公司、学校或其他组织管理。您的管理员可以远程更改您的浏览器设置。此设备上的活动也可能会在 Chrome 外部受管理。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">从 Chrome 中移除信用卡信息?</translation>
<translation id="7569983096843329377">黑色</translation>
<translation id="7578104083680115302">通过各种设备在网站和应用中购物时,您都可以使用 Google 为您保存的银行卡信息快速付款。</translation>
@@ -1044,6 +1177,7 @@
<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="7633909222644580952">性能数据和崩溃报告</translation>
<translation id="7637571805876720304">要从 Chromium 中移除信用卡吗?</translation>
<translation id="7639968568612851608">深灰色</translation>
<translation id="765676359832457558">隐藏高级设置...</translation>
@@ -1053,9 +1187,11 @@
<translation id="7667346355482952095">返回的政策令牌为空或与当前令牌不匹配</translation>
<translation id="7668654391829183341">未知设备</translation>
<translation id="7669271284792375604">此网站上的攻击者可能会试图诱骗您安装有损浏览体验的程序(例如:通过更改您的主页或在您访问的网站上显示额外的广告)。</translation>
+<translation id="7676643023259824263">搜索剪贴板上的文字:<ph name="TEXT" /></translation>
<translation id="7681101578153515023">更改搜索引擎</translation>
<translation id="7682287625158474539">送货地址</translation>
<translation id="7687186412095877299">在付款表单中填入已保存的付款方式</translation>
+<translation id="7697066736081121494">Prc8 (Envelope)</translation>
<translation id="769721561045429135">此刻,您有一些卡只能在这部设备上使用。点击“继续”即可查看这些卡。</translation>
<translation id="7699293099605015246">目前没有文章可显示</translation>
<translation id="7701040980221191251">无</translation>
@@ -1067,11 +1203,13 @@
<translation id="774634243536837715">危险内容已被拦截。</translation>
<translation id="7752995774971033316">非托管</translation>
<translation id="7755287808199759310">您的父亲/母亲可为您取消屏蔽此网站</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">防火墙或防病毒软件可能已阻止您连接到网络。</translation>
<translation id="7759163816903619567">显示网域:</translation>
<translation id="7761701407923456692">服务器的证书与网址不相符。</translation>
<translation id="7763386264682878361">付款清单解析器</translation>
<translation id="7764225426217299476">添加地址</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">县</translation>
<translation id="7791543448312431591">添加</translation>
<translation id="7793809570500803535">网址为 <ph name="SITE" /> 的网页可能暂时无法连接或已永久性地移动到了新网址。</translation>
@@ -1083,8 +1221,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">从 Chrome 中移除表单建议?</translation>
<translation id="7815407501681723534">找到了 <ph name="NUMBER_OF_RESULTS" /> 个与“<ph name="SEARCH_STRING" />”相符的<ph name="SEARCH_RESULTS" /></translation>
-<translation id="7818867226424560206">政策管理</translation>
<translation id="782886543891417279">您要使用的 Wi-Fi 网络(<ph name="WIFI_NAME" />)可能需要您访问其登录页面。</translation>
+<translation id="7836231406687464395">Postfix (Envelope)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{无}=1{1 个应用(<ph name="EXAMPLE_APP_1" />)}=2{2 个应用(<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />)}other{# 个应用(<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />、<ph name="AND_MORE" />)}}</translation>
<translation id="785549533363645510">但是,这并不意味着您能完全隐身。即使您进入隐身模式,您的雇主、互联网服务提供商和您访问的网站仍然能看到您的浏览活动。</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1093,7 +1231,7 @@
<translation id="7878562273885520351">您的密码可能会被盗用</translation>
<translation id="7882421473871500483">棕色</translation>
<translation id="7887683347370398519">请检查您的银行卡验证码 (CVC),然后重试</translation>
-<translation id="7893255318348328562">会话名称</translation>
+<translation id="7904208859782148177">C3 (Envelope)</translation>
<translation id="79338296614623784">请输入有效的电话号码</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">到期时间:<ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1103,21 +1241,25 @@
<translation id="7951415247503192394">(32 位)</translation>
<translation id="7956713633345437162">移动设备书签</translation>
<translation id="7961015016161918242">一律不</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">未指定</translation>
<translation id="800218591365569300">请尝试关闭其他标签页或程序以释放内存。</translation>
+<translation id="8004582292198964060">浏览器</translation>
<translation id="8009225694047762179">管理密码</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{这张卡及其帐单邮寄地址将被保存。登录 <ph name="USER_EMAIL" /> 后即可使用这张卡。}other{这些卡及其帐单邮寄地址将被保存。登录 <ph name="USER_EMAIL" /> 后即可使用这些卡。}}</translation>
<translation id="8012647001091218357">我们暂时无法与您父母取得联系,请重试。</translation>
<translation id="8025119109950072390">此网站上的攻击者可能会诱骗您做出一些诸如安装软件或泄露个人信息(例如:密码、电话号码或信用卡信息)之类的危险事情。</translation>
<translation id="8034522405403831421">此网页的源语言为<ph name="SOURCE_LANGUAGE" />,要将其翻译成<ph name="TARGET_LANGUAGE" />吗?</translation>
<translation id="8035152190676905274">钢笔</translation>
+<translation id="8037117624646282037">最近使用过这部设备的用户</translation>
<translation id="8037357227543935929">询问(默认)</translation>
<translation id="803771048473350947">文件</translation>
<translation id="8041089156583427627">发送反馈</translation>
<translation id="8041940743680923270">使用全局默认设置(询问)</translation>
<translation id="8042918947222776840">选择取货方式</translation>
<translation id="8057711352706143257">“<ph name="SOFTWARE_NAME" />”的配置有误。卸载“<ph name="SOFTWARE_NAME" />”通常可解决此问题。<ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">您的设备已被配置为:</translation>
+<translation id="8066955247577885446">抱歉,出了点问题。</translation>
+<translation id="8074253406171541171">10x13 (Envelope)</translation>
<translation id="8078141288243656252">无法在旋转后添加注释</translation>
<translation id="8079031581361219619">重新加载此网站?</translation>
<translation id="8088680233425245692">无法查看文章。</translation>
@@ -1126,11 +1268,12 @@
<translation id="8091372947890762290">正等待在服务器上激活</translation>
<translation id="8092774999298748321">深紫色</translation>
<translation id="8094917007353911263">您要使用的网络可能需要您访问 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">无效的卡已被移除</translation>
<translation id="8103161714697287722">付款方式</translation>
<translation id="8118489163946903409">付款方式</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> 由 <ph name="ENROLLMENT_DOMAIN" /> 管理</translation>
<translation id="8127301229239896662">“<ph name="SOFTWARE_NAME" />”没有正确地安装到您的计算机或网络上。请让您的 IT 管理员解决此问题。</translation>
-<translation id="8130693978878176684">我已无法再提供帮助,接下来请自行操作。</translation>
<translation id="8131740175452115882">确认</translation>
<translation id="8149426793427495338">您的计算机已进入休眠模式。</translation>
<translation id="8150722005171944719">无法读取 <ph name="URL" /> 上的文件。该文件可能已遭到删除、移动,或者文件权限不允许进行访问。</translation>
@@ -1140,8 +1283,11 @@
<translation id="8197543752516192074">翻译网页</translation>
<translation id="8201077131113104583">ID 为“<ph name="EXTENSION_ID" />”的扩展程序的更新网址无效。</translation>
<translation id="8202097416529803614">订单摘要</translation>
+<translation id="8202370299023114387">冲突</translation>
+<translation id="8206978196348664717">Prc4 (Envelope)</translation>
<translation id="8211406090763984747">连接是安全的</translation>
<translation id="8218327578424803826">分配的位置:</translation>
+<translation id="8220146938470311105">C7/C6 (Envelope)</translation>
<translation id="8225771182978767009">设置此计算机的用户已选择屏蔽此网站。</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />、<ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">在新的无痕式标签页中打开网页</translation>
@@ -1153,14 +1299,16 @@
<translation id="825929999321470778">显示所有已保存的密码</translation>
<translation id="8261506727792406068">删除</translation>
<translation id="8267698848189296333">目前登录的帐号是 <ph name="USERNAME" /></translation>
+<translation id="8278457561961988242">此浏览器由 <ph name="ENROLLMENT_DOMAIN" /> 管理。您的管理员可以远程更改您的浏览器设置。此设备上的活动也可能会在 Chrome 外部受管理。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">登录</translation>
<translation id="8288807391153049143">显示证书</translation>
<translation id="8289355894181816810">如果您不确定这是什么意思,请与您的网络管理员联系。</translation>
<translation id="8293206222192510085">添加书签</translation>
<translation id="8294431847097064396">来源</translation>
<translation id="8298115750975731693">您要使用的 Wi-Fi 网络(<ph name="WIFI_NAME" />)可能需要您访问 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">由于网络连接问题,翻译失败。</translation>
-<translation id="8311129316111205805">加载会话</translation>
<translation id="8332188693563227489">访问 <ph name="HOST_NAME" /> 的请求遭到拒绝</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">如果您了解自己将面临的安全风险,则可以在有害程序被清除之前<ph name="BEGIN_LINK" />访问此网站<ph name="END_LINK" />。</translation>
@@ -1178,7 +1326,6 @@
<translation id="8416694386774425977">网络配置无效,因此无法导入。
更多详情:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">设备由 <ph name="ENROLLMENT_DOMAIN" /> 管理</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> - <ph name="SECOND_LABEL" /> - <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">更改</translation>
<translation id="8428213095426709021">设置</translation>
@@ -1206,9 +1353,11 @@
<translation id="860043288473659153">持卡人姓名</translation>
<translation id="861775596732816396">大小:4</translation>
<translation id="8620436878122366504">您的父母尚未批准此请求</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">将此卡的信息保存到该设备</translation>
<translation id="8663226718884576429">订单摘要,<ph name="TOTAL_LABEL" />,更多详情</translation>
<translation id="8680536109547170164"><ph name="QUERY" />,答案,<ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">您与 <ph name="DOMAIN" /> 的连接未加密。</translation>
<translation id="8718314106902482036">未能完成付款</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />,<ph name="DESCRIPTION" />,搜索建议</translation>
@@ -1222,6 +1371,7 @@
<translation id="8761567432415473239">Google安全浏览功能最近在<ph name="SITE" />上<ph name="BEGIN_LINK" />发现了有害程序<ph name="END_LINK" />。</translation>
<translation id="8763927697961133303">USB 设备</translation>
<translation id="8768895707659403558">要在所有设备上使用您的卡,请<ph name="SIGN_IN_LINK" />。</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">恢复删除(&amp;R)</translation>
<translation id="8792621596287649091">您可能会无法再访问自己的 <ph name="ORG_NAME" /> 帐号,或者身份信息遭到盗用。Chromium 建议您立即更改密码。</translation>
<translation id="8800988563907321413">此处将显示系统建议您浏览的附近网页</translation>
@@ -1232,10 +1382,12 @@
<translation id="885730110891505394">与 Google 分享</translation>
<translation id="8858065207712248076">如果您在其他网站上重复使用了您的 <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> 密码,Chrome 建议您重置该密码。</translation>
<translation id="8866481888320382733">解析策略设置时出错</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">最近关闭的标签页</translation>
<translation id="8874824191258364635">请输入有效的信用卡号</translation>
<translation id="8891727572606052622">代理模式无效。</translation>
<translation id="8903921497873541725">放大</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">要将此卡的信息保存到您的 Google 帐号吗?</translation>
<translation id="8932102934695377596">您的时钟慢了</translation>
<translation id="893332455753468063">添加名称</translation>
@@ -1243,13 +1395,13 @@
<translation id="894185898663964645">您的管理员配置了自定义根证书,这些证书可能会允许管理员查看您所访问的网站的内容。</translation>
<translation id="8943282376843390568">绿黄色</translation>
<translation id="8957210676456822347">强制门户授权</translation>
+<translation id="8966619695390250636">您是想?</translation>
<translation id="8968766641738584599">保存卡片</translation>
<translation id="8971063699422889582">服务器的证书已过期。</translation>
<translation id="8975012916872825179">包括电话号码、电子邮件地址和送货地址等信息</translation>
<translation id="8978053250194585037">Google 安全浏览功能最近在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />检测到网上诱骗行为<ph name="END_LINK" />。网上诱骗网站会假冒其他网站来欺骗您。</translation>
<translation id="8983003182662520383">Google Pay 中存储的付款方式和地址信息</translation>
<translation id="8987927404178983737">月</translation>
-<translation id="8988408250700415532">出了点问题。您可在相应网站上完成订单。</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">您要访问的网站包含有害程序</translation>
<translation id="8997023839087525404">该服务器提供了一个未通过证书透明度政策公开披露的证书。某些证书必须通过证书透明度政策进行公开披露,以确保它们值得信任且能保护用户免遭攻击。</translation>
@@ -1259,6 +1411,7 @@
<translation id="9011424611726486705">打开网站设置</translation>
<translation id="9020200922353704812">必须输入信用卡帐单邮寄地址</translation>
<translation id="9020542370529661692">已将此网页内容翻译成<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(无效)</translation>
<translation id="9035022520814077154">安全错误</translation>
<translation id="9038649477754266430">使用联想查询服务更快速地加载网页</translation>
@@ -1270,11 +1423,11 @@
<translation id="9065745800631924235">在历史记录中搜索<ph name="TEXT" /></translation>
<translation id="9069693763241529744">已被某款扩展程序阻止</translation>
<translation id="9076283476770535406">此网站可能包含成人内容</translation>
+<translation id="9076630408993835509">此浏览器不由某个公司或其他组织管理。此设备上的活动可能会在 Chrome 外部受管理。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">必须提供更多信息</translation>
<translation id="9080712759204168376">订单摘要</translation>
<translation id="9103872766612412690"><ph name="SITE" /> 通常会使用加密技术来保护您的信息。Chromium 此次尝试连接到 <ph name="SITE" /> 时,此网站发回了异常的错误凭据。这可能是因为有攻击者在试图冒充 <ph name="SITE" />,或 Wi-Fi 登录屏幕中断了此次连接。请放心,您的信息仍然是安全的,因为 Chromium 尚未进行任何数据交换便停止了连接。</translation>
<translation id="9106062320799175032">添加帐单邮寄地址</translation>
-<translation id="9110718169272311511">Chrome 中的 Google 助理位于屏幕底部附近</translation>
<translation id="9114524666733003316">正在确认信用卡…</translation>
<translation id="9128870381267983090">连接到网络</translation>
<translation id="9137013805542155359">显示原始网页</translation>
@@ -1283,6 +1436,7 @@
<translation id="9148507642005240123">撤消修改(&amp;U)</translation>
<translation id="9154194610265714752">已更新</translation>
<translation id="9157595877708044936">正在设置...</translation>
+<translation id="9158625974267017556">C6 (Envelope)</translation>
<translation id="9168814207360376865">允许网站检查您是否已保存付款方式</translation>
<translation id="9169664750068251925">在此网站上始终阻止</translation>
<translation id="9170848237812810038">撤消(&amp;U)</translation>
@@ -1297,10 +1451,12 @@
<translation id="9219103736887031265">图片</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">清除表单内容</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">您可能会无法再访问自己的 Google 帐号。Chromium 建议您立即更改密码。系统会要求您登录。</translation>
<translation id="939736085109172342">新建文件夹</translation>
<translation id="945855313015696284">请查看下面的信息,并删除所有无效卡片</translation>
<translation id="951104842009476243">接受的借记卡和预付卡</translation>
+<translation id="958202389743790697">已被屏蔽,依据是 <ph name="ORIGIN" /> 的安全政策。</translation>
<translation id="962484866189421427">此内容可能会尝试安装欺骗性应用,而这些应用能够冒充其他内容或收集可用于对您进行跟踪的数据。<ph name="BEGIN_LINK" />仍然显示<ph name="END_LINK" /></translation>
<translation id="969892804517981540">正式版本</translation>
<translation id="973773823069644502">添加速递地址</translation>
@@ -1309,6 +1465,7 @@
<translation id="984275831282074731">付款方式</translation>
<translation id="985199708454569384">&lt;p&gt;如果您的计算机或移动设备的日期与时间不准确,您就会看到这条错误消息。&lt;/p&gt;
&lt;p&gt;要修正该错误,请打开您设备的时钟,并确保日期与时间正确无误。&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">开发者内部版本</translation>
<translation id="989988560359834682">修改地址</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/strings/components_strings_zh-TW.xtb b/chromium/components/strings/components_strings_zh-TW.xtb
index eca9ceac738..51c62c404df 100644
--- a/chromium/components/strings/components_strings_zh-TW.xtb
+++ b/chromium/components/strings/components_strings_zh-TW.xtb
@@ -1,7 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-TW">
-<translation id="1005145902654145231">無法重新命名工作階段。</translation>
<translation id="1008557486741366299">現在不要</translation>
<translation id="1010200102790553230">稍後再載入頁面</translation>
<translation id="1015730422737071372">提供其他詳細資訊</translation>
@@ -11,11 +10,14 @@
<translation id="1038842779957582377">不明名稱</translation>
<translation id="1050038467049342496">關閉其他應用程式</translation>
<translation id="1055184225775184556">復原新增(&amp;U)</translation>
+<translation id="1056898198331236512">警告</translation>
<translation id="1058479211578257048">正在儲存卡片...</translation>
<translation id="10614374240317010">一律不儲存</translation>
+<translation id="1062160989074299343">Prc10 (信封)</translation>
<translation id="106701514854093668">電腦版書籤</translation>
<translation id="1074497978438210769">不安全</translation>
<translation id="1080116354587839789">符合視窗寬度</translation>
+<translation id="1086953900555227778">Index-5x8</translation>
<translation id="1088860948719068836">新增持卡人姓名</translation>
<translation id="1089439967362294234">變更密碼</translation>
<translation id="109743633954054152">在 Chrome 設定中管理密碼</translation>
@@ -27,6 +29,7 @@
<translation id="1125573121925420732">網站更新安全性設定期間,可能會經常顯示警告。這項行為將於近期內改善。</translation>
<translation id="1126551341858583091">佔用的本機儲存空間大小:<ph name="CRASH_SIZE" />。</translation>
<translation id="112840717907525620">政策快取正確</translation>
+<translation id="1131264053432022307">你複製的圖片</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>
@@ -34,7 +37,6 @@
<translation id="1158211211994409885"><ph name="HOST_NAME" /> 意外中斷連線。</translation>
<translation id="1161325031994447685">重新連線至 Wi-Fi 網路</translation>
<translation id="1165039591588034296">錯誤</translation>
-<translation id="1173894706177603556">重新命名</translation>
<translation id="1175364870820465910">列印(&amp;P)...</translation>
<translation id="1181037720776840403">移除</translation>
<translation id="1197088940767939838">橘色</translation>
@@ -45,9 +47,9 @@
<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="1240347957665416060">你的裝置名稱</translation>
<translation id="124116460088058876">更多語言</translation>
<translation id="1250759482327835220">只要將你的卡片資訊、姓名與帳單地址儲存到你的 Google 帳戶中,下次即可更快完成付款程序。</translation>
<translation id="1253921432148366685"><ph name="TYPE_1" />、<ph name="TYPE_2" /> (已同步)</translation>
@@ -66,7 +68,8 @@
<translation id="1294154142200295408">命令列變化版本</translation>
<translation id="129553762522093515">最近關閉的分頁</translation>
<translation id="129863573139666797"><ph name="BEGIN_LINK" />試試看清除 Cookie<ph name="END_LINK" /></translation>
-<translation id="1314614906530272393">你所選的工作階段不存在。</translation>
+<translation id="1320233736580025032">Prc1 (信封)</translation>
+<translation id="132301787627749051">搜尋剪貼簿圖片</translation>
<translation id="1323433172918577554">顯示完整清單</translation>
<translation id="132390688737681464">儲存及填入地址</translation>
<translation id="1333989956347591814">以下各方<ph name="BEGIN_EMPHASIS" />可能仍會看到<ph name="END_EMPHASIS" />你的活動:
@@ -79,12 +82,19 @@
<translation id="1340482604681802745">取件地址</translation>
<translation id="1348198688976932919">你要造訪的網站含有不安全的應用程式</translation>
<translation id="1348779747280417563">確認姓名</translation>
+<translation id="1357195169723583938">最近使用過裝置的使用者及其使用時間</translation>
+<translation id="1364822246244961190">這項政策遭到封鎖,系統會忽略其設定值。</translation>
<translation id="1374468813861204354">建議</translation>
+<translation id="1374692235857187091">Index-4x6 (明信片)</translation>
<translation id="1375198122581997741">關於版本</translation>
<translation id="1376836354785490390">顯示較少</translation>
<translation id="1377321085342047638">卡號</translation>
<translation id="138218114945450791">淺藍色</translation>
+<translation id="1382194467192730611">系統管理員允許使用的 USB 裝置</translation>
<translation id="139305205187523129"><ph name="HOST_NAME" /> 未傳送任何資料。</translation>
+<translation id="140316286225361634"><ph name="ORIGIN" /> 這個網站要求為其所有要求套用
+ 安全性政策,而這項政策目前判定該網站
+ 不安全。</translation>
<translation id="1405567553485452995">淺綠色</translation>
<translation id="1407135791313364759">全部開啟</translation>
<translation id="1413809658975081374">隱私權設定發生錯誤</translation>
@@ -92,9 +102,12 @@
<translation id="1426410128494586442">是</translation>
<translation id="1430915738399379752">列印</translation>
<translation id="1455413310270022028">橡皮擦</translation>
+<translation id="1463543813647160932">5x7</translation>
+<translation id="1472675084647422956">顯示更多</translation>
+<translation id="147358896496811705">2A0</translation>
<translation id="1484290072879560759">選擇運送地址</translation>
+<translation id="1492194039220927094">政策通知推送:</translation>
<translation id="1501859676467574491">顯示你 Google 帳戶中的卡片</translation>
-<translation id="1506687042165942984">顯示這個網頁的儲存複本 (亦即現已不再使用的版本)。</translation>
<translation id="1507202001669085618">&lt;p&gt;如果您使用的 Wi-Fi 入口網站必須先登入才能連上網路,系統就會顯示這則錯誤訊息。&lt;/p&gt;
&lt;p&gt;如要修正這個錯誤,請在您要嘗試開啟的網頁上按一下 [連線]&lt;strong&gt;&lt;/strong&gt;。&lt;/p&gt;</translation>
<translation id="1517433312004943670">必須輸入電話號碼</translation>
@@ -102,23 +115,27 @@
<translation id="1519264250979466059">建立日期</translation>
<translation id="1521655867290435174">Google 試算表</translation>
<translation id="1527263332363067270">正在等待連線…</translation>
+<translation id="1529521330346880926">10x15 (信封)</translation>
+<translation id="1531205177818805254">Exec</translation>
<translation id="1532118530259321453">這個網頁顯示</translation>
<translation id="153384715582417236">暫無內容</translation>
<translation id="154408704832528245">選擇快遞地址</translation>
<translation id="1549470594296187301">您必須啟用 JavaScript 才能使用這項功能。</translation>
+<translation id="155039086686388498">Engineering-D</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="1569487616857761740">輸入到期日</translation>
<translation id="1581080074034554886">CVC</translation>
<translation id="1583429793053364125">顯示這個網頁時發生錯誤。</translation>
<translation id="1592005682883173041">本機資料存取權</translation>
<translation id="1594030484168838125">選擇</translation>
<translation id="161042844686301425">青色</translation>
-<translation id="1618822247301510817">你複製的圖片</translation>
<translation id="1620510694547887537">攝影機</translation>
<translation id="1623104350909869708">防止這個網頁產生其他對話方塊</translation>
+<translation id="16338877384480380">Architecture-B</translation>
<translation id="1634051627998691300">結束工作階段</translation>
<translation id="1639239467298939599">載入中</translation>
<translation id="1640180200866533862">使用者政策</translation>
@@ -133,8 +150,10 @@
<translation id="1676269943528358898"><ph name="SITE" /> 通常使用加密方式保護您的資訊。但 Google Chrome 這次嘗試連線到 <ph name="SITE" /> 時,該網站傳回了異常且錯誤的憑證。這可能是因為有攻擊者企圖偽裝成 <ph name="SITE" />,或是受到 Wi-Fi 登入畫面影響而造成連線中斷。不過請放心,Google Chrome 已及時停止連線,並未傳輸任何資料,因此您的資訊仍然安全無虞。</translation>
<translation id="168841957122794586">伺服器憑證含有防護力薄弱的加密編譯金鑰。</translation>
<translation id="1697532407822776718">大功告成!</translation>
+<translation id="1703835215927279855">Letter</translation>
<translation id="1706954506755087368">{1,plural, =1{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證預定明天才生效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。}other{這個伺服器無法證明所在網域是 <ph name="DOMAIN" />;伺服器的安全性憑證預定 # 天後才生效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線。}}</translation>
<translation id="1710259589646384581">作業系統</translation>
+<translation id="1715874602234207">F</translation>
<translation id="1718029547804390981">文件過大,無法加註</translation>
<translation id="1721312023322545264">你必須獲得<ph name="NAME" />授權,才能造訪這個網站</translation>
<translation id="1721424275792716183">* 這是必填欄位</translation>
@@ -145,6 +164,7 @@
<translation id="1734878702283171397">建議您與系統管理員聯絡。</translation>
<translation id="1740951997222943430">請輸入有效的到期月份</translation>
<translation id="1743520634839655729">只要將你的卡片資訊、姓名與帳單地址儲存到你的 Google 帳戶中和這部裝置上,下次即可更快完成付款程序。</translation>
+<translation id="1745880797583122200">你的瀏覽器受到管理</translation>
<translation id="17513872634828108">開啟的分頁</translation>
<translation id="1753706481035618306">頁碼</translation>
<translation id="1763864636252898013">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得你裝置作業系統的信任。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
@@ -152,8 +172,10 @@
<translation id="1783075131180517613">請更新你的同步通關密語。</translation>
<translation id="1787142507584202372">這裡會顯示你最近開啟的分頁</translation>
<translation id="1791429645902722292">Google Smart Lock</translation>
+<translation id="1800473098294731951">B9</translation>
<translation id="1803264062614276815">持卡人姓名</translation>
<translation id="1821930232296380041">要求或要求參數無效</translation>
+<translation id="1822540298136254167">你造訪的網站和瀏覽時間</translation>
<translation id="1826516787628120939">檢查中</translation>
<translation id="1834321415901700177">這個網站含有有害程式</translation>
<translation id="1839551713262164453">發生錯誤,政策值驗證失敗</translation>
@@ -180,6 +202,10 @@
<translation id="1981206234434200693">清除 Chrome 的瀏覽記錄資料</translation>
<translation id="2001146170449793414">{COUNT,plural, =1{以及另外 1 個應用程式}other{以及另外 # 個應用程式}}</translation>
<translation id="2003709556000175978">立即重設你的密碼</translation>
+<translation id="20053308747750172">你的目標伺服器「<ph name="ORIGIN" />」要求為其收到的所有要求
+ 套用安全性政策。不過,由於該伺服器
+ 目前提供的政策無效,因此瀏覽器無法完成你向
+ 「<ph name="SITE" />」提出的要求。</translation>
<translation id="2025186561304664664">Proxy 已設為自動設定。</translation>
<translation id="2030481566774242610">你要找的是 <ph name="LINK" /> 嗎?</translation>
<translation id="2032962459168915086"><ph name="BEGIN_LINK" />檢查 Proxy 和防火牆<ph name="END_LINK" /></translation>
@@ -196,6 +222,7 @@
<translation id="2096368010154057602">部門</translation>
<translation id="2102134110707549001">建議高強度密碼…</translation>
<translation id="2108755909498034140">重新啟動電腦</translation>
+<translation id="2111256659903765347">Super-A</translation>
<translation id="2113977810652731515">信用卡</translation>
<translation id="2114841414352855701">由於政策被「<ph name="POLICY_NAME" />」覆寫了,因此遭到略過。</translation>
<translation id="213826338245044447">行動版書籤</translation>
@@ -206,6 +233,7 @@
<translation id="2154484045852737596">編輯卡片資訊</translation>
<translation id="2166049586286450108">完整管理員存取權</translation>
<translation id="2166378884831602661">這個網站無法提供安全連線</translation>
+<translation id="2169984857010174799">Kaku2 (信封)</translation>
<translation id="2181821976797666341">政策</translation>
<translation id="2183608646556468874">電話號碼</translation>
<translation id="2184405333245229118">{COUNT,plural, =1{1 個地址}other{# 個地址}}</translation>
@@ -223,11 +251,15 @@
<translation id="2270484714375784793">電話號碼</translation>
<translation id="2283340219607151381">儲存及填入地址</translation>
<translation id="2292556288342944218">您的網際網路存取權遭到封鎖</translation>
+<translation id="2294558542833290837">你原先開啟的連結有異常之處</translation>
+<translation id="2297722699537546652">B5 (信封)</translation>
+<translation id="2310021320168182093">Chou2 (信封)</translation>
<translation id="2316887270356262533">釋出不到 1 MB。下次造訪部分網站時,載入速度可能會變慢。</translation>
<translation id="2317259163369394535"><ph name="DOMAIN" /> 要求提供使用者名稱和密碼。</translation>
<translation id="2317583587496011522">接受簽帳金融卡。</translation>
<translation id="2330137317877982892"><ph name="CREDIT_CARD" />,到期日:<ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="2337852623177822836">管理員所控制的設定</translation>
+<translation id="2346319942568447007">你複製的圖片</translation>
<translation id="2349790679044093737">VR 工作階段執行中</translation>
<translation id="2354001756790975382">其他書籤</translation>
<translation id="2354430244986887761">Google 安全瀏覽服務最近在 <ph name="SITE" /> <ph name="BEGIN_LINK" />發現有害的應用程式<ph name="END_LINK" />。</translation>
@@ -239,29 +271,37 @@
<translation id="2365563543831475020">當機報告擷取時間:<ph name="CRASH_TIME" /> (尚未上傳)</translation>
<translation id="2367567093518048410">等級</translation>
<translation id="2378238891085281592">你已啟用私密模式</translation>
+<translation id="2380886658946992094">Legal</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="2410754574180102685">Government-Legal</translation>
<translation id="2413528052993050574">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證已遭撤銷。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
+<translation id="2418081434543109369">你的目標伺服器「<ph name="ORIGIN" />」要求為其收到的所有要求
+ 套用安全性政策。不過,由於該伺服器
+ 目前並未提供政策,因此瀏覽器無法完成你向
+ 「<ph name="SITE" />」提出的要求。</translation>
<translation id="244665789865330679">你的裝置和帳戶是由 <ph name="ENROLLMENT_DOMAIN" /> 管理,這表示你的系統管理員可以從遠端設定你的裝置和帳戶。</translation>
<translation id="2463193859425327265">變更首頁</translation>
<translation id="2463739503403862330">填入</translation>
+<translation id="2465402087343596252">Architecture-E</translation>
<translation id="2465655957518002998">選擇快遞方式</translation>
<translation id="2467694685043708798"><ph name="BEGIN_LINK" />執行網路診斷<ph name="END_LINK" /></translation>
<translation id="2473195200299095979">翻譯這個網頁</translation>
<translation id="2479410451996844060">無效的搜尋網址。</translation>
<translation id="2482878487686419369">通知</translation>
<translation id="248348093745724435">裝置政策</translation>
+<translation id="2485387744899240041">你在裝置和瀏覽器中的使用者名稱</translation>
<translation id="2491120439723279231">伺服器憑證含有錯誤。</translation>
+<translation id="2493640343870896922">Letter-Plus</translation>
<translation id="2495083838625180221">JSON 剖析器</translation>
<translation id="2495093607237746763">勾選後,Chromium 會將您的信用卡資料儲存在這個裝置上,以加快表單填寫速度。</translation>
<translation id="2498091847651709837">掃描新信用卡</translation>
<translation id="2501278716633472235">返回</translation>
<translation id="2503184589641749290">接受的簽帳金融卡和預付卡</translation>
<translation id="2515629240566999685">檢查所在位置的網路訊號</translation>
-<translation id="2516852381693169964">透過 <ph name="SEARCH_ENGINE" /> 搜尋圖片</translation>
<translation id="2523886232349826891">僅儲存在這部裝置</translation>
<translation id="2524461107774643265">新增詳細資訊</translation>
<translation id="2536110899380797252">新增地址</translation>
@@ -273,6 +313,7 @@
<translation id="2587841377698384444">Directory API ID:</translation>
<translation id="2597378329261239068">此文件受到密碼保護,請輸入密碼。</translation>
<translation id="2609632851001447353">變化版本</translation>
+<translation id="2618023639789766142">C10 (信封)</translation>
<translation id="2625385379895617796">你的時鐘時間過快</translation>
<translation id="2634124572758952069">找不到 <ph name="HOST_NAME" /> 的伺服器 IP 位址。</translation>
<translation id="2639739919103226564">狀態:</translation>
@@ -282,7 +323,9 @@
<translation id="2666117266261740852">關閉其他分頁或應用程式</translation>
<translation id="267371737713284912">按下 <ph name="MODIFIER_KEY_DESCRIPTION" /> 即可復原</translation>
<translation id="2674170444375937751">確定要從你的記錄中刪除這些網頁嗎?</translation>
+<translation id="2676271551327853224">Roc-8K</translation>
<translation id="2677748264148917807">離開</translation>
+<translation id="2684561033061424857">11x12</translation>
<translation id="2699302886720511147">接受的卡片</translation>
<translation id="2702801445560668637">閱讀清單</translation>
<translation id="2704283930420550640">政策值格式不符。</translation>
@@ -299,7 +342,6 @@
<translation id="2742870351467570537">移除選取的項目</translation>
<translation id="277133753123645258">運送方式</translation>
<translation id="277499241957683684">沒有裝置記錄</translation>
-<translation id="2781030394888168909">匯出 MacOS</translation>
<translation id="2781692009645368755">Google Pay</translation>
<translation id="2784949926578158345">連線已重設。</translation>
<translation id="2788784517760473862">接受的信用卡</translation>
@@ -311,8 +353,10 @@
<translation id="2826760142808435982">連線採用 <ph name="CIPHER" /> 加密,並設有 <ph name="KX" /> 金鑰交換機制。</translation>
<translation id="2835170189407361413">清除表單</translation>
<translation id="2847118875340931228">開啟無痕式視窗</translation>
+<translation id="2850739647070081192">Invite (信封)</translation>
<translation id="2851634818064021665">你必須獲得授權,才能造訪這個網站</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="2878424575911748999">A1</translation>
<translation id="2881276955470682203">要儲存卡片嗎?</translation>
<translation id="2903493209154104877">地址</translation>
<translation id="290376772003165898">不是<ph name="LANGUAGE" />網頁嗎?</translation>
@@ -322,6 +366,7 @@
<translation id="2925673989565098301">快遞方式</translation>
<translation id="2928905813689894207">帳單地址</translation>
<translation id="2929525460561903222">{SHIPPING_ADDRESS,plural, =0{<ph name="SHIPPING_ADDRESS_PREVIEW" />}=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="2934466151127459956">Government-Letter</translation>
<translation id="2941952326391522266">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證來自 <ph name="DOMAIN2" /> 網域。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
<translation id="2948083400971632585">你可以在設定頁面停用任何為連線設置的 Proxy。</translation>
<translation id="2955913368246107853">關閉搜尋列</translation>
@@ -338,11 +383,14 @@
<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="3023071826883856138">You4 (信封)</translation>
<translation id="3024663005179499861">政策類型有誤</translation>
<translation id="3037605927509011580">糟糕!</translation>
<translation id="3041612393474885105">憑證資訊</translation>
+<translation id="3060227939791841287">C9 (信封)</translation>
<translation id="3064966200440839136">即將離開無痕模式,改為使用外部應用程式付款,要繼續嗎?</translation>
<translation id="3083099961703215236">{COUNT,plural, =0{無}=1{1 組密碼}other{# 組密碼}}</translation>
+<translation id="3095940652251934233">Statement</translation>
<translation id="3096100844101284527">新增取件地址</translation>
<translation id="3105172416063519923">資產 ID:</translation>
<translation id="3109728660330352905">您未獲得授權,無法瀏覽這個網頁。</translation>
@@ -364,20 +412,21 @@
<translation id="3195213714973468956"><ph name="SERVER_NAME" /> 上的 <ph name="PRINTER_NAME" /></translation>
<translation id="320323717674993345">取消付款</translation>
<translation id="3207960819495026254">已加入書籤</translation>
-<translation id="3209375525920864198">請輸入有效的工作階段名稱。</translation>
+<translation id="321912867715453276">警告:這項政策有多個來源,但來源的值都相同。</translation>
<translation id="3225919329040284222">伺服器呈現的憑證與內建的預期條件不符。我們在系統中針對特定高安全性的網站內建了這些預期條件,目的在於保護你的資料安全無虞。</translation>
<translation id="3226128629678568754">按下重新載入按鈕,重新提交載入網頁所需的資料。</translation>
<translation id="3227137524299004712">麥克風</translation>
<translation id="3228969707346345236">網頁已經是<ph name="LANGUAGE" />,翻譯作業失敗。</translation>
+<translation id="3229041911291329567">裝置和瀏覽器的版本資訊</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="3274521967729236597">Pa-Kai</translation>
<translation id="3282497668470633863">新增持卡人姓名</translation>
<translation id="3287510313208355388">等到可連線時再下載網頁內容</translation>
<translation id="3293642807462928945">進一步瞭解 <ph name="POLICY_NAME" /> 政策</translation>
<translation id="3303855915957856445">找不到相符的搜尋結果</translation>
-<translation id="3305707030755673451">您已在 <ph name="TIME" />使用同步通關密語對資料進行加密,請輸入通關密語開始進行同步。</translation>
<translation id="3320021301628644560">新增帳單地址</translation>
<translation id="3324983252691184275">深紅色</translation>
<translation id="3338095232262050444">安全</translation>
@@ -405,9 +454,11 @@
<translation id="3427342743765426898">重做編輯(&amp;R)</translation>
<translation id="342781501876943858">如果你在其他網站上重複使用過你的密碼,Chromium 會建議你重設密碼。</translation>
<translation id="3431636764301398940">將這張信用卡儲存到這個裝置</translation>
+<translation id="3443726618221119081">Juuro-Ku-Kai</translation>
<translation id="3447661539832366887">這個裝置的擁有者已關閉恐龍遊戲。</translation>
<translation id="3447884698081792621">顯示憑證 (核發者:<ph name="ISSUER" />)</translation>
<translation id="3452404311384756672">擷取間隔:</translation>
+<translation id="3456231139987291353">Number-11 (信封)</translation>
<translation id="3461824795358126837">螢光筆</translation>
<translation id="3462200631372590220">隱藏詳細資料</translation>
<translation id="3467763166455606212">持卡人姓名為必填項目</translation>
@@ -430,20 +481,23 @@
<translation id="358285529439630156">接受信用卡和預付卡。</translation>
<translation id="3582930987043644930">新增名稱</translation>
<translation id="3583757800736429874">重做移動(&amp;R)</translation>
+<translation id="35866233670761917">你的系統管理員未查看你造訪的網站內容</translation>
<translation id="3586931643579894722">隱藏詳細資訊</translation>
+<translation id="3592413004129370115">Italian (信封)</translation>
<translation id="3600246354004376029"><ph name="TITLE" />,<ph name="DOMAIN" />,<ph name="TIME" /></translation>
<translation id="3614103345592970299">粗細:2</translation>
<translation id="3615877443314183785">請輸入有效的到期日</translation>
<translation id="36224234498066874">清除瀏覽資料...</translation>
<translation id="362276910939193118">顯示完整記錄</translation>
-<translation id="3623476034248543066">顯示政策值</translation>
<translation id="3630155396527302611">如果程式已列在允許存取網路的清單中,建議您
從清單中將其移除,然後再重新加入。</translation>
+<translation id="3640766068866876100">Index-4x6-Ext</translation>
<translation id="3650584904733503804">驗證成功</translation>
<translation id="3655670868607891010">如果你經常看到這個頁面,請參考這些說明:<ph name="HELP_LINK" />。</translation>
<translation id="3658742229777143148">修訂版本</translation>
<translation id="366077651725703012">更新信用卡</translation>
<translation id="3676592649209844519">裝置 ID:</translation>
+<translation id="3677008721441257057">你是否要前往 &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
<translation id="3678029195006412963">無法簽署要求</translation>
<translation id="3678529606614285348">在新的無痕式視窗中開啟網頁 (Ctrl + Shift + N 鍵)</translation>
<translation id="3679803492151881375">當機報告擷取時間:<ph name="CRASH_TIME" />,報告上傳時間:<ph name="UPLOAD_TIME" /></translation>
@@ -451,13 +505,14 @@
<translation id="3704162925118123524">您可能需要造訪目前所使用網路的登入網頁。</translation>
<translation id="3704609568417268905"><ph name="TIME" />,<ph name="BOOKMARKED" />,<ph name="TITLE" />,<ph name="DOMAIN" /></translation>
<translation id="370665806235115550">載入中…</translation>
+<translation id="3709599264800900598">你複製的文字</translation>
<translation id="3712624925041724820">授權已用盡</translation>
<translation id="3714780639079136834">開啟行動數據或 Wi-Fi</translation>
<translation id="3715597595485130451">連線至 Wi-Fi</translation>
<translation id="3717027428350673159"><ph name="BEGIN_LINK" />檢查 Proxy、防火牆和 DNS 設定<ph name="END_LINK" /></translation>
<translation id="372429172604983730">可能造成這個錯誤的應用程式包括防毒軟體、防火牆、網路篩選或 Proxy 軟體。</translation>
+<translation id="373042150751172459">B4 (信封)</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="3745099705178523657">經你確認後,這個網站就會取得你的 Google 帳戶中的信用卡詳細資料。</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>
@@ -470,10 +525,12 @@
<translation id="3783418713923659662">Mastercard</translation>
<translation id="3787705759683870569">到期日:<ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="3789155188480882154">粗細:16</translation>
+<translation id="3797522431967816232">Prc3 (信封)</translation>
<translation id="3807873520724684969">已封鎖有害內容。</translation>
<translation id="3810973564298564668">管理</translation>
<translation id="382518646247711829">如果你使用 Proxy 伺服器...</translation>
<translation id="3828924085048779000">通關密語欄位不得留空。</translation>
+<translation id="3831915413245941253"><ph name="ENROLLMENT_DOMAIN" /> 的管理員已安裝支援額外功能的擴充功能。這些擴充功能可存取你的部分資料。</translation>
<translation id="385051799172605136">返回</translation>
<translation id="3858027520442213535">更新日期和時間</translation>
<translation id="3884278016824448484">裝置識別碼發生衝突</translation>
@@ -481,6 +538,7 @@
<translation id="3886446263141354045">你想存取這個網站的要求已傳送給<ph name="NAME" /></translation>
<translation id="3890664840433101773">新增電子郵件地址</translation>
<translation id="3901925938762663762">這張信用卡已過期</translation>
+<translation id="3906600011954732550">B5-Extra</translation>
<translation id="3909695131102177774"><ph name="LABEL" />:<ph name="ERROR" /></translation>
<translation id="3946209740501886391">一律詢問你是否接受這個網站的要求</translation>
<translation id="3949571496842715403">這個伺服器無法證明所屬網域為 <ph name="DOMAIN" />;其安全性憑證未指定主體別名。這可能是因為設定錯誤,或是有攻擊者攔截你的連線所致。</translation>
@@ -491,11 +549,13 @@
<translation id="3964661563329879394">{COUNT,plural, =0{無}=1{來自 1 個網站 }other{來自 # 個網站 }}</translation>
<translation id="397105322502079400">計算中…</translation>
<translation id="3973234410852337861"><ph name="HOST_NAME" /> 遭到封鎖</translation>
-<translation id="3984550557525787191">已經有相同名稱的工作階段。</translation>
<translation id="3987940399970879459">不到 1 MB</translation>
+<translation id="4008849406247176967">警告:這項政策有多個來源,且來源的值相衝突!</translation>
<translation id="40103911065039147">{URL_count,plural, =1{附近有 1 個網頁}other{附近有 # 個網頁}}</translation>
<translation id="4030383055268325496">復原新增(&amp;U)</translation>
+<translation id="4032320456957708163">你的瀏覽器受到 <ph name="ENROLLMENT_DOMAIN" /> 管理</translation>
<translation id="4058922952496707368">鍵「<ph name="SUBKEY" />」:<ph name="ERROR" /></translation>
+<translation id="4067263367174615723">C1 (信封)</translation>
<translation id="4067947977115446013">新增有效的地址</translation>
<translation id="4072486802667267160">處理你的訂單時發生錯誤,請再試一次。</translation>
<translation id="4075732493274867456">用戶端和伺服器不支援一般 SSL 通訊協定版本或加密套件。</translation>
@@ -515,10 +575,12 @@
<translation id="4159784952369912983">紫色</translation>
<translation id="4165986682804962316">網站設定</translation>
<translation id="4171400957073367226">驗證簽名無效</translation>
+<translation id="4173315687471669144">Foolscap</translation>
<translation id="4173827307318847180">{MORE_ITEMS,plural, =1{還有另外 <ph name="ITEM_COUNT" /> 個項目}other{還有另外 <ph name="ITEM_COUNT" /> 個項目}}</translation>
<translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation>
<translation id="4196861286325780578">重做移動(&amp;R)</translation>
<translation id="4203896806696719780"><ph name="BEGIN_LINK" />檢查防火牆和防毒軟體設定<ph name="END_LINK" /></translation>
+<translation id="4215751373031079683">7x9 (信封)</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="4221630205957821124">&lt;h4&gt;步驟 1:從入口網站登入&lt;/h4&gt;
@@ -550,58 +612,79 @@
<translation id="4277028893293644418">重設密碼</translation>
<translation id="4280429058323657511">,到期日:<ph name="EXPIRATION_DATE_ABBR" /></translation>
<translation id="428639260510061158">{NUM_CARDS,plural, =1{這張卡片已儲存到你的 Google 帳戶}other{這些卡片已儲存到你的 Google 帳戶}}</translation>
+<translation id="42981349822642051">展開</translation>
+<translation id="4302965934281694568">Chou3 (信封)</translation>
<translation id="4305817255990598646">切換</translation>
+<translation id="4312613361423056926">B2</translation>
<translation id="4312866146174492540">封鎖 (預設)</translation>
+<translation id="4318566738941496689">你的裝置名稱和網路位址</translation>
<translation id="4325863107915753736">找不到文章</translation>
<translation id="4326324639298822553">請檢查信用卡到期日,然後再試一次</translation>
<translation id="4331708818696583467">不安全</translation>
<translation id="4340982228985273705">系統偵測結果顯示這台電腦未受企業管理,因此政策只能自動安裝透過 Chrome 線上應用程式商店代管的擴充功能。Chrome 線上應用程式商店更新網址為「<ph name="CWS_UPDATE_URL" />」。</translation>
<translation id="4346197816712207223">接受的信用卡</translation>
+<translation id="4346833872170306413">Roc-16K</translation>
<translation id="4356973930735388585">攻擊者可能會試圖透過這個網站在你的電腦上安裝危險程式,藉此竊取或刪除你的資訊 (例如相片、密碼、郵件和信用卡資料)。</translation>
<translation id="4358461427845829800">管理付款方式...</translation>
+<translation id="4367563149485757821">Number-12 (Envelope)</translation>
+<translation id="4372516964750095882">Fanfold-Us</translation>
<translation id="4372948949327679948">預期的「<ph name="VALUE_TYPE" />」值。</translation>
<translation id="4377125064752653719">你嘗試前往 <ph name="DOMAIN" />,但是發行者已撤銷伺服器提供的憑證。在這種情況下,請勿信任伺服器提供的安全性憑證,因為你的連線對象可能是攻擊者的電腦。</translation>
<translation id="4378154925671717803">電話</translation>
<translation id="4406896451731180161">搜尋結果</translation>
-<translation id="4406972042435603828">你的系統管理員已在瀏覽器中安裝功能強大的擴充功能。</translation>
<translation id="4408413947728134509"><ph name="NUM_COOKIES" /> 個 Cookie</translation>
<translation id="4415426530740016218">取件地址</translation>
<translation id="4424024547088906515">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證未取得 Chrome 的信任。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
+<translation id="443121186588148776">序列埠</translation>
<translation id="4432688616882109544"><ph name="HOST_NAME" /> 不接受你的登入憑證,或是你可能未提供登入憑證。</translation>
<translation id="4434045419905280838">彈出式視窗與重新導向</translation>
+<translation id="4435702339979719576">明信片)</translation>
<translation id="443673843213245140">雖然已停用 Proxy,不過已指定明確 Proxy 設定。</translation>
<translation id="445100540951337728">接受的簽帳金融卡</translation>
+<translation id="4466881336512663640">你對表單所做變更將會遺失。確定要繼續嗎?</translation>
<translation id="4482953324121162758">系統不會翻譯這個網站。</translation>
+<translation id="4490717597759821841">A7</translation>
+<translation id="4493480324863638523">網址無效。網址必須採用標準架構,例如 http://example.com 或 https://example.com。</translation>
+<translation id="4503882053543859973">Architecture-D</translation>
<translation id="4506176782989081258">驗證錯誤:<ph name="VALIDATION_ERROR" /></translation>
<translation id="4506599922270137252">與系統管理員聯絡</translation>
<translation id="450710068430902550">與管理員分享</translation>
+<translation id="4510487217173779431">Chou4 (信封)</translation>
<translation id="4515275063822566619">信用卡和地址資訊皆來自 Chrome 和你的 Google 帳戶 (<ph name="ACCOUNT_EMAIL" />)。你可以在<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />頁面管理這些資訊。</translation>
+<translation id="4517607026994743406">Comm-10 (信封)</translation>
<translation id="4522570452068850558">詳細資訊</translation>
<translation id="4524805452350978254">管理卡片</translation>
+<translation id="455113658016510503">A9</translation>
<translation id="4552089082226364758">Flash</translation>
<translation id="4558551763791394412">試試看停用擴充功能。</translation>
+<translation id="4559332380232738994">10x11</translation>
<translation id="457875822857220463">快遞</translation>
+<translation id="4579056131138995126">Personal (信封)</translation>
<translation id="4582204425268416675">移除卡片</translation>
<translation id="4587425331216688090">要從 Chrome 中移除地址嗎?</translation>
<translation id="4592951414987517459">您的 <ph name="DOMAIN" /> 連線使用新型加密套件進行加密。</translation>
<translation id="4594403342090139922">復原刪除(&amp;U)</translation>
<translation id="4597348597567598915">粗細:8</translation>
+<translation id="4600854749408232102">C6/C5 (信封)</translation>
<translation id="4646534391647090355">立即前往下載中心</translation>
<translation id="4668929960204016307">,</translation>
<translation id="467662567472608290">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證含有錯誤。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
<translation id="467809019005607715">Google 簡報</translation>
<translation id="4690462567478992370">停止使用無效的憑證</translation>
+<translation id="4691835149146451662">Architecture-A (信封)</translation>
<translation id="4701488924964507374"><ph name="SENTENCE1" /> <ph name="SENTENCE2" /></translation>
<translation id="4708268264240856090">您的連線已中斷</translation>
<translation id="471880041731876836">你沒有這個網站的瀏覽權限</translation>
<translation id="4722547256916164131"><ph name="BEGIN_LINK" />執行 Windows 網路診斷<ph name="END_LINK" /></translation>
<translation id="4726672564094551039">重新載入政策</translation>
<translation id="4728558894243024398">平台</translation>
+<translation id="4731967714531604179">Prc2 (信封)</translation>
<translation id="4736825316280949806">重新啟動 Chromium</translation>
<translation id="473775607612524610">更新</translation>
<translation id="4738601419177586157">「<ph name="TEXT" />」搜尋建議</translation>
<translation id="4742407542027196863">管理密碼…</translation>
<translation id="4744603770635761495">可執行檔的路徑</translation>
+<translation id="4746351372139058112">Messages</translation>
<translation id="4750917950439032686">你傳送給這個網站的資訊 (例如密碼或信用卡號碼) 不會外洩。</translation>
<translation id="4756388243121344051">記錄(&amp;H)</translation>
<translation id="4758311279753947758">新增聯絡資訊</translation>
@@ -609,9 +692,9 @@
<translation id="4764776831041365478"><ph name="URL" /> 的網頁可能暫時離線,或是已經遷移到另一個網址。</translation>
<translation id="4771973620359291008">發生不明的錯誤。</translation>
<translation id="4785689107224900852">切換至這個分頁</translation>
-<translation id="4792143361752574037">存取工作階段檔案時發生問題,目前無法將檔案儲存到磁碟。請重新載入網頁,然後再試一次。</translation>
<translation id="4798078619018708837">請輸入 <ph name="CREDIT_CARD" /> 的到期日和信用卡安全碼,以更新你的信用卡詳細資料。經你確認後,這個網站就會取得你的 Google 帳戶中的信用卡詳細資料。</translation>
<translation id="4800132727771399293">請檢查您的有效期限和信用卡安全碼,然後再試一次</translation>
+<translation id="480334179571489655">來源政策錯誤</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>
@@ -626,7 +709,6 @@
<translation id="4881695831933465202">開啟</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>
@@ -635,15 +717,15 @@
<translation id="4943872375798546930">沒有結果</translation>
<translation id="4950898438188848926">分頁切換按鈕,按下 Enter 鍵即可切換至開啟的分頁:<ph name="TAB_SWITCH_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
<translation id="495170559598752135">動作</translation>
-<translation id="495832697253704892">擴充功能回報</translation>
+<translation id="4955242332710481440">A5-Extra</translation>
<translation id="4958444002117714549">展開清單</translation>
<translation id="4974590756084640048">重新啟用警告功能</translation>
+<translation id="4984339528288761049">Prc5 (信封)</translation>
<translation id="4989163558385430922">查看全部</translation>
<translation id="4989809363548539747">這是不支援的外掛程式</translation>
-<translation id="4996230189582812866">回報功能</translation>
<translation id="5002932099480077015">啟用後,Chrome 會將您的信用卡複本儲存在這個裝置上,以加快表單填寫速度。</translation>
-<translation id="5014174725590676422">目前顯示 Chrome 版 Google 助理首次執行的畫面</translation>
<translation id="5015510746216210676">裝置名稱:</translation>
+<translation id="5017554619425969104">你複製的文字</translation>
<translation id="5018422839182700155">無法開啟這個網頁</translation>
<translation id="5019198164206649151">備份儲存狀態不佳</translation>
<translation id="5023310440958281426">請查看你的管理員政策</translation>
@@ -653,35 +735,51 @@
<translation id="5034369478845443529">本機當機 ID <ph name="CRASH_LOCAL_ID" /></translation>
<translation id="5039804452771397117">允許</translation>
<translation id="5040262127954254034">隱私權</translation>
+<translation id="5043480802608081735">你複製的連結</translation>
<translation id="5045550434625856497">密碼不正確</translation>
<translation id="5056549851600133418">推薦給你的文章</translation>
+<translation id="5068524481479508725">A10</translation>
<translation id="5070335125961472645"><ph name="BEGIN_LINK" />檢查 Proxy 位址<ph name="END_LINK" /></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="5097099694988056070">CPU/RAM 使用量等裝置統計資料</translation>
+<translation id="5097501891273180634">A2</translation>
<translation id="5098222253617183465">你的裝置是由 <ph name="ENROLLMENT_DOMAIN" /> 管理,而你的帳戶是由 <ph name="ACCOUNT_DOMAIN" /> 管理;這表示你的系統管理員可以從遠端設定你的裝置和帳戶。</translation>
+<translation id="5112422516732747637">A5</translation>
+<translation id="5115216390227830982">European-Edp</translation>
<translation id="5115563688576182185">(64 位元)</translation>
-<translation id="5128122789703661928">無法將使用這個名稱的工作階段刪除。</translation>
+<translation id="5125394840236832993">B-Plus</translation>
<translation id="5135404736266831032">管理地址...</translation>
+<translation id="5138227688689900538">顯示較少</translation>
<translation id="5141240743006678641">使用你的 Google 憑證對已同步處理的密碼進行加密</translation>
<translation id="5145883236150621069">政策回應中存在錯誤代碼</translation>
+<translation id="515292512908731282">C4 (信封)</translation>
<translation id="5159010409087891077">在新的無痕式視窗中開啟網頁 (⇧ + ⌘ + N 鍵)</translation>
<translation id="516920405563544094">請輸入 <ph name="CREDIT_CARD" /> 的信用卡安全碼。經你確認後,這個網站就會取得你的 Google 帳戶中的信用卡詳細資料。</translation>
<translation id="5169827969064885044">你可能會失去貴機構帳戶的存取權,或身分遭到冒用。Chrome 建議你立即變更密碼。</translation>
<translation id="5171045022955879922">搜尋或輸入網址</translation>
+<translation id="5171689220826475070">Fanfold-European</translation>
<translation id="5172758083709347301">本機</translation>
<translation id="5179510805599951267">網頁內容不是<ph name="ORIGINAL_LANGUAGE" />嗎?請回報此錯誤</translation>
<translation id="5190835502935405962">書籤列</translation>
-<translation id="5200263511887412697">回報最近登入的裝置使用者名單</translation>
+<translation id="519422657042045905">無法使用註解模式</translation>
<translation id="5201306358585911203">這個網頁上的嵌入式網頁顯示</translation>
<translation id="5205222826937269299">請輸入名稱</translation>
<translation id="5215116848420601511">儲存在 Google Pay 的付款方式和地址資訊</translation>
+<translation id="5215363486134917902">Folio-Sp</translation>
<translation id="5222812217790122047">請輸入電子郵件地址</translation>
<translation id="5230733896359313003">運送地址</translation>
+<translation id="5230815978613972521">B8</translation>
+<translation id="5233045608889518621">12x19</translation>
<translation id="5250209940322997802">「連線至網路」</translation>
<translation id="5251803541071282808">雲端</translation>
+<translation id="5252000469029418751">C7 (信封)</translation>
+<translation id="5254958791078852567">E1</translation>
+<translation id="5283044957620376778">B1</translation>
+<translation id="5284909709419567258">網路位址</translation>
<translation id="5285570108065881030">顯示所有已儲存的密碼</translation>
<translation id="5287240709317226393">顯示 Cookie</translation>
<translation id="5288108484102287882">政策值驗證作業出現警告訊息</translation>
@@ -693,7 +791,9 @@
<translation id="5323105697514565458"><ph name="FRIENDLY_MATCH_TEXT" />,<ph name="NUM_MATCHES" /> 之 <ph name="MATCH_POSITION" /></translation>
<translation id="5324080437450482387">選擇聯絡資訊</translation>
<translation id="5327248766486351172">名稱</translation>
+<translation id="5329858041417644019">你的瀏覽器未受管理</translation>
<translation id="5332219387342487447">運送方式</translation>
+<translation id="5334013548165032829">詳細系統記錄</translation>
<translation id="5344579389779391559">進入接下來的頁面後,系統可能會向您收費</translation>
<translation id="5355557959165512791">目前無法造訪 <ph name="SITE" />,因為這個網站的憑證已遭撤銷。網路錯誤和攻擊行為通常是暫時性的,因此這個網頁可能稍後就會恢復正常狀態。</translation>
<translation id="536296301121032821">無法儲存政策設定</translation>
@@ -701,6 +801,7 @@
<translation id="5377026284221673050">「你的時鐘時間過慢」、「你的時鐘時間過快」或 「&lt;span class="error-code"&gt;NET::ERR_CERT_DATE_INVALID&lt;/span&gt;」</translation>
<translation id="5384855140246857529">如要將卡片同步到所有裝置,請登入並開啟同步功能。</translation>
<translation id="5386426401304769735">這個網站的憑證鏈結包含使用 SHA-1 進行簽署的憑證。</translation>
+<translation id="538659543871111977">A4-Tab</translation>
<translation id="540969355065856584">這個伺服器無法證明所屬網域為 <ph name="DOMAIN" />;其安全性憑證目前無效。這可能是因為設定錯誤,或是有攻擊者攔截您的連線所致。</translation>
<translation id="5421136146218899937">清除瀏覽資料...</translation>
<translation id="5430298929874300616">移除書籤</translation>
@@ -711,6 +812,7 @@
<translation id="5457113250005438886">無效</translation>
<translation id="5458150163479425638">{CONTACT,plural, =0{<ph name="CONTACT_PREVIEW" />}=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="5470861586879999274">重做編輯(&amp;R)</translation>
+<translation id="5478437291406423475">B6/C4 (信封)</translation>
<translation id="5481076368049295676">這項內容可能會試圖在你的裝置上安裝危險軟體,藉此竊取或刪除你的資訊。<ph name="BEGIN_LINK" />仍要顯示<ph name="END_LINK" /></translation>
<translation id="54817484435770891">新增有效的地址</translation>
<translation id="5490432419156082418">地址和其他資訊</translation>
@@ -718,10 +820,12 @@
<ph name="LINE_BREAK" />
請與您的系統管理員聯絡。</translation>
<translation id="549333378215107354">粗細:3</translation>
+<translation id="5509762909502811065">B0</translation>
<translation id="5509780412636533143">受管理書籤</translation>
<translation id="5510766032865166053">檔案可能已移至其他位置或遭到刪除。</translation>
<translation id="5523118979700054094">政策名稱</translation>
<translation id="552553974213252141">擷取的文字是否正確?</translation>
+<translation id="553484882784876924">Prc6 (信封)</translation>
<translation id="5540224163453853">找不到要求的文章。</translation>
<translation id="5541546772353173584">新增電子郵件地址</translation>
<translation id="5545756402275714221">為你推薦的報導</translation>
@@ -736,15 +840,21 @@
<translation id="5595485650161345191">編輯地址</translation>
<translation id="5598944008576757369">選擇付款方式</translation>
<translation id="560412284261940334">系統不支援管理</translation>
+<translation id="5605670050355397069">Ledger</translation>
+<translation id="5607240918979444548">Architecture-C</translation>
<translation id="5610142619324316209">檢查連線狀態</translation>
<translation id="5610807607761827392">你可以在<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />中管理信用卡和地址資訊。</translation>
<translation id="5617949217645503996"><ph name="HOST_NAME" /> 將您重新導向的次數過多。</translation>
<translation id="5629630648637658800">無法載入政策設定</translation>
<translation id="5631439013527180824">裝置管理符記無效</translation>
+<translation id="5632627355679805402">你在 <ph name="TIME" />已使用 <ph name="BEGIN_LINK" />Google 密碼<ph name="END_LINK" />將資料加密。如要開始同步處理資料,請輸入密碼。</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="563324245173044180">已封鎖欺騙性內容。</translation>
<translation id="5659593005791499971">電子郵件</translation>
+<translation id="5663614846592581799">9x11 (信封)</translation>
+<translation id="5663955426505430495">這部裝置的管理員已安裝支援額外功能的擴充功能。這些擴充功能可存取你的部分資料。</translation>
<translation id="5675650730144413517">這個網頁無法正常運作</translation>
+<translation id="5684874026226664614">糟糕!系統無法翻譯這個網頁的內容。</translation>
<translation id="5685654322157854305">新增運送地址</translation>
<translation id="5689199277474810259">以 JSON 格式匯出</translation>
<translation id="5689516760719285838">位置</translation>
@@ -753,38 +863,39 @@
<translation id="5710435578057952990">此網頁的身分未經驗證。</translation>
<translation id="5719499550583120431">接受預付卡。</translation>
<translation id="5720705177508910913">目前使用者</translation>
+<translation id="5728056243719941842">C5 (信封)</translation>
<translation id="5730040223043577876">如果你在其他網站上重複使用過你的密碼,Chrome 會建議你重設密碼。</translation>
<translation id="5732392974455271431">你的家長可以為你解除封鎖這個網站</translation>
<translation id="5737183892635480227">{NUM_CARDS,plural, =1{將卡片儲存到你的 Google 帳戶}other{將卡片儲存到你的 Google 帳戶}}</translation>
<translation id="5763042198335101085">請輸入有效的電子郵件地址</translation>
<translation id="5765072501007116331">如要查看快遞方式和相關規定,請選取一個地址</translation>
-<translation id="5770114862687765385">這個檔案似乎已毀損。按一下 [重設] 按鈕即可重設工作階段。</translation>
<translation id="5778550464785688721">MIDI 裝置完整控制</translation>
<translation id="578305955206182703">琥珀色</translation>
<translation id="57838592816432529">靜音</translation>
<translation id="5784606427469807560">驗證您的信用卡時發生問題。請檢查網際網路連線,然後再試一次。</translation>
<translation id="5785756445106461925">此外,這個網頁含有其他不安全的資源。其他人可能會在資源傳輸期間檢視這些資源,攻擊者也可能會修改這些資源,進而變更網頁外觀。</translation>
<translation id="5786044859038896871">要填入你的信用卡資訊嗎?</translation>
+<translation id="5798290721819630480">要捨棄變更嗎?</translation>
<translation id="5798683403665926540">在 Chrome 設定中變更首頁</translation>
<translation id="5803412860119678065">要填入你的 <ph name="CARD_DETAIL" /> 資訊嗎?</translation>
<translation id="5804241973901381774">權限</translation>
<translation id="5810442152076338065">您的 <ph name="DOMAIN" /> 連線使用過舊的加密套件進行加密。</translation>
<translation id="5813119285467412249">重做新增(&amp;R)</translation>
<translation id="5838278095973806738">請勿在這個網站上輸入任何機密資訊 (例如密碼或信用卡號碼),以免遭到攻擊者竊取。</translation>
+<translation id="5860033963881614850">關閉</translation>
<translation id="5863847714970149516">你要瀏覽的網頁可能會向你收取費用</translation>
<translation id="5866257070973731571">新增電話號碼</translation>
<translation id="5869405914158311789">無法連上這個網站</translation>
<translation id="5869522115854928033">已儲存的密碼</translation>
<translation id="5887400589839399685">已儲存卡片</translation>
-<translation id="5893718151540690985">回報網路介面清單,當中包含網路介面類型和硬體位址資料</translation>
<translation id="5893752035575986141">接受簽帳金融卡。</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="5916664084637901428">開啟</translation>
+<translation id="5919090499915321845">B10</translation>
<translation id="5921639886840618607">要將這張卡片儲存到 Google 帳戶嗎?</translation>
<translation id="5922853866070715753">即將完成</translation>
<translation id="5932224571077948991">網站顯示干擾性或誤導性廣告</translation>
-<translation id="5939518447894949180">重設</translation>
<translation id="5946937721014915347">正在開啟 <ph name="SITE_NAME" />…</translation>
<translation id="5951495562196540101">無法透過個人帳戶註冊 (有封裝授權)。</translation>
<translation id="5967592137238574583">編輯聯絡資訊</translation>
@@ -792,6 +903,7 @@
<translation id="5975083100439434680">縮小</translation>
<translation id="5977489021191000276">你的裝置並非由系統管理員管理。</translation>
<translation id="5977976211062815271">在這部裝置上</translation>
+<translation id="5980920751713728343">Index-3x5</translation>
<translation id="598637245381783098">無法開啟付款應用程式</translation>
<translation id="5989320800837274978">沒有指定固定的 Proxy 伺服器和 .pac 指令碼網址。</translation>
<translation id="5990559369517809815">擴充功能已封鎖要傳送至伺服器的要求。</translation>
@@ -802,8 +914,8 @@
<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="6033927989869462158">回報 CPU/RAM 使用量等硬體統計資料</translation>
<translation id="6034000775414344507">淺灰色</translation>
+<translation id="6034283069659657473">10x14 (信封)</translation>
<translation id="6039846035001940113">如果問題仍未解決,請與網站擁有者聯絡。</translation>
<translation id="6040143037577758943">關閉</translation>
<translation id="6044573915096792553">粗細:12</translation>
@@ -812,10 +924,10 @@
<translation id="6051221802930200923">目前無法造訪 <ph name="SITE" />,因為這個網站使用憑證鎖定功能。網路錯誤和攻擊行為通常是暫時性的,因此這個網頁可能稍後就會恢復正常狀態。</translation>
<translation id="6058977677006700226">想在所有裝置上使用你的卡片嗎?</translation>
<translation id="6059925163896151826">USB 裝置</translation>
-<translation id="6071091556643036997">政策類型無效。</translation>
<translation id="6080696365213338172">你使用了管理員提供的憑證存取內容,因此管理員可攔截你傳送至「<ph name="DOMAIN" />」的資料。</translation>
<translation id="6094273045989040137">註解</translation>
<translation id="610911394827799129">你的 Google 帳戶仍可能保留了其他類型的瀏覽記錄 (可前往 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 查詢)。</translation>
+<translation id="6132597952260690497">已安裝的擴充功能和外掛程式相關資訊</translation>
<translation id="6144381551823904650">{COUNT,plural, =0{無}=1{1 組密碼 (保持同步)}other{# 組密碼 (保持同步)}}</translation>
<translation id="6146055958333702838">檢查您的網路線是否穩固連接。重新啟動您可能正在使用的任何路由器、
數據機或其他網路裝置。</translation>
@@ -850,15 +962,21 @@
<translation id="6337133576188860026">釋出不到 <ph name="SIZE" />。下次造訪部分網站時,載入速度可能會變慢。</translation>
<translation id="6337534724793800597">依名稱篩選政策</translation>
<translation id="6358450015545214790">我需要進一步資訊</translation>
+<translation id="6361757823711327522">B7</translation>
+<translation id="6380497234672085559">A0</translation>
<translation id="6383221683286411806">你要造訪的網站可能會誘導使用者支付額外額外費用。</translation>
<translation id="6386120369904791316">{COUNT,plural, =1{以及另外 1 個建議項目}other{以及另外 # 個建議項目}}</translation>
<translation id="6387754724289022810">只要將卡片資訊與帳單地址儲存到你的 Google 帳戶中和這部裝置上,下次即可更快完成付款程序。</translation>
+<translation id="6390662030813198813">Engineering-E</translation>
<translation id="6404511346730675251">編輯書籤</translation>
+<translation id="6406765186087300643">C0 (信封)</translation>
<translation id="6410264514553301377">輸入 <ph name="CREDIT_CARD" /> 的到期日和信用卡安全碼</translation>
<translation id="6414888972213066896">你已詢問家長是否同意你造訪這個網站</translation>
<translation id="6417515091412812850">無法檢查憑證是否已遭撤銷。</translation>
<translation id="6433490469411711332">編輯聯絡資訊</translation>
<translation id="6433595998831338502"><ph name="HOST_NAME" /> 拒絕連線。</translation>
+<translation id="6434309073475700221">捨棄</translation>
+<translation id="6446163441502663861">Kahu (信封)</translation>
<translation id="6446608382365791566">新增詳細資訊</translation>
<translation id="6447842834002726250">Cookie</translation>
<translation id="6451458296329894277">確認重新提交表單</translation>
@@ -871,11 +989,17 @@
<translation id="6508722015517270189">重新啟動 Chrome</translation>
<translation id="6529602333819889595">重做刪除(&amp;R)</translation>
<translation id="6534179046333460208">實體化網路建議</translation>
+<translation id="6556866813142980365">重做</translation>
<translation id="6563469144985748109">你的管理員尚未核准這個網站</translation>
<translation id="6569060085658103619">目前顯示的是擴充功能頁面</translation>
+<translation id="6578796323535178455">C2 (信封)</translation>
<translation id="6579990219486187401">淺粉紅色</translation>
+<translation id="6583674473685352014">B6 (信封)</translation>
+<translation id="6587923378399804057">你複製的連結</translation>
+<translation id="6591833882275308647">你的 <ph name="DEVICE_TYPE" /> 未受管理</translation>
<translation id="6596325263575161958">加密選項</translation>
<translation id="6604181099783169992">動作或光源感應器</translation>
+<translation id="6609880536175561541">Prc7 (信封)</translation>
<translation id="6624427990725312378">聯絡資訊</translation>
<translation id="6626291197371920147">新增有效的信用卡號碼</translation>
<translation id="6628463337424475685"><ph name="ENGINE" /> 搜尋</translation>
@@ -884,6 +1008,7 @@
<translation id="6644283850729428850">這項政策已遭取代。</translation>
<translation id="6646269444027925224">{COUNT,plural, =0{無}=1{1 個網站 (你不會因此登出 Google 帳戶)}other{# 個網站 (你不會因此登出 Google 帳戶)}}</translation>
<translation id="6657585470893396449">密碼</translation>
+<translation id="6670613747977017428">返回安全網頁。</translation>
<translation id="6671697161687535275">要從 Chromium 中移除表單填寫建議嗎?</translation>
<translation id="6685834062052613830">請登出並完成設定程序</translation>
<translation id="6710213216561001401">返回</translation>
@@ -891,12 +1016,15 @@
<translation id="671076103358959139">註冊憑證:</translation>
<translation id="6711464428925977395">Proxy 伺服器發生錯誤,或是位址不正確。</translation>
<translation id="6723740634201835758">在你的 Google 帳戶中</translation>
+<translation id="6738516213925468394">你在 <ph name="TIME" />已使用<ph name="BEGIN_LINK" />同步通關密語<ph name="END_LINK" />將資料加密。如要開始同步處理資料,請輸入通關密語。</translation>
<translation id="674375294223700098">不明的伺服器憑證錯誤。</translation>
<translation id="6744009308914054259">等待連線的同時,你可以前往「下載」頁面閱讀離線文章。</translation>
<translation id="6753269504797312559">政策值</translation>
<translation id="6757797048963528358">您的裝置已進入睡眠模式。</translation>
+<translation id="6768213884286397650">Hagaki (明信片)</translation>
<translation id="6778737459546443941">你的家長尚未核准這個網站</translation>
<translation id="67862343314499040">紫羅蘭色</translation>
+<translation id="6786747875388722282">擴充功能</translation>
<translation id="679355240208270552">由於政策未啟用預設搜尋設定,因此遭到忽略。</translation>
<translation id="681021252041861472">必填欄位</translation>
<translation id="6810899417690483278">自訂 ID</translation>
@@ -929,10 +1057,12 @@
<translation id="6965978654500191972">裝置</translation>
<translation id="6970216967273061347">District</translation>
<translation id="6973656660372572881">已指定固定的 Proxy 伺服器和 .pac 指令碼網址。</translation>
+<translation id="6973932557599545801">抱歉,目前無法提供協助,請自行填入資料。</translation>
<translation id="6979158407327259162">Google 雲端硬碟</translation>
<translation id="6979440798594660689">靜音 (預設)</translation>
<translation id="6984479912851154518">即將離開私密模式,改為使用外部應用程式付款,要繼續嗎?</translation>
<translation id="6989763994942163495">顯示進階設定...</translation>
+<translation id="6993898126790112050">6x9 (信封)</translation>
<translation id="6996312675313362352">一律翻譯<ph name="ORIGINAL_LANGUAGE" /></translation>
<translation id="7012363358306927923">中國銀聯</translation>
<translation id="7016992613359344582">這些費用可能只收取一次,也可能屬於週期性費用,而且你不一定會注意到自己需要付費。</translation>
@@ -948,28 +1078,36 @@
<translation id="7108338896283013870">隱藏</translation>
<translation id="7108819624672055576">依據擴充功能設定允許</translation>
<translation id="7111012039238467737">(有效)</translation>
+<translation id="7118618213916969306">搜尋剪貼簿網址 <ph name="SHORT_URL" /></translation>
<translation id="7119414471315195487">關閉其他分頁或程式</translation>
<translation id="7129409597930077180">無法運送到這個地址,請改用其他地址。</translation>
<translation id="7135130955892390533">顯示狀態</translation>
<translation id="7138472120740807366">快遞方式</translation>
<translation id="7139724024395191329">埃米爾管轄區</translation>
+<translation id="7152423860607593928">Number-14 (Envelope)</translation>
<translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=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="7153618581592392745">淡紫色</translation>
-<translation id="7158980942472052083">網址無效。網址必須採用標準架構。</translation>
<translation id="717330890047184534">GAIA ID:</translation>
<translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=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="7177397715882417099">你的目標伺服器「<ph name="ORIGIN" />」要求為其收到的所有要求
+ 套用安全性政策。不過,由於該伺服器
+ 並未提供政策,而是將瀏覽器重新導向他處,因此
+ 瀏覽器無法完成你向「<ph name="SITE" />」提出的要求。</translation>
<translation id="7179323680825933600">儲存及填入付款方式</translation>
<translation id="7180611975245234373">重新整理</translation>
<translation id="7182878459783632708">沒有設定任何政策</translation>
<translation id="7186367841673660872">此網頁內容已由<ph name="ORIGINAL_LANGUAGE" />翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation>
<translation id="7192203810768312527">釋出 <ph name="SIZE" />。下次造訪部分網站時,載入速度可能會變慢。</translation>
<translation id="719464814642662924">Visa</translation>
+<translation id="7201591969684833065">系統管理員可以查看以下項目:</translation>
+<translation id="7202346780273620635">Letter-Extra</translation>
<translation id="7210863904660874423"><ph name="HOST_NAME" /> 不符合安全性標準。</translation>
<translation id="721197778055552897"><ph name="BEGIN_LINK" />進一步瞭解<ph name="END_LINK" />這個問題。</translation>
<translation id="7219179957768738017">這個連線使用 <ph name="SSL_VERSION" />。</translation>
<translation id="7220786058474068424">處理中</translation>
<translation id="7243010569062352439"><ph name="PASSWORDS" />,<ph name="SIGNIN_DATA" /></translation>
<translation id="724691107663265825">你要造訪的網站含有惡意軟體</translation>
+<translation id="724766306220616965">警告和衝突</translation>
<translation id="724975217298816891">請輸入 <ph name="CREDIT_CARD" /> 的有效日期和信用卡安全碼,更新您的信用卡詳細資訊。完成驗證後,這個網站就會取得您的信用卡詳細資訊。</translation>
<translation id="7251437084390964440">網路設定未遵循 ONC 標準,系統可能無法匯入部分設定。
其他詳細資料:
@@ -982,11 +1120,14 @@
<translation id="7300012071106347854">鈷藍色</translation>
<translation id="7302712225291570345">「<ph name="TEXT" />」</translation>
<translation id="7309308571273880165">當機報告擷取時間:<ph name="CRASH_TIME" /> (使用者要求上傳,但尚未上傳)</translation>
+<translation id="7313965965371928911"><ph name="BEGIN_LINK" />安全瀏覽<ph name="END_LINK" />警告</translation>
+<translation id="7319430975418800333">A3</translation>
<translation id="7320336641823683070">連線說明</translation>
<translation id="7334320624316649418">重做重新排序(&amp;R)</translation>
<translation id="733923710415886693">伺服器憑證未依憑證透明化政策公開。</translation>
+<translation id="734600844861828519">11x15</translation>
+<translation id="7349430561505560861">A4-Extra</translation>
<translation id="7353601530677266744">命令列</translation>
-<translation id="7365061714576910172">以 Linux 格式匯出</translation>
<translation id="7372973238305370288">搜尋結果</translation>
<translation id="7377249249140280793"><ph name="RELATIVE_DATE" /> - <ph name="FULL_DATE" /></translation>
<translation id="7378627244592794276">不需要</translation>
@@ -994,6 +1135,7 @@
<translation id="7381288752349550461">受管理工作階段覆寫</translation>
<translation id="7390545607259442187">驗證信用卡</translation>
<translation id="7400418766976504921">網址</translation>
+<translation id="7403591733719184120">你的 <ph name="DEVICE_NAME" /> 受到管理</translation>
<translation id="7407424307057130981">&lt;p&gt;如果你的 Windows 電腦上有 Superfish 軟體,系統就會顯示這則錯誤訊息。&lt;/p&gt;
&lt;p&gt;請按照以下步驟暫時停用該軟體,以便順利連上網路。你需要管理員權限。&lt;/p&gt;
&lt;ol&gt;
@@ -1004,7 +1146,7 @@
&lt;li&gt;依序按一下 [套用]&lt;strong&gt;&lt;/strong&gt; 和 [確定]&lt;strong&gt;&lt;/strong&gt;
&lt;li&gt;前往 &lt;a href="https://support.google.com/chrome/answer/6098869"&gt;Chrome 說明中心&lt;/a&gt;瞭解如何將該軟體從電腦上永久移除
&lt;/ol&gt;</translation>
-<translation id="7413422570546054399">管理 <ph name="PRODUCT_NAME" /></translation>
+<translation id="741007362987735528">Wide-Format</translation>
<translation id="7416351320495623771">管理密碼…</translation>
<translation id="7419106976560586862">設定檔路徑</translation>
<translation id="7437289804838430631">新增聯絡資訊</translation>
@@ -1013,22 +1155,24 @@
<translation id="7442725080345379071">淺橘色</translation>
<translation id="7444046173054089907">這個網站遭到封鎖</translation>
<translation id="7445762425076701745">你所連線的伺服器身分無法完全驗證,該伺服器所使用的名稱僅在你的網路中有效,無法驗證外部憑證授權單位的擁有權。即使某些憑證授權單位會核發這些憑證,不過無法就此確保你所連上的網站是正確的,而不會遭到網路攻擊。</translation>
-<translation id="7449109375006139765">將系統記錄傳送到管理伺服器</translation>
<translation id="7451311239929941790"><ph name="BEGIN_LINK" />進一步瞭解<ph name="END_LINK" />這個問題。</translation>
<translation id="7455133967321480974">使用全域預設值 (封鎖)</translation>
<translation id="7460618730930299168">放映場次細節與你所選取的不同。要繼續嗎?</translation>
<translation id="7473891865547856676">不用了,謝謝</translation>
-<translation id="7475525192983021547">回報使用者的裝置使用時間範圍</translation>
<translation id="7481312909269577407">往前</translation>
<translation id="7485870689360869515">找不到任何資料。</translation>
+<translation id="7498234416455752244">繼續編輯</translation>
<translation id="7508255263130623398">傳回的政策裝置 ID 沒有任何內容,或是與目前的裝置 ID 不符</translation>
<translation id="7508870219247277067">酪梨綠</translation>
<translation id="7511955381719512146">目前使用的 Wi-Fi 網路可能會要求您造訪 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
<translation id="7514365320538308">下載</translation>
<translation id="7518003948725431193">找不到此網址的網頁:<ph name="URL" /></translation>
+<translation id="7520302887438682816">C8 (信封)</translation>
<translation id="7521387064766892559">JavaScript</translation>
<translation id="7526934274050461096">你與這個網站之間的連線不是私人連線</translation>
+<translation id="7535087603100972091">值</translation>
<translation id="7537536606612762813">強制</translation>
+<translation id="7538364083937897561">A2 (信封)</translation>
<translation id="7542403920425041731">經過你確認後,這個網站就會取得你的信用卡詳細資料。</translation>
<translation id="7542995811387359312">由於這個表單並未採用加密連線方式,所以信用卡自動填入功能已停用。</translation>
<translation id="7543525346216957623">請徵求家長同意</translation>
@@ -1037,8 +1181,8 @@
<translation id="7552846755917812628">嘗試按照下列提示操作:</translation>
<translation id="7554791636758816595">新增分頁</translation>
<translation id="7564049878696755256">你可能會失去 <ph name="ORG_NAME" /> 帳戶存取權,或身分遭到冒用。Chrome 建議你立即變更密碼。</translation>
-<translation id="7566125604157659769">你複製的文字</translation>
<translation id="7567204685887185387">伺服器無法證明其屬於 <ph name="DOMAIN" /> 網域;其安全性憑證是以欺詐方式發行。這可能是因為設定錯誤,或有攻擊者攔截你的連線所致。</translation>
+<translation id="7568105740864181217">這個瀏覽器是由公司、學校或其他組織管理。你的系統管理員可以遠端變更瀏覽器設定。這部裝置上的活動也可透過 Chrome 以外的服務管理。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation>
<translation id="7569952961197462199">要從 Chrome 中移除信用卡嗎?</translation>
<translation id="7569983096843329377">黑色</translation>
<translation id="7578104083680115302">在不同的裝置上透過各個網站和應用程式消費時,使用您讓 Google 儲存的信用卡資料即可快速付款。</translation>
@@ -1049,6 +1193,7 @@
<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="7633909222644580952">效能資料和當機報告</translation>
<translation id="7637571805876720304">要從 Chromium 中移除信用卡嗎?</translation>
<translation id="7639968568612851608">深灰色</translation>
<translation id="765676359832457558">隱藏進階設定...</translation>
@@ -1058,9 +1203,11 @@
<translation id="7667346355482952095">傳回的政策憑證沒有任何內容,或是與目前的憑證不符</translation>
<translation id="7668654391829183341">不明的裝置</translation>
<translation id="7669271284792375604">攻擊者可能會試圖透過這個網站誘使你安裝對瀏覽體驗有害 (例如變更你的首頁,或是在你造訪的網站上顯示多餘的廣告) 的程式。</translation>
+<translation id="7676643023259824263">搜尋剪貼簿文字:<ph name="TEXT" /></translation>
<translation id="7681101578153515023">變更搜尋引擎</translation>
<translation id="7682287625158474539">寄送地址</translation>
<translation id="7687186412095877299">在付款表單中填入已儲存的付款方式</translation>
+<translation id="7697066736081121494">Prc8 (信封)</translation>
<translation id="769721561045429135">目前你有某些卡片只能在這部裝置上使用。按一下 [繼續] 即可查看卡片。</translation>
<translation id="7699293099605015246">目前無法顯示文章</translation>
<translation id="7701040980221191251">無</translation>
@@ -1072,11 +1219,13 @@
<translation id="774634243536837715">已封鎖危險內容。</translation>
<translation id="7752995774971033316">未管理</translation>
<translation id="7755287808199759310">你的家長可以為你解除封鎖這個網站</translation>
+<translation id="7757555340166475417">Dai-Pa-Kai</translation>
<translation id="7758069387465995638">防火牆或防毒軟體可能封鎖了連線。</translation>
<translation id="7759163816903619567">顯示網域:</translation>
<translation id="7761701407923456692">伺服器憑證與網址不符。</translation>
<translation id="7763386264682878361">付款資訊清單剖析器</translation>
<translation id="7764225426217299476">新增地址</translation>
+<translation id="7770259615151589601">Designated-Long</translation>
<translation id="777702478322588152">縣</translation>
<translation id="7791543448312431591">新增</translation>
<translation id="7793809570500803535"><ph name="SITE" /> 的網頁可能暫時無法使用或已永久移至新網址。</translation>
@@ -1088,8 +1237,8 @@
<translation id="7812922009395017822">Mir</translation>
<translation id="7813600968533626083">要從 Chrome 中移除建議嗎?</translation>
<translation id="7815407501681723534">找到 <ph name="NUMBER_OF_RESULTS" /> 個與「<ph name="SEARCH_STRING" />」相符的<ph name="SEARCH_RESULTS" /></translation>
-<translation id="7818867226424560206">政策管理</translation>
<translation id="782886543891417279">目前使用的 Wi-Fi 網路 (<ph name="WIFI_NAME" />) 可能會要求您造訪登入網頁。</translation>
+<translation id="7836231406687464395">Postfix (信封)</translation>
<translation id="7844689747373518809">{COUNT,plural, =0{無}=1{1 個應用程式:<ph name="EXAMPLE_APP_1" />}=2{2 個應用程式:<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />}other{# 個應用程式:<ph name="EXAMPLE_APP_1" />、<ph name="EXAMPLE_APP_2" />、<ph name="AND_MORE" />}}</translation>
<translation id="785549533363645510">不過,這並不意味著您可以完全隱形。使用無痕模式時,您的雇主和網際網路服務供應商仍然可以追蹤您的瀏覽記錄,您所造訪的網站也可能會記錄您的瀏覽行為。</translation>
<translation id="7855695075675558090"><ph name="TOTAL_LABEL" /> <ph name="CURRENCY_CODE" /> <ph name="FORMATTED_TOTAL_AMOUNT" /></translation>
@@ -1098,7 +1247,7 @@
<translation id="7878562273885520351">你的密碼可能已經外洩</translation>
<translation id="7882421473871500483">棕色</translation>
<translation id="7887683347370398519">請檢查您的 CVC,然後再試一次</translation>
-<translation id="7893255318348328562">工作階段名稱</translation>
+<translation id="7904208859782148177">C3 (信封)</translation>
<translation id="79338296614623784">請輸入有效的電話號碼</translation>
<translation id="7935318582918952113">DOM Distiller</translation>
<translation id="7937554595067888181">到期日:<ph name="EXPIRATION_DATE_ABBR" /></translation>
@@ -1108,21 +1257,25 @@
<translation id="7951415247503192394">(32 位元)</translation>
<translation id="7956713633345437162">行動版書籤</translation>
<translation id="7961015016161918242">一律不要</translation>
+<translation id="7977894662897852582">Edp</translation>
<translation id="7995512525968007366">未指定</translation>
<translation id="800218591365569300">嘗試關閉其他分頁或程式,以釋出記憶體。</translation>
+<translation id="8004582292198964060">瀏覽器</translation>
<translation id="8009225694047762179">管理密碼</translation>
<translation id="8012116502927253373">{NUM_CARDS,plural, =1{系統會儲存這張卡片和相應的帳單地址。只要登入 <ph name="USER_EMAIL" /> 即可使用。}other{系統會儲存這些卡片和相應的帳單地址。只要登入 <ph name="USER_EMAIL" /> 即可使用。}}</translation>
<translation id="8012647001091218357">我們暫時無法與您的家長聯絡,請再試一次。</translation>
<translation id="8025119109950072390">攻擊者可能會試圖透過這個網站誘使你做一些危險的行為,例如安裝軟體或提供個人資訊 (包括密碼、電話號碼或信用卡資料)。</translation>
<translation id="8034522405403831421">這是<ph name="SOURCE_LANGUAGE" />網頁,需要翻譯成<ph name="TARGET_LANGUAGE" />嗎?</translation>
<translation id="8035152190676905274">畫筆</translation>
+<translation id="8037117624646282037">最近使用過裝置的使用者</translation>
<translation id="8037357227543935929">詢問 (預設)</translation>
<translation id="803771048473350947">檔案</translation>
<translation id="8041089156583427627">提供意見</translation>
<translation id="8041940743680923270">使用全域預設值 (要求確認)</translation>
<translation id="8042918947222776840">選擇取件方式</translation>
<translation id="8057711352706143257">「<ph name="SOFTWARE_NAME" />」的設定不正確。通常解除安裝「<ph name="SOFTWARE_NAME" />」即可修正這個問題。<ph name="FURTHER_EXPLANATION" /></translation>
-<translation id="8068418091938640101">你的裝置已設定為:</translation>
+<translation id="8066955247577885446">抱歉,系統發生錯誤。</translation>
+<translation id="8074253406171541171">10x13 (信封)</translation>
<translation id="8078141288243656252">文件旋轉後無法加註</translation>
<translation id="8079031581361219619">要重新載入網站嗎?</translation>
<translation id="8088680233425245692">無法查看文章。</translation>
@@ -1131,11 +1284,12 @@
<translation id="8091372947890762290">尚未在伺服器上啟動</translation>
<translation id="8092774999298748321">深紫色</translation>
<translation id="8094917007353911263">目前使用的網路可能會要求您造訪 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
+<translation id="809898108652741896">A6</translation>
<translation id="8100588592594801589">已移除無效的卡片</translation>
<translation id="8103161714697287722">付款方式</translation>
<translation id="8118489163946903409">付款方式</translation>
+<translation id="8123836779274890062"><ph name="DEVICE_TYPE" /> 受到 <ph name="ENROLLMENT_DOMAIN" /> 管理</translation>
<translation id="8127301229239896662">「<ph name="SOFTWARE_NAME" />」未正確安裝在電腦或網路上。請通知 IT 管理員解決這個問題。</translation>
-<translation id="8130693978878176684">我幫不上忙了,請自行填入資料。</translation>
<translation id="8131740175452115882">確認</translation>
<translation id="8149426793427495338">您的電腦已進入睡眠模式。</translation>
<translation id="8150722005171944719">無法讀取位於 <ph name="URL" /> 的檔案。這個檔案可能已遭移除或移動位置,或者檔案權限為禁止存取。</translation>
@@ -1145,8 +1299,11 @@
<translation id="8197543752516192074">翻譯網頁</translation>
<translation id="8201077131113104583">擴充功能 (ID:「<ph name="EXTENSION_ID" />」) 的更新網址無效。</translation>
<translation id="8202097416529803614">訂單摘要</translation>
+<translation id="8202370299023114387">衝突</translation>
+<translation id="8206978196348664717">Prc4 (信封)</translation>
<translation id="8211406090763984747">已建立安全連線</translation>
<translation id="8218327578424803826">指派的位置:</translation>
+<translation id="8220146938470311105">C7/C6 (信封)</translation>
<translation id="8225771182978767009">設定這部電腦的使用者選擇封鎖這個網站。</translation>
<translation id="822964464349305906"><ph name="TYPE_1" />、<ph name="TYPE_2" /></translation>
<translation id="8238581221633243064">在新的無痕式分頁中開啟網頁</translation>
@@ -1158,14 +1315,16 @@
<translation id="825929999321470778">顯示所有已儲存的密碼</translation>
<translation id="8261506727792406068">刪除</translation>
<translation id="8267698848189296333">正在以 <ph name="USERNAME" /> 的身分登入</translation>
+<translation id="8278457561961988242">這個瀏覽器是由 <ph name="ENROLLMENT_DOMAIN" /> 所管理。你的系統管理員可以遠端變更瀏覽器設定。這部裝置上的活動也可透過 Chrome 以外的服務管理。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation>
+<translation id="8281084378435768645">Large-Photo</translation>
<translation id="8286036467436129157">登入</translation>
<translation id="8288807391153049143">顯示憑證</translation>
<translation id="8289355894181816810">如果你不確定這代表什麼意思,請與網路管理員聯絡。</translation>
<translation id="8293206222192510085">新增書籤</translation>
<translation id="8294431847097064396">來源</translation>
<translation id="8298115750975731693">目前使用的 Wi-Fi 網路 (<ph name="WIFI_NAME" />) 可能會要求您造訪 <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />。</translation>
+<translation id="8307358339886459768">Small-Photo</translation>
<translation id="8308427013383895095">網路連線發生問題,翻譯作業失敗。</translation>
-<translation id="8311129316111205805">載入工作階段</translation>
<translation id="8332188693563227489">存取 <ph name="HOST_NAME" /> 的要求遭到拒絕</translation>
<translation id="8340095855084055290"><ph name="EXPIRATION_MONTH" />/<ph name="EXPIRATION_YEAR" /></translation>
<translation id="834457929814110454">如果你瞭解安全性風險,也可以選擇在有害程式尚未遭到移除的狀態下<ph name="BEGIN_LINK" />造訪這個網站<ph name="END_LINK" />。</translation>
@@ -1183,7 +1342,6 @@
<translation id="8416694386774425977">網路設定無效,無法匯入。
其他詳細資料:
<ph name="DEBUG_INFO" /></translation>
-<translation id="8422642323886341533">由 <ph name="ENROLLMENT_DOMAIN" /> 管理的裝置</translation>
<translation id="8424582179843326029"><ph name="FIRST_LABEL" /> <ph name="SECOND_LABEL" /> <ph name="THIRD_LABEL" /></translation>
<translation id="8425213833346101688">變更</translation>
<translation id="8428213095426709021">設定</translation>
@@ -1210,9 +1368,11 @@
<translation id="860043288473659153">持卡人姓名</translation>
<translation id="861775596732816396">粗細:4</translation>
<translation id="8620436878122366504">你的家長尚未核准這個網站</translation>
+<translation id="8622948367223941507">Legal-Extra</translation>
<translation id="8625384913736129811">將這張信用卡儲存到這個裝置</translation>
<translation id="8663226718884576429">訂單摘要:<ph name="TOTAL_LABEL" />,更多詳細資料</translation>
<translation id="8680536109547170164"><ph name="QUERY" />,答案:<ph name="ANSWER" /></translation>
+<translation id="8685155993131031756">Prc-16K</translation>
<translation id="8703575177326907206">你到 <ph name="DOMAIN" /> 的連線未加密。</translation>
<translation id="8718314106902482036">未完成付款程序</translation>
<translation id="8719263113926255150"><ph name="ENTITY" />,<ph name="DESCRIPTION" />,搜尋建議</translation>
@@ -1226,6 +1386,7 @@
<translation id="8761567432415473239">Google 安全瀏覽最近在「<ph name="SITE" />」<ph name="BEGIN_LINK" />發現了有害程式<ph name="END_LINK" />。</translation>
<translation id="8763927697961133303">USB 裝置</translation>
<translation id="8768895707659403558">如要在所有裝置上使用你的卡片,請<ph name="SIGN_IN_LINK" />。</translation>
+<translation id="877985182522063539">A4</translation>
<translation id="8790007591277257123">重做刪除(&amp;R)</translation>
<translation id="8792621596287649091">你可能會失去 <ph name="ORG_NAME" /> 帳戶存取權,或身分遭到冒用。Chromium 建議你立即變更密碼。</translation>
<translation id="8800988563907321413">這裡會顯示系統建議你瀏覽的鄰近網頁</translation>
@@ -1236,10 +1397,12 @@
<translation id="885730110891505394">與 Google 分享</translation>
<translation id="8858065207712248076">如果你在其他網站上重複使用過你的 <ph name="BEGIN_BOLD" /><ph name="ORG_NAME" /><ph name="END_BOLD" /> 密碼,Chrome 會建議你重設密碼。</translation>
<translation id="8866481888320382733">解析政策設定時發生錯誤</translation>
+<translation id="886872106311861689">B3</translation>
<translation id="8870413625673593573">最近關閉的分頁</translation>
<translation id="8874824191258364635">請輸入有效的信用卡號碼</translation>
<translation id="8891727572606052622">Proxy 模式無效。</translation>
<translation id="8903921497873541725">放大</translation>
+<translation id="890485472659500557">Engineering-C</translation>
<translation id="8931333241327730545">您要將這張卡片的資訊儲存到您的 Google 帳戶嗎?</translation>
<translation id="8932102934695377596">你的時鐘時間過慢</translation>
<translation id="893332455753468063">新增名稱</translation>
@@ -1247,13 +1410,13 @@
<translation id="894185898663964645">你的系統管理員已設定自訂根憑證,這項設定將能允許系統管理員查看你所造訪網站的內容。</translation>
<translation id="8943282376843390568">萊姆綠</translation>
<translation id="8957210676456822347">監控式入口網站授權</translation>
+<translation id="8966619695390250636">你是不是要前往:</translation>
<translation id="8968766641738584599">儲存卡片</translation>
<translation id="8971063699422889582">伺服器憑證已過期。</translation>
<translation id="8975012916872825179">包括電話號碼、電子郵件地址和運送地址等資訊</translation>
<translation id="8978053250194585037">Google 安全瀏覽功能最近在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />偵測到網路詐騙行為<ph name="END_LINK" />。詐騙網站會偽裝成其他網站,藉此騙取你的資訊。</translation>
<translation id="8983003182662520383">儲存在 Google Pay 的付款方式和地址資訊</translation>
<translation id="8987927404178983737">月</translation>
-<translation id="8988408250700415532">發生錯誤。你可以前往相關網站完成訂單。</translation>
<translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
<translation id="8996941253935762404">你要瀏覽的網站含有有害程式</translation>
<translation id="8997023839087525404">該伺服器的憑證並未根據憑證透明化政策對外公開。部分憑證必須符合這項規定,以確保憑證值得信任,不會讓使用者遭到攻擊。</translation>
@@ -1263,6 +1426,7 @@
<translation id="9011424611726486705">開啟網站設定</translation>
<translation id="9020200922353704812">請輸入信用卡帳單地址</translation>
<translation id="9020542370529661692">此網頁內容已翻譯成<ph name="TARGET_LANGUAGE" /></translation>
+<translation id="9020742383383852663">A8</translation>
<translation id="9025348182339809926">(無效)</translation>
<translation id="9035022520814077154">安全性錯誤</translation>
<translation id="9038649477754266430">使用預測查詢字串服務,讓系統更快載入網頁</translation>
@@ -1274,11 +1438,11 @@
<translation id="9065745800631924235">「<ph name="TEXT" />」的搜尋記錄</translation>
<translation id="9069693763241529744">依據擴充功能設定封鎖</translation>
<translation id="9076283476770535406">這個網站可能含有成人內容</translation>
+<translation id="9076630408993835509">這個瀏覽器未受到任何公司或其他機構管理。這部裝置上的活動可透過 Chrome 以外的服務管理。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation>
<translation id="9078964945751709336">請提供詳細資訊</translation>
<translation id="9080712759204168376">訂單摘要</translation>
<translation id="9103872766612412690"><ph name="SITE" /> 通常使用加密方式保護您的資訊。但 Chromium 這次嘗試連線到 <ph name="SITE" /> 時,該網站傳回了異常且錯誤的憑證。這可能是因為有攻擊者企圖偽裝成 <ph name="SITE" />,或是受到 Wi-Fi 登入畫面影響而造成連線中斷。不過請放心,Chromium 已及時停止連線,並未傳輸任何資料,因此您的資訊仍然安全無虞。</translation>
<translation id="9106062320799175032">新增帳單地址</translation>
-<translation id="9110718169272311511">Chrome 版 Google 助理位於靠近畫面底部的位置</translation>
<translation id="9114524666733003316">正在驗證信用卡...</translation>
<translation id="9128870381267983090">連線至網路</translation>
<translation id="9137013805542155359">顯示原文</translation>
@@ -1287,6 +1451,7 @@
<translation id="9148507642005240123">復原編輯(&amp;U)</translation>
<translation id="9154194610265714752">已更新</translation>
<translation id="9157595877708044936">設定中...</translation>
+<translation id="9158625974267017556">C6 (信封)</translation>
<translation id="9168814207360376865">允許網站檢查付款方式是否已成功儲存</translation>
<translation id="9169664750068251925">永遠禁止在這個網站執行</translation>
<translation id="9170848237812810038">取消(&amp;U)</translation>
@@ -1301,10 +1466,12 @@
<translation id="9219103736887031265">圖片</translation>
<translation id="933712198907837967">Diners Club</translation>
<translation id="935608979562296692">清除表單</translation>
+<translation id="936474030629450166">Super-B</translation>
<translation id="936602727769022409">為避免失去 Google 帳戶存取權,Chromium 建議你立即變更密碼。系統會要求你登入帳戶。</translation>
<translation id="939736085109172342">新增資料夾</translation>
<translation id="945855313015696284">查看下方資訊並刪除所有無效的卡片</translation>
<translation id="951104842009476243">接受的簽帳金融卡和預付卡</translation>
+<translation id="958202389743790697">依據 <ph name="ORIGIN" /> 的安全性政策設定封鎖。</translation>
<translation id="962484866189421427">這項內容可能會試圖讓你安裝身分不實的欺騙性應用程式,或是收集可用於追蹤你的資料。<ph name="BEGIN_LINK" />仍要顯示<ph name="END_LINK" /></translation>
<translation id="969892804517981540">正式版本</translation>
<translation id="973773823069644502">新增快遞地址</translation>
@@ -1313,6 +1480,7 @@
<translation id="984275831282074731">付款方式</translation>
<translation id="985199708454569384">&lt;p&gt;如果畫面顯示這則錯誤訊息,表示您電腦或行動裝置的日期或時間不正確。&lt;/p&gt;
&lt;p&gt;如要修正這項錯誤,請開啟裝置的時鐘,確認時間和日期是否正確無誤。&lt;/p&gt;</translation>
+<translation id="985956168329721395">Prc-32K</translation>
<translation id="988159990683914416">開發人員版本</translation>
<translation id="989988560359834682">編輯地址</translation>
<translation id="992115559265932548"><ph name="MICROSOFT_ACTIVE_DIRECTORY" /></translation>
diff --git a/chromium/components/subresource_filter/content/browser/BUILD.gn b/chromium/components/subresource_filter/content/browser/BUILD.gn
index 1f52117d9d5..2b7aa3b3914 100644
--- a/chromium/components/subresource_filter/content/browser/BUILD.gn
+++ b/chromium/components/subresource_filter/content/browser/BUILD.gn
@@ -44,9 +44,9 @@ static_library("browser") {
"//components/safe_browsing/db:database_manager",
"//components/safe_browsing/db:util",
"//components/subresource_filter/content/common",
- "//components/subresource_filter/content/mojom",
"//components/subresource_filter/core/browser",
"//components/subresource_filter/core/common",
+ "//components/subresource_filter/core/mojom",
"//components/ukm:ukm",
"//content/public/browser",
"//content/public/common",
@@ -55,6 +55,7 @@ static_library("browser") {
"//url",
]
public_deps = [
+ "//components/subresource_filter/content/mojom",
"//third_party/flatbuffers:flatbuffers",
"//ui/base",
]
@@ -105,7 +106,6 @@ source_set("unit_tests") {
"//components/prefs:test_support",
"//components/safe_browsing/db:util",
"//components/subresource_filter/content/common",
- "//components/subresource_filter/content/mojom",
"//components/subresource_filter/core/browser",
"//components/subresource_filter/core/browser:test_support",
"//components/subresource_filter/core/common",
@@ -117,4 +117,7 @@ source_set("unit_tests") {
"//ipc:test_support",
"//testing/gtest",
]
+ public_deps = [
+ "//components/subresource_filter/content/mojom",
+ ]
}
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 f0e2ffb4b9e..27282df5c7f 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
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
@@ -641,11 +642,11 @@ TEST_P(ActivationStateComputingThrottleSubFrameTest, SpeculationWithDelay) {
sub_histogram_tester.ExpectTotalCount(kActivationCPU, ExpectThreadTimers(2));
}
-INSTANTIATE_TEST_CASE_P(,
- ActivationStateComputingNavigationThrottleTest,
- ::testing::Values(true, false));
-INSTANTIATE_TEST_CASE_P(,
- ActivationStateComputingThrottleSubFrameTest,
- ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ ActivationStateComputingNavigationThrottleTest,
+ ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ ActivationStateComputingThrottleSubFrameTest,
+ ::testing::Values(true, false));
} // namespace subresource_filter
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 581f7478376..dab14691b86 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
@@ -9,6 +9,8 @@
#include <tuple>
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_current.h"
@@ -371,10 +373,10 @@ class ContentSubresourceFilterThrottleManagerTest
DISALLOW_COPY_AND_ASSIGN(ContentSubresourceFilterThrottleManagerTest);
};
-INSTANTIATE_TEST_CASE_P(,
- ContentSubresourceFilterThrottleManagerTest,
- ::testing::Values(WILL_START_REQUEST,
- WILL_PROCESS_RESPONSE));
+INSTANTIATE_TEST_SUITE_P(,
+ ContentSubresourceFilterThrottleManagerTest,
+ ::testing::Values(WILL_START_REQUEST,
+ WILL_PROCESS_RESPONSE));
TEST_P(ContentSubresourceFilterThrottleManagerTest,
ActivateMainFrameAndFilterSubframeNavigation) {
diff --git a/chromium/components/subresource_filter/content/browser/ruleset_service.cc b/chromium/components/subresource_filter/content/browser/ruleset_service.cc
index 2be68ab1d2a..34a2d7b6113 100644
--- a/chromium/components/subresource_filter/content/browser/ruleset_service.cc
+++ b/chromium/components/subresource_filter/content/browser/ruleset_service.cc
@@ -92,7 +92,7 @@ class SentinelFile {
base::FilePath IndexedRulesetLocator::GetSubdirectoryPathForVersion(
const base::FilePath& base_dir,
const IndexedRulesetVersion& version) {
- return base_dir.AppendASCII(base::IntToString(version.format_version))
+ return base_dir.AppendASCII(base::NumberToString(version.format_version))
.AppendASCII(version.content_version);
}
@@ -119,7 +119,7 @@ void IndexedRulesetLocator::DeleteObsoleteRulesets(
const base::FilePath& indexed_ruleset_base_dir,
const IndexedRulesetVersion& most_recent_version) {
base::FilePath current_format_dir(indexed_ruleset_base_dir.AppendASCII(
- base::IntToString(IndexedRulesetVersion::CurrentFormatVersion())));
+ base::NumberToString(IndexedRulesetVersion::CurrentFormatVersion())));
// First delete all directories containing rulesets of obsolete formats.
base::FileEnumerator format_dirs(indexed_ruleset_base_dir,
@@ -235,7 +235,8 @@ IndexedRulesetVersion RulesetService::GetMostRecentlyIndexedVersion() const {
IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
const base::FilePath& indexed_ruleset_base_dir,
const UnindexedRulesetInfo& unindexed_ruleset_info) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
base::File unindexed_ruleset_file(
unindexed_ruleset_info.ruleset_path,
diff --git a/chromium/components/subresource_filter/content/browser/ruleset_service_unittest.cc b/chromium/components/subresource_filter/content/browser/ruleset_service_unittest.cc
index 47a7bfe56eb..1d4a284e92d 100644
--- a/chromium/components/subresource_filter/content/browser/ruleset_service_unittest.cc
+++ b/chromium/components/subresource_filter/content/browser/ruleset_service_unittest.cc
@@ -444,7 +444,7 @@ TEST_F(SubresourceFilteringRulesetServiceTest, PathsAreSane) {
EXPECT_TRUE(base_dir().IsParent(version_dir));
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
- base::IntToString(indexed_version.format_version),
+ base::NumberToString(indexed_version.format_version),
version_dir.MaybeAsASCII());
EXPECT_PRED_FORMAT2(::testing::IsSubstring, indexed_version.content_version,
version_dir.MaybeAsASCII());
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 ffcb7a93171..9d5a874cc03 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
@@ -11,6 +11,7 @@
#include "base/debug/dump_without_crashing.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/strings/stringprintf.h"
#include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
#include "components/subresource_filter/core/common/time_measurements.h"
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 3dd4c72f329..d9a5e92a687 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
@@ -8,6 +8,7 @@
#include <sstream>
#include <string>
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.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 2be64c59aeb..a79d99750c8 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
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/timer/timer.h"
#include "base/trace_event/trace_event.h"
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 b17dc36b5d2..9b27febc0e0 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
@@ -11,6 +11,8 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/message_loop/message_loop_current.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
@@ -723,7 +725,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
EXPECT_EQ(mojom::ActivationLevel::kDisabled,
*observer()->GetPageActivationForLastCommittedLoad());
}
-};
+}
// Only main frames with http/https schemes should activate.
TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
@@ -757,7 +759,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
EXPECT_EQ(test_data.expected_activation_level,
*observer()->GetPageActivationForLastCommittedLoad());
}
-};
+}
TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
ListNotMatched_NoActivation) {
@@ -1034,7 +1036,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 0);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CancelMethod,
SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
::testing::Combine(
@@ -1045,12 +1047,12 @@ INSTANTIATE_TEST_CASE_P(
::testing::Values(content::TestNavigationThrottle::SYNCHRONOUS,
content::TestNavigationThrottle::ASYNCHRONOUS)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ActivationLevelTest,
SubresourceFilterSafeBrowsingActivationThrottleParamTest,
::testing::ValuesIn(kActivationListTestData));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ActivationScopeTest,
SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
::testing::ValuesIn(kActivationScopeTestData));
diff --git a/chromium/components/subresource_filter/content/common/ad_delay_throttle.cc b/chromium/components/subresource_filter/content/common/ad_delay_throttle.cc
index ac29ef59d8f..594d979002b 100644
--- a/chromium/components/subresource_filter/content/common/ad_delay_throttle.cc
+++ b/chromium/components/subresource_filter/content/common/ad_delay_throttle.cc
@@ -79,7 +79,7 @@ class NonIsolatedCondition : public AdDelayThrottle::DeferCondition {
}
};
-}; // namespace
+} // namespace
AdDelayThrottle::DeferCondition::DeferCondition(
base::TimeDelta delay,
diff --git a/chromium/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc b/chromium/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc
index b2775d57c0f..d98014080ad 100644
--- a/chromium/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc
+++ b/chromium/components/subresource_filter/content/common/ad_delay_throttle_unittest.cc
@@ -565,8 +565,8 @@ TEST_P(AdDelayThrottleEnabledParamTest, IsolatedMetrics) {
}
}
-INSTANTIATE_TEST_CASE_P(,
- AdDelayThrottleEnabledParamTest,
- ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(,
+ AdDelayThrottleEnabledParamTest,
+ ::testing::Values(true, false));
} // namespace subresource_filter
diff --git a/chromium/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/chromium/components/subresource_filter/content/renderer/subresource_filter_agent.cc
index 0202b182c00..081bb89e84c 100644
--- a/chromium/components/subresource_filter/content/renderer/subresource_filter_agent.cc
+++ b/chromium/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
diff --git a/chromium/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc b/chromium/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
index 39630445bc3..c038b95f70e 100644
--- a/chromium/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
+++ b/chromium/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
@@ -138,12 +138,14 @@ class SubresourceFilterAgentTest : public ::testing::Test {
}
void StartLoadWithoutSettingActivationState() {
- agent_as_rfo()->DidStartProvisionalLoad(nullptr, true);
+ agent_as_rfo()->DidStartNavigation(GURL(), base::nullopt);
+ agent_as_rfo()->ReadyToCommitNavigation(nullptr);
agent_as_rfo()->DidCreateNewDocument();
}
void PerformSameDocumentNavigationWithoutSettingActivationLevel() {
- agent_as_rfo()->DidStartProvisionalLoad(nullptr, true);
+ agent_as_rfo()->DidStartNavigation(GURL(), base::nullopt);
+ agent_as_rfo()->ReadyToCommitNavigation(nullptr);
// No DidCreateNewDocument, since same document navigations by definition
// don't create a new document.
// No DidFinishLoad is called in this case.
@@ -160,7 +162,8 @@ class SubresourceFilterAgentTest : public ::testing::Test {
void StartLoadAndSetActivationState(
mojom::ActivationState state,
AdFrameType ad_type = AdFrameType::kNonAd) {
- agent_as_rfo()->DidStartProvisionalLoad(nullptr, true);
+ agent_as_rfo()->DidStartNavigation(GURL(), base::nullopt);
+ agent_as_rfo()->ReadyToCommitNavigation(nullptr);
agent()->ActivateForNextCommittedLoad(state.Clone(), ad_type);
agent_as_rfo()->DidCreateNewDocument();
}
@@ -464,7 +467,8 @@ TEST_F(SubresourceFilterAgentTest,
ASSERT_NO_FATAL_FAILURE(
SetTestRulesetToDisallowURLsWithPathSuffix(kTestBothURLsPathSuffix));
ExpectNoSubresourceFilterGetsInjected();
- agent_as_rfo()->DidStartProvisionalLoad(nullptr, true);
+ agent_as_rfo()->DidStartNavigation(GURL(), base::nullopt);
+ agent_as_rfo()->ReadyToCommitNavigation(nullptr);
mojom::ActivationStatePtr state = mojom::ActivationState::New();
state->activation_level = mojom::ActivationLevel::kEnabled;
state->measure_performance = true;
@@ -472,7 +476,8 @@ TEST_F(SubresourceFilterAgentTest,
AdFrameType::kNonAd /* ad_type */);
agent_as_rfo()->DidFailProvisionalLoad(
blink::WebURLError(net::ERR_FAILED, blink::WebURL()));
- agent_as_rfo()->DidStartProvisionalLoad(nullptr, true);
+ agent_as_rfo()->DidStartNavigation(GURL(), base::nullopt);
+ agent_as_rfo()->ReadyToCommitNavigation(nullptr);
agent_as_rfo()->DidCommitProvisionalLoad(
false /* is_same_document_navigation */, ui::PAGE_TRANSITION_LINK);
FinishLoad();
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 a0cc54611dd..3555c7f0b9d 100644
--- a/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc
+++ b/chromium/components/subresource_filter/core/browser/subresource_filter_features.cc
@@ -21,6 +21,7 @@
#include "base/time/time.h"
#include "base/trace_event/traced_value.h"
#include "components/subresource_filter/core/common/common_features.h"
+#include "components/subresource_filter/core/mojom/subresource_filter.mojom.h"
namespace subresource_filter {
diff --git a/chromium/components/subresource_filter/core/common/first_party_origin_unittest.cc b/chromium/components/subresource_filter/core/common/first_party_origin_unittest.cc
index 68e271e73e8..9f4a591524b 100644
--- a/chromium/components/subresource_filter/core/common/first_party_origin_unittest.cc
+++ b/chromium/components/subresource_filter/core/common/first_party_origin_unittest.cc
@@ -14,7 +14,7 @@ TEST(FirstPartyOriginTest, AllSameDomain) {
FirstPartyOrigin first_party(url::Origin::Create(GURL("https://" + kDomain)));
for (int index = 0; index < 5; ++index) {
- GURL url("https://" + kDomain + "/path?q=" + base::IntToString(index));
+ GURL url("https://" + kDomain + "/path?q=" + base::NumberToString(index));
EXPECT_FALSE(FirstPartyOrigin::IsThirdParty(url, first_party.origin()));
EXPECT_FALSE(first_party.IsThirdParty(url));
}
@@ -25,7 +25,8 @@ TEST(FirstPartyOriginTest, AllFirstParty) {
FirstPartyOrigin first_party(url::Origin::Create(GURL("https://" + kDomain)));
for (int index = 0; index < 5; ++index) {
- GURL url("https://sub" + base::IntToString(index) + "." + kDomain + "/suf");
+ GURL url("https://sub" + base::NumberToString(index) + "." + kDomain +
+ "/suf");
EXPECT_FALSE(FirstPartyOrigin::IsThirdParty(url, first_party.origin()));
EXPECT_FALSE(first_party.IsThirdParty(url));
}
@@ -36,7 +37,8 @@ TEST(FirstPartyOriginTest, AllThirdParty) {
FirstPartyOrigin first_party(url::Origin::Create(GURL("https://" + kDomain)));
for (int index = 0; index < 5; ++index) {
- GURL url("https://example" + base::IntToString(index) + ".co.uk/path?k=v");
+ GURL url("https://example" + base::NumberToString(index) +
+ ".co.uk/path?k=v");
EXPECT_TRUE(FirstPartyOrigin::IsThirdParty(url, first_party.origin()));
EXPECT_TRUE(first_party.IsThirdParty(url));
}
diff --git a/chromium/components/subresource_filter/core/common/indexed_ruleset.cc b/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
index af89f6ec154..964176a6d0e 100644
--- a/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
+++ b/chromium/components/subresource_filter/core/common/indexed_ruleset.cc
@@ -52,12 +52,12 @@ VerifyStatus GetVerifyStatus(const uint8_t* buffer,
// RulesetIndexer --------------------------------------------------------------
-const int RulesetIndexer::kIndexedFormatVersion = 25;
+const int RulesetIndexer::kIndexedFormatVersion = 26;
// This static assert is meant to catch cases where
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
// updating RulesetIndexer::kIndexedFormatVersion.
-static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 4,
+static_assert(url_pattern_index::kUrlPatternIndexFormatVersion == 5,
"kUrlPatternIndexFormatVersion has changed, make sure you've "
"also updated RulesetIndexer::kIndexedFormatVersion above.");
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 1785b8d245a..4d359de34e1 100644
--- a/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc
+++ b/chromium/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -145,7 +145,7 @@ void TestRulesetCreator::CreateRulesetToDisallowURLsWithManySuffixes(
std::vector<proto::UrlRule> rules;
for (int i = 0; i < num_of_suffixes; ++i) {
std::string current_suffix =
- suffix.as_string() + '_' + base::IntToString(i);
+ suffix.as_string() + '_' + base::NumberToString(i);
rules.push_back(CreateSuffixRule(current_suffix));
}
CreateRulesetWithRules(rules, test_ruleset_pair);
@@ -176,7 +176,7 @@ void TestRulesetCreator::GetUniqueTemporaryPath(base::FilePath* path) {
ASSERT_TRUE(scoped_temp_dir_->IsValid() ||
scoped_temp_dir_->CreateUniqueTempDir());
*path = scoped_temp_dir_->GetPath().AppendASCII(
- base::IntToString(next_unique_file_suffix++));
+ base::NumberToString(next_unique_file_suffix++));
}
void TestRulesetCreator::CreateTestRulesetFromContents(
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 2fefde299b8..6bc6f792e30 100644
--- a/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
+++ b/chromium/components/subresource_filter/core/common/unindexed_ruleset_unittest.cc
@@ -65,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";
+ std::string url_pattern = "example" + base::NumberToString(i) + ".com";
if (!AddUrlRule(UrlPattern(url_pattern), testing::kAnyParty, i & 1))
return false;
}
diff --git a/chromium/components/subresource_filter/tools/filter_tool.cc b/chromium/components/subresource_filter/tools/filter_tool.cc
index 69e1b85c67c..ac1f8e766ee 100644
--- a/chromium/components/subresource_filter/tools/filter_tool.cc
+++ b/chromium/components/subresource_filter/tools/filter_tool.cc
@@ -162,7 +162,8 @@ void FilterTool::MatchBatchImpl(std::istream* request_stream,
if (line.empty())
continue;
- std::unique_ptr<base::Value> dictionary = base::JSONReader::Read(line);
+ std::unique_ptr<base::Value> dictionary =
+ base::JSONReader::ReadDeprecated(line);
CHECK(dictionary);
const std::string& origin =
diff --git a/chromium/components/subresource_filter/tools/indexing_tool_unittest.cc b/chromium/components/subresource_filter/tools/indexing_tool_unittest.cc
index 79434dac9c0..cc9f2cfaadd 100644
--- a/chromium/components/subresource_filter/tools/indexing_tool_unittest.cc
+++ b/chromium/components/subresource_filter/tools/indexing_tool_unittest.cc
@@ -46,7 +46,7 @@ class IndexingToolTest : public ::testing::Test {
base::FilePath GetUniquePath() {
base::FilePath path = scoped_temp_dir_.GetPath().AppendASCII(
- base::IntToString(file_count_++));
+ base::NumberToString(file_count_++));
return path;
}
@@ -131,8 +131,8 @@ TEST_F(IndexingToolTest, VersionMetadata) {
WriteVersionMetadata(version_path, "1.2.3", checksum);
std::string version_json;
EXPECT_TRUE(base::ReadFileToString(version_path, &version_json));
- std::unique_ptr<base::DictionaryValue> json =
- base::DictionaryValue::From(base::JSONReader::Read(version_json));
+ std::unique_ptr<base::DictionaryValue> json = base::DictionaryValue::From(
+ base::JSONReader::ReadDeprecated(version_json));
std::string actual_content =
json->FindPath({"subresource_filter", "ruleset_version", "content"})
diff --git a/chromium/components/subresource_filter/tools/ruleset_converter/BUILD.gn b/chromium/components/subresource_filter/tools/ruleset_converter/BUILD.gn
index 7ab3f2d412f..e44e3677f64 100644
--- a/chromium/components/subresource_filter/tools/ruleset_converter/BUILD.gn
+++ b/chromium/components/subresource_filter/tools/ruleset_converter/BUILD.gn
@@ -12,11 +12,15 @@ source_set("support") {
"ruleset_format.cc",
"ruleset_format.h",
]
+
+ public_deps = [
+ "//components/url_pattern_index/proto:url_pattern_index",
+ ]
+
deps = [
"../rule_parser",
"//base",
"//components/subresource_filter/core/common",
- "//components/url_pattern_index/proto:url_pattern_index",
"//third_party/protobuf:protobuf_lite",
]
}
diff --git a/chromium/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc b/chromium/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
index e10501564f5..dfd1001bddc 100644
--- a/chromium/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
+++ b/chromium/components/subresource_filter/tools/ruleset_converter/rule_stream_unittest.cc
@@ -77,7 +77,7 @@ std::vector<std::string> GetManyRules() {
text_rule += "@@";
if (i & 1)
text_rule += "sub.";
- text_rule += "example" + base::IntToString(i) + ".com";
+ text_rule += "example" + base::NumberToString(i) + ".com";
text_rule += '$';
text_rule += (i & 7) ? "script" : "image";
if (i & 1)
@@ -90,7 +90,7 @@ std::vector<std::string> GetManyRules() {
if (i & 1)
text_rule += ",~but_not.domain.com";
text_rule += (i & 3) ? "##" : "#@#";
- text_rule += "#id" + base::IntToString(i);
+ text_rule += "#id" + base::NumberToString(i);
text_rules.push_back(text_rule);
}
diff --git a/chromium/components/suggestions/suggestions_service_impl.cc b/chromium/components/suggestions/suggestions_service_impl.cc
index b3f8a26743b..0814503b29a 100644
--- a/chromium/components/suggestions/suggestions_service_impl.cc
+++ b/chromium/components/suggestions/suggestions_service_impl.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/metrics/field_trial_params.h"
@@ -444,8 +445,8 @@ SuggestionsServiceImpl::CreateSuggestionsRequest(
// Add Chrome experiment state to the request headers.
// TODO: We should call AppendVariationHeaders with explicit
// variations::SignedIn::kNo If the access_token is empty
- variations::AppendVariationHeadersUnknownSignedIn(
- url, variations::InIncognito::kNo, &resource_request->headers);
+ variations::AppendVariationsHeaderUnknownSignedIn(
+ url, variations::InIncognito::kNo, resource_request.get());
if (!access_token.empty()) {
resource_request->headers.SetHeader(
"Authorization", base::StrCat({"Bearer ", access_token}));
diff --git a/chromium/components/suggestions/webui/suggestions_source.cc b/chromium/components/suggestions/webui/suggestions_source.cc
index 2cad79be861..b6b56abdfcb 100644
--- a/chromium/components/suggestions/webui/suggestions_source.cc
+++ b/chromium/components/suggestions/webui/suggestions_source.cc
@@ -68,7 +68,7 @@ std::string RenderOutputHtml(const std::string& base_url,
line += base::UTF16ToUTF8(remaining_time_formatted);
std::vector<std::string> providers;
for (int p = 0; p < suggestion.providers_size(); ++p)
- providers.push_back(base::IntToString(suggestion.providers(p)));
+ providers.push_back(base::NumberToString(suggestion.providers(p)));
line += ". Provider IDs: " + base::JoinString(providers, ", ");
line += "</li>\n";
out.push_back(line);
diff --git a/chromium/components/supervised_user_error_page/gin_wrapper.cc b/chromium/components/supervised_user_error_page/gin_wrapper.cc
index 6ebd909c615..fe4d773384c 100644
--- a/chromium/components/supervised_user_error_page/gin_wrapper.cc
+++ b/chromium/components/supervised_user_error_page/gin_wrapper.cc
@@ -4,6 +4,7 @@
#include "components/supervised_user_error_page/gin_wrapper.h"
+#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/renderer/render_frame.h"
#include "gin/handle.h"
diff --git a/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css b/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
index 4dd222b2645..59d5f17ed05 100644
--- a/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
+++ b/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
@@ -12,30 +12,23 @@ a {
}
button {
+ background: #1A73E8;
border: 0;
border-radius: 2px;
box-sizing: border-box;
- color: #fff;
+ color: #ffffff;
cursor: pointer;
- float: right;
- font-family: Roboto;
+ font-family: 'Google Sans', Roboto, sans-serif;
font-size: 14px;
- font-weight: 500;
+ font-weight: 550;
+ line-height: 16pt;
margin: 0;
- padding: 10px 24px;
+ padding: 7px 24px;
transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
-[dir='rtl'] button {
- float: left;
-}
-
-.primary-button {
- background: rgb(66, 133, 244);
-}
-
-.primary-button:active {
+button:active {
background: rgb(50, 102, 213);
outline: 0;
}
@@ -44,6 +37,18 @@ button:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, .50);
}
+[dir='rtl'] button {
+ float: left;
+}
+
+.ask-permission-button {
+ float: right;
+}
+
+.go-back-button {
+ float: left;
+}
+
#details {
color: #696969;
margin: 45px 0 50px;
@@ -83,11 +88,6 @@ h1 {
margin-bottom: 16px;
}
-h2 {
- font-size: 1.2em;
- font-weight: normal;
-}
-
html {
-webkit-text-size-adjust: 100%;
font-size: 125%;
@@ -103,13 +103,28 @@ html {
.main-frame-blocked {
box-sizing: border-box;
- font-size: 1em;
- line-height: 1.6em;
margin: 100px auto 0;
max-width: 600px;
width: 100%;
}
+/* "Ask your Parent" title */
+.main-frame-blocked h1 {
+ color: #202124;
+ font-family: 'Google Sans', Roboto, sans-serif;
+ font-size: 24px;
+ font-weight: normal;
+ line-height: 32px;
+}
+
+/* "You need permission..." message */
+.main-frame-blocked p {
+ color: #3c4043;
+ font-family: Roboto;
+ font-size: 16px;
+ font-weight: normal;
+}
+
#main-message > p:not([hidden]) {
display: inline;
}
@@ -138,13 +153,13 @@ html {
content: -webkit-image-set(
url(default_100_percent/logo_avatar_circle_blue_color.png) 1x,
url(default_200_percent/logo_avatar_circle_blue_color.png) 2x);
- height: 45px;
+ height: 36px;
margin-bottom: 5px;
margin-right: 15px;
margin-top: 5px;
position: relative;
user-select: none;
- width: 45px;
+ width: 36px;
}
#feedback {
@@ -154,20 +169,22 @@ html {
.custodian-information {
align-items: center;
display: flex;
- font-size: 15px;
+ font-family: Roboto;
font-weight: 400;
line-height: normal;
margin-top: 14px;
}
.custodian-name {
- color: rgba(0, 0, 0, 0.87);
- padding: 1px 0;
+ color: #202124;
+ font-size: 16px;
+ line-height: 24px;
}
.custodian-email {
- color: rgb(0, 0, 0, 0.54);
- padding: 1px 0;
+ color: #5f6368;
+ font-size: 14px;
+ line-height: 20px;
}
diff --git a/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html b/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
index c04f9249f6f..7e6f621486f 100644
--- a/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
+++ b/chromium/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
@@ -5,6 +5,7 @@
<meta name="viewport"
content="initial-scale=1, minimum-scale=1, width=device-width">
<title>$i18n{blockPageTitle}</title>
+<link href="https://fonts.googleapis.com/css?family=Google+Sans" rel="stylesheet">
<link rel="stylesheet" href="supervised_user_block_interstitial.css">
<script src="../../../ui/webui/resources/js/cr.js"></script>
<script src="../../../ui/webui/resources/js/util.js"></script>
@@ -38,7 +39,7 @@
</div>
</div>
<div class="button-container">
- <button id="request-access-button" class="primary-button">
+ <button id="request-access-button" class="ask-permission-button">
$i18n{requestAccessButton}
</button>
<div id="details-button-container">
@@ -49,7 +50,7 @@
$i18n{hideDetailsLink}
</button>
</div>
- <button id="back-button" class="details-button small-link" hidden>
+ <button id="back-button" class="go-back-button" hidden>
$i18n{backButton}
</button>
</div>
diff --git a/chromium/components/supervised_user_error_page/supervised_user_error_page.cc b/chromium/components/supervised_user_error_page/supervised_user_error_page.cc
index 92eb8befdac..bc630de15f0 100644
--- a/chromium/components/supervised_user_error_page/supervised_user_error_page.cc
+++ b/chromium/components/supervised_user_error_page/supervised_user_error_page.cc
@@ -20,8 +20,8 @@ namespace supervised_user_error_page {
namespace {
-static const int kAvatarSize1x = 45;
-static const int kAvatarSize2x = 90;
+static const int kAvatarSize1x = 36;
+static const int kAvatarSize2x = 72;
bool ReasonIsAutomatic(FilteringBehaviorReason reason) {
return reason == ASYNC_CHECKER || reason == BLACKLIST;
@@ -34,7 +34,7 @@ std::string BuildAvatarImageUrl(const std::string& url, int size) {
// Check if the URL already contains the monogram (-mo) option.
// In that case, we must use the '-' separator, instead of '/'.
std::string separator = result.substr(slash - 3, 3) == "/mo" ? "-" : "/";
- result.insert(slash, separator + "s" + base::IntToString(size) + "-c");
+ result.insert(slash, separator + "s" + base::NumberToString(size) + "-c");
}
return result;
}
diff --git a/chromium/components/supervised_user_error_page/supervised_user_error_page_unittest.cc b/chromium/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
index 873c8508103..c1e712a6172 100644
--- a/chromium/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
+++ b/chromium/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
@@ -49,9 +49,9 @@ BlockMessageIDTestParameter block_message_id_test_params[] = {
{MANUAL, true, false, IDS_CHILD_BLOCK_MESSAGE_MANUAL_MULTI_PARENT},
};
-INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
- SupervisedUserErrorPageTest_GetBlockMessageID,
- ::testing::ValuesIn(block_message_id_test_params));
+INSTANTIATE_TEST_SUITE_P(GetBlockMessageIDParameterized,
+ SupervisedUserErrorPageTest_GetBlockMessageID,
+ ::testing::ValuesIn(block_message_id_test_params));
struct BuildHtmlTestParameter {
bool allow_access_requests;
@@ -201,8 +201,8 @@ BuildHtmlTestParameter build_html_test_parameter[] = {
"custodian2_email", true, false, ASYNC_CHECKER, true},
};
-INSTANTIATE_TEST_CASE_P(GetBlockMessageIDParameterized,
- SupervisedUserErrorPageTest_BuildHtml,
- ::testing::ValuesIn(build_html_test_parameter));
+INSTANTIATE_TEST_SUITE_P(GetBlockMessageIDParameterized,
+ SupervisedUserErrorPageTest_BuildHtml,
+ ::testing::ValuesIn(build_html_test_parameter));
} // namespace supervised_user_error_page
diff --git a/chromium/components/sync/BUILD.gn b/chromium/components/sync/BUILD.gn
index a06f30a7859..129a82836e0 100644
--- a/chromium/components/sync/BUILD.gn
+++ b/chromium/components/sync/BUILD.gn
@@ -108,7 +108,6 @@ jumbo_static_library("sync") {
"driver/async_directory_type_controller.h",
"driver/backend_migrator.cc",
"driver/backend_migrator.h",
- "driver/clear_server_data_events.h",
"driver/configure_context.h",
"driver/data_type_controller.cc",
"driver/data_type_controller.h",
@@ -131,8 +130,8 @@ jumbo_static_library("sync") {
"driver/generic_change_processor_factory.h",
"driver/glue/sync_backend_host_core.cc",
"driver/glue/sync_backend_host_core.h",
- "driver/glue/sync_backend_host_impl.cc",
- "driver/glue/sync_backend_host_impl.h",
+ "driver/glue/sync_engine_impl.cc",
+ "driver/glue/sync_engine_impl.h",
"driver/model_association_manager.cc",
"driver/model_association_manager.h",
"driver/model_associator.h",
@@ -170,6 +169,8 @@ jumbo_static_library("sync") {
"driver/sync_token_status.h",
"driver/sync_type_preference_provider.h",
"driver/sync_user_settings.h",
+ "driver/sync_user_settings_impl.cc",
+ "driver/sync_user_settings_impl.h",
"driver/sync_util.cc",
"driver/sync_util.h",
"driver/syncable_service_based_model_type_controller.cc",
@@ -260,8 +261,6 @@ jumbo_static_library("sync") {
"engine_impl/apply_control_data_updates.h",
"engine_impl/backoff_delay_provider.cc",
"engine_impl/backoff_delay_provider.h",
- "engine_impl/clear_server_data.cc",
- "engine_impl/clear_server_data.h",
"engine_impl/commit.cc",
"engine_impl/commit.h",
"engine_impl/commit_contribution.cc",
@@ -301,10 +300,6 @@ jumbo_static_library("sync") {
"engine_impl/directory_commit_contributor.h",
"engine_impl/directory_update_handler.cc",
"engine_impl/directory_update_handler.h",
- "engine_impl/events/clear_server_data_request_event.cc",
- "engine_impl/events/clear_server_data_request_event.h",
- "engine_impl/events/clear_server_data_response_event.cc",
- "engine_impl/events/clear_server_data_response_event.h",
"engine_impl/events/commit_request_event.cc",
"engine_impl/events/commit_request_event.h",
"engine_impl/events/commit_response_event.cc",
@@ -610,7 +605,7 @@ jumbo_static_library("sync") {
if (is_chromeos) {
# Required by get_session_name.cc on Chrome OS.
- deps += [ "//chromeos:chromeos_constants" ]
+ deps += [ "//chromeos/constants" ]
}
if (is_mac) {
@@ -801,8 +796,6 @@ static_library("test_support_driver") {
"driver/fake_data_type_controller.h",
"driver/fake_generic_change_processor.cc",
"driver/fake_generic_change_processor.h",
- "driver/fake_sync_client.cc",
- "driver/fake_sync_client.h",
"driver/fake_sync_service.cc",
"driver/fake_sync_service.h",
"driver/frontend_data_type_controller_mock.cc",
@@ -813,6 +806,8 @@ static_library("test_support_driver") {
"driver/sync_api_component_factory_mock.h",
"driver/sync_client_mock.cc",
"driver/sync_client_mock.h",
+ "driver/sync_user_settings_mock.cc",
+ "driver/sync_user_settings_mock.h",
"driver/test_sync_service.cc",
"driver/test_sync_service.h",
"driver/test_sync_user_settings.cc",
@@ -869,7 +864,7 @@ source_set("unit_tests") {
"driver/data_type_manager_impl_unittest.cc",
"driver/frontend_data_type_controller_unittest.cc",
"driver/generic_change_processor_unittest.cc",
- "driver/glue/sync_backend_host_impl_unittest.cc",
+ "driver/glue/sync_engine_impl_unittest.cc",
"driver/model_association_manager_unittest.cc",
"driver/model_type_controller_unittest.cc",
"driver/shared_change_processor_unittest.cc",
@@ -994,7 +989,7 @@ source_set("unit_tests") {
if (is_chromeos) {
# Required by get_session_name_unittest.cc on Chrome OS.
- deps += [ "//chromeos:chromeos_constants" ]
+ deps += [ "//chromeos/constants" ]
}
if (is_ios) {
diff --git a/chromium/components/sync/android/BUILD.gn b/chromium/components/sync/android/BUILD.gn
index e16c41de3ac..37b8fc27feb 100644
--- a/chromium/components/sync/android/BUILD.gn
+++ b/chromium/components/sync/android/BUILD.gn
@@ -20,7 +20,7 @@ android_library("sync_java") {
java_files = [
"java/src/org/chromium/components/sync/AndroidSyncSettings.java",
"java/src/org/chromium/components/sync/ModelTypeHelper.java",
- "java/src/org/chromium/components/sync/PassphraseType.java",
+ "java/src/org/chromium/components/sync/Passphrase.java",
"java/src/org/chromium/components/sync/SyncConstants.java",
"java/src/org/chromium/components/sync/SyncContentResolverDelegate.java",
"java/src/org/chromium/components/sync/SystemSyncContentResolverDelegate.java",
diff --git a/chromium/components/sync/protocol/protocol_sources.gni b/chromium/components/sync/protocol/protocol_sources.gni
index 59f8b8e5ad2..169b3ae2bfe 100644
--- a/chromium/components/sync/protocol/protocol_sources.gni
+++ b/chromium/components/sync/protocol/protocol_sources.gni
@@ -24,6 +24,7 @@ sync_protocol_bases = [
"extension_specifics",
"favicon_image_specifics",
"favicon_tracking_specifics",
+ "gaia_password_reuse",
"get_updates_caller_info",
"history_delete_directive_specifics",
"history_status",
@@ -43,6 +44,7 @@ sync_protocol_bases = [
"priority_preference_specifics",
"reading_list_specifics",
"search_engine_specifics",
+ "security_event_specifics",
"send_tab_to_self_specifics",
"session_specifics",
"sync",
diff --git a/chromium/components/sync_bookmarks/bookmark_change_processor.cc b/chromium/components/sync_bookmarks/bookmark_change_processor.cc
index 32cbf98c9ae..acb064faac3 100644
--- a/chromium/components/sync_bookmarks/bookmark_change_processor.cc
+++ b/chromium/components/sync_bookmarks/bookmark_change_processor.cc
@@ -20,7 +20,6 @@
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/favicon/core/favicon_service.h"
-#include "components/sync/driver/sync_client.h"
#include "components/sync/syncable/change_record.h"
#include "components/sync/syncable/entry.h" // TODO(tim): Investigating bug 121587.
#include "components/sync/syncable/read_node.h"
@@ -42,15 +41,12 @@ namespace sync_bookmarks {
static const char kMobileBookmarksTag[] = "synced_bookmarks";
BookmarkChangeProcessor::BookmarkChangeProcessor(
- syncer::SyncClient* sync_client,
BookmarkModelAssociator* model_associator,
std::unique_ptr<syncer::DataTypeErrorHandler> err_handler)
: syncer::ChangeProcessor(std::move(err_handler)),
bookmark_model_(nullptr),
- sync_client_(sync_client),
model_associator_(model_associator) {
DCHECK(model_associator);
- DCHECK(sync_client);
DCHECK(error_handler());
}
@@ -62,7 +58,7 @@ BookmarkChangeProcessor::~BookmarkChangeProcessor() {
void BookmarkChangeProcessor::StartImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!bookmark_model_);
- bookmark_model_ = sync_client_->GetBookmarkModel();
+ bookmark_model_ = model_associator_->GetBookmarkModel();
DCHECK(bookmark_model_->loaded());
bookmark_model_->AddObserver(this);
}
@@ -584,7 +580,7 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel(
// Changes made to the bookmark model due to sync should not be undoable.
ScopedSuspendBookmarkUndo suspend_undo(
- sync_client_->GetBookmarkUndoServiceIfExists());
+ model_associator_->GetBookmarkUndoService());
// Notify UI intensive observers of BookmarkModel that we are about to make
// potentially significant changes to it, so the updates may be batched. For
@@ -702,7 +698,8 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel(
if (dst) {
DCHECK(it->action == ChangeRecord::ACTION_UPDATE)
<< "ACTION_UPDATE should be seen if and only if the node is known.";
- UpdateBookmarkWithSyncData(src, model, dst, sync_client_);
+ UpdateBookmarkWithSyncData(src, model, dst,
+ model_associator_->GetFaviconService());
// Move all modified entries to the right. We'll fix it later.
model->Move(dst, parent, parent->child_count());
@@ -710,7 +707,8 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel(
DCHECK(it->action == ChangeRecord::ACTION_ADD)
<< "ACTION_ADD should be seen if and only if the node is unknown.";
- dst = CreateBookmarkNode(&src, parent, model, sync_client_,
+ dst = CreateBookmarkNode(&src, parent, model,
+ model_associator_->GetFaviconService(),
parent->child_count());
if (!dst) {
// We ignore bookmarks we can't add. Chances are this is caused by
@@ -763,7 +761,7 @@ void BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
const syncer::BaseNode& sync_node,
BookmarkModel* model,
const BookmarkNode* node,
- syncer::SyncClient* sync_client) {
+ favicon::FaviconService* favicon_service) {
DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
const sync_pb::BookmarkSpecifics& specifics =
sync_node.GetBookmarkSpecifics();
@@ -775,7 +773,7 @@ void BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
node,
base::Time::FromInternalValue(specifics.creation_time_us()));
}
- SetBookmarkFavicon(&sync_node, node, sync_client);
+ SetBookmarkFavicon(&sync_node, node, favicon_service);
model->SetNodeMetaInfoMap(node, *GetBookmarkMetaInfo(&sync_node));
}
@@ -799,11 +797,11 @@ const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
const syncer::BaseNode* sync_node,
const BookmarkNode* parent,
BookmarkModel* model,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
int index) {
return CreateBookmarkNode(base::UTF8ToUTF16(sync_node->GetTitle()),
GURL(sync_node->GetBookmarkSpecifics().url()),
- sync_node, parent, model, sync_client, index);
+ sync_node, parent, model, favicon_service, index);
}
// static
@@ -815,7 +813,7 @@ const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
const syncer::BaseNode* sync_node,
const BookmarkNode* parent,
BookmarkModel* model,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
int index) {
DCHECK(parent);
@@ -834,7 +832,7 @@ const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
parent, index, title, url, create_time,
GetBookmarkMetaInfo(sync_node).get());
if (node)
- SetBookmarkFavicon(sync_node, node, sync_client);
+ SetBookmarkFavicon(sync_node, node, favicon_service);
}
return node;
@@ -845,7 +843,7 @@ const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
void BookmarkChangeProcessor::SetBookmarkFavicon(
const syncer::BaseNode* sync_node,
const BookmarkNode* bookmark_node,
- syncer::SyncClient* sync_client) {
+ favicon::FaviconService* favicon_service) {
const sync_pb::BookmarkSpecifics& specifics =
sync_node->GetBookmarkSpecifics();
const std::string& icon_bytes_str = specifics.favicon();
@@ -853,8 +851,8 @@ void BookmarkChangeProcessor::SetBookmarkFavicon(
new base::RefCountedString());
icon_bytes->data().assign(icon_bytes_str);
- ApplyBookmarkFavicon(bookmark_node, sync_client, GURL(specifics.icon_url()),
- icon_bytes);
+ ApplyBookmarkFavicon(bookmark_node, favicon_service,
+ GURL(specifics.icon_url()), icon_bytes);
}
// static
@@ -921,12 +919,10 @@ void BookmarkChangeProcessor::SetSyncNodeMetaInfo(
// static
void BookmarkChangeProcessor::ApplyBookmarkFavicon(
const BookmarkNode* bookmark_node,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
const GURL& icon_url,
const scoped_refptr<base::RefCountedMemory>& bitmap_data) {
- favicon::FaviconService* favicon_service = sync_client->GetFaviconService();
-
- // Some tests (that use FakeSyncClient) use no services.
+ // Some tests use no services.
if (favicon_service == nullptr)
return;
diff --git a/chromium/components/sync_bookmarks/bookmark_change_processor.h b/chromium/components/sync_bookmarks/bookmark_change_processor.h
index 72234f5f238..e11a2ddf641 100644
--- a/chromium/components/sync_bookmarks/bookmark_change_processor.h
+++ b/chromium/components/sync_bookmarks/bookmark_change_processor.h
@@ -25,11 +25,14 @@ class RefCountedMemory;
} // namespace base
namespace syncer {
-class SyncClient;
class WriteNode;
class WriteTransaction;
} // namespace syncer
+namespace favicon {
+class FaviconService;
+} // namespace favicon
+
namespace sync_bookmarks {
// This class is responsible for taking changes from the BookmarkModel
@@ -40,7 +43,6 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver,
public syncer::ChangeProcessor {
public:
BookmarkChangeProcessor(
- syncer::SyncClient* sync_client,
BookmarkModelAssociator* model_associator,
std::unique_ptr<syncer::DataTypeErrorHandler> error_handler);
~BookmarkChangeProcessor() override;
@@ -92,10 +94,11 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver,
// Updates the title, URL, creation time and favicon of the bookmark |node|
// with data taken from the |sync_node| sync node.
- static void UpdateBookmarkWithSyncData(const syncer::BaseNode& sync_node,
- bookmarks::BookmarkModel* model,
- const bookmarks::BookmarkNode* node,
- syncer::SyncClient* sync_client);
+ static void UpdateBookmarkWithSyncData(
+ const syncer::BaseNode& sync_node,
+ bookmarks::BookmarkModel* model,
+ const bookmarks::BookmarkNode* node,
+ favicon::FaviconService* favicon_service);
// Creates a bookmark node under the given parent node from the given sync
// node. Returns the newly created node. The created node is placed at the
@@ -104,7 +107,7 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver,
const syncer::BaseNode* sync_node,
const bookmarks::BookmarkNode* parent,
bookmarks::BookmarkModel* model,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
int index);
// Overload of CreateBookmarkNode function above that helps to avoid
@@ -115,20 +118,20 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver,
const syncer::BaseNode* sync_node,
const bookmarks::BookmarkNode* parent,
bookmarks::BookmarkModel* model,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
int index);
// Sets the favicon of the given bookmark node from the given sync node.
static void SetBookmarkFavicon(const syncer::BaseNode* sync_node,
const bookmarks::BookmarkNode* bookmark_node,
- syncer::SyncClient* sync_client);
+ favicon::FaviconService* favicon_service);
// Applies the 1x favicon |bitmap_data| and |icon_url| to |bookmark_node|.
// |profile| is the profile that contains the HistoryService and BookmarkModel
// for the bookmark in question.
static void ApplyBookmarkFavicon(
const bookmarks::BookmarkNode* bookmark_node,
- syncer::SyncClient* sync_client,
+ favicon::FaviconService* favicon_service,
const GURL& icon_url,
const scoped_refptr<base::RefCountedMemory>& bitmap_data);
@@ -241,8 +244,6 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver,
// |running_| is true.
bookmarks::BookmarkModel* bookmark_model_;
- syncer::SyncClient* sync_client_;
-
// The two models should be associated according to this ModelAssociator.
BookmarkModelAssociator* model_associator_;
diff --git a/chromium/components/sync_bookmarks/bookmark_data_type_controller.cc b/chromium/components/sync_bookmarks/bookmark_data_type_controller.cc
index 24f358a11f6..709c6c63a90 100644
--- a/chromium/components/sync_bookmarks/bookmark_data_type_controller.cc
+++ b/chromium/components/sync_bookmarks/bookmark_data_type_controller.cc
@@ -11,7 +11,6 @@
#include "components/history/core/browser/history_service.h"
#include "components/sync/driver/model_associator.h"
#include "components/sync/driver/sync_api_component_factory.h"
-#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/change_processor.h"
@@ -20,13 +19,17 @@ using bookmarks::BookmarkModel;
namespace sync_bookmarks {
BookmarkDataTypeController::BookmarkDataTypeController(
- const base::Closure& dump_stack,
+ const base::RepeatingClosure& dump_stack,
syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client)
+ bookmarks::BookmarkModel* bookmark_model,
+ history::HistoryService* history_service,
+ syncer::SyncApiComponentFactory* component_factory)
: syncer::FrontendDataTypeController(syncer::BOOKMARKS,
dump_stack,
sync_service),
- sync_client_(sync_client),
+ bookmark_model_(bookmark_model),
+ history_service_(history_service),
+ component_factory_(component_factory),
history_service_observer_(this),
bookmark_model_observer_(this) {}
@@ -35,11 +38,8 @@ BookmarkDataTypeController::~BookmarkDataTypeController() {}
bool BookmarkDataTypeController::StartModels() {
DCHECK(CalledOnValidThread());
if (!DependentsLoaded()) {
- BookmarkModel* bookmark_model = sync_client_->GetBookmarkModel();
- bookmark_model_observer_.Add(bookmark_model);
- history::HistoryService* history_service =
- sync_client_->GetHistoryService();
- history_service_observer_.Add(history_service);
+ bookmark_model_observer_.Add(bookmark_model_);
+ history_service_observer_.Add(history_service_);
return false;
}
return true;
@@ -54,7 +54,7 @@ void BookmarkDataTypeController::CleanUpState() {
void BookmarkDataTypeController::CreateSyncComponents() {
DCHECK(CalledOnValidThread());
syncer::SyncApiComponentFactory::SyncComponents sync_components =
- sync_client_->GetSyncApiComponentFactory()->CreateBookmarkSyncComponents(
+ component_factory_->CreateBookmarkSyncComponents(
CreateErrorHandler(), sync_service()->GetUserShare());
set_model_associator(std::move(sync_components.model_associator));
set_change_processor(std::move(sync_components.change_processor));
@@ -85,12 +85,10 @@ void BookmarkDataTypeController::BookmarkModelBeingDeleted(
// are loaded.
bool BookmarkDataTypeController::DependentsLoaded() {
DCHECK(CalledOnValidThread());
- BookmarkModel* bookmark_model = sync_client_->GetBookmarkModel();
- if (!bookmark_model || !bookmark_model->loaded())
+ if (!bookmark_model_ || !bookmark_model_->loaded())
return false;
- history::HistoryService* history_service = sync_client_->GetHistoryService();
- if (!history_service || !history_service->BackendLoaded())
+ if (!history_service_ || !history_service_->BackendLoaded())
return false;
// All necessary services are loaded.
diff --git a/chromium/components/sync_bookmarks/bookmark_data_type_controller.h b/chromium/components/sync_bookmarks/bookmark_data_type_controller.h
index bb78735d442..febbeec2e4b 100644
--- a/chromium/components/sync_bookmarks/bookmark_data_type_controller.h
+++ b/chromium/components/sync_bookmarks/bookmark_data_type_controller.h
@@ -14,7 +14,7 @@
#include "components/sync/driver/frontend_data_type_controller.h"
namespace syncer {
-class SyncClient;
+class SyncApiComponentFactory;
class SyncService;
} // namespace syncer
@@ -26,9 +26,12 @@ class BookmarkDataTypeController : public syncer::FrontendDataTypeController,
public history::HistoryServiceObserver {
public:
// |dump_stack| is called when an unrecoverable error occurs.
- BookmarkDataTypeController(const base::Closure& dump_stack,
- syncer::SyncService* sync_service,
- syncer::SyncClient* sync_client);
+ BookmarkDataTypeController(
+ const base::RepeatingClosure& dump_stack,
+ syncer::SyncService* sync_service,
+ bookmarks::BookmarkModel* bookmark_model,
+ history::HistoryService* history_service,
+ syncer::SyncApiComponentFactory* component_factory);
~BookmarkDataTypeController() override;
private:
@@ -52,7 +55,9 @@ class BookmarkDataTypeController : public syncer::FrontendDataTypeController,
void HistoryServiceBeingDeleted(
history::HistoryService* history_service) override;
- syncer::SyncClient* const sync_client_;
+ bookmarks::BookmarkModel* const bookmark_model_;
+ history::HistoryService* const history_service_;
+ syncer::SyncApiComponentFactory* const component_factory_;
ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
history_service_observer_;
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 1f56d6e1c07..b89dbfc8723 100644
--- a/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
+++ b/chromium/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
@@ -20,7 +20,6 @@
#include "components/prefs/testing_pref_service.h"
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/data_type_controller_mock.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/driver/fake_sync_service.h"
#include "components/sync/driver/model_associator_mock.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
@@ -55,20 +54,10 @@ class HistoryMock : public history::HistoryService {
} // namespace
-class SyncBookmarkDataTypeControllerTest : public testing::Test,
- public syncer::FakeSyncClient {
+class SyncBookmarkDataTypeControllerTest : public testing::Test {
public:
SyncBookmarkDataTypeControllerTest() {}
- // FakeSyncClient overrides.
- BookmarkModel* GetBookmarkModel() override { return bookmark_model_.get(); }
- history::HistoryService* GetHistoryService() override {
- return history_service_.get();
- }
- syncer::SyncApiComponentFactory* GetSyncApiComponentFactory() override {
- return &components_factory_;
- }
-
void SetUp() override {
model_associator_deleter_ =
std::make_unique<NiceMock<ModelAssociatorMock>>();
@@ -76,9 +65,12 @@ class SyncBookmarkDataTypeControllerTest : public testing::Test,
std::make_unique<NiceMock<ChangeProcessorMock>>();
model_associator_ = model_associator_deleter_.get();
change_processor_ = change_processor_deleter_.get();
+ bookmark_model_ = std::make_unique<BookmarkModel>(
+ std::make_unique<bookmarks::TestBookmarkClient>());
history_service_ = std::make_unique<HistoryMock>();
bookmark_dtc_ = std::make_unique<BookmarkDataTypeController>(
- base::DoNothing(), &service_, this);
+ base::DoNothing(), &service_, bookmark_model_.get(),
+ history_service_.get(), &components_factory_);
ON_CALL(components_factory_, CreateBookmarkSyncComponents(_, _))
.WillByDefault(testing::InvokeWithoutArgs([=]() {
@@ -90,21 +82,12 @@ class SyncBookmarkDataTypeControllerTest : public testing::Test,
}
protected:
- enum BookmarkLoadPolicy {
- DONT_LOAD_MODEL,
- LOAD_MODEL,
- };
-
- void CreateBookmarkModel(BookmarkLoadPolicy bookmark_load_policy) {
- bookmark_model_ = std::make_unique<BookmarkModel>(
- std::make_unique<bookmarks::TestBookmarkClient>());
- if (bookmark_load_policy == LOAD_MODEL) {
- TestingPrefServiceSimple prefs;
- bookmark_model_->Load(&prefs, base::FilePath(),
- base::SequencedTaskRunnerHandle::Get(),
- base::SequencedTaskRunnerHandle::Get());
- bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_.get());
- }
+ void LoadBookmarkModel() {
+ TestingPrefServiceSimple prefs;
+ bookmark_model_->Load(&prefs, base::FilePath(),
+ base::SequencedTaskRunnerHandle::Get(),
+ base::SequencedTaskRunnerHandle::Get());
+ bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_.get());
}
void SetStartExpectations() {
@@ -157,7 +140,7 @@ class SyncBookmarkDataTypeControllerTest : public testing::Test,
};
TEST_F(SyncBookmarkDataTypeControllerTest, StartDependentsReady) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
SetAssociateExpectations();
@@ -169,7 +152,6 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartDependentsReady) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartBookmarkModelNotReady) {
- CreateBookmarkModel(DONT_LOAD_MODEL);
SetStartExpectations();
SetAssociateExpectations();
@@ -196,7 +178,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartBookmarkModelNotReady) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartHistoryServiceNotReady) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
EXPECT_CALL(*history_service_.get(), BackendLoaded())
.WillRepeatedly(Return(false));
@@ -217,7 +199,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartHistoryServiceNotReady) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartFirstRun) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
SetAssociateExpectations();
EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
@@ -227,7 +209,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartFirstRun) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartBusy) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
EXPECT_CALL(*history_service_.get(), BackendLoaded())
.WillRepeatedly(Return(false));
@@ -243,7 +225,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartBusy) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartOk) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
SetAssociateExpectations();
EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_))
@@ -254,7 +236,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartOk) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartAssociationFailed) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
// Set up association to fail.
EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
@@ -275,7 +257,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartAssociationFailed) {
TEST_F(SyncBookmarkDataTypeControllerTest,
StartAssociationTriggersUnrecoverableError) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
// Set up association to fail with an unrecoverable error.
EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()).
@@ -289,7 +271,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest,
}
TEST_F(SyncBookmarkDataTypeControllerTest, StartAborted) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
EXPECT_CALL(*history_service_.get(), BackendLoaded())
.WillRepeatedly(Return(false));
@@ -303,7 +285,7 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartAborted) {
}
TEST_F(SyncBookmarkDataTypeControllerTest, Stop) {
- CreateBookmarkModel(LOAD_MODEL);
+ LoadBookmarkModel();
SetStartExpectations();
SetAssociateExpectations();
SetStopExpectations();
diff --git a/chromium/components/sync_bookmarks/bookmark_local_changes_builder.cc b/chromium/components/sync_bookmarks/bookmark_local_changes_builder.cc
index 92bda90302a..9d4210fe477 100644
--- a/chromium/components/sync_bookmarks/bookmark_local_changes_builder.cc
+++ b/chromium/components/sync_bookmarks/bookmark_local_changes_builder.cc
@@ -10,7 +10,6 @@
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/sync/base/time.h"
-#include "components/sync/engine/engine_util.h"
#include "components/sync/protocol/bookmark_model_metadata.pb.h"
#include "components/sync_bookmarks/bookmark_specifics_conversions.h"
#include "components/sync_bookmarks/synced_bookmark_tracker.h"
@@ -61,18 +60,12 @@ BookmarkLocalChangesBuilder::BuildCommitRequests(size_t max_entries) const {
// 2. Bookmarks (maybe ancient legacy bookmarks only?) use/used |name| to
// encode the title.
data.is_folder = node->is_folder();
- // Adjust the non_unique_name for backward compatibility with legacy
- // clients.
- std::string new_legal_title;
- syncer::SyncAPINameToServerName(base::UTF16ToUTF8(node->GetTitle()),
- &new_legal_title);
- base::TruncateUTF8ToByteSize(new_legal_title, 255, &new_legal_title);
- data.non_unique_name = new_legal_title;
data.unique_position = metadata->unique_position();
// Assign specifics only for the non-deletion case. In case of deletion,
// EntityData should contain empty specifics to indicate deletion.
data.specifics = CreateSpecificsFromBookmarkNode(
node, bookmark_model_, /*force_favicon_load=*/true);
+ data.non_unique_name = data.specifics.bookmark().title();
}
request.entity = data.PassToPtr();
request.sequence_number = metadata->sequence_number();
diff --git a/chromium/components/sync_bookmarks/bookmark_model_associator.cc b/chromium/components/sync_bookmarks/bookmark_model_associator.cc
index 7508dd73969..958a6ffa60b 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_associator.cc
+++ b/chromium/components/sync_bookmarks/bookmark_model_associator.cc
@@ -20,7 +20,6 @@
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/sync/base/cryptographer.h"
#include "components/sync/base/data_type_histogram.h"
-#include "components/sync/driver/sync_client.h"
#include "components/sync/engine/engine_util.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/model/sync_merge_result.h"
@@ -297,12 +296,14 @@ void BookmarkModelAssociator::Context::MarkForVersionUpdate(
BookmarkModelAssociator::BookmarkModelAssociator(
BookmarkModel* bookmark_model,
- syncer::SyncClient* sync_client,
+ BookmarkUndoService* bookmark_undo_service,
+ favicon::FaviconService* favicon_service,
syncer::UserShare* user_share,
std::unique_ptr<syncer::DataTypeErrorHandler> unrecoverable_error_handler,
bool expect_mobile_bookmarks_folder)
: bookmark_model_(bookmark_model),
- sync_client_(sync_client),
+ bookmark_undo_service_(bookmark_undo_service),
+ favicon_service_(favicon_service),
user_share_(user_share),
unrecoverable_error_handler_(std::move(unrecoverable_error_handler)),
expect_mobile_bookmarks_folder_(expect_mobile_bookmarks_folder),
@@ -316,6 +317,18 @@ BookmarkModelAssociator::~BookmarkModelAssociator() {
DCHECK(thread_checker_.CalledOnValidThread());
}
+bookmarks::BookmarkModel* BookmarkModelAssociator::GetBookmarkModel() {
+ return bookmark_model_;
+}
+
+favicon::FaviconService* BookmarkModelAssociator::GetFaviconService() {
+ return favicon_service_;
+}
+
+BookmarkUndoService* BookmarkModelAssociator::GetBookmarkUndoService() {
+ return bookmark_undo_service_;
+}
+
syncer::SyncError BookmarkModelAssociator::DisassociateModels() {
id_map_.clear();
id_map_inverse_.clear();
@@ -436,8 +449,7 @@ syncer::SyncError BookmarkModelAssociator::AssociateModels(
syncer::SyncMergeResult* syncer_merge_result) {
// Since any changes to the bookmark model made here are not user initiated,
// these change should not be undoable and so suspend the undo tracking.
- ScopedSuspendBookmarkUndo suspend_undo(
- sync_client_->GetBookmarkUndoServiceIfExists());
+ ScopedSuspendBookmarkUndo suspend_undo(bookmark_undo_service_);
Context context(local_merge_result, syncer_merge_result);
@@ -681,7 +693,7 @@ syncer::SyncError BookmarkModelAssociator::BuildAssociations(
(parent_node->GetChild(index) == child_node);
if (!is_in_sync) {
BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
- sync_child_node, bookmark_model_, child_node, sync_client_);
+ sync_child_node, bookmark_model_, child_node, favicon_service_);
bookmark_model_->Move(child_node, parent_node, index);
context->IncrementLocalItemsModified();
context->MarkForVersionUpdate(child_node);
@@ -755,7 +767,7 @@ const BookmarkNode* BookmarkModelAssociator::CreateBookmarkNode(
base::string16 bookmark_title = base::UTF8ToUTF16(sync_title);
const BookmarkNode* child_node = BookmarkChangeProcessor::CreateBookmarkNode(
bookmark_title, url, sync_child_node, parent_node, bookmark_model_,
- sync_client_, bookmark_index);
+ favicon_service_, bookmark_index);
if (!child_node) {
*error = unrecoverable_error_handler_->CreateAndUploadError(
FROM_HERE, "Failed to create bookmark node with title " + sync_title +
diff --git a/chromium/components/sync_bookmarks/bookmark_model_associator.h b/chromium/components/sync_bookmarks/bookmark_model_associator.h
index bbf21979cd4..70873dc3b69 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_associator.h
+++ b/chromium/components/sync_bookmarks/bookmark_model_associator.h
@@ -26,20 +26,24 @@
#include "components/sync/driver/model_associator.h"
#include "components/sync/model/data_type_error_handler.h"
+class BookmarkUndoService;
class GURL;
namespace bookmarks {
class BookmarkModel;
class BookmarkNode;
-}
+} // namespace bookmarks
+
+namespace favicon {
+class FaviconService;
+} // namespace favicon
namespace syncer {
class BaseNode;
class BaseTransaction;
-class SyncClient;
class WriteTransaction;
struct UserShare;
-}
+} // namespace syncer
namespace sync_bookmarks {
@@ -50,17 +54,23 @@ namespace sync_bookmarks {
class BookmarkModelAssociator : public syncer::AssociatorInterface {
public:
static syncer::ModelType model_type() { return syncer::BOOKMARKS; }
+
// |expect_mobile_bookmarks_folder| controls whether or not we
// expect the mobile bookmarks permanent folder to be created.
// Should be set to true only by mobile clients.
BookmarkModelAssociator(
bookmarks::BookmarkModel* bookmark_model,
- syncer::SyncClient* sync_client,
+ BookmarkUndoService* bookmark_undo_service,
+ favicon::FaviconService* favicon_service,
syncer::UserShare* user_share,
std::unique_ptr<syncer::DataTypeErrorHandler> unrecoverable_error_handler,
bool expect_mobile_bookmarks_folder);
~BookmarkModelAssociator() override;
+ bookmarks::BookmarkModel* GetBookmarkModel();
+ favicon::FaviconService* GetFaviconService();
+ BookmarkUndoService* GetBookmarkUndoService();
+
// AssociatorInterface implementation.
//
// AssociateModels iterates through both the sync and the browser
@@ -282,9 +292,10 @@ class BookmarkModelAssociator : public syncer::AssociatorInterface {
syncer::SyncError CheckModelSyncState(Context* context) const;
base::ThreadChecker thread_checker_;
- bookmarks::BookmarkModel* bookmark_model_;
- syncer::SyncClient* sync_client_;
- syncer::UserShare* user_share_;
+ bookmarks::BookmarkModel* const bookmark_model_;
+ BookmarkUndoService* const bookmark_undo_service_;
+ favicon::FaviconService* const favicon_service_;
+ syncer::UserShare* const user_share_;
std::unique_ptr<syncer::DataTypeErrorHandler> unrecoverable_error_handler_;
const bool expect_mobile_bookmarks_folder_;
BookmarkIdToSyncIdMap id_map_;
diff --git a/chromium/components/sync_bookmarks/bookmark_model_type_processor.cc b/chromium/components/sync_bookmarks/bookmark_model_type_processor.cc
index 1e21c4fa91e..eb091cf835f 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_type_processor.cc
+++ b/chromium/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -6,7 +6,9 @@
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
+#include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/bookmarks/browser/bookmark_model.h"
@@ -32,6 +34,15 @@ namespace sync_bookmarks {
namespace {
+// Enables scheduling bookmark model saving only upon changes in entity sync
+// metadata. This would stop persisting changes to the model type state that
+// doesn't involve changes to the entity metadata as well.
+// TODO(crbug.com/945820): This should be removed in M80 if not issues are
+// observed.
+const base::Feature kSyncScheduleForEntityMetadataChangesOnly{
+ "SyncScheduleForEntityMetadataChangesOnly",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
class ScopedRemoteUpdateBookmarks {
public:
// |bookmark_model|, |bookmark_undo_service| and |observer| must not be null
@@ -209,8 +220,14 @@ void BookmarkModelTypeProcessor::OnUpdateReceived(
bookmark_tracker_->set_model_type_state(
std::make_unique<sync_pb::ModelTypeState>(model_type_state));
updates_handler.Process(updates, got_new_encryption_requirements);
- // Schedule save just in case one is needed.
- schedule_save_closure_.Run();
+ // There are cases when we receive non-empty updates that don't result in
+ // model changes (e.g. reflections). In that case, issue a write to persit the
+ // progress marker in order to avoid downloading those updates again.
+ if (!updates.empty() || !base::FeatureList::IsEnabled(
+ kSyncScheduleForEntityMetadataChangesOnly)) {
+ // Schedule save just in case one is needed.
+ schedule_save_closure_.Run();
+ }
}
const SyncedBookmarkTracker* BookmarkModelTypeProcessor::GetTrackerForTest()
diff --git a/chromium/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc b/chromium/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
index 6bb9b2f4cef..9edc84a3250 100644
--- a/chromium/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
+++ b/chromium/components/sync_bookmarks/bookmark_model_type_processor_unittest.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
@@ -14,7 +15,6 @@
#include "components/bookmarks/test/test_bookmark_client.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "components/sync/base/unique_position.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/model/data_type_activation_request.h"
#include "components/undo/bookmark_undo_service.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -258,8 +258,9 @@ TEST_F(BookmarkModelTypeProcessorTest, ShouldUpdateModelAfterRemoteUpdate) {
EXPECT_THAT(bookmark_node->url(), Eq(GURL(kNewUrl)));
}
-TEST_F(BookmarkModelTypeProcessorTest,
- ShouldScheduleSaveAfterRemoteUpdateWithOnlyMetadataChange) {
+TEST_F(
+ BookmarkModelTypeProcessorTest,
+ ShouldScheduleSaveAfterRemoteUpdateWithOnlyMetadataChangeAndReflections) {
const std::string kNodeId = "node_id";
const std::string kTitle = "title";
const std::string kUrl = "http://www.url.com";
@@ -444,7 +445,6 @@ TEST_F(BookmarkModelTypeProcessorTest,
sync_pb::ModelTypeState model_type_state(CreateDummyModelTypeState());
model_type_state.set_encryption_key_name(kEncryptionKeyName);
- EXPECT_CALL(*schedule_save_closure(), Run());
// Push empty updates list to the processor together with the updated model
// type state.
processor()->OnUpdateReceived(model_type_state,
diff --git a/chromium/components/sync_bookmarks/bookmark_specifics_conversions.cc b/chromium/components/sync_bookmarks/bookmark_specifics_conversions.cc
index f949a1b67a4..cbb43999d3f 100644
--- a/chromium/components/sync_bookmarks/bookmark_specifics_conversions.cc
+++ b/chromium/components/sync_bookmarks/bookmark_specifics_conversions.cc
@@ -7,11 +7,13 @@
#include <string>
#include <unordered_set>
#include <utility>
+#include <vector>
#include "base/strings/utf_string_conversions.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/favicon/core/favicon_service.h"
+#include "components/sync/engine/engine_util.h"
#include "components/sync/protocol/sync.pb.h"
#include "ui/gfx/favicon_size.h"
#include "url/gurl.h"
@@ -20,6 +22,27 @@ namespace sync_bookmarks {
namespace {
+// Maximum number of bytes to allow in a title (must match sync's internal
+// limits; see write_node.cc).
+const int kTitleLimitBytes = 255;
+
+base::string16 NodeTitleFromSpecificsTitle(const std::string& specifics_title) {
+ // Adjust the title for backward compatibility with legacy clients.
+ std::string node_title;
+ syncer::ServerNameToSyncAPIName(specifics_title, &node_title);
+ return base::UTF8ToUTF16(node_title);
+}
+
+std::string SpecificsTitleFromNodeTitle(const base::string16& node_title) {
+ // Adjust the title for backward compatibility with legacy clients.
+ std::string specifics_title;
+ syncer::SyncAPINameToServerName(base::UTF16ToUTF8(node_title),
+ &specifics_title);
+ base::TruncateUTF8ToByteSize(specifics_title, kTitleLimitBytes,
+ &specifics_title);
+ return specifics_title;
+}
+
void UpdateBookmarkSpecificsMetaInfo(
const bookmarks::BookmarkNode::MetaInfoMap* metainfo_map,
sync_pb::BookmarkSpecifics* bm_specifics) {
@@ -96,7 +119,7 @@ sync_pb::EntitySpecifics CreateSpecificsFromBookmarkNode(
if (!node->is_folder()) {
bm_specifics->set_url(node->url().spec());
}
- bm_specifics->set_title(base::UTF16ToUTF8(node->GetTitle()));
+ bm_specifics->set_title(SpecificsTitleFromNodeTitle(node->GetTitle()));
bm_specifics->set_creation_time_us(
node->date_added().ToDeltaSinceWindowsEpoch().InMicroseconds());
@@ -150,7 +173,8 @@ const bookmarks::BookmarkNode* CreateBookmarkNodeFromSpecifics(
const bookmarks::BookmarkNode* node;
if (is_folder) {
node = model->AddFolderWithMetaInfo(
- parent, index, base::UTF8ToUTF16(specifics.title()), &metainfo);
+ parent, index, NodeTitleFromSpecificsTitle(specifics.title()),
+ &metainfo);
} else {
const int64_t create_time_us = specifics.creation_time_us();
base::Time create_time = base::Time::FromDeltaSinceWindowsEpoch(
@@ -158,7 +182,7 @@ const bookmarks::BookmarkNode* CreateBookmarkNodeFromSpecifics(
// always used the Windows epoch.
base::TimeDelta::FromMicroseconds(create_time_us));
node = model->AddURLWithCreationTimeAndMetaInfo(
- parent, index, base::UTF8ToUTF16(specifics.title()),
+ parent, index, NodeTitleFromSpecificsTitle(specifics.title()),
GURL(specifics.url()), create_time, &metainfo);
}
if (node) {
@@ -180,7 +204,7 @@ void UpdateBookmarkNodeFromSpecifics(
model->SetURL(node, GURL(specifics.url()));
}
- model->SetTitle(node, base::UTF8ToUTF16(specifics.title()));
+ model->SetTitle(node, NodeTitleFromSpecificsTitle(specifics.title()));
model->SetNodeMetaInfoMap(node, GetBookmarkMetaInfo(specifics));
SetBookmarkFaviconFromSpecifics(specifics, node, favicon_service);
}
diff --git a/chromium/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc b/chromium/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc
index 15418414fa6..4be58ae1caf 100644
--- a/chromium/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc
+++ b/chromium/components/sync_bookmarks/bookmark_specifics_conversions_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include <utility>
+#include <vector>
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
@@ -89,6 +90,26 @@ TEST(BookmarkSpecificsConversionsTest, ShouldCreateSpecificsFromBookmarkNode) {
}
TEST(BookmarkSpecificsConversionsTest,
+ ShouldCreateSpecificsFromBookmarkNodeWithIllegalTitle) {
+ std::unique_ptr<bookmarks::BookmarkModel> model =
+ bookmarks::TestBookmarkClient::CreateModel();
+
+ const bookmarks::BookmarkNode* bookmark_bar_node = model->bookmark_bar_node();
+ const std::vector<std::string> illegal_titles = {"", ".", ".."};
+ int index = 0;
+ for (const std::string& illegal_title : illegal_titles) {
+ const bookmarks::BookmarkNode* node = model->AddURL(
+ /*parent=*/bookmark_bar_node, index++, base::UTF8ToUTF16(illegal_title),
+ GURL("http://www.url.com"));
+ ASSERT_THAT(node, NotNull());
+ sync_pb::EntitySpecifics specifics = CreateSpecificsFromBookmarkNode(
+ node, model.get(), /*force_favicon_load=*/false);
+ // Legacy clients append a space to illegal titles.
+ EXPECT_THAT(specifics.bookmark().title(), Eq(illegal_title + " "));
+ }
+}
+
+TEST(BookmarkSpecificsConversionsTest,
ShouldCreateSpecificsWithoutUrlFromFolderNode) {
std::unique_ptr<bookmarks::BookmarkModel> model =
bookmarks::TestBookmarkClient::CreateModel();
@@ -194,6 +215,31 @@ TEST(BookmarkSpecificsConversionsTest, ShouldCreateBookmarkNodeFromSpecifics) {
}
TEST(BookmarkSpecificsConversionsTest,
+ ShouldCreateBookmarkNodeFromSpecificsWithIllegalTitle) {
+ std::unique_ptr<bookmarks::BookmarkModel> model =
+ bookmarks::TestBookmarkClient::CreateModel();
+ testing::NiceMock<favicon::MockFaviconService> favicon_service;
+
+ const std::vector<std::string> illegal_titles = {"", ".", ".."};
+
+ int index = 0;
+ for (const std::string& illegal_title : illegal_titles) {
+ sync_pb::EntitySpecifics specifics;
+ sync_pb::BookmarkSpecifics* bm_specifics = specifics.mutable_bookmark();
+ bm_specifics->set_url("http://www.url.com");
+ // Legacy clients append an extra space to illegal clients.
+ bm_specifics->set_title(illegal_title + " ");
+ const bookmarks::BookmarkNode* node = CreateBookmarkNodeFromSpecifics(
+ *bm_specifics,
+ /*parent=*/model->bookmark_bar_node(), index++,
+ /*is_folder=*/false, model.get(), &favicon_service);
+ ASSERT_THAT(node, NotNull());
+ // The node should be created without the extra space.
+ EXPECT_THAT(node->GetTitle(), Eq(base::UTF8ToUTF16(illegal_title)));
+ }
+}
+
+TEST(BookmarkSpecificsConversionsTest,
ShouldCreateBookmarkNodeFromSpecificsWithFaviconAndWithoutIconUrl) {
const GURL kUrl("http://www.url.com");
const std::string kTitle = "Title";
diff --git a/chromium/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc b/chromium/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc
index a711f89d638..b83caa677cd 100644
--- a/chromium/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc
+++ b/chromium/components/sync_bookmarks/synced_bookmark_tracker_unittest.cc
@@ -5,7 +5,6 @@
#include "components/sync_bookmarks/synced_bookmark_tracker.h"
#include "base/base64.h"
-#include "base/sha1.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "components/bookmarks/browser/bookmark_model.h"
diff --git a/chromium/components/sync_preferences/pref_model_associator.cc b/chromium/components/sync_preferences/pref_model_associator.cc
index 09602ffb549..4a2fe0651cc 100644
--- a/chromium/components/sync_preferences/pref_model_associator.cc
+++ b/chromium/components/sync_preferences/pref_model_associator.cc
@@ -97,7 +97,7 @@ void PrefModelAssociator::InitPrefAndAssociate(
DCHECK(pref_name == preference.name());
base::JSONReader reader;
std::unique_ptr<base::Value> sync_value(
- reader.ReadToValue(preference.value()));
+ reader.ReadToValueDeprecated(preference.value()));
if (!sync_value.get()) {
LOG(ERROR) << "Failed to deserialize value of preference '" << pref_name
<< "': " << reader.GetErrorMessage();
@@ -420,7 +420,8 @@ syncer::SyncError PrefModelAssociator::ProcessSyncChanges(
base::Value* PrefModelAssociator::ReadPreferenceSpecifics(
const sync_pb::PreferenceSpecifics& preference) {
base::JSONReader reader;
- std::unique_ptr<base::Value> value(reader.ReadToValue(preference.value()));
+ std::unique_ptr<base::Value> value(
+ reader.ReadToValueDeprecated(preference.value()));
if (!value.get()) {
std::string err =
"Failed to deserialize preference value: " + reader.GetErrorMessage();
diff --git a/chromium/components/sync_preferences/pref_service_syncable_unittest.cc b/chromium/components/sync_preferences/pref_service_syncable_unittest.cc
index 3c4b3e5f90a..e79214908e8 100644
--- a/chromium/components/sync_preferences/pref_service_syncable_unittest.cc
+++ b/chromium/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_string_value_serializer.h"
#include "base/json/json_writer.h"
@@ -166,7 +167,7 @@ class PrefServiceSyncableTest : public testing::Test {
auto it = list.begin();
for (; it != list.end(); ++it) {
if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) {
- return base::JSONReader::Read(
+ return base::JSONReader::ReadDeprecated(
it->sync_data().GetSpecifics().preference().value());
}
}
@@ -206,7 +207,7 @@ TEST_F(PrefServiceSyncableTest, CreatePrefSyncData) {
EXPECT_EQ(std::string(kStringPrefName), specifics.name());
std::unique_ptr<base::Value> value =
- base::JSONReader::Read(specifics.value());
+ base::JSONReader::ReadDeprecated(specifics.value());
EXPECT_TRUE(pref->GetValue()->Equals(value.get()));
}
@@ -416,7 +417,7 @@ class PrefServiceSyncableMergeTest : public testing::Test {
auto it = list.begin();
for (; it != list.end(); ++it) {
if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) {
- return base::JSONReader::Read(
+ return base::JSONReader::ReadDeprecated(
it->sync_data().GetSpecifics().preference().value());
}
}
diff --git a/chromium/components/sync_sessions/favicon_cache.cc b/chromium/components/sync_sessions/favicon_cache.cc
index 53014c5f7cd..bae2883eb18 100644
--- a/chromium/components/sync_sessions/favicon_cache.cc
+++ b/chromium/components/sync_sessions/favicon_cache.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
@@ -518,6 +519,10 @@ void FaviconCache::UpdateMappingsFromForeignTab(const sync_pb::SessionTab& tab,
}
}
+base::WeakPtr<FaviconCache> FaviconCache::GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
size_t FaviconCache::NumFaviconsForTest() const {
return synced_favicons_.size();
}
diff --git a/chromium/components/sync_sessions/favicon_cache.h b/chromium/components/sync_sessions/favicon_cache.h
index 292636af11c..08946fba2d0 100644
--- a/chromium/components/sync_sessions/favicon_cache.h
+++ b/chromium/components/sync_sessions/favicon_cache.h
@@ -106,6 +106,8 @@ class FaviconCache : public syncer::SyncableService,
void UpdateMappingsFromForeignTab(const sync_pb::SessionTab& tab,
base::Time visit_time);
+ base::WeakPtr<FaviconCache> GetWeakPtr();
+
// For testing only.
size_t NumFaviconsForTest() const;
size_t NumTasksForTest() const;
diff --git a/chromium/components/sync_sessions/local_session_event_handler_impl.cc b/chromium/components/sync_sessions/local_session_event_handler_impl.cc
index 3eedc3c0a80..bf7d848c3b8 100644
--- a/chromium/components/sync_sessions/local_session_event_handler_impl.cc
+++ b/chromium/components/sync_sessions/local_session_event_handler_impl.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "components/sync/model/sync_change.h"
@@ -303,7 +304,7 @@ void LocalSessionEventHandlerImpl::AssociateTab(
int current_index = tab_delegate->GetCurrentEntryIndex();
const GURL new_url = tab_delegate->GetVirtualURLAtIndex(current_index);
- if (new_url != old_url) {
+ if (current_index >= 0 && new_url != old_url) {
delegate_->OnFaviconVisited(
new_url, tab_delegate->GetFaviconURLAtIndex(current_index));
}
diff --git a/chromium/components/sync_sessions/lost_navigations_recorder.h b/chromium/components/sync_sessions/lost_navigations_recorder.h
index a9c314ad833..e3d5f91f0a4 100644
--- a/chromium/components/sync_sessions/lost_navigations_recorder.h
+++ b/chromium/components/sync_sessions/lost_navigations_recorder.h
@@ -53,6 +53,6 @@ class LostNavigationsRecorder : public syncer::LocalChangeObserver {
std::map<SessionID, id_type> max_recorded_for_tab_;
DISALLOW_COPY_AND_ASSIGN(LostNavigationsRecorder);
};
-}; // namespace sync_sessions
+} // namespace sync_sessions
#endif // COMPONENTS_SYNC_SESSIONS_LOST_NAVIGATIONS_RECORDER_H_
diff --git a/chromium/components/sync_sessions/lost_navigations_recorder_unittest.cc b/chromium/components/sync_sessions/lost_navigations_recorder_unittest.cc
index 495e6a0d638..f3efa7015f5 100644
--- a/chromium/components/sync_sessions/lost_navigations_recorder_unittest.cc
+++ b/chromium/components/sync_sessions/lost_navigations_recorder_unittest.cc
@@ -392,5 +392,5 @@ TEST_F(LostNavigationsRecorderTest, MultipleNavsMultipleLostWithOverlap) {
histogram_tester.ExpectBucketCount("Sync.LostNavigationCount", 2, 1);
}
-}; // namespace
-}; // namespace sync_sessions
+} // namespace
+} // namespace sync_sessions
diff --git a/chromium/components/sync_sessions/open_tabs_ui_delegate_impl_unittest.cc b/chromium/components/sync_sessions/open_tabs_ui_delegate_impl_unittest.cc
index 3f924a38c06..1b30ab846a4 100644
--- a/chromium/components/sync_sessions/open_tabs_ui_delegate_impl_unittest.cc
+++ b/chromium/components/sync_sessions/open_tabs_ui_delegate_impl_unittest.cc
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/time/time.h"
#include "components/sessions/core/serialized_navigation_entry_test_helper.h"
#include "components/sync_sessions/mock_sync_sessions_client.h"
diff --git a/chromium/components/sync_sessions/session_model_type_controller.cc b/chromium/components/sync_sessions/session_model_type_controller.cc
index 3d1ee221f31..ab1384acdbc 100644
--- a/chromium/components/sync_sessions/session_model_type_controller.cc
+++ b/chromium/components/sync_sessions/session_model_type_controller.cc
@@ -6,8 +6,8 @@
#include <utility>
+#include "base/bind.h"
#include "components/prefs/pref_service.h"
-#include "components/sync/driver/sync_client.h"
namespace sync_sessions {
diff --git a/chromium/components/sync_sessions/session_store.cc b/chromium/components/sync_sessions/session_store.cc
index d91625e0547..935b76d05dd 100644
--- a/chromium/components/sync_sessions/session_store.cc
+++ b/chromium/components/sync_sessions/session_store.cc
@@ -13,6 +13,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
@@ -100,122 +101,31 @@ void ForwardError(syncer::OnceModelErrorHandler error_handler,
}
}
-class FactoryImpl : public base::SupportsWeakPtr<FactoryImpl> {
- public:
- // Raw pointers must not be null and must outlive this object.
- FactoryImpl(SyncSessionsClient* sessions_client,
- const SessionStore::RestoredForeignTabCallback&
- restored_foreign_tab_callback)
- : sessions_client_(sessions_client),
- restored_foreign_tab_callback_(restored_foreign_tab_callback) {
- DCHECK(sessions_client);
- }
-
- ~FactoryImpl() {}
-
- void Create(const syncer::DeviceInfo& device_info,
- SessionStore::FactoryCompletionCallback callback) {
- const std::string& cache_guid = device_info.guid();
- DCHECK(!cache_guid.empty());
-
- SessionStore::SessionInfo session_info;
- session_info.client_name = device_info.client_name();
- session_info.device_type = device_info.device_type();
- session_info.session_tag = GetSessionTagWithPrefs(
- cache_guid, sessions_client_->GetSessionSyncPrefs());
-
- DVLOG(1) << "Initiating creation of session store";
-
- sessions_client_->GetStoreFactory().Run(
- syncer::SESSIONS,
- base::BindOnce(&FactoryImpl::OnStoreCreated, base::AsWeakPtr(this),
- session_info, std::move(callback)));
- }
-
- private:
- void OnStoreCreated(const SessionStore::SessionInfo& session_info,
- SessionStore::FactoryCompletionCallback callback,
- const base::Optional<syncer::ModelError>& error,
- std::unique_ptr<ModelTypeStore> store) {
- if (error) {
- std::move(callback).Run(error, /*store=*/nullptr,
- /*metadata_batch=*/nullptr);
- return;
- }
-
- DCHECK(store);
- ModelTypeStore* store_copy = store.get();
- store_copy->ReadAllData(
- base::BindOnce(&FactoryImpl::OnReadAllData, base::AsWeakPtr(this),
- session_info, std::move(callback), std::move(store)));
- }
-
- void OnReadAllData(const SessionStore::SessionInfo& session_info,
- SessionStore::FactoryCompletionCallback callback,
- std::unique_ptr<ModelTypeStore> store,
- const base::Optional<syncer::ModelError>& error,
- std::unique_ptr<ModelTypeStore::RecordList> record_list) {
- if (error) {
- std::move(callback).Run(error, /*store=*/nullptr,
- /*metadata_batch=*/nullptr);
- return;
- }
-
- ModelTypeStore* store_raw = store.get();
- store_raw->ReadAllMetadata(base::BindOnce(
- &FactoryImpl::OnReadAllMetadata, base::AsWeakPtr(this), session_info,
- std::move(callback), std::move(store), std::move(record_list)));
- }
-
- void OnReadAllMetadata(
- const SessionStore::SessionInfo& session_info,
- SessionStore::FactoryCompletionCallback callback,
- std::unique_ptr<ModelTypeStore> store,
- std::unique_ptr<ModelTypeStore::RecordList> record_list,
- const base::Optional<syncer::ModelError>& error,
- std::unique_ptr<syncer::MetadataBatch> metadata_batch) {
- // Remove after fixing https://crbug.com/902203.
- TRACE_EVENT0("browser", "FactoryImpl::OnReadAllMetadata");
- if (error) {
- std::move(callback).Run(error, /*store=*/nullptr,
- /*metadata_batch=*/nullptr);
- return;
- }
-
- std::map<std::string, sync_pb::SessionSpecifics> initial_data;
- for (ModelTypeStore::Record& record : *record_list) {
- const std::string& storage_key = record.id;
- SessionSpecifics specifics;
- if (storage_key.empty() ||
- !specifics.ParseFromString(std::move(record.value))) {
- DVLOG(1) << "Ignoring corrupt database entry with key: " << storage_key;
- continue;
- }
- initial_data[storage_key].Swap(&specifics);
- }
-
- auto session_store = std::make_unique<SessionStore>(
- sessions_client_, session_info, std::move(store),
- std::move(initial_data), metadata_batch->GetAllMetadata(),
- restored_foreign_tab_callback_);
-
- std::move(callback).Run(/*error=*/base::nullopt, std::move(session_store),
- std::move(metadata_batch));
- }
-
- SyncSessionsClient* const sessions_client_;
- const SessionStore::RestoredForeignTabCallback restored_foreign_tab_callback_;
-};
-
} // namespace
// static
-SessionStore::Factory SessionStore::CreateFactory(
+void SessionStore::Open(
+ const syncer::DeviceInfo& device_info,
+ const RestoredForeignTabCallback& restored_foreign_tab_callback,
SyncSessionsClient* sessions_client,
- const RestoredForeignTabCallback& restored_foreign_tab_callback) {
- auto factory = std::make_unique<FactoryImpl>(sessions_client,
- restored_foreign_tab_callback);
- return base::BindRepeating(&FactoryImpl::Create, std::move(factory));
+ OpenCallback callback) {
+ DCHECK(sessions_client);
+ DCHECK(!device_info.guid().empty());
+
+ SessionStore::SessionInfo session_info;
+ session_info.client_name = device_info.client_name();
+ session_info.device_type = device_info.device_type();
+ session_info.session_tag = GetSessionTagWithPrefs(
+ device_info.guid(), sessions_client->GetSessionSyncPrefs());
+
+ DVLOG(1) << "Opening session store";
+ // WrapUnique() used because constructor is private.
+ auto session_store = base::WrapUnique(new SessionStore(
+ session_info, restored_foreign_tab_callback, sessions_client));
+ sessions_client->GetStoreFactory().Run(
+ syncer::SESSIONS,
+ base::BindOnce(&OnStoreCreated, std::move(session_store),
+ std::move(callback)));
}
SessionStore::WriteBatch::WriteBatch(
@@ -380,27 +290,110 @@ std::string SessionStore::GetTabClientTagForTest(const std::string& session_tag,
return TabNodeIdToClientTag(session_tag, tab_node_id);
}
+// static
+void SessionStore::OnStoreCreated(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<ModelTypeStore> underlying_store) {
+ if (error) {
+ std::move(callback).Run(error, /*store=*/nullptr,
+ /*metadata_batch=*/nullptr);
+ return;
+ }
+
+ DCHECK(underlying_store);
+ ModelTypeStore* underlying_store_copy = underlying_store.get();
+ underlying_store_copy->ReadAllMetadata(
+ base::BindOnce(&OnReadAllMetadata, std::move(session_store),
+ std::move(callback), std::move(underlying_store)));
+}
+
+// static
+void SessionStore::OnReadAllMetadata(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ std::unique_ptr<ModelTypeStore> underlying_store,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch) {
+ if (error) {
+ std::move(callback).Run(error, /*store=*/nullptr,
+ /*metadata_batch=*/nullptr);
+ return;
+ }
+
+ ModelTypeStore* underlying_store_copy = underlying_store.get();
+ underlying_store_copy->ReadAllData(base::BindOnce(
+ &OnReadAllData, std::move(session_store), std::move(callback),
+ std::move(underlying_store), std::move(metadata_batch)));
+}
+
+// static
+void SessionStore::OnReadAllData(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ std::unique_ptr<ModelTypeStore> underlying_store,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<ModelTypeStore::RecordList> record_list) {
+ // Remove after fixing https://crbug.com/902203.
+ TRACE_EVENT0("browser", "OnReadAllMetadata");
+ if (error) {
+ std::move(callback).Run(error, /*store=*/nullptr,
+ /*metadata_batch=*/nullptr);
+ return;
+ }
+
+ std::map<std::string, sync_pb::SessionSpecifics> initial_data;
+ for (ModelTypeStore::Record& record : *record_list) {
+ const std::string& storage_key = record.id;
+ SessionSpecifics specifics;
+ if (storage_key.empty() ||
+ !specifics.ParseFromString(std::move(record.value))) {
+ DVLOG(1) << "Ignoring corrupt database entry with key: " << storage_key;
+ continue;
+ }
+ initial_data[storage_key].Swap(&specifics);
+ }
+
+ // We avoid initialization of the store if the callback was cancelled, in
+ // case dependencies (SessionSyncClient) are already destroyed, even though
+ // the current implementation doesn't seem to crash otherwise.
+ if (callback.IsCancelled()) {
+ return;
+ }
+
+ session_store->Init(std::move(underlying_store), std::move(initial_data),
+ metadata_batch->GetAllMetadata());
+
+ std::move(callback).Run(/*error=*/base::nullopt, std::move(session_store),
+ std::move(metadata_batch));
+}
+
SessionStore::SessionStore(
- SyncSessionsClient* sessions_client,
const SessionInfo& local_session_info,
- std::unique_ptr<ModelTypeStore> store,
- std::map<std::string, sync_pb::SessionSpecifics> initial_data,
- const syncer::EntityMetadataMap& initial_metadata,
- const RestoredForeignTabCallback& restored_foreign_tab_callback)
- : store_(std::move(store)),
- local_session_info_(local_session_info),
+ const RestoredForeignTabCallback& restored_foreign_tab_callback,
+ SyncSessionsClient* sessions_client)
+ : local_session_info_(local_session_info),
+ restored_foreign_tab_callback_(restored_foreign_tab_callback),
session_tracker_(sessions_client),
weak_ptr_factory_(this) {
- DCHECK(store_);
+ session_tracker_.InitLocalSession(local_session_info_.session_tag,
+ local_session_info_.client_name,
+ local_session_info_.device_type);
+}
- DVLOG(1) << "Constructed session store with " << initial_data.size()
+void SessionStore::Init(
+ std::unique_ptr<ModelTypeStore> store,
+ std::map<std::string, sync_pb::SessionSpecifics> initial_data,
+ const syncer::EntityMetadataMap& initial_metadata) {
+ DCHECK(store);
+ store_ = std::move(store);
+
+ DVLOG(1) << "Initializing session store with " << initial_data.size()
<< " restored entities and " << initial_metadata.size()
<< " metadata entries.";
- session_tracker_.InitLocalSession(local_session_info.session_tag,
- local_session_info.client_name,
- local_session_info.device_type);
-
bool found_local_header = false;
for (auto& storage_key_and_specifics : initial_data) {
@@ -424,13 +417,13 @@ SessionStore::SessionStore(
const base::Time mtime =
syncer::ProtoTimeToTime(metadata_it->second.modification_time());
- if (specifics.session_tag() != local_session_info.session_tag) {
+ if (specifics.session_tag() != local_session_info_.session_tag) {
UpdateTrackerWithSpecifics(specifics, mtime, &session_tracker_);
// Notify listeners. In practice, this has the goal to load the URLs and
// visit times into the in-memory favicon cache.
if (specifics.has_tab()) {
- restored_foreign_tab_callback.Run(specifics.tab(), mtime);
+ restored_foreign_tab_callback_.Run(specifics.tab(), mtime);
}
} else if (specifics.has_header()) {
// This is previously stored local header information. Restoring the local
@@ -529,7 +522,12 @@ std::unique_ptr<SessionStore::WriteBatch> SessionStore::CreateWriteBatch(
void SessionStore::DeleteAllDataAndMetadata() {
session_tracker_.Clear();
- return store_->DeleteAllDataAndMetadata(base::DoNothing());
+ store_->DeleteAllDataAndMetadata(base::DoNothing());
+
+ // At all times, the local session must be tracked.
+ session_tracker_.InitLocalSession(local_session_info_.session_tag,
+ local_session_info_.client_name,
+ local_session_info_.device_type);
}
} // namespace sync_sessions
diff --git a/chromium/components/sync_sessions/session_store.h b/chromium/components/sync_sessions/session_store.h
index 80d95446476..7c9f10230cd 100644
--- a/chromium/components/sync_sessions/session_store.h
+++ b/chromium/components/sync_sessions/session_store.h
@@ -38,25 +38,23 @@ class SessionStore {
sync_pb::SyncEnums::DeviceType device_type = sync_pb::SyncEnums::TYPE_UNSET;
};
- // Creation factory. The instantiation process is quite complex because it
- // loads state from disk.
- using FactoryCompletionCallback = base::OnceCallback<void(
+ using OpenCallback = base::OnceCallback<void(
const base::Optional<syncer::ModelError>& error,
std::unique_ptr<SessionStore> store,
std::unique_ptr<syncer::MetadataBatch> metadata_batch)>;
- using Factory =
- base::RepeatingCallback<void(const syncer::DeviceInfo& device_info,
- FactoryCompletionCallback callback)>;
// Mimics signature of FaviconCache::UpdateMappingsFromForeignTab().
using RestoredForeignTabCallback =
base::RepeatingCallback<void(const sync_pb::SessionTab&, base::Time)>;
- // Creates a factory object that is capable of constructing instances of type
- // |SessionStore| and handling the involved IO. |sessions_client| must not be
- // null and must outlive the factory as well as the instantiated stores.
- static Factory CreateFactory(
+ // Opens a SessionStore instance, which involves IO to load previous state
+ // from disk. |sessions_client| must not be null and must outlive the
+ // SessionStore instance returned via |callback|, or until the callback is
+ // cancelled.
+ static void Open(
+ const syncer::DeviceInfo& device_info,
+ const RestoredForeignTabCallback& restored_foreign_tab_callback,
SyncSessionsClient* sessions_client,
- const RestoredForeignTabCallback& restored_foreign_tab_callback);
+ OpenCallback callback);
// Verifies whether a proto is malformed (e.g. required fields are missing).
static bool AreValidSpecifics(const sync_pb::SessionSpecifics& specifics);
@@ -120,15 +118,6 @@ class SessionStore {
DISALLOW_COPY_AND_ASSIGN(WriteBatch);
};
- // Construction once all data and metadata has been loaded from disk. Use
- // the factory above to take care of the IO. |sessions_client| must not be
- // null and must outlive this object.
- SessionStore(SyncSessionsClient* sessions_client,
- const SessionInfo& local_session_info,
- std::unique_ptr<syncer::ModelTypeStore> store,
- std::map<std::string, sync_pb::SessionSpecifics> initial_data,
- const syncer::EntityMetadataMap& initial_metadata,
- const RestoredForeignTabCallback& restored_foreign_tab_callback);
~SessionStore();
const SessionInfo& local_session_info() const { return local_session_info_; }
@@ -155,10 +144,43 @@ class SessionStore {
const SyncedSessionTracker* tracker() const { return &session_tracker_; }
private:
+ static void OnStoreCreated(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore> underlying_store);
+ static void OnReadAllMetadata(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ std::unique_ptr<syncer::ModelTypeStore> underlying_store,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch);
+ static void OnReadAllData(
+ std::unique_ptr<SessionStore> session_store,
+ OpenCallback callback,
+ std::unique_ptr<syncer::ModelTypeStore> underlying_store,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch,
+ const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<syncer::ModelTypeStore::RecordList> record_list);
+
+ // Construction prior to any data being read from disk. Callers are expected
+ // to read state from disk and call Init(). |sessions_client| must not be null
+ // and must outlive this object.
+ SessionStore(const SessionInfo& local_session_info,
+ const RestoredForeignTabCallback& restored_foreign_tab_callback,
+ SyncSessionsClient* sessions_client);
+
+ // Initialization once IO is completed.
+ void Init(std::unique_ptr<syncer::ModelTypeStore> store,
+ std::map<std::string, sync_pb::SessionSpecifics> initial_data,
+ const syncer::EntityMetadataMap& initial_metadata);
+
+ const SessionInfo local_session_info_;
+ const RestoredForeignTabCallback restored_foreign_tab_callback_;
+
// In charge of actually persisting changes to disk.
std::unique_ptr<syncer::ModelTypeStore> store_;
- const SessionInfo local_session_info_;
SyncedSessionTracker session_tracker_;
diff --git a/chromium/components/sync_sessions/session_store_unittest.cc b/chromium/components/sync_sessions/session_store_unittest.cc
index 1517cce4313..19566f31dcc 100644
--- a/chromium/components/sync_sessions/session_store_unittest.cc
+++ b/chromium/components/sync_sessions/session_store_unittest.cc
@@ -8,7 +8,9 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/cancelable_callback.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
@@ -54,16 +56,16 @@ const char kClientName[] = "Some Client Name";
// A mock callback that a) can be used as mock to verify call expectations and
// b) conveniently exposes the last instantiated session store.
-class MockFactoryCompletionCallback {
+class MockOpenCallback {
public:
MOCK_METHOD3(Run,
void(const base::Optional<syncer::ModelError>& error,
SessionStore* store,
MetadataBatch* metadata_batch));
- SessionStore::FactoryCompletionCallback Get() {
+ SessionStore::OpenCallback Get() {
return base::BindOnce(
- [](MockFactoryCompletionCallback* callback,
+ [](MockOpenCallback* callback,
const base::Optional<syncer::ModelError>& error,
std::unique_ptr<SessionStore> store,
std::unique_ptr<MetadataBatch> metadata_batch) {
@@ -152,9 +154,9 @@ std::map<std::string, SessionSpecifics> ReadAllPersistedDataFrom(
return result;
}
-class SessionStoreFactoryTest : public ::testing::Test {
+class SessionStoreOpenTest : public ::testing::Test {
protected:
- SessionStoreFactoryTest()
+ SessionStoreOpenTest()
: local_device_info_(kCacheGuid,
kClientName,
"Chromium 10k",
@@ -167,39 +169,39 @@ class SessionStoreFactoryTest : public ::testing::Test {
syncer::SESSIONS)) {
SessionSyncPrefs::RegisterProfilePrefs(pref_service_.registry());
- ON_CALL(mock_sync_sessions_client_, GetSessionSyncPrefs())
+ mock_sync_sessions_client_ =
+ std::make_unique<testing::NiceMock<MockSyncSessionsClient>>();
+
+ ON_CALL(*mock_sync_sessions_client_, GetSessionSyncPrefs())
.WillByDefault(Return(&session_sync_prefs_));
- ON_CALL(mock_sync_sessions_client_, GetStoreFactory())
+ ON_CALL(*mock_sync_sessions_client_, GetStoreFactory())
.WillByDefault(
Return(syncer::ModelTypeStoreTestUtil::FactoryForForwardingStore(
underlying_store_.get())));
-
- factory_ = SessionStore::CreateFactory(
- &mock_sync_sessions_client_, mock_restored_foreign_tab_callback_.Get());
}
- ~SessionStoreFactoryTest() override {}
+ ~SessionStoreOpenTest() override {}
base::test::ScopedTaskEnvironment task_environment_;
const syncer::DeviceInfo local_device_info_;
TestingPrefServiceSimple pref_service_;
SessionSyncPrefs session_sync_prefs_;
- testing::NiceMock<MockSyncSessionsClient> mock_sync_sessions_client_;
+ std::unique_ptr<MockSyncSessionsClient> mock_sync_sessions_client_;
testing::NiceMock<
base::MockCallback<SessionStore::RestoredForeignTabCallback>>
mock_restored_foreign_tab_callback_;
-
std::unique_ptr<ModelTypeStore> underlying_store_;
- SessionStore::Factory factory_;
};
-TEST_F(SessionStoreFactoryTest, ShouldCreateStore) {
+TEST_F(SessionStoreOpenTest, ShouldCreateStore) {
ASSERT_THAT(session_sync_prefs_.GetSyncSessionsGUID(), IsEmpty());
- MockFactoryCompletionCallback completion;
+ MockOpenCallback completion;
EXPECT_CALL(completion, Run(NoModelError(), /*store=*/NotNull(),
MetadataBatchContains(_, IsEmpty())));
- factory_.Run(local_device_info_, completion.Get());
+ SessionStore::Open(local_device_info_,
+ mock_restored_foreign_tab_callback_.Get(),
+ mock_sync_sessions_client_.get(), completion.Get());
completion.Wait();
ASSERT_THAT(completion.GetResult(), NotNull());
EXPECT_THAT(completion.GetResult()->local_session_info().client_name,
@@ -208,12 +210,14 @@ TEST_F(SessionStoreFactoryTest, ShouldCreateStore) {
Eq(std::string("session_sync") + kCacheGuid));
}
-TEST_F(SessionStoreFactoryTest, ShouldReadSessionsGuidFromPrefs) {
+TEST_F(SessionStoreOpenTest, ShouldReadSessionsGuidFromPrefs) {
const std::string kCachedGuid = "cachedguid1";
session_sync_prefs_.SetSyncSessionsGUID(kCachedGuid);
- NiceMock<MockFactoryCompletionCallback> completion;
- factory_.Run(local_device_info_, completion.Get());
+ NiceMock<MockOpenCallback> completion;
+ SessionStore::Open(local_device_info_,
+ mock_restored_foreign_tab_callback_.Get(),
+ mock_sync_sessions_client_.get(), completion.Get());
completion.Wait();
ASSERT_THAT(completion.GetResult(), NotNull());
EXPECT_THAT(completion.GetResult()->local_session_info().session_tag,
@@ -221,8 +225,47 @@ TEST_F(SessionStoreFactoryTest, ShouldReadSessionsGuidFromPrefs) {
EXPECT_THAT(session_sync_prefs_.GetSyncSessionsGUID(), Eq(kCachedGuid));
}
+TEST_F(SessionStoreOpenTest, ShouldNotUseClientIfCancelled) {
+ // Mimics a caller that uses a weak pointer.
+ class Caller {
+ public:
+ explicit Caller(SessionStore::OpenCallback cb)
+ : cb_(std::move(cb)), weak_ptr_factory_(this) {}
+
+ SessionStore::OpenCallback GetCancelableCallback() {
+ return base::BindOnce(&Caller::Completed, weak_ptr_factory_.GetWeakPtr());
+ }
+
+ private:
+ void Completed(const base::Optional<syncer::ModelError>& error,
+ std::unique_ptr<SessionStore> store,
+ std::unique_ptr<syncer::MetadataBatch> metadata_batch) {
+ std::move(cb_).Run(error, std::move(store), std::move(metadata_batch));
+ }
+
+ SessionStore::OpenCallback cb_;
+ base::WeakPtrFactory<Caller> weak_ptr_factory_;
+ };
+
+ NiceMock<MockOpenCallback> mock_completion;
+ auto caller = std::make_unique<Caller>(mock_completion.Get());
+
+ EXPECT_CALL(mock_completion, Run(_, _, _)).Times(0);
+
+ SessionStore::Open(
+ local_device_info_, mock_restored_foreign_tab_callback_.Get(),
+ mock_sync_sessions_client_.get(), caller->GetCancelableCallback());
+
+ // The client gets destroyed before callback completion.
+ mock_sync_sessions_client_.reset();
+ caller.reset();
+
+ // Run until idle to test for crashes due to use-after-free.
+ base::RunLoop().RunUntilIdle();
+}
+
// Test fixture that creates an initial session store.
-class SessionStoreTest : public SessionStoreFactoryTest {
+class SessionStoreTest : public SessionStoreOpenTest {
protected:
const std::string kLocalSessionTag = "localsessiontag";
@@ -232,8 +275,10 @@ class SessionStoreTest : public SessionStoreFactoryTest {
}
std::unique_ptr<SessionStore> CreateSessionStore() {
- NiceMock<MockFactoryCompletionCallback> completion;
- factory_.Run(local_device_info_, completion.Get());
+ NiceMock<MockOpenCallback> completion;
+ SessionStore::Open(local_device_info_,
+ mock_restored_foreign_tab_callback_.Get(),
+ mock_sync_sessions_client_.get(), completion.Get());
completion.Wait();
EXPECT_THAT(completion.GetResult(), NotNull());
return completion.StealResult();
@@ -296,12 +341,14 @@ TEST_F(SessionStoreTest, ShouldWriteAndRestoreMetadata) {
ElementsAre(Pair(kStorageKey1, _))));
// Create second session store.
- NiceMock<MockFactoryCompletionCallback> completion;
+ NiceMock<MockOpenCallback> completion;
EXPECT_CALL(completion, Run(NoModelError(), /*store=*/NotNull(),
MetadataBatchContains(
HasEncryptionKeyName(kEncryptionKeyName1),
ElementsAre(Pair(kStorageKey1, _)))));
- factory_.Run(local_device_info_, completion.Get());
+ SessionStore::Open(local_device_info_,
+ mock_restored_foreign_tab_callback_.Get(),
+ mock_sync_sessions_client_.get(), completion.Get());
completion.Wait();
EXPECT_THAT(completion.GetResult(), NotNull());
EXPECT_NE(session_store(), completion.GetResult());
diff --git a/chromium/components/sync_sessions/session_sync_bridge.cc b/chromium/components/sync_sessions/session_sync_bridge.cc
index b9956b5b004..4f5fead7a51 100644
--- a/chromium/components/sync_sessions/session_sync_bridge.cc
+++ b/chromium/components/sync_sessions/session_sync_bridge.cc
@@ -112,10 +112,6 @@ SessionSyncBridge::SessionSyncBridge(
favicon_cache_(sessions_client->GetFaviconService(),
sessions_client->GetHistoryService(),
kMaxSyncFavicons),
- session_store_factory_(SessionStore::CreateFactory(
- sessions_client,
- base::BindRepeating(&FaviconCache::UpdateMappingsFromForeignTab,
- base::Unretained(&favicon_cache_)))),
weak_ptr_factory_(this) {
DCHECK(sessions_client_);
DCHECK(local_session_event_router_);
@@ -127,15 +123,6 @@ SessionSyncBridge::~SessionSyncBridge() {
}
}
-void SessionSyncBridge::ScheduleGarbageCollection() {
- if (!syncing_) {
- return;
- }
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&SessionSyncBridge::DoGarbageCollection,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
FaviconCache* SessionSyncBridge::GetFaviconCache() {
return &favicon_cache_;
}
@@ -159,7 +146,7 @@ SessionSyncBridge::CreateMetadataChangeList() {
base::Optional<syncer::ModelError> SessionSyncBridge::MergeSyncData(
std::unique_ptr<MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
- DCHECK(syncing_);
+ DCHECK(!syncing_);
DCHECK(change_processor()->IsTrackingMetadata());
StartLocalSessionEventHandler();
@@ -170,14 +157,22 @@ base::Optional<syncer::ModelError> SessionSyncBridge::MergeSyncData(
void SessionSyncBridge::StartLocalSessionEventHandler() {
// We should be ready to propagate local state to sync.
- DCHECK(syncing_);
- DCHECK(!syncing_->local_session_event_handler);
DCHECK(change_processor()->IsTrackingMetadata());
+ DCHECK(!syncing_);
+ syncing_.emplace();
+
+ // Constructing LocalSessionEventHandlerImpl takes care of the "merge" logic,
+ // that is, associating the local windows and tabs with the state in the
+ // store.
syncing_->local_session_event_handler =
std::make_unique<LocalSessionEventHandlerImpl>(
- /*delegate=*/this, sessions_client_,
- syncing_->store->mutable_tracker());
+ /*delegate=*/this, sessions_client_, store_->mutable_tracker());
+
+ syncing_->open_tabs_ui_delegate = std::make_unique<OpenTabsUIDelegateImpl>(
+ sessions_client_, store_->tracker(), &favicon_cache_,
+ base::BindRepeating(&SessionSyncBridge::DeleteForeignSessionFromUI,
+ base::Unretained(this)));
// Start processing local changes, which will be propagated to the store as
// well as the processor.
@@ -203,8 +198,7 @@ base::Optional<syncer::ModelError> SessionSyncBridge::ApplySyncChanges(
// Deletions are all or nothing (since we only ever delete entire
// sessions). Therefore we don't care if it's a tab node or meta node,
// and just ensure we've disassociated.
- if (syncing_->store->StorageKeyMatchesLocalSession(
- change.storage_key())) {
+ if (store_->StorageKeyMatchesLocalSession(change.storage_key())) {
// Another client has attempted to delete our local data (possibly by
// error or a clock is inaccurate). Just ignore the deletion for now.
DLOG(WARNING) << "Local session data deleted. Ignoring until next "
@@ -227,8 +221,7 @@ base::Optional<syncer::ModelError> SessionSyncBridge::ApplySyncChanges(
case syncer::EntityChange::ACTION_UPDATE: {
const SessionSpecifics& specifics = change.data().specifics.session();
- if (syncing_->store->StorageKeyMatchesLocalSession(
- change.storage_key())) {
+ if (store_->StorageKeyMatchesLocalSession(change.storage_key())) {
// We should only ever receive a change to our own machine's session
// info if encryption was turned on. In that case, the data is still
// the same, so we can ignore.
@@ -260,6 +253,9 @@ base::Optional<syncer::ModelError> SessionSyncBridge::ApplySyncChanges(
static_cast<syncer::InMemoryMetadataChangeList*>(metadata_change_list.get())
->TransferChangesTo(batch->GetMetadataChangeList());
+
+ DoGarbageCollection(batch.get());
+
SessionStore::WriteBatch::Commit(std::move(batch));
if (!entity_changes.empty()) {
@@ -272,12 +268,12 @@ base::Optional<syncer::ModelError> SessionSyncBridge::ApplySyncChanges(
void SessionSyncBridge::GetData(StorageKeyList storage_keys,
DataCallback callback) {
DCHECK(syncing_);
- std::move(callback).Run(syncing_->store->GetSessionDataForKeys(storage_keys));
+ std::move(callback).Run(store_->GetSessionDataForKeys(storage_keys));
}
void SessionSyncBridge::GetAllDataForDebugging(DataCallback callback) {
DCHECK(syncing_);
- std::move(callback).Run(syncing_->store->GetAllSessionData());
+ std::move(callback).Run(store_->GetAllSessionData());
}
std::string SessionSyncBridge::GetClientTag(
@@ -296,14 +292,14 @@ std::string SessionSyncBridge::GetStorageKey(
return SessionStore::GetStorageKey(entity_data.specifics.session());
}
-ModelTypeSyncBridge::StopSyncResponse SessionSyncBridge::ApplyStopSyncChanges(
+void SessionSyncBridge::ApplyStopSyncChanges(
std::unique_ptr<MetadataChangeList> delete_metadata_change_list) {
+ DCHECK(store_);
local_session_event_router_->Stop();
- if (syncing_ && delete_metadata_change_list) {
- syncing_->store->DeleteAllDataAndMetadata();
+ if (delete_metadata_change_list) {
+ store_->DeleteAllDataAndMetadata();
}
syncing_.reset();
- return StopSyncResponse::kModelNoLongerReadyToSync;
}
std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch>
@@ -323,13 +319,13 @@ SessionSyncBridge::CreateLocalSessionWriteBatch() {
}
return std::make_unique<LocalSessionWriteBatch>(
- syncing_->store->local_session_info(), CreateSessionStoreWriteBatch(),
+ store_->local_session_info(), CreateSessionStoreWriteBatch(),
change_processor());
}
bool SessionSyncBridge::IsTabNodeUnsynced(int tab_node_id) {
const std::string storage_key = SessionStore::GetTabStorageKey(
- syncing_->store->local_session_info().session_tag, tab_node_id);
+ store_->local_session_info().session_tag, tab_node_id);
return change_processor()->IsEntityUnsynced(storage_key);
}
@@ -351,6 +347,17 @@ void SessionSyncBridge::OnSyncStarting(
const syncer::DataTypeActivationRequest& request) {
DCHECK(!syncing_);
+ // |store_| may be already initialized if sync was previously started and
+ // then stopped.
+ if (store_) {
+ // If initial sync was already done, MergeSyncData() will never be called so
+ // we need to start syncing local changes.
+ if (change_processor()->IsTrackingMetadata()) {
+ StartLocalSessionEventHandler();
+ }
+ return;
+ }
+
const syncer::DeviceInfo* device_info =
sessions_client_->GetLocalDeviceInfo();
@@ -359,9 +366,14 @@ void SessionSyncBridge::OnSyncStarting(
DCHECK(device_info);
DCHECK_EQ(device_info->guid(), request.cache_guid);
- session_store_factory_.Run(
- *device_info, base::BindOnce(&SessionSyncBridge::OnStoreInitialized,
- weak_ptr_factory_.GetWeakPtr()));
+ // Open the store and read state from disk if it exists.
+ SessionStore::Open(
+ *device_info,
+ base::BindRepeating(&FaviconCache::UpdateMappingsFromForeignTab,
+ favicon_cache_.GetWeakPtr()),
+ sessions_client_,
+ base::BindOnce(&SessionSyncBridge::OnStoreInitialized,
+ weak_ptr_factory_.GetWeakPtr()));
}
void SessionSyncBridge::OnStoreInitialized(
@@ -378,12 +390,7 @@ void SessionSyncBridge::OnStoreInitialized(
DCHECK(store);
DCHECK(metadata_batch);
- syncing_.emplace();
- syncing_->store = std::move(store);
- syncing_->open_tabs_ui_delegate = std::make_unique<OpenTabsUIDelegateImpl>(
- sessions_client_, syncing_->store->tracker(), &favicon_cache_,
- base::BindRepeating(&SessionSyncBridge::DeleteForeignSessionFromUI,
- base::Unretained(this)));
+ store_ = std::move(store);
change_processor()->ModelReadyToSync(std::move(metadata_batch));
@@ -405,30 +412,23 @@ void SessionSyncBridge::DeleteForeignSessionFromUI(const std::string& tag) {
SessionStore::WriteBatch::Commit(std::move(batch));
}
-void SessionSyncBridge::DoGarbageCollection() {
- if (!syncing_) {
- return;
- }
-
- std::unique_ptr<SessionStore::WriteBatch> batch =
- CreateSessionStoreWriteBatch();
+void SessionSyncBridge::DoGarbageCollection(SessionStore::WriteBatch* batch) {
+ DCHECK(syncing_);
+ DCHECK(batch);
// Iterate through all the sessions and delete any with age older than
// |kStaleSessionThreshold|.
for (const auto* session :
- syncing_->store->tracker()->LookupAllForeignSessions(
- SyncedSessionTracker::RAW)) {
+ store_->tracker()->LookupAllForeignSessions(SyncedSessionTracker::RAW)) {
const base::TimeDelta session_age =
base::Time::Now() - session->modified_time;
if (session_age > kStaleSessionThreshold) {
const std::string session_tag = session->session_tag;
DVLOG(1) << "Found stale session " << session_tag << " with age "
<< session_age.InDays() << " days, deleting.";
- DeleteForeignSessionWithBatch(session_tag, batch.get());
+ DeleteForeignSessionWithBatch(session_tag, batch);
}
}
-
- SessionStore::WriteBatch::Commit(std::move(batch));
}
void SessionSyncBridge::DeleteForeignSessionWithBatch(
@@ -437,7 +437,7 @@ void SessionSyncBridge::DeleteForeignSessionWithBatch(
DCHECK(syncing_);
DCHECK(change_processor()->IsTrackingMetadata());
- if (session_tag == syncing_->store->local_session_info().session_tag) {
+ if (session_tag == store_->local_session_info().session_tag) {
DLOG(ERROR) << "Attempting to delete local session. This is not currently "
<< "supported.";
return;
@@ -459,7 +459,7 @@ std::unique_ptr<SessionStore::WriteBatch>
SessionSyncBridge::CreateSessionStoreWriteBatch() {
DCHECK(syncing_);
- return syncing_->store->CreateWriteBatch(base::BindOnce(
+ return store_->CreateWriteBatch(base::BindOnce(
&SessionSyncBridge::ReportError, weak_ptr_factory_.GetWeakPtr()));
}
@@ -470,11 +470,10 @@ void SessionSyncBridge::ResubmitLocalSession() {
std::unique_ptr<SessionStore::WriteBatch> write_batch =
CreateSessionStoreWriteBatch();
- std::unique_ptr<syncer::DataBatch> read_batch =
- syncing_->store->GetAllSessionData();
+ std::unique_ptr<syncer::DataBatch> read_batch = store_->GetAllSessionData();
while (read_batch->HasNext()) {
syncer::KeyAndData key_and_data = read_batch->Next();
- if (syncing_->store->StorageKeyMatchesLocalSession(key_and_data.first)) {
+ if (store_->StorageKeyMatchesLocalSession(key_and_data.first)) {
change_processor()->Put(key_and_data.first,
std::move(key_and_data.second),
write_batch->GetMetadataChangeList());
diff --git a/chromium/components/sync_sessions/session_sync_bridge.h b/chromium/components/sync_sessions/session_sync_bridge.h
index 6bd112c3c7d..aa14ae3efdc 100644
--- a/chromium/components/sync_sessions/session_sync_bridge.h
+++ b/chromium/components/sync_sessions/session_sync_bridge.h
@@ -45,7 +45,6 @@ class SessionSyncBridge : public syncer::ModelTypeSyncBridge,
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor);
~SessionSyncBridge() override;
- void ScheduleGarbageCollection();
FaviconCache* GetFaviconCache();
SessionsGlobalIdMapper* GetGlobalIdMapper();
OpenTabsUIDelegate* GetOpenTabsUIDelegate();
@@ -65,9 +64,8 @@ class SessionSyncBridge : public syncer::ModelTypeSyncBridge,
void GetAllDataForDebugging(DataCallback callback) override;
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
- StopSyncResponse ApplyStopSyncChanges(
- std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list)
- override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
// LocalSessionEventHandlerImpl::Delegate implementation.
std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch>
@@ -84,7 +82,7 @@ class SessionSyncBridge : public syncer::ModelTypeSyncBridge,
std::unique_ptr<syncer::MetadataBatch> metadata_batch);
void StartLocalSessionEventHandler();
void DeleteForeignSessionFromUI(const std::string& tag);
- void DoGarbageCollection();
+ void DoGarbageCollection(SessionStore::WriteBatch* write_batch);
std::unique_ptr<SessionStore::WriteBatch> CreateSessionStoreWriteBatch();
void DeleteForeignSessionWithBatch(const std::string& session_tag,
SessionStore::WriteBatch* batch);
@@ -97,14 +95,13 @@ class SessionSyncBridge : public syncer::ModelTypeSyncBridge,
FaviconCache favicon_cache_;
SessionsGlobalIdMapper global_id_mapper_;
- SessionStore::Factory session_store_factory_;
+ std::unique_ptr<SessionStore> store_;
// All data dependent on sync being starting or started.
struct SyncingState {
SyncingState();
~SyncingState();
- std::unique_ptr<SessionStore> store;
std::unique_ptr<OpenTabsUIDelegateImpl> open_tabs_ui_delegate;
std::unique_ptr<LocalSessionEventHandlerImpl> local_session_event_handler;
@@ -118,6 +115,7 @@ class SessionSyncBridge : public syncer::ModelTypeSyncBridge,
bool local_data_out_of_sync = false;
};
+ // TODO(mastiz): We should rather rename this to |syncing_state_|.
base::Optional<SyncingState> syncing_;
base::WeakPtrFactory<SessionSyncBridge> weak_ptr_factory_;
diff --git a/chromium/components/sync_sessions/session_sync_bridge_unittest.cc b/chromium/components/sync_sessions/session_sync_bridge_unittest.cc
index 47a81ffcf9d..a9daa06db05 100644
--- a/chromium/components/sync_sessions/session_sync_bridge_unittest.cc
+++ b/chromium/components/sync_sessions/session_sync_bridge_unittest.cc
@@ -54,6 +54,7 @@ using syncer::MetadataBatch;
using syncer::MetadataChangeList;
using syncer::MockModelTypeChangeProcessor;
using testing::_;
+using testing::AtLeast;
using testing::Contains;
using testing::ElementsAre;
using testing::Eq;
@@ -983,7 +984,6 @@ TEST_F(SessionSyncBridgeTest, ShouldDisableSyncAndReenable) {
EXPECT_CALL(mock_processor(), ModelReadyToSync(_)).Times(0);
real_processor()->OnSyncStopping(syncer::CLEAR_METADATA);
- EXPECT_CALL(mock_processor(), ModelReadyToSync(IsEmptyMetadataBatch()));
StartSyncing();
ASSERT_THAT(GetData(header_storage_key),
EntityDataHasSpecifics(
@@ -1469,7 +1469,6 @@ TEST_F(SessionSyncBridgeTest, ShouldDoGarbageCollection) {
CreateTabSpecifics(kRecentSessionTag, kWindowId, kTabId, kTabNodeId,
"http://baz.com/"),
recent_mtime));
- real_processor()->OnUpdateReceived(state, updates);
// During garbage collection, we expect |kStaleSessionTag| to be deleted.
EXPECT_CALL(mock_processor(),
@@ -1477,10 +1476,9 @@ TEST_F(SessionSyncBridgeTest, ShouldDoGarbageCollection) {
EXPECT_CALL(
mock_processor(),
Delete(SessionStore::GetTabStorageKey(kStaleSessionTag, kTabNodeId), _));
- EXPECT_CALL(mock_foreign_session_updated_cb(), Run());
- bridge()->ScheduleGarbageCollection();
- base::RunLoop().RunUntilIdle();
+ EXPECT_CALL(mock_foreign_session_updated_cb(), Run()).Times(AtLeast(1));
+ real_processor()->OnUpdateReceived(state, updates);
}
} // namespace
diff --git a/chromium/components/sync_sessions/session_sync_service.h b/chromium/components/sync_sessions/session_sync_service.h
index 61236cd1614..1aea2eaa666 100644
--- a/chromium/components/sync_sessions/session_sync_service.h
+++ b/chromium/components/sync_sessions/session_sync_service.h
@@ -44,9 +44,6 @@ class SessionSyncService : public KeyedService {
SubscribeToForeignSessionsChanged(const base::RepeatingClosure& cb)
WARN_UNUSED_RESULT = 0;
- // Schedules garbage collection of foreign sessions.
- virtual void ScheduleGarbageCollection() = 0;
-
// For ProfileSyncService to initialize the controller for SESSIONS.
virtual base::WeakPtr<syncer::ModelTypeControllerDelegate>
GetControllerDelegate() = 0;
diff --git a/chromium/components/sync_sessions/session_sync_service_impl.cc b/chromium/components/sync_sessions/session_sync_service_impl.cc
index cea0d52aa41..124176908c5 100644
--- a/chromium/components/sync_sessions/session_sync_service_impl.cc
+++ b/chromium/components/sync_sessions/session_sync_service_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
@@ -50,10 +51,6 @@ SessionSyncServiceImpl::SubscribeToForeignSessionsChanged(
return foreign_sessions_changed_callback_list_.Add(cb);
}
-void SessionSyncServiceImpl::ScheduleGarbageCollection() {
- bridge_->ScheduleGarbageCollection();
-}
-
base::WeakPtr<syncer::ModelTypeControllerDelegate>
SessionSyncServiceImpl::GetControllerDelegate() {
return bridge_->change_processor()->GetControllerDelegate();
diff --git a/chromium/components/sync_sessions/session_sync_service_impl.h b/chromium/components/sync_sessions/session_sync_service_impl.h
index 365625a26f2..2cd68c40482 100644
--- a/chromium/components/sync_sessions/session_sync_service_impl.h
+++ b/chromium/components/sync_sessions/session_sync_service_impl.h
@@ -37,9 +37,6 @@ class SessionSyncServiceImpl : public SessionSyncService {
SubscribeToForeignSessionsChanged(const base::RepeatingClosure& cb) override
WARN_UNUSED_RESULT;
- // Schedules garbage collection of foreign sessions.
- void ScheduleGarbageCollection() override;
-
// For ProfileSyncService to initialize the controller for SESSIONS.
base::WeakPtr<syncer::ModelTypeControllerDelegate> GetControllerDelegate()
override;
diff --git a/chromium/components/sync_sessions/synced_session_unittest.cc b/chromium/components/sync_sessions/synced_session_unittest.cc
index dc709c2df74..67c31047a9e 100644
--- a/chromium/components/sync_sessions/synced_session_unittest.cc
+++ b/chromium/components/sync_sessions/synced_session_unittest.cc
@@ -202,7 +202,7 @@ TEST(SyncedSessionTest, SetSessionTabFromSyncData) {
sync_data.set_extension_app_id("app_id");
for (int i = 0; i < 5; ++i) {
sync_pb::TabNavigation* navigation = sync_data.add_navigation();
- navigation->set_virtual_url("http://foo/" + base::IntToString(i));
+ navigation->set_virtual_url("http://foo/" + base::NumberToString(i));
navigation->set_referrer("referrer");
navigation->set_title("title");
navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED);
@@ -236,7 +236,7 @@ TEST(SyncedSessionTest, SetSessionTabFromSyncData) {
EXPECT_EQ(base::ASCIIToUTF16("title"), tab.navigations[i].title());
EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
tab.navigations[i].transition_type(), ui::PAGE_TRANSITION_TYPED));
- EXPECT_EQ(GURL("http://foo/" + base::IntToString(i)),
+ EXPECT_EQ(GURL("http://foo/" + base::NumberToString(i)),
tab.navigations[i].virtual_url());
}
EXPECT_TRUE(tab.session_storage_persistent_id.empty());
@@ -255,7 +255,7 @@ TEST(SyncedSessionTest, SessionTabToSyncData) {
for (int i = 0; i < 5; ++i) {
tab.navigations.push_back(
SerializedNavigationEntryTestHelper::CreateNavigation(
- "http://foo/" + base::IntToString(i), "title"));
+ "http://foo/" + base::NumberToString(i), "title"));
}
tab.session_storage_persistent_id = "fake";
diff --git a/chromium/components/sync_ui_strings.grdp b/chromium/components/sync_ui_strings.grdp
index 4247f22e68c..c4751313e4b 100644
--- a/chromium/components/sync_ui_strings.grdp
+++ b/chromium/components/sync_ui_strings.grdp
@@ -52,10 +52,24 @@
<message name="IDS_SYNC_SERVICE_UNAVAILABLE" desc="Error message to display when the user domain entered by the user has sync disabled.">
Sync is not available for your domain
</message>
+ <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user enters their Sync passphrase.">
+ Your data was encrypted with your <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>sync passphrase<ph name="END_LINK">&lt;/a&gt;</ph> on <ph name="TIME">$2<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+ </message>
+ <message name="IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user needs to enter their previous google passphrase.">
+ Your data was encrypted with your <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Google password<ph name="END_LINK">&lt;/a&gt;</ph> as of <ph name="TIME">$2<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+ </message>
</if>
- <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE" desc="Instructions for the dialog where the user enters the passphrase.">
- Your data was encrypted with your sync passphrase on <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
- </message>
+
+ <if expr="is_android">
+ <message name="IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID" desc="Instructions for the dialog where the user enters their Sync passphrase.">
+ Your data was encrypted with your <ph name="BEGIN_LINK">&lt;learnmore&gt;</ph>sync passphrase<ph name="END_LINK">&lt;/learnmore&gt;</ph> on <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+ </message>
+ <message name="IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY_WITH_DATE_ANDROID" desc="Instructions for the dialog where the user needs to enter their previous google passphrase.">
+ Your data was encrypted with your <ph name="BEGIN_LINK">&lt;learnmore&gt;</ph>Google password<ph name="END_LINK">&lt;/learnmore&gt;</ph> as of <ph name="TIME">$1<ex>Sept 1, 2012</ex></ph>. Enter it to start sync.
+ </message>
+
+ </if>
+
<message name="IDS_SYNC_ENTER_PASSPHRASE_BODY" desc="Instructions for the dialog where the user enters the passphrase.">
Your data is encrypted with your sync passphrase. Enter it to start sync.
</message>
diff --git a/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1 b/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1
new file mode 100644
index 00000000000..d591a939e88
--- /dev/null
+++ b/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE.png.sha1
@@ -0,0 +1 @@
+65f9fcb54fd03b79fcb9c349165115ba3ce192ea \ No newline at end of file
diff --git a/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1 b/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1
new file mode 100644
index 00000000000..085de34624f
--- /dev/null
+++ b/chromium/components/sync_ui_strings_grdp/IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE_ANDROID.png.sha1
@@ -0,0 +1 @@
+874727fdb430be8fa0f9565dcaa63bbbc6c796f6 \ No newline at end of file
diff --git a/chromium/components/task_scheduler_util/variations_util.cc b/chromium/components/task_scheduler_util/variations_util.cc
index cff79ac56d2..d7b3e7ae043 100644
--- a/chromium/components/task_scheduler_util/variations_util.cc
+++ b/chromium/components/task_scheduler_util/variations_util.cc
@@ -98,23 +98,14 @@ std::unique_ptr<base::TaskScheduler::InitParams> GetTaskSchedulerInitParams(
const auto background_worker_pool_params =
GetWorkerPoolParams("Background", variation_params);
- const auto background_blocking_worker_pool_params =
- GetWorkerPoolParams("BackgroundBlocking", variation_params);
const auto foreground_worker_pool_params =
GetWorkerPoolParams("Foreground", variation_params);
- const auto foreground_blocking_worker_pool_params =
- GetWorkerPoolParams("ForegroundBlocking", variation_params);
- if (!background_worker_pool_params ||
- !background_blocking_worker_pool_params ||
- !foreground_worker_pool_params ||
- !foreground_blocking_worker_pool_params) {
+ if (!background_worker_pool_params || !foreground_worker_pool_params)
return nullptr;
- }
return std::make_unique<base::TaskScheduler::InitParams>(
- *background_worker_pool_params, *background_blocking_worker_pool_params,
- *foreground_worker_pool_params, *foreground_blocking_worker_pool_params);
+ *background_worker_pool_params, *foreground_worker_pool_params);
}
std::unique_ptr<base::TaskScheduler::InitParams>
diff --git a/chromium/components/task_scheduler_util/variations_util_unittest.cc b/chromium/components/task_scheduler_util/variations_util_unittest.cc
index 7193ca88328..d5aaffb6ce4 100644
--- a/chromium/components/task_scheduler_util/variations_util_unittest.cc
+++ b/chromium/components/task_scheduler_util/variations_util_unittest.cc
@@ -41,9 +41,7 @@ class TaskSchedulerUtilVariationsUtilTest : public testing::Test {
TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0;42";
- variation_params["BackgroundBlocking"] = "2;2;1;0;52";
variation_params["Foreground"] = "4;4;1;0;62";
- variation_params["ForegroundBlocking"] = "8;8;1;0;72";
SetVariationParams(variation_params);
auto init_params = GetTaskSchedulerInitParams(kRendererSchedulerInitParams);
@@ -57,14 +55,6 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
base::SchedulerBackwardCompatibility::DISABLED,
init_params->background_worker_pool_params.backward_compatibility());
- EXPECT_EQ(2, init_params->background_blocking_worker_pool_params.max_tasks());
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(52),
- init_params->background_blocking_worker_pool_params
- .suggested_reclaim_time());
- EXPECT_EQ(base::SchedulerBackwardCompatibility::DISABLED,
- init_params->background_blocking_worker_pool_params
- .backward_compatibility());
-
EXPECT_EQ(4, init_params->foreground_worker_pool_params.max_tasks());
EXPECT_EQ(
base::TimeDelta::FromMilliseconds(62),
@@ -72,14 +62,6 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, OrderingParams5) {
EXPECT_EQ(
base::SchedulerBackwardCompatibility::DISABLED,
init_params->foreground_worker_pool_params.backward_compatibility());
-
- EXPECT_EQ(8, init_params->foreground_blocking_worker_pool_params.max_tasks());
- EXPECT_EQ(base::TimeDelta::FromMilliseconds(72),
- init_params->foreground_blocking_worker_pool_params
- .suggested_reclaim_time());
- EXPECT_EQ(base::SchedulerBackwardCompatibility::DISABLED,
- init_params->foreground_blocking_worker_pool_params
- .backward_compatibility());
}
TEST_F(TaskSchedulerUtilVariationsUtilTest, NoData) {
@@ -89,9 +71,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, NoData) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0";
- variation_params["BackgroundBlocking"] = "2;2;1;0";
variation_params["Foreground"] = "4;4;1;0";
- variation_params["ForegroundBlocking"] = "8;8;1;0";
SetVariationParams(variation_params);
EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams));
}
@@ -99,9 +79,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, IncompleteParameters) {
TEST_F(TaskSchedulerUtilVariationsUtilTest, InvalidParametersFormat) {
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "a;b;c;d;e";
- variation_params["BackgroundBlocking"] = "a;b;c;d;e";
variation_params["Foreground"] = "a;b;c;d;e";
- variation_params["ForegroundBlocking"] = "a;b;c;d;e";
SetVariationParams(variation_params);
EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams));
}
@@ -111,9 +89,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, ZeroMaxThreads) {
// invalid.
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "0;0;0;0;0";
- variation_params["BackgroundBlocking"] = "2;2;1;0;52";
variation_params["Foreground"] = "4;4;1;0;62";
- variation_params["ForegroundBlocking"] = "8;8;1;0;72";
SetVariationParams(variation_params);
EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams));
}
@@ -123,9 +99,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, NegativeMaxThreads) {
// invalid.
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "-5;-5;0;0;0";
- variation_params["BackgroundBlocking"] = "2;2;1;0;52";
variation_params["Foreground"] = "4;4;1;0;62";
- variation_params["ForegroundBlocking"] = "8;8;1;0;72";
SetVariationParams(variation_params);
EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams));
}
@@ -135,9 +109,7 @@ TEST_F(TaskSchedulerUtilVariationsUtilTest, NegativeSuggestedReclaimTime) {
// invalid.
std::map<std::string, std::string> variation_params;
variation_params["Background"] = "1;1;1;0;-5";
- variation_params["BackgroundBlocking"] = "2;2;1;0;52";
variation_params["Foreground"] = "4;4;1;0;62";
- variation_params["ForegroundBlocking"] = "8;8;1;0;72";
SetVariationParams(variation_params);
EXPECT_FALSE(GetTaskSchedulerInitParams(kRendererSchedulerInitParams));
}
diff --git a/chromium/components/test/BUILD.gn b/chromium/components/test/BUILD.gn
index 870351a767b..59e4418613d 100644
--- a/chromium/components/test/BUILD.gn
+++ b/chromium/components/test/BUILD.gn
@@ -3,8 +3,6 @@
# found in the LICENSE file.
import("//printing/buildflags/buildflags.gni")
-import("//services/catalog/public/tools/catalog.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//ui/base/ui_features.gni")
source_set("test_support") {
diff --git a/chromium/components/timers/alarm_timer_chromeos.cc b/chromium/components/timers/alarm_timer_chromeos.cc
index 94a9294b340..005fea1639e 100644
--- a/chromium/components/timers/alarm_timer_chromeos.cc
+++ b/chromium/components/timers/alarm_timer_chromeos.cc
@@ -12,17 +12,43 @@
#include <utility>
#include "base/bind.h"
-#include "base/debug/task_annotator.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/pending_task.h"
+#include "base/task/common/task_annotator.h"
#include "base/trace_event/trace_event.h"
namespace timers {
-SimpleAlarmTimer::SimpleAlarmTimer()
- : alarm_fd_(timerfd_create(CLOCK_REALTIME_ALARM, TFD_CLOEXEC)),
- weak_factory_(this) {}
+// static
+std::unique_ptr<SimpleAlarmTimer> SimpleAlarmTimer::Create() {
+ return CreateInternal(CLOCK_REALTIME_ALARM);
+}
+
+// static
+std::unique_ptr<SimpleAlarmTimer> SimpleAlarmTimer::CreateForTesting() {
+ // For unittest, use CLOCK_REALTIME in order to run the tests without
+ // CAP_WAKE_ALARM.
+ return CreateInternal(CLOCK_REALTIME);
+}
+
+// static
+std::unique_ptr<SimpleAlarmTimer> SimpleAlarmTimer::CreateInternal(
+ int clockid) {
+ base::ScopedFD alarm_fd(timerfd_create(clockid, TFD_CLOEXEC));
+ if (!alarm_fd.is_valid()) {
+ PLOG(ERROR) << "Failed to create timer fd";
+ return nullptr;
+ }
+
+ // Note: std::make_unique<> cannot be used because the constructor is
+ // private.
+ return base::WrapUnique(new SimpleAlarmTimer(std::move(alarm_fd)));
+}
+
+SimpleAlarmTimer::SimpleAlarmTimer(base::ScopedFD alarm_fd)
+ : alarm_fd_(std::move(alarm_fd)), weak_factory_(this) {}
SimpleAlarmTimer::~SimpleAlarmTimer() {
DCHECK(origin_task_runner_->RunsTasksInCurrentSequence());
@@ -35,11 +61,6 @@ void SimpleAlarmTimer::Stop() {
if (!IsRunning())
return;
- if (!CanWakeFromSuspend()) {
- base::RetainingOneShotTimer::Stop();
- return;
- }
-
// Cancel any previous callbacks.
weak_factory_.InvalidateWeakPtrs();
@@ -52,11 +73,6 @@ void SimpleAlarmTimer::Reset() {
DCHECK(origin_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!base::RetainingOneShotTimer::user_task().is_null());
- if (!CanWakeFromSuspend()) {
- base::RetainingOneShotTimer::Reset();
- return;
- }
-
// Cancel any previous callbacks and stop watching |alarm_fd_|.
weak_factory_.InvalidateWeakPtrs();
alarm_fd_watcher_.reset();
@@ -81,7 +97,7 @@ void SimpleAlarmTimer::Reset() {
alarm_time.it_value.tv_nsec =
(delay.InMicroseconds() % base::Time::kMicrosecondsPerSecond) *
base::Time::kNanosecondsPerMicrosecond;
- if (timerfd_settime(alarm_fd_, 0, &alarm_time, NULL) < 0)
+ if (timerfd_settime(alarm_fd_.get(), 0, &alarm_time, NULL) < 0)
PLOG(ERROR) << "Error while setting alarm time. Timer will not fire";
// The timer is running.
@@ -95,10 +111,10 @@ void SimpleAlarmTimer::Reset() {
} else {
// Otherwise, if the delay is not zero, generate a tracing event to indicate
// that the task was posted and watch |alarm_fd_|.
- base::debug::TaskAnnotator().WillQueueTask("SimpleAlarmTimer::Reset",
- pending_task_.get());
+ base::TaskAnnotator().WillQueueTask("SimpleAlarmTimer::Reset",
+ pending_task_.get());
alarm_fd_watcher_ = base::FileDescriptorWatcher::WatchReadable(
- alarm_fd_,
+ alarm_fd_.get(),
base::BindRepeating(&SimpleAlarmTimer::OnAlarmFdReadableWithoutBlocking,
weak_factory_.GetWeakPtr()));
}
@@ -110,7 +126,7 @@ void SimpleAlarmTimer::OnAlarmFdReadableWithoutBlocking() {
// Read from |alarm_fd_| to ack the event.
char val[sizeof(uint64_t)];
- if (!base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t)))
+ if (!base::ReadFromFD(alarm_fd_.get(), val, sizeof(uint64_t)))
PLOG(DFATAL) << "Unable to read from timer file descriptor.";
OnTimerFired();
@@ -129,16 +145,12 @@ void SimpleAlarmTimer::OnTimerFired() {
// Run the task.
TRACE_TASK_EXECUTION("SimpleAlarmTimer::OnTimerFired", *pending_user_task);
- base::debug::TaskAnnotator().RunTask("SimpleAlarmTimer::Reset",
- pending_user_task.get());
+ base::TaskAnnotator().RunTask("SimpleAlarmTimer::Reset",
+ pending_user_task.get());
// If the timer wasn't deleted, stopped or reset by the callback, stop it.
if (weak_ptr)
Stop();
}
-bool SimpleAlarmTimer::CanWakeFromSuspend() const {
- return alarm_fd_ != -1;
-}
-
} // namespace timers
diff --git a/chromium/components/timers/alarm_timer_chromeos.h b/chromium/components/timers/alarm_timer_chromeos.h
index 1ff689ec067..e1301e9e947 100644
--- a/chromium/components/timers/alarm_timer_chromeos.h
+++ b/chromium/components/timers/alarm_timer_chromeos.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/files/file_descriptor_watcher_posix.h"
+#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
@@ -24,8 +25,7 @@ namespace timers {
// suspended state. For example, this is useful for running tasks that are
// needed for maintaining network connectivity, like sending heartbeat messages.
// Currently, this feature is only available on Chrome OS systems running linux
-// version 3.11 or higher. On all other platforms, the SimpleAlarmTimer behaves
-// exactly the same way as a regular Timer.
+// version 3.11 or higher.
//
// A SimpleAlarmTimer instance can only be used from the sequence on which it
// was instantiated. Start() and Stop() must be called from a thread that
@@ -36,7 +36,15 @@ namespace timers {
// times but not at a regular interval.
class SimpleAlarmTimer : public base::RetainingOneShotTimer {
public:
- SimpleAlarmTimer();
+ // Creates the SimpleAlarmTimer instance, or returns null on failure, e.g.,
+ // on a platform without timerfd_* system calls support, or missing
+ // capability (CAP_WAKE_ALARM).
+ static std::unique_ptr<SimpleAlarmTimer> Create();
+
+ // Similar to Create(), but for unittests without capability.
+ // Specifically, uses CLOCK_REALTIME instead of CLOCK_REALTIME_ALARM.
+ static std::unique_ptr<SimpleAlarmTimer> CreateForTesting();
+
~SimpleAlarmTimer() override;
// Timer overrides.
@@ -44,6 +52,11 @@ class SimpleAlarmTimer : public base::RetainingOneShotTimer {
void Reset() override;
private:
+ // Shared implementation of Create and CreateForTesting.
+ static std::unique_ptr<SimpleAlarmTimer> CreateInternal(int clockid);
+
+ explicit SimpleAlarmTimer(base::ScopedFD alarm_fd);
+
// Called when |alarm_fd_| is readable without blocking. Reads data from
// |alarm_fd_| and calls OnTimerFired().
void OnAlarmFdReadableWithoutBlocking();
@@ -51,14 +64,8 @@ class SimpleAlarmTimer : public base::RetainingOneShotTimer {
// Called when the timer fires. Runs the callback.
void OnTimerFired();
- // Tracks whether the timer has the ability to wake the system up from
- // suspend. This is a runtime check because we won't know if the system
- // supports being woken up from suspend until the constructor actually tries
- // to set it up.
- bool CanWakeFromSuspend() const;
-
// Timer file descriptor.
- const int alarm_fd_;
+ const base::ScopedFD alarm_fd_;
// Watches |alarm_fd_|.
std::unique_ptr<base::FileDescriptorWatcher::Controller> alarm_fd_watcher_;
diff --git a/chromium/components/timers/alarm_timer_unittest.cc b/chromium/components/timers/alarm_timer_unittest.cc
index 7863d774397..166144ea329 100644
--- a/chromium/components/timers/alarm_timer_unittest.cc
+++ b/chromium/components/timers/alarm_timer_unittest.cc
@@ -24,7 +24,9 @@
// regular Timer so it should pass the same tests as the Timer class.
namespace timers {
namespace {
-const base::TimeDelta kTenMilliseconds = base::TimeDelta::FromMilliseconds(10);
+
+constexpr base::TimeDelta kTenMilliseconds =
+ base::TimeDelta::FromMilliseconds(10);
class AlarmTimerTester {
public:
@@ -34,7 +36,7 @@ class AlarmTimerTester {
: did_run_(did_run),
quit_closure_(std::move(quit_closure)),
delay_(delay),
- timer_(new timers::SimpleAlarmTimer()) {}
+ timer_(SimpleAlarmTimer::CreateForTesting()) {}
void Start() {
timer_->Start(
FROM_HERE, delay_,
@@ -51,7 +53,7 @@ class AlarmTimerTester {
bool* did_run_;
base::OnceClosure quit_closure_;
const base::TimeDelta delay_;
- std::unique_ptr<timers::SimpleAlarmTimer> timer_;
+ std::unique_ptr<SimpleAlarmTimer> timer_;
DISALLOW_COPY_AND_ASSIGN(AlarmTimerTester);
};
@@ -64,7 +66,7 @@ class SelfDeletingAlarmTimerTester {
: did_run_(did_run),
quit_closure_(std::move(quit_closure)),
delay_(delay),
- timer_(new timers::SimpleAlarmTimer()) {}
+ timer_(SimpleAlarmTimer::CreateForTesting()) {}
void Start() {
timer_->Start(FROM_HERE, delay_,
base::BindRepeating(&SelfDeletingAlarmTimerTester::Run,
@@ -83,7 +85,7 @@ class SelfDeletingAlarmTimerTester {
bool* did_run_;
base::OnceClosure quit_closure_;
const base::TimeDelta delay_;
- std::unique_ptr<timers::SimpleAlarmTimer> timer_;
+ std::unique_ptr<SimpleAlarmTimer> timer_;
DISALLOW_COPY_AND_ASSIGN(SelfDeletingAlarmTimerTester);
};
@@ -221,49 +223,47 @@ TEST(AlarmTimerTest, MessageLoopShutdown) {
}
TEST(AlarmTimerTest, NonRepeatIsRunning) {
- {
- base::test::ScopedTaskEnvironment task_environment(
- base::test::ScopedTaskEnvironment::MainThreadType::IO);
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
- timers::SimpleAlarmTimer timer;
- EXPECT_FALSE(timer.IsRunning());
- timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ EXPECT_FALSE(timer->IsRunning());
+ timer->Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
- // Allow FileDescriptorWatcher to start watching the timer. Without this, a
- // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
- base::RunLoop().RunUntilIdle();
+ // Allow FileDescriptorWatcher to start watching the timer. Without this, a
+ // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
+ base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(timer.IsRunning());
- timer.Stop();
- EXPECT_FALSE(timer.IsRunning());
- ASSERT_FALSE(timer.user_task().is_null());
- timer.Reset();
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(timer.IsRunning());
- }
+ EXPECT_TRUE(timer->IsRunning());
+ timer->Stop();
+ EXPECT_FALSE(timer->IsRunning());
+ ASSERT_FALSE(timer->user_task().is_null());
+ timer->Reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(timer->IsRunning());
}
TEST(AlarmTimerTest, RetainNonRepeatIsRunning) {
base::test::ScopedTaskEnvironment task_environment(
base::test::ScopedTaskEnvironment::MainThreadType::IO);
- timers::SimpleAlarmTimer timer;
- EXPECT_FALSE(timer.IsRunning());
- timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ EXPECT_FALSE(timer->IsRunning());
+ timer->Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
// Allow FileDescriptorWatcher to start watching the timer. Without this, a
// task posted by FileDescriptorWatcher::WatchReadable() is leaked.
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(timer.IsRunning());
- timer.Reset();
+ EXPECT_TRUE(timer->IsRunning());
+ timer->Reset();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(timer.IsRunning());
- timer.Stop();
- EXPECT_FALSE(timer.IsRunning());
- timer.Reset();
+ EXPECT_TRUE(timer->IsRunning());
+ timer->Stop();
+ EXPECT_FALSE(timer->IsRunning());
+ timer->Reset();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(timer.IsRunning());
+ EXPECT_TRUE(timer->IsRunning());
}
namespace {
@@ -293,16 +293,16 @@ TEST(AlarmTimerTest, ContinuationStopStart) {
base::test::ScopedTaskEnvironment task_environment(
base::test::ScopedTaskEnvironment::MainThreadType::IO);
- timers::SimpleAlarmTimer timer;
- timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
- base::BindRepeating(&SetCallbackHappened1,
- base::DoNothing().Repeatedly()));
- timer.Stop();
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ timer->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
+ base::BindRepeating(&SetCallbackHappened1,
+ base::DoNothing().Repeatedly()));
+ timer->Stop();
base::RunLoop run_loop;
- timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40),
- base::BindRepeating(&SetCallbackHappened2,
- run_loop.QuitWhenIdleClosure()));
+ timer->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(40),
+ base::BindRepeating(&SetCallbackHappened2,
+ run_loop.QuitWhenIdleClosure()));
run_loop.Run();
EXPECT_FALSE(g_callback_happened1);
@@ -315,12 +315,12 @@ TEST(AlarmTimerTest, ContinuationReset) {
base::test::ScopedTaskEnvironment::MainThreadType::IO);
base::RunLoop run_loop;
- timers::SimpleAlarmTimer timer;
- timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
- base::BindRepeating(&SetCallbackHappened1,
- run_loop.QuitWhenIdleClosure()));
- timer.Reset();
- ASSERT_FALSE(timer.user_task().is_null());
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ timer->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(10),
+ base::BindRepeating(&SetCallbackHappened1,
+ run_loop.QuitWhenIdleClosure()));
+ timer->Reset();
+ ASSERT_FALSE(timer->user_task().is_null());
run_loop.Run();
EXPECT_TRUE(g_callback_happened1);
}
@@ -334,16 +334,13 @@ TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunning) {
base::RunLoop run_loop;
// Will be deleted by the callback.
- timers::SimpleAlarmTimer* timer = new timers::SimpleAlarmTimer;
-
- timer->Start(
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ auto* timer_ptr = timer.get();
+ timer_ptr->Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(10),
- base::BindRepeating(
- [](timers::SimpleAlarmTimer* timer, base::RunLoop* run_loop) {
- delete timer;
- run_loop->Quit();
- },
- timer, &run_loop));
+ base::BindRepeating([](std::unique_ptr<SimpleAlarmTimer> timer,
+ base::RunLoop* run_loop) { run_loop->Quit(); },
+ base::Passed(std::move(timer)), &run_loop));
run_loop.Run();
}
@@ -355,16 +352,13 @@ TEST(AlarmTimerTest, DeleteTimerWhileCallbackIsRunningZeroDelay) {
base::RunLoop run_loop;
// Will be deleted by the callback.
- timers::SimpleAlarmTimer* timer = new timers::SimpleAlarmTimer;
-
- timer->Start(
+ auto timer = SimpleAlarmTimer::CreateForTesting();
+ auto* timer_ptr = timer.get();
+ timer_ptr->Start(
FROM_HERE, base::TimeDelta(),
- base::BindRepeating(
- [](timers::SimpleAlarmTimer* timer, base::RunLoop* run_loop) {
- delete timer;
- run_loop->Quit();
- },
- timer, &run_loop));
+ base::BindRepeating([](std::unique_ptr<SimpleAlarmTimer> timer,
+ base::RunLoop* run_loop) { run_loop->Quit(); },
+ base::Passed(std::move(timer)), &run_loop));
run_loop.Run();
}
diff --git a/chromium/components/tracing/BUILD.gn b/chromium/components/tracing/BUILD.gn
index 42d878a8eaa..c80e46eede4 100644
--- a/chromium/components/tracing/BUILD.gn
+++ b/chromium/components/tracing/BUILD.gn
@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//testing/test.gni")
import("//build/config/compiler/compiler.gni")
+import("//testing/test.gni")
if (is_android) {
import("//build/config/android/rules.gni")
@@ -50,8 +50,6 @@ component("tracing") {
component("startup_tracing") {
sources = [
- "common/trace_startup.cc",
- "common/trace_startup.h",
"common/trace_startup_config.cc",
"common/trace_startup_config.h",
"common/trace_to_console.cc",
diff --git a/chromium/components/tracing/common/native_stack_sampler_android.cc b/chromium/components/tracing/common/native_stack_sampler_android.cc
index 15d5b414310..e28ae1f6bc9 100644
--- a/chromium/components/tracing/common/native_stack_sampler_android.cc
+++ b/chromium/components/tracing/common/native_stack_sampler_android.cc
@@ -4,6 +4,7 @@
#include "components/tracing/common/native_stack_sampler_android.h"
+#include "base/sampling_heap_profiler/module_cache.h"
#include "base/trace_event/trace_event.h"
namespace tracing {
@@ -16,8 +17,6 @@ NativeStackSamplerAndroid::NativeStackSamplerAndroid(base::PlatformThreadId tid)
NativeStackSamplerAndroid::~NativeStackSamplerAndroid() = default;
-void NativeStackSamplerAndroid::ProfileRecordingStarting() {}
-
std::vector<base::StackSamplingProfiler::Frame>
NativeStackSamplerAndroid::RecordStackFrames(
StackBuffer* stack_buffer,
@@ -25,7 +24,8 @@ NativeStackSamplerAndroid::RecordStackFrames(
if (!unwinder_.is_initialized()) {
// May block on disk access. This function is executed on the profiler
// thread, so this will only block profiling execution.
- TRACE_EVENT0("cpu_profiler", "StackUnwinderAndroid::Initialize");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+ "StackUnwinderAndroid::Initialize");
unwinder_.Initialize();
}
const void* pcs[kMaxFrameDepth];
@@ -34,8 +34,7 @@ NativeStackSamplerAndroid::RecordStackFrames(
frames.reserve(depth);
for (size_t i = 0; i < depth; ++i) {
// TODO(ssid): Add support for obtaining modules here.
- frames.emplace_back(reinterpret_cast<uintptr_t>(pcs[i]),
- base::ModuleCache::Module());
+ frames.emplace_back(reinterpret_cast<uintptr_t>(pcs[i]), nullptr);
}
return frames;
}
diff --git a/chromium/components/tracing/common/native_stack_sampler_android.h b/chromium/components/tracing/common/native_stack_sampler_android.h
index e5c49aa23d8..e80ae2e5096 100644
--- a/chromium/components/tracing/common/native_stack_sampler_android.h
+++ b/chromium/components/tracing/common/native_stack_sampler_android.h
@@ -22,7 +22,6 @@ class NativeStackSamplerAndroid : public base::NativeStackSampler {
~NativeStackSamplerAndroid() override;
// StackSamplingProfiler::NativeStackSampler:
- void ProfileRecordingStarting() override;
std::vector<base::StackSamplingProfiler::Frame> RecordStackFrames(
StackBuffer* stack_buffer,
base::StackSamplingProfiler::ProfileBuilder* profile_builder) override;
diff --git a/chromium/components/tracing/common/stack_unwinder_android_unittest.cc b/chromium/components/tracing/common/stack_unwinder_android_unittest.cc
index 17598c41e10..cf39a0593c0 100644
--- a/chromium/components/tracing/common/stack_unwinder_android_unittest.cc
+++ b/chromium/components/tracing/common/stack_unwinder_android_unittest.cc
@@ -5,6 +5,7 @@
#include "components/tracing/common/stack_unwinder_android.h"
#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/post_task.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/tracing/common/trace_startup.cc b/chromium/components/tracing/common/trace_startup.cc
deleted file mode 100644
index f50a8882372..00000000000
--- a/chromium/components/tracing/common/trace_startup.cc
+++ /dev/null
@@ -1,51 +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/tracing/common/trace_startup.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/trace_log.h"
-#include "build/build_config.h"
-#include "components/tracing/common/trace_startup_config.h"
-#include "components/tracing/common/trace_to_console.h"
-#include "components/tracing/common/tracing_switches.h"
-
-namespace tracing {
-
-void EnableStartupTracingIfNeeded() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
-
- // TODO(oysteine): Startup tracing using Perfetto
- // is enabled by the Mojo consumer in content/browser
- // for now; this is too late in the browser startup
- // process however.
- if (command_line.HasSwitch(switches::kPerfettoOutputFile))
- return;
-
- // Ensure TraceLog is initialized first.
- // https://crbug.com/764357
- base::trace_event::TraceLog::GetInstance();
-
- if (TraceStartupConfig::GetInstance()->IsEnabled()) {
- const base::trace_event::TraceConfig& trace_config =
- TraceStartupConfig::GetInstance()->GetTraceConfig();
- uint8_t modes = base::trace_event::TraceLog::RECORDING_MODE;
- if (!trace_config.event_filters().empty())
- modes |= base::trace_event::TraceLog::FILTERING_MODE;
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- TraceStartupConfig::GetInstance()->GetTraceConfig(), modes);
- } else if (command_line.HasSwitch(switches::kTraceToConsole)) {
- base::trace_event::TraceConfig trace_config = GetConfigForTraceToConsole();
- LOG(ERROR) << "Start " << switches::kTraceToConsole
- << " with CategoryFilter '"
- << trace_config.ToCategoryFilterString() << "'.";
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_config, base::trace_event::TraceLog::RECORDING_MODE);
- }
-}
-
-} // namespace tracing
diff --git a/chromium/components/tracing/common/trace_startup.h b/chromium/components/tracing/common/trace_startup.h
deleted file mode 100644
index 4cb568371af..00000000000
--- a/chromium/components/tracing/common/trace_startup.h
+++ /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.
-
-#ifndef COMPONENTS_TRACING_COMMON_TRACE_STARTUP_H
-#define COMPONENTS_TRACING_COMMON_TRACE_STARTUP_H
-
-#include "components/tracing/tracing_export.h"
-
-namespace tracing {
-
-// Enables TraceLog with config based on the command line flags of the process.
-void TRACING_EXPORT EnableStartupTracingIfNeeded();
-
-} // namespace tracing
-
-#endif // COMPONENTS_TRACING_COMMON_TRACE_STARTUP_H
diff --git a/chromium/components/tracing/common/trace_startup_config.cc b/chromium/components/tracing/common/trace_startup_config.cc
index 0f5f37afa50..0ccaff23ffa 100644
--- a/chromium/components/tracing/common/trace_startup_config.cc
+++ b/chromium/components/tracing/common/trace_startup_config.cc
@@ -31,6 +31,9 @@ namespace {
const size_t kTraceConfigFileSizeLimit = 64 * 1024;
const int kDefaultStartupDuration = 5;
+// 95th percentile size of current startup traces size uploaded.
+const size_t kMaxStartupTraceSizeInKb = 300;
+
// Trace config file path:
// - Android: /data/local/chrome-trace-config.json
// - Others: specified by --trace-config-file flag.
@@ -70,6 +73,7 @@ TraceStartupConfig::GetDefaultBrowserStartupConfig() {
{base::GetCurrentProcId()});
// First 10k events at start are sufficient to debug startup traces.
trace_config.SetTraceBufferSizeInEvents(10000);
+ trace_config.SetTraceBufferSizeInKb(kMaxStartupTraceSizeInKb);
trace_config.SetProcessFilterConfig(process_config);
// Enable argument filter since we could be background tracing.
trace_config.EnableArgumentFilter();
@@ -85,7 +89,7 @@ TraceStartupConfig::TraceStartupConfig()
if (EnableFromCommandLine()) {
DCHECK(IsEnabled());
} else if (EnableFromConfigFile()) {
- DCHECK(IsEnabled());
+ DCHECK(IsEnabled() || IsUsingPerfettoOutput());
} else if (EnableFromBackgroundTracing()) {
DCHECK(IsEnabled());
DCHECK(!IsTracingStartupForDuration());
@@ -97,7 +101,12 @@ TraceStartupConfig::TraceStartupConfig()
TraceStartupConfig::~TraceStartupConfig() = default;
bool TraceStartupConfig::IsEnabled() const {
- return is_enabled_;
+ // TODO(oysteine): Support early startup tracing using Perfetto
+ // output; right now the early startup tracing gets controlled
+ // through the TracingController, and the Perfetto output is
+ // using the Consumer Mojo interface; the two can't be used
+ // together.
+ return is_enabled_ && !IsUsingPerfettoOutput();
}
void TraceStartupConfig::SetDisabled() {
@@ -105,21 +114,21 @@ void TraceStartupConfig::SetDisabled() {
}
bool TraceStartupConfig::IsTracingStartupForDuration() const {
- return is_enabled_ && startup_duration_ > 0;
+ return IsEnabled() && startup_duration_ > 0;
}
base::trace_event::TraceConfig TraceStartupConfig::GetTraceConfig() const {
- DCHECK(IsEnabled());
+ DCHECK(IsEnabled() || IsUsingPerfettoOutput());
return trace_config_;
}
int TraceStartupConfig::GetStartupDuration() const {
- DCHECK(IsEnabled());
+ DCHECK(IsEnabled() || IsUsingPerfettoOutput());
return startup_duration_;
}
bool TraceStartupConfig::ShouldTraceToResultFile() const {
- return is_enabled_ && should_trace_to_result_file_;
+ return IsEnabled() && should_trace_to_result_file_;
}
base::FilePath TraceStartupConfig::GetResultFile() const {
@@ -132,6 +141,11 @@ bool TraceStartupConfig::GetBackgroundStartupTracingEnabled() const {
return is_enabled_from_background_tracing_;
}
+bool TraceStartupConfig::IsUsingPerfettoOutput() const {
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kPerfettoOutputFile);
+}
+
void TraceStartupConfig::SetBackgroundStartupTracingEnabled(bool enabled) {
#if defined(OS_ANDROID)
base::android::SetBackgroundStartupTracingFlag(enabled);
@@ -227,7 +241,7 @@ bool TraceStartupConfig::EnableFromBackgroundTracing() {
bool TraceStartupConfig::ParseTraceConfigFileContent(
const std::string& content) {
- std::unique_ptr<base::Value> value(base::JSONReader::Read(content));
+ std::unique_ptr<base::Value> value(base::JSONReader::ReadDeprecated(content));
if (!value || !value->is_dict())
return false;
diff --git a/chromium/components/tracing/common/trace_startup_config.h b/chromium/components/tracing/common/trace_startup_config.h
index 2c961bf7d68..1b0c7da2e85 100644
--- a/chromium/components/tracing/common/trace_startup_config.h
+++ b/chromium/components/tracing/common/trace_startup_config.h
@@ -109,6 +109,8 @@ class TRACING_EXPORT TraceStartupConfig {
void SetBackgroundStartupTracingEnabled(bool enabled);
private:
+ bool IsUsingPerfettoOutput() const;
+
// This allows constructor and destructor to be private and usable only
// by the Singleton class.
friend struct base::DefaultSingletonTraits<TraceStartupConfig>;
diff --git a/chromium/components/tracing/common/tracing_sampler_profiler.cc b/chromium/components/tracing/common/tracing_sampler_profiler.cc
index 5e266e861ba..f27aee7b3be 100644
--- a/chromium/components/tracing/common/tracing_sampler_profiler.cc
+++ b/chromium/components/tracing/common/tracing_sampler_profiler.cc
@@ -38,49 +38,53 @@ std::string GetFrameNameFromOffsetAddr(uintptr_t offset_from_module_base) {
return base::StringPrintf("off:0x%" PRIxPTR, offset_from_module_base);
}
-// This class will receive the sampling profiler stackframes and output them
-// to the chrome trace via an event.
-class TracingProfileBuilder
- : public base::StackSamplingProfiler::ProfileBuilder {
- public:
- TracingProfileBuilder(base::PlatformThreadId sampled_thread_id)
- : sampled_thread_id_(sampled_thread_id) {}
-
- void OnSampleCompleted(
- std::vector<base::StackSamplingProfiler::Frame> frames) override {
- int process_priority = base::Process::Current().GetPriority();
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
- "ProcessPriority", TRACE_EVENT_SCOPE_THREAD,
- "priority", process_priority);
-
- if (frames.empty()) {
- TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
- "StackCpuSampling", TRACE_EVENT_SCOPE_THREAD,
- "frames", "empty", "thread_id", sampled_thread_id_);
-
- return;
- }
- // Insert an event with the frames rendered as a string with the following
- // formats:
- // offset - module [debugid]
- // [OR]
- // symbol - module []
- // The offset is difference between the load module address and the
- // frame address.
- //
- // Example:
- //
- // "malloc - libc.so []
- // std::string::alloc - stdc++.so []
- // off:7ffb3f991b2d - USER32.dll [2103C0950C7DEC7F7AAA44348EDC1DDD1]
- // off:7ffb3d439164 - win32u.dll [B3E4BE89CA7FB42A2AC1E1C475284CA11]
- // off:7ffaf3e26201 - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
- // off:7ffaf3e26008 - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
- // [...] "
- std::string result;
- for (const auto& frame : frames) {
- std::string frame_name;
- std::string module_name;
+} // namespace
+
+TracingSamplerProfiler::TracingProfileBuilder::TracingProfileBuilder(
+ base::PlatformThreadId sampled_thread_id)
+ : sampled_thread_id_(sampled_thread_id) {}
+
+base::ModuleCache*
+TracingSamplerProfiler::TracingProfileBuilder::GetModuleCache() {
+ return &module_cache_;
+}
+
+void TracingSamplerProfiler::TracingProfileBuilder::OnSampleCompleted(
+ std::vector<base::StackSamplingProfiler::Frame> frames) {
+ int process_priority = base::Process::Current().GetPriority();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+ "ProcessPriority", TRACE_EVENT_SCOPE_THREAD, "priority",
+ process_priority);
+
+ if (frames.empty()) {
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
+ "StackCpuSampling", TRACE_EVENT_SCOPE_THREAD, "frames",
+ "empty", "thread_id", sampled_thread_id_);
+
+ return;
+ }
+ // Insert an event with the frames rendered as a string with the following
+ // formats:
+ // offset - module [debugid]
+ // [OR]
+ // symbol - module []
+ // The offset is difference between the load module address and the
+ // frame address.
+ //
+ // Example:
+ //
+ // "malloc - libc.so []
+ // std::string::alloc - stdc++.so []
+ // off:7ffb3f991b2d - USER32.dll [2103C0950C7DEC7F7AAA44348EDC1DDD1]
+ // off:7ffb3d439164 - win32u.dll [B3E4BE89CA7FB42A2AC1E1C475284CA11]
+ // off:7ffaf3e26201 - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
+ // off:7ffaf3e26008 - chrome.dll [8767EB7E1C77DD10014E8152A34786B812]
+ // [...] "
+ std::string result;
+ for (const auto& frame : frames) {
+ std::string frame_name;
+ std::string module_name;
+ std::string module_id;
#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
defined(OFFICIAL_BUILD)
Dl_info info = {};
@@ -108,27 +112,24 @@ class TracingProfileBuilder
if (frame_name.empty())
frame_name = "Unknown";
#else
- module_name = frame.module.filename.BaseName().MaybeAsASCII();
+ if (frame.module) {
+ module_name = frame.module->GetDebugBasename().MaybeAsASCII();
+ module_id = frame.module->GetId();
frame_name = GetFrameNameFromOffsetAddr(frame.instruction_pointer -
- frame.module.base_address);
+ frame.module->GetBaseAddress());
+ } else {
+ module_name = module_id = "";
+ frame_name = "Unknown";
+ }
#endif
base::StringAppendF(&result, "%s - %s [%s]\n", frame_name.c_str(),
- module_name.c_str(), frame.module.id.c_str());
- }
+ module_name.c_str(), module_id.c_str());
+ }
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("cpu_profiler"),
"StackCpuSampling", TRACE_EVENT_SCOPE_THREAD, "frames",
result, "thread_id", sampled_thread_id_);
- }
-
- void OnProfileCompleted(base::TimeDelta profile_duration,
- base::TimeDelta sampling_period) override {}
-
- private:
- base::PlatformThreadId sampled_thread_id_;
-};
-
-} // namespace
+}
// static
std::unique_ptr<TracingSamplerProfiler>
diff --git a/chromium/components/tracing/common/tracing_sampler_profiler.h b/chromium/components/tracing/common/tracing_sampler_profiler.h
index 16c0f01693a..2901071769d 100644
--- a/chromium/components/tracing/common/tracing_sampler_profiler.h
+++ b/chromium/components/tracing/common/tracing_sampler_profiler.h
@@ -7,15 +7,12 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/profiler/stack_sampling_profiler.h"
#include "base/sequence_checker.h"
#include "base/threading/platform_thread.h"
#include "base/trace_event/trace_log.h"
#include "components/tracing/tracing_export.h"
-namespace base {
-class StackSamplingProfiler;
-}
-
namespace tracing {
// This class is a bridge between the base stack sampling profiler and chrome
@@ -30,6 +27,25 @@ namespace tracing {
class TRACING_EXPORT TracingSamplerProfiler
: public base::trace_event::TraceLog::EnabledStateObserver {
public:
+ // This class will receive the sampling profiler stackframes and output them
+ // to the chrome trace via an event. Exposed for testing.
+ class TRACING_EXPORT TracingProfileBuilder
+ : public base::StackSamplingProfiler::ProfileBuilder {
+ public:
+ TracingProfileBuilder(base::PlatformThreadId sampled_thread_id);
+
+ // base::StackSamplingProfiler::ProfileBuilder
+ base::ModuleCache* GetModuleCache() override;
+ void OnSampleCompleted(
+ std::vector<base::StackSamplingProfiler::Frame> frames) override;
+ void OnProfileCompleted(base::TimeDelta profile_duration,
+ base::TimeDelta sampling_period) override {}
+
+ private:
+ base::ModuleCache module_cache_;
+ base::PlatformThreadId sampled_thread_id_;
+ };
+
// Creates sampling profiler on main thread. Since the message loop might not
// be setup when creating this profiler, the client must call
// OnMessageLoopStarted() when setup.
diff --git a/chromium/components/tracing/common/tracing_sampler_profiler_unittest.cc b/chromium/components/tracing/common/tracing_sampler_profiler_unittest.cc
index b3f9d637861..6bd88e9a79b 100644
--- a/chromium/components/tracing/common/tracing_sampler_profiler_unittest.cc
+++ b/chromium/components/tracing/common/tracing_sampler_profiler_unittest.cc
@@ -5,6 +5,7 @@
#include "components/tracing/common/tracing_sampler_profiler.h"
#include "base/at_exit.h"
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted_memory.h"
#include "base/profiler/stack_sampling_profiler.h"
@@ -92,7 +93,8 @@ class TracingSampleProfilerTest : public testing::Test {
std::string error_msg;
std::unique_ptr<base::Value> trace_data =
- base::JSONReader::ReadAndReturnError(json_data, 0, nullptr, &error_msg);
+ base::JSONReader::ReadAndReturnErrorDeprecated(json_data, 0, nullptr,
+ &error_msg);
CHECK(trace_data) << "JSON parsing failed (" << error_msg << ")";
base::ListValue* list;
@@ -140,6 +142,20 @@ class TracingSampleProfilerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(TracingSampleProfilerTest);
};
+// Stub module for testing.
+class TestModule : public base::ModuleCache::Module {
+ public:
+ TestModule() = default;
+
+ TestModule(const TestModule&) = delete;
+ TestModule& operator=(const TestModule&) = delete;
+
+ uintptr_t GetBaseAddress() const override { return 0; }
+ std::string GetId() const override { return ""; }
+ base::FilePath GetDebugBasename() const override { return base::FilePath(); }
+ size_t GetSize() const override { return 0; }
+};
+
} // namespace
TEST_F(TracingSampleProfilerTest, OnSampleCompleted) {
@@ -174,4 +190,19 @@ TEST_F(TracingSampleProfilerTest, SamplingChildThread) {
ValidateReceivedEvents();
}
+TEST(TracingProfileBuilderTest, ValidModule) {
+ TestModule module;
+ TracingSamplerProfiler::TracingProfileBuilder profile_builder(
+ (base::PlatformThreadId()));
+ profile_builder.OnSampleCompleted(
+ {base::StackSamplingProfiler::Frame(0x1010, &module)});
+}
+
+TEST(TracingProfileBuilderTest, InvalidModule) {
+ TracingSamplerProfiler::TracingProfileBuilder profile_builder(
+ (base::PlatformThreadId()));
+ profile_builder.OnSampleCompleted(
+ {base::StackSamplingProfiler::Frame(0x1010, nullptr)});
+}
+
} // namespace tracing
diff --git a/chromium/components/tracing/common/tracing_switches.cc b/chromium/components/tracing/common/tracing_switches.cc
index 533ad0213d9..352f4abf3f3 100644
--- a/chromium/components/tracing/common/tracing_switches.cc
+++ b/chromium/components/tracing/common/tracing_switches.cc
@@ -54,12 +54,28 @@ const char kTraceStartupFile[] = "trace-startup-file";
// "record-until-full" mode will be used.
const char kTraceStartupRecordMode[] = "trace-startup-record-mode";
+// Enables the perfetto tracing backend. We need a separate command line
+// argument from the kTracingPerfettoBackend feature, because feature flags are
+// parsed too late during startup for early startup tracing support.
+// TODO(eseckler): When perfetto becomes the default, replace this with
+// --disable-perfetto for legacy startup tracing support.
+const char kEnablePerfetto[] = "enable-perfetto";
+
+// Repeat internable data for each TraceEvent in the perfetto proto format.
+const char kPerfettoDisableInterning[] = "perfetto-disable-interning";
+
// If supplied, will enable Perfetto startup tracing and stream the
// output to the given file.
// TODO(oysteine): Remove once Perfetto starts early enough after
// process startup to be able to replace the legacy startup tracing.
const char kPerfettoOutputFile[] = "perfetto-output-file";
+// If enabled (and perfetto is enabled), the data sources will write trace
+// events in the new TraceEvent proto format instead of the ChromeEventBundle
+// format.
+// TODO(eseckler): Remove this when we remove ChromeEventBundle support.
+const char kPerfettoUseNewProtos[] = "perfetto-use-new-protos";
+
// Sends a pretty-printed version of tracing info to the console.
const char kTraceToConsole[] = "trace-to-console";
diff --git a/chromium/components/tracing/common/tracing_switches.h b/chromium/components/tracing/common/tracing_switches.h
index 6304a24b360..859d82508f3 100644
--- a/chromium/components/tracing/common/tracing_switches.h
+++ b/chromium/components/tracing/common/tracing_switches.h
@@ -17,7 +17,10 @@ TRACING_EXPORT extern const char kTraceStartup[];
TRACING_EXPORT extern const char kTraceStartupDuration[];
TRACING_EXPORT extern const char kTraceStartupFile[];
TRACING_EXPORT extern const char kTraceStartupRecordMode[];
+TRACING_EXPORT extern const char kEnablePerfetto[];
+TRACING_EXPORT extern const char kPerfettoDisableInterning[];
TRACING_EXPORT extern const char kPerfettoOutputFile[];
+TRACING_EXPORT extern const char kPerfettoUseNewProtos[];
TRACING_EXPORT extern const char kTraceToConsole[];
TRACING_EXPORT extern const char kTraceUploadURL[];
diff --git a/chromium/components/translate/core/browser/BUILD.gn b/chromium/components/translate/core/browser/BUILD.gn
index aea0ed1c786..5ee75683ae5 100644
--- a/chromium/components/translate/core/browser/BUILD.gn
+++ b/chromium/components/translate/core/browser/BUILD.gn
@@ -84,12 +84,6 @@ source_set("unit_tests") {
testonly = true
sources = [
"language_state_unittest.cc",
- "mock_translate_client.cc",
- "mock_translate_client.h",
- "mock_translate_driver.cc",
- "mock_translate_driver.h",
- "mock_translate_ranker.cc",
- "mock_translate_ranker.h",
"translate_accept_languages_unittest.cc",
"translate_browser_metrics_unittest.cc",
"translate_language_list_unittest.cc",
@@ -102,6 +96,7 @@ source_set("unit_tests") {
]
deps = [
":browser",
+ ":test_support",
"//base",
"//components/assist_ranker",
"//components/assist_ranker/proto",
@@ -120,8 +115,38 @@ source_set("unit_tests") {
"//services/metrics/public/cpp:ukm_builders",
"//services/network:test_support",
"//services/network/public/cpp:cpp",
- "//testing/gtest",
- "//third_party/metrics_proto",
"//ui/base",
]
}
+
+source_set("test_support") {
+ testonly = true
+ sources = [
+ "mock_translate_client.cc",
+ "mock_translate_client.h",
+ "mock_translate_driver.cc",
+ "mock_translate_driver.h",
+ "mock_translate_ranker.cc",
+ "mock_translate_ranker.h",
+ ]
+ deps = [
+ "//base",
+ "//components/infobars/core",
+ "//components/language/core/browser",
+ "//components/sync_preferences",
+ "//components/sync_preferences:test_support",
+ "//components/translate/core/browser",
+ "//components/translate/core/common",
+ "//testing/gmock",
+ "//testing/gtest",
+ "//third_party/metrics_proto:metrics_proto",
+ "//url",
+ ]
+
+ if (is_ios || is_android) {
+ sources += [
+ "mock_translate_infobar_delegate.cc",
+ "mock_translate_infobar_delegate.h",
+ ]
+ }
+}
diff --git a/chromium/components/translate/core/language_detection/BUILD.gn b/chromium/components/translate/core/language_detection/BUILD.gn
index 5653eb1404f..713c50dde31 100644
--- a/chromium/components/translate/core/language_detection/BUILD.gn
+++ b/chromium/components/translate/core/language_detection/BUILD.gn
@@ -25,6 +25,7 @@ static_library("language_detection") {
deps = [
":chinese_script_classifier",
"//base",
+ "//components/language/core/common",
"//components/translate/core/common",
"//third_party/cld_3/src/src:cld_3",
"//third_party/icu",
diff --git a/chromium/components/translate_strings.grdp b/chromium/components/translate_strings.grdp
index d5ce1081db7..ce817d88da6 100644
--- a/chromium/components/translate_strings.grdp
+++ b/chromium/components/translate_strings.grdp
@@ -72,13 +72,16 @@
</message>
<!-- Translate Notifications -->
- <message name="IDS_TRANSLATE_NOTIFICATION_ALWAYS_TRANSLATE" desc="After the user selects 'Always translate pages in [source_language]', this text confirms the user's choice and lets them know that pages in [source_language] will be translated to the [target_language] automatically.">
+ <message name="IDS_TRANSLATE_NOTIFICATION_ERROR" desc="This text lets the user know that the page could not be translated.">
+ Oops. This page could not be translated.
+ </message>
+ <message name="IDS_TRANSLATE_NOTIFICATION_ALWAYS_TRANSLATE" desc="After the user selects 'Always translate [source_language]', this text confirms the user's choice and lets them know that pages in [source_language] will be translated to the [target_language] automatically.">
Pages in <ph name="source_language">$1<ex>French</ex></ph> will be translated to <ph name="target_language">$2<ex>English</ex></ph> from now on.
</message>
- <message name="IDS_TRANSLATE_NOTIFICATION_LANGUAGE_NEVER" desc="After the user selects 'Never translate pages in [language]', this text confirms the user's choice and lets them know that pages in [language] will not be translated to their chosen target language automatically.">
+ <message name="IDS_TRANSLATE_NOTIFICATION_LANGUAGE_NEVER" desc="After the user selects 'Never translate [language]', this text confirms the user's choice and lets them know that pages in [language] will not be translated to their chosen target language automatically.">
Pages in <ph name="language">$1<ex>French</ex></ph> will not be translated.
</message>
- <message name="IDS_TRANSLATE_NOTIFICATION_SITE_NEVER" desc="Text to be displayed in translate snackbar that lets the user know this site will not be translated.">
+ <message name="IDS_TRANSLATE_NOTIFICATION_SITE_NEVER" desc="After the user selects 'Never translate this site', this text confirms the user's choice and lets them know that this site will not be translated.">
This site will not be translated.
</message>
<message name="IDS_TRANSLATE_NOTIFICATION_UNDO" desc="A text label on the translate snackbar widget to undo the this selection.">
diff --git a/chromium/components/typemaps.gni b/chromium/components/typemaps.gni
index 780ef767707..e4019a5dde7 100644
--- a/chromium/components/typemaps.gni
+++ b/chromium/components/typemaps.gni
@@ -6,6 +6,7 @@ typemaps = [
"//components/account_id/interfaces/account_id.typemap",
"//components/autofill/content/common/autofill_types.typemap",
"//components/chrome_cleaner/public/typemaps/chrome_prompt.typemap",
+ "//components/content_capture/common/content_capture.typemap",
"//components/content_settings/core/common/content_settings.typemap",
"//components/nacl/common/nacl.typemap",
"//components/password_manager/content/common/credential_manager.typemap",
diff --git a/chromium/components/ui_devtools/BUILD.gn b/chromium/components/ui_devtools/BUILD.gn
index 5fde53c2a66..0036fafa125 100644
--- a/chromium/components/ui_devtools/BUILD.gn
+++ b/chromium/components/ui_devtools/BUILD.gn
@@ -6,6 +6,8 @@ _inspector_protocol = "//third_party/inspector_protocol"
import("$_inspector_protocol/inspector_protocol.gni")
_protocol_generated = [
+ "base_string_adapter.cc",
+ "base_string_adapter.h",
"CSS.cpp",
"CSS.h",
"DOM.cpp",
@@ -71,8 +73,6 @@ component("ui_devtools") {
"overlay_agent.h",
"root_element.cc",
"root_element.h",
- "string_util.cc",
- "string_util.h",
"switches.cc",
"switches.h",
"ui_element.cc",
diff --git a/chromium/components/ui_devtools/OWNERS b/chromium/components/ui_devtools/OWNERS
index 6507f289a50..95d3eeca0ad 100644
--- a/chromium/components/ui_devtools/OWNERS
+++ b/chromium/components/ui_devtools/OWNERS
@@ -1,5 +1,6 @@
sadrul@chromium.org
dgozman@chromium.org
lgrey@chromium.org
+pfeldman@chromium.org
# COMPONENT: Platform>DevTools
diff --git a/chromium/components/ui_devtools/css_agent.cc b/chromium/components/ui_devtools/css_agent.cc
index d4d9c57ba3a..4fd7f685b10 100644
--- a/chromium/components/ui_devtools/css_agent.cc
+++ b/chromium/components/ui_devtools/css_agent.cc
@@ -37,7 +37,7 @@ std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name,
return CSS::CSSProperty::create()
.setRange(BuildDefaultSourceRange())
.setName(name)
- .setValue(base::IntToString(value))
+ .setValue(base::NumberToString(value))
.build();
}
@@ -78,7 +78,7 @@ std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(UIElement* ui_element) {
return CSS::CSSStyle::create()
.setRange(BuildDefaultSourceRange())
- .setStyleSheetId(base::IntToString(ui_element->node_id()))
+ .setStyleSheetId(base::NumberToString(ui_element->node_id()))
.setCssProperties(std::move(css_properties))
.setShorthandEntries(Array<protocol::CSS::ShorthandEntry>::create())
.build();
@@ -191,7 +191,7 @@ std::unique_ptr<CSS::CSSStyle> CSSAgent::GetStylesForUIElement(
void CSSAgent::InvalidateStyleSheet(UIElement* ui_element) {
// The stylesheetId for each node is equivalent to its node_id (as a string).
- frontend()->styleSheetChanged(base::IntToString(ui_element->node_id()));
+ frontend()->styleSheetChanged(base::NumberToString(ui_element->node_id()));
}
bool CSSAgent::GetPropertiesForUIElement(UIElement* ui_element,
diff --git a/chromium/components/ui_devtools/css_agent_unittest.cc b/chromium/components/ui_devtools/css_agent_unittest.cc
index 320937d3763..675103f1918 100644
--- a/chromium/components/ui_devtools/css_agent_unittest.cc
+++ b/chromium/components/ui_devtools/css_agent_unittest.cc
@@ -86,7 +86,7 @@ class CSSAgentTest : public testing::Test {
int node_id) {
auto edits = protocol::Array<protocol::CSS::StyleDeclarationEdit>::create();
auto edit = protocol::CSS::StyleDeclarationEdit::create()
- .setStyleSheetId(base::IntToString(node_id))
+ .setStyleSheetId(base::NumberToString(node_id))
.setRange(protocol::CSS::SourceRange::create()
.setStartLine(0)
.setStartColumn(0)
@@ -171,7 +171,7 @@ TEST_F(CSSAgentTest, SettingVisibility) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "visibility"), "1");
}
@@ -184,7 +184,7 @@ TEST_F(CSSAgentTest, SettingX) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "x"), "500");
}
@@ -197,7 +197,7 @@ TEST_F(CSSAgentTest, SettingY) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "y"), "100");
}
TEST_F(CSSAgentTest, SettingWidth) {
@@ -209,7 +209,7 @@ TEST_F(CSSAgentTest, SettingWidth) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "width"), "20");
}
TEST_F(CSSAgentTest, SettingHeight) {
@@ -221,7 +221,7 @@ TEST_F(CSSAgentTest, SettingHeight) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "height"), "30");
}
@@ -239,7 +239,7 @@ TEST_F(CSSAgentTest, SettingAll) {
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
- base::IntToString(element()->node_id()));
+ base::NumberToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "x"), "9000");
EXPECT_EQ(GetValueForProperty(style, "y"), "25");
EXPECT_EQ(GetValueForProperty(style, "width"), "50");
diff --git a/chromium/components/ui_devtools/devtools_base_agent.h b/chromium/components/ui_devtools/devtools_base_agent.h
index 7d24f96f3a2..7f44cdccfc1 100644
--- a/chromium/components/ui_devtools/devtools_base_agent.h
+++ b/chromium/components/ui_devtools/devtools_base_agent.h
@@ -38,9 +38,9 @@ class UiDevToolsBaseAgent : public UiDevToolsAgent,
// Common methods between all generated Backends, subclasses may
// choose to override them (but not necessary).
- protocol::Response enable() override { return protocol::Response::OK(); };
+ protocol::Response enable() override { return protocol::Response::OK(); }
- protocol::Response disable() override { return protocol::Response::OK(); };
+ protocol::Response disable() override { return protocol::Response::OK(); }
protected:
UiDevToolsBaseAgent() {}
diff --git a/chromium/components/ui_devtools/devtools_client.cc b/chromium/components/ui_devtools/devtools_client.cc
index 1356bc356c9..865f209b100 100644
--- a/chromium/components/ui_devtools/devtools_client.cc
+++ b/chromium/components/ui_devtools/devtools_client.cc
@@ -33,7 +33,7 @@ void UiDevToolsClient::Dispatch(const std::string& data) {
int call_id;
std::string method;
std::unique_ptr<protocol::Value> protocolCommand =
- protocol::StringUtil::parseJSON(data);
+ protocol::StringUtil::parseMessage(data, false);
if (dispatcher_.parseCommand(protocolCommand.get(), &call_id, &method)) {
dispatcher_.dispatch(call_id, method, std::move(protocolCommand), data);
}
@@ -60,13 +60,13 @@ void UiDevToolsClient::sendProtocolResponse(
int callId,
std::unique_ptr<protocol::Serializable> message) {
if (connected())
- server_->SendOverWebSocket(connection_id_, message->serialize());
+ server_->SendOverWebSocket(connection_id_, message->serialize(false));
}
void UiDevToolsClient::sendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) {
if (connected())
- server_->SendOverWebSocket(connection_id_, message->serialize());
+ server_->SendOverWebSocket(connection_id_, message->serialize(false));
}
void UiDevToolsClient::flushProtocolNotifications() {
diff --git a/chromium/components/ui_devtools/devtools_server.cc b/chromium/components/ui_devtools/devtools_server.cc
index a1625b72d68..a4a1c407eea 100644
--- a/chromium/components/ui_devtools/devtools_server.cc
+++ b/chromium/components/ui_devtools/devtools_server.cc
@@ -168,7 +168,7 @@ void UiDevToolsServer::AttachClient(std::unique_ptr<UiDevToolsClient> client) {
}
void UiDevToolsServer::SendOverWebSocket(int connection_id,
- const String& message) {
+ const protocol::String& message) {
DCHECK_CALLED_ON_VALID_SEQUENCE(devtools_server_sequence_);
server_->SendOverWebSocket(connection_id, message, tag_);
}
diff --git a/chromium/components/ui_devtools/devtools_server.h b/chromium/components/ui_devtools/devtools_server.h
index f4395f75f63..12877d13b8b 100644
--- a/chromium/components/ui_devtools/devtools_server.h
+++ b/chromium/components/ui_devtools/devtools_server.h
@@ -16,7 +16,6 @@
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/devtools_client.h"
#include "components/ui_devtools/devtools_export.h"
-#include "components/ui_devtools/string_util.h"
#include "services/network/public/cpp/server/http_server.h"
namespace ui_devtools {
@@ -63,7 +62,7 @@ class UI_DEVTOOLS_EXPORT UiDevToolsServer
int default_port);
void AttachClient(std::unique_ptr<UiDevToolsClient> client);
- void SendOverWebSocket(int connection_id, const String& message);
+ void SendOverWebSocket(int connection_id, const protocol::String& message);
int port() const { return port_; }
diff --git a/chromium/components/ui_devtools/dom_agent.cc b/chromium/components/ui_devtools/dom_agent.cc
index c12800ae426..925d61cab8f 100644
--- a/chromium/components/ui_devtools/dom_agent.cc
+++ b/chromium/components/ui_devtools/dom_agent.cc
@@ -66,7 +66,7 @@ void DOMAgent::OnUIElementAdded(UIElement* parent, UIElement* child) {
const auto& children = parent->children();
auto iter = std::find(children.begin(), children.end(), child);
int prev_node_id =
- (iter == children.end() - 1) ? 0 : (*std::next(iter))->node_id();
+ (iter == children.begin()) ? 0 : (*std::prev(iter))->node_id();
frontend()->childNodeInserted(parent->node_id(), prev_node_id,
BuildTreeForUIElement(child));
diff --git a/chromium/components/ui_devtools/inspector_protocol_config.json b/chromium/components/ui_devtools/inspector_protocol_config.json
index 76292154de1..41062e7950e 100644
--- a/chromium/components/ui_devtools/inspector_protocol_config.json
+++ b/chromium/components/ui_devtools/inspector_protocol_config.json
@@ -10,7 +10,7 @@
"lib": {
"package": "components/ui_devtools",
"output": "",
- "string_header": "components/ui_devtools/string_util.h",
+ "string_header": "components/ui_devtools/base_string_adapter.h",
"export_macro": "UI_DEVTOOLS_EXPORT",
"export_header": "components/ui_devtools/devtools_export.h"
}
diff --git a/chromium/components/ui_devtools/overlay_agent.cc b/chromium/components/ui_devtools/overlay_agent.cc
index 5804dc00784..5cd89fbee43 100644
--- a/chromium/components/ui_devtools/overlay_agent.cc
+++ b/chromium/components/ui_devtools/overlay_agent.cc
@@ -13,7 +13,7 @@ OverlayAgent::OverlayAgent(DOMAgent* dom_agent) : dom_agent_(dom_agent) {
OverlayAgent::~OverlayAgent() {}
protocol::Response OverlayAgent::setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
NOTREACHED();
return protocol::Response::OK();
diff --git a/chromium/components/ui_devtools/overlay_agent.h b/chromium/components/ui_devtools/overlay_agent.h
index 2bee58a189c..5d0de0e0102 100644
--- a/chromium/components/ui_devtools/overlay_agent.h
+++ b/chromium/components/ui_devtools/overlay_agent.h
@@ -18,7 +18,7 @@ class UI_DEVTOOLS_EXPORT OverlayAgent
// Overlay::Backend:
protocol::Response setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
override;
protocol::Response highlightNode(
@@ -27,7 +27,7 @@ class UI_DEVTOOLS_EXPORT OverlayAgent
protocol::Response hideHighlight() override;
protected:
- DOMAgent* dom_agent() const { return dom_agent_; };
+ DOMAgent* dom_agent() const { return dom_agent_; }
private:
DOMAgent* const dom_agent_;
diff --git a/chromium/components/ui_devtools/string_util.cc b/chromium/components/ui_devtools/string_util.cc
deleted file mode 100644
index fde02a7b521..00000000000
--- a/chromium/components/ui_devtools/string_util.cc
+++ /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.
-
-#include "components/ui_devtools/string_util.h"
-
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/ui_devtools/Protocol.h"
-
-namespace ui_devtools {
-namespace protocol {
-
-// static
-std::unique_ptr<Value> StringUtil::parseJSON(const String& string) {
- DCHECK(base::IsStringUTF8(string));
- // TODO(mhashmi): 16-bit strings need to be handled
- return parseJSONCharacters(reinterpret_cast<const uint8_t*>(&string[0]),
- string.length());
-};
-
-// static
-void StringUtil::builderAppendQuotedString(StringBuilder& builder,
- const String& str) {
- builder.append('"');
- base::string16 str16 = base::UTF8ToUTF16(str);
- escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(&str16[0]),
- str16.length(), &builder);
- builder.append('"');
-}
-
-} // namespace protocol
-} // namespace ui_devtools
diff --git a/chromium/components/ui_devtools/string_util.h b/chromium/components/ui_devtools/string_util.h
deleted file mode 100644
index 50995dcb724..00000000000
--- a/chromium/components/ui_devtools/string_util.h
+++ /dev/null
@@ -1,93 +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_UI_DEVTOOLS_STRING_UTIL_H_
-#define COMPONENTS_UI_DEVTOOLS_STRING_UTIL_H_
-
-#include <memory>
-
-#include "base/json/json_reader.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace ui_devtools {
-
-using String = std::string;
-
-namespace protocol {
-
-class Value;
-
-class CustomStringBuilder {
- String s_;
-
- public:
- CustomStringBuilder() {}
- CustomStringBuilder(String& s) : s_(s) {}
- void reserveCapacity(std::size_t size) { s_.reserve(size); }
- void append(const String& s) { s_ += s; }
- void append(char c) { s_ += c; }
- void append(const char* data, size_t length) { s_.append(data, length); }
- String toString() { return s_; }
-};
-
-using StringBuilder = CustomStringBuilder;
-
-class StringUtil {
- public:
- static String substring(const String& s, unsigned pos, unsigned len) {
- return s.substr(pos, len);
- }
- static String fromInteger(int number) { return base::IntToString(number); }
- static String fromDouble(double number) {
- return base::NumberToString(number);
- }
- static double toDouble(const char* s, size_t len, bool* ok) {
- double v = 0.0;
- *ok = base::StringToDouble(std::string(s, len), &v);
- return *ok ? v : 0.0;
- }
- static void builderAppend(StringBuilder& builder, const String& s) {
- builder.append(s);
- }
- static void builderAppend(StringBuilder& builder, char c) {
- builder.append(c);
- }
- static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
- builder.append(s, len);
- }
- static void builderAppendQuotedString(StringBuilder& builder,
- const String& str);
- static void builderReserve(StringBuilder& builder, unsigned capacity) {
- builder.reserveCapacity(capacity);
- }
- static String builderToString(StringBuilder& builder) {
- return builder.toString();
- }
- static size_t find(const String& s, const char* needle) {
- return s.find(needle);
- }
- static size_t find(const String& s, const String& needle) {
- return s.find(needle);
- }
- static const size_t kNotFound = static_cast<size_t>(-1);
- static std::unique_ptr<Value> parseJSON(const String& string);
-};
-
-// A read-only sequence of uninterpreted bytes with reference-counted storage.
-// Though the templates for generating the protocol bindings reference
-// this type, thus far it's not used in the Chrome layer, so we provide no
-// implementation here and rely on the linker optimizing it away. If this
-// changes, look to content/browser/devtools/protocol_string{.h,.cc} for
-// inspiration.
-class Binary {
- public:
- const uint8_t* data() const;
- size_t size() const;
- String toBase64() const;
- static Binary fromBase64(const String& base64, bool* success);
-};
-} // namespace protocol
-} // namespace ui_devtools
-
-#endif // COMPONENTS_UI_DEVTOOLS_STRING_UTIL_H_
diff --git a/chromium/components/ui_devtools/ui_devtools_unittest_utils.cc b/chromium/components/ui_devtools/ui_devtools_unittest_utils.cc
index 462cc9f2c6a..a2303d5e927 100644
--- a/chromium/components/ui_devtools/ui_devtools_unittest_utils.cc
+++ b/chromium/components/ui_devtools/ui_devtools_unittest_utils.cc
@@ -32,7 +32,7 @@ int FakeFrontendChannel::CountProtocolNotificationMessage(
void FakeFrontendChannel::sendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) {
EXPECT_TRUE(allow_notifications_);
- protocol_notification_messages_.push_back(message->serialize());
+ protocol_notification_messages_.push_back(message->serialize(false));
}
} // namespace ui_devtools
diff --git a/chromium/components/ui_devtools/ui_element.cc b/chromium/components/ui_devtools/ui_element.cc
index 8883a12e6dd..a760ee02052 100644
--- a/chromium/components/ui_devtools/ui_element.cc
+++ b/chromium/components/ui_devtools/ui_element.cc
@@ -54,12 +54,23 @@ void UIElement::AddChild(UIElement* child, UIElement* before) {
delegate_->OnUIElementAdded(this, child);
}
+void UIElement::AddOrderedChild(UIElement* child,
+ ElementCompare compare,
+ bool notify_delegate) {
+ auto iter =
+ std::lower_bound(children_.begin(), children_.end(), child, compare);
+ children_.insert(iter, child);
+ if (notify_delegate)
+ delegate_->OnUIElementAdded(this, child);
+}
+
void UIElement::ClearChildren() {
children_.clear();
}
-void UIElement::RemoveChild(UIElement* child) {
- delegate()->OnUIElementRemoved(child);
+void UIElement::RemoveChild(UIElement* child, bool notify_delegate) {
+ if (notify_delegate)
+ delegate_->OnUIElementRemoved(child);
auto iter = std::find(children_.begin(), children_.end(), child);
DCHECK(iter != children_.end());
children_.erase(iter);
diff --git a/chromium/components/ui_devtools/ui_element.h b/chromium/components/ui_devtools/ui_element.h
index 10abb56eecd..6fbdd8ae3c2 100644
--- a/chromium/components/ui_devtools/ui_element.h
+++ b/chromium/components/ui_devtools/ui_element.h
@@ -41,17 +41,27 @@ class UI_DEVTOOLS_EXPORT UIElement {
void set_is_updating(bool is_updating) { is_updating_ = is_updating; }
void set_owns_children(bool owns_children) { owns_children_ = owns_children; }
+ using ElementCompare = bool (*)(const UIElement*, const UIElement*);
+
// |child| is inserted in front of |before|. If |before| is null, it
// is inserted at the end. Parent takes ownership of the added child.
void AddChild(UIElement* child, UIElement* before = nullptr);
+ // |child| is inserted according to a custom ordering function.
+ // |notify_delegate| calls OnUIElementAdded, which creates the subtree of
+ // UIElements at |child|, and the corresponding DOM nodes.
+ void AddOrderedChild(UIElement* child,
+ ElementCompare compare,
+ bool notify_delegate = true);
+
// Removes all elements from |children_|. Caller is responsible for destroying
// children.
void ClearChildren();
// Remove |child| out of vector |children_| but |child| is not destroyed.
- // The caller is responsible for destroying |child|.
- void RemoveChild(UIElement* child);
+ // The caller is responsible for destroying |child|. |notify_delegate| calls
+ // OnUIElementRemoved, which destroys the DOM node for |child|.
+ void RemoveChild(UIElement* child, bool notify_delegate = true);
// Move |child| to position new_index in |children_|.
void ReorderChild(UIElement* child, int new_index);
diff --git a/chromium/components/ui_devtools/ui_element_delegate.h b/chromium/components/ui_devtools/ui_element_delegate.h
index c8dde2ea32e..7b3205b73fe 100644
--- a/chromium/components/ui_devtools/ui_element_delegate.h
+++ b/chromium/components/ui_devtools/ui_element_delegate.h
@@ -15,8 +15,8 @@ class UIElement;
class UIElementDelegate {
public:
- UIElementDelegate(){};
- virtual ~UIElementDelegate(){};
+ UIElementDelegate() {}
+ virtual ~UIElementDelegate() {}
virtual void OnUIElementAdded(UIElement* parent, UIElement* child) = 0;
diff --git a/chromium/components/ui_devtools/views/dom_agent_aura.cc b/chromium/components/ui_devtools/views/dom_agent_aura.cc
index 3a140cd8d34..db17684b416 100644
--- a/chromium/components/ui_devtools/views/dom_agent_aura.cc
+++ b/chromium/components/ui_devtools/views/dom_agent_aura.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/stl_util.h"
#include "components/ui_devtools/devtools_server.h"
#include "components/ui_devtools/root_element.h"
#include "components/ui_devtools/ui_element.h"
@@ -65,7 +66,7 @@ void DOMAgentAura::OnHostInitialized(aura::WindowTreeHost* host) {
}
void DOMAgentAura::OnWindowDestroying(aura::Window* window) {
- roots_.erase(std::remove(roots_.begin(), roots_.end(), window), roots_.end());
+ base::Erase(roots_, window);
}
std::vector<UIElement*> DOMAgentAura::CreateChildrenForRoot() {
diff --git a/chromium/components/ui_devtools/views/overlay_agent_aura.cc b/chromium/components/ui_devtools/views/overlay_agent_aura.cc
index bd0614a379c..d7c5e6a7b9a 100644
--- a/chromium/components/ui_devtools/views/overlay_agent_aura.cc
+++ b/chromium/components/ui_devtools/views/overlay_agent_aura.cc
@@ -396,7 +396,7 @@ void OverlayAgentAura::SetPinnedNodeId(int node_id) {
}
protocol::Response OverlayAgentAura::setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
pinned_id_ = 0;
if (in_mode.compare("searchForNode") == 0) {
diff --git a/chromium/components/ui_devtools/views/overlay_agent_aura.h b/chromium/components/ui_devtools/views/overlay_agent_aura.h
index 9659ca8bdcd..b371cba4568 100644
--- a/chromium/components/ui_devtools/views/overlay_agent_aura.h
+++ b/chromium/components/ui_devtools/views/overlay_agent_aura.h
@@ -53,7 +53,7 @@ class OverlayAgentAura : public OverlayAgent,
// Overlay::Backend:
protocol::Response setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
override;
protocol::Response highlightNode(
@@ -63,7 +63,7 @@ class OverlayAgentAura : public OverlayAgent,
HighlightRectsConfiguration highlight_rect_config() const {
return highlight_rect_config_;
- };
+ }
// Return the id of the UI element located at |event|'s root location.
// The function first searches for the targeted window, then the targeted
diff --git a/chromium/components/ui_devtools/views/view_element.cc b/chromium/components/ui_devtools/views/view_element.cc
index 2caf77967e0..2872741c86d 100644
--- a/chromium/components/ui_devtools/views/view_element.cc
+++ b/chromium/components/ui_devtools/views/view_element.cc
@@ -37,8 +37,7 @@ void ViewElement::OnChildViewRemoved(views::View* parent, views::View* view) {
void ViewElement::OnChildViewAdded(views::View* parent, views::View* view) {
DCHECK_EQ(parent, view_);
- AddChild(new ViewElement(view, delegate(), this),
- children().empty() ? nullptr : children().back());
+ AddChild(new ViewElement(view, delegate(), this));
}
void ViewElement::OnChildViewReordered(views::View* parent, views::View* view) {
diff --git a/chromium/components/ui_devtools/views/view_element.h b/chromium/components/ui_devtools/views/view_element.h
index ee84c75a274..2f5a7c3d108 100644
--- a/chromium/components/ui_devtools/views/view_element.h
+++ b/chromium/components/ui_devtools/views/view_element.h
@@ -22,7 +22,7 @@ class ViewElement : public views::ViewObserver, public UIElement {
UIElementDelegate* ui_element_delegate,
UIElement* parent);
~ViewElement() override;
- views::View* view() const { return view_; };
+ views::View* view() const { return view_; }
// views::ViewObserver
void OnChildViewRemoved(views::View* parent, views::View* view) override;
diff --git a/chromium/components/ui_devtools/views/widget_element.h b/chromium/components/ui_devtools/views/widget_element.h
index 24a90cca535..b041e4d09b1 100644
--- a/chromium/components/ui_devtools/views/widget_element.h
+++ b/chromium/components/ui_devtools/views/widget_element.h
@@ -25,7 +25,7 @@ class WidgetElement : public views::WidgetRemovalsObserver,
UIElementDelegate* ui_element_delegate,
UIElement* parent);
~WidgetElement() override;
- views::Widget* widget() const { return widget_; };
+ views::Widget* widget() const { return widget_; }
// views::WidgetRemovalsObserver:
void OnWillRemoveView(views::Widget* widget, views::View* view) override;
diff --git a/chromium/components/ui_devtools/views/widget_element_unittest.cc b/chromium/components/ui_devtools/views/widget_element_unittest.cc
index 3587e80e728..31a5352a83e 100644
--- a/chromium/components/ui_devtools/views/widget_element_unittest.cc
+++ b/chromium/components/ui_devtools/views/widget_element_unittest.cc
@@ -46,7 +46,7 @@ class WidgetElementTest : public views::ViewsTestBase {
}
protected:
- views::Widget* widget() { return widget_; };
+ views::Widget* widget() { return widget_; }
WidgetElement* element() { return element_.get(); }
MockUIElementDelegate* delegate() { return delegate_.get(); }
diff --git a/chromium/components/ui_devtools/views/window_element.cc b/chromium/components/ui_devtools/views/window_element.cc
index 366d13ee4dc..0378b762902 100644
--- a/chromium/components/ui_devtools/views/window_element.cc
+++ b/chromium/components/ui_devtools/views/window_element.cc
@@ -48,8 +48,7 @@ void WindowElement::OnWindowHierarchyChanging(
void WindowElement::OnWindowHierarchyChanged(
const aura::WindowObserver::HierarchyChangeParams& params) {
if (window_ == params.new_parent && params.receiver == params.new_parent) {
- AddChild(new WindowElement(params.target, delegate(), this),
- children().empty() ? nullptr : children().back());
+ AddChild(new WindowElement(params.target, delegate(), this));
}
}
diff --git a/chromium/components/ui_devtools/views/window_element.h b/chromium/components/ui_devtools/views/window_element.h
index 89c32800d44..d32b85848b0 100644
--- a/chromium/components/ui_devtools/views/window_element.h
+++ b/chromium/components/ui_devtools/views/window_element.h
@@ -20,7 +20,7 @@ class WindowElement : public aura::WindowObserver, public UIElement {
UIElementDelegate* ui_element_delegate,
UIElement* parent);
~WindowElement() override;
- aura::Window* window() const { return window_; };
+ aura::Window* window() const { return window_; }
// WindowObserver:
void OnWindowHierarchyChanging(
diff --git a/chromium/components/ui_devtools/viz/BUILD.gn b/chromium/components/ui_devtools/viz/BUILD.gn
index 235b1d6a1cf..3242bedf991 100644
--- a/chromium/components/ui_devtools/viz/BUILD.gn
+++ b/chromium/components/ui_devtools/viz/BUILD.gn
@@ -14,6 +14,8 @@ source_set("viz") {
"overlay_agent_viz.h",
"surface_element.cc",
"surface_element.h",
+ "viz_element.cc",
+ "viz_element.h",
]
deps = [
diff --git a/chromium/components/ui_devtools/viz/dom_agent_viz.cc b/chromium/components/ui_devtools/viz/dom_agent_viz.cc
index 76052207973..85ab818a6ba 100644
--- a/chromium/components/ui_devtools/viz/dom_agent_viz.cc
+++ b/chromium/components/ui_devtools/viz/dom_agent_viz.cc
@@ -90,7 +90,8 @@ void DOMAgentViz::OnFirstSurfaceActivation(
const viz::SurfaceId& surface_id = surface_info.id();
if (!base::ContainsKey(surface_elements_, surface_id)) {
UIElement* surface_root = GetRootSurfaceElement();
- surface_root->AddChild(CreateSurfaceElement(surface_id, surface_root));
+ CreateSurfaceElement(surface_id, surface_root)
+ ->AddToParentSorted(surface_root);
}
}
@@ -121,7 +122,8 @@ void DOMAgentViz::OnAddedSurfaceReference(const viz::SurfaceId& parent_id,
auto it_parent = surface_elements_.find(parent_id);
if (it_parent == surface_elements_.end()) {
UIElement* surface_root = GetRootSurfaceElement();
- surface_root->AddChild(CreateSurfaceElement(parent_id, surface_root));
+ CreateSurfaceElement(parent_id, surface_root)
+ ->AddToParentSorted(surface_root);
// The subtree is populated in AddChild, so we don't need to do anything
// else here.
return;
@@ -132,10 +134,10 @@ void DOMAgentViz::OnAddedSurfaceReference(const viz::SurfaceId& parent_id,
// create a new element as a child of |parent| if it doesn't already exist.
auto it_child = surface_elements_.find(child_id);
if (it_child == surface_elements_.end()) {
- parent->AddChild(CreateSurfaceElement(child_id, parent));
+ CreateSurfaceElement(child_id, parent)->AddToParentSorted(parent);
} else {
- UIElement* child = it_child->second.get();
- Reparent(parent, child);
+ SurfaceElement* child = it_child->second.get();
+ child->Reparent(parent);
}
}
@@ -145,7 +147,7 @@ void DOMAgentViz::OnRemovedSurfaceReference(const viz::SurfaceId& parent_id,
// surface.
auto it_child = surface_elements_.find(child_id);
DCHECK(it_child != surface_elements_.end());
- UIElement* child = it_child->second.get();
+ SurfaceElement* child = it_child->second.get();
// Do nothing if parent is not a parent of this child anymore. This can
// happen when we have Surface A referencing Surface B, then we create
@@ -157,16 +159,16 @@ void DOMAgentViz::OnRemovedSurfaceReference(const viz::SurfaceId& parent_id,
if (SurfaceElement::From(old_parent) != parent_id)
return;
- Reparent(GetRootSurfaceElement(), child);
+ child->Reparent(GetRootSurfaceElement());
}
void DOMAgentViz::OnRegisteredFrameSinkId(
const viz::FrameSinkId& frame_sink_id) {
// If a FrameSink was just registered we don't know anything about
// hierarchy. So we should attach it to the RootElement.
- element_root()->AddChild(
- CreateFrameSinkElement(frame_sink_id, element_root(), /*is_root=*/false,
- /*has_created_frame_sink=*/false));
+ CreateFrameSinkElement(frame_sink_id, element_root(), /*is_root=*/false,
+ /*has_created_frame_sink=*/false)
+ ->AddToParentSorted(element_root());
}
void DOMAgentViz::OnInvalidatedFrameSinkId(
@@ -215,7 +217,7 @@ void DOMAgentViz::OnRegisteredFrameSinkHierarchy(
FrameSinkElement* new_parent = it_parent->second.get();
// TODO: Add support for |child| to have multiple parents.
- Reparent(new_parent, child);
+ child->Reparent(new_parent);
}
void DOMAgentViz::OnUnregisteredFrameSinkHierarchy(
@@ -231,7 +233,7 @@ void DOMAgentViz::OnUnregisteredFrameSinkHierarchy(
// TODO: Add support for |child| to have multiple parents: only adds |child|
// to RootElement if all parents of |child| are unregistered.
- Reparent(element_root(), child);
+ child->Reparent(element_root());
}
SurfaceElement* DOMAgentViz::GetRootSurfaceElement() {
@@ -256,7 +258,7 @@ std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForFrameSink(
child_id, parent_element, /*is_root=*/false, has_created_frame_sink);
children->addItem(BuildTreeForFrameSink(child_element, child_id));
- parent_element->AddChild(child_element);
+ child_element->AddToParentSorted(parent_element);
}
return BuildNode("FrameSink", parent_element->GetAttributes(),
@@ -273,15 +275,18 @@ std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForSurface(
// recursively build the subtree for them.
for (auto& child_id :
surface_manager_->GetSurfacesReferencedByParent(parent_id)) {
- // If the child element exists already, destroy it and rebuild here.
+ SurfaceElement* child_element;
+ // If the child element exists already, move it here.
auto it_child = surface_elements_.find(child_id);
- if (it_child != surface_elements_.end())
- DestroyElementAndRemoveSubtree(it_child->second.get());
+ if (it_child != surface_elements_.end()) {
+ child_element = it_child->second.get();
+ child_element->Reparent(parent_element);
+ } else {
+ child_element = CreateSurfaceElement(child_id, parent_element);
+ child_element->AddToParentSorted(parent_element);
+ }
- SurfaceElement* child_element =
- CreateSurfaceElement(child_id, parent_element);
children->addItem(BuildTreeForSurface(child_element, child_id));
- parent_element->AddChild(child_element);
}
return BuildNode("Surface", parent_element->GetAttributes(),
@@ -365,26 +370,12 @@ void DOMAgentViz::DestroyElementAndRemoveSubtree(UIElement* element) {
// elements are moved.
std::vector<UIElement*> children(element->children());
for (auto* child : children)
- Reparent(new_parent, child);
+ VizElement::AsVizElement(child)->Reparent(new_parent);
element->parent()->RemoveChild(element);
DestroyElement(element);
}
-void DOMAgentViz::Reparent(UIElement* new_parent, UIElement* child) {
- if (new_parent == child->parent())
- return;
-
- DestroySubtree(child);
-
- // This removes the child element from the Node map. It has to be added with
- // null parent to recreate the entry.
- child->parent()->RemoveChild(child);
- OnUIElementAdded(nullptr, child);
- new_parent->AddChild(child);
- child->set_parent(new_parent);
-}
-
void DOMAgentViz::DestroyElement(UIElement* element) {
if (element->type() == UIElementType::FRAMESINK) {
frame_sink_elements_.erase(FrameSinkElement::From(element));
@@ -395,14 +386,6 @@ void DOMAgentViz::DestroyElement(UIElement* element) {
}
}
-void DOMAgentViz::DestroySubtree(UIElement* element) {
- for (auto* child : element->children()) {
- DestroySubtree(child);
- DestroyElement(child);
- }
- element->ClearChildren();
-}
-
FrameSinkElement* DOMAgentViz::CreateFrameSinkElement(
const viz::FrameSinkId& frame_sink_id,
UIElement* parent,
diff --git a/chromium/components/ui_devtools/viz/dom_agent_viz.h b/chromium/components/ui_devtools/viz/dom_agent_viz.h
index d5618f80eaf..540b270598b 100644
--- a/chromium/components/ui_devtools/viz/dom_agent_viz.h
+++ b/chromium/components/ui_devtools/viz/dom_agent_viz.h
@@ -36,13 +36,13 @@ class DOMAgentViz : public viz::SurfaceObserver,
// viz::SurfaceObserver:
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnSurfaceActivated(const viz::SurfaceId& surface_id,
- base::Optional<base::TimeDelta> duration) override{};
- void OnSurfaceDestroyed(const viz::SurfaceId& surface_id) override{};
+ base::Optional<base::TimeDelta> duration) override {}
+ void OnSurfaceDestroyed(const viz::SurfaceId& surface_id) override {}
bool OnSurfaceDamaged(const viz::SurfaceId& surface_id,
const viz::BeginFrameAck& ack) override;
void OnSurfaceDiscarded(const viz::SurfaceId& surface_id) override;
void OnSurfaceDamageExpected(const viz::SurfaceId& surface_id,
- const viz::BeginFrameArgs& args) override{};
+ const viz::BeginFrameArgs& args) override {}
void OnAddedSurfaceReference(const viz::SurfaceId& parent_id,
const viz::SurfaceId& child_id) override;
void OnRemovedSurfaceReference(const viz::SurfaceId& parent_id,
@@ -93,21 +93,10 @@ class DOMAgentViz : public viz::SurfaceObserver,
// Destroy |element| and attach all its children to the root_element().
void DestroyElementAndRemoveSubtree(UIElement* element);
- // Destroy all children and move to |new_parent|. This also rebuilds the
- // subtree via BuildTreeForUIElement.
- // TODO(sgilhuly): Improve the way reparenting is handled. Currently, after
- // the node is removed, you have to remove all of its children, and add the
- // element back to the tree. Then, the list of children is repopulated.
- void Reparent(UIElement* new_parent, UIElement* child);
-
// Removes an element from either |frame_sink_elements_| or
// |surface_elements_|.
void DestroyElement(UIElement* element);
- // Remove all subtree elements from either |frame_sink_elements_| or
- // |surface_elements_|. |element| itself is preserved.
- void DestroySubtree(UIElement* element);
-
// Constructs a new FrameSinkElement with some default arguments, adds it to
// |frame_sink_elements_|, and returns its pointer.
FrameSinkElement* CreateFrameSinkElement(
diff --git a/chromium/components/ui_devtools/viz/frame_sink_element.cc b/chromium/components/ui_devtools/viz/frame_sink_element.cc
index 697ded6a7e6..4ee4a9c0cb8 100644
--- a/chromium/components/ui_devtools/viz/frame_sink_element.cc
+++ b/chromium/components/ui_devtools/viz/frame_sink_element.cc
@@ -21,7 +21,7 @@ FrameSinkElement::FrameSinkElement(
UIElement* parent,
bool is_root,
bool has_created_frame_sink)
- : UIElement(UIElementType::FRAMESINK, ui_element_delegate, parent),
+ : VizElement(UIElementType::FRAMESINK, ui_element_delegate, parent),
frame_sink_id_(frame_sink_id),
frame_sink_manager_(frame_sink_manager),
is_root_(is_root),
diff --git a/chromium/components/ui_devtools/viz/frame_sink_element.h b/chromium/components/ui_devtools/viz/frame_sink_element.h
index 70dc5235c08..37bb48037c1 100644
--- a/chromium/components/ui_devtools/viz/frame_sink_element.h
+++ b/chromium/components/ui_devtools/viz/frame_sink_element.h
@@ -6,7 +6,7 @@
#define COMPONENTS_UI_DEVTOOLS_VIZ_FRAME_SINK_ELEMENT_H_
#include "base/macros.h"
-#include "components/ui_devtools/ui_element.h"
+#include "components/ui_devtools/viz/viz_element.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
namespace viz {
@@ -15,7 +15,7 @@ class FrameSinkManagerImpl;
namespace ui_devtools {
-class FrameSinkElement : public UIElement {
+class FrameSinkElement : public VizElement {
public:
FrameSinkElement(const viz::FrameSinkId& frame_sink_id,
viz::FrameSinkManagerImpl* frame_sink_manager,
diff --git a/chromium/components/ui_devtools/viz/overlay_agent_viz.cc b/chromium/components/ui_devtools/viz/overlay_agent_viz.cc
index 7501924e7a5..85e7d62b52f 100644
--- a/chromium/components/ui_devtools/viz/overlay_agent_viz.cc
+++ b/chromium/components/ui_devtools/viz/overlay_agent_viz.cc
@@ -12,7 +12,7 @@ OverlayAgentViz::OverlayAgentViz(DOMAgentViz* dom_agent)
OverlayAgentViz::~OverlayAgentViz() {}
protocol::Response OverlayAgentViz::setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
return protocol::Response::OK();
}
diff --git a/chromium/components/ui_devtools/viz/overlay_agent_viz.h b/chromium/components/ui_devtools/viz/overlay_agent_viz.h
index c71652c6156..531071663a9 100644
--- a/chromium/components/ui_devtools/viz/overlay_agent_viz.h
+++ b/chromium/components/ui_devtools/viz/overlay_agent_viz.h
@@ -18,7 +18,7 @@ class OverlayAgentViz : public OverlayAgent {
// Overlay::Backend:
protocol::Response setInspectMode(
- const String& in_mode,
+ const protocol::String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
override;
protocol::Response highlightNode(
diff --git a/chromium/components/ui_devtools/viz/surface_element.cc b/chromium/components/ui_devtools/viz/surface_element.cc
index 9c46fa9b347..bb44354f55d 100644
--- a/chromium/components/ui_devtools/viz/surface_element.cc
+++ b/chromium/components/ui_devtools/viz/surface_element.cc
@@ -16,7 +16,7 @@ SurfaceElement::SurfaceElement(const viz::SurfaceId& surface_id,
viz::FrameSinkManagerImpl* frame_sink_manager,
UIElementDelegate* ui_element_delegate,
UIElement* parent)
- : UIElement(UIElementType::SURFACE, ui_element_delegate, parent),
+ : VizElement(UIElementType::SURFACE, ui_element_delegate, parent),
surface_id_(surface_id),
frame_sink_manager_(frame_sink_manager) {
viz::Surface* surface =
diff --git a/chromium/components/ui_devtools/viz/surface_element.h b/chromium/components/ui_devtools/viz/surface_element.h
index eed60c78a4a..93d34c1ccbe 100644
--- a/chromium/components/ui_devtools/viz/surface_element.h
+++ b/chromium/components/ui_devtools/viz/surface_element.h
@@ -6,7 +6,7 @@
#define COMPONENTS_UI_DEVTOOLS_VIZ_SURFACE_ELEMENT_H_
#include "base/macros.h"
-#include "components/ui_devtools/ui_element.h"
+#include "components/ui_devtools/viz/viz_element.h"
#include "components/viz/common/surfaces/surface_id.h"
namespace viz {
@@ -16,7 +16,7 @@ class FrameSinkManagerImpl;
namespace ui_devtools {
// A type of UIElement. Each SurfaceElement is corresponding to a SurfaceId.
-class SurfaceElement : public UIElement {
+class SurfaceElement : public VizElement {
public:
SurfaceElement(const viz::SurfaceId& surface_id,
viz::FrameSinkManagerImpl* frame_sink_manager,
diff --git a/chromium/components/ui_devtools/viz/viz_devtools_unittest.cc b/chromium/components/ui_devtools/viz/viz_devtools_unittest.cc
index 849168f269e..37c4467d44f 100644
--- a/chromium/components/ui_devtools/viz/viz_devtools_unittest.cc
+++ b/chromium/components/ui_devtools/viz/viz_devtools_unittest.cc
@@ -149,8 +149,8 @@ class VizDevToolsTest : public PlatformTest {
viz::SurfaceId CreateFrameSinkAndSurface(
const viz::FrameSinkId& frame_sink_id,
uint32_t parent_id) {
- viz::LocalSurfaceId local_surface_id(
- parent_id, base::UnguessableToken::Deserialize(0, 1u));
+ viz::LocalSurfaceId local_surface_id(parent_id,
+ base::UnguessableToken::Create());
// Ensure that a CompositorFrameSinkSupport exists for this frame sink.
auto& support = supports_[frame_sink_id];
if (!support) {
@@ -263,7 +263,8 @@ TEST_F(VizDevToolsTest, FrameSinkHierarchyUnregistered) {
DOM::Node* parent_node = FindFrameSinkNode(kFrameSink1, root());
DOM::Node* child_node = FindFrameSinkNode(kFrameSink2, parent_node);
ExpectChildNodeRemoved(parent_node->getNodeId(), child_node->getNodeId());
- ExpectChildNodeInserted(dom_agent()->element_root()->node_id(), 0);
+ ExpectChildNodeInserted(dom_agent()->element_root()->node_id(),
+ parent_node->getNodeId());
}
// Verify that the initial tree at viz devtools startup is correct, including an
@@ -286,6 +287,25 @@ TEST_F(VizDevToolsTest, InitialFrameSinkHierarchy) {
EXPECT_EQ(node3, root()->getChildren(nullptr)->get(1));
}
+// Verify that FrameSinkElements are inserted into the tree according to the
+// ordering of their FrameSinkIds.
+TEST_F(VizDevToolsTest, FrameSinkElementOrdering) {
+ RegisterFrameSinkId(kFrameSink2);
+
+ BuildDocument();
+
+ DOM::Node* frame_sink_node = FindFrameSinkNode(kFrameSink2, root());
+
+ // Create a frame sink element before the existing frame sink.
+ RegisterFrameSinkId(kFrameSink1);
+ ExpectChildNodeInserted(dom_agent()->element_root()->node_id(), 0);
+
+ // Create a frame sink element after the existing frame sink.
+ RegisterFrameSinkId(kFrameSink3);
+ ExpectChildNodeInserted(dom_agent()->element_root()->node_id(),
+ frame_sink_node->getNodeId());
+}
+
// Verify that creating a surface and adding a reference to the root surface
// creates a node attached to the root surface node.
TEST_F(VizDevToolsTest, SurfaceCreated) {
@@ -347,7 +367,8 @@ TEST_F(VizDevToolsTest, SurfaceReferenceRemoved) {
DOM::Node* parent_node = FindSurfaceNode(id1, root());
DOM::Node* child_node = FindSurfaceNode(id2, parent_node);
ExpectChildNodeRemoved(parent_node->getNodeId(), child_node->getNodeId());
- ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0);
+ ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(),
+ parent_node->getNodeId());
}
// Verify that a hierarchy of surfaces can be destroyed and cleaned up properly.
@@ -431,9 +452,10 @@ TEST_F(VizDevToolsTest, MultipleSurfaceReferences) {
frontend_channel()->SetAllowNotifications(true);
// Remove the reference to the second parent. This should move the child node
- // to the root surface.
+ // to the root surface, after the second parent.
RemoveSurfaceReference(parent_id_2, child_id);
- ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0);
+ ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(),
+ parent_node_2->getNodeId());
ExpectChildNodeRemoved(parent_node_2->getNodeId(), child_node->getNodeId());
}
@@ -465,4 +487,48 @@ TEST_F(VizDevToolsTest, SurfaceReferenceAddedBeforeChildActivation) {
ExpectChildNodeInserted(parent_node->getNodeId(), 0);
}
+// Verify that SurfaceElements are inserted into the tree according to the
+// ordering of their SurfaceIds.
+TEST_F(VizDevToolsTest, SurfaceElementOrdering) {
+ viz::SurfaceId id2 = CreateFrameSinkAndSurface(kFrameSink2, 1);
+ AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id2);
+
+ BuildDocument();
+
+ DOM::Node* surface_node = FindSurfaceNode(id2, root());
+
+ // Create a surface element before the existing surface.
+ viz::SurfaceId id1 = CreateFrameSinkAndSurface(kFrameSink1, 1);
+ AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id1);
+ ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(), 0);
+
+ // Create a surface element after the existing surface.
+ viz::SurfaceId id3 = CreateFrameSinkAndSurface(kFrameSink3, 1);
+ AddSurfaceReference(surface_manager()->GetRootSurfaceId(), id3);
+ ExpectChildNodeInserted(dom_agent()->GetRootSurfaceElement()->node_id(),
+ surface_node->getNodeId());
+}
+
+// Verify that FrameSinkElements are placed before the root SurfaceElement.
+TEST_F(VizDevToolsTest, FrameSinkAndSurfaceElementOrdering) {
+ RegisterFrameSinkId(kFrameSink1);
+
+ BuildDocument();
+
+ DOM::Node* frame_sink_node = FindFrameSinkNode(kFrameSink1, root());
+ DOM::Node* root_surface_node =
+ FindSurfaceNode(surface_manager()->GetRootSurfaceId(), root());
+
+ // The frame sink should be before the root surface node.
+ EXPECT_EQ(frame_sink_node, root()->getChildren(nullptr)->get(0));
+ EXPECT_EQ(root_surface_node, root()->getChildren(nullptr)->get(1));
+
+ // Create a frame sink element with a large id, it should still be inserted
+ // before the root surface element.
+ viz::FrameSinkId big_frame_sink(50, 50);
+ RegisterFrameSinkId(big_frame_sink);
+ ExpectChildNodeInserted(dom_agent()->element_root()->node_id(),
+ frame_sink_node->getNodeId());
+}
+
} // namespace ui_devtools
diff --git a/chromium/components/ui_devtools/viz/viz_element.cc b/chromium/components/ui_devtools/viz/viz_element.cc
new file mode 100644
index 00000000000..5d830c6bf49
--- /dev/null
+++ b/chromium/components/ui_devtools/viz/viz_element.cc
@@ -0,0 +1,66 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ui_devtools/viz/viz_element.h"
+
+#include <algorithm>
+
+#include "components/ui_devtools/ui_element_delegate.h"
+#include "components/ui_devtools/viz/frame_sink_element.h"
+#include "components/ui_devtools/viz/surface_element.h"
+
+namespace ui_devtools {
+
+namespace {
+
+bool IsVizElement(const UIElement* element) {
+ return element->type() == UIElementType::FRAMESINK ||
+ element->type() == UIElementType::SURFACE;
+}
+
+bool CompareVizElements(const UIElement* a, const UIElement* b) {
+ if (a->type() == UIElementType::FRAMESINK) {
+ if (b->type() == UIElementType::SURFACE)
+ return true;
+ // From() checks that |b| is a FrameSinkElement.
+ return FrameSinkElement::From(a) < FrameSinkElement::From(b);
+ } else {
+ if (b->type() == UIElementType::FRAMESINK)
+ return false;
+ // From() checks that |a| and |b| are SurfaceElements.
+ return SurfaceElement::From(a) < SurfaceElement::From(b);
+ }
+}
+
+} // namespace
+
+VizElement::VizElement(const UIElementType type,
+ UIElementDelegate* delegate,
+ UIElement* parent)
+ : UIElement(type, delegate, parent) {}
+
+VizElement::~VizElement() {}
+
+void VizElement::AddToParentSorted(UIElement* parent, bool notify_delegate) {
+ parent->AddOrderedChild(this, &CompareVizElements, notify_delegate);
+}
+
+void VizElement::Reparent(UIElement* new_parent) {
+ if (parent() == new_parent)
+ return;
+ // Become a child of |new_parent| without calling OnUIElementRemoved or
+ // OnUIElementAdded on |delegate_|. Instead, call OnUIElementReordered, which
+ // destroys and rebuilds the DOM node in the new location.
+ parent()->RemoveChild(this, false);
+ AddToParentSorted(new_parent, false);
+ delegate()->OnUIElementReordered(new_parent, this);
+ set_parent(new_parent);
+}
+
+VizElement* VizElement::AsVizElement(UIElement* element) {
+ DCHECK(IsVizElement(element));
+ return static_cast<VizElement*>(element);
+}
+
+} // namespace ui_devtools
diff --git a/chromium/components/ui_devtools/viz/viz_element.h b/chromium/components/ui_devtools/viz/viz_element.h
new file mode 100644
index 00000000000..19e228f188a
--- /dev/null
+++ b/chromium/components/ui_devtools/viz/viz_element.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UI_DEVTOOLS_VIZ_VIZ_ELEMENT_H_
+#define COMPONENTS_UI_DEVTOOLS_VIZ_VIZ_ELEMENT_H_
+
+#include "base/macros.h"
+#include "components/ui_devtools/ui_element.h"
+
+namespace ui_devtools {
+
+class VizElement : public UIElement {
+ public:
+ ~VizElement() override;
+
+ // Insert this into the list of |parent|'s children, comparing to siblings to
+ // find an appropriate insert point. |parent| isn't necessarily a VizElement,
+ // but each of its children should be so that they can be compared.
+ void AddToParentSorted(UIElement* parent, bool notify_delegate = true);
+
+ // Move to become a child of |new_parent|. The DOM node for this element is
+ // destroyed and recreated in the new location.
+ void Reparent(UIElement* new_parent);
+
+ static VizElement* AsVizElement(UIElement* element);
+
+ protected:
+ VizElement(const UIElementType type,
+ UIElementDelegate* delegate,
+ UIElement* parent);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VizElement);
+};
+
+} // namespace ui_devtools
+
+#endif // COMPONENTS_UI_DEVTOOLS_VIZ_FRAME_SINK_ELEMENT_H_
diff --git a/chromium/components/ukm/content/DEPS b/chromium/components/ukm/content/DEPS
index 8ec5f07c52d..0d9254af5de 100644
--- a/chromium/components/ukm/content/DEPS
+++ b/chromium/components/ukm/content/DEPS
@@ -4,5 +4,5 @@ include_rules = [
"+content/public/common",
"+content/public/test",
"+content/shell",
- "+third_party/blink/public/platform/ukm.mojom.h",
+ "+third_party/blink/public/mojom/ukm/ukm.mojom.h",
]
diff --git a/chromium/components/ukm/content/source_url_recorder.cc b/chromium/components/ukm/content/source_url_recorder.cc
index 0ffa9776d49..106f0b67f6b 100644
--- a/chromium/components/ukm/content/source_url_recorder.cc
+++ b/chromium/components/ukm/content/source_url_recorder.cc
@@ -8,6 +8,7 @@
#include "base/containers/flat_map.h"
#include "base/macros.h"
+#include "base/metrics/field_trial_params.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_binding_set.h"
@@ -15,12 +16,28 @@
#include "content/public/browser/web_contents_user_data.h"
#include "services/metrics/public/cpp/delegating_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
-#include "third_party/blink/public/platform/ukm.mojom.h"
+#include "third_party/blink/public/mojom/ukm/ukm.mojom.h"
#include "url/gurl.h"
namespace ukm {
+namespace {
+
+// -1 indicates no max number of same document sources per full source.
+int kUnlimitedSameDocumentSourcesPerFullSource = -1;
+
+// Returns the maximum number of same document sources that are allowed to be
+// recorded for a full source.
+int GetMaxSameDocumentSourcesPerFullSource() {
+ return base::GetFieldTrialParamByFeatureAsInt(
+ kUkmFeature, "MaxSameDocumentSourcesPerFullSource",
+ kUnlimitedSameDocumentSourcesPerFullSource);
+}
+
+} // namespace
+
namespace internal {
int64_t CreateUniqueTabId() {
@@ -71,6 +88,12 @@ class SourceUrlRecorderWebContentsObserver
// Record any pending DocumentCreated events to UKM.
void MaybeFlushPendingEvents();
+ void HandleSameDocumentNavigation(
+ content::NavigationHandle* navigation_handle);
+ void HandleDifferentDocumentNavigation(
+ content::NavigationHandle* navigation_handle,
+ const GURL& initial_url);
+
void MaybeRecordUrl(content::NavigationHandle* navigation_handle,
const GURL& initial_url);
@@ -97,10 +120,13 @@ class SourceUrlRecorderWebContentsObserver
};
std::vector<PendingEvent> pending_document_created_events_;
- SourceId last_committed_source_id_;
+ // The source id of the last committed full navigation (where a full
+ // navigation is a non-same-document navigation).
+ SourceId last_committed_full_navigation_source_id_;
- // The source id before |last_committed_source_id_|.
- SourceId previous_committed_source_id_;
+ // The source id of the last committed navigation, either full navigation or
+ // same document.
+ SourceId last_committed_full_navigation_or_same_document_source_id_;
// The source id of the last committed source in the tab that opened this tab.
// Will be set to kInvalidSourceId after the first navigation in this tab is
@@ -109,6 +135,8 @@ class SourceUrlRecorderWebContentsObserver
const int64_t tab_id_;
+ int num_same_document_sources_for_full_navigation_source_;
+
WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(SourceUrlRecorderWebContentsObserver);
@@ -120,10 +148,12 @@ SourceUrlRecorderWebContentsObserver::SourceUrlRecorderWebContentsObserver(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
bindings_(web_contents, this),
- last_committed_source_id_(ukm::kInvalidSourceId),
- previous_committed_source_id_(ukm::kInvalidSourceId),
+ last_committed_full_navigation_source_id_(ukm::kInvalidSourceId),
+ last_committed_full_navigation_or_same_document_source_id_(
+ ukm::kInvalidSourceId),
opener_source_id_(ukm::kInvalidSourceId),
- tab_id_(CreateUniqueTabId()) {}
+ tab_id_(CreateUniqueTabId()),
+ num_same_document_sources_for_full_navigation_source_(0) {}
void SourceUrlRecorderWebContentsObserver::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
@@ -151,27 +181,68 @@ void SourceUrlRecorderWebContentsObserver::DidStartNavigation(
void SourceUrlRecorderWebContentsObserver::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
auto it = pending_navigations_.find(navigation_handle->GetNavigationId());
- if (it == pending_navigations_.end())
+ if (!navigation_handle->IsInMainFrame()) {
+ DCHECK(it == pending_navigations_.end());
return;
+ }
- DCHECK(navigation_handle->IsInMainFrame());
- DCHECK(!navigation_handle->IsSameDocument());
+ if (navigation_handle->IsSameDocument()) {
+ DCHECK(it == pending_navigations_.end());
+ HandleSameDocumentNavigation(navigation_handle);
+ return;
+ }
- if (navigation_handle->HasCommitted()) {
- previous_committed_source_id_ = last_committed_source_id_;
- last_committed_source_id_ = ukm::ConvertToSourceId(
- navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
+ if (it != pending_navigations_.end()) {
+ GURL initial_url = std::move(it->second);
+ pending_navigations_.erase(it);
+ HandleDifferentDocumentNavigation(navigation_handle, initial_url);
}
+}
- GURL initial_url = std::move(it->second);
- pending_navigations_.erase(it);
+void SourceUrlRecorderWebContentsObserver::HandleSameDocumentNavigation(
+ content::NavigationHandle* navigation_handle) {
+ if (!navigation_handle->HasCommitted())
+ return;
+ // Only record same document sources if we were also recording the associated
+ // full source.
+ if (last_committed_full_navigation_source_id_ == ukm::kInvalidSourceId) {
+ return;
+ }
+
+ const int max_same_document_sources_per_full_source =
+ GetMaxSameDocumentSourcesPerFullSource();
+
+ if (max_same_document_sources_per_full_source ==
+ kUnlimitedSameDocumentSourcesPerFullSource ||
+ num_same_document_sources_for_full_navigation_source_ <
+ max_same_document_sources_per_full_source) {
+ MaybeRecordUrl(navigation_handle, GURL::EmptyGURL());
+ }
+
+ last_committed_full_navigation_or_same_document_source_id_ =
+ ukm::ConvertToSourceId(navigation_handle->GetNavigationId(),
+ ukm::SourceIdType::NAVIGATION_ID);
+ ++num_same_document_sources_for_full_navigation_source_;
+}
+
+void SourceUrlRecorderWebContentsObserver::HandleDifferentDocumentNavigation(
+ content::NavigationHandle* navigation_handle,
+ const GURL& initial_url) {
// UKM doesn't want to record URLs for navigations that result in downloads.
if (navigation_handle->IsDownload())
return;
MaybeRecordUrl(navigation_handle, initial_url);
+ if (navigation_handle->HasCommitted()) {
+ last_committed_full_navigation_source_id_ = ukm::ConvertToSourceId(
+ navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
+ last_committed_full_navigation_or_same_document_source_id_ =
+ last_committed_full_navigation_source_id_;
+ num_same_document_sources_for_full_navigation_source_ = 0;
+ }
+
MaybeFlushPendingEvents();
// Reset the opener source id. Only the first source in a tab should have an
@@ -197,7 +268,7 @@ void SourceUrlRecorderWebContentsObserver::DidOpenRequestedURL(
ukm::SourceId SourceUrlRecorderWebContentsObserver::GetLastCommittedSourceId()
const {
- return last_committed_source_id_;
+ return last_committed_full_navigation_source_id_;
}
void SourceUrlRecorderWebContentsObserver::SetDocumentSourceId(
@@ -217,7 +288,7 @@ void SourceUrlRecorderWebContentsObserver::SetDocumentSourceId(
}
void SourceUrlRecorderWebContentsObserver::MaybeFlushPendingEvents() {
- if (!last_committed_source_id_)
+ if (!last_committed_full_navigation_source_id_)
return;
ukm::DelegatingUkmRecorder* ukm_recorder = ukm::DelegatingUkmRecorder::Get();
@@ -228,7 +299,7 @@ void SourceUrlRecorderWebContentsObserver::MaybeFlushPendingEvents() {
auto record = pending_document_created_events_.back();
ukm::builders::DocumentCreated(record.source_id)
- .SetNavigationSourceId(last_committed_source_id_)
+ .SetNavigationSourceId(last_committed_full_navigation_source_id_)
.SetIsMainFrame(record.is_main_frame)
.SetIsCrossOriginFrame(record.is_cross_origin_frame)
.Record(ukm_recorder);
@@ -241,7 +312,6 @@ void SourceUrlRecorderWebContentsObserver::MaybeRecordUrl(
content::NavigationHandle* navigation_handle,
const GURL& initial_url) {
DCHECK(navigation_handle->IsInMainFrame());
- DCHECK(!navigation_handle->IsSameDocument());
ukm::DelegatingUkmRecorder* ukm_recorder = ukm::DelegatingUkmRecorder::Get();
if (!ukm_recorder)
@@ -251,14 +321,27 @@ void SourceUrlRecorderWebContentsObserver::MaybeRecordUrl(
const GURL& final_url = navigation_handle->GetURL();
// TODO(crbug.com/869123): This check isn't quite correct, as self redirecting
// is possible. This may also be changed to include the entire redirect chain.
- if (final_url != initial_url)
+ // Additionally, since same-document navigations don't have initial URLs,
+ // ignore empty initial URLs.
+ if (!initial_url.is_empty() && final_url != initial_url)
navigation_data.urls = {initial_url};
navigation_data.urls.push_back(final_url);
- // Careful note: the current navigation may have failed.
- navigation_data.previous_source_id = navigation_handle->HasCommitted()
- ? previous_committed_source_id_
- : last_committed_source_id_;
+ navigation_data.is_same_document_navigation =
+ navigation_handle->IsSameDocument();
+ navigation_data.previous_source_id =
+ last_committed_full_navigation_source_id_;
+
+ // If the last_committed_full_navigation_or_same_document_source_id_ isn't
+ // equal to the last_committed_full_navigation_source_id_, it indicates the
+ // previous source was a same document navigation.
+ const bool previous_source_was_same_document_navigation =
+ last_committed_full_navigation_or_same_document_source_id_ !=
+ last_committed_full_navigation_source_id_;
+ if (previous_source_was_same_document_navigation) {
+ navigation_data.previous_same_document_source_id =
+ last_committed_full_navigation_or_same_document_source_id_;
+ }
navigation_data.opener_source_id = opener_source_id_;
navigation_data.tab_id = tab_id_;
diff --git a/chromium/components/ukm/content/source_url_recorder_test.cc b/chromium/components/ukm/content/source_url_recorder_test.cc
index aaed5581760..3acc43a9457 100644
--- a/chromium/components/ukm/content/source_url_recorder_test.cc
+++ b/chromium/components/ukm/content/source_url_recorder_test.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/ukm/content/source_url_recorder.h"
+#include "base/test/scoped_feature_list.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/navigation_simulator.h"
@@ -10,6 +11,7 @@
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/metrics_proto/ukm/source.pb.h"
#include "url/gurl.h"
using content::NavigationSimulator;
@@ -81,7 +83,84 @@ TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUrlInSubframe) {
EXPECT_EQ(main_frame_url, GetAssociatedURLForWebContentsDocument());
}
-TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreSameDocumentNavigation) {
+TEST_F(SourceUrlRecorderWebContentsObserverTest, SameDocumentNavigation) {
+ GURL url1("https://www.example.com/");
+ GURL url2("https://www.example.com/2");
+ GURL same_document_url1("https://www.example.com/#samedocument");
+ GURL same_document_url2("https://www.example.com/#samedocument2");
+ NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), url1);
+ NavigationSimulator::CreateRendererInitiated(same_document_url1, main_rfh())
+ ->CommitSameDocument();
+ NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), url2);
+ NavigationSimulator::CreateRendererInitiated(same_document_url2, main_rfh())
+ ->CommitSameDocument();
+
+ EXPECT_EQ(same_document_url2, web_contents()->GetLastCommittedURL());
+
+ // Serialize each source so we can verify expectations below.
+ ukm::Source full_nav_source1, full_nav_source2, same_doc_source1,
+ same_doc_source2;
+ EXPECT_EQ(4ul, test_ukm_recorder_.GetSources().size());
+ for (auto& kv : test_ukm_recorder_.GetSources()) {
+ if (kv.second->url() == url1) {
+ kv.second->PopulateProto(&full_nav_source1);
+ } else if (kv.second->url() == url2) {
+ kv.second->PopulateProto(&full_nav_source2);
+ } else if (kv.second->url() == same_document_url1) {
+ kv.second->PopulateProto(&same_doc_source1);
+ } else if (kv.second->url() == same_document_url2) {
+ kv.second->PopulateProto(&same_doc_source2);
+ } else {
+ FAIL() << "Encountered unexpected source.";
+ }
+ }
+
+ // The first navigation was a non-same-document navigation to url1. As such,
+ // it shouldn't have any previous source ids.
+ EXPECT_EQ(url1, full_nav_source1.url());
+ EXPECT_TRUE(full_nav_source1.has_id());
+ EXPECT_FALSE(full_nav_source1.is_same_document_navigation());
+ EXPECT_FALSE(full_nav_source1.has_previous_source_id());
+ EXPECT_FALSE(full_nav_source1.has_previous_same_document_source_id());
+
+ // The second navigation was a same-document navigation to
+ // same_document_url1. It should have a previous_source_id that points to
+ // url1's source, but no previous_same_document_source_id.
+ EXPECT_EQ(same_document_url1, same_doc_source1.url());
+ EXPECT_TRUE(same_doc_source1.has_id());
+ EXPECT_TRUE(same_doc_source1.is_same_document_navigation());
+ EXPECT_EQ(full_nav_source1.id(), same_doc_source1.previous_source_id());
+ EXPECT_FALSE(same_doc_source1.has_previous_same_document_source_id());
+
+ // The third navigation was a non-same-document navigation to url2. It should
+ // have a previous_source_id pointing to the source for url1, and a
+ // previous_same_document_source_id pointing to the source for
+ // same_document_url1.
+ EXPECT_EQ(url2, full_nav_source2.url());
+ EXPECT_TRUE(full_nav_source2.has_id());
+ EXPECT_FALSE(full_nav_source2.is_same_document_navigation());
+ EXPECT_EQ(full_nav_source1.id(), full_nav_source2.previous_source_id());
+ EXPECT_EQ(same_doc_source1.id(),
+ full_nav_source2.previous_same_document_source_id());
+
+ // The fourth navigation was a same-document navigation to
+ // same_document_url2. It should have a previous_source_id pointing to the
+ // source for url2, and no previous_same_document_source_id.
+ EXPECT_EQ(same_document_url2, same_doc_source2.url());
+ EXPECT_TRUE(same_doc_source2.has_id());
+ EXPECT_TRUE(same_doc_source2.is_same_document_navigation());
+ EXPECT_EQ(full_nav_source2.id(), same_doc_source2.previous_source_id());
+ EXPECT_FALSE(same_doc_source2.has_previous_same_document_source_id());
+
+ EXPECT_EQ(url2, GetAssociatedURLForWebContentsDocument());
+}
+
+TEST_F(SourceUrlRecorderWebContentsObserverTest,
+ SameDocumentNavigationDisabled) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ ukm::kUkmFeature, {{"MaxSameDocumentSourcesPerFullSource", "0"}});
+
GURL url("https://www.example.com/");
GURL same_document_url("https://www.example.com/#samedocument");
NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), url);
@@ -92,9 +171,10 @@ TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreSameDocumentNavigation) {
const auto& sources = test_ukm_recorder_.GetSources();
EXPECT_EQ(1ul, sources.size());
- for (const auto& kv : sources) {
+ for (auto& kv : sources) {
EXPECT_EQ(url, kv.second->url());
EXPECT_EQ(1u, kv.second->urls().size());
+ EXPECT_FALSE(kv.second->navigation_data().is_same_document_navigation);
}
EXPECT_EQ(url, GetAssociatedURLForWebContentsDocument());
diff --git a/chromium/components/ukm/debug/PRESUBMIT.py b/chromium/components/ukm/debug/PRESUBMIT.py
index 2bc036d7df2..5b19bfe6ad7 100644
--- a/chromium/components/ukm/debug/PRESUBMIT.py
+++ b/chromium/components/ukm/debug/PRESUBMIT.py
@@ -4,11 +4,21 @@
def _CommonChecks(input_api, output_api):
- import web_dev_style.presubmit_support
- return (
+ 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.CheckStyleESLint(input_api, output_api) +
input_api.canned_checks.CheckPatchFormatted(
- input_api, output_api, check_js=True))
+ input_api, output_api, check_js=True))
+ finally:
+ sys.path = old_sys_path
+ return results
+
def CheckChangeOnUpload(input_api, output_api):
@@ -17,4 +27,3 @@ def CheckChangeOnUpload(input_api, output_api):
def CheckChangeOnCommit(input_api, output_api):
return _CommonChecks(input_api, output_api)
-
diff --git a/chromium/components/ukm/debug/ukm_debug_data_extractor.cc b/chromium/components/ukm/debug/ukm_debug_data_extractor.cc
index f26e9e4086d..f858bcdaaa4 100644
--- a/chromium/components/ukm/debug/ukm_debug_data_extractor.cc
+++ b/chromium/components/ukm/debug/ukm_debug_data_extractor.cc
@@ -13,6 +13,7 @@
#include "base/strings/stringprintf.h"
#include "services/metrics/public/cpp/ukm_decode.h"
#include "services/metrics/public/cpp/ukm_source.h"
+#include "services/metrics/public/mojom/ukm_interface.mojom.h"
#include "url/gurl.h"
namespace ukm {
diff --git a/chromium/components/ukm/ios/BUILD.gn b/chromium/components/ukm/ios/BUILD.gn
new file mode 100644
index 00000000000..a836ad661d2
--- /dev/null
+++ b/chromium/components/ukm/ios/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+assert(target_os == "ios")
+
+source_set("features") {
+ sources = [
+ "features.cc",
+ "features.h",
+ ]
+ deps = [
+ "//base",
+ ]
+}
diff --git a/chromium/components/ukm/ios/features.cc b/chromium/components/ukm/ios/features.cc
new file mode 100644
index 00000000000..ff2a1f03dca
--- /dev/null
+++ b/chromium/components/ukm/ios/features.cc
@@ -0,0 +1,8 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "components/ukm/ios/features.h"
+
+const base::Feature kUmaCellular{"UmaCellular",
+ base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromium/components/ukm/ios/features.h b/chromium/components/ukm/ios/features.h
new file mode 100644
index 00000000000..b18cd37008b
--- /dev/null
+++ b/chromium/components/ukm/ios/features.h
@@ -0,0 +1,13 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UKM_IOS_FEATURES_H_
+#define COMPONENTS_UKM_IOS_FEATURES_H_
+
+#include "base/feature_list.h"
+
+// Used to send UMA data over cellular.
+extern const base::Feature kUmaCellular;
+
+#endif // COMPONENTS_UKM_IOS_FEATURES_H_
diff --git a/chromium/components/ukm/observers/sync_disable_observer.cc b/chromium/components/ukm/observers/sync_disable_observer.cc
index 58ef844bde6..724d71c9b00 100644
--- a/chromium/components/ukm/observers/sync_disable_observer.cc
+++ b/chromium/components/ukm/observers/sync_disable_observer.cc
@@ -11,6 +11,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "components/sync/driver/sync_token_status.h"
+#include "components/sync/driver/sync_user_settings.h"
#include "components/sync/engine/connection_status.h"
#include "components/unified_consent/feature.h"
#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
@@ -113,7 +114,8 @@ SyncDisableObserver::SyncState SyncDisableObserver::GetSyncState(
status.connection_status == syncer::CONNECTION_OK;
state.passphrase_protected =
- state.initialized && sync_service->IsUsingSecondaryPassphrase();
+ state.initialized &&
+ sync_service->GetUserSettings()->IsUsingSecondaryPassphrase();
if (consent_helper) {
state.anonymized_data_collection_state =
consent_helper->IsEnabled() ? DataCollectionState::kEnabled
diff --git a/chromium/components/ukm/test_ukm_recorder.cc b/chromium/components/ukm/test_ukm_recorder.cc
index bfe3f1a916f..b5267ef0a46 100644
--- a/chromium/components/ukm/test_ukm_recorder.cc
+++ b/chromium/components/ukm/test_ukm_recorder.cc
@@ -42,8 +42,7 @@ TestUkmRecorder::TestUkmRecorder() {
DisableSamplingForTesting();
}
-TestUkmRecorder::~TestUkmRecorder() {
-};
+TestUkmRecorder::~TestUkmRecorder() {}
bool TestUkmRecorder::ShouldRestrictToWhitelistedSourceIds() const {
// In tests, we want to record all source ids (not just those that are
@@ -163,6 +162,6 @@ TestAutoSetUkmRecorder::TestAutoSetUkmRecorder() : self_ptr_factory_(this) {
TestAutoSetUkmRecorder::~TestAutoSetUkmRecorder() {
DelegatingUkmRecorder::Get()->RemoveDelegate(this);
-};
+}
} // namespace ukm
diff --git a/chromium/components/ukm/ukm_recorder_impl.cc b/chromium/components/ukm/ukm_recorder_impl.cc
index fe2b7319a9e..67479d70d89 100644
--- a/chromium/components/ukm/ukm_recorder_impl.cc
+++ b/chromium/components/ukm/ukm_recorder_impl.cc
@@ -21,6 +21,7 @@
#include "services/metrics/public/cpp/ukm_decode.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "services/metrics/public/mojom/ukm_interface.mojom.h"
#include "third_party/metrics_proto/ukm/entry.pb.h"
#include "third_party/metrics_proto/ukm/report.pb.h"
#include "third_party/metrics_proto/ukm/source.pb.h"
@@ -204,7 +205,7 @@ void UkmRecorderImpl::CreateFallbackSamplingTrial(
// Everybody (100%) should have a sampling configuration.
std::map<std::string, std::string> params = {
- {"_default_sampling", base::IntToString(default_sampling)}};
+ {"_default_sampling", base::NumberToString(default_sampling)}};
variations::AssociateVariationParams(trial->trial_name(), sampled_group,
params);
trial->AppendGroup(sampled_group, 100);
@@ -321,9 +322,8 @@ void UkmRecorderImpl::StoreRecordingsInReport(Report* report) {
serialized_source_type_counts[GetSourceIdType(kv.first)]++;
}
+
for (const auto& event_and_aggregate : recordings_.event_aggregations) {
- if (event_and_aggregate.second.metrics.empty())
- continue;
const EventAggregate& event_aggregate = event_and_aggregate.second;
Aggregate* proto_aggregate = report->add_aggregates();
proto_aggregate->set_source_id(0); // Across all sources.
@@ -664,11 +664,15 @@ void UkmRecorderImpl::LoadExperimentSamplingInfo() {
default_sampling_rate_ = 1;
}
+int UkmRecorderImpl::RandInt(int begin, int end) {
+ return base::RandInt(begin, end);
+}
+
bool UkmRecorderImpl::IsSampledIn(int sampling_rate) {
// A sampling rate of 0 is "never"; everything else is 1-in-N but skip
// the RandInt() call if N==1.
return sampling_rate > 0 &&
- (sampling_rate == 1 || base::RandInt(1, sampling_rate) == 1);
+ (sampling_rate == 1 || RandInt(1, sampling_rate) == 1);
}
void UkmRecorderImpl::StoreWhitelistedEntries() {
diff --git a/chromium/components/ukm/ukm_recorder_impl.h b/chromium/components/ukm/ukm_recorder_impl.h
index 1732626d02a..de336dd1d1b 100644
--- a/chromium/components/ukm/ukm_recorder_impl.h
+++ b/chromium/components/ukm/ukm_recorder_impl.h
@@ -18,7 +18,7 @@
#include "base/strings/string_piece.h"
#include "services/metrics/public/cpp/ukm_decode.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
-#include "services/metrics/public/mojom/ukm_interface.mojom.h"
+#include "services/metrics/public/mojom/ukm_interface.mojom-forward.h"
namespace metrics {
class UkmBrowserTestBase;
@@ -68,9 +68,11 @@ class UkmRecorderImpl : public UkmRecorder {
const IsWebstoreExtensionCallback& callback);
protected:
- // Calculates sampled in/out based on a given |rate|. This is virtual so
- // it can be overriden by tests.
- virtual bool IsSampledIn(int sampling_rate);
+ // Generates a random number. This is virtual so it can be overriden by tests.
+ virtual int RandInt(int begin, int end);
+
+ // Calculates sampled in/out based on a given |rate|.
+ bool IsSampledIn(int sampling_rate);
// Cache the list of whitelisted entries from the field trial parameter.
void StoreWhitelistedEntries();
diff --git a/chromium/components/ukm/ukm_recorder_impl_unittest.cc b/chromium/components/ukm/ukm_recorder_impl_unittest.cc
index 1314fe150a0..246741829ca 100644
--- a/chromium/components/ukm/ukm_recorder_impl_unittest.cc
+++ b/chromium/components/ukm/ukm_recorder_impl_unittest.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/metrics/ukm_source_id.h"
+#include "base/test/scoped_feature_list.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_entry_builder.h"
#include "services/metrics/public/cpp/ukm_source.h"
@@ -21,22 +22,27 @@ class TestUkmRecorderImpl : public UkmRecorderImpl {
TestUkmRecorderImpl() {}
~TestUkmRecorderImpl() override {}
- void set_sampled_in(bool sampled_in) { sampled_in_ = sampled_in; }
+ // Set the value returned by the "random number generator" used to control
+ // whether something gets sampled "in" (1) or "out" (anything else).
+ void set_rand_int(int rand_int) { rand_int_ = rand_int; }
- size_t sampled_callback_count() { return sampled_callback_count_; }
+ // Used to verify that random sampling is taking place.
+ size_t rand_callback_count() { return rand_callback_count_; }
protected:
// UkmRecorderImpl:
bool ShouldRestrictToWhitelistedSourceIds() const override { return false; }
bool ShouldRestrictToWhitelistedEntries() const override { return false; }
- bool IsSampledIn(int sampling_rate) override {
- ++sampled_callback_count_;
- return sampled_in_;
+
+ // Override the "random" number returned and count number of calls.
+ int RandInt(int begin, int end) override {
+ ++rand_callback_count_;
+ return rand_int_;
}
private:
- bool sampled_in_ = true;
- size_t sampled_callback_count_ = 0;
+ int rand_int_ = 0;
+ size_t rand_callback_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(TestUkmRecorderImpl);
};
@@ -52,9 +58,9 @@ class UkmRecorderImplTest : public testing::Test {
UkmRecorderImpl& impl() { return impl_; }
- void set_sampled_in(bool sampled_in) { impl_.set_sampled_in(sampled_in); }
+ void set_rand_int(int rand_int) { impl_.set_rand_int(rand_int); }
- size_t sampled_callback_count() { return impl_.sampled_callback_count(); }
+ size_t rand_callback_count() { return impl_.rand_callback_count(); }
size_t source_sampling_count() { return impl_.source_event_sampling_.size(); }
@@ -76,26 +82,29 @@ class UkmRecorderImplTest : public testing::Test {
};
TEST_F(UkmRecorderImplTest, PageSamplingCondition) {
- EXPECT_FALSE(impl().UkmRecorderImpl::IsSampledIn(0));
- EXPECT_TRUE(impl().UkmRecorderImpl::IsSampledIn(1));
-
- // Actual sampling is "random" so there's no single operation to test.
- // Instead, sample many times and expect that some, but less than 1/2,
- // will be sampled-in. This is sufficient to ensure that the condition
- // is not "dead" (always false) and has not been mistakenly reversed...
- // without the test being flaky.
- const int kRandomCheckCount = 1000;
- int sampled_in_count = 0;
- for (int i = 0; i < kRandomCheckCount; ++i) {
- // Sample 1-in-10...
- if (impl().UkmRecorderImpl::IsSampledIn(10))
- sampled_in_count += 1;
+ EXPECT_FALSE(impl().IsSampledIn(0));
+ EXPECT_TRUE(impl().IsSampledIn(1));
+
+ const int kSamplingRate = 10;
+ for (int i = 1; i <= kSamplingRate; ++i) {
+ set_rand_int(i);
+ EXPECT_EQ(i == 1, impl().IsSampledIn(kSamplingRate));
}
- EXPECT_LT(0, sampled_in_count);
- EXPECT_GT(kRandomCheckCount / 2, sampled_in_count);
}
TEST_F(UkmRecorderImplTest, PageSampling) {
+ const base::Feature kUkmSamplingRateFeature{
+ "UkmSamplingRate", base::FEATURE_DISABLED_BY_DEFAULT};
+ std::map<std::string, std::string> sampling_params;
+
+ // A default sampling of "2" will ensure that RandInt() gets called for
+ // every "sampled in" check.
+ sampling_params["_default_sampling"] = "2";
+
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ kUkmSamplingRateFeature, sampling_params);
+
SourceId page1_source =
ConvertToSourceId(101, base::UkmSourceId::Type::NAVIGATION_ID);
UkmSource::NavigationData page1_nav;
@@ -106,19 +115,19 @@ TEST_F(UkmRecorderImplTest, PageSampling) {
AddEntry(builders::PageLoad(page1_source)
.SetDocumentTiming_NavigationToLoadEventFired(1000)
.TakeEntry());
- EXPECT_EQ(1U, sampled_callback_count());
+ EXPECT_EQ(1U, rand_callback_count());
// Second event will use what was already determined.
AddEntry(builders::PageLoad(page1_source)
.SetDocumentTiming_NavigationToLoadEventFired(2000)
.TakeEntry());
- EXPECT_EQ(1U, sampled_callback_count());
+ EXPECT_EQ(1U, rand_callback_count());
// Different event will again do the callback.
AddEntry(builders::Memory_Experimental(page1_source)
.SetCommandBuffer(3000)
.TakeEntry());
- EXPECT_EQ(2U, sampled_callback_count());
+ EXPECT_EQ(2U, rand_callback_count());
SourceId page2_source =
ConvertToSourceId(102, base::UkmSourceId::Type::NAVIGATION_ID);
@@ -130,7 +139,7 @@ TEST_F(UkmRecorderImplTest, PageSampling) {
AddEntry(builders::PageLoad(page2_source)
.SetDocumentTiming_NavigationToLoadEventFired(1000)
.TakeEntry());
- EXPECT_EQ(3U, sampled_callback_count());
+ EXPECT_EQ(3U, rand_callback_count());
// First report won't clear this information.
EXPECT_EQ(2U, source_sampling_count());
diff --git a/chromium/components/ukm/ukm_reporting_service.cc b/chromium/components/ukm/ukm_reporting_service.cc
index a74c6ac9348..e2fe21d41d3 100644
--- a/chromium/components/ukm/ukm_reporting_service.cc
+++ b/chromium/components/ukm/ukm_reporting_service.cc
@@ -40,13 +40,13 @@ constexpr int kMinPersistedBytes = 300000;
// limit is exceeded.
constexpr size_t kMaxLogRetransmitSize = 100 * 1024;
-std::string GetServerUrl() {
+GURL GetServerUrl() {
constexpr char kDefaultServerUrl[] = "https://clients4.google.com/ukm";
std::string server_url =
base::GetFieldTrialParamValueByFeature(kUkmFeature, "ServerUrl");
if (!server_url.empty())
- return server_url;
- return kDefaultServerUrl;
+ return GURL(server_url);
+ return GURL(kDefaultServerUrl);
}
} // namespace
@@ -75,12 +75,12 @@ metrics::LogStore* UkmReportingService::log_store() {
return &persisted_logs_;
}
-std::string UkmReportingService::GetUploadUrl() const {
+GURL UkmReportingService::GetUploadUrl() const {
return GetServerUrl();
}
-std::string UkmReportingService::GetInsecureUploadUrl() const {
- return "";
+GURL UkmReportingService::GetInsecureUploadUrl() const {
+ return GURL();
}
base::StringPiece UkmReportingService::upload_mime_type() const {
diff --git a/chromium/components/ukm/ukm_reporting_service.h b/chromium/components/ukm/ukm_reporting_service.h
index a805395148e..07ffc6a7162 100644
--- a/chromium/components/ukm/ukm_reporting_service.h
+++ b/chromium/components/ukm/ukm_reporting_service.h
@@ -47,9 +47,9 @@ class UkmReportingService : public metrics::ReportingService {
private:
// metrics:ReportingService:
metrics::LogStore* log_store() override;
- std::string GetUploadUrl() const override;
+ GURL GetUploadUrl() const override;
// Returns an empty string since retrying over HTTP is not enabled for UKM
- std::string GetInsecureUploadUrl() const override;
+ GURL GetInsecureUploadUrl() const override;
base::StringPiece upload_mime_type() const override;
metrics::MetricsLogUploader::MetricServiceType service_type() const override;
void LogCellularConstraint(bool upload_canceled) override;
diff --git a/chromium/components/ukm/ukm_service.h b/chromium/components/ukm/ukm_service.h
index ba8fe13a22e..d28f540971b 100644
--- a/chromium/components/ukm/ukm_service.h
+++ b/chromium/components/ukm/ukm_service.h
@@ -9,6 +9,7 @@
#include <memory>
#include <vector>
+#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
@@ -21,6 +22,7 @@
class PrefRegistrySimple;
class PrefService;
+FORWARD_DECLARE_TEST(ChromeMetricsServiceClientTest, TestRegisterUKMProviders);
namespace metrics {
class MetricsServiceClient;
@@ -80,7 +82,7 @@ class UkmService : public UkmRecorderImpl {
// Registers the specified |provider| to provide additional metrics into the
// UKM log. Should be called during MetricsService initialization only.
- void RegisterMetricsProvider(
+ virtual void RegisterMetricsProvider(
std::unique_ptr<metrics::MetricsProvider> provider);
// Registers the names of all of the preferences used by UkmService in
@@ -94,7 +96,8 @@ class UkmService : public UkmRecorderImpl {
friend ::metrics::UkmEGTestHelper;
friend ::ukm::debug::UkmDebugDataExtractor;
friend ::ukm::UkmUtilsForTest;
-
+ FRIEND_TEST_ALL_PREFIXES(::ChromeMetricsServiceClientTest,
+ TestRegisterUKMProviders);
// Starts metrics client initialization.
void StartInitTask();
diff --git a/chromium/components/unified_consent/BUILD.gn b/chromium/components/unified_consent/BUILD.gn
index 36fd403b412..42104af51dc 100644
--- a/chromium/components/unified_consent/BUILD.gn
+++ b/chromium/components/unified_consent/BUILD.gn
@@ -12,8 +12,6 @@ static_library("unified_consent") {
"unified_consent_metrics.h",
"unified_consent_service.cc",
"unified_consent_service.h",
- "unified_consent_service_client.cc",
- "unified_consent_service_client.h",
"url_keyed_data_collection_consent_helper.cc",
"url_keyed_data_collection_consent_helper.h",
]
@@ -21,10 +19,10 @@ static_library("unified_consent") {
"//base",
"//components/autofill/core/common",
"//components/browser_sync",
- "//components/contextual_search/core:browser",
"//components/pref_registry",
"//components/signin/core/browser",
"//components/sync",
+ "//components/sync_preferences",
"//services/identity/public/cpp",
]
}
@@ -58,8 +56,6 @@ source_set("unit_tests") {
":test_support",
":unified_consent",
"//base/test:test_support",
- "//components/autofill/core/common",
- "//components/contextual_search/core:browser",
"//components/sync",
"//components/sync:test_support_driver",
"//components/sync_preferences:test_support",
diff --git a/chromium/components/unified_consent/pref_names.cc b/chromium/components/unified_consent/pref_names.cc
index e2420921dc9..1f74743547b 100644
--- a/chromium/components/unified_consent/pref_names.cc
+++ b/chromium/components/unified_consent/pref_names.cc
@@ -7,16 +7,7 @@
namespace unified_consent {
namespace prefs {
-// Boolean indicating whether all unified consent services were ever enabled
-// because the user opted into unified consent. This pref is used during
-// rollback to disable off-by-default services.
-const char kAllUnifiedConsentServicesWereEnabled[] =
- "unified_consent.all_services_were_enabled";
-
-// Integer indicating the migration state of unified consent, defined in
-// unified_consent::MigrationState.
const char kUnifiedConsentMigrationState[] = "unified_consent.migration_state";
-
const char kUrlKeyedAnonymizedDataCollectionEnabled[] =
"url_keyed_anonymized_data_collection.enabled";
diff --git a/chromium/components/unified_consent/pref_names.h b/chromium/components/unified_consent/pref_names.h
index 534f9d14ba0..522095809d6 100644
--- a/chromium/components/unified_consent/pref_names.h
+++ b/chromium/components/unified_consent/pref_names.h
@@ -8,8 +8,12 @@
namespace unified_consent {
namespace prefs {
-extern const char kAllUnifiedConsentServicesWereEnabled[];
+// Integer indicating the migration state of unified consent, defined in
+// unified_consent::MigrationState.
extern const char kUnifiedConsentMigrationState[];
+
+// Boolean indicating whether anonymized URL-keyed data data collection is
+// enabled.
extern const char kUrlKeyedAnonymizedDataCollectionEnabled[];
} // namespace prefs
diff --git a/chromium/components/unified_consent/unified_consent_metrics.cc b/chromium/components/unified_consent/unified_consent_metrics.cc
index 7bc53b29a4b..0a4c0e064e6 100644
--- a/chromium/components/unified_consent/unified_consent_metrics.cc
+++ b/chromium/components/unified_consent/unified_consent_metrics.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
#include "components/sync/base/model_type.h"
@@ -14,12 +15,29 @@
#include "components/unified_consent/pref_names.h"
namespace unified_consent {
-
namespace metrics {
namespace {
-typedef std::pair<SyncDataType, syncer::ModelType> DT;
+// Sync data types that can be customized in settings.
+// Used in histograms. Do not change existing values, append new values at the
+// end.
+enum class SyncDataType {
+ kNone = 0,
+ kApps = 1,
+ kBookmarks = 2,
+ kExtensions = 3,
+ kHistory = 4,
+ kSettings = 5,
+ kThemes = 6,
+ kTabs = 7,
+ kPasswords = 8,
+ kAutofill = 9,
+ kPayments = 10,
+ kSync = 11,
+
+ kMaxValue = kSync
+};
// Records a sample in the SyncAndGoogleServicesSettings histogram. Wrapped in a
// function to avoid code size issues caused by histogram macros.
@@ -40,22 +58,6 @@ bool RecordSettingsHistogramFromPref(const char* pref_name,
return true;
}
-// Checks if a service is enabled and if so, records a sample in the
-// SyncAndGoogleServicesSettings histogram. Returns true if a sample was
-// recorded.
-bool RecordSettingsHistogramFromService(
- UnifiedConsentServiceClient* client,
- UnifiedConsentServiceClient::Service service,
- SettingsHistogramValue value) {
- if (client->GetServiceState(service) !=
- UnifiedConsentServiceClient::ServiceState::kEnabled) {
- return false;
- }
-
- RecordSettingsHistogramSample(value);
- return true;
-}
-
void RecordSyncDataTypeSample(SyncDataType data_type) {
UMA_HISTOGRAM_ENUMERATION(
"UnifiedConsent.SyncAndGoogleServicesSettings.AfterAdvancedOptIn."
@@ -63,43 +65,33 @@ void RecordSyncDataTypeSample(SyncDataType data_type) {
data_type);
}
-} // namespace
-
-void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client,
- PrefService* pref_service) {
- bool metric_recorded = false;
-
- metric_recorded |= RecordSettingsHistogramFromPref(
- prefs::kAllUnifiedConsentServicesWereEnabled, pref_service,
- metrics::SettingsHistogramValue::kAllServicesWereEnabled);
- metric_recorded |= RecordSettingsHistogramFromPref(
- prefs::kUrlKeyedAnonymizedDataCollectionEnabled, pref_service,
- metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection);
- metric_recorded |= RecordSettingsHistogramFromService(
- service_client,
- UnifiedConsentServiceClient::Service::kSafeBrowsingExtendedReporting,
- metrics::SettingsHistogramValue::kSafeBrowsingExtendedReporting);
- metric_recorded |= RecordSettingsHistogramFromService(
- service_client, UnifiedConsentServiceClient::Service::kSpellCheck,
- metrics::SettingsHistogramValue::kSpellCheck);
-
- if (!metric_recorded)
- RecordSettingsHistogramSample(metrics::SettingsHistogramValue::kNone);
-}
+// Checks states of sync data types and records corresponding histogram.
+// Returns true if a sample was recorded.
+bool RecordSyncSetupDataTypesImpl(syncer::SyncUserSettings* sync_settings,
+ PrefService* pref_service) {
+#if defined(OS_ANDROID)
+ if (!sync_settings->IsSyncRequested()) {
+ RecordSyncDataTypeSample(SyncDataType::kSync);
+ return true; // Don't record states of data types if sync is disabled.
+ }
+#endif
-void RecordSyncSetupDataTypesHistrogam(syncer::SyncUserSettings* sync_settings,
- PrefService* pref_service) {
bool metric_recorded = false;
- for (DT data_type : {DT(SyncDataType::kApps, syncer::APPS),
- DT(SyncDataType::kBookmarks, syncer::BOOKMARKS),
- DT(SyncDataType::kExtensions, syncer::EXTENSIONS),
- DT(SyncDataType::kHistory, syncer::TYPED_URLS),
- DT(SyncDataType::kSettings, syncer::PREFERENCES),
- DT(SyncDataType::kThemes, syncer::THEMES),
- DT(SyncDataType::kTabs, syncer::PROXY_TABS),
- DT(SyncDataType::kPasswords, syncer::PASSWORDS),
- DT(SyncDataType::kAutofill, syncer::AUTOFILL)}) {
+ std::vector<std::pair<SyncDataType, syncer::ModelType>> sync_types;
+ sync_types.emplace_back(SyncDataType::kBookmarks, syncer::BOOKMARKS);
+ sync_types.emplace_back(SyncDataType::kHistory, syncer::TYPED_URLS);
+ sync_types.emplace_back(SyncDataType::kSettings, syncer::PREFERENCES);
+ sync_types.emplace_back(SyncDataType::kTabs, syncer::PROXY_TABS);
+ sync_types.emplace_back(SyncDataType::kPasswords, syncer::PASSWORDS);
+ sync_types.emplace_back(SyncDataType::kAutofill, syncer::AUTOFILL);
+#if !defined(OS_ANDROID)
+ sync_types.emplace_back(SyncDataType::kApps, syncer::APPS);
+ sync_types.emplace_back(SyncDataType::kExtensions, syncer::EXTENSIONS);
+ sync_types.emplace_back(SyncDataType::kThemes, syncer::THEMES);
+#endif
+
+ for (const auto& data_type : sync_types) {
if (!sync_settings->GetChosenDataTypes().Has(data_type.second)) {
RecordSyncDataTypeSample(data_type.first);
metric_recorded = true;
@@ -110,11 +102,24 @@ void RecordSyncSetupDataTypesHistrogam(syncer::SyncUserSettings* sync_settings,
RecordSyncDataTypeSample(SyncDataType::kPayments);
metric_recorded = true;
}
+ return metric_recorded;
+}
+
+} // namespace
+void RecordSettingsHistogram(PrefService* pref_service) {
+ bool metric_recorded = RecordSettingsHistogramFromPref(
+ prefs::kUrlKeyedAnonymizedDataCollectionEnabled, pref_service,
+ metrics::SettingsHistogramValue::kUrlKeyedAnonymizedDataCollection);
if (!metric_recorded)
+ RecordSettingsHistogramSample(metrics::SettingsHistogramValue::kNone);
+}
+
+void RecordSyncSetupDataTypesHistrogam(syncer::SyncUserSettings* sync_settings,
+ PrefService* pref_service) {
+ if (!RecordSyncSetupDataTypesImpl(sync_settings, pref_service))
RecordSyncDataTypeSample(SyncDataType::kNone);
}
} // namespace metrics
-
} // namespace unified_consent
diff --git a/chromium/components/unified_consent/unified_consent_metrics.h b/chromium/components/unified_consent/unified_consent_metrics.h
index 9b16c624ed7..1431cd1ef55 100644
--- a/chromium/components/unified_consent/unified_consent_metrics.h
+++ b/chromium/components/unified_consent/unified_consent_metrics.h
@@ -5,14 +5,13 @@
#ifndef COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_
#define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_
-#include "components/unified_consent/unified_consent_service_client.h"
+class PrefService;
namespace syncer {
class SyncUserSettings;
}
namespace unified_consent {
-
namespace metrics {
// Google services that can be toggled in user settings.
@@ -30,29 +29,9 @@ enum class SettingsHistogramValue {
kMaxValue = kAllServicesWereEnabled
};
-// Sync data types that can be customized in settings.
-// Used in histograms. Do not change existing values, append new values at the
-// end.
-enum class SyncDataType {
- kNone = 0,
- kApps = 1,
- kBookmarks = 2,
- kExtensions = 3,
- kHistory = 4,
- kSettings = 5,
- kThemes = 6,
- kTabs = 7,
- kPasswords = 8,
- kAutofill = 9,
- kPayments = 10,
-
- kMaxValue = kPayments
-};
-
// Records settings entries in the SyncAndGoogleServicesSettings.
// kNone is recorded when none of the settings is enabled.
-void RecordSettingsHistogram(UnifiedConsentServiceClient* service_client,
- PrefService* pref_service);
+void RecordSettingsHistogram(PrefService* pref_service);
// Records the sync data types that were turned off during the advanced sync
// opt-in flow. When none of the data types were turned off, kNone is recorded.
@@ -60,7 +39,6 @@ void RecordSyncSetupDataTypesHistrogam(syncer::SyncUserSettings* sync_settings,
PrefService* pref_service);
} // namespace metrics
-
} // namespace unified_consent
#endif // COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_METRICS_H_
diff --git a/chromium/components/unified_consent/unified_consent_service.cc b/chromium/components/unified_consent/unified_consent_service.cc
index 1ccfff8c042..a4df21707d4 100644
--- a/chromium/components/unified_consent/unified_consent_service.cc
+++ b/chromium/components/unified_consent/unified_consent_service.cc
@@ -9,27 +9,25 @@
#include "base/scoped_observer.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
-#include "components/autofill/core/common/autofill_prefs.h"
#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/prefs/pref_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_user_settings.h"
+#include "components/sync_preferences/pref_service_syncable.h"
#include "components/unified_consent/feature.h"
#include "components/unified_consent/pref_names.h"
namespace unified_consent {
UnifiedConsentService::UnifiedConsentService(
- std::unique_ptr<UnifiedConsentServiceClient> service_client,
- PrefService* pref_service,
+ sync_preferences::PrefServiceSyncable* pref_service,
identity::IdentityManager* identity_manager,
- syncer::SyncService* sync_service)
- : service_client_(std::move(service_client)),
- pref_service_(pref_service),
+ syncer::SyncService* sync_service,
+ const std::vector<std::string>& service_pref_names)
+ : pref_service_(pref_service),
identity_manager_(identity_manager),
- sync_service_(sync_service) {
- DCHECK(service_client_);
+ sync_service_(sync_service),
+ service_pref_names_(service_pref_names) {
DCHECK(pref_service_);
DCHECK(identity_manager_);
DCHECK(sync_service_);
@@ -37,6 +35,7 @@ UnifiedConsentService::UnifiedConsentService(
if (GetMigrationState() == MigrationState::kNotInitialized)
MigrateProfileToUnifiedConsent();
+ pref_service_->AddObserver(this);
identity_manager_->AddObserver(this);
sync_service_->AddObserver(this);
}
@@ -51,17 +50,13 @@ void UnifiedConsentService::RegisterPrefs(
registry->RegisterIntegerPref(
prefs::kUnifiedConsentMigrationState,
static_cast<int>(MigrationState::kNotInitialized));
- registry->RegisterBooleanPref(prefs::kAllUnifiedConsentServicesWereEnabled,
- false);
}
// static
void UnifiedConsentService::RollbackIfNeeded(
PrefService* user_pref_service,
- syncer::SyncService* sync_service,
- UnifiedConsentServiceClient* service_client) {
+ syncer::SyncService* sync_service) {
DCHECK(user_pref_service);
- DCHECK(service_client);
if (user_pref_service->GetInteger(prefs::kUnifiedConsentMigrationState) ==
static_cast<int>(MigrationState::kNotInitialized)) {
@@ -69,71 +64,48 @@ void UnifiedConsentService::RollbackIfNeeded(
return;
}
- // Turn off all off-by-default services if services were enabled due to
- // unified consent.
- if (user_pref_service->GetBoolean(
- prefs::kAllUnifiedConsentServicesWereEnabled)) {
- service_client->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting,
- false);
- service_client->SetServiceEnabled(Service::kSpellCheck, false);
- service_client->SetServiceEnabled(Service::kContextualSearch, false);
- }
-
// Clear all unified consent prefs.
user_pref_service->ClearPref(prefs::kUrlKeyedAnonymizedDataCollectionEnabled);
user_pref_service->ClearPref(prefs::kUnifiedConsentMigrationState);
- user_pref_service->ClearPref(prefs::kAllUnifiedConsentServicesWereEnabled);
}
-void UnifiedConsentService::EnableGoogleServices() {
- DCHECK(identity_manager_->HasPrimaryAccount());
- DCHECK_LT(MigrationState::kNotInitialized, GetMigrationState());
-
- if (GetMigrationState() != MigrationState::kCompleted) {
- // If the user opted into unified consent, the migration is completed.
+void UnifiedConsentService::SetUrlKeyedAnonymizedDataCollectionEnabled(
+ bool enabled) {
+ if (GetMigrationState() != MigrationState::kCompleted)
SetMigrationState(MigrationState::kCompleted);
- }
- // Enable all Google services except sync.
pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
- true);
- for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) {
- Service service = static_cast<Service>(i);
- if (service_client_->GetServiceState(service) !=
- ServiceState::kNotSupported) {
- service_client_->SetServiceEnabled(service, true);
- }
- }
-
- pref_service_->SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled, true);
+ enabled);
}
void UnifiedConsentService::Shutdown() {
+ pref_service_->RemoveObserver(this);
identity_manager_->RemoveObserver(this);
sync_service_->RemoveObserver(this);
}
void UnifiedConsentService::OnPrimaryAccountCleared(
- const AccountInfo& account_info) {
- pref_service_->SetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled,
- false);
-
- // By design, signing out of Chrome automatically disables off-by-default
- // services.
- pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
- false);
- service_client_->SetServiceEnabled(Service::kSafeBrowsingExtendedReporting,
- false);
- service_client_->SetServiceEnabled(Service::kSpellCheck, false);
- service_client_->SetServiceEnabled(Service::kContextualSearch, false);
-
- if (GetMigrationState() != MigrationState::kCompleted) {
- // When the user signs out, the migration is complete.
- SetMigrationState(MigrationState::kCompleted);
- }
+ const CoreAccountInfo& account_info) {
+ // By design, clearing the primary account disables URL-keyed data collection.
+ SetUrlKeyedAnonymizedDataCollectionEnabled(false);
}
void UnifiedConsentService::OnStateChanged(syncer::SyncService* sync) {
+ // Start observing pref changes when the user enters sync setup.
+ // Note: |sync->IsSetupInProgress()| is used instead of
+ // |sync->IsFirstSetupInProgress()|, because on Android
+ // |SetFirstSetupComplete()| is called automatically during the first setup.
+ // I.e. the value could change in the meantime.
+ if (sync->IsSetupInProgress() && !pref_service_->IsSyncing()) {
+ StartObservingServicePrefChanges();
+ } else {
+ StopObservingServicePrefChanges();
+
+ // If the user cancelled the sync setup, clear all observed changes.
+ if (!sync->CanSyncFeatureStart())
+ service_pref_changes_.clear();
+ }
+
if (!sync_service_->CanSyncFeatureStart() ||
!sync_service_->IsEngineInitialized()) {
return;
@@ -143,6 +115,43 @@ void UnifiedConsentService::OnStateChanged(syncer::SyncService* sync) {
UpdateSettingsForMigration();
}
+void UnifiedConsentService::OnIsSyncingChanged() {
+ if (pref_service_->IsSyncing() && !service_pref_changes_.empty()) {
+ // Re-apply all observed service pref changes.
+ // If any service prefs had a value coming in through Sync, then that
+ // would've overridden any changes that the user made during the first sync
+ // setup. So re-apply the local changes to make sure they stick.
+ for (const auto& pref_change : service_pref_changes_) {
+ pref_service_->Set(pref_change.first, pref_change.second);
+ }
+ service_pref_changes_.clear();
+ }
+}
+
+void UnifiedConsentService::StartObservingServicePrefChanges() {
+ if (!service_pref_change_registrar_.IsEmpty())
+ return;
+
+ service_pref_change_registrar_.Init(pref_service_);
+ for (const std::string& pref_name : service_pref_names_) {
+ service_pref_change_registrar_.Add(
+ pref_name,
+ base::BindRepeating(&UnifiedConsentService::ServicePrefChanged,
+ base::Unretained(this)));
+ }
+}
+
+void UnifiedConsentService::StopObservingServicePrefChanges() {
+ service_pref_change_registrar_.RemoveAll();
+}
+
+void UnifiedConsentService::ServicePrefChanged(const std::string& name) {
+ DCHECK(sync_service_->IsSetupInProgress());
+ const base::Value* value = pref_service_->Get(name);
+ DCHECK(value);
+ service_pref_changes_[name] = value->Clone();
+}
+
MigrationState UnifiedConsentService::GetMigrationState() {
int migration_state_int =
pref_service_->GetInteger(prefs::kUnifiedConsentMigrationState);
@@ -181,10 +190,7 @@ void UnifiedConsentService::UpdateSettingsForMigration() {
sync_service_->GetUserSettings()->GetChosenDataTypes().Has(
syncer::TYPED_URLS) &&
!sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase();
- pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
- url_keyed_metrics_enabled);
-
- SetMigrationState(MigrationState::kCompleted);
+ SetUrlKeyedAnonymizedDataCollectionEnabled(url_keyed_metrics_enabled);
}
} // namespace unified_consent
diff --git a/chromium/components/unified_consent/unified_consent_service.h b/chromium/components/unified_consent/unified_consent_service.h
index 018d032ff38..95350aa74a6 100644
--- a/chromium/components/unified_consent/unified_consent_service.h
+++ b/chromium/components/unified_consent/unified_consent_service.h
@@ -5,22 +5,29 @@
#ifndef COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_H_
#define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_H_
+#include <map>
#include <memory>
+#include <string>
+#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
+#include "base/values.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "components/prefs/pref_change_registrar.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/sync_service_observer.h"
+#include "components/sync_preferences/pref_service_syncable_observer.h"
#include "components/unified_consent/unified_consent_metrics.h"
-#include "components/unified_consent/unified_consent_service_client.h"
#include "services/identity/public/cpp/identity_manager.h"
namespace user_prefs {
class PrefRegistrySyncable;
}
-class PrefService;
+namespace sync_preferences {
+class PrefServiceSyncable;
+}
namespace syncer {
class SyncService;
@@ -28,9 +35,6 @@ class SyncService;
namespace unified_consent {
-using Service = UnifiedConsentServiceClient::Service;
-using ServiceState = UnifiedConsentServiceClient::ServiceState;
-
enum class MigrationState : int {
kNotInitialized = 0,
kInProgressWaitForSyncInit = 1,
@@ -40,15 +44,26 @@ enum class MigrationState : int {
// A browser-context keyed service that is used to manage the user consent
// when UnifiedConsent feature is enabled.
-class UnifiedConsentService : public KeyedService,
- public identity::IdentityManager::Observer,
- public syncer::SyncServiceObserver {
+//
+// This service makes sure that UrlKeyedAnonymizedDataCollection is turned on
+// during sync opt-in and turned off when the user opts out.
+//
+// During the advanced opt-in through settings, the changes the user makes to
+// the service toggles(prefs) are applied after prefs start syncing. This is
+// done to prevent changes the user makes during sync setup to be overridden by
+// syncing down older changes.
+class UnifiedConsentService
+ : public KeyedService,
+ public identity::IdentityManager::Observer,
+ public syncer::SyncServiceObserver,
+ public sync_preferences::PrefServiceSyncableObserver {
public:
- UnifiedConsentService(
- std::unique_ptr<UnifiedConsentServiceClient> service_client,
- PrefService* pref_service,
- identity::IdentityManager* identity_manager,
- syncer::SyncService* sync_service);
+ // Initializes the service. The |service_pref_names| vector is used to track
+ // pref changes during the first sync setup.
+ UnifiedConsentService(sync_preferences::PrefServiceSyncable* pref_service,
+ identity::IdentityManager* identity_manager,
+ syncer::SyncService* sync_service,
+ const std::vector<std::string>& service_pref_names);
~UnifiedConsentService() override;
// Register the prefs used by this UnifiedConsentService.
@@ -57,20 +72,17 @@ class UnifiedConsentService : public KeyedService,
// Rolls back changes made during migration. This method does nothing if the
// user hasn't migrated to unified consent yet.
static void RollbackIfNeeded(PrefService* user_pref_service,
- syncer::SyncService* sync_service,
- UnifiedConsentServiceClient* service_client);
+ syncer::SyncService* sync_service);
- // Enables all Google services tied to unified consent.
- // Note: Sync has to be enabled through the SyncService. It is *not* enabled
- // in this method.
- void EnableGoogleServices();
+ // Enables or disables URL-keyed anonymized data collection.
+ void SetUrlKeyedAnonymizedDataCollectionEnabled(bool enabled);
// KeyedService:
void Shutdown() override;
// IdentityManager::Observer:
void OnPrimaryAccountCleared(
- const AccountInfo& previous_primary_account_info) override;
+ const CoreAccountInfo& previous_primary_account_info) override;
private:
friend class UnifiedConsentServiceTest;
@@ -78,6 +90,14 @@ class UnifiedConsentService : public KeyedService,
// syncer::SyncServiceObserver:
void OnStateChanged(syncer::SyncService* sync) override;
+ // sync_preferences::PrefServiceSyncableObserver:
+ void OnIsSyncingChanged() override;
+
+ // Helpers for observing changes in the service prefs.
+ void StartObservingServicePrefChanges();
+ void StopObservingServicePrefChanges();
+ void ServicePrefChanged(const std::string& name);
+
// Migration helpers.
MigrationState GetMigrationState();
void SetMigrationState(MigrationState migration_state);
@@ -88,11 +108,15 @@ class UnifiedConsentService : public KeyedService,
// |OnStateChanged| when the sync engine is initialized.
void UpdateSettingsForMigration();
- std::unique_ptr<UnifiedConsentServiceClient> service_client_;
- PrefService* pref_service_;
+ sync_preferences::PrefServiceSyncable* pref_service_;
identity::IdentityManager* identity_manager_;
syncer::SyncService* sync_service_;
+ // Used for tracking the service pref states during the advanced sync opt-in.
+ const std::vector<std::string> service_pref_names_;
+ std::map<std::string, base::Value> service_pref_changes_;
+ PrefChangeRegistrar service_pref_change_registrar_;
+
DISALLOW_COPY_AND_ASSIGN(UnifiedConsentService);
};
diff --git a/chromium/components/unified_consent/unified_consent_service_client.cc b/chromium/components/unified_consent/unified_consent_service_client.cc
deleted file mode 100644
index 87d37710ebd..00000000000
--- a/chromium/components/unified_consent/unified_consent_service_client.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/unified_consent/unified_consent_service_client.h"
-
-#include "base/bind.h"
-
-namespace unified_consent {
-
-UnifiedConsentServiceClient::UnifiedConsentServiceClient() {}
-UnifiedConsentServiceClient::~UnifiedConsentServiceClient() {}
-
-bool UnifiedConsentServiceClient::IsServiceSupported(Service service) {
- return GetServiceState(service) != ServiceState::kNotSupported;
-}
-
-void UnifiedConsentServiceClient::AddObserver(Observer* observer) {
- observer_list_.AddObserver(observer);
-}
-
-void UnifiedConsentServiceClient::RemoveObserver(Observer* observer) {
- observer_list_.RemoveObserver(observer);
-}
-
-void UnifiedConsentServiceClient::ObserveServicePrefChange(
- Service service,
- const std::string& pref_name,
- PrefService* pref_service) {
- service_prefs_[pref_name] = service;
-
- // First access to the pref registrar of |pref_service| in the map
- // automatically creates an entry for it.
- PrefChangeRegistrar* pref_change_registrar =
- &(pref_change_registrars_[pref_service]);
- if (!pref_change_registrar->prefs())
- pref_change_registrar->Init(pref_service);
- pref_change_registrar->Add(
- pref_name,
- base::BindRepeating(&UnifiedConsentServiceClient::OnPrefChanged,
- base::Unretained(this)));
-}
-
-void UnifiedConsentServiceClient::FireOnServiceStateChanged(Service service) {
- for (auto& observer : observer_list_)
- observer.OnServiceStateChanged(service);
-}
-
-void UnifiedConsentServiceClient::OnPrefChanged(const std::string& pref_name) {
- DCHECK(service_prefs_.count(pref_name));
- FireOnServiceStateChanged(service_prefs_[pref_name]);
-}
-
-} // namespace unified_consent
diff --git a/chromium/components/unified_consent/unified_consent_service_client.h b/chromium/components/unified_consent/unified_consent_service_client.h
deleted file mode 100644
index 5391429e3f1..00000000000
--- a/chromium/components/unified_consent/unified_consent_service_client.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_
-#define COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_
-
-#include <map>
-#include <string>
-
-#include "base/observer_list.h"
-#include "components/prefs/pref_change_registrar.h"
-
-class PrefService;
-
-namespace unified_consent {
-
-class UnifiedConsentServiceClient {
- public:
- enum class Service {
- // Extended safe browsing.
- kSafeBrowsingExtendedReporting,
- // Spell checking.
- kSpellCheck,
- // Contextual search.
- kContextualSearch,
-
- // Last element of the enum, used for iteration.
- kLast = kContextualSearch,
- };
-
- enum class ServiceState {
- // The service is not supported on this platform.
- kNotSupported,
- // The service is supported, but disabled.
- kDisabled,
- // The service is enabled.
- kEnabled
- };
-
- class Observer {
- public:
- // Called when the service state of |service| changes.
- virtual void OnServiceStateChanged(Service service) = 0;
- };
-
- UnifiedConsentServiceClient();
- virtual ~UnifiedConsentServiceClient();
-
- // Returns the ServiceState for |service|.
- virtual ServiceState GetServiceState(Service service) = 0;
- // Sets |service| enabled if it is supported on this platform.
- virtual void SetServiceEnabled(Service service, bool enabled) = 0;
-
- // Returns whether |service| is supported on this platform.
- bool IsServiceSupported(Service service);
-
- // Methods to register or remove observers.
- void AddObserver(Observer* observer);
- void RemoveObserver(Observer* observer);
-
- protected:
- // This method adds |pref_name| to the list of prefs that will be observed for
- // changes. Whenever there's a change in the pref, all
- // |UnifiedConsentServiceClient::Observer|s are fired.
- void ObserveServicePrefChange(Service service,
- const std::string& pref_name,
- PrefService* pref_service);
-
- // Fires |OnServiceStateChanged| on all observers.
- void FireOnServiceStateChanged(Service service);
-
- private:
- // Callback for the pref change registrars.
- void OnPrefChanged(const std::string& pref_name);
-
- base::ObserverList<Observer, true>::Unchecked observer_list_;
-
- // Matches the pref name to it's service.
- std::map<std::string, Service> service_prefs_;
- // Matches pref service to it's change registrar.
- std::map<PrefService*, PrefChangeRegistrar> pref_change_registrars_;
-
- DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceClient);
-};
-
-} // namespace unified_consent
-
-#endif // COMPONENTS_UNIFIED_CONSENT_UNIFIED_CONSENT_SERVICE_CLIENT_H_
diff --git a/chromium/components/unified_consent/unified_consent_service_unittest.cc b/chromium/components/unified_consent/unified_consent_service_unittest.cc
index 3fe214269b9..19aec0aaa06 100644
--- a/chromium/components/unified_consent/unified_consent_service_unittest.cc
+++ b/chromium/components/unified_consent/unified_consent_service_unittest.cc
@@ -11,7 +11,6 @@
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
-#include "components/autofill/core/common/autofill_prefs.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_user_settings.h"
#include "components/sync/driver/test_sync_service.h"
@@ -19,7 +18,6 @@
#include "components/unified_consent/pref_names.h"
#include "components/unified_consent/scoped_unified_consent.h"
#include "components/unified_consent/unified_consent_metrics.h"
-#include "components/unified_consent/unified_consent_service_client.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,83 +43,13 @@ class TestSyncService : public syncer::TestSyncService {
DISALLOW_COPY_AND_ASSIGN(TestSyncService);
};
-const char kSpellCheckDummyEnabled[] = "spell_check_dummy.enabled";
-
-class FakeUnifiedConsentServiceClient : public UnifiedConsentServiceClient {
- public:
- FakeUnifiedConsentServiceClient(PrefService* pref_service)
- : pref_service_(pref_service) {
- // When the |kSpellCheckDummyEnabled| pref is changed, all observers should
- // be fired.
- ObserveServicePrefChange(Service::kSpellCheck, kSpellCheckDummyEnabled,
- pref_service);
- }
- ~FakeUnifiedConsentServiceClient() override = default;
-
- // UnifiedConsentServiceClient:
- ServiceState GetServiceState(Service service) override {
- if (is_not_supported_[service])
- return ServiceState::kNotSupported;
- bool enabled;
- // Special treatment for spell check.
- if (service == Service::kSpellCheck) {
- enabled = pref_service_->GetBoolean(kSpellCheckDummyEnabled);
- } else {
- enabled = service_enabled_[service];
- }
- return enabled ? ServiceState::kEnabled : ServiceState::kDisabled;
- }
- void SetServiceEnabled(Service service, bool enabled) override {
- if (is_not_supported_[service])
- return;
- // Special treatment for spell check.
- if (service == Service::kSpellCheck) {
- pref_service_->SetBoolean(kSpellCheckDummyEnabled, enabled);
- return;
- }
- bool should_notify_observers = service_enabled_[service] != enabled;
- service_enabled_[service] = enabled;
- if (should_notify_observers)
- FireOnServiceStateChanged(service);
- }
-
- void SetServiceNotSupported(Service service) {
- is_not_supported_[service] = true;
- }
-
- static void ClearServiceStates() {
- service_enabled_.clear();
- is_not_supported_.clear();
- }
-
- private:
- // Service states are shared between multiple instances of this class.
- static std::map<Service, bool> service_enabled_;
- static std::map<Service, bool> is_not_supported_;
-
- PrefService* pref_service_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeUnifiedConsentServiceClient);
-};
-
-std::map<Service, bool> FakeUnifiedConsentServiceClient::service_enabled_;
-std::map<Service, bool> FakeUnifiedConsentServiceClient::is_not_supported_;
-
} // namespace
class UnifiedConsentServiceTest : public testing::Test {
public:
UnifiedConsentServiceTest() {
- pref_service_.registry()->RegisterBooleanPref(
- autofill::prefs::kAutofillWalletImportEnabled, false);
UnifiedConsentService::RegisterPrefs(pref_service_.registry());
syncer::SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
- pref_service_.registry()->RegisterBooleanPref(kSpellCheckDummyEnabled,
- false);
-
- FakeUnifiedConsentServiceClient::ClearServiceStates();
- service_client_ =
- std::make_unique<FakeUnifiedConsentServiceClient>(&pref_service_);
}
~UnifiedConsentServiceTest() override {
@@ -129,25 +57,15 @@ class UnifiedConsentServiceTest : public testing::Test {
consent_service_->Shutdown();
}
- void CreateConsentService(bool client_services_on_by_default = false) {
+ void CreateConsentService() {
if (!scoped_unified_consent_) {
SetUnifiedConsentFeatureState(
unified_consent::UnifiedConsentFeatureState::kEnabled);
}
- auto client =
- std::make_unique<FakeUnifiedConsentServiceClient>(&pref_service_);
- if (client_services_on_by_default) {
- for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) {
- Service service = static_cast<Service>(i);
- client->SetServiceEnabled(service, true);
- }
- pref_service_.SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled,
- true);
- }
consent_service_ = std::make_unique<UnifiedConsentService>(
- std::move(client), &pref_service_,
- identity_test_environment_.identity_manager(), &sync_service_);
+ &pref_service_, identity_test_environment_.identity_manager(),
+ &sync_service_, std::vector<std::string>());
sync_service_.FireStateChanged();
// Run until idle so the migration can finish.
@@ -164,19 +82,6 @@ class UnifiedConsentServiceTest : public testing::Test {
new unified_consent::ScopedUnifiedConsent(feature_state));
}
- bool AreAllGoogleServicesEnabled() {
- for (int i = 0; i <= static_cast<int>(Service::kLast); ++i) {
- Service service = static_cast<Service>(i);
- if (service_client_->GetServiceState(service) == ServiceState::kDisabled)
- return false;
- }
- if (!pref_service_.GetBoolean(
- prefs::kUrlKeyedAnonymizedDataCollectionEnabled))
- return false;
-
- return true;
- }
-
unified_consent::MigrationState GetMigrationState() {
int migration_state_int =
pref_service_.GetInteger(prefs::kUnifiedConsentMigrationState);
@@ -189,8 +94,6 @@ class UnifiedConsentServiceTest : public testing::Test {
identity::IdentityTestEnvironment identity_test_environment_;
TestSyncService sync_service_;
std::unique_ptr<UnifiedConsentService> consent_service_;
- std::unique_ptr<FakeUnifiedConsentServiceClient> service_client_;
-
std::unique_ptr<ScopedUnifiedConsent> scoped_unified_consent_;
DISALLOW_COPY_AND_ASSIGN(UnifiedConsentServiceTest);
@@ -202,31 +105,16 @@ TEST_F(UnifiedConsentServiceTest, DefaultValuesWhenSignedOut) {
prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
}
-TEST_F(UnifiedConsentServiceTest, EnableServices) {
+TEST_F(UnifiedConsentServiceTest, EnableUrlKeyedAnonymizedDataCollection) {
CreateConsentService();
identity_test_environment_.SetPrimaryAccount("testaccount");
EXPECT_FALSE(pref_service_.GetBoolean(
prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
- EXPECT_FALSE(AreAllGoogleServicesEnabled());
// Enable services and check expectations.
- consent_service_->EnableGoogleServices();
- EXPECT_TRUE(AreAllGoogleServicesEnabled());
-}
-
-TEST_F(UnifiedConsentServiceTest, EnableServices_WithUnsupportedService) {
- CreateConsentService();
- identity_test_environment_.SetPrimaryAccount("testaccount");
- EXPECT_FALSE(pref_service_.GetBoolean(
+ consent_service_->SetUrlKeyedAnonymizedDataCollectionEnabled(true);
+ EXPECT_TRUE(pref_service_.GetBoolean(
prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
- service_client_->SetServiceNotSupported(Service::kSpellCheck);
- EXPECT_EQ(service_client_->GetServiceState(Service::kSpellCheck),
- ServiceState::kNotSupported);
- EXPECT_FALSE(AreAllGoogleServicesEnabled());
-
- // Enable services and check expectations.
- consent_service_->EnableGoogleServices();
- EXPECT_TRUE(AreAllGoogleServicesEnabled());
}
TEST_F(UnifiedConsentServiceTest, Migration_UpdateSettings) {
@@ -254,22 +142,15 @@ TEST_F(UnifiedConsentServiceTest, ClearPrimaryAccountDisablesSomeServices) {
identity_test_environment_.SetPrimaryAccount("testaccount");
// Precondition: Enable unified consent.
- consent_service_->EnableGoogleServices();
- EXPECT_TRUE(AreAllGoogleServicesEnabled());
+ consent_service_->SetUrlKeyedAnonymizedDataCollectionEnabled(true);
+ EXPECT_TRUE(pref_service_.GetBoolean(
+ prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
// Clearing primary account revokes unfied consent and a couple of other
// non-personalized services.
identity_test_environment_.ClearPrimaryAccount();
- EXPECT_FALSE(AreAllGoogleServicesEnabled());
EXPECT_FALSE(pref_service_.GetBoolean(
prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
- EXPECT_EQ(service_client_->GetServiceState(Service::kSpellCheck),
- ServiceState::kDisabled);
- EXPECT_EQ(
- service_client_->GetServiceState(Service::kSafeBrowsingExtendedReporting),
- ServiceState::kDisabled);
- EXPECT_EQ(service_client_->GetServiceState(Service::kContextualSearch),
- ServiceState::kDisabled);
}
TEST_F(UnifiedConsentServiceTest, Migration_NotSignedIn) {
@@ -287,32 +168,22 @@ TEST_F(UnifiedConsentServiceTest, Rollback_UserOptedIntoUnifiedConsent) {
// Migrate and opt into unified consent.
CreateConsentService();
- consent_service_->EnableGoogleServices();
+ consent_service_->SetUrlKeyedAnonymizedDataCollectionEnabled(true);
// Check expectations after opt-in.
- EXPECT_TRUE(AreAllGoogleServicesEnabled());
+ EXPECT_TRUE(pref_service_.GetBoolean(
+ prefs::kUrlKeyedAnonymizedDataCollectionEnabled));
EXPECT_EQ(unified_consent::MigrationState::kCompleted, GetMigrationState());
- EXPECT_TRUE(
- pref_service_.GetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled));
consent_service_->Shutdown();
consent_service_.reset();
SetUnifiedConsentFeatureState(UnifiedConsentFeatureState::kDisabled);
// Rollback
- UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_,
- service_client_.get());
+ UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_);
// Unified consent prefs should be cleared.
EXPECT_EQ(unified_consent::MigrationState::kNotInitialized,
GetMigrationState());
- // Off-by-default services should be turned off.
- EXPECT_NE(ServiceState::kEnabled,
- service_client_->GetServiceState(
- Service::kSafeBrowsingExtendedReporting));
- EXPECT_NE(ServiceState::kEnabled,
- service_client_->GetServiceState(Service::kSpellCheck));
- EXPECT_NE(ServiceState::kEnabled,
- service_client_->GetServiceState(Service::kContextualSearch));
}
} // namespace unified_consent
diff --git a/chromium/components/update_client/BUILD.gn b/chromium/components/update_client/BUILD.gn
index 636f40a42f9..06cb620a29a 100644
--- a/chromium/components/update_client/BUILD.gn
+++ b/chromium/components/update_client/BUILD.gn
@@ -4,6 +4,33 @@
import("//net/features.gni")
+source_set("network_public") {
+ sources = [
+ "net/network_chromium.h",
+ ]
+
+ deps = [
+ "//base",
+ ]
+}
+
+source_set("network") {
+ sources = [
+ "net/network_impl.cc",
+ "net/network_impl.h",
+ ]
+
+ visibility = [ ":*" ]
+
+ deps = [
+ ":network_public",
+ "//base",
+ "//net",
+ "//services/network/public/cpp:cpp",
+ "//url",
+ ]
+}
+
static_library("update_client") {
sources = [
"action_runner.cc",
@@ -26,6 +53,8 @@ static_library("update_client") {
"crx_downloader.cc",
"crx_downloader.h",
"crx_update_item.h",
+ "network.cc",
+ "network.h",
"persisted_data.cc",
"persisted_data.h",
"ping_manager.cc",
@@ -76,7 +105,14 @@ static_library("update_client") {
"utils.h",
]
+ # Allows callers to include the network factory through "update_client" deps.
+ public_deps = [
+ ":network_public",
+ ]
+
deps = [
+ ":network",
+ ":network_public",
"//base",
"//components/client_update_protocol",
"//components/crx_file",
@@ -87,22 +123,25 @@ static_library("update_client") {
"//components/version_info:version_info",
"//courgette:courgette_lib",
"//crypto",
- "//net",
- "//services/network/public/cpp:cpp",
"//third_party/libxml",
"//url",
]
+
+ allow_circular_includes_from = [
+ ":network",
+ ":network_public",
+ ]
}
static_library("test_support") {
testonly = true
sources = [
+ "net/url_loader_post_interceptor.cc",
+ "net/url_loader_post_interceptor.h",
"test_configurator.cc",
"test_configurator.h",
"test_installer.cc",
"test_installer.h",
- "url_loader_post_interceptor.cc",
- "url_loader_post_interceptor.h",
]
public_deps = [
@@ -182,6 +221,7 @@ source_set("unit_tests") {
}
deps = [
+ ":network",
":test_support",
":unit_tests_bundle_data",
":update_client",
diff --git a/chromium/components/update_client/DEPS b/chromium/components/update_client/DEPS
index 7beeb7b82cb..0ac27fdef56 100644
--- a/chromium/components/update_client/DEPS
+++ b/chromium/components/update_client/DEPS
@@ -10,11 +10,17 @@ include_rules = [
"+crypto",
"+libxml",
"+mojo",
- "+net",
- "+services/network/public/cpp",
- "+services/network/test",
"+services/service_manager/public",
"+third_party/libxml",
"+third_party/re2",
"+third_party/zlib",
]
+
+# Allow the unit tests to depend on the network for testing purposes.
+specific_include_rules = {
+ "(test_configurator|.*_unittest\.(cc|h))" : [
+ "+net",
+ "+services/network/public/cpp",
+ "+services/network/test",
+ ]
+}
diff --git a/chromium/components/update_client/background_downloader_win.cc b/chromium/components/update_client/background_downloader_win.cc
index f0867157998..4d6e28e9f61 100644
--- a/chromium/components/update_client/background_downloader_win.cc
+++ b/chromium/components/update_client/background_downloader_win.cc
@@ -442,6 +442,8 @@ void BackgroundDownloader::BeginDownload(const GURL& url) {
return;
}
+ VLOG(1) << "Starting BITS download for: " << url.spec();
+
ResetInterfacePointers();
main_task_runner()->PostTask(FROM_HERE,
base::BindOnce(&BackgroundDownloader::StartTimer,
diff --git a/chromium/components/update_client/component.cc b/chromium/components/update_client/component.cc
index 59e50fcf5bd..c0ea7919133 100644
--- a/chromium/components/update_client/component.cc
+++ b/chromium/components/update_client/component.cc
@@ -20,6 +20,7 @@
#include "components/update_client/action_runner.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/configurator.h"
+#include "components/update_client/network.h"
#include "components/update_client/protocol_definition.h"
#include "components/update_client/protocol_serializer.h"
#include "components/update_client/task_traits.h"
@@ -620,7 +621,7 @@ void Component::StateDownloadingDiff::DoHandle() {
crx_downloader_ = update_context.crx_downloader_factory(
component.CanDoBackgroundDownload(),
- update_context.config->URLLoaderFactory());
+ update_context.config->GetNetworkFetcherFactory());
const auto& id = component.id_;
crx_downloader_->set_progress_callback(
@@ -685,7 +686,7 @@ void Component::StateDownloading::DoHandle() {
crx_downloader_ = update_context.crx_downloader_factory(
component.CanDoBackgroundDownload(),
- update_context.config->URLLoaderFactory());
+ update_context.config->GetNetworkFetcherFactory());
const auto& id = component.id_;
crx_downloader_->set_progress_callback(
diff --git a/chromium/components/update_client/configurator.h b/chromium/components/update_client/configurator.h
index 15ad3f0f8d8..02822f2727d 100644
--- a/chromium/components/update_client/configurator.h
+++ b/chromium/components/update_client/configurator.h
@@ -13,7 +13,6 @@
#include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
class GURL;
class PrefService;
@@ -30,6 +29,7 @@ class Connector;
namespace update_client {
class ActivityDataService;
+class NetworkFetcherFactory;
class ProtocolHandlerFactory;
using RecoveryCRXElevator = base::OnceCallback<std::tuple<bool, int, int>(
@@ -103,8 +103,7 @@ class Configurator : public base::RefCountedThreadSafe<Configurator> {
// Returns an empty string if no policy is in effect.
virtual std::string GetDownloadPreference() const = 0;
- virtual scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
- const = 0;
+ virtual scoped_refptr<NetworkFetcherFactory> GetNetworkFetcherFactory() = 0;
// Returns a new connector to the service manager. That connector is not bound
// to any thread yet.
diff --git a/chromium/components/update_client/crx_downloader.cc b/chromium/components/update_client/crx_downloader.cc
index e07f6c6cce5..a881c865291 100644
--- a/chromium/components/update_client/crx_downloader.cc
+++ b/chromium/components/update_client/crx_downloader.cc
@@ -17,11 +17,11 @@
#if defined(OS_WIN)
#include "components/update_client/background_downloader_win.h"
#endif
+#include "components/update_client/network.h"
#include "components/update_client/task_traits.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/url_fetcher_downloader.h"
#include "components/update_client/utils.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace update_client {
@@ -37,10 +37,9 @@ CrxDownloader::DownloadMetrics::DownloadMetrics()
// which uses the BITS service.
std::unique_ptr<CrxDownloader> CrxDownloader::Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
std::unique_ptr<CrxDownloader> url_fetcher_downloader =
- std::make_unique<UrlFetcherDownloader>(nullptr,
- std::move(url_loader_factory));
+ std::make_unique<UrlFetcherDownloader>(nullptr, network_fetcher_factory);
#if defined(OS_WIN)
if (is_background_download) {
diff --git a/chromium/components/update_client/crx_downloader.h b/chromium/components/update_client/crx_downloader.h
index 565b8bc40d9..4824e3fa3bc 100644
--- a/chromium/components/update_client/crx_downloader.h
+++ b/chromium/components/update_client/crx_downloader.h
@@ -19,12 +19,10 @@
#include "base/threading/thread_checker.h"
#include "url/gurl.h"
-namespace network {
-class SharedURLLoaderFactory;
-}
-
namespace update_client {
+class NetworkFetcherFactory;
+
// Defines a download interface for downloading components, with retrying on
// fallback urls in case of errors. This class implements a chain of
// responsibility design pattern. It can give successors in the chain a chance
@@ -75,9 +73,9 @@ class CrxDownloader {
// different urls and different downloaders.
using ProgressCallback = base::RepeatingCallback<void()>;
- using Factory = std::unique_ptr<CrxDownloader> (*)(
- bool,
- scoped_refptr<network::SharedURLLoaderFactory>);
+ using Factory =
+ std::unique_ptr<CrxDownloader> (*)(bool,
+ scoped_refptr<NetworkFetcherFactory>);
// Factory method to create an instance of this class and build the
// chain of responsibility. |is_background_download| specifies that a
@@ -86,7 +84,7 @@ class CrxDownloader {
// code such as file IO operations.
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
virtual ~CrxDownloader();
void set_progress_callback(const ProgressCallback& progress_callback);
diff --git a/chromium/components/update_client/crx_downloader_unittest.cc b/chromium/components/update_client/crx_downloader_unittest.cc
index 06a7361b22a..03c90026294 100644
--- a/chromium/components/update_client/crx_downloader_unittest.cc
+++ b/chromium/components/update_client/crx_downloader_unittest.cc
@@ -17,6 +17,7 @@
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
+#include "components/update_client/net/network_chromium.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
#include "net/base/net_errors.h"
@@ -122,8 +123,9 @@ void CrxDownloaderTest::SetUp() {
num_progress_calls_ = 0;
// Do not use the background downloader in these tests.
- crx_downloader_ =
- CrxDownloader::Create(false, test_shared_url_loader_factory_);
+ crx_downloader_ = CrxDownloader::Create(
+ false, base::MakeRefCounted<NetworkFetcherChromiumFactory>(
+ test_shared_url_loader_factory_));
crx_downloader_->set_progress_callback(progress_callback_);
test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
diff --git a/chromium/components/update_client/net/DEPS b/chromium/components/update_client/net/DEPS
new file mode 100644
index 00000000000..efe07caf73b
--- /dev/null
+++ b/chromium/components/update_client/net/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "+net",
+ "+services/network/public/cpp",
+ "+services/network/test",
+]
diff --git a/chromium/components/update_client/net/network_chromium.h b/chromium/components/update_client/net/network_chromium.h
new file mode 100644
index 00000000000..e8ac9bbceaa
--- /dev/null
+++ b/chromium/components/update_client/net/network_chromium.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UPDATE_CLIENT_NET_NETWORK_CHROMIUM_H_
+#define COMPONENTS_UPDATE_CLIENT_NET_NETWORK_CHROMIUM_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "components/update_client/network.h"
+
+namespace network {
+class SharedURLLoaderFactory;
+}
+
+namespace update_client {
+
+class NetworkFetcherChromiumFactory : public NetworkFetcherFactory {
+ public:
+ explicit NetworkFetcherChromiumFactory(
+ scoped_refptr<network::SharedURLLoaderFactory>
+ shared_url_network_factory);
+
+ std::unique_ptr<NetworkFetcher> Create() const override;
+
+ protected:
+ ~NetworkFetcherChromiumFactory() override;
+
+ private:
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkFetcherChromiumFactory);
+};
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_NET_NETWORK_CHROMIUM_H_
diff --git a/chromium/components/update_client/net/network_impl.cc b/chromium/components/update_client/net/network_impl.cc
new file mode 100644
index 00000000000..8b2959d8c18
--- /dev/null
+++ b/chromium/components/update_client/net/network_impl.cc
@@ -0,0 +1,207 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/update_client/net/network_impl.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/numerics/safe_conversions.h"
+#include "components/update_client/net/network_chromium.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/gurl.h"
+
+namespace {
+
+const net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("update_client", R"(
+ semantics {
+ sender: "Component Updater and Extension Updater"
+ description:
+ "This network module is used by both the component and the "
+ "extension updaters in Chrome. "
+ "The component updater 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. "
+ "The extension updater works similarly, but it updates user "
+ "extensions instead of Chrome components. "
+ trigger: "Manual or automatic software updates."
+ data:
+ "Various OS and Chrome parameters such as version, bitness, "
+ "release tracks, etc. The component and the extension ids are also "
+ "present in both the request and the response from the servers. "
+ "The URL that refers to a component CRX payload is obfuscated for "
+ "most components."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: NO
+ setting: "This feature cannot be disabled."
+ chrome_policy {
+ ComponentUpdatesEnabled {
+ policy_options {mode: MANDATORY}
+ ComponentUpdatesEnabled: false
+ }
+ }
+ })");
+
+// Returns the string value of a header of the server response or an empty
+// string if the header is not available. Only the first header is returned
+// if multiple instances of the same header are present.
+std::string GetStringHeader(const network::SimpleURLLoader* simple_url_loader,
+ const char* header_name) {
+ DCHECK(simple_url_loader);
+
+ const auto* response_info = simple_url_loader->ResponseInfo();
+ if (!response_info || !response_info->headers)
+ return {};
+
+ std::string header_value;
+ return response_info->headers->EnumerateHeader(nullptr, header_name,
+ &header_value)
+ ? header_value
+ : std::string{};
+}
+
+// Returns the integral value of a header of the server response or -1 if
+// if the header is not available or a conversion error has occured.
+int64_t GetInt64Header(const network::SimpleURLLoader* simple_url_loader,
+ const char* header_name) {
+ DCHECK(simple_url_loader);
+
+ const auto* response_info = simple_url_loader->ResponseInfo();
+ if (!response_info || !response_info->headers)
+ return -1;
+
+ return response_info->headers->GetInt64HeaderValue(header_name);
+}
+
+} // namespace
+
+namespace update_client {
+
+NetworkFetcherImpl::NetworkFetcherImpl(
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory)
+ : shared_url_network_factory_(shared_url_network_factory) {}
+NetworkFetcherImpl::~NetworkFetcherImpl() = default;
+
+void NetworkFetcherImpl::PostRequest(
+ const GURL& url,
+ const std::string& post_data,
+ const base::flat_map<std::string, std::string>& post_additional_headers,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ PostRequestCompleteCallback post_request_complete_callback) {
+ DCHECK(!simple_url_loader_);
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = url;
+ resource_request->method = "POST";
+ resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DISABLE_CACHE;
+ for (const auto& header : post_additional_headers)
+ resource_request->headers.SetHeader(header.first, header.second);
+ simple_url_loader_ = network::SimpleURLLoader::Create(
+ std::move(resource_request), traffic_annotation);
+ simple_url_loader_->SetRetryOptions(
+ kMaxRetriesOnNetworkChange,
+ network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
+ simple_url_loader_->AttachStringForUpload(post_data, "application/xml");
+ simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce(
+ &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this),
+ std::move(response_started_callback)));
+ simple_url_loader_->SetOnDownloadProgressCallback(base::BindRepeating(
+ &NetworkFetcherImpl::OnProgressCallback, base::Unretained(this),
+ std::move(progress_callback)));
+ constexpr size_t kMaxResponseSize = 1024 * 1024;
+ simple_url_loader_->DownloadToString(
+ shared_url_network_factory_.get(),
+ base::BindOnce(
+ [](const network::SimpleURLLoader* simple_url_loader,
+ PostRequestCompleteCallback post_request_complete_callback,
+ std::unique_ptr<std::string> response_body) {
+ std::move(post_request_complete_callback)
+ .Run(std::move(response_body), simple_url_loader->NetError(),
+ GetStringHeader(simple_url_loader, kHeaderEtag),
+ GetInt64Header(simple_url_loader, kHeaderXRetryAfter));
+ },
+ simple_url_loader_.get(), std::move(post_request_complete_callback)),
+ kMaxResponseSize);
+}
+
+void NetworkFetcherImpl::DownloadToFile(
+ const GURL& url,
+ const base::FilePath& file_path,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ DownloadToFileCompleteCallback download_to_file_complete_callback) {
+ DCHECK(!simple_url_loader_);
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = url;
+ resource_request->method = "GET";
+ resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DISABLE_CACHE;
+ simple_url_loader_ = network::SimpleURLLoader::Create(
+ std::move(resource_request), traffic_annotation);
+ simple_url_loader_->SetRetryOptions(
+ kMaxRetriesOnNetworkChange,
+ network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
+ simple_url_loader_->SetAllowPartialResults(true);
+ simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce(
+ &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this),
+ std::move(response_started_callback)));
+ simple_url_loader_->SetOnDownloadProgressCallback(base::BindRepeating(
+ &NetworkFetcherImpl::OnProgressCallback, base::Unretained(this),
+ std::move(progress_callback)));
+ simple_url_loader_->DownloadToFile(
+ shared_url_network_factory_.get(),
+ base::BindOnce(
+ [](const network::SimpleURLLoader* simple_url_loader,
+ DownloadToFileCompleteCallback download_to_file_complete_callback,
+ base::FilePath file_path) {
+ std::move(download_to_file_complete_callback)
+ .Run(file_path, simple_url_loader->NetError(),
+ simple_url_loader->GetContentSize());
+ },
+ simple_url_loader_.get(),
+ std::move(download_to_file_complete_callback)),
+ file_path);
+}
+
+void NetworkFetcherImpl::OnResponseStartedCallback(
+ ResponseStartedCallback response_started_callback,
+ const GURL& final_url,
+ const network::ResourceResponseHead& response_head) {
+ std::move(response_started_callback)
+ .Run(final_url,
+ response_head.headers ? response_head.headers->response_code() : -1,
+ response_head.content_length);
+}
+
+void NetworkFetcherImpl::OnProgressCallback(ProgressCallback progress_callback,
+ uint64_t current) {
+ progress_callback.Run(base::saturated_cast<int64_t>(current));
+}
+
+NetworkFetcherChromiumFactory::NetworkFetcherChromiumFactory(
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory)
+ : shared_url_network_factory_(shared_url_network_factory) {}
+
+NetworkFetcherChromiumFactory::~NetworkFetcherChromiumFactory() = default;
+
+std::unique_ptr<NetworkFetcher> NetworkFetcherChromiumFactory::Create() const {
+ return std::make_unique<NetworkFetcherImpl>(shared_url_network_factory_);
+}
+
+} // namespace update_client
diff --git a/chromium/components/update_client/net/network_impl.h b/chromium/components/update_client/net/network_impl.h
new file mode 100644
index 00000000000..f28cf2f9437
--- /dev/null
+++ b/chromium/components/update_client/net/network_impl.h
@@ -0,0 +1,65 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UPDATE_CLIENT_NET_NETWORK_IMPL_H_
+#define COMPONENTS_UPDATE_CLIENT_NET_NETWORK_IMPL_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "components/update_client/network.h"
+
+namespace network {
+struct ResourceResponseHead;
+class SharedURLLoaderFactory;
+class SimpleURLLoader;
+} // namespace network
+
+namespace update_client {
+
+class NetworkFetcherImpl : public NetworkFetcher {
+ public:
+ explicit NetworkFetcherImpl(scoped_refptr<network::SharedURLLoaderFactory>
+ shared_url_network_factory);
+ ~NetworkFetcherImpl() override;
+
+ // NetworkFetcher overrides.
+ void PostRequest(
+ const GURL& url,
+ const std::string& post_data,
+ const base::flat_map<std::string, std::string>& post_additional_headers,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ PostRequestCompleteCallback post_request_complete_callback) override;
+ void DownloadToFile(const GURL& url,
+ const base::FilePath& file_path,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ DownloadToFileCompleteCallback
+ download_to_file_complete_callback) override;
+
+ private:
+ void OnResponseStartedCallback(
+ ResponseStartedCallback response_started_callback,
+ const GURL& final_url,
+ const network::ResourceResponseHead& response_head);
+
+ void OnProgressCallback(ProgressCallback response_started_callback,
+ uint64_t current);
+
+ static constexpr int kMaxRetriesOnNetworkChange = 3;
+
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkFetcherImpl);
+};
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_NET_NETWORK_IMPL_H_
diff --git a/chromium/components/update_client/url_loader_post_interceptor.cc b/chromium/components/update_client/net/url_loader_post_interceptor.cc
index 6f374787dce..11a2af87933 100644
--- a/chromium/components/update_client/url_loader_post_interceptor.cc
+++ b/chromium/components/update_client/net/url_loader_post_interceptor.cc
@@ -2,12 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/update_client/url_loader_post_interceptor.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
+#include "components/update_client/net/url_loader_post_interceptor.h"
+#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/run_loop.h"
diff --git a/chromium/components/update_client/url_loader_post_interceptor.h b/chromium/components/update_client/net/url_loader_post_interceptor.h
index c9c264bb66f..9907f499dd1 100644
--- a/chromium/components/update_client/url_loader_post_interceptor.h
+++ b/chromium/components/update_client/net/url_loader_post_interceptor.h
@@ -2,8 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_UPDATE_CLIENT_URL_LOADER_POST_INTERCEPTOR_H_
-#define COMPONENTS_UPDATE_CLIENT_URL_LOADER_POST_INTERCEPTOR_H_
+#ifndef COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
+#define COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
#include "base/callback.h"
#include "base/containers/queue.h"
@@ -172,4 +178,4 @@ class AnyMatch : public URLLoaderPostInterceptor::RequestMatcher {
} // namespace update_client
-#endif // COMPONENTS_UPDATE_CLIENT_URL_LOADER_POST_INTERCEPTOR_H_
+#endif // COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
diff --git a/chromium/components/update_client/network.cc b/chromium/components/update_client/network.cc
new file mode 100644
index 00000000000..cb8e15189e7
--- /dev/null
+++ b/chromium/components/update_client/network.cc
@@ -0,0 +1,12 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/update_client/network.h"
+
+namespace update_client {
+
+constexpr char NetworkFetcher::kHeaderEtag[];
+constexpr char NetworkFetcher::kHeaderXRetryAfter[];
+
+} // namespace update_client
diff --git a/chromium/components/update_client/network.h b/chromium/components/update_client/network.h
new file mode 100644
index 00000000000..daed162ecbb
--- /dev/null
+++ b/chromium/components/update_client/network.h
@@ -0,0 +1,89 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UPDATE_CLIENT_NETWORK_H_
+#define COMPONENTS_UPDATE_CLIENT_NETWORK_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+
+class GURL;
+
+namespace base {
+class FilePath;
+} // namespace base
+
+namespace update_client {
+
+class NetworkFetcher {
+ public:
+ using PostRequestCompleteCallback =
+ base::OnceCallback<void(std::unique_ptr<std::string> response_body,
+ int net_error,
+ const std::string& header_etag,
+ int64_t xheader_retry_after_sec)>;
+ using DownloadToFileCompleteCallback = base::OnceCallback<
+ void(base::FilePath path, int net_error, int64_t content_size)>;
+ using ResponseStartedCallback = base::OnceCallback<
+ void(const GURL& final_url, int response_code, int64_t content_length)>;
+ using ProgressCallback = base::RepeatingCallback<void(int64_t current)>;
+
+ // The ETag header carries the ECSDA signature of the POST response, if
+ // signing has been used.
+ static constexpr char kHeaderEtag[] = "ETag";
+
+ // The server uses the optional X-Retry-After header to indicate that the
+ // current request should not be attempted again.
+ //
+ // The value of the header is the number of seconds to wait before trying to
+ // do a subsequent update check. Only the values retrieved over HTTPS are
+ // trusted.
+ static constexpr char kHeaderXRetryAfter[] = "X-Retry-After";
+
+ virtual ~NetworkFetcher() = default;
+
+ virtual void PostRequest(
+ const GURL& url,
+ const std::string& post_data,
+ const base::flat_map<std::string, std::string>& post_additional_headers,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ PostRequestCompleteCallback post_request_complete_callback) = 0;
+ virtual void DownloadToFile(
+ const GURL& url,
+ const base::FilePath& file_path,
+ ResponseStartedCallback response_started_callback,
+ ProgressCallback progress_callback,
+ DownloadToFileCompleteCallback download_to_file_complete_callback) = 0;
+
+ protected:
+ NetworkFetcher() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkFetcher);
+};
+
+class NetworkFetcherFactory : public base::RefCounted<NetworkFetcherFactory> {
+ public:
+ virtual std::unique_ptr<NetworkFetcher> Create() const = 0;
+
+ protected:
+ friend class base::RefCounted<NetworkFetcherFactory>;
+ NetworkFetcherFactory() = default;
+ virtual ~NetworkFetcherFactory() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkFetcherFactory);
+};
+
+} // namespace update_client
+
+#endif // COMPONENTS_UPDATE_CLIENT_NETWORK_H_
diff --git a/chromium/components/update_client/ping_manager.cc b/chromium/components/update_client/ping_manager.cc
index dbb7f67ceb1..3c2a60ca994 100644
--- a/chromium/components/update_client/ping_manager.cc
+++ b/chromium/components/update_client/ping_manager.cc
@@ -23,7 +23,6 @@
#include "components/update_client/protocol_serializer.h"
#include "components/update_client/request_sender.h"
#include "components/update_client/utils.h"
-#include "net/url_request/url_fetcher.h"
#include "url/gurl.h"
namespace update_client {
diff --git a/chromium/components/update_client/ping_manager_unittest.cc b/chromium/components/update_client/ping_manager_unittest.cc
index e33a7556956..b48a905e5ae 100644
--- a/chromium/components/update_client/ping_manager_unittest.cc
+++ b/chromium/components/update_client/ping_manager_unittest.cc
@@ -20,12 +20,11 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "components/update_client/component.h"
+#include "components/update_client/net/url_loader_post_interceptor.h"
#include "components/update_client/protocol_definition.h"
#include "components/update_client/protocol_serializer.h"
#include "components/update_client/test_configurator.h"
#include "components/update_client/update_engine.h"
-#include "components/update_client/url_loader_post_interceptor.h"
-#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/re2/src/re2/re2.h"
@@ -115,7 +114,7 @@ scoped_refptr<UpdateContext> PingManagerTest::MakeMockUpdateContext() const {
// This test is parameterized for using JSON or XML serialization. |true| means
// JSON serialization is used.
-INSTANTIATE_TEST_CASE_P(Parameterized, PingManagerTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(Parameterized, PingManagerTest, testing::Bool());
TEST_P(PingManagerTest, SendPing) {
auto interceptor = std::make_unique<URLLoaderPostInterceptor>(
@@ -140,7 +139,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
ASSERT_TRUE(request);
EXPECT_TRUE(request->FindKey("@os"));
@@ -220,7 +220,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
const auto& app = request->FindKey("app")->GetList()[0];
EXPECT_EQ("abc", app.FindKey("appid")->GetString());
@@ -267,7 +268,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
const auto& app = request->FindKey("app")->GetList()[0];
EXPECT_EQ("abc", app.FindKey("appid")->GetString());
@@ -317,7 +319,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
const auto& app = request->FindKey("app")->GetList()[0];
EXPECT_EQ("abc", app.FindKey("appid")->GetString());
@@ -351,7 +354,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
const auto& app = request->FindKey("app")->GetList()[0];
EXPECT_EQ("abc", app.FindKey("appid")->GetString());
@@ -415,7 +419,8 @@ TEST_P(PingManagerTest, SendPing) {
EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
const auto msg = interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(msg);
+ const auto root = base::JSONReader::Read(msg);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
const auto& app = request->FindKey("app")->GetList()[0];
EXPECT_EQ("abc", app.FindKey("appid")->GetString());
diff --git a/chromium/components/update_client/protocol_parser_json.cc b/chromium/components/update_client/protocol_parser_json.cc
index 77cea146e8c..09dd08f61c7 100644
--- a/chromium/components/update_client/protocol_parser_json.cc
+++ b/chromium/components/update_client/protocol_parser_json.cc
@@ -282,7 +282,7 @@ bool ProtocolParserJSON::DoParse(const std::string& response_json,
ParseError("Missing secure JSON prefix.");
return false;
}
- const auto doc = base::JSONReader().Read(
+ const auto doc = base::JSONReader::Read(
{response_json.begin() + std::char_traits<char>::length(kJSONPrefix),
response_json.end()});
if (!doc) {
diff --git a/chromium/components/update_client/request_sender.cc b/chromium/components/update_client/request_sender.cc
index b6657163b72..a68df9868cf 100644
--- a/chromium/components/update_client/request_sender.cc
+++ b/chromium/components/update_client/request_sender.cc
@@ -4,55 +4,35 @@
#include "components/update_client/request_sender.h"
-#include <algorithm>
#include <utility>
#include "base/base64.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/client_update_protocol/ecdsa.h"
#include "components/update_client/configurator.h"
+#include "components/update_client/network.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
-#include "net/http/http_response_headers.h"
-#include "services/network/public/cpp/simple_url_loader.h"
namespace update_client {
namespace {
// This is an ECDSA prime256v1 named-curve key.
-constexpr int kKeyVersion = 8;
+constexpr int kKeyVersion = 9;
const char kKeyPubBytesBase64[] =
- "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+J2iCpfk8lThcuKUPzTaVcUjhNR3"
- "AYHK+tTelGdHvyGGx7RP7BphYSPmpH6P4Vr72ak0W1a0bW55O9HW2oz3rQ==";
-
-// The ETag header carries the ECSDA signature of the protocol response, if
-// signing has been used.
-constexpr const char* kHeaderEtag = "ETag";
-
-// The server uses the optional X-Retry-After header to indicate that the
-// current request should not be attempted again. Any response received along
-// with the X-Retry-After header should be interpreted as it would have been
-// without the X-Retry-After header.
-//
-// In addition to the presence of the header, the value of the header is
-// used as a signal for when to do future update checks, but only when the
-// response is over https. Values over http are not trusted and are ignored.
-//
-// The value of the header is the number of seconds to wait before trying to do
-// a subsequent update check. The upper bound for the number of seconds to wait
-// before trying to do a subsequent update check is capped at 24 hours.
-constexpr const char* kHeaderXRetryAfter = "X-Retry-After";
-constexpr int64_t kMaxRetryAfterSec = 24 * 60 * 60;
+ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsVwVMmIJaWBjktSx9m1JrZWYBvMm"
+ "bsrGGQPhScDtao+DloD871YmEeunAaQvRMZgDh1nCaWkVG6wo75+yDbKDA==";
} // namespace
RequestSender::RequestSender(scoped_refptr<Configurator> config)
- : config_(config), use_signing_(false) {}
+ : config_(config) {}
RequestSender::~RequestSender() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -104,19 +84,21 @@ void RequestSender::SendInternal() {
url = BuildUpdateUrl(url, request_query_string);
}
- update_client::LoadCompleteCallback callback = base::BindOnce(
- &RequestSender::OnSimpleURLLoaderComplete, base::Unretained(this), url);
-
- url_loader_ =
- SendProtocolRequest(url, request_extra_headers_, request_body_,
- std::move(callback), config_->URLLoaderFactory());
- if (!url_loader_)
+ network_fetcher_ = config_->GetNetworkFetcherFactory()->Create();
+ if (!network_fetcher_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&RequestSender::SendInternalComplete,
base::Unretained(this),
static_cast<int>(ProtocolError::URL_FETCHER_FAILED),
std::string(), std::string(), 0));
+ }
+ network_fetcher_->PostRequest(
+ url, request_body_, request_extra_headers_,
+ base::BindOnce(&RequestSender::OnResponseStarted, base::Unretained(this)),
+ base::BindRepeating([](int64_t current) {}),
+ base::BindOnce(&RequestSender::OnNetworkFetcherComplete,
+ base::Unretained(this), url));
}
void RequestSender::SendInternalComplete(int error,
@@ -157,41 +139,41 @@ void RequestSender::SendInternalComplete(int error,
HandleSendError(error, retry_after_sec);
}
-void RequestSender::OnSimpleURLLoaderComplete(
+void RequestSender::OnResponseStarted(const GURL& final_url,
+ int response_code,
+ int64_t content_length) {
+ response_code_ = response_code;
+}
+
+void RequestSender::OnNetworkFetcherComplete(
const GURL& original_url,
- std::unique_ptr<std::string> response_body) {
+ std::unique_ptr<std::string> response_body,
+ int net_error,
+ const std::string& header_etag,
+ int64_t xheader_retry_after_sec) {
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "request completed from url: " << original_url.spec();
- int response_code = -1;
- if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) {
- response_code = url_loader_->ResponseInfo()->headers->response_code();
- }
-
- int fetch_error = -1;
- if (response_body && response_code == 200) {
- fetch_error = 0;
- } else if (response_code != -1) {
- fetch_error = response_code;
+ int error = -1;
+ if (response_body && response_code_ == 200) {
+ DCHECK_EQ(0, net_error);
+ error = 0;
+ } else if (response_code_ != -1) {
+ error = response_code_;
} else {
- fetch_error = url_loader_->NetError();
+ error = net_error;
}
- int64_t retry_after_sec(-1);
- if (original_url.SchemeIsCryptographic() && fetch_error > 0) {
- retry_after_sec =
- GetInt64HeaderValue(url_loader_.get(), kHeaderXRetryAfter);
- retry_after_sec = std::min(retry_after_sec, kMaxRetryAfterSec);
- }
+ int retry_after_sec = -1;
+ if (original_url.SchemeIsCryptographic() && error > 0)
+ retry_after_sec = base::saturated_cast<int>(xheader_retry_after_sec);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&RequestSender::SendInternalComplete,
- base::Unretained(this), fetch_error,
- response_body ? *response_body : std::string(),
- GetStringHeaderValue(url_loader_.get(), kHeaderEtag),
- static_cast<int>(retry_after_sec)));
+ FROM_HERE, base::BindOnce(&RequestSender::SendInternalComplete,
+ base::Unretained(this), error,
+ response_body ? *response_body : std::string(),
+ header_etag, retry_after_sec));
}
void RequestSender::HandleSendError(int error, int retry_after_sec) {
@@ -219,30 +201,4 @@ GURL RequestSender::BuildUpdateUrl(const GURL& url,
return url.ReplaceComponents(replacements);
}
-std::string RequestSender::GetStringHeaderValue(
- const network::SimpleURLLoader* url_loader,
- const char* header_name) {
- DCHECK(url_loader);
- if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
- std::string etag;
- return url_loader->ResponseInfo()->headers->EnumerateHeader(
- nullptr, header_name, &etag)
- ? etag
- : std::string();
- }
-
- return std::string();
-}
-
-int64_t RequestSender::GetInt64HeaderValue(
- const network::SimpleURLLoader* url_loader,
- const char* header_name) {
- DCHECK(url_loader);
- if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
- return url_loader->ResponseInfo()->headers->GetInt64HeaderValue(
- header_name);
- }
- return -1;
-}
-
} // namespace update_client
diff --git a/chromium/components/update_client/request_sender.h b/chromium/components/update_client/request_sender.h
index 2ffdd62bd57..7b9e21bc5d1 100644
--- a/chromium/components/update_client/request_sender.h
+++ b/chromium/components/update_client/request_sender.h
@@ -22,13 +22,10 @@ namespace client_update_protocol {
class Ecdsa;
}
-namespace network {
-class SimpleURLLoader;
-}
-
namespace update_client {
class Configurator;
+class NetworkFetcher;
// Sends a request to one of the urls provided. The class implements a chain
// of responsibility design pattern, where the urls are tried in the order they
@@ -68,19 +65,15 @@ class RequestSender {
// Decodes and returns the public key used by CUP.
static std::string GetKey(const char* key_bytes_base64);
- // Returns the string value of a header of the server response or an empty
- // string if the header is not available.
- static std::string GetStringHeaderValue(
- const network::SimpleURLLoader* url_loader,
- const char* header_name);
+ void OnResponseStarted(const GURL& final_url,
+ int response_code,
+ int64_t content_length);
- // Returns the integral value of a header of the server response or -1 if
- // if the header is not available or a conversion error has occured.
- static int64_t GetInt64HeaderValue(const network::SimpleURLLoader* loader,
- const char* header_name);
-
- void OnSimpleURLLoaderComplete(const GURL& original_url,
- std::unique_ptr<std::string> response_body);
+ void OnNetworkFetcherComplete(const GURL& original_url,
+ std::unique_ptr<std::string> response_body,
+ int net_error,
+ const std::string& header_etag,
+ int64_t xheader_retry_after_sec);
// Implements the error handling and url fallback mechanism.
void SendInternal();
@@ -102,14 +95,16 @@ class RequestSender {
std::vector<GURL> urls_;
base::flat_map<std::string, std::string> request_extra_headers_;
std::string request_body_;
- bool use_signing_; // True if CUP signing is used.
+ bool use_signing_ = false; // True if CUP signing is used.
RequestSenderCallback request_sender_callback_;
std::string public_key_;
std::vector<GURL>::const_iterator cur_url_;
- std::unique_ptr<network::SimpleURLLoader> url_loader_;
+ std::unique_ptr<NetworkFetcher> network_fetcher_;
std::unique_ptr<client_update_protocol::Ecdsa> signer_;
+ int response_code_ = -1;
+
DISALLOW_COPY_AND_ASSIGN(RequestSender);
};
diff --git a/chromium/components/update_client/request_sender_unittest.cc b/chromium/components/update_client/request_sender_unittest.cc
index aa9e4c93c12..7d5debbc74d 100644
--- a/chromium/components/update_client/request_sender_unittest.cc
+++ b/chromium/components/update_client/request_sender_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
@@ -14,8 +15,8 @@
#include "base/strings/string_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "components/update_client/net/url_loader_post_interceptor.h"
#include "components/update_client/test_configurator.h"
-#include "components/update_client/url_loader_post_interceptor.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace update_client {
@@ -72,7 +73,7 @@ class RequestSenderTest : public testing::Test,
DISALLOW_COPY_AND_ASSIGN(RequestSenderTest);
};
-INSTANTIATE_TEST_CASE_P(IsForeground, RequestSenderTest, ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(IsForeground, RequestSenderTest, ::testing::Bool());
RequestSenderTest::RequestSenderTest()
: scoped_task_environment_(
diff --git a/chromium/components/update_client/test_configurator.cc b/chromium/components/update_client/test_configurator.cc
index ad2f618f219..7820f3be03d 100644
--- a/chromium/components/update_client/test_configurator.cc
+++ b/chromium/components/update_client/test_configurator.cc
@@ -12,6 +12,7 @@
#include "components/services/patch/public/interfaces/constants.mojom.h"
#include "components/services/unzip/public/interfaces/constants.mojom.h"
#include "components/update_client/activity_data_service.h"
+#include "components/update_client/net/network_chromium.h"
#include "components/update_client/protocol_handler.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -44,7 +45,10 @@ TestConfigurator::TestConfigurator()
connector_factory_.RegisterInstance(patch::mojom::kServiceName)),
test_shared_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_)) {
+ &test_url_loader_factory_)),
+ network_fetcher_factory_(
+ base::MakeRefCounted<NetworkFetcherChromiumFactory>(
+ test_shared_loader_factory_)) {
connector_factory_.set_ignore_quit_requests(true);
}
@@ -115,9 +119,9 @@ std::string TestConfigurator::GetDownloadPreference() const {
return download_preference_;
}
-scoped_refptr<network::SharedURLLoaderFactory>
-TestConfigurator::URLLoaderFactory() const {
- return test_shared_loader_factory_;
+scoped_refptr<NetworkFetcherFactory>
+TestConfigurator::GetNetworkFetcherFactory() {
+ return network_fetcher_factory_;
}
std::unique_ptr<service_manager::Connector>
diff --git a/chromium/components/update_client/test_configurator.h b/chromium/components/update_client/test_configurator.h
index 8c7d0e9cc55..d4a404cd189 100644
--- a/chromium/components/update_client/test_configurator.h
+++ b/chromium/components/update_client/test_configurator.h
@@ -35,6 +35,7 @@ class Connector;
namespace update_client {
class ActivityDataService;
+class NetworkFetcherFactory;
class ProtocolHandlerFactory;
#define POST_INTERCEPT_SCHEME "https"
@@ -90,8 +91,7 @@ class TestConfigurator : public Configurator {
std::string GetOSLongName() const override;
base::flat_map<std::string, std::string> ExtraRequestParams() const override;
std::string GetDownloadPreference() const override;
- scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactory()
- const override;
+ scoped_refptr<NetworkFetcherFactory> GetNetworkFetcherFactory() override;
std::unique_ptr<service_manager::Connector> CreateServiceManagerConnector()
const override;
bool EnabledDeltas() const override;
@@ -146,6 +146,7 @@ class TestConfigurator : public Configurator {
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
network::TestURLLoaderFactory test_url_loader_factory_;
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory_;
DISALLOW_COPY_AND_ASSIGN(TestConfigurator);
};
diff --git a/chromium/components/update_client/test_installer.cc b/chromium/components/update_client/test_installer.cc
index d0febe59c41..c6e5b8aa466 100644
--- a/chromium/components/update_client/test_installer.cc
+++ b/chromium/components/update_client/test_installer.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
diff --git a/chromium/components/update_client/update_checker.cc b/chromium/components/update_client/update_checker.cc
index 5b095cc50ce..b9d83ba4bbd 100644
--- a/chromium/components/update_client/update_checker.cc
+++ b/chromium/components/update_client/update_checker.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <algorithm>
+#include <functional>
#include <memory>
#include <string>
#include <utility>
@@ -134,9 +135,8 @@ void UpdateCheckerImpl::CheckForUpdates(
base::BindOnce(&UpdateCheckerImpl::ReadUpdaterStateAttributes,
base::Unretained(this)),
base::BindOnce(&UpdateCheckerImpl::CheckForUpdatesHelper,
- base::Unretained(this), session_id,
- base::ConstRef(components), additional_attributes,
- enabled_component_updates));
+ base::Unretained(this), session_id, std::cref(components),
+ additional_attributes, enabled_component_updates));
}
// This function runs on the blocking pool task runner.
diff --git a/chromium/components/update_client/update_checker_unittest.cc b/chromium/components/update_client/update_checker_unittest.cc
index a62d0ffb1ef..c74a51f67ba 100644
--- a/chromium/components/update_client/update_checker_unittest.cc
+++ b/chromium/components/update_client/update_checker_unittest.cc
@@ -29,12 +29,10 @@
#include "components/prefs/testing_pref_service.h"
#include "components/update_client/activity_data_service.h"
#include "components/update_client/component.h"
+#include "components/update_client/net/url_loader_post_interceptor.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_loader_post_interceptor.h"
-#include "net/url_request/url_request_test_util.h"
-#include "services/network/public/cpp/resource_request.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -164,9 +162,9 @@ class UpdateCheckerTest : public testing::TestWithParam<UpdateCheckTestParams> {
};
// This test is parameterized for |is_foreground and |use_JSON|.
-INSTANTIATE_TEST_CASE_P(Parameterized,
- UpdateCheckerTest,
- testing::Combine(testing::Bool(), testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(Parameterized,
+ UpdateCheckerTest,
+ testing::Combine(testing::Bool(), testing::Bool()));
UpdateCheckerTest::UpdateCheckerTest()
: scoped_task_environment_(
@@ -286,7 +284,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckSuccess) {
// Sanity check the request.
const auto& request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto* request = root->FindKey("request");
ASSERT_TRUE(request);
EXPECT_TRUE(request->FindKey("@os"));
@@ -433,7 +432,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckInvalidAp) {
const auto request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -490,7 +490,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckSuccessNoBrand) {
const auto request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -573,6 +574,7 @@ TEST_P(UpdateCheckerTest, UpdateCheckDownloadPreference) {
const auto request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
const auto root = base::JSONReader().Read(request);
+ ASSERT_TRUE(root);
EXPECT_EQ("cacheable",
root->FindKey("request")->FindKey("dlpref")->GetString());
} else {
@@ -610,7 +612,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckCupError) {
// Sanity check the request.
const auto& request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -713,11 +716,13 @@ TEST_P(UpdateCheckerTest, UpdateCheckLastRollCall) {
if (use_JSON_) {
const auto root1 =
- base::JSONReader().Read(post_interceptor_->GetRequestBody(0));
+ base::JSONReader::Read(post_interceptor_->GetRequestBody(0));
+ ASSERT_TRUE(root1);
const auto& app1 = root1->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(5, app1.FindPath({"ping", "r"})->GetInt());
const auto root2 =
- base::JSONReader().Read(post_interceptor_->GetRequestBody(1));
+ base::JSONReader::Read(post_interceptor_->GetRequestBody(1));
+ ASSERT_TRUE(root2);
const auto& app2 = root2->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(3383, app2.FindPath({"ping", "rd"})->GetInt());
EXPECT_TRUE(app2.FindPath({"ping", "ping_freshness"})->is_string());
@@ -786,14 +791,16 @@ TEST_P(UpdateCheckerTest, UpdateCheckLastActive) {
if (use_JSON_) {
{
const auto root =
- base::JSONReader().Read(post_interceptor_->GetRequestBody(0));
+ base::JSONReader::Read(post_interceptor_->GetRequestBody(0));
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(10, app.FindPath({"ping", "a"})->GetInt());
EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
}
{
const auto root =
- base::JSONReader().Read(post_interceptor_->GetRequestBody(1));
+ base::JSONReader::Read(post_interceptor_->GetRequestBody(1));
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(3383, app.FindPath({"ping", "ad"})->GetInt());
EXPECT_EQ(3383, app.FindPath({"ping", "rd"})->GetInt());
@@ -801,7 +808,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckLastActive) {
}
{
const auto root =
- base::JSONReader().Read(post_interceptor_->GetRequestBody(2));
+ base::JSONReader::Read(post_interceptor_->GetRequestBody(2));
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(3383, app.FindPath({"ping", "rd"})->GetInt());
EXPECT_TRUE(app.FindPath({"ping", "ping_freshness"})->is_string());
@@ -841,7 +849,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckInstallSource) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app =
root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
@@ -869,7 +878,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckInstallSource) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app =
root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ("sideload", app.FindKey("installsource")->GetString());
@@ -897,7 +907,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckInstallSource) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_FALSE(app.FindKey("installsource"));
} else {
@@ -921,7 +932,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckInstallSource) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ("webstore", app.FindKey("installsource")->GetString());
EXPECT_EQ("external", app.FindKey("installedby")->GetString());
@@ -955,7 +967,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
EXPECT_FALSE(app.FindKey("disabled"));
@@ -981,7 +994,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
EXPECT_FALSE(app.FindKey("disabled"));
@@ -1007,7 +1021,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
const auto& disabled = app.FindKey("disabled")->GetList();
@@ -1034,7 +1049,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
const auto& disabled = app.FindKey("disabled")->GetList();
@@ -1062,7 +1078,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
const auto& disabled = app.FindKey("disabled")->GetList();
@@ -1094,7 +1111,8 @@ TEST_P(UpdateCheckerTest, ComponentDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
const auto& disabled = app.FindKey("disabled")->GetList();
@@ -1145,7 +1163,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -1178,7 +1197,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -1211,7 +1231,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -1244,7 +1265,8 @@ TEST_P(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
RunThreads();
const auto& request = post_interceptor->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
@@ -1319,7 +1341,8 @@ TEST_P(UpdateCheckerTest, UpdatePauseResume) {
const auto& request = post_interceptor_->GetRequestBody(0);
if (use_JSON_) {
- const auto root = base::JSONReader().Read(request);
+ const auto root = base::JSONReader::Read(request);
+ ASSERT_TRUE(root);
const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
EXPECT_EQ("0.9", app.FindKey("version")->GetString());
diff --git a/chromium/components/update_client/update_client_unittest.cc b/chromium/components/update_client/update_client_unittest.cc
index 2f67919ee11..20e2dd6dfbb 100644
--- a/chromium/components/update_client/update_client_unittest.cc
+++ b/chromium/components/update_client/update_client_unittest.cc
@@ -28,6 +28,7 @@
#include "components/prefs/testing_pref_service.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/crx_update_item.h"
+#include "components/update_client/network.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/ping_manager.h"
#include "components/update_client/protocol_parser.h"
@@ -280,7 +281,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdate) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -445,7 +446,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -646,7 +647,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateFirstServerIgnoresSecond) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -854,7 +855,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentData) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -993,7 +994,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentDataAtAll) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -1183,7 +1184,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -1474,7 +1475,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -1748,7 +1749,7 @@ TEST_F(UpdateClientTest, OneCrxInstallError) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -1997,7 +1998,7 @@ TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2216,7 +2217,7 @@ TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2363,7 +2364,7 @@ TEST_F(UpdateClientTest, OneCrxInstall) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2492,7 +2493,7 @@ TEST_F(UpdateClientTest, OneCrxInstallNoCrxComponentData) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2626,7 +2627,7 @@ TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2717,7 +2718,7 @@ TEST_F(UpdateClientTest, EmptyIdList) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -2779,7 +2780,7 @@ TEST_F(UpdateClientTest, SendUninstallPing) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return nullptr;
}
@@ -2911,7 +2912,7 @@ TEST_F(UpdateClientTest, RetryAfter) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -3154,7 +3155,7 @@ TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -3323,7 +3324,7 @@ TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -3478,7 +3479,7 @@ TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -3663,7 +3664,7 @@ TEST_F(UpdateClientTest, ActionRun_Install) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
@@ -3825,7 +3826,7 @@ TEST_F(UpdateClientTest, ActionRun_NoUpdate) {
public:
static std::unique_ptr<CrxDownloader> Create(
bool is_background_download,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory) {
return std::make_unique<MockCrxDownloader>();
}
diff --git a/chromium/components/update_client/update_engine.cc b/chromium/components/update_client/update_engine.cc
index 3340adc61ae..a6d69208e44 100644
--- a/chromium/components/update_client/update_engine.cc
+++ b/chromium/components/update_client/update_engine.cc
@@ -4,6 +4,7 @@
#include "components/update_client/update_engine.h"
+#include <algorithm>
#include <memory>
#include <utility>
@@ -199,12 +200,12 @@ void UpdateEngine::UpdateCheckResultsAvailable(
update_context->retry_after_sec = retry_after_sec;
- const int throttle_sec(update_context->retry_after_sec);
- DCHECK_LE(throttle_sec, 24 * 60 * 60);
-
// Only positive values for throttle_sec are effective. 0 means that no
- // throttling occurs and has the effect of resetting the member.
+ // throttling occurs and it resets |throttle_updates_until_|.
// Negative values are not trusted and are ignored.
+ constexpr int kMaxRetryAfterSec = 24 * 60 * 60; // 24 hours.
+ const int throttle_sec =
+ std::min(update_context->retry_after_sec, kMaxRetryAfterSec);
if (throttle_sec >= 0) {
throttle_updates_until_ =
throttle_sec ? base::TimeTicks::Now() +
diff --git a/chromium/components/update_client/updater_state.cc b/chromium/components/update_client/updater_state.cc
index f8fd5fb77fc..7178b540665 100644
--- a/chromium/components/update_client/updater_state.cc
+++ b/chromium/components/update_client/updater_state.cc
@@ -76,7 +76,7 @@ UpdaterState::Attributes UpdaterState::BuildAttributes() const {
is_autoupdate_check_enabled_ ? "1" : "0";
DCHECK((update_policy_ >= 0 && update_policy_ <= 3) || update_policy_ == -1);
- attributes["updatepolicy"] = base::IntToString(update_policy_);
+ attributes["updatepolicy"] = base::NumberToString(update_policy_);
return attributes;
}
diff --git a/chromium/components/update_client/url_fetcher_downloader.cc b/chromium/components/update_client/url_fetcher_downloader.cc
index 6742c8105fb..03eb4325a8f 100644
--- a/chromium/components/update_client/url_fetcher_downloader.cc
+++ b/chromium/components/update_client/url_fetcher_downloader.cc
@@ -15,12 +15,8 @@
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/update_client/network.h"
#include "components/update_client/utils.h"
-#include "net/base/load_flags.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/resource_response.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
namespace {
@@ -35,9 +31,9 @@ namespace update_client {
UrlFetcherDownloader::UrlFetcherDownloader(
std::unique_ptr<CrxDownloader> successor,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory)
: CrxDownloader(std::move(successor)),
- url_loader_factory_(std::move(url_loader_factory)) {}
+ network_fetcher_factory_(network_fetcher_factory) {}
UrlFetcherDownloader::~UrlFetcherDownloader() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -45,7 +41,6 @@ UrlFetcherDownloader::~UrlFetcherDownloader() {
void UrlFetcherDownloader::DoStartDownload(const GURL& url) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
base::PostTaskWithTraitsAndReply(
FROM_HERE, kTaskTraits,
base::BindOnce(&UrlFetcherDownloader::CreateDownloadDir,
@@ -62,35 +57,6 @@ void UrlFetcherDownloader::CreateDownloadDir() {
void UrlFetcherDownloader::StartURLFetch(const GURL& url) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- 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: NO
- setting: "This feature cannot be disabled."
- chrome_policy {
- ComponentUpdatesEnabled {
- policy_options {mode: MANDATORY}
- ComponentUpdatesEnabled: false
- }
- }
- })");
-
if (download_dir_.empty()) {
Result result;
result.error = -1;
@@ -110,39 +76,23 @@ void UrlFetcherDownloader::StartURLFetch(const GURL& url) {
return;
}
- const base::FilePath response =
- download_dir_.AppendASCII(url.ExtractFileName());
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = url;
- resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DISABLE_CACHE;
- url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
- traffic_annotation);
- const int kMaxRetries = 3;
- url_loader_->SetRetryOptions(
- kMaxRetries,
- network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
-
- url_loader_->SetOnResponseStartedCallback(base::BindOnce(
- &UrlFetcherDownloader::OnResponseStarted, base::Unretained(this)));
-
- // For the end-to-end system it is important that the client reports the
- // number of bytes it loaded from the server even in the case that the
- // overall network transaction failed.
- url_loader_->SetAllowPartialResults(true);
-
- VLOG(1) << "Starting background download: " << url.spec();
- url_loader_->DownloadToFile(
- url_loader_factory_.get(),
- base::BindOnce(&UrlFetcherDownloader::OnURLLoadComplete,
+ const auto file_path = download_dir_.AppendASCII(url.ExtractFileName());
+ network_fetcher_ = network_fetcher_factory_->Create();
+ network_fetcher_->DownloadToFile(
+ url, file_path,
+ base::BindOnce(&UrlFetcherDownloader::OnResponseStarted,
base::Unretained(this)),
- response);
+ base::BindRepeating(&UrlFetcherDownloader::OnDownloadProgress,
+ base::Unretained(this)),
+ base::BindOnce(&UrlFetcherDownloader::OnNetworkFetcherComplete,
+ base::Unretained(this)));
download_start_time_ = base::TimeTicks::Now();
}
-void UrlFetcherDownloader::OnURLLoadComplete(base::FilePath file_path) {
+void UrlFetcherDownloader::OnNetworkFetcherComplete(base::FilePath file_path,
+ int net_error,
+ int64_t content_size) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
const base::TimeTicks download_end_time(base::TimeTicks::Now());
@@ -154,47 +104,39 @@ void UrlFetcherDownloader::OnURLLoadComplete(base::FilePath file_path) {
// Consider a 5xx response from the server as an indication to terminate
// the request and avoid overloading the server in this case.
// is not accepting requests for the moment.
- int response_code = -1;
- if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) {
- response_code = url_loader_->ResponseInfo()->headers->response_code();
- }
-
- int fetch_error = -1;
- if (!file_path.empty() && response_code == 200) {
- fetch_error = 0;
- } else if (response_code != -1) {
- fetch_error = response_code;
+ int error = -1;
+ if (!file_path.empty() && response_code_ == 200) {
+ DCHECK_EQ(0, net_error);
+ error = 0;
+ } else if (response_code_ != -1) {
+ error = response_code_;
} else {
- fetch_error = url_loader_->NetError();
+ error = net_error;
}
- const bool is_handled = fetch_error == 0 || IsHttpServerError(fetch_error);
+ const bool is_handled = error == 0 || IsHttpServerError(error);
Result result;
- result.error = fetch_error;
- if (!fetch_error) {
+ result.error = error;
+ if (!error) {
result.response = file_path;
}
DownloadMetrics download_metrics;
download_metrics.url = url();
download_metrics.downloader = DownloadMetrics::kUrlFetcher;
- download_metrics.error = fetch_error;
+ download_metrics.error = error;
// Tests expected -1, in case of failures and no content is available.
- download_metrics.downloaded_bytes =
- fetch_error && !url_loader_->GetContentSize()
- ? -1
- : url_loader_->GetContentSize();
+ download_metrics.downloaded_bytes = error ? -1 : content_size;
download_metrics.total_bytes = total_bytes_;
download_metrics.download_time_ms = download_time.InMilliseconds();
- VLOG(1) << "Downloaded " << url_loader_->GetContentSize() << " bytes in "
- << download_time.InMilliseconds() << "ms from "
- << url_loader_->GetFinalURL().spec() << " to "
- << result.response.value();
+ VLOG(1) << "Downloaded " << content_size << " bytes in "
+ << download_time.InMilliseconds() << "ms from " << final_url_.spec()
+ << " to " << result.response.value();
// Delete the download directory in the error cases.
- if (fetch_error && !download_dir_.empty())
+ if (error && !download_dir_.empty())
base::PostTaskWithTraits(
FROM_HERE, kTaskTraits,
base::BindOnce(IgnoreResult(&base::DeleteFile), download_dir_, true));
@@ -206,15 +148,21 @@ void UrlFetcherDownloader::OnURLLoadComplete(base::FilePath file_path) {
}
// This callback is used to indicate that a download has been started.
-void UrlFetcherDownloader::OnResponseStarted(
- const GURL& final_url,
- const network::ResourceResponseHead& response_head) {
+void UrlFetcherDownloader::OnResponseStarted(const GURL& final_url,
+ int response_code,
+ int64_t content_length) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (response_head.content_length != -1)
- total_bytes_ = response_head.content_length;
+ VLOG(1) << "url fetcher response started for: " << final_url.spec();
- OnDownloadProgress();
+ final_url_ = final_url;
+ response_code_ = response_code;
+ total_bytes_ = content_length;
+}
+
+void UrlFetcherDownloader::OnDownloadProgress(int64_t current) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ CrxDownloader::OnDownloadProgress();
}
} // namespace update_client
diff --git a/chromium/components/update_client/url_fetcher_downloader.h b/chromium/components/update_client/url_fetcher_downloader.h
index 03fee0ab672..a9330b87bad 100644
--- a/chromium/components/update_client/url_fetcher_downloader.h
+++ b/chromium/components/update_client/url_fetcher_downloader.h
@@ -16,20 +16,17 @@
#include "base/time/time.h"
#include "components/update_client/crx_downloader.h"
-namespace network {
-class SharedURLLoaderFactory;
-class SimpleURLLoader;
-struct ResourceResponseHead;
-} // namespace network
-
namespace update_client {
-// Implements a CRX downloader in top of the SimpleURLLoader.
+class NetworkFetcher;
+class NetworkFetcherFactory;
+
+// Implements a CRX downloader using a NetworkFetcher object.
class UrlFetcherDownloader : public CrxDownloader {
public:
UrlFetcherDownloader(
std::unique_ptr<CrxDownloader> successor,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory);
~UrlFetcherDownloader() override;
private:
@@ -38,19 +35,26 @@ class UrlFetcherDownloader : public CrxDownloader {
void CreateDownloadDir();
void StartURLFetch(const GURL& url);
- void OnURLLoadComplete(base::FilePath file_path);
+ void OnNetworkFetcherComplete(base::FilePath file_path,
+ int net_error,
+ int64_t content_size);
void OnResponseStarted(const GURL& final_url,
- const network::ResourceResponseHead& response_head);
+ int response_code,
+ int64_t content_length);
+ void OnDownloadProgress(int64_t content_length);
+
THREAD_CHECKER(thread_checker_);
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- std::unique_ptr<network::SimpleURLLoader> url_loader_;
+ scoped_refptr<NetworkFetcherFactory> network_fetcher_factory_;
+ std::unique_ptr<NetworkFetcher> network_fetcher_;
// Contains a temporary download directory for the downloaded file.
base::FilePath download_dir_;
base::TimeTicks download_start_time_;
+ GURL final_url_;
+ int response_code_ = -1;
int64_t total_bytes_ = -1;
DISALLOW_COPY_AND_ASSIGN(UrlFetcherDownloader);
diff --git a/chromium/components/update_client/utils.cc b/chromium/components/update_client/utils.cc
index 34dc92c8d91..06fa82afdd6 100644
--- a/chromium/components/update_client/utils.cc
+++ b/chromium/components/update_client/utils.cc
@@ -24,75 +24,15 @@
#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/network.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 "net/base/load_flags.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
namespace update_client {
-std::unique_ptr<network::SimpleURLLoader> SendProtocolRequest(
- const GURL& url,
- const base::flat_map<std::string, std::string>&
- protocol_request_extra_headers,
- const std::string& protocol_request,
- network::SimpleURLLoader::BodyAsStringCallback callback,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
- 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: NO
- setting: "This feature cannot be disabled."
- chrome_policy {
- ComponentUpdatesEnabled {
- policy_options {mode: MANDATORY}
- ComponentUpdatesEnabled: false
- }
- }
- })");
- // Create and initialize URL loader.
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = url;
- resource_request->method = "POST";
- resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DISABLE_CACHE;
- for (const auto& header : protocol_request_extra_headers)
- resource_request->headers.SetHeader(header.first, header.second);
-
- auto simple_loader = network::SimpleURLLoader::Create(
- std::move(resource_request), traffic_annotation);
- const int max_retry_on_network_change = 3;
- simple_loader->SetRetryOptions(
- max_retry_on_network_change,
- network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
- simple_loader->AttachStringForUpload(protocol_request, "application/xml");
- simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- url_loader_factory.get(), std::move(callback));
- return simple_loader;
-}
-
bool HasDiffUpdate(const Component& component) {
return !component.crx_diffurls().empty();
}
diff --git a/chromium/components/update_client/utils.h b/chromium/components/update_client/utils.h
index 77fc76c178e..50e891f5f0f 100644
--- a/chromium/components/update_client/utils.h
+++ b/chromium/components/update_client/utils.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/callback_forward.h"
-#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
#include "components/update_client/update_client.h"
@@ -22,11 +21,6 @@ class DictionaryValue;
class FilePath;
}
-namespace network {
-class SharedURLLoaderFactory;
-class SimpleURLLoader;
-} // namespace network
-
namespace update_client {
class Component;
@@ -37,20 +31,6 @@ struct CrxComponent;
// in an update check request.
using InstallerAttribute = std::pair<std::string, std::string>;
-using LoadCompleteCallback =
- base::OnceCallback<void(std::unique_ptr<std::string> response_body)>;
-
-// 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.
-std::unique_ptr<network::SimpleURLLoader> SendProtocolRequest(
- const GURL& url,
- const base::flat_map<std::string, std::string>&
- protocol_request_extra_headers,
- const std::string& protocol_request,
- LoadCompleteCallback callback,
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
-
// Returns true if the |component| contains a valid differential update url.
bool HasDiffUpdate(const Component& component);
diff --git a/chromium/components/upload_list/text_log_upload_list_unittest.cc b/chromium/components/upload_list/text_log_upload_list_unittest.cc
index 9e011aa813e..91922ed25e7 100644
--- a/chromium/components/upload_list/text_log_upload_list_unittest.cc
+++ b/chromium/components/upload_list/text_log_upload_list_unittest.cc
@@ -248,7 +248,7 @@ TEST_F(TextLogUploadListTest, ParseWithState) {
test_entry += ",";
test_entry.append(kTestCaptureTime);
test_entry += ",";
- test_entry.append(base::IntToString(
+ test_entry.append(base::NumberToString(
static_cast<int>(UploadList::UploadInfo::State::Uploaded)));
test_entry += "\n";
}
diff --git a/chromium/components/url_formatter/elide_url.cc b/chromium/components/url_formatter/elide_url.cc
index 77cd4dd0a99..a629cc4769e 100644
--- a/chromium/components/url_formatter/elide_url.cc
+++ b/chromium/components/url_formatter/elide_url.cc
@@ -432,7 +432,7 @@ base::string16 FormatOriginForSecurityDisplay(
const int default_port = url::DefaultPortForScheme(
scheme.data(), static_cast<int>(scheme.length()));
if (port != 0 && port != default_port)
- result += colon + base::UintToString16(origin.port());
+ result += colon + base::NumberToString16(origin.port());
return result;
}
diff --git a/chromium/components/url_formatter/top_domains/BUILD.gn b/chromium/components/url_formatter/top_domains/BUILD.gn
index 5edcf0d5015..04dcc164007 100644
--- a/chromium/components/url_formatter/top_domains/BUILD.gn
+++ b/chromium/components/url_formatter/top_domains/BUILD.gn
@@ -119,3 +119,30 @@ compiled_action("generate_top_domains_for_edit_distance") {
args =
rebase_path(inputs, root_build_dir) + rebase_path(outputs, root_build_dir)
}
+
+# top500_domains and top500_domains_header are intentionally separated to remove
+# serialized build dependency from some targets to
+# generate_top_domains_for_edit_distance action target.
+source_set("top500_domains") {
+ # This empty public is intentional to remove unnecessary build dependency.
+ public = []
+
+ visibility = [ ":top500_domains_header" ]
+
+ sources = [
+ "$target_gen_dir/top500-domains-inc.cc",
+ ]
+
+ deps = [
+ ":generate_top_domains_for_edit_distance",
+ ]
+}
+
+source_set("top500_domains_header") {
+ sources = [
+ "top500_domains.h",
+ ]
+ deps = [
+ ":top500_domains",
+ ]
+}
diff --git a/chromium/components/url_formatter/top_domains/make_top_domain_list_for_edit_distance.cc b/chromium/components/url_formatter/top_domains/make_top_domain_list_for_edit_distance.cc
index a85649a2497..95a641f5cd6 100644
--- a/chromium/components/url_formatter/top_domains/make_top_domain_list_for_edit_distance.cc
+++ b/chromium/components/url_formatter/top_domains/make_top_domain_list_for_edit_distance.cc
@@ -96,13 +96,17 @@ int main(int argc, char* argv[]) {
}
size_t count = 0;
- std::string output = "const char* const kTop500[] = {";
+ std::string output =
+ R"(#include "components/url_formatter/top_domains/top500_domains.h"
+namespace top500_domains {
+const char* const kTop500[500] = {
+)";
for (std::string line : lines) {
base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line);
if (line.empty() || line[0] == '#') {
continue;
}
- if (count > kTopN)
+ if (count >= kTopN)
break;
if (!url_formatter::top_domains::IsEditDistanceCandidate(line)) {
continue;
@@ -111,7 +115,9 @@ int main(int argc, char* argv[]) {
const std::string skeleton = GetSkeleton(line, spoof_checker.get());
output += "\"" + skeleton + "\",\n";
}
- output += "};\n";
+ output += R"(};
+} // namespace top500_domains
+)";
base::FilePath output_path = base::FilePath::FromUTF8Unsafe(argv[2]);
if (base::WriteFile(output_path, output.c_str(),
diff --git a/chromium/components/url_formatter/top_domains/top500_domains.h b/chromium/components/url_formatter/top_domains/top500_domains.h
new file mode 100644
index 00000000000..ed0667d1927
--- /dev/null
+++ b/chromium/components/url_formatter/top_domains/top500_domains.h
@@ -0,0 +1,13 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP500_DOMAINS_H_
+#define COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP500_DOMAINS_H_
+
+namespace top500_domains {
+
+extern const char* const kTop500[500];
+
+} // namespace top500_domains
+
+#endif // COMPONENTS_URL_FORMATTER_TOP_DOMAINS_TOP500_DOMAINS_H_
diff --git a/chromium/components/url_pattern_index/fuzzy_pattern_matching.h b/chromium/components/url_pattern_index/fuzzy_pattern_matching.h
index 52dc75b4069..3feb7701706 100644
--- a/chromium/components/url_pattern_index/fuzzy_pattern_matching.h
+++ b/chromium/components/url_pattern_index/fuzzy_pattern_matching.h
@@ -6,8 +6,10 @@
// separator character, which is any ASCII symbol except letters, digits, and
// the following: '_', '-', '.', '%'. Note that the separator placeholder
// character '^' is itself a separator, as well as '\0'.
-// TODO(pkalinnikov): In addition, a separator placeholder at the end of the
-// pattern can be matched by the end of |text|.
+//
+// In addition, a separator placeholder at the end of the pattern can be matched
+// by the end of |text|. This should be handled by the clients using the
+// following utility functions.
//
// We define a fuzzy occurrence as an occurrence of a |subpattern| in |text|
// such that all its non-placeholder characters are equal to the corresponding
diff --git a/chromium/components/url_pattern_index/url_pattern.cc b/chromium/components/url_pattern_index/url_pattern.cc
index a9762fa1560..1d914efabef 100644
--- a/chromium/components/url_pattern_index/url_pattern.cc
+++ b/chromium/components/url_pattern_index/url_pattern.cc
@@ -33,9 +33,11 @@ namespace url_pattern_index {
namespace {
+constexpr char kWildcard = '*';
+
class IsWildcard {
public:
- bool operator()(char c) const { return c == '*'; }
+ bool operator()(char c) const { return c == kWildcard; }
};
proto::UrlPatternType ConvertUrlPatternType(flat::UrlPatternType type) {
@@ -144,6 +146,80 @@ size_t FindSubdomainAnchoredSubpattern(base::StringPiece url,
return base::StringPiece::npos;
}
+// Helper for DoesTextMatchLastSubpattern. Treats kSeparatorPlaceholder as not
+// matching the end of the text.
+bool DoesTextMatchLastSubpatternInternal(proto::AnchorType anchor_left,
+ proto::AnchorType anchor_right,
+ base::StringPiece text,
+ url::Component url_host,
+ base::StringPiece subpattern) {
+ // Enumerate all possible combinations of |anchor_left| and |anchor_right|.
+ if (anchor_left == proto::ANCHOR_TYPE_NONE &&
+ anchor_right == proto::ANCHOR_TYPE_NONE) {
+ return FindSubpattern(text, subpattern) != base::StringPiece::npos;
+ }
+
+ if (anchor_left == proto::ANCHOR_TYPE_NONE &&
+ anchor_right == proto::ANCHOR_TYPE_BOUNDARY) {
+ return EndsWithFuzzy(text, subpattern);
+ }
+
+ if (anchor_left == proto::ANCHOR_TYPE_BOUNDARY &&
+ anchor_right == proto::ANCHOR_TYPE_NONE) {
+ return StartsWithFuzzy(text, subpattern);
+ }
+
+ if (anchor_left == proto::ANCHOR_TYPE_BOUNDARY &&
+ anchor_right == proto::ANCHOR_TYPE_BOUNDARY) {
+ return text.size() == subpattern.size() &&
+ StartsWithFuzzy(text, subpattern);
+ }
+
+ if (anchor_left == proto::ANCHOR_TYPE_SUBDOMAIN &&
+ anchor_right == proto::ANCHOR_TYPE_NONE) {
+ return url_host.is_nonempty() &&
+ FindSubdomainAnchoredSubpattern(text, url_host, subpattern) !=
+ base::StringPiece::npos;
+ }
+
+ if (anchor_left == proto::ANCHOR_TYPE_SUBDOMAIN &&
+ anchor_right == proto::ANCHOR_TYPE_BOUNDARY) {
+ return url_host.is_nonempty() && text.size() >= subpattern.size() &&
+ IsSubdomainAnchored(text, url_host,
+ text.size() - subpattern.size()) &&
+ EndsWithFuzzy(text, subpattern);
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+// Matches the last |subpattern| against |text|. Special treatment is required
+// for the last subpattern since |kSeparatorPlaceholder| can also match the end
+// of the text.
+bool DoesTextMatchLastSubpattern(proto::AnchorType anchor_left,
+ proto::AnchorType anchor_right,
+ base::StringPiece text,
+ url::Component url_host,
+ base::StringPiece subpattern) {
+ DCHECK(!subpattern.empty());
+
+ if (DoesTextMatchLastSubpatternInternal(anchor_left, anchor_right, text,
+ url_host, subpattern)) {
+ return true;
+ }
+
+ // If the last |subpattern| ends with kSeparatorPlaceholder, then it can also
+ // match the end of text.
+ if (subpattern.back() == kSeparatorPlaceholder) {
+ subpattern.remove_suffix(1);
+ return DoesTextMatchLastSubpatternInternal(
+ anchor_left, proto::ANCHOR_TYPE_BOUNDARY, text, url_host, subpattern);
+ }
+
+ return false;
+}
+
// Returns whether the given |url_pattern| matches the given |url_spec|.
// Compares the pattern the the url in a case-sensitive manner.
bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
@@ -157,6 +233,7 @@ bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
auto subpattern_it = subpatterns.begin();
auto subpattern_end = subpatterns.end();
+ // No subpatterns.
if (subpattern_it == subpattern_end) {
return anchor_left == proto::ANCHOR_TYPE_NONE ||
anchor_right == proto::ANCHOR_TYPE_NONE;
@@ -165,22 +242,10 @@ bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
base::StringPiece subpattern = *subpattern_it;
++subpattern_it;
- // If there is only one |subpattern|, and it has a right anchor, then simply
- // check that it is a suffix of the |url_spec|, and the left anchor is
- // fulfilled.
- if (subpattern_it == subpattern_end &&
- anchor_right == proto::ANCHOR_TYPE_BOUNDARY) {
- if (!EndsWithFuzzy(url_spec, subpattern))
- return false;
- if (anchor_left == proto::ANCHOR_TYPE_BOUNDARY)
- return url_spec.size() == subpattern.size();
- if (anchor_left == proto::ANCHOR_TYPE_SUBDOMAIN) {
- DCHECK_LE(subpattern.size(), url_spec.size());
- return url_host.is_nonempty() &&
- IsSubdomainAnchored(url_spec, url_host,
- url_spec.size() - subpattern.size());
- }
- return true;
+ // There is only one |subpattern|.
+ if (subpattern_it == subpattern_end) {
+ return DoesTextMatchLastSubpattern(anchor_left, anchor_right, url_spec,
+ url_host, subpattern);
}
// Otherwise, the first |subpattern| does not have to be a suffix. But it
@@ -189,10 +254,6 @@ bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
if (anchor_left == proto::ANCHOR_TYPE_BOUNDARY) {
if (!StartsWithFuzzy(url_spec, subpattern))
return false;
- if (subpattern_it == subpattern_end) {
- DCHECK_EQ(anchor_right, proto::ANCHOR_TYPE_NONE);
- return true;
- }
text.remove_prefix(subpattern.size());
} else if (anchor_left == proto::ANCHOR_TYPE_SUBDOMAIN) {
if (!url_host.is_nonempty())
@@ -201,10 +262,6 @@ bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
FindSubdomainAnchoredSubpattern(url_spec, url_host, subpattern);
if (match_begin == base::StringPiece::npos)
return false;
- if (subpattern_it == subpattern_end) {
- DCHECK_EQ(anchor_right, proto::ANCHOR_TYPE_NONE);
- return true;
- }
text.remove_prefix(match_begin + subpattern.size());
} else {
DCHECK_EQ(anchor_left, proto::ANCHOR_TYPE_NONE);
@@ -212,26 +269,24 @@ bool IsCaseSensitiveMatch(base::StringPiece url_pattern,
subpattern_it = subpatterns.begin();
}
- // Consecutively find all the remaining subpatterns in the |text|. If the
- // pattern has a right anchor, don't search for the last subpattern, but
- // instead check that it is a suffix of the |text|.
- while (subpattern_it != subpattern_end) {
- subpattern = *subpattern_it;
- DCHECK(!subpattern.empty());
+ DCHECK(subpattern_it != subpattern_end);
+ subpattern = *subpattern_it;
- if (++subpattern_it == subpattern_end &&
- anchor_right == proto::ANCHOR_TYPE_BOUNDARY) {
- break;
- }
+ // Consecutively find all the remaining subpatterns in the |text|. Handle the
+ // last subpattern outside the loop.
+ while (++subpattern_it != subpattern_end) {
+ DCHECK(!subpattern.empty());
const size_t match_position = FindSubpattern(text, subpattern);
if (match_position == base::StringPiece::npos)
return false;
text.remove_prefix(match_position + subpattern.size());
+
+ subpattern = *subpattern_it;
}
- return anchor_right != proto::ANCHOR_TYPE_BOUNDARY ||
- EndsWithFuzzy(text, subpattern);
+ return DoesTextMatchLastSubpattern(proto::ANCHOR_TYPE_NONE, anchor_right,
+ text, url::Component(), subpattern);
}
} // namespace
@@ -290,15 +345,30 @@ bool UrlPattern::MatchesUrl(const UrlInfo& url) const {
DCHECK(base::IsStringASCII(url.spec()));
DCHECK(base::IsStringASCII(url.GetLowerCaseSpec()));
+ // Pre-process patterns to ensure left anchored and right anchored patterns
+ // don't begin and end with a wildcard respectively i.e. change "|*xyz" to
+ // "*xyz" and "xyz*|" to "xyz*".
+ proto::AnchorType anchor_left = anchor_left_;
+ proto::AnchorType anchor_right = anchor_right_;
+ if (!url_pattern_.empty()) {
+ if (url_pattern_.front() == kWildcard) {
+ // Note: We don't handle "||*" and expect clients to disallow it.
+ DCHECK_NE(proto::ANCHOR_TYPE_SUBDOMAIN, anchor_left_);
+ anchor_left = proto::ANCHOR_TYPE_NONE;
+ }
+ if (url_pattern_.back() == kWildcard)
+ anchor_right = proto::ANCHOR_TYPE_NONE;
+ }
+
if (match_case()) {
- return IsCaseSensitiveMatch(url_pattern_, anchor_left_, anchor_right_,
+ return IsCaseSensitiveMatch(url_pattern_, anchor_left, anchor_right,
url.spec(), url.host());
}
// Use the lower-cased url for case-insensitive comparison. Case-insensitive
// patterns should already be lower-cased.
DCHECK(!HasAnyUpperAscii(url_pattern_));
- return IsCaseSensitiveMatch(url_pattern_, anchor_left_, anchor_right_,
+ return IsCaseSensitiveMatch(url_pattern_, anchor_left, anchor_right,
url.GetLowerCaseSpec(), url.host());
}
diff --git a/chromium/components/url_pattern_index/url_pattern_index.cc b/chromium/components/url_pattern_index/url_pattern_index.cc
index a2d96a80396..ad885a3f5e6 100644
--- a/chromium/components/url_pattern_index/url_pattern_index.cc
+++ b/chromium/components/url_pattern_index/url_pattern_index.cc
@@ -343,6 +343,13 @@ class UrlRuleFlatBufferConverter {
if (anchor_right_ == flat::AnchorType_SUBDOMAIN)
return false; // Unsupported right anchor.
+ // We disallow patterns like "||*xyz" because it isn't clear how to match
+ // them.
+ if (anchor_left_ == flat::AnchorType_SUBDOMAIN &&
+ (!rule_.url_pattern().empty() && rule_.url_pattern().front() == '*')) {
+ return false;
+ }
+
return true;
}
diff --git a/chromium/components/url_pattern_index/url_pattern_index.h b/chromium/components/url_pattern_index/url_pattern_index.h
index ec1dc9599b5..0262664e02b 100644
--- a/chromium/components/url_pattern_index/url_pattern_index.h
+++ b/chromium/components/url_pattern_index/url_pattern_index.h
@@ -83,7 +83,7 @@ int CompareDomains(base::StringPiece lhs_domain, base::StringPiece rhs_domain);
// Increase this value when introducing an incompatible change to the
// UrlPatternIndex schema (flat/url_pattern_index.fbs). url_pattern_index
// clients can use this as a signal to rebuild rulesets.
-constexpr int kUrlPatternIndexFormatVersion = 4;
+constexpr int kUrlPatternIndexFormatVersion = 5;
// 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
diff --git a/chromium/components/url_pattern_index/url_pattern_unittest.cc b/chromium/components/url_pattern_index/url_pattern_unittest.cc
index d067d128e03..a2c642a4b42 100644
--- a/chromium/components/url_pattern_index/url_pattern_unittest.cc
+++ b/chromium/components/url_pattern_index/url_pattern_unittest.cc
@@ -90,7 +90,9 @@ TEST(UrlPatternTest, MatchesUrl) {
{{"^^a^^"}, "http://ex.com/?a=/", true},
{{"^^a^^"}, "http://ex.com/?a=/&b=0", true},
- {{"^^a^^"}, "http://ex.com/?a=", false},
+ {{"^^a^^"}, "http://ex.com/?a=x", false},
+ // The last ^ matches the end of the url.
+ {{"^^a^^"}, "http://ex.com/?a=", true},
{{"ex.com^path^*k=v^"}, "http://ex.com/path/?k1=v1&ak=v&kk=vv", true},
{{"ex.com^path^*k=v^"}, "http://ex.com/p/path/?k1=v1&ak=v&kk=vv", false},
@@ -152,6 +154,42 @@ TEST(UrlPatternTest, MatchesUrl) {
{{"abc*def^", proto::URL_PATTERN_TYPE_WILDCARDED, kDonotMatchCase},
"http://a.com/abcxAdef/vo",
true},
+ {{"abc^", kAnchorNone, kAnchorNone}, "https://xyz.com/abc/123", true},
+ {{"abc^", kAnchorNone, kAnchorNone}, "https://xyz.com/abc", true},
+ {{"abc^", kAnchorNone, kAnchorNone}, "https://abc.com", false},
+ {{"abc^", kAnchorNone, kBoundary}, "https://xyz.com/abc/", true},
+ {{"abc^", kAnchorNone, kBoundary}, "https://xyz.com/abc", true},
+ {{"abc^", kAnchorNone, kBoundary}, "https://xyz.com/abc/123", false},
+ {{"http://abc.com/x^", kBoundary, kAnchorNone}, "http://abc.com/x", true},
+ {{"http://abc.com/x^", kBoundary, kAnchorNone},
+ "http://abc.com/x/",
+ true},
+ {{"http://abc.com/x^", kBoundary, kAnchorNone},
+ "http://abc.com/x/123",
+ true},
+ {{"http://abc.com/x^", kBoundary, kBoundary}, "http://abc.com/x", true},
+ {{"http://abc.com/x^", kBoundary, kBoundary}, "http://abc.com/x/", true},
+ {{"http://abc.com/x^", kBoundary, kBoundary},
+ "http://abc.com/x/123",
+ false},
+ {{"abc.com^", kSubdomain, kAnchorNone}, "http://xyz.abc.com/123", true},
+ {{"abc.com^", kSubdomain, kAnchorNone}, "http://xyz.abc.com", true},
+ {{"abc.com^", kSubdomain, kAnchorNone},
+ "http://abc.com.xyz.com?q=abc.com",
+ false},
+ {{"abc.com^", kSubdomain, kBoundary}, "http://xyz.abc.com/123", false},
+ {{"abc.com^", kSubdomain, kBoundary}, "http://xyz.abc.com", true},
+ {{"abc.com^", kSubdomain, kBoundary},
+ "http://abc.com.xyz.com?q=abc.com/",
+ false},
+ {{"abc*^", kAnchorNone, kAnchorNone}, "https://abc.com", true},
+ {{"abc*^", kAnchorNone, kAnchorNone}, "https://abc.com?q=123", true},
+ {{"abc*^", kAnchorNone, kBoundary}, "https://abc.com", true},
+ {{"abc*^", kAnchorNone, kBoundary}, "https://abc.com?q=123", true},
+ {{"abc*", kAnchorNone, kBoundary}, "https://a.com/abcxyz", true},
+ {{"*google.com", kBoundary, kAnchorNone}, "https://www.google.com", true},
+ {{"*", kBoundary, kBoundary}, "https://example.com", true},
+ {{"", kBoundary, kBoundary}, "https://example.com", false},
};
for (const auto& test_case : kTestCases) {
diff --git a/chromium/components/user_manager/fake_user_manager.cc b/chromium/components/user_manager/fake_user_manager.cc
index d32da8bd9f8..45dd014a4ef 100644
--- a/chromium/components/user_manager/fake_user_manager.cc
+++ b/chromium/components/user_manager/fake_user_manager.cc
@@ -56,10 +56,6 @@ const user_manager::User* FakeUserManager::AddUserWithAffiliation(
return user;
}
-void FakeUserManager::OnProfileInitialized(User* user) {
- user->set_profile_ever_initialized(true);
-}
-
void FakeUserManager::RemoveUserFromList(const AccountId& account_id) {
const user_manager::UserList::iterator it =
std::find_if(users_.begin(), users_.end(),
diff --git a/chromium/components/user_manager/fake_user_manager.h b/chromium/components/user_manager/fake_user_manager.h
index 48b4e494d53..4f877753698 100644
--- a/chromium/components/user_manager/fake_user_manager.h
+++ b/chromium/components/user_manager/fake_user_manager.h
@@ -61,7 +61,6 @@ class USER_MANAGER_EXPORT FakeUserManager : public UserManagerBase {
user_manager::UserList GetUnlockUsers() const override;
const AccountId& GetOwnerAccountId() const override;
void OnSessionStarted() override {}
- void OnProfileInitialized(User* user) override;
void RemoveUser(const AccountId& account_id,
user_manager::RemoveUserDelegate* delegate) override {}
void RemoveUserFromList(const AccountId& account_id) override;
diff --git a/chromium/components/user_manager/known_user.cc b/chromium/components/user_manager/known_user.cc
index 44a5bdd9a33..8501c20d359 100644
--- a/chromium/components/user_manager/known_user.cc
+++ b/chromium/components/user_manager/known_user.cc
@@ -54,9 +54,6 @@ const char kReauthReasonKey[] = "reauth_reason";
// Key for the GaiaId migration status.
const char kGaiaIdMigration[] = "gaia_id_migration";
-// Key of the boolean flag telling if user session has finished init yet.
-const char kProfileEverInitialized[] = "profile_ever_initialized";
-
// Key of the boolean flag telling if a minimal user home migration has been
// attempted.
const char kMinimalMigrationAttempted[] = "minimal_migration_attempted";
@@ -488,19 +485,6 @@ bool IsUsingSAML(const AccountId& account_id) {
return false;
}
-bool WasProfileEverInitialized(const AccountId& account_id) {
- bool profile_ever_initialized;
- if (GetBooleanPref(account_id, kProfileEverInitialized,
- &profile_ever_initialized)) {
- return profile_ever_initialized;
- }
- return false;
-}
-
-void SetProfileEverInitialized(const AccountId& account_id, bool initialized) {
- SetBooleanPref(account_id, kProfileEverInitialized, initialized);
-}
-
void SetProfileRequiresPolicy(const AccountId& account_id,
ProfileRequiresPolicy required) {
DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
diff --git a/chromium/components/user_manager/known_user.h b/chromium/components/user_manager/known_user.h
index 52a92fb53a5..a76f7faa563 100644
--- a/chromium/components/user_manager/known_user.h
+++ b/chromium/components/user_manager/known_user.h
@@ -136,17 +136,6 @@ void USER_MANAGER_EXPORT UpdateUsingSAML(const AccountId& account_id,
// returns false.
bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id);
-// Returns true if the user's session has already completed initialization
-// (set to false when session is created, and then is set to true once
-// the profile is intiaiized - this allows us to detect crashes/restarts during
-// initial session creation so we can recover gracefully).
-bool USER_MANAGER_EXPORT WasProfileEverInitialized(const AccountId& account_id);
-
-// Sets the flag that denotes whether the session associated with a user has
-// completed initialization at least once.
-void USER_MANAGER_EXPORT SetProfileEverInitialized(const AccountId& account_id,
- bool initialized);
-
// Enum describing whether a user's profile requires policy. If kPolicyRequired,
// the profile initialization code will ensure that valid policy is loaded
// before session initialization completes.
diff --git a/chromium/components/user_manager/user.h b/chromium/components/user_manager/user.h
index a2712362674..9dc31a0a235 100644
--- a/chromium/components/user_manager/user.h
+++ b/chromium/components/user_manager/user.h
@@ -161,14 +161,6 @@ class USER_MANAGER_EXPORT User : public UserInfo {
// user's next sign-in.
bool force_online_signin() const { return force_online_signin_; }
- // Whether the user's session has completed initialization yet.
- bool profile_ever_initialized() const { return profile_ever_initialized_; }
-
- // Public so it can be called via tests.
- void set_profile_ever_initialized(bool profile_ever_initialized) {
- profile_ever_initialized_ = profile_ever_initialized;
- }
-
// True if the user's session can be locked (i.e. the user has a password with
// which to unlock the session).
bool can_lock() const;
@@ -289,7 +281,6 @@ class USER_MANAGER_EXPORT User : public UserInfo {
std::unique_ptr<UserImage> user_image_;
OAuthTokenStatus oauth_token_status_ = OAUTH_TOKEN_STATUS_UNKNOWN;
bool force_online_signin_ = false;
- bool profile_ever_initialized_ = false;
// This is set to chromeos locale if account data has been downloaded.
// (Or failed to download, but at least one download attempt finished).
diff --git a/chromium/components/user_manager/user_manager.h b/chromium/components/user_manager/user_manager.h
index cf398fad8ff..d13ef14307a 100644
--- a/chromium/components/user_manager/user_manager.h
+++ b/chromium/components/user_manager/user_manager.h
@@ -174,14 +174,6 @@ class USER_MANAGER_EXPORT UserManager {
// Invoked by session manager to inform session start.
virtual void OnSessionStarted() = 0;
- // Invoked once profile initialization has been completed. This allows various
- // subsystems (for example, policy framework) to skip an expensive online
- // initialization process, and also allows the signin screen to force an
- // online signin if it knows that profile initialization has not yet
- // completed. |user| is the User associated with the profile that has
- // completed initialization.
- virtual void OnProfileInitialized(User* user) = 0;
-
// Removes the user from the device. Note, it will verify that the given user
// isn't the owner, so calling this method for the owner will take no effect.
// Note, |delegate| can be NULL.
@@ -324,10 +316,6 @@ class USER_MANAGER_EXPORT UserManager {
const gfx::ImageSkia& profile_image) = 0;
virtual void NotifyUsersSignInConstraintsChanged() = 0;
- // Resets this profile to be regarded as if it has never been initialized
- // before. Used on profile wipe.
- virtual void ResetProfileEverInitialized(const AccountId& account_id) = 0;
-
// Returns true if supervised users allowed.
virtual bool AreSupervisedUsersAllowed() const = 0;
diff --git a/chromium/components/user_manager/user_manager_base.cc b/chromium/components/user_manager/user_manager_base.cc
index a0be5b732ca..5e050b7db5e 100644
--- a/chromium/components/user_manager/user_manager_base.cc
+++ b/chromium/components/user_manager/user_manager_base.cc
@@ -94,7 +94,7 @@ UserType GetStoredUserType(const base::DictionaryValue* prefs_user_types,
// Feature that hides Supervised Users.
const base::Feature kHideSupervisedUsers{"HideSupervisedUsers",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// static
void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
@@ -306,16 +306,6 @@ void UserManagerBase::OnSessionStarted() {
GetLocalState()->CommitPendingWrite();
}
-void UserManagerBase::OnProfileInitialized(User* user) {
- DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
-
- // Mark the user as having an initialized session and persist this in
- // the known_user DB.
- user->set_profile_ever_initialized(true);
- known_user::SetProfileEverInitialized(user->GetAccountId(), true);
- GetLocalState()->CommitPendingWrite();
-}
-
void UserManagerBase::RemoveUser(const AccountId& account_id,
RemoveUserDelegate* delegate) {
DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
@@ -333,19 +323,28 @@ void UserManagerBase::RemoveUserInternal(const AccountId& account_id,
void UserManagerBase::RemoveNonOwnerUserInternal(const AccountId& account_id,
RemoveUserDelegate* delegate) {
+ // If account_id points to AccountId in User object, it will become deleted
+ // after RemoveUserFromList(), which could lead to use-after-free in observer.
+ // TODO(https://crbug.com/928534): Update user removal flow to prevent this.
+ const AccountId account_id_copy(account_id);
+
if (delegate)
delegate->OnBeforeUserRemoved(account_id);
AsyncRemoveCryptohome(account_id);
RemoveUserFromList(account_id);
if (delegate)
- delegate->OnUserRemoved(account_id);
+ delegate->OnUserRemoved(account_id_copy);
}
void UserManagerBase::RemoveUserFromList(const AccountId& account_id) {
DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
RemoveNonCryptohomeData(account_id);
+ known_user::RemovePrefs(account_id);
if (user_loading_stage_ == STAGE_LOADED) {
+ // After the User object is deleted from memory in DeleteUser() here,
+ // the account_id reference will be invalid if the reference points
+ // to the account_id in the User object.
DeleteUser(
RemoveRegularOrSupervisedUserFromList(account_id, true /* notify */));
} else if (user_loading_stage_ == STAGE_LOADING) {
@@ -360,8 +359,6 @@ void UserManagerBase::RemoveUserFromList(const AccountId& account_id) {
return;
}
- known_user::RemovePrefs(account_id);
-
// Make sure that new data is persisted to Local State.
GetLocalState()->CommitPendingWrite();
}
@@ -841,8 +838,6 @@ void UserManagerBase::EnsureUsersLoaded() {
}
user->set_oauth_token_status(LoadUserOAuthStatus(*it));
user->set_force_online_signin(LoadForceOnlineSignin(*it));
- user->set_profile_ever_initialized(
- known_user::WasProfileEverInitialized(*it));
user->set_using_saml(known_user::IsUsingSAML(*it));
users_.push_back(user);
@@ -933,8 +928,6 @@ void UserManagerBase::RegularUserLoggedIn(const AccountId& account_id,
active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id));
SaveUserDisplayName(active_user_->GetAccountId(),
base::UTF8ToUTF16(active_user_->GetAccountName(true)));
- known_user::SetProfileEverInitialized(
- active_user_->GetAccountId(), active_user_->profile_ever_initialized());
} else {
SaveUserType(active_user_);
}
@@ -1069,18 +1062,6 @@ void UserManagerBase::NotifyActiveUserHashChanged(const std::string& hash) {
observer.ActiveUserHashChanged(hash);
}
-void UserManagerBase::ResetProfileEverInitialized(const AccountId& account_id) {
- User* user = FindUserAndModify(account_id);
- if (!user) {
- LOG(ERROR) << "User not found: " << account_id.GetUserEmail();
- return; // Ignore if there is no such user.
- }
-
- user->set_profile_ever_initialized(false);
- known_user::SetProfileEverInitialized(user->GetAccountId(), false);
- GetLocalState()->CommitPendingWrite();
-}
-
void UserManagerBase::Initialize() {
UserManager::Initialize();
if (!HasBrowserRestarted())
diff --git a/chromium/components/user_manager/user_manager_base.h b/chromium/components/user_manager/user_manager_base.h
index cfa5e7fb931..886191ca1bd 100644
--- a/chromium/components/user_manager/user_manager_base.h
+++ b/chromium/components/user_manager/user_manager_base.h
@@ -61,7 +61,6 @@ class USER_MANAGER_EXPORT UserManagerBase : public UserManager {
void SwitchActiveUser(const AccountId& account_id) override;
void SwitchToLastActiveUser() override;
void OnSessionStarted() override;
- void OnProfileInitialized(User* user) override;
void RemoveUser(const AccountId& account_id,
RemoveUserDelegate* delegate) override;
void RemoveUserFromList(const AccountId& account_id) override;
@@ -115,7 +114,6 @@ class USER_MANAGER_EXPORT UserManagerBase : public UserManager {
const User& user,
const gfx::ImageSkia& profile_image) override;
void NotifyUsersSignInConstraintsChanged() override;
- void ResetProfileEverInitialized(const AccountId& account_id) override;
void Initialize() override;
// This method updates "User was added to the device in this session nad is
diff --git a/chromium/components/user_manager/user_unittest.cc b/chromium/components/user_manager/user_unittest.cc
index f5ff2037c41..96265ab964f 100644
--- a/chromium/components/user_manager/user_unittest.cc
+++ b/chromium/components/user_manager/user_unittest.cc
@@ -44,13 +44,4 @@ TEST(UserTest, DeviceLocalAccountAffiliation) {
EXPECT_TRUE(arc_kiosk_user.IsAffiliated());
}
-TEST(UserTest, UserSessionInitialized) {
- const AccountId account_id = AccountId::FromUserEmailGaiaId(kEmail, kGaiaId);
- std::unique_ptr<User> user(
- User::CreateRegularUser(account_id, user_manager::USER_TYPE_REGULAR));
- EXPECT_FALSE(user->profile_ever_initialized());
- user->set_profile_ever_initialized(true);
- EXPECT_TRUE(user->profile_ever_initialized());
-}
-
} // namespace user_manager
diff --git a/chromium/components/variations/BUILD.gn b/chromium/components/variations/BUILD.gn
index c764b7d13ea..5caa15ce040 100644
--- a/chromium/components/variations/BUILD.gn
+++ b/chromium/components/variations/BUILD.gn
@@ -21,8 +21,6 @@ static_library("variations") {
"client_filterable_state.h",
"entropy_provider.cc",
"entropy_provider.h",
- "experiment_labels.cc",
- "experiment_labels.h",
"hashing.cc",
"hashing.h",
"metrics.cc",
@@ -49,8 +47,6 @@ static_library("variations") {
"variations_associated_data.h",
"variations_crash_keys.cc",
"variations_crash_keys.h",
- "variations_experiment_util.cc",
- "variations_experiment_util.h",
"variations_http_header_provider.cc",
"variations_http_header_provider.h",
"variations_id_collection.cc",
@@ -103,12 +99,16 @@ if (is_android) {
}
android_library("load_seed_result_enum_java") {
- deps = [ "//base:base_java" ]
+ deps = [
+ "//base:base_java",
+ ]
srcjar_deps = [ ":load_seed_result_enum_srcjar" ]
}
java_cpp_enum("load_seed_result_enum_srcjar") {
- sources = [ "metrics.h" ]
+ sources = [
+ "metrics.h",
+ ]
}
}
@@ -135,7 +135,6 @@ source_set("unit_tests") {
"active_field_trials_unittest.cc",
"child_process_field_trial_syncer_unittest.cc",
"entropy_provider_unittest.cc",
- "experiment_labels_unittest.cc",
"hashing_unittest.cc",
"net/variations_command_line_unittest.cc",
"net/variations_http_headers_unittest.cc",
diff --git a/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java b/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
index 08081611f02..01054b79c19 100644
--- a/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
+++ b/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
@@ -6,6 +6,7 @@ package org.chromium.components.variations.firstrun;
import android.content.SharedPreferences;
import android.os.SystemClock;
+import android.support.annotation.IntDef;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
@@ -17,6 +18,8 @@ import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
@@ -27,7 +30,6 @@ import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
-import java.util.concurrent.TimeUnit;
/**
* Fetches the variations seed before the actual first run of Chrome.
@@ -35,7 +37,12 @@ import java.util.concurrent.TimeUnit;
public class VariationsSeedFetcher {
private static final String TAG = "VariationsSeedFetch";
- public enum VariationsPlatform { ANDROID, ANDROID_WEBVIEW }
+ @IntDef({VariationsPlatform.ANDROID, VariationsPlatform.ANDROID_WEBVIEW})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VariationsPlatform {
+ int ANDROID = 0;
+ int ANDROID_WEBVIEW = 1;
+ }
private static final String VARIATIONS_SERVER_URL =
"https://clientservices.googleapis.com/chrome-variations/seed?osname=";
@@ -85,7 +92,7 @@ public class VariationsSeedFetcher {
@VisibleForTesting
protected HttpURLConnection getServerConnection(
- VariationsPlatform platform, String restrictMode, String milestone, String channel)
+ @VariationsPlatform int platform, String restrictMode, String milestone, String channel)
throws MalformedURLException, IOException {
String urlString = getConnectionString(platform, restrictMode, milestone, channel);
URL url = new URL(urlString);
@@ -93,14 +100,14 @@ public class VariationsSeedFetcher {
}
@VisibleForTesting
- protected String getConnectionString(
- VariationsPlatform platform, String restrictMode, String milestone, String channel) {
+ protected String getConnectionString(@VariationsPlatform int platform, String restrictMode,
+ String milestone, String channel) {
String urlString = VARIATIONS_SERVER_URL;
switch (platform) {
- case ANDROID:
+ case VariationsPlatform.ANDROID:
urlString += "android";
break;
- case ANDROID_WEBVIEW:
+ case VariationsPlatform.ANDROID_WEBVIEW:
urlString += "android_webview";
break;
default:
@@ -192,14 +199,14 @@ public class VariationsSeedFetcher {
private void recordSeedFetchTime(long timeDeltaMillis) {
Log.i(TAG, "Fetched first run seed in " + timeDeltaMillis + " ms");
- TimesHistogramSample histogram = new TimesHistogramSample(
- "Variations.FirstRun.SeedFetchTime", TimeUnit.MILLISECONDS);
+ TimesHistogramSample histogram =
+ new TimesHistogramSample("Variations.FirstRun.SeedFetchTime");
histogram.record(timeDeltaMillis);
}
private void recordSeedConnectTime(long timeDeltaMillis) {
- TimesHistogramSample histogram = new TimesHistogramSample(
- "Variations.FirstRun.SeedConnectTime", TimeUnit.MILLISECONDS);
+ TimesHistogramSample histogram =
+ new TimesHistogramSample("Variations.FirstRun.SeedConnectTime");
histogram.record(timeDeltaMillis);
}
@@ -217,7 +224,7 @@ public class VariationsSeedFetcher {
* connection.
*/
public SeedInfo downloadContent(
- VariationsPlatform platform, String restrictMode, String milestone, String channel)
+ @VariationsPlatform int platform, String restrictMode, String milestone, String channel)
throws SocketTimeoutException, UnknownHostException, IOException {
HttpURLConnection connection = null;
try {
diff --git a/chromium/components/variations/entropy_provider.cc b/chromium/components/variations/entropy_provider.cc
index 0c46368228a..d7eb868650f 100644
--- a/chromium/components/variations/entropy_provider.cc
+++ b/chromium/components/variations/entropy_provider.cc
@@ -37,8 +37,9 @@ double SHA1EntropyProvider::GetEntropyForTrial(
// distribution given the same |trial_name|. When using such a low entropy
// source, NormalizedMurmurHashEntropyProvider should be used instead.
std::string input(entropy_source_);
- input.append(randomization_seed == 0 ? trial_name : base::UintToString(
- randomization_seed));
+ input.append(randomization_seed == 0
+ ? trial_name
+ : base::NumberToString(randomization_seed));
unsigned char sha1_hash[base::kSHA1Length];
base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()),
diff --git a/chromium/components/variations/entropy_provider_unittest.cc b/chromium/components/variations/entropy_provider_unittest.cc
index de2ca1027db..79040f40cf3 100644
--- a/chromium/components/variations/entropy_provider_unittest.cc
+++ b/chromium/components/variations/entropy_provider_unittest.cc
@@ -91,7 +91,7 @@ class SHA1EntropyGenerator : public TrialEntropyGenerator {
const int low_entropy_source =
static_cast<uint16_t>(base::RandInt(0, kMaxLowEntropySize - 1));
const std::string high_entropy_source =
- base::GenerateGUID() + base::IntToString(low_entropy_source);
+ base::GenerateGUID() + base::NumberToString(low_entropy_source);
return GenerateSHA1Entropy(high_entropy_source, trial_name_);
}
diff --git a/chromium/components/variations/experiment_labels.cc b/chromium/components/variations/experiment_labels.cc
deleted file mode 100644
index 1b0d85a5c96..00000000000
--- a/chromium/components/variations/experiment_labels.cc
+++ /dev/null
@@ -1,49 +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/variations/experiment_labels.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/variations/variations_associated_data.h"
-#include "components/variations/variations_experiment_util.h"
-
-namespace variations {
-namespace {
-
-const char kVariationPrefix[] = "CrVar";
-
-} // namespace
-
-base::string16 ExtractNonVariationLabels(const base::string16& labels) {
- // First, split everything by the label separator.
- std::vector<base::StringPiece16> entries = base::SplitStringPiece(
- labels, base::StringPiece16(&kExperimentLabelSeparator, 1),
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
- // For each label, keep the ones that do not look like a Variations label.
- base::string16 non_variation_labels;
- for (const base::StringPiece16& entry : entries) {
- if (entry.empty() ||
- base::StartsWith(entry,
- base::ASCIIToUTF16(kVariationPrefix),
- base::CompareCase::INSENSITIVE_ASCII)) {
- continue;
- }
-
- // Dump the whole thing, including the timestamp.
- if (!non_variation_labels.empty())
- non_variation_labels += kExperimentLabelSeparator;
- entry.AppendToString(&non_variation_labels);
- }
-
- return non_variation_labels;
-}
-
-} // namespace variations
diff --git a/chromium/components/variations/experiment_labels.h b/chromium/components/variations/experiment_labels.h
deleted file mode 100644
index cd10825aa57..00000000000
--- a/chromium/components/variations/experiment_labels.h
+++ /dev/null
@@ -1,20 +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_VARIATIONS_EXPERIMENT_LABELS_H_
-#define COMPONENTS_VARIATIONS_EXPERIMENT_LABELS_H_
-
-#include "base/metrics/field_trial.h"
-#include "base/strings/string16.h"
-
-namespace variations {
-
-// Takes the value of experiment_labels from the registry and returns a valid
-// experiment_labels string value containing only the labels that are not
-// associated with Chrome Variations.
-base::string16 ExtractNonVariationLabels(const base::string16& labels);
-
-} // namespace variations
-
-#endif // COMPONENTS_VARIATIONS_EXPERIMENT_LABELS_H_
diff --git a/chromium/components/variations/experiment_labels_unittest.cc b/chromium/components/variations/experiment_labels_unittest.cc
deleted file mode 100644
index 797f57a82f8..00000000000
--- a/chromium/components/variations/experiment_labels_unittest.cc
+++ /dev/null
@@ -1,87 +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/variations/experiment_labels.h"
-
-#include <stddef.h>
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/metrics/field_trial.h"
-#include "base/stl_util.h"
-#include "base/strings/string_split.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/variations/variations_associated_data.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace variations {
-
-TEST(ExperimentLabelsTest, ExtractNonVariationLabels) {
- struct {
- const char* input_label;
- const char* expected_output;
- } test_cases[] = {
- // Empty
- {"", ""},
- // One
- {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT",
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // Three
- {"CrVar1=123|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar1=123|Tue, 21 Jan 2014 15:30:21 GMT",
- "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT"},
- // One and one Variation
- {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT",
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // One and one Variation, flipped
- {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;"
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT",
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // Sandwiched
- {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;"
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar2=3310003|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar3=3310004|Tue, 21 Jan 2014 15:30:21 GMT",
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // Only Variations
- {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar2=3310003|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar3=3310004|Tue, 21 Jan 2014 15:30:21 GMT",
- ""},
- // Empty values
- {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT",
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // Trailing semicolon
- {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;"
- "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;", // Note the semi here.
- "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- // Semis
- {";;;;", ""},
- // Three non-Variation labels
- // Testing that the order is preserved.
- {"experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment3=123|Tue, 21 Jan 2014 15:30:21 GMT",
- "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;"
- "experiment3=123|Tue, 21 Jan 2014 15:30:21 GMT"},
- };
-
- for (size_t i = 0; i < base::size(test_cases); ++i) {
- std::string non_variation_labels = base::UTF16ToUTF8(
- ExtractNonVariationLabels(
- base::ASCIIToUTF16(test_cases[i].input_label)));
- EXPECT_EQ(test_cases[i].expected_output, non_variation_labels);
- }
-}
-
-} // namespace variations
diff --git a/chromium/components/variations/net/variations_http_headers.cc b/chromium/components/variations/net/variations_http_headers.cc
index 1b2eb27c137..c06fd473f75 100644
--- a/chromium/components/variations/net/variations_http_headers.cc
+++ b/chromium/components/variations/net/variations_http_headers.cc
@@ -6,8 +6,10 @@
#include <stddef.h>
+#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
@@ -27,25 +29,9 @@ namespace variations {
namespace {
-const char* kSuffixesToSetHeadersFor[] = {
- ".android.com",
- ".doubleclick.com",
- ".doubleclick.net",
- ".ggpht.com",
- ".googleadservices.com",
- ".googleapis.com",
- ".googlesyndication.com",
- ".googleusercontent.com",
- ".googlevideo.com",
- ".gstatic.com",
- ".litepages.googlezip.net",
- ".ytimg.com",
-};
-
-// Exact hostnames in lowercase to set headers for.
-const char* kHostsToSetHeadersFor[] = {
- "googleweblight.com",
-};
+// The name string for the header for variations information.
+// Note that prior to M33 this header was named X-Chrome-Variations.
+const char kClientDataHeader[] = "X-Client-Data";
// The result of checking if a URL should have variations headers appended.
// This enum is used to record UMA histogram values, and should not be
@@ -60,142 +46,194 @@ enum URLValidationResult {
URL_VALIDATION_RESULT_SIZE,
};
-// Checks whether headers should be appended to the |url|, based on the domain
-// of |url|. |url| is assumed to be valid, and to have an http/https scheme.
-bool IsGoogleDomain(const GURL& url) {
- if (google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN,
- google_util::ALLOW_NON_STANDARD_PORTS)) {
- return true;
+void LogUrlValidationHistogram(URLValidationResult result) {
+ UMA_HISTOGRAM_ENUMERATION("Variations.Headers.URLValidationResult", result,
+ URL_VALIDATION_RESULT_SIZE);
+}
+
+bool ShouldAppendVariationsHeader(const GURL& url) {
+ if (!url.is_valid()) {
+ LogUrlValidationHistogram(INVALID_URL);
+ return false;
}
- if (google_util::IsYoutubeDomainUrl(url, google_util::ALLOW_SUBDOMAIN,
- google_util::ALLOW_NON_STANDARD_PORTS)) {
- return true;
+ if (!url.SchemeIsHTTPOrHTTPS()) {
+ LogUrlValidationHistogram(NEITHER_HTTP_HTTPS);
+ return false;
}
+ if (!google_util::IsGoogleAssociatedDomainUrl(url)) {
+ LogUrlValidationHistogram(NOT_GOOGLE_DOMAIN);
+ return false;
+ }
+ // We check https here, rather than before the IsGoogleDomain() check, to know
+ // how many Google domains are being rejected by the change to https only.
+ if (!url.SchemeIs(url::kHttpsScheme)) {
+ LogUrlValidationHistogram(IS_GOOGLE_NOT_HTTPS);
+ return false;
+ }
+ LogUrlValidationHistogram(SHOULD_APPEND);
+ return true;
+}
+
+constexpr network::ResourceRequest* null_resource_request = nullptr;
+constexpr net::URLRequest* null_url_request = nullptr;
- // Some domains don't have international TLD extensions, so testing for them
- // is very straight forward.
- const std::string host = url.host();
- for (size_t i = 0; i < base::size(kSuffixesToSetHeadersFor); ++i) {
- if (base::EndsWith(host, kSuffixesToSetHeadersFor[i],
- base::CompareCase::INSENSITIVE_ASCII))
- return true;
+class VariationsHeaderHelper {
+ public:
+ // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect
+ // transmission of experiments coming from the variations server.
+ VariationsHeaderHelper(network::ResourceRequest* request,
+ SignedIn signed_in = SignedIn::kNo)
+ : VariationsHeaderHelper(request,
+ null_url_request,
+ CreateVariationsHeader(signed_in)) {}
+ VariationsHeaderHelper(net::URLRequest* request,
+ SignedIn signed_in = SignedIn::kNo)
+ : VariationsHeaderHelper(null_resource_request,
+ request,
+ CreateVariationsHeader(signed_in)) {}
+ VariationsHeaderHelper(network::ResourceRequest* request,
+ const std::string& variations_header)
+ : VariationsHeaderHelper(request, null_url_request, variations_header) {}
+
+ bool AppendHeaderIfNeeded(const GURL& url, InIncognito incognito) {
+ // Note the criteria for attaching client experiment headers:
+ // 1. We only transmit to Google owned domains which can evaluate
+ // experiments.
+ // 1a. These include hosts which have a standard postfix such as:
+ // *.doubleclick.net or *.googlesyndication.com or
+ // exactly www.googleadservices.com or
+ // international TLD domains *.google.<TLD> or *.youtube.<TLD>.
+ // 2. Only transmit for non-Incognito profiles.
+ // 3. For the X-Client-Data header, only include non-empty variation IDs.
+ if ((incognito == InIncognito::kYes) || !ShouldAppendVariationsHeader(url))
+ return false;
+
+ if (variations_header_.empty())
+ return false;
+
+ if (resource_request_) {
+ // Set the variations header to client_data_header rather than headers to
+ // be exempted from CORS checks.
+ resource_request_->client_data_header = variations_header_;
+ } else if (url_request_) {
+ url_request_->SetExtraRequestHeaderByName(kClientDataHeader,
+ variations_header_, false);
+ } else {
+ NOTREACHED();
+ return false;
+ }
+ return true;
}
- for (size_t i = 0; i < base::size(kHostsToSetHeadersFor); ++i) {
- if (base::LowerCaseEqualsASCII(host, kHostsToSetHeadersFor[i]))
- return true;
+
+ private:
+ static std::string CreateVariationsHeader(SignedIn signed_in) {
+ return VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader(
+ signed_in == SignedIn::kYes);
}
- return false;
-}
+ VariationsHeaderHelper(network::ResourceRequest* resource_request,
+ net::URLRequest* url_request,
+ std::string variations_header)
+ : resource_request_(resource_request), url_request_(url_request) {
+ DCHECK(resource_request_ || url_request_);
+ variations_header_ = std::move(variations_header);
+ }
-void LogUrlValidationHistogram(URLValidationResult result) {
- UMA_HISTOGRAM_ENUMERATION("Variations.Headers.URLValidationResult", result,
- URL_VALIDATION_RESULT_SIZE);
-}
+ network::ResourceRequest* resource_request_;
+ net::URLRequest* url_request_;
+ std::string variations_header_;
-// Removes variations headers for requests when a redirect to a non-Google URL
-// occurs. This function is used as the callback parameter for
-// SimpleURLLoader::SetOnRedirectCallback() when
-// CreateSimpleURLLoaderWithVariationsHeaders() creates a SimpleURLLoader
-// object.
-void RemoveVariationsHeader(const net::RedirectInfo& redirect_info,
- const network::ResourceResponseHead& response_head,
- std::vector<std::string>* to_be_removed_headers) {
- if (!ShouldAppendVariationHeaders(redirect_info.new_url))
- to_be_removed_headers->push_back(kClientDataHeader);
-}
+ DISALLOW_COPY_AND_ASSIGN(VariationsHeaderHelper);
+};
} // namespace
-const char kClientDataHeader[] = "X-Client-Data";
+bool AppendVariationsHeader(const GURL& url,
+ InIncognito incognito,
+ SignedIn signed_in,
+ network::ResourceRequest* request) {
+ return VariationsHeaderHelper(request, signed_in)
+ .AppendHeaderIfNeeded(url, incognito);
+}
-bool AppendVariationHeaders(const GURL& url,
+bool AppendVariationsHeader(const GURL& url,
InIncognito incognito,
SignedIn signed_in,
- net::HttpRequestHeaders* headers) {
- // Note the criteria for attaching client experiment headers:
- // 1. We only transmit to Google owned domains which can evaluate experiments.
- // 1a. These include hosts which have a standard postfix such as:
- // *.doubleclick.net or *.googlesyndication.com or
- // exactly www.googleadservices.com or
- // international TLD domains *.google.<TLD> or *.youtube.<TLD>.
- // 2. Only transmit for non-Incognito profiles.
- // 3. For the X-Client-Data header, only include non-empty variation IDs.
- if ((incognito == InIncognito::kYes) || !ShouldAppendVariationHeaders(url))
- return false;
+ net::URLRequest* request) {
+ return VariationsHeaderHelper(request, signed_in)
+ .AppendHeaderIfNeeded(url, incognito);
+}
- const std::string variation_ids_header =
- VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader(
- signed_in == SignedIn::kYes);
- if (!variation_ids_header.empty()) {
- // Note that prior to M33 this header was named X-Chrome-Variations.
- headers->SetHeaderIfMissing(kClientDataHeader, variation_ids_header);
- return true;
- }
- return false;
+bool AppendVariationsHeaderWithCustomValue(const GURL& url,
+ InIncognito incognito,
+ const std::string& variations_header,
+ network::ResourceRequest* request) {
+ return VariationsHeaderHelper(request, variations_header)
+ .AppendHeaderIfNeeded(url, incognito);
}
-bool AppendVariationHeadersUnknownSignedIn(const GURL& url,
+bool AppendVariationsHeaderUnknownSignedIn(const GURL& url,
InIncognito incognito,
- net::HttpRequestHeaders* headers) {
- // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect
- // transmission of experiments coming from the variations server.
- return AppendVariationHeaders(url, incognito, SignedIn::kNo, headers);
+ network::ResourceRequest* request) {
+ return VariationsHeaderHelper(request).AppendHeaderIfNeeded(url, incognito);
+}
+
+bool AppendVariationsHeaderUnknownSignedIn(const GURL& url,
+ InIncognito incognito,
+ net::URLRequest* request) {
+ return VariationsHeaderHelper(request).AppendHeaderIfNeeded(url, incognito);
}
-void StripVariationHeaderIfNeeded(const GURL& new_location,
- net::URLRequest* request) {
- if (!ShouldAppendVariationHeaders(new_location))
+void RemoveVariationsHeaderIfNeeded(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ std::vector<std::string>* to_be_removed_headers) {
+ if (!ShouldAppendVariationsHeader(redirect_info.new_url))
+ to_be_removed_headers->push_back(kClientDataHeader);
+}
+
+void StripVariationsHeaderIfNeeded(const GURL& new_location,
+ net::URLRequest* request) {
+ if (!ShouldAppendVariationsHeader(new_location))
request->RemoveRequestHeaderByName(kClientDataHeader);
}
std::unique_ptr<network::SimpleURLLoader>
-CreateSimpleURLLoaderWithVariationsHeaders(
+CreateSimpleURLLoaderWithVariationsHeader(
std::unique_ptr<network::ResourceRequest> request,
InIncognito incognito,
SignedIn signed_in,
const net::NetworkTrafficAnnotationTag& annotation_tag) {
- bool variation_headers_added = AppendVariationHeaders(
- request->url, incognito, signed_in, &request->headers);
+ bool variation_headers_added =
+ AppendVariationsHeader(request->url, incognito, signed_in, request.get());
std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
network::SimpleURLLoader::Create(std::move(request), annotation_tag);
if (variation_headers_added) {
simple_url_loader->SetOnRedirectCallback(
- base::BindRepeating(&RemoveVariationsHeader));
+ base::BindRepeating(&RemoveVariationsHeaderIfNeeded));
}
return simple_url_loader;
}
std::unique_ptr<network::SimpleURLLoader>
-CreateSimpleURLLoaderWithVariationsHeadersUnknownSignedIn(
+CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn(
std::unique_ptr<network::ResourceRequest> request,
InIncognito incognito,
const net::NetworkTrafficAnnotationTag& annotation_tag) {
- return CreateSimpleURLLoaderWithVariationsHeaders(
+ return CreateSimpleURLLoaderWithVariationsHeader(
std::move(request), incognito, SignedIn::kNo, annotation_tag);
}
-bool ShouldAppendVariationHeaders(const GURL& url) {
- if (!url.is_valid()) {
- LogUrlValidationHistogram(INVALID_URL);
- return false;
- }
- if (!url.SchemeIsHTTPOrHTTPS()) {
- LogUrlValidationHistogram(NEITHER_HTTP_HTTPS);
- return false;
- }
- if (!IsGoogleDomain(url)) {
- LogUrlValidationHistogram(NOT_GOOGLE_DOMAIN);
- return false;
- }
- // We check https here, rather than before the IsGoogleDomain() check, to know
- // how many Google domains are being rejected by the change to https only.
- if (!url.SchemeIs("https")) {
- LogUrlValidationHistogram(IS_GOOGLE_NOT_HTTPS);
- return false;
- }
- LogUrlValidationHistogram(SHOULD_APPEND);
- return true;
+bool IsVariationsHeader(const std::string& header_name) {
+ return header_name == kClientDataHeader;
+}
+
+bool HasVariationsHeader(const network::ResourceRequest& request) {
+ return !request.client_data_header.empty();
+}
+
+bool ShouldAppendVariationsHeaderForTesting(const GURL& url) {
+ return ShouldAppendVariationsHeader(url);
}
} // namespace variations
diff --git a/chromium/components/variations/net/variations_http_headers.h b/chromium/components/variations/net/variations_http_headers.h
index 4530a6d773f..a25f45d1c26 100644
--- a/chromium/components/variations/net/variations_http_headers.h
+++ b/chromium/components/variations/net/variations_http_headers.h
@@ -8,15 +8,17 @@
#include <memory>
#include <set>
#include <string>
+#include <vector>
namespace net {
-class HttpRequestHeaders;
struct NetworkTrafficAnnotationTag;
+struct RedirectInfo;
class URLRequest;
}
namespace network {
struct ResourceRequest;
+struct ResourceResponseHead;
class SimpleURLLoader;
} // namespace network
@@ -28,10 +30,7 @@ enum class InIncognito { kNo, kYes };
enum class SignedIn { kNo, kYes };
-// The name string for the header for variations information.
-extern const char kClientDataHeader[];
-
-// Adds Chrome experiment and metrics state as custom headers to |headers|.
+// Adds Chrome experiment and metrics state as custom headers to |request|.
// The content of the headers will depend on |incognito| and |signed_in|
// parameters. It is fine to pass SignedIn::NO if the state is not known to the
// caller. This will prevent addition of ids of type
@@ -39,46 +38,79 @@ extern const char kClientDataHeader[];
// from the variations server. These headers are never transmitted to non-Google
// web sites, which is checked based on the destination |url|.
// Returns true if custom headers are added. Returns false otherwise.
-bool AppendVariationHeaders(const GURL& url,
+bool AppendVariationsHeader(const GURL& url,
+ InIncognito incognito,
+ SignedIn signed_in,
+ network::ResourceRequest* request);
+
+// TODO(toyoshim): Remove this deprecated API that takes net::URLRequest* once
+// all callers are removed after NetworkService being fully enabled, or migrated
+// to use SimpleURLLoader. See, crbug.com/773295.
+bool AppendVariationsHeader(const GURL& url,
InIncognito incognito,
SignedIn signed_in,
- net::HttpRequestHeaders* headers);
+ net::URLRequest* request);
+
+// Similar to functions above, but uses specified |variations_header| as the
+// custom header value. You should not generally need to use this.
+bool AppendVariationsHeaderWithCustomValue(const GURL& url,
+ InIncognito incognito,
+ const std::string& variations_header,
+ network::ResourceRequest* request);
-// Adds Chrome experiment and metrics state as custom headers to |headers|
+// Adds Chrome experiment and metrics state as a custom header to |request|
// when the signed-in state is not known to the caller; See above for details.
-bool AppendVariationHeadersUnknownSignedIn(const GURL& url,
+bool AppendVariationsHeaderUnknownSignedIn(const GURL& url,
InIncognito incognito,
- net::HttpRequestHeaders* headers);
+ network::ResourceRequest* request);
-// Strips the variation header if |new_location| does not point to a location
+// TODO(toyoshim): Remove this deprecated API that takes net::URLRequest* once
+// all callers are removed after NetworkService being fully enabled, or migrated
+// to use SimpleURLLoader. See, crbug.com/773295.
+bool AppendVariationsHeaderUnknownSignedIn(const GURL& url,
+ InIncognito incognito,
+ net::URLRequest* request);
+
+// Removes the variations header for requests when a redirect to a non-Google
+// URL occurs.
+void RemoveVariationsHeaderIfNeeded(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ std::vector<std::string>* to_be_removed_headers);
+
+// Strips the variations header if |new_location| does not point to a location
// that should receive it. This is being called by the ChromeNetworkDelegate.
-// Components calling AppendVariationsHeaders() don't need to take care of this.
-void StripVariationHeaderIfNeeded(const GURL& new_location,
- net::URLRequest* request);
+// Components calling AppendVariationsHeader() don't need to take care of this.
+void StripVariationsHeaderIfNeeded(const GURL& new_location,
+ net::URLRequest* request);
-// Creates a SimpleURLLoader that will include variations headers for requests
-// to Google and ensures they're removed if a redirect to a non-Google URL
-// occurs.
+// Creates a SimpleURLLoader that will include the variations header for
+// requests to Google and ensures they're removed if a redirect to a non-Google
+// URL occurs.
std::unique_ptr<network::SimpleURLLoader>
-CreateSimpleURLLoaderWithVariationsHeaders(
+CreateSimpleURLLoaderWithVariationsHeader(
std::unique_ptr<network::ResourceRequest> request,
InIncognito incognito,
SignedIn signed_in,
const net::NetworkTrafficAnnotationTag& annotation_tag);
-// Creates a SimpleURLLoader that will include variations headers for requests
-// to Google when the signed-in state is unknown and ensures they're removed
-// if a redirect to a non-Google URL occurs.
+// Creates a SimpleURLLoader that will include the variations header for
+// requests to Google when the signed-in state is unknown and ensures they're
+// removed if a redirect to a non-Google URL occurs.
std::unique_ptr<network::SimpleURLLoader>
-CreateSimpleURLLoaderWithVariationsHeadersUnknownSignedIn(
+CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn(
std::unique_ptr<network::ResourceRequest> request,
InIncognito incognito,
const net::NetworkTrafficAnnotationTag& annotation_tag);
-// Checks whether variation headers should be appended to requests to the
-// specified |url|. Returns true for google.<TLD> and youtube.<TLD> URLs with
-// the https scheme.
-bool ShouldAppendVariationHeaders(const GURL& url);
+// Checks if |header_name| is one for the variations header.
+bool IsVariationsHeader(const std::string& header_name);
+
+// Checks if |request| contains the variations header.
+bool HasVariationsHeader(const network::ResourceRequest& request);
+
+// Calls the internal ShouldAppendVariationsHeader() for testing.
+bool ShouldAppendVariationsHeaderForTesting(const GURL& url);
} // namespace variations
diff --git a/chromium/components/variations/net/variations_http_headers_unittest.cc b/chromium/components/variations/net/variations_http_headers_unittest.cc
index 87dfc2dc533..a07883107ad 100644
--- a/chromium/components/variations/net/variations_http_headers_unittest.cc
+++ b/chromium/components/variations/net/variations_http_headers_unittest.cc
@@ -13,7 +13,7 @@
namespace variations {
-TEST(VariationsHttpHeadersTest, ShouldAppendHeaders) {
+TEST(VariationsHttpHeadersTest, ShouldAppendVariationsHeader) {
struct {
const char* url;
bool should_append_headers;
@@ -154,7 +154,8 @@ TEST(VariationsHttpHeadersTest, ShouldAppendHeaders) {
for (size_t i = 0; i < base::size(cases); ++i) {
const GURL url(cases[i].url);
- EXPECT_EQ(cases[i].should_append_headers, ShouldAppendVariationHeaders(url))
+ EXPECT_EQ(cases[i].should_append_headers,
+ ShouldAppendVariationsHeaderForTesting(url))
<< url;
}
}
diff --git a/chromium/components/variations/platform_field_trials.h b/chromium/components/variations/platform_field_trials.h
index 3a7f64238f0..bb010fee9a6 100644
--- a/chromium/components/variations/platform_field_trials.h
+++ b/chromium/components/variations/platform_field_trials.h
@@ -29,6 +29,10 @@ class PlatformFieldTrials {
bool has_seed,
base::FeatureList* feature_list) = 0;
+ // Register any synthetic field trials. Will be called later than the above
+ // methods, in particular after g_browser_process is available..
+ virtual void RegisterSyntheticTrials() {}
+
private:
DISALLOW_COPY_AND_ASSIGN(PlatformFieldTrials);
};
diff --git a/chromium/components/variations/processed_study.cc b/chromium/components/variations/processed_study.cc
index e207ba4d75a..b8abc438682 100644
--- a/chromium/components/variations/processed_study.cc
+++ b/chromium/components/variations/processed_study.cc
@@ -55,11 +55,11 @@ bool ValidateStudyAndComputeTotalProbability(
return false;
}
- // Note: This checks for ACTIVATION_EXPLICIT, since there is no reason to
- // have this association with ACTIVATION_AUTO (where the trial starts
+ // Note: This checks for ACTIVATE_ON_QUERY, since there is no reason to
+ // have this association with ACTIVATE_ON_STARTUP (where the trial starts
// active), as well as allowing flexibility to disable this behavior in the
// future from the server by introducing a new activation type.
- if (study.activation_type() == Study_ActivationType_ACTIVATION_EXPLICIT) {
+ if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_QUERY) {
const auto& features = experiment.feature_association();
for (int i = 0; i < features.enable_feature_size(); ++i) {
features_to_associate.insert(features.enable_feature(i));
diff --git a/chromium/components/variations/proto/study.proto b/chromium/components/variations/proto/study.proto
index 0169db04e26..0993802180c 100644
--- a/chromium/components/variations/proto/study.proto
+++ b/chromium/components/variations/proto/study.proto
@@ -334,10 +334,10 @@ message Study {
enum ActivationType {
// The study will be activated when its state is queried by the client.
// This is recommended for most studies that include client code.
- ACTIVATION_EXPLICIT = 0;
+ ACTIVATE_ON_QUERY = 0;
// The study will be automatically activated when it is created. This
// is recommended for studies that do not have any client logic.
- ACTIVATION_AUTO = 1;
+ ACTIVATE_ON_STARTUP = 1;
}
// Activation type for this study. Defaults to ACTIVATION_EXPLICIT if omitted.
diff --git a/chromium/components/variations/service/variations_field_trial_creator.cc b/chromium/components/variations/service/variations_field_trial_creator.cc
index c1622956f5d..f98bbbcd0cb 100644
--- a/chromium/components/variations/service/variations_field_trial_creator.cc
+++ b/chromium/components/variations/service/variations_field_trial_creator.cc
@@ -15,6 +15,7 @@
#include <vector>
#include "base/base_switches.h"
+#include "base/bind.h"
#include "base/build_time.h"
#include "base/command_line.h"
#include "base/metrics/histogram_functions.h"
diff --git a/chromium/components/variations/service/variations_field_trial_creator_unittest.cc b/chromium/components/variations/service/variations_field_trial_creator_unittest.cc
index c1088cdadb3..3910b35828c 100644
--- a/chromium/components/variations/service/variations_field_trial_creator_unittest.cc
+++ b/chromium/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -30,7 +30,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_ANDROID)
-#include "components/variations/android/variations_seed_bridge.h"
#include "components/variations/seed_response.h"
#endif // OS_ANDROID
@@ -99,6 +98,7 @@ VariationsSeed CreateTestSeedWithCountryFilter() {
Study* study = seed.mutable_study(0);
Study::Filter* filter = study->mutable_filter();
filter->add_country(kTestSeedCountry);
+ filter->add_platform(Study::PLATFORM_ANDROID);
return seed;
}
diff --git a/chromium/components/variations/service/variations_service.cc b/chromium/components/variations/service/variations_service.cc
index 6c53f8b5d2d..0583214e3de 100644
--- a/chromium/components/variations/service/variations_service.cc
+++ b/chromium/components/variations/service/variations_service.cc
@@ -25,6 +25,7 @@
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/timer/elapsed_timer.h"
+#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
@@ -502,11 +503,11 @@ bool VariationsService::DoFetchFromURL(const GURL& url, bool is_http_retry) {
safe_seed_manager_.RecordFetchStarted();
- // Normally, there shouldn't be a |pending_request_| when this fires. However
- // it's not impossible - for example if Chrome was paused (e.g. in a debugger
- // or if the machine was suspended) and OnURLFetchComplete() hasn't had a
- // chance to run yet from the previous request. In this case, don't start a
- // new request and just let the previous one finish.
+ // Normally, there shouldn't be a |pending_seed_request_| when this fires.
+ // However it's not impossible - for example if Chrome was paused (e.g. in a
+ // debugger or if the machine was suspended) and OnURLFetchComplete() hasn't
+ // had a chance to run yet from the previous request. In this case, don't
+ // start a new request and just let the previous one finish.
if (pending_seed_request_)
return false;
@@ -692,6 +693,7 @@ void VariationsService::OnSimpleLoaderRedirect(
void VariationsService::OnSimpleLoaderCompleteOrRedirect(
std::unique_ptr<std::string> response_body,
bool was_redirect) {
+ TRACE_EVENT0("browser", "VariationsService::OnSimpleLoaderCompleteOrRedirect");
const bool is_first_request = !initial_request_completed_;
initial_request_completed_ = true;
@@ -918,6 +920,10 @@ void VariationsService::OverrideCachedUIStrings() {
field_trial_creator_.OverrideCachedUIStrings();
}
+void VariationsService::CancelCurrentRequestForTesting() {
+ pending_seed_request_.reset();
+}
+
std::string VariationsService::GetStoredPermanentCountry() {
const base::ListValue* list_value =
local_state_->GetList(prefs::kVariationsPermanentConsistencyCountry);
diff --git a/chromium/components/variations/service/variations_service.h b/chromium/components/variations/service/variations_service.h
index 217a7c56457..bc5fd826b0c 100644
--- a/chromium/components/variations/service/variations_service.h
+++ b/chromium/components/variations/service/variations_service.h
@@ -176,6 +176,11 @@ class VariationsService
// Exposed for testing.
void GetClientFilterableStateForVersionCalledForTesting();
+ web_resource::ResourceRequestAllowedNotifier*
+ GetResourceRequestAllowedNotifierForTesting() {
+ return resource_request_allowed_notifier_.get();
+ }
+
// Wrapper around VariationsFieldTrialCreator::SetupFieldTrials().
bool SetupFieldTrials(const char* kEnableGpuBenchmarking,
const char* kEnableFeatures,
@@ -190,6 +195,9 @@ class VariationsService
int request_count() const { return request_count_; }
+ // Cancels the currently pending fetch request.
+ void CancelCurrentRequestForTesting();
+
protected:
// Starts the fetching process once, where |OnURLFetchComplete| is called with
// the response. This calls DoFetchToURL with the set url.
diff --git a/chromium/components/variations/service/variations_service_unittest.cc b/chromium/components/variations/service/variations_service_unittest.cc
index 57eac53d3bb..0eb1a64ca37 100644
--- a/chromium/components/variations/service/variations_service_unittest.cc
+++ b/chromium/components/variations/service/variations_service_unittest.cc
@@ -11,12 +11,12 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/feature_list.h"
#include "base/json/json_string_value_serializer.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
-#include "base/sha1.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
diff --git a/chromium/components/variations/study_filtering.cc b/chromium/components/variations/study_filtering.cc
index 6f1e21773de..54aa57b04e6 100644
--- a/chromium/components/variations/study_filtering.cc
+++ b/chromium/components/variations/study_filtering.cc
@@ -107,10 +107,6 @@ bool CheckStudyLocale(const Study::Filter& filter, const std::string& locale) {
}
bool CheckStudyPlatform(const Study::Filter& filter, Study::Platform platform) {
- // An empty platform list matches all platforms.
- if (filter.platform_size() == 0)
- return true;
-
for (int i = 0; i < filter.platform_size(); ++i) {
if (filter.platform(i) == platform)
return true;
diff --git a/chromium/components/variations/study_filtering_unittest.cc b/chromium/components/variations/study_filtering_unittest.cc
index 184747fda93..2b11e1afc04 100644
--- a/chromium/components/variations/study_filtering_unittest.cc
+++ b/chromium/components/variations/study_filtering_unittest.cc
@@ -222,10 +222,10 @@ TEST(VariationsStudyFilteringTest, CheckStudyPlatform) {
Study::Filter filter;
// Check in the forwarded order. The loop cond is <= base::size(platforms)
- // instead of < so that the result of adding the last channel gets checked.
+ // instead of < so that the result of adding the last platform gets checked.
for (size_t i = 0; i <= base::size(platforms); ++i) {
for (size_t j = 0; j < base::size(platforms); ++j) {
- const bool expected = platform_added[j] || filter.platform_size() == 0;
+ const bool expected = platform_added[j];
const bool result = internal::CheckStudyPlatform(filter, platforms[j]);
EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
}
@@ -241,7 +241,7 @@ TEST(VariationsStudyFilteringTest, CheckStudyPlatform) {
memset(&platform_added, 0, sizeof(platform_added));
for (size_t i = 0; i <= base::size(platforms); ++i) {
for (size_t j = 0; j < base::size(platforms); ++j) {
- const bool expected = platform_added[j] || filter.platform_size() == 0;
+ const bool expected = platform_added[j];
const bool result = internal::CheckStudyPlatform(filter, platforms[j]);
EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
}
@@ -575,6 +575,7 @@ TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) {
study->set_default_experiment_name("Default");
AddExperiment("Default", 100, study);
study->set_consistency(test.consistency);
+ study->mutable_filter()->add_platform(Study::PLATFORM_ANDROID);
if (test.filter_country)
study->mutable_filter()->add_country(test.filter_country);
if (test.filter_exclude_country)
@@ -585,7 +586,7 @@ TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) {
client_state.reference_date = base::Time::Now();
client_state.version = base::Version("20.0.0.0");
client_state.channel = Study::STABLE;
- client_state.form_factor = Study::DESKTOP;
+ client_state.form_factor = Study::PHONE;
client_state.platform = Study::PLATFORM_ANDROID;
client_state.session_consistency_country = kSessionCountry;
client_state.permanent_consistency_country = kPermanentCountry;
diff --git a/chromium/components/variations/variations_experiment_util.cc b/chromium/components/variations/variations_experiment_util.cc
deleted file mode 100644
index 9cf78bbabc0..00000000000
--- a/chromium/components/variations/variations_experiment_util.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/variations/variations_experiment_util.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-
-namespace variations {
-
-const base::char16 kExperimentLabelSeparator = ';';
-
-namespace {
-
-const char* const kDays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
-
-const char* const kMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-} // namespace
-
-base::string16 BuildExperimentDateString(const base::Time& current_time) {
- // The Google Update experiment_labels timestamp format is:
- // "DAY, DD0 MON YYYY HH0:MI0:SE0 TZ"
- // DAY = 3 character day of week,
- // DD0 = 2 digit day of month,
- // MON = 3 character month of year,
- // YYYY = 4 digit year,
- // HH0 = 2 digit hour,
- // MI0 = 2 digit minute,
- // SE0 = 2 digit second,
- // TZ = 3 character timezone
- base::Time::Exploded then = {};
- current_time.UTCExplode(&then);
- then.year += 1;
- DCHECK(then.HasValidValues());
-
- return base::UTF8ToUTF16(
- base::StringPrintf("%s, %02d %s %d %02d:%02d:%02d GMT",
- kDays[then.day_of_week],
- then.day_of_month,
- kMonths[then.month - 1],
- then.year,
- then.hour,
- then.minute,
- then.second));
-}
-
-} // namespace variations
diff --git a/chromium/components/variations/variations_experiment_util.h b/chromium/components/variations/variations_experiment_util.h
deleted file mode 100644
index c9c23f4006b..00000000000
--- a/chromium/components/variations/variations_experiment_util.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_
-#define COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_
-
-#include "base/strings/string16.h"
-
-namespace base {
-class Time;
-}
-
-namespace variations {
-
-// The separator used to separate items in experiment labels.
-extern const base::char16 kExperimentLabelSeparator;
-
-// Constructs a date string in the format understood by Google Update for the
-// |current_time| plus one year.
-base::string16 BuildExperimentDateString(const base::Time& current_time);
-
-} // namespace variations
-
-#endif // COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_
diff --git a/chromium/components/variations/variations_http_header_provider.cc b/chromium/components/variations/variations_http_header_provider.cc
index 29084615b68..e8a1a389cbf 100644
--- a/chromium/components/variations/variations_http_header_provider.cc
+++ b/chromium/components/variations/variations_http_header_provider.cc
@@ -40,7 +40,7 @@ namespace variations {
// ChromeContentBrowserClient::CreateURLLoaderThrottles() by also adding a
// GoogleURLLoaderThrottle to a content::URLLoaderThrottle vector.
// 3. SimpleURLLoader in browser, it is implemented in a SimpleURLLoader wrapper
-// function variations::CreateSimpleURLLoaderWithVariationsHeaders().
+// function variations::CreateSimpleURLLoaderWithVariationsHeader().
// static
VariationsHttpHeaderProvider* VariationsHttpHeaderProvider::GetInstance() {
@@ -74,7 +74,7 @@ std::string VariationsHttpHeaderProvider::GetVariationsString() {
base::AutoLock scoped_lock(lock_);
for (const VariationIDEntry& entry : GetAllVariationIds()) {
if (entry.second == GOOGLE_WEB_PROPERTIES) {
- ids_string.append(base::IntToString(entry.first));
+ ids_string.append(base::NumberToString(entry.first));
ids_string.push_back(' ');
}
}
@@ -82,6 +82,28 @@ std::string VariationsHttpHeaderProvider::GetVariationsString() {
return ids_string;
}
+std::vector<VariationID> VariationsHttpHeaderProvider::GetVariationsVector(
+ IDCollectionKey key) {
+ InitVariationIDsCacheIfNeeded();
+
+ // Get all the active variation ids while holding the lock.
+ std::set<VariationIDEntry> all_variation_ids;
+ {
+ base::AutoLock scoped_lock(lock_);
+ all_variation_ids = GetAllVariationIds();
+ }
+
+ // Copy the requested variations to the output vector. Note that the ids will
+ // be in sorted order because they're coming from a std::set.
+ std::vector<VariationID> result;
+ result.reserve(all_variation_ids.size());
+ for (const VariationIDEntry& entry : all_variation_ids) {
+ if (entry.second == key)
+ result.push_back(entry.first);
+ }
+ return result;
+}
+
VariationsHttpHeaderProvider::ForceIdsResult
VariationsHttpHeaderProvider::ForceVariationIds(
const std::vector<std::string>& variation_ids,
diff --git a/chromium/components/variations/variations_http_header_provider.h b/chromium/components/variations/variations_http_header_provider.h
index b29fcd07cdd..85b9d737d0d 100644
--- a/chromium/components/variations/variations_http_header_provider.h
+++ b/chromium/components/variations/variations_http_header_provider.h
@@ -57,6 +57,10 @@ class VariationsHttpHeaderProvider : public base::FieldTrialList::Observer,
// a leading and trailing space, e.g. " 123 234 345 ".
std::string GetVariationsString();
+ // Returns the collection of of variation ids matching the given |key|. Each
+ // entry in the returned vector will be unique.
+ std::vector<VariationID> GetVariationsVector(IDCollectionKey key);
+
// Result of ForceVariationIds() call.
enum class ForceIdsResult {
SUCCESS,
@@ -95,6 +99,8 @@ class VariationsHttpHeaderProvider : public base::FieldTrialList::Observer,
OnFieldTrialGroupFinalized);
FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
GetVariationsString);
+ FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
+ GetVariationsVector);
VariationsHttpHeaderProvider();
~VariationsHttpHeaderProvider() override;
diff --git a/chromium/components/variations/variations_http_header_provider_unittest.cc b/chromium/components/variations/variations_http_header_provider_unittest.cc
index 70d1cbe8f4b..6e7823def3f 100644
--- a/chromium/components/variations/variations_http_header_provider_unittest.cc
+++ b/chromium/components/variations/variations_http_header_provider_unittest.cc
@@ -184,4 +184,25 @@ TEST_F(VariationsHttpHeaderProviderTest, GetVariationsString) {
EXPECT_EQ(" 100 123 124 200 ", provider.GetVariationsString());
}
+TEST_F(VariationsHttpHeaderProviderTest, GetVariationsVector) {
+ base::test::ScopedTaskEnvironment task_environment;
+ base::FieldTrialList field_trial_list(nullptr);
+
+ CreateTrialAndAssociateId("t1", "g1", GOOGLE_WEB_PROPERTIES, 121);
+ CreateTrialAndAssociateId("t2", "g2", GOOGLE_WEB_PROPERTIES, 122);
+ CreateTrialAndAssociateId("t3", "g3", GOOGLE_WEB_PROPERTIES_TRIGGER, 123);
+ CreateTrialAndAssociateId("t4", "g4", GOOGLE_WEB_PROPERTIES_TRIGGER, 124);
+ CreateTrialAndAssociateId("t5", "g5", GOOGLE_WEB_PROPERTIES_SIGNED_IN, 125);
+
+ VariationsHttpHeaderProvider provider;
+ provider.ForceVariationIds({"100", "200", "t101"}, "");
+
+ EXPECT_EQ((std::vector<VariationID>{100, 121, 122, 200}),
+ provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES));
+ EXPECT_EQ((std::vector<VariationID>{101, 123, 124}),
+ provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES_TRIGGER));
+ EXPECT_EQ((std::vector<VariationID>{125}),
+ provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES_SIGNED_IN));
+}
+
} // namespace variations
diff --git a/chromium/components/variations/variations_id_collection_unittest.cc b/chromium/components/variations/variations_id_collection_unittest.cc
index a17343d9b65..2c4f4bbb5c9 100644
--- a/chromium/components/variations/variations_id_collection_unittest.cc
+++ b/chromium/components/variations/variations_id_collection_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/variations/variations_murmur_hash.h b/chromium/components/variations/variations_murmur_hash.h
index 9ec77ad416e..b3e7458a82d 100644
--- a/chromium/components/variations/variations_murmur_hash.h
+++ b/chromium/components/variations/variations_murmur_hash.h
@@ -32,9 +32,9 @@ class VariationsMurmurHash {
// it produces the same results that MurmurHash3_x86_32 would produce on a
// little-endian platform.
//
- // |length| is the number of bytes to hash. It mustn't exceed
- // padded_data.size() * 4. If length % 4 != 0, Hash will consume the
- // less-significant bytes of the last uint32_t first.
+ // |length| is the number of bytes to hash. It mustn't exceed data.size() * 4.
+ // If length % 4 != 0, Hash will consume the less-significant bytes of the
+ // last uint32_t first.
//
// MurmurHash3_x86_32 takes a seed, for which 0 is the typical value. Hash
// hard-codes the seed to 0, since NormalizedMurmurHashEntropyProvider doesn't
diff --git a/chromium/components/variations/variations_request_scheduler_mobile.h b/chromium/components/variations/variations_request_scheduler_mobile.h
index 5b46f1f1286..838373fb4ac 100644
--- a/chromium/components/variations/variations_request_scheduler_mobile.h
+++ b/chromium/components/variations/variations_request_scheduler_mobile.h
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/timer/timer.h"
#include "components/variations/variations_request_scheduler.h"
class PrefService;
diff --git a/chromium/components/variations/variations_seed_processor.cc b/chromium/components/variations/variations_seed_processor.cc
index 3bc232fdbdc..58e41585210 100644
--- a/chromium/components/variations/variations_seed_processor.cc
+++ b/chromium/components/variations/variations_seed_processor.cc
@@ -84,12 +84,12 @@ void ForceExperimentState(
base::FieldTrial* trial) {
RegisterExperimentParams(study, experiment);
RegisterVariationIds(experiment, study.name());
- if (study.activation_type() == Study_ActivationType_ACTIVATION_AUTO) {
+ if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_STARTUP) {
// This call must happen after all params have been registered for the
// trial. Otherwise, since we look up params by trial and group name, the
// params won't be registered under the correct key.
trial->group();
- // UI Strings can only be overridden from ACTIVATION_AUTO experiments.
+ // UI Strings can only be overridden from ACTIVATE_ON_STARTUP experiments.
ApplyUIStringOverrides(experiment, override_callback);
}
}
@@ -297,7 +297,7 @@ void VariationsSeedProcessor::CreateTrialFromStudy(
if (enables_or_disables_features)
RegisterFeatureOverrides(processed_study, trial.get(), feature_list);
- if (study.activation_type() == Study_ActivationType_ACTIVATION_AUTO) {
+ if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_STARTUP) {
// This call must happen after all params have been registered for the
// trial. Otherwise, since we look up params by trial and group name, the
// params won't be registered under the correct key.
@@ -308,7 +308,7 @@ void VariationsSeedProcessor::CreateTrialFromStudy(
if (!has_overrides)
return;
- // UI Strings can only be overridden from ACTIVATION_AUTO experiments.
+ // UI Strings can only be overridden from ACTIVATE_ON_STARTUP experiments.
int experiment_index = processed_study.GetExperimentIndexByName(group_name);
// If the chosen experiment was not found in the study, simply return.
// Although not normally expected, but could happen in exception cases, see
diff --git a/chromium/components/variations/variations_seed_processor_unittest.cc b/chromium/components/variations/variations_seed_processor_unittest.cc
index fcc5fb1c48f..f41d36ecc39 100644
--- a/chromium/components/variations/variations_seed_processor_unittest.cc
+++ b/chromium/components/variations/variations_seed_processor_unittest.cc
@@ -306,7 +306,7 @@ TEST_F(VariationsSeedProcessorTest, OverrideUIStrings) {
Study study;
study.set_name("Study1");
study.set_default_experiment_name("B");
- study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO);
+ study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
Study_Experiment* experiment1 = AddExperiment("A", 0, &study);
Study_Experiment_OverrideUIString* override =
@@ -339,7 +339,7 @@ TEST_F(VariationsSeedProcessorTest, OverrideUIStringsWithForcingFlag) {
Study study = CreateStudyWithFlagGroups(100, 0, 0);
ASSERT_EQ(kForcingFlag1, study.experiment(1).forcing_flag());
- study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO);
+ study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
Study_Experiment_OverrideUIString* override =
study.mutable_experiment(1)->add_override_ui_string();
override->set_name_hash(1234);
@@ -451,7 +451,7 @@ TEST_F(VariationsSeedProcessorTest, ValidateStudyWithAssociatedFeatures) {
// Setting a different activation type should result in empty
// |associated_features|.
- study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO);
+ study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
EXPECT_TRUE(processed_study.Init(&study, false));
EXPECT_THAT(processed_study.associated_features(), IsEmpty());
}
@@ -539,14 +539,14 @@ TEST_F(VariationsSeedProcessorTest, StartsActive) {
study2->set_default_experiment_name("Default");
AddExperiment("BB", 100, study2);
AddExperiment("Default", 0, study2);
- study2->set_activation_type(Study_ActivationType_ACTIVATION_AUTO);
+ study2->set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
Study* study3 = seed.add_study();
study3->set_name("C");
study3->set_default_experiment_name("Default");
AddExperiment("CC", 100, study3);
AddExperiment("Default", 0, study3);
- study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT);
+ study3->set_activation_type(Study_ActivationType_ACTIVATE_ON_QUERY);
ClientFilterableState client_state;
client_state.locale = "en-CA";
@@ -561,8 +561,8 @@ TEST_F(VariationsSeedProcessorTest, StartsActive) {
override_callback_.callback(), nullptr,
&feature_list_);
- // Non-specified and ACTIVATION_EXPLICIT should not start active, but
- // ACTIVATION_AUTO should.
+ // Non-specified and ACTIVATE_ON_QUERY should not start active, but
+ // ACTIVATE_ON_STARTUP should.
EXPECT_FALSE(base::FieldTrialList::IsTrialActive("A"));
EXPECT_TRUE(base::FieldTrialList::IsTrialActive("B"));
EXPECT_FALSE(base::FieldTrialList::IsTrialActive("C"));
@@ -583,7 +583,7 @@ TEST_F(VariationsSeedProcessorTest, StartsActiveWithFlag) {
base::FieldTrialList field_trial_list(nullptr);
Study study = CreateStudyWithFlagGroups(100, 0, 0);
- study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO);
+ study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP);
EXPECT_TRUE(CreateTrialFromStudy(study));
EXPECT_TRUE(base::FieldTrialList::IsTrialActive(kFlagStudyName));
diff --git a/chromium/components/vector_icons/BUILD.gn b/chromium/components/vector_icons/BUILD.gn
index f6c69848fad..474e9b5556a 100644
--- a/chromium/components/vector_icons/BUILD.gn
+++ b/chromium/components/vector_icons/BUILD.gn
@@ -47,6 +47,7 @@ aggregate_vector_icons("components_vector_icons") {
"replay.icon",
"screen_share.icon",
"search.icon",
+ "serial_port.icon",
"usb.icon",
"videocam.icon",
"warning.icon",
diff --git a/chromium/components/vector_icons/serial_port.icon b/chromium/components/vector_icons/serial_port.icon
new file mode 100644
index 00000000000..84d6f1ef1f4
--- /dev/null
+++ b/chromium/components/vector_icons/serial_port.icon
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 18,
+STROKE, 0.53f,
+MOVE_TO, 2.01f, 5.55f,
+H_LINE_TO, 16,
+R_CUBIC_TO, 0.44f, 0, 0.81f, 0.58f, 0.7f, 1,
+R_LINE_TO, -1.5f, 5.1f,
+R_CUBIC_TO, -0.12f, 0.43f, -0.35f, 0.8f, -0.8f, 0.8f,
+H_LINE_TO, 3.6f,
+R_CUBIC_TO, -0.44f, 0, -0.67f, -0.37f, -0.8f, -0.8f,
+LINE_TO, 1.33f, 6.59f,
+R_CUBIC_TO, -0.13f, -0.42f, 0.25f, -1.03f, 0.7f, -1.03f,
+CLOSE,
+CIRCLE, 3.63, 7.53, 0.8,
+CIRCLE, 4.66, 10.49, 0.8,
+CIRCLE, 14.49, 7.53, 0.8,
+CIRCLE, 11.78, 7.53, 0.8,
+CIRCLE, 9.06, 7.53, 0.8,
+CIRCLE, 6.34, 7.53, 0.8,
+CIRCLE, 7.5, 10.49, 0.8,
+CIRCLE, 10.34, 10.49, 0.8,
+CIRCLE, 13.18, 10.49, 0.8
diff --git a/chromium/components/version_info/version_info.cc b/chromium/components/version_info/version_info.cc
index f378da9a685..8478204c5c3 100644
--- a/chromium/components/version_info/version_info.cc
+++ b/chromium/components/version_info/version_info.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/no_destructor.h"
+#include "base/strings/string_number_conversions.h"
#include "base/version.h"
#include "build/build_config.h"
#include "components/version_info/version_info_values.h"
@@ -24,6 +25,11 @@ std::string GetVersionNumber() {
return PRODUCT_VERSION;
}
+std::string GetMajorVersionNumber() {
+ DCHECK(version_info::GetVersion().IsValid());
+ return base::UintToString(version_info::GetVersion().components()[0]);
+}
+
const base::Version& GetVersion() {
static const base::NoDestructor<base::Version> version(GetVersionNumber());
return *version;
diff --git a/chromium/components/version_info/version_info.h b/chromium/components/version_info/version_info.h
index 4e5c20e727c..0b15db16a8e 100644
--- a/chromium/components/version_info/version_info.h
+++ b/chromium/components/version_info/version_info.h
@@ -25,6 +25,9 @@ std::string GetProductName();
// Returns the version number, e.g. "6.0.490.1".
std::string GetVersionNumber();
+// Returns the major component of the version, e.g. "6".
+std::string GetMajorVersionNumber();
+
// Returns the result of GetVersionNumber() as a base::Version.
const base::Version& GetVersion();
diff --git a/chromium/components/version_ui/resources/about_version.html b/chromium/components/version_ui/resources/about_version.html
index a6ddaff346c..83e52528f5b 100644
--- a/chromium/components/version_ui/resources/about_version.html
+++ b/chromium/components/version_ui/resources/about_version.html
@@ -145,6 +145,5 @@ about:version template page
</tr>
</table>
</div>
- <script src="chrome://resources/js/i18n_template.js"></script>
</body>
</html>
diff --git a/chromium/components/visitedlink/renderer/visitedlink_slave.cc b/chromium/components/visitedlink/renderer/visitedlink_slave.cc
index 62fe684ceb8..e894c81e7b7 100644
--- a/chromium/components/visitedlink/renderer/visitedlink_slave.cc
+++ b/chromium/components/visitedlink/renderer/visitedlink_slave.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bind.h"
#include "base/logging.h"
#include "third_party/blink/public/web/web_view.h"
diff --git a/chromium/components/viz/client/client_resource_provider.cc b/chromium/components/viz/client/client_resource_provider.cc
index 069774ca3df..efca8bb3ee3 100644
--- a/chromium/components/viz/client/client_resource_provider.cc
+++ b/chromium/components/viz/client/client_resource_provider.cc
@@ -4,11 +4,13 @@
#include "components/viz/client/client_resource_provider.h"
+#include "base/bind.h"
#include "base/bits.h"
#include "base/debug/stack_trace.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/context_provider.h"
+#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/common/resources/returned_resource.h"
@@ -93,6 +95,35 @@ void ClientResourceProvider::PrepareSendToParent(
const std::vector<ResourceId>& export_ids,
std::vector<TransferableResource>* list,
ContextProvider* context_provider) {
+ auto cb = base::BindOnce(
+ [](scoped_refptr<ContextProvider> context_provider,
+ std::vector<GLbyte*>* tokens) {
+ context_provider->ContextGL()->VerifySyncTokensCHROMIUM(tokens->data(),
+ tokens->size());
+ },
+ base::WrapRefCounted(context_provider));
+ PrepareSendToParentInternal(export_ids, list, std::move(cb));
+}
+
+void ClientResourceProvider::PrepareSendToParent(
+ const std::vector<ResourceId>& export_ids,
+ std::vector<TransferableResource>* list,
+ RasterContextProvider* context_provider) {
+ PrepareSendToParentInternal(
+ export_ids, list,
+ base::BindOnce(
+ [](scoped_refptr<RasterContextProvider> context_provider,
+ std::vector<GLbyte*>* tokens) {
+ context_provider->RasterInterface()->VerifySyncTokensCHROMIUM(
+ tokens->data(), tokens->size());
+ },
+ base::WrapRefCounted(context_provider)));
+}
+
+void ClientResourceProvider::PrepareSendToParentInternal(
+ const std::vector<ResourceId>& export_ids,
+ std::vector<TransferableResource>* list,
+ base::OnceCallback<void(std::vector<GLbyte*>* tokens)> verify_sync_tokens) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// This function goes through the array multiple times, store the resources
@@ -121,9 +152,8 @@ void ClientResourceProvider::PrepareSendToParent(
if (!unverified_sync_tokens.empty()) {
DCHECK(verified_sync_tokens_required_);
- DCHECK(context_provider);
- context_provider->ContextGL()->VerifySyncTokensCHROMIUM(
- unverified_sync_tokens.data(), unverified_sync_tokens.size());
+ DCHECK(verify_sync_tokens);
+ std::move(verify_sync_tokens).Run(&unverified_sync_tokens);
}
for (ImportedResource* imported : imports) {
diff --git a/chromium/components/viz/client/client_resource_provider.h b/chromium/components/viz/client/client_resource_provider.h
index 6de51210f75..f3965af5e05 100644
--- a/chromium/components/viz/client/client_resource_provider.h
+++ b/chromium/components/viz/client/client_resource_provider.h
@@ -32,6 +32,7 @@ class RasterInterface;
namespace viz {
class ContextProvider;
+class RasterContextProvider;
// This class is used to give an integer name (ResourceId) to a gpu or software
// resource (shipped as a TransferableResource), in order to use that name in
@@ -58,6 +59,13 @@ class VIZ_CLIENT_EXPORT ClientResourceProvider {
void PrepareSendToParent(
const std::vector<ResourceId>& resource_ids,
std::vector<TransferableResource>* transferable_resources,
+ RasterContextProvider* context_provider);
+
+ // TODO(sergeyu): Remove after updating all callers to use the above version
+ // of this method.
+ void PrepareSendToParent(
+ const std::vector<ResourceId>& resource_ids,
+ std::vector<TransferableResource>* transferable_resources,
ContextProvider* context_provider);
// Receives resources from the parent, moving them from mailboxes. ResourceIds
@@ -126,6 +134,12 @@ class VIZ_CLIENT_EXPORT ClientResourceProvider {
private:
struct ImportedResource;
+ void PrepareSendToParentInternal(
+ const std::vector<ResourceId>& export_ids,
+ std::vector<TransferableResource>* list,
+ base::OnceCallback<void(std::vector<GLbyte*>* tokens)>
+ verify_sync_tokens);
+
THREAD_CHECKER(thread_checker_);
const bool verified_sync_tokens_required_;
diff --git a/chromium/components/viz/client/client_resource_provider_unittest.cc b/chromium/components/viz/client/client_resource_provider_unittest.cc
index cdb71a9b030..e948d23c003 100644
--- a/chromium/components/viz/client/client_resource_provider_unittest.cc
+++ b/chromium/components/viz/client/client_resource_provider_unittest.cc
@@ -80,9 +80,9 @@ class ClientResourceProviderTest : public testing::TestWithParam<bool> {
std::unique_ptr<ClientResourceProvider> provider_;
};
-INSTANTIATE_TEST_CASE_P(ClientResourceProviderTests,
- ClientResourceProviderTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(ClientResourceProviderTests,
+ ClientResourceProviderTest,
+ ::testing::Values(false, true));
class MockReleaseCallback {
public:
diff --git a/chromium/components/viz/common/BUILD.gn b/chromium/components/viz/common/BUILD.gn
index 7156c304153..601ce40b6bf 100644
--- a/chromium/components/viz/common/BUILD.gn
+++ b/chromium/components/viz/common/BUILD.gn
@@ -69,6 +69,7 @@ if (enable_vulkan) {
"//base",
"//gpu/vulkan",
"//gpu/vulkan:buildflags",
+ "//ui/gfx",
]
}
}
@@ -81,6 +82,8 @@ viz_component("common") {
sources = [
"constants.cc",
"constants.h",
+ "display/overlay_strategy.cc",
+ "display/overlay_strategy.h",
"display/renderer_settings.cc",
"display/renderer_settings.h",
"features.cc",
@@ -152,6 +155,8 @@ viz_component("common") {
"quads/texture_draw_quad.h",
"quads/tile_draw_quad.cc",
"quads/tile_draw_quad.h",
+ "quads/video_hole_draw_quad.cc",
+ "quads/video_hole_draw_quad.h",
"quads/yuv_video_draw_quad.cc",
"quads/yuv_video_draw_quad.h",
"resources/bitmap_allocation.cc",
@@ -196,6 +201,8 @@ viz_component("common") {
"traced_value.cc",
"traced_value.h",
"viz_common_export.h",
+ "viz_utils.cc",
+ "viz_utils.h",
]
deps = [
@@ -229,6 +236,10 @@ viz_component("common") {
deps += [ "//ui/base" ]
}
+ if (is_android) {
+ deps += [ "//gpu/config" ]
+ }
+
if (is_chromecast) {
defines += [ "IS_CHROMECAST" ]
}
@@ -250,6 +261,7 @@ viz_source_set("unit_tests") {
never_build_jumbo = true
testonly = true
sources = [
+ "display/overlay_strategy_unittest.cc",
"frame_sinks/begin_frame_args_unittest.cc",
"frame_sinks/begin_frame_source_unittest.cc",
"frame_sinks/copy_output_util_unittest.cc",
diff --git a/chromium/components/viz/common/DEPS b/chromium/components/viz/common/DEPS
index d1f52eb3b25..e8cea65c0db 100644
--- a/chromium/components/viz/common/DEPS
+++ b/chromium/components/viz/common/DEPS
@@ -35,4 +35,7 @@ specific_include_rules = {
"+gpu/ipc/gl_in_process_context.h",
"+gpu/ipc/test_gpu_thread_holder.h",
],
+ "features.cc" : [
+ "+gpu/config/gpu_finch_features.h",
+ ],
}
diff --git a/chromium/components/viz/common/display/overlay_strategy.cc b/chromium/components/viz/common/display/overlay_strategy.cc
new file mode 100644
index 00000000000..7dfdd6337c8
--- /dev/null
+++ b/chromium/components/viz/common/display/overlay_strategy.cc
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/common/display/overlay_strategy.h"
+
+#include "base/logging.h"
+#include "base/strings/string_split.h"
+
+namespace viz {
+
+std::vector<OverlayStrategy> ParseOverlayStategies(
+ const std::string& strategies_string) {
+ std::vector<OverlayStrategy> strategies;
+
+ auto strategy_names = base::SplitStringPiece(
+ strategies_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ for (auto& strategy_name : strategy_names) {
+ if (strategy_name == "single-fullscreen") {
+ strategies.push_back(OverlayStrategy::kFullscreen);
+ } else if (strategy_name == "single-on-top") {
+ strategies.push_back(OverlayStrategy::kSingleOnTop);
+ } else if (strategy_name == "underlay") {
+ strategies.push_back(OverlayStrategy::kUnderlay);
+ } else if (strategy_name == "cast") {
+ strategies.push_back(OverlayStrategy::kUnderlayCast);
+ } else {
+ LOG(ERROR) << "Unrecognized overlay strategy " << strategy_name;
+ }
+ }
+ return strategies;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/common/display/overlay_strategy.h b/chromium/components/viz/common/display/overlay_strategy.h
new file mode 100644
index 00000000000..d88cc314b0b
--- /dev/null
+++ b/chromium/components/viz/common/display/overlay_strategy.h
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_
+#define COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_
+
+#include <string>
+#include <vector>
+
+#include "components/viz/common/viz_common_export.h"
+
+namespace viz {
+
+// Enum used for UMA histogram. These enum values must not be changed or
+// reused.
+enum class OverlayStrategy {
+ kUnknown = 0,
+ kNoStrategyUsed = 1,
+ kFullscreen = 2,
+ kSingleOnTop = 3,
+ kUnderlay = 4,
+ kUnderlayCast = 5,
+ kMaxValue = kUnderlayCast,
+};
+
+// Parses a comma separated list of overlay strategy types and returns a list
+// of the corresponding OverlayStrategy enum values.
+VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStategies(
+ const std::string& strategies_string);
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_
diff --git a/chromium/components/viz/common/display/overlay_strategy_unittest.cc b/chromium/components/viz/common/display/overlay_strategy_unittest.cc
new file mode 100644
index 00000000000..7df3227ba05
--- /dev/null
+++ b/chromium/components/viz/common/display/overlay_strategy_unittest.cc
@@ -0,0 +1,43 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/common/display/overlay_strategy.h"
+
+#include <string>
+#include <vector>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::IsEmpty;
+using testing::UnorderedElementsAre;
+
+namespace viz {
+
+TEST(ParseOverlayStrategiesTest, ParseEmptyList) {
+ std::vector<OverlayStrategy> strategies = ParseOverlayStategies("");
+ EXPECT_THAT(strategies, IsEmpty());
+}
+
+TEST(ParseOverlayStrategiesTest, ParseFullList) {
+ std::vector<OverlayStrategy> strategies =
+ ParseOverlayStategies("single-fullscreen,single-on-top,underlay,cast");
+
+ EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen,
+ OverlayStrategy::kSingleOnTop,
+ OverlayStrategy::kUnderlay,
+ OverlayStrategy::kUnderlayCast));
+}
+
+TEST(ParseOverlayStrategiesTest, BadValue) {
+ std::vector<OverlayStrategy> strategies =
+ ParseOverlayStategies("single-fullscreen,bad-value,underlay");
+
+ // The string "bad-value" doesn't correspond to an overlay strategy so it
+ // should be skipped.
+ EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen,
+ OverlayStrategy::kUnderlay));
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/common/display/renderer_settings.h b/chromium/components/viz/common/display/renderer_settings.h
index 2b8cd275a5e..b40fa9cdd72 100644
--- a/chromium/components/viz/common/display/renderer_settings.h
+++ b/chromium/components/viz/common/display/renderer_settings.h
@@ -29,8 +29,8 @@ class VIZ_COMMON_EXPORT RendererSettings {
bool release_overlay_resources_after_gpu_query = false;
bool tint_gl_composited_content = false;
bool show_overdraw_feedback = false;
- bool enable_draw_occlusion = false;
bool use_skia_renderer = false;
+ bool use_skia_renderer_non_ddl = false;
bool allow_overlays = true;
bool dont_round_texture_sizes_for_pixel_tests = false;
int highp_threshold_min = 0;
@@ -48,6 +48,7 @@ class VIZ_COMMON_EXPORT RendererSettings {
gfx::Size initial_screen_size = gfx::Size(0, 0);
gfx::ColorSpace color_space;
+ bool backed_by_surface_texture = false;
#endif
};
diff --git a/chromium/components/viz/common/features.cc b/chromium/components/viz/common/features.cc
index 1f35ba2f3c9..d7726323708 100644
--- a/chromium/components/viz/common/features.cc
+++ b/chromium/components/viz/common/features.cc
@@ -8,12 +8,11 @@
#include "build/build_config.h"
#include "components/viz/common/switches.h"
-namespace features {
+#if defined(OS_ANDROID)
+#include "gpu/config/gpu_finch_features.h" // nogncheck
+#endif
-// Enables running draw occlusion algorithm to remove Draw Quads that are not
-// shown on screen from CompositorFrame.
-const base::Feature kEnableDrawOcclusion{"DrawOcclusion",
- base::FEATURE_ENABLED_BY_DEFAULT};
+namespace features {
#if defined(USE_AURA) || defined(OS_MACOSX)
const base::Feature kEnableSurfaceSynchronization{
@@ -28,7 +27,7 @@ const base::Feature kEnableSurfaceSynchronization{
// (OOP-D).
// TODO(dnicoara): Look at enabling Chromecast support when ChromeOS support is
// ready.
-#if defined(OS_CHROMEOS) || defined(IS_CHROMECAST) || defined(OS_ANDROID)
+#if defined(OS_CHROMEOS) || defined(IS_CHROMECAST)
const base::Feature kVizDisplayCompositor{"VizDisplayCompositor",
base::FEATURE_DISABLED_BY_DEFAULT};
#else
@@ -47,15 +46,27 @@ const base::Feature kEnableVizHitTestSurfaceLayer{
const base::Feature kUseSkiaRenderer{"UseSkiaRenderer",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Use the SkiaRenderer without DDL.
+const base::Feature kUseSkiaRendererNonDDL{"UseSkiaRendererNonDDL",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Use the SkiaRenderer to record SkPicture.
const base::Feature kRecordSkPicture{"RecordSkPicture",
base::FEATURE_DISABLED_BY_DEFAULT};
bool IsSurfaceSynchronizationEnabled() {
auto* command_line = base::CommandLine::ForCurrentProcess();
- return base::FeatureList::IsEnabled(kEnableSurfaceSynchronization) ||
- command_line->HasSwitch(switches::kEnableSurfaceSynchronization) ||
- base::FeatureList::IsEnabled(kVizDisplayCompositor);
+ return IsVizDisplayCompositorEnabled() ||
+ base::FeatureList::IsEnabled(kEnableSurfaceSynchronization) ||
+ command_line->HasSwitch(switches::kEnableSurfaceSynchronization);
+}
+
+bool IsVizDisplayCompositorEnabled() {
+#if defined(OS_ANDROID)
+ if (features::IsAndroidSurfaceControlEnabled())
+ return true;
+#endif
+ return base::FeatureList::IsEnabled(kVizDisplayCompositor);
}
bool IsVizHitTestingDebugEnabled() {
@@ -82,14 +93,14 @@ bool IsVizHitTestingSurfaceLayerEnabled() {
base::FeatureList::IsEnabled(kEnableVizHitTestSurfaceLayer);
}
-bool IsDrawOcclusionEnabled() {
- return base::FeatureList::IsEnabled(kEnableDrawOcclusion);
-}
-
bool IsUsingSkiaRenderer() {
return base::FeatureList::IsEnabled(kUseSkiaRenderer);
}
+bool IsUsingSkiaRendererNonDDL() {
+ return base::FeatureList::IsEnabled(kUseSkiaRendererNonDDL);
+}
+
bool IsRecordingSkPicture() {
return IsUsingSkiaRenderer() &&
base::FeatureList::IsEnabled(kRecordSkPicture);
diff --git a/chromium/components/viz/common/features.h b/chromium/components/viz/common/features.h
index 2d76f380b3a..1ddae70cd74 100644
--- a/chromium/components/viz/common/features.h
+++ b/chromium/components/viz/common/features.h
@@ -11,21 +11,22 @@
namespace features {
-VIZ_COMMON_EXPORT extern const base::Feature kEnableDrawOcclusion;
VIZ_COMMON_EXPORT extern const base::Feature kEnableSurfaceSynchronization;
VIZ_COMMON_EXPORT extern const base::Feature kEnableVizHitTestDrawQuad;
VIZ_COMMON_EXPORT extern const base::Feature kEnableVizHitTestSurfaceLayer;
VIZ_COMMON_EXPORT extern const base::Feature kUseSkiaRenderer;
+VIZ_COMMON_EXPORT extern const base::Feature kUseSkiaRendererNonDDL;
VIZ_COMMON_EXPORT extern const base::Feature kRecordSkPicture;
VIZ_COMMON_EXPORT extern const base::Feature kVizDisplayCompositor;
-VIZ_COMMON_EXPORT bool IsDrawOcclusionEnabled();
VIZ_COMMON_EXPORT bool IsSurfaceSynchronizationEnabled();
+VIZ_COMMON_EXPORT bool IsVizDisplayCompositorEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingDebugEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingDrawQuadEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingSurfaceLayerEnabled();
VIZ_COMMON_EXPORT bool IsUsingSkiaRenderer();
+VIZ_COMMON_EXPORT bool IsUsingSkiaRendererNonDDL();
VIZ_COMMON_EXPORT bool IsRecordingSkPicture();
} // namespace features
diff --git a/chromium/components/viz/common/frame_sinks/begin_frame_args.cc b/chromium/components/viz/common/frame_sinks/begin_frame_args.cc
index 336637875f5..0466d995dbb 100644
--- a/chromium/components/viz/common/frame_sinks/begin_frame_args.cc
+++ b/chromium/components/viz/common/frame_sinks/begin_frame_args.cc
@@ -98,20 +98,6 @@ void BeginFrameArgs::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetBoolean("animate_only", animate_only);
}
-// This is a hard-coded deadline adjustment that assumes 60Hz, to be used in
-// cases where a good estimated draw time is not known. Using 1/3 of the vsync
-// as the default adjustment gives the Browser the last 1/3 of a frame to
-// produce output, the Renderer Impl thread the middle 1/3 of a frame to produce
-// ouput, and the Renderer Main thread the first 1/3 of a frame to produce
-// output.
-base::TimeDelta BeginFrameArgs::DefaultEstimatedParentDrawTime() {
- return base::TimeDelta::FromMicroseconds(16666 / 3);
-}
-
-base::TimeDelta BeginFrameArgs::DefaultInterval() {
- return base::TimeDelta::FromMicroseconds(16666);
-}
-
BeginFrameAck::BeginFrameAck()
: source_id(0),
sequence_number(BeginFrameArgs::kInvalidFrameNumber),
diff --git a/chromium/components/viz/common/frame_sinks/begin_frame_args.h b/chromium/components/viz/common/frame_sinks/begin_frame_args.h
index 63642475f67..faf84916e69 100644
--- a/chromium/components/viz/common/frame_sinks/begin_frame_args.h
+++ b/chromium/components/viz/common/frame_sinks/begin_frame_args.h
@@ -80,13 +80,21 @@ struct VIZ_COMMON_EXPORT BeginFrameArgs {
base::TimeDelta interval,
BeginFrameArgsType type);
- // This is the default delta that will be used to adjust the deadline when
- // proper draw-time estimations are not yet available.
- static base::TimeDelta DefaultEstimatedParentDrawTime();
-
- // This is the default interval to use to avoid sprinkling the code with
- // magic numbers.
- static base::TimeDelta DefaultInterval();
+ // This is the default interval assuming 60Hz to use to avoid sprinkling the
+ // code with magic numbers.
+ static constexpr base::TimeDelta DefaultInterval() {
+ return base::TimeDelta::FromMicroseconds(16666);
+ }
+
+ // This is a hard-coded deadline adjustment that assumes 60Hz, to be used in
+ // cases where a good estimated draw time is not known. Using 1/3 of the vsync
+ // as the default adjustment gives the Browser the last 1/3 of a frame to
+ // produce output, the Renderer Impl thread the middle 1/3 of a frame to
+ // produce ouput, and the Renderer Main thread the first 1/3 of a frame to
+ // produce output.
+ static constexpr base::TimeDelta DefaultEstimatedParentDrawTime() {
+ return base::TimeDelta::FromMicroseconds(16666 / 3);
+ }
bool IsValid() const { return interval >= base::TimeDelta(); }
diff --git a/chromium/components/viz/common/frame_sinks/begin_frame_source.cc b/chromium/components/viz/common/frame_sinks/begin_frame_source.cc
index 65b081cb925..769cd717560 100644
--- a/chromium/components/viz/common/frame_sinks/begin_frame_source.cc
+++ b/chromium/components/viz/common/frame_sinks/begin_frame_source.cc
@@ -41,8 +41,29 @@ void FilterAndIssueBeginFrame(BeginFrameObserver* observer,
observer->OnBeginFrame(args);
}
+// Checks |args| for continuity with our last args. It is possible that the
+// source in which |args| originate changes, or that our hookup to this source
+// changes, so we have to check for continuity. See also
+// https://crbug.com/690127 for what may happen without this check.
+bool CheckBeginFrameContinuity(BeginFrameObserver* observer,
+ const BeginFrameArgs& args) {
+ const BeginFrameArgs& last_args = observer->LastUsedBeginFrameArgs();
+ if (!last_args.IsValid() || (args.frame_time > last_args.frame_time)) {
+ DCHECK((args.source_id != last_args.source_id) ||
+ (args.sequence_number > last_args.sequence_number))
+ << "current " << args.AsValue()->ToString() << ", last "
+ << last_args.AsValue()->ToString();
+ return true;
+ }
+ return false;
+}
} // namespace
+// BeginFrameObserver -----------------------------------------------------
+bool BeginFrameObserver::IsRoot() const {
+ return false;
+}
+
// BeginFrameObserverBase -------------------------------------------------
BeginFrameObserverBase::BeginFrameObserverBase() = default;
@@ -385,18 +406,24 @@ void ExternalBeginFrameSource::OnBeginFrame(const BeginFrameArgs& args) {
last_begin_frame_args_ = args;
base::flat_set<BeginFrameObserver*> observers(observers_);
+
+ // Process non-root observers.
+ // TODO(ericrk): Remove root/non-root handling once a better workaround
+ // exists. https://crbug.com/947717
for (auto* obs : observers) {
- // It is possible that the source in which |args| originate changes, or that
- // our hookup to this source changes, so we have to check for continuity.
- // See also https://crbug.com/690127 for what may happen without this check.
- const BeginFrameArgs& last_args = obs->LastUsedBeginFrameArgs();
- if (!last_args.IsValid() || (args.frame_time > last_args.frame_time)) {
- DCHECK((args.source_id != last_args.source_id) ||
- (args.sequence_number > last_args.sequence_number))
- << "current " << args.AsValue()->ToString() << ", last "
- << last_args.AsValue()->ToString();
- FilterAndIssueBeginFrame(obs, args);
- }
+ if (obs->IsRoot())
+ continue;
+ if (!CheckBeginFrameContinuity(obs, args))
+ continue;
+ FilterAndIssueBeginFrame(obs, args);
+ }
+ // Process root observers.
+ for (auto* obs : observers) {
+ if (!obs->IsRoot())
+ continue;
+ if (!CheckBeginFrameContinuity(obs, args))
+ continue;
+ FilterAndIssueBeginFrame(obs, args);
}
}
@@ -404,17 +431,9 @@ BeginFrameArgs ExternalBeginFrameSource::GetMissedBeginFrameArgs(
BeginFrameObserver* obs) {
if (!last_begin_frame_args_.IsValid())
return BeginFrameArgs();
-
- const BeginFrameArgs& last_args = obs->LastUsedBeginFrameArgs();
- if (last_args.IsValid() &&
- last_begin_frame_args_.frame_time <= last_args.frame_time) {
+ if (!CheckBeginFrameContinuity(obs, last_begin_frame_args_))
return BeginFrameArgs();
- }
- DCHECK((last_begin_frame_args_.source_id != last_args.source_id) ||
- (last_begin_frame_args_.sequence_number > last_args.sequence_number))
- << "current " << last_begin_frame_args_.AsValue()->ToString() << ", last "
- << last_args.AsValue()->ToString();
BeginFrameArgs missed_args = last_begin_frame_args_;
missed_args.type = BeginFrameArgs::MISSED;
return missed_args;
diff --git a/chromium/components/viz/common/frame_sinks/begin_frame_source.h b/chromium/components/viz/common/frame_sinks/begin_frame_source.h
index 3ccaace54d1..a718369264d 100644
--- a/chromium/components/viz/common/frame_sinks/begin_frame_source.h
+++ b/chromium/components/viz/common/frame_sinks/begin_frame_source.h
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
@@ -61,6 +62,13 @@ class VIZ_COMMON_EXPORT BeginFrameObserver {
// Whether the observer also wants to receive animate_only BeginFrames.
virtual bool WantsAnimateOnlyBeginFrames() const = 0;
+
+ // Indicates whether this observer is the root frame sink. This helps in
+ // a workaround for input jank, allowing us to deliver BeginFrames to the
+ // root last, avoiding a race.
+ // TODO(ericrk): Remove this once we have a longer-term fix.
+ // https://crbug.com/947717
+ virtual bool IsRoot() const;
};
// Simple base class which implements a BeginFrameObserver which checks the
@@ -299,6 +307,12 @@ class VIZ_COMMON_EXPORT ExternalBeginFrameSource : public BeginFrameSource {
void OnSetBeginFrameSourcePaused(bool paused);
void OnBeginFrame(const BeginFrameArgs& args);
+#if defined(OS_ANDROID)
+ // Notifies when the refresh rate of the display is updated. |refresh_rate| is
+ // the rate in frames per second.
+ virtual void UpdateRefreshRate(float refresh_rate) {}
+#endif
+
protected:
// Called on AddObserver and gets missed BeginFrameArgs for the given
// observer. The missed BeginFrame is sent only if the returned
diff --git a/chromium/components/viz/common/frame_sinks/begin_frame_source_unittest.cc b/chromium/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
index 6d5633a5791..65fc6fd095d 100644
--- a/chromium/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
+++ b/chromium/components/viz/common/frame_sinks/begin_frame_source_unittest.cc
@@ -618,5 +618,52 @@ TEST_F(ExternalBeginFrameSourceTest, DISABLED_GetMissedBeginFrameArgs) {
source_->AddObserver(obs_.get());
}
+// Tests that an observer which returns true from IsRoot is notified after
+// observers which return false.
+TEST_F(ExternalBeginFrameSourceTest, RootsNotifiedLast) {
+ using ::testing::InSequence;
+
+ NiceMock<MockBeginFrameObserver> obs1, obs2;
+ source_->AddObserver(&obs1);
+ source_->AddObserver(&obs2);
+
+ {
+ BeginFrameArgs args = CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, 0, 1, 10000, 10100, 100);
+ // Set obs1 to root, obs2 to child.
+ EXPECT_CALL(obs1, IsRoot()).WillRepeatedly(::testing::Return(true));
+ EXPECT_CALL(obs2, IsRoot()).WillRepeatedly(::testing::Return(false));
+ {
+ // Ensure that OnBeginFrame delivers the calls in the right order.
+ InSequence s;
+ EXPECT_CALL(obs2, OnBeginFrame(args))
+ .WillOnce(::testing::SaveArg<0>(&(obs2.last_begin_frame_args)));
+ EXPECT_CALL(obs1, OnBeginFrame(args))
+ .WillOnce(::testing::SaveArg<0>(&(obs1.last_begin_frame_args)));
+ source_->OnBeginFrame(args);
+ }
+ }
+
+ {
+ BeginFrameArgs args = CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, 0, 2, 10001, 10101, 100);
+ // Set obs2 to root, obs1 to child.
+ EXPECT_CALL(obs1, IsRoot()).WillRepeatedly(::testing::Return(false));
+ EXPECT_CALL(obs2, IsRoot()).WillRepeatedly(::testing::Return(true));
+ {
+ // Ensure that OnBeginFrame delivers the calls in the right order.
+ InSequence s;
+ EXPECT_CALL(obs1, OnBeginFrame(args))
+ .WillOnce(::testing::SaveArg<0>(&(obs1.last_begin_frame_args)));
+ EXPECT_CALL(obs2, OnBeginFrame(args))
+ .WillOnce(::testing::SaveArg<0>(&(obs2.last_begin_frame_args)));
+ source_->OnBeginFrame(args);
+ }
+ }
+
+ source_->RemoveObserver(&obs1);
+ source_->RemoveObserver(&obs2);
+}
+
} // namespace
} // namespace viz
diff --git a/chromium/components/viz/common/frame_sinks/copy_output_util.cc b/chromium/components/viz/common/frame_sinks/copy_output_util.cc
index 9c9bc255fec..fa917e2c7a2 100644
--- a/chromium/components/viz/common/frame_sinks/copy_output_util.cc
+++ b/chromium/components/viz/common/frame_sinks/copy_output_util.cc
@@ -40,8 +40,8 @@ gfx::Rect ComputeResultRect(const gfx::Rect& area,
const gfx::Vector2d& scale_to) {
DCHECK_GT(scale_from.x(), 0);
DCHECK_GT(scale_from.y(), 0);
- DCHECK_GT(scale_to.x(), 0);
- DCHECK_GT(scale_to.y(), 0);
+ DCHECK_GE(scale_to.x(), 0);
+ DCHECK_GE(scale_to.y(), 0);
const int64_t x = FloorScale(area.x(), scale_to.x(), scale_from.x());
const int64_t y = FloorScale(area.y(), scale_to.y(), scale_from.y());
@@ -70,5 +70,8 @@ gfx::Rect ComputeResultRect(const gfx::Rect& area,
static_cast<int>(w), static_cast<int>(h));
}
+RenderPassGeometry::RenderPassGeometry() = default;
+RenderPassGeometry::~RenderPassGeometry() = default;
+
} // namespace copy_output
} // namespace viz
diff --git a/chromium/components/viz/common/frame_sinks/copy_output_util.h b/chromium/components/viz/common/frame_sinks/copy_output_util.h
index b0db4159003..ef5da5b7bfc 100644
--- a/chromium/components/viz/common/frame_sinks/copy_output_util.h
+++ b/chromium/components/viz/common/frame_sinks/copy_output_util.h
@@ -7,10 +7,8 @@
#include "components/viz/common/viz_common_export.h"
-namespace gfx {
-class Rect;
-class Vector2d;
-} // namespace gfx
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
namespace viz {
namespace copy_output {
@@ -23,6 +21,29 @@ gfx::Rect VIZ_COMMON_EXPORT ComputeResultRect(const gfx::Rect& area,
const gfx::Vector2d& scale_from,
const gfx::Vector2d& scale_to);
+// Geometry of the CopyOutputRequest mapped to the draw and window space of
+// the relevant RenderPass.
+struct VIZ_COMMON_EXPORT RenderPassGeometry {
+ // Bounds CopyOutputRequest result. RenderPass output_rect clamped to
+ // CopyOutputRequest area. Represented in post-scaled draw coordinate space.
+ gfx::Rect result_bounds;
+
+ // |result_bounds| clamped to the CopyOutputRequest selection. Represented in
+ // post-scaled draw coordinate space. It is the region that is actually
+ // returned.
+ gfx::Rect result_selection;
+
+ // |result_bounds| represented in pre-scaled window coordinate space.
+ gfx::Rect sampling_bounds;
+
+ // If request is not scaled, the origin of |result_selection| in window
+ // coordinate space. Otherwise undefined.
+ gfx::Vector2d readback_offset;
+
+ RenderPassGeometry();
+ ~RenderPassGeometry();
+};
+
} // namespace copy_output
} // namespace viz
diff --git a/chromium/components/viz/common/gl_helper.cc b/chromium/components/viz/common/gl_helper.cc
index 29bfd28e87d..cbd11c70fcb 100644
--- a/chromium/components/viz/common/gl_helper.cc
+++ b/chromium/components/viz/common/gl_helper.cc
@@ -11,6 +11,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/containers/queue.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
diff --git a/chromium/components/viz/common/gl_helper_unittest.cc b/chromium/components/viz/common/gl_helper_unittest.cc
index ae1bf518938..a328f4e0978 100644
--- a/chromium/components/viz/common/gl_helper_unittest.cc
+++ b/chromium/components/viz/common/gl_helper_unittest.cc
@@ -1329,7 +1329,7 @@ TEST_P(GLHelperPixelReadbackTest, DISABLED_ScalePatching) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
GLHelperPixelReadbackTest,
::testing::Combine(
diff --git a/chromium/components/viz/common/gl_i420_converter_pixeltest.cc b/chromium/components/viz/common/gl_i420_converter_pixeltest.cc
index d6e27e9b7ea..05ac138b3a8 100644
--- a/chromium/components/viz/common/gl_i420_converter_pixeltest.cc
+++ b/chromium/components/viz/common/gl_i420_converter_pixeltest.cc
@@ -122,6 +122,6 @@ TEST_P(GLI420ConverterPixelTest, ScaleAndConvert) {
// Run the tests twice, once disallowing use of the MRT path, and once allowing
// its use (auto-detecting whether the current platform supports it).
-INSTANTIATE_TEST_CASE_P(, GLI420ConverterPixelTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, GLI420ConverterPixelTest, testing::Bool());
} // namespace viz
diff --git a/chromium/components/viz/common/gl_scaler.cc b/chromium/components/viz/common/gl_scaler.cc
index 417b83d412b..78b5725ffec 100644
--- a/chromium/components/viz/common/gl_scaler.cc
+++ b/chromium/components/viz/common/gl_scaler.cc
@@ -185,17 +185,16 @@ bool GLScaler::Configure(const Parameters& new_params) {
params_.scale_from != params_.scale_to) {
// Ensure the scaling color space is using a linear transfer function.
constexpr auto kLinearFunction = std::make_tuple(1, 0, 1, 0, 0, 0, 1);
- SkColorSpaceTransferFn fn;
+ skcms_TransferFunction fn;
if (params_.source_color_space.GetTransferFunction(&fn) &&
- std::make_tuple(fn.fA, fn.fB, fn.fC, fn.fD, fn.fE, fn.fF, fn.fG) ==
+ std::make_tuple(fn.a, fn.b, fn.c, fn.d, fn.e, fn.f, fn.g) ==
kLinearFunction) {
scaling_color_space_ = params_.source_color_space;
} else {
// Use the source color space, but with a linear transfer function.
skcms_Matrix3x3 to_XYZD50;
params_.source_color_space.GetPrimaryMatrix(&to_XYZD50);
- std::tie(fn.fA, fn.fB, fn.fC, fn.fD, fn.fE, fn.fF, fn.fG) =
- kLinearFunction;
+ std::tie(fn.a, fn.b, fn.c, fn.d, fn.e, fn.f, fn.g) = kLinearFunction;
scaling_color_space_ = gfx::ColorSpace::CreateCustom(to_XYZD50, fn);
}
intermediate_texture_type = GL_HALF_FLOAT_OES;
@@ -1390,6 +1389,7 @@ void GLScaler::ScalerStage::ScaleToMultipleOutputs(
// It would be better to stash the existing parameter values, and restore them
// back later. However, glGetTexParameteriv() currently requires a blocking
// call to the GPU service, which is extremely costly performance-wise.
+ gl_->ActiveTexture(GL_TEXTURE0);
gl_->BindTexture(GL_TEXTURE_2D, src_texture);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
diff --git a/chromium/components/viz/common/gl_scaler_shader_pixeltest.cc b/chromium/components/viz/common/gl_scaler_shader_pixeltest.cc
index 1b93812e9d8..ad3bc9acf3a 100644
--- a/chromium/components/viz/common/gl_scaler_shader_pixeltest.cc
+++ b/chromium/components/viz/common/gl_scaler_shader_pixeltest.cc
@@ -683,8 +683,8 @@ TEST_P(GLScalerShaderPixelTest, Export_PairwiseDeinterleave) {
ExpectAreTheSameImage(expected_b, actual_b);
}
-INSTANTIATE_TEST_CASE_P(,
- GLScalerShaderPixelTest,
- testing::Combine(testing::Bool(), testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(,
+ GLScalerShaderPixelTest,
+ testing::Combine(testing::Bool(), testing::Bool()));
} // namespace viz
diff --git a/chromium/components/viz/common/gpu/vulkan_in_process_context_provider.cc b/chromium/components/viz/common/gpu/vulkan_in_process_context_provider.cc
index 74d4461fc77..581794b801d 100644
--- a/chromium/components/viz/common/gpu/vulkan_in_process_context_provider.cc
+++ b/chromium/components/viz/common/gpu/vulkan_in_process_context_provider.cc
@@ -7,6 +7,7 @@
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_implementation.h"
+#include "gpu/vulkan/vulkan_instance.h"
#include "third_party/skia/include/gpu/GrContext.h"
namespace viz {
@@ -50,14 +51,25 @@ bool VulkanInProcessContextProvider::Initialize() {
backend_context.fDevice = device_queue_->GetVulkanDevice();
backend_context.fQueue = device_queue_->GetVulkanQueue();
backend_context.fGraphicsQueueIndex = device_queue_->GetVulkanQueueIndex();
+ backend_context.fInstanceVersion =
+ vulkan_implementation_->GetVulkanInstance()->api_version();
+
+ backend_context.fExtensions = 0;
+
+ // Instance extensions.
+ const gfx::ExtensionSet& extensions =
+ vulkan_implementation_->GetVulkanInstance()->enabled_extensions();
+ if (gfx::HasExtension(extensions, VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
+ backend_context.fExtensions |= kEXT_debug_report_GrVkExtensionFlag;
+ if (gfx::HasExtension(extensions, VK_KHR_SURFACE_EXTENSION_NAME))
+ backend_context.fExtensions |= kKHR_surface_GrVkExtensionFlag;
+
+ // Device extensions.
+ if (gfx::HasExtension(device_queue_->enabled_extensions(),
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
+ backend_context.fExtensions |= kKHR_swapchain_GrVkExtensionFlag;
+ }
- // gpu::VulkanInstance always initializes apiVersion=1.1.
- // TODO(sergeyu): Extend VulkanImplementation interface to provide apiVersion
- // and list of enabled extensions instead of hardcoding them here.
- backend_context.fInstanceVersion = VK_MAKE_VERSION(1, 1, 0);
- backend_context.fExtensions =
- kEXT_debug_report_GrVkExtensionFlag | kKHR_surface_GrVkExtensionFlag |
- kKHR_swapchain_GrVkExtensionFlag | kKHR_xcb_surface_GrVkExtensionFlag;
backend_context.fFeatures = kGeometryShader_GrVkFeatureFlag |
kDualSrcBlend_GrVkFeatureFlag |
kSampleRateShading_GrVkFeatureFlag;
diff --git a/chromium/components/viz/common/hit_test/hit_test_data_builder.cc b/chromium/components/viz/common/hit_test/hit_test_data_builder.cc
index 1d7ae75a599..1fce5952384 100644
--- a/chromium/components/viz/common/hit_test/hit_test_data_builder.cc
+++ b/chromium/components/viz/common/hit_test/hit_test_data_builder.cc
@@ -27,7 +27,8 @@ void AddHitTestRegion(const FrameSinkId& frame_sink_id,
const gfx::Rect& visible_rect,
const gfx::Transform& hit_test_region_transform,
std::vector<HitTestRegion>* regions,
- bool should_ask_for_child_region) {
+ bool should_ask_for_child_region,
+ bool ignores_input_event) {
regions->emplace_back();
HitTestRegion* hit_test_region = &regions->back();
hit_test_region->frame_sink_id = frame_sink_id;
@@ -39,6 +40,8 @@ void AddHitTestRegion(const FrameSinkId& frame_sink_id,
hit_test_region->async_hit_test_reasons =
AsyncHitTestReasons::kUseDrawQuadData;
}
+ if (ignores_input_event)
+ hit_test_region->flags |= HitTestRegionFlags::kHitTestIgnore;
hit_test_region->rect = visible_rect;
hit_test_region->transform = hit_test_region_transform;
}
@@ -100,10 +103,6 @@ void AddHitTestDataFromRenderPass(const CompositorFrame& frame,
if (quad->material == DrawQuad::SURFACE_CONTENT) {
const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
- // Skip the quad if it has pointer-events:none set.
- if (surface_quad->ignores_input_event)
- continue;
-
// Skip the quad if the transform is not invertible (i.e. it will not
// be able to receive events).
gfx::Transform quad_to_target_transform =
@@ -126,12 +125,14 @@ void AddHitTestDataFromRenderPass(const CompositorFrame& frame,
if (filter_regions.empty()) {
AddHitTestRegion(surface_quad->surface_range.end().frame_sink_id(),
surface_quad->rect, hit_test_region_transform, regions,
- should_ask_for_child_region);
+ should_ask_for_child_region,
+ surface_quad->ignores_input_event);
} else {
for (const auto& filter_region : filter_regions) {
AddHitTestRegion(surface_quad->surface_range.end().frame_sink_id(),
filter_region, hit_test_region_transform, regions,
- should_ask_for_child_region);
+ should_ask_for_child_region,
+ surface_quad->ignores_input_event);
}
}
} else if (quad->material == DrawQuad::RENDER_PASS) {
diff --git a/chromium/components/viz/common/quads/draw_quad.h b/chromium/components/viz/common/quads/draw_quad.h
index 4cbe49f365d..01de49eebf2 100644
--- a/chromium/components/viz/common/quads/draw_quad.h
+++ b/chromium/components/viz/common/quads/draw_quad.h
@@ -44,7 +44,8 @@ class VIZ_COMMON_EXPORT DrawQuad {
TEXTURE_CONTENT,
TILED_CONTENT,
YUV_VIDEO_CONTENT,
- MATERIAL_LAST = YUV_VIDEO_CONTENT
+ VIDEO_HOLE,
+ MATERIAL_LAST = VIDEO_HOLE
};
DrawQuad(const DrawQuad& other);
@@ -73,7 +74,8 @@ class VIZ_COMMON_EXPORT DrawQuad {
bool IsDebugQuad() const { return material == DEBUG_BORDER; }
bool ShouldDrawWithBlending() const {
- return needs_blending || shared_quad_state->opacity < 1.0f;
+ return needs_blending || shared_quad_state->opacity < 1.0f ||
+ shared_quad_state->blend_mode != SkBlendMode::kSrcOver;
}
// Is the left edge of this tile aligned with the originating layer's
diff --git a/chromium/components/viz/common/quads/draw_quad_perftest.cc b/chromium/components/viz/common/quads/draw_quad_perftest.cc
index 8e2353285c9..6759fde2469 100644
--- a/chromium/components/viz/common/quads/draw_quad_perftest.cc
+++ b/chromium/components/viz/common/quads/draw_quad_perftest.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/time/time.h"
-#include "cc/base/lap_timer.h"
+#include "base/timer/lap_timer.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/render_pass.h"
#include "components/viz/common/quads/texture_draw_quad.h"
@@ -104,7 +104,7 @@ class DrawQuadPerfTest : public testing::Test {
private:
std::unique_ptr<RenderPass> render_pass_;
SharedQuadState* shared_state_;
- cc::LapTimer timer_;
+ base::LapTimer timer_;
};
TEST_F(DrawQuadPerfTest, IterateResources) {
diff --git a/chromium/components/viz/common/quads/draw_quad_unittest.cc b/chromium/components/viz/common/quads/draw_quad_unittest.cc
index ceba6e7192b..99927327fcc 100644
--- a/chromium/components/viz/common/quads/draw_quad_unittest.cc
+++ b/chromium/components/viz/common/quads/draw_quad_unittest.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/unguessable_token.h"
#include "cc/base/math_util.h"
#include "cc/paint/filter_operations.h"
#include "cc/test/fake_raster_source.h"
@@ -24,6 +25,7 @@
#include "components/viz/common/quads/surface_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
@@ -255,24 +257,28 @@ TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
bool needs_blending = true;
ResourceId resource_id = 64;
gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
- gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
+ gfx::PointF uv_top_left(0.25f, 0.3f);
+ gfx::PointF uv_bottom_right(0.75f, 0.7f);
CREATE_SHARED_STATE();
CREATE_QUAD_NEW(StreamVideoDrawQuad, visible_rect, needs_blending,
- resource_id, resource_size_in_pixels, matrix);
+ resource_id, resource_size_in_pixels, uv_top_left,
+ uv_bottom_right);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
EXPECT_EQ(visible_rect, copy_quad->visible_rect);
EXPECT_EQ(needs_blending, copy_quad->needs_blending);
EXPECT_EQ(resource_id, copy_quad->resource_id());
EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
- EXPECT_EQ(matrix, copy_quad->matrix);
+ EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
+ EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
CREATE_QUAD_ALL(StreamVideoDrawQuad, resource_id, resource_size_in_pixels,
- matrix);
+ uv_top_left, uv_bottom_right);
EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
EXPECT_EQ(resource_id, copy_quad->resource_id());
EXPECT_EQ(resource_size_in_pixels, copy_quad->resource_size_in_pixels());
- EXPECT_EQ(matrix, copy_quad->matrix);
+ EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
+ EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
}
TEST(DrawQuadTest, CopySurfaceDrawQuad) {
@@ -392,6 +398,21 @@ TEST(DrawQuadTest, CopyTileDrawQuad) {
EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
}
+TEST(DrawQuadTest, CopyVideoHoleDrawQuad) {
+ gfx::Rect visible_rect(40, 50, 30, 20);
+ base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
+ CREATE_SHARED_STATE();
+
+ CREATE_QUAD_NEW(VideoHoleDrawQuad, visible_rect, overlay_plane_id);
+ EXPECT_EQ(DrawQuad::VIDEO_HOLE, copy_quad->material);
+ EXPECT_EQ(visible_rect, copy_quad->visible_rect);
+ EXPECT_EQ(overlay_plane_id, copy_quad->overlay_plane_id);
+
+ CREATE_QUAD_ALL(VideoHoleDrawQuad, overlay_plane_id);
+ EXPECT_EQ(DrawQuad::VIDEO_HOLE, copy_quad->material);
+ EXPECT_EQ(overlay_plane_id, copy_quad->overlay_plane_id);
+}
+
TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
gfx::Rect visible_rect(40, 50, 30, 20);
bool needs_blending = true;
@@ -567,11 +588,13 @@ TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
gfx::Rect visible_rect(40, 50, 30, 20);
ResourceId resource_id = 64;
gfx::Size resource_size_in_pixels = gfx::Size(40, 41);
- gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
+ gfx::PointF uv_top_left(0.25f, 0.3f);
+ gfx::PointF uv_bottom_right(0.75f, 0.7f);
CREATE_SHARED_STATE();
CREATE_QUAD_NEW(StreamVideoDrawQuad, visible_rect, needs_blending,
- resource_id, resource_size_in_pixels, matrix);
+ resource_id, resource_size_in_pixels, uv_top_left,
+ uv_bottom_right);
EXPECT_EQ(resource_id, quad_new->resource_id());
EXPECT_EQ(resource_size_in_pixels, quad_new->resource_size_in_pixels());
EXPECT_EQ(1, IterateAndCount(quad_new));
@@ -633,6 +656,15 @@ TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
EXPECT_EQ(resource_id + 1, quad_new->resource_id());
}
+TEST_F(DrawQuadIteratorTest, VideoHoleDrawQuad) {
+ gfx::Rect visible_rect(40, 50, 30, 20);
+ base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
+
+ CREATE_SHARED_STATE();
+ CREATE_QUAD_NEW(VideoHoleDrawQuad, visible_rect, overlay_plane_id);
+ EXPECT_EQ(0, IterateAndCount(quad_new));
+}
+
TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
gfx::Rect visible_rect(40, 50, 30, 20);
gfx::RectF ya_tex_coord_rect(0.0f, 0.0f, 0.75f, 0.5f);
@@ -695,6 +727,9 @@ TEST(DrawQuadTest, LargestQuadType) {
case DrawQuad::YUV_VIDEO_CONTENT:
largest = std::max(largest, sizeof(YUVVideoDrawQuad));
break;
+ case DrawQuad::VIDEO_HOLE:
+ largest = std::max(largest, sizeof(VideoHoleDrawQuad));
+ break;
case DrawQuad::INVALID:
break;
}
@@ -736,6 +771,9 @@ TEST(DrawQuadTest, LargestQuadType) {
case DrawQuad::YUV_VIDEO_CONTENT:
LOG(ERROR) << "YUVVideoDrawQuad " << sizeof(YUVVideoDrawQuad);
break;
+ case DrawQuad::VIDEO_HOLE:
+ LOG(ERROR) << "VideoHoleDrawQuad " << sizeof(VideoHoleDrawQuad);
+ break;
case DrawQuad::INVALID:
break;
}
diff --git a/chromium/components/viz/common/quads/frame_deadline.cc b/chromium/components/viz/common/quads/frame_deadline.cc
index f5f5619b86a..6ab63d9a38a 100644
--- a/chromium/components/viz/common/quads/frame_deadline.cc
+++ b/chromium/components/viz/common/quads/frame_deadline.cc
@@ -31,7 +31,7 @@ std::string FrameDeadline::ToString() const {
start_time_delta.InMilliseconds(),
use_default_lower_bound_deadline_
? "unresolved"
- : base::UintToString(deadline_in_frames_).c_str(),
+ : base::NumberToString(deadline_in_frames_).c_str(),
frame_interval_.InMilliseconds());
}
diff --git a/chromium/components/viz/common/quads/render_pass.cc b/chromium/components/viz/common/quads/render_pass.cc
index b432ad9e94a..1da238d0e83 100644
--- a/chromium/components/viz/common/quads/render_pass.cc
+++ b/chromium/components/viz/common/quads/render_pass.cc
@@ -26,6 +26,7 @@
#include "components/viz/common/quads/surface_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/common/traced_value.h"
@@ -189,7 +190,7 @@ void RenderPass::SetAll(uint64_t id,
const gfx::Transform& transform_to_root_target,
const cc::FilterOperations& filters,
const cc::FilterOperations& backdrop_filters,
- const gfx::RectF& backdrop_filter_bounds,
+ const gfx::RRectF& backdrop_filter_bounds,
const gfx::ColorSpace& color_space,
bool has_transparent_background,
bool cache_render_pass,
@@ -298,6 +299,9 @@ DrawQuad* RenderPass::CopyFromAndAppendDrawQuad(const DrawQuad* quad) {
case DrawQuad::SURFACE_CONTENT:
CopyFromAndAppendTypedDrawQuad<SurfaceDrawQuad>(quad);
break;
+ case DrawQuad::VIDEO_HOLE:
+ CopyFromAndAppendTypedDrawQuad<VideoHoleDrawQuad>(quad);
+ break;
case DrawQuad::YUV_VIDEO_CONTENT:
CopyFromAndAppendTypedDrawQuad<YUVVideoDrawQuad>(quad);
break;
diff --git a/chromium/components/viz/common/quads/render_pass.h b/chromium/components/viz/common/quads/render_pass.h
index b4f422630b6..a967fb9129d 100644
--- a/chromium/components/viz/common/quads/render_pass.h
+++ b/chromium/components/viz/common/quads/render_pass.h
@@ -20,7 +20,7 @@
#include "components/viz/common/viz_common_export.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/rrect_f.h"
#include "ui/gfx/transform.h"
namespace base {
@@ -91,7 +91,7 @@ class VIZ_COMMON_EXPORT RenderPass {
const gfx::Transform& transform_to_root_target,
const cc::FilterOperations& filters,
const cc::FilterOperations& backdrop_filters,
- const gfx::RectF& backdrop_filter_bounds,
+ const gfx::RRectF& backdrop_filter_bounds,
const gfx::ColorSpace& color_space,
bool has_transparent_background,
bool cache_render_pass,
@@ -131,7 +131,7 @@ class VIZ_COMMON_EXPORT RenderPass {
cc::FilterOperations backdrop_filters;
// Clipping bounds for backdrop filter.
- gfx::RectF backdrop_filter_bounds;
+ gfx::RRectF backdrop_filter_bounds;
// The color space into which content will be rendered for this render pass.
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
diff --git a/chromium/components/viz/common/quads/render_pass_unittest.cc b/chromium/components/viz/common/quads/render_pass_unittest.cc
index 57e756f5c82..9d106c73f0c 100644
--- a/chromium/components/viz/common/quads/render_pass_unittest.cc
+++ b/chromium/components/viz/common/quads/render_pass_unittest.cc
@@ -29,7 +29,7 @@ struct RenderPassSize {
gfx::Transform transform_to_root_target;
cc::FilterOperations filters;
cc::FilterOperations backdrop_filters;
- gfx::RectF backdrop_filter_bounds;
+ gfx::RRectF backdrop_filter_bounds;
gfx::ColorSpace color_space;
bool has_transparent_background;
bool generate_mipmap;
@@ -82,7 +82,7 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
filters.Append(cc::FilterOperation::CreateOpacityFilter(0.5));
cc::FilterOperations backdrop_filters;
backdrop_filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
- gfx::RectF backdrop_filter_bounds = gfx::RectF(10, 20, 130, 140);
+ gfx::RRectF backdrop_filter_bounds(10, 20, 130, 140, 1, 2, 3, 4, 5, 6, 7, 8);
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
bool has_transparent_background = true;
bool cache_render_pass = false;
@@ -114,8 +114,8 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
EXPECT_EQ(pass->damage_rect, copy->damage_rect);
EXPECT_EQ(pass->filters, copy->filters);
EXPECT_EQ(pass->backdrop_filters, copy->backdrop_filters);
- EXPECT_EQ(gfx::ToNearestRect(pass->backdrop_filter_bounds),
- gfx::ToNearestRect(copy->backdrop_filter_bounds));
+ EXPECT_TRUE(pass->backdrop_filter_bounds.ApproximatelyEqual(
+ copy->backdrop_filter_bounds, 0.001));
EXPECT_EQ(pass->has_transparent_background, copy->has_transparent_background);
EXPECT_EQ(pass->generate_mipmap, copy->generate_mipmap);
EXPECT_EQ(0u, copy->quad_list.size());
@@ -139,7 +139,7 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) {
filters.Append(cc::FilterOperation::CreateOpacityFilter(0.5));
cc::FilterOperations backdrop_filters;
backdrop_filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
- gfx::RectF backdrop_filter_bounds = gfx::RectF(10, 20, 130, 140);
+ gfx::RRectF backdrop_filter_bounds(10, 20, 130, 140, 1, 2, 3, 4, 5, 6, 7, 8);
gfx::ColorSpace color_space = gfx::ColorSpace::CreateXYZD50();
bool has_transparent_background = true;
bool cache_render_pass = false;
@@ -192,7 +192,8 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) {
contrib_filters.Append(cc::FilterOperation::CreateSepiaFilter(0.5));
cc::FilterOperations contrib_backdrop_filters;
contrib_backdrop_filters.Append(cc::FilterOperation::CreateSaturateFilter(1));
- gfx::RectF contrib_backdrop_filter_bounds = gfx::RectF(20, 30, 140, 150);
+ gfx::RRectF contrib_backdrop_filter_bounds(20, 30, 140, 150, 1, 2, 3, 4, 5, 6,
+ 7, 8);
gfx::ColorSpace contrib_color_space = gfx::ColorSpace::CreateSCRGBLinear();
bool contrib_has_transparent_background = true;
bool contrib_cache_render_pass = false;
@@ -247,7 +248,7 @@ TEST(RenderPassTest, CopyAllWithCulledQuads) {
filters.Append(cc::FilterOperation::CreateOpacityFilter(0.5));
cc::FilterOperations backdrop_filters;
backdrop_filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
- gfx::RectF backdrop_filter_bounds = gfx::RectF(10, 20, 130, 140);
+ gfx::RRectF backdrop_filter_bounds(10, 20, 130, 140, 1, 2, 3, 4, 5, 6, 7, 8);
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSCRGBLinear();
bool has_transparent_background = true;
bool cache_render_pass = false;
diff --git a/chromium/components/viz/common/quads/shared_quad_state.h b/chromium/components/viz/common/quads/shared_quad_state.h
index aa1cc84b91c..1de514c19f8 100644
--- a/chromium/components/viz/common/quads/shared_quad_state.h
+++ b/chromium/components/viz/common/quads/shared_quad_state.h
@@ -60,6 +60,13 @@ class VIZ_COMMON_EXPORT SharedQuadState {
float opacity;
SkBlendMode blend_mode;
int sorting_context_id;
+ // An internal flag used only in the SurfaceAggregator and the
+ // OverlayProcessor. If set to true surface's compositor frame was updated in
+ // current aggregation, and if set to false the surface has not changed since
+ // the previous frame. It can be used for underlay optimization when the quads
+ // on top are not damaged. SetAll() doesn't update this flag. It has to be set
+ // sepaerately.
+ bool has_surface_damage = false;
};
} // namespace viz
diff --git a/chromium/components/viz/common/quads/stream_video_draw_quad.cc b/chromium/components/viz/common/quads/stream_video_draw_quad.cc
index 03eaf79e2a5..47bada5efff 100644
--- a/chromium/components/viz/common/quads/stream_video_draw_quad.cc
+++ b/chromium/components/viz/common/quads/stream_video_draw_quad.cc
@@ -19,13 +19,15 @@ void StreamVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
bool needs_blending,
unsigned resource_id,
gfx::Size resource_size_in_pixels,
- const gfx::Transform& matrix) {
+ const gfx::PointF& uv_top_left,
+ const gfx::PointF& uv_bottom_right) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
visible_rect, needs_blending);
resources.ids[kResourceIdIndex] = resource_id;
overlay_resources.size_in_pixels[kResourceIdIndex] = resource_size_in_pixels;
resources.count = 1;
- this->matrix = matrix;
+ this->uv_top_left = uv_top_left;
+ this->uv_bottom_right = uv_bottom_right;
}
void StreamVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
@@ -34,13 +36,15 @@ void StreamVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
bool needs_blending,
unsigned resource_id,
gfx::Size resource_size_in_pixels,
- const gfx::Transform& matrix) {
+ const gfx::PointF& uv_top_left,
+ const gfx::PointF& uv_bottom_right) {
DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
visible_rect, needs_blending);
resources.ids[kResourceIdIndex] = resource_id;
overlay_resources.size_in_pixels[kResourceIdIndex] = resource_size_in_pixels;
resources.count = 1;
- this->matrix = matrix;
+ this->uv_top_left = uv_top_left;
+ this->uv_bottom_right = uv_bottom_right;
}
const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
@@ -52,7 +56,8 @@ const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
void StreamVideoDrawQuad::ExtendValue(
base::trace_event::TracedValue* value) const {
value->SetInteger("resource_id", resources.ids[kResourceIdIndex]);
- cc::MathUtil::AddToTracedValue("matrix", matrix, value);
+ cc::MathUtil::AddToTracedValue("uv_top_left", uv_top_left, value);
+ cc::MathUtil::AddToTracedValue("uv_bottom_right", uv_bottom_right, value);
}
StreamVideoDrawQuad::OverlayResources::OverlayResources() {}
diff --git a/chromium/components/viz/common/quads/stream_video_draw_quad.h b/chromium/components/viz/common/quads/stream_video_draw_quad.h
index efa82a151aa..63a18a37fe7 100644
--- a/chromium/components/viz/common/quads/stream_video_draw_quad.h
+++ b/chromium/components/viz/common/quads/stream_video_draw_quad.h
@@ -11,7 +11,7 @@
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/viz_common_export.h"
-#include "ui/gfx/transform.h"
+#include "ui/gfx/geometry/point_f.h"
namespace viz {
@@ -27,7 +27,8 @@ class VIZ_COMMON_EXPORT StreamVideoDrawQuad : public DrawQuad {
bool needs_blending,
unsigned resource_id,
gfx::Size resource_size_in_pixels,
- const gfx::Transform& matrix);
+ const gfx::PointF& uv_top_left,
+ const gfx::PointF& uv_bottom_right);
void SetAll(const SharedQuadState* shared_quad_state,
const gfx::Rect& rect,
@@ -35,9 +36,11 @@ class VIZ_COMMON_EXPORT StreamVideoDrawQuad : public DrawQuad {
bool needs_blending,
unsigned resource_id,
gfx::Size resource_size_in_pixels,
- const gfx::Transform& matrix);
+ const gfx::PointF& uv_top_left,
+ const gfx::PointF& uv_bottom_right);
- gfx::Transform matrix;
+ gfx::PointF uv_top_left;
+ gfx::PointF uv_bottom_right;
struct OverlayResources {
OverlayResources();
diff --git a/chromium/components/viz/common/quads/video_hole_draw_quad.cc b/chromium/components/viz/common/quads/video_hole_draw_quad.cc
new file mode 100644
index 00000000000..a3c8425ea82
--- /dev/null
+++ b/chromium/components/viz/common/quads/video_hole_draw_quad.cc
@@ -0,0 +1,48 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/common/quads/video_hole_draw_quad.h"
+
+#include <stddef.h>
+#include "base/trace_event/traced_value.h"
+#include "base/values.h"
+
+namespace viz {
+
+VideoHoleDrawQuad::VideoHoleDrawQuad() = default;
+
+VideoHoleDrawQuad::VideoHoleDrawQuad(const VideoHoleDrawQuad& other) = default;
+
+VideoHoleDrawQuad::~VideoHoleDrawQuad() = default;
+
+void VideoHoleDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
+ const gfx::Rect& rect,
+ const gfx::Rect& visible_rect,
+ const base::UnguessableToken& overlay_plane_id) {
+ DrawQuad::SetAll(shared_quad_state, DrawQuad::VIDEO_HOLE, rect, visible_rect,
+ /*needs_blending=*/false);
+ this->overlay_plane_id = overlay_plane_id;
+}
+
+void VideoHoleDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
+ const gfx::Rect& rect,
+ const gfx::Rect& visible_rect,
+ bool needs_blending,
+ const base::UnguessableToken& overlay_plane_id) {
+ DrawQuad::SetAll(shared_quad_state, DrawQuad::VIDEO_HOLE, rect, visible_rect,
+ needs_blending);
+ this->overlay_plane_id = overlay_plane_id;
+}
+
+const VideoHoleDrawQuad* VideoHoleDrawQuad::MaterialCast(const DrawQuad* quad) {
+ DCHECK(quad->material == DrawQuad::VIDEO_HOLE);
+ return static_cast<const VideoHoleDrawQuad*>(quad);
+}
+
+void VideoHoleDrawQuad::ExtendValue(
+ base::trace_event::TracedValue* value) const {
+ value->SetString("overlay_plane_id", overlay_plane_id.ToString());
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/common/quads/video_hole_draw_quad.h b/chromium/components/viz/common/quads/video_hole_draw_quad.h
new file mode 100644
index 00000000000..e4cbf07a1b0
--- /dev/null
+++ b/chromium/components/viz/common/quads/video_hole_draw_quad.h
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_COMMON_QUADS_VIDEO_HOLE_DRAW_QUAD_H_
+#define COMPONENTS_VIZ_COMMON_QUADS_VIDEO_HOLE_DRAW_QUAD_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+#include "base/unguessable_token.h"
+#include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/viz_common_export.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gl/dc_renderer_layer_params.h"
+
+namespace viz {
+
+// A VideoHoleDrawQuad is used by Chromecast to instruct that a video
+// overlay is to be activated. It carries |overlay_plane_id| which identifies
+// the origin of the video overlay frame. |overlay_plane_id| will be used
+// to find the right VideoDecoder to apply SetGeometry() on.
+class VIZ_COMMON_EXPORT VideoHoleDrawQuad : public DrawQuad {
+ public:
+ VideoHoleDrawQuad();
+ VideoHoleDrawQuad(const VideoHoleDrawQuad& other);
+ ~VideoHoleDrawQuad() override;
+
+ void SetNew(const SharedQuadState* shared_quad_state,
+ const gfx::Rect& rect,
+ const gfx::Rect& visible_rect,
+ const base::UnguessableToken& overlay_plane_id);
+
+ void SetAll(const SharedQuadState* shared_quad_state,
+ const gfx::Rect& rect,
+ const gfx::Rect& visible_rect,
+ bool needs_blending,
+ const base::UnguessableToken& overlay_plane_id);
+
+ static const VideoHoleDrawQuad* MaterialCast(const DrawQuad*);
+ base::UnguessableToken overlay_plane_id;
+
+ private:
+ void ExtendValue(base::trace_event::TracedValue* value) const override;
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_COMMON_QUADS_VIDEO_HOLE_DRAW_QUAD_H_
diff --git a/chromium/components/viz/common/resources/resource_format_utils.cc b/chromium/components/viz/common/resources/resource_format_utils.cc
index 012c6171076..f7852c439ad 100644
--- a/chromium/components/viz/common/resources/resource_format_utils.cc
+++ b/chromium/components/viz/common/resources/resource_format_utils.cc
@@ -425,15 +425,17 @@ VkFormat ToVkFormat(ResourceFormat format) {
case R16_EXT:
return VK_FORMAT_R16_UNORM;
case RGBX_8888:
- return VK_FORMAT_R8G8B8_UNORM;
+ return VK_FORMAT_R8G8B8A8_UNORM;
case BGRX_8888:
- return VK_FORMAT_B8G8R8_UNORM;
+ return VK_FORMAT_B8G8R8A8_UNORM;
case RGBX_1010102:
return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
case BGRX_1010102:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
case ALPHA_8:
+ return VK_FORMAT_R8_UNORM;
case LUMINANCE_8:
+ return VK_FORMAT_R8_UNORM;
case LUMINANCE_F16:
case YVU_420:
case YUV_420_BIPLANAR:
@@ -441,7 +443,7 @@ VkFormat ToVkFormat(ResourceFormat format) {
case ETC1:
break;
}
- NOTREACHED();
+ NOTREACHED() << "Unsupported format " << format;
return VK_FORMAT_UNDEFINED;
}
#endif
diff --git a/chromium/components/viz/common/resources/returned_resource.h b/chromium/components/viz/common/resources/returned_resource.h
index c3e72aa3fd6..c8f8ba40be5 100644
--- a/chromium/components/viz/common/resources/returned_resource.h
+++ b/chromium/components/viz/common/resources/returned_resource.h
@@ -17,7 +17,13 @@ namespace viz {
// parent compositor that corresponds to a TransferableResource that was
// first passed to the parent compositor.
struct VIZ_COMMON_EXPORT ReturnedResource {
- ReturnedResource() : id(0), count(0), lost(false) {}
+ ReturnedResource(ResourceId id,
+ gpu::SyncToken sync_token,
+ int count,
+ bool lost)
+ : id(id), sync_token(sync_token), count(count), lost(lost) {}
+
+ ReturnedResource() {}
bool operator==(const ReturnedResource& other) const {
return id == other.id && sync_token == other.sync_token &&
@@ -30,7 +36,7 @@ struct VIZ_COMMON_EXPORT ReturnedResource {
// |id| is an identifier generated by the child compositor that uniquely
// identifies a resource. This is the same ID space as TransferableResource.
- ResourceId id;
+ ResourceId id = 0;
// A |sync_token| is an identifier for a point in the parent compositor's
// command buffer. The child compositor then issues a WaitSyncPointCHROMIUM
@@ -42,12 +48,12 @@ struct VIZ_COMMON_EXPORT ReturnedResource {
// |count| is a reference count for this resource. A resource may be used
// by mulitple compositor frames submitted to the parent compositor. |count|
// is the number of references being returned back to the child compositor.
- int count;
+ int count = 0;
// If the resource is lost, then the returner cannot give a sync point for it,
// and so it has taken ownership of the resource. The receiver cannot do
// anything with the resource except delete it.
- bool lost;
+ bool lost = false;
};
} // namespace viz
diff --git a/chromium/components/viz/common/skia_helper.cc b/chromium/components/viz/common/skia_helper.cc
index 2228ca37349..f6413733f28 100644
--- a/chromium/components/viz/common/skia_helper.cc
+++ b/chromium/components/viz/common/skia_helper.cc
@@ -6,6 +6,7 @@
#include "cc/base/math_util.h"
#include "third_party/skia/include/effects/SkOverdrawColorFilter.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gfx/skia_util.h"
namespace viz {
diff --git a/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.cc b/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.cc
index b7ab824762e..3ab5170ccb1 100644
--- a/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.cc
+++ b/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.cc
@@ -4,8 +4,6 @@
#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
-#include <stdint.h>
-
#include "base/rand_util.h"
#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
@@ -24,6 +22,16 @@ ChildLocalSurfaceIdAllocator::ChildLocalSurfaceIdAllocator(
ChildLocalSurfaceIdAllocator::ChildLocalSurfaceIdAllocator()
: ChildLocalSurfaceIdAllocator(base::DefaultTickClock::GetInstance()) {}
+// static
+std::unique_ptr<ChildLocalSurfaceIdAllocator>
+ChildLocalSurfaceIdAllocator::CreateWithChildSequenceNumber(uint32_t value) {
+ std::unique_ptr<ChildLocalSurfaceIdAllocator> allocator =
+ std::make_unique<ChildLocalSurfaceIdAllocator>();
+ allocator->current_local_surface_id_allocation_.local_surface_id_
+ .child_sequence_number_ = value;
+ return allocator;
+}
+
bool ChildLocalSurfaceIdAllocator::UpdateFromParent(
const LocalSurfaceIdAllocation& parent_local_surface_id_allocation) {
const LocalSurfaceId& current_local_surface_id =
@@ -47,9 +55,29 @@ bool ChildLocalSurfaceIdAllocator::UpdateFromParent(
// than the one provided by the parent, then the merged LocalSurfaceId
// is actually a new LocalSurfaceId and so we report its allocation time
// as now.
+ if (current_local_surface_id != parent_allocated_local_surface_id) {
+ TRACE_EVENT_WITH_FLOW2(
+ TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+ "ChildLocalSurfaceIdAllocator::UpdateFromParent New Id Allocation",
+ TRACE_ID_LOCAL(
+ parent_allocated_local_surface_id.submission_trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "current",
+ current_local_surface_id_allocation_.ToString(), "parent",
+ parent_local_surface_id_allocation.ToString());
+ }
current_local_surface_id_allocation_.allocation_time_ =
tick_clock_->NowTicks();
} else {
+ if (current_local_surface_id != parent_allocated_local_surface_id) {
+ TRACE_EVENT_WITH_FLOW2(
+ TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+ "ChildLocalSurfaceIdAllocator::UpdateFromParent Synchronization",
+ TRACE_ID_LOCAL(
+ parent_allocated_local_surface_id.submission_trace_id()),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "current",
+ current_local_surface_id_allocation_.ToString(), "parent",
+ parent_local_surface_id_allocation.ToString());
+ }
current_local_surface_id_allocation_.allocation_time_ =
parent_local_surface_id_allocation.allocation_time();
}
@@ -92,4 +120,13 @@ void ChildLocalSurfaceIdAllocator::GenerateId() {
current_local_surface_id_allocation_.local_surface_id_.ToString());
}
+void ChildLocalSurfaceIdAllocator::GenerateIdOrIncrementChild() {
+ if (current_local_surface_id_allocation_.IsValid()) {
+ GenerateId();
+ } else {
+ ++current_local_surface_id_allocation_.local_surface_id_
+ .child_sequence_number_;
+ }
+}
+
} // namespace viz
diff --git a/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.h b/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.h
index 92f5e15144e..53db1256953 100644
--- a/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.h
+++ b/chromium/components/viz/common/surfaces/child_local_surface_id_allocator.h
@@ -7,6 +7,8 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
@@ -34,6 +36,12 @@ class VIZ_COMMON_EXPORT ChildLocalSurfaceIdAllocator {
~ChildLocalSurfaceIdAllocator() = default;
+ // Creates a ChildLocalSurfaceIdAllocator seeded with a LocalSurfaceId
+ // whose child sequence number is |value|. UpdateFromParent() must still be
+ // called.
+ static std::unique_ptr<ChildLocalSurfaceIdAllocator>
+ CreateWithChildSequenceNumber(uint32_t value);
+
// When a parent-allocated LocalSurfaceId arrives in the child, the child
// needs to update its understanding of the last generated message so the
// messages can continue to monotonically increase. Returns whether the
@@ -43,6 +51,10 @@ class VIZ_COMMON_EXPORT ChildLocalSurfaceIdAllocator {
void GenerateId();
+ // If UpdateFromParent() has been called this calls GenerateId(), otherwise
+ // the child sequence number is advanced.
+ void GenerateIdOrIncrementChild();
+
const LocalSurfaceIdAllocation& GetCurrentLocalSurfaceIdAllocation() const {
return current_local_surface_id_allocation_;
}
diff --git a/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.cc b/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
index abe57aa4658..1f1e19bb748 100644
--- a/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
+++ b/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
@@ -45,9 +45,19 @@ bool ParentLocalSurfaceIdAllocator::UpdateFromChild(
// than the one provided by the child, then the merged LocalSurfaceId
// is actually a new LocalSurfaceId and so we report its allocation time
// as now.
+ TRACE_EVENT2(
+ TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+ "ParentLocalSurfaceIdAllocator::UpdateFromChild New Allocation",
+ "current", current_local_surface_id_allocation_.ToString(), "child",
+ child_local_surface_id_allocation.ToString());
current_local_surface_id_allocation_.allocation_time_ =
tick_clock_->NowTicks();
} else {
+ TRACE_EVENT2(
+ TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
+ "ParentLocalSurfaceIdAllocator::UpdateFromChild Synchronization",
+ "current", current_local_surface_id_allocation_.ToString(), "child",
+ child_local_surface_id_allocation.ToString());
current_local_surface_id_allocation_.allocation_time_ =
child_local_surface_id_allocation.allocation_time();
}
@@ -120,6 +130,11 @@ bool ParentLocalSurfaceIdAllocator::HasValidLocalSurfaceIdAllocation() const {
return !is_invalid_ && current_local_surface_id_allocation_.IsValid();
}
+const base::UnguessableToken& ParentLocalSurfaceIdAllocator::GetEmbedToken()
+ const {
+ return current_local_surface_id_allocation_.local_surface_id_.embed_token();
+}
+
// static
const LocalSurfaceIdAllocation&
ParentLocalSurfaceIdAllocator::InvalidLocalSurfaceIdAllocation() {
diff --git a/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.h b/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.h
index 5cac5c6673b..8eb55840145 100644
--- a/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.h
+++ b/chromium/components/viz/common/surfaces/parent_local_surface_id_allocator.h
@@ -56,6 +56,8 @@ class VIZ_COMMON_EXPORT ParentLocalSurfaceIdAllocator {
static const LocalSurfaceIdAllocation& InvalidLocalSurfaceIdAllocation();
+ const base::UnguessableToken& GetEmbedToken() const;
+
bool is_allocation_suppressed() const { return is_allocation_suppressed_; }
private:
diff --git a/chromium/components/viz/common/viz_utils.cc b/chromium/components/viz/common/viz_utils.cc
new file mode 100644
index 00000000000..cf216d60e16
--- /dev/null
+++ b/chromium/components/viz/common/viz_utils.cc
@@ -0,0 +1,19 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/common/viz_utils.h"
+
+#include "base/system/sys_info.h"
+#include "build/build_config.h"
+
+namespace viz {
+
+bool PreferRGB565ResourcesForDisplay() {
+#if defined(OS_ANDROID)
+ return base::SysInfo::AmountOfPhysicalMemoryMB() <= 512;
+#endif
+ return false;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/common/viz_utils.h b/chromium/components/viz/common/viz_utils.h
new file mode 100644
index 00000000000..f8406511533
--- /dev/null
+++ b/chromium/components/viz/common/viz_utils.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_COMMON_VIZ_UTILS_H_
+#define COMPONENTS_VIZ_COMMON_VIZ_UTILS_H_
+
+#include "components/viz/common/viz_common_export.h"
+
+namespace viz {
+
+VIZ_COMMON_EXPORT bool PreferRGB565ResourcesForDisplay();
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_COMMON_VIZ_UTILS_H_
diff --git a/chromium/components/viz/common/yuv_readback_unittest.cc b/chromium/components/viz/common/yuv_readback_unittest.cc
index fa3ae47daaf..437ecefc110 100644
--- a/chromium/components/viz/common/yuv_readback_unittest.cc
+++ b/chromium/components/viz/common/yuv_readback_unittest.cc
@@ -4,6 +4,7 @@
#include <tuple>
+#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
@@ -101,7 +102,8 @@ class YUVReadbackTest : public testing::Test {
std::string error_msg;
std::unique_ptr<base::Value> trace_data =
- base::JSONReader::ReadAndReturnError(json_data, 0, nullptr, &error_msg);
+ base::JSONReader::ReadAndReturnErrorDeprecated(json_data, 0, nullptr,
+ &error_msg);
CHECK(trace_data) << "JSON parsing failed (" << error_msg
<< ") JSON data:" << std::endl
<< json_data;
@@ -549,7 +551,7 @@ TEST_P(YUVReadbackPixelTest, Test) {
}
// First argument is intentionally empty.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
YUVReadbackPixelTest,
::testing::Combine(
diff --git a/chromium/components/viz/demo/BUILD.gn b/chromium/components/viz/demo/BUILD.gn
new file mode 100644
index 00000000000..ad446765ad9
--- /dev/null
+++ b/chromium/components/viz/demo/BUILD.gn
@@ -0,0 +1,83 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/ui.gni")
+
+static_library("client") {
+ output_name = "demo_client"
+
+ sources = [
+ "client/demo_client.cc",
+ "client/demo_client.h",
+ ]
+
+ deps = [
+ "//components/viz/common",
+ "//mojo/public/cpp/bindings",
+ "//services/viz/public/interfaces",
+ ]
+}
+
+static_library("host") {
+ output_name = "demo_host"
+ sources = [
+ "host/demo_host.cc",
+ "host/demo_host.h",
+ ]
+
+ deps = [
+ ":client",
+ "//components/viz/common",
+ "//components/viz/host",
+ "//mojo/public/cpp/system",
+ "//services/viz/privileged/interfaces",
+ ]
+}
+
+static_library("service") {
+ output_name = "demo_service"
+ sources = [
+ "service/demo_service.cc",
+ "service/demo_service.h",
+ ]
+
+ deps = [
+ "//components/viz/common",
+ "//components/viz/service/main",
+ "//mojo/public/cpp/system",
+ "//services/viz/privileged/interfaces",
+ ]
+}
+
+executable("viz_demo") {
+ sources = [
+ "demo_main.cc",
+ ]
+
+ deps = [
+ "//base",
+ "//base:i18n",
+ "//build/win:default_exe_manifest",
+ "//components/viz/demo:host",
+ "//components/viz/demo:service",
+ "//components/viz/service",
+ "//components/viz/service/main",
+ "//mojo/core/embedder",
+ "//skia",
+ "//ui/events",
+ "//ui/events/platform",
+ "//ui/platform_window",
+ ]
+
+ if (use_x11) {
+ deps += [
+ "//ui/events/platform/x11",
+ "//ui/platform_window/x11",
+ ]
+ }
+
+ if (is_win) {
+ deps += [ "//ui/platform_window/win" ]
+ }
+}
diff --git a/chromium/components/viz/demo/DEPS b/chromium/components/viz/demo/DEPS
new file mode 100644
index 00000000000..af86491f4c0
--- /dev/null
+++ b/chromium/components/viz/demo/DEPS
@@ -0,0 +1,17 @@
+include_rules = [
+ "-cc",
+ "-components/viz",
+ "+components/viz/common",
+ "+mojo/public/cpp",
+ "-ui",
+ "+ui/gfx",
+]
+
+specific_include_rules = {
+ "demo_main\.cc": [
+ "+components/viz/demo/host",
+ "+components/viz/demo/service",
+ "+mojo/core/embedder",
+ "+ui",
+ ],
+}
diff --git a/chromium/components/viz/demo/client/DEPS b/chromium/components/viz/demo/client/DEPS
new file mode 100644
index 00000000000..d2ccc891701
--- /dev/null
+++ b/chromium/components/viz/demo/client/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+services/viz/public",
+]
diff --git a/chromium/components/viz/demo/client/demo_client.cc b/chromium/components/viz/demo/client/demo_client.cc
new file mode 100644
index 00000000000..29939431caf
--- /dev/null
+++ b/chromium/components/viz/demo/client/demo_client.cc
@@ -0,0 +1,188 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/demo/client/demo_client.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
+#include "components/viz/common/quads/surface_draw_quad.h"
+
+namespace demo {
+
+DemoClient::DemoClient(const viz::FrameSinkId& frame_sink_id,
+ const viz::LocalSurfaceIdAllocation& local_surface_id,
+ const gfx::Rect& bounds)
+ : thread_(frame_sink_id.ToString()),
+ frame_sink_id_(frame_sink_id),
+ local_surface_id_(local_surface_id),
+ bounds_(bounds),
+ binding_(this) {
+ CHECK(thread_.Start());
+}
+
+DemoClient::~DemoClient() = default;
+
+void DemoClient::Initialize(
+ viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info) {
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DemoClient::InitializeOnThread, base::Unretained(this),
+ std::move(request), std::move(sink_info), nullptr));
+}
+
+void DemoClient::Initialize(
+ viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkPtrInfo sink_info) {
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DemoClient::InitializeOnThread, base::Unretained(this),
+ std::move(request), nullptr, std::move(sink_info)));
+}
+
+viz::LocalSurfaceIdAllocation DemoClient::Embed(
+ const viz::FrameSinkId& frame_sink_id,
+ const gfx::Rect& bounds) {
+ // |embeds_| is used on the client-thread in CreateFrame(). So this needs to
+ // be mutated under a lock.
+ base::AutoLock lock(lock_);
+ allocator_.GenerateId();
+ embeds_[frame_sink_id] = {allocator_.GetCurrentLocalSurfaceIdAllocation(),
+ bounds};
+ return embeds_[frame_sink_id].lsid;
+}
+
+void DemoClient::Resize(const gfx::Size& size,
+ const viz::LocalSurfaceIdAllocation& local_surface_id) {
+ // |bounds_| and |local_surface_id_| are used on the client-thread in
+ // CreateFrame(). So these need to be mutated under a lock.
+ base::AutoLock lock(lock_);
+ bounds_.set_size(size);
+ local_surface_id_ = local_surface_id;
+}
+
+viz::CompositorFrame DemoClient::CreateFrame(const viz::BeginFrameArgs& args) {
+ constexpr SkColor colors[] = {SK_ColorRED, SK_ColorGREEN, SK_ColorYELLOW};
+ viz::CompositorFrame frame;
+
+ frame.metadata.begin_frame_ack = viz::BeginFrameAck(args, true);
+ frame.metadata.device_scale_factor = 1.f;
+ frame.metadata.local_surface_id_allocation_time =
+ local_surface_id_.allocation_time();
+ frame.metadata.frame_token = ++next_frame_token_;
+
+ const int kRenderPassId = 1;
+ const gfx::Rect& output_rect = bounds_;
+ const gfx::Rect& damage_rect = output_rect;
+ std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
+ render_pass->SetNew(kRenderPassId, output_rect, damage_rect,
+ gfx::Transform());
+
+ // The content of the client is one big solid-color rectangle, which includes
+ // the other clients above it (in z-order). The embedded clients are first
+ // added to the CompositorFrame using their SurfaceId (i.e. the FrameSinkId
+ // and LocalSurfaceId), and then the big rectangle is added afterwards.
+ for (auto& iter : embeds_) {
+ const gfx::Rect& child_bounds = iter.second.bounds;
+ const gfx::Vector2dF center(child_bounds.width() / 2,
+ child_bounds.height() / 2);
+
+ // Apply a rotation so there's visual-update every frame in the demo.
+ gfx::Transform transform;
+ transform.Translate(center + child_bounds.OffsetFromOrigin());
+ transform.Rotate(iter.second.degrees);
+ iter.second.degrees += 0.3;
+ transform.Translate(-center);
+
+ viz::SharedQuadState* quad_state =
+ render_pass->CreateAndAppendSharedQuadState();
+ quad_state->SetAll(
+ transform,
+ /*quad_layer_rect=*/child_bounds,
+ /*visible_quad_layer_rect=*/child_bounds,
+ /*clip_rect=*/gfx::Rect(),
+ /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f,
+ /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+
+ viz::SurfaceDrawQuad* embed =
+ render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
+ viz::SurfaceId surface_id(iter.first, iter.second.lsid.local_surface_id());
+ // |rect| and |visible_rect| needs to be in the quad's coord-space, so to
+ // draw the whole quad, it needs to use origin (0, 0).
+ embed->SetNew(quad_state,
+ /*rect=*/gfx::Rect(child_bounds.size()),
+ /*visible_rect=*/gfx::Rect(child_bounds.size()),
+ viz::SurfaceRange(surface_id), SK_ColorGRAY,
+ /*stretch_content_to_fill_bounds=*/false,
+ /*ignores_input_event=*/false);
+ }
+
+ // Add a solid-color draw-quad for the big rectangle covering the entire
+ // content-area of the client.
+ viz::SharedQuadState* quad_state =
+ render_pass->CreateAndAppendSharedQuadState();
+ quad_state->SetAll(
+ gfx::Transform(),
+ /*quad_layer_rect=*/output_rect,
+ /*visible_quad_layer_rect=*/output_rect,
+ /*clip_rect=*/gfx::Rect(),
+ /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f,
+ /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+
+ viz::SolidColorDrawQuad* color_quad =
+ render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
+ color_quad->SetNew(quad_state, output_rect, output_rect,
+ colors[(++frame_count_ / 60) % base::size(colors)], false);
+
+ frame.render_pass_list.push_back(std::move(render_pass));
+
+ return frame;
+}
+
+viz::mojom::CompositorFrameSink* DemoClient::GetPtr() {
+ if (associated_sink_.is_bound())
+ return associated_sink_.get();
+ return sink_.get();
+}
+
+void DemoClient::InitializeOnThread(
+ viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo associated_sink_info,
+ viz::mojom::CompositorFrameSinkPtrInfo sink_info) {
+ binding_.Bind(std::move(request));
+ if (associated_sink_info)
+ associated_sink_.Bind(std::move(associated_sink_info));
+ else
+ sink_.Bind(std::move(sink_info));
+ // Request for begin-frames.
+ GetPtr()->SetNeedsBeginFrame(true);
+}
+
+void DemoClient::DidReceiveCompositorFrameAck(
+ const std::vector<viz::ReturnedResource>& resources) {
+ // See documentation in mojom for how this can be used.
+}
+
+void DemoClient::OnBeginFrame(
+ const viz::BeginFrameArgs& args,
+ const base::flat_map<uint32_t, gfx::PresentationFeedback>& feedbacks) {
+ // Generate a new compositor-frame for each begin-frame. This demo client
+ // generates and submits the compositor-frame immediately. But it is possible
+ // for the client to delay sending the compositor-frame. |args| includes the
+ // deadline for the client before it needs to submit the compositor-frame.
+ base::AutoLock lock(lock_);
+ GetPtr()->SubmitCompositorFrame(local_surface_id_.local_surface_id(),
+ CreateFrame(args),
+ base::Optional<viz::HitTestRegionList>(),
+ /*trace_time=*/0);
+}
+void DemoClient::OnBeginFramePausedChanged(bool paused) {}
+void DemoClient::ReclaimResources(
+ const std::vector<viz::ReturnedResource>& resources) {}
+
+} // namespace demo
diff --git a/chromium/components/viz/demo/client/demo_client.h b/chromium/components/viz/demo/client/demo_client.h
new file mode 100644
index 00000000000..61d77d93e9c
--- /dev/null
+++ b/chromium/components/viz/demo/client/demo_client.h
@@ -0,0 +1,123 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_
+#define COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_
+
+#include <map>
+#include <vector>
+
+#include "base/synchronization/lock.h"
+#include "base/threading/thread.h"
+#include "components/viz/common/quads/compositor_frame_metadata.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
+
+namespace viz {
+class CompositorFrame;
+}
+
+namespace demo {
+
+// DemoClient is responsible for communicating with the display-compositor. It
+// sends messages to the service over the mojom.CompositorFrameSink interface,
+// and receives messages through the mojom.CompositorFrameSinkClient interface.
+//
+// The client needs to have an identifier, FrameSinkId, which doesn't change
+// during the lifetime of the client. The embedder of the client needs to know
+// about this FrameSinkId. The 'host', when it itself is not the embedder, also
+// needs to know about this FrameSinkId, so that it can set up the
+// frame-hierarchy correctly in the service.
+//
+// The client also needs to have a LocalSurfaceId, which represents an embedding
+// of the client in a particular state. If, for example, the size of the client
+// changes (or other attributes, like device scale factor), then a new
+// LocalSurfaceId needs to be allocated. The LocalSurfaceId is used to submit
+// the CompositorFrame. Both the embedder and the embedded clients need to know
+// the LocalSurfaceId. It is possible for both the embedder and the embedded
+// client to generate new LocalSurfaceId (typically using a
+// ParentLocalSurfaceIdAllocator and ChildLocalSurfaceIdAllocator respectively).
+// In this demo, only the embedder allocates the LocalSurfaceId.
+class DemoClient : public viz::mojom::CompositorFrameSinkClient {
+ public:
+ DemoClient(const viz::FrameSinkId& frame_sink_id,
+ const viz::LocalSurfaceIdAllocation& local_surface_id,
+ const gfx::Rect& bounds);
+ ~DemoClient() override;
+
+ const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
+
+ // Initializes the mojo connection to the service.
+ void Initialize(viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info);
+ void Initialize(viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkPtrInfo sink_info);
+
+ // This prepares for this client to embed another client (i.e. this client
+ // acts as the embedder). Since this client is the embedder, it allocates the
+ // LocalSurfaceId, and returns that. The client that should be embedded (i.e.
+ // the client represented by |frame_sink_id|) should use the returned
+ // LocalSurfaceId to submit visual content (CompositorFrame).
+ viz::LocalSurfaceIdAllocation Embed(const viz::FrameSinkId& frame_sink_id,
+ const gfx::Rect& bounds);
+
+ // When this client is resized, it is important that it also receives a new
+ // LocalSurfaceId with the new size.
+ void Resize(const gfx::Size& size,
+ const viz::LocalSurfaceIdAllocation& local_surface_id);
+
+ private:
+ struct EmbedInfo {
+ viz::LocalSurfaceIdAllocation lsid;
+ gfx::Rect bounds;
+ float degrees = 0.f;
+ };
+
+ viz::CompositorFrame CreateFrame(const viz::BeginFrameArgs& args)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ viz::mojom::CompositorFrameSink* GetPtr();
+
+ void InitializeOnThread(
+ viz::mojom::CompositorFrameSinkClientRequest request,
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo associated_sink_info,
+ viz::mojom::CompositorFrameSinkPtrInfo sink_info);
+
+ // viz::mojom::CompositorFrameSinkClient:
+ void DidReceiveCompositorFrameAck(
+ const std::vector<viz::ReturnedResource>& resources) override;
+ void OnBeginFrame(const viz::BeginFrameArgs& args,
+ const base::flat_map<uint32_t, gfx::PresentationFeedback>&
+ feedbacks) override;
+ void OnBeginFramePausedChanged(bool paused) override;
+ void ReclaimResources(
+ const std::vector<viz::ReturnedResource>& resources) override;
+
+ // This thread is created solely to demonstrate that the client can live in
+ // its own thread (or even in its own process). A viz client does not need to
+ // have its own thread.
+ base::Thread thread_;
+
+ const viz::FrameSinkId frame_sink_id_;
+ viz::LocalSurfaceIdAllocation local_surface_id_ GUARDED_BY(lock_);
+ gfx::Rect bounds_ GUARDED_BY(lock_);
+
+ mojo::Binding<viz::mojom::CompositorFrameSinkClient> binding_;
+ viz::mojom::CompositorFrameSinkAssociatedPtr associated_sink_;
+ viz::mojom::CompositorFrameSinkPtr sink_;
+ viz::FrameTokenGenerator next_frame_token_;
+ uint32_t frame_count_ = 0;
+
+ base::Lock lock_;
+ // The |allocator_| is used only when this client acts as an embedder, and
+ // embeds other clients.
+ viz::ParentLocalSurfaceIdAllocator allocator_;
+ std::map<viz::FrameSinkId, EmbedInfo> embeds_ GUARDED_BY(lock_);
+
+ DISALLOW_COPY_AND_ASSIGN(DemoClient);
+};
+
+} // namespace demo
+
+#endif // COMPONENTS_VIZ_DEMO_CLIENT_DEMO_CLIENT_H_
diff --git a/chromium/components/viz/demo/demo_main.cc b/chromium/components/viz/demo/demo_main.cc
new file mode 100644
index 00000000000..9bf7fe9525d
--- /dev/null
+++ b/chromium/components/viz/demo/demo_main.cc
@@ -0,0 +1,199 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/i18n/icu_util.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/task/task_scheduler/task_scheduler.h"
+#include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "components/viz/demo/host/demo_host.h"
+#include "components/viz/demo/service/demo_service.h"
+#include "mojo/core/embedder/embedder.h"
+#include "mojo/core/embedder/scoped_ipc_support.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/platform_window/platform_window_init_properties.h"
+
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#endif
+
+#if defined(OS_WIN)
+#include "ui/base/cursor/cursor_loader_win.h"
+#include "ui/platform_window/win/win_window.h"
+#endif
+
+#if defined(USE_X11)
+#include "ui/platform_window/x11/x11_window.h"
+#endif
+
+namespace {
+
+// Initializes and owns the components from base necessary to run the app.
+class InitBase {
+ public:
+ InitBase(int argc, char** argv) {
+ base::CommandLine::Init(argc, argv);
+ base::i18n::InitializeICU();
+ base::TaskScheduler::CreateAndStartWithDefaultParams("demo");
+ }
+
+ ~InitBase() = default;
+
+ private:
+ // The exit manager is in charge of calling the dtors of singleton objects.
+ base::AtExitManager exit_manager_;
+ base::MessageLoopForUI message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitBase);
+};
+
+// Initializes and owns mojo.
+class InitMojo {
+ public:
+ InitMojo() : thread_("Mojo thread") {
+ mojo::core::Init();
+ thread_.StartWithOptions(
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
+ ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
+ thread_.task_runner(),
+ mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
+ }
+
+ ~InitMojo() = default;
+
+ private:
+ base::Thread thread_;
+ std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitMojo);
+};
+
+// Initializes and owns the UI components needed for the app.
+class InitUI {
+ public:
+ InitUI() {
+#if defined(USE_X11)
+ XInitThreads();
+#endif
+ event_source_ = ui::PlatformEventSource::CreateDefault();
+ }
+
+ ~InitUI() = default;
+
+ private:
+ std::unique_ptr<ui::PlatformEventSource> event_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitUI);
+};
+
+// DemoWindow creates the native window for the demo app. The native window
+// provides a gfx::AcceleratedWidget, which is needed for the display
+// compositor.
+class DemoWindow : public ui::PlatformWindowDelegate {
+ public:
+ DemoWindow() = default;
+ ~DemoWindow() override = default;
+
+ void Create(const gfx::Rect& bounds) {
+ platform_window_ = CreatePlatformWindow(bounds);
+ platform_window_->Show();
+ if (widget_ != gfx::kNullAcceleratedWidget)
+ InitializeDemo();
+ }
+
+ private:
+ std::unique_ptr<ui::PlatformWindow> CreatePlatformWindow(
+ const gfx::Rect& bounds) {
+ ui::PlatformWindowInitProperties props(bounds);
+#if defined(USE_OZONE)
+ return ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
+ this, std::move(props));
+#elif defined(OS_WIN)
+ return std::make_unique<ui::WinWindow>(this, props.bounds);
+#elif defined(USE_X11)
+ return std::make_unique<ui::X11Window>(this, props.bounds);
+#else
+ NOTIMPLEMENTED();
+ return nullptr;
+#endif
+ }
+
+ void InitializeDemo() {
+ DCHECK_NE(widget_, gfx::kNullAcceleratedWidget);
+ // We finally have a valid gfx::AcceleratedWidget. We can now start the
+ // actual process of setting up the viz host and the service.
+ // First, set up the mojo message-pipes that the host and the service will
+ // use to communicate with each other.
+ viz::mojom::FrameSinkManagerPtr frame_sink_manager;
+ viz::mojom::FrameSinkManagerRequest frame_sink_manager_request =
+ mojo::MakeRequest(&frame_sink_manager);
+ viz::mojom::FrameSinkManagerClientPtr frame_sink_manager_client;
+ viz::mojom::FrameSinkManagerClientRequest
+ frame_sink_manager_client_request =
+ mojo::MakeRequest(&frame_sink_manager_client);
+
+ // Next, create the host and the service, and pass them the right ends of
+ // the message-pipes.
+ host_ = std::make_unique<demo::DemoHost>(
+ widget_, platform_window_->GetBounds().size(),
+ std::move(frame_sink_manager_client_request),
+ std::move(frame_sink_manager));
+
+ service_ = std::make_unique<demo::DemoService>(
+ std::move(frame_sink_manager_request),
+ std::move(frame_sink_manager_client));
+ }
+
+ // ui::PlatformWindowDelegate:
+ void OnBoundsChanged(const gfx::Rect& new_bounds) override {
+ host_->Resize(new_bounds.size());
+ }
+
+ void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override {
+ widget_ = widget;
+ if (platform_window_)
+ InitializeDemo();
+ }
+
+ void OnDamageRect(const gfx::Rect& damaged_region) override {}
+ void DispatchEvent(ui::Event* event) override {}
+ void OnCloseRequest() override {}
+ void OnClosed() override {}
+ void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
+ void OnLostCapture() override {}
+ void OnAcceleratedWidgetDestroyed() override {}
+ void OnActivationChanged(bool active) override {}
+
+ std::unique_ptr<demo::DemoHost> host_;
+ std::unique_ptr<demo::DemoService> service_;
+
+ std::unique_ptr<ui::PlatformWindow> platform_window_;
+ gfx::AcceleratedWidget widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(DemoWindow);
+};
+
+int DemoMain() {
+ DemoWindow window;
+ window.Create(gfx::Rect(800, 600));
+
+ base::RunLoop().Run();
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char** argv) {
+ InitBase base(argc, argv);
+ InitMojo mojo;
+ InitUI ui;
+
+ return DemoMain();
+}
diff --git a/chromium/components/viz/demo/host/DEPS b/chromium/components/viz/demo/host/DEPS
new file mode 100644
index 00000000000..f37b0af4744
--- /dev/null
+++ b/chromium/components/viz/demo/host/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+components/viz/demo/client",
+ "+components/viz/host",
+ "+services/viz/privileged",
+ "+services/viz/public",
+]
diff --git a/chromium/components/viz/demo/host/demo_host.cc b/chromium/components/viz/demo/host/demo_host.cc
new file mode 100644
index 00000000000..36499307a2d
--- /dev/null
+++ b/chromium/components/viz/demo/host/demo_host.cc
@@ -0,0 +1,169 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/demo/host/demo_host.h"
+
+#include <utility>
+
+#include "base/rand_util.h"
+#include "components/viz/demo/client/demo_client.h"
+#include "components/viz/host/renderer_settings_creation.h"
+
+namespace demo {
+
+DemoHost::DemoHost(gfx::AcceleratedWidget widget,
+ const gfx::Size& size,
+ viz::mojom::FrameSinkManagerClientRequest client_request,
+ viz::mojom::FrameSinkManagerPtr frame_sink_manager_ptr)
+ : widget_(widget), size_(size), thread_("DemoHost") {
+ CHECK(thread_.Start());
+ thread_.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&DemoHost::Initialize, base::Unretained(this),
+ std::move(client_request),
+ frame_sink_manager_ptr.PassInterface()));
+}
+
+DemoHost::~DemoHost() = default;
+
+void DemoHost::Resize(const gfx::Size& size) {
+ thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DemoHost::ResizeOnThread, base::Unretained(this), size));
+}
+
+void DemoHost::ResizeOnThread(const gfx::Size& size) {
+ if (size_ == size)
+ return;
+ size_ = size;
+ display_private_->Resize(size);
+
+ // Every size change for a client needs a new LocalSurfaceId.
+ allocator_.GenerateId();
+ root_client_->Resize(size_, allocator_.GetCurrentLocalSurfaceIdAllocation());
+}
+
+void DemoHost::EmbedClients(DemoClient* embedder_client,
+ const gfx::Rect& child_bounds) {
+ // Generate a FrameSinkId for the client. Each client can have any number of
+ // frame-sinks, and these frame-sinks should share the same |client_id|
+ // component for the FrameSinkId. In this demo however, each client has a
+ // single FrameSink, so the client-id can just be randomly generated, and it
+ // doesn't make a difference.
+ uint64_t rand = base::RandUint64();
+ viz::FrameSinkId frame_sink_id(rand >> 32, rand & 0xffffffff);
+
+ // Register the frame sink and its hierarchy.
+ host_frame_sink_manager_.RegisterFrameSinkId(
+ frame_sink_id, this, viz::ReportFirstSurfaceActivation::kNo);
+ host_frame_sink_manager_.RegisterFrameSinkHierarchy(
+ embedder_client->frame_sink_id(), frame_sink_id);
+
+ // Next, create a mojom::CompositorFrameSink for the client, so that the
+ // client is able to submit visual (and hit-test) content to the viz service.
+ // Note that in this demo app, the host is setting up the message-pipes, and
+ // then sending the end-points to the embedded-client and the viz-service.
+ // However, it is possible for the embedded-client to initiate the creation of
+ // the message-pipes, in which case, the client would need to send the
+ // service-end-points to the host (via a non-viz API), so that the host can in
+ // turn send them to the service.
+ viz::mojom::CompositorFrameSinkClientPtr client_ptr;
+ auto client_request = mojo::MakeRequest(&client_ptr);
+
+ viz::mojom::CompositorFrameSinkPtr sink_ptr;
+ auto sink_request = mojo::MakeRequest(&sink_ptr);
+
+ host_frame_sink_manager_.CreateCompositorFrameSink(
+ frame_sink_id, std::move(sink_request), std::move(client_ptr));
+
+ // At this point, the host is done setting everything up. Now it is up to the
+ // new client to take over the communication (i.e. the mojo message pipes)
+ // with the service for the frame-sink. The embedder (i.e. the parent client)
+ // also needs to know about the new client's FrameSinkId, so that it is able
+ // to embed it. Both the embedder and the embedded client also need to use
+ // the same LocalSurfaceId for the embedding. Typically, the embedder is the
+ // one that generates the LocalSurfaceId for the embedded client. However, it
+ // is possible for another source (e.g. the viz-host) to generate the
+ // LocalSurfaceId, and dispatch that separately to both the embedder and the
+ // embedded clients. There is no specific viz-API for communicating these
+ // FrameSinkId and LocalSurfaceId between these clients. In chrome, these
+ // happen through the content API (or through the window-service API in
+ // ChromeOS).
+ // In this demo app, the embedder-client is assigning the LocalSurfaceId
+ // (through DemoClient).
+
+ auto lsid_allocation = embedder_client->Embed(frame_sink_id, child_bounds);
+ auto embedded_client = std::make_unique<DemoClient>(
+ frame_sink_id, lsid_allocation, child_bounds);
+ embedded_client->Initialize(std::move(client_request),
+ sink_ptr.PassInterface());
+ if (embedder_client == root_client_.get()) {
+ // Embed another client after a second. This could embed the client
+ // immediately here too if desired. The delay is to demonstrate asynchronous
+ // usage of the API.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&DemoHost::EmbedClients, base::Unretained(this),
+ embedded_client.get(), gfx::Rect(125, 125, 150, 150)),
+ base::TimeDelta::FromSeconds(1));
+ }
+ embedded_clients_.push_back(std::move(embedded_client));
+}
+
+void DemoHost::Initialize(viz::mojom::FrameSinkManagerClientRequest request,
+ viz::mojom::FrameSinkManagerPtrInfo ptr_info) {
+ host_frame_sink_manager_.BindAndSetManager(
+ std::move(request), nullptr,
+ viz::mojom::FrameSinkManagerPtr(std::move(ptr_info)));
+
+ display_client_ = std::make_unique<viz::HostDisplayClient>(widget_);
+
+ auto root_params = viz::mojom::RootCompositorFrameSinkParams::New();
+
+ // Create interfaces for a root CompositorFrameSink.
+ viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
+ root_params->compositor_frame_sink = mojo::MakeRequest(&sink_info);
+ auto client_request =
+ mojo::MakeRequest(&root_params->compositor_frame_sink_client);
+ root_params->display_private = mojo::MakeRequest(&display_private_);
+ root_params->display_client =
+ display_client_->GetBoundPtr(nullptr).PassInterface();
+
+ constexpr viz::FrameSinkId root_frame_sink_id(0xdead, 0xbeef);
+ root_params->frame_sink_id = root_frame_sink_id;
+ root_params->widget = widget_;
+ root_params->gpu_compositing = false;
+ root_params->renderer_settings = viz::CreateRendererSettings();
+
+ host_frame_sink_manager_.RegisterFrameSinkId(
+ root_params->frame_sink_id, this, viz::ReportFirstSurfaceActivation::kNo);
+ host_frame_sink_manager_.CreateRootCompositorFrameSink(
+ std::move(root_params));
+
+ display_private_->Resize(size_);
+ display_private_->SetDisplayVisible(true);
+
+ // Initialize as a client now, since the host has to submit compositor frames
+ // like any other clients.
+ // The 'root' is not embedded by anything else. However, it still needs to
+ // have a valid LocalSurfaceId, which changes when root changes size (or
+ // device-scale-factor etc.).
+ allocator_.GenerateId();
+ root_client_ = std::make_unique<DemoClient>(
+ root_frame_sink_id, allocator_.GetCurrentLocalSurfaceIdAllocation(),
+ gfx::Rect(size_));
+ root_client_->Initialize(std::move(client_request), std::move(sink_info));
+
+ // Embed a new client into the root after the first second.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&DemoHost::EmbedClients, base::Unretained(this),
+ root_client_.get(), gfx::Rect(50, 50, 300, 300)),
+ base::TimeDelta::FromSeconds(1));
+}
+
+void DemoHost::OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) {}
+
+void DemoHost::OnFrameTokenChanged(uint32_t frame_token) {}
+
+} // namespace demo
diff --git a/chromium/components/viz/demo/host/demo_host.h b/chromium/components/viz/demo/host/demo_host.h
new file mode 100644
index 00000000000..e036c6a64fb
--- /dev/null
+++ b/chromium/components/viz/demo/host/demo_host.h
@@ -0,0 +1,70 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_DEMO_HOST_DEMO_HOST_H_
+#define COMPONENTS_VIZ_DEMO_HOST_DEMO_HOST_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/threading/thread.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+#include "components/viz/host/host_display_client.h"
+#include "components/viz/host/host_frame_sink_client.h"
+#include "components/viz/host/host_frame_sink_manager.h"
+#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h"
+#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace demo {
+
+class DemoClient;
+
+// DemoHost is the 'host', i.e. the privileged component, responsible for
+// managing the service, and establishing the connection between the clients and
+// the service.
+class DemoHost : public viz::HostFrameSinkClient {
+ public:
+ DemoHost(gfx::AcceleratedWidget widget,
+ const gfx::Size& size,
+ viz::mojom::FrameSinkManagerClientRequest client_request,
+ viz::mojom::FrameSinkManagerPtr frame_sink_manager_ptr);
+ ~DemoHost() override;
+
+ void Resize(const gfx::Size& size);
+
+ private:
+ void ResizeOnThread(const gfx::Size& size);
+
+ void EmbedClients(DemoClient* embedder_client, const gfx::Rect& child_bounds);
+
+ void Initialize(viz::mojom::FrameSinkManagerClientRequest request,
+ viz::mojom::FrameSinkManagerPtrInfo ptr_info);
+
+ // viz::HostFrameSinkClient:
+ void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
+
+ const gfx::AcceleratedWidget widget_;
+ gfx::Size size_;
+ viz::HostFrameSinkManager host_frame_sink_manager_;
+ viz::mojom::DisplayPrivateAssociatedPtr display_private_;
+ std::unique_ptr<viz::HostDisplayClient> display_client_;
+ viz::ParentLocalSurfaceIdAllocator allocator_;
+
+ std::unique_ptr<DemoClient> root_client_;
+ std::vector<std::unique_ptr<DemoClient>> embedded_clients_;
+
+ // The thread is created to demonstrate that the host can run on a separate
+ // thread (or even a separate process), since it communicates with the service
+ // and clients over mojo. The host does not need to have its own thread
+ // though.
+ base::Thread thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(DemoHost);
+};
+
+} // namespace demo
+
+#endif // COMPONENTS_VIZ_DEMO_HOST_DEMO_HOST_H_
diff --git a/chromium/components/viz/demo/service/DEPS b/chromium/components/viz/demo/service/DEPS
new file mode 100644
index 00000000000..d775b9ad568
--- /dev/null
+++ b/chromium/components/viz/demo/service/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+components/viz/common",
+ "+components/viz/service",
+ "+services/viz/privileged",
+ "+services/viz/public",
+]
diff --git a/chromium/components/viz/demo/service/demo_service.cc b/chromium/components/viz/demo/service/demo_service.cc
new file mode 100644
index 00000000000..24a6724cb3d
--- /dev/null
+++ b/chromium/components/viz/demo/service/demo_service.cc
@@ -0,0 +1,29 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/demo/service/demo_service.h"
+
+#include <memory>
+#include <utility>
+
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
+#include "components/viz/service/main/viz_compositor_thread_runner.h"
+
+namespace demo {
+
+DemoService::DemoService(viz::mojom::FrameSinkManagerRequest request,
+ viz::mojom::FrameSinkManagerClientPtr client) {
+ auto params = viz::mojom::FrameSinkManagerParams::New();
+ params->restart_id = viz::BeginFrameSource::kNotRestartableId;
+ params->use_activation_deadline = false;
+ params->activation_deadline_in_frames = 0u;
+ params->frame_sink_manager = std::move(request);
+ params->frame_sink_manager_client = client.PassInterface();
+ runner_ = std::make_unique<viz::VizCompositorThreadRunner>();
+ runner_->CreateFrameSinkManager(std::move(params));
+}
+
+DemoService::~DemoService() = default;
+
+} // namespace demo
diff --git a/chromium/components/viz/demo/service/demo_service.h b/chromium/components/viz/demo/service/demo_service.h
new file mode 100644
index 00000000000..8257d2459db
--- /dev/null
+++ b/chromium/components/viz/demo/service/demo_service.h
@@ -0,0 +1,37 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_DEMO_SERVICE_DEMO_SERVICE_H_
+#define COMPONENTS_VIZ_DEMO_SERVICE_DEMO_SERVICE_H_
+
+#include <memory>
+
+#include "base/threading/thread.h"
+#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
+
+namespace viz {
+class VizCompositorThreadRunner;
+} // namespace viz
+
+namespace demo {
+
+// DemoService sets up the display compositor, and connects to the host over the
+// mojom API. The host communicates with the FrameSinkManagerImpl over the
+// mojom.FrameSinkManager API, and the FrameSinkManagerImpl communicates with
+// the host over the mojom.FrameSinkManagerClient API.
+class DemoService {
+ public:
+ DemoService(viz::mojom::FrameSinkManagerRequest request,
+ viz::mojom::FrameSinkManagerClientPtr client);
+ ~DemoService();
+
+ private:
+ std::unique_ptr<viz::VizCompositorThreadRunner> runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(DemoService);
+};
+
+} // namespace demo
+
+#endif // COMPONENTS_VIZ_DEMO_SERVICE_DEMO_SERVICE_H_
diff --git a/chromium/components/viz/host/DEPS b/chromium/components/viz/host/DEPS
index d8f55bbb226..1a6b0e007ae 100644
--- a/chromium/components/viz/host/DEPS
+++ b/chromium/components/viz/host/DEPS
@@ -11,6 +11,7 @@ include_rules = [
"+gpu/ipc/client",
"+gpu/ipc/common",
"+gpu/ipc/host",
+ "+media/capture/mojom/video_capture_types.mojom.h",
"+mojo/public/cpp",
"+services/viz/privileged/interfaces",
"+services/viz/public/interfaces",
diff --git a/chromium/components/viz/host/client_frame_sink_video_capturer.cc b/chromium/components/viz/host/client_frame_sink_video_capturer.cc
index 387f8c6bbb7..d8b32c98db5 100644
--- a/chromium/components/viz/host/client_frame_sink_video_capturer.cc
+++ b/chromium/components/viz/host/client_frame_sink_video_capturer.cc
@@ -6,6 +6,9 @@
#include <utility>
+#include "base/bind.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
+
namespace viz {
namespace {
@@ -147,13 +150,12 @@ ClientFrameSinkVideoCapturer::ResolutionConstraints::ResolutionConstraints(
void ClientFrameSinkVideoCapturer::OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
media::mojom::VideoFrameInfoPtr info,
- const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnFrameCaptured(std::move(data), std::move(info), update_rect,
- content_rect, std::move(callbacks));
+ consumer_->OnFrameCaptured(std::move(data), std::move(info), content_rect,
+ std::move(callbacks));
}
void ClientFrameSinkVideoCapturer::OnStopped() {
diff --git a/chromium/components/viz/host/client_frame_sink_video_capturer.h b/chromium/components/viz/host/client_frame_sink_video_capturer.h
index c5717d7a4bb..1b790ebc8da 100644
--- a/chromium/components/viz/host/client_frame_sink_video_capturer.h
+++ b/chromium/components/viz/host/client_frame_sink_video_capturer.h
@@ -117,7 +117,6 @@ class VIZ_HOST_EXPORT ClientFrameSinkVideoCapturer
void OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
media::mojom::VideoFrameInfoPtr info,
- const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) final;
void OnStopped() final;
diff --git a/chromium/components/viz/host/gpu_client.cc b/chromium/components/viz/host/gpu_client.cc
index 2dac7adf5ca..9610168666b 100644
--- a/chromium/components/viz/host/gpu_client.cc
+++ b/chromium/components/viz/host/gpu_client.cc
@@ -4,6 +4,7 @@
#include "components/viz/host/gpu_client.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/checked_math.h"
#include "components/viz/host/gpu_host_impl.h"
diff --git a/chromium/components/viz/host/gpu_host_impl.cc b/chromium/components/viz/host/gpu_host_impl.cc
index 314623a6d2e..4fd50ad9031 100644
--- a/chromium/components/viz/host/gpu_host_impl.cc
+++ b/chromium/components/viz/host/gpu_host_impl.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
@@ -508,8 +509,7 @@ void GpuHostImpl::DidInitialize(
client_id_to_shader_cache_.clear();
if (!params_.disable_gpu_shader_disk_cache) {
- bool oopd_enabled =
- base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
+ bool oopd_enabled = features::IsVizDisplayCompositorEnabled();
if (oopd_enabled)
CreateChannelCache(gpu::kInProcessCommandBufferClientId);
diff --git a/chromium/components/viz/host/hit_test/hit_test_query.cc b/chromium/components/viz/host/hit_test/hit_test_query.cc
index 21a9fa3ea1a..6b6a63ab28c 100644
--- a/chromium/components/viz/host/hit_test/hit_test_query.cc
+++ b/chromium/components/viz/host/hit_test/hit_test_query.cc
@@ -109,7 +109,6 @@ Target HitTestQuery::FindTargetForLocationStartingFrom(
}
bool HitTestQuery::TransformLocationForTarget(
- EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors,
const gfx::PointF& location_in_root,
gfx::PointF* transformed_location) const {
@@ -142,9 +141,8 @@ bool HitTestQuery::TransformLocationForTarget(
transform_timer.Elapsed(),
base::TimeDelta::FromMicroseconds(1),
base::TimeDelta::FromSeconds(10), 50);
- return TransformLocationForTargetRecursively(event_source, target_ancestors,
- target_ancestors.size() - 1, 0,
- transformed_location);
+ return TransformLocationForTargetRecursively(
+ target_ancestors, target_ancestors.size() - 1, 0, transformed_location);
}
bool HitTestQuery::GetTransformToTarget(const FrameSinkId& target,
@@ -238,7 +236,8 @@ bool HitTestQuery::FindTargetInRegionForLocation(
// TODO(sunxd): v2 doesn't work with drag-n-drop when it still relies on
// synchronous targeting result for nested OOPIF cases. crbug.com/896786
if (features::IsVizHitTestingSurfaceLayerEnabled() &&
- (flags & HitTestRegionFlags::kHitTestAsk)) {
+ ((flags & HitTestRegionFlags::kHitTestAsk) &&
+ !(flags & HitTestRegionFlags::kHitTestIgnore))) {
target->frame_sink_id = hit_test_data_[region_index].frame_sink_id;
target->location_in_target = location_in_target;
target->flags = flags;
@@ -265,8 +264,9 @@ bool HitTestQuery::FindTargetInRegionForLocation(
if (!RegionMatchEventSource(event_source, flags))
return false;
- if (flags &
- (HitTestRegionFlags::kHitTestMine | HitTestRegionFlags::kHitTestAsk)) {
+ if ((flags &
+ (HitTestRegionFlags::kHitTestMine | HitTestRegionFlags::kHitTestAsk)) &&
+ !(flags & HitTestRegionFlags::kHitTestIgnore)) {
target->frame_sink_id = hit_test_data_[region_index].frame_sink_id;
target->location_in_target = location_in_target;
target->flags = flags;
@@ -279,17 +279,10 @@ bool HitTestQuery::FindTargetInRegionForLocation(
}
bool HitTestQuery::TransformLocationForTargetRecursively(
- EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors,
size_t target_ancestor,
size_t region_index,
gfx::PointF* location_in_target) const {
- const uint32_t flags = hit_test_data_[region_index].flags;
- if ((flags & HitTestRegionFlags::kHitTestChildSurface) == 0u &&
- !RegionMatchEventSource(event_source, flags)) {
- return false;
- }
-
hit_test_data_[region_index].transform().TransformPoint(location_in_target);
if (!target_ancestor)
return true;
@@ -306,7 +299,7 @@ bool HitTestQuery::TransformLocationForTargetRecursively(
if (hit_test_data_[child_region].frame_sink_id ==
target_ancestors[target_ancestor - 1]) {
return TransformLocationForTargetRecursively(
- event_source, target_ancestors, target_ancestor - 1, child_region,
+ target_ancestors, target_ancestor - 1, child_region,
location_in_target);
}
diff --git a/chromium/components/viz/host/hit_test/hit_test_query.h b/chromium/components/viz/host/hit_test/hit_test_query.h
index 8261e31a91d..c1f50fde4c0 100644
--- a/chromium/components/viz/host/hit_test/hit_test_query.h
+++ b/chromium/components/viz/host/hit_test/hit_test_query.h
@@ -93,7 +93,6 @@ class VIZ_HOST_EXPORT HitTestQuery {
// |target_ancestors.front()| is the target, and |target_ancestors.back()|
// is the root.
bool TransformLocationForTarget(
- EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors,
const gfx::PointF& location_in_root,
gfx::PointF* transformed_location) const;
@@ -143,7 +142,6 @@ class VIZ_HOST_EXPORT HitTestQuery {
// |location_in_target| is in the coordinate space of |region_index|'s parent
// at the beginning.
bool TransformLocationForTargetRecursively(
- EventSource event_source,
const std::vector<FrameSinkId>& target_ancestors,
size_t target_ancestor,
size_t region_index,
diff --git a/chromium/components/viz/host/hit_test/hit_test_query_fuzzer.cc b/chromium/components/viz/host/hit_test/hit_test_query_fuzzer.cc
index 9af346ce53d..64f601a7878 100644
--- a/chromium/components/viz/host/hit_test/hit_test_query_fuzzer.cc
+++ b/chromium/components/viz/host/hit_test/hit_test_query_fuzzer.cc
@@ -83,8 +83,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t num_bytes) {
for (float y = 0; y < 1000.; y += 10) {
gfx::PointF location(x, y);
query.FindTargetForLocation(viz::EventSource::MOUSE, location);
- query.TransformLocationForTarget(viz::EventSource::MOUSE, frame_sink_ids,
- location, &location);
+ query.TransformLocationForTarget(frame_sink_ids, location, &location);
}
}
diff --git a/chromium/components/viz/host/hit_test/hit_test_query_unittest.cc b/chromium/components/viz/host/hit_test/hit_test_query_unittest.cc
index be5a97edd1a..0c4f06636df 100644
--- a/chromium/components/viz/host/hit_test/hit_test_query_unittest.cc
+++ b/chromium/components/viz/host/hit_test/hit_test_query_unittest.cc
@@ -400,19 +400,19 @@ TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneathTransform) {
std::vector<FrameSinkId> target_ancestors1{e_id};
gfx::PointF transformed_point;
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors1, point1, &transformed_point));
+ target_ancestors1, point1, &transformed_point));
EXPECT_EQ(transformed_point, point1);
std::vector<FrameSinkId> target_ancestors2{a_id, c_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors2, point2, &transformed_point));
+ target_ancestors2, point2, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
std::vector<FrameSinkId> target_ancestors3{d_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors3, point3, &transformed_point));
+ target_ancestors3, point3, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(50, 100));
std::vector<FrameSinkId> target_ancestors4{b_id, c_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors4, point4, &transformed_point));
+ target_ancestors4, point4, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
}
@@ -617,29 +617,29 @@ TEST_F(HitTestQueryTest,
std::vector<FrameSinkId> target_ancestors1{e_id};
gfx::PointF transformed_point;
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors1, point1, &transformed_point));
+ target_ancestors1, point1, &transformed_point));
EXPECT_EQ(transformed_point, point1);
std::vector<FrameSinkId> target_ancestors2{a_id, c1_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors2, point2, &transformed_point));
+ target_ancestors2, point2, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors1, point3, &transformed_point));
+ target_ancestors1, point3, &transformed_point));
EXPECT_EQ(transformed_point, point3);
std::vector<FrameSinkId> target_ancestors3{b_id, c1_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors3, point4, &transformed_point));
+ target_ancestors3, point4, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(2, 2));
std::vector<FrameSinkId> target_ancestors4{g_id, c2_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors4, point5, &transformed_point));
+ target_ancestors4, point5, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(50, 50));
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors1, point6, &transformed_point));
+ target_ancestors1, point6, &transformed_point));
EXPECT_EQ(transformed_point, point6);
std::vector<FrameSinkId> target_ancestors5{h_id, c2_id, e_id};
EXPECT_TRUE(hit_test_query().TransformLocationForTarget(
- EventSource::MOUSE, target_ancestors5, point7, &transformed_point));
+ target_ancestors5, point7, &transformed_point));
EXPECT_EQ(transformed_point, gfx::PointF(150, 300));
}
diff --git a/chromium/components/viz/host/host_frame_sink_manager.cc b/chromium/components/viz/host/host_frame_sink_manager.cc
index 0a5cfbc5245..63d8a0db257 100644
--- a/chromium/components/viz/host/host_frame_sink_manager.cc
+++ b/chromium/components/viz/host/host_frame_sink_manager.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -221,7 +223,6 @@ bool HostFrameSinkManager::RegisterFrameSinkHierarchy(
child_frame_sink_id);
FrameSinkData& child_data = frame_sink_data_map_[child_frame_sink_id];
- DCHECK(child_data.IsFrameSinkRegistered());
DCHECK(!base::ContainsValue(child_data.parents, parent_frame_sink_id));
child_data.parents.push_back(parent_frame_sink_id);
diff --git a/chromium/components/viz/host/host_frame_sink_manager.h b/chromium/components/viz/host/host_frame_sink_manager.h
index 2b331a9552a..54e16d6a4bb 100644
--- a/chromium/components/viz/host/host_frame_sink_manager.h
+++ b/chromium/components/viz/host/host_frame_sink_manager.h
@@ -137,10 +137,7 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
// the child. If |parent_frame_sink_id| is registered then it will be added as
// a parent of |child_frame_sink_id| and the function will return true. If
// |parent_frame_sink_id| is not registered then the function will return
- // false.
- //
- // |child_frame_sink_id| must be registered before calling. A frame sink
- // can have multiple parents.
+ // false. A frame sink can have multiple parents.
bool RegisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id,
const FrameSinkId& child_frame_sink_id);
diff --git a/chromium/components/viz/host/host_gpu_memory_buffer_manager.cc b/chromium/components/viz/host/host_gpu_memory_buffer_manager.cc
index 7bb324eb14e..c3dee70c372 100644
--- a/chromium/components/viz/host/host_gpu_memory_buffer_manager.cc
+++ b/chromium/components/viz/host/host_gpu_memory_buffer_manager.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_dump_manager.h"
diff --git a/chromium/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc b/chromium/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc
index 84cfcad1ec0..5f5c09252b4 100644
--- a/chromium/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc
+++ b/chromium/components/viz/host/host_gpu_memory_buffer_manager_unittest.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
@@ -19,6 +21,10 @@
#include "ui/ozone/public/ozone_platform.h"
#endif
+#if defined(OS_ANDROID)
+#include "base/android/android_hardware_buffer_compat.h"
+#endif
+
namespace viz {
namespace {
@@ -208,6 +214,9 @@ class HostGpuMemoryBufferManagerTest : public ::testing::Test {
native_pixmap_supported =
ui::OzonePlatform::GetInstance()->IsNativePixmapConfigSupported(
gfx::BufferFormat::RGBA_8888, gfx::BufferUsage::GPU_READ);
+#elif defined(OS_ANDROID)
+ native_pixmap_supported =
+ base::AndroidHardwareBufferCompat::IsSupportAvailable();
#elif defined(OS_MACOSX) || defined(OS_WIN)
native_pixmap_supported = true;
#endif
diff --git a/chromium/components/viz/host/renderer_settings_creation.cc b/chromium/components/viz/host/renderer_settings_creation.cc
index e63d201943f..ee1f83f4d3d 100644
--- a/chromium/components/viz/host/renderer_settings_creation.cc
+++ b/chromium/components/viz/host/renderer_settings_creation.cc
@@ -57,10 +57,11 @@ RendererSettings CreateRendererSettings() {
command_line->HasSwitch(switches::kTintGlCompositedContent);
renderer_settings.show_overdraw_feedback =
command_line->HasSwitch(switches::kShowOverdrawFeedback);
- renderer_settings.enable_draw_occlusion = features::IsDrawOcclusionEnabled();
renderer_settings.allow_antialiasing =
!command_line->HasSwitch(switches::kDisableCompositedAntialiasing);
renderer_settings.use_skia_renderer = features::IsUsingSkiaRenderer();
+ renderer_settings.use_skia_renderer_non_ddl =
+ features::IsUsingSkiaRendererNonDDL();
#if defined(OS_MACOSX)
renderer_settings.allow_overlays =
ui::RemoteLayerAPISupported() &&
diff --git a/chromium/components/viz/service/BUILD.gn b/chromium/components/viz/service/BUILD.gn
index 3ecb373d91b..1fd04b6888c 100644
--- a/chromium/components/viz/service/BUILD.gn
+++ b/chromium/components/viz/service/BUILD.gn
@@ -98,6 +98,8 @@ viz_component("service") {
"display_embedder/compositing_mode_reporter_impl.cc",
"display_embedder/compositing_mode_reporter_impl.h",
"display_embedder/compositor_overlay_candidate_validator.h",
+ "display_embedder/direct_context_provider.cc",
+ "display_embedder/direct_context_provider.h",
"display_embedder/display_provider.h",
"display_embedder/gl_output_surface.cc",
"display_embedder/gl_output_surface.h",
@@ -156,6 +158,8 @@ viz_component("service") {
"surfaces/referenced_surface_tracker.h",
"surfaces/surface.cc",
"surfaces/surface.h",
+ "surfaces/surface_allocation_group.cc",
+ "surfaces/surface_allocation_group.h",
"surfaces/surface_client.h",
"surfaces/surface_deadline_client.h",
"surfaces/surface_dependency_deadline.cc",
@@ -285,6 +289,8 @@ viz_component("service") {
"display_embedder/gl_output_surface_android.h",
"display_embedder/gl_output_surface_buffer_queue_android.cc",
"display_embedder/gl_output_surface_buffer_queue_android.h",
+ "display_embedder/overlay_candidate_validator_android.cc",
+ "display_embedder/overlay_candidate_validator_android.h",
]
}
@@ -305,6 +311,8 @@ viz_source_set("gpu_service_dependencies") {
sources = [
"display_embedder/skia_output_surface_impl.cc",
"display_embedder/skia_output_surface_impl.h",
+ "display_embedder/skia_output_surface_impl_non_ddl.cc",
+ "display_embedder/skia_output_surface_impl_non_ddl.h",
"display_embedder/skia_output_surface_impl_on_gpu.cc",
"display_embedder/skia_output_surface_impl_on_gpu.h",
"gl/gpu_service_impl.cc",
@@ -439,7 +447,14 @@ viz_source_set("unit_tests") {
}
if (is_android) {
- sources += [ "frame_sinks/external_begin_frame_source_android_unittest.cc" ]
+ sources += [
+ "display_embedder/overlay_candidate_validator_android_unittest.cc",
+ "frame_sinks/external_begin_frame_source_android_unittest.cc",
+ ]
+ }
+
+ if (enable_vulkan) {
+ deps += [ "//gpu/vulkan/init" ]
}
}
@@ -500,3 +515,11 @@ if (is_android) {
]
}
}
+
+group("viz_service_fuzzers") {
+ testonly = true
+ deps = [
+ ":hit_test_manager_fuzzer",
+ "compositor_frame_fuzzer:compositor_frame_fuzzer",
+ ]
+}
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/BUILD.gn b/chromium/components/viz/service/compositor_frame_fuzzer/BUILD.gn
new file mode 100644
index 00000000000..4530798259f
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/BUILD.gn
@@ -0,0 +1,79 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//testing/libfuzzer/fuzzer_test.gni")
+import("//third_party/protobuf/proto_library.gni")
+
+declare_args() {
+ seed_corpus_dir = "$target_gen_dir/binary_seed_corpus"
+}
+
+proto_library("compositor_frame_fuzzer_proto") {
+ sources = [
+ "compositor_frame_fuzzer.proto",
+ ]
+}
+
+# Encodes text-format protobuf messages into binary-format protobuf
+# messages in seed_corpus_dir.
+#
+# The messages must be of type RenderPass, as defined in the proto2 file
+# compositor_frame_fuzzer.proto (these assumptions are all hardcoded into
+# generate_renderpass_binary.py)
+action_foreach("generate_seed_corpus") {
+ script = "generate_renderpass_binary.py"
+ pyproto_path = "$root_out_dir/pyproto"
+
+ input_dir = "text_format_seed_corpus"
+ sources = [
+ "$input_dir/1_quad_renderpass.asciipb",
+ "$input_dir/2_quad_renderpass.asciipb",
+ "$input_dir/solid_color_tiled_background_with_2_quads_on_top.asciipb",
+ ]
+ outputs = [
+ "$seed_corpus_dir/{{source_name_part}}.pb",
+ ]
+
+ deps = [
+ ":compositor_frame_fuzzer_proto",
+ "//third_party/protobuf:py_proto",
+ ]
+
+ args = [
+ "-i",
+ "{{source}}",
+ "-d",
+ rebase_path(seed_corpus_dir, root_build_dir),
+ "-o",
+ "{{source_name_part}}.pb",
+ "-p",
+ rebase_path(pyproto_path, root_build_dir),
+ "-p",
+ rebase_path("$pyproto_path/components/viz/service/compositor_frame_fuzzer",
+ root_build_dir),
+ ]
+}
+
+fuzzer_test("compositor_frame_fuzzer") {
+ sources = [
+ "compositor_frame_fuzzer.cc",
+ "compositor_frame_fuzzer_util.cc",
+ "compositor_frame_fuzzer_util.h",
+ "fuzzer_browser_process.cc",
+ "fuzzer_browser_process.h",
+ "fuzzer_software_display_provider.cc",
+ "fuzzer_software_display_provider.h",
+ ]
+
+ deps = [
+ ":compositor_frame_fuzzer_proto",
+ "//components/viz/service",
+ "//components/viz/test:test_support",
+ "//mojo/core/embedder",
+ "//third_party/libprotobuf-mutator",
+ ]
+
+ seed_corpus = "$seed_corpus_dir"
+ seed_corpus_deps = [ ":generate_seed_corpus" ]
+}
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/DEPS b/chromium/components/viz/service/compositor_frame_fuzzer/DEPS
new file mode 100644
index 00000000000..0594bae56d6
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/DEPS
@@ -0,0 +1,10 @@
+include_rules = [
+ "+components/viz/service",
+ "+components/viz/test",
+]
+
+specific_include_rules = {
+ "compositor_frame_fuzzer.cc": [
+ "+mojo/core/embedder",
+ ]
+}
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.cc b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.cc
new file mode 100644
index 00000000000..0412aed95bd
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.cc
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "base/no_destructor.h"
+#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h"
+#include "components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h"
+#include "mojo/core/embedder/embedder.h"
+#include "testing/libfuzzer/proto/lpm_interface.h"
+
+#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.pb.h"
+
+namespace {
+
+struct Env {
+ public:
+ Env() {
+ mojo::core::Init();
+
+ // Run fuzzer with the flag --dump-to-png[=dir-name] to dump the browser
+ // display into PNG files for debugging purposes.
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ auto png_dir_path =
+ command_line->HasSwitch("dump-to-png")
+ ? base::Optional<base::FilePath>(
+ command_line->GetSwitchValuePath("dump-to-png"))
+ : base::nullopt;
+
+ browser_process = std::make_unique<viz::FuzzerBrowserProcess>(png_dir_path);
+ }
+ ~Env() = default;
+
+ std::unique_ptr<viz::FuzzerBrowserProcess> browser_process;
+
+ private:
+ base::MessageLoop message_loop;
+};
+
+} // namespace
+
+extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
+ base::CommandLine::Init(*argc, *argv);
+ return 0;
+}
+
+DEFINE_BINARY_PROTO_FUZZER(
+ const content::fuzzing::proto::RenderPass& render_pass_spec) {
+ static base::NoDestructor<Env> env;
+ viz::CompositorFrame frame =
+ viz::GenerateFuzzedCompositorFrame(render_pass_spec);
+ env->browser_process->EmbedFuzzedCompositorFrame(std::move(frame));
+}
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto
new file mode 100644
index 00000000000..7c29097e8c4
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+package content.fuzzing.proto;
+
+message RenderPass {
+ required Rect output_rect = 1;
+ required Rect damage_rect = 2;
+ repeated DrawQuad quad_list = 3;
+}
+
+message DrawQuad {
+ required SharedQuadState sqs = 1;
+ required Rect rect = 2;
+ required Rect visible_rect = 3;
+ required SolidColorDrawQuad quad = 4;
+}
+
+message SharedQuadState {
+ required Transform transform = 1;
+ required Rect layer_rect = 2;
+ required Rect visible_rect = 3;
+ required Rect clip_rect = 4;
+ required bool is_clipped = 5;
+ required bool are_contents_opaque = 6;
+
+ // Will be normalized to a float in [0,1].
+ required fixed32 opacity = 7 [default = 0xffffffff];
+
+ // TODO(celineo): add fuzzable SkBlendMode, crbug.com/923088
+
+ required sint32 sorting_context_id = 9;
+}
+
+message SolidColorDrawQuad {
+ required fixed32 color = 1 [default = 0xffffffff];
+ required bool force_anti_aliasing_off = 2;
+}
+
+// Spec to initialize a gfx::Rect.
+// Defaults to the size of the renderer frame as defined in
+// fuzzer_browser_process.cc, in the hopes that this generally yields more
+// interesting values more quickly.
+message Rect {
+ required sint32 x = 1 [default = 0];
+ required sint32 y = 2 [default = 0];
+ required sint32 width = 3 [default = 620];
+ required sint32 height = 4 [default = 400];
+}
+
+message Transform {
+ required double rotate = 1 [default = 0];
+
+ required float scale_x = 2 [default = 1];
+ required float scale_y = 3 [default = 1];
+
+ required float translate_x = 4 [default = 0];
+ required float translate_y = 5 [default = 0];
+}
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
new file mode 100644
index 00000000000..988c4d46925
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -0,0 +1,142 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h"
+
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "components/viz/common/quads/solid_color_draw_quad.h"
+#include "components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h"
+
+namespace viz {
+
+namespace {
+
+// Handles inf / NaN by setting to 0.
+double MakeNormal(double x) {
+ return isnormal(x) ? x : 0;
+}
+float MakeNormal(float x) {
+ return isnormal(x) ? x : 0;
+}
+
+// Normalizes value to a float in [0, 1]. Use to convert a fuzzed
+// uint32 into a percentage.
+float Normalize(uint32_t x) {
+ return static_cast<float>(x) / std::numeric_limits<uint32_t>::max();
+}
+
+gfx::Rect GetRectFromProtobuf(const content::fuzzing::proto::Rect& proto_rect) {
+ return gfx::Rect(proto_rect.x(), proto_rect.y(), proto_rect.width(),
+ proto_rect.height());
+}
+
+gfx::Transform GetTransformFromProtobuf(
+ const content::fuzzing::proto::Transform& proto_transform) {
+ gfx::Transform transform = gfx::Transform();
+
+ // Note: There are no checks here that disallow a non-invertible transform
+ // (for instance, if |scale_x| or |scale_y| is 0).
+ transform.Scale(MakeNormal(proto_transform.scale_x()),
+ MakeNormal(proto_transform.scale_y()));
+
+ transform.Rotate(MakeNormal(proto_transform.rotate()));
+
+ transform.Translate(MakeNormal(proto_transform.translate_x()),
+ MakeNormal(proto_transform.translate_y()));
+
+ return transform;
+}
+
+// Mutates a gfx::Rect to ensure width and height are both at least min_size.
+// Use in case e.g. a 0-width/height Rect would cause a validation error on
+// deserialization.
+void ExpandToMinSize(gfx::Rect* rect, int min_size) {
+ if (rect->width() < min_size) {
+ // grow width to min_size in +x direction
+ // (may be clamped if x + min_size overflows)
+ rect->set_width(min_size);
+ }
+
+ // if previous attempt failed due to overflow
+ if (rect->width() < min_size) {
+ // grow width to min_size in -x direction
+ rect->Offset(-(min_size - rect->width()), 0);
+ rect->set_width(min_size);
+ }
+
+ if (rect->height() < min_size) {
+ // grow height to min_size in +y direction
+ // (may be clamped if y + min_size overflows)
+ rect->set_height(min_size);
+ }
+
+ // if previous attempt failed due to overflow
+ if (rect->height() < min_size) {
+ // grow height to min_size in -y direction
+ rect->Offset(0, -(min_size - rect->height()));
+ rect->set_height(min_size);
+ }
+}
+
+} // namespace
+
+CompositorFrame GenerateFuzzedCompositorFrame(
+ const content::fuzzing::proto::RenderPass& render_pass_spec) {
+ CompositorFrame frame;
+
+ frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId;
+ frame.metadata.begin_frame_ack.sequence_number =
+ BeginFrameArgs::kStartingFrameNumber;
+ frame.metadata.begin_frame_ack.has_damage = true;
+ frame.metadata.frame_token = 1;
+ frame.metadata.device_scale_factor = 1;
+ frame.metadata.local_surface_id_allocation_time = base::TimeTicks::Now();
+
+ std::unique_ptr<RenderPass> pass = RenderPass::Create();
+ gfx::Rect rp_output_rect =
+ GetRectFromProtobuf(render_pass_spec.output_rect());
+ gfx::Rect rp_damage_rect =
+ GetRectFromProtobuf(render_pass_spec.damage_rect());
+
+ // Handle constraints on RenderPass:
+ // Ensure that |rp_output_rect| has non-zero area and that |rp_damage_rect| is
+ // contained in |rp_output_rect|.
+ ExpandToMinSize(&rp_output_rect, 1);
+ rp_damage_rect.AdjustToFit(rp_output_rect);
+
+ pass->SetNew(1, rp_output_rect, rp_damage_rect, gfx::Transform());
+
+ for (const auto& quad_spec : render_pass_spec.quad_list()) {
+ gfx::Rect quad_rect = GetRectFromProtobuf(quad_spec.rect());
+ gfx::Rect quad_visible_rect = GetRectFromProtobuf(quad_spec.visible_rect());
+
+ // Handle constraints on DrawQuad:
+ // Ensure that |quad_rect| has non-zero area and that |quad_visible_rect| is
+ // contained in |quad_rect|.
+ ExpandToMinSize(&quad_rect, 1);
+ quad_visible_rect.AdjustToFit(quad_rect);
+
+ auto* shared_quad_state = pass->CreateAndAppendSharedQuadState();
+ shared_quad_state->SetAll(
+ GetTransformFromProtobuf(quad_spec.sqs().transform()),
+ GetRectFromProtobuf(quad_spec.sqs().layer_rect()),
+ GetRectFromProtobuf(quad_spec.sqs().visible_rect()),
+ GetRectFromProtobuf(quad_spec.sqs().clip_rect()),
+ quad_spec.sqs().is_clipped(), quad_spec.sqs().are_contents_opaque(),
+ Normalize(quad_spec.sqs().opacity()), SkBlendMode::kSrcOver,
+ quad_spec.sqs().sorting_context_id());
+ auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ color_quad->SetNew(shared_quad_state, quad_rect, quad_visible_rect,
+ quad_spec.quad().color(),
+ quad_spec.quad().force_anti_aliasing_off());
+ }
+
+ frame.render_pass_list.push_back(std::move(pass));
+ return frame;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h
new file mode 100644
index 00000000000..633bc08d060
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_COMPOSITOR_FRAME_FUZZER_UTIL_H_
+#define COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_COMPOSITOR_FRAME_FUZZER_UTIL_H_
+
+#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.pb.h"
+
+namespace viz {
+
+// Converts a fuzzed specification in the form of a RenderPass protobuf message
+// (as defined in compositor_frame_fuzzer.proto) into a CompositorFrame with a
+// RenderPass member.
+//
+// Performs minimal validation and corrections to ensure that submitting the
+// frame to a CompositorFrameSink will not result in a mojo deserialization
+// validation error.
+CompositorFrame GenerateFuzzedCompositorFrame(
+ const content::fuzzing::proto::RenderPass& render_pass_spec);
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_COMPOSITOR_FRAME_FUZZER_UTIL_H_
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc
new file mode 100644
index 00000000000..a3ed55ce230
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc
@@ -0,0 +1,142 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/run_loop.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
+#include "components/viz/common/quads/surface_draw_quad.h"
+#include "components/viz/common/surfaces/surface_range.h"
+
+namespace viz {
+
+namespace {
+
+// If modifying these sizes, consider also updating the default values in
+// compositor_frame_fuzzer.proto to match.
+constexpr gfx::Size kBrowserSize(620, 480);
+constexpr gfx::Size kTopBarSize(620, 80);
+constexpr gfx::Size kRendererFrameSize(620, 400);
+
+constexpr FrameSinkId kEmbeddedFrameSinkId(2, 1);
+constexpr FrameSinkId kRootFrameSinkId(1, 1);
+
+} // namespace
+
+FuzzerBrowserProcess::FuzzerBrowserProcess(
+ base::Optional<base::FilePath> png_dir_path)
+ : root_local_surface_id_(1, 1, base::UnguessableToken::Create()),
+ display_provider_(std::move(png_dir_path)),
+ frame_sink_manager_(&shared_bitmap_manager_,
+ base::nullopt,
+ &display_provider_) {
+ frame_sink_manager_.RegisterFrameSinkId(kEmbeddedFrameSinkId,
+ /*report_activation=*/false);
+ frame_sink_manager_.RegisterFrameSinkId(kRootFrameSinkId,
+ /*report_activation=*/false);
+ frame_sink_manager_.CreateRootCompositorFrameSink(
+ BuildRootCompositorFrameSinkParams());
+ display_private_->SetDisplayVisible(true);
+ display_private_->Resize(kBrowserSize);
+}
+
+FuzzerBrowserProcess::~FuzzerBrowserProcess() {
+ frame_sink_manager_.InvalidateFrameSinkId(kRootFrameSinkId);
+ frame_sink_manager_.InvalidateFrameSinkId(kEmbeddedFrameSinkId);
+}
+
+void FuzzerBrowserProcess::EmbedFuzzedCompositorFrame(
+ CompositorFrame fuzzed_frame) {
+ mojom::CompositorFrameSinkPtr sink_ptr;
+ FakeCompositorFrameSinkClient sink_client;
+ frame_sink_manager_.CreateCompositorFrameSink(kEmbeddedFrameSinkId,
+ mojo::MakeRequest(&sink_ptr),
+ sink_client.BindInterfacePtr());
+
+ lsi_allocator_.GenerateId();
+ SurfaceId embedded_surface_id(
+ kEmbeddedFrameSinkId,
+ lsi_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ sink_ptr->SubmitCompositorFrame(embedded_surface_id.local_surface_id(),
+ std::move(fuzzed_frame), base::nullopt, 0);
+
+ CompositorFrame browser_frame =
+ BuildBrowserUICompositorFrame(embedded_surface_id);
+ root_compositor_frame_sink_ptr_->SubmitCompositorFrame(
+ root_local_surface_id_, std::move(browser_frame), base::nullopt, 0);
+ display_private_->ForceImmediateDrawAndSwapIfPossible();
+
+ base::RunLoop().RunUntilIdle(); // needed to actually run queued messages
+
+ frame_sink_manager_.DestroyCompositorFrameSink(kEmbeddedFrameSinkId,
+ base::DoNothing());
+}
+
+mojom::RootCompositorFrameSinkParamsPtr
+FuzzerBrowserProcess::BuildRootCompositorFrameSinkParams() {
+ auto params = mojom::RootCompositorFrameSinkParams::New();
+ params->frame_sink_id = kRootFrameSinkId;
+ params->widget = gpu::kNullSurfaceHandle;
+ params->gpu_compositing = false;
+ params->compositor_frame_sink = mojo::MakeRequestAssociatedWithDedicatedPipe(
+ &root_compositor_frame_sink_ptr_);
+ params->compositor_frame_sink_client =
+ root_compositor_frame_sink_client_.BindInterfacePtr().PassInterface();
+ params->display_private =
+ MakeRequestAssociatedWithDedicatedPipe(&display_private_);
+ params->display_client = display_client_.BindInterfacePtr().PassInterface();
+ return params;
+}
+
+CompositorFrame FuzzerBrowserProcess::BuildBrowserUICompositorFrame(
+ SurfaceId renderer_surface_id) {
+ CompositorFrame frame;
+
+ frame.metadata.frame_token = 1;
+ frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId;
+ frame.metadata.begin_frame_ack.sequence_number =
+ BeginFrameArgs::kStartingFrameNumber;
+ frame.metadata.device_scale_factor = 1;
+ frame.metadata.local_surface_id_allocation_time = base::TimeTicks::Now();
+ frame.metadata.referenced_surfaces.push_back(
+ SurfaceRange(base::nullopt, renderer_surface_id));
+
+ std::unique_ptr<RenderPass> pass = RenderPass::Create();
+ pass->SetNew(/*id=*/1, gfx::Rect(kBrowserSize), gfx::Rect(kBrowserSize),
+ gfx::Transform());
+
+ auto* renderer_sqs = pass->CreateAndAppendSharedQuadState();
+ renderer_sqs->SetAll(gfx::Transform(1.0, 0.0, 0.0, 1.0, 0, 80),
+ gfx::Rect(kRendererFrameSize),
+ gfx::Rect(kRendererFrameSize),
+ gfx::Rect(kRendererFrameSize), /*is_clipped=*/false,
+ /*are_contents_opaque=*/false, /*opacity=*/1,
+ SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
+ auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
+ surface_quad->SetNew(renderer_sqs, gfx::Rect(kRendererFrameSize),
+ gfx::Rect(kRendererFrameSize),
+ SurfaceRange(base::nullopt, renderer_surface_id),
+ SK_ColorWHITE,
+ /*stretch_content_to_fill_bounds=*/false,
+ /*ignores_input_event=*/false);
+
+ auto* toolbar_sqs = pass->CreateAndAppendSharedQuadState();
+ toolbar_sqs->SetAll(gfx::Transform(), gfx::Rect(kTopBarSize),
+ gfx::Rect(kTopBarSize), gfx::Rect(kTopBarSize),
+ /*is_clipped=*/false, /*are_contents_opaque=*/false,
+ /*opacity=*/1, SkBlendMode::kSrcOver,
+ /*sorting_context_id=*/0);
+ auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ color_quad->SetNew(toolbar_sqs, gfx::Rect(kTopBarSize),
+ gfx::Rect(kTopBarSize), SK_ColorLTGRAY,
+ /*force_antialiasing_off=*/false);
+ frame.render_pass_list.push_back(std::move(pass));
+
+ return frame;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h
new file mode 100644
index 00000000000..d080d6a6227
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h
@@ -0,0 +1,58 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_BROWSER_PROCESS_H_
+#define COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_BROWSER_PROCESS_H_
+
+#include "components/viz/common/surfaces/frame_sink_id.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+#include "components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h"
+#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "components/viz/test/fake_compositor_frame_sink_client.h"
+#include "components/viz/test/fake_display_client.h"
+
+namespace viz {
+
+// A fake browser process to use as a fuzzer target.
+// Uses software compositing.
+class FuzzerBrowserProcess {
+ public:
+ explicit FuzzerBrowserProcess(base::Optional<base::FilePath> png_dir_path);
+ ~FuzzerBrowserProcess();
+
+ // Fuzz target mimicking the process of submitting a rendered CompositorFrame
+ // to be embedded in the browser UI.
+ //
+ // Submits the provided fuzzed CompositorFrame to a new
+ // CompositorFrameSinkImpl.
+ //
+ // Submits a CompositorFrame to the RootCompositorFrameSinkImpl
+ // with a SolidColorDrawQuad "toolbar" and a SurfaceDrawQuad "renderer frame"
+ // embedding the fuzzed CompositorFrame.
+ void EmbedFuzzedCompositorFrame(CompositorFrame fuzzed_frame);
+
+ private:
+ mojom::RootCompositorFrameSinkParamsPtr BuildRootCompositorFrameSinkParams();
+ CompositorFrame BuildBrowserUICompositorFrame(SurfaceId renderer_surface_id);
+
+ const LocalSurfaceId root_local_surface_id_;
+
+ ServerSharedBitmapManager shared_bitmap_manager_;
+ FuzzerSoftwareDisplayProvider display_provider_;
+ FrameSinkManagerImpl frame_sink_manager_;
+
+ mojom::CompositorFrameSinkAssociatedPtr root_compositor_frame_sink_ptr_;
+ FakeCompositorFrameSinkClient root_compositor_frame_sink_client_;
+ mojom::DisplayPrivateAssociatedPtr display_private_;
+ FakeDisplayClient display_client_;
+
+ ParentLocalSurfaceIdAllocator lsi_allocator_;
+
+ DISALLOW_COPY_AND_ASSIGN(FuzzerBrowserProcess);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_BROWSER_PROCESS_H_
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc
new file mode 100644
index 00000000000..dda5a2fb497
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/files/file_util.h"
+#include "components/viz/service/display/software_output_device.h"
+#include "components/viz/service/display_embedder/software_output_surface.h"
+#include "third_party/skia/include/encode/SkPngEncoder.h"
+#include "ui/gfx/codec/png_codec.h"
+
+namespace viz {
+
+namespace {
+
+// SoftwareOutputDevice that dumps the display's pixmap into a new PNG file per
+// paint event. For debugging only: this significantly slows down fuzzing
+// iterations and will not handle more than UINT32_MAX files.
+class PNGSoftwareOutputDevice : public SoftwareOutputDevice {
+ public:
+ explicit PNGSoftwareOutputDevice(base::FilePath output_dir)
+ : output_dir_(output_dir) {}
+
+ // SoftwareOutputDevice implementation
+ void EndPaint() override {
+ SkPixmap input_pixmap;
+ surface_->peekPixels(&input_pixmap);
+
+ gfx::PNGCodec::ColorFormat color_format;
+ switch (input_pixmap.colorType()) {
+ case kRGBA_8888_SkColorType:
+ color_format = gfx::PNGCodec::FORMAT_RGBA;
+ break;
+ case kBGRA_8888_SkColorType:
+ color_format = gfx::PNGCodec::FORMAT_BGRA;
+ break;
+ default:
+ // failing to find a better default, this one is OK; PNGCodec::Encode
+ // will convert this to kN32_SkColorType
+ color_format = gfx::PNGCodec::FORMAT_SkBitmap;
+ break;
+ }
+
+ std::vector<unsigned char> output;
+ gfx::PNGCodec::Encode(
+ static_cast<const unsigned char*>(input_pixmap.addr()), color_format,
+ gfx::Size(input_pixmap.width(), input_pixmap.height()),
+ input_pixmap.rowBytes(),
+ /*discard_transparency=*/false,
+ /*comments=*/{}, &output);
+
+ base::WriteFile(NextOutputFilePath(),
+ reinterpret_cast<char*>(output.data()), output.size());
+ }
+
+ private:
+ // Return path of next output file. Will not handle overflow of file_id_.
+ base::FilePath NextOutputFilePath() {
+ // maximum possible length of next_file_id_ (in characters)
+ constexpr int kPaddedIntLength = 10;
+
+ std::string file_name =
+ base::StringPrintf("%0*u.png", kPaddedIntLength, next_file_id_++);
+
+ return output_dir_.Append(base::FilePath::FromUTF8Unsafe(file_name));
+ }
+
+ base::FilePath output_dir_;
+ uint32_t next_file_id_ = 0;
+};
+
+} // namespace
+
+FuzzerSoftwareDisplayProvider::FuzzerSoftwareDisplayProvider(
+ base::Optional<base::FilePath> png_dir_path)
+ : png_dir_path_(png_dir_path),
+ begin_frame_source_(std::make_unique<StubBeginFrameSource>()) {}
+
+FuzzerSoftwareDisplayProvider::~FuzzerSoftwareDisplayProvider() = default;
+
+std::unique_ptr<Display> FuzzerSoftwareDisplayProvider::CreateDisplay(
+ const FrameSinkId& frame_sink_id,
+ gpu::SurfaceHandle surface_handle,
+ bool gpu_compositing,
+ mojom::DisplayClient* display_client,
+ ExternalBeginFrameSource* external_begin_frame_source,
+ SyntheticBeginFrameSource* synthetic_begin_frame_source,
+ const RendererSettings& renderer_settings,
+ bool send_swap_size_notifications) {
+ auto task_runner = base::ThreadTaskRunnerHandle::Get();
+ DCHECK(task_runner);
+
+ std::unique_ptr<SoftwareOutputDevice> software_output_device =
+ png_dir_path_ ? std::make_unique<PNGSoftwareOutputDevice>(*png_dir_path_)
+ : std::make_unique<SoftwareOutputDevice>();
+
+ auto output_surface = std::make_unique<SoftwareOutputSurface>(
+ std::move(software_output_device), synthetic_begin_frame_source);
+
+ auto scheduler = std::make_unique<DisplayScheduler>(
+ begin_frame_source_.get(), task_runner.get(),
+ output_surface->capabilities().max_frames_pending);
+
+ return std::make_unique<Display>(&shared_bitmap_manager_, renderer_settings,
+ frame_sink_id, std::move(output_surface),
+ std::move(scheduler), task_runner);
+}
+
+uint32_t FuzzerSoftwareDisplayProvider::GetRestartId() const {
+ return BeginFrameSource::kNotRestartableId;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h
new file mode 100644
index 00000000000..ee236bf2568
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.h
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_SOFTWARE_DISPLAY_PROVIDER_H_
+#define COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_SOFTWARE_DISPLAY_PROVIDER_H_
+
+#include <memory>
+
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display_embedder/display_provider.h"
+#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+
+namespace viz {
+
+// DisplayProvider implementation that provides Displays that use a
+// SoftwareOutputSurface (no-op by default, with an option to dump pixmap to a
+// PNG for debugging).
+//
+// Provided Displays will only draw when explicitly asked to
+// (e.g. if Display::ForceImmediateDrawAndSwapIfPossible() is called),
+// ignoring the BeginFrameSource parameters passed to CreateDisplay.
+class FuzzerSoftwareDisplayProvider : public DisplayProvider {
+ public:
+ explicit FuzzerSoftwareDisplayProvider(
+ base::Optional<base::FilePath> png_dir_path);
+ ~FuzzerSoftwareDisplayProvider() override;
+
+ // DisplayProvider implementation.
+ std::unique_ptr<Display> CreateDisplay(
+ const FrameSinkId& frame_sink_id,
+ gpu::SurfaceHandle surface_handle,
+ bool gpu_compositing,
+ mojom::DisplayClient* display_client,
+ ExternalBeginFrameSource* external_begin_frame_source,
+ SyntheticBeginFrameSource* synthetic_begin_frame_source,
+ const RendererSettings& renderer_settings,
+ bool send_swap_size_notifications) override;
+ uint32_t GetRestartId() const override;
+
+ private:
+ base::Optional<base::FilePath> png_dir_path_;
+ ServerSharedBitmapManager shared_bitmap_manager_;
+ std::unique_ptr<StubBeginFrameSource> begin_frame_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(FuzzerSoftwareDisplayProvider);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_COMPOSITOR_FRAME_FUZZER_FUZZER_SOFTWARE_DISPLAY_PROVIDER_H_
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/generate_renderpass_binary.py b/chromium/components/viz/service/compositor_frame_fuzzer/generate_renderpass_binary.py
new file mode 100755
index 00000000000..8db27544d68
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/generate_renderpass_binary.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Compiles a text-format RenderPass protobuf message to binary format.
+"""
+
+import os
+import sys
+
+# go up 5 parent directories to //src/
+path_to_src_root = os.path.join(
+ os.path.abspath(__file__), *[os.path.pardir] * 5)
+
+# allow importing modules from //src/chrome/browser/resources/protobufs
+sys.path.insert(0, os.path.normpath(
+ os.path.join(path_to_src_root, 'chrome/browser/resources/protobufs')))
+
+from binary_proto_generator import BinaryProtoGenerator
+
+class RenderPassProtoGenerator(BinaryProtoGenerator):
+ def ImportProtoModule(self):
+ import compositor_frame_fuzzer_pb2
+ globals()['compositor_frame_fuzzer_pb2'] = compositor_frame_fuzzer_pb2
+
+ def EmptyProtoInstance(self):
+ return compositor_frame_fuzzer_pb2.RenderPass()
+
+ def ProcessPb(self, opts, pb):
+ with open(os.path.join(opts.outdir, opts.outbasename), 'wb') as out_file:
+ out_file.write(pb.SerializeToString())
+
+def main():
+ return RenderPassProtoGenerator().Run()
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/1_quad_renderpass.asciipb b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/1_quad_renderpass.asciipb
new file mode 100644
index 00000000000..92469d4ad91
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/1_quad_renderpass.asciipb
@@ -0,0 +1,63 @@
+output_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+damage_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+quad_list: [
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ quad: {
+ color: 0xffffffff
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: -90
+ scale_x: 0.5
+ scale_y: 1.5
+ translate_x: -50
+ translate_y: 10
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: false
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ }
+]
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/2_quad_renderpass.asciipb b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/2_quad_renderpass.asciipb
new file mode 100644
index 00000000000..615682595e7
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/2_quad_renderpass.asciipb
@@ -0,0 +1,112 @@
+output_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+damage_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+quad_list: [
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ quad: {
+ color: 0xffffffff
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: -90
+ scale_x: -0.5
+ scale_y: -1.5
+ translate_x: -50
+ translate_y: 10
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ quad: {
+ color: 0xff000000
+ force_anti_aliasing_off: true
+ }
+ sqs: {
+ transform: {
+ rotate: 90
+ scale_x: 0.5
+ scale_y: 1.5
+ translate_x: 50
+ translate_y: -10
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: false
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 1
+ }
+ }
+]
diff --git a/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/solid_color_tiled_background_with_2_quads_on_top.asciipb b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/solid_color_tiled_background_with_2_quads_on_top.asciipb
new file mode 100644
index 00000000000..f6d487a0703
--- /dev/null
+++ b/chromium/components/viz/service/compositor_frame_fuzzer/text_format_seed_corpus/solid_color_tiled_background_with_2_quads_on_top.asciipb
@@ -0,0 +1,406 @@
+output_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+damage_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+}
+quad_list: [
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ quad: {
+ color: 0xffff0000
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 20
+ scale_x: 1
+ scale_y: 1
+ translate_x: 100
+ translate_y: 100
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 0
+ height: 0
+ }
+ is_clipped: false
+ are_contents_opaque: false
+ opacity: 0x7FFFFFFF
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ quad: {
+ color: 0xffffffff
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 2
+ scale_y: 2
+ translate_x: 100
+ translate_y: -20
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 100
+ height: 100
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 0
+ height: 0
+ }
+ is_clipped: false
+ are_contents_opaque: false
+ opacity: 0x7FFFFFFF
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 0
+ y: 0
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 256
+ height: 256
+ }
+ quad: {
+ color: 0xff000000
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 256
+ y: 0
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 256
+ height: 256
+ }
+ quad: {
+ color: 0xff00ff00
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 512
+ y: 0
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 108
+ height: 256
+ }
+ quad: {
+ color: 0xff0000ff
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 0
+ y: 256
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 256
+ height: 144
+ }
+ quad: {
+ color: 0xff0000ff
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 256
+ y: 256
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 256
+ height: 144
+ }
+ quad: {
+ color: 0xff00ff00
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ },
+ {
+ rect: {
+ x: 512
+ y: 256
+ width: 256
+ height: 256
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 108
+ height: 144
+ }
+ quad: {
+ color: 0xff000000
+ force_anti_aliasing_off: false
+ }
+ sqs: {
+ transform: {
+ rotate: 0
+ scale_x: 1
+ scale_y: 1
+ translate_x: 0
+ translate_y: 0
+ }
+ layer_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ visible_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ clip_rect: {
+ x: 0
+ y: 0
+ width: 620
+ height: 400
+ }
+ is_clipped: true
+ are_contents_opaque: false
+ opacity: 0xffffffff
+ sorting_context_id: 0
+ }
+ }
+]
diff --git a/chromium/components/viz/service/display/bsp_tree_perftest.cc b/chromium/components/viz/service/display/bsp_tree_perftest.cc
index 29efb30ae91..2895bd10070 100644
--- a/chromium/components/viz/service/display/bsp_tree_perftest.cc
+++ b/chromium/components/viz/service/display/bsp_tree_perftest.cc
@@ -14,7 +14,7 @@
#include "base/strings/string_piece.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
-#include "cc/base/lap_timer.h"
+#include "base/timer/lap_timer.h"
#include "cc/layers/layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_layer_tree_host_client.h"
@@ -135,12 +135,12 @@ class BspTreePerfTest : public cc::LayerTreeTest {
void AfterTest() override {
CHECK(!test_name_.empty()) << "Must SetTestName() before TearDown().";
perf_test::PrintResult("calc_draw_props_time", "", test_name_,
- 1000 * timer_.MsPerLap(), "us", true);
+ timer_.TimePerLap().InMicrosecondsF(), "us", true);
}
private:
cc::FakeContentLayerClient content_layer_client_;
- cc::LapTimer timer_;
+ base::LapTimer timer_;
std::string test_name_;
std::string json_;
cc::LayerImplList base_list_;
diff --git a/chromium/components/viz/service/display/ca_layer_overlay.cc b/chromium/components/viz/service/display/ca_layer_overlay.cc
index d1c440b268e..2d0eed44a8c 100644
--- a/chromium/components/viz/service/display/ca_layer_overlay.cc
+++ b/chromium/components/viz/service/display/ca_layer_overlay.cc
@@ -33,7 +33,7 @@ enum CALayerResult {
CA_LAYER_FAILED_UNKNOWN,
CA_LAYER_FAILED_IO_SURFACE_NOT_CANDIDATE,
CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE,
- CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM,
+ CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM_DEPRECATED,
CA_LAYER_FAILED_TEXTURE_NOT_CANDIDATE,
CA_LAYER_FAILED_TEXTURE_Y_FLIPPED,
CA_LAYER_FAILED_TILE_NOT_CANDIDATE,
@@ -111,11 +111,8 @@ CALayerResult FromStreamVideoQuad(DisplayResourceProvider* resource_provider,
if (!resource_provider->IsOverlayCandidate(resource_id))
return CA_LAYER_FAILED_STREAM_VIDEO_NOT_CANDIDATE;
ca_layer_overlay->contents_resource_id = resource_id;
- // TODO(ccameron): Support merging at least some basic transforms into the
- // layer transform.
- if (!quad->matrix.IsIdentity())
- return CA_LAYER_FAILED_STREAM_VIDEO_TRANSFORM;
- ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1);
+ ca_layer_overlay->contents_rect =
+ BoundingRect(quad->uv_top_left, quad->uv_bottom_right);
return CA_LAYER_SUCCESS;
}
diff --git a/chromium/components/viz/service/display/copy_output_scaling_pixeltest.cc b/chromium/components/viz/service/display/copy_output_scaling_pixeltest.cc
index 771585a9a26..8f5d9e940b4 100644
--- a/chromium/components/viz/service/display/copy_output_scaling_pixeltest.cc
+++ b/chromium/components/viz/service/display/copy_output_scaling_pixeltest.cc
@@ -297,14 +297,14 @@ using GLCopyOutputScalingPixelTest = CopyOutputScalingPixelTest<GLRenderer>;
TEST_P(GLCopyOutputScalingPixelTest, ScaledCopyOfDrawnFrame) {
RunTest();
}
-INSTANTIATE_TEST_CASE_P(, GLCopyOutputScalingPixelTest, kParameters);
+INSTANTIATE_TEST_SUITE_P(, GLCopyOutputScalingPixelTest, kParameters);
using SoftwareCopyOutputScalingPixelTest =
CopyOutputScalingPixelTest<SoftwareRenderer>;
TEST_P(SoftwareCopyOutputScalingPixelTest, ScaledCopyOfDrawnFrame) {
RunTest();
}
-INSTANTIATE_TEST_CASE_P(, SoftwareCopyOutputScalingPixelTest, kParameters);
+INSTANTIATE_TEST_SUITE_P(, SoftwareCopyOutputScalingPixelTest, kParameters);
} // namespace
} // namespace viz
diff --git a/chromium/components/viz/service/display/dc_layer_overlay.cc b/chromium/components/viz/service/display/dc_layer_overlay.cc
index 2a4e470eedd..a1fe58701d0 100644
--- a/chromium/components/viz/service/display/dc_layer_overlay.cc
+++ b/chromium/components/viz/service/display/dc_layer_overlay.cc
@@ -13,6 +13,7 @@
#include "components/viz/service/display/display_resource_provider.h"
#include "components/viz/service/display/output_surface.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/config/gpu_finch_features.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gl/gl_switches.h"
@@ -39,6 +40,7 @@ enum DCLayerResult {
DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
const gfx::Transform& transform_to_root_target,
bool has_hw_overlay_support,
+ int current_frame_processed_overlay_count,
DisplayResourceProvider* resource_provider,
DCLayerOverlay* dc_layer) {
// Check that resources are overlay compatible first so that subsequent
@@ -60,6 +62,22 @@ DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
ui::ProtectedVideoType::kSoftwareProtected) {
return DC_LAYER_FAILED_NO_HW_OVERLAY_SUPPORT;
}
+
+ if (!quad->shared_quad_state->quad_to_target_transform
+ .Preserves2dAxisAlignment() &&
+ quad->protected_video_type !=
+ ui::ProtectedVideoType::kHardwareProtected &&
+ !base::FeatureList::IsEnabled(
+ features::kDirectCompositionComplexOverlays)) {
+ return DC_LAYER_FAILED_COMPLEX_TRANSFORM;
+ }
+
+ if (current_frame_processed_overlay_count > 0 &&
+ quad->protected_video_type !=
+ ui::ProtectedVideoType::kHardwareProtected) {
+ return DC_LAYER_FAILED_TOO_MANY_OVERLAYS;
+ }
+
// Direct composition path only supports single NV12 buffer, or two buffers
// one each for Y and UV planes.
DCHECK(quad->y_plane_resource_id() && quad->u_plane_resource_id());
@@ -94,6 +112,24 @@ DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
return DC_LAYER_SUCCESS;
}
+DCLayerResult IsUnderlayAllowed(const QuadList::Iterator& it,
+ bool is_root,
+ const DCLayerOverlay& dc_layer) {
+ if (!dc_layer.RequiresOverlay()) {
+ if (!base::FeatureList::IsEnabled(features::kDirectCompositionUnderlays)) {
+ return DC_LAYER_FAILED_OCCLUDED;
+ }
+ if (!is_root && !base::FeatureList::IsEnabled(
+ features::kDirectCompositionNonrootOverlays)) {
+ return DC_LAYER_FAILED_NON_ROOT;
+ }
+ if (it->shared_quad_state->opacity < 1.0f) {
+ return DC_LAYER_FAILED_TRANSPARENT;
+ }
+ }
+ return DC_LAYER_SUCCESS;
+}
+
// This returns the smallest rectangle in target space that contains the quad.
gfx::RectF ClippedQuadRectangle(const DrawQuad* quad) {
gfx::RectF quad_rect = cc::MathUtil::MapClippedRect(
@@ -104,12 +140,15 @@ gfx::RectF ClippedQuadRectangle(const DrawQuad* quad) {
return quad_rect;
}
-// Find a rectangle containing all the quads in a list that occlude the area
-// in target_quad.
+// GetOcclusionBounds() - Find a rectangle containing all the quads in a list
+// that occlude the area in target_quad.
+// |has_occluding_surface_damage| - used for underlay power optimization.
gfx::RectF GetOcclusionBounds(const gfx::RectF& target_quad,
QuadList::ConstIterator quad_list_begin,
- QuadList::ConstIterator quad_list_end) {
+ QuadList::ConstIterator quad_list_end,
+ bool* has_occluding_surface_damage) {
gfx::RectF occlusion_bounding_box;
+ *has_occluding_surface_damage = false;
for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end;
++overlap_iter) {
float opacity = overlap_iter->shared_quad_state->opacity;
@@ -127,6 +166,8 @@ gfx::RectF GetOcclusionBounds(const gfx::RectF& target_quad,
overlap_rect.Intersect(target_quad);
if (!overlap_rect.IsEmpty()) {
occlusion_bounding_box.Union(overlap_rect);
+ *has_occluding_surface_damage |=
+ overlap_iter->shared_quad_state->has_surface_damage;
}
}
return occlusion_bounding_box;
@@ -176,20 +217,24 @@ void DCLayerOverlayProcessor::Process(
DisplayResourceProvider* resource_provider,
const gfx::RectF& display_rect,
RenderPassList* render_passes,
- gfx::Rect* overlay_damage_rect,
gfx::Rect* damage_rect,
DCLayerOverlayList* dc_layer_overlays) {
- processed_overlay_in_frame_ = false;
pass_punch_through_rects_.clear();
for (auto& pass : *render_passes) {
bool is_root = (pass == render_passes->back());
ProcessRenderPass(resource_provider, display_rect, pass.get(), is_root,
- overlay_damage_rect,
is_root ? damage_rect : &pass->damage_rect,
dc_layer_overlays);
}
}
+void DCLayerOverlayProcessor::ClearOverlayState() {
+ previous_frame_underlay_rect_ = gfx::Rect();
+ previous_frame_underlay_occlusion_ = gfx::Rect();
+ previous_frame_overlay_rect_union_ = gfx::Rect();
+ previous_frame_processed_overlay_count_ = 0;
+}
+
QuadList::Iterator DCLayerOverlayProcessor::ProcessRenderPassDrawQuad(
RenderPass* render_pass,
gfx::Rect* damage_rect,
@@ -288,7 +333,6 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
const gfx::RectF& display_rect,
RenderPass* render_pass,
bool is_root,
- gfx::Rect* overlay_damage_rect,
gfx::Rect* damage_rect,
DCLayerOverlayList* dc_layer_overlays) {
gfx::Rect this_frame_underlay_rect;
@@ -312,10 +356,11 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
auto uma_protected_video_type = ui::ProtectedVideoType::kClear;
switch (it->material) {
case DrawQuad::YUV_VIDEO_CONTENT:
- result =
- FromYUVQuad(YUVVideoDrawQuad::MaterialCast(*it),
- render_pass->transform_to_root_target,
- has_hw_overlay_support_, resource_provider, &dc_layer);
+ result = FromYUVQuad(YUVVideoDrawQuad::MaterialCast(*it),
+ render_pass->transform_to_root_target,
+ has_hw_overlay_support_,
+ current_frame_processed_overlay_count_,
+ resource_provider, &dc_layer);
uma_protected_video_type =
YUVVideoDrawQuad::MaterialCast(*it)->protected_video_type;
break;
@@ -328,21 +373,40 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
continue;
}
- if (!it->shared_quad_state->quad_to_target_transform
- .Preserves2dAxisAlignment() &&
- !dc_layer.RequiresOverlay() &&
- !base::FeatureList::IsEnabled(
- features::kDirectCompositionComplexOverlays)) {
- RecordDCLayerResult(DC_LAYER_FAILED_COMPLEX_TRANSFORM,
- dc_layer.protected_video_type);
- continue;
+ gfx::Rect quad_rectangle_in_target_space =
+ gfx::ToEnclosingRect(ClippedQuadRectangle(*it));
+ bool has_occluding_surface_damage = false;
+ gfx::RectF occlusion_bounding_box = GetOcclusionBounds(
+ gfx::RectF(quad_rectangle_in_target_space), quad_list->begin(), it,
+ &has_occluding_surface_damage);
+ // Non-root video is always treated as underlay.
+ bool is_overlay = occlusion_bounding_box.IsEmpty() && is_root;
+
+ // Skip quad if it's an underlay and underlays are not allowed
+ if (!is_overlay) {
+ result = IsUnderlayAllowed(it, is_root, dc_layer);
+ if (result != DC_LAYER_SUCCESS) {
+ RecordDCLayerResult(result, uma_protected_video_type);
+ continue;
+ }
}
- // These rects are in quad target space.
- gfx::Rect quad_rectangle = gfx::ToEnclosingRect(ClippedQuadRectangle(*it));
- gfx::RectF occlusion_bounding_box =
- GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
- bool processed_overlay = false;
+ // Quad is always promoted to either an underlay or an overlay after this
+ // point. It should not fail.
+
+ // If the current overlay has changed in size/position from the previous
+ // frame, we have to add the overlay quads from the previous frame to the
+ // damage rect for GL compositor. It's hard to optimize multiple overlays or
+ // an overlay in non-root render pass. So always add the overlay rects back
+ // in these two cases. This is only done once at the first overlay/underlay.
+ if (current_frame_processed_overlay_count_ == 0 && is_root &&
+ !previous_frame_overlay_rect_union_.IsEmpty()) {
+ if (quad_rectangle_in_target_space !=
+ previous_frame_overlay_rect_union_ ||
+ previous_frame_processed_overlay_count_ > 1)
+ damage_rect->Union(previous_frame_overlay_rect_union_);
+ previous_frame_overlay_rect_union_ = gfx::Rect();
+ }
// Underlays are less efficient, so attempt regular overlays first. Only
// check root render pass because we can only check for occlusion within a
@@ -352,36 +416,48 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
// overlays for protected video, but don't calculate damage differently.
// TODO(magchen): Collect all overlay candidates, and filter the list at the
// end to find the best candidates (largest size?).
- if (is_root &&
- (!processed_overlay_in_frame_ || dc_layer.RequiresOverlay()) &&
- ProcessForOverlay(display_rect, quad_list, quad_rectangle,
- occlusion_bounding_box, &it, damage_rect)) {
+ if (is_overlay) {
+ ProcessForOverlay(display_rect, quad_list, quad_rectangle_in_target_space,
+ &it, damage_rect);
// ProcessForOverlay makes the iterator point to the next value on
// success.
next_it = it;
- processed_overlay = true;
- } else if (ProcessForUnderlay(display_rect, render_pass, quad_rectangle,
- occlusion_bounding_box, it, is_root,
- damage_rect, &this_frame_underlay_rect,
- &this_frame_underlay_occlusion, &dc_layer)) {
- processed_overlay = true;
+ } else {
+ ProcessForUnderlay(display_rect, render_pass,
+ quad_rectangle_in_target_space, occlusion_bounding_box,
+ it, is_root, has_occluding_surface_damage, damage_rect,
+ &this_frame_underlay_rect,
+ &this_frame_underlay_occlusion, &dc_layer);
}
- if (processed_overlay) {
- gfx::Rect rect_in_root = cc::MathUtil::MapEnclosingClippedRect(
- render_pass->transform_to_root_target, quad_rectangle);
- overlay_damage_rect->Union(rect_in_root);
+ gfx::Rect rect_in_root = cc::MathUtil::MapEnclosingClippedRect(
+ render_pass->transform_to_root_target, quad_rectangle_in_target_space);
+ current_frame_overlay_rect_union_.Union(rect_in_root);
- RecordDCLayerResult(DC_LAYER_SUCCESS, dc_layer.protected_video_type);
- dc_layer_overlays->push_back(dc_layer);
+ RecordDCLayerResult(DC_LAYER_SUCCESS, dc_layer.protected_video_type);
+ dc_layer_overlays->push_back(dc_layer);
- // Only allow one overlay unless non-root overlays are enabled.
- // TODO(magchen): We want to produce all overlay candidates, and then
- // choose the best one.
- processed_overlay_in_frame_ = true;
- }
+ // Only allow one overlay unless it's hardware protected video.
+ // TODO(magchen): We want to produce all overlay candidates, and then
+ // choose the best one.
+ current_frame_processed_overlay_count_++;
}
+
+ // Update previous frame state after processing root pass
if (is_root) {
+ // If there is no overlay in this frame, previous_frame_overlay_rect_union_
+ // will be added to the damage_rect here for GL composition because the
+ // overlay image from the previous frame is missing in the GL composition
+ // path. If any overlay is found in this frame, the previous overlay rects
+ // would have been handled above and previous_frame_overlay_rect_union_
+ // becomes empty.
+ damage_rect->Union(previous_frame_overlay_rect_union_);
+ previous_frame_overlay_rect_union_ = current_frame_overlay_rect_union_;
+ current_frame_overlay_rect_union_ = gfx::Rect();
+ previous_frame_processed_overlay_count_ =
+ current_frame_processed_overlay_count_;
+ current_frame_processed_overlay_count_ = 0;
+
damage_rect->Intersect(gfx::ToEnclosingRect(display_rect));
previous_display_rect_ = display_rect;
previous_frame_underlay_rect_ = this_frame_underlay_rect;
@@ -389,15 +465,11 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
}
}
-bool DCLayerOverlayProcessor::ProcessForOverlay(
- const gfx::RectF& display_rect,
- QuadList* quad_list,
- const gfx::Rect& quad_rectangle,
- const gfx::RectF& occlusion_bounding_box,
- QuadList::Iterator* it,
- gfx::Rect* damage_rect) {
- if (!occlusion_bounding_box.IsEmpty())
- return false;
+void DCLayerOverlayProcessor::ProcessForOverlay(const gfx::RectF& display_rect,
+ QuadList* quad_list,
+ const gfx::Rect& quad_rectangle,
+ QuadList::Iterator* it,
+ gfx::Rect* damage_rect) {
// The quad is on top, so promote it to an overlay and remove all damage
// underneath it.
bool display_rect_changed = (display_rect != previous_display_rect_);
@@ -408,49 +480,24 @@ bool DCLayerOverlayProcessor::ProcessForOverlay(
damage_rect->Subtract(quad_rectangle);
}
*it = quad_list->EraseAndInvalidateAllPointers(*it);
- return true;
}
-bool DCLayerOverlayProcessor::ProcessForUnderlay(
+void DCLayerOverlayProcessor::ProcessForUnderlay(
const gfx::RectF& display_rect,
RenderPass* render_pass,
const gfx::Rect& quad_rectangle,
const gfx::RectF& occlusion_bounding_box,
const QuadList::Iterator& it,
bool is_root,
+ bool has_occluding_surface_damage,
gfx::Rect* damage_rect,
gfx::Rect* this_frame_underlay_rect,
gfx::Rect* this_frame_underlay_occlusion,
DCLayerOverlay* dc_layer) {
- if (!dc_layer->RequiresOverlay()) {
- if (!base::FeatureList::IsEnabled(features::kDirectCompositionUnderlays)) {
- RecordDCLayerResult(DC_LAYER_FAILED_OCCLUDED,
- dc_layer->protected_video_type);
- return false;
- }
- if (!is_root && !base::FeatureList::IsEnabled(
- features::kDirectCompositionNonrootOverlays)) {
- RecordDCLayerResult(DC_LAYER_FAILED_NON_ROOT,
- dc_layer->protected_video_type);
- return false;
- }
- if (it->shared_quad_state->opacity < 1.0f) {
- RecordDCLayerResult(DC_LAYER_FAILED_TRANSPARENT,
- dc_layer->protected_video_type);
- return false;
- }
- // Record this UMA only after we're absolutely sure this quad could be an
- // underlay.
- if (processed_overlay_in_frame_) {
- RecordDCLayerResult(DC_LAYER_FAILED_TOO_MANY_OVERLAYS,
- dc_layer->protected_video_type);
- return false;
- }
- }
- // TODO(magchen): Assign decreasing z-order so that underlays processed
- // earlier, and hence which are above the subsequent underlays, are placed
- // above in the direct composition visual tree.
- dc_layer->z_order = -1;
+ // Assign decreasing z-order so that underlays processed earlier, and hence
+ // which are above the subsequent underlays, are placed above in the direct
+ // composition visual tree.
+ dc_layer->z_order = -1 - current_frame_processed_overlay_count_;
const SharedQuadState* shared_quad_state = it->shared_quad_state;
gfx::Rect rect = it->visible_rect;
@@ -494,8 +541,9 @@ bool DCLayerOverlayProcessor::ProcessForUnderlay(
bool is_axis_aligned =
shared_quad_state->quad_to_target_transform.Preserves2dAxisAlignment();
- if (is_root && !processed_overlay_in_frame_ && is_axis_aligned && is_opaque &&
- !underlay_rect_changed && !display_rect_changed) {
+ if (is_root && current_frame_processed_overlay_count_ == 0 &&
+ is_axis_aligned && is_opaque && !underlay_rect_changed &&
+ !display_rect_changed) {
// If this underlay rect is the same as for last frame, subtract its area
// from the damage of the main surface, as the cleared area was already
// cleared last frame. Add back the damage from the occluded area for this
@@ -503,13 +551,21 @@ bool DCLayerOverlayProcessor::ProcessForUnderlay(
gfx::Rect occluding_damage_rect = *damage_rect;
damage_rect->Subtract(quad_rectangle);
- gfx::Rect occlusion = gfx::ToEnclosingRect(occlusion_bounding_box);
- occlusion.Union(previous_frame_underlay_occlusion_);
+ // If none of the quads on top give any damage, we can skip compositing
+ // these quads when the incoming damage rect is smaller or equal to the
+ // video quad. After subtraction, the resulting output damage rect for GL
+ // compositor will be empty. If the incoming damage rect is bigger than the
+ // video quad, we don't have an oppertunity for power optimization even if
+ // no damage on top. The output damage rect will not be empty in this case.
+ if (has_occluding_surface_damage) {
+ gfx::Rect occlusion = gfx::ToEnclosingRect(occlusion_bounding_box);
+ occlusion.Union(previous_frame_underlay_occlusion_);
- occluding_damage_rect.Intersect(quad_rectangle);
- occluding_damage_rect.Intersect(occlusion);
+ occluding_damage_rect.Intersect(quad_rectangle);
+ occluding_damage_rect.Intersect(occlusion);
- damage_rect->Union(occluding_damage_rect);
+ damage_rect->Union(occluding_damage_rect);
+ }
} else {
// Entire replacement quad must be redrawn.
// TODO(sunnyps): We should avoid this extra damage if we knew that the
@@ -520,7 +576,8 @@ bool DCLayerOverlayProcessor::ProcessForUnderlay(
// We only compare current frame's first root pass underlay with the previous
// frame's first root pass underlay. Non-opaque regions can have different
// alpha from one frame to another so this optimization doesn't work.
- if (is_root && !processed_overlay_in_frame_ && is_axis_aligned && is_opaque) {
+ if (is_root && current_frame_processed_overlay_count_ == 0 &&
+ is_axis_aligned && is_opaque) {
*this_frame_underlay_rect = quad_rectangle;
*this_frame_underlay_occlusion =
gfx::ToEnclosingRect(occlusion_bounding_box);
@@ -531,8 +588,6 @@ bool DCLayerOverlayProcessor::ProcessForUnderlay(
// RPDQ target (parent render pass) in ProcessRenderPassDrawQuad().
pass_punch_through_rects_[render_pass->id].push_back(
gfx::ToEnclosingRect(ClippedQuadRectangle(*it)));
-
- return true;
}
} // namespace viz
diff --git a/chromium/components/viz/service/display/dc_layer_overlay.h b/chromium/components/viz/service/display/dc_layer_overlay.h
index 3e9bdbdd620..0fe4e8dd0ea 100644
--- a/chromium/components/viz/service/display/dc_layer_overlay.h
+++ b/chromium/components/viz/service/display/dc_layer_overlay.h
@@ -75,14 +75,15 @@ class DCLayerOverlayProcessor {
void Process(DisplayResourceProvider* resource_provider,
const gfx::RectF& display_rect,
RenderPassList* render_passes,
- gfx::Rect* overlay_damage_rect,
gfx::Rect* damage_rect,
DCLayerOverlayList* dc_layer_overlays);
- void ClearOverlayState() {
- previous_frame_underlay_rect_ = gfx::Rect();
- previous_frame_underlay_occlusion_ = gfx::Rect();
- }
+ void ClearOverlayState();
void SetHasHwOverlaySupport() { has_hw_overlay_support_ = true; }
+ // This is the damage contribution due to previous frame's overlays which can
+ // be empty.
+ gfx::Rect previous_frame_overlay_damage_contribution() {
+ return previous_frame_overlay_rect_union_;
+ }
private:
// Returns an iterator to the element after |it|.
@@ -94,21 +95,20 @@ class DCLayerOverlayProcessor {
const gfx::RectF& display_rect,
RenderPass* render_pass,
bool is_root,
- gfx::Rect* overlay_damage_rect,
gfx::Rect* damage_rect,
DCLayerOverlayList* dc_layer_overlays);
- bool ProcessForOverlay(const gfx::RectF& display_rect,
+ void ProcessForOverlay(const gfx::RectF& display_rect,
QuadList* quad_list,
const gfx::Rect& quad_rectangle,
- const gfx::RectF& occlusion_bounding_box,
QuadList::Iterator* it,
gfx::Rect* damage_rect);
- bool ProcessForUnderlay(const gfx::RectF& display_rect,
+ void ProcessForUnderlay(const gfx::RectF& display_rect,
RenderPass* render_pass,
const gfx::Rect& quad_rectangle,
const gfx::RectF& occlusion_bounding_box,
const QuadList::Iterator& it,
bool is_root,
+ bool has_occluding_surface_damage,
gfx::Rect* damage_rect,
gfx::Rect* this_frame_underlay_rect,
gfx::Rect* this_frame_underlay_occlusion,
@@ -117,7 +117,11 @@ class DCLayerOverlayProcessor {
gfx::Rect previous_frame_underlay_rect_;
gfx::Rect previous_frame_underlay_occlusion_;
gfx::RectF previous_display_rect_;
- bool processed_overlay_in_frame_ = false;
+ // previous and current overlay_rect_union_ include both overlay and underlay
+ gfx::Rect previous_frame_overlay_rect_union_;
+ gfx::Rect current_frame_overlay_rect_union_;
+ int previous_frame_processed_overlay_count_ = 0;
+ int current_frame_processed_overlay_count_ = 0;
bool has_hw_overlay_support_ = true;
// Store information about clipped punch-through rects in target space for
diff --git a/chromium/components/viz/service/display/direct_renderer.cc b/chromium/components/viz/service/display/direct_renderer.cc
index 0d4e3e866d4..53ae85d61a6 100644
--- a/chromium/components/viz/service/display/direct_renderer.cc
+++ b/chromium/components/viz/service/display/direct_renderer.cc
@@ -20,6 +20,7 @@
#include "cc/paint/filter_operations.h"
#include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/service/display/bsp_tree.h"
#include "components/viz/service/display/bsp_walk_action.h"
@@ -167,7 +168,6 @@ gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace(
// static
const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly(
const RenderPass* pass,
- bool is_using_vulkan,
DisplayResourceProvider* const resource_provider) {
#if defined(OS_MACOSX)
// On Macs, this path can sometimes lead to all black output.
@@ -200,6 +200,9 @@ const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly(
if (quad->shared_quad_state->opacity != 1.0f)
return nullptr;
+ if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
+ return nullptr;
+
const TileDrawQuad* tile_quad = TileDrawQuad::MaterialCast(quad);
// Hack: this could be supported by passing in a subrectangle to draw
// render pass, although in practice if there is only one quad there
@@ -209,14 +212,12 @@ const TileDrawQuad* DirectRenderer::CanPassBeDrawnDirectly(
// Tile quad features not supported in render pass shaders.
if (tile_quad->swizzle_contents || tile_quad->nearest_neighbor)
return nullptr;
- if (!is_using_vulkan) {
- // BUG=skia:3868, Skia currently doesn't support texture rectangle inputs.
- // See also the DCHECKs about GL_TEXTURE_2D in DrawRenderPassQuad.
- GLenum target =
- resource_provider->GetResourceTextureTarget(tile_quad->resource_id());
- if (target != GL_TEXTURE_2D)
- return nullptr;
- }
+ // BUG=skia:3868, Skia currently doesn't support texture rectangle inputs.
+ // See also the DCHECKs about GL_TEXTURE_2D in DrawRenderPassQuad.
+ GLenum target =
+ resource_provider->GetResourceTextureTarget(tile_quad->resource_id());
+ if (target != GL_TEXTURE_2D)
+ return nullptr;
return tile_quad;
}
@@ -344,6 +345,7 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
gfx::RectF(device_viewport_size.width(), device_viewport_size.height());
output_surface_plane.resource_size_in_pixels = device_viewport_size;
output_surface_plane.format = output_surface_->GetOverlayBufferFormat();
+ output_surface_plane.color_space = reshape_device_color_space_;
output_surface_plane.use_output_surface_for_resource = true;
output_surface_plane.overlay_handled = true;
output_surface_plane.is_opaque = true;
@@ -508,7 +510,7 @@ const cc::FilterOperations* DirectRenderer::BackgroundFiltersForPass(
return it == render_pass_backdrop_filters_.end() ? nullptr : it->second;
}
-const gfx::RectF* DirectRenderer::BackgroundFilterBoundsForPass(
+const gfx::RRectF* DirectRenderer::BackgroundFilterBoundsForPass(
RenderPassId render_pass_id) const {
auto it = render_pass_backdrop_filter_bounds_.find(render_pass_id);
return it == render_pass_backdrop_filter_bounds_.end() ? nullptr : it->second;
@@ -541,8 +543,38 @@ void DirectRenderer::DrawRenderPassAndExecuteCopyRequests(
for (int i = 0; i < settings_->slow_down_compositing_scale_factor; ++i)
DrawRenderPass(render_pass);
- for (auto& copy_request : render_pass->copy_requests)
- CopyDrawnRenderPass(std::move(copy_request));
+ for (auto& request : render_pass->copy_requests) {
+ // Finalize the source subrect (output_rect, result_bounds,
+ // sampling_bounds), as the entirety of the RenderPass's output optionally
+ // clamped to the requested copy area. Then, compute the result rect
+ // (result_selection), which is the selection clamped to the maximum
+ // possible result bounds. If there will be zero pixels of output or the
+ // scaling ratio was not reasonable, do not proceed.
+ gfx::Rect output_rect = render_pass->output_rect;
+ if (request->has_area())
+ output_rect.Intersect(request->area());
+
+ copy_output::RenderPassGeometry geometry;
+ geometry.result_bounds =
+ request->is_scaled() ? copy_output::ComputeResultRect(
+ gfx::Rect(output_rect.size()),
+ request->scale_from(), request->scale_to())
+ : gfx::Rect(output_rect.size());
+
+ geometry.result_selection = geometry.result_bounds;
+ if (request->has_result_selection())
+ geometry.result_selection.Intersect(request->result_selection());
+ if (geometry.result_selection.IsEmpty())
+ continue;
+
+ geometry.sampling_bounds = MoveFromDrawToWindowSpace(output_rect);
+
+ geometry.readback_offset =
+ MoveFromDrawToWindowSpace(geometry.result_selection +
+ output_rect.OffsetFromOrigin())
+ .OffsetFromOrigin();
+ CopyDrawnRenderPass(geometry, std::move(request));
+ }
}
void DirectRenderer::DrawRenderPass(const RenderPass* render_pass) {
@@ -689,10 +721,9 @@ void DirectRenderer::UseRenderPass(const RenderPass* render_pass) {
if (render_pass == current_frame()->root_render_pass) {
BindFramebufferToOutputSurface();
- if (supports_dc_layers_) {
+ if (supports_dc_layers_)
SetEnableDCLayers(using_dc_layers_);
- output_surface_->SetDrawRectangle(current_frame()->root_damage_rect);
- }
+ output_surface_->SetDrawRectangle(current_frame()->root_damage_rect);
InitializeViewport(current_frame(), render_pass->output_rect,
gfx::Rect(current_frame()->device_viewport_size),
current_frame()->device_viewport_size);
diff --git a/chromium/components/viz/service/display/direct_renderer.h b/chromium/components/viz/service/display/direct_renderer.h
index e06752dffd7..eab013a051a 100644
--- a/chromium/components/viz/service/display/direct_renderer.h
+++ b/chromium/components/viz/service/display/direct_renderer.h
@@ -29,7 +29,8 @@ class FilterOperations;
namespace gfx {
class ColorSpace;
-}
+class RRectF;
+} // namespace gfx
namespace viz {
class BspWalkActionDrawPolygon;
@@ -38,6 +39,10 @@ class OutputSurface;
class RendererSettings;
class RenderPass;
+namespace copy_output {
+struct RenderPassGeometry;
+} // namespace copy_output
+
// This is the base class for code shared between the GL and software
// renderer implementations. "Direct" refers to the fact that it does not
// delegate rendering to another compositor (see historical DelegatingRenderer
@@ -107,7 +112,7 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
struct RenderPassRequirements {
gfx::Size size;
- bool mipmap = false;
+ bool generate_mipmap = false;
};
static gfx::RectF QuadVertexRect();
@@ -154,7 +159,7 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
const cc::FilterOperations* FiltersForPass(RenderPassId render_pass_id) const;
const cc::FilterOperations* BackgroundFiltersForPass(
RenderPassId render_pass_id) const;
- const gfx::RectF* BackgroundFilterBoundsForPass(
+ const gfx::RRectF* BackgroundFilterBoundsForPass(
RenderPassId render_pass_id) const;
// Private interface implemented by subclasses for use by DirectRenderer.
@@ -188,7 +193,6 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
// return that quad, otherwise return null.
static const TileDrawQuad* CanPassBeDrawnDirectly(
const RenderPass* pass,
- bool is_using_vulkan,
DisplayResourceProvider* const resource_provider);
virtual const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass);
virtual void FinishDrawingQuadList() {}
@@ -197,6 +201,7 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
virtual void EnsureScissorTestDisabled() = 0;
virtual void DidChangeVisibility() = 0;
virtual void CopyDrawnRenderPass(
+ const copy_output::RenderPassGeometry& geometry,
std::unique_ptr<CopyOutputRequest> request) = 0;
virtual void SetEnableDCLayers(bool enable) = 0;
virtual void GenerateMipmap() = 0;
@@ -235,7 +240,8 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
base::flat_map<RenderPassId, cc::FilterOperations*> render_pass_filters_;
base::flat_map<RenderPassId, cc::FilterOperations*>
render_pass_backdrop_filters_;
- base::flat_map<RenderPassId, gfx::RectF*> render_pass_backdrop_filter_bounds_;
+ base::flat_map<RenderPassId, gfx::RRectF*>
+ render_pass_backdrop_filter_bounds_;
bool visible_ = false;
bool disable_color_checks_for_testing_ = false;
diff --git a/chromium/components/viz/service/display/display.cc b/chromium/components/viz/service/display/display.cc
index d5b094cbf73..99e4be6d8d8 100644
--- a/chromium/components/viz/service/display/display.cc
+++ b/chromium/components/viz/service/display/display.cc
@@ -33,7 +33,6 @@
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/vulkan/buildflags.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -150,7 +149,8 @@ Display::~Display() {
}
void Display::Initialize(DisplayClient* client,
- SurfaceManager* surface_manager) {
+ SurfaceManager* surface_manager,
+ bool enable_shared_images) {
DCHECK(client);
DCHECK(surface_manager);
client_ = client;
@@ -162,7 +162,7 @@ void Display::Initialize(DisplayClient* client,
if (output_surface_->software_device())
output_surface_->software_device()->BindToClient(this);
- InitializeRenderer();
+ InitializeRenderer(enable_shared_images);
// This depends on assumptions that Display::Initialize will happen on the
// same callstack as the ContextProvider being created/initialized or else
@@ -274,40 +274,34 @@ void Display::SetOutputIsSecure(bool secure) {
}
}
-void Display::InitializeRenderer() {
+void Display::InitializeRenderer(bool enable_shared_images) {
auto mode = output_surface_->context_provider() || skia_output_surface_
? DisplayResourceProvider::kGpu
: DisplayResourceProvider::kSoftware;
resource_provider_ = std::make_unique<DisplayResourceProvider>(
- mode, output_surface_->context_provider(), bitmap_manager_);
-
- if (settings_.use_skia_renderer && mode == DisplayResourceProvider::kGpu) {
+ mode, output_surface_->context_provider(), bitmap_manager_,
+ enable_shared_images);
+ const bool use_skia_renderer =
+ settings_.use_skia_renderer || settings_.use_skia_renderer_non_ddl;
+ if (use_skia_renderer && mode == DisplayResourceProvider::kGpu) {
// Default to use DDL if skia_output_surface is not null.
if (skia_output_surface_) {
renderer_ = std::make_unique<SkiaRenderer>(
&settings_, output_surface_.get(), resource_provider_.get(),
skia_output_surface_, SkiaRenderer::DrawMode::DDL);
} else {
- // GPU compositing with GL.
+ // GPU compositing with GL to an SKP.
DCHECK(output_surface_);
DCHECK(output_surface_->context_provider());
- SkiaRenderer::DrawMode mode = settings_.record_sk_picture
- ? SkiaRenderer::DrawMode::SKPRECORD
- : SkiaRenderer::DrawMode::GL;
+ DCHECK(settings_.record_sk_picture);
renderer_ = std::make_unique<SkiaRenderer>(
&settings_, output_surface_.get(), resource_provider_.get(),
- nullptr /* skia_output_surface */, mode);
+ nullptr /* skia_output_surface */, SkiaRenderer::DrawMode::SKPRECORD);
}
} else if (output_surface_->context_provider()) {
renderer_ = std::make_unique<GLRenderer>(&settings_, output_surface_.get(),
resource_provider_.get(),
current_task_runner_);
-#if BUILDFLAG(ENABLE_VULKAN)
- } else if (output_surface_->vulkan_context_provider()) {
- renderer_ = std::make_unique<SkiaRenderer>(
- &settings_, output_surface_.get(), resource_provider_.get(),
- nullptr /* skia_output_surface */, SkiaRenderer::DrawMode::VULKAN);
-#endif
} else {
auto renderer = std::make_unique<SoftwareRenderer>(
&settings_, output_surface_.get(), resource_provider_.get());
@@ -427,13 +421,11 @@ bool Display::DrawAndSwap() {
TRACE_EVENT_ASYNC_STEP_INTO0("viz,benchmark",
"Graphics.Pipeline.DrawAndSwap",
swapped_trace_id_, "Draw");
- if (settings_.enable_draw_occlusion) {
- base::ElapsedTimer draw_occlusion_timer;
- RemoveOverdrawQuads(&frame);
- UMA_HISTOGRAM_COUNTS_1000(
- "Compositing.Display.Draw.Occlusion.Calculation.Time",
- draw_occlusion_timer.Elapsed().InMicroseconds());
- }
+ base::ElapsedTimer draw_occlusion_timer;
+ RemoveOverdrawQuads(&frame);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "Compositing.Display.Draw.Occlusion.Calculation.Time",
+ draw_occlusion_timer.Elapsed().InMicroseconds());
bool disable_image_filtering =
frame.metadata.is_resourceless_software_draw_with_scroll_or_animation;
@@ -564,7 +556,10 @@ void Display::DidSwapWithSize(const gfx::Size& pixel_size) {
void Display::DidReceivePresentationFeedback(
const gfx::PresentationFeedback& feedback) {
- DCHECK(!pending_presented_callbacks_.empty());
+ if (pending_presented_callbacks_.empty()) {
+ DLOG(ERROR) << "Received unexpected PresentationFeedback";
+ return;
+ }
++last_presented_trace_id_;
TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
"viz,benchmark", "Graphics.Pipeline.DrawAndSwap",
diff --git a/chromium/components/viz/service/display/display.h b/chromium/components/viz/service/display/display.h
index f5d58f611d7..bed83dd20e2 100644
--- a/chromium/components/viz/service/display/display.h
+++ b/chromium/components/viz/service/display/display.h
@@ -76,7 +76,11 @@ class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
~Display() override;
- void Initialize(DisplayClient* client, SurfaceManager* surface_manager);
+ // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary
+ // solution that unblocks us until SharedImages are threadsafe in WebView.
+ void Initialize(DisplayClient* client,
+ SurfaceManager* surface_manager,
+ bool enable_shared_images = true);
void AddObserver(DisplayObserver* observer);
void RemoveObserver(DisplayObserver* observer);
@@ -134,7 +138,9 @@ class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
void RemoveOverdrawQuads(CompositorFrame* frame);
private:
- void InitializeRenderer();
+ // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary
+ // solution that unblocks us until SharedImages are threadsafe in WebView.
+ void InitializeRenderer(bool enable_shared_images = true);
void UpdateRootFrameMissing();
void RunDrawCallbacks();
diff --git a/chromium/components/viz/service/display/display_perftest.cc b/chromium/components/viz/service/display/display_perftest.cc
index dc09344a333..d6f91b74fd9 100644
--- a/chromium/components/viz/service/display/display_perftest.cc
+++ b/chromium/components/viz/service/display/display_perftest.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/test/null_task_runner.h"
#include "base/time/time.h"
-#include "cc/base/lap_timer.h"
+#include "base/timer/lap_timer.h"
#include "components/viz/common/display/renderer_settings.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/draw_quad.h"
@@ -290,7 +290,7 @@ class RemoveOverdrawQuadPerfTest : public testing::Test {
private:
CompositorFrame frame_;
- cc::LapTimer timer_;
+ base::LapTimer timer_;
StubBeginFrameSource begin_frame_source_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
ServerSharedBitmapManager bitmap_manager_;
diff --git a/chromium/components/viz/service/display/display_resource_provider.cc b/chromium/components/viz/service/display/display_resource_provider.cc
index 691e2903800..9d45b467781 100644
--- a/chromium/components/viz/service/display/display_resource_provider.cc
+++ b/chromium/components/viz/service/display/display_resource_provider.cc
@@ -15,6 +15,7 @@
#include "components/viz/common/resources/resource_sizes.h"
#include "components/viz/service/display/shared_bitmap_manager.h"
#include "components/viz/service/display/skia_output_surface.h"
+#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
@@ -59,11 +60,13 @@ class ScopedSetActiveTexture {
DisplayResourceProvider::DisplayResourceProvider(
Mode mode,
ContextProvider* compositor_context_provider,
- SharedBitmapManager* shared_bitmap_manager)
+ SharedBitmapManager* shared_bitmap_manager,
+ bool enable_shared_images)
: mode_(mode),
compositor_context_provider_(compositor_context_provider),
shared_bitmap_manager_(shared_bitmap_manager),
- tracing_id_(g_next_display_resource_provider_tracing_id.GetNext()) {
+ tracing_id_(g_next_display_resource_provider_tracing_id.GetNext()),
+ enable_shared_images_(enable_shared_images) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// If no ContextProvider, then we are doing software compositing and a
// SharedBitmapManager must be given.
@@ -254,6 +257,11 @@ gfx::BufferFormat DisplayResourceProvider::GetBufferFormat(ResourceId id) {
return BufferFormat(resource->transferable.format);
}
+const gfx::ColorSpace& DisplayResourceProvider::GetColorSpace(ResourceId id) {
+ ChildResource* resource = GetResource(id);
+ return resource->transferable.color_space;
+}
+
void DisplayResourceProvider::WaitSyncToken(ResourceId id) {
ChildResource* resource = TryGetResource(id);
// TODO(ericrk): We should never fail TryGetResource, but we appear to
@@ -460,17 +468,28 @@ DisplayResourceProvider::LockForRead(ResourceId id) {
// calling LockForRead().
DCHECK_NE(NEEDS_WAIT, resource->synchronization_state());
- if (resource->is_gpu_resource_type() && !resource->gl_id) {
+ const gpu::Mailbox& mailbox = resource->transferable.mailbox_holder.mailbox;
+ if (resource->is_gpu_resource_type()) {
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- resource->gl_id = gl->CreateAndConsumeTextureCHROMIUM(
- resource->transferable.mailbox_holder.mailbox.name);
- resource->SetLocallyUsed();
+ if (!resource->gl_id) {
+ if (mailbox.IsSharedImage() && enable_shared_images_) {
+ resource->gl_id =
+ gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name);
+ } else {
+ resource->gl_id = gl->CreateAndConsumeTextureCHROMIUM(
+ resource->transferable.mailbox_holder.mailbox.name);
+ }
+ resource->SetLocallyUsed();
+ }
+ if (mailbox.IsSharedImage() && enable_shared_images_) {
+ gl->BeginSharedImageAccessDirectCHROMIUM(
+ resource->gl_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
+ }
}
if (!resource->shared_bitmap && !resource->is_gpu_resource_type()) {
- const SharedBitmapId& shared_bitmap_id =
- resource->transferable.mailbox_holder.mailbox;
+ const SharedBitmapId& shared_bitmap_id = mailbox;
std::unique_ptr<SharedBitmap> bitmap =
shared_bitmap_manager_->GetSharedBitmapFromId(
resource->transferable.size, resource->transferable.format,
@@ -504,6 +523,13 @@ void DisplayResourceProvider::UnlockForRead(ResourceId id) {
ChildResource* resource = &it->second;
DCHECK_GT(resource->lock_for_read_count, 0);
+ if (resource->transferable.mailbox_holder.mailbox.IsSharedImage() &&
+ resource->is_gpu_resource_type() && enable_shared_images_) {
+ DCHECK(resource->gl_id);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ gl->EndSharedImageAccessDirectCHROMIUM(resource->gl_id);
+ }
resource->lock_for_read_count--;
TryReleaseResource(it);
}
@@ -525,6 +551,7 @@ ResourceMetadata DisplayResourceProvider::LockForExternalUse(ResourceId id) {
metadata.size = resource->transferable.size;
metadata.resource_format = resource->transferable.format;
metadata.mailbox_holder.sync_token = resource->sync_token();
+ metadata.color_space = resource->transferable.color_space;
resource->locked_for_external_use = true;
return metadata;
@@ -634,29 +661,32 @@ void DisplayResourceProvider::DeleteAndReturnUnusedResourcesToChild(
}
std::vector<ReturnedResource> to_return;
+ // Reserve enough space to avoid re-allocating, so we can keep item pointers
+ // for later using.
to_return.reserve(unused.size());
std::vector<ReturnedResource*> need_synchronization_resources;
std::vector<GLbyte*> unverified_sync_tokens;
- std::vector<size_t> to_return_indices_unverified;
+ std::vector<sk_sp<SkImage>> external_used_sk_images;
+ std::vector<ReturnedResource*> external_used_resources;
+ if (external_use_client_) {
+ external_used_sk_images.reserve(unused.size());
+ external_used_resources.reserve(unused.size());
+ }
GLES2Interface* gl = ContextGL();
-
for (ResourceId local_id : unused) {
auto it = resources_.find(local_id);
CHECK(it != resources_.end());
ChildResource& resource = it->second;
- // TODO(https://crbug.com/922592): Batch deletion for reduced overhead.
+ bool is_external_used_resource = false;
auto sk_image_it = resource_sk_images_.find(local_id);
if (sk_image_it != resource_sk_images_.end()) {
- sk_sp<SkImage> found(std::move(sk_image_it->second));
- resource_sk_images_.erase(sk_image_it);
-
if (external_use_client_) {
- gpu::SyncToken token =
- external_use_client_->QueueReleasePromiseSkImage(std::move(found));
- resource.UpdateSyncToken(token);
+ external_used_sk_images.push_back(std::move(sk_image_it->second));
+ is_external_used_resource = true;
}
+ resource_sk_images_.erase(sk_image_it);
}
ResourceId child_id = resource.transferable.id;
@@ -697,23 +727,20 @@ void DisplayResourceProvider::DeleteAndReturnUnusedResourcesToChild(
resource.SetLocallyUsed();
}
- ReturnedResource returned;
- returned.id = child_id;
- returned.sync_token = resource.sync_token();
- returned.count = resource.imported_count;
- returned.lost = is_lost;
- to_return.push_back(returned);
+ to_return.emplace_back(child_id, resource.sync_token(),
+ resource.imported_count, is_lost);
+ auto& returned = to_return.back();
if (resource.is_gpu_resource_type() && child_info->needs_sync_tokens) {
if (resource.needs_sync_token()) {
- need_synchronization_resources.push_back(&to_return.back());
+ need_synchronization_resources.push_back(&returned);
} else if (returned.sync_token.HasData() &&
!returned.sync_token.verified_flush()) {
- // Before returning any sync tokens, they must be verified. Store an
- // index into |to_return| instead of a pointer as vectors may realloc
- // and move their data.
- to_return_indices_unverified.push_back(to_return.size() - 1);
+ unverified_sync_tokens.push_back(returned.sync_token.GetData());
}
+
+ if (is_external_used_resource)
+ external_used_resources.push_back(&returned);
}
child_info->child_to_parent_map.erase(child_id);
@@ -724,12 +751,6 @@ void DisplayResourceProvider::DeleteAndReturnUnusedResourcesToChild(
DeleteResourceInternal(it, style);
}
- if (external_use_client_)
- external_use_client_->FlushQueuedReleases();
-
- for (size_t i : to_return_indices_unverified)
- unverified_sync_tokens.push_back(to_return[i].sync_token.GetData());
-
gpu::SyncToken new_sync_token;
if (!need_synchronization_resources.empty()) {
DCHECK(child_info->needs_sync_tokens);
@@ -749,6 +770,13 @@ void DisplayResourceProvider::DeleteAndReturnUnusedResourcesToChild(
for (ReturnedResource* returned : need_synchronization_resources)
returned->sync_token = new_sync_token;
+ if (external_use_client_ && !external_used_sk_images.empty()) {
+ auto sync_token = external_use_client_->ReleasePromiseSkImages(
+ std::move(external_used_sk_images));
+ for (auto* to_return : external_used_resources)
+ to_return->sync_token = sync_token;
+ }
+
if (!to_return.empty())
child_info->return_callback.Run(to_return);
@@ -850,7 +878,8 @@ DisplayResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() = default;
DisplayResourceProvider::ScopedReadLockSkImage::ScopedReadLockSkImage(
DisplayResourceProvider* resource_provider,
- ResourceId resource_id)
+ ResourceId resource_id,
+ SkAlphaType alpha_type)
: resource_provider_(resource_provider), resource_id_(resource_id) {
const ChildResource* resource = resource_provider->LockForRead(resource_id);
DCHECK(resource);
@@ -876,8 +905,7 @@ DisplayResourceProvider::ScopedReadLockSkImage::ScopedReadLockSkImage(
backend_texture, kTopLeft_GrSurfaceOrigin,
ResourceFormatToClosestSkColorType(!resource_provider->IsSoftware(),
resource->transferable.format),
- kPremul_SkAlphaType, nullptr);
- resource_provider_->resource_sk_images_[resource_id] = sk_image_;
+ alpha_type, resource->transferable.color_space.ToSkColorSpace());
return;
}
@@ -925,8 +953,10 @@ ResourceMetadata DisplayResourceProvider::LockSetForExternalUse::LockResource(
sk_sp<SkImage>
DisplayResourceProvider::LockSetForExternalUse::LockResourceAndCreateSkImage(
- ResourceId id) {
+ ResourceId id,
+ SkAlphaType alpha_type) {
auto metadata = LockResource(id);
+ metadata.alpha_type = alpha_type;
auto& resource_sk_image = resource_provider_->resource_sk_images_[id];
if (!resource_sk_image) {
resource_sk_image =
diff --git a/chromium/components/viz/service/display/display_resource_provider.h b/chromium/components/viz/service/display/display_resource_provider.h
index 310e0660165..20a4f37da7a 100644
--- a/chromium/components/viz/service/display/display_resource_provider.h
+++ b/chromium/components/viz/service/display/display_resource_provider.h
@@ -64,9 +64,12 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
kGpu,
kSoftware,
};
+ // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary
+ // solution that unblocks us until SharedImages are threadsafe in WebView.
DisplayResourceProvider(Mode mode,
ContextProvider* compositor_context_provider,
- SharedBitmapManager* shared_bitmap_manager);
+ SharedBitmapManager* shared_bitmap_manager,
+ bool enable_shared_images = true);
~DisplayResourceProvider() override;
bool IsSoftware() const { return mode_ == kSoftware; }
@@ -109,6 +112,7 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
GLenum GetResourceTextureTarget(ResourceId id);
// Return the format of the underlying buffer that can be used for scanout.
gfx::BufferFormat GetBufferFormat(ResourceId id);
+ const gfx::ColorSpace& GetColorSpace(ResourceId id);
// Indicates if this resource may be used for a hardware overlay plane.
bool IsOverlayCandidate(ResourceId id);
@@ -171,7 +175,8 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
class VIZ_SERVICE_EXPORT ScopedReadLockSkImage {
public:
ScopedReadLockSkImage(DisplayResourceProvider* resource_provider,
- ResourceId resource_id);
+ ResourceId resource_id,
+ SkAlphaType alpha_type = kPremul_SkAlphaType);
~ScopedReadLockSkImage();
const SkImage* sk_image() const { return sk_image_.get(); }
@@ -201,7 +206,8 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
// Lock a resource and create a SkImage from it by using
// Client::CreateImage.
- sk_sp<SkImage> LockResourceAndCreateSkImage(ResourceId resource_id);
+ sk_sp<SkImage> LockResourceAndCreateSkImage(ResourceId resource_id,
+ SkAlphaType alpha_type);
// Unlock all locked resources with a |sync_token|.
// See UnlockForExternalUse for the detail. All resources must be unlocked
@@ -504,6 +510,8 @@ class VIZ_SERVICE_EXPORT DisplayResourceProvider
ResourceIdSet wants_promotion_hints_set_;
#endif
+ bool enable_shared_images_;
+
DISALLOW_COPY_AND_ASSIGN(DisplayResourceProvider);
};
diff --git a/chromium/components/viz/service/display/display_resource_provider_unittest.cc b/chromium/components/viz/service/display/display_resource_provider_unittest.cc
index 9cd37ea5ce6..52c6bb91d97 100644
--- a/chromium/components/viz/service/display/display_resource_provider_unittest.cc
+++ b/chromium/components/viz/service/display/display_resource_provider_unittest.cc
@@ -442,9 +442,9 @@ class DisplayResourceProviderTest : public testing::TestWithParam<bool> {
std::unique_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
};
-INSTANTIATE_TEST_CASE_P(DisplayResourceProviderTests,
- DisplayResourceProviderTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(DisplayResourceProviderTests,
+ DisplayResourceProviderTest,
+ ::testing::Values(false, true));
TEST_P(DisplayResourceProviderTest, LockForExternalUse) {
// TODO(penghuang): consider supporting SW mode.
@@ -465,8 +465,9 @@ TEST_P(DisplayResourceProviderTest, LockForExternalUse) {
// Transfer some resources to the parent.
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id1}, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {id1}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(1u, list.size());
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
@@ -519,7 +520,8 @@ TEST_P(DisplayResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
// Transfer some resources to the parent.
std::vector<TransferableResource> list;
child_resource_provider_->PrepareSendToParent(
- {id1}, &list, child_context_provider_.get());
+ {id1}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(1u, list.size());
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
@@ -583,8 +585,9 @@ TEST_P(DisplayResourceProviderTest, ReadLockFenceStopsReturnToChildOrDelete) {
// Transfer some resources to the parent.
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id1}, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {id1}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(1u, list.size());
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
EXPECT_TRUE(list[0].read_lock_fences_enabled);
@@ -642,8 +645,9 @@ TEST_P(DisplayResourceProviderTest, ReadLockFenceDestroyChild) {
// Transfer resources to the parent.
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id1, id2}, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {id1, id2}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(2u, list.size());
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
@@ -703,8 +707,9 @@ TEST_P(DisplayResourceProviderTest, ReadLockFenceContextLost) {
// Transfer resources to the parent.
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id1, id2}, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {id1, id2}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(2u, list.size());
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
@@ -770,7 +775,8 @@ TEST_P(DisplayResourceProviderTest, ReturnResourcesWithoutSyncToken) {
// Transfer some resources to the parent.
std::vector<TransferableResource> list;
no_token_resource_provider->PrepareSendToParent(
- {id}, &list, child_context_provider_.get());
+ {id}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(1u, list.size());
// A given sync point should be passed through.
EXPECT_EQ(external_sync_token, list[0].mailbox_holder.sync_token);
@@ -832,8 +838,9 @@ TEST_P(DisplayResourceProviderTest, ScopedBatchReturnResourcesPreventsReturn) {
std::vector<ResourceId> resource_ids_to_transfer(ids, ids + kTotalResources);
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ resource_ids_to_transfer, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(kTotalResources, list.size());
for (const auto& id : ids)
EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
@@ -951,8 +958,9 @@ TEST_P(DisplayResourceProviderTest, ReadSoftwareResources) {
std::vector<ReturnedResource> returned_to_child;
int child_id = resource_provider_->CreateChild(
base::BindRepeating(&CollectResources, &returned_to_child), true);
- child_resource_provider_->PrepareSendToParent({resource_id}, &send_to_parent,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {resource_id}, &send_to_parent,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
resource_provider_->ReceiveFromChild(child_id, send_to_parent);
// In DisplayResourceProvider's namespace, use the mapped resource id.
@@ -1070,8 +1078,9 @@ class ResourceProviderTestImportedResourceGLFilters {
std::vector<ReturnedResource> returned_to_child;
int child_id = resource_provider->CreateChild(
base::BindRepeating(&CollectResources, &returned_to_child), true);
- child_resource_provider->PrepareSendToParent({resource_id}, &send_to_parent,
- child_context_provider.get());
+ child_resource_provider->PrepareSendToParent(
+ {resource_id}, &send_to_parent,
+ static_cast<RasterContextProvider*>(child_context_provider.get()));
resource_provider->ReceiveFromChild(child_id, send_to_parent);
// In DisplayResourceProvider's namespace, use the mapped resource id.
@@ -1223,8 +1232,9 @@ TEST_P(DisplayResourceProviderTest, ReceiveGLTextureExternalOES) {
std::vector<ReturnedResource> returned_to_child;
int child_id = resource_provider->CreateChild(
base::BindRepeating(&CollectResources, &returned_to_child), true);
- child_resource_provider->PrepareSendToParent({resource_id}, &send_to_parent,
- child_context_provider_.get());
+ child_resource_provider->PrepareSendToParent(
+ {resource_id}, &send_to_parent,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
resource_provider->ReceiveFromChild(child_id, send_to_parent);
// Before create DrawQuad in DisplayResourceProvider's namespace, get the
@@ -1357,8 +1367,9 @@ TEST_P(DisplayResourceProviderTest, OverlayPromotionHint) {
// Transfer some resources to the parent.
std::vector<TransferableResource> list;
- child_resource_provider_->PrepareSendToParent({id1, id2}, &list,
- child_context_provider_.get());
+ child_resource_provider_->PrepareSendToParent(
+ {id1, id2}, &list,
+ static_cast<RasterContextProvider*>(child_context_provider_.get()));
ASSERT_EQ(2u, list.size());
resource_provider_->ReceiveFromChild(child_id, list);
std::unordered_map<ResourceId, ResourceId> resource_map =
diff --git a/chromium/components/viz/service/display/display_scheduler.cc b/chromium/components/viz/service/display/display_scheduler.cc
index aa7f3ddc740..351a025fca4 100644
--- a/chromium/components/viz/service/display/display_scheduler.cc
+++ b/chromium/components/viz/service/display/display_scheduler.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
diff --git a/chromium/components/viz/service/display/display_unittest.cc b/chromium/components/viz/service/display/display_unittest.cc
index 580c22583eb..ef392f0dd57 100644
--- a/chromium/components/viz/service/display/display_unittest.cc
+++ b/chromium/components/viz/service/display/display_unittest.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/null_task_runner.h"
@@ -101,7 +102,7 @@ class StubDisplayClient : public DisplayClient {
RenderPassList* render_passes) override {}
void DisplayDidDrawAndSwap() override {}
void DisplayDidReceiveCALayerParams(
- const gfx::CALayerParams& ca_layer_params) override{};
+ const gfx::CALayerParams& ca_layer_params) override {}
void DisplayDidCompleteSwapWithSize(const gfx::Size& pixel_size) override {}
void DidSwapAfterSnapshotRequestReceived(
const std::vector<ui::LatencyInfo>& latency_info) override {}
@@ -3387,6 +3388,19 @@ TEST_F(DisplayTest, BeginFrameThrottling) {
1.f);
support_->SetNeedsBeginFrame(true);
+ // Helper fn to submit a CF.
+ auto submit_frame = [this](RenderPassList* pass_list) {
+ auto pass = RenderPass::Create();
+ pass->output_rect = gfx::Rect(0, 0, 100, 100);
+ pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+ pass->id = 1u;
+ pass_list->push_back(std::move(pass));
+
+ SubmitCompositorFrame(
+ pass_list,
+ id_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ };
+
// BeginFrame should not be throttled when the client has not submitted any
// compositor frames.
base::TimeTicks frame_time = base::TimeTicks::Now();
@@ -3396,15 +3410,7 @@ TEST_F(DisplayTest, BeginFrameThrottling) {
// Submit the first frame for the client. Begin-frame should still not be
// throttled since it has not been embedded yet.
RenderPassList pass_list;
- auto pass = RenderPass::Create();
- pass->output_rect = gfx::Rect(0, 0, 100, 100);
- pass->damage_rect = gfx::Rect(10, 10, 1, 1);
- pass->id = 1u;
- pass_list.push_back(std::move(pass));
-
- SubmitCompositorFrame(
- &pass_list,
- id_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ submit_frame(&pass_list);
frame_time = base::TimeTicks::Now();
EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
UpdateBeginFrameTime(support_.get(), frame_time);
@@ -3414,17 +3420,17 @@ TEST_F(DisplayTest, BeginFrameThrottling) {
EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
UpdateBeginFrameTime(support_.get(), frame_time);
- // Submit a second frame. This time, begin-frame should be throttled after the
- // first begin-frame is sent because of presentation-feedbacks, until the next
- // draw happens.
- pass = RenderPass::Create();
- pass->output_rect = gfx::Rect(0, 0, 100, 100);
- pass->damage_rect = gfx::Rect(10, 10, 1, 1);
- pass->id = 1u;
- pass_list.push_back(std::move(pass));
- SubmitCompositorFrame(
- &pass_list,
- id_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ // Submit a second frame. This frame should not be throttled, even after
+ // presentation-feedbacks, as we allow up to two undrawn frames.
+ submit_frame(&pass_list);
+ frame_time = base::TimeTicks::Now();
+ EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
+ UpdateBeginFrameTime(support_.get(), frame_time);
+ EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
+
+ // Submit a third frame. This frame should be throttled after
+ // presentation-feedbacks, as we throttle at two undrawn frames.
+ submit_frame(&pass_list);
frame_time = base::TimeTicks::Now();
EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
UpdateBeginFrameTime(support_.get(), frame_time);
@@ -3436,16 +3442,13 @@ TEST_F(DisplayTest, BeginFrameThrottling) {
EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
UpdateBeginFrameTime(support_.get(), frame_time);
- // Submit a third frame. Again, begin-frame should be throttled after the
+ // Submit two more frames. Begin-frame should be throttled after the
// begin-frame for presenatation-feedback.
- pass = RenderPass::Create();
- pass->output_rect = gfx::Rect(0, 0, 100, 100);
- pass->damage_rect = gfx::Rect(10, 10, 1, 1);
- pass->id = 1u;
- pass_list.push_back(std::move(pass));
- SubmitCompositorFrame(
- &pass_list,
- id_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ submit_frame(&pass_list);
+ frame_time = base::TimeTicks::Now();
+ EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
+ UpdateBeginFrameTime(support_.get(), frame_time);
+ submit_frame(&pass_list);
frame_time = base::TimeTicks::Now();
EXPECT_TRUE(ShouldSendBeginFrame(support_.get(), frame_time));
UpdateBeginFrameTime(support_.get(), frame_time);
diff --git a/chromium/components/viz/service/display/gl_renderer.cc b/chromium/components/viz/service/display/gl_renderer.cc
index 6ee04d0919d..9e0979a93d6 100644
--- a/chromium/components/viz/service/display/gl_renderer.cc
+++ b/chromium/components/viz/service/display/gl_renderer.cc
@@ -74,6 +74,7 @@
#include "ui/gfx/geometry/quad_f.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/rrect_f.h"
#include "ui/gfx/skia_util.h"
using gpu::gles2::GLES2Interface;
@@ -212,7 +213,7 @@ struct GLRenderer::DrawRenderPassDrawQuadParams {
gfx::Transform quad_to_target_transform;
const cc::FilterOperations* filters = nullptr;
const cc::FilterOperations* backdrop_filters = nullptr;
- const gfx::RectF* backdrop_filter_bounds = nullptr;
+ const gfx::RRectF* backdrop_filter_bounds = nullptr;
// Whether the texture to be sampled from needs to be flipped.
bool source_needs_flip = false;
@@ -315,10 +316,7 @@ GLRenderer::GLRenderer(
gl_(output_surface->context_provider()->ContextGL()),
context_support_(output_surface->context_provider()->ContextSupport()),
texture_deleter_(current_task_runner),
- copier_(output_surface->context_provider(),
- &texture_deleter_,
- base::BindRepeating(&GLRenderer::MoveFromDrawToWindowSpace,
- base::Unretained(this))),
+ copier_(output_surface->context_provider(), &texture_deleter_),
sync_queries_(gl_),
bound_geometry_(NO_BINDING),
color_lut_cache_(gl_,
@@ -514,6 +512,14 @@ void GLRenderer::DoDrawQuad(const DrawQuad* quad,
case DrawQuad::YUV_VIDEO_CONTENT:
DrawYUVVideoQuad(YUVVideoDrawQuad::MaterialCast(quad), clip_region);
break;
+ case DrawQuad::VIDEO_HOLE:
+ // VideoHoleDrawQuad should only be used by Cast, and should
+ // have been replaced by cast-specific OverlayProcessor before
+ // reach here. In non-cast build, an untrusted render could send such
+ // Quad and the quad would then reach here unexpectedly. Therefore
+ // we should skip NOTREACHED() so an untrusted render is not capable
+ // of causing a crash.
+ break;
}
}
@@ -715,10 +721,12 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
const cc::FilterOperations* filters,
const cc::FilterOperations* backdrop_filters,
const gfx::QuadF* clip_region,
- const gfx::RectF* backdrop_filter_bounds_input,
+ const gfx::RRectF* backdrop_filter_bounds_input,
bool use_aa,
- gfx::Rect* backdrop_filter_bounds,
+ gfx::RRectF* backdrop_filter_bounds,
gfx::Rect* unclipped_rect) {
+ DCHECK(backdrop_filter_bounds);
+ DCHECK(unclipped_rect);
gfx::QuadF scaled_region;
if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) {
scaled_region = SharedGeometryQuad().BoundingBox();
@@ -732,10 +740,9 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
// was not found. For example, some GLRenderer tests can trigger this case,
// e.g. GLRendererShaderTest.DrawRenderPassQuadShaderPermutations.
if (backdrop_filter_bounds_input) {
- *backdrop_filter_bounds =
- gfx::ToEnclosingRect(*backdrop_filter_bounds_input);
+ *backdrop_filter_bounds = *backdrop_filter_bounds_input;
} else {
- *backdrop_filter_bounds = gfx::Rect();
+ *backdrop_filter_bounds = gfx::RRectF();
}
if (ShouldApplyBackgroundFilters(quad, backdrop_filters)) {
@@ -833,7 +840,7 @@ sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters(
const gfx::Rect& rect,
const gfx::Rect& unclipped_rect,
const float backdrop_filter_quality,
- const gfx::Rect& backdrop_filter_bounds) {
+ const gfx::RRectF& backdrop_filter_bounds) {
DCHECK(ShouldApplyBackgroundFilters(quad, backdrop_filters));
auto use_gr_context = ScopedUseGrContext::Create(this);
@@ -915,13 +922,12 @@ sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters(
quad->filters_origin, true);
if (!backdrop_filter_bounds.IsEmpty()) {
- // Clip the filtered image to the bounding box of the element.
+ // Clip the filtered image to the (rounded) bounding box of the element.
surface->getCanvas()->save();
- gfx::RectF clip_rect_scaled = gfx::RectF(backdrop_filter_bounds);
- clip_rect_scaled.Scale(backdrop_filter_quality);
- SkRRect clip_rect =
- SkRRect::MakeRectXY(RectFToSkRect(clip_rect_scaled), 0, 0);
- surface->getCanvas()->clipRRect(clip_rect, SkClipOp::kIntersect,
+ gfx::RRectF clip_rect(backdrop_filter_bounds);
+ DCHECK(backdrop_filter_quality);
+ clip_rect.Scale(backdrop_filter_quality);
+ surface->getCanvas()->clipRRect(SkRRect(clip_rect), SkClipOp::kIntersect,
true /* antialias */);
}
@@ -947,8 +953,7 @@ sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters(
}
const TileDrawQuad* GLRenderer::CanPassBeDrawnDirectly(const RenderPass* pass) {
- return DirectRenderer::CanPassBeDrawnDirectly(pass, false,
- resource_provider_);
+ return DirectRenderer::CanPassBeDrawnDirectly(pass, resource_provider_);
}
void GLRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
@@ -1091,7 +1096,7 @@ void GLRenderer::UpdateRPDQShadersForBlending(
if (params->use_shaders_for_blending) {
// Compute a bounding box around the pixels that will be visible through
// the quad.
- gfx::Rect backdrop_filter_bounds_rect;
+ gfx::RRectF backdrop_filter_bounds_rect;
gfx::Rect unclipped_rect;
params->background_rect = GetBackdropBoundingBoxForRenderPassQuad(
quad, params->contents_device_transform, params->filters,
@@ -1748,13 +1753,16 @@ void GLRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
SkColor color = quad->color;
float opacity = quad->shared_quad_state->opacity;
- float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
- // Early out if alpha is small enough that quad doesn't contribute to output.
- if (alpha < std::numeric_limits<float>::epsilon() &&
- quad->ShouldDrawWithBlending() &&
- quad->shared_quad_state->blend_mode == SkBlendMode::kSrcOver)
- return;
+ // Early out if alpha is small enough that quad doesn't contribute to output,
+ // for kSrcOver blend mode.
+ if (quad->shared_quad_state->blend_mode == SkBlendMode::kSrcOver) {
+ float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
+ if (alpha < std::numeric_limits<float>::epsilon() &&
+ quad->ShouldDrawWithBlending() &&
+ quad->shared_quad_state->blend_mode == SkBlendMode::kSrcOver)
+ return;
+ }
gfx::Transform device_transform =
current_frame()->window_matrix * current_frame()->projection_matrix *
@@ -1961,9 +1969,12 @@ void GLRenderer::DrawContentQuadAA(const ContentDrawQuadBase* quad,
// Blending is required for antialiasing.
SetBlendEnabled(true);
SetShaderOpacity(quad->shared_quad_state->opacity);
+ DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode));
+ ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode);
// Draw the quad with antialiasing.
DrawQuadGeometryWithAA(quad, &local_quad, tile_rect);
+ RestoreBlendFuncToDefault(quad->shared_quad_state->blend_mode);
}
void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
@@ -2046,7 +2057,9 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
tex_coord_rect.x(), tex_coord_rect.y(), tex_coord_rect.width(),
tex_coord_rect.height());
+ DCHECK(CanApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode));
SetBlendEnabled(quad->ShouldDrawWithBlending());
+ ApplyBlendModeUsingBlendFunc(quad->shared_quad_state->blend_mode);
SetShaderOpacity(quad->shared_quad_state->opacity);
@@ -2088,6 +2101,7 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
num_triangles_drawn_ += 2;
+ RestoreBlendFuncToDefault(quad->shared_quad_state->blend_mode);
}
void GLRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
@@ -2280,14 +2294,19 @@ void GLRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id());
static float gl_matrix[16];
- ToGLMatrix(&gl_matrix[0], quad->matrix);
+ gfx::Transform matrix;
+ matrix.Scale(quad->uv_bottom_right.x() - quad->uv_top_left.x(),
+ quad->uv_bottom_right.y() - quad->uv_top_left.y());
+ matrix.Translate(quad->uv_top_left.x(), quad->uv_top_left.y());
+ ToGLMatrix(&gl_matrix[0], matrix);
gl_->UniformMatrix4fvStreamTextureMatrixCHROMIUM(
current_program_->tex_matrix_location(), false, gl_matrix);
SetShaderOpacity(quad->shared_quad_state->opacity);
gfx::Size texture_size = lock.size();
- gfx::Vector2dF uv = quad->matrix.Scale2d();
- gfx::RectF uv_visible_rect(0, 0, uv.x(), uv.y());
+ gfx::RectF uv_visible_rect(quad->uv_top_left.x(), quad->uv_top_left.y(),
+ quad->uv_bottom_right.x() - quad->uv_top_left.x(),
+ quad->uv_bottom_right.y() - quad->uv_top_left.y());
const SamplerType sampler = SamplerTypeFromTextureTarget(lock.target());
Float4 tex_clamp_rect = UVClampRect(uv_visible_rect, texture_size, sampler);
gl_->Uniform4f(current_program_->tex_clamp_rect_location(),
@@ -2583,6 +2602,7 @@ void GLRenderer::EnsureScissorTestDisabled() {
}
void GLRenderer::CopyDrawnRenderPass(
+ const copy_output::RenderPassGeometry& geometry,
std::unique_ptr<CopyOutputRequest> request) {
TRACE_EVENT0("viz", "GLRenderer::CopyDrawnRenderPass");
@@ -2596,9 +2616,8 @@ void GLRenderer::CopyDrawnRenderPass(
framebuffer_texture_size = current_framebuffer_texture_->size();
}
copier_.CopyFromTextureOrFramebuffer(
- std::move(request), current_frame()->current_render_pass->output_rect,
- GetFramebufferCopyTextureFormat(), framebuffer_texture,
- framebuffer_texture_size, FlippedFramebuffer(),
+ std::move(request), geometry, GetFramebufferCopyTextureFormat(),
+ framebuffer_texture, framebuffer_texture_size, FlippedFramebuffer(),
current_frame()->current_render_pass->color_space);
// The copier modified texture/framebuffer bindings, shader programs, and
@@ -3651,7 +3670,7 @@ void GLRenderer::UpdateRenderPassTextures(
bool size_appropriate =
texture.size().width() >= requirements.size.width() &&
texture.size().height() >= requirements.size.height();
- bool mipmap_appropriate = !requirements.mipmap || texture.mipmap();
+ bool mipmap_appropriate = !requirements.generate_mipmap || texture.mipmap();
if (!size_appropriate || !mipmap_appropriate)
passes_to_delete.push_back(pair.first);
}
@@ -3683,7 +3702,7 @@ void GLRenderer::AllocateRenderPassResourceIfNeeded(
ScopedRenderPassTexture contents_texture(
output_surface_->context_provider(), requirements.size,
BackbufferFormat(), current_frame()->current_render_pass->color_space,
- requirements.mipmap);
+ requirements.generate_mipmap);
render_pass_textures_[render_pass_id] = std::move(contents_texture);
}
diff --git a/chromium/components/viz/service/display/gl_renderer.h b/chromium/components/viz/service/display/gl_renderer.h
index 6aa68062d0b..e1ab32000b6 100644
--- a/chromium/components/viz/service/display/gl_renderer.h
+++ b/chromium/components/viz/service/display/gl_renderer.h
@@ -41,6 +41,10 @@ class GLES2Interface;
}
} // namespace gpu
+namespace gfx {
+class RRectF;
+}
+
namespace viz {
class DynamicGeometryBinding;
@@ -102,7 +106,8 @@ class VIZ_SERVICE_EXPORT GLRenderer : public DirectRenderer {
bool FlippedRootFramebuffer() const;
void EnsureScissorTestEnabled() override;
void EnsureScissorTestDisabled() override;
- void CopyDrawnRenderPass(std::unique_ptr<CopyOutputRequest> request) override;
+ void CopyDrawnRenderPass(const copy_output::RenderPassGeometry& geometry,
+ std::unique_ptr<CopyOutputRequest> request) override;
void SetEnableDCLayers(bool enable) override;
void FinishDrawingQuadList() override;
void GenerateMipmap() override;
@@ -196,9 +201,9 @@ class VIZ_SERVICE_EXPORT GLRenderer : public DirectRenderer {
const cc::FilterOperations* filters,
const cc::FilterOperations* backdrop_filters,
const gfx::QuadF* clip_region,
- const gfx::RectF* backdrop_filter_bounds_input,
+ const gfx::RRectF* backdrop_filter_bounds_input,
bool use_aa,
- gfx::Rect* backdrop_filter_bounds,
+ gfx::RRectF* backdrop_filter_bounds,
gfx::Rect* unclipped_rect);
// Allocates and returns a texture id that contains a copy of the contents
// of the current RenderPass being drawn.
@@ -223,7 +228,7 @@ class VIZ_SERVICE_EXPORT GLRenderer : public DirectRenderer {
const gfx::Rect& rect,
const gfx::Rect& unclipped_rect,
const float backdrop_filter_quality,
- const gfx::Rect& backdrop_filter_bounds);
+ const gfx::RRectF& backdrop_filter_bounds);
const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass) override;
diff --git a/chromium/components/viz/service/display/gl_renderer_copier.cc b/chromium/components/viz/service/display/gl_renderer_copier.cc
index dcd5e017f54..72ca2215adf 100644
--- a/chromium/components/viz/service/display/gl_renderer_copier.cc
+++ b/chromium/components/viz/service/display/gl_renderer_copier.cc
@@ -105,11 +105,9 @@ void PopulateScalerParameters(const CopyOutputRequest& request,
GLRendererCopier::GLRendererCopier(
scoped_refptr<ContextProvider> context_provider,
- TextureDeleter* texture_deleter,
- ComputeWindowRectCallback window_rect_callback)
+ TextureDeleter* texture_deleter)
: context_provider_(std::move(context_provider)),
- texture_deleter_(texture_deleter),
- window_rect_callback_(std::move(window_rect_callback)) {}
+ texture_deleter_(texture_deleter) {}
GLRendererCopier::~GLRendererCopier() {
for (auto& entry : cache_)
@@ -118,46 +116,25 @@ GLRendererCopier::~GLRendererCopier() {
void GLRendererCopier::CopyFromTextureOrFramebuffer(
std::unique_ptr<CopyOutputRequest> request,
- const gfx::Rect& output_rect,
+ const copy_output::RenderPassGeometry& geometry,
GLenum internal_format,
GLuint framebuffer_texture,
const gfx::Size& framebuffer_texture_size,
bool flipped_source,
const gfx::ColorSpace& color_space) {
- // Finalize the source subrect, as the entirety of the RenderPass's output
- // optionally clamped to the requested copy area. Then, compute the result
- // rect, which is the selection clamped to the maximum possible result bounds.
- // If there will be zero pixels of output or the scaling ratio was not
- // reasonable, do not proceed.
- gfx::Rect copy_rect = output_rect;
- if (request->has_area())
- copy_rect.Intersect(request->area());
- gfx::Rect result_rect = request->is_scaled()
- ? copy_output::ComputeResultRect(
- gfx::Rect(copy_rect.size()),
- request->scale_from(), request->scale_to())
- : gfx::Rect(copy_rect.size());
- if (request->has_result_selection())
- result_rect.Intersect(request->result_selection());
- if (result_rect.IsEmpty())
- return;
+ const gfx::Rect& result_rect = geometry.result_selection;
// Fast-Path: If no transformation is necessary and no new textures need to be
// generated, read-back directly from the currently-bound framebuffer.
if (request->result_format() == ResultFormat::RGBA_BITMAP &&
!request->is_scaled()) {
- const gfx::Vector2d readback_offset =
- window_rect_callback_.Run(result_rect + copy_rect.OffsetFromOrigin())
- .OffsetFromOrigin();
- StartReadbackFromFramebuffer(std::move(request), readback_offset,
+ StartReadbackFromFramebuffer(std::move(request), geometry.readback_offset,
flipped_source, false, result_rect,
color_space);
return;
}
- // Transform the copy rect into window coordinates, the coordinate system GL
- // is using for the currently-bound framebuffer.
- gfx::Rect sampling_rect = window_rect_callback_.Run(copy_rect);
+ gfx::Rect sampling_rect = geometry.sampling_bounds;
const base::UnguessableToken requester = SourceOf(*request);
std::unique_ptr<ReusableThings> things =
@@ -235,7 +212,7 @@ void GLRendererCopier::CopyFromTextureOrFramebuffer(
// requires that the result be accessed via a task in the same task runner
// sequence as the GLRendererCopier. Since I420_PLANES requests are meant
// to be VIZ-internal, this is an acceptable limitation to enforce.
- DCHECK(request->SendsResultsInCurrentSequence());
+ DCHECK(request->SendsResultsInCurrentSequence() || async_gl_task_runner_);
const gfx::Rect aligned_rect = RenderI420Textures(
*request, flipped_source, color_space, source_texture,
@@ -633,17 +610,41 @@ class GLPixelBufferI420Result : public CopyOutputResult {
public:
// |aligned_rect| identifies the region of result pixels in the pixel buffer,
// while the |result_rect| is the subregion that is exposed to the client.
- GLPixelBufferI420Result(const gfx::Rect& aligned_rect,
- const gfx::Rect& result_rect,
- scoped_refptr<ContextProvider> context_provider,
- GLuint transfer_buffer)
+ GLPixelBufferI420Result(
+ const gfx::Rect& aligned_rect,
+ const gfx::Rect& result_rect,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ scoped_refptr<ContextProvider> context_provider,
+ GLuint transfer_buffer)
: CopyOutputResult(CopyOutputResult::Format::I420_PLANES, result_rect),
aligned_rect_(aligned_rect),
+ task_runner_(task_runner),
context_provider_(std::move(context_provider)),
- transfer_buffer_(transfer_buffer) {}
+ transfer_buffer_(transfer_buffer) {
+ auto* const gl = context_provider_->ContextGL();
+ gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, transfer_buffer_);
+ pixels_ = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
+ GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
+ gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ }
~GLPixelBufferI420Result() final {
- context_provider_->ContextGL()->DeleteBuffers(1, &transfer_buffer_);
+ auto cleanup = base::BindOnce(
+ [](scoped_refptr<ContextProvider> context_provider,
+ GLuint transfer_buffer) {
+ auto* const gl = context_provider->ContextGL();
+ gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
+ transfer_buffer);
+ gl->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
+ gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ gl->DeleteBuffers(1, &transfer_buffer);
+ },
+ context_provider_, transfer_buffer_);
+ if (task_runner_) {
+ task_runner_->PostTask(FROM_HERE, std::move(cleanup));
+ } else {
+ std::move(cleanup).Run();
+ }
}
bool ReadI420Planes(uint8_t* y_out,
@@ -657,10 +658,7 @@ class GLPixelBufferI420Result : public CopyOutputResult {
DCHECK_GE(u_out_stride, chroma_row_bytes);
DCHECK_GE(v_out_stride, chroma_row_bytes);
- auto* const gl = context_provider_->ContextGL();
- gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, transfer_buffer_);
- const uint8_t* pixels = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
- GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
+ uint8_t* pixels = pixels_;
if (pixels) {
const auto CopyPlane = [](const uint8_t* src, int src_stride,
int row_bytes, int num_rows, uint8_t* out,
@@ -687,18 +685,16 @@ class GLPixelBufferI420Result : public CopyOutputResult {
pixels += chroma_stride * (aligned_rect_.height() / 2);
CopyPlane(pixels + chroma_start_offset, chroma_stride, chroma_row_bytes,
chroma_height, v_out, v_out_stride);
- gl->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
}
- gl->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
-
return !!pixels;
}
private:
const gfx::Rect aligned_rect_;
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const scoped_refptr<ContextProvider> context_provider_;
const GLuint transfer_buffer_;
- const gfx::Vector2d i420_offset_;
+ uint8_t* pixels_;
};
// Like the ReadPixelsWorkflow, except for I420 planes readback. Because there
@@ -715,13 +711,16 @@ class GLPixelBufferI420Result : public CopyOutputResult {
class ReadI420PlanesWorkflow
: public base::RefCountedThreadSafe<ReadI420PlanesWorkflow> {
public:
- ReadI420PlanesWorkflow(std::unique_ptr<CopyOutputRequest> copy_request,
- const gfx::Rect& aligned_rect,
- const gfx::Rect& result_rect,
- scoped_refptr<ContextProvider> context_provider)
+ ReadI420PlanesWorkflow(
+ std::unique_ptr<CopyOutputRequest> copy_request,
+ const gfx::Rect& aligned_rect,
+ const gfx::Rect& result_rect,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ scoped_refptr<ContextProvider> context_provider)
: copy_request_(std::move(copy_request)),
aligned_rect_(aligned_rect),
result_rect_(result_rect),
+ task_runner_(std::move(task_runner)),
context_provider_(std::move(context_provider)) {
// Create a buffer for the pixel transfer: A single buffer is used and will
// contain the Y plane, then the U plane, then the V plane.
@@ -802,7 +801,8 @@ class ReadI420PlanesWorkflow
// If all three readbacks have completed, send the result.
if (queries_ == std::array<GLuint, 3>{{0, 0, 0}}) {
copy_request_->SendResult(std::make_unique<GLPixelBufferI420Result>(
- aligned_rect_, result_rect_, context_provider_, transfer_buffer_));
+ aligned_rect_, result_rect_, task_runner_, context_provider_,
+ transfer_buffer_));
transfer_buffer_ = 0; // Ownership was transferred to the result.
}
}
@@ -810,6 +810,7 @@ class ReadI420PlanesWorkflow
const std::unique_ptr<CopyOutputRequest> copy_request_;
const gfx::Rect aligned_rect_;
const gfx::Rect result_rect_;
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const scoped_refptr<ContextProvider> context_provider_;
GLuint transfer_buffer_;
std::array<int, 3> data_offsets_;
@@ -833,7 +834,8 @@ void GLRendererCopier::StartI420ReadbackFromTextures(
// CopyOutputRequest is passed to the ReadI420PlanesWorkflow, which will send
// the CopyOutputResult once all readback operations are complete.
const auto workflow = base::MakeRefCounted<ReadI420PlanesWorkflow>(
- std::move(request), aligned_rect, result_rect, context_provider_);
+ std::move(request), aligned_rect, result_rect, async_gl_task_runner_,
+ context_provider_);
workflow->BindTransferBuffer();
for (int plane = 0; plane < 3; ++plane) {
gl->BindFramebuffer(GL_FRAMEBUFFER,
diff --git a/chromium/components/viz/service/display/gl_renderer_copier.h b/chromium/components/viz/service/display/gl_renderer_copier.h
index 97ee58eaf73..4038994562e 100644
--- a/chromium/components/viz/service/display/gl_renderer_copier.h
+++ b/chromium/components/viz/service/display/gl_renderer_copier.h
@@ -14,11 +14,15 @@
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/task_runner.h"
#include "base/unguessable_token.h"
#include "components/viz/service/viz_service_export.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
#include "ui/gfx/geometry/size.h"
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
namespace gfx {
class ColorSpace;
class Rect;
@@ -39,6 +43,10 @@ class GLI420Converter;
class GLScaler;
class TextureDeleter;
+namespace copy_output {
+struct RenderPassGeometry;
+} // namespace copy_output
+
// Helper class for GLRenderer that executes CopyOutputRequests using GL, to
// perform texture copies/transformations and read back bitmaps. Also manages
// the caching of resources needed to ensure efficient video performance.
@@ -57,14 +65,14 @@ class TextureDeleter;
// "source" has ended.
class VIZ_SERVICE_EXPORT GLRendererCopier {
public:
- // A callback that calls GLRenderer::MoveFromDrawToWindowSpace().
- using ComputeWindowRectCallback =
- base::RepeatingCallback<gfx::Rect(const gfx::Rect&)>;
+ // Define types to avoid pulling in command buffer GL headers, which conflict
+ // the ui/gl/gl_bindings.h
+ using GLuint = unsigned int;
+ using GLenum = unsigned int;
// |texture_deleter| must outlive this instance.
GLRendererCopier(scoped_refptr<ContextProvider> context_provider,
- TextureDeleter* texture_deleter,
- ComputeWindowRectCallback window_rect_callback);
+ TextureDeleter* texture_deleter);
~GLRendererCopier();
@@ -82,19 +90,25 @@ class VIZ_SERVICE_EXPORT GLRendererCopier {
// and framebuffer bindings, shader programs, and related attributes; and so
// the caller must not make any assumptions about the state of the GL context
// after this call.
- void CopyFromTextureOrFramebuffer(std::unique_ptr<CopyOutputRequest> request,
- const gfx::Rect& output_rect,
- GLenum internal_format,
- GLuint framebuffer_texture,
- const gfx::Size& framebuffer_texture_size,
- bool flipped_source,
- const gfx::ColorSpace& color_space);
+ void CopyFromTextureOrFramebuffer(
+ std::unique_ptr<CopyOutputRequest> request,
+ const copy_output::RenderPassGeometry& geometry,
+ GLenum internal_format,
+ GLuint framebuffer_texture,
+ const gfx::Size& framebuffer_texture_size,
+ bool flipped_source,
+ const gfx::ColorSpace& color_space);
// Checks whether cached resources should be freed because recent copy
// activity is no longer using them. This should be called after a frame has
// finished drawing (after all copy requests have been executed).
void FreeUnusedCachedResources();
+ void set_async_gl_task_runner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ async_gl_task_runner_ = task_runner;
+ }
+
private:
friend class GLRendererCopierTest;
@@ -108,7 +122,7 @@ class VIZ_SERVICE_EXPORT GLRendererCopier {
// Texture containing a copy of the source framebuffer, if the source
// framebuffer cannot be used directly.
GLuint fb_copy_texture = 0;
- GLenum fb_copy_texture_internal_format = static_cast<GLenum>(GL_NONE);
+ GLenum fb_copy_texture_internal_format = static_cast<GLenum>(0 /*GL_NONE*/);
gfx::Size fb_copy_texture_size;
// RGBA requests: Scaling, and texture/framebuffer for readback.
@@ -245,7 +259,6 @@ class VIZ_SERVICE_EXPORT GLRendererCopier {
// Injected dependencies.
const scoped_refptr<ContextProvider> context_provider_;
TextureDeleter* const texture_deleter_;
- const ComputeWindowRectCallback window_rect_callback_;
// This increments by one for every call to FreeUnusedCachedResources(). It
// is meant to determine when cached resources should be freed because they
@@ -263,7 +276,7 @@ class VIZ_SERVICE_EXPORT GLRendererCopier {
// efficiently using GL_RGBA or GL_BGRA_EXT format. This starts out as
// GL_NONE, which means "unknown," and will be determined at the time the
// first readback request is made.
- GLenum optimal_readback_format_ = static_cast<GLenum>(GL_NONE);
+ GLenum optimal_readback_format_ = static_cast<GLenum>(0 /*GL_NONE*/);
// Purge cache entries that have not been used after this many calls to
// FreeUnusedCachedResources(). The choice of 60 is arbitrary, but on most
@@ -271,6 +284,12 @@ class VIZ_SERVICE_EXPORT GLRendererCopier {
// things to be auto-purged after approx. 1-2 seconds of not being used.
static constexpr int kKeepalivePeriod = 60;
+ // The task runner that is being used to call into GLRendererCopier. This
+ // allows for CopyOutputResults, owned by external entities, to execute
+ // post-destruction clean-up tasks. If null, assume CopyOutputResults are
+ // always destroyed from the same task runner
+ scoped_refptr<base::SingleThreadTaskRunner> async_gl_task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(GLRendererCopier);
};
diff --git a/chromium/components/viz/service/display/gl_renderer_copier_pixeltest.cc b/chromium/components/viz/service/display/gl_renderer_copier_pixeltest.cc
index 8c5f5d58d95..c7b5f2e3dd0 100644
--- a/chromium/components/viz/service/display/gl_renderer_copier_pixeltest.cc
+++ b/chromium/components/viz/service/display/gl_renderer_copier_pixeltest.cc
@@ -22,8 +22,10 @@
#include "cc/test/pixel_test_utils.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/service/display/gl_renderer.h"
#include "components/viz/test/paths.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImageInfo.h"
@@ -73,16 +75,8 @@ class GLRendererCopierPixelTest
flipped_source_ = std::get<4>(GetParam());
gl_ = context_provider()->ContextGL();
- copier_ = std::make_unique<GLRendererCopier>(
- context_provider(), texture_deleter_.get(),
- base::BindRepeating(
- [](bool flipped_source, const gfx::Rect& draw_rect) {
- gfx::Rect window_rect = draw_rect;
- if (flipped_source)
- window_rect.set_y(kSourceSize.height() - window_rect.bottom());
- return window_rect;
- },
- flipped_source_));
+ copier_ = std::make_unique<GLRendererCopier>(context_provider(),
+ texture_deleter_.get());
ASSERT_TRUE(cc::ReadPNGFile(
GetTestFilePath(FILE_PATH_LITERAL("16_color_rects.png")),
@@ -99,6 +93,13 @@ class GLRendererCopierPixelTest
GLRendererCopier* copier() { return copier_.get(); }
+ gfx::Rect DrawToWindowSpace(const gfx::Rect& draw_rect) {
+ gfx::Rect window_rect = draw_rect;
+ if (flipped_source_)
+ window_rect.set_y(kSourceSize.height() - window_rect.bottom());
+ return window_rect;
+ }
+
// Creates a packed RGBA (bytes_per_pixel=4) or RGB (bytes_per_pixel=3) bitmap
// in OpenGL byte/row order from the given SkBitmap.
std::unique_ptr<uint8_t[]> CreateGLPixelsFromSkBitmap(SkBitmap bitmap) {
@@ -266,8 +267,16 @@ TEST_P(GLRendererCopierPixelTest, ExecutesCopyRequest) {
}
const GLuint source_texture = CreateSourceTexture();
CreateAndBindSourceFramebuffer(source_texture);
+
+ copy_output::RenderPassGeometry geometry;
+ // geometry.result_bounds not used by GLRendererCopier
+ geometry.sampling_bounds = DrawToWindowSpace(gfx::Rect(kSourceSize));
+ geometry.result_selection = request->result_selection();
+ geometry.readback_offset =
+ DrawToWindowSpace(geometry.result_selection).OffsetFromOrigin();
+
copier()->CopyFromTextureOrFramebuffer(
- std::move(request), gfx::Rect(kSourceSize), source_gl_format_,
+ std::move(request), geometry, source_gl_format_,
have_source_texture_ ? source_texture : 0, kSourceSize, flipped_source_,
gfx::ColorSpace::CreateSRGB());
loop.Run();
@@ -305,7 +314,7 @@ TEST_P(GLRendererCopierPixelTest, ExecutesCopyRequest) {
// Instantiate parameter sets for all possible combinations of scenarios
// GLRendererCopier will encounter, which will cause it to follow different
// workflows.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
GLRendererCopierPixelTest,
testing::Combine(
diff --git a/chromium/components/viz/service/display/gl_renderer_copier_unittest.cc b/chromium/components/viz/service/display/gl_renderer_copier_unittest.cc
index af7633768fb..aebb5ed5d56 100644
--- a/chromium/components/viz/service/display/gl_renderer_copier_unittest.cc
+++ b/chromium/components/viz/service/display/gl_renderer_copier_unittest.cc
@@ -65,9 +65,8 @@ class GLRendererCopierTest : public testing::Test {
auto context_provider = TestContextProvider::Create(
std::make_unique<CopierTestGLES2Interface>());
context_provider->BindToCurrentThread();
- copier_ = std::make_unique<GLRendererCopier>(
- std::move(context_provider), nullptr,
- base::BindRepeating([](const gfx::Rect& rect) { return rect; }));
+ copier_ = std::make_unique<GLRendererCopier>(std::move(context_provider),
+ nullptr);
}
void TearDown() override { copier_.reset(); }
diff --git a/chromium/components/viz/service/display/gl_renderer_unittest.cc b/chromium/components/viz/service/display/gl_renderer_unittest.cc
index 327b91b5e85..0a6b9d83265 100644
--- a/chromium/components/viz/service/display/gl_renderer_unittest.cc
+++ b/chromium/components/viz/service/display/gl_renderer_unittest.cc
@@ -12,6 +12,8 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_feature_list.h"
@@ -39,6 +41,7 @@
#include "components/viz/test/test_shared_bitmap_manager.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/config/gpu_finch_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkMatrix.h"
@@ -227,7 +230,7 @@ class GLRendererShaderPixelTest : public cc::GLRendererPixelTest {
void TestColorShaders() {
const size_t kNumTransferFns = 7;
- SkColorSpaceTransferFn transfer_fns[kNumTransferFns] = {
+ skcms_TransferFunction transfer_fns[kNumTransferFns] = {
// The identity.
{1.f, 1.f, 0.f, 1.f, 0.f, 0.f, 0.f},
// The identity, with an if statement.
@@ -399,9 +402,9 @@ TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
TestShadersWithPrecision(GetParam());
}
-INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
- PrecisionShaderPixelTest,
- ::testing::ValuesIn(kPrecisionList));
+INSTANTIATE_TEST_SUITE_P(PrecisionShadersCompile,
+ PrecisionShaderPixelTest,
+ ::testing::ValuesIn(kPrecisionList));
class PrecisionBlendShaderPixelTest
: public GLRendererShaderPixelTest,
@@ -413,7 +416,7 @@ TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
std::get<1>(GetParam()));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PrecisionBlendShadersCompile,
PrecisionBlendShaderPixelTest,
::testing::Combine(::testing::ValuesIn(kPrecisionList),
@@ -429,10 +432,10 @@ TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
std::get<1>(GetParam()));
}
-INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
- PrecisionSamplerShaderPixelTest,
- ::testing::Combine(::testing::ValuesIn(kPrecisionList),
- ::testing::ValuesIn(kSamplerList)));
+INSTANTIATE_TEST_SUITE_P(PrecisionSamplerShadersCompile,
+ PrecisionSamplerShaderPixelTest,
+ ::testing::Combine(::testing::ValuesIn(kPrecisionList),
+ ::testing::ValuesIn(kSamplerList)));
class MaskShaderPixelTest
: public GLRendererShaderPixelTest,
@@ -444,12 +447,12 @@ TEST_P(MaskShaderPixelTest, ShadersCompile) {
std::get<2>(GetParam()), std::get<3>(GetParam()));
}
-INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
- MaskShaderPixelTest,
- ::testing::Combine(::testing::ValuesIn(kPrecisionList),
- ::testing::ValuesIn(kSamplerList),
- ::testing::ValuesIn(kBlendModeList),
- ::testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(MaskShadersCompile,
+ MaskShaderPixelTest,
+ ::testing::Combine(::testing::ValuesIn(kPrecisionList),
+ ::testing::ValuesIn(kSamplerList),
+ ::testing::ValuesIn(kBlendModeList),
+ ::testing::Bool()));
#endif
@@ -2046,12 +2049,6 @@ class MockOutputSurface : public OutputSurface {
MOCK_METHOD0(GetFramebufferCopyTextureFormat, GLenum());
MOCK_METHOD1(SwapBuffers_, void(OutputSurfaceFrame& frame)); // NOLINT
void SwapBuffers(OutputSurfaceFrame frame) override { SwapBuffers_(frame); }
-#if BUILDFLAG(ENABLE_VULKAN)
- gpu::VulkanSurface* GetVulkanSurface() override {
- NOTREACHED();
- return nullptr;
- }
-#endif
MOCK_CONST_METHOD0(GetOverlayCandidateValidator,
OverlayCandidateValidator*());
MOCK_CONST_METHOD0(IsDisplayedAsOverlayPlane, bool());
@@ -2223,8 +2220,9 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
std::vector<ResourceId> resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource_id);
std::vector<TransferableResource> list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, &list,
- child_context_provider.get());
+ child_resource_provider->PrepareSendToParent(
+ resource_ids_to_transfer, &list,
+ static_cast<RasterContextProvider*>(child_context_provider.get()));
parent_resource_provider->ReceiveFromChild(child_id, list);
// In DisplayResourceProvider's namespace, use the mapped resource id.
@@ -2435,8 +2433,9 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) {
std::vector<ResourceId> resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource_id);
std::vector<TransferableResource> list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, &list,
- child_context_provider.get());
+ child_resource_provider->PrepareSendToParent(
+ resource_ids_to_transfer, &list,
+ static_cast<RasterContextProvider*>(child_context_provider.get()));
parent_resource_provider->ReceiveFromChild(child_id, list);
// In DisplayResourceProvider's namespace, use the mapped resource id.
@@ -2821,8 +2820,9 @@ TEST_F(GLRendererTest, DCLayerOverlaySwitch) {
std::vector<ResourceId> resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource_id);
std::vector<TransferableResource> list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer, &list,
- child_context_provider.get());
+ child_resource_provider->PrepareSendToParent(
+ resource_ids_to_transfer, &list,
+ static_cast<RasterContextProvider*>(child_context_provider.get()));
parent_resource_provider->ReceiveFromChild(child_id, list);
// In DisplayResourceProvider's namespace, use the mapped resource id.
std::unordered_map<ResourceId, ResourceId> resource_map =
diff --git a/chromium/components/viz/service/display/output_surface.cc b/chromium/components/viz/service/display/output_surface.cc
index aeec9fccf91..1f05d2e451b 100644
--- a/chromium/components/viz/service/display/output_surface.cc
+++ b/chromium/components/viz/service/display/output_surface.cc
@@ -16,7 +16,6 @@
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/vulkan/buildflags.h"
#include "ui/gfx/swap_result.h"
namespace viz {
@@ -34,14 +33,6 @@ OutputSurface::OutputSurface(
DCHECK(software_device_);
}
-#if BUILDFLAG(ENABLE_VULKAN)
-OutputSurface::OutputSurface(
- scoped_refptr<VulkanContextProvider> vulkan_context_provider)
- : vulkan_context_provider_(std::move(vulkan_context_provider)) {
- DCHECK(vulkan_context_provider_);
-}
-#endif
-
OutputSurface::~OutputSurface() = default;
void OutputSurface::UpdateLatencyInfoOnSwap(
diff --git a/chromium/components/viz/service/display/output_surface.h b/chromium/components/viz/service/display/output_surface.h
index 8ed647a451b..572ff9e0da9 100644
--- a/chromium/components/viz/service/display/output_surface.h
+++ b/chromium/components/viz/service/display/output_surface.h
@@ -17,15 +17,9 @@
#include "components/viz/service/display/software_output_device.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/texture_in_use_response.h"
-#include "gpu/vulkan/buildflags.h"
#include "ui/gfx/color_space.h"
#include "ui/latency/latency_info.h"
-#if BUILDFLAG(ENABLE_VULKAN)
-#include "components/viz/common/gpu/vulkan_context_provider.h"
-#include "gpu/vulkan/vulkan_surface.h"
-#endif
-
namespace gfx {
class ColorSpace;
class Size;
@@ -62,11 +56,6 @@ class VIZ_SERVICE_EXPORT OutputSurface {
explicit OutputSurface(scoped_refptr<ContextProvider> context_provider);
// Constructor for software compositing.
explicit OutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device);
-#if BUILDFLAG(ENABLE_VULKAN)
- // Constructor for Vulkan-based compositing.
- explicit OutputSurface(
- scoped_refptr<VulkanContextProvider> vulkan_context_provider);
-#endif
virtual ~OutputSurface();
@@ -77,11 +66,6 @@ class VIZ_SERVICE_EXPORT OutputSurface {
// In the event of a lost context, the entire output surface should be
// recreated.
ContextProvider* context_provider() const { return context_provider_.get(); }
-#if BUILDFLAG(ENABLE_VULKAN)
- VulkanContextProvider* vulkan_context_provider() const {
- return vulkan_context_provider_.get();
- }
-#endif
SoftwareOutputDevice* software_device() const {
return software_device_.get();
}
@@ -101,8 +85,7 @@ class VIZ_SERVICE_EXPORT OutputSurface {
virtual void BindFramebuffer() = 0;
// Marks that the given rectangle will be drawn to on the default, bound
- // framebuffer. Only valid for surfaces with dc_layers in the context
- // capabilities.
+ // framebuffer.
virtual void SetDrawRectangle(const gfx::Rect& rect) = 0;
// Get the class capable of informing cc of hardware overlay capability.
@@ -135,11 +118,6 @@ class VIZ_SERVICE_EXPORT OutputSurface {
// after returning from this method in order to unblock the next frame.
virtual void SwapBuffers(OutputSurfaceFrame frame) = 0;
-#if BUILDFLAG(ENABLE_VULKAN)
- // Gives the Vulkan surface created when enable_vulkan flag is set.
- virtual gpu::VulkanSurface* GetVulkanSurface() = 0;
-#endif
-
// Updates the GpuFence associated with this surface. The id of a newly
// created GpuFence is returned, or if an error occurs, or fences are not
// supported, the special id of 0 (meaning "no fence") is returned. In all
@@ -163,9 +141,6 @@ class VIZ_SERVICE_EXPORT OutputSurface {
protected:
struct OutputSurface::Capabilities capabilities_;
scoped_refptr<ContextProvider> context_provider_;
-#if BUILDFLAG(ENABLE_VULKAN)
- scoped_refptr<VulkanContextProvider> vulkan_context_provider_;
-#endif
std::unique_ptr<SoftwareOutputDevice> software_device_;
private:
diff --git a/chromium/components/viz/service/display/overlay_candidate.cc b/chromium/components/viz/service/display/overlay_candidate.cc
index 5c67d0143da..6e94a82daf7 100644
--- a/chromium/components/viz/service/display/overlay_candidate.cc
+++ b/chromium/components/viz/service/display/overlay_candidate.cc
@@ -15,6 +15,7 @@
#include "components/viz/common/quads/stream_video_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/service/display/display_resource_provider.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -78,102 +79,6 @@ gfx::OverlayTransform GetOverlayTransform(const gfx::Transform& quad_transform,
return gfx::OVERLAY_TRANSFORM_INVALID;
}
-// Apply transform |delta| to |in| and return the resulting transform,
-// or OVERLAY_TRANSFORM_INVALID.
-gfx::OverlayTransform ComposeTransforms(gfx::OverlayTransform delta,
- gfx::OverlayTransform in) {
- // There are 8 different possible transforms. We can characterize these
- // by looking at where the origin moves and the direction the horizontal goes.
- // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
- // NONE: TL, H
- // FLIP_VERTICAL: BL, H
- // FLIP_HORIZONTAL: TR, H
- // ROTATE_90: TR, V
- // ROTATE_180: BR, H
- // ROTATE_270: BL, V
- // Missing transforms: TL, V & BR, V
- // Basic combinations:
- // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
- // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
- // Rotate + Rotate simply adds values.
- // Rotate 90/270 + flip is invalid because we can only have verticals with
- // the origin in TR or BL.
- if (delta == gfx::OVERLAY_TRANSFORM_NONE)
- return in;
- switch (in) {
- case gfx::OVERLAY_TRANSFORM_NONE:
- return delta;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_ROTATE_270;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_NONE;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
- return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
- return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_ROTATE_270;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_ROTATE_90;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- switch (delta) {
- case gfx::OVERLAY_TRANSFORM_ROTATE_90:
- return gfx::OVERLAY_TRANSFORM_NONE;
- case gfx::OVERLAY_TRANSFORM_ROTATE_180:
- return gfx::OVERLAY_TRANSFORM_ROTATE_90;
- case gfx::OVERLAY_TRANSFORM_ROTATE_270:
- return gfx::OVERLAY_TRANSFORM_ROTATE_180;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
- break;
- default:
- return gfx::OVERLAY_TRANSFORM_INVALID;
- }
-}
-
} // namespace
OverlayCandidate::OverlayCandidate()
@@ -225,6 +130,9 @@ bool OverlayCandidate::FromDrawQuad(DisplayResourceProvider* resource_provider,
case DrawQuad::TILED_CONTENT:
return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad),
candidate);
+ case DrawQuad::VIDEO_HOLE:
+ return FromVideoHoleQuad(
+ resource_provider, VideoHoleDrawQuad::MaterialCast(quad), candidate);
case DrawQuad::STREAM_VIDEO_CONTENT:
return FromStreamVideoQuad(resource_provider,
StreamVideoDrawQuad::MaterialCast(quad),
@@ -273,6 +181,8 @@ bool OverlayCandidate::RequiresOverlay(const DrawQuad* quad) {
case DrawQuad::TEXTURE_CONTENT:
return TextureDrawQuad::MaterialCast(quad)->protected_video_type ==
ui::ProtectedVideoType::kHardwareProtected;
+ case DrawQuad::VIDEO_HOLE:
+ return true;
case DrawQuad::YUV_VIDEO_CONTENT:
return YUVVideoDrawQuad::MaterialCast(quad)->protected_video_type ==
ui::ProtectedVideoType::kHardwareProtected;
@@ -317,6 +227,7 @@ bool OverlayCandidate::FromDrawQuadResource(
return false;
candidate->format = resource_provider->GetBufferFormat(resource_id);
+ candidate->color_space = resource_provider->GetColorSpace(resource_id);
if (!base::ContainsValue(kOverlayFormats, candidate->format))
return false;
@@ -340,11 +251,33 @@ bool OverlayCandidate::FromDrawQuadResource(
}
// static
+// For VideoHoleDrawQuad, only calculate geometry information
+// and put it in the |candidate|.
+bool OverlayCandidate::FromVideoHoleQuad(
+ DisplayResourceProvider* resource_provider,
+ const VideoHoleDrawQuad* quad,
+ OverlayCandidate* candidate) {
+ gfx::OverlayTransform overlay_transform = GetOverlayTransform(
+ quad->shared_quad_state->quad_to_target_transform, false);
+ if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
+ return false;
+
+ auto& transform = quad->shared_quad_state->quad_to_target_transform;
+ candidate->display_rect = gfx::RectF(quad->rect);
+ transform.TransformRect(&candidate->display_rect);
+ candidate->transform = overlay_transform;
+
+ return true;
+}
+
+// static
bool OverlayCandidate::FromTextureQuad(
DisplayResourceProvider* resource_provider,
const TextureDrawQuad* quad,
OverlayCandidate* candidate) {
- if (quad->background_color != SK_ColorTRANSPARENT)
+ if (quad->background_color != SK_ColorTRANSPARENT &&
+ (quad->background_color != SK_ColorBLACK ||
+ quad->ShouldDrawWithBlending()))
return false;
if (!FromDrawQuadResource(resource_provider, quad, quad->resource_id(),
quad->y_flipped, candidate)) {
@@ -377,42 +310,14 @@ bool OverlayCandidate::FromStreamVideoQuad(
candidate)) {
return false;
}
- if (!quad->matrix.IsScaleOrTranslation()) {
- // We cannot handle anything other than scaling & translation for texture
- // coordinates yet.
- return false;
- }
+
candidate->resource_id = quad->resource_id();
candidate->resource_size_in_pixels = quad->resource_size_in_pixels();
+ candidate->uv_rect = BoundingRect(quad->uv_top_left, quad->uv_bottom_right);
#if defined(OS_ANDROID)
candidate->is_backed_by_surface_texture =
resource_provider->IsBackedBySurfaceTexture(quad->resource_id());
#endif
-
- gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
- gfx::Point3F uv1 = gfx::Point3F(1, 1, 0);
- quad->matrix.TransformPoint(&uv0);
- quad->matrix.TransformPoint(&uv1);
- gfx::Vector3dF delta = uv1 - uv0;
- if (delta.x() < 0) {
- candidate->transform = ComposeTransforms(
- gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL, candidate->transform);
- float x0 = uv0.x();
- uv0.set_x(uv1.x());
- uv1.set_x(x0);
- delta.set_x(-delta.x());
- }
-
- if (delta.y() < 0) {
- // In this situation, uv0y < uv1y. Since we overlay inverted, a request
- // to invert the source texture means we can just output the texture
- // normally and it will be correct.
- candidate->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y());
- } else {
- candidate->transform = ComposeTransforms(
- gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL, candidate->transform);
- candidate->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y());
- }
return true;
}
diff --git a/chromium/components/viz/service/display/overlay_candidate.h b/chromium/components/viz/service/display/overlay_candidate.h
index c2b8f2675d8..3c52114c163 100644
--- a/chromium/components/viz/service/display/overlay_candidate.h
+++ b/chromium/components/viz/service/display/overlay_candidate.h
@@ -29,6 +29,7 @@ class DisplayResourceProvider;
class StreamVideoDrawQuad;
class TextureDrawQuad;
class TileDrawQuad;
+class VideoHoleDrawQuad;
class VIZ_SERVICE_EXPORT OverlayCandidate {
public:
@@ -70,6 +71,8 @@ class VIZ_SERVICE_EXPORT OverlayCandidate {
gfx::OverlayTransform transform;
// Format of the buffer to scanout.
gfx::BufferFormat format;
+ // ColorSpace of the buffer for scanout.
+ gfx::ColorSpace color_space;
// Size of the resource, in pixels.
gfx::Size resource_size_in_pixels;
// Rect on the display to position the overlay to. Implementer must convert
@@ -130,6 +133,9 @@ class VIZ_SERVICE_EXPORT OverlayCandidate {
static bool FromStreamVideoQuad(DisplayResourceProvider* resource_provider,
const StreamVideoDrawQuad* quad,
OverlayCandidate* candidate);
+ static bool FromVideoHoleQuad(DisplayResourceProvider* resource_provider,
+ const VideoHoleDrawQuad* quad,
+ OverlayCandidate* candidate);
};
class VIZ_SERVICE_EXPORT OverlayCandidateList
diff --git a/chromium/components/viz/service/display/overlay_processor.cc b/chromium/components/viz/service/display/overlay_processor.cc
index 68e4fc2f292..965663d2d57 100644
--- a/chromium/components/viz/service/display/overlay_processor.cc
+++ b/chromium/components/viz/service/display/overlay_processor.cc
@@ -9,6 +9,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/service/display/dc_layer_overlay.h"
#include "components/viz/service/display/display_resource_provider.h"
#include "components/viz/service/display/output_surface.h"
@@ -45,8 +46,8 @@ class SendPromotionHintsBeforeReturning {
} // namespace
-OverlayProcessor::StrategyType OverlayProcessor::Strategy::GetUMAEnum() const {
- return StrategyType::kUnknown;
+OverlayStrategy OverlayProcessor::Strategy::GetUMAEnum() const {
+ return OverlayStrategy::kUnknown;
}
OverlayProcessor::OverlayProcessor(OutputSurface* surface)
@@ -109,9 +110,9 @@ bool OverlayProcessor::ProcessForDCLayers(
if (!overlay_validator || !overlay_validator->AllowDCLayerOverlays())
return false;
- dc_processor_.Process(
- resource_provider, gfx::RectF(render_passes->back()->output_rect),
- render_passes, &overlay_damage_rect_, damage_rect, dc_layer_overlays);
+ dc_processor_.Process(resource_provider,
+ gfx::RectF(render_passes->back()->output_rect),
+ render_passes, damage_rect, dc_layer_overlays);
DCHECK(overlay_candidates->empty());
return true;
@@ -150,7 +151,12 @@ void OverlayProcessor::ProcessForOverlays(
// CALayers because the framebuffer would be missing the removed quads'
// contents.
if (!render_pass->copy_requests.empty()) {
+ damage_rect->Union(
+ dc_processor_.previous_frame_overlay_damage_contribution());
+ // Update damage rect before calling ClearOverlayState, otherwise
+ // previous_frame_overlay_rect_union will be empty.
dc_processor_.ClearOverlayState();
+
return;
}
@@ -170,15 +176,16 @@ void OverlayProcessor::ProcessForOverlays(
// Only if that fails, attempt hardware overlay strategies.
Strategy* successful_strategy = nullptr;
for (const auto& strategy : strategies_) {
- if (!strategy->Attempt(output_color_matrix, render_pass_backdrop_filters,
- resource_provider, render_passes, candidates,
- content_bounds)) {
- continue;
+ if (strategy->Attempt(output_color_matrix, render_pass_backdrop_filters,
+ resource_provider, render_passes, candidates,
+ content_bounds)) {
+ successful_strategy = strategy.get();
+
+ UpdateDamageRect(candidates, previous_frame_underlay_rect,
+ previous_frame_underlay_was_unoccluded,
+ &render_pass->quad_list, damage_rect);
+ break;
}
- successful_strategy = strategy.get();
- UpdateDamageRect(candidates, previous_frame_underlay_rect,
- previous_frame_underlay_was_unoccluded, damage_rect);
- break;
}
if (!successful_strategy && !previous_frame_underlay_rect.IsEmpty())
@@ -187,7 +194,7 @@ void OverlayProcessor::ProcessForOverlays(
UMA_HISTOGRAM_ENUMERATION("Viz.DisplayCompositor.OverlayStrategy",
successful_strategy
? successful_strategy->GetUMAEnum()
- : StrategyType::kNoStrategyUsed);
+ : OverlayStrategy::kNoStrategyUsed);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("viz.debug.overlay_planes"),
"Scheduled overlay planes", candidates->size());
@@ -204,6 +211,7 @@ void OverlayProcessor::UpdateDamageRect(
OverlayCandidateList* candidates,
const gfx::Rect& previous_frame_underlay_rect,
bool previous_frame_underlay_was_unoccluded,
+ const QuadList* quad_list,
gfx::Rect* damage_rect) {
gfx::Rect output_surface_overlay_damage_rect;
gfx::Rect this_frame_underlay_rect;
@@ -219,24 +227,47 @@ void OverlayProcessor::UpdateDamageRect(
if (overlay.is_opaque)
damage_rect->Subtract(overlay_display_rect);
}
- } else if (this_frame_underlay_rect.IsEmpty()) {
+ } else {
// Process underlay candidates:
- // Track the underlay_rect from frame to frame. If it is the same
- // and nothing is on top of it then that rect doesn't need to
- // be damaged because the drawing is occurring on a different plane.
- // If it is different then that indicates that a different underlay
- // has been chosen and the previous underlay rect should be damaged
- // because it has changed planes from the underlay plane to the
- // main plane.
+ // Track the underlay_rect from frame to frame. If it is the same and
+ // nothing is on top of it then that rect doesn't need to be damaged
+ // because the drawing is occurring on a different plane. If it is
+ // different then that indicates that a different underlay has been chosen
+ // and the previous underlay rect should be damaged because it has changed
+ // planes from the underlay plane to the main plane.
+ // It then checks that this is not a transition from occluded to
+ // unoccluded.
//
// We also insist that the underlay is unoccluded for at leat one frame,
// else when content above the overlay transitions from not fully
// transparent to fully transparent, we still need to erase it from the
// framebuffer. Otherwise, the last non-transparent frame will remain.
// https://crbug.com/875879
+ // However, if the underlay is unoccluded, we check if the damage is due
+ // to a solid-opaque-transparent quad. If so, then we subtract this
+ // damage.
this_frame_underlay_rect = ToEnclosedRect(overlay.display_rect);
- if ((this_frame_underlay_rect == previous_frame_underlay_rect) &&
- overlay.is_unoccluded && previous_frame_underlay_was_unoccluded) {
+
+ bool same_underlay_rect =
+ this_frame_underlay_rect == previous_frame_underlay_rect;
+ bool transition_from_occluded_to_unoccluded =
+ overlay.is_unoccluded && !previous_frame_underlay_was_unoccluded;
+ bool always_unoccluded =
+ overlay.is_unoccluded && previous_frame_underlay_was_unoccluded;
+ bool has_damage = std::any_of(
+ quad_list->begin(), quad_list->end(), [](const auto& quad) {
+ bool solid_opaque_tranparent =
+ !quad->ShouldDrawWithBlending() &&
+ quad->material == DrawQuad::SOLID_COLOR &&
+ SolidColorDrawQuad::MaterialCast(quad)->color ==
+ SK_ColorTRANSPARENT;
+
+ return !solid_opaque_tranparent &&
+ quad->shared_quad_state->has_surface_damage;
+ });
+
+ if (same_underlay_rect && !transition_from_occluded_to_unoccluded &&
+ (always_unoccluded || !has_damage)) {
damage_rect->Subtract(this_frame_underlay_rect);
}
previous_frame_underlay_was_unoccluded_ = overlay.is_unoccluded;
diff --git a/chromium/components/viz/service/display/overlay_processor.h b/chromium/components/viz/service/display/overlay_processor.h
index 4ec681aede5..1a696cfe29a 100644
--- a/chromium/components/viz/service/display/overlay_processor.h
+++ b/chromium/components/viz/service/display/overlay_processor.h
@@ -9,6 +9,7 @@
#include "base/containers/flat_map.h"
#include "base/macros.h"
+#include "components/viz/common/display/overlay_strategy.h"
#include "components/viz/common/quads/render_pass.h"
#include "components/viz/service/display/ca_layer_overlay.h"
#include "components/viz/service/display/dc_layer_overlay.h"
@@ -24,18 +25,6 @@ class OutputSurface;
class VIZ_SERVICE_EXPORT OverlayProcessor {
public:
- // Enum used for UMA histogram. These enum values must not be changed or
- // reused.
- enum class StrategyType {
- kUnknown = 0,
- kNoStrategyUsed = 1,
- kFullscreen = 2,
- kSingleOnTop = 3,
- kUnderlay = 4,
- kUnderlayCast = 5,
- kMaxValue = kUnderlayCast,
- };
-
using FilterOperationsMap =
base::flat_map<RenderPassId, cc::FilterOperations*>;
@@ -55,7 +44,7 @@ class VIZ_SERVICE_EXPORT OverlayProcessor {
OverlayCandidateList* candidates,
std::vector<gfx::Rect>* content_bounds) = 0;
- virtual StrategyType GetUMAEnum() const;
+ virtual OverlayStrategy GetUMAEnum() const;
};
using StrategyList = std::vector<std::unique_ptr<Strategy>>;
@@ -112,6 +101,7 @@ class VIZ_SERVICE_EXPORT OverlayProcessor {
void UpdateDamageRect(OverlayCandidateList* candidates,
const gfx::Rect& previous_frame_underlay_rect,
bool previous_frame_underlay_was_unoccluded,
+ const QuadList* quad_list,
gfx::Rect* damage_rect);
DCLayerOverlayProcessor dc_processor_;
diff --git a/chromium/components/viz/service/display/overlay_strategy_fullscreen.cc b/chromium/components/viz/service/display/overlay_strategy_fullscreen.cc
index c7232106d66..7515ad52bf9 100644
--- a/chromium/components/viz/service/display/overlay_strategy_fullscreen.cc
+++ b/chromium/components/viz/service/display/overlay_strategy_fullscreen.cc
@@ -69,8 +69,8 @@ bool OverlayStrategyFullscreen::Attempt(
return true;
}
-OverlayProcessor::StrategyType OverlayStrategyFullscreen::GetUMAEnum() const {
- return OverlayProcessor::StrategyType::kFullscreen;
+OverlayStrategy OverlayStrategyFullscreen::GetUMAEnum() const {
+ return OverlayStrategy::kFullscreen;
}
} // namespace viz
diff --git a/chromium/components/viz/service/display/overlay_strategy_fullscreen.h b/chromium/components/viz/service/display/overlay_strategy_fullscreen.h
index 3a98a80ca45..a3a76a98b01 100644
--- a/chromium/components/viz/service/display/overlay_strategy_fullscreen.h
+++ b/chromium/components/viz/service/display/overlay_strategy_fullscreen.h
@@ -30,7 +30,7 @@ class VIZ_SERVICE_EXPORT OverlayStrategyFullscreen
OverlayCandidateList* candidate_list,
std::vector<gfx::Rect>* content_bounds) override;
- OverlayProcessor::StrategyType GetUMAEnum() const override;
+ OverlayStrategy GetUMAEnum() const override;
private:
OverlayCandidateValidator* capability_checker_; // Weak.
diff --git a/chromium/components/viz/service/display/overlay_strategy_single_on_top.cc b/chromium/components/viz/service/display/overlay_strategy_single_on_top.cc
index 758e629bcb7..03e711880c0 100644
--- a/chromium/components/viz/service/display/overlay_strategy_single_on_top.cc
+++ b/chromium/components/viz/service/display/overlay_strategy_single_on_top.cc
@@ -75,8 +75,8 @@ bool OverlayStrategySingleOnTop::TryOverlay(
return false;
}
-OverlayProcessor::StrategyType OverlayStrategySingleOnTop::GetUMAEnum() const {
- return OverlayProcessor::StrategyType::kSingleOnTop;
+OverlayStrategy OverlayStrategySingleOnTop::GetUMAEnum() const {
+ return OverlayStrategy::kSingleOnTop;
}
} // namespace viz
diff --git a/chromium/components/viz/service/display/overlay_strategy_single_on_top.h b/chromium/components/viz/service/display/overlay_strategy_single_on_top.h
index 91ce21ed69c..dd9f28e12d3 100644
--- a/chromium/components/viz/service/display/overlay_strategy_single_on_top.h
+++ b/chromium/components/viz/service/display/overlay_strategy_single_on_top.h
@@ -28,7 +28,7 @@ class VIZ_SERVICE_EXPORT OverlayStrategySingleOnTop
OverlayCandidateList* candidate_list,
std::vector<gfx::Rect>* content_bounds) override;
- OverlayProcessor::StrategyType GetUMAEnum() const override;
+ OverlayStrategy GetUMAEnum() const override;
private:
bool TryOverlay(QuadList* quad_list,
diff --git a/chromium/components/viz/service/display/overlay_strategy_underlay.cc b/chromium/components/viz/service/display/overlay_strategy_underlay.cc
index 40be03004ce..86be7fd7eee 100644
--- a/chromium/components/viz/service/display/overlay_strategy_underlay.cc
+++ b/chromium/components/viz/service/display/overlay_strategy_underlay.cc
@@ -100,8 +100,8 @@ bool OverlayStrategyUnderlay::Attempt(
return false;
}
-OverlayProcessor::StrategyType OverlayStrategyUnderlay::GetUMAEnum() const {
- return OverlayProcessor::StrategyType::kUnderlay;
+OverlayStrategy OverlayStrategyUnderlay::GetUMAEnum() const {
+ return OverlayStrategy::kUnderlay;
}
} // namespace viz
diff --git a/chromium/components/viz/service/display/overlay_strategy_underlay.h b/chromium/components/viz/service/display/overlay_strategy_underlay.h
index 5ccce6c20fb..338b8f752a9 100644
--- a/chromium/components/viz/service/display/overlay_strategy_underlay.h
+++ b/chromium/components/viz/service/display/overlay_strategy_underlay.h
@@ -44,7 +44,7 @@ class VIZ_SERVICE_EXPORT OverlayStrategyUnderlay
OverlayCandidateList* candidate_list,
std::vector<gfx::Rect>* content_bounds) override;
- OverlayProcessor::StrategyType GetUMAEnum() const override;
+ OverlayStrategy GetUMAEnum() const override;
private:
OverlayCandidateValidator* capability_checker_; // Weak.
diff --git a/chromium/components/viz/service/display/overlay_strategy_underlay_cast.cc b/chromium/components/viz/service/display/overlay_strategy_underlay_cast.cc
index e55968ae249..6378ec1cf53 100644
--- a/chromium/components/viz/service/display/overlay_strategy_underlay_cast.cc
+++ b/chromium/components/viz/service/display/overlay_strategy_underlay_cast.cc
@@ -6,9 +6,10 @@
#include "base/containers/adapters.h"
#include "base/lazy_instance.h"
+#include "base/unguessable_token.h"
#include "components/viz/common/quads/draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "ui/gfx/geometry/rect_conversions.h"
namespace viz {
@@ -54,10 +55,11 @@ bool OverlayStrategyUnderlayCast::Attempt(
// sitting underneath the primary plane. This is only looking at where the
// quad is supposed to be to replace it with a transparent quad to allow
// the underlay to be visible.
+ // VIDEO_HOLE implies it requires overlay.
is_underlay =
+ quad->material == DrawQuad::VIDEO_HOLE &&
OverlayCandidate::FromDrawQuad(resource_provider, output_color_matrix,
- quad, &candidate) &&
- OverlayCandidate::RequiresOverlay(quad);
+ quad, &candidate);
found_underlay = is_underlay;
}
@@ -90,11 +92,18 @@ bool OverlayStrategyUnderlayCast::Attempt(
for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
OverlayCandidate candidate;
- if (!OverlayCandidate::FromDrawQuad(
+ if (it->material != DrawQuad::VIDEO_HOLE ||
+ !OverlayCandidate::FromDrawQuad(
resource_provider, output_color_matrix, *it, &candidate)) {
continue;
}
+ // TODO(guohuideng): activate overlay through MediaServe when it's
+ // ready, using |overlay_plane_id|. see b/79266094.
+ base::UnguessableToken overlay_plane_id =
+ VideoHoleDrawQuad::MaterialCast(*it)->overlay_plane_id;
+ ANALYZER_ALLOW_UNUSED(overlay_plane_id);
+
render_pass->quad_list.ReplaceExistingQuadWithOpaqueTransparentSolidColor(
it);
@@ -102,7 +111,6 @@ bool OverlayStrategyUnderlayCast::Attempt(
g_overlay_composited_callback.Get().Run(candidate.display_rect,
candidate.transform);
}
-
break;
}
}
@@ -114,8 +122,8 @@ bool OverlayStrategyUnderlayCast::Attempt(
return found_underlay;
}
-OverlayProcessor::StrategyType OverlayStrategyUnderlayCast::GetUMAEnum() const {
- return OverlayProcessor::StrategyType::kUnderlayCast;
+OverlayStrategy OverlayStrategyUnderlayCast::GetUMAEnum() const {
+ return OverlayStrategy::kUnderlayCast;
}
// static
diff --git a/chromium/components/viz/service/display/overlay_strategy_underlay_cast.h b/chromium/components/viz/service/display/overlay_strategy_underlay_cast.h
index 1040e08e573..284df817cdd 100644
--- a/chromium/components/viz/service/display/overlay_strategy_underlay_cast.h
+++ b/chromium/components/viz/service/display/overlay_strategy_underlay_cast.h
@@ -38,7 +38,7 @@ class VIZ_SERVICE_EXPORT OverlayStrategyUnderlayCast
base::RepeatingCallback<void(const gfx::RectF&, gfx::OverlayTransform)>;
static void SetOverlayCompositedCallback(const OverlayCompositedCallback& cb);
- OverlayProcessor::StrategyType GetUMAEnum() const override;
+ OverlayStrategy GetUMAEnum() const override;
private:
// Keep track if an overlay is being used on the previous frame.
diff --git a/chromium/components/viz/service/display/overlay_unittest.cc b/chromium/components/viz/service/display/overlay_unittest.cc
index 8a7cc7c2f3b..dd71b44894b 100644
--- a/chromium/components/viz/service/display/overlay_unittest.cc
+++ b/chromium/components/viz/service/display/overlay_unittest.cc
@@ -7,8 +7,10 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/test/scoped_feature_list.h"
+#include "base/unguessable_token.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/resource_provider_test_utils.h"
@@ -18,6 +20,7 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/stream_video_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/service/display/ca_layer_overlay.h"
#include "components/viz/service/display/display_resource_provider.h"
@@ -34,6 +37,7 @@
#include "components/viz/test/test_context_provider.h"
#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
+#include "gpu/config/gpu_finch_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -204,12 +208,6 @@ class OverlayOutputSurface : public OutputSurface {
bool has_alpha,
bool use_stencil) override {}
void SwapBuffers(OutputSurfaceFrame frame) override {}
-#if BUILDFLAG(ENABLE_VULKAN)
- gpu::VulkanSurface* GetVulkanSurface() override {
- NOTREACHED();
- return nullptr;
- }
-#endif
uint32_t GetFramebufferCopyTextureFormat() override {
// TestContextProvider has no real framebuffer, just use RGB.
return GL_RGB;
@@ -253,6 +251,7 @@ std::unique_ptr<RenderPass> CreateRenderPass() {
SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
shared_state->opacity = 1.f;
+ shared_state->has_surface_damage = true;
return pass;
}
@@ -368,6 +367,19 @@ TextureDrawQuad* CreateCandidateQuadAt(
shared_quad_state, render_pass, rect, ui::ProtectedVideoType::kClear);
}
+// For Cast we use VideoHoleDrawQuad, and that's what overlay_processor_
+// expects.
+VideoHoleDrawQuad* CreateVideoHoleDrawQuadAt(
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass,
+ const gfx::Rect& rect) {
+ base::UnguessableToken overlay_plane_id = base::UnguessableToken::Create();
+ auto* overlay_quad =
+ render_pass->CreateAndAppendDrawQuad<VideoHoleDrawQuad>();
+ overlay_quad->SetNew(shared_quad_state, rect, rect, overlay_plane_id);
+ return overlay_quad;
+}
+
TextureDrawQuad* CreateTransparentCandidateQuadAt(
DisplayResourceProvider* parent_resource_provider,
ClientResourceProvider* child_resource_provider,
@@ -397,29 +409,6 @@ TextureDrawQuad* CreateTransparentCandidateQuadAt(
return overlay_quad;
}
-StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
- DisplayResourceProvider* parent_resource_provider,
- ClientResourceProvider* child_resource_provider,
- ContextProvider* child_context_provider,
- const SharedQuadState* shared_quad_state,
- RenderPass* render_pass,
- const gfx::Rect& rect,
- const gfx::Transform& transform) {
- bool needs_blending = false;
- gfx::Size resource_size_in_pixels = rect.size();
- bool is_overlay_candidate = true;
- ResourceId resource_id = CreateResource(
- parent_resource_provider, child_resource_provider, child_context_provider,
- resource_size_in_pixels, is_overlay_candidate);
-
- auto* overlay_quad =
- render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
- overlay_quad->SetNew(shared_quad_state, rect, rect, needs_blending,
- resource_id, resource_size_in_pixels, transform);
-
- return overlay_quad;
-}
-
TextureDrawQuad* CreateFullscreenCandidateQuad(
DisplayResourceProvider* parent_resource_provider,
ClientResourceProvider* child_resource_provider,
@@ -431,18 +420,6 @@ TextureDrawQuad* CreateFullscreenCandidateQuad(
shared_quad_state, render_pass, render_pass->output_rect);
}
-StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
- DisplayResourceProvider* parent_resource_provider,
- ClientResourceProvider* child_resource_provider,
- ContextProvider* child_context_provider,
- const SharedQuadState* shared_quad_state,
- RenderPass* render_pass,
- const gfx::Transform& transform) {
- return CreateCandidateVideoQuadAt(
- parent_resource_provider, child_resource_provider, child_context_provider,
- shared_quad_state, render_pass, render_pass->output_rect, transform);
-}
-
YUVVideoDrawQuad* CreateFullscreenCandidateYUVVideoQuad(
DisplayResourceProvider* parent_resource_provider,
ClientResourceProvider* child_resource_provider,
@@ -1057,7 +1034,46 @@ TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
TextureDrawQuad* quad = CreateFullscreenCandidateQuad(
resource_provider_.get(), child_resource_provider_.get(),
child_provider_.get(), pass->shared_quad_state_list.back(), pass.get());
+ quad->background_color = SK_ColorRED;
+
+ OverlayCandidateList candidate_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &candidate_list,
+ nullptr, nullptr, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AcceptBlackBackgroundColor) {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* quad = CreateFullscreenCandidateQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), pass->shared_quad_state_list.back(), pass.get());
+ quad->background_color = SK_ColorBLACK;
+
+ OverlayCandidateList candidate_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &candidate_list,
+ nullptr, nullptr, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(1U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBlackBackgroundColorWithBlending) {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* quad = CreateFullscreenCandidateQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), pass->shared_quad_state_list.back(), pass.get());
quad->background_color = SK_ColorBLACK;
+ quad->needs_blending = true;
OverlayCandidateList candidate_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
@@ -1545,101 +1561,6 @@ TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
EXPECT_EQ(0U, candidate_list.size());
}
-TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
- std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateFullscreenCandidateVideoQuad(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kSwapTransform);
-
- OverlayCandidateList candidate_list;
- OverlayProcessor::FilterOperationsMap render_pass_filters;
- OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
- overlay_processor_->ProcessForOverlays(
- resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
- render_pass_filters, render_pass_backdrop_filters, &candidate_list,
- nullptr, nullptr, &damage_rect_, &content_bounds_);
- EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(UnderlayTest, AllowVideoXMirrorTransform) {
- std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateFullscreenCandidateVideoQuad(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kXMirrorTransform);
-
- OverlayCandidateList candidate_list;
- OverlayProcessor::FilterOperationsMap render_pass_filters;
- OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
- overlay_processor_->ProcessForOverlays(
- resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
- render_pass_filters, render_pass_backdrop_filters, &candidate_list,
- nullptr, nullptr, &damage_rect_, &content_bounds_);
- EXPECT_EQ(1U, candidate_list.size());
-}
-
-TEST_F(UnderlayTest, AllowVideoBothMirrorTransform) {
- std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateFullscreenCandidateVideoQuad(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kBothMirrorTransform);
-
- OverlayCandidateList candidate_list;
- OverlayProcessor::FilterOperationsMap render_pass_filters;
- OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
- overlay_processor_->ProcessForOverlays(
- resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
- render_pass_filters, render_pass_backdrop_filters, &candidate_list,
- nullptr, nullptr, &damage_rect_, &content_bounds_);
- EXPECT_EQ(1U, candidate_list.size());
-}
-
-TEST_F(UnderlayTest, AllowVideoNormalTransform) {
- std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateFullscreenCandidateVideoQuad(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kNormalTransform);
-
- OverlayCandidateList candidate_list;
- OverlayProcessor::FilterOperationsMap render_pass_filters;
- OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
- overlay_processor_->ProcessForOverlays(
- resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
- render_pass_filters, render_pass_backdrop_filters, &candidate_list,
- nullptr, nullptr, &damage_rect_, &content_bounds_);
- EXPECT_EQ(1U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
- std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateFullscreenCandidateVideoQuad(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kYMirrorTransform);
-
- OverlayCandidateList candidate_list;
- OverlayProcessor::FilterOperationsMap render_pass_filters;
- OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
- overlay_processor_->ProcessForOverlays(
- resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
- render_pass_filters, render_pass_backdrop_filters, &candidate_list,
- nullptr, nullptr, &damage_rect_, &content_bounds_);
- EXPECT_EQ(1U, candidate_list.size());
-}
-
TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
output_surface_->GetOverlayCandidateValidator()->AddExpectedRect(
gfx::RectF(kOverlayBottomRightRect));
@@ -2022,6 +1943,46 @@ TEST_F(UnderlayTest, UpdateDamageRectWhenNoPromotion) {
}
}
+// Tests that no damage occurs due to unchanged elements on top of HW underlays
+TEST_F(UnderlayTest, DamageSubtractedWhenElementsOnHwUnderlayNotChanged) {
+ for (int i = 0; i < 2; ++i) {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+
+ gfx::Rect rect(2, 3);
+ SharedQuadState* non_damaged_quad_state =
+ pass->shared_quad_state_list.AllocateAndCopyFrom(
+ pass->shared_quad_state_list.back());
+ // Element on top has not changed (no damage caused by this quad)
+ non_damaged_quad_state->has_surface_damage = false;
+ CreateSolidColorQuadAt(non_damaged_quad_state, SK_ColorBLACK, pass.get(),
+ rect);
+
+ CreateFullscreenCandidateQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), pass->shared_quad_state_list.front(),
+ pass.get());
+
+ damage_rect_ = kOverlayRect;
+
+ OverlayCandidateList candidate_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &candidate_list,
+ nullptr, nullptr, &damage_rect_, &content_bounds_);
+
+ // The damage rect should not be subtracted on the first frame
+ if (i == 0)
+ EXPECT_FALSE(damage_rect_.IsEmpty());
+ }
+ // As the UI on top of the underlay persists and does not change, damage
+ // should be subtracted.
+ EXPECT_TRUE(damage_rect_.IsEmpty());
+}
+
TEST_F(UnderlayCastTest, NoOverlayContentBounds) {
std::unique_ptr<RenderPass> pass = CreateRenderPass();
@@ -2043,10 +2004,8 @@ TEST_F(UnderlayCastTest, NoOverlayContentBounds) {
TEST_F(UnderlayCastTest, FullScreenOverlayContentBounds) {
std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kOverlayRect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayRect);
OverlayCandidateList candidate_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
@@ -2070,10 +2029,8 @@ TEST_F(UnderlayCastTest, BlackOutsideOverlayContentBounds) {
const gfx::Rect kTopRight(128, 0, 128, 128);
std::unique_ptr<RenderPass> pass = CreateRenderPass();
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kOverlayBottomRightRect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayBottomRightRect);
CreateOpaqueQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(), kLeftSide,
SK_ColorBLACK);
@@ -2100,10 +2057,8 @@ TEST_F(UnderlayCastTest, OverlayOccludedContentBounds) {
CreateOpaqueQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(),
kOverlayTopLeftRect);
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kOverlayRect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayRect);
OverlayCandidateList candidate_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
@@ -2127,10 +2082,8 @@ TEST_F(UnderlayCastTest, OverlayOccludedUnionContentBounds) {
CreateOpaqueQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(),
kOverlayBottomRightRect);
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kOverlayRect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayRect);
OverlayCandidateList candidate_list;
OverlayProcessor::FilterOperationsMap render_pass_filters;
@@ -2157,10 +2110,8 @@ TEST_F(UnderlayCastTest, RoundOverlayContentBounds) {
transform.Translate(0.5f, 0.5f);
std::unique_ptr<RenderPass> pass = CreateRenderPassWithTransform(transform);
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- overlay_rect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ overlay_rect);
CreateOpaqueQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(),
gfx::Rect(0, 0, 10, 10), SK_ColorWHITE);
@@ -2191,10 +2142,8 @@ TEST_F(UnderlayCastTest, RoundContentBounds) {
transform.Translate(0.5f, 0.5f);
std::unique_ptr<RenderPass> pass = CreateRenderPassWithTransform(transform);
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- overlay_rect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ overlay_rect);
CreateOpaqueQuadAt(resource_provider_.get(),
pass->shared_quad_state_list.back(), pass.get(),
gfx::Rect(0, 0, 255, 255), SK_ColorWHITE);
@@ -2220,10 +2169,8 @@ TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) {
pass->shared_quad_state_list.back(), pass.get(),
output_rect, SK_ColorWHITE);
- CreateCandidateQuadAt(
- resource_provider_.get(), child_resource_provider_.get(),
- child_provider_.get(), pass->shared_quad_state_list.back(), pass.get(),
- kOverlayRect, ui::ProtectedVideoType::kHardwareProtected);
+ CreateVideoHoleDrawQuadAt(pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayRect);
OverlayCandidateList candidate_list;
OverlayCandidate candidate;
@@ -2504,7 +2451,8 @@ TEST_F(DCLayerOverlayTest, Occluded) {
EXPECT_EQ(0U, overlay_list.size());
EXPECT_EQ(2U, dc_layer_list.size());
EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
- EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ EXPECT_EQ(-1, dc_layer_list.front().z_order);
+ EXPECT_EQ(-2, dc_layer_list.back().z_order);
// Entire underlay rect must be redrawn.
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), damage_rect_);
}
@@ -2539,11 +2487,174 @@ TEST_F(DCLayerOverlayTest, Occluded) {
EXPECT_EQ(0U, overlay_list.size());
EXPECT_EQ(2U, dc_layer_list.size());
EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
- EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ EXPECT_EQ(-1, dc_layer_list.front().z_order);
+ EXPECT_EQ(-2, dc_layer_list.back().z_order);
// The underlay rectangle is the same, so the damage for first video quad is
// contained within the combined occluding rects for this and the last
// frame. Second video quad also adds its damage.
- EXPECT_EQ(gfx::Rect(1, 2, 255, 254), damage_rect_);
+
+ // This is calculated by carving out the underlay rect size from the
+ // damage_rect, adding back the quads on top and then the overlay/underlay
+ // rects from the previous frame. The damage rect carried over from the
+ // revious frame with multiple overlays cannot be skipped.
+ EXPECT_EQ(gfx::Rect(0, 0, 256, 256), damage_rect_);
+ }
+}
+
+TEST_F(DCLayerOverlayTest, DamageRectWithoutVideoDamage) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kDirectCompositionUnderlays);
+ {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+ // Occluding quad fully contained in video rect.
+ CreateOpaqueQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ gfx::Rect(0, 3, 100, 100), SK_ColorWHITE);
+ // Non-occluding quad fully outside video rect
+ CreateOpaqueQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ gfx::Rect(210, 210, 20, 20), SK_ColorWHITE);
+ // Underlay video quad
+ auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), pass->shared_quad_state_list.back(), pass.get());
+ video_quad->rect = gfx::Rect(0, 0, 200, 200);
+ video_quad->visible_rect = video_quad->rect;
+
+ DCLayerOverlayList dc_layer_list;
+ OverlayCandidateList overlay_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ // Damage rect fully outside video quad
+ damage_rect_ = gfx::Rect(210, 210, 20, 20);
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &overlay_list,
+ nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, overlay_list.size());
+ EXPECT_EQ(1U, dc_layer_list.size());
+ EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
+ EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ // All rects must be redrawn at the first frame.
+ EXPECT_EQ(gfx::Rect(0, 0, 230, 230), damage_rect_);
+ }
+ {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+ // Occluding quad fully contained in video rect.
+ CreateOpaqueQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ gfx::Rect(0, 3, 100, 100), SK_ColorWHITE);
+ // Non-occluding quad fully outside video rect
+ CreateOpaqueQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ gfx::Rect(210, 210, 20, 20), SK_ColorWHITE);
+ // Underlay video quad
+ auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), pass->shared_quad_state_list.back(), pass.get());
+ video_quad->rect = gfx::Rect(0, 0, 200, 200);
+ video_quad->visible_rect = video_quad->rect;
+
+ DCLayerOverlayList dc_layer_list;
+ OverlayCandidateList overlay_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ // Damage rect fully outside video quad
+ damage_rect_ = gfx::Rect(210, 210, 20, 20);
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &overlay_list,
+ nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, overlay_list.size());
+ EXPECT_EQ(1U, dc_layer_list.size());
+ EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
+ EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ // Only the non-overlay damaged rect need to be drawn by the gl compositor
+ EXPECT_EQ(gfx::Rect(210, 210, 20, 20), damage_rect_);
+ }
+}
+
+TEST_F(DCLayerOverlayTest, DamageRectWithNonRootOverlay) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures({features::kDirectCompositionUnderlays,
+ features::kDirectCompositionNonrootOverlays},
+ {});
+ {
+ // A root solid quad
+ std::unique_ptr<RenderPass> root_pass = CreateRenderPass();
+ CreateOpaqueQuadAt(
+ resource_provider_.get(), root_pass->shared_quad_state_list.back(),
+ root_pass.get(), gfx::Rect(210, 0, 20, 20), SK_ColorWHITE);
+
+ // A non-root video quad
+ std::unique_ptr<RenderPass> nonroot_pass = CreateRenderPass();
+ auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), nonroot_pass->shared_quad_state_list.back(),
+ nonroot_pass.get());
+ video_quad->rect = gfx::Rect(0, 0, 200, 200);
+ video_quad->visible_rect = video_quad->rect;
+
+ DCLayerOverlayList dc_layer_list;
+ OverlayCandidateList overlay_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ // Damage rect fully outside video quad
+ damage_rect_ = gfx::Rect(210, 0, 20, 20);
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(nonroot_pass));
+ pass_list.push_back(std::move(root_pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &overlay_list,
+ nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, overlay_list.size());
+ EXPECT_EQ(1U, dc_layer_list.size());
+ EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
+ EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ // damage_rect returned from ProcessForOverlays() is for root render pass
+ // only. Non-root damage rect is not included.
+ EXPECT_EQ(gfx::Rect(210, 0, 20, 20), damage_rect_);
+ }
+ {
+ // A root solid quad
+ std::unique_ptr<RenderPass> root_pass = CreateRenderPass();
+ CreateOpaqueQuadAt(
+ resource_provider_.get(), root_pass->shared_quad_state_list.back(),
+ root_pass.get(), gfx::Rect(210, 0, 20, 20), SK_ColorWHITE);
+
+ // A non-root video quad
+ std::unique_ptr<RenderPass> nonroot_pass = CreateRenderPass();
+ auto* video_quad = CreateFullscreenCandidateYUVVideoQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), nonroot_pass->shared_quad_state_list.back(),
+ nonroot_pass.get());
+ video_quad->rect = gfx::Rect(0, 0, 200, 200);
+ video_quad->visible_rect = video_quad->rect;
+
+ DCLayerOverlayList dc_layer_list;
+ OverlayCandidateList overlay_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ // Damage rect fully outside video quad
+ damage_rect_ = gfx::Rect(210, 0, 20, 20);
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(nonroot_pass));
+ pass_list.push_back(std::move(root_pass));
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &overlay_list,
+ nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, overlay_list.size());
+ EXPECT_EQ(1U, dc_layer_list.size());
+ EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
+ EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ // Nonroot damage_rect from the previous frame should be added to this frame
+ EXPECT_EQ(gfx::Rect(0, 0, 230, 200), damage_rect_);
}
}
@@ -2672,8 +2783,10 @@ TEST_F(DCLayerOverlayTest, MultiplePassDamageRect) {
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), pass_list[0]->damage_rect);
EXPECT_EQ(gfx::Rect(), pass_list[1]->damage_rect);
EXPECT_EQ(gfx::Rect(0, 100, 256, 156), root_damage_rect);
+ // Overlay damage handling is done entirely within DCOverlayProcessor so this
+ // is expected to return an empty rect
gfx::Rect overlay_damage = overlay_processor_->GetAndResetOverlayDamage();
- EXPECT_EQ(gfx::Rect(0, 100, 256, 256), overlay_damage);
+ EXPECT_EQ(gfx::Rect(0, 0, 0, 0), overlay_damage);
EXPECT_EQ(1u, pass_list[0]->quad_list.size());
EXPECT_EQ(DrawQuad::SOLID_COLOR,
@@ -2801,6 +2914,56 @@ TEST_F(DCLayerOverlayTest, TransparentOnTop) {
}
}
+TEST_F(DCLayerOverlayTest, UnderlayDamageRectWithQuadOnTopUnchanged) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kDirectCompositionUnderlays);
+
+ for (int i = 0; i < 3; i++) {
+ std::unique_ptr<RenderPass> pass = CreateRenderPass();
+ // Add a solid color quad on top
+ SharedQuadState* shared_state_on_top = pass->shared_quad_state_list.back();
+ CreateSolidColorQuadAt(shared_state_on_top, SK_ColorRED, pass.get(),
+ kOverlayBottomRightRect);
+
+ SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 1.f;
+ CreateFullscreenCandidateYUVVideoQuad(
+ resource_provider_.get(), child_resource_provider_.get(),
+ child_provider_.get(), shared_state, pass.get());
+
+ DCLayerOverlayList dc_layer_list;
+ OverlayCandidateList overlay_list;
+ OverlayProcessor::FilterOperationsMap render_pass_filters;
+ OverlayProcessor::FilterOperationsMap render_pass_backdrop_filters;
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+ gfx::Rect damage_rect_ = kOverlayRect;
+
+ // The quad on top does not give damage on the third frame
+ if (i == 2)
+ shared_state_on_top->has_surface_damage = false;
+ else
+ shared_state_on_top->has_surface_damage = true;
+
+ overlay_processor_->ProcessForOverlays(
+ resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
+ render_pass_filters, render_pass_backdrop_filters, &overlay_list,
+ nullptr, &dc_layer_list, &damage_rect_, &content_bounds_);
+ EXPECT_EQ(0U, overlay_list.size());
+ EXPECT_EQ(1U, dc_layer_list.size());
+ EXPECT_EQ(0U, output_surface_->bind_framebuffer_count());
+ EXPECT_EQ(-1, dc_layer_list.back().z_order);
+ // Damage rect should be unchanged on initial frame, but should be reduced
+ // to the size of quad on top, and empty on the third frame.
+ if (i == 0)
+ EXPECT_EQ(kOverlayRect, damage_rect_);
+ else if (i == 1)
+ EXPECT_EQ(kOverlayBottomRightRect, damage_rect_);
+ else if (i == 2)
+ EXPECT_EQ(gfx::Rect(), damage_rect_);
+ }
+}
+
class OverlayInfoRendererGL : public GLRenderer {
public:
OverlayInfoRendererGL(const RendererSettings* settings,
diff --git a/chromium/components/viz/service/display/renderer_pixeltest.cc b/chromium/components/viz/service/display/renderer_pixeltest.cc
index aadc7a741ca..22feb9fda90 100644
--- a/chromium/components/viz/service/display/renderer_pixeltest.cc
+++ b/chromium/components/viz/service/display/renderer_pixeltest.cc
@@ -7,6 +7,8 @@
#include <memory>
#include <tuple>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/memory/aligned_memory.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
@@ -847,7 +849,7 @@ using RendererTypes =
SkiaRenderer,
cc::GLRendererWithExpandedViewport,
cc::SoftwareRendererWithExpandedViewport>;
-TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
+TYPED_TEST_SUITE(RendererPixelTest, RendererTypes);
template <typename RendererType>
class SoftwareRendererPixelTest : public cc::RendererPixelTest<RendererType> {};
@@ -855,7 +857,7 @@ class SoftwareRendererPixelTest : public cc::RendererPixelTest<RendererType> {};
using SoftwareRendererTypes =
::testing::Types<SoftwareRenderer,
cc::SoftwareRendererWithExpandedViewport>;
-TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
+TYPED_TEST_SUITE(SoftwareRendererPixelTest, SoftwareRendererTypes);
// TODO(weiliangc): Move these tests to normal RendererPixelTest as they pass
// with SkiaRenderer. Failed test list recorded in crbug.com/821176.
@@ -867,7 +869,15 @@ using NonSkiaRendererTypes =
SoftwareRenderer,
cc::GLRendererWithExpandedViewport,
cc::SoftwareRendererWithExpandedViewport>;
-TYPED_TEST_CASE(NonSkiaRendererPixelTest, NonSkiaRendererTypes);
+TYPED_TEST_SUITE(NonSkiaRendererPixelTest, NonSkiaRendererTypes);
+
+// Test GLRenderer as well as SkiaRenderer.
+template <typename RendererType>
+class GLCapableRendererPixelTest : public cc::RendererPixelTest<RendererType> {
+};
+
+using GLCapableRendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
+TYPED_TEST_SUITE(GLCapableRendererPixelTest, GLCapableRendererTypes);
template <typename RendererType>
class FuzzyForSoftwareOnlyPixelComparator : public cc::PixelComparator {
@@ -1239,11 +1249,13 @@ class IntersectingQuadGLPixelTest
constexpr int kMaxResourceSize = 10000;
video_resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
- this->child_context_provider_.get(), nullptr,
+ this->child_context_provider_.get(),
+ /*raster_context_provider=*/nullptr, nullptr,
this->child_resource_provider_.get(), kUseStreamVideoDrawQuad,
kUseGpuMemoryBufferResources, kUseR16Texture, kMaxResourceSize);
video_resource_updater2_ = std::make_unique<media::VideoResourceUpdater>(
- this->child_context_provider_.get(), nullptr,
+ this->child_context_provider_.get(),
+ /*raster_context_provider=*/nullptr, nullptr,
this->child_resource_provider_.get(), kUseStreamVideoDrawQuad,
kUseGpuMemoryBufferResources, kUseR16Texture, kMaxResourceSize);
}
@@ -1263,9 +1275,9 @@ using SoftwareRendererTypes =
using GLRendererTypes =
::testing::Types<GLRenderer, cc::GLRendererWithExpandedViewport>;
-TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
-TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
-TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
+TYPED_TEST_SUITE(IntersectingQuadPixelTest, RendererTypes);
+TYPED_TEST_SUITE(IntersectingQuadGLPixelTest, GLRendererTypes);
+TYPED_TEST_SUITE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
this->SetupQuadStateAndRenderPass();
@@ -1595,8 +1607,14 @@ TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
cc::FuzzyPixelOffByOneComparator(true)));
}
-class VideoGLRendererPixelTest : public cc::GLRendererPixelTest {
+template <typename RendererType>
+class VideoRendererPixelTest : public cc::RendererPixelTest<RendererType> {
protected:
+ // Include the protected member variables from the parent class.
+ using cc::PixelTest::child_context_provider_;
+ using cc::PixelTest::child_resource_provider_;
+ using cc::PixelTest::resource_provider_;
+
void CreateEdgeBleedPass(media::VideoPixelFormat format,
const gfx::ColorSpace& color_space,
RenderPassList* pass_list) {
@@ -1636,86 +1654,114 @@ class VideoGLRendererPixelTest : public cc::GLRendererPixelTest {
}
void SetUp() override {
- GLRendererPixelTest::SetUp();
+ cc::RendererPixelTest<RendererType>::SetUp();
constexpr bool kUseStreamVideoDrawQuad = false;
constexpr bool kUseGpuMemoryBufferResources = false;
constexpr bool kUseR16Texture = false;
constexpr int kMaxResourceSize = 10000;
video_resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
- child_context_provider_.get(), nullptr, child_resource_provider_.get(),
- kUseStreamVideoDrawQuad, kUseGpuMemoryBufferResources, kUseR16Texture,
- kMaxResourceSize);
+ child_context_provider_.get(), nullptr, nullptr,
+ child_resource_provider_.get(), kUseStreamVideoDrawQuad,
+ kUseGpuMemoryBufferResources, kUseR16Texture, kMaxResourceSize);
}
void TearDown() override {
video_resource_updater_ = nullptr;
- GLRendererPixelTest::TearDown();
+ cc::RendererPixelTest<RendererType>::TearDown();
}
std::unique_ptr<media::VideoResourceUpdater> video_resource_updater_;
};
-class VideoGLRendererPixelHiLoTest : public VideoGLRendererPixelTest,
- public testing::WithParamInterface<bool> {
+TYPED_TEST_SUITE(VideoRendererPixelTest, GLCapableRendererTypes);
+
+// TODO(crbug.com/936822): Remove this once it passes with SkiaRenderer.
+using VideoGLRendererPixelTest = VideoRendererPixelTest<GLRenderer>;
+
+template <typename RendererType>
+class VideoRendererPixelHiLoTest : public VideoRendererPixelTest<RendererType>,
+ public testing::WithParamInterface<bool> {
public:
bool IsHighbit() const { return GetParam(); }
-};
-TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
- gfx::Rect rect(this->device_viewport_size_);
+ void SimpleYUVRect() {
+ gfx::Rect rect(this->device_viewport_size_);
- int id = 1;
- std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
- // Set the output color space to match the input primaries and transfer.
- pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M,
- gfx::ColorSpace::TransferID::SMPTE170M);
+ int id = 1;
+ std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+ // Set the output color space to match the input primaries and transfer.
+ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M,
+ gfx::ColorSpace::TransferID::SMPTE170M);
- SharedQuadState* shared_state =
- CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
- CreateTestYUVVideoDrawQuad_Striped(
- shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
- false, IsHighbit(), gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ CreateTestYUVVideoDrawQuad_Striped(
+ shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
+ false, IsHighbit(), gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
- EXPECT_TRUE(this->RunPixelTest(
- &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
- cc::FuzzyPixelOffByOneComparator(true)));
-}
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
+ cc::FuzzyPixelOffByOneComparator(true)));
+ }
+ void ClippedYUVRect() {
+ gfx::Rect viewport(this->device_viewport_size_);
+ gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
+ this->device_viewport_size_.height() * 1.5);
-TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
- gfx::Rect viewport(this->device_viewport_size_);
- gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
- this->device_viewport_size_.height() * 1.5);
+ int id = 1;
+ std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
+ // Set the output color space to match the input primaries and transfer.
+ pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M,
+ gfx::ColorSpace::TransferID::SMPTE170M);
- int id = 1;
- std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
- // Set the output color space to match the input primaries and transfer.
- pass->color_space = gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE170M,
- gfx::ColorSpace::TransferID::SMPTE170M);
+ SharedQuadState* shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
+
+ CreateTestYUVVideoDrawQuad_Striped(
+ shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
+ false, IsHighbit(), gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
+ this->video_resource_updater_.get(), draw_rect, viewport,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
+ RenderPassList pass_list;
+ pass_list.push_back(std::move(pass));
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
+ cc::FuzzyPixelOffByOneComparator(true)));
+ }
+};
- SharedQuadState* shared_state =
- CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
+using VideoGLRendererPixelHiLoTest = VideoRendererPixelHiLoTest<GLRenderer>;
+using VideoSkiaRendererPixelHiLoTest = VideoRendererPixelHiLoTest<SkiaRenderer>;
- CreateTestYUVVideoDrawQuad_Striped(
- shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
- false, IsHighbit(), gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
- video_resource_updater_.get(), draw_rect, viewport,
- resource_provider_.get(), child_resource_provider_.get(),
- child_context_provider_.get());
- RenderPassList pass_list;
- pass_list.push_back(std::move(pass));
+TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
+ SimpleYUVRect();
+}
+// TODO(crbug.com/936822): Enable this test.
+TEST_P(VideoSkiaRendererPixelHiLoTest, DISABLED_SimpleYUVRect) {
+ SimpleYUVRect();
+}
- EXPECT_TRUE(this->RunPixelTest(
- &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
- cc::FuzzyPixelOffByOneComparator(true)));
+TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
+ ClippedYUVRect();
+}
+// TODO(crbug.com/936822): Enable this test.
+TEST_P(VideoSkiaRendererPixelHiLoTest, DISABLED_ClippedYUVRect) {
+ ClippedYUVRect();
}
-TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
+// TODO(crbug.com/936822): Enable this test for SkiaRenderer
+// TYPED_TEST(VideoRendererPixelTest, OffsetYUVRect) {
+TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1731,8 +1777,9 @@ TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
CreateTestYUVVideoDrawQuad_Striped(
shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
false, false, gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1742,7 +1789,7 @@ TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
cc::FuzzyPixelComparator(true, 100.0f, 1.0f, 1.0f, 1, 0)));
}
-TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
+TYPED_TEST(VideoRendererPixelTest, SimpleYUVRectBlack) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1758,8 +1805,9 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
CreateTestYUVVideoDrawQuad_Solid(
shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateREC601(),
false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1772,9 +1820,10 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
}
// First argument (test case prefix) is intentionally left empty.
-INSTANTIATE_TEST_CASE_P(, VideoGLRendererPixelHiLoTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, VideoGLRendererPixelHiLoTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, VideoSkiaRendererPixelHiLoTest, testing::Bool());
-TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
+TYPED_TEST(VideoRendererPixelTest, SimpleYUVJRect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1787,8 +1836,9 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
CreateTestYUVVideoDrawQuad_Solid(
shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateJpeg(),
false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1798,7 +1848,7 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
cc::FuzzyPixelOffByOneComparator(true)));
}
-TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) {
+TYPED_TEST(VideoRendererPixelTest, SimpleNV12JRect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1811,8 +1861,9 @@ TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) {
CreateTestYUVVideoDrawQuad_NV12(
shared_state, gfx::ColorSpace::CreateJpeg(),
gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_);
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_);
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1824,6 +1875,8 @@ TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) {
// Test that a YUV video doesn't bleed outside of its tex coords when the
// tex coord rect is only a partial subrectangle of the coded contents.
+// TODO(crbug.com/936822): Enable this test for SkiaRenderer
+// TYPED_TEST(VideoRendererPixelTest, YUVEdgeBleed) {
TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
RenderPassList pass_list;
CreateEdgeBleedPass(media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateJpeg(),
@@ -1833,6 +1886,8 @@ TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
cc::FuzzyPixelOffByOneComparator(true)));
}
+// TODO(crbug.com/936822): Enable this test for SkiaRenderer
+// TYPED_TEST(VideoRendererPixelTest, YUVAEdgeBleed) {
TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
RenderPassList pass_list;
CreateEdgeBleedPass(media::PIXEL_FORMAT_I420A,
@@ -1846,7 +1901,7 @@ TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
cc::FuzzyPixelOffByOneComparator(true)));
}
-TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
+TYPED_TEST(VideoRendererPixelTest, SimpleYUVJRectGrey) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1859,8 +1914,9 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
CreateTestYUVVideoDrawQuad_Solid(
shared_state, media::PIXEL_FORMAT_I420, gfx::ColorSpace::CreateJpeg(),
false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -1870,7 +1926,9 @@ TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
cc::FuzzyPixelOffByOneComparator(true)));
}
-TEST_F(VideoGLRendererPixelHiLoTest, SimpleYUVARect) {
+// TODO(crbug.com/936822): Enable this test for SkiaRenderer
+// TYPED_TEST(VideoRendererPixelTest, SimpleYUVARect) {
+TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1885,8 +1943,9 @@ TEST_F(VideoGLRendererPixelHiLoTest, SimpleYUVARect) {
CreateTestYUVVideoDrawQuad_Striped(
shared_state, media::PIXEL_FORMAT_I420A, gfx::ColorSpace::CreateREC601(),
false, false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
@@ -1899,7 +1958,7 @@ TEST_F(VideoGLRendererPixelHiLoTest, SimpleYUVARect) {
cc::FuzzyPixelOffByOneComparator(true)));
}
-TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
+TYPED_TEST(VideoRendererPixelTest, FullyTransparentYUVARect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1914,8 +1973,9 @@ TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
CreateTestYUVVideoDrawQuad_Striped(
shared_state, media::PIXEL_FORMAT_I420A, gfx::ColorSpace::CreateREC601(),
true, false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
- video_resource_updater_.get(), rect, rect, resource_provider_.get(),
- child_resource_provider_.get(), child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
@@ -1928,7 +1988,7 @@ TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
cc::ExactPixelComparator(true)));
}
-TEST_F(VideoGLRendererPixelTest, TwoColorY16Rect) {
+TYPED_TEST(VideoRendererPixelTest, TwoColorY16Rect) {
gfx::Rect rect(this->device_viewport_size_);
int id = 1;
@@ -1940,9 +2000,9 @@ TEST_F(VideoGLRendererPixelTest, TwoColorY16Rect) {
gfx::Rect upper_rect(rect.x(), rect.y(), rect.width(), rect.height() / 2);
CreateTestY16TextureDrawQuad_TwoColor(
shared_state, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 68, 123, pass.get(),
- video_resource_updater_.get(), rect, rect, upper_rect,
- resource_provider_.get(), child_resource_provider_.get(),
- child_context_provider_.get());
+ this->video_resource_updater_.get(), rect, rect, upper_rect,
+ this->resource_provider_.get(), this->child_resource_provider_.get(),
+ this->child_context_provider_.get());
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
@@ -2627,7 +2687,7 @@ class RendererPixelTestWithBackgroundFilter
RenderPassList pass_list_;
cc::FilterOperations backdrop_filters_;
- gfx::RectF backdrop_filter_bounds_;
+ gfx::RRectF backdrop_filter_bounds_;
gfx::Transform filter_pass_to_target_transform_;
gfx::Rect filter_pass_layer_rect_;
};
@@ -2636,8 +2696,8 @@ class RendererPixelTestWithBackgroundFilter
using BackgroundFilterRendererTypes =
::testing::Types<GLRenderer, SkiaRenderer>;
-TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
- BackgroundFilterRendererTypes);
+TYPED_TEST_SUITE(RendererPixelTestWithBackgroundFilter,
+ BackgroundFilterRendererTypes);
TYPED_TEST(RendererPixelTestWithBackgroundFilter, InvertFilter) {
this->backdrop_filters_.Append(cc::FilterOperation::CreateInvertFilter(1.f));
@@ -2647,8 +2707,8 @@ TYPED_TEST(RendererPixelTestWithBackgroundFilter, InvertFilter) {
// so the clipping bounds should be 0,0 WxH, not
// this->filter_pass_layer_rect_.
this->backdrop_filter_bounds_ =
- gfx::RectF(0, 0, this->filter_pass_layer_rect_.width(),
- this->filter_pass_layer_rect_.height());
+ gfx::RRectF(0, 0, this->filter_pass_layer_rect_.width(),
+ this->filter_pass_layer_rect_.height(), 0);
this->SetUpRenderPassList();
EXPECT_TRUE(this->RunPixelTest(
&this->pass_list_,
@@ -3055,7 +3115,7 @@ TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
}
// Trilinear filtering is only supported in the gl renderer.
-TEST_F(GLRendererPixelTest, TrilinearFiltering) {
+TYPED_TEST(GLCapableRendererPixelTest, TrilinearFiltering) {
gfx::Rect viewport_rect(this->device_viewport_size_);
int root_pass_id = 1;
@@ -3071,7 +3131,7 @@ TEST_F(GLRendererPixelTest, TrilinearFiltering) {
std::unique_ptr<RenderPass> child_pass = RenderPass::Create();
child_pass->SetAll(
child_pass_id, child_pass_rect, child_pass_rect, transform_to_root,
- cc::FilterOperations(), cc::FilterOperations(), gfx::RectF(),
+ cc::FilterOperations(), cc::FilterOperations(), gfx::RRectF(),
gfx::ColorSpace::CreateSRGB(), false, false, false, generate_mipmap);
gfx::Rect red_rect(child_pass_rect);
@@ -4030,7 +4090,7 @@ TEST_F(GLRendererPixelTestWithOverdrawFeedback, TranslucentRectangles) {
}
using SkiaRendererTypes = ::testing::Types<SkiaRenderer>;
-TYPED_TEST_CASE(SkiaRendererPixelTestWithOverdrawFeedback, SkiaRendererTypes);
+TYPED_TEST_SUITE(SkiaRendererPixelTestWithOverdrawFeedback, SkiaRendererTypes);
class SkiaRendererPixelTestWithOverdrawFeedback
: public cc::RendererPixelTest<SkiaRenderer> {
@@ -4290,14 +4350,14 @@ bool color_space_premul_values[] = {
true, false,
};
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
FromColorSpace,
ColorTransformPixelTest,
testing::Combine(testing::ValuesIn(src_color_spaces),
testing::ValuesIn(intermediate_color_spaces),
testing::ValuesIn(color_space_premul_values)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ToColorSpace,
ColorTransformPixelTest,
testing::Combine(testing::ValuesIn(intermediate_color_spaces),
diff --git a/chromium/components/viz/service/display/resource_metadata.h b/chromium/components/viz/service/display/resource_metadata.h
index ef8cb4f2f9c..a6c9bb59f41 100644
--- a/chromium/components/viz/service/display/resource_metadata.h
+++ b/chromium/components/viz/service/display/resource_metadata.h
@@ -33,6 +33,9 @@ struct VIZ_SERVICE_EXPORT ResourceMetadata {
// The color space for the resource texture.
gfx::ColorSpace color_space;
+
+ // Whether resource is premultiplied.
+ SkAlphaType alpha_type;
};
} // namespace viz
diff --git a/chromium/components/viz/service/display/skia_output_surface.h b/chromium/components/viz/service/display/skia_output_surface.h
index 3e203932d7c..b0d6480f712 100644
--- a/chromium/components/viz/service/display/skia_output_surface.h
+++ b/chromium/components/viz/service/display/skia_output_surface.h
@@ -14,7 +14,7 @@ class SkImage;
namespace gfx {
class ColorSpace;
-}
+} // namespace gfx
namespace viz {
@@ -22,6 +22,10 @@ class ContextLostObserver;
class CopyOutputRequest;
struct ResourceMetadata;
+namespace copy_output {
+struct RenderPassGeometry;
+} // namespace copy_output
+
// This class extends the OutputSurface for SkiaRenderer needs. In future, the
// SkiaRenderer will be the only renderer. When other renderers are removed,
// we will replace OutputSurface with SkiaOutputSurface, and remove all
@@ -59,13 +63,11 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface {
SkYUVColorSpace yuv_color_space,
bool has_alpha) = 0;
- // Release SkImage created by MakePromiseSkImage on the thread on which
+ // Release SkImages created by MakePromiseSkImage on the thread on which
// it was fulfilled. SyncToken represents point after which SkImage is
// released.
- virtual gpu::SyncToken QueueReleasePromiseSkImage(sk_sp<SkImage>&& image) = 0;
-
- // Flush all the queued releases. No-op if none were queued.
- virtual void FlushQueuedReleases() = 0;
+ virtual gpu::SyncToken ReleasePromiseSkImages(
+ std::vector<sk_sp<SkImage>> images) = 0;
// Swaps the current backbuffer to the screen.
virtual void SkiaSwapBuffers(OutputSurfaceFrame frame) = 0;
@@ -78,7 +80,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface {
virtual SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
const gfx::Size& size,
ResourceFormat format,
- bool mipmap) = 0;
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) = 0;
// Finish painting the current frame or current render pass, depends on which
// BeginPaint function is called last. This method will schedule a GPU task to
@@ -96,7 +99,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface {
const RenderPassId& id,
const gfx::Size& size,
ResourceFormat format,
- bool mipmap) = 0;
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) = 0;
// Remove cached resources generated by BeginPaintRenderPass and
// FinishPaintRenderPass.
@@ -105,9 +109,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface {
// Copy the output of the current frame if the |id| is zero, otherwise copy
// the output of a cached SkSurface for the given |id|.
virtual void CopyOutput(RenderPassId id,
- const gfx::Rect& copy_rect,
+ const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
- const gfx::Rect& result_rect,
std::unique_ptr<CopyOutputRequest> request) = 0;
// Add context lost observer.
diff --git a/chromium/components/viz/service/display/skia_renderer.cc b/chromium/components/viz/service/display/skia_renderer.cc
index 5a757c437d3..490ef4e2aaf 100644
--- a/chromium/components/viz/service/display/skia_renderer.cc
+++ b/chromium/components/viz/service/display/skia_renderer.cc
@@ -33,7 +33,6 @@
#include "skia/ext/opacity_filter_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkOverdrawCanvas.h"
#include "third_party/skia/include/core/SkPath.h"
@@ -70,8 +69,16 @@ bool IsTextureResource(DisplayResourceProvider* resource_provider,
return !resource_provider->IsResourceSoftwareBacked(resource_id);
}
-bool ApplyTransformAndScissorToTileRect(const gfx::Transform& transform) {
- return transform.IsPositiveScaleOrTranslation();
+bool ApplyTransformAndScissorToTileRect(
+ const gfx::Transform& contents_device_transform) {
+ // This is slightly different than
+ // gfx::Transform::IsPositiveScaleAndTranslation in that it also allows zero
+ // scales. This is because in the common orthographic case the z scale is 0.
+ if (!contents_device_transform.IsScaleOrTranslation())
+ return false;
+ return contents_device_transform.matrix().get(0, 0) >= 0.0 &&
+ contents_device_transform.matrix().get(1, 1) >= 0.0 &&
+ contents_device_transform.matrix().get(2, 2) >= 0.0;
}
} // namespace
@@ -79,7 +86,9 @@ bool ApplyTransformAndScissorToTileRect(const gfx::Transform& transform) {
// Scoped helper class for building SkImage from resource id.
class SkiaRenderer::ScopedSkImageBuilder {
public:
- ScopedSkImageBuilder(SkiaRenderer* skia_renderer, ResourceId resource_id);
+ ScopedSkImageBuilder(SkiaRenderer* skia_renderer,
+ ResourceId resource_id,
+ SkAlphaType alpha_type = kPremul_SkAlphaType);
~ScopedSkImageBuilder() = default;
const SkImage* sk_image() const { return sk_image_; }
@@ -93,14 +102,15 @@ class SkiaRenderer::ScopedSkImageBuilder {
SkiaRenderer::ScopedSkImageBuilder::ScopedSkImageBuilder(
SkiaRenderer* skia_renderer,
- ResourceId resource_id) {
+ ResourceId resource_id,
+ SkAlphaType alpha_type) {
if (!resource_id)
return;
auto* resource_provider = skia_renderer->resource_provider_;
if (!skia_renderer->is_using_ddl() || skia_renderer->non_root_surface_ ||
!IsTextureResource(resource_provider, resource_id)) {
// TODO(penghuang): remove this code when DDL is used everywhere.
- lock_.emplace(resource_provider, resource_id);
+ lock_.emplace(resource_provider, resource_id, alpha_type);
sk_image_ = lock_->sk_image();
} else {
// Look up the image from promise_images_by resource_id and return the
@@ -110,7 +120,7 @@ SkiaRenderer::ScopedSkImageBuilder::ScopedSkImageBuilder(
auto& image = skia_renderer->promise_images_[resource_id];
if (!image) {
image = skia_renderer->lock_set_for_external_use_
- ->LockResourceAndCreateSkImage(resource_id);
+ ->LockResourceAndCreateSkImage(resource_id, alpha_type);
LOG_IF(ERROR, !image) << "Failed to create the promise sk image.";
}
sk_image_ = image.get();
@@ -146,16 +156,22 @@ class SkiaRenderer::ScopedYUVSkImageBuilder {
const size_t number_of_textures = (is_i420 ? 3 : 2) + (has_alpha ? 1 : 0);
std::vector<ResourceMetadata> metadatas;
metadatas.reserve(number_of_textures);
+ // metadata.size is overridden because it is always the same size for
+ // all planes. Trust the size in |quad| instead. See
+ // https://crbug.com/939362
auto y_metadata = skia_renderer->lock_set_for_external_use_->LockResource(
quad->y_plane_resource_id());
+ y_metadata.size = quad->ya_tex_size;
metadatas.push_back(std::move(y_metadata));
auto u_metadata = skia_renderer->lock_set_for_external_use_->LockResource(
quad->u_plane_resource_id());
+ u_metadata.size = quad->uv_tex_size;
metadatas.push_back(std::move(u_metadata));
if (is_i420) {
auto v_metadata =
skia_renderer->lock_set_for_external_use_->LockResource(
quad->v_plane_resource_id());
+ v_metadata.size = quad->uv_tex_size;
metadatas.push_back(std::move(v_metadata));
}
@@ -163,6 +179,7 @@ class SkiaRenderer::ScopedYUVSkImageBuilder {
auto a_metadata =
skia_renderer->lock_set_for_external_use_->LockResource(
quad->a_plane_resource_id());
+ a_metadata.size = quad->ya_tex_size;
metadatas.push_back(std::move(a_metadata));
}
@@ -193,24 +210,6 @@ SkiaRenderer::SkiaRenderer(const RendererSettings* settings,
draw_mode_(mode),
skia_output_surface_(skia_output_surface) {
switch (draw_mode_) {
- case DrawMode::GL: {
- DCHECK(output_surface_);
- context_provider_ = output_surface_->context_provider();
- const auto& context_caps = context_provider_->ContextCapabilities();
- use_swap_with_bounds_ = context_caps.swap_buffers_with_bounds;
- if (context_caps.sync_query) {
- sync_queries_ =
- base::Optional<SyncQueryCollection>(context_provider_->ContextGL());
- }
- break;
- }
- case DrawMode::VULKAN: {
- DCHECK(output_surface_);
-#if BUILDFLAG(ENABLE_VULKAN)
- vulkan_context_provider_ = output_surface_->vulkan_context_provider();
-#endif
- break;
- }
case DrawMode::DDL: {
DCHECK(skia_output_surface_);
lock_set_for_external_use_.emplace(resource_provider,
@@ -233,7 +232,7 @@ SkiaRenderer::SkiaRenderer(const RendererSettings* settings,
SkiaRenderer::~SkiaRenderer() = default;
bool SkiaRenderer::CanPartialSwap() {
- if (draw_mode_ != DrawMode::GL && draw_mode_ != DrawMode::SKPRECORD)
+ if (draw_mode_ != DrawMode::SKPRECORD)
return false;
DCHECK(context_provider_);
@@ -245,7 +244,7 @@ bool SkiaRenderer::CanPartialSwap() {
void SkiaRenderer::BeginDrawingFrame() {
TRACE_EVENT0("viz", "SkiaRenderer::BeginDrawingFrame");
- if (draw_mode_ != DrawMode::GL && draw_mode_ != DrawMode::SKPRECORD)
+ if (draw_mode_ != DrawMode::SKPRECORD)
return;
// Copied from GLRenderer.
@@ -305,25 +304,6 @@ void SkiaRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) {
skia_output_surface_->SkiaSwapBuffers(std::move(output_frame));
break;
}
- case DrawMode::VULKAN: {
-#if BUILDFLAG(ENABLE_VULKAN)
- // TODO(penghuang): remove it when SkiaRenderer and SkDDL are always used.
- auto backend = root_surface_->getBackendRenderTarget(
- SkSurface::kFlushRead_BackendHandleAccess);
- GrVkImageInfo vk_image_info;
- if (!backend.getVkImageInfo(&vk_image_info))
- NOTREACHED() << "Failed to get the image info.";
- auto* vulkan_surface = output_surface_->GetVulkanSurface();
- auto* swap_chain = vulkan_surface->GetSwapChain();
- swap_chain->SetCurrentImageLayout(vk_image_info.fImageLayout);
- output_surface_->SwapBuffers(std::move(output_frame));
-#endif
- break;
- }
- case DrawMode::GL: {
- output_surface_->SwapBuffers(std::move(output_frame));
- break;
- }
case DrawMode::SKPRECORD: {
// write to skp files
std::string file_name = "composited-frame.skp";
@@ -359,67 +339,12 @@ void SkiaRenderer::BindFramebufferToOutputSurface() {
DCHECK(!output_surface_->HasExternalStencilTest());
non_root_surface_ = nullptr;
- // LegacyFontHost will get LCD text and skia figures out what type to use.
- SkSurfaceProps surface_props =
- SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
-
- // TODO(weiliangc): Set up correct can_use_lcd_text for SkSurfaceProps flags.
- // How to setup is in ResourceProvider. (http://crbug.com/644851)
switch (draw_mode_) {
case DrawMode::DDL: {
root_canvas_ = skia_output_surface_->BeginPaintCurrentFrame();
DCHECK(root_canvas_);
break;
}
- case DrawMode::VULKAN: {
-#if BUILDFLAG(ENABLE_VULKAN)
- auto* vulkan_surface = output_surface_->GetVulkanSurface();
- auto* swap_chain = vulkan_surface->GetSwapChain();
- VkImage image = swap_chain->GetCurrentImage();
- VkImageLayout image_layout = swap_chain->GetCurrentImageLayout();
- GrVkImageInfo vk_image_info;
- vk_image_info.fImage = image;
- vk_image_info.fAlloc = {VK_NULL_HANDLE, 0, 0, 0};
- vk_image_info.fImageLayout = image_layout;
- vk_image_info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
- vk_image_info.fFormat = VK_FORMAT_B8G8R8A8_UNORM;
- vk_image_info.fLevelCount = 1;
- GrBackendRenderTarget render_target(
- current_frame()->device_viewport_size.width(),
- current_frame()->device_viewport_size.height(), 0, 0, vk_image_info);
- root_surface_ = SkSurface::MakeFromBackendRenderTarget(
- GetGrContext(), render_target, kTopLeft_GrSurfaceOrigin,
- kBGRA_8888_SkColorType, nullptr, &surface_props);
- DCHECK(root_surface_);
- root_canvas_ = root_surface_->getCanvas();
-#else
- NOTREACHED();
-#endif
- break;
- }
- case DrawMode::GL: {
- auto* gr_context = GetGrContext();
- if (!root_canvas_ || root_canvas_->getGrContext() != gr_context ||
- gfx::SkISizeToSize(root_canvas_->getBaseLayerSize()) !=
- current_frame()->device_viewport_size) {
- // Either no SkSurface setup yet, or new GrContext, need to create new
- // surface.
- GrGLFramebufferInfo framebuffer_info;
- framebuffer_info.fFBOID = 0;
- framebuffer_info.fFormat = GL_RGB8_OES;
- GrBackendRenderTarget render_target(
- current_frame()->device_viewport_size.width(),
- current_frame()->device_viewport_size.height(), 0, 8,
- framebuffer_info);
-
- root_surface_ = SkSurface::MakeFromBackendRenderTarget(
- gr_context, render_target, kBottomLeft_GrSurfaceOrigin,
- kRGB_888x_SkColorType, nullptr, &surface_props);
- DCHECK(root_surface_);
- root_canvas_ = root_surface_->getCanvas();
- }
- break;
- }
case DrawMode::SKPRECORD: {
root_recorder_ = std::make_unique<SkPictureRecorder>();
@@ -460,14 +385,8 @@ void SkiaRenderer::BindFramebufferToTexture(const RenderPassId render_pass_id) {
case DrawMode::DDL: {
non_root_surface_ = nullptr;
current_canvas_ = skia_output_surface_->BeginPaintRenderPass(
- render_pass_id, backing.size, backing.format, backing.mipmap);
- break;
- }
- case DrawMode::GL: // Fallthrough
- case DrawMode::VULKAN: {
- non_root_surface_ = backing.render_pass_surface;
- current_surface_ = non_root_surface_.get();
- current_canvas_ = non_root_surface_->getCanvas();
+ render_pass_id, backing.size, backing.format, backing.generate_mipmap,
+ backing.color_space.ToSkColorSpace());
break;
}
case DrawMode::SKPRECORD: {
@@ -533,18 +452,23 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad,
if (!current_canvas_)
return;
TRACE_EVENT0("viz", "SkiaRenderer::DoDrawQuad");
- if (MustDrawBatchedTileQuadsBeforeQuad(quad, draw_region))
- DrawBatchedTileQuads();
if (quad->material == DrawQuad::TILED_CONTENT) {
AddTileQuadToBatch(TileDrawQuad::MaterialCast(quad), draw_region);
return;
}
+ // If the current quad is not tiled content then we must flush any
+ // bufferred tiled content quads.
+ if (!batched_tiles_.empty())
+ DrawBatchedTileQuads();
base::Optional<SkAutoCanvasRestore> auto_canvas_restore;
const gfx::Rect* scissor_rect =
is_scissor_enabled_ ? &scissor_rect_ : nullptr;
- PrepareCanvasForDrawQuads(quad->shared_quad_state->quad_to_target_transform,
- draw_region, scissor_rect, &auto_canvas_restore);
+ gfx::Transform contents_device_transform =
+ current_frame()->window_matrix * current_frame()->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform;
+ PrepareCanvasForDrawQuads(contents_device_transform, draw_region,
+ scissor_rect, &auto_canvas_restore);
SkPaint paint;
if (settings_->force_antialiasing ||
@@ -596,30 +520,41 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad,
DrawUnsupportedQuad(quad, &paint);
NOTREACHED();
break;
+ case DrawQuad::VIDEO_HOLE:
+ // VideoHoleDrawQuad should only be used by Cast, and should
+ // have been replaced by cast-specific OverlayProcessor before
+ // reach here. In non-cast build, an untrusted render could send such
+ // Quad and the quad would then reach here unexpectedly. Therefore
+ // we should skip NOTREACHED() so an untrusted render is not capable
+ // of causing a crash.
+ DrawUnsupportedQuad(quad, &paint);
+ break;
}
current_canvas_->resetMatrix();
}
-bool SkiaRenderer::MustDrawBatchedTileQuadsBeforeQuad(
+bool SkiaRenderer::MustDrawBatchedTileQuads(
const DrawQuad* new_quad,
+ const gfx::Transform& contents_device_transform,
+ bool apply_transform_and_scissor,
const gfx::QuadF* draw_region) {
+ DCHECK(new_quad->material == DrawQuad::TILED_CONTENT);
+ DCHECK(apply_transform_and_scissor ==
+ ApplyTransformAndScissorToTileRect(contents_device_transform));
+
if (batched_tiles_.empty())
return false;
bool has_draw_region = draw_region != nullptr;
- if (new_quad->material != DrawQuad::TILED_CONTENT)
- return true;
-
- if (ApplyTransformAndScissorToTileRect(
- new_quad->shared_quad_state->quad_to_target_transform)) {
- if (!batched_tile_state_.transform.IsIdentity())
+ if (apply_transform_and_scissor) {
+ if (!batched_tile_state_.contents_device_transform.IsIdentity())
return true;
DCHECK(!batched_tile_state_.has_scissor_rect);
} else {
- if (batched_tile_state_.transform !=
- new_quad->shared_quad_state->quad_to_target_transform ||
+ if (batched_tile_state_.contents_device_transform !=
+ contents_device_transform ||
batched_tile_state_.has_scissor_rect != is_scissor_enabled_ ||
(is_scissor_enabled_ &&
batched_tile_state_.scissor_rect != scissor_rect_))
@@ -641,7 +576,7 @@ bool SkiaRenderer::MustDrawBatchedTileQuadsBeforeQuad(
}
void SkiaRenderer::PrepareCanvasForDrawQuads(
- const gfx::Transform& quad_to_target_transform,
+ gfx::Transform contents_device_transform,
const gfx::QuadF* draw_region,
const gfx::Rect* scissor_rect,
base::Optional<SkAutoCanvasRestore>* auto_canvas_restore) {
@@ -651,9 +586,6 @@ void SkiaRenderer::PrepareCanvasForDrawQuads(
current_canvas_->clipRect(gfx::RectToSkRect(*scissor_rect));
}
- gfx::Transform contents_device_transform =
- current_frame()->window_matrix * current_frame()->projection_matrix *
- quad_to_target_transform;
contents_device_transform.FlattenTo2d();
SkMatrix sk_device_matrix;
gfx::TransformToFlattenedSkMatrix(contents_device_transform,
@@ -706,12 +638,6 @@ void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad,
SkCanvas* raster_canvas = current_canvas_;
- std::unique_ptr<SkCanvas> color_transform_canvas;
- // TODO(enne): color transform needs to be replicated in gles2_cmd_decoder
- color_transform_canvas = SkCreateColorSpaceXformCanvas(
- current_canvas_, gfx::ColorSpace::CreateSRGB().ToSkColorSpace());
- raster_canvas = color_transform_canvas.get();
-
base::Optional<skia::OpacityFilterCanvas> opacity_canvas;
if (needs_transparency || disable_image_filtering) {
// TODO(aelias): This isn't correct in all cases. We should detect these
@@ -746,7 +672,9 @@ void SkiaRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
- ScopedSkImageBuilder builder(this, quad->resource_id());
+ ScopedSkImageBuilder builder(
+ this, quad->resource_id(),
+ quad->premultiplied_alpha ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
const SkImage* image = builder.sk_image();
if (!image)
return;
@@ -784,9 +712,15 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad,
const gfx::QuadF* draw_region) {
- DCHECK(!MustDrawBatchedTileQuadsBeforeQuad(quad, draw_region));
- bool applyTransformAndScissor = ApplyTransformAndScissorToTileRect(
- quad->shared_quad_state->quad_to_target_transform);
+ gfx::Transform contents_device_transform =
+ current_frame()->window_matrix * current_frame()->projection_matrix *
+ quad->shared_quad_state->quad_to_target_transform;
+ bool apply_transform_and_scissor =
+ ApplyTransformAndScissorToTileRect(contents_device_transform);
+ if (MustDrawBatchedTileQuads(quad, contents_device_transform,
+ apply_transform_and_scissor, draw_region))
+ DrawBatchedTileQuads();
+
if (batched_tiles_.empty()) {
if (draw_region) {
batched_tile_state_.draw_region = *draw_region;
@@ -794,12 +728,11 @@ void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad,
batched_tile_state_.blend_mode = quad->shared_quad_state->blend_mode;
batched_tile_state_.is_nearest_neighbor = quad->nearest_neighbor;
batched_tile_state_.has_draw_region = (draw_region != nullptr);
- if (applyTransformAndScissor) {
- batched_tile_state_.transform = gfx::Transform();
+ if (apply_transform_and_scissor) {
+ batched_tile_state_.contents_device_transform = gfx::Transform();
batched_tile_state_.has_scissor_rect = false;
} else {
- batched_tile_state_.transform =
- quad->shared_quad_state->quad_to_target_transform;
+ batched_tile_state_.contents_device_transform = contents_device_transform;
batched_tile_state_.has_scissor_rect = is_scissor_enabled_;
batched_tile_state_.scissor_rect = scissor_rect_;
}
@@ -808,7 +741,9 @@ void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad,
// |resource_provider_| can be NULL in resourceless software draws, which
// should never produce tile quads in the first place.
DCHECK(resource_provider_);
- ScopedSkImageBuilder builder(this, quad->resource_id());
+ ScopedSkImageBuilder builder(
+ this, quad->resource_id(),
+ quad->is_premultiplied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
const SkImage* image = builder.sk_image();
if (!image)
return;
@@ -828,8 +763,8 @@ void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad,
aa_flags |= SkCanvas::kBottom_QuadAAFlag;
}
gfx::RectF quad_rect = gfx::RectF(quad->visible_rect);
- if (applyTransformAndScissor) {
- quad->shared_quad_state->quad_to_target_transform.TransformRect(&quad_rect);
+ if (apply_transform_and_scissor) {
+ contents_device_transform.TransformRect(&quad_rect);
if (is_scissor_enabled_) {
float left_inset = scissor_rect_.x() - quad_rect.x();
float top_inset = scissor_rect_.y() - quad_rect.y();
@@ -875,8 +810,8 @@ void SkiaRenderer::DrawBatchedTileQuads() {
? &batched_tile_state_.scissor_rect
: nullptr;
base::Optional<SkAutoCanvasRestore> auto_canvas_restore;
- PrepareCanvasForDrawQuads(batched_tile_state_.transform, draw_region,
- scissor_rect, &auto_canvas_restore);
+ PrepareCanvasForDrawQuads(batched_tile_state_.contents_device_transform,
+ draw_region, scissor_rect, &auto_canvas_restore);
SkFilterQuality filter_quality = batched_tile_state_.is_nearest_neighbor
? kNone_SkFilterQuality
@@ -966,15 +901,14 @@ bool SkiaRenderer::CalculateRPDQParams(sk_sp<SkImage> content,
if (dst_rect.IsEmpty())
return false;
- params->image_filter = filter;
+ params->image_filter = filter->makeWithLocalMatrix(local_matrix);
}
return true;
}
const TileDrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(
const RenderPass* pass) {
- return DirectRenderer::CanPassBeDrawnDirectly(pass, is_using_vulkan(),
- resource_provider_);
+ return DirectRenderer::CanPassBeDrawnDirectly(pass, resource_provider_);
}
void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
@@ -984,7 +918,10 @@ void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
// When Render Pass has a single quad inside we would draw that directly.
if (bypass != render_pass_bypass_quads_.end()) {
TileDrawQuad* tile_quad = &bypass->second;
- ScopedSkImageBuilder builder(this, tile_quad->resource_id());
+ ScopedSkImageBuilder builder(this, tile_quad->resource_id(),
+ tile_quad->is_premultiplied
+ ? kPremul_SkAlphaType
+ : kUnpremul_SkAlphaType);
sk_sp<SkImage> content_image = sk_ref_sp(builder.sk_image());
DrawRenderPassQuadInternal(quad, content_image, paint);
} else {
@@ -998,12 +935,8 @@ void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
switch (draw_mode_) {
case DrawMode::DDL: {
content_image = skia_output_surface_->MakePromiseSkImageFromRenderPass(
- quad->render_pass_id, backing.size, backing.format, backing.mipmap);
- break;
- }
- case DrawMode::GL: // Fallthrough
- case DrawMode::VULKAN: {
- content_image = backing.render_pass_surface->makeImageSnapshot();
+ quad->render_pass_id, backing.size, backing.format,
+ backing.generate_mipmap, backing.color_space.ToSkColorSpace());
break;
}
case DrawMode::SKPRECORD: {
@@ -1016,6 +949,11 @@ void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
}
}
+ // Currently the only trigger for generate_mipmap for render pass is
+ // trilinear filtering. It only affects GPU backed implementations and thus
+ // requires medium filter quality level.
+ if (backing.generate_mipmap)
+ paint->setFilterQuality(kMedium_SkFilterQuality);
DrawRenderPassQuadInternal(quad, content_image, paint);
}
}
@@ -1137,37 +1075,11 @@ void SkiaRenderer::DrawUnsupportedQuad(const DrawQuad* quad, SkPaint* paint) {
}
void SkiaRenderer::CopyDrawnRenderPass(
+ const copy_output::RenderPassGeometry& geometry,
std::unique_ptr<CopyOutputRequest> request) {
// TODO(weiliangc): Make copy request work. (crbug.com/644851)
TRACE_EVENT0("viz", "SkiaRenderer::CopyDrawnRenderPass");
- // Finalize the source subrect, as the entirety of the RenderPass's output
- // optionally clamped to the requested copy area. Then, compute the result
- // rect, which is the selection clamped to the maximum possible result bounds.
- // If there will be zero pixels of output or the scaling ratio was not
- // reasonable, do not proceed.
- gfx::Rect output_rect = current_frame()->current_render_pass->output_rect;
- if (request->has_area())
- output_rect.Intersect(request->area());
- const gfx::Rect result_bounds =
- request->is_scaled() ? copy_output::ComputeResultRect(
- gfx::Rect(output_rect.size()),
- request->scale_from(), request->scale_to())
- : gfx::Rect(output_rect.size());
- gfx::Rect result_rect = result_bounds;
- if (request->has_result_selection())
- result_rect.Intersect(request->result_selection());
- if (result_rect.IsEmpty())
- return;
-
- gfx::Rect copy_rect;
- if (request->is_scaled()) {
- copy_rect = MoveFromDrawToWindowSpace(output_rect);
- } else {
- copy_rect =
- MoveFromDrawToWindowSpace(result_rect + output_rect.OffsetFromOrigin());
- }
-
switch (draw_mode_) {
case DrawMode::DDL: {
// Root framebuffer uses id 0 in SkiaOutputSurface.
@@ -1176,44 +1088,11 @@ void SkiaRenderer::CopyDrawnRenderPass(
if (render_pass != current_frame()->root_render_pass) {
render_pass_id = render_pass->id;
}
- skia_output_surface_->CopyOutput(render_pass_id, copy_rect,
- render_pass->color_space, result_rect,
+ skia_output_surface_->CopyOutput(render_pass_id, geometry,
+ render_pass->color_space,
std::move(request));
break;
}
- case DrawMode::GL: // Fallthrough
- case DrawMode::VULKAN: {
- if (request->result_format() != CopyOutputResult::Format::RGBA_BITMAP ||
- request->is_scaled() ||
- (request->has_result_selection() &&
- request->result_selection() == gfx::Rect(copy_rect.size()))) {
- // TODO(crbug.com/644851): Complete the implementation for all request
- // types, scaling, etc.
- NOTIMPLEMENTED();
- return;
- }
- sk_sp<SkImage> copy_image =
- current_surface_->makeImageSnapshot()->makeSubset(
- RectToSkIRect(copy_rect));
-
- // Send copy request by copying into a bitmap.
- SkBitmap bitmap;
- copy_image->asLegacyBitmap(&bitmap);
- // TODO(crbug.com/795132): Plumb color space throughout SkiaRenderer up to
- // the SkSurface/SkImage here. Until then, play "musical chairs" with the
- // SkPixelRef to hack-in the RenderPass's |color_space|.
- sk_sp<SkPixelRef> pixels(SkSafeRef(bitmap.pixelRef()));
- SkIPoint origin = bitmap.pixelRefOrigin();
- bitmap.setInfo(
- bitmap.info().makeColorSpace(
- current_frame()
- ->current_render_pass->color_space.ToSkColorSpace()),
- bitmap.rowBytes());
- bitmap.setPixelRef(std::move(pixels), origin.x(), origin.y());
- request->SendResult(
- std::make_unique<CopyOutputSkBitmapResult>(copy_rect, bitmap));
- break;
- }
case DrawMode::SKPRECORD: {
NOTIMPLEMENTED();
break;
@@ -1247,24 +1126,6 @@ void SkiaRenderer::FinishDrawingQuadList() {
lock_set_for_external_use_->UnlockResources(sync_token);
break;
}
- case DrawMode::GL: // Fallthrough
- case DrawMode::VULKAN: {
- // For SkiaRendererPixelTestWithOverdrawFeedback, CopyDrawnRenderPass
- // happens before FinishDrawingFrame which results in an empty image. So
- // force a draw here.
- if (settings_->show_overdraw_feedback &&
- (current_frame()->current_render_pass ==
- current_frame()->root_render_pass)) {
- sk_sp<SkImage> image = overdraw_surface_->makeImageSnapshot();
- SkPaint paint;
- sk_sp<SkColorFilter> color_filter =
- SkiaHelper::MakeOverdrawColorFilter();
- paint.setColorFilter(color_filter);
- current_surface_->getCanvas()->drawImage(image.get(), 0, 0, &paint);
- }
- current_canvas_->flush();
- break;
- }
case DrawMode::SKPRECORD: {
current_canvas_->flush();
sk_sp<SkPicture> picture = current_recorder_->finishRecordingAsPicture();
@@ -1274,8 +1135,8 @@ void SkiaRenderer::FinishDrawingQuadList() {
}
void SkiaRenderer::GenerateMipmap() {
- // TODO(reveman): Generates mipmaps for current canvas. (crbug.com/763664)
- NOTIMPLEMENTED();
+ // This is a no-op since setting FilterQuality to high during drawing of
+ // RenderPassDrawQuad is what actually generates generate_mipmap.
}
bool SkiaRenderer::ShouldApplyBackgroundFilters(
@@ -1291,15 +1152,6 @@ GrContext* SkiaRenderer::GetGrContext() {
switch (draw_mode_) {
case DrawMode::DDL:
return nullptr;
- case DrawMode::VULKAN:
-#if BUILDFLAG(ENABLE_VULKAN)
- return vulkan_context_provider_->GetGrContext();
-#else
- NOTREACHED();
- return nullptr;
-#endif
- case DrawMode::GL:
- return context_provider_->GrContext();
case DrawMode::SKPRECORD:
return nullptr;
}
@@ -1321,7 +1173,8 @@ void SkiaRenderer::UpdateRenderPassTextures(
const RenderPassBacking& backing = pair.second;
bool size_appropriate = backing.size.width() >= requirements.size.width() &&
backing.size.height() >= requirements.size.height();
- bool mipmap_appropriate = !requirements.mipmap || backing.mipmap;
+ bool mipmap_appropriate =
+ !requirements.generate_mipmap || backing.generate_mipmap;
if (!size_appropriate || !mipmap_appropriate)
passes_to_delete.push_back(pair.first);
}
@@ -1352,20 +1205,10 @@ void SkiaRenderer::AllocateRenderPassResourceIfNeeded(
switch (draw_mode_) {
case DrawMode::DDL:
break;
- case DrawMode::VULKAN: {
- // TODO(penghuang): check supported format correctly.
- caps.texture_format_bgra8888 = true;
- break;
- }
- case DrawMode::GL: {
- caps.texture_format_bgra8888 =
- context_provider_->ContextCapabilities().texture_format_bgra8888;
- break;
- }
case DrawMode::SKPRECORD: {
render_pass_backings_.emplace(
render_pass_id,
- RenderPassBacking(requirements.size, requirements.mipmap,
+ RenderPassBacking(requirements.size, requirements.generate_mipmap,
current_frame()->current_render_pass->color_space));
return;
}
@@ -1373,7 +1216,7 @@ void SkiaRenderer::AllocateRenderPassResourceIfNeeded(
render_pass_backings_.emplace(
render_pass_id,
RenderPassBacking(gr_context, caps, requirements.size,
- requirements.mipmap,
+ requirements.generate_mipmap,
current_frame()->current_render_pass->color_space));
}
@@ -1381,9 +1224,9 @@ SkiaRenderer::RenderPassBacking::RenderPassBacking(
GrContext* gr_context,
const gpu::Capabilities& caps,
const gfx::Size& size,
- bool mipmap,
+ bool generate_mipmap,
const gfx::ColorSpace& color_space)
- : size(size), mipmap(mipmap), color_space(color_space) {
+ : size(size), generate_mipmap(generate_mipmap), color_space(color_space) {
if (color_space.IsHDR()) {
// If a platform does not support half-float renderbuffers then it should
// not should request HDR rendering.
@@ -1405,18 +1248,19 @@ SkiaRenderer::RenderPassBacking::RenderPassBacking(
int msaa_sample_count = 0;
SkColorType color_type =
ResourceFormatToClosestSkColorType(true /* gpu_compositing*/, format);
- SkImageInfo image_info = SkImageInfo::Make(
- size.width(), size.height(), color_type, kPremul_SkAlphaType, nullptr);
+ SkImageInfo image_info =
+ SkImageInfo::Make(size.width(), size.height(), color_type,
+ kPremul_SkAlphaType, color_space.ToSkColorSpace());
render_pass_surface = SkSurface::MakeRenderTarget(
gr_context, SkBudgeted::kNo, image_info, msaa_sample_count,
- kTopLeft_GrSurfaceOrigin, &surface_props, mipmap);
+ kTopLeft_GrSurfaceOrigin, &surface_props, generate_mipmap);
}
SkiaRenderer::RenderPassBacking::RenderPassBacking(
const gfx::Size& size,
- bool mipmap,
+ bool generate_mipmap,
const gfx::ColorSpace& color_space)
- : size(size), mipmap(mipmap), color_space(color_space) {
+ : size(size), generate_mipmap(generate_mipmap), color_space(color_space) {
recorder = std::make_unique<SkPictureRecorder>();
}
@@ -1425,7 +1269,7 @@ SkiaRenderer::RenderPassBacking::~RenderPassBacking() {}
SkiaRenderer::RenderPassBacking::RenderPassBacking(
SkiaRenderer::RenderPassBacking&& other)
: size(other.size),
- mipmap(other.mipmap),
+ generate_mipmap(other.generate_mipmap),
color_space(other.color_space),
format(other.format) {
render_pass_surface = other.render_pass_surface;
@@ -1436,7 +1280,7 @@ SkiaRenderer::RenderPassBacking::RenderPassBacking(
SkiaRenderer::RenderPassBacking& SkiaRenderer::RenderPassBacking::operator=(
SkiaRenderer::RenderPassBacking&& other) {
size = other.size;
- mipmap = other.mipmap;
+ generate_mipmap = other.generate_mipmap;
color_space = other.color_space;
format = other.format;
render_pass_surface = other.render_pass_surface;
diff --git a/chromium/components/viz/service/display/skia_renderer.h b/chromium/components/viz/service/display/skia_renderer.h
index a1535b26246..24567214212 100644
--- a/chromium/components/viz/service/display/skia_renderer.h
+++ b/chromium/components/viz/service/display/skia_renderer.h
@@ -12,7 +12,6 @@
#include "components/viz/service/display/direct_renderer.h"
#include "components/viz/service/display/sync_query_collection.h"
#include "components/viz/service/viz_service_export.h"
-#include "gpu/vulkan/buildflags.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "ui/latency/latency_info.h"
@@ -30,13 +29,15 @@ class SkiaOutputSurface;
class SolidColorDrawQuad;
class TextureDrawQuad;
class TileDrawQuad;
-class VulkanContextProvider;
class YUVVideoDrawQuad;
+// TODO(795132): SkColorSpace is only a subset comparing to gfx::ColorSpace.
+// Need to figure out support for color space that is not covered by
+// SkColorSpace.
class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
public:
// Different draw modes that are supported by SkiaRenderer right now.
- enum DrawMode { GL, DDL, VULKAN, SKPRECORD };
+ enum DrawMode { DDL, SKPRECORD };
// TODO(penghuang): Remove skia_output_surface when DDL is used everywhere.
SkiaRenderer(const RendererSettings* settings,
@@ -76,7 +77,8 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
bool FlippedFramebuffer() const override;
void EnsureScissorTestEnabled() override;
void EnsureScissorTestDisabled() override;
- void CopyDrawnRenderPass(std::unique_ptr<CopyOutputRequest> request) override;
+ void CopyDrawnRenderPass(const copy_output::RenderPassGeometry& geometry,
+ std::unique_ptr<CopyOutputRequest> request) override;
void SetEnableDCLayers(bool enable) override;
void DidChangeVisibility() override;
void FinishDrawingQuadList() override;
@@ -91,7 +93,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
void ClearFramebuffer();
void PrepareCanvasForDrawQuads(
- const gfx::Transform& transform,
+ gfx::Transform contents_device_transform,
const gfx::QuadF* draw_region,
const gfx::Rect* scissor_rect,
base::Optional<SkAutoCanvasRestore>* auto_canvas_restore);
@@ -104,8 +106,10 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
void DrawSolidColorQuad(const SolidColorDrawQuad* quad, SkPaint* paint);
void DrawTextureQuad(const TextureDrawQuad* quad, SkPaint* paint);
- bool MustDrawBatchedTileQuadsBeforeQuad(const DrawQuad* new_quad,
- const gfx::QuadF* draw_region);
+ bool MustDrawBatchedTileQuads(const DrawQuad* new_quad,
+ const gfx::Transform& content_device_transform,
+ bool apply_transform_and_scissor,
+ const gfx::QuadF* draw_region);
void AddTileQuadToBatch(const TileDrawQuad* quad,
const gfx::QuadF* draw_region);
void DrawBatchedTileQuads();
@@ -117,20 +121,19 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
bool ShouldApplyBackgroundFilters(
const RenderPassDrawQuad* quad,
const cc::FilterOperations* backdrop_filters) const;
- bool IsUsingVulkan() const;
const TileDrawQuad* CanPassBeDrawnDirectly(const RenderPass* pass) override;
- // Get corresponding GrContext in DrawMode::GL or DrawMode::VULKAN. Returns
- // nullptr when there is no GrContext.
+ // Get corresponding GrContext. Returns nullptr when there is no GrContext.
+ // TODO(weiliangc): This currently only returns nullptr. If SKPRecord isn't
+ // going to use this later, it should be removed.
GrContext* GetGrContext();
bool is_using_ddl() const { return draw_mode_ == DrawMode::DDL; }
- bool is_using_vulkan() const { return draw_mode_ == DrawMode::VULKAN; }
// A map from RenderPass id to the texture used to draw the RenderPass from.
struct RenderPassBacking {
sk_sp<SkSurface> render_pass_surface;
gfx::Size size;
- bool mipmap;
+ bool generate_mipmap;
gfx::ColorSpace color_space;
ResourceFormat format;
@@ -141,10 +144,10 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
RenderPassBacking(GrContext* gr_context,
const gpu::Capabilities& caps,
const gfx::Size& size,
- bool mipmap,
+ bool generate_mipmap,
const gfx::ColorSpace& color_space);
RenderPassBacking(const gfx::Size& size,
- bool mipmap,
+ bool generate_mipmap,
const gfx::ColorSpace& color_space);
~RenderPassBacking();
RenderPassBacking(RenderPassBacking&&);
@@ -170,16 +173,14 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
std::unique_ptr<SkCanvas> overdraw_canvas_;
std::unique_ptr<SkNWayCanvas> nway_canvas_;
- // Specific for GL.
- ContextProvider* context_provider_ = nullptr;
- base::Optional<SyncQueryCollection> sync_queries_;
+ // TODO(crbug.com/920344): Use partial swap for SkDDL.
bool use_swap_with_bounds_ = false;
gfx::Rect swap_buffer_rect_;
std::vector<gfx::Rect> swap_content_bounds_;
// State common to all tile quads in a batch
struct BatchedTileState {
- gfx::Transform transform;
+ gfx::Transform contents_device_transform;
gfx::Rect scissor_rect;
gfx::QuadF draw_region;
SkBlendMode blend_mode;
@@ -190,11 +191,6 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
BatchedTileState batched_tile_state_;
std::vector<SkCanvas::ImageSetEntry> batched_tiles_;
-// Specific for Vulkan.
-#if BUILDFLAG(ENABLE_VULKAN)
- VulkanContextProvider* vulkan_context_provider_ = nullptr;
-#endif
-
// Specific for SkDDL.
SkiaOutputSurface* const skia_output_surface_ = nullptr;
@@ -219,6 +215,8 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
sk_sp<SkPicture> root_picture_;
sk_sp<SkPicture>* current_picture_;
SkPictureRecorder* current_recorder_;
+ ContextProvider* context_provider_ = nullptr;
+ base::Optional<SyncQueryCollection> sync_queries_;
DISALLOW_COPY_AND_ASSIGN(SkiaRenderer);
};
diff --git a/chromium/components/viz/service/display/software_renderer.cc b/chromium/components/viz/service/display/software_renderer.cc
index 0aba701c131..62fad652b8b 100644
--- a/chromium/components/viz/service/display/software_renderer.cc
+++ b/chromium/components/viz/service/display/software_renderer.cc
@@ -25,7 +25,6 @@
#include "skia/ext/opacity_filter_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPath.h"
@@ -46,14 +45,16 @@ class AnimatedImagesProvider : public cc::ImageProvider {
: image_animation_map_(image_animation_map) {}
~AnimatedImagesProvider() override = default;
- ScopedDecodedDrawImage GetDecodedDrawImage(
+ ImageProvider::ScopedResult GetRasterContent(
const cc::DrawImage& draw_image) override {
+ // TODO(xidachen): Ensure this function works for paint worklet generated
+ // images.
const auto& paint_image = draw_image.paint_image();
auto it = image_animation_map_->find(paint_image.stable_id());
size_t frame_index = it == image_animation_map_->end()
? cc::PaintImage::kDefaultFrameIndex
: it->second;
- return ScopedDecodedDrawImage(cc::DecodedDrawImage(
+ return ScopedResult(cc::DecodedDrawImage(
paint_image.GetSkImageForFrame(
frame_index, cc::PaintImage::kDefaultGeneratorClientId),
SkSize::Make(0, 0), SkSize::Make(1.f, 1.f), draw_image.filter_quality(),
@@ -291,6 +292,15 @@ void SoftwareRenderer::DoDrawQuad(const DrawQuad* quad,
DrawUnsupportedQuad(quad);
NOTREACHED();
break;
+ case DrawQuad::VIDEO_HOLE:
+ // VideoHoleDrawQuad should only be used by Cast, and should
+ // have been replaced by cast-specific OverlayProcessor before
+ // reach here. In non-cast build, an untrusted render could send such
+ // Quad and the quad would then reach here unexpectedly. Therefore
+ // we should skip NOTREACHED() so an untrusted render is not capable
+ // of causing a crash.
+ DrawUnsupportedQuad(quad);
+ break;
}
current_canvas_->resetMatrix();
@@ -330,12 +340,6 @@ void SoftwareRenderer::DrawPictureQuad(const PictureDrawQuad* quad) {
SkCanvas* raster_canvas = current_canvas_;
- std::unique_ptr<SkCanvas> color_transform_canvas;
- // TODO(enne): color transform needs to be replicated in gles2_cmd_decoder
- color_transform_canvas = SkCreateColorSpaceXformCanvas(
- current_canvas_, gfx::ColorSpace::CreateSRGB().ToSkColorSpace());
- raster_canvas = color_transform_canvas.get();
-
base::Optional<skia::OpacityFilterCanvas> opacity_canvas;
if (needs_transparency || disable_image_filtering) {
// TODO(aelias): This isn't correct in all cases. We should detect these
@@ -541,26 +545,8 @@ void SoftwareRenderer::DrawUnsupportedQuad(const DrawQuad* quad) {
}
void SoftwareRenderer::CopyDrawnRenderPass(
+ const copy_output::RenderPassGeometry& geometry,
std::unique_ptr<CopyOutputRequest> request) {
- // Finalize the source subrect, as the entirety of the RenderPass's output
- // optionally clamped to the requested copy area. Then, compute the result
- // rect, which is the selection clamped to the maximum possible result bounds.
- // If there will be zero pixels of output or the scaling ratio was not
- // reasonable, do not proceed.
- gfx::Rect output_rect = current_frame()->current_render_pass->output_rect;
- if (request->has_area())
- output_rect.Intersect(request->area());
- const gfx::Rect result_bounds =
- request->is_scaled() ? copy_output::ComputeResultRect(
- gfx::Rect(output_rect.size()),
- request->scale_from(), request->scale_to())
- : gfx::Rect(output_rect.size());
- gfx::Rect result_rect = result_bounds;
- if (request->has_result_selection())
- result_rect.Intersect(request->result_selection());
- if (result_rect.IsEmpty())
- return;
-
sk_sp<SkColorSpace> color_space =
current_frame()->current_render_pass->color_space.ToSkColorSpace();
DCHECK(color_space);
@@ -574,12 +560,13 @@ void SoftwareRenderer::CopyDrawnRenderPass(
if (!current_canvas_->peekPixels(&render_pass_output))
return;
{
- const gfx::Rect subrect = MoveFromDrawToWindowSpace(output_rect);
render_pass_output =
SkPixmap(render_pass_output.info()
- .makeWH(subrect.width(), subrect.height())
+ .makeWH(geometry.sampling_bounds.width(),
+ geometry.sampling_bounds.height())
.makeColorSpace(std::move(color_space)),
- render_pass_output.addr(subrect.x(), subrect.y()),
+ render_pass_output.addr(geometry.sampling_bounds.x(),
+ geometry.sampling_bounds.y()),
render_pass_output.rowBytes());
}
@@ -595,18 +582,17 @@ void SoftwareRenderer::CopyDrawnRenderPass(
is_downscale_in_both_dimensions ? ImageOperations::RESIZE_BETTER
: ImageOperations::RESIZE_BEST;
bitmap = ImageOperations::Resize(
- render_pass_output, method, result_bounds.width(),
- result_bounds.height(),
- SkIRect{result_rect.x(), result_rect.y(), result_rect.right(),
- result_rect.bottom()});
+ render_pass_output, method, geometry.result_bounds.width(),
+ geometry.result_bounds.height(),
+ SkIRect{geometry.result_selection.x(), geometry.result_selection.y(),
+ geometry.result_selection.right(),
+ geometry.result_selection.bottom()});
} else /* if (!request->is_scaled()) */ {
- const gfx::Rect window_copy_rect =
- MoveFromDrawToWindowSpace(result_rect + output_rect.OffsetFromOrigin());
- bitmap.allocPixels(SkImageInfo::MakeN32Premul(window_copy_rect.width(),
- window_copy_rect.height(),
- std::move(color_space)));
- if (!current_canvas_->readPixels(bitmap, window_copy_rect.x(),
- window_copy_rect.y()))
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(
+ geometry.result_selection.width(), geometry.result_selection.height(),
+ std::move(color_space)));
+ if (!current_canvas_->readPixels(bitmap, geometry.readback_offset.x(),
+ geometry.readback_offset.y()))
return;
}
@@ -623,7 +609,7 @@ void SoftwareRenderer::CopyDrawnRenderPass(
// Note: The CopyOutputSkBitmapResult automatically provides I420 format
// conversion, if needed.
request->SendResult(std::make_unique<CopyOutputSkBitmapResult>(
- result_format, result_rect, bitmap));
+ result_format, geometry.result_selection, bitmap));
}
void SoftwareRenderer::SetEnableDCLayers(bool enable) {
diff --git a/chromium/components/viz/service/display/software_renderer.h b/chromium/components/viz/service/display/software_renderer.h
index 72f797a338b..6cfa3dc3ce8 100644
--- a/chromium/components/viz/service/display/software_renderer.h
+++ b/chromium/components/viz/service/display/software_renderer.h
@@ -59,7 +59,8 @@ class VIZ_SERVICE_EXPORT SoftwareRenderer : public DirectRenderer {
bool FlippedFramebuffer() const override;
void EnsureScissorTestEnabled() override;
void EnsureScissorTestDisabled() override;
- void CopyDrawnRenderPass(std::unique_ptr<CopyOutputRequest> request) override;
+ void CopyDrawnRenderPass(const copy_output::RenderPassGeometry& geometry,
+ std::unique_ptr<CopyOutputRequest> request) override;
void SetEnableDCLayers(bool enable) override;
void DidChangeVisibility() override;
void GenerateMipmap() override;
diff --git a/chromium/components/viz/service/display/surface_aggregator.cc b/chromium/components/viz/service/display/surface_aggregator.cc
index c43c243df8c..c08fab0739d 100644
--- a/chromium/components/viz/service/display/surface_aggregator.cc
+++ b/chromium/components/viz/service/display/surface_aggregator.cc
@@ -71,6 +71,10 @@ bool CalculateQuadSpaceDamageRect(
} // namespace
+std::string SurfaceAggregator::ClipData::ToString() const {
+ return is_clipped ? "clip " + rect.ToString() : "no clip";
+}
+
SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
DisplayResourceProvider* provider,
bool aggregate_only_damaged)
@@ -147,16 +151,25 @@ int SurfaceAggregator::ChildIdForSurface(Surface* surface) {
}
}
-gfx::Rect SurfaceAggregator::DamageRectForSurface(
- const Surface* surface,
- const RenderPass& source,
- const gfx::Rect& full_rect) const {
+bool SurfaceAggregator::IsSurfaceFrameIndexSameAsPrevious(
+ const Surface* surface) const {
auto it = previous_contained_surfaces_.find(surface->surface_id());
if (it != previous_contained_surfaces_.end()) {
uint64_t previous_index = it->second;
if (previous_index == surface->GetActiveFrameIndex())
- return gfx::Rect();
+ return true;
}
+ return false;
+}
+
+gfx::Rect SurfaceAggregator::DamageRectForSurface(
+ const Surface* surface,
+ const RenderPass& source,
+ const gfx::Rect& full_rect) const {
+ if (IsSurfaceFrameIndexSameAsPrevious(surface))
+ return gfx::Rect();
+
+ auto it = previous_contained_surfaces_.find(surface->surface_id());
const SurfaceId& previous_surface_id = surface->previous_frame_surface_id();
if (surface->surface_id() != previous_surface_id) {
@@ -299,6 +312,7 @@ void SurfaceAggregator::EmitSurfaceContent(
}
referenced_surfaces_.insert(surface_id);
+ bool has_surface_damage = !IsSurfaceFrameIndexSameAsPrevious(surface);
// TODO(vmpstr): provider check is a hack for unittests that don't set up a
// resource provider.
std::unordered_map<ResourceId, ResourceId> empty_map;
@@ -347,7 +361,7 @@ void SurfaceAggregator::EmitSurfaceContent(
CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
surface->GetActiveFrame().device_scale_factor(),
child_to_parent_map, gfx::Transform(), ClipData(),
- copy_pass.get(), surface_id);
+ copy_pass.get(), surface_id, has_surface_damage);
// If the render pass has copy requests, or should be cached, or has
// moving-pixel filters, or in a moving-pixel surface, we should damage the
@@ -401,7 +415,7 @@ void SurfaceAggregator::EmitSurfaceContent(
CopyQuadsToPass(quads, last_pass.shared_quad_state_list,
surface->GetActiveFrame().device_scale_factor(),
child_to_parent_map, surface_transform, quads_clip,
- dest_pass, surface_id);
+ dest_pass, surface_id, has_surface_damage);
} else {
auto* shared_quad_state = CopyAndScaleSharedQuadState(
source_sqs, scaled_quad_to_target_transform, target_transform,
@@ -411,7 +425,7 @@ void SurfaceAggregator::EmitSurfaceContent(
gfx::ScaleToEnclosingRect(source_sqs->visible_quad_layer_rect,
layer_to_content_scale_x,
layer_to_content_scale_y),
- clip_rect, dest_pass);
+ clip_rect, dest_pass, has_surface_damage);
gfx::Rect scaled_rect(gfx::ScaleToEnclosingRect(
source_rect, layer_to_content_scale_x, layer_to_content_scale_y));
@@ -442,8 +456,9 @@ void SurfaceAggregator::EmitDefaultBackgroundColorQuad(
// surface specified so create a SolidColorDrawQuad with the default
// background color.
SkColor background_color = surface_quad->default_background_color;
- auto* shared_quad_state = CopySharedQuadState(
- surface_quad->shared_quad_state, target_transform, clip_rect, dest_pass);
+ auto* shared_quad_state =
+ CopySharedQuadState(surface_quad->shared_quad_state, target_transform,
+ clip_rect, dest_pass, /*has_surface_damage*/ true);
auto* solid_color_quad =
dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
solid_color_quad->SetNew(shared_quad_state, surface_quad->rect,
@@ -474,7 +489,8 @@ void SurfaceAggregator::EmitGutterQuadsIfNecessary(
SharedQuadState* shared_quad_state = CopyAndScaleSharedQuadState(
primary_shared_quad_state,
primary_shared_quad_state->quad_to_target_transform, target_transform,
- right_gutter_rect, right_gutter_rect, clip_rect, dest_pass);
+ right_gutter_rect, right_gutter_rect, clip_rect, dest_pass,
+ /*has_surface_damage*/ true);
auto* right_gutter =
dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -490,7 +506,8 @@ void SurfaceAggregator::EmitGutterQuadsIfNecessary(
SharedQuadState* shared_quad_state = CopyAndScaleSharedQuadState(
primary_shared_quad_state,
primary_shared_quad_state->quad_to_target_transform, target_transform,
- bottom_gutter_rect, bottom_gutter_rect, clip_rect, dest_pass);
+ bottom_gutter_rect, bottom_gutter_rect, clip_rect, dest_pass,
+ /*has_surface_damage*/ true);
auto* bottom_gutter =
dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
@@ -543,11 +560,12 @@ SharedQuadState* SurfaceAggregator::CopySharedQuadState(
const SharedQuadState* source_sqs,
const gfx::Transform& target_transform,
const ClipData& clip_rect,
- RenderPass* dest_render_pass) {
+ RenderPass* dest_render_pass,
+ bool has_surface_damage) {
return CopyAndScaleSharedQuadState(
source_sqs, source_sqs->quad_to_target_transform, target_transform,
source_sqs->quad_layer_rect, source_sqs->visible_quad_layer_rect,
- clip_rect, dest_render_pass);
+ clip_rect, dest_render_pass, has_surface_damage);
}
SharedQuadState* SurfaceAggregator::CopyAndScaleSharedQuadState(
@@ -557,7 +575,8 @@ SharedQuadState* SurfaceAggregator::CopyAndScaleSharedQuadState(
const gfx::Rect& quad_layer_rect,
const gfx::Rect& visible_quad_layer_rect,
const ClipData& clip_rect,
- RenderPass* dest_render_pass) {
+ RenderPass* dest_render_pass,
+ bool has_surface_damage) {
auto* shared_quad_state = dest_render_pass->CreateAndAppendSharedQuadState();
ClipData new_clip_rect = CalculateClipRect(
clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect),
@@ -577,6 +596,7 @@ SharedQuadState* SurfaceAggregator::CopyAndScaleSharedQuadState(
new_clip_rect.rect, new_clip_rect.is_clipped,
source_sqs->are_contents_opaque, source_sqs->opacity,
source_sqs->blend_mode, source_sqs->sorting_context_id);
+ shared_quad_state->has_surface_damage = has_surface_damage;
return shared_quad_state;
}
@@ -589,7 +609,8 @@ void SurfaceAggregator::CopyQuadsToPass(
const gfx::Transform& target_transform,
const ClipData& clip_rect,
RenderPass* dest_pass,
- const SurfaceId& surface_id) {
+ const SurfaceId& surface_id,
+ bool has_surface_damage) {
const SharedQuadState* last_copied_source_shared_quad_state = nullptr;
// If the current frame has copy requests or cached render passes, then
// aggregate the entire thing, as otherwise parts of the copy requests may be
@@ -632,8 +653,9 @@ void SurfaceAggregator::CopyQuadsToPass(
&damage_rect_in_quad_space_valid);
} else {
if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
- const SharedQuadState* dest_shared_quad_state = CopySharedQuadState(
- quad->shared_quad_state, target_transform, clip_rect, dest_pass);
+ const SharedQuadState* dest_shared_quad_state =
+ CopySharedQuadState(quad->shared_quad_state, target_transform,
+ clip_rect, dest_pass, has_surface_damage);
last_copied_source_shared_quad_state = quad->shared_quad_state;
if (ignore_undamaged) {
damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect(
@@ -707,6 +729,9 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame,
if (!valid_surfaces_.count(surface->surface_id()))
return;
+ // No changes in the target surface if it's the same as the previous frame
+ // This information will be used later in overlay processing.
+ bool has_surface_damage = !IsSurfaceFrameIndexSameAsPrevious(surface);
// TODO(vmpstr): provider check is a hack for unittests that don't set up a
// resource provider.
std::unordered_map<ResourceId, ResourceId> empty_map;
@@ -736,7 +761,7 @@ void SurfaceAggregator::CopyPasses(const CompositorFrame& frame,
CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
frame.device_scale_factor(), child_to_parent_map,
gfx::Transform(), ClipData(), copy_pass.get(),
- surface->surface_id());
+ surface->surface_id(), has_surface_damage);
// If the render pass has copy requests, or should be cached, or has
// moving-pixel filters, or in a moving-pixel surface, we should damage the
diff --git a/chromium/components/viz/service/display/surface_aggregator.h b/chromium/components/viz/service/display/surface_aggregator.h
index 335d6d288c5..d692e754ab7 100644
--- a/chromium/components/viz/service/display/surface_aggregator.h
+++ b/chromium/components/viz/service/display/surface_aggregator.h
@@ -6,6 +6,7 @@
#define COMPONENTS_VIZ_SERVICE_DISPLAY_SURFACE_AGGREGATOR_H_
#include <memory>
+#include <string>
#include <unordered_map>
#include "base/containers/flat_map.h"
@@ -64,6 +65,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
ClipData(bool is_clipped, const gfx::Rect& rect)
: is_clipped(is_clipped), rect(rect) {}
+ std::string ToString() const;
+
bool is_clipped;
gfx::Rect rect;
};
@@ -130,7 +133,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
SharedQuadState* CopySharedQuadState(const SharedQuadState* source_sqs,
const gfx::Transform& target_transform,
const ClipData& clip_rect,
- RenderPass* dest_render_pass);
+ RenderPass* dest_render_pass,
+ bool has_surface_damage);
SharedQuadState* CopyAndScaleSharedQuadState(
const SharedQuadState* source_sqs,
@@ -139,7 +143,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
const gfx::Rect& quad_layer_rect,
const gfx::Rect& visible_quad_layer_rect,
const ClipData& clip_rect,
- RenderPass* dest_render_pass);
+ RenderPass* dest_render_pass,
+ bool has_surface_damage);
void CopyQuadsToPass(
const QuadList& source_quad_list,
@@ -149,7 +154,8 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
const gfx::Transform& target_transform,
const ClipData& clip_rect,
RenderPass* dest_pass,
- const SurfaceId& surface_id);
+ const SurfaceId& surface_id,
+ bool has_surface_damage);
gfx::Rect PrewalkTree(Surface* surface,
bool in_moved_pixel_surface,
int parent_pass,
@@ -168,6 +174,7 @@ class VIZ_SERVICE_EXPORT SurfaceAggregator {
void PropagateCopyRequestPasses();
int ChildIdForSurface(Surface* surface);
+ bool IsSurfaceFrameIndexSameAsPrevious(const Surface* surface) const;
gfx::Rect DamageRectForSurface(const Surface* surface,
const RenderPass& source,
const gfx::Rect& full_rect) const;
diff --git a/chromium/components/viz/service/display/surface_aggregator_perftest.cc b/chromium/components/viz/service/display/surface_aggregator_perftest.cc
index 2975828aa8c..95539d51217 100644
--- a/chromium/components/viz/service/display/surface_aggregator_perftest.cc
+++ b/chromium/components/viz/service/display/surface_aggregator_perftest.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 "cc/base/lap_timer.h"
+#include "base/timer/lap_timer.h"
#include "cc/test/fake_output_surface_client.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/quads/compositor_frame.h"
@@ -157,7 +157,7 @@ class SurfaceAggregatorPerfTest : public testing::Test {
scoped_refptr<TestContextProvider> context_provider_;
std::unique_ptr<DisplayResourceProvider> resource_provider_;
std::unique_ptr<SurfaceAggregator> aggregator_;
- cc::LapTimer timer_;
+ base::LapTimer timer_;
};
TEST_F(SurfaceAggregatorPerfTest, ManySurfacesOpaque) {
diff --git a/chromium/components/viz/service/display/surface_aggregator_pixeltest.cc b/chromium/components/viz/service/display/surface_aggregator_pixeltest.cc
index 0c721569048..3422dd06dc7 100644
--- a/chromium/components/viz/service/display/surface_aggregator_pixeltest.cc
+++ b/chromium/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -55,7 +55,7 @@ class SurfaceAggregatorPixelTest : public cc::RendererPixelTest<GLRenderer> {
protected:
ServerSharedBitmapManager shared_bitmap_manager_;
FrameSinkManagerImpl manager_;
- ParentLocalSurfaceIdAllocator allocator_;
+ ParentLocalSurfaceIdAllocator root_allocator_;
std::unique_ptr<CompositorFrameSinkSupport> support_;
base::TimeTicks next_display_time_ =
base::TimeTicks() + base::TimeDelta::FromSeconds(1);
@@ -96,12 +96,12 @@ TEST_F(SurfaceAggregatorPixelTest, DrawSimpleFrame) {
auto root_frame =
CompositorFrameBuilder().AddRenderPass(std::move(pass)).Build();
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
SurfaceId root_surface_id(
support_->frame_sink_id(),
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
support_->SubmitCompositorFrame(
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
std::move(root_frame));
SurfaceAggregator aggregator(manager_.surface_manager(),
@@ -124,14 +124,15 @@ TEST_F(SurfaceAggregatorPixelTest, DrawSimpleAggregatedFrame) {
nullptr, &manager_, kArbitraryChildFrameSinkId, kIsChildRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId child_surface_id(child_support->frame_sink_id(),
child_local_surface_id);
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
LocalSurfaceId root_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id);
{
@@ -213,18 +214,22 @@ TEST_F(SurfaceAggregatorPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
auto right_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryRightFrameSinkId, kIsChildRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator left_child_allocator;
+ left_child_allocator.GenerateId();
LocalSurfaceId left_child_local_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ left_child_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId left_child_id(left_support->frame_sink_id(), left_child_local_id);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator right_child_allocator;
+ right_child_allocator.GenerateId();
LocalSurfaceId right_child_local_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ right_child_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId right_child_id(right_support->frame_sink_id(),
right_child_local_id);
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
LocalSurfaceId root_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id);
{
diff --git a/chromium/components/viz/service/display/surface_aggregator_unittest.cc b/chromium/components/viz/service/display/surface_aggregator_unittest.cc
index 7d5a4d4554f..0aa827e8987 100644
--- a/chromium/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/chromium/components/viz/service/display/surface_aggregator_unittest.cc
@@ -9,7 +9,9 @@
#include <set>
#include <utility>
+#include <vector>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
@@ -49,7 +51,12 @@ constexpr FrameSinkId kArbitraryFrameSinkId2(3, 3);
constexpr FrameSinkId kArbitraryMiddleFrameSinkId(4, 4);
constexpr FrameSinkId kArbitraryReservedFrameSinkId(5, 5);
constexpr FrameSinkId kArbitraryFrameSinkId3(6, 6);
-const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
+const base::UnguessableToken kArbitraryToken =
+ base::UnguessableToken::Deserialize(1, 2);
+const base::UnguessableToken kArbitraryToken2 =
+ base::UnguessableToken::Deserialize(3, 4);
+const base::UnguessableToken kArbitraryToken3 =
+ base::UnguessableToken::Deserialize(5, 6);
constexpr bool kRootIsRoot = true;
constexpr bool kChildIsRoot = false;
constexpr bool kNeedsSyncPoints = false;
@@ -106,7 +113,7 @@ class SurfaceAggregatorTest : public testing::Test, public DisplayTimeSource {
explicit SurfaceAggregatorTest(bool use_damage_rect)
: manager_(&shared_bitmap_manager_),
observer_(false),
- support_(std::make_unique<CompositorFrameSinkSupport>(
+ root_sink_(std::make_unique<CompositorFrameSinkSupport>(
&fake_client_,
&manager_,
kArbitraryRootFrameSinkId,
@@ -344,7 +351,7 @@ class SurfaceAggregatorTest : public testing::Test, public DisplayTimeSource {
FrameSinkManagerImpl manager_;
FakeSurfaceObserver observer_;
FakeCompositorFrameSinkClient fake_client_;
- std::unique_ptr<CompositorFrameSinkSupport> support_;
+ std::unique_ptr<CompositorFrameSinkSupport> root_sink_;
SurfaceAggregator aggregator_;
};
@@ -352,13 +359,13 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
public:
explicit SurfaceAggregatorValidSurfaceTest(bool use_damage_rect)
: SurfaceAggregatorTest(use_damage_rect),
- child_support_(std::make_unique<CompositorFrameSinkSupport>(
+ child_sink_(std::make_unique<CompositorFrameSinkSupport>(
nullptr,
&manager_,
kArbitraryReservedFrameSinkId,
kChildIsRoot,
kNeedsSyncPoints)) {
- child_support_->set_allow_copy_output_requests_for_testing();
+ child_sink_->set_allow_copy_output_requests_for_testing();
}
SurfaceAggregatorValidSurfaceTest()
@@ -366,11 +373,11 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
void SetUp() override {
SurfaceAggregatorTest::SetUp();
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
root_local_surface_id_ =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
root_surface_ = manager_.surface_manager()->GetSurfaceForId(
- SurfaceId(support_->frame_sink_id(), root_local_surface_id_));
+ SurfaceId(root_sink_->frame_sink_id(), root_local_surface_id_));
}
void TearDown() override { SurfaceAggregatorTest::TearDown(); }
@@ -400,7 +407,7 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
void AggregateAndVerify(const std::vector<Pass>& expected_passes,
const std::vector<SurfaceId>& expected_surface_ids) {
CompositorFrame aggregated_frame = aggregator_.Aggregate(
- SurfaceId(support_->frame_sink_id(), root_local_surface_id_),
+ SurfaceId(root_sink_->frame_sink_id(), root_local_surface_id_),
GetNextDisplayTimeAndIncrement());
TestPassesMatchExpectations(expected_passes,
@@ -494,9 +501,8 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
protected:
LocalSurfaceId root_local_surface_id_;
Surface* root_surface_;
- ParentLocalSurfaceIdAllocator allocator_;
- std::unique_ptr<CompositorFrameSinkSupport> child_support_;
- ParentLocalSurfaceIdAllocator child_allocator_;
+ ParentLocalSurfaceIdAllocator root_allocator_;
+ std::unique_ptr<CompositorFrameSinkSupport> child_sink_;
};
// Tests that a very simple frame containing only two solid color quads makes it
@@ -509,14 +515,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
// Add a callback for when the surface is damaged.
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
// Check that the AggregatedDamageCallback is called with the right arguments.
EXPECT_CALL(
@@ -535,9 +542,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator embedded_allocator;
+ embedded_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ embedded_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
@@ -549,7 +558,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
constexpr float device_scale_factor = 1.0f;
SubmitCompositorFrame(embedded_support.get(), embedded_passes,
embedded_local_surface_id, device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
{
std::vector<Quad> quads = {
Quad::SurfaceQuad(SurfaceRange(base::nullopt, embedded_surface_id),
@@ -558,7 +568,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
/*ignores_input_event=*/false)};
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
CompositorFrame aggregated_frame = aggregator_.Aggregate(
@@ -582,7 +592,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
/*ignores_input_event=*/false)};
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
CompositorFrame aggregated_frame = aggregator_.Aggregate(
@@ -599,9 +609,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RotatedClip) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator embedded_allocator;
+ embedded_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ embedded_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
@@ -621,10 +633,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RotatedClip) {
/*ignores_input_event=*/false)};
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -647,10 +660,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(passes, {root_surface_id});
}
@@ -666,10 +680,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassDeallocation) {
Pass(quads[1], 1, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId surface_id(root_sink_->frame_sink_id(), root_local_surface_id_);
CompositorFrame aggregated_frame;
aggregated_frame =
@@ -687,7 +701,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassDeallocation) {
std::vector<Pass> passes2 = {Pass(quads[0], 3, SurfaceSize()),
Pass(quads[1], 1, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), passes2, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes2, root_local_surface_id_,
device_scale_factor);
// The RenderPass that still exists should keep the same ID.
@@ -698,7 +712,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassDeallocation) {
EXPECT_NE(id2, id0);
EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
// |id1| didn't exist in the previous frame, so it should be
@@ -720,9 +734,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator embedded_allocator;
+ embedded_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ embedded_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
@@ -743,7 +759,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
Quad::SolidColorQuad(SK_ColorBLACK, gfx::Rect(5, 5))};
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
@@ -751,7 +767,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5)),
Quad::SolidColorQuad(SK_ColorBLACK, gfx::Rect(5, 5))};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id, embedded_surface_id});
}
@@ -760,24 +777,23 @@ class TestVizClient {
TestVizClient(SurfaceAggregatorValidSurfaceTest* test,
FrameSinkManagerImpl* manager,
const FrameSinkId& frame_sink_id,
- const LocalSurfaceId& local_surface_id,
const gfx::Rect& bounds)
: test_(test),
manager_(manager),
frame_sink_id_(frame_sink_id),
- local_surface_id_(local_surface_id),
bounds_(bounds) {
constexpr bool is_root = false;
constexpr bool needs_sync_points = false;
- support_ = std::make_unique<CompositorFrameSinkSupport>(
+ root_sink_ = std::make_unique<CompositorFrameSinkSupport>(
nullptr, manager_, frame_sink_id, is_root, needs_sync_points);
+ allocator_.GenerateId();
}
~TestVizClient() = default;
Surface* GetSurface() const {
return manager_->surface_manager()->GetSurfaceForId(
- SurfaceId(frame_sink_id_, local_surface_id_));
+ SurfaceId(frame_sink_id_, local_surface_id()));
}
void SubmitCompositorFrame(SkColor bgcolor) {
@@ -803,8 +819,9 @@ class TestVizClient {
constexpr float device_scale_factor = 1.0f;
RenderPassList pass_list =
test_->GenerateRenderPassList(embedded_passes, &referenced_surfaces);
- test_->SubmitPassListAsFrame(support_.get(), local_surface_id_, &pass_list,
- referenced_surfaces, device_scale_factor);
+ test_->SubmitPassListAsFrame(root_sink_.get(), local_surface_id(),
+ &pass_list, referenced_surfaces,
+ device_scale_factor);
}
void SetEmbeddedClient(TestVizClient* embedded, bool add_quad) {
@@ -814,20 +831,24 @@ class TestVizClient {
CopyOutputRequest* RequestCopyOfOutput() {
auto copy_request = CopyOutputRequest::CreateStubForTesting();
auto* copy_request_ptr = copy_request.get();
- support_->RequestCopyOfOutput(local_surface_id_, std::move(copy_request));
+ root_sink_->RequestCopyOfOutput(local_surface_id(),
+ std::move(copy_request));
return copy_request_ptr;
}
- SurfaceId surface_id() const { return {frame_sink_id_, local_surface_id_}; }
+ SurfaceId surface_id() const { return {frame_sink_id_, local_surface_id()}; }
const gfx::Rect& bounds() const { return bounds_; }
+ const LocalSurfaceId& local_surface_id() const {
+ return allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ }
private:
SurfaceAggregatorValidSurfaceTest* const test_;
FrameSinkManagerImpl* const manager_;
- std::unique_ptr<CompositorFrameSinkSupport> support_;
+ std::unique_ptr<CompositorFrameSinkSupport> root_sink_;
const FrameSinkId frame_sink_id_;
- const LocalSurfaceId local_surface_id_;
const gfx::Rect bounds_;
+ ParentLocalSurfaceIdAllocator allocator_;
std::map<TestVizClient*, bool> embedded_clients_;
@@ -835,19 +856,15 @@ class TestVizClient {
};
TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfaces) {
- allocator_.GenerateId();
TestVizClient child(
this, &manager_, kArbitraryFrameSinkId1,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(10, 10));
child.SubmitCompositorFrame(SK_ColorBLUE);
// Parent first submits a CompositorFrame that renfereces |child|, but does
// not provide a DrawQuad that embeds it.
- allocator_.GenerateId();
TestVizClient parent(
this, &manager_, kArbitraryFrameSinkId2,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(15, 15));
parent.SetEmbeddedClient(&child, false);
parent.SubmitCompositorFrame(SK_ColorGREEN);
@@ -862,7 +879,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfaces) {
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
@@ -870,7 +887,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfaces) {
Quad::SolidColorQuad(SK_ColorGREEN, parent.bounds()),
Quad::SolidColorQuad(SK_ColorBLACK, gfx::Rect(5, 5))};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id, parent.surface_id(),
child.surface_id()});
// |child| should not be drawn.
@@ -893,20 +911,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfaces) {
}
TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfacesWithCopyRequests) {
- allocator_.GenerateId();
TestVizClient child(
this, &manager_, kArbitraryFrameSinkId1,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(10, 10));
child.SubmitCompositorFrame(SK_ColorBLUE);
child.RequestCopyOfOutput();
// Parent first submits a CompositorFrame that renfereces |child|, but does
// not provide a DrawQuad that embeds it.
- allocator_.GenerateId();
TestVizClient parent(
this, &manager_, kArbitraryFrameSinkId2,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(15, 15));
parent.SetEmbeddedClient(&child, false);
parent.SubmitCompositorFrame(SK_ColorGREEN);
@@ -921,7 +935,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfacesWithCopyRequests) {
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
@@ -932,7 +946,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfacesWithCopyRequests) {
Quad::SolidColorQuad(SK_ColorBLUE, child.bounds())};
std::vector<Pass> expected_passes = {Pass(expected_copy_quads, SurfaceSize()),
Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id, parent.surface_id(),
child.surface_id()});
EXPECT_FALSE(child.GetSurface()->HasUndrawnActiveFrame());
@@ -941,29 +956,23 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UndrawnSurfacesWithCopyRequests) {
TEST_F(SurfaceAggregatorValidSurfaceTest,
SurfacesWithMultipleEmbeddersBothVisibleAndInvisible) {
- allocator_.GenerateId();
TestVizClient child(
this, &manager_, kArbitraryFrameSinkId1,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(10, 10));
child.SubmitCompositorFrame(SK_ColorBLUE);
// First parent submits a CompositorFrame that renfereces |child|, but does
// not provide a DrawQuad that embeds it.
- allocator_.GenerateId();
TestVizClient first_parent(
this, &manager_, kArbitraryFrameSinkId2,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(15, 15));
first_parent.SetEmbeddedClient(&child, false);
first_parent.SubmitCompositorFrame(SK_ColorGREEN);
// Second parent submits a CompositorFrame referencing |child|, and also
// includes a draw-quad for it.
- allocator_.GenerateId();
TestVizClient second_parent(
this, &manager_, kArbitraryMiddleFrameSinkId,
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
gfx::Rect(25, 25));
second_parent.SetEmbeddedClient(&child, true);
second_parent.SubmitCompositorFrame(SK_ColorYELLOW);
@@ -983,7 +992,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
EXPECT_TRUE(child.GetSurface()->HasUndrawnActiveFrame());
@@ -998,7 +1007,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
Quad::SolidColorQuad(SK_ColorBLACK, gfx::Rect(5, 5))};
std::vector<Quad> expected_copy_quads = {};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes,
{root_surface_id, first_parent.surface_id(),
second_parent.surface_id(), child.surface_id()});
@@ -1019,15 +1029,18 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
kNeedsSyncPoints);
- child_allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator fallback_allocator;
+ fallback_allocator.GenerateId();
LocalSurfaceId fallback_child_local_surface_id =
- child_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ fallback_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(),
fallback_child_local_surface_id);
- child_allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator primary_allocator;
+ primary_allocator.GenerateId();
LocalSurfaceId primary_child_local_surface_id =
- child_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ primary_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
primary_child_local_surface_id);
@@ -1042,7 +1055,6 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
constexpr float device_scale_factor_1 = 1.0f;
constexpr float device_scale_factor_2 = 2.0f;
SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
-
fallback_child_local_surface_id, device_scale_factor_2);
// Try to embed |primary_child_surface_id| and if unavailable, embed
@@ -1056,14 +1068,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
primary_child_support->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
fallback_child_support->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor_1);
// There is no CompositorFrame submitted to |primary_child_surface_id| and
@@ -1079,7 +1091,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
};
std::vector<Pass> expected_passes1 = {Pass(expected_quads1, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
EXPECT_CALL(aggregated_damage_callback,
OnAggregatedDamage(fallback_child_local_surface_id, fallback_size,
@@ -1103,9 +1116,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
testing::Mock::VerifyAndClearExpectations(&aggregated_damage_callback);
// Submit the fallback again to create some damage then aggregate again.
- child_allocator_.GenerateId();
+ fallback_allocator.GenerateId();
fallback_child_local_surface_id =
- child_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ fallback_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
@@ -1176,9 +1190,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillBounds) {
auto primary_child_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId primary_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
primary_child_local_surface_id);
@@ -1206,11 +1221,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillBounds) {
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
1.0f);
EXPECT_CALL(
@@ -1246,9 +1262,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillStretchedBounds) {
auto primary_child_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId primary_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
primary_child_local_surface_id);
@@ -1276,11 +1293,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillStretchedBounds) {
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
2.0f);
EXPECT_CALL(
@@ -1317,9 +1335,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillSquashedBounds) {
auto primary_child_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId primary_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
primary_child_local_surface_id);
@@ -1347,11 +1366,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, StretchContentToFillSquashedBounds) {
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
0.5f);
EXPECT_CALL(
@@ -1385,9 +1405,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
auto primary_child_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator primary_allocator;
+ primary_allocator.GenerateId();
LocalSurfaceId primary_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ primary_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
primary_child_local_surface_id);
std::vector<Quad> primary_child_quads = {
@@ -1406,9 +1427,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
auto fallback_child_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator fallback_allocator;
+ fallback_allocator.GenerateId();
LocalSurfaceId fallback_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ fallback_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(),
fallback_child_local_surface_id);
@@ -1433,10 +1456,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
std::vector<Pass> root_passes = {Pass(root_quads, root_size, NoDamage())};
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
// The CompositorFrame is submitted to |primary_child_surface_id|, so
@@ -1446,7 +1469,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5))};
std::vector<Pass> expected_passes1 = {Pass(expected_quads1, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
EXPECT_CALL(aggregated_damage_callback,
OnAggregatedDamage(root_local_surface_id_, root_size,
@@ -1479,9 +1503,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator embedded_allocator;
+ embedded_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ embedded_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
@@ -1506,10 +1532,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
Quad::SolidColorQuad(SK_ColorBLACK, gfx::Rect(5, 5))};
std::vector<Pass> root_passes = {Pass(root_quads, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -1541,9 +1568,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator embedded_allocator;
+ embedded_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ embedded_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
@@ -1578,10 +1607,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
frame.render_pass_list[1]->copy_requests.push_back(
std::move(copy_request2));
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
}
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -1627,15 +1657,16 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
auto parent_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId2, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
embedded_local_surface_id);
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
SurfaceId nonexistent_surface_id(
- support_->frame_sink_id(),
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
+ root_sink_->frame_sink_id(),
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id());
std::vector<Quad> embedded_quads = {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5))};
@@ -1649,9 +1680,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
embedded_support->RequestCopyOfOutput(embedded_local_surface_id,
std::move(copy_request));
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator parent_allocator;
+ parent_allocator.GenerateId();
LocalSurfaceId parent_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ parent_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId parent_surface_id(parent_support->frame_sink_id(),
parent_local_surface_id);
@@ -1691,10 +1723,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
// included in previous_contained_surfaces, but otherwise ignored.
frame.metadata.referenced_surfaces.emplace_back(nonexistent_surface_id);
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
}
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -1712,7 +1745,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
aggregated_frame.render_pass_list[0]->copy_requests[0].get());
SurfaceId surface_ids[] = {
- SurfaceId(support_->frame_sink_id(), root_local_surface_id_),
+ SurfaceId(root_sink_->frame_sink_id(), root_local_surface_id_),
parent_surface_id, embedded_surface_id};
EXPECT_EQ(base::size(surface_ids),
aggregator_.previous_contained_surfaces().size());
@@ -1725,10 +1758,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
// This tests referencing a surface that has multiple render passes.
TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
- child_allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId embedded_local_surface_id =
- child_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId embedded_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId embedded_surface_id(child_sink_->frame_sink_id(),
embedded_local_surface_id);
int pass_ids[] = {1, 2, 3};
@@ -1746,7 +1780,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
Pass(embedded_quads[2], pass_ids[2], SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(child_support_.get(), embedded_passes,
+ SubmitCompositorFrame(child_sink_.get(), embedded_passes,
embedded_local_surface_id, device_scale_factor);
std::vector<Quad> root_quads[3] = {
@@ -1764,10 +1798,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
Pass(root_quads[1], pass_ids[1], SurfaceSize()),
Pass(root_quads[2], pass_ids[2], SurfaceSize())};
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -1886,23 +1921,25 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5)),
Quad::SolidColorQuad(SK_ColorBLUE, gfx::Rect(5, 5))};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id});
}
// Tests a reference to a valid surface with no submitted frame. A
// SolidColorDrawQuad should be placed in lieu of a frame.
TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId empty_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId surface_with_no_frame_id(kArbitraryFrameSinkId1,
empty_local_surface_id);
@@ -1916,7 +1953,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
@@ -1924,7 +1961,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
Quad::SolidColorQuad(SK_ColorYELLOW, gfx::Rect(5, 5)),
Quad::SolidColorQuad(SK_ColorBLUE, gfx::Rect(5, 5))};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id});
}
@@ -1932,10 +1970,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
// with no submitted frame. A SolidColorDrawQuad should be placed in lieu of a
// frame.
TEST_F(SurfaceAggregatorValidSurfaceTest, ValidFallbackWithNoFrame) {
- allocator_.GenerateId();
+ root_allocator_.GenerateId();
const LocalSurfaceId empty_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- const SurfaceId surface_with_no_frame_id(support_->frame_sink_id(),
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ const SurfaceId surface_with_no_frame_id(root_sink_->frame_sink_id(),
empty_local_surface_id);
std::vector<Quad> quads = {Quad::SurfaceQuad(
@@ -1944,21 +1982,23 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidFallbackWithNoFrame) {
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
Quad::SolidColorQuad(SK_ColorYELLOW, gfx::Rect(5, 5)),
};
std::vector<Pass> expected_passes = {Pass(expected_quads, SurfaceSize())};
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
AggregateAndVerify(expected_passes, {root_surface_id});
}
// Tests a surface quad referencing itself, generating a trivial cycle.
// The quad creating the cycle should be dropped from the final frame.
TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
std::vector<Quad> quads = {
Quad::SurfaceQuad(SurfaceRange(base::nullopt, root_surface_id),
SK_ColorWHITE, gfx::Rect(5, 5),
@@ -1968,7 +2008,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
std::vector<Pass> passes = {Pass(quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
std::vector<Quad> expected_quads = {
@@ -1979,10 +2019,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
// Tests a more complex cycle with one intermediate surface.
TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
std::vector<Quad> parent_quads = {
@@ -1995,10 +2036,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
std::vector<Pass> parent_passes = {Pass(parent_quads, SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), parent_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), parent_passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
std::vector<Quad> child_quads = {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5)),
Quad::SurfaceQuad(SurfaceRange(base::nullopt, root_surface_id),
@@ -2008,8 +2050,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
Quad::SolidColorQuad(SK_ColorMAGENTA, gfx::Rect(5, 5))};
std::vector<Pass> child_passes = {Pass(child_quads, SurfaceSize())};
- SubmitCompositorFrame(child_support_.get(), child_passes,
- child_local_surface_id, device_scale_factor);
+ SubmitCompositorFrame(child_sink_.get(), child_passes, child_local_surface_id,
+ device_scale_factor);
// The child surface's reference to the root_surface_ will be dropped, so
// we'll end up with:
@@ -2029,10 +2071,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
// Tests that we map render pass IDs from different surfaces into a unified
// namespace and update RenderPassDrawQuad's id references to match.
TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
RenderPassId child_pass_id[] = {1u, 2u};
@@ -2044,7 +2087,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
Pass(child_quad[1], child_pass_id[1], SurfaceSize())};
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(child_support_.get(), surface_passes,
+ SubmitCompositorFrame(child_sink_.get(), surface_passes,
child_local_surface_id, device_scale_factor);
// Pass IDs from the parent surface may collide with ones from the child.
@@ -2059,10 +2102,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
Pass(parent_quad[0], parent_pass_id[0], SurfaceSize()),
Pass(parent_quad[1], parent_pass_id[1], SurfaceSize())};
- SubmitCompositorFrame(support_.get(), parent_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), parent_passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -2155,6 +2199,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
SkBlendMode::kSrcIn, // 5
SkBlendMode::kDstIn, // 6
};
+ ParentLocalSurfaceIdAllocator grandchild_allocator;
+ ParentLocalSurfaceIdAllocator child_one_allocator;
+ ParentLocalSurfaceIdAllocator child_two_allocator;
auto grandchild_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
kNeedsSyncPoints);
@@ -2165,9 +2212,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
nullptr, &manager_, kArbitraryFrameSinkId3, kChildIsRoot,
kNeedsSyncPoints);
int pass_id = 1;
- allocator_.GenerateId();
+ grandchild_allocator.GenerateId();
LocalSurfaceId grandchild_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ grandchild_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId grandchild_surface_id(grandchild_support->frame_sink_id(),
grandchild_local_surface_id);
@@ -2183,9 +2231,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
QueuePassAsFrame(std::move(grandchild_pass), grandchild_local_surface_id,
device_scale_factor, grandchild_support.get());
- allocator_.GenerateId();
+ child_one_allocator.GenerateId();
LocalSurfaceId child_one_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_one_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId child_one_surface_id(child_one_support->frame_sink_id(),
child_one_local_surface_id);
@@ -2206,9 +2255,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id,
device_scale_factor, child_one_support.get());
- allocator_.GenerateId();
+ child_two_allocator.GenerateId();
LocalSurfaceId child_two_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_two_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId child_two_surface_id(child_two_support->frame_sink_id(),
child_two_local_surface_id);
@@ -2246,9 +2296,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
blend_modes[6]);
QueuePassAsFrame(std::move(root_pass), root_local_surface_id_,
- device_scale_factor, support_.get());
+ device_scale_factor, root_sink_.get());
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -2290,10 +2341,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
kNeedsSyncPoints);
// Innermost child surface.
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
{
int child_pass_id[] = {1, 2};
@@ -2321,14 +2373,15 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
child_root_pass_sqs->is_clipped = true;
child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
}
// Middle child surface.
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator middle_allocator;
+ middle_allocator.GenerateId();
LocalSurfaceId middle_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ middle_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId middle_surface_id(middle_support->frame_sink_id(),
middle_local_surface_id);
{
@@ -2383,10 +2436,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
root_frame_quad->visible_rect = gfx::Rect(8, 100);
root_frame.render_pass_list[0]->transform_to_root_target.Translate(10, 5);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -2463,7 +2517,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
// Add a callback for when the surface is damaged.
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
auto parent_support = std::make_unique<CompositorFrameSinkSupport>(
@@ -2480,13 +2534,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
std::vector<Quad> parent_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -2501,9 +2556,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
AddPasses(&parent_surface_frame.render_pass_list, parent_surface_passes,
&parent_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator parent_allocator;
+ parent_allocator.GenerateId();
LocalSurfaceId parent_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ parent_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId parent_surface_id(parent_support->frame_sink_id(),
parent_local_surface_id);
parent_support->SubmitCompositorFrame(parent_local_surface_id,
@@ -2529,13 +2585,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 10, 10);
root_frame.render_pass_list[1]->damage_rect = gfx::Rect(5, 5, 100, 100);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
// Damage rect for first aggregation should contain entire root surface. The
// damage rect reported to the callback is actually 10 pixels taller because
// of the 10-pixel vertical translation of the first RenderPass.
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
EXPECT_CALL(
aggregated_damage_callback,
OnAggregatedDamage(root_local_surface_id_, SurfaceSize(),
@@ -2557,12 +2614,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
// Outer surface didn't change, so a transformed inner damage rect is
// expected.
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
const gfx::Rect expected_damage_rect(10, 20, 10, 10);
EXPECT_CALL(aggregated_damage_callback,
@@ -2586,8 +2643,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
->quad_to_target_transform.Translate(0, 10);
root_frame.render_pass_list[0]->damage_rect = gfx::Rect(0, 0, 1, 1);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
}
{
@@ -2600,12 +2657,12 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
->quad_to_target_transform.Translate(0, 10);
root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 1, 1, 1);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
// The root surface was enqueued without being aggregated once, so it should
// be treated as completely damaged.
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
EXPECT_CALL(
aggregated_damage_callback,
@@ -2620,7 +2677,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
// No Surface changed, so no damage should be given.
{
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
EXPECT_CALL(aggregated_damage_callback, OnAggregatedDamage(_, _, _, _))
.Times(0);
@@ -2653,7 +2710,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
// Add a callback for when the surface is damaged.
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
auto parent_support = std::make_unique<CompositorFrameSinkSupport>(
@@ -2670,13 +2727,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
std::vector<Quad> parent_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -2691,9 +2749,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
AddPasses(&parent_surface_frame.render_pass_list, parent_surface_passes,
&parent_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator parent_allocator;
+ parent_allocator.GenerateId();
LocalSurfaceId parent_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ parent_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId parent_surface_id(parent_support->frame_sink_id(),
parent_local_surface_id);
parent_support->SubmitCompositorFrame(parent_local_surface_id,
@@ -2709,12 +2768,13 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
Pass(root_surface_quads, 1, SurfaceSize()),
Pass(root_render_pass_quads, 2, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
1.0f);
// Damage rect for first aggregation should be exactly the entire root
// surface.
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
EXPECT_CALL(
aggregated_damage_callback,
OnAggregatedDamage(root_local_surface_id_, SurfaceSize(),
@@ -2734,14 +2794,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
auto* child_root_pass = child_frame.render_pass_list[0].get();
child_root_pass->damage_rect = gfx::Rect(10, 20, 20, 30);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
// Outer surface didn't change, so transformed inner damage rect should be
// used. Since the child surface is stretching to fit the outer surface
// which is half the size, we end up with a damage rect that is half the
// size of the child surface.
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
const gfx::Rect expected_damage_rect(5, 10, 10, 15);
EXPECT_CALL(aggregated_damage_callback,
@@ -2761,7 +2821,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithSquashToFit) {
TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithStretchToFit) {
// Add a callback for when the surface is damaged.
MockAggregatedDamageCallback aggregated_damage_callback;
- support_->SetAggregatedDamageCallbackForTesting(
+ root_sink_->SetAggregatedDamageCallbackForTesting(
aggregated_damage_callback.GetCallback());
auto parent_support = std::make_unique<CompositorFrameSinkSupport>(
@@ -2778,13 +2838,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithStretchToFit) {
auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
std::vector<Quad> parent_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -2799,9 +2860,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithStretchToFit) {
AddPasses(&parent_surface_frame.render_pass_list, parent_surface_passes,
&parent_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator parent_allocator;
+ parent_allocator.GenerateId();
LocalSurfaceId parent_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ parent_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId parent_surface_id(parent_support->frame_sink_id(),
parent_local_surface_id);
parent_support->SubmitCompositorFrame(parent_local_surface_id,
@@ -2817,13 +2879,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithStretchToFit) {
Pass(root_surface_quads, 1, SurfaceSize()),
Pass(root_render_pass_quads, 2, SurfaceSize())};
- SubmitCompositorFrame(support_.get(), root_passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), root_passes, root_local_surface_id_,
1.0f);
// Damage rect for first aggregation should contain entire root surface. The
// damage rect reported to the callback is actually 200x200, larger than the
// root surface size, because the root's Quad is 200x200.
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
EXPECT_CALL(
aggregated_damage_callback,
OnAggregatedDamage(root_local_surface_id_, SurfaceSize(),
@@ -2843,14 +2906,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRectWithStretchToFit) {
auto* child_root_pass = child_frame.render_pass_list[0].get();
child_root_pass->damage_rect = gfx::Rect(10, 15, 20, 30);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
// Outer surface didn't change, so transformed inner damage rect should be
// used. Since the child surface is stretching to fit the outer surface
// which is twice the size, we end up with a damage rect that is double the
// size of the child surface.
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
const gfx::Rect expected_damage_rect(20, 30, 40, 60);
EXPECT_CALL(aggregated_damage_callback,
@@ -2879,11 +2942,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) {
root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 100, 100);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
{
- SurfaceId root_surface_id(support_->frame_sink_id(),
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
root_local_surface_id_);
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -2897,10 +2960,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) {
gfx::Rect(SurfaceSize())));
}
- allocator_.GenerateId();
LocalSurfaceId second_root_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId second_root_surface_id(support_->frame_sink_id(),
+ root_allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId second_root_surface_id(root_sink_->frame_sink_id(),
second_root_local_surface_id);
{
std::vector<Quad> root_render_pass_quads = {
@@ -2915,8 +2977,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) {
root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 2, 3, 4);
- support_->SubmitCompositorFrame(second_root_local_surface_id,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(second_root_local_surface_id,
+ std::move(root_frame));
}
{
CompositorFrame aggregated_frame = aggregator_.Aggregate(
@@ -2947,21 +3009,22 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageSameFrameSinkId) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId id1 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GenerateId();
LocalSurfaceId id2 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GenerateId();
LocalSurfaceId id3 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GenerateId();
LocalSurfaceId id4 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GenerateId();
LocalSurfaceId id5 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId fallback_surface_id(kArbitraryFrameSinkId1, id2);
SurfaceId primary_surface_id(kArbitraryFrameSinkId1, id4);
std::vector<Quad> embedded_quads = {
@@ -2975,9 +3038,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageSameFrameSinkId) {
CompositorFrame frame = MakeCompositorFrameFromSurfaceRanges(
{SurfaceRange(fallback_surface_id, primary_surface_id)});
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -3013,18 +3077,21 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageDifferentFrameSinkId) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator sink1_allocator;
+ ParentLocalSurfaceIdAllocator sink2_allocator;
+ ParentLocalSurfaceIdAllocator sink3_allocator;
+ sink1_allocator.GenerateId();
LocalSurfaceId id1 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ sink1_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ sink1_allocator.GenerateId();
LocalSurfaceId id2 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ sink1_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ sink2_allocator.GenerateId();
LocalSurfaceId id3 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ sink2_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ sink2_allocator.GenerateId();
LocalSurfaceId id4 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ sink2_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId fallback_surface_id(kArbitraryFrameSinkId1, id2);
SurfaceId primary_surface_id(kArbitraryFrameSinkId2, id4);
std::vector<Quad> embedded_quads = {
@@ -3038,9 +3105,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageDifferentFrameSinkId) {
CompositorFrame frame = MakeCompositorFrameFromSurfaceRanges(
{SurfaceRange(fallback_surface_id, primary_surface_id)});
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -3052,11 +3120,6 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageDifferentFrameSinkId) {
EXPECT_TRUE(aggregator_.NotifySurfaceDamageAndCheckForDisplayDamage(
SurfaceId(kArbitraryFrameSinkId1, id2)));
- // |id3| is after the fallback and primary has a different FrameSinkId so it
- // should damage the display.
- EXPECT_TRUE(aggregator_.NotifySurfaceDamageAndCheckForDisplayDamage(
- SurfaceId(kArbitraryFrameSinkId1, id3)));
-
// |id3| is before the primary and fallback has a different FrameSinkId so it
// should damage the display.
EXPECT_TRUE(aggregator_.NotifySurfaceDamageAndCheckForDisplayDamage(
@@ -3074,22 +3137,29 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamageDifferentFrameSinkId) {
// Verifies that when only a primary surface is provided any damage to primary
// surface damages the display.
TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamagePrimarySurfaceOnly) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId id1 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GenerateId();
LocalSurfaceId id2 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GenerateId();
LocalSurfaceId id3 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId primary_surface_id(kArbitraryFrameSinkId1, id2);
+ ParentLocalSurfaceIdAllocator allocator2;
+ allocator.GenerateId();
+ LocalSurfaceId id4 =
+ allocator2.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+
CompositorFrame frame = MakeCompositorFrameFromSurfaceRanges(
{SurfaceRange(base::nullopt, primary_surface_id)});
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -3107,27 +3177,33 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SurfaceDamagePrimarySurfaceOnly) {
// This FrameSinkId is not embedded at all so it shouldn't damage the display.
EXPECT_FALSE(aggregator_.NotifySurfaceDamageAndCheckForDisplayDamage(
- SurfaceId(kArbitraryFrameSinkId3, id2)));
+ SurfaceId(kArbitraryFrameSinkId3, id4)));
}
// Verifies that when primary and fallback ids are equal, only damage to that
-// particular surface causee damage to display.
+// particular surface causes damage to display.
TEST_F(SurfaceAggregatorValidSurfaceTest,
SurfaceDamagePrimaryAndFallbackEqual) {
auto embedded_support = std::make_unique<CompositorFrameSinkSupport>(
nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
kNeedsSyncPoints);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId id1 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GenerateId();
LocalSurfaceId id2 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator_.GenerateId();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GenerateId();
LocalSurfaceId id3 =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId surface_id(kArbitraryFrameSinkId1, id2);
+ ParentLocalSurfaceIdAllocator allocator2;
+ allocator2.GenerateId();
+ LocalSurfaceId id4 =
+ allocator2.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+
std::vector<Quad> embedded_quads = {
Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(5, 5)),
Quad::SolidColorQuad(SK_ColorBLUE, gfx::Rect(5, 5))};
@@ -3138,9 +3214,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
CompositorFrame frame =
MakeCompositorFrameFromSurfaceRanges({SurfaceRange(surface_id)});
- support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -3158,7 +3235,7 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
// This FrameSinkId is not embedded at all so it shouldn't damage the display.
EXPECT_FALSE(aggregator_.NotifySurfaceDamageAndCheckForDisplayDamage(
- SurfaceId(kArbitraryFrameSinkId3, id2)));
+ SurfaceId(kArbitraryFrameSinkId3, id4)));
}
class SurfaceAggregatorPartialSwapTest
@@ -3170,10 +3247,11 @@ class SurfaceAggregatorPartialSwapTest
// Tests that quads outside the damage rect are ignored.
TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
constexpr float device_scale_factor = 1.0f;
@@ -3212,7 +3290,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
child_pass_list[2]->quad_list.ElementAt(0)->visible_rect =
gfx::Rect(0, 0, 2, 2);
- SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+ SubmitPassListAsFrame(child_sink_.get(), child_local_surface_id,
&child_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3234,12 +3312,13 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
->quad_to_target_transform.Translate(10, 10);
root_pass->damage_rect = gfx::Rect(0, 0, 1, 1);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -3270,7 +3349,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
root_pass->shared_quad_state_list.front()
->quad_to_target_transform.Translate(10, 10);
root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3321,7 +3400,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
child_root_pass->copy_requests.push_back(
CopyOutputRequest::CreateStubForTesting());
child_root_pass->damage_rect = gfx::Rect();
- SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+ SubmitPassListAsFrame(child_sink_.get(), child_local_surface_id,
&child_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3384,7 +3463,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
auto* root_pass = root_pass_list[2].get();
filter_pass->filters.Append(cc::FilterOperation::CreateBlurFilter(2));
root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3437,7 +3516,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
pass->backdrop_filters.Append(
cc::FilterOperation::CreateOpacityFilter(0.5f));
root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3493,7 +3572,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
// Damage rect intersects with render passes of |pass_with_filter| and
// |root_pass|.
root_pass->damage_rect = gfx::Rect(3, 3, 3, 3);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3550,7 +3629,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
cc::FilterOperation::CreateBlurFilter(2));
// Damage rect does not intersect with render pass.
root_pass->damage_rect = gfx::Rect(6, 6, 3, 3);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -3811,10 +3890,10 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) {
LocalSurfaceId root_local_surface_id(7u, kArbitraryToken);
SurfaceId root_surface_id(root_support->frame_sink_id(),
root_local_surface_id);
- LocalSurfaceId middle_local_surface_id(8u, kArbitraryToken);
+ LocalSurfaceId middle_local_surface_id(8u, kArbitraryToken2);
SurfaceId middle_surface_id(middle_support->frame_sink_id(),
middle_local_surface_id);
- LocalSurfaceId child_local_surface_id(9u, kArbitraryToken);
+ LocalSurfaceId child_local_surface_id(9u, kArbitraryToken3);
SurfaceId child_surface_id(child_support->frame_sink_id(),
child_local_surface_id);
@@ -3931,10 +4010,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ColorSpaceTest) {
gfx::ColorSpace color_space3 = gfx::ColorSpace::CreateSCRGBLinear();
constexpr float device_scale_factor = 1.0f;
- SubmitCompositorFrame(support_.get(), passes, root_local_surface_id_,
+ SubmitCompositorFrame(root_sink_.get(), passes, root_local_surface_id_,
device_scale_factor);
- SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId surface_id(root_sink_->frame_sink_id(), root_local_surface_id_);
CompositorFrame aggregated_frame;
aggregator_.SetOutputColorSpace(color_space1, color_space1);
@@ -3971,13 +4050,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageByChangingChildSurface) {
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
std::vector<Quad> root_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -3989,9 +4069,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageByChangingChildSurface) {
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
// On first frame there is no existing cache texture to worry about re-using,
// so we don't worry what this bool is set to.
@@ -4011,8 +4092,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageByChangingChildSurface) {
CompositorFrame child_surface_frame = MakeEmptyCompositorFrame();
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4027,8 +4108,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageByChangingChildSurface) {
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
child_surface_frame.render_pass_list[0]->damage_rect = gfx::Rect();
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4054,13 +4135,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator child_allocator;
+ child_allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ child_allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
std::vector<Quad> root_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -4072,9 +4154,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
// On first frame there is no existing cache texture to worry about re-using,
// so we don't worry what this bool is set to.
@@ -4093,9 +4176,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
std::vector<Quad> grand_child_quads = {Quad::RenderPassQuad(1)};
std::vector<Pass> grand_child_passes = {
Pass(grand_child_quads, 1, SurfaceSize())};
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator grandchild_allocator;
+ grandchild_allocator.GenerateId();
LocalSurfaceId grand_child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ grandchild_allocator.GetCurrentLocalSurfaceIdAllocation()
+ .local_surface_id();
SurfaceId grand_child_surface_id(grand_child_support->frame_sink_id(),
grand_child_local_surface_id);
{
@@ -4117,8 +4202,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
child_surface_frame = MakeEmptyCompositorFrame();
AddPasses(&child_surface_frame.render_pass_list, new_child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4177,13 +4262,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageFromRenderPassQuads) {
AddPasses(&child_frame.render_pass_list, child_passes,
&child_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
std::vector<Quad> root_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -4199,10 +4285,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageFromRenderPassQuads) {
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4227,8 +4314,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, HasDamageFromRenderPassQuads) {
CompositorFrame child_frame = MakeEmptyCompositorFrame();
AddPasses(&child_frame.render_pass_list, child_passes,
&child_frame.metadata.referenced_surfaces);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4256,10 +4343,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectOfCachedRenderPass) {
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4289,8 +4377,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectOfCachedRenderPass) {
auto* root_pass_sqs = root_pass->shared_quad_state_list.front();
root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4317,8 +4405,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectOfCachedRenderPass) {
auto* root_pass_sqs = root_pass->shared_quad_state_list.front();
root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4347,13 +4435,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
AddPasses(&child_frame.render_pass_list, child_passes,
&child_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
std::vector<Quad> root_surface_quads = {Quad::SurfaceQuad(
SurfaceRange(base::nullopt, child_surface_id), SK_ColorWHITE,
@@ -4366,10 +4455,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4399,8 +4489,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4427,8 +4517,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest,
auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4452,13 +4542,14 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
// root surface quads
std::vector<Quad> root_surface_quads = {Quad::SurfaceQuad(
@@ -4471,9 +4562,10 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
AddPasses(&root_frame.render_pass_list, root_passes,
&root_frame.metadata.referenced_surfaces);
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
// The damage rect of the very first frame is always the full rect
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4487,8 +4579,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
CompositorFrame child_surface_frame = MakeEmptyCompositorFrame();
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
CompositorFrame root_frame = MakeEmptyCompositorFrame();
AddPasses(&root_frame.render_pass_list, root_passes,
@@ -4499,8 +4591,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
surface_quad_sqs->is_clipped = false;
// Set the root damage rect to empty. Only the child surface will be tested.
root_render_pass->damage_rect = gfx::Rect();
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4515,8 +4607,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
CompositorFrame child_surface_frame = MakeEmptyCompositorFrame();
AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
&child_surface_frame.metadata.referenced_surfaces);
- child_support_->SubmitCompositorFrame(child_local_surface_id,
- std::move(child_surface_frame));
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
CompositorFrame root_frame = MakeEmptyCompositorFrame();
AddPasses(&root_frame.render_pass_list, root_passes,
@@ -4527,8 +4619,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
surface_quad_sqs->is_clipped = true;
surface_quad_sqs->clip_rect = clip_rect;
root_render_pass->damage_rect = gfx::Rect();
- support_->SubmitCompositorFrame(root_local_surface_id_,
- std::move(root_frame));
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
CompositorFrame aggregated_frame = aggregator_.Aggregate(
root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4544,10 +4636,11 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, DamageRectWithClippedChildSurface) {
// Tests that quads outside the damage rect are not ignored for cached render
// pass.
TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
- allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
LocalSurfaceId child_local_surface_id =
- allocator_.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- SurfaceId child_surface_id(child_support_->frame_sink_id(),
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
child_local_surface_id);
// The child surface has two quads, one with a visible rect of 15,15 6x6 and
// the other other with a visible rect of 10,10 2x2 (relative to root target
@@ -4578,7 +4671,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
gfx::Rect(0, 0, 2, 2);
- SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+ SubmitPassListAsFrame(child_sink_.get(), child_local_surface_id,
&child_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -4605,12 +4698,13 @@ TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
->quad_to_target_transform.Translate(10, 10);
root_pass->damage_rect = gfx::Rect(0, 0, 1, 1);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
- SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
CompositorFrame aggregated_frame =
aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
@@ -4647,7 +4741,7 @@ TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
root_pass->shared_quad_state_list.front()
->quad_to_target_transform.Translate(10, 10);
root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
- SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+ SubmitPassListAsFrame(root_sink_.get(), root_local_surface_id_,
&root_pass_list, std::move(referenced_surfaces),
device_scale_factor);
}
@@ -4674,5 +4768,97 @@ TEST_F(SurfaceAggregatorPartialSwapTest, NotIgnoreOutsideForCachedRenderPass) {
}
}
+TEST_F(SurfaceAggregatorValidSurfaceTest, NoDamageIfNoFrameChange) {
+ // child surface
+ std::vector<Quad> child_surface_quads = {
+ Quad::SolidColorQuad(SK_ColorRED, gfx::Rect(SurfaceSize()))};
+ std::vector<Pass> child_surface_passes = {
+ Pass(child_surface_quads, 1, SurfaceSize())};
+
+ CompositorFrame child_surface_frame = MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame.render_pass_list, child_surface_passes,
+ &child_surface_frame.metadata.referenced_surfaces);
+
+ ParentLocalSurfaceIdAllocator allocator;
+ allocator.GenerateId();
+ LocalSurfaceId child_local_surface_id =
+ allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ SurfaceId child_surface_id(child_sink_->frame_sink_id(),
+ child_local_surface_id);
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame));
+
+ // root surface
+ std::vector<Quad> root_surface_quads = {
+ Quad::SurfaceQuad(SurfaceRange(base::nullopt, child_surface_id),
+ SK_ColorWHITE, gfx::Rect(SurfaceSize()),
+ /*stretch_content_to_fill_bounds=*/false,
+ /*ignores_input_event=*/false),
+ Quad::SolidColorQuad(SK_ColorGREEN, gfx::Rect(SurfaceSize()))};
+
+ std::vector<Pass> root_passes = {Pass(root_surface_quads, 1, SurfaceSize())};
+
+ CompositorFrame root_frame = MakeEmptyCompositorFrame();
+ AddPasses(&root_frame.render_pass_list, root_passes,
+ &root_frame.metadata.referenced_surfaces);
+
+ SurfaceId root_surface_id(root_sink_->frame_sink_id(),
+ root_local_surface_id_);
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame));
+ // The first frame - both root and child surfaces cause damages
+ CompositorFrame aggregated_frame =
+ aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
+
+ auto* root_render_pass = aggregated_frame.render_pass_list[0].get();
+ auto* root_surface_quad_sqs = root_render_pass->shared_quad_state_list.back();
+ auto* child_surface_quad_sqs =
+ root_render_pass->shared_quad_state_list.front();
+
+ ASSERT_EQ(1u, aggregated_frame.render_pass_list.size());
+ ASSERT_EQ(2u, root_render_pass->shared_quad_state_list.size());
+ EXPECT_EQ(true, root_surface_quad_sqs->has_surface_damage);
+ EXPECT_EQ(true, child_surface_quad_sqs->has_surface_damage);
+
+ // The second frame - only root surface changed
+ CompositorFrame root_frame2 = MakeEmptyCompositorFrame();
+ AddPasses(&root_frame2.render_pass_list, root_passes,
+ &root_frame2.metadata.referenced_surfaces);
+
+ root_sink_->SubmitCompositorFrame(root_local_surface_id_,
+ std::move(root_frame2));
+
+ CompositorFrame aggregated_frame2 =
+ aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
+
+ auto* root_render_pass2 = aggregated_frame2.render_pass_list[0].get();
+ auto* root_surface_quad_sqs2 =
+ root_render_pass2->shared_quad_state_list.back();
+ auto* child_surface_quad_sqs2 =
+ root_render_pass2->shared_quad_state_list.front();
+
+ EXPECT_EQ(true, root_surface_quad_sqs2->has_surface_damage);
+ EXPECT_EQ(false, child_surface_quad_sqs2->has_surface_damage);
+
+ // The third frame - only child surface changed
+ CompositorFrame child_surface_frame3 = MakeEmptyCompositorFrame();
+ AddPasses(&child_surface_frame3.render_pass_list, child_surface_passes,
+ &child_surface_frame3.metadata.referenced_surfaces);
+ child_sink_->SubmitCompositorFrame(child_local_surface_id,
+ std::move(child_surface_frame3));
+
+ CompositorFrame aggregated_frame3 =
+ aggregator_.Aggregate(root_surface_id, GetNextDisplayTimeAndIncrement());
+
+ auto* root_render_pass3 = aggregated_frame3.render_pass_list[0].get();
+ auto* root_surface_quad_sqs3 =
+ root_render_pass3->shared_quad_state_list.back();
+ auto* child_surface_quad_sqs3 =
+ root_render_pass3->shared_quad_state_list.front();
+
+ EXPECT_EQ(false, root_surface_quad_sqs3->has_surface_damage);
+ EXPECT_EQ(true, child_surface_quad_sqs3->has_surface_damage);
+}
+
} // namespace
} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/DEPS b/chromium/components/viz/service/display_embedder/DEPS
index 1246dfd2a43..34132c62935 100644
--- a/chromium/components/viz/service/display_embedder/DEPS
+++ b/chromium/components/viz/service/display_embedder/DEPS
@@ -36,11 +36,13 @@ include_rules = [
"+ui/ozone/public",
# TODO(danakj): Double check the layering for these dependencies.
+ "+components/viz/service/display/gl_renderer_copier.h",
"+components/viz/service/display/overlay_processor.h",
"+components/viz/service/display/overlay_strategy_fullscreen.h",
"+components/viz/service/display/overlay_strategy_single_on_top.h",
"+components/viz/service/display/overlay_strategy_underlay_cast.h",
"+components/viz/service/display/overlay_strategy_underlay.h",
+ "+components/viz/service/display/texture_deleter.h",
]
specific_include_rules = {
diff --git a/chromium/components/viz/service/display_embedder/buffer_queue.cc b/chromium/components/viz/service/display_embedder/buffer_queue.cc
index 197c59417a1..9fb0ab8b585 100644
--- a/chromium/components/viz/service/display_embedder/buffer_queue.cc
+++ b/chromium/components/viz/service/display_embedder/buffer_queue.cc
@@ -101,38 +101,45 @@ void BufferQueue::UpdateBufferDamage(const gfx::Rect& damage) {
}
}
-void BufferQueue::SwapBuffers(const gfx::Rect& damage) {
- if (damage.IsEmpty()) {
- in_flight_surfaces_.push_back(std::move(current_surface_));
+void BufferQueue::CopyDamageForCurrentSurface(const gfx::Rect& damage) {
+ if (!current_surface_)
return;
- }
- if (current_surface_) {
- if (damage != gfx::Rect(size_)) {
- // Copy damage from the most recently swapped buffer. In the event that
- // the buffer was destroyed and failed to recreate, pick from the most
- // recently available buffer.
- uint32_t texture_id = 0;
- for (auto& surface : base::Reversed(in_flight_surfaces_)) {
- if (surface) {
- texture_id = surface->texture;
- break;
- }
+ if (damage != gfx::Rect(size_)) {
+ // Copy damage from the most recently swapped buffer. In the event that
+ // the buffer was destroyed and failed to recreate, pick from the most
+ // recently available buffer.
+ uint32_t texture_id = 0;
+ for (auto& surface : base::Reversed(in_flight_surfaces_)) {
+ if (surface) {
+ texture_id = surface->texture;
+ break;
}
- if (!texture_id && displayed_surface_)
- texture_id = displayed_surface_->texture;
+ }
+ if (!texture_id && displayed_surface_)
+ texture_id = displayed_surface_->texture;
- if (texture_id) {
- CopyBufferDamage(current_surface_->texture, texture_id, damage,
- current_surface_->damage);
- }
+ if (texture_id) {
+ CopyBufferDamage(current_surface_->texture, texture_id, damage,
+ current_surface_->damage);
+ gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
}
- current_surface_->damage = gfx::Rect();
}
+ current_surface_->damage = gfx::Rect();
+}
+
+void BufferQueue::SwapBuffers(const gfx::Rect& damage) {
+ if (damage.IsEmpty()) {
+ in_flight_surfaces_.push_back(std::move(current_surface_));
+ return;
+ }
+
+ DCHECK(!current_surface_ || current_surface_->damage.IsEmpty());
UpdateBufferDamage(damage);
in_flight_surfaces_.push_back(std::move(current_surface_));
// Some things reset the framebuffer (CopyBufferDamage, some GLRenderer
// paths), so ensure we restore it here.
+ // TODO(khushalsagar): Not needed anymore. Remove this.
gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
}
@@ -299,6 +306,11 @@ std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() {
allocated_count_++;
gl_->BindTexture(texture_target_, texture);
gl_->BindTexImage2DCHROMIUM(texture_target_, id);
+
+ // The texture must be bound to the image before setting the color space.
+ gl_->SetColorSpaceMetadataCHROMIUM(
+ texture, reinterpret_cast<GLColorSpace>(&color_space_));
+
return std::make_unique<AllocatedSurface>(this, std::move(buffer), texture,
id, stencil, gfx::Rect(size_));
}
diff --git a/chromium/components/viz/service/display_embedder/buffer_queue.h b/chromium/components/viz/service/display_embedder/buffer_queue.h
index 8b26330a819..b7314e8f5a5 100644
--- a/chromium/components/viz/service/display_embedder/buffer_queue.h
+++ b/chromium/components/viz/service/display_embedder/buffer_queue.h
@@ -59,6 +59,7 @@ class VIZ_SERVICE_EXPORT BufferQueue {
bool use_stencil);
void RecreateBuffers();
uint32_t GetCurrentTextureId() const;
+ void CopyDamageForCurrentSurface(const gfx::Rect& damage);
uint32_t fbo() const { return fbo_; }
uint32_t internal_format() const { return internal_format_; }
diff --git a/chromium/components/viz/service/display_embedder/buffer_queue_unittest.cc b/chromium/components/viz/service/display_embedder/buffer_queue_unittest.cc
index 6dddb7b8c06..a641dfbdcc4 100644
--- a/chromium/components/viz/service/display_embedder/buffer_queue_unittest.cc
+++ b/chromium/components/viz/service/display_embedder/buffer_queue_unittest.cc
@@ -187,15 +187,18 @@ class BufferQueueTest : public ::testing::Test {
}
}
- void SwapBuffers() {
- output_surface_->SwapBuffers(gfx::Rect(output_surface_->size_));
+ void SwapBuffers(const gfx::Rect& damage) {
+ output_surface_->CopyDamageForCurrentSurface(damage);
+ output_surface_->SwapBuffers(damage);
}
+ void SwapBuffers() { SwapBuffers(gfx::Rect(output_surface_->size_)); }
+
void SendDamagedFrame(const gfx::Rect& damage) {
// We don't care about the GL-level implementation here, just how it uses
// damage rects.
output_surface_->BindFramebuffer();
- output_surface_->SwapBuffers(damage);
+ SwapBuffers(damage);
if (doublebuffering_ || !first_frame_)
output_surface_->PageFlipComplete();
first_frame_ = false;
@@ -348,9 +351,11 @@ TEST(BufferQueueStandaloneTest, CheckBoundFramebuffer) {
output_surface->Reshape(screen_size, 1.0f, gfx::ColorSpace(), false);
// Trigger a sub-buffer copy to exercise all paths.
output_surface->BindFramebuffer();
+ output_surface->CopyDamageForCurrentSurface(screen_rect);
output_surface->SwapBuffers(screen_rect);
output_surface->PageFlipComplete();
output_surface->BindFramebuffer();
+ output_surface->CopyDamageForCurrentSurface(small_damage);
output_surface->SwapBuffers(small_damage);
int current_fbo = 0;
@@ -682,13 +687,13 @@ TEST_F(BufferQueueTest, AllocateFails) {
// Succeed in the two swaps.
output_surface_->BindFramebuffer();
EXPECT_TRUE(current_frame());
- output_surface_->SwapBuffers(screen_rect);
+ SwapBuffers(screen_rect);
// Fail the next surface allocation.
gpu_memory_buffer_manager_->set_allocate_succeeds(false);
output_surface_->BindFramebuffer();
EXPECT_FALSE(current_frame());
- output_surface_->SwapBuffers(screen_rect);
+ SwapBuffers(screen_rect);
EXPECT_FALSE(current_frame());
// Try another swap. It should copy the buffer damage from the back
@@ -701,7 +706,7 @@ TEST_F(BufferQueueTest, AllocateFails) {
EXPECT_CALL(*mock_output_surface_,
CopyBufferDamage(target_texture, source_texture, small_damage, _))
.Times(1);
- output_surface_->SwapBuffers(small_damage);
+ SwapBuffers(small_damage);
testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
// Destroy the just-created buffer, and try another swap. The copy should
@@ -721,7 +726,7 @@ TEST_F(BufferQueueTest, AllocateFails) {
EXPECT_CALL(*mock_output_surface_,
CopyBufferDamage(target_texture, source_texture, small_damage, _))
.Times(1);
- output_surface_->SwapBuffers(small_damage);
+ SwapBuffers(small_damage);
testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
}
diff --git a/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc b/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
index 845d211f099..6a06990d117 100644
--- a/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
+++ b/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
@@ -8,8 +8,6 @@
#include <utility>
-#include "base/bind.h"
-#include "base/strings/string_split.h"
#include "components/viz/service/display/overlay_strategy_fullscreen.h"
#include "components/viz/service/display/overlay_strategy_single_on_top.h"
#include "components/viz/service/display/overlay_strategy_underlay.h"
@@ -17,60 +15,44 @@
#include "ui/ozone/public/overlay_candidates_ozone.h"
namespace viz {
-namespace {
-// Templated function used to create an OverlayProcessor::Strategy
-// of type |S|.
-template <typename S>
-std::unique_ptr<OverlayProcessor::Strategy> MakeOverlayStrategy(
- CompositorOverlayCandidateValidatorOzone* capability_checker) {
- return std::make_unique<S>(capability_checker);
-}
-
-} // namespace
// |overlay_candidates| is an object used to answer questions about possible
// overlays configurations.
-// |strategies_string| is a comma-separated string containing all the overlay
-// strategies that should be returned by GetStrategies.
-// If |strategies_string| is empty "single-on-top,underlay" will be used as
-// default.
+// |strategies_string| is a list of overlay strategies that should be returned
+// by GetStrategies.
CompositorOverlayCandidateValidatorOzone::
CompositorOverlayCandidateValidatorOzone(
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
- std::string strategies_string)
+ std::vector<OverlayStrategy> strategies)
: overlay_candidates_(std::move(overlay_candidates)),
- software_mirror_active_(false) {
- if (!strategies_string.length())
- strategies_string = "single-on-top,underlay";
-
- for (const auto& strategy_name :
- base::SplitStringPiece(strategies_string, ",", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY)) {
- if (strategy_name == "single-fullscreen") {
- strategies_instantiators_.push_back(
- base::BindRepeating(MakeOverlayStrategy<OverlayStrategyFullscreen>));
- } else if (strategy_name == "single-on-top") {
- strategies_instantiators_.push_back(
- base::BindRepeating(MakeOverlayStrategy<OverlayStrategySingleOnTop>));
- } else if (strategy_name == "underlay") {
- strategies_instantiators_.push_back(
- base::BindRepeating(MakeOverlayStrategy<OverlayStrategyUnderlay>));
- } else if (strategy_name == "cast") {
- strategies_instantiators_.push_back(base::BindRepeating(
- MakeOverlayStrategy<OverlayStrategyUnderlayCast>));
- } else {
- LOG(WARNING) << "Unrecognized overlay strategy " << strategy_name;
- }
- }
-}
+ strategies_(std::move(strategies)) {}
CompositorOverlayCandidateValidatorOzone::
~CompositorOverlayCandidateValidatorOzone() {}
void CompositorOverlayCandidateValidatorOzone::GetStrategies(
OverlayProcessor::StrategyList* strategies) {
- for (auto& instantiator : strategies_instantiators_)
- strategies->push_back(instantiator.Run(this));
+ for (OverlayStrategy strategy : strategies_) {
+ switch (strategy) {
+ case OverlayStrategy::kFullscreen:
+ strategies->push_back(
+ std::make_unique<OverlayStrategyFullscreen>(this));
+ break;
+ case OverlayStrategy::kSingleOnTop:
+ strategies->push_back(
+ std::make_unique<OverlayStrategySingleOnTop>(this));
+ break;
+ case OverlayStrategy::kUnderlay:
+ strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(this));
+ break;
+ case OverlayStrategy::kUnderlayCast:
+ strategies->push_back(
+ std::make_unique<OverlayStrategyUnderlayCast>(this));
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
}
bool CompositorOverlayCandidateValidatorOzone::AllowCALayerOverlays() {
diff --git a/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h b/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h
index cca7a65b00b..b1e657e4d0a 100644
--- a/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h
+++ b/chromium/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h
@@ -6,9 +6,10 @@
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_
#include <memory>
+#include <vector>
-#include "base/callback.h"
#include "base/macros.h"
+#include "components/viz/common/display/overlay_strategy.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
#include "components/viz/service/viz_service_export.h"
#include "ui/gfx/native_widget_types.h"
@@ -24,7 +25,7 @@ class VIZ_SERVICE_EXPORT CompositorOverlayCandidateValidatorOzone
public:
CompositorOverlayCandidateValidatorOzone(
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates,
- std::string strategies_string);
+ std::vector<OverlayStrategy> strategies);
~CompositorOverlayCandidateValidatorOzone() override;
// OverlayCandidateValidator implementation.
@@ -38,14 +39,8 @@ class VIZ_SERVICE_EXPORT CompositorOverlayCandidateValidatorOzone
private:
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_;
- // Callback declaration to allocate a new OverlayProcessor::Strategy.
- using StrategyInstantiator =
- base::RepeatingCallback<std::unique_ptr<OverlayProcessor::Strategy>(
- CompositorOverlayCandidateValidatorOzone*)>;
- // List callbacks used to instantiate OverlayProcessor::Strategy
- // as defined by |strategies_string| paramter in the constructor.
- std::vector<StrategyInstantiator> strategies_instantiators_;
- bool software_mirror_active_;
+ const std::vector<OverlayStrategy> strategies_;
+ bool software_mirror_active_ = false;
DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorOzone);
};
diff --git a/chromium/components/viz/service/display_embedder/direct_context_provider.cc b/chromium/components/viz/service/display_embedder/direct_context_provider.cc
new file mode 100644
index 00000000000..3830a6eeb34
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/direct_context_provider.cc
@@ -0,0 +1,340 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/direct_context_provider.h"
+
+#include <stdint.h>
+
+#include <utility>
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "build/build_config.h"
+#include "components/viz/common/gpu/context_lost_observer.h"
+#include "components/viz/common/gpu/context_lost_reason.h"
+#include "gpu/command_buffer/client/gles2_cmd_helper.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/shared_memory_limits.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
+#include "gpu/command_buffer/common/context_creation_attribs.h"
+#include "gpu/command_buffer/service/command_buffer_direct.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/memory_tracking.h"
+#include "gpu/config/gpu_feature_info.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_surface.h"
+
+namespace viz {
+
+DirectContextProvider::DirectContextProvider(
+ scoped_refptr<gl::GLContext> gl_context,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ bool supports_alpha,
+ const gpu::GpuPreferences& gpu_preferences,
+ gpu::gles2::FeatureInfo* feature_info)
+ : translator_cache_(gpu_preferences) {
+ DCHECK(gl_context->IsCurrent(gl_surface.get()));
+
+ auto limits = gpu::SharedMemoryLimits::ForMailboxContext();
+ auto group = base::MakeRefCounted<gpu::gles2::ContextGroup>(
+ gpu_preferences, true, &mailbox_manager_, /*memory_tracker=*/nullptr,
+ &translator_cache_, &completeness_cache_, feature_info, true,
+ &image_manager_, /*image_factory=*/nullptr,
+ /*progress_reporter=*/nullptr, gpu_feature_info_, &discardable_manager_,
+ &passthrough_discardable_manager_, &shared_image_manager_);
+
+ auto command_buffer = std::make_unique<gpu::CommandBufferDirect>();
+
+ std::unique_ptr<gpu::gles2::GLES2Decoder> decoder(
+ gpu::gles2::GLES2Decoder::Create(command_buffer.get(),
+ command_buffer->service(), &outputter_,
+ group.get()));
+
+ if (gpu_preferences.enable_gpu_service_logging)
+ decoder->SetLogCommands(true);
+
+ command_buffer->set_handler(decoder.get());
+
+ gpu::ContextCreationAttribs attribs;
+ attribs.alpha_size = supports_alpha ? 8 : 0;
+ attribs.buffer_preserved = false;
+ attribs.bind_generates_resource = true;
+ attribs.fail_if_major_perf_caveat = false;
+ attribs.lose_context_when_out_of_memory = true;
+ attribs.context_type = gpu::CONTEXT_TYPE_OPENGLES2;
+
+ context_result_ =
+ decoder->Initialize(gl_surface, gl_context, gl_surface->IsOffscreen(),
+ gpu::gles2::DisallowedFeatures(), attribs);
+ if (context_result_ != gpu::ContextResult::kSuccess)
+ return;
+
+ auto gles2_cmd_helper =
+ std::make_unique<gpu::gles2::GLES2CmdHelper>(command_buffer.get());
+ context_result_ = gles2_cmd_helper->Initialize(limits.command_buffer_size);
+ if (context_result_ != gpu::ContextResult::kSuccess) {
+ decoder->Destroy(true);
+ return;
+ }
+ // Client side Capabilities queries return reference, service side return
+ // value. Here two sides are joined together.
+ capabilities_ = decoder->GetCapabilities();
+
+ auto transfer_buffer =
+ std::make_unique<gpu::TransferBuffer>(gles2_cmd_helper.get());
+
+ gles2_cmd_helper_ = std::move(gles2_cmd_helper);
+ transfer_buffer_ = std::move(transfer_buffer);
+ command_buffer_ = std::move(command_buffer);
+ decoder_ = std::move(decoder);
+ gl_context_ = std::move(gl_context);
+
+ gles2_implementation_ = std::make_unique<gpu::gles2::GLES2Implementation>(
+ gles2_cmd_helper_.get(), nullptr, transfer_buffer_.get(),
+ attribs.bind_generates_resource, attribs.lose_context_when_out_of_memory,
+ /*kSupportClientSideArrays=*/false, this);
+
+ context_result_ = gles2_implementation_->Initialize(limits);
+ if (context_result_ != gpu::ContextResult::kSuccess) {
+ Destroy();
+ return;
+ }
+
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ this, "viz::DirectContextProvider", base::ThreadTaskRunnerHandle::Get());
+
+ // TraceEndCHROMIUM is implicit when the context is destroyed
+ gles2_implementation_->TraceBeginCHROMIUM("VizCompositor",
+ "DisplayCompositor");
+}
+
+DirectContextProvider::~DirectContextProvider() {
+ if (decoder_)
+ Destroy();
+}
+
+void DirectContextProvider::Destroy() {
+ DCHECK(decoder_);
+ bool have_context = !decoder_->WasContextLost();
+ if (have_context && framebuffer_id_ != 0) {
+ gles2_implementation_->DeleteFramebuffers(1, &framebuffer_id_);
+ framebuffer_id_ = 0;
+ }
+
+ // The client gl interface might still be set to current global
+ // interface. This will be cleaned up in ApplyContextReleased
+ // with AutoCurrentContextRestore.
+ gles2_implementation_.reset();
+ gl_context_.reset();
+ transfer_buffer_.reset();
+ gles2_cmd_helper_.reset();
+ command_buffer_.reset();
+
+ decoder_->Destroy(have_context);
+ decoder_.reset();
+}
+
+void DirectContextProvider::SetGLRendererCopierRequiredState(
+ GLuint texture_client_id) {
+ // Get into known state (see
+ // SkiaOutputSurfaceImplOnGpu::ScopedUseContextProvider).
+ gles2_implementation_->BindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ decoder_->RestoreActiveTexture();
+ decoder_->RestoreProgramBindings();
+ decoder_->RestoreAllAttributes();
+ decoder_->RestoreGlobalState();
+ decoder_->RestoreBufferBindings();
+
+ if (texture_client_id) {
+ if (!framebuffer_id_)
+ gles2_implementation_->GenFramebuffers(1, &framebuffer_id_);
+ gles2_implementation_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
+ gles2_implementation_->FramebufferTexture2D(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_client_id,
+ 0);
+ DCHECK_EQ(gles2_implementation_->CheckFramebufferStatus(GL_FRAMEBUFFER),
+ static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE));
+ }
+}
+
+gpu::gles2::TextureManager* DirectContextProvider::texture_manager() {
+ return decoder_->GetContextGroup()->texture_manager();
+}
+
+void DirectContextProvider::AddRef() const {
+ base::RefCountedThreadSafe<DirectContextProvider>::AddRef();
+}
+
+void DirectContextProvider::Release() const {
+ base::RefCountedThreadSafe<DirectContextProvider>::Release();
+}
+
+gpu::ContextResult DirectContextProvider::BindToCurrentThread() {
+ return context_result_;
+}
+
+gpu::gles2::GLES2Interface* DirectContextProvider::ContextGL() {
+ return gles2_implementation_.get();
+}
+
+gpu::ContextSupport* DirectContextProvider::ContextSupport() {
+ return gles2_implementation_.get();
+}
+
+class GrContext* DirectContextProvider::GrContext() {
+ NOTREACHED();
+ return nullptr;
+}
+
+gpu::SharedImageInterface* DirectContextProvider::SharedImageInterface() {
+ NOTREACHED();
+ return nullptr;
+}
+
+ContextCacheController* DirectContextProvider::CacheController() {
+ NOTREACHED();
+ return nullptr;
+}
+
+base::Lock* DirectContextProvider::GetLock() {
+ NOTREACHED();
+ return nullptr;
+}
+
+const gpu::Capabilities& DirectContextProvider::ContextCapabilities() const {
+ return capabilities_;
+}
+
+const gpu::GpuFeatureInfo& DirectContextProvider::GetGpuFeatureInfo() const {
+ return gpu_feature_info_;
+}
+
+void DirectContextProvider::AddObserver(ContextLostObserver* obs) {
+ observers_.AddObserver(obs);
+}
+
+void DirectContextProvider::RemoveObserver(ContextLostObserver* obs) {
+ observers_.RemoveObserver(obs);
+}
+
+void DirectContextProvider::OnContextLost() {
+ // TODO(https://crbug.com/927460): Instrument this with a context loss UMA
+ // stat shared with SkiaRenderer.
+ for (auto& observer : observers_)
+ observer.OnContextLost();
+}
+
+bool DirectContextProvider::OnMemoryDump(
+ const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) {
+ DCHECK_EQ(context_result_, gpu::ContextResult::kSuccess);
+
+ gles2_implementation_->OnMemoryDump(args, pmd);
+ gles2_cmd_helper_->OnMemoryDump(args, pmd);
+
+ return true;
+}
+
+void DirectContextProvider::SetGpuControlClient(gpu::GpuControlClient*) {
+ // The client is not currently called, so don't store it.
+}
+
+const gpu::Capabilities& DirectContextProvider::GetCapabilities() const {
+ return capabilities_;
+}
+
+int32_t DirectContextProvider::CreateImage(ClientBuffer buffer,
+ size_t width,
+ size_t height) {
+ NOTREACHED();
+ return -1;
+}
+
+void DirectContextProvider::DestroyImage(int32_t id) {
+ NOTREACHED();
+}
+
+void DirectContextProvider::SignalQuery(uint32_t query,
+ base::OnceClosure callback) {
+ decoder_->SetQueryCallback(query, std::move(callback));
+}
+
+void DirectContextProvider::CreateGpuFence(uint32_t gpu_fence_id,
+ ClientGpuFence source) {
+ NOTREACHED();
+}
+
+void DirectContextProvider::GetGpuFence(
+ uint32_t gpu_fence_id,
+ base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) {
+ NOTREACHED();
+}
+
+void DirectContextProvider::SetLock(base::Lock*) {
+ NOTREACHED();
+}
+
+void DirectContextProvider::EnsureWorkVisible() {
+ NOTREACHED();
+}
+
+gpu::CommandBufferNamespace DirectContextProvider::GetNamespaceID() const {
+ return gpu::CommandBufferNamespace::INVALID;
+}
+
+gpu::CommandBufferId DirectContextProvider::GetCommandBufferID() const {
+ return gpu::CommandBufferId();
+}
+
+void DirectContextProvider::FlushPendingWork() {
+ NOTREACHED();
+}
+
+uint64_t DirectContextProvider::GenerateFenceSyncRelease() {
+ NOTREACHED();
+ return 0;
+}
+
+bool DirectContextProvider::IsFenceSyncReleased(uint64_t release) {
+ NOTREACHED();
+ return false;
+}
+
+void DirectContextProvider::SignalSyncToken(const gpu::SyncToken& sync_token,
+ base::OnceClosure callback) {
+ NOTREACHED();
+}
+
+void DirectContextProvider::WaitSyncToken(const gpu::SyncToken& sync_token) {
+ NOTREACHED();
+}
+
+bool DirectContextProvider::CanWaitUnverifiedSyncToken(
+ const gpu::SyncToken& sync_token) {
+ return false;
+}
+
+GLuint DirectContextProvider::GenClientTextureId() {
+ const auto& share_group = gles2_implementation_->share_group();
+ auto* id_handler =
+ share_group->GetIdHandler(gpu::gles2::SharedIdNamespaces::kTextures);
+ GLuint client_id;
+ id_handler->MakeIds(gles2_implementation_.get(), 0, 1, &client_id);
+ return client_id;
+}
+
+void DirectContextProvider::DeleteClientTextureId(GLuint client_id) {
+ gles2_implementation_->DeleteTextures(1, &client_id);
+}
+
+void DirectContextProvider::MarkContextLost() {
+ if (!decoder_->WasContextLost()) {
+ decoder_->MarkContextLost(gpu::error::kUnknown);
+ command_buffer_->service()->SetParseError(gpu::error::kLostContext);
+ OnContextLost();
+ }
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/direct_context_provider.h b/chromium/components/viz/service/display_embedder/direct_context_provider.h
new file mode 100644
index 00000000000..d87c3d497b7
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/direct_context_provider.h
@@ -0,0 +1,151 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DIRECT_CONTEXT_PROVIDER_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DIRECT_CONTEXT_PROVIDER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
+#include "base/trace_event/memory_dump_provider.h"
+#include "components/viz/common/gpu/context_provider.h"
+#include "components/viz/service/viz_service_export.h"
+#include "gpu/command_buffer/client/gpu_control.h"
+#include "gpu/command_buffer/common/context_result.h"
+#include "gpu/command_buffer/service/gpu_tracer.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager_impl.h"
+#include "gpu/command_buffer/service/passthrough_discardable_manager.h"
+#include "gpu/command_buffer/service/service_discardable_manager.h"
+#include "gpu/command_buffer/service/shared_image_manager.h"
+class GrContext;
+
+namespace gpu {
+class CommandBufferDirect;
+class DecoderContext;
+class TransferBuffer;
+struct GpuPreferences;
+
+namespace gles2 {
+class GLES2CmdHelper;
+class GLES2Implementation;
+class GLES2Interface;
+class TextureManager;
+} // namespace gles2
+} // namespace gpu
+
+namespace viz {
+class ContextLostObserver;
+
+// DirectContextProvider provides a GLES2Interface by running cross process code
+// (e.g. GLES2Implementation and GLES2Decoder) within a single thread. It is
+// suitable for easily porting code relying on GLES2Interface, but is less
+// efficient than calling native GL because it serializes/deserializes command
+// streams, validates command streams, and has unnecessary copies through shared
+// memory (e.g. glReadPixels frame buffer). Parts of GLES2Interface are
+// NOTIMPLEMENTED().
+class VIZ_SERVICE_EXPORT DirectContextProvider
+ : public base::RefCountedThreadSafe<DirectContextProvider>,
+ public ContextProvider,
+ public gpu::GpuControl,
+ public base::trace_event::MemoryDumpProvider {
+ public:
+ DirectContextProvider(scoped_refptr<gl::GLContext> gl_context,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ bool supports_alpha,
+ const gpu::GpuPreferences& gpu_preferences,
+ gpu::gles2::FeatureInfo* feature_info);
+ gpu::DecoderContext* decoder() { return decoder_.get(); }
+
+ // Set required state, including texture_client_id as color attachment 0
+ // of a currently bound framebuffer. If texture_client_id == 0, set FBO0 as
+ // current.
+ void SetGLRendererCopierRequiredState(GLuint texture_client_id);
+ gpu::gles2::TextureManager* texture_manager();
+ GLuint GenClientTextureId();
+ void DeleteClientTextureId(GLuint client_id);
+ void MarkContextLost();
+
+ // ContextProvider implementation.
+ void AddRef() const override;
+ void Release() const override;
+ gpu::ContextResult BindToCurrentThread() override;
+ gpu::gles2::GLES2Interface* ContextGL() override;
+ gpu::ContextSupport* ContextSupport() override;
+ class GrContext* GrContext() override;
+ gpu::SharedImageInterface* SharedImageInterface() override;
+ ContextCacheController* CacheController() override;
+ base::Lock* GetLock() override;
+ const gpu::Capabilities& ContextCapabilities() const override;
+ const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override;
+ void AddObserver(ContextLostObserver* obs) override;
+ void RemoveObserver(ContextLostObserver* obs) override;
+
+ // GpuControl implementation.
+ void SetGpuControlClient(gpu::GpuControlClient*) override;
+ const gpu::Capabilities& GetCapabilities() const override;
+ int32_t CreateImage(ClientBuffer buffer,
+ size_t width,
+ size_t height) override;
+ void DestroyImage(int32_t id) override;
+ void SignalQuery(uint32_t query, base::OnceClosure callback) override;
+ void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override;
+ void GetGpuFence(uint32_t gpu_fence_id,
+ base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
+ callback) override;
+ void SetLock(base::Lock*) override;
+ void EnsureWorkVisible() override;
+ gpu::CommandBufferNamespace GetNamespaceID() const override;
+ gpu::CommandBufferId GetCommandBufferID() const override;
+ void FlushPendingWork() override;
+ uint64_t GenerateFenceSyncRelease() override;
+ bool IsFenceSyncReleased(uint64_t release) override;
+ void SignalSyncToken(const gpu::SyncToken& sync_token,
+ base::OnceClosure callback) override;
+ void WaitSyncToken(const gpu::SyncToken& sync_token) override;
+ bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override;
+
+ private:
+ friend class base::RefCountedThreadSafe<DirectContextProvider>;
+ ~DirectContextProvider() override;
+
+ void Destroy();
+ void OnContextLost();
+
+ // base::trace_event::MemoryDumpProvider implementation.
+ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+ base::trace_event::ProcessMemoryDump* pmd) override;
+
+ gpu::gles2::MailboxManagerImpl mailbox_manager_;
+ gpu::gles2::TraceOutputter outputter_;
+ gpu::gles2::ImageManager image_manager_;
+ gpu::ServiceDiscardableManager discardable_manager_;
+ gpu::PassthroughDiscardableManager passthrough_discardable_manager_;
+ gpu::SharedImageManager shared_image_manager_;
+ gpu::gles2::ShaderTranslatorCache translator_cache_;
+ gpu::gles2::FramebufferCompletenessCache completeness_cache_;
+ gpu::GpuFeatureInfo gpu_feature_info_;
+ gpu::Capabilities capabilities_;
+ gpu::ContextResult context_result_ = gpu::ContextResult::kSuccess;
+
+ // Only non-null if BindToCurrentThread() == ContextResult::kSuccess.
+ std::unique_ptr<gpu::CommandBufferDirect> command_buffer_;
+ std::unique_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
+ std::unique_ptr<gpu::gles2::GLES2Decoder> decoder_;
+ std::unique_ptr<gpu::TransferBuffer> transfer_buffer_;
+ scoped_refptr<gl::GLContext> gl_context_;
+ std::unique_ptr<gpu::gles2::GLES2Implementation> gles2_implementation_;
+
+ GLuint framebuffer_id_ = 0;
+
+ base::ObserverList<ContextLostObserver>::Unchecked observers_;
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DIRECT_CONTEXT_PROVIDER_H_
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface.cc b/chromium/components/viz/service/display_embedder/gl_output_surface.cc
index 35cee0df783..3da59a892f0 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface.cc
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface.cc
@@ -4,7 +4,8 @@
#include "components/viz/service/display_embedder/gl_output_surface.h"
-#include <stdint.h>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -66,6 +67,9 @@ void GLOutputSurface::BindFramebuffer() {
}
void GLOutputSurface::SetDrawRectangle(const gfx::Rect& rect) {
+ if (!context_provider_->ContextCapabilities().dc_layers)
+ return;
+
if (set_draw_rectangle_for_frame_)
return;
DCHECK(gfx::Rect(size_).Contains(rect));
@@ -107,6 +111,10 @@ void GLOutputSurface::SwapBuffers(OutputSurfaceFrame frame) {
if (frame.sub_buffer_rect) {
HandlePartialSwap(*frame.sub_buffer_rect, flags, std::move(swap_callback),
std::move(presentation_callback));
+ } else if (!frame.content_bounds.empty()) {
+ context_provider_->ContextSupport()->SwapWithBounds(
+ frame.content_bounds, flags, std::move(swap_callback),
+ std::move(presentation_callback));
} else {
context_provider_->ContextSupport()->Swap(flags, std::move(swap_callback),
std::move(presentation_callback));
@@ -188,13 +196,6 @@ void GLOutputSurface::OnPresentation(
client_->DidReceivePresentationFeedback(feedback);
}
-#if BUILDFLAG(ENABLE_VULKAN)
-gpu::VulkanSurface* GLOutputSurface::GetVulkanSurface() {
- NOTIMPLEMENTED();
- return nullptr;
-}
-#endif
-
unsigned GLOutputSurface::UpdateGpuFence() {
if (!use_gpu_fence_)
return 0;
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface.h b/chromium/components/viz/service/display_embedder/gl_output_surface.h
index e64b657c9d2..0556d3a6c36 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface.h
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface.h
@@ -43,9 +43,6 @@ class GLOutputSurface : public OutputSurface {
gfx::BufferFormat GetOverlayBufferFormat() const override;
bool HasExternalStencilTest() const override;
void ApplyExternalStencil() override;
-#if BUILDFLAG(ENABLE_VULKAN)
- gpu::VulkanSurface* GetVulkanSurface() override;
-#endif
unsigned UpdateGpuFence() override;
void SetNeedsSwapSizeNotifications(
bool needs_swap_size_notifications) override;
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_android.cc b/chromium/components/viz/service/display_embedder/gl_output_surface_android.cc
index c5bd5a8c545..b5bf7cde459 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_android.cc
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_android.cc
@@ -10,10 +10,14 @@ namespace viz {
GLOutputSurfaceAndroid::GLOutputSurfaceAndroid(
scoped_refptr<VizProcessContextProvider> context_provider,
- SyntheticBeginFrameSource* synthetic_begin_frame_source)
- : GLOutputSurface(context_provider, synthetic_begin_frame_source),
- overlay_candidate_validator_(
- std::make_unique<CompositorOverlayCandidateValidatorAndroid>()) {}
+ SyntheticBeginFrameSource* synthetic_begin_frame_source,
+ bool allow_overlays)
+ : GLOutputSurface(context_provider, synthetic_begin_frame_source) {
+ if (allow_overlays) {
+ overlay_candidate_validator_ =
+ std::make_unique<CompositorOverlayCandidateValidatorAndroid>();
+ }
+}
GLOutputSurfaceAndroid::~GLOutputSurfaceAndroid() = default;
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_android.h b/chromium/components/viz/service/display_embedder/gl_output_surface_android.h
index e10c4630179..b39b06861d9 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_android.h
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_android.h
@@ -16,7 +16,8 @@ class GLOutputSurfaceAndroid : public GLOutputSurface {
public:
GLOutputSurfaceAndroid(
scoped_refptr<VizProcessContextProvider> context_provider,
- SyntheticBeginFrameSource* synthetic_begin_frame_source);
+ SyntheticBeginFrameSource* synthetic_begin_frame_source,
+ bool allow_overlays);
~GLOutputSurfaceAndroid() override;
// GLOutputSurface implementation:
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
index 7f0ae294788..fc58592bd9a 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
@@ -37,15 +37,13 @@ GLOutputSurfaceBufferQueue::GLOutputSurfaceBufferQueue(
// implementation.
capabilities_.max_frames_pending = 2;
- buffer_queue_.reset(new BufferQueue(
+ buffer_queue_ = std::make_unique<BufferQueue>(
context_provider->ContextGL(), target, internalformat, buffer_format,
- gpu_memory_buffer_manager, surface_handle));
+ gpu_memory_buffer_manager, surface_handle);
buffer_queue_->Initialize();
}
-GLOutputSurfaceBufferQueue::~GLOutputSurfaceBufferQueue() {
- // TODO(rjkroege): Support cleanup.
-}
+GLOutputSurfaceBufferQueue::~GLOutputSurfaceBufferQueue() = default;
void GLOutputSurfaceBufferQueue::BindFramebuffer() {
DCHECK(buffer_queue_);
@@ -69,6 +67,11 @@ void GLOutputSurfaceBufferQueue::Reshape(const gfx::Size& size,
buffer_queue_->Reshape(size, device_scale_factor, color_space, use_stencil);
}
+void GLOutputSurfaceBufferQueue::SetDrawRectangle(const gfx::Rect& damage) {
+ GLOutputSurface::SetDrawRectangle(damage);
+ buffer_queue_->CopyDamageForCurrentSurface(damage);
+}
+
void GLOutputSurfaceBufferQueue::SwapBuffers(OutputSurfaceFrame frame) {
DCHECK(buffer_queue_);
@@ -89,7 +92,6 @@ uint32_t GLOutputSurfaceBufferQueue::GetFramebufferCopyTextureFormat() {
}
bool GLOutputSurfaceBufferQueue::IsDisplayedAsOverlayPlane() const {
- // TODO(rjkroege): implement remaining overlay functionality.
return true;
}
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h
index 817ebee82c8..3366d783de4 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h
@@ -58,6 +58,7 @@ class GLOutputSurfaceBufferQueue : public GLOutputSurface {
bool IsDisplayedAsOverlayPlane() const override;
unsigned GetOverlayTextureId() const override;
gfx::BufferFormat GetOverlayBufferFormat() const override;
+ void SetDrawRectangle(const gfx::Rect& damage) override;
// GLOutputSurface:
void DidReceiveSwapBuffersAck(gfx::SwapResult result) override;
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc
index 9e99733e523..f208e87aa77 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc
@@ -4,41 +4,14 @@
#include "components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h"
-#include "components/viz/service/display/overlay_strategy_single_on_top.h"
-#include "components/viz/service/display/overlay_strategy_underlay.h"
-#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h"
#include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/geometry/rect_conversions.h"
namespace viz {
namespace {
-class OverlayCandidateValidatorImpl : public OverlayCandidateValidator {
- public:
- OverlayCandidateValidatorImpl() = default;
- ~OverlayCandidateValidatorImpl() override = default;
- void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
- strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(
- this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
- }
- bool AllowCALayerOverlays() override { return false; }
- bool AllowDCLayerOverlays() override { return false; }
- void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
- DCHECK(!surfaces->empty());
-
- // Only update the last candidate that was added to the list. All previous
- // overlays should have already been handled.
- auto& candidate = surfaces->back();
- candidate.display_rect =
- gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
- candidate.overlay_handled = true;
-
-#if DCHECK_IS_ON()
- for (auto& candidate : *surfaces)
- DCHECK(candidate.overlay_handled);
-#endif
- }
-};
+uint32_t TextureFormat(gfx::BufferFormat format) {
+ return format == gfx::BufferFormat::BGR_565 ? GL_RGB : GL_RGBA;
+}
} // namespace
@@ -53,27 +26,17 @@ GLOutputSurfaceBufferQueueAndroid::GLOutputSurfaceBufferQueueAndroid(
synthetic_begin_frame_source,
gpu_memory_buffer_manager,
GL_TEXTURE_2D,
- GL_RGBA,
- buffer_format),
- overlay_candidate_validator_(
- std::make_unique<OverlayCandidateValidatorImpl>()) {}
+ TextureFormat(buffer_format),
+ buffer_format) {}
GLOutputSurfaceBufferQueueAndroid::~GLOutputSurfaceBufferQueueAndroid() =
default;
-void GLOutputSurfaceBufferQueueAndroid::HandlePartialSwap(
- const gfx::Rect& sub_buffer_rect,
- uint32_t flags,
- gpu::ContextSupport::SwapCompletedCallback swap_callback,
- gpu::ContextSupport::PresentationCallback presentation_callback) {
- DCHECK(sub_buffer_rect.IsEmpty());
- context_provider_->ContextSupport()->CommitOverlayPlanes(
- flags, std::move(swap_callback), std::move(presentation_callback));
-}
-
OverlayCandidateValidator*
GLOutputSurfaceBufferQueueAndroid::GetOverlayCandidateValidator() const {
- return overlay_candidate_validator_.get();
+ // TODO(khushalsagar): The API shouldn't be const.
+ return &const_cast<GLOutputSurfaceBufferQueueAndroid*>(this)
+ ->overlay_candidate_validator_;
}
} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h
index 822a78d77ef..bf8f72c743e 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h
@@ -6,6 +6,8 @@
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_BUFFER_QUEUE_ANDROID_H_
#include "components/viz/service/display_embedder/gl_output_surface_buffer_queue.h"
+
+#include "components/viz/service/display_embedder/overlay_candidate_validator_android.h"
#include "ui/gfx/buffer_types.h"
namespace viz {
@@ -21,15 +23,10 @@ class GLOutputSurfaceBufferQueueAndroid : public GLOutputSurfaceBufferQueue {
~GLOutputSurfaceBufferQueueAndroid() override;
// GLOutputSurfaceBufferQueue implementation:
- void HandlePartialSwap(
- const gfx::Rect& sub_buffer_rect,
- uint32_t flags,
- gpu::ContextSupport::SwapCompletedCallback swap_callback,
- gpu::ContextSupport::PresentationCallback presentation_callback) override;
OverlayCandidateValidator* GetOverlayCandidateValidator() const override;
private:
- std::unique_ptr<OverlayCandidateValidator> overlay_candidate_validator_;
+ OverlayCandidateValidatorAndroid overlay_candidate_validator_;
DISALLOW_COPY_AND_ASSIGN(GLOutputSurfaceBufferQueueAndroid);
};
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.cc b/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.cc
index 8c42482ba2c..6a563a52177 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.cc
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.cc
@@ -23,6 +23,12 @@ GLOutputSurfaceOzone::GLOutputSurfaceOzone(
internal_format,
display::DisplaySnapshot::PrimaryFormat()) {}
-GLOutputSurfaceOzone::~GLOutputSurfaceOzone() {}
+GLOutputSurfaceOzone::~GLOutputSurfaceOzone() = default;
+
+OverlayCandidateValidator* GLOutputSurfaceOzone::GetOverlayCandidateValidator()
+ const {
+ // TODO(crbug.com/930173): Implement overlay functionality.
+ return nullptr;
+}
} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.h b/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.h
index 47a7cffb50f..3dc09198488 100644
--- a/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.h
+++ b/chromium/components/viz/service/display_embedder/gl_output_surface_ozone.h
@@ -20,6 +20,9 @@ class GLOutputSurfaceOzone : public GLOutputSurfaceBufferQueue {
uint32_t internal_format);
~GLOutputSurfaceOzone() override;
+ // OutputSurface implementation.
+ OverlayCandidateValidator* GetOverlayCandidateValidator() const override;
+
private:
DISALLOW_COPY_AND_ASSIGN(GLOutputSurfaceOzone);
};
diff --git a/chromium/components/viz/service/display_embedder/gpu_display_provider.cc b/chromium/components/viz/service/display_embedder/gpu_display_provider.cc
index 53053fceb49..65e543b2c15 100644
--- a/chromium/components/viz/service/display_embedder/gpu_display_provider.cc
+++ b/chromium/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -18,17 +18,22 @@
#include "components/viz/service/display_embedder/gl_output_surface_offscreen.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/display_embedder/skia_output_surface_impl.h"
+#include "components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h"
#include "components/viz/service/display_embedder/software_output_surface.h"
#include "components/viz/service/display_embedder/viz_process_context_provider.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/service/image_factory.h"
+#include "gpu/command_buffer/service/mailbox_manager_factory.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/ipc/command_buffer_task_executor.h"
#include "gpu/ipc/common/surface_handle.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
+#include "gpu/ipc/service/image_transport_surface.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/init/gl_factory.h"
#if defined(OS_WIN)
#include "components/viz/service/display_embedder/gl_output_surface_win.h"
@@ -122,16 +127,46 @@ std::unique_ptr<Display> GpuDisplayProvider::CreateDisplay(
if (!gpu_compositing) {
output_surface = std::make_unique<SoftwareOutputSurface>(
- CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client));
- } else if (renderer_settings.use_skia_renderer) {
+ CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client),
+ synthetic_begin_frame_source);
+ } else if (renderer_settings.use_skia_renderer ||
+ renderer_settings.use_skia_renderer_non_ddl) {
#if defined(OS_MACOSX) || defined(OS_WIN)
- // TODO(penghuang): Support DDL for all platforms.
+ // TODO(penghuang): Support SkiaRenderer for all platforms.
NOTIMPLEMENTED();
return nullptr;
#else
- output_surface = std::make_unique<SkiaOutputSurfaceImpl>(
- gpu_service_impl_, surface_handle, synthetic_begin_frame_source,
- renderer_settings.show_overdraw_feedback);
+ if (renderer_settings.use_skia_renderer_non_ddl) {
+ DCHECK_EQ(gl::GetGLImplementation(), gl::kGLImplementationEGLGLES2)
+ << "SkiaRendererNonDDL is only supported with GLES2.";
+ auto gl_surface = gpu::ImageTransportSurface::CreateNativeSurface(
+ nullptr, surface_handle, gl::GLSurfaceFormat());
+ if (!shared_context_state_) {
+ auto gl_share_group = base::MakeRefCounted<gl::GLShareGroup>();
+ auto gl_context = gl::init::CreateGLContext(
+ gl_share_group.get(), gl_surface.get(), gl::GLContextAttribs());
+ gl_context->MakeCurrent(gl_surface.get());
+ shared_context_state_ = base::MakeRefCounted<gpu::SharedContextState>(
+ std::move(gl_share_group), gl_surface, std::move(gl_context),
+ false /* use_virtualized_gl_contexts */, base::DoNothing::Once(),
+ nullptr /* vulkan_context_provider */);
+ shared_context_state_->InitializeGrContext(
+ gpu::GpuDriverBugWorkarounds(), nullptr /* gr_shader_cache */);
+ mailbox_manager_ = gpu::gles2::CreateMailboxManager(
+ gpu_service_impl_->gpu_preferences());
+ DCHECK(mailbox_manager_->UsesSync());
+ }
+ output_surface = std::make_unique<SkiaOutputSurfaceImplNonDDL>(
+ std::move(gl_surface), shared_context_state_, mailbox_manager_.get(),
+ gpu_service_impl_->shared_image_manager(),
+ gpu_service_impl_->sync_point_manager(),
+ true /* need_swapbuffers_ack */);
+
+ } else {
+ output_surface = std::make_unique<SkiaOutputSurfaceImpl>(
+ gpu_service_impl_, surface_handle, synthetic_begin_frame_source,
+ renderer_settings.show_overdraw_feedback);
+ }
skia_output_surface = static_cast<SkiaOutputSurface*>(output_surface.get());
#endif
} else {
@@ -186,8 +221,9 @@ std::unique_ptr<Display> GpuDisplayProvider::CreateDisplay(
synthetic_begin_frame_source, gpu_memory_buffer_manager_.get(),
renderer_settings.allow_overlays);
#elif defined(OS_ANDROID)
- // TODO(khushalsagar): Use RGB_565 if specified by context provider.
- auto buffer_format = gfx::BufferFormat::RGBA_8888;
+ auto buffer_format = context_provider->UseRGB565PixelFormat()
+ ? gfx::BufferFormat::BGR_565
+ : gfx::BufferFormat::RGBA_8888;
output_surface = std::make_unique<GLOutputSurfaceBufferQueueAndroid>(
std::move(context_provider), surface_handle,
synthetic_begin_frame_source, gpu_memory_buffer_manager_.get(),
@@ -208,8 +244,16 @@ std::unique_ptr<Display> GpuDisplayProvider::CreateDisplay(
std::move(context_provider), synthetic_begin_frame_source,
use_overlays);
#elif defined(OS_ANDROID)
+ const bool surface_control_enabled =
+ task_executor_->gpu_feature_info()
+ .status_values[gpu::GPU_FEATURE_TYPE_ANDROID_SURFACE_CONTROL] ==
+ gpu::kGpuFeatureStatusEnabled;
+ DCHECK(!surface_control_enabled ||
+ renderer_settings.backed_by_surface_texture);
+
output_surface = std::make_unique<GLOutputSurfaceAndroid>(
- std::move(context_provider), synthetic_begin_frame_source);
+ std::move(context_provider), synthetic_begin_frame_source,
+ !surface_control_enabled /* allow_overlays */);
#else
output_surface = std::make_unique<GLOutputSurface>(
std::move(context_provider), synthetic_begin_frame_source);
diff --git a/chromium/components/viz/service/display_embedder/gpu_display_provider.h b/chromium/components/viz/service/display_embedder/gpu_display_provider.h
index e28bca541d6..50935a0a99d 100644
--- a/chromium/components/viz/service/display_embedder/gpu_display_provider.h
+++ b/chromium/components/viz/service/display_embedder/gpu_display_provider.h
@@ -27,6 +27,7 @@ class CommandBufferTaskExecutor;
class GpuChannelManagerDelegate;
class GpuMemoryBufferManager;
class ImageFactory;
+class SharedContextState;
} // namespace gpu
namespace viz {
@@ -88,6 +89,11 @@ class VIZ_SERVICE_EXPORT GpuDisplayProvider : public DisplayProvider {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ // A shared context which will be used on display compositor thread.
+ scoped_refptr<gpu::SharedContextState> shared_context_state_;
+ std::unique_ptr<gpu::MailboxManager> mailbox_manager_;
+ std::unique_ptr<gpu::SyncPointManager> sync_point_manager_;
+
const bool headless_;
const bool wait_for_all_pipeline_stages_before_draw_;
diff --git a/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.cc b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.cc
new file mode 100644
index 00000000000..78b13923e0e
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.cc
@@ -0,0 +1,93 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/overlay_candidate_validator_android.h"
+
+#include "cc/base/math_util.h"
+#include "components/viz/service/display/overlay_strategy_fullscreen.h"
+#include "components/viz/service/display/overlay_strategy_single_on_top.h"
+#include "components/viz/service/display/overlay_strategy_underlay.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gl/android/android_surface_control_compat.h"
+
+namespace viz {
+namespace {
+
+gfx::RectF ClipFromOrigin(gfx::RectF input) {
+ if (input.x() < 0.f) {
+ input.set_width(input.width() + input.x());
+ input.set_x(0.f);
+ }
+
+ if (input.y() < 0) {
+ input.set_height(input.height() + input.y());
+ input.set_y(0.f);
+ }
+
+ return input;
+}
+
+} // namespace
+
+OverlayCandidateValidatorAndroid::OverlayCandidateValidatorAndroid() = default;
+OverlayCandidateValidatorAndroid::~OverlayCandidateValidatorAndroid() = default;
+
+void OverlayCandidateValidatorAndroid::GetStrategies(
+ OverlayProcessor::StrategyList* strategies) {
+ // Added in priority order, most to least desirable.
+ strategies->push_back(std::make_unique<OverlayStrategyFullscreen>(this));
+ strategies->push_back(std::make_unique<OverlayStrategySingleOnTop>(this));
+ strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(
+ this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates));
+}
+
+bool OverlayCandidateValidatorAndroid::AllowCALayerOverlays() {
+ return false;
+}
+
+bool OverlayCandidateValidatorAndroid::AllowDCLayerOverlays() {
+ return false;
+}
+
+void OverlayCandidateValidatorAndroid::CheckOverlaySupport(
+ OverlayCandidateList* surfaces) {
+ DCHECK(!surfaces->empty());
+
+ // Only update the last candidate that was added to the list. All previous
+ // overlays should have already been handled.
+ auto& candidate = surfaces->back();
+ if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) {
+ DCHECK(!candidate.use_output_surface_for_resource)
+ << "The main overlay must only use color space supported by the "
+ "device";
+ candidate.overlay_handled = false;
+ return;
+ }
+
+ const gfx::RectF orig_display_rect =
+ gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect));
+
+ candidate.display_rect = orig_display_rect;
+ if (candidate.is_clipped)
+ candidate.display_rect.Intersect(gfx::RectF(candidate.clip_rect));
+
+ // The framework doesn't support display rects positioned at a negative
+ // offset.
+ candidate.display_rect = ClipFromOrigin(candidate.display_rect);
+ if (candidate.display_rect.IsEmpty()) {
+ candidate.overlay_handled = false;
+ return;
+ }
+
+ candidate.uv_rect = cc::MathUtil::ScaleRectProportional(
+ candidate.uv_rect, orig_display_rect, candidate.display_rect);
+ candidate.overlay_handled = true;
+
+#if DCHECK_IS_ON()
+ for (auto& candidate : *surfaces)
+ DCHECK(candidate.overlay_handled);
+#endif
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.h b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.h
new file mode 100644
index 00000000000..ee498faba8a
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android.h
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
+
+#include "components/viz/service/display/overlay_candidate_validator.h"
+#include "components/viz/service/viz_service_export.h"
+
+namespace viz {
+
+class VIZ_SERVICE_EXPORT OverlayCandidateValidatorAndroid
+ : public OverlayCandidateValidator {
+ public:
+ OverlayCandidateValidatorAndroid();
+ ~OverlayCandidateValidatorAndroid() override;
+
+ void GetStrategies(OverlayProcessor::StrategyList* strategies) override;
+ bool AllowCALayerOverlays() override;
+ bool AllowDCLayerOverlays() override;
+ void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OverlayCandidateValidatorAndroid);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
diff --git a/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc
new file mode 100644
index 00000000000..6ba5a5ec561
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc
@@ -0,0 +1,87 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/overlay_candidate_validator_android.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/test/gfx_util.h"
+
+namespace viz {
+
+TEST(OverlayCandidateValidatorAndroidTest, NoClipOrNegativeOffset) {
+ OverlayCandidate candidate;
+ candidate.display_rect = gfx::RectF(10.f, 10.f);
+ candidate.uv_rect = gfx::RectF(1.f, 1.f);
+ candidate.is_clipped = false;
+ candidate.clip_rect = gfx::Rect(5, 5);
+ candidate.overlay_handled = false;
+
+ OverlayCandidateList candidates;
+ candidates.push_back(candidate);
+
+ OverlayCandidateValidatorAndroid validator;
+ validator.CheckOverlaySupport(&candidates);
+ EXPECT_TRUE(candidates.at(0).overlay_handled);
+ EXPECT_RECTF_EQ(candidates.at(0).display_rect, gfx::RectF(10.f, 10.f));
+}
+
+TEST(OverlayCandidateValidatorAndroidTest, Clipped) {
+ OverlayCandidate candidate;
+ candidate.display_rect = gfx::RectF(10.f, 10.f);
+ candidate.uv_rect = gfx::RectF(1.f, 1.f);
+ candidate.is_clipped = true;
+ candidate.clip_rect = gfx::Rect(2, 2, 5, 5);
+ candidate.overlay_handled = false;
+
+ OverlayCandidateList candidates;
+ candidates.push_back(candidate);
+
+ OverlayCandidateValidatorAndroid validator;
+ validator.CheckOverlaySupport(&candidates);
+ EXPECT_TRUE(candidates.at(0).overlay_handled);
+ EXPECT_RECTF_EQ(candidates.at(0).display_rect,
+ gfx::RectF(2.f, 2.f, 5.f, 5.f));
+ EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.2f, 0.2f, 0.5f, 0.5f));
+}
+
+TEST(OverlayCandidateValidatorAndroidTest, NegativeOffset) {
+ OverlayCandidate candidate;
+ candidate.display_rect = gfx::RectF(-2.f, -4.f, 10.f, 10.f);
+ candidate.uv_rect = gfx::RectF(0.5f, 0.5f);
+ candidate.is_clipped = false;
+ candidate.clip_rect = gfx::Rect(5, 5);
+ candidate.overlay_handled = false;
+
+ OverlayCandidateList candidates;
+ candidates.push_back(candidate);
+
+ OverlayCandidateValidatorAndroid validator;
+ validator.CheckOverlaySupport(&candidates);
+ EXPECT_TRUE(candidates.at(0).overlay_handled);
+ EXPECT_RECTF_EQ(candidates.at(0).display_rect,
+ gfx::RectF(0.f, 0.f, 8.f, 6.f));
+ EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.1f, 0.2f, 0.4f, 0.3f));
+}
+
+TEST(OverlayCandidateValidatorAndroidTest, ClipAndNegativeOffset) {
+ OverlayCandidate candidate;
+ candidate.display_rect = gfx::RectF(-5.0f, -5.0f, 10.0f, 10.0f);
+ candidate.uv_rect = gfx::RectF(0.5f, 0.5f, 0.5f, 0.5f);
+ candidate.is_clipped = true;
+ candidate.clip_rect = gfx::Rect(5, 5);
+ candidate.overlay_handled = false;
+
+ OverlayCandidateList candidates;
+ candidates.push_back(candidate);
+
+ OverlayCandidateValidatorAndroid validator;
+ validator.CheckOverlaySupport(&candidates);
+ EXPECT_TRUE(candidates.at(0).overlay_handled);
+ EXPECT_RECTF_EQ(candidates.at(0).display_rect,
+ gfx::RectF(0.f, 0.f, 5.f, 5.f));
+ EXPECT_RECTF_EQ(candidates.at(0).uv_rect,
+ gfx::RectF(0.75f, 0.75f, 0.25f, 0.25f));
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl.cc b/chromium/components/viz/service/display_embedder/skia_output_surface_impl.cc
index c9aaf933dac..8a391b38ff8 100644
--- a/chromium/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -4,11 +4,18 @@
#include "components/viz/service/display_embedder/skia_output_surface_impl.h"
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "components/viz/service/display/output_surface_client.h"
@@ -19,6 +26,8 @@
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/shared_image_representation.h"
+#include "gpu/ipc/command_buffer_task_executor.h"
+#include "gpu/vulkan/buildflags.h"
#include "third_party/skia/include/core/SkYUVAIndex.h"
#include "ui/gfx/skia_util.h"
#include "ui/gl/gl_bindings.h"
@@ -41,6 +50,8 @@ template <typename... Args>
base::RepeatingCallback<void(Args...)> CreateSafeCallback(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const base::RepeatingCallback<void(Args...)>& callback) {
+ if (!task_runner)
+ return callback;
return base::BindRepeating(&PostAsyncTask<Args...>, task_runner, callback);
}
@@ -54,7 +65,8 @@ class SkiaOutputSurfaceImpl::PromiseTextureHelper {
const ResourceMetadata& metadata) {
auto* helper = new PromiseTextureHelper(
impl->impl_on_gpu_->weak_ptr(), metadata.size, metadata.resource_format,
- metadata.mailbox_holder);
+ metadata.mailbox_holder, metadata.color_space.ToSkColorSpace(),
+ metadata.alpha_type);
return helper->MakePromiseSkImage(impl);
}
@@ -62,13 +74,16 @@ class SkiaOutputSurfaceImpl::PromiseTextureHelper {
SkiaOutputSurfaceImpl* impl,
ResourceFormat resource_format,
gfx::Size size,
- RenderPassId render_pass_id) {
+ RenderPassId render_pass_id,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
DCHECK_CALLED_ON_VALID_THREAD(impl->thread_checker_);
// The ownership of the helper will be passed into makePromisTexture(). The
// PromiseTextureHelper::Done will always be called. It will delete the
// helper.
auto* helper = new PromiseTextureHelper(
- impl->impl_on_gpu_->weak_ptr(), size, resource_format, render_pass_id);
+ impl->impl_on_gpu_->weak_ptr(), size, resource_format, render_pass_id,
+ mipmap, std::move(color_space));
return helper->MakePromiseSkImage(impl);
}
@@ -78,34 +93,43 @@ class SkiaOutputSurfaceImpl::PromiseTextureHelper {
PromiseTextureHelper(base::WeakPtr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu,
const gfx::Size& size,
ResourceFormat resource_format,
- RenderPassId render_pass_id)
+ RenderPassId render_pass_id,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space)
: impl_on_gpu_(impl_on_gpu),
size_(size),
resource_format_(resource_format),
- render_pass_id_(render_pass_id) {}
+ render_pass_id_(render_pass_id),
+ mipmap_(mipmap ? GrMipMapped::kYes : GrMipMapped::kNo),
+ color_space_(std::move(color_space)) {}
+
PromiseTextureHelper(base::WeakPtr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu,
const gfx::Size& size,
ResourceFormat resource_format,
- const gpu::MailboxHolder& mailbox_holder)
+ const gpu::MailboxHolder& mailbox_holder,
+ sk_sp<SkColorSpace> color_space,
+ SkAlphaType alpha_type)
: impl_on_gpu_(impl_on_gpu),
size_(size),
resource_format_(resource_format),
render_pass_id_(0u),
- mailbox_holder_(mailbox_holder) {}
+ mailbox_holder_(mailbox_holder),
+ color_space_(std::move(color_space)),
+ alpha_type_(alpha_type) {}
~PromiseTextureHelper() = default;
sk_sp<SkImage> MakePromiseSkImage(SkiaOutputSurfaceImpl* impl) {
SkColorType color_type = ResourceFormatToClosestSkColorType(
true /* gpu_compositing */, resource_format_);
GrBackendFormat backend_format;
- if (!impl->gpu_service_->is_using_vulkan()) {
+ if (!impl->is_using_vulkan_) {
// Convert internal format from GLES2 to platform GL.
const auto* version_info = impl->impl_on_gpu_->gl_version_info();
unsigned int texture_storage_format =
TextureStorageFormat(resource_format_);
backend_format = GrBackendFormat::MakeGL(
gl::GetInternalFormat(version_info, texture_storage_format),
- GL_TEXTURE_2D);
+ render_pass_id_ ? GL_TEXTURE_2D : mailbox_holder_.texture_target);
} else {
#if BUILDFLAG(ENABLE_VULKAN)
backend_format = GrBackendFormat::MakeVk(ToVkFormat(resource_format_));
@@ -114,9 +138,9 @@ class SkiaOutputSurfaceImpl::PromiseTextureHelper {
#endif
}
return impl->recorder_->makePromiseTexture(
- backend_format, size_.width(), size_.height(), GrMipMapped::kNo,
- kTopLeft_GrSurfaceOrigin /* origin */, color_type, kPremul_SkAlphaType,
- nullptr /* color_space */, PromiseTextureHelper::Fulfill,
+ backend_format, size_.width(), size_.height(), mipmap_,
+ kTopLeft_GrSurfaceOrigin /* origin */, color_type, alpha_type_,
+ color_space_, PromiseTextureHelper::Fulfill,
PromiseTextureHelper::Release, PromiseTextureHelper::Done, this);
}
@@ -147,14 +171,22 @@ class SkiaOutputSurfaceImpl::PromiseTextureHelper {
static void Done(void* texture_context) {
DCHECK(texture_context);
auto* helper = static_cast<PromiseTextureHelper*>(texture_context);
+ if (helper->shared_image_) {
+ DCHECK(helper->impl_on_gpu_);
+ if (helper->impl_on_gpu_->was_context_lost())
+ helper->shared_image_->OnContextLost();
+ }
delete helper;
}
base::WeakPtr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu_;
const gfx::Size size_;
const ResourceFormat resource_format_;
- RenderPassId render_pass_id_;
- gpu::MailboxHolder mailbox_holder_;
+ const RenderPassId render_pass_id_;
+ const gpu::MailboxHolder mailbox_holder_;
+ const GrMipMapped mipmap_ = GrMipMapped::kNo;
+ const sk_sp<SkColorSpace> color_space_;
+ const SkAlphaType alpha_type_ = kPremul_SkAlphaType;
// If non-null, an outstanding SharedImageRepresentation that must be freed on
// Release. Only written / read from GPU thread.
@@ -184,7 +216,7 @@ class SkiaOutputSurfaceImpl::YUVAPromiseTextureHelper {
{-1, SkColorChannel::kR},
};
SkISize yuva_sizes[4] = {};
- SkDeferredDisplayListRecorder::TextureContext contexts[4] = {
+ SkDeferredDisplayListRecorder::PromiseImageTextureContext contexts[4] = {
nullptr, nullptr, nullptr, nullptr};
// The ownership of the contexts will be passed into
@@ -199,7 +231,8 @@ class SkiaOutputSurfaceImpl::YUVAPromiseTextureHelper {
yuva_sizes[i].set(metadata.size.width(), metadata.size.height());
contexts[i] = new PromiseTextureHelper(
impl->impl_on_gpu_->weak_ptr(), metadata.size,
- metadata.resource_format, metadata.mailbox_holder);
+ metadata.resource_format, metadata.mailbox_holder,
+ metadata.color_space.ToSkColorSpace(), metadata.alpha_type);
};
if (is_i420) {
@@ -255,6 +288,7 @@ SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl(
SyntheticBeginFrameSource* synthetic_begin_frame_source,
bool show_overdraw_feedback)
: gpu_service_(gpu_service),
+ is_using_vulkan_(gpu_service->is_using_vulkan()),
surface_handle_(surface_handle),
synthetic_begin_frame_source_(synthetic_begin_frame_source),
show_overdraw_feedback_(show_overdraw_feedback),
@@ -262,6 +296,20 @@ SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
+SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl(
+ scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state)
+ : gpu_service_(nullptr),
+ task_executor_(std::move(task_executor)),
+ gl_surface_(std::move(gl_surface)),
+ shared_context_state_(std::move(shared_context_state)),
+ is_using_vulkan_(false),
+ surface_handle_(gpu::kNullSurfaceHandle),
+ synthetic_begin_frame_source_(nullptr),
+ show_overdraw_feedback_(false),
+ weak_ptr_factory_(this) {}
+
SkiaOutputSurfaceImpl::~SkiaOutputSurfaceImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
recorder_.reset();
@@ -269,12 +317,10 @@ SkiaOutputSurfaceImpl::~SkiaOutputSurfaceImpl() {
// scheduled tasks for the impl_on_gpu_ will be executed, before releasing
// it. The GPU thread is the main thread of the viz process. It outlives the
// compositor thread. We don't need worry about it for now.
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
auto callback =
base::BindOnce([](std::unique_ptr<SkiaOutputSurfaceImplOnGpu>) {},
std::move(impl_on_gpu_));
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
void SkiaOutputSurfaceImpl::BindToClient(OutputSurfaceClient* client) {
@@ -284,15 +330,17 @@ void SkiaOutputSurfaceImpl::BindToClient(OutputSurfaceClient* client) {
client_ = client;
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
- client_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
-
+ if (task_executor_) {
+ DCHECK(!sequence_);
+ sequence_ = task_executor_->CreateSequence();
+ } else {
+ client_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ }
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
auto callback = base::BindOnce(&SkiaOutputSurfaceImpl::InitializeOnGpuThread,
base::Unretained(this), &event);
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
event.Wait();
}
@@ -320,6 +368,12 @@ void SkiaOutputSurfaceImpl::Reshape(const gfx::Size& size,
const gfx::ColorSpace& color_space,
bool has_alpha,
bool use_stencil) {
+ reshape_surface_size_ = size;
+ reshape_device_scale_factor_ = device_scale_factor;
+ reshape_color_space_ = color_space;
+ reshape_has_alpha_ = has_alpha;
+ reshape_use_stencil_ = use_stencil;
+
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (initialize_waitable_event_) {
initialize_waitable_event_->Wait();
@@ -327,26 +381,33 @@ void SkiaOutputSurfaceImpl::Reshape(const gfx::Size& size,
}
SkSurfaceCharacterization* characterization = nullptr;
- if (characterization_.isValid()) {
- characterization_ =
- characterization_.createResized(size.width(), size.height());
- } else {
+ // If the render target is changed between GL fbo zero and non-zero, we cannot
+ // recreate SkSurface characterization from the existing characterization. So
+ // we have to request a new SkSurface characterization from
+ // SkiaOutputSurfaceImplOnGpu.
+ backing_framebuffer_object_ =
+ gl_surface_ ? gl_surface_->GetBackingFramebufferObject() : 0;
+ if (!characterization_.isValid() ||
+ (!is_using_vulkan_ &&
+ characterization_.usesGLFBO0() != (backing_framebuffer_object_ == 0))) {
characterization = &characterization_;
initialize_waitable_event_ = std::make_unique<base::WaitableEvent>(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
+ } else {
+ // TODO(weiliang): support color space. https://crbug.com/795132
+ characterization_ =
+ characterization_.createResized(size.width(), size.height());
}
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
- auto callback =
- base::BindOnce(&SkiaOutputSurfaceImplOnGpu::Reshape,
- base::Unretained(impl_on_gpu_.get()), size,
- device_scale_factor, color_space, has_alpha, use_stencil,
- characterization, initialize_waitable_event_.get());
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::Reshape,
+ base::Unretained(impl_on_gpu_.get()), size,
+ device_scale_factor, std::move(color_space),
+ has_alpha, use_stencil, characterization,
+ initialize_waitable_event_.get());
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
void SkiaOutputSurfaceImpl::SwapBuffers(OutputSurfaceFrame frame) {
@@ -389,18 +450,15 @@ void SkiaOutputSurfaceImpl::ApplyExternalStencil() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
-#if BUILDFLAG(ENABLE_VULKAN)
-gpu::VulkanSurface* SkiaOutputSurfaceImpl::GetVulkanSurface() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- return nullptr;
-}
-#endif
-
unsigned SkiaOutputSurfaceImpl::UpdateGpuFence() {
return 0;
}
+void SkiaOutputSurfaceImpl::SetNeedsSwapSizeNotifications(
+ bool needs_swap_size_notifications) {
+ needs_swap_size_notifications_ = needs_swap_size_notifications;
+}
+
SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
@@ -413,6 +471,15 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() {
}
DCHECK(characterization_.isValid());
+ // The fbo is changed, in that case we need notify SkiaOutputSurfaceImplOnGpu,
+ // so it can recreate SkSurface from the new fbo, and return a updated
+ // SkSurfaceCharacterization if necessary.
+ if (gl_surface_ && backing_framebuffer_object_ !=
+ gl_surface_->GetBackingFramebufferObject()) {
+ Reshape(reshape_surface_size_, reshape_device_scale_factor_,
+ reshape_color_space_, reshape_has_alpha_, reshape_use_stencil_);
+ }
+
recorder_.emplace(characterization_);
if (!show_overdraw_feedback_)
return recorder_->getCanvas();
@@ -422,7 +489,7 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() {
SkSurfaceCharacterization characterization = CreateSkSurfaceCharacterization(
gfx::Size(characterization_.width(), characterization_.height()),
- BGRA_8888, false);
+ BGRA_8888, false /* mipmap */, characterization_.refColorSpace());
overdraw_surface_recorder_.emplace(characterization);
overdraw_canvas_.emplace((overdraw_surface_recorder_->getCanvas()));
@@ -455,51 +522,40 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromYUV(
this, yuv_color_space, std::move(metadatas), has_alpha);
}
-gpu::SyncToken SkiaOutputSurfaceImpl::QueueReleasePromiseSkImage(
- sk_sp<SkImage>&& image) {
- images_pending_release_.emplace_back(std::move(image));
-
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE,
- impl_on_gpu_->command_buffer_id(),
- ++sync_fence_release_);
+gpu::SyncToken SkiaOutputSurfaceImpl::ReleasePromiseSkImages(
+ std::vector<sk_sp<SkImage>> images) {
+ if (images.empty())
+ return gpu::SyncToken();
+ gpu::SyncToken sync_token(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE,
+ impl_on_gpu_->command_buffer_id(), ++sync_fence_release_);
sync_token.SetVerifyFlush();
- return sync_token;
-}
-
-void SkiaOutputSurfaceImpl::FlushQueuedReleases() {
- if (images_pending_release_.empty())
- return;
-
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
- auto callback =
- base::BindOnce(&SkiaOutputSurfaceImplOnGpu::DestroySkImages,
- base::Unretained(impl_on_gpu_.get()),
- std::move(images_pending_release_), sync_fence_release_);
- images_pending_release_.clear();
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::DestroySkImages,
+ base::Unretained(impl_on_gpu_.get()),
+ std::move(images), sync_fence_release_);
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
+ return sync_token;
}
void SkiaOutputSurfaceImpl::SkiaSwapBuffers(OutputSurfaceFrame frame) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!recorder_);
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
auto callback =
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::SwapBuffers,
base::Unretained(impl_on_gpu_.get()), std::move(frame));
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
const RenderPassId& id,
const gfx::Size& surface_size,
ResourceFormat format,
- bool mipmap) {
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
DCHECK(!recorder_);
@@ -508,8 +564,8 @@ SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
current_render_pass_id_ = id;
- SkSurfaceCharacterization characterization =
- CreateSkSurfaceCharacterization(surface_size, format, mipmap);
+ SkSurfaceCharacterization characterization = CreateSkSurfaceCharacterization(
+ surface_size, format, mipmap, std::move(color_space));
recorder_.emplace(characterization);
return recorder_->getCanvas();
}
@@ -522,9 +578,9 @@ gpu::SyncToken SkiaOutputSurfaceImpl::SubmitPaint() {
// Otherwise we are painting a frame.
bool painting_render_pass = current_render_pass_id_ != 0;
- gpu::SyncToken sync_token(gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE,
- impl_on_gpu_->command_buffer_id(),
- ++sync_fence_release_);
+ gpu::SyncToken sync_token(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE,
+ impl_on_gpu_->command_buffer_id(), ++sync_fence_release_);
sync_token.SetVerifyFlush();
auto ddl = recorder_->detach();
@@ -539,7 +595,6 @@ gpu::SyncToken SkiaOutputSurfaceImpl::SubmitPaint() {
overdraw_surface_recorder_.reset();
}
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
base::OnceCallback<void()> callback;
@@ -547,15 +602,14 @@ gpu::SyncToken SkiaOutputSurfaceImpl::SubmitPaint() {
callback = base::BindOnce(
&SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass,
base::Unretained(impl_on_gpu_.get()), current_render_pass_id_,
- std::move(ddl), sync_fence_release_);
+ std::move(ddl), resource_sync_tokens_, sync_fence_release_);
} else {
- callback =
- base::BindOnce(&SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame,
- base::Unretained(impl_on_gpu_.get()), std::move(ddl),
- std::move(overdraw_ddl), sync_fence_release_);
+ callback = base::BindOnce(
+ &SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame,
+ base::Unretained(impl_on_gpu_.get()), std::move(ddl),
+ std::move(overdraw_ddl), resource_sync_tokens_, sync_fence_release_);
}
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::move(resource_sync_tokens_)));
+ ScheduleGpuTask(std::move(callback), std::move(resource_sync_tokens_));
current_render_pass_id_ = 0;
return sync_token;
}
@@ -564,46 +618,40 @@ sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromRenderPass(
const RenderPassId& id,
const gfx::Size& size,
ResourceFormat format,
- bool mipmap) {
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(recorder_);
- // TODO(penghuang): remove this mipmap argument, because we always pass false.
- DCHECK(!mipmap);
- return PromiseTextureHelper::MakePromiseSkImageFromRenderPass(this, format,
- size, id);
+ return PromiseTextureHelper::MakePromiseSkImageFromRenderPass(
+ this, format, size, id, mipmap, std::move(color_space));
}
void SkiaOutputSurfaceImpl::RemoveRenderPassResource(
std::vector<RenderPassId> ids) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!ids.empty());
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
auto callback =
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource,
base::Unretained(impl_on_gpu_.get()), std::move(ids));
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
void SkiaOutputSurfaceImpl::CopyOutput(
RenderPassId id,
- const gfx::Rect& copy_rect,
+ const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
- const gfx::Rect& result_rect,
std::unique_ptr<CopyOutputRequest> request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!request->has_result_task_runner())
request->set_result_task_runner(base::ThreadTaskRunnerHandle::Get());
- auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
- auto callback =
- base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput,
- base::Unretained(impl_on_gpu_.get()), id, copy_rect,
- color_space, result_rect, std::move(request));
- gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
- sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
+
+ auto callback = base::BindOnce(&SkiaOutputSurfaceImplOnGpu::CopyOutput,
+ base::Unretained(impl_on_gpu_.get()), id,
+ geometry, color_space, std::move(request));
+ ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
void SkiaOutputSurfaceImpl::AddContextLostObserver(
@@ -617,20 +665,40 @@ void SkiaOutputSurfaceImpl::RemoveContextLostObserver(
}
void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event) {
- base::ScopedClosureRunner scoped_runner(
- base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event)));
- auto did_swap_buffer_complete_callback = base::BindRepeating(
- &SkiaOutputSurfaceImpl::DidSwapBuffersComplete, weak_ptr_);
- auto buffer_presented_callback =
- base::BindRepeating(&SkiaOutputSurfaceImpl::BufferPresented, weak_ptr_);
- auto context_lost_callback =
- base::BindRepeating(&SkiaOutputSurfaceImpl::ContextLost, weak_ptr_);
- impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>(
- gpu_service_, surface_handle_,
- CreateSafeCallback(client_thread_task_runner_,
- did_swap_buffer_complete_callback),
- CreateSafeCallback(client_thread_task_runner_, buffer_presented_callback),
- CreateSafeCallback(client_thread_task_runner_, context_lost_callback));
+ base::Optional<base::ScopedClosureRunner> scoped_runner;
+ if (event) {
+ scoped_runner.emplace(
+ base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event)));
+ }
+
+ if (task_executor_) {
+ // When |task_executor_| is not nullptr, DidSwapBuffersComplete(),
+ // BufferPresented(), ContextList() are not expected to be called by this
+ // class. The SurfacesInstance will do it.
+ impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>(
+ task_executor_.get(), gl_surface_, std::move(shared_context_state_),
+ sequence_->GetSequenceId(),
+ base::DoNothing::Repeatedly<gpu::SwapBuffersCompleteParams,
+ const gfx::Size&>(),
+ base::DoNothing::Repeatedly<const gfx::PresentationFeedback&>(),
+ base::DoNothing::Repeatedly<>());
+ } else {
+ auto did_swap_buffer_complete_callback = base::BindRepeating(
+ &SkiaOutputSurfaceImpl::DidSwapBuffersComplete, weak_ptr_);
+ did_swap_buffer_complete_callback = CreateSafeCallback(
+ client_thread_task_runner_, did_swap_buffer_complete_callback);
+ auto buffer_presented_callback =
+ base::BindRepeating(&SkiaOutputSurfaceImpl::BufferPresented, weak_ptr_);
+ buffer_presented_callback = CreateSafeCallback(client_thread_task_runner_,
+ buffer_presented_callback);
+ auto context_lost_callback =
+ base::BindRepeating(&SkiaOutputSurfaceImpl::ContextLost, weak_ptr_);
+ context_lost_callback =
+ CreateSafeCallback(client_thread_task_runner_, context_lost_callback);
+ impl_on_gpu_ = std::make_unique<SkiaOutputSurfaceImplOnGpu>(
+ gpu_service_, surface_handle_, did_swap_buffer_complete_callback,
+ buffer_presented_callback, context_lost_callback);
+ }
capabilities_ = impl_on_gpu_->capabilities();
}
@@ -638,7 +706,8 @@ SkSurfaceCharacterization
SkiaOutputSurfaceImpl::CreateSkSurfaceCharacterization(
const gfx::Size& surface_size,
ResourceFormat format,
- bool mipmap) {
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
auto gr_context_thread_safe = impl_on_gpu_->GetGrContextThreadSafeProxy();
constexpr uint32_t flags = 0;
// LegacyFontHost will get LCD text and skia figures out what type to use.
@@ -648,13 +717,13 @@ SkiaOutputSurfaceImpl::CreateSkSurfaceCharacterization(
ResourceFormatToClosestSkColorType(true /* gpu_compositing */, format);
SkImageInfo image_info =
SkImageInfo::Make(surface_size.width(), surface_size.height(), color_type,
- kPremul_SkAlphaType, nullptr /* color_space */);
+ kPremul_SkAlphaType, std::move(color_space));
// TODO(penghuang): Figure out how to choose the right size.
constexpr size_t kCacheMaxResourceBytes = 90 * 1024 * 1024;
GrBackendFormat backend_format;
- if (!gpu_service_->is_using_vulkan()) {
+ if (!is_using_vulkan_) {
const auto* version_info = impl_on_gpu_->gl_version_info();
unsigned int texture_storage_format = TextureStorageFormat(format);
backend_format = GrBackendFormat::MakeGL(
@@ -710,9 +779,16 @@ void SkiaOutputSurfaceImpl::ContextLost() {
observer.OnContextLost();
}
-void SkiaOutputSurfaceImpl::SetNeedsSwapSizeNotifications(
- bool needs_swap_size_notifications) {
- needs_swap_size_notifications_ = needs_swap_size_notifications;
+void SkiaOutputSurfaceImpl::ScheduleGpuTask(
+ base::OnceClosure callback,
+ std::vector<gpu::SyncToken> sync_tokens) {
+ if (gpu_service_) {
+ auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
+ gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
+ sequence_id, std::move(callback), std::move(sync_tokens)));
+ } else {
+ sequence_->ScheduleTask(std::move(callback), std::move(sync_tokens));
+ }
}
} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl.h b/chromium/components/viz/service/display_embedder/skia_output_surface_impl.h
index 5e95e7eb6de..a39e6497c3c 100644
--- a/chromium/components/viz/service/display_embedder/skia_output_surface_impl.h
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -22,6 +22,15 @@ namespace base {
class WaitableEvent;
}
+namespace gl {
+class GLSurface;
+}
+
+namespace gpu {
+class CommandBufferTaskExecutor;
+class SharedContextState;
+} // namespace gpu
+
namespace viz {
class GpuServiceImpl;
@@ -44,6 +53,10 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
gpu::SurfaceHandle surface_handle,
SyntheticBeginFrameSource* synthetic_begin_frame_source,
bool show_overdraw_feedback);
+ SkiaOutputSurfaceImpl(
+ scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state);
~SkiaOutputSurfaceImpl() override;
// OutputSurface implementation:
@@ -65,9 +78,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
gfx::BufferFormat GetOverlayBufferFormat() const override;
bool HasExternalStencilTest() const override;
void ApplyExternalStencil() override;
-#if BUILDFLAG(ENABLE_VULKAN)
- gpu::VulkanSurface* GetVulkanSurface() override;
-#endif
unsigned UpdateGpuFence() override;
void SetNeedsSwapSizeNotifications(
bool needs_swap_size_notifications) override;
@@ -82,21 +92,23 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
const gfx::Size& surface_size,
ResourceFormat format,
- bool mipmap) override;
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) override;
gpu::SyncToken SubmitPaint() override;
sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) override;
- sk_sp<SkImage> MakePromiseSkImageFromRenderPass(const RenderPassId& id,
- const gfx::Size& size,
- ResourceFormat format,
- bool mipmap) override;
- gpu::SyncToken QueueReleasePromiseSkImage(sk_sp<SkImage>&& image) override;
- void FlushQueuedReleases() override;
+ sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
+ const RenderPassId& id,
+ const gfx::Size& size,
+ ResourceFormat format,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) override;
+ gpu::SyncToken ReleasePromiseSkImages(
+ std::vector<sk_sp<SkImage>> image) override;
void RemoveRenderPassResource(std::vector<RenderPassId> ids) override;
void CopyOutput(RenderPassId id,
- const gfx::Rect& copy_rect,
+ const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
- const gfx::Rect& result_rect,
std::unique_ptr<CopyOutputRequest> request) override;
void AddContextLostObserver(ContextLostObserver* observer) override;
void RemoveContextLostObserver(ContextLostObserver* observer) override;
@@ -108,18 +120,37 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
SkSurfaceCharacterization CreateSkSurfaceCharacterization(
const gfx::Size& surface_size,
ResourceFormat format,
- bool mipmap);
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space);
void DidSwapBuffersComplete(gpu::SwapBuffersCompleteParams params,
const gfx::Size& pixel_size);
void BufferPresented(const gfx::PresentationFeedback& feedback);
void ContextLost();
+ void ScheduleGpuTask(base::OnceClosure callback,
+ std::vector<gpu::SyncToken> sync_tokens);
uint64_t sync_fence_release_ = 0;
+
GpuServiceImpl* const gpu_service_;
+
+ // Stuffs for running with |task_executor_| instead of |gpu_service_|.
+ scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor_;
+ scoped_refptr<gl::GLSurface> gl_surface_;
+ scoped_refptr<gpu::SharedContextState> shared_context_state_;
+ std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence> sequence_;
+
+ const bool is_using_vulkan_;
const gpu::SurfaceHandle surface_handle_;
SyntheticBeginFrameSource* const synthetic_begin_frame_source_;
OutputSurfaceClient* client_ = nullptr;
+ unsigned int backing_framebuffer_object_ = 0;
+ gfx::Size reshape_surface_size_;
+ float reshape_device_scale_factor_ = 0.f;
+ gfx::ColorSpace reshape_color_space_;
+ bool reshape_has_alpha_ = false;
+ bool reshape_use_stencil_ = false;
+
std::unique_ptr<base::WaitableEvent> initialize_waitable_event_;
SkSurfaceCharacterization characterization_;
base::Optional<SkDeferredDisplayListRecorder> recorder_;
@@ -156,8 +187,6 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
// Observers for context lost.
base::ObserverList<ContextLostObserver>::Unchecked observers_;
- std::vector<sk_sp<SkImage>> images_pending_release_;
-
THREAD_CHECKER(thread_checker_);
base::WeakPtr<SkiaOutputSurfaceImpl> weak_ptr_;
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc
new file mode 100644
index 00000000000..cdcc4034e01
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc
@@ -0,0 +1,519 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h"
+
+#include <utility>
+
+#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
+#include "base/synchronization/waitable_event.h"
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
+#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/gpu/context_lost_observer.h"
+#include "components/viz/common/resources/resource_format_utils.h"
+#include "components/viz/service/display/output_surface_client.h"
+#include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/resource_metadata.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
+#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/shared_image_factory.h"
+#include "gpu/command_buffer/service/shared_image_representation.h"
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "gpu/command_buffer/service/sync_point_manager.h"
+#include "gpu/command_buffer/service/texture_base.h"
+#include "third_party/skia/include/core/SkPromiseImageTexture.h"
+#include "third_party/skia/include/core/SkYUVAIndex.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_surface.h"
+#include "ui/gl/gl_version_info.h"
+
+namespace viz {
+
+namespace {
+
+scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState(
+ gpu::SyncPointManager* sync_point_manager,
+ gpu::SequenceId sequence_id) {
+ static uint64_t next_command_buffer_id = 0u;
+ auto command_buffer_id =
+ gpu::CommandBufferId::FromUnsafeValue(++next_command_buffer_id);
+ return sync_point_manager->CreateSyncPointClientState(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE_NON_DDL,
+ command_buffer_id, sequence_id);
+}
+
+std::unique_ptr<gpu::SharedImageRepresentationFactory>
+CreateSharedImageRepresentationFactory(gpu::SharedImageManager* manager) {
+ if (!manager)
+ return nullptr;
+ // TODO(https://crbug.com/899905): Use a real MemoryTracker, not nullptr.
+ return std::make_unique<gpu::SharedImageRepresentationFactory>(
+ manager, nullptr /* tracker */);
+}
+
+void ReleaseSharedImagePresentation(void* context) {
+ std::unique_ptr<gpu::SharedImageRepresentationSkia> representation(
+ static_cast<gpu::SharedImageRepresentationSkia*>(context));
+ representation->EndReadAccess();
+}
+
+} // namespace
+
+SkiaOutputSurfaceImplNonDDL::SkiaOutputSurfaceImplNonDDL(
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state,
+ gpu::MailboxManager* mailbox_manager,
+ gpu::SharedImageManager* shared_image_manager,
+ gpu::SyncPointManager* sync_point_manager,
+ bool need_swapbuffers_ack)
+ : gl_surface_(std::move(gl_surface)),
+ shared_context_state_(std::move(shared_context_state)),
+ mailbox_manager_(mailbox_manager),
+ sir_factory_(
+ CreateSharedImageRepresentationFactory(shared_image_manager)),
+ sync_point_order_data_(sync_point_manager->CreateSyncPointOrderData()),
+ sync_point_client_state_(
+ CreateSyncPointClientState(sync_point_manager,
+ sync_point_order_data_->sequence_id())),
+ need_swapbuffers_ack_(need_swapbuffers_ack),
+ weak_ptr_factory_(this) {}
+
+SkiaOutputSurfaceImplNonDDL::~SkiaOutputSurfaceImplNonDDL() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+void SkiaOutputSurfaceImplNonDDL::BindToClient(OutputSurfaceClient* client) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(client);
+ DCHECK(!client_);
+ client_ = client;
+}
+
+void SkiaOutputSurfaceImplNonDDL::EnsureBackbuffer() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ NOTIMPLEMENTED();
+}
+
+void SkiaOutputSurfaceImplNonDDL::DiscardBackbuffer() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ NOTIMPLEMENTED();
+}
+
+void SkiaOutputSurfaceImplNonDDL::BindFramebuffer() {
+ // TODO(penghuang): remove this method when GLRenderer is removed.
+}
+
+void SkiaOutputSurfaceImplNonDDL::SetDrawRectangle(
+ const gfx::Rect& draw_rectangle) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ NOTIMPLEMENTED();
+}
+
+void SkiaOutputSurfaceImplNonDDL::Reshape(const gfx::Size& size,
+ float device_scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha,
+ bool use_stencil) {
+ reshape_surface_size_ = size;
+ reshape_device_scale_factor_ = device_scale_factor;
+ reshape_color_space_ = color_space;
+ reshape_has_alpha_ = has_alpha;
+ reshape_use_stencil_ = use_stencil;
+
+ // Conversion to GLSurface's color space follows the same logic as in
+ // gl::GetGLColorSpace().
+ gl::GLSurface::ColorSpace surface_color_space =
+ color_space.IsHDR() ? gl::GLSurface::ColorSpace::SCRGB_LINEAR
+ : gl::GLSurface::ColorSpace::UNSPECIFIED;
+ gl_surface_->Resize(size, device_scale_factor, surface_color_space,
+ has_alpha);
+
+ backing_framebuffer_object_ = gl_surface_->GetBackingFramebufferObject();
+
+ SkSurfaceProps surface_props =
+ SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
+
+ GrGLFramebufferInfo framebuffer_info;
+ framebuffer_info.fFBOID = backing_framebuffer_object_;
+ framebuffer_info.fFormat = GL_RGBA8;
+
+ GrBackendRenderTarget render_target(size.width(), size.height(), 0, 8,
+ framebuffer_info);
+
+ sk_surface_ = SkSurface::MakeFromBackendRenderTarget(
+ gr_context(), render_target, kBottomLeft_GrSurfaceOrigin,
+ kRGBA_8888_SkColorType, color_space.ToSkColorSpace(), &surface_props);
+ DCHECK(sk_surface_);
+}
+
+void SkiaOutputSurfaceImplNonDDL::SwapBuffers(OutputSurfaceFrame frame) {
+ NOTIMPLEMENTED();
+}
+
+uint32_t SkiaOutputSurfaceImplNonDDL::GetFramebufferCopyTextureFormat() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return GL_RGB;
+}
+
+OverlayCandidateValidator*
+SkiaOutputSurfaceImplNonDDL::GetOverlayCandidateValidator() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return nullptr;
+}
+
+bool SkiaOutputSurfaceImplNonDDL::IsDisplayedAsOverlayPlane() const {
+ return false;
+}
+
+unsigned SkiaOutputSurfaceImplNonDDL::GetOverlayTextureId() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return 0;
+}
+
+gfx::BufferFormat SkiaOutputSurfaceImplNonDDL::GetOverlayBufferFormat() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return gfx::BufferFormat::RGBX_8888;
+}
+
+bool SkiaOutputSurfaceImplNonDDL::HasExternalStencilTest() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return false;
+}
+
+void SkiaOutputSurfaceImplNonDDL::ApplyExternalStencil() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+unsigned SkiaOutputSurfaceImplNonDDL::UpdateGpuFence() {
+ return 0;
+}
+
+void SkiaOutputSurfaceImplNonDDL::SetNeedsSwapSizeNotifications(
+ bool needs_swap_size_notifications) {
+ NOTIMPLEMENTED();
+}
+
+SkCanvas* SkiaOutputSurfaceImplNonDDL::BeginPaintCurrentFrame() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(sk_surface_);
+ DCHECK_EQ(current_render_pass_id_, 0u);
+ DCHECK_EQ(order_num_, 0u);
+ order_num_ = sync_point_order_data_->GenerateUnprocessedOrderNumber();
+ sync_point_order_data_->BeginProcessingOrderNumber(order_num_);
+
+ // If FBO is changed, we need call Reshape() to recreate |sk_surface_|.
+ if (backing_framebuffer_object_ !=
+ gl_surface_->GetBackingFramebufferObject()) {
+ Reshape(reshape_surface_size_, reshape_device_scale_factor_,
+ reshape_color_space_, reshape_has_alpha_, reshape_use_stencil_);
+ }
+
+ return sk_surface_->getCanvas();
+}
+
+sk_sp<SkImage> SkiaOutputSurfaceImplNonDDL::MakePromiseSkImage(
+ ResourceMetadata metadata) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (metadata.mailbox_holder.mailbox.IsSharedImage() && sir_factory_) {
+ WaitSyncToken(metadata.mailbox_holder.sync_token);
+ return MakeSkImageFromSharedImage(metadata);
+ }
+
+ GrBackendTexture backend_texture;
+ if (!GetGrBackendTexture(metadata, &backend_texture)) {
+ DLOG(ERROR) << "Failed to GetGrBackendTexture from mailbox.";
+ return nullptr;
+ }
+
+ auto sk_color_type = ResourceFormatToClosestSkColorType(
+ true /* gpu_compositing */, metadata.resource_format);
+ return SkImage::MakeFromTexture(
+ gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin, sk_color_type,
+ metadata.alpha_type, metadata.color_space.ToSkColorSpace());
+}
+
+sk_sp<SkImage> SkiaOutputSurfaceImplNonDDL::MakePromiseSkImageFromYUV(
+ std::vector<ResourceMetadata> metadatas,
+ SkYUVColorSpace yuv_color_space,
+ bool has_alpha) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK((has_alpha && (metadatas.size() == 3 || metadatas.size() == 4)) ||
+ (!has_alpha && (metadatas.size() == 2 || metadatas.size() == 3)));
+
+ bool is_i420 = has_alpha ? metadatas.size() == 4 : metadatas.size() == 3;
+
+ GrBackendFormat formats[4];
+ SkYUVAIndex indices[4] = {
+ {-1, SkColorChannel::kR},
+ {-1, SkColorChannel::kR},
+ {-1, SkColorChannel::kR},
+ {-1, SkColorChannel::kR},
+ };
+ GrBackendTexture yuva_textures[4] = {};
+ const auto process_planar = [&](size_t i, ResourceFormat resource_format) {
+ auto& metadata = metadatas[i];
+ metadata.resource_format = resource_format;
+ if (!GetGrBackendTexture(metadata, &yuva_textures[i]))
+ DLOG(ERROR) << "Failed to GetGrBackendTexture from a mailbox.";
+ };
+
+ if (is_i420) {
+ process_planar(0, RED_8);
+ indices[SkYUVAIndex::kY_Index].fIndex = 0;
+ indices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR;
+
+ process_planar(1, RED_8);
+ indices[SkYUVAIndex::kU_Index].fIndex = 1;
+ indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
+
+ process_planar(2, RED_8);
+ indices[SkYUVAIndex::kV_Index].fIndex = 2;
+ indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kR;
+ if (has_alpha) {
+ process_planar(3, RED_8);
+ indices[SkYUVAIndex::kA_Index].fIndex = 3;
+ indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
+ }
+ } else {
+ process_planar(0, RED_8);
+ indices[SkYUVAIndex::kY_Index].fIndex = 0;
+ indices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR;
+
+ process_planar(1, RG_88);
+ indices[SkYUVAIndex::kU_Index].fIndex = 1;
+ indices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
+
+ indices[SkYUVAIndex::kV_Index].fIndex = 1;
+ indices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kG;
+ if (has_alpha) {
+ process_planar(2, RED_8);
+ indices[SkYUVAIndex::kA_Index].fIndex = 2;
+ indices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
+ }
+ }
+
+ return SkImage::MakeFromYUVATextures(
+ gr_context(), yuv_color_space, yuva_textures, indices,
+ SkISize::Make(yuva_textures[0].width(), yuva_textures[1].height()),
+ kTopLeft_GrSurfaceOrigin);
+}
+
+gpu::SyncToken SkiaOutputSurfaceImplNonDDL::ReleasePromiseSkImages(
+ std::vector<sk_sp<SkImage>> images) {
+ if (images.empty())
+ return gpu::SyncToken();
+ DCHECK_EQ(order_num_, 0u);
+ order_num_ = sync_point_order_data_->GenerateUnprocessedOrderNumber();
+ sync_point_order_data_->BeginProcessingOrderNumber(order_num_);
+ gpu::SyncToken sync_token(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE_NON_DDL,
+ sync_point_client_state_->command_buffer_id(), ++sync_fence_release_);
+ sync_token.SetVerifyFlush();
+ sync_point_client_state_->ReleaseFenceSync(sync_fence_release_);
+ DCHECK(mailbox_manager_->UsesSync());
+ mailbox_manager_->PushTextureUpdates(sync_token);
+ sync_point_order_data_->FinishProcessingOrderNumber(order_num_);
+ order_num_ = 0u;
+ return sync_token;
+}
+
+void SkiaOutputSurfaceImplNonDDL::SkiaSwapBuffers(OutputSurfaceFrame frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ gl_surface_->SwapBuffers(
+ base::BindOnce(&SkiaOutputSurfaceImplNonDDL::BufferPresented,
+ weak_ptr_factory_.GetWeakPtr()));
+ if (need_swapbuffers_ack_)
+ client_->DidReceiveSwapBuffersAck();
+}
+
+SkCanvas* SkiaOutputSurfaceImplNonDDL::BeginPaintRenderPass(
+ const RenderPassId& id,
+ const gfx::Size& surface_size,
+ ResourceFormat format,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // Make sure there is no unsubmitted PaintFrame or PaintRenderPass.
+ DCHECK_EQ(current_render_pass_id_, 0u);
+ DCHECK_EQ(order_num_, 0u);
+ order_num_ = sync_point_order_data_->GenerateUnprocessedOrderNumber();
+ sync_point_order_data_->BeginProcessingOrderNumber(order_num_);
+ current_render_pass_id_ = id;
+ auto& sk_surface = offscreen_sk_surfaces_[id];
+
+ if (!sk_surface) {
+ SkColorType color_type =
+ ResourceFormatToClosestSkColorType(true /* gpu_compositing */, format);
+ SkImageInfo image_info = SkImageInfo::Make(
+ surface_size.width(), surface_size.height(), color_type,
+ kPremul_SkAlphaType, std::move(color_space));
+ sk_surface =
+ SkSurface::MakeRenderTarget(gr_context(), SkBudgeted::kNo, image_info);
+ }
+ return sk_surface->getCanvas();
+}
+
+gpu::SyncToken SkiaOutputSurfaceImplNonDDL::SubmitPaint() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (current_render_pass_id_ == 0) {
+ sk_surface_->flush();
+ } else {
+ offscreen_sk_surfaces_[current_render_pass_id_]->flush();
+ }
+ gpu::SyncToken sync_token(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE_NON_DDL,
+ sync_point_client_state_->command_buffer_id(), ++sync_fence_release_);
+ sync_token.SetVerifyFlush();
+ sync_point_client_state_->ReleaseFenceSync(sync_fence_release_);
+ DCHECK(mailbox_manager_->UsesSync());
+ mailbox_manager_->PushTextureUpdates(sync_token);
+ DCHECK_NE(order_num_, 0u);
+ sync_point_order_data_->FinishProcessingOrderNumber(order_num_);
+ order_num_ = 0u;
+ current_render_pass_id_ = 0;
+ return sync_token;
+}
+
+sk_sp<SkImage> SkiaOutputSurfaceImplNonDDL::MakePromiseSkImageFromRenderPass(
+ const RenderPassId& id,
+ const gfx::Size& size,
+ ResourceFormat format,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ auto it = offscreen_sk_surfaces_.find(id);
+ DCHECK(it != offscreen_sk_surfaces_.end());
+ return it->second->makeImageSnapshot();
+}
+
+void SkiaOutputSurfaceImplNonDDL::RemoveRenderPassResource(
+ std::vector<RenderPassId> ids) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(!ids.empty());
+
+ for (const auto& id : ids) {
+ auto it = offscreen_sk_surfaces_.find(id);
+ DCHECK(it != offscreen_sk_surfaces_.end());
+ offscreen_sk_surfaces_.erase(it);
+ }
+}
+
+void SkiaOutputSurfaceImplNonDDL::CopyOutput(
+ RenderPassId id,
+ const copy_output::RenderPassGeometry& geometry,
+ const gfx::ColorSpace& color_space,
+ std::unique_ptr<CopyOutputRequest> request) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ NOTIMPLEMENTED();
+}
+
+void SkiaOutputSurfaceImplNonDDL::AddContextLostObserver(
+ ContextLostObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SkiaOutputSurfaceImplNonDDL::RemoveContextLostObserver(
+ ContextLostObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool SkiaOutputSurfaceImplNonDDL::WaitSyncToken(
+ const gpu::SyncToken& sync_token) {
+ base::WaitableEvent event;
+ if (!sync_point_client_state_->Wait(
+ sync_token, base::BindOnce(&base::WaitableEvent::Signal,
+ base::Unretained(&event)))) {
+ return false;
+ }
+ event.Wait();
+ return true;
+}
+
+sk_sp<SkImage> SkiaOutputSurfaceImplNonDDL::MakeSkImageFromSharedImage(
+ const ResourceMetadata& metadata) {
+ auto representation =
+ sir_factory_->ProduceSkia(metadata.mailbox_holder.mailbox);
+ if (!representation) {
+ DLOG(ERROR) << "Failed to make the SkImage - SharedImage mailbox not "
+ "found in SharedImageManager.";
+ return nullptr;
+ }
+
+ if (!(representation->usage() & gpu::SHARED_IMAGE_USAGE_DISPLAY)) {
+ DLOG(ERROR) << "Failed to make the SkImage - SharedImage was not created "
+ "with display usage.";
+ return nullptr;
+ }
+ // TODO(penghuang): make SharedImageBacking be aware the target context.
+ auto promise_texture =
+ representation->BeginReadAccess(nullptr /* read_surface */);
+ if (!promise_texture) {
+ DLOG(ERROR)
+ << "Failed to begin read access for SharedImageRepresentationSkia";
+ return nullptr;
+ }
+
+ SkColorType color_type = ResourceFormatToClosestSkColorType(
+ true /* gpu_compositing */, metadata.resource_format);
+
+ auto sk_image = SkImage::MakeFromTexture(
+ gr_context(), promise_texture->backendTexture(), kTopLeft_GrSurfaceOrigin,
+ color_type, metadata.alpha_type, metadata.color_space.ToSkColorSpace(),
+ ReleaseSharedImagePresentation, representation.get());
+
+ if (!sk_image) {
+ DLOG(ERROR) << "Failed to create the SkImage";
+ return nullptr;
+ }
+
+ representation.release();
+ return sk_image;
+}
+
+bool SkiaOutputSurfaceImplNonDDL::GetGrBackendTexture(
+ const ResourceMetadata& metadata,
+ GrBackendTexture* backend_texture) {
+ DCHECK(!metadata.mailbox_holder.mailbox.IsZero());
+ if (WaitSyncToken(metadata.mailbox_holder.sync_token)) {
+ DCHECK(mailbox_manager_->UsesSync());
+ mailbox_manager_->PullTextureUpdates(metadata.mailbox_holder.sync_token);
+ }
+
+ auto* texture_base =
+ mailbox_manager_->ConsumeTexture(metadata.mailbox_holder.mailbox);
+ if (!texture_base) {
+ DLOG(ERROR) << "Failed to make the SkImage";
+ return false;
+ }
+
+ auto* gl_version_info =
+ shared_context_state_->real_context()->GetVersionInfo();
+ return gpu::GetGrBackendTexture(gl_version_info, texture_base->target(),
+ metadata.size, texture_base->service_id(),
+ metadata.resource_format, backend_texture);
+}
+
+void SkiaOutputSurfaceImplNonDDL::BufferPresented(
+ const gfx::PresentationFeedback& feedback) {
+ if (need_swapbuffers_ack_)
+ client_->DidReceivePresentationFeedback(feedback);
+}
+
+void SkiaOutputSurfaceImplNonDDL::ContextLost() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ for (auto& observer : observers_)
+ observer.OnContextLost();
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h
new file mode 100644
index 00000000000..3bb3e95721e
--- /dev/null
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h
@@ -0,0 +1,163 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_NON_DDL_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_NON_DDL_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
+#include "components/viz/service/display/skia_output_surface.h"
+#include "components/viz/service/viz_service_export.h"
+#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+
+namespace gfx {
+struct PresentationFeedback;
+}
+
+namespace gl {
+class GLSurface;
+}
+
+namespace gpu {
+class MailboxManager;
+class SharedImageManager;
+class SharedImageRepresentationFactory;
+class SyncPointClientState;
+class SyncPointManager;
+class SyncPointOrderData;
+} // namespace gpu
+
+namespace viz {
+
+// A SkiaOutputSurface implementation for running SkiaRenderer on GpuThread.
+// Comparing to SkiaOutputSurfaceImpl, it will issue skia draw operations
+// against OS graphics API (GL, Vulkan, etc) instead of recording deferred
+// display list first.
+class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImplNonDDL
+ : public SkiaOutputSurface {
+ public:
+ SkiaOutputSurfaceImplNonDDL(
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state,
+ gpu::MailboxManager* mailbox_manager,
+ gpu::SharedImageManager* shared_image_manager,
+ gpu::SyncPointManager* sync_point_manager,
+ bool need_swapbuffers_ack);
+ ~SkiaOutputSurfaceImplNonDDL() override;
+
+ // OutputSurface implementation:
+ void BindToClient(OutputSurfaceClient* client) override;
+ void EnsureBackbuffer() override;
+ void DiscardBackbuffer() override;
+ void BindFramebuffer() override;
+ void SetDrawRectangle(const gfx::Rect& draw_rectangle) override;
+ void Reshape(const gfx::Size& size,
+ float device_scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha,
+ bool use_stencil) override;
+ void SwapBuffers(OutputSurfaceFrame frame) override;
+ uint32_t GetFramebufferCopyTextureFormat() override;
+ OverlayCandidateValidator* GetOverlayCandidateValidator() const override;
+ bool IsDisplayedAsOverlayPlane() const override;
+ unsigned GetOverlayTextureId() const override;
+ gfx::BufferFormat GetOverlayBufferFormat() const override;
+ bool HasExternalStencilTest() const override;
+ void ApplyExternalStencil() override;
+ unsigned UpdateGpuFence() override;
+ void SetNeedsSwapSizeNotifications(
+ bool needs_swap_size_notifications) override;
+
+ // SkiaOutputSurface implementation:
+ SkCanvas* BeginPaintCurrentFrame() override;
+ sk_sp<SkImage> MakePromiseSkImageFromYUV(
+ std::vector<ResourceMetadata> metadatas,
+ SkYUVColorSpace yuv_color_space,
+ bool has_alpha) override;
+ void SkiaSwapBuffers(OutputSurfaceFrame frame) override;
+ SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
+ const gfx::Size& surface_size,
+ ResourceFormat format,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) override;
+ gpu::SyncToken SubmitPaint() override;
+ sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) override;
+ sk_sp<SkImage> MakePromiseSkImageFromRenderPass(
+ const RenderPassId& id,
+ const gfx::Size& size,
+ ResourceFormat format,
+ bool mipmap,
+ sk_sp<SkColorSpace> color_space) override;
+ gpu::SyncToken ReleasePromiseSkImages(
+ std::vector<sk_sp<SkImage>> images) override;
+
+ void RemoveRenderPassResource(std::vector<RenderPassId> ids) override;
+ void CopyOutput(RenderPassId id,
+ const copy_output::RenderPassGeometry& geometry,
+ const gfx::ColorSpace& color_space,
+ std::unique_ptr<CopyOutputRequest> request) override;
+ void AddContextLostObserver(ContextLostObserver* observer) override;
+ void RemoveContextLostObserver(ContextLostObserver* observer) override;
+
+ private:
+ GrContext* gr_context() { return shared_context_state_->gr_context(); }
+
+ bool WaitSyncToken(const gpu::SyncToken& sync_token);
+ sk_sp<SkImage> MakeSkImageFromSharedImage(const ResourceMetadata& metadata);
+ bool GetGrBackendTexture(const ResourceMetadata& metadata,
+ GrBackendTexture* backend_texture);
+
+ void BufferPresented(const gfx::PresentationFeedback& feedback);
+ void ContextLost();
+
+ uint64_t sync_fence_release_ = 0;
+
+ // Stuffs for running with |task_executor_| instead of |gpu_service_|.
+ scoped_refptr<gl::GLSurface> gl_surface_;
+ scoped_refptr<gpu::SharedContextState> shared_context_state_;
+ gpu::MailboxManager* const mailbox_manager_;
+ std::unique_ptr<gpu::SharedImageRepresentationFactory> sir_factory_;
+ scoped_refptr<gpu::SyncPointOrderData> sync_point_order_data_;
+ scoped_refptr<gpu::SyncPointClientState> sync_point_client_state_;
+ const bool need_swapbuffers_ack_;
+ uint32_t order_num_ = 0u;
+
+ OutputSurfaceClient* client_ = nullptr;
+
+ unsigned int backing_framebuffer_object_ = 0;
+ gfx::Size reshape_surface_size_;
+ float reshape_device_scale_factor_ = 0.f;
+ gfx::ColorSpace reshape_color_space_;
+ bool reshape_has_alpha_ = false;
+ bool reshape_use_stencil_ = false;
+
+ // The current render pass id set by BeginPaintRenderPass.
+ RenderPassId current_render_pass_id_ = 0;
+
+ // Observers for context lost.
+ base::ObserverList<ContextLostObserver>::Unchecked observers_;
+
+ // The SkSurface for the framebuffer.
+ sk_sp<SkSurface> sk_surface_;
+
+ // Offscreen SkSurfaces for render passes.
+ base::flat_map<RenderPassId, sk_sp<SkSurface>> offscreen_sk_surfaces_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ base::WeakPtrFactory<SkiaOutputSurfaceImplNonDDL> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SkiaOutputSurfaceImplNonDDL);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_SURFACE_IMPL_NON_DDL_H_
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index e58ace1d6d1..5e1af789033 100644
--- a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -5,25 +5,33 @@
#include "components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h"
#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/common/skia_helper.h"
+#include "components/viz/service/display/gl_renderer_copier.h"
#include "components/viz/service/display/output_surface_frame.h"
+#include "components/viz/service/display/texture_deleter.h"
+#include "components/viz/service/display_embedder/direct_context_provider.h"
#include "components/viz/service/gl/gpu_service_impl.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/service/context_state.h"
#include "gpu/command_buffer/service/gr_shader_cache.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/scheduler.h"
+#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/command_buffer/service/shared_image_representation.h"
#include "gpu/command_buffer/service/skia_utils.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/command_buffer/service/texture_base.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/config/gpu_preferences.h"
+#include "gpu/ipc/command_buffer_task_executor.h"
#include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/common/gpu_surface_lookup.h"
#include "gpu/ipc/service/image_transport_surface.h"
@@ -41,7 +49,9 @@
#include "ui/gl/init/gl_factory.h"
#if BUILDFLAG(ENABLE_VULKAN)
+#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/vulkan/vulkan_implementation.h"
+#include "gpu/vulkan/vulkan_surface.h"
#endif
#if defined(USE_OZONE)
@@ -51,6 +61,67 @@
#endif
namespace viz {
+
+// Skia gr_context() and |context_provider_| share an underlying GLContext.
+// Each of them caches some GL state. Interleaving usage could make cached
+// state inconsistent with GL state. Using a ScopedUseContextProvider whenever
+// |context_provider_| could be accessed (e.g. processing completed queries),
+// will keep cached state consistent with driver GL state.
+class SkiaOutputSurfaceImplOnGpu::ScopedUseContextProvider {
+ public:
+ ScopedUseContextProvider(SkiaOutputSurfaceImplOnGpu* impl_on_gpu,
+ GLuint texture_client_id)
+ : impl_on_gpu_(impl_on_gpu) {
+ if (!impl_on_gpu_->MakeCurrent(true /* need_fbo0 */)) {
+ valid_ = false;
+ return;
+ }
+
+ // GLRendererCopier uses context_provider_->ContextGL(), which caches GL
+ // state and removes state setting calls that it considers redundant. To get
+ // to a known GL state, we first set driver GL state and then make client
+ // side consistent with that.
+ auto* api = impl_on_gpu_->api_;
+ api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, 0);
+ impl_on_gpu_->context_provider_->SetGLRendererCopierRequiredState(
+ texture_client_id);
+ }
+
+ ~ScopedUseContextProvider() {
+ if (valid_)
+ impl_on_gpu_->gr_context()->resetContext();
+ }
+
+ bool valid() { return valid_; }
+
+ private:
+ SkiaOutputSurfaceImplOnGpu* const impl_on_gpu_;
+ bool valid_ = true;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedUseContextProvider);
+};
+
+// TODO(backer): Use this wrapper for GL as well.
+// Thin wrapper around gpu::VulkanSurface that allows us to easily inject
+// a fake offscreen surface for tests.
+class SkiaOutputSurfaceImplOnGpu::SurfaceWrapper {
+ public:
+ SurfaceWrapper();
+ virtual ~SurfaceWrapper();
+
+ // SkSurface that can be drawn to.
+ virtual sk_sp<SkSurface> DrawSurface() = 0;
+
+ // Changes the size of draw surface and invalidates it's contents.
+ virtual void Reshape(const gfx::Size& size) = 0;
+
+ // Presents DrawSurface.
+ virtual gpu::SwapBuffersCompleteParams SwapBuffers() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SurfaceWrapper);
+};
+
namespace {
base::AtomicSequenceNumber g_next_command_buffer_id;
@@ -68,6 +139,318 @@ class FakeOnScreenSurface : public gl::GLSurfaceAdapter {
~FakeOnScreenSurface() override = default;
};
+scoped_refptr<gpu::gles2::FeatureInfo> CreateFeatureInfo(
+ GpuServiceImpl* gpu_service) {
+ auto* channel_manager = gpu_service->gpu_channel_manager();
+ return base::MakeRefCounted<gpu::gles2::FeatureInfo>(
+ channel_manager->gpu_driver_bug_workarounds(),
+ channel_manager->gpu_feature_info());
+}
+
+scoped_refptr<gpu::gles2::FeatureInfo> CreateFeatureInfo(
+ gpu::CommandBufferTaskExecutor* task_executor) {
+ return base::MakeRefCounted<gpu::gles2::FeatureInfo>(
+ gpu::GpuDriverBugWorkarounds(
+ task_executor->gpu_feature_info().enabled_gpu_driver_bug_workarounds),
+ task_executor->gpu_feature_info());
+}
+
+scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState(
+ GpuServiceImpl* gpu_service) {
+ auto command_buffer_id = gpu::CommandBufferId::FromUnsafeValue(
+ g_next_command_buffer_id.GetNext() + 1);
+ return gpu_service->sync_point_manager()->CreateSyncPointClientState(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE, command_buffer_id,
+ gpu_service->skia_output_surface_sequence_id());
+}
+
+scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState(
+ gpu::CommandBufferTaskExecutor* task_executor,
+ gpu::SequenceId sequence_id) {
+ auto command_buffer_id = gpu::CommandBufferId::FromUnsafeValue(
+ g_next_command_buffer_id.GetNext() + 1);
+ return task_executor->sync_point_manager()->CreateSyncPointClientState(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE, command_buffer_id,
+ sequence_id);
+}
+
+std::unique_ptr<gpu::SharedImageRepresentationFactory>
+CreateSharedImageRepresentationFactory(GpuServiceImpl* gpu_service) {
+ // TODO(https://crbug.com/899905): Use a real MemoryTracker, not nullptr.
+ return std::make_unique<gpu::SharedImageRepresentationFactory>(
+ gpu_service->shared_image_manager(), nullptr);
+}
+
+std::unique_ptr<gpu::SharedImageRepresentationFactory>
+CreateSharedImageRepresentationFactory(
+ gpu::CommandBufferTaskExecutor* task_executor) {
+ // TODO(https://crbug.com/899905): Use a real MemoryTracker, not nullptr.
+ return std::make_unique<gpu::SharedImageRepresentationFactory>(
+ task_executor->shared_image_manager(), nullptr);
+}
+
+class ScopedSurfaceToTexture {
+ public:
+ ScopedSurfaceToTexture(scoped_refptr<DirectContextProvider> context_provider,
+ SkSurface* surface)
+ : context_provider_(context_provider) {
+ GrBackendTexture skia_texture =
+ surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
+ GrGLTextureInfo gl_texture_info;
+ skia_texture.getGLTextureInfo(&gl_texture_info);
+ GLuint client_id = context_provider_->GenClientTextureId();
+ auto* texture_manager = context_provider_->texture_manager();
+ texture_ref_ =
+ texture_manager->CreateTexture(client_id, gl_texture_info.fID);
+ texture_manager->SetTarget(texture_ref_.get(), gl_texture_info.fTarget);
+ texture_manager->SetLevelInfo(
+ texture_ref_.get(), gl_texture_info.fTarget,
+ /*level=*/0,
+ /*internal_format=*/GL_RGBA, surface->width(), surface->height(),
+ /*depth=*/1, /*border=*/0,
+ /*format=*/GL_RGBA, /*type=*/GL_UNSIGNED_BYTE,
+ /*cleared_rect=*/gfx::Rect(surface->width(), surface->height()));
+ }
+
+ ~ScopedSurfaceToTexture() {
+ context_provider_->DeleteClientTextureId(client_id());
+
+ // Skia owns the texture. It will delete it when it is done.
+ texture_ref_->ForceContextLost();
+ }
+
+ GLuint client_id() { return texture_ref_->client_id(); }
+
+ private:
+ scoped_refptr<DirectContextProvider> context_provider_;
+ scoped_refptr<gpu::gles2::TextureRef> texture_ref_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSurfaceToTexture);
+};
+
+// This SingleThreadTaskRunner runs tasks on the GPU main thread, where
+// DirectContextProvider can safely service calls. It wraps all posted tasks to
+// ensure that |impl_on_gpu_->context_provider_| is made current and in a known
+// state when the task is run. If |impl_on_gpu| is destructed, pending tasks are
+// no-oped when they are run.
+class ContextCurrentTaskRunner : public base::SingleThreadTaskRunner {
+ public:
+ explicit ContextCurrentTaskRunner(SkiaOutputSurfaceImplOnGpu* impl_on_gpu)
+ : real_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ impl_on_gpu_(impl_on_gpu) {}
+
+ bool PostDelayedTask(const base::Location& from_here,
+ base::OnceClosure task,
+ base::TimeDelta delay) override {
+ return real_task_runner_->PostDelayedTask(
+ from_here, WrapClosure(std::move(task)), delay);
+ }
+
+ bool PostNonNestableDelayedTask(const base::Location& from_here,
+ base::OnceClosure task,
+ base::TimeDelta delay) override {
+ return real_task_runner_->PostNonNestableDelayedTask(
+ from_here, WrapClosure(std::move(task)), delay);
+ }
+
+ bool RunsTasksInCurrentSequence() const override {
+ return real_task_runner_->RunsTasksInCurrentSequence();
+ }
+
+ private:
+ base::OnceClosure WrapClosure(base::OnceClosure task) {
+ return base::BindOnce(
+ [](base::WeakPtr<SkiaOutputSurfaceImplOnGpu> impl_on_gpu,
+ base::OnceClosure task) {
+ if (!impl_on_gpu)
+ return;
+ SkiaOutputSurfaceImplOnGpu::ScopedUseContextProvider scoped_use(
+ impl_on_gpu.get(), /*texture_client_id=*/0);
+ if (!scoped_use.valid())
+ return;
+
+ std::move(task).Run();
+ },
+ impl_on_gpu_->weak_ptr(), std::move(task));
+ }
+
+ ~ContextCurrentTaskRunner() override = default;
+
+ scoped_refptr<base::SingleThreadTaskRunner> real_task_runner_;
+ SkiaOutputSurfaceImplOnGpu* const impl_on_gpu_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContextCurrentTaskRunner);
+};
+
+#if BUILDFLAG(ENABLE_VULKAN)
+// Wrap gpu::VulkanSurface for use in Skia API. Creates a sequence of SkSurface
+// around the gpu::VulkanSurface::GetSwapChain().
+class OnScreenVulkanSurface final
+ : public SkiaOutputSurfaceImplOnGpu::SurfaceWrapper {
+ public:
+ OnScreenVulkanSurface(VulkanContextProvider* context_provider,
+ gpu::SurfaceHandle surface_handle)
+ : context_provider_(context_provider), surface_handle_(surface_handle) {}
+
+ ~OnScreenVulkanSurface() override {
+ if (vulkan_surface_)
+ vulkan_surface_->Destroy();
+ }
+
+ // SurfaceWrapper implementation
+ sk_sp<SkSurface> DrawSurface() override { return draw_surface_; }
+
+ void Reshape(const gfx::Size& size) override {
+ if (!vulkan_surface_)
+ CreateVulkanSurface();
+
+ auto old_size = vulkan_surface_->size();
+ vulkan_surface_->SetSize(size);
+ if (vulkan_surface_->size() != old_size) {
+ // Size has been changed, we need to clear all surfaces which will be
+ // recreated later.
+ sk_surfaces_.clear();
+ sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images());
+ }
+
+ UpdateDrawSurface();
+ }
+
+ gpu::SwapBuffersCompleteParams SwapBuffers() override {
+ // Reshape should have been called first.
+ DCHECK(vulkan_surface_);
+ DCHECK(draw_surface_);
+
+ gpu::SwapBuffersCompleteParams params;
+ params.swap_response.swap_start = base::TimeTicks::Now();
+
+ auto backend = draw_surface_->getBackendRenderTarget(
+ SkSurface::kFlushRead_BackendHandleAccess);
+ GrVkImageInfo vk_image_info;
+ if (!backend.getVkImageInfo(&vk_image_info))
+ NOTREACHED() << "Failed to get the image info.";
+ vulkan_surface_->GetSwapChain()->SetCurrentImageLayout(
+ vk_image_info.fImageLayout);
+ params.swap_response.result = vulkan_surface_->SwapBuffers();
+ params.swap_response.swap_end = base::TimeTicks::Now();
+
+ UpdateDrawSurface();
+
+ return params;
+ }
+
+ private:
+ void CreateVulkanSurface() {
+ gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget;
+#if defined(OS_ANDROID)
+ accelerated_widget =
+ gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
+ surface_handle_);
+#else
+ accelerated_widget = surface_handle_;
+#endif
+ auto vulkan_surface =
+ context_provider_->GetVulkanImplementation()->CreateViewSurface(
+ accelerated_widget);
+ if (!vulkan_surface)
+ LOG(FATAL) << "Failed to create vulkan surface.";
+ if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(),
+ gpu::VulkanSurface::FORMAT_RGBA_32)) {
+ LOG(FATAL) << "Failed to initialize vulkan surface.";
+ }
+ vulkan_surface_ = std::move(vulkan_surface);
+ }
+
+ void UpdateDrawSurface() {
+ DCHECK(vulkan_surface_);
+ auto* swap_chain = vulkan_surface_->GetSwapChain();
+ auto index = swap_chain->current_image();
+ auto& sk_surface = sk_surfaces_[index];
+ if (!sk_surface) {
+ SkSurfaceProps surface_props =
+ SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
+ VkImage vk_image = swap_chain->GetCurrentImage();
+ VkImageLayout vk_image_layout = swap_chain->GetCurrentImageLayout();
+ const auto surface_format = vulkan_surface_->surface_format().format;
+ DCHECK(surface_format == VK_FORMAT_B8G8R8A8_UNORM ||
+ surface_format == VK_FORMAT_R8G8B8A8_UNORM);
+ GrVkImageInfo vk_image_info(vk_image, GrVkAlloc(),
+ VK_IMAGE_TILING_OPTIMAL, vk_image_layout,
+ surface_format, 1 /* level_count */);
+ GrBackendRenderTarget render_target(vulkan_surface_->size().width(),
+ vulkan_surface_->size().height(),
+ 0 /* sample_cnt */, vk_image_info);
+ auto sk_color_type = surface_format == VK_FORMAT_B8G8R8A8_UNORM
+ ? kBGRA_8888_SkColorType
+ : kRGBA_8888_SkColorType;
+ sk_surface = SkSurface::MakeFromBackendRenderTarget(
+ context_provider_->GetGrContext(), render_target,
+ kTopLeft_GrSurfaceOrigin, sk_color_type, nullptr /* color_space */,
+ &surface_props);
+ DCHECK(sk_surface);
+ } else {
+ auto backend = sk_surface->getBackendRenderTarget(
+ SkSurface::kFlushRead_BackendHandleAccess);
+ backend.setVkImageLayout(swap_chain->GetCurrentImageLayout());
+ }
+
+ draw_surface_ = sk_surface;
+ }
+
+ VulkanContextProvider* const context_provider_;
+
+ const gpu::SurfaceHandle surface_handle_;
+ std::unique_ptr<gpu::VulkanSurface> vulkan_surface_;
+
+ // SkSurfaces for swap chain images.
+ std::vector<sk_sp<SkSurface>> sk_surfaces_;
+
+ // SkSurface to be drawn to. Updated after Reshape and SwapBuffers.
+ sk_sp<SkSurface> draw_surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(OnScreenVulkanSurface);
+};
+
+// An offscreen surface suitable for tests.
+class OffscreenVulkanSurface final
+ : public SkiaOutputSurfaceImplOnGpu::SurfaceWrapper {
+ public:
+ explicit OffscreenVulkanSurface(GrContext* gr_context)
+ : gr_context_(gr_context) {}
+ ~OffscreenVulkanSurface() override = default;
+
+ // SurfaceWrapper implementation:
+ sk_sp<SkSurface> DrawSurface() override { return draw_surface_; }
+
+ void Reshape(const gfx::Size& size) override {
+ auto image_info =
+ SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
+ kOpaque_SkAlphaType);
+ draw_surface_ =
+ SkSurface::MakeRenderTarget(gr_context_, SkBudgeted::kNo, image_info);
+ }
+
+ gpu::SwapBuffersCompleteParams SwapBuffers() override {
+ // Reshape should have been called first.
+ DCHECK(draw_surface_);
+
+ gpu::SwapBuffersCompleteParams params;
+ params.swap_response.swap_start = base::TimeTicks::Now();
+ params.swap_response.result = gfx::SwapResult::SWAP_ACK;
+ params.swap_response.swap_end = params.swap_response.swap_start;
+
+ return params;
+ }
+
+ private:
+ GrContext* const gr_context_;
+ sk_sp<SkSurface> draw_surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(OffscreenVulkanSurface);
+};
+
+#endif // if BUILDFLAG(ENABLE_VULKAN)
+
} // namespace
SkiaOutputSurfaceImplOnGpu::OffscreenSurface::OffscreenSurface() = default;
@@ -75,71 +458,132 @@ SkiaOutputSurfaceImplOnGpu::OffscreenSurface::OffscreenSurface() = default;
SkiaOutputSurfaceImplOnGpu::OffscreenSurface::~OffscreenSurface() = default;
SkiaOutputSurfaceImplOnGpu::OffscreenSurface::OffscreenSurface(
- const OffscreenSurface& offscreen_surface) = default;
-
-SkiaOutputSurfaceImplOnGpu::OffscreenSurface::OffscreenSurface(
OffscreenSurface&& offscreen_surface) = default;
SkiaOutputSurfaceImplOnGpu::OffscreenSurface&
SkiaOutputSurfaceImplOnGpu::OffscreenSurface::operator=(
- const OffscreenSurface& offscreen_surface) = default;
-
-SkiaOutputSurfaceImplOnGpu::OffscreenSurface&
-SkiaOutputSurfaceImplOnGpu::OffscreenSurface::operator=(
OffscreenSurface&& offscreen_surface) = default;
+SkSurface* SkiaOutputSurfaceImplOnGpu::OffscreenSurface::surface() const {
+ return surface_.get();
+}
+
+sk_sp<SkPromiseImageTexture>
+SkiaOutputSurfaceImplOnGpu::OffscreenSurface::fulfill() {
+ DCHECK(surface_);
+ if (!promise_texture_) {
+ promise_texture_ = SkPromiseImageTexture::Make(
+ surface_->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
+ }
+ return promise_texture_;
+}
+
+void SkiaOutputSurfaceImplOnGpu::OffscreenSurface::set_surface(
+ sk_sp<SkSurface> surface) {
+ surface_ = std::move(surface);
+ promise_texture_ = {};
+}
+
+SkiaOutputSurfaceImplOnGpu::SurfaceWrapper::SurfaceWrapper() = default;
+
+SkiaOutputSurfaceImplOnGpu::SurfaceWrapper::~SurfaceWrapper() = default;
+
SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
- GpuServiceImpl* gpu_service,
gpu::SurfaceHandle surface_handle,
+ scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
+ gpu::MailboxManager* mailbox_manager,
+ scoped_refptr<gpu::SyncPointClientState> sync_point_client_state,
+ std::unique_ptr<gpu::SharedImageRepresentationFactory> sir_factory,
+ gpu::raster::GrShaderCache* gr_shader_cache,
+ VulkanContextProvider* vulkan_context_provider,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
const BufferPresentedCallback& buffer_presented_callback,
const ContextLostCallback& context_lost_callback)
- : command_buffer_id_(gpu::CommandBufferId::FromUnsafeValue(
- g_next_command_buffer_id.GetNext() + 1)),
- gpu_service_(gpu_service),
- surface_handle_(surface_handle),
+ : surface_handle_(surface_handle),
+ feature_info_(std::move(feature_info)),
+ mailbox_manager_(mailbox_manager),
+ sync_point_client_state_(std::move(sync_point_client_state)),
+ shared_image_representation_factory_(std::move(sir_factory)),
+ gr_shader_cache_(gr_shader_cache),
+ vulkan_context_provider_(vulkan_context_provider),
did_swap_buffer_complete_callback_(did_swap_buffer_complete_callback),
buffer_presented_callback_(buffer_presented_callback),
context_lost_callback_(context_lost_callback),
- // TODO(https://crbug.com/899905): Use a real MemoryTracker, not nullptr.
- shared_image_representation_factory_(
- std::make_unique<gpu::SharedImageRepresentationFactory>(
- gpu_service_->shared_image_manager(),
- nullptr)),
weak_ptr_factory_(this) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
+}
- sync_point_client_state_ =
- gpu_service_->sync_point_manager()->CreateSyncPointClientState(
- gpu::CommandBufferNamespace::VIZ_OUTPUT_SURFACE, command_buffer_id_,
- gpu_service_->skia_output_surface_sequence_id());
-
- gpu::GpuChannelManager* channel_manager = gpu_service_->gpu_channel_manager();
- feature_info_ = base::MakeRefCounted<gpu::gles2::FeatureInfo>(
- channel_manager->gpu_driver_bug_workarounds(),
- channel_manager->gpu_feature_info());
-
+SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
+ GpuServiceImpl* gpu_service,
+ gpu::SurfaceHandle surface_handle,
+ const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
+ const BufferPresentedCallback& buffer_presented_callback,
+ const ContextLostCallback& context_lost_callback)
+ : SkiaOutputSurfaceImplOnGpu(
+ surface_handle,
+ CreateFeatureInfo(gpu_service),
+ gpu_service->mailbox_manager(),
+ CreateSyncPointClientState(gpu_service),
+ CreateSharedImageRepresentationFactory(gpu_service),
+ gpu_service->gr_shader_cache(),
+ gpu_service->vulkan_context_provider(),
+ did_swap_buffer_complete_callback,
+ buffer_presented_callback,
+ context_lost_callback) {
#if defined(USE_OZONE)
window_surface_ = ui::OzonePlatform::GetInstance()
->GetSurfaceFactoryOzone()
->CreatePlatformWindowSurface(surface_handle);
#endif
+ if (gpu_service) {
+ gpu_preferences_ = gpu_service->gpu_channel_manager()->gpu_preferences();
+ } else {
+ auto* command_line = base::CommandLine::ForCurrentProcess();
+ gpu_preferences_ = gpu::gles2::ParseGpuPreferences(command_line);
+ }
- if (gpu_service_->is_using_vulkan())
- InitializeForVulkan();
+ if (is_using_vulkan())
+ InitializeForVulkan(gpu_service);
else
- InitializeForGL();
+ InitializeForGLWithGpuService(gpu_service);
+}
+
+SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
+ gpu::CommandBufferTaskExecutor* task_executor,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state,
+ gpu::SequenceId sequence_id,
+ const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
+ const BufferPresentedCallback& buffer_presented_callback,
+ const ContextLostCallback& context_lost_callback)
+ : SkiaOutputSurfaceImplOnGpu(
+ gpu::kNullSurfaceHandle,
+ CreateFeatureInfo(task_executor),
+ task_executor->mailbox_manager(),
+ CreateSyncPointClientState(task_executor, sequence_id),
+ CreateSharedImageRepresentationFactory(task_executor),
+ nullptr /* gr_shader_cache */,
+ nullptr /* vulkan_context_provider */,
+ did_swap_buffer_complete_callback,
+ buffer_presented_callback,
+ context_lost_callback) {
+ DCHECK(!is_using_vulkan());
+ gl_surface_ = std::move(gl_surface);
+ context_state_ = std::move(shared_context_state);
+ InitializeForGL();
}
SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-#if BUILDFLAG(ENABLE_VULKAN)
- if (vulkan_surface_) {
- vulkan_surface_->Destroy();
- vulkan_surface_ = nullptr;
- }
-#endif
+
+ // |context_provider_| and clients want either the context to be lost or made
+ // current on destruction.
+ MakeCurrent(false /* need_fbo0 */);
+ copier_ = nullptr;
+ texture_deleter_ = nullptr;
+ context_provider_ = nullptr;
+
sync_point_client_state_->Destroy();
}
@@ -159,67 +603,36 @@ void SkiaOutputSurfaceImplOnGpu::Reshape(
base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event)));
}
- if (!gpu_service_->is_using_vulkan()) {
- if (!MakeCurrent())
+ if (!is_using_vulkan()) {
+ if (!MakeCurrent(true /* need_fbo0 */))
return;
+ size_ = size;
+ color_space_ = color_space;
+ // Conversion to GLSurface's color space follows the same logic as in
+ // gl::GetGLColorSpace().
gl::GLSurface::ColorSpace surface_color_space =
- color_space == gfx::ColorSpace::CreateSCRGBLinear()
- ? gl::GLSurface::ColorSpace::SCRGB_LINEAR
- : gl::GLSurface::ColorSpace::UNSPECIFIED;
+ color_space.IsHDR() ? gl::GLSurface::ColorSpace::SCRGB_LINEAR
+ : gl::GLSurface::ColorSpace::UNSPECIFIED;
if (!gl_surface_->Resize(size, device_scale_factor, surface_color_space,
has_alpha)) {
LOG(FATAL) << "Failed to resize.";
// TODO(penghuang): Handle the failure.
}
DCHECK(gr_context());
-
- SkSurfaceProps surface_props =
- SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
-
- GrGLFramebufferInfo framebuffer_info;
- framebuffer_info.fFBOID = 0;
- framebuffer_info.fFormat =
- gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8;
-
- GrBackendRenderTarget render_target(size.width(), size.height(), 0, 8,
- framebuffer_info);
-
- sk_surface_ = SkSurface::MakeFromBackendRenderTarget(
- gr_context(), render_target, kBottomLeft_GrSurfaceOrigin,
- kBGRA_8888_SkColorType, nullptr, &surface_props);
- DCHECK(sk_surface_);
+ CreateSkSurfaceForGL();
} else {
#if BUILDFLAG(ENABLE_VULKAN)
- gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget;
-#if defined(OS_ANDROID)
- accelerated_widget =
- gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
- surface_handle_);
-#else
- accelerated_widget = surface_handle_;
-#endif
if (!vulkan_surface_) {
- auto vulkan_surface = gpu_service_->vulkan_context_provider()
- ->GetVulkanImplementation()
- ->CreateViewSurface(accelerated_widget);
- if (!vulkan_surface)
- LOG(FATAL) << "Failed to create vulkan surface.";
- if (!vulkan_surface->Initialize(
- gpu_service_->vulkan_context_provider()->GetDeviceQueue(),
- gpu::VulkanSurface::DEFAULT_SURFACE_FORMAT)) {
- LOG(FATAL) << "Failed to initialize vulkan surface.";
+ if (surface_handle_ == gpu::kNullSurfaceHandle) {
+ vulkan_surface_ =
+ std::make_unique<OffscreenVulkanSurface>(gr_context());
+ } else {
+ vulkan_surface_ = std::make_unique<OnScreenVulkanSurface>(
+ vulkan_context_provider_, surface_handle_);
}
- vulkan_surface_ = std::move(vulkan_surface);
- }
- auto old_size = vulkan_surface_->size();
- vulkan_surface_->SetSize(size);
- if (vulkan_surface_->size() != old_size) {
- // Size has been changed, we need to clear all surfaces which will be
- // recreated later.
- sk_surfaces_.clear();
- sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images());
}
- CreateSkSurfaceForVulkan();
+ vulkan_surface_->Reshape(size);
+ sk_surface_ = vulkan_surface_->DrawSurface();
#else
NOTREACHED();
#endif
@@ -234,19 +647,21 @@ void SkiaOutputSurfaceImplOnGpu::Reshape(
void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame(
std::unique_ptr<SkDeferredDisplayList> ddl,
std::unique_ptr<SkDeferredDisplayList> overdraw_ddl,
+ std::vector<gpu::SyncToken> sync_tokens,
uint64_t sync_fence_release) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(ddl);
DCHECK(sk_surface_);
- if (!MakeCurrent())
+ if (!MakeCurrent(true /* need_fbo0 */))
return;
+ PullTextureUpdates(std::move(sync_tokens));
+
{
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
- if (gpu_service_->gr_shader_cache()) {
- cache_use.emplace(gpu_service_->gr_shader_cache(),
- gpu::kInProcessCommandBufferClientId);
+ if (gr_shader_cache_) {
+ cache_use.emplace(gr_shader_cache_, gpu::kInProcessCommandBufferClientId);
}
sk_surface_->draw(ddl.get());
gr_context()->flush();
@@ -255,13 +670,12 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame(
// Note that the ScopedCacheUse for GrShaderCache is scoped until the
// ReleaseFenceSync call here since releasing the fence may schedule a
// different decoder's stream which also uses the shader cache.
- sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
+ ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release);
if (overdraw_ddl) {
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
- if (gpu_service_->gr_shader_cache()) {
- cache_use.emplace(gpu_service_->gr_shader_cache(),
- gpu::kInProcessCommandBufferClientId);
+ if (gr_shader_cache_) {
+ cache_use.emplace(gr_shader_cache_, gpu::kInProcessCommandBufferClientId);
}
sk_sp<SkSurface> overdraw_surface = SkSurface::MakeRenderTarget(
@@ -283,8 +697,8 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(sk_surface_);
base::TimeTicks swap_start, swap_end;
- if (!gpu_service_->is_using_vulkan()) {
- if (!MakeCurrent())
+ if (!is_using_vulkan()) {
+ if (!MakeCurrent(true /* need_fbo0 */))
return;
swap_start = base::TimeTicks::Now();
OnSwapBuffers();
@@ -292,24 +706,16 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) {
swap_end = base::TimeTicks::Now();
} else {
#if BUILDFLAG(ENABLE_VULKAN)
- swap_start = base::TimeTicks::Now();
+ DCHECK(vulkan_surface_);
OnSwapBuffers();
- auto backend = sk_surface_->getBackendRenderTarget(
- SkSurface::kFlushRead_BackendHandleAccess);
- GrVkImageInfo vk_image_info;
- if (!backend.getVkImageInfo(&vk_image_info))
- NOTREACHED() << "Failed to get the image info.";
- vulkan_surface_->GetSwapChain()->SetCurrentImageLayout(
- vk_image_info.fImageLayout);
-
- gpu::SwapBuffersCompleteParams params;
- params.swap_response.swap_start = base::TimeTicks::Now();
- params.swap_response.result = vulkan_surface_->SwapBuffers();
- params.swap_response.swap_end = base::TimeTicks::Now();
+ auto params = vulkan_surface_->SwapBuffers();
+ sk_surface_ = vulkan_surface_->DrawSurface();
DidSwapBuffersComplete(params);
+ buffer_presented_callback_.Run(gfx::PresentationFeedback(
+ params.swap_response.swap_end, base::TimeDelta(), 0 /* flag */));
- CreateSkSurfaceForVulkan();
- swap_end = base::TimeTicks::Now();
+ swap_start = params.swap_response.swap_start;
+ swap_end = params.swap_response.swap_end;
#else
NOTREACHED();
#endif
@@ -326,32 +732,35 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) {
void SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass(
RenderPassId id,
std::unique_ptr<SkDeferredDisplayList> ddl,
+ std::vector<gpu::SyncToken> sync_tokens,
uint64_t sync_fence_release) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(ddl);
- if (!MakeCurrent())
+ if (!MakeCurrent(true /* need_fbo0 */))
return;
- auto& surface = offscreen_surfaces_[id].surface;
+ PullTextureUpdates(std::move(sync_tokens));
+
+ auto& offscreen = offscreen_surfaces_[id];
SkSurfaceCharacterization characterization;
// TODO(penghuang): Using characterization != ddl->characterization(), when
// the SkSurfaceCharacterization::operator!= is implemented in Skia.
- if (!surface || !surface->characterize(&characterization) ||
+ if (!offscreen.surface() ||
+ !offscreen.surface()->characterize(&characterization) ||
characterization != ddl->characterization()) {
- surface = SkSurface::MakeRenderTarget(gr_context(), ddl->characterization(),
- SkBudgeted::kNo);
- DCHECK(surface);
+ offscreen.set_surface(SkSurface::MakeRenderTarget(
+ gr_context(), ddl->characterization(), SkBudgeted::kNo));
+ DCHECK(offscreen.surface());
}
{
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
- if (gpu_service_->gr_shader_cache())
- cache_use.emplace(gpu_service_->gr_shader_cache(),
- gpu::kInProcessCommandBufferClientId);
- surface->draw(ddl.get());
+ if (gr_shader_cache_)
+ cache_use.emplace(gr_shader_cache_, gpu::kInProcessCommandBufferClientId);
+ offscreen.surface()->draw(ddl.get());
gr_context()->flush();
}
- sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
+ ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release);
}
void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource(
@@ -367,29 +776,75 @@ void SkiaOutputSurfaceImplOnGpu::RemoveRenderPassResource(
void SkiaOutputSurfaceImplOnGpu::CopyOutput(
RenderPassId id,
- const gfx::Rect& copy_rect,
+ const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
- const gfx::Rect& result_rect,
std::unique_ptr<CopyOutputRequest> request) {
- // TODO(crbug.com/914502): Do this on the GPU instead of CPU with GL.
// TODO(crbug.com/898595): Do this on the GPU instead of CPU with Vulkan.
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!MakeCurrent())
+ bool from_fbo0 = !id;
+ if (!MakeCurrent(true /* need_fbo0 */))
return;
- DCHECK(!id || offscreen_surfaces_.find(id) != offscreen_surfaces_.end());
+ DCHECK(from_fbo0 ||
+ offscreen_surfaces_.find(id) != offscreen_surfaces_.end());
auto* surface =
- id ? offscreen_surfaces_[id].surface.get() : sk_surface_.get();
+ from_fbo0 ? sk_surface_.get() : offscreen_surfaces_[id].surface();
+
+ if (!is_using_vulkan()) {
+ // Lazy initialize GLRendererCopier.
+ if (!copier_) {
+ context_provider_ = base::MakeRefCounted<DirectContextProvider>(
+ context_state_->context(), gl_surface_, supports_alpha_,
+ gpu_preferences_, feature_info_.get());
+ auto result = context_provider_->BindToCurrentThread();
+ if (result != gpu::ContextResult::kSuccess) {
+ DLOG(ERROR) << "Couldn't initialize GLRendererCopier";
+ context_provider_ = nullptr;
+ return;
+ }
+ context_current_task_runner_ =
+ base::MakeRefCounted<ContextCurrentTaskRunner>(this);
+ texture_deleter_ =
+ std::make_unique<TextureDeleter>(context_current_task_runner_);
+ copier_ = std::make_unique<GLRendererCopier>(context_provider_,
+ texture_deleter_.get());
+ copier_->set_async_gl_task_runner(context_current_task_runner_);
+ }
+ surface->flush();
- SkBitmap bitmap;
- SkImageInfo copy_rect_info = SkImageInfo::Make(
- copy_rect.width(), copy_rect.height(), SkColorType::kN32_SkColorType,
- SkAlphaType::kPremul_SkAlphaType,
- surface->getCanvas()->imageInfo().refColorSpace());
- bitmap.allocPixels(copy_rect_info, copy_rect.width() * 4);
- surface->readPixels(bitmap, copy_rect.x(), copy_rect.y());
+ GLuint gl_id = 0;
+ GLenum internal_format = supports_alpha_ ? GL_RGBA : GL_RGB;
+ bool flipped = !capabilities_.flipped_output_surface;
+
+ base::Optional<ScopedSurfaceToTexture> texture_mapper;
+ if (!from_fbo0) {
+ texture_mapper.emplace(context_provider_.get(), surface);
+ gl_id = texture_mapper.value().client_id();
+ internal_format = GL_RGBA;
+ flipped = false;
+ }
+ gfx::Size surface_size(surface->width(), surface->height());
+ ScopedUseContextProvider use_context_provider(this, gl_id);
+ copier_->CopyFromTextureOrFramebuffer(std::move(request), geometry,
+ internal_format, gl_id, surface_size,
+ flipped, color_space);
+ if (decoder()->HasMoreIdleWork() || decoder()->HasPendingQueries())
+ ScheduleDelayedWork();
+
+ return;
+ }
+
+ SkBitmap bitmap;
if (request->is_scaled()) {
+ SkImageInfo sampling_bounds_info = SkImageInfo::Make(
+ geometry.sampling_bounds.width(), geometry.sampling_bounds.height(),
+ SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType,
+ surface->getCanvas()->imageInfo().refColorSpace());
+ bitmap.allocPixels(sampling_bounds_info);
+ surface->readPixels(bitmap, geometry.sampling_bounds.x(),
+ geometry.sampling_bounds.y());
+
// Execute the scaling: For downscaling, use the RESIZE_BETTER strategy
// (appropriate for thumbnailing); and, for upscaling, use the RESIZE_BEST
// strategy. Note that processing is only done on the subset of the
@@ -402,9 +857,19 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput(
is_downscale_in_both_dimensions ? ImageOperations::RESIZE_BETTER
: ImageOperations::RESIZE_BEST;
bitmap = ImageOperations::Resize(
- bitmap, method, result_rect.width(), result_rect.height(),
- SkIRect{result_rect.x(), result_rect.y(), result_rect.right(),
- result_rect.bottom()});
+ bitmap, method, geometry.result_bounds.width(),
+ geometry.result_bounds.height(),
+ SkIRect{geometry.result_selection.x(), geometry.result_selection.y(),
+ geometry.result_selection.right(),
+ geometry.result_selection.bottom()});
+ } else {
+ SkImageInfo sampling_bounds_info = SkImageInfo::Make(
+ geometry.result_selection.width(), geometry.result_selection.height(),
+ SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType,
+ surface->getCanvas()->imageInfo().refColorSpace());
+ bitmap.allocPixels(sampling_bounds_info);
+ surface->readPixels(bitmap, geometry.readback_offset.x(),
+ geometry.readback_offset.y());
}
// TODO(crbug.com/795132): Plumb color space throughout SkiaRenderer up to the
@@ -429,7 +894,37 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput(
// Note: The CopyOutputSkBitmapResult automatically provides I420 format
// conversion, if needed.
request->SendResult(std::make_unique<CopyOutputSkBitmapResult>(
- result_format, result_rect, bitmap));
+ result_format, geometry.result_selection, bitmap));
+}
+
+gpu::DecoderContext* SkiaOutputSurfaceImplOnGpu::decoder() {
+ return context_provider_->decoder();
+}
+
+void SkiaOutputSurfaceImplOnGpu::ScheduleDelayedWork() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (delayed_work_pending_)
+ return;
+ delayed_work_pending_ = true;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&SkiaOutputSurfaceImplOnGpu::PerformDelayedWork,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(2));
+}
+
+void SkiaOutputSurfaceImplOnGpu::PerformDelayedWork() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ ScopedUseContextProvider use_context_provider(this, /*texture_client_id=*/0);
+
+ delayed_work_pending_ = false;
+ if (MakeCurrent(true /* need_fbo0 */)) {
+ decoder()->PerformIdleWork();
+ decoder()->ProcessPendingQueries(false);
+ if (decoder()->HasMoreIdleWork() || decoder()->HasPendingQueries()) {
+ ScheduleDelayedWork();
+ }
+ }
}
sk_sp<SkPromiseImageTexture> SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
@@ -438,6 +933,7 @@ sk_sp<SkPromiseImageTexture> SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
const ResourceFormat resource_format,
std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
if (!*shared_image_out && mailbox_holder.mailbox.IsSharedImage()) {
std::unique_ptr<gpu::SharedImageRepresentationSkia> shared_image =
shared_image_representation_factory_->ProduceSkia(
@@ -447,6 +943,11 @@ sk_sp<SkPromiseImageTexture> SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
"mailbox not found in SharedImageManager.";
return nullptr;
}
+ if (!(shared_image->usage() & gpu::SHARED_IMAGE_USAGE_DISPLAY)) {
+ DLOG(ERROR) << "Failed to fulfill the promise texture - SharedImage "
+ "was not created with display usage.";
+ return nullptr;
+ }
*shared_image_out = std::move(shared_image);
}
if (*shared_image_out) {
@@ -457,15 +958,14 @@ sk_sp<SkPromiseImageTexture> SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
return promise_texture;
}
- if (gpu_service_->is_using_vulkan()) {
+ if (is_using_vulkan()) {
// Probably this texture is created with wrong inteface (GLES2Interface).
DLOG(ERROR) << "Failed to fulfill the promise texture whose backend is not "
"compitable with vulkan.";
return nullptr;
}
- auto* mailbox_manager = gpu_service_->mailbox_manager();
- auto* texture_base = mailbox_manager->ConsumeTexture(mailbox_holder.mailbox);
+ auto* texture_base = mailbox_manager_->ConsumeTexture(mailbox_holder.mailbox);
if (!texture_base) {
DLOG(ERROR) << "Failed to fulfill the promise texture.";
return nullptr;
@@ -488,19 +988,12 @@ sk_sp<SkPromiseImageTexture> SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture(
DCHECK(!*shared_image_out);
auto it = offscreen_surfaces_.find(id);
DCHECK(it != offscreen_surfaces_.end());
- auto& surface = it->second.surface;
- auto& promise_texture = it->second.promise_texture;
+ auto promise_texture = it->second.fulfill();
if (!promise_texture) {
- promise_texture = SkPromiseImageTexture::Make(
- surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
- if (!promise_texture) {
- DLOG(ERROR)
- << "Failed to fulfill the promise texture created from RenderPassId:"
- << id;
- return nullptr;
- }
- } else {
- surface->flush();
+ DLOG(ERROR)
+ << "Failed to fulfill the promise texture created from RenderPassId:"
+ << id;
+ return nullptr;
}
return promise_texture;
}
@@ -513,9 +1006,11 @@ SkiaOutputSurfaceImplOnGpu::GetGrContextThreadSafeProxy() {
void SkiaOutputSurfaceImplOnGpu::DestroySkImages(
std::vector<sk_sp<SkImage>>&& images,
uint64_t sync_fence_release) {
- MakeCurrent();
+ // The window could be destroyed already, and the MakeCurrent will fail with
+ // an destroyed window, so MakeCurrent without requiring the fbo0.
+ MakeCurrent(false /* need_fbo0 */);
images.clear();
- sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
+ ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release);
}
#if defined(OS_WIN)
@@ -566,6 +1061,40 @@ int32_t SkiaOutputSurfaceImplOnGpu::GetRouteID() const {
}
void SkiaOutputSurfaceImplOnGpu::InitializeForGL() {
+ if (!MakeCurrent(true /* need_fbo0 */))
+ return;
+
+ auto* context = context_state_->real_context();
+ auto* current_gl = context->GetCurrentGL();
+ api_ = current_gl->Api;
+ gl_version_info_ = context->GetVersionInfo();
+
+ capabilities_.flipped_output_surface = gl_surface_->FlipsVertically();
+
+ // Get alpha and stencil bits from the default frame buffer.
+ api_->glBindFramebufferEXTFn(GL_FRAMEBUFFER, 0);
+ gr_context()->resetContext(kRenderTarget_GrGLBackendState);
+ const auto* version = current_gl->Version;
+ GLint stencil_bits = 0;
+ GLint alpha_bits = 0;
+ if (version->is_desktop_core_profile) {
+ api_->glGetFramebufferAttachmentParameterivEXTFn(
+ GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
+ &stencil_bits);
+ api_->glGetFramebufferAttachmentParameterivEXTFn(
+ GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
+ &alpha_bits);
+ } else {
+ api_->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
+ api_->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
+ }
+ CHECK_GL_ERROR();
+ capabilities_.supports_stencil = stencil_bits > 0;
+ supports_alpha_ = alpha_bits > 0;
+}
+
+void SkiaOutputSurfaceImplOnGpu::InitializeForGLWithGpuService(
+ GpuServiceImpl* gpu_service) {
if (surface_handle_) {
gl_surface_ = gpu::ImageTransportSurface::CreateNativeSurface(
weak_ptr_factory_.GetWeakPtr(), surface_handle_, gl::GLSurfaceFormat());
@@ -579,41 +1108,20 @@ void SkiaOutputSurfaceImplOnGpu::InitializeForGL() {
}
DCHECK(gl_surface_);
- context_state_ = gpu_service_->GetContextStateForGLSurface(gl_surface_.get());
+ context_state_ = gpu_service->GetContextStateForGLSurface(gl_surface_.get());
if (!context_state_) {
LOG(FATAL) << "Failed to create GrContext";
// TODO(penghuang): handle the failure.
}
-
- if (!MakeCurrent())
- return;
-
- auto* context = context_state_->real_context();
- gl_version_info_ = context->GetVersionInfo();
-
- capabilities_.flipped_output_surface = gl_surface_->FlipsVertically();
-
- // Get stencil bits from the default frame buffer.
- auto* current_gl = context->GetCurrentGL();
- const auto* version = current_gl->Version;
- auto* api = current_gl->Api;
- api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, 0);
- gr_context()->resetContext(kRenderTarget_GrGLBackendState);
- GLint stencil_bits = 0;
- if (version->is_desktop_core_profile) {
- api->glGetFramebufferAttachmentParameterivEXTFn(
- GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
- &stencil_bits);
- } else {
- api->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
- }
- CHECK_GL_ERROR();
- capabilities_.supports_stencil = stencil_bits > 0;
+ InitializeForGL();
}
-void SkiaOutputSurfaceImplOnGpu::InitializeForVulkan() {
- context_state_ = gpu_service_->GetContextStateForVulkan();
+void SkiaOutputSurfaceImplOnGpu::InitializeForVulkan(
+ GpuServiceImpl* gpu_service) {
+ context_state_ = gpu_service->GetContextStateForVulkan();
DCHECK(context_state_);
+ supports_alpha_ = true;
+ capabilities_.flipped_output_surface = true;
}
void SkiaOutputSurfaceImplOnGpu::BindOrCopyTextureIfNecessary(
@@ -631,7 +1139,9 @@ void SkiaOutputSurfaceImplOnGpu::BindOrCopyTextureIfNecessary(
auto* image = texture->GetLevelImage(GL_TEXTURE_2D, 0, &image_state);
if (image && image_state == gpu::gles2::Texture::UNBOUND) {
glBindTexture(texture_base->target(), texture_base->service_id());
- if (image->BindTexImage(texture_base->target())) {
+ if (image->ShouldBindOrCopy() == gl::GLImage::BIND) {
+ if (!image->BindTexImage(texture_base->target()))
+ LOG(ERROR) << "Failed to bind a gl image to texture.";
} else {
texture->SetLevelImageState(texture_base->target(), 0,
gpu::gles2::Texture::COPIED);
@@ -647,45 +1157,35 @@ void SkiaOutputSurfaceImplOnGpu::OnSwapBuffers() {
pending_swap_completed_params_.emplace_back(swap_id, pixel_size);
}
-void SkiaOutputSurfaceImplOnGpu::CreateSkSurfaceForVulkan() {
-#if BUILDFLAG(ENABLE_VULKAN)
- auto* swap_chain = vulkan_surface_->GetSwapChain();
- auto index = swap_chain->current_image();
- auto& sk_surface = sk_surfaces_[index];
- if (!sk_surface) {
- SkSurfaceProps surface_props =
- SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
- VkImage vk_image = swap_chain->GetCurrentImage();
- VkImageLayout vk_image_layout = swap_chain->GetCurrentImageLayout();
- GrVkImageInfo vk_image_info;
- vk_image_info.fImage = vk_image;
- vk_image_info.fAlloc = {VK_NULL_HANDLE, 0, 0, 0};
- vk_image_info.fImageLayout = vk_image_layout;
- vk_image_info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
- vk_image_info.fFormat = VK_FORMAT_B8G8R8A8_UNORM;
- vk_image_info.fLevelCount = 1;
- GrBackendRenderTarget render_target(vulkan_surface_->size().width(),
- vulkan_surface_->size().height(), 0, 0,
- vk_image_info);
- sk_surface = SkSurface::MakeFromBackendRenderTarget(
- gr_context(), render_target, kTopLeft_GrSurfaceOrigin,
- kBGRA_8888_SkColorType, nullptr, &surface_props);
- DCHECK(sk_surface);
- } else {
- auto backend = sk_surface->getBackendRenderTarget(
- SkSurface::kFlushRead_BackendHandleAccess);
- backend.setVkImageLayout(swap_chain->GetCurrentImageLayout());
- }
-
- sk_surface_ = sk_surface;
-#endif
+void SkiaOutputSurfaceImplOnGpu::CreateSkSurfaceForGL() {
+ SkSurfaceProps surface_props =
+ SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
+
+ GrGLFramebufferInfo framebuffer_info;
+ framebuffer_info.fFBOID = gl_surface_->GetBackingFramebufferObject();
+ framebuffer_info.fFormat = supports_alpha_ ? GL_RGBA8 : GL_RGB8_OES;
+ GrBackendRenderTarget render_target(size_.width(), size_.height(), 0, 8,
+ framebuffer_info);
+ auto origin = capabilities_.flipped_output_surface
+ ? kTopLeft_GrSurfaceOrigin
+ : kBottomLeft_GrSurfaceOrigin;
+ auto color_type =
+ supports_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType;
+ sk_surface_ = SkSurface::MakeFromBackendRenderTarget(
+ gr_context(), render_target, origin, color_type,
+ color_space_.ToSkColorSpace(), &surface_props);
+ DCHECK(sk_surface_);
}
-bool SkiaOutputSurfaceImplOnGpu::MakeCurrent() {
- if (!gpu_service_->is_using_vulkan()) {
- if (!context_state_->MakeCurrent(gl_surface_.get())) {
+bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) {
+ if (!is_using_vulkan()) {
+ // Only make current with |gl_surface_|, if following operations will use
+ // fbo0.
+ if (!context_state_->MakeCurrent(need_fbo0 ? gl_surface_.get() : nullptr)) {
LOG(ERROR) << "Failed to make current.";
context_lost_callback_.Run();
+ if (context_provider_)
+ context_provider_->MarkContextLost();
return false;
}
context_state_->set_need_context_state_reset(true);
@@ -693,4 +1193,37 @@ bool SkiaOutputSurfaceImplOnGpu::MakeCurrent() {
return true;
}
+void SkiaOutputSurfaceImplOnGpu::PullTextureUpdates(
+ std::vector<gpu::SyncToken> sync_tokens) {
+ // TODO(https://crbug.com/900973): Remove it when MailboxManager is replaced
+ // with SharedImage API.
+ if (mailbox_manager_->UsesSync()) {
+ for (auto& sync_token : sync_tokens)
+ mailbox_manager_->PullTextureUpdates(sync_token);
+ }
+}
+
+void SkiaOutputSurfaceImplOnGpu::ReleaseFenceSyncAndPushTextureUpdates(
+ uint64_t sync_fence_release) {
+ // TODO(https://crbug.com/900973): Remove it when MailboxManager is replaced
+ // with SharedImage API.
+ if (mailbox_manager_->UsesSync()) {
+ // If MailboxManagerSync is used, we are sharing textures between threads.
+ // In this case, sync point can only guarantee GL commands are issued in
+ // correct order across threads and GL contexts. However GPU driver may
+ // execute GL commands out of the issuing order across GL contexts. So we
+ // have to use PushTextureUpdates() and PullTextureUpdates() to ensure the
+ // correct GL commands executing order.
+ // PushTextureUpdates(token) will insert a GL fence into the current GL
+ // context, PullTextureUpdates(token) will wait the GL fence associated with
+ // the give token on the current GL context.
+ // Reconstruct sync_token from sync_fence_release.
+ gpu::SyncToken sync_token(
+ gpu::CommandBufferNamespace::VIZ_SKIA_OUTPUT_SURFACE,
+ command_buffer_id(), sync_fence_release);
+ mailbox_manager_->PushTextureUpdates(sync_token);
+ }
+ sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
+}
+
} // namespace viz
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 672a4c67f99..0f44d5dbead 100644
--- a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -19,6 +19,7 @@
#include "components/viz/service/display/resource_metadata.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/command_buffer/service/shared_context_state.h"
+#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/ipc/common/surface_handle.h"
#include "gpu/ipc/in_process_command_buffer.h"
#include "gpu/ipc/service/image_transport_surface_delegate.h"
@@ -37,16 +38,14 @@ class ColorSpace;
}
namespace gl {
+class GLApi;
class GLSurface;
}
namespace gpu {
+class CommandBufferTaskExecutor;
class SyncPointClientState;
class SharedImageRepresentationSkia;
-
-#if BUILDFLAG(ENABLE_VULKAN)
-class VulkanSurface;
-#endif
}
namespace ui {
@@ -57,7 +56,15 @@ class PlatformWindowSurface;
namespace viz {
+class DirectContextProvider;
+class GLRendererCopier;
class GpuServiceImpl;
+class TextureDeleter;
+class VulkanContextProvider;
+
+namespace copy_output {
+struct RenderPassGeometry;
+} // namespace copy_output
// The SkiaOutputSurface implementation running on the GPU thread. This class
// should be created, used and destroyed on the GPU thread.
@@ -69,15 +76,38 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
using BufferPresentedCallback =
base::RepeatingCallback<void(const gfx::PresentationFeedback& feedback)>;
using ContextLostCallback = base::RepeatingCallback<void()>;
+
+ SkiaOutputSurfaceImplOnGpu(
+ gpu::SurfaceHandle surface_handle,
+ scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
+ gpu::MailboxManager* mailbox_manager,
+ scoped_refptr<gpu::SyncPointClientState> sync_point_client_data,
+ std::unique_ptr<gpu::SharedImageRepresentationFactory> sir_factory,
+ gpu::raster::GrShaderCache* gr_shader_cache,
+ VulkanContextProvider* vulkan_context_provider,
+ const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
+ const BufferPresentedCallback& buffer_presented_callback,
+ const ContextLostCallback& context_lost_callback);
SkiaOutputSurfaceImplOnGpu(
GpuServiceImpl* gpu_service,
gpu::SurfaceHandle surface_handle,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
const BufferPresentedCallback& buffer_presented_callback,
const ContextLostCallback& context_lost_callback);
+ SkiaOutputSurfaceImplOnGpu(
+ gpu::CommandBufferTaskExecutor* task_executor,
+ scoped_refptr<gl::GLSurface> gl_surface,
+ scoped_refptr<gpu::SharedContextState> shared_context_state,
+ gpu::SequenceId sequence_id,
+ const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
+ const BufferPresentedCallback& buffer_presented_callback,
+ const ContextLostCallback& context_lost_callback);
+
~SkiaOutputSurfaceImplOnGpu() override;
- gpu::CommandBufferId command_buffer_id() const { return command_buffer_id_; }
+ gpu::CommandBufferId command_buffer_id() const {
+ return sync_point_client_state_->command_buffer_id();
+ }
const OutputSurface::Capabilities capabilities() const {
return capabilities_;
}
@@ -95,17 +125,17 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
void FinishPaintCurrentFrame(
std::unique_ptr<SkDeferredDisplayList> ddl,
std::unique_ptr<SkDeferredDisplayList> overdraw_ddl,
+ std::vector<gpu::SyncToken> sync_tokens,
uint64_t sync_fence_release);
void SwapBuffers(OutputSurfaceFrame frame);
- void FinishPaintRenderPass(
- RenderPassId id,
- std::unique_ptr<SkDeferredDisplayList> ddl,
- uint64_t sync_fence_release);
+ void FinishPaintRenderPass(RenderPassId id,
+ std::unique_ptr<SkDeferredDisplayList> ddl,
+ std::vector<gpu::SyncToken> sync_tokens,
+ uint64_t sync_fence_release);
void RemoveRenderPassResource(std::vector<RenderPassId> ids);
void CopyOutput(RenderPassId id,
- const gfx::Rect& copy_rect,
+ const copy_output::RenderPassGeometry& geometry,
const gfx::ColorSpace& color_space,
- const gfx::Rect& result_rect,
std::unique_ptr<CopyOutputRequest> request);
// Fulfill callback for promise SkImage created from a resource.
@@ -127,6 +157,11 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
void DestroySkImages(std::vector<sk_sp<SkImage>>&& images,
uint64_t sync_fence_release);
+ bool was_context_lost() { return context_state_->context_lost(); }
+
+ class ScopedUseContextProvider;
+ class SurfaceWrapper;
+
private:
// gpu::ImageTransportSurfaceDelegate implementation:
#if defined(OS_WIN)
@@ -142,24 +177,43 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
int32_t GetRouteID() const override;
void InitializeForGL();
- void InitializeForVulkan();
+ void InitializeForGLWithGpuService(GpuServiceImpl* gpu_service);
+ void InitializeForGLWithTaskExecutor(
+ gpu::CommandBufferTaskExecutor* task_executor,
+ scoped_refptr<gl::GLSurface> gl_surface);
+ void InitializeForVulkan(GpuServiceImpl* gpu_service);
void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base);
// Generage the next swap ID and push it to our pending swap ID queues.
void OnSwapBuffers();
- void CreateSkSurfaceForVulkan();
+ void CreateSkSurfaceForGL();
// Make context current for GL, and return false if the context is lost.
// It will do nothing when Vulkan is used.
- bool MakeCurrent();
+ bool MakeCurrent(bool need_fbo0);
+
+ void PullTextureUpdates(std::vector<gpu::SyncToken> sync_token);
+
+ void ReleaseFenceSyncAndPushTextureUpdates(uint64_t sync_fence_release);
GrContext* gr_context() { return context_state_->gr_context(); }
+ gpu::DecoderContext* decoder();
+
+ void ScheduleDelayedWork();
+ void PerformDelayedWork();
+
+ bool is_using_vulkan() const { return !!vulkan_context_provider_; }
- const gpu::CommandBufferId command_buffer_id_;
- GpuServiceImpl* const gpu_service_;
const gpu::SurfaceHandle surface_handle_;
+ scoped_refptr<gpu::gles2::FeatureInfo> feature_info_;
+ gpu::MailboxManager* const mailbox_manager_;
+ scoped_refptr<gpu::SyncPointClientState> sync_point_client_state_;
+ std::unique_ptr<gpu::SharedImageRepresentationFactory>
+ shared_image_representation_factory_;
+ gpu::raster::GrShaderCache* const gr_shader_cache_;
+ VulkanContextProvider* const vulkan_context_provider_;
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_;
BufferPresentedCallback buffer_presented_callback_;
ContextLostCallback context_lost_callback_;
@@ -169,35 +223,35 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
std::unique_ptr<ui::PlatformWindowSurface> window_surface_;
#endif
- scoped_refptr<gpu::SyncPointClientState> sync_point_client_state_;
gpu::GpuPreferences gpu_preferences_;
+ gfx::Size size_;
+ gfx::ColorSpace color_space_;
scoped_refptr<gl::GLSurface> gl_surface_;
sk_sp<SkSurface> sk_surface_;
scoped_refptr<gpu::SharedContextState> context_state_;
const gl::GLVersionInfo* gl_version_info_ = nullptr;
OutputSurface::Capabilities capabilities_;
- std::unique_ptr<gpu::SharedImageRepresentationFactory>
- shared_image_representation_factory_;
- scoped_refptr<gpu::gles2::FeatureInfo> feature_info_;
-#if BUILDFLAG(ENABLE_VULKAN)
- std::unique_ptr<gpu::VulkanSurface> vulkan_surface_;
-
- // surfaces for swap chain images.
- std::vector<sk_sp<SkSurface>> sk_surfaces_;
-#endif
+ std::unique_ptr<SurfaceWrapper> vulkan_surface_;
// Offscreen surfaces for render passes. It can only be accessed on GPU
// thread.
- struct OffscreenSurface {
+ class OffscreenSurface {
+ public:
OffscreenSurface();
- OffscreenSurface(const OffscreenSurface& offscreen_surface);
+ OffscreenSurface(const OffscreenSurface& offscreen_surface) = delete;
OffscreenSurface(OffscreenSurface&& offscreen_surface);
- OffscreenSurface& operator=(const OffscreenSurface& offscreen_surface);
+ OffscreenSurface& operator=(const OffscreenSurface& offscreen_surface) =
+ delete;
OffscreenSurface& operator=(OffscreenSurface&& offscreen_surface);
~OffscreenSurface();
- sk_sp<SkSurface> surface;
- sk_sp<SkPromiseImageTexture> promise_texture;
+ SkSurface* surface() const;
+ sk_sp<SkPromiseImageTexture> fulfill();
+ void set_surface(sk_sp<SkSurface> surface);
+
+ private:
+ sk_sp<SkSurface> surface_;
+ sk_sp<SkPromiseImageTexture> promise_texture_;
};
base::flat_map<RenderPassId, OffscreenSurface> offscreen_surfaces_;
@@ -209,6 +263,16 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
ui::LatencyTracker latency_tracker_;
+ scoped_refptr<base::SingleThreadTaskRunner> context_current_task_runner_;
+ scoped_refptr<DirectContextProvider> context_provider_;
+ std::unique_ptr<TextureDeleter> texture_deleter_;
+ std::unique_ptr<GLRendererCopier> copier_;
+
+ bool delayed_work_pending_ = false;
+
+ gl::GLApi* api_ = nullptr;
+ bool supports_alpha_ = false;
+
THREAD_CHECKER(thread_checker_);
base::WeakPtr<SkiaOutputSurfaceImplOnGpu> weak_ptr_;
diff --git a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
index 543aa473177..a85a117585a 100644
--- a/chromium/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
+++ b/chromium/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
@@ -9,20 +9,31 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
#include "base/test/scoped_feature_list.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/pixel_test_utils.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "gpu/command_buffer/service/scheduler.h"
+#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/ipc/gpu_in_process_thread_service.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
+#include "gpu/vulkan/buildflags.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/init/gl_factory.h"
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "gpu/vulkan/init/vulkan_factory.h"
+#include "gpu/vulkan/vulkan_implementation.h"
+#endif
+
namespace viz {
static void ExpectEquals(SkBitmap actual, SkBitmap expected) {
@@ -49,6 +60,13 @@ class SkiaOutputSurfaceImplTest : public testing::Test {
void TearDown() override;
void BlockMainThread();
void UnblockMainThread();
+ bool is_vulkan_enabled() {
+#if BUILDFLAG(ENABLE_VULKAN)
+ return !!vulkan_implementation_;
+#else
+ return false;
+#endif
+ }
std::unique_ptr<base::Thread> gpu_thread_;
std::unique_ptr<SkiaOutputSurfaceImpl> output_surface_;
@@ -59,6 +77,10 @@ class SkiaOutputSurfaceImplTest : public testing::Test {
void TearDownGpuServiceOnGpuThread();
void SetUpGpuServiceOnGpuThread();
+#if BUILDFLAG(ENABLE_VULKAN)
+ std::unique_ptr<gpu::VulkanImplementation> vulkan_implementation_;
+#endif
+
std::unique_ptr<base::Thread> io_thread_;
scoped_refptr<gpu::CommandBufferTaskExecutor> task_executor_;
std::unique_ptr<cc::FakeOutputSurfaceClient> output_surface_client_;
@@ -77,12 +99,31 @@ void SkiaOutputSurfaceImplTest::UnblockMainThread() {
void SkiaOutputSurfaceImplTest::SetUpGpuServiceOnGpuThread() {
ASSERT_TRUE(gpu_thread_->task_runner()->BelongsToCurrentThread());
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+ gpu::GpuPreferences gpu_preferences =
+ gpu::gles2::ParseGpuPreferences(command_line);
+ if (gpu_preferences.enable_vulkan) {
+#if BUILDFLAG(ENABLE_VULKAN)
+ vulkan_implementation_ = gpu::CreateVulkanImplementation();
+ if (!vulkan_implementation_ ||
+ !vulkan_implementation_->InitializeVulkanInstance()) {
+ LOG(FATAL) << "Failed to create and initialize Vulkan implementation.";
+ }
+#else
+ NOTREACHED();
+#endif
+ }
gpu_service_ = std::make_unique<GpuServiceImpl>(
gpu::GPUInfo(), nullptr /* watchdog_thread */, io_thread_->task_runner(),
- gpu::GpuFeatureInfo(), gpu::GpuPreferences(),
+ gpu::GpuFeatureInfo(), gpu_preferences,
gpu::GPUInfo() /* gpu_info_for_hardware_gpu */,
gpu::GpuFeatureInfo() /* gpu_feature_info_for_hardware_gpu */,
+#if BUILDFLAG(ENABLE_VULKAN)
+ vulkan_implementation_.get(),
+#else
nullptr /* vulkan_implementation */,
+#endif
base::DoNothing() /* exit_callback */);
// Uses a null gpu_host here, because we don't want to receive any message.
@@ -93,7 +134,8 @@ void SkiaOutputSurfaceImplTest::SetUpGpuServiceOnGpuThread() {
gpu_service_->InitializeWithHost(
std::move(gpu_host_proxy), gpu::GpuProcessActivityFlags(),
gl::init::CreateOffscreenGLSurface(gfx::Size()),
- nullptr /* sync_point_manager */, nullptr /* shutdown_event */);
+ nullptr /* sync_point_manager */, nullptr /* shared_image_manager */,
+ nullptr /* shutdown_event */);
task_executor_ = base::MakeRefCounted<gpu::GpuInProcessThreadService>(
gpu_thread_->task_runner(), gpu_service_->scheduler(),
gpu_service_->sync_point_manager(), gpu_service_->mailbox_manager(),
@@ -189,7 +231,8 @@ void SkiaOutputSurfaceImplTest::CopyRequestCallbackOnGpuThread(
}
TEST_F(SkiaOutputSurfaceImplTest, SubmitPaint) {
- output_surface_->Reshape(gfx::Size(100.0, 100.0), 1, gfx::ColorSpace(), true,
+ const gfx::Rect surface_rect(0, 0, 100, 100);
+ output_surface_->Reshape(surface_rect.size(), 1, gfx::ColorSpace(), true,
false);
SkCanvas* root_canvas = output_surface_->BeginPaintCurrentFrame();
SkPaint paint;
@@ -220,9 +263,24 @@ TEST_F(SkiaOutputSurfaceImplTest, SubmitPaint) {
base::Unretained(this), output_color, output_rect,
color_space));
request->set_result_task_runner(gpu_thread_->task_runner());
- gfx::Rect result_rect = output_rect;
- output_surface_->CopyOutput(0, output_rect, color_space, result_rect,
- std::move(request));
+ copy_output::RenderPassGeometry geometry;
+ geometry.result_bounds = surface_rect;
+ geometry.result_selection = output_rect;
+ geometry.sampling_bounds = surface_rect;
+
+ if (is_vulkan_enabled()) {
+ // No flipping because Skia handles all co-ordinate transformation on the
+ // software readback path currently implemented for Vulkan.
+ geometry.readback_offset = geometry.readback_offset = gfx::Vector2d(0, 0);
+ } else {
+ // GLRendererCopier may need a vertical flip depending on output surface
+ // characteristics.
+ geometry.readback_offset =
+ output_surface_->capabilities().flipped_output_surface
+ ? geometry.readback_offset = gfx::Vector2d(0, 0)
+ : geometry.readback_offset = gfx::Vector2d(0, 90);
+ }
+ output_surface_->CopyOutput(0, geometry, color_space, std::move(request));
BlockMainThread();
}
diff --git a/chromium/components/viz/service/display_embedder/software_output_device_win.cc b/chromium/components/viz/service/display_embedder/software_output_device_win.cc
index 740d4edb3ce..a339eaa4dc9 100644
--- a/chromium/components/viz/service/display_embedder/software_output_device_win.cc
+++ b/chromium/components/viz/service/display_embedder/software_output_device_win.cc
@@ -4,6 +4,7 @@
#include "components/viz/service/display_embedder/software_output_device_win.h"
+#include "base/bind.h"
#include "base/memory/shared_memory.h"
#include "base/threading/thread_checker.h"
#include "base/win/windows_version.h"
@@ -18,6 +19,7 @@
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/win/hwnd_util.h"
+#include "ui/gl/vsync_provider_win.h"
namespace viz {
namespace {
@@ -25,7 +27,10 @@ namespace {
// Shared base class for Windows SoftwareOutputDevice implementations.
class SoftwareOutputDeviceWinBase : public SoftwareOutputDevice {
public:
- explicit SoftwareOutputDeviceWinBase(HWND hwnd) : hwnd_(hwnd) {}
+ explicit SoftwareOutputDeviceWinBase(HWND hwnd) : hwnd_(hwnd) {
+ vsync_provider_ = std::make_unique<gl::VSyncProviderWin>(hwnd);
+ }
+
~SoftwareOutputDeviceWinBase() override {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!in_paint_);
diff --git a/chromium/components/viz/service/display_embedder/software_output_surface.cc b/chromium/components/viz/service/display_embedder/software_output_surface.cc
index e48ab5455aa..5c1c96ffe30 100644
--- a/chromium/components/viz/service/display_embedder/software_output_surface.cc
+++ b/chromium/components/viz/service/display_embedder/software_output_surface.cc
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "build/build_config.h"
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/service/display/output_surface_client.h"
#include "components/viz/service/display/output_surface_frame.h"
#include "components/viz/service/display/software_output_device.h"
@@ -21,8 +22,11 @@
namespace viz {
SoftwareOutputSurface::SoftwareOutputSurface(
- std::unique_ptr<SoftwareOutputDevice> software_device)
- : OutputSurface(std::move(software_device)), weak_factory_(this) {}
+ std::unique_ptr<SoftwareOutputDevice> software_device,
+ SyntheticBeginFrameSource* synthetic_begin_frame_source)
+ : OutputSurface(std::move(software_device)),
+ synthetic_begin_frame_source_(synthetic_begin_frame_source),
+ weak_factory_(this) {}
SoftwareOutputSurface::~SoftwareOutputSurface() = default;
@@ -45,9 +49,7 @@ void SoftwareOutputSurface::BindFramebuffer() {
NOTREACHED();
}
-void SoftwareOutputSurface::SetDrawRectangle(const gfx::Rect& draw_rectangle) {
- NOTREACHED();
-}
+void SoftwareOutputSurface::SetDrawRectangle(const gfx::Rect& draw_rectangle) {}
void SoftwareOutputSurface::Reshape(const gfx::Size& size,
float device_scale_factor,
@@ -72,14 +74,15 @@ void SoftwareOutputSurface::SwapBuffers(OutputSurfaceFrame frame) {
<< "arrive before the previous latency info is processed.";
stored_latency_info_ = std::move(frame.latency_info);
- // TODO(danakj): Update vsync params.
- // gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider();
- // if (vsync_provider)
- // vsync_provider->GetVSyncParameters(update_vsync_parameters_callback_);
- // Update refresh_interval_ as well.
-
software_device()->OnSwapBuffers(base::BindOnce(
&SoftwareOutputSurface::SwapBuffersCallback, weak_factory_.GetWeakPtr()));
+
+ gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider();
+ if (vsync_provider && synthetic_begin_frame_source_) {
+ vsync_provider->GetVSyncParameters(
+ base::BindOnce(&SoftwareOutputSurface::UpdateVSyncParametersCallback,
+ weak_factory_.GetWeakPtr()));
+ }
}
bool SoftwareOutputSurface::IsDisplayedAsOverlayPlane() const {
@@ -117,16 +120,23 @@ void SoftwareOutputSurface::SwapBuffersCallback() {
client_->DidFinishLatencyInfo(stored_latency_info_);
std::vector<ui::LatencyInfo>().swap(stored_latency_info_);
client_->DidReceiveSwapBuffersAck();
+
+ base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeDelta interval_to_next_refresh =
+ now.SnappedToNextTick(refresh_timebase_, refresh_interval_) - now;
+
client_->DidReceivePresentationFeedback(
- gfx::PresentationFeedback(base::TimeTicks::Now(), refresh_interval_, 0u));
+ gfx::PresentationFeedback(now, interval_to_next_refresh, 0u));
}
-#if BUILDFLAG(ENABLE_VULKAN)
-gpu::VulkanSurface* SoftwareOutputSurface::GetVulkanSurface() {
- NOTIMPLEMENTED();
- return nullptr;
+void SoftwareOutputSurface::UpdateVSyncParametersCallback(
+ base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ DCHECK(synthetic_begin_frame_source_);
+ refresh_timebase_ = timebase;
+ refresh_interval_ = interval;
+ synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval);
}
-#endif
unsigned SoftwareOutputSurface::UpdateGpuFence() {
return 0;
diff --git a/chromium/components/viz/service/display_embedder/software_output_surface.h b/chromium/components/viz/service/display_embedder/software_output_surface.h
index c371a84695a..f7111f1d2e1 100644
--- a/chromium/components/viz/service/display_embedder/software_output_surface.h
+++ b/chromium/components/viz/service/display_embedder/software_output_surface.h
@@ -6,6 +6,7 @@
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_SURFACE_H_
#include "base/memory/weak_ptr.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/service/display/output_surface.h"
#include "components/viz/service/viz_service_export.h"
#include "ui/latency/latency_info.h"
@@ -13,11 +14,13 @@
namespace viz {
class SoftwareOutputDevice;
+class SyntheticBeginFrameSource;
class VIZ_SERVICE_EXPORT SoftwareOutputSurface : public OutputSurface {
public:
- explicit SoftwareOutputSurface(
- std::unique_ptr<SoftwareOutputDevice> software_device);
+ SoftwareOutputSurface(
+ std::unique_ptr<SoftwareOutputDevice> software_device,
+ SyntheticBeginFrameSource* synthetic_begin_frame_source);
~SoftwareOutputSurface() override;
// OutputSurface implementation.
@@ -39,18 +42,22 @@ class VIZ_SERVICE_EXPORT SoftwareOutputSurface : public OutputSurface {
bool HasExternalStencilTest() const override;
void ApplyExternalStencil() override;
uint32_t GetFramebufferCopyTextureFormat() override;
-#if BUILDFLAG(ENABLE_VULKAN)
- gpu::VulkanSurface* GetVulkanSurface() override;
-#endif
unsigned UpdateGpuFence() override;
private:
void SwapBuffersCallback();
+ void UpdateVSyncParametersCallback(base::TimeTicks timebase,
+ base::TimeDelta interval);
OutputSurfaceClient* client_ = nullptr;
- base::TimeDelta refresh_interval_;
+
+ SyntheticBeginFrameSource* const synthetic_begin_frame_source_;
+ base::TimeTicks refresh_timebase_;
+ base::TimeDelta refresh_interval_ = BeginFrameArgs::DefaultInterval();
+
std::vector<ui::LatencyInfo> stored_latency_info_;
ui::LatencyTracker latency_tracker_;
+
base::WeakPtrFactory<SoftwareOutputSurface> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SoftwareOutputSurface);
diff --git a/chromium/components/viz/service/display_embedder/viz_process_context_provider.cc b/chromium/components/viz/service/display_embedder/viz_process_context_provider.cc
index 9ba70c004a4..353bfb63618 100644
--- a/chromium/components/viz/service/display_embedder/viz_process_context_provider.cc
+++ b/chromium/components/viz/service/display_embedder/viz_process_context_provider.cc
@@ -8,6 +8,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -19,6 +20,7 @@
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/gpu/context_lost_reason.h"
#include "components/viz/common/resources/platform_color.h"
+#include "components/viz/common/viz_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
@@ -42,7 +44,7 @@ namespace {
gpu::ContextCreationAttribs CreateAttributes(
bool requires_alpha_channel,
- const gfx::ColorSpace& color_space) {
+ const RendererSettings& renderer_settings) {
gpu::ContextCreationAttribs attributes;
attributes.alpha_size = requires_alpha_channel ? 8 : -1;
attributes.depth_size = 0;
@@ -63,17 +65,17 @@ gpu::ContextCreationAttribs CreateAttributes(
attributes.lose_context_when_out_of_memory = true;
#if defined(OS_ANDROID)
- if (color_space == gfx::ColorSpace::CreateSRGB()) {
+ if (renderer_settings.color_space == gfx::ColorSpace::CreateSRGB()) {
attributes.color_space = gpu::COLOR_SPACE_SRGB;
- } else if (color_space == gfx::ColorSpace::CreateDisplayP3D65()) {
+ } else if (renderer_settings.color_space ==
+ gfx::ColorSpace::CreateDisplayP3D65()) {
attributes.color_space = gpu::COLOR_SPACE_DISPLAY_P3;
} else {
// The browser only sends the above two color spaces.
NOTREACHED();
}
- if (!requires_alpha_channel &&
- base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) {
+ if (!requires_alpha_channel && PreferRGB565ResourcesForDisplay()) {
// See compositor_impl_android.cc for more information about this.
// It is inside GetCompositorContextAttributes().
attributes.alpha_size = 0;
@@ -83,6 +85,8 @@ gpu::ContextCreationAttribs CreateAttributes(
}
attributes.enable_swap_timestamps_if_supported = true;
+ attributes.backed_by_surface_texture =
+ renderer_settings.backed_by_surface_texture;
#endif // defined(OS_ANDROID)
return attributes;
@@ -92,15 +96,6 @@ void UmaRecordContextLost(ContextLostReason reason) {
UMA_HISTOGRAM_ENUMERATION("GPU.ContextLost.DisplayCompositor", reason);
}
-gfx::ColorSpace ColorSpaceForRendererSettings(
- const RendererSettings& renderer_settings) {
-#if defined(OS_ANDROID)
- return renderer_settings.color_space;
-#else
- return gfx::ColorSpace();
-#endif
-}
-
gpu::SharedMemoryLimits SharedMemoryLimitsForRendererSettings(
const RendererSettings& renderer_settings) {
#if defined(OS_ANDROID)
@@ -120,9 +115,8 @@ VizProcessContextProvider::VizProcessContextProvider(
gpu::ImageFactory* image_factory,
gpu::GpuChannelManagerDelegate* gpu_channel_manager_delegate,
const RendererSettings& renderer_settings)
- : attributes_(
- CreateAttributes(renderer_settings.requires_alpha_channel,
- ColorSpaceForRendererSettings(renderer_settings))) {
+ : attributes_(CreateAttributes(renderer_settings.requires_alpha_channel,
+ renderer_settings)) {
InitializeContext(std::move(task_executor), surface_handle,
gpu_memory_buffer_manager, image_factory,
gpu_channel_manager_delegate,
diff --git a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
index 9d5e5883376..c9d62355461 100644
--- a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
+++ b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
namespace viz {
diff --git a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
index a469d9e14df..58e78127982 100644
--- a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
+++ b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <utility>
+#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/time/time.h"
@@ -75,6 +76,13 @@ CompositorFrameSinkSupport::~CompositorFrameSinkSupport() {
DCHECK(!added_frame_observer_);
}
+CompositorFrameSinkSupport::PresentationFeedbackMap
+CompositorFrameSinkSupport::TakePresentationFeedbacks() {
+ PresentationFeedbackMap map;
+ map.swap(presentation_feedbacks_);
+ return map;
+}
+
void CompositorFrameSinkSupport::SetUpHitTest(
LatestLocalSurfaceIdLookupDelegate* local_surface_id_lookup_delegate) {
DCHECK(is_root_);
@@ -142,6 +150,10 @@ void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) {
MaybeEvictSurfaces();
}
+void CompositorFrameSinkSupport::OnSurfaceDrawn(Surface* surface) {
+ last_drawn_frame_index_ = surface->GetActiveFrameIndex();
+}
+
void CompositorFrameSinkSupport::OnFrameTokenChanged(uint32_t frame_token) {
frame_sink_manager_->OnFrameTokenChanged(frame_sink_id_, frame_token);
}
@@ -275,6 +287,10 @@ bool CompositorFrameSinkSupport::WantsAnimateOnlyBeginFrames() const {
return wants_animate_only_begin_frames_;
}
+bool CompositorFrameSinkSupport::IsRoot() const {
+ return is_root_;
+}
+
void CompositorFrameSinkSupport::DidNotProduceFrame(const BeginFrameAck& ack) {
TRACE_EVENT2("viz", "CompositorFrameSinkSupport::DidNotProduceFrame",
"ack.source_id", ack.source_id, "ack.sequence_number",
@@ -463,13 +479,12 @@ SubmitResult CompositorFrameSinkSupport::MaybeSubmitCompositorFrameInternal(
return SubmitResult::ACCEPTED;
}
current_surface = CreateSurface(surface_info, block_activation_on_parent);
- last_created_surface_id_ = SurfaceId(frame_sink_id_, local_surface_id);
-
if (!current_surface) {
TRACE_EVENT_INSTANT0("viz", "Surface Invariants Violation",
TRACE_EVENT_SCOPE_THREAD);
return SubmitResult::SURFACE_INVARIANTS_VIOLATION;
}
+ last_created_surface_id_ = SurfaceId(frame_sink_id_, local_surface_id);
surface_manager_->SurfaceDamageExpected(current_surface->surface_id(),
last_begin_frame_args_);
@@ -752,12 +767,30 @@ bool CompositorFrameSinkSupport::ShouldSendBeginFrame(
if (!surface || !surface->seen_first_surface_embedding())
return true;
- // Send begin-frames if the client has requested for it, and the previously
- // submitted frame has already been drawn, or if the previous begin-frame was
- // sent more than 1 second ago.
+ // If the embedded surface doesn't have an active frame, send begin frame.
+ if (!surface->HasActiveFrame())
+ return true;
+
+ uint64_t active_frame_index = surface->GetActiveFrameIndex();
+
+ // Since we have an active frame, and frame indexes strictly increase during
+ // the lifetime of the CompositorFrameSinkSupport, our active frame index
+ // must be at least as large as our last drawn frame index.
+ DCHECK_GE(active_frame_index, last_drawn_frame_index_);
+
+ // Determine the number of undrawn frames. If this is below our limit, send
+ // begin frame. Limit must be at least 1, as the relative ordering of
+ // renderer / browser frame submissions allows us to have one outstanding
+ // undrawn frame under normal operation.
+ constexpr uint64_t undrawn_frame_limit = 1;
+ uint64_t num_undrawn_frames = active_frame_index - last_drawn_frame_index_;
+ if (num_undrawn_frames <= undrawn_frame_limit)
+ return true;
+
+ // Send begin-frames if the previous begin-frame was sent more than 1 second
+ // ago.
constexpr base::TimeDelta throttled_rate = base::TimeDelta::FromSeconds(1);
- return !surface->HasUndrawnActiveFrame() ||
- (frame_time - last_frame_time_) >= throttled_rate;
+ return (frame_time - last_frame_time_) >= throttled_rate;
}
} // namespace viz
diff --git a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.h
index 26af0a7b95b..174bd709d5e 100644
--- a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.h
+++ b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -56,6 +56,8 @@ class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
const gfx::Size& frame_size_in_pixels,
const gfx::Rect& damage_rect,
base::TimeTicks expected_display_time)>;
+ using PresentationFeedbackMap =
+ base::flat_map<uint32_t, gfx::PresentationFeedback>;
static const uint64_t kFrameIndexStart = 2;
@@ -80,11 +82,12 @@ class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
FrameSinkManagerImpl* frame_sink_manager() { return frame_sink_manager_; }
- const base::flat_map<uint32_t, gfx::PresentationFeedback>&
- presentation_feedbacks() {
+ const PresentationFeedbackMap& presentation_feedbacks() {
return presentation_feedbacks_;
}
+ PresentationFeedbackMap TakePresentationFeedbacks() WARN_UNUSED_RESULT;
+
// Viz hit-test setup is only called when |is_root_| is true (except on
// android webview).
void SetUpHitTest(
@@ -100,6 +103,7 @@ class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
// SurfaceClient implementation.
void OnSurfaceActivated(Surface* surface) override;
void OnSurfaceDiscarded(Surface* surface) override;
+ void OnSurfaceDrawn(Surface* surface) override;
void RefResources(
const std::vector<TransferableResource>& resources) override;
void UnrefResources(const std::vector<ReturnedResource>& resources) override;
@@ -210,6 +214,7 @@ class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
bool WantsAnimateOnlyBeginFrames() const override;
+ bool IsRoot() const override;
void UpdateNeedsBeginFramesInternal();
Surface* CreateSurface(const SurfaceInfo& surface_info,
@@ -304,11 +309,17 @@ class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
bool callback_received_receive_ack_ = true;
uint32_t trace_sequence_ = 0;
- base::flat_map<uint32_t, gfx::PresentationFeedback> presentation_feedbacks_;
+ PresentationFeedbackMap presentation_feedbacks_;
uint32_t last_evicted_parent_sequence_number_ = 0;
base::TimeTicks last_frame_time_;
+ // Initialize |last_drawn_frame_index_| as though the frame before the first
+ // has been drawn.
+ static_assert(kFrameIndexStart > 1,
+ "|last_drawn_frame_index| relies on kFrameIndexStart > 1");
+ uint64_t last_drawn_frame_index_ = kFrameIndexStart - 1;
+
base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport);
diff --git a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
index 1c911650c8f..cd2618ab650 100644
--- a/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -4,6 +4,7 @@
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "base/bind.h"
#include "base/stl_util.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
@@ -41,7 +42,8 @@ constexpr bool kNeedsSyncPoints = true;
constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
constexpr FrameSinkId kAnotherArbitraryFrameSinkId(2, 2);
-const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
+const base::UnguessableToken kArbitraryToken =
+ base::UnguessableToken::Deserialize(1, 2);
const base::UnguessableToken kArbitrarySourceId1 =
base::UnguessableToken::Deserialize(0xdead, 0xbeef);
const base::UnguessableToken kArbitrarySourceId2 =
@@ -578,12 +580,13 @@ TEST_F(CompositorFrameSinkSupportTest, MonotonicallyIncreasingLocalSurfaceIds) {
auto support = std::make_unique<CompositorFrameSinkSupport>(
&mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
kNeedsSyncPoints);
- LocalSurfaceId local_surface_id1(6, 1, kArbitraryToken);
- LocalSurfaceId local_surface_id2(6, 2, kArbitraryToken);
- LocalSurfaceId local_surface_id3(7, 2, kArbitraryToken);
- LocalSurfaceId local_surface_id4(5, 3, kArbitraryToken);
- LocalSurfaceId local_surface_id5(8, 1, kArbitraryToken);
- LocalSurfaceId local_surface_id6(9, 3, kArbitraryToken);
+ base::UnguessableToken embed_token = base::UnguessableToken::Create();
+ LocalSurfaceId local_surface_id1(6, 1, embed_token);
+ LocalSurfaceId local_surface_id2(6, 2, embed_token);
+ LocalSurfaceId local_surface_id3(7, 2, embed_token);
+ LocalSurfaceId local_surface_id4(5, 3, embed_token);
+ LocalSurfaceId local_surface_id5(8, 1, embed_token);
+ LocalSurfaceId local_surface_id6(9, 3, embed_token);
// LocalSurfaceId1(6, 1)
auto result = support->MaybeSubmitCompositorFrame(
@@ -1204,4 +1207,26 @@ TEST_F(CompositorFrameSinkSupportTest,
support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
}
+// This test verifies that it is not possible to reuse the same embed token in
+// two different frame sinks.
+TEST_F(CompositorFrameSinkSupportTest,
+ DisallowEmbedTokenReuseAcrossFrameSinks) {
+ auto result = support_->MaybeSubmitCompositorFrame(
+ local_surface_id_, MakeDefaultCompositorFrame(), base::nullopt, 0,
+ mojom::CompositorFrameSink::SubmitCompositorFrameSyncCallback());
+ EXPECT_EQ(SubmitResult::ACCEPTED, result);
+
+ // Create another sink and reuse the same embed token to submit a frame. The
+ // frame should be rejected.
+ MockCompositorFrameSinkClient mock_client;
+ auto support = std::make_unique<CompositorFrameSinkSupport>(
+ &mock_client, &manager_, kAnotherArbitraryFrameSinkId,
+ false /* not root frame sink */, kNeedsSyncPoints);
+ LocalSurfaceId local_surface_id(31232, local_surface_id_.embed_token());
+ result = support->MaybeSubmitCompositorFrame(
+ local_surface_id, MakeDefaultCompositorFrame(), base::nullopt, 0,
+ mojom::CompositorFrameSink::SubmitCompositorFrameSyncCallback());
+ EXPECT_EQ(SubmitResult::SURFACE_INVARIANTS_VIOLATION, result);
+}
+
} // namespace viz
diff --git a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.cc b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.cc
index 6dfc7926846..b626908ae49 100644
--- a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.cc
+++ b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.cc
@@ -10,11 +10,13 @@
namespace viz {
ExternalBeginFrameSourceAndroid::ExternalBeginFrameSourceAndroid(
- uint32_t restart_id)
+ uint32_t restart_id,
+ float refresh_rate)
: ExternalBeginFrameSource(this, restart_id),
j_object_(Java_ExternalBeginFrameSourceAndroid_Constructor(
base::android::AttachCurrentThread(),
- reinterpret_cast<jlong>(this))) {}
+ reinterpret_cast<jlong>(this),
+ refresh_rate)) {}
ExternalBeginFrameSourceAndroid::~ExternalBeginFrameSourceAndroid() {
SetEnabled(false);
@@ -48,6 +50,11 @@ void ExternalBeginFrameSourceAndroid::OnVSync(
OnBeginFrame(begin_frame_args);
}
+void ExternalBeginFrameSourceAndroid::UpdateRefreshRate(float refresh_rate) {
+ Java_ExternalBeginFrameSourceAndroid_updateRefreshRate(
+ base::android::AttachCurrentThread(), j_object_, refresh_rate);
+}
+
void ExternalBeginFrameSourceAndroid::OnNeedsBeginFrames(
bool needs_begin_frames) {
SetEnabled(needs_begin_frames);
diff --git a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.h b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.h
index 49ae2a6961c..80072f2062c 100644
--- a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.h
+++ b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android.h
@@ -20,13 +20,14 @@ class VIZ_SERVICE_EXPORT ExternalBeginFrameSourceAndroid
: public ExternalBeginFrameSource,
public ExternalBeginFrameSourceClient {
public:
- explicit ExternalBeginFrameSourceAndroid(uint32_t restart_id);
+ ExternalBeginFrameSourceAndroid(uint32_t restart_id, float refresh_rate);
~ExternalBeginFrameSourceAndroid() override;
void OnVSync(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong time_micros,
jlong period_micros);
+ void UpdateRefreshRate(float refresh_rate) override;
private:
// ExternalBeginFrameSourceClient implementation.
diff --git a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android_unittest.cc b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android_unittest.cc
index 273beda5983..5daad10105b 100644
--- a/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/external_begin_frame_source_android_unittest.cc
@@ -5,6 +5,7 @@
#include "components/viz/service/frame_sinks/external_begin_frame_source_android.h"
#include "base/android/java_handler_thread.h"
+#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -35,10 +36,14 @@ class ExternalBeginFrameSourceAndroidTest : public ::testing::Test,
frames_done_event_.Wait();
}
+ ExternalBeginFrameSourceAndroid* begin_frame_source() {
+ return begin_frame_source_.get();
+ }
+
private:
void InitOnThread() {
begin_frame_source_ = std::make_unique<ExternalBeginFrameSourceAndroid>(
- BeginFrameSource::kNotRestartableId);
+ BeginFrameSource::kNotRestartableId, 60.f);
}
void AddObserverOnThread(uint32_t frame_count) {
@@ -75,4 +80,14 @@ TEST_F(ExternalBeginFrameSourceAndroidTest, DeliversFrames) {
WaitForFrames(10);
}
+TEST_F(ExternalBeginFrameSourceAndroidTest, DeliversFramesAfterIntervalChange) {
+ CreateThread();
+ // Ensure we receive frames. When this returns we are no longer observing the
+ // BeginFrameSource.
+ WaitForFrames(10);
+ begin_frame_source()->UpdateRefreshRate(30.f);
+ // Ensure we can re-observe the same BeginFrameSource and get more frames.
+ WaitForFrames(10);
+}
+
} // namespace viz
diff --git a/chromium/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/chromium/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index 8676bc246b0..96e240aae2a 100644
--- a/chromium/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/chromium/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "components/viz/service/display/shared_bitmap_manager.h"
@@ -256,8 +257,10 @@ void FrameSinkManagerImpl::AddVideoDetectorObserver(
void FrameSinkManagerImpl::CreateVideoCapturer(
mojom::FrameSinkVideoCapturerRequest request) {
- video_capturers_.emplace(
- std::make_unique<FrameSinkVideoCapturerImpl>(this, std::move(request)));
+ video_capturers_.emplace(std::make_unique<FrameSinkVideoCapturerImpl>(
+ this, std::move(request),
+ std::make_unique<media::VideoCaptureOracle>(
+ true /* enable_auto_throttling */)));
}
void FrameSinkManagerImpl::EvictSurfaces(
diff --git a/chromium/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/chromium/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
index ed5a7bb8803..5a6e3c8c05f 100644
--- a/chromium/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -420,13 +420,14 @@ TEST_F(FrameSinkManagerTest,
// Verifies that the SurfaceIds passed to EvictSurfaces will be destroyed in the
// next garbage collection.
TEST_F(FrameSinkManagerTest, EvictSurfaces) {
- ParentLocalSurfaceIdAllocator allocator;
- allocator.GenerateId();
+ ParentLocalSurfaceIdAllocator allocator1;
+ ParentLocalSurfaceIdAllocator allocator2;
+ allocator1.GenerateId();
LocalSurfaceId local_surface_id1 =
- allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
- allocator.GenerateId();
+ allocator1.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator2.GenerateId();
LocalSurfaceId local_surface_id2 =
- allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
+ allocator2.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
SurfaceId surface_id1(kFrameSinkIdA, local_surface_id1);
SurfaceId surface_id2(kFrameSinkIdB, local_surface_id2);
@@ -646,7 +647,7 @@ TEST_P(FrameSinkManagerOrderingParamTest, Ordering) {
UnregisterBFS();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
FrameSinkManagerOrderingParamTestInstantiation,
FrameSinkManagerOrderingParamTest,
::testing::Combine(::testing::ValuesIn(kRegisterOrderList),
diff --git a/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index 5ee9199d38e..8a6d9ff4d47 100644
--- a/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -52,7 +52,8 @@ RootCompositorFrameSinkImpl::Create(
} else {
#if defined(OS_ANDROID)
external_begin_frame_source =
- std::make_unique<ExternalBeginFrameSourceAndroid>(restart_id);
+ std::make_unique<ExternalBeginFrameSourceAndroid>(restart_id,
+ params->refresh_rate);
#else
if (params->disable_frame_rate_limit) {
synthetic_begin_frame_source =
@@ -151,6 +152,11 @@ void RootCompositorFrameSinkImpl::SetVSyncPaused(bool paused) {
if (external_begin_frame_source_)
external_begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
}
+
+void RootCompositorFrameSinkImpl::UpdateRefreshRate(float refresh_rate) {
+ if (external_begin_frame_source_)
+ external_begin_frame_source_->UpdateRefreshRate(refresh_rate);
+}
#endif // defined(OS_ANDROID)
void RootCompositorFrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) {
diff --git a/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
index ddbc794a867..e14dcbdd1c9 100644
--- a/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
+++ b/chromium/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -52,6 +52,7 @@ class RootCompositorFrameSinkImpl : public mojom::CompositorFrameSink,
void ForceImmediateDrawAndSwapIfPossible() override;
#if defined(OS_ANDROID)
void SetVSyncPaused(bool paused) override;
+ void UpdateRefreshRate(float refresh_rate) override;
#endif
// mojom::CompositorFrameSink:
diff --git a/chromium/components/viz/service/frame_sinks/surface_references_unittest.cc b/chromium/components/viz/service/frame_sinks/surface_references_unittest.cc
index 557be3bfd81..cb2bd50e623 100644
--- a/chromium/components/viz/service/frame_sinks/surface_references_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/surface_references_unittest.cc
@@ -16,6 +16,7 @@
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/test/compositor_frame_helpers.h"
+#include "components/viz/test/surface_id_allocator_set.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -47,11 +48,12 @@ class SurfaceReferencesTest : public testing::Test {
// Will first create a Surfacesupport for |frame_sink_id| if necessary.
SurfaceId CreateSurface(const FrameSinkId& frame_sink_id,
uint32_t parent_id) {
- LocalSurfaceId local_surface_id(parent_id,
- base::UnguessableToken::Deserialize(0, 1u));
+ SurfaceId surface_id =
+ allocator_set_.MakeSurfaceId(frame_sink_id, parent_id);
GetCompositorFrameSinkSupport(frame_sink_id)
- .SubmitCompositorFrame(local_surface_id, MakeDefaultCompositorFrame());
- return SurfaceId(frame_sink_id, local_surface_id);
+ .SubmitCompositorFrame(surface_id.local_surface_id(),
+ MakeDefaultCompositorFrame());
+ return surface_id;
}
// Destroy Surface with |surface_id|.
@@ -140,6 +142,7 @@ class SurfaceReferencesTest : public testing::Test {
std::unique_ptr<CompositorFrameSinkSupport>,
FrameSinkIdHash>
supports_;
+ SurfaceIdAllocatorSet allocator_set_;
};
TEST_F(SurfaceReferencesTest, AddReference) {
diff --git a/chromium/components/viz/service/frame_sinks/surface_synchronization_unittest.cc b/chromium/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
index 10db1240649..dc15dedb733 100644
--- a/chromium/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
@@ -13,6 +13,7 @@
#include "components/viz/test/fake_external_begin_frame_source.h"
#include "components/viz/test/fake_surface_observer.h"
#include "components/viz/test/mock_compositor_frame_sink_client.h"
+#include "components/viz/test/surface_id_allocator_set.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -40,14 +41,6 @@ std::vector<SurfaceRange> empty_surface_ranges() {
return std::vector<SurfaceRange>();
}
-SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id,
- uint32_t parent_sequence_number,
- uint32_t child_sequence_number = 1u) {
- return SurfaceId(frame_sink_id,
- LocalSurfaceId(parent_sequence_number, child_sequence_number,
- base::UnguessableToken::Deserialize(0, 1u)));
-}
-
CompositorFrame MakeCompositorFrame(
std::vector<SurfaceId> activation_dependencies,
std::vector<SurfaceRange> referenced_surfaces,
@@ -127,6 +120,9 @@ class SurfaceSynchronizationTest : public testing::Test {
}
FrameSinkManagerImpl& frame_sink_manager() { return frame_sink_manager_; }
+ SurfaceManager* surface_manager() {
+ return frame_sink_manager_.surface_manager();
+ }
// Returns all the references where |surface_id| is the parent.
const base::flat_set<SurfaceId>& GetChildReferences(
@@ -142,12 +138,6 @@ class SurfaceSynchronizationTest : public testing::Test {
surface_id);
}
- // Returns true if there is a Persistent reference for |surface_id|.
- bool HasPersistentReference(const SurfaceId& surface_id) {
- return frame_sink_manager().surface_manager()->HasPersistentReference(
- surface_id);
- }
-
Surface* GetLatestInFlightSurface(const SurfaceRange& surface_range) {
return frame_sink_manager().surface_manager()->GetLatestInFlightSurface(
surface_range);
@@ -243,6 +233,13 @@ class SurfaceSynchronizationTest : public testing::Test {
return frame_sink_manager_.surface_manager()->GetSurfaceForId(surface_id);
}
+ SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id,
+ uint32_t parent_sequence_number,
+ uint32_t child_sequence_number = 1u) {
+ return allocator_set_.MakeSurfaceId(frame_sink_id, parent_sequence_number,
+ child_sequence_number);
+ }
+
protected:
testing::NiceMock<MockCompositorFrameSinkClient> support_client_;
@@ -256,6 +253,7 @@ class SurfaceSynchronizationTest : public testing::Test {
std::unique_ptr<CompositorFrameSinkSupport>,
FrameSinkIdHash>
supports_;
+ SurfaceIdAllocatorSet allocator_set_;
DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest);
};
@@ -2057,9 +2055,11 @@ TEST_F(SurfaceSynchronizationTest, LatestInFlightSurface) {
GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
}
-// This test verifies that GetLatestInFlightSurface will return nullptr
-// if it has a bogus fallback SurfaceID.
-TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceWithBogusFallback) {
+// This test verifies that GetLatestInFlightSurface will return nullptr when the
+// start of the range is newer than its end, even if a surface matching the end
+// exists.
+TEST_F(SurfaceSynchronizationTest,
+ LatestInFlightSurfaceWithInvalidSurfaceRange) {
const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
@@ -2083,12 +2083,11 @@ TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceWithBogusFallback) {
const SurfaceId bogus_child_id = MakeSurfaceId(kChildFrameSink1, 10);
- // If primary exists and active return it regardless of the fallback.
- EXPECT_EQ(GetSurfaceForId(child_id1),
+ // The end exists but don't return it because the start is newer than the end.
+ EXPECT_EQ(nullptr,
GetLatestInFlightSurface(SurfaceRange(bogus_child_id, child_id1)));
- // If primary is not active and fallback is doesn't exist, we always return
- // nullptr.
+ // In this case, the end doesn't exist either. Still return nullptr.
EXPECT_EQ(nullptr,
GetLatestInFlightSurface(SurfaceRange(bogus_child_id, child_id2)));
}
@@ -2309,7 +2308,9 @@ TEST_F(SurfaceSynchronizationTest,
// |child_id1| now should have a temporary reference.
EXPECT_TRUE(HasTemporaryReference(child_id1));
- EXPECT_FALSE(HasPersistentReference(child_id1));
+ EXPECT_TRUE(surface_manager()
+ ->GetSurfacesThatReferenceChildForTesting(child_id1)
+ .empty());
// Activate |child_id2|.
child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
@@ -2317,7 +2318,9 @@ TEST_F(SurfaceSynchronizationTest,
// |child_id2| now should have a temporary reference.
EXPECT_TRUE(HasTemporaryReference(child_id2));
- EXPECT_FALSE(HasPersistentReference(child_id2));
+ EXPECT_TRUE(surface_manager()
+ ->GetSurfacesThatReferenceChildForTesting(child_id2)
+ .empty());
// Create a reference from |parent_id| to |child_id2|.
parent_support().SubmitCompositorFrame(
@@ -2327,11 +2330,15 @@ TEST_F(SurfaceSynchronizationTest,
// |child_id1| have no references and can be garbage collected.
EXPECT_FALSE(HasTemporaryReference(child_id1));
- EXPECT_FALSE(HasPersistentReference(child_id1));
+ EXPECT_TRUE(surface_manager()
+ ->GetSurfacesThatReferenceChildForTesting(child_id1)
+ .empty());
// |child_id2| has a persistent references now.
EXPECT_FALSE(HasTemporaryReference(child_id2));
- EXPECT_TRUE(HasPersistentReference(child_id2));
+ EXPECT_FALSE(surface_manager()
+ ->GetSurfacesThatReferenceChildForTesting(child_id2)
+ .empty());
// Verify that GetLatestInFlightSurface returns |child_id2|.
EXPECT_EQ(GetSurfaceForId(child_id2),
@@ -2390,11 +2397,55 @@ TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceSkipDifferentNonce) {
// This test verifies that if a child submits a LocalSurfaceId newer that the
// parent's dependency, then the parent will drop its dependency and activate
-// if possible.
-TEST_F(SurfaceSynchronizationTest, DropDependenciesThatWillNeverArrive) {
+// if possible. In this version of the test, parent sequence number of the
+// activated surface is larger than that in the dependency, while the child
+// sequence number is smaller.
+TEST_F(SurfaceSynchronizationTest, DropDependenciesThatWillNeverArrive1) {
+ const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
+ const SurfaceId child_id11 = MakeSurfaceId(kChildFrameSink1, 1, 2);
+ const SurfaceId child_id12 = MakeSurfaceId(kChildFrameSink1, 2, 1);
+ const SurfaceId child_id21 = MakeSurfaceId(kChildFrameSink2, 1);
+
+ // |parent_id| depends on { child_id11, child_id21 }. It shouldn't activate.
+ parent_support().SubmitCompositorFrame(
+ parent_id.local_surface_id(),
+ MakeCompositorFrame({child_id11, child_id21}, empty_surface_ranges(),
+ std::vector<TransferableResource>()));
+ EXPECT_FALSE(parent_surface()->HasActiveFrame());
+ EXPECT_TRUE(parent_surface()->HasPendingFrame());
+
+ // The first child submits a new CompositorFrame to |child_id12|. |parent_id|
+ // no longer depends on |child_id11| because it cannot expect it to arrive.
+ // However, the parent is still blocked on |child_id21|.
+ child_support1().SubmitCompositorFrame(
+ child_id12.local_surface_id(),
+ MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
+ std::vector<TransferableResource>()));
+ EXPECT_FALSE(parent_surface()->HasActiveFrame());
+ EXPECT_TRUE(parent_surface()->HasPendingFrame());
+ EXPECT_THAT(parent_surface()->activation_dependencies(),
+ UnorderedElementsAre(child_id21));
+
+ // Finally, the second child submits a frame to the remaining dependency and
+ // the parent activates.
+ child_support2().SubmitCompositorFrame(
+ child_id21.local_surface_id(),
+ MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
+ std::vector<TransferableResource>()));
+ EXPECT_TRUE(parent_surface()->HasActiveFrame());
+ EXPECT_FALSE(parent_surface()->HasPendingFrame());
+ EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
+}
+
+// This test verifies that if a child submits a LocalSurfaceId newer that the
+// parent's dependency, then the parent will drop its dependency and activate
+// if possible. In this version of the test, parent sequence number of the
+// activated surface is smaller than that in the dependency, while the child
+// sequence number is larger.
+TEST_F(SurfaceSynchronizationTest, DropDependenciesThatWillNeverArrive2) {
const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
- const SurfaceId child_id11 = MakeSurfaceId(kChildFrameSink1, 1);
- const SurfaceId child_id12 = MakeSurfaceId(kChildFrameSink1, 2);
+ const SurfaceId child_id11 = MakeSurfaceId(kChildFrameSink1, 2, 1);
+ const SurfaceId child_id12 = MakeSurfaceId(kChildFrameSink1, 1, 2);
const SurfaceId child_id21 = MakeSurfaceId(kChildFrameSink2, 1);
// |parent_id| depends on { child_id11, child_id21 }. It shouldn't activate.
diff --git a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
index 521ce7e9de5..cd0e3c16225 100644
--- a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
+++ b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -17,6 +17,7 @@
#include "build/build_config.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
#include "media/base/limits.h"
@@ -51,16 +52,18 @@ constexpr gfx::ColorSpace FrameSinkVideoCapturerImpl::kDefaultColorSpace;
FrameSinkVideoCapturerImpl::FrameSinkVideoCapturerImpl(
FrameSinkVideoCapturerManager* frame_sink_manager,
- mojom::FrameSinkVideoCapturerRequest request)
+ mojom::FrameSinkVideoCapturerRequest request,
+ std::unique_ptr<media::VideoCaptureOracle> oracle)
: frame_sink_manager_(frame_sink_manager),
binding_(this),
copy_request_source_(base::UnguessableToken::Create()),
clock_(base::DefaultTickClock::GetInstance()),
- oracle_(true /* enable_auto_throttling */),
+ oracle_(std::move(oracle)),
frame_pool_(kDesignLimitMaxFrames),
- feedback_weak_factory_(&oracle_),
+ feedback_weak_factory_(oracle_.get()),
capture_weak_factory_(this) {
DCHECK(frame_sink_manager_);
+ DCHECK(oracle_);
// Instantiate a default base::OneShotTimer instance.
refresh_frame_retry_timer_.emplace();
@@ -165,7 +168,7 @@ void FrameSinkVideoCapturerImpl::SetMinCapturePeriod(
}
}
- oracle_.SetMinCapturePeriod(min_capture_period);
+ oracle_->SetMinCapturePeriod(min_capture_period);
if (refresh_frame_retry_timer_->IsRunning()) {
// With the change in the minimum capture period, a pending refresh might
// be ready to execute now (or sooner than it would have been).
@@ -177,7 +180,7 @@ void FrameSinkVideoCapturerImpl::SetMinSizeChangePeriod(
base::TimeDelta min_period) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- oracle_.SetMinSizeChangePeriod(min_period);
+ oracle_->SetMinSizeChangePeriod(min_period);
}
void FrameSinkVideoCapturerImpl::SetResolutionConstraints(
@@ -197,12 +200,13 @@ void FrameSinkVideoCapturerImpl::SetResolutionConstraints(
return;
}
- oracle_.SetCaptureSizeConstraints(min_size, max_size, use_fixed_aspect_ratio);
+ oracle_->SetCaptureSizeConstraints(min_size, max_size,
+ use_fixed_aspect_ratio);
RefreshEntireSourceSoon();
}
void FrameSinkVideoCapturerImpl::SetAutoThrottlingEnabled(bool enabled) {
- oracle_.SetAutoThrottlingEnabled(enabled);
+ oracle_->SetAutoThrottlingEnabled(enabled);
}
void FrameSinkVideoCapturerImpl::ChangeTarget(
@@ -240,7 +244,7 @@ void FrameSinkVideoCapturerImpl::Stop() {
// Cancel any captures in-flight and any captured frames pending delivery.
capture_weak_factory_.InvalidateWeakPtrs();
- oracle_.CancelAllCaptures();
+ oracle_->CancelAllCaptures();
while (!delivery_queue_.empty()) {
delivery_queue_.pop();
}
@@ -286,8 +290,8 @@ base::TimeDelta FrameSinkVideoCapturerImpl::GetDelayBeforeNextRefreshAttempt()
// of frame captures that are expected to take place due to compositor update
// events. However, the delay should not be excessively long either. Two frame
// periods should be "just right."
- return 2 * std::max(oracle_.estimated_frame_duration(),
- oracle_.min_capture_period());
+ return 2 * std::max(oracle_->estimated_frame_duration(),
+ oracle_->min_capture_period());
}
void FrameSinkVideoCapturerImpl::RefreshEntireSourceSoon() {
@@ -321,13 +325,13 @@ void FrameSinkVideoCapturerImpl::RefreshSoon() {
ScheduleRefreshFrame();
return;
}
- if (source_size != oracle_.source_size()) {
- oracle_.SetSourceSize(source_size);
+ if (source_size != oracle_->source_size()) {
+ oracle_->SetSourceSize(source_size);
dirty_rect_ = kMaxRect;
}
MaybeCaptureFrame(VideoCaptureOracle::kRefreshRequest,
- gfx::Rect(oracle_.source_size()), clock_->NowTicks(),
+ gfx::Rect(oracle_->source_size()), clock_->NowTicks(),
*resolved_target_->GetLastActivatedFrameMetadata());
}
@@ -342,10 +346,10 @@ void FrameSinkVideoCapturerImpl::OnFrameDamaged(
DCHECK(!expected_display_time.is_null());
DCHECK(resolved_target_);
- if (frame_size == oracle_.source_size()) {
+ if (frame_size == oracle_->source_size()) {
InvalidateRect(damage_rect);
} else {
- oracle_.SetSourceSize(frame_size);
+ oracle_->SetSourceSize(frame_size);
dirty_rect_ = kMaxRect;
}
@@ -356,7 +360,7 @@ void FrameSinkVideoCapturerImpl::OnFrameDamaged(
gfx::Size FrameSinkVideoCapturerImpl::GetSourceSize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return oracle_.source_size();
+ return oracle_->source_size();
}
void FrameSinkVideoCapturerImpl::InvalidateRect(const gfx::Rect& rect) {
@@ -401,7 +405,7 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
DCHECK(resolved_target_);
// Consult the oracle to determine whether this frame should be captured.
- if (oracle_.ObserveEventAndDecideCapture(event, damage_rect, event_time)) {
+ if (oracle_->ObserveEventAndDecideCapture(event, damage_rect, event_time)) {
// Regardless of the type of |event|, there is no longer a need for the
// refresh frame retry timer to fire. The following is a no-op, if the timer
// was not running.
@@ -427,18 +431,25 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
return;
}
- // Reserve a buffer from the pool for the next frame.
- const OracleFrameNumber oracle_frame_number = oracle_.next_frame_number();
+ // Reserve a buffer from the pool for the next frame. Optimization: If there
+ // are no changes in the source that need to be captured AND there are no
+ // captures currently in-flight, attempt to resurrect the last frame from the
+ // pool (and there is no need to capture anything new into the frame).
+ const OracleFrameNumber oracle_frame_number = oracle_->next_frame_number();
const gfx::Size capture_size =
- AdjustSizeForPixelFormat(oracle_.capture_size());
+ AdjustSizeForPixelFormat(oracle_->capture_size());
+
scoped_refptr<VideoFrame> frame;
- if (dirty_rect_.IsEmpty()) {
+ bool using_resurrected_frame =
+ dirty_rect_.IsEmpty() &&
+ next_capture_frame_number_ == next_delivery_frame_number_;
+ if (using_resurrected_frame) {
frame = frame_pool_.ResurrectLastVideoFrame(pixel_format_, capture_size);
// If the resurrection failed, promote to a full frame capture.
if (!frame) {
TRACE_EVENT_INSTANT0("gpu.capture", "ResurrectionFailed",
TRACE_EVENT_SCOPE_THREAD);
- dirty_rect_ = kMaxRect;
+ using_resurrected_frame = false;
frame = frame_pool_.ReserveVideoFrame(pixel_format_, capture_size);
}
} else {
@@ -458,7 +469,7 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
"gpu.capture", "PipelineLimited", TRACE_EVENT_SCOPE_THREAD, "trigger",
VideoCaptureOracle::EventAsString(event), "atten_util_percent",
base::saturated_cast<int>(utilization * 100.0f + 0.5f));
- oracle_.RecordWillNotCapture(utilization);
+ oracle_->RecordWillNotCapture(utilization);
if (next_capture_frame_number_ == 0) {
// The pool was unable to provide a buffer for the very first capture, and
// so there is no expectation of recovery. Thus, treat this as a fatal
@@ -483,13 +494,16 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
// At this point, the capture is going to proceed. Populate the VideoFrame's
// metadata, and notify the oracle.
+ const int64_t capture_frame_number = next_capture_frame_number_++;
VideoFrameMetadata* const metadata = frame->metadata();
metadata->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME,
clock_->NowTicks());
+ metadata->SetInteger(VideoFrameMetadata::CAPTURE_COUNTER,
+ capture_frame_number);
metadata->SetTimeDelta(VideoFrameMetadata::FRAME_DURATION,
- oracle_.estimated_frame_duration());
+ oracle_->estimated_frame_duration());
metadata->SetDouble(VideoFrameMetadata::FRAME_RATE,
- 1.0 / oracle_.min_capture_period().InSecondsF());
+ 1.0 / oracle_->min_capture_period().InSecondsF());
metadata->SetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, event_time);
metadata->SetDouble(VideoFrameMetadata::DEVICE_SCALE_FACTOR,
frame_metadata.device_scale_factor);
@@ -504,13 +518,12 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
metadata->SetDouble(VideoFrameMetadata::TOP_CONTROLS_SHOWN_RATIO,
frame_metadata.top_controls_shown_ratio);
- oracle_.RecordCapture(utilization);
- const int64_t frame_number = next_capture_frame_number_++;
+ oracle_->RecordCapture(utilization);
TRACE_EVENT_ASYNC_BEGIN2("gpu.capture", "Capture", oracle_frame_number,
- "frame_number", frame_number, "trigger",
+ "frame_number", capture_frame_number, "trigger",
VideoCaptureOracle::EventAsString(event));
- const gfx::Size& source_size = oracle_.source_size();
+ const gfx::Size& source_size = oracle_->source_size();
DCHECK(!source_size.IsEmpty());
gfx::Rect content_rect;
if (pixel_format_ == media::PIXEL_FORMAT_I420) {
@@ -521,6 +534,25 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
content_rect =
media::ComputeLetterboxRegion(frame->visible_rect(), source_size);
}
+
+ // Determine what rectangluar region has changed since the last captured
+ // frame.
+ gfx::Rect update_rect;
+ if (dirty_rect_ == kMaxRect ||
+ frame->visible_rect() != last_frame_visible_rect_) {
+ // Source or VideoFrame size change: Assume entire frame (including
+ // letterboxed regions) have changed.
+ update_rect = last_frame_visible_rect_ = frame->visible_rect();
+ } else {
+ update_rect = copy_output::ComputeResultRect(
+ dirty_rect_, gfx::Vector2d(source_size.width(), source_size.height()),
+ gfx::Vector2d(content_rect.width(), content_rect.height()));
+ update_rect.Offset(content_rect.OffsetFromOrigin());
+ if (pixel_format_ == media::PIXEL_FORMAT_I420)
+ update_rect = ExpandRectToI420SubsampleBoundaries(update_rect);
+ }
+ metadata->SetRect(media::VideoFrameMetadata::CAPTURE_UPDATE_RECT,
+ update_rect);
// Extreme edge-case: If somehow the source size is so tiny that the content
// region becomes empty, just deliver a frame filled with black.
if (content_rect.IsEmpty()) {
@@ -532,14 +564,15 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
frame->set_color_space(gfx::ColorSpace::CreateSRGB());
}
dirty_rect_ = gfx::Rect();
- DidCaptureFrame(frame_number, oracle_frame_number, gfx::Rect(),
+ DidCaptureFrame(capture_frame_number, oracle_frame_number, gfx::Rect(),
std::move(frame));
return;
}
- // For passive refreshes, just deliver the resurrected frame.
- if (dirty_rect_.IsEmpty()) {
- DidCaptureFrame(frame_number, oracle_frame_number, content_rect,
+ // If the frame is a resurrected one, just deliver it since it already
+ // contains the most up-to-date capture of the source content.
+ if (using_resurrected_frame) {
+ DidCaptureFrame(capture_frame_number, oracle_frame_number, content_rect,
std::move(frame));
return;
}
@@ -550,7 +583,7 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
? CopyOutputRequest::ResultFormat::I420_PLANES
: CopyOutputRequest::ResultFormat::RGBA_BITMAP,
base::BindOnce(&FrameSinkVideoCapturerImpl::DidCopyFrame,
- capture_weak_factory_.GetWeakPtr(), frame_number,
+ capture_weak_factory_.GetWeakPtr(), capture_frame_number,
oracle_frame_number, content_rect,
VideoCaptureOverlay::MakeCombinedRenderer(
GetOverlaysInOrder(), content_rect, frame->format()),
@@ -564,19 +597,32 @@ void FrameSinkVideoCapturerImpl::MaybeCaptureFrame(
// just the part of the result that would have changed due to aggregated
// damage over all the frames that weren't captured.
request->set_result_selection(gfx::Rect(content_rect.size()));
+
+ // Clear the |dirty_rect_|, to indicate all changes at the source are now
+ // being captured. This will also enable the "frame resurrection" optimization
+ // in future calls to this method. In other words, while the source content
+ // remains unchanged, there is no need to make any more CopyOutputRequests.
+ //
+ // Note that some optimistic assumptions are being made here: 1) that this
+ // |request| will succeed and it's image data successfully transferred to the
+ // VideoFrame; and 2) that delivery of the VideoFrame to the consumer will
+ // succeed. If, later in the pipeline, either of these assumptions is
+ // violated, the |dirty_rect_| will be changed to indicate that there might
+ // still be source changes requiring capture. See MaybeDeliverFrame().
dirty_rect_ = gfx::Rect();
+
resolved_target_->RequestCopyOfOutput(LocalSurfaceId(), std::move(request));
}
void FrameSinkVideoCapturerImpl::DidCopyFrame(
- int64_t frame_number,
+ int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
VideoCaptureOverlay::OnceRenderer overlay_renderer,
scoped_refptr<VideoFrame> frame,
std::unique_ptr<CopyOutputResult> result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_GE(frame_number, next_delivery_frame_number_);
+ DCHECK_GE(capture_frame_number, next_delivery_frame_number_);
DCHECK(frame);
DCHECK(result);
@@ -636,17 +682,17 @@ void FrameSinkVideoCapturerImpl::DidCopyFrame(
AdjustSizeForPixelFormat(result->size())));
}
- DidCaptureFrame(frame_number, oracle_frame_number, content_rect,
+ DidCaptureFrame(capture_frame_number, oracle_frame_number, content_rect,
std::move(frame));
}
void FrameSinkVideoCapturerImpl::DidCaptureFrame(
- int64_t frame_number,
+ int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
scoped_refptr<VideoFrame> frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_GE(frame_number, next_delivery_frame_number_);
+ DCHECK_GE(capture_frame_number, next_delivery_frame_number_);
if (frame) {
frame->metadata()->SetTimeTicks(VideoFrameMetadata::CAPTURE_END_TIME,
@@ -655,9 +701,10 @@ void FrameSinkVideoCapturerImpl::DidCaptureFrame(
// Ensure frames are delivered in-order by using a min-heap, and only
// deliver the next frame(s) in-sequence when they are found at the top.
- delivery_queue_.emplace(frame_number, oracle_frame_number, content_rect,
- std::move(frame));
- while (delivery_queue_.top().frame_number == next_delivery_frame_number_) {
+ delivery_queue_.emplace(capture_frame_number, oracle_frame_number,
+ content_rect, std::move(frame));
+ while (delivery_queue_.top().capture_frame_number ==
+ next_delivery_frame_number_) {
auto& next = delivery_queue_.top();
MaybeDeliverFrame(next.oracle_frame_number, next.content_rect,
std::move(next.frame));
@@ -679,7 +726,7 @@ void FrameSinkVideoCapturerImpl::MaybeDeliverFrame(
// also rewrites the media timestamp in terms of the smooth flow of the
// original source content.
base::TimeTicks media_ticks;
- if (!oracle_.CompleteCapture(oracle_frame_number, !!frame, &media_ticks)) {
+ if (!oracle_->CompleteCapture(oracle_frame_number, !!frame, &media_ticks)) {
// The following is used by
// chrome/browser/extension/api/cast_streaming/performance_test.cc, in
// addition to the usual runtime tracing.
@@ -687,8 +734,11 @@ void FrameSinkVideoCapturerImpl::MaybeDeliverFrame(
"success", false);
// Mark the whole source as dirty, since this frame may have contained
- // updated content that will not be delivered.
+ // updated content that will not be delivered. See the comment at the end of
+ // MaybeCaptureFrame() regarding "optimistic assumptions" for further
+ // discussion.
dirty_rect_ = kMaxRect;
+
ScheduleRefreshFrame();
return;
}
@@ -724,7 +774,6 @@ void FrameSinkVideoCapturerImpl::MaybeDeliverFrame(
info->visible_rect = frame->visible_rect();
DCHECK(frame->ColorSpace().IsValid()); // Ensure it was set by this point.
info->color_space = frame->ColorSpace();
- const gfx::Rect update_rect = frame->visible_rect();
// Create an InFlightFrameDelivery for this frame, owned by its mojo binding.
// It responds to the consumer's Done() notification by returning the video
@@ -744,8 +793,8 @@ void FrameSinkVideoCapturerImpl::MaybeDeliverFrame(
mojo::MakeRequest(&callbacks));
// Send the frame to the consumer.
- consumer_->OnFrameCaptured(std::move(handle), std::move(info), update_rect,
- content_rect, std::move(callbacks));
+ consumer_->OnFrameCaptured(std::move(handle), std::move(info), content_rect,
+ std::move(callbacks));
}
gfx::Size FrameSinkVideoCapturerImpl::AdjustSizeForPixelFormat(
@@ -767,12 +816,22 @@ gfx::Size FrameSinkVideoCapturerImpl::AdjustSizeForPixelFormat(
return result;
}
+// static
+gfx::Rect FrameSinkVideoCapturerImpl::ExpandRectToI420SubsampleBoundaries(
+ const gfx::Rect& rect) {
+ const int x = rect.x() & ~1;
+ const int y = rect.y() & ~1;
+ const int r = rect.right() + (rect.right() & 1);
+ const int b = rect.bottom() + (rect.bottom() & 1);
+ return gfx::Rect(x, y, r - x, b - y);
+}
+
FrameSinkVideoCapturerImpl::CapturedFrame::CapturedFrame(
- int64_t frame_number,
+ int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
scoped_refptr<media::VideoFrame> frame)
- : frame_number(frame_number),
+ : capture_frame_number(capture_frame_number),
oracle_frame_number(oracle_frame_number),
content_rect(content_rect),
frame(std::move(frame)) {}
@@ -786,7 +845,7 @@ bool FrameSinkVideoCapturerImpl::CapturedFrame::operator<(
const FrameSinkVideoCapturerImpl::CapturedFrame& other) const {
// Reverse the sort order; so std::priority_queue<CapturedFrame> becomes a
// min-heap instead of a max-heap.
- return other.frame_number < frame_number;
+ return other.capture_frame_number < capture_frame_number;
}
} // namespace viz
diff --git a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h
index 69f25dab2aa..3c5ddc071e6 100644
--- a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h
+++ b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h
@@ -74,7 +74,8 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// Mojo message pipe endpoint in |request|, but |request| may be empty for
// unit testing.
FrameSinkVideoCapturerImpl(FrameSinkVideoCapturerManager* frame_sink_manager,
- mojom::FrameSinkVideoCapturerRequest request);
+ mojom::FrameSinkVideoCapturerRequest request,
+ std::unique_ptr<media::VideoCaptureOracle> oracle);
~FrameSinkVideoCapturerImpl() final;
@@ -186,7 +187,7 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// Extracts the image data from the copy output |result|, populating the
// |content_rect| region of a [possibly letterboxed] video |frame|.
- void DidCopyFrame(int64_t frame_number,
+ void DidCopyFrame(int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
VideoCaptureOverlay::OnceRenderer overlay_renderer,
@@ -196,7 +197,7 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// Places the frame in the |delivery_queue_| and calls MaybeDeliverFrame(),
// one frame at a time, in-order. |frame| may be null to indicate a
// completed, but unsuccessful capture.
- void DidCaptureFrame(int64_t frame_number,
+ void DidCaptureFrame(int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
scoped_refptr<media::VideoFrame> frame);
@@ -213,6 +214,10 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// I420 format, ensures that every dimension is even and at least 2.
gfx::Size AdjustSizeForPixelFormat(const gfx::Size& size);
+ // Expands |rect| such that its x, y, right, and bottom values are even
+ // numbers.
+ static gfx::Rect ExpandRectToI420SubsampleBoundaries(const gfx::Rect& rect);
+
// Owner/Manager of this instance.
FrameSinkVideoCapturerManager* const frame_sink_manager_;
@@ -235,7 +240,7 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// Models current content change/draw behavior and proposes when to capture
// frames, and at what size and frame rate.
- media::VideoCaptureOracle oracle_;
+ const std::unique_ptr<media::VideoCaptureOracle> oracle_;
// The target requested by the client, as provided in the last call to
// ChangeTarget().
@@ -253,6 +258,10 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// captured.
gfx::Rect dirty_rect_;
+ // Allows determining whether or not the frame size has changed since the last
+ // captured frame.
+ gfx::Rect last_frame_visible_rect_;
+
// These are sequence counters used to ensure that the frames are being
// delivered in the same order they are captured.
int64_t next_capture_frame_number_ = 0;
@@ -275,11 +284,11 @@ class VIZ_SERVICE_EXPORT FrameSinkVideoCapturerImpl final
// A queue of captured frames pending delivery. This queue is used to re-order
// frames, if they should happen to be captured out-of-order.
struct CapturedFrame {
- int64_t frame_number;
+ int64_t capture_frame_number;
OracleFrameNumber oracle_frame_number;
gfx::Rect content_rect;
scoped_refptr<media::VideoFrame> frame;
- CapturedFrame(int64_t frame_number,
+ CapturedFrame(int64_t capture_frame_number,
OracleFrameNumber oracle_frame_number,
const gfx::Rect& content_rect,
scoped_refptr<media::VideoFrame> frame);
diff --git a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
index 64ab61ed712..68b0214e1ae 100644
--- a/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
@@ -17,9 +17,11 @@
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/frame_sinks/copy_output_util.h"
#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
#include "media/base/limits.h"
#include "media/base/video_util.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
#include "services/viz/privileged/interfaces/compositing/frame_sink_video_capture.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -41,6 +43,11 @@ using testing::Return;
namespace viz {
namespace {
+bool AlignsWithI420SubsamplingBoundaries(const gfx::Rect& update_rect) {
+ return (update_rect.x() % 2 == 0) && (update_rect.y() % 2 == 0) &&
+ (update_rect.width() % 2 == 0) && (update_rect.height() % 2 == 0);
+}
+
// Returns true if |frame|'s device scale factor, page scale factor and root
// scroll offset are equal to the expected values.
bool CompareVarsInCompositorFrameMetadata(
@@ -71,20 +78,23 @@ constexpr FrameSinkId kFrameSinkId = FrameSinkId(1, 1);
constexpr base::TimeDelta kVsyncInterval =
base::TimeDelta::FromSecondsD(1.0 / 60.0);
-// The size of the compositor frame sink's Surface.
-constexpr gfx::Size kSourceSize = gfx::Size(100, 100);
-
-// The size of the VideoFrames produced by the capturer.
-constexpr gfx::Size kCaptureSize = gfx::Size(32, 18);
+const struct SizeSet {
+ // The size of the compositor frame sink's Surface.
+ gfx::Size source_size;
+ // The size of the VideoFrames produced by the capturer.
+ gfx::Size capture_size;
+ // The location of the letterboxed content within each VideoFrame. All pixels
+ // outside of this region should be black.
+ gfx::Rect expected_content_rect;
+} kSizeSets[3] = {
+ {gfx::Size(100, 100), gfx::Size(32, 18), gfx::Rect(6, 0, 18, 18)},
+ {gfx::Size(64, 18), gfx::Size(32, 18), gfx::Rect(0, 4, 32, 8)},
+ {gfx::Size(64, 18), gfx::Size(64, 18), gfx::Rect(0, 0, 64, 18)}};
constexpr float kDefaultDeviceScaleFactor = 1.f;
constexpr float kDefaultPageScaleFactor = 1.f;
constexpr gfx::Vector2dF kDefaultRootScrollOffset = gfx::Vector2dF(0, 0);
-// The location of the letterboxed content within each VideoFrame. All pixels
-// outside of this region should be black.
-constexpr gfx::Rect kContentRect = gfx::Rect(6, 0, 18, 18);
-
struct YUVColor {
uint8_t y;
uint8_t u;
@@ -109,10 +119,7 @@ class MockConsumer : public mojom::FrameSinkVideoConsumer {
public:
MockConsumer() : binding_(this) {}
- MOCK_METHOD3(OnFrameCapturedMock,
- void(scoped_refptr<VideoFrame> frame,
- const gfx::Rect& update_rect,
- mojom::FrameSinkVideoConsumerFrameCallbacks* callbacks));
+ MOCK_METHOD0(OnFrameCapturedMock, void());
MOCK_METHOD0(OnStopped, void());
int num_frames_received() const { return frames_.size(); }
@@ -134,19 +141,17 @@ class MockConsumer : public mojom::FrameSinkVideoConsumer {
void OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
media::mojom::VideoFrameInfoPtr info,
- const gfx::Rect& update_rect,
- const gfx::Rect& content_rect,
+ const gfx::Rect& expected_content_rect,
mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) final {
ASSERT_TRUE(data.IsValid());
const auto required_bytes_to_hold_planes =
static_cast<uint32_t>(info->coded_size.GetArea() * 3 / 2);
ASSERT_LE(required_bytes_to_hold_planes, data.GetSize());
ASSERT_TRUE(info);
- EXPECT_EQ(gfx::Rect(kCaptureSize), update_rect);
ASSERT_TRUE(callbacks.get());
// Map the shared memory buffer and re-constitute a VideoFrame instance
- // around it for analysis by OnFrameCapturedMock().
+ // around it for analysis via TakeFrame().
base::ReadOnlySharedMemoryMapping mapping = data.Map();
ASSERT_TRUE(mapping.IsValid());
ASSERT_LE(
@@ -162,9 +167,10 @@ class MockConsumer : public mojom::FrameSinkVideoConsumer {
frame->metadata()->MergeInternalValuesFrom(info->metadata);
if (info->color_space.has_value())
frame->set_color_space(info->color_space.value());
+
frame->AddDestructionObserver(base::BindOnce(
[](base::ReadOnlySharedMemoryMapping mapping) {}, std::move(mapping)));
- OnFrameCapturedMock(frame, update_rect, callbacks.get());
+ OnFrameCapturedMock();
frames_.push_back(std::move(frame));
done_callbacks_.push_back(
@@ -215,7 +221,7 @@ class SolidColorI420Result : public CopyOutputResult {
class FakeCapturableFrameSink : public CapturableFrameSink {
public:
- FakeCapturableFrameSink() {
+ FakeCapturableFrameSink() : size_set_(kSizeSets[0]) {
metadata_.root_scroll_offset = kDefaultRootScrollOffset;
metadata_.page_scale_factor = kDefaultPageScaleFactor;
metadata_.device_scale_factor = kDefaultDeviceScaleFactor;
@@ -235,15 +241,16 @@ class FakeCapturableFrameSink : public CapturableFrameSink {
client_ = nullptr;
}
- gfx::Size GetActiveFrameSize() override { return kSourceSize; }
+ gfx::Size GetActiveFrameSize() override { return source_size(); }
void RequestCopyOfOutput(
const LocalSurfaceId& local_surface_id,
std::unique_ptr<CopyOutputRequest> request) override {
EXPECT_EQ(CopyOutputResult::Format::I420_PLANES, request->result_format());
EXPECT_NE(base::UnguessableToken(), request->source());
- EXPECT_EQ(gfx::Rect(kSourceSize), request->area());
- EXPECT_EQ(gfx::Rect(kContentRect.size()), request->result_selection());
+ EXPECT_EQ(gfx::Rect(size_set_.source_size), request->area());
+ EXPECT_EQ(gfx::Rect(size_set_.expected_content_rect.size()),
+ request->result_selection());
auto result = std::make_unique<SolidColorI420Result>(
request->result_selection(), color_);
@@ -259,6 +266,10 @@ class FakeCapturableFrameSink : public CapturableFrameSink {
return &metadata_;
}
+ const gfx::Size& source_size() const { return size_set_.source_size; }
+
+ void set_size_set(const SizeSet& size_set) { size_set_ = size_set; }
+
void set_metadata(const CompositorFrameMetadata& metadata) {
metadata_ = metadata.Clone();
}
@@ -276,30 +287,66 @@ class FakeCapturableFrameSink : public CapturableFrameSink {
private:
CapturableFrameSink::Client* client_ = nullptr;
YUVColor color_ = {0xde, 0xad, 0xbf};
+ SizeSet size_set_;
CompositorFrameMetadata metadata_;
std::vector<base::OnceClosure> results_;
};
+class InstrumentedVideoCaptureOracle : public media::VideoCaptureOracle {
+ public:
+ explicit InstrumentedVideoCaptureOracle(bool enable_auto_throttling)
+ : media::VideoCaptureOracle(enable_auto_throttling),
+ return_false_on_complete_capture_(false) {}
+
+ bool CompleteCapture(int frame_number,
+ bool capture_was_successful,
+ base::TimeTicks* frame_timestamp) override {
+ capture_was_successful &= !return_false_on_complete_capture_;
+ return media::VideoCaptureOracle::CompleteCapture(
+ frame_number, capture_was_successful, frame_timestamp);
+ }
+
+ void set_return_false_on_complete_capture(bool should_return_false) {
+ return_false_on_complete_capture_ = should_return_false;
+ }
+
+ gfx::Size capture_size() const override {
+ if (forced_capture_size_.has_value())
+ return forced_capture_size_.value();
+ return media::VideoCaptureOracle::capture_size();
+ }
+
+ void set_forced_capture_size(base::Optional<gfx::Size> size) {
+ forced_capture_size_ = size;
+ }
+
+ private:
+ bool return_false_on_complete_capture_;
+ base::Optional<gfx::Size> forced_capture_size_;
+};
+
// Matcher that returns true if the content region of a letterboxed VideoFrame
// is filled with the given color, and black everywhere else.
-MATCHER_P(IsLetterboxedFrame, color, "") {
+MATCHER_P2(IsLetterboxedFrame, color, content_rect, "") {
if (!arg) {
return false;
}
const VideoFrame& frame = *arg;
- const auto IsLetterboxedPlane = [&frame](int plane, uint8_t color) {
- gfx::Rect content_rect = kContentRect;
+ const gfx::Rect kContentRect = content_rect;
+ const auto IsLetterboxedPlane = [&frame, kContentRect](int plane,
+ uint8_t color) {
+ gfx::Rect content_rect_copy = kContentRect;
if (plane != VideoFrame::kYPlane) {
- content_rect =
- gfx::Rect(content_rect.x() / 2, content_rect.y() / 2,
- content_rect.width() / 2, content_rect.height() / 2);
+ content_rect_copy = gfx::Rect(
+ content_rect_copy.x() / 2, content_rect_copy.y() / 2,
+ content_rect_copy.width() / 2, content_rect_copy.height() / 2);
}
for (int row = 0; row < frame.rows(plane); ++row) {
const uint8_t* p = frame.visible_data(plane) + row * frame.stride(plane);
for (int col = 0; col < frame.row_bytes(plane); ++col) {
- if (content_rect.Contains(gfx::Point(col, row))) {
+ if (content_rect_copy.Contains(gfx::Point(col, row))) {
if (p[col] != color) {
return false;
}
@@ -322,9 +369,14 @@ MATCHER_P(IsLetterboxedFrame, color, "") {
class FrameSinkVideoCapturerTest : public testing::Test {
public:
- FrameSinkVideoCapturerTest()
- : capturer_(&frame_sink_manager_,
- mojom::FrameSinkVideoCapturerRequest()) {}
+ FrameSinkVideoCapturerTest() : size_set_(kSizeSets[0]) {
+ auto oracle = std::make_unique<InstrumentedVideoCaptureOracle>(
+ true /* enable_auto_throttling */);
+ oracle_ = oracle.get();
+ capturer_ = std::make_unique<FrameSinkVideoCapturerImpl>(
+ &frame_sink_manager_, mojom::FrameSinkVideoCapturerRequest(),
+ std::move(oracle));
+ }
void SetUp() override {
// Override the capturer's TickClock with a virtual clock managed by a
@@ -333,44 +385,45 @@ class FrameSinkVideoCapturerTest : public testing::Test {
base::Time::Now(), base::TimeTicks() + base::TimeDelta::FromSeconds(1),
base::TestMockTimeTaskRunner::Type::kStandalone);
start_time_ = task_runner_->NowTicks();
- capturer_.clock_ = task_runner_->GetMockTickClock();
+ capturer_->clock_ = task_runner_->GetMockTickClock();
// Replace the retry timer with one that uses this test's fake clock and
// task runner.
- capturer_.refresh_frame_retry_timer_.emplace(
+ capturer_->refresh_frame_retry_timer_.emplace(
task_runner_->GetMockTickClock());
- capturer_.refresh_frame_retry_timer_->SetTaskRunner(task_runner_);
+ capturer_->refresh_frame_retry_timer_->SetTaskRunner(task_runner_);
// Before setting the format, ensure the defaults are in-place. Then, for
// these tests, set a specific format and color space.
ASSERT_EQ(FrameSinkVideoCapturerImpl::kDefaultPixelFormat,
- capturer_.pixel_format_);
+ capturer_->pixel_format_);
ASSERT_EQ(FrameSinkVideoCapturerImpl::kDefaultColorSpace,
- capturer_.color_space_);
- capturer_.SetFormat(media::PIXEL_FORMAT_I420,
- gfx::ColorSpace::CreateREC709());
- ASSERT_EQ(media::PIXEL_FORMAT_I420, capturer_.pixel_format_);
- ASSERT_EQ(gfx::ColorSpace::CreateREC709(), capturer_.color_space_);
+ capturer_->color_space_);
+ capturer_->SetFormat(media::PIXEL_FORMAT_I420,
+ gfx::ColorSpace::CreateREC709());
+ ASSERT_EQ(media::PIXEL_FORMAT_I420, capturer_->pixel_format_);
+ ASSERT_EQ(gfx::ColorSpace::CreateREC709(), capturer_->color_space_);
// Set min capture period as small as possible so that the
// media::VideoCapturerOracle used by the capturer will want to capture
// every composited frame. The capturer will override the too-small value of
// zero with a value based on media::limits::kMaxFramesPerSecond.
- capturer_.SetMinCapturePeriod(base::TimeDelta());
- ASSERT_LT(base::TimeDelta(), capturer_.oracle_.min_capture_period());
+ capturer_->SetMinCapturePeriod(base::TimeDelta());
+ ASSERT_LT(base::TimeDelta(), oracle_->min_capture_period());
- capturer_.SetResolutionConstraints(kCaptureSize, kCaptureSize, false);
+ capturer_->SetResolutionConstraints(size_set_.capture_size,
+ size_set_.capture_size, false);
}
void TearDown() override { task_runner_->ClearPendingTasks(); }
void StartCapture(MockConsumer* consumer) {
- capturer_.Start(consumer->BindVideoConsumer());
+ capturer_->Start(consumer->BindVideoConsumer());
PropagateMojoTasks();
}
void StopCapture() {
- capturer_.Stop();
+ capturer_->Stop();
PropagateMojoTasks();
}
@@ -384,7 +437,18 @@ class FrameSinkVideoCapturerTest : public testing::Test {
task_runner_->FastForwardBy(GetNextVsync() - task_runner_->NowTicks());
}
+ void SwitchToSizeSet(const SizeSet& size_set) {
+ size_set_ = size_set;
+ oracle_->set_forced_capture_size(size_set.capture_size);
+ frame_sink_.set_size_set(size_set);
+ capturer_->SetResolutionConstraints(size_set_.capture_size,
+ size_set_.capture_size, false);
+ }
+
+ const SizeSet& size_set() { return size_set_; }
+
void NotifyFrameDamaged(
+ gfx::Rect damage_rect,
float device_scale_factor = kDefaultDeviceScaleFactor,
float page_scale_factor = kDefaultPageScaleFactor,
gfx::Vector2dF root_scroll_offset = kDefaultRootScrollOffset) {
@@ -396,30 +460,37 @@ class FrameSinkVideoCapturerTest : public testing::Test {
frame_sink_.set_metadata(metadata);
- capturer_.OnFrameDamaged(kSourceSize, gfx::Rect(kSourceSize),
- GetNextVsync(), metadata);
+ capturer_->OnFrameDamaged(frame_sink_.source_size(), damage_rect,
+ GetNextVsync(), metadata);
}
void NotifyTargetWentAway() {
- capturer_.OnTargetWillGoAway();
+ capturer_->OnTargetWillGoAway();
PropagateMojoTasks();
}
bool IsRefreshRetryTimerRunning() {
- return capturer_.refresh_frame_retry_timer_->IsRunning();
+ return capturer_->refresh_frame_retry_timer_->IsRunning();
}
void AdvanceClockForRefreshTimer() {
- task_runner_->FastForwardBy(capturer_.GetDelayBeforeNextRefreshAttempt());
+ task_runner_->FastForwardBy(capturer_->GetDelayBeforeNextRefreshAttempt());
PropagateMojoTasks();
}
+ gfx::Rect ExpandRectToI420SubsampleBoundaries(const gfx::Rect& rect) {
+ return FrameSinkVideoCapturerImpl::ExpandRectToI420SubsampleBoundaries(
+ rect);
+ }
+
protected:
+ SizeSet size_set_;
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
base::TimeTicks start_time_;
MockFrameSinkManager frame_sink_manager_;
FakeCapturableFrameSink frame_sink_;
- FrameSinkVideoCapturerImpl capturer_;
+ std::unique_ptr<FrameSinkVideoCapturerImpl> capturer_;
+ InstrumentedVideoCaptureOracle* oracle_;
};
// Tests that the capturer attaches to a frame sink immediately, in the case
@@ -428,10 +499,10 @@ TEST_F(FrameSinkVideoCapturerTest, ResolvesTargetImmediately) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- EXPECT_EQ(FrameSinkId(), capturer_.requested_target());
- capturer_.ChangeTarget(kFrameSinkId);
- EXPECT_EQ(kFrameSinkId, capturer_.requested_target());
- EXPECT_EQ(&capturer_, frame_sink_.attached_client());
+ EXPECT_EQ(FrameSinkId(), capturer_->requested_target());
+ capturer_->ChangeTarget(kFrameSinkId);
+ EXPECT_EQ(kFrameSinkId, capturer_->requested_target());
+ EXPECT_EQ(capturer_.get(), frame_sink_.attached_client());
}
// Tests that the capturer attaches to a frame sink later, in the case where the
@@ -440,13 +511,13 @@ TEST_F(FrameSinkVideoCapturerTest, ResolvesTargetLater) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(nullptr));
- EXPECT_EQ(FrameSinkId(), capturer_.requested_target());
- capturer_.ChangeTarget(kFrameSinkId);
- EXPECT_EQ(kFrameSinkId, capturer_.requested_target());
+ EXPECT_EQ(FrameSinkId(), capturer_->requested_target());
+ capturer_->ChangeTarget(kFrameSinkId);
+ EXPECT_EQ(kFrameSinkId, capturer_->requested_target());
EXPECT_EQ(nullptr, frame_sink_.attached_client());
- capturer_.SetResolvedTarget(&frame_sink_);
- EXPECT_EQ(&capturer_, frame_sink_.attached_client());
+ capturer_->SetResolvedTarget(&frame_sink_);
+ EXPECT_EQ(capturer_.get(), frame_sink_.attached_client());
}
// Tests that no initial frame is sent after Start() is called until after the
@@ -456,7 +527,7 @@ TEST_F(FrameSinkVideoCapturerTest, PostponesCaptureWithoutATarget) {
.WillRepeatedly(Return(&frame_sink_));
MockConsumer consumer;
- EXPECT_CALL(consumer, OnFrameCapturedMock(_, _, _)).Times(0);
+ EXPECT_CALL(consumer, OnFrameCapturedMock()).Times(0);
EXPECT_CALL(consumer, OnStopped()).Times(1);
StartCapture(&consumer);
@@ -476,7 +547,7 @@ TEST_F(FrameSinkVideoCapturerTest, PostponesCaptureWithoutATarget) {
// Now, set the target. As it resolves, the capturer will immediately attempt
// a refresh capture, which will cancel the timer and trigger a copy request.
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
EXPECT_EQ(1, frame_sink_.num_copy_results());
EXPECT_FALSE(IsRefreshRetryTimerRunning());
@@ -492,14 +563,14 @@ TEST_F(FrameSinkVideoCapturerTest, CapturesCompositedFrames) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
EXPECT_FALSE(IsRefreshRetryTimerRunning());
MockConsumer consumer;
const int num_refresh_frames = 1;
const int num_update_frames =
3 * FrameSinkVideoCapturerImpl::kDesignLimitMaxFrames;
- EXPECT_CALL(consumer, OnFrameCapturedMock(_, _, _))
+ EXPECT_CALL(consumer, OnFrameCapturedMock())
.Times(num_refresh_frames + num_update_frames);
EXPECT_CALL(consumer, OnStopped()).Times(1);
StartCapture(&consumer);
@@ -514,7 +585,8 @@ TEST_F(FrameSinkVideoCapturerTest, CapturesCompositedFrames) {
frame_sink_.SendCopyOutputResult(0);
ASSERT_EQ(num_refresh_frames, consumer.num_frames_received());
EXPECT_THAT(consumer.TakeFrame(0),
- IsLetterboxedFrame(YUVColor{0x80, 0x80, 0x80}));
+ IsLetterboxedFrame(YUVColor{0x80, 0x80, 0x80},
+ size_set().expected_content_rect));
consumer.SendDoneNotification(0);
// Drive the capturer pipeline for a series of frame composites.
@@ -535,7 +607,7 @@ TEST_F(FrameSinkVideoCapturerTest, CapturesCompositedFrames) {
task_runner_->FastForwardBy(kVsyncInterval / 4);
const base::TimeTicks expected_capture_begin_time =
task_runner_->NowTicks();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
// The frame sink should have received a CopyOutputRequest. Simulate a short
// pause before the result is sent back to the capturer, and the capturer
@@ -549,9 +621,10 @@ TEST_F(FrameSinkVideoCapturerTest, CapturesCompositedFrames) {
// Verify the frame is the right size, has the right content, and has
// required metadata set.
const scoped_refptr<VideoFrame> frame = consumer.TakeFrame(i);
- EXPECT_THAT(frame, IsLetterboxedFrame(color));
- EXPECT_EQ(kCaptureSize, frame->coded_size());
- EXPECT_EQ(gfx::Rect(kCaptureSize), frame->visible_rect());
+ EXPECT_THAT(frame,
+ IsLetterboxedFrame(color, size_set().expected_content_rect));
+ EXPECT_EQ(size_set().capture_size, frame->coded_size());
+ EXPECT_EQ(gfx::Rect(size_set().capture_size), frame->visible_rect());
EXPECT_LT(last_timestamp, frame->timestamp());
last_timestamp = frame->timestamp();
const VideoFrameMetadata* metadata = frame->metadata();
@@ -594,7 +667,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
NiceMock<MockConsumer> consumer;
StartCapture(&consumer);
@@ -607,7 +680,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
int num_frames = FrameSinkVideoCapturerImpl::kDesignLimitMaxFrames;
for (int i = num_refresh_frames; i < num_frames; ++i) {
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
// The oracle should not be rejecting captures caused by compositor updates.
ASSERT_FALSE(IsRefreshRetryTimerRunning());
}
@@ -618,7 +691,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
// scheduled to account for the capture of changed content that could not take
// place.
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_TRUE(IsRefreshRetryTimerRunning());
@@ -628,7 +701,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
frame_sink_.SendCopyOutputResult(0);
ASSERT_EQ(1, consumer.num_frames_received());
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_TRUE(IsRefreshRetryTimerRunning());
@@ -639,7 +712,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
EXPECT_TRUE(consumer.TakeFrame(0));
consumer.SendDoneNotification(0);
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
++num_frames;
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_FALSE(IsRefreshRetryTimerRunning());
@@ -648,7 +721,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
// because the pipeline became saturated again. Once again, the refresh timer
// should be started to account for the need to capture at some future point.
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_TRUE(IsRefreshRetryTimerRunning());
@@ -661,7 +734,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
}
ASSERT_EQ(frame_sink_.num_copy_results(), consumer.num_frames_received());
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_TRUE(IsRefreshRetryTimerRunning());
@@ -673,7 +746,7 @@ TEST_F(FrameSinkVideoCapturerTest, HaltsWhenPipelineIsFull) {
consumer.SendDoneNotification(i);
}
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
++num_frames;
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
frame_sink_.SendCopyOutputResult(frame_sink_.num_copy_results() - 1);
@@ -692,7 +765,7 @@ TEST_F(FrameSinkVideoCapturerTest, DeliversFramesInOrder) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
NiceMock<MockConsumer> consumer;
StartCapture(&consumer);
@@ -709,7 +782,7 @@ TEST_F(FrameSinkVideoCapturerTest, DeliversFramesInOrder) {
static_cast<uint8_t>((i << 4) + 0x20)});
frame_sink_.SetCopyOutputColor(colors.back());
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
}
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
@@ -718,19 +791,24 @@ TEST_F(FrameSinkVideoCapturerTest, DeliversFramesInOrder) {
// each video frame is correct.
frame_sink_.SendCopyOutputResult(0);
ASSERT_EQ(1, consumer.num_frames_received());
- EXPECT_THAT(consumer.TakeFrame(0), IsLetterboxedFrame(colors[0]));
+ EXPECT_THAT(consumer.TakeFrame(0),
+ IsLetterboxedFrame(colors[0], size_set().expected_content_rect));
frame_sink_.SendCopyOutputResult(2);
ASSERT_EQ(1, consumer.num_frames_received()); // Waiting for frame 1.
frame_sink_.SendCopyOutputResult(3);
ASSERT_EQ(1, consumer.num_frames_received()); // Still waiting for frame 1.
frame_sink_.SendCopyOutputResult(1);
ASSERT_EQ(4, consumer.num_frames_received()); // Sent frames 1, 2, and 3.
- EXPECT_THAT(consumer.TakeFrame(1), IsLetterboxedFrame(colors[1]));
- EXPECT_THAT(consumer.TakeFrame(2), IsLetterboxedFrame(colors[2]));
- EXPECT_THAT(consumer.TakeFrame(3), IsLetterboxedFrame(colors[3]));
+ EXPECT_THAT(consumer.TakeFrame(1),
+ IsLetterboxedFrame(colors[1], size_set().expected_content_rect));
+ EXPECT_THAT(consumer.TakeFrame(2),
+ IsLetterboxedFrame(colors[2], size_set().expected_content_rect));
+ EXPECT_THAT(consumer.TakeFrame(3),
+ IsLetterboxedFrame(colors[3], size_set().expected_content_rect));
frame_sink_.SendCopyOutputResult(4);
ASSERT_EQ(5, consumer.num_frames_received());
- EXPECT_THAT(consumer.TakeFrame(4), IsLetterboxedFrame(colors[4]));
+ EXPECT_THAT(consumer.TakeFrame(4),
+ IsLetterboxedFrame(colors[4], size_set().expected_content_rect));
StopCapture();
}
@@ -744,11 +822,11 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
// Start capturing to the first consumer.
MockConsumer consumer;
- EXPECT_CALL(consumer, OnFrameCapturedMock(_, _, _)).Times(2);
+ EXPECT_CALL(consumer, OnFrameCapturedMock()).Times(2);
EXPECT_CALL(consumer, OnStopped()).Times(1);
StartCapture(&consumer);
// With the start, an immediate refresh should have occurred.
@@ -761,7 +839,7 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
for (int i = num_refresh_frames; i < num_copy_requests; ++i) {
SCOPED_TRACE(testing::Message() << "frame #" << i);
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
}
ASSERT_EQ(num_copy_requests, frame_sink_.num_copy_results());
@@ -771,7 +849,8 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
SCOPED_TRACE(testing::Message() << "frame #" << i);
frame_sink_.SendCopyOutputResult(i);
ASSERT_EQ(i + 1, consumer.num_frames_received());
- EXPECT_THAT(consumer.TakeFrame(i), IsLetterboxedFrame(color1));
+ EXPECT_THAT(consumer.TakeFrame(i),
+ IsLetterboxedFrame(color1, size_set().expected_content_rect));
}
// Stopping capture should cancel the remaning copy requests.
@@ -782,7 +861,7 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
frame_sink_.SetCopyOutputColor(color2);
MockConsumer consumer2;
const int num_captures_for_second_consumer = 3;
- EXPECT_CALL(consumer2, OnFrameCapturedMock(_, _, _))
+ EXPECT_CALL(consumer2, OnFrameCapturedMock())
.Times(num_captures_for_second_consumer);
EXPECT_CALL(consumer2, OnStopped()).Times(1);
StartCapture(&consumer2);
@@ -808,7 +887,7 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
if (i == 0) {
// Expect that advancing the clock caused the refresh timer to fire.
} else {
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
}
++num_copy_requests;
ASSERT_EQ(num_copy_requests, frame_sink_.num_copy_results());
@@ -817,7 +896,7 @@ TEST_F(FrameSinkVideoCapturerTest, CancelsInFlightCapturesOnStop) {
++num_completed_captures;
ASSERT_EQ(num_completed_captures, consumer2.num_frames_received());
EXPECT_THAT(consumer2.TakeFrame(consumer2.num_frames_received() - 1),
- IsLetterboxedFrame(color2));
+ IsLetterboxedFrame(color2, size_set().expected_content_rect));
}
StopCapture();
@@ -830,12 +909,12 @@ TEST_F(FrameSinkVideoCapturerTest, EventuallySendsARefreshFrame) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
MockConsumer consumer;
const int num_refresh_frames = 2; // Initial, plus later refresh.
const int num_update_frames = 3;
- EXPECT_CALL(consumer, OnFrameCapturedMock(_, _, _))
+ EXPECT_CALL(consumer, OnFrameCapturedMock())
.Times(num_refresh_frames + num_update_frames);
EXPECT_CALL(consumer, OnStopped()).Times(1);
StartCapture(&consumer);
@@ -852,7 +931,7 @@ TEST_F(FrameSinkVideoCapturerTest, EventuallySendsARefreshFrame) {
int num_frames = 1 + num_update_frames;
for (int i = 1; i < num_frames; ++i) {
AdvanceClockToNextVsync();
- NotifyFrameDamaged();
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size));
ASSERT_EQ(i + 1, frame_sink_.num_copy_results());
ASSERT_FALSE(IsRefreshRetryTimerRunning());
frame_sink_.SendCopyOutputResult(i);
@@ -862,7 +941,7 @@ TEST_F(FrameSinkVideoCapturerTest, EventuallySendsARefreshFrame) {
// Request a refresh frame. Because the refresh request was made just after
// the last frame capture, the refresh retry timer should be started.
- capturer_.RequestRefreshFrame();
+ capturer_->RequestRefreshFrame();
ASSERT_EQ(num_frames, frame_sink_.num_copy_results());
EXPECT_TRUE(IsRefreshRetryTimerRunning());
@@ -885,13 +964,13 @@ TEST_F(FrameSinkVideoCapturerTest, EventuallySendsARefreshFrame) {
TEST_F(FrameSinkVideoCapturerTest, CompositorFrameMetadataReachesConsumer) {
EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
.WillRepeatedly(Return(&frame_sink_));
- capturer_.ChangeTarget(kFrameSinkId);
+ capturer_->ChangeTarget(kFrameSinkId);
MockConsumer consumer;
// Initial refresh frame for starting capture, plus later refresh.
const int num_refresh_frames = 2;
const int num_update_frames = 1;
- EXPECT_CALL(consumer, OnFrameCapturedMock(_, _, _))
+ EXPECT_CALL(consumer, OnFrameCapturedMock())
.Times(num_refresh_frames + num_update_frames);
EXPECT_CALL(consumer, OnStopped()).Times(1);
StartCapture(&consumer);
@@ -916,10 +995,11 @@ TEST_F(FrameSinkVideoCapturerTest, CompositorFrameMetadataReachesConsumer) {
// Notify frame damage with new metadata, and expect that the refresh frame
// is delivered to the consumer with this new metadata.
AdvanceClockToNextVsync();
- NotifyFrameDamaged(kNewDeviceScaleFactor, kNewPageScaleFactor,
- kNewRootScrollOffset);
+ NotifyFrameDamaged(gfx::Rect(size_set().source_size), kNewDeviceScaleFactor,
+ kNewPageScaleFactor, kNewRootScrollOffset);
frame_sink_.SendCopyOutputResult(++cur_frame_index);
- EXPECT_EQ(++expected_frames_count, consumer.num_frames_received());
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
EXPECT_TRUE(CompareVarsInCompositorFrameMetadata(
*(consumer.TakeFrame(cur_frame_index)), kNewDeviceScaleFactor,
kNewPageScaleFactor, kNewRootScrollOffset));
@@ -929,13 +1009,209 @@ TEST_F(FrameSinkVideoCapturerTest, CompositorFrameMetadataReachesConsumer) {
// the last frame capture, the refresh retry timer should be started.
// Expect that the refresh frame is delivered to the consumer with the same
// metadata from the previous frame.
- capturer_.RequestRefreshFrame();
+ capturer_->RequestRefreshFrame();
AdvanceClockForRefreshTimer();
- EXPECT_EQ(++expected_frames_count, consumer.num_frames_received());
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
EXPECT_TRUE(CompareVarsInCompositorFrameMetadata(
*(consumer.TakeFrame(++cur_frame_index)), kNewDeviceScaleFactor,
kNewPageScaleFactor, kNewRootScrollOffset));
StopCapture();
}
+// Tests that frame metadata CAPTURE_COUNTER and CAPTURE_UPDATE_RECT are sent to
+// the consumer as part of each frame delivery.
+TEST_F(FrameSinkVideoCapturerTest, DeliversUpdateRectAndCaptureCounter) {
+ EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
+ .WillRepeatedly(Return(&frame_sink_));
+ capturer_->ChangeTarget(kFrameSinkId);
+
+ MockConsumer consumer;
+ StartCapture(&consumer);
+
+ // With the start, an immediate refresh occurred. Simulate a copy result.
+ // Expect to see the refresh frame delivered to the consumer, along with
+ // default metadata values.
+ int cur_capture_index = 0, cur_frame_index = 0, expected_frames_count = 1,
+ previous_capture_counter_received = 0;
+ frame_sink_.SendCopyOutputResult(cur_capture_index);
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(cur_frame_index);
+ gfx::Rect received_update_rect;
+ int received_capture_counter = 0;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_EQ(gfx::Rect(size_set().capture_size), received_update_rect);
+ previous_capture_counter_received = received_capture_counter;
+ }
+ consumer.SendDoneNotification(cur_frame_index);
+
+ const gfx::Rect kSourceDamageRect = gfx::Rect(3, 7, 60, 45);
+ gfx::Rect expected_frame_update_rect = copy_output::ComputeResultRect(
+ kSourceDamageRect,
+ gfx::Vector2d(size_set().source_size.width(),
+ size_set().source_size.height()),
+ gfx::Vector2d(size_set().expected_content_rect.width(),
+ size_set().expected_content_rect.height()));
+ expected_frame_update_rect.Offset(
+ size_set().expected_content_rect.OffsetFromOrigin());
+ EXPECT_FALSE(AlignsWithI420SubsamplingBoundaries(expected_frame_update_rect));
+ expected_frame_update_rect =
+ ExpandRectToI420SubsampleBoundaries(expected_frame_update_rect);
+ EXPECT_TRUE(AlignsWithI420SubsamplingBoundaries(expected_frame_update_rect));
+
+ // Notify frame damage with custom damage rect, and expect that the refresh
+ // frame is delivered to the consumer with a corresponding |update_rect|.
+ AdvanceClockToNextVsync();
+ NotifyFrameDamaged(kSourceDamageRect);
+ frame_sink_.SendCopyOutputResult(++cur_capture_index);
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(++cur_frame_index);
+ int received_capture_counter = 0;
+ gfx::Rect received_update_rect;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_EQ(expected_frame_update_rect, received_update_rect);
+ EXPECT_EQ(previous_capture_counter_received + 1, received_capture_counter);
+ previous_capture_counter_received = received_capture_counter;
+ }
+ consumer.SendDoneNotification(cur_frame_index);
+
+ // Request a refresh frame. Because the refresh request was made just after
+ // the last frame capture, the refresh retry timer should be started.
+ // Since there was no damage to the source, expect that the |update_region|
+ // delivered to the consumer is empty.
+ capturer_->RequestRefreshFrame();
+ AdvanceClockForRefreshTimer();
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(++cur_frame_index);
+ int received_capture_counter = 0;
+ gfx::Rect received_update_rect;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_TRUE(received_update_rect.IsEmpty());
+ EXPECT_EQ(previous_capture_counter_received + 1, received_capture_counter);
+ previous_capture_counter_received = received_capture_counter;
+ }
+ consumer.SendDoneNotification(cur_frame_index);
+
+ // If we do not advance the clock, the oracle will reject capture due to
+ // frame rate limits.
+ AdvanceClockToNextVsync();
+ // Simulate a change in the source size.
+ // This is expected to trigger a refresh capture.
+ SwitchToSizeSet(kSizeSets[1]);
+ frame_sink_.SendCopyOutputResult(++cur_capture_index);
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(++cur_frame_index);
+ int received_capture_counter = 0;
+ gfx::Rect received_update_rect;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_EQ(gfx::Rect(size_set().capture_size), received_update_rect);
+ EXPECT_EQ(previous_capture_counter_received + 1, received_capture_counter);
+ previous_capture_counter_received = received_capture_counter;
+ }
+ consumer.SendDoneNotification(cur_frame_index);
+
+ // If we do not advance the clock, the oracle will reject capture due to
+ // frame rate.
+ AdvanceClockToNextVsync();
+ // Simulate a change in the capture size.
+ // This is expected to trigger a refresh capture.
+ SwitchToSizeSet(kSizeSets[2]);
+ frame_sink_.SendCopyOutputResult(++cur_capture_index);
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(++cur_frame_index);
+ int received_capture_counter = 0;
+ gfx::Rect received_update_rect;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_EQ(gfx::Rect(size_set().capture_size), received_update_rect);
+ EXPECT_EQ(previous_capture_counter_received + 1, received_capture_counter);
+ previous_capture_counter_received = received_capture_counter;
+ }
+
+ StopCapture();
+}
+
+// Tests that when captured frames being dropped before delivery, the
+// CAPTURE_COUNTER metadata value sent to the consumer reflects the frame drops
+// indicating that CAPTURE_UPDATE_RECT must be ignored.
+TEST_F(FrameSinkVideoCapturerTest, CaptureCounterSkipsWhenFramesAreDropped) {
+ EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(kFrameSinkId))
+ .WillRepeatedly(Return(&frame_sink_));
+ capturer_->ChangeTarget(kFrameSinkId);
+
+ MockConsumer consumer;
+ StartCapture(&consumer);
+
+ // With the start, an immediate refresh occurred. Simulate a copy result.
+ // Expect to see the refresh frame delivered to the consumer, along with
+ // default metadata values.
+ int cur_capture_frame_index = 0, cur_receive_frame_index = 0,
+ expected_frames_count = 1, previous_capture_counter_received = 0;
+ frame_sink_.SendCopyOutputResult(cur_capture_frame_index);
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(cur_receive_frame_index);
+ int received_capture_counter = 0;
+ gfx::Rect received_update_rect;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ ASSERT_TRUE(received_frame->metadata()->GetRect(
+ media::VideoFrameMetadata::CAPTURE_UPDATE_RECT, &received_update_rect));
+ EXPECT_EQ(gfx::Rect(size_set().capture_size), received_update_rect);
+ previous_capture_counter_received = received_capture_counter;
+ }
+ consumer.SendDoneNotification(cur_receive_frame_index);
+
+ const gfx::Rect kArbitraryDamageRect1 = gfx::Rect(1, 2, 6, 6);
+ const gfx::Rect kArbitraryDamageRect2 = gfx::Rect(3, 7, 5, 5);
+
+ // Notify frame damage with custom damage rect, but have oracle reject frame
+ // delivery. Expect that no frame is sent to the consumer.
+ oracle_->set_return_false_on_complete_capture(true);
+ AdvanceClockToNextVsync();
+ NotifyFrameDamaged(kArbitraryDamageRect1);
+ frame_sink_.SendCopyOutputResult(++cur_capture_frame_index);
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+
+ // Another frame damage with a different rect is reported. This time the
+ // oracle accepts frame delivery.
+ oracle_->set_return_false_on_complete_capture(false);
+ AdvanceClockToNextVsync();
+ NotifyFrameDamaged(kArbitraryDamageRect2);
+ frame_sink_.SendCopyOutputResult(++cur_capture_frame_index);
+ ++expected_frames_count;
+ EXPECT_EQ(expected_frames_count, consumer.num_frames_received());
+ {
+ auto received_frame = consumer.TakeFrame(++cur_receive_frame_index);
+ int received_capture_counter = 0;
+ ASSERT_TRUE(received_frame->metadata()->GetInteger(
+ media::VideoFrameMetadata::CAPTURE_COUNTER, &received_capture_counter));
+ EXPECT_NE(previous_capture_counter_received + 1, received_capture_counter);
+ }
+ StopCapture();
+}
+
} // namespace viz
diff --git a/chromium/components/viz/service/frame_sinks/video_capture/video_capture_overlay_unittest.cc b/chromium/components/viz/service/frame_sinks/video_capture/video_capture_overlay_unittest.cc
index 849345524b6..2ebef7cce42 100644
--- a/chromium/components/viz/service/frame_sinks/video_capture/video_capture_overlay_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/video_capture/video_capture_overlay_unittest.cc
@@ -555,7 +555,7 @@ TEST_P(VideoCaptureOverlayRenderTest, ClipsToContentBounds) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
VideoCaptureOverlayRenderTest,
testing::Values(VideoCaptureOverlayRenderTest::kARGBFormat,
diff --git a/chromium/components/viz/service/frame_sinks/video_detector_unittest.cc b/chromium/components/viz/service/frame_sinks/video_detector_unittest.cc
index db249d5b97c..484cac1b3be 100644
--- a/chromium/components/viz/service/frame_sinks/video_detector_unittest.cc
+++ b/chromium/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -19,6 +19,7 @@
#include "components/viz/service/frame_sinks/video_detector.h"
#include "components/viz/test/compositor_frame_helpers.h"
#include "components/viz/test/fake_compositor_frame_sink_client.h"
+#include "components/viz/test/surface_id_allocator_set.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/viz/public/interfaces/compositing/video_detector_observer.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -95,10 +96,11 @@ class VideoDetectorTest : public testing::Test {
detector_->AddObserver(std::move(video_detector_observer));
root_frame_sink_ = CreateFrameSink();
- parent_local_surface_id_allocator_.GenerateId();
+ ParentLocalSurfaceIdAllocator* allocator =
+ allocators_.GetAllocator(root_frame_sink_->frame_sink_id());
+ allocator->GenerateId();
root_frame_sink_->SubmitCompositorFrame(
- parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
- .local_surface_id(),
+ allocator->GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
MakeDefaultCompositorFrame());
}
@@ -150,10 +152,11 @@ class VideoDetectorTest : public testing::Test {
LocalSurfaceId local_surface_id =
frame_sink->last_activated_local_surface_id();
if (!local_surface_id.is_valid()) {
- parent_local_surface_id_allocator_.GenerateId();
- local_surface_id = parent_local_surface_id_allocator_
- .GetCurrentLocalSurfaceIdAllocation()
- .local_surface_id();
+ ParentLocalSurfaceIdAllocator* allocator =
+ allocators_.GetAllocator(frame_sink->frame_sink_id());
+ allocator->GenerateId();
+ local_surface_id =
+ allocator->GetCurrentLocalSurfaceIdAllocation().local_surface_id();
}
frame_sink->SubmitCompositorFrame(local_surface_id,
MakeDamagedCompositorFrame(damage));
@@ -205,7 +208,7 @@ class VideoDetectorTest : public testing::Test {
ServerSharedBitmapManager shared_bitmap_manager_;
FrameSinkManagerImpl frame_sink_manager_;
FakeCompositorFrameSinkClient frame_sink_client_;
- ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
+ SurfaceIdAllocatorSet allocators_;
SurfaceAggregator surface_aggregator_;
std::unique_ptr<CompositorFrameSinkSupport> root_frame_sink_;
std::set<CompositorFrameSinkSupport*> embedded_clients_;
diff --git a/chromium/components/viz/service/gl/gpu_service_impl.cc b/chromium/components/viz/service/gl/gpu_service_impl.cc
index 645131b48b7..2c29bf93f5d 100644
--- a/chromium/components/viz/service/gl/gpu_service_impl.cc
+++ b/chromium/components/viz/service/gl/gpu_service_impl.cc
@@ -190,6 +190,7 @@ GpuServiceImpl::~GpuServiceImpl() {
// Scheduler must be destroyed before sync point manager is destroyed.
scheduler_.reset();
owned_sync_point_manager_.reset();
+ owned_shared_image_manager_.reset();
// Signal this event before destroying the child process. That way all
// background threads can cleanup. For example, in the renderer the
@@ -223,6 +224,7 @@ void GpuServiceImpl::InitializeWithHost(
gpu::GpuProcessActivityFlags activity_flags,
scoped_refptr<gl::GLSurface> default_offscreen_surface,
gpu::SyncPointManager* sync_point_manager,
+ gpu::SharedImageManager* shared_image_manager,
base::WaitableEvent* shutdown_event) {
DCHECK(main_runner_->BelongsToCurrentThread());
gpu_host->DidInitialize(gpu_info_, gpu_feature_info_,
@@ -239,10 +241,17 @@ void GpuServiceImpl::InitializeWithHost(
logging::SetLogMessageHandler(GpuLogMessageHandler);
}
- sync_point_manager_ = sync_point_manager;
- if (!sync_point_manager_) {
+ if (!sync_point_manager) {
owned_sync_point_manager_ = std::make_unique<gpu::SyncPointManager>();
- sync_point_manager_ = owned_sync_point_manager_.get();
+ sync_point_manager = owned_sync_point_manager_.get();
+ }
+
+ if (!shared_image_manager) {
+ // The shared image will be only used on GPU main thread, so it doesn't need
+ // to be thread safe.
+ owned_shared_image_manager_ =
+ std::make_unique<gpu::SharedImageManager>(false /* thread_safe */);
+ shared_image_manager = owned_shared_image_manager_.get();
}
shutdown_event_ = shutdown_event;
@@ -254,7 +263,7 @@ void GpuServiceImpl::InitializeWithHost(
}
scheduler_ =
- std::make_unique<gpu::Scheduler>(main_runner_, sync_point_manager_);
+ std::make_unique<gpu::Scheduler>(main_runner_, sync_point_manager);
skia_output_surface_sequence_id_ =
scheduler_->CreateSequence(gpu::SchedulingPriority::kHigh);
@@ -264,9 +273,9 @@ void GpuServiceImpl::InitializeWithHost(
// initialization has succeeded.
gpu_channel_manager_ = std::make_unique<gpu::GpuChannelManager>(
gpu_preferences_, this, watchdog_thread_.get(), main_runner_, io_runner_,
- scheduler_.get(), sync_point_manager_, gpu_memory_buffer_factory_.get(),
- gpu_feature_info_, std::move(activity_flags),
- std::move(default_offscreen_surface),
+ scheduler_.get(), sync_point_manager, shared_image_manager,
+ gpu_memory_buffer_factory_.get(), gpu_feature_info_,
+ std::move(activity_flags), std::move(default_offscreen_surface),
nullptr /* image_decode_accelerator_worker */, vulkan_context_provider());
media_gpu_channel_manager_.reset(
@@ -624,6 +633,8 @@ void GpuServiceImpl::SendCreatedChildWindow(gpu::SurfaceHandle parent_window,
void GpuServiceImpl::SetActiveURL(const GURL& url) {
DCHECK(main_runner_->BelongsToCurrentThread());
+ // Note that the url is intentionally excluded from webview crash dumps
+ // using a whitelist for privacy reasons. See kWebViewCrashKeyWhiteList.
static crash_reporter::CrashKeyString<1024> crash_key("url-chunk");
crash_key.Set(url.possibly_invalid_spec());
}
diff --git a/chromium/components/viz/service/gl/gpu_service_impl.h b/chromium/components/viz/service/gl/gpu_service_impl.h
index 691f2e2dc04..fdee651d96a 100644
--- a/chromium/components/viz/service/gl/gpu_service_impl.h
+++ b/chromium/components/viz/service/gl/gpu_service_impl.h
@@ -44,6 +44,7 @@ class GpuMemoryBufferFactory;
class GpuWatchdogThread;
class Scheduler;
class SyncPointManager;
+class SharedImageManager;
class VulkanImplementation;
} // namespace gpu
@@ -85,6 +86,7 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
gpu::GpuProcessActivityFlags activity_flags,
scoped_refptr<gl::GLSurface> default_offscreen_surface,
gpu::SyncPointManager* sync_point_manager = nullptr,
+ gpu::SharedImageManager* shared_image_manager = nullptr,
base::WaitableEvent* shutdown_event = nullptr);
void Bind(mojom::GpuServiceRequest request);
@@ -98,6 +100,66 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
// accordingly. This can safely be called from any thread.
void DisableGpuCompositing();
+ // mojom::GpuService:
+ void EstablishGpuChannel(int32_t client_id,
+ uint64_t client_tracing_id,
+ bool is_gpu_host,
+ bool cache_shaders_on_disk,
+ EstablishGpuChannelCallback callback) override;
+ void CloseChannel(int32_t client_id) override;
+#if defined(OS_CHROMEOS)
+ void CreateArcVideoDecodeAccelerator(
+ arc::mojom::VideoDecodeAcceleratorRequest vda_request) override;
+ void CreateArcVideoEncodeAccelerator(
+ arc::mojom::VideoEncodeAcceleratorRequest vea_request) override;
+ void CreateArcVideoProtectedBufferAllocator(
+ arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) override;
+ void CreateArcProtectedBufferManager(
+ arc::mojom::ProtectedBufferManagerRequest pbm_request) override;
+#endif // defined(OS_CHROMEOS)
+ void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
+ void CreateJpegEncodeAccelerator(
+ media::mojom::JpegEncodeAcceleratorRequest jea_request) override;
+ void CreateVideoEncodeAcceleratorProvider(
+ media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
+ override;
+ void CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ int client_id,
+ gpu::SurfaceHandle surface_handle,
+ CreateGpuMemoryBufferCallback callback) override;
+ void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
+ int client_id,
+ const gpu::SyncToken& sync_token) override;
+ void GetVideoMemoryUsageStats(
+ GetVideoMemoryUsageStatsCallback callback) override;
+#if defined(OS_WIN)
+ void RequestCompleteGpuInfo(RequestCompleteGpuInfoCallback callback) override;
+ void GetGpuSupportedRuntimeVersion(
+ GetGpuSupportedRuntimeVersionCallback callback) override;
+#endif
+ void RequestHDRStatus(RequestHDRStatusCallback callback) override;
+ void LoadedShader(int32_t client_id,
+ const std::string& key,
+ const std::string& data) override;
+ void WakeUpGpu() override;
+ void GpuSwitched() override;
+ void DestroyAllChannels() override;
+ void OnBackgroundCleanup() override;
+ void OnBackgrounded() override;
+ void OnForegrounded() override;
+#if defined(OS_MACOSX)
+ void BeginCATransaction() override;
+ void CommitCATransaction(CommitCATransactionCallback callback) override;
+#endif
+ void Crash() override;
+ void Hang() override;
+ void ThrowJavaException() override;
+ void Stop(StopCallback callback) override;
+
bool is_initialized() const { return !!gpu_host_; }
media::MediaGpuChannelManager* media_gpu_channel_manager() {
@@ -129,7 +191,9 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
return gpu_channel_manager_->gr_shader_cache();
}
- gpu::SyncPointManager* sync_point_manager() { return sync_point_manager_; }
+ gpu::SyncPointManager* sync_point_manager() {
+ return gpu_channel_manager_->sync_point_manager();
+ }
gpu::Scheduler* scheduler() { return scheduler_.get(); }
gpu::GpuWatchdogThread* watchdog_thread() { return watchdog_thread_.get(); }
@@ -189,66 +253,6 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
#endif
void SetActiveURL(const GURL& url) override;
- // mojom::GpuService:
- void EstablishGpuChannel(int32_t client_id,
- uint64_t client_tracing_id,
- bool is_gpu_host,
- bool cache_shaders_on_disk,
- EstablishGpuChannelCallback callback) override;
- void CloseChannel(int32_t client_id) override;
-#if defined(OS_CHROMEOS)
- void CreateArcVideoDecodeAccelerator(
- arc::mojom::VideoDecodeAcceleratorRequest vda_request) override;
- void CreateArcVideoEncodeAccelerator(
- arc::mojom::VideoEncodeAcceleratorRequest vea_request) override;
- void CreateArcVideoProtectedBufferAllocator(
- arc::mojom::VideoProtectedBufferAllocatorRequest pba_request) override;
- void CreateArcProtectedBufferManager(
- arc::mojom::ProtectedBufferManagerRequest pbm_request) override;
-#endif // defined(OS_CHROMEOS)
- void CreateJpegDecodeAccelerator(
- media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
- void CreateJpegEncodeAccelerator(
- media::mojom::JpegEncodeAcceleratorRequest jea_request) override;
- void CreateVideoEncodeAcceleratorProvider(
- media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
- override;
- void CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- int client_id,
- gpu::SurfaceHandle surface_handle,
- CreateGpuMemoryBufferCallback callback) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- int client_id,
- const gpu::SyncToken& sync_token) override;
- void GetVideoMemoryUsageStats(
- GetVideoMemoryUsageStatsCallback callback) override;
-#if defined(OS_WIN)
- void RequestCompleteGpuInfo(RequestCompleteGpuInfoCallback callback) override;
- void GetGpuSupportedRuntimeVersion(
- GetGpuSupportedRuntimeVersionCallback callback) override;
-#endif
- void RequestHDRStatus(RequestHDRStatusCallback callback) override;
- void LoadedShader(int32_t client_id,
- const std::string& key,
- const std::string& data) override;
- void WakeUpGpu() override;
- void GpuSwitched() override;
- void DestroyAllChannels() override;
- void OnBackgroundCleanup() override;
- void OnBackgrounded() override;
- void OnForegrounded() override;
-#if defined(OS_MACOSX)
- void BeginCATransaction() override;
- void CommitCATransaction(CommitCATransactionCallback callback) override;
-#endif
- void Crash() override;
- void Hang() override;
- void ThrowJavaException() override;
- void Stop(StopCallback callback) override;
-
#if defined(OS_CHROMEOS)
void CreateArcVideoDecodeAcceleratorOnMainThread(
arc::mojom::VideoDecodeAcceleratorRequest vda_request);
@@ -292,10 +296,11 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
std::unique_ptr<gpu::GpuChannelManager> gpu_channel_manager_;
std::unique_ptr<media::MediaGpuChannelManager> media_gpu_channel_manager_;
- // On some platforms (e.g. android webview), the SyncPointManager comes from
- // external sources.
+ // On some platforms (e.g. android webview), the SyncPointManager and
+ // SharedImageManager comes from external sources.
std::unique_ptr<gpu::SyncPointManager> owned_sync_point_manager_;
- gpu::SyncPointManager* sync_point_manager_ = nullptr;
+
+ std::unique_ptr<gpu::SharedImageManager> owned_shared_image_manager_;
std::unique_ptr<gpu::Scheduler> scheduler_;
diff --git a/chromium/components/viz/service/gl/gpu_service_impl_unittest.cc b/chromium/components/viz/service/gl/gpu_service_impl_unittest.cc
index 5e86a3f910c..399eaaa0baa 100644
--- a/chromium/components/viz/service/gl/gpu_service_impl_unittest.cc
+++ b/chromium/components/viz/service/gl/gpu_service_impl_unittest.cc
@@ -6,6 +6,8 @@
#include <memory>
+#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/components/viz/service/hit_test/hit_test_aggregator_unittest.cc b/chromium/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
index cbcf0ba8d52..e7071c4c031 100644
--- a/chromium/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
+++ b/chromium/components/viz/service/hit_test/hit_test_aggregator_unittest.cc
@@ -17,6 +17,7 @@
#include "components/viz/service/hit_test/hit_test_aggregator_delegate.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/test/compositor_frame_helpers.h"
+#include "components/viz/test/surface_id_allocator_set.h"
#include "components/viz/test/test_latest_local_surface_id_lookup_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -26,12 +27,6 @@ namespace {
constexpr uint32_t kDisplayClientId = 2;
constexpr FrameSinkId kDisplayFrameSink(kDisplayClientId, 0);
-SurfaceId MakeSurfaceId(uint32_t frame_sink_id_client_id) {
- return SurfaceId(
- FrameSinkId(frame_sink_id_client_id, 0),
- LocalSurfaceId(1, base::UnguessableToken::Deserialize(0, 1u)));
-}
-
// TODO(riajiang): TestHostFrameSinkManager should be based on
// mojom::FrameSinkManagerClient instead.
class TestHostFrameSinkManager : public HostFrameSinkManager {
@@ -186,6 +181,11 @@ class HitTestAggregatorTest : public testing::Test {
return client_id;
}
+ SurfaceId MakeSurfaceId(uint32_t frame_sink_id_client_id) {
+ return allocator_set_.MakeSurfaceId(FrameSinkId(frame_sink_id_client_id, 0),
+ 1);
+ }
+
protected:
TestHitTestAggregator* hit_test_aggregator() {
return hit_test_aggregator_.get();
@@ -226,6 +226,7 @@ class HitTestAggregatorTest : public testing::Test {
std::unique_ptr<TestLatestLocalSurfaceIdLookupDelegate>
local_surface_id_lookup_delegate_;
std::unique_ptr<CompositorFrameSinkSupport> support_;
+ SurfaceIdAllocatorSet allocator_set_;
DISALLOW_COPY_AND_ASSIGN(HitTestAggregatorTest);
};
diff --git a/chromium/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java b/chromium/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java
index c53e1d6b4c5..4d3d3c4acc4 100644
--- a/chromium/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java
+++ b/chromium/components/viz/service/java/src/org/chromium/components/viz/service/frame_sinks/ExternalBeginFrameSourceAndroid.java
@@ -32,9 +32,11 @@ public class ExternalBeginFrameSourceAndroid {
};
@CalledByNative
- private ExternalBeginFrameSourceAndroid(long nativeExternalBeginFrameSourceAndroid) {
+ private ExternalBeginFrameSourceAndroid(
+ long nativeExternalBeginFrameSourceAndroid, float refreshRate) {
mNativeExternalBeginFrameSourceAndroid = nativeExternalBeginFrameSourceAndroid;
- mVSyncMonitor = new VSyncMonitor(ContextUtils.getApplicationContext(), mVSyncListener);
+ mVSyncMonitor =
+ new VSyncMonitor(ContextUtils.getApplicationContext(), mVSyncListener, refreshRate);
}
@CalledByNative
@@ -49,6 +51,11 @@ public class ExternalBeginFrameSourceAndroid {
}
}
+ @CalledByNative
+ private void updateRefreshRate(float refreshRate) {
+ mVSyncMonitor.updateRefreshRate(refreshRate);
+ }
+
private native void nativeOnVSync(long nativeExternalBeginFrameSourceAndroid,
long vsyncTimeMicros, long vsyncPeriodMicros);
};
diff --git a/chromium/components/viz/service/main/BUILD.gn b/chromium/components/viz/service/main/BUILD.gn
index 13b0a2796ab..6a7c537caaa 100644
--- a/chromium/components/viz/service/main/BUILD.gn
+++ b/chromium/components/viz/service/main/BUILD.gn
@@ -4,8 +4,6 @@
import("//build/config/ui.gni")
import("//components/ui_devtools/devtools.gni")
-import("//services/catalog/public/tools/catalog.gni")
-import("//services/service_manager/public/service_manifest.gni")
import("//testing/test.gni")
source_set("main") {
diff --git a/chromium/components/viz/service/main/viz_compositor_thread_runner.cc b/chromium/components/viz/service/main/viz_compositor_thread_runner.cc
index f40ccebabf2..6e0a544f269 100644
--- a/chromium/components/viz/service/main/viz_compositor_thread_runner.cc
+++ b/chromium/components/viz/service/main/viz_compositor_thread_runner.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
@@ -48,15 +49,12 @@ std::unique_ptr<VizCompositorThreadType> CreateAndStartCompositorThread() {
auto thread = std::make_unique<base::Thread>(kThreadName);
base::Thread::Options thread_options;
-#if defined(OS_WIN)
- // Windows needs a UI message loop for child HWND.
- thread_options.message_loop_type = base::MessageLoop::TYPE_UI;
-#elif defined(USE_OZONE)
+#if defined(USE_OZONE)
// We may need a non-default message loop type for the platform surface.
thread_options.message_loop_type =
ui::OzonePlatform::GetInstance()->GetMessageLoopTypeForGpu();
#endif
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(USE_OZONE)
thread_options.priority = base::ThreadPriority::DISPLAY;
#endif
diff --git a/chromium/components/viz/service/main/viz_main_impl.cc b/chromium/components/viz/service/main/viz_main_impl.cc
index 543d2dc3040..2b1af6b1a84 100644
--- a/chromium/components/viz/service/main/viz_main_impl.cc
+++ b/chromium/components/viz/service/main/viz_main_impl.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/single_thread_task_runner.h"
@@ -35,7 +36,7 @@ std::unique_ptr<base::Thread> CreateAndStartIOThread() {
// It should be possible to use |main_task_runner_| for doing IO tasks.
base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
thread_options.priority = base::ThreadPriority::NORMAL;
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(USE_OZONE)
// TODO(reveman): Remove this in favor of setting it explicitly for each
// type of process.
thread_options.priority = base::ThreadPriority::DISPLAY;
@@ -196,7 +197,8 @@ void VizMainImpl::CreateGpuService(
std::move(gpu_host),
gpu::GpuProcessActivityFlags(std::move(activity_flags)),
gpu_init_->TakeDefaultOffscreenSurface(),
- dependencies_.sync_point_manager, dependencies_.shutdown_event);
+ dependencies_.sync_point_manager, dependencies_.shared_image_manager,
+ dependencies_.shutdown_event);
if (!pending_frame_sink_manager_params_.is_null()) {
CreateFrameSinkManagerInternal(
diff --git a/chromium/components/viz/service/main/viz_main_impl.h b/chromium/components/viz/service/main/viz_main_impl.h
index f8d3c8a0345..5c7dbd94351 100644
--- a/chromium/components/viz/service/main/viz_main_impl.h
+++ b/chromium/components/viz/service/main/viz_main_impl.h
@@ -28,6 +28,7 @@
namespace gpu {
class GpuInit;
class SyncPointManager;
+class SharedImageManager;
} // namespace gpu
namespace service_manager {
@@ -77,6 +78,7 @@ class VizMainImpl : public mojom::VizMain {
bool create_display_compositor = false;
gpu::SyncPointManager* sync_point_manager = nullptr;
+ gpu::SharedImageManager* shared_image_manager = nullptr;
base::WaitableEvent* shutdown_event = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner;
service_manager::Connector* connector = nullptr;
diff --git a/chromium/components/viz/service/surfaces/surface.cc b/chromium/components/viz/service/surfaces/surface.cc
index 196879a0219..9c101cc38e1 100644
--- a/chromium/components/viz/service/surfaces/surface.cc
+++ b/chromium/components/viz/service/surfaces/surface.cc
@@ -17,6 +17,7 @@
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/service/surfaces/referenced_surface_tracker.h"
+#include "components/viz/service/surfaces/surface_allocation_group.h"
#include "components/viz/service/surfaces/surface_client.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/service/viz_service_export.h"
@@ -26,6 +27,7 @@ namespace viz {
Surface::Surface(const SurfaceInfo& surface_info,
SurfaceManager* surface_manager,
+ SurfaceAllocationGroup* allocation_group,
base::WeakPtr<SurfaceClient> surface_client,
bool needs_sync_tokens,
bool block_activation_on_parent)
@@ -33,10 +35,12 @@ Surface::Surface(const SurfaceInfo& surface_info,
surface_manager_(surface_manager),
surface_client_(std::move(surface_client)),
needs_sync_tokens_(needs_sync_tokens),
- block_activation_on_parent_(block_activation_on_parent) {
+ block_activation_on_parent_(block_activation_on_parent),
+ allocation_group_(allocation_group) {
TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("viz.surface_lifetime"),
"Surface", this, "surface_info",
surface_info.ToString());
+ allocation_group_->RegisterSurface(this);
}
Surface::~Surface() {
@@ -59,6 +63,7 @@ Surface::~Surface() {
TRACE_EVENT_ASYNC_END1(TRACE_DISABLED_BY_DEFAULT("viz.surface_lifetime"),
"Surface", this, "surface_info",
surface_info_.ToString());
+ allocation_group_->UnregisterSurface(this);
}
void Surface::SetDependencyDeadline(
@@ -297,27 +302,45 @@ void Surface::NotifySurfaceIdAvailable(const SurfaceId& surface_id) {
if (it == frame_sink_id_dependencies_.end())
return;
- if (surface_id.local_surface_id().parent_sequence_number() >=
- it->second.parent_sequence_number &&
- surface_id.local_surface_id().child_sequence_number() >=
- it->second.child_sequence_number) {
+ if (surface_id.local_surface_id().parent_sequence_number() >
+ it->second.parent_sequence_number ||
+ surface_id.local_surface_id().child_sequence_number() >
+ it->second.child_sequence_number ||
+ (surface_id.local_surface_id().parent_sequence_number() ==
+ it->second.parent_sequence_number &&
+ surface_id.local_surface_id().child_sequence_number() ==
+ it->second.child_sequence_number)) {
frame_sink_id_dependencies_.erase(it);
surface_manager_->SurfaceDependenciesChanged(this, {},
{surface_id.frame_sink_id()});
}
- // LocalSurfaceIds of a given FrameSinkId are monotonically increasing in time
- // so if LocalSurfaceId j arrives then all LocalSurfaceIds i<j will never
- // arrive and so we just drop these invalid activation dependencies here.
// TODO(fsamuel): This is a linear scan which is probably fine today because
// a given surface has a small number of dependencies. We might need to
// revisit this in the future if the number of dependencies grows
// significantly.
- base::EraseIf(
- activation_dependencies_, [surface_id](const SurfaceId& dependency) {
- return dependency.frame_sink_id() == surface_id.frame_sink_id() &&
- dependency.local_surface_id() <= surface_id.local_surface_id();
- });
+ auto delete_fn = [surface_id](const SurfaceId& dependency) {
+ if (dependency.frame_sink_id() != surface_id.frame_sink_id())
+ return false;
+ // The dependency will never get satisfied if the child is already using a
+ // larger parent or child sequence number, so drop the dependency in that
+ // case.
+ if (dependency.local_surface_id().parent_sequence_number() <
+ surface_id.local_surface_id().parent_sequence_number() ||
+ dependency.local_surface_id().child_sequence_number() <
+ surface_id.local_surface_id().child_sequence_number()) {
+ return true;
+ }
+ // For the dependency to get satisfied, both parent and child sequence
+ // numbers of the activated SurfaceId must be equal to those of the
+ // dependency.
+ return dependency.local_surface_id().parent_sequence_number() ==
+ surface_id.local_surface_id().parent_sequence_number() &&
+ dependency.local_surface_id().child_sequence_number() ==
+ surface_id.local_surface_id().child_sequence_number();
+ };
+
+ base::EraseIf(activation_dependencies_, delete_fn);
// We cannot activate this CompositorFrame if there are still missing
// activation dependencies or this surface is blocked on its parent arriving
@@ -647,8 +670,11 @@ void Surface::SendAckToClient() {
}
void Surface::MarkAsDrawn() {
- if (active_frame_data_)
- active_frame_data_->frame_drawn = true;
+ if (!active_frame_data_)
+ return;
+ active_frame_data_->frame_drawn = true;
+ if (surface_client_)
+ surface_client_->OnSurfaceDrawn(this);
}
void Surface::NotifyAggregatedDamage(const gfx::Rect& damage_rect,
diff --git a/chromium/components/viz/service/surfaces/surface.h b/chromium/components/viz/service/surfaces/surface.h
index 4ff0194ffb7..45b90816680 100644
--- a/chromium/components/viz/service/surfaces/surface.h
+++ b/chromium/components/viz/service/surfaces/surface.h
@@ -43,6 +43,7 @@ class LatencyInfo;
namespace viz {
class SurfaceClient;
+class SurfaceAllocationGroup;
class SurfaceManager;
// A Surface is a representation of a sequence of CompositorFrames with a
@@ -80,6 +81,7 @@ class VIZ_SERVICE_EXPORT Surface final : public SurfaceDeadlineClient {
Surface(const SurfaceInfo& surface_info,
SurfaceManager* surface_manager,
+ SurfaceAllocationGroup* allocation_group,
base::WeakPtr<SurfaceClient> surface_client,
bool needs_sync_tokens,
bool block_activation_on_parent);
@@ -345,6 +347,8 @@ class VIZ_SERVICE_EXPORT Surface final : public SurfaceDeadlineClient {
// Frame sinks that this surface observe for activation events.
base::flat_set<FrameSinkId> observed_sinks_;
+ SurfaceAllocationGroup* const allocation_group_;
+
DISALLOW_COPY_AND_ASSIGN(Surface);
};
diff --git a/chromium/components/viz/service/surfaces/surface_allocation_group.cc b/chromium/components/viz/service/surfaces/surface_allocation_group.cc
new file mode 100644
index 00000000000..dc42639a181
--- /dev/null
+++ b/chromium/components/viz/service/surfaces/surface_allocation_group.cc
@@ -0,0 +1,115 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/surfaces/surface_allocation_group.h"
+
+#include "components/viz/service/surfaces/surface.h"
+
+namespace viz {
+
+SurfaceAllocationGroup::SurfaceAllocationGroup(
+ const FrameSinkId& submitter,
+ const base::UnguessableToken& embed_token)
+ : submitter_(submitter), embed_token_(embed_token) {}
+
+SurfaceAllocationGroup::~SurfaceAllocationGroup() = default;
+
+bool SurfaceAllocationGroup::IsReadyToDestroy() const {
+ return surfaces_.empty();
+}
+
+void SurfaceAllocationGroup::RegisterSurface(Surface* surface) {
+ DCHECK_EQ(submitter_, surface->surface_id().frame_sink_id());
+ DCHECK_EQ(embed_token_,
+ surface->surface_id().local_surface_id().embed_token());
+ DCHECK(!last_created_surface() || surface->surface_id().IsNewerThan(
+ last_created_surface()->surface_id()));
+ surfaces_.push_back(surface);
+}
+
+void SurfaceAllocationGroup::UnregisterSurface(Surface* surface) {
+ auto it = std::find(surfaces_.begin(), surfaces_.end(), surface);
+ DCHECK(it != surfaces_.end());
+ surfaces_.erase(it);
+}
+
+Surface* SurfaceAllocationGroup::FindLatestActiveSurfaceInRange(
+ const SurfaceRange& range) const {
+ // If the embed token of the end of the SurfaceRange matches that of this
+ // group, find the latest active surface that is older than or equal to the
+ // end, then check that it's not older than start.
+ if (range.end().local_surface_id().embed_token() == embed_token_) {
+ DCHECK_EQ(submitter_, range.end().frame_sink_id());
+ Surface* result = FindOlderOrEqual(range.end());
+ if (result &&
+ (!range.start() || !range.start()->IsNewerThan(result->surface_id()))) {
+ return result;
+ } else {
+ return nullptr;
+ }
+ }
+
+ // If we are here, the embed token of the end of the range doesn't match this
+ // group's embed token. In this case, the range must have a start and its
+ // embed token must match this group. Simply find the last active surface, and
+ // check whether it's newer than the range's start.
+ DCHECK(range.start());
+ DCHECK_EQ(embed_token_, range.start()->local_surface_id().embed_token());
+ DCHECK_NE(embed_token_, range.end().local_surface_id().embed_token());
+ DCHECK_EQ(submitter_, range.start()->frame_sink_id());
+
+ Surface* result = nullptr;
+ // Normally there is at most one pending surface, so this for loop shouldn't
+ // take more than two iterations.
+ for (int i = surfaces_.size() - 1; i >= 0; i--) {
+ if (surfaces_[i]->HasActiveFrame()) {
+ result = surfaces_[i];
+ break;
+ }
+ }
+ if (result && range.start()->IsNewerThan(result->surface_id()))
+ return nullptr;
+ return result;
+}
+
+Surface* SurfaceAllocationGroup::FindOlderOrEqual(
+ const SurfaceId& surface_id) const {
+ DCHECK_EQ(submitter_, surface_id.frame_sink_id());
+ DCHECK_EQ(embed_token_, surface_id.local_surface_id().embed_token());
+
+ // Return early if there are no surfaces in this group.
+ if (surfaces_.empty())
+ return nullptr;
+
+ // If even the first surface is newer than |surface_id|, we can't find a
+ // surface that is older than or equal to |surface_id|.
+ if (surfaces_[0]->surface_id().IsNewerThan(surface_id))
+ return nullptr;
+
+ // Perform a binary search the find the latest active surface that is older
+ // than or equal to |surface_id|.
+ int begin = 0;
+ int end = surfaces_.size();
+ while (end - begin > 1) {
+ int avg = (begin + end) / 2;
+ if (surfaces_[avg]->surface_id().IsNewerThan(surface_id))
+ end = avg;
+ else
+ begin = avg;
+ }
+
+ // We have found the latest surface. Now keep iterating back until we find an
+ // active surface. Normally, there is only one pending surface at a time, so
+ // this shouldn't take more than two iterations.
+ for (; begin >= 0; --begin) {
+ if (surfaces_[begin]->HasActiveFrame())
+ return surfaces_[begin];
+ }
+
+ // No active surface was found, so return null.
+ DCHECK_EQ(-1, begin);
+ return nullptr;
+}
+
+} // namespace viz
diff --git a/chromium/components/viz/service/surfaces/surface_allocation_group.h b/chromium/components/viz/service/surfaces/surface_allocation_group.h
new file mode 100644
index 00000000000..780ce97d11e
--- /dev/null
+++ b/chromium/components/viz/service/surfaces/surface_allocation_group.h
@@ -0,0 +1,79 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_ALLOCATION_GROUP_H_
+#define COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_ALLOCATION_GROUP_H_
+
+#include <vector>
+
+#include "base/unguessable_token.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
+#include "components/viz/common/surfaces/surface_range.h"
+#include "components/viz/service/viz_service_export.h"
+
+namespace viz {
+
+class Surface;
+
+// This class keeps track of the LocalSurfaceIds that were generated using the
+// same ParentLocalSurfaceIdAllocator (i.e. have the same embed token).
+class VIZ_SERVICE_EXPORT SurfaceAllocationGroup {
+ public:
+ SurfaceAllocationGroup(const FrameSinkId& submitter,
+ const base::UnguessableToken& embed_token);
+ ~SurfaceAllocationGroup();
+
+ // Returns the ID of the FrameSink that is submitting to surfaces in this
+ // allocation group.
+ const FrameSinkId& submitter_frame_sink_id() const { return submitter_; }
+
+ // Returns whether this SurfaceAllocationGroup can be destroyed by the garbage
+ // collector; that is, there are no surfaces left in this allocation group.
+ // TODO(samans): Also take into account the observers once
+ // SurfaceAllocationGroups can be observed.
+ bool IsReadyToDestroy() const;
+
+ // Called by |surface| at construction time to register itself in this
+ // allocation group.
+ void RegisterSurface(Surface* surface);
+
+ // Called by |surface| at destruction time to unregister itself from this
+ // allocation group.
+ void UnregisterSurface(Surface* surface);
+
+ // Returns the latest active surface in the given range that is a part of this
+ // allocation group. The embed token of at least one end of the range must
+ // match the embed token of this group.
+ Surface* FindLatestActiveSurfaceInRange(const SurfaceRange& range) const;
+
+ // Returns the last surface created in this allocation group.
+ Surface* last_created_surface() const {
+ return surfaces_.empty() ? nullptr : surfaces_.back();
+ }
+
+ private:
+ // Helper method for FindLatestActiveSurfaceInRange. Returns the latest active
+ // surface whose SurfaceId is older than or equal to |surface_id|.
+ Surface* FindOlderOrEqual(const SurfaceId& surface_id) const;
+
+ // The ID of the FrameSink that is submitting to the surfaces in this
+ // allocation group.
+ const FrameSinkId submitter_;
+
+ // The embed token that the ParentLocalSurfaceIdAllocator used to allocate
+ // LocalSurfaceIds for the surfaces in this allocation group. All the surfaces
+ // in this allocation group use this embed token.
+ const base::UnguessableToken embed_token_;
+
+ // The list of surfaces in this allocation group in the order of creation. The
+ // parent and child sequence numbers of these surfaces is monotonically
+ // increasing.
+ std::vector<Surface*> surfaces_;
+
+ DISALLOW_COPY_AND_ASSIGN(SurfaceAllocationGroup);
+};
+
+} // namespace viz
+
+#endif // COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_ALLOCATION_GROUP_H_
diff --git a/chromium/components/viz/service/surfaces/surface_client.h b/chromium/components/viz/service/surfaces/surface_client.h
index 4793a35f0f9..a9e60b68d24 100644
--- a/chromium/components/viz/service/surfaces/surface_client.h
+++ b/chromium/components/viz/service/surfaces/surface_client.h
@@ -27,6 +27,9 @@ class VIZ_SERVICE_EXPORT SurfaceClient {
// Called when |surface| is about to be destroyed.
virtual void OnSurfaceDiscarded(Surface* surface) = 0;
+ // Called when a |surface| is about to be drawn.
+ virtual void OnSurfaceDrawn(Surface* surface) = 0;
+
// Increments the reference count on resources specified by |resources|.
virtual void RefResources(
const std::vector<TransferableResource>& resources) = 0;
diff --git a/chromium/components/viz/service/surfaces/surface_manager.cc b/chromium/components/viz/service/surfaces/surface_manager.cc
index 4698e8e19b1..b96a45c8783 100644
--- a/chromium/components/viz/service/surfaces/surface_manager.cc
+++ b/chromium/components/viz/service/surfaces/surface_manager.cc
@@ -19,6 +19,7 @@
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/service/surfaces/surface.h"
+#include "components/viz/service/surfaces/surface_allocation_group.h"
#include "components/viz/service/surfaces/surface_client.h"
#include "components/viz/service/surfaces/surface_manager_delegate.h"
@@ -64,7 +65,6 @@ SurfaceManager::~SurfaceManager() {
// destroyed.
temporary_references_.clear();
temporary_reference_ranges_.clear();
- persistent_references_by_frame_sink_id_.clear();
// Create a copy of the children set as RemoveSurfaceReferenceImpl below will
// mutate that set.
base::flat_set<SurfaceId> children(
@@ -76,8 +76,9 @@ SurfaceManager::~SurfaceManager() {
// All SurfaceClients and their surfaces are supposed to be
// destroyed before SurfaceManager.
- DCHECK(surface_map_.empty());
- DCHECK(surfaces_to_destroy_.empty());
+ // TODO(crbug.com/823043): The following two DCHECKs don't hold.
+ // DCHECK(surface_map_.empty());
+ // DCHECK(surfaces_to_destroy_.empty());
}
#if DCHECK_IS_ON()
@@ -111,15 +112,21 @@ Surface* SurfaceManager::CreateSurface(
DCHECK(surface_info.is_valid());
DCHECK(surface_client);
+ // We should not be asked to create a surface that already exists.
auto it = surface_map_.find(surface_info.id());
if (it != surface_map_.end())
return nullptr;
- // If no surface with this SurfaceId exists, simply create the surface
- // and return.
- std::unique_ptr<Surface> surface =
- std::make_unique<Surface>(surface_info, this, surface_client,
- needs_sync_tokens, block_activation_on_parent);
+ SurfaceAllocationGroup* allocation_group =
+ GetOrCreateAllocationGroupForSurfaceId(surface_info.id());
+ // GetOrCreateAllocationGroupForSurfaceId can fail if two FrameSinkIds use the
+ // same embed token.
+ if (!allocation_group)
+ return nullptr;
+
+ std::unique_ptr<Surface> surface = std::make_unique<Surface>(
+ surface_info, this, allocation_group, surface_client, needs_sync_tokens,
+ block_activation_on_parent);
surface->SetDependencyDeadline(std::make_unique<SurfaceDependencyDeadline>(
surface.get(), begin_frame_source, tick_clock_));
surface_map_[surface_info.id()] = std::move(surface);
@@ -216,6 +223,9 @@ void SurfaceManager::GarbageCollectSurfaces() {
// re-entrancy, and if not just remove here.
for (const SurfaceId& surface_id : surfaces_to_delete)
surfaces_to_destroy_.erase(surface_id);
+
+ base::EraseIf(embed_token_to_allocation_group_,
+ [](auto& entry) { return entry.second->IsReadyToDestroy(); });
}
const base::flat_set<SurfaceId>& SurfaceManager::GetSurfacesReferencedByParent(
@@ -238,43 +248,6 @@ SurfaceManager::GetSurfacesThatReferenceChildForTesting(
return parents;
}
-Surface* SurfaceManager::GetLatestInFlightSurfaceForFrameSinkId(
- const SurfaceRange& surface_range,
- const FrameSinkId& sink_id) {
- std::vector<LocalSurfaceId> valid_local_surfaces;
- // Get all valid temporary references.
- auto temporary_it = temporary_reference_ranges_.find(sink_id);
- if (temporary_it != temporary_reference_ranges_.end()) {
- for (const LocalSurfaceId& local_id : temporary_it->second) {
- if (surface_range.IsInRangeInclusive(SurfaceId(sink_id, local_id)))
- valid_local_surfaces.push_back(local_id);
- }
- }
-
- // Get all valid persistent references.
- auto persistent_it = persistent_references_by_frame_sink_id_.find(sink_id);
- if (persistent_it != persistent_references_by_frame_sink_id_.end()) {
- for (const LocalSurfaceId& local_id : persistent_it->second) {
- if (surface_range.IsInRangeInclusive(SurfaceId(sink_id, local_id)))
- valid_local_surfaces.push_back(local_id);
- }
- }
-
- // Sort all possible surfaces from newest to oldest, then return the first
- // surface that has an active frame.
- std::sort(valid_local_surfaces.begin(), valid_local_surfaces.end(),
- [](const LocalSurfaceId& first, const LocalSurfaceId& second) {
- return first > second;
- });
-
- for (const LocalSurfaceId& local_surface_id : valid_local_surfaces) {
- Surface* surface = GetSurfaceForId(SurfaceId(sink_id, local_surface_id));
- if (surface && surface->HasActiveFrame())
- return surface;
- }
- return nullptr;
-}
-
SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() {
SurfaceIdSet reachable_surfaces;
@@ -332,10 +305,6 @@ void SurfaceManager::AddSurfaceReferenceImpl(
references_[parent_id].insert(child_id);
- // Add a real reference to child_id.
- persistent_references_by_frame_sink_id_[child_id.frame_sink_id()].insert(
- child_id.local_surface_id());
-
for (auto& observer : observer_list_)
observer.OnAddedSurfaceReference(parent_id, child_id);
@@ -362,36 +331,12 @@ void SurfaceManager::RemoveSurfaceReferenceImpl(
iter_parent->second.erase(child_iter);
if (iter_parent->second.empty())
references_.erase(iter_parent);
-
- // Remove the presistent reference.
- const FrameSinkId& sink_id = child_id.frame_sink_id();
- const LocalSurfaceId& local_id = child_id.local_surface_id();
-
- auto sink_it = persistent_references_by_frame_sink_id_.find(sink_id);
- if (sink_it == persistent_references_by_frame_sink_id_.end())
- return;
-
- auto local_surface_it = sink_it->second.find(local_id);
- if (local_surface_it == sink_it->second.end())
- return;
-
- sink_it->second.erase(local_surface_it);
- if (sink_it->second.empty())
- persistent_references_by_frame_sink_id_.erase(sink_it);
}
bool SurfaceManager::HasTemporaryReference(const SurfaceId& surface_id) const {
return temporary_references_.count(surface_id) != 0;
}
-bool SurfaceManager::HasPersistentReference(const SurfaceId& surface_id) const {
- auto it =
- persistent_references_by_frame_sink_id_.find(surface_id.frame_sink_id());
- if (it == persistent_references_by_frame_sink_id_.end())
- return false;
- return it->second.count(surface_id.local_surface_id()) != 0;
-}
-
void SurfaceManager::AddTemporaryReference(const SurfaceId& surface_id) {
DCHECK(!HasTemporaryReference(surface_id));
@@ -451,29 +396,24 @@ void SurfaceManager::RemoveTemporaryReferenceImpl(const SurfaceId& surface_id,
Surface* SurfaceManager::GetLatestInFlightSurface(
const SurfaceRange& surface_range) {
- // If primary exists, we return it.
- Surface* primary_surface = GetSurfaceForId(surface_range.end());
- if (primary_surface && primary_surface->HasActiveFrame())
- return primary_surface;
-
- // If both end of the range exists, we try the primary's FrameSinkId first.
- Surface* latest_surface = GetLatestInFlightSurfaceForFrameSinkId(
- surface_range, surface_range.end().frame_sink_id());
-
- // If the fallback has a different FrameSinkId, then try that also.
- if (!latest_surface && surface_range.HasDifferentFrameSinkIds()) {
- latest_surface = GetLatestInFlightSurfaceForFrameSinkId(
- surface_range, surface_range.start()->frame_sink_id());
+ SurfaceAllocationGroup* end_allocation_group =
+ GetAllocationGroupForSurfaceId(surface_range.end());
+ if (end_allocation_group) {
+ Surface* result =
+ end_allocation_group->FindLatestActiveSurfaceInRange(surface_range);
+ if (result)
+ return result;
}
-
- // Fallback might have neither temporary or presistent references, so we
- // consider it separately.
- if (!latest_surface && surface_range.start())
- latest_surface = GetSurfaceForId(*surface_range.start());
-
- if (latest_surface && latest_surface->HasActiveFrame())
- return latest_surface;
- return nullptr;
+ if (!surface_range.start() ||
+ surface_range.start()->local_surface_id().embed_token() ==
+ surface_range.end().local_surface_id().embed_token()) {
+ return nullptr;
+ }
+ SurfaceAllocationGroup* start_allocation_group =
+ GetAllocationGroupForSurfaceId(*surface_range.start());
+ if (!start_allocation_group)
+ return nullptr;
+ return start_allocation_group->FindLatestActiveSurfaceInRange(surface_range);
}
void SurfaceManager::ExpireOldTemporaryReferences() {
@@ -658,4 +598,36 @@ void SurfaceManager::DropTemporaryReference(const SurfaceId& surface_id) {
RemoveTemporaryReferenceImpl(surface_id, RemovedReason::DROPPED);
}
+SurfaceAllocationGroup* SurfaceManager::GetOrCreateAllocationGroupForSurfaceId(
+ const SurfaceId& surface_id) {
+ std::unique_ptr<SurfaceAllocationGroup>& allocation_group =
+ embed_token_to_allocation_group_[surface_id.local_surface_id()
+ .embed_token()];
+ if (allocation_group && allocation_group->submitter_frame_sink_id() !=
+ surface_id.frame_sink_id()) {
+ DLOG(ERROR) << "Cannot reuse embed token across frame sinks";
+ return nullptr;
+ }
+ if (!allocation_group) {
+ allocation_group = std::make_unique<SurfaceAllocationGroup>(
+ surface_id.frame_sink_id(),
+ surface_id.local_surface_id().embed_token());
+ }
+ return allocation_group.get();
+}
+
+SurfaceAllocationGroup* SurfaceManager::GetAllocationGroupForSurfaceId(
+ const SurfaceId& surface_id) {
+ auto it = embed_token_to_allocation_group_.find(
+ surface_id.local_surface_id().embed_token());
+ if (it == embed_token_to_allocation_group_.end())
+ return nullptr;
+ DCHECK(it->second);
+ if (it->second->submitter_frame_sink_id() != surface_id.frame_sink_id()) {
+ DLOG(ERROR) << "Cannot reuse embed token across frame sinks";
+ return nullptr;
+ }
+ return it->second.get();
+}
+
} // namespace viz
diff --git a/chromium/components/viz/service/surfaces/surface_manager.h b/chromium/components/viz/service/surfaces/surface_manager.h
index 3f6f288ff3d..82218421783 100644
--- a/chromium/components/viz/service/surfaces/surface_manager.h
+++ b/chromium/components/viz/service/surfaces/surface_manager.h
@@ -39,6 +39,7 @@ class TickClock;
namespace viz {
class Surface;
+class SurfaceAllocationGroup;
class SurfaceManagerDelegate;
struct BeginFrameAck;
struct BeginFrameArgs;
@@ -196,6 +197,20 @@ class VIZ_SERVICE_EXPORT SurfaceManager {
// Removes temporary reference to |surface_id| and older surfaces.
void DropTemporaryReference(const SurfaceId& surface_id);
+ // Returns the corresponding SurfaceAllocationGroup for |surface_id|. A
+ // SurfaceAllocationGroup will be created for |surface_id| if one doesn't
+ // exist yet. If there is already a SurfaceAllocationGroup that matches the
+ // embed token of |surface_id| but its submitter doesn't match |surface_id|'s
+ // FrameSinkId, nullptr will be returned. In any other case, the returned
+ // value will always be a valid SurfaceAllocationGroup.
+ SurfaceAllocationGroup* GetOrCreateAllocationGroupForSurfaceId(
+ const SurfaceId& surface_id);
+
+ // Similar to GetOrCreateAllocationGroupForSurfaceId, but will not attempt to
+ // create the allocation group if it does not already exist.
+ SurfaceAllocationGroup* GetAllocationGroupForSurfaceId(
+ const SurfaceId& surface_id);
+
private:
friend class CompositorFrameSinkSupportTest;
friend class FrameSinkManagerTest;
@@ -223,11 +238,6 @@ class VIZ_SERVICE_EXPORT SurfaceManager {
bool marked_as_old = false;
};
- // Returns the latest surface in a FrameSinkId that satisfies |is_valid|.
- Surface* GetLatestInFlightSurfaceForFrameSinkId(
- const SurfaceRange& surface_range,
- const FrameSinkId& sink_id);
-
// Returns set of live surfaces for |lifetime_manager_| is REFERENCES.
SurfaceIdSet GetLiveSurfacesForReferences();
@@ -244,9 +254,6 @@ class VIZ_SERVICE_EXPORT SurfaceManager {
// Returns whether |surface_id| has a temporary reference or not.
bool HasTemporaryReference(const SurfaceId& surface_id) const;
- // Returns whether |surface_id| has a Persistent reference or not.
- bool HasPersistentReference(const SurfaceId& surface_id) const;
-
// Adds a temporary reference to |surface_id|. The reference will not have an
// owner initially.
void AddTemporaryReference(const SurfaceId& surface_id);
@@ -321,11 +328,6 @@ class VIZ_SERVICE_EXPORT SurfaceManager {
std::unordered_map<FrameSinkId, std::vector<LocalSurfaceId>, FrameSinkIdHash>
temporary_reference_ranges_;
- // A list of surfaces with a given FrameSinkId that have a persistent
- // reference.
- base::flat_map<FrameSinkId, base::flat_set<LocalSurfaceId>>
- persistent_references_by_frame_sink_id_;
-
// A map storing SurfaceIds interested in knowing about activation events
// happending in FrameSinkId.
base::flat_map<FrameSinkId, base::flat_set<SurfaceId>> activation_observers_;
@@ -335,6 +337,10 @@ class VIZ_SERVICE_EXPORT SurfaceManager {
// are temporary references. Also the timer isn't used with Android WebView.
base::Optional<base::RepeatingTimer> expire_timer_;
+ base::flat_map<base::UnguessableToken,
+ std::unique_ptr<SurfaceAllocationGroup>>
+ embed_token_to_allocation_group_;
+
base::WeakPtrFactory<SurfaceManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
diff --git a/chromium/components/viz/service/surfaces/surface_unittest.cc b/chromium/components/viz/service/surfaces/surface_unittest.cc
index 7fbec7cdf83..579d055a08d 100644
--- a/chromium/components/viz/service/surfaces/surface_unittest.cc
+++ b/chromium/components/viz/service/surfaces/surface_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/viz/service/surfaces/surface.h"
+#include "base/bind.h"
#include "cc/test/scheduler_test_common.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
diff --git a/chromium/components/viz/test/BUILD.gn b/chromium/components/viz/test/BUILD.gn
index d83a217b990..bf31d3f4599 100644
--- a/chromium/components/viz/test/BUILD.gn
+++ b/chromium/components/viz/test/BUILD.gn
@@ -17,12 +17,16 @@ viz_static_library("test_support") {
"fake_compositor_frame_sink_client.h",
"fake_delay_based_time_source.cc",
"fake_delay_based_time_source.h",
+ "fake_display_client.cc",
+ "fake_display_client.h",
"fake_external_begin_frame_source.cc",
"fake_external_begin_frame_source.h",
"fake_host_frame_sink_client.cc",
"fake_host_frame_sink_client.h",
"fake_output_surface.cc",
"fake_output_surface.h",
+ "fake_skia_output_surface.cc",
+ "fake_skia_output_surface.h",
"fake_surface_observer.cc",
"fake_surface_observer.h",
"gpu_host_impl_test_api.cc",
@@ -40,6 +44,8 @@ viz_static_library("test_support") {
"paths.h",
"surface_hittest_test_helpers.cc",
"surface_hittest_test_helpers.h",
+ "surface_id_allocator_set.cc",
+ "surface_id_allocator_set.h",
"test_context_provider.cc",
"test_context_provider.h",
"test_context_support.cc",
diff --git a/chromium/components/web_cache/browser/web_cache_manager.cc b/chromium/components/web_cache/browser/web_cache_manager.cc
index 9d2a41d2863..d156c4a6bd9 100644
--- a/chromium/components/web_cache/browser/web_cache_manager.cc
+++ b/chromium/components/web_cache/browser/web_cache_manager.cc
@@ -309,10 +309,11 @@ void WebCacheManager::EnactStrategy(const AllocationStrategy& strategy) {
// Find the WebCachePtr by renderer process id.
auto it = web_cache_services_.find(allocation->first);
- DCHECK(it != web_cache_services_.end());
- const mojom::WebCachePtr& service = it->second;
- DCHECK(service);
- service->SetCacheCapacity(capacity);
+ if (it != web_cache_services_.end()) {
+ const mojom::WebCachePtr& service = it->second;
+ DCHECK(service);
+ service->SetCacheCapacity(capacity);
+ }
}
++allocation;
}
@@ -334,10 +335,11 @@ void WebCacheManager::ClearRendererCache(
if (host) {
// Find the WebCachePtr by renderer process id.
auto it = web_cache_services_.find(*iter);
- DCHECK(it != web_cache_services_.end());
- const mojom::WebCachePtr& service = it->second;
- DCHECK(service);
- service->ClearCache(occasion == ON_NAVIGATION);
+ if (it != web_cache_services_.end()) {
+ const mojom::WebCachePtr& service = it->second;
+ DCHECK(service);
+ service->ClearCache(occasion == ON_NAVIGATION);
+ }
}
}
}
diff --git a/chromium/components/web_resource/resource_request_allowed_notifier.cc b/chromium/components/web_resource/resource_request_allowed_notifier.cc
index 7e1baf9624d..ccada65a2af 100644
--- a/chromium/components/web_resource/resource_request_allowed_notifier.cc
+++ b/chromium/components/web_resource/resource_request_allowed_notifier.cc
@@ -4,6 +4,7 @@
#include "components/web_resource/resource_request_allowed_notifier.h"
+#include "base/bind.h"
#include "base/command_line.h"
namespace web_resource {
diff --git a/chromium/components/web_resource/resource_request_allowed_notifier_test_util.cc b/chromium/components/web_resource/resource_request_allowed_notifier_test_util.cc
index 3c12718f382..2702ae486e8 100644
--- a/chromium/components/web_resource/resource_request_allowed_notifier_test_util.cc
+++ b/chromium/components/web_resource/resource_request_allowed_notifier_test_util.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "components/web_resource/resource_request_allowed_notifier_test_util.h"
+#include "base/bind.h"
namespace web_resource {
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 ec0c78d3492..58578123de9 100644
--- a/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc
+++ b/chromium/components/web_resource/resource_request_allowed_notifier_unittest.cc
@@ -296,7 +296,7 @@ TEST_P(ResourceRequestAllowedNotifierTest, NoRequestNoNotifyEula) {
EXPECT_FALSE(was_notified());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
ResourceRequestAllowedNotifierTest,
testing::Values(ConnectionTrackerResponseMode::kSynchronous,
diff --git a/chromium/components/web_resource/web_resource_service_unittest.cc b/chromium/components/web_resource/web_resource_service_unittest.cc
index 2017e9aa1ec..6b7faed01f1 100644
--- a/chromium/components/web_resource/web_resource_service_unittest.cc
+++ b/chromium/components/web_resource/web_resource_service_unittest.cc
@@ -87,7 +87,7 @@ class TestWebResourceService : public WebResourceService {
[](network::NetworkConnectionTracker* tracker) {
return tracker;
},
- network_connection_tracker)){};
+ network_connection_tracker)) {}
void Unpack(const base::DictionaryValue& parsed_json) override {}
};
diff --git a/chromium/components/web_restrictions/browser/web_restrictions_client.cc b/chromium/components/web_restrictions/browser/web_restrictions_client.cc
index f13249ed515..7d3beb6ba18 100644
--- a/chromium/components/web_restrictions/browser/web_restrictions_client.cc
+++ b/chromium/components/web_restrictions/browser/web_restrictions_client.cc
@@ -33,7 +33,8 @@ bool RequestPermissionTask(
bool CheckSupportsRequestTask(
const base::android::JavaRef<jobject>& java_provider) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
JNIEnv* env = base::android::AttachCurrentThread();
return Java_WebRestrictionsClient_supportsRequest(env, java_provider);
}
@@ -61,8 +62,8 @@ void WebRestrictionsClient::SetAuthority(
// accessed from the IO thread.
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO},
- base::Bind(&WebRestrictionsClient::SetAuthorityTask,
- base::Unretained(this), content_provider_authority));
+ base::BindOnce(&WebRestrictionsClient::SetAuthorityTask,
+ base::Unretained(this), content_provider_authority));
}
void WebRestrictionsClient::SetAuthorityTask(
@@ -136,9 +137,9 @@ void WebRestrictionsClient::RequestPermission(
void WebRestrictionsClient::OnWebRestrictionsChanged(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj) {
- base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::IO},
- base::Bind(&WebRestrictionsClient::ClearCache, base::Unretained(this)));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&WebRestrictionsClient::ClearCache,
+ base::Unretained(this)));
}
void WebRestrictionsClient::RecordURLAccess(const std::string& url) {
diff --git a/chromium/components/webcrypto/algorithms/aes.cc b/chromium/components/webcrypto/algorithms/aes.cc
index a856d2be290..345735493ea 100644
--- a/chromium/components/webcrypto/algorithms/aes.cc
+++ b/chromium/components/webcrypto/algorithms/aes.cc
@@ -63,7 +63,7 @@ Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
if (status.IsError())
return status;
- unsigned int keylen_bits = algorithm.AesKeyGenParams()->LengthBits();
+ uint16_t keylen_bits = algorithm.AesKeyGenParams()->LengthBits();
// 192-bit AES is intentionally unsupported (http://crbug.com/533699).
if (keylen_bits == 192)
diff --git a/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc b/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc
index b4b36cf5db6..fc9982d53f2 100644
--- a/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/aes_cbc_unittest.cc
@@ -30,7 +30,7 @@ blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(
}
blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
- unsigned short key_length_bits) {
+ uint16_t key_length_bits) {
return CreateAesKeyGenAlgorithm(blink::kWebCryptoAlgorithmIdAesCbc,
key_length_bits);
}
@@ -90,13 +90,13 @@ TEST_F(WebCryptoAesCbcTest, ExportKeyUnsupportedFormat) {
// Tests importing of keys (in a variety of formats), errors during import,
// encryption, and decryption, using known answers.
TEST_F(WebCryptoAesCbcTest, KnownAnswerEncryptDecrypt) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_cbc.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
std::vector<uint8_t> key_data =
@@ -167,7 +167,7 @@ TEST_F(WebCryptoAesCbcTest, KnownAnswerEncryptDecrypt) {
TEST_F(WebCryptoAesCbcTest, GenerateKeyIsRandom) {
// Check key generation for each allowed key length.
std::vector<blink::WebCryptoAlgorithm> algorithm;
- const unsigned short kKeyLength[] = {128, 256};
+ const uint16_t kKeyLength[] = {128, 256};
for (size_t key_length_i = 0; key_length_i < base::size(kKeyLength);
++key_length_i) {
blink::WebCryptoKey key;
@@ -196,7 +196,7 @@ TEST_F(WebCryptoAesCbcTest, GenerateKeyIsRandom) {
}
TEST_F(WebCryptoAesCbcTest, GenerateKeyBadLength) {
- const unsigned short kKeyLen[] = {0, 127, 257};
+ const uint16_t kKeyLen[] = {0, 127, 257};
blink::WebCryptoKey key;
for (size_t i = 0; i < base::size(kKeyLen); ++i) {
SCOPED_TRACE(i);
diff --git a/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc b/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc
index f08fa9fecec..ac0a2a916e2 100644
--- a/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/aes_ctr_unittest.cc
@@ -30,13 +30,13 @@ blink::WebCryptoAlgorithm CreateAesCtrAlgorithm(
class WebCryptoAesCtrTest : public WebCryptoTestBase {};
TEST_F(WebCryptoAesCtrTest, EncryptDecryptKnownAnswer) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_ctr.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
std::vector<uint8_t> test_counter = GetBytesFromHexString(test, "counter");
diff --git a/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc b/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc
index 185a43cba9a..e409ba0f64b 100644
--- a/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/aes_gcm_unittest.cc
@@ -31,7 +31,7 @@ blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
}
blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
- unsigned short key_length_bits) {
+ uint16_t key_length_bits) {
return CreateAesKeyGenAlgorithm(blink::kWebCryptoAlgorithmIdAesGcm,
key_length_bits);
}
@@ -97,7 +97,7 @@ Status AesGcmDecrypt(const blink::WebCryptoKey& key,
class WebCryptoAesGcmTest : public WebCryptoTestBase {};
TEST_F(WebCryptoAesGcmTest, GenerateKeyBadLength) {
- const unsigned short kKeyLen[] = {0, 127, 257};
+ const uint16_t kKeyLen[] = {0, 127, 257};
blink::WebCryptoKey key;
for (size_t i = 0; i < base::size(kKeyLen); ++i) {
SCOPED_TRACE(i);
@@ -133,14 +133,14 @@ TEST_F(WebCryptoAesGcmTest, ImportExportJwk) {
// * Test decryption with empty input
// * Test decryption with tag length of 0.
TEST_F(WebCryptoAesGcmTest, SampleSets) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_gcm.json", &tests));
// Note that WebCrypto appends the authentication tag to the ciphertext.
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
const std::vector<uint8_t> test_iv = GetBytesFromHexString(test, "iv");
diff --git a/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc b/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc
index fd38d6478f8..645c9d258ee 100644
--- a/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/aes_kw_unittest.cc
@@ -20,8 +20,7 @@ namespace webcrypto {
namespace {
-blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm(
- unsigned short key_length_bits) {
+blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm(uint16_t key_length_bits) {
return CreateAesKeyGenAlgorithm(blink::kWebCryptoAlgorithmIdAesKw,
key_length_bits);
}
@@ -29,7 +28,7 @@ blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm(
class WebCryptoAesKwTest : public WebCryptoTestBase {};
TEST_F(WebCryptoAesKwTest, GenerateKeyBadLength) {
- const unsigned short kKeyLen[] = {0, 127, 257};
+ const uint16_t kKeyLen[] = {0, 127, 257};
blink::WebCryptoKey key;
for (size_t i = 0; i < base::size(kKeyLen); ++i) {
SCOPED_TRACE(i);
@@ -163,10 +162,10 @@ TEST_F(WebCryptoAesKwTest, AesKwKeyImport) {
TEST_F(WebCryptoAesKwTest, UnwrapFailures) {
// This test exercises the code path common to all unwrap operations.
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(0, &test));
+ ASSERT_TRUE(tests.GetDictionary(0, &test));
const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek");
const std::vector<uint8_t> test_ciphertext =
GetBytesFromHexString(test, "ciphertext");
@@ -187,13 +186,13 @@ TEST_F(WebCryptoAesKwTest, UnwrapFailures) {
}
TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapKnownAnswer) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek");
const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
const std::vector<uint8_t> test_ciphertext =
@@ -246,11 +245,11 @@ TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapKnownAnswer) {
// Unwrap a HMAC key using AES-KW, and then try doing a sign/verify with the
// unwrapped key
TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapSignVerifyHmac) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(0, &test));
+ ASSERT_TRUE(tests.GetDictionary(0, &test));
const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek");
const std::vector<uint8_t> test_ciphertext =
GetBytesFromHexString(test, "ciphertext");
@@ -297,11 +296,11 @@ TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapSignVerifyHmac) {
}
TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapErrors) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
base::DictionaryValue* test;
// Use 256 bits of data with a 256-bit KEK
- ASSERT_TRUE(tests->GetDictionary(3, &test));
+ ASSERT_TRUE(tests.GetDictionary(3, &test));
const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek");
const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
const std::vector<uint8_t> test_ciphertext =
@@ -338,11 +337,11 @@ TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyWrapUnwrapErrors) {
}
TEST_F(WebCryptoAesKwTest, AesKwRawSymkeyUnwrapCorruptData) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
base::DictionaryValue* test;
// Use 256 bits of data with a 256-bit KEK
- ASSERT_TRUE(tests->GetDictionary(3, &test));
+ ASSERT_TRUE(tests.GetDictionary(3, &test));
const std::vector<uint8_t> test_kek = GetBytesFromHexString(test, "kek");
const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
const std::vector<uint8_t> test_ciphertext =
diff --git a/chromium/components/webcrypto/algorithms/ecdh_unittest.cc b/chromium/components/webcrypto/algorithms/ecdh_unittest.cc
index 4c6cd87bacf..1a5b92b94ac 100644
--- a/chromium/components/webcrypto/algorithms/ecdh_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/ecdh_unittest.cc
@@ -34,8 +34,7 @@ blink::WebCryptoAlgorithm CreateEcdhDeriveParams(
new blink::WebCryptoEcdhKeyDeriveParams(public_key));
}
-blink::WebCryptoAlgorithm CreateAesGcmDerivedKeyParams(
- unsigned short length_bits) {
+blink::WebCryptoAlgorithm CreateAesGcmDerivedKeyParams(uint16_t length_bits) {
return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
blink::kWebCryptoAlgorithmIdAesGcm,
new blink::WebCryptoAesDerivedKeyParams(length_bits));
@@ -77,14 +76,14 @@ bool ImportKeysFromTest(const base::DictionaryValue* test,
class WebCryptoEcdhTest : public WebCryptoTestBase {};
TEST_F(WebCryptoEcdhTest, DeriveBitsKnownAnswer) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("ecdh.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
// Import the keys.
blink::WebCryptoKey public_key;
@@ -119,15 +118,15 @@ TEST_F(WebCryptoEcdhTest, DeriveBitsKnownAnswer) {
// 528 bits.
::testing::AssertionResult LoadTestKeys(blink::WebCryptoKey* public_key,
blink::WebCryptoKey* private_key) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
if (!ReadJsonTestFileToList("ecdh.json", &tests))
return ::testing::AssertionFailure() << "Failed loading ecdh.json";
const base::DictionaryValue* test = nullptr;
bool valid_p521_keys = false;
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
- EXPECT_TRUE(tests->GetDictionary(test_index, &test));
+ EXPECT_TRUE(tests.GetDictionary(test_index, &test));
test->GetBoolean("valid_p521_keys", &valid_p521_keys);
if (valid_p521_keys)
break;
@@ -302,11 +301,11 @@ TEST_F(WebCryptoEcdhTest, DeriveKeyAes128) {
TEST_F(WebCryptoEcdhTest, ImportKeyEmptyUsage) {
blink::WebCryptoKey key;
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("ecdh.json", &tests));
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(0, &test));
+ ASSERT_TRUE(tests.GetDictionary(0, &test));
// Import the public key.
const base::DictionaryValue* public_key_json = nullptr;
diff --git a/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc b/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc
index b7d30c45994..0426b954ee9 100644
--- a/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/ecdsa_unittest.cc
@@ -97,10 +97,10 @@ TEST_F(WebCryptoEcdsaTest, SignatureIsRandom) {
// Import a public and private keypair from "ec_private_keys.json". It doesn't
// really matter which one is used since they are all valid. In this case
// using the first one.
- std::unique_ptr<base::ListValue> private_keys;
+ base::ListValue private_keys;
ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &private_keys));
const base::DictionaryValue* key_dict;
- ASSERT_TRUE(private_keys->GetDictionary(0, &key_dict));
+ ASSERT_TRUE(private_keys.GetDictionary(0, &key_dict));
blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(key_dict);
const base::DictionaryValue* key_jwk;
ASSERT_TRUE(key_dict->GetDictionary("jwk", &key_jwk));
@@ -152,14 +152,14 @@ TEST_F(WebCryptoEcdsaTest, SignatureIsRandom) {
// Tests verify() for ECDSA using an assortment of keys, curves and hashes.
// These tests also include expected failures for bad signatures and keys.
TEST_F(WebCryptoEcdsaTest, VerifyKnownAnswer) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("ecdsa.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
@@ -234,14 +234,14 @@ blink::WebCryptoKeyUsageMask GetExpectedUsagesForKeyImport(
// Tests importing bad public/private keys in a variety of formats.
TEST_F(WebCryptoEcdsaTest, ImportBadKeys) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("bad_ec_keys.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
@@ -264,14 +264,14 @@ TEST_F(WebCryptoEcdsaTest, ImportBadKeys) {
// The test imports a key first using JWK, and then exporting it to JWK and
// PKCS8. It does the same thing using PKCS8 as the original source of truth.
TEST_F(WebCryptoEcdsaTest, ImportExportPrivateKey) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test);
const base::DictionaryValue* jwk_dict;
diff --git a/chromium/components/webcrypto/algorithms/hmac_unittest.cc b/chromium/components/webcrypto/algorithms/hmac_unittest.cc
index 89b2a2a91b4..175bbe7dfcb 100644
--- a/chromium/components/webcrypto/algorithms/hmac_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/hmac_unittest.cc
@@ -50,12 +50,12 @@ blink::WebCryptoAlgorithm CreateHmacImportAlgorithmWithLength(
class WebCryptoHmacTest : public WebCryptoTestBase {};
TEST_F(WebCryptoHmacTest, HMACSampleSets) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash");
const std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
diff --git a/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc
index ebd998f3dee..fcceed5d93b 100644
--- a/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_oaep_unittest.cc
@@ -156,14 +156,14 @@ TEST_F(WebCryptoRsaOaepTest, ExportPublicJwk) {
}
TEST_F(WebCryptoRsaOaepTest, EncryptDecryptKnownAnswerTest) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("rsa_oaep.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test = nullptr;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoAlgorithm digest_algorithm =
GetDigestAlgorithm(test, "hash");
diff --git a/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc
index e52ddfc4bd7..f4af3f140ba 100644
--- a/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_pss_unittest.cc
@@ -168,14 +168,14 @@ TEST_F(WebCryptoRsaPssTest, SignEmptyMessage) {
// * Verify over corrupted message should fail
// * Verification with corrupted signature should fail
TEST_F(WebCryptoRsaPssTest, VerifyKnownAnswer) {
- std::unique_ptr<base::DictionaryValue> test_data;
+ base::DictionaryValue test_data;
ASSERT_TRUE(ReadJsonTestFileToDictionary("rsa_pss.json", &test_data));
const base::DictionaryValue* keys_dict = nullptr;
- ASSERT_TRUE(test_data->GetDictionary("keys", &keys_dict));
+ ASSERT_TRUE(test_data.GetDictionary("keys", &keys_dict));
const base::ListValue* tests = nullptr;
- ASSERT_TRUE(test_data->GetList("tests", &tests));
+ ASSERT_TRUE(test_data.GetList("tests", &tests));
for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
diff --git a/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc b/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc
index 5017ae24818..35dff52d0ae 100644
--- a/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/rsa_ssa_unittest.cc
@@ -202,18 +202,18 @@ TEST_F(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) {
// be imported correctly, however every key after that would actually import
// the first key.
TEST_F(WebCryptoRsaSsaTest, ImportMultipleRSAPrivateKeysJwk) {
- std::unique_ptr<base::ListValue> key_list;
+ base::ListValue key_list;
ASSERT_TRUE(ReadJsonTestFileToList("rsa_private_keys.json", &key_list));
// For this test to be meaningful the keys MUST be kept alive before importing
// new keys.
std::vector<blink::WebCryptoKey> live_keys;
- for (size_t key_index = 0; key_index < key_list->GetSize(); ++key_index) {
+ for (size_t key_index = 0; key_index < key_list.GetSize(); ++key_index) {
SCOPED_TRACE(key_index);
base::DictionaryValue* key_values;
- ASSERT_TRUE(key_list->GetDictionary(key_index, &key_values));
+ ASSERT_TRUE(key_list.GetDictionary(key_index, &key_values));
// Get the JWK representation of the key.
base::DictionaryValue* key_jwk;
@@ -260,12 +260,12 @@ TEST_F(WebCryptoRsaSsaTest, ImportMultipleRSAPrivateKeysJwk) {
// that the second import retrieves the first key. See http://crbug.com/378315
// for how that could happen.
TEST_F(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
- std::unique_ptr<base::ListValue> key_list;
+ base::ListValue key_list;
ASSERT_TRUE(ReadJsonTestFileToList("rsa_private_keys.json", &key_list));
// Import a 1024-bit private key.
base::DictionaryValue* key1_props;
- ASSERT_TRUE(key_list->GetDictionary(1, &key1_props));
+ ASSERT_TRUE(key_list.GetDictionary(1, &key1_props));
base::DictionaryValue* key1_jwk;
ASSERT_TRUE(key1_props->GetDictionary("jwk", &key1_jwk));
@@ -283,7 +283,7 @@ TEST_F(WebCryptoRsaSsaTest, ImportJwkExistingModulusAndInvalid) {
// Construct a JWK using the modulus of key1, but all the other fields from
// another key (also a 1024-bit private key).
base::DictionaryValue* key2_props;
- ASSERT_TRUE(key_list->GetDictionary(5, &key2_props));
+ ASSERT_TRUE(key_list.GetDictionary(5, &key2_props));
base::DictionaryValue* key2_jwk;
ASSERT_TRUE(key2_props->GetDictionary("jwk", &key2_jwk));
std::string modulus;
@@ -631,7 +631,7 @@ TEST_F(WebCryptoRsaSsaTest, SignVerifyFailures) {
}
TEST_F(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("pkcs1v15_sign.json", &tests));
// Import the key pair.
@@ -651,11 +651,11 @@ TEST_F(WebCryptoRsaSsaTest, SignVerifyKnownAnswer) {
// Validate the signatures are computed and verified as expected.
std::vector<uint8_t> signature;
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
std::vector<uint8_t> test_message =
GetBytesFromHexString(test, "message_hex");
@@ -986,14 +986,14 @@ TEST_F(WebCryptoRsaSsaTest, ImportRsaSsaJwkBadUsageAndData) {
// Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected.
TEST_F(WebCryptoRsaSsaTest, ImportInvalidKeyData) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
const base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
std::vector<uint8_t> key_data =
diff --git a/chromium/components/webcrypto/algorithms/sha_unittest.cc b/chromium/components/webcrypto/algorithms/sha_unittest.cc
index 8518ffc5ff8..8363ca36906 100644
--- a/chromium/components/webcrypto/algorithms/sha_unittest.cc
+++ b/chromium/components/webcrypto/algorithms/sha_unittest.cc
@@ -23,13 +23,13 @@ namespace {
class WebCryptoShaTest : public WebCryptoTestBase {};
TEST_F(WebCryptoShaTest, DigestSampleSets) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("sha.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoAlgorithm test_algorithm =
GetDigestAlgorithm(test, "algorithm");
@@ -44,13 +44,13 @@ TEST_F(WebCryptoShaTest, DigestSampleSets) {
}
TEST_F(WebCryptoShaTest, DigestSampleSetsInChunks) {
- std::unique_ptr<base::ListValue> tests;
+ base::ListValue tests;
ASSERT_TRUE(ReadJsonTestFileToList("sha.json", &tests));
- for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
+ for (size_t test_index = 0; test_index < tests.GetSize(); ++test_index) {
SCOPED_TRACE(test_index);
base::DictionaryValue* test;
- ASSERT_TRUE(tests->GetDictionary(test_index, &test));
+ ASSERT_TRUE(tests.GetDictionary(test_index, &test));
blink::WebCryptoAlgorithm test_algorithm =
GetDigestAlgorithm(test, "algorithm");
diff --git a/chromium/components/webcrypto/algorithms/test_helpers.cc b/chromium/components/webcrypto/algorithms/test_helpers.cc
index 394805db7a0..4ca7898ae83 100644
--- a/chromium/components/webcrypto/algorithms/test_helpers.cc
+++ b/chromium/components/webcrypto/algorithms/test_helpers.cc
@@ -138,9 +138,8 @@ std::vector<uint8_t> MakeJsonVector(const base::DictionaryValue& dict) {
return MakeJsonVector(json);
}
-::testing::AssertionResult ReadJsonTestFile(
- const char* test_file_name,
- std::unique_ptr<base::Value>* value) {
+::testing::AssertionResult ReadJsonTestFile(const char* test_file_name,
+ base::Value* value) {
base::FilePath test_data_dir;
if (!base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir))
return ::testing::AssertionFailure() << "Couldn't retrieve test dir";
@@ -162,52 +161,49 @@ std::vector<uint8_t> MakeJsonVector(const base::DictionaryValue& dict) {
re2::RE2::GlobalReplace(&file_contents, re2::RE2("\\s*//.*"), "");
// Parse the JSON to a dictionary.
- *value = base::JSONReader::Read(file_contents);
- if (!*value) {
+ base::Optional<base::Value> read_value =
+ base::JSONReader::Read(file_contents);
+ if (!read_value.has_value()) {
return ::testing::AssertionFailure()
<< "Couldn't parse test file JSON: " << file_path.value();
}
+ *value = std::move(read_value).value();
return ::testing::AssertionSuccess();
}
-::testing::AssertionResult ReadJsonTestFileToList(
- const char* test_file_name,
- std::unique_ptr<base::ListValue>* list) {
+::testing::AssertionResult ReadJsonTestFileToList(const char* test_file_name,
+ base::ListValue* list) {
// Read the JSON.
- std::unique_ptr<base::Value> json;
+ base::Value json;
::testing::AssertionResult result = ReadJsonTestFile(test_file_name, &json);
if (!result)
return result;
// Cast to an ListValue.
- base::ListValue* list_value = nullptr;
- if (!json->GetAsList(&list_value) || !list_value)
+ base::ListValue* json_as_list = nullptr;
+ if (!json.GetAsList(&json_as_list))
return ::testing::AssertionFailure() << "The JSON was not a list";
- list->reset(list_value);
- ignore_result(json.release());
-
+ *list = std::move(*json_as_list);
return ::testing::AssertionSuccess();
}
::testing::AssertionResult ReadJsonTestFileToDictionary(
const char* test_file_name,
- std::unique_ptr<base::DictionaryValue>* dict) {
+ base::DictionaryValue* dict) {
// Read the JSON.
- std::unique_ptr<base::Value> json;
+ base::Value json;
::testing::AssertionResult result = ReadJsonTestFile(test_file_name, &json);
if (!result)
return result;
// Cast to an DictionaryValue.
- base::DictionaryValue* dict_value = nullptr;
- if (!json->GetAsDictionary(&dict_value) || !dict_value)
+ base::DictionaryValue* json_as_dict = nullptr;
+ if (!json.GetAsDictionary(&json_as_dict))
return ::testing::AssertionFailure() << "The JSON was not a dictionary";
- dict->reset(dict_value);
- ignore_result(json.release());
-
+ *dict = std::move(*json_as_dict);
return ::testing::AssertionSuccess();
}
@@ -279,7 +275,7 @@ bool CopiesExist(const std::vector<std::vector<uint8_t>>& bufs) {
blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
blink::WebCryptoAlgorithmId aes_alg_id,
- unsigned short length) {
+ uint16_t length) {
return blink::WebCryptoAlgorithm::AdoptParamsAndCreate(
aes_alg_id, new blink::WebCryptoAesKeyGenParams(length));
}
@@ -385,28 +381,31 @@ Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
usages, key);
}
-std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
+base::Optional<base::DictionaryValue> GetJwkDictionary(
const std::vector<uint8_t>& json) {
base::StringPiece json_string(reinterpret_cast<const char*>(json.data()),
json.size());
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json_string);
- EXPECT_TRUE(value.get());
- EXPECT_TRUE(value->is_dict());
+ base::Optional<base::Value> value = base::JSONReader::Read(json_string);
+ EXPECT_TRUE(value.has_value());
+ EXPECT_TRUE(value.value().is_dict());
+
+ base::DictionaryValue* dict_value = nullptr;
+ if (!value.value().GetAsDictionary(&dict_value))
+ return base::nullopt;
- return std::unique_ptr<base::DictionaryValue>(
- static_cast<base::DictionaryValue*>(value.release()));
+ return std::move(*dict_value);
}
// Verifies the input dictionary contains the expected values. Exact matches are
// required on the fields examined.
::testing::AssertionResult VerifyJwk(
- const std::unique_ptr<base::DictionaryValue>& dict,
+ const base::DictionaryValue& dict,
const std::string& kty_expected,
const std::string& alg_expected,
blink::WebCryptoKeyUsageMask use_mask_expected) {
// ---- kty
std::string value_string;
- if (!dict->GetString("kty", &value_string))
+ if (!dict.GetString("kty", &value_string))
return ::testing::AssertionFailure() << "Missing 'kty'";
if (value_string != kty_expected)
return ::testing::AssertionFailure() << "Expected 'kty' to be "
@@ -414,7 +413,7 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
<< value_string;
// ---- alg
- if (!dict->GetString("alg", &value_string))
+ if (!dict.GetString("alg", &value_string))
return ::testing::AssertionFailure() << "Missing 'alg'";
if (value_string != alg_expected)
return ::testing::AssertionFailure() << "Expected 'alg' to be "
@@ -424,15 +423,15 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
// ---- ext
// always expect ext == true in this case
bool ext_value;
- if (!dict->GetBoolean("ext", &ext_value))
+ if (!dict.GetBoolean("ext", &ext_value))
return ::testing::AssertionFailure() << "Missing 'ext'";
if (!ext_value)
return ::testing::AssertionFailure()
<< "Expected 'ext' to be true but found false";
// ---- key_ops
- base::ListValue* key_ops;
- if (!dict->GetList("key_ops", &key_ops))
+ const base::ListValue* key_ops;
+ if (!dict.GetList("key_ops", &key_ops))
return ::testing::AssertionFailure() << "Missing 'key_ops'";
blink::WebCryptoKeyUsageMask key_ops_mask = 0;
Status status =
@@ -452,13 +451,13 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
const std::string& alg_expected,
const std::string& k_expected_hex,
blink::WebCryptoKeyUsageMask use_mask_expected) {
- std::unique_ptr<base::DictionaryValue> dict = GetJwkDictionary(json);
- if (!dict || dict->empty())
+ base::Optional<base::DictionaryValue> dict = GetJwkDictionary(json);
+ if (!dict.has_value() || dict.value().empty())
return ::testing::AssertionFailure() << "JSON parsing failed";
// ---- k
std::string value_string;
- if (!dict->GetString("k", &value_string))
+ if (!dict.value().GetString("k", &value_string))
return ::testing::AssertionFailure() << "Missing 'k'";
std::string k_value;
if (!Base64DecodeUrlSafe(value_string, &k_value))
@@ -470,7 +469,7 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
<< " but found something different";
}
- return VerifyJwk(dict, "oct", alg_expected, use_mask_expected);
+ return VerifyJwk(dict.value(), "oct", alg_expected, use_mask_expected);
}
::testing::AssertionResult VerifyPublicJwk(
@@ -479,13 +478,13 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
const std::string& n_expected_hex,
const std::string& e_expected_hex,
blink::WebCryptoKeyUsageMask use_mask_expected) {
- std::unique_ptr<base::DictionaryValue> dict = GetJwkDictionary(json);
- if (!dict || dict->empty())
+ base::Optional<base::DictionaryValue> dict = GetJwkDictionary(json);
+ if (!dict.has_value() || dict.value().empty())
return ::testing::AssertionFailure() << "JSON parsing failed";
// ---- n
std::string value_string;
- if (!dict->GetString("n", &value_string))
+ if (!dict.value().GetString("n", &value_string))
return ::testing::AssertionFailure() << "Missing 'n'";
std::string n_value;
if (!Base64DecodeUrlSafe(value_string, &n_value))
@@ -497,7 +496,7 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
// TODO(padolph): LowerCaseEqualsASCII() does not work for above!
// ---- e
- if (!dict->GetString("e", &value_string))
+ if (!dict.value().GetString("e", &value_string))
return ::testing::AssertionFailure() << "Missing 'e'";
std::string e_value;
if (!Base64DecodeUrlSafe(value_string, &e_value))
@@ -509,7 +508,7 @@ std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
<< " but found something different";
}
- return VerifyJwk(dict, "RSA", alg_expected, use_mask_expected);
+ return VerifyJwk(dict.value(), "RSA", alg_expected, use_mask_expected);
}
void ImportExportJwkSymmetricKey(
diff --git a/chromium/components/webcrypto/algorithms/test_helpers.h b/chromium/components/webcrypto/algorithms/test_helpers.h
index 5bf5ce2bc83..cf031b494fb 100644
--- a/chromium/components/webcrypto/algorithms/test_helpers.h
+++ b/chromium/components/webcrypto/algorithms/test_helpers.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "base/optional.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_crypto_algorithm.h"
#include "third_party/blink/public/platform/web_crypto_key.h"
@@ -83,17 +84,15 @@ std::vector<uint8_t> MakeJsonVector(const base::DictionaryValue& dict);
// Reads a file in "src/content/test/data/webcrypto" to a base::Value.
// The file must be JSON, however it can also include C++ style comments.
-::testing::AssertionResult ReadJsonTestFile(
- const char* test_file_name,
- std::unique_ptr<base::Value>* value);
+::testing::AssertionResult ReadJsonTestFile(const char* test_file_name,
+ base::Value* value);
// Same as ReadJsonTestFile(), but returns the value as a List.
-::testing::AssertionResult ReadJsonTestFileToList(
- const char* test_file_name,
- std::unique_ptr<base::ListValue>* list);
+::testing::AssertionResult ReadJsonTestFileToList(const char* test_file_name,
+ base::ListValue* list);
// Same as ReadJsonTestFile(), but returns the value as a Dictionary.
::testing::AssertionResult ReadJsonTestFileToDictionary(
const char* test_file_name,
- std::unique_ptr<base::DictionaryValue>* dict);
+ base::DictionaryValue* dict);
// Reads a string property from the dictionary with path |property_name|
// (which can include periods for nested dictionaries). Interprets the
@@ -113,7 +112,7 @@ bool CopiesExist(const std::vector<std::vector<uint8_t>>& bufs);
blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
blink::WebCryptoAlgorithmId aes_alg_id,
- unsigned short length);
+ uint16_t length);
// The following key pair is comprised of the SPKI (public key) and PKCS#8
// (private key) representations of the key pair provided in Example 1 of the
@@ -148,7 +147,7 @@ Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
blink::WebCryptoKey* key);
// Parses a vector of JSON into a dictionary.
-std::unique_ptr<base::DictionaryValue> GetJwkDictionary(
+base::Optional<base::DictionaryValue> GetJwkDictionary(
const std::vector<uint8_t>& json);
// Verifies the input dictionary contains the expected values. Exact matches are
diff --git a/chromium/components/webcrypto/jwk.cc b/chromium/components/webcrypto/jwk.cc
index b76d6d2fb70..5abc8308e0b 100644
--- a/chromium/components/webcrypto/jwk.cc
+++ b/chromium/components/webcrypto/jwk.cc
@@ -135,7 +135,7 @@ Status GetWebCryptoUsagesFromJwkKeyOps(const base::ListValue* key_ops,
Status VerifyUsages(const JwkReader& jwk,
blink::WebCryptoKeyUsageMask expected_usages) {
// JWK "key_ops" (optional) --> usages parameter
- base::ListValue* jwk_key_ops_value = nullptr;
+ const base::ListValue* jwk_key_ops_value = nullptr;
bool has_jwk_key_ops;
Status status =
jwk.GetOptionalList("key_ops", &jwk_key_ops_value, &has_jwk_key_ops);
@@ -196,16 +196,17 @@ Status JwkReader::Init(const CryptoData& bytes,
base::StringPiece json_string(reinterpret_cast<const char*>(bytes.bytes()),
bytes.byte_length());
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json_string);
- base::DictionaryValue* dict_value = nullptr;
+ {
+ // Limit the visibility for |value| as it is moved to |dict_| (via
+ // |dict_value|) once it has been loaded successfully.
+ base::Optional<base::Value> value = base::JSONReader::Read(json_string);
+ base::DictionaryValue* dict_value = nullptr;
- if (!value || !value->GetAsDictionary(&dict_value) || !dict_value)
- return Status::ErrorJwkNotDictionary();
+ if (!value.has_value() || !value.value().GetAsDictionary(&dict_value))
+ return Status::ErrorJwkNotDictionary();
- // Release |value|, as ownership will be transferred to |dict| via
- // |dict_value|, which points to the same object as |value|.
- ignore_result(value.release());
- dict_.reset(dict_value);
+ dict_ = std::move(*dict_value);
+ }
// JWK "kty". Exit early if this required JWK parameter is missing.
std::string kty;
@@ -235,13 +236,13 @@ Status JwkReader::Init(const CryptoData& bytes,
}
bool JwkReader::HasMember(const std::string& member_name) const {
- return dict_->HasKey(member_name);
+ return dict_.HasKey(member_name);
}
Status JwkReader::GetString(const std::string& member_name,
std::string* result) const {
- base::Value* value = nullptr;
- if (!dict_->Get(member_name, &value))
+ const base::Value* value = nullptr;
+ if (!dict_.Get(member_name, &value))
return Status::ErrorJwkMemberMissing(member_name);
if (!value->GetAsString(result))
return Status::ErrorJwkMemberWrongType(member_name, "string");
@@ -252,8 +253,8 @@ Status JwkReader::GetOptionalString(const std::string& member_name,
std::string* result,
bool* member_exists) const {
*member_exists = false;
- base::Value* value = nullptr;
- if (!dict_->Get(member_name, &value))
+ const base::Value* value = nullptr;
+ if (!dict_.Get(member_name, &value))
return Status::Success();
if (!value->GetAsString(result))
@@ -264,11 +265,11 @@ Status JwkReader::GetOptionalString(const std::string& member_name,
}
Status JwkReader::GetOptionalList(const std::string& member_name,
- base::ListValue** result,
+ const base::ListValue** result,
bool* member_exists) const {
*member_exists = false;
- base::Value* value = nullptr;
- if (!dict_->Get(member_name, &value))
+ const base::Value* value = nullptr;
+ if (!dict_.Get(member_name, &value))
return Status::Success();
if (!value->GetAsList(result))
@@ -318,8 +319,8 @@ Status JwkReader::GetOptionalBool(const std::string& member_name,
bool* result,
bool* member_exists) const {
*member_exists = false;
- base::Value* value = nullptr;
- if (!dict_->Get(member_name, &value))
+ const base::Value* value = nullptr;
+ if (!dict_.Get(member_name, &value))
return Status::Success();
if (!value->GetAsBoolean(result))
diff --git a/chromium/components/webcrypto/jwk.h b/chromium/components/webcrypto/jwk.h
index ea022f57360..0f81f1cff3d 100644
--- a/chromium/components/webcrypto/jwk.h
+++ b/chromium/components/webcrypto/jwk.h
@@ -69,7 +69,7 @@ class JwkReader {
//
// NOTE: |*result| is owned by the JwkReader.
Status GetOptionalList(const std::string& member_name,
- base::ListValue** result,
+ const base::ListValue** result,
bool* member_exists) const;
// Extracts the required string member |member_name| and saves the
@@ -99,7 +99,7 @@ class JwkReader {
Status VerifyAlg(const std::string& expected_alg) const;
private:
- std::unique_ptr<base::DictionaryValue> dict_;
+ base::DictionaryValue dict_;
};
// Helper class for building the JSON for a JWK.
diff --git a/chromium/components/webdata/common/web_database_migration_unittest.cc b/chromium/components/webdata/common/web_database_migration_unittest.cc
index 2f0dcc072d2..eb338ba3b16 100644
--- a/chromium/components/webdata/common/web_database_migration_unittest.cc
+++ b/chromium/components/webdata/common/web_database_migration_unittest.cc
@@ -156,7 +156,7 @@ TEST_F(WebDatabaseMigrationTest, VersionXxSqlFilesAreGolden) {
connection.Raze();
const base::FilePath& file_name = base::FilePath::FromUTF8Unsafe(
- "version_" + base::IntToString(i) + ".sql");
+ "version_" + base::NumberToString(i) + ".sql");
ASSERT_NO_FATAL_FAILURE(LoadDatabase(file_name.value()))
<< "Failed to load " << file_name.MaybeAsASCII();
DoMigration();
diff --git a/chromium/components/webdata/common/web_database_service.h b/chromium/components/webdata/common/web_database_service.h
index 58ef7632295..c6263206471 100644
--- a/chromium/components/webdata/common/web_database_service.h
+++ b/chromium/components/webdata/common/web_database_service.h
@@ -107,7 +107,7 @@ class WEBDATA_EXPORT WebDatabaseService
// be stored or called.
void RegisterDBErrorCallback(const DBLoadErrorCallback& callback);
- bool db_loaded() const { return db_loaded_; };
+ bool db_loaded() const { return db_loaded_; }
private:
class BackendDelegate;
diff --git a/chromium/components/webrtc_logging/browser/log_cleanup.cc b/chromium/components/webrtc_logging/browser/log_cleanup.cc
index a04ae557c05..827f3e5358f 100644
--- a/chromium/components/webrtc_logging/browser/log_cleanup.cc
+++ b/chromium/components/webrtc_logging/browser/log_cleanup.cc
@@ -50,7 +50,8 @@ void DeleteOldWebRtcLogFiles(const base::FilePath& log_dir) {
void DeleteOldAndRecentWebRtcLogFiles(const base::FilePath& log_dir,
const base::Time& delete_begin_time) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+ base::BlockingType::MAY_BLOCK);
if (!base::PathExists(log_dir)) {
// This will happen if no logs have been stored or uploaded.
diff --git a/chromium/components/wifi/fake_wifi_service.cc b/chromium/components/wifi/fake_wifi_service.cc
index 2db91c77636..26b0eb7033c 100644
--- a/chromium/components/wifi/fake_wifi_service.cc
+++ b/chromium/components/wifi/fake_wifi_service.cc
@@ -211,13 +211,14 @@ void FakeWiFiService::NotifyNetworkListChanged(const NetworkList& networks) {
}
task_runner_->PostTask(
- FROM_HERE, base::Bind(network_list_changed_observer_, current_networks));
+ FROM_HERE,
+ base::BindOnce(network_list_changed_observer_, current_networks));
}
void FakeWiFiService::NotifyNetworkChanged(const std::string& network_guid) {
WiFiService::NetworkGuidList changed_networks(1, network_guid);
task_runner_->PostTask(
- FROM_HERE, base::Bind(networks_changed_observer_, changed_networks));
+ FROM_HERE, base::BindOnce(networks_changed_observer_, changed_networks));
}
} // namespace wifi
diff --git a/chromium/components/wifi/wifi_service_mac.mm b/chromium/components/wifi/wifi_service_mac.mm
index ad40c2a9fc5..4719569e345 100644
--- a/chromium/components/wifi/wifi_service_mac.mm
+++ b/chromium/components/wifi/wifi_service_mac.mm
@@ -401,8 +401,8 @@ void WiFiServiceMac::SetEventObservers(
DVLOG(1) << "Received CWSSIDDidChangeNotification";
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&WiFiServiceMac::OnWlanObserverNotification,
- base::Unretained(this)));
+ base::BindOnce(&WiFiServiceMac::OnWlanObserverNotification,
+ base::Unretained(this)));
};
wlan_observer_ = [[NSNotificationCenter defaultCenter]
@@ -602,7 +602,8 @@ void WiFiServiceMac::NotifyNetworkListChanged(const NetworkList& networks) {
}
event_task_runner_->PostTask(
- FROM_HERE, base::Bind(network_list_changed_observer_, current_networks));
+ FROM_HERE,
+ base::BindOnce(network_list_changed_observer_, current_networks));
}
void WiFiServiceMac::NotifyNetworkChanged(const std::string& network_guid) {
@@ -612,7 +613,7 @@ void WiFiServiceMac::NotifyNetworkChanged(const std::string& network_guid) {
DVLOG(1) << "NotifyNetworkChanged: " << network_guid;
NetworkGuidList changed_networks(1, network_guid);
event_task_runner_->PostTask(
- FROM_HERE, base::Bind(networks_changed_observer_, changed_networks));
+ FROM_HERE, base::BindOnce(networks_changed_observer_, changed_networks));
}
// static
diff --git a/chromium/components/wifi/wifi_service_win.cc b/chromium/components/wifi/wifi_service_win.cc
index 9dc82c0c826..1a18583955a 100644
--- a/chromium/components/wifi/wifi_service_win.cc
+++ b/chromium/components/wifi/wifi_service_win.cc
@@ -845,17 +845,18 @@ void WiFiServiceImpl::OnWlanNotification(
reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>(
wlan_notification_data->pData);
event_task_runner_->PostTask(
- FROM_HERE, base::Bind(&WiFiServiceImpl::NotifyNetworkChanged,
- base::Unretained(this),
- GUIDFromSSID(wlan_connection_data->dot11Ssid)));
+ FROM_HERE,
+ base::BindOnce(&WiFiServiceImpl::NotifyNetworkChanged,
+ base::Unretained(this),
+ GUIDFromSSID(wlan_connection_data->dot11Ssid)));
break;
}
case wlan_notification_acm_scan_complete:
case wlan_notification_acm_interface_removal:
event_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&WiFiServiceImpl::OnNetworkScanCompleteOnMainThread,
- base::Unretained(this)));
+ base::BindOnce(&WiFiServiceImpl::OnNetworkScanCompleteOnMainThread,
+ base::Unretained(this)));
break;
}
}
@@ -941,10 +942,8 @@ void WiFiServiceImpl::WaitForNetworkConnect(const std::string& network_guid,
// Continue waiting for network connection state change.
task_runner_->PostDelayedTask(
FROM_HERE,
- base::Bind(&WiFiServiceImpl::WaitForNetworkConnect,
- base::Unretained(this),
- network_guid,
- ++attempt),
+ base::BindOnce(&WiFiServiceImpl::WaitForNetworkConnect,
+ base::Unretained(this), network_guid, ++attempt),
base::TimeDelta::FromMilliseconds(kAttemptDelayMs));
}
}
@@ -1806,7 +1805,8 @@ void WiFiServiceImpl::NotifyNetworkListChanged(const NetworkList& networks) {
}
event_task_runner_->PostTask(
- FROM_HERE, base::Bind(network_list_changed_observer_, current_networks));
+ FROM_HERE,
+ base::BindOnce(network_list_changed_observer_, current_networks));
}
void WiFiServiceImpl::NotifyNetworkChanged(const std::string& network_guid) {
@@ -1814,7 +1814,8 @@ void WiFiServiceImpl::NotifyNetworkChanged(const std::string& network_guid) {
DVLOG(1) << "NotifyNetworkChanged: " << network_guid;
NetworkGuidList changed_networks(1, network_guid);
event_task_runner_->PostTask(
- FROM_HERE, base::Bind(networks_changed_observer_, changed_networks));
+ FROM_HERE,
+ base::BindOnce(networks_changed_observer_, changed_networks));
}
}
diff --git a/chromium/components/zoom/page_zoom.cc b/chromium/components/zoom/page_zoom.cc
index d683926d867..2049f67d544 100644
--- a/chromium/components/zoom/page_zoom.cc
+++ b/chromium/components/zoom/page_zoom.cc
@@ -17,7 +17,6 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_zoom.h"
-#include "content/public/common/renderer_preferences.h"
using base::UserMetricsAction;
diff --git a/chromium/components/zoom/zoom_controller.cc b/chromium/components/zoom/zoom_controller.cc
index b68c2d327fd..3a66e896de1 100644
--- a/chromium/components/zoom/zoom_controller.cc
+++ b/chromium/components/zoom/zoom_controller.cc
@@ -4,6 +4,7 @@
#include "components/zoom/zoom_controller.h"
+#include "base/bind.h"
#include "components/zoom/zoom_event_manager.h"
#include "components/zoom/zoom_observer.h"
#include "content/public/browser/browser_thread.h"
diff --git a/chromium/components/zucchini/main_utils.cc b/chromium/components/zucchini/main_utils.cc
index 6a09b32c8ba..3e6ff2d1700 100644
--- a/chromium/components/zucchini/main_utils.cc
+++ b/chromium/components/zucchini/main_utils.cc
@@ -91,7 +91,7 @@ void GetPeakMemoryMetrics(size_t* peak_virtual_memory,
*resident_set_size_hwm = 0;
auto status_path =
base::FilePath("/proc")
- .Append(base::IntToString(base::GetCurrentProcessHandle()))
+ .Append(base::NumberToString(base::GetCurrentProcessHandle()))
.Append("status");
std::string contents_string;
base::ReadFileToString(status_path, &contents_string);
diff --git a/chromium/components/zucchini/rel32_utils.h b/chromium/components/zucchini/rel32_utils.h
index 7a01230d121..ff9e7127626 100644
--- a/chromium/components/zucchini/rel32_utils.h
+++ b/chromium/components/zucchini/rel32_utils.h
@@ -5,18 +5,22 @@
#ifndef COMPONENTS_ZUCCHINI_REL32_UTILS_H_
#define COMPONENTS_ZUCCHINI_REL32_UTILS_H_
+#include <algorithm>
+#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "components/zucchini/address_translator.h"
+#include "components/zucchini/arm_utils.h"
#include "components/zucchini/buffer_view.h"
#include "components/zucchini/image_utils.h"
+#include "components/zucchini/io_utils.h"
namespace zucchini {
-// A visitor that emits References (locations and target) from a specified
-// portion of an x86 / x64 image, given a list of valid locations.
+// Reader that emits x86 / x64 References (locations and target) from a list of
+// valid locations, constrained by a portion of an image.
class Rel32ReaderX86 : public ReferenceReader {
public:
// |image| is an image containing x86 / x64 code in [|lo|, |hi|).
@@ -45,7 +49,7 @@ class Rel32ReaderX86 : public ReferenceReader {
DISALLOW_COPY_AND_ASSIGN(Rel32ReaderX86);
};
-// Writer for x86 / x64 rel32 references.
+// Writer for x86 / x64 rel32 References.
class Rel32WriterX86 : public ReferenceWriter {
public:
// |image| wraps the raw bytes of a binary in which rel32 references will be
@@ -65,6 +69,114 @@ class Rel32WriterX86 : public ReferenceWriter {
DISALLOW_COPY_AND_ASSIGN(Rel32WriterX86);
};
+// Reader that emits x86 / x64 References (locations and target) of a spcific
+// type from a list of valid locations, constrained by a portion of an image.
+template <class ADDR_TRAITS>
+class Rel32ReaderArm : public ReferenceReader {
+ public:
+ using CODE_T = typename ADDR_TRAITS::code_t;
+
+ Rel32ReaderArm(const AddressTranslator& translator,
+ ConstBufferView view,
+ const std::vector<offset_t>& rel32_locations,
+ offset_t lo,
+ offset_t hi)
+ : view_(view),
+ offset_to_rva_(translator),
+ rva_to_offset_(translator),
+ hi_(hi) {
+ cur_it_ =
+ std::lower_bound(rel32_locations.begin(), rel32_locations.end(), lo);
+ rel32_end_ = rel32_locations.end();
+ }
+
+ base::Optional<Reference> GetNext() override {
+ while (cur_it_ < rel32_end_ && *cur_it_ < hi_) {
+ offset_t location = *(cur_it_++);
+ CODE_T code = ADDR_TRAITS::Fetch(view_, location);
+ rva_t instr_rva = offset_to_rva_.Convert(location);
+ rva_t target_rva = kInvalidRva;
+ if (ADDR_TRAITS::Read(instr_rva, code, &target_rva)) {
+ offset_t target = rva_to_offset_.Convert(target_rva);
+ if (target != kInvalidOffset)
+ return Reference{location, target};
+ }
+ }
+ return base::nullopt;
+ }
+
+ private:
+ ConstBufferView view_;
+ AddressTranslator::OffsetToRvaCache offset_to_rva_;
+ AddressTranslator::RvaToOffsetCache rva_to_offset_;
+ std::vector<offset_t>::const_iterator cur_it_;
+ std::vector<offset_t>::const_iterator rel32_end_;
+ offset_t hi_;
+
+ DISALLOW_COPY_AND_ASSIGN(Rel32ReaderArm);
+};
+
+// Writer for ARM rel32 References of a specific type.
+template <class ADDR_TRAITS>
+class Rel32WriterArm : public ReferenceWriter {
+ public:
+ using CODE_T = typename ADDR_TRAITS::code_t;
+
+ Rel32WriterArm(const AddressTranslator& translator,
+ MutableBufferView mutable_view)
+ : mutable_view_(mutable_view), offset_to_rva_(translator) {}
+
+ void PutNext(Reference ref) override {
+ CODE_T code = ADDR_TRAITS::Fetch(mutable_view_, ref.location);
+ rva_t instr_rva = offset_to_rva_.Convert(ref.location);
+ rva_t target_rva = offset_to_rva_.Convert(ref.target);
+ if (ADDR_TRAITS::Write(instr_rva, target_rva, &code)) {
+ ADDR_TRAITS::Store(mutable_view_, ref.location, code);
+ } else {
+ LOG(ERROR) << "Write error: " << AsHex<8>(ref.location) << ": "
+ << AsHex<static_cast<int>(sizeof(CODE_T)) * 2>(code)
+ << " <= " << AsHex<8>(target_rva) << ".";
+ }
+ }
+
+ private:
+ MutableBufferView mutable_view_;
+ AddressTranslator::OffsetToRvaCache offset_to_rva_;
+
+ DISALLOW_COPY_AND_ASSIGN(Rel32WriterArm);
+};
+
+// Type for specialized versions of ArmCopyDisp().
+// TODO(etiennep/huangs): Fold ReferenceByteMixer into Disassembler and remove
+// direct function pointer usage.
+typedef bool (*ArmCopyDispFun)(ConstBufferView src_view,
+ offset_t src_idx,
+ MutableBufferView dst_view,
+ offset_t dst_idx);
+
+// Copier that makes |*dst_it| similar to |*src_it| (both assumed to point to
+// rel32 instructions of type ADDR_TRAITS) by copying the displacement (i.e.,
+// payload bits) from |src_it| to |dst_it|. If successful, updates |*dst_it|,
+// and returns true. Otherwise returns false. Note that alignment is not an
+// issue since the displacement is not translated to target RVA!
+template <class ADDR_TRAITS>
+bool ArmCopyDisp(ConstBufferView src_view,
+ offset_t src_idx,
+ MutableBufferView dst_view,
+ offset_t dst_idx) {
+ using CODE_T = typename ADDR_TRAITS::code_t;
+ CODE_T src_code = ADDR_TRAITS::Fetch(src_view, src_idx);
+ arm_disp_t disp = 0;
+ if (ADDR_TRAITS::Decode(src_code, &disp)) {
+ CODE_T dst_code = ADDR_TRAITS::Fetch(dst_view, dst_idx);
+ if (ADDR_TRAITS::Encode(disp, &dst_code)) {
+ ADDR_TRAITS::Store(dst_view, dst_idx, dst_code);
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace zucchini
#endif // COMPONENTS_ZUCCHINI_REL32_UTILS_H_
diff --git a/chromium/components/zucchini/rel32_utils_unittest.cc b/chromium/components/zucchini/rel32_utils_unittest.cc
index 29e8560d8a8..e3d34f41432 100644
--- a/chromium/components/zucchini/rel32_utils_unittest.cc
+++ b/chromium/components/zucchini/rel32_utils_unittest.cc
@@ -7,11 +7,13 @@
#include <stdint.h>
#include <memory>
+#include <utility>
#include <vector>
#include "base/optional.h"
#include "base/test/gtest_util.h"
#include "components/zucchini/address_translator.h"
+#include "components/zucchini/arm_utils.h"
#include "components/zucchini/image_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,7 +33,7 @@ class TestAddressTranslator : public AddressTranslator {
// Checks that |reader| emits and only emits |expected_refs|, in order.
void CheckReader(const std::vector<Reference>& expected_refs,
- ReferenceReader* reader) {
+ std::unique_ptr<ReferenceReader> reader) {
for (Reference expected_ref : expected_refs) {
auto ref = reader->GetNext();
EXPECT_TRUE(ref.has_value());
@@ -40,6 +42,31 @@ void CheckReader(const std::vector<Reference>& expected_refs,
EXPECT_EQ(base::nullopt, reader->GetNext()); // Nothing should be left.
}
+// Copies displacements from |bytes1| to |bytes2| and checks results against
+// |bytes_exp_1_to_2|. Then repeats for |*bytes2| , |*byte1|, and
+// |bytes_exp_2_to_1|. Empty expected bytes mean failure is expected. The copy
+// function is specified by |copier|.
+void CheckCopy(const std::vector<uint8_t>& bytes_exp_1_to_2,
+ const std::vector<uint8_t>& bytes_exp_2_to_1,
+ const std::vector<uint8_t>& bytes1,
+ const std::vector<uint8_t>& bytes2,
+ ArmCopyDispFun copier) {
+ auto run_test = [&copier](const std::vector<uint8_t>& bytes_exp,
+ const std::vector<uint8_t>& bytes_in,
+ std::vector<uint8_t> bytes_out) {
+ ConstBufferView buffer_in(&bytes_in[0], bytes_in.size());
+ MutableBufferView buffer_out(&bytes_out[0], bytes_out.size());
+ if (bytes_exp.empty()) {
+ EXPECT_FALSE(copier(buffer_in, 0U, buffer_out, 0U));
+ } else {
+ EXPECT_TRUE(copier(buffer_in, 0U, buffer_out, 0U));
+ EXPECT_EQ(bytes_exp, bytes_out);
+ }
+ };
+ run_test(bytes_exp_1_to_2, bytes1, bytes2);
+ run_test(bytes_exp_2_to_1, bytes2, bytes1);
+}
+
} // namespace
TEST(Rel32UtilsTest, Rel32ReaderX86) {
@@ -64,24 +91,24 @@ TEST(Rel32UtilsTest, Rel32ReaderX86) {
std::vector<offset_t> rel32_locations = {0x0008U, 0x0010U, 0x0018U, 0x001CU};
// Generate everything.
- Rel32ReaderX86 reader1(buffer, 0x0000U, 0x0020U, &rel32_locations,
- translator);
+ auto reader1 = std::make_unique<Rel32ReaderX86>(buffer, 0x0000U, 0x0020U,
+ &rel32_locations, translator);
CheckReader({{0x0008U, 0x0010U},
{0x0010U, 0x0014U},
{0x0018U, 0x0010U},
{0x001CU, 0x0004U}},
- &reader1);
+ std::move(reader1));
// Exclude last.
- Rel32ReaderX86 reader2(buffer, 0x0000U, 0x001CU, &rel32_locations,
- translator);
+ auto reader2 = std::make_unique<Rel32ReaderX86>(buffer, 0x0000U, 0x001CU,
+ &rel32_locations, translator);
CheckReader({{0x0008U, 0x0010U}, {0x0010U, 0x0014U}, {0x0018U, 0x0010U}},
- &reader2);
+ std::move(reader2));
// Only find one.
- Rel32ReaderX86 reader3(buffer, 0x000CU, 0x0018U, &rel32_locations,
- translator);
- CheckReader({{0x0010U, 0x0014U}}, &reader3);
+ auto reader3 = std::make_unique<Rel32ReaderX86>(buffer, 0x000CU, 0x0018U,
+ &rel32_locations, translator);
+ CheckReader({{0x0010U, 0x0014U}}, std::move(reader3));
}
TEST(Rel32UtilsTest, Rel32WriterX86) {
@@ -118,4 +145,392 @@ TEST(Rel32UtilsTest, Rel32WriterX86) {
bytes);
}
+TEST(Rel32UtilsTest, Rel32ReaderArm_Arm32) {
+ constexpr offset_t kTestImageSize = 0x00100000U;
+ constexpr rva_t kRvaBegin = 0x00030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ // A24.
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030000: (Filler)
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030004: (Filler)
+ 0x00, 0x00, 0x00, 0xEA, // 00030008: B 00030010 ; A24
+ 0xFF, 0xFF, 0xFF, 0xFF, // 0003000C: (Filler)
+ 0xFF, 0xFF, 0xFF, 0xEB, // 00030010: BL 00030014 ; A24
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030014: (Filler)
+ 0xFC, 0xFF, 0xFF, 0xEB, // 00030018: BL 00030010 ; A24
+ 0xF8, 0xFF, 0xFF, 0xEA, // 0003001C: B 00030004 ; A24
+ };
+ ConstBufferView region(&bytes[0], bytes.size());
+ // Specify rel32 locations directly, instead of parsing.
+ std::vector<offset_t> rel32_locations_A24 = {0x0008U, 0x0010U, 0x0018U,
+ 0x001CU};
+
+ // Generate everything.
+ auto reader1 =
+ std::make_unique<Rel32ReaderArm<Arm32Rel32Translator::AddrTraits_A24>>(
+ translator, region, rel32_locations_A24, 0x0000U, 0x0020U);
+ CheckReader({{0x0008U, 0x0010U},
+ {0x0010U, 0x0014U},
+ {0x0018U, 0x0010U},
+ {0x001CU, 0x0004U}},
+ std::move(reader1));
+
+ // Exclude last.
+ auto reader2 =
+ std::make_unique<Rel32ReaderArm<Arm32Rel32Translator::AddrTraits_A24>>(
+ translator, region, rel32_locations_A24, 0x0000U, 0x001CU);
+ CheckReader({{0x0008U, 0x0010U}, {0x0010U, 0x0014U}, {0x0018U, 0x0010U}},
+ std::move(reader2));
+
+ // Only find one.
+ auto reader3 =
+ std::make_unique<Rel32ReaderArm<Arm32Rel32Translator::AddrTraits_A24>>(
+ translator, region, rel32_locations_A24, 0x000CU, 0x0018U);
+ CheckReader({{0x0010U, 0x0014U}}, std::move(reader3));
+}
+
+TEST(Rel32UtilsTest, Rel32WriterArm_Arm32_Easy) {
+ constexpr offset_t kTestImageSize = 0x00100000U;
+ constexpr rva_t kRvaBegin = 0x00030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, // 00030000: (Filler)
+ 0x01, 0xDE, // 00030002: B 00030008 ; T8
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030004: (Filler)
+ 0x01, 0xE0, // 00030008: B 0003000E ; T11
+ 0xFF, 0xFF, // 0003000A: (Filler)
+ 0x80, 0xF3, 0x00, 0x80, // 0003000C: B 00030010 ; T20
+ };
+ MutableBufferView region(&bytes[0], bytes.size());
+
+ auto writer1 =
+ std::make_unique<Rel32WriterArm<Arm32Rel32Translator::AddrTraits_T8>>(
+ translator, region);
+ writer1->PutNext({0x0002U, 0x0004U});
+ EXPECT_EQ(0xFF, bytes[0x02]); // 00030002: B 00030004 ; T8
+ EXPECT_EQ(0xDE, bytes[0x03]);
+
+ writer1->PutNext({0x0002U, 0x000AU});
+ EXPECT_EQ(0x02, bytes[0x02]); // 00030002: B 0003000A ; T8
+ EXPECT_EQ(0xDE, bytes[0x03]);
+
+ auto writer2 =
+ std::make_unique<Rel32WriterArm<Arm32Rel32Translator::AddrTraits_T11>>(
+ translator, region);
+ writer2->PutNext({0x0008U, 0x0008U});
+ EXPECT_EQ(0xFE, bytes[0x08]); // 00030008: B 00030008 ; T11
+ EXPECT_EQ(0xE7, bytes[0x09]);
+ writer2->PutNext({0x0008U, 0x0010U});
+ EXPECT_EQ(0x02, bytes[0x08]); // 00030008: B 00030010 ; T11
+ EXPECT_EQ(0xE0, bytes[0x09]);
+
+ auto writer3 =
+ std::make_unique<Rel32WriterArm<Arm32Rel32Translator::AddrTraits_T20>>(
+ translator, region);
+ writer3->PutNext({0x000CU, 0x000AU});
+ EXPECT_EQ(0xBF, bytes[0x0C]); // 0003000C: B 0003000A ; T20
+ EXPECT_EQ(0xF7, bytes[0x0D]);
+ EXPECT_EQ(0xFD, bytes[0x0E]);
+ EXPECT_EQ(0xAF, bytes[0x0F]);
+ writer3->PutNext({0x000CU, 0x0010U});
+ EXPECT_EQ(0x80, bytes[0x0C]); // 0003000C: B 00030010 ; T20
+ EXPECT_EQ(0xF3, bytes[0x0D]);
+ EXPECT_EQ(0x00, bytes[0x0E]);
+ EXPECT_EQ(0x80, bytes[0x0F]);
+}
+
+TEST(Rel32UtilsTest, Rel32WriterArm_Arm32_Hard) {
+ constexpr offset_t kTestImageSize = 0x10000000U;
+ constexpr rva_t kRvaBegin = 0x0C030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, // 0C030000: (Filler)
+ 0x00, 0xF0, 0x00, 0xB8, // 0C030002: B 0C030006 ; T24
+ 0xFF, 0xFF, 0xFF, 0xFF, // 0C030006: (Filler)
+ 0x00, 0xF0, 0x7A, 0xE8, // 0C03000A: BLX 0C030100 ; T24
+ 0xFF, 0xFF, // 0C03000E: (Filler)
+ 0x00, 0xF0, 0x7A, 0xE8, // 0C030010: BLX 0C030108 ; T24
+ };
+ MutableBufferView region(&bytes[0], bytes.size());
+
+ auto writer =
+ std::make_unique<Rel32WriterArm<Arm32Rel32Translator::AddrTraits_T24>>(
+ translator, region);
+ writer->PutNext({0x0002U, 0x0000U});
+ EXPECT_EQ(0xFF, bytes[0x02]); // 0C030002: B 0C030000 ; T24
+ EXPECT_EQ(0xF7, bytes[0x03]);
+ EXPECT_EQ(0xFD, bytes[0x04]);
+ EXPECT_EQ(0xBF, bytes[0x05]);
+ writer->PutNext({0x0002U, 0x0008U});
+ EXPECT_EQ(0x00, bytes[0x02]); // 0C030002: B 0C030008 ; T24
+ EXPECT_EQ(0xF0, bytes[0x03]);
+ EXPECT_EQ(0x01, bytes[0x04]);
+ EXPECT_EQ(0xB8, bytes[0x05]);
+
+ // BLX complication, with location that's not 4-byte aligned.
+ writer->PutNext({0x000AU, 0x0010U});
+ EXPECT_EQ(0x00, bytes[0x0A]); // 0C03000A: BLX 0C030010 ; T24
+ EXPECT_EQ(0xF0, bytes[0x0B]);
+ EXPECT_EQ(0x02, bytes[0x0C]);
+ EXPECT_EQ(0xE8, bytes[0x0D]);
+ writer->PutNext({0x000AU, 0x0100U});
+ EXPECT_EQ(0x00, bytes[0x0A]); // 0C03000A: BLX 0C030100 ; T24
+ EXPECT_EQ(0xF0, bytes[0x0B]);
+ EXPECT_EQ(0x7A, bytes[0x0C]);
+ EXPECT_EQ(0xE8, bytes[0x0D]);
+ writer->PutNext({0x000AU, 0x0000U});
+ EXPECT_EQ(0xFF, bytes[0x0A]); // 0C03000A: BLX 0C030000 ; T24
+ EXPECT_EQ(0xF7, bytes[0x0B]);
+ EXPECT_EQ(0xFA, bytes[0x0C]);
+ EXPECT_EQ(0xEF, bytes[0x0D]);
+
+ // BLX complication, with location that's 4-byte aligned.
+ writer->PutNext({0x0010U, 0x0010U});
+ EXPECT_EQ(0xFF, bytes[0x10]); // 0C030010: BLX 0C030010 ; T24
+ EXPECT_EQ(0xF7, bytes[0x11]);
+ EXPECT_EQ(0xFE, bytes[0x12]);
+ EXPECT_EQ(0xEF, bytes[0x13]);
+ writer->PutNext({0x0010U, 0x0108U});
+ EXPECT_EQ(0x00, bytes[0x10]); // 0C030010: BLX 0C030108 ; T24
+ EXPECT_EQ(0xF0, bytes[0x11]);
+ EXPECT_EQ(0x7A, bytes[0x12]);
+ EXPECT_EQ(0xE8, bytes[0x13]);
+}
+
+// Test BLX encoding A2, which is an ARM instruction that switches to THUMB2,
+// and therefore should have 2-byte alignment.
+TEST(Rel32UtilsTest, Arm32SwitchToThumb2) {
+ constexpr offset_t kTestImageSize = 0x10000000U;
+ constexpr rva_t kRvaBegin = 0x08030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, 0x00, 0x00, // 08030000: (Filler)
+ 0x00, 0x00, 0x00, 0xFA, // 08030004: BLX 0803000C ; A24
+ };
+ MutableBufferView region(&bytes[0], bytes.size());
+
+ auto writer =
+ std::make_unique<Rel32WriterArm<Arm32Rel32Translator::AddrTraits_A24>>(
+ translator, region);
+
+ // To location that's 4-byte aligned.
+ writer->PutNext({0x0004U, 0x0100U});
+ EXPECT_EQ(0x3D, bytes[0x04]); // 08030004: BLX 08030100 ; A24
+ EXPECT_EQ(0x00, bytes[0x05]);
+ EXPECT_EQ(0x00, bytes[0x06]);
+ EXPECT_EQ(0xFA, bytes[0x07]);
+
+ // To location that's 2-byte aligned but not 4-byte aligned.
+ writer->PutNext({0x0004U, 0x0052U});
+ EXPECT_EQ(0x11, bytes[0x04]); // 08030004: BLX 08030052 ; A24
+ EXPECT_EQ(0x00, bytes[0x05]);
+ EXPECT_EQ(0x00, bytes[0x06]);
+ EXPECT_EQ(0xFB, bytes[0x07]);
+
+ // Clean slate code.
+ writer->PutNext({0x0004U, 0x000CU});
+ EXPECT_EQ(0x00, bytes[0x04]); // 08030004: BLX 0803000C ; A24
+ EXPECT_EQ(0x00, bytes[0x05]);
+ EXPECT_EQ(0x00, bytes[0x06]);
+ EXPECT_EQ(0xFA, bytes[0x07]);
+}
+
+TEST(Rel32UtilsTest, ArmCopyDisp_Arm32) {
+ std::vector<uint8_t> expect_fail;
+
+ // Successful A24.
+ ArmCopyDispFun copier_A24 = ArmCopyDisp<Arm32Rel32Translator::AddrTraits_A24>;
+ CheckCopy({0x12, 0x34, 0x56, 0xEB}, // 00000100: BL 0158D150
+ {0xA0, 0xC0, 0x0E, 0x2A}, // 00000100: BCS 003B0388
+ {0x12, 0x34, 0x56, 0x2A}, // 00000100: BCS 0158D150
+ {0xA0, 0xC0, 0x0E, 0xEB}, // 00000100: BL 003B0388
+ copier_A24);
+
+ // Successful T8.
+ ArmCopyDispFun copier_T8 = ArmCopyDisp<Arm32Rel32Translator::AddrTraits_T8>;
+ CheckCopy({0x12, 0xD5}, // 00000100: BPL 00000128
+ {0xAB, 0xD8}, // 00000100: BHI 0000005A
+ {0x12, 0xD8}, // 00000100: BHI 00000128
+ {0xAB, 0xD5}, // 00000100: BPL 0000005A
+ copier_T8);
+
+ // Successful T11.
+ ArmCopyDispFun copier_T11 = ArmCopyDisp<Arm32Rel32Translator::AddrTraits_T11>;
+ CheckCopy({0xF5, 0xE0}, // 00000100: B 000002EE
+ {0x12, 0xE7}, // 00000100: B FFFFFF28
+ {0xF5, 0xE0}, // 00000100: B 000002EE
+ {0x12, 0xE7}, // 00000100: B FFFFFF28
+ copier_T11);
+
+ // Failure if wrong copier is used.
+ CheckCopy(expect_fail, expect_fail, {0xF5, 0xE0}, {0x12, 0xE7}, copier_T8);
+
+ // Successful T20.
+ ArmCopyDispFun copier_T20 = ArmCopyDisp<Arm32Rel32Translator::AddrTraits_T20>;
+ CheckCopy({0x41, 0xF2, 0xA5, 0x88}, // 00000100: BLS.W 0008124E
+ {0x04, 0xF3, 0x3C, 0xA2}, // 00000100: BGT.W 0004457C
+ {0x01, 0xF3, 0xA5, 0x88}, // 00000100: BGT.W 0008124E
+ {0x44, 0xF2, 0x3C, 0xA2}, // 00000100: BLS.W 0004457C
+ copier_T20);
+ CheckCopy({0x7F, 0xF6, 0xFF, 0xAF}, // 00000100: BLS.W 00000102
+ {0x00, 0xF3, 0x00, 0x80}, // 00000100: BGT.W 00000104
+ {0x3F, 0xF7, 0xFF, 0xAF}, // 00000100: BGT.W 00000102
+ {0x40, 0xF2, 0x00, 0x80}, // 00000100: BLS.W 00000104
+ copier_T20);
+
+ // Failure if wrong copier is used.
+ CheckCopy(expect_fail, expect_fail, {0x41, 0xF2, 0xA5, 0x88},
+ {0x84, 0xF3, 0x3C, 0xA2}, copier_A24);
+
+ // T24: Mix B encoding T4 and BL encoding T1.
+ ArmCopyDispFun copier_T24 = ArmCopyDisp<Arm32Rel32Translator::AddrTraits_T24>;
+ CheckCopy({0xFF, 0xF7, 0xFF, 0xFF}, // 00000100: BL 00000102
+ {0x00, 0xF0, 0x00, 0x90}, // 00000100: B.W 00C00104
+ {0xFF, 0xF7, 0xFF, 0xBF}, // 00000100: B.W 00000102
+ {0x00, 0xF0, 0x00, 0xD0}, // 00000100: BL 00C00104
+ copier_T24);
+
+ // Mix B encoding T4 and BLX encoding T2. Note that the forward direction
+ // fails because B's target is invalid for BLX! It's possible to do "best
+ // effort" copying to reduce diff -- but right now we're not doing this.
+ CheckCopy(expect_fail, {0x00, 0xF0, 0x00, 0x90}, // 00000100: B.W 00C00104
+ {0xFF, 0xF7, 0xFF, 0xBF}, // 00000100: B.W 00000102
+ {0x00, 0xF0, 0x00, 0xC0}, // 00000100: BLX 00C00104
+ copier_T24);
+ // Success if ow B's target is valid for BLX.
+ CheckCopy({0xFF, 0xF7, 0xFE, 0xEF}, // 00000100: BLX 00000100
+ {0x00, 0xF0, 0x00, 0x90}, // 00000100: B.W 00C00104
+ {0xFF, 0xF7, 0xFE, 0xBF}, // 00000100: B.W 00000100
+ {0x00, 0xF0, 0x00, 0xC0}, // 00000100: BLX 00C00104
+ copier_T24);
+}
+
+TEST(Rel32UtilsTest, Rel32ReaderArm_AArch64) {
+ constexpr offset_t kTestImageSize = 0x00100000U;
+ constexpr rva_t kRvaBegin = 0x00030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030000: (Filler)
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030004: (Filler)
+ 0x02, 0x00, 0x00, 0x14, // 00030008: B 00030010 ; Immd26
+ 0xFF, 0xFF, 0xFF, 0xFF, // 0003000C: (Filler)
+ 0x25, 0x00, 0x00, 0x35, // 00030010: CBNZ R5,00030014 ; Immd19
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030014: (Filler)
+ 0xCA, 0xFF, 0xFF, 0x54, // 00030018: BGE 00030010 ; Immd19
+ 0x4C, 0xFF, 0x8F, 0x36, // 0003001C: TBZ X12,#17,00030004 ; Immd14
+ };
+ MutableBufferView region(&bytes[0], bytes.size());
+
+ // Generate Immd26. We specify rel32 locations directly.
+ std::vector<offset_t> rel32_locations_Immd26 = {0x0008U};
+ auto reader1 = std::make_unique<
+ Rel32ReaderArm<AArch64Rel32Translator::AddrTraits_Immd26>>(
+ translator, region, rel32_locations_Immd26, 0x0000U, 0x0020U);
+ CheckReader({{0x0008U, 0x0010U}}, std::move(reader1));
+
+ // Generate Immd19.
+ std::vector<offset_t> rel32_locations_Immd19 = {0x0010U, 0x0018U};
+ auto reader2 = std::make_unique<
+ Rel32ReaderArm<AArch64Rel32Translator::AddrTraits_Immd19>>(
+ translator, region, rel32_locations_Immd19, 0x0000U, 0x0020U);
+ CheckReader({{0x0010U, 0x0014U}, {0x0018U, 0x0010U}}, std::move(reader2));
+
+ // Generate Immd14.
+ std::vector<offset_t> rel32_locations_Immd14 = {0x001CU};
+ auto reader3 = std::make_unique<
+ Rel32ReaderArm<AArch64Rel32Translator::AddrTraits_Immd14>>(
+ translator, region, rel32_locations_Immd14, 0x0000U, 0x0020U);
+ CheckReader({{0x001CU, 0x0004U}}, std::move(reader3));
+}
+
+TEST(Rel32UtilsTest, Rel32WriterArm_AArch64) {
+ constexpr offset_t kTestImageSize = 0x00100000U;
+ constexpr rva_t kRvaBegin = 0x00030000U;
+ TestAddressTranslator translator(kTestImageSize, kRvaBegin);
+
+ std::vector<uint8_t> bytes = {
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030000: (Filler)
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030004: (Filler)
+ 0x02, 0x00, 0x00, 0x14, // 00030008: B 00030010 ; Immd26
+ 0xFF, 0xFF, 0xFF, 0xFF, // 0003000C: (Filler)
+ 0x25, 0x00, 0x00, 0x35, // 00030010: CBNZ R5,00030014 ; Immd19
+ 0xFF, 0xFF, 0xFF, 0xFF, // 00030014: (Filler)
+ 0xCA, 0xFF, 0xFF, 0x54, // 00030018: BGE 00030010 ; Immd19
+ 0x4C, 0xFF, 0x8F, 0x36, // 0003001C: TBZ X12,#17,00030004 ; Immd14
+ };
+ MutableBufferView region(&bytes[0], bytes.size());
+
+ auto writer1 = std::make_unique<
+ Rel32WriterArm<AArch64Rel32Translator::AddrTraits_Immd26>>(translator,
+ region);
+ writer1->PutNext({0x0008U, 0x0000U});
+ EXPECT_EQ(0xFE, bytes[0x08]); // 00030008: B 00030000 ; Immd26
+ EXPECT_EQ(0xFF, bytes[0x09]);
+ EXPECT_EQ(0xFF, bytes[0x0A]);
+ EXPECT_EQ(0x17, bytes[0x0B]);
+
+ auto writer2 = std::make_unique<
+ Rel32WriterArm<AArch64Rel32Translator::AddrTraits_Immd19>>(translator,
+ region);
+ writer2->PutNext({0x0010U, 0x0000U});
+ EXPECT_EQ(0x85, bytes[0x10]); // 00030010: CBNZ R5,00030000 ; Immd19
+ EXPECT_EQ(0xFF, bytes[0x11]);
+ EXPECT_EQ(0xFF, bytes[0x12]);
+ EXPECT_EQ(0x35, bytes[0x13]);
+ writer2->PutNext({0x0018U, 0x001CU});
+ EXPECT_EQ(0x2A, bytes[0x18]); // 00030018: BGE 0003001C ; Immd19
+ EXPECT_EQ(0x00, bytes[0x19]);
+ EXPECT_EQ(0x00, bytes[0x1A]);
+ EXPECT_EQ(0x54, bytes[0x1B]);
+
+ auto writer3 = std::make_unique<
+ Rel32WriterArm<AArch64Rel32Translator::AddrTraits_Immd14>>(translator,
+ region);
+ writer3->PutNext({0x001CU, 0x0010U});
+ EXPECT_EQ(0xAC, bytes[0x1C]); // 0003001C: TBZ X12,#17,00030010 ; Immd14
+ EXPECT_EQ(0xFF, bytes[0x1D]);
+ EXPECT_EQ(0x8F, bytes[0x1E]);
+ EXPECT_EQ(0x36, bytes[0x1F]);
+}
+
+TEST(Rel32UtilsTest, ArmCopyDisp_AArch64) {
+ std::vector<uint8_t> expect_fail;
+
+ // Successful Imm26.
+ ArmCopyDispFun copier_Immd26 =
+ ArmCopyDisp<AArch64Rel32Translator::AddrTraits_Immd26>;
+ CheckCopy({0x12, 0x34, 0x56, 0x94}, // 00000100: BL 0158D148
+ {0xA1, 0xC0, 0x0E, 0x17}, // 00000100: B FC3B0384
+ {0x12, 0x34, 0x56, 0x14}, // 00000100: B 0158D148
+ {0xA1, 0xC0, 0x0E, 0x97}, // 00000100: BL FC3B0384
+ copier_Immd26);
+
+ // Successful Imm19.
+ ArmCopyDispFun copier_Immd19 =
+ ArmCopyDisp<AArch64Rel32Translator::AddrTraits_Immd19>;
+ CheckCopy({0x24, 0x12, 0x34, 0x54}, // 00000100: BMI 00068344
+ {0xD7, 0xA5, 0xFC, 0xB4}, // 00000100: CBZ X23,FFFF95B8
+ {0x37, 0x12, 0x34, 0xB4}, // 00000100: CBZ X23,00068344
+ {0xC4, 0xA5, 0xFC, 0x54}, // 00000100: BMI FFFF95B8
+ copier_Immd19);
+
+ // Successful Imm14.
+ ArmCopyDispFun copier_Immd14 =
+ ArmCopyDisp<AArch64Rel32Translator::AddrTraits_Immd14>;
+ CheckCopy({0x00, 0x00, 0x00, 0x36}, // 00000100: TBZ X0,#0,00000100
+ {0xFF, 0xFF, 0xFF, 0xB7}, // 00000100: TBNZ ZR,#63,000000FC
+ {0x1F, 0x00, 0xF8, 0xB7}, // 00000100: TBNZ ZR,#63,00000100
+ {0xE0, 0xFF, 0x07, 0x36}, // 00000100: TBZ X0,#0,000000FC
+ copier_Immd14);
+
+ // Failure if wrong copier is used.
+ CheckCopy(expect_fail, expect_fail, {0x1F, 0x00, 0xF8, 0xB7},
+ {0xE0, 0xFF, 0x07, 0x36}, copier_Immd26);
+}
+
} // namespace zucchini